Преглед изворни кода

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

李磊 пре 3 година
родитељ
комит
6e3961311e

+ 1 - 1
.env.development

@@ -1,7 +1,7 @@
 NODE_ENV=development
 VUE_APP_PREVIEW=true
 VUE_APP_API_BASE_URL=/api
-VUE_APP_WX_BASE_URL=//192.168.16.103:8602/ocs-admin/websocket/
+VUE_APP_WX_BASE_URL=/api/websocket/
 VUE_APP_VERSION=V1.0.1
 VUE_APP_ENVTIPS=开发环境
 VUE_APP_PRO_NAME=运营中心系统

+ 1 - 1
public/version.json

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

+ 8 - 0
src/api/allocateReturn.js

@@ -118,6 +118,14 @@ export const allocReturnDetailInsert = params => {
     method: 'post'
   })
 }
+// 批量添加退货明细
+export const allocReturnDetailInsertBatch = params => {
+  return axios({
+    url: '/allocReturnDetail/insertBatch',
+    data: params,
+    method: 'post'
+  })
+}
 // 分页查询调拨退货明细列表
 export const allocReturnDetailQueryPage = (params) => {
   const url = `/allocReturnDetail/queryPage/${params.pageNo}/${params.pageSize}`

+ 36 - 0
src/api/expenseManagement.js

@@ -28,6 +28,15 @@ export const expenseAccountList = (params) => {
     method: 'post'
   })
 }
