Просмотр исходного кода

Merge branch 'dev' into 'test'

Dev

See merge request quanshu/mp-ui-pc!212
hunagwb 3 лет назад
Родитель
Сommit
6b24365dd0

+ 54 - 0
src/api/business/couponPkg.js

@@ -0,0 +1,54 @@
+import request from '@/utils/request'
+
+// 查询列表
+export function getCouponList(urlParams, data) {
+  return request({
+    url: '/api/v1/mp/admin/coupon/pkg/list',
+    method: 'post',
+    data,
+    urlParams
+  })
+}
+
+// 删除券包
+export function delCoupon(id) {
+  return request({
+    url: `/api/v1/mp/admin/coupon/pkg/delete/${id}`,
+    method: 'post'
+  })
+}
+
+// 上架下架
+export function setCouponPkgStatus(data) {
+  return request({
+    url: '/api/v1/mp/admin/coupon/pkg/status',
+    method: 'post',
+    data
+  })
+}
+
+// 创建券包
+export function couponPkgCreate(data) {
+  return request({
+    url: '/api/v1/mp/admin/coupon/pkg/create',
+    method: 'post',
+    data
+  })
+}
+
+// 修改券包
+export function couponPkgUpdate(data) {
+  return request({
+    url: '/api/v1/mp/admin/coupon/pkg/update',
+    method: 'post',
+    data
+  })
+}
+
+// 券包详情
+export function couponPkgDetail(orderId) {
+  return request({
+    url: `/api/v1/mp/admin/coupon/pkg/detail/${ orderId }`,
+    method: 'post',
+  })
+}

+ 121 - 0
src/api/business/ticketPkg.js

@@ -0,0 +1,121 @@
+import request from '@/utils/request'
+
+// 优惠券列表
+export function getTicketList(urlParams, data) {
+  return request({
+    url: '/api/v1/mp/admin/ticket/box/list',
+    method: 'post',
+    data,
+    urlParams
+  })
+}
+
+// 步进器修改
+export function setListData(data) {
+  return request({
+    url: '/api/v1/mp/admin/ticket/box/update/sortWeight',
+    method: 'post',
+    data
+  })
+}
+
+// 创建盲票组
+export function ticketBoxCreate(data) {
+  return request({
+    url: '/api/v1/mp/admin/ticket/box/create',
+    method: 'post',
+    data
+  })
+}
+
+// 盲票组详情
+export function ticketBoxDetail(data) {
+  return request({
+    url: '/api/v1/mp/admin/ticket/box/detail',
+    method: 'post',
+    data
+  })
+}
+
+//
+export function urlschemaGeneratee(data) {
+  return request({
+    url: '/api/v1/mp/wx/urlschema/generate',
+    method: 'post',
+    data
+  })
+}
+
+// 盲票组导出
+export function exportTicket(data) {
+  return request({
+    url: '/api/v1/mp/admin/ticket/box/export',
+    method: 'post',
+    timeout: 15 * 60 * 1000,
+    data
+  })
+}
+
+// 导出印刷
+export function exportDraw(data) {
+  return request({
+    url: '/api/v1/mp/admin/ticket/box/exportDraw',
+    method: 'post',
+    timeout: 15 * 60 * 1000,
+    data
+  })
+}
+
+// 下载批量导入模板
+export function importTemplate(){
+  return request({
+    url: '/api/v1/mp/admin/ticket/box/importTemplate',
+    method: 'get'
+  })
+}
+
+
+// 批量导入
+export function importTicket(data, config = {}){
+  var formData  = new FormData()
+  Object.keys(data).forEach(key => {
+    formData.append(key, data[key])
+  })
+  return request({
+    url: '/api/v1/mp/admin/ticket/box/importTicket',
+    method: 'post',
+    data: formData ,
+    ...config,
+    headers: {
+      'Content-Type': 'multipart/form-data'
+    }
+  })
+}
+
+// 上架、下架
+export function ticketBoxPut(data) {
+  return request({
+    url: '/api/v1/mp/admin/ticket/box/put',
+    method: 'post',
+    data
+  })
+}
+
+// 删除
+export function ticketBoxRemove(data) {
+  return request({
+    url: '/api/v1/mp/admin/ticket/box/remove',
+    method: 'post',
+    data
+  })
+}
+
+
+// 编辑盲票组
+export function setListDetail(data) {
+  return request({
+    url: '/api/v1/mp/admin/ticket/box/update',
+    method: 'post',
+    data
+  })
+}

+ 2 - 2
src/router/index.js

@@ -214,11 +214,11 @@ export const constantRoutes = [
         path: 'pkg/add',
         component: (resolve) => require(['@/views/business/couponPkg/create'], resolve),
         name: 'CouponPkgAdd',
-        meta: { title: '添加券包', activeMenu: '/coupon/listCouponPkg', noCache: true }
+        meta: { title: '生成券包', activeMenu: '/coupon/listCouponPkg', noCache: true }
       },
       {
         path: 'pkg/query',
-        component: (resolve) => require(['@/views/business/couponPkg/detail'], resolve),
+        component: (resolve) => require(['@/views/business/couponPkg/create'], resolve),
         name: 'CouponPkgQuery',
         meta: { title: '查看券包', activeMenu: '/coupon/listCouponPkg', noCache: true }
       },

+ 186 - 0
src/views/business/couponPkg/components/CouponAdd.vue

