潘超林 5 napja
szülő
commit
a349ff8202

+ 85 - 0
src/api/marketing/voucher.js

@@ -86,3 +86,88 @@ export function recordPage(query) {
   })
 }
 
+export function statisticsActivity(query) {
+  return request({
+    url: '/system/storeMarketingActivity/statisticsActivity',
+    method: 'get',
+    params: query
+  })
+}
+
+export function storeMarketingActivityRemove(query) {
+  return request({
+    url: '/system/storeMarketingActivity/remove',
+    method: 'get',
+    params: query
+  })
+}
+
+export function storeMarketingActivitySave(query) {
+  return request({
+    url: '/system/storeMarketingActivity/save',
+    method: 'post',
+    data: query
+  })
+}
+export function shoppingVoucherRuleInfo(query) {
+  return request({
+    url: '/system/shoppingVoucherRule/info',
+    method: 'get',
+    params: query
+  })
+}
+export function saveOrUpdatesRule(query) {
+  return request({
+    url: '/system/shoppingVoucherRule/saveOrUpdates',
+    method: 'post',
+    data: query
+  })
+}
+export function removeStore(query) {
+  return request({
+    url: '/system/storeMarketingActivity/removeStore',
+    method: 'get',
+    params: query
+  })
+}
+export function getActivitySpuListPage(query) {
+  return request({
+    url: '/system/goods/getActivitySpuListPage',
+    method: 'get',
+    params: query
+  })
+}
+export function storeMarketingActivityUpdate(query) {
+  return request({
+    url: '/system/storeMarketingActivity/update',
+    method: 'post',
+    data: query
+  })
+}
+export function queryStorePage(query) {
+  return request({
+    url: '/system/storeMarketingActivity/queryStorePage',
+    method: 'get',
+    params: query
+  })
+}
+export function storeMarketingActivityInfo(query) {
+  return request({
+    url: '/system/storeMarketingActivity/info/' + query,
+    method: 'get',
+  })
+}
+export function queryPageRecord(query) {
+  return request({
+    url: '/system/storeMarketingActivity/queryPageRecord',
+    method: 'get',
+    params: query
+  })
+}
+export function storeMarqueryPage(query) {
+  return request({
+    url: '/system/storeMarketingActivity/queryPage',
+    method: 'get',
+    params: query
+  })
+}

+ 2 - 2
src/views/fullReturn/add.vue

@@ -315,7 +315,7 @@ export default {
         .then(() => {
           this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
           this.$router.replace({
-            path: "/marketing/fullReturn/index",
+            path: "/marketing/voucher/index",
           });
         })
         .catch(() => {});
@@ -368,7 +368,7 @@ export default {
               this.$message.success("保存成功!");
               this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
               this.$router.replace({
-                path: "/marketing/fullReturn/index",
+                path: "/marketing/voucher/index",
               });
             }
           });

+ 0 - 2
src/views/fullReturn/components/spulist.vue

@@ -27,7 +27,6 @@
           @change="cascaderChange"
         />
       </el-form-item>
-      <el-form-item label="类型" prop="spuType">
         <el-form-item label="类型" prop="scope">
         <el-select
           v-model="queryParams.scope"
@@ -41,7 +40,6 @@
           <el-option label="会员专区商品" :value="4"> </el-option>
         </el-select>
       </el-form-item>
-      </el-form-item>
       <el-form-item label="商品状态" prop="spuStatus">
         <el-select
           v-model="queryParams.spuStatus"

+ 6 - 4
src/views/fullReturn/detail.vue

@@ -53,7 +53,7 @@
               <el-radio :label="1">长期有效</el-radio>
             </el-radio-group>
           </el-form-item>
-          <el-form-item>
+          <el-form-item v-if="shopInfo.orderType == 0">
             <el-date-picker
               readonly
               v-model="shopInfo.dateRange"
@@ -95,7 +95,7 @@
               <el-radio :label="1">长期有效</el-radio>
             </el-radio-group>
           </el-form-item>
-          <el-form-item>
+          <el-form-item v-if="shopInfo.useType == 0">
             <el-date-picker
               readonly
               v-model="shopInfo.dateRange1"
@@ -232,12 +232,14 @@ export default {
             const orderStartTime = new Date(this.shopInfo.orderStartTime);
             const orderEndTime = new Date(this.shopInfo.orderEndTime);
             this.shopInfo.dateRange = [orderStartTime, orderEndTime];
+          }
+          if (this.shopInfo.useStartTime) {
             const useStartTime = new Date(this.shopInfo.useStartTime);
             const useEndTime = new Date(this.shopInfo.useEndTime);
             this.shopInfo.dateRange1 = [useStartTime, useEndTime];
-            console.log(this.shopInfo);
-            this.tabList = this.shopInfo.spuList;
           }
+
+          this.tabList = this.shopInfo.spuList;
         }
       });
     },

+ 17 - 9
src/views/fullReturn/edit.vue

