فهرست منبع

Merge branch 'test' into 'master'

Test

See merge request quanshu/mp-ui-pc!222
zhong chunping 3 سال پیش
والد
کامیت
79c97ba6ee
33فایلهای تغییر یافته به همراه2463 افزوده شده و 64 حذف شده
  1. 54 0
      src/api/business/couponPkg.js
  2. 28 0
      src/api/business/order.js
  3. 23 0
      src/api/business/template.js
  4. 121 0
      src/api/business/ticketPkg.js
  5. 46 0
      src/api/setting/template.js
  6. 132 1
      src/router/index.js
  7. 1 1
      src/views/business/banner/index.vue
  8. 1 1
      src/views/business/category/index.vue
  9. 5 3
      src/views/business/coupon/add.vue
  10. 3 3
      src/views/business/coupon/index.vue
  11. 186 0
      src/views/business/couponPkg/components/CouponAdd.vue
  12. 188 0
      src/views/business/couponPkg/create.vue
  13. 236 0
      src/views/business/couponPkg/index.vue
  14. 25 13
      src/views/business/goods/index.vue
  15. 1 1
      src/views/business/tag/index.vue
  16. 15 7
      src/views/business/ticket/components/AwardsList.vue
  17. 1 0
      src/views/business/ticket/components/CoinAdd.vue
  18. 2 0
      src/views/business/ticket/components/CouponAdd.vue
  19. 154 0
      src/views/business/ticket/components/CouponPkgAdd.vue
  20. 1 0
      src/views/business/ticket/components/GoodsAdd.vue
  21. 77 8
      src/views/business/ticket/create.vue
  22. 13 0
      src/views/business/ticket/detail.vue
  23. 11 7
      src/views/business/ticket/index.vue
  24. 8 6
      src/views/order/channel/detail.vue
  25. 2 2
      src/views/order/channel/index.vue
  26. 6 4
      src/views/order/deliver/detail.vue
  27. 3 7
      src/views/order/deliver/index.vue
  28. 181 0
      src/views/order/userTicket/detail.vue
  29. 304 0
      src/views/order/userTicket/index.vue
  30. 89 0
      src/views/setting/template/components/regionList.vue
  31. 466 0
      src/views/setting/template/create.vue
  32. 79 0
      src/views/setting/template/index.vue
  33. 1 0
      vue.config.js

+ 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',
+  })
+}

+ 28 - 0
src/api/business/order.js

@@ -137,3 +137,31 @@ export function removeChannelOrder(data) {
     data
   })
 }
+
+// 盲票订单
+export function ticketOrderList(urlParams, data) {
+  return request({
+      url: '/api/v1/mp/admin/ticket/order/list',
+      method: 'post',
+      data,
+      urlParams
+  })
+}
+
+// 盲票订单导出
+export function ticketOrderExport(data) {
+  return request({
+    url: '/api/v1/mp/admin/ticket/order/export',
+    method: 'post',
+    timeout: 15 * 60 * 1000,
+    data
+  })
+}
+
+// 盲票订单详情
+export function ticketOrderDetail(orderId) {
+  return request({
+    url: `/api/v1/mp/admin/ticket/order/detail/${ orderId }`,
+    method: 'post',
+  })
+}

+ 23 - 0
src/api/business/template.js

@@ -0,0 +1,23 @@
+import request from '@/utils/request'
+
+//查询列表
+export function getTemplateList(urlParams, data) {
+  return request({
+    url: '/api/v1/mp/admin/shipping/template/list',
+    method: 'post',
+    data,
+    urlParams
+  })
+}
+
+//删除模板
+export function delTemplate(id) {
+  return request({
+    url: `/api/v1/mp/admin/shipping/template/delete/${id}`,
+    method: 'post',
+    headers: {
+      'Content-Type': 'application/x-www-form-urlencoded'
+    },
+  })
+}
+

+ 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
+  })
+}

+ 46 - 0
src/api/setting/template.js

@@ -0,0 +1,46 @@
+import request from '@/utils/request'
+
+// 省市列表
+export function getTreeList() {
+  return request({
+    url: '/api/v1/mp/admin/area/tree/list',
+    method: 'post',
+  })
+}
+
+// 运费模板列表
+export function getTemplateList() {
+  return request({
+    url: '/api/v1/mp/admin/shipping/template/list',
+    method: 'post',
+  })
+}
+
+// 创建运费模板
+export function addTemplateList(data) {
+  return request({
+    url: '/api/v1/mp/admin/shipping/template/create',
+    method: 'post',
+    data
+  })
+}
+
+//运费模板详情
+export function getTemplateDetail(id) {
+  return request({
+    url: `/api/v1/mp/admin/shipping/template/detail/${id}`,
+    method: 'post',
+    headers: {
+      'Content-Type': 'application/x-www-form-urlencoded'
+    },
+  })
+}
+
+//编辑
+export function setTemplateDetail(data) {
+  return request({
+    url: '/api/v1/mp/admin/shipping/template/update',
+    method: 'post',
+    data
+  })
+}

+ 132 - 1
src/router/index.js

@@ -164,10 +164,141 @@ export const constantRoutes = [
         path: 'channel/childs',
         component: (resolve) => require(['@/views/business/channel/childs'], resolve),
         name: 'ChannelChilds',
-        meta: { title: '子渠道管理',activeMenu: '/channel/channel'}
+        meta: { title: '子渠道管理', activeMenu: '/channel/channel'}
       }
     ],
   },
