Procházet zdrojové kódy

指定领料追踪

l1069030731 před 2 roky
rodič
revize
5c809b220b

+ 1 - 0
src/locale/lang/zh-CN.js

@@ -43,6 +43,7 @@ export default {
   material_stranded: '滞留物料',
   store_warning: '库存预警',
   technician_reprot: '技术员报表',
+  picking_tracking: '指定领料追踪',
   material_pay_detail: '付款详情',
   error_401: '暂无权限',
   error_tag: '异常标签查询',

+ 8 - 0
src/router/routers.js

@@ -654,6 +654,14 @@ export default [
           title: '异常出库'
         },
         component: () => import('@/view/store-out-manage/error-out/error-out')
+      },
+      {
+        path: '/picking_tracking',
+        name: 'picking_tracking',
+        meta: {
+          title: '指定领料追踪'
+        },
+        component: () => import('@/view/store-out-manage/picking-tracking/picking-tracking')
       }
     ]
   },

+ 949 - 0
src/view/store-out-manage/picking-tracking/picking-tracking.vue

@@ -0,0 +1,949 @@
+<!-- 技术员报表 -->
+<template>
+  <div class="container">
+    <div class="tab-nav">
+      <div class="date-filter-wrap">
+        <span style="font-size: 14px;font-weight: bold;color: black">指定领料追踪</span>
+      </div>
+      <div class="date-filter-wrap">
+        <div class="date-filter">
+          <div
+            class="date-tab"
+            v-for="item in dateTabs"
+            :key="item.type"
+            :class="item.type === type ? 'active' : ''"
+            @click="dateTabToggle(item.type)"
+          >{{ item.label }}</div>
+        </div>
+        <DatePicker
+          @on-change="dateClick"
+          v-model="dataArea"
+          type="daterange"
+          placement="bottom-end"
+          placeholder="请选择日期"
+          style="width: 200px;margin-left: 10px;"
+        ></DatePicker>
+      </div>
+    </div>
+    <div class="border"></div>
+    <div class="tab-nav">
+      <div class="row">
+        <Button
+          :type="btnIndex === index  ? 'primary' : 'default'"
+          @click="userClick(item.jobNo, index)"
+          v-for="(item, index) in userList"
+          :key="index"
+        >
+          <span>{{ item.userName }}(</span>
+          <span style="color: red">{{ item.sum }}</span>
+          <span>)</span>
+        </Button>
+      </div>
+    </div>
+    <div class="border"></div>
+    <div class="table-filter" style="border: 1px solid #e6e6e6;">
+      <div class="item">
+        <div class="label">指定领料卷数</div>
+        <p class="value">{{ statistical.appointNum }}</p>
+      </div>
+      <div class="item">
+        <div class="label">实际领料卷数</div>
+        <p class="value">{{ statistical.actualNum }}</p>
+      </div>
+      <div class="item">
+        <div class="label">指定领料未领卷数</div>
+        <p
+          class="value"
+          style="color: red; text-decoration:underline"
+        >{{ statistical.appointNotClaimedNum }}</p>
+      </div>
+      <div class="item" style="border-right: 1px solid #e6e6e6;">
+        <div class="label">额外领料卷数</div>
+        <p
+          class="value"
+          style="color: red; text-decoration:underline"
+        >{{ statistical.additionalNum }}</p>
+      </div>
+      <div class="item">
+        <div class="label">排班米数</div>
+        <p class="value">{{ statistical.planMeter }}</p>
+      </div>
+      <div class="item">
+        <div class="label">指定领料米数</div>
+        <p class="value">{{ statistical.appointMeter }}</p>
+      </div>
+      <div class="item" style="border-right: 1px solid #e6e6e6;">
+        <div class="label">实际领料米数</div>
+        <p class="value">{{ statistical.actualMeter }}</p>
+      </div>
+      <div class="item">
+        <div class="label">排班面积</div>
+        <p class="value">{{ statistical.planArea }}</p>
+      </div>
+      <div class="item">
+        <div class="label">指定领料面积</div>
+        <p class="value">{{ statistical.appointArea }}</p>
+      </div>
+      <div class="item" style="border-right: 1px solid #e6e6e6;">
+        <div class="label">实际领料面积</div>
+        <p class="value">{{ statistical.actualArea }}</p>
+      </div>
+      <div class="item" style="border-right: 1px solid #e6e6e6;">
+        <div class="label">指定领料产出比</div>
+        <p class="value">{{ parseFloat(Number(statistical.appointOutputRatio) * 100).toFixed(2) }}%</p>
+      </div>
+      <div class="item" style="border-right: 1px solid #e6e6e6;">
+        <div class="label" style="color: red">实际产出比</div>
+        <p class="value">{{ parseFloat(Number(statistical.actualOutputRatio) * 100).toFixed(2) }}%</p>
+      </div>
+      <div class="item">
+        <div class="label" style="color: red">产出比差额</div>
+        <p
+          class="value"
+        >{{ parseFloat(Number(statistical.outputRatioDifference) * 100).toFixed(2) }}%</p>
+      </div>
+    </div>
+    <div class="main">
+      <my-table :data="tableList" :columns="columns" :isShowPage="false"></my-table>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from 'axios'
+import MyTable from '_c/my-table/my-table'
+
+export default {
+  name: 'picking_tracking',
+  components: { MyTable },
+  data() {
+    return {
+      dataArea: [],
+      beginTime: '',
+      endTime: '',
+      type: '1',
+      dateTabs: [
+        { label: '本日', type: '1' },
+        { label: '本周', type: '2' },
+        { label: '本月', type: '3' },
+        { label: '今年', type: '4' }
+      ],
+      params: {
+        pageIndex: 1,
+        pageSize: 20,
+        total: 0
+      },
+      btnIndex: 0,
+      jobNo: '',
+      userList: [],
+      statistical: {},
+      tableList: [],
+      columns: [
+        {
+          title: '序号',
+          type: 'index',
+          width: 60,
+          align: 'center'
+        },
+        {
+          title: '指定领用面料',
+          key: 'realName',
+          minWidth: 200,
+          align: 'center'
+        },
+        {
+          title: '门幅',
+          key: 'width',
+          minWidth: 120,
+          align: 'center',
+          render: (h, params) => {
+            if (params.row.list[0].width !== void 0) {
+              return h(
+                'div',
+                {
+                  attrs: {
+                    class: 'subCol'
+                  }
+                },
+                [
+                  h(
+                    'ul',
+                    params.row.list.map(item => {
+                      return h('li', {}, item.width)
+                    })
+                  )
+                ]
+              )
+            } else {
+              return h('div', [h('span', '----')])
+            }
+          }
+        },
+        {
+          title: '指定领用卷数',
+          key: 'appointNum',
+          minWidth: 120,
+          align: 'center',
+          render: (h, params) => {
+            if (params.row.list[0].appointNum !== void 0) {
+              return h(
+                'div',
+                {
+                  attrs: {
+                    class: 'subCol'
+                  }
+                },
+                [
+                  h(
+                    'ul',
+                    params.row.list.map(item => {
+                      return h('li', {}, item.appointNum)
+                    })
+                  )
+                ]
+              )
+            } else {
+              return h('div', [h('span', '----')])
+            }
+          }
+        },
+        {
+          title: '实际领用卷数',
+          key: 'actualNum',
+          minWidth: 120,
+          align: 'center',
+          render: (h, params) => {
+            if (params.row.list[0].actualNum !== void 0) {
+              return h(
+                'div',
+                {
+                  attrs: {
+                    class: 'subCol'
+                  }
+                },
+                [
+                  h(
+                    'ul',
+                    params.row.list.map(item => {
+                      return h('li', {}, item.actualNum)
+                    })
+                  )
+                ]
+              )
+            } else {
+              return h('div', [h('span', '----')])
+            }
+          }
+        },
+        {
+          title: '指定领料未领卷数',
+          key: 'appointNotClaimedNum',
+          minWidth: 135,
+          align: 'center',
+          className: 'add-color',
+          render: (h, params) => {
+            if (params.row.list[0].appointNotClaimedNum !== void 0) {
+              return h(
+                'div',
+                {
+                  attrs: {
+                    class: 'subCol'
+                  }
+                },
+                [
+                  h(
+                    'ul',
+                    params.row.list.map(item => {
+                      return h(
+                        'li',
+                        {
+                          style: {
+                            color: 'red',
+                            cursor: 'pointer'
+                          },
+                          on: {
+                            click() {
+                              console.log(item)
+                            }
+                          }
+                        },
+                        item.appointNotClaimedNum
+                      )
+                    })
+                  )
+                ]
+              )
+            } else {
+              return h('div', [h('span', '----')])
+            }
+          }
+        },
+        {
+          title: '额外领料卷数',
+          key: 'additionalNum',
+          minWidth: 120,
+          align: 'center',
+          className: 'add-color',
+          render: (h, params) => {
+            if (params.row.list[0].additionalNum !== void 0) {
+              return h(
+                'div',
+                {
+                  attrs: {
+                    class: 'subCol'
+                  }
+                },
+                [
+                  h(
+                    'ul',
+                    params.row.list.map(item => {
+                      return h(
+                        'li',
+                        {
+                          style: {
+                            color: 'red',
+                            cursor: 'pointer'
+                          },
+                          on: {
+                            click() {
+                              console.log(item)
+                            }
+                          }
+                        },
+                        item.additionalNum
+                      )
+                    })
+                  )
+                ]
+              )
+            } else {
+              return h('div', [h('span', '----')])
+            }
+          }
+        },
+        {
+          title: '排班米数',
+          key: 'planMeter',
+          minWidth: 120,
+          align: 'center',
+          render: (h, params) => {
+            if (params.row.list[0].planMeter !== void 0) {
+              return h(
+                'div',
+                {
+                  attrs: {
+                    class: 'subCol'
+                  }
+                },
+                [
+                  h(
+                    'ul',
+                    params.row.list.map(item => {
+                      return h('li', {}, item.planMeter)
+                    })
+                  )
+                ]
+              )
+            } else {
+              return h('div', [h('span', '----')])
+            }
+          }
+        },
+        {
+          title: '指定领料米数',
+          key: 'appointMeter',
+          minWidth: 120,
+          align: 'center',
+          render: (h, params) => {
+            if (params.row.list[0].appointMeter !== void 0) {
+              return h(
+                'div',
+                {
+                  attrs: {
+                    class: 'subCol'
+                  }
+                },
+                [
+                  h(
+                    'ul',
+                    params.row.list.map(item => {
+                      return h('li', {}, item.appointMeter)
+                    })
+                  )
+                ]
+              )
+            } else {
+              return h('div', [h('span', '----')])
+            }
+          }
+        },
+        {
+          title: '指定领料面积',
+          key: 'appointArea',
+          minWidth: 120,
+          align: 'center',
+          render: (h, params) => {
+            if (params.row.list[0].appointArea !== void 0) {
+              return h(
+                'div',
+                {
+                  attrs: {
+                    class: 'subCol'
+                  }
+                },
+                [
+                  h(
+                    'ul',
+                    params.row.list.map(item => {
+                      return h('li', {}, item.appointArea)
+                    })
+                  )
+                ]
+              )
+            } else {
+              return h('div', [h('span', '----')])
+            }
+          }
+        },
+        {
+          title: '实际领料米数',
+          key: 'actualMeter',
+          minWidth: 120,
+          align: 'center',
+          render: (h, params) => {
+            if (params.row.list[0].actualMeter !== void 0) {
+              return h(
+                'div',
+                {
+                  attrs: {
+                    class: 'subCol'
+                  }
+                },
+                [
+                  h(
+                    'ul',
+                    params.row.list.map(item => {
+                      return h('li', {}, item.actualMeter)
+                    })
+                  )
+                ]
+              )
+            } else {
+              return h('div', [h('span', '----')])
+            }
+          }
+        },
+        {
+          title: '排班面数',
+          key: 'planArea',
+          minWidth: 120,
+          align: 'center',
+          render: (h, params) => {
+            if (params.row.list[0].planArea !== void 0) {
+              return h(
+                'div',
+                {
+                  attrs: {
+                    class: 'subCol'
+                  }
+                },
+                [
+                  h(
+                    'ul',
+                    params.row.list.map(item => {
+                      return h('li', {}, item.planArea)
+                    })
+                  )
+                ]
+              )
+            } else {
+              return h('div', [h('span', '----')])
+            }
+          }
+        },
+        {
+          title: '指定领料面积',
+          key: 'appointArea',
+          minWidth: 120,
+          align: 'center',
+          render: (h, params) => {
+            if (params.row.list[0].appointArea !== void 0) {
+              return h(
+                'div',
+                {
+                  attrs: {
+                    class: 'subCol'
+                  }
+                },
+                [
+                  h(
+                    'ul',
+                    params.row.list.map(item => {
+                      return h('li', {}, item.appointArea)
+                    })
+                  )
+                ]
+              )
+            } else {
+              return h('div', [h('span', '----')])
+            }
+          }
+        },
+        {
+          title: '实际领料面积',
+          key: 'actualArea',
+          minWidth: 120,
+          align: 'center',
+          render: (h, params) => {
+            if (params.row.list[0].actualArea !== void 0) {
+              return h(
+                'div',
+                {
+                  attrs: {
+                    class: 'subCol'
+                  }
+                },
+                [
+                  h(
+                    'ul',
+                    params.row.list.map(item => {
+                      return h('li', {}, item.actualArea)
+                    })
+                  )
+                ]
+              )
+            } else {
+              return h('div', [h('span', '----')])
+            }
+          }
+        },
+        {
+          title: '指定领料产出比',
+          key: 'appointOutputRatio',
+          minWidth: 120,
+          align: 'center',
+          render: (h, params) => {
+            if (params.row.list[0].appointOutputRatio !== void 0) {
+              return h(
+                'div',
+                {
+                  attrs: {
+                    class: 'subCol'
+                  }
+                },
+                [
+                  h(
+                    'ul',
+                    params.row.list.map(item => {
+                      return h(
+                        'li',
+                        {},
+                        parseFloat(
+                          Number(item.appointOutputRatio) * 100
+                        ).toFixed(2) + '%'
+                      )
+                    })
+                  )
+                ]
+              )
+            } else {
+              return h('div', [h('span', '----')])
+            }
+          }
+        },
+        {
+          title: '实际产出比',
+          key: 'actualOutputRatio',
+          minWidth: 120,
+          align: 'center',
+          className: 'add-color',
+          render: (h, params) => {
+            if (params.row.list[0].actualOutputRatio !== void 0) {
+              return h(
+                'div',
+                {
+                  attrs: {
+                    class: 'subCol'
+                  },
+                  style: {
+                    color: 'red'
+                  }
+                },
+                [
+                  h(
+                    'ul',
+                    params.row.list.map(item => {
+                      return h(
+                        'li',
+                        {},
+                        parseFloat(
+                          Number(item.actualOutputRatio) * 100
+                        ).toFixed(2) + '%'
+                      )
+                    })
+                  )
+                ]
+              )
+            } else {
+              return h('div', [h('span', '----')])
+            }
+          }
+        },
+        {
+          title: '产出比差额',
+          key: 'outputRatioDifference',
+          minWidth: 120,
+          align: 'center',
+          className: 'add-color',
+          render: (h, params) => {
+            if (params.row.list[0].outputRatioDifference !== void 0) {
+              return h(
+                'div',
+                {
+                  attrs: {
+                    class: 'subCol'
+                  },
+                  style: {
+                    color: 'red'
+                  }
+                },
+                [
+                  h(
+                    'ul',
+                    params.row.list.map(item => {
+                      return h(
+                        'li',
+                        {},
+                        parseFloat(
+                          Number(item.outputRatioDifference) * 100
+                        ).toFixed(2) + '%'
+                      )
+                    })
+                  )
+                ]
+              )
+            } else {
+              return h('div', [h('span', '----')])
+            }
+          }
+        }
+      ]
+    }
+  },
+  mounted() {
+    this.dateTabToggle('1')
+  },
+  methods: {
+    handleSpan({ row, column, rowIndex, columnIndex }) {
+      console.log(row, column, rowIndex, columnIndex)
+      if (rowIndex === 0 && columnIndex === 0) {
+        return [1, 2]
+      } else if (rowIndex === 0 && columnIndex === 1) {
+        return [0, 0]
+      }
+      if (rowIndex === 2 && columnIndex === 0) {
+        return {
+          rowspan: 2,
+          colspan: 1
+        }
+      } else if (rowIndex === 3 && columnIndex === 0) {
+        return {
+          rowspan: 0,
+          colspan: 0
+        }
+      }
+    },
+    dateClick(date) {
+      this.beginTime = date[0]
+      this.endTime = date[1]
+      this.type = '99'
+      this.getUserList()
+      this.getList()
+    },
+    /* 选项卡切换 */
+    dateTabToggle(index) {
+      this.params.pageIndex = 1
+      this.type = index
+      if (index === '1') {
+        let time = new Date().getTime()
+        this.beginTime = this.$dayjs(time).format('YYYY-MM-DD HH:mm:ss')
+        this.endTime = this.$dayjs(time).format('YYYY-MM-DD HH:mm:ss')
+        this.dataArea = [this.beginTime, this.endTime]
+      } else if (index === '2') {
+        let Nowdate = new Date()
+        let WeekFirstDay = Nowdate.getDay()
+          ? new Date(Nowdate - (Nowdate.getDay() - 1) * 86400000)
+          : new Date(Nowdate - (Nowdate.getDay() + 6) * 86400000)
+        let WeekLastDay = new Date((WeekFirstDay / 1000 + 6 * 86400) * 1000)
+        this.beginTime = this.$dayjs(WeekFirstDay).format('YYYY-MM-DD HH:mm:ss')
+        this.endTime = this.$dayjs(WeekLastDay).format('YYYY-MM-DD HH:mm:ss')
+        this.dataArea = [this.beginTime, this.endTime]
+      } else if (index === '3') {
+        let now = new Date() // 当前日期
+        let nowMonth = now.getMonth() // 当前月
+        let nowYear = now.getFullYear() // 当前年
+        // 本月的开始时间
+        let monthStartDate = new Date(nowYear, nowMonth, 1)
+        // 本月的结束时间
+        let monthEndDate = new Date(nowYear, nowMonth + 1, 0)
+        this.beginTime = this.$dayjs(monthStartDate).format(
+          'YYYY-MM-DD HH:mm:ss'
+        )
+        this.endTime = this.$dayjs(monthEndDate).format('YYYY-MM-DD HH:mm:ss')
+        this.dataArea = [this.beginTime, this.endTime]
+      } else if (index === '4') {
+        let now = new Date() // 当前日期
+        let nowYear = now.getFullYear() // 当前年
+        // 本年的开始时间
+        let monthStartDate = new Date(nowYear, 0, 1)
+        // 本年的结束时间
+        let monthEndDate = new Date(nowYear, 11, 31)
+        this.beginTime = this.$dayjs(monthStartDate).format(
+          'YYYY-MM-DD HH:mm:ss'
+        )
+        this.endTime = this.$dayjs(monthEndDate).format('YYYY-MM-DD HH:mm:ss')
+        this.dataArea = [this.beginTime, this.endTime]
+      }
+      this.btnIndex = 0
+      this.jobNo = ''
+      this.getUserList()
+      this.getList()
+    },
+    getUserList() {
+      axios
+        .post('/cloudApi/stockDetail/pickingTrackingUserStatistics', {
+          type: this.type,
+          beginTime: this.beginTime,
+          endTime: this.endTime
+        })
+        .then(res => {
+          this.userList = res.data.data
+        })
+    },
+    getList() {
+      axios
+        .post('/cloudApi/stockDetail/pickingTrackingNumStatistics', {
+          type: this.type,
+          beginTime: this.beginTime,
+          endTime: this.endTime,
+          jobNo: this.jobNo
+        })
+        .then(res => {
+          this.statistical = res.data.data
+        })
+      axios
+        .post('/cloudApi/stockDetail/pickingTrackingList', {
+          type: this.type,
+          beginTime: this.beginTime,
+          endTime: this.endTime,
+          jobNo: this.jobNo
+        })
+        .then(res => {
+          let list = res.data.data
+          if (list && list.length > 0) {
+            let data = []
+            for (let i = 0; i < list.length; i++) {
+              data.push({
+                realName: Object.keys(list[i])[0],
+                list: list[i][Object.keys(list[i])[0]]
+              })
+            }
+            this.tableList = data
+          } else {
+            this.tableList = []
+          }
+        })
+    },
+    userClick(value = '', index) {
+      this.jobNo = value
+      this.btnIndex = index
+      this.getList()
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.container {
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  .tab-nav {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    .date-filter-wrap {
+      display: flex;
+      align-items: center;
+      .date-filter {
+        width: 300px;
+        overflow: hidden;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        background-color: #ffffff;
+        border-radius: 4px;
+        &.other {
+          width: 100%;
+          height: 100%;
+          .date-tab {
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            justify-content: center;
+            padding: 9px;
+            height: 100%;
+            white-space: nowrap;
+            cursor: auto;
+            &.active {
+              background-color: #333333;
+              font-size: 14px;
+              font-weight: bold;
+            }
+            .num {
+              padding-top: 5px;
+              font-weight: bold;
+              font-size: 14px;
+              &.red {
+                color: red;
+                cursor: pointer;
+                text-decoration: underline;
+              }
+            }
+          }
+        }
+        .date-tab {
+          flex: 1;
+          padding: 9px 4px;
+          line-height: 1;
+          text-align: center;
+          border: 1px solid #e6e6e6;
+          border-radius: 2px;
+          border-right: none;
+          cursor: pointer;
+          font-weight: 500;
+          &:first-child {
+            border-radius: 4px 0 0 4px;
+          }
+          &:last-child {
+            border-radius: 0 4px 4px 0;
+            border-right: 1px solid #e6e6e6;
+          }
+          &.active {
+            background-color: #3f92f9;
+            color: #ffffff;
+          }
+        }
+      }
+    }
+    &.sub-nav {
+      .other-tab {
+        flex: 1;
+        height: 100%;
+        display: flex;
+        flex-direction: column;
+        padding: 5px 10px;
+        text-align: center;
+        border: 1px solid #e6e6e6;
+        border-right: none;
+        font-weight: bold;
+        cursor: pointer;
+        white-space: nowrap;
+        &:first-child {
+          border-radius: 2px 0 0 2px;
+        }
+        &:last-child {
+          border-radius: 0 2px 2px 0;
+          border-right: 1px solid #e6e6e6;
+        }
+        &.active {
+          background-color: #ffffff !important;
+          color: blue !important;
+          border: 1px solid blue;
+        }
+      }
+    }
+    .all {
+      margin-right: 20px;
+    }
+    .row {
+      white-space: nowrap;
+      button {
+        margin-right: 10px;
+        min-width: 120px;
+        &:last-child {
+          margin-right: 0;
+        }
+      }
+    }
+  }
+  .table-filter {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    .item {
+      height: 100%;
+      padding: 10px 0;
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      overflow: hidden;
+      background-color: #ffffff;
+      &:first-child {
+        border-radius: 5px 0 0 5px;
+      }
+      &:last-child {
+        border-radius: 0 5px 5px 0;
+        border-right: 1px solid #e6e6e6;
+      }
+      .label {
+        display: flex;
+        justify-content: center;
+        align-items: center;
+      }
+      .value {
+        font-size: 16px;
+        font-weight: bold;
+        &.red {
+          color: red;
+        }
+      }
+    }
+  }
+  .main {
+    flex: 1;
+    overflow: hidden;
+  }
+  .border {
+    margin: 10px 0;
+    width: 100%;
+    height: 1px;
+    background-color: #d7d7d7;
+  }
+}
+::v-deep {
+  .subCol > ul > li {
+    margin: 0 -18px;
+    list-style: none;
+    padding: 9px;
+    border-bottom: 1px solid #ccc;
+    overflow-x: hidden;
+    height: 48px; /*看单元格内容*/
+    padding-left: 18px;
+    line-height: 28px;
+  }
+  .subCol > ul > li:last-child {
+    border-bottom: none;
+  }
+  .ivu-table-row {
+    td {
+      border-right: 1px solid #ccc;
+    }
+  }
+  .add-color {
+    color: red;
+  }
+}
+</style>