fix: 完成设计项目和归档台账接口对接,功能联调
| | |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | export namespace MesDvRepairApi { |
| | | /** MES 维修工å */ |
| | | /** MES 维修订å */ |
| | | export interface Repair { |
| | | id?: number; // å·¥åç¼å· |
| | | code?: string; // 维修工åç¼ç |
| | | name?: string; // 维修工ååç§° |
| | | id?: number; // 订åç¼å· |
| | | code?: string; // 维修订åç¼ç |
| | | name?: string; // 维修订ååç§° |
| | | machineryId?: number; // 设å¤ç¼å· |
| | | machineryCode?: string; // 设å¤ç¼ç |
| | | machineryName?: string; // 设å¤åç§° |
| | |
| | | } |
| | | } |
| | | |
| | | /** æ¥è¯¢ç»´ä¿®å·¥åå页 */ |
| | | /** æ¥è¯¢ç»´ä¿®è®¢åå页 */ |
| | | export function getRepairPage(params: PageParam) { |
| | | return requestClient.get<PageResult<MesDvRepairApi.Repair>>( |
| | | '/mes/dv/repair/page', |
| | |
| | | ); |
| | | } |
| | | |
| | | /** æ¥è¯¢ç»´ä¿®å·¥å详æ
*/ |
| | | /** æ¥è¯¢ç»´ä¿®è®¢å详æ
*/ |
| | | export function getRepair(id: number) { |
| | | return requestClient.get<MesDvRepairApi.Repair>( |
| | | `/mes/dv/repair/get?id=${id}`, |
| | | ); |
| | | } |
| | | |
| | | /** æ°å¢ç»´ä¿®å·¥å */ |
| | | /** æ°å¢ç»´ä¿®è®¢å */ |
| | | export function createRepair(data: MesDvRepairApi.Repair) { |
| | | return requestClient.post<number>('/mes/dv/repair/create', data); |
| | | } |
| | | |
| | | /** ä¿®æ¹ç»´ä¿®å·¥å */ |
| | | /** ä¿®æ¹ç»´ä¿®è®¢å */ |
| | | export function updateRepair(data: MesDvRepairApi.Repair) { |
| | | return requestClient.put('/mes/dv/repair/update', data); |
| | | } |
| | | |
| | | /** å é¤ç»´ä¿®å·¥å */ |
| | | /** å é¤ç»´ä¿®è®¢å */ |
| | | export function deleteRepair(id: number) { |
| | | return requestClient.delete(`/mes/dv/repair/delete?id=${id}`); |
| | | } |
| | | |
| | | /** 导åºç»´ä¿®å·¥å */ |
| | | /** 导åºç»´ä¿®è®¢å */ |
| | | export function exportRepair(params: any) { |
| | | return requestClient.download('/mes/dv/repair/export-excel', { params }); |
| | | } |
| | | |
| | | /** æäº¤ç»´ä¿®å·¥å */ |
| | | /** æäº¤ç»´ä¿®è®¢å */ |
| | | export function submitRepair(id: number) { |
| | | return requestClient.put(`/mes/dv/repair/submit?id=${id}`); |
| | | } |
| | |
| | | import type { PageParam, PageResult } from '../../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | export namespace MesDvRepairLineApi { |
| | | /** MES 维修工åè¡ */ |
| | | /** MES 维修订åè¡ */ |
| | | export interface RepairLine { |
| | | id?: number; // æç»ç¼å· |
| | | repairId?: number; // 维修工åç¼å· |
| | | repairId?: number; // 维修订åç¼å· |
| | | subjectId?: number; // 项ç®ç¼å· |
| | | subjectName?: string; // 项ç®åç§° |
| | | subjectContent?: string; // 项ç®å
容 |
| | |
| | | } |
| | | } |
| | | |
| | | /** æ¥è¯¢ç»´ä¿®å·¥åè¡å页 */ |
| | | /** æ¥è¯¢ç»´ä¿®è®¢åè¡å页 */ |
| | | export function getRepairLinePage(params: PageParam) { |
| | | return requestClient.get<PageResult<MesDvRepairLineApi.RepairLine>>( |
| | | '/mes/dv/repair-line/page', |
| | |
| | | ); |
| | | } |
| | | |
| | | /** æ¥è¯¢ç»´ä¿®å·¥åè¡è¯¦æ
*/ |
| | | /** æ¥è¯¢ç»´ä¿®è®¢åè¡è¯¦æ
*/ |
| | | export function getRepairLine(id: number) { |
| | | return requestClient.get<MesDvRepairLineApi.RepairLine>( |
| | | `/mes/dv/repair-line/get?id=${id}`, |
| | | ); |
| | | } |
| | | |
| | | /** æ°å¢ç»´ä¿®å·¥åè¡ */ |
| | | /** æ°å¢ç»´ä¿®è®¢åè¡ */ |
| | | export function createRepairLine(data: MesDvRepairLineApi.RepairLine) { |
| | | return requestClient.post('/mes/dv/repair-line/create', data); |
| | | } |
| | | |
| | | /** ä¿®æ¹ç»´ä¿®å·¥åè¡ */ |
| | | /** ä¿®æ¹ç»´ä¿®è®¢åè¡ */ |
| | | export function updateRepairLine(data: MesDvRepairLineApi.RepairLine) { |
| | | return requestClient.put('/mes/dv/repair-line/update', data); |
| | | } |
| | | |
| | | /** å é¤ç»´ä¿®å·¥åè¡ */ |
| | | /** å é¤ç»´ä¿®è®¢åè¡ */ |
| | | export function deleteRepairLine(id: number) { |
| | | return requestClient.delete(`/mes/dv/repair-line/delete?id=${id}`); |
| | | } |
| | |
| | | import { requestClient } from '#/api/request'; |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | export namespace MesHomeApi { |
| | | /** MES é¦é¡µæ±æ»ç»è®¡ */ |
| | | export interface Summary { |
| | | workOrderActiveCount: number; // è¿è¡ä¸å·¥åæ° |
| | | workOrderPrepareCount: number; // å¾
æäº§å·¥åæ° |
| | | workOrderFinishedCount: number; // 已宿工忰 |
| | | workOrderActiveCount: number; // è¿è¡ä¸è®¢åæ° |
| | | workOrderPrepareCount: number; // å¾
æäº§è®¢åæ° |
| | | workOrderFinishedCount: number; // å·²å®æè®¢åæ° |
| | | todayOutput: number; // 仿¥äº§é |
| | | yesterdayOutput: number; // æ¨æ¥äº§é |
| | | todayQualifiedQuantity: number; // 仿¥åæ ¼åæ° |
| | |
| | | machineryStop: number; // åæºè®¾å¤æ° |
| | | machineryMaintenance: number; // ç»´æ¤ä¸è®¾å¤æ° |
| | | andonActiveCount: number; // æªå¤ç½®å®ç¯å¼å«æ° |
| | | repairActiveCount: number; // å¾
å¤çç»´ä¿®å·¥åæ° |
| | | repairActiveCount: number; // å¾
å¤çç»´ä¿®è®¢åæ° |
| | | } |
| | | |
| | | /** MES å·¥åç¶æåå¸ */ |
| | | /** MES 订åç¶æåå¸ */ |
| | | export interface WorkOrderStatus { |
| | | status: number; // å·¥åç¶æ |
| | | statusName: string; // å·¥åç¶æåç§° |
| | | status: number; // 订åç¶æ |
| | | statusName: string; // 订åç¶æåç§° |
| | | count: number; // æ°é |
| | | } |
| | | |
| | |
| | | return requestClient.get<MesHomeApi.Summary>('/mes/home-statistics/summary'); |
| | | } |
| | | |
| | | /** è·å¾å·¥åç¶æåå¸ */ |
| | | /** è·å¾è®¢åç¶æåå¸ */ |
| | | export function getWorkOrderStatusDistribution() { |
| | | return requestClient.get<MesHomeApi.WorkOrderStatus[]>( |
| | | '/mes/home-statistics/work-order-status', |
| | |
| | | import { requestClient } from '#/api/request'; |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | export namespace MesMdItemBatchConfigApi { |
| | | /** MES ç©ææ¹æ¬¡å±æ§é
ç½® */ |
| | |
| | | clientFlag?: boolean; // æ¹æ¬¡å±æ§-å®¢æ· |
| | | salesOrderCodeFlag?: boolean; // æ¹æ¬¡å±æ§-éå®è®¢åç¼å· |
| | | purchaseOrderCodeFlag?: boolean; // æ¹æ¬¡å±æ§-éè´è®¢åç¼å· |
| | | workorderFlag?: boolean; // æ¹æ¬¡å±æ§-ç产工å |
| | | workorderFlag?: boolean; // æ¹æ¬¡å±æ§-ç产订å |
| | | taskFlag?: boolean; // æ¹æ¬¡å±æ§-çäº§ä»»å¡ |
| | | workstationFlag?: boolean; // æ¹æ¬¡å±æ§-å·¥ä½ç« |
| | | toolFlag?: boolean; // æ¹æ¬¡å±æ§-å·¥å
· |
| | |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | import { isPdMockEnabled } from '../mock/enabled'; |
| | | import { pdMockStore } from '../mock/store'; |
| | | |
| | | export namespace MesPdArchiveApi { |
| | | /** æ°ååè®¾è®¡å½æ¡£å°è´¦ */ |
| | | /** 彿¡£å°è´¦ï¼å页èåï¼ */ |
| | | export interface Archive { |
| | | id?: number; |
| | | code?: string; |
| | | /** ææ°å½æ¡£ç¼å· */ |
| | | archiveCode?: string; |
| | | /** 设计项ç®ID */ |
| | | projectId?: number; |
| | | projectCode?: string; |
| | | projectName?: string; |
| | | /** ä»»å¡ç¼ç */ |
| | | taskCode?: string; |
| | | /** ä»»å¡åç§° */ |
| | | taskName?: string; |
| | | /** 产åç¼ç */ |
| | | productCode?: string; |
| | | /** 产ååç§° */ |
| | | productName?: string; |
| | | /** 该项ç®ä¸å½æ¡£è®°å½æ»æ° */ |
| | | archiveCount?: number; |
| | | /** 彿¡£äººID */ |
| | | archiver?: number; |
| | | /** 彿¡£äººåç§° */ |
| | | archiverNickname?: string; |
| | | /** 彿¡£ç¶æï¼åå
¸ mes_pd_archive_statusï¼ */ |
| | | archiveStatus?: number; |
| | | /** 彿¡£æ¶é´ */ |
| | | archiveTime?: number; |
| | | /** 夿³¨ */ |
| | | remark?: string; |
| | | /** å建æ¶é´ */ |
| | | createTime?: number; |
| | | /** æ´æ°äººID */ |
| | | updater?: string; |
| | | /** æ´æ°äººåç§° */ |
| | | updaterNickname?: string; |
| | | /** æ´æ°æ¶é´ */ |
| | | updateTime?: number; |
| | | } |
| | | |
| | | export interface PageParams extends PageParam { |
| | | archiveCode?: string; |
| | | projectId?: number; |
| | | archiveStatus?: number; |
| | | productCode?: string; |
| | | productName?: string; |
| | | } |
| | | |
| | | /** 详æ
- 项ç®ä¿¡æ¯ */ |
| | | export interface ProjectInfo { |
| | | id?: number; |
| | | taskCode?: string; |
| | | taskName?: string; |
| | | productCode?: string; |
| | | productName?: string; |
| | | version?: string; |
| | | archiveStatus?: number; |
| | | archiveTime?: number; |
| | | archiverId?: number; |
| | | archiverName?: string; |
| | | documentCount?: number; |
| | | bomCount?: number; |
| | | storagePath?: string; |
| | | status?: number; |
| | | chiefDesigner?: number; |
| | | chiefDesignerNickname?: string; |
| | | reviewer?: number; |
| | | reviewerNickname?: string; |
| | | planFinishTime?: number; |
| | | remark?: string; |
| | | createTime?: number; |
| | | } |
| | | |
| | | export interface PageParams extends PageParam { |
| | | code?: string; |
| | | projectCode?: string; |
| | | productCode?: string; |
| | | /** 详æ
- 彿¡£è®°å½ */ |
| | | export interface ArchiveInfo { |
| | | id?: number; |
| | | archiveCode?: string; |
| | | archiver?: number; |
| | | archiverNickname?: string; |
| | | archiveStatus?: number; |
| | | archiveTime?: number; |
| | | remark?: string; |
| | | createTime?: number; |
| | | } |
| | | |
| | | /** 详æ
- è®¾è®¡èµæ */ |
| | | export interface DocumentInfo { |
| | | id?: number; |
| | | documentType?: string; |
| | | documentName?: string; |
| | | documentVersion?: string; |
| | | fileName?: string; |
| | | fileUrl?: string; |
| | | uploadUserId?: number; |
| | | uploadUserNickname?: string; |
| | | uploadTime?: number; |
| | | remark?: string; |
| | | createTime?: number; |
| | | } |
| | | |
| | | /** 详æ
ï¼æäº§åæ¥è¯¢ï¼ */ |
| | | export interface DetailItem { |
| | | project: ProjectInfo; |
| | | archives: ArchiveInfo[]; |
| | | documents: DocumentInfo[]; |
| | | } |
| | | } |
| | | |
| | | /** 彿¡£å°è´¦åé¡µï¼æé¡¹ç®/产åèåï¼ */ |
| | | export function getPdArchivePage(params: MesPdArchiveApi.PageParams) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.getArchivePage(params); |
| | | } |
| | | return requestClient.get<PageResult<MesPdArchiveApi.Archive>>( |
| | | '/mes/pd/archive/page', |
| | | { params }, |
| | | ); |
| | | } |
| | | |
| | | export function getPdArchive(id: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.getArchive(id); |
| | | /** 彿¡£å°è´¦è¯¦æ
ï¼æäº§åç¼ç æ¥è¯¢ï¼ */ |
| | | export function getPdArchiveDetailByProduct(productCode: string) { |
| | | return requestClient.get<MesPdArchiveApi.DetailItem[]>( |
| | | '/mes/pd/archive/detail-by-product', |
| | | { params: { productCode } }, |
| | | ); |
| | | } |
| | | |
| | | export function getPdArchive(id: number) { |
| | | return requestClient.get<MesPdArchiveApi.Archive>( |
| | | `/mes/pd/archive/get?id=${id}`, |
| | | ); |
| | | } |
| | | |
| | | export function exportPdArchive(params: MesPdArchiveApi.PageParams) { |
| | | if (isPdMockEnabled()) { |
| | | return Promise.resolve(new Blob()); |
| | | export function updatePdArchive(data: MesPdArchiveApi.Archive) { |
| | | return requestClient.put('/mes/pd/archive/update', data); |
| | | } |
| | | |
| | | export function deletePdArchive(id: number) { |
| | | return requestClient.delete(`/mes/pd/archive/delete?id=${id}`); |
| | | } |
| | | |
| | | export function exportPdArchive(params: MesPdArchiveApi.PageParams) { |
| | | return requestClient.download('/mes/pd/archive/export-excel', { params }); |
| | | } |
| | |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | import { isPdMockEnabled } from '../mock/enabled'; |
| | | import { pdMockStore } from '../mock/store'; |
| | | |
| | | export namespace MesPdBomApi { |
| | | /** 设计 BOM è¡ */ |
| | | export interface BomLine { |
| | |
| | | } |
| | | |
| | | export function getPdBomPage(params: MesPdBomApi.PageParams) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.getBomPage(params); |
| | | } |
| | | return requestClient.get<PageResult<MesPdBomApi.BomLine>>( |
| | | '/mes/pd/bom/page', |
| | | { params }, |
| | |
| | | } |
| | | |
| | | export function createPdBomLine(data: MesPdBomApi.BomLine) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.createBomLine(data); |
| | | } |
| | | return requestClient.post<number>('/mes/pd/bom/create', data); |
| | | } |
| | | |
| | | export function updatePdBomLine(data: MesPdBomApi.BomLine) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.updateBomLine(data); |
| | | } |
| | | return requestClient.put('/mes/pd/bom/update', data); |
| | | } |
| | | |
| | | export function deletePdBomLine(id: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.deleteBomLine(id); |
| | | } |
| | | return requestClient.delete(`/mes/pd/bom/delete?id=${id}`); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import type { PageParam, PageResult } from '#/packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | export namespace MesPdDocumentAuditApi { |
| | | /** èµæå®¡æ ¸ */ |
| | | export interface DocumentAudit { |
| | | id?: number; |
| | | /** å®¡æ ¸åå· */ |
| | | auditNo?: string; |
| | | /** èµæID */ |
| | | documentId?: number; |
| | | /** èµæåç§°ï¼åä½ï¼ */ |
| | | documentName?: string; |
| | | /** èµæçæ¬ï¼åä½ï¼ */ |
| | | documentVersion?: string; |
| | | /** å®¡æ ¸äººï¼ç¨æ·IDï¼ */ |
| | | reviewer?: number; |
| | | /** å®¡æ ¸äººåç§° */ |
| | | reviewerNickname?: string; |
| | | /** å®¡æ ¸ç¶æï¼åå
¸ mes_pd_document_audit_statusï¼ */ |
| | | auditStatus?: number; |
| | | /** å®¡æ ¸æ¶é´ */ |
| | | auditTime?: number; |
| | | /** 夿³¨ */ |
| | | remark?: string; |
| | | /** å建æ¶é´ */ |
| | | createTime?: number; |
| | | } |
| | | |
| | | export interface PageParams extends PageParam { |
| | | auditNo?: string; |
| | | documentId?: number; |
| | | documentName?: string; |
| | | auditStatus?: number; |
| | | } |
| | | } |
| | | |
| | | /** è·åèµæå®¡æ ¸å页ï¼ä¸ä¼ èµææ¶å端èªå¨å建ï¼å端æ éè°ç¨ createï¼ */ |
| | | export function getPdDocumentAuditPage( |
| | | params: MesPdDocumentAuditApi.PageParams, |
| | | ) { |
| | | return requestClient.get<PageResult<MesPdDocumentAuditApi.DocumentAudit>>( |
| | | '/mes/pd/document-audit/page', |
| | | { params }, |
| | | ); |
| | | } |
| | | |
| | | export function getPdDocumentAudit(id: number) { |
| | | return requestClient.get<MesPdDocumentAuditApi.DocumentAudit>( |
| | | `/mes/pd/document-audit/get?id=${id}`, |
| | | ); |
| | | } |
| | | |
| | | export function updatePdDocumentAudit(data: MesPdDocumentAuditApi.DocumentAudit) { |
| | | return requestClient.put('/mes/pd/document-audit/update', data); |
| | | } |
| | | |
| | | export function deletePdDocumentAudit(id: number) { |
| | | return requestClient.delete(`/mes/pd/document-audit/delete?id=${id}`); |
| | | } |
| | | |
| | | export function exportPdDocumentAudit( |
| | | params: MesPdDocumentAuditApi.PageParams, |
| | | ) { |
| | | return requestClient.download('/mes/pd/document-audit/export-excel', { |
| | | params, |
| | | }); |
| | | } |
| | |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | import { isPdMockEnabled } from '../mock/enabled'; |
| | | import { pdMockStore } from '../mock/store'; |
| | | |
| | | export namespace MesPdDocumentApi { |
| | | /** è®¾è®¡èµæ */ |
| | | export interface Document { |
| | | id?: number; |
| | | /** 设计项ç®ID */ |
| | | projectId?: number; |
| | | documentType?: number; |
| | | name?: string; |
| | | version?: string; |
| | | fileUrl?: string; |
| | | /** èµæç±»åï¼åå
¸ mes_pd_document_typeï¼ */ |
| | | documentType?: string; |
| | | /** èµæåç§° */ |
| | | documentName?: string; |
| | | /** çæ¬ */ |
| | | documentVersion?: string; |
| | | /** æä»¶å */ |
| | | fileName?: string; |
| | | fileSize?: number; |
| | | uploaderId?: number; |
| | | uploaderName?: string; |
| | | /** ä¸ä¼ 人ï¼ç¨æ·IDï¼ */ |
| | | uploadUserId?: number; |
| | | /** ä¸ä¼ 人åç§° */ |
| | | uploadUserNickname?: string; |
| | | /** ä¸ä¼ æ¶é´ */ |
| | | uploadTime?: number; |
| | | /** æä»¶URL */ |
| | | fileUrl?: string; |
| | | /** 夿³¨ */ |
| | | remark?: string; |
| | | /** å建æ¶é´ */ |
| | | createTime?: number; |
| | | } |
| | | |
| | | export interface PageParams extends PageParam { |
| | | projectId: number; |
| | | documentType?: number; |
| | | name?: string; |
| | | version?: string; |
| | | documentType?: string; |
| | | documentName?: string; |
| | | documentVersion?: string; |
| | | } |
| | | } |
| | | |
| | | export function getPdDocumentPage(params: MesPdDocumentApi.PageParams) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.getDocumentPage(params); |
| | | } |
| | | return requestClient.get<PageResult<MesPdDocumentApi.Document>>( |
| | | '/mes/pd/document/page', |
| | | { params }, |
| | |
| | | } |
| | | |
| | | export function getPdDocument(id: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.getDocument(id); |
| | | } |
| | | return requestClient.get<MesPdDocumentApi.Document>( |
| | | `/mes/pd/document/get?id=${id}`, |
| | | ); |
| | | } |
| | | |
| | | export function createPdDocument(data: MesPdDocumentApi.Document) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.createDocument(data); |
| | | } |
| | | return requestClient.post<number>('/mes/pd/document/create', data); |
| | | } |
| | | |
| | | export function updatePdDocument(data: MesPdDocumentApi.Document) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.updateDocument(data); |
| | | } |
| | | return requestClient.put('/mes/pd/document/update', data); |
| | | } |
| | | |
| | | export function deletePdDocument(id: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.deleteDocument(id); |
| | | } |
| | | return requestClient.delete(`/mes/pd/document/delete?id=${id}`); |
| | | } |
| | | |
| | | export function exportPdDocument(params: MesPdDocumentApi.PageParams) { |
| | | return requestClient.download('/mes/pd/document/export-excel', { params }); |
| | | } |
| | |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | import { isPdMockEnabled } from '../mock/enabled'; |
| | | import { pdMockStore } from '../mock/store'; |
| | | |
| | | export namespace MesPdDrawingReviewApi { |
| | | /** å¾çº¸å®¡æ ¸ */ |
| | | export interface DrawingReview { |
| | |
| | | export function getPdDrawingReviewPage( |
| | | params: MesPdDrawingReviewApi.PageParams, |
| | | ) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.getDrawingReviewPage(params); |
| | | } |
| | | return requestClient.get<PageResult<MesPdDrawingReviewApi.DrawingReview>>( |
| | | '/mes/pd/drawing-review/page', |
| | | { params }, |
| | |
| | | } |
| | | |
| | | export function getPdDrawingReview(id: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.getDrawingReview(id); |
| | | } |
| | | return requestClient.get<MesPdDrawingReviewApi.DrawingReview>( |
| | | `/mes/pd/drawing-review/get?id=${id}`, |
| | | ); |
| | | } |
| | | |
| | | export function createPdDrawingReview(data: MesPdDrawingReviewApi.DrawingReview) { |
| | | if (isPdMockEnabled()) { |
| | | return Promise.resolve(1); |
| | | } |
| | | return requestClient.post<number>('/mes/pd/drawing-review/create', data); |
| | | } |
| | | |
| | | export function reviewPdDrawing(data: MesPdDrawingReviewApi.ReviewParams) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.reviewDrawing(data); |
| | | } |
| | | return requestClient.put('/mes/pd/drawing-review/review', data); |
| | | } |
| | |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | import { isPdMockEnabled } from '../mock/enabled'; |
| | | import { pdMockStore } from '../mock/store'; |
| | | |
| | | export namespace MesPdProjectApi { |
| | | /** 产åè®¾è®¡é¡¹ç® */ |
| | | export interface Project { |
| | | id?: number; |
| | | code?: string; |
| | | name?: string; |
| | | /** ä»»å¡ç¼ç */ |
| | | taskCode?: string; |
| | | /** ä»»å¡åç§° */ |
| | | taskName?: string; |
| | | /** 产åç¼ç */ |
| | | productCode?: string; |
| | | /** 产ååç§° */ |
| | | productName?: string; |
| | | /** çæ¬å· */ |
| | | version?: string; |
| | | /** ç¶æ */ |
| | | status?: number; |
| | | designerId?: number; |
| | | designerName?: string; |
| | | reviewerId?: number; |
| | | reviewerName?: string; |
| | | planStartDate?: number; |
| | | planEndDate?: number; |
| | | actualFinishDate?: number; |
| | | /** 主设计å¸ï¼ç¨æ·IDï¼ */ |
| | | chiefDesigner?: number; |
| | | /** 主设计å¸åç§° */ |
| | | chiefDesignerNickname?: string; |
| | | /** å®¡æ ¸äººï¼ç¨æ·IDï¼ */ |
| | | reviewer?: number; |
| | | /** å®¡æ ¸äººåç§° */ |
| | | reviewerNickname?: string; |
| | | /** 计å宿æ¶é´ */ |
| | | planFinishTime?: number; |
| | | /** 夿³¨ */ |
| | | remark?: string; |
| | | /** å建æ¶é´ */ |
| | | createTime?: number; |
| | | } |
| | | |
| | | export interface PageParams extends PageParam { |
| | | code?: string; |
| | | name?: string; |
| | | taskCode?: string; |
| | | taskName?: string; |
| | | productCode?: string; |
| | | productName?: string; |
| | | status?: number; |
| | | designerId?: number; |
| | | planFinishTime?: number[]; |
| | | } |
| | | } |
| | | |
| | | export function getPdProjectPage(params: MesPdProjectApi.PageParams) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.getProjectPage(params); |
| | | } |
| | | return requestClient.get<PageResult<MesPdProjectApi.Project>>( |
| | | '/mes/pd/project/page', |
| | | { params }, |
| | |
| | | } |
| | | |
| | | export function getPdProject(id: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.getProject(id); |
| | | } |
| | | return requestClient.get<MesPdProjectApi.Project>( |
| | | `/mes/pd/project/get?id=${id}`, |
| | | ); |
| | | } |
| | | |
| | | export function createPdProject(data: MesPdProjectApi.Project) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.createProject(data); |
| | | } |
| | | return requestClient.post<number>('/mes/pd/project/create', data); |
| | | } |
| | | |
| | | export function updatePdProject(data: MesPdProjectApi.Project) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.updateProject(data); |
| | | } |
| | | return requestClient.put('/mes/pd/project/update', data); |
| | | } |
| | | |
| | | export function deletePdProject(id: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.deleteProject(id); |
| | | } |
| | | return requestClient.delete(`/mes/pd/project/delete?id=${id}`); |
| | | } |
| | | |
| | | export function exportPdProject(params: MesPdProjectApi.PageParams) { |
| | | if (isPdMockEnabled()) { |
| | | return Promise.resolve(new Blob()); |
| | | } |
| | | return requestClient.download('/mes/pd/project/export-excel', { params }); |
| | | } |
| | | |
| | | export function submitPdProjectReview(id: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.submitProjectReview(id); |
| | | } |
| | | return requestClient.put('/mes/pd/project/submit-review', undefined, { |
| | | params: { id }, |
| | | }); |
| | | } |
| | | |
| | | /** åå¸ï¼å¾
åå¸âå¾
ä¸ä¼ ï¼ */ |
| | | export function publishPdProject(id: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.publishProject(id); |
| | | } |
| | | return requestClient.put('/mes/pd/project/publish', undefined, { |
| | | params: { id }, |
| | | }); |
| | | } |
| | | |
| | | export function approvePdProject(id: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.approveProject(id); |
| | | } |
| | | return requestClient.put('/mes/pd/project/approve', undefined, { |
| | | /** ä¸ä¼ èµæï¼å¾
ä¸ä¼ âå¾
å®¡æ ¸ï¼ï¼å端èªå¨åå»ºèµæå®¡æ ¸è®°å½ */ |
| | | export function uploadPdProject(id: number) { |
| | | return requestClient.put('/mes/pd/project/upload', undefined, { |
| | | params: { id }, |
| | | }); |
| | | } |
| | | |
| | | export function archivePdProject(id: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.archiveProject(id); |
| | | /** å®¡æ ¸ï¼å¾
å®¡æ ¸âå¾
彿¡£ï¼ */ |
| | | export function auditPdProject(id: number) { |
| | | return requestClient.put('/mes/pd/project/audit', undefined, { |
| | | params: { id }, |
| | | }); |
| | | } |
| | | |
| | | /** 彿¡£ï¼å¾
彿¡£â已彿¡£ï¼ï¼å端èªå¨åå»ºå½æ¡£å°è´¦è®°å½ */ |
| | | export function archivePdProject(id: number) { |
| | | return requestClient.put('/mes/pd/project/archive', undefined, { |
| | | params: { id }, |
| | | }); |
| | |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | import { isPdMockEnabled } from '../mock/enabled'; |
| | | import { pdMockStore } from '../mock/store'; |
| | | |
| | | export namespace MesPdTaskApi { |
| | | /** 产åè®¾è®¡ä»»å¡ */ |
| | | export interface Task { |
| | |
| | | } |
| | | |
| | | export function getPdTaskPage(params: MesPdTaskApi.PageParams) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.getTaskPage(params); |
| | | } |
| | | return requestClient.get<PageResult<MesPdTaskApi.Task>>( |
| | | '/mes/pd/task/page', |
| | | { params }, |
| | |
| | | } |
| | | |
| | | export function getPdTask(id: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.getTask(id); |
| | | } |
| | | return requestClient.get<MesPdTaskApi.Task>(`/mes/pd/task/get?id=${id}`); |
| | | } |
| | | |
| | | export function createPdTask(data: MesPdTaskApi.Task) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.createTask(data); |
| | | } |
| | | return requestClient.post<number>('/mes/pd/task/create', data); |
| | | } |
| | | |
| | | export function updatePdTask(data: MesPdTaskApi.Task) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.updateTask(data); |
| | | } |
| | | return requestClient.put('/mes/pd/task/update', data); |
| | | } |
| | | |
| | | export function deletePdTask(id: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.deleteTask(id); |
| | | } |
| | | return requestClient.delete(`/mes/pd/task/delete?id=${id}`); |
| | | } |
| | | |
| | | export function dispatchPdTask(data: MesPdTaskApi.DispatchParams) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.dispatchTask(data); |
| | | } |
| | | return requestClient.put('/mes/pd/task/dispatch', data); |
| | | } |
| | | |
| | | export function completePdTask(id: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.completeTask(id); |
| | | } |
| | | return requestClient.put('/mes/pd/task/complete', undefined, { |
| | | params: { id }, |
| | | }); |
| | |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | import { isPdMockEnabled } from '../mock/enabled'; |
| | | import { pdMockStore } from '../mock/store'; |
| | | |
| | | export namespace MesPdVersionChangeApi { |
| | | /** çæ¬åæ´ */ |
| | | export interface VersionChange { |
| | |
| | | export function getPdVersionChangePage( |
| | | params: MesPdVersionChangeApi.PageParams, |
| | | ) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.getVersionChangePage(params); |
| | | } |
| | | return requestClient.get<PageResult<MesPdVersionChangeApi.VersionChange>>( |
| | | '/mes/pd/version-change/page', |
| | | { params }, |
| | |
| | | } |
| | | |
| | | export function getPdVersionChange(id: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.getVersionChange(id); |
| | | } |
| | | return requestClient.get<MesPdVersionChangeApi.VersionChange>( |
| | | `/mes/pd/version-change/get?id=${id}`, |
| | | ); |
| | | } |
| | | |
| | | export function createPdVersionChange(data: MesPdVersionChangeApi.VersionChange) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.createVersionChange(data); |
| | | } |
| | | return requestClient.post<number>('/mes/pd/version-change/create', data); |
| | | } |
| | | |
| | | export function updatePdVersionChange(data: MesPdVersionChangeApi.VersionChange) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.updateVersionChange(data); |
| | | } |
| | | return requestClient.put('/mes/pd/version-change/update', data); |
| | | } |
| | | |
| | | export function deletePdVersionChange(id: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.deleteVersionChange(id); |
| | | } |
| | | return requestClient.delete(`/mes/pd/version-change/delete?id=${id}`); |
| | | } |
| | | |
| | | export function approvePdVersionChange(id: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.approveVersionChange(id); |
| | | } |
| | | return requestClient.put('/mes/pd/version-change/approve', undefined, { |
| | | params: { id }, |
| | | }); |
| | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | import { isPdMockEnabled } from '../mock/enabled'; |
| | | import { pdMockStore } from '../mock/store'; |
| | | |
| | | export namespace MesPdWorkflowApi { |
| | | /** 设计æµç¨èç¹ */ |
| | | export interface WorkflowNode { |
| | |
| | | } |
| | | |
| | | export function getPdWorkflowList(projectId: number) { |
| | | if (isPdMockEnabled()) { |
| | | return pdMockStore.getWorkflowList(projectId); |
| | | } |
| | | return requestClient.get<MesPdWorkflowApi.WorkflowNode[]>( |
| | | '/mes/pd/workflow/list', |
| | | { params: { projectId } }, |
| | |
| | | import type { PageParam, PageResult } from '../../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | |
| | | workstationId?: number; // å·¥ä½ç«ç¼å· |
| | | workstationCode?: string; // å·¥ä½ç«ç¼ç |
| | | workstationName?: string; // å·¥ä½ç«åç§° |
| | | workOrderId?: number; // ç产工åç¼å· |
| | | workOrderCode?: string; // å·¥åç¼ç |
| | | workOrderId?: number; // ç产订åç¼å· |
| | | workOrderCode?: string; // 订åç¼ç |
| | | processId?: number; // å·¥åºç¼å· |
| | | processName?: string; // å·¥åºåç§° |
| | | userId?: number; // åèµ·ç¨æ·ç¼å· |
| | |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | |
| | | export interface Card { |
| | | id?: number; // ç¼å· |
| | | code?: string; // æµè½¬å¡ç¼ç |
| | | workOrderId?: number; // ç产工åç¼å· |
| | | workOrderCode?: string; // å·¥åç¼ç |
| | | workOrderName?: string; // å·¥ååç§° |
| | | workOrderId?: number; // ç产订åç¼å· |
| | | workOrderCode?: string; // 订åç¼ç |
| | | workOrderName?: string; // 订ååç§° |
| | | batchCode?: string; // æ¹æ¬¡å· |
| | | itemId?: number; // 产åç©æç¼å· |
| | | itemCode?: string; // 产åç¼ç |
| | |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | |
| | | /** MES ç产æ¥å·¥ */ |
| | | export interface Feedback { |
| | | id?: number; |
| | | code?: string; // æ¥å·¥åç¼å· |
| | | code?: string; // æ¥è®¢åç¼å· |
| | | type?: number; // æ¥å·¥ç±»å |
| | | channel?: string; // æ¥å·¥éå¾ |
| | | feedbackTime?: number; // æ¥å·¥æ¶é´ |
| | |
| | | processCode?: string; // å·¥åºç¼ç |
| | | processName?: string; // å·¥åºåç§° |
| | | checkFlag?: boolean; // æ¯å¦éè¦æ£éª |
| | | workOrderId?: number; // ç产工åç¼å· |
| | | workOrderCode?: string; // å·¥åç¼ç |
| | | workOrderName?: string; // å·¥ååç§° |
| | | workOrderId?: number; // ç产订åç¼å· |
| | | workOrderCode?: string; // 订åç¼ç |
| | | workOrderName?: string; // 订ååç§° |
| | | taskId?: number; // ç产任å¡ç¼å· |
| | | taskCode?: string; // ä»»å¡ç¼ç |
| | | itemId?: number; // 产åç©æç¼å· |
| | |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | |
| | | id?: number; |
| | | code?: string; // ä»»å¡ç¼ç |
| | | name?: string; // ä»»å¡åç§° |
| | | workOrderId?: number; // ç产工åç¼å· |
| | | workOrderCode?: string; // å·¥åç¼ç |
| | | workOrderName?: string; // å·¥ååç§° |
| | | workOrderId?: number; // ç产订åç¼å· |
| | | workOrderCode?: string; // 订åç¼ç |
| | | workOrderName?: string; // 订ååç§° |
| | | workstationId?: number; // å·¥ä½ç«ç¼å· |
| | | workstationCode?: string; // å·¥ä½ç«ç¼ç |
| | | workstationName?: string; // å·¥ä½ç«åç§° |
| | |
| | | startTime?: number; // å¼å§ç产æ¶é´ |
| | | endTime?: number; // ç»æç产æ¶é´ |
| | | duration?: number; // ç产æ¶é¿ï¼å·¥ä½æ¥ï¼1=8å°æ¶ï¼ |
| | | requestDate?: number; // éæ±æ¥æï¼ä»å·¥åæ¥ï¼ |
| | | requestDate?: number; // éæ±æ¥æï¼ä»è®¢åæ¥ï¼ |
| | | finishDate?: number; // å®ææ¥æ |
| | | cancelDate?: number; // åæ¶æ¥æ |
| | | colorCode?: string; // çç¹å¾æ¾ç¤ºé¢è² |
| | |
| | | import type { PageParam, PageResult } from '../../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | |
| | | export interface TaskIssue { |
| | | id?: number; // ç¼å· |
| | | taskId?: number; // ç产任å¡ç¼å· |
| | | workOrderId?: number; // ç产工åç¼å· |
| | | workOrderId?: number; // ç产订åç¼å· |
| | | workstationId?: number; // å·¥ä½ç«ç¼å· |
| | | sourceDocType?: string; // æ¥æºåæ®ç±»å |
| | | sourceDocId?: number; // æ¥æºåæ®ç¼å· |
| | |
| | | /** MES çäº§ä»»å¡ææå页æ¥è¯¢åæ° */ |
| | | export interface PageParams extends PageParam { |
| | | taskId?: number; // ç产任å¡ç¼å· |
| | | workOrderId?: number; // ç产工åç¼å· |
| | | workOrderId?: number; // ç产订åç¼å· |
| | | workstationId?: number; // å·¥ä½ç«ç¼å· |
| | | itemId?: number; // 产åç©æç¼å· |
| | | } |
| | |
| | | import type { PageParam, PageResult } from '../../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | export namespace MesProWorkOrderBomApi { |
| | | /** MES ç产工å BOM */ |
| | | /** MES ç产订å BOM */ |
| | | export interface WorkOrderBom { |
| | | id?: number; // ç¼å· |
| | | workOrderId?: number; // ç产工åç¼å· |
| | | workOrderId?: number; // ç产订åç¼å· |
| | | itemId?: number; // BOM ç©æç¼å· |
| | | itemName?: string; // ç©æåç§° |
| | | itemCode?: string; // ç©æç¼ç |
| | |
| | | itemOrProduct?: string; // ç©æäº§åæ è¯ |
| | | } |
| | | |
| | | /** MES ç产工å BOM å页æ¥è¯¢åæ° */ |
| | | /** MES ç产订å BOM å页æ¥è¯¢åæ° */ |
| | | export interface PageParams extends PageParam { |
| | | workOrderId?: number; |
| | | } |
| | | } |
| | | |
| | | /** æ¥è¯¢å·¥å BOM å页 */ |
| | | /** æ¥è¯¢è®¢å BOM å页 */ |
| | | export function getWorkOrderBomPage(params: MesProWorkOrderBomApi.PageParams) { |
| | | return requestClient.get<PageResult<MesProWorkOrderBomApi.WorkOrderBom>>( |
| | | '/mes/pro/work-order-bom/page', |
| | |
| | | ); |
| | | } |
| | | |
| | | /** æ¥è¯¢å·¥å BOM 详æ
*/ |
| | | /** æ¥è¯¢è®¢å BOM 详æ
*/ |
| | | export function getWorkOrderBom(id: number) { |
| | | return requestClient.get<MesProWorkOrderBomApi.WorkOrderBom>( |
| | | `/mes/pro/work-order-bom/get?id=${id}`, |
| | | ); |
| | | } |
| | | |
| | | /** æ°å¢å·¥å BOM */ |
| | | /** æ°å¢è®¢å BOM */ |
| | | export function createWorkOrderBom(data: MesProWorkOrderBomApi.WorkOrderBom) { |
| | | return requestClient.post('/mes/pro/work-order-bom/create', data); |
| | | } |
| | | |
| | | /** ä¿®æ¹å·¥å BOM */ |
| | | /** ä¿®æ¹è®¢å BOM */ |
| | | export function updateWorkOrderBom(data: MesProWorkOrderBomApi.WorkOrderBom) { |
| | | return requestClient.put('/mes/pro/work-order-bom/update', data); |
| | | } |
| | | |
| | | /** å é¤å·¥å BOM */ |
| | | /** å é¤è®¢å BOM */ |
| | | export function deleteWorkOrderBom(id: number) { |
| | | return requestClient.delete(`/mes/pro/work-order-bom/delete?id=${id}`); |
| | | } |
| | | |
| | | /** æ¥è¯¢å·¥åç©æéæ±å表 */ |
| | | /** æ¥è¯¢è®¢åç©æéæ±å表 */ |
| | | export function getWorkOrderBomItemListByWorkOrderId(workOrderId: number) { |
| | | return requestClient.get<MesProWorkOrderBomApi.WorkOrderBom[]>( |
| | | `/mes/pro/work-order-bom/item-list-by-work-order-id?workOrderId=${workOrderId}`, |
| | |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | export namespace MesProWorkOrderApi { |
| | | /** MES ç产工å */ |
| | | /** MES ç产订å */ |
| | | export interface WorkOrder { |
| | | id?: number; // ç¼å· |
| | | code?: string; // å·¥åç¼ç |
| | | name?: string; // å·¥ååç§° |
| | | type?: number; // å·¥åç±»å |
| | | code?: string; // 订åç¼ç |
| | | name?: string; // 订ååç§° |
| | | type?: number; // 订åç±»å |
| | | orderSourceType?: number; // æ¥æºç±»å |
| | | orderSourceCode?: string; // æ¥æºåæ®ç¼å· |
| | | productId?: number; // 产åç¼å· |
| | |
| | | vendorCode?: string; // ä¾åºåç¼ç |
| | | batchCode?: string; // æ¹æ¬¡å· |
| | | requestDate?: number; // éæ±æ¥æ |
| | | parentId?: number; // ç¶å·¥åç¼å· |
| | | parentCode?: string; // ç¶å·¥åç¼ç |
| | | parentId?: number; // ç¶è®¢åç¼å· |
| | | parentCode?: string; // ç¶è®¢åç¼ç |
| | | finishDate?: number; // 宿æ¶é´ |
| | | cancelDate?: number; // åæ¶æ¶é´ |
| | | status?: number; // å·¥åç¶æ |
| | | status?: number; // 订åç¶æ |
| | | remark?: string; // 夿³¨ |
| | | createTime?: number; // å建æ¶é´ |
| | | } |
| | | |
| | | /** MES ç产工åå页æ¥è¯¢åæ° */ |
| | | /** MES ç产订åå页æ¥è¯¢åæ° */ |
| | | export interface PageParams extends PageParam { |
| | | code?: string; |
| | | name?: string; |
| | |
| | | } |
| | | } |
| | | |
| | | /** æ¥è¯¢ç产工åå页 */ |
| | | /** æ¥è¯¢ç产订åå页 */ |
| | | export function getWorkOrderPage(params: MesProWorkOrderApi.PageParams) { |
| | | return requestClient.get<PageResult<MesProWorkOrderApi.WorkOrder>>( |
| | | '/mes/pro/work-order/page', |
| | |
| | | ); |
| | | } |
| | | |
| | | /** æ¥è¯¢ç产工å详æ
*/ |
| | | /** æ¥è¯¢ç产订å详æ
*/ |
| | | export function getWorkOrder(id: number) { |
| | | return requestClient.get<MesProWorkOrderApi.WorkOrder>( |
| | | `/mes/pro/work-order/get?id=${id}`, |
| | | ); |
| | | } |
| | | |
| | | /** æ°å¢ç产工å */ |
| | | /** æ°å¢ç产订å */ |
| | | export function createWorkOrder(data: MesProWorkOrderApi.WorkOrder) { |
| | | return requestClient.post<number>('/mes/pro/work-order/create', data); |
| | | } |
| | | |
| | | /** ä¿®æ¹ç产工å */ |
| | | /** ä¿®æ¹ç产订å */ |
| | | export function updateWorkOrder(data: MesProWorkOrderApi.WorkOrder) { |
| | | return requestClient.put('/mes/pro/work-order/update', data); |
| | | } |
| | | |
| | | /** å é¤ç产工å */ |
| | | /** å é¤ç产订å */ |
| | | export function deleteWorkOrder(id: number) { |
| | | return requestClient.delete(`/mes/pro/work-order/delete?id=${id}`); |
| | | } |
| | | |
| | | /** 导åºç产工å */ |
| | | /** 导åºç产订å */ |
| | | export function exportWorkOrder(params: any) { |
| | | return requestClient.download('/mes/pro/work-order/export-excel', { params }); |
| | | } |
| | | |
| | | /** 宿工å */ |
| | | /** å®æè®¢å */ |
| | | export function finishWorkOrder(id: number) { |
| | | return requestClient.put(`/mes/pro/work-order/finish?id=${id}`); |
| | | } |
| | | |
| | | /** åæ¶å·¥å */ |
| | | /** åæ¶è®¢å */ |
| | | export function cancelWorkOrder(id: number) { |
| | | return requestClient.put(`/mes/pro/work-order/cancel?id=${id}`); |
| | | } |
| | | |
| | | /** 确认工å */ |
| | | /** 确认订å */ |
| | | export function confirmWorkOrder(id: number) { |
| | | return requestClient.put(`/mes/pro/work-order/confirm?id=${id}`); |
| | | } |
| | |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | |
| | | sourceDocId?: number; // æ¥æºåæ® ID |
| | | sourceLineId?: number; // æ¥æºåæ®è¡ ID |
| | | sourceDocCode?: string; // æ¥æºåæ®ç¼å·ï¼å
³èæ¥è¯¢ï¼ |
| | | workOrderId?: number; // ç产工å ID |
| | | workOrderCode?: string; // å·¥åç¼å·ï¼å
³èæ¥è¯¢ï¼ |
| | | workOrderName?: string; // å·¥ååç§°ï¼å
³èæ¥è¯¢ï¼ |
| | | workOrderId?: number; // ç产订å ID |
| | | workOrderCode?: string; // 订åç¼å·ï¼å
³èæ¥è¯¢ï¼ |
| | | workOrderName?: string; // 订ååç§°ï¼å
³èæ¥è¯¢ï¼ |
| | | taskId?: number; // çäº§ä»»å¡ ID |
| | | workstationId?: number; // å·¥ä½ ID |
| | | workstationName?: string; // å·¥ä½åç§°ï¼å
³èæ¥è¯¢ï¼ |
| | |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | |
| | | // ä¾åºåï¼IQC åºæ¯ï¼ |
| | | vendorId?: number; // ä¾åºå ID |
| | | vendorName?: string; // ä¾åºååç§° |
| | | // å·¥å/å·¥ä½ç«/ä»»å¡ï¼IPQC/RQC åºæ¯ï¼ |
| | | workOrderId?: number; // ç产工å ID |
| | | // 订å/å·¥ä½ç«/ä»»å¡ï¼IPQC/RQC åºæ¯ï¼ |
| | | workOrderId?: number; // ç产订å ID |
| | | workstationId?: number; // å·¥ä½ç« ID |
| | | workstationName?: string; // å·¥ä½ç«åç§° |
| | | taskId?: number; // çäº§ä»»å¡ ID |
| | |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | |
| | | clientName?: string; // 客æ·åç§° |
| | | purchaseOrderCode?: string; // éè´è®¢åç¼å· |
| | | salesOrderCode?: string; // éå®è®¢åç¼å· |
| | | workOrderId?: number; // ç产工å ID |
| | | workOrderCode?: string; // ç产工åç¼å· |
| | | workOrderId?: number; // ç产订å ID |
| | | workOrderCode?: string; // ç产订åç¼å· |
| | | taskId?: number; // çäº§ä»»å¡ ID |
| | | taskCode?: string; // ç产任å¡ç¼å· |
| | | workstationId?: number; // å·¥ä½ç« ID |
| | |
| | | itemId?: number; // ç©æç¼å· |
| | | vendorId?: number; // ä¾åºåç¼å· |
| | | clientId?: number; // 客æ·ç¼å· |
| | | workOrderId?: number; // å·¥åç¼å· |
| | | workOrderId?: number; // 订åç¼å· |
| | | taskId?: number; // ç产任å¡ç¼å· |
| | | workstationId?: number; // å·¥ä½ç«ç¼å· |
| | | toolId?: number; // å·¥å
·ç¼å· |
| | |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | |
| | | vendorId?: number; // ä¾åºåç¼å· |
| | | vendorCode?: string; // ä¾åºåç¼ç |
| | | vendorName?: string; // ä¾åºååç§° |
| | | workOrderId?: number; // ç产工åç¼å· |
| | | workOrderCode?: string; // ç产工åç¼ç |
| | | workOrderName?: string; // ç产工ååç§° |
| | | workOrderId?: number; // ç产订åç¼å· |
| | | workOrderCode?: string; // ç产订åç¼ç |
| | | workOrderName?: string; // ç产订ååç§° |
| | | issueDate?: number; // åææ¥æ |
| | | status?: number; // åæ®ç¶æ |
| | | remark?: string; // 夿³¨ |
| | |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | |
| | | id?: number; // å
¥åºåç¼å· |
| | | code?: string; // å
¥åºåç¼ç |
| | | name?: string; // å
¥åºååç§° |
| | | workOrderId?: number; // å¤åå·¥åç¼å· |
| | | workOrderCode?: string; // å¤åå·¥åç¼ç |
| | | workOrderId?: number; // å¤å订åç¼å· |
| | | workOrderCode?: string; // å¤å订åç¼ç |
| | | vendorId?: number; // ä¾åºåç¼å· |
| | | vendorName?: string; // ä¾åºååç§° |
| | | receiptDate?: number; // å
¥åºæ¥æ |
| | |
| | | import type { PageParam, PageResult } from '../../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | |
| | | specification?: string; // è§æ ¼åå· |
| | | unitMeasureName?: string; // 计éåä½åç§° |
| | | quantity?: number; // è£
ç®±æ°é |
| | | workOrderId?: number; // ç产工åç¼å· |
| | | workOrderCode?: string; // ç产工åç¼å· |
| | | workOrderId?: number; // ç产订åç¼å· |
| | | workOrderCode?: string; // ç产订åç¼å· |
| | | batchCode?: string; // æ¹æ¬¡å· |
| | | expireDate?: number; // æææ |
| | | remark?: string; // 夿³¨ |
| | |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | |
| | | workstationId?: number; // å·¥ä½ç«ç¼å· |
| | | workstationCode?: string; // å·¥ä½ç«ç¼ç |
| | | workstationName?: string; // å·¥ä½ç«åç§° |
| | | workOrderId?: number; // ç产工åç¼å· |
| | | workOrderCode?: string; // ç产工åç¼ç |
| | | workOrderId?: number; // ç产订åç¼å· |
| | | workOrderCode?: string; // ç产订åç¼ç |
| | | clientCode?: string; // 客æ·ç¼ç |
| | | clientName?: string; // 客æ·åç§° |
| | | requiredTime?: number; // éæ±æ¶é´ |
| | |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | |
| | | id?: number; // å
¥åºåç¼å· |
| | | code?: string; // å
¥åºåç¼ç |
| | | name?: string; // å
¥åºååç§° |
| | | workOrderId?: number; // ç产工åç¼å· |
| | | workOrderCode?: string; // ç产工åç¼ç |
| | | workOrderId?: number; // ç产订åç¼å· |
| | | workOrderCode?: string; // ç产订åç¼ç |
| | | itemId?: number; // 产åç©æç¼å· |
| | | itemCode?: string; // 产åç©æç¼ç |
| | | itemName?: string; // 产åç©æåç§° |
| | |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | |
| | | name?: string; // éæååç§° |
| | | workstationId?: number; // å·¥ä½ç«ç¼å· |
| | | workstationName?: string; // å·¥ä½ç«åç§° |
| | | workOrderId?: number; // ç产工åç¼å· |
| | | workOrderCode?: string; // ç产工åç¼ç |
| | | workOrderId?: number; // ç产订åç¼å· |
| | | workOrderCode?: string; // ç产订åç¼ç |
| | | type?: number; // éæç±»å |
| | | returnDate?: number; // éææ¥æ |
| | | status?: number; // åæ®ç¶æ |
| | |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | import type { PageParam, PageResult } from '../../../../packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | |
| | | specification?: string; // è§æ ¼åå· |
| | | unitName?: string; // åä½åç§° |
| | | batchCode?: string; // æ¹æ¬¡å· |
| | | workOrderId?: number; // ç产工åç¼å· |
| | | workOrderId?: number; // ç产订åç¼å· |
| | | createTime?: Date; // çææ¶é´ |
| | | } |
| | | |
| | |
| | | specification?: string; // è§æ ¼åå· |
| | | unitName?: string; // åä½åç§° |
| | | batchCode?: string; // æ¹æ¬¡å· |
| | | workOrderId?: number; // ç产工åç¼å· |
| | | workOrderId?: number; // ç产订åç¼å· |
| | | createTime?: Date; // çææ¶é´ |
| | | } |
| | | |
| | |
| | | export interface SnGenerate { |
| | | itemId?: number; // ç©æç¼å· |
| | | batchCode?: string; // æ¹æ¬¡å· |
| | | workOrderId?: number; // ç产工åç¼å· |
| | | workOrderId?: number; // ç产订åç¼å· |
| | | count?: number; // çææ°é |
| | | } |
| | | |
| | |
| | | PD_PROJECT_CODE: 'PD_PROJECT_CODE', |
| | | PD_TASK_CODE: 'PD_TASK_CODE', |
| | | PD_VERSION_CODE: 'PD_VERSION_CODE', |
| | | PD_DOCUMENT_AUDIT_CODE: 'PD_DOCUMENT_AUDIT_CODE', |
| | | PD_ARCHIVE_CODE: 'PD_ARCHIVE_CODE', |
| | | PRO_CARD_CODE: 'PRO_CARD_CODE', |
| | | PRO_FEEDBACK_CODE: 'PRO_FEEDBACK_CODE', |
| | | PRO_PROCESS_CODE: 'PRO_PROCESS_CODE', |
| | |
| | | RIGHT: 2, // å³è¡¥é½ |
| | | } as const; |
| | | |
| | | /** MES 产å设计项ç®ç¶ææä¸¾ */ |
| | | /** MES 产å设计项ç®ç¶ææä¸¾ï¼çº¿æ§æµè½¬ï¼å¾
åå¸âå¾
ä¸ä¼ âå¾
å®¡æ ¸âå¾
彿¡£â已彿¡£ï¼ */ |
| | | export const MesPdProjectStatusEnum = { |
| | | DRAFT: MesOrderStatusConstants.DRAFT, |
| | | DESIGNING: 10, |
| | | REVIEWING: MesOrderStatusConstants.APPROVING, |
| | | APPROVED: MesOrderStatusConstants.APPROVED, |
| | | ARCHIVED: 20, |
| | | CANCELLED: MesOrderStatusConstants.CANCELLED, |
| | | PENDING_PUBLISH: 0, // å¾
åå¸ |
| | | PENDING_UPLOAD: 1, // å¾
ä¸ä¼ |
| | | PENDING_AUDIT: 2, // å¾
å®¡æ ¸ |
| | | PENDING_ARCHIVE: 3, // å¾
彿¡£ |
| | | ARCHIVED: 4, // 已彿¡£ |
| | | } as const; |
| | | |
| | | /** MES 产å设计任å¡ç¶ææä¸¾ */ |
| | |
| | | PATCH: 3, |
| | | } as const; |
| | | |
| | | /** MES 产åè®¾è®¡èµæç±»åæä¸¾ */ |
| | | /** MES 产åè®¾è®¡èµæç±»åæä¸¾ï¼åå
¸ mes_pd_document_typeï¼å端åå¨ string ç±»åï¼ */ |
| | | export const MesPdDocumentTypeEnum = { |
| | | SCHEME: 1, |
| | | DRAWING: 2, |
| | | MODEL: 3, |
| | | PRODUCT_DESIGN: 4, |
| | | OTHER: 5, |
| | | BOM: 6, |
| | | SCHEME: 'scheme', |
| | | DRAWING: 'drawing', |
| | | MODEL: 'model', |
| | | PRODUCT_DESIGN: 'product_design', |
| | | BOM: 'bom', |
| | | OTHER: 'other', |
| | | } as const; |
| | | |
| | | /** MES æ¡ç æ ¼å¼æä¸¾ */ |
| | |
| | | MES_PD_PROJECT_STATUS: 'mes_pd_project_status', // MES 产å设计项ç®ç¶æ |
| | | MES_PD_TASK_STATUS: 'mes_pd_task_status', // MES 产å设计任å¡ç¶æ |
| | | MES_PD_DRAWING_REVIEW_STATUS: 'mes_pd_drawing_review_status', // MES å¾çº¸å®¡æ ¸ç¶æ |
| | | MES_PD_DOCUMENT_AUDIT_STATUS: 'mes_pd_document_audit_status', // MES èµæå®¡æ ¸ç¶æ |
| | | MES_PD_VERSION_CHANGE_TYPE: 'mes_pd_version_change_type', // MES çæ¬åæ´ç±»å |
| | | MES_PD_DOCUMENT_TYPE: 'mes_pd_document_type', // MES è®¾è®¡èµæç±»å |
| | | MES_PD_ARCHIVE_STATUS: 'mes_pd_archive_status', // MES è®¾è®¡å½æ¡£ç¶æ |
| | |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesDvRepairApi } from '#/api/mes/dv/repair'; |
| | | |
| | |
| | | return ['confirm', 'detail', 'finish'].includes(formType); |
| | | } |
| | | |
| | | /** æ°å¢/ä¿®æ¹ç»´ä¿®å·¥åç表å */ |
| | | /** æ°å¢/ä¿®æ¹ç»´ä¿®è®¢åç表å */ |
| | | export function useFormSchema( |
| | | formType: FormType, |
| | | formApi?: VbenFormApi, |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesDvRepairApi } from '#/api/mes/dv/repair'; |
| | | |
| | |
| | | gridApi.query(); |
| | | } |
| | | |
| | | /** å建维修工å */ |
| | | /** å建维修订å */ |
| | | function handleCreate() { |
| | | formModalApi.setData({ formType: 'create' }).open(); |
| | | } |
| | | |
| | | /** æ¥ç维修工å */ |
| | | /** æ¥ç维修订å */ |
| | | function handleDetail(row: MesDvRepairApi.Repair) { |
| | | formModalApi.setData({ id: row.id, formType: 'detail' }).open(); |
| | | } |
| | | |
| | | /** ç¼è¾ç»´ä¿®å·¥å */ |
| | | /** ç¼è¾ç»´ä¿®è®¢å */ |
| | | function handleEdit(row: MesDvRepairApi.Repair) { |
| | | formModalApi.setData({ id: row.id, formType: 'update' }).open(); |
| | | } |
| | |
| | | formModalApi.setData({ id: row.id, formType: 'finish' }).open(); |
| | | } |
| | | |
| | | /** å é¤ç»´ä¿®å·¥å */ |
| | | /** å é¤ç»´ä¿®è®¢å */ |
| | | async function handleDelete(row: MesDvRepairApi.Repair) { |
| | | const hideLoading = message.loading({ |
| | | content: $t('ui.actionMessage.deleting', [row.name]), |
| | |
| | | } |
| | | } |
| | | |
| | | /** 导åºç»´ä¿®å·¥å */ |
| | | /** 导åºç»´ä¿®è®¢å */ |
| | | async function handleExport() { |
| | | const data = await exportRepair(await gridApi.formApi.getValues()); |
| | | downloadFileFromBlobPart({ fileName: '维修工å.xls', source: data }); |
| | | downloadFileFromBlobPart({ fileName: '维修订å.xls', source: data }); |
| | | } |
| | | |
| | | const [Grid, gridApi] = useVbenVxeGrid({ |
| | |
| | | </script> |
| | | <template> |
| | | <Page auto-content-height><FormModal @success="handleRefresh" /> |
| | | <Grid table-title="维修工åå表"> |
| | | <Grid table-title="维修订åå表"> |
| | | <template #toolbar-tools> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: $t('ui.actionTitle.create', ['维修工å']), |
| | | label: $t('ui.actionTitle.create', ['维修订å']), |
| | | type: 'primary', |
| | | icon: ACTION_ICON.ADD, |
| | | auth: ['mes:dv-repair:create'], |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { FormType } from '../data'; |
| | | |
| | | import type { MesDvRepairApi } from '#/api/mes/dv/repair'; |
| | |
| | | ); |
| | | const getTitle = computed(() => { |
| | | if (formType.value === 'detail') { |
| | | return 'æ¥ç维修工å'; |
| | | return 'æ¥ç维修订å'; |
| | | } |
| | | if (formType.value === 'confirm') { |
| | | return 'å®æç»´ä¿®'; |
| | |
| | | if (formType.value === 'finish') { |
| | | return 'éªæ¶ç»´ä¿®'; |
| | | } |
| | | return formType.value === 'update' ? 'ä¿®æ¹ç»´ä¿®å·¥å' : 'æ°å¢ç»´ä¿®å·¥å'; |
| | | return formType.value === 'update' ? 'ä¿®æ¹ç»´ä¿®è®¢å' : 'æ°å¢ç»´ä¿®è®¢å'; |
| | | }); |
| | | |
| | | const [Form, formApi] = useVbenForm({ |
| | |
| | | showDefaultActions: false, |
| | | }); |
| | | |
| | | /** æäº¤ç»´ä¿®å·¥å */ |
| | | /** æäº¤ç»´ä¿®è®¢å */ |
| | | async function handleSubmit() { |
| | | const { valid } = await formApi.validate(); |
| | | if (!valid || !formData.value?.id) { |
| | |
| | | await doSubmit(); |
| | | } |
| | | |
| | | /** æ§è¡ç»´ä¿®å·¥åæäº¤ */ |
| | | /** æ§è¡ç»´ä¿®è®¢åæäº¤ */ |
| | | async function doSubmit() { |
| | | modalApi.lock(); |
| | | try { |
| | |
| | | <div class="flex flex-auto items-center gap-2"> |
| | | <Popconfirm |
| | | v-if="canSubmit" |
| | | title="确认æäº¤è¯¥ç»´ä¿®å·¥åï¼æäº¤åå°ä¸è½ä¿®æ¹ã" |
| | | title="确认æäº¤è¯¥ç»´ä¿®è®¢åï¼æäº¤åå°ä¸è½ä¿®æ¹ã" |
| | | @confirm="handleSubmit" |
| | | > |
| | | <Button type="primary">æäº¤</Button> |
| | |
| | | import type { EChartsOption } from '../../../packages/effects/plugins/src/echarts'; |
| | | import type { EChartsOption } from '../../../packages/effects/plugins/src/echarts'; |
| | | |
| | | /** ç产è¶å¿æçº¿å¾é
ç½® */ |
| | | export function getProductionTrendChartOptions( |
| | |
| | | }; |
| | | } |
| | | |
| | | /** å·¥åç¶æåå¸é¥¼å¾é
ç½® */ |
| | | /** 订åç¶æåå¸é¥¼å¾é
ç½® */ |
| | | export function getWorkOrderStatusChartOptions( |
| | | data: Array<{ itemStyle: { color: string }; name: string; value: number }>, |
| | | ): EChartsOption { |
| | |
| | | import type { MesHomeApi } from '#/api/mes/home'; |
| | | import type { MesHomeApi } from '#/api/mes/home'; |
| | | |
| | | import { MesProWorkOrderStatusEnum } from '../../../packages/constants/src'; |
| | | |
| | |
| | | yesterdayOutput: 0, |
| | | }; |
| | | |
| | | /** å·¥åç¶æå¯¹åºçé¢è²æ å° */ |
| | | /** 订åç¶æå¯¹åºçé¢è²æ å° */ |
| | | export const WORK_ORDER_STATUS_COLOR_MAP: Record<number, string> = { |
| | | [MesProWorkOrderStatusEnum.PREPARE]: '#909399', // è稿 |
| | | [MesProWorkOrderStatusEnum.CONFIRMED]: '#409EFF', // 已确认 |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { MesHomeApi } from '#/api/mes/home'; |
| | | |
| | | import { onMounted, ref } from 'vue'; |
| | |
| | | </Col> |
| | | </Row> |
| | | |
| | | <!-- 第ä¸è¡ï¼å·¥ååå¸ + å¿«æ·å
¥å£ --> |
| | | <!-- 第ä¸è¡ï¼è®¢ååå¸ + å¿«æ·å
¥å£ --> |
| | | <Row :gutter="16"> |
| | | <Col :lg="12" :md="24" :sm="24" :xl="12" :xs="24" class="mb-4"> |
| | | <WorkOrderChart /> |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { MesHomeApi } from '#/api/mes/home'; |
| | | |
| | | import { computed } from 'vue'; |
| | |
| | | }, |
| | | { |
| | | count: props.summary.repairActiveCount, |
| | | desc: 'å¾
å¤çç维修工å', |
| | | desc: 'å¾
å¤çç维修订å', |
| | | icon: 'lucide:wrench', |
| | | iconClass: 'bg-orange-50 text-orange-500', |
| | | label: '设å¤ç»´ä¿®', |
| | |
| | | }, |
| | | { |
| | | count: props.summary.workOrderPrepareCount, |
| | | desc: 'èç¨¿ç¶æçç产工å', |
| | | desc: 'èç¨¿ç¶æçç产订å', |
| | | icon: 'lucide:clipboard-list', |
| | | iconClass: 'bg-blue-50 text-blue-500', |
| | | label: 'å¾
æäº§å·¥å', |
| | | label: 'å¾
æäº§è®¢å', |
| | | routeName: 'MesProWorkOrder', |
| | | }, |
| | | ]); |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { MesHomeApi } from '#/api/mes/home'; |
| | | |
| | | import { computed } from 'vue'; |
| | |
| | | <IconifyIcon class="size-7" icon="lucide:file-text" /> |
| | | </div> |
| | | <div> |
| | | <div class="text-muted-foreground mb-1 text-sm">ç产工å</div> |
| | | <div class="text-muted-foreground mb-1 text-sm">ç产订å</div> |
| | | <div class="flex items-baseline gap-1"> |
| | | <CountTo |
| | | class="text-2xl font-bold leading-tight text-[#409eff]" |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import { IconifyIcon } from '../../../../packages/icons/src'; |
| | | |
| | | import { Card, Col, Row } from 'ant-design-vue'; |
| | |
| | | navigate: [name: string]; |
| | | }>(); |
| | | |
| | | /** å¿«æ·å
¥å£å表ï¼3Ã3 ç½æ ¼å¸å±ä¸å·¥åç¶æåå¸é¢æ¿çé« */ |
| | | /** å¿«æ·å
¥å£å表ï¼3Ã3 ç½æ ¼å¸å±ä¸è®¢åç¶æåå¸é¢æ¿çé« */ |
| | | const shortcuts = [ |
| | | { |
| | | bgColor: '#409EFF', |
| | | icon: 'lucide:file-text', |
| | | name: 'ç产工å', |
| | | name: 'ç产订å', |
| | | routeName: 'MesProWorkOrder', |
| | | }, |
| | | { |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { EchartsUIType } from '../../../../packages/effects/plugins/src/echarts'; |
| | | |
| | | import { onMounted, ref } from 'vue'; |
| | |
| | | const chartRef = ref<EchartsUIType>(); |
| | | const { renderEcharts } = useEcharts(chartRef); |
| | | |
| | | /** å 载工åç¶æå叿°æ®å¹¶æ¸²æé¥¼å¾ */ |
| | | /** å 载订åç¶æå叿°æ®å¹¶æ¸²æé¥¼å¾ */ |
| | | async function loadData() { |
| | | const data = await getWorkOrderStatusDistribution(); |
| | | const chartData = data.map((d) => ({ |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <Card title="å·¥åç¶æåå¸" class="h-full"> |
| | | <Card title="订åç¶æåå¸" class="h-full"> |
| | | <EchartsUI ref="chartRef" class="h-[280px] w-full" /> |
| | | </Card> |
| | | </template> |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { FormType } from '../data'; |
| | | |
| | | import type { MesMdItemBatchConfigApi } from '#/api/mes/md/item/batchConfig'; |
| | |
| | | v-model:checked="formData.workorderFlag" |
| | | :disabled="isReadOnly" |
| | | > |
| | | ç产工å |
| | | ç产订å |
| | | </Checkbox> |
| | | <Checkbox v-model:checked="formData.taskFlag" :disabled="isReadOnly"> |
| | | çäº§ä»»å¡ |
| | |
| | | import type { VbenFormSchema } from "#/adapter/form"; |
| | | import type { VxeTableGridOptions } from "#/adapter/vxe-table"; |
| | | import type { VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | |
| | | import { DICT_TYPE } from "#/packages/constants/src"; |
| | | import { getDictOptions } from "#/packages/effects/hooks/src"; |
| | | import { DICT_TYPE } from '#/packages/constants/src'; |
| | | import { getDictOptions } from '#/packages/effects/hooks/src'; |
| | | |
| | | export function useGridFormSchema(): VbenFormSchema[] { |
| | | return [ |
| | | { |
| | | fieldName: "code", |
| | | label: "彿¡£ç¼å·", |
| | | component: "Input", |
| | | componentProps: { placeholder: "请è¾å
¥å½æ¡£ç¼å·" }, |
| | | fieldName: 'archiveCode', |
| | | label: '彿¡£ç¼å·', |
| | | component: 'Input', |
| | | componentProps: { placeholder: '请è¾å
¥å½æ¡£ç¼å·' }, |
| | | }, |
| | | { |
| | | fieldName: "projectCode", |
| | | label: "ä»»å¡ç¼ç ", |
| | | component: "Input", |
| | | componentProps: { placeholder: "请è¾å
¥ä»»å¡ç¼ç " }, |
| | | fieldName: 'productCode', |
| | | label: '产åç¼ç ', |
| | | component: 'Input', |
| | | componentProps: { placeholder: '请è¾å
¥äº§åç¼ç ' }, |
| | | }, |
| | | { |
| | | fieldName: "productCode", |
| | | label: "产åç¼ç ", |
| | | component: "Input", |
| | | componentProps: { placeholder: "请è¾å
¥äº§åç¼ç " }, |
| | | fieldName: 'productName', |
| | | label: '产ååç§°', |
| | | component: 'Input', |
| | | componentProps: { placeholder: '请è¾å
¥äº§ååç§°' }, |
| | | }, |
| | | { |
| | | fieldName: "archiveStatus", |
| | | label: "彿¡£ç¶æ", |
| | | component: "Select", |
| | | fieldName: 'archiveStatus', |
| | | label: '彿¡£ç¶æ', |
| | | component: 'Select', |
| | | componentProps: { |
| | | allowClear: true, |
| | | options: getDictOptions(DICT_TYPE.MES_PD_ARCHIVE_STATUS, "number"), |
| | | placeholder: "è¯·éæ©å½æ¡£ç¶æ", |
| | | options: getDictOptions(DICT_TYPE.MES_PD_ARCHIVE_STATUS, 'number'), |
| | | placeholder: 'è¯·éæ©å½æ¡£ç¶æ', |
| | | }, |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | export function useGridColumns(): VxeTableGridOptions["columns"] { |
| | | export function useGridColumns(): VxeTableGridOptions['columns'] { |
| | | return [ |
| | | { |
| | | field: "code", |
| | | title: "彿¡£ç¼å·", |
| | | field: 'archiveCode', |
| | | title: '彿¡£ç¼å·', |
| | | minWidth: 130, |
| | | slots: { default: "code" }, |
| | | slots: { default: 'archiveCode' }, |
| | | }, |
| | | { field: "projectCode", title: "ä»»å¡ç¼ç ", minWidth: 120 }, |
| | | { field: "projectName", title: "ä»»å¡åç§°", minWidth: 140 }, |
| | | { field: "productCode", title: "产åç¼ç ", minWidth: 120 }, |
| | | { field: "productName", title: "产ååç§°", minWidth: 140 }, |
| | | { field: "version", title: "çæ¬å·", minWidth: 90 }, |
| | | { field: 'productCode', title: '产åç¼ç ', minWidth: 120 }, |
| | | { field: 'productName', title: '产ååç§°', minWidth: 140 }, |
| | | { field: 'taskCode', title: 'ä»»å¡ç¼ç ', minWidth: 130 }, |
| | | { field: 'taskName', title: 'ä»»å¡åç§°', minWidth: 160 }, |
| | | { field: 'archiveCount', title: '彿¡£æ°é', minWidth: 90 }, |
| | | { |
| | | field: "archiveStatus", |
| | | title: "彿¡£ç¶æ", |
| | | field: 'archiveStatus', |
| | | title: '彿¡£ç¶æ', |
| | | minWidth: 100, |
| | | cellRender: { |
| | | name: "CellDict", |
| | | name: 'CellDict', |
| | | props: { type: DICT_TYPE.MES_PD_ARCHIVE_STATUS }, |
| | | }, |
| | | }, |
| | | { field: "documentCount", title: "èµææ°", minWidth: 80 }, |
| | | { field: "archiverName", title: "彿¡£äºº", minWidth: 100 }, |
| | | { field: 'archiverNickname', title: '彿¡£äºº', minWidth: 100 }, |
| | | { |
| | | field: "archiveTime", |
| | | title: "彿¡£æ¶é´", |
| | | field: 'archiveTime', |
| | | title: '彿¡£æ¶é´', |
| | | minWidth: 160, |
| | | formatter: "formatDateTime", |
| | | formatter: 'formatDateTime', |
| | | }, |
| | | { field: 'updaterNickname', title: 'æ´æ°äºº', minWidth: 100 }, |
| | | { |
| | | field: 'updateTime', |
| | | title: 'æ´æ°æ¶é´', |
| | | minWidth: 160, |
| | | formatter: 'formatDateTime', |
| | | }, |
| | | |
| | | |
| | | ]; |
| | | } |
| | |
| | | const detailRef = ref<InstanceType<typeof Detail>>(); |
| | | |
| | | function handleDetail(row: MesPdArchiveApi.Archive) { |
| | | detailRef.value?.open(row.id!); |
| | | detailRef.value?.open(row.productCode!); |
| | | } |
| | | |
| | | async function handleExport() { |
| | | const data = await exportPdArchive(await gridApi.formApi.getValues()); |
| | | downloadFileFromBlobPart({ fileName: 'è®¾è®¡å½æ¡£å°è´¦.xls', source: data }); |
| | | downloadFileFromBlobPart({ fileName: '彿¡£å°è´¦.xls', source: data }); |
| | | } |
| | | |
| | | const [Grid, gridApi] = useVbenVxeGrid({ |
| | |
| | | <Page auto-content-height> |
| | | <Detail ref="detailRef" /> |
| | | |
| | | <Grid table-title="产åçæ¬å½æ¡£å°è´¦"> |
| | | <Grid table-title="彿¡£å°è´¦"> |
| | | <template #toolbar-tools> |
| | | <TableAction |
| | | :actions="[ |
| | |
| | | ]" |
| | | /> |
| | | </template> |
| | | <template #code="{ row }"> |
| | | <Button type="link" @click="handleDetail(row)">{{ row.code }}</Button> |
| | | <template #archiveCode="{ row }"> |
| | | <Button type="link" @click="handleDetail(row)">{{ row.archiveCode }}</Button> |
| | | </template> |
| | | </Grid> |
| | | </Page> |
| | |
| | | <script lang="ts" setup> |
| | | import type { MesPdArchiveApi } from '#/api/mes/pd/archive'; |
| | | import type { MesPdVersionChangeApi } from '#/api/mes/pd/version-change'; |
| | | |
| | | import { ref } from 'vue'; |
| | | |
| | | import { useVbenModal } from '#/packages/effects/common-ui/src'; |
| | | import { DICT_TYPE } from '#/packages/constants/src'; |
| | | |
| | | import { Alert, Descriptions, Tabs } from 'ant-design-vue'; |
| | | import { Descriptions, Table, Tabs } from 'ant-design-vue'; |
| | | |
| | | import { getPdArchive } from '#/api/mes/pd/archive'; |
| | | import { getPdArchiveDetailByProduct } from '#/api/mes/pd/archive'; |
| | | |
| | | import MaterialPanel from '#/views/mes/pd/project/modules/material-panel.vue'; |
| | | import VersionChangeList from '#/views/mes/pd/project/modules/version-change/version-change-list.vue'; |
| | | const loading = ref(false); |
| | | const detailList = ref<MesPdArchiveApi.DetailItem[]>([]); |
| | | const activeProject = ref('0'); |
| | | |
| | | const detail = ref<MesPdArchiveApi.Archive>(); |
| | | const activeTab = ref('version-change'); |
| | | const materialVersion = ref<string>(); |
| | | const materialVersionHint = ref<string>(); |
| | | const archiveColumns = [ |
| | | { title: '彿¡£ç¼å·', dataIndex: 'archiveCode', key: 'archiveCode' }, |
| | | { title: '彿¡£äºº', dataIndex: 'archiverNickname', key: 'archiverNickname' }, |
| | | { title: '彿¡£ç¶æ', dataIndex: 'archiveStatus', key: 'archiveStatus' }, |
| | | { title: '彿¡£æ¶é´', dataIndex: 'archiveTime', key: 'archiveTime' }, |
| | | { title: '夿³¨', dataIndex: 'remark', key: 'remark', ellipsis: true }, |
| | | ]; |
| | | |
| | | function handleViewMaterials(row: MesPdVersionChangeApi.VersionChange) { |
| | | materialVersion.value = row.toVersion; |
| | | materialVersionHint.value = `åæ´å ${row.code}ï¼${row.fromVersion} â ${row.toVersion}`; |
| | | activeTab.value = 'material'; |
| | | } |
| | | |
| | | function clearMaterialVersionFilter() { |
| | | materialVersion.value = detail.value?.version; |
| | | materialVersionHint.value = undefined; |
| | | } |
| | | const documentColumns = [ |
| | | { title: 'èµæåç§°', dataIndex: 'documentName', key: 'documentName' }, |
| | | { title: 'èµæç±»å', dataIndex: 'documentType', key: 'documentType' }, |
| | | { title: 'çæ¬', dataIndex: 'documentVersion', key: 'documentVersion', width: 80 }, |
| | | { title: 'æä»¶å', dataIndex: 'fileName', key: 'fileName' }, |
| | | { title: 'ä¸ä¼ 人', dataIndex: 'uploadUserNickname', key: 'uploadUserNickname' }, |
| | | { title: 'ä¸ä¼ æ¶é´', dataIndex: 'uploadTime', key: 'uploadTime' }, |
| | | { |
| | | title: 'æä½', |
| | | key: 'action', |
| | | width: 80, |
| | | }, |
| | | ]; |
| | | |
| | | const [Modal, modalApi] = useVbenModal({ |
| | | async onOpenChange(isOpen: boolean) { |
| | | if (!isOpen) { |
| | | detail.value = undefined; |
| | | activeTab.value = 'version-change'; |
| | | materialVersion.value = undefined; |
| | | materialVersionHint.value = undefined; |
| | | detailList.value = []; |
| | | activeProject.value = '0'; |
| | | return; |
| | | } |
| | | const data = modalApi.getData<{ id: number }>(); |
| | | modalApi.lock(); |
| | | const data = modalApi.getData<{ productCode: number }>(); |
| | | loading.value = true; |
| | | try { |
| | | detail.value = await getPdArchive(data.id); |
| | | materialVersion.value = detail.value.version; |
| | | detailList.value = await getPdArchiveDetailByProduct(data.productCode); |
| | | activeProject.value = '0'; |
| | | } finally { |
| | | modalApi.unlock(); |
| | | loading.value = false; |
| | | } |
| | | }, |
| | | }); |
| | | |
| | | defineExpose({ |
| | | open: (id: number) => modalApi.setData({ id }).open(), |
| | | open: (productCode: number) => modalApi.setData({ productCode }).open(), |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <Modal class="w-4/5" title="彿¡£è¯¦æ
"> |
| | | <Descriptions v-if="detail" :column="3" bordered class="mx-4 mb-4" size="small"> |
| | | <Descriptions.Item label="彿¡£ç¼å·">{{ detail.code }}</Descriptions.Item> |
| | | <Descriptions.Item label="产åç¼ç ">{{ detail.productCode }}</Descriptions.Item> |
| | | <Descriptions.Item label="产ååç§°">{{ detail.productName }}</Descriptions.Item> |
| | | <Descriptions.Item label="è®¾è®¡çæ¬">{{ detail.version }}</Descriptions.Item> |
| | | <Descriptions.Item label="ä»»å¡ç¼ç ">{{ detail.projectCode }}</Descriptions.Item> |
| | | <Descriptions.Item label="ä»»å¡åç§°">{{ detail.projectName }}</Descriptions.Item> |
| | | <Descriptions.Item label="èµææ°">{{ detail.documentCount ?? '-' }}</Descriptions.Item> |
| | | <Descriptions.Item label="彿¡£äºº">{{ detail.archiverName || '-' }}</Descriptions.Item> |
| | | <Descriptions.Item label="彿¡£è·¯å¾" :span="3"> |
| | | {{ detail.storagePath || '-' }} |
| | | </Descriptions.Item> |
| | | <Descriptions.Item label="夿³¨" :span="3">{{ detail.remark || '-' }}</Descriptions.Item> |
| | | <Modal class="w-4/5" title="彿¡£è¯¦æ
" :loading="loading"> |
| | | <Tabs v-if="detailList.length > 0" v-model:active-key="activeProject" type="card"> |
| | | <Tabs.TabPane |
| | | v-for="(detail, index) in detailList" |
| | | :key="String(index)" |
| | | :tab="detail.project.taskName || '项ç®'" |
| | | > |
| | | <!-- 项ç®ä¿¡æ¯ --> |
| | | <Descriptions :column="3" bordered size="small" class="mb-4"> |
| | | <Descriptions.Item label="ä»»å¡ç¼ç ">{{ detail.project.taskCode }}</Descriptions.Item> |
| | | <Descriptions.Item label="ä»»å¡åç§°">{{ detail.project.taskName }}</Descriptions.Item> |
| | | <Descriptions.Item label="产åç¼ç ">{{ detail.project.productCode }}</Descriptions.Item> |
| | | <Descriptions.Item label="产ååç§°">{{ detail.project.productName }}</Descriptions.Item> |
| | | <Descriptions.Item label="çæ¬å·">{{ detail.project.version }}</Descriptions.Item> |
| | | <Descriptions.Item label="主设计å¸">{{ detail.project.chiefDesignerNickname }}</Descriptions.Item> |
| | | <Descriptions.Item label="å®¡æ ¸äºº">{{ detail.project.reviewerNickname }}</Descriptions.Item> |
| | | <Descriptions.Item label="计å宿">{{ detail.project.planFinishTime }}</Descriptions.Item> |
| | | </Descriptions> |
| | | |
| | | <template v-if="detail?.projectId"> |
| | | <Tabs v-model:active-key="activeTab" class="mx-4"> |
| | | <Tabs.TabPane key="version-change" tab="çæ¬åæ´è®°å½"> |
| | | <VersionChangeList |
| | | form-type="detail" |
| | | :project-id="detail.projectId" |
| | | :project-version="detail.version" |
| | | @view-materials="handleViewMaterials" |
| | | <!-- 彿¡£è®°å½ --> |
| | | <div class="mb-4"> |
| | | <h4 class="mb-2 text-sm font-medium">彿¡£è®°å½</h4> |
| | | <Table |
| | | :columns="archiveColumns" |
| | | :data-source="detail.archives" |
| | | :pagination="false" |
| | | bordered |
| | | row-key="id" |
| | | size="small" |
| | | /> |
| | | </Tabs.TabPane> |
| | | <Tabs.TabPane key="material" tab="çæ¬èµæ"> |
| | | <Alert |
| | | v-if="materialVersionHint" |
| | | class="mb-3" |
| | | closable |
| | | show-icon |
| | | type="info" |
| | | :message="`æ£å¨æ¥ç ${materialVersion} çæ¬èµæï¼${materialVersionHint}ï¼`" |
| | | @close="clearMaterialVersionFilter" |
| | | /> |
| | | <MaterialPanel |
| | | form-type="detail" |
| | | :project-id="detail.projectId" |
| | | table-title="çæ¬èµæ" |
| | | :version="materialVersion" |
| | | /> |
| | | </div> |
| | | |
| | | <!-- è®¾è®¡èµæ --> |
| | | <div> |
| | | <h4 class="mb-2 text-sm font-medium">è®¾è®¡èµæ</h4> |
| | | <Table |
| | | :columns="documentColumns" |
| | | :data-source="detail.documents" |
| | | :pagination="false" |
| | | bordered |
| | | row-key="id" |
| | | size="small" |
| | | > |
| | | <template #bodyCell="{ column, record }"> |
| | | <template v-if="column.key === 'action'"> |
| | | <a v-if="record.fileUrl" :href="record.fileUrl" target="_blank" class="text-primary">ä¸è½½</a> |
| | | <span v-else class="text-gray-400">-</span> |
| | | </template> |
| | | </template> |
| | | </Table> |
| | | </div> |
| | | </Tabs.TabPane> |
| | | </Tabs> |
| | | </template> |
| | | <div v-else class="py-8 text-center text-gray-400"> |
| | | ææ å½æ¡£è®°å½ |
| | | </div> |
| | | </Modal> |
| | | </template> |
| | |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesMdItemApi } from '#/api/mes/md/item'; |
| | | import type { MesPdProjectApi } from '#/api/mes/pd/project'; |
| | | import type { ExtendedFormApi, VbenFormSchema } from "#/adapter/form"; |
| | | import type { VxeTableGridOptions } from "#/adapter/vxe-table"; |
| | | import type { MesMdItemApi } from "#/api/mes/md/item"; |
| | | import type { MesPdProjectApi } from "#/api/mes/pd/project"; |
| | | |
| | | import { h, markRaw } from 'vue'; |
| | | import { h, markRaw } from "vue"; |
| | | |
| | | import { |
| | | DICT_TYPE, |
| | | MesAutoCodeRuleCode, |
| | | MesPdDocumentTypeEnum, |
| | | } from '#/packages/constants/src'; |
| | | import { getDictOptions } from '#/packages/effects/hooks/src'; |
| | | } from "#/packages/constants/src"; |
| | | import { getDictOptions } from "#/packages/effects/hooks/src"; |
| | | |
| | | import { Button } from 'ant-design-vue'; |
| | | import { Button } from "ant-design-vue"; |
| | | |
| | | import { generateAutoCode } from '#/api/mes/md/autocode/record'; |
| | | import { isPdMockEnabled } from '#/api/mes/pd/mock/enabled'; |
| | | import { mockNextCode } from '#/api/mes/pd/mock/utils'; |
| | | import { getRangePickerDefaultProps } from '#/utils'; |
| | | import { MdItemSelect } from '#/views/mes/md/item/components'; |
| | | import { generateAutoCode } from "#/api/mes/md/autocode/record"; |
| | | |
| | | export type FormType = 'create' | 'detail' | 'update'; |
| | | import { MdItemSelect } from "#/views/mes/md/item/components"; |
| | | import PdUserSelect from "../project/modules/user-select.vue"; |
| | | |
| | | async function generateTaskCode(formApi?: VbenFormApi) { |
| | | const code = isPdMockEnabled() |
| | | ? mockNextCode('DT-2026', Math.floor(Date.now() % 10_000)) |
| | | : await generateAutoCode(MesAutoCodeRuleCode.PD_PROJECT_CODE); |
| | | await formApi?.setFieldValue('code', code); |
| | | export type FormType = "create" | "detail" | "update"; |
| | | |
| | | /** å¼¹çªå
DatePickerï¼æè½½å° dialog å
ï¼é¿å
focus-outside æ¦æªæ¥åç¹å» */ |
| | | function useModalDatePickerProps(options?: { |
| | | disabled?: boolean; |
| | | placeholder?: string; |
| | | }) { |
| | | return { |
| | | allowClear: true, |
| | | class: "!w-full", |
| | | disabled: options?.disabled, |
| | | format: "YYYY-MM-DD", |
| | | getPopupContainer: (node: HTMLElement) => |
| | | (node.closest('[data-slot="dialog-content"]') as HTMLElement) ?? |
| | | document.body, |
| | | inputReadOnly: true, |
| | | placeholder: options?.placeholder ?? "è¯·éæ©æ¥æ", |
| | | valueFormat: "x", |
| | | }; |
| | | } |
| | | |
| | | async function generateTaskCode(formApi?: ExtendedFormApi) { |
| | | const code = await generateAutoCode(MesAutoCodeRuleCode.PD_PROJECT_CODE); |
| | | await formApi?.setFieldValue("taskCode", code); |
| | | } |
| | | |
| | | async function syncTaskNameFromProduct( |
| | | formApi: VbenFormApi | undefined, |
| | | productName?: string, |
| | | formApi: ExtendedFormApi | undefined, |
| | | productName?: string |
| | | ) { |
| | | const version = (await formApi?.getFieldValue('version')) as |
| | | | string |
| | | | undefined; |
| | | const values = await formApi?.getValues(); |
| | | const version = values?.version as string | undefined; |
| | | const name = productName?.trim(); |
| | | if (name && version?.trim()) { |
| | | await formApi?.setFieldValue('name', `${name} ${version.trim()} 设计`); |
| | | await formApi?.setFieldValue("taskName", `${name} ${version.trim()} 设计`); |
| | | } |
| | | } |
| | | |
| | | /** 产åéæ©ï¼éæ©åèªå¨å¸¦åºäº§åç¼ç */ |
| | | function useProductSelectSchema( |
| | | formApi: VbenFormApi | undefined, |
| | | readonly: boolean, |
| | | formApi: ExtendedFormApi | undefined, |
| | | readonly: boolean |
| | | ): VbenFormSchema[] { |
| | | if (readonly) { |
| | | return [ |
| | | { |
| | | fieldName: 'productCode', |
| | | label: '产åç¼ç ', |
| | | component: 'Input', |
| | | fieldName: "productCode", |
| | | label: "产åç¼ç ", |
| | | component: "Input", |
| | | componentProps: { disabled: true }, |
| | | }, |
| | | { |
| | | fieldName: 'productName', |
| | | label: '产ååç§°', |
| | | component: 'Input', |
| | | fieldName: "productName", |
| | | label: "产ååç§°", |
| | | component: "Input", |
| | | componentProps: { disabled: true }, |
| | | }, |
| | | ]; |
| | | } |
| | | return [ |
| | | { |
| | | fieldName: 'productId', |
| | | label: '产å', |
| | | fieldName: "productId", |
| | | label: "产å", |
| | | component: markRaw(MdItemSelect), |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©äº§å', |
| | | placeholder: "è¯·éæ©äº§å", |
| | | onChange: async (item: MesMdItemApi.Item | undefined) => { |
| | | await formApi?.setFieldValue('productCode', item?.code ?? ''); |
| | | await formApi?.setFieldValue('productName', item?.name ?? ''); |
| | | await formApi?.setFieldValue("productCode", item?.code ?? ""); |
| | | await formApi?.setFieldValue("productName", item?.name ?? ""); |
| | | await syncTaskNameFromProduct(formApi, item?.name); |
| | | }, |
| | | }, |
| | | rules: 'selectRequired', |
| | | rules: "selectRequired", |
| | | }, |
| | | { |
| | | fieldName: 'productCode', |
| | | label: '产åç¼ç ', |
| | | component: 'Input', |
| | | fieldName: "productCode", |
| | | label: "产åç¼ç ", |
| | | component: "Input", |
| | | componentProps: { |
| | | disabled: true, |
| | | placeholder: 'éæ©äº§ååèªå¨å¸¦åº', |
| | | placeholder: "éæ©äº§ååèªå¨å¸¦åº", |
| | | }, |
| | | rules: 'required', |
| | | rules: "required", |
| | | }, |
| | | { |
| | | fieldName: 'productName', |
| | | component: 'Input', |
| | | dependencies: { triggerFields: [''], show: () => false }, |
| | | fieldName: "productName", |
| | | component: "Input", |
| | | dependencies: { triggerFields: [""], show: () => false }, |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | /** å起设计任å¡è¡¨å */ |
| | | export function useCreateTaskSchema(formApi?: VbenFormApi): VbenFormSchema[] { |
| | | /** åèµ·è®¾è®¡ä»»å¡ / å建表å */ |
| | | export function useCreateFormSchema( |
| | | formApi?: ExtendedFormApi |
| | | ): VbenFormSchema[] { |
| | | return [ |
| | | { |
| | | fieldName: 'id', |
| | | component: 'Input', |
| | | dependencies: { triggerFields: [''], show: () => false }, |
| | | fieldName: "id", |
| | | component: "Input", |
| | | dependencies: { triggerFields: [""], show: () => false }, |
| | | }, |
| | | { |
| | | fieldName: 'code', |
| | | label: 'ä»»å¡ç¼ç ', |
| | | component: 'Input', |
| | | componentProps: { placeholder: '请ç¹å»çæä»»å¡ç¼ç ' }, |
| | | rules: 'required', |
| | | fieldName: "taskCode", |
| | | label: "ä»»å¡ç¼ç ", |
| | | component: "Input", |
| | | componentProps: { placeholder: "请ç¹å»çæä»»å¡ç¼ç " }, |
| | | rules: "required", |
| | | suffix: () => |
| | | h( |
| | | Button, |
| | | { type: 'default', onClick: () => generateTaskCode(formApi) }, |
| | | { default: () => 'çæ' }, |
| | | { type: "default", onClick: () => generateTaskCode(formApi) }, |
| | | { default: () => "çæ" } |
| | | ), |
| | | }, |
| | | ...useProductSelectSchema(formApi, false), |
| | | { |
| | | fieldName: 'version', |
| | | label: 'è®¾è®¡çæ¬', |
| | | component: 'Input', |
| | | componentProps: { placeholder: 'å¦ V1.0ãV2.1' }, |
| | | rules: 'required', |
| | | fieldName: "version", |
| | | label: "çæ¬å·", |
| | | component: "Input", |
| | | componentProps: { placeholder: "å¦ V1.0ãV2.1" }, |
| | | rules: "required", |
| | | }, |
| | | { |
| | | fieldName: 'name', |
| | | label: 'ä»»å¡åç§°', |
| | | component: 'Input', |
| | | componentProps: { placeholder: 'å°æ ¹æ®äº§åä¸çæ¬èªå¨çæï¼å¯ä¿®æ¹' }, |
| | | rules: 'required', |
| | | fieldName: "taskName", |
| | | label: "ä»»å¡åç§°", |
| | | component: "Input", |
| | | componentProps: { placeholder: "å°æ ¹æ®äº§åä¸çæ¬èªå¨çæï¼å¯ä¿®æ¹" }, |
| | | rules: "required", |
| | | dependencies: { |
| | | triggerFields: ['productName', 'version'], |
| | | triggerFields: ["productName", "version"], |
| | | trigger(values: Record<string, string>, form) { |
| | | const productName = values.productName?.trim(); |
| | | const version = values.version?.trim(); |
| | | if (productName && version) { |
| | | form.setFieldValue('name', `${productName} ${version} 设计`); |
| | | form.setFieldValue("taskName", `${productName} ${version} 设计`); |
| | | } |
| | | }, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'designerName', |
| | | label: '主设计å¸', |
| | | component: 'Input', |
| | | componentProps: { placeholder: '请è¾å
¥ä¸»è®¾è®¡å¸' }, |
| | | rules: 'required', |
| | | fieldName: "chiefDesigner", |
| | | label: "主设计å¸", |
| | | component: markRaw(PdUserSelect), |
| | | componentProps: { placeholder: "è¯·éæ©ä¸»è®¾è®¡å¸" }, |
| | | rules: "selectRequired", |
| | | }, |
| | | { |
| | | fieldName: 'reviewerName', |
| | | label: 'å®¡æ ¸äºº', |
| | | component: 'Input', |
| | | componentProps: { placeholder: 'èµæå®¡æ ¸è´è´£äºº' }, |
| | | rules: 'required', |
| | | fieldName: "reviewer", |
| | | label: "å®¡æ ¸äºº", |
| | | component: markRaw(PdUserSelect), |
| | | componentProps: { placeholder: "è¯·éæ©å®¡æ ¸äºº" }, |
| | | rules: "selectRequired", |
| | | }, |
| | | { |
| | | fieldName: 'planDateRange', |
| | | label: '计å卿', |
| | | component: 'RangePicker', |
| | | componentProps: getRangePickerDefaultProps(), |
| | | rules: 'required', |
| | | fieldName: "planFinishTime", |
| | | label: "计å宿æ¶é´", |
| | | component: "DatePicker", |
| | | componentProps: useModalDatePickerProps({ |
| | | placeholder: "è¯·éæ©è®¡å宿æ¶é´", |
| | | }), |
| | | }, |
| | | { |
| | | fieldName: 'remark', |
| | | label: 'ä»»å¡è¯´æ', |
| | | component: 'Textarea', |
| | | fieldName: "remark", |
| | | label: "夿³¨", |
| | | component: "Textarea", |
| | | componentProps: { |
| | | placeholder: 'ç®è¿°æ¬æ¬¡è®¾è®¡ç®æ ãåæ´èæ¯ç', |
| | | placeholder: "ç®è¿°æ¬æ¬¡è®¾è®¡ç®æ ãåæ´èæ¯ç", |
| | | rows: 3, |
| | | }, |
| | | formItemClass: 'col-span-2', |
| | | formItemClass: "col-span-2", |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | /** åå¸ä»»å¡ç¡®è®¤è¡¨å */ |
| | | export function usePublishFormSchema(): VbenFormSchema[] { |
| | | return [ |
| | | { |
| | | fieldName: 'publishRemark', |
| | | label: 'åå¸è¯´æ', |
| | | component: 'Textarea', |
| | | componentProps: { |
| | | placeholder: 'å¯éï¼å¡«ååå¸è¦æ±ææ³¨æäºé¡¹', |
| | | rows: 3, |
| | | }, |
| | | formItemClass: 'col-span-2', |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | export type WorkflowActionType = 'approve' | 'archive' | 'submit-review'; |
| | | |
| | | export interface WorkflowActionConfig { |
| | | title: string; |
| | | alertMessage: string; |
| | | alertDescription: string; |
| | | remarkLabel: string; |
| | | remarkTag: string; |
| | | remarkPlaceholder: string; |
| | | successMessage: string; |
| | | alertType: 'info' | 'success' | 'warning'; |
| | | } |
| | | |
| | | export const WORKFLOW_ACTION_CONFIG: Record< |
| | | WorkflowActionType, |
| | | WorkflowActionConfig |
| | | > = { |
| | | 'submit-review': { |
| | | title: 'æäº¤èµæå®¡æ ¸', |
| | | alertMessage: '确认æäº¤å®¡æ ¸', |
| | | alertDescription: |
| | | 'æäº¤åå°è¿å
¥èµæå®¡æ ¸ç¯èï¼è¯·ç¡®è®¤è®¾è®¡èµæå·²ä¸ä¼ 宿´ãæäº¤å设计å¸å°æ æ³ç»§ç»ä¿®æ¹èµæã', |
| | | remarkLabel: 'æäº¤è¯´æ', |
| | | remarkTag: 'ãæäº¤è¯´æã', |
| | | remarkPlaceholder: 'å¯éï¼å¡«åæäº¤å®¡æ ¸çè¡¥å
说æ', |
| | | successMessage: 'å·²æäº¤èµæå®¡æ ¸', |
| | | alertType: 'info', |
| | | }, |
| | | approve: { |
| | | title: 'å®¡æ ¸éè¿', |
| | | alertMessage: 'ç¡®è®¤å®¡æ ¸éè¿', |
| | | alertDescription: |
| | | 'å®¡æ ¸éè¿åä»»å¡è¿å
¥ãå·²éè¿ãç¶æï¼å¯è¿è¡å½æ¡£æä½ãè¯·ç¡®è®¤è®¾è®¡èµæç¬¦åè¦æ±ã', |
| | | remarkLabel: 'å®¡æ ¸æè§', |
| | | remarkTag: 'ãå®¡æ ¸æè§ã', |
| | | remarkPlaceholder: 'å¯éï¼å¡«åå®¡æ ¸éè¿æè§', |
| | | successMessage: 'èµæå®¡æ ¸éè¿', |
| | | alertType: 'success', |
| | | }, |
| | | archive: { |
| | | title: '彿¡£è®¾è®¡ä»»å¡', |
| | | alertMessage: 'ç¡®è®¤å½æ¡£', |
| | | alertDescription: |
| | | '彿¡£åå°çææ¬çæ¬å½æ¡£å°è´¦è®°å½ï¼ä»»å¡ç¶æåä¸ºå·²å½æ¡£ï¼è®¾è®¡èµæå°éå®ä¸å¯ä¿®æ¹ã', |
| | | remarkLabel: '彿¡£è¯´æ', |
| | | remarkTag: 'ã彿¡£è¯´æã', |
| | | remarkPlaceholder: 'å¯éï¼å¡«å彿¡£å¤æ³¨', |
| | | successMessage: 'ä»»å¡å·²å½æ¡£', |
| | | alertType: 'warning', |
| | | }, |
| | | }; |
| | | |
| | | /** æµç¨æä½ç¡®è®¤è¡¨å */ |
| | | export function useWorkflowActionFormSchema( |
| | | action: WorkflowActionType, |
| | | ): VbenFormSchema[] { |
| | | const config = WORKFLOW_ACTION_CONFIG[action]; |
| | | return [ |
| | | { |
| | | fieldName: 'actionRemark', |
| | | label: config.remarkLabel, |
| | | component: 'Textarea', |
| | | componentProps: { |
| | | placeholder: config.remarkPlaceholder, |
| | | rows: 3, |
| | | }, |
| | | formItemClass: 'col-span-2', |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | /** ç½æ ¼æç´¢è¡¨å */ |
| | | export function useGridFormSchema(): VbenFormSchema[] { |
| | | return [ |
| | | { |
| | | fieldName: 'code', |
| | | label: 'ä»»å¡ç¼ç ', |
| | | component: 'Input', |
| | | componentProps: { placeholder: '请è¾å
¥ä»»å¡ç¼ç ' }, |
| | | fieldName: "taskCode", |
| | | label: "ä»»å¡ç¼ç ", |
| | | component: "Input", |
| | | componentProps: { placeholder: "请è¾å
¥ä»»å¡ç¼ç " }, |
| | | }, |
| | | { |
| | | fieldName: 'name', |
| | | label: 'ä»»å¡åç§°', |
| | | component: 'Input', |
| | | componentProps: { placeholder: '请è¾å
¥ä»»å¡åç§°' }, |
| | | fieldName: "taskName", |
| | | label: "ä»»å¡åç§°", |
| | | component: "Input", |
| | | componentProps: { placeholder: "请è¾å
¥ä»»å¡åç§°" }, |
| | | }, |
| | | { |
| | | fieldName: 'productCode', |
| | | label: '产åç¼ç ', |
| | | component: 'Input', |
| | | componentProps: { placeholder: '请è¾å
¥äº§åç¼ç ' }, |
| | | fieldName: "productCode", |
| | | label: "产åç¼ç ", |
| | | component: "Input", |
| | | componentProps: { placeholder: "请è¾å
¥äº§åç¼ç " }, |
| | | }, |
| | | { |
| | | fieldName: 'status', |
| | | label: 'ä»»å¡ç¶æ', |
| | | component: 'Select', |
| | | fieldName: "productName", |
| | | label: "产ååç§°", |
| | | component: "Input", |
| | | componentProps: { placeholder: "请è¾å
¥äº§ååç§°" }, |
| | | }, |
| | | { |
| | | fieldName: "status", |
| | | label: "ä»»å¡ç¶æ", |
| | | component: "Select", |
| | | componentProps: { |
| | | allowClear: true, |
| | | options: getDictOptions(DICT_TYPE.MES_PD_PROJECT_STATUS, 'number'), |
| | | placeholder: 'è¯·éæ©é¡¹ç®ç¶æ', |
| | | options: getDictOptions(DICT_TYPE.MES_PD_PROJECT_STATUS, "number"), |
| | | placeholder: "è¯·éæ©é¡¹ç®ç¶æ", |
| | | }, |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | export function useGridColumns(): VxeTableGridOptions['columns'] { |
| | | /** ç½æ ¼åå®ä¹ */ |
| | | export function useGridColumns(): VxeTableGridOptions["columns"] { |
| | | return [ |
| | | { field: 'code', title: 'ä»»å¡ç¼ç ', minWidth: 140, slots: { default: 'code' } }, |
| | | { field: 'name', title: 'ä»»å¡åç§°', minWidth: 160 }, |
| | | { field: 'productCode', title: '产åç¼ç ', minWidth: 120 }, |
| | | { field: 'productName', title: '产ååç§°', minWidth: 140 }, |
| | | { field: 'version', title: 'çæ¬å·', minWidth: 90 }, |
| | | { |
| | | field: 'status', |
| | | title: 'ç¶æ', |
| | | field: "taskCode", |
| | | title: "ä»»å¡ç¼ç ", |
| | | minWidth: 140, |
| | | slots: { default: "taskCode" }, |
| | | }, |
| | | { field: "taskName", title: "ä»»å¡åç§°", minWidth: 160 }, |
| | | { field: "productCode", title: "产åç¼ç ", minWidth: 120 }, |
| | | { field: "productName", title: "产ååç§°", minWidth: 140 }, |
| | | { field: "version", title: "çæ¬å·", minWidth: 90 }, |
| | | { |
| | | field: "status", |
| | | title: "ç¶æ", |
| | | minWidth: 100, |
| | | cellRender: { |
| | | name: 'CellDict', |
| | | name: "CellDict", |
| | | props: { type: DICT_TYPE.MES_PD_PROJECT_STATUS }, |
| | | }, |
| | | }, |
| | | { field: 'designerName', title: '主设计å¸', minWidth: 100 }, |
| | | { field: 'reviewerName', title: 'å®¡æ ¸äºº', minWidth: 100 }, |
| | | { field: 'planEndDate', title: '计å宿', minWidth: 120, formatter: 'formatDate' }, |
| | | { field: 'createTime', title: 'å建æ¶é´', minWidth: 160, formatter: 'formatDateTime' }, |
| | | { field: 'action', title: 'æä½', width: 220, fixed: 'right', slots: { default: 'actions' } }, |
| | | { field: "chiefDesignerNickname", title: "主设计å¸", minWidth: 100 }, |
| | | { field: "reviewerNickname", title: "å®¡æ ¸äºº", minWidth: 100 }, |
| | | { |
| | | field: "planFinishTime", |
| | | title: "计å宿", |
| | | minWidth: 120, |
| | | formatter: "formatDate", |
| | | }, |
| | | { |
| | | field: "createTime", |
| | | title: "å建æ¶é´", |
| | | minWidth: 160, |
| | | formatter: "formatDateTime", |
| | | }, |
| | | { |
| | | field: "action", |
| | | title: "æä½", |
| | | width: 260, |
| | | fixed: "right", |
| | | slots: { default: "actions" }, |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | /** ç¼è¾/详æ
表å */ |
| | | export function useFormSchema( |
| | | formType: FormType, |
| | | formApi?: VbenFormApi, |
| | | formApi?: ExtendedFormApi |
| | | ): VbenFormSchema[] { |
| | | const readonly = formType === 'detail'; |
| | | const readonly = formType === "detail"; |
| | | return [ |
| | | { |
| | | fieldName: 'id', |
| | | component: 'Input', |
| | | dependencies: { triggerFields: [''], show: () => false }, |
| | | fieldName: "id", |
| | | component: "Input", |
| | | dependencies: { triggerFields: [""], show: () => false }, |
| | | }, |
| | | { |
| | | fieldName: 'code', |
| | | label: 'ä»»å¡ç¼ç ', |
| | | component: 'Input', |
| | | componentProps: { disabled: readonly, placeholder: '请è¾å
¥ä»»å¡ç¼ç ' }, |
| | | rules: 'required', |
| | | fieldName: "taskCode", |
| | | label: "ä»»å¡ç¼ç ", |
| | | component: "Input", |
| | | componentProps: { disabled: readonly, placeholder: "请è¾å
¥ä»»å¡ç¼ç " }, |
| | | rules: "required", |
| | | suffix: |
| | | formType === 'detail' |
| | | formType === "detail" |
| | | ? undefined |
| | | : () => |
| | | h( |
| | | Button, |
| | | { |
| | | type: 'default', |
| | | type: "default", |
| | | onClick: async () => { |
| | | const code = isPdMockEnabled() |
| | | ? mockNextCode( |
| | | 'DT-2026', |
| | | Math.floor(Date.now() % 10_000), |
| | | ) |
| | | : await generateAutoCode( |
| | | MesAutoCodeRuleCode.PD_PROJECT_CODE, |
| | | const code = await generateAutoCode( |
| | | MesAutoCodeRuleCode.PD_PROJECT_CODE |
| | | ); |
| | | await formApi?.setFieldValue('code', code); |
| | | await formApi?.setFieldValue("taskCode", code); |
| | | }, |
| | | }, |
| | | { default: () => 'çæ' }, |
| | | { default: () => "çæ" } |
| | | ), |
| | | }, |
| | | ...useProductSelectSchema(formApi, readonly), |
| | | { |
| | | fieldName: 'version', |
| | | label: 'çæ¬å·', |
| | | component: 'Input', |
| | | componentProps: { disabled: readonly, placeholder: 'å¦ V1.0' }, |
| | | rules: 'required', |
| | | fieldName: "version", |
| | | label: "çæ¬å·", |
| | | component: "Input", |
| | | componentProps: { disabled: readonly, placeholder: "å¦ V1.0" }, |
| | | rules: "required", |
| | | }, |
| | | { |
| | | fieldName: 'name', |
| | | label: 'ä»»å¡åç§°', |
| | | component: 'Input', |
| | | componentProps: { disabled: readonly, placeholder: 'å¦ï¼æºè½æ¸©æ§æ¨¡ç» V1.0 设计' }, |
| | | rules: 'required', |
| | | fieldName: "taskName", |
| | | label: "ä»»å¡åç§°", |
| | | component: "Input", |
| | | componentProps: { |
| | | disabled: readonly, |
| | | placeholder: "å¦ï¼æºè½æ¸©æ§æ¨¡ç» V1.0 设计", |
| | | }, |
| | | rules: "required", |
| | | dependencies: { |
| | | triggerFields: ['productName', 'version'], |
| | | triggerFields: ["productName", "version"], |
| | | trigger(values: Record<string, string>, form) { |
| | | if (readonly) { |
| | | return; |
| | |
| | | const productName = values.productName?.trim(); |
| | | const version = values.version?.trim(); |
| | | if (productName && version) { |
| | | form.setFieldValue('name', `${productName} ${version} 设计`); |
| | | form.setFieldValue("taskName", `${productName} ${version} 设计`); |
| | | } |
| | | }, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'status', |
| | | label: 'ä»»å¡ç¶æ', |
| | | component: 'Select', |
| | | fieldName: "status", |
| | | label: "ä»»å¡ç¶æ", |
| | | component: "Select", |
| | | componentProps: { |
| | | disabled: true, |
| | | options: getDictOptions(DICT_TYPE.MES_PD_PROJECT_STATUS, 'number'), |
| | | options: getDictOptions(DICT_TYPE.MES_PD_PROJECT_STATUS, "number"), |
| | | }, |
| | | dependencies: { triggerFields: [''], show: () => formType !== 'create' }, |
| | | dependencies: { triggerFields: [""], show: () => formType !== "create" }, |
| | | }, |
| | | { |
| | | fieldName: 'designerName', |
| | | label: '主设计å¸', |
| | | component: 'Input', |
| | | componentProps: { disabled: readonly, placeholder: '请è¾å
¥ä¸»è®¾è®¡å¸' }, |
| | | fieldName: "chiefDesigner", |
| | | label: "主设计å¸", |
| | | component: markRaw(PdUserSelect), |
| | | componentProps: { disabled: readonly, placeholder: "è¯·éæ©ä¸»è®¾è®¡å¸" }, |
| | | }, |
| | | { |
| | | fieldName: 'reviewerName', |
| | | label: 'å®¡æ ¸äºº', |
| | | component: 'Input', |
| | | componentProps: { disabled: readonly, placeholder: '请è¾å
¥å®¡æ ¸äºº' }, |
| | | fieldName: "reviewer", |
| | | label: "å®¡æ ¸äºº", |
| | | component: markRaw(PdUserSelect), |
| | | componentProps: { disabled: readonly, placeholder: "è¯·éæ©å®¡æ ¸äºº" }, |
| | | }, |
| | | { |
| | | fieldName: 'planDateRange', |
| | | label: '计å卿', |
| | | component: 'RangePicker', |
| | | componentProps: { |
| | | ...getRangePickerDefaultProps(), |
| | | fieldName: "planFinishTime", |
| | | label: "计å宿æ¶é´", |
| | | component: "DatePicker", |
| | | componentProps: useModalDatePickerProps({ |
| | | disabled: readonly, |
| | | }, |
| | | placeholder: "è¯·éæ©è®¡å宿æ¶é´", |
| | | }), |
| | | }, |
| | | { |
| | | fieldName: 'remark', |
| | | label: '夿³¨', |
| | | component: 'Textarea', |
| | | componentProps: { disabled: readonly, placeholder: '请è¾å
¥å¤æ³¨', rows: 3 }, |
| | | formItemClass: 'col-span-3', |
| | | fieldName: "remark", |
| | | label: "夿³¨", |
| | | component: "Textarea", |
| | | componentProps: { |
| | | disabled: readonly, |
| | | placeholder: "请è¾å
¥å¤æ³¨", |
| | | rows: 3, |
| | | }, |
| | | formItemClass: "col-span-3", |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | /** è®¾è®¡èµæç±»åé项ï¼ä¸ä¼ æ¶éæ©ï¼ */ |
| | | /** è®¾è®¡èµæç±»åé项 */ |
| | | export function getPdDocumentTypeOptions() { |
| | | return [ |
| | | { label: 'è®¾è®¡æ¹æ¡', value: MesPdDocumentTypeEnum.SCHEME }, |
| | | { label: '设计å¾çº¸', value: MesPdDocumentTypeEnum.DRAWING }, |
| | | { label: '设计模å', value: MesPdDocumentTypeEnum.MODEL }, |
| | | { label: '产å设计', value: MesPdDocumentTypeEnum.PRODUCT_DESIGN }, |
| | | { label: 'BOM æ¸
å', value: MesPdDocumentTypeEnum.BOM }, |
| | | { label: 'å
¶ä»éä»¶', value: MesPdDocumentTypeEnum.OTHER }, |
| | | { label: "è®¾è®¡æ¹æ¡", value: MesPdDocumentTypeEnum.SCHEME }, |
| | | { label: "设计å¾çº¸", value: MesPdDocumentTypeEnum.DRAWING }, |
| | | { label: "设计模å", value: MesPdDocumentTypeEnum.MODEL }, |
| | | { label: "产å设计", value: MesPdDocumentTypeEnum.PRODUCT_DESIGN }, |
| | | { label: "BOM æ¸
å", value: MesPdDocumentTypeEnum.BOM }, |
| | | { label: "å
¶ä»éä»¶", value: MesPdDocumentTypeEnum.OTHER }, |
| | | ]; |
| | | } |
| | | |
| | | /** ç»ä¸è®¾è®¡èµæå表å */ |
| | | /** èµæå表æç´¢è¡¨å */ |
| | | export function useMaterialListGridFormSchema(): VbenFormSchema[] { |
| | | return [ |
| | | { |
| | | fieldName: 'name', |
| | | label: 'èµæåç§°', |
| | | component: 'Input', |
| | | componentProps: { placeholder: '请è¾å
¥èµæåç§°' }, |
| | | fieldName: "documentName", |
| | | label: "èµæåç§°", |
| | | component: "Input", |
| | | componentProps: { placeholder: "请è¾å
¥èµæåç§°" }, |
| | | }, |
| | | { |
| | | fieldName: 'documentType', |
| | | label: 'èµæç±»å', |
| | | component: 'Select', |
| | | fieldName: "documentType", |
| | | label: "èµæç±»å", |
| | | component: "Select", |
| | | componentProps: { |
| | | allowClear: true, |
| | | options: getPdDocumentTypeOptions(), |
| | | placeholder: 'è¯·éæ©èµæç±»å', |
| | | placeholder: "è¯·éæ©èµæç±»å", |
| | | }, |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | export function useMaterialListGridColumns(): VxeTableGridOptions['columns'] { |
| | | /** èµæå表åå®ä¹ */ |
| | | export function useMaterialListGridColumns(): VxeTableGridOptions["columns"] { |
| | | return [ |
| | | { |
| | | field: 'documentType', |
| | | title: 'èµæç±»å', |
| | | field: "documentType", |
| | | title: "èµæç±»å", |
| | | minWidth: 110, |
| | | formatter: ({ cellValue }: { cellValue: number }) => { |
| | | formatter: ({ cellValue }: { cellValue: string }) => { |
| | | const option = getPdDocumentTypeOptions().find( |
| | | (item) => item.value === cellValue, |
| | | (item) => item.value === cellValue |
| | | ); |
| | | return option?.label ?? String(cellValue ?? ''); |
| | | return option?.label ?? String(cellValue ?? ""); |
| | | }, |
| | | }, |
| | | { field: 'name', title: 'èµæåç§°', minWidth: 180 }, |
| | | { field: 'version', title: 'çæ¬', minWidth: 90 }, |
| | | { field: 'fileName', title: 'æä»¶å', minWidth: 200 }, |
| | | { field: 'uploaderName', title: 'ä¸ä¼ 人', minWidth: 100 }, |
| | | { field: "documentName", title: "èµæåç§°", minWidth: 180 }, |
| | | { field: "documentVersion", title: "çæ¬", minWidth: 90 }, |
| | | { |
| | | field: 'createTime', |
| | | title: 'ä¸ä¼ æ¶é´', |
| | | field: "fileUrl", |
| | | title: "æä»¶", |
| | | minWidth: 140, |
| | | slots: { default: "file" }, |
| | | }, |
| | | { field: "fileName", title: "æä»¶å", minWidth: 160 }, |
| | | { field: "uploadUserNickname", title: "ä¸ä¼ 人", minWidth: 100 }, |
| | | { |
| | | field: "uploadTime", |
| | | title: "ä¸ä¼ æ¶é´", |
| | | minWidth: 160, |
| | | formatter: 'formatDateTime', |
| | | formatter: "formatDateTime", |
| | | }, |
| | | { |
| | | field: 'action', |
| | | title: 'æä½', |
| | | field: "action", |
| | | title: "æä½", |
| | | width: 140, |
| | | fixed: 'right', |
| | | slots: { default: 'actions' }, |
| | | fixed: "right", |
| | | slots: { default: "actions" }, |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | /** @deprecated æç±»åå Tab æ¶ä½¿ç¨ï¼è¯·æ¹ç¨ useMaterialListGridColumns */ |
| | | export function useDocumentGridColumns(documentType: number): VxeTableGridOptions['columns'] { |
| | | const typeLabel = |
| | | documentType === MesPdDocumentTypeEnum.SCHEME |
| | | ? 'æ¹æ¡' |
| | | : documentType === MesPdDocumentTypeEnum.DRAWING |
| | | ? 'å¾çº¸' |
| | | : documentType === MesPdDocumentTypeEnum.MODEL |
| | | ? '模å' |
| | | : documentType === MesPdDocumentTypeEnum.PRODUCT_DESIGN |
| | | ? '产å设计' |
| | | : 'èµæ'; |
| | | |
| | | return [ |
| | | { field: 'name', title: `${typeLabel}åç§°`, minWidth: 180 }, |
| | | { field: 'version', title: 'çæ¬', minWidth: 90 }, |
| | | { field: 'fileName', title: 'æä»¶å', minWidth: 200 }, |
| | | { field: 'uploaderName', title: 'ä¸ä¼ 人', minWidth: 100 }, |
| | | { field: 'createTime', title: 'ä¸ä¼ æ¶é´', minWidth: 160, formatter: 'formatDateTime' }, |
| | | { field: 'action', title: 'æä½', width: 140, slots: { default: 'actions' } }, |
| | | ]; |
| | | } |
| | | |
| | | /** BOM è¡¨æ ¼å */ |
| | | export function useBomGridColumns(): VxeTableGridOptions['columns'] { |
| | | export function useBomGridColumns(): VxeTableGridOptions["columns"] { |
| | | return [ |
| | | { field: 'itemCode', title: 'ç©æç¼ç ', minWidth: 120 }, |
| | | { field: 'itemName', title: 'ç©æåç§°', minWidth: 160 }, |
| | | { field: 'specification', title: 'è§æ ¼åå·', minWidth: 140 }, |
| | | { field: 'unitMeasureName', title: 'åä½', minWidth: 80 }, |
| | | { field: 'quantity', title: 'ç¨é', minWidth: 90 }, |
| | | { field: 'remark', title: '夿³¨', minWidth: 140 }, |
| | | { field: 'action', title: 'æä½', width: 140, slots: { default: 'actions' } }, |
| | | { field: "itemCode", title: "ç©æç¼ç ", minWidth: 120 }, |
| | | { field: "itemName", title: "ç©æåç§°", minWidth: 160 }, |
| | | { field: "specification", title: "è§æ ¼åå·", minWidth: 140 }, |
| | | { field: "unitMeasureName", title: "åä½", minWidth: 80 }, |
| | | { field: "quantity", title: "ç¨é", minWidth: 90 }, |
| | | { field: "remark", title: "夿³¨", minWidth: 140 }, |
| | | { |
| | | field: "action", |
| | | title: "æä½", |
| | | width: 140, |
| | | slots: { default: "actions" }, |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | |
| | | /** 设计任å¡è¯¦æ
æè¦ */ |
| | | export function useDetailSchema(): DescriptionItemSchema[] { |
| | | return [ |
| | | { field: 'code', label: 'ä»»å¡ç¼ç ' }, |
| | | { field: 'name', label: 'ä»»å¡åç§°' }, |
| | | { field: 'taskCode', label: 'ä»»å¡ç¼ç ' }, |
| | | { field: 'taskName', label: 'ä»»å¡åç§°' }, |
| | | { field: 'productCode', label: '产åç¼ç ' }, |
| | | { field: 'productName', label: '产ååç§°' }, |
| | | { field: 'version', label: 'è®¾è®¡çæ¬' }, |
| | |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.MES_PD_PROJECT_STATUS, value: val }), |
| | | }, |
| | | { field: 'designerName', label: '设计å¸' }, |
| | | { field: 'reviewerName', label: 'å®¡æ ¸äºº' }, |
| | | { field: 'chiefDesignerNickname', label: '主设计å¸' }, |
| | | { field: 'reviewerNickname', label: 'å®¡æ ¸äºº' }, |
| | | { |
| | | field: 'planStartDate', |
| | | label: '计åå¼å§', |
| | | render: (val) => (val ? formatDate(val) : '-'), |
| | | }, |
| | | { |
| | | field: 'planEndDate', |
| | | field: 'planFinishTime', |
| | | label: '计å宿', |
| | | render: (val) => (val ? formatDate(val) : '-'), |
| | | }, |
| | | { |
| | | field: 'createTime', |
| | | label: 'åèµ·æ¶é´', |
| | | label: 'å建æ¶é´', |
| | | render: (val) => (val ? formatDateTime(val) : '-'), |
| | | }, |
| | | { field: 'remark', label: '夿³¨' }, |
| | |
| | | import { useTabs } from '#/packages/effects/hooks/src'; |
| | | import { MesPdProjectStatusEnum } from '#/packages/constants/src'; |
| | | |
| | | import { Card, Tabs } from 'ant-design-vue'; |
| | | import { Card, message, Tabs } from 'ant-design-vue'; |
| | | |
| | | import { |
| | | archivePdProject, |
| | | auditPdProject, |
| | | getPdProject, |
| | | publishPdProject, |
| | | uploadPdProject, |
| | | } from '#/api/mes/pd/project'; |
| | | import { useDescription } from '#/components/description'; |
| | | import { ACTION_ICON, TableAction } from '#/adapter/vxe-table'; |
| | | import { $t } from '#/locales'; |
| | | |
| | | import Form from '../modules/form.vue'; |
| | | import PublishForm from '../modules/publish-form.vue'; |
| | | import WorkflowActionForm from '../modules/workflow-action-form.vue'; |
| | | import ReviewList from '../modules/drawing-review/review-list.vue'; |
| | | import MaterialPanel from '../modules/material-panel.vue'; |
| | | import TaskDraftBanner from '../modules/task-draft-banner.vue'; |
| | | import DocumentAuditList from '../modules/document-audit-list.vue'; |
| | | import DocumentList from '../modules/document-list.vue'; |
| | | import WorkflowTimeline from '../modules/workflow-timeline.vue'; |
| | | import TaskDraftBanner from '../modules/task-draft-banner.vue'; |
| | | import { useDetailSchema } from './data'; |
| | | |
| | | const route = useRoute(); |
| | |
| | | const projectId = ref(0); |
| | | const project = ref<MesPdProjectApi.Project>({}); |
| | | const activeTab = ref('workflow'); |
| | | const workflowKey = ref(0); |
| | | |
| | | const isDraft = computed( |
| | | () => project.value.status === MesPdProjectStatusEnum.DRAFT, |
| | | const isPendingPublish = computed( |
| | | () => project.value.status === MesPdProjectStatusEnum.PENDING_PUBLISH, |
| | | ); |
| | | const isDesigning = computed( |
| | | () => project.value.status === MesPdProjectStatusEnum.DESIGNING, |
| | | const isPendingUpload = computed( |
| | | () => project.value.status === MesPdProjectStatusEnum.PENDING_UPLOAD, |
| | | ); |
| | | const isReviewing = computed( |
| | | () => project.value.status === MesPdProjectStatusEnum.REVIEWING, |
| | | const isPendingAudit = computed( |
| | | () => project.value.status === MesPdProjectStatusEnum.PENDING_AUDIT, |
| | | ); |
| | | const isApproved = computed( |
| | | () => project.value.status === MesPdProjectStatusEnum.APPROVED, |
| | | const isPendingArchive = computed( |
| | | () => project.value.status === MesPdProjectStatusEnum.PENDING_ARCHIVE, |
| | | ); |
| | | const isArchived = computed( |
| | | () => project.value.status === MesPdProjectStatusEnum.ARCHIVED, |
| | | ); |
| | | |
| | | const isFormEditable = computed( |
| | | () => |
| | | !isArchived.value && |
| | | project.value.status !== MesPdProjectStatusEnum.CANCELLED && |
| | | (isDraft.value || isDesigning.value), |
| | | () => isPendingPublish.value, |
| | | ); |
| | | |
| | | const materialFormType = computed<FormType>(() => |
| | | isDesigning.value ? 'update' : 'detail', |
| | | ); |
| | | |
| | | const showReviewTab = computed( |
| | | () => isReviewing.value || isApproved.value || isArchived.value, |
| | | isPendingPublish.value || isPendingUpload.value || isPendingAudit.value ? 'update' : 'detail', |
| | | ); |
| | | |
| | | const [Descriptions] = useDescription({ |
| | |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | const [PublishModal, publishModalApi] = useVbenModal({ |
| | | connectedComponent: PublishForm, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | const [WorkflowActionModal, workflowActionModalApi] = useVbenModal({ |
| | | connectedComponent: WorkflowActionForm, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | async function loadProjectDetail() { |
| | | loading.value = true; |
| | | try { |
| | | project.value = await getPdProject(projectId.value); |
| | | workflowKey.value += 1; |
| | | if (isDesigning.value) { |
| | | if (isPendingUpload.value) { |
| | | activeTab.value = 'material'; |
| | | } else if (isReviewing.value) { |
| | | activeTab.value = 'review'; |
| | | } else if (isPendingAudit.value) { |
| | | activeTab.value = 'audit'; |
| | | } |
| | | } finally { |
| | | loading.value = false; |
| | |
| | | formModalApi.setData({ formType: 'update', id: projectId.value }).open(); |
| | | } |
| | | |
| | | function handlePublish() { |
| | | publishModalApi.setData({ id: projectId.value }).open(); |
| | | async function handlePublish() { |
| | | const hideLoading = message.loading({ content: 'åå¸ä¸â¦', duration: 0 }); |
| | | try { |
| | | await publishPdProject(projectId.value); |
| | | message.success('ä»»å¡å·²åå¸ï¼è¿å
¥å¾
ä¸ä¼ ç¶æ'); |
| | | loadProjectDetail(); |
| | | } finally { |
| | | hideLoading(); |
| | | } |
| | | } |
| | | |
| | | function handleWorkflowAction(action: 'approve' | 'archive' | 'submit-review') { |
| | | workflowActionModalApi.setData({ id: projectId.value, action }).open(); |
| | | async function handleUpload() { |
| | | const hideLoading = message.loading({ content: 'æäº¤å®¡æ ¸ä¸â¦', duration: 0 }); |
| | | try { |
| | | await uploadPdProject(projectId.value); |
| | | message.success('å·²æäº¤èµæå®¡æ ¸'); |
| | | tabs.closeCurrentTab(); |
| | | router.back(); |
| | | } finally { |
| | | hideLoading(); |
| | | } |
| | | } |
| | | |
| | | async function handleAudit() { |
| | | const hideLoading = message.loading({ content: 'å®¡æ ¸ä¸â¦', duration: 0 }); |
| | | try { |
| | | await auditPdProject(projectId.value); |
| | | message.success('å®¡æ ¸éè¿ï¼è¿å
¥å¾
彿¡£ç¶æ'); |
| | | tabs.closeCurrentTab(); |
| | | router.back(); |
| | | } finally { |
| | | hideLoading(); |
| | | } |
| | | } |
| | | |
| | | async function handleArchive() { |
| | | const hideLoading = message.loading({ content: '彿¡£ä¸â¦', duration: 0 }); |
| | | try { |
| | | await archivePdProject(projectId.value); |
| | | message.success('已彿¡£'); |
| | | loadProjectDetail(); |
| | | } finally { |
| | | hideLoading(); |
| | | } |
| | | } |
| | | |
| | | onMounted(() => { |
| | |
| | | <Page |
| | | auto-content-height |
| | | :loading="loading" |
| | | :title="project.name || '设计任å¡è¯¦æ
'" |
| | | :title="project.taskName || '设计任å¡è¯¦æ
'" |
| | | > |
| | | <FormModal @success="loadProjectDetail" /> |
| | | <PublishModal @success="loadProjectDetail" /> |
| | | <WorkflowActionModal @success="loadProjectDetail" /> |
| | | |
| | | <template #extra> |
| | | <TableAction |
| | |
| | | onClick: handleEdit, |
| | | }, |
| | | { |
| | | label: 'åå¸ä»»å¡', |
| | | label: 'åå¸', |
| | | type: 'primary', |
| | | auth: ['mes:pd-project:update'], |
| | | ifShow: isDraft, |
| | | ifShow: isPendingPublish, |
| | | onClick: handlePublish, |
| | | }, |
| | | { |
| | | label: 'æäº¤å®¡æ ¸', |
| | | type: 'default', |
| | | auth: ['mes:pd-project:submit-review'], |
| | | ifShow: isDesigning, |
| | | onClick: () => handleWorkflowAction('submit-review'), |
| | | label: '确认ä¸ä¼ ', |
| | | type: 'primary', |
| | | auth: ['mes:pd-project:update'], |
| | | ifShow: isPendingUpload, |
| | | onClick: handleUpload, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸éè¿', |
| | | type: 'primary', |
| | | auth: ['mes:pd-drawing-review:review'], |
| | | ifShow: isReviewing, |
| | | onClick: () => handleWorkflowAction('approve'), |
| | | auth: ['mes:pd-project:audit'], |
| | | ifShow: isPendingAudit, |
| | | onClick: handleAudit, |
| | | }, |
| | | { |
| | | label: '彿¡£', |
| | | type: 'default', |
| | | auth: ['mes:pd-project:archive'], |
| | | ifShow: isApproved, |
| | | onClick: () => handleWorkflowAction('archive'), |
| | | ifShow: isPendingArchive, |
| | | onClick: handleArchive, |
| | | }, |
| | | ]" |
| | | /> |
| | | </template> |
| | | |
| | | <TaskDraftBanner |
| | | v-if="isDraft" |
| | | :designer-name="project.designerName" |
| | | v-if="isPendingPublish" |
| | | :designer-name="project.chiefDesignerNickname" |
| | | :product-name="project.productName" |
| | | :version="project.version" |
| | | @edit="handleEdit" |
| | |
| | | <Card class="mt-4 min-h-[60%]"> |
| | | <Tabs v-model:active-key="activeTab"> |
| | | <Tabs.TabPane key="workflow" tab="æµç¨è¿åº¦" :force-render="true"> |
| | | <WorkflowTimeline :key="workflowKey" :project-id="projectId" /> |
| | | <WorkflowTimeline :status="project.status ?? 0" /> |
| | | </Tabs.TabPane> |
| | | <Tabs.TabPane key="material" tab="è®¾è®¡èµæ" :force-render="true"> |
| | | <p v-if="isDraft" class="mb-3 text-sm text-amber-600"> |
| | | <Tabs.TabPane v-if="!isPendingAudit" key="material" tab="è®¾è®¡èµæ" :force-render="true"> |
| | | <p v-if="isPendingPublish" class="mb-3 text-sm text-amber-600"> |
| | | 请å
åå¸ä»»å¡ååä¸ä¼ è®¾è®¡èµæ |
| | | </p> |
| | | <MaterialPanel :form-type="materialFormType" :project-id="projectId" /> |
| | | <DocumentList |
| | | :form-type="materialFormType" |
| | | :project-id="projectId" |
| | | :project-status="project.status" |
| | | /> |
| | | </Tabs.TabPane> |
| | | <Tabs.TabPane |
| | | v-if="showReviewTab" |
| | | key="review" |
| | | tab="èµæå®¡æ ¸" |
| | | :force-render="true" |
| | | > |
| | | <ReviewList form-type="detail" :project-id="projectId" /> |
| | | <Tabs.TabPane v-if="isPendingAudit" key="audit" tab="èµæå®¡æ ¸" :force-render="true"> |
| | | <DocumentAuditList :project-id="projectId" @success="loadProjectDetail" /> |
| | | </Tabs.TabPane> |
| | | </Tabs> |
| | | </Card> |
| | |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesPdProjectApi } from '#/api/mes/pd/project'; |
| | | |
| | | import { onActivated } from 'vue'; |
| | | import { useRouter } from 'vue-router'; |
| | | |
| | | import { Page, useVbenModal } from '#/packages/effects/common-ui/src'; |
| | |
| | | |
| | | import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; |
| | | import { |
| | | archivePdProject, |
| | | |
| | | deletePdProject, |
| | | exportPdProject, |
| | | getPdProjectPage, |
| | | publishPdProject, |
| | | |
| | | } from '#/api/mes/pd/project'; |
| | | import { $t } from '#/locales'; |
| | | |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import CreateForm from './modules/create-form.vue'; |
| | | import Form from './modules/form.vue'; |
| | | import PublishForm from './modules/publish-form.vue'; |
| | | import WorkflowActionForm from './modules/workflow-action-form.vue'; |
| | | |
| | | const router = useRouter(); |
| | | |
| | |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | const [PublishModal, publishModalApi] = useVbenModal({ |
| | | connectedComponent: PublishForm, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | const [WorkflowActionModal, workflowActionModalApi] = useVbenModal({ |
| | | connectedComponent: WorkflowActionForm, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | function handleRefresh() { |
| | | gridApi.query(); |
| | | } |
| | | |
| | | function handleCreateSuccess(projectId: number) { |
| | | function handleCreateSuccess() { |
| | | handleRefresh(); |
| | | router.push({ name: 'MesPdProjectDetail', params: { id: projectId } }); |
| | | } |
| | | |
| | | function handleCreate() { |
| | |
| | | formModalApi.setData({ formType: 'update', id: row.id }).open(); |
| | | } |
| | | |
| | | function handlePublish(row: MesPdProjectApi.Project) { |
| | | publishModalApi.setData({ id: row.id }).open(); |
| | | async function handlePublish(row: MesPdProjectApi.Project) { |
| | | const hideLoading = message.loading({ |
| | | content: 'åå¸ä¸â¦', |
| | | duration: 0, |
| | | }); |
| | | try { |
| | | await publishPdProject(row.id!); |
| | | message.success('ä»»å¡å·²åå¸ï¼è¿å
¥å¾
ä¸ä¼ ç¶æ'); |
| | | handleRefresh(); |
| | | } finally { |
| | | hideLoading(); |
| | | } |
| | | } |
| | | |
| | | function handleWorkflowAction( |
| | | row: MesPdProjectApi.Project, |
| | | action: 'approve' | 'archive' | 'submit-review', |
| | | ) { |
| | | workflowActionModalApi.setData({ id: row.id, action }).open(); |
| | | async function handleArchive(row: MesPdProjectApi.Project) { |
| | | const hideLoading = message.loading({ |
| | | content: '彿¡£ä¸â¦', |
| | | duration: 0, |
| | | }); |
| | | try { |
| | | await archivePdProject(row.id!); |
| | | message.success('已彿¡£'); |
| | | handleRefresh(); |
| | | } finally { |
| | | hideLoading(); |
| | | } |
| | | } |
| | | |
| | | async function handleDelete(row: MesPdProjectApi.Project) { |
| | | const hideLoading = message.loading({ |
| | | content: $t('ui.actionMessage.deleting', [row.name]), |
| | | content: $t('ui.actionMessage.deleting', [row.taskName]), |
| | | duration: 0, |
| | | }); |
| | | try { |
| | | await deletePdProject(row.id!); |
| | | message.success($t('ui.actionMessage.deleteSuccess', [row.name])); |
| | | message.success($t('ui.actionMessage.deleteSuccess', [row.taskName])); |
| | | handleRefresh(); |
| | | } finally { |
| | | hideLoading(); |
| | |
| | | toolbarConfig: { refresh: true, search: true }, |
| | | } as VxeTableGridOptions<MesPdProjectApi.Project>, |
| | | }); |
| | | |
| | | onActivated(() => { |
| | | handleRefresh(); |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <Page auto-content-height> |
| | | <CreateFormModal @success="handleCreateSuccess" /> |
| | | <FormModal @success="handleRefresh" /> |
| | | <PublishModal @success="handleRefresh" /> |
| | | <WorkflowActionModal @success="handleRefresh" /> |
| | | |
| | | <Grid table-title="设计任å¡"> |
| | | <template #toolbar-tools> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: 'å起设计任å¡', |
| | | label: 'å建设计任å¡', |
| | | type: 'primary', |
| | | icon: ACTION_ICON.ADD, |
| | | auth: ['mes:pd-project:create'], |
| | |
| | | ]" |
| | | /> |
| | | </template> |
| | | <template #code="{ row }"> |
| | | <Button type="link" @click="handleDetail(row)">{{ row.code }}</Button> |
| | | <template #taskCode="{ row }"> |
| | | <Button type="link" @click="handleDetail(row)">{{ row.taskCode }}</Button> |
| | | </template> |
| | | <template #actions="{ row }"> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: 'åå¸ä»»å¡', |
| | | label: 'åå¸', |
| | | type: 'link', |
| | | auth: ['mes:pd-project:update'], |
| | | ifShow: row.status === MesPdProjectStatusEnum.DRAFT, |
| | | onClick: handlePublish.bind(null, row), |
| | | ifShow: row.status === MesPdProjectStatusEnum.PENDING_PUBLISH, |
| | | popConfirm: { |
| | | title: '确认åå¸è¯¥ä»»å¡ï¼åå¸åè¿å
¥å¾
ä¸ä¼ ç¶æã', |
| | | confirm: handlePublish.bind(null, row), |
| | | }, |
| | | }, |
| | | { |
| | | label: 'ä¸ä¼ èµæ', |
| | | type: 'link', |
| | | auth: ['mes:pd-project:update'], |
| | | ifShow: row.status === MesPdProjectStatusEnum.PENDING_UPLOAD, |
| | | onClick: () => handleDetail(row), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | auth: ['mes:pd-project:audit'], |
| | | ifShow: row.status === MesPdProjectStatusEnum.PENDING_AUDIT, |
| | | onClick: () => handleDetail(row), |
| | | }, |
| | | { |
| | | label: '彿¡£', |
| | | type: 'link', |
| | | auth: ['mes:pd-project:archive'], |
| | | ifShow: row.status === MesPdProjectStatusEnum.PENDING_ARCHIVE, |
| | | popConfirm: { |
| | | title: 'ç¡®è®¤å½æ¡£ï¼å½æ¡£åå°çæå°è´¦è®°å½ï¼ä»»å¡ä¸å¯åä¿®æ¹ã', |
| | | confirm: handleArchive.bind(null, row), |
| | | }, |
| | | }, |
| | | { |
| | | label: $t('common.edit'), |
| | | type: 'link', |
| | | icon: ACTION_ICON.EDIT, |
| | | auth: ['mes:pd-project:update'], |
| | | ifShow: |
| | | row.status === MesPdProjectStatusEnum.DRAFT || |
| | | row.status === MesPdProjectStatusEnum.DESIGNING, |
| | | ifShow: row.status === MesPdProjectStatusEnum.PENDING_PUBLISH, |
| | | onClick: handleEdit.bind(null, row), |
| | | }, |
| | | { |
| | | label: 'æäº¤å®¡æ ¸', |
| | | type: 'link', |
| | | auth: ['mes:pd-project:submit-review'], |
| | | ifShow: row.status === MesPdProjectStatusEnum.DESIGNING, |
| | | onClick: () => handleWorkflowAction(row, 'submit-review'), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸éè¿', |
| | | type: 'link', |
| | | auth: ['mes:pd-drawing-review:review'], |
| | | ifShow: row.status === MesPdProjectStatusEnum.REVIEWING, |
| | | onClick: () => handleWorkflowAction(row, 'approve'), |
| | | }, |
| | | { |
| | | label: '彿¡£', |
| | | type: 'link', |
| | | auth: ['mes:pd-project:archive'], |
| | | ifShow: row.status === MesPdProjectStatusEnum.APPROVED, |
| | | onClick: () => handleWorkflowAction(row, 'archive'), |
| | | }, |
| | | { |
| | | label: $t('common.delete'), |
| | |
| | | danger: true, |
| | | icon: ACTION_ICON.DELETE, |
| | | auth: ['mes:pd-project:delete'], |
| | | ifShow: row.status === MesPdProjectStatusEnum.DRAFT, |
| | | ifShow: row.status === MesPdProjectStatusEnum.PENDING_PUBLISH, |
| | | popConfirm: { |
| | | title: $t('ui.actionMessage.deleteConfirm', [row.name]), |
| | | title: $t('ui.actionMessage.deleteConfirm', [row.taskName]), |
| | | confirm: handleDelete.bind(null, row), |
| | | }, |
| | | }, |
| | |
| | | import { createPdProject } from '#/api/mes/pd/project'; |
| | | import { $t } from '#/locales'; |
| | | |
| | | import { useCreateTaskSchema } from '../data'; |
| | | import { useCreateFormSchema } from '../data'; |
| | | |
| | | const emit = defineEmits<{ |
| | | success: [projectId: number]; |
| | | success: []; |
| | | }>(); |
| | | |
| | | const [Form, formApi] = useVbenForm({ |
| | |
| | | } |
| | | modalApi.lock(); |
| | | const raw = (await formApi.getValues()) as MesPdProjectApi.Project & { |
| | | planDateRange?: [string, string]; |
| | | productId?: number; |
| | | }; |
| | | const { productId: _productId, planDateRange, ...data } = raw; |
| | | if (planDateRange?.length === 2) { |
| | | data.planStartDate = new Date(planDateRange[0]).getTime(); |
| | | data.planEndDate = new Date(planDateRange[1]).getTime(); |
| | | const { productId: _productId, ...data } = raw; |
| | | if (data.planFinishTime) { |
| | | data.planFinishTime = Number(data.planFinishTime); |
| | | } |
| | | try { |
| | | const id = await createPdProject(data); |
| | | emit('success', id); |
| | | message.success('设计任å¡å·²åèµ·ï¼è¯·åå¸ä»»å¡åå¼å§ä¸ä¼ èµæ'); |
| | | await createPdProject(data); |
| | | emit('success'); |
| | | message.success('设计任å¡å·²å建ï¼è¯·åå¸ä»»å¡åå¼å§ä¸ä¼ èµæ'); |
| | | await modalApi.close(); |
| | | } finally { |
| | | modalApi.unlock(); |
| | |
| | | await formApi.resetForm(); |
| | | return; |
| | | } |
| | | formApi.setState({ schema: useCreateTaskSchema(formApi) }); |
| | | modalApi.setState({ title: 'å起设计任å¡' }); |
| | | formApi.setState({ schema: useCreateFormSchema(formApi) }); |
| | | modalApi.setState({ title: 'å建设计任å¡' }); |
| | | }, |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <Modal class="w-[720px]"> |
| | | <Alert |
| | | class="mx-4 mb-4" |
| | | message="åèµ·ä»»å¡" |
| | | description="为æå®äº§åçæä¸è®¾è®¡çæ¬å建设计任å¡ãä»»å¡ä¿å为è稿ï¼åå¸åæ¹å¯ä¸ä¼ è®¾è®¡èµæã" |
| | | show-icon |
| | | type="info" |
| | | /> |
| | | <Form class="mx-4" /> |
| | | </Modal> |
| | | </template> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { MesPdDocumentAuditApi } from '#/api/mes/pd/document-audit'; |
| | | |
| | | import { useVbenModal } from '#/packages/effects/common-ui/src'; |
| | | import { DICT_TYPE } from '#/packages/constants/src'; |
| | | import { getDictOptions } from '#/packages/effects/hooks/src'; |
| | | |
| | | import { message } from 'ant-design-vue'; |
| | | |
| | | import { useVbenForm } from '#/adapter/form'; |
| | | import { updatePdDocumentAudit } from '#/api/mes/pd/document-audit'; |
| | | import { $t } from '#/locales'; |
| | | |
| | | const emit = defineEmits(['success']); |
| | | |
| | | const [Form, formApi] = useVbenForm({ |
| | | commonConfig: { componentProps: { class: 'w-full' }, labelWidth: 100 }, |
| | | layout: 'horizontal', |
| | | schema: [ |
| | | { fieldName: 'id', component: 'Input', dependencies: { triggerFields: [''], show: () => false } }, |
| | | { fieldName: 'auditNo', label: 'å®¡æ ¸åå·', component: 'Input', componentProps: { disabled: true } }, |
| | | { fieldName: 'documentName', label: 'èµæåç§°', component: 'Input', componentProps: { disabled: true } }, |
| | | { fieldName: 'documentVersion', label: 'èµæçæ¬', component: 'Input', componentProps: { disabled: true } }, |
| | | { fieldName: 'reviewerNickname', label: 'å®¡æ ¸äºº', component: 'Input', componentProps: { disabled: true } }, |
| | | { |
| | | fieldName: 'auditStatus', |
| | | label: 'å®¡æ ¸ç»æ', |
| | | component: 'Select', |
| | | componentProps: { options: getDictOptions(DICT_TYPE.MES_PD_DOCUMENT_AUDIT_STATUS, 'number'), placeholder: 'è¯·éæ©å®¡æ ¸ç»æ' }, |
| | | rules: 'selectRequired', |
| | | }, |
| | | { fieldName: 'remark', label: 'å®¡æ ¸æè§', component: 'Textarea', componentProps: { placeholder: '请è¾å
¥å®¡æ ¸æè§', rows: 3 } }, |
| | | ], |
| | | showDefaultActions: false, |
| | | }); |
| | | |
| | | const [Modal, modalApi] = useVbenModal({ |
| | | async onConfirm() { |
| | | const { valid } = await formApi.validate(); |
| | | if (!valid) return; |
| | | modalApi.lock(); |
| | | try { |
| | | const raw = await formApi.getValues(); |
| | | await updatePdDocumentAudit({ id: raw.id, auditStatus: raw.auditStatus, remark: raw.remark, auditTime: Date.now() }); |
| | | emit('success'); |
| | | message.success($t('ui.actionMessage.operationSuccess')); |
| | | await modalApi.close(); |
| | | } finally { |
| | | modalApi.unlock(); |
| | | } |
| | | }, |
| | | async onOpenChange(isOpen: boolean) { |
| | | if (!isOpen) return; |
| | | const data = modalApi.getData<MesPdDocumentAuditApi.DocumentAudit>(); |
| | | modalApi.setState({ title: 'èµæå®¡æ ¸' }); |
| | | await formApi.setValues(data); |
| | | }, |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <Modal class="w-[520px]"> |
| | | <Form class="mx-4" /> |
| | | </Modal> |
| | | </template> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesPdDocumentAuditApi } from '#/api/mes/pd/document-audit'; |
| | | |
| | | import { useVbenModal } from '#/packages/effects/common-ui/src'; |
| | | import { DICT_TYPE } from '#/packages/constants/src'; |
| | | import { getDictOptions } from '#/packages/effects/hooks/src'; |
| | | |
| | | import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; |
| | | import { getPdDocumentAuditPage } from '#/api/mes/pd/document-audit'; |
| | | |
| | | import AuditForm from './document-audit-form.vue'; |
| | | |
| | | const props = defineProps<{ |
| | | projectId: number; |
| | | }>(); |
| | | |
| | | const emit = defineEmits(['success']); |
| | | |
| | | const [AuditFormModal, auditFormModalApi] = useVbenModal({ |
| | | connectedComponent: AuditForm, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | function handleRefresh() { |
| | | gridApi.query(); |
| | | emit('success'); |
| | | } |
| | | |
| | | function handleAudit(row: MesPdDocumentAuditApi.DocumentAudit) { |
| | | auditFormModalApi.setData(row).open(); |
| | | } |
| | | |
| | | const [Grid, gridApi] = useVbenVxeGrid({ |
| | | formOptions: { |
| | | schema: [ |
| | | { fieldName: 'auditNo', label: 'å®¡æ ¸åå·', component: 'Input', componentProps: { placeholder: '请è¾å
¥å®¡æ ¸åå·' } }, |
| | | { fieldName: 'documentName', label: 'èµæåç§°', component: 'Input', componentProps: { placeholder: '请è¾å
¥èµæåç§°' } }, |
| | | { |
| | | fieldName: 'auditStatus', |
| | | label: 'å®¡æ ¸ç¶æ', |
| | | component: 'Select', |
| | | componentProps: { allowClear: true, options: getDictOptions(DICT_TYPE.MES_PD_DOCUMENT_AUDIT_STATUS, 'number'), placeholder: 'è¯·éæ©å®¡æ ¸ç¶æ' }, |
| | | }, |
| | | ], |
| | | }, |
| | | gridOptions: { |
| | | columns: [ |
| | | { field: 'auditNo', title: 'å®¡æ ¸åå·', minWidth: 140 }, |
| | | { field: 'documentName', title: 'èµæåç§°', minWidth: 160 }, |
| | | { field: 'documentVersion', title: 'èµæçæ¬', minWidth: 90 }, |
| | | { field: 'reviewerNickname', title: 'å®¡æ ¸äºº', minWidth: 100 }, |
| | | { field: 'auditStatus', title: 'å®¡æ ¸ç¶æ', minWidth: 100, cellRender: { name: 'CellDict', props: { type: DICT_TYPE.MES_PD_DOCUMENT_AUDIT_STATUS } } }, |
| | | { field: 'auditTime', title: 'å®¡æ ¸æ¶é´', minWidth: 160, formatter: 'formatDateTime' }, |
| | | { field: 'createTime', title: 'å建æ¶é´', minWidth: 160, formatter: 'formatDateTime' }, |
| | | { field: 'action', title: 'æä½', width: 100, fixed: 'right', slots: { default: 'actions' } }, |
| | | ], |
| | | height: 400, |
| | | keepSource: true, |
| | | proxyConfig: { |
| | | ajax: { |
| | | query: async ({ page }, formValues) => { |
| | | return await getPdDocumentAuditPage({ |
| | | pageNo: page.currentPage, |
| | | pageSize: page.pageSize, |
| | | ...formValues, |
| | | }); |
| | | }, |
| | | }, |
| | | }, |
| | | rowConfig: { keyField: 'id', isHover: true }, |
| | | toolbarConfig: { refresh: true, search: true }, |
| | | } as VxeTableGridOptions<MesPdDocumentAuditApi.DocumentAudit>, |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <AuditFormModal @success="handleRefresh" /> |
| | | <Grid table-title="èµæå®¡æ ¸"> |
| | | <template #actions="{ row }"> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.EDIT, |
| | | auth: ['mes:pd-document-audit:update'], |
| | | onClick: handleAudit.bind(null, row), |
| | | }, |
| | | ]" |
| | | /> |
| | | </template> |
| | | </Grid> |
| | | </template> |
| | |
| | | <script lang="ts" setup> |
| | | import type { MesPdDocumentApi } from '#/api/mes/pd/document'; |
| | | |
| | | import { ref } from 'vue'; |
| | | import { markRaw, ref } from 'vue'; |
| | | |
| | | import { useVbenModal } from '#/packages/effects/common-ui/src'; |
| | | import { MesPdDocumentTypeEnum } from '#/packages/constants/src'; |
| | |
| | | getPdDocument, |
| | | updatePdDocument, |
| | | } from '#/api/mes/pd/document'; |
| | | import { FileUpload } from '#/components/upload'; |
| | | import { $t } from '#/locales'; |
| | | |
| | | import { getPdDocumentTypeOptions } from '../data'; |
| | |
| | | const [Form, formApi] = useVbenForm({ |
| | | commonConfig: { |
| | | componentProps: { class: 'w-full' }, |
| | | formItemClass: 'col-span-1', |
| | | labelWidth: 100, |
| | | }, |
| | | layout: 'horizontal', |
| | | wrapperClass: 'grid-cols-1', |
| | | schema: [ |
| | | { |
| | | fieldName: 'id', |
| | |
| | | rules: 'selectRequired', |
| | | }, |
| | | { |
| | | fieldName: 'name', |
| | | fieldName: 'documentName', |
| | | label: 'èµæåç§°', |
| | | component: 'Input', |
| | | componentProps: { placeholder: '请è¾å
¥èµæåç§°' }, |
| | | rules: 'required', |
| | | }, |
| | | { |
| | | fieldName: 'version', |
| | | fieldName: 'documentVersion', |
| | | label: 'çæ¬å·', |
| | | component: 'Input', |
| | | componentProps: { placeholder: 'å¦ V1.0' }, |
| | |
| | | }, |
| | | { |
| | | fieldName: 'fileUrl', |
| | | label: 'æä»¶å°å', |
| | | component: 'Input', |
| | | componentProps: { placeholder: '请è¾å
¥æä»¶ URL æä¸ä¼ åå¡«å
¥' }, |
| | | label: 'æä»¶', |
| | | component: markRaw(FileUpload), |
| | | componentProps: { |
| | | directory: 'mes/pd', |
| | | maxNumber: 1, |
| | | onChange: async (url: string) => { |
| | | if (url) { |
| | | await formApi?.setFieldValue('fileUrl', url); |
| | | } |
| | | }, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'fileName', |
| | | label: 'æä»¶å', |
| | | component: 'Input', |
| | | componentProps: { placeholder: 'å¦ bom-list.xlsx' }, |
| | | }, |
| | | { |
| | | fieldName: 'remark', |
| | | label: '夿³¨', |
| | | component: 'Textarea', |
| | | componentProps: { placeholder: '请è¾å
¥å¤æ³¨', rows: 3 }, |
| | | componentProps: { placeholder: 'ä¸ä¼ åèªå¨å¡«å
¥ï¼ä¹å¯æå¨è¾å
¥' }, |
| | | }, |
| | | ], |
| | | showDefaultActions: false, |
| | |
| | | const data = modalApi.getData<{ |
| | | id?: number; |
| | | projectId: number; |
| | | documentType?: number; |
| | | documentType?: string; |
| | | }>(); |
| | | isUpdate.value = !!data.id; |
| | | modalApi.setState({ title: isUpdate.value ? 'ç¼è¾éä»¶' : 'ä¸ä¼ éä»¶' }); |
| | | modalApi.setState({ title: isUpdate.value ? 'ç¼è¾èµæ' : 'ä¸ä¼ èµæ' }); |
| | | if (data.id) { |
| | | modalApi.lock(); |
| | | try { |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <Modal class="w-[560px]"> |
| | | <Modal class="w-[720px]"> |
| | | <Form class="mx-4" /> |
| | | </Modal> |
| | | </template> |
| | |
| | | import { computed, watch } from 'vue'; |
| | | |
| | | import { useVbenModal } from '#/packages/effects/common-ui/src'; |
| | | import { MesPdDocumentTypeEnum } from '#/packages/constants/src'; |
| | | import { MesPdDocumentTypeEnum, MesPdProjectStatusEnum } from '#/packages/constants/src'; |
| | | |
| | | import { message } from 'ant-design-vue'; |
| | | |
| | |
| | | formType: FormType; |
| | | gridHeight?: number | string; |
| | | projectId: number; |
| | | projectStatus?: number; |
| | | tableTitle?: string; |
| | | version?: string; |
| | | }>(), |
| | |
| | | }, |
| | | ); |
| | | |
| | | const isEditable = computed(() => |
| | | ['create', 'update'].includes(props.formType), |
| | | /** æ¯å¦å
许æ°å¢/ç¼è¾/å é¤èµæ */ |
| | | const canEdit = computed(() => |
| | | props.projectStatus === undefined || |
| | | props.projectStatus === MesPdProjectStatusEnum.PENDING_PUBLISH || |
| | | props.projectStatus === MesPdProjectStatusEnum.PENDING_UPLOAD, |
| | | ); |
| | | |
| | | const [DocumentFormModal, documentFormModalApi] = useVbenModal({ |
| | |
| | | |
| | | async function handleDelete(row: MesPdDocumentApi.Document) { |
| | | const hideLoading = message.loading({ |
| | | content: $t('ui.actionMessage.deleting', [row.name]), |
| | | content: $t('ui.actionMessage.deleting', [row.documentName]), |
| | | duration: 0, |
| | | }); |
| | | try { |
| | | await deletePdDocument(row.id!); |
| | | message.success($t('ui.actionMessage.deleteSuccess', [row.name])); |
| | | message.success($t('ui.actionMessage.deleteSuccess', [row.documentName])); |
| | | handleRefresh(); |
| | | } finally { |
| | | hideLoading(); |
| | | } |
| | | } |
| | | |
| | | function handlePreview(row: MesPdDocumentApi.Document) { |
| | | if (row.fileUrl) { |
| | | window.open(row.fileUrl, '_blank'); |
| | | } |
| | | } |
| | | |
| | |
| | | pageNo: page.currentPage, |
| | | pageSize: page.pageSize, |
| | | projectId: props.projectId, |
| | | version: props.version, |
| | | documentVersion: props.version, |
| | | ...formValues, |
| | | }); |
| | | }, |
| | |
| | | <template> |
| | | <DocumentFormModal @success="handleRefresh" /> |
| | | <Grid :table-title="tableTitle"> |
| | | <template v-if="isEditable" #toolbar-tools> |
| | | <template v-if="canEdit" #toolbar-tools> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: 'ä¸ä¼ éä»¶', |
| | | label: 'ä¸ä¼ èµæ', |
| | | type: 'primary', |
| | | icon: ACTION_ICON.ADD, |
| | | onClick: handleCreate, |
| | |
| | | ]" |
| | | /> |
| | | </template> |
| | | <template #file="{ row }"> |
| | | <a v-if="row.fileUrl" :href="row.fileUrl" target="_blank" class="text-primary"> |
| | | {{ row.fileName || 'æ¥çæä»¶' }} |
| | | </a> |
| | | <span v-else class="text-gray-400">-</span> |
| | | </template> |
| | | <template #actions="{ row }"> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: 'é¢è§', |
| | | type: 'link', |
| | | ifShow: !!row.fileUrl, |
| | | onClick: handlePreview.bind(null, row), |
| | | }, |
| | | { |
| | | label: $t('common.edit'), |
| | | type: 'link', |
| | | icon: ACTION_ICON.EDIT, |
| | | ifShow: isEditable, |
| | | ifShow: canEdit, |
| | | onClick: handleEdit.bind(null, row), |
| | | }, |
| | | { |
| | |
| | | type: 'link', |
| | | danger: true, |
| | | icon: ACTION_ICON.DELETE, |
| | | ifShow: isEditable, |
| | | ifShow: canEdit, |
| | | popConfirm: { |
| | | title: $t('ui.actionMessage.deleteConfirm', [row.name]), |
| | | title: $t('ui.actionMessage.deleteConfirm', [row.documentName]), |
| | | confirm: handleDelete.bind(null, row), |
| | | }, |
| | | }, |
| | |
| | | } |
| | | modalApi.lock(); |
| | | const raw = (await formApi.getValues()) as MesPdProjectApi.Project & { |
| | | planDateRange?: [string, string]; |
| | | productId?: number; |
| | | }; |
| | | const { productId: _productId, planDateRange, ...data } = raw; |
| | | if (planDateRange?.length === 2) { |
| | | data.planStartDate = new Date(planDateRange[0]).getTime(); |
| | | data.planEndDate = new Date(planDateRange[1]).getTime(); |
| | | const { productId: _productId, ...data } = raw; |
| | | if (data.planFinishTime) { |
| | | data.planFinishTime = Number(data.planFinishTime); |
| | | } |
| | | try { |
| | | await updatePdProject(data); |
| | |
| | | modalApi.lock(); |
| | | try { |
| | | formData.value = await getPdProject(data.id); |
| | | const { planFinishTime, ...rest } = formData.value; |
| | | await formApi.setValues({ |
| | | ...formData.value, |
| | | planDateRange: |
| | | formData.value.planStartDate && formData.value.planEndDate |
| | | ? [formData.value.planStartDate, formData.value.planEndDate] |
| | | : undefined, |
| | | ...rest, |
| | | planFinishTime: planFinishTime ? String(planFinishTime) : undefined, |
| | | }); |
| | | } finally { |
| | | modalApi.unlock(); |
| | |
| | | class="mb-4 flex items-center justify-between rounded-lg border border-amber-200 bg-amber-50 px-4 py-3" |
| | | > |
| | | <div class="text-sm text-amber-900"> |
| | | <span class="font-medium">ä»»å¡å·²åèµ·ï¼è稿ï¼</span> |
| | | <span class="font-medium">ä»»å¡å¾
åå¸</span> |
| | | <span class="ml-2 text-amber-700"> |
| | | {{ productName }} {{ version }} · è®¾è®¡å¸ {{ designerName || 'æªæå®' }} |
| | | </span> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { SystemUserApi } from '#/api/system/user'; |
| | | |
| | | import { onMounted, ref, watch } from 'vue'; |
| | | |
| | | import { Select } from 'ant-design-vue'; |
| | | |
| | | import { getSimpleUserList } from '#/api/system/user'; |
| | | |
| | | defineOptions({ name: 'PdUserSelect', inheritAttrs: false }); |
| | | |
| | | const props = withDefaults( |
| | | defineProps<{ |
| | | disabled?: boolean; |
| | | modelValue?: number; |
| | | placeholder?: string; |
| | | }>(), |
| | | { |
| | | disabled: false, |
| | | modelValue: undefined, |
| | | placeholder: 'è¯·éæ©', |
| | | }, |
| | | ); |
| | | |
| | | const emit = defineEmits<{ |
| | | 'update:modelValue': [value: number | undefined]; |
| | | }>(); |
| | | |
| | | const options = ref<{ label: string; value: number }[]>([]); |
| | | |
| | | onMounted(async () => { |
| | | const users = await getSimpleUserList(); |
| | | options.value = users |
| | | .filter((u): u is SystemUserApi.User & { id: number } => u.id !== undefined) |
| | | .map((u) => ({ label: u.nickname || u.username, value: u.id })); |
| | | }); |
| | | |
| | | watch( |
| | | () => props.modelValue, |
| | | (val) => { |
| | | emit('update:modelValue', val); |
| | | }, |
| | | ); |
| | | </script> |
| | | |
| | | <template> |
| | | <Select |
| | | v-bind="$attrs" |
| | | :disabled="disabled" |
| | | :options="options" |
| | | :placeholder="placeholder" |
| | | :value="modelValue" |
| | | allow-clear |
| | | show-search |
| | | :filter-option=" |
| | | (input: string, option: any) => |
| | | option?.label?.toLowerCase().includes(input.toLowerCase()) |
| | | " |
| | | @change="(val: number) => emit('update:modelValue', val)" |
| | | /> |
| | | </template> |
| | |
| | | import { Button } from 'ant-design-vue'; |
| | | |
| | | import { generateAutoCode } from '#/api/mes/md/autocode/record'; |
| | | import { isPdMockEnabled } from '#/api/mes/pd/mock/enabled'; |
| | | import { mockNextCode } from '#/api/mes/pd/mock/utils'; |
| | | |
| | | export type VersionChangeFormType = 'create' | 'detail' | 'update'; |
| | | |
| | |
| | | { |
| | | type: 'default', |
| | | onClick: async () => { |
| | | const code = isPdMockEnabled() |
| | | ? mockNextCode( |
| | | 'VC-2026', |
| | | Math.floor(Date.now() % 10_000), |
| | | ) |
| | | : await generateAutoCode( |
| | | const code = await generateAutoCode( |
| | | MesAutoCodeRuleCode.PD_VERSION_CODE, |
| | | ); |
| | | await formApi?.setFieldValue('code', code); |
| | |
| | | <script lang="ts" setup> |
| | | import type { MesPdWorkflowApi } from '#/api/mes/pd/workflow'; |
| | | |
| | | import { onMounted, ref, watch } from 'vue'; |
| | | import { computed } from 'vue'; |
| | | |
| | | import { Steps } from 'ant-design-vue'; |
| | | |
| | | import { getPdWorkflowList } from '#/api/mes/pd/workflow'; |
| | | const STEPS = ['å¾
åå¸', 'å¾
ä¸ä¼ ', 'å¾
å®¡æ ¸', 'å¾
彿¡£', '已彿¡£'] as const; |
| | | |
| | | const props = defineProps<{ |
| | | projectId: number; |
| | | /** 项ç®å½åç¶æ (0-4) */ |
| | | status: number; |
| | | }>(); |
| | | |
| | | const loading = ref(false); |
| | | const nodes = ref<MesPdWorkflowApi.WorkflowNode[]>([]); |
| | | const current = ref(0); |
| | | const current = computed(() => { |
| | | // ç¶æå¼å³å½å已宿å°ç¬¬å æ¥ï¼0=ç¬¬ä¸æ¥è¿è¡ä¸ï¼4=å
¨é¨å®æ |
| | | return props.status; |
| | | }); |
| | | |
| | | async function loadData() { |
| | | loading.value = true; |
| | | try { |
| | | nodes.value = await getPdWorkflowList(props.projectId); |
| | | const activeIndex = nodes.value.findIndex((item) => item.status !== 1); |
| | | current.value = activeIndex === -1 ? nodes.value.length : activeIndex; |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | } |
| | | |
| | | watch( |
| | | () => props.projectId, |
| | | () => loadData(), |
| | | { immediate: true }, |
| | | const nodes = computed(() => |
| | | STEPS.map((name, index) => ({ |
| | | title: name, |
| | | status: index < props.status ? 'finish' : index === props.status ? 'process' : 'wait', |
| | | })), |
| | | ); |
| | | |
| | | onMounted(loadData); |
| | | </script> |
| | | |
| | | <template> |
| | | <Steps :current="current" direction="vertical" size="small"> |
| | | <Steps.Step |
| | | v-for="node in nodes" |
| | | :key="node.id" |
| | | :description="node.remark" |
| | | :sub-title="node.operatorName" |
| | | :title="node.nodeName" |
| | | /> |
| | | <Steps.Step |
| | | v-if="!loading && nodes.length === 0" |
| | | description="ææ æµç¨è®°å½ï¼ä¿å项ç®åå°èªå¨çæ" |
| | | title="å¾
å¯å¨" |
| | | v-for="(node, index) in nodes" |
| | | :key="index" |
| | | :status="node.status as any" |
| | | :title="node.title" |
| | | /> |
| | | </Steps> |
| | | </template> |
| | |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesProAndonConfigApi } from '#/api/mes/pro/andon/config'; |
| | | import type { MesProAndonRecordApi } from '#/api/mes/pro/andon/record'; |
| | |
| | | return [ |
| | | { field: 'workstationCode', title: 'å·¥ä½ç«ç¼ç ', width: 140 }, |
| | | { field: 'workstationName', title: 'å·¥ä½ç«åç§°', minWidth: 140 }, |
| | | { field: 'workOrderCode', title: 'å·¥åç¼ç ', width: 140 }, |
| | | { field: 'workOrderCode', title: '订åç¼ç ', width: 140 }, |
| | | { field: 'processName', title: 'å·¥åºåç§°', width: 140 }, |
| | | { field: 'userNickname', title: 'å起人', width: 110 }, |
| | | { |
| | |
| | | /** |
| | | * æ°å¢/å¤ç½®/详æ
å®ç¯å¼å«è®°å½ç表å |
| | | * |
| | | * - createï¼å½å
¥å¼å«ä¸»ä½ä¿¡æ¯ï¼å·¥ä½ç«/å起人/å·¥å/å·¥åº/å¼å«åå /夿³¨ï¼ |
| | | * - createï¼å½å
¥å¼å«ä¸»ä½ä¿¡æ¯ï¼å·¥ä½ç«/å起人/订å/å·¥åº/å¼å«åå /夿³¨ï¼ |
| | | * - updateï¼å¼å«ä¸»ä½åªè¯»å±ç¤ºå建æ¶çå¿«ç
§å段ï¼workstationName/workOrderCode/processName/reasonï¼ï¼ç¼è¾å¤ç½®æ¶é´/å¤ç½®äºº/夿³¨ |
| | | * - detailï¼ææå段åªè¯» |
| | | */ |
| | |
| | | isCreate |
| | | ? { |
| | | fieldName: 'workOrderId', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©å·¥åï¼å¯éï¼', |
| | | placeholder: 'è¯·éæ©è®¢åï¼å¯éï¼', |
| | | status: MesProWorkOrderStatusEnum.CONFIRMED, |
| | | }, |
| | | } |
| | | : { |
| | | fieldName: 'workOrderCode', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | component: 'Input', |
| | | componentProps: { |
| | | disabled: true, |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { MesProCardApi } from '#/api/mes/pro/card'; |
| | | |
| | | import { computed, ref, useAttrs, watch } from 'vue'; |
| | |
| | | <template #title> |
| | | <div v-if="selectedItem" class="leading-6"> |
| | | <div>ç¼å·ï¼{{ selectedItem.code || '-' }}</div> |
| | | <div>å·¥åï¼{{ selectedItem.workOrderCode || '-' }}</div> |
| | | <div>订åï¼{{ selectedItem.workOrderCode || '-' }}</div> |
| | | <div>æ¹æ¬¡ï¼{{ selectedItem.batchCode || '-' }}</div> |
| | | <div>产åï¼{{ selectedItem.itemName || '-' }}</div> |
| | | </div> |
| | |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesProCardApi } from '#/api/mes/pro/card'; |
| | | import type { MesProCardProcessApi } from '#/api/mes/pro/card/process'; |
| | |
| | | }, |
| | | { |
| | | fieldName: 'workOrderId', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | disabled: headerReadonly, |
| | | placeholder: 'è¯·éæ©ç产工å', |
| | | placeholder: 'è¯·éæ©ç产订å', |
| | | status: MesProWorkOrderStatusEnum.CONFIRMED, |
| | | }, |
| | | rules: 'selectRequired', |
| | |
| | | }, |
| | | { |
| | | fieldName: 'workOrderId', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©ç产工å', |
| | | placeholder: 'è¯·éæ©ç产订å', |
| | | }, |
| | | }, |
| | | { |
| | |
| | | }, |
| | | { |
| | | field: 'workOrderCode', |
| | | title: 'ç产工åç¼å·', |
| | | title: 'ç产订åç¼å·', |
| | | width: 160, |
| | | }, |
| | | { |
| | | field: 'workOrderName', |
| | | title: 'å·¥ååç§°', |
| | | title: '订ååç§°', |
| | | minWidth: 150, |
| | | }, |
| | | { |
| | |
| | | }, |
| | | { |
| | | fieldName: 'workOrderId', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©ç产工å', |
| | | placeholder: 'è¯·éæ©ç产订å', |
| | | }, |
| | | }, |
| | | { |
| | |
| | | }, |
| | | { |
| | | field: 'workOrderCode', |
| | | title: 'ç产工åç¼å·', |
| | | title: 'ç产订åç¼å·', |
| | | width: 160, |
| | | }, |
| | | { |
| | |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesProFeedbackApi } from '#/api/mes/pro/feedback'; |
| | | import type { MesProTaskApi } from '#/api/mes/pro/task'; |
| | |
| | | return [ |
| | | { |
| | | fieldName: 'code', |
| | | label: 'æ¥å·¥åå·', |
| | | label: 'æ¥è®¢åå·', |
| | | component: 'Input', |
| | | componentProps: { |
| | | allowClear: true, |
| | | placeholder: '请è¾å
¥æ¥å·¥åå·', |
| | | placeholder: '请è¾å
¥æ¥è®¢åå·', |
| | | }, |
| | | }, |
| | | { |
| | |
| | | }, |
| | | { |
| | | fieldName: 'workOrderId', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | allowClear: true, |
| | | placeholder: 'è¯·éæ©å·¥å', |
| | | placeholder: 'è¯·éæ©è®¢å', |
| | | }, |
| | | }, |
| | | { |
| | |
| | | return [ |
| | | { |
| | | field: 'code', |
| | | title: 'æ¥å·¥åå·', |
| | | title: 'æ¥è®¢åå·', |
| | | width: 160, |
| | | slots: { default: 'code' }, |
| | | }, |
| | |
| | | }, |
| | | { field: 'workstationName', title: 'å·¥ä½ç«', width: 120 }, |
| | | { field: 'processName', title: 'å·¥åº', width: 100 }, |
| | | { field: 'workOrderCode', title: 'ç产工åç¼ç ', width: 160 }, |
| | | { field: 'workOrderCode', title: 'ç产订åç¼ç ', width: 160 }, |
| | | { field: 'itemCode', title: '产åç©æç¼ç ', width: 120 }, |
| | | { field: 'itemName', title: '产åç©æåç§°', minWidth: 140 }, |
| | | { field: 'itemSpecification', title: 'è§æ ¼åå·', width: 120 }, |
| | |
| | | }, |
| | | { |
| | | fieldName: 'code', |
| | | label: 'æ¥å·¥åå·', |
| | | label: 'æ¥è®¢åå·', |
| | | component: 'Input', |
| | | componentProps: { |
| | | disabled: isHeaderReadonly, |
| | | placeholder: '请è¾å
¥æ¥å·¥åå·', |
| | | placeholder: '请è¾å
¥æ¥è®¢åå·', |
| | | }, |
| | | rules: 'required', |
| | | suffix: () => |
| | |
| | | }, |
| | | { |
| | | fieldName: 'workOrderId', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | disabled: isHeaderReadonly, |
| | | placeholder: 'è¯·éæ©å·¥å', |
| | | placeholder: 'è¯·éæ©è®¢å', |
| | | status: MesProWorkOrderStatusEnum.CONFIRMED, |
| | | // å·¥ååæ´ï¼æ¸
空任å¡åä»»å¡å¸¦åºç产åä¿¡æ¯ãæ°éåºåæ§å¶ä½ |
| | | // 订ååæ´ï¼æ¸
空任å¡åä»»å¡å¸¦åºç产åä¿¡æ¯ãæ°éåºåæ§å¶ä½ |
| | | onChange: async () => { |
| | | await formApi?.setValues({ |
| | | checkFlag: true, |
| | |
| | | triggerFields: ['workOrderId', 'workstationId'], |
| | | componentProps: (values) => ({ |
| | | disabled: isHeaderReadonly || !values.workOrderId, |
| | | placeholder: values.workOrderId ? 'è¯·éæ©ä»»å¡' : '请å
鿩工å', |
| | | placeholder: values.workOrderId ? 'è¯·éæ©ä»»å¡' : '请å
éæ©è®¢å', |
| | | statuses: [MesProTaskStatusEnum.PREPARE], |
| | | workOrderId: values.workOrderId, |
| | | workstationId: values.workstationId, |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { FormType } from '../data'; |
| | | |
| | | import type { MesProFeedbackApi } from '#/api/mes/pro/feedback'; |
| | |
| | | await submitFeedback(formData.value!.id!); |
| | | await modalApi.close(); |
| | | emit('success'); |
| | | message.success('æ¥å·¥åå·²æäº¤'); |
| | | message.success('æ¥è®¢åå·²æäº¤'); |
| | | } finally { |
| | | modalApi.unlock(); |
| | | } |
| | |
| | | await modalApi.close(); |
| | | emit('success'); |
| | | message.success( |
| | | finished ? 'æ¥å·¥å已审æ¹å®æ' : 'æ¥å·¥æåï¼è¯·çå¾
è´¨éæ£éªå®æï¼', |
| | | finished ? 'æ¥è®¢å已审æ¹å®æ' : 'æ¥å·¥æåï¼è¯·çå¾
è´¨éæ£éªå®æï¼', |
| | | ); |
| | | } finally { |
| | | modalApi.unlock(); |
| | |
| | | await rejectFeedback(formData.value.id); |
| | | await modalApi.close(); |
| | | emit('success'); |
| | | message.success('æ¥å·¥å已驳å'); |
| | | message.success('æ¥è®¢å已驳å'); |
| | | } finally { |
| | | modalApi.unlock(); |
| | | } |
| | |
| | | formType.value !== 'detail' && formType.value !== 'approve', |
| | | }); |
| | | if (!data?.id) { |
| | | // æ°å¢ï¼é»è®¤æ¥å·¥äººåæ¥å·¥æ¶é´ï¼å¹¶èªå¨çææ¥å·¥åå· |
| | | // æ°å¢ï¼é»è®¤æ¥å·¥äººåæ¥å·¥æ¶é´ï¼å¹¶èªå¨çææ¥è®¢åå· |
| | | const code = await generateAutoCode( |
| | | MesAutoCodeRuleCode.PRO_FEEDBACK_CODE, |
| | | ); |
| | |
| | | <div class="flex flex-auto items-center justify-end gap-2"> |
| | | <Popconfirm |
| | | v-if="canSubmit" |
| | | title="确认æäº¤è¯¥æ¥å·¥åï¼æäº¤åå°ä¸è½ä¿®æ¹ã" |
| | | title="确认æäº¤è¯¥æ¥è®¢åï¼æäº¤åå°ä¸è½ä¿®æ¹ã" |
| | | @confirm="handleSubmit" |
| | | > |
| | | <Button type="primary">{{ $t('common.submit') }}</Button> |
| | | </Popconfirm> |
| | | <Popconfirm |
| | | v-if="canApprove" |
| | | title="确认审æ¹éè¿è¯¥æ¥å·¥åï¼" |
| | | title="确认审æ¹éè¿è¯¥æ¥è®¢åï¼" |
| | | @confirm="handleApprove" |
| | | > |
| | | <Button type="primary">éè¿</Button> |
| | | </Popconfirm> |
| | | <Popconfirm |
| | | v-if="canApprove" |
| | | title="确认驳å该æ¥å·¥åï¼" |
| | | title="确认驳å该æ¥è®¢åï¼" |
| | | @confirm="handleReject" |
| | | > |
| | | <Button danger>ä¸éè¿</Button> |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import { onBeforeUnmount, onMounted, ref, watch } from 'vue'; |
| | | |
| | | import { BarcodeBizTypeEnum } from '../../../../../packages/constants/src'; |
| | |
| | | /** |
| | | * çç¹å¾ç»ä»¶ï¼åºäº dhtmlx-ganttï¼ |
| | | * |
| | | * 1. æå·¥ååç»å±ç¤ºç产任å¡ï¼å·¥å为 project è¡ï¼ä»»å¡ä¸ºåè¡ |
| | | * 1. æè®¢ååç»å±ç¤ºç产任å¡ï¼è®¢å为 project è¡ï¼ä»»å¡ä¸ºåè¡ |
| | | * 2. æ¯æåªè¯»é¢è§åææ½ç¼è¾ä¸¤ç§æ¨¡å¼ |
| | | * 3. ææ½å触å taskUpdate äºä»¶ï¼éç¥ç¶ç»ä»¶æ¹éä¿å |
| | | * 4. æ¶é´å»åº¦ï¼å¨ â æ¥ â 8 å°æ¶ï¼1 工使¥ = 8 å°æ¶ï¼ |
| | |
| | | gantt.templates.task_text = (_start: any, _end: any, task: any) => { |
| | | const percent = Math.round((task.progress || 0) * 100); |
| | | if (task.type === 'project') { |
| | | return `<b>ç产工å:</b> ${task.text} <span>宿æ¯ä¾ï¼${percent}%</span>`; |
| | | return `<b>ç产订å:</b> ${task.text} <span>宿æ¯ä¾ï¼${percent}%</span>`; |
| | | } |
| | | return `<b>ç产任å¡:</b> ${task.process || ''} ${task.text} <span>宿æ¯ä¾ï¼${percent}%</span>`; |
| | | }; |
| | |
| | | gantt.templates.tooltip_text = (_start: any, _end: any, task: any) => { |
| | | const percent = Math.round((task.progress || 0) * 100); |
| | | if (task.type === 'project') { |
| | | return `<b>ç产工å:</b> ${task.text} <span>宿æ¯ä¾ï¼${percent}%</span>`; |
| | | return `<b>ç产订å:</b> ${task.text} <span>宿æ¯ä¾ï¼${percent}%</span>`; |
| | | } |
| | | return `<b>ç产任å¡:</b> ${task.process || ''} ${task.text} <span>宿æ¯ä¾ï¼${percent}%</span>`; |
| | | }; |
| | |
| | | if (!props.readonly) { |
| | | gantt.attachEvent('onAfterTaskUpdate', (id: number | string) => { |
| | | const task = gantt.getTask(id); |
| | | // åªåå task èç¹ï¼é¿å
æå·¥å(project)èç¹å½æä»»å¡ä¿å |
| | | // åªåå task èç¹ï¼é¿å
æè®¢å(project)èç¹å½æä»»å¡ä¿å |
| | | if (task.type !== gantt.config.types.task || !task.originalId) { |
| | | return; |
| | | } |
| | |
| | | color: #f44; |
| | | } |
| | | |
| | | /* å·¥åï¼projectï¼è¡æ ·å¼ */ |
| | | /* 订åï¼projectï¼è¡æ ·å¼ */ |
| | | .gantt-project-bar .gantt_task_progress { |
| | | background: #7b68ee; |
| | | } |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesProTaskApi } from '#/api/mes/pro/task'; |
| | | |
| | |
| | | const multiple = ref(false); // æ¯å¦å¤éï¼é»è®¤æåééæ©å¨ä½¿ç¨ |
| | | const selectedRows = ref<MesProTaskApi.Task[]>([]); // å·²éä»»å¡å表 |
| | | const preSelectedIds = ref<number[]>([]); // é¢éä»»å¡ç¼å·å表 |
| | | const externalWorkOrderId = ref<number>(); // å¤é¨ä¼ å
¥çé»è®¤å·¥åè¿æ»¤ |
| | | const externalWorkOrderId = ref<number>(); // å¤é¨ä¼ å
¥çé»è®¤è®¢åè¿æ»¤ |
| | | const externalWorkstationId = ref<number>(); // å¤é¨ä¼ å
¥çé»è®¤å·¥ä½è¿æ»¤ |
| | | |
| | | const statusTip = computed(() => { |
| | |
| | | }, |
| | | }); |
| | | |
| | | /** éç½®æ¥è¯¢åéæ©ç¶æï¼ä¿çå¤é¨ä¼ å
¥çå·¥å/å·¥ä½é»è®¤è¿æ»¤ */ |
| | | /** éç½®æ¥è¯¢åéæ©ç¶æï¼ä¿çå¤é¨ä¼ å
¥ç订å/å·¥ä½é»è®¤è¿æ»¤ */ |
| | | async function resetQueryState() { |
| | | selectedRows.value = []; |
| | | await gridApi.grid.clearCheckboxRow(); |
| | |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesProTaskApi } from '#/api/mes/pro/task'; |
| | | import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder'; |
| | |
| | | import { RouteColorPicker } from '#/views/mes/process-design/route/components'; |
| | | import { ProWorkOrderSelect } from '#/views/mes/pro/workorder/components'; |
| | | |
| | | /** å¾
æäº§å·¥åå表çæç´¢è¡¨å */ |
| | | /** å¾
æäº§è®¢åå表çæç´¢è¡¨å */ |
| | | export function useGridFormSchema(): VbenFormSchema[] { |
| | | return [ |
| | | { |
| | | fieldName: 'code', |
| | | label: 'å·¥åç¼ç ', |
| | | label: '订åç¼ç ', |
| | | component: 'Input', |
| | | componentProps: { |
| | | allowClear: true, |
| | | placeholder: '请è¾å
¥å·¥åç¼ç ', |
| | | placeholder: '请è¾å
¥è®¢åç¼ç ', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'name', |
| | | label: 'å·¥ååç§°', |
| | | label: '订ååç§°', |
| | | component: 'Input', |
| | | componentProps: { |
| | | allowClear: true, |
| | | placeholder: '请è¾å
¥å·¥ååç§°', |
| | | placeholder: '请è¾å
¥è®¢ååç§°', |
| | | }, |
| | | }, |
| | | { |
| | |
| | | ]; |
| | | } |
| | | |
| | | /** å¾
æäº§å·¥åå表çåæ®µ */ |
| | | /** å¾
æäº§è®¢åå表çåæ®µ */ |
| | | export function useGridColumns(): VxeTableGridOptions<MesProWorkOrderApi.WorkOrder>['columns'] { |
| | | return [ |
| | | { |
| | | field: 'code', |
| | | title: 'å·¥åç¼ç ', |
| | | title: '订åç¼ç ', |
| | | fixed: 'left', |
| | | width: 200, |
| | | treeNode: true, |
| | |
| | | }, |
| | | { |
| | | field: 'name', |
| | | title: 'å·¥ååç§°', |
| | | title: '订ååç§°', |
| | | minWidth: 150, |
| | | }, |
| | | { |
| | | field: 'orderSourceType', |
| | | title: '工忥æº', |
| | | title: 'è®¢åæ¥æº', |
| | | width: 100, |
| | | cellRender: { |
| | | name: 'CellDict', |
| | |
| | | }, |
| | | { |
| | | field: 'quantity', |
| | | title: '工忰é', |
| | | title: 'è®¢åæ°é', |
| | | width: 100, |
| | | }, |
| | | { |
| | |
| | | ]; |
| | | } |
| | | |
| | | /** æäº§å¯¹è¯æ¡åªè¯»å·¥åä¿¡æ¯ç表å */ |
| | | /** æäº§å¯¹è¯æ¡åªè¯»è®¢åä¿¡æ¯ç表å */ |
| | | export function useScheduleFormSchema(): VbenFormSchema[] { |
| | | return [ |
| | | { |
| | | fieldName: 'code', |
| | | label: 'å·¥åç¼ç ', |
| | | label: '订åç¼ç ', |
| | | component: 'Input', |
| | | componentProps: { |
| | | disabled: true, |
| | |
| | | }, |
| | | { |
| | | fieldName: 'name', |
| | | label: 'å·¥ååç§°', |
| | | label: '订ååç§°', |
| | | component: 'Input', |
| | | componentProps: { |
| | | disabled: true, |
| | |
| | | }, |
| | | { |
| | | fieldName: 'orderSourceType', |
| | | label: '工忥æº', |
| | | label: 'è®¢åæ¥æº', |
| | | component: 'Select', |
| | | componentProps: { |
| | | disabled: true, |
| | |
| | | }, |
| | | { |
| | | fieldName: 'type', |
| | | label: 'å·¥åç±»å', |
| | | label: '订åç±»å', |
| | | component: 'Select', |
| | | componentProps: { |
| | | disabled: true, |
| | |
| | | }, |
| | | { |
| | | fieldName: 'quantity', |
| | | label: '工忰é', |
| | | label: 'è®¢åæ°é', |
| | | component: 'InputNumber', |
| | | componentProps: { |
| | | class: '!w-full', |
| | |
| | | }, |
| | | { |
| | | fieldName: 'status', |
| | | label: 'å·¥åç¶æ', |
| | | label: '订åç¶æ', |
| | | component: 'Select', |
| | | componentProps: { |
| | | disabled: true, |
| | |
| | | return [ |
| | | { |
| | | fieldName: 'workOrderId', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | allowClear: true, |
| | | placeholder: 'è¯·éæ©ç产工å', |
| | | placeholder: 'è¯·éæ©ç产订å', |
| | | }, |
| | | }, |
| | | { |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder'; |
| | | |
| | |
| | | }); |
| | | } |
| | | |
| | | /** æ¥çå·¥å详æ
*/ |
| | | /** æ¥ç订å详æ
*/ |
| | | function handleDetail(row: MesProWorkOrderApi.WorkOrder) { |
| | | scheduleModalApi.setData({ formType: 'detail', id: row.id }).open(); |
| | | } |
| | |
| | | <GanttChart :height="350" :readonly="true" :tasks="ganttTasks" /> |
| | | </Card> |
| | | |
| | | <Grid table-title="å¾
æäº§å·¥å"> |
| | | <Grid table-title="å¾
æäº§è®¢å"> |
| | | <template #toolbar-tools> |
| | | <TableAction |
| | | :actions="[ |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { MesProRouteProcessApi } from '#/api/mes/pro/route/process'; |
| | | import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder'; |
| | | |
| | |
| | | |
| | | const emit = defineEmits(['success']); |
| | | const formType = ref<'detail' | 'schedule'>('schedule'); |
| | | const workOrder = ref<MesProWorkOrderApi.WorkOrder>(); // å½åå·¥å详æ
|
| | | const workOrder = ref<MesProWorkOrderApi.WorkOrder>(); // å½å订å详æ
|
| | | const routeProcessList = ref<MesProRouteProcessApi.RouteProcess[]>([]); // å·¥èºè·¯çº¿å·¥åºå表 |
| | | const activeProcessStep = ref(0); // å½åå·¥åºæ¥éª¤ç´¢å¼ |
| | | const currentRouteId = ref(0); // å½åå·¥èºè·¯çº¿ç¼å· |
| | | |
| | | const isReadonly = computed(() => formType.value === 'detail'); // 详æ
æåªè¯» |
| | | const getTitle = computed(() => |
| | | formType.value === 'detail' ? 'å·¥å详æ
' : 'ç产æäº§', |
| | | formType.value === 'detail' ? '订å详æ
' : 'ç产æäº§', |
| | | ); |
| | | |
| | | const [Form, formApi] = useVbenForm({ |
| | |
| | | ); |
| | | } |
| | | |
| | | /** 宿工å */ |
| | | /** å®æè®¢å */ |
| | | async function handleFinish() { |
| | | if (!workOrder.value?.id) { |
| | | return; |
| | |
| | | modalApi.lock(); |
| | | try { |
| | | await finishWorkOrder(workOrder.value.id); |
| | | message.success('å·¥å已宿'); |
| | | message.success('订å已宿'); |
| | | await modalApi.close(); |
| | | emit('success'); |
| | | } finally { |
| | |
| | | <div class="flex flex-auto items-center gap-2"> |
| | | <Popconfirm |
| | | v-if="formType === 'schedule'" |
| | | title="确认è¦å®æè¯¥å·¥ååï¼å®æåå·¥å䏿æä»»å¡å°æ è®°ä¸ºå·²å®æã" |
| | | title="确认è¦å®æè¯¥è®¢ååï¼å®æå订å䏿æä»»å¡å°æ è®°ä¸ºå·²å®æã" |
| | | @confirm="handleFinish" |
| | | > |
| | | <Button type="primary">宿</Button> |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { MesProTaskApi } from '#/api/mes/pro/task'; |
| | | |
| | | import { computed, ref } from 'vue'; |
| | |
| | | processId?: number; |
| | | routeId?: number; |
| | | workOrderId?: number; |
| | | }>({}); // æ°å¢ä»»å¡æ¶çå·¥å / å·¥åºä¸ä¸æ |
| | | }>({}); // æ°å¢ä»»å¡æ¶ç订å / å·¥åºä¸ä¸æ |
| | | |
| | | const getTitle = computed(() => { |
| | | return formData.value?.id |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder'; |
| | | |
| | |
| | | |
| | | const open = ref(false); // å¼¹çªæ¯å¦æå¼ |
| | | const multiple = ref(false); // æ¯å¦å¤éï¼é»è®¤æåééæ©å¨ä½¿ç¨ |
| | | const selectedRows = ref<MesProWorkOrderApi.WorkOrder[]>([]); // å·²éå·¥åå表 |
| | | const preSelectedIds = ref<number[]>([]); // é¢éå·¥åç¼å·å表 |
| | | const selectedRows = ref<MesProWorkOrderApi.WorkOrder[]>([]); // å·²é订åå表 |
| | | const preSelectedIds = ref<number[]>([]); // é¢é订åç¼å·å表 |
| | | |
| | | const typeTip = computed(() => { |
| | | if (props.type === undefined) { |
| | | return ''; |
| | | } |
| | | return `ä»
å±ç¤ºã${getDictLabel(DICT_TYPE.MES_PRO_WORK_ORDER_TYPE, props.type)}ãç±»åçå·¥å`; |
| | | return `ä»
å±ç¤ºã${getDictLabel(DICT_TYPE.MES_PRO_WORK_ORDER_TYPE, props.type)}ãç±»åç订å`; |
| | | }); |
| | | |
| | | /** è·åå¤éè®°å½ï¼å
å« VXE reserve è·¨é¡µè®°å½ */ |
| | |
| | | handleConfirm(); |
| | | } |
| | | |
| | | /** åæ¾é¢éå·¥å */ |
| | | /** åæ¾é¢é订å */ |
| | | async function applyPreSelection() { |
| | | if (preSelectedIds.value.length === 0) { |
| | | return; |
| | |
| | | } |
| | | } |
| | | |
| | | /** æå¼å·¥åéæ©å¼¹çª */ |
| | | /** æå¼è®¢åéæ©å¼¹çª */ |
| | | async function openModal( |
| | | selectedIds?: number[], |
| | | options?: { multiple?: boolean }, |
| | |
| | | await applyPreSelection(); |
| | | } |
| | | |
| | | /** å
³éå·¥åéæ©å¼¹çª */ |
| | | /** å
³é订åéæ©å¼¹çª */ |
| | | function closeModal() { |
| | | open.value = false; |
| | | } |
| | | |
| | | /** ç¡®è®¤éæ©å·¥å */ |
| | | /** ç¡®è®¤éæ©è®¢å */ |
| | | function handleConfirm() { |
| | | const rows = multiple.value ? getMultipleSelectedRows() : selectedRows.value; |
| | | if (rows.length === 0) { |
| | |
| | | <template> |
| | | <Modal |
| | | v-model:open="open" |
| | | title="ç产工åéæ©" |
| | | title="ç产订åéæ©" |
| | | width="80%" |
| | | :destroy-on-close="true" |
| | | @ok="handleConfirm" |
| | |
| | | show-icon |
| | | class="!mb-3" |
| | | /> |
| | | <Grid table-title="ç产工åå表" /> |
| | | <Grid table-title="ç产订åå表" /> |
| | | <template #footer> |
| | | <Button @click="closeModal">åæ¶</Button> |
| | | <Button type="primary" @click="handleConfirm">ç¡®å®</Button> |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder'; |
| | | |
| | | import { computed, ref, useAttrs, watch } from 'vue'; |
| | |
| | | allowClear: true, |
| | | disabled: false, |
| | | modelValue: undefined, |
| | | placeholder: 'è¯·éæ©å·¥å', |
| | | placeholder: 'è¯·éæ©è®¢å', |
| | | status: undefined, |
| | | type: undefined, |
| | | }, |
| | |
| | | }>(); |
| | | |
| | | const attrs = useAttrs(); // éä¼ å±æ§ |
| | | const dialogRef = ref<InstanceType<typeof ProWorkOrderSelectDialog>>(); // å·¥åéæ©å¼¹çª |
| | | const dialogRef = ref<InstanceType<typeof ProWorkOrderSelectDialog>>(); // 订åéæ©å¼¹çª |
| | | const hovering = ref(false); // æ¯å¦æ¬å |
| | | const selectedItem = ref<MesProWorkOrderApi.WorkOrder>(); // å½åéä¸å·¥å |
| | | const selectedItem = ref<MesProWorkOrderApi.WorkOrder>(); // å½åéä¸è®¢å |
| | | |
| | | const displayLabel = computed(() => selectedItem.value?.code ?? ''); // éæ©å¨å±ç¤ºç¼ç |
| | | const showClear = computed( |
| | |
| | | props.modelValue !== null, |
| | | ); |
| | | |
| | | /** æ ¹æ®ç¼å·åæ¡æ¥è¯¢å·¥åä¿¡æ¯ï¼ç¨äºç¼è¾åæ¾ï¼ */ |
| | | /** æ ¹æ®ç¼å·åæ¡æ¥è¯¢è®¢åä¿¡æ¯ï¼ç¨äºç¼è¾åæ¾ï¼ */ |
| | | async function resolveItemById(id: number | undefined) { |
| | | if (!id) { |
| | | selectedItem.value = undefined; |
| | |
| | | |
| | | watch(() => props.modelValue, resolveItemById, { immediate: true }); |
| | | |
| | | /** æ¸
空已éå·¥å */ |
| | | /** æ¸
空已é订å */ |
| | | function clearSelected() { |
| | | selectedItem.value = undefined; |
| | | emit('update:modelValue', undefined); |
| | | emit('change', undefined); |
| | | } |
| | | |
| | | /** æå¼å·¥åéæ©å¼¹çª */ |
| | | /** æå¼è®¢åéæ©å¼¹çª */ |
| | | function handleClick(event: MouseEvent) { |
| | | if (props.disabled) { |
| | | return; |
| | |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesMdProductBomApi } from '#/api/mes/md/item/productBom'; |
| | | import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder'; |
| | |
| | | }, |
| | | { |
| | | fieldName: 'status', |
| | | label: 'å·¥åç¶æ', |
| | | label: '订åç¶æ', |
| | | component: 'Select', |
| | | componentProps: { |
| | | disabled: true, |
| | |
| | | }, |
| | | { |
| | | fieldName: 'code', |
| | | label: 'å·¥åç¼ç ', |
| | | label: '订åç¼ç ', |
| | | component: 'Input', |
| | | componentProps: { |
| | | disabled: headerReadonly, |
| | | placeholder: '请è¾å
¥å·¥åç¼ç ', |
| | | placeholder: '请è¾å
¥è®¢åç¼ç ', |
| | | }, |
| | | rules: 'required', |
| | | suffix: |
| | |
| | | }, |
| | | { |
| | | fieldName: 'name', |
| | | label: 'å·¥ååç§°', |
| | | label: '订ååç§°', |
| | | component: 'Input', |
| | | componentProps: { |
| | | disabled: headerReadonly, |
| | | placeholder: '请è¾å
¥å·¥ååç§°', |
| | | placeholder: '请è¾å
¥è®¢ååç§°', |
| | | }, |
| | | rules: 'required', |
| | | }, |
| | | { |
| | | fieldName: 'orderSourceType', |
| | | label: '工忥æº', |
| | | label: 'è®¢åæ¥æº', |
| | | component: 'Select', |
| | | componentProps: { |
| | | disabled: headerReadonly, |
| | |
| | | DICT_TYPE.MES_PRO_WORK_ORDER_SOURCE_TYPE, |
| | | 'number', |
| | | ), |
| | | placeholder: 'è¯·éæ©å·¥åæ¥æº', |
| | | // 工忥æºåæ´ï¼é客æ·è®¢åæ¶æ¸
ç©ºæ¥æºåæ®ç¼å·åå®¢æ· |
| | | placeholder: 'è¯·éæ©è®¢åæ¥æº', |
| | | // è®¢åæ¥æºåæ´ï¼é客æ·è®¢åæ¶æ¸
ç©ºæ¥æºåæ®ç¼å·åå®¢æ· |
| | | onChange: async (value: number) => { |
| | | if (value !== MesProWorkOrderSourceTypeEnum.ORDER) { |
| | | await formApi?.setValues({ |
| | |
| | | }, |
| | | { |
| | | fieldName: 'type', |
| | | label: 'å·¥åç±»å', |
| | | label: '订åç±»å', |
| | | component: 'Select', |
| | | componentProps: { |
| | | disabled: headerReadonly, |
| | | options: getDictOptions(DICT_TYPE.MES_PRO_WORK_ORDER_TYPE, 'number'), |
| | | placeholder: 'è¯·éæ©å·¥åç±»å', |
| | | // å·¥åç±»ååæ´ï¼é代工/éè´æ¶æ¸
空ä¾åºå |
| | | placeholder: 'è¯·éæ©è®¢åç±»å', |
| | | // 订åç±»ååæ´ï¼é代工/éè´æ¶æ¸
空ä¾åºå |
| | | onChange: async (value: number) => { |
| | | if ( |
| | | value !== MesProWorkOrderTypeEnum.OUTSOURCE && |
| | |
| | | }, |
| | | { |
| | | fieldName: 'quantity', |
| | | label: '工忰é', |
| | | label: 'è®¢åæ°é', |
| | | component: 'InputNumber', |
| | | componentProps: { |
| | | class: '!w-full', |
| | | disabled: headerReadonly, |
| | | min: 1, |
| | | placeholder: '请è¾å
¥å·¥åæ°é', |
| | | placeholder: '请è¾å
¥è®¢åæ°é', |
| | | precision: 2, |
| | | }, |
| | | rules: 'required', |
| | |
| | | return [ |
| | | { |
| | | fieldName: 'code', |
| | | label: 'å·¥åç¼ç ', |
| | | label: '订åç¼ç ', |
| | | component: 'Input', |
| | | componentProps: { |
| | | allowClear: true, |
| | | placeholder: '请è¾å
¥å·¥åç¼ç ', |
| | | placeholder: '请è¾å
¥è®¢åç¼ç ', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'name', |
| | | label: 'å·¥ååç§°', |
| | | label: '订ååç§°', |
| | | component: 'Input', |
| | | componentProps: { |
| | | allowClear: true, |
| | | placeholder: '请è¾å
¥å·¥ååç§°', |
| | | placeholder: '请è¾å
¥è®¢ååç§°', |
| | | }, |
| | | }, |
| | | { |
| | |
| | | }, |
| | | { |
| | | fieldName: 'type', |
| | | label: 'å·¥åç±»å', |
| | | label: '订åç±»å', |
| | | component: 'Select', |
| | | componentProps: { |
| | | allowClear: true, |
| | | options: getDictOptions(DICT_TYPE.MES_PRO_WORK_ORDER_TYPE, 'number'), |
| | | placeholder: 'è¯·éæ©å·¥åç±»å', |
| | | placeholder: 'è¯·éæ©è®¢åç±»å', |
| | | }, |
| | | }, |
| | | { |
| | |
| | | return [ |
| | | { |
| | | field: 'code', |
| | | title: 'å·¥åç¼ç ', |
| | | title: '订åç¼ç ', |
| | | fixed: 'left', |
| | | width: 200, |
| | | treeNode: true, |
| | |
| | | }, |
| | | { |
| | | field: 'name', |
| | | title: 'å·¥ååç§°', |
| | | title: '订ååç§°', |
| | | minWidth: 150, |
| | | }, |
| | | { |
| | | field: 'type', |
| | | title: 'å·¥åç±»å', |
| | | title: '订åç±»å', |
| | | width: 100, |
| | | cellRender: { |
| | | name: 'CellDict', |
| | |
| | | }, |
| | | { |
| | | field: 'orderSourceType', |
| | | title: '工忥æº', |
| | | title: 'è®¢åæ¥æº', |
| | | width: 100, |
| | | cellRender: { |
| | | name: 'CellDict', |
| | |
| | | }, |
| | | { |
| | | field: 'quantity', |
| | | title: '工忰é', |
| | | title: 'è®¢åæ°é', |
| | | width: 100, |
| | | }, |
| | | { |
| | |
| | | }, |
| | | { |
| | | field: 'status', |
| | | title: 'å·¥åç¶æ', |
| | | title: '订åç¶æ', |
| | | width: 100, |
| | | cellRender: { |
| | | name: 'CellDict', |
| | |
| | | ]; |
| | | } |
| | | |
| | | /** å·¥å BOM å表çåæ®µ */ |
| | | /** 订å BOM å表çåæ®µ */ |
| | | export function useBomGridColumns( |
| | | editable: boolean, |
| | | generatable: boolean, |
| | |
| | | ]; |
| | | } |
| | | |
| | | /** å·¥å BOM æ°å¢/ä¿®æ¹ç表å */ |
| | | /** 订å BOM æ°å¢/ä¿®æ¹ç表å */ |
| | | export function useBomFormSchema( |
| | | isCreate: boolean, |
| | | productId?: number, |
| | |
| | | ]; |
| | | } |
| | | |
| | | /** å·¥å鿩弹çªçæç´¢è¡¨å */ |
| | | /** 订å鿩弹çªçæç´¢è¡¨å */ |
| | | export function useWorkOrderSelectGridFormSchema(): VbenFormSchema[] { |
| | | return [ |
| | | { |
| | | fieldName: 'code', |
| | | label: 'å·¥åç¼ç ', |
| | | label: '订åç¼ç ', |
| | | component: 'Input', |
| | | componentProps: { |
| | | allowClear: true, |
| | | placeholder: '请è¾å
¥å·¥åç¼ç ', |
| | | placeholder: '请è¾å
¥è®¢åç¼ç ', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'name', |
| | | label: 'å·¥ååç§°', |
| | | label: '订ååç§°', |
| | | component: 'Input', |
| | | componentProps: { |
| | | allowClear: true, |
| | | placeholder: '请è¾å
¥å·¥ååç§°', |
| | | placeholder: '请è¾å
¥è®¢ååç§°', |
| | | }, |
| | | }, |
| | | { |
| | |
| | | }, |
| | | { |
| | | fieldName: 'status', |
| | | label: 'å·¥åç¶æ', |
| | | label: '订åç¶æ', |
| | | component: 'Select', |
| | | componentProps: { |
| | | allowClear: true, |
| | | options: getDictOptions(DICT_TYPE.MES_PRO_WORK_ORDER_STATUS, 'number'), |
| | | placeholder: 'è¯·éæ©å·¥åç¶æ', |
| | | placeholder: 'è¯·éæ©è®¢åç¶æ', |
| | | }, |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | /** å·¥å鿩弹çªçåæ®µ */ |
| | | /** 订å鿩弹çªçåæ®µ */ |
| | | export function useWorkOrderSelectGridColumns( |
| | | multiple = false, |
| | | ): VxeTableGridOptions<MesProWorkOrderApi.WorkOrder>['columns'] { |
| | |
| | | }, |
| | | { |
| | | field: 'code', |
| | | title: 'å·¥åç¼ç ', |
| | | title: '订åç¼ç ', |
| | | width: 180, |
| | | }, |
| | | { |
| | | field: 'name', |
| | | title: 'å·¥ååç§°', |
| | | title: '订ååç§°', |
| | | minWidth: 180, |
| | | }, |
| | | { |
| | | field: 'orderSourceType', |
| | | title: '工忥æº', |
| | | title: 'è®¢åæ¥æº', |
| | | width: 100, |
| | | cellRender: { |
| | | name: 'CellDict', |
| | |
| | | }, |
| | | { |
| | | field: 'quantity', |
| | | title: '工忰é', |
| | | title: 'è®¢åæ°é', |
| | | width: 100, |
| | | }, |
| | | { |
| | |
| | | }, |
| | | { |
| | | field: 'status', |
| | | title: 'å·¥åç¶æ', |
| | | title: '订åç¶æ', |
| | | width: 100, |
| | | cellRender: { |
| | | name: 'CellDict', |
| | |
| | | ]; |
| | | } |
| | | |
| | | /** å·¥åç©æéæ±å表çåæ®µï¼åªè¯»ï¼ */ |
| | | /** 订åç©æéæ±å表çåæ®µï¼åªè¯»ï¼ */ |
| | | export function useItemGridColumns(): VxeTableGridOptions<MesProWorkOrderBomApi.WorkOrderBom>['columns'] { |
| | | return [ |
| | | { |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder'; |
| | | |
| | |
| | | gridApi.query(); |
| | | } |
| | | |
| | | /** å建工å */ |
| | | /** å建订å */ |
| | | function handleCreate() { |
| | | formModalApi.setData({ formType: 'create' }).open(); |
| | | } |
| | | |
| | | /** æ°å¢åå·¥å */ |
| | | /** æ°å¢å订å */ |
| | | function handleAddChild(row: MesProWorkOrderApi.WorkOrder) { |
| | | formModalApi.setData({ formType: 'create', parentRow: row }).open(); |
| | | } |
| | | |
| | | /** æ¥çå·¥å详æ
*/ |
| | | /** æ¥ç订å详æ
*/ |
| | | function handleDetail(row: MesProWorkOrderApi.WorkOrder) { |
| | | formModalApi.setData({ formType: 'detail', id: row.id }).open(); |
| | | } |
| | | |
| | | /** ç¼è¾å·¥å */ |
| | | /** ç¼è¾è®¢å */ |
| | | function handleEdit(row: MesProWorkOrderApi.WorkOrder) { |
| | | formModalApi.setData({ formType: 'update', id: row.id }).open(); |
| | | } |
| | | |
| | | /** 宿工å */ |
| | | /** å®æè®¢å */ |
| | | function handleFinish(row: MesProWorkOrderApi.WorkOrder) { |
| | | formModalApi.setData({ formType: 'finish', id: row.id }).open(); |
| | | } |
| | | |
| | | /** å é¤å·¥å */ |
| | | /** å é¤è®¢å */ |
| | | async function handleDelete(row: MesProWorkOrderApi.WorkOrder) { |
| | | const hideLoading = message.loading({ |
| | | content: $t('ui.actionMessage.deleting', [row.code]), |
| | |
| | | } |
| | | } |
| | | |
| | | /** åæ¶å·¥å */ |
| | | /** åæ¶è®¢å */ |
| | | async function handleCancel(row: MesProWorkOrderApi.WorkOrder) { |
| | | await cancelWorkOrder(row.id!); |
| | | message.success('å·¥å已忶'); |
| | | message.success('订å已忶'); |
| | | handleRefresh(); |
| | | } |
| | | |
| | | /** æ¥ç工忡ç */ |
| | | /** æ¥çè®¢åæ¡ç */ |
| | | function handleBarcode(row: MesProWorkOrderApi.WorkOrder) { |
| | | barcodeDetailRef.value?.openByBusiness( |
| | | row.id!, |
| | |
| | | /** 导åºè¡¨æ ¼ */ |
| | | async function handleExport() { |
| | | const data = await exportWorkOrder(await gridApi.formApi.getValues()); |
| | | downloadFileFromBlobPart({ fileName: 'ç产工å.xls', source: data }); |
| | | downloadFileFromBlobPart({ fileName: 'ç产订å.xls', source: data }); |
| | | } |
| | | |
| | | const [Grid, gridApi] = useVbenVxeGrid({ |
| | |
| | | <template> |
| | | <Page auto-content-height><FormModal @success="handleRefresh" /> |
| | | |
| | | <Grid table-title="ç产工åå表"> |
| | | <Grid table-title="ç产订åå表"> |
| | | <template #toolbar-tools> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: $t('ui.actionTitle.create', ['å·¥å']), |
| | | label: $t('ui.actionTitle.create', ['订å']), |
| | | type: 'primary', |
| | | icon: ACTION_ICON.ADD, |
| | | auth: ['mes:pro-work-order:create'], |
| | |
| | | auth: ['mes:pro-work-order:update'], |
| | | ifShow: row.status === MesProWorkOrderStatusEnum.CONFIRMED, |
| | | popConfirm: { |
| | | title: '确认è¦åæ¶è¯¥å·¥ååï¼åæ¶åä¸å¯æ¢å¤ã', |
| | | title: '确认è¦åæ¶è¯¥è®¢ååï¼åæ¶åä¸å¯æ¢å¤ã', |
| | | confirm: handleCancel.bind(null, row), |
| | | }, |
| | | }, |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { MesProWorkOrderBomApi } from '#/api/mes/pro/workorder/bom'; |
| | | |
| | | import { computed, ref } from 'vue'; |
| | |
| | | |
| | | const emit = defineEmits(['success']); |
| | | const formData = ref<MesProWorkOrderBomApi.WorkOrderBom>(); |
| | | const workOrderId = ref<number>(); // æå±å·¥åç¼å· |
| | | const workOrderId = ref<number>(); // æå±è®¢åç¼å· |
| | | |
| | | const getTitle = computed(() => { |
| | | return formData.value?.id |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { FormType } from '../data'; |
| | | |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | |
| | | ); |
| | | const isConfirmed = computed( |
| | | () => |
| | | // 已确认æå¯çæåå·¥å |
| | | // 已确认æå¯çæå订å |
| | | props.workOrder.status === MesProWorkOrderStatusEnum.CONFIRMED, |
| | | ); |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | /** ä» BOM è¡çæåå·¥åï¼éç¥ç¶ç»ä»¶ï¼ */ |
| | | /** ä» BOM è¡çæå订åï¼éç¥ç¶ç»ä»¶ï¼ */ |
| | | function handleGenerateWorkOrder(row: MesProWorkOrderBomApi.WorkOrderBom) { |
| | | emit('generateWorkOrder', row); |
| | | } |
| | | |
| | | /** æ¯å¦å±ç¤ºçæåå·¥åæé®ï¼å·²ç¡®è®¤ + èªå¶ + 产åç±»å BOM è¡ */ |
| | | /** æ¯å¦å±ç¤ºçæå订åæé®ï¼å·²ç¡®è®¤ + èªå¶ + 产åç±»å BOM è¡ */ |
| | | function showGenerate(row: MesProWorkOrderBomApi.WorkOrderBom) { |
| | | return ( |
| | | isConfirmed.value && |
| | |
| | | <template> |
| | | <div> |
| | | <BomFormModal @success="handleRefresh" /> |
| | | <Grid table-title="å·¥å BOM"> |
| | | <Grid table-title="订å BOM"> |
| | | <template v-if="isEditable" #toolbar-tools> |
| | | <TableAction |
| | | :actions="[ |
| | |
| | | }, |
| | | }, |
| | | { |
| | | label: 'çæå·¥å', |
| | | label: 'çæè®¢å', |
| | | type: 'link', |
| | | ifShow: showGenerate(row), |
| | | onClick: handleGenerateWorkOrder.bind(null, row), |
| | |
| | | <script lang="ts" setup> |
| | | <script lang="ts" setup> |
| | | import type { FormType } from '../data'; |
| | | |
| | | import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder'; |
| | |
| | | const isChild = !!formData.value?.parentId; |
| | | switch (formType.value) { |
| | | case 'confirm': { |
| | | return '确认工å'; |
| | | return '确认订å'; |
| | | } |
| | | case 'detail': { |
| | | return $t('ui.actionTitle.view', ['å·¥å']); |
| | | return $t('ui.actionTitle.view', ['订å']); |
| | | } |
| | | case 'finish': { |
| | | return '宿工å'; |
| | | return 'å®æè®¢å'; |
| | | } |
| | | case 'update': { |
| | | return isChild ? 'ç¼è¾åå·¥å' : $t('ui.actionTitle.edit', ['å·¥å']); |
| | | return isChild ? 'ç¼è¾å订å' : $t('ui.actionTitle.edit', ['订å']); |
| | | } |
| | | default: { |
| | | return isChild ? 'æ°å¢åå·¥å' : $t('ui.actionTitle.create', ['å·¥å']); |
| | | return isChild ? 'æ°å¢å订å' : $t('ui.actionTitle.create', ['订å']); |
| | | } |
| | | } |
| | | }); |
| | |
| | | modalApi.setState({ showConfirmButton: isEditable.value }); |
| | | } |
| | | |
| | | /** æ¥ç工忡ç */ |
| | | /** æ¥çè®¢åæ¡ç */ |
| | | function handleBarcode() { |
| | | if (!formData.value?.id) { |
| | | return; |
| | |
| | | ); |
| | | } |
| | | |
| | | /** 确认工åï¼ç¼è¾ææä¿®æ¹æ¶å
ä¿åï¼å确认 */ |
| | | /** 确认订åï¼ç¼è¾ææä¿®æ¹æ¶å
ä¿åï¼å确认 */ |
| | | async function handleConfirm() { |
| | | const { valid } = await formApi.validate(); |
| | | if (!valid || !formData.value?.id) { |
| | |
| | | } |
| | | } |
| | | await confirmWorkOrder(formData.value.id); |
| | | message.success('å·¥å已确认'); |
| | | message.success('订å已确认'); |
| | | await modalApi.close(); |
| | | emit('success'); |
| | | } finally { |
| | |
| | | } |
| | | } |
| | | |
| | | /** 宿工å */ |
| | | /** å®æè®¢å */ |
| | | async function handleFinish() { |
| | | if (!formData.value?.id) { |
| | | return; |
| | |
| | | modalApi.lock(); |
| | | try { |
| | | await finishWorkOrder(formData.value.id); |
| | | message.success('å·¥å已宿'); |
| | | message.success('订å已宿'); |
| | | await modalApi.close(); |
| | | emit('success'); |
| | | } finally { |
| | |
| | | } |
| | | } |
| | | |
| | | /** ä» BOM ç©æè¡é¢å¡«åå·¥åï¼å¤ç¨å½åå·¥åä¸ä¸æï¼è¿å
¥æ°å¢æ */ |
| | | /** ä» BOM ç©æè¡é¢å¡«å订åï¼å¤ç¨å½å订åä¸ä¸æï¼è¿å
¥æ°å¢æ */ |
| | | async function handleGenerateWorkOrder( |
| | | bomRow: MesProWorkOrderBomApi.WorkOrderBom, |
| | | ) { |
| | |
| | | vendorId: current.vendorId, |
| | | }); |
| | | originalSnapshot.value = JSON.stringify(await formApi.getValues()); |
| | | message.info('å·²ä» BOM ç©æé¢å¡«åå·¥åï¼è¯·è¡¥å
å·¥åç¼ç çä¿¡æ¯åä¿å'); |
| | | message.info('å·²ä» BOM ç©æé¢å¡«å订åï¼è¯·è¡¥å
订åç¼ç çä¿¡æ¯åä¿å'); |
| | | } |
| | | |
| | | const [Modal, modalApi] = useVbenModal({ |
| | |
| | | status: MesProWorkOrderStatusEnum.PREPARE, |
| | | }; |
| | | formType.value = 'update'; |
| | | // å建æåå忢ç¼è¾æï¼éæ schema 让ãå·¥åç¶æãåæ®µæ¾ç° |
| | | // å建æåå忢ç¼è¾æï¼éæ schema 让ã订åç¶æãåæ®µæ¾ç° |
| | | applySchema(); |
| | | await formApi.setValues(formData.value); |
| | | } |
| | |
| | | modalApi.unlock(); |
| | | } |
| | | } else if (data?.parentRow) { |
| | | // æ°å¢å工忶ï¼é¢å¡«ç¶å·¥åä¿¡æ¯ |
| | | // æ°å¢åè®¢åæ¶ï¼é¢å¡«ç¶è®¢åä¿¡æ¯ |
| | | const parent = data.parentRow; |
| | | await formApi.setValues({ |
| | | clientId: parent.clientId, |
| | |
| | | <!-- BOM / ç©æéæ± Tabï¼éæ°å»ºæå±ç¤º --> |
| | | <template v-if="formData?.id"> |
| | | <Tabs v-model:active-key="subTabsName" class="mx-4"> |
| | | <Tabs.TabPane key="bom" tab="å·¥å BOM"> |
| | | <Tabs.TabPane key="bom" tab="订å BOM"> |
| | | <BomList |
| | | :form-type="formType" |
| | | :work-order="formData" |
| | |
| | | <div class="flex flex-auto items-center gap-2"> |
| | | <Popconfirm |
| | | v-if="canConfirm || isConfirm" |
| | | title="确认è¦å®æå·¥åç¼å¶åï¼ç¡®è®¤åå°ä¸è½æ´æ¹ã" |
| | | title="确认è¦å®æè®¢åç¼å¶åï¼ç¡®è®¤åå°ä¸è½æ´æ¹ã" |
| | | @confirm="handleConfirm" |
| | | > |
| | | <Button type="primary">确认</Button> |
| | | </Popconfirm> |
| | | <Popconfirm |
| | | v-if="isFinish" |
| | | title="确认è¦å®æè¯¥å·¥ååï¼" |
| | | title="确认è¦å®æè¯¥è®¢ååï¼" |
| | | @confirm="handleFinish" |
| | | > |
| | | <Button type="primary">宿</Button> |
| | |
| | | import type { VbenFormSchema } from '#/adapter/form'; |
| | | import type { VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesWmBatchApi } from '#/api/mes/wm/batch'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | |
| | | return [ |
| | | { |
| | | field: 'workOrderCode', |
| | | title: 'ç产工åå·', |
| | | title: 'ç产订åå·', |
| | | width: 160, |
| | | }, |
| | | { |
| | |
| | | }, |
| | | { |
| | | field: 'workOrderCode', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | }, |
| | | { |
| | | field: 'workstationCode', |
| | |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesQcIpqcApi } from '#/api/mes/qc/ipqc'; |
| | | import type { MesQcIpqcLineApi } from '#/api/mes/qc/ipqc/line'; |
| | |
| | | }, |
| | | { |
| | | fieldName: 'workOrderId', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©ç产工å', |
| | | placeholder: 'è¯·éæ©ç产订å', |
| | | status: MesProWorkOrderStatusEnum.CONFIRMED, |
| | | // å·¥ååæ´æ¶æ¸
空çäº§ä»»å¡ |
| | | // 订ååæ´æ¶æ¸
空çäº§ä»»å¡ |
| | | onChange: () => formApi?.setFieldValue('taskId', undefined), |
| | | }, |
| | | rules: 'selectRequired', |
| | |
| | | triggerFields: ['sourceDocId'], |
| | | componentProps: (values) => ({ |
| | | disabled: !!values.sourceDocId, |
| | | placeholder: 'è¯·éæ©ç产工å', |
| | | placeholder: 'è¯·éæ©ç产订å', |
| | | status: MesProWorkOrderStatusEnum.CONFIRMED, |
| | | onChange: () => formApi?.setFieldValue('taskId', undefined), |
| | | }), |
| | |
| | | }, |
| | | { |
| | | fieldName: 'workOrderId', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©ç产工å', |
| | | placeholder: 'è¯·éæ©ç产订å', |
| | | }, |
| | | }, |
| | | { |
| | |
| | | }, |
| | | { |
| | | field: 'workOrderCode', |
| | | title: 'ç产工åç¼å·', |
| | | title: 'ç产订åç¼å·', |
| | | width: 140, |
| | | }, |
| | | { |
| | |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesWmBarcodeApi } from '#/api/mes/wm/barcode'; |
| | | import type { MesWmBarcodeConfigApi } from '#/api/mes/wm/barcode/config'; |
| | |
| | | }, |
| | | { |
| | | fieldName: 'bizId', |
| | | label: 'å·¥å', |
| | | label: '订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | status: MesProWorkOrderStatusEnum.CONFIRMED, |
| | |
| | | import type { VbenFormSchema } from '#/adapter/form'; |
| | | import type { VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesWmBatchApi } from '#/api/mes/wm/batch'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | |
| | | }, |
| | | { |
| | | fieldName: 'workOrderId', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©ç产工å', |
| | | placeholder: 'è¯·éæ©ç产订å', |
| | | }, |
| | | }, |
| | | { |
| | |
| | | }, |
| | | { |
| | | field: 'workOrderCode', |
| | | title: 'å·¥åç¼ç ', |
| | | title: '订åç¼ç ', |
| | | width: 140, |
| | | }, |
| | | { |
| | |
| | | }, |
| | | { |
| | | field: 'workOrderCode', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | render: (value) => value || '-', |
| | | }, |
| | | { |
| | |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder'; |
| | | import type { MesWmMaterialStockApi } from '#/api/mes/wm/materialstock'; |
| | |
| | | }, |
| | | { |
| | | fieldName: 'workOrderId', |
| | | label: 'å¤åå·¥å', |
| | | label: 'å¤å订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | // éæ©å¤åå·¥ååï¼èªå¨åå¡«ä¾åºå |
| | | // éæ©å¤å订ååï¼èªå¨åå¡«ä¾åºå |
| | | onChange: async (workOrder?: MesProWorkOrderApi.WorkOrder) => { |
| | | await formApi?.setFieldValue('vendorId', workOrder?.vendorId); |
| | | }, |
| | |
| | | }, |
| | | { |
| | | field: 'workOrderCode', |
| | | title: 'ç产工åå·', |
| | | title: 'ç产订åå·', |
| | | minWidth: 140, |
| | | }, |
| | | { |
| | |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder'; |
| | | import type { MesWmOutsourceReceiptApi } from '#/api/mes/wm/outsourcereceipt'; |
| | |
| | | }, |
| | | { |
| | | fieldName: 'workOrderId', |
| | | label: 'å¤åå·¥å', |
| | | label: 'å¤å订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | // éæ©å¤åå·¥ååï¼èªå¨åå¡«ä¾åºå |
| | | // éæ©å¤å订ååï¼èªå¨åå¡«ä¾åºå |
| | | onChange: async (workOrder?: MesProWorkOrderApi.WorkOrder) => { |
| | | await formApi?.setFieldValue('vendorId', workOrder?.vendorId); |
| | | }, |
| | |
| | | }, |
| | | { |
| | | fieldName: 'workOrderCode', |
| | | label: 'å¤åå·¥åå·', |
| | | label: 'å¤å订åå·', |
| | | component: 'Input', |
| | | componentProps: { |
| | | allowClear: true, |
| | | placeholder: '请è¾å
¥å¤åå·¥åå·', |
| | | placeholder: '请è¾å
¥å¤å订åå·', |
| | | }, |
| | | }, |
| | | { |
| | |
| | | }, |
| | | { |
| | | field: 'workOrderCode', |
| | | title: 'å¤åå·¥åå·', |
| | | title: 'å¤å订åå·', |
| | | minWidth: 140, |
| | | }, |
| | | { |
| | |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesWmPackageApi } from '#/api/mes/wm/packages'; |
| | | import type { MesWmPackageLineApi } from '#/api/mes/wm/packages/line'; |
| | |
| | | return [ |
| | | { |
| | | fieldName: 'workOrderId', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©ç产工å', |
| | | placeholder: 'è¯·éæ©ç产订å', |
| | | status: MesProWorkOrderStatusEnum.CONFIRMED, |
| | | }, |
| | | rules: 'selectRequired', |
| | |
| | | }, |
| | | { |
| | | field: 'workOrderCode', |
| | | title: 'ç产工åç¼å·', |
| | | title: 'ç产订åç¼å·', |
| | | minWidth: 140, |
| | | }, |
| | | { |
| | |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesWmMaterialStockApi } from '#/api/mes/wm/materialstock'; |
| | | import type { MesWmProductIssueApi } from '#/api/mes/wm/productissue'; |
| | |
| | | }, |
| | | { |
| | | fieldName: 'workOrderId', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | status: MesProWorkOrderStatusEnum.CONFIRMED, |
| | |
| | | }, |
| | | { |
| | | field: 'workOrderCode', |
| | | title: 'ç产工å', |
| | | title: 'ç产订å', |
| | | minWidth: 140, |
| | | }, |
| | | { |
| | |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesWmMaterialStockApi } from '#/api/mes/wm/materialstock'; |
| | | import type { MesWmProductReceiptApi } from '#/api/mes/wm/productreceipt'; |
| | |
| | | }, |
| | | { |
| | | fieldName: 'workOrderId', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | status: MesProWorkOrderStatusEnum.CONFIRMED, |
| | |
| | | }, |
| | | { |
| | | field: 'workOrderCode', |
| | | title: 'ç产工å', |
| | | title: 'ç产订å', |
| | | minWidth: 140, |
| | | }, |
| | | { |
| | |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesWmMaterialStockApi } from '#/api/mes/wm/materialstock'; |
| | | import type { MesWmReturnIssueApi } from '#/api/mes/wm/returnissue'; |
| | |
| | | }, |
| | | { |
| | | fieldName: 'workOrderId', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | status: MesProWorkOrderStatusEnum.CONFIRMED, |
| | |
| | | }, |
| | | { |
| | | fieldName: 'workOrderId', |
| | | label: 'ç产工å', |
| | | label: 'ç产订å', |
| | | component: markRaw(ProWorkOrderSelect), |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©ç产工å', |
| | | placeholder: 'è¯·éæ©ç产订å', |
| | | }, |
| | | }, |
| | | { |
| | |
| | | }, |
| | | { |
| | | field: 'workOrderCode', |
| | | title: 'ç产工å', |
| | | title: 'ç产订å', |
| | | minWidth: 140, |
| | | }, |
| | | { |