+  {
+    path: '/goods',
+    component: Layout,
+    hidden: true,
+    children: [
+      {
+        path: 'add',
+        component: (resolve) => require(['@/views/business/goods/add'], resolve),
+        name: 'GoodsAdd',
+        meta: { title: '添加商品', activeMenu: '/goods/list', noCache: true }
+      },
+      {
+        path: 'edit',
+        component: (resolve) => require(['@/views/business/goods/add'], resolve),
+        name: 'GoodsEdit',
+        meta: { title: '修改商品', activeMenu: '/goods/list', noCache: true }
+      }
+    ],
+  },
+  {
+    path: '/coupon',
+    component: Layout,
+    hidden: true,
+    children: [
+      {
+        path: 'add',
+        component: (resolve) => require(['@/views/business/coupon/add'], resolve),
+        name: 'CouponAdd',
+        meta: { title: '生成优惠券', activeMenu: '/coupon/list', noCache: true }
+      },
+      {
+        path: 'query',
+        component: (resolve) => require(['@/views/business/coupon/add'], resolve),
+        name: 'CouponQuery',
+        meta: { title: '查看优惠券', activeMenu: '/coupon/list', noCache: true }
+      },
+      {
+        path: 'edit',
+        component: (resolve) => require(['@/views/business/coupon/add'], resolve),
+        name: 'CouponEdit',
+        meta: { title: '修改优惠券', activeMenu: '/coupon/list', noCache: true }
+      },
+      {
+        path: 'pkg/add',
+        component: (resolve) => require(['@/views/business/couponPkg/create'], resolve),
+        name: 'CouponPkgAdd',
+        meta: { title: '生成券包', activeMenu: '/coupon/listCouponPkg', noCache: true }
+      },
+      {
+        path: 'pkg/query',
+        component: (resolve) => require(['@/views/business/couponPkg/create'], resolve),
+        name: 'CouponPkgQuery',
+        meta: { title: '查看券包', activeMenu: '/coupon/listCouponPkg', noCache: true }
+      },
+      {
+        path: 'pkg/edit',
+        component: (resolve) => require(['@/views/business/couponPkg/create'], resolve),
+        name: 'CouponPkgEdit',
+        meta: { title: '修改券包', activeMenu: '/coupon/listCouponPkg', noCache: true }
+      }
+    ],
+  },
+  {
+    path: '/ticket',
+    component: Layout,
+    hidden: true,
+    children: [
+      {
+        path: 'create',
+        component: (resolve) => require(['@/views/business/ticket/create'], resolve),
+        name: 'TicketCreate',
+        meta: { title: '添加盲票组' , activeMenu: '/ticket/ticket', noCache: true }
+      },
+      {
+        path: 'edit',
+        component: (resolve) => require(['@/views/business/ticket/create'], resolve),
+        name: 'TicketEdit',
+        meta: { title: '修改盲票组' , activeMenu: '/ticket/ticket', noCache: true }
+      },
+      {
+        path: 'detail',
+        component: (resolve) => require(['@/views/business/ticket/detail'], resolve),
+        name: 'TicketDetail',
+        meta: { title: '盲票组详情' , activeMenu: '/ticket/ticket', noCache: true }
+      }
+    ]
+  },
+  {
+    path: '/order',
+    component: Layout,
+    hidden: true,
+    children: [
+      {
+        path: 'channel/query',
+        component: (resolve) => require(['@/views/order/channel/detail'], resolve),
+        name: 'ChannelDetail',
+        meta: { title: '经销商订单查看' , activeMenu: '/order/channel', noCache: true }
+      },
+      {
+        path: 'deliver/query',
+        component: (resolve) => require(['@/views/order/deliver/detail'], resolve),
+        name: 'DeliverDetail',
+        meta: { title: '提货订单查看' , activeMenu: '/order/deliver', noCache: true }
+      },
+      {
+        path: 'userTicket/query',
+        component: (resolve) => require(['@/views/order/userTicket/detail'], resolve),
+        name: 'UserTicketDetail',
+        meta: { title: '盲票销售订单查看' , activeMenu: '/order/userTicket', noCache: true }
+      }
+    ]
+  },
+  {
+    path: '/setting',
+    component: Layout,
+    hidden: true,
+    children: [
+      {
+        path: 'template/create',
+        component: (resolve) => require(['@/views/setting/template/create'], resolve),
+        name: 'TemplateCreate',
+        meta: { title: '添加运费模板' , activeMenu: '/setting/template', noCache: true }
+      },
+      {
+        path: 'template/edit',
+        component: (resolve) => require(['@/views/setting/template/create'], resolve),
+        name: 'TemplateEdit',
+        meta: { title: '修改运费模板' , activeMenu: '/setting/template', noCache: true }
+      }
+    ]
+  }
 ]
 
 export default new Router({

+ 1 - 1
src/views/business/banner/index.vue

@@ -45,7 +45,7 @@
           icon="el-icon-plus"
           size="mini"
           @click="handleAdd"
-          v-hasPermi="['business:ticket:add']"
+          v-hasPermi="['business:banner:add']"
           >添加banner</el-button
         >
       </el-col>

+ 1 - 1
src/views/business/category/index.vue

@@ -42,7 +42,7 @@
           icon="el-icon-plus"
           size="mini"
           @click="handleAdd"
-          v-hasPermi="['business:ticket:add']"
+          v-hasPermi="['business:category:add']"
           >添加分类</el-button
         >
       </el-col>

+ 5 - 3
src/views/business/coupon/add.vue

@@ -36,7 +36,7 @@
             <el-input v-model="addData.minOrderAmt" :readonly="readonly" type="number" placeholder="请输入可使用的最低消费金额">
               <template slot="append">元</template>
             </el-input>
-            <div class="tip">最低消费金额小于等于面值则为无门槛券</div>
+            <div class="tip">最低消费金额为0则为无门槛优惠券</div>
           </el-form-item>
           <el-form-item label="有效期限:" prop="dueDays">
             <el-select v-model="addData.dueDays" clearable placeholder="请选择有效期限">
@@ -126,12 +126,14 @@ export default {
     return {
       IMG_URL: publicFileGetUrl,
       id: this.$route.query.id,
-      readonly: this.$route.name === 'View',
+      readonly: this.$route.name === 'CouponQuery',
       addData: {
         ticketBoxList:[],
         useArea: 5,
         dueDays: 90,
-        type: 2
+        type: 2,
+        channelSharedRate:0,
+        minOrderAmt:0,
       },
       addIng: false,
       rules: {

+ 3 - 3
src/views/business/coupon/index.vue

@@ -35,7 +35,7 @@
           type="primary"
           icon="el-icon-plus"
           size="mini"
-          @click="$router.push('/coupon/add')"
+          @click="$router.push({ name: 'CouponAdd' })"
           v-hasPermi="['business:coupon:add']"
         >生成优惠券</el-button>
       </el-col>
@@ -67,8 +67,8 @@
       </el-table-column>
       <el-table-column fixed="right" align="right" label="操作" width="150">
         <template slot-scope="{row}">
-          <el-button v-hasPermi="['business:coupon:query']" type="text" @click="$router.push('/coupon/view?id=' + row.couponId)">查看</el-button>
-          <el-button v-if="JSON.parse(row.status).value === 'init'" v-hasPermi="['business:coupon:edit']" type="text" @click="$router.push('/coupon/edit?id=' + row.couponId)">编辑</el-button>
+          <el-button v-hasPermi="['business:coupon:query']" type="text" @click="$router.push({ name: 'CouponQuery', query: { id: row.couponId } })">查看</el-button>
+          <el-button v-if="JSON.parse(row.status).value === 'init'" v-hasPermi="['business:coupon:edit']" type="text" @click="$router.push({ name: 'CouponEdit', query: { id: row.couponId } })">编辑</el-button>
           <el-button v-if="JSON.parse(row.status).value === 'off' || JSON.parse(row.status).value === 'init'" v-hasPermi="['business:coupon:on']" type="text" @click="setStatus(row, 'on')">上架</el-button>
           <el-button v-if="JSON.parse(row.status).value === 'on'" v-hasPermi="['business:coupon:off']" type="text" @click="setStatus(row, 'off')">下架</el-button>
           <el-button v-if="JSON.parse(row.status).value === 'init'" v-hasPermi="['business:coupon:remove']" class="del" type="text" @click="del(row)">删除</el-button>

+ 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" width="60" />
+        <el-table-column label="券图片" align="center">
+          <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>

+ 188 - 0
src/views/business/couponPkg/create.vue

@@ -0,0 +1,188 @@
+<template>
+  <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">优惠券数量:{{ totalCouponNum }}</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"
+              @change="changeCouponNum"
+            ></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();getCouponNum()">删除</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"
+import { accMul } from '@/utils/util'
+export default {
+  components: {
+    CouponAdd
+  },
+  data() {
+    return {
+      id: this.$route.query.id,
+      readonly: this.$route.name === 'CouponPkgQuery',
+      addData: {},
+      couponTableVisible: false,
+      couponPkgItemList: [],
+      totalPrice: 0,
+      totalCouponNum: 0,
+      addIng: false,
+      rules: {
+        title: [{ required: true, message: '请输入券包名称', trigger: 'blur' }]
+      }
+    };
+  },
+  created() {
+    if(this.id) {
+      couponPkgDetail(this.id).then(res => {
+        const { couponPkgItemVOList, facePrice, title, couponNum } = res.data
+        this.addData = { title }
+        this.totalPrice = facePrice
+        this.totalCouponNum = couponNum
+        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()
+      this.getCouponNum()
+    },
+
+    changeCouponNum(e) {
+      let rule = /^([1-9]\d*)$/;
+      if(!rule.test(e)) {
+        this.$message.error('优惠券数量格式错误');
+        return
+      }
+      this.getPrice()
+      this.getCouponNum()
+    },
+
+    getPrice() {
+      let num = 0
+      this.couponPkgItemList.forEach(item => {
+        num = (accMul(item.discount, item.couponNum)) + num
+      })
+      this.totalPrice = num
+    },
+
+    getCouponNum() {
+      let num = 0
+      this.couponPkgItemList.forEach(item => {
+        num = item.couponNum + num
+      })
+      this.totalCouponNum = num
+    },
+
+    update() {
+      const subForm = this.$refs["addItem"];
+      subForm.validate((valid) => {
+        if (valid) {
+          if(!this.couponPkgItemList.length) {
+            this.$message.error('请添加优惠券');
+            return
+          }
+          let couponIndex = this.couponPkgItemList.findIndex((item) => {
+            let rule = /^([1-9]\d*)$/;
+            return !rule.test(item.couponNum);
+          });
+          // 判断优惠券数量格式
+          if (couponIndex != -1) {
+            this.$message.error(
+              `券${this.couponPkgItemList[couponIndex].title}的数量格式错误!`
+            );
+            return;
+          }
+          this.addIng = true
+          let data = {
+            title: this.addData.title,
+            couponPkgItemList: this.couponPkgItemList,
+            facePrice: this.totalPrice,
+            couponNum: this.totalCouponNum
+          }
+          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
+          })
+          }
+      });
+    }
+  },
+};
+</script>
+<style>
+</style>

+ 236 - 0
src/views/business/couponPkg/index.vue

@@ -0,0 +1,236 @@
+<template>
+  <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 {
+      loading: false,
+      showSearch: true,
+      queryParams: {
+        title: "",
+      },
+      // 分页
+      pageParams: {
+        pageNum: 1,
+        pageSize: 10,
+      },
+      // 总条数
+      total: 0,
+      list: [],
+    };
+  },
+  watch: {
+    $route: {
+      handler: function (val, oldVal) {
+        if (val.name == "ListCouponPkg") {
+          this.getList();
+        }
+      },
+    },
+  },
+  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();
+          }
+        });
+      });
+    },
+  },
+};
+</script>
+<style>
+</style>

