lilei 9 months ago
parent
commit
e2559bf225

+ 302 - 0
src/components/VTable/index.vue

@@ -0,0 +1,302 @@
+<template>
+  <div class="v-table">
+    <a-spin :spinning="localLoading" tip="Loading...">
+      <ve-table
+        ref="tableRef"
+        style="width:100%"
+        :max-height="scroll.y"
+        :scroll-width="scroll.x"
+        :columns="veColumns"
+        :table-data="localDataSource"
+        :row-key-field-name="rowKeyName"
+        :border-x="true"
+        :border-y="bordered"
+        :border-around="bordered"
+        :column-width-resize-option="columnWidthResizeOption"
+        :columnHiddenOption="columnHiddenOption"
+        :row-style-option="{clickHighlight: true}"
+        :cellSelectionOption="{enable: false}"
+        :virtual-scroll-option="{enable: false}"
+      />
+      <div class="ve-pagination">
+        <div class="ve-page-left"></div>
+        <a-pagination
+          v-show="showPagination"
+          size="small"
+          :total="localPagination.total"
+          v-model="localPagination.current"
+          :pageSize="localPagination.pageSize"
+          :showTotal="total => `共 ${total} 条记录`"
+          :pageSizeOptions="localPagination.pageSizeOptions"
+          :show-quick-jumper="localPagination.showQuickJumper"
+          @change="paginationChange"
+          show-size-changer
+          @showSizeChange="paginationShowSizeChange"
+        />
+      </div>
+    </a-spin>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'VTable',
+  props: {
+    columns: {
+      type: Array,
+      default: () => []
+    },
+    data: {
+      type: Function,
+      required: true
+    },
+    scroll: {
+      type: Object,
+      default: () => ({ x: 0, y: 400 })
+    },
+    bordered: {
+      type: Boolean,
+      default: true
+    },
+    defaultLoadData: {
+      type: Boolean,
+      default: true
+    },
+    rowKeyName: {
+      type: String,
+      default: 'id'
+    },
+    defaultHiddenColumnKeys: {
+      type: Array,
+      default: () => []
+    },
+    pagination: {
+      type: Object
+    },
+    showPagination: {
+      type: Boolean,
+      default: true
+    }
+  },
+  computed: {
+    veColumns () {
+      const arr = this.convertColumns(this.columns)
+      console.log(arr)
+      return arr
+    }
+  },
+  data () {
+    return {
+      localLoading: false,
+      localDataSource: [],
+      sortObj: null,
+      isSucceed: true, //  是否请求成功
+      // 拖到列宽
+      columnWidthResizeOption: {
+        // default false
+        enable: true,
+        // column resize min width
+        minWidth: 30,
+        // column size change
+        sizeChange: ({ column, differWidth, columnWidth }) => {}
+      },
+      columnHiddenOption: {
+        // default hidden column keys
+        defaultHiddenColumnKeys: this.defaultHiddenColumnKeys
+      },
+      localPagination: Object.assign({
+        current: 1,
+        pageSize: 10,
+        showSizeChanger: true,
+        showQuickJumper: false
+      }, this.pagination)
+    }
+  },
+  created () {
+    if (this.defaultLoadData) {
+      this.loadData()
+    }
+  },
+  methods: {
+    // 转换colums数据结构,兼容老页面
+    convertColumns (columns) {
+      const ret = []
+      const _this = this
+      for (let i = 0; i < columns.length; i++) {
+        const item = columns[i]
+        ret.push({
+          field: item.dataIndex,
+          key: 'col-' + i,
+          title: item.title,
+          renderHeaderCell: ({ column }, h) => {
+            if (item.slots) {
+              return _this.$scopedSlots[item.slots.title]()
+            }
+            if (item.align != 'center') {
+              return (
+                <div style="text-align:center;">{column.title}</div>
+              )
+            }
+            return h('span', column.title)
+          },
+          width: item.width.indexOf('%') >= 0 ? item.width.replace('%', '') * 12 : item.width, // 百分比转数字
+          align: item.align,
+          fixed: item.fixed,
+          children: item.children ? _this.convertColumns(item.children) : undefined,
+          // 自定义单元格
+          scopedSlotsKey: item.scopedSlots && item.scopedSlots.customRender,
+          renderBodyCell: ({ row, column, rowIndex }, h) => {
+            const text = row[column.field]
+            if (column.scopedSlotsKey) {
+              return _this.$scopedSlots[column.scopedSlotsKey](text, row, rowIndex, column)
+            }
+            if (item.ellipsis && column.field) {
+              return (
+                <a-tooltip placement="right">
+                  <template slot="title">
+                    <span>{text}</span>
+                  </template>
+                  <span style="width:100%;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;">{text}</span>
+                </a-tooltip>
+              )
+            }
+            return item.customRender ? h('span', item.customRender(text)) : h('span', text || '--')
+          }
+        })
+      }
+      return ret
+    },
+    // hidden columns
+    hideColumns (keys) {
+      this.$refs['tableRef'].hideColumnsByKeys(keys)
+    },
+    // show cloumns
+    showColumns (keys) {
+      this.$refs['tableRef'].showColumnsByKeys(keys)
+    },
+    /**
+     * 加载数据方法
+     * @param {Object} pagination 分页选项器
+     * @param {Object} filters 过滤条件
+     * @param {Object} sorter 排序条件
+     */
+    loadData (pagination, filters, sorter) {
+      this.localLoading = true
+      const parameter = Object.assign({
+        pageNo: this.showPagination && pagination && pagination.pageSize != this.localPagination.pageSize ? 1 : (pagination && pagination.current) || this.showPagination && this.localPagination.current,
+        pageSize: (pagination && pagination.pageSize) || this.showPagination && this.localPagination.pageSize
+      },
+      (sorter ? sorter.field && { sortField: sorter.field } : this.sortObj && { sortField: this.sortObj.field }) || {},
+      (sorter ? sorter.order && { sortOrder: sorter.order } : this.sortObj && { sortOrder: this.sortObj.order }) || {},
+      { ...filters }
+      )
+      // 缓存排序参数
+      if (sorter) {
+        this.sortObj = {
+          field: sorter.field || '',
+          order: sorter.order || ''
+        }
+      }
+      const result = this.data(parameter)
+      // 对接自己的通用数据接口需要修改下方代码中的 r.pageNo, r.count, r.data
+      if ((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') {
+        result.then(r => {
+          const list = r.list || r.data || r || []
+          this.isSucceed = !!r
+          this.localPagination = this.showPagination && Object.assign({}, this.localPagination, {
+            current: r.pageNo || 1, // 返回结果中的当前分页数
+            total: Number(r.count) || 0, // 返回结果中的总记录数
+            pageSize: r.pageSize || (pagination && pagination.pageSize) || this.localPagination.pageSize
+          }) || false
+
+          // 为防止删除数据后导致页面当前页面数据长度为 0 ,自动翻页到上一页
+          if (list.length === 0 && this.showPagination && this.localPagination.current > 1) {
+            this.localPagination.current--
+            this.loadData()
+            return
+          }
+
+          // 这里用于判断接口是否有返回 r.count 且 this.showPagination = true 且 pageNo 和 pageSize 存在 且 count 小于等于 pageNo * pageSize 的大小
+          // 当情况满足时,表示数据不满足分页大小,关闭 table 分页功能
+          try {
+            if ((['auto', true].includes(this.showPagination) && r.count <= (r.pageNo * this.localPagination.pageSize))) {
+              // this.localPagination.hideOnSinglePage = true
+            }
+          } catch (e) {
+            this.localPagination = false
+          }
+          this.localDataSource = list // 返回结果中的数组数据
+          this.localLoading = false
+        }).catch(err => {
+          this.clearTable()
+        })
+      }
+    },
+    // 页码变更
+    paginationChange (pageNumber) {
+      this.localPagination.current = pageNumber
+      this.loadData()
+    },
+    paginationShowSizeChange (current, pageSize) {
+      this.localPagination.current = current
+      this.localPagination.pageSize = pageSize
+      this.loadData()
+    },
+    /**
+     * 表格重新加载方法
+     * 如果参数为 true, 则强制刷新到第一页
+     * @param Boolean bool
+     */
+    refresh (bool = false) {
+      bool && (this.localPagination = Object.assign({}, {
+        current: 1, pageSize: this.localPagination.pageSize
+      }))
+      this.loadData()
+    },
+    // 重置表格为空
+    clearTable () {
+      this.localLoading = false
+      this.localDataSource = []
+      this.sortObj = null
+      this.clearSelected()
+      this.localPagination = Object.assign({}, {
+        current: 1, pageSize: this.localPagination.pageSize, total: 0
+      })
+    },
+    /**
+     * 清空 table 已选中项
+     */
+    clearSelected () {
+      if (this.rowSelection) {
+        this.selectedRows = []
+        this.selectedRowKeys = []
+        this.updateSelect()
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+  .v-table {
+    width: 100%;
+    > div{
+      height: 100%;
+    }
+    .ant-spin-container{
+      height: 100%;
+    }
+    .ve-pagination{
+      display:flex;
+      justify-content: space-between;
+      align-items: center;
+      padding: 20px 0 10px 0;
+    }
+    /deep/ .ve-table .ve-table-container .ve-table-content-wrapper table.ve-table-content tbody.ve-table-body tr.ve-table-body-tr td.ve-table-body-td,
+    .ve-table .ve-table-container .ve-table-content-wrapper table.ve-table-content tbody.ve-table-body tr.ve-table-expand-tr td.ve-table-body-td{
+      div:empty::before {
+        content:'--'
+      }
+    }
+  }
+</style>

+ 2 - 0
src/components/index.js

@@ -21,6 +21,7 @@ import DescriptionList from '@/components/DescriptionList'
 import Tree from '@/components/Tree/Tree'
 import Trend from '@/components/Trend'
 import STable from '@/components/Table'
+import VTable from '@/components/VTable/index.vue'
 import MultiTab from '@/components/MultiTab'
 import Result from '@/components/Result'
 import IconSelector from '@/components/IconSelector'
@@ -54,6 +55,7 @@ export {
   DescriptionList as DetailList,
   Tree,
   STable,
+  VTable,
   VSelect,
   SelectInput,
   Upload,

+ 17 - 17
src/views/salesManagement/salesQueryNew/list.vue

@@ -175,10 +175,10 @@
         </div>
 
         <!-- 列表 -->
-        <s-table
+        <v-table
           class="sTable fixPagination"
           ref="table"
-          :style="{ height: tableHeight+87+'px' }"
+          :style="{ height: tableHeight+35+'px' }"
           size="small"
           :rowKey="(record) => record.id"
           :columns="columns"
@@ -186,12 +186,16 @@
           :scroll="{ y: tableHeight }"
           :defaultLoadData="false"
           bordered>
+          <!-- 时间表头 -->
+          <template slot="customDateTitle">
+            <a-tooltip placement="top" title="第一次提交时间">提交时间&nbsp;<a-icon type="question-circle" /></a-tooltip>
+          </template>
           <!-- 销售单号 -->
           <template slot="salesBillNo" slot-scope="text, record">
             <span v-if="$hasPermissions('B_salesDetail')" class="link-bule" @click="handleDetail(record)">{{ record.salesBillNo }}</span>
             <span v-else>{{ record.salesBillNo }}</span>
-            <a-badge :count="'改'+record.changeTimes" :number-style="{ zoom:'80%' }" v-if="record.changeTimes>0"></a-badge>
-            <a-badge count="促" v-if="record.promoFlag==1" :number-style="{ backgroundColor: '#52c41a', zoom:'80%' }"></a-badge>
+            <a-badge :count="'改'+record.changeTimes" :number-style="{ zoom:'0.8' }" v-if="record.changeTimes>0"></a-badge>
+            <a-badge count="促" v-if="record.promoFlag==1" :number-style="{ backgroundColor: '#52c41a', zoom:'0.8' }"></a-badge>
           </template>
           <!-- 出库仓库 -->
           <template slot="warehouseBox" slot-scope="text, record">
@@ -205,10 +209,6 @@
             </a-tooltip>
             <div v-else>--</div>
           </template>
-          <!-- 总数量 -->
-          <template slot="totalQty" slot-scope="text, record">
-            {{ record.totalQty }}
-          </template>
           <!-- 操作 -->
           <template slot="action" slot-scope="text, record">
             <div>
@@ -278,7 +278,7 @@
               >转费用报销单</a-button>
             </div>
           </template>
-        </s-table>
+        </v-table>
       </a-spin>
       <!-- 选择客户弹框 -->
       <choose-custom-modal :show="openModal" @ok="chooseCustomOk" @cancel="openModal=false"></choose-custom-modal>
@@ -319,7 +319,7 @@ import { hdExportExcel } from '@/libs/exportExcel'
 import subarea from '@/views/common/subarea.js'
 import Area from '@/views/common/area.js'
 import rangeDate from '@/views/common/rangeDate.vue'
-import { STable, VSelect } from '@/components'
+import { VTable, VSelect } from '@/components'
 import commonModal from '@/views/common/commonModal.vue'
 import chooseCustomModal from './chooseCustomModal.vue'
 import tipModal from './tipModal.vue'
@@ -336,7 +336,7 @@ import { salesDetailExport } from '@/api/salesBillReport'
 export default {
   name: 'SalesQueryList',
   mixins: [commonMixin],
-  components: { STable, VSelect, tipModal, chooseCustomModal, dealerSubareaScopeList, Area, rangeDate, subarea, commonModal, reportModal, chooseWarehouse, baseDataModal, customerService },
+  components: { VTable, VSelect, tipModal, chooseCustomModal, dealerSubareaScopeList, Area, rangeDate, subarea, commonModal, reportModal, chooseWarehouse, baseDataModal, customerService },
   data () {
     return {
       spinning: false,
@@ -483,11 +483,11 @@ export default {
       const _this = this
       const arr = [
         { title: '创建时间', dataIndex: 'createDate', width: '6%', align: 'center', customRender: function (text) { return text || '--' }, sorter: true },
-        { title: '销售单号', scopedSlots: { customRender: 'salesBillNo' }, width: '8%', align: 'center' },
-        { title: <a-tooltip placement='top' title='第一次提交时间'>提交时间&nbsp;<a-icon type="question-circle" /></a-tooltip>, dataIndex: 'firstSubmitDate', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') }, sorter: true },
+        { title: '销售单号', scopedSlots: { customRender: 'salesBillNo' }, width: '8%', align: 'left' },
+        { title: '提交时间', slots: { title: 'customDateTitle' }, dataIndex: 'firstSubmitDate', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') }, sorter: true },
         { title: '客户名称', dataIndex: 'buyerName', width: '8%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
         { title: '出库仓库', scopedSlots: { customRender: 'warehouseBox' }, width: '6%', align: 'center', ellipsis: true },
-        { title: '总数量', dataIndex: 'totalQty', scopedSlots: { customRender: 'totalQty' }, width: '4%', align: 'center' },
+        { title: '总数量', dataIndex: 'totalQty', width: '4%', align: 'center' },
         { title: '总售价', dataIndex: 'totalAmount', width: '4%', align: 'right', isShow: false, customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
         { title: '已下推数量', dataIndex: 'totalPushedQty', width: '5%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
         { title: '下推总金额', dataIndex: 'totalPushedAmount', width: '5%', align: 'right', isShow: false, customRender: function (text) { return ((text || text == 0) ? _this.toThousands(text) : '--') } },
@@ -502,8 +502,8 @@ export default {
         { title: '最近备货时间', dataIndex: 'lastStockUpDate', width: '6%', align: 'center', customRender: function (text) { return text || '--' }, sorter: true },
         { title: '业务状态', dataIndex: 'billStatusDictValue', width: '6%', align: 'center', customRender: function (text) { return text || '--' } },
         { title: '财务状态', dataIndex: 'financialStatusDictValue', width: '5%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '备货打印状态', dataIndex: 'printStatusDictValue', width: '5%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: '操作', scopedSlots: { customRender: 'action' }, width: '7%', align: 'center' }
+        { title: '备货打印状态', dataIndex: 'printStatusDictValue', width: '6%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '9%', align: 'center' }
       ]
       // 根据权限及勾选按固定顺序动态显示列
       arr.map(item => {
@@ -809,7 +809,7 @@ export default {
     // 计算表格高度
     setTableH () {
       const tableSearchH = this.$refs.tableSearch.offsetHeight
-      this.tableHeight = window.innerHeight - tableSearchH - 260
+      this.tableHeight = window.innerHeight - tableSearchH - 210
     }
   },
   watch: {

+ 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.10/ocs-admin',
+        // target: 'http://192.168.2.10/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: {