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