| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553 |
- <template>
- <div class="table-box button-table friend-relation-container">
- <ProTable ref="proTable" :columns="columns" :request-api="getTableList" :init-param="initParam" :data-callback="dataCallback">
- <!-- 表格 header 按钮 -->
- <template #tableHeader="scope">
- <div class="header-button">
- <el-button type="primary" @click="openAddDialog"> 添加活动 </el-button>
- </div>
- </template>
- <!-- 状态列 -->
- <template #status="scope">
- <el-tag :type="getStatusType(scope.row.status)">
- {{ getStatusText(scope.row.status) }}
- </el-tag>
- </template>
- <!-- 表格操作 -->
- <template #operation="scope">
- <el-button link type="primary" @click="editRow(scope.row)"> 编辑 </el-button>
- <el-button link type="primary" @click="deleteRow(scope.row)"> 删除 </el-button>
- <el-button v-if="scope.row.status === 0" link type="primary" @click="handleApprove(scope.row)"> 同意 </el-button>
- </template>
- </ProTable>
- <!-- 添加/编辑活动对话框 -->
- <el-dialog v-model="dialogVisible" :title="dialogTitle" width="700px" @close="closeDialog">
- <el-form ref="formRef" :model="formData" :rules="formRules" label-width="140px">
- <el-form-item label="活动名称" prop="acName">
- <el-input v-model="formData.acName" placeholder="请输入" clearable />
- </el-form-item>
- <el-form-item label="消费门槛金额(¥)" required>
- <div style="display: flex; gap: 10px; align-items: center; width: 100%">
- <el-form-item prop="moneyLow" style=" flex: 1;margin-bottom: 0">
- <el-input v-model.number="formData.moneyLow" placeholder="0.00" clearable>
- <template #prefix> ¥ </template>
- </el-input>
- </el-form-item>
- <span>~</span>
- <el-form-item prop="moneyHigh" style=" flex: 1;margin-bottom: 0">
- <el-input v-model.number="formData.moneyHigh" placeholder="0.00" clearable>
- <template #prefix> ¥ </template>
- </el-input>
- </el-form-item>
- </div>
- </el-form-item>
- <el-form-item label="来源商家及优惠券">
- <div class="merchant-coupon-list">
- <div v-for="(item, index) in formData.details" :key="index" class="merchant-coupon-item">
- <el-select
- v-model="item.friendStoreUserId"
- placeholder="选择商家"
- style="width: 200px; margin-right: 10px"
- @change="handleMerchantChange(index)"
- >
- <el-option
- v-for="merchant in merchantList"
- :key="merchant.couponId"
- :label="merchant.storeName"
- :value="merchant.couponId"
- />
- </el-select>
- <el-select
- v-model="item.couponId"
- placeholder="选择优惠券"
- style="width: 200px; margin-right: 10px"
- @change="handleCouponChange(index)"
- >
- <el-option
- v-for="coupon in item.couponList"
- :key="coupon.couponId || coupon.id"
- :label="coupon.couponName"
- :value="coupon.couponId || coupon.id"
- />
- </el-select>
- <el-input v-model="item.remainingCount" placeholder="剩余张数1000张" style="width: 180px; margin-right: 10px" />
- <el-button type="danger" link @click="removeMerchantCoupon(index)" v-if="formData.details.length > 1">
- 删除
- </el-button>
- </div>
- <el-button type="primary" link @click="addMerchantCoupon" style="margin-top: 10px">
- <el-icon><Plus /></el-icon>
- 添加商家优惠券
- </el-button>
- </div>
- </el-form-item>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="closeDialog"> 取消 </el-button>
- <el-button type="primary" @click="handleSubmit"> 确定 </el-button>
- </div>
- </template>
- </el-dialog>
- </div>
- </template>
- <script setup lang="tsx" name="friendRelation">
- import { computed, onMounted, reactive, ref } from "vue";
- import type { FormInstance, FormRules } from "element-plus";
- import { ElMessage, ElMessageBox } from "element-plus";
- import { Plus } from "@element-plus/icons-vue";
- import ProTable from "@/components/ProTable/index.vue";
- import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
- import { localGet } from "@/utils";
- import {
- getRuleList,
- saveFriendCouponRule,
- getReceivedFriendCouponList,
- delFriendCouponRule,
- getRuleById
- } from "@/api/modules/newLoginApi";
- // ProTable 实例
- const proTable = ref<ProTableInstance>();
- // 对话框相关
- const dialogVisible = ref(false);
- const dialogTitle = computed(() => (isEdit.value ? "编辑活动" : "添加活动"));
- const isEdit = ref(false);
- const currentEditId = ref("");
- // 表单引用
- const formRef = ref<FormInstance>();
- // 商家列表
- const merchantList = ref<any[]>([]);
- // 表单数据
- const formData = reactive({
- acName: "",
- moneyLow: undefined as number | undefined,
- moneyHigh: undefined as number | undefined,
- details: [] as Array<{
- friendStoreUserId: string | number;
- couponId: string | number;
- couponList: any[]; // 当前商家的优惠券列表
- remainingCount: number; // 剩余张数
- }>
- });
- // 表单验证规则
- const formRules = reactive<FormRules>({
- acName: [{ required: true, message: "请输入活动名称", trigger: "blur" }],
- moneyLow: [{ required: true, message: "请输入最低消费金额", trigger: "blur" }],
- moneyHigh: [{ required: true, message: "请输入最高消费金额", trigger: "blur" }]
- });
- // 表格列配置
- const columns = reactive<ColumnProps<any>[]>([
- {
- prop: "acName",
- label: "活动名称"
- },
- {
- prop: "endDate",
- label: "有效期至"
- },
- {
- prop: "relationType",
- label: "消费门槛",
- render: (scope: any) => {
- return scope.row.moneyLow + "元" + "~" + scope.row.moneyHigh + "元";
- }
- },
- {
- prop: "status",
- label: "状态",
- enum: [
- { label: "启用中", value: "0" },
- { label: "已停用", value: "1" }
- ],
- fieldNames: { label: "label", value: "value" },
- render: (scope: any) => {
- return scope.row.status == "0" ? "启用中" : "已停用";
- }
- },
- { prop: "operation", label: "操作", fixed: "right", width: 250 }
- ]);
- // 初始化请求参数
- const initParam = reactive({
- storeId: localGet("createdId") || ""
- });
- // 数据回调处理
- const dataCallback = (data: any) => {
- return {
- list: data || [],
- total: data?.total || 0
- };
- };
- // 获取表格列表
- const getTableList = (params: any) => {
- return getRuleList(params);
- };
- // 获取状态文本
- const getStatusText = (status: number) => {
- const statusMap: Record<number, string> = {
- 0: "待同意",
- 1: "已同意",
- 2: "已拒绝"
- };
- return statusMap[status] || "--";
- };
- // 获取状态类型
- const getStatusType = (status: number): "success" | "warning" | "info" | "danger" => {
- const typeMap: Record<number, "success" | "warning" | "info" | "danger"> = {
- 0: "warning",
- 1: "success",
- 2: "info"
- };
- return typeMap[status] || "info";
- };
- // 获取商家列表(选择商家)
- const getMerchantList = async () => {
- try {
- const res: any = await getReceivedFriendCouponList({
- storeId: localGet("createdId") || ""
- });
- if (res.code == 200) {
- merchantList.value = res.data;
- console.log(merchantList.value);
- }
- } catch (error) {
- console.error("获取商家列表失败", error);
- }
- };
- // 打开添加对话框
- const openAddDialog = async () => {
- isEdit.value = false;
- await getMerchantList();
- // 初始化一个空的商家优惠券项
- formData.details = [
- {
- friendStoreUserId: "",
- couponId: "",
- couponList: [],
- remainingCount: 0
- }
- ];
- dialogVisible.value = true;
- };
- // 关闭对话框
- const closeDialog = () => {
- dialogVisible.value = false;
- formRef.value?.resetFields();
- Object.assign(formData, {
- acName: "",
- moneyLow: undefined,
- moneyHigh: undefined,
- details: []
- });
- currentEditId.value = "";
- };
- // 添加商家优惠券
- const addMerchantCoupon = () => {
- formData.details.push({
- friendStoreUserId: "",
- couponId: "",
- couponList: [],
- remainingCount: 0
- });
- };
- // 移除商家优惠券
- const removeMerchantCoupon = (index: number) => {
- formData.details.splice(index, 1);
- };
- // 商家选择改变时,获取该商家的优惠券列表(选择优惠券)
- const handleMerchantChange = async (index: number) => {
- const item = formData.details[index];
- item.couponId = ""; // 重置优惠券选择
- item.remainingCount = 0; // 重置剩余张数
- if (!item.friendStoreUserId) {
- item.couponList = [];
- return;
- }
- // item.friendStoreUserId 存储的是商家的 couponId,需要找到对应商家的 friendStoreUserId
- const merchant = merchantList.value.find((m: any) => m.couponId === item.friendStoreUserId);
- if (!merchant) {
- item.couponList = [];
- return;
- }
- try {
- const res: any = await getReceivedFriendCouponList({
- storeId: localGet("createdId") || "",
- friendStoreUserId: merchant.friendStoreUserId
- });
- if (res.code == 200) {
- item.couponList = res.data;
- } else {
- item.couponList = [];
- }
- } catch (error) {
- console.error("获取优惠券列表失败", error);
- item.couponList = [];
- }
- };
- // 优惠券选择改变时,更新剩余张数
- const handleCouponChange = (index: number) => {
- const item = formData.details[index];
- const coupon = item.couponList.find((c: any) => (c.couponId || c.id) === item.couponId);
- if (coupon) {
- item.remainingCount = coupon.couponNum || 0; // 使用 getReceivedFriendCouponList 返回的 couponNum
- }
- };
- // 编辑行数据
- const editRow = async (row: any) => {
- isEdit.value = true;
- currentEditId.value = row.id;
- try {
- // 1. 获取商家列表
- await getMerchantList();
- // 2. 调用 getRuleById 获取活动详情
- const res: any = await getRuleById({ id: row.id });
- if (res.code == 200 && res.data) {
- const detailData = res.data;
- console.log("getRuleById 返回的数据:", detailData);
- // 3. 处理 lifeDiscountCouponFriendRuleDetailVos 数据
- let details: Array<{
- friendStoreUserId: string | number;
- couponId: string | number;
- couponList: any[];
- remainingCount: number;
- }> = [];
- const detailVos = detailData.lifeDiscountCouponFriendRuleDetailVos || detailData.details || [];
- if (detailVos && Array.isArray(detailVos) && detailVos.length > 0) {
- details = await Promise.all(
- detailVos.map(async (item: any) => {
- console.log("detail item:", item);
- // 根据 couponId 在商家列表中找到对应的商家
- const matchedMerchant = merchantList.value.find((m: any) => m.couponId === item.couponId);
- console.log("匹配到的商家:", matchedMerchant);
- // 如果没有匹配到商家,返回默认值
- if (!matchedMerchant) {
- return {
- friendStoreUserId: item.couponId, // 商家选择框绑定的是 couponId
- couponId: "",
- couponList: [],
- remainingCount: 0
- };
- }
- // 获取该商家的优惠券列表
- let couponList: any[] = [];
- try {
- const couponRes: any = await getReceivedFriendCouponList({
- storeId: localGet("createdId") || "",
- friendStoreUserId: matchedMerchant.friendStoreUserId
- });
- if (couponRes.code == 200) {
- couponList = couponRes.data || [];
- }
- } catch (error) {
- console.error("获取优惠券列表失败", error);
- }
- // 在优惠券列表中找到匹配的优惠券
- let matchedCoupon = couponList.find((c: any) => c.couponId === item.couponId);
- console.log("匹配到的优惠券:", matchedCoupon);
- // 如果没有在列表中找到,使用 lifeDiscountCouponFriendRuleDetailVos 中的数据创建一个临时对象
- if (!matchedCoupon && item.couponId) {
- matchedCoupon = {
- couponId: item.couponId,
- couponName: item.couponName, // 使用 getRuleById 返回的 couponName
- couponNum: item.couponNum || 0 // 使用 getRuleById 返回的 couponNum
- };
- // 将这个临时对象添加到列表中,以便下拉框可以显示
- couponList = [matchedCoupon, ...couponList];
- }
- return {
- friendStoreUserId: item.couponId, // 商家选择框的值是商家的 couponId
- couponId: matchedCoupon?.couponId || item.couponId || "", // 优惠券选择框的值使用 couponId
- couponList: couponList,
- remainingCount: matchedCoupon?.couponNum || 0 // 使用 getReceivedFriendCouponList 返回的 couponNum
- };
- })
- );
- } else {
- details = [
- {
- friendStoreUserId: "",
- couponId: "",
- couponList: [],
- remainingCount: 0
- }
- ];
- }
- Object.assign(formData, {
- acName: detailData.acName,
- moneyLow: detailData.moneyLow,
- moneyHigh: detailData.moneyHigh,
- details: details
- });
- dialogVisible.value = true;
- } else {
- ElMessage.error(res.msg || "获取活动详情失败");
- }
- } catch (error: any) {
- ElMessage.error(error?.msg || "获取活动详情失败");
- }
- };
- // 删除行数据
- const deleteRow = (row: any) => {
- ElMessageBox.confirm("确定要删除这个活动吗?", "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning"
- })
- .then(async () => {
- try {
- const res: any = await delFriendCouponRule({ id: row.id });
- if (res.code == 200) {
- ElMessage.success("删除成功");
- proTable.value?.getTableList();
- } else {
- ElMessage.error(res.msg || "删除失败");
- }
- } catch (error: any) {
- ElMessage.error(error?.msg || "删除失败");
- }
- })
- .catch(() => {
- // 用户取消删除
- });
- };
- // 同意好友申请(此页面可能不需要)
- const handleApprove = async (row: any) => {
- try {
- ElMessage.success("操作成功");
- proTable.value?.getTableList();
- } catch (error) {
- ElMessage.error("操作失败");
- }
- };
- // 提交表单
- const handleSubmit = async () => {
- if (!formRef.value) return;
- await formRef.value.validate(async (valid: boolean) => {
- if (valid) {
- // 验证是否至少添加了一个商家优惠券
- if (!formData.details.length) {
- ElMessage.warning("请至少添加一个商家优惠券");
- return;
- }
- // 验证所有商家优惠券项是否都已选择
- const hasEmpty = formData.details.some(item => !item.friendStoreUserId || !item.couponId);
- if (hasEmpty) {
- ElMessage.warning("请完善所有商家优惠券信息");
- return;
- }
- try {
- // 转换数据:item.friendStoreUserId 存储的是商家的 couponId,item.couponId 存储的是优惠券的 couponId
- const details = formData.details.map(item => {
- // 找到对应的商家
- const merchant = merchantList.value.find((m: any) => m.couponId === item.friendStoreUserId);
- // 找到对应的优惠券
- const coupon = item.couponList.find((c: any) => (c.couponId || c.id) === item.couponId);
- return {
- couponId: item.couponId, // 直接使用选中的 couponId
- friendStoreUserId: merchant?.friendStoreUserId || "" // 使用商家的真实 friendStoreUserId
- };
- });
- const params = {
- storeId: localGet("createdId") || "",
- acName: formData.acName,
- moneyHigh: formData.moneyHigh,
- moneyLow: formData.moneyLow,
- details: details
- };
- console.log("提交参数:", params);
- const res: any = await saveFriendCouponRule(params);
- if (res.code == 200) {
- ElMessage.success(isEdit.value ? "编辑成功" : "添加成功");
- closeDialog();
- proTable.value?.getTableList();
- } else {
- ElMessage.error(res.msg || "操作失败");
- }
- } catch (error: any) {
- ElMessage.error(error?.msg || (isEdit.value ? "编辑失败" : "添加失败"));
- }
- }
- });
- };
- // 页面加载时触发查询
- onMounted(() => {
- proTable.value?.getTableList();
- });
- </script>
- <style lang="scss" scoped>
- .friend-relation-container {
- .header-button {
- margin-bottom: 16px;
- }
- .merchant-coupon-list {
- width: 100%;
- .merchant-coupon-item {
- display: flex;
- align-items: center;
- margin-bottom: 10px;
- }
- }
- .dialog-footer {
- display: flex;
- gap: 10px;
- justify-content: flex-end;
- }
- }
- </style>
|