|
@@ -0,0 +1,382 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="table-box button-table friend-coupon-container">
|
|
|
|
|
+ <ProTable
|
|
|
|
|
+ ref="proTable"
|
|
|
|
|
+ :columns="columns"
|
|
|
|
|
+ :request-api="getTableList"
|
|
|
|
|
+ :init-param="initParam"
|
|
|
|
|
+ :data-callback="dataCallback"
|
|
|
|
|
+ :key="activeName"
|
|
|
|
|
+ >
|
|
|
|
|
+ <!-- 表格 header 按钮 -->
|
|
|
|
|
+ <template #tableHeader="scope">
|
|
|
|
|
+ <div class="table-header-content">
|
|
|
|
|
+ <div class="header-button">
|
|
|
|
|
+ <el-button type="primary" @click="openGiftDialog"> 赠送好友优惠券 </el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-tabs v-model="activeName" class="header-tabs" @tab-click="handleTabClick">
|
|
|
|
|
+ <el-tab-pane label="好友赠我" name="friendMessage" />
|
|
|
|
|
+ <el-tab-pane label="我赠好友" name="myGift" />
|
|
|
|
|
+ </el-tabs>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 表格操作 -->
|
|
|
|
|
+ <template #operation="scope">
|
|
|
|
|
+ <el-button link type="primary" @click="viewDetail(scope.row)"> 查看详情 </el-button>
|
|
|
|
|
+ <el-button v-if="activeName === 'myGift'" link type="primary" @click="deleteRow(scope.row)"> 删除 </el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </ProTable>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 赠送好友优惠券对话框 -->
|
|
|
|
|
+ <el-dialog v-model="giftDialogVisible" title="赠送好友优惠券" width="600px" @close="closeGiftDialog">
|
|
|
|
|
+ <el-form ref="giftFormRef" :model="giftFormData" :rules="giftRules" label-width="120px">
|
|
|
|
|
+ <el-form-item label="选择好友" prop="friendId">
|
|
|
|
|
+ <el-select v-model="giftFormData.friendId" placeholder="请选择好友" style="width: 100%">
|
|
|
|
|
+ <el-option v-for="friend in friendList" :key="friend.id" :label="friend.name" :value="friend.id" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <el-form-item label="选择优惠券" prop="couponId">
|
|
|
|
|
+ <el-select v-model="giftFormData.couponId" placeholder="请选择优惠券" style="width: 100%" @change="handleCouponChange">
|
|
|
|
|
+ <el-option v-for="coupon in couponList" :key="coupon.id" :label="coupon.name" :value="coupon.id" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <div v-if="giftFormData.couponId" class="coupon-info">
|
|
|
|
|
+ <span>请输入赠送数量</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <el-form-item v-if="giftFormData.couponId" label="赠送数量" prop="quantity">
|
|
|
|
|
+ <el-input-number v-model="giftFormData.quantity" :min="1" :max="100" placeholder="请输入数量" style="width: 100%" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <div class="dialog-footer">
|
|
|
|
|
+ <el-button @click="closeGiftDialog"> 取消 </el-button>
|
|
|
|
|
+ <el-button type="primary" @click="handleGiftSubmit"> 确定 </el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup lang="tsx" name="friendCoupon">
|
|
|
|
|
+import { computed, onMounted, reactive, ref } from "vue";
|
|
|
|
|
+import { useRouter } from "vue-router";
|
|
|
|
|
+import type { FormInstance, FormRules } from "element-plus";
|
|
|
|
|
+import { ElMessage, ElMessageBox } from "element-plus";
|
|
|
|
|
+import ProTable from "@/components/ProTable/index.vue";
|
|
|
|
|
+import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
|
|
|
|
|
+import { localGet } from "@/utils";
|
|
|
|
|
+// import { getFriendCouponList, sendCouponToFriend, deleteFriendCoupon } from "@/api/modules/friendCoupon";
|
|
|
|
|
+
|
|
|
|
|
+const router = useRouter();
|
|
|
|
|
+
|
|
|
|
|
+// 当前激活的标签页
|
|
|
|
|
+const activeName = ref("friendMessage");
|
|
|
|
|
+
|
|
|
|
|
+// ProTable 实例
|
|
|
|
|
+const proTable = ref<ProTableInstance>();
|
|
|
|
|
+
|
|
|
|
|
+// 赠送对话框
|
|
|
|
|
+const giftDialogVisible = ref(false);
|
|
|
|
|
+const giftFormRef = ref<FormInstance>();
|
|
|
|
|
+
|
|
|
|
|
+// 好友列表(模拟数据)
|
|
|
|
|
+const friendList = ref([
|
|
|
|
|
+ { id: 1, name: "张三" },
|
|
|
|
|
+ { id: 2, name: "李四" },
|
|
|
|
|
+ { id: 3, name: "王五" }
|
|
|
|
|
+]);
|
|
|
|
|
+
|
|
|
|
|
+// 优惠券列表(模拟数据)
|
|
|
|
|
+const couponList = ref([
|
|
|
|
|
+ { id: 1, name: "满100减20代金券", stock: 50 },
|
|
|
|
|
+ { id: 2, name: "8折优惠券", stock: 30 },
|
|
|
|
|
+ { id: 3, name: "满200减50代金券", stock: 20 }
|
|
|
|
|
+]);
|
|
|
|
|
+
|
|
|
|
|
+// 赠送表单数据
|
|
|
|
|
+const giftFormData = reactive({
|
|
|
|
|
+ friendId: "",
|
|
|
|
|
+ couponId: "",
|
|
|
|
|
+ quantity: 1
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 表单验证规则
|
|
|
|
|
+const giftRules = reactive<FormRules>({
|
|
|
|
|
+ friendId: [{ required: true, message: "请选择好友", trigger: "change" }],
|
|
|
|
|
+ couponId: [{ required: true, message: "请选择优惠券", trigger: "change" }],
|
|
|
|
|
+ quantity: [{ required: true, message: "请输入赠送数量", trigger: "blur" }]
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 好友留言表格列配置
|
|
|
|
|
+const friendMessageColumns = reactive<ColumnProps<any>[]>([
|
|
|
|
|
+ {
|
|
|
|
|
+ prop: "storeName",
|
|
|
|
|
+ label: "店铺名称",
|
|
|
|
|
+ search: {
|
|
|
|
|
+ el: "input"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ prop: "couponAmount",
|
|
|
|
|
+ label: "优惠券额",
|
|
|
|
|
+ render: (scope: any) => {
|
|
|
|
|
+ return `¥${scope.row.couponAmount || 0}`;
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ prop: "validUntil",
|
|
|
|
|
+ label: "有效期至",
|
|
|
|
|
+ render: (scope: any) => {
|
|
|
|
|
+ return scope.row.validUntil?.replace(/-/g, "/") || "--";
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ prop: "senderName",
|
|
|
|
|
+ label: "赠送人"
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ prop: "receiveTime",
|
|
|
|
|
+ label: "接收时间",
|
|
|
|
|
+ render: (scope: any) => {
|
|
|
|
|
+ return scope.row.receiveTime?.replace(/-/g, "/") || "--";
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ { prop: "operation", label: "操作", fixed: "right", width: 200 }
|
|
|
|
|
+]);
|
|
|
|
|
+
|
|
|
|
|
+// 我感好友表格列配置
|
|
|
|
|
+const myGiftColumns = reactive<ColumnProps<any>[]>([
|
|
|
|
|
+ {
|
|
|
|
|
+ prop: "storeName",
|
|
|
|
|
+ label: "店铺名称",
|
|
|
|
|
+ search: {
|
|
|
|
|
+ el: "input"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ prop: "couponAmount",
|
|
|
|
|
+ label: "优惠券额",
|
|
|
|
|
+ render: (scope: any) => {
|
|
|
|
|
+ return `¥${scope.row.couponAmount || 0}`;
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ prop: "validUntil",
|
|
|
|
|
+ label: "有效期至",
|
|
|
|
|
+ render: (scope: any) => {
|
|
|
|
|
+ return scope.row.validUntil?.replace(/-/g, "/") || "--";
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ prop: "receiverName",
|
|
|
|
|
+ label: "接收人"
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ prop: "status",
|
|
|
|
|
+ label: "状态",
|
|
|
|
|
+ render: (scope: any) => {
|
|
|
|
|
+ const statusMap: Record<number, string> = {
|
|
|
|
|
+ 0: "未使用",
|
|
|
|
|
+ 1: "已使用",
|
|
|
|
|
+ 2: "已过期"
|
|
|
|
|
+ };
|
|
|
|
|
+ return statusMap[scope.row.status] || "--";
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ prop: "sendTime",
|
|
|
|
|
+ label: "赠送时间",
|
|
|
|
|
+ render: (scope: any) => {
|
|
|
|
|
+ return scope.row.sendTime?.replace(/-/g, "/") || "--";
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ { prop: "operation", label: "操作", fixed: "right", width: 200 }
|
|
|
|
|
+]);
|
|
|
|
|
+
|
|
|
|
|
+// 根据当前选中的tab动态返回列配置
|
|
|
|
|
+const columns = computed(() => {
|
|
|
|
|
+ return activeName.value === "friendMessage" ? friendMessageColumns : myGiftColumns;
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 初始化请求参数
|
|
|
|
|
+const initParam = reactive({
|
|
|
|
|
+ storeId: localGet("createdId") || "",
|
|
|
|
|
+ type: activeName.value
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// Tab切换处理
|
|
|
|
|
+const handleTabClick = () => {
|
|
|
|
|
+ initParam.type = activeName.value;
|
|
|
|
|
+ proTable.value?.getTableList();
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// dataCallback 是对于返回的表格数据做处理
|
|
|
|
|
+const dataCallback = (data: any) => {
|
|
|
|
|
+ return {
|
|
|
|
|
+ list: data?.records || [],
|
|
|
|
|
+ total: data?.total || 0
|
|
|
|
|
+ };
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 获取表格列表
|
|
|
|
|
+const getTableList = (params: any) => {
|
|
|
|
|
+ const newParams = {
|
|
|
|
|
+ ...params,
|
|
|
|
|
+ type: activeName.value
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // TODO: 集成真实接口时,取消下面的注释
|
|
|
|
|
+ // return getFriendCouponList(newParams);
|
|
|
|
|
+
|
|
|
|
|
+ // 临时方案:返回模拟数据
|
|
|
|
|
+ return new Promise(resolve => {
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ const mockData = activeName.value === "friendMessage" ? generateMockFriendMessages() : generateMockMyGifts();
|
|
|
|
|
+ resolve({
|
|
|
|
|
+ code: 200,
|
|
|
|
|
+ data: {
|
|
|
|
|
+ records: mockData,
|
|
|
|
|
+ total: mockData.length
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }, 500);
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 生成模拟的好友留言数据
|
|
|
|
|
+const generateMockFriendMessages = () => {
|
|
|
|
|
+ return Array.from({ length: 2 }, (_, i) => ({
|
|
|
|
|
+ id: i + 1,
|
|
|
|
|
+ storeName: i === 0 ? "甜客优越" : "洗浴优越铺",
|
|
|
|
|
+ couponAmount: 200,
|
|
|
|
|
+ validUntil: "2025-05-01",
|
|
|
|
|
+ senderName: "张三",
|
|
|
|
|
+ receiveTime: "2025-03-01"
|
|
|
|
|
+ }));
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 生成模拟的我感好友数据
|
|
|
|
|
+const generateMockMyGifts = () => {
|
|
|
|
|
+ return Array.from({ length: 3 }, (_, i) => ({
|
|
|
|
|
+ id: i + 1,
|
|
|
|
|
+ storeName: `店铺${i + 1}`,
|
|
|
|
|
+ couponAmount: 200,
|
|
|
|
|
+ validUntil: "2025-05-01",
|
|
|
|
|
+ receiverName: `好友${i + 1}`,
|
|
|
|
|
+ status: i % 3,
|
|
|
|
|
+ sendTime: "2025-03-01"
|
|
|
|
|
+ }));
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 打开赠送对话框
|
|
|
|
|
+const openGiftDialog = () => {
|
|
|
|
|
+ giftDialogVisible.value = true;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 关闭赠送对话框
|
|
|
|
|
+const closeGiftDialog = () => {
|
|
|
|
|
+ giftDialogVisible.value = false;
|
|
|
|
|
+ giftFormRef.value?.resetFields();
|
|
|
|
|
+ Object.assign(giftFormData, {
|
|
|
|
|
+ friendId: "",
|
|
|
|
|
+ couponId: "",
|
|
|
|
|
+ quantity: 1
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 优惠券改变时
|
|
|
|
|
+const handleCouponChange = (val: string) => {
|
|
|
|
|
+ giftFormData.quantity = 1;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 提交赠送
|
|
|
|
|
+const handleGiftSubmit = async () => {
|
|
|
|
|
+ if (!giftFormRef.value) return;
|
|
|
|
|
+
|
|
|
|
|
+ await giftFormRef.value.validate(async (valid: boolean) => {
|
|
|
|
|
+ if (valid) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // TODO: 集成真实接口时,取消下面的注释
|
|
|
|
|
+ // await sendCouponToFriend({
|
|
|
|
|
+ // friendId: giftFormData.friendId,
|
|
|
|
|
+ // couponId: giftFormData.couponId,
|
|
|
|
|
+ // quantity: giftFormData.quantity
|
|
|
|
|
+ // });
|
|
|
|
|
+
|
|
|
|
|
+ ElMessage.success("赠送成功");
|
|
|
|
|
+ closeGiftDialog();
|
|
|
|
|
+ proTable.value?.getTableList();
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ ElMessage.error("赠送失败");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 查看详情
|
|
|
|
|
+const viewDetail = (row: any) => {
|
|
|
|
|
+ ElMessage.info(`查看详情: ${row.storeName}`);
|
|
|
|
|
+ // TODO: 跳转到详情页或显示详情对话框
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 删除行数据
|
|
|
|
|
+const deleteRow = (row: any) => {
|
|
|
|
|
+ ElMessageBox.confirm("确定要删除这条赠送记录吗?", "提示", {
|
|
|
|
|
+ confirmButtonText: "确定",
|
|
|
|
|
+ cancelButtonText: "取消",
|
|
|
|
|
+ type: "warning"
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // TODO: 集成真实接口时,取消下面的注释
|
|
|
|
|
+ // await deleteFriendCoupon({ id: row.id });
|
|
|
|
|
+
|
|
|
|
|
+ ElMessage.success("删除成功");
|
|
|
|
|
+ proTable.value?.getTableList();
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ ElMessage.error("删除失败");
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch(() => {
|
|
|
|
|
+ // 用户取消删除
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 页面加载时触发查询
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ proTable.value?.getTableList();
|
|
|
|
|
+});
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
|
+.friend-coupon-container {
|
|
|
|
|
+ .table-header-content {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 16px;
|
|
|
|
|
+ .header-tabs {
|
|
|
|
|
+ :deep(.el-tabs__nav-wrap::after) {
|
|
|
|
|
+ height: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .header-button {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: flex-start;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .coupon-info {
|
|
|
|
|
+ margin-top: 8px;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ color: #909399;
|
|
|
|
|
+ }
|
|
|
|
|
+ .dialog-footer {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+ justify-content: flex-end;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|