瀏覽代碼

Merge remote-tracking branch 'origin/demo_' into demo_

hfxc226 2 年之前
父節點
當前提交
2ed955b1b7

+ 18 - 0
src/api/report/repair-chart.js

@@ -0,0 +1,18 @@
+import { axios } from '@/utils/request'
+import { stringify } from 'qs'
+
+/**
+ * page func
+ * parameter: { }
+ * @param parameter
+ * @returns {*}
+ */
+export function getRepairReport (parameter) {
+  return axios({
+    url: '/repair/application-forms/repair/report?' + stringify(parameter),
+    method: 'get',
+    headers: {
+      'Content-Type': 'application/json;charset=UTF-8'
+    }
+  })
+}

+ 15 - 0
src/api/report/sbinfo.js

@@ -33,3 +33,18 @@ export function exportMonthReport (parameter) {
     responseType: 'blob'
   })
 }
+/**
+ * page func
+ * parameter: { }
+ * @param parameter
+ * @returns {*}
+ */
+export function getSbType () {
+  return axios({
+    url: '/sb/types',
+    method: 'get',
+    headers: {
+      'Content-Type': 'application/json;charset=UTF-8'
+    }
+  })
+}

+ 125 - 0
src/components/ChartView/index.vue

@@ -0,0 +1,125 @@
+<template>
+  <div class="chart">
+    <div ref="chart" :style="{height: height, width: width }" />
+  </div>
+</template>
+
+<script>
+// 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
+import * as echarts from 'echarts/core'
+// 引入柱状图图表,图表后缀都为 Chart
+import { BarChart, PieChart, LineChart, MapChart, GaugeChart } from 'echarts/charts'
+// 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
+import {
+  TitleComponent,
+  TooltipComponent,
+  LegendComponent,
+  GridComponent,
+  MarkPointComponent,
+  GeoComponent
+  // DatasetComponent,
+  // TransformComponent
+} from 'echarts/components'
+// 标签自动布局、全局过渡动画等特性
+import { LabelLayout, UniversalTransition } from 'echarts/features'
+// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
+import { CanvasRenderer } from 'echarts/renderers'
+
+// 注册必须的组件
+echarts.use([
+  TitleComponent,
+  TooltipComponent,
+  GridComponent,
+  LegendComponent,
+  GeoComponent,
+  // DatasetComponent,
+  // TransformComponent,
+  MarkPointComponent,
+  BarChart,
+  PieChart,
+  MapChart,
+  GaugeChart,
+  LineChart,
+  LabelLayout,
+  UniversalTransition,
+  CanvasRenderer
+])
+export default {
+  name: 'ChartView',
+  props: {
+    width: {
+      type: String,
+      default: '100%'
+    },
+    height: {
+      type: String,
+      default: '100%'
+    },
+    autoResize: {
+      type: Boolean,
+      default: true
+    },
+    chartOption: {
+      type: Object,
+      required: true
+    }
+  },
+  data() {
+    return {
+      chart: null
+    }
+  },
+  watch: {
+    chartOption: {
+      deep: true,
+      handler(newVal) {
+        this.setOptions(newVal)
+      }
+    }
+  },
+  mounted() {
+    this.initChart()
+    if (this.autoResize) {
+      window.addEventListener('resize', this.resizeHandler)
+    }
+  },
+  beforeDestroy() {
+    if (!this.chart) {
+      return
+    }
+    if (this.autoResize) {
+      window.removeEventListener('resize', this.resizeHandler)
+    }
+    this.chart.dispose()
+    this.chart = null
+  },
+  methods: {
+    resizeHandler() {
+      this.chart.resize()
+    },
+    initChart() {
+      this.chart = echarts.init(this.$refs.chart)
+      this.chart.setOption(this.chartOption, true)
+      this.chart.on('click', this.handleClick)
+      window.removeEventListener('resize', this.resizeHandler)
+    },
+    handleClick(params) {
+      this.$emit('click', params)
+    },
+    setOptions(option) {
+      this.clearChart()
+      this.resizeHandler()
+      if (this.chart) {
+        this.chart.setOption(option, true)
+      }
+    },
+    clearChart() {
+      this.chart && this.chart.clear()
+    }
+  }
+}
+</script>
+
+<style>
+
+</style>

+ 4 - 3
src/main.js

@@ -20,9 +20,10 @@ import './utils/filter' // global filter
 import BaseTool from './utils/install'
 // import echarts from 'echarts'
 import VueI18n from 'vue-i18n'
