Bladeren bron

Merge remote-tracking branch 'origin/development' into development

spy 1 maand geleden
bovenliggende
commit
1fc1ad0bde

BIN
public/logo.png


+ 34 - 0
src/api/modules/couponManagement.ts

@@ -0,0 +1,34 @@
+import { ResPage, StoreUser } from "@/api/interface/index";
+import { PORT_NONE } from "@/api/config/servicePort";
+import http from "@/api";
+
+export const getThaliList = params => {
+  return http.get<ResPage<StoreUser.ResStoreUserList>>(PORT_NONE + `/PcGroupBuy/getThaliList`, params);
+};
+export const deleteThali = (params: { id: string }) => {
+  return http.delete(PORT_NONE + `/PcGroupBuy/deleteThali`, params);
+};
+export const sjxj = params => {
+  return http.get(PORT_NONE + `/PcGroupBuy/sjxj`, params);
+};
+export const updateNum = params => {
+  return http.get(PORT_NONE + `/PcGroupBuy/updateNum1`, params);
+};
+export const saveDraft = params => {
+  return http.post(PORT_NONE + `/PcGroupBuy/saveDraft`, params);
+};
+export const getUserByPhone = params => {
+  return http.get(PORT_NONE + `/store/user/getUserByPhone`, params);
+};
+export const getDetail = params => {
+  return http.get(PORT_NONE + `/store/info/getDetail`, params);
+};
+export const getMenuByStoreId = params => {
+  return http.get(PORT_NONE + `/menuPlatform/getMenuByStoreId`, params);
+};
+export const getHolidayList = (params: any) => {
+  return http.get<StoreUser.ResStoreUserList>(PORT_NONE + `/couponPlatform/getHolidayList`, params);
+};
+export const getCouponDetail = (params: StoreUser.ReqUserParams) => {
+  return http.get<StoreUser.ResStoreUserList>(PORT_NONE + `/store/info/getStoreDetail`, params);
+};

+ 9 - 10
src/api/modules/groupPackageManagement.ts