+ 25 - 13
src/views/business/goods/index.vue

@@ -1,23 +1,25 @@
 <template>
   <div class="app-container coupon-list">
     <el-form v-show="showSearch" :model="queryParams" ref="queryForm" :inline="true" size="small">
-      <el-form-item label="商品名称">
+      <el-form-item label="商品名称" prop="title">
         <el-input
           v-model="queryParams.title"
           placeholder="请输入商品名称"
           clearable
+          @clear="queryParams.pageNum = 1;getList()"
           @keyup.enter.native="queryParams.pageNum = 1;getList()"
         />
       </el-form-item>
-      <el-form-item label="商品ID">
+      <el-form-item label="商品ID" prop="goodsId">
         <el-input
           v-model="queryParams.goodsId"
           placeholder="请输入商品ID"
           clearable
+          @clear="queryParams.pageNum = 1;getList()"
           @keyup.enter.native="queryParams.pageNum = 1;getList()"
         />
       </el-form-item>
-      <el-form-item label="商品分类">
+      <el-form-item label="商品分类" prop="categoryId">
        <el-select
           v-model="queryParams.categoryId"
           placeholder="请选择商品分类"
@@ -27,7 +29,7 @@
           <el-option :label="item.name" :value="item.categoryId" v-for="(item, index) in goodsCategoryItemsList" :key="index" />
         </el-select>
       </el-form-item>
-      <el-form-item label="商品标签">
+      <el-form-item label="商品标签" prop="tagId">
         <el-select
           v-model="queryParams.tagId"
           placeholder="请选择商品标签"
@@ -37,7 +39,7 @@
           <el-option :label="item.name" :value="item.tagId" v-for="(item, index) in goodsTagItemsList" :key="index" />
         </el-select>
       </el-form-item>
-      <el-form-item label="上架状态">
+      <el-form-item label="上架状态" prop="status">
         <el-select v-model="queryParams.status" placeholder="请选择商品状态" clearable @change="queryParams.pageNum = 1;getList()">
           <el-option label="全部" value="" />
           <el-option label="待上架" value="init" />
@@ -45,33 +47,33 @@
           <el-option label="已下架" value="off" />
         </el-select>
       </el-form-item>
-      <el-form-item label="是否支持兑换">
+      <el-form-item label="是否支持兑换" prop="exchangeShow">
         <el-select v-model="queryParams.exchangeShow" placeholder="请选择是否支持兑换" clearable @change="queryParams.pageNum = 1;getList()">
           <el-option label="全部" value="" />
           <el-option label="支持兑换" value="1" />
           <el-option label="不支持兑换" value="0" />
         </el-select>
       </el-form-item>
-      <el-form-item label="采购价格">
+      <el-form-item label="采购价格" prop="minCost">
         <el-input v-model="queryParams.minCost" placeholder="最低采购价格" clearable @keyup.enter.native="queryParams.pageNum = 1;getList()" />
       </el-form-item>
-      <el-form-item label="-">
+      <el-form-item label="-" prop="maxCost">
         <el-input v-model="queryParams.maxCost" placeholder="最高采购价格" clearable @keyup.enter.native="queryParams.pageNum = 1;getList()" />
       </el-form-item>
-      <el-form-item label="价格">
+      <el-form-item label="价格" prop="minValue">
         <el-input v-model="queryParams.minValue" placeholder="最低价格" clearable @keyup.enter.native="queryParams.pageNum = 1;getList()" />
       </el-form-item>
-      <el-form-item label="-">
+      <el-form-item label="-" prop="maxValue">
         <el-input v-model="queryParams.maxValue" placeholder="最高价格" clearable @keyup.enter.native="queryParams.pageNum = 1;getList()" />
       </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" @click="queryParams.pageNum = 1;getList()">搜索</el-button>
-        <el-button icon="el-icon-refresh" @click="getList(true)">重置</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 v-hasPermi="['business:goods:add']" type="primary" icon="el-icon-plus" size="mini" @click="$router.push('/goods/add')">添加商品</el-button>
+        <el-button v-hasPermi="['business:goods:add']" type="primary" icon="el-icon-plus" size="mini" @click="$router.push({ name: 'GoodsAdd' })">添加商品</el-button>
         <!-- <el-button v-hasPermi="['business:goods:on']" type="primary" plain size="mini">上架</el-button> -->
         <!-- <el-button v-hasPermi="['business:goods:off']" type="primary" plain size="mini">下架</el-button> -->
         <!-- <el-button v-hasPermi="['business:goods:remove']" type="danger" plain size="mini">删除</el-button> -->
@@ -125,7 +127,7 @@
       <el-table-column fixed="right" align="center" label="操作" width="140">
         <template slot-scope="{row}">
           <!-- <el-button v-hasPermi="['business:goods:query']" type="text">查看</el-button> -->
-          <el-button v-hasPermi="['business:goods:edit']" type="text" @click="$router.push('/goods/edit?id=' + row.goodsId)">编辑</el-button>
+          <el-button v-hasPermi="['business:goods:edit']" type="text" @click="$router.push({ name: 'GoodsEdit', query: { id: row.goodsId } })">编辑</el-button>
           <el-button v-if="JSON.parse(row.status).value === 'off' || JSON.parse(row.status).value === 'init'" v-hasPermi="['business:goods:on']" type="text" @click="setStatus(row, 'on')">上架</el-button>
           <el-button v-if="JSON.parse(row.status).value === 'on'" v-hasPermi="['business:goods:off']" type="text" @click="setStatus(row, 'off')">下架</el-button>
           <el-button v-if="JSON.parse(row.status).value === 'init'" v-hasPermi="['business:coupon:remove']" class="del" type="text" @click="del(row)">删除</el-button>
@@ -186,11 +188,13 @@ export default {
         this.goodsCategoryItemsList = res && res.data
       })
     },
+
     getGoodsTagItems(){
       goodsTagItems({}).then(res => {
         this.goodsTagItemsList = res && res.data
       })
     },
+
     getList(reset) {
       if (this.loading) {
         return
@@ -221,6 +225,13 @@ export default {
         this.loading = false
       })
     },
+
+    // 重置
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.getList();
+    },
+
     setStatus(item, status) {
       this.$confirm(`确认${status === 'on' ? '上架' : '下架'}商品 “${item.title}” 吗?`, `${status === 'on' ? '上架' : '下架'}商品`, {
         confirmButtonText: '确定',
@@ -238,6 +249,7 @@ export default {
         })
       })
     },
+
     del(item) {
       this.$confirm(`确认删除商品 “${item.title}” 吗?`, '删除商品', {
         confirmButtonText: '确定',

+ 1 - 1
src/views/business/tag/index.vue

@@ -42,7 +42,7 @@
           icon="el-icon-plus"
           size="mini"
           @click="handleAdd"
-          v-hasPermi="['business:ticket:add']"
+          v-hasPermi="['business:tag:add']"
           >添加标签</el-button
         >
       </el-col>

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

@@ -33,9 +33,22 @@
               <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>
+            <el-table-column label="排序" prop="sortWeight">
+              <template slot-scope="scope">
+                <div>
+                  <el-input-number
+                    v-model="scope.row.sortWeight"
+                    controls-position="right"
+                    :min="0"
+                    size="small"
+                  ></el-input-number>
+                </div>
+              </template>
+            </el-table-column>
             <!-- <el-table-column label="奖品数量" prop="storeName">
               <template slot-scope="scope">
                 <div>
@@ -69,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>
@@ -170,15 +184,9 @@ 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)
     },
+    
     // 改变奖级数量
     handleChangeAll(e, item) {
       this.$set(item, "quantity", e);

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

@@ -65,6 +65,7 @@ export default {
         title: `盲豆 x${this.coinForm.quantity}`,
         picUrl: publicFileGetUrl + "md.jpeg",
         coinValue: this.coinForm.quantity,
+        sortWeight: 100
       };
       this.$refs["coinForm"].validate((valid) => {
         if (valid) {

+ 2 - 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">
@@ -145,6 +146,7 @@ export default {
           couponId: item.couponId,
           picUrl: item.picUrl,
           title: item.title,
+          sortWeight: 100
         };
       });
     },

+ 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>

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

@@ -136,6 +136,7 @@ export default {
           goodsId: item.goodsId,
           picUrl: item.picUrl,
           title: item.title,
+          sortWeight: 100
         };
       });
     },

