f
This commit is contained in:
131
src/components/ShareReportButton.vue
Normal file
131
src/components/ShareReportButton.vue
Normal file
@@ -0,0 +1,131 @@
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { showToast, showDialog } from "vant";
|
||||
|
||||
const props = defineProps({
|
||||
orderId: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
orderNo: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
isExample: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const isLoading = ref(false);
|
||||
|
||||
const copyToClipboard = async (text) => {
|
||||
await navigator.clipboard.writeText(text);
|
||||
showToast({
|
||||
type: "success",
|
||||
message: "链接已复制到剪贴板",
|
||||
position: "bottom",
|
||||
});
|
||||
};
|
||||
const handleShare = async () => {
|
||||
if (isLoading.value || props.disabled) return;
|
||||
// 如果是示例模式,直接分享当前URL
|
||||
if (props.isExample) {
|
||||
try {
|
||||
const currentUrl = window.location.href;
|
||||
await copyToClipboard(currentUrl);
|
||||
showToast({
|
||||
type: "success",
|
||||
message: "示例链接已复制到剪贴板",
|
||||
position: "bottom",
|
||||
});
|
||||
} catch (err) {
|
||||
showToast({
|
||||
type: "fail",
|
||||
message: "复制链接失败",
|
||||
position: "bottom",
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 优先使用 orderId,如果没有则使用 orderNo
|
||||
const orderIdentifier = props.orderId || props.orderNo;
|
||||
if (!orderIdentifier) {
|
||||
showToast({
|
||||
type: "fail",
|
||||
message: "缺少订单标识",
|
||||
position: "bottom",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
isLoading.value = true;
|
||||
try {
|
||||
// 根据实际使用的标识构建请求参数
|
||||
const requestData = props.orderId
|
||||
? { order_id: parseInt(props.orderId) }
|
||||
: { order_no: props.orderNo };
|
||||
|
||||
const { data, error } = await useApiFetch("/query/generate_share_link")
|
||||
.post(requestData)
|
||||
.json();
|
||||
|
||||
if (error.value) {
|
||||
throw new Error(error.value);
|
||||
}
|
||||
|
||||
if (data.value?.code === 200 && data.value.data?.share_link) {
|
||||
const baseUrl = window.location.origin;
|
||||
const linkId = encodeURIComponent(data.value.data.share_link);
|
||||
const fullShareUrl = `${baseUrl}/report/share/${linkId}`;
|
||||
|
||||
try {
|
||||
// 显示确认对话框
|
||||
await showDialog({
|
||||
title: "分享链接已生成",
|
||||
message: "链接将在7天后过期,是否复制到剪贴板?",
|
||||
confirmButtonText: "复制链接",
|
||||
cancelButtonText: "取消",
|
||||
showCancelButton: true,
|
||||
});
|
||||
|
||||
// 用户点击确认后复制链接
|
||||
await copyToClipboard(fullShareUrl);
|
||||
} catch (dialogErr) {
|
||||
// 用户点击取消按钮时,dialogErr 会是 'cancel'
|
||||
// 这里不需要显示错误提示,直接返回即可
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
throw new Error(data.value?.message || "生成分享链接失败");
|
||||
}
|
||||
} catch (err) {
|
||||
showToast({
|
||||
type: "fail",
|
||||
message: err.message || "生成分享链接失败",
|
||||
position: "bottom",
|
||||
});
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="bg-primary-second border border-primary-second rounded-[40px] px-3 py-1 flex items-center justify-center cursor-pointer hover:bg-primary-600 transition-colors duration-200"
|
||||
:class="{ 'opacity-50 cursor-not-allowed': isLoading || disabled }" @click="handleShare">
|
||||
<img src="@/assets/images/report/fx.png" alt="分享" class="w-4 h-4 mr-1" />
|
||||
<span class="text-white text-sm font-medium">
|
||||
{{ isLoading ? "生成中..." : (isExample ? "分享示例" : "分享报告") }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 样式已通过 Tailwind CSS 类实现 */
|
||||
</style>
|
||||
Reference in New Issue
Block a user