-import Print from 'vue-print-nb'
-Vue.use(Print) // 注册
-
+import Print from 'vue-print-nb' // 注册
+import ChartPanel from '@/components/ChartView/index.vue'
+Vue.use(Print)
+Vue.component(ChartPanel.name, ChartPanel)
 // Vue.prototype.$echarts = echarts
 Vue.config.productionTip = false
 

+ 1 - 0
src/router/generator-platform-routers.js

@@ -344,6 +344,7 @@ const constantRouterComponents = {
   'SbInfoStandard': () => import('@/views/sb/info/SbInfoStandard'),
 
   // 报表
+  'RepairDetail': () => import('@/views/report/repairdetail/RepairDetail'), // 维修报表
   'AnalysisSbInfo': () => import('@/views/dashboard/AnalysisSbInfo'), // 保养任务完成率报表
   'CheckJobReport': () => import('@/views/dashboard/CheckJobReport'), // 保养任务完成率报表
   'MeasureLogReport': () => import('@/views/dashboard/MeasureLogReport'), // 检定记录月完成数量报表

+ 18 - 3
src/views/dashboard/SbInfoTypeReport.vue

@@ -4,7 +4,8 @@
       <div class="salesCard">
         <a-tabs default-active-key="1" size="large" :tab-bar-style="{marginBottom: '24px', paddingLeft: '16px'}">
           <div class="table-operator" style="margin-bottom: 8px;margin-top: 8px;" slot="tabBarExtraContent">
-            <a-select style="margin-left: 8px" v-model="queryParam.useType" placeholder="请选择">
+
+            <a-select style="margin-left: 8px;width:150px" v-model="queryParam.useType" placeholder="请选择">
               <a-select-option
                 v-for="(label,value) in useTypeMap"
                 :key="value"
@@ -12,6 +13,14 @@
                 :value="parseInt(value)">{{ label }}
               </a-select-option>
             </a-select>
+            <a-select style="margin-left: 8px;width:150px" v-model="queryParam.typeId" placeholder="请选择">
+              <a-select-option
+                v-for="{name,id} in typeList"
+                :key="id"
+                :label="name"
+                :value="id">{{ name }}
+              </a-select-option>
+            </a-select>
             <a-button style="margin-left: 8px" type="default" @click="getData()">查询</a-button>
             <a-button style="margin-left: 8px" type="primary" @click="handlePrint()">打印</a-button>
             <a-button style="margin-left: 8px" type="primary" @click="doExport()">导出</a-button>
@@ -58,7 +67,7 @@
 </template>
 
 <script>
-import { getMonthReport, exportMonthReport } from '@/api/report/sbinfo'
+import { getMonthReport, exportMonthReport, getSbType } from '@/api/report/sbinfo'
 import { Chart } from '@antv/g2'
 import PrintInSbInfoTypeReport from '@/views/dashboard/modules/PrintInSbInfoTypeReport'
 import DetailMeasureLogReport from '@/views/dashboard/modules/DetailMeasureLogReport'
@@ -82,8 +91,10 @@ export default {
       loading: false,
       useTypeMap: {},
       queryParam: {
-        useType: 4
+        useType: 4,
+        typeId: ''
       },
+      typeList: [],
       visible: true,
       chart: null, // 创建一个chart变量
       chartsData: [],
@@ -126,6 +137,10 @@ export default {
   },
   created () {
     this.useTypeMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.SB_USE_TYPE)
+    getSbType().then(res => {
+      console.log(res)
+      this.typeList = res.data
+    })
   },
   mounted () {
     this.$nextTick(function () {

+ 20 - 7
src/views/repair/application-form/modules/BaseForm.vue

@@ -139,22 +139,30 @@
             </a-tree-select>
           </a-form-item>
         </row-item>
-        <!-- <row-item>
+        <row-item v-if="inputType===1">
           <a-form-item
-            label="生产装置"
+            label="车间位置"
             :labelCol="BaseTool.Constant.labelCol"
             :wrapperCol="BaseTool.Constant.wrapperCol"
           >
-            <a-cascader
+            <a-select v-decorator="['positionId', {rules: [{required: true, message: '车间位置不能为空'}]}]" placeholder="请选择">
+              <a-select-option
+                v-for="({id,name}) in sbPositionData"
+                :key="id"
+                :label="name"
+                :value="id">{{ name }}
+              </a-select-option>
+            </a-select>
+            <!-- <a-cascader
               :options="sbPositionList"
               :load-data="loadData"
               placeholder="请选择"
               change-on-select
               @change="sbPositionChange"
-              v-decorator="['sbPosition', {rules: [{required: true, message: '生产装置不能为空'}]}]"
-            />
+              v-decorator="['sbPosition', {rules: [{required: true, message: '车间位置不能为空'}]}]"
+            /> -->
           </a-form-item>
-        </row-item> -->
+        </row-item>
         <row-item>
           <a-form-item
             label="特殊作业类型"
@@ -476,6 +484,7 @@ import { uploadUrl } from '@/api/upms/file'
 import Vue from 'vue'
 import { ACCESS_TOKEN } from '@/store/mutation-types'
 import { fetchErrorTypeTree } from '@/api/repair/errortype'
+import { querySbPosition } from '@/api/sb/position'
 import { TreeSelect } from 'ant-design-vue'
 const SHOW_PARENT = TreeSelect.SHOW_PARENT
 export default {
@@ -499,6 +508,8 @@ export default {
       questionMap: {},
       dispatchUserList: {},
       treeData: [],
+      sbPositionData: [],
+
       needStop: null,
       needStopMap: {},
       category: 0,
@@ -543,6 +554,9 @@ export default {
     this.professorMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.REPAIR_APPLICATION_PROFESSOR)
     this.getUsers()
     this.getSbPositions()
+    querySbPosition().then(res => {
+      this.sbPositionData = res.data
+    })
   },
   methods: {
     base (record) {
@@ -684,7 +698,6 @@ export default {
         values.applicationFileList = this.applicationFileList
         values.reportFileList = this.reportFileList
         // values.sbPosition = values.sbPosition.join('->')
-        values.positionId = this.positionId
         console.log(values)
         if (values.partId === undefined) {
           values.partId = ''

+ 273 - 0
src/views/report/repairdetail/RepairDetail.vue

@@ -0,0 +1,273 @@
+<template>
+  <div class="page-header-index-wide">
+    <a-card title="出入库数据" :loading="loading" v-show="visible" :bordered="false" :body-style="{padding: '0'}">
+      <div class="salesCard">
+        <a-tabs default-active-key="1" size="large" :tab-bar-style="{marginBottom: '24px', paddingLeft: '16px'}">
+          <div class="extra-wrapper" slot="tabBarExtraContent">
+            <a-row :gutter="8">
+              <a-col :md="6" :sm="24">
+                <a-date-picker
+                  mode="year"
+                  style="width:150px"
+                  :format="monthFormat"
+                  v-model="queryParam.searchYear"
+                  placeholder="请输入年份"
+                  @panelChange="getData"
+                />
+              </a-col>
+              <!-- <a-col :md="2" :sm="24">
+                <a-button style="margin-left: 8px" type="primary" @click="handlePrint()">打印</a-button>
+              </a-col> -->
+              <!-- <a-col :md="2" :sm="24">
+                <a-button style="margin-left: 8px" type="primary" @click="doExport()">导出</a-button>
+              </a-col> -->
+            </a-row>
+          </div>
+          <a-tab-pane loading="true" tab="图形统计" key="1">
+            <a-row>
+              <a-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24">
+                <chart-view :chartOption="chartOption" width="100%" height="600px" />
+              </a-col>
+            </a-row>
+          </a-tab-pane>
+          <!-- <a-tab-pane loading="true" tab="表格统计" key="2">
+            <a-row>
+              <a-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24">
+                <div style="padding: 10px">
+                  <a-table
+                    bordered
+                    :data-source="chartsData"
+                    :columns="columns"
+                    tableLayout="auto"
+                    :scroll="{x: 1, y: BaseTool.Constant.scrollY }"
+                    rowKey="month">
+                    <span slot="action" slot-scope="record">
+                      <template>
+                        <a @click="handleView(record)">查看明细</a>
+                        <a-divider type="vertical" />
+                      </template>
+                    </span>
+                  </a-table>
+                </div>
+              </a-col>
+            </a-row>
+          </a-tab-pane> -->
+        </a-tabs>
+      </div>
+    </a-card>
+  </div>
+</template>
+
+<script>
+import { getRepairReport } from '@/api/report/repair-chart'
+import { Chart } from '@antv/g2'
+import moment from 'moment'
+
+export default {
+  name: 'Analysis',
+  components: {
+    Chart
+  },
+  props: {
+    title: {
+      type: String,
+      default: '保养任务月统计报表'
+    }
+  },
+  data () {
+    return {
+      loading: false,
+      serverData: [],
+      sbLevelMap: {},
+      treeData: [],
+      monthFormat: 'YYYY',
+      queryParam: {
+        searchYear: null
+      },
+      visible: true,
+      chart: null, // 创建一个chart变量
+      chartsData: {},
+      // 表头
+      columns: [
+        {
+          title: '月份',
+          width: 180,
+          dataIndex: 'month'
+        },
+        {
+          title: '数量',
+          width: 120,
+          dataIndex: 'totalNum'
+        },
+        {
+          title: '完成数量',
+          width: 120,
+          dataIndex: 'totalFinishNum'
+        },
+        {
+          title: '未完成数量',
+          width: 120,
+          dataIndex: 'totalWaitNum'
+        },
+        {
+          title: '完成率',
+          width: 120,
+          dataIndex: 'finishRate'
+        },
+        {
+          title: '操作',
+          key: 'action',
+          width: '200px',
+          align: 'center',
+          scopedSlots: { customRender: 'action' }
+        }
+      ]
+    }
+  },
+  computed: {
+    chartOption () {
+      return {
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          }
+        },
+        legend: {},
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '3%',
+          containLabel: true
+        },
+        yAxis: {
+          type: 'value',
+          boundaryGap: [0, 0.01]
+        },
+        xAxis: {
+          type: 'category',
+          data: this.chartsData.keys
+        },
+        series: [
+          {
+            name: this.chartsData.dianQiName,
+            type: 'bar',
+            data: this.chartsData.dianQiNums
+          },
+          {
+            name: this.chartsData.jiXiName,
+            type: 'bar',
+            data: this.chartsData.jiXiNums
+          },
+          {
+            name: this.chartsData.yiBiaoName,
+            type: 'bar',
+            data: this.chartsData.yiBiaoNums
+          }
+        ]
+      }
+    }
+  },
+  created () {
+
+  },
+  mounted () {
+    this.$nextTick(function () {
+      this.getData()
+    })
+  },
+  methods: {
+    moment,
+    getData (val) {
+      console.log(val)
+      const params = {}
+      params.searchYear = this.BaseTool.Date.formatter(val, this.monthFormat)
+      this.queryParam.searchYear = params.searchYear
+      getRepairReport(params)
+        .then(res => {
+          console.log(res.data)
+          // 需要将数据分组:总数,完成数
+          this.chartsData = {}
+          const keys = []
+          const jiXiNums = []
+          const dianQiNums = []
+          const yiBiaoNums = []
+
+          for (const [key, value] of Object.entries(res.data)) {
+            keys.push(key)
+            jiXiNums.push(value.jiXiNum)
+            dianQiNums.push(value.dianQiNum)
+            yiBiaoNums.push(value.yiBiaoNum)
+          }
+          this.chartsData = { keys, jiXiNums, dianQiNums, yiBiaoNums }
+          this.chartsData.dianQiName = res.data[1].dianQiName
+          this.chartsData.jiXiName = res.data[1].jiXiName
+          this.chartsData.yiBiaoName = res.data[1].yiBiaoName
+          console.log(this.chartsData)
+        })
+    },
+    // handlePrint (record) {
+    //   const modal = this.$refs.basePrintModal
+    //   this.visible = false
+    //   modal.base({ startMonth: this.queryParam.startMonth, endMonth: this.queryParam.endMonth, title: this.title, data: this.chartsData })
+    // },
+    // handleView (record) {
+    //   const modal = this.$refs.detailModal
+    //   modal.base(record)
+    // },
+    handleOk () {
+      this.visible = true
+    },
+    reset () {
+      this.queryParam = {
+      }
+      this.getData()
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.extra-wrapper {
+  line-height: 55px;
+  padding-right: 24px;
+
+  .extra-item {
+    display: inline-block;
+    margin-right: 24px;
+
+    a {
+      margin-left: 24px;
+    }
+  }
+}
+
+.antd-pro-pages-dashboard-analysis-twoColLayout {
+  position: relative;
+  display: flex;
+  display: block;
+  flex-flow: row wrap;
+}
+
+.antd-pro-pages-dashboard-analysis-salesCard {
+  height: calc(100% - 24px);
+  /deep/ .ant-card-head {
+    position: relative;
+  }
+}
+
+.dashboard-analysis-iconGroup {
+  i {
+    margin-left: 16px;
+    color: rgba(0,0,0,.45);
+    cursor: pointer;
+    transition: color .32s;
+    color: black;
+  }
+}
+.analysis-salesTypeRadio {
+  position: absolute;
+  right: 54px;
+  bottom: 12px;
+}
+</style>