Kaynağa Gözat

建立页面与路由

congxuesong 1 ay önce
ebeveyn
işleme
8c2677b2b0

+ 204 - 150
src/assets/json/authMenuList.json

@@ -21,7 +21,7 @@
       "redirect": "/store/storeUser/index",
       "meta": {
         "icon": "Shop",
-        "title": "商家管理",
+        "title": "Demo",
         "isLink": "",
         "isHide": false,
         "isFull": false,
@@ -30,141 +30,6 @@
       },
       "children": [
         {
-          "path": "/store/storeInfo",
-          "name": "storeInfo",
-          "component": "/store/storeUser/index",
-          "meta": {
-            "icon": "ShoppingTrolley",
-            "title": "店铺管理",
-            "isLink": "",
-            "isHide": false,
-            "isFull": false,
-            "isAffix": false,
-            "isKeepAlive": false
-          },
-          "children": [
-            {
-              "path": "/store/storeInfo/storeInfoDetail",
-              "name": "storeInfo/detail",
-              "component": "/store/storeUser/storeInfoDetail",
-              "meta": {
-                "icon": "Menu",
-                "title": "商铺明细信息页面",
-                "activeMenu": "/store/storeInfo",
-                "isLink": "",
-                "isHide": true,
-                "isFull": false,
-                "isAffix": false,
-                "isKeepAlive": false
-              }
-            }
-          ]
-        },
-        {
-          "path": "/store/storeInfo/contractRenewal",
-          "name": "contractRenewal",
-          "component": "/store/storeUser/contractRenewal/index",
-          "meta": {
-            "icon": "ShoppingTrolley",
-            "title": "续约合同",
-            "isLink": "",
-            "isHide": false,
-            "isFull": false,
-            "isAffix": false,
-            "isKeepAlive": false
-          },
-          "children": [
-            {
-              "path": "/store/storeInfo/contractRenewal/detail",
-              "name": "contractRenewal/detail",
-              "component": "/store/storeUser/contractRenewal/detail",
-              "meta": {
-                "icon": "Menu",
-                "title": "续约合同详情",
-                "activeMenu": "/store/storeInfo/contractRenewal",
-                "isLink": "",
-                "isHide": true,
-                "isFull": false,
-                "isAffix": false,
-                "isKeepAlive": false
-              }
-            }
-          ]
-        },
-        {
-          "path": "/store/storeInfo/foodLicence",
-          "name": "foodLicence",
-          "component": "/store/storeUser/foodLicence/index",
-          "meta": {
-            "icon": "ShoppingTrolley",
-            "title": "食品许可证管理",
-            "isLink": "",
-            "isHide": false,
-            "isFull": false,
-            "isAffix": false,
-            "isKeepAlive": false
-          },
-          "children": [
-            {
-              "path": "/store/storeInfo/foodLicence/detail",
-              "name": "foodLicence/detail",
-              "component": "/store/storeUser/foodLicence/detail",
-              "meta": {
-                "icon": "Menu",
-                "title": "食品许可证管理详情",
-                "activeMenu": "/store/storeInfo/foodLicence",
-                "isLink": "",
-                "isHide": true,
-                "isFull": false,
-                "isAffix": false,
-                "isKeepAlive": false
-              }
-            }
-          ]
-        },
-        {
-          "path": "/store/storeInfo/foodLicenceTime",
-          "name": "foodLicenceTime",
-          "component": "/store/storeUser/foodLicence/time",
-          "meta": {
-            "icon": "ShoppingTrolley",
-            "title": "食品许可证到期时间管理",
-            "isLink": "",
-            "isHide": false,
-            "isFull": false,
-            "isAffix": false,
-            "isKeepAlive": false
-          }
-        },
-        {
-          "path": "/store/storeUser",
-          "name": "storeUser",
-          "component": "/store/storeUser/storeUser",
-          "meta": {
-            "icon": "UserFilled",
-            "title": "账号管理",
-            "isLink": "",
-            "isHide": false,
-            "isFull": false,
-            "isAffix": false,
-            "isKeepAlive": false
-          }
-        },
-        {
-          "path": "/store/storeMaturityManagement",
-          "name": "storeMaturityManagement",
-          "component": "/store/storeUser/storeMaturityManagement",
-          "meta": {
-            "icon": "Timer",
-            "title": "商铺到期时间管理",
-            "isLink": "",
-            "isHide": false,
-            "isFull": false,
-            "isAffix": false,
-            "isKeepAlive": false
-          }
-        },
-        {
           "path": "/store/storeUser/storeStaffConfigManagement",
           "name": "storeStaffConfigManagement",
           "component": "/store/storeUser/storeStaffConfigManagement/index",
@@ -177,20 +42,6 @@
             "isAffix": false,
             "isKeepAlive": false
           }
-        },
-        {
-          "path": "/store/holidayManagement",
-          "name": "holidayManagement",
-          "component": "/store/holidayManagement/index",
-          "meta": {
-            "icon": "UserFilled",
-            "title": "节假日管理",
-            "isLink": "",
-            "isHide": false,
-            "isFull": false,
-            "isAffix": false,
-            "isKeepAlive": false
-          }
         }
       ]
     },
@@ -208,6 +59,209 @@
         "isAffix": false,
         "isKeepAlive": false
       }
+    },
+    {
+      "path": "/store/groupPackageManagement",
+      "name": "groupPackageManagement",
+      "component": "/store/groupPackageManagement/index",
+      "meta": {
+        "icon": "ShoppingBag",
+        "title": "团购管理",
+        "isLink": "",
+        "isHide": false,
+        "isFull": false,
+        "isAffix": false,
+        "isKeepAlive": false
+      }
+    },
+    {
+      "path": "/store/groupPackageManagementDetail",
+      "name": "groupPackageManagementDetail",
+      "component": "/store/groupPackageManagement/detail",
+      "meta": {
+        "icon": "Menu",
+        "title": "团购管理详情",
+        "activeMenu": "/store/groupPackageManagement",
+        "isLink": "",
+        "isHide": true,
+        "isFull": false,
+        "isAffix": false,
+        "isKeepAlive": false
+      }
+    },
+    {
+      "path": "/store/couponManagement",
+      "name": "couponManagement",
+      "component": "/store/couponManagement/index",
+      "meta": {
+        "icon": "Ticket",
+        "title": "优惠券管理",
+        "isLink": "",
+        "isHide": false,
+        "isFull": false,
+        "isAffix": false,
+        "isKeepAlive": false
+      }
+    },
+    {
+      "path": "/store/couponManagementDetail",
+      "name": "couponManagementDetail",
+      "component": "/store/couponManagement/detail",
+      "meta": {
+        "icon": "Menu",
+        "title": "优惠券管理详情",
+        "activeMenu": "/store/couponManagement",
+        "isLink": "",
+        "isHide": true,
+        "isFull": false,
+        "isAffix": false,
+        "isKeepAlive": false
+      }
+    },
+    {
+      "path": "/store/voucherManagement",
+      "name": "voucherManagement",
+      "component": "/store/voucherManagement/index",
+      "meta": {
+        "icon": "Money",
+        "title": "代金券管理",
+        "isLink": "",
+        "isHide": false,
+        "isFull": false,
+        "isAffix": false,
+        "isKeepAlive": false
+      }
+    },
+    {
+      "path": "/store/voucherManagementDetail",
+      "name": "voucherManagementDetail",
+      "component": "/store/voucherManagement/detail",
+      "meta": {
+        "icon": "Menu",
+        "title": "代金券管理详情",
+        "activeMenu": "/store/voucherManagement",
+        "isLink": "",
+        "isHide": true,
+        "isFull": false,
+        "isAffix": false,
+        "isKeepAlive": false
+      }
+    },
+    {
+      "path": "/store/orderManagement",
+      "name": "orderManagement",
+      "component": "/store/orderManagement/index",
+      "meta": {
+        "icon": "Document",
+        "title": "订单管理",
+        "isLink": "",
+        "isHide": false,
+        "isFull": false,
+        "isAffix": false,
+        "isKeepAlive": false
+      }
+    },
+    {
+      "path": "/store/orderManagementDetail",
+      "name": "orderManagementDetail",
+      "component": "/store/orderManagement/detail",
+      "meta": {
+        "icon": "Menu",
+        "title": "订单管理详情",
+        "activeMenu": "/store/orderManagement",
+        "isLink": "",
+        "isHide": true,
+        "isFull": false,
+        "isAffix": false,
+        "isKeepAlive": false
+      }
+    },
+    {
+      "path": "/store/storeDecoration",
+      "name": "storeDecoration",
+      "component": "/store/storeDecoration/index",
+      "meta": {
+        "icon": "Brush",
+        "title": "门店装修",
+        "isLink": "",
+        "isHide": false,
+        "isFull": false,
+        "isAffix": false,
+        "isKeepAlive": false
+      }
+    },
+    {
+      "path": "/store/storeDecorationDetail",
+      "name": "storeDecorationDetail",
+      "component": "/store/storeDecoration/detail",
+      "meta": {
+        "icon": "Menu",
+        "title": "门店装修详情",
+        "activeMenu": "/store/storeDecoration",
+        "isLink": "",
+        "isHide": true,
+        "isFull": false,
+        "isAffix": false,
+        "isKeepAlive": false
+      }
+    },
+    {
+      "path": "/store/licenseManagement",
+      "name": "licenseManagement",
+      "component": "/store/licenseManagement/index",
+      "meta": {
+        "icon": "Files",
+        "title": "证照管理",
+        "isLink": "",
+        "isHide": false,
+        "isFull": false,
+        "isAffix": false,
+        "isKeepAlive": false
+      }
+    },
+    {
+      "path": "/store/licenseManagementDetail",
+      "name": "licenseManagementDetail",
+      "component": "/store/licenseManagement/detail",
+      "meta": {
+        "icon": "Menu",
+        "title": "证照管理详情",
+        "activeMenu": "/store/licenseManagement",
+        "isLink": "",
+        "isHide": true,
+        "isFull": false,
+        "isAffix": false,
+        "isKeepAlive": false
+      }
+    },
+    {
+      "path": "/store/financialManagement",
+      "name": "financialManagement",
+      "component": "/store/financialManagement/index",
+      "meta": {
+        "icon": "CreditCard",
+        "title": "财务管理",
+        "isLink": "",
+        "isHide": false,
+        "isFull": false,
+        "isAffix": false,
+        "isKeepAlive": false
+      }
+    },
+    {
+      "path": "/store/financialManagementDetail",
+      "name": "financialManagementDetail",
+      "component": "/store/financialManagement/detail",
+      "meta": {
+        "icon": "Menu",
+        "title": "财务管理详情",
+        "activeMenu": "/store/financialManagement",
+        "isLink": "",
+        "isHide": true,
+        "isFull": false,
+        "isAffix": false,
+        "isKeepAlive": false
+      }
     }
   ],
   "msg": "成功"

+ 93 - 0
src/views/store/couponManagement/detail.vue