@@ -267,7 +267,11 @@ export default {
           { required: true, message: "请输入满减条件", trigger: "blur " },
         ],
         orderFullShopLimit: [
-          { required: true, message: "请输入下单满购物红包额度", trigger: "blur " },
+          {
+            required: true,
+            message: "请输入下单满购物红包额度",
+            trigger: "blur ",
+          },
         ],
       },
       shopInfo: {
@@ -304,7 +308,7 @@ export default {
         .then(() => {
           this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
           this.$router.replace({
-            path: "/marketing/fullReturn/index",
+            path: "/marketing/voucher/index",
           });
         })
         .catch(() => {});
@@ -316,26 +320,29 @@ export default {
           if (this.shopInfo.orderStartTime) {
             const orderStartTime = new Date(this.shopInfo.orderStartTime);
             const orderEndTime = new Date(this.shopInfo.orderEndTime);
-            // this.shopInfo.dateRange = [orderStartTime, orderEndTime];
             this.$set(this.shopInfo, "dateRange", [
               orderStartTime,
               orderEndTime,
             ]);
+          }
+          if (this.shopInfo.useStartTime) {
             const useStartTime = new Date(this.shopInfo.useStartTime);
             const useEndTime = new Date(this.shopInfo.useEndTime);
             this.$set(this.shopInfo, "dateRange1", [useStartTime, useEndTime]);
-
-            // this.shopInfo.dateRange1 = [useStartTime, useEndTime];
-            this.tabList = this.shopInfo.spuList;
-            console.log(this.tabList);
           }
+          this.tabList = this.shopInfo.spuList;
         }
       });
     },