+// 新增再次编辑
+export const expenseAccountAgainEdit = (params) => {
+  const url = `/expenseAccount/againEdit/${params.expenseAccountSn} `
+  return axios({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
 // 报销单详情
 export const expenseAccountDetail = (params) => {
   return axios({
@@ -149,6 +158,15 @@ export const expenseAccountDetailList = (params) => {
     method: 'post'
   })
 }
+// 费用报销明细统计
+export const expenseAccountDetailCount = (params) => {
+  const url = `/report/expenseAcctDetailReport/queryDetailReport/count`
+  return axios({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
 
 //  费用报销明细单 导出
 export const expenseAcctDetailReport = (params) => {
@@ -184,3 +202,21 @@ export const queryDingTalkDeptUser = (params) => {
     method: 'post'
   })
 }
+
+ // 同步钉钉部门人员
+ export const refashDingTalkAllDeptUser = (params) => {
+   return axios({
+     url: `/dingTalk/syncAllDeptUser `,
+     data: params,
+     method: 'post'
+   })
+ }
+ 
+// 获取所以部门人员
+ export const getDingTalkAllDeptUser = (params) => {
+   return axios({
+     url: `/dingTalk/getAllDeptUser`,
+     data: params,
+     method: 'post'
+   })
+ }

+ 34 - 6
src/api/product.js

@@ -127,7 +127,35 @@ export const productPricingAudit = (params) => {
   })
 }
 
-//  产品  上线审核  列表  分页
+// 产品上线、下线分页接口
+export const productLogList = (params) => {
+  const url = `/productLog/queryPage/${params.pageNo}/${params.pageSize}`
+  delete params.pageNo
+  delete params.pageSize
+  return axios({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+// 产品上线、下线审核
+export const productLogAudit = (params) => {
+  return axios({
+    url: `/productLog/audit`,
+    data: params,
+    method: 'post'
+  })
+}
+// 批量上线、下线审核
+export const productLogAuditBatch = (params) => {
+  return axios({
+    url: `/productLog/auditBatch`,
+    data: params,
+    method: 'post'
+  })
+}
+
+//  产品  上线审核  列表  分页 (已废弃)
 export const productOnlineList = (params) => {
   const url = `/product/online/queryPage/${params.pageNo}/${params.pageSize}`
   delete params.pageNo
@@ -138,14 +166,14 @@ export const productOnlineList = (params) => {
     method: 'post'
   })
 }
-//  产品 上线审核  审核
+//  产品 上线审核  审核(已废弃)
 export const productOnlineAudit = (params) => {
   return axios({
     url: `/product/auditOnline/${params.sn}`,
     method: 'get'
   })
 }
-//  产品 批量上线审核
+//  产品 批量上线审核(已废弃)
 export const productBatchOnlineAudit = (params) => {
   return axios({
     url: '/product/batchAuditOnline',
@@ -154,7 +182,7 @@ export const productBatchOnlineAudit = (params) => {
   })
 }
 
-//  产品  下线审核  列表  分页
+//  产品  下线审核  列表  分页 (已废弃)
 export const productOfflineList = (params) => {
   const url = `/product/offline/queryPage/${params.pageNo}/${params.pageSize}`
   delete params.pageNo
@@ -165,14 +193,14 @@ export const productOfflineList = (params) => {
     method: 'post'
   })
 }
-//  产品 下线审核  审核
+//  产品 下线审核  审核(已废弃)
 export const productOfflineAudit = (params) => {
   return axios({
     url: `/product/auditOffline/${params.sn}`,
     method: 'get'
   })
 }
-//  产品 批量下线审核
+//  产品 批量下线审核(已废弃)
 export const productBatchOfflineAudit = (params) => {
   return axios({
     url: '/product/batchAuditOffline',

+ 9 - 0
src/api/salesDetail.js

@@ -9,6 +9,15 @@ export const salesDetailDel = (params) => {
   })
 }
 
+// 批量删除
+export const salesDetailBatchDel = (params) => {
+  return axios({
+    url: `/sales/detail/delete/batch`,
+    data: params,
+    method: 'post'
+  })
+}
+
 // 一键发货
 export const salesDetailDispatchByOneKey = (params) => {
   return axios({

+ 81 - 7
src/views/allocationManagement/transferReturn/editGrp.vue

@@ -40,25 +40,35 @@
             <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-col :md="5" :sm="24">
                     <a-form-item label="调拨单号" prop="allocateNo">
                       <a-input id="editGrap-allocateNo" v-model.trim="queryParam.allocateNo" placeholder="请输入调拨单号" allowClear />
                     </a-form-item>
                   </a-col>
-                  <a-col :md="6" :sm="24">
+                  <a-col :md="5" :sm="24">
                     <a-form-item label="产品编码" prop="productCode">
                       <a-input id="editGrap-productCode" v-model.trim="queryParam.productCode" placeholder="请输入产品编码" allowClear />
                     </a-form-item>
                   </a-col>
-                  <a-col :md="6" :sm="24">
+                  <a-col :md="5" :sm="24">
                     <a-form-item label="产品名称" prop="productName">
                       <a-input id="editGrap-productName" v-model.trim="queryParam.productName" placeholder="请输入产品名称" allowClear />
                     </a-form-item>
                   </a-col>
-                  <a-col :md="6" :sm="24" style="margin-bottom: 10px;">
+                  <a-col :md="4" :sm="24" style="margin-bottom: 10px;">
                     <a-button type="primary" @click="$refs.table.refresh(true)" :disabled="disabled" id="storeTransferOutList-refresh">查询</a-button>
                     <a-button style="margin-left: 8px" @click="resetSearchForm" :disabled="disabled" id="storeTransferOutList-reset">重置</a-button>
                   </a-col>
+                  <a-col :md="5" :sm="24" style="margin-bottom: 10px;text-align: right;">
+                    <span>已选{{ selectTotal }}项</span>
+                    <a-button
+                      style="margin:0 15px;"
+                      size="small"
+                      type="primary"
+                      class="button-info"
+                      id="salesEdit-plDel-btn"
+                      @click="handleBatchAdd">批量添加</a-button>
+                  </a-col>
                 </a-row>
               </a-form>
             </div>
@@ -73,6 +83,8 @@
               :columns="columns"
               :customRow="handleClickRow"
               :data="loadData"
+              :row-selection="{ columnWidth: 40, getCheckboxProps: record => ({ props: { disabled: !record.refundableQty } }) }"
+              @rowSelection="rowSelectionFun"
               :scroll="{ y: 300 }"
               :defaultLoadData="false"
               bordered>
@@ -230,8 +242,8 @@ import {
   allocReturnDetailInsert,
   allocReturnDetailUpdate,
   allocateReturnSubmit,
-  allocReturnDetailDelete
-  // allocateBillBatchInsert
+  allocReturnDetailDelete,
+  allocReturnDetailInsertBatch
 } from '@/api/allocateReturn'
 
 export default {
@@ -295,10 +307,14 @@ export default {
         })
       },
       basicInfoData: null, // 基本信息
-      openGuideModal: false //  导入产品引导
+      openGuideModal: false, //  导入产品引导
+      rowSelectionInfo: null
     }
   },
   computed: {
+    selectTotal () {
+      return this.rowSelectionInfo && this.rowSelectionInfo.selectedRowKeys.length || 0
+    },
     columns () {
       const arr = [
         { title: '序号', dataIndex: 'no', width: '4%', align: 'center' },
@@ -331,6 +347,63 @@ export default {
     }
   },
   methods: {
+    // 表格选中项
+    rowSelectionFun (obj) {
+      this.rowSelectionInfo = obj || null
+    },
+    // 批量添加
+    handleBatchAdd () {
+      const _this = this
+      if (!_this.rowSelectionInfo || (_this.rowSelectionInfo && _this.rowSelectionInfo.selectedRowKeys.length < 1)) {
+        _this.$message.warning('请在选择要添加的产品后再进行批量操作!')
+        return
+      }
+      const obj = []
+      _this.rowSelectionInfo && _this.rowSelectionInfo.selectedRows.map(item => {
+        obj.push({
+          'allocateNo': item.allocateNo,
+          'allocateSn': item.allocateSn,
+          'oldPrice': item.oldPrice,
+          'price': item.returnPrice,
+          'productSn': item.productSn,
+          'productCode': item.productCode
+        })
+      })
+      this.$confirm({
+        title: '提示',
+        content: '已选产品' + obj.length + '项,确认要批量添加吗?',
+        centered: true,
+        onOk () {
+          _this.spinning = true
+          allocReturnDetailInsertBatch({
+            allocateReturnSn: _this.$route.params.sn,
+            detailDtoList: obj
+          }).then(res => {
+            if (res.status == 200) {
+              _this.$refs.table.clearSelected() // 清空表格选中项
+              _this.getDetail(true)
+              _this.$refs.chooseTable.refresh()
+              if (res.data.failMessage.length) {
+                _this.showFailMessage(res.data)
+              }
+            }
+            _this.spinning = false
+          })
+        }
+      })
+    },
+    showFailMessage (data) {
+      const h = this.$createElement
+      const htmlStr = [h('p', data.message)]
+      for (let i = 0; i < data.failMessage.length; i++) {
+        htmlStr.push(h('p', data.failMessage[i]))
+      }
+      this.$info({
+        title: '操作提示',
+        content: h('div', {}, htmlStr),
+        centered: true
+      })
+    },
     // 修改备注
     handleEditRemark () {
       const _this = this
@@ -366,6 +439,7 @@ export default {
       this.queryParam.productName = ''
       this.queryParam.allocateNo = ''
       this.$refs.table.refresh(true)
+      this.$refs.table.clearSelected() // 清空表格选中项
     },
     // 双击快速添加
     handleClickRow (record) {

+ 31 - 28
src/views/common/dingDepartUser.js

@@ -1,14 +1,14 @@
-import { getDingTalkDepartmentList, queryDingTalkDeptUser } from '@/api/expenseManagement'
+import { getDingTalkAllDeptUser, refashDingTalkAllDeptUser } from '@/api/expenseManagement'
 const DingDepartUser = {
   template: `
       <a-tree-select
+          :disabled="disabled"
           :value="defaultVal"
           tree-data-simple-mode
           style="width: 100%"
           :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
           :tree-data="treeData"
           :placeholder="placeholder"
-          :load-data="onLoadData"
           multiple
           treeCheckable
           :treeCheckStrictly="true"
@@ -30,6 +30,10 @@ const DingDepartUser = {
     placeholder: {
       type: String,
       default: '请选择人员'
+    },
+    disabled:{
+      type: Boolean,
+      default: false
     }
   },
   data() {
@@ -39,7 +43,7 @@ const DingDepartUser = {
     };
   },
   mounted() {
-    this.genTreeNode(1)
+    this.genTreeNode()
   },
   watch: {
     value(newValue, oldValue) {
@@ -63,7 +67,7 @@ const DingDepartUser = {
       const ret = []
       data.map(item => {
         if(type == 'bm'){
-          ret.push({
+          const node = {
             title: item.name,
             id:item.deptId,
             value: item.deptId,
@@ -72,11 +76,15 @@ const DingDepartUser = {
             createDeptGroup: item.createDeptGroup,
             disableCheckbox: true,
             checkable: false
-          })
+          }
+          if(item.deptUserList||item.deptList){
+            node.children = this.formatData(item.deptUserList||item.deptList,item.deptList?'bm':'yg')
+          }
+          ret.push(node)
         }else{
           ret.push({
             title: item.name,
-            id:item.userid,
+            id: item.userid,
             value: item.userid,
             pId: item.parentId,
             avatar: item.avatar,
@@ -91,29 +99,24 @@ const DingDepartUser = {
       })
       return ret
     },
-    // 获取部门
-    genTreeNode(parentId, isLeaf = false) {
-       Promise.all([
-         getDingTalkDepartmentList({deptId:parentId}),
-         queryDingTalkDeptUser({deptId:parentId,pageNo:1,pageSize:10})
-         ]).then(res => {
-          const res1 = res[0].data||[]
-          const res2 = res[1].data||[]
-          this.treeData = this.treeData.concat(this.formatData(res1,'bm')).concat(this.formatData(res2,'yg'));
-          if(res1.length==0&&res2.length==0){
-            this.$message.info("没有下一级了")
-          }
-       })
-    },
-    onLoadData(treeNode) {
-      return new Promise(resolve => {
-        const { value } = treeNode.dataRef;
-         this.genTreeNode(value)
-         setTimeout(()=>{
-           resolve();
-         },1000)
-      });
+    // 获取部门人员
+    async genTreeNode() {
+       let ret = await getDingTalkAllDeptUser().then(res => res.data)
+       const res1 = ret.deptList||[]
+       const res2 = ret.deptUserList||[]
+       this.treeData = this.treeData.concat(this.formatData(res1,'bm')).concat(this.formatData(res2,'yg'));
     },
+    // 更新人员数据
+    updateDeptUser(){
+      refashDingTalkAllDeptUser().then(res => {
+        this.$message.info(res.message)
+        if(res.status == 200){
+          this.treeData = []
+          this.genTreeNode()
+        }
+        this.$emit("loaded")
+      })
+    }
   },
 };
 

+ 26 - 7
src/views/common/productCodeList.vue

@@ -61,6 +61,12 @@ export default {
         this.fetching = false
       })
     },
+    getRow (cur) {
+      const _this = this
+      const ind = _this.data.findIndex(item => item.productSn == cur.key)
+      cur.row = ind != -1 ? _this.data[ind] : undefined
+      return cur
+    },
     handleChange (value) {
       const _this = this
       if (this.mode == 'default') { //  单选
@@ -69,13 +75,23 @@ export default {
           value.row = ind != -1 ? _this.data[ind] : undefined
         }
       } else if (this.mode == 'multiple') { //  多选
-        if (value.length > 0) {
-          const ind = _this.data.findIndex(item => item.productSn == value[value.length - 1].key)
-          value[value.length - 1].row = ind != -1 ? _this.data[ind] : undefined
-        }
-        if (this.lastData && this.lastData.length > 0) {
-          this.lastData = this.lastData.concat(value[value.length - 1])
-          value = this.lastData
+        // 新增
+        if (this.lastData.length < value.length) {
+          if (value.length <= 5) {
+            const ret = this.getRow(value[value.length - 1])
+            value = [...this.lastData, ret]
+          } else {
+            this.$message.info('最多选择5个通用编码')
+            return false
+          }
+        } else {
+          // 删除
+          value.map(item => {
+            const r = this.lastData.find(k => k.key == item.key)
+            if (r) {
+              item.row = r.row
+            }
+          })
         }
       }
       Object.assign(this, {
@@ -83,6 +99,9 @@ export default {
         data: [],
         fetching: false
       })
+      if (this.dealerName) {
+        this.lastData = JSON.parse(JSON.stringify(this.dealerName))
+      }
       this.$emit('change', value || { key: undefined }, this.id)
     },
     resetForm () {

+ 13 - 0
src/views/expenseManagement/expenseReimbursement/chooseDepartUserModal.vue

@@ -20,7 +20,10 @@
             :wrapper-col="formItemLayout.wrapperCol">
             <a-form-model-item label="审批人员" prop="approvers">
               <dingDepartUser
+                ref="departUserApp"
+                @loaded="uploading=false"
                 id="departUser-approvers"
+                :disabled="uploading"
                 v-model="form.approvers"
                 @change="changeApprovers"
                 allowClear
@@ -29,6 +32,9 @@
             </a-form-model-item>
             <a-form-model-item label="抄送人" prop="ccList">
               <dingDepartUser
+                ref="departUserCc"
+                @loaded="uploading=false"
+                :disabled="uploading"
                 id="departUser-ccList"
                 v-model="form.ccList"
                 allowClear
@@ -39,6 +45,7 @@
         </div>
         <div class="btn-cont">
           <a-button type="primary" id="departUser-save" @click="handleSave">确定</a-button>
+          <a-button :loading="uploading" style="margin-left: 15px;" @click="updateUser">刷新人员</a-button>
           <a-button id="departUser-back" @click="isShow = false" style="margin-left: 15px;">取消</a-button>
         </div>
       </div>
@@ -59,6 +66,7 @@ export default {
   },
   data () {
     return {
+      uploading: false,
       spinning: false,
       isShow: this.openModal, //  是否打开弹框
       title: '',
@@ -81,6 +89,11 @@ export default {
     }
   },
   methods: {
+    updateUser () {
+      this.uploading = true
+      this.$refs.departUserApp.updateDeptUser()
+      this.$refs.departUserCc.updateDeptUser()
+    },
     changeApprovers (value) {
       this.form.approvers = value
       this.$refs.ruleForm.clearValidate()

+ 1 - 0
src/views/expenseManagement/expenseReimbursement/epenseCdfModal.vue

@@ -176,6 +176,7 @@ export default {
     splitObjTypeChange (index) {
       const row = this.dataList[index]
       console.log(index, row.splitObjType)
+      row.splitObjSn = undefined
       // 只有部门有承担人员
       this.$set(row, 'childDetailSplitList', row.splitObjType == 'DEPARTMENT' ? [{
         splitObjType: 'EMPLOYEE',

+ 2 - 1
src/views/expenseManagement/expenseReimbursement/epenseDetailModal.vue

@@ -83,7 +83,7 @@
                     style="width: 100%;color: red;font-weight: bold;"
                     id="epenseDetailModal-expense"
                     :disabled="true"
-                    v-model="form.expense"
+                    :value="Math.abs(form.expense) * -1"
                   />
                 </a-form-model-item>
               </a-col>
@@ -272,6 +272,7 @@ export default {
           form.provinceSn = form.provinceSn ? form.provinceSn : ''
           form.citySn = form.citySn ? form.citySn : ''
           form.cityName = form.cityName ? form.cityName : ''
+          form.expense = Math.abs(form.expense)
           console.log(form)
           delete form.subareaNames
           delete form.subareaSns

+ 30 - 1
src/views/expenseManagement/expenseReimbursement/list.vue

@@ -122,6 +122,15 @@
           >
             审核进度
           </a-button>
+          <a-button
+            v-if="record.state=='AUDIT_REJECT'"
+            size="small"
+            type="link"
+            class="button-info"
+            @click="againEdit(record)"
+          >
+            再次编辑
+          </a-button>
           <!-- <span v-if="record.state=='AUDIT_REJECT' || record.state=='AUDIT_PASS'">--</span> -->
         </template>
       </s-table>
@@ -141,7 +150,7 @@ import subarea from '@/views/common/subarea.js'
 import employee from './employee.js'
 import { STable, VSelect } from '@/components'
 import verifyModal from './verifyModal.vue'
-import { expenseAccountList, expenseAccountDelete } from '@/api/expenseManagement'
+import { expenseAccountList, expenseAccountDelete, expenseAccountAgainEdit } from '@/api/expenseManagement'
 import baseDataModal from './baseDataModal.vue'
 export default {
   name: 'ExpenseReimbursementList',
@@ -249,6 +258,26 @@ export default {
       this.openModal = true
       this.itemSn = row.expenseAccountSn
     },
+    // 再次编辑
+    againEdit (row) {
+      const _this = this
+      this.$confirm({
+        title: '操作提示',
+        content: '系统将自动生成一个新的费用报销单,与原审核不通过的单据内容相同。您可以对新单据进行编辑、提交等操作,原单据保持不变,确认操作吗?',
+        centered: true,
+        closable: true,
+        onOk () {
+          _this.spinning = true
+          expenseAccountAgainEdit({ expenseAccountSn: row.expenseAccountSn }).then(res => {
+            if (res.status == 200) {
+              _this.$message.success(res.message)
+              _this.resetSearchForm()
+            }
+            _this.spinning = false
+          })
+        }
+      })
+    },
     // 重置
     resetSearchForm () {
       this.queryParam = {

+ 9 - 9
src/views/expenseManagement/expenseReimbursement/previewModal.vue

@@ -42,28 +42,28 @@
           <thead>
             <tr>
               <th style="padding:5px 10px;width:8%;">序号</th>
-              <th style="padding:5px 10px;width:17%;">记账方</th>
-              <th style="padding:5px 10px;width:15%;">区域/省/市</th>
-              <th style="padding:5px 10px;width:12%;">记账费用</th>
-              <th style="padding:5px 10px;width:28%;">费用承担方</th>
+              <th style="padding:5px 10px;width:26%;">记账方</th>
+              <!-- <th style="padding:5px 10px;width:15%;">区域/省/市</th> -->
+              <th style="padding:5px 10px;width:10%;">记账费用</th>
+              <th style="padding:5px 10px;width:26%;">费用承担方</th>
               <th style="padding:5px 10px;width:20%;">产品信息</th>
             </tr>
           </thead>
           <tbody>
             <tr v-for="(item,index) in fyListData" :key="index">
               <td style="text-align: center;width:8%;">{{ index+1 }}</td>
-              <td style="text-align: left;width:17%;padding:5px 10px;">
+              <td style="text-align: left;width:26%;padding:5px 10px;">
                 <div>{{ item.accountTypeDictValue }}</div>
                 <div>{{ item.accountName||'' }}</div>
                 <div v-if="item.accountNameFnumber">({{ item.accountNameFnumber }})</div>
               </td>
-              <td style="text-align: left;width:15%;padding:5px 10px;">
+              <!-- <td style="text-align: left;width:15%;padding:5px 10px;">
                 <div>{{ item.subareaNames }}</div>
                 <div>{{ item.provinceName }}</div>
                 <div>{{ item.cityName }}</div>
-              </td>
-              <td style="text-align: right;width:12%;padding:5px 10px;">{{ item.expense||item.expense==0?item.expense.toFixed(2):'' }}</td>
-              <td style="text-align: left;width:28%;padding:5px 10px;vertical-align: top;">
+              </td> -->
+              <td style="text-align: right;width:10%;padding:5px 10px;">{{ item.expense||item.expense==0?item.expense.toFixed(2):'' }}</td>
+              <td style="text-align: left;width:26%;padding:5px 10px;vertical-align: top;">
                 <div v-for="(ditem,index) in item.detailSplitList" :key="ditem.id+'-'+index" style="padding: 3px 0;" >
                   {{ ditem.splitObjName }}
                   <span v-if="ditem.splitObjFnumber">({{ ditem.splitObjFnumber }})</span>

+ 18 - 1
src/views/expenseManagement/expenseReimbursementDetail/list.vue

@@ -150,6 +150,15 @@
           </a-row>
         </a-form>
       </div>
+      <!-- alert -->
+      <a-alert type="info" v-if="countData" style="margin-bottom:10px">
+        <div slot="message">
+          <div>
+            总单数:<strong>{{ countData&&(countData.detailNum || countData.detailNum==0) ? countData.detailNum : '--' }}</strong>;
+            总费用金额:<strong>{{ countData&&(countData.expense || countData.expense==0) ? countData.expense : '--' }}</strong>;
+          </div>
+        </div>
+      </a-alert>
       <!-- 列表 -->
       <s-table
         class="sTable fixPagination"
@@ -180,7 +189,7 @@ import department from '../expenseReimbursement/department.js'
 import employee from '../expenseReimbursement/employee.js'
 import custList from '@/views/common/custList.vue'
 import supplier from '@/views/common/supplier.js'
-import { expenseAccountDetailList, expenseAcctDetailReport } from '@/api/expenseManagement'
+import { expenseAccountDetailList, expenseAcctDetailReport, expenseAccountDetailCount } from '@/api/expenseManagement'
 import { hdExportExcel } from '@/libs/exportExcel'
 moment.locale('zh-cn')
 export default {
@@ -199,6 +208,7 @@ export default {
         moment(getDate.getCurrMonthDays().starttime, 'YYYY-MM-DD'),
         moment(getDate.getCurrMonthDays().endtime, 'YYYY-MM-DD')
       ],
+      countData: null,
       // 查询参数
       queryParam: {
         expenseDate: undefined, // 月份
@@ -231,6 +241,8 @@ export default {
         if (params.expenseDate) {
           params.expenseDate = params.expenseDate + '-01'
         }
+        // 统计
+        this.getDetailCount(params)
         return expenseAccountDetailList(params).then(res => {
           let data
           if (res.status == 200) {
@@ -301,6 +313,11 @@ export default {
       this.queryParam.childSplitObjSn = undefined
       this.$refs.custList.dealerName = []
     },
+    getDetailCount (params) {
+      expenseAccountDetailCount(params).then(res => {
+        this.countData = res.data || null
+      })
+    },
     //  导出
     handleExport () {
       const _this = this

+ 39 - 5
src/views/productManagement/productInfo/list.vue

@@ -15,13 +15,13 @@
                 <a-input id="productInfoList-queryWord" v-model.trim="queryParam.queryWord" allowClear placeholder="请输入产品编码/原厂编码"/>
               </a-form-item>
             </a-col>
-            <a-col :md="5" :sm="24">
+            <a-col :md="4" :sm="24">
               <a-form-item label="品牌">
                 <ProductBrand id="productInfoList-productBrandSn" v-model="queryParam.productBrandSn"></ProductBrand>
               </a-form-item>
             </a-col>
             <template v-if="advanced">
-              <a-col :md="7" :sm="24">
+              <a-col :md="4" :sm="24">
                 <a-form-item label="产品分类">
                   <a-cascader
                     @change="changeProductType"
@@ -35,16 +35,28 @@
                     v-model="productType" />
                 </a-form-item>
               </a-col>
-              <a-col :md="6" :sm="24">
+              <a-col :md="4" :sm="24">
                 <a-form-item label="产品状态">
                   <v-select code="PRODUCT_STATUS" id="productInfoList-state" v-model="queryParam.state" allowClear placeholder="请选择产品状态"></v-select>
                 </a-form-item>
               </a-col>
-              <a-col :md="6" :sm="24">
+              <a-col :md="4" :sm="24">
                 <a-form-item label="定价状态">
                   <v-select code="PRICING_STATUS" id="productInfoList-pricingState" v-model="queryParam.pricingState" allowClear placeholder="请选择定价状态"></v-select>
                 </a-form-item>
               </a-col>
+              <a-col :md="4" :sm="24">
+                <a-form-item label="产品图片">
+                  <a-select id="productInfoList-picFlag" v-model="queryParam.picFlag" allowClear placeholder="请选择产品图片">
+                    <a-select-option value="1">
+                      有图片
+                    </a-select-option>
+                    <a-select-option value="0">
+                      无图片
+                    </a-select-option>
+                  </a-select>
+                </a-form-item>
+              </a-col>
             </template>
             <a-col :md="7" :sm="24" style="margin-bottom: 10px;">
               <a-button type="primary" @click="$refs.table.refresh(true)" :disabled="disabled" id="productInfoList-refresh">查询</a-button>
@@ -128,6 +140,13 @@
           <span v-if="record.productTypeName2 || record.productTypeName3">{{ record.productTypeName2 }} {{ record.productTypeName3 ? '>' : '' }} {{ record.productTypeName3 }}</span>
           <span v-else>--</span>
         </template>
+        <!-- 产品图片 -->
+        <template slot="imageUrl" slot-scope="text, record">
+          <div v-if="record.productPicList && record.productPicList.length>0">
+            <img :src="record.productPicList[0].imageUrl+'?x-oss-process=image/resize,h_30,m_lfit' || ''" width="30" height="30" class="imageUrl" @click="inited(record.productPicList)" />
+          </div>
+          <span v-else>--</span>
+        </template>
         <!-- 操作 -->
         <template slot="action" slot-scope="text, record">
           <a-button
@@ -210,7 +229,8 @@ export default {
         productTypeSn2: '', //  产品二级分类
         productTypeSn3: '', //  产品三级分类
         state: undefined, //  产品状态
-        pricingState: undefined //  定价状态
+        pricingState: undefined, //  定价状态
+        picFlag: undefined
       },
       productType: [],
       disabled: false, //  查询、重置按钮是否可操作
@@ -227,6 +247,7 @@ export default {
         { title: '最近修改时间', dataIndex: 'updateDate', 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: '产品图片', scopedSlots: { customRender: 'imageUrl' }, width: '8%', align: 'center' },
         { title: '操作', scopedSlots: { customRender: 'action' }, width: '15%', align: 'center' }
       ],
       loadingAudit: false,
@@ -332,6 +353,18 @@ export default {
         }
       })
     },
+    // 预览图片
+    inited (viewer) {
+      if (viewer) {
+        const imageUrl = []
+        viewer.map(item => {
+          imageUrl.push(item.imageUrl)
+        })
+        this.$viewerApi({
+          images: imageUrl
+        })
+      }
+    },
     // 批量上线
     handleBatchLaunch () {
       const _this = this
@@ -403,6 +436,7 @@ export default {
       this.queryParam.productTypeSn3 = ''
       this.queryParam.state = undefined
       this.queryParam.pricingState = undefined
+      this.queryParam.picFlag = undefined
       this.productType = []
       this.$refs.table.refresh(true)
     },

+ 1 - 0
src/views/productManagement/productInfo/offlineModal.vue

@@ -132,6 +132,7 @@ export default {
         if (valid) {
           const params = JSON.parse(JSON.stringify(_this.form))
           params.offlineProductList = _this.loadData
+          console.log(params)
           _this.spinning = true
           productOffline(params).then(res => {
             if (res.status == 200) {

+ 181 - 120
src/views/productManagement/productLaunchAudit/list.vue

@@ -1,115 +1,115 @@
 <template>
-  <a-card size="small" :bordered="false" class="productLaunchAuditList-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="产品名称">
-                <a-input id="productLaunchAuditList-name" v-model.trim="queryParam.name" allowClear placeholder="请输入产品名称"/>
-              </a-form-item>
-            </a-col>
-            <a-col :md="6" :sm="24">
-              <a-form-item label="产品编码">
-                <a-input id="productLaunchAuditList-code" v-model.trim="queryParam.code" allowClear placeholder="请输入产品编码"/>
-              </a-form-item>
-            </a-col>
-            <a-col :md="6" :sm="24">
-              <a-form-item label="审核状态">
-                <v-select
-                  v-model="queryParam.state"
-                  ref="state"
-                  id="productLaunchAuditList-state"
-                  code="PRODUCT_ONOFFLINE_STATUS"
-                  placeholder="请选择审核状态"
-                  allowClear></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)" :disabled="disabled" id="productLaunchAuditList-refresh">查询</a-button>
-              <a-button style="margin-left: 5px" @click="resetSearchForm" :disabled="disabled" id="productLaunchAuditList-reset">重置</a-button>
-            </a-col>
-          </a-row>
-        </a-form>
-      </div>
-      <!-- 列表 -->
-      <div style="margin-bottom: 10px">
-        <a-button type="primary" v-if="$hasPermissions('B_productLaunchAudit_batchAudit')" id="productLaunchAudit-export" :loading="loading" @click="handleBatchAudit">批量审核</a-button>
-        <span style="margin-left: 5px" v-if="$hasPermissions('B_productLaunchAudit_batchAudit')">
-          <template v-if="rowSelectionInfo && rowSelectionInfo.selectedRowKeys.length>0">{{ `已选 ${rowSelectionInfo.selectedRowKeys.length} 项` }}</template>
-        </span>
-      </div>
-      <s-table
-        class="sTable fixPagination"
-        ref="table"
-        :style="{ height: tableHeight+84.5+'px' }"
-        size="small"
-        :rowKey="(record) => record.productSn"
-        rowKeyName="productSn"
-        :row-selection="$hasPermissions('B_productLaunchAudit_batchAudit')?{ columnWidth: 40, getCheckboxProps: record => ({ props: { disabled: record.state != 'WAIT_ONLINE_AUDIT' } }) }:null"
-        @rowSelection="rowSelectionFun"
-        :columns="columns"
-        :data="loadData"
-        :scroll="{ y: tableHeight }"
-        :defaultLoadData="false"
-        bordered>
-        <!-- 产品分类 -->
-        <template slot="productType" slot-scope="text, record">
-          <span v-if="record.productTypeName2 || record.productTypeName3">{{ record.productTypeName2 }} {{ record.productTypeName3 ? '>' : '' }} {{ record.productTypeName3 }}</span>
-          <span v-else>--</span>
-        </template>
-        <!-- 操作 -->
-        <template slot="action" slot-scope="text, record">
-          <a-button
-            size="small"
-            type="link"
-            v-if="record.state=='WAIT_ONLINE_AUDIT' && $hasPermissions('B_productLaunchAudit_audit')"
-            class="button-warning"
-            @click="handleAudit(record)"
-            id="productLaunchAuditList-audit-btn">审核</a-button>
-          <span v-else>--</span>
-        </template>
-      </s-table>
-    </a-spin>
-  </a-card>
+  <div class="productLaunchAuditList-wrap">
+    <!-- 状态 -->
+    <div style="background-color: #fff;margin-bottom: 5px;">
+      <v-select
+        v-model="queryParam.bizState"
+        ref="state"
+        showType="tabs"
+        @change="resetSearchForm()"
+        code="PRODUCT_LOG_BIZ_STATE"
+        allowClear></v-select>
+    </div>
+    <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="productLaunchAuditList-name" v-model.trim="queryParam.name" allowClear placeholder="请输入产品名称"/>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="产品编码">
+                  <a-input id="productLaunchAuditList-code" v-model.trim="queryParam.code" allowClear placeholder="请输入产品编码"/>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="24">
+                <a-form-item label="提交时间">
+                  <rangeDate ref="rangeDate" :value="time" @change="dateChange" />
+                </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="productLaunchAuditList-refresh">查询</a-button>
+                <a-button style="margin-left: 5px" @click="resetSearchForm" :disabled="disabled" id="productLaunchAuditList-reset">重置</a-button>
+              </a-col>
+            </a-row>
+          </a-form>
+        </div>
+        <!-- 列表 -->
+        <div style="margin-bottom: 10px">
+          <a-button type="primary" v-if="$hasPermissions('B_productLaunchAudit_batchAudit')&&queryParam.bizState == 'WAIT'" id="productLaunchAudit-export" :loading="loading" @click="handleBatchAudit">批量审核</a-button>
+          <span style="margin-left: 5px" v-if="$hasPermissions('B_productLaunchAudit_batchAudit')">
+            <template v-if="rowSelectionInfo && rowSelectionInfo.selectedRowKeys.length>0">{{ `已选 ${rowSelectionInfo.selectedRowKeys.length} 项` }}</template>
+          </span>
+        </div>
+        <s-table
+          class="sTable fixPagination"
+          ref="table"
+          :style="{ height: tableHeight+84.5+'px' }"
+          size="small"
+          :rowKey="(record) => record.productLogSn"
+          rowKeyName="productLogSn"
+          :row-selection="$hasPermissions('B_productLaunchAudit_batchAudit')&&queryParam.bizState == 'WAIT'?{ columnWidth: 40 }:null"
+          @rowSelection="rowSelectionFun"
+          :columns="columns"
+          :data="loadData"
+          :scroll="{ y: tableHeight }"
+          :defaultLoadData="false"
+          bordered>
+          <!-- 产品分类 -->
+          <template slot="productType" slot-scope="text, record">
+            <span v-if="record.productTypeName2 || record.productTypeName3">{{ record.productTypeName2 }} {{ record.productTypeName3 ? '>' : '' }} {{ record.productTypeName3 }}</span>
+            <span v-else>--</span>
+          </template>
+          <!-- 操作 -->
+          <template slot="action" slot-scope="text, record">
+            <a-button
+              size="small"
+              type="link"
+              v-if="record.bizState=='WAIT' && $hasPermissions('B_productLaunchAudit_audit')"
+              class="button-warning"
+              @click="handleAudit(record)"
+              id="productLaunchAuditList-audit-btn">审核</a-button>
+            <span v-else>--</span>
+          </template>
+        </s-table>
+      </a-spin>
+    </a-card>
+  </div>
 </template>
 
 <script>
+import rangeDate from '@/views/common/rangeDate.vue'
 import { commonMixin } from '@/utils/mixin'
 import { STable, VSelect } from '@/components'
-import { productOnlineList, productBatchOnlineAudit, productOnlineAudit } from '@/api/product'
+import { productLogList, productLogAuditBatch, productLogAudit } from '@/api/product'
 export default {
   name: 'ProductLaunchAuditList',
   mixins: [commonMixin],
-  components: { STable, VSelect },
+  components: { STable, VSelect, rangeDate },
   data () {
     return {
       spinning: false,
+      time: [],
       queryParam: { //  查询条件
+        beginDate: '',
+        endDate: '',
         name: '', //  名称
         code: '', //  编码
-        state: undefined //  状态
+        bizType: 'ONLINE', // 上线
+        bizState: 'WAIT' //  状态
       },
       tableHeight: 0,
       disabled: false, //  查询、重置按钮是否可操作
-      columns: [
-        { title: '产品名称', dataIndex: 'name', align: 'center', width: '20%', customRender: function (text) { return text || '--' }, ellipsis: true },
-        { title: '产品编码', dataIndex: 'code', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '产品分类', scopedSlots: { customRender: 'productType' }, width: '15%', align: 'center' },
-        { title: '提交时间', dataIndex: 'onlineSubmitTime', width: '13%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '提交人', dataIndex: 'onlineSubmitPerson', width: '10%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
-        { title: '审核状态', dataIndex: 'stateDictValue', width: '7%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '审核时间', dataIndex: 'onlineAuditTime', width: '13%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '审核人', dataIndex: 'onlineAuditPerson', width: '8%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
-        { title: '操作', scopedSlots: { customRender: 'action' }, width: '6%', align: 'center' }
-      ],
       loading: false,
       // 加载数据方法 必须为 Promise 对象
       loadData: parameter => {
         this.disabled = true
         this.spinning = true
-        return productOnlineList(Object.assign(parameter, this.queryParam)).then(res => {
+        return productLogList(Object.assign(parameter, this.queryParam)).then(res => {
           let data
           if (res.status == 200) {
             data = res.data
@@ -122,7 +122,31 @@ export default {
       rowSelectionInfo: null
     }
   },
+  computed: {
+    columns () {
+      const arr = [
+        { title: '产品名称', dataIndex: 'name', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '产品编码', dataIndex: 'code', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品分类', scopedSlots: { customRender: 'productType' }, width: '15%', align: 'center' },
+        { title: '提交时间', dataIndex: 'submitTime', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '提交人', dataIndex: 'submitPerson', width: '10%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '审核状态', dataIndex: 'bizStateDictValue', width: '10%', align: 'center', customRender: function (text) { return text || '--' } }
+      ]
+      if (this.queryParam.bizState == 'WAIT') {
+        arr.splice(6, 1, { title: '操作', scopedSlots: { customRender: 'action' }, width: '6%', align: 'center' })
+      } else {
+        arr.splice(6, 1, { title: '审核时间', dataIndex: 'auditTime', width: '10%', align: 'center', customRender: function (text) { return text || '--' } })
+        arr.splice(7, 1, { title: '审核人', dataIndex: 'auditPerson', width: '10%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true })
+      }
+      return arr
+    }
+  },
   methods: {
+    //  时间  change
+    dateChange (date) {
+      this.queryParam.beginDate = date[0]
+      this.queryParam.endDate = date[1]
+    },
     // 表格选中项
     rowSelectionFun (obj) {
       this.rowSelectionInfo = obj || null
@@ -131,58 +155,88 @@ export default {
     resetSearchForm () {
       this.queryParam.name = ''
       this.queryParam.code = ''
-      this.queryParam.state = undefined
+      this.queryParam.beginDate = ''
+      this.queryParam.endDate = ''
+      this.time = []
+      this.$refs.rangeDate.resetDate(this.time)
       this.$refs.table.refresh(true)
     },
     // 单个审核
+    singAudit (row, state) {
+      const _this = this
+      _this.spinning = true
+      productLogAudit({ productLogSn: row.productLogSn, 'bizState': state }).then(res => {
+        if (res.status == 200) {
+          _this.$message.success(res.message)
+          _this.$refs.table.refresh()
+          _this.spinning = false
+        } else {
+          _this.spinning = false
+        }
+      })
+    },
     handleAudit (row) {
       const _this = this
-      this.$confirm({
+      const modal = this.$confirm({
         title: '提示',
-        content: '确认要上线审核吗?',
+        content: '请点击下方按钮确认操作',
+        cancelText: '不通过',
+        okText: '通过',
         centered: true,
+        closable: true,
         onOk () {
-          _this.spinning = true
-          productOnlineAudit({ sn: row.productSn }).then(res => {
-            if (res.status == 200) {
-              _this.$message.success(res.message)
-              _this.$refs.table.refresh()
-              _this.spinning = false
-            } else {
-              _this.spinning = false
-            }
-          })
+          _this.singAudit(row, 'PASS')
+        },
+        onCancel (e) {
+          if (!e.triggerCancel) {
+            _this.singAudit(row, 'REFUSE')
+            modal.destroy()
+          }
         }
       })
     },
     // 批量审核
+    batchAudit (state) {
+      const _this = this
+      _this.loading = true
+      _this.spinning = true
+      const params = {
+        productLogSnList: _this.rowSelectionInfo && _this.rowSelectionInfo.selectedRowKeys || [],
+        bizState: state
+      }
+      productLogAuditBatch(params).then(res => {
+        _this.loading = false
+        if (res.status == 200) {
+          _this.$refs.table.clearSelected() // 清空表格选中项
+          _this.$message.success(res.message)
+          _this.$refs.table.refresh()
+          _this.spinning = false
+        } else {
+          _this.spinning = false
+        }
+      })
+    },
     handleBatchAudit () {
       const _this = this
       if (!_this.rowSelectionInfo || (_this.rowSelectionInfo && _this.rowSelectionInfo.selectedRowKeys.length < 1)) {
         _this.$message.warning('请在列表勾选后再进行批量操作!')
         return
       }
-      this.$confirm({
+      const modal = this.$confirm({
         title: '提示',
-        content: '确认要批量上线审核吗?',
+        content: '请点击下方按钮确认操作',
+        cancelText: '不通过',
+        okText: '通过',
         centered: true,
+        closable: true,
         onOk () {
-          _this.loading = true
-          _this.spinning = true
-          productBatchOnlineAudit(_this.rowSelectionInfo && _this.rowSelectionInfo.selectedRowKeys).then(res => {
-            _this.loading = false
-            if (res.status == 200) {
-              _this.$refs.table.clearSelected() // 清空表格选中项
-              _this.$message.success(res.message)
-              _this.$refs.table.refresh()
-              _this.spinning = false
-            } else {
-              _this.spinning = false
-            }
-          })
+          _this.batchAudit('PASS')
         },
-        onCancel () {
-          console.log('Cancel')
+        onCancel (e) {
+          if (!e.triggerCancel) {
+            _this.batchAudit('REFUSE')
+            modal.destroy()
+          }
         }
       })
     },
@@ -196,7 +250,7 @@ export default {
     },
     setTableH () {
       const tableSearchH = this.$refs.tableSearch.offsetHeight
-      this.tableHeight = window.innerHeight - tableSearchH - 235
+      this.tableHeight = window.innerHeight - tableSearchH - 285
     }
   },
   watch: {
@@ -224,3 +278,10 @@ export default {
   }
 }
 </script>
+<style lang="less">
+  .productLaunchAuditList-wrap{
+    .ant-tabs-bar{
+      margin: 0;
+    }
+  }
+</style>

+ 202 - 172
src/views/productManagement/productOfflineAudit/list.vue

@@ -1,164 +1,152 @@
 <template>
-  <a-card size="small" :bordered="false" class="productOfflineAuditList-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="产品名称">
-                <a-input id="productOfflineAuditList-name" v-model.trim="queryParam.name" allowClear placeholder="请输入产品名称"/>
-              </a-form-item>
-            </a-col>
-            <a-col :md="6" :sm="24">
-              <a-form-item label="产品编码/通用编码">
-                <a-input id="productOfflineAuditList-queryWord" v-model.trim="queryParam.queryWord" allowClear placeholder="请输入产品编码/通用编码"/>
-              </a-form-item>
-            </a-col>
-            <a-col :md="6" :sm="24">
-              <a-form-item label="下线选项">
-                <v-select
-                  v-model="queryParam.offlineReasonType"
-                  ref="offlineReasonType"
-                  id="productOfflineAuditList-offlineReasonType"
-                  code="OFFLINE_REASON_TYPE"
-                  placeholder="请选择下线选项"
-                  allowClear></v-select>
-              </a-form-item>
-            </a-col>
-            <template v-if="advanced">
+  <div class="productOfflineAuditList-wrap">
+    <!-- 状态 -->
+    <div style="background-color: #fff;margin-bottom: 5px;">
+      <v-select
+        v-model="queryParam.bizState"
+        ref="state"
+        showType="tabs"
+        @change="resetSearchForm()"
+        code="PRODUCT_LOG_BIZ_STATE"
+        allowClear></v-select>
+    </div>
+
+    <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="品牌">
-                  <ProductBrand id="productOfflineAuditList-productBrandSn" v-model="queryParam.productBrandSn"></ProductBrand>
+                <a-form-item label="产品名称">
+                  <a-input id="productOfflineAuditList-name" v-model.trim="queryParam.name" allowClear placeholder="请输入产品名称"/>
                 </a-form-item>
               </a-col>
               <a-col :md="6" :sm="24">
-                <a-form-item label="产品分类">
-                  <a-cascader
-                    @change="changeProductType"
-                    expand-trigger="hover"
-                    change-on-select
-                    :options="productTypeList"
-                    :fieldNames="{ label: 'productTypeName', value: 'productTypeSn', children: 'children' }"
-                    id="productOfflineAuditList-productType"
-                    placeholder="请选择产品分类"
-                    allowClear
-                    v-model="productType" />
+                <a-form-item label="产品编码/通用编码">
+                  <a-input id="productOfflineAuditList-queryWord" v-model.trim="queryParam.queryWord" allowClear placeholder="请输入产品编码/通用编码"/>
                 </a-form-item>
               </a-col>
               <a-col :md="6" :sm="24">
-                <a-form-item label="审核状态">
+                <a-form-item label="下线选项">
                   <v-select
-                    v-model="queryParam.state"
-                    ref="state"
-                    id="productOfflineAuditList-state"
-                    code="PRODUCT_ONOFFLINE_STATUS"
-                    placeholder="请选择审核状态"
+                    v-model="queryParam.reasonType"
+                    ref="reasonType"
+                    id="productOfflineAuditList-reasonType"
+                    code="OFFLINE_REASON_TYPE"
+                    placeholder="请选择下线选项"
                     allowClear></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)" :disabled="disabled" id="productOfflineAuditList-refresh">查询</a-button>
-              <a-button style="margin-left: 5px" @click="resetSearchForm" :disabled="disabled" id="productOfflineAuditList-reset">重置</a-button>
-              <a @click="advanced=!advanced" style="margin-left: 5px">
-                {{ advanced ? '收起' : '展开' }}
-                <a-icon :type="advanced ? 'up' : 'down'"/>
-              </a>
-            </a-col>
-          </a-row>
-        </a-form>
-      </div>
-      <!-- 列表 -->
-      <div style="margin-bottom: 10px">
-        <a-button type="primary" v-if="$hasPermissions('B_productOfflineAudit_batchAudit')" id="productOfflineAudit-export" :loading="loading" @click="handleBatchAudit">批量审核</a-button>
-        <span style="margin-left: 5px" v-if="$hasPermissions('B_productOfflineAudit_batchAudit')">
-          <template v-if="rowSelectionInfo && rowSelectionInfo.selectedRowKeys.length>0">{{ `已选 ${rowSelectionInfo.selectedRowKeys.length} 项` }}</template>
-        </span>
-      </div>
-      <s-table
-        class="sTable fixPagination"
-        ref="table"
-        :style="{ height: tableHeight+84.5+'px' }"
-        size="small"
-        :rowKey="(record) => record.productSn"
-        rowKeyName="productSn"
-        :row-selection="$hasPermissions('B_productOfflineAudit_batchAudit')?{ columnWidth: 40, getCheckboxProps: record => ({ props: { disabled: record.state != 'WAIT_OFFLINE_AUDIT' } }) }:null"
-        @rowSelection="rowSelectionFun"
-        :columns="columns"
-        :data="loadData"
-        :scroll="{ y: tableHeight }"
-        :defaultLoadData="false"
-        bordered>
-        <!-- 产品分类 -->
-        <template slot="productType" slot-scope="text, record">
-          <span v-if="record.productTypeName2 || record.productTypeName3">{{ record.productTypeName2 }} {{ record.productTypeName3 ? '>' : '' }} {{ record.productTypeName3 }}</span>
-          <span v-else>--</span>
-        </template>
-        <!-- 操作 -->
-        <template slot="action" slot-scope="text, record">
-          <a-button
-            size="small"
-            type="link"
-            v-if="record.state=='WAIT_OFFLINE_AUDIT' && $hasPermissions('B_productOfflineAudit_audit')"
-            class="button-warning"
-            @click="handleAudit(record)"
-            id="productOfflineAuditList-audit-btn">审核</a-button>
-          <span v-else>--</span>
-        </template>
-      </s-table>
-    </a-spin>
-  </a-card>
+              <template v-if="advanced">
+                <a-col :md="6" :sm="24">
+                  <a-form-item label="品牌">
+                    <ProductBrand id="productOfflineAuditList-productBrandSn" v-model="queryParam.productBrandSn"></ProductBrand>
+                  </a-form-item>
+                </a-col>
+                <a-col :md="6" :sm="24">
+                  <a-form-item label="产品分类">
+                    <productTypeAll placeholder="请选择产品分类" @change="changeProductType" v-model="productType" id="productOfflineAuditList-productType"></productTypeAll>
+                  </a-form-item>
+                </a-col>
+                <a-col :md="6" :sm="24">
+                  <a-form-item label="提交时间">
+                    <rangeDate ref="rangeDate" :value="time" @change="dateChange" />
+                  </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)" :disabled="disabled" id="productOfflineAuditList-refresh">查询</a-button>
+                <a-button style="margin-left: 5px" @click="resetSearchForm" :disabled="disabled" id="productOfflineAuditList-reset">重置</a-button>
+                <a @click="advanced=!advanced" style="margin-left: 5px">
+                  {{ advanced ? '收起' : '展开' }}
+                  <a-icon :type="advanced ? 'up' : 'down'"/>
+                </a>
+              </a-col>
+            </a-row>
+          </a-form>
+        </div>
+        <!-- 列表 -->
+        <div style="margin-bottom: 10px">
+          <a-button type="primary" v-if="$hasPermissions('B_productOfflineAudit_batchAudit')&&queryParam.bizState == 'WAIT'" id="productOfflineAudit-export" :loading="loading" @click="handleBatchAudit">批量审核</a-button>
+          <span style="margin-left: 5px" v-if="$hasPermissions('B_productOfflineAudit_batchAudit')">
+            <template v-if="rowSelectionInfo && rowSelectionInfo.selectedRowKeys.length>0">{{ `已选 ${rowSelectionInfo.selectedRowKeys.length} 项` }}</template>
+          </span>
+        </div>
+        <s-table
+          class="sTable fixPagination"
+          ref="table"
+          :style="{ height: tableHeight+84.5+'px' }"
+          size="small"
+          :rowKey="(record) => record.productLogSn"
+          rowKeyName="productLogSn"
+          :row-selection="$hasPermissions('B_productOfflineAudit_batchAudit')&&queryParam.bizState == 'WAIT'?{ columnWidth: 40 }:null"
+          @rowSelection="rowSelectionFun"
+          :columns="columns"
+          :data="loadData"
+          :scroll="{ y: tableHeight }"
+          :defaultLoadData="false"
+          bordered>
+          <!-- 产品分类 -->
+          <template slot="productType" slot-scope="text, record">
+            <span v-if="record.productTypeName2 || record.productTypeName3">{{ record.productTypeName2 }} {{ record.productTypeName3 ? '>' : '' }} {{ record.productTypeName3 }}</span>
+            <span v-else>--</span>
+          </template>
+          <!-- 操作 -->
+          <template slot="action" slot-scope="text, record">
+            <a-button
+              size="small"
+              type="link"
+              v-if="record.bizState=='WAIT' && $hasPermissions('B_productOfflineAudit_audit')"
+              class="button-warning"
+              @click="handleAudit(record)"
+              id="productOfflineAuditList-audit-btn">审核</a-button>
+            <span v-else>--</span>
+          </template>
+        </s-table>
+      </a-spin>
+    </a-card>
+  </div>
 </template>
 
 <script>
+import rangeDate from '@/views/common/rangeDate.vue'
 import { commonMixin } from '@/utils/mixin'
 import { STable, VSelect } from '@/components'
-import { productBrandQuery } from '@/api/productBrand'
-import { productTypeQuery } from '@/api/productType'
 import ProductBrand from '@/views/common/productBrand.js'
-import { productOfflineList, productOfflineAudit, productBatchOfflineAudit } from '@/api/product'
+import productTypeAll from '@/views/common/productTypeAll.js'
+import { productLogList, productLogAudit, productLogAuditBatch } from '@/api/product'
 export default {
   name: 'ProductOfflineAuditList',
   mixins: [commonMixin],
-  components: { STable, VSelect, ProductBrand },
+  components: { STable, VSelect, ProductBrand, productTypeAll, rangeDate },
   data () {
     return {
       spinning: false,
       advanced: true, // 高级搜索 展开/关闭
       tableHeight: 0,
+      time: [],
       queryParam: { //  查询条件
+        beginDate: '',
+        endDate: '',
         name: '', //  产品名称
         queryWord: '',
         productBrandSn: undefined, //  产品品牌
         productTypeSn1: '', //  产品一级分类
         productTypeSn2: '', //  产品二级分类
         productTypeSn3: '', //  产品三级分类
-        offlineReasonType: undefined, // 下线选项
-        state: undefined //  状态
+        reasonType: undefined, // 下线选项
+        bizType: 'OFFLINE', // 下线
+        bizState: 'WAIT' //  状态
       },
       productType: [],
       disabled: false, //  查询、重置按钮是否可操作
-      columns: [
-        { title: '产品名称', dataIndex: 'name', align: 'center', width: '15%', customRender: function (text) { return text || '--' }, ellipsis: true },
-        { title: '产品编码', dataIndex: 'code', width: '7%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '产品分类', scopedSlots: { customRender: 'productType' }, width: '10%', align: 'center' },
-        { title: '提交时间', dataIndex: 'offlineSubmitTime', width: '7%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '提交人', dataIndex: 'offlineSubmitPerson', width: '8%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
-        { title: '下线选项', dataIndex: 'offlineReasonType', width: '6%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '通用编码', dataIndex: 'commonCode', width: '11%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '下线原因', dataIndex: 'offlineRemark', width: '8%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
-        { title: '审核状态', dataIndex: 'stateDictValue', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '审核时间', dataIndex: 'offlineAuditTime', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '审核人', dataIndex: 'offlineAuditPerson', width: '9%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
-        { title: '操作', scopedSlots: { customRender: 'action' }, width: '5%', align: 'center' }
-      ],
       loading: false,
       // 加载数据方法 必须为 Promise 对象
       loadData: parameter => {
         this.disabled = true
         this.spinning = true
-        return productOfflineList(Object.assign(parameter, this.queryParam)).then(res => {
+        return productLogList(Object.assign(parameter, this.queryParam)).then(res => {
           let data
           if (res.status == 200) {
             data = res.data
@@ -173,7 +161,34 @@ export default {
       rowSelectionInfo: null
     }
   },
+  computed: {
+    columns () {
+      const arr = [
+        { title: '产品名称', dataIndex: 'name', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '产品编码', dataIndex: 'code', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品分类', scopedSlots: { customRender: 'productType' }, width: '10%', align: 'center' },
+        { title: '提交时间', dataIndex: 'submitTime', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '提交人', dataIndex: 'submitPerson', width: '8%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '下线选项', dataIndex: 'reasonType', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '通用编码', dataIndex: 'commonCode', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '下线备注', dataIndex: 'submitNote', width: '8%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '审核状态', dataIndex: 'bizStateDictValue', width: '8%', align: 'center', customRender: function (text) { return text || '--' } }
+      ]
+      if (this.queryParam.bizState == 'WAIT') {
+        arr.splice(8, 1, { title: '操作', scopedSlots: { customRender: 'action' }, width: '5%', align: 'center' })
+      } else {
+        arr.splice(8, 1, { title: '审核时间', dataIndex: 'auditTime', width: '8%', align: 'center', customRender: function (text) { return text || '--' } })
+        arr.splice(9, 1, { title: '审核人', dataIndex: 'auditPerson', width: '8%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true })
+      }
+      return arr
+    }
+  },
   methods: {
+    //  时间  change
+    dateChange (date) {
+      this.queryParam.beginDate = date[0]
+      this.queryParam.endDate = date[1]
+    },
     // 表格选中项
     rowSelectionFun (obj) {
       this.rowSelectionInfo = obj || null
@@ -186,29 +201,66 @@ export default {
       this.queryParam.productTypeSn1 = ''
       this.queryParam.productTypeSn2 = ''
       this.queryParam.productTypeSn3 = ''
-      this.queryParam.offlineReasonType = undefined
-      this.queryParam.state = undefined
+      this.queryParam.reasonType = undefined
+      this.queryParam.beginDate = ''
+      this.queryParam.endDate = ''
+      this.time = []
+      this.$refs.rangeDate.resetDate(this.time)
       this.productType = []
       this.$refs.table.refresh(true)
     },
     // 单个审核
+    singAudit (row, state) {
+      const _this = this
+      _this.spinning = true
+      productLogAudit({ productLogSn: row.productLogSn, 'bizState': state }).then(res => {
+        if (res.status == 200) {
+          _this.$message.success(res.message)
+          _this.$refs.table.refresh()
+          _this.spinning = false
+        } else {
+          _this.spinning = false
+        }
+      })
+    },
     handleAudit (row) {
       const _this = this
-      this.$confirm({
+      const modal = this.$confirm({
         title: '提示',
-        content: '确认要下线审核通过吗?',
+        content: '请点击下方按钮确认操作',
+        cancelText: '不通过',
+        okText: '通过',
         centered: true,
+        closable: true,
         onOk () {
-          _this.spinning = true
-          productOfflineAudit({ sn: row.productSn }).then(res => {
-            if (res.status == 200) {
-              _this.$message.success(res.message)
-              _this.$refs.table.refresh()
-              _this.spinning = false
-            } else {
-              _this.spinning = false
-            }
-          })
+          _this.singAudit(row, 'PASS')
+        },
+        onCancel (e) {
+          if (!e.triggerCancel) {
+            _this.singAudit(row, 'REFUSE')
+            modal.destroy()
+          }
+        }
+      })
+    },
+    // 批量审核
+    batchAudit (state) {
+      const _this = this
+      _this.loading = true
+      _this.spinning = true
+      const params = {
+        productLogSnList: _this.rowSelectionInfo && _this.rowSelectionInfo.selectedRowKeys || [],
+        bizState: state
+      }
+      productLogAuditBatch(params).then(res => {
+        _this.loading = false
+        if (res.status == 200) {
+          _this.$refs.table.clearSelected() // 清空表格选中项
+          _this.$message.success(res.message)
+          _this.$refs.table.refresh()
+          _this.spinning = false
+        } else {
+          _this.spinning = false
         }
       })
     },
@@ -219,24 +271,21 @@ export default {
         _this.$message.warning('请在列表勾选后再进行批量操作!')
         return
       }
-      this.$confirm({
+      const modal = this.$confirm({
         title: '提示',
-        content: '确认要批量下线审核通过吗?',
+        content: '请点击下方按钮确认操作',
+        cancelText: '不通过',
+        okText: '通过',
         centered: true,
+        closable: true,
         onOk () {
-          _this.loading = true
-          _this.spinning = true
-          productBatchOfflineAudit(_this.rowSelectionInfo && _this.rowSelectionInfo.selectedRowKeys).then(res => {
-            _this.loading = false
-            if (res.status == 200) {
-              _this.$refs.table.clearSelected() // 清空表格选中项
-              _this.$message.success(res.message)
-              _this.$refs.table.refresh()
-              _this.spinning = false
-            } else {
-              _this.spinning = false
-            }
-          })
+          _this.batchAudit('PASS')
+        },
+        onCancel (e) {
+          if (!e.triggerCancel) {
+            _this.batchAudit('REFUSE')
+            modal.destroy()
+          }
         }
       })
     },
@@ -246,39 +295,17 @@ export default {
       this.queryParam.productTypeSn2 = val[1] ? val[1] : ''
       this.queryParam.productTypeSn3 = val[2] ? val[2] : ''
     },
-    //  产品品牌  列表
-    getProductBrand () {
-      productBrandQuery({}).then(res => {
-        if (res.status == 200) {
-          this.productBrandList = res.data
-        } else {
-          this.productBrandList = []
-        }
-      })
-    },
-    //  产品分类  列表
-    getProductType () {
-      productTypeQuery({}).then(res => {
-        if (res.status == 200) {
-          this.productTypeList = res.data
-        } else {
-          this.productTypeList = []
-        }
-      })
-    },
     pageInit () {
       const _this = this
       this.$nextTick(() => { // 页面渲染完成后的回调
         _this.setTableH()
       })
-      this.getProductBrand()
-      this.getProductType()
       this.rowSelectionInfo = null
       this.$refs.table.clearTable()
     },
     setTableH () {
       const tableSearchH = this.$refs.tableSearch.offsetHeight
-      this.tableHeight = window.innerHeight - tableSearchH - 235
+      this.tableHeight = window.innerHeight - tableSearchH - 300
     }
   },
   watch: {
@@ -324,5 +351,8 @@ export default {
     .green{
       color: #19be6b;
     }
+    .ant-tabs-bar{
+      margin: 0;
+    }
   }
 </style>

+ 1 - 0
src/views/reportData/transferReturnDetailReport/list.vue

@@ -335,6 +335,7 @@ export default {
       this.$refs.ruleForm.validate(valid => {
         if (valid) {
           const params = _this.queryParam
+          params.showCostFlag = this.$hasPermissions('B_isShowCost')
           _this.showExport = true
           _this.exportLoading = true
           _this.spinning = true

+ 1 - 0
src/views/reportData/transferReturnReport/list.vue

@@ -191,6 +191,7 @@ export default {
       this.$refs.ruleForm.validate(valid => {
         if (valid) {
           const params = _this.queryParam
+          params.showCostFlag = this.$hasPermissions('B_isShowCost')
           _this.showExport = true
           _this.exportLoading = true
           _this.spinning = true

+ 58 - 3
src/views/salesManagement/salesQuery/edit.vue

@@ -65,7 +65,20 @@
                 </a-row>
               </a-form>
               <div style="position: absolute;right: 0;top: 3px;">
-                <a-button size="small" type="primary" class="button-info" id="salesEdit-import-btn" @click="openGuideModal=true">导入产品</a-button>
+                <span>已选{{ selectTotal }}项</span>
+                <a-button
+                  style="margin:0 15px;"
+                  size="small"
+                  type="danger"
+                  class="button-info"
+                  id="salesEdit-plDel-btn"
+                  @click="handleBatchDel">批量删除</a-button>
+                <a-button
+                  size="small"
+                  type="primary"
+                  class="button-info"
+                  id="salesEdit-import-btn"
+                  @click="openGuideModal=true">导入产品</a-button>
               </div>
             </div>
           </a-col>
@@ -78,6 +91,8 @@
           :rowKey="(record) => record.id"
           :columns="columns"
           :data="loadData"
+          :row-selection="{ columnWidth: 40 }"
+          @rowSelection="rowSelectionFun"
           :defaultLoadData="false"
           :scroll="{ y: 300 }"
           bordered>
@@ -193,7 +208,7 @@ import queryPromotable from './queryPromotable.vue'
 import ChooseActive from './chooseActive.vue'
 import ImportGuideModal from './importGuideModal.vue'
 import { salesDetailBySn, salesWriteSubmit, getPromoacActiveList } from '@/api/sales'
-import { salesDetailStockList, salesDetailInsert, salesDetailUpdateQty, salesDetailDel, salesDetailDelAll, addPromoGoods, salesBatchInsert } from '@/api/salesDetail'
+import { salesDetailStockList, salesDetailInsert, salesDetailUpdateQty, salesDetailDel, salesDetailBatchDel, salesDetailDelAll, addPromoGoods, salesBatchInsert } from '@/api/salesDetail'
 export default {
   name: 'SalesEdit',
   mixins: [commonMixin],
@@ -239,10 +254,14 @@ export default {
       queryParam: {
         productCode: '',
         productName: ''
-      }
+      },
+      rowSelectionInfo: null
     }
   },
   computed: {
+    selectTotal () {
+      return this.rowSelectionInfo && this.rowSelectionInfo.selectedRowKeys.length || 0
+    },
     columns () {
       const arr = [
         { title: '序号', dataIndex: 'no', width: '4%', align: 'center' },
@@ -263,6 +282,41 @@ export default {
     }
   },
   methods: {
+    // 表格选中项
+    rowSelectionFun (obj) {
+      this.rowSelectionInfo = obj || null
+    },
+    // 批量删除已选产品
+    handleBatchDel () {
+      const _this = this
+      if (!_this.rowSelectionInfo || (_this.rowSelectionInfo && _this.rowSelectionInfo.selectedRowKeys.length < 1)) {
+        _this.$message.warning('请在选择要删除的产品后再进行批量操作!')
+        return
+      }
+      const obj = []
+      _this.rowSelectionInfo && _this.rowSelectionInfo.selectedRows.map(item => {
+        obj.push(item.salesBillDetailSn)
+      })
+      this.$confirm({
+        title: '提示',
+        content: '已选产品' + obj.length + '项,确认要批量删除吗?',
+        centered: true,
+        onOk () {
+          _this.spinning = true
+          salesDetailBatchDel({
+            salesBillSn: _this.salesBillSn,
+            salesBillDetailSnList: obj
+          }).then(res => {
+            if (res.status == 200) {
+              _this.resetSearchForm(true)
+              _this.$refs.promotable.resetCurForm()
+              _this.$message.success(res.message)
+            }
+            _this.spinning = false
+          })
+        }
+      })
+    },
     // 已选产品  blur
     onCellBlur (val, record) {
       const _this = this
@@ -297,6 +351,7 @@ export default {
       this.$refs.table.refresh(!!flag)
       this.getPromoacActiveList()
       this.getOrderDetail(false)
+      this.$refs.table.clearSelected() // 清空表格选中项
     },
     //  返回
     handleBack () {

+ 1 - 1
src/views/salesManagement/salesQuery/queryPart.vue

@@ -129,7 +129,7 @@ export default {
       loadData: parameter => {
         this.disabled = true
         this.queryParam.dealerSn = this.buyerSn
-        return queryStockProductPage(Object.assign(parameter, this.queryParam, { onlineFalg: '1' })).then(res => {
+        return queryStockProductPage(Object.assign(parameter, this.queryParam, { onlineFalg: '1', pricingState: 'PRICED' })).then(res => {
           let data
           if (res.status == 200) {
             data = res.data

+ 2 - 2
vue.config.js

@@ -107,9 +107,9 @@ const vueConfig = {
     // If you want to turn on the proxy, please remove the mockjs /src/main.jsL11
     proxy: {
       '/api': {
-        target: 'http://192.168.16.156/ocs-admin',
+        // target: 'http://192.168.16.102/ocs-admin',
         // target: 'https://t.ocs.360arrow.com/ocs-admin', //  Á·Ï°
-        // target: 'http://p.ocs.360arrow.com/ocs-admin', //  Ô¤·¢²¼
+        target: 'http://p.ocs.360arrow.com/ocs-admin', //  Ô¤·¢²¼
         ws: false,
         changeOrigin: true,
         pathRewrite: {