+ 77 - 8
src/views/business/ticket/create.vue

@@ -6,7 +6,7 @@
       <div class="base-info-form">
         <el-form :model="form" :rules="rules" ref="form" label-width="100px">
           <el-form-item label="盲票类型" prop="type">
-            <el-radio-group v-model="form.type" size="small" :disabled="form.disabled">
+            <el-radio-group v-model="form.type" size="small" :disabled="form.disabled" @change="$refs['form'].clearValidate()">
               <el-radio label="online">线上盲票</el-radio>
               <el-radio label="offline">线下盲票</el-radio>
             </el-radio-group>
@@ -24,6 +24,7 @@
               v-model="ticketPicUrl"
               :limit="1"
               :file-size="0.2"
+              @change="$refs.form.validateField(['picUrl'])"
             />
           </el-form-item>
           <div class="tip">
@@ -96,6 +97,34 @@
           <div class="tip">
             例如:一张盲票用户支付10元,盲票佣金系数90%,经销商佣金比例20%,那么经销商佣金为10元*90%*20%=1.8元
           </div>
+          <el-form-item label="销售范围" prop="saleChannelType" v-if="form.type == 'offline'">
+            <el-radio-group v-model="form.saleChannelType" size="small" @change="$refs['form'].clearValidate()">
+              <el-radio :label="1">所有渠道</el-radio>
+              <el-radio :label="2">指定渠道</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item label="渠道" prop="channelIdList" v-if="form.saleChannelType == 2">
+            <el-select
+              v-model="form.channelIdList"
+              placeholder="请选择渠道"
+              style="width: 240px;"
+              filterable
+              clearable
+              multiple
+            >
+              <el-option
+                v-for="(item, index) in channelList"
+                :key="index"
+                :label="item.name"
+                :value="item.channelId">
+                <div>
+                  <span style="float: left;">{{item.name}} </span>
+                  <span style="float: right;">{{item.mobile}}</span>
+                </div>
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <div class="tip" v-if="form.type == 'offline'">注:盲票只对所选渠道下的经销商可见</div>
         </el-form>
       </div>
       <div class="base-info-title" >奖级设置</div>
@@ -117,6 +146,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>
@@ -125,10 +156,12 @@
 import { publicFileGetUrl } from "@/api/common";
 import CustomFieldsMixin from "@/mixins/CustomFields";
 import { ticketBoxCreate, setListDetail, ticketBoxDetail} from "@/api/business/ticket";
+import { listAllChannel} from "@/api/admin/channel";
 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",
