Browse Source

Merge branch 'develop_sale20' of jianguan-web/jg-ocs-html into pre-release

李磊 2 năm trước cách đây
mục cha
commit
90f3f28631

+ 1 - 1
public/version.json

@@ -1,4 +1,4 @@
 {
-    "version": "2.2.28",
+    "version": "2.2.35",
     "message": "发现有新版本发布,确定更新系统?"
 }

+ 10 - 0
src/api/dealer.js

@@ -147,3 +147,13 @@ export const dealerUserSave = (params) => {
     method: 'post'
   })
 }
+
+// 根据经销商sn查询经销商信息   选择列表回显可用
+
+export const getDealerListInfo = (params) => {
+  return axios({
+    url: `/dealer/queryBySns`,
+    data: params,
+    method: 'post'
+  })
+}

+ 64 - 0
src/api/promoTerminal.js

@@ -0,0 +1,64 @@
+import { axios } from '@/utils/request'
+// 修理厂促销列表  有分页
+export const promoTerminalList = (params) => {
+  const url = `/promoTerminal/queryPage/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+//  保存促销
+export const promoTerminalSave = (params) => {
+  return axios({
+    url: '/promoTerminal/save',
+    data: params,
+    method: 'post'
+  })
+}
+
+//  获取促销详情
+export const promoTerminalDetail = (params) => {
+  const url = `/promoTerminal/findBySn/${params.sn}`
+  return axios({
+    url: url,
+    method: 'get'
+  })
+}
+
+//  促销活动 删除
+export const promoTerminalDel = (params) => {
+  const url = `/promoTerminal/delete/${params.sn}`
+  return axios({
+    url: url,
+    method: 'get'
+  })
+}
+//  促销活动 修改显示状态
+export const updateShowFlag = (params) => {
+  const url = `/promoTerminal/updateShowFlag/${params.sn}/${params.showFlag}`
+  return axios({
+    url: url,
+    method: 'get'
+  })
+}
+//  促销活动发布
+export const saveActive = (params) => {
+  return axios({
+    url: '/promoTerminal/saveActive',
+    data: params,
+    method: 'post'
+  })
+}
+
+// 导出活动经销商列表
+export const dealerExport = (params) => {
+  return axios({
+    url: '/dealer/exportListForPromo',
+    data: params,
+    method: 'post',
+    responseType: 'blob'
+  })
+}

+ 8 - 0
src/api/salesReturn.js

@@ -25,6 +25,14 @@ export const salesReturnDel = (params) => {
   })
 }
 
+//  销售退货 取消
+export const salesReturnCancelBill = (params) => {
+  return axios({
+    url: `/salesReturn/cancelBill/${params.salesReturnBillSn}`,
+    method: 'get'
+  })
+}
+
 // 再次编辑
 export const updateAgain = (params) => {
   return axios({

+ 8 - 0
src/api/sendBill.js

@@ -15,6 +15,14 @@ export const sendBillUpdate = params => {
     method: 'post'
   })
 }
+// 修改问题反馈
+export const updateIssueRemark = params => {
+  return axios({
+    url: '/sendBill/updateIssueRemark',
+    data: params,
+    method: 'post'
+  })
+}
 // 删除出库单修改发货状态
 export const deleteSendBillStockOut = params => {
   return axios({

BIN
src/assets/iphone.png


+ 13 - 10
src/components/UploadFile/index.vue

@@ -58,7 +58,7 @@ export default {
     },
     upText: {
       type: String,
-      default: ''
+      default: '上传文件'
     },
     value: {
       type: String
@@ -139,10 +139,10 @@ export default {
       this.previewVisible = false
     },
     handlePreview (file) {
-      if (this.listType == 'text') {
-        return
-      }
-      console.log(file)
+      // if (this.listType == 'text') {
+      //   return
+      // }
+      // console.log(file)
       if (file.response.status == 200) {
         this.previewImage = file.response.data
       } else {
@@ -252,19 +252,16 @@ export default {
   }
 }
 </script>
-<style lang="less">
+<style lang="less" scoped>
   .upload-file{
     float: left;
     overflow: hidden;
-    height: 80px;
     /* you can make up upload button and sample style by using stylesheets */
     .ant-upload-select-picture-card i {
       font-size: 32px;
       color: #999;
-      margin-top: 9px;
     }
     .ant-upload-select-picture-card .ant-upload-text {
-      margin-top: 8px;
       color: #666;
     }
     .ant-upload-btn{
@@ -295,5 +292,11 @@ export default {
       white-space: normal;
     }
   }
-
+/deep/.ant-modal-body{
+      max-height:860px;
+      text-align:center;
+  }
+ /deep/.ant-modal-body video{
+    width: 90% !important;
+  }
 </style>

+ 25 - 0
src/config/router.config.js

@@ -3211,6 +3211,31 @@ export const asyncRouterMap = [
                 }
               }
             ]
+          },
+          {
+            path: '/promotionRulesManagement/promotionManagement',
+            redirect: '/promotionRulesManagement/promotionManagement/list',
+            name: 'promotionManagement',
+            component: BlankLayout,
+            meta: {
+              title: '修理厂促销',
+              icon: 'file-ppt',
+              permission: 'M_promotionManagementList'
+            },
+            hideChildrenInMenu: true,
+            children: [
+              {
+                path: 'list',
+                name: 'promotionManagementList',
+                component: () => import(/* webpackChunkName: "promotionRulesManagement" */ '@/views/promotionRulesManagement/promotionManagement/list.vue'),
+                meta: {
+                  title: '促销列表',
+                  icon: 'file-ppt',
+                  hidden: true,
+                  permission: 'M_promotionManagementList'
+                }
+              }
+            ]
           }
         ]
       },

+ 4 - 2
src/utils/util.js

@@ -192,11 +192,13 @@ export function hasPriceAuth(authNode, priceOptions, userAuthCode){
       codes.push(a[a.length-1])
     }
   })
+  // console.log(codes)
   // 根据拥有的价格权限生成数组标记[1,0,1,0,0],每一位对应一个价格权限
   // 有权限标记1,否则标记0
   priceOptions.map(item => {
     ret.push(codes.includes(item.value)?1:0)
   })
+  // console.log(ret)
   return ret
 }
 // 获取接口对应的价格权限code
@@ -216,14 +218,14 @@ export function getAuthPriceCode (config, router, store) {
     const a = item.split('_')
     return priceOptions.find(k => k.value == a[a.length-1])
   })
-  // console.log(userAuthCode)
-  console.log(authCode)
+
   // 如果有权限code
   if(authCode){
     // 当前正在调用的接口url
     const url = config.url
     // 所有的权限菜单数据
     const authTree = store.state.app.authMenusList
+    
     // 从所有的权限菜单中查找当前权限code对应的权限菜单数据
     const authNode = treeFind(authTree,(item)=>item.code == authCode)
     console.log(authNode)

+ 3 - 1
src/views/Home.vue

@@ -114,7 +114,9 @@ export default {
         { label: '成本价', value: 'costPrice' },
         { label: '省级价', value: 'provincePrice' },
         { label: '市级价', value: 'cityPrice' },
-        { label: '特约价', value: 'specialPrice' }
+        { label: '特约价', value: 'specialPrice' },
+        { label: '终端价', value: 'terminalPrice' },
+        { label: '车主价', value: 'carOwnersPrice' }
       ]
     })
   }

+ 3 - 1
src/views/dealerManagement/businessOwnerSettings/chooseDealer.vue

@@ -148,6 +148,7 @@ export default {
                 }
               }
             }
+            console.log('11111111111111:', chooseData)
             if (!this.pageFlag) {
               this.pageFlag = true
               _this.$refs.table.setTableSelected(_this.chooseInfo, chooseData) // 设置表格选中项
@@ -187,6 +188,7 @@ export default {
     // 表格选中项
     rowSelectionFun (obj) {
       this.rowSelectionInfo = obj || null
+      console.log('22222222222222222222:', obj)
     },
     areaChange (val) {
       this.queryParam.provinceSn = val[0] ? val[0] : ''
@@ -262,7 +264,7 @@ export default {
       this.$nextTick(() => { // 页面渲染完成后的回调
         _this.setTableH()
       })
-      this.chooseInfo = data.list ? data.list :[]
+      this.chooseInfo = data.list ? data.list : []
       this.userSn = data.sn
       this.resetSearchForm()
     },

+ 42 - 6
src/views/power/role/menuModal.vue

@@ -90,6 +90,7 @@ export default {
       authAllPrice: [],
       leafNode:[],
       checkLeafNode:[],
+      priceCheckNode:[],
       form: {},
       rules: {},
       authType: '1',
@@ -165,9 +166,18 @@ export default {
       const _this = this
       this.$refs.ruleForm.validate(valid => {
         if (valid) {
-          const arr = [...this.checkedKeys, ...this.halfCheckedKeys, ...this.checkedData].filter((x, index,self)=>self.indexOf(x)===index) 
-          console.log(this.checkedData)
-
+          // 功能权限时的已选价格菜单或价格权限时的已选功能菜单
+          const checkData = this.authType == 1 ? this.priceCheckNode : this.checkedData.filter(item => !this.priceCheckNode.includes(item))
+          // 功能权限时,首次半选节点拿不到值(this.halfCheckedKeys为空时),
+          // 此时通过从所有已选checkedData数据中过滤当前选择的功能菜单和已选的价格菜单,剩下的就是半选节点
+          let halfCheckedKeys = this.halfCheckedKeys.length ? this.halfCheckedKeys : this.checkedData.filter(item => ![...this.checkedKeys,...checkData].includes(item))
+          // 功能权限没有选择任何菜单或价格权限时,halfCheckedKeys 半选节点为空
+          if(this.checkedKeys.length==0 || this.authType == 0){
+            halfCheckedKeys = []
+          }
+          // 最终保存的节点,包括当前已选的和半选的节点
+          const arr = [...this.checkedKeys, ...halfCheckedKeys, ...checkData].filter((x, index,self)=>self.indexOf(x)===index) 
+          console.log(arr, '--444--')
           _this.spinning = true
           addMenuPower({ id: this.id, menuIds: arr.join(',') }).then(res => {
             if (res.status == 200) {
@@ -257,6 +267,25 @@ export default {
         }
       }
     },
+    // 根据id查找是否价格菜单
+    getPriceTreeNode(data, arr){
+      const _this = this
+      for (let i = 0; i < data.length; i++) {
+        const node = data[i]
+        if(_this.isPriceNode(node)){
+           // 默认回显已选节点
+          const hasCheck = _this.priceCheckNode.find(item => item == node.id)
+          // 已选节点勾选
+          const hasNode = arr.find(item => item == node.id)
+          if (hasNode && !hasCheck) {
+            _this.priceCheckNode.push(node.id)
+          }
+        }
+        if (node.children && node.children.length) {
+          _this.getPriceTreeNode(node.children, arr)
+        }
+      }
+    },
     pageInit(){
       this.id = this.nowData.role.id
       this.titleText = (this.nowData.type == 1 ? '功能权限分配': '价格权限分配') + '(' + this.nowData.role.name + ')'
@@ -265,20 +294,26 @@ export default {
       // 权限类型, 1功能权限设置,0 价格权限设置
       this.authType = this.nowData.type
       this.checkedData = arr ? arr.split(',') : []
+
       // 找出叶子节点
       const treeData = this.nowData.allMenuList
-      
       this.expandedKeys.push(treeData.id)
+
+      // 获取已选的价格菜单
+      this.getPriceTreeNode(treeData, this.checkedData)
+
+      // 功能权限设置
       if(this.authType == 1){
         this.findLeaf(treeData, this.checkedData)
       }
+      // 价格权限设置
       if(this.authType == 0){
         this.findPrice(treeData, this.checkedData)
         this.hasAllSelect()
       }
-      this.checkedData = this.checkedData.filter(item => !this.checkedKeys.includes(item))
-      // console.log(this.checkedData)
       // console.log(this.checkedKeys)
+      // console.log(this.checkedData)
+      
       this.treeData = treeData
 
       if(this.authType == 0){
@@ -308,6 +343,7 @@ export default {
         this.id = ''
         this.authAllPrice = []
         this.checkLeafNode = []
+        this.priceCheckNode = []
         this.leafNode = []
         this.checkedKeys = []
         this.expandedKeys = []

+ 2 - 13
src/views/productManagement/productInfo/list.vue

@@ -101,19 +101,8 @@
           :loading="loadingDownline"
           @click="handleBatchDownline"
           style="margin: 0 10px;">批量下线</a-button>
-        <!-- <a-button
-          v-if="$hasPermissions('B_productInfo_batchImport')"
-          type="primary"
-          class="button-error"
-          @click="openGuideModal=true"
-          style="margin: 0 10px;">批量导入</a-button> -->
-        <a-dropdown id="productInfoList-batchImport">
-          <a-menu slot="overlay" @click="handleMenuClick">
-            <a-menu-item key="1" v-if="$hasPermissions('B_productInfo_batchImport')">新增产品导入</a-menu-item>
-            <a-menu-item key="2">下线产品导入</a-menu-item>
-          </a-menu>
-          <a-button type="primary" class="button-error" style="margin: 0 10px;"> 批量导入 <a-icon type="down" /> </a-button>
-        </a-dropdown>
+        <a-button type="primary" class="button-error" @click="handleMenuClick({key:'1'})" v-if="$hasPermissions('B_productInfo_batchImport')" style="margin: 0 10px;"> 新增产品导入</a-button>
+        <a-button type="primary" class="button-info" @click="handleMenuClick({key:'2'})" v-if="$hasPermissions('B_offlineProduct_import')" style="margin: 0 10px;"> 下线产品导入</a-button>
         <span style="margin-left: 8px" v-if="$hasPermissions('B_productInfo_batchAudit') || $hasPermissions('B_productInfo_batchLaunch') || $hasPermissions('B_productInfo_batchDownline')">
           <template v-if="rowSelectionInfo && rowSelectionInfo.selectedRowKeys.length>0">{{ `已选 ${rowSelectionInfo.selectedRowKeys.length} 项` }}</template>
         </span>

+ 24 - 9
src/views/productManagement/productNotOnline/list.vue

@@ -51,7 +51,7 @@
                 class="button-warning"
                 @click="handleExport"
                 :disabled="disabled"
-                v-if="$hasPermissions('B_ProductPriceExoprt')"
+                v-if="$hasPermissions('M_productOnlineExport')"
                 id="productInfoList-export">导出</a-button>
               <a @click="advanced=!advanced" style="margin-left: 5px">
                 {{ advanced ? '收起' : '展开' }}
@@ -97,7 +97,7 @@ import { queryOnlinePage, excelOnlineList } from '@/api/product'
 import ProductType from '@/views/common/productType.js'
 import ProductBrand from '@/views/common/productBrand.js'
 export default {
-  name: 'ProductPricingList',
+  name: 'productNotOnlineList',
   mixins: [commonMixin],
   components: { STable, VSelect, rangeDate, ProductBrand, ProductType },
   data () {
@@ -158,14 +158,27 @@ export default {
         { title: '第一次入库时间', dataIndex: 'skCreateDate', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
         { title: '产品状态', dataIndex: 'stateDictValue', width: '6%', align: 'center', customRender: function (text) { return text || '--' } },
         { title: '定价状态', dataIndex: 'pricingStateDictValue', width: '6%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '定价时间', dataIndex: 'pricingTime', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '最新成本', dataIndex: 'lastStockCost', width: '5%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
-        { title: '省级价', dataIndex: 'provincePrice', width: '5%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
-        { title: '市级价', dataIndex: 'cityPrice', width: '5%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
-        { title: '特约价', dataIndex: 'specialPrice', width: '5%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
-        { title: '终端价', dataIndex: 'terminalPrice', width: '5%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
-        { title: '车主价', dataIndex: 'carOwnersPrice', width: '5%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } }
+        { title: '定价时间', dataIndex: 'pricingTime', width: '8%', align: 'center', customRender: function (text) { return text || '--' } }
       ]
+
+      if (this.$hasPermissions('M_productNotOnlineList_costPrice')) {
+        arr.push({ title: '最新成本', dataIndex: 'lastStockCost', width: '5%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } })
+      }
+      if (this.$hasPermissions('M_productNotOnlineList_provincePrice')) {
+        arr.push({ title: '省级价', dataIndex: 'provincePrice', width: '5%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } })
+      }
+      if (this.$hasPermissions('M_productNotOnlineList_cityPrice')) {
+        arr.push({ title: '市级价', dataIndex: 'cityPrice', width: '5%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } })
+      }
+      if (this.$hasPermissions('M_productNotOnlineList_specialPrice')) {
+        arr.push({ title: '特约价', dataIndex: 'specialPrice', width: '5%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } })
+      }
+      if (this.$hasPermissions('M_productNotOnlineList_terminalPrice')) {
+        arr.push({ title: '终端价', dataIndex: 'terminalPrice', width: '5%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } })
+      }
+      if (this.$hasPermissions('M_productNotOnlineList_carOwnersPrice')) {
+        arr.push({ title: '车主价', dataIndex: 'carOwnersPrice', width: '5%', align: 'right', customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } })
+      }
       return arr
     }
   },
@@ -208,10 +221,12 @@ export default {
     //  导出
     handleExport () {
       const _this = this
+      _this.$store.state.app.curActionPermission = 'M_productOnlineExport'
       const params = this.queryParam
       this.spinning = true
       exportExcel(excelOnlineList, params, '产品状态信息导出', function () {
         _this.spinning = false
+        _this.$store.state.app.curActionPermission = ''
       })
     },
     //  产品分类  change

+ 279 - 0
src/views/promotionRulesManagement/promotionManagement/addModal.vue

@@ -0,0 +1,279 @@
+<template>
+  <a-modal
+    centered
+    class="promotion-modal"
+    :footer="null"
+    :maskClosable="false"
+    :title="isEdit?'编辑':'新增'"
+    v-model="isShow"
+    @cancel="isShow = false"
+    :width="900">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-form-model
+        id="promotion-form"
+        ref="ruleForm"
+        :model="form"
+        :rules="rules"
+        :label-col="formItemLayout.labelCol"
+        :wrapper-col="formItemLayout.wrapperCol"
+      >
+        <a-form-model-item label="促销名称" prop="name">
+          <a-input v-model="form.name" placeholder="请输入促销名称(最多30个字符)" :maxLength="30"></a-input>
+        </a-form-model-item>
+        <a-form-model-item label="促销时间" prop="time">
+          <a-range-picker
+            style="width:100%"
+            v-model="form.time"
+            :format="dateFormat"
+            :disabled-date="disabledDate"
+            @change="dateChange"
+            :placeholder="['开始时间', '结束时间']" />
+        </a-form-model-item>
+        <a-form-model-item label="参与经销商" prop="promoBuyerList">
+          <a-row :gutter="15">
+            <!-- <a-col :md="15" :sm="24">
+              <a-select
+                v-model="form.buyerLimitEnable"
+                placeholder="请选择参与经销商"
+              >
+                <a-select-option :value="0">全部经销商</a-select-option>
+                <a-select-option :value="1">部分经销商</a-select-option>
+              </a-select>
+            </a-col> -->
+            <a-col :md="5" :sm="24">
+              <a-button type="primary" :loading="spinning" @click="handleDealerModal">选择经销商</a-button>
+            </a-col>
+            <a-col :md="6" :sm="24" v-show="chooseDealerList && chooseDealerList.length>0">
+              已{{ chooseDealerList.length }}选项
+            </a-col>
+            <a-col :md="24" :sm="24" v-show="chooseDealerList && chooseDealerList.length>0">
+              <div class="buyerBox">
+                <a-tag closable v-for="con in chooseDealerList" :key="con.buyerSn" @close="delBuyerName(con)">
+                  {{ con.buyerName }}
+                </a-tag>
+              </div>
+            </a-col>
+          </a-row>
+        </a-form-model-item>
+        <a-form-model-item style="margin-bottom:10px;" label="促销描述" prop="description" :wrapperCol="{ span: 16 }" :labelCol="{ span: 4 }">
+          <a-textarea
+            :rows="5"
+            id="promotion-remark"
+            :maxLength="500"
+            v-model="form.description"
+            placeholder="请输入备注(最多500个字符)"
+            allowClear />
+        </a-form-model-item>
+      </a-form-model>
+      <div class="btn-cont">
+        <a-button id="promotion-modal-back" @click="isShow = false" >取消</a-button>
+        <a-button type="primary" style="margin-left: 15px;" :loading="spinning" id="promotion-modal-save" @click="handleSave">确定</a-button>
+      </div>
+    </a-spin>
+    <!-- 选择经销商 -->
+    <a-modal
+      title="选择经销商"
+      :visible="openDealerModal"
+      :footer="null"
+      centered
+      class="lookUpCustomers-modal"
+      @cancel="openDealerModal = false"
+      width="60%"
+    >
+      <div class="dealerModalCon">
+        <chooseDealer ref="dealerChoose" @plAdd="handleAddDealer"></chooseDealer>
+      </div>
+    </a-modal>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { promoTerminalSave, promoTerminalDetail } from '@/api/promoTerminal'
+import chooseDealer from './chooseDealer'
+import moment from 'moment'
+export default {
+  name: 'PromotionAddModal',
+  mixins: [commonMixin],
+  components: { chooseDealer },
+  props: {
+    openModal: {
+      //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    itemId: {
+      //  弹框显示状态
+      type: String,
+      default: ''
+    }
+  },
+  data () {
+    return {
+      isShow: this.openModal, //  是否打开弹框
+      openDealerModal: false,
+      spinning: false,
+      formItemLayout: {
+        labelCol: { span: 4 },
+        wrapperCol: { span: 16 }
+      },
+      form: {
+        promoActiveSn: undefined,
+        name: '',
+        time: [],
+        activeDateStart: undefined,
+        activeDateEnd: undefined,
+        activeDateEnable: '1',
+        buyerLimitEnable: '1',
+        description: '',
+        promoBuyerList: []
+      },
+      rules: {
+        promoBuyerList: [{ required: true, message: '请选择参与经销商', trigger: 'change' }],
+        time: [{ required: true, message: '请选择促销时间', trigger: 'change' }],
+        name: [{ required: true, message: '请输入促销名称', trigger: 'blur' }],
+        description: [{ required: true, message: '请输入促销描述', trigger: 'blur' }]
+      },
+      dateFormat: 'YYYY-MM-DD',
+      isEdit: false,
+      chooseDealerList: []// 选择经销商列表
+    }
+  },
+  methods: {
+    disabledDate (current) {
+      return current && current < moment().startOf('day')
+    },
+    handleDealerModal () {
+      this.openDealerModal = true
+      const _this = this
+      if (_this.chooseDealerList.length == 0) {
+        _this.form.promoBuyerList = []
+      }
+      const arr = _this.chooseDealerList.map(item => {
+        return item.buyerSn
+      })
+      // 选择经销商回显
+      _this.$nextTick(() => {
+        _this.$refs.dealerChoose.pageInit(arr)
+      })
+    },
+    // 日期  change
+    dateChange (date, dateStrings) {
+      if (dateStrings && dateStrings[0]) {
+        this.form.time = dateStrings
+        this.form.activeDateStart = date.length ? dateStrings[0] : ''
+        this.form.activeDateEnd = date.length ? dateStrings[1] : ''
+      } else {
+        this.form.time = []
+      }
+    },
+    // 添加经销商
+    handleAddDealer (list) {
+      this.chooseDealerList = list.map(con => {
+        return {
+          buyerSn: con.dealerSn,
+          buyerName: con.dealerName
+        }
+      })
+      this.openDealerModal = false
+      // 移除表单必填项
+      this.$refs.ruleForm.clearValidate('promoBuyerList')
+    },
+    // 获取编辑详情
+    getEditInfo () {
+      promoTerminalDetail({ sn: this.itemId }).then(res => {
+        if (res.status == 200) {
+          const data = res.data
+          this.chooseDealerList = data.promoBuyerList
+          data.promoBuyerList = data.promoBuyerList.map(item => {
+            return {
+              buyerSn: item.buyerSn
+            }
+          })
+          data.time = [data.activeDateStart, data.activeDateEnd]
+          this.form = data
+        }
+      })
+    },
+    // 删除所选经销商
+    delBuyerName (row) {
+      const pot = this.chooseDealerList.findIndex(con => { return con.buyerSn == row.buyerSn })
+      this.chooseDealerList.splice(pot, 1)
+    },
+    //  保存促销
+    handleSave () {
+      const _this = this
+      const newArr = this.chooseDealerList.map(item => {
+        return {
+          buyerSn: item.buyerSn
+        }
+      })
+      this.form.promoBuyerList = newArr
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          const form = JSON.parse(JSON.stringify(_this.form))
+          delete form.time
+          _this.spinning = true
+          promoTerminalSave(form).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.isShow = false
+              _this.$emit('ok', res.data)
+            }
+            _this.spinning = false
+          })
+        } else {
+          _this.spinning = false
+          return false
+        }
+      })
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.$refs.ruleForm.resetFields()
+        this.form = {
+          promoActiveSn: undefined,
+          name: '',
+          time: [],
+          activeDateStart: undefined,
+          activeDateEnd: undefined,
+          activeDateEnable: '1',
+          buyerLimitEnable: '1',
+          description: '',
+          promoBuyerList: []
+        }
+        this.isEdit = false
+        this.chooseDealerList = []
+      } else {
+        this.isEdit = !!this.itemId
+        if (this.itemId) {
+          this.getEditInfo()
+        }
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.promotion-modal {
+	.ant-modal-body {
+		padding: 40px 40px 24px;
+	}
+  .buyerBox{
+    border:1px solid #d9d9d9;margin-top:10px;border-radius:4px;padding:4px 10px;background:#f2f2f2;max-height:130px;overflow-y:scroll;
+  }
+	.btn-cont {
+		text-align: center;
+		margin: 35px 0 10px;
+	}
+}
+</style>

+ 263 - 0
src/views/promotionRulesManagement/promotionManagement/chooseDealer.vue

@@ -0,0 +1,263 @@
+<template>
+  <a-spin :spinning="spinning" tip="Loading...">
+    <!-- 搜索条件 -->
+    <div ref="tableSearch" class="table-page-search-wrapper newTableSearchName">
+      <a-form layout="inline" @keyup.enter.native="$refs.table.refresh(true)">
+        <a-row :gutter="15">
+          <a-col :md="8" :sm="24">
+            <a-form-item label="经销商名称/别名">
+              <a-input id="chooseDealer-nameLike" v-model.trim="queryParam.nameLike" allowClear placeholder="请输入经销商名称/别名"/>
+            </a-form-item>
+          </a-col>
+          <a-col :md="8" :sm="24">
+            <a-form-item label="商户类型">
+              <v-select code="DEALER_TYPE" id="chooseDealer-dealerType" v-model="queryParam.dealerType" allowClear placeholder="请选择商户类型"></v-select>
+            </a-form-item>
+          </a-col>
+          <a-col :md="8" :sm="24">
+            <a-form-model-item label="商户级别" prop="dealerLevel">
+              <v-select code="DEALER_LEVEL" id="ucModal-dealerLevel" v-model="queryParam.dealerLevel" allowClear placeholder="请选择商户级别"></v-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :md="8" :sm="24" v-if="pageType!='viewDealers'">
+            <a-form-item label="所在区域/分区">
+              <subarea id="chooseDealer-subarea" ref="subarea" @change="subareaChange"></subarea>
+            </a-form-item>
+          </a-col>
+          <div v-else>
+            <a-col :md="8" :sm="24">
+              <a-form-item label="审核状态">
+                <v-select code="AUDIT_STATE" id="viewDealers-auditState" v-model="queryParam.auditState" allowClear placeholder="请选择审核状态"></v-select>
+              </a-form-item>
+            </a-col>
+            <a-col :md="8" :sm="24">
+              <a-form-model-item label="地区">
+                <AreaList id="viewDealers-areaList" changeOnSelect ref="areaList" @change="areaChange" defValKey="id"></AreaList>
+              </a-form-model-item>
+            </a-col>
+          </div>
+          <a-col :md="pageType!='viewDealers'?8:6" :sm="24" style="margin-bottom: 10px;">
+            <a-button type="primary" @click="searchForm(true)" :disabled="disabled" id="chooseDealer-refresh">查询</a-button>
+            <a-button style="margin-left: 5px" @click="resetSearchForm" :disabled="disabled" id="chooseDealer-reset">重置</a-button>
+          </a-col>
+        </a-row>
+      </a-form>
+      <!-- 列表 -->
+      <div style="margin-bottom: 10px">
+        <a-button type="primary" ghost :loading="loading" @click="handleBatchAudit">批量添加</a-button>
+        <span style="margin-left: 5px">
+          <template v-if="selectCount"> {{ `已选 ${selectCount} 项` }} </template>
+        </span>
+      </div>
+    </div>
+    <a-table
+      style="height: 320px;"
+      :scroll="{ y: 230 }"
+      :bordered="true"
+      :pagination="pagination"
+      :row-key="record => record.dealerSn"
+      :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
+      :columns="columns"
+      :data-source="dealerList"
+      @change="handlePage"
+    ></a-table>
+  </a-spin>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import AreaList from '@/views/common/areaList.js'
+import { dealerQueryList, getDealerListInfo } from '@/api/dealer'
+import subarea from '@/views/common/subarea.js'
+export default {
+  name: 'ChooseDealer',
+  mixins: [commonMixin],
+  components: { STable, VSelect, subarea, AreaList },
+  props: {
+    pageType: {
+      type: String,
+      default: ''
+    },
+    parentData: {
+      type: Object,
+      default: function () {
+        return null
+      }
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      queryParam: { //  查询条件
+        nameLike: '',
+        dealerType: null,
+        dealerLevel: null,
+        subareaArea: {
+          subareaSn: undefined, //  区域
+          subareaAreaSn: undefined // 分区
+        },
+        auditState: undefined,
+        provinceSn: undefined,
+        citySn: undefined,
+        districtSn: undefined
+      },
+      pagination: {
+        pageSize: 20,
+        showSizeChanger: true
+      },
+      pageFlag: false,
+      chooseInfo: [],
+      selectedRowKeys: [],
+      columns: [
+        { title: '经销商名称', dataIndex: 'dealerName', width: '30%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '商户别名', dataIndex: 'dealerAlias', align: 'left', width: '30%', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '商户类型', dataIndex: 'dealerTypeDictValue', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '商户级别', dataIndex: 'dealerLevelDictValue', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '所在区域', dataIndex: 'subareaArea.subareaName', width: '20%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '所在分区', dataIndex: 'subareaArea.subareaAreaName', width: '20%', align: 'center', customRender: function (text) { return text || '--' } }
+      ],
+      dealerList: [],
+      tableHeight: 0,
+      disabled: false, //  查询、重置按钮是否可操作
+      loading: false // 批量添加loading
+    }
+  },
+  computed: {
+    selectCount () {
+      return this.selectedRowKeys && this.selectedRowKeys.length
+    }
+  },
+  methods: {
+    onSelectChange (selectedRowKeys) {
+      this.selectedRowKeys = selectedRowKeys
+    },
+    handlePage (pagination, filters, sorter) {
+      const pager = { ...this.pagination }
+      pager.current = pagination.current
+      pager.pageSize = pagination.pageSize
+      this.pagination = pager
+
+      this.loadData({ pageNo: pagination.current, pageSize: pagination.pageSize })
+    },
+    loadData (pager) {
+      this.spinning = true
+      const params = { pageSize: 20, pageNo: 1, ...pager }
+      dealerQueryList(Object.assign(params, this.queryParam)).then(res => {
+        let data
+        if (res.status == 200) {
+          data = res.data
+          const pagination = { ...this.pagination }
+          pagination.total = data.count
+          const no = 0
+          for (var i = 0; i < data.list.length; i++) {
+            data.list[i].no = no + i + 1
+          }
+          this.dealerList = data.list
+          this.pagination = pagination
+          if (this.chooseInfo && !this.pageFlag) {
+            this.pageFlag = true
+            this.selectedRowKeys = this.chooseInfo
+          }
+        }
+        this.spinning = false
+      })
+    },
+    // 表格选中项
+    rowSelectionFun (obj) {
+      this.rowSelectionInfo = obj || null
+    },
+    areaChange (val) {
+      this.queryParam.provinceSn = val[0] ? val[0] : ''
+      this.queryParam.citySn = val[1] ? val[1] : ''
+      this.queryParam.districtSn = val[2] ? val[2] : ''
+    },
+    searchForm () {
+      this.loadData()
+      this.spinning = false
+    },
+    subareaChange (val) {
+      this.queryParam.subareaArea.subareaSn = val[0] ? val[0] : undefined
+      this.queryParam.subareaArea.subareaAreaSn = val[1] ? val[1] : undefined
+    },
+    //  重置
+    resetSearchForm () {
+      this.queryParam = {
+        nameLike: '',
+        dealerType: null,
+        dealerLevel: null,
+        subareaArea: {
+          subareaSn: undefined, //  区域
+          subareaAreaSn: undefined // 分区
+        },
+        auditState: undefined,
+        provinceSn: undefined,
+        citySn: undefined,
+        districtSn: undefined
+      }
+      if (this.pageType != 'viewDealers') {
+        this.$refs.subarea.clearData()
+      } else {
+        this.$refs.areaList.clearData()
+      }
+      this.pagination = {
+        pageSize: 20,
+        showSizeChanger: true,
+        current: 1
+      }
+      this.selectedRowKeys = []
+      this.loadData()
+      this.pageFlag = false
+    },
+    clearTable () {
+      this.rowSelectionInfo = null
+      this.$refs.table.clearTable()
+    },
+    // 批量添加
+    async handleBatchAudit () {
+      const _this = this
+      if (_this.selectedRowKeys && _this.selectedRowKeys.length < 1) {
+        _this.$message.warning('请在列表勾选后再进行批量操作!')
+        return
+      }
+      const dealerInfoList = await getDealerListInfo({ dealerSnList: _this.selectedRowKeys })
+      this.spinning = false
+      this.$emit('plAdd', dealerInfoList.data)
+    },
+    handleAdd (row) {
+      if (row.subareaArea) {
+        const _this = this
+        this.$confirm({
+          title: '提示',
+          content: '当前经销商已被其他区域分区绑定,确定要更新绑定关系吗?',
+          centered: true,
+          onOk () {
+            _this.spinning = true
+            _this.$emit('add', row)
+          }
+        })
+      } else {
+        this.spinning = true
+        this.$emit('add', row)
+      }
+    },
+    pageInit (data) {
+      const _this = this
+      this.$nextTick(() => { // 页面渲染完成后的回调
+        _this.setTableH()
+      })
+      this.chooseInfo = data || []
+      this.resetSearchForm()
+    },
+    setTableH () {
+      const tableSearchH = this.$refs.tableSearch.offsetHeight
+      this.tableHeight = window.innerHeight - tableSearchH - 285
+    }
+  },
+  watch: {
+    '$store.state.app.winHeight' (newValue, oldValue) { //  窗口变更时,需同时更改表格高度
+      this.setTableH()
+    }
+  }
+}
+</script>

+ 414 - 0
src/views/promotionRulesManagement/promotionManagement/editModal.vue

@@ -0,0 +1,414 @@
+<template>
+  <a-modal
+    centered
+    class="promotionEdit-modal"
+    :footer="null"
+    :maskClosable="false"
+    :title="modalTit"
+    v-model="isShow"
+    @cancel="isShow=false"
+    width="76%">
+    <!-- 表单 -->
+    <div class="promotionEdit-content" ref="formBox">
+      <a-spin :spinning="spinning" tip="Loading...">
+        <a-form-model
+          id="promotionEdit-form"
+          ref="ruleForm"
+          :model="form"
+          :rules="rules"
+          :label-col="formItemLayout.labelCol"
+          :wrapper-col="formItemLayout.wrapperCol"
+        >
+          <a-form-model-item label="标题名称" prop="title">
+            <a-input
+              id="promotionEdit-title"
+              :maxLength="30"
+              v-model.trim="form.title"
+              placeholder="请输入标题名称(最多30个字符)"
+              :disabled="isDisabled"
+              allowClear/>
+          </a-form-model-item>
+          <a-form-model-item label="封面图片" prop="imageSet">
+            <Upload
+              v-if="pageType==='add'"
+              class="upload"
+              id="promotionEdit-imageSet"
+              v-model="form.imageSet"
+              ref="imageSet"
+              :fileSize="10"
+              :maxNums="10"
+              @change="changeImage"
+              listType="picture-card"></Upload>
+            <Upload
+              v-else-if="pageType==='edit'&&!isDisabled"
+              class="upload"
+              id="promotionEdit-imageSet"
+              v-model="form.imageSet"
+              ref="imageSet"
+              :fileSize="10"
+              :maxNums="10"
+              @change="changeImage"
+              listType="picture-card"></Upload>
+            <div v-else>
+              <img
+                :src="con"
+                alt="图片走丢了"
+                width="80"
+                height="80"
+                v-for="(con,i) in images"
+                style="margin-right:10px;"
+                :key="i" />
+            </div>
+            <span class="upload-desc">说明:单张大小小于10Mb,最多10张;建议尺寸:宽(420px)*高(230px)</span>
+          </a-form-model-item>
+          <a-form-model-item label="排序" prop="sort">
+              <a-input-number style="width:300px;" id="promotionEdit-sort" :disabled="isDisabled" allowClear placeholder="请输入排序数字(数字越大越靠后)" v-model="form.sort" :min="0" :max="999999"/>
+          </a-form-model-item>
+          <a-form-model-item label="内容类型" prop="contentType">
+            <v-select
+              v-model="form.contentType"
+              ref="saleStatus"
+              id="promotion-saleStatus"
+              code="PROMO_CONTENT_TYPE"
+              showType="radio"
+              :disabled="isDisabled"
+              allowClear></v-select>
+          </a-form-model-item>
+          <a-form-model-item label="内容" prop="content" v-show="form.contentType =='IMAGE_CONTENT'">
+            <editor
+              v-if="pageType === 'add'"
+              id="promotionEdit-editor"
+              ref="editor"
+              class="promotionEdit-editor"
+              @on-change="editorChange"
+              :cache="false"></editor>
+            <editor
+              v-if="pageType === 'edit'&&!isDisabled"
+              id="promotionEdit-editor"
+              ref="editor"
+              class="promotionEdit-editor"
+              @on-change="editorChange"
+              :cache="false"></editor>
+            <div v-show="pageType === 'edit'&&isDisabled" class="box" v-html="form.content"></div>
+          </a-form-model-item>
+          <a-form-model-item label="上传视频" prop="content" v-show="form.contentType =='VIDEO'">
+            <Upload
+              v-if="pageType==='add'"
+              class="upload"
+              id="promotionEdit-imageSet"
+              v-model="form.content"
+              fileType="video/mp4"
+              ref="videoSet"
+              :fileSize="100"
+              :maxNums="1"
+              @change="changeVideo"
+              ></Upload>
+            <Upload
+              v-else-if="pageType==='edit'&&!isDisabled"
+              class="upload"
+              id="promotionEdit-imageSet"
+              v-model="form.content"
+              fileType="video/mp4"
+              ref="videoSet"
+              :fileSize="100"
+              :maxNums="1"
+              @change="changeVideo"
+              ></Upload>
+            <div v-if="pageType==='edit'&&isDisabled">
+              <video width="230" height="150" controls loop controlsList="nodownload">
+                <source :src="form.content" type="video/mp4">
+              </video>
+            </div>
+            <span class="upload-desc">说明:文件最大100M;视频:mp4.avi.flv</span>
+          </a-form-model-item>
+          <a-form-model-item label="跳转链接" prop="contentLink" v-if="form.contentType =='LINK'">
+            <a-input
+              :disabled="isDisabled"
+              id="promotionEdit-title"
+              :maxLength="100"
+              v-model.trim="form.contentLink"
+              placeholder="请输入跳转链接"
+              allowClear />
+          </a-form-model-item>
+          <a-form-model-item label="是否发布" prop="enabledFlag">
+            <a-radio-group button-style="solid" v-model="form.enabledFlag">
+              <a-radio-button value="1">
+                是
+              </a-radio-button>
+              <a-radio-button value="0">
+                否
+              </a-radio-button>
+            </a-radio-group>
+          </a-form-model-item>
+          <a-form-model-item label="是否显示" prop="showFlag" v-if="form.enabledFlag == 1">
+            <a-radio-group button-style="solid" v-model="form.showFlag">
+              <a-radio-button value="1">
+                显示
+              </a-radio-button>
+              <a-radio-button value="0">
+                隐藏
+              </a-radio-button>
+            </a-radio-group>
+          </a-form-model-item>
+        </a-form-model>
+      </a-spin>
+      <div class="btn-cont">
+        <a-button id="product-brand-edit-modal-back" @click="isShow = false" style="margin-right:15px;">取消</a-button>
+        <a-button
+          style="margin-right:15px;color: #fff;background-color: #39f;border-color: #39f;"
+          @click="handleSee"
+          v-if="form.contentType !='LINK'">预览</a-button>
+        <a-button type="primary" id="product-brand-edit-modal-save" @click="handleSave">确定</a-button>
+      </div>
+    </div>
+    <!-- 预览 -->
+    <promotion-show-modal ref="showModal" :openModal="openShowModal" @close="openShowModal = false"></promotion-show-modal>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { VSelect, Upload } from '@/components'
+import Editor from '@/components/WEeditor'
+import { saveActive, promoTerminalDetail } from '@/api/promoTerminal'
+import promotionShowModal from './promotionShowModal'
+export default {
+  name: 'ProductBrandEditModal',
+  mixins: [commonMixin],
+  components: { VSelect, Upload, Editor, promotionShowModal },
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    itemId: {
+      type: [Number, String],
+      default: ''
+    },
+    pageType: {
+      type: String,
+      default: 'add'
+    }
+  },
+  computed: {
+    modalTit () {
+      return this.pageType != 'add' ? '发布修改' : '促销发布'
+    }
+  },
+  data () {
+    return {
+      isShow: this.openModal, //  是否打开弹框
+      spinning: false,
+      formItemLayout: {
+        labelCol: { span: 4 },
+        wrapperCol: { span: 18 }
+      },
+      form: {
+        promoActiveSn: undefined,
+        title: '',
+        contentType: 'IMAGE_CONTENT',
+        imageSet: '',
+        showFlag: '0',
+        content: '',
+        enabledFlag: '0',
+        sort: undefined,
+        contentLink: ''
+      },
+      images: [],
+      openShowModal: false,
+      isDisabled: false, // 控制是否能编辑
+      rules: {
+        title: [
+          { required: true, message: '请输入标题名称', trigger: 'blur' }
+        ],
+        imageSet: [
+          { required: true, message: '请选择要上传的封面图片', trigger: 'change' }
+        ],
+        sort: [
+          { required: true, message: '请输入排序数字', trigger: 'blur' }
+        ],
+        contentType: [
+          { required: true, message: '请选择内容类型', trigger: 'change' }
+        ],
+        content: [
+          { required: true, message: '请输入对应内容', trigger: ['blur', 'change'] }
+        ],
+        contentLink: [
+          { required: true, message: '请输入对应内容', trigger: 'blur' }
+        ],
+        enabledFlag: [
+          { required: true, message: '请选择是否发布', trigger: 'change' }
+        ],
+        showFlag: [
+          { required: true, message: '请选择是否显示', trigger: 'change' }
+        ]
+      }
+    }
+  },
+  methods: {
+    // 预览
+    handleSee () {
+      if (this.form.content) {
+        this.openShowModal = true
+        this.$refs.showModal.pageInit({ type: this.form.contentType, con: this.form.content })
+      } else {
+        this.$message.error('请输入预览内容!')
+      }
+    },
+    //  详情
+    getDetail () {
+      promoTerminalDetail({ sn: this.itemId }).then(res => {
+        if (res.status == 200) {
+          this.isDisabled = res.data.state === 'PUBLISH'
+          this.form.promoActiveSn = res.data.promoActiveSn
+          this.form.title = res.data.title
+          this.form.contentType = res.data.contentType
+          this.form.showFlag = res.data.showFlag
+          this.form.enabledFlag = res.data.enabledFlag
+          this.form.sort = res.data.sort
+          this.images = res.data.imageSet
+          this.form.imageSet = res.data.images
+          this.form.content = res.data.content
+          this.$refs.imageSet.setFileList(res.data.images)
+          if (res.data.contentType == 'IMAGE_CONTENT') {
+            this.$refs.editor.setHtml(res.data.content)
+          } else if (res.data.contentType == 'VIDEO') {
+            if (res.data.state != 'PUBLISH') {
+              this.$refs.videoSet.setFileList(res.data.content)
+            }
+          } else if (res.data.contentType == 'LINK') {
+            this.form.contentLink = res.data.content
+          }
+        }
+      })
+    },
+    //  确定
+    handleSave () {
+      const _this = this
+      if (_this.form.contentType == 'LINK') {
+        _this.form.content = _this.form.contentLink
+      }
+      _this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          _this.form.promoActiveSn = this.itemId
+          const formData = JSON.parse(JSON.stringify(_this.form))
+          formData.imageSet = formData.imageSet ? formData.imageSet.split(',') : []
+          formData.showFlag = formData.enabledFlag == 0 ? '0' : formData.showFlag
+          if (formData.contentType == 'LINK') {
+            delete formData.contentLink
+          }
+          _this.spinning = true
+          saveActive(formData).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.spinning = false
+              _this.isShow = false
+              _this.$emit('ok')
+            } else {
+              _this.spinning = false
+            }
+          })
+        } else {
+          return false
+        }
+      })
+    },
+    //  图片上传
+    changeImage (file) {
+      this.form.imageSet = file
+    },
+    // 视频上传
+    changeVideo (file) {
+      this.form.content = file
+    },
+    //  文本编辑器
+    editorChange (html, text) {
+      this.form.content = html
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        if (this.pageType == 'add' || (this.pageType == 'edit' && !this.isDisabled)) {
+          this.$refs.imageSet.setFileList('')
+          this.$refs.videoSet.setFileList('')
+        }
+        if (this.$refs.editor) {
+          this.$refs.editor.setHtml('')
+        }
+        this.form = {
+          promoActiveSn: undefined,
+          title: '',
+          contentType: 'IMAGE_CONTENT',
+          imageSet: '',
+          showFlag: '0',
+          content: '',
+          enabledFlag: '0',
+          sort: undefined
+        }
+        this.images = []
+        this.isDisabled = false
+        this.$refs.ruleForm.resetFields()
+        this.$refs.formBox.scrollTop = 0
+      } else {
+        if (this.pageType == 'edit') {
+          this.getDetail()
+        }
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+  .promotionEdit-modal{
+    .promotionEdit-content{
+      max-height:60vh;
+      overflow-y: scroll;
+  }
+    .ant-modal-body {
+      padding: 40px 40px 24px;
+    }
+    .upload{
+      width: 100%!important;
+    }
+    /deep/.upload-file .ant-upload-list-item-info{
+      padding:2px !important;
+    }
+    //  商品图片描述
+    .upload-desc{
+      font-size: 12px;
+      color: #808695;
+    }
+    //  文本编辑器  工具栏样式换行
+    .promotionEdit-editor{
+      .w-e-toolbar{
+        flex-wrap: wrap;
+      }
+    }
+    .btn-cont {
+      text-align: center;
+      margin: 35px 0 10px;
+    }
+    #promotionEdit-attachList{
+      height: auto;
+    }
+    a{
+      color: inherit;
+    }
+    .box{
+      border:1px solid #d9d9d9;
+      border-radius:4px;
+      padding:4px 11px;
+      color:rgba(0, 0, 0, 0.25);
+      cursor: not-allowed;
+      background:#fdfdfd;
+    }
+  }
+</style>

+ 393 - 0
src/views/promotionRulesManagement/promotionManagement/list.vue

@@ -0,0 +1,393 @@
+<template>
+  <a-card size="small" :bordered="false" class="promotion-wrap">
+    <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="创建时间">
+                <rangeDate ref="rangeCreateDate" :value="createDate" @change="dateCreateChange" />
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="24">
+              <a-form-item label="促销名称">
+                <a-input id="promotion-promotionName" v-model.trim="queryParam.name" allowClear placeholder="请输入总部销退单号"/>
+              </a-form-item>
+            </a-col>
+            <a-col :md="4" :sm="24">
+              <a-form-item label="显示状态">
+                <a-select
+                  v-model="queryParam.showFlag"
+                  placeholder="请选择显示状态"
+                >
+                  <a-select-option :value="1">已显示</a-select-option>
+                  <a-select-option :value="0">未显示</a-select-option>
+                </a-select>
+              </a-form-item>
+            </a-col>
+            <a-col :md="4" :sm="24">
+              <a-form-item label="促销状态">
+                <v-select
+                  v-model="queryParam.state"
+                  ref="saleStatus"
+                  id="promotion-saleStatus"
+                  code="PROMO_STATE"
+                  placeholder="请选择促销状态"
+                  allowClear></v-select>
+              </a-form-item>
+            </a-col>
+            <a-col :md="4" :sm="24">
+              <span class="table-page-search-submitButtons">
+                <a-button type="primary" :disabled="disabled" @click="$refs.table.refresh(true)">查询</a-button>
+                <a-button style="margin-left: 8px" :disabled="disabled" @click="resetSearchForm()">重置</a-button>
+              </span>
+            </a-col>
+          </a-row>
+        </a-form>
+        <!-- 操作按钮 -->
+        <div class="table-operator" v-if="$hasPermissions('B_promotionManagementAdd')">
+          <a-button type="primary" class="button-error" @click="openAddModal = true">新增</a-button>
+        </div>
+      </div>
+      <!-- 列表 -->
+      <s-table
+        class="sTable fixPagination"
+        ref="table"
+        :style="{ height: tableHeight+94.5+'px' }"
+        size="small"
+        :rowKey="(record) => record.id"
+        :columns="columns"
+        :data="loadData"
+        :scroll="{ y: tableHeight }"
+        :defaultLoadData="false"
+        bordered>
+        <!-- 自定义表头 -->
+        <template slot="arrowFalgTitle">
+          <a-tooltip placement="top">
+            <template slot="title">
+              <span>易码通轮播促销展示显示状态</span>
+            </template>
+            显示状态<a-icon type="question-circle" :style="{ marginLeft: '10px' }" />
+          </a-tooltip>
+        </template>
+        <!-- 显示状态 -->
+        <template slot="arrowFalg" slot-scope="text, record">
+          <a-switch
+            checkedChildren="显示"
+            unCheckedChildren="隐藏"
+            id="promotion-isEnable"
+            v-model="record.isEnable"
+            :disabled="record.state!='PUBLISH'"
+            @change="changeFlagHandle(record)" />
+        </template>
+        <!-- 促销时间 -->
+        <template slot="promotionTime" slot-scope="text, record">
+          <span>{{ record.activeDateStart }}至{{ record.activeDateEnd }}</span>
+        </template>
+        <!-- 参与客户 -->
+        <template slot="joinCustomers" slot-scope="text, record">
+          <span @click="handleCustomers(record)">共有<span class="font1">{{ record.promoBuyerSnSet?record.promoBuyerSnSet.length:0 }}</span>个客户</span>
+        </template>
+        <!-- 促销描述 -->
+        <template slot="salesDesc" slot-scope="text, record">
+          <a-tooltip placement="rightBottom" v-if="record.description&&record.description.length>14">
+            <template slot="title">
+              <span>{{ record.description }}</span>
+            </template>
+            <div @click="promotionDesc(record)" class="desc font1">{{ record.description }}</div>
+          </a-tooltip>
+          <div v-else @click="promotionDesc(record)" class="desc font1">{{ record.description }}</div>
+        </template>
+        <!-- 促销展示 -->
+        <template slot="salesShow" slot-scope="text, record">
+          <div @click="handleSaleShow(record)" v-if="record.contentType!='LINK'&&record.imageSet && record.imageSet.length>0">
+            <img :src="record.imageSet[0]" alt="图片走丢啦" width="60" />
+          </div>
+          <div v-else-if="record.contentType=='LINK'&&record.imageSet && record.imageSet.length>0">
+            <img :src="record.imageSet[0]" alt="图片走丢啦" width="60" />
+          </div>
+          <span v-else>--</span>
+        </template>
+        <!-- 操作 -->
+        <template slot="action" slot-scope="text, record">
+          <div>
+            <a-button
+              size="small"
+              type="link"
+              class="button-warning"
+              @click="promotionEdit(record)"
+              v-if="(record.state=='UNPUBLISH' || record.state=='CLOSE') && $hasPermissions('B_promotionManagementAdd')"
+              id="promotion-edit-btn">促销编辑</a-button>
+            <a-button
+              size="small"
+              type="link"
+              class="button-warning"
+              @click="handleRelease(record,'edit')"
+              v-if="(record.state=='PUBLISH' || record.state=='CLOSE')&&$hasPermissions('B_promotionManagementContent')"
+              id="promotion-modify-btn">发布修改</a-button>
+            <a-button
+              size="small"
+              type="link"
+              class="button-info"
+              @click="handleRelease(record,'add')"
+              v-if="record.state=='UNPUBLISH'&&$hasPermissions('B_promotionManagementContent')"
+              id="promotion-release-btn">促销发布</a-button>
+            <a-button
+              size="small"
+              type="link"
+              class="button-error"
+              v-if="record.state=='UNPUBLISH'&&$hasPermissions('B_promotionManagementDel')"
+              @click="handleDel(record)"
+              id="promotion-del-btn">删除</a-button>
+            <span v-if="record.state=='End'">--</span>
+          </div>
+        </template>
+      </s-table>
+    </a-spin>
+    <!-- 参与客户 -->
+    <lookUp-customers-modal ref="lookUpCustomers" :openModal="openCustomerModal" @close="openCustomerModal = false"></lookUp-customers-modal>
+    <!-- 促销描述 -->
+    <promotion-desc-modal :openModal="openDescModal" :con="descCon" @close="openDescModal = false;descCon=''"></promotion-desc-modal>
+    <!-- 促销展示 -->
+    <promotion-show-modal ref="showModal" :openModal="openShowModal" @close="openShowModal = false"></promotion-show-modal>
+    <!-- 新增 -->
+    <addModal :openModal="openAddModal" :itemId="itemId" @close="closeAddModal" @ok="$refs.table.refresh()"></addModal>
+    <!-- 促销发布 -->
+    <promotion-edit-modal :pageType="pageType" :openModal="openPromotionEditModal" :itemId="itemId" @close="closePromotionEditModal" @ok="$refs.table.refresh()" />
+  </a-card>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable, VSelect } from '@/components'
+import rangeDate from '@/views/common/rangeDate.vue'
+import { promoTerminalList, promoTerminalDel, updateShowFlag } from '@/api/promoTerminal'
+import lookUpCustomersModal from './lookUpCustomersModal'
+import promotionDescModal from './promotionDescModal'
+import promotionShowModal from './promotionShowModal'
+import addModal from './addModal'
+import promotionEditModal from './editModal'
+export default {
+  name: 'PromotionList',
+  mixins: [commonMixin],
+  components: {
+    STable,
+    VSelect,
+    rangeDate,
+    lookUpCustomersModal,
+    promotionShowModal,
+    promotionDescModal,
+    addModal,
+    promotionEditModal
+  },
+  data () {
+    return {
+      spinning: false,
+      tableHeight: 0,
+      disabled: false, //  查询、重置按钮是否可操作
+      openCustomerModal: false,
+      openDescModal: false,
+      openShowModal: false,
+      openAddModal: false,
+      openPromotionEditModal: false,
+      createDate: [], //  创建时间
+      itemId: '',
+      descCon: '', // 描述内容
+      pageType: '', // 发布类型  add  促销发布  edit 发布修改
+      dealerSn: [],
+      // 查询参数
+      queryParam: {
+        beginDate: undefined,
+        endDate: undefined,
+        name: '',
+        showFlag: undefined,
+        state: undefined
+      },
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        const params = Object.assign(parameter, this.queryParam)
+        return promoTerminalList(params).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+              data.list[i].isEnable = data.list[i].showFlag + '' === '1'
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      },
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '4%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '创建时间', dataIndex: 'createDate', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '促销名称', dataIndex: 'name', width: '12%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '促销时间', scopedSlots: { customRender: 'promotionTime' }, width: '8%', align: 'center' },
+        { title: '参与客户', scopedSlots: { customRender: 'joinCustomers' }, width: '12%', align: 'center' },
+        { title: '促销描述', scopedSlots: { customRender: 'salesDesc' }, width: '12%', align: 'center' },
+        { title: '促销展示', scopedSlots: { customRender: 'salesShow' }, width: '6%', align: 'center' },
+        { slots: { title: 'arrowFalgTitle' }, scopedSlots: { customRender: 'arrowFalg' }, width: '6%', align: 'center' },
+        { title: '促销状态', dataIndex: 'stateDictValue', width: '6%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '10%', align: 'center' }
+      ]
+    }
+  },
+  methods: {
+    // 关闭添加促销活动弹窗
+    closeAddModal () {
+      this.openAddModal = false; this.itemId = ''
+    },
+    // 参与经销商
+    handleCustomers (row) {
+      this.openCustomerModal = true
+      this.$nextTick(() => {
+        this.$refs.lookUpCustomers.pageInit({ dealerSnList: row.promoBuyerSnSet ? row.promoBuyerSnSet : undefined, promoActiveSn: row.promoActiveSn })
+      })
+    },
+    //  创建时间  change
+    dateCreateChange (date) {
+      this.queryParam.beginDate = date[0]
+      this.queryParam.endDate = date[1]
+    },
+    // 促销展示
+    handleSaleShow (record) {
+      this.openShowModal = true
+      this.$nextTick(() => {
+        this.$refs.showModal.pageInit({ type: record.contentType, con: record.content })
+      })
+    },
+    // 修改显示状态
+    changeFlagHandle (record) {
+      const _data = {
+        sn: record.promoActiveSn,
+        showFlag: record.isEnable ? '1' : '0'
+      }
+      this.spinning = true
+      updateShowFlag(_data).then(res => {
+        if (res.status == 200) {
+          this.$message.success(res.message)
+          this.$refs.table.refresh()
+          this.spinning = false
+        } else {
+          this.$refs.table.refresh()
+          this.spinning = false
+        }
+      })
+    },
+    // 促销编辑
+    promotionEdit (item) {
+      this.itemId = item.promoActiveSn
+      this.$nextTick(() => {
+        this.openAddModal = true
+      })
+    },
+    // 促销描述
+    promotionDesc (row) {
+      this.descCon = row.description
+      this.$nextTick(() => {
+        this.openDescModal = true
+      })
+    },
+    // 删除促销活动
+    handleDel (row) {
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: '点击确定,该内容将会被删除,不可再恢复!',
+        centered: true,
+        onOk () {
+          _this.spinning = true
+          promoTerminalDel({ sn: row.promoActiveSn }).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.$refs.table.refresh()
+              _this.spinning = false
+            } else {
+              _this.spinning = false
+            }
+          })
+        }
+      })
+    },
+    resetSearchForm () {
+      this.$refs.rangeCreateDate.resetDate(this.createDate)
+      this.queryParam.beginDate = undefined
+      this.queryParam.endDate = undefined
+      this.queryParam.name = ''
+      this.queryParam.showFlag = undefined
+      this.queryParam.state = undefined
+      this.$refs.table.refresh(true)
+    },
+    // 促销发布
+    handleRelease (row, type) {
+      this.itemId = row.promoActiveSn
+      this.pageType = row.imageSet && row.imageSet.length > 0 ? 'edit' : type
+      this.$nextTick(() => {
+        this.openPromotionEditModal = true
+      })
+    },
+    // 关闭促销发布
+    closePromotionEditModal () {
+      this.openPromotionEditModal = false
+      this.itemId = ''
+    },
+    pageInit () {
+      const _this = this
+      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 () {
+    if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
+      this.pageInit()
+      this.resetSearchForm()
+    }
+  },
+  activated () {
+    // 如果是新页签打开,则重置当前页面
+    if (this.$store.state.app.isNewTab) {
+      this.pageInit()
+      this.resetSearchForm()
+    }
+    // 仅刷新列表,不重置页面
+    if (this.$store.state.app.updateList) {
+      this.pageInit()
+      this.$refs.table.refresh()
+    }
+  },
+  beforeRouteEnter (to, from, next) {
+    next(vm => {})
+  }
+}
+</script>
+<style lang="less" scoped>
+  .font1{
+   color:#39f;
+  }
+  .desc{
+    width: 100%;
+    padding:0 10px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    display: -webkit-box;
+    box-sizing: border-box;
+    -webkit-line-clamp: 3;
+    -webkit-box-orient: vertical;
+  }
+</style>

+ 237 - 0
src/views/promotionRulesManagement/promotionManagement/lookUpCustomersModal.vue

@@ -0,0 +1,237 @@
+<template>
+  <a-modal
+    centered
+    class="lookUpCustomers-modal"
+    :footer="null"
+    :maskClosable="false"
+    title="参与客户"
+    v-model="isShow"
+    @cancel="isShow = false"
+    width="60%">
+    <a-spin :spinning="spinning" tip="Loading...">
+      <a-card size="small" :bordered="false">
+        <!-- 筛选条件 -->
+        <div 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-model-item label="地区">
+                  <AreaList id="actualSalesReportList-areaList" changeOnSelect ref="areaList" @change="areaChange" defValKey="id"></AreaList>
+                </a-form-model-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-model-item label="区域/分区">
+                  <subarea ref="subarea" id="salesManagementList-subarea" @change="subareaChange"></subarea>
+                </a-form-model-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="经销商名称">
+                  <a-input id="salesManagementList-purchaseBillNo" v-model.trim="queryParam.dealerName" allowClear placeholder="请输入经销商名称"/>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24" style="margin-bottom: 10px;">
+                <a-button type="primary" @click="$refs.table.refresh(true)" :disabled="disabled" id="inventoryCheckMakeInventoryList-refresh">查询</a-button>
+                <a-button style="margin-left: 5px" @click="resetSearchForm" :disabled="disabled" id="inventoryCheckMakeInventoryList-reset">重置</a-button>
+                <a-button
+                  style="margin-left: 10px"
+                  type="primary"
+                  class="button-warning"
+                  @click="handleExport"
+                  :disabled="disabled"
+                  :loading="exportLoading"
+                >导出</a-button>
+              </a-col>
+            </a-row>
+          </a-form>
+        </div>
+        <!-- 列表 -->
+        <s-table
+          class="sTable"
+          ref="table"
+          size="small"
+          :rowKey="(record) => record.id"
+          :columns="columns"
+          :data="loadData"
+          :defaultLoadData="false"
+          :scroll="{ y: 450 }"
+          :rowClassName="(record, index) => record.checkProfitLossQty < 0 ? 'redBg-row':''"
+          bordered>
+          <!-- 地区 -->
+          <template slot="address" slot-scope="text, record">
+            {{ record.provinceName }}/{{ record.cityName }}/{{ record.districtName }}
+          </template>
+        </s-table>
+      </a-card>
+      <div class="btn-cont">
+        <a-button type="primary" id="lookUpCustomers-modal-back" @click="isShow = false">关闭</a-button>
+      </div>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+import { STable } from '@/components'
+import ProductType from '@/views/common/productType.js'
+import subarea from '@/views/common/subarea.js'
+import AreaList from '@/views/common/areaList.js'
+import { hdExportExcel } from '@/libs/exportExcel'
+import { dealerExport } from '@/api/promoTerminal'
+import { dealerQueryList } from '@/api/dealer'
+export default {
+  name: 'LookUpCustomersModal',
+  components: { STable, ProductType, subarea, AreaList },
+  mixins: [commonMixin],
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    }
+  },
+  data () {
+    return {
+      spinning: false,
+      isShow: this.openModal, //  是否打开弹框
+      disabled: false,
+      advanced: false,
+      exportShow: false,
+      exportLoading: false,
+      queryParam: {
+        subareaArea: {
+          subareaSn: undefined,
+          subareaAreaSn: undefined
+        },
+        provinceSn: undefined,
+        citySn: undefined,
+        districtSn: undefined,
+        dealerName: undefined
+      },
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        this.disabled = true
+        this.spinning = true
+        const params = Object.assign(parameter, this.queryParam)
+        return dealerQueryList(params).then(res => {
+          let data
+          if (res.status == 200) {
+            data = res.data
+            const no = (data.pageNo - 1) * data.pageSize
+            for (var i = 0; i < data.list.length; i++) {
+              data.list[i].no = no + i + 1
+            }
+            this.disabled = false
+          }
+          this.spinning = false
+          return data
+        })
+      },
+      basicInfoData: null, //  基本信息
+      productTotal: null,
+      productType: [],
+      snObj: undefined, // 经销商列表
+      warehouseList: [], //  仓库  下拉数据
+      localDataSource: [],
+      isPrice: false, //  仅显示盈亏
+      openPrintModal: false,
+      nowType: null,
+      printerType: 'NEEDLE', //  打印机类型
+      columns: [
+        { title: '序号', dataIndex: 'no', width: '4%', align: 'center' },
+        { title: '地区', scopedSlots: { customRender: 'address' }, width: '20%', align: 'center', ellipsis: true },
+        { title: '区域', dataIndex: 'subareaArea.subareaName', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '分区', dataIndex: 'subareaArea.subareaAreaName', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '经销商名称', dataIndex: 'dealerName', width: '20%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '商户类型', dataIndex: 'dealerLevelDictValue', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '商户级别', dataIndex: 'dealerTypeDictValue', width: '15%', align: 'center', customRender: function (text) { return text || '--' } }
+      ]
+    }
+  },
+  methods: {
+    areaChange (val) {
+      this.queryParam.provinceSn = val[0] ? val[0] : ''
+      this.queryParam.citySn = val[1] ? val[1] : ''
+      this.queryParam.districtSn = val[2] ? val[2] : ''
+    },
+    subareaChange (val) {
+      this.queryParam.subareaArea.subareaSn = val[0] ? val[0] : undefined
+      this.queryParam.subareaArea.subareaAreaSn = val[1] ? val[1] : undefined
+    },
+    pageInit (data) {
+      this.snObj = data
+      this.queryParam = Object.assign(this.queryParam, data)
+      this.$refs.table.refresh(true)
+    },
+    //  重置
+    resetSearchForm () {
+      this.queryParam = Object.assign({
+        provinceSn: undefined,
+        citySn: undefined,
+        districtSn: undefined,
+        subareaArea: {
+          subareaSn: undefined,
+          subareaAreaSn: undefined
+        }
+      }, this.snObj)
+      this.queryParam.dealerName = undefined
+      this.$refs.areaList.clearData()
+      this.$refs.subarea.clearData()
+      this.$refs.table.refresh(true)
+    },
+    //  导出
+    handleExport () {
+      const _this = this
+      _this.exportLoading = true
+      _this.spinning = true
+      hdExportExcel(dealerExport, _this.queryParam, '促销经销商列表导出', function () {
+        _this.exportLoading = false
+        _this.spinning = false
+        _this.showExport = true
+      })
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+        this.resetSearchForm()
+      }
+    }
+  }
+}
+</script>
+<style lang="less" scoped>
+  .lookUpCustomers-modal{
+    .ant-modal-body{
+      padding: 0 24px 24px;
+    }
+    .redBg-row{
+      background-color: #f5cdc8;
+    }
+    .btn-cont {
+      text-align: center;
+      margin: 5px 0 10px;
+    }
+    .table-page-search-wrapper{
+      margin-bottom:6px;
+      /deep/.ant-select-selection{
+        border:0 !important;
+        box-shadow: none !important;
+      }
+      .ant-form.ant-form-inline .ant-form-item{
+        border:1px solid #dadada;
+        border-radius: 3px;
+        overflow: hidden;
+        margin-bottom: 10px!important;
+        /deep/.ant-form-item-label{
+          padding-left: 11px !important;
+          padding-right: 0!important;
+        }
+      }
+    }
+  }
+</style>

+ 69 - 0
src/views/promotionRulesManagement/promotionManagement/promotionDescModal.vue

@@ -0,0 +1,69 @@
+<template>
+  <a-modal
+    centered
+    class="promotionDesc-modal"
+    :footer="null"
+    :maskClosable="false"
+    :title="modalTit"
+    v-model="isShow"
+    @cancel="isShow=false"
+    :width="500">
+    <div class="promotionDesc-con">
+      {{ con }}
+    </div>
+    <div class="btn-cont">
+      <a-button type="primary" id="promotionDesc-modal-back" @click="isShow = false">关闭</a-button>
+    </div>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+export default {
+  name: 'PromotionDescModal',
+  mixins: [commonMixin],
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    },
+    con: {
+      type: String,
+      default: ''
+    }
+  },
+  data () {
+    return {
+      modalTit: '促销描述',
+      isShow: this.openModal //  是否打开弹框
+    }
+  },
+  methods: {
+
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+  .promotionDesc-modal{
+    .promotionDesc-con{
+       text-align: center;
+    }
+    .btn-cont {
+      text-align: center;
+      margin: 50px 0 0px;
+    }
+  }
+</style>

+ 102 - 0
src/views/promotionRulesManagement/promotionManagement/promotionShowModal.vue

@@ -0,0 +1,102 @@
+<template>
+  <a-modal
+    centered
+    class="promotionDesc-modal"
+    :footer="null"
+    :maskClosable="false"
+    :title="modalTit"
+    v-model="isShow"
+    @cancel="isShow=false"
+    :width="500">
+    <div class="promotionDesc-con">
+      <img src="@/assets/iphone.png" alt="图片走丢了" srcset="">
+      <div class="promotionDescCon" v-if="showType==='IMAGE_CONTENT'" v-html="mainContent"></div>
+      <div class="promotionDescCon" v-if="showType=='VIDEO'" >
+        <video width="100%" height="auto" controls loop controlsList="nodownload">
+          <source :src="mainContent" type="video/mp4"></source>
+        </video>
+      </div>
+    </div>
+    <div class="btn-cont">
+      <!-- <a-button id="promotionDesc-modal-back" @click="isShow = false" style="margin-right:10px;">下载图片</a-button> -->
+      <a-button type="primary" id="promotionDesc-modal-back" @click="isShow = false">关闭</a-button>
+    </div>
+  </a-modal>
+</template>
+
+<script>
+import { commonMixin } from '@/utils/mixin'
+export default {
+  name: 'PromotionDescModal',
+  mixins: [commonMixin],
+  props: {
+    openModal: { //  弹框显示状态
+      type: Boolean,
+      default: false
+    }
+  },
+  data () {
+    return {
+      modalTit: '促销展示',
+      isShow: this.openModal, //  是否打开弹框
+      mainContent: '', // 主要显示内容
+      showType: undefined//
+    }
+  },
+  methods: {
+    pageInit (con) {
+      this.showType = con.type
+      this.mainContent = con.con
+    }
+  },
+  watch: {
+    //  父页面传过来的弹框状态
+    openModal (newValue, oldValue) {
+      this.isShow = newValue
+    },
+    //  重定义的弹框状态
+    isShow (newValue, oldValue) {
+      if (!newValue) {
+        this.$emit('close')
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+  .promotionDesc-modal{
+    /deep/.ant-modal-body{
+       text-algin:center !important;
+    }
+
+    .promotionDesc-con{
+      width:340px;
+      margin:0 auto;
+      position:relative;
+      text-align: center;
+      img{
+         width:81%;
+         height:auto;
+       }
+       .promotionDescCon{
+         position: absolute;
+         left:15%;
+         top:12.5%;
+         width: 70%;
+         max-height:420px;
+         overflow-y: scroll;
+         scrollbar-width:none;
+         -ms-overflow-style: none;
+       }
+       .promotionDescCon::-webkit-scrollbar{
+           display:none;
+       }
+    }
+
+    .btn-cont {
+      text-align: center;
+      margin: 30px 0 0px;
+    }
+  }
+</style>

+ 24 - 4
src/views/salesManagement/sendOutOrder/detailModal.vue

@@ -30,7 +30,6 @@
           <div style="flex-basis:35%">物流电话:{{ detail.transportTele||'--' }}</div>
           <div style="flex-basis:35%">物流单号:{{ detail.transportNo||'--' }}</div>
           <div style="flex-basis:30%"></div>
-          <!-- <div style="flex-basis:100%;word-break: break-all;">发货备注:{{ detail.sendRemark||'--' }}</div> -->
           <div style="flex-basis:35%" :class="type==0?'requerd':''">物流情况:
             <v-select
               v-model="form.transportState"
@@ -54,11 +53,23 @@
             <span v-else>{{ detail.receiveDate||'--' }}</span>
           </div>
           <div style="flex-basis:30%" v-else></div>
-          <div style="flex-basis:100%">
+          <div style="flex-basis:30%">
             <label>物流备注:</label>
             <a-textarea v-model="form.transportRemark" placeholder="请输入备注" v-if="type==0"/>
             <span v-else>{{ detail.transportRemark||'--' }}</span>
           </div>
+          <div style="flex-basis:60%;display:flex;" v-if="detail.receiveFlag == 1 && type!=0">
+            问题反馈:
+            <div style="padding:0 10px;">
+              <div v-if="showEditQus" style="width:400px;">
+                <a-textarea @blur="saveIssue" allowClear v-model="detail.issueRemark" placeholder="请输入问题反馈(最多100字符)" :maxLength="100" auto-size />
+              </div>
+              <div v-else>{{ detail.issueRemark||'--' }}</div>
+            </div>
+            <div v-if="!showEditQus">
+              <a-icon @click="showEditQus = !showEditQus" style="color:#00aaff;font-size:16px;cursor:pointer;" type="form" />
+            </div>
+          </div>
         </div>
         <div>
           <a-table class="sTable" :columns="columns" :pagination="false" :data-source="tableData" bordered></a-table>
@@ -82,7 +93,7 @@ import moment from 'moment'
 import { STable, VSelect } from '@/components'
 import printModel from './printModel.vue'
 import commonModal from '@/views/common/commonModal.vue'
-import { updateTransportInfo, sendBillFindBySn } from '@/api/sendBill'
+import { updateTransportInfo, sendBillFindBySn, updateIssueRemark } from '@/api/sendBill'
 export default {
   name: 'SendOutDetailModal',
   mixins: [commonMixin],
@@ -148,7 +159,8 @@ export default {
       ],
       sendBillSn: null,
       customeName: '',
-      showTipModal: false
+      showTipModal: false,
+      showEditQus: false
     }
   },
   methods: {
@@ -163,6 +175,13 @@ export default {
         this.showTipModal = false
       }
     },
+    saveIssue(){
+      updateIssueRemark({issueRemark: this.detail.issueRemark, sendBillSn: this.sendBillSn}).then(res => {
+        if(res.status == 200){
+          this.showEditQus = false
+        }
+      })
+    },
     // 编辑
     getDetail (data, type, title) {
       this.type = type // 0 是物流跟踪,1是详情
@@ -176,6 +195,7 @@ export default {
         if (res.data) {
           this.detail = res.data
           this.detail.receiveFlag = res.data.receiveFlag == 1
+          this.detail.issueRemark = this.detail.issueRemark || ''
           this.form.receiveFlag = false
           this.form.receiveDate = ''
           this.form.transportState = res.data.transportState

+ 2 - 1
src/views/salesManagement/stockPrint/list.vue

@@ -300,10 +300,11 @@ export default {
       }
       if (this.$hasPermissions('M_stockPrintList_salesPrice')) { //  售价权限
         const ind = this.isShowWarehouse ? 11 : 10
-		arr.splice(ind, 0, { slots: { title: 'costTitle' }, dataIndex: 'receiveTotalAmount', width: '90px', align: 'right', customRender: text => ((text || text == 0) ? this.toThousands(text) : '--') })
+		    arr.splice(ind, 0, { slots: { title: 'costTitle' }, dataIndex: 'receiveTotalAmount', width: '90px', align: 'right', customRender: text => ((text || text == 0) ? this.toThousands(text) : '--') })
         arr.splice(ind+1, 0, { title: '易损件售价', dataIndex: 'receiveYsjTotalAmount', width: '90px', align: 'right', customRender: text => ((text || text == 0) ? this.toThousands(text) : '--') })
         arr.splice(ind+2, 0, { title: '电池售价', dataIndex: 'receiveDcTotalAmount', width: '70px', align: 'right', customRender: text => ((text || text == 0) ? this.toThousands(text) : '--') })
         arr.splice(ind+3, 0, { title: '机油售价', dataIndex: 'receiveJyTotalAmount', width: '70px', align: 'right', customRender: text => ((text || text == 0) ? this.toThousands(text) : '--') })
+        arr.splice(ind+4, 0, { title: '轮胎售价', dataIndex: 'receiveLtTotalAmount', width: '70px', align: 'right', customRender: text => ((text || text == 0) ? this.toThousands(text) : '--') })
       }
       return arr
     }

+ 2 - 2
src/views/salesReturnManagement/receiveCheck/list.vue

@@ -27,7 +27,7 @@
                   ref="billStatus"
                   id="receiveCheck-billStatus"
                   code="SALES_RETURN_BILL_STATUS"
-                  :notIn="['WAIT_SUBMIT', 'WAIT_AUDIT', 'AUDIT_REJECT', 'CANCEL']"
+                  :notIn="['WAIT_SUBMIT', 'WAIT_AUDIT', 'AUDIT_REJECT']"
                   placeholder="请选择业务状态"
                   allowClear></v-select>
               </a-form-item>
@@ -149,7 +149,7 @@ export default {
         this.disabled = true
         this.spinning = true
         return takeQueryPage(Object.assign(parameter, this.queryParam, {
-          'excludeBillStatusList': ['WAIT_SUBMIT', 'WAIT_AUDIT', 'AUDIT_REJECT', 'CANCEL']
+          'excludeBillStatusList': ['WAIT_SUBMIT', 'WAIT_AUDIT', 'AUDIT_REJECT']
         })).then(res => {
           let data
           if (res.status == 200) {

+ 29 - 1
src/views/salesReturnManagement/salesReturn/list.vue

@@ -181,6 +181,13 @@
               v-if="record.billStatus == 'WAIT_RECEIVE'&& $hasPermissions('B_newPickUp')"
               @click="handlePickUp(record)"
               id="salesReturn-edit-btn">申请提货</a-button>
+            <a-button
+              size="small"
+              type="link"
+              class="button-error"
+              v-if="record.billStatus == 'WAIT_RECEIVE'&&record.salesReturnBillSource=='PURCHASE'"
+              @click="handleCansel(record)"
+              id="salesReturn-cansel-btn">取消</a-button>
             <a-button
               size="small"
               type="link"
@@ -212,7 +219,7 @@ import verifyModal from './verifyModal.vue'
 import chooseDepartUserModal from './chooseDepartUserModal.vue'
 import rangeDate from '@/views/common/rangeDate.vue'
 import warehouse from '@/views/common/chooseWarehouse.js'
-import { salesReturnList, salesReturnQueryCount, salesReturnDel, salesReturnSubmit } from '@/api/salesReturn'
+import { salesReturnList, salesReturnQueryCount, salesReturnDel, salesReturnCancelBill, salesReturnSubmit } from '@/api/salesReturn'
 import moment from 'moment'
 import getDate from '@/libs/getDate.js'
 export default {
@@ -359,6 +366,27 @@ export default {
         this.$router.push({ name: 'billOfLadingList', query: { billNo: row.salesReturnBillNo } })
       }
     },
+    // 取消
+    handleCansel(row){
+      const _this = this
+      this.$confirm({
+        title: '提示',
+        content: '确认要取消吗?',
+        centered: true,
+        onOk () {
+          _this.spinning = true
+          salesReturnCancelBill({ salesReturnBillSn: row.salesReturnBillSn }).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.$refs.table.refresh()
+              _this.spinning = false
+            } else {
+              _this.spinning = false
+            }
+          })
+        }
+      })
+    },
     // 删除
     handleDel (row) {
       const _this = this

+ 2 - 2
vue.config.js

@@ -108,9 +108,9 @@ const vueConfig = {
     // If you want to turn on the proxy, please remosve the mockjs /src/main.jsL11
     proxy: {
       '/api': {
-        target: 'http://192.168.2.103/ocs-admin',
+        // target: 'http://192.168.2.117/ocs-admin',
         // target: 'https://t.ocs.360arrow.com/ocs-admin', //  练习
-        // target: 'https://p.ocs.360arrow.com/ocs-admin', //  预发布
+        target: 'https://p.ocs.360arrow.com/ocs-admin', //  预发布
         ws: false,
         changeOrigin: true,
         pathRewrite: {