-    datePicker(val) {
+    xddatePicker(val){
       this.shopInfo.orderStartTime = moment(val[0]).valueOf();
       this.shopInfo.orderEndTime = moment(val[1]).valueOf();
     },
+    datePicker(val) {
+      this.shopInfo.useStartTime = moment(val[0]).valueOf();
+      this.shopInfo.useEndTime = moment(val[1]).valueOf();
+
+    },
     spuSelect() {
       this.shopDialog = true;
     },
@@ -358,6 +365,7 @@ export default {
         this.$message.error("请选择商品!");
         return;
       }
+
       this.shopInfo.orderSpuIds = `[${ids.toString()}]`;
       this.$refs.form.validate((valid) => {
         if (valid) {
@@ -366,7 +374,7 @@ export default {
               this.$message.success("保存成功!");
               this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
               this.$router.replace({
-                path: "/marketing/fullReturn/index",
+                path: "/marketing/voucher/index",
               });
             }
           });

+ 15 - 12
src/views/fullReturn/index.vue

@@ -10,7 +10,7 @@
       <el-form-item label="" prop="key">
         <el-input
           v-model="queryParams.key"
-          placeholder="输入主题名称关键字搜索"
+          placeholder="输入ID/名称关键字搜索"
           clearable
           style="width: 240px"
           @keyup.enter.native="handleQuery"
@@ -62,17 +62,20 @@
       </el-table-column>
       <el-table-column label="活动时间" align="center">
         <template slot-scope="scope">
-          {{
-            scope.row.orderStartTime
-              ? $moment(scope.row.orderStartTime).format("YYYY-MM-DD")
-              : ""
-          }}
-          --
-          {{
-            scope.row.orderEndTime
-              ? $moment(scope.row.orderEndTime).format("YYYY-MM-DD")
-              : ""
-          }}
+          <span v-if="scope.row.orderType == 1"> 长期有效 </span>
+          <span v-else>
+            {{
+              scope.row.orderStartTime
+                ? $moment(scope.row.orderStartTime).format("YYYY-MM-DD")
+                : ""
+            }}
+            --
+            {{
+              scope.row.orderEndTime
+                ? $moment(scope.row.orderEndTime).format("YYYY-MM-DD")
+                : ""
+            }}
+          </span>
         </template>
       </el-table-column>
       <el-table-column label="下单商品价格" align="center" prop="spuLength" />

+ 125 - 52
src/views/manage/order.vue

@@ -288,8 +288,8 @@
     <!-- :span-method="objectSpanMethod" -->
     <el-table
       ref="multipleTable"
-      v-loading="loading"
       :span-method="objectSpanMethod"
+      v-loading="loading"
       :data="spuList"
       @selection-change="handleSelectionChange"
       row-key="id"
@@ -833,7 +833,7 @@ export default {
         sn: "",
       },
       column: [
-        { header: "订单编号", key: "userOrderSn", width: 20 },
+        { header: "订单编号", key: "carPayNo", width: 20 },
         { header: "买家姓名", key: "userNick", width: 20 },
         { header: "买家手机号", key: "userPhone", width: 20 },
         { header: "商品名称", key: "skuName", width: 20 },
@@ -996,74 +996,94 @@ export default {
       });
     },
 
-    /** 查询参数列表 */
     getList() {
       this.selectList = [];
       this.loading = true;
       queryUserOrderByShopId(
         this.addDateRange(this.queryParams, this.dateRange)
       ).then((response) => {
-        if (response.code == 200) {
-          let list = response.data.records;
-          let infoList = [];
-          for (let index = 0; index < list.length; index++) {
-            let e = list[index];
-            if (e.dxUserOrderVOList) {
-              for (let i = 0; i < e.dxUserOrderVOList.length; i++) {
-                let a = e.dxUserOrderVOList[i];
-                let c = { ...e, ...a };
-                infoList.push(c);
-              }
-            } else {
-              infoList.push(e);
-            }
-          }
-          let totalList = [];
-          for (let index = 0; index < infoList.length; index++) {
-            let e = infoList[index];
-            if (e.goodsInfo) {
+        if (response.code !== 200) {
+          this.loading = false;
+          return;
+        }
+        try {
+          // 扁平化嵌套结构
+          const flattenedList = this.flattenOrderItems(response.data.records);
+          console.log("flattenedList", flattenedList);
+
+          // 处理商品信息和规格
+          const processedList = flattenedList.map((item) => {
+            const processedItem = { ...item };
+
+            // 解析并合并商品信息
+            if (item.goodsInfo) {
               try {
-                var goods = JSON.parse(e.goodsInfo);
-                e = { ...e, ...goods[0] };
+                const goods = JSON.parse(item.goodsInfo);
+                if (Array.isArray(goods) && goods.length > 0) {
+                  // 合并第一个商品的信息
+                  Object.assign(processedItem, goods[0]);
+
+                  processedItem.specsName = goods
+                    .map((good) => `${good.specsValue?.[0]?.specsName}`)
+                    .toString();
+                  processedItem.specsValue = goods
+                    .map((good) => `${good.specsValue?.[0]?.specsValue}`)
+                    .toString();
+                  // 生成商品详情字符串
+                  processedItem.goodsDetails = goods
+                    .map(
+                      (good) =>
+                        `${good.skuName}(${
+                          good.specsValue?.[0]?.specsName || ""
+                        })-数量:${good.quantity}${good.unit}`
+                    )
+                    .join(";");
+                }
               } catch (error) {
-                console.error("解析 JSON 时出错:", error);
-                // 跳出当前循环,继续处理下一个元素
-                continue;
-              }
-            }
-            if (e.specsValue) {
-              for (let i = 0; i < e.specsValue.length; i++) {
-                let a = e.specsValue[i];
-                e = { ...e, ...a };
+                console.error("解析商品信息失败:", error);
+                processedItem.goodsDetails = "商品信息解析失败";
               }
             }
 
-            totalList.push(e);
-          }
-
-          totalList.forEach((e) => {
-            try {
-              let goos = JSON.parse(e.goodsInfo);
-              let detail = "";
-              if (goos && goos.length > 0) {
-                // 检查 goos 是否为空
-                goos.forEach((a) => {
-                  detail += `${a.skuName}(${a.specsValue[0]?.specsName})-数量:${a.quantity}${a.unit};`;
-                });
-              }
-              e.goodsDetails = detail;
-            } catch (error) {
-              console.error("解析 goodsInfo 时出错:", error);
+            // 合并规格信息
+            if (Array.isArray(item.specsValue)) {
+              item.specsValue.forEach((spec) => {
+                Object.assign(processedItem, spec);
+              });
             }
+
+            return processedItem;
           });
 
-          this.spuList = totalList;
+          console.log("12312312", processedList);
+
+          this.spuList = processedList;
           this.total = response.data.total;
+        } catch (error) {
+          console.error("处理订单数据失败:", error);
+          this.spuList = [];
+          this.total = 0;
+        } finally {
           this.loading = false;
         }
       });
     },
 
+    // 扁平化订单项目
+    flattenOrderItems(records) {
+      return records.flatMap((record) => {
+        if (
+          Array.isArray(record.dxUserOrderVOList) &&
+          record.dxUserOrderVOList.length > 0
+        ) {
+          return record.dxUserOrderVOList.map((item) => ({
+            ...record,
+            ...item,
+          }));
+        }
+        return [record];
+      });
+    },
     // 取消按钮
     cancel() {
       this.open = false;
@@ -1107,13 +1127,25 @@ export default {
     handleSelectionChange(selection) {
       console.log("selection", selection);
       this.selectList = selection.map((item) => item.carPayNo);
-      this.selectListDC = selection.map((item) => item);
-      // this.ids = Array.from(new Set(this.selectList));
+      const payNoMap = {};
+      selection.forEach((row) => {
+        const carPayNo = row.carPayNo;
+        if (!payNoMap[carPayNo]) {
+          // 找到spuList中所有相同carPayNo的行
+          payNoMap[carPayNo] = this.spuList.filter(
+            (item) => item.carPayNo === carPayNo
+          );
+        }
+      });
+      // 将所有找到的行展平到selectListDC
+      this.selectListDC = Object.values(payNoMap).flat();
+      console.log(this.selectListDC);
     },
 
     /** 导出按钮操作 */
     handleExport() {
       let lists = [];
+
       for (let index = 0; index < this.spuList.length; index++) {
         for (let a = 0; a < this.selectListDC.length; a++) {
           if (this.spuList[index].id == this.selectListDC[a].id) {
@@ -1121,6 +1153,47 @@ export default {
           }
         }
       }
+      // 定义订单状态映射表
+      const ORDER_STATUS_MAP = {
+        0: "待商家确认修改运费",
+        10: "等待买家支付",
+        20: "等待商家发布货运信息",
+        30: "司机已到达,等待买家签收",
+        40: "买家已收货",
+        50: "已取消",
+        60: "退款中",
+        70: "退款成功",
+        80: "退款失败",
+        90: "等待司机接单",
+        100: "等待司机支付保证金",
+        110: "等待司机装货",
+        120: "已装货,运输中",
+        130: "待处理售后",
+        140: "已处理售后",
+      };
+      const AFTER_SALE_STATUS_MAP = {
+        0: "未申请",
+        1: "已申请",
+        2: "审核失败",
+        3: "审核成功(退款中)",
+        4: "退款成功",
+        5: "退款失败(联系客服解决)",
+      };
+      // 处理订单状态
+      lists.forEach((e) => {
+        // 订单状态处理(使用映射表)
+        if (AFTER_SALE_STATUS_MAP.hasOwnProperty(e.afterSaleStatus)) {
+          e.afterSaleStatus = AFTER_SALE_STATUS_MAP[e.afterSaleStatus];
+        } else {
+          e.afterSaleStatus = "未知状态"; // 处理未知状态
+        }
+        // 订单状态处理(使用映射表)
+        if (ORDER_STATUS_MAP.hasOwnProperty(e.orderStatus)) {
+          e.orderStatus = ORDER_STATUS_MAP[e.orderStatus];
+        } else {
+          e.orderStatus = "未知状态"; // 处理未知状态
+        }
+      });
       console.log(lists);
       Utils.exportExcel(this.column, lists, "订单列表"); //导出方法
     },

+ 1 - 1
src/views/marketing/voucher/add.vue

@@ -253,7 +253,7 @@ export default {
               this.$message.success("保存成功!");
               this.$store.dispatch("tagsView/delView", this.$route); //关闭当前页
               this.$router.replace({
-                path: "/marketing/marketing/voucher/index",
+                path: "/marketing/voucher/index",
               });
 
               this.getInfo();

+ 56 - 16
src/views/outbound/edit.vue

@@ -13,7 +13,7 @@
         <el-col :span="12">
           <el-form-item prop="outboundOdd" label="出库单号">
             <el-input
-            disabled
+              disabled
               v-model="form.outboundOdd"
               placeholder="不输入自动生成"
               clearable
@@ -104,11 +104,15 @@
                 <template slot-scope="scope">
                   skuID:{{ scope.row.skuId }} <br />
                   规格:{{
-                    scope.row.skuSpecs ? JSON.parse(scope.row.skuSpecs)[0].specsName : ""
+                    scope.row.skuSpecs
+                      ? JSON.parse(scope.row.skuSpecs)[0].specsName
+                      : ""
                   }}
                   <br />
                   内容:{{
-                    scope.row.skuSpecs ? JSON.parse(scope.row.skuSpecs)[0].specsValue : ""
+                    scope.row.skuSpecs
+                      ? JSON.parse(scope.row.skuSpecs)[0].specsValue
+                      : ""
                   }}
                   <br />
                   计量单位:{{ scope.row.storeUnit }}
@@ -156,9 +160,8 @@
                     style="width: 100px"
                     show-word-limit
                     @input="passValue"
-                    disabled
                   >
-                  <span slot="suffix">{{ scope.row.storeUnit }}</span>
+                    <span slot="suffix">{{ scope.row.storeUnit }}</span>
                   </el-input>
                 </template>
               </el-table-column>
@@ -192,7 +195,9 @@
     </el-form>
     <div class="dialog-footer" style="text-align: center">
       <el-button @click="submitCancel">取 消</el-button>
-      <el-button type="primary" @click="submitForm" :loading="btnLading">保 存</el-button>
+      <el-button type="primary" @click="submitForm" :loading="btnLading"
+        >保 存</el-button
+      >
     </div>
 
     <el-dialog
@@ -249,18 +254,36 @@
         row-key="id"
       >
         <el-table-column type="selection" width="50" align="center" />
-        <el-table-column label="入库单号" align="center" prop="storeOdd" width="200" />
-        <el-table-column label="入库订单名称" align="center" prop="storeOddName" />
-        <el-table-column label="入库时间" align="center" prop="storeDate" width="200" />
+        <el-table-column
+          label="入库单号"
+          align="center"
+          prop="storeOdd"
+          width="200"
+        />
+        <el-table-column
+          label="入库订单名称"
+          align="center"
+          prop="storeOddName"
+        />
+        <el-table-column
+          label="入库时间"
+          align="center"
+          prop="storeDate"
+          width="200"
+        />
         <el-table-column label="入库商品信息" align="skuSpecs" width="150">
           <template slot-scope="scope">
             skuID:{{ scope.row.skuId }} <br />
             规格:{{
-              scope.row.skuSpecs ? JSON.parse(scope.row.skuSpecs)[0].specsName : ""
+              scope.row.skuSpecs
+                ? JSON.parse(scope.row.skuSpecs)[0].specsName
+                : ""
             }}
             <br />
             内容:{{
-              scope.row.skuSpecs ? JSON.parse(scope.row.skuSpecs)[0].specsValue : ""
+              scope.row.skuSpecs
+                ? JSON.parse(scope.row.skuSpecs)[0].specsValue
+                : ""
             }}
             <br />
             计量单位:{{ scope.row.storeUnit }}
@@ -272,15 +295,28 @@
             {{ scope.row.storeNum }}{{ scope.row.storeUnit }}
           </template>
         </el-table-column>
-        <el-table-column label="生产日期" align="center" prop="produceDate" width="200" />
+        <el-table-column
+          label="生产日期"
+          align="center"
+          prop="produceDate"
+          width="200"
+        />
         <el-table-column label="保质期" align="center" prop="shelfLife" />
         <el-table-column label="可出库数量" align="center">
           <template slot-scope="scope">
             {{ scope.row.canOutboundNum }}{{ scope.row.storeUnit }}
           </template>
         </el-table-column>
-        <el-table-column label="供应商名称" align="center" prop="supplierName" />
-        <el-table-column label="供应商电话" align="center" prop="supplierPhone" />
+        <el-table-column
+          label="供应商名称"
+          align="center"
+          prop="supplierName"
+        />
+        <el-table-column
+          label="供应商电话"
+          align="center"
+          prop="supplierPhone"
+        />
       </el-table>
 
       <pagination
@@ -333,8 +369,12 @@ export default {
       },
       multipleSelection: [],
       rules: {
-        outboundType: [{ required: true, message: "出库类型不能为空", trigger: "blur" }],
-        outboundDate: [{ required: true, message: "出库时间不能为空", trigger: "blur" }],
+        outboundType: [
+          { required: true, message: "出库类型不能为空", trigger: "blur" },
+        ],
+        outboundDate: [
+          { required: true, message: "出库时间不能为空", trigger: "blur" },
+        ],
       },
       ids: [],
     };

+ 1 - 1
src/views/outbound/index.vue

@@ -157,7 +157,7 @@
               v-hasPermi="['storage:detail']"
               >查看</el-button
             >
-            <el-button
+            <el-button v-if="scope.row.outboundType!=2"
               size="mini"
               type="text"
               @click="handleEdit(scope.row)"

+ 136 - 0
src/views/voucher/config.vue

@@ -0,0 +1,136 @@
+<template>
+  <div class="app-container">
+    <span style="color: orange">提示:只针对平台内发布的购物红包</span>
+    <el-form
+      ref="form"
+      :model="person"
+      :rules="rules"
+      label-width="180px"
+      style="margin-top: 40px"
+    >
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="单笔订单可使用红包个数" prop="oneOrderLimit">
+            <el-input
+              v-model="person.oneOrderLimit"
+              placeholder="请输入"
+              style="width: 300px"
+            />&nbsp;&nbsp; 个
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="使用红包周期设置" prop="cycleDays">
+            <el-input
+              v-model="person.cycleDays"
+              placeholder="请输入"
+              style="width: 120px"
+            />&nbsp;&nbsp; 天,可使用
+            <el-input
+              v-model="person.useNum"
+              placeholder="请输入"
+              style="width: 120px"
+            />&nbsp;&nbsp; 次
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="单次使用红包金额设置" prop="dayOrderLimit">
+            <el-input
+              v-model="person.dayOrderLimit"
+              placeholder="请输入"
+              style="width: 300px"
+            />&nbsp;&nbsp; 元
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <div style="text-align: center; margin-top: 20px">
+      <el-button type="primary" @click="personSubmit">保 存</el-button>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  saveOrUpdatesRule,
+  shoppingVoucherRuleInfo,
+} from "@/api/marketing/voucher";
+export default {
+  data() {
+    return {
+      spuList: [],
+      activeName: 0,
+      person: {},
+      rules: {
+        cycleDays: [
+          {
+            required: true,
+            message: "请输入周期天数",
+            trigger: "blur",
+          },
+        ],
+        dayOrderLimit: [
+          {
+            required: true,
+            message: "请输入单笔订单使用红包金额",
+            trigger: "blur",
+          },
+        ],
+        oneOrderLimit: [
+          {
+            required: true,
+            message: "请输入	单笔订单使用红包个数",
+            trigger: "blur",
+          },
+        ],
+      },
+    };
+  },
+  mounted() {
+    this.getList();
+  },
+  methods: {
+    getList() {
+      this.loading = true;
+      shoppingVoucherRuleInfo().then((res) => {
+        if (res.code == 200) {
+          this.person = res.data;
+        }
+      });
+    },
+
+    personSubmit() {
+      saveOrUpdatesRule(this.person).then((res) => {
+        if (res.code == 200) {
+          this.$modal.msgSuccess("保存成功!");
+          this.getList();
+        }
+      });
+    },
+  },
+};
+</script>
+
+<style>
+.hide > .el-upload--picture-card {
+  display: none;
+}
+</style>
+<style lang="scss" scoped>
+.detail_Header {
+  margin-bottom: 35px;
+  display: flex;
+  flex-direction: row;
+  justify-content: space-around;
+  align-items: center;
+  .item {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    .count {
+      font-weight: bold;
+      font-size: 18px;
+    }
+  }
+}
+</style>

+ 231 - 0
src/views/voucher/exchange.vue

@@ -0,0 +1,231 @@
+<template>
+  <div class="app-container">
+    <div>
+      <span style="color: orange"
+        >提示:只针对店铺内使用购物红包兑换的商品</span
+      >
+    </div>
+
+    <div style="margin-top: 20px">
+      <el-button type="primary" size="mini" @click="spuSelect"
+        >选择商品</el-button
+      >
+      <el-button
+        size="mini"
+        @click="removeRow"
+        v-if="selectList && selectList.length > 0"
+        >批量移除</el-button
+      >
+      <span v-if="selectList && selectList.length > 0" style="margin-left: 10px"
+        >已选择:{{ selectList.length }}个商品</span
+      >
+    </div>
+
+    <el-table
+      v-loading="loading"
+      :data="tableList"
+      @selection-change="handleSelectionChange"
+      row-key="id"
+    >
+      <el-table-column
+        type="selection"
+        width="55"
+        align="center"
+        :selectable="checkSelectable"
+      />
+      <el-table-column label="商品Id" align="center" prop="id" />
+      <el-table-column label="商品信息" align="center">
+        <template slot-scope="scope">
+          <div
+            style="
+              display: flex;
+              flex-direction: row;
+              justify-content: space-between;
+              align-items: center;
+            "
+          >
+            <el-image
+              style="width: 30px; height: 30px"
+              :src="scope.row.pic"
+              :preview-src-list="[scope.row.pic]"
+            >
+            </el-image>
+            <div
+              :title="scope.row.spuName"
+              style="
+                width: 80px;
+                height: auto;
+                word-wrap: break-word;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                white-space: nowrap;
+              "
+            >
+              {{ scope.row.spuName }}
+            </div>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="分类" align="center" prop="categoryName" />
+      <el-table-column label="商品状态" align="center">
+        <template slot-scope="scope">
+          {{
+            scope.row.spuStatus == 2
+              ? "售罄"
+              : scope.row.spuStatus == 0
+              ? "上架"
+              : scope.row.spuStatus == 1
+              ? "下架"
+              : ""
+          }}
+        </template>
+      </el-table-column>
+      <el-table-column label="销量" align="center" prop="salesVolume" />
+      <el-table-column label="价格" align="center" width="120">
+        <template slot-scope="scope">
+          {{ scope.row.originalPrice }}元/{{ scope.row.unit }}
+        </template>
+      </el-table-column>
+      <el-table-column label="类型" align="center" width="120">
+        <template slot-scope="scope">
+          {{
+            scope.row.scope == 1
+              ? "农商批发商品"
+              : scope.row.scope == 3
+              ? "同城秒送商品"
+              : scope.row.scope == 4
+              ? "会员专区"
+              : scope.row.scope == 2
+              ? "同城特价商品"
+              : ""
+          }}
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- <pagination
+      v-show="total > 0"
+      :total="total"
+      :page.sync="queryParams.pageNo"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    /> -->
+    <div style="text-align: center; margin-top: 20px">
+      <el-button type="primary" @click="submit">保存</el-button>
+    </div>
+    <el-dialog
+      :visible.sync="shopDialog"
+      width="50%"
+      :destroy-on-close="true"
+      @close="close"
+    >
+      <SpuList
+        :selectData="tableList"
+        :dialog="false"
+        @voucherChoose="voucherChooseSpu"
+      ></SpuList>
+
+      <span
+        slot="footer"
+        class="dialog-footer"
+        v-if="$route.query.type != 'look'"
+      >
+        <el-button @click="shopDialog = false">取 消</el-button>
+        <el-button type="primary" @click="shopDialogSubmit">确 定</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  saveOrUpdatesRule,
+  shoppingVoucherRuleInfo,
+} from "@/api/marketing/voucher";
+import SpuList from "../fullReturn/components/spulist.vue";
+export default {
+  props: ["selectData"],
+  name: "product",
+  components: { SpuList },
+  data() {
+    return {
+      spulist: [],
+      // 遮罩层
+      loading: true,
+      total: 0,
+      tableList: [],
+      title: "",
+      shopDialog: false,
+      // 日期范围
+      dateRange: [],
+      selectList: [],
+      spulist: [],
+    };
+  },
+  mounted() {
+    this.getList();
+  },
+  methods: {
+    spuSelect() {
+      this.shopDialog = true;
+    },
+    handleSelectionChange(val) {
+      this.selectList = val;
+      this.$emit("voucherChoose", val);
+    },
+    removeRow() {
+      const filteredArray = this.tableList.filter(
+        (item1) => !this.selectList.some((item2) => item2.id === item1.id)
+      );
+      this.tableList = filteredArray;
+    },
+    submit() {
+      let ids = this.tableList.map((item) => item.id);
+      saveOrUpdatesRule({
+        spuIds: ids.toString(),
+      }).then((res) => {
+        this.$message({
+          message: "保存成功",
+          type: "success",
+        });
+        this.getList();
+      });
+    },
+    /** 查询参数列表 */
+    getList() {
+      this.loading = true;
+      shoppingVoucherRuleInfo().then((res) => {
+        this.tableList = res.data.spuList;
+        this.loading = false;
+      });
+    },
+
+    voucherChooseSpu(val) {
+      // 将新选择的商品与现有商品合并,并根据ID去重
+      this.spulist = val; // 同步更新spulist
+    },
+    shopDialogSubmit() {
+      console.log(1111);
+      const list1 = this.tableList ?? []; // 等价于:this.tableList || []
+      const list2 = this.spulist ?? []; // 等价于:this.spulist || []
+      // 现在合并的都是有效数组,不会报错
+      const mergedList = [...list1, ...list2];
+
+      // 使用Map数据结构根据ID去重
+      const uniqueMap = new Map();
+      mergedList.forEach((item) => {
+        if (!uniqueMap.has(item.id)) {
+          uniqueMap.set(item.id, item);
+        }
+      });
+      // 更新表格数据
+      this.tableList = Array.from(uniqueMap.values());
+      this.shopDialog = false;
+    },
+  },
+};
+</script>
+<style>
+.el-form-item {
+  margin-bottom: 10px;
+}
+</style>

+ 48 - 0
src/views/voucher/index.vue

@@ -0,0 +1,48 @@
+<template>
+  <div class="app-container">
+    <el-tabs v-model="activeName" @tab-click="handleClick">
+      <el-tab-pane label="添加购物红包" :name="1"></el-tab-pane>
+      <el-tab-pane label="购物红包使用规则" :name="2"></el-tab-pane>
+      <el-tab-pane label="兑换商品" :name="4"></el-tab-pane>
+      <el-tab-pane label="满返记录" :name="3"></el-tab-pane>
+    </el-tabs>
+    <component :is="componentName"></component>
+  </div>
+</template>
+
+<script>
+import voucherList from "../fullReturn/index.vue";
+import ruleConfig from "./config.vue";
+import recordList from "./record.vue";
+import Exchange from "./exchange.vue";
+
+export default {
+  components: { voucherList, ruleConfig, recordList, Exchange },
+  data() {
+    return {
+      activeName: 1,
+      componentName: voucherList,
+    };
+  },
+  created() {},
+  methods: {
+    handleClick() {
+      console.log(this.activeName);
+      switch (this.activeName) {
+        case 1:
+          this.componentName = voucherList;
+          break;
+        case 2:
+          this.componentName = ruleConfig;
+          break;
+        case 3:
+          this.componentName = recordList;
+          break;
+        case 4:
+          this.componentName = Exchange;
+          break;
+      }
+    },
+  },
+};
+</script>

+ 325 - 0
src/views/voucher/record.vue

@@ -0,0 +1,325 @@
+<template>
+  <div class="app-container">
+    <div style="text-align: right; margin-bottom: 10px">
+      <el-date-picker
+        v-model="dateRange"
+        type="datetimerange"
+        range-separator="-"
+        value-format="yyyy-MM-dd HH:mm:ss"
+        start-placeholder="开始日期"
+        end-placeholder="结束日期"
+        @change="tjdatePicker"
+      >
+      </el-date-picker>
+    </div>
+    <div class="header" style="width: 100%">
+      <el-row class="row" :gutter="12">
+        <el-col :span="3">
+          <div class="item">
+            <div class="count">
+              {{ orderStatistics ? orderStatistics.peopleNum : 0 }} 个
+            </div>
+            <div class="title">
+              <span>活动订单总金额(元)</span>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="3">
+          <div class="item">
+            <div class="count">
+              {{ orderStatistics ? orderStatistics.totalOrderNum : 0 }}
+            </div>
+            <div class="title">
+              <span>活动订单总笔数(元)</span>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="3">
+          <div class="item">
+            <div class="count">
+              {{ orderStatistics ? orderStatistics.totalOrderNum : 0 }}个
+            </div>
+            <div class="title">
+              <span>总返红包数量</span>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="3">
+          <div class="item">
+            <div class="count">
+              {{ orderStatistics ? orderStatistics.reduce : 0 }}个
+            </div>
+            <div class="title">
+              <span>总返红包金额(元)</span>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="3">
+          <div class="item">
+            <div class="count">
+              {{ orderStatistics ? orderStatistics.peopleNum : 0 }}个
+            </div>
+            <div class="title">
+              <span>获得活动满返红包人数</span>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+    </div>
+    <el-form
+      style="margin-top: 20px"
+      :model="queryParams"
+      ref="queryForm"
+      size="small"
+      :inline="true"
+      label-width="120px"
+    >
+      <el-form-item label="" prop="key">
+        <el-input
+          v-model="queryParams.key"
+          placeholder="请输入活动ID/活动名称/用户Id/用户昵称/用户手机号/订单编号搜索"
+          clearable
+          style="width: 300px"
+        />
+      </el-form-item>
+      <el-form-item label="下单时间" prop="dateRange">
+        <el-date-picker
+          v-model="queryParams.dateRange"
+          type="datetimerange"
+          range-separator="-"
+          value-format="yyyy-MM-dd HH:mm:ss"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          @change="datePicker"
+        >
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="返红包时间" prop="dateRange">
+        <el-date-picker
+          v-model="queryParams.dateRange1"
+          type="datetimerange"
+          range-separator="-"
+          value-format="yyyy-MM-dd HH:mm:ss"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          @change="fhbdatePicker"
+        >
+        </el-date-picker>
+      </el-form-item>
+
+      <el-form-item>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="handleQuery"
+          >搜索</el-button
+        >
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
+          >重置</el-button
+        >
+      </el-form-item>
+    </el-form>
+    <el-table
+      ref="multipleTable"
+      v-loading="loading"
+      :data="spuList"
+      :border="true"
+      row-key="id"
+    >
+      <el-table-column type="selection" align="center" />
+      <el-table-column label="领取人ID" align="center" prop="userId" />
+      <el-table-column label="领取人昵称" align="center" prop="nick" />
+      <el-table-column label="领取人手机号" align="center" prop="phone" />
+      <el-table-column label="代金券ID" align="center" prop="voucherId" />
+      <el-table-column label="代金券名称" align="center" prop="voucherName" />
+
+      <el-table-column label="类型" align="center" width="120">
+        <template slot-scope="scope">
+          {{
+            scope.row.type == 0
+              ? "通用券"
+              : scope.row.type == 1
+              ? "独立券"
+              : scope.row.type == 2
+              ? "连锁券"
+              : scope.row.type == 3
+              ? "联合券"
+              : ""
+          }}
+        </template>
+      </el-table-column>
+
+      <el-table-column label="推广方式" align="center">
+        <template slot-scope="scope">
+          {{
+            scope.row.showType == 0
+              ? "全网自动推出"
+              : scope.row.showType == 1
+              ? "定向渠道推广"
+              : ""
+          }}
+        </template>
+      </el-table-column>
+      <el-table-column label="面额(元)" align="center" prop="sendAmount" />
+      <el-table-column label="领取时间" align="center">
+        <template slot-scope="scope">
+          {{
+            scope.row.reviewTime
+              ? $moment(scope.row.reviewTime).format("YYYY-MM-DD HH:mm:ss")
+              : ""
+          }}
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total > 0"
+      :total="total"
+      :page.sync="queryParams.pageNo"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </div>
+</template>
+
+<script>
+import moment from "moment";
+import { statisticsActivity, queryPageRecord } from "@/api/marketing/voucher";
+export default {
+  data() {
+    return {
+      // 遮罩层
+      loading: false,
+      // 显示搜索条件
+      total: 0,
+      // 参数表格数据
+      spuList: [],
+      // 弹出层标题
+      title: "",
+      // 查询参数
+      dateRange: [],
+      queryParams: {
+        pageNo: 1,
+        pageSize: 10,
+        key: "",
+        showType: "",
+        startTime: "",
+        endTime: "",
+        type: "",
+        dateRange: [],
+      },
+      orderStatistics: {},
+      queryStatistics: {
+        startTime: "",
+        endTime: "",
+      },
+    };
+  },
+  mounted() {
+    this.getList();
+    this.getstatisticsOrder();
+  },
+  methods: {
+    tjdatePicker(val) {
+      if (val) {
+        this.queryStatistics.startTime = moment(val[0]).valueOf();
+        this.queryStatistics.endTime = moment(val[1]).valueOf();
+      } else {
+        this.queryStatistics.startTime = "";
+        this.queryStatistics.endTime = "";
+      }
+      this.getstatisticsOrder();
+    },
+    fhbdatePicker(val) {
+      this.queryParams.returnStartTime = moment(val[0]).valueOf();
+      this.queryParams.returnEndTime = moment(val[1]).valueOf();
+    },
+    datePicker(val) {
+      this.queryParams.orderStartTime = moment(val[0]).valueOf();
+      this.queryParams.orderEndTime = moment(val[1]).valueOf();
+    },
+    getstatisticsOrder() {
+      statisticsActivity(this.queryStatistics).then((res) => {
+        if (res.code == 200) {
+          this.orderStatistics = res.data;
+        } else {
+          this.$modal.msgError(res.msg);
+        }
+      });
+    },
+
+    /** 查询参数列表 */
+    getList() {
+      this.loading = true;
+      queryPageRecord(this.queryParams).then((response) => {
+        if (response.code == 200) {
+          this.spuList = response.data.records;
+          this.total = response.data.total;
+          this.loading = false;
+        }
+      });
+    },
+
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.queryParams.dateRange = [];
+      this.queryParams.dateRange1 = [];
+      this.queryParams.orderStartTime = "";
+      this.queryParams.orderEndTime = "";
+      this.queryParams.returnStartTime = "";
+      this.queryParams.returnEndTime = "";
+      this.resetForm("queryForm");
+      this.queryParams.pageNo = 1;
+      this.getList();
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNo = 1;
+      this.getList();
+    },
+  },
+};
+</script>
+<style scoped lang="scss">
+.header {
+  .item {
+    height: 100px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    line-height: 40px;
+  }
+  .row {
+    background: #f4f4f4;
+    padding: 10px;
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    .title {
+      text-align: center;
+    }
+    .count {
+      text-align: center;
+      font-size: 20px;
+      font-weight: bold;
+      color: rgb(64, 158, 255);
+    }
+    .zz {
+      font-size: 14px;
+      color: red;
+      padding: 0px 10px;
+    }
+  }
+}
+.radio {
+  margin: 20px 0px;
+}
+</style>
+<style>
+.el-radio-button__inner {
+  width: 150px;
+}
+</style>