|
@@ -12,14 +12,15 @@
|
|
|
<template #tableHeader="scope">
|
|
<template #tableHeader="scope">
|
|
|
<div class="table-header-btn">
|
|
<div class="table-header-btn">
|
|
|
<div class="header-actions">
|
|
<div class="header-actions">
|
|
|
- <!-- <el-tabs v-model="activeName" class="tabs" @tab-click="handleClick">-->
|
|
|
|
|
- <!-- <el-tab-pane v-for="tab in allTabOptions" :key="tab.name" :label="tab.label" :name="tab.name" />-->
|
|
|
|
|
- <!-- </el-tabs>-->
|
|
|
|
|
- <el-button :icon="Plus" class="button" type="primary" @click="newCoupon" v-if="type"> 新建优惠券 </el-button>
|
|
|
|
|
|
|
+ <!-- 优惠券:状态 Tab(全部、未开始、进行中、已下架、已结束、已清库,不含草稿) -->
|
|
|
|
|
+ <el-tabs v-if="activeName === '2'" v-model="couponStatusTab" class="status-tabs" @tab-click="onCouponStatusTabChange">
|
|
|
|
|
+ <el-tab-pane v-for="tab in couponStatusTabOptions" :key="tab.value" :label="tab.label" :name="tab.value" />
|
|
|
|
|
+ </el-tabs>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
<template #tableHeaderRight="scope">
|
|
<template #tableHeaderRight="scope">
|
|
|
|
|
+ <el-button :icon="Plus" class="button" type="primary" @click="newCoupon" v-if="type"> 新建优惠券 </el-button>
|
|
|
<!-- <div class="action-buttons">-->
|
|
<!-- <div class="action-buttons">-->
|
|
|
<!-- <el-button :icon="Plus" class="button" type="primary" @click="newGroupBuying" v-if="type"> 新建代金券 </el-button>-->
|
|
<!-- <el-button :icon="Plus" class="button" type="primary" @click="newGroupBuying" v-if="type"> 新建代金券 </el-button>-->
|
|
|
<!-- <el-button :icon="Plus" class="button" type="primary" @click="newCoupon" v-if="type"> 新建优惠券 </el-button>-->
|
|
<!-- <el-button :icon="Plus" class="button" type="primary" @click="newCoupon" v-if="type"> 新建优惠券 </el-button>-->
|
|
@@ -40,91 +41,40 @@
|
|
|
</template>
|
|
</template>
|
|
|
<!-- 表格操作 -->
|
|
<!-- 表格操作 -->
|
|
|
<template #operation="scope">
|
|
<template #operation="scope">
|
|
|
- <!-- 上架按钮 -->
|
|
|
|
|
- <el-button
|
|
|
|
|
- v-if="canShowButton(scope.row.status, currentOperationPermissions.上架)"
|
|
|
|
|
- link
|
|
|
|
|
- type="primary"
|
|
|
|
|
- @click="changeTypes(scope.row, 5)"
|
|
|
|
|
- >
|
|
|
|
|
|
|
+ <el-button v-if="canShowAction(scope.row, '上架')" link type="primary" @click="changeTypes(scope.row, 5)">
|
|
|
上架
|
|
上架
|
|
|
</el-button>
|
|
</el-button>
|
|
|
- <!-- 下架按钮 -->
|
|
|
|
|
- <el-button
|
|
|
|
|
- v-if="canShowButton(scope.row.status, currentOperationPermissions.下架)"
|
|
|
|
|
- link
|
|
|
|
|
- type="primary"
|
|
|
|
|
- @click="changeTypes(scope.row, 6)"
|
|
|
|
|
- >
|
|
|
|
|
|
|
+ <el-button v-if="canShowAction(scope.row, '下架')" link type="primary" @click="changeTypes(scope.row, 6)">
|
|
|
下架
|
|
下架
|
|
|
</el-button>
|
|
</el-button>
|
|
|
- <!-- 修改库存按钮(仅代金券) -->
|
|
|
|
|
- <el-button
|
|
|
|
|
- v-if="isVoucher && canShowButton(scope.row.status, VOUCHER_OPERATION_PERMISSIONS.修改库存)"
|
|
|
|
|
- link
|
|
|
|
|
- type="primary"
|
|
|
|
|
- @click="changeInventory(scope.row)"
|
|
|
|
|
- >
|
|
|
|
|
|
|
+ <el-button v-if="canShowAction(scope.row, '修改库存')" link type="primary" @click="changeInventory(scope.row)">
|
|
|
修改库存
|
|
修改库存
|
|
|
</el-button>
|
|
</el-button>
|
|
|
- <!-- 查看详情按钮 -->
|
|
|
|
|
- <el-button
|
|
|
|
|
- v-if="
|
|
|
|
|
- isVoucher
|
|
|
|
|
- ? canShowButton(scope.row.status, currentOperationPermissions.查看详情) && scope.row.dataType == 0
|
|
|
|
|
- : canShowButton(scope.row.status, currentOperationPermissions.查看详情)
|
|
|
|
|
- "
|
|
|
|
|
- link
|
|
|
|
|
- type="primary"
|
|
|
|
|
- @click="toDetail(scope.row)"
|
|
|
|
|
- >
|
|
|
|
|
|
|
+ <el-button v-if="canShowAction(scope.row, '查看详情')" link type="primary" @click="toDetail(scope.row)">
|
|
|
查看详情
|
|
查看详情
|
|
|
</el-button>
|
|
</el-button>
|
|
|
- <!-- 编辑按钮 -->
|
|
|
|
|
- <el-button
|
|
|
|
|
- v-if="
|
|
|
|
|
- isVoucher
|
|
|
|
|
- ? canShowButton(scope.row.status, currentOperationPermissions.编辑) || scope.row.dataType == 1
|
|
|
|
|
- : canShowButton(scope.row.status, currentOperationPermissions.编辑)
|
|
|
|
|
- "
|
|
|
|
|
- link
|
|
|
|
|
- type="primary"
|
|
|
|
|
- @click="editRow(scope.row)"
|
|
|
|
|
- >
|
|
|
|
|
- 编辑
|
|
|
|
|
- </el-button>
|
|
|
|
|
- <!-- 删除按钮 -->
|
|
|
|
|
- <el-button
|
|
|
|
|
- v-if="
|
|
|
|
|
- isVoucher
|
|
|
|
|
- ? canShowButton(scope.row.status, currentOperationPermissions.删除) || scope.row.dataType == 1
|
|
|
|
|
- : canShowButton(scope.row.status, currentOperationPermissions.删除)
|
|
|
|
|
- "
|
|
|
|
|
- link
|
|
|
|
|
- type="primary"
|
|
|
|
|
- @click="deleteRow(scope.row)"
|
|
|
|
|
- >
|
|
|
|
|
- 删除
|
|
|
|
|
- </el-button>
|
|
|
|
|
- <!-- 查看拒绝原因按钮(仅代金券) -->
|
|
|
|
|
- <el-button
|
|
|
|
|
- v-if="isVoucher && canShowButton(scope.row.status, VOUCHER_OPERATION_PERMISSIONS.查看拒绝原因)"
|
|
|
|
|
- link
|
|
|
|
|
- type="primary"
|
|
|
|
|
- @click="viewRejectReason(scope.row)"
|
|
|
|
|
- >
|
|
|
|
|
|
|
+ <el-button v-if="canShowAction(scope.row, '编辑')" link type="primary" @click="editRow(scope.row)"> 编辑 </el-button>
|
|
|
|
|
+ <el-button v-if="canShowAction(scope.row, '删除')" link type="primary" @click="deleteRow(scope.row)"> 删除 </el-button>
|
|
|
|
|
+ <el-button v-if="canShowAction(scope.row, '查看拒绝原因')" link type="primary" @click="viewRejectReason(scope.row)">
|
|
|
查看拒绝原因
|
|
查看拒绝原因
|
|
|
</el-button>
|
|
</el-button>
|
|
|
</template>
|
|
</template>
|
|
|
</ProTable>
|
|
</ProTable>
|
|
|
- <el-dialog v-model="dialogFormVisible" title="修改库存" width="500">
|
|
|
|
|
|
|
+ <el-dialog v-model="dialogFormVisible" title="修改库存" width="500" append-to-body class="inventory-dialog-ios-fix">
|
|
|
<el-form ref="ruleFormRef" :model="formInventory" :rules="rules" @submit.prevent>
|
|
<el-form ref="ruleFormRef" :model="formInventory" :rules="rules" @submit.prevent>
|
|
|
<el-form-item label="套餐名">
|
|
<el-form-item label="套餐名">
|
|
|
{{ formInventory.name }}
|
|
{{ formInventory.name }}
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item label="剩余库存"> {{ formInventory.singleQty }}张 </el-form-item>
|
|
<el-form-item label="剩余库存"> {{ formInventory.singleQty }}张 </el-form-item>
|
|
|
<el-form-item label="修改库存" prop="newInventory">
|
|
<el-form-item label="修改库存" prop="newInventory">
|
|
|
- <el-input v-model="formInventory.newInventory" placeholder="请输入" />
|
|
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="formInventory.newInventory"
|
|
|
|
|
+ placeholder="请输入"
|
|
|
|
|
+ inputmode="numeric"
|
|
|
|
|
+ pattern="[0-9]*"
|
|
|
|
|
+ autocomplete="off"
|
|
|
|
|
+ @focus="onInventoryInputFocus"
|
|
|
|
|
+ />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-form>
|
|
</el-form>
|
|
|
<template #footer>
|
|
<template #footer>
|
|
@@ -160,7 +110,7 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="tsx" name="voucherManagement">
|
|
<script setup lang="tsx" name="voucherManagement">
|
|
|
-import { computed, onActivated, onMounted, reactive, ref, watch } from "vue";
|
|
|
|
|
|
|
+import { computed, nextTick, onActivated, onMounted, reactive, ref, watch } from "vue";
|
|
|
import { useRouter, useRoute } from "vue-router";
|
|
import { useRouter, useRoute } from "vue-router";
|
|
|
import type { FormInstance, FormRules } from "element-plus";
|
|
import type { FormInstance, FormRules } from "element-plus";
|
|
|
import { ElMessage } from "element-plus";
|
|
import { ElMessage } from "element-plus";
|
|
@@ -168,7 +118,7 @@ import ProTable from "@/components/ProTable/index.vue";
|
|
|
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
|
|
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
|
|
|
import { Plus } from "@element-plus/icons-vue";
|
|
import { Plus } from "@element-plus/icons-vue";
|
|
|
import { delThaliById, getThaliList, updateNum, updateStatus } from "@/api/modules/voucherManagement";
|
|
import { delThaliById, getThaliList, updateNum, updateStatus } from "@/api/modules/voucherManagement";
|
|
|
-import { delCouponById, updateCouponSingleQty, updateCouponStatus } from "@/api/modules/couponManagement";
|
|
|
|
|
|
|
+import { delCouponById, getStoreAllCouponList, updateCouponSingleQty, updateCouponStatus } from "@/api/modules/couponManagement";
|
|
|
import { ElMessageBox } from "element-plus/es";
|
|
import { ElMessageBox } from "element-plus/es";
|
|
|
import { localGet, usePermission } from "@/utils";
|
|
import { localGet, usePermission } from "@/utils";
|
|
|
import { formatCurrency } from "@/utils/formatCurrency";
|
|
import { formatCurrency } from "@/utils/formatCurrency";
|
|
@@ -232,9 +182,27 @@ const statusEnum = [
|
|
|
{ label: "已结束", value: "7" }
|
|
{ label: "已结束", value: "7" }
|
|
|
];
|
|
];
|
|
|
const statusEnumY = [
|
|
const statusEnumY = [
|
|
|
- { label: "草稿", value: "3" },
|
|
|
|
|
|
|
+ { label: "未开始", value: "2" },
|
|
|
|
|
+ { label: "进行中", value: "0" },
|
|
|
|
|
+ { label: "已下架", value: "3" },
|
|
|
|
|
+ { label: "已结束", value: "1" },
|
|
|
|
|
+ { label: "已清库", value: "4" }
|
|
|
|
|
+];
|
|
|
|
|
+// 优惠券状态 Tab 选项(不含草稿)
|
|
|
|
|
+const couponStatusTabOptions = [
|
|
|
|
|
+ { label: "全部", value: "0" },
|
|
|
{ label: "进行中", value: "1" },
|
|
{ label: "进行中", value: "1" },
|
|
|
- { label: "已结束", value: "2" }
|
|
|
|
|
|
|
+ // { label: "草稿", value: "3" },
|
|
|
|
|
+ { label: "已结束", value: "2" },
|
|
|
|
|
+ { label: "已下架", value: "5" },
|
|
|
|
|
+ { label: "未开始", value: "4" },
|
|
|
|
|
+ { label: "已清库", value: "6" }
|
|
|
|
|
+];
|
|
|
|
|
+const couponStatusTab = ref("0");
|
|
|
|
|
+// 优惠券类型枚举(满减券、折扣券)
|
|
|
|
|
+const couponTypeEnum = [
|
|
|
|
|
+ { label: "满减券", value: "1" },
|
|
|
|
|
+ { label: "折扣券", value: "2" }
|
|
|
];
|
|
];
|
|
|
// ProTable 实例(需要在使用它的地方之前定义)
|
|
// ProTable 实例(需要在使用它的地方之前定义)
|
|
|
const proTable = ref<ProTableInstance>();
|
|
const proTable = ref<ProTableInstance>();
|
|
@@ -291,22 +259,14 @@ const voucherColumns = reactive<ColumnProps<any>[]>([
|
|
|
{ prop: "operation", label: "操作", fixed: "right", width: 330 }
|
|
{ prop: "operation", label: "操作", fixed: "right", width: 330 }
|
|
|
]);
|
|
]);
|
|
|
|
|
|
|
|
-// 优惠券表格列配置
|
|
|
|
|
|
|
+// 优惠券表格列配置(参考商家端:优惠券名称、剩余库存、结束时间、状态、类型、操作)
|
|
|
const couponColumns = reactive<ColumnProps<any>[]>([
|
|
const couponColumns = reactive<ColumnProps<any>[]>([
|
|
|
{
|
|
{
|
|
|
prop: "name",
|
|
prop: "name",
|
|
|
- label: "券名称",
|
|
|
|
|
|
|
+ label: "优惠券名称",
|
|
|
search: {
|
|
search: {
|
|
|
- el: "input"
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- prop: "quantityClaimed",
|
|
|
|
|
- label: "已领",
|
|
|
|
|
- render: scope => {
|
|
|
|
|
- return scope.row.quantityClaimed === null || scope.row.quantityClaimed === undefined || scope.row.quantityClaimed === ""
|
|
|
|
|
- ? 0
|
|
|
|
|
- : scope.row.quantityClaimed;
|
|
|
|
|
|
|
+ el: "input",
|
|
|
|
|
+ props: { placeholder: "请输入" }
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
@@ -315,7 +275,7 @@ const couponColumns = reactive<ColumnProps<any>[]>([
|
|
|
render: scope => {
|
|
render: scope => {
|
|
|
return scope.row.singleQty === null || scope.row.singleQty === undefined || scope.row.singleQty === ""
|
|
return scope.row.singleQty === null || scope.row.singleQty === undefined || scope.row.singleQty === ""
|
|
|
? 0
|
|
? 0
|
|
|
- : scope.row.singleQty + "张";
|
|
|
|
|
|
|
+ : scope.row.singleQty;
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
@@ -326,21 +286,21 @@ const couponColumns = reactive<ColumnProps<any>[]>([
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
|
- prop: "couponStatus",
|
|
|
|
|
- label: "状态",
|
|
|
|
|
- isShow: false,
|
|
|
|
|
|
|
+ prop: "status",
|
|
|
|
|
+ label: "状态"
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ prop: "couponType",
|
|
|
|
|
+ label: "类型",
|
|
|
search: {
|
|
search: {
|
|
|
el: "select",
|
|
el: "select",
|
|
|
props: { placeholder: "请选择" }
|
|
props: { placeholder: "请选择" }
|
|
|
},
|
|
},
|
|
|
- enum: statusEnumY,
|
|
|
|
|
- fieldNames: { label: "label", value: "value" }
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- prop: "status",
|
|
|
|
|
- label: "状态"
|
|
|
|
|
|
|
+ enum: couponTypeEnum,
|
|
|
|
|
+ fieldNames: { label: "label", value: "value" },
|
|
|
|
|
+ render: (scope: any) => getCouponTypeLabel(scope.row.couponType)
|
|
|
},
|
|
},
|
|
|
- { prop: "operation", label: "操作", fixed: "right", width: 330 }
|
|
|
|
|
|
|
+ { prop: "operation", label: "操作", fixed: "right", width: 280 }
|
|
|
]);
|
|
]);
|
|
|
|
|
|
|
|
// 根据当前选中的tab动态返回列配置
|
|
// 根据当前选中的tab动态返回列配置
|
|
@@ -374,47 +334,40 @@ const CO_STATUS = {
|
|
|
草稿: 5
|
|
草稿: 5
|
|
|
} as const;
|
|
} as const;
|
|
|
|
|
|
|
|
-// 代金券操作按钮权限配置:定义每个操作按钮在哪些状态下显示 草稿单独判断
|
|
|
|
|
-const VOUCHER_OPERATION_PERMISSIONS = {
|
|
|
|
|
- // 查看详情:待审核、未开始、审核拒绝、进行中、已售罄、已下架
|
|
|
|
|
- 查看详情: [VO_STATUS.待审核, VO_STATUS.未开始, VO_STATUS.审核拒绝, VO_STATUS.进行中, VO_STATUS.已售罄, VO_STATUS.已下架],
|
|
|
|
|
- // 上架:未开始、已下架
|
|
|
|
|
- 上架: [VO_STATUS.未开始, VO_STATUS.已下架],
|
|
|
|
|
- // 下架:进行中
|
|
|
|
|
- 下架: [VO_STATUS.进行中],
|
|
|
|
|
- // 修改库存:未开始、进行中、已售罄
|
|
|
|
|
- 修改库存: [VO_STATUS.未开始, VO_STATUS.进行中, VO_STATUS.已售罄],
|
|
|
|
|
- // 编辑:审核拒绝、已售罄、已下架、已结束
|
|
|
|
|
- 编辑: [VO_STATUS.审核拒绝, VO_STATUS.已售罄, VO_STATUS.已下架, VO_STATUS.已结束],
|
|
|
|
|
- // 删除:未开始、审核拒绝、已售罄、已结束
|
|
|
|
|
- 删除: [VO_STATUS.未开始, VO_STATUS.审核拒绝, VO_STATUS.已售罄, VO_STATUS.已结束],
|
|
|
|
|
- // 查看拒绝原因:审核拒绝
|
|
|
|
|
- 查看拒绝原因: [VO_STATUS.审核拒绝]
|
|
|
|
|
-} as const;
|
|
|
|
|
-
|
|
|
|
|
-// 优惠券操作按钮权限配置
|
|
|
|
|
-const COUPON_OPERATION_PERMISSIONS = {
|
|
|
|
|
- // 查看详情:草稿、未开始、进行中、已下架、已结束、已售罄
|
|
|
|
|
- 查看详情: [CO_STATUS.草稿, CO_STATUS.未开始, CO_STATUS.进行中, CO_STATUS.已下架, CO_STATUS.已结束, CO_STATUS.已售罄],
|
|
|
|
|
- // 上架:未开始、已下架
|
|
|
|
|
- 上架: [CO_STATUS.未开始, CO_STATUS.已下架],
|
|
|
|
|
- // 下架:进行中
|
|
|
|
|
- 下架: [CO_STATUS.进行中],
|
|
|
|
|
- // 编辑:草稿、未开始、进行中、已下架、已结束、已售罄
|
|
|
|
|
- 编辑: [CO_STATUS.草稿, CO_STATUS.未开始, CO_STATUS.进行中, CO_STATUS.已下架, CO_STATUS.已结束, CO_STATUS.已售罄],
|
|
|
|
|
- // 删除:草稿、已结束、已售罄
|
|
|
|
|
- 删除: [CO_STATUS.草稿, CO_STATUS.已结束, CO_STATUS.已售罄]
|
|
|
|
|
-} as const;
|
|
|
|
|
|
|
+// 按「状态 → 可执行操作」配置,与产品表一致,一目了然
|
|
|
|
|
+// 代金券:各状态下的操作列表(草稿用 dataType==1 单独判断)
|
|
|
|
|
+const VOUCHER_ACTIONS_BY_STATUS: Record<number, string[]> = {
|
|
|
|
|
+ [VO_STATUS.待审核]: ["查看详情", "查看拒绝原因"],
|
|
|
|
|
+ [VO_STATUS.未开始]: ["查看详情", "上架", "修改库存", "删除"],
|
|
|
|
|
+ [VO_STATUS.审核拒绝]: ["查看详情", "编辑", "删除", "查看拒绝原因"],
|
|
|
|
|
+ [VO_STATUS.进行中]: ["查看详情", "下架", "修改库存"],
|
|
|
|
|
+ [VO_STATUS.已售罄]: ["查看详情", "编辑", "修改库存", "删除"],
|
|
|
|
|
+ [VO_STATUS.已下架]: ["查看详情", "上架", "编辑", "删除"],
|
|
|
|
|
+ [VO_STATUS.已结束]: ["编辑", "删除"]
|
|
|
|
|
+};
|
|
|
|
|
+// 代金券草稿(dataType==1)仅显示:编辑、删除
|
|
|
|
|
+const VOUCHER_DRAFT_ACTIONS = ["编辑", "删除"];
|
|
|
|
|
|
|
|
-// 判断按钮是否显示的工具函数
|
|
|
|
|
-const canShowButton = (status: number, allowedStatuses: readonly number[]) => {
|
|
|
|
|
- return allowedStatuses.includes(status);
|
|
|
|
|
|
|
+// 优惠券:各状态下的操作列表(完全按产品表)
|
|
|
|
|
+const COUPON_ACTIONS_BY_STATUS: Record<number, string[]> = {
|
|
|
|
|
+ [CO_STATUS.草稿]: ["查看详情", "编辑", "删除"],
|
|
|
|
|
+ [CO_STATUS.未开始]: ["查看详情", "修改库存"],
|
|
|
|
|
+ [CO_STATUS.进行中]: ["下架", "查看详情", "修改库存"],
|
|
|
|
|
+ [CO_STATUS.已下架]: ["上架", "查看详情", "修改库存"],
|
|
|
|
|
+ [CO_STATUS.已结束]: ["查看详情", "删除"],
|
|
|
|
|
+ [CO_STATUS.已售罄]: ["查看详情", "编辑", "删除"]
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-// 根据当前tab获取操作权限配置
|
|
|
|
|
-const currentOperationPermissions = computed(() => {
|
|
|
|
|
- return activeName.value === "1" ? VOUCHER_OPERATION_PERMISSIONS : COUPON_OPERATION_PERMISSIONS;
|
|
|
|
|
-});
|
|
|
|
|
|
|
+/** 判断当前行是否显示某操作按钮(代金券/优惠券通用) */
|
|
|
|
|
+const canShowAction = (row: any, actionName: string): boolean => {
|
|
|
|
|
+ if (activeName.value === "1") {
|
|
|
|
|
+ if (row.dataType === 1) return VOUCHER_DRAFT_ACTIONS.includes(actionName);
|
|
|
|
|
+ const actions = VOUCHER_ACTIONS_BY_STATUS[row.status];
|
|
|
|
|
+ return actions != null && actions.includes(actionName);
|
|
|
|
|
+ }
|
|
|
|
|
+ const actions = COUPON_ACTIONS_BY_STATUS[row.status];
|
|
|
|
|
+ return actions != null && actions.includes(actionName);
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
// 判断是否为代金券
|
|
// 判断是否为代金券
|
|
|
const isVoucher = computed(() => activeName.value === "1");
|
|
const isVoucher = computed(() => activeName.value === "1");
|
|
@@ -424,10 +377,8 @@ const isCoupon = computed(() => activeName.value === "2");
|
|
|
|
|
|
|
|
// 获取状态标签
|
|
// 获取状态标签
|
|
|
const getStatusLabel = (status: any) => {
|
|
const getStatusLabel = (status: any) => {
|
|
|
- // 根据当前选中的tab选择对应的状态枚举
|
|
|
|
|
- const statusEnum = CO_STATUS;
|
|
|
|
|
- // 从状态枚举中查找对应的标签
|
|
|
|
|
- for (const [label, value] of Object.entries(statusEnum)) {
|
|
|
|
|
|
|
+ const statusEnumMap = CO_STATUS;
|
|
|
|
|
+ for (const [label, value] of Object.entries(statusEnumMap)) {
|
|
|
if (value === status) {
|
|
if (value === status) {
|
|
|
return label;
|
|
return label;
|
|
|
}
|
|
}
|
|
@@ -435,11 +386,19 @@ const getStatusLabel = (status: any) => {
|
|
|
return "--";
|
|
return "--";
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
|
|
|
|
|
|
|
+// 优惠券类型展示(满减券/折扣券)
|
|
|
|
|
+const getCouponTypeLabel = (type: number | string) => {
|
|
|
|
|
+ const t = type === undefined || type === null ? "" : String(type);
|
|
|
|
|
+ const item = couponTypeEnum.find(e => e.value === t);
|
|
|
|
|
+ return item ? item.label : "--";
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 如果表格需要初始化请求参数,直接定义传给 ProTable
|
|
|
|
|
+// 注意:不用 couponType,避免与搜索项「类型」(满减券/折扣券) 冲突,用 listType 表示 代金券(1)/优惠券(2)
|
|
|
const initParam = reactive({
|
|
const initParam = reactive({
|
|
|
storeId: localGet("createdId") || "",
|
|
storeId: localGet("createdId") || "",
|
|
|
groupType: localGet("businessSection") || "1",
|
|
groupType: localGet("businessSection") || "1",
|
|
|
- couponType: activeName
|
|
|
|
|
|
|
+ listType: activeName
|
|
|
});
|
|
});
|
|
|
const type = ref(false);
|
|
const type = ref(false);
|
|
|
const typeCoupon = ref(false);
|
|
const typeCoupon = ref(false);
|
|
@@ -490,31 +449,29 @@ watch(
|
|
|
{ immediate: false }
|
|
{ immediate: false }
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
-// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
|
|
|
|
|
-// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
|
|
|
|
|
|
|
+// dataCallback 是对于返回的表格数据做处理
|
|
|
const dataCallback = (data: any) => {
|
|
const dataCallback = (data: any) => {
|
|
|
- // 代金券从 couponList.records 取值,优惠券从 discountList.records 取值
|
|
|
|
|
if (activeName.value === "1") {
|
|
if (activeName.value === "1") {
|
|
|
- // 代金券
|
|
|
|
|
return {
|
|
return {
|
|
|
list: data.couponList?.records || [],
|
|
list: data.couponList?.records || [],
|
|
|
total: data.couponList?.total || 0
|
|
total: data.couponList?.total || 0
|
|
|
};
|
|
};
|
|
|
} else {
|
|
} else {
|
|
|
- // 优惠券
|
|
|
|
|
|
|
+ // 优惠券:新接口 getStoreAllCouponList 返回格式兼容 data.data 或 data.records
|
|
|
|
|
+ const raw = data?.data ?? data;
|
|
|
return {
|
|
return {
|
|
|
- list: data.discountList?.records || [],
|
|
|
|
|
- total: data.discountList?.total || 0
|
|
|
|
|
|
|
+ list: raw?.records ?? raw?.list ?? [],
|
|
|
|
|
+ total: raw?.total ?? 0
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
|
|
// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
|
|
|
-// 默认不做操作就直接在 ProTable 组件上绑定 :requestApi="getUserList"
|
|
|
|
|
const getTableList = (params: any) => {
|
|
const getTableList = (params: any) => {
|
|
|
let newParams = JSON.parse(JSON.stringify(params));
|
|
let newParams = JSON.parse(JSON.stringify(params));
|
|
|
if (activeName.value === "1") {
|
|
if (activeName.value === "1") {
|
|
|
- // 代金券
|
|
|
|
|
|
|
+ // 代金券:使用 voucherManagement 接口,listType 即 代金券/优惠券 区分
|
|
|
|
|
+ newParams.couponType = newParams.listType;
|
|
|
if (newParams.status === "0") {
|
|
if (newParams.status === "0") {
|
|
|
newParams.dataType = 1; // 草稿
|
|
newParams.dataType = 1; // 草稿
|
|
|
} else if (newParams.status) {
|
|
} else if (newParams.status) {
|
|
@@ -522,12 +479,19 @@ const getTableList = (params: any) => {
|
|
|
} else {
|
|
} else {
|
|
|
newParams.dataType = 2;
|
|
newParams.dataType = 2;
|
|
|
}
|
|
}
|
|
|
|
|
+ return getThaliList(newParams);
|
|
|
} else {
|
|
} else {
|
|
|
- // 优惠券
|
|
|
|
|
- delete newParams.dataType;
|
|
|
|
|
- newParams.couponsFromType = 1;
|
|
|
|
|
|
|
+ // 优惠券:使用 getStoreAllCouponList,搜索项 name、couponType 需一并传入
|
|
|
|
|
+ return getStoreAllCouponList({
|
|
|
|
|
+ storeId: newParams.storeId || localGet("createdId") || "",
|
|
|
|
|
+ tab: couponStatusTab.value || "",
|
|
|
|
|
+ size: newParams.pageSize || 10,
|
|
|
|
|
+ page: newParams.pageNum || 1,
|
|
|
|
|
+ couponName: newParams.name ?? "",
|
|
|
|
|
+ couponType: newParams.couponType ?? "",
|
|
|
|
|
+ couponsFromType: 1
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
- return getThaliList(newParams);
|
|
|
|
|
};
|
|
};
|
|
|
const newGroupBuying = () => {
|
|
const newGroupBuying = () => {
|
|
|
router.push(`/ticketManagement/newVoucher?type=add`);
|
|
router.push(`/ticketManagement/newVoucher?type=add`);
|
|
@@ -584,9 +548,14 @@ const deleteRow = (row: any) => {
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
// Tab切换处理
|
|
// Tab切换处理
|
|
|
-const handleClick = () => {
|
|
|
|
|
- // initParam 中的 couponType 是响应式的,当 activeName 变化时会自动触发 ProTable 内部的 watch 监听,无需手动调用
|
|
|
|
|
- // proTable.value?.getTableList();
|
|
|
|
|
|
|
+const handleClick = () => {};
|
|
|
|
|
+
|
|
|
|
|
+// 优惠券状态 Tab 切换
|
|
|
|
|
+// 优惠券状态 Tab 切换(tab-click 触发时 v-model 尚未更新,用 nextTick 等绑定更新后再请求)
|
|
|
|
|
+const onCouponStatusTabChange = () => {
|
|
|
|
|
+ nextTick(() => {
|
|
|
|
|
+ proTable.value?.getTableList();
|
|
|
|
|
+ });
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// 修改状态(上架/下架)
|
|
// 修改状态(上架/下架)
|
|
@@ -594,14 +563,14 @@ const changeTypes = async (row: any, status: number) => {
|
|
|
if (isVoucher.value) {
|
|
if (isVoucher.value) {
|
|
|
// 代金券上架/下架逻辑
|
|
// 代金券上架/下架逻辑
|
|
|
const res = await updateStatus({ id: row.id, status: status, approvalComments: "" });
|
|
const res = await updateStatus({ id: row.id, status: status, approvalComments: "" });
|
|
|
- if (res && res.code == 200) {
|
|
|
|
|
|
|
+ if (res && Number((res as any).code) === 200) {
|
|
|
ElMessage.success("操作成功");
|
|
ElMessage.success("操作成功");
|
|
|
proTable.value?.getTableList();
|
|
proTable.value?.getTableList();
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
// 优惠券上架/下架逻辑
|
|
// 优惠券上架/下架逻辑
|
|
|
const res = await updateCouponStatus({ counponId: row.id });
|
|
const res = await updateCouponStatus({ counponId: row.id });
|
|
|
- if (res && res.code == 200) {
|
|
|
|
|
|
|
+ if (res && Number((res as any).code) === 200) {
|
|
|
ElMessage.success("操作成功");
|
|
ElMessage.success("操作成功");
|
|
|
proTable.value?.getTableList();
|
|
proTable.value?.getTableList();
|
|
|
}
|
|
}
|
|
@@ -629,14 +598,14 @@ const handleSubmit = async () => {
|
|
|
};
|
|
};
|
|
|
if (isVoucher.value) {
|
|
if (isVoucher.value) {
|
|
|
const res = await updateNum(params);
|
|
const res = await updateNum(params);
|
|
|
- if (res && res.code == 200) {
|
|
|
|
|
|
|
+ if (res && Number((res as any).code) === 200) {
|
|
|
ElMessage.success("修改成功");
|
|
ElMessage.success("修改成功");
|
|
|
closeDialog();
|
|
closeDialog();
|
|
|
proTable.value?.getTableList();
|
|
proTable.value?.getTableList();
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
const res = await updateCouponSingleQty(params);
|
|
const res = await updateCouponSingleQty(params);
|
|
|
- if (res && res.code == 200) {
|
|
|
|
|
|
|
+ if (res && Number((res as any).code) === 200) {
|
|
|
ElMessage.success("修改成功");
|
|
ElMessage.success("修改成功");
|
|
|
closeDialog();
|
|
closeDialog();
|
|
|
proTable.value?.getTableList();
|
|
proTable.value?.getTableList();
|
|
@@ -656,6 +625,16 @@ const closeDialog = () => {
|
|
|
newInventory: ""
|
|
newInventory: ""
|
|
|
};
|
|
};
|
|
|
};
|
|
};
|
|
|
|
|
+
|
|
|
|
|
+// iOS 上输入框获焦时滚动到可视区域,避免键盘遮挡底部按钮
|
|
|
|
|
+const onInventoryInputFocus = (e: Event) => {
|
|
|
|
|
+ const target = e.target as HTMLElement;
|
|
|
|
|
+ if (!target) return;
|
|
|
|
|
+ requestAnimationFrame(() => {
|
|
|
|
|
+ target.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
// 查看拒绝原因
|
|
// 查看拒绝原因
|
|
|
const viewRejectReason = (row: any) => {
|
|
const viewRejectReason = (row: any) => {
|
|
|
rejectReasonData.value = {
|
|
rejectReasonData.value = {
|
|
@@ -671,6 +650,15 @@ const closeRejectReasonDialog = () => {
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
|
|
|
+/* iOS 上修改库存弹窗:避免键盘弹起时遮挡底部,弹窗可滚动 */
|
|
|
|
|
+:deep(.inventory-dialog-ios-fix) {
|
|
|
|
|
+ .el-dialog__body {
|
|
|
|
|
+ max-height: 60vh;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ -webkit-overflow-scrolling: touch;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// 在组件样式中添加
|
|
// 在组件样式中添加
|
|
|
.date-range {
|
|
.date-range {
|
|
|
display: block; // 确保换行生效
|
|
display: block; // 确保换行生效
|
|
@@ -681,14 +669,23 @@ const closeRejectReasonDialog = () => {
|
|
|
.table-header-btn {
|
|
.table-header-btn {
|
|
|
.header-actions {
|
|
.header-actions {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ gap: 12px;
|
|
|
|
|
+ align-items: center;
|
|
|
justify-content: space-between;
|
|
justify-content: space-between;
|
|
|
width: 100%;
|
|
width: 100%;
|
|
|
- .tabs {
|
|
|
|
|
|
|
+ .status-tabs {
|
|
|
flex: 0 0 auto;
|
|
flex: 0 0 auto;
|
|
|
|
|
+ :deep(.el-tabs__header) {
|
|
|
|
|
+ margin-bottom: 0;
|
|
|
|
|
+ }
|
|
|
:deep(.el-tabs__nav-wrap::after) {
|
|
:deep(.el-tabs__nav-wrap::after) {
|
|
|
height: 0;
|
|
height: 0;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ .button {
|
|
|
|
|
+ margin-bottom: 0;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
.action-buttons {
|
|
.action-buttons {
|