From dacf37deb3d53345024402016e9c4d19ac82e3aa Mon Sep 17 00:00:00 2001 From: cuilei <ray_tsu1@163.com> Date: 星期四, 07 八月 2025 10:29:19 +0800 Subject: [PATCH] 生产管控 排产工单页面 --- src/views/mes/MesProductionWorkOrderList.vue | 780 ++++++++++++++++++++--------- src/views/mes/modules/MesProductionWorkOrderRepublishModal.vue | 132 +++++ src/views/mes/modules/MesProductionWeekCalendar.vue | 241 +++++++++ src/views/mes/modules/MesProductionWorkOrderForm.vue | 18 src/views/mes/modules/MesProductionWorkOrderListModal.vue | 375 ++++++++++++++ src/views/mes/modules/MesProductionWorkOrderModal.vue | 2 6 files changed, 1,298 insertions(+), 250 deletions(-) diff --git a/src/views/mes/MesProductionWorkOrderList.vue b/src/views/mes/MesProductionWorkOrderList.vue index d81fb4d..8d1fe7d 100644 --- a/src/views/mes/MesProductionWorkOrderList.vue +++ b/src/views/mes/MesProductionWorkOrderList.vue @@ -1,266 +1,566 @@ <template> - <a-card :bordered="false"> - <!-- 鏌ヨ鍖哄煙 --> - <div class="table-page-search-wrapper"> - <a-form layout="inline" @keyup.enter.native="searchQuery"> - <a-row :gutter="24"> - <a-col :xl="6" :lg="7" :md="8" :sm="24"> - <a-form-item label="宸ュ崟鍙�(浠诲姟鍙�)"> - <j-input placeholder="璇疯緭鍏ュ伐鍗曞彿(浠诲姟鍙�)" v-model="queryParam.workOrderCode"></j-input> - </a-form-item> - </a-col> - <a-col :xl="6" :lg="7" :md="8" :sm="24"> - <a-form-item label="鐗╂枡缂栧彿"> - <j-input placeholder="璇疯緭鍏ョ墿鏂欑紪鍙�" v-model="queryParam.materialNumber"></j-input> - </a-form-item> - </a-col> - <a-col :xl="6" :lg="7" :md="8" :sm="24"> - <a-form-item label="宸ュ崟鐘舵��"> - <j-dict-select-tag dictCode="work_order_status" placeholder="璇疯緭鍏ュ伐鍗曠姸鎬�" v-model="queryParam.workOrderStatus"></j-dict-select-tag> - </a-form-item> - </a-col> - <a-col :xl="6" :lg="7" :md="8" :sm="24"> - <a-form-item label="閲嶅彂甯冧汉"> - <j-select-user-by-dep placeholder="璇疯緭鍏ラ噸鍙戝竷浜�" v-model="queryParam.republisher"></j-select-user-by-dep> - </a-form-item> - </a-col> - <a-col :xl="6" :lg="7" :md="8" :sm="24"> + <a-row :gutter="{ xs: 4, sm: 8, md: 16}"> + <a-col :span="12"> + <a-card :bordered="false"> + <!-- 鏌ヨ鍖哄煙 --> + <div class="table-page-search-wrapper"> + <a-form layout="inline" @keyup.enter.native="searchQuery"> + <a-row :gutter="24"> + <a-col :span="12"> + <a-form-item label="浜х嚎"> + <j-tree-select dict="base_factory,factory_name,id" pid-field="parent_id" + v-model="queryParam.factoryId"></j-tree-select> + </a-form-item> + </a-col> + <a-col :span="12"> + <a-form-item label="璧锋鏃ユ湡"> + <a-range-picker + style="width: 100%" + @change="dateRangeChange" + :value="dateRange" + :disabledDate="disabledDate" + @openChange="onOpenChange" + /> + </a-form-item> + </a-col> + <a-col :xl="6" :lg="7" :md="8" :sm="24"> <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons"> <a-button type="primary" @click="searchQuery" icon="search">鏌ヨ</a-button> - <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">閲嶇疆</a-button> + <a-button type="info" @click="searchReset" icon="reload" style="margin-left: 8px">閲嶇疆</a-button> + <a-button type="primary" @click="productionSchedule" icon="retweet" + style="margin-left: 8px">鎺掍骇</a-button> </span> - </a-col> - </a-row> - </a-form> - </div> + </a-col> + </a-row> + </a-form> + </div> - <div class="table-operator"> - <a-dropdown v-if="selectedRowKeys.length > 0"> - <a-menu slot="overlay"> - <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>鍒犻櫎</a-menu-item> - </a-menu> - <a-button style="margin-left: 8px"> 鎵归噺鎿嶄綔 <a-icon type="down" /></a-button> - </a-dropdown> - </div> - <div> - <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;"> - <i class="anticon anticon-info-circle ant-alert-icon"></i> 宸查�夋嫨 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>椤� - <a style="margin-left: 24px" @click="onClearSelected">娓呯┖</a> - </div> - - <a-table - ref="table" - size="middle" - :scroll="{x:true}" - bordered - rowKey="id" - :columns="columns" - :dataSource="dataSource" - :pagination="ipagination" - :loading="loading" - :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}" - class="j-table-force-nowrap" - @change="handleTableChange"> - - <template slot="htmlSlot" slot-scope="text"> - <div v-html="text"></div> - </template> - <template slot="imgSlot" slot-scope="text,record"> - <span v-if="!text" style="font-size: 12px;font-style: italic;">鏃犲浘鐗�</span> - <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/> - </template> - <template slot="fileSlot" slot-scope="text"> - <span v-if="!text" style="font-size: 12px;font-style: italic;">鏃犳枃浠�</span> - <a-button - v-else - :ghost="true" - type="primary" - icon="download" - size="small" - @click="downloadFile(text)"> - 涓嬭浇 - </a-button> - </template> - - <span slot="action" slot-scope="text, record"> - <a @click="handleEdit(record)">缂栬緫</a> - - <a-divider type="vertical" /> - <a-dropdown> - <a class="ant-dropdown-link">鏇村 <a-icon type="down" /></a> + <div class="table-operator"> + <a-dropdown v-if="selectedRowKeys.length > 0"> <a-menu slot="overlay"> - <a-menu-item> - <a @click="handleDetail(record)">璇︽儏</a> - </a-menu-item> - <a-menu-item> - <a-popconfirm title="纭畾鍒犻櫎鍚�?" @confirm="() => handleDelete(record.id)"> - <a>鍒犻櫎</a> - </a-popconfirm> + <a-menu-item key="1" @click="batchDel"> + <a-icon type="delete" /> + 鍒犻櫎 </a-menu-item> </a-menu> + <a-button style="margin-left: 8px"> 鎵归噺鎿嶄綔 + <a-icon type="down" /> + </a-button> </a-dropdown> + </div> + <div> + <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;"> + <i class="anticon anticon-info-circle ant-alert-icon"></i> 宸查�夋嫨 <a + style="font-weight: 600">{{ selectedRowKeys.length }}</a>椤� + <a style="margin-left: 24px" @click="onClearSelected">娓呯┖</a> + </div> + + <a-table + ref="table" + size="middle" + :scroll="{x:true}" + bordered + rowKey="id" + :columns="columns" + :dataSource="dataSource" + :pagination="ipagination" + :loading="loading" + :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}" + class="j-table-force-nowrap" + @change="handleTableChange"> + + <template slot="htmlSlot" slot-scope="text"> + <div v-html="text"></div> + </template> + <template slot="imgSlot" slot-scope="text,record"> + <span v-if="!text" style="font-size: 12px;font-style: italic;">鏃犲浘鐗�</span> + <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" + style="max-width:80px;font-size: 12px;font-style: italic;" /> + </template> + <template slot="fileSlot" slot-scope="text"> + <span v-if="!text" style="font-size: 12px;font-style: italic;">鏃犳枃浠�</span> + <a-button + v-else + :ghost="true" + type="primary" + icon="download" + size="small" + @click="downloadFile(text)"> + 涓嬭浇 + </a-button> + </template> + + <span slot="action" slot-scope="text, record"> + <span v-if="record.workOrderStatus === 'NEW'"> + <a-popconfirm title="纭畾鍙戝竷鍚�?" @confirm="() => handlePublish(record.id)"> + <a>鍙戝竷</a> + </a-popconfirm> + <a-divider type="vertical" /> + </span> + <span v-if="record.workOrderStatus === 'PUBLISHED'"> + <a @click="handleRePublish(record)">閲嶅彂甯�</a> + <a-divider type="vertical" /> + </span> + <span> + <a-dropdown v-if="record.workOrderStatus === 'NEW'"> + <a class="ant-dropdown-link">鏇村 <a-icon type="down" /></a> + <a-menu slot="overlay"> + <a-menu-item> + <a @click="handleDetail(record)">璇︽儏</a> + </a-menu-item> + <a-menu-item> + <a-popconfirm title="纭畾鍒犻櫎鍚�?" @confirm="() => handleDelete(record.id)"> + <a>鍒犻櫎</a> + </a-popconfirm> + </a-menu-item> + </a-menu> + </a-dropdown> + </span> + <span v-if="record.workOrderStatus !== 'NEW'"> + <a @click="handleDetail(record)">璇︽儏</a> + </span> </span> + </a-table> + </div> - </a-table> - </div> - - <mes-production-work-order-modal ref="modalForm" @ok="modalFormOk"></mes-production-work-order-modal> - </a-card> + <mes-production-work-order-list-modal ref="modal" @ok="modalFormOk"></mes-production-work-order-list-modal> + <mes-production-work-order-modal ref="modalForm"></mes-production-work-order-modal> + <mes-production-work-order-republish-modal ref="republishModal" @ok="modalFormOk"></mes-production-work-order-republish-modal> + </a-card> + </a-col> + <a-col :span="12"> + <a-card> + <MesProductionWeekCalendar + ref="weekCalendar" + :start-date="calendarStartDate" + @select="onDateSelect" + @change="onCalendarChange" + > + <!-- 浣跨敤鎻掓Ы鑷畾涔夋棩鏈熷崟鍏冩牸鍐呭 --> + <template #dateCell="{ date, isSelected, isToday }"> + <div class="custom-date-content"> + <!-- 绀轰緥锛氬湪鏃ユ湡鍗曞厓鏍间腑鏄剧ず宸ュ崟淇℃伅 --> + <div + v-for="workOrder in getWorkOrdersForDate(date)" + :key="workOrder.id" + class="work-order-item" + :class="{ 'urgent': isUrgent(workOrder) }" + > + <span class="work-order-shift">{{ workOrder.groupName }}</span> + <span class="work-order-material">{{ workOrder.materialName }}</span> + <span class="work-order-quantity">{{ workOrder.planQuantity }}</span> + </div> + </div> + </template> + </MesProductionWeekCalendar> + </a-card> + </a-col> + </a-row> </template> <script> - import '@/assets/less/TableExpand.less' - import { mixinDevice } from '@/utils/mixin' - import { JeecgListMixin } from '@/mixins/JeecgListMixin' - import MesProductionWorkOrderModal from './modules/MesProductionWorkOrderModal' - import {filterMultiDictText} from '@/components/dict/JDictSelectUtil' +import '@/assets/less/TableExpand.less' +import { mixinDevice } from '@/utils/mixin' +import { JeecgListMixin } from '@/mixins/JeecgListMixin' +import MesProductionWorkOrderModal from './modules/MesProductionWorkOrderModal' +import MesProductionWeekCalendar from '@views/mes/modules/MesProductionWeekCalendar.vue' +import MesProductionWorkOrderListModal from '@views/mes/modules/MesProductionWorkOrderListModal.vue' +import MesProductionWorkOrderRepublishModal from '@views/mes/modules/MesProductionWorkOrderRepublishModal.vue' +import { filterMultiDictText } from '@/components/dict/JDictSelectUtil' +import moment from 'moment' +import { getAction, postAction, requestPut } from '@api/manage' - export default { - name: 'MesProductionWorkOrderList', - mixins:[JeecgListMixin, mixinDevice], - components: { - MesProductionWorkOrderModal - }, - data () { - return { - description: '鎺掍骇宸ュ崟绠$悊椤甸潰', - // 琛ㄥご - columns: [ - { - title: '#', - dataIndex: '', - key:'rowIndex', - width:60, - align:"center", - customRender:function (t,r,index) { - return parseInt(index)+1; - } - }, - { - title:'宸ュ崟鍙�(浠诲姟鍙�)', - align:"center", - dataIndex: 'workOrderCode' - }, - { - title:'鐗╂枡缂栫爜', - align:"center", - dataIndex: 'materialNumber' - }, - { - title:'鐗╂枡鍚嶇О', - align:"center", - dataIndex: 'materialName' - }, - { - title:'璁″垝鐢熶骇鏁伴噺', - align:"center", - dataIndex: 'planQuantity' - }, - { - title:'浜х嚎(鍐椾綑)', - align:"center", - dataIndex: 'factoryId_dictText' - }, - { - title:'鐝粍', - align:"center", - dataIndex: 'groupId_dictText' - }, - { - title:'鐝(鍐椾綑)', - align:"center", - dataIndex: 'shiftId_dictText' - }, - { - title:'鎺掍骇鏃ユ湡', - align:"center", - dataIndex: 'workOrderDate' - }, - { - title:'宸ュ崟鐘舵��', - align:"center", - dataIndex: 'workOrderStatus_dictText' - }, - { - title:'瀹為檯鎶ュ伐鏁伴噺', - align:"center", - dataIndex: 'actualQuantity' - }, - { - title:'鍙戝竷浜�', - align:"center", - dataIndex: 'publisher' - }, - { - title:'鍙戝竷鏃堕棿', - align:"center", - dataIndex: 'publishTime' - }, - { - title:'閲嶅彂甯冧汉', - align:"center", - dataIndex: 'republisher' - }, - { - title:'閲嶅彂甯冩椂闂�', - align:"center", - dataIndex: 'republishTime' - }, - { - title: '鎿嶄綔', - dataIndex: 'action', - align:"center", - fixed:"right", - width:147, - scopedSlots: { customRender: 'action' } +export default { + name: 'MesProductionWorkOrderList', + mixins: [JeecgListMixin, mixinDevice], + components: { + MesProductionWorkOrderModal, + MesProductionWeekCalendar, + MesProductionWorkOrderListModal, + MesProductionWorkOrderRepublishModal + }, + data() { + return { + description: '鎺掍骇宸ュ崟绠$悊椤甸潰', + // 琛ㄥご + columns: [ + { + title: '#', + dataIndex: '', + key: 'rowIndex', + width: 60, + align: 'center', + customRender: function(t, r, index) { + return parseInt(index) + 1 } - ], - url: { - list: "/mesproductionworkorder/mesProductionWorkOrder/list", - delete: "/mesproductionworkorder/mesProductionWorkOrder/delete", - deleteBatch: "/mesproductionworkorder/mesProductionWorkOrder/deleteBatch", - exportXlsUrl: "/mesproductionworkorder/mesProductionWorkOrder/exportXls", - importExcelUrl: "mesproductionworkorder/mesProductionWorkOrder/importExcel", - }, - dictOptions:{}, - superFieldList:[], + { + title: '宸ュ崟鍙�(浠诲姟鍙�)', + align: 'center', + dataIndex: 'workOrderCode' + }, + { + title: '鐗╂枡缂栫爜', + align: 'center', + dataIndex: 'materialNumber' + }, + { + title: '鐗╂枡鍚嶇О', + align: 'center', + dataIndex: 'materialName' + }, + { + title: '璁″垝鐢熶骇鏁伴噺', + align: 'center', + dataIndex: 'planQuantity' + }, + { + title: '浜х嚎', + align: 'center', + dataIndex: 'factoryId_dictText' + }, + { + title: '鐝粍', + align: 'center', + dataIndex: 'groupId_dictText' + }, + { + title: '鐝', + align: 'center', + dataIndex: 'shiftId_dictText' + }, + { + title: '鎺掍骇鏃ユ湡', + align: 'center', + dataIndex: 'workOrderDate' + }, + { + title: '宸ュ崟鐘舵��', + align: 'center', + dataIndex: 'workOrderStatus_dictText' + }, + { + title: '瀹為檯鎶ュ伐鏁伴噺', + align: 'center', + dataIndex: 'actualQuantity' + }, + { + title: '鍙戝竷浜�', + align: 'center', + dataIndex: 'publisher' + }, + { + title: '鍙戝竷鏃堕棿', + align: 'center', + dataIndex: 'publishTime' + }, + { + title: '閲嶅彂甯冧汉', + align: 'center', + dataIndex: 'republisher' + }, + { + title: '閲嶅彂甯冩椂闂�', + align: 'center', + dataIndex: 'republishTime' + }, + { + title: '鎿嶄綔', + dataIndex: 'action', + align: 'center', + fixed: 'right', + width: 147, + scopedSlots: { customRender: 'action' } + } + ], + url: { + list: '/mesproductionworkorder/mesProductionWorkOrder/list', + delete: '/mesproductionworkorder/mesProductionWorkOrder/delete', + deleteBatch: '/mesproductionworkorder/mesProductionWorkOrder/deleteBatch', + exportXlsUrl: '/mesproductionworkorder/mesProductionWorkOrder/exportXls', + importExcelUrl: 'mesproductionworkorder/mesProductionWorkOrder/importExcel', + listProductionLinesOption: '/base/factory/queryIdTree', + schedule: '/mesproductionworkorder/mesProductionWorkOrder/schedule', + publish: '/mesproductionworkorder/mesProductionWorkOrder/publish' + }, + dictOptions: {}, + superFieldList: [], + // 鐢ㄤ簬婕旂ず鐨勫伐鍗曟暟鎹� + workOrdersByDate: {}, + // 鏃ュ巻璧峰鏃ユ湡 + calendarStartDate: moment(), + productionLineData: [], + dateRange: [], + tempStartDate: null, // 涓存椂瀛樺偍寮�濮嬫棩鏈� + hoveredDate: null, // 瀛樺偍榧犳爣鎮仠鐨勬棩鏈� + } + }, + created() { + this.getSuperFieldList() + this.initDictConfig() + }, + computed: { + importExcelUrl: function() { + return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}` + } + }, + methods: { + modalFormOk() { + this.onClearSelected() + this.loadData(1).then(() => { + if (this.queryParam.factoryId) { + // 鍚屾椂鏇存柊鏃ュ巻涓殑宸ュ崟鏁版嵁 + this.updateCalendarWorkOrders() + } + }).catch(error => { + console.error('鏁版嵁鍔犺浇澶辫触:', error) + }) + }, + loadData(arg) { + return new Promise((resolve, reject) => { + if (!this.url.list) { + this.$message.error("璇疯缃畊rl.list灞炴��!") + reject(new Error("璇疯缃畊rl.list灞炴��!")) + return + } + //鍔犺浇鏁版嵁 鑻ヤ紶鍏ュ弬鏁�1鍒欏姞杞界涓�椤电殑鍐呭 + if (arg === 1) { + this.ipagination.current = 1; + } + var params = this.getQueryParams();//鏌ヨ鏉′欢 + console.log('params', params) + if (!params) { + reject(new Error("鏌ヨ鍙傛暟鏃犳晥")) + return false; + } + this.loading = true; + getAction(this.url.list, params).then((res) => { + if (res.success) { + // console.log(res) + //update-begin---author:zhangyafei Date:20201118 for锛氶�傞厤涓嶅垎椤电殑鏁版嵁鍒楄〃------------ + this.dataSource = res.result.records || res.result; + if (res.result.total) { + this.ipagination.total = res.result.total; + } else { + this.ipagination.total = 0; + } + //update-end---author:zhangyafei Date:20201118 for锛氶�傞厤涓嶅垎椤电殑鏁版嵁鍒楄〃------------ + resolve(res) + } else { + this.$message.warning(res.message) + reject(new Error(res.message)) + } + }).catch(error => { + reject(error) + }).finally(() => { + this.loading = false + }) + }) + }, + searchQuery() { + this.queryParam = Object.assign(this.queryParam, this.dateRange) + this.loadData(1).then(() => { + if (this.queryParam.factoryId) { + // 鍚屾椂鏇存柊鏃ュ巻涓殑宸ュ崟鏁版嵁 + this.updateCalendarWorkOrders() + } + }).catch(error => { + console.error('鏁版嵁鍔犺浇澶辫触:', error) + }) + }, + searchReset() { + this.queryParam = {} + this.dateRange = [] + this.workOrdersByDate = {} + this.loadData(1); + }, + handlePublish(id) { + requestPut(this.url.publish, null, { ids: id }).then(res => { + if (res.success) { + this.$message.success(res.message) + this.loadData(1).then(() => { + if (this.queryParam.factoryId) { + // 鍚屾椂鏇存柊鏃ュ巻涓殑宸ュ崟鏁版嵁 + this.updateCalendarWorkOrders() + } + }).catch(error => { + console.error('鏁版嵁鍔犺浇澶辫触:', error) + }) + } else { + this.$message.warning(res.message) + } + }) + }, + handleRePublish(record) { + this.$refs.republishModal.add(record) + }, + initDictConfig() { + getAction(this.url.listProductionLinesOption, null).then(res => { + if (res.success) { + this.productionLineData = res.result + } + }) + }, + getSuperFieldList() { + let fieldList = [] + fieldList.push({ type: 'int', value: 'delFlag', text: '鍒犻櫎鏍囪', dictCode: '' }) + fieldList.push({ type: 'string', value: 'workOrderCode', text: '宸ュ崟鍙�(浠诲姟鍙�)', dictCode: '' }) + fieldList.push({ type: 'string', value: 'materialNumber', text: '鐗╂枡缂栫爜', dictCode: '' }) + fieldList.push({ type: 'string', value: 'materialName', text: '鐗╂枡鍚嶇О', dictCode: '' }) + fieldList.push({ type: 'double', value: 'planQuantity', text: '璁″垝鐢熶骇鏁伴噺', dictCode: '' }) + fieldList.push({ type: 'string', value: 'factoryId', text: '浜х嚎ID(鍐椾綑)', dictCode: '' }) + fieldList.push({ type: 'string', value: 'groupId', text: '鐝粍ID', dictCode: '' }) + fieldList.push({ type: 'string', value: 'shiftId', text: '鐝ID(鍐椾綑)', dictCode: '' }) + fieldList.push({ type: 'datetime', value: 'workOrderDate', text: '鎺掍骇鏃ユ湡' }) + fieldList.push({ type: 'string', value: 'workOrderStatus', text: '宸ュ崟鐘舵��', dictCode: 'work_order_status' }) + fieldList.push({ type: 'double', value: 'actualQuantity', text: '瀹為檯鎶ュ伐鏁伴噺', dictCode: '' }) + fieldList.push({ type: 'string', value: 'publisher', text: '鍙戝竷浜�', dictCode: '' }) + fieldList.push({ type: 'datetime', value: 'publishTime', text: '鍙戝竷鏃堕棿' }) + fieldList.push({ type: 'string', value: 'republisher', text: '閲嶅彂甯冧汉', dictCode: '' }) + fieldList.push({ type: 'datetime', value: 'republishTime', text: '閲嶅彂甯冩椂闂�' }) + this.superFieldList = fieldList + }, + productionSchedule() { + if (!this.queryParam.factoryId || this.dateRange.length === 0) { + this.$message.warning('璇烽�夋嫨浜х嚎鍙婃帓浜ф棩鏈熻寖鍥达紒') + return + } + getAction(this.url.schedule, { + factoryId: this.queryParam.factoryId, + startDate: this.dateRange[0].format('YYYY-MM-DD'), + endDate: this.dateRange[1].format('YYYY-MM-DD') + }).then(res => { + if (res.success) { + this.$refs.modal.edit(res.result, this.dateRange) + } + }) + }, + onOpenChange(open) { + if (!open) { + // 鍏抽棴閫夋嫨鍣ㄦ椂閲嶇疆鐘舵�� + this.tempStartDate = null + this.hoveredDate = null } }, - created() { - this.getSuperFieldList(); - }, - computed: { - importExcelUrl: function(){ - return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`; - }, - }, - methods: { - initDictConfig(){ - }, - getSuperFieldList(){ - let fieldList=[]; - fieldList.push({type:'int',value:'delFlag',text:'鍒犻櫎鏍囪',dictCode:''}) - fieldList.push({type:'string',value:'workOrderCode',text:'宸ュ崟鍙�(浠诲姟鍙�)',dictCode:''}) - fieldList.push({type:'string',value:'materialNumber',text:'鐗╂枡缂栫爜',dictCode:''}) - fieldList.push({type:'string',value:'materialName',text:'鐗╂枡鍚嶇О',dictCode:''}) - fieldList.push({type:'double',value:'planQuantity',text:'璁″垝鐢熶骇鏁伴噺',dictCode:''}) - fieldList.push({type:'string',value:'factoryId',text:'浜х嚎ID(鍐椾綑)',dictCode:''}) - fieldList.push({type:'string',value:'groupId',text:'鐝粍ID',dictCode:''}) - fieldList.push({type:'string',value:'shiftId',text:'鐝ID(鍐椾綑)',dictCode:''}) - fieldList.push({type:'datetime',value:'workOrderDate',text:'鎺掍骇鏃ユ湡'}) - fieldList.push({type:'string',value:'workOrderStatus',text:'宸ュ崟鐘舵��',dictCode:'work_order_status'}) - fieldList.push({type:'double',value:'actualQuantity',text:'瀹為檯鎶ュ伐鏁伴噺',dictCode:''}) - fieldList.push({type:'string',value:'publisher',text:'鍙戝竷浜�',dictCode:''}) - fieldList.push({type:'datetime',value:'publishTime',text:'鍙戝竷鏃堕棿'}) - fieldList.push({type:'string',value:'republisher',text:'閲嶅彂甯冧汉',dictCode:''}) - fieldList.push({type:'datetime',value:'republishTime',text:'閲嶅彂甯冩椂闂�'}) - this.superFieldList = fieldList + disabledDate(current) { + // 濡傛灉鏈変复鏃跺紑濮嬫棩鏈燂紝鍒欓檺鍒剁粨鏉熸棩鏈熻寖鍥� + if (this.tempStartDate) { + const startDate = this.tempStartDate.clone().startOf('day') + const maxDate = startDate.clone().add(6, 'days').endOf('day') // 7澶╁寘鎷捣濮嬫棩 + const minDate = startDate.clone().subtract(6, 'days').startOf('day') // 涔熷彲浠ュ悜鍓嶉��6澶� + // 绂佺敤瓒呭嚭7澶╄寖鍥寸殑鏃ユ湡 + return current && (current < minDate || current > maxDate) } + // 榛樿涓嶇鐢� + return false + }, + dateRangeChange(dates, dateStrings) { + this.dateRange = dates + if (dates && dates.length > 0) { + if (dates.length === 1) { + // 閫夋嫨浜嗗紑濮嬫棩鏈燂紝淇濆瓨鍒颁复鏃跺彉閲� + this.tempStartDate = dates[0] + this.hoveredDate = dates[0] + } else if (dates.length === 2) { + // 閫夋嫨浜嗙粨鏉熸棩鏈燂紝楠岃瘉鑼冨洿 + const startDate = dates[0] + const endDate = dates[1] + const diffDays = endDate.diff(startDate, 'days') + 1 + + if (diffDays > 7) { + this.$message.warning('鏃ユ湡鑼冨洿涓嶈兘瓒呰繃7澶�') + // 鑷姩璋冩暣涓�7澶╄寖鍥� + const adjustedEndDate = startDate.clone().add(6, 'days') + this.dateRange = [startDate, adjustedEndDate] + this.queryParam.startDate = startDate.format('YYYY-MM-DD') + this.queryParam.endDate = adjustedEndDate.format('YYYY-MM-DD') + } else { + this.queryParam.startDate = dateStrings[0] + this.queryParam.endDate = dateStrings[1] + } + // 閲嶇疆涓存椂鐘舵�� + this.tempStartDate = null + this.hoveredDate = null + } + } else { + // 娓呴櫎浜嗛�夋嫨 + this.queryParam.startDate = null + this.queryParam.endDate = null + this.tempStartDate = null + this.hoveredDate = null + } + }, + // 澶勭悊鏃ユ湡閫夋嫨浜嬩欢 + onDateSelect(date) { + console.log('Selected date:', date.format('YYYY-MM-DD')) + }, + // 澶勭悊鏃ュ巻鍛ㄥ彉鍖栦簨浠� + onCalendarChange(date) { + console.log('Calendar week changed:', date.format('YYYY-MM-DD')) + }, + // 鏇存柊鏃ュ巻涓殑宸ュ崟鏁版嵁 + updateCalendarWorkOrders() { + // 灏嗗綋鍓嶈〃鏍兼暟鎹寜鏃ユ湡鍒嗙粍鏄剧ず鍦ㄦ棩鍘嗕腑 + const workOrdersByDate = {} + this.dataSource.filter(workOrder => workOrder.workOrderStatus !== 'NEW').forEach(workOrder => { + const workOrderDate = workOrder.workOrderDate + if (workOrderDate) { + if (!workOrdersByDate[workOrderDate]) { + workOrdersByDate[workOrderDate] = [] + } + workOrdersByDate[workOrderDate].push({ + id: workOrder.id, + groupName: workOrder.groupId_dictText || '', + materialName: workOrder.materialName || '', + planQuantity: workOrder.planQuantity || 0 + }) + } + }) + this.workOrdersByDate = workOrdersByDate + }, + // 鑾峰彇鎸囧畾鏃ユ湡鐨勫伐鍗� + getWorkOrdersForDate(date) { + const dateStr = date.format('YYYY-MM-DD') + console.log(dateStr) + return this.workOrdersByDate[dateStr] || [] + }, + // 鍒ゆ柇宸ュ崟鏄惁绱ф�� + isUrgent(workOrder) { + return workOrder.status === 'urgent' } } +} </script> <style scoped> - @import '~@assets/less/common.less'; +@import '~@assets/less/common.less'; + +.work-order-item { + font-size: 12px; + padding: 2px 4px; + margin-bottom: 2px; + background-color: #f0f0f0; + border-radius: 2px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.work-order-item.urgent { + background-color: #ffccc7; + border-left: 2px solid #ff4d4f; +} + +.work-order-shift { + font-weight: bold; + margin-right: 4px; +} + +.work-order-material { + margin-right: 4px; +} + +.work-order-quantity { + float: right; +} </style> \ No newline at end of file diff --git a/src/views/mes/modules/MesProductionWeekCalendar.vue b/src/views/mes/modules/MesProductionWeekCalendar.vue new file mode 100644 index 0000000..46c0716 --- /dev/null +++ b/src/views/mes/modules/MesProductionWeekCalendar.vue @@ -0,0 +1,241 @@ +<!-- src/views/mes/modules/MesProductionWeekCalendar.vue --> +<template> + <div class="week-calendar"> + <div class="calendar-header"> + <a-button icon="left" @click="prevWeek" size="small" /> + <span class="current-week-range">{{ weekRangeText }}</span> + <a-button icon="right" @click="nextWeek" size="small" /> + <a-button @click="goToToday" size="small" style="margin-left: 8px">浠婂ぉ</a-button> + </div> + + <div class="calendar-grid"> + <div class="week-header"> + <div + v-for="(day, index) in weekDays" + :key="index" + class="header-cell" + > + <div class="day-name">{{ day.format('ddd') }}</div> + <div + class="day-number" + :class="{ today: isToday(day), selected: isSelected(day) }" + @click="selectDay(day)" + > + {{ day.date() }} + </div> + </div> + </div> + + <div class="calendar-body"> + <div + v-for="(day, index) in weekDays" + :key="index" + class="day-cell" + :class="{ today: isToday(day), selected: isSelected(day) }" + @click="selectDay(day)" + > + <div class="cell-content"> + <!-- 鎻掓Ы鐢ㄤ簬娓叉煋鏃ユ湡鍐呭 --> + <slot + name="dateCell" + :date="day" + :isSelected="isSelected(day)" + :isToday="isToday(day)" + > + <!-- 榛樿鍐呭 --> + <div class="default-content"> + <!-- 鍙互鍦ㄨ繖閲屾坊鍔犻粯璁ょ殑鏃ユ湡鍐呭娓叉煋閫昏緫 --> + </div> + </slot> + </div> + </div> + </div> + </div> + </div> +</template> + +<script> +import moment from 'moment' + +export default { + name: 'MesProductionWeekCalendar', + props: { + // 璧峰鏃ユ湡锛岄粯璁や负浠婂ぉ + startDate: { + type: [Object, String, Date], + default: null + } + }, + data() { + return { + // 褰撳墠鏄剧ず鐨勮捣濮嬫棩鏈� + currentStartDate: this.startDate ? moment(this.startDate) : moment(), + // 閫変腑鐨勬棩鏈� + selectedDate: this.startDate ? moment(this.startDate) : moment() + } + }, + computed: { + // 璁$畻杩炵画7澶╃殑鏃ユ湡 + weekDays() { + const days = [] + for (let i = 0; i < 7; i++) { + days.push(this.currentStartDate.clone().add(i, 'days')) + } + return days + }, + // 褰撳墠鏄剧ず鐨勬棩鏈熻寖鍥存枃鏈� + weekRangeText() { + const start = this.currentStartDate + const end = this.currentStartDate.clone().add(6, 'days') + + if (start.month() === end.month()) { + return `${start.format('YYYY骞碝鏈圖鏃�')} - ${end.format('D鏃�')}` + } else { + return `${start.format('YYYY骞碝鏈圖鏃�')} - ${end.format('M鏈圖鏃�')}` + } + } + }, + watch: { + startDate(newVal) { + if (newVal) { + this.currentStartDate = moment(newVal) + this.selectedDate = moment(newVal) + } + } + }, + methods: { + // 鍒囨崲鍒颁笂7澶� + prevWeek() { + this.currentStartDate = this.currentStartDate.clone().subtract(7, 'days') + this.$emit('change', this.currentStartDate) + }, + // 鍒囨崲鍒颁笅7澶� + nextWeek() { + this.currentStartDate = this.currentStartDate.clone().add(7, 'days') + this.$emit('change', this.currentStartDate) + }, + // 璺宠浆鍒颁粖澶� + goToToday() { + this.currentStartDate = moment() + this.selectedDate = moment() + this.$emit('change', this.currentStartDate) + this.$emit('select', this.selectedDate) + }, + // 閫夋嫨鏃ユ湡 + selectDay(day) { + this.selectedDate = day.clone() + this.$emit('select', day) + }, + // 鍒ゆ柇鏄惁鏄粖澶� + isToday(day) { + return day.isSame(moment(), 'day') + }, + // 鍒ゆ柇鏄惁鏄�変腑鐨勬棩鏈� + isSelected(day) { + return day.isSame(this.selectedDate, 'day') + } + } +} +</script> + +<style scoped> +.week-calendar { + padding: 16px; +} + +.calendar-header { + display: flex; + justify-content: center; + align-items: center; + margin-bottom: 16px; +} + +.current-week-range { + margin: 0 16px; + font-weight: bold; + font-size: 14px; +} + +.calendar-grid { + border: 1px solid #e8e8e8; + border-radius: 4px; + overflow: hidden; +} + +.week-header { + display: flex; + background-color: #fafafa; + border-bottom: 1px solid #e8e8e8; +} + +.header-cell { + flex: 1; + text-align: center; + padding: 8px 0; + border-right: 1px solid #e8e8e8; +} + +.header-cell:last-child { + border-right: none; +} + +.day-name { + font-size: 12px; + color: #666; + margin-bottom: 4px; +} + +.day-number { + font-size: 16px; + font-weight: bold; + cursor: pointer; + width: 30px; + height: 30px; + line-height: 30px; + margin: 0 auto; + border-radius: 50%; +} + +.day-number.today { + background-color: #1890ff; + color: white; +} + +.day-number.selected { + background-color: #bae7ff; + color: #1890ff; +} + +.calendar-body { + display: flex; + height: 300px; +} + +.day-cell { + flex: 1; + border-right: 1px solid #e8e8e8; + cursor: pointer; + padding: 4px; +} + +.day-cell:last-child { + border-right: none; +} + +.day-cell.today { + background-color: #e6f7ff; +} + +.day-cell.selected { + background-color: #bae7ff; +} + +.cell-content { + height: 100%; + overflow: hidden; +} + +.default-content { + height: 100%; +} +</style> diff --git a/src/views/mes/modules/MesProductionWorkOrderForm.vue b/src/views/mes/modules/MesProductionWorkOrderForm.vue index 76de965..ce6941f 100644 --- a/src/views/mes/modules/MesProductionWorkOrderForm.vue +++ b/src/views/mes/modules/MesProductionWorkOrderForm.vue @@ -24,28 +24,28 @@ </a-form-model-item> </a-col> <a-col :span="12"> - <a-form-model-item label="浜х嚎ID(鍐椾綑)" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="factoryId"> - <a-input v-model="model.factoryId" placeholder="璇疯緭鍏ヤ骇绾縄D(鍐椾綑)" ></a-input> + <a-form-model-item label="浜х嚎" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="factoryId"> + <a-input v-model="model.factoryId_dictText" placeholder="璇疯緭鍏ヤ骇绾縄D(鍐椾綑)" ></a-input> </a-form-model-item> </a-col> <a-col :span="12"> - <a-form-model-item label="鐝粍ID" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="groupId"> - <a-input v-model="model.groupId" placeholder="璇疯緭鍏ョ彮缁処D" ></a-input> + <a-form-model-item label="鐝粍" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="groupId"> + <a-input v-model="model.groupId_dictText" placeholder="璇疯緭鍏ョ彮缁処D" ></a-input> </a-form-model-item> </a-col> <a-col :span="12"> - <a-form-model-item label="鐝ID(鍐椾綑)" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="shiftId"> - <a-input v-model="model.shiftId" placeholder="璇疯緭鍏ョ彮娆D(鍐椾綑)" ></a-input> + <a-form-model-item label="鐝" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="shiftId"> + <a-input v-model="model.shiftId_dictText" placeholder="璇疯緭鍏ョ彮娆D(鍐椾綑)" ></a-input> </a-form-model-item> </a-col> <a-col :span="12"> <a-form-model-item label="鎺掍骇鏃ユ湡" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="workOrderDate"> - <j-date placeholder="璇烽�夋嫨鎺掍骇鏃ユ湡" v-model="model.workOrderDate" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" /> + <j-date placeholder="璇烽�夋嫨鎺掍骇鏃ユ湡" v-model="model.workOrderDate" :show-time="true" date-format="YYYY-MM-DD" style="width: 100%" /> </a-form-model-item> </a-col> <a-col :span="12"> <a-form-model-item label="宸ュ崟鐘舵��" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="workOrderStatus"> - <j-dict-select-tag type="list" v-model="model.workOrderStatus" dictCode="work_order_status" placeholder="璇烽�夋嫨宸ュ崟鐘舵��" /> + <j-dict-select-tag type="list" v-model="model.workOrderStatus_dictText" dictCode="work_order_status" placeholder="璇烽�夋嫨宸ュ崟鐘舵��" /> </a-form-model-item> </a-col> <a-col :span="12"> @@ -102,7 +102,7 @@ }, labelCol: { xs: { span: 24 }, - sm: { span: 5 }, + sm: { span: 6 }, }, wrapperCol: { xs: { span: 24 }, diff --git a/src/views/mes/modules/MesProductionWorkOrderListModal.vue b/src/views/mes/modules/MesProductionWorkOrderListModal.vue new file mode 100644 index 0000000..6075145 --- /dev/null +++ b/src/views/mes/modules/MesProductionWorkOrderListModal.vue @@ -0,0 +1,375 @@ +<template> + <j-modal + :title="title" + :width="width" + :visible="visible" + switchFullscreen + @ok="handleOk" + :okButtonProps="{ class:{'jee-hidden': disableSubmit} }" + @cancel="handleCancel" + cancelText="鍏抽棴"> + + <a-button :style="{ marginBottom: '10px' }" type="primary" @click="handleAdd">鏂板</a-button> + <vxe-table + ref="table" + border + :data="dataSource" + :edit-config="{trigger: 'click', mode: 'cell'}" + :edit-rules="editRules" + > + <vxe-table-column type="seq" width="40"/> + <vxe-table-column width="200" title="宸ュ崟鍙�" field="workOrderCode"> + <template #default="{ row }"> + <span v-if="row.workOrderCode">{{ row.workOrderCode }}</span> + <span v-else class="placeholder-text">绯荤粺鑷姩鐢熸垚</span> + </template> + </vxe-table-column> + <vxe-table-column + title="鐗╂枡缂栧彿" + field="materialNumber" + :edit-render="{name: '$select', options: materialOptions, events: {change: handleMaterialChange}}"> + <template #default="{ row }"> + <span v-if="row.materialNumber">{{ row.materialNumber }}</span> + <span v-else class="placeholder-text">璇烽�夋嫨鐗╂枡缂栧彿</span> + </template> + </vxe-table-column> + <vxe-table-column title="鐗╂枡鍚嶇О" field="materialName"> + <template #default="{ row }"> + <span v-if="row.materialName">{{ row.materialName }}</span> + <span v-else class="placeholder-text">鐗╂枡鍚嶇О鑷姩濉厖</span> + </template> + </vxe-table-column> + <vxe-table-column title="浜х嚎" field="factoryName"></vxe-table-column> + <vxe-table-column + title="鐝粍" + field="groupId" + :edit-render="{name: '$select', options: groupOptions, events: {change: handleGroupChange}}"> + </vxe-table-column> + <vxe-table-column title="鐝id" :visible="false" field="shiftName"></vxe-table-column> + <vxe-table-column title="鐝" field="shiftName"></vxe-table-column> + <vxe-table-column + title="鎺掍骇鏃ユ湡" + field="workOrderDate" + :edit-render="{name: '$select', options: workOrderDateOptions, events: {change: handleWorkOrderDateChange}}"> + </vxe-table-column> + <vxe-table-column + title="璁″垝鐢熶骇鏁伴噺" + field="planQuantity" + width="150" + :edit-render="{name: '$input'}"> + <template #default="{ row }"> + <span v-if="row.planQuantity">{{ row.planQuantity }}</span> + <span v-else class="placeholder-text">璇峰~鍐欒鍒掔敓浜ф暟閲�</span> + </template> + </vxe-table-column> + <vxe-table-column title="鎿嶄綔"> + <template #default="{ row }"> + <vxe-button size="small" class="error-button" @click="handleRemove(row)">鍒犻櫎</vxe-button> + </template> + </vxe-table-column> + </vxe-table> + </j-modal> +</template> + +<script> + +import MesProductionWorkOrderForm from './MesProductionWorkOrderForm' +import { ajaxGetDictItems } from '@api/api' +import { getAction, postAction } from '@api/manage' + +export default { + name: 'MesProductionWorkOrderModal', + components: { + MesProductionWorkOrderForm + }, + data () { + return { + title: '鎺掍骇鏄庣粏', + width: 1300, + visible: false, + disableSubmit: false, + loading: false, + dataSource: [], + groupOptions: [], + groupShiftMap: {}, + materialOptions: [], + materNumberNameMap: {}, + workOrderDateOptions: [], + url: { + queryShiftGroupByFactoryId: '/base/shiftGroup/queryShiftGroupByFactoryId', + addSchedulePlan: '/mesproductionworkorder/mesProductionWorkOrder/addSchedulePlan' + }, + editRules: { + materialNumber: [ + { required: true, message: '鐗╂枡缂栧彿蹇呴』閫夋嫨' } + ], + groupId: [ + { required: true, message: '鐝粍蹇呴』閫夋嫨' } + ], + workOrderDate: [ + { required: true, message: '鎺掍骇鏃ユ湡蹇呴』閫夋嫨' } + ], + planQuantity: [ + { required: true, message: '璁″垝鐢熶骇鏁伴噺涓哄繀濉�' } + ] + } + } + }, + methods: { + // 鐢熸垚鏃ユ湡鑼冨洿鏁扮粍 + generateDateRangeOptions(startDate, endDate) { + const dateOptions = []; + const start = new Date(startDate); + const end = new Date(endDate); + + // 璁剧疆鏃堕棿涓烘瘡澶╃殑0鐐� + start.setHours(0, 0, 0, 0); + end.setHours(0, 0, 0, 0); + + // 鐢熸垚鏃ユ湡鑼冨洿鍐呯殑鎵�鏈夋棩鏈� + for (let date = new Date(start); date <= end; date.setDate(date.getDate() + 1)) { + const formattedDate = this.formatDate(date); + dateOptions.push({ + value: formattedDate, + label: formattedDate + }); + } + return dateOptions; + }, + // 鏍煎紡鍖栨棩鏈熶负 YYYY-MM-DD + formatDate(date) { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; + }, + // 鐢熸垚宸ュ崟鍙风殑鏂规硶 + generateWorkOrderCode(row) { + console.log('row:', row) + // 鑾峰彇鍚勪釜瀛楁鐨勫�� + const factoryCode = row.factoryCode || ''; // 浜х嚎缂栧彿 + const materialNumber = row.materialNumber || ''; // 鐗╂枡缂栧彿 + const workDate = row.workOrderDate || ''; // 鎺掍骇鏃ユ湡 + const shiftCode = row.shiftCode || ''; // 鐝缂栧彿 + + // 鏍煎紡鍖栨帓浜ф棩鏈燂紙濡傛灉闇�瑕佺壒瀹氭牸寮忥紝姣斿鍙彇骞存湀鏃ワ級 + let formattedDate = workDate; + if (workDate && workDate.length >= 10) { + // 濡傛灉鏄畬鏁存棩鏈熸牸寮忥紝鎻愬彇 YYYY-MM-DD 閮ㄥ垎 + formattedDate = workDate.substring(0, 10).replace(/-/g, ''); + } + // 鎷兼帴宸ュ崟鍙� + return `${factoryCode}${materialNumber}${formattedDate}${shiftCode}`; + }, + // 鍦ㄩ�傚綋鏃舵満鏇存柊宸ュ崟鍙� + updateWorkOrderCode(row) { + row.workOrderCode = this.generateWorkOrderCode(row); + }, + handleWorkOrderDateChange($event, value) { + $event.row.workOrderDate = value.value; + this.updateWorkOrderCode($event.row) + }, + handleMaterialChange($event, value) { + const key = value.value + if (key && this.materNumberNameMap[key]) { + $event.row.materialName = this.materNumberNameMap[key] + } else { + $event.row.materialName = ''; + } + // 鏇存柊鐗╂枡缂栧彿 + $event.row.materialNumber = key; + // 閲嶆柊鐢熸垚宸ュ崟鍙� + this.updateWorkOrderCode($event.row); + }, + handleGroupChange($event, value) { + const key = value.value + // 浠� groupShiftMap 涓幏鍙栧搴旂殑鐝淇℃伅 + if (key && this.groupShiftMap[key]) { + // 鏇存柊褰撳墠琛岀殑鐝瀛楁 + $event.row.shiftId = this.groupShiftMap[key].shiftId; + $event.row.shiftCode = this.groupShiftMap[key].shiftCode; + $event.row.shiftName = this.groupShiftMap[key].shiftName; + } else { + // 濡傛灉娌℃湁鍖归厤鐨勭彮娆′俊鎭紝鍒欐竻绌虹彮娆″瓧娈� + $event.row.shiftId = ''; + $event.row.shiftCode = ''; + $event.row.shiftName = ''; + } + // 閲嶆柊鐢熸垚宸ュ崟鍙� + this.updateWorkOrderCode($event.row); + }, + initDictSelectOptions(record) { + return new Promise((resolve) => { + // 骞惰鎵ц澶氫釜寮傛璇锋眰 + const promises = []; + + // 鑾峰彇鐝粍鍜岀彮娆′俊鎭� + if (record && record.length > 0) { + const factoryId = record[0].factoryId + const shiftGroupPromise = getAction(this.url.queryShiftGroupByFactoryId, { factoryId: factoryId }).then(res => { + if (res.success) { + // 淇鏄犲皠閫昏緫 + this.groupOptions = res.result.map(item => { + return { + value: item.id, + label: item.groupName + } + }) + // 淇濆瓨鐝粍鍜岀彮娆$殑鏄犲皠鍏崇郴 + this.groupShiftMap = res.result.reduce((map, item) => { + map[item.id] = { + shiftId: item.shiftId, + shiftCode: item.shiftCode_dictText, + shiftName: item.shiftId_dictText + } + return map + }, {}) + } + }).catch(() => { + // 鍗充娇璇锋眰澶辫触涔熶笉闃诲 + }); + promises.push(shiftGroupPromise); + } + + //鑾峰彇鐗╂枡缂栧彿涓嬫媺閫夐」 + const materialNumberPromise = ajaxGetDictItems("lsw_material,material_name,material_number,del_flag!='1' order by material_number asc", null).then(res => { + if (res.success) { + // 鍋囪鐗╂枡缂栧彿瀛楁涓� materialNumber锛岄渶瑕佹牴鎹疄闄呭瓧娈佃皟鏁� + // 灏嗙墿鏂欓�夐」瀛樺偍鍒扮粍浠舵暟鎹腑锛屼緵琛ㄦ牸浣跨敤 + this.materialOptions = res.result.map(item => { + return { + value: item.value, + label: item.value + } + }); + this.materNumberNameMap = res.result.reduce((map, item) => { + map[item.value] = item.text + return map + }, {}) + } + }).catch(() => { + // 鍗充娇璇锋眰澶辫触涔熶笉闃诲 + }); + promises.push(materialNumberPromise); + + // 绛夊緟鎵�鏈夎姹傚畬鎴� + Promise.all(promises).then(() => { + resolve(); + }); + }) + }, + edit (record, dateRange) { + // 鍏堝姞杞藉瓧鍏告暟鎹紝鍐嶅垵濮嬪寲琛ㄥ崟 + this.initDictSelectOptions(record).then(() => { + this.$nextTick(() => { + // 鏍规嵁鏃ユ湡鑼冨洿鐢熸垚鎺掍骇鏃ユ湡閫夐」 + if (dateRange && dateRange.length === 2) { + this.workOrderDateOptions = this.generateDateRangeOptions(dateRange[0], dateRange[1]); + } + + // 涓烘瘡鏉¤褰曠敓鎴愬伐鍗曞彿 + if (record && record.length > 0) { + record.forEach(row => { + if (!row.workOrderCode) { + this.updateWorkOrderCode(row); + } + }); + } + this.dataSource = record + this.visible = true + // 鏁版嵁鍔犺浇瀹屾垚鍚庢縺娲绘墍鏈夎鐨勭紪杈戠姸鎬� + this.$nextTick(() => { + if (this.$refs.table && this.dataSource.length > 0) { + // 婵�娲荤涓�琛岃繘鍏ョ紪杈戠姸鎬� + this.$refs.table.setActiveRow(this.dataSource[0]) + } + }) + }); + }) + }, + close () { + this.$emit('close'); + this.visible = false; + }, + handleAdd() { + // 鍒涘缓鏂拌鏁版嵁 + const newRow = { + workOrderCode: this.dataSource.length > 0 ? this.dataSource[0].factoryCode : '', + materialNumber: '', // 鐗╂枡缂栧彿锛堥渶閫夋嫨锛� + materialName: '', // 鐗╂枡鍚嶇О锛堣嚜鍔ㄥ~鍏咃級 + factoryId: this.dataSource.length > 0 ? this.dataSource[0].factoryId : '', + factoryCode: this.dataSource.length > 0 ? this.dataSource[0].factoryCode : '', + factoryName: this.dataSource.length > 0 ? this.dataSource[0].factoryName : '', + groupId: '', // 鐝粍锛堥渶閫夋嫨锛� + shiftId: '', // 鐝ID + shiftCode: '', // 鐝缂栧彿 + shiftName: '', // 鐝鍚嶇О + workOrderDate: '', // 鎺掍骇鏃ユ湡锛堥渶閫夋嫨锛� + planQuantity: '' // 璁″垝鐢熶骇鏁伴噺锛堥渶濉啓锛� + } + // 灏嗘柊琛屾坊鍔犲埌鏁版嵁婧愪腑 + this.dataSource.push(newRow); + // 婵�娲绘柊澧炵殑琛岃繘鍏ョ紪杈戠姸鎬� + this.$nextTick(() => { + if (this.$refs.table) { + this.$refs.table.setActiveRow(newRow); + } + }); + }, + handleRemove(row) { + let table = this.$refs.table + this.$confirm({ + title: '鎻愮ず', + content: '纭瑕佸垹闄ゅ悧锛�', + okText: '纭畾', + cancelText: '鍙栨秷', + onOk: () => { + // 鍒犻櫎琛� + table.remove(row) + } + }) + }, + handleOk () { + // 琛ㄦ牸鍏ㄨ〃鏍¢獙 + this.$refs.table.validate((valid) => { + if (valid) { + this.$message.error("璇峰畬鎴愭墍鏈夊繀濉俊鎭悗鍐嶆彁浜わ紒") + } else { + let tableData = this.$refs.table.getTableData().fullData + console.log(tableData) + postAction(this.url.addSchedulePlan, tableData).then(res=> { + if (res.success) { + this.$message.success(res.message) + this.submitCallback() + } else { + this.$message.warning(res.message) + } + }) + } + }) + }, + submitCallback(){ + this.$emit('ok'); + this.visible = false; + }, + handleCancel () { + this.close() + } + } + } +</script> + +<style scoped> + +.placeholder-text { + color: #999; + font-style: italic; +} + +.error-button { + background-color: #ff4d4f !important; + border-color: #ff4d4f !important; + color: #fff !important; +} + +</style> \ No newline at end of file diff --git a/src/views/mes/modules/MesProductionWorkOrderModal.vue b/src/views/mes/modules/MesProductionWorkOrderModal.vue index 33c60fc..012dcdf 100644 --- a/src/views/mes/modules/MesProductionWorkOrderModal.vue +++ b/src/views/mes/modules/MesProductionWorkOrderModal.vue @@ -23,7 +23,7 @@ data () { return { title:'', - width:896, + width:900, visible: false, disableSubmit: false } diff --git a/src/views/mes/modules/MesProductionWorkOrderRepublishModal.vue b/src/views/mes/modules/MesProductionWorkOrderRepublishModal.vue new file mode 100644 index 0000000..bf3160d --- /dev/null +++ b/src/views/mes/modules/MesProductionWorkOrderRepublishModal.vue @@ -0,0 +1,132 @@ +<template> + <j-modal + :title="title" + :width="width" + :visible="visible" + switchFullscreen + @ok="handleOk" + :okButtonProps="{ class:{'jee-hidden': disableSubmit} }" + @cancel="handleCancel" + cancelText="鍏抽棴"> + + <a-spin :spinning="confirmLoading"> + <j-form-container :disabled="formDisabled"> + <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail"> + <a-row> + <a-col :span="24"> + <a-form-model-item label="璁″垝鐢熶骇鏁伴噺" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="planQuantity"> + <a-input-number + v-model="model.planQuantity" + placeholder="璇疯緭鍏ヨ鍒掔敓浜ф暟閲�" + style="width: 100%" + :min="0"> + </a-input-number> + </a-form-model-item> + </a-col> + <a-col :span="24"> + <a-form-model-item label="閲嶅彂甯冨師鍥�" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="republishReason"> + <a-textarea + v-model="model.republishReason" + placeholder="璇峰~鍐欓噸鍙戝竷鍘熷洜" + :rows="4"> + </a-textarea> + </a-form-model-item> + </a-col> + </a-row> + </a-form-model> + </j-form-container> + </a-spin> + </j-modal> +</template> + +<script> +import { postAction } from '@api/manage' + +export default { + name: 'MesProductionWorkOrderRepublishModal', + data () { + return { + title: '閲嶅彂甯冨伐鍗�', + width: 600, + visible: false, + disableSubmit: false, + confirmLoading: false, + model: { + id: '', + planQuantity: null, + republishReason: '' + }, + validatorRules: { + planQuantity: [ + { required: true, message: '璇疯緭鍏ヨ鍒掔敓浜ф暟閲�!' } + ], + republishReason: [ + { required: true, message: '璇峰~鍐欓噸鍙戝竷鍘熷洜!' } + ] + }, + labelCol: { + xs: { span: 24 }, + sm: { span: 6 }, + }, + wrapperCol: { + xs: { span: 24 }, + sm: { span: 18 }, + }, + url: { + republish: '/mesproductionworkorder/mesProductionWorkOrder/republish' + } + } + }, + computed: { + formDisabled(){ + return this.disabled + }, + }, + methods: { + add (record) { + // 閲嶇疆琛ㄥ崟 + this.$refs.form && this.$refs.form.resetFields() + // 璁剧疆鍒濆鍊� + if (record) { + this.model.id = record.id + this.model.planQuantity = record.planQuantity + this.model.republishReason = '' + } + this.visible = true + }, + close () { + this.$emit('close'); + this.visible = false; + }, + handleOk () { + this.$refs.form.validate(valid => { + if (valid) { + this.confirmLoading = true + let formData = { + id: this.model.id, + planQuantity: this.model.planQuantity, + republishReason: this.model.republishReason + } + postAction(this.url.republish, formData).then(res => { + if (res.success) { + this.$message.success(res.message) + this.submitCallback() + } else { + this.$message.warning(res.message) + } + }).finally(() => { + this.confirmLoading = false + }) + } + }) + }, + submitCallback(){ + this.$emit('ok'); + this.visible = false; + }, + handleCancel () { + this.close() + } + } +} +</script> -- Gitblit v1.9.3