@@ -137,6 +170,7 @@ export default {
     AwardsList,
     GoodsAdd,
     CouponAdd,
+    CouponPkgAdd,
     CoinAdd,
   },
   data() {
@@ -153,8 +187,11 @@ export default {
         pkgUnit: 200, // 张数
         pkgSalePrice: 0, // 单价
         saleCommRate: "", // 基数
-        disabled:false,
+        disabled: false,
+        saleChannelType: 1
       },
+      // 上级渠道列表
+      channelList:[],
       rules: {
         type: [
           { required: true, message: "请选择盲票类型", trigger: "change" },
@@ -166,7 +203,7 @@ export default {
           {
             required: true,
             message: "请上传盲票图片",
-            trigger: "change",
+            trigger: ["blur", "change"],
           },
         ],
         facePrice: [
@@ -221,6 +258,12 @@ export default {
             trigger: ["blur", "change"],
           },
         ],
+        saleChannelType: [
+          { required: true, message: "请选择销售范围", trigger: "change" },
+        ],
+        channelIdList: [
+          { required: true, message: "请选择渠道", trigger: "change" },
+        ],
       },
 
       // 奖级列表
@@ -228,6 +271,7 @@ export default {
       goodsTableVisible: false, // 添加商品弹框
       couponTitle: "", // 券名称
       couponTableVisible: false, // 添加卡券弹框
+      couponPkgTableVisible: false, // 添加券包弹框
       coinTableVisible: false, // 添加盲豆弹框
       pageParams: {
         pageNum: 1,
@@ -250,14 +294,22 @@ export default {
     }
   },
   created() {
+    this.getChannelList()
     if (this.id) {
       let data = {
         boxId: this.id
       }
       ticketBoxDetail(data).then(res => {
-        const { awardsList, type, title, picUrl,facePrice, salePrice, quantity, pkgUnit, pkgSalePrice, saleCommRate } = res.data
-        this.form = { type: JSON.parse(type).value, disabled:true,
-          title, picUrl, facePrice:accDiv(facePrice, 100), salePrice:accDiv(salePrice, 100), quantity, pkgUnit, pkgSalePrice:accDiv(pkgSalePrice, 100), saleCommRate }
+        const { awardsList, type, title, picUrl, facePrice, salePrice, quantity, pkgUnit, pkgSalePrice, saleCommRate, saleChannelType, channelList } = res.data
+        this.form = { 
+          disabled:true,
+          title, picUrl, quantity, pkgUnit, saleCommRate, saleChannelType,
+          channelIdList: channelList.map(item => item.channelId),
+          type: JSON.parse(type).value,
+          facePrice:accDiv(facePrice, 100), 
+          salePrice:accDiv(salePrice, 100),  
+          pkgSalePrice:accDiv(pkgSalePrice, 100) 
+        }
         if(awardsList){
           awardsList.forEach((item) => {
               item.isEdit = true,
@@ -275,6 +327,12 @@ export default {
     }
   },
   methods: {
+    // 获取上级渠道下拉列表
+    getChannelList(){
+      listAllChannel().then(response => {
+         this.channelList = response.data || [];
+      });
+    },
 
     // 保存
     submitForm() {
@@ -291,6 +349,10 @@ export default {
           //   );
           //   return;
           // }
+          if (this.form.quantity > 100000) {
+            this.$message.error("盲票数量超出限制,请重新填写!");
+            return;
+          }
 
           let prizeIndex = this.awardsList.findIndex((item) => {
             return !item.prizeList.length && item.quantity > 0;
@@ -327,7 +389,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),
@@ -364,7 +426,6 @@ export default {
             background: "rgba(0, 0, 0, 0.4)",
           });
 
-
           request(data)
             .then((res) => {
               loading.close();
@@ -388,6 +449,7 @@ export default {
     close() {
       this.goodsTableVisible = false;
       this.couponTableVisible = false;
+      this.couponPkgTableVisible = false;
       this.coinTableVisible = false;
     },
 
@@ -397,6 +459,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;
       }
@@ -412,6 +476,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)

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

@@ -46,6 +46,11 @@
           <span :class="loading ? 'el-icon-loading' : ''"></span>
           {{ info && info.boxNo }}
         </el-form-item>
+        <el-form-item label="销售范围:">
+          <span :class="loading ? 'el-icon-loading' : ''"></span>
+          <span v-if="info.saleChannelType == 1">所有渠道</span>
+          <span v-else>{{ info.channelTitle }}</span>
+        </el-form-item>
       </el-form>
       <div class="base-info-title">奖级设置</div>
       <!-- 奖级设置 -->
@@ -77,9 +82,15 @@
               <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>
+            <el-table-column label="排序" prop="title" align="center">
+              <template slot-scope="{ row }">
+                <div>{{ row.sortWeight }}</div>
+              </template>
+            </el-table-column>
           </el-table>
         </div>
       </div>
@@ -90,6 +101,7 @@
 import { publicFileGetUrl } from "@/api/common";
 import { ticketBoxDetail } from "@/api/business/ticket";
 export default {
+  name: "TicketDetail",
   components: {},
   data() {
     return {
@@ -119,6 +131,7 @@ export default {
               ...data,
               type: JSON.parse(data.type),
               picUrl: publicFileGetUrl + data.picUrl,
+              channelTitle: data.channelList.map(item => item.name).join(',')
             };
             data.awardsList.forEach((item) => {
               item.prizeList.forEach((ele) => {

+ 11 - 7
src/views/business/ticket/index.vue

@@ -7,7 +7,7 @@
       v-show="showSearch"
       label-width="90px"
     >
-      <el-form-item label="盲票组名称">
+      <el-form-item label="盲票组名称" prop="title">
         <el-input
           v-model="queryParams.title"
           placeholder="请输入盲票组名称"
@@ -18,7 +18,7 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="盲票组类型">
+      <el-form-item label="盲票组类型" prop="type">
         <el-select
           v-model="queryParams.type"
           placeholder="请选择盲票组类型"
@@ -31,7 +31,7 @@
           <el-option label="线下票" value="offline" />
         </el-select>
       </el-form-item>
-      <el-form-item label="盲票组状态">
+      <el-form-item label="盲票组状态" prop="status">
         <el-select
           v-model="queryParams.status"
           placeholder="请选择盲票组状态"
@@ -55,7 +55,7 @@
           @click="handleQuery"
           >搜索</el-button
         >
-        <el-button icon="el-icon-refresh" size="mini" @click="getList(true)"
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
           >重置</el-button
         >
       </el-form-item>
@@ -391,12 +391,16 @@ export default {
     handleQuery() {
       this.getList();
     },
+
     // 重置
-    resetQuery() {},
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.getList();
+    },
 
     // 添加盲票组
     handleAdd() {
-      this.$router.push({ name: "Create" });
+      this.$router.push({ name: "TicketCreate" });
     },
 
     handleSelect(selection, row) {
@@ -412,9 +416,9 @@ export default {
 
     // 查看详情
     getDetail(row) {
-
       this.$router.push({ name: "TicketDetail", query: { id: row.boxId } });
     },
+    
     // 编辑信息
     setDetail(row) {
       this.$router.push({ name: "TicketEdit", query: { id: row.boxId } });

+ 8 - 6
src/views/order/channel/detail.vue

@@ -68,7 +68,7 @@
             <div class="txt" v-if="status.value == 2">已发货</div>
             <div class="txt" v-else>{{ status.desc || "--" }}</div>
           </div>
-          <div class="info-item-content-one" v-if="status.value === 2">
+          <div class="info-item-content-one" v-if="status.value === 2 || status.value === 3">
             <div class="title">发货时间:</div>
             <div class="txt">{{ parseTime(info.deliveryTime) || "--" }}</div>
           </div>
@@ -84,20 +84,20 @@
             @click="toGoods()"
             >发货</el-button
           >
-          <div class="info-item-content-one" v-if="status.value === 2">
+          <div class="info-item-content-one" v-if="status.value === 2 || status.value === 3">
             <div class="title">配送方式:</div>
             <div class="txt">
 <!--              {{ info.deliveryType || "&#45;&#45;" }}-->
               {{ "快递发货" || "--" }}
             </div>
           </div>
-          <div class="info-item-content-one" v-if="status.value === 2">
+          <div class="info-item-content-one" v-if="status.value === 2 || status.value === 3">
             <div class="title">快递公司:</div>
             <div class="txt">
               {{ (delivery && delivery.companyName) || "--" }}
             </div>
           </div>
-          <div class="info-item-content-one" v-if="status.value === 2">
+          <div class="info-item-content-one" v-if="status.value === 2 || status.value === 3">
             <div class="title">快递单号:</div>
             <div class="txt">{{ info.deliveryFlowId || "--" }}</div>
           </div>
@@ -155,7 +155,7 @@
           <span>运费:</span>{{ $numberFormat(info.freightAmt) }}元
         </div>
         <div class="info-amt-price">
-          <span>共计金额:</span>{{ $numberFormat(info.orderAmt) }}元
+          <span>共计金额:</span>{{ $numberFormat(info.payAmt) }}元
         </div>
       </div>
     </div>
@@ -185,7 +185,7 @@ import { accMul } from "@/utils/util";
 import SendGoods from "./components/SendGoods";
 import ExpressEdit from "./components/ExpressEdit";
 export default {
-  name: "Detail",
+  name: "ChannelDetail",
   components: {
     SendGoods,
     ExpressEdit,
@@ -284,6 +284,7 @@ export default {
         margin-bottom: 10px;
 
         .title {
+          line-height: 22px;
           width: 100px;
         }
 
@@ -293,6 +294,7 @@ export default {
         }
 
         .txt {
+          line-height: 22px;
           width: 200px;
         }
       }

+ 2 - 2
src/views/order/channel/index.vue

@@ -93,7 +93,7 @@
         >
       </el-form-item>
     </el-form>
-    <el-row :gutter="10" style="margin-bottom: 15px;">
+    <el-row :gutter="10" class="mb8">
       <el-col :span="1.5">
         <el-button
           type="infor"
@@ -388,7 +388,7 @@ export default {
 
     // 查看详情
     getDetail(row) {
-      this.$router.push({ name: "Detail", query: { id: row.orderId } });
+      this.$router.push({ name: "ChannelDetail", query: { id: row.orderId } });
     },
 
     // 点击发货

+ 6 - 4
src/views/order/deliver/detail.vue

@@ -77,7 +77,7 @@
       </div>
     </div>
     <!-- 物流信息 -->
-    <div class="info" v-if="status.value === 2 || status.value === 4">
+    <div class="info" v-if="status.value === 2 || status.value === 3 || status.value === 4">
       <div class="info-title">物流信息</div>
       <div class="info-item">
         <div
@@ -112,7 +112,7 @@
               <div class="txt">{{ parseTime(item.deliveryTime) || "--" }}</div>
             </div>
             <div class="info-one">
-              <div class="edit-express" @click="editExpress(item)">修改</div>
+              <div class="edit-express" @click="editExpress(item)" v-if="status.value === 2 || status.value === 4">修改</div>
             </div>
           </div>
           <div class="goods">
@@ -166,7 +166,7 @@
           <span>运费:</span>{{ $numberFormat(info.freightAmt) }}元
         </div>
         <div class="info-amt-price">
-          <span>共计金额:</span>{{ $numberFormat(info.orderAmt) }}元
+          <span>共计金额:</span>{{ $numberFormat(info.payAmt) }}元
         </div>
       </div>
     </div>
@@ -190,7 +190,7 @@ import { publicFileGetUrl } from "@/api/common";
 import SendGoods from "./components/SendGoods";
 import ExpressEdit from "./components/ExpressEdit";
 export default {
-  name: "UserDetail",
+  name: "DeliverDetail",
   components: {
     SendGoods,
     ExpressEdit,
@@ -312,9 +312,11 @@ export default {
           display: flex;
         }
         .tit {
+          line-height: 22px;
           width: 100px;
         }
         .txt {
+          line-height: 22px;
           width: 200px;
         }
         .edit-express{

+ 3 - 7
src/views/order/deliver/index.vue

@@ -74,7 +74,7 @@
       </el-form-item>
     </el-form>
     <!-- 导出、刷新 -->
-    <el-row :gutter="10">
+    <el-row :gutter="10" class="mb8">
       <el-col :span="1.5">
         <el-button
           type="infor"
@@ -91,7 +91,6 @@
         @queryTable="getList"
       ></right-toolbar>
     </el-row>
-    <div class="ge"></div>
     <!-- 订单状态 -->
     <el-tabs type="card" v-model="state" @tab-click="handleClick">
       <el-tab-pane label="全部订单" name="no"></el-tab-pane>
@@ -145,7 +144,7 @@
           <div>{{ row.orderNum }}件</div>
         </template>
       </el-table-column>
-      <el-table-column label="付金额(元)" min-width="85">
+      <el-table-column label="付金额(元)" min-width="85">
         <template slot-scope="{ row }">
           <div>{{ $numberFormat(row.payAmt) }}</div>
         </template>
@@ -331,7 +330,7 @@ export default {
 
     // 查看详情
     getDetail(row) {
-      this.$router.push({ name: "UserDetail", query: { id: row.orderId } });
+      this.$router.push({ name: "DeliverDetail", query: { id: row.orderId } });
     },
 
     // 点击发货
@@ -376,7 +375,4 @@ export default {
 ::v-deep .el-tabs--border-card > .el-tabs__content {
   padding: 0;
 }
-.ge {
-  height: 20px;
-}
 </style>

+ 181 - 0
src/views/order/userTicket/detail.vue

@@ -0,0 +1,181 @@
+<template>
+  <div class="app-container">
+    <!-- 订单信息 -->
+    <div class="info">
+      <div class="info-title">订单信息</div>
+      <div class="info-item">
+        <div class="info-item-content">
+          <div class="info-item-content-one">
+            <div class="title">订单编号:</div>
+            <div class="txt">{{ info.orderId }}</div>
+          </div>
+          <div class="info-item-content-one">
+            <div class="title">订单类型:</div>
+            <div class="txt">用户盲票订单</div>
+          </div>
+          <div class="info-item-content-one">
+            <div class="title">下单时间:</div>
+            <div class="txt">{{ parseTime(info.createdTime) }}</div>
+          </div>
+        </div>
+        <div class="info-item-content">
+          <div class="info-item-content-one">
+            <div class="title">订单状态:</div>
+            <div class="txt">{{ info.status && JSON.parse(info.status).desc }}</div>
+          </div>
+          <div class="info-item-content-one">
+            <div class="title">优惠金额:</div>
+            <div class="txt">{{ $numberFormat(info.discountAmt) }}元</div>
+          </div>
+          <div class="info-item-content-one">
+            <div class="title">实付金额:</div>
+            <div class="txt">{{ $numberFormat(info.payAmt) }}元</div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- 买家信息 -->
+    <div class="info">
+      <div class="info-title">买家信息</div>
+      <div class="info-item">
+        <div class="info-item-content">
+          <div class="info-item-content-one">
+            <div class="title">用户昵称:</div>
+            <div class="txt">{{ info.nickName }}</div>
+          </div>
+          <div class="info-item-content-one">
+            <div class="title">手机号:</div>
+            <div class="txt">{{ info.phone }}</div>
+          </div>
+          <div class="info-item-content-one">
+            <div class="title">上级渠道商:</div>
+            <div class="txt">{{ info.channelName }}</div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- 盲票信息 -->
+    <div class="info">
+      <div class="info-title">盲票信息</div>
+      <div class="info-item">
+        <div class="info-item-content">
+          <div class="info-item-content-one">
+            <div class="title">盲票组名称:</div>
+            <div class="txt">{{ info.ticketBoxTitle }}</div>
+          </div>
+          <div class="info-item-content-one">
+            <div class="title">盲票类型:</div>
+            <div class="txt">{{ info.ticketBoxType && JSON.parse(info.ticketBoxType).desc }}</div>
+          </div>
+          <div class="info-item-content-one">
+            <div class="title">佣金系数:</div>
+            <div class="txt">{{ info.saleCommRate }}%</div>
+          </div>
+        </div>
+        <div class="info-item-content">
+          <div class="info-item-content-one">
+            <div class="title">购买数量:</div>
+            <div class="txt">{{ info.ticketNum }}</div>
+          </div>
+          <div class="info-item-content-one">
+            <div class="title">盲票售价:</div>
+            <div class="txt">{{ $numberFormat(info.salePrice) }}元</div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="info" v-if="info.ticketDetailList instanceof Array && info.ticketDetailList.length > 0 && info.ticketDetailList[0] instanceof Object">
+      <table border="1" class="table" bordercolor="#CCC">
+        <tr width="20%">
+          <th>盲票序列号</th>
+          <th>兑奖状态</th>
+          <th>奖级</th>
+          <th>奖品</th>
+        </tr>
+        <tr v-for="(item, index) in info.ticketDetailList" :key="index">
+          <td>{{ item && item.serialNo }}</td>
+          <td>{{ item && item.status && JSON.parse(item.status).desc }}</td>
+          <td>{{ item && item.prizeGrade }}</td>
+          <td>{{ item && item.prizeTitle }}</td>
+        </tr>
+      </table>
+    </div>
+  </div>
+</template>
+<script>
+import { ticketOrderDetail } from "@/api/business/order";
+export default {
+  name: "UserTicketDetail",
+  data() {
+    return {
+      info: {}
+    };
+  },
+  created() {
+    this.getDetail(this.$route.query.id);
+  },
+  methods: {
+    // 订单详情
+    getDetail(id) {
+      ticketOrderDetail(id).then((res) => {
+        if (res.code == 0) {
+          this.info = {
+            ...res.data,
+          };
+        }
+      });
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.info {
+  margin-bottom: 10px;
+  &-title {
+    font-size: 14px;
+    margin-bottom: 10px;
+    font-weight: bold;
+  }
+  &-item {
+    padding-left: 50px;
+    &-content {
+      display: flex;
+
+      &-one {
+        display: flex;
+        margin-bottom: 10px;
+
+        .title {
+          line-height: 22px;
+          width: 100px;
+        }
+
+        .txt {
+          line-height: 22px;
+          width: 200px;
+        }
+      }
+    }
+  }
+}
+.flex {
+  display: flex;
+  align-items: center;
+  .txt {
+    margin-left: 20px;
+  }
+}
+.table {
+  border-collapse: collapse;
+  width: 100%;
+  line-height: 32px;
+  color: #606266;
+  font-size: 14px;
+  th {
+    background-color: #ECECEC;
+  }
+  td {
+    text-align: center;
+  }
+}
+</style>

+ 304 - 0
src/views/order/userTicket/index.vue

@@ -0,0 +1,304 @@
+<template>
+  <div class="app-container">
+    <el-form
+      :model="queryParams"
+      ref="queryForm"
+      :inline="true"
+      v-show="showSearch"
+      label-width="90px"
+    >
+      <el-form-item label="盲票组名称" prop="boxTitle">
+        <el-input
+          v-model="queryParams.boxTitle"
+          placeholder="请输入盲票组名称"
+          clearable
+          size="small"
+          style="width: 240px"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="盲票类型" prop="boxType">
+        <el-select
+          v-model="queryParams.boxType"
+          placeholder="请选择盲票类型"
+          style="width: 100%"
+          size="small"
+          filterable
+          clearable
+          @change="handleQuery"
+        >
+          <el-option label="线上盲票" value="online"></el-option>
+          <el-option label="线下盲票" value="offline"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="用户手机号" prop="phone">
+        <el-input
+          v-model="queryParams.phone"
+          placeholder="请输入用户手机号"
+          clearable
+          size="small"
+          style="width: 240px"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="下单时间">
+        <el-date-picker
+          v-model="tradeTimeArr"
+          type="datetimerange"
+          size="small"
+          value-format="timestamp"
+          range-separator="至"
+          start-placeholder="时间选择"
+          end-placeholder="时间选择"
+          @change="tardeTime"
+        >
+        </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-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="infor"
+          plain
+          icon="el-icon-download"
+          size="small"
+          @click="handleExportDraw"
+          v-hasPermi="['order:deliver:export']"
+          >导出订单</el-button
+        >
+      </el-col>
+      <right-toolbar
+        :showSearch.sync="showSearch"
+        @queryTable="getList"
+      ></right-toolbar>
+    </el-row>
+    <!-- 订单状态 -->
+    <el-tabs type="card" v-model="state" @tab-click="handleClick">
+      <el-tab-pane label="全部订单" name="null"></el-tab-pane>
+      <el-tab-pane label="待付款" name="0"></el-tab-pane>
+      <el-tab-pane label="已完成" name="1"></el-tab-pane>
+      <el-tab-pane label="已取消" name="-1"></el-tab-pane>
+    </el-tabs>
+
+    <!-- 列表 -->
+    <el-table ref="table" v-loading="loading" :data="list">
+      <el-table-column
+        label="订单号"
+        fixed="left"
+        align="center"
+        prop="orderId"
+        min-width="110"
+      />
+      <el-table-column label="下单时间" min-width="100">
+        <template slot-scope="{ row }">
+          <div>{{ parseTime(row.createdTime) }}</div>
+        </template>
+      </el-table-column>
+      <el-table-column label="盲票组名称" prop="title" min-width="95" />
+      <el-table-column label="盲票类型" prop="boxType" min-width="95" />
+      <el-table-column label="盲票售价(元)" prop="parentName" min-width="95">
+        <template slot-scope="{ row }">
+          <div>{{ $numberFormat(row.salePrice) }}</div>
+        </template>
+      </el-table-column>
+      <el-table-column label="数量" prop="ticketNum" min-width="60" />
+      <el-table-column label="订单状态" prop="status" min-width="95" />
+      <el-table-column label="实付金额(元)" min-width="95">
+        <template slot-scope="{ row }">
+          <div>{{ $numberFormat(row.payAmt) }}</div>
+        </template>
+      </el-table-column>
+      <el-table-column label="用户昵称/手机号" min-width="120">
+        <template slot-scope="{ row }">
+          <div>{{ row.nickName }}/{{ row.phone }}</div>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" fixed="right" align="center" width="80">
+        <template slot-scope="{ row }">
+          <div>
+            <el-button
+              v-hasPermi="['order:channel:query']"
+              type="text"
+              @click="$router.push({ name: 'UserTicketDetail', query: { id: row.orderId } })"
+              >查看</el-button
+            >
+          </div>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 分页 -->
+    <pagination
+      v-show="total > 0"
+      :total="total"
+      :page.sync="pageParams.pageNum"
+      :limit.sync="pageParams.pageSize"
+      @pagination="getList"
+    />
+  </div>
+</template>
+<script>
+import { ticketOrderList, ticketOrderExport } from "@/api/business/order";
+export default {
+  name: "UserTicket",
+  data() {
+    return {
+      loading: false,
+      showSearch: true,
+      // 筛选
+      queryParams: {
+        boxTitle: "",
+        boxType: "",
+        startTime: "",
+        endTime: "",
+        phone: "",
+        status: ""
+      },
+      // 分页
+      pageParams: {
+        pageNum: 1,
+        pageSize: 10,
+      },
+      // 总条数
+      total: 0,
+      list: [],
+      // 下单时间
+      tradeTimeArr: [],
+      // 订单列表状态
+      state: "null",
+    };
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    // 订单列表
+    getList() {
+      this.loading = true;
+      ticketOrderList(
+        "pageNum=" +
+          this.pageParams.pageNum +
+          "&pageSize=" +
+          this.pageParams.pageSize +
+          "&",
+        this.queryParams
+      )
+        .then((res) => {
+          this.loading = false;
+          if (res.code == 0) {
+            this.total = res.total;
+            this.list = res.rows;
+            this.list.forEach((item) => {
+              item.boxType = item.boxType && JSON.parse(item.boxType).desc;
+              item.status = item.status && JSON.parse(item.status).desc;
+            });
+          }
+        })
+        .catch(() => {
+          this.loading = false;
+        });
+    },
+
+    // 订单切换
+    handleClick(e) {
+      if (e.name == "null") {
+        this.queryParams.status = "";
+      } else {
+        this.queryParams.status = Number(e.name);
+      }
+      this.getList();
+    },
+
+    //搜索
+    handleQuery() {
+      this.pageParams.pageNum = 1;
+      this.getList();
+    },
+
+    // 重置
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.tradeTimeArr = [];
+      this.pageParams.pageNum = 1;
+      this.queryParams.startTime = "";
+      this.queryParams.endTime = "";
+      this.queryParams.status = "";
+      this.state = "null"
+      this.getList();
+    },
+
+    // 选择下单时间
+    tardeTime(e) {
+      if (e) {
+        this.queryParams.startTime = e[0];
+        this.queryParams.endTime = e[1];
+        this.handleQuery();
+      } else {
+        this.queryParams.startTime = "";
+        this.queryParams.endTime = "";
+        this.handleQuery();
+      }
+    },
+
+    // 查看详情
+    getDetail(row) {
+      this.$router.push({ name: "ChannelDetail", query: { id: row.orderId } });
+    },
+
+    // 点击发货
+    toGoods(row) {
+      this.goodsShow = true;
+      this.goodsInfo = row;
+      this.getBoxList(row);
+    },
+
+    // 关闭发货弹框
+    close() {
+      this.getList();
+    },
+
+    // 导出订单
+    handleExportDraw() {
+      this.$confirm("是否确认导出订单?", "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          this.vloading = this.$loading({
+            lock: true,
+            text: "正在导出订单.....",
+            background: "rgba(0, 0, 0, 0.7)",
+          });
+          return ticketOrderExport(this.queryParams);
+        })
+        .then((response) => {
+          this.vloading.close();
+          this.download(response.msg);
+        })
+        .catch(() => {
+          this.vloading.close();
+        });
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+::v-deep .el-tabs--border-card > .el-tabs__content {
+  padding: 0;
+}
+</style>

+ 89 - 0
src/views/setting/template/components/regionList.vue

@@ -0,0 +1,89 @@
+<template>
+  <el-dialog title="添加地区" :visible.sync="selectShow" width="700px" :close-on-click-modal="false" :destroy-on-close="true">
+    <el-form  ref="shippingTemplateRuleAreaList" :model="shippingTemplateRuleAreaList" label-width="100px">
+      <flexbox class="ygp-form-items" align="flex-start" justify="flex-start">
+        <el-form-item label="省/市" style="width: 80%;">
+
+          <el-cascader :options="listPidProvince" clearable :props="props" v-model="pidData"></el-cascader>
+        </el-form-item>
+
+      </flexbox>
+    </el-form>
+    <span slot="footer">
+      <el-button type="info" plain @click="selectShow = false">取消</el-button>
+      <el-button type="primary" @click="update">确定</el-button>
+    </span>
+  </el-dialog>
+</template>
+<script>
+import { getTemplateList, } from "@/api/setting/template";
+import { publicFileGetUrl } from "@/api/common"
+import { listAreaByPid} from "@/api/admin/area";
+export default {
+  name: "regionList",
+  props: {
+    value: {
+      type: Array,
+      default: []
+    }
+  },
+  data() {
+    return {
+      props:{
+        multiple: true,
+        value:'areaId',
+        label:'areaName',
+        children:'cityList',
+      },
+      IMG_URL: publicFileGetUrl,
+      selectShow: false,
+      listPidProvince:[],//省
+      pidData:[],
+      shippingTemplateRuleAreaList:{
+          city: '',//市
+          cityId: '',//市id
+          province: '',//省
+          provinceId: '',//省id
+        },
+    }
+  },
+  methods: {
+    show() {
+      this.getList(true)
+      this.selectShow = true
+    },
+    getList(reset) {
+      getTemplateList().then(res =>{
+        if(res.code == 0){
+          this.listPidProvince = res.data || []
+        }
+      })
+
+    },
+    getCityList(){
+      getTemplateList().then(res =>{
+        if(res.code == 0){
+          this.listPidProvince = res.data || []
+        }
+      })
+    },
+
+
+
+    update() {
+      // this.$emit('input', this.shippingTemplateRuleAreaList)
+      this.selectShow = false
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.ygp-form-items {
+.el-form-item {
+  padding: 0 15px;
+
+}
+}
+</style>
+

+ 466 - 0
src/views/setting/template/create.vue

@@ -0,0 +1,466 @@
+<template>
+  <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>
+      <!-- 买家付费地区 -->
+      <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 width="30%">付费区域</th>
+                <th width="15%">首件(个)</th>
+                <th width="15%">运费(元)</th>
+                <th width="15%">续件(个)</th>
+                <th width="15%">续费(元)</th>
+                <th width="10%">操作</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%" label-width="0">
+                    <el-cascader @visible-change="listPidDisabled($event,index)" ref="cascaderAdd" :options="listPidProvince" clearable :props="props" v-model="item.shippingTemplateRuleAreaList" style="width: 100%;" ></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='[{ pattern: /^([0-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="[{ pattern: /^([0-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>
+      </el-form>
+
+      <!-- 不发货地区 -->
+      <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 width="30%">不发货区域</th>
+                <th>原因</th>
+                <th width="10%">操作</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: '请选择地区' }]" label-width="0">
+                    <el-cascader @visible-change="listPidDisabled($event,shippingTemplateRuleList.length + index)" :options="listPidProvince" clearable :props="props" v-model="item.shippingTemplateRuleAreaList" style="width: 100%;"></el-cascader>
+                  </el-form-item>
+                </td>
+                <td>
+                  <el-form-item :prop="`shippingTemplateRuleList2.${index}.remark`" :rules="{ required: true, message: '原因不能为空', trigger: 'blur' }" label-width="0">
+                    <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>
+
+      <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>
+        <el-button :loading="addIng" type="primary" @click="update()">保存</el-button>
+      </el-col>
+    </el-row>
+
+  </div>
+</template>
+<script>
+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() {
+    return {
+      listPidProvince:[],//省
+      props:{
+        multiple: true,
+        value:'areaId',
+        label:'areaName',
+        children:'cityList',
+      },
+      id: this.$route.query.id,
+      select:false,
+      addIng: false,
+      readonly: this.$route.name === 'TemplateQuery',
+      shippingTemplateRuleList:[],
+      shippingTemplateRuleList2:[],
+      addData:{
+        title:'',
+        shippingTemplateRuleList:[
+          {
+            createNumber: '',//新增数量
+            createPrice: '',//新增价格
+            defaultNumber: '',//默认数量
+            defaultPrice: '',//默认价格
+            type: '',//类型 1发货 2不发货
+            shippingTemplateRuleAreaList:[
+              {
+                city: '',//市
+                cityId: '',//市id
+                province: '',//省
+                provinceId: '',//省id
+                remark:'不发货备注',
+              },{
+                city: '',//市
+                cityId: '',//市id
+                province: '',//省
+                provinceId: '',//省id
+                remark:'不发货备注',
+              },{
+
+              }
+            ],
+          },
+        ],
+      },
+      //运费相关区域列表
+      listPid:[],
+
+      rules: {
+        title: [{ required: true, message: '请输入模板名称', trigger: 'blur' }],
+      }
+    };
+  },
+  created() {
+    this.getList()
+    if (this.id) {
+      getTemplateDetail(this.id).then(res => {
+        const { id, title, shippingTemplateRuleList } = res.data
+        shippingTemplateRuleList.map(item=>{
+          item.createPrice = accDiv(item.createPrice,100)
+          item.defaultPrice = accDiv(item.defaultPrice,100)
+          let data = []
+          item.shippingTemplateRuleAreaList.map(ressage => {
+            data.push([ressage.provinceId,ressage.cityId])
+          })
+          item.shippingTemplateRuleAreaList = data
+
+          if(item.type == 1){
+            this.shippingTemplateRuleList.push(item)
+          }
+          if(item.type == 2){
+            this.shippingTemplateRuleList2.push(item)
+          }
+        })
+        this.addData = {id, title}
+      })
+    }
+  },
+  methods: {
+
+    //获取省份
+    getList(reset) {
+      getTreeList().then(res => {
+        if (res.code == 0) {
+          this.listPidProvince = res.data || []
+        }
+      })
+    },
+
+    //付费地区
+    getListData(){
+      let data = this.shippingTemplateRuleList[this.shippingTemplateRuleList.length-1] || {}
+      if(data.shippingTemplateRuleAreaList == 1 || data.defaultNumber == '' || data.defaultPrice == ''){
+        this.$message({
+          showClose: true,
+          message: '请输入完整后再添加',
+          type: 'warning'
+        });
+        return
+      }
+      let data2 = {
+        createNumber:'',
+        createPrice:'',
+        defaultNumber:'',
+        defaultPrice:'',
+        shippingTemplateRuleAreaList:1,
+        type:1,
+      }
+      this.shippingTemplateRuleList.push(data2)
+    },
+
+    //不包邮地区
+    getListData2(){
+      let data = this.shippingTemplateRuleList2[this.shippingTemplateRuleList2.length-1] || {}
+      if(data.shippingTemplateRuleAreaList == 1 || data.remark == ''){
+        this.$message({
+          showClose: true,
+          message: '请输入完整后再添加',
+          type: 'warning'
+        });
+        return
+      }
+      let data2 = {
+        remark:'',
+        shippingTemplateRuleAreaList:1,
+        type:2,
+      }
+      this.shippingTemplateRuleList2.push(data2)
+    },
+
+    listPidDisabled(e,index,){
+      let shippingTemplateRuleList = [...this.shippingTemplateRuleList,...this.shippingTemplateRuleList2]
+      if(e){
+        this.listPidProvince.map(item=>{//省
+          item.cityList.map(res=>{//市
+            shippingTemplateRuleList.map(listItem=>{//列表
+              if(listItem.shippingTemplateRuleAreaList != 1){
+                listItem.shippingTemplateRuleAreaList.map(listRes=>{//列表存在的省市
+                  if(res.areaId == listRes[1] ){
+                    // res.disabled = true
+                    this.$set(res,'disabled',true)
+                  }
+                })
+              }
+            })
+          })
+        })
+        this.listPidProvince.map(item=>{//省
+          item.cityList.map(res=>{//市
+            for (let i = 0; i < shippingTemplateRuleList[index].shippingTemplateRuleAreaList.length; i++) {
+              if (res.areaId == shippingTemplateRuleList[index].shippingTemplateRuleAreaList[i][1] ){
+                this.$delete(res,'disabled',)
+              }
+            }
+          })
+        })
+
+      }else {
+        this.listPidProvince.map(item=>{
+          item.cityList.map(res=>{
+            // res.disabled = false
+            this.$set(res,'disabled',false)
+          })
+        })
+      }
+    },
+
+    update() {
+      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;
+        }
+      });
+      if (this.addData.title == ""){
+        this.$message({
+          showClose: true,
+          message: '模板名称不能为空',
+          type: 'warning'
+        });
+        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.shippingTemplateRuleAreaList.length == 0 || item.defaultNumber == '' || item.defaultPrice == ''){
+            this.$message({
+              showClose: true,
+              message: '请输入完整后再保存',
+              type: 'warning'
+            });
+            return
+          }
+        }
+      }
+      //判断不发货区域
+      if(this.shippingTemplateRuleList2){
+        for (let i = 0; i < this.shippingTemplateRuleList2.length; i++) {
+          let item = this.shippingTemplateRuleList2[i]
+          if(item.shippingTemplateRuleAreaList == 1 || item.shippingTemplateRuleAreaList.length == 0 || item.remark == ''){
+            this.$message({
+              showClose: true,
+              message: '请输入完整后再保存',
+              type: 'warning'
+            });
+            return
+          }
+        }
+      }
+
+      let shippingTemplateRuleList = [...this.shippingTemplateRuleList,...this.shippingTemplateRuleList2]
+      shippingTemplateRuleList.map(item =>{
+          let ressage = []
+          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
+          arr.push(item)
+      })
+
+      for (let i = 0; i < arr.length; i++) {
+        if(arr[i].type == 1){
+          arr[i].createPrice = accMul(arr[i].createPrice,100)
+          arr[i].defaultPrice = accMul(arr[i].defaultPrice,100)
+        }
+      }
+      this.addData.shippingTemplateRuleList = arr
+
+      this.submitForm()
+    },
+
+    submitForm(){
+      if (this.id){
+        setTemplateDetail(this.addData).then(res=>{
+          if (res.code === 0) {
+            this.$message({
+              message: '修改成功!',
+              type: 'success'
+            })
+          }
+          this.$store.dispatch('tagsView/delView', this.$route)
+          this.$router.go(-1)
+        })
+
+      }else {
+        addTemplateList(this.addData).then(res=>{
+          if (res.code === 0) {
+            this.$message({
+              message: '添加成功!',
+              type: 'success'
+            })
+            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 lang="scss" scoped>
+.spec-table {
+  border-collapse: collapse;
+  //width: 100%;
+  line-height: 32px;
+  border-color: #DCDFE6;
+  color: #606266;
+  font-size: 14px;
+  th {
+    background-color: #ECECEC;
+  }
+  td {
+    text-align: center;
+    padding: 19px 15px;
+  }
+  .required {
+    position: relative;
+    span {
+      position: relative;
+      top: -6px;
+      left: 2px;
+      font-size: 10px;
+      color: red;
+    }
+  }
+
+}
+</style>

+ 79 - 0
src/views/setting/template/index.vue

@@ -0,0 +1,79 @@
+<template>
+  <div class="app-container coupon-list">
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="10">
+        <el-button
+          type="primary"
+          icon="el-icon-plus"
+          size="mini"
+          @click="$router.push({ name: 'TemplateCreate' })"
+          v-hasPermi="['setting:template:add']"
+        >添加运费模板</el-button>
+      </el-col>
+    </el-row>
+    <el-table v-loading="loading" :data="tableData">
+      <el-table-column label="模板编号" prop="id" width="280" />
+      <el-table-column label="模板名称" prop="title" />
+      <el-table-column fixed="right" align="right" label="操作" width="150">
+        <template slot-scope="{row}">
+          <el-button v-hasPermi="['setting:template:edit']" type="text" @click="$router.push({ name: 'TemplateEdit', query: { id: row.id } })">编辑</el-button>
+          <el-button v-if="1 === 1" v-hasPermi="['setting:template:remove']" class="del" type="text" @click="del(row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+<script>
+import { getTemplateList, delTemplate } from '@/api/business/template'
+export default {
+  data() {
+    return {
+      loading: false,
+      queryParams: {},
+      tableData: [],
+      total: 0
+    };
+  },
+  created() {
+    this.getList(true)
+  },
+  methods: {
+    getList(reset) {
+      if (this.loading) {
+        return
+      }
+      this.loading = true
+      if (reset) {
+        this.queryParams = { pageNum: 1, pageSize: 20 }
+      }
+      getTemplateList('pageNum='+this.queryParams.pageNum + '&pageSize='+this.queryParams.pageSize+'&', this.queryParams).then(res => {
+        this.loading = false
+        if (res.code === 0) {
+          this.tableData = res.rows
+          // this.total = res.total
+        }
+      }).catch(() => {
+        this.loading = false
+      })
+    },
+
+    del(item) {
+      this.$confirm(`确认删除券 “${item.title}” 吗?`, '删除券', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        delTemplate(item.id).then(res => {
+          if (res.code === 0) {
+            this.$message.success('操作已完成!')
+            this.getList()
+          }
+        })
+      })
+    },
+
+  },
+};
+</script>
+<style>
+</style>

+ 1 - 0
vue.config.js

@@ -35,6 +35,7 @@ module.exports = {
       [process.env.VUE_APP_BASE_API]: {
       //target: `http://113.31.163.91:8090`,
       // target: `http://localhost:8080`,
+      // target: `https://mp-api.51jiazhu.com`,
       target: `https://test-mp.quanshu123.com`,
         changeOrigin: true,
         pathRewrite: {