Переглянути джерело

Merge branch 'develop_hb01' of jianguan-web/jq-repairFusion-html into pre-release

李磊 2 роки тому
батько
коміт
03359ae6bc

+ 1 - 1
public/version.json

@@ -1,3 +1,3 @@
 {
-    "version": "1.0.0"
+    "version": "1.0.1"
 }

+ 83 - 0
src/api/redPacket.js

@@ -0,0 +1,83 @@
+import { axios } from '@/utils/request'
+
+// 创建
+export const rewardRuleCreate = params => {
+  return axios({
+    url: `/rewardRule/create`,
+    data: params,
+    method: 'post'
+  })
+}
+// 删除
+export const rewardRuleDelete = params => {
+  return axios({
+    url: `/rewardRule/delete`,
+    data: params,
+    method: 'post'
+  })
+}
+// 终止
+export const rewardRuleClose = params => {
+  return axios({
+    url: `/rewardRule/closeRule`,
+    data: params,
+    method: 'post'
+  })
+}
+// 详情列表
+export const rewardRuleDetail = params => {
+  return axios({
+    url: `/rewardRule/findBySn/${params.rewardRuleSn}`,
+    data: params,
+    method: 'get'
+  })
+}
+// 修改
+export const rewardRuleModify = params => {
+  return axios({
+    url: `/rewardRule/modify`,
+    data: params,
+    method: 'post'
+  })
+}
+// 分页列表
+export const rewardRuleList = params => {
+  const url = `/rewardRule/queryPage/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'POST'
+  })
+}
+// 发布
+export const rewardRuleRelease = params => {
+  return axios({
+    url: `/rewardRule/releaseRule`,
+    data: params,
+    method: 'post'
+  })
+}
+// 分页列表
+export const rewardRuleShelfQueryPage = params => {
+  const url = `/rewardRuleStore/shelf/queryPage/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'POST'
+  })
+}
+// 货架加入列表
+export const shelfJoinQueryPage = params => {
+  const url = `/rewardRuleStore/shelf/joinQueryPage/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'POST'
+  })
+}

+ 78 - 0
src/api/rewardOrder.js

@@ -0,0 +1,78 @@
+import { axios } from '@/utils/request'
+
+// 删除
+export const rewardOrderCancel = params => {
+  return axios({
+    url: `/rewardOrder/cancelReward`,
+    data: params,
+    method: 'post'
+  })
+}
+// 批量删除
+export const cancelRewardBatch = params => {
+  return axios({
+    url: `/rewardOrder/cancelRewardBatch`,
+    data: params,
+    method: 'post'
+  })
+}
+// 导出
+export const exportRewardOrder = params => {
+  return axios({
+    url: `/rewardOrder/product/export`,
+    data: params,
+    method: 'post',
+    responseType: 'blob'
+  })
+}
+// 详情
+export const rewardOrderDetail = params => {
+  return axios({
+    url: `/rewardOrder/findById/${params.id}`,
+    data: params,
+    method: 'get'
+  })
+}
+// 标记已发
+export const rewardOrderGiveReward = params => {
+  return axios({
+    url: `/rewardOrder/giveReward`,
+    data: params,
+    method: 'post'
+  })
+}
+// 批量标记已发
+export const rewardOrderGiveRewardBatch = params => {
+  return axios({
+    url: `/rewardOrder/giveRewardBatch`,
+    data: params,
+    method: 'post'
+  })
+}
+// 订单产品列表
+export const rewardOrderQueryList = params => {
+  return axios({
+    url: `/rewardOrder/product/queryList`,
+    data: params,
+    method: 'post'
+  })
+}
+// 分页列表
+export const rewardOrderQueryPage = params => {
+  const url = `/rewardOrder/queryPage/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'POST'
+  })
+}
+// 汇总
+export const rewardOrderQueryCount = params => {
+  return axios({
+    url: `/rewardOrder/queryCount`,
+    data: params,
+    method: 'post'
+  })
+}

+ 7 - 1
src/components/Select/index.js

@@ -29,6 +29,12 @@ export default {
     isEnable: { // 是否只获取已启用的数据
       type: Boolean,
       default: false
+    },
+    notIn: {
+      type: Array,
+      default: function(){
+        return []
+      }
     }
   }),
   created () {
@@ -41,7 +47,7 @@ export default {
       isEnable: _this.isEnable ? 1 : undefined
     }).then(res => {
       if (res.status == 200) {
-        _this.dataList = res.data.list
+        _this.dataList = res.data.list.filter(item => _this.notIn.indexOf(item.code)<0)
       }
     })
   },

+ 75 - 19
src/components/Table/index.js