@@ -11,12 +11,15 @@ export const deleteThali = (params: { id: string }) => {
 export const sjxj = params => {
   return http.get(PORT_NONE + `/PcGroupBuy/sjxj`, params);
 };
-export const xgkc = params => {
-  return http.get(PORT_NONE + `/PcGroupBuy/xgkc`, params);
+export const updateNum = params => {
+  return http.get(PORT_NONE + `/PcGroupBuy/updateNum`, params);
 };
 export const saveDraft = params => {
   return http.post(PORT_NONE + `/PcGroupBuy/saveDraft`, params);
 };
+export const saveThali = params => {
+  return http.post(PORT_NONE + `/PcGroupBuy/saveThali`, params);
+};
 export const getUserByPhone = params => {
   return http.get(PORT_NONE + `/store/user/getUserByPhone`, params);
 };
@@ -26,13 +29,9 @@ export const getDetail = params => {
 export const getMenuByStoreId = params => {
   return http.get(PORT_NONE + `/menuPlatform/getMenuByStoreId`, params);
 };
-
-//获取商铺明细信息
-export const getStoreDetail = (params: StoreUser.ReqUserParams) => {
-  return http.get<StoreUser.ResStoreUserList>(PORT_NONE + `/store/info/getStoreDetail`, params);
+export const getHolidayList = (params: any) => {
+  return http.get<StoreUser.ResStoreUserList>(PORT_NONE + `/couponPlatform/getHolidayList`, params);
 };
-
-//新增商铺信息
-export const editStoreInfo = (params: { id: string }) => {
-  return http.post(PORT_NONE + `/store/info/editStoreInfo`, params);
+export const getThaliById = params => {
+  return http.get(PORT_NONE + `/PcGroupBuy/getThaliById`, params);
 };

+ 33 - 0
src/api/modules/licenseManagement.ts

@@ -0,0 +1,33 @@
+import { ResPage, StoreUser } from "@/api/interface/index";
+import { PORT_NONE } from "@/api/config/servicePort";
+import http from "@/api";
+
+// 获取营业执照
+export const getBusinessLicense = params => {
+  return http.get(PORT_NONE + `/license/getBusinessLicense`, params);
+};
+
+// 获取食品经营许可证
+export const getFoodBusinessLicense = params => {
+  return http.get(PORT_NONE + `/license/getFoodBusinessLicense`, params);
+};
+
+// 获取合同图片列表
+export const getContractImages = params => {
+  return http.get(PORT_NONE + `/license/getContractImages`, params);
+};
+
+// 获取变更记录
+export const getChangeRecords = params => {
+  return http.get(PORT_NONE + `/license/getChangeRecords`, params);
+};
+
+// 提交食品经营许可证审核
+export const submitFoodLicenseReview = params => {
+  return http.post(PORT_NONE + `/license/submitFoodLicenseReview`, params);
+};
+
+// 提交合同审核
+export const submitContractReview = params => {
+  return http.post(PORT_NONE + `/license/submitContractReview`, params);
+};

+ 37 - 0
src/api/modules/orderManagement.ts

@@ -0,0 +1,37 @@
+import { ResPage, StoreUser } from "@/api/interface/index";
+import { PORT_NONE } from "@/api/config/servicePort";
+import http from "@/api";
+
+export const getThaliList = params => {
+  return http.get<ResPage<StoreUser.ResStoreUserList>>(PORT_NONE + `/PcGroupBuy/getThaliList`, params);
+};
+export const getCpList = params => {
+  return http.get<ResPage<StoreUser.ResStoreUserList>>(PORT_NONE + `/PcGroupBuy/getCpList`, params);
+};
+export const deleteThali = (params: { id: string }) => {
+  return http.delete(PORT_NONE + `/PcGroupBuy/deleteThali`, params);
+};
+export const sjxj = params => {
+  return http.get(PORT_NONE + `/PcGroupBuy/sjxj`, params);
+};
+export const xgkc = params => {
+  return http.get(PORT_NONE + `/PcGroupBuy/xgkc`, params);
+};
+export const saveDraft = params => {
+  return http.post(PORT_NONE + `/PcGroupBuy/saveDraft`, params);
+};
+export const getUserByPhone = params => {
+  return http.get(PORT_NONE + `/store/user/getUserByPhone`, params);
+};
+export const getDetail = params => {
+  return http.get(PORT_NONE + `/store/info/getDetail`, params);
+};
+export const getMenuByStoreId = params => {
+  return http.get(PORT_NONE + `/menuPlatform/getMenuByStoreId`, params);
+};
+export const getHolidayList = (params: any) => {
+  return http.get<StoreUser.ResStoreUserList>(PORT_NONE + `/couponPlatform/getHolidayList`, params);
+};
+export const getStoreDetail = (params: StoreUser.ReqUserParams) => {
+  return http.get<StoreUser.ResStoreUserList>(PORT_NONE + `/store/info/getStoreDetail`, params);
+};

+ 34 - 0
src/api/modules/voucherManagement.ts

@@ -0,0 +1,34 @@
+import { ResPage, StoreUser } from "@/api/interface/index";
+import { PORT_NONE } from "@/api/config/servicePort";
+import http from "@/api";
+
+export const getThaliList = params => {
+  return http.get<ResPage<StoreUser.ResStoreUserList>>(PORT_NONE + `/PcGroupBuy/getThaliList`, params);
+};
+export const deleteThali = (params: { id: string }) => {
+  return http.delete(PORT_NONE + `/PcGroupBuy/deleteThali`, params);
+};
+export const sjxj = params => {
+  return http.get(PORT_NONE + `/PcGroupBuy/sjxj`, params);
+};
+export const updateNum = params => {
+  return http.get(PORT_NONE + `/PcGroupBuy/updateNum11`, params);
+};
+export const saveDraft = params => {
+  return http.post(PORT_NONE + `/PcGroupBuy/saveDraft`, params);
+};
+export const getUserByPhone = params => {
+  return http.get(PORT_NONE + `/store/user/getUserByPhone`, params);
+};
+export const getVoucherDetail = params => {
+  return http.get(PORT_NONE + `/store/info/getDetail`, params);
+};
+export const getMenuByStoreId = params => {
+  return http.get(PORT_NONE + `/menuPlatform/getMenuByStoreId`, params);
+};
+export const getHolidayList = (params: any) => {
+  return http.get<StoreUser.ResStoreUserList>(PORT_NONE + `/couponPlatform/getHolidayList`, params);
+};
+export const getStoreDetail = (params: StoreUser.ReqUserParams) => {
+  return http.get<StoreUser.ResStoreUserList>(PORT_NONE + `/store/info/getStoreDetail`, params);
+};

BIN
src/assets/images/logo.png


+ 42 - 35
src/views/couponManagement/index.vue

@@ -68,7 +68,7 @@
           {{ formInventory.packageName }}
         </el-form-item>
         <el-form-item label="剩余库存">
-          {{ formInventory.remainingInventory }}
+          {{ formInventory.inventoryNum }}
         </el-form-item>
         <el-form-item label="修改库存" prop="newInventory">
           <el-input v-model="formInventory.newInventory" placeholder="请输入" />
@@ -92,20 +92,23 @@ import { ElMessage } from "element-plus";
 import ProTable from "@/components/ProTable/index.vue";
 import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
 import { Plus } from "@element-plus/icons-vue";
-import { audit, getStaffConfigList } from "@/api/modules/staffConfig";
-import { getThaliList } from "@/api/modules/groupPackageManagement";
+import { getThaliList, sjxj, updateNum, deleteThali } from "@/api/modules/couponManagement";
+import { ElMessageBox } from "element-plus/es";
 
 const router = useRouter();
 const dialogFormVisible = ref(false);
 const formInventory: any = ref({
   id: "",
   packageName: "",
-  remainingInventory: "",
+  inventoryNum: "",
   newInventory: ""
 });
 const rowData = ref<any>();
 const activeName = ref("");
-
+// 定义表单类型
+interface RuleForm {
+  newInventory: string;
+}
 const ruleFormRef = ref<FormInstance>();
 const rules = reactive<FormRules<RuleForm>>({
   newInventory: [
@@ -267,51 +270,55 @@ const getTableList = (params: any) => {
   return getThaliList(newParams);
 };
 
+const newGroupBuying = () => {
+  router.push(`/couponManagement/newCoupon?type=add`);
+};
 // 跳转详情页
 const toDetail = row => {
-  router.push(`/couponManagement/detail?id=${row.id}&type=edit`);
+  router.push(`/couponManagement/detail?id=${row.id}`);
 };
-const editRow = row => {};
-const deleteRow = row => {};
-const newGroupBuying = () => {
-  router.push(`/couponManagement/newCoupon?id=104&type=add`);
+const editRow = row => {
+  router.push(`/couponManagement/newCoupon?id=${row.id}&type=edit`);
+};
+const deleteRow = row => {
+  ElMessageBox.confirm("确定要删除吗?", "提示", {
+    confirmButtonText: "OK",
+    cancelButtonText: "Cancel",
+    type: "warning"
+  }).then(() => {
+    deleteThali(row.id).then(() => {
+      ElMessage.success("删除成功");
+      proTable.value?.getTableList();
+    });
+  });
 };
 const handleClick = () => {};
-const changeTypes = (row: any, status: string) => {
+const changeTypes = async (row: any, status: string) => {
   rowData.value = row;
-  if (status === "on") {
-    handleChangeStatus(row, "1");
-  } else {
-    handleChangeStatus(row, "2");
+  let res = await sjxj({ id: row.id, status: status });
+  if (res && res.code == 200) {
+    ElMessage.success("操作成功");
+    proTable.value?.getTableList();
   }
 };
 const changeInventory = (row: any) => {
-  formInventory.value.id = 1;
-  formInventory.value.packageName = 1;
-  formInventory.value.remainingInventory = 1;
+  formInventory.value.id = row.id;
+  formInventory.value.packageName = row.packageName;
+  formInventory.value.inventoryNum = row.inventoryNum;
   formInventory.value.newInventory = "";
   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 handleSubmit = async () => {
   if (!ruleFormRef.value) return;
-  await ruleFormRef.value.validate((valid, fields) => {
+  await ruleFormRef.value.validate(async (valid, fields) => {
     if (valid) {
-      ElMessage.success("修改成功");
-      dialogFormVisible.value = false;
+      let res = await updateNum({ id: formInventory.value.id, num: formInventory.value.newInventory });
+      if (res && res.code == 200) {
+        ElMessage.success("库存修改成功");
+        dialogFormVisible.value = false;
+        proTable.value?.getTableList();
+      }
     }
   });
 };
@@ -321,7 +328,7 @@ const closeDialog = () => {
   formInventory.value = {
     id: "",
     packageName: "",
-    remainingInventory: "",
+    inventoryNum: "",
     newInventory: ""
   };
 };

+ 44 - 4
src/views/couponManagement/newCoupon.vue

@@ -101,16 +101,20 @@
  * 优惠券管理 - 新增页面
  * 功能:支持优惠券的新增操作
  */
-import { ref, reactive, watch, nextTick } from "vue";
+import { ref, reactive, watch, nextTick, onMounted } from "vue";
 import { ElMessage } from "element-plus";
-import { useRouter } from "vue-router";
+import { useRoute, useRouter } from "vue-router";
 import type { FormInstance } from "element-plus";
-
+import { getCouponDetail } from "@/api/modules/couponManagement";
 // ==================== 响应式数据定义 ====================
 
 // 路由相关
 const router = useRouter();
+const route = useRoute();
 
+// 页面状态
+const type = ref<string>(""); // 页面类型:add-新增, edit-编辑
+const id = ref<string>(""); // 页面ID参数
 // ==================== 表单验证规则 ====================
 const rules = reactive({
   couponName: [{ required: true, message: "请输入优惠券名称" }],
@@ -318,7 +322,43 @@ watch(
 );
 
 // ==================== 事件处理函数 ====================
-
+/**
+ * 组件挂载时初始化
+ * 从路由参数中获取页面类型和ID
+ */
+onMounted(async () => {
+  id.value = (route.query.id as string) || "";
+  type.value = (route.query.type as string) || "";
+  // 不要删除-开始
+  // let param = {
+  //   // phone: localGet("iphone")
+  //   phone: "18641153170"
+  // };
+  // const resP: any = await getUserByPhone(param);
+  // if (resP.data && resP.data.storeId) {
+  //   localSet("createdId", resP.data.storeId);
+  //   const resD: any = await getDetail({
+  //     id: localGet("createdId")
+  //   });
+  //   if (resD.data && resD.data.commissionRate) {
+  //     localSet("commissionRate", resD.data.commissionRate);
+  //   }
+  //   if (resD.data && resD.data.businessSection) {
+  //     localSet("businessSection", resD.data.businessSection);
+  //   }
+  // } else {
+  //   ElMessage.warning("请完成商家入驻后再进行新建团购");
+  // }
+  // if (!getGroupCombination()) {
+  //   ElMessage.warning("请完成商家入驻后重新登录再进行新建团购");
+  //   return;
+  // }
+  // 不要删除-结束
+  if (type.value != "add") {
+    // TODO: 加载优惠券详情数据
+    // let res: any = await getCouponDetail({ id: id.value });
+  }
+});
 /**
  * 返回上一页
  */

+ 633 - 66
src/views/groupPackageManagement/detail.vue

@@ -1,93 +1,660 @@
 <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 class="table-box" style="width: 100%; min-height: 100%; background-color: white">
+    <div class="header">
+      <el-button @click="goBack"> 返回 </el-button>
+      <h2 class="title">团购详情</h2>
+    </div>
+    <div class="content">
+      <!-- 左侧内容区域 -->
+      <div class="contentLeft">
+        <!-- 基础信息模块 -->
+        <div class="model">
+          <h3 style="font-weight: bold">基础信息:</h3>
+          <!-- 团购图片 -->
+          <div class="detail-item">
+            <div class="detail-label">图片</div>
+            <div class="detail-value">
+              <div class="image-list">
+                <el-image
+                  v-for="(image, index) in storeInfoModel.imageValueStr"
+                  :key="index"
+                  :src="getImageUrl(image)"
+                  class="detail-image"
+                  :preview-src-list="imagePreviewList"
+                  :initial-index="index"
+                  show-progress
+                  preview-teleported
+                />
+              </div>
+            </div>
+          </div>
+          <!-- 团购名称 -->
+          <div class="detail-item">
+            <div class="detail-label">团购名称</div>
+            <div class="detail-value">
+              {{ storeInfoModel.groupName || "-" }}
+            </div>
+          </div>
+          <!-- 开始售卖时间 -->
+          <div class="detail-item">
+            <div class="detail-label">开始时间</div>
+            <div class="detail-value">
+              {{ getStartTimeText() }}
+            </div>
+          </div>
+          <!-- 结束售卖时间 -->
+          <div class="detail-item">
+            <div class="detail-label">结束时间</div>
+            <div class="detail-value">
+              {{ storeInfoModel.endTime ? formatDate(storeInfoModel.endTime) : "-" }}
+            </div>
+          </div>
+          <!-- 库存数量 -->
+          <div class="detail-item">
+            <div class="detail-label">库存数量</div>
+            <div class="detail-value">
+              {{ storeInfoModel.inventoryNum || "-" }}
+            </div>
+          </div>
+          <!-- 每人限购 -->
+          <div class="detail-item">
+            <div class="detail-label">每人限购</div>
+            <div class="detail-value">
+              {{ getQuotaText() }}
+            </div>
+          </div>
+          <!-- 套餐内容 -->
+          <div class="detail-item package-content-item">
+            <div class="detail-label">套餐内容</div>
+            <div class="detail-value">
+              <div v-if="lifeGroupBuyThalis && lifeGroupBuyThalis.length > 0" class="package-content-list">
+                <div v-for="(group, groupIndex) in lifeGroupBuyThalis" :key="groupIndex" class="package-group-item">
+                  <div v-for="(dish, dishIndex) in group.dishes" :key="dishIndex" class="package-dish-item">
+                    <span class="dish-category">{{ group.groupName }}:</span>
+                    <span class="dish-name">{{ dish.dishName }}</span>
+                    <span class="dish-price">¥{{ dish.dishPrice }}/{{ dish.dishesUnit }}</span>
+                    <span class="dish-quantity">数量{{ dish.qty }}</span>
+                  </div>
+                </div>
+              </div>
+              <span v-else class="empty-text">-</span>
+            </div>
+          </div>
+        </div>
+        <!-- 价格信息模块 -->
+        <div class="model">
+          <h3 style="font-weight: bold">价格:</h3>
+          <!-- 原价 -->
+          <div class="detail-item">
+            <div class="detail-label">原价(¥)</div>
+            <div class="detail-value">
+              {{ storeInfoModel.originalPrice || "-" }}
+            </div>
+          </div>
+          <!-- 优惠价 -->
+          <div class="detail-item">
+            <div class="detail-label">优惠价(¥)</div>
+            <div class="detail-value">
+              {{ storeInfoModel.preferentialPrice || "-" }}
+            </div>
+          </div>
+        </div>
+      </div>
+      <!-- 右侧内容区域 -->
+      <div class="contentRight">
+        <!-- 购买须知模块 -->
+        <div class="model">
+          <h3 style="font-weight: bold">购买须知:</h3>
+          <!-- 有效期 -->
+          <div class="detail-item">
+            <div class="detail-label">有效期</div>
+            <div class="detail-value">
+              {{ getEffectiveDateText() }}
+            </div>
+          </div>
+          <!-- 不可用日期 -->
+          <div class="detail-item">
+            <div class="detail-label">不可用日期</div>
+            <div class="detail-value">
+              {{ getDisableDateText() }}
+            </div>
+          </div>
+          <!-- 核销方式 -->
+          <div class="detail-item">
+            <div class="detail-label">核销方式</div>
+            <div class="detail-value">手动核销</div>
+          </div>
+          <!-- 预约规则 -->
+          <div class="detail-item">
+            <div class="detail-label">预约规则</div>
+            <div class="detail-value">
+              {{ storeInfoModel.reservationRules || "详情请咨询商家" }}
+            </div>
+          </div>
+          <!-- 使用规则 -->
+          <div class="detail-item">
+            <div class="detail-label">使用规则</div>
+            <div class="detail-value">
+              {{ storeInfoModel.useRules || "详情请咨询商家" }}
+            </div>
+          </div>
+          <!-- 适用人数 -->
+          <div class="detail-item">
+            <div class="detail-label">适用人数</div>
+            <div class="detail-value">
+              {{ storeInfoModel.applicableNum ? storeInfoModel.applicableNum + "人" : "-" }}
+            </div>
+          </div>
+          <!-- 其他规则 -->
+          <div class="detail-item">
+            <div class="detail-label">其他规则</div>
+            <div class="detail-value">
+              {{ storeInfoModel.otherRules || "详情请咨询商家" }}
+            </div>
+          </div>
+          <!-- 发票信息 -->
+          <div class="detail-item">
+            <div class="detail-label">发票信息</div>
+            <div class="detail-value">
+              <div v-if="invoiceInfoList && invoiceInfoList.length > 0">
+                <span v-for="(info, index) in invoiceInfoList" :key="index">
+                  {{ info }}<span v-if="index < invoiceInfoList.length - 1">、</span>
+                </span>
+              </div>
+              <span v-else>详情请咨询商家</span>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
-<script setup lang="tsx" name="groupPackageManagementDetail">
-import { ref, onMounted } from "vue";
-import { useRoute, useRouter } from "vue-router";
+<script setup lang="tsx" name="groupPackageDetail">
+/**
+ * 团购包管理 - 详情页面
+ * 功能:显示团购包的详细信息
+ */
+import { ref, onMounted, computed } from "vue";
+import { useRouter, useRoute } from "vue-router";
 import { ElMessage } from "element-plus";
-import { getStaffConfigDeatail } from "@/api/modules/staffConfig";
+import { getThaliById, getHolidayList } from "@/api/modules/groupPackageManagement";
+import { localGet } from "@/utils";
 
-const route = useRoute();
+// ==================== 响应式数据定义 ====================
+
+// 路由相关
 const router = useRouter();
+const route = useRoute();
+
+// 页面ID参数
+const id = ref<string>("");
+
+// ==================== 团购包信息数据模型 ====================
+const storeInfoModel = ref<any>({
+  // 团购图片列表
+  imageValueStr: [],
+  // 团购名称
+  groupName: "",
+  // 开始售卖时间设置方式:0-审核通过后立即开始,1-设置售卖时间
+  startTimeType: 0,
+  // 开始售卖时间(当storeStatus为1时必填)
+  startTimeValue: "",
+  // 结束售卖时间
+  endTime: "",
+  // 库存数量
+  inventoryNum: "",
+  // 每人限购设置:0-不限量,1-自定义限购数量
+  quotaType: 0,
+  // 自定义限购数量(当quotaType为1时必填)
+  quotaValue: 0,
+  // 原价
+  originalPrice: "",
+  // 优惠价
+  preferentialPrice: "",
+  // 有效期设置:0-指定天数,1-指定时间段内可用
+  effectiveDateType: 0,
+  expirationDate: 0,
+  expirationDateList: [],
+  // 不可用日期设置:0-全部日期可用,1-限制日期,2-自定义不可用日期
+  disableDateType: 0,
+  // 限制日期 - 星期选择(数组,存储选中的星期值)
+  unavailableWeekdays: [],
+  // 限制日期 - 节日选择(数组,存储选中的节日值)
+  unavailableHolidays: [],
+  // 自定义不可用日期列表
+  disableDateList: [],
+  // 预约规则
+  reservationRules: "",
+  // 使用规则
+  useRules: "",
+  // 适用人数
+  applicableNum: "",
+  // 其他规则
+  otherRules: "",
+  // 发票信息(复选框,可多选)
+  invoiceInformation: [],
+  // 发票说明
+  invoiceDescribe: ""
+});
 
-const formData = ref({});
+// 套餐内容(数组,每个元素是一个分组)
+const lifeGroupBuyThalis = ref<any[]>([]);
 
-const id = ref((route.query.id as string) || "");
+// 星期选项列表
+const weekdayList = ref([
+  { name: "周一", id: "0", oName: "星期一" },
+  { name: "周二", id: "1", oName: "星期二" },
+  { name: "周三", id: "2", oName: "星期三" },
+  { name: "周四", id: "3", oName: "星期四" },
+  { name: "周五", id: "4", oName: "星期五" },
+  { name: "周六", id: "5", oName: "星期六" },
+  { name: "周日", id: "6", oName: "星期日" }
+]);
 
-const getStatusName = (status: string) => {
-  switch (status) {
-    case "0":
-      return "待审核";
-    case "1":
-      return "审核通过";
-    case "2":
-      return "审核拒绝";
-    default:
-      return "未知状态";
+// 节日选项列表
+const holidayList: any = ref([]);
+
+// 发票类型列表
+const businessTypes = ref([
+  { value: 0, label: "提供电子发票" },
+  { value: 1, label: "提供纸质发票" }
+]);
+
+// ==================== 计算属性 ====================
+
+// 图片预览列表
+const imagePreviewList = computed(() => {
+  return storeInfoModel.value.imageValueStr.map((item: any) => getImageUrl(item));
+});
+
+// 发票信息列表
+const invoiceInfoList = computed(() => {
+  if (!storeInfoModel.value.invoiceInformation || storeInfoModel.value.invoiceInformation.length === 0) {
+    return [];
   }
-};
+  return storeInfoModel.value.invoiceInformation
+    .map((val: string) => {
+      const numVal = parseInt(val);
+      const type = businessTypes.value.find(item => item.value === numVal);
+      return type ? type.label : "";
+    })
+    .filter(Boolean);
+});
+
+// ==================== 生命周期钩子 ====================
 
+/**
+ * 组件挂载时初始化
+ * 从路由参数中获取ID并加载详情数据
+ */
 onMounted(async () => {
-  await initData();
+  id.value = (route.query.id as string) || "";
+  // 加载节日列表
+  await loadHolidayList();
+  if (id.value) {
+    await loadDetailData();
+  } else {
+    ElMessage.warning("缺少团购ID参数");
+  }
 });
 
-const initData = async () => {
-  if (id.value) {
-    try {
-      const response = await getStaffConfigDeatail({ id: id.value });
-      if (response.code === 200) {
-        formData.value = response.data;
+// ==================== 事件处理函数 ====================
+
+/**
+ * 返回上一页
+ */
+const goBack = () => {
+  router.go(-1);
+};
+
+// ==================== 数据加载函数 ====================
+
+/**
+ * 加载节日列表
+ */
+const loadHolidayList = async () => {
+  try {
+    let params = {
+      year: new Date().getFullYear(),
+      page: 1,
+      size: 500,
+      openFlag: 1,
+      holidayName: ""
+    };
+    let res: any = await getHolidayList(params);
+    if (res && res.code == 200) {
+      holidayList.value = res.data.records;
+    }
+  } catch (error) {
+    console.error("加载节日列表出错:", error);
+  }
+};
+
+/**
+ * 加载详情数据
+ */
+const loadDetailData = async () => {
+  try {
+    const params = {
+      id: id.value,
+      userId: localGet("userId") || "104"
+    };
+    const res: any = await getThaliById(params);
+    if (res && res.code == 200) {
+      // 合并主数据
+      storeInfoModel.value = { ...storeInfoModel.value, ...res.data.lifeGroupBuyMain };
+      // 处理发票信息
+      if (storeInfoModel.value.invoiceType) {
+        storeInfoModel.value.invoiceInformation = storeInfoModel.value.invoiceType.split(";");
+      }
+
+      // 处理不可用日期
+      if (storeInfoModel.value.disableDateValue) {
+        const listVal = storeInfoModel.value.disableDateValue.split(";");
+        if (listVal.length >= 2) {
+          storeInfoModel.value.unavailableWeekdays = listVal[0] ? listVal[0].split(",") : [];
+          storeInfoModel.value.unavailableHolidays = listVal[1] ? listVal[1].split(",") : [];
+        }
+      }
+
+      // 处理套餐内容
+      if (res.data.lifeGroupBuyThalis && res.data.lifeGroupBuyThalis.length > 0) {
+        lifeGroupBuyThalis.value = res.data.lifeGroupBuyThalis;
       }
-    } catch (error) {
-      ElMessage.error("获取详情失败");
+    } else {
+      ElMessage.error("加载详情数据失败");
     }
+  } catch (error) {
+    console.error("加载详情数据出错:", error);
+    ElMessage.error("加载详情数据出错");
   }
 };
 
-const goBack = () => {
-  router.go(-1);
+// ==================== 工具函数 ====================
+
+/**
+ * 获取开始时间文本
+ */
+const getStartTimeText = () => {
+  if (storeInfoModel.value.startTimeType === 0) {
+    return (
+      "审核通过立即开始" + (storeInfoModel.value.startTimeValue ? "/" + formatDate(storeInfoModel.value.startTimeValue) : "")
+    );
+  } else if (storeInfoModel.value.startTimeType === 1 && storeInfoModel.value.startTimeValue) {
+    return formatDate(storeInfoModel.value.startTimeValue);
+  }
+  return "-";
+};
+
+/**
+ * 获取限购文本
+ */
+const getQuotaText = () => {
+  if (storeInfoModel.value.quotaType === 0) {
+    return "不限量";
+  } else if (storeInfoModel.value.quotaType === 1) {
+    return storeInfoModel.value.quotaValue ? `不限量/${storeInfoModel.value.quotaValue}` : "不限量";
+  }
+  return "-";
+};
+
+/**
+ * 获取有效期文本
+ */
+const getEffectiveDateText = () => {
+  if (storeInfoModel.value.effectiveDateType === 0) {
+    if (storeInfoModel.value.expirationDate) {
+      return `用户购买后${storeInfoModel.value.expirationDate}天内有效`;
+    }
+    return "-";
+  } else if (storeInfoModel.value.effectiveDateType === 1) {
+    if (storeInfoModel.value.expirationDateList && storeInfoModel.value.expirationDateList.length === 2) {
+      return `${formatDate(storeInfoModel.value.expirationDateList[0])}-${formatDate(storeInfoModel.value.expirationDateList[1])}`;
+    }
+    return "-";
+  }
+  return "-";
+};
+
+/**
+ * 获取不可用日期文本
+ */
+const getDisableDateText = () => {
+  if (storeInfoModel.value.disableDateType === 0) {
+    return "全部日期可用";
+  } else if (storeInfoModel.value.disableDateType === 1) {
+    const weekdays: string[] = [];
+    const holidays: string[] = [];
+
+    // 处理星期
+    if (storeInfoModel.value.unavailableWeekdays && storeInfoModel.value.unavailableWeekdays.length > 0) {
+      storeInfoModel.value.unavailableWeekdays.forEach((day: string) => {
+        const weekday = weekdayList.value.find(w => w.oName === day);
+        if (weekday) {
+          weekdays.push(weekday.name);
+        }
+      });
+    }
+
+    // 处理节日
+    if (storeInfoModel.value.unavailableHolidays && storeInfoModel.value.unavailableHolidays.length > 0) {
+      storeInfoModel.value.unavailableHolidays.forEach((holidayId: string) => {
+        const holiday = holidayList.value.find((h: any) => h.id === holidayId);
+        if (holiday) {
+          holidays.push(holiday.festivalName);
+        }
+      });
+    }
+
+    const parts: string[] = [];
+    if (weekdays.length > 0) {
+      parts.push(weekdays.join("、"));
+    }
+    if (holidays.length > 0) {
+      parts.push(holidays.join("、"));
+    }
+
+    return parts.length > 0 ? parts.join("、") : "-";
+  } else if (storeInfoModel.value.disableDateType === 2) {
+    if (storeInfoModel.value.disableDateList && storeInfoModel.value.disableDateList.length > 0) {
+      const dateStrings = storeInfoModel.value.disableDateList
+        .filter((date: any) => date && date.length === 2)
+        .map((date: any) => `${formatDate(date[0])}-${formatDate(date[1])}`);
+      return dateStrings.length > 0 ? dateStrings.join("、") : "-";
+    }
+    return "-";
+  }
+  return "-";
+};
+
+/**
+ * 格式化日期
+ * @param date 日期字符串 (YYYY-MM-DD)
+ * @returns 格式化后的日期字符串 (YYYY/MM/DD)
+ */
+const formatDate = (date: string) => {
+  if (!date) return "-";
+  return date.replace(/-/g, "/");
+};
+
+/**
+ * 获取图片URL
+ * @param item 图片项(可能是文件对象或URL字符串)
+ * @returns 图片URL
+ */
+const getImageUrl = (item: any): string => {
+  if (typeof item === "string") {
+    return item;
+  }
+  if (item.url) {
+    return item.url;
+  }
+  if (item.response && item.response.data) {
+    return item.response.data;
+  }
+  return "";
 };
 </script>
 
-<style lang="scss" scoped>
-.el-form {
-  width: 100%;
-  .text-center {
-    text-align: center;
+<style scoped lang="scss">
+/* 页面容器 */
+.table-box {
+  display: flex;
+  flex-direction: column;
+  height: auto !important;
+  min-height: 100%;
+}
+
+/* 头部区域 */
+.header {
+  display: flex;
+  align-items: center;
+  padding: 20px 24px;
+  background-color: #ffffff;
+  border-bottom: 1px solid #e4e7ed;
+  box-shadow: 0 2px 4px rgb(0 0 0 / 2%);
+}
+.title {
+  flex: 1;
+  margin: 0;
+  font-size: 18px;
+  font-weight: 600;
+  color: #303133;
+  text-align: center;
+}
+
+/* 内容区域布局 */
+.content {
+  display: flex;
+  flex: 1;
+  column-gap: 24px;
+  width: 98%;
+  padding: 0 12px;
+  margin: 24px auto;
+
+  /* 左侧内容区域 */
+  .contentLeft {
+    width: 50%;
+    padding-right: 12px;
+  }
+
+  /* 右侧内容区域 */
+  .contentRight {
+    width: 50%;
+    padding-left: 12px;
   }
 }
-.el-col {
-  box-sizing: border-box;
-  padding-right: 10px;
+
+/* 模块容器 */
+.model {
+  margin-bottom: 50px;
+  h3 {
+    padding-bottom: 12px;
+    margin: 0 0 20px;
+    font-size: 16px;
+    color: #303133;
+    border-bottom: 2px solid #e4e7ed;
+  }
+}
+
+/* 详情项样式 */
+.detail-item {
+  display: flex;
+  align-items: flex-start;
+  min-height: 32px;
+  margin-bottom: 24px;
+}
+.detail-label {
+  flex-shrink: 0;
+  min-width: 120px;
+  font-size: 14px;
+  font-weight: 500;
+  line-height: 32px;
+  color: #606266;
+}
+.detail-value {
+  flex: 1;
+  font-size: 14px;
+  line-height: 32px;
+  color: #303133;
+  word-break: break-word;
+}
+.empty-text {
+  color: #909399;
+}
+
+/* 图片列表样式 */
+.image-list {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 12px;
+}
+.detail-image {
+  width: 100px;
+  height: 100px;
+  cursor: pointer;
+  border: 1px solid #e4e7ed;
+  border-radius: 6px;
+  box-shadow: 0 2px 4px rgb(0 0 0 / 5%);
+  transition: all 0.3s;
+}
+.detail-image:hover {
+  border-color: #409eff;
+  box-shadow: 0 4px 8px rgb(64 158 255 / 20%);
+  transform: translateY(-2px);
+}
+
+/* 套餐内容样式 */
+.package-content-item {
+  align-items: flex-start;
+}
+.package-content-item .detail-value {
+  line-height: 1.8;
+}
+.package-content-list {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+  width: 100%;
+}
+.package-group-item {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+}
+.package-dish-item {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8px;
+  align-items: center;
+  padding: 8px 12px;
+  font-size: 14px;
+  line-height: 1.6;
+  background-color: #f8f9fa;
+  border-radius: 4px;
+  transition: background-color 0.2s;
+}
+.package-dish-item:hover {
+  background-color: #f0f2f5;
+}
+.dish-category {
+  font-weight: 500;
+  color: #303133;
+  white-space: nowrap;
+}
+.dish-name {
+  color: #303133;
+  white-space: nowrap;
+}
+.dish-price {
+  font-weight: 500;
+  color: #e6a23c;
+  white-space: nowrap;
+}
+.dish-quantity {
+  color: #606266;
+  white-space: nowrap;
 }
 </style>

+ 123 - 13
src/views/groupPackageManagement/index.vue

@@ -57,6 +57,14 @@
           修改库存
         </el-button>
         <el-button
+          link
+          type="primary"
+          @click="viewRejectReason(scope.row)"
+          v-if="canShowButton(scope.row.status, OPERATION_PERMISSIONS.查看拒绝原因)"
+        >
+          查看拒绝原因
+        </el-button>
+        <el-button
           type="primary"
           link
           @click="toDetail(scope.row)"
@@ -85,13 +93,13 @@
     <el-dialog v-model="dialogFormVisible" title="修改库存" width="500">
       <el-form ref="ruleFormRef" :model="formInventory" :rules="rules" @submit.prevent>
         <el-form-item label="套餐名">
-          {{ formInventory.packageName }}
+          {{ formInventory.groupName }}
         </el-form-item>
         <el-form-item label="剩余库存">
-          {{ formInventory.remainingInventory }}
+          {{ formInventory.inventoryNum }}
         </el-form-item>
         <el-form-item label="修改库存" prop="newInventory">
-          <el-input v-model="formInventory.newInventory" placeholder="请输入" />
+          <el-input v-model="formInventory.newInventory" placeholder="请输入库存数量" />
         </el-form-item>
       </el-form>
       <template #footer>
@@ -101,6 +109,40 @@
         </div>
       </template>
     </el-dialog>
+    <!-- 查看拒绝原因弹窗 -->
+    <el-dialog v-model="rejectReasonDialogVisible" title="查看拒绝原因" width="600px">
+      <div class="reject-reason-content">
+        <div class="reject-reason-item">
+          <div class="reject-reason-label">团购名称:</div>
+          <div class="reject-reason-value">
+            {{ rejectReasonData.groupName || "--" }}
+          </div>
+        </div>
+        <div class="reject-reason-item">
+          <div class="reject-reason-label">团购编号:</div>
+          <div class="reject-reason-value">
+            {{ rejectReasonData.groupNo || "--" }}
+          </div>
+        </div>
+        <div class="reject-reason-item">
+          <div class="reject-reason-label">拒绝原因:</div>
+          <div class="reject-reason-value reject-reason-text">
+            {{
+              rejectReasonData.rejectReason ||
+              rejectReasonData.rejectionReason ||
+              rejectReasonData.refuseReason ||
+              rejectReasonData.auditReason ||
+              "暂无拒绝原因"
+            }}
+          </div>
+        </div>
+      </div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="closeRejectReasonDialog"> 确定 </el-button>
+        </div>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
@@ -112,18 +154,28 @@ import { ElMessage } from "element-plus";
 import ProTable from "@/components/ProTable/index.vue";
 import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
 import { Plus } from "@element-plus/icons-vue";
-import { deleteThali, getThaliList, sjxj, xgkc } from "@/api/modules/groupPackageManagement";
+import { deleteThali, getThaliList, sjxj, updateNum } from "@/api/modules/groupPackageManagement";
 
 const router = useRouter();
 const dialogFormVisible = ref(false);
 const formInventory: any = ref({
   id: "",
-  packageName: "",
-  remainingInventory: "",
+  groupName: "",
+  inventoryNum: "",
   newInventory: ""
 });
 const rowData = ref<any>();
 const activeName = ref("");
+// 查看拒绝原因弹窗相关
+const rejectReasonDialogVisible = ref(false);
+const rejectReasonData = ref<any>({
+  groupName: "",
+  groupNo: "",
+  rejectReason: "",
+  rejectionReason: "",
+  refuseReason: "",
+  auditReason: ""
+});
 
 // 定义表单类型
 interface RuleForm {
@@ -182,7 +234,9 @@ const OPERATION_PERMISSIONS = {
   // 编辑:草稿、审核拒绝、已售罄、已下架、已结束
   编辑: [STATUS.草稿, STATUS.审核拒绝, STATUS.已售罄, STATUS.已下架, STATUS.已结束],
   // 删除:草稿、未开始、审核拒绝、已售罄、已结束
-  删除: [STATUS.草稿, STATUS.未开始, STATUS.审核拒绝, STATUS.已售罄, STATUS.已结束]
+  删除: [STATUS.草稿, STATUS.未开始, STATUS.审核拒绝, STATUS.已售罄, STATUS.已结束],
+  // 查看拒绝原因:审核拒绝
+  查看拒绝原因: [STATUS.审核拒绝]
 } as const;
 
 // 判断按钮是否显示的工具函数
@@ -269,7 +323,8 @@ const columns = reactive<ColumnProps<any>[]>([
   },
   {
     prop: "status",
-    label: "状态"
+    label: "状态",
+    width: 200
   },
   { prop: "operation", label: "操作", fixed: "right", width: 330 }
 ]);
@@ -377,8 +432,8 @@ const changeTypes = async (row: any, status: string) => {
 };
 const changeInventory = (row: any) => {
   formInventory.value.id = row.id;
-  formInventory.value.packageName = 1;
-  formInventory.value.remainingInventory = 1;
+  formInventory.value.groupName = row.groupName;
+  formInventory.value.inventoryNum = row.inventoryNum;
   formInventory.value.newInventory = "";
   dialogFormVisible.value = true;
 };
@@ -387,7 +442,7 @@ const handleSubmit = async () => {
   if (!ruleFormRef.value) return;
   await ruleFormRef.value.validate(async (valid, fields) => {
     if (valid) {
-      let res = await xgkc({ id: formInventory.value.id, status: formInventory.value.newInventory });
+      let res = await updateNum({ id: formInventory.value.id, num: formInventory.value.newInventory });
       if (res && res.code == 200) {
         ElMessage.success("库存修改成功");
         dialogFormVisible.value = false;
@@ -401,11 +456,35 @@ const closeDialog = () => {
   dialogFormVisible.value = false;
   formInventory.value = {
     id: "",
-    packageName: "",
-    remainingInventory: "",
+    groupName: "",
+    inventoryNum: "",
     newInventory: ""
   };
 };
+// 查看拒绝原因
+const viewRejectReason = (row: any) => {
+  rejectReasonData.value = {
+    groupName: row.groupName || "",
+    groupNo: row.groupNo || "",
+    rejectReason: row.rejectReason || "",
+    rejectionReason: row.rejectionReason || "",
+    refuseReason: row.refuseReason || "",
+    auditReason: row.auditReason || ""
+  };
+  rejectReasonDialogVisible.value = true;
+};
+// 关闭拒绝原因弹窗
+const closeRejectReasonDialog = () => {
+  rejectReasonDialogVisible.value = false;
+  rejectReasonData.value = {
+    groupName: "",
+    groupNo: "",
+    rejectReason: "",
+    rejectionReason: "",
+    refuseReason: "",
+    auditReason: ""
+  };
+};
 </script>
 
 <style lang="scss" scoped>
@@ -435,4 +514,35 @@ const closeDialog = () => {
     align-items: flex-start;
   }
 }
+.reject-reason-content {
+  padding: 20px 0;
+  .reject-reason-item {
+    display: flex;
+    margin-bottom: 20px;
+    &:last-child {
+      margin-bottom: 0;
+    }
+    .reject-reason-label {
+      flex-shrink: 0;
+      min-width: 100px;
+      font-size: 14px;
+      font-weight: 500;
+      color: #606266;
+    }
+    .reject-reason-value {
+      flex: 1;
+      font-size: 14px;
+      color: #303133;
+      word-break: break-word;
+      &.reject-reason-text {
+        min-height: 80px;
+        padding: 12px;
+        line-height: 1.6;
+        white-space: pre-wrap;
+        background-color: #f5f7fa;
+        border-radius: 4px;
+      }
+    }
+  }
+}
 </style>

+ 84 - 39
src/views/groupPackageManagement/newGroup.vue

@@ -12,10 +12,10 @@
           <!-- 基础信息模块 -->
           <div class="model">
             <h3 style="font-weight: bold">基础信息:</h3>
-            <!-- 团购图片上传 prop="imageList" 本地服务测不了上传图片 先去掉必填-->
+            <!-- 团购图片上传 prop="imageValueStr" 本地服务测不了上传图片 先去掉必填-->
             <el-form-item label="图片">
               <el-upload
-                v-model:file-list="storeInfoModel.imageList"
+                v-model:file-list="storeInfoModel.imageValueStr"
                 :action="uploadUrl"
                 list-type="picture-card"
                 :accept="'.jpg,.png'"
@@ -298,7 +298,7 @@
                       <el-button
                         v-for="holiday in holidayList"
                         :key="holiday.id"
-                        :type="storeInfoModel.unavailableHolidays?.includes(holiday.id) ? 'primary' : ''"
+                        :type="storeInfoModel.unavailableHolidays?.includes(String(holiday.id)) ? 'primary' : ''"
                         class="date-select-btn"
                         @click="toggleHoliday(holiday.id)"
                       >
@@ -454,12 +454,12 @@ import { ElMessage, ElMessageBox } from "element-plus";
 import { Plus, Delete, ArrowDown, ArrowUp, Picture } from "@element-plus/icons-vue";
 import {
   saveDraft,
-  editStoreInfo,
-  getDetail,
   getStoreDetail,
   getHolidayList,
   getUserByPhone,
-  getMenuByStoreId
+  getMenuByStoreId,
+  getThaliById,
+  saveThali
 } from "@/api/modules/groupPackageManagement";
 import { useRouter, useRoute } from "vue-router";
 import type { UploadProps, FormInstance } from "element-plus";
@@ -481,11 +481,11 @@ const type = ref<string>(""); // 页面类型:add-新增, edit-编辑
 const id = ref<string>(""); // 页面ID参数
 
 // 文件上传地址
-const uploadUrl = ref(`${import.meta.env.VITE_API_URL_STORE}/file/upload`);
+const uploadUrl = ref(`${import.meta.env.VITE_API_URL_PLATFORM}/file/uploadImg`);
 
 // ==================== 表单验证规则 ====================
 const rules = reactive({
-  imageList: [{ required: true, message: "请上传图片" }],
+  imageValueStr: [{ required: true, message: "请上传图片" }],
   groupName: [{ required: true, message: "请填写团购名称" }],
   startTimeType: [{ required: true, message: "请选择开始售卖时间" }],
   startTimeValue: [
@@ -805,7 +805,8 @@ const rules = reactive({
 // ==================== 团购包信息数据模型 ====================
 const storeInfoModel = ref<any>({
   // 团购图片列表
-  imageList: [],
+  imageValueStr: [],
+  imageId: [],
   // 团购名称
   groupName: "",
   // 开始售卖时间设置方式:0-审核通过后立即开始,1-设置售卖时间
@@ -1053,17 +1054,31 @@ onMounted(async () => {
     holidayList.value = res.data.records;
   }
   if (type.value != "add") {
-    let res: any = await getStoreDetail({ id: id.value } as any);
+    const params = {
+      id: id.value,
+      userId: localGet("userId") || "104"
+    };
+    let res: any = await getThaliById(params);
     storeInfoModel.value = { ...storeInfoModel.value, ...res.data.lifeGroupBuyMain };
-    let imageList: any[] = [];
-    handleImageParam((res.data as any).businessLicenseAddress || [], imageList);
-    storeInfoModel.value.imageList = imageList;
-    storeInfoModel.value.expirationDateList = storeInfoModel.value.expirationDateList.split(";");
-    storeInfoModel.value.invoiceInformation = storeInfoModel.value.invoiceType.split(";");
+    storeInfoModel.value.imageId = storeInfoModel.value.imageId ? storeInfoModel.value.imageId.split(",") : [];
+    let imageValueStr: any[] = [];
+    handleImageParam(storeInfoModel.value.imageValueStr || [], imageValueStr);
+    // 将 imageId 关联到对应的文件对象中
+    if (imageValueStr.length > 0 && storeInfoModel.value.imageId.length > 0) {
+      imageValueStr.forEach((file, index) => {
+        if (storeInfoModel.value.imageId[index]) {
+          file.imageId = storeInfoModel.value.imageId[index];
+        }
+      });
+    }
+    storeInfoModel.value.imageValueStr = imageValueStr;
+    storeInfoModel.value.invoiceInformation = storeInfoModel.value.invoiceType ? storeInfoModel.value.invoiceType.split(";") : [];
     // 确保星期和节日字段存在
-    const listVal = storeInfoModel.value.disableDateValue.split(";");
-    storeInfoModel.value.unavailableWeekdays = listVal[0].split(",");
-    storeInfoModel.value.unavailableHolidays = listVal[1].split(",");
+    if (storeInfoModel.value.disableDateType == 1) {
+      const listVal = storeInfoModel.value.disableDateValue ? storeInfoModel.value.disableDateValue.split(";") : [];
+      storeInfoModel.value.unavailableWeekdays = listVal[0] ? listVal[0].split(",").filter((item: string) => item) : [];
+      storeInfoModel.value.unavailableHolidays = listVal[1] ? listVal[1].split(",").filter((item: string) => item) : [];
+    }
     if (res.data.lifeGroupBuyThalis && res.data.lifeGroupBuyThalis.length > 0) {
       lifeGroupBuyThalis.value = res.data.lifeGroupBuyThalis;
       // 确保每个分组都有必要的字段
@@ -1142,6 +1157,16 @@ const handleBeforeRemove = async (uploadFile: any, uploadFiles: any[]): Promise<
  * @param uploadFiles 删除后的文件列表
  */
 const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
+  // 从被删除的文件对象中获取 imageId
+  const file = uploadFile as any;
+  const imageId = file.imageId;
+  if (imageId) {
+    // 从 imageId 数组中删除对应的 imageId
+    const index = storeInfoModel.value.imageId.indexOf(imageId);
+    if (index > -1) {
+      storeInfoModel.value.imageId.splice(index, 1);
+    }
+  }
   // 删除成功后提示
   ElMessage.success("图片已删除");
 };
@@ -1149,10 +1174,21 @@ const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
 /**
  * 图片上传 - 上传成功回调
  * @param response 上传响应数据
+ * @param uploadFile 上传的文件对象
+ * @param uploadFiles 当前文件列表
  */
-const handleSuccess = (response: any) => {
+const handleSuccess = (response: any, uploadFile: any, uploadFiles: any[]) => {
+  const imageId = response?.data[0];
+  // 将 imageId 添加到 storeInfoModel 的 imageId 数组中
+  if (!storeInfoModel.value.imageId.includes(imageId)) {
+    storeInfoModel.value.imageId.push(imageId);
+  }
+  // 将 imageId 保存到文件对象中,以便删除时使用
+  if (uploadFile) {
+    (uploadFile as any).imageId = imageId;
+  }
   ElMessage.success("图片上传成功");
-  // 上传成功后,imageList 会自动更新,response.data 包含图片URL
+  // 上传成功后,imageValueStr 会自动更新,response.data 包含图片URL
 };
 
 /**
@@ -1161,7 +1197,7 @@ const handleSuccess = (response: any) => {
  */
 const handlePictureCardPreview = (file: any) => {
   // 获取所有图片的 URL 列表
-  const urlList = storeInfoModel.value.imageList.map((item: any) => item.url || item.response?.data || item);
+  const urlList = storeInfoModel.value.imageValueStr.map((item: any) => item.url || item.response?.data || item);
   // 找到当前点击的图片索引
   const currentIndex = urlList.findIndex((url: string) => url === file.url);
   imageViewerUrlList.value = urlList;
@@ -1221,13 +1257,14 @@ const toggleHoliday = value => {
   if (!storeInfoModel.value.unavailableHolidays) {
     storeInfoModel.value.unavailableHolidays = [];
   }
-  const index = storeInfoModel.value.unavailableHolidays.indexOf(value);
+  // 统一转换为字符串进行比较
+  const valueStr = String(value);
+  const index = storeInfoModel.value.unavailableHolidays.findIndex((item: any) => String(item) === valueStr);
   if (index > -1) {
     storeInfoModel.value.unavailableHolidays.splice(index, 1);
   } else {
-    storeInfoModel.value.unavailableHolidays.push(value);
+    storeInfoModel.value.unavailableHolidays.push(valueStr);
   }
-  console.log(storeInfoModel.value.unavailableHolidays);
   // 触发表单验证
   nextTick(() => {
     ruleFormRef.value?.validateField("unavailableHolidays");
@@ -1716,23 +1753,18 @@ const packageFormRules = computed(() => {
  */
 const handleSubmit = async (type?) => {
   let params: any = { ...storeInfoModel.value };
+  // 确保 imageId 是数组,然后转换为逗号分隔的字符串
+  if (Array.isArray(params.imageId)) {
+    params.imageId = params.imageId.join(",");
+  } else {
+    params.imageId = "";
+  }
   if (params.disableDateType == 1) {
     params.disableDateValue = params.unavailableWeekdays.join(",") + ";" + params.unavailableHolidays.join(",");
-    // params.disableDateValue = [params.unavailableWeekdays, params.unavailableHolidays];
     delete params.unavailableWeekdays;
     delete params.unavailableHolidays;
-  } else if (params.disableDateType == 2) {
-    // params.disableDateValue = params.disableDateList.map(subArray => subArray.join(",")).join(";");
   }
   params.invoiceType = params.invoiceInformation.join(",");
-  // const output = lifeGroupBuyThalis.value.flatMap(group =>
-  //   group.dishes.map(dish => ({
-  //     groupName: group.groupName,
-  //     detailId: dish.detailId,
-  //     qty: dish.qty,
-  //     dishPrice: dish.dishPrice
-  //   }))
-  // );
   const paramsObj: any = {
     lifeGroupBuyMain: params,
     lifeGroupBuyThalis: lifeGroupBuyThalis.value
@@ -1751,10 +1783,11 @@ const handleSubmit = async (type?) => {
     }
     let res: any = await saveDraft(paramsObj);
     if (res && res.code == 200) {
+      ElMessage.success("保存成功");
+      goBack();
     }
-    // goBack();
   } else {
-    ruleFormRef.value!.validate(async valid => {
+    await ruleFormRef.value!.validate(async valid => {
       if (!valid) {
         ElMessage.warning("请完善表单内容信息");
         return;
@@ -1776,10 +1809,10 @@ const handleSubmit = async (type?) => {
         }
       }
       // 组装提交参数
-      let res: any = await saveDraft(paramsObj);
+      let res: any = await saveThali(paramsObj);
       if (res && res.code == 200) {
+        ElMessage.success("保存成功");
       }
-      // goBack();
     });
   }
 };
@@ -1928,6 +1961,18 @@ const handleImageParam = (list: any[], result: any[]) => {
   margin-bottom: 50px;
 }
 
+/* el-upload 图片预览铺满容器 */
+:deep(.el-upload-list--picture-card) {
+  .el-upload-list__item {
+    overflow: hidden;
+    .el-upload-list__item-thumbnail {
+      width: 100%;
+      height: 100%;
+      object-fit: fill;
+    }
+  }
+}
+
 /* 表单容器 */
 .formBox {
   display: flex;

+ 10 - 2
src/views/orderManagement/index.vue

@@ -36,7 +36,7 @@ import { onActivated, onMounted, reactive, ref } from "vue";
 import { useRouter } from "vue-router";
 import ProTable from "@/components/ProTable/index.vue";
 import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
-import { getThaliList } from "@/api/modules/groupPackageManagement";
+import { getThaliList, getCpList } from "@/api/modules/orderManagement";
 
 const router = useRouter();
 const proTable = ref<ProTableInstance>();
@@ -189,6 +189,14 @@ const handleClick = () => {
 // 显示菜品弹窗
 const showDishDialog = (row: any) => {
   // TODO: 根据实际API获取菜品数据
+  // const params = {
+  //   storeId: "104",
+  //   status: "1"
+  // };
+  // let res: any = await getCpList(params);
+  // if (res && res.code == 200) {
+  //   dishList.value = res.data.records;
+  // }
   // 这里先使用模拟数据
   dishList.value = [
     { category: "蔬菜", name: "黄豆芽", price: 5, quantity: 1 },
@@ -199,7 +207,7 @@ const showDishDialog = (row: any) => {
 
 // 跳转详情页
 const toDetail = (row: any) => {
-  router.push(`/orderManagementDetail?id=${row.id}`);
+  router.push(`/orderManagement/detail?id=${row.id}`);
 };
 </script>
 

+ 42 - 36
src/views/voucherManagement/index.vue

@@ -72,7 +72,7 @@
           {{ formInventory.packageName }}
         </el-form-item>
         <el-form-item label="剩余库存">
-          {{ formInventory.remainingInventory }}
+          {{ formInventory.inventoryNum }}
         </el-form-item>
         <el-form-item label="修改库存" prop="newInventory">
           <el-input v-model="formInventory.newInventory" placeholder="请输入" />
@@ -96,20 +96,23 @@ import { ElMessage } from "element-plus";
 import ProTable from "@/components/ProTable/index.vue";
 import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
 import { Plus } from "@element-plus/icons-vue";
-import { audit, getStaffConfigList } from "@/api/modules/staffConfig";
-import { getThaliList } from "@/api/modules/groupPackageManagement";
+import { deleteThali, getThaliList, sjxj, updateNum } from "@/api/modules/voucherManagement";
+import { ElMessageBox } from "element-plus/es";
 
 const router = useRouter();
 const dialogFormVisible = ref(false);
 const formInventory: any = ref({
   id: "",
   packageName: "",
-  remainingInventory: "",
+  inventoryNum: "",
   newInventory: ""
 });
 const rowData = ref<any>();
 const activeName = ref("");
-
+// 定义表单类型
+interface RuleForm {
+  newInventory: string;
+}
 const ruleFormRef = ref<FormInstance>();
 const rules = reactive<FormRules<RuleForm>>({
   newInventory: [
@@ -298,52 +301,55 @@ const getTableList = (params: any) => {
   let newParams = JSON.parse(JSON.stringify(params));
   return getThaliList(newParams);
 };
-
+const newGroupBuying = () => {
+  router.push(`/voucherManagement/newVoucher?type=add`);
+};
 // 跳转详情页
 const toDetail = row => {
-  router.push(`/voucherManagement/detail?id=${row.id}&type=edit`);
+  router.push(`/voucherManagement/detail?id=${row.id}`);
 };
-const editRow = row => {};
-const deleteRow = row => {};
-const newGroupBuying = () => {
-  router.push(`/voucherManagement/newVoucher?id=104&type=add`);
+const editRow = row => {
+  router.push(`/voucherManagement/newVoucher?id=${row.id}&type=edit`);
+};
+const deleteRow = row => {
+  ElMessageBox.confirm("确定要删除吗?", "提示", {
+    confirmButtonText: "OK",
+    cancelButtonText: "Cancel",
+    type: "warning"
+  }).then(() => {
+    deleteThali(row.id).then(() => {
+      ElMessage.success("删除成功");
+      proTable.value?.getTableList();
+    });
+  });
 };
 const handleClick = () => {};
-const changeTypes = (row: any, status: string) => {
+const changeTypes = async (row: any, status: string) => {
   rowData.value = row;
-  if (status === "on") {
-    handleChangeStatus(row, "1");
-  } else {
-    handleChangeStatus(row, "2");
+  let res = await sjxj({ id: row.id, status: status });
+  if (res && res.code == 200) {
+    ElMessage.success("操作成功");
+    proTable.value?.getTableList();
   }
 };
 const changeInventory = (row: any) => {
-  formInventory.value.id = 1;
-  formInventory.value.packageName = 1;
-  formInventory.value.remainingInventory = 1;
+  formInventory.value.id = row.id;
+  formInventory.value.packageName = row.packageName;
+  formInventory.value.inventoryNum = row.inventoryNum;
   formInventory.value.newInventory = "";
   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 handleSubmit = async () => {
   if (!ruleFormRef.value) return;
-  await ruleFormRef.value.validate((valid, fields) => {
+  await ruleFormRef.value.validate(async (valid, fields) => {
     if (valid) {
-      ElMessage.success("修改成功");
-      dialogFormVisible.value = false;
+      let res = await updateNum({ id: formInventory.value.id, num: formInventory.value.newInventory });
+      if (res && res.code == 200) {
+        ElMessage.success("库存修改成功");
+        dialogFormVisible.value = false;
+        proTable.value?.getTableList();
+      }
     }
   });
 };
@@ -353,7 +359,7 @@ const closeDialog = () => {
   formInventory.value = {
     id: "",
     packageName: "",
-    remainingInventory: "",
+    inventoryNum: "",
     newInventory: ""
   };
 };

+ 3 - 18
src/views/voucherManagement/newVoucher.vue

@@ -231,12 +231,11 @@
  * 代金券管理 - 新增/编辑页面
  * 功能:支持代金券的新增和编辑操作
  */
-import { ref, reactive, onMounted, watch, nextTick } from "vue";
+import { ref, reactive, watch, nextTick, onMounted } from "vue";
 import { ElMessage } from "element-plus";
-import { Plus, Delete } from "@element-plus/icons-vue";
-import { getHolidayList } from "@/api/modules/groupPackageManagement";
-import { useRouter, useRoute } from "vue-router";
+import { useRoute, useRouter } from "vue-router";
 import type { FormInstance } from "element-plus";
+import { getVoucherDetail } from "@/api/modules/voucherManagement";
 
 // ==================== 响应式数据定义 ====================
 
@@ -656,20 +655,6 @@ watch(
 onMounted(async () => {
   id.value = (route.query.id as string) || "";
   type.value = (route.query.type as string) || "";
-
-  // 获取节日列表
-  let params = {
-    year: new Date().getFullYear(),
-    page: 1,
-    size: 500,
-    openFlag: 1,
-    holidayName: ""
-  };
-  let res = await getHolidayList(params);
-  if (res && res.code == 200) {
-    holidayList.value = res.data.records;
-  }
-
   // 编辑模式下加载数据
   if (type.value != "add") {
     // TODO: 加载代金券详情数据