@@ -0,0 +1,93 @@
+<template>
+  <div class="card content-box">
+    <el-form :model="formData" label-width="140px">
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="店铺名称 :">
+            <span>{{ formData.storeName }}</span>
+          </el-form-item>
+          <el-form-item label="名称 :">
+            <span>{{ formData.name }}</span>
+          </el-form-item>
+          <el-form-item label="描述 :">
+            <span>{{ formData.description }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="状态:">
+            <span>{{ getStatusName(formData.status) }}</span>
+          </el-form-item>
+          <el-form-item label="拒绝原因:" v-if="formData.status === '2'">
+            <span>{{ formData.rejectionReason }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row class="text-center" style="margin-top: 20px">
+        <el-col :span="24">
+          <el-button type="primary" @click="goBack"> 确定 </el-button>
+        </el-col>
+      </el-row>
+    </el-form>
+  </div>
+</template>
+
+<script setup lang="tsx" name="couponManagementDetail">
+import { ref, onMounted } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import { getStaffConfigDeatail } from "@/api/modules/staffConfig";
+
+const route = useRoute();
+const router = useRouter();
+
+const formData = ref({});
+
+const id = ref((route.query.id as string) || "");
+
+const getStatusName = (status: string) => {
+  switch (status) {
+    case "0":
+      return "待审核";
+    case "1":
+      return "审核通过";
+    case "2":
+      return "审核拒绝";
+    default:
+      return "未知状态";
+  }
+};
+
+onMounted(async () => {
+  await initData();
+});
+
+const initData = async () => {
+  if (id.value) {
+    try {
+      const response = await getStaffConfigDeatail({ id: id.value });
+      if (response.code === 200) {
+        formData.value = response.data;
+      }
+    } catch (error) {
+      ElMessage.error("获取详情失败");
+    }
+  }
+};
+
+const goBack = () => {
+  router.go(-1);
+};
+</script>
+
+<style lang="scss" scoped>
+.el-form {
+  width: 100%;
+  .text-center {
+    text-align: center;
+  }
+}
+.el-col {
+  box-sizing: border-box;
+  padding-right: 10px;
+}
+</style>

+ 203 - 0
src/views/store/couponManagement/index.vue

@@ -0,0 +1,203 @@
+<template>
+  <div class="table-box">
+    <ProTable ref="proTable" :columns="columns" :request-api="getTableList" :init-param="initParam" :data-callback="dataCallback">
+      <!-- 表格 header 按钮 -->
+      <template #tableHeader="scope">
+        <el-button type="primary" :icon="Download" @click="exportInfoExcel(scope)"> 导出 </el-button>
+      </template>
+      <template #expand="scope">
+        {{ scope.row }}
+      </template>
+      <!-- 表格操作 -->
+      <template #operation="scope">
+        <!-- 审批通过和拒绝按钮仅在状态为0时显示 -->
+        <template v-if="scope.row.status === '0'">
+          <el-button type="primary" link @click="changeTypes(scope.row, 'pass')"> 审核通过 </el-button>
+          <el-button type="primary" link @click="changeTypes(scope.row, '')"> 审核拒绝 </el-button>
+        </template>
+        <el-button type="primary" link @click="toDetail(scope.row)"> 查看详情 </el-button>
+      </template>
+    </ProTable>
+
+    <el-dialog v-model="dialogFormVisible" title="审核拒绝" width="500">
+      <el-form :model="form">
+        <el-form-item label="" label-width="0">
+          <el-input v-model="form.comment" autocomplete="off" type="textarea" maxlength="200" />
+        </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="couponManagement">
+import { ref, reactive, onMounted, onActivated } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import ProTable from "@/components/ProTable/index.vue";
+import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
+import { Download } from "@element-plus/icons-vue";
+import { audit, exportExcelStaffConfig, getStaffConfigList } from "@/api/modules/staffConfig";
+
+const router = useRouter();
+const dialogFormVisible = ref(false);
+const form = reactive({
+  comment: ""
+});
+
+const rowData = ref<any>();
+
+const statusEnum = [
+  { value: "0", label: "待审核" },
+  { value: "1", label: "审核通过" },
+  { value: "2", label: "审核拒绝" }
+];
+// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
+const initParam = reactive({});
+
+// 定义 filterValues
+const filterValues = reactive({});
+
+const getStatusObj = (statusValue: string) => {
+  const statusObj = statusEnum.find(item => item.value === statusValue);
+  if (statusObj) {
+    filterValues.status = statusObj;
+  } else {
+    filterValues.status = "";
+  }
+  return statusObj;
+};
+
+// ProTable 实例
+const proTable = ref<ProTableInstance>();
+
+// 页面加载时触发查询
+onMounted(() => {
+  proTable.value?.getTableList();
+});
+
+// 从其他页面返回时触发查询
+onActivated(() => {
+  proTable.value?.getTableList();
+});
+
+// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
+// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
+const dataCallback = (data: any) => {
+  return {
+    list: data.records,
+    total: data.total
+  };
+};
+
+// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
+// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
+const getTableList = (params: any) => {
+  let newParams = JSON.parse(JSON.stringify(params));
+  return getStaffConfigList(newParams);
+};
+
+// 跳转详情页
+const toDetail = row => {
+  router.push(`/store/couponManagementDetail?id=${row.id}`);
+};
+
+// 表格配置项
+const columns = reactive<ColumnProps<any>[]>([
+  { type: "index", fixed: "left", label: "序号", width: 130 },
+  { prop: "storeName", label: "所属店铺" },
+  { prop: "name", label: "名称" },
+  { prop: "description", label: "描述" },
+  {
+    prop: "status",
+    label: "状态",
+    render: scope => {
+      const statusObj = getStatusObj(scope.row.status);
+      return statusObj ? statusObj.label : "未知状态";
+    },
+    search: {
+      el: "select"
+    },
+    enum: statusEnum,
+    fieldNames: { label: "label", value: "value" }
+  },
+  { prop: "operation", label: "操作", fixed: "right", width: 330 }
+]);
+
+const changeTypes = (row: any, status: string) => {
+  rowData.value = row;
+  if (status === "pass") {
+    handleChangeStatus(row, "1");
+  } else {
+    form.comment = "";
+    dialogFormVisible.value = true;
+  }
+};
+
+const handleChangeStatus = async (row: any, status: string) => {
+  try {
+    let res = await audit({ id: row.id, status: status, rejectionReason: form.comment });
+    if (res.code === 200) {
+      proTable.value?.getTableList();
+      if (status === "2") closeDialog();
+      ElMessage.success("审核成功");
+    }
+  } catch (error) {
+    ElMessage.error("操作失败");
+  }
+};
+
+// 导出信息
+const exportInfoExcel = async scope => {
+  let res;
+  // 获取原始状态值(可能为数字、字符串或 undefined)
+  const rawStatus = proTable.value.searchParam.status;
+  // 转换为字符串(处理 undefined/null 为 "" 或保留原始字符串)
+  const statusParam = rawStatus !== undefined && rawStatus !== null ? String(rawStatus) : undefined;
+  // 将筛选条件作为参数传递给后台
+  res = await exportExcelStaffConfig({ status: statusParam });
+  if (res.code === 200) {
+    if (!res.data) {
+      ElMessage.error("暂无可下载数据");
+      return;
+    }
+    const exportFile = document.createElement("a");
+    exportFile.style.display = "none";
+    exportFile.download = `优惠券管理.xlsx`;
+    exportFile.href = `${res.data}?timestamp=${new Date().getTime()}`; // 添加时间戳防止缓存
+    document.body.appendChild(exportFile);
+    exportFile.click();
+    document.body.removeChild(exportFile);
+    ElMessage.success("下载成功");
+  }
+};
+
+// 弹窗提交
+const handleSubmit = () => {
+  if (!form.comment) {
+    ElMessage.error("请输入审批意见");
+    return;
+  }
+  handleChangeStatus(rowData.value, "2");
+};
+// 关闭弹窗;
+const closeDialog = () => {
+  dialogFormVisible.value = false;
+  form.comment = "";
+};
+</script>
+
+<style lang="scss" scoped>
+// 在组件样式中添加
+.date-range {
+  display: block; // 确保换行生效
+  padding: 0 8px; // 可选:增加内边距
+  word-wrap: break-word; // 长单词内换行
+  white-space: normal; // 允许自然换行
+}
+</style>

+ 93 - 0
src/views/store/financialManagement/detail.vue

@@ -0,0 +1,93 @@
+<template>
+  <div class="card content-box">
+    <el-form :model="formData" label-width="140px">
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="店铺名称 :">
+            <span>{{ formData.storeName }}</span>
+          </el-form-item>
+          <el-form-item label="名称 :">
+            <span>{{ formData.name }}</span>
+          </el-form-item>
+          <el-form-item label="描述 :">
+            <span>{{ formData.description }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="状态:">
+            <span>{{ getStatusName(formData.status) }}</span>
+          </el-form-item>
+          <el-form-item label="拒绝原因:" v-if="formData.status === '2'">
+            <span>{{ formData.rejectionReason }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row class="text-center" style="margin-top: 20px">
+        <el-col :span="24">
+          <el-button type="primary" @click="goBack"> 确定 </el-button>
+        </el-col>
+      </el-row>
+    </el-form>
+  </div>
+</template>
+
+<script setup lang="tsx" name="financialManagementDetail">
+import { ref, onMounted } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import { getStaffConfigDeatail } from "@/api/modules/staffConfig";
+
+const route = useRoute();
+const router = useRouter();
+
+const formData = ref({});
+
+const id = ref((route.query.id as string) || "");
+
+const getStatusName = (status: string) => {
+  switch (status) {
+    case "0":
+      return "待审核";
+    case "1":
+      return "审核通过";
+    case "2":
+      return "审核拒绝";
+    default:
+      return "未知状态";
+  }
+};
+
+onMounted(async () => {
+  await initData();
+});
+
+const initData = async () => {
+  if (id.value) {
+    try {
+      const response = await getStaffConfigDeatail({ id: id.value });
+      if (response.code === 200) {
+        formData.value = response.data;
+      }
+    } catch (error) {
+      ElMessage.error("获取详情失败");
+    }
+  }
+};
+
+const goBack = () => {
+  router.go(-1);
+};
+</script>
+
+<style lang="scss" scoped>
+.el-form {
+  width: 100%;
+  .text-center {
+    text-align: center;
+  }
+}
+.el-col {
+  box-sizing: border-box;
+  padding-right: 10px;
+}
+</style>

+ 203 - 0
src/views/store/financialManagement/index.vue

@@ -0,0 +1,203 @@
+<template>
+  <div class="table-box">
+    <ProTable ref="proTable" :columns="columns" :request-api="getTableList" :init-param="initParam" :data-callback="dataCallback">
+      <!-- 表格 header 按钮 -->
+      <template #tableHeader="scope">
+        <el-button type="primary" :icon="Download" @click="exportInfoExcel(scope)"> 导出 </el-button>
+      </template>
+      <template #expand="scope">
+        {{ scope.row }}
+      </template>
+      <!-- 表格操作 -->
+      <template #operation="scope">
+        <!-- 审批通过和拒绝按钮仅在状态为0时显示 -->
+        <template v-if="scope.row.status === '0'">
+          <el-button type="primary" link @click="changeTypes(scope.row, 'pass')"> 审核通过 </el-button>
+          <el-button type="primary" link @click="changeTypes(scope.row, '')"> 审核拒绝 </el-button>
+        </template>
+        <el-button type="primary" link @click="toDetail(scope.row)"> 查看详情 </el-button>
+      </template>
+    </ProTable>
+
+    <el-dialog v-model="dialogFormVisible" title="审核拒绝" width="500">
+      <el-form :model="form">
+        <el-form-item label="" label-width="0">
+          <el-input v-model="form.comment" autocomplete="off" type="textarea" maxlength="200" />
+        </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="financialManagement">
+import { ref, reactive, onMounted, onActivated } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import ProTable from "@/components/ProTable/index.vue";
+import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
+import { Download } from "@element-plus/icons-vue";
+import { audit, exportExcelStaffConfig, getStaffConfigList } from "@/api/modules/staffConfig";
+
+const router = useRouter();
+const dialogFormVisible = ref(false);
+const form = reactive({
+  comment: ""
+});
+
+const rowData = ref<any>();
+
+const statusEnum = [
+  { value: "0", label: "待审核" },
+  { value: "1", label: "审核通过" },
+  { value: "2", label: "审核拒绝" }
+];
+// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
+const initParam = reactive({});
+
+// 定义 filterValues
+const filterValues = reactive({});
+
+const getStatusObj = (statusValue: string) => {
+  const statusObj = statusEnum.find(item => item.value === statusValue);
+  if (statusObj) {
+    filterValues.status = statusObj;
+  } else {
+    filterValues.status = "";
+  }
+  return statusObj;
+};
+
+// ProTable 实例
+const proTable = ref<ProTableInstance>();
+
+// 页面加载时触发查询
+onMounted(() => {
+  proTable.value?.getTableList();
+});
+
+// 从其他页面返回时触发查询
+onActivated(() => {
+  proTable.value?.getTableList();
+});
+
+// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
+// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
+const dataCallback = (data: any) => {
+  return {
+    list: data.records,
+    total: data.total
+  };
+};
+
+// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
+// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
+const getTableList = (params: any) => {
+  let newParams = JSON.parse(JSON.stringify(params));
+  return getStaffConfigList(newParams);
+};
+
+// 跳转详情页
+const toDetail = row => {
+  router.push(`/store/financialManagementDetail?id=${row.id}`);
+};
+
+// 表格配置项
+const columns = reactive<ColumnProps<any>[]>([
+  { type: "index", fixed: "left", label: "序号", width: 130 },
+  { prop: "storeName", label: "所属店铺" },
+  { prop: "name", label: "名称" },
+  { prop: "description", label: "描述" },
+  {
+    prop: "status",
+    label: "状态",
+    render: scope => {
+      const statusObj = getStatusObj(scope.row.status);
+      return statusObj ? statusObj.label : "未知状态";
+    },
+    search: {
+      el: "select"
+    },
+    enum: statusEnum,
+    fieldNames: { label: "label", value: "value" }
+  },
+  { prop: "operation", label: "操作", fixed: "right", width: 330 }
+]);
+
+const changeTypes = (row: any, status: string) => {
+  rowData.value = row;
+  if (status === "pass") {
+    handleChangeStatus(row, "1");
+  } else {
+    form.comment = "";
+    dialogFormVisible.value = true;
+  }
+};
+
+const handleChangeStatus = async (row: any, status: string) => {
+  try {
+    let res = await audit({ id: row.id, status: status, rejectionReason: form.comment });
+    if (res.code === 200) {
+      proTable.value?.getTableList();
+      if (status === "2") closeDialog();
+      ElMessage.success("审核成功");
+    }
+  } catch (error) {
+    ElMessage.error("操作失败");
+  }
+};
+
+// 导出信息
+const exportInfoExcel = async scope => {
+  let res;
+  // 获取原始状态值(可能为数字、字符串或 undefined)
+  const rawStatus = proTable.value.searchParam.status;
+  // 转换为字符串(处理 undefined/null 为 "" 或保留原始字符串)
+  const statusParam = rawStatus !== undefined && rawStatus !== null ? String(rawStatus) : undefined;
+  // 将筛选条件作为参数传递给后台
+  res = await exportExcelStaffConfig({ status: statusParam });
+  if (res.code === 200) {
+    if (!res.data) {
+      ElMessage.error("暂无可下载数据");
+      return;
+    }
+    const exportFile = document.createElement("a");
+    exportFile.style.display = "none";
+    exportFile.download = `财务管理.xlsx`;
+    exportFile.href = `${res.data}?timestamp=${new Date().getTime()}`; // 添加时间戳防止缓存
+    document.body.appendChild(exportFile);
+    exportFile.click();
+    document.body.removeChild(exportFile);
+    ElMessage.success("下载成功");
+  }
+};
+
+// 弹窗提交
+const handleSubmit = () => {
+  if (!form.comment) {
+    ElMessage.error("请输入审批意见");
+    return;
+  }
+  handleChangeStatus(rowData.value, "2");
+};
+// 关闭弹窗;
+const closeDialog = () => {
+  dialogFormVisible.value = false;
+  form.comment = "";
+};
+</script>
+
+<style lang="scss" scoped>
+// 在组件样式中添加
+.date-range {
+  display: block; // 确保换行生效
+  padding: 0 8px; // 可选:增加内边距
+  word-wrap: break-word; // 长单词内换行
+  white-space: normal; // 允许自然换行
+}
+</style>

+ 93 - 0
src/views/store/groupPackageManagement/detail.vue

@@ -0,0 +1,93 @@
+<template>
+  <div class="card content-box">
+    <el-form :model="formData" label-width="140px">
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="店铺名称 :">
+            <span>{{ formData.storeName }}</span>
+          </el-form-item>
+          <el-form-item label="名称 :">
+            <span>{{ formData.name }}</span>
+          </el-form-item>
+          <el-form-item label="描述 :">
+            <span>{{ formData.description }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="状态:">
+            <span>{{ getStatusName(formData.status) }}</span>
+          </el-form-item>
+          <el-form-item label="拒绝原因:" v-if="formData.status === '2'">
+            <span>{{ formData.rejectionReason }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row class="text-center" style="margin-top: 20px">
+        <el-col :span="24">
+          <el-button type="primary" @click="goBack"> 确定 </el-button>
+        </el-col>
+      </el-row>
+    </el-form>
+  </div>
+</template>
+
+<script setup lang="tsx" name="groupPackageManagementDetail">
+import { ref, onMounted } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import { getStaffConfigDeatail } from "@/api/modules/staffConfig";
+
+const route = useRoute();
+const router = useRouter();
+
+const formData = ref({});
+
+const id = ref((route.query.id as string) || "");
+
+const getStatusName = (status: string) => {
+  switch (status) {
+    case "0":
+      return "待审核";
+    case "1":
+      return "审核通过";
+    case "2":
+      return "审核拒绝";
+    default:
+      return "未知状态";
+  }
+};
+
+onMounted(async () => {
+  await initData();
+});
+
+const initData = async () => {
+  if (id.value) {
+    try {
+      const response = await getStaffConfigDeatail({ id: id.value });
+      if (response.code === 200) {
+        formData.value = response.data;
+      }
+    } catch (error) {
+      ElMessage.error("获取详情失败");
+    }
+  }
+};
+
+const goBack = () => {
+  router.go(-1);
+};
+</script>
+
+<style lang="scss" scoped>
+.el-form {
+  width: 100%;
+  .text-center {
+    text-align: center;
+  }
+}
+.el-col {
+  box-sizing: border-box;
+  padding-right: 10px;
+}
+</style>

+ 203 - 0
src/views/store/groupPackageManagement/index.vue

@@ -0,0 +1,203 @@
+<template>
+  <div class="table-box">
+    <ProTable ref="proTable" :columns="columns" :request-api="getTableList" :init-param="initParam" :data-callback="dataCallback">
+      <!-- 表格 header 按钮 -->
+      <template #tableHeader="scope">
+        <el-button type="primary" :icon="Download" @click="exportInfoExcel(scope)"> 导出 </el-button>
+      </template>
+      <template #expand="scope">
+        {{ scope.row }}
+      </template>
+      <!-- 表格操作 -->
+      <template #operation="scope">
+        <!-- 审批通过和拒绝按钮仅在状态为0时显示 -->
+        <template v-if="scope.row.status === '0'">
+          <el-button type="primary" link @click="changeTypes(scope.row, 'pass')"> 审核通过 </el-button>
+          <el-button type="primary" link @click="changeTypes(scope.row, '')"> 审核拒绝 </el-button>
+        </template>
+        <el-button type="primary" link @click="toDetail(scope.row)"> 查看详情 </el-button>
+      </template>
+    </ProTable>
+
+    <el-dialog v-model="dialogFormVisible" title="审核拒绝" width="500">
+      <el-form :model="form">
+        <el-form-item label="" label-width="0">
+          <el-input v-model="form.comment" autocomplete="off" type="textarea" maxlength="200" />
+        </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="groupPackageManagement">
+import { ref, reactive, onMounted, onActivated } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import ProTable from "@/components/ProTable/index.vue";
+import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
+import { Download } from "@element-plus/icons-vue";
+import { audit, exportExcelStaffConfig, getStaffConfigList } from "@/api/modules/staffConfig";
+
+const router = useRouter();
+const dialogFormVisible = ref(false);
+const form = reactive({
+  comment: ""
+});
+
+const rowData = ref<any>();
+
+const statusEnum = [
+  { value: "0", label: "待审核" },
+  { value: "1", label: "审核通过" },
+  { value: "2", label: "审核拒绝" }
+];
+// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
+const initParam = reactive({});
+
+// 定义 filterValues
+const filterValues = reactive({});
+
+const getStatusObj = (statusValue: string) => {
+  const statusObj = statusEnum.find(item => item.value === statusValue);
+  if (statusObj) {
+    filterValues.status = statusObj;
+  } else {
+    filterValues.status = "";
+  }
+  return statusObj;
+};
+
+// ProTable 实例
+const proTable = ref<ProTableInstance>();
+
+// 页面加载时触发查询
+onMounted(() => {
+  proTable.value?.getTableList();
+});
+
+// 从其他页面返回时触发查询
+onActivated(() => {
+  proTable.value?.getTableList();
+});
+
+// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
+// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
+const dataCallback = (data: any) => {
+  return {
+    list: data.records,
+    total: data.total
+  };
+};
+
+// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
+// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
+const getTableList = (params: any) => {
+  let newParams = JSON.parse(JSON.stringify(params));
+  return getStaffConfigList(newParams);
+};
+
+// 跳转详情页
+const toDetail = row => {
+  router.push(`/store/groupPackageManagementDetail?id=${row.id}`);
+};
+
+// 表格配置项
+const columns = reactive<ColumnProps<any>[]>([
+  { type: "index", fixed: "left", label: "序号", width: 130 },
+  { prop: "storeName", label: "所属店铺" },
+  { prop: "name", label: "名称" },
+  { prop: "description", label: "描述" },
+  {
+    prop: "status",
+    label: "状态",
+    render: scope => {
+      const statusObj = getStatusObj(scope.row.status);
+      return statusObj ? statusObj.label : "未知状态";
+    },
+    search: {
+      el: "select"
+    },
+    enum: statusEnum,
+    fieldNames: { label: "label", value: "value" }
+  },
+  { prop: "operation", label: "操作", fixed: "right", width: 330 }
+]);
+
+const changeTypes = (row: any, status: string) => {
+  rowData.value = row;
+  if (status === "pass") {
+    handleChangeStatus(row, "1");
+  } else {
+    form.comment = "";
+    dialogFormVisible.value = true;
+  }
+};
+
+const handleChangeStatus = async (row: any, status: string) => {
+  try {
+    let res = await audit({ id: row.id, status: status, rejectionReason: form.comment });
+    if (res.code === 200) {
+      proTable.value?.getTableList();
+      if (status === "2") closeDialog();
+      ElMessage.success("审核成功");
+    }
+  } catch (error) {
+    ElMessage.error("操作失败");
+  }
+};
+
+// 导出信息
+const exportInfoExcel = async scope => {
+  let res;
+  // 获取原始状态值(可能为数字、字符串或 undefined)
+  const rawStatus = proTable.value.searchParam.status;
+  // 转换为字符串(处理 undefined/null 为 "" 或保留原始字符串)
+  const statusParam = rawStatus !== undefined && rawStatus !== null ? String(rawStatus) : undefined;
+  // 将筛选条件作为参数传递给后台
+  res = await exportExcelStaffConfig({ status: statusParam });
+  if (res.code === 200) {
+    if (!res.data) {
+      ElMessage.error("暂无可下载数据");
+      return;
+    }
+    const exportFile = document.createElement("a");
+    exportFile.style.display = "none";
+    exportFile.download = `团购管理.xlsx`;
+    exportFile.href = `${res.data}?timestamp=${new Date().getTime()}`; // 添加时间戳防止缓存
+    document.body.appendChild(exportFile);
+    exportFile.click();
+    document.body.removeChild(exportFile);
+    ElMessage.success("下载成功");
+  }
+};
+
+// 弹窗提交
+const handleSubmit = () => {
+  if (!form.comment) {
+    ElMessage.error("请输入审批意见");
+    return;
+  }
+  handleChangeStatus(rowData.value, "2");
+};
+// 关闭弹窗;
+const closeDialog = () => {
+  dialogFormVisible.value = false;
+  form.comment = "";
+};
+</script>
+
+<style lang="scss" scoped>
+// 在组件样式中添加
+.date-range {
+  display: block; // 确保换行生效
+  padding: 0 8px; // 可选:增加内边距
+  word-wrap: break-word; // 长单词内换行
+  white-space: normal; // 允许自然换行
+}
+</style>

+ 93 - 0
src/views/store/licenseManagement/detail.vue

@@ -0,0 +1,93 @@
+<template>
+  <div class="card content-box">
+    <el-form :model="formData" label-width="140px">
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="店铺名称 :">
+            <span>{{ formData.storeName }}</span>
+          </el-form-item>
+          <el-form-item label="名称 :">
+            <span>{{ formData.name }}</span>
+          </el-form-item>
+          <el-form-item label="描述 :">
+            <span>{{ formData.description }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="状态:">
+            <span>{{ getStatusName(formData.status) }}</span>
+          </el-form-item>
+          <el-form-item label="拒绝原因:" v-if="formData.status === '2'">
+            <span>{{ formData.rejectionReason }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row class="text-center" style="margin-top: 20px">
+        <el-col :span="24">
+          <el-button type="primary" @click="goBack"> 确定 </el-button>
+        </el-col>
+      </el-row>
+    </el-form>
+  </div>
+</template>
+
+<script setup lang="tsx" name="licenseManagementDetail">
+import { ref, onMounted } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import { getStaffConfigDeatail } from "@/api/modules/staffConfig";
+
+const route = useRoute();
+const router = useRouter();
+
+const formData = ref({});
+
+const id = ref((route.query.id as string) || "");
+
+const getStatusName = (status: string) => {
+  switch (status) {
+    case "0":
+      return "待审核";
+    case "1":
+      return "审核通过";
+    case "2":
+      return "审核拒绝";
+    default:
+      return "未知状态";
+  }
+};
+
+onMounted(async () => {
+  await initData();
+});
+
+const initData = async () => {
+  if (id.value) {
+    try {
+      const response = await getStaffConfigDeatail({ id: id.value });
+      if (response.code === 200) {
+        formData.value = response.data;
+      }
+    } catch (error) {
+      ElMessage.error("获取详情失败");
+    }
+  }
+};
+
+const goBack = () => {
+  router.go(-1);
+};
+</script>
+
+<style lang="scss" scoped>
+.el-form {
+  width: 100%;
+  .text-center {
+    text-align: center;
+  }
+}
+.el-col {
+  box-sizing: border-box;
+  padding-right: 10px;
+}
+</style>

+ 203 - 0
src/views/store/licenseManagement/index.vue

@@ -0,0 +1,203 @@
+<template>
+  <div class="table-box">
+    <ProTable ref="proTable" :columns="columns" :request-api="getTableList" :init-param="initParam" :data-callback="dataCallback">
+      <!-- 表格 header 按钮 -->
+      <template #tableHeader="scope">
+        <el-button type="primary" :icon="Download" @click="exportInfoExcel(scope)"> 导出 </el-button>
+      </template>
+      <template #expand="scope">
+        {{ scope.row }}
+      </template>
+      <!-- 表格操作 -->
+      <template #operation="scope">
+        <!-- 审批通过和拒绝按钮仅在状态为0时显示 -->
+        <template v-if="scope.row.status === '0'">
+          <el-button type="primary" link @click="changeTypes(scope.row, 'pass')"> 审核通过 </el-button>
+          <el-button type="primary" link @click="changeTypes(scope.row, '')"> 审核拒绝 </el-button>
+        </template>
+        <el-button type="primary" link @click="toDetail(scope.row)"> 查看详情 </el-button>
+      </template>
+    </ProTable>
+
+    <el-dialog v-model="dialogFormVisible" title="审核拒绝" width="500">
+      <el-form :model="form">
+        <el-form-item label="" label-width="0">
+          <el-input v-model="form.comment" autocomplete="off" type="textarea" maxlength="200" />
+        </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="licenseManagement">
+import { ref, reactive, onMounted, onActivated } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import ProTable from "@/components/ProTable/index.vue";
+import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
+import { Download } from "@element-plus/icons-vue";
+import { audit, exportExcelStaffConfig, getStaffConfigList } from "@/api/modules/staffConfig";
+
+const router = useRouter();
+const dialogFormVisible = ref(false);
+const form = reactive({
+  comment: ""
+});
+
+const rowData = ref<any>();
+
+const statusEnum = [
+  { value: "0", label: "待审核" },
+  { value: "1", label: "审核通过" },
+  { value: "2", label: "审核拒绝" }
+];
+// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
+const initParam = reactive({});
+
+// 定义 filterValues
+const filterValues = reactive({});
+
+const getStatusObj = (statusValue: string) => {
+  const statusObj = statusEnum.find(item => item.value === statusValue);
+  if (statusObj) {
+    filterValues.status = statusObj;
+  } else {
+    filterValues.status = "";
+  }
+  return statusObj;
+};
+
+// ProTable 实例
+const proTable = ref<ProTableInstance>();
+
+// 页面加载时触发查询
+onMounted(() => {
+  proTable.value?.getTableList();
+});
+
+// 从其他页面返回时触发查询
+onActivated(() => {
+  proTable.value?.getTableList();
+});
+
+// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
+// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
+const dataCallback = (data: any) => {
+  return {
+    list: data.records,
+    total: data.total
+  };
+};
+
+// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
+// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
+const getTableList = (params: any) => {
+  let newParams = JSON.parse(JSON.stringify(params));
+  return getStaffConfigList(newParams);
+};
+
+// 跳转详情页
+const toDetail = row => {
+  router.push(`/store/licenseManagementDetail?id=${row.id}`);
+};
+
+// 表格配置项
+const columns = reactive<ColumnProps<any>[]>([
+  { type: "index", fixed: "left", label: "序号", width: 130 },
+  { prop: "storeName", label: "所属店铺" },
+  { prop: "name", label: "名称" },
+  { prop: "description", label: "描述" },
+  {
+    prop: "status",
+    label: "状态",
+    render: scope => {
+      const statusObj = getStatusObj(scope.row.status);
+      return statusObj ? statusObj.label : "未知状态";
+    },
+    search: {
+      el: "select"
+    },
+    enum: statusEnum,
+    fieldNames: { label: "label", value: "value" }
+  },
+  { prop: "operation", label: "操作", fixed: "right", width: 330 }
+]);
+
+const changeTypes = (row: any, status: string) => {
+  rowData.value = row;
+  if (status === "pass") {
+    handleChangeStatus(row, "1");
+  } else {
+    form.comment = "";
+    dialogFormVisible.value = true;
+  }
+};
+
+const handleChangeStatus = async (row: any, status: string) => {
+  try {
+    let res = await audit({ id: row.id, status: status, rejectionReason: form.comment });
+    if (res.code === 200) {
+      proTable.value?.getTableList();
+      if (status === "2") closeDialog();
+      ElMessage.success("审核成功");
+    }
+  } catch (error) {
+    ElMessage.error("操作失败");
+  }
+};
+
+// 导出信息
+const exportInfoExcel = async scope => {
+  let res;
+  // 获取原始状态值(可能为数字、字符串或 undefined)
+  const rawStatus = proTable.value.searchParam.status;
+  // 转换为字符串(处理 undefined/null 为 "" 或保留原始字符串)
+  const statusParam = rawStatus !== undefined && rawStatus !== null ? String(rawStatus) : undefined;
+  // 将筛选条件作为参数传递给后台
+  res = await exportExcelStaffConfig({ status: statusParam });
+  if (res.code === 200) {
+    if (!res.data) {
+      ElMessage.error("暂无可下载数据");
+      return;
+    }
+    const exportFile = document.createElement("a");
+    exportFile.style.display = "none";
+    exportFile.download = `证照管理.xlsx`;
+    exportFile.href = `${res.data}?timestamp=${new Date().getTime()}`; // 添加时间戳防止缓存
+    document.body.appendChild(exportFile);
+    exportFile.click();
+    document.body.removeChild(exportFile);
+    ElMessage.success("下载成功");
+  }
+};
+
+// 弹窗提交
+const handleSubmit = () => {
+  if (!form.comment) {
+    ElMessage.error("请输入审批意见");
+    return;
+  }
+  handleChangeStatus(rowData.value, "2");
+};
+// 关闭弹窗;
+const closeDialog = () => {
+  dialogFormVisible.value = false;
+  form.comment = "";
+};
+</script>
+
+<style lang="scss" scoped>
+// 在组件样式中添加
+.date-range {
+  display: block; // 确保换行生效
+  padding: 0 8px; // 可选:增加内边距
+  word-wrap: break-word; // 长单词内换行
+  white-space: normal; // 允许自然换行
+}
+</style>

+ 93 - 0
src/views/store/orderManagement/detail.vue

@@ -0,0 +1,93 @@
+<template>
+  <div class="card content-box">
+    <el-form :model="formData" label-width="140px">
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="店铺名称 :">
+            <span>{{ formData.storeName }}</span>
+          </el-form-item>
+          <el-form-item label="名称 :">
+            <span>{{ formData.name }}</span>
+          </el-form-item>
+          <el-form-item label="描述 :">
+            <span>{{ formData.description }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="状态:">
+            <span>{{ getStatusName(formData.status) }}</span>
+          </el-form-item>
+          <el-form-item label="拒绝原因:" v-if="formData.status === '2'">
+            <span>{{ formData.rejectionReason }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row class="text-center" style="margin-top: 20px">
+        <el-col :span="24">
+          <el-button type="primary" @click="goBack"> 确定 </el-button>
+        </el-col>
+      </el-row>
+    </el-form>
+  </div>
+</template>
+
+<script setup lang="tsx" name="orderManagementDetail">
+import { ref, onMounted } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import { getStaffConfigDeatail } from "@/api/modules/staffConfig";
+
+const route = useRoute();
+const router = useRouter();
+
+const formData = ref({});
+
+const id = ref((route.query.id as string) || "");
+
+const getStatusName = (status: string) => {
+  switch (status) {
+    case "0":
+      return "待审核";
+    case "1":
+      return "审核通过";
+    case "2":
+      return "审核拒绝";
+    default:
+      return "未知状态";
+  }
+};
+
+onMounted(async () => {
+  await initData();
+});
+
+const initData = async () => {
+  if (id.value) {
+    try {
+      const response = await getStaffConfigDeatail({ id: id.value });
+      if (response.code === 200) {
+        formData.value = response.data;
+      }
+    } catch (error) {
+      ElMessage.error("获取详情失败");
+    }
+  }
+};
+
+const goBack = () => {
+  router.go(-1);
+};
+</script>
+
+<style lang="scss" scoped>
+.el-form {
+  width: 100%;
+  .text-center {
+    text-align: center;
+  }
+}
+.el-col {
+  box-sizing: border-box;
+  padding-right: 10px;
+}
+</style>

+ 203 - 0
src/views/store/orderManagement/index.vue

@@ -0,0 +1,203 @@
+<template>
+  <div class="table-box">
+    <ProTable ref="proTable" :columns="columns" :request-api="getTableList" :init-param="initParam" :data-callback="dataCallback">
+      <!-- 表格 header 按钮 -->
+      <template #tableHeader="scope">
+        <el-button type="primary" :icon="Download" @click="exportInfoExcel(scope)"> 导出 </el-button>
+      </template>
+      <template #expand="scope">
+        {{ scope.row }}
+      </template>
+      <!-- 表格操作 -->
+      <template #operation="scope">
+        <!-- 审批通过和拒绝按钮仅在状态为0时显示 -->
+        <template v-if="scope.row.status === '0'">
+          <el-button type="primary" link @click="changeTypes(scope.row, 'pass')"> 审核通过 </el-button>
+          <el-button type="primary" link @click="changeTypes(scope.row, '')"> 审核拒绝 </el-button>
+        </template>
+        <el-button type="primary" link @click="toDetail(scope.row)"> 查看详情 </el-button>
+      </template>
+    </ProTable>
+
+    <el-dialog v-model="dialogFormVisible" title="审核拒绝" width="500">
+      <el-form :model="form">
+        <el-form-item label="" label-width="0">
+          <el-input v-model="form.comment" autocomplete="off" type="textarea" maxlength="200" />
+        </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="orderManagement">
+import { ref, reactive, onMounted, onActivated } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import ProTable from "@/components/ProTable/index.vue";
+import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
+import { Download } from "@element-plus/icons-vue";
+import { audit, exportExcelStaffConfig, getStaffConfigList } from "@/api/modules/staffConfig";
+
+const router = useRouter();
+const dialogFormVisible = ref(false);
+const form = reactive({
+  comment: ""
+});
+
+const rowData = ref<any>();
+
+const statusEnum = [
+  { value: "0", label: "待审核" },
+  { value: "1", label: "审核通过" },
+  { value: "2", label: "审核拒绝" }
+];
+// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
+const initParam = reactive({});
+
+// 定义 filterValues
+const filterValues = reactive({});
+
+const getStatusObj = (statusValue: string) => {
+  const statusObj = statusEnum.find(item => item.value === statusValue);
+  if (statusObj) {
+    filterValues.status = statusObj;
+  } else {
+    filterValues.status = "";
+  }
+  return statusObj;
+};
+
+// ProTable 实例
+const proTable = ref<ProTableInstance>();
+
+// 页面加载时触发查询
+onMounted(() => {
+  proTable.value?.getTableList();
+});
+
+// 从其他页面返回时触发查询
+onActivated(() => {
+  proTable.value?.getTableList();
+});
+
+// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
+// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
+const dataCallback = (data: any) => {
+  return {
+    list: data.records,
+    total: data.total
+  };
+};
+
+// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
+// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
+const getTableList = (params: any) => {
+  let newParams = JSON.parse(JSON.stringify(params));
+  return getStaffConfigList(newParams);
+};
+
+// 跳转详情页
+const toDetail = row => {
+  router.push(`/store/orderManagementDetail?id=${row.id}`);
+};
+
+// 表格配置项
+const columns = reactive<ColumnProps<any>[]>([
+  { type: "index", fixed: "left", label: "序号", width: 130 },
+  { prop: "storeName", label: "所属店铺" },
+  { prop: "name", label: "名称" },
+  { prop: "description", label: "描述" },
+  {
+    prop: "status",
+    label: "状态",
+    render: scope => {
+      const statusObj = getStatusObj(scope.row.status);
+      return statusObj ? statusObj.label : "未知状态";
+    },
+    search: {
+      el: "select"
+    },
+    enum: statusEnum,
+    fieldNames: { label: "label", value: "value" }
+  },
+  { prop: "operation", label: "操作", fixed: "right", width: 330 }
+]);
+
+const changeTypes = (row: any, status: string) => {
+  rowData.value = row;
+  if (status === "pass") {
+    handleChangeStatus(row, "1");
+  } else {
+    form.comment = "";
+    dialogFormVisible.value = true;
+  }
+};
+
+const handleChangeStatus = async (row: any, status: string) => {
+  try {
+    let res = await audit({ id: row.id, status: status, rejectionReason: form.comment });
+    if (res.code === 200) {
+      proTable.value?.getTableList();
+      if (status === "2") closeDialog();
+      ElMessage.success("审核成功");
+    }
+  } catch (error) {
+    ElMessage.error("操作失败");
+  }
+};
+
+// 导出信息
+const exportInfoExcel = async scope => {
+  let res;
+  // 获取原始状态值(可能为数字、字符串或 undefined)
+  const rawStatus = proTable.value.searchParam.status;
+  // 转换为字符串(处理 undefined/null 为 "" 或保留原始字符串)
+  const statusParam = rawStatus !== undefined && rawStatus !== null ? String(rawStatus) : undefined;
+  // 将筛选条件作为参数传递给后台
+  res = await exportExcelStaffConfig({ status: statusParam });
+  if (res.code === 200) {
+    if (!res.data) {
+      ElMessage.error("暂无可下载数据");
+      return;
+    }
+    const exportFile = document.createElement("a");
+    exportFile.style.display = "none";
+    exportFile.download = `订单管理.xlsx`;
+    exportFile.href = `${res.data}?timestamp=${new Date().getTime()}`; // 添加时间戳防止缓存
+    document.body.appendChild(exportFile);
+    exportFile.click();
+    document.body.removeChild(exportFile);
+    ElMessage.success("下载成功");
+  }
+};
+
+// 弹窗提交
+const handleSubmit = () => {
+  if (!form.comment) {
+    ElMessage.error("请输入审批意见");
+    return;
+  }
+  handleChangeStatus(rowData.value, "2");
+};
+// 关闭弹窗;
+const closeDialog = () => {
+  dialogFormVisible.value = false;
+  form.comment = "";
+};
+</script>
+
+<style lang="scss" scoped>
+// 在组件样式中添加
+.date-range {
+  display: block; // 确保换行生效
+  padding: 0 8px; // 可选:增加内边距
+  word-wrap: break-word; // 长单词内换行
+  white-space: normal; // 允许自然换行
+}
+</style>

+ 93 - 0
src/views/store/storeDecoration/detail.vue

@@ -0,0 +1,93 @@
+<template>
+  <div class="card content-box">
+    <el-form :model="formData" label-width="140px">
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="店铺名称 :">
+            <span>{{ formData.storeName }}</span>
+          </el-form-item>
+          <el-form-item label="名称 :">
+            <span>{{ formData.name }}</span>
+          </el-form-item>
+          <el-form-item label="描述 :">
+            <span>{{ formData.description }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="状态:">
+            <span>{{ getStatusName(formData.status) }}</span>
+          </el-form-item>
+          <el-form-item label="拒绝原因:" v-if="formData.status === '2'">
+            <span>{{ formData.rejectionReason }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row class="text-center" style="margin-top: 20px">
+        <el-col :span="24">
+          <el-button type="primary" @click="goBack"> 确定 </el-button>
+        </el-col>
+      </el-row>
+    </el-form>
+  </div>
+</template>
+
+<script setup lang="tsx" name="storeDecorationDetail">
+import { ref, onMounted } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import { getStaffConfigDeatail } from "@/api/modules/staffConfig";
+
+const route = useRoute();
+const router = useRouter();
+
+const formData = ref({});
+
+const id = ref((route.query.id as string) || "");
+
+const getStatusName = (status: string) => {
+  switch (status) {
+    case "0":
+      return "待审核";
+    case "1":
+      return "审核通过";
+    case "2":
+      return "审核拒绝";
+    default:
+      return "未知状态";
+  }
+};
+
+onMounted(async () => {
+  await initData();
+});
+
+const initData = async () => {
+  if (id.value) {
+    try {
+      const response = await getStaffConfigDeatail({ id: id.value });
+      if (response.code === 200) {
+        formData.value = response.data;
+      }
+    } catch (error) {
+      ElMessage.error("获取详情失败");
+    }
+  }
+};
+
+const goBack = () => {
+  router.go(-1);
+};
+</script>
+
+<style lang="scss" scoped>
+.el-form {
+  width: 100%;
+  .text-center {
+    text-align: center;
+  }
+}
+.el-col {
+  box-sizing: border-box;
+  padding-right: 10px;
+}
+</style>

+ 203 - 0
src/views/store/storeDecoration/index.vue

@@ -0,0 +1,203 @@
+<template>
+  <div class="table-box">
+    <ProTable ref="proTable" :columns="columns" :request-api="getTableList" :init-param="initParam" :data-callback="dataCallback">
+      <!-- 表格 header 按钮 -->
+      <template #tableHeader="scope">
+        <el-button type="primary" :icon="Download" @click="exportInfoExcel(scope)"> 导出 </el-button>
+      </template>
+      <template #expand="scope">
+        {{ scope.row }}
+      </template>
+      <!-- 表格操作 -->
+      <template #operation="scope">
+        <!-- 审批通过和拒绝按钮仅在状态为0时显示 -->
+        <template v-if="scope.row.status === '0'">
+          <el-button type="primary" link @click="changeTypes(scope.row, 'pass')"> 审核通过 </el-button>
+          <el-button type="primary" link @click="changeTypes(scope.row, '')"> 审核拒绝 </el-button>
+        </template>
+        <el-button type="primary" link @click="toDetail(scope.row)"> 查看详情 </el-button>
+      </template>
+    </ProTable>
+
+    <el-dialog v-model="dialogFormVisible" title="审核拒绝" width="500">
+      <el-form :model="form">
+        <el-form-item label="" label-width="0">
+          <el-input v-model="form.comment" autocomplete="off" type="textarea" maxlength="200" />
+        </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="storeDecoration">
+import { ref, reactive, onMounted, onActivated } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import ProTable from "@/components/ProTable/index.vue";
+import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
+import { Download } from "@element-plus/icons-vue";
+import { audit, exportExcelStaffConfig, getStaffConfigList } from "@/api/modules/staffConfig";
+
+const router = useRouter();
+const dialogFormVisible = ref(false);
+const form = reactive({
+  comment: ""
+});
+
+const rowData = ref<any>();
+
+const statusEnum = [
+  { value: "0", label: "待审核" },
+  { value: "1", label: "审核通过" },
+  { value: "2", label: "审核拒绝" }
+];
+// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
+const initParam = reactive({});
+
+// 定义 filterValues
+const filterValues = reactive({});
+
+const getStatusObj = (statusValue: string) => {
+  const statusObj = statusEnum.find(item => item.value === statusValue);
+  if (statusObj) {
+    filterValues.status = statusObj;
+  } else {
+    filterValues.status = "";
+  }
+  return statusObj;
+};
+
+// ProTable 实例
+const proTable = ref<ProTableInstance>();
+
+// 页面加载时触发查询
+onMounted(() => {
+  proTable.value?.getTableList();
+});
+
+// 从其他页面返回时触发查询
+onActivated(() => {
+  proTable.value?.getTableList();
+});
+
+// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
+// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
+const dataCallback = (data: any) => {
+  return {
+    list: data.records,
+    total: data.total
+  };
+};
+
+// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
+// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
+const getTableList = (params: any) => {
+  let newParams = JSON.parse(JSON.stringify(params));
+  return getStaffConfigList(newParams);
+};
+
+// 跳转详情页
+const toDetail = row => {
+  router.push(`/store/storeDecorationDetail?id=${row.id}`);
+};
+
+// 表格配置项
+const columns = reactive<ColumnProps<any>[]>([
+  { type: "index", fixed: "left", label: "序号", width: 130 },
+  { prop: "storeName", label: "所属店铺" },
+  { prop: "name", label: "名称" },
+  { prop: "description", label: "描述" },
+  {
+    prop: "status",
+    label: "状态",
+    render: scope => {
+      const statusObj = getStatusObj(scope.row.status);
+      return statusObj ? statusObj.label : "未知状态";
+    },
+    search: {
+      el: "select"
+    },
+    enum: statusEnum,
+    fieldNames: { label: "label", value: "value" }
+  },
+  { prop: "operation", label: "操作", fixed: "right", width: 330 }
+]);
+
+const changeTypes = (row: any, status: string) => {
+  rowData.value = row;
+  if (status === "pass") {
+    handleChangeStatus(row, "1");
+  } else {
+    form.comment = "";
+    dialogFormVisible.value = true;
+  }
+};
+
+const handleChangeStatus = async (row: any, status: string) => {
+  try {
+    let res = await audit({ id: row.id, status: status, rejectionReason: form.comment });
+    if (res.code === 200) {
+      proTable.value?.getTableList();
+      if (status === "2") closeDialog();
+      ElMessage.success("审核成功");
+    }
+  } catch (error) {
+    ElMessage.error("操作失败");
+  }
+};
+
+// 导出信息
+const exportInfoExcel = async scope => {
+  let res;
+  // 获取原始状态值(可能为数字、字符串或 undefined)
+  const rawStatus = proTable.value.searchParam.status;
+  // 转换为字符串(处理 undefined/null 为 "" 或保留原始字符串)
+  const statusParam = rawStatus !== undefined && rawStatus !== null ? String(rawStatus) : undefined;
+  // 将筛选条件作为参数传递给后台
+  res = await exportExcelStaffConfig({ status: statusParam });
+  if (res.code === 200) {
+    if (!res.data) {
+      ElMessage.error("暂无可下载数据");
+      return;
+    }
+    const exportFile = document.createElement("a");
+    exportFile.style.display = "none";
+    exportFile.download = `门店装修.xlsx`;
+    exportFile.href = `${res.data}?timestamp=${new Date().getTime()}`; // 添加时间戳防止缓存
+    document.body.appendChild(exportFile);
+    exportFile.click();
+    document.body.removeChild(exportFile);
+    ElMessage.success("下载成功");
+  }
+};
+
+// 弹窗提交
+const handleSubmit = () => {
+  if (!form.comment) {
+    ElMessage.error("请输入审批意见");
+    return;
+  }
+  handleChangeStatus(rowData.value, "2");
+};
+// 关闭弹窗;
+const closeDialog = () => {
+  dialogFormVisible.value = false;
+  form.comment = "";
+};
+</script>
+
+<style lang="scss" scoped>
+// 在组件样式中添加
+.date-range {
+  display: block; // 确保换行生效
+  padding: 0 8px; // 可选:增加内边距
+  word-wrap: break-word; // 长单词内换行
+  white-space: normal; // 允许自然换行
+}
+</style>

+ 0 - 219
src/views/store/storeUser/contractRenewal/detail.vue

@@ -1,219 +0,0 @@
-<template>
-  <div style="width: 100%; min-height: 100%; background-color: white">
-    <div class="model">续约合同管理</div>
-    <el-form :model="storeInfoModel" label-width="120px" ref="ruleFormRef" class="formBox">
-      <el-row>
-        <el-col :span="9" :offset="6">
-          <el-form-item label="联系人">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel.storeUserName" />
-          </el-form-item>
-          <el-form-item label="身份证号码">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel.idCard" />
-          </el-form-item>
-          <el-form-item label="联系电话">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel.storePhone" />
-          </el-form-item>
-          <el-form-item label="商铺名称">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel.storeName" />
-          </el-form-item>
-          <el-form-item label="经营板块">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel.businessSectionName" />
-          </el-form-item>
-          <el-form-item label="经营种类">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel.businessTypesName" />
-          </el-form-item>
-          <el-form-item label="门店营业状态">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel.businessStatusStr" />
-          </el-form-item>
-          <el-form-item label="续约合同">
-            <div style="display: flex; flex-wrap: wrap; gap: 10px">
-              <template v-for="contractImage in storeInfoModel.renewContractImageList" :key="contractImage">
-                <el-image
-                  :src="contractImage"
-                  style="height: 150px; cursor: pointer; border-radius: 13px"
-                  @click="handlePictureCardPreview(contractImage)"
-                />
-              </template>
-            </div>
-          </el-form-item>
-        </el-col>
-        <el-col :span="9">
-          <el-form-item label="提交时间">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel.updateRenewContractTime" />
-          </el-form-item>
-          <el-form-item label="审核状态">
-            <el-input :disabled="true" maxlength="50" value="待审核" />
-          </el-form-item>
-          <!-- <el-form-item label="拒绝原因" v-if="storeInfoModel.contractReason">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel.contractReason" />
-          </el-form-item> -->
-        </el-col>
-      </el-row>
-    </el-form>
-    <div class="model">
-      <el-button @click="goBack"> 返回 </el-button>
-    </div>
-  </div>
-  <!--图片预览-->
-  <el-dialog v-model="imagePopupVisible" title="预览" width="30%">
-    <el-image style="width: 100%" :src="previewImage" fit="contain" />
-  </el-dialog>
-</template>
-
-<script setup lang="tsx" name="ContractRenewalDetail">
-import { ref, onMounted } from "vue";
-import { StoreUser } from "@/api/interface";
-import { ElMessage } from "element-plus";
-import {
-  getBusinessSection,
-  getBusinessSectionTypes,
-  getUnboundAccountList,
-  saveStoreInfo,
-  getStoreDetail,
-  editStoreInfo,
-  getInputPrompt,
-  getDistrict
-} from "@/api/modules/storeUser";
-import { useRouter, useRoute } from "vue-router";
-import type { FormInstance } from "element-plus";
-
-const imagePopupVisible = ref(false);
-const previewImage = ref("");
-
-//文件上传地址
-const uploadUrl = ref(`${import.meta.env.VITE_API_URL}/file/upload`);
-
-const router = useRouter();
-const route = useRoute();
-
-//页面操作列是否禁用
-const isDisabled = ref<boolean>(false);
-//进入页面类型(新增:add,查看:show,编辑:edit)
-//页面展开类型
-const type = ref<String>("");
-//页面id参数
-const id = ref<String>("");
-
-//商铺信息模块
-const storeInfoModel = ref<StoreUser.ResStoreUserList>({
-  //店铺名称
-  storeName: "",
-  //容纳人数
-  storeCapacity: 1,
-  //门店电话
-  storeTel: "",
-  //门店面积
-  storeArea: "1",
-  //是否连锁
-  isChain: 1,
-  //详细地址
-  storeAddress: "",
-  //门店简介
-  storeBlurb: "",
-  //经营板块
-  businessSection: "1",
-  //经营种类
-  businessTypes: [],
-  //营业执照
-  fileList: [],
-  //用户账号id
-  userAccount: "",
-  //门店状态
-  storeStatus: "0",
-  //门店营业状态
-  businessStatus: "0",
-  //行政区域
-  district: []
-});
-
-//用户列表
-const userOptions = ref<StoreUser.UserOptions[]>([]);
-
-// 门店面积列表
-const storeAreaList = ref<any[]>([
-  { value: 1, label: "小于20平米" },
-  { value: 2, label: "20~50平米" },
-  { value: 3, label: "50~100平米" },
-  { value: 4, label: "100~300平米" },
-  { value: 5, label: "300~500平米" },
-  { value: 6, label: "500~1000平米" },
-  { value: 7, label: "大于1000平米" }
-]);
-
-// 经营板块列表
-const businessSectionList = ref<any[]>([]);
-
-//经营种类列表
-const businessTypes = ref<any[]>([]);
-
-// 门店状态列表
-const storeStatusList = ref<any[]>([
-  { value: 0, label: "正常" },
-  { value: 1, label: "禁用" }
-]);
-
-// 门店营业状态列表
-const businessStatusList = ref<any[]>([
-  { value: 0, label: "正常营业" },
-  { value: 1, label: "暂停营业" },
-  { value: 2, label: "筹建中" },
-  { value: 99, label: "永久关门" }
-]);
-
-//返回上一页
-const goBack = () => {
-  router.go(-1);
-};
-
-const handlePictureCardPreview = (url: string) => {
-  previewImage.value = url;
-  imagePopupVisible.value = true;
-};
-
-// 提交数据(新增/编辑)
-const ruleFormRef = ref<FormInstance>();
-
-onMounted(async () => {
-  id.value = route.query.id as string;
-  type.value = route.query.type as string;
-
-  if (type.value != "add") {
-    if (type.value == "show") {
-      isDisabled.value = true;
-    }
-    try {
-      let res = await getStoreDetail({ id: id.value });
-      storeInfoModel.value = res.data;
-    } catch (error) {
-      ElMessage.error("获取详情失败");
-    }
-  }
-});
-</script>
-
-<style scoped lang="scss">
-.content {
-  display: flex;
-  width: 98%;
-  height: 98%;
-  margin: auto;
-  .contentLeft {
-    width: 50%;
-  }
-  .contentRight {
-    width: 50%;
-  }
-}
-.model {
-  padding: 20px 0;
-  margin-left: 50%;
-  text-align: center;
-  transform: translate(-60%, 0);
-}
-.formBox {
-  width: 70%;
-}
-.table-box {
-  height: auto !important;
-}
-</style>

+ 0 - 250
src/views/store/storeUser/contractRenewal/index.vue

@@ -1,250 +0,0 @@
-<template>
-  <div class="table-box">
-    <ProTable
-      ref="proTable"
-      :columns="columns"
-      :request-api="getTableList"
-      :init-param="initParam"
-      :data-callback="dataCallback"
-      @drag-sort="sortTable"
-    >
-      <template #expand="scope">
-        {{ scope.row }}
-      </template>
-      <!-- usernameHeader -->
-      <template #usernameHeader="scope">
-        <el-button type="primary" @click="ElMessage.success('我是通过作用域插槽渲染的表头')">
-          {{ scope.column.label }}
-        </el-button>
-      </template>
-      <!-- createTime -->
-      <template #createTime="scope">
-        <el-button type="primary" link @click="ElMessage.success('我是通过作用域插槽渲染的内容')">
-          {{ scope.row.createTime }}
-        </el-button>
-      </template>
-      <!-- 表格操作 -->
-      <template #operation="scope">
-        <el-button type="primary" link :icon="Check" @click="approve(1, scope.row)"> 通过 </el-button>
-        <el-button type="primary" link :icon="Close" @click="showRejectDialog(scope.row)"> 拒绝 </el-button>
-        <el-button type="primary" link :icon="Search" @click="handleToDetail('show', scope.row.id)"> 查看详情 </el-button>
-      </template>
-    </ProTable>
-    <!--拒绝-->
-    <el-dialog v-model="dialogVisible" title="拒绝原因" width="500">
-      <el-input v-model="rejectReason" style="width: 240px" placeholder="请填写拒绝原因" />
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="dialogVisible = false"> 取消 </el-button>
-          <el-button type="primary" @click="approve(3, rejectObj)"> 确定 </el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup lang="tsx" name="useProTable">
-import { useRouter, useRoute } from "vue-router";
-import { ref, reactive, computed, onMounted, watch, onUnmounted, onActivated } from "vue";
-import { StoreUser } from "@/api/interface";
-import { ElMessage } from "element-plus";
-import ProTable from "@/components/ProTable/index.vue";
-import ImportExcel from "@/components/ImportExcel/index.vue";
-import StoreUserDrawer from "@/views/proTable/components/StoreUserDrawer.vue";
-import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
-import { CirclePlus, Delete, EditPen, Download, Upload, Refresh, Check, Close, Search } from "@element-plus/icons-vue";
-import {
-  getStoreUserList,
-  addStoreUser,
-  editStoreUser,
-  deleteStoreUser,
-  resetStoreUserPassWord,
-  getStoreInfoList,
-  getBusinessSection,
-  deleteStoreInfo,
-  updateContractImageStatus,
-  exportExcel
-} from "@/api/modules/storeUser";
-import { useHandleData } from "@/hooks/useHandleData";
-import { number } from "echarts";
-
-const dialogVisible = ref(false);
-const rejectReason = ref("");
-const rejectObj = ref<StoreUser.ResStoreUserList>({});
-const showRejectDialog = (row: StoreUser.ResStoreUserList) => {
-  dialogVisible.value = true;
-  rejectObj.value = row;
-};
-
-const router = useRouter();
-const route = useRoute();
-watch(
-  () => route.fullPath,
-  (newVal, oldVal) => {
-    if (newVal.startsWith("/store/storeUser") && newVal !== oldVal) {
-      proTable.value?.getTableList();
-    }
-  },
-  { immediate: true }
-);
-
-//导出信息
-const exportInfoExcel = async () => {
-  let params = proTable.value?.searchParam;
-  let res = await exportExcel(params);
-  console.log("导出res", res);
-  // link.href = "https://file.ailien.shop/excel/generate/storeCashOutRecord4.xlsx";
-  if (res.code == "200") {
-    if (!res.data) {
-      ElMessage.error("暂无可下载数据");
-      return;
-    }
-    const exportFile = document.createElement("a");
-    exportFile.style.display = "none";
-    exportFile.download = `商铺信息.xlsx`;
-    // return;
-    exportFile.href = `${res.data}?timestamp=${new Date().getTime()}`; // 添加时间戳防止缓存
-    // exportFile.href = ` https://file.ailien.shop/excel/generate/storeCashOutRecord4.xlsx?timestamp=${new Date().getTime()}`; // 添加时间戳防止缓存
-    https: document.body.appendChild(exportFile);
-    exportFile.click();
-    // 去除下载对 url 的影响
-    document.body.removeChild(exportFile);
-    ElMessage.success("下载成功");
-  }
-};
-
-//审批状态
-const approve = async (renewContractStatus: number, row: StoreUser.ResStoreUserList) => {
-  let approvalStatusStr = renewContractStatus == 3 ? "拒绝" : "通过";
-  approvalStatusStr += "【" + row.storeName + "】商铺续约合同申请?";
-  await useHandleData(
-    updateContractImageStatus,
-    { id: row.id, renewContractStatus: renewContractStatus, contractReason: renewContractStatus == 3 ? rejectReason.value : "" },
-    approvalStatusStr
-  );
-  if (renewContractStatus == 3) {
-    dialogVisible.value = false;
-    rejectReason.value = "";
-  }
-  proTable.value?.getTableList();
-};
-
-// 表格拖拽排序
-const sortTable = ({ newIndex, oldIndex }: { newIndex?: number; oldIndex?: number }) => {
-  console.log(newIndex, oldIndex);
-  console.log(proTable.value?.tableData);
-  ElMessage.success("修改列表排序成功");
-};
-
-// ProTable 实例
-const proTable = ref<ProTableInstance>();
-
-// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
-const initParam = reactive({ type: 1 });
-
-// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
-// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
-const dataCallback = (data: any) => {
-  return {
-    list: data.records,
-    total: data.total
-  };
-};
-
-// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
-// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
-const getTableList = (params: any) => {
-  let newParams = JSON.parse(JSON.stringify(params));
-  // newParams.createTime && (newParams.startTime = newParams.createTime[0]);
-  // newParams.createTime && (newParams.endTime = newParams.createTime[1]);
-  // delete newParams.createTime;
-  console.log(newParams);
-  newParams.renewContractStatus = "2";
-  return getStoreInfoList(newParams);
-};
-
-// 门店审核状态列表
-const storeApplicationStatus = ref<any[]>([
-  { value: 0, label: "待审核" },
-  { value: 1, label: "审核通过" },
-  { value: 2, label: "审核拒绝" }
-]);
-
-// 门店状态列表
-const storeStatuss = ref<any[]>([
-  { value: 0, label: "正常" },
-  { value: 1, label: "禁用" },
-  { value: 2, label: "已注销" }
-]);
-
-//获取审批状态列表
-const getAuditStatus = computed((params: any) => {
-  const list: any = [];
-  list.push({ auditLabel: "待审核", auditValue: "0" });
-  list.push({ auditLabel: "审核通过", auditValue: "1" });
-  list.push({ auditLabel: "审核拒绝", auditValue: "2" });
-  return list;
-});
-
-// 经营板块列表
-const businessSectionList = ref<any[]>([]);
-
-const getBusinessSectionList = async () => {
-  const res = await getBusinessSection();
-  let addData = [];
-  res.data.forEach(element => {
-    addData.push({
-      value: Number(element.dictId),
-      label: element.dictDetail,
-      parentId: element.parentId
-    });
-  });
-  businessSectionList.value = addData;
-};
-
-// 表格配置项
-const columns = reactive<ColumnProps<StoreUser.ResStoreUserList>[]>([
-  { type: "selection", fixed: "left" },
-  { prop: "storeContact", label: "联系人" },
-  { prop: "storePhone", label: "联系电话", search: { el: "input", tooltip: "请输入联系人电话" } },
-  { prop: "storeName", label: "店铺名称", search: { el: "input" } },
-  {
-    prop: "businessSection",
-    label: "经营板块",
-    enum: businessSectionList,
-    search: { el: "select" },
-    fieldNames: { label: "label", value: "value" }
-  },
-  {
-    prop: "updateRenewContractTime",
-    label: "提交时间",
-    width: 180
-  },
-  { prop: "operation", label: "操作", fixed: "right", width: 330 }
-]);
-
-// 打开 drawer(新增、查看、编辑)
-const drawerRef = ref<InstanceType<typeof StoreUserDrawer> | null>(null);
-
-//跳转至新增页面
-const handleToDetail = (type: string, id: string) => {
-  router.push({
-    path: `/store/storeInfo/contractRenewal/detail`,
-    query: {
-      id: id,
-      type: type
-    }
-  });
-  // router.push(`/store/storeInfo/storeInfoDetail`);
-};
-
-onMounted(async () => {
-  //获取商铺经营板块
-  await getBusinessSectionList();
-  await getTableList({});
-});
-
-onActivated(() => {
-  proTable.value?.getTableList();
-});
-</script>

+ 0 - 12
src/views/store/storeUser/detail.vue

@@ -1,12 +0,0 @@
-<template>
-  <div class="card content-box">
-    <span class="text">我是 ProTable 详情页,属于 ProTable 下面的子集 🍓🍇🍈🍉</span>
-    <span class="text">params:{{ route.params }}</span>
-    <span class="text">query:{{ route.query }}</span>
-  </div>
-</template>
-
-<script setup lang="ts" name="useProTableDetail">
-import { useRoute } from "vue-router";
-const route = useRoute();
-</script>

+ 0 - 386
src/views/store/storeUser/foodLicence/detail.vue

@@ -1,386 +0,0 @@
-<template>
-  <div style="width: 100%; min-height: 100%; background-color: white">
-    <div class="model">食品经营许可证管理</div>
-    <el-form :model="storeInfoModel" label-width="120px" ref="ruleFormRef" class="formBox">
-      <el-row>
-        <el-col :span="9" :offset="6">
-          <el-form-item label="联系人">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel!.storeUserName" />
-          </el-form-item>
-          <el-form-item label="身份证号码">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel!.idCard" />
-          </el-form-item>
-          <el-form-item label="联系电话">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel!.storePhone" />
-          </el-form-item>
-          <el-form-item label="商铺名称">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel!.storeName" />
-          </el-form-item>
-          <el-form-item label="经营板块">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel!.businessSectionName" />
-          </el-form-item>
-          <el-form-item label="经营种类">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel!.businessTypesName" />
-          </el-form-item>
-          <el-form-item label="门店营业状态">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel!.businessStatusStr" />
-          </el-form-item>
-          <el-form-item label="食品经营许可证变更">
-            <div style="display: flex; flex-wrap: wrap; gap: 10px">
-              <template v-for="contractImage in storeInfoModel!.notPassFoodLicenceImageList" :key="contractImage">
-                <el-image
-                  :src="contractImage"
-                  style=" height: 150px;border-radius: 13px"
-                  @click="handlePictureCardPreview(contractImage)"
-                />
-              </template>
-            </div>
-          </el-form-item>
-        </el-col>
-        <el-col :span="9">
-          <el-form-item label="提交时间">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel!.updateFoodLicenceTime" />
-          </el-form-item>
-          <el-form-item label="审核状态">
-            <el-input :disabled="true" maxlength="50" value="待审核" />
-          </el-form-item>
-          <el-form-item label="拒绝原因">
-            <el-input :disabled="true" maxlength="50" v-model="storeInfoModel!.foodLicenceReason" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-    </el-form>
-    <div class="model">
-      <el-button @click="goBack"> 返回 </el-button>
-    </div>
-  </div>
-  <!--图片预览-->
-  <el-dialog v-model="imagePopupVisible" title="预览" width="30%">
-    <el-image style="width: 100%" :src="previewImage" fit="fit" />
-  </el-dialog>
-</template>
-
-<script setup lang="tsx" name="useProTable">
-import { ref, reactive, onMounted, nextTick } from "vue";
-import { StoreUser } from "@/api/interface";
-import { ElMessage } from "element-plus";
-import { QuestionFilled } from "@element-plus/icons-vue";
-import {
-  getBusinessSection,
-  getBusinessSectionTypes,
-  getUnboundAccountList,
-  addBusinessSectionAndTypes,
-  saveStoreInfo,
-  getStoreDetail,
-  editStoreInfo,
-  getInputPrompt,
-  getDistrict
-} from "@/api/modules/storeUser";
-import { useRouter, useRoute } from "vue-router";
-import { UploadProps, UploadUserFile } from "element-plus";
-
-const imagePopupVisible = ref(false);
-//文件上传地址
-const uploadUrl = ref(`${import.meta.env.VITE_API_URL}/file/upload`);
-//行政区域组件
-const props: CascaderProps = {
-  lazy: true,
-  async lazyLoad(node, resolve) {
-    const { level } = node;
-    try {
-      let param = { adCode: node.data.adCode ? node.data.adCode : "" };
-      // 调用后台接口获取数据
-      const response = await getDistrict(param);
-      // 转换数据格式
-      const nodes = response.data.districts[0].districts.map(item => ({
-        value: item.adcode,
-        adCode: item.adcode,
-        label: item.name,
-        leaf: level >= 2 // 假设最多三级,可以根据实际需求调整
-      }));
-
-      // 返回数据
-      resolve(nodes);
-    } catch (error) {
-      console.error("获取区域数据失败:", error);
-      resolve([]);
-    }
-  }
-};
-
-const router = useRouter();
-const route = useRoute();
-const InputRef = ref<InstanceType<typeof ElInput>>();
-//页面操作列是否禁用
-const isDisabled = ref<boolean>(false);
-//进入页面类型(新增:add,查看:show,编辑:edit)
-//新增板块
-const storeSectionModel = ref<StoreUser.StoreSection>({ sectionName: "", types: [] });
-//页面展开类型
-const type = ref<String>("");
-//页面id参数
-const id = ref<String>("");
-//地址名称
-const addressName = ref<String>("");
-//查询地址名称
-const queryAddress = ref<String>("");
-//地址集合
-const addressList = ref<[]>([]);
-
-//商铺信息模块
-const storeInfoModel = ref<StoreUser.ResStoreUserList>({
-  //店铺名称
-  storeName: "",
-  //容纳人数
-  storeCapacity: "1",
-  //门店电话
-  storeTel: "",
-  //门店面积
-  storeArea: 1,
-  //是否连锁
-  isChain: 1,
-  //详细地址
-  storeAddress: "",
-  //门店简介
-  storeBlurb: "",
-  //经营板块
-  businessSection: "1",
-  //经营种类
-  businessTypes: [],
-  //营业执照
-  fileList: [],
-  //用户账号id
-  userAccount: "",
-  //门店状态
-  storeStatus: 0,
-  //门店营业状态
-  businessStatus: 0,
-  //行政区域
-  district: []
-});
-//用户列表
-const userOptions = ref<StoreUser.UserOptions[]>([]);
-//用户经营板块对话框开启标识
-const addSectionDialogVisible = ref<boolean>(false);
-//添加板块类型开启标识
-const sectionTypeVisable = ref<boolean>(false);
-//添加板块类型值
-const sectionTypeValue = ref<string>("");
-//添加板块类型名称
-const sectionSectionName = ref<string>("");
-//添加板块类型英文值
-const businessTypeValue = ref<string>("");
-//添加板块类型名称
-const sectionSectionTypes = ref<[string]>([]);
-//营业执照图片集合
-const videoUrlList = ref<[string]>([]);
-//合同图片集合
-const contractImageList = ref<[string]>([]);
-
-// 门店面积列表
-const storeAreaList = ref<any[]>([
-  { value: 1, label: "小于20平米" },
-  { value: 2, label: "20~50平米" },
-  { value: 3, label: "50~100平米" },
-  { value: 4, label: "100~300平米" },
-  { value: 5, label: "300~500平米" },
-  { value: 6, label: "500~1000平米" },
-  { value: 7, label: "大于1000平米" }
-]);
-// 经营板块列表
-const businessSectionList = ref<any[]>([]);
-//经营种类列表
-const businessTypes = ref<any[]>([]);
-//获取用户列表
-const getUserOptions = async () => {
-  let res = await getUnboundAccountList({ id: id.value });
-  //todo 此处修改成调用接口
-  // let a = { name: "张三", id: 1 };
-  // let b = { name: "李四", id: 2 };
-  res.data.forEach(element => {
-    let addData = {
-      name: element.name,
-      id: element.id
-    };
-    userOptions.value.push(addData);
-  });
-};
-// 门店状态列表
-const storeStatusList = ref<any[]>([
-  { value: 0, label: "正常" },
-  { value: 1, label: "禁用" }
-]);
-// 门店营业状态列表
-const businessStatusList = ref<any[]>([
-  { value: 0, label: "正常营业" },
-  { value: 1, label: "暂停营业" },
-  { value: 2, label: "筹建中" },
-  { value: 99, label: "永久关门" }
-]);
-//新增经营板块
-const addSection = () => {
-  addSectionDialogVisible.value = true;
-};
-//返回上一页
-const goBack = () => {
-  router.go(-1);
-};
-
-const getBusinessSectionList = async () => {
-  const res = await getBusinessSection();
-  let addData = [];
-  res.data.forEach(element => {
-    addData.push({ value: element.dictId, label: element.dictDetail, parentId: element.parentId });
-  });
-  //默认 storeInfoModel!.businessSection 为第一个元素
-  storeInfoModel.value.businessSection = addData[0].value;
-  businessSectionList.value = addData;
-  changeSection();
-};
-
-const changeSection = async () => {
-  storeInfoModel.value.businessTypes = [];
-  //获取经营种类
-  const resType = await getBusinessSectionTypes({ parentId: storeInfoModel.value.businessSection });
-  let addData = [];
-  resType.data.forEach(element => {
-    addData.push({ value: element.dictId, label: element.dictDetail, parentId: element.parentId });
-  });
-  businessTypes.value = addData;
-  if (type.value == "add") {
-    storeInfoModel.value.businessTypes = ["0"];
-  }
-};
-
-const getLonAndLat = async (keyword: string) => {
-  if (keyword) {
-    console.log("地址查询", keyword);
-    let param = {
-      addressName: keyword
-    };
-    let res = await getInputPrompt(param);
-    if (res.code == "200") {
-      addressList.value = res.data.tips;
-      console.log("res", res);
-    } else {
-      ElMessage.error("新增失败!");
-    }
-  } else {
-    addressList.value = [];
-  }
-};
-
-const clearInput = async () => {};
-
-const selectAddress = async param => {
-  console.log("addressName.value", addressName.value);
-  let locationList = addressName.value.split(",");
-  addressList.value.forEach(item => {
-    if (item.location == addressName.value) {
-      queryAddress.value = item.name;
-    }
-  });
-  console.log("locationList", locationList);
-  storeInfoModel.value.storePositionLongitude = locationList[0];
-  storeInfoModel.value.storePositionLatitude = locationList[1];
-};
-
-// const handlePictureCardPreview: UploadProps["onPreview"] = uploadFile => {};
-const previewImage = ref("");
-const handlePictureCardPreview = e => {
-  imagePopupVisible.value = true;
-  previewImage.value = e;
-};
-
-// 提交数据(新增/编辑)
-const ruleFormRef = ref<FormInstance>();
-const ruleFormRef2 = ref<FormInstance>();
-const ruleFormRef3 = ref<FormInstance>();
-const handleSubmit = () => {
-  console.log("storeInfoModel.value.district", storeInfoModel.value.district);
-  ruleFormRef.value!.validate(async valid => {
-    if (!valid) return;
-    ruleFormRef2.value!.validate(async valid2 => {
-      if (!valid2) return;
-      ruleFormRef3.value!.validate(async valid3 => {
-        if (!valid3) return;
-        if (!storeInfoModel.value.district[0] || !storeInfoModel.value.district[1] || !storeInfoModel.value.district[2]) {
-          ElMessage.error("请完整选择行政区域");
-          return;
-        }
-        let param = storeInfoModel.value;
-        param.queryAddress = queryAddress.value;
-        console.log("videoUrlList.value ===> ", videoUrlList.value);
-        console.log("storeInfoModel.value ===> ", storeInfoModel.value);
-        param.businessLicenseAddress = videoUrlList.value;
-        param.contractImageList = contractImageList.value;
-        param.createTime = null;
-        param.updatedTime = null;
-        param.administrativeRegionProvinceAdcode = storeInfoModel.value.district[0];
-        param.administrativeRegionCityAdcode = storeInfoModel.value.district[1];
-        param.administrativeRegionDistrictAdcode = storeInfoModel.value.district[2];
-        if (type.value == "add") {
-          let res = await saveStoreInfo(param);
-          if (res.code == "200") {
-            ElMessage.success("新增成功");
-            router.go(-1);
-          } else {
-            ElMessage.error("新增失败");
-          }
-        } else if (type.value == "edit") {
-          let res = await editStoreInfo(param);
-          if (res.code == "200") {
-            ElMessage.success("编辑成功");
-            router.go(-1);
-          } else {
-            ElMessage.error("编辑失败");
-          }
-        }
-      });
-    });
-  });
-};
-
-onMounted(async () => {
-  id.value = route.query.id;
-  type.value = route.query.type;
-  //调用获取用户列表
-  getUserOptions();
-  //获取商铺经营板块
-  getBusinessSectionList();
-  if (type.value != "add") {
-    if (type.value == "show") {
-      isDisabled.value = true;
-    }
-    let res = await getStoreDetail({ id: id.value });
-    storeInfoModel.value = res.data;
-  }
-});
-</script>
-
-<style scoped lang="scss">
-.content {
-  display: flex;
-  width: 98%;
-  height: 98%;
-  margin: auto;
-  .contentLeft {
-    width: 50%;
-  }
-  .contentRight {
-    width: 50%;
-  }
-}
-.model {
-  padding: 20px 0;
-  margin-left: 50%;
-  text-align: center;
-  transform: translate(-60%, 0);
-}
-.formBox {
-  width: 70%;
-}
-.table-box {
-  height: auto !important;
-}
-</style>

+ 0 - 197
src/views/store/storeUser/foodLicence/index.vue

@@ -1,197 +0,0 @@
-<template>
-  <div class="table-box">
-    <ProTable
-      ref="proTable"
-      :columns="columns"
-      :request-api="getTableList"
-      :init-param="initParam"
-      :data-callback="dataCallback"
-      @drag-sort="sortTable"
-    >
-      <template #expand="scope">
-        {{ scope.row }}
-      </template>
-      <!-- usernameHeader -->
-      <template #usernameHeader="scope">
-        <el-button type="primary" @click="ElMessage.success('我是通过作用域插槽渲染的表头')">
-          {{ scope.column.label }}
-        </el-button>
-      </template>
-      <!-- createTime -->
-      <template #createTime="scope">
-        <el-button type="primary" link @click="ElMessage.success('我是通过作用域插槽渲染的内容')">
-          {{ scope.row.createTime }}
-        </el-button>
-      </template>
-      <!-- 表格操作 -->
-      <template #operation="scope">
-        <el-button type="primary" link :icon="Check" @click="approve(1, scope.row)"> 通过 </el-button>
-        <el-button type="primary" link :icon="Close" @click="showRejectDialog(scope.row)"> 拒绝 </el-button>
-        <el-button type="primary" link :icon="Search" @click="handleToDetail('show', scope.row.id)"> 查看详情 </el-button>
-      </template>
-    </ProTable>
-    <!--拒绝-->
-    <el-dialog v-model="dialogVisible" title="拒绝原因" width="500">
-      <el-input v-model="rejectReason" style="width: 240px" placeholder="请填写拒绝原因" />
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="dialogVisible = false"> 取消 </el-button>
-          <el-button type="primary" @click="approve(3, rejectObj)"> 确定 </el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup lang="tsx" name="useProTable">
-import { useRouter, useRoute } from "vue-router";
-import { ref, reactive, computed, onMounted, watch, onUnmounted, onActivated } from "vue";
-import { StoreUser } from "@/api/interface";
-import { ElMessage } from "element-plus";
-import ProTable from "@/components/ProTable/index.vue";
-import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
-import { Check, Close, Search } from "@element-plus/icons-vue";
-import { getStoreInfoList, getBusinessSection, updatefoodLicenceImageStatus } from "@/api/modules/storeUser";
-import { useHandleData } from "@/hooks/useHandleData";
-import { number } from "echarts";
-
-const dialogVisible = ref(false);
-const rejectReason = ref("");
-const rejectObj = ref<StoreUser.ResStoreUserList>({});
-const showRejectDialog = (row: StoreUser.ResStoreUserList) => {
-  dialogVisible.value = true;
-  rejectObj.value = row;
-};
-
-const router = useRouter();
-const route = useRoute();
-watch(
-  () => route.fullPath,
-  (newVal, oldVal) => {
-    if (newVal.startsWith("/store/storeUser") && newVal !== oldVal) {
-      proTable.value?.getTableList();
-    }
-  },
-  { immediate: true }
-);
-
-//审批状态
-const approve = async (foodLicenceStatus: number, row: StoreUser.ResStoreUserList) => {
-  let approvalStatusStr = foodLicenceStatus == 3 ? "拒绝" : "通过";
-  approvalStatusStr += "【" + row.storeName + "】商铺经营许可证变更申请?";
-  await useHandleData(
-    updatefoodLicenceImageStatus,
-    {
-      id: row.id,
-      foodLicenceStatus: foodLicenceStatus,
-      foodLicenceReason: foodLicenceStatus == 3 ? rejectReason.value : ""
-    },
-    approvalStatusStr
-  );
-  if (foodLicenceStatus == 3) {
-    dialogVisible.value = false;
-    rejectReason.value = "";
-  }
-  proTable.value?.getTableList();
-};
-
-// 表格拖拽排序
-const sortTable = ({ newIndex, oldIndex }: { newIndex?: number; oldIndex?: number }) => {
-  console.log(newIndex, oldIndex);
-  console.log(proTable.value?.tableData);
-  ElMessage.success("修改列表排序成功");
-};
-
-// ProTable 实例
-const proTable = ref<ProTableInstance>();
-
-// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
-const initParam = reactive({ type: 1 });
-
-// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
-// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
-const dataCallback = (data: any) => {
-  return {
-    list: data.records,
-    total: data.total
-  };
-};
-
-//跳转至新增页面
-const handleToDetail = (type: string, id: string) => {
-  router.push({
-    path: `/store/storeInfo/foodLicence/detail`,
-    query: {
-      id: id,
-      type: type
-    }
-  });
-  // router.push(`/store/storeInfo/storeInfoDetail`);
-};
-
-// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
-// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
-const getTableList = (params: any) => {
-  let newParams = JSON.parse(JSON.stringify(params));
-  // newParams.createTime && (newParams.startTime = newParams.createTime[0]);
-  // newParams.createTime && (newParams.endTime = newParams.createTime[1]);
-  // delete newParams.createTime;
-  console.log(newParams);
-  newParams.foodLicenceStatus = "2";
-  return getStoreInfoList(newParams);
-};
-
-// 门店状态列表
-const storeStatuss = ref<any[]>([
-  { value: 0, label: "正常" },
-  { value: 1, label: "禁用" },
-  { value: 2, label: "已注销" }
-]);
-
-// 经营板块列表
-const businessSectionList = ref<any[]>([]);
-
-const getBusinessSectionList = async () => {
-  const res = await getBusinessSection();
-  let addData = [];
-  res.data.forEach(element => {
-    addData.push({
-      value: Number(element.dictId),
-      label: element.dictDetail,
-      parentId: element.parentId
-    });
-  });
-  businessSectionList.value = addData;
-};
-
-// 表格配置项
-const columns = reactive<ColumnProps<StoreUser.ResStoreUserList>[]>([
-  { type: "selection", fixed: "left" },
-  { prop: "storeContact", label: "联系人" },
-  { prop: "storePhone", label: "联系电话", search: { el: "input", tooltip: "请输入联系人电话" } },
-  { prop: "storeName", label: "店铺名称", search: { el: "input" } },
-  {
-    prop: "businessSection",
-    label: "经营板块",
-    enum: businessSectionList,
-    search: { el: "select" },
-    fieldNames: { label: "label", value: "value" }
-  },
-  {
-    prop: "updateFoodLicenceTime",
-    label: "提交时间",
-    width: 180
-  },
-  { prop: "operation", label: "操作", fixed: "right", width: 330 }
-]);
-
-onMounted(async () => {
-  //获取商铺经营板块
-  await getBusinessSectionList();
-  await getTableList({});
-});
-
-onActivated(() => {
-  proTable.value?.getTableList();
-});
-</script>

+ 0 - 264
src/views/store/storeUser/foodLicence/time.vue

@@ -1,264 +0,0 @@
-<template>
-  <div class="table-box">
-    <ProTable
-      ref="proTable"
-      :columns="columns"
-      :request-api="getTableList"
-      :init-param="initParam"
-      :data-callback="dataCallback"
-      @drag-sort="sortTable"
-    >
-      <template #expand="scope">
-        {{ scope.row }}
-      </template>
-      <!-- usernameHeader -->
-      <template #usernameHeader="scope">
-        <el-button type="primary" @click="ElMessage.success('我是通过作用域插槽渲染的表头')">
-          {{ scope.column.label }}
-        </el-button>
-      </template>
-      <!-- createTime -->
-      <template #createTime="scope">
-        <el-button type="primary" link @click="ElMessage.success('我是通过作用域插槽渲染的内容')">
-          {{ scope.row.createTime }}
-        </el-button>
-      </template>
-      <!-- 表格操作 -->
-      <template #operation="scope">
-        <el-button type="primary" link :icon="Search" @click="handleToDetail(scope.row)"> 查看详情 </el-button>
-
-        <el-button
-          v-if="scope.row.foodLicenceRemainingDays == '0天' && scope.row.foodLicenceExpireStatus == '已到期'"
-          type="primary"
-          link
-          :icon="Delete"
-          @click="deleteAccount(scope.row)"
-        >
-          删除
-        </el-button>
-      </template>
-    </ProTable>
-    <!--拒绝-->
-    <el-dialog v-model="dialogVisible" title="详情" width="500">
-      <el-form :model="item" label-width="120px" ref="ruleFormRef" class="formBox">
-        <el-form-item label="商铺名称">
-          <el-input :disabled="true" maxlength="50" v-model="item!.storeName" />
-        </el-form-item>
-        <el-form-item label="经营板块">
-          <el-input :disabled="true" maxlength="50" v-model="item!.businessSectionName" />
-        </el-form-item>
-        <el-form-item label="到期状态">
-          <el-input :disabled="true" maxlength="50" v-model="item!.foodLicenceExpireStatus" />
-        </el-form-item>
-        <el-form-item label="到期时间">
-          <el-input :disabled="true" maxlength="50" v-model="item!.foodLicenceExpirationTime" />
-        </el-form-item>
-        <el-form-item label="经营许可证图片">
-          <el-upload
-            v-if="item.foodLicenceImageUrl"
-            :file-list="getFileList(item.foodLicenceImageUrl)"
-            :disabled="true"
-            list-type="picture-card"
-            :on-preview="handlePictureCardPreview"
-          >
-            <el-icon><Plus /></el-icon>
-          </el-upload>
-        </el-form-item>
-      </el-form>
-    </el-dialog>
-
-    <el-dialog v-model="dialogImageVisible">
-      <img w-full :src="dialogImageUrl" alt="Preview Image" />
-    </el-dialog>
-  </div>
-</template>
-
-<script setup lang="tsx" name="useProTable">
-import { useRouter, useRoute } from "vue-router";
-import { ref, reactive, computed, onMounted, watch, onUnmounted, onActivated } from "vue";
-import { StoreUser } from "@/api/interface";
-import { ElMessage } from "element-plus";
-import ProTable from "@/components/ProTable/index.vue";
-import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
-import { Check, Close, Delete, Search } from "@element-plus/icons-vue";
-import { getStoreInfoList, getBusinessSection, updatefoodLicenceImageStatus, deleteStoreInfo } from "@/api/modules/storeUser";
-import { useHandleData } from "@/hooks/useHandleData";
-import { number } from "echarts";
-import type { UploadProps } from "element-plus";
-
-const dialogVisible = ref(false);
-const rejectReason = ref("");
-const item = ref<StoreUser.ResStoreUserList>({});
-
-const router = useRouter();
-const route = useRoute();
-watch(
-  () => route.fullPath,
-  (newVal, oldVal) => {
-    if (newVal.startsWith("/store/storeUser") && newVal !== oldVal) {
-      proTable.value?.getTableList();
-    }
-  },
-  { immediate: true }
-);
-
-const getFileList = str => {
-  return [
-    {
-      url: str
-    }
-  ];
-};
-
-//审批状态
-const approve = async (foodLicenceStatus: number, row: StoreUser.ResStoreUserList) => {
-  let approvalStatusStr = foodLicenceStatus == 3 ? "拒绝" : "通过";
-  approvalStatusStr += "【" + row.storeName + "】商铺经营许可证变更申请?";
-  await useHandleData(
-    updatefoodLicenceImageStatus,
-    {
-      id: row.id,
-      foodLicenceStatus: foodLicenceStatus,
-      foodLicenceReason: foodLicenceStatus == 3 ? rejectReason.value : ""
-    },
-    approvalStatusStr
-  );
-  if (foodLicenceStatus == 3) {
-    dialogVisible.value = false;
-    rejectReason.value = "";
-  }
-  proTable.value?.getTableList();
-};
-
-const dialogImageUrl = ref("");
-const dialogImageVisible = ref(false);
-const handlePictureCardPreview: UploadProps["onPreview"] = uploadFile => {
-  dialogImageUrl.value = uploadFile.url!;
-  dialogImageVisible.value = true;
-};
-
-// 表格拖拽排序
-const sortTable = ({ newIndex, oldIndex }: { newIndex?: number; oldIndex?: number }) => {
-  console.log(newIndex, oldIndex);
-  console.log(proTable.value?.tableData);
-  ElMessage.success("修改列表排序成功");
-};
-
-// ProTable 实例
-const proTable = ref<ProTableInstance>();
-
-// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
-const initParam = reactive({ type: 1 });
-
-// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
-// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
-const dataCallback = (data: any) => {
-  return {
-    list: data.records,
-    total: data.total
-  };
-};
-
-//跳转至新增页面
-const handleToDetail = row => {
-  dialogVisible.value = true;
-  item.value = row;
-};
-
-// 删除商户信息
-const deleteAccount = async (params: StoreUser.ResStoreUserList) => {
-  await useHandleData(deleteStoreInfo, { id: params.id }, `删除【${params.storeName}】商铺与管理账户`);
-  proTable.value?.getTableList();
-};
-
-// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
-// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
-const getTableList = (params: any) => {
-  let newParams = JSON.parse(JSON.stringify(params));
-  // newParams.createTime && (newParams.startTime = newParams.createTime[0]);
-  // newParams.createTime && (newParams.endTime = newParams.createTime[1]);
-  // delete newParams.createTime;
-  newParams.storeApplicationStatus = 1;
-  return getStoreInfoList(newParams);
-};
-
-// 门店状态列表
-const storeStatuss = ref<any[]>([
-  { value: 0, label: "正常" },
-  { value: 1, label: "禁用" },
-  { value: 2, label: "已注销" }
-]);
-
-// 经营板块列表
-const businessSectionList = ref<any[]>([]);
-
-const getBusinessSectionList = async () => {
-  const res = await getBusinessSection();
-  let addData = [];
-  res.data.forEach(element => {
-    addData.push({
-      value: Number(element.dictId),
-      label: element.dictDetail,
-      parentId: element.parentId
-    });
-  });
-  businessSectionList.value = addData;
-};
-
-const foodLicenceExpireStatus = reactive([
-  { label: "已到期", value: 0 },
-  { label: "即将到期", value: 1 },
-  { label: "未到期", value: 2 }
-]);
-
-// 表格配置项
-const columns = reactive<ColumnProps<StoreUser.ResStoreUserList>[]>([
-  { type: "selection", fixed: "left" },
-  { prop: "storeName", label: "店铺名称", search: { el: "input" } },
-  {
-    prop: "businessSectionName",
-    label: "经营板块",
-    fieldNames: { label: "label", value: "value" }
-  },
-  {
-    prop: "foodLicenceExpirationTime",
-    label: "到期时间",
-    width: 180
-  },
-  {
-    prop: "foodLicenceRemainingDays",
-    label: "剩余天数",
-    width: 180
-  },
-  {
-    prop: "foodLicenceExpireStatus",
-    label: "状态",
-    width: 180
-  },
-  {
-    prop: "foodLicenceWhetherExpiredStatus",
-    label: "状态",
-    isShow: false,
-    search: { el: "select" },
-    enum: foodLicenceExpireStatus,
-    fieldNames: { label: "label", value: "value" }
-  },
-  { prop: "operation", label: "操作", fixed: "right", width: 330 }
-]);
-
-onMounted(async () => {
-  //获取商铺经营板块
-  await getBusinessSectionList();
-  await getTableList({});
-});
-
-onActivated(() => {
-  proTable.value?.getTableList();
-});
-</script>
-
-<style scoped lang="scss">
-:deep(.el-upload--picture-card) {
-  display: none;
-}
-</style>

+ 0 - 492
src/views/store/storeUser/index.vue

@@ -1,492 +0,0 @@
-<template>
-  <div class="table-box">
-    <ProTable
-      ref="proTable"
-      :columns="columns"
-      :request-api="getTableList"
-      :init-param="initParam"
-      :data-callback="dataCallback"
-      @drag-sort="sortTable"
-    >
-      <!-- 表格 header 按钮 -->
-      <template #tableHeader="scope">
-        <!-- <el-button type="primary" :icon="CirclePlus" @click="openDrawer('新增')">新增商铺及商铺管理员</el-button> -->
-        <el-button type="primary" :icon="CirclePlus" @click="handleToDetail('add', '')"> 新增 </el-button>
-        <el-button type="primary" :icon="Download" @click="exportInfoExcel()"> 导出 </el-button>
-      </template>
-      <!-- Expand -->
-      <template #expand="scope">
-        {{ scope.row }}
-      </template>
-      <!-- usernameHeader -->
-      <template #usernameHeader="scope">
-        <el-button type="primary" @click="ElMessage.success('我是通过作用域插槽渲染的表头')">
-          {{ scope.column.label }}
-        </el-button>
-      </template>
-      <!-- createTime -->
-      <template #createTime="scope">
-        <el-button type="primary" link @click="ElMessage.success('我是通过作用域插槽渲染的内容')">
-          {{ scope.row.createTime }}
-        </el-button>
-      </template>
-      <!-- 表格操作 -->
-      <template #operation="scope">
-        <el-button type="primary" v-if="scope.row.storeApplicationStatus == 0" link :icon="Check" @click="approve(1, scope.row)">
-          通过
-        </el-button>
-        <!-- <el-button type="primary" v-if="scope.row.storeApplicationStatus == 0" link :icon="Close"
-          @click="approve(2, scope.row)">拒绝</el-button> -->
-
-        <el-button type="primary" v-if="scope.row.storeApplicationStatus == 0" link :icon="Close" @click="jj(scope.row)">
-          拒绝
-        </el-button>
-
-        <el-button type="primary" link :icon="Search" @click="handleToDetail('show', scope.row.id)"> 查看详情 </el-button>
-        <el-button
-          v-if="scope.row.storeStatus != 2"
-          type="primary"
-          link
-          :icon="EditPen"
-          @click="handleToDetail('edit', scope.row.id)"
-        >
-          编辑
-        </el-button>
-        <el-button
-          v-if="scope.row.storeApplicationStatus != 0"
-          type="primary"
-          link
-          :icon="Delete"
-          @click="deleteAccount(scope.row)"
-        >
-          删除
-        </el-button>
-        <el-button type="primary" link :icon="PieChart" @click="handleCC(scope.row)" v-if="scope.row.storeStatus !== 2">
-          设置抽成比例
-        </el-button>
-      </template>
-    </ProTable>
-    <StoreUserDrawer ref="drawerRef" />
-    <ImportExcel ref="dialogRef" />
-    <!--  设置抽成百分比弹出框-->
-    <el-drawer v-model="drawer" :direction="direction" size="89%">
-      <template #header>
-        <h4>商家管理/店铺管理</h4>
-      </template>
-      <template #default>
-        <div class="topTitle">当前店铺订单抽成比例:{{ ccValuefix || 0 }}%</div>
-        <div class="inputcc">
-          <span>设置抽成比例</span>
-          <div>
-            <el-input
-              style="width: 100%"
-              placeholder="请输入0~100的抽成比例"
-              type="number"
-              size="large"
-              v-model="ccValue"
-              :min="0"
-              :max="100"
-              @change="changeCCValue"
-            >
-              <template #append>
-                <span>% / 每单</span>
-              </template>
-            </el-input>
-          </div>
-        </div>
-        <div class="topTitle zysx">
-          <span>计算说明</span>
-          <div>
-            <span>订单金额x抽成比例=平台抽成金额</span>
-            <br />
-            <span>例如:订单金额100元,抽成比例3%,则平台抽成为3元</span>
-          </div>
-        </div>
-        <div class="topTitle zysx zysx2">
-          <span>注意</span>
-          <div>
-            <span>1.修改抽成比例将影响所有新生产的订单</span>
-            <br />
-            <span>2.已完成订单的抽成比例不受影响</span>
-            <br />
-            <span>3.建议根据市场情况合理设置抽成比例</span>
-          </div>
-        </div>
-      </template>
-      <template #footer>
-        <div style="flex: auto">
-          <el-button @click="cancelClick"> 取消 </el-button>
-          <el-button type="primary" @click="confirmClick"> 确定 </el-button>
-        </div>
-      </template>
-    </el-drawer>
-
-    <!-- 拒接弹窗 -->
-    <el-dialog v-model="dialogFormVisible" title="温馨提示" width="500">
-      <div style="padding-bottom: 2vh; font-size: 15px; font-weight: 700">是否拒绝【{{ jjValue?.storeName }}】商铺申请?</div>
-      <el-form :model="form">
-        <el-form-item label="拒绝原因:" :label-width="formLabelWidth">
-          <el-input v-model="form.reason" autocomplete="off" :rows="2" type="textarea" />
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="dialogFormVisible = false"> 取消 </el-button>
-          <el-button type="primary" @click="jjQd"> 确定 </el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup lang="tsx" name="useProTable">
-import { useRouter, useRoute } from "vue-router";
-import { ref, reactive, computed, onMounted, watch, onUnmounted, onActivated } from "vue";
-import { StoreUser } from "@/api/interface";
-import { ElMessage } from "element-plus";
-import ProTable from "@/components/ProTable/index.vue";
-import ImportExcel from "@/components/ImportExcel/index.vue";
-import StoreUserDrawer from "@/views/proTable/components/StoreUserDrawer.vue";
-import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
-import { CirclePlus, Delete, EditPen, Download, Upload, Refresh, Check, Close, Search, PieChart } from "@element-plus/icons-vue";
-import {
-  getStoreUserList,
-  addStoreUser,
-  editStoreUser,
-  deleteStoreUser,
-  resetStoreUserPassWord,
-  getStoreInfoList,
-  getBusinessSection,
-  deleteStoreInfo,
-  approveStoreInfo,
-  exportExcel,
-  updateStoreCommissionRate
-} from "@/api/modules/storeUser";
-import { useHandleData } from "@/hooks/useHandleData";
-import { number } from "echarts";
-import type { DrawerProps } from "element-plus";
-const dialogFormVisible = ref(false);
-const formLabelWidth = "140px";
-const form = reactive({
-  reason: ""
-});
-const router = useRouter();
-const route = useRoute();
-watch(
-  () => route.fullPath,
-  (newVal, oldVal) => {
-    if (newVal.startsWith("/store/storeUser") && newVal !== oldVal) {
-      proTable.value?.getTableList();
-    }
-  },
-  { immediate: true }
-);
-
-//导出信息
-const exportInfoExcel = async () => {
-  const params = (proTable.value?.searchParam as Record<string, any>) ?? {};
-  let res = await exportExcel(params);
-  console.log("导出res", res);
-  // link.href = "https://file.ailien.shop/excel/generate/storeCashOutRecord4.xlsx";
-  if (res.code == "200") {
-    if (!res.data) {
-      ElMessage.error("暂无可下载数据");
-      return;
-    }
-    const exportFile = document.createElement("a");
-    exportFile.style.display = "none";
-    exportFile.download = `商铺信息.xlsx`;
-    // return;
-    exportFile.href = `${res.data}?timestamp=${new Date().getTime()}`; // 添加时间戳防止缓存
-    // exportFile.href = ` https://file.ailien.shop/excel/generate/storeCashOutRecord4.xlsx?timestamp=${new Date().getTime()}`; // 添加时间戳防止缓存
-    https: document.body.appendChild(exportFile);
-    exportFile.click();
-    // 去除下载对 url 的影响
-    document.body.removeChild(exportFile);
-    ElMessage.success("下载成功");
-  }
-};
-
-//审批状态
-const approve = async (approvalStatus: number, row: StoreUser.ResStoreUserList) => {
-  if (!row.expirationTime) {
-    ElMessage.error("请先选择商铺的到期时间");
-    return;
-  }
-  let approvalStatusStr = approvalStatus == 1 ? "通过" : "拒绝";
-  approvalStatusStr += "【" + row.storeName + "】商铺申请?";
-  await useHandleData(approveStoreInfo, { id: row.id, approvalStatus: approvalStatus }, approvalStatusStr);
-  proTable.value?.getTableList();
-};
-
-// 表格拖拽排序
-const sortTable = ({ newIndex, oldIndex }: { newIndex?: number; oldIndex?: number }) => {
-  console.log(newIndex, oldIndex);
-  console.log(proTable.value?.tableData);
-  ElMessage.success("修改列表排序成功");
-};
-
-// ProTable 实例
-const proTable = ref<ProTableInstance>();
-
-// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
-const initParam = reactive({ type: 1 });
-
-// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
-// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
-const dataCallback = (data: any) => {
-  return {
-    list: data.records,
-    total: data.total
-  };
-};
-
-// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
-// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
-const getTableList = (params: any) => {
-  let newParams = JSON.parse(JSON.stringify(params));
-  // newParams.createTime && (newParams.startTime = newParams.createTime[0]);
-  // newParams.createTime && (newParams.endTime = newParams.createTime[1]);
-  // delete newParams.createTime;
-  return getStoreInfoList(newParams);
-};
-
-// 门店审核状态列表
-const storeApplicationStatus = ref<any[]>([
-  { value: 0, label: "待审核" },
-  { value: 1, label: "审核通过" },
-  { value: 2, label: "审核拒绝" }
-]);
-
-// 门店状态列表
-const storeStatuss = ref<any[]>([
-  { value: 1, label: "正常" },
-  { value: 0, label: "禁用" },
-  { value: 2, label: "已注销" }
-]);
-
-//获取审批状态列表
-const getAuditStatus = computed((params: any) => {
-  const list: any = [];
-  list.push({ auditLabel: "待审核", auditValue: "0" });
-  list.push({ auditLabel: "审核通过", auditValue: "1" });
-  list.push({ auditLabel: "审核拒绝", auditValue: "2" });
-  return list;
-});
-
-// 经营板块列表
-const businessSectionList = ref<any[]>([]);
-
-const getBusinessSectionList = async () => {
-  const res = await getBusinessSection();
-  const addData: any[] = [];
-  const data = (res as any)?.data ?? [];
-  data.forEach((element: any) => {
-    addData.push({
-      value: Number(element.dictId),
-      label: element.dictDetail,
-      parentId: element.parentId
-    });
-  });
-  businessSectionList.value = addData;
-};
-
-// 表格配置项
-const columns = reactive<ColumnProps<StoreUser.ResStoreUserList>[]>([
-  { type: "selection", fixed: "left" },
-  { prop: "id", label: "商铺ID", search: { el: "input", tooltip: "请输入商铺id" } },
-  { prop: "storeContact", label: "联系人" },
-  { prop: "storePhone", label: "联系电话", search: { el: "input", tooltip: "请输入联系人电话" } },
-  { prop: "storeName", label: "店铺名称" },
-  {
-    prop: "businessSection",
-    label: "经营板块",
-    enum: businessSectionList,
-    search: { el: "select" },
-    fieldNames: { label: "label", value: "value" }
-  },
-  {
-    prop: "createdTime",
-    label: "创建时间",
-    width: 180,
-    search: {
-      span: 2,
-      props: { type: "datetimerange", valueFormat: "YYYY-MM-DD HH:mm:ss" },
-      defaultValue: ["2022-11-12 11:35:00", "2022-12-12 11:35:00"]
-    }
-  },
-  {
-    prop: "storeApplicationStatus",
-    label: "审核状态 ",
-    search: { el: "select" },
-    enum: storeApplicationStatus,
-    fieldNames: { label: "label", value: "value" }
-  },
-  {
-    prop: "storeStatus",
-    label: "状态 ",
-    enum: storeStatuss,
-    fieldNames: { label: "label", value: "value" }
-  },
-
-  // { prop: "storeTypeStr", label: "经营类型" },
-  // { prop: "businessStatusStr", label: "状态" },
-  { prop: "operation", label: "操作", fixed: "right", width: 330 }
-]);
-
-// 打开 drawer(新增、查看、编辑)
-const drawerRef = ref<InstanceType<typeof StoreUserDrawer> | null>(null);
-const openDrawer = (title: string, row: Partial<StoreUser.ResStoreUserList> = {}) => {
-  const params = {
-    title,
-    isView: title === "查看",
-    row: { ...row },
-    api: title === "新增" ? addStoreUser : title === "编辑" ? editStoreUser : undefined,
-    getTableList: proTable.value?.getTableList
-  };
-  drawerRef.value?.acceptParams(params);
-};
-
-// 删除商户信息
-const deleteAccount = async (params: StoreUser.ResStoreUserList) => {
-  await useHandleData(deleteStoreInfo, { id: params.id }, `删除【${params.storeName}】商铺与管理账户`);
-  proTable.value?.getTableList();
-};
-
-// 重置用户密码
-const resetPass = async (params: StoreUser.ResStoreUserList) => {
-  await useHandleData(resetStoreUserPassWord, { id: params.id }, `重置【${params.storeName}】】商铺与管理账户密码`);
-  proTable.value?.getTableList();
-};
-
-//跳转至新增页面
-const handleToDetail = (type: string, id?: string) => {
-  router.push({
-    path: `/store/storeInfo/storeInfoDetail`,
-    query: {
-      id: id,
-      type: type
-    }
-  });
-  // router.push(`/store/storeInfo/storeInfoDetail`);
-};
-
-onMounted(async () => {
-  //获取商铺经营板块
-  await getBusinessSectionList();
-  await getTableList({});
-});
-
-onActivated(() => {
-  proTable.value?.getTableList();
-});
-//抽成比例部分
-const ccValue = ref(30);
-const ccValuefix = ref(30);
-const drawer = ref(false);
-const direction = ref<DrawerProps["direction"]>("rtl");
-function cancelClick() {
-  drawer.value = false;
-}
-const storeId = ref("");
-const confirmClick = async () => {
-  let params = {
-    id: storeId.value,
-    commissionRate: ccValue.value
-  };
-  let res = await updateStoreCommissionRate(params);
-  if (res.code == "200") {
-    ElMessage.success("设置抽成比例成功!");
-    ccValuefix.value = ccValue.value;
-    drawer.value = false;
-    proTable.value?.getTableList();
-  } else {
-    ElMessage.error("设置抽成比例失败!");
-  }
-};
-//这个是为了不让输入框输入超过100%
-function changeCCValue() {
-  if (ccValue.value < 0) {
-    ccValue.value = 0;
-  } else if (ccValue.value > 100) {
-    ccValue.value = 100;
-  }
-}
-//点击抽成百分比
-const handleCC = (item: any) => {
-  console.log(item, "点击抽成百分比");
-  storeId.value = item.id;
-  ccValue.value = item.commissionRate;
-  ccValuefix.value = item.commissionRate;
-  drawer.value = true;
-};
-const jjValue = ref<any>({});
-// 点击拒接
-const jj = (item: any) => {
-  dialogFormVisible.value = true;
-  form.reason = "";
-  jjValue.value = item;
-};
-// 点击拒绝确定
-const jjQd = async () => {
-  let res = await approveStoreInfo({
-    id: jjValue.value.id,
-    approvalStatus: 2,
-    reason: form.reason
-  });
-  if (res.code == "200") {
-    dialogFormVisible.value = false;
-    proTable.value?.getTableList();
-    ElMessage.success("审核拒绝成功!");
-  } else {
-    ElMessage.error("审核拒绝失败!");
-  }
-};
-</script>
-
-<style scoped lang="scss">
-.topTitle {
-  width: 100%;
-  padding: 14px;
-  margin-bottom: 4vh;
-  font-weight: 600;
-  color: white;
-  background-color: rgb(64 149 229);
-  border-radius: 6px;
-}
-.inputcc {
-  margin-bottom: 4vh;
-  > span {
-    display: block;
-    margin-bottom: 8px;
-  }
-}
-.zysx {
-  padding: 16px;
-  font-family: serif;
-  font-weight: 400;
-  color: black;
-  background-color: rgb(212 212 212);
-  border-radius: 6px;
-  > span {
-    display: block;
-    margin-bottom: 8px;
-  }
-}
-.zysx2 {
-  font-family: serif;
-  background-color: rgb(240 187 125);
-  > div {
-    margin-left: 1.5%;
-  }
-}
-::v-deep .el-drawer__footer {
-  > div {
-    display: flex;
-    justify-content: space-around;
-    button {
-      width: 6vw;
-    }
-  }
-}
-</style>

+ 0 - 132
src/views/store/storeUser/index_old.vue

@@ -1,132 +0,0 @@
-<template>
-  <div class="table-box">
-    <ProTable
-      ref="proTable"
-      :columns="columns"
-      :request-api="getTableList"
-      :init-param="initParam"
-      :data-callback="dataCallback"
-      @drag-sort="sortTable"
-    >
-      <!-- 表格 header 按钮 -->
-      <template #tableHeader="scope">
-        <el-button type="primary" :icon="CirclePlus" @click="openDrawer('新增')"> 新增商铺及商铺管理员 </el-button>
-      </template>
-      <!-- Expand -->
-      <template #expand="scope">
-        {{ scope.row }}
-      </template>
-      <!-- usernameHeader -->
-      <template #usernameHeader="scope">
-        <el-button type="primary" @click="ElMessage.success('我是通过作用域插槽渲染的表头')">
-          {{ scope.column.label }}
-        </el-button>
-      </template>
-      <!-- createTime -->
-      <template #createTime="scope">
-        <el-button type="primary" link @click="ElMessage.success('我是通过作用域插槽渲染的内容')">
-          {{ scope.row.createTime }}
-        </el-button>
-      </template>
-      <!-- 表格操作 -->
-      <template #operation="scope">
-        <el-button type="primary" link :icon="EditPen" @click="openDrawer('编辑', scope.row)"> 编辑 </el-button>
-        <el-button type="primary" link :icon="Refresh" @click="resetPass(scope.row)"> 重置密码 </el-button>
-        <el-button type="primary" link :icon="Delete" @click="deleteAccount(scope.row)"> 删除 </el-button>
-      </template>
-    </ProTable>
-    <StoreUserDrawer ref="drawerRef" />
-    <ImportExcel ref="dialogRef" />
-  </div>
-</template>
-
-<script setup lang="tsx" name="useProTable">
-import { ref, reactive } from "vue";
-import { StoreUser } from "@/api/interface";
-import { ElMessage } from "element-plus";
-import ProTable from "@/components/ProTable/index.vue";
-import ImportExcel from "@/components/ImportExcel/index.vue";
-import StoreUserDrawer from "@/views/proTable/components/StoreUserDrawer.vue";
-import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
-import { CirclePlus, Delete, EditPen, Download, Upload, Refresh } from "@element-plus/icons-vue";
-import { getStoreUserList, addStoreUser, editStoreUser, deleteStoreUser, resetStoreUserPassWord } from "@/api/modules/storeUser";
-import { useHandleData } from "@/hooks/useHandleData";
-
-// 表格拖拽排序
-const sortTable = ({ newIndex, oldIndex }: { newIndex?: number; oldIndex?: number }) => {
-  console.log(newIndex, oldIndex);
-  console.log(proTable.value?.tableData);
-  ElMessage.success("修改列表排序成功");
-};
-
-// ProTable 实例
-const proTable = ref<ProTableInstance>();
-
-// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
-const initParam = reactive({ type: 1 });
-
-// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
-// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
-const dataCallback = (data: any) => {
-  return {
-    list: data.records,
-    total: data.total
-  };
-};
-
-// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
-// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
-const getTableList = (params: any) => {
-  let newParams = JSON.parse(JSON.stringify(params));
-  newParams.createTime && (newParams.startTime = newParams.createTime[0]);
-  newParams.createTime && (newParams.endTime = newParams.createTime[1]);
-  delete newParams.createTime;
-  return getStoreUserList(newParams);
-};
-
-// 表格配置项
-const columns = reactive<ColumnProps<StoreUser.ResStoreUserList>[]>([
-  { type: "selection", fixed: "left" },
-  { prop: "storeName", label: "商店名称", search: { el: "input", tooltip: "请输入商户名称" } },
-  { prop: "storeContact", label: "联系人" },
-  { prop: "storePhone", label: "联系电话", search: { el: "input", tooltip: "请输入联系人电话" } },
-  { prop: "storeTypeStr", label: "经营类型" },
-  { prop: "businessStatusStr", label: "状态" },
-  {
-    prop: "createdTime",
-    label: "创建时间",
-    width: 180,
-    search: {
-      span: 2,
-      props: { type: "datetimerange", valueFormat: "YYYY-MM-DD HH:mm:ss" },
-      defaultValue: ["2022-11-12 11:35:00", "2022-12-12 11:35:00"]
-    }
-  },
-  { prop: "operation", label: "操作", fixed: "right", width: 330 }
-]);
-
-// 打开 drawer(新增、查看、编辑)
-const drawerRef = ref<InstanceType<typeof StoreUserDrawer> | null>(null);
-const openDrawer = (title: string, row: Partial<StoreUser.ResStoreUserList> = {}) => {
-  const params = {
-    title,
-    isView: title === "查看",
-    row: { ...row },
-    api: title === "新增" ? addStoreUser : title === "编辑" ? editStoreUser : undefined,
-    getTableList: proTable.value?.getTableList
-  };
-  drawerRef.value?.acceptParams(params);
-};
-
-// 删除商户信息
-const deleteAccount = async (params: StoreUser.ResStoreUserList) => {
-  await useHandleData(deleteStoreUser, { id: params.id }, `删除【${params.storeName}】商铺与管理账户`);
-  proTable.value?.getTableList();
-};
-
-// 重置用户密码
-const resetPass = async (params: StoreUser.ResStoreUserList) => {
-  await useHandleData(resetStoreUserPassWord, { id: params.id }, `重置【${params.storeName}】】商铺与管理账户密码`);
-  proTable.value?.getTableList();
-};
-</script>

+ 0 - 916
src/views/store/storeUser/storeInfoDetail.vue

@@ -1,916 +0,0 @@
-<template>
-  <div class="table-box" style="width: 100%; min-height: 100%; background-color: white">
-    <div class="content">
-      <div class="contentLeft">
-        <!-- 账号绑定模块 -->
-        <div class="model">
-          <h3 style="font-weight: bold">账号绑定:</h3>
-          <el-form :model="storeInfoModel" :rules="rules" label-width="120px" ref="ruleFormRef" class="formBox">
-            <el-form-item label="用户:" prop="userAccount">
-              <el-select
-                v-model="storeInfoModel.userAccount"
-                class="m-2"
-                placeholder="请选择要绑定的用户"
-                size="large"
-                :disabled="isDisabled"
-              >
-                <el-option v-for="item in userOptions" :key="item.id" :label="item.name" :value="item.id" />
-              </el-select>
-            </el-form-item>
-          </el-form>
-        </div>
-        <!-- 商铺信息设置模块 -->
-        <div class="model">
-          <h3 style="font-weight: bold">商铺信息:</h3>
-          <el-form :model="storeInfoModel" ref="ruleFormRef2" :rules="rules" label-width="120px" class="formBox">
-            <el-form-item label="商店名称" prop="storeName">
-              <el-input
-                :disabled="isDisabled"
-                maxlength="50"
-                v-model="storeInfoModel!.storeName"
-                placeholder="请填写商店名称"
-                clearable
-              />
-            </el-form-item>
-            <el-form-item label="容纳人数" prop="storeCapacity">
-              <el-input-number
-                type="storeCapacity"
-                :disabled="isDisabled"
-                v-model="storeInfoModel!.storeCapacity"
-                placeholder="容纳人数"
-                clearable
-                :min="0"
-                :max="9999999"
-              />
-            </el-form-item>
-            <el-form-item label="门店电话" prop="storeTel">
-              <el-input
-                :disabled="isDisabled"
-                v-model="storeInfoModel!.storeTel"
-                maxlength="15"
-                placeholder="请填写门店电话"
-                clearable
-              />
-            </el-form-item>
-            <el-form-item label="门店面积" prop="storeArea">
-              <el-radio-group :disabled="isDisabled" v-model="storeInfoModel!.storeArea" class="ml-4">
-                <el-radio v-for="storeArea in storeAreaList" :value="storeArea.value" :key="storeArea.value">
-                  {{ storeArea.label }}
-                </el-radio>
-              </el-radio-group>
-            </el-form-item>
-            <!--            <el-form-item label="是否连锁" prop="isChain">-->
-            <!--              <el-radio-group :disabled="isDisabled" v-model="storeInfoModel!.isChain" class="ml-4">-->
-            <!--                <el-radio label="0" :value="0"> 否 </el-radio>-->
-            <!--                <el-radio label="1" :value="1"> 是 </el-radio>-->
-            <!--              </el-radio-group>-->
-            <!--            </el-form-item>-->
-            <el-form-item label="详细地址" prop="storeAddress">
-              <el-input
-                maxlength="100"
-                :disabled="isDisabled"
-                v-model="storeInfoModel!.storeAddress"
-                :rows="2"
-                type="textarea"
-                placeholder="请输入详细地址"
-              />
-            </el-form-item>
-            <el-form-item label="行政区域" prop="district">
-              <el-cascader :props="props" :disabled="isDisabled" v-model="storeInfoModel!.district" style="width: 100%" />
-            </el-form-item>
-            <el-form-item label="门店简介" prop="storeBlurb">
-              <el-input
-                maxlength="100"
-                :disabled="isDisabled"
-                v-model="storeInfoModel!.storeBlurb"
-                :rows="2"
-                type="textarea"
-                placeholder="请输入门店简介"
-              />
-            </el-form-item>
-            <el-form-item label="经营板块" prop="businessSection">
-              <el-radio-group
-                :disabled="isDisabled"
-                @change="changeSection"
-                v-model="storeInfoModel!.businessSection"
-                class="ml-4"
-              >
-                <el-radio
-                  v-for="businessSection in businessSectionList"
-                  :value="businessSection.value"
-                  :key="businessSection.value"
-                >
-                  {{ businessSection.label }}
-                </el-radio>
-              </el-radio-group>
-              <span v-if="!isDisabled" style="margin-right: 10px">没有相应板块,点击这里</span>
-              <el-icon v-if="!isDisabled" style="cursor: pointer" @click="addSection" color="#409EFC" class="no-inherit">
-                <Plus />
-              </el-icon>
-            </el-form-item>
-            <el-form-item label="经营种类" prop="businessTypes">
-              <el-checkbox-group :disabled="isDisabled" v-model="storeInfoModel!.businessTypes">
-                <el-checkbox v-for="bt in businessTypes" :key="bt.value" :value="bt.value" :label="bt.label">
-                  {{ bt.label }}
-                  <el-tooltip
-                    class="box-item"
-                    effect="dark"
-                    content="指射箭、射击、赛车、攀岩、滑翔伞、滑雪滑冰等"
-                    placement="top"
-                  >
-                    <el-icon v-if="bt.label == '休闲运动'" :size="13">
-                      <QuestionFilled />
-                    </el-icon>
-                  </el-tooltip>
-                </el-checkbox>
-              </el-checkbox-group>
-            </el-form-item>
-          </el-form>
-        </div>
-      </div>
-      <div class="contentRight">
-        <el-form :model="storeInfoModel" ref="ruleFormRef3" :rules="rules" label-width="120px" class="formBox">
-          <el-form-item label="门店状态" prop="storeStatus">
-            <el-radio-group :disabled="isDisabled" v-model="storeInfoModel!.storeStatus" class="ml-4">
-              <el-radio v-for="status in storeStatusList" :value="status.value" :key="status.value">
-                {{ status.label }}
-              </el-radio>
-            </el-radio-group>
-          </el-form-item>
-          <el-form-item label="门店营业状态" prop="businessStatus">
-            <el-radio-group :disabled="isDisabled" v-model="storeInfoModel!.businessStatus" class="ml-4">
-              <el-radio v-for="status in businessStatusList" :value="status.value" :key="status.value">
-                {{ status.label }}
-              </el-radio>
-            </el-radio-group>
-          </el-form-item>
-          <el-form-item label="经度" prop="storePositionLongitude">
-            <el-input disabled v-model="storeInfoModel!.storePositionLongitude" placeholder="请填写经度" clearable />
-          </el-form-item>
-          <el-form-item label="纬度" prop="storePositionLatitude">
-            <el-input disabled v-model="storeInfoModel!.storePositionLatitude" placeholder="请填写纬度" clearable />
-          </el-form-item>
-          <el-form-item v-if="!isDisabled" label="经纬度查询">
-            <!-- <el-input v-model="addressName" placeholder="请填写地址后点击查询经纬度按钮" clearable />
-            <br />
-            <el-button type="primary" @click="getLonAndLatByAddressFun">查询经纬度</el-button> -->
-
-            <el-select
-              v-model="addressName"
-              filterable
-              placeholder="请输入地址进行查询"
-              remote
-              reserve-keyword
-              :remote-method="getLonAndLat"
-              @blur="clearInput"
-              @change="selectAddress"
-            >
-              <el-option v-for="item in addressList" :key="item.id" :label="item.name" :value="item.location">
-                <span style="float: left">{{ item.name }}</span>
-                <span style="float: right; font-size: 13px; color: var(--el-text-color-secondary)">{{ item.district }}</span>
-              </el-option>
-            </el-select>
-          </el-form-item>
-
-          <el-form-item label="店铺到期时间" prop="expirationTime">
-            <el-date-picker
-              :disabled="isDisabled"
-              v-model="storeInfoModel!.expirationTime"
-              format="YYYY/MM/DD hh:mm:ss"
-              value-format="YYYY-MM-DD h:m:s"
-              type="datetime"
-              placeholder="请选择店铺到期时间"
-            />
-            <!-- {{ drawerProps.row!.expirationTime }} -->
-          </el-form-item>
-          <el-form-item label="食品经营许可证到期时间" prop="foodLicenceExpirationTime">
-            <el-date-picker
-              :disabled="isDisabled"
-              v-model="storeInfoModel!.foodLicenceExpirationTime"
-              format="YYYY/MM/DD hh:mm:ss"
-              value-format="YYYY-MM-DD h:m:s"
-              type="datetime"
-              placeholder="请选择到期时间"
-            />
-          </el-form-item>
-          <!-- <el-form-item label="门店密码" prop="storePass">
-            <el-input
-              :disabled="isDisabled"
-              type="password"
-              v-model="storeInfoModel!.storePass"
-              placeholder="请填写门店密码"
-              clearable
-              maxlength="6"
-            />
-          </el-form-item> -->
-          <el-form-item label="营业执照" prop="fileList">
-            <template v-if="isDisabled">
-              <div
-                v-for="(item, idx) in storeInfoModel.fileList"
-                :key="item.url || idx"
-                style="width: 150px; height: 150px; overflow: hidden; border: 1px solid rgb(0 0 0 / 10%); border-radius: 6px"
-              >
-                <el-image :src="item.url" style="width: 100%; height: 100%" fit="contain" />
-              </div>
-            </template>
-            <el-upload
-              v-else
-              v-model:file-list="storeInfoModel!.fileList"
-              :action="uploadUrl"
-              list-type="picture-card"
-              :accept="'.jpg,.png'"
-              :limit="1"
-              :on-preview="handlePictureCardPreview"
-              :on-remove="handleRemove"
-              :on-success="handleSuccess"
-              :show-file-list="true"
-            >
-              <el-icon>
-                <Plus />
-              </el-icon>
-            </el-upload>
-          </el-form-item>
-          <el-form-item label="合同图片" prop="contractImage">
-            <div v-if="isDisabled" style="display: flex; gap: 10px">
-              <div
-                v-for="(item, idx) in storeInfoModel.contractImage"
-                :key="item.url || idx"
-                style="width: 150px; height: 150px; overflow: hidden; border: 1px solid rgb(0 0 0 / 10%); border-radius: 6px"
-              >
-                <el-image :src="item.url" style="width: 100%; height: 100%" fit="contain" />
-              </div>
-            </div>
-            <el-upload
-              v-else
-              v-model:file-list="storeInfoModel!.contractImage"
-              :action="uploadUrl"
-              list-type="picture-card"
-              :accept="'.jpg,.png'"
-              :on-preview="handlePictureCardPreview"
-              :on-remove="handleContractRemove"
-              :on-success="handleContractSuccess"
-              :show-file-list="true"
-            >
-              <el-icon>
-                <Plus />
-              </el-icon>
-            </el-upload>
-          </el-form-item>
-          <el-form-item label="食品经营许可证" prop="foodLicenceImage">
-            <template v-if="isDisabled">
-              <div
-                v-for="(item, idx) in storeInfoModel.foodLicenceImage"
-                :key="item.url || idx"
-                style="width: 150px; height: 150px; overflow: hidden; border: 1px solid rgb(0 0 0 / 10%); border-radius: 6px"
-              >
-                <el-image :src="item.url" style="width: 100%; height: 100%" fit="contain" />
-              </div>
-            </template>
-            <el-upload
-              v-else
-              v-model:file-list="storeInfoModel!.foodLicenceImage"
-              :action="uploadUrl"
-              list-type="picture-card"
-              :accept="'.jpg,.png'"
-              :on-preview="handlePictureCardPreview"
-              :on-remove="handleFoodLicenceRemove"
-              :on-success="handleFoodLicenceSuccess"
-              :show-file-list="true"
-              :limit="1"
-            >
-              <el-icon>
-                <Plus />
-              </el-icon>
-            </el-upload>
-          </el-form-item>
-          <!--          <el-form-item label="创建时间" v-if="type !== 'add'">-->
-          <!--            <el-date-picker-->
-          <!--              :disabled="isDisabled"-->
-          <!--              v-model="storeInfoModel!.createdTime"-->
-          <!--              format="YYYY/MM/DD hh:mm:ss"-->
-          <!--              value-format="YYYY-MM-DD h:m:s"-->
-          <!--              type="datetime"-->
-          <!--              placeholder="请选择创建时间"-->
-          <!--              readonly-->
-          <!--            />-->
-          <!--          </el-form-item>-->
-
-          <!--          <el-form-item label="审核状态" prop="storeApplicationStatus" v-if="type !== 'add'">-->
-          <!--            <el-input :disabled="isDisabled" :value="storeApplicationStatusText" readonly placeholder="请填写审核状态" />-->
-          <!--          </el-form-item>-->
-
-          <el-form-item label="拒绝原因" v-if="type !== 'add' && storeApplicationStatusText === '审核拒绝'">
-            <el-input :disabled="isDisabled" :value="storeInfoModel!.reason || '暂无'" readonly placeholder="请填写拒接原因" />
-          </el-form-item>
-
-          <el-form-item label="抽成比例" prop="commissionRate">
-            <el-input
-              maxlength="50"
-              :disabled="true"
-              v-model="storeInfoModel!.commissionRate"
-              placeholder="请填写抽成比例"
-              clearable
-              type="number"
-            />
-          </el-form-item>
-        </el-form>
-        <!--图片预览-->
-        <el-dialog v-model="imagePopupVisible" title="预览" width="30%">
-          <el-image style="width: 100%" :src="previewImage" fit="contain" />
-        </el-dialog>
-        <el-button @click="goBack"> 返回 </el-button>
-        <el-button v-if="type != 'show'" type="primary" @click="handleSubmit"> 确定 </el-button>
-      </div>
-    </div>
-    <!-- 新增分类dialog -->
-    <el-dialog v-model="addSectionDialogVisible" title="新增经营板块" width="30%" :before-close="closeSection">
-      <el-form :model="userAccountModel" label-width="120px">
-        <el-form-item label="经营板块名称" prop="storeName">
-          <el-input v-model="sectionSectionName" placeholder="请填写经营板块名称" clearable />
-        </el-form-item>
-        <el-form-item label="经营类型英文值" prop="storeName">
-          <el-input v-model="businessTypeValue" placeholder="请填写经营类型英文值" clearable />
-        </el-form-item>
-        <el-form-item label="经营种类" prop="storeName">
-          <el-tag
-            v-for="tag in sectionSectionTypes"
-            :key="tag"
-            class="mx-1"
-            closable
-            :disable-transitions="false"
-            @close="handleClose(tag)"
-          >
-            {{ tag }}
-          </el-tag>
-          <el-input
-            v-if="sectionTypeVisable"
-            ref="InputRef"
-            v-model="sectionTypeValue"
-            class="ml-1 w-20"
-            size="small"
-            @keyup.enter="handleInputConfirm"
-            @blur="handleInputConfirm"
-          />
-          <el-button v-else class="button-new-tag ml-1" size="small" @click="showInput"> + 新增分类 </el-button>
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <span class="dialog-footer">
-          <el-button @click="closeSection()">取消</el-button>
-          <el-button type="primary" @click="addBusinessSectionTypes"> 确定</el-button>
-        </span>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup lang="tsx" name="useProTable">
-import { ref, reactive, computed, onMounted, nextTick } from "vue";
-import { StoreUser } from "@/api/interface";
-import { ElMessage } from "element-plus";
-import ProTable from "@/components/ProTable/index.vue";
-import ImportExcel from "@/components/ImportExcel/index.vue";
-import StoreUserDrawer from "@/views/proTable/components/StoreUserDrawer.vue";
-import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
-import {
-  CirclePlus,
-  Delete,
-  EditPen,
-  Download,
-  Upload,
-  Refresh,
-  Check,
-  Close,
-  Search,
-  QuestionFilled
-} from "@element-plus/icons-vue";
-import {
-  getStoreUserList,
-  addStoreUser,
-  editStoreUser,
-  deleteStoreUser,
-  resetStoreUserPassWord,
-  getStoreAuditStatus,
-  getBusinessSection,
-  getBusinessSectionTypes,
-  getUnboundAccountList,
-  addBusinessSectionAndTypes,
-  saveStoreInfo,
-  getStoreDetail,
-  editStoreInfo,
-  getInputPrompt,
-  getDistrict
-} from "@/api/modules/storeUser";
-import { useHandleData } from "@/hooks/useHandleData";
-import { useRouter, useRoute } from "vue-router";
-import type { UploadProps, UploadUserFile, FormInstance } from "element-plus";
-import { forEach } from "lodash";
-
-const imagePopupVisible = ref(false);
-
-const rules = reactive({
-  storeName: [{ required: true, message: "请填写商户名称" }],
-  storeContact: [{ required: true, message: "请填写联系人" }],
-  name: [{ required: true, message: "请填写联系人" }],
-  storePhone: [{ required: true, message: "请填写联系人电话" }],
-  phone: [{ required: true, message: "请填写联系人电话" }],
-  password: [{ required: true, message: "请填写密码" }],
-  payPassword: [{ required: true, message: "请填写支付密码" }],
-  storeCapacity: [{ required: true, message: "请填写容纳人数" }],
-  storeTel: [{ required: true, message: "请填写门店电话" }],
-  isChain: [{ required: true, message: "请选择是否连锁" }],
-  storeAddress: [{ required: true, message: "请输入详细地址" }],
-  district: [{ required: true, message: "请选择行政区域" }],
-  storeBlurb: [{ required: true, message: "请输入门店简介" }],
-  storeTypeList: [{ required: true, message: "请选择经营种类" }],
-  storeStatus: [{ required: true, message: "请选择门店状态" }],
-  businessStatus: [{ required: true, message: "请选择门店营业状态" }],
-  storePositionLongitude: [{ required: true, message: "请选择门店经度" }],
-  storePositionLatitude: [{ required: true, message: "请选择门店纬度" }],
-  expirationTime: [{ required: true, message: "请选择门店到期时间" }],
-  foodLicenceExpirationTime: [{ required: true, message: "请选择门店经营许可证到期时间" }],
-  storePass: [{ required: true, message: "请输入门店密码" }],
-  storeArea: [{ required: true, message: "请选择门店面积" }],
-  businessSection: [{ required: true, message: "请选择经营板块" }],
-  businessTypes: [{ required: true, message: "请选择经营种类" }],
-  userAccount: [{ required: true, message: "请选择用户账号" }],
-  fileList: [{ required: true, message: "请上传营业执照" }],
-  contractImage: [{ required: true, message: "请上传合同图片" }],
-  foodLicenceImage: [{ required: true, message: "请上传食品经营许可证图片" }],
-  commissionRate: [{ required: true, message: "请填写抽成比例" }],
-  // createdTime: [{ required: true, message: "请选择创建时间" }],
-  storeApplicationStatus: [{ required: true, message: "请填写审核状态" }]
-  // reason: [{ required: true, message: "请填写拒绝原因" }],
-});
-//文件上传地址
-const uploadUrl = ref(`${import.meta.env.VITE_API_URL_STORE}/file/upload`);
-//行政区域组件
-const props: any = {
-  lazy: true,
-  async lazyLoad(node, resolve) {
-    const { level } = node;
-    try {
-      let param = { adCode: node.data.adCode ? node.data.adCode : "" };
-      // 调用后台接口获取数据
-      const response: any = await getDistrict(param as any);
-      // 转换数据格式
-      const nodes = (response?.data?.districts?.[0]?.districts || []).map((item: any) => ({
-        value: item.adcode,
-        adCode: item.adcode,
-        label: item.name,
-        leaf: level >= 2 // 假设最多三级,可以根据实际需求调整
-      }));
-
-      // 返回数据
-      resolve(nodes);
-    } catch (error) {
-      console.error("获取区域数据失败:", error);
-      resolve([]);
-    }
-  }
-};
-const fileList = ref<UploadUserFile[]>([]);
-
-const router = useRouter();
-const route = useRoute();
-const InputRef = ref<any>();
-//页面操作列是否禁用
-const isDisabled = ref<boolean>(false);
-//进入页面类型(新增:add,查看:show,编辑:edit)
-//用户账号
-const userAccountModel = ref<any>({ userAccount: "" });
-//新增板块
-const storeSectionModel = ref<any>({ sectionName: "", types: [] });
-//页面展开类型
-const type = ref<string>("");
-//页面id参数
-const id = ref<string>("");
-//地址名称
-const addressName = ref<string>("");
-//查询地址名称
-const queryAddress = ref<string>("");
-//地址集合
-const addressList = ref<any[]>([]);
-
-//商铺信息模块
-const storeInfoModel = ref<any>({
-  //店铺名称
-  storeName: "",
-  //容纳人数
-  storeCapacity: "1",
-  //门店电话
-  storeTel: "",
-  //门店面积
-  storeArea: 1,
-  //是否连锁
-  isChain: 1,
-  //详细地址
-  storeAddress: "",
-  //门店简介
-  storeBlurb: "",
-  //经营板块
-  businessSection: "1",
-  //经营种类
-  businessTypes: [],
-  //营业执照
-  fileList: [],
-  //用户账号id
-  userAccount: "",
-  //门店状态
-  storeStatus: 1,
-  //门店营业状态
-  businessStatus: 0,
-  //行政区域
-  district: [],
-  // 抽成比例
-  commissionRate: "3",
-  // 创建时间
-  createdTime: "",
-  // 审核状态
-  storeApplicationStatus: "",
-  // 拒绝原因
-  reason: ""
-});
-//用户列表
-const userOptions = ref<StoreUser.UserOptions[]>([]);
-//用户经营板块对话框开启标识
-const addSectionDialogVisible = ref<boolean>(false);
-//添加板块类型开启标识
-const sectionTypeVisable = ref<boolean>(false);
-//添加板块类型值
-const sectionTypeValue = ref<string>("");
-//添加板块类型名称
-const sectionSectionName = ref<string>("");
-//添加板块类型英文值
-const businessTypeValue = ref<string>("");
-//添加板块类型名称
-const sectionSectionTypes = ref<string[]>([]);
-//营业执照图片集合
-const videoUrlList = ref<string[]>([]);
-//合同图片集合
-const contractImageList = ref<string[]>([]);
-//合同图片集合
-const foodLicenceImageList = ref<string[]>([]);
-
-// 门店面积列表
-const storeAreaList = ref<any[]>([
-  { value: 1, label: "小于20平米" },
-  { value: 2, label: "20~50平米" },
-  { value: 3, label: "50~100平米" },
-  { value: 4, label: "100~300平米" },
-  { value: 5, label: "300~500平米" },
-  { value: 6, label: "500~1000平米" },
-  { value: 7, label: "大于1000平米" }
-]);
-// 经营板块列表
-const businessSectionList = ref<any[]>([]);
-//经营种类列表
-const businessTypes = ref<any[]>([]);
-//获取用户列表
-const getUserOptions = async () => {
-  let res: any = await getUnboundAccountList({ id: id.value } as any);
-  //todo 此处修改成调用接口
-  // let a = { name: "张三", id: 1 };
-  // let b = { name: "李四", id: 2 };
-  (res?.data || []).forEach((element: any) => {
-    let addData = {
-      name: `${element.phone}(${element.name ? element.name : "未知"})`,
-      id: element.id
-    };
-    userOptions.value.push(addData);
-  });
-};
-// 门店状态列表(0: 禁用,1: 正常)
-const storeStatusList = ref<any[]>([
-  { value: 0, label: "禁用" },
-  { value: 1, label: "正常" }
-]);
-// 门店营业状态列表
-const businessStatusList = ref<any[]>([
-  { value: 0, label: "正常营业" },
-  { value: 1, label: "暂停营业" },
-  { value: 2, label: "筹建中" },
-  { value: 99, label: "永久关门" }
-]);
-//新增经营板块
-const addSection = () => {
-  addSectionDialogVisible.value = true;
-};
-//关闭新增经营板块弹窗
-const closeSection = () => {
-  sectionSectionName.value = "";
-  businessTypeValue.value = "";
-  sectionSectionTypes.value = [];
-  addSectionDialogVisible.value = false;
-};
-//删除门店经营板块分类
-const handleClose = (tag: string) => {
-  storeSectionModel.value.types.splice(storeSectionModel.value.types.indexOf(tag), 1);
-};
-//新增标签
-const handleInputConfirm = () => {
-  if (sectionTypeValue.value) {
-    sectionSectionTypes.value.push(sectionTypeValue.value);
-  }
-  sectionTypeVisable.value = false;
-  sectionTypeValue.value = "";
-};
-//展示新增标签input
-const showInput = () => {
-  sectionTypeVisable.value = true;
-  nextTick(() => {
-    InputRef.value!.input!.focus();
-  });
-};
-//返回上一页
-const goBack = () => {
-  router.go(-1);
-};
-const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
-  videoUrlList.value = [];
-};
-
-const handleSuccess = (response: any, uploadFile: UploadUserFile) => {
-  ElMessage.success("执照上传成功");
-  console.log(response);
-  if (response.data) {
-    videoUrlList.value.push(response.data);
-    // videoUrl.value = response.data;
-  }
-  console.log("videoUrlList.value ===> ", videoUrlList.value);
-};
-
-const handleContractRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
-  contractImageList.value = [];
-  (uploadFiles || []).forEach((f: any) => {
-    if (f.url) contractImageList.value.push(f.url);
-  });
-  // storeInfoModel.value.contractImageList = storeInfoModel.value.contractImageList.filter(item => item.uid !== uploadFile.uid)
-};
-
-const handleContractSuccess = (response: any, uploadFile: UploadUserFile) => {
-  ElMessage.success("合同上传成功");
-  if (response.data) {
-    contractImageList.value.push(response.data);
-  }
-  console.log(contractImageList.value);
-};
-
-const handleFoodLicenceSuccess = (response: any, uploadFile: UploadUserFile) => {
-  ElMessage.success("食品经营许可上传成功");
-  if (response.data) {
-    foodLicenceImageList.value.push(response.data);
-  }
-  console.log(response);
-};
-
-const handleFoodLicenceRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
-  foodLicenceImageList.value = [];
-  (uploadFiles || []).forEach((item: any) => {
-    if (item.url) foodLicenceImageList.value.push(item.url);
-  });
-  console.log("foodLicenceImageList.value ===> ", foodLicenceImageList.value);
-};
-
-const getBusinessSectionList = async () => {
-  let res: any = await getBusinessSection();
-  let addData: any[] = [];
-  (res?.data || []).forEach((element: any) => {
-    addData.push({ value: element.dictId, label: element.dictDetail, parentId: element.parentId });
-  });
-  //默认 storeInfoModel!.businessSection 为第一个元素
-  storeInfoModel.value.businessSection = addData[0].value;
-  businessSectionList.value = addData;
-  changeSection();
-};
-
-const changeSection = async () => {
-  storeInfoModel.value.businessTypes = [];
-  //获取经营种类
-  const resType: any = await getBusinessSectionTypes({ parentId: storeInfoModel.value.businessSection } as any);
-  let addData: any[] = [];
-  (resType?.data || []).forEach((element: any) => {
-    addData.push({ value: element.dictId, label: element.dictDetail, parentId: element.parentId });
-  });
-  businessTypes.value = addData;
-  if (type.value == "add") {
-    storeInfoModel.value.businessTypes = ["0"];
-  }
-};
-
-const addBusinessSectionTypes = async () => {
-  let param = {
-    businessSectionName: sectionSectionName.value,
-    businessTypeValue: businessTypeValue.value,
-    businessTypesList: sectionSectionTypes.value
-  };
-  let res: any = await addBusinessSectionAndTypes(param as any);
-  if (res.code == "200") {
-    ElMessage.success("新增成功!");
-    addSectionDialogVisible.value = false;
-    sectionSectionName.value = "";
-    businessTypeValue.value = "";
-    sectionSectionTypes.value = [];
-    getBusinessSectionList();
-  } else {
-    ElMessage.error("新增失败!");
-  }
-};
-
-const getLonAndLat = async (keyword: string) => {
-  if (keyword) {
-    console.log("地址查询", keyword);
-    let param = {
-      addressName: keyword
-    };
-    let res: any = await getInputPrompt(param as any);
-    if (res.code == "200") {
-      addressList.value = res?.data?.tips || [];
-      console.log("res", res);
-    } else {
-      ElMessage.error("新增失败!");
-    }
-  } else {
-    addressList.value = [];
-  }
-};
-
-const clearInput = async () => {};
-
-const selectAddress = async (param: any) => {
-  console.log("addressName.value", addressName.value);
-  let locationList = addressName.value.split(",");
-  addressList.value.forEach((item: any) => {
-    if (item.location == addressName.value) {
-      queryAddress.value = item.name;
-    }
-  });
-  console.log("locationList", locationList);
-  storeInfoModel.value.storePositionLongitude = locationList[0];
-  storeInfoModel.value.storePositionLatitude = locationList[1];
-};
-
-// const handlePictureCardPreview: UploadProps["onPreview"] = uploadFile => {};
-const previewImage = ref("");
-const handlePictureCardPreview = (e: any) => {
-  imagePopupVisible.value = true;
-  previewImage.value = e.url;
-};
-
-const closeImagePopup = () => {
-  imagePopupVisible.value = false;
-  previewImage.value = "";
-};
-
-// 提交数据(新增/编辑)
-const ruleFormRef = ref<FormInstance>();
-const ruleFormRef2 = ref<FormInstance>();
-const ruleFormRef3 = ref<FormInstance>();
-const handleSubmit = () => {
-  ruleFormRef.value!.validate(async valid => {
-    if (!valid) return;
-    ruleFormRef2.value!.validate(async valid2 => {
-      if (!valid2) return;
-      ruleFormRef3.value!.validate(async valid3 => {
-        if (!valid3) return;
-        if (!storeInfoModel.value.district[0] || !storeInfoModel.value.district[1] || !storeInfoModel.value.district[2]) {
-          ElMessage.error("请完整选择行政区域");
-          return;
-        }
-        let param: any = storeInfoModel.value;
-        param.queryAddress = queryAddress.value;
-        console.log("videoUrlList.value ===> ", videoUrlList.value);
-        console.log("storeInfoModel.value ===> ", storeInfoModel.value);
-        param.businessLicenseAddress = videoUrlList.value;
-        param.contractImageList = handleImageResult(contractImageList.value);
-        let arr = handleImageResult(foodLicenceImageList.value);
-        param.foodLicenceUrl = arr.length > 0 ? arr[0] : "";
-        param.createTime = null;
-        param.updatedTime = null;
-        param.administrativeRegionProvinceAdcode = storeInfoModel.value.district[0];
-        param.administrativeRegionCityAdcode = storeInfoModel.value.district[1];
-        param.administrativeRegionDistrictAdcode = storeInfoModel.value.district[2];
-        if (type.value == "add") {
-          let res = await saveStoreInfo(param);
-          if (res.code == "200") {
-            ElMessage.success("新增成功");
-            router.go(-1);
-          } else {
-            ElMessage.error("新增失败");
-          }
-        } else if (type.value == "edit") {
-          let res = await editStoreInfo(param);
-          if (res.code == "200") {
-            ElMessage.success("编辑成功");
-            router.go(-1);
-          } else {
-            ElMessage.error("编辑失败");
-          }
-        }
-      });
-    });
-  });
-};
-
-onMounted(async () => {
-  id.value = (route.query.id as string) || "";
-  type.value = (route.query.type as string) || "";
-  //调用获取用户列表
-  getUserOptions();
-  //获取商铺经营板块
-  await getBusinessSectionList();
-  if (type.value != "add") {
-    if (type.value == "show") {
-      isDisabled.value = true;
-    }
-    let res: any = await getStoreDetail({ id: id.value } as any);
-    storeInfoModel.value = res.data as any;
-    storeInfoModel.value.businessSection = storeInfoModel.value.businessSection + "";
-    storeInfoModel.value.userAccount = Number(storeInfoModel.value.userAccount);
-    await changeSection();
-    storeInfoModel.value.businessTypes = storeInfoModel.value.businessTypesList;
-    storeInfoModel.value.storePositionLongitude = storeInfoModel.value.storePosition.split(",")[0];
-    storeInfoModel.value.storePositionLatitude = storeInfoModel.value.storePosition.split(",")[1];
-    let district: any[] = [];
-    district[0] = storeInfoModel.value.administrativeRegionProvinceAdcode;
-    district[1] = storeInfoModel.value.administrativeRegionCityAdcode;
-    district[2] = storeInfoModel.value.administrativeRegionDistrictAdcode;
-    storeInfoModel.value.district = district;
-    videoUrlList.value = (res.data as any).businessLicenseAddress || [];
-    let fileList: any[] = [];
-    handleImageParam((res.data as any).businessLicenseAddress || [], fileList);
-
-    let contractImageList: any[] = [];
-    handleImageParam((res.data as any).contractImageList || [], contractImageList);
-
-    let foodLicenceImageList: any[] = [];
-    handleImageParam((res.data as any).foodLicenceImageList || [], foodLicenceImageList);
-
-    storeInfoModel.value.fileList = fileList;
-    storeInfoModel.value.contractImage = contractImageList;
-    storeInfoModel.value.contractImageList = contractImageList;
-    (contractImageList as any).value = contractImageList as any;
-    storeInfoModel.value.foodLicenceImage = foodLicenceImageList;
-    storeInfoModel.value.foodLicenceImageList = foodLicenceImageList;
-  }
-});
-//图片list 转换为upload 组件的参数
-const handleImageParam = (list: any[], result: any[]) => {
-  (list || []).forEach((item: any) => {
-    // 使用split方法以'/'为分隔符将URL拆分成数组
-    const parts = item.split("/");
-    // 取数组的最后一项,即图片名称
-    const imageName = parts[parts.length - 1];
-    result.push({
-      name: imageName,
-      percentage: 100,
-      url: item
-    });
-  });
-};
-
-const handleImageResult = (list: any[]) => {
-  let result: any[] = [];
-  (list || []).forEach((item: any) => {
-    if (item.uid) {
-      result.push(item.url);
-    } else {
-      result.push(item);
-    }
-  });
-  return result;
-};
-
-// 判断审核状态
-const storeApplicationStatusText = computed(() => {
-  const status = storeInfoModel.value.storeApplicationStatus;
-  if (status == 0) return "待审核";
-  if (status == 1) return "审核通过";
-  if (status == 2) return "审核拒绝";
-  return "";
-});
-</script>
-
-<style scoped lang="scss">
-.content {
-  display: flex;
-  width: 98%;
-  height: 98%;
-  margin: auto;
-  .contentLeft {
-    width: 50%;
-  }
-  .contentRight {
-    width: 50%;
-  }
-}
-.model {
-  margin-bottom: 50px;
-}
-.formBox {
-  width: 70%;
-}
-.table-box {
-  height: auto !important;
-}
-</style>

+ 0 - 219
src/views/store/storeUser/storeMaturityManagement.vue

@@ -1,219 +0,0 @@
-<template>
-  <div class="table-box">
-    <ProTable
-      ref="proTable"
-      :columns="columns"
-      :request-api="getTableList"
-      :init-param="initParam"
-      :data-callback="dataCallback"
-      @drag-sort="sortTable"
-    >
-      <!-- 表格 header 按钮 -->
-      <template #tableHeader="scope">
-        <el-button type="primary" :icon="Download" @click="exportInfoExcel()"> 导出 </el-button>
-      </template>
-      <!-- Expand -->
-      <template #expand="scope">
-        {{ scope.row }}
-      </template>
-      <!-- usernameHeader -->
-      <template #usernameHeader="scope">
-        <el-button type="primary" @click="ElMessage.success('我是通过作用域插槽渲染的表头')">
-          {{ scope.column.label }}
-        </el-button>
-      </template>
-      <!-- createTime -->
-      <template #createTime="scope">
-        <el-button type="primary" link @click="ElMessage.success('我是通过作用域插槽渲染的内容')">
-          {{ scope.row.createTime }}
-        </el-button>
-      </template>
-      <!-- 表格操作 -->
-      <template #operation="scope">
-        <el-button type="primary" link :icon="Search" @click="openDialogVisible(scope.row)"> 查看详情 </el-button>
-        <el-button type="primary" link :icon="Delete" @click="deleteAccount(scope.row)"> 删除 </el-button>
-        <!-- <el-button type="primary" link :icon="Refresh" @click="resetPass(scope.row)">重置密码</el-button> -->
-      </template>
-    </ProTable>
-
-    <!-- 查看详情 -->
-    <el-dialog v-model="dialogVisible" title="详情" width="30%" :before-close="handleClose">
-      <el-form label-width="100px" :model="model" style="max-width: 460px">
-        <el-form-item label="商店名称">
-          <el-input disabled v-model="model.storeName" />
-        </el-form-item>
-        <el-form-item label="经营板块">
-          <el-input disabled v-model="model.businessSectionName" />
-        </el-form-item>
-        <el-form-item label="到期状态">
-          <el-input disabled :value="getName(model.expiredState)" />
-        </el-form-item>
-        <el-form-item label="到期时间">
-          <el-input disabled v-model="model.expirationTime" />
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <span class="dialog-footer">
-          <el-button @click="dialogVisible = false">取消</el-button>
-          <el-button type="primary" @click="dialogVisible = false"> 确定 </el-button>
-        </span>
-      </template>
-    </el-dialog>
-    <ImportExcel ref="dialogRef" />
-  </div>
-</template>
-
-<script setup lang="tsx" name="useProTable">
-import { ref, reactive, computed, onActivated } from "vue";
-import { StoreUser } from "@/api/interface";
-import { ElMessage } from "element-plus";
-import ProTable from "@/components/ProTable/index.vue";
-import ImportExcel from "@/components/ImportExcel/index.vue";
-import StoreUserDrawer from "@/views/proTable/components/StoreUserDrawer.vue";
-import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
-import { CirclePlus, Delete, EditPen, Download, Upload, Refresh, Search } from "@element-plus/icons-vue";
-import { getStoreInfoList, exportExcelExpirationTime, deleteStoreInfo } from "@/api/modules/storeUser";
-import { useHandleData } from "@/hooks/useHandleData";
-
-const dialogVisible = ref<boolean>(false);
-const model = ref<StoreUser.ResStoreUserList>();
-//获取过期状态列表
-const getExpiredState = computed((params: any) => {
-  const list: any = [];
-  list.push({ label: "未到期", status: "0" });
-  list.push({ label: "即将到期", status: "1" });
-  list.push({ label: "已到期", status: "2" });
-  return list;
-});
-
-//导出信息
-const exportInfoExcel = async () => {
-  let params = proTable.value?.searchParam;
-  let res = await exportExcelExpirationTime(params);
-  console.log("导出res", res);
-  // link.href = "https://file.ailien.shop/excel/generate/storeCashOutRecord4.xlsx";
-  if (res.code == "200") {
-    if (!res.data) {
-      ElMessage.error("暂无可下载数据");
-      return;
-    }
-    const exportFile = document.createElement("a");
-    exportFile.style.display = "none";
-    exportFile.download = `商铺过期信息.xlsx`;
-    // return;
-    exportFile.href = `${res.data}?timestamp=${new Date().getTime()}`; // 添加时间戳防止缓存
-    // exportFile.href = ` https://file.ailien.shop/excel/generate/storeCashOutRecord4.xlsx?timestamp=${new Date().getTime()}`; // 添加时间戳防止缓存
-    https: document.body.appendChild(exportFile);
-    exportFile.click();
-    // 去除下载对 url 的影响
-    document.body.removeChild(exportFile);
-    ElMessage.success("下载成功");
-  }
-};
-
-// 表格拖拽排序
-const sortTable = ({ newIndex, oldIndex }: { newIndex?: number; oldIndex?: number }) => {
-  console.log(newIndex, oldIndex);
-  console.log(proTable.value?.tableData);
-  ElMessage.success("修改列表排序成功");
-};
-
-const getName = state => {
-  return state == "0" ? "未到期" : state == "1" ? "即将到期" : "已到期";
-};
-// ProTable 实例
-const proTable = ref<ProTableInstance>();
-
-// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
-const initParam = reactive({ type: 1 });
-
-// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
-// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
-const dataCallback = (data: any) => {
-  return {
-    list: data.records,
-    total: data.total
-  };
-};
-
-// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
-// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
-const getTableList = (params: any) => {
-  let newParams = JSON.parse(JSON.stringify(params));
-  newParams.createTime && (newParams.startTime = newParams.createTime[0]);
-  newParams.createTime && (newParams.endTime = newParams.createTime[1]);
-  delete newParams.createTime;
-  return getStoreInfoList(newParams);
-};
-
-// 表格配置项
-const columns = reactive<ColumnProps<StoreUser.ResStoreUserList>[]>([
-  { type: "selection", fixed: "left" },
-  { prop: "id", label: "商铺ID", search: { el: "input", tooltip: "请输入商户名称" } },
-  { prop: "storeName", label: "店铺名称" },
-  { prop: "businessSectionName", label: "经营板块" },
-  {
-    prop: "expirationTime",
-    label: "到期时间",
-    width: 180,
-    search: {
-      span: 2,
-      props: { type: "datetimerange", valueFormat: "YYYY-MM-DD HH:mm:ss" },
-      defaultValue: ["2022-11-12 11:35:00", "2022-12-12 11:35:00"]
-    }
-  },
-  {
-    prop: "daysToExpire",
-    label: "剩余天数",
-    render: scope => {
-      return scope.row.expiredState == "0" || scope.row.expiredState == "1" ? scope.row.daysToExpire : "0";
-    }
-  },
-  {
-    prop: "expiredState",
-    label: "状态",
-    render: scope => {
-      return scope.row.expiredState == "0" ? "未到期" : scope.row.expiredState == "1" ? "即将到期" : "已到期";
-    },
-    search: { el: "select" },
-    enum: getExpiredState,
-    fieldNames: { label: "label", value: "status" }
-  },
-  { prop: "operation", label: "操作", fixed: "right", width: 330 }
-]);
-
-// 打开 drawer(新增、查看、编辑)
-const drawerRef = ref<InstanceType<typeof StoreUserDrawer> | null>(null);
-const openDrawer = (title: string, row: Partial<StoreUser.ResStoreUserList> = {}) => {
-  const params = {
-    title,
-    isView: title === "查看",
-    row: { ...row },
-    api: title === "新增" ? addStoreUser : title === "编辑" ? editStoreUser : undefined,
-    getTableList: proTable.value?.getTableList
-  };
-  drawerRef.value?.acceptParams(params);
-};
-
-// 删除商户信息
-const deleteAccount = async (params: StoreUser.ResStoreUserList) => {
-  await useHandleData(deleteStoreInfo, { id: params.id }, `删除【${params.storeName}】商铺与管理账户`);
-  proTable.value?.getTableList();
-};
-
-// 重置用户密码
-const resetPass = async (params: StoreUser.ResStoreUserList) => {
-  await useHandleData(resetStoreUserPassWord, { id: params.id }, `重置【${params.storeName}】】商铺与管理账户密码`);
-  proTable.value?.getTableList();
-};
-
-const openDialogVisible = (params: StoreUser.ResStoreUserList) => {
-  dialogVisible.value = true;
-  params.expiredStateName = params.expiredState == "0" ? "未到期" : "已到期";
-  model.value = params;
-};
-
-onActivated(() => {
-  proTable.value?.getTableList();
-});
-</script>

+ 0 - 233
src/views/store/storeUser/storeUser.vue

@@ -1,233 +0,0 @@
-<template>
-  <div class="table-box">
-    <ProTable
-      ref="proTable"
-      :columns="columns"
-      :request-api="getTableList"
-      :init-param="initParam"
-      :data-callback="dataCallback"
-      @drag-sort="sortTable"
-    >
-      <!-- 表格 header 按钮 -->
-      <template #tableHeader="scope">
-        <el-button type="primary" :icon="CirclePlus" @click="openDrawer('新增')"> 新增 </el-button>
-        <el-button type="primary" :icon="Download" @click="exportUserInfoExcel()"> 导出 </el-button>
-      </template>
-      <!-- Expand -->
-      <template #expand="scope">
-        {{ scope.row }}
-      </template>
-      <!-- usernameHeader -->
-      <template #usernameHeader="scope">
-        <el-button type="primary" @click="ElMessage.success('我是通过作用域插槽渲染的表头')">
-          {{ scope.column.label }}
-        </el-button>
-      </template>
-      <!-- createTime -->
-      <template #createTime="scope">
-        <el-button type="primary" link @click="ElMessage.success('我是通过作用域插槽渲染的内容')">
-          {{ scope.row.createTime }}
-        </el-button>
-      </template>
-      <!-- 表格操作 -->
-      <template #operation="scope">
-        <el-button type="primary" link :icon="Search" @click="openDrawer('查看', scope.row)"> 查看详情 </el-button>
-        <!-- <el-button type="primary" link :icon="EditPen" @click="openDrawer('编辑', scope.row)">编辑</el-button> -->
-        <el-button
-          v-if="scope.row.status == 0 || scope.row.status == 1"
-          type="primary"
-          link
-          :icon="Refresh"
-          @click="resetPass(scope.row)"
-        >
-          重置密码
-        </el-button>
-        <el-button
-          :type="scope.row.status == 1 ? 'primary' : 'danger'"
-          link
-          v-if="scope.row.status == 0"
-          :icon="scope.row.status == 0 ? CircleCloseFilled : CircleCheckFilled"
-          @click="switchingStatesFun(scope.row)"
-        >
-          禁用
-        </el-button>
-        <el-button
-          :type="scope.row.status == 1 ? 'primary' : 'danger'"
-          link
-          v-if="scope.row.status == 1"
-          :icon="scope.row.status == 0 ? CircleCloseFilled : CircleCheckFilled"
-          @click="switchingStatesFun(scope.row)"
-        >
-          启用
-        </el-button>
-        <el-button type="primary" link :icon="Delete" @click="deleteAccount(scope.row)"> 删除 </el-button>
-      </template>
-    </ProTable>
-    <StoreUserDrawer ref="drawerRef" />
-    <ImportExcel ref="dialogRef" />
-  </div>
-</template>
-
-<script setup lang="tsx" name="useProTable">
-import { ref, reactive, computed } from "vue";
-import { StoreUser } from "@/api/interface";
-import { ElMessage } from "element-plus";
-import ProTable from "@/components/ProTable/index.vue";
-import ImportExcel from "@/components/ImportExcel/index.vue";
-import StoreUserDrawer from "@/views/proTable/components/StoreUserDrawer.vue";
-import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
-import {
-  CirclePlus,
-  Delete,
-  EditPen,
-  Download,
-  Upload,
-  Refresh,
-  CircleCloseFilled,
-  CircleCheckFilled,
-  Search
-} from "@element-plus/icons-vue";
-import {
-  getStoreUserList,
-  addStoreUser,
-  editStoreUser,
-  deleteStoreUser,
-  resetStoreUserPassword,
-  switchingStates,
-  exportUserExcel
-} from "@/api/modules/storeUser";
-import { useHandleData } from "@/hooks/useHandleData";
-
-//导出信息
-const exportUserInfoExcel = async () => {
-  let params = proTable.value?.searchParam;
-  let res = await exportUserExcel(params);
-  console.log("导出res", res);
-  // link.href = "https://file.ailien.shop/excel/generate/storeCashOutRecord4.xlsx";
-  if (res.code == "200") {
-    if (!res.data) {
-      ElMessage.error("暂无可下载数据");
-      return;
-    }
-    const exportFile = document.createElement("a");
-    exportFile.style.display = "none";
-    exportFile.download = `商铺过期信息.xlsx`;
-    // return;
-    exportFile.href = `${res.data}?timestamp=${new Date().getTime()}`; // 添加时间戳防止缓存
-    // exportFile.href = ` https://file.ailien.shop/excel/generate/storeCashOutRecord4.xlsx?timestamp=${new Date().getTime()}`; // 添加时间戳防止缓存
-    https: document.body.appendChild(exportFile);
-    exportFile.click();
-    // 去除下载对 url 的影响
-    document.body.removeChild(exportFile);
-    ElMessage.success("下载成功");
-  }
-};
-
-// 表格拖拽排序
-const sortTable = ({ newIndex, oldIndex }: { newIndex?: number; oldIndex?: number }) => {
-  console.log(newIndex, oldIndex);
-  console.log(proTable.value?.tableData);
-  ElMessage.success("修改列表排序成功");
-};
-//获取用户状态列表
-const getUserStatus = computed((params: any) => {
-  const list: any = [];
-  list.push({ userLabel: "正常", userStatus: "0" });
-  list.push({ userLabel: "禁用", userStatus: "1" });
-  list.push({ userLabel: "注销中", userStatus: "-1" });
-  list.push({ userLabel: "已注销", userStatus: "2" });
-  return list;
-});
-
-// ProTable 实例
-const proTable = ref<ProTableInstance>();
-
-// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
-const initParam = reactive({ type: 1 });
-
-// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
-// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
-const dataCallback = (data: any) => {
-  return {
-    list: data.records,
-    total: data.total
-  };
-};
-
-// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
-// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
-const getTableList = (params: any) => {
-  let newParams = JSON.parse(JSON.stringify(params));
-  return getStoreUserList(newParams);
-};
-
-// 表格配置项
-const columns = reactive<ColumnProps<StoreUser.ResStoreUserList>[]>([
-  { type: "selection", fixed: "left" },
-  { prop: "id", label: "账号ID", search: { el: "input", tooltip: "请输入账号id" } },
-  // { prop: "name", label: "账号名称" },
-  { prop: "phone", label: "联系电话", search: { el: "input", tooltip: "请输入联系人电话" } },
-  {
-    prop: "createdTime",
-    label: "创建时间",
-    width: 180,
-    search: {
-      span: 2,
-      props: { type: "datetimerange", valueFormat: "YYYY-MM-DD HH:mm:ss" },
-      defaultValue: ["2022-11-12 11:35:00", "2022-12-12 11:35:00"]
-    }
-  },
-  {
-    prop: "status",
-    label: "状态",
-    render: scope => {
-      let name = "";
-      if (scope.row.status == "0") {
-        name = "正常";
-      } else if (scope.row.status == "1") {
-        name = "禁用";
-      } else if (scope.row.status == "-1") {
-        name = "注销中";
-      } else if (scope.row.status == "2") {
-        name = "已注销";
-      }
-      return name;
-    },
-    search: { el: "select" },
-    enum: getUserStatus,
-    fieldNames: { label: "userLabel", value: "userStatus" }
-  },
-  { prop: "operation", label: "操作", fixed: "right", width: 430 }
-]);
-
-// 打开 drawer(新增、查看、编辑)
-const drawerRef = ref<InstanceType<typeof StoreUserDrawer> | null>(null);
-const openDrawer = (title: string, row: Partial<StoreUser.ResStoreUserList> = {}) => {
-  const params = {
-    title,
-    isView: title === "查看",
-    row: { ...row },
-    api: title === "新增" ? addStoreUser : title === "编辑" ? editStoreUser : undefined,
-    getTableList: proTable.value?.getTableList
-  };
-  drawerRef.value?.acceptParams(params);
-};
-
-// 删除商户信息
-const deleteAccount = async (params: StoreUser.ResStoreUserList) => {
-  await useHandleData(deleteStoreUser, { id: params.id }, `删除商家端账号?`);
-  proTable.value?.getTableList();
-};
-
-// 重置用户密码
-const resetPass = async (params: StoreUser.ResStoreUserList) => {
-  await useHandleData(resetStoreUserPassword, { id: params.id }, `重置账号密码及支付密码为123456`);
-  proTable.value?.getTableList();
-};
-//切换状态
-const switchingStatesFun = async (params: StoreUser.ResStoreUserList) => {
-  let paramStatus = params.status == "1" ? `启用` : `禁用`;
-  await useHandleData(switchingStates, { id: params.id }, paramStatus + `商家端账号状态`);
-  proTable.value?.getTableList();
-};
-</script>

+ 93 - 0
src/views/store/voucherManagement/detail.vue

@@ -0,0 +1,93 @@
+<template>
+  <div class="card content-box">
+    <el-form :model="formData" label-width="140px">
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="店铺名称 :">
+            <span>{{ formData.storeName }}</span>
+          </el-form-item>
+          <el-form-item label="名称 :">
+            <span>{{ formData.name }}</span>
+          </el-form-item>
+          <el-form-item label="描述 :">
+            <span>{{ formData.description }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="状态:">
+            <span>{{ getStatusName(formData.status) }}</span>
+          </el-form-item>
+          <el-form-item label="拒绝原因:" v-if="formData.status === '2'">
+            <span>{{ formData.rejectionReason }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row class="text-center" style="margin-top: 20px">
+        <el-col :span="24">
+          <el-button type="primary" @click="goBack"> 确定 </el-button>
+        </el-col>
+      </el-row>
+    </el-form>
+  </div>
+</template>
+
+<script setup lang="tsx" name="voucherManagementDetail">
+import { ref, onMounted } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import { getStaffConfigDeatail } from "@/api/modules/staffConfig";
+
+const route = useRoute();
+const router = useRouter();
+
+const formData = ref({});
+
+const id = ref((route.query.id as string) || "");
+
+const getStatusName = (status: string) => {
+  switch (status) {
+    case "0":
+      return "待审核";
+    case "1":
+      return "审核通过";
+    case "2":
+      return "审核拒绝";
+    default:
+      return "未知状态";
+  }
+};
+
+onMounted(async () => {
+  await initData();
+});
+
+const initData = async () => {
+  if (id.value) {
+    try {
+      const response = await getStaffConfigDeatail({ id: id.value });
+      if (response.code === 200) {
+        formData.value = response.data;
+      }
+    } catch (error) {
+      ElMessage.error("获取详情失败");
+    }
+  }
+};
+
+const goBack = () => {
+  router.go(-1);
+};
+</script>
+
+<style lang="scss" scoped>
+.el-form {
+  width: 100%;
+  .text-center {
+    text-align: center;
+  }
+}
+.el-col {
+  box-sizing: border-box;
+  padding-right: 10px;
+}
+</style>

+ 203 - 0
src/views/store/voucherManagement/index.vue

@@ -0,0 +1,203 @@
+<template>
+  <div class="table-box">
+    <ProTable ref="proTable" :columns="columns" :request-api="getTableList" :init-param="initParam" :data-callback="dataCallback">
+      <!-- 表格 header 按钮 -->
+      <template #tableHeader="scope">
+        <el-button type="primary" :icon="Download" @click="exportInfoExcel(scope)"> 导出 </el-button>
+      </template>
+      <template #expand="scope">
+        {{ scope.row }}
+      </template>
+      <!-- 表格操作 -->
+      <template #operation="scope">
+        <!-- 审批通过和拒绝按钮仅在状态为0时显示 -->
+        <template v-if="scope.row.status === '0'">
+          <el-button type="primary" link @click="changeTypes(scope.row, 'pass')"> 审核通过 </el-button>
+          <el-button type="primary" link @click="changeTypes(scope.row, '')"> 审核拒绝 </el-button>
+        </template>
+        <el-button type="primary" link @click="toDetail(scope.row)"> 查看详情 </el-button>
+      </template>
+    </ProTable>
+
+    <el-dialog v-model="dialogFormVisible" title="审核拒绝" width="500">
+      <el-form :model="form">
+        <el-form-item label="" label-width="0">
+          <el-input v-model="form.comment" autocomplete="off" type="textarea" maxlength="200" />
+        </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="voucherManagement">
+import { ref, reactive, onMounted, onActivated } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import ProTable from "@/components/ProTable/index.vue";
+import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
+import { Download } from "@element-plus/icons-vue";
+import { audit, exportExcelStaffConfig, getStaffConfigList } from "@/api/modules/staffConfig";
+
+const router = useRouter();
+const dialogFormVisible = ref(false);
+const form = reactive({
+  comment: ""
+});
+
+const rowData = ref<any>();
+
+const statusEnum = [
+  { value: "0", label: "待审核" },
+  { value: "1", label: "审核通过" },
+  { value: "2", label: "审核拒绝" }
+];
+// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
+const initParam = reactive({});
+
+// 定义 filterValues
+const filterValues = reactive({});
+
+const getStatusObj = (statusValue: string) => {
+  const statusObj = statusEnum.find(item => item.value === statusValue);
+  if (statusObj) {
+    filterValues.status = statusObj;
+  } else {
+    filterValues.status = "";
+  }
+  return statusObj;
+};
+
+// ProTable 实例
+const proTable = ref<ProTableInstance>();
+
+// 页面加载时触发查询
+onMounted(() => {
+  proTable.value?.getTableList();
+});
+
+// 从其他页面返回时触发查询
+onActivated(() => {
+  proTable.value?.getTableList();
+});
+
+// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
+// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
+const dataCallback = (data: any) => {
+  return {
+    list: data.records,
+    total: data.total
+  };
+};
+
+// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
+// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
+const getTableList = (params: any) => {
+  let newParams = JSON.parse(JSON.stringify(params));
+  return getStaffConfigList(newParams);
+};
+
+// 跳转详情页
+const toDetail = row => {
+  router.push(`/store/voucherManagementDetail?id=${row.id}`);
+};
+
+// 表格配置项
+const columns = reactive<ColumnProps<any>[]>([
+  { type: "index", fixed: "left", label: "序号", width: 130 },
+  { prop: "storeName", label: "所属店铺" },
+  { prop: "name", label: "名称" },
+  { prop: "description", label: "描述" },
+  {
+    prop: "status",
+    label: "状态",
+    render: scope => {
+      const statusObj = getStatusObj(scope.row.status);
+      return statusObj ? statusObj.label : "未知状态";
+    },
+    search: {
+      el: "select"
+    },
+    enum: statusEnum,
+    fieldNames: { label: "label", value: "value" }
+  },
+  { prop: "operation", label: "操作", fixed: "right", width: 330 }
+]);
+
+const changeTypes = (row: any, status: string) => {
+  rowData.value = row;
+  if (status === "pass") {
+    handleChangeStatus(row, "1");
+  } else {
+    form.comment = "";
+    dialogFormVisible.value = true;
+  }
+};
+
+const handleChangeStatus = async (row: any, status: string) => {
+  try {
+    let res = await audit({ id: row.id, status: status, rejectionReason: form.comment });
+    if (res.code === 200) {
+      proTable.value?.getTableList();
+      if (status === "2") closeDialog();
+      ElMessage.success("审核成功");
+    }
+  } catch (error) {
+    ElMessage.error("操作失败");
+  }
+};
+
+// 导出信息
+const exportInfoExcel = async scope => {
+  let res;
+  // 获取原始状态值(可能为数字、字符串或 undefined)
+  const rawStatus = proTable.value.searchParam.status;
+  // 转换为字符串(处理 undefined/null 为 "" 或保留原始字符串)
+  const statusParam = rawStatus !== undefined && rawStatus !== null ? String(rawStatus) : undefined;
+  // 将筛选条件作为参数传递给后台
+  res = await exportExcelStaffConfig({ status: statusParam });
+  if (res.code === 200) {
+    if (!res.data) {
+      ElMessage.error("暂无可下载数据");
+      return;
+    }
+    const exportFile = document.createElement("a");
+    exportFile.style.display = "none";
+    exportFile.download = `代金券管理.xlsx`;
+    exportFile.href = `${res.data}?timestamp=${new Date().getTime()}`; // 添加时间戳防止缓存
+    document.body.appendChild(exportFile);
+    exportFile.click();
+    document.body.removeChild(exportFile);
+    ElMessage.success("下载成功");
+  }
+};
+
+// 弹窗提交
+const handleSubmit = () => {
+  if (!form.comment) {
+    ElMessage.error("请输入审批意见");
+    return;
+  }
+  handleChangeStatus(rowData.value, "2");
+};
+// 关闭弹窗;
+const closeDialog = () => {
+  dialogFormVisible.value = false;
+  form.comment = "";
+};
+</script>
+
+<style lang="scss" scoped>
+// 在组件样式中添加
+.date-range {
+  display: block; // 确保换行生效
+  padding: 0 8px; // 可选:增加内边距
+  word-wrap: break-word; // 长单词内换行
+  white-space: normal; // 允许自然换行
+}
+</style>