@@ -9,7 +9,8 @@ export default {
       selectedRowKeys: [],
       localLoading: false,
       localDataSource: [],
-      localPagination: Object.assign({}, this.pagination)
+      localPagination: Object.assign({}, this.pagination),
+      isSucceed: true //  是否请求成功
     }
   },
   props: Object.assign({}, T.props, {
@@ -17,6 +18,10 @@ export default {
       type: [String, Function],
       default: 'key'
     },
+    rowKeyName: { // 多选时,唯一标识键名
+      type: String,
+      default: 'id'
+    },
     rowClassName: {
       type: [String, Function],
       default: ''
@@ -55,11 +60,6 @@ export default {
       type: Object,
       default: null
     },
-    /** @Deprecated */
-    showAlertInfo: {
-      type: Boolean,
-      default: false
-    },
     showPagination: {
       type: String | Boolean,
       default: 'auto'
@@ -123,7 +123,7 @@ export default {
     this.localPagination = ['auto', true].includes(this.showPagination) && Object.assign({}, this.localPagination, {
       current: localPageNum,
       pageSize: this.pageSize,
-      pageSizeOptions:['5','10', '20', '30', '40'],
+      pageSizeOptions: ['5', '10', '20', '30', '40'],
       showTotal: total => `共 ${total} 条记录`,
       showSizeChanger: this.showSizeChanger
     }) || false
@@ -147,7 +147,10 @@ export default {
     },
     // 重置表格为空
     clearTable () {
+      this.localLoading = false
       this.localDataSource = []
+      this.needTotalList = []
+      this.clearSelected()
       this.localPagination = Object.assign({}, {
         current: 1, pageSize: this.pageSize, total: 0
       })
@@ -183,8 +186,13 @@ export default {
       // eslint-disable-next-line
       if ((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') {
         result.then(r => {
-          const list = r.list || r.data || r
+          // const list = r.list || r.data || r
+          let list = []
+          if (r) {
+            list = r.list || r.data || r
+          }
           // console.log(r,'rrrrrrrrrr')
+          this.isSucceed = !!r
           this.localPagination = this.showPagination && Object.assign({}, this.localPagination, {
             current: r.pageNo, // 返回结果中的当前分页数
             total: Number(r.count), // 返回结果中的总记录数
@@ -210,6 +218,8 @@ export default {
           }
           this.localDataSource = list // 返回结果中的数组数据
           this.localLoading = false
+        }).catch(err => {
+          this.clearTable()
         })
       }
     },
@@ -231,26 +241,66 @@ export default {
      * @param selectedRows
      */
     updateSelect (selectedRowKeys, selectedRows) {
-      this.selectedRows = selectedRows
-      this.selectedRowKeys = selectedRowKeys
       const list = this.needTotalList
       this.needTotalList = list.map(item => {
         return {
           ...item,
-          total: selectedRows.reduce((sum, val) => {
+          total: this.selectedRows.reduce((sum, val) => {
             const total = sum + parseInt(get(val, item.dataIndex))
             return isNaN(total) ? 0 : total
           }, 0)
         }
       })
+      const obj = {
+        selectedRowKeys: this.selectedRowKeys,
+        selectedRows: this.selectedRows
+      }
+      this.$emit('rowSelection', obj)
+    },
+    onSelectChange (record, selected, selectedRows, nativeEvent) {
+      if (selected) { //  选择
+        this.selectedRows.push(record)
+      } else { //  取消
+        const selectedRowsArr = []
+        this.selectedRows.map(item => {
+          if (this.selectedRowKeys.indexOf(item[this.rowKeyName]) != -1) {
+            selectedRowsArr.push(item)
+          }
+        })
+        this.selectedRows = selectedRowsArr
+      }
+      this.updateSelect()
+    },
+    // 本页全选/取消全选
+    onSelectAllChange (selected, selectedRows, changeRows) {
+      const _this = this
+      if (selected) { //  选择
+        this.selectedRows = [...this.selectedRows, ...changeRows]
+      } else { //  取消
+        const selectedRowsArr = []
+        this.selectedRows.map((item, index) => {
+          if(!changeRows.find(subItem => subItem[this.rowKeyName] == item[this.rowKeyName])){
+            selectedRowsArr.push(item)
+          }
+        })
+        this.selectedRows = selectedRowsArr
+      }
+      this.updateSelect()
+    },
+    // 设置 table 已选中项
+    setTableSelected (selectedRowKeys, selectedRows) {
+      this.selectedRows = selectedRows
+      this.selectedRowKeys = selectedRowKeys
+      this.updateSelect()
     },
     /**
      * 清空 table 已选中项
      */
     clearSelected () {
       if (this.rowSelection) {
-        this.rowSelection.onChange([], [])
-        this.updateSelect([], [])
+        this.selectedRows = []
+        this.selectedRowKeys = []
+        this.updateSelect()
       }
     },
     /**
@@ -299,7 +349,6 @@ export default {
     const props = {}
     const localKeys = Object.keys(this.$data)
     const showAlert = (typeof this.alert === 'object' && this.alert !== null && this.alert.show) && typeof this.rowSelection.selectedRowKeys !== 'undefined' || this.alert
-
     Object.keys(T.props).forEach(k => {
       const localKey = `local${k.substring(0, 1).toUpperCase()}${k.substring(1)}`
       if (localKeys.includes(localKey)) {
@@ -307,16 +356,19 @@ export default {
         return props[k]
       }
       if (k === 'rowSelection') {
-        if (showAlert && this.rowSelection) {
+        if (this.rowSelection) {
           // 如果需要使用alert,则重新绑定 rowSelection 事件
-          // console.log('this.rowSelection', this.rowSelection)
           props[k] = {
             ...this.rowSelection,
-            selectedRows: this.selectedRows,
             selectedRowKeys: this.selectedRowKeys,
             onChange: (selectedRowKeys, selectedRows) => {
-              this.updateSelect(selectedRowKeys, selectedRows)
-              typeof this[k].onChange !== 'undefined' && this[k].onChange(selectedRowKeys, selectedRows)
+              this.selectedRowKeys = selectedRowKeys
+            },
+            onSelect: (record, selected, selectedRows, nativeEvent) => {
+              this.onSelectChange(record, selected, selectedRows, nativeEvent)
+            },
+            onSelectAll: (selected, selectedRows, changeRows) => {
+              this.onSelectAllChange(selected, selectedRows, changeRows)
             }
           }
           return props[k]
@@ -329,6 +381,10 @@ export default {
       this[k] && (props[k] = this[k])
       return props[k]
     })
+    if (!this.isSucceed) { // 请求失败
+      props['locale'] = { emptyText: '网络异常,请点击按钮刷新' }
+    }
+    // isSucceed
     const table = (
       <a-table {...{ props, scopedSlots: { ...this.$scopedSlots } }} onChange={this.loadData}>
         { Object.keys(this.$slots).map(name => (<template slot={name}>{this.$slots[name]}</template>)) }

+ 1 - 1
src/components/UploadFile/index.vue

@@ -20,7 +20,7 @@
         <a-button> <a-icon type="upload" /> {{ upText }} </a-button>
       </div>
     </a-upload>
-    <a-modal :visible="previewVisible" :footer="null" centered :maskClosable="false" @cancel="handleCancel">
+    <a-modal :visible="previewVisible" :footer="null" centered :maskClosable="true" @cancel="handleCancel">
       <video v-if="fileType=='video/mp4'" controls="controls" style="width: 100%" :src="previewImage" />
       <img v-else alt="example" style="width: 100%" :src="previewImage" />
     </a-modal>

+ 63 - 2
src/config/router.config.js

@@ -94,7 +94,7 @@ export const asyncRouterMap = [
                 }
               },
               {
-                path: 'jsSet/:id',
+                path: 'jsSet/:shelfSn',
                 name: 'settlementSet',
                 component: () => import('@/views/numsGoodsShelves/goodsShelvesAdministration/settlementSet.vue'),
                 meta: {
@@ -125,7 +125,68 @@ export const asyncRouterMap = [
               icon: 'user',
               permission: 'M_partsDealerManagement '
             }
-          }
+          },
+          {
+            path: '/numsGoodsShelves/redPacket',
+            redirect: '/numsGoodsShelves/redPacket/list',
+            name: 'redPacket',
+            component: BlankLayout,
+            meta: {
+              title: '红包活动设置',
+              icon: 'monitor',
+              // permission: 'M_redPacket'
+            },
+            hideChildrenInMenu: true,
+            children: [
+              {
+                path: 'list',
+                name: 'redPacketList',
+                component: () => import('@/views/numsGoodsShelves/redPacket/list.vue'),
+                meta: {
+                  title: '红包活动设置',
+                  icon: 'monitor',
+                  hidden: true
+                }
+              },
+              {
+                path: 'edit/:sn',
+                name: 'redPacketEdit',
+                component: () => import('@/views/numsGoodsShelves/redPacket/edit.vue'),
+                meta: {
+                  title: '编辑红包活动',
+                  hidden: true,
+                }
+              },
+              {
+                path: 'add',
+                name: 'redPacketAdd',
+                component: () => import('@/views/numsGoodsShelves/redPacket/edit.vue'),
+                meta: {
+                  title: '新增红包活动',
+                  hidden: true,
+                }
+              },
+              {
+                path: 'detail/:sn',
+                name: 'redPacketDetail',
+                component: () => import('@/views/numsGoodsShelves/redPacket/detail.vue'),
+                meta: {
+                  title: '红包活动详情',
+                  hidden: true,
+                }
+              },
+            ]
+          },
+          {
+            path: '/numsGoodsShelves/redPacketStatistics',
+            name: 'redPacketStatistics',
+            component: () => import('@/views/numsGoodsShelves/redPacket/redPacketStatistics.vue'),
+            meta: {
+              title: '红包活动统计',
+              icon: 'user',
+              // permission: 'M_redPacketStatistics'
+            }
+          },
         ]
       },
       // 系统设置

+ 2 - 2
src/layouts/RouteView.vue

@@ -26,8 +26,8 @@ export default {
     // if (!getters.multiTab && !meta.keepAlive) {
     //   return notKeep
     // }
-    return this.keepAlive || getters.multiTab || meta.keepAlive ? inKeep : notKeep
-    // return meta.keepAlive ? inKeep : notKeep
+    // return this.keepAlive || getters.multiTab || meta.keepAlive ? inKeep : notKeep
+    return meta.keepAlive ? inKeep : notKeep
   }
 }
 </script>

+ 0 - 1
src/views/numsGoodsShelves/goodsShelvesAdministration/list.vue

@@ -93,7 +93,6 @@ export default {
       queryParam: {
         dealerSn: undefined, // 配件经销商sn
         shelfName: '', // 货架名称
-        state: '', // 货架状态
         settleType: '', // 结算状态
         storeSn: undefined, // 汽车修理厂
         state: undefined// 货架状态

+ 198 - 0
src/views/numsGoodsShelves/redPacket/detail.vue

@@ -0,0 +1,198 @@
+<template>
+  <div class="redPacketSetDetail-page">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-page-header :ghost="false" :backIcon="false" class="redPacketSetDetail-baseInfo">
+        <template slot="subTitle">
+          <a href="javascript:;" @click="handleBack" id="redPacketSetDetail-handleBack">
+            <a-icon type="left"></a-icon> 返回列表
+          </a>
+          <span style="margin: 0 15px;color: #666;font-weight: bold;">红包活动详情</span>
+        </template>
+      </a-page-header>
+      <a-card :bordered="false" size="small" class="pages-wrap">
+        <div class="redPacketSetDetail-baseInfo">
+          <a-form-model
+            id="redPacketSetDetail-form"
+            ref="ruleForm"
+            :model="form"
+            :rules="rules"
+            :label-col="formItemLayout.labelCol"
+            :wrapper-col="formItemLayout.wrapperCol"
+          >
+            <a-row :gutter="24">
+              <a-row>
+                <a-col :span="12">
+                  <a-form-model-item label="活动名称">
+                    {{ form.ruleName }}
+                  </a-form-model-item>
+                </a-col>
+                <!-- <a-col :span="12">
+                  <a-form-model-item label="活动截止时间" prop="activeTime" help="活动成发布后即刻开始,无需设置开始时间">
+                    <a-input id="redPacket-time" style="width: 70%;margin-right:10px;" allowClear v-model.trim="form.activeTime" placeholder="请输入活动截止时间(精确到小时)"/>
+                    <a-checkbox>永久</a-checkbox>
+                  </a-form-model-item>
+                </a-col> -->
+              </a-row>
+              <a-row>
+                <a-col :span="24">
+                  <a-form-model-item label="参与货架" prop="joinNum" :label-col="{span: 3}" :wrapper-col="{span: 20}">
+                    <span v-if="form.joinNum">已选{{ form.joinNum }}货架</span>
+                    <a-button type="link" class="button-info" @click="openModal=true">点击查看</a-button>
+                  </a-form-model-item>
+                </a-col>
+              </a-row>
+              <!-- <a-row>
+                <a-col :span="24">
+                  <a-form-model-item label="活动范围" prop="activeOrg" :label-col="{span: 3}" :wrapper-col="{span: 20}">
+                    <div style="color:#999">修配易码通用户下单后可获得红包奖励</div>
+                    <a-checkbox-group
+                      v-model="form.activeOrg"
+                      name="checkboxgroup"
+                      :options="plainOptions"
+                    />
+                  </a-form-model-item>
+                </a-col>
+              </a-row> -->
+              <a-row>
+                <a-col :span="24">
+                  <a-form-model-item label="客服微信" prop="serviceQrcode" :label-col="{span: 3}" :wrapper-col="{span: 20}">
+                    <img :src="form.serviceQrcode" @click="viewImg()" width="100px"></img>
+                  </a-form-model-item>
+                </a-col>
+              </a-row>
+              <a-row>
+                <a-col :span="24">
+                  <a-form-model-item label="备注" :label-col="{span: 3}" :wrapper-col="{span: 20}">
+                    {{ form.remarks||'--' }}
+                  </a-form-model-item>
+                </a-col>
+              </a-row>
+            </a-row>
+            <a-form-model-item :label-col="{span: 0}" :wrapper-col="{span: 24}" style="text-align: center;">
+              <a-button type="default" @click="handleBack" style="margin-right:20px;" id="redPacketSetDetail-cansel">返回列表</a-button>
+            </a-form-model-item>
+          </a-form-model>
+        </div>
+      </a-card>
+      <!-- 选择货架弹窗 -->
+      <shelfDetail ref="shelfDetail" :itemData="form" :visible="openModal" @close="openModal=false"></shelfDetail>
+    </a-spin>
+  </div>
+</template>
+
+<script>
+import { VSelect, Upload } from '@/components'
+import { rewardRuleDetail } from '@/api/redPacket.js'
+import shelfDetail from './shelfDetail.vue'
+export default {
+  components: { shelfDetail, VSelect, Upload },
+  data () {
+    return {
+      spinning: false,
+      openModal: false, // 货位模板弹窗初始状态
+      formItemLayout: {
+        labelCol: { span: 6 },
+        wrapperCol: { span: 14 }
+      },
+      plainOptions: [{ label: '货架订单', value: '1' }],
+      pageInfo: null,
+      form: {
+        ruleName: '', // 活动名称
+        joinNum: '', // 参与数
+        ruleStoreList: [], // 参与门店
+        serviceQrcode: '', // 客服二维码图片
+        remarks: ''
+      },
+      rules: {}
+    }
+  },
+  computed: {
+    isEdit () {
+      return this.$route.params.sn
+    }
+  },
+  methods: {
+    handleBack () {
+      this.form = {
+        ruleName: '', // 活动名称
+        joinNum: '', // 参与数
+        ruleStoreList: [], // 参与门店
+        serviceQrcode: '', // 客服二维码图片
+        remarks: ''
+      }
+      this.$refs.ruleForm.resetFields()
+      this.$router.push({ name: 'redPacketList' })
+    },
+    viewImg () {
+      const h = this.$createElement
+      this.$info({
+        title: '图片预览',
+        centered: true,
+        width: '600px',
+        okText: '关闭',
+        content: h('div', {}, [
+          h('img', { domProps: {
+            src: this.form.serviceQrcode,
+            style: 'width:100%;'
+          } })
+        ])
+      })
+    },
+    // 活动详情
+    getDetail () {
+      this.spinning = true
+      rewardRuleDetail({
+        rewardRuleSn: this.$route.params.sn
+      }).then(res => {
+        if (res.status == 200) {
+          const storeList = []
+          res.data.rewardRuleStoreList.map(item => {
+            storeList.push({
+              shelfSn: item.shelfSn
+            })
+          })
+          this.form = {
+            ruleName: res.data.ruleName, // 活动名称
+            joinNum: res.data.joinNum, // 参与数
+            ruleStoreList: storeList, // 参与门店
+            serviceQrcode: res.data.serviceQrcode, // 客服二维码图片
+            remarks: res.data.remarks,
+            rewardRuleSn: res.data.rewardRuleSn
+          }
+        }
+        this.spinning = false
+      })
+    }
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {
+      // 编辑
+      if (vm.$route.params.sn) {
+        vm.getDetail()
+      }
+    })
+  }
+}
+</script>
+
+<style lang="less">
+  .redPacketSetDetail-page{
+    position: relative;
+    height: 100%;
+    padding-bottom: 51px;
+    box-sizing: border-box;
+    .redPacketSetDetail-baseInfo{
+      margin-bottom: 10px;
+      .ant-input-number-handler-wrap{
+        display: none;
+      }
+    }
+    .bzj-collapse{
+      margin-top: 10px;
+      .ant-collapse-content-box{
+        padding: 10px !important;
+      }
+    }
+
+  }
+</style>

+ 243 - 0
src/views/numsGoodsShelves/redPacket/edit.vue

@@ -0,0 +1,243 @@
+<template>
+  <div class="redPacketSetEidit-page">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-page-header :ghost="false" :backIcon="false" class="redPacketSetEidit-baseInfo">
+        <template slot="subTitle">
+          <a href="javascript:;" @click="handleBack" id="redPacketSetEidit-handleBack">
+            <a-icon type="left"></a-icon> 返回列表
+          </a>
+          <span style="margin: 0 15px;color: #666;font-weight: bold;">新增红包活动</span>
+        </template>
+      </a-page-header>
+      <a-card :bordered="false" size="small" class="pages-wrap">
+        <div class="redPacketSetEidit-baseInfo">
+          <a-form-model
+            id="redPacketSetEidit-form"
+            ref="ruleForm"
+            :model="form"
+            :rules="rules"
+            :label-col="formItemLayout.labelCol"
+            :wrapper-col="formItemLayout.wrapperCol"
+          >
+            <a-row :gutter="24">
+              <a-row>
+                <a-col :span="12">
+                  <a-form-model-item label="活动名称" prop="ruleName">
+                    <a-input id="redPacket-ruleName" allowClear :maxLength="30" v-model.trim="form.ruleName" placeholder="请输入活动名称(最多30个字符)"/>
+                  </a-form-model-item>
+                </a-col>
+                <!-- <a-col :span="12">
+                  <a-form-model-item label="活动截止时间" prop="activeTime" help="活动成发布后即刻开始,无需设置开始时间">
+                    <a-input id="redPacket-time" style="width: 70%;margin-right:10px;" allowClear v-model.trim="form.activeTime" placeholder="请输入活动截止时间(精确到小时)"/>
+                    <a-checkbox>永久</a-checkbox>
+                  </a-form-model-item>
+                </a-col> -->
+              </a-row>
+              <a-row>
+                <a-col :span="24">
+                  <a-form-model-item label="参与货架" prop="joinNum" :label-col="{span: 3}" :wrapper-col="{span: 20}">
+                    <span v-if="form.joinNum">已选{{ form.joinNum }}货架</span>
+                    <a-button type="link" class="button-info" @click="openModal=true">点击选择</a-button>
+                  </a-form-model-item>
+                </a-col>
+              </a-row>
+              <!-- <a-row>
+                <a-col :span="24">
+                  <a-form-model-item label="活动范围" prop="activeOrg" :label-col="{span: 3}" :wrapper-col="{span: 20}">
+                    <div style="color:#999">修配易码通用户下单后可获得红包奖励</div>
+                    <a-checkbox-group
+                      v-model="form.activeOrg"
+                      name="checkboxgroup"
+                      :options="plainOptions"
+                    />
+                  </a-form-model-item>
+                </a-col>
+              </a-row> -->
+              <a-row>
+                <a-col :span="24">
+                  <a-form-model-item label="客服微信" prop="serviceQrcode" :label-col="{span: 3}" :wrapper-col="{span: 20}">
+                    <Upload
+                      class="upload"
+                      v-model="form.serviceQrcode"
+                      ref="serviceQrcode"
+                      :fileSize="10"
+                      :maxNums="1"
+                      @remove="removeImage"
+                      @change="changeImage"
+                      listType="picture-card"></Upload>
+                    <div class="upload-desc" style="margin-left: 100px;color:#999">说明:单张大小小于10Mb,最多1张。</div>
+                  </a-form-model-item>
+                </a-col>
+              </a-row>
+              <a-row>
+                <a-col :span="24">
+                  <a-form-model-item label="备注" :label-col="{span: 3}" :wrapper-col="{span: 20}">
+                    <a-textarea :rows="4" v-model="form.remarks" :maxLength="150" placeholder="请输入备注(最多150字符)"></a-textarea>
+                  </a-form-model-item>
+                </a-col>
+              </a-row>
+            </a-row>
+            <a-form-model-item :label-col="{span: 0}" :wrapper-col="{span: 24}" style="text-align: center;">
+              <a-button type="default" @click="handleBack" style="margin-right:20px;" id="redPacketSetEidit-cansel">取消</a-button>
+              <a-button type="primary" @click="handleSubmit" id="redPacketSetEidit-handleSubmit">保存</a-button>
+            </a-form-model-item>
+          </a-form-model>
+        </div>
+      </a-card>
+      <!-- 选择货架弹窗 -->
+      <shelfModal ref="shelfModal" :checkedList="form.ruleStoreList" :visible="openModal" @close="openModal=false" @ok="chooseShelf"></shelfModal>
+    </a-spin>
+  </div>
+</template>
+
+<script>
+import { VSelect, Upload } from '@/components'
+import { rewardRuleDetail, rewardRuleCreate, rewardRuleModify } from '@/api/redPacket.js'
+import shelfModal from './shelfModal.vue'
+export default {
+  components: { shelfModal, VSelect, Upload },
+  data () {
+    return {
+      spinning: false,
+      openModal: false, // 货位模板弹窗初始状态
+      formItemLayout: {
+        labelCol: { span: 6 },
+        wrapperCol: { span: 14 }
+      },
+      plainOptions: [{ label: '货架订单', value: '1' }],
+      pageInfo: null,
+      form: {
+        ruleName: '', // 活动名称
+        joinNum: '', // 参与数
+        ruleStoreList: [], // 参与门店
+        serviceQrcode: '', // 客服二维码图片
+        remarks: ''
+      },
+      rules: {
+        ruleName: [ { required: true, message: '请输入活动名称', trigger: 'change' } ],
+        joinNum: [ { required: true, message: '请选择参与货架', trigger: 'change' } ],
+        serviceQrcode: [ { required: true, message: '请上传客服微信二维码图片', trigger: 'change' } ]
+      }
+    }
+  },
+  computed: {
+    isEdit () {
+      return this.$route.params.sn
+    }
+  },
+  methods: {
+    retForm () {
+      this.form = {
+        ruleName: '', // 活动名称
+        joinNum: '', // 参与数
+        ruleStoreList: [], // 参与门店
+        serviceQrcode: '', // 客服二维码图片
+        remarks: ''
+      }
+      this.$refs.ruleForm.resetFields()
+      this.removeImage()
+    },
+    handleBack () {
+      this.retForm()
+      this.$router.push({ name: 'redPacketList' })
+    },
+    //  图片上传
+    changeImage (file) {
+      this.form.serviceQrcode = file
+    },
+    removeImage () {
+      this.form.serviceQrcode = ''
+      this.$refs.serviceQrcode.setFileList('')
+    },
+    chooseShelf (data) {
+      this.form.ruleStoreList = data
+      this.openModal = false
+      this.form.joinNum = data.length
+      this.$refs.ruleForm.validateField('joinNum')
+    },
+    // 活动详情
+    getDetail () {
+      this.spinning = true
+      rewardRuleDetail({
+        rewardRuleSn: this.$route.params.sn
+      }).then(res => {
+        if (res.status == 200) {
+          const storeList = []
+          res.data.rewardRuleStoreList.map(item => {
+            storeList.push({
+              shelfSn: item.shelfSn
+            })
+          })
+          this.form = {
+            ruleName: res.data.ruleName, // 活动名称
+            joinNum: res.data.joinNum, // 参与数
+            ruleStoreList: storeList, // 参与门店
+            serviceQrcode: res.data.serviceQrcode, // 客服二维码图片
+            remarks: res.data.remarks,
+            rewardRuleSn: res.data.rewardRuleSn
+          }
+          this.$refs.serviceQrcode.setFileList(res.data.serviceQrcode)
+        }
+        this.spinning = false
+      })
+    },
+    // 保存
+    handleSubmit () {
+      const _this = this
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          const params = Object.assign({}, _this.form)
+          const fun = !this.isEdit ? rewardRuleCreate : rewardRuleModify
+          _this.spinning = true
+          fun(params).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              setTimeout(function () {
+                _this.isshow = false
+                _this.spinning = false
+                _this.handleBack()
+              }, 300)
+            } else {
+              _this.spinning = false
+            }
+          })
+        } else {
+          return false
+        }
+      })
+    }
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {
+      // 编辑
+      if (vm.$route.params.sn) {
+        vm.getDetail()
+      } else {
+        vm.retForm()
+      }
+    })
+  }
+}
+</script>
+
+<style lang="less">
+  .redPacketSetEidit-page{
+    position: relative;
+    height: 100%;
+    padding-bottom: 51px;
+    box-sizing: border-box;
+    .redPacketSetEidit-baseInfo{
+      margin-bottom: 10px;
+      .ant-input-number-handler-wrap{
+        display: none;
+      }
+    }
+    .bzj-collapse{
+      margin-top: 10px;
+      .ant-collapse-content-box{
+        padding: 10px !important;
+      }
+    }
+
+  }
+</style>

+ 227 - 0
src/views/numsGoodsShelves/redPacket/list.vue

@@ -0,0 +1,227 @@
+<template>
+  <a-card size="small" :bordered="false">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <div ref="tableSearch" class="table-page-search-wrapper">
+        <a-form layout="inline" @keyup.enter.native="$refs.table.refresh(true)">
+          <a-row :gutter="15">
+            <a-col :md="6" :sm="24">
+              <a-form-item label="活动名称">
+                <a-input id="redPacket-shelfName" allowClear v-model.trim="queryParam.ruleName" placeholder="请输入活动名称"/>
+              </a-form-item>
+            </a-col>
+            <a-col :md="4" :sm="24">
+              <a-form-item label="活动状态">
+                <v-select id="redPacket-state" code="REWARD_RULE_STATUS" v-model="queryParam.ruleStatus" allowClear placeholder="请选择状态"></v-select>
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24" style="margin-bottom: 10px;">
+              <a-button type="primary" @click="$refs.table.refresh(true)" id="redPacket-search">查询</a-button>
+              <a-button type="" @click="reset" id="redPacket-reset" style="margin-left: 10px;">重置</a-button>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
+      <div class="table-operator">
+        <a-button type="primary" class="button-error" @click="handleEdit()" id="redPacket-handleEdit">新增红包活动</a-button>
+      </div>
+      <s-table
+        class="sTable fixPagination"
+        ref="table"
+        :style="{ height: tableHeight+84.5+'px', wordBreak: 'break-all' }"
+        size="small"
+        rowKey="id"
+        :columns="columns"
+        :data="loadData"
+        :scroll="{ y: tableHeight }"
+        :defaultLoadData="false"
+        bordered>
+        <template slot="shelf" slot-scope="text, record">
+          共 <a title="查看参与货架" @click="viewShelf(record)">{{ text }}</a> 个货架
+        </template>
+        <template slot="action" slot-scope="text, record">
+          <a-button v-if="record.ruleStatus == 'wait'" size="small" type="link" class="button-info" @click="handlePublish(record)">发布</a-button>
+          <a-button v-if="record.ruleStatus == 'release'" size="small" type="link" class="button-info" @click="handleEnd(record)">终止</a-button>
+          <a-button v-if="record.ruleStatus == 'wait'||record.ruleStatus == 'release'" size="small" type="link" class="button-info" @click="handleEdit(record)">编辑</a-button>
+          <a-button v-if="record.ruleStatus == 'wait'" size="small" type="link" class="button-error" @click="handleDelete(record)">删除</a-button>
+          <a-button size="small" type="link" class="button-info" @click="handleDetail(record)">详情</a-button>
+        </template>
+      </s-table>
+    </a-spin>
+    <shelfDetail ref="shelfDetail" :itemData="itemData" :visible="showModal" @close="closeModal"></shelfDetail>
+  </a-card>
+</template>
+
+<script>
+import { STable, VSelect } from '@/components'
+import { rewardRuleList, rewardRuleRelease, rewardRuleDelete, rewardRuleClose } from '@/api/redPacket.js'
+import dealerList from '@/views/common/dealerList.vue'
+import storeList from '@/views/common/storeList.vue'
+import shelfDetail from './shelfDetail.vue'
+export default {
+  name: 'UserList',
+  components: { STable, VSelect, storeList, dealerList, shelfDetail },
+  data () {
+    return {
+      spinning: false,
+      advanced: false,
+      tableHeight: 0,
+      // 查询参数
+      queryParam: {
+        ruleName: '', // 活动名称
+        ruleStatus: undefined // 状态
+      },
+      showModal: false,
+      itemData: null, // 编辑行数据
+      // 表头
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '5%', align: 'center' },
+        { title: '活动名称', dataIndex: 'ruleName', width: '17%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '活动发布时间', dataIndex: 'releaseDate', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '活动截止时间', dataIndex: 'expireDate', width: '10%', align: 'center', customRender: function (text, record) { return record.neverExpireFlag == 1 ? '永久' : text } },
+        { title: '参与货架', dataIndex: 'joinNum', width: '8%', align: 'center', scopedSlots: { customRender: 'shelf' } },
+        { title: '活动范围', dataIndex: 'bizTypes', width: '8%', align: 'center', customRender: function (text) { return '货架订单' } },
+        { title: '活动状态', dataIndex: 'ruleStatusDictValue', width: '8%', align: 'center', customRender: function (text) { return (text || text == 0) ? text : '--' } },
+        { title: '备注', dataIndex: 'remarks', width: '12%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '创建时间', dataIndex: 'createDate', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '操作', width: '12%', align: 'center', scopedSlots: { customRender: 'action' } }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.spinning = true
+        return rewardRuleList(Object.assign(parameter, this.queryParam)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (let i = 0; i < data.list.length; i++) {
+              const _item = data.list[i]
+              _item.no = no + i + 1
+            }
+          }
+          this.spinning = false
+          return data
+        })
+      }
+    }
+  },
+  methods: {
+    // 重置
+    reset () {
+      this.queryParam = {
+        ruleName: '', // 活动名称
+        ruleStatus: undefined // 状态
+      }
+      this.$refs.table.refresh(true)
+    },
+    // 编辑/新增
+    handleEdit (row) {
+      if (row) { //  编辑
+        this.$router.push({ name: 'redPacketEdit', params: { sn: row.rewardRuleSn } })
+      } else {
+        this.$router.push({ name: 'redPacketAdd' })
+      }
+    },
+    // 详情
+    handleDetail (row) {
+      this.$router.push({ name: 'redPacketDetail', params: { sn: row.rewardRuleSn } })
+    },
+    // 查看参与货架详细
+    viewShelf (row) {
+      this.showModal = true
+      this.itemData = row
+    },
+    closeModal () {
+      this.showModal = false
+      this.itemData = null
+    },
+    // 发布
+    handlePublish (row) {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: '确认要发布吗?',
+        centered: true,
+        onOk () {
+          _this.spinning = true
+          rewardRuleRelease({ rewardRuleSn: row.rewardRuleSn }).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.$refs.table.refresh()
+            }
+            _this.spinning = false
+          })
+        }
+      })
+    },
+    // 终止
+    handleEnd (row) {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: '确认要终止吗?',
+        centered: true,
+        onOk () {
+          _this.spinning = true
+          rewardRuleClose({ rewardRuleSn: row.rewardRuleSn }).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.$refs.table.refresh()
+            }
+            _this.spinning = false
+          })
+        }
+      })
+    },
+    // 删除
+    handleDelete (row) {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: '确认要删除吗?',
+        centered: true,
+        onOk () {
+          _this.spinning = true
+          rewardRuleDelete({ rewardRuleSn: row.rewardRuleSn }).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.$refs.table.refresh()
+              _this.spinning = false
+            } else {
+              _this.spinning = false
+            }
+          })
+        }
+      })
+    },
+    pageInit () {
+      const _this = this
+      _this.$refs.table.refresh()
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+    },
+    setTableH () {
+      const tableSearchH = this.$refs.tableSearch.offsetHeight
+      this.tableHeight = window.innerHeight - tableSearchH - 215
+    }
+  },
+  watch: {
+    '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
+      this.setTableH()
+    }
+  },
+  mounted () {
+    this.pageInit()
+    this.reset()
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {
+      if (from.name == 'redPacketEdit' || from.name == 'redPacketAdd') {
+        vm.$refs.table.refresh()
+      } else {
+        vm.reset()
+      }
+    })
+  }
+}
+</script>

+ 357 - 0
src/views/numsGoodsShelves/redPacket/redPacketStatistics.vue

@@ -0,0 +1,357 @@
+<template>
+  <a-card size="small" :bordered="false">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <div ref="tableSearch" class="table-page-search-wrapper">
+        <a-form layout="inline" @keyup.enter.native="$refs.table.refresh(true)">
+          <a-row :gutter="15">
+            <a-col :md="6" :sm="24">
+              <a-form-item label="活动名称">
+                <a-input id="redPacket-shelfName" allowClear v-model.trim="queryParam.rewardRuleName" placeholder="请输入活动名称"/>
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-item label="货架名称">
+                <a-input id="redPacket-shelfName" allowClear v-model.trim="queryParam.shelfName" placeholder="请输入货架名称"/>
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-item label="配件经销商">
+                <dealerList ref="dealerList" @change="dealerChange" id="redPacket-dealerChange"></dealerList>
+              </a-form-item>
+            </a-col>
+            <template v-if="advanced">
+              <a-col :md="6" :sm="24">
+                <a-form-item label="汽车修理厂">
+                  <storeList ref="storeList" @change="storeChange" id="redPacket-storeChange"></storeList>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="员工姓名">
+                  <a-input id="redPacket-shelfName" allowClear v-model.trim="queryParam.userName" placeholder="请输入员工姓名"/>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="员工手机号码">
+                  <a-input id="redPacket-shelfName" allowClear v-model.trim="queryParam.userMobile" placeholder="请输入员工手机号码"/>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="订单编号">
+                  <a-input id="redPacket-orderNo" allowClear v-model.trim="queryParam.orderNo" placeholder="请输入订单编号"/>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="订单类型">
+                  <v-select id="redPacket-orderType" code="REWARD_BIZ_TYPE" v-model="queryParam.orderType" allowClear placeholder="请选择订单类型"></v-select>
+                </a-form-item>
+              </a-col>
+              <!-- <a-col :md="6" :sm="24">
+                <a-form-item label="iSCM销售单号">
+                  <a-input id="redPacket-shelfName" allowClear v-model.trim="queryParam.bizNo" placeholder="请输入iSCM销售单号"/>
+                </a-form-item>
+              </a-col> -->
+              <a-col :md="6" :sm="24">
+                <a-form-item label="红包奖励时间">
+                  <rangeDate ref="rangeDate" @change="dateChange" />
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="红包发放状态">
+                  <v-select id="redPacket-rewardStatus" code="REWARD_SEND_STATUS" v-model="queryParam.rewardStatus" allowClear placeholder="请选择红包发放状态"></v-select>
+                </a-form-item>
+              </a-col>
+            </template>
+            <a-col :md="6" :sm="24" style="margin-bottom: 10px;">
+              <a-button type="primary" @click="$refs.table.refresh(true)" id="redPacket-search">查询</a-button>
+              <a-button type="" @click="reset" id="gredPacket-reset" style="margin-left: 10px;">重置</a-button>
+              <a-button type="primary" @click="exportFile" class="button-warning" id="gredPacket-export" style="margin-left: 10px;">导出</a-button>
+              <a @click="advanced=!advanced" style="margin-left: 8px">
+                {{ advanced ? '收起' : '展开' }}
+                <a-icon :type="advanced ? 'up' : 'down'"/>
+              </a>
+            </a-col>
+          </a-row>
+        </a-form>
+        <div class="table-operator">
+          <a-button type="primary" class="button-error" @click="plPublish">批量标记已发</a-button>
+          <span v-if="totalChoose">已选{{ totalChoose }}项</span>
+        </div>
+        <a-alert type="info" style="margin-bottom:10px">
+          <div slot="message">
+            售价总计:<strong>{{ totalData&&(totalData.totalTerminalPrice || totalData.totalTerminalPrice==0) ? totalData.totalTerminalPrice : '--' }}</strong>;
+            成本总计:<strong>{{ totalData&&(totalData.totalCityPrice || totalData.totalCityPrice==0) ? totalData.totalCityPrice : '--' }}</strong>;
+            毛利总计:<strong>{{ totalData&&(totalData.totalGrossAmount || totalData.totalGrossAmount==0) ? totalData.totalGrossAmount : '--' }}</strong>;
+            红包金额总计:<strong>{{ totalData&&(totalData.totalRewardAmount || totalData.totalRewardAmount==0) ? totalData.totalRewardAmount : '--' }}</strong>;
+          </div>
+        </a-alert>
+      </div>
+      <s-table
+        class="sTable fixPagination"
+        ref="table"
+        :style="{ height: tableHeight+84.5+'px', wordBreak: 'break-all' }"
+        size="small"
+        rowKey="id"
+        :columns="columns"
+        :row-selection="{ columnWidth: 40, getCheckboxProps: record => ({ props: { disabled: record.rewardStatus!='un_paid' } })}"
+        @rowSelection="rowSelectionFun"
+        :data="loadData"
+        :scroll="{ y: tableHeight, x: 2240 }"
+        :defaultLoadData="false"
+        bordered>
+        <template slot="orderNo" slot-scope="text, record">
+          <a @click="viewDetail(record)">{{ record.orderNo }}</a>
+        </template>
+        <template slot="rewardStatus" slot-scope="text, record">
+          <span v-if="record.rewardStatus=='un_paid'" style="color: #ffaa00;">{{ text }}</span>
+          <span v-else-if="record.rewardStatus=='paid'" style="color: #55aa00;">{{ text }}</span>
+          <span v-else style="color: #ff0000;">{{ text }}</span>
+        </template>
+        <template slot="action" slot-scope="text, record">
+          <a-button v-if="record.rewardStatus=='un_paid'" size="small" type="link" class="button-info" @click="handlePublish(record)">标记已发</a-button>
+          <a-button v-if="record.rewardStatus=='un_paid'" size="small" type="link" class="button-error" @click="handleDelete(record)">删除</a-button>
+          <span v-if="record.rewardStatus!='un_paid'">--</span>
+        </template>
+      </s-table>
+    </a-spin>
+    <!-- 详情弹框 -->
+    <statisticsDetail :visible="openModal" :itemData="itemData" @close="openModal=false"></statisticsDetail>
+  </a-card>
+</template>
+
+<script>
+import { STable, VSelect } from '@/components'
+import { rewardOrderQueryPage, rewardOrderCancel, cancelRewardBatch, exportRewardOrder, rewardOrderGiveReward, rewardOrderGiveRewardBatch, rewardOrderQueryCount } from '@/api/rewardOrder.js'
+import { hdExportExcel } from '@/libs/exportExcel'
+import dealerList from '@/views/common/dealerList.vue'
+import storeList from '@/views/common/storeList.vue'
+import rangeDate from '@/views/common/rangeDate.vue'
+import statisticsDetail from './statisticsDetail.vue'
+export default {
+  name: 'UserList',
+  components: { STable, VSelect, storeList, dealerList, rangeDate, statisticsDetail },
+  data () {
+    return {
+      spinning: false,
+      advanced: false,
+      openModal: false,
+      tableHeight: 0,
+      // 查询参数
+      queryParam: {
+        rewardRuleName: '',
+        shelfName: '',
+        userName: '',
+        userMobile: '',
+        orderNo: '',
+        orderType: undefined,
+        bizNo: '',
+        rewardStatus: undefined,
+        beginDate: '',
+        endDate: ''
+      },
+      itemData: null, // 编辑行数据
+      totalData: null,
+      // 表头
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '60px', align: 'center' },
+        { title: '活动名称', dataIndex: 'rewardRuleName', width: '150px', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '货架名称', dataIndex: 'shelfName', width: '180px', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '配件经销商', dataIndex: 'dealerName', width: '160px', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '汽车修理厂', dataIndex: 'storeName', width: '160px', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '员工姓名', dataIndex: 'userName', width: '80px', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '员工手机号码', dataIndex: 'userMobile', width: '100px', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '订单编号', dataIndex: 'orderNo', scopedSlots: { customRender: 'orderNo' }, width: '130px', align: 'center' },
+        { title: '订单类型', dataIndex: 'orderTypeDictValue', width: '80px', align: 'center', customRender: function (text) { return (text || text == 0) ? text : '--' } },
+        { title: '订单状态', dataIndex: 'orderStatusDictValue', width: '80px', align: 'center', customRender: function (text) { return (text || text == 0) ? text : '--' } },
+        { title: '下单方式', dataIndex: 'orderSourceDictValue', width: '90px', align: 'center', customRender: function (text) { return (text || text == 0) ? text : '--' } },
+        { title: '下单时间', dataIndex: 'orderDate', width: '150px', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: 'VIN', dataIndex: 'vin', width: '140px', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '车型', dataIndex: 'vehicleModel', width: '180px', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '红包奖励时间', dataIndex: 'rewardCreateDate', width: '150px', align: 'center', customRender: function (text) { return (text || text == 0) ? text : '--' } },
+        { title: '本单红包金额小计', dataIndex: 'totalRewardAmount', width: '80px', align: 'center', customRender: function (text) { return (text || text == 0) ? text : '--' } },
+        { title: '红包发放状态', dataIndex: 'rewardStatusDictValue', width: '100px', align: 'center', scopedSlots: { customRender: 'rewardStatus' } },
+        { title: '红包发放时间', dataIndex: 'giveDate', width: '150px', align: 'center', customRender: function (text) { return (text || text == 0) ? text : '--' } },
+        { title: '操作', width: '120px', align: 'center', scopedSlots: { customRender: 'action' }, fixed: 'right' }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.spinning = true
+        const params = Object.assign(parameter, this.queryParam)
+        return rewardOrderQueryPage(params).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (let i = 0; i < data.list.length; i++) {
+              const _item = data.list[i]
+              _item.no = no + i + 1
+            }
+          }
+          this.getCount(params)
+          this.spinning = false
+          return data
+        })
+      },
+      rowSelectionInfo: null
+    }
+  },
+  computed: {
+    totalChoose () {
+      return this.rowSelectionInfo && this.rowSelectionInfo.selectedRowKeys && this.rowSelectionInfo.selectedRowKeys.length
+    }
+  },
+  methods: {
+    getCount (params) {
+      rewardOrderQueryCount(params).then(res => {
+        this.totalData = res.data
+      })
+    },
+    // 表格选中项
+    rowSelectionFun (obj) {
+      this.rowSelectionInfo = obj || null
+    },
+    //  创建时间  change
+    dateChange (date) {
+      this.queryParam.beginDate = date[0] ? date[0] + ' 00:00:00' : ''
+      this.queryParam.endDate = date[1] ? date[1] + ' 23:59:59' : ''
+    },
+    // 经销商 change
+    dealerChange (obj) {
+      this.queryParam.dealerSn = obj.key || undefined
+    },
+    // 汽车修理厂 change
+    storeChange (obj) {
+      this.queryParam.storeSn = obj.key || undefined
+    },
+    // 重置
+    reset () {
+      this.queryParam = {
+        rewardRuleName: '',
+        shelfName: '',
+        userName: '',
+        userMobile: '',
+        orderNo: '',
+        orderType: undefined,
+        bizNo: '',
+        rewardStatus: undefined,
+        beginDate: '',
+        endDate: ''
+      }
+      this.$refs.dealerList.resetForm()
+      if (this.advanced) {
+        this.$refs.rangeDate.resetDate()
+        this.$refs.storeList.resetForm()
+      }
+      this.$refs.table.refresh(true)
+    },
+    // 标记发布
+    handlePublish (row) {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: '确认要标记为已发吗?',
+        centered: true,
+        onOk () {
+          _this.spinning = true
+          rewardOrderGiveReward({ id: row.id }).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.$refs.table.refresh()
+              _this.$refs.table.clearSelected()
+            }
+            _this.spinning = false
+          })
+        }
+      })
+    },
+    // 批量发布
+    plPublish () {
+      const _this = this
+      if (this.totalChoose) {
+        this.$confirm({
+          title: '提示',
+          content: '确认要批量标记为已发吗?',
+          centered: true,
+          onOk () {
+            _this.spinning = true
+            rewardOrderGiveRewardBatch({
+              idList: _this.rowSelectionInfo.selectedRowKeys
+            }).then(res => {
+              if (res.status == 200) {
+                _this.$message.success(res.message)
+                _this.$refs.table.refresh()
+                _this.$refs.table.clearSelected()
+              }
+              _this.spinning = false
+            })
+          }
+        })
+      } else {
+        this.$message.warning('请先选择红包奖励记录!')
+      }
+    },
+    // 详情
+    viewDetail (row) {
+      this.itemData = row
+      this.openModal = true
+    },
+    // 删除
+    handleDelete (row) {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: '确认要删除吗?',
+        centered: true,
+        onOk () {
+          _this.spinning = true
+          rewardOrderCancel({ id: row.id }).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.$refs.table.refresh()
+              _this.spinning = false
+            } else {
+              _this.spinning = false
+            }
+          })
+        }
+      })
+    },
+    // 导出
+    exportFile () {
+      const _this = this
+      _this.spinning = true
+      hdExportExcel(exportRewardOrder, this.queryParam, '红包活动统计', function () {
+        _this.spinning = false
+      })
+    },
+    pageInit () {
+      const _this = this
+      _this.$refs.table.refresh()
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+    },
+    setTableH () {
+      const tableSearchH = this.$refs.tableSearch.offsetHeight
+      this.tableHeight = window.innerHeight - tableSearchH - 275
+    }
+  },
+  watch: {
+    '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
+      this.setTableH()
+    }
+  },
+  mounted () {
+    this.pageInit()
+    this.reset()
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {
+      if (from.name == 'redPacketEdit' || from.name == 'redPacketAdd') {
+        vm.pageInit()
+      } else {
+        vm.reset()
+      }
+    })
+  }
+}
+</script>

+ 116 - 0
src/views/numsGoodsShelves/redPacket/shelfDetail.vue

@@ -0,0 +1,116 @@
+<template>
+  <div>
+    <a-modal
+      centered
+      wrapClassName="settlementModifyModal-modal"
+      :footer="null"
+      :maskClosable="false"
+      title="查看参与货架"
+      v-model="isshow"
+      @cancle="handleBack"
+      width="70%">
+      <a-spin :spinning="spinning" tip="Loading...">
+        <div style="padding: 15px 0;" v-if="itemData">
+          活动名称:{{ itemData.ruleName }}
+        </div>
+        <s-table
+          class="sTable"
+          ref="table"
+          size="small"
+          rowKey="shelfSn"
+          :columns="columns"
+          :data="loadData"
+          :defaultLoadData="false"
+          :scroll="{ y: 350 }"
+          bordered>
+        </s-table>
+        <div style="padding:10px;text-align:center;">
+          <a-button type="default" @click="handleBack">关闭</a-button>
+        </div>
+      </a-spin>
+    </a-modal>
+  </div>
+</template>
+
+<script>
+import { STable, VSelect } from '@/components'
+import { shelfJoinQueryPage } from '@/api/redPacket.js'
+import dealerList from '@/views/common/dealerList.vue'
+import storeList from '@/views/common/storeList.vue'
+export default {
+  name: 'ShelfModal',
+  components: {
+    STable, VSelect, storeList, dealerList
+  },
+  props: {
+    visible: {
+      type: Boolean,
+      default: false
+    },
+    itemData: {
+      type: Object,
+      default: function () {
+        return null
+      }
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isshow: this.visible,
+      // 表头
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '5%', align: 'center' },
+        { title: '货架名称', dataIndex: 'shelfName', width: '27%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '配件经销商', dataIndex: 'dealerName', width: '27%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '汽车修理厂', dataIndex: 'storeName', width: '26%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '货架状态', dataIndex: 'stateDictValue', width: '15%', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.spinning = true
+        return shelfJoinQueryPage(Object.assign(parameter, { rewardRuleSn: this.itemData.rewardRuleSn })).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (let i = 0; i < data.list.length; i++) {
+              const _item = data.list[i]
+              _item.no = no + i + 1
+            }
+          }
+          this.spinning = false
+          return data
+        })
+      },
+      rowSelectionInfo: null
+    }
+  },
+  methods: {
+    handleBack () {
+      this.$emit('close')
+    }
+  },
+  watch: {
+    visible (newValue, oldValue) {
+      this.isshow = newValue
+    },
+    isshow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+      } else {
+        this.$nextTick(() => {
+          this.$refs.table.refresh(true)
+        })
+      }
+    }
+  }
+}
+</script>
+<style lang="less">
+.settlementModifyModal-modal{
+  .ant-input-number-handler-wrap{
+    display: none;
+  }
+}
+</style>

+ 204 - 0
src/views/numsGoodsShelves/redPacket/shelfModal.vue

@@ -0,0 +1,204 @@
+<template>
+  <div>
+    <a-modal
+      centered
+      wrapClassName="settlementModifyModal-modal"
+      :footer="null"
+      :maskClosable="false"
+      title="选择参与货架"
+      v-model="isshow"
+      @cancle="handleBack"
+      width="80%">
+      <a-spin :spinning="spinning" tip="Loading...">
+        <div ref="tableSearch" class="table-page-search-wrapper">
+          <a-form layout="inline" @keyup.enter.native="$refs.table.refresh(true)">
+            <a-row :gutter="15">
+              <a-col :md="6" :sm="24">
+                <a-form-item label="货架名称">
+                  <a-input id="goodsShelvesAdministrationList-shelfName" allowClear v-model.trim="queryParam.shelfName" placeholder="请输入货架名称"/>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="配件经销商">
+                  <dealerList ref="dealerList" @change="dealerChange" id="goodsShelvesAdministrationList-dealerChange"></dealerList>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="汽车修理厂">
+                  <storeList ref="storeList" @change="storeChange" id="goodsShelvesAdministrationList-storeChange"></storeList>
+                </a-form-item>
+              </a-col>
+              <a-col :md="4" :sm="24" style="margin-bottom: 10px;">
+                <a-button type="primary" @click="$refs.table.refresh(true)" id="goodsShelvesAdministrationList-search">查询</a-button>
+                <a-button type="" @click="reset" id="goodsShelvesAdministrationList-reset" style="margin-left: 10px;">重置</a-button>
+              </a-col>
+            </a-row>
+          </a-form>
+        </div>
+        <s-table
+          class="sTable"
+          ref="table"
+          size="small"
+          rowKey="shelfSn"
+          :columns="columns"
+          :row-selection="{ columnWidth: 40, getCheckboxProps: record => ({ props: { disabled: !!record.rewardRuleStoreList && !checkedList.find(item=>item.shelfSn==record.shelfSn) } })}"
+          @rowSelection="rowSelectionFun"
+          :data="loadData"
+          :defaultLoadData="false"
+          :scroll="{ y: 350 }"
+          bordered>
+          <template slot="ruleName" slot-scope="text, record">
+            <div v-if="record.rewardRuleStoreList">
+              <div v-for="item in record.rewardRuleStoreList" :key="item.id">
+                {{ item.rewardRule.ruleName }}({{ item.rewardRule.ruleStatusDictValue }})
+              </div>
+            </div>
+          </template>
+        </s-table>
+        <div style="padding:10px;text-align:center;">
+          <a-button type="default" @click="handleBack" style="margin-right:20px;">取消</a-button>
+          <a-button type="primary" @click="handleOk">确定</a-button>
+        </div>
+      </a-spin>
+    </a-modal>
+  </div>
+</template>
+
+<script>
+import { STable, VSelect } from '@/components'
+import { rewardRuleShelfQueryPage } from '@/api/redPacket.js'
+import dealerList from '@/views/common/dealerList.vue'
+import storeList from '@/views/common/storeList.vue'
+export default {
+  name: 'ShelfModal',
+  components: {
+    STable, VSelect, storeList, dealerList
+  },
+  props: {
+    visible: {
+      type: Boolean,
+      default: false
+    },
+    checkedList: {
+      type: Array,
+      default: function () {
+        return []
+      }
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isshow: this.visible,
+      // 查询参数
+      queryParam: {
+        dealerSn: undefined, // 配件经销商sn
+        shelfName: '', // 货架名称
+        storeSn: undefined, // 汽车修理厂
+        state: 'ENABLE'
+      },
+      // 表头
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '5%', align: 'center' },
+        { title: '货架名称', dataIndex: 'shelfName', width: '20%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '配件经销商', dataIndex: 'dealerName', width: '20%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '汽车修理厂', dataIndex: 'storeName', width: '20%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '货架状态', dataIndex: 'stateDictValue', width: '11%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: <div>已参加活动&nbsp;<a-tooltip placement='top' title='如果货架存在未开始或进行中的红包活动,则不能再参与其它红包活动。'><a-icon type="question-circle" /></a-tooltip></div>, width: '20%', align: 'center', scopedSlots: { customRender: 'ruleName' } }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.spinning = true
+        return rewardRuleShelfQueryPage(Object.assign(parameter, this.queryParam)).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (let i = 0; i < data.list.length; i++) {
+              const _item = data.list[i]
+              _item.no = no + i + 1
+            }
+          }
+          this.setCheckList()
+          this.spinning = false
+          return data
+        })
+      },
+      rowSelectionInfo: null
+    }
+  },
+  methods: {
+    // 表格选中项
+    rowSelectionFun (obj) {
+      this.rowSelectionInfo = obj || null
+    },
+    // 经销商 change
+    dealerChange (obj) {
+      this.queryParam.dealerSn = obj.key || undefined
+    },
+    // 汽车修理厂 change
+    storeChange (obj) {
+      this.queryParam.storeSn = obj.key || undefined
+    },
+    // 设置已选中项
+    setCheckList () {
+      const selected = []
+      this.checkedList.map(item => {
+        selected.push(item.shelfSn)
+      })
+      this.$refs.table.setTableSelected(selected, [])
+    },
+    handleBack () {
+      this.$emit('close')
+    },
+    handleOk () {
+      const _this = this
+      console.log(_this.rowSelectionInfo)
+      if (!_this.rowSelectionInfo || (_this.rowSelectionInfo && _this.rowSelectionInfo.selectedRowKeys.length < 1)) {
+        _this.$message.warning('请选择货架!')
+        return
+      }
+      const ret = []
+      _this.rowSelectionInfo.selectedRowKeys.map(item => {
+        ret.push({
+          'shelfSn': item
+        })
+      })
+      this.$emit('ok', ret)
+    },
+    // 重置
+    reset (flag) {
+      this.queryParam = {
+        dealerSn: undefined, // 配件经销商sn
+        shelfName: '', // 货架名称
+        storeSn: undefined, // 汽车修理厂
+        state: 'ENABLE'
+      }
+      this.$refs.dealerList.resetForm()
+      this.$refs.storeList.resetForm()
+      this.$refs.table.refresh(true)
+    }
+  },
+  watch: {
+    visible (newValue, oldValue) {
+      this.isshow = newValue
+    },
+    isshow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+      } else {
+        this.$nextTick(() => {
+          this.reset(true)
+        })
+      }
+    }
+  }
+}
+</script>
+<style lang="less">
+.settlementModifyModal-modal{
+  .ant-input-number-handler-wrap{
+    display: none;
+  }
+}
+</style>

+ 162 - 0
src/views/numsGoodsShelves/redPacket/statisticsDetail.vue

@@ -0,0 +1,162 @@
+<template>
+  <div>
+    <a-modal
+      centered
+      wrapClassName="settlementModifyModal-modal"
+      :footer="null"
+      :maskClosable="false"
+      title="订单详情"
+      v-model="isshow"
+      @cancle="handleBack"
+      width="80%">
+      <a-spin :spinning="spinning" tip="Loading...">
+        <div ref="tableSearch" class="table-page-search-wrapper" v-if="itemData">
+          <a-descriptions>
+            <a-descriptions-item label="活动名称">
+              {{ itemData.rewardRuleName|| '--' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="货架名称">
+              {{ itemData.shelfName|| '--' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="配件经销商">
+              {{ itemData.dealerName|| '--' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="汽车修理厂">
+              {{ itemData.storeName|| '--' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="员工姓名">
+              {{ itemData.userName|| '--' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="员工手机号码">
+              {{ itemData.userMobile|| '--' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="订单编号">
+              {{ itemData.orderNo|| '--' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="订单类型">
+              {{ itemData.orderTypeDictValue|| '--' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="订单状态">
+              {{ itemData.orderStatusDictValue|| '--' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="红包奖励时间">
+              {{ itemData.rewardCreateDate|| '--' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="红包发放状态">
+              {{ itemData.rewardStatusDictValue|| '--' }}
+            </a-descriptions-item>
+            <a-descriptions-item label="红包发放时间">
+              {{ itemData.giveDate|| '--' }}
+            </a-descriptions-item>
+          </a-descriptions>
+        </div>
+        <a-alert type="info" style="margin-bottom:10px" v-if="itemData">
+          <div slot="message">
+            红包金额小计:<strong>{{ itemData&&(itemData.totalRewardAmount || itemData.totalRewardAmount==0) ? itemData.totalRewardAmount : '--' }}</strong>;
+          </div>
+        </a-alert>
+        <s-table
+          class="sTable"
+          ref="table"
+          size="small"
+          rowKey="id"
+          :columns="columns"
+          :data="loadData"
+          :showPagination="false"
+          :defaultLoadData="false"
+          :scroll="{ y: 350 }"
+          bordered>
+        </s-table>
+        <div style="padding:10px;text-align:center;">
+          <a-button type="default" @click="handleBack">关闭</a-button>
+        </div>
+      </a-spin>
+    </a-modal>
+  </div>
+</template>
+
+<script>
+import { STable, VSelect } from '@/components'
+import { rewardOrderQueryList } from '@/api/rewardOrder.js'
+export default {
+  name: 'StatisticsDetail',
+  components: {
+    STable, VSelect
+  },
+  props: {
+    visible: {
+      type: Boolean,
+      default: false
+    },
+    itemData: {
+      type: Object,
+      default: function () {
+        return null
+      }
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isshow: this.visible,
+      // 表头
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '5%', align: 'center' },
+        { title: '产品编码', dataIndex: 'productCode', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'productName', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '下单数量', dataIndex: 'productQty', width: '8%', align: 'center', customRender: function (text) { return (text || text == 0) ? text : '--' } },
+        { title: '售价(终端会员价)', dataIndex: 'terminalPrice', width: '10%', align: 'center', customRender: function (text) { return (text || text == 0) ? text : '--' } },
+        { title: '成本价(市级价)', dataIndex: 'cityPrice', width: '10%', align: 'center', customRender: function (text) { return (text || text == 0) ? text : '--' } },
+        { title: '售价小计', dataIndex: 'terminalPriceTotal', width: '8%', align: 'center', customRender: function (text) { return (text || text == 0) ? text : '--' } },
+        { title: '成本小计', dataIndex: 'cityPriceTotal', width: '8%', align: 'center', customRender: function (text) { return (text || text == 0) ? text : '--' } },
+        { title: '毛利小计', dataIndex: 'grossAmountTotal', width: '8%', align: 'center', customRender: function (text) { return (text || text == 0) ? text : '--' } },
+        { title: '红包毛利比例', dataIndex: 'rewardRatio', width: '10%', align: 'center', customRender: function (text) { return (text || text == 0) ? (text * 100 + '%') : '--' } },
+        { title: '红包金额', dataIndex: 'rewardAmount', width: '8%', align: 'center', customRender: function (text) { return (text || text == 0) ? text : '--' } }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.spinning = true
+        return rewardOrderQueryList(Object.assign(parameter, { rewardOrderSn: this.itemData.rewardOrderSn })).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = 0
+            for (let i = 0; i < data.length; i++) {
+              const _item = data[i]
+              _item.no = no + i + 1
+            }
+          }
+          this.spinning = false
+          return data
+        })
+      }
+    }
+  },
+  methods: {
+    handleBack () {
+      this.$emit('close')
+    }
+  },
+  watch: {
+    visible (newValue, oldValue) {
+      this.isshow = newValue
+    },
+    isshow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+      } else {
+        this.$nextTick(() => {
+          this.$refs.table.refresh(true)
+        })
+      }
+    }
+  }
+}
+</script>
+<style lang="less">
+.settlementModifyModal-modal{
+  .ant-input-number-handler-wrap{
+    display: none;
+  }
+}
+</style>

+ 2 - 2
vue.config.js

@@ -108,8 +108,8 @@ const vueConfig = {
     // If you want to turn on the proxy, please remove the mockjs /src/main.jsL11
     proxy: {
       '/api': {
-        // target: 'http://p.xprh.360arrow.com/xprh-admin',
-        target: 'http://192.168.0.215:8701/xprh-admin',
+        target: 'http://p.xprh.360arrow.com/xprh-admin',
+        // target: 'http://192.168.0.103:8701/xprh-admin',
         // ws: false,
         ws: true,
         changeOrigin: true,