@@ -0,0 +1,186 @@
+<template>
+  <div>
+    <el-dialog
+      title="添加券"
+      width="1000px"
+      :visible.sync="dialogVisible"
+      :before-close="close"
+    >
+      <div class="dialog-search">
+        <div>券名称:</div>
+        <el-input
+          v-model="couponTitle"
+          placeholder="请输入券名称"
+          clearable
+          size="small"
+          style="width: 240px"
+          @keyup.enter.native="getCouponList"
+        />
+        <div class="ge"></div>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="getCouponList"
+          >查询</el-button
+        >
+      </div>
+      <el-table
+        v-loading="loading"
+        :data="couponList"
+        @selection-change="handleSelectionCoupon"
+        class="el-table"
+      >
+        <el-table-column
+          type="selection"
+          width="55"
+          align="center"
+          fixed="left"
+        />
+        <!--  -->
+        <el-table-column label="券ID" prop="couponId" />
+        <el-table-column label="券图片">
+          <template slot-scope="scope">
+            <div>
+              <el-image
+                style="width: 100px; height: 100px"
+                :src="scope.row.picUrl"
+                :preview-src-list="[scope.row.picUrl]"
+              >
+              </el-image>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="券名称" prop="title" min-width="85" />
+        <el-table-column label="使用场景" min-width="85">
+          <template slot-scope="scope">
+            <div>{{ scope.row.type.desc }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column label="券价格" min-width="85">
+          <template slot-scope="scope">
+            <div>¥{{ $numberFormat(scope.row.discount) }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column label="有效期限" min-width="85">
+          <template slot-scope="scope">
+            <div>领取后{{ scope.row.dueDays }}天有效</div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination
+        v-show="couponTotal > 0"
+        :total="couponTotal"
+        :page.sync="pageParams.pageNum"
+        :limit.sync="pageParams.pageSize"
+        @pagination="getCouponList"
+      />
+      <div class="dialog-btn">
+        <el-button size="small" @click="close"> 取 消 </el-button>
+        <div class="ge"></div>
+        <el-button type="primary" size="small" @click="confirmCoupon">
+          确 认
+        </el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import { publicFileGetUrl } from "@/api/common";
+import { getCouponList } from "@/api/business/coupon";
+export default {
+  name: "CouponAdd",
+  props: {
+    dialogVisible: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      loading: false,
+      couponTitle: "", // 券名称
+      couponList: [], // 卡券列表
+      couponTotal: 0, // 卡券总数
+      selectCouponList: [], // 选中卡券
+      pageParams: {
+        pageNum: 1,
+        pageSize: 10,
+      },
+    };
+  },
+  created() {
+    this.getCouponList();
+  },
+  methods: {
+    // 卡券列表
+    getCouponList() {
+      this.loading = true;
+      getCouponList(
+        "pageNum=" +
+          this.pageParams.pageNum +
+          "&pageSize=" +
+          this.pageParams.pageSize +
+          "&",
+        { title: this.couponTitle, status: "on" }
+      ).then((res) => {
+        this.couponList = res.rows.map((item) => {
+          return {
+            ...item,
+            type: JSON.parse(item.type),
+            useArea: JSON.parse(item.useArea),
+            picUrl: publicFileGetUrl + item.picUrl,
+          };
+        });
+        this.couponTotal = res.total;
+        this.loading = false;
+      });
+    },
+
+    // 选中卡券
+    handleSelectionCoupon(e) {
+      this.selectCouponList = e.map((item) => {
+        return {
+          couponNum: 1,
+          couponId: item.couponId,
+          title: item.title,
+          createdTime: item.createdTime,
+          updatedTime: item.updatedTime,
+          type: item.type,
+          discount: item.discount,
+          dueDays: item.dueDays
+        };
+      });
+    },
+
+    // 确认选中卡券
+    confirmCoupon() {
+      this.$emit("confirmCoupon", this.selectCouponList);
+      this.close()
+    },
+
+    close() {
+      this.$emit("close");
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.dialog-search {
+  display: flex;
+  line-height: 32px;
+  margin-bottom: 20px;
+  .ge {
+    width: 40px;
+  }
+}
+.dialog-btn {
+  display: flex;
+  align-content: center;
+  justify-content: flex-end;
+  padding: 40px 0 0;
+  .ge {
+    width: 40px;
+  }
+}
+</style>

+ 145 - 4
src/views/business/couponPkg/create.vue

@@ -1,13 +1,154 @@
 <template>
-  <div></div>
+  <div class="app-container coupon-add">
+    <el-row  style="width: 700px">
+        <el-form ref="addItem" :model="addData" :rules="rules" label-width="100px">
+          <el-form-item label="券包名称:" prop="title">
+            <el-input v-model="addData.title" :readonly="readonly" placeholder="请输入券包名称" :maxlength="32" show-word-limit />
+          </el-form-item>
+        </el-form>
+    </el-row>
+    <br>
+    <el-button v-if="!readonly" type="primary" size="small" plain @click="couponTableVisible = true">添加优惠券</el-button>
+    <br>
+    <br>
+    <span style="font-size: 14px; line-height: 40px">面值总额:¥{{ $numberFormat(totalPrice) }}</span>
+    <span style="margin-left: 80px;font-size: 14px; line-height: 40px">优惠券数量:{{ couponPkgItemList.length }}</span>
+    <el-table :data="couponPkgItemList">
+      <el-table-column label="券编号" prop="couponId" align="center" />
+      <el-table-column label="券名称" prop="title" />
+       <el-table-column label="券金额" min-width="85">
+          <template slot-scope="{ row }">
+            <div>¥{{ $numberFormat(row.discount) }}</div>
+          </template>
+        </el-table-column>
+      <el-table-column label="使用场景" prop="type">
+        <template slot-scope="{ row }">
+          <div>{{ row.type.desc }}</div>
+        </template>
+      </el-table-column>
+      <el-table-column label="数量" align="center">
+        <template slot-scope="{ row }">
+          <div>
+            <el-input-number
+              :disabled="readonly"
+              v-model="row.couponNum"
+              controls-position="right"
+              :min="1"
+              size="small"
+            ></el-input-number>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="有效期限" min-width="85" align="center">
+          <template slot-scope="{ row }">
+            <div>领取后{{ row.dueDays }}天有效</div>
+          </template>
+        </el-table-column>
+      <el-table-column v-if="!readonly" prop="date" label="操作" align="center">
+        <template slot-scope="{ $index }">
+          <el-button type="text" class="del" @click="couponPkgItemList.splice($index, 1);getPrice()">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <br>
+    <el-row v-if="!readonly">
+      <el-col :span="23" style="text-align: right">
+        <el-button type="info" @click="$router.go(-1)">取消</el-button>
+        <el-button :loading="addIng" type="primary" @click="update()">保存</el-button>
+      </el-col>
+    </el-row>
+    
+    <!-- 添加券 -->
+    <coupon-add :dialog-visible="couponTableVisible" @close="couponTableVisible = false" @confirmCoupon="confirmCoupon" v-if="couponTableVisible" />
+  </div>
 </template>
 <script>
+import { couponPkgCreate, couponPkgDetail, couponPkgUpdate } from "@/api/business/couponPkg";
+import CouponAdd from "./components/CouponAdd"
 export default {
+  components: {
+    CouponAdd
+  },
   data() {
-    return {};
+    return {
+      id: this.$route.query.id,
+      readonly: this.$route.name === 'CouponPkgQuery',
+      addData: {},
+      couponTableVisible: false,
+      couponPkgItemList: [],
+      totalPrice: 0,
+      addIng: false,
+      rules: {
+        title: [{ required: true, message: '请输入券包名称', trigger: 'blur' }]
+      }
+    };
+  },
+  created() {
+    if(this.id) {
+      couponPkgDetail(this.id).then(res => {
+        const { couponPkgItemVOList, facePrice, title } = res.data
+        this.addData = { title }
+        this.totalPrice = facePrice
+        this.couponPkgItemList = couponPkgItemVOList.map(item => {
+          return {
+            ... item, 
+            type: item.type && JSON.parse(item.type)
+          }
+        })
+      })
+    }
+  },
+  methods: {
+    confirmCoupon(arr) {
+      this.couponPkgItemList = this.couponPkgItemList.concat(arr)
+      this.getPrice()
+    },
+
+    getPrice() {
+      let num = 0
+      this.couponPkgItemList.forEach(item => {
+        num = item.discount + num
+      })
+      this.totalPrice = num
+    },
+
+    update() {
+      const subForm = this.$refs["addItem"];
+      subForm.validate((valid) => {
+        if (valid) {
+          if(!this.couponPkgItemList.length) {
+            this.$message.error('请添加优惠券');
+            return
+          }
+          this.addIng = true
+          let data = {
+            title: this.addData.title,
+            couponPkgItemList: this.couponPkgItemList,
+            facePrice: this.totalPrice,
+            couponNum: this.couponPkgItemList.length
+          }
+          if(this.id){
+            data.id = this.id
+          }
+          let request = this.id ? couponPkgUpdate : couponPkgCreate
+          request(data).then(res => {
+            this.addIng = false
+            if (res.code === 0) {
+              this.$message({
+                message: this.id ? '修改成功!' : '添加成功!',
+                type: 'success'
+              })
+              this.$store.dispatch('tagsView/delView', this.$route)
+              this.$router.go(-1)
+            }
+          }).catch(() => {
+            this.addIng = false
+          })
+          }
+      });
+    }
   },
-  methods: {},
 };
 </script>
 <style>
-</style>
+</style>

+ 0 - 13
src/views/business/couponPkg/detail.vue

@@ -1,13 +0,0 @@
-<template>
-  <div></div>
-</template>
-<script>
-export default {
-  data() {
-    return {};
-  },
-  methods: {},
-};
-</script>
-<style>
-</style>

+ 217 - 7
src/views/business/couponPkg/index.vue

@@ -1,17 +1,227 @@
 <template>
-  <div>
-      <el-button @click="$router.push({ name: 'CouponPkgAdd' })">添加券包</el-button>
-      <el-button @click="$router.push({ name: 'CouponPkgQuery' })">查看券包</el-button>
-      <el-button @click="$router.push({ name: 'CouponPkgEdit' })">修改券包</el-button>
+  <div class="app-container">
+    <el-form
+      v-show="showSearch"
+      :model="queryParams"
+      ref="queryForm"
+      :inline="true"
+      size="small"
+      @submit.native.prevent
+    >
+      <el-form-item label="券包名称" prop="title">
+         <el-input
+          v-model="queryParams.title"
+          placeholder="请输入券包名称"
+          clearable
+          size="small"
+          style="width: 240px"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          @click="handleQuery"
+          >搜索</el-button
+        >
+        <el-button icon="el-icon-refresh" @click="resetQuery"
+          >重置</el-button
+        >
+      </el-form-item>
+    </el-form>
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="10">
+        <el-button
+          type="primary"
+          icon="el-icon-plus"
+          size="mini"
+          @click="$router.push({ name: 'CouponPkgAdd' })"
+          v-hasPermi="['business:couponPkg:add']"
+          >生成券包</el-button
+        >
+      </el-col>
+      <right-toolbar
+        :showSearch.sync="showSearch"
+        @queryTable="getList"
+      ></right-toolbar>
+    </el-row>
+    <el-table v-loading="loading" :data="list">
+      <el-table-column label="券包编号" prop="id" width="80" align="center" />
+      <el-table-column label="券包名称" prop="title" align="center" />
+      <el-table-column label="券数量" prop="couponNum" />
+      <el-table-column label="总面值">
+        <template slot-scope="{ row }">
+          ¥{{ $numberFormat(row.facePrice) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="状态" prop="status">
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.status == 0" type="info">待上架</el-tag>
+          <el-tag v-else-if="row.status == 1" type="success">上架</el-tag>
+          <el-tag v-else-if="row.status == 2" type="info">下架</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column fixed="right" align="center" label="操作" width="230">
+        <template slot-scope="{ row }">
+          <el-button
+            v-hasPermi="['business:couponPkg:query']"
+            type="text"
+            @click="
+              $router.push({
+                name: 'CouponPkgQuery',
+                query: { id: row.id },
+              })
+            "
+            >查看</el-button
+          >
+          <el-button
+            v-if="row.status === 0"
+            v-hasPermi="['business:couponPkg:edit']"
+            type="text"
+            @click="
+              $router.push({
+                name: 'CouponPkgEdit',
+                query: { id: row.id },
+              })
+            "
+            >编辑</el-button
+          >
+          <el-button
+            v-if="row.status === 0 || row.status === 2"
+            v-hasPermi="['business:couponPkg:on']"
+            type="text"
+            @click="setStatus(row, 1)"
+            >上架</el-button
+          >
+          <el-button
+            v-if="row.status === 1"
+            v-hasPermi="['business:couponPkg:off']"
+            type="text"
+            @click="setStatus(row, 2)"
+            >下架</el-button
+          >
+          <el-button
+            v-if="row.status === 0"
+            v-hasPermi="['business:couponPkg:remove']"
+            class="del"
+            type="text"
+            @click="del(row)"
+            >删除</el-button
+          >
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList()"
+    />
   </div>
 </template>
 <script>
+import {
+  getCouponList,
+  delCoupon,
+  setCouponPkgStatus,
+} from "@/api/business/couponPkg";
 export default {
+  name: 'ListCouponPkg',
   data() {
-    return {};
+    return {
+      loading: false,
+      showSearch: true,
+      queryParams: {
+        title: "",
+      },
+      // 分页
+      pageParams: {
+        pageNum: 1,
+        pageSize: 10,
+      },
+      // 总条数
+      total: 0,
+      list: [],
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    getList() {
+      this.loading = true;
+      getCouponList(
+        "pageNum=" +
+          this.pageParams.pageNum +
+          "&pageSize=" +
+          this.pageParams.pageSize +
+          "&",
+        this.queryParams
+      )
+        .then((res) => {
+          this.loading = false;
+          if (res.code === 0) {
+            this.list = res.rows;
+            this.total = res.total;
+          }
+        })
+        .catch(() => {
+          this.loading = false;
+        });
+    },
+
+     //搜索
+    handleQuery() {
+      this.pageParams.pageNum = 1;
+      this.getList();
+    },
+
+    // 重置
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.pageParams.pageNum = 1;
+      this.getList();
+    },
+
+    setStatus(item, status) {
+      this.$confirm(
+        `确认${status === "on" ? "上架" : "下架"}券包 “${item.title}” 吗?`,
+        `${status === "on" ? "上架" : "下架"}券包`,
+        {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning",
+        }
+      ).then(() => {
+        setCouponPkgStatus({
+          id: item.id,
+          status,
+        }).then((res) => {
+          if (res.code === 0) {
+            this.$message.success("操作已完成!");
+            this.getList();
+          }
+        });
+      });
+    },
+
+    del(item) {
+      this.$confirm(`确认删除券包 “${item.title}” 吗?`, "删除券", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      }).then(() => {
+        delCoupon(item.id).then((res) => {
+          if (res.code === 0) {
+            this.$message.success("操作已完成!");
+            this.getList();
+          }
+        });
+      });
+    },
   },
-  methods: {},
 };
 </script>
 <style>
-</style>
+</style>

+ 2 - 7
src/views/business/ticket/components/AwardsList.vue

@@ -33,6 +33,7 @@
               <template slot-scope="scope">
                 <div v-if="scope.row.prizeType == 'goods'">商品</div>
                 <div v-if="scope.row.prizeType == 'coupon'">券</div>
+                <div v-if="scope.row.prizeType == 'coupon_pkg'">券包</div>
                 <div v-if="scope.row.prizeType == 'coin'">盲豆</div>
               </template>
             </el-table-column>
@@ -81,6 +82,7 @@
             <el-dropdown-menu slot="dropdown">
               <el-dropdown-item command="goods">商品</el-dropdown-item>
               <el-dropdown-item command="coupon">券</el-dropdown-item>
+              <el-dropdown-item command="coupon_pkg">券包</el-dropdown-item>
               <el-dropdown-item command="coin">盲豆</el-dropdown-item>
             </el-dropdown-menu>
           </el-dropdown>
@@ -182,13 +184,6 @@ export default {
     // 选择奖品种类
     handleCommand(e, index) {
       this.prizeIndex = index;
-      if (e == "goods") {
-        this.goodsTableVisible = true;
-      } else if (e == "coupon") {
-        this.couponTableVisible = true;
-      } else if (e == "coin") {
-        this.coinTableVisible = true;
-      }
       this.$emit('handleCommand', e)
     },
     

+ 1 - 0
src/views/business/ticket/components/CouponAdd.vue

@@ -37,6 +37,7 @@
           align="center"
           fixed="left"
         />
+        <!--  -->
         <el-table-column label="券ID" prop="couponId" />
         <el-table-column label="券图片">
           <template slot-scope="scope">

+ 154 - 0
src/views/business/ticket/components/CouponPkgAdd.vue

@@ -0,0 +1,154 @@
+<template>
+  <div>
+    <el-dialog
+      title="添加券包奖品"
+      width="1000px"
+      :visible.sync="dialogVisible"
+      :before-close="close"
+    >
+      <div class="dialog-search">
+        <div>券名称:</div>
+        <el-input
+          v-model="title"
+          placeholder="请输入券包名称"
+          clearable
+          size="small"
+          style="width: 240px"
+          @keyup.enter.native="getCouponList"
+        />
+        <div class="ge"></div>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="getCouponList"
+          >查询</el-button
+        >
+      </div>
+      <el-table
+        v-loading="loading"
+        :data="couponList"
+        @selection-change="handleSelectionCouponPkg"
+        class="el-table"
+      >
+        <el-table-column
+          type="selection"
+          width="55"
+          align="center"
+          fixed="left"
+        />
+        <el-table-column label="券包编号" prop="id" />
+        <el-table-column label="券包名称" prop="title" min-width="85" />
+        <el-table-column label="优惠券数量" prop="couponNum" />
+        <el-table-column label="总面值" min-width="85">
+          <template slot-scope="scope">
+            <div>¥{{ $numberFormat(scope.row.facePrice) }}</div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination
+        v-show="couponPkgTotal > 0"
+        :total="couponPkgTotal"
+        :page.sync="pageParams.pageNum"
+        :limit.sync="pageParams.pageSize"
+        @pagination="getCouponList"
+      />
+      <div class="dialog-btn">
+        <el-button size="small" @click="close"> 取 消 </el-button>
+        <div class="ge"></div>
+        <el-button type="primary" size="small" @click="confirmCouponPkg">
+          确 认
+        </el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import { publicFileGetUrl } from "@/api/common";
+import { getCouponList } from "@/api/business/couponPkg";
+export default {
+  name: "CouponAdd",
+  props: {
+    dialogVisible: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      loading: false,
+      title: "", // 券包名称
+      couponList: [], // 券包列表
+      couponPkgTotal: 0, // 券包总数
+      selectCouponPkgList: [], // 选中券包
+      pageParams: {
+        pageNum: 1,
+        pageSize: 10,
+      },
+    };
+  },
+  created() {
+    this.getCouponList();
+  },
+  methods: {
+    // 券包列表
+    getCouponList() {
+      this.loading = true;
+      getCouponList(
+        "pageNum=" +
+          this.pageParams.pageNum +
+          "&pageSize=" +
+          this.pageParams.pageSize +
+          "&",
+        { title: this.title, status: 1 }
+      ).then((res) => {
+        this.couponList = res.rows
+        this.couponPkgTotal = res.total;
+        this.loading = false;
+      });
+    },
+
+    // 选中券包
+    handleSelectionCouponPkg(e) {
+      this.selectCouponPkgList = e.map((item) => {
+        return {
+          prizeType: "coupon_pkg",
+          // quantity: 1,
+          id: item.id,
+          picUrl: publicFileGetUrl + item.picUrl,
+          title: item.title,
+          sortWeight: 100
+        };
+      });
+    },
+
+    // 确认选中券包
+    confirmCouponPkg() {
+      this.$emit("confirmCouponPkg", this.selectCouponPkgList);
+    },
+
+    close() {
+      this.$emit("close");
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.dialog-search {
+  display: flex;
+  line-height: 32px;
+  margin-bottom: 20px;
+  .ge {
+    width: 40px;
+  }
+}
+.dialog-btn {
+  display: flex;
+  align-content: center;
+  justify-content: flex-end;
+  padding: 40px 0 0;
+  .ge {
+    width: 40px;
+  }
+}
+</style>

+ 14 - 2
src/views/business/ticket/create.vue

@@ -145,6 +145,8 @@
     <goods-add :dialog-visible="goodsTableVisible" @close="close" @confirmGoods="confirmGoods" v-if="goodsTableVisible" />
     <!-- 添加券 -->
     <coupon-add :dialog-visible="couponTableVisible" @close="close" @confirmCoupon="confirmCoupon" v-if="couponTableVisible" />
+    <!-- 添加券包 -->
+    <coupon-pkg-add :dialog-visible="couponPkgTableVisible" @close="close" @confirmCouponPkg="confirmCouponPkg" v-if="couponPkgTableVisible" />
     <!-- 添加盲豆 -->
     <coin-add :dialog-visible="coinTableVisible" @close="close" @confirmCoin="confirmCoin" v-if="coinTableVisible" />
   </div>
@@ -158,6 +160,7 @@ import { accMul, accDiv } from "@/utils/util";
 import AwardsList from "./components/AwardsList"
 import GoodsAdd from "./components/GoodsAdd"
 import CouponAdd from "./components/CouponAdd"
+import CouponPkgAdd from "./components/CouponPkgAdd"
 import CoinAdd from "./components/CoinAdd"
 export default {
   name: "TicketCreate",
@@ -166,6 +169,7 @@ export default {
     AwardsList,
     GoodsAdd,
     CouponAdd,
+    CouponPkgAdd,
     CoinAdd,
   },
   data() {
@@ -266,6 +270,7 @@ export default {
       goodsTableVisible: false, // 添加商品弹框
       couponTitle: "", // 券名称
       couponTableVisible: false, // 添加卡券弹框
+      couponPkgTableVisible: false, // 添加券包弹框
       coinTableVisible: false, // 添加盲豆弹框
       pageParams: {
         pageNum: 1,
@@ -379,7 +384,7 @@ export default {
             item.prizeList = item.prizeList.map((ele) => {
               return {
                 ...ele,
-                refId: ele.goodsId || ele.couponId,
+                refId: ele.goodsId || ele.couponId || ele.id,
                 prizeType: ele.prizeType,
                 quantity: ele.quantity,
                 value: Number(ele.coinValue),
@@ -416,7 +421,6 @@ export default {
             background: "rgba(0, 0, 0, 0.4)",
           });
 
-
           request(data)
             .then((res) => {
               loading.close();
@@ -440,6 +444,7 @@ export default {
     close() {
       this.goodsTableVisible = false;
       this.couponTableVisible = false;
+      this.couponPkgTableVisible = false;
       this.coinTableVisible = false;
     },
 
@@ -449,6 +454,8 @@ export default {
         this.goodsTableVisible = true;
       } else if (e == "coupon") {
         this.couponTableVisible = true;
+      } else if (e == "coupon_pkg") {
+        this.couponPkgTableVisible = true;
       } else if (e == "coin") {
         this.coinTableVisible = true;
       }
@@ -464,6 +471,11 @@ export default {
       this.$refs.awards.add(1, arr)
     },
 
+    // 确认选中券包
+    confirmCouponPkg(arr) {;
+      this.$refs.awards.add(1, arr)
+    },
+
     // 确认输入盲豆
     confirmCoin(obj) {
       this.$refs.awards.add(2, obj)

+ 1 - 0
src/views/business/ticket/detail.vue

@@ -82,6 +82,7 @@
               <template slot-scope="{ row }">
                 <div v-if="row.prizeType.value == 'goods'">商品</div>
                 <div v-if="row.prizeType.value == 'coupon'">券</div>
+                <div v-if="row.prizeType.value == 'coupon_pkg'">券包</div>
                 <div v-if="row.prizeType.value == 'coin'">盲豆</div>
               </template>
             </el-table-column>

+ 1 - 5
src/views/order/userTicket/index.vue

@@ -169,11 +169,7 @@ export default {
       },
       // 总条数
       total: 0,
-      list: [
-        {
-          orderId: 1,
-        },
-      ],
+      list: [],
       // 下单时间
       tradeTimeArr: [],
       // 订单列表状态

+ 214 - 94
src/views/setting/template/create.vue

@@ -2,71 +2,115 @@
   <div class="app-container coupon-add">
     <br>
     <el-row>
+      <!-- 模板名称部分 -->
       <el-form ref="addItem" :model="addData" :rules="rules" label-width="120px">
         <el-form-item label="模板名称:" prop="title">
           <el-input v-model="addData.title" :readonly="readonly" placeholder="请输入模板名称" :maxlength="32" show-word-limit style="width: 500px;"/>
         </el-form-item>
         <br>
-        <el-form-item label="买家付费地区:" style="width: 75%">
-          <el-table :data="shippingTemplateRuleList" border style="width: 100%">
-            <el-table-column prop="shippingTemplateRuleAreaList" label="付费区域"  width="280%" @click="getList">
-              <template slot-scope="{row,$index}">
-                <el-cascader @visible-change="listPidDisabled($event,$index)" ref="cascaderAdd" :options="listPidProvince" clearable :props="props" v-model="row.shippingTemplateRuleAreaList"></el-cascader>
-              </template>
-            </el-table-column>
-            <el-table-column prop="defaultNumber" label="首件(个)">
-              <template slot-scope="{row}">
-                <el-input v-model="row.defaultNumber" placeholder="请输入内容"></el-input>
-              </template>
-            </el-table-column>
-            <el-table-column prop="defaultPrice" label="运费(元)">
-              <template slot-scope="{row}">
-                <el-input v-model="row.defaultPrice" placeholder="请输入内容"></el-input>
-              </template>
-            </el-table-column>
-            <el-table-column prop="createNumber" label="续件(个)">
-              <template slot-scope="{row}">
-                <el-input v-model="row.createNumber" placeholder="请输入内容"></el-input>
-              </template>
-            </el-table-column>
-            <el-table-column prop="createPrice" label="续费(元)">
-              <template slot-scope="{row}">
-                <el-input v-model="row.createPrice" placeholder="请输入内容"></el-input>
-              </template>
-            </el-table-column>
-          </el-table>
-          <el-col style="margin-top: 10px">
-            <el-button type="primary" size="mini" @click="getListData">添加地区</el-button>
-          </el-col>
+      </el-form>
+      <!-- 买家付费地区 -->
+      <el-form label-width="120px">
+        <el-form-item label="买家付费区域:">
+          <el-form ref="addItemTwo" :model="{shippingTemplateRuleList}" label-width="120px">
+            <table style="width: 75%"  bordercolor="#ccc" border="1" cellpadding="0" cellspacing="0"  class="spec-table">
+              <tr>
+                <th>付费区域</th>
+                <th>首件(个)</th>
+                <th>运费(元)</th>
+                <th>续件(个)</th>
+                <th>续费(元)</th>
+                <th>操作</th>
+              </tr>
+              <tr v-if="shippingTemplateRuleList == ''">
+                <td colspan="6">
+                  暂无数据
+                </td>
+              </tr>
+              <tr v-for="(item,index) in shippingTemplateRuleList" :key="index" style="">
+                <td>
+                  <el-form-item :prop="`shippingTemplateRuleList.${index}.shippingTemplateRuleAreaList`" :rules="[{ required: true, message: '地区不能为空', trigger:['blur','change'] },{ type: 'array', message: '请选择地区' }]" style="width: 100%">
+                    <el-cascader @visible-change="listPidDisabled($event,index)" ref="cascaderAdd" :options="listPidProvince" clearable :props="props" v-model="item.shippingTemplateRuleAreaList" style="" ></el-cascader>
+                  </el-form-item>
+                </td>
+                <td>
+                  <el-form-item :prop="`shippingTemplateRuleList.${index}.defaultNumber`" :rules='[{ required: true, message: "件数不能为空", trigger: "blur" },{ pattern: /^([1-9]\d*)$/, message: "请输入正确的件数", trigger: ["blur", "change"]}]' label-width="0">
+                    <el-input v-model="item.defaultNumber" placeholder="请输入内容"></el-input>
+                  </el-form-item>
+                </td>
+                <td>
+                  <el-form-item :prop="`shippingTemplateRuleList.${index}.defaultPrice`" :rules="[{ required: true, message: '运费不能为空', trigger: 'blur' },{ pattern: /^([1-9]\d*(\.\d{1,2})?|([0](\.([0][1-9]|[1-9]\d{0,1}))))$/, message: '请输入正确的金额,最多两位小数', trigger: ['blur', 'change'] }]" label-width="0">
+                    <el-input v-model="item.defaultPrice" placeholder="请输入内容"></el-input>
+                  </el-form-item>
+                </td>
+                <td>
+                  <el-form-item :prop="`shippingTemplateRuleList.${index}.createNumber`" :rules='[{ required: true, message: "件数不能为空", trigger: "blur" },{ pattern: /^([1-9]\d*)$/, message: "请输入正确的件数", trigger: ["blur", "change"]}]' label-width="0">
+                    <el-input v-model="item.createNumber" placeholder="请输入内容"></el-input>
+                  </el-form-item>
+                </td>
+                <td>
+                  <el-form-item :prop="`shippingTemplateRuleList.${index}.createPrice`" :rules="[{ required: true, message: '运费不能为空', trigger: 'blur' },{ pattern: /^([1-9]\d*(\.\d{1,2})?|([0](\.([0][1-9]|[1-9]\d{0,1}))))$/, message: '请输入正确的金额,最多两位小数', trigger: ['blur', 'change'] }]" label-width="0">
+                    <el-input v-model="item.createPrice" placeholder="请输入内容"></el-input>
+                  </el-form-item>
+                </td>
+                <td>
+                  <el-button  type="text" @click="delRow(item)">删除</el-button>
+                </td>
+              </tr>
+            </table>
+            <el-col style="margin-top: 10px">
+              <el-button type="primary" size="mini" @click="getListData">添加地区</el-button>
+            </el-col>
+
+          </el-form>
         </el-form-item>
-        <br>
-        <br>
       </el-form>
-      <el-form ref="form" :model="addData" label-width="120px">
-        <el-form-item label="不发货地区:"   style="width: 75%">
-          <el-table :data="shippingTemplateRuleList2" border style="width: 100%">
-            <el-table-column prop="shippingTemplateRuleAreaList" label="不发货区域" >
-              <template slot-scope="{row,$index}">
-                <el-cascader @visible-change="listPidDisabled($event,shippingTemplateRuleList.length+$index)" :options="listPidProvince" clearable :props="props" v-model="row.shippingTemplateRuleAreaList"></el-cascader>
-              </template>
-            </el-table-column>
-            <el-table-column prop="remark" label="原因" >
-              <template slot-scope="{row}">
-                <el-input v-model="row.remark" placeholder="请输入内容"></el-input>
-              </template>
-            </el-table-column>
-          </el-table>
-          <el-col style="margin-top: 10px">
-            <el-button type="primary" size="mini" @click="getListData2">添加地区</el-button>
-          </el-col>
+
+      <!-- 不发货地区 -->
+      <el-form label-width="120px">
+        <el-form-item label="不发货区域:">
+          <el-form ref="addItemThree" :model="{shippingTemplateRuleList2}" label-width="120px">
+            <table style="width: 75%"  bordercolor="#ccc" border="1" cellpadding="0" cellspacing="0"  class="spec-table">
+              <tr>
+                <th>不发货区域</th>
+                <th>原因</th>
+                <th>操作</th>
+              </tr>
+              <tr v-if="shippingTemplateRuleList2 == ''">
+                <td colspan="3">
+                  暂无数据
+                </td>
+              </tr>
+              <tr v-for="(item,index) in shippingTemplateRuleList2" :key="index">
+                <td>
+                  <el-form-item :prop="`shippingTemplateRuleList2.${index}.shippingTemplateRuleAreaList`" :rules="[{ required: true, message: '地区不能为空', trigger:['blur','change'] },{ type: 'array', message: '请选择地区' }]">
+                    <el-cascader @visible-change="listPidDisabled($event,shippingTemplateRuleList.length + index)" :options="listPidProvince" clearable :props="props" v-model="item.shippingTemplateRuleAreaList"></el-cascader>
+                  </el-form-item>
+                </td>
+                <td>
+                  <el-form-item :prop="`shippingTemplateRuleList2.${index}.remark`" :rules="{ required: true, message: '原因不能为空', trigger: 'blur' }">
+                    <el-input v-model="item.remark" placeholder="请输入内容"></el-input>
+                  </el-form-item>
+                </td>
+                <td>
+                  <el-button  type="text" @click="delRowTwo(item)">删除</el-button>
+                </td>
+              </tr>
+            </table>
+            <el-col style="margin-top: 10px">
+              <el-button type="primary" size="mini" @click="getListData2">添加地区</el-button>
+            </el-col>
+          </el-form>
         </el-form-item>
+      </el-form>
 
-        <br>
+      <el-form label-width="120px">
         <el-form-item label="包邮地区:" >
           除以上地区外均为包邮地区
         </el-form-item>
       </el-form>
     </el-row>
+
     <el-row v-if="!readonly">
       <el-col :span="23" style="text-align: right">
         <el-button type="info" @click="$router.go(-1)">取消</el-button>
@@ -80,6 +124,7 @@
 import RegionList from "./components/regionList";
 import { getTemplateList, addTemplateList, getTreeList, getTemplateDetail, setTemplateDetail} from "@/api/setting/template";
 import { accDiv, accMul } from '@/utils/util'
+import {addData} from "../../../api/system/dict/data";
 export default {
   components: {RegionList},
   data() {
@@ -130,7 +175,7 @@ export default {
       listPid:[],
 
       rules: {
-        title: [{ required: true, message: '请输入模板名称', trigger: 'blur' }]
+        title: [{ required: true, message: '请输入模板名称', trigger: 'blur' }],
       }
     };
   },
@@ -249,51 +294,82 @@ export default {
     },
 
     update() {
-      if(this.addData.title.trim() == ""){
-        this.$message.error('请输入模板名称');
-        return
-      }
+      this.$refs['addItem'].validate((valid) => {
+        if (valid) {
+        } else {
+          return;
+        }
+      });
+      this.$refs['addItemTwo'].validate((valid) => {
+        if (valid) {
+        } else {
+          return;
+        }
+      });
+      this.$refs['addItemThree'].validate((valid) => {
+        if (valid) {
+        } else {
+          return;
+        }
+      });
+
       let arr = []
       if (this.shippingTemplateRuleList){
+        for (let i = 0; i < this.shippingTemplateRuleList.length; i++) {
+          let item = this.shippingTemplateRuleList[i]
+          if(item.shippingTemplateRuleAreaList == 1 || item.createNumber == '' || item.createPrice == '' || item.defaultNumber == '' || item.defaultPrice == ''){
+            this.$message({
+              showClose: true,
+              message: '请输入完整后再保存',
+              type: 'warning'
+            });
+            return
+          }
+        }
         this.shippingTemplateRuleList.map(item =>{
           let ressage = []
-          if(item.shippingTemplateRuleAreaList != 1 && item.createNumber != '' && item.createPrice != '' && item.defaultNumber != '' && item.defaultPrice != ''){
-              item.shippingTemplateRuleAreaList.map(res=>{
-                let city = ''
-                let province = ''
-                for (let i = 0; i < this.listPidProvince.length; i++) {
-                  if(this.listPidProvince[i].areaId == res[0]){
-                    city =  this.listPidProvince[i].areaName
-
-                    let cityList =  this.listPidProvince[i].cityList
-                    for (let j = 0; j < cityList.length ; j++) {
-                      if(cityList[j].areaId == res[1]){
-                        province = cityList[j].areaName
-                      }
-                    }
+          item.shippingTemplateRuleAreaList.map(res=>{
+            let city = ''
+            let province = ''
+            for (let i = 0; i < this.listPidProvince.length; i++) {
+              if(this.listPidProvince[i].areaId == res[0]){
+                city =  this.listPidProvince[i].areaName
+                let cityList =  this.listPidProvince[i].cityList
+                for (let j = 0; j < cityList.length ; j++) {
+                  if(cityList[j].areaId == res[1]){
+                    province = cityList[j].areaName
                   }
                 }
-                res = {
-                  provinceId:res[0],
-                  cityId:res[1],
-                  city:city,
-                  province:province,
-                }
-                ressage.push(res)
-              })
-            item.shippingTemplateRuleAreaList = ressage
-            item.createPrice = accMul(item.createPrice,100)
-            item.defaultPrice = accMul(item.defaultPrice,100)
-            arr.push(item)
-          }
+              }
+            }
+            res = {
+              provinceId:res[0],
+              cityId:res[1],
+              city:city,
+              province:province,
+            }
+            ressage.push(res)
+          })
+          item.shippingTemplateRuleAreaList = ressage
+          item.createPrice = accMul(item.createPrice,100)
+          item.defaultPrice = accMul(item.defaultPrice,100)
+          arr.push(item)
         })
       }
-
       if(this.shippingTemplateRuleList2){
+        for (let i = 0; i < this.shippingTemplateRuleList2.length; i++) {
+          let item = this.shippingTemplateRuleList2[i]
+          if(item.shippingTemplateRuleAreaList == 1 || item.remark == ''){
+            this.$message({
+              showClose: true,
+              message: '请输入完整后再保存',
+              type: 'warning'
+            });
+            return
+          }
+        }
         this.shippingTemplateRuleList2.map(item =>{
           let ressage = []
-          if(item.shippingTemplateRuleAreaList != [] && item.remark != ''){
-
             item.shippingTemplateRuleAreaList.map(res=>{
               let city = ''
               let province = ''
@@ -318,12 +394,12 @@ export default {
             })
             item.shippingTemplateRuleAreaList = ressage
             arr.push(item)
-          }
         })
       }
-
       this.addData.shippingTemplateRuleList = arr
-
+      this.submitForm()
+    },
+    submitForm(){
       if (this.id){
         setTemplateDetail(this.addData).then(res=>{
           if (res.code === 0) {
@@ -332,9 +408,10 @@ export default {
               type: 'success'
             })
           }
+          this.$store.dispatch('tagsView/delView', this.$route)
+          this.$router.go(-1)
         })
-        this.$store.dispatch('tagsView/delView', this.$route)
-        this.$router.go(-1)
+
       }else {
         addTemplateList(this.addData).then(res=>{
           if (res.code === 0) {
@@ -342,15 +419,58 @@ export default {
               message: '添加成功!',
               type: 'success'
             })
+            this.$store.dispatch('tagsView/delView', this.$route)
+            this.$router.go(-1)
           }
-          this.$store.dispatch('tagsView/delView', this.$route)
-          this.$router.go(-1)
         })
       }
+    },
+
 
+    delRow(row){
+      for (let i = 0; i < this.shippingTemplateRuleList.length; i++) {
+        if(this.shippingTemplateRuleList[i] == row){
+          this.shippingTemplateRuleList.splice(i,1)
+        }
+      }
+    },
+    delRowTwo(row){
+      for (let i = 0; i < this.shippingTemplateRuleList2.length; i++) {
+        if(this.shippingTemplateRuleList2[i] == row){
+          this.shippingTemplateRuleList2.splice(i,1)
+        }
+      }
     }
+
   },
 };
 </script>
-<style>
+<style lang="scss" scoped>
+.spec-table {
+  border-collapse: collapse;
+  width: 100%;
+  line-height: 32px;
+  color: #606266;
+  font-size: 14px;
+th {
+  background-color: #ECECEC;
+}
+td {
+  text-align: center;
+}
+.pd {
+  padding: 15px;
+}
+.required {
+  position: relative;
+span {
+  position: relative;
+  top: -6px;
+  left: 2px;
+  font-size: 10px;
+  color: red;
+}
+}
+
+}
 </style>