| | |
| | | "VITE_JAVA_API": "http://114.132.189.42:9037" |
| | | }, |
| | | "screen": "screen/HYSNView.png", |
| | | "logo": "logo/ZGLTLogo.png", |
| | | "logo": "logo/LCLogo.png", |
| | | "favicon": "favicon/favicon.ico" |
| | | }, |
| | | "WDSY": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "ä¼å¾·å®ä¸ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:8068", |
| | | "VITE_JAVA_API": "http://114.132.189.42:8085" |
| | | }, |
| | | "screen": "screen/WDSYView.png", |
| | | "logo": "logo/WDSYLogo.png", |
| | | "favicon": "favicon/WDSYico.ico" |
| | | }, |
| | | "JZYJ": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "åºæºæ²¹äºä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:8078", |
| | | "VITE_JAVA_API": "http://114.132.189.42:8086" |
| | | }, |
| | | "screen": "screen/JZYJView.png", |
| | | "logo": "logo/JZYJLogo.png", |
| | | "favicon": "favicon/JZYJico.ico" |
| | | }, |
| | | "ZQHX": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "ä¸å¼ºæå
´ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:1234", |
| | | "VITE_JAVA_API": "http://114.132.189.42:8080" |
| | | }, |
| | | "screen": "screen/ZQHXView.png", |
| | | "logo": "logo/ZQHXLogo.png", |
| | | "favicon": "favicon/ZQHXico.ico" |
| | | }, |
| | | "XYHB": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "宣屹ç¯ä¿ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9052", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9051" |
| | | }, |
| | | "screen": "screen/XYHBView.png", |
| | | "logo": "logo/XYHBLogo.png", |
| | | "favicon": "favicon/XYHBico.ico" |
| | | }, |
| | | "BHMY": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "åå®ç
¤ä¸ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9070", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9069" |
| | | }, |
| | | "screen": "screen/ZQHXView.png", |
| | | "logo": "logo/BHMYLogo.png", |
| | | "favicon": "favicon/BHMY.ico" |
| | | }, |
| | | "HHKJ": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "ææç§æä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9046", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9047" |
| | | }, |
| | | "screen": "screen/HHKJView.png", |
| | | "logo": "logo/HHKJLogo.png", |
| | | "favicon": "favicon/HHKJIco.ico" |
| | | }, |
| | | "RZNY": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "éæ©è½æºä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9058", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9057" |
| | | }, |
| | | "screen": "screen/RZNYView.png", |
| | | "logo": "logo/RZNYLogo.png", |
| | | "favicon": "favicon/RZNY.ico" |
| | | }, |
| | | "TJXM": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "æ³°æ±æ´ç
¤ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9064", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9063" |
| | | }, |
| | | "screen": "screen/TJXMView.png", |
| | | "logo": "logo/TJXMLogo.png", |
| | | "favicon": "favicon/TJXM.ico" |
| | | }, |
| | | "HYSN": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "å¼ä¹æ°´æ³¥ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9034", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9035" |
| | | }, |
| | | "screen": "screen/HYSNView.png", |
| | | "logo": "logo/HYSNLogo.png", |
| | | "favicon": "favicon/HYSNico.ico" |
| | | }, |
| | | "JYHJ": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "éé¹°é»éä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9030", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9031" |
| | | }, |
| | | "screen": "screen/HYSNView.png", |
| | | "logo": "logo/JYHJLogo.png", |
| | | "favicon": "favicon/JYHJico.ico" |
| | | }, |
| | | "DHDC": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "æ¦ç
é¼è¯ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9032", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9033" |
| | | }, |
| | | "screen": "screen/DHDCView.png", |
| | | "logo": "logo/DHDCLogo.png", |
| | | "favicon": "favicon/DHDCico.ico" |
| | | }, |
| | | "MXSC": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "é½å
´ç³æä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9048", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9049" |
| | | }, |
| | | "screen": "screen/MXSCBack.png", |
| | | "logo": "logo/MXSCLogo.png", |
| | | "favicon": "favicon/MXSCIco.ico" |
| | | }, |
| | | "CJNY": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "åå·¨è½æºä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9038", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9039" |
| | | }, |
| | | "screen": "screen/MXSCBack.png", |
| | | "logo": "logo/CJNYLogo.png", |
| | | "favicon": "favicon/CJNYico.ico" |
| | | }, |
| | | "JSMY": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "éç³ç
¤ä¸ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9042", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9043" |
| | | }, |
| | | "screen": "screen/MXSCBack.png", |
| | | "logo": "logo/JSMYLogo.png", |
| | | "favicon": "favicon/JSMYico.ico" |
| | | }, |
| | | "JSYNY": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "é¦çæºè½æºä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9074", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9073" |
| | | }, |
| | | "screen": "screen/HYSNView.png", |
| | | "logo": "logo/JSYNYLogo.png", |
| | | "favicon": "favicon/JSYNYico.ico" |
| | | }, |
| | | "CMNY": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "åéè½æºä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9088", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9087" |
| | | }, |
| | | "screen": "screen/DHDCView.png", |
| | | "logo": "logo/CMNYLogo.png", |
| | | "favicon": "favicon/CMNYico.ico" |
| | | }, |
| | | "HCKX": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "æµ·å·å¼å¿é£åä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9090", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9089" |
| | | }, |
| | | "screen": "screen/HCKXView.png", |
| | | "logo": "logo/HCKXLogo.png", |
| | | "favicon": "favicon/HCKXico.ico" |
| | | }, |
| | | "JLSN": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "é¦é¾æ°´æ³¥ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9094", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9093" |
| | | }, |
| | | "screen": "screen/JLSNView.png", |
| | | "logo": "logo/JLSNLogo.png", |
| | | "favicon": "favicon/JLSNico.ico" |
| | | }, |
| | | "BDSM": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "åè¾¾å贸信æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9096", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9095" |
| | | }, |
| | | "screen": "screen/BDSMView.png", |
| | | "logo": "logo/BDSMLogo.png", |
| | | "favicon": "favicon/BDSMico.ico" |
| | | }, |
| | | "HXGY": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "æ±æéä¸ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9098", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9097" |
| | | }, |
| | | "screen": "screen/HXGYView.png", |
| | | "logo": "logo/HXGYLogo.png", |
| | | "favicon": "favicon/HXGYico.ico" |
| | | }, |
| | | "ZDXM": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "æå¾·åç
¤ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9100", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9096" |
| | | }, |
| | | "screen": "screen/ZDXMView.png", |
| | | "logo": "logo/ZDXMLogo.png", |
| | | "favicon": "favicon/ZDXMico.ico" |
| | | }, |
| | | "HSX": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "æ¹æ°´å³¡åä¸åå±ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9101", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9098" |
| | | }, |
| | | "screen": "screen/HSXView.png", |
| | | "logo": "logo/HSXLogo.png", |
| | | "favicon": "favicon/HSXico.ico" |
| | | }, |
| | | "NYDL": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "åæ´çµç¼äº§é¾éä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9036", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9037" |
| | | }, |
| | | "screen": "screen/NYDLView.png", |
| | | "logo": "logo/NYDLLogo.png", |
| | | "favicon": "favicon/NYDLico.ico" |
| | | }, |
| | | "HCMY": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "浩æç
¤ä¸ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9103", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9094" |
| | | }, |
| | | "screen": "screen/HCMYView.png", |
| | | "logo": "logo/HCMYLogo.png", |
| | | "favicon": "favicon/HCMYico.ico" |
| | | }, |
| | | "HGJJ": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "æ±å½æ´ååç
¤ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9107", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9090" |
| | | }, |
| | | "screen": "screen/HGJJView.png", |
| | | "logo": "logo/HGJJLogo.png", |
| | | "favicon": "favicon/HGJJico.ico" |
| | | }, |
| | | "MKZS": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "模å¯åçä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9111", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9086" |
| | | }, |
| | | "screen": "screen/MKZSView.png", |
| | | "logo": "logo/MKZSLogo.png", |
| | | "favicon": "favicon/MKZSico.ico" |
| | | }, |
| | | "HSMY": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "å顺éä¸ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9115", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9082" |
| | | }, |
| | | "screen": "screen/HSMYView.png", |
| | | "logo": "logo/HSMYLogo.png", |
| | | "favicon": "favicon/HSMYico.ico" |
| | | }, |
| | | "DHHB": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "丹海ç¯ä¿ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9117", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9080" |
| | | }, |
| | | "screen": "screen/DHHBView.png", |
| | | "logo": "logo/DHHBLogo.png", |
| | | "favicon": "favicon/DHHBico.ico" |
| | | }, |
| | | "PHMK": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "æ®ç¦¾ç
¤ç¿ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9119", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9078" |
| | | }, |
| | | "screen": "screen/PHMKView.png", |
| | | "logo": "logo/PHMKLogo.png", |
| | | "favicon": "favicon/PHMKico.ico" |
| | | }, |
| | | "TYMK": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "éæºç
¤ç¿ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9121", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9076" |
| | | }, |
| | | "screen": "screen/TYMKView.png", |
| | | "logo": "logo/TYMKLogo.png", |
| | | "favicon": "favicon/TYMKico.ico" |
| | | }, |
| | | "LQM": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "èçªéº¦é£åä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9123", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9074" |
| | | }, |
| | | "screen": "screen/LQMView.png", |
| | | "logo": "logo/LQMLogo.png", |
| | | "favicon": "favicon/LQMico.ico" |
| | | }, |
| | | "ZYRQ": { |
| | | "env": { |
| | | "VITE_APP_TITLE": "伿ºçæ°ä¿¡æ¯ç®¡çç³»ç»", |
| | | "VITE_BASE_API": "http://114.132.189.42:9123", |
| | | "VITE_JAVA_API": "http://114.132.189.42:9031" |
| | | }, |
| | | "screen": "screen/ZYRQView.png", |
| | | "logo": "logo/ZYRQLogo.png", |
| | | "favicon": "favicon/ZYRQico.ico" |
| | | }, |
| | | "screen": "/src/assets/images/login-background.png", |
| | | "logo": "/src/assets/logo/logo.png", |
| | | "favicon": "/public/favicon.ico" |
| | |
| | | data: query, |
| | | }); |
| | | } |
| | | // å é¤è®°å½ |
| | | export function ledgerRecordDelete(ids) { |
| | | return request({ |
| | | url: "/measuringInstrumentLedgerRecord/delete", |
| | | method: "delete", |
| | | data: ids, |
| | | }); |
| | | } |
| | |
| | | }); |
| | | }; |
| | | |
| | | // æ¥è¯¢ç产å
¥åºä¿¡æ¯å表 |
| | | export const getStockInPageByProduction = (params) => { |
| | | return request({ |
| | | url: "/stockin/listPageByProduction", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | // åºåºå°è´¦-æ¥è¯¢èªå®ä¹å
¥åºä¿¡æ¯å表 |
| | | export const getStockInPageByCustom = (params) => { |
| | | return request({ |
| | | url: "/stockmanagement/listPageByCustom", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | // å
¥åºç®¡ç-æ¥è¯¢èªå®ä¹å
¥åºä¿¡æ¯å表 |
| | | export const getInPageByCustom = (params) => { |
| | | return request({ |
| | | url: "/stockin/listPageByCustom", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | // åºåºå°è´¦-æ¥è¯¢ç产åºåºä¿¡æ¯å表 |
| | | export const getStockInPageByProduct = (params) => { |
| | | return request({ |
| | | url: "/stockmanagement/listPageByProduct", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | // ä¿®æ¹å
¥åºåä¿¡æ¯ |
| | | export const updateStockIn = (data) => { |
| | | return request({ |
| | |
| | | data, |
| | | }); |
| | | }; |
| | | // ä¿®æ¹ææåºåä¿¡æ¯ |
| | | export const updateManagementByCustom = (data) => { |
| | | return request({ |
| | | url: "/stockin/updateManagementByCustom ", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | }; |
| | | |
| | | // æ°å¢ååå
¥åºä¿¡æ¯ |
| | | export function addSutockIn(data) { |
| | |
| | | }) |
| | | } |
| | | |
| | | // æ°å¢èªå®ä¹å
¥åºä¿¡æ¯ |
| | | export function addStockInCustom(data) { |
| | | return request({ |
| | | url: '/stockin/addCustom', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ç¼è¾èªå®ä¹å
¥åºä¿¡æ¯ |
| | | export function updateStockInCustom(data) { |
| | | return request({ |
| | | url: '/stockin/updateCustom', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | // ç¼è¾æåå
¥åºä¿¡æ¯ |
| | | export function updateProduct(data) { |
| | | return request({ |
| | | url: '/stockin/update', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // å é¤å
¥åºä¿¡æ¯ |
| | | export function delStockIn(ids) { |
| | | return request({ |
| | |
| | | }) |
| | | } |
| | | |
| | | // å é¤èªå®ä¹å
¥åºä¿¡æ¯ |
| | | export function delStockInCustom(ids) { |
| | | return request({ |
| | | url: '/stockin/delteCustom', |
| | | method: 'post', |
| | | data: ids |
| | | }) |
| | | } |
| | | |
| | | // 导åºå
¥åºä¿¡æ¯ |
| | | export function exportStockIn(query) { |
| | | return request({ |
| | |
| | | }); |
| | | }; |
| | | |
| | | // æ¥è¯¢ç产å
¥åºåºåä¿¡æ¯å表 |
| | | export const getStockManagePageByProduction = (params) => { |
| | | return request({ |
| | | url: "/stockin/listPageCopyByProduction", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | // æ¥è¯¢èªå®ä¹å
¥åºåºåä¿¡æ¯å表 |
| | | export const getStockManagePageByCustom = (params) => { |
| | | return request({ |
| | | url: "/stockin/listPageCopyByCustom", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | |
| | | // ä¿®æ¹åºåä¿¡æ¯ |
| | | export const updateStockManage = (data) => { |
| | |
| | | }) |
| | | } |
| | | |
| | | //åºåºæ¥å£ |
| | | // åºåºç®¡ç-é¢ç¨æ¥å£ |
| | | export const stockOut = (data) => { |
| | | return request({ |
| | | url: '/stockmanagement/stockout', |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | //æ¥è¯¢åºåºå表 |
| | | // åºåºå°è´¦-éè´åºåºæ¥è¯¢åºåºå表 |
| | | export const getStockOutPage = (params) => { |
| | | return request({ |
| | | url: "/stockmanagement/listPage", |
| | |
| | | url: '/stockmanagement/del', |
| | | method: 'post', |
| | | data: ids |
| | | }) |
| | | } |
| | | |
| | | //导åºåºåºä¿¡æ¯ |
| | | export const exportStockOut = (query) => { |
| | | return request({ |
| | | url: '/stockmanagement/export', |
| | | method: 'get', |
| | | params: query, |
| | | responseType: 'blob' |
| | | }) |
| | | } |
| | |
| | | params: query, |
| | | }) |
| | | } |
| | | |
| | | // 导åºåå坿¬ |
| | | export function staffOnJobExportCopy(data) { |
| | | return request({ |
| | | url: '/staff/staffOnJob/exportCopy', |
| | | method: 'post', |
| | | data: data, |
| | | }) |
| | | } |
| | |
| | | data: query, |
| | | }); |
| | | } |
| | | // 导å
¥ |
| | | export function importData(query) { |
| | | return request({ |
| | | url: "/compensationPerformance/importData", |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| | | // ä¸è½½æ¨¡ç |
| | | export function exportTemplate(query) { |
| | | return request({ |
| | | url: "/compensationPerformance/exportTemplate", |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| | |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | export function getCurrentUserLatestScheduling(){ |
| | | return request({ |
| | | url: "/staff/staffScheduling/getCurrentUserLatestScheduling", |
| | | method: "get" |
| | | }) |
| | | } |
| | |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // è·åçæºæ£å¨å·¥ä½éæ°æ® |
| | | export function schedulingList(query) { |
| | | return request({ |
| | | url: "/salesLedger/scheduling/list", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // ä¿åçæºè®¾ç½® |
| | | export function addSpeculatTrading(data) { |
| | | return request({ |
| | | url: "/salesLedger/scheduling/addSpeculatTrading", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹çæºè®¾ç½® |
| | | export function updateSpeculatTrading(data) { |
| | | return request({ |
| | | url: "/salesLedger/scheduling/updateSpeculatTrading", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // ç产派工 |
| | | export function productionDispatch(query) { |
| | | return request({ |
| | |
| | | data: query, |
| | | }); |
| | | } |
| | | // èªå¨æ´¾å·¥ |
| | | export function productionDispatchList(query) { |
| | | return request({ |
| | | url: "/salesLedger/scheduling/productionDispatchList", |
| | | method: "post", |
| | | data: query, |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢æèç |
| | | export function getLossRate() { |
| | | return request({ |
| | | url: "/salesLedger/scheduling/loss", |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢æèç |
| | | export function addLossRate(data) { |
| | | return request({ |
| | | url: "/salesLedger/scheduling/addLoss", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹æèç |
| | | export function updateLossRate(data) { |
| | | return request({ |
| | | url: "/salesLedger/scheduling/updateLoss", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // å
Œ
±æä»¶ç®¡çæ¥å£ |
| | | import request from '@/utils/request' |
| | | |
| | | // å é¤å
Œ
±æä»¶ |
| | | export function delCommonFile(ids) { |
| | | return request({ |
| | | url: '/commonFile/delCommonFile', |
| | | method: 'delete', |
| | | data: ids |
| | | }) |
| | | } |
| | | // å¼ç¥¨å°è´¦æä»¶å é¤ |
| | | export function delCommonFileInvoiceLedger(ids) { |
| | | return request({ |
| | | url: '/invoiceLedger/delFile', |
| | | method: 'delete', |
| | | data: ids |
| | | }) |
| | | } |
| | |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | }// æ¥è¯¢ç¨æ·å表 |
| | | export function listAll(query) { |
| | | return request({ |
| | | url: '/system/user//listAll', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢ç¨æ·è¯¦ç» |
| | |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // ååå¾
审æ¹åæ¥ä¿®å¾
åäºé¡¹ |
| | | export const approveAndDeviceTodos = () => { |
| | | return request({ |
| | | url: '/home/approveAndDeviceTodos', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | export const noticesCount = () => { |
| | | return request({ |
| | | url: '/home/noticesCount', |
| | | method: 'get' |
| | | }) |
| | | } |
| | |
| | | }) |
| | | |
| | | const handleSizeChange = (val) => { |
| | | console.log('handleSizeChange', val) |
| | | if (currentPage.value * val > props.total) { |
| | | currentPage.value = 1 |
| | | } |
| | |
| | | } |
| | | |
| | | const handleCurrentChange = (val) => { |
| | | console.log('handleCurrentChange---', val) |
| | | emit('pagination', { page: val, limit: pageSize.value }) |
| | | if (props.autoScroll) { |
| | | scrollTo(0, 800) |
| | |
| | | <el-select |
| | | v-model="form.maintainer" |
| | | placeholder="è¯·éæ©" |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | clearable |
| | | disabled |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openForm("edit", row); |
| | | }, |
| | | disabled: (row) => { |
| | | return row.maintainer !== userStore.nickName |
| | | } |
| | | }, |
| | | ], |
| | |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | // æ£æ¥æ¯å¦æä»äººç»´æ¤çæ°æ® |
| | | const unauthorizedData = selectedRows.value.filter(item => item.maintainer !== userStore.nickName); |
| | | if (unauthorizedData.length > 0) { |
| | | proxy.$modal.msgWarning("ä¸å¯å é¤ä»äººç»´æ¤çæ°æ®"); |
| | | return; |
| | | } |
| | | ids = selectedRows.value.map((item) => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| | |
| | | <el-form-item label="è§æ ¼åå·ï¼" prop="model"> |
| | | <el-input |
| | | v-model="modelForm.model" |
| | | placeholder="请è¾å
¥è§æ ¼åå·" |
| | | placeholder="请è¾å
¥è§æ ¼åå·(g*è¢æ°)" |
| | | clearable |
| | | @keydown.enter.prevent |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å
¶ä»è§æ ¼åå·ï¼" prop="otherModel"> |
| | | <el-input |
| | | v-model="modelForm.otherModel" |
| | | placeholder="请è¾å
¥å
¶ä»è§æ ¼åå·" |
| | | clearable |
| | | @keydown.enter.prevent |
| | | /> |
| | |
| | | clearable |
| | | @keydown.enter.prevent |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="ç»å®æºå¨ï¼" prop="speculativeTradingName"> |
| | | <el-select |
| | | v-model="modelForm.speculativeTradingName" |
| | | placeholder="è¯·éæ©ç»å®æºå¨" |
| | | multiple |
| | | clearable |
| | | style="width: 100%" |
| | | > |
| | | <el-option label="çæº1" value="çæº1" /> |
| | | <el-option label="çæº2" value="çæº2" /> |
| | | <el-option label="çæº3" value="çæº3" /> |
| | | <el-option label="çæº4" value="çæº4" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | prop: "unit", |
| | | }, |
| | | { |
| | | label: "ç»å®æºå¨", |
| | | prop: "speculativeTradingName", |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | |
| | | productName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | }, |
| | | modelForm: { |
| | | otherModel:'', |
| | | model: "", |
| | | unit: "", |
| | | speculativeTradingName: [], |
| | | }, |
| | | modelRules: { |
| | | model: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | unit: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | model: [ |
| | | // { required: true, message: "请è¾å
¥", trigger: "blur" }, |
| | | { |
| | | pattern: /^[0-9*]*$/, |
| | | message: "åªè½è¾å
¥æ°åå*å·", |
| | | trigger: "blur" |
| | | } |
| | | ], |
| | | // unit: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | // speculativeTradingName: [{ required: false, message: "è¯·éæ©ç»å®æºå¨", trigger: "change" }], |
| | | }, |
| | | }); |
| | | const { form, rules, modelForm, modelRules } = toRefs(data); |
| | |
| | | modelOperationType.value = type; |
| | | modelDia.value = true; |
| | | modelForm.value.model = ""; |
| | | modelForm.value.model = ""; |
| | | modelForm.value.unit = ""; |
| | | modelForm.value.speculativeTradingName = []; |
| | | modelForm.value.id = ""; |
| | | if (type === "edit") { |
| | | modelForm.value = { ...data }; |
| | | // 妿å端è¿åçæ¯å符串ï¼éè¦è½¬æ¢ä¸ºæ°ç» |
| | | if (data.speculativeTradingName && typeof data.speculativeTradingName === 'string') { |
| | | modelForm.value.speculativeTradingName = data.speculativeTradingName.split(','); |
| | | } |
| | | } |
| | | }; |
| | | // æäº¤äº§ååç§°ä¿®æ¹ |
| | |
| | | const submitModelForm = () => { |
| | | proxy.$refs.modelFormRef.validate((valid) => { |
| | | if (valid) { |
| | | modelForm.value.productId = currentId.value; |
| | | addOrEditProductModel(modelForm.value).then((res) => { |
| | | let _modelForm = { ...modelForm.value }; |
| | | |
| | | if(_modelForm.otherModel){ |
| | | _modelForm.model = _modelForm.otherModel; |
| | | } |
| | | delete _modelForm.otherModel; |
| | | // å°éä¸çæºå¨æ°ç»è½¬æ¢ä¸ºéå·åéçå符串 |
| | | const submitData = { |
| | | ..._modelForm, |
| | | productId: currentId.value, |
| | | speculativeTradingName: modelForm.value.speculativeTradingName.join(',') |
| | | }; |
| | | addOrEditProductModel(submitData).then((res) => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeModelDia(); |
| | | getModelList(); |
| | |
| | | v-model="form.maintainUserId" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | disabled |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | |
| | | clickFun: (row) => { |
| | | openForm("edit", row); |
| | | }, |
| | | disabled: (row) => { |
| | | return row.maintainUserName !== userStore.nickName |
| | | } |
| | | }, |
| | | ], |
| | | }, |
| | |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | // æ£æ¥æ¯å¦æä»äººç»´æ¤çæ°æ® |
| | | const unauthorizedData = selectedRows.value.filter(item => item.maintainUserName !== userStore.nickName); |
| | | if (unauthorizedData.length > 0) { |
| | | proxy.$modal.msgWarning("ä¸å¯å é¤ä»äººç»´æ¤çæ°æ®"); |
| | | return; |
| | | } |
| | | ids = selectedRows.value.map((item) => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| | |
| | | <template #footer v-if="operationType === 'approval'"> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm(2)">ä¸éè¿</el-button> |
| | | <el-button type="primary" @click="openSignatureDialog(1)">éè¿</el-button> |
| | | <el-button type="primary" @click="submitForm(1)">éè¿</el-button> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <!-- çµåç¾åå¼¹çªï¼vue3-signature-padï¼ --> |
| | | <el-dialog v-model="signatureDialogVisible" title="çµåç¾å" width="600px" append-to-body> |
| | | <vueEsign |
| | | ref="esign" |
| | | class="mySign" |
| | | :width="800" |
| | | :height="300" |
| | | :isCrop="isCrop" |
| | | :lineWidth="lineWidth" |
| | | :lineColor="lineColor" |
| | | /> |
| | | <div style="margin-top:10px;"> |
| | | <el-button @click="clearSignature">æ¸
é¤</el-button> |
| | | <el-button type="primary" @click="confirmSignature">ç¡®å®</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { getCurrentInstance, reactive, ref, toRefs } from "vue"; |
| | | import vueEsign from "vue-esign"; |
| | | import { |
| | | approveProcessDetails, |
| | | getDept, |
| | |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import {userListNoPageByTenantId} from "@/api/system/user.js"; |
| | | import { WarningFilled, Edit, Check, MoreFilled } from '@element-plus/icons-vue' |
| | | import { getToken } from "@/utils/auth"; |
| | | const emit = defineEmits(['close']) |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | |
| | | }, |
| | | }); |
| | | const { form } = toRefs(data); |
| | | const signatureDialogVisible = ref(false); |
| | | const signatureImg = ref(''); |
| | | let submitStatus = null; // 临æ¶åå¨éè¿/ä¸éè¿ç¶æ |
| | | const isCrop = ref(""); |
| | | const esign = ref(null); |
| | | const lineWidth = ref(0); |
| | | const lineColor = ref("#000000"); |
| | | |
| | | // ä¸ä¼ é
ç½® |
| | | const upload = reactive({ |
| | | // ä¸ä¼ çå°å |
| | | url: import.meta.env.VITE_APP_BASE_API + "/file/upload", |
| | | // 设置ä¸ä¼ ç请æ±å¤´é¨ |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | }); |
| | | |
| | | // èç¹æ é¢ |
| | | const getNodeTitle = (index, len) => { |
| | |
| | | productOptions.value = res.data; |
| | | }); |
| | | }; |
| | | // æå¼ç¾åå¼¹çª |
| | | const openSignatureDialog = (status) => { |
| | | submitStatus = status; |
| | | signatureDialogVisible.value = true; |
| | | }; |
| | | // æ¸
é¤ç¾å |
| | | const clearSignature = () => { |
| | | esign.value.reset(); |
| | | }; |
| | | // 确认ç¾å |
| | | const confirmSignature = () => { |
| | | esign.value.generate().then((res) => { |
| | | console.log(res); |
| | | // å°base64转æ¢ä¸ºäºè¿å¶ |
| | | const base64Data = res.split(',')[1]; // ç§»é¤data:image/png;base64,åç¼ |
| | | const binaryString = atob(base64Data); |
| | | const bytes = new Uint8Array(binaryString.length); |
| | | for (let i = 0; i < binaryString.length; i++) { |
| | | bytes[i] = binaryString.charCodeAt(i); |
| | | } |
| | | signatureImg.value = bytes; |
| | | |
| | | // å建æä»¶å¯¹è±¡ç¨äºä¸ä¼ |
| | | const blob = new Blob([bytes], { type: 'image/png' }); |
| | | const file = new File([blob], 'signature.png', { type: 'image/png' }); |
| | | |
| | | // å建FormData |
| | | const formData = new FormData(); |
| | | formData.append('file', file); |
| | | |
| | | // ä¸ä¼ ç¾åå¾ç |
| | | fetch(upload.url, { |
| | | method: 'POST', |
| | | headers: upload.headers, |
| | | body: formData |
| | | }) |
| | | .then(response => response.json()) |
| | | .then(data => { |
| | | if (data.code === 200) { |
| | | console.log('data---', data) |
| | | let tempFileIds = []; |
| | | tempFileIds.push(data.data.tempId); |
| | | signatureDialogVisible.value = false; |
| | | clearSignature(); |
| | | // åªæéè¿æ¶æä¼ éç¾åæä»¶ID |
| | | if (submitStatus === 1) { |
| | | submitForm(submitStatus, tempFileIds); |
| | | } else { |
| | | submitForm(submitStatus); |
| | | } |
| | | } else { |
| | | proxy.$modal.msgError("ç¾åå¾çä¸ä¼ 失败ï¼" + data.msg); |
| | | } |
| | | }) |
| | | .catch(error => { |
| | | console.error('ä¸ä¼ 失败:', error); |
| | | proxy.$modal.msgError("ç¾åå¾çä¸ä¼ 失败"); |
| | | }); |
| | | }).catch((err) => { |
| | | console.log(err); |
| | | proxy.$modal.msgWarning("请å
ç¾åï¼"); |
| | | }) |
| | | }; |
| | | // æäº¤å®¡æ¹ |
| | | const submitForm = (status, tempFileIds) => { |
| | | const submitForm = (status) => { |
| | | const filteredActivities = activities.value.filter(activity => activity.isShen); |
| | | filteredActivities[0].approveNodeStatus = status; |
| | | // åªæéè¿æ¶æéè¦ç¾å |
| | | if (status === 1 && tempFileIds) { |
| | | filteredActivities[0].tempFileIds = tempFileIds; |
| | | } |
| | | // 夿æ¯å¦ä¸ºæå䏿¥ |
| | | const isLast = activities.value.findIndex(a => a.isShen) === activities.value.length-1; |
| | | updateApproveNode({ ...filteredActivities[0], isLast }).then(() => { |
| | |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="ç³è¯·é¨é¨ï¼" prop="approveDeptId"> |
| | | <el-select |
| | | disabled |
| | | v-model="form.approveDeptId" |
| | | placeholder="éæ©é¨é¨" |
| | | > |
| | | <el-option |
| | | v-for="user in productOptions" |
| | | :key="user.deptId" |
| | | :label="user.deptName" |
| | | :value="user.deptId" |
| | | /> |
| | | </el-select> |
| | | <el-form-item label="ç³è¯·é¨é¨ï¼" prop="approveDeptName"> |
| | | <el-input v-model="form.approveDeptName" placeholder="请è¾å
¥" clearable/> |
| | | <!-- <el-select--> |
| | | <!-- disabled--> |
| | | <!-- v-model="form.approveDeptId"--> |
| | | <!-- placeholder="éæ©é¨é¨"--> |
| | | <!-- >--> |
| | | <!-- <el-option--> |
| | | <!-- v-for="user in productOptions"--> |
| | | <!-- :key="user.deptId"--> |
| | | <!-- :label="user.deptName"--> |
| | | <!-- :value="user.deptId"--> |
| | | <!-- />--> |
| | | <!-- </el-select>--> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | <el-col :span="24"> |
| | | <el-form-item :label="props.approveType == 5 ? 'éè´è¯´æï¼' : '审æ¹äºç±ï¼'" prop="approveReason"> |
| | | <el-input v-model="form.approveReason" placeholder="请è¾å
¥" clearable type="textarea" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <!-- è¯·åæ¶é´ï¼ä»
å½ approveType 为 2 æ¶æ¾ç¤ºï¼ --> |
| | | <el-row :gutter="30" v-if="props.approveType == 2"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="请åå¼å§æ¶é´ï¼" prop="startDate"> |
| | | <el-date-picker |
| | | v-model="form.startDate" |
| | | type="date" |
| | | placeholder="è¯·éæ©å¼å§æ¥æ" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="请åç»ææ¶é´ï¼" prop="endDate"> |
| | | <el-date-picker |
| | | v-model="form.endDate" |
| | | type="date" |
| | | placeholder="è¯·éæ©ç»ææ¥æ" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <!-- æ¥ééé¢ï¼ä»
å½ approveType 为 4 æ¶æ¾ç¤ºï¼ --> |
| | | <el-row v-if="props.approveType == 4"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="æ¥ééé¢ï¼" prop="price"> |
| | | <el-input-number |
| | | v-model="form.price" |
| | | placeholder="请è¾å
¥æ¥ééé¢" |
| | | :min="0" |
| | | :precision="2" |
| | | :step="0.01" |
| | | style="width: 100%" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <!-- åºå·®å°ç¹ï¼ä»
å½ approveType 为 3 æ¶æ¾ç¤ºï¼ --> |
| | | <el-row v-if="props.approveType == 3"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="åºå·®å°ç¹ï¼" prop="location"> |
| | | <el-input |
| | | v-model="form.location" |
| | | placeholder="请è¾å
¥åºå·®å°ç¹" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | <el-select |
| | | v-model="form.approveUser" |
| | | placeholder="éæ©äººå" |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | > |
| | | <el-option |
| | | v-for="user in userList" |
| | |
| | | approveId: "", |
| | | approveUser: "", |
| | | approveDeptId: "", |
| | | approveDeptName: "", |
| | | approveReason: "", |
| | | checkResult: "", |
| | | tempFileIds: [], |
| | | approverList: [] // æ°å¢å段ï¼å卿æèç¹ç审æ¹äººid |
| | | approverList: [], // æ°å¢å段ï¼å卿æèç¹ç审æ¹äººid |
| | | startDate: "", // 请åå¼å§æ¶é´ |
| | | endDate: "", // 请åç»ææ¶é´ |
| | | price: null, // æ¥ééé¢ |
| | | location: "" // åºå·®å°ç¹ |
| | | }, |
| | | rules: { |
| | | approveTime: [{ required: false, message: "请è¾å
¥", trigger: "change" },], |
| | | approveId: [{ required: false, message: "请è¾å
¥", trigger: "blur" }], |
| | | approveUser: [{ required: false, message: "请è¾å
¥", trigger: "blur" }], |
| | | approveDeptId: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | approveDeptName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | approveReason: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | checkResult: [{ required: false, message: "请è¾å
¥", trigger: "blur" }], |
| | | startDate: [{ required: true, message: "è¯·éæ©è¯·åå¼å§æ¶é´", trigger: "change" }], |
| | | endDate: [{ required: true, message: "è¯·éæ©è¯·åç»ææ¶é´", trigger: "change" }], |
| | | price: [{ required: true, message: "请è¾å
¥æ¥ééé¢", trigger: "blur" }], |
| | | location: [{ required: true, message: "请è¾å
¥åºå·®å°ç¹", trigger: "blur" }], |
| | | }, |
| | | }); |
| | | const { form, rules } = toRefs(data); |
| | |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = (type, row) => { |
| | | console.log('openDialog', type, row) |
| | | operationType.value = type; |
| | | dialogFormVisible.value = true; |
| | | userListNoPageByTenantId().then((res) => { |
| | |
| | | proxy.$modal.msgError("请为ææå®¡æ¹èç¹éæ©å®¡æ¹äººï¼") |
| | | return |
| | | } |
| | | // å½ approveType 为 2 æ¶ï¼æ ¡éªè¯·åæ¶é´ |
| | | if (props.approveType == 2) { |
| | | if (!form.value.startDate) { |
| | | proxy.$modal.msgError("è¯·éæ©è¯·åå¼å§æ¶é´ï¼") |
| | | return |
| | | } |
| | | if (!form.value.endDate) { |
| | | proxy.$modal.msgError("è¯·éæ©è¯·åç»ææ¶é´ï¼") |
| | | return |
| | | } |
| | | // æ ¡éªç»ææ¶é´ä¸è½æ©äºå¼å§æ¶é´ |
| | | if (new Date(form.value.endDate) < new Date(form.value.startDate)) { |
| | | proxy.$modal.msgError("请åç»ææ¶é´ä¸è½æ©äºå¼å§æ¶é´ï¼") |
| | | return |
| | | } |
| | | } |
| | | // å½ approveType 为 3 æ¶ï¼æ ¡éªåºå·®å°ç¹ |
| | | if (props.approveType == 3) { |
| | | if (!form.value.location || form.value.location.trim() === '') { |
| | | proxy.$modal.msgError("请è¾å
¥åºå·®å°ç¹ï¼") |
| | | return |
| | | } |
| | | } |
| | | // å½ approveType 为 4 æ¶ï¼æ ¡éªæ¥ééé¢ |
| | | if (props.approveType == 4) { |
| | | if (!form.value.price || form.value.price <= 0) { |
| | | proxy.$modal.msgError("请è¾å
¥ææçæ¥ééé¢ï¼") |
| | | return |
| | | } |
| | | } |
| | | proxy.$refs.formRef.validate(valid => { |
| | | if (valid) { |
| | | if (operationType.value === "add" || currentApproveStatus.value == 3) { |
| | |
| | | <el-dialog v-model="dialogVisible" title="éä»¶" width="40%" :before-close="handleClose"> |
| | | <el-table :data="tableData" border height="40vh"> |
| | | <el-table-column label="éä»¶åç§°" prop="name" min-width="400" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="æä½" width="100" align="center"> |
| | | <el-table-column fixed="right" label="æä½" width="150" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">ä¸è½½</el-button> |
| | | <el-button link type="primary" size="small" @click="lookFile(scope.row)">é¢è§</el-button> |
| | | <el-button link type="danger" size="small" @click="handleDelete(scope.row)">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | <script setup> |
| | | import { ref } from 'vue' |
| | | import filePreview from '@/components/filePreview/index.vue' |
| | | import { ElMessageBox, ElMessage } from 'element-plus' |
| | | import { delCommonFile } from '@/api/publicApi/commonFile.js' |
| | | |
| | | const dialogVisible = ref(false) |
| | | const tableData = ref([]) |
| | |
| | | const lookFile = (row) => { |
| | | filePreviewRef.value.open(row.url) |
| | | } |
| | | // å é¤éä»¶ |
| | | const handleDelete = (row) => { |
| | | ElMessageBox.confirm(`确认å é¤éä»¶"${row.name}"åï¼`, 'æç¤º', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | delCommonFile([row.id]).then(() => { |
| | | ElMessage.success('å 餿å') |
| | | // ä»å表ä¸ç§»é¤å·²å é¤çéä»¶ |
| | | const index = tableData.value.findIndex(item => item.id === row.id) |
| | | if (index !== -1) { |
| | | tableData.value.splice(index, 1) |
| | | } |
| | | }).catch(() => { |
| | | ElMessage.error('å é¤å¤±è´¥') |
| | | }) |
| | | }).catch(() => { |
| | | ElMessage.info('已忶å é¤') |
| | | }) |
| | | } |
| | | defineExpose({ |
| | | open |
| | | }) |
| | |
| | | width: 120 |
| | | }, |
| | | { |
| | | label: "ç³è¯·æ¥æ", |
| | | prop: "approveTime", |
| | | label: "éé¢ï¼å
ï¼", |
| | | prop: "price", |
| | | width: 120 |
| | | }, |
| | | { |
| | | label: props.approveType === 2 ? "å¼å§æ¥æ" : "ç³è¯·æ¥æ", |
| | | prop: props.approveType === 2 ? "startDate" : "approveTime", |
| | | width: 200 |
| | | }, |
| | | { |
| | | label: "ç»ææ¥æ", |
| | | prop: "approveOverTime", |
| | | prop: props.approveType === 2 ? "endDate" : "approveOverTime", |
| | | width: 120 |
| | | }, |
| | | { |
| | |
| | | clickFun: (row) => { |
| | | openForm("edit", row); |
| | | }, |
| | | disabled: (row) => row.approveStatus == 2 || row.approveStatus == 1 || row.approveStatus == 4 |
| | | }, |
| | | { |
| | | name: "å®¡æ ¸", |
| | |
| | | |
| | | <!-- éç¥å
¬åæ¿ --> |
| | | <div class="notice-board"> |
| | | <!-- æ¾åéç¥åºå --> |
| | | <div class="notice-section" v-if="holidayNoticeCount > 0"> |
| | | <!-- ç»ä¸éç¥åºå --> |
| | | <div class="notice-section" v-if="totalNoticeCount > 0"> |
| | | <div class="section-header"> |
| | | <h3>ð
æ¾åéç¥</h3> |
| | | <span class="section-count">{{ holidayNoticeCount }}æ¡</span> |
| | | <h3>� éç¥å
Œ</h3> |
| | | <span class="section-count">{{ totalNoticeCount }}æ¡</span> |
| | | </div> |
| | | <div class="notice-cards"> |
| | | <!-- æ¾åéç¥ --> |
| | | <div |
| | | v-for="notice in holidayNotices" |
| | | :key="notice.id" |
| | | :key="'holiday-' + notice.id" |
| | | class="notice-card holiday-card" |
| | | :class="{ 'urgent': notice.priority === '3' }" |
| | | > |
| | |
| | | </div> |
| | | <div class="card-footer"> |
| | | <div class="card-meta"> |
| | | <span class="type" :class="'type-' + notice.type"> |
| | | {{ notice.type }} |
| | | </span> |
| | | <span class="priority" :class="'priority-' + notice.priority"> |
| | | {{ getPriorityText(notice.priority) }} |
| | | </span> |
| | |
| | | <span>{{ notice.remark }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <pagination |
| | | v-if="holidayNoticePage.total > 0" |
| | | :total="holidayNoticePage.total" |
| | | :page="holidayNoticePage.current" |
| | | :limit="holidayNoticePage.size" |
| | | @pagination="handleHolidayNoticeCurrentChange" |
| | | /> |
| | | |
| | | <!-- 设å¤ç»´ä¿®éç¥åºå --> |
| | | <div class="notice-section" v-if="maintenanceNoticeCount > 0"> |
| | | <div class="section-header"> |
| | | <h3>ð§ 设å¤ç»´ä¿®éç¥</h3> |
| | | <span class="section-count">{{ maintenanceNoticeCount }}æ¡</span> |
| | | </div> |
| | | <div class="notice-cards"> |
| | | <!-- 设å¤ç»´ä¿®éç¥ --> |
| | | <div |
| | | v-for="notice in maintenanceNotices" |
| | | :key="notice.id" |
| | | :key="'maintenance-' + notice.id" |
| | | class="notice-card maintenance-card" |
| | | :class="{ 'urgent': notice.priority === '3' }" |
| | | > |
| | |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- ç»ä¸å页 --> |
| | | <pagination |
| | | v-if="maintenanceNoticePage.total > 0" |
| | | :total="maintenanceNoticePage.total" |
| | | :page="maintenanceNoticePage.current" |
| | | :limit="maintenanceNoticePage.size" |
| | | @pagination="handleMaintenanceNoticeCurrentChange" |
| | | v-if="(holidayNoticePage.total + maintenanceNoticePage.total) > 0" |
| | | :total="holidayNoticePage.total + maintenanceNoticePage.total" |
| | | :page="Math.max(holidayNoticePage.current, maintenanceNoticePage.current)" |
| | | :limit="Math.max(holidayNoticePage.size, maintenanceNoticePage.size)" |
| | | @pagination="handleCurrentChange" |
| | | /> |
| | | |
| | | <!-- ç©ºç¶æ --> |
| | |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¬åç±»å" prop="type"> |
| | | <el-select v-model="form.type" placeholder="è¯·éæ©å
¬åç±»å" style="width: 100%"> |
| | | <el-option label="æ¾åéç¥" :value="1"/> |
| | | <el-option label="设å¤ç»´ä¿®éç¥" :value="2"/> |
| | | </el-select> |
| | | <el-input v-model="form.type" placeholder="请è¾å
¥å
¬åæ é¢"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | }); |
| | | }; |
| | | |
| | | const holidayNoticeCount = ref() |
| | | const maintenanceNoticeCount = ref() |
| | | const totalNoticeCount = ref(0) |
| | | const fetchCount = () => { |
| | | getCount().then(res => { |
| | | holidayNoticeCount.value = res.data.filter(item => { |
| | | return item.type === 1 |
| | | })[0].count; |
| | | maintenanceNoticeCount.value = res.data.filter(item => { |
| | | return item.type === 2 |
| | | })[0].count; |
| | | totalNoticeCount.value = res.data.reduce((total, item) => total + item.count, 0); |
| | | }); |
| | | } |
| | | |
| | |
| | | }) |
| | | |
| | | const fetchHolidayNotices = () => { |
| | | listNotice({...holidayNoticePage.value, type: 1}).then(res => { |
| | | listNotice({...holidayNoticePage.value}).then(res => { |
| | | holidayNotices.value = res.data.records |
| | | holidayNoticePage.value.total = res.data.total |
| | | }); |
| | |
| | | }); |
| | | }; |
| | | |
| | | const handleHolidayNoticeCurrentChange = (val) => { |
| | | const handleCurrentChange = (val) => { |
| | | holidayNoticePage.value.size = val.limit |
| | | holidayNoticePage.value.current = val.page |
| | | fetchHolidayNotices() |
| | | }; |
| | | |
| | | const handleMaintenanceNoticeCurrentChange = (val) => { |
| | | maintenanceNoticePage.value.size = val.limit |
| | | maintenanceNoticePage.value.current = val.page |
| | | fetchHolidayNotices() |
| | | fetchMaintenanceNotices() |
| | | }; |
| | | |
| | |
| | | gap: 8px; |
| | | } |
| | | |
| | | .priority, .status { |
| | | .type, .priority, .status { |
| | | padding: 2px 8px; |
| | | border-radius: 12px; |
| | | font-size: 12px; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .type-1 { |
| | | background: #f0f9ff; |
| | | color: #0369a1; |
| | | } |
| | | |
| | | .type-2 { |
| | | background: #fef3c7; |
| | | color: #d97706; |
| | | } |
| | | |
| | | .priority-1 { |
| | | background: #f0f9ff; |
| | | color: #0369a1; |
| | |
| | | |
| | | <template #operation="{ row }"> |
| | | <el-button type="primary" link @click="openForm('view', row)">æ¥ç</el-button> |
| | | <el-button type="primary" link @click="openForm('edit', row)" v-if="row.status === 1">ç¼è¾</el-button> |
| | | <el-button type="primary" link @click="openForm('edit', row)">ç¼è¾</el-button> |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | |
| | | clickFun: (row) => { |
| | | openForm("edit", row); |
| | | }, |
| | | disabled: (row) => { |
| | | return row.checkUserId !== userStore.id || row.status !== 1 |
| | | } |
| | | }, |
| | | ], |
| | | }, |
| | |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | // æ£æ¥æ¯å¦æä»äººç»´æ¤çæ°æ® |
| | | const unauthorizedData = selectedRows.value.filter(item => item.checkUserId !== userStore.id); |
| | | if (unauthorizedData.length > 0) { |
| | | proxy.$modal.msgWarning("ä¸å¯å é¤ä»äººç»´æ¤çæ°æ®"); |
| | | return; |
| | | } |
| | | ids = selectedRows.value.map((item) => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| | |
| | | |
| | | <script setup> |
| | | import {onMounted, ref} from "vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import {ElMessageBox, ElMessage} from "element-plus"; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import CalibrationDia from "@/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue"; |
| | | import {ledgerRecordListPage} from "@/api/equipmentManagement/calibration.js"; |
| | | import {ledgerRecordListPage, ledgerRecordDelete} from "@/api/equipmentManagement/calibration.js"; |
| | | const { proxy } = getCurrentInstance(); |
| | | const userStore = useUserStore() |
| | | |
| | |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | width: 100, |
| | | align: "center", |
| | | fixed: 'right', |
| | | operation: [ |
| | |
| | | clickFun: (row) => { |
| | | openCalibrationDia("edit", row); |
| | | }, |
| | | disabled: (row) => { |
| | | return row.userId !== userStore.id |
| | | } |
| | | }, |
| | | { |
| | | name: "å é¤", |
| | | type: "text", |
| | | style: { |
| | | color: "#F56C6C" |
| | | }, |
| | | clickFun: (row) => { |
| | | handleDelete(row); |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | |
| | | }) |
| | | } |
| | | |
| | | // å é¤è®°å½ |
| | | const handleDelete = (row) => { |
| | | ElMessageBox.confirm(`确认å é¤è®¡éå¨å
·ç¼å·ä¸º"${row.code}"çæ£å®è®°å½åï¼`, "å é¤ç¡®è®¤", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | ledgerRecordDelete([row.id]).then(() => { |
| | | ElMessage.success("å 餿å"); |
| | | getList(); |
| | | }).catch(() => { |
| | | ElMessage.error("å é¤å¤±è´¥"); |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶å é¤"); |
| | | }); |
| | | }; |
| | | |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="设å¤åç§°" prop="taskId"> |
| | | <el-select v-model="form.taskId" @change="setDeviceModel"> |
| | | <el-select v-model="form.taskId" @change="setDeviceModel" filterable> |
| | | <el-option |
| | | v-for="(item, index) in deviceOptions" |
| | | :key="index" |
| | |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å·¡æ£äºº" prop="inspector"> |
| | | <el-select v-model="form.inspector" placeholder="è¯·éæ©" multiple clearable> |
| | | <el-select v-model="form.inspector" filterable |
| | | default-first-option |
| | | :reserve-keyword="false" placeholder="è¯·éæ©" multiple clearable> |
| | | <el-option v-for="item in userList" :label="item.nickName" :value="item.userId" :key="item.userId"/> |
| | | </el-select> |
| | | </el-form-item> |
| | |
| | | <el-col :span="12"> |
| | | <el-form-item label="夿³¨" prop="remarks"> |
| | | <el-input v-model="form.remarks" placeholder="请è¾å
¥å¤æ³¨" type="textarea" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»è®°æ¶é´" prop="dateStr"> |
| | | <el-date-picker |
| | | v-model="form.dateStr" |
| | | type="date" |
| | | placeholder="éæ©ç»è®°æ¥æ" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | frequencyType: '', |
| | | frequencyDetail: '', |
| | | week: '', |
| | | time: '' |
| | | time: '', |
| | | dateStr: '' |
| | | }, |
| | | rules: { |
| | | taskId: [{ required: true, message: "è¯·éæ©è®¾å¤", trigger: "change" },], |
| | | inspector: [{ required: true, message: "请è¾å
¥å·¡æ£äºº", trigger: "blur" },], |
| | | dateStr: [{ required: true, message: "è¯·éæ©ç»è®°æ¶é´", trigger: "change" }] |
| | | } |
| | | }) |
| | | const { form, rules } = toRefs(data) |
| | |
| | | |
| | | <!-- ç产å --> |
| | | <div class="form-container"> |
| | | <div class="title">ç产å</div> |
| | | <div class="title">ç产ä¸</div> |
| | | |
| | | <!-- å¾çå表 --> |
| | | <div style="display: flex; flex-wrap: wrap;"> |
| | |
| | | |
| | | <!-- ç产é®é¢ --> |
| | | <div class="form-container"> |
| | | <div class="title">ç产é®é¢</div> |
| | | <div class="title">ç产å</div> |
| | | |
| | | <!-- å¾çå表 --> |
| | | <div style="display: flex; flex-wrap: wrap;"> |
| | |
| | | :is-selection="true" |
| | | :border="true" |
| | | :table-style="{ width: '100%', height: 'calc(100vh - 23em)' }" |
| | | :page="{ |
| | | current: pageNum, |
| | | size: pageSize, |
| | | total: total, |
| | | }" |
| | | @pagination="pagination" |
| | | > |
| | | <template #inspector="{ row }"> |
| | | <div class="person-tags"> |
| | |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | <pagination |
| | | v-if="total>0" |
| | | :page="pageNum" |
| | | :limit="pageSize" |
| | | :total="total" |
| | | @pagination="handlePagination" |
| | | :layout="'total, prev, pager, next, jumper'" |
| | | /> |
| | | </div> |
| | | </el-card> |
| | | <form-dia ref="formDia" @closeDia="handleQuery"></form-dia> |
| | |
| | | } |
| | | }, |
| | | { prop: "registrant", label: "ç»è®°äºº", minWidth: 100 }, |
| | | { prop: "createTime", label: "ç»è®°æ¥æ", minWidth: 100 }, |
| | | { prop: "dateStr", label: "ç»è®°æ¥æ", minWidth: 100 }, |
| | | ]); |
| | | |
| | | // æä½åé
ç½® |
| | |
| | | pageSize.value = 10; |
| | | getList(); |
| | | }; |
| | | // å页å¤ç |
| | | const handlePagination = (val) => { |
| | | pageNum.value = val.page; |
| | | pageSize.value = val.size; |
| | | const pagination = (obj) => { |
| | | pageNum.value = obj.page; |
| | | pageSize.value = obj.limit; |
| | | getList(); |
| | | }; |
| | | // è·ååè¡¨æ°æ® |
| | |
| | | <el-dialog v-model="qrDialogVisible" title="äºç»´ç " width="300px"> |
| | | <div style="text-align:center;"> |
| | | <img :src="qrCodeUrl" alt="äºç»´ç " style="width:200px;height:200px;" /> |
| | | <div style="margin-top:6px;font-size:14px;color:#333;">{{ qrRowData?.deviceName }}</div> |
| | | <div style="margin:10px 0;"> |
| | | <el-button type="primary" @click="downloadQRCode">ä¸è½½äºç»´ç å¾ç</el-button> |
| | | </div> |
| | |
| | | }; |
| | | |
| | | const downloadQRCode = () => { |
| | | const name = qrRowData.value?.deviceName || "äºç»´ç "; |
| | | const img = new Image(); |
| | | img.src = qrCodeUrl.value; |
| | | img.onload = () => { |
| | | const padding = 10; |
| | | const qrSize = 200; |
| | | const textHeight = 24; // space for text |
| | | const width = qrSize + padding * 2; |
| | | const height = qrSize + padding * 2 + textHeight; |
| | | const canvas = document.createElement("canvas"); |
| | | canvas.width = width; |
| | | canvas.height = height; |
| | | const ctx = canvas.getContext("2d"); |
| | | // background |
| | | ctx.fillStyle = "#ffffff"; |
| | | ctx.fillRect(0, 0, width, height); |
| | | // draw QR centered |
| | | ctx.drawImage(img, padding, padding, qrSize, qrSize); |
| | | // draw name centered below |
| | | ctx.fillStyle = "#333"; |
| | | ctx.font = "14px Arial"; |
| | | ctx.textAlign = "center"; |
| | | ctx.textBaseline = "middle"; |
| | | const maxTextWidth = width - padding * 2; |
| | | let displayName = name; |
| | | // ellipsis if too long |
| | | while (ctx.measureText(displayName).width > maxTextWidth && displayName.length > 0) { |
| | | displayName = displayName.slice(0, -1); |
| | | } |
| | | if (displayName !== name) displayName = displayName + "â¦"; |
| | | ctx.fillText(displayName, width / 2, qrSize + padding + textHeight / 2); |
| | | |
| | | const dataUrl = canvas.toDataURL("image/png"); |
| | | const a = document.createElement("a"); |
| | | a.href = dataUrl; |
| | | a.download = `${name}.png`; |
| | | a.href = qrCodeUrl.value; |
| | | a.download = `${qrRowData.value.deviceName || "äºç»´ç "}.png`; |
| | | a.click(); |
| | | }; |
| | | }; |
| | | |
| | | onMounted(() => { |
| | |
| | | <el-select |
| | | v-model="form.userId" |
| | | placeholder="è¯·éæ©" |
| | | disabled |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | clearable |
| | | > |
| | | <el-option |
| | |
| | | v-model="form.userId" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | disabled |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | |
| | | openCalibrationDia("verifying", row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "éä»¶", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openFilesFormDia(row); |
| | | }, |
| | | }, |
| | | // { |
| | | // name: "éä»¶", |
| | | // type: "text", |
| | | // clickFun: (row) => { |
| | | // openFilesFormDia(row); |
| | | // }, |
| | | // }, |
| | | ], |
| | | }, |
| | | ]); |
| | |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | // æ£æ¥æ¯å¦æä»äººç»´æ¤çæ°æ® |
| | | const unauthorizedData = selectedRows.value.filter(item => item.userId !== userStore.id); |
| | | if (unauthorizedData.length > 0) { |
| | | proxy.$modal.msgWarning("ä¸å¯å é¤ä»äººç»´æ¤çæ°æ®"); |
| | | return; |
| | | } |
| | | ids = selectedRows.value.map((item) => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| | |
| | | <el-form-item label="ç»´ä¿®ç»æ"> |
| | | <el-input v-model="form.maintenanceResult" placeholder="请è¾å
¥ç»´ä¿®ç»æ" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ¥ä¿®ç¶æ"> |
| | | <el-select v-model="form.status"> |
| | | <el-option label="å¾
æ¥ä¿®" :value="0"></el-option> |
| | | <el-option label="å®ç»" :value="1"></el-option> |
| | | <el-option label="失败" :value="2"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ç»´ä¿®æ¥æ"> |
| | | <el-date-picker |
| | | v-model="form.maintenanceTime" |
| | |
| | | maintenanceName: undefined, // ç»´ä¿®åç§° |
| | | maintenanceResult: undefined, // ç»´ä¿®ç»æ |
| | | maintenanceTime: undefined, // ç»´ä¿®æ¥æ |
| | | status: 0, |
| | | }); |
| | | |
| | | const setForm = (data) => { |
| | |
| | | <el-input v-model="form.repairName" placeholder="请è¾å
¥æ¥ä¿®äºº" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row v-if="id"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¥ä¿®ç¶æ"> |
| | | <el-select v-model="form.status"> |
| | | <el-option label="å¾
ç»´ä¿®" :value="0"></el-option> |
| | | <el-option label="å®ç»" :value="1"></el-option> |
| | | <el-option label="失败" :value="2"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="æ
éç°è±¡"> |
| | | <el-input |
| | |
| | | import useFormData from "@/hooks/useFormData"; |
| | | import { getDeviceLedger } from "@/api/equipmentManagement/ledger"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | |
| | | const { id } = defineProps(["id"]) |
| | | |
| | | defineOptions({ |
| | | name: "è®¾å¤æ¥ä¿®è¡¨å", |
| | |
| | | repairTime: undefined, // æ¥ä¿®æ¥æ |
| | | repairName: userStore.nickName, // æ¥ä¿®äºº |
| | | remark: undefined, // æ
éç°è±¡ |
| | | status: 0, // æ¥ä¿®ç¶æ |
| | | }); |
| | | |
| | | const setDeviceModel = (id) => { |
| | |
| | | form.repairTime = data.repairTime; |
| | | form.repairName = data.repairName; |
| | | form.remark = data.remark; |
| | | form.status = data.status; |
| | | }; |
| | | |
| | | // onMounted(() => { |
| | |
| | | <template> |
| | | <el-dialog v-model="visible" :title="modalOptions.title" @close="close"> |
| | | <RepairForm ref="repairFormRef" /> |
| | | <RepairForm ref="repairFormRef" :id="id" /> |
| | | <template #footer> |
| | | <el-button type="primary" @click="sendForm" :loading="loading"> |
| | | {{ modalOptions.confirmText }} |
| | |
| | | @pagination="changePage" |
| | | > |
| | | <template #statusRef="{ row }"> |
| | | <el-tag v-if="row.status === 2" type="danger">失败</el-tag> |
| | | <el-tag v-if="row.status === 1" type="success">å®ç»</el-tag> |
| | | <el-tag v-if="row.status === 0" type="danger">å¾
ç»´ä¿®</el-tag> |
| | | <el-tag v-if="row.status === 0" type="warning">å¾
ç»´ä¿®</el-tag> |
| | | </template> |
| | | <template #operation="{ row }"> |
| | | <el-button |
| | |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ä¿å
»ç¶æ"> |
| | | <el-select v-model="form.status"> |
| | | <el-option label="å¾
ä¿å
»" :value="0"></el-option> |
| | | <el-option label="å®ç»" :value="1"></el-option> |
| | | <el-option label="失败" :value="2"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ä¿å
ȍȾ"> |
| | | <el-select v-model="form.maintenanceResult" placeholder="è¯·éæ©ä¿å
ȍȾ"> |
| | | <!-- <el-select v-model="form.maintenanceResult" placeholder="è¯·éæ©ä¿å
ȍȾ"> |
| | | <el-option label="å®å¥½" :value="1"></el-option> |
| | | <el-option label="ç»´ä¿®" :value="0"></el-option> |
| | | </el-select> |
| | | </el-select> --> |
| | | <el-input |
| | | v-model="form.maintenanceResult" |
| | | placeholder="请è¾å
¥ä¿å
ȍȾ" |
| | | type="text" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | </template> |
| | |
| | | maintenanceActuallyName: undefined, // å®é
ä¿å
»äºº |
| | | maintenanceActuallyTime: undefined, // å®é
ä¿å
»æ¥æ |
| | | maintenanceResult: undefined, // ä¿å
ȍȾ |
| | | status: 0, // ä¿å
»ç¶æ |
| | | }); |
| | | |
| | | const setForm = (data) => { |
| | |
| | | v-model="form.deviceLedgerId" |
| | | @change="setDeviceModel" |
| | | placeholder="è¯·éæ©è®¾å¤" |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | > |
| | | <el-option |
| | | v-for="(item, index) in deviceOptions" |
| | |
| | | placeholder="请è¾å
¥è§æ ¼åå·" |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="å½å
¥äºº"> |
| | | <el-select |
| | | v-model="form.createUser" |
| | | placeholder="è¯·éæ©" |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | | :key="item.userId" |
| | | :label="item.userName" |
| | | :value="item.userId" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item v-if="id" label="ä¿ä¿®ç¶æ"> |
| | | <el-select v-model="form.status"> |
| | | <el-option label="å¾
ä¿ä¿®" :value="0"></el-option> |
| | | <el-option label="å®ç»" :value="1"></el-option> |
| | | <el-option label="失败" :value="2"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="计åä¿å
»æ¥æ"> |
| | | <el-date-picker |
| | |
| | | import { getDeviceLedger } from "@/api/equipmentManagement/ledger"; |
| | | import { onMounted } from "vue"; |
| | | import dayjs from "dayjs"; |
| | | import { userListNoPage } from "@/api/system/user.js"; |
| | | |
| | | defineOptions({ |
| | | name: "计å表å", |
| | |
| | | deviceOptions.value = data; |
| | | }; |
| | | |
| | | const { id } = defineProps(['id']); |
| | | |
| | | const { form, resetForm } = useFormData({ |
| | | deviceLedgerId: undefined, // 设å¤Id |
| | | deviceName: undefined, // 设å¤åç§° |
| | | deviceModel: undefined, // è§æ ¼åå· |
| | | maintenancePlanTime: undefined, // 计åä¿å
»æ¥æ |
| | | createUser: undefined, // å½å
¥äºº |
| | | status: 0, //ä¿ä¿®ç¶æ |
| | | }); |
| | | |
| | | const setDeviceModel = (id) => { |
| | |
| | | form.deviceLedgerId = data.deviceLedgerId; |
| | | form.deviceName = data.deviceName; |
| | | form.deviceModel = data.deviceModel; |
| | | form.createUser = Number(data.createUser); |
| | | form.status = data.status; |
| | | form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format( |
| | | "YYYY-MM-DD HH:mm:ss" |
| | | ); |
| | | }; |
| | | |
| | | // ç¨æ·å表 |
| | | const userList = ref([]); |
| | | |
| | | const loadForm = () => {}; |
| | | |
| | | onMounted(() => { |
| | | loadDeviceName(); |
| | | userListNoPage().then((res) => { |
| | | userList.value = res.data; |
| | | }); |
| | | }); |
| | | |
| | | defineExpose({ |
| | |
| | | width="30%" |
| | | @close="close" |
| | | > |
| | | <PlanForm ref="planFormRef"></PlanForm> |
| | | <PlanForm ref="planFormRef" :id="id"></PlanForm> |
| | | <template #footer> |
| | | <el-button type="primary" @click="sendForm" :loading="loading"> |
| | | {{ modalOptions.confirmText }} |
| | |
| | | @pagination="changePage" |
| | | > |
| | | <template #maintenanceResultRef="{ row }"> |
| | | <el-tag v-if="row.maintenanceResult === 1" type="success"> |
| | | <div>{{ row.maintenanceResult || '-' }}</div> |
| | | <!-- <el-tag v-if="row.maintenanceResult === 1" type="success"> |
| | | å®å¥½ |
| | | </el-tag> |
| | | <el-tag v-if="row.maintenanceResult === 0" type="danger"> |
| | | ç»´ä¿® |
| | | </el-tag> |
| | | </el-tag> --> |
| | | </template> |
| | | <template #statusRef="{ row }"> |
| | | <el-tag v-if="row.status === 2" type="danger">失败</el-tag> |
| | | <el-tag v-if="row.status === 1" type="success">å®ç»</el-tag> |
| | | <el-tag v-if="row.status === 0" type="danger">å¾
ä¿å
»</el-tag> |
| | | <el-tag v-if="row.status === 0" type="warning">å¾
ä¿å
»</el-tag> |
| | | </template> |
| | | <template #operation="{ row }"> |
| | | <el-button |
| | |
| | | align: "center", |
| | | prop: "createUserName", |
| | | }, |
| | | { |
| | | label: "å½å
¥æ¥æ", |
| | | align: "center", |
| | | prop: "createTime", |
| | | formatData: (cell) => dayjs(cell).format("YYYY-MM-DD HH:mm:ss"), |
| | | width: 200, |
| | | }, |
| | | // { |
| | | // label: "å½å
¥æ¥æ", |
| | | // align: "center", |
| | | // prop: "createTime", |
| | | // formatData: (cell) => dayjs(cell).format("YYYY-MM-DD HH:mm:ss"), |
| | | // width: 200, |
| | | // }, |
| | | { |
| | | label: "å®é
ä¿å
»äºº", |
| | | align: "center", |
| | |
| | | listPage, |
| | | { |
| | | expenseMethod: undefined, |
| | | entryDate: undefined, |
| | | }, |
| | | [ |
| | | { |
| | |
| | | |
| | | const changeDaterange = (value) => { |
| | | if (value) { |
| | | filters.entryDate = value; |
| | | filters.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD"); |
| | | filters.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD"); |
| | | } else { |
| | | filters.entryDate = null; |
| | | filters.entryDateStart = undefined; |
| | | filters.entryDateEnd = undefined; |
| | | } |
| | |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | filters.entryDate = [ |
| | | dayjs().format("YYYY-MM-DD"), |
| | | dayjs().add(1, "day").format("YYYY-MM-DD"), |
| | | ] |
| | | filters.entryDateStart = dayjs().format("YYYY-MM-DD") |
| | | filters.entryDateEnd = dayjs().add(1, "day").format("YYYY-MM-DD") |
| | | getTableData(); |
| | | }); |
| | | </script> |
| | |
| | | range-separator="è³" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | clearable |
| | | :default-value="[new Date(firstDayOfMonth), new Date()]" |
| | | @change="handleDateChange" |
| | | class="w-full md:w-auto" |
| | | style="margin-right: 30px;" |
| | |
| | | import dayjs from "dayjs"; |
| | | |
| | | // æ¥æèå´ |
| | | const dateRange = ref(null); |
| | | const dateRange = ref([]); |
| | | const firstDayOfMonth = ref(null); |
| | | const chartStyle = { |
| | | width: '100%', |
| | | height: '100%', // 设置å¾è¡¨å®¹å¨çé«åº¦ |
| | |
| | | }) |
| | | |
| | | const getData = async () => { |
| | | if (!dateRange.value || !dateRange.value.length) { |
| | | return; |
| | | } |
| | | try { |
| | | const {code,data} = await reportForms({entryDateStart:dateRange.value[0], entryDateEnd:dateRange.value[1]}); |
| | | if(code === 200) { |
| | |
| | | }; |
| | | |
| | | |
| | | // åå§å |
| | | // åå§åæ¥æèå´ï¼é»è®¤å½æï¼ |
| | | onMounted(() => { |
| | | // ä¸è®¾ç½®é»è®¤æ¥æï¼ç±ç¨æ·æå¨éæ© |
| | | const today = new Date(); |
| | | const firstDay = new Date(today.getFullYear(), today.getMonth(), 1); |
| | | firstDayOfMonth.value = firstDay; |
| | | dateRange.value = [dayjs(firstDay).format("YYYY-MM-DD"), dayjs(today).format("YYYY-MM-DD")]; |
| | | getData() |
| | | |
| | | }); |
| | | |
| | | // å¤çæ¥æèå´åå |
| | | const handleDateChange = (newRange) => { |
| | | dateRange.value = newRange; |
| | | if (newRange && newRange.length === 2) { |
| | | dateRange.value = newRange; |
| | | getData() |
| | | } |
| | | }; |
| | | |
| | | // éç½®æ¥æèå´ |
| | | const resetDateRange = () => { |
| | | dateRange.value = null; |
| | | const today = new Date(); |
| | | const firstDay = new Date(today.getFullYear(), today.getMonth(), 1); |
| | | dateRange.value = [dayjs(firstDay).format("YYYY-MM-DD"), dayjs(today).format("YYYY-MM-DD")]; |
| | | getData() |
| | | }; |
| | | |
| | | </script> |
| | |
| | | listPage, |
| | | { |
| | | incomeMethod: undefined, |
| | | entryDate: undefined, |
| | | }, |
| | | [ |
| | | { |
| | |
| | | |
| | | const changeDaterange = (value) => { |
| | | if (value) { |
| | | filters.entryDate = value; |
| | | filters.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD"); |
| | | filters.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD"); |
| | | } else { |
| | | filters.entryDate = null; |
| | | filters.entryDateStart = undefined; |
| | | filters.entryDateEnd = undefined; |
| | | } |
| | |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | filters.entryDate = [ |
| | | dayjs().format("YYYY-MM-DD"), |
| | | dayjs().add(1, "day").format("YYYY-MM-DD"), |
| | | ] |
| | | filters.entryDateStart = dayjs().format("YYYY-MM-DD") |
| | | filters.entryDateEnd = dayjs().add(1, "day").format("YYYY-MM-DD") |
| | | getTableData(); |
| | | }); |
| | | </script> |
| | |
| | | <el-icon color="#5053B5" size="22"><Clock /></el-icon> |
| | | <span>ç»éæ¥æï¼{{userStore.currentLoginTime}}</span> |
| | | </div> |
| | | <div style="display: flex;align-items: center;gap: 8px"> |
| | | <el-icon color="#5053B5" size="22"><Calendar /></el-icon> |
| | | <span>æçæ¶é´ï¼{{scheduleTime}}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="data-cards"> |
| | |
| | | <div class="main-panel"> |
| | | <div style="display: flex;justify-content: space-between;"> |
| | | <div class="section-title">åºæ¶åºä»ç»è®¡</div> |
| | | <el-radio-group v-model="radio1" size="large" @change="statisticsReceivable"> |
| | | <el-radio-button label="æå¨" :value="1" /> |
| | | <el-radio-button label="ææ" :value="2" /> |
| | | <el-radio-button label="æå£åº¦" :value="3" /> |
| | | </el-radio-group> |
| | | <!-- <el-radio-group v-model="radio1" size="large" @change="statisticsReceivable">--> |
| | | <!-- <el-radio-button label="æå¨" :value="1" />--> |
| | | <!-- <el-radio-button label="ææ" :value="2" />--> |
| | | <!-- <el-radio-button label="æå£åº¦" :value="3" />--> |
| | | <!-- </el-radio-group>--> |
| | | </div> |
| | | <Echarts ref="chart" |
| | | :color="barColors2" |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted } from 'vue' |
| | | import { ref, reactive, onMounted } from 'vue' |
| | | import { ElNotification } from 'element-plus' |
| | | import Echarts from "@/components/Echarts/echarts.vue"; |
| | | import * as echarts from 'echarts'; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import { Clock, Calendar } from '@element-plus/icons-vue' |
| | | import { |
| | | analysisCustomerContractAmounts, getAmountHalfYear, |
| | | getBusiness, |
| | | homeTodos, |
| | | qualityStatistics, |
| | | statisticsReceivablePayable |
| | | statisticsReceivablePayable, |
| | | approveAndDeviceTodos, |
| | | noticesCount |
| | | } from "@/api/viewIndex.js"; |
| | | import { getCurrentUserLatestScheduling } from "@/api/personnelManagement/scheduling.js"; |
| | | import dayjs from "dayjs"; |
| | | |
| | | const userStore = useUserStore() |
| | | |
| | |
| | | const todoList = ref([]) |
| | | const radio1 = ref(1) |
| | | |
| | | // æçæ¶é´ |
| | | const scheduleTime = ref('') |
| | | const scheduleInfo = ref({}) |
| | | |
| | | // å¾è¡¨å¼ç¨ |
| | | const barChart = ref(null) |
| | | const lineChart = ref(null) |
| | |
| | | statisticsReceivable() |
| | | qualityStatisticsInfo() |
| | | getAmountHalfYearNum() |
| | | getCurrentUserSchedule() |
| | | getApproveAndDeviceTodos() |
| | | getOngoingAnnouncementNoticeNumber() |
| | | }) |
| | | // æ°æ®ç»è®¡ |
| | | const getBusinessData = () => { |
| | |
| | | qualityStatisticsObject.value.factoryNum = res.data.factoryNum |
| | | }) |
| | | } |
| | | // è·åå½åç¨æ·æçä¿¡æ¯ |
| | | const getCurrentUserSchedule = async () => { |
| | | try { |
| | | const res = await getCurrentUserLatestScheduling() |
| | | |
| | | if (res.data) { |
| | | const currentSchedule = res.data |
| | | scheduleInfo.value = currentSchedule |
| | | |
| | | // æ ¼å¼åæçæ¶é´æ¾ç¤º |
| | | if (currentSchedule.startTime && currentSchedule.endTime) { |
| | | scheduleTime.value = `${currentSchedule.startTime} - ${currentSchedule.endTime}` |
| | | } else if (currentSchedule.workStartTime && currentSchedule.workEndTime) { |
| | | const startTime = dayjs(currentSchedule.workStartTime).format('HH:mm') |
| | | const endTime = dayjs(currentSchedule.workEndTime).format('HH:mm') |
| | | scheduleTime.value = `${startTime} - ${endTime}` |
| | | } else { |
| | | scheduleTime.value = '仿¥æ æç' |
| | | } |
| | | } else { |
| | | scheduleTime.value = '仿¥æ æç' |
| | | scheduleInfo.value = {} |
| | | } |
| | | } catch (error) { |
| | | console.error('è·åæçä¿¡æ¯å¤±è´¥:', error) |
| | | scheduleTime.value = 'è·åæçä¿¡æ¯å¤±è´¥' |
| | | } |
| | | } |
| | | |
| | | const getAmountHalfYearNum = async () => { |
| | | const res = await getAmountHalfYear() |
| | | console.log(res) |
| | |
| | | } |
| | | ] |
| | | } |
| | | |
| | | // ååå¾
审æ¹åæ¥ä¿®å¾
åäºé¡¹ |
| | | const getApproveAndDeviceTodos = async () => { |
| | | try { |
| | | const res = await approveAndDeviceTodos() |
| | | const { approveTodo, deviceRepairTodo } = res.data |
| | | |
| | | // æ¾ç¤ºéç¥ |
| | | ElNotification({ |
| | | title: 'å¾
åäºé¡¹æé', |
| | | message: `å½åæ${approveTodo}æ¡å¾
审æ¹äºé¡¹ï¼${deviceRepairTodo}æ¡å¾
ç»´ä¿®äºé¡¹`, |
| | | type: 'warning', |
| | | duration: 5000 |
| | | }) |
| | | } catch (error) { |
| | | console.error('è·åååå¾
åäºé¡¹å¤±è´¥:', error) |
| | | } |
| | | } |
| | | // è¿è¡ä¸å
¬åéç¥ |
| | | const getOngoingAnnouncementNoticeNumber = async () => { |
| | | try { |
| | | const res = await noticesCount() |
| | | // const { approveTodo, deviceRepairTodo } = res.data |
| | | const _noticesCount = res.data |
| | | if(!_noticesCount){ |
| | | return |
| | | } |
| | | // æ¾ç¤ºéç¥ |
| | | ElNotification({ |
| | | title: 'éç¥å
¬åéç¥', |
| | | message: `å½åæ${_noticesCount}æ¡å
¬åéç¥ï¼æ³¨ææ¥ç`, |
| | | type: 'warning', |
| | | duration: 5000 |
| | | }) |
| | | } catch (error) { |
| | | console.error('è·åååå¾
åäºé¡¹å¤±è´¥:', error) |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-tabs v-model="activeTab" @tab-change="handleTabChange"> |
| | | <el-tab-pane label="æååºåº" name="production"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">ä¾åºååç§°ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.supplierName" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | @change="handleQuery" |
| | | clearable |
| | | prefix-icon="Search" |
| | | /> |
| | | <span class="search_title ml10">åºåºæ¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.timeStr" |
| | |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px" |
| | | >æç´¢</el-button |
| | | > |
| | | <span class="search_title ml10">产å大类ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.productCategory" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">æç´¢</el-button> |
| | | </div> |
| | | <div> |
| | | <!-- <el-button type="primary" @click="openForm('add')">æ°å¢</el-button> --> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | <el-button type="primary" plain @click="handlePrint">æå°</el-button> |
| | |
| | | > |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column |
| | | label="åºåºæ¥æ" |
| | | prop="createTime" |
| | | min-width="250" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="ä¾åºååç§°" |
| | | prop="supplierName" |
| | | width="250" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="产å大类" |
| | | prop="productCategory" |
| | | width="100" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="è§æ ¼åå·" |
| | | prop="specificationModel" |
| | | width="100" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="åä½" |
| | | prop="unit" |
| | | width="80" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="åºåºæ°é" |
| | | prop="inboundNum" |
| | | width="100" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="å«ç¨åä»·(å
)" |
| | | prop="taxInclusiveUnitPrice" |
| | | width="100" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="å«ç¨æ»ä»·(å
)" |
| | | prop="taxInclusiveTotalPrice" |
| | | width="100" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="ç¨ç(%)" |
| | | prop="taxRate" |
| | | width="100" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="ä¸å«ç¨æ»ä»·(å
)" |
| | | prop="taxExclusiveTotalPrice" |
| | | width="180" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="åºåºäºº" |
| | | prop="createBy" |
| | | width="80" |
| | | show-overflow-tooltip |
| | | /> |
| | | <!-- <el-table-column |
| | | fixed="right" |
| | | label="æä½" |
| | | min-width="60" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | <el-button |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | @click="openForm('edit', scope.row)" |
| | | >ç¼è¾</el-button |
| | | > |
| | | </template> |
| | | </el-table-column> --> |
| | | <el-table-column label="åºåºæ¥æ" prop="createTime" width="120" show-overflow-tooltip /> |
| | | <el-table-column label="éå®ååå·" prop="salesContractNo" width="180" show-overflow-tooltip /> |
| | | <el-table-column label="产å大类" prop="productCategory" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" show-overflow-tooltip /> |
| | | <el-table-column label="åä½" prop="unit" width="80" show-overflow-tooltip /> |
| | | <el-table-column label="åºåºæ°é" prop="inboundNum" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="åä»·(å
)" prop="unitPrice" width="150"></el-table-column> |
| | | <el-table-column label="æ»ä»·(å
)" prop="totalPrice" width="150"></el-table-column> |
| | | <el-table-column label="åºåºäºº" prop="createBy" width="80" show-overflow-tooltip /> |
| | | </el-table> |
| | | <pagination |
| | | v-show="total > 0" |
| | |
| | | @pagination="paginationChange" |
| | | /> |
| | | </div> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="åæåºåº" name="purchase"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title ml10">åºåºæ¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.timeStr" |
| | | type="date" |
| | | placeholder="è¯·éæ©æ¥æ" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | <span class="search_title ml10">产å大类ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.productCategory" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">æç´¢</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | <el-button type="primary" plain @click="handlePrint">æå°</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <el-table |
| | | :data="tableData" |
| | | border |
| | | v-loading="tableLoading" |
| | | @selection-change="handleSelectionChange" |
| | | :expand-row-keys="expandedRowKeys" |
| | | :row-key="(row) => row.id" |
| | | show-summary |
| | | style="width: 100%" |
| | | :summary-method="summarizeMainTable" |
| | | height="calc(100vh - 18.5em)" |
| | | > |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column label="åºåºæ¥æ" prop="createTime" width="120" show-overflow-tooltip /> |
| | | <el-table-column label="éè´ååå·" prop="purchaseContractNumber" width="180" show-overflow-tooltip /> |
| | | <el-table-column label="产å大类" prop="productCategory" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" show-overflow-tooltip /> |
| | | <el-table-column label="åä½" prop="unit" width="80" show-overflow-tooltip /> |
| | | <el-table-column label="åºåºæ°é" prop="inboundNum" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å«ç¨åä»·(å
)" prop="taxInclusiveUnitPrice" width="150"></el-table-column> |
| | | <el-table-column label="å«ç¨æ»ä»·(å
)" prop="taxInclusiveTotalPrice" width="150"></el-table-column> |
| | | <el-table-column label="åºåºäºº" prop="createBy" width="80" show-overflow-tooltip /> |
| | | </el-table> |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" |
| | | :limit="page.size" |
| | | @pagination="paginationChange" |
| | | /> |
| | | </div> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="ææåºåº" name="manual"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title ml10">åºåºæ¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.timeStr" |
| | | type="date" |
| | | placeholder="è¯·éæ©æ¥æ" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | <span class="search_title ml10">产å大类ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.productCategory" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">æç´¢</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | <el-button type="primary" plain @click="handlePrint">æå°</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <el-table |
| | | :data="tableData" |
| | | border |
| | | v-loading="tableLoading" |
| | | @selection-change="handleSelectionChange" |
| | | :expand-row-keys="expandedRowKeys" |
| | | :row-key="(row) => row.id" |
| | | show-summary |
| | | style="width: 100%" |
| | | :summary-method="summarizeMainTable" |
| | | height="calc(100vh - 18.5em)" |
| | | > |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column label="åºåºæ¥æ" prop="createTime" show-overflow-tooltip width="130"/> |
| | | <el-table-column label="æ¹æ¬¡å·" prop="code" width="130" show-overflow-tooltip /> |
| | | <el-table-column label="产å大类" prop="productCategory" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" show-overflow-tooltip /> |
| | | <el-table-column label="åä½" prop="unit" show-overflow-tooltip /> |
| | | <el-table-column label="ç©åç±»å" prop="itemType" show-overflow-tooltip /> |
| | | <el-table-column label="åºåºæ°é" prop="inboundNum" show-overflow-tooltip /> |
| | | <el-table-column label="åä»·(å
)" prop="taxInclusiveUnitPrice" width="150"></el-table-column> |
| | | <el-table-column label="æ»ä»·(å
)" prop="taxInclusiveTotalPrice" width="150"></el-table-column> |
| | | <el-table-column label="åºåºäºº" prop="createBy" show-overflow-tooltip /> |
| | | </el-table> |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" |
| | | :limit="page.size" |
| | | @pagination="paginationChange" |
| | | /> |
| | | </div> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | |
| | | <!-- æå°é¢è§å¼¹çª --> |
| | | <el-dialog |
| | |
| | | <div v-for="(item, index) in printData" :key="index" class="print-page"> |
| | | <div class="delivery-note"> |
| | | <div class="header"> |
| | | <div class="company-name">é¼è¯çå®ä¸æé责任å
¬å¸</div> |
| | | <div class="company-name">æµ·å·å¼å¿é£åæéå
¬å¸</div> |
| | | <div class="document-title">é¶å®åè´§å</div> |
| | | </div> |
| | | |
| | |
| | | |
| | | <script setup> |
| | | import pagination from "@/components/PIMTable/Pagination.vue"; |
| | | import { ref } from "vue"; |
| | | import { ref, reactive, toRefs, onMounted, getCurrentInstance } from "vue"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { |
| | | getStockOutPage, |
| | | delStockOut, |
| | | } from "@/api/inventoryManagement/stockOut.js"; |
| | | import { |
| | | getStockInPageByProduct, |
| | | getStockInPageByCustom, |
| | | } from "@/api/inventoryManagement/stockIn.js"; |
| | | |
| | | const userStore = useUserStore(); |
| | | const { proxy } = getCurrentInstance(); |
| | | const tableData = ref([]); |
| | | const activeTab = ref('production'); |
| | | const selectedRows = ref([]); |
| | | const tableLoading = ref(false); |
| | | const page = reactive({ |
| | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | supplierName: "", |
| | | timeStr: "", |
| | | customerName: "", |
| | | productCategory:'', |
| | | timeStr: getCurrentDate(), |
| | | }, |
| | | form: { |
| | | supplierId: null, |
| | |
| | | }; |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | getStockOutPage({ ...searchForm.value, ...page }) |
| | | const params = { ...page } |
| | | if (activeTab.value === 'production') { |
| | | params.customerName = searchForm.value.customerName |
| | | params.timeStr = searchForm.value.timeStr |
| | | } else { |
| | | params.supplierName = searchForm.value.supplierName |
| | | params.timeStr = searchForm.value.timeStr |
| | | } |
| | | params.productCategory = searchForm.value.productCategory |
| | | |
| | | // æ ¹æ®ä¸åç tab ç±»åè°ç¨ä¸åçæ¥å£ |
| | | const apiCall = activeTab.value === 'production' |
| | | ? getStockInPageByProduct(params) |
| | | : activeTab.value === 'manual' |
| | | ? getStockInPageByCustom(params) |
| | | : getStockOutPage(params) |
| | | |
| | | apiCall |
| | | .then((res) => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records; |
| | | tableData.value.map((item) => { |
| | | item.children = []; |
| | | // åç«¯è®¡ç®æ»ä»· |
| | | const inboundNum = Number(item.inboundNum) || 0; |
| | | if (activeTab.value === 'production') { |
| | | // æååºåºï¼æ»ä»· = unitPrice à inboundNum |
| | | const unitPrice = Number(item.unitPrice) || 0; |
| | | item.totalPrice = (unitPrice * inboundNum).toFixed(2); |
| | | } else { |
| | | // åæåææåºåºï¼æ»ä»· = taxInclusiveUnitPrice à inboundNum |
| | | const taxInclusiveUnitPrice = Number(item.taxInclusiveUnitPrice) || 0; |
| | | item.taxInclusiveTotalPrice = (taxInclusiveUnitPrice * inboundNum).toFixed(2); |
| | | } |
| | | }); |
| | | total.value = res.data.total; |
| | | }) |
| | | .catch(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | const handleTabChange = () => { |
| | | page.current = 1 |
| | | searchForm.value.supplierName = '' |
| | | searchForm.value.customerName = '' |
| | | searchForm.value.timeStr = '' |
| | | selectedRows.value = [] |
| | | searchForm.value.productCategory = '' |
| | | getList() |
| | | }; |
| | | |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | proxy.download("/stockmanagement/export", {}, "åºåºå°è´¦.xlsx"); |
| | | // æ ¹æ®ä¸åç tab ç±»åè°ç¨ä¸åçå¯¼åºæ¥å£ |
| | | let exportUrl = "/stockmanagement/export" |
| | | if (activeTab.value === 'production') { |
| | | exportUrl = "/stockmanagement/exportone" |
| | | } else if (activeTab.value === 'manual') { |
| | | exportUrl = "/stockmanagement/exportTwo" |
| | | } |
| | | proxy.download(exportUrl, {}, "åºåºå°è´¦.xlsx"); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | |
| | | <div class="print-page"> |
| | | <div class="delivery-note"> |
| | | <div class="header"> |
| | | <div class="company-name">é¼è¯çå®ä¸æé责任å
¬å¸</div> |
| | | <div class="company-name">æµ·å·å¼å¿é£åæéå
¬å¸</div> |
| | | <div class="document-title">é¶å®åè´§å</div> |
| | | </div> |
| | | |
| | |
| | | } |
| | | } |
| | | </style> |
| | | |
| | | |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-tabs v-model="activeTab" @tab-change="handleTabChange"> |
| | | <el-tab-pane label="æååºåº" name="production"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">ä¾åºååç§°ï¼</span> |
| | | <el-input v-model="searchForm.supplierName" style="width: 240px" placeholder="请è¾å
¥" @change="handleQuery" |
| | | clearable prefix-icon="Search" /> |
| | | <span class="search_title ml10">å
¥åºæ¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.timeStr" |
| | | type="date" |
| | | placeholder="è¯·éæ©æ¥æ" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | <span class="search_title ml10">产å大类ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.productCategory" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">æç´¢</el-button> |
| | | </div> |
| | | <div> |
| | | <!-- <el-button type="primary" @click="openForm('add')">æ°å¢åºåº</el-button> --> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <!-- <el-button type="danger" plain @click="handleDelete">å é¤</el-button> --> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <el-table :data="tableData" border v-loading="tableLoading" |
| | | :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%" |
| | | :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)"> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column label="éå®ååå·" prop="salesContractNo" width="180" show-overflow-tooltip /> |
| | | <el-table-column label="产å大类" prop="productCategory" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" show-overflow-tooltip /> |
| | | <el-table-column label="åä½" prop="unit" width="70" show-overflow-tooltip /> |
| | | <el-table-column label="å©ä½åºå" prop="inboundNum0" width="90" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="æä½" min-width="60" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="openForm(scope.row);">åè´§</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" :limit="page.size" @pagination="paginationChange" /> |
| | | </div> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="åæåºåº" name="purchase"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title ml10">产å大类ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.productCategory" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">æç´¢</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | |
| | | :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)"> |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column label="å
¥åºæ¶é´" prop="createTime" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å
¥åºæ¹æ¬¡" prop="inboundBatches" width="160" show-overflow-tooltip /> |
| | | <el-table-column label="ä¾åºååç§°" prop="supplierName" width="240" show-overflow-tooltip /> |
| | | <el-table-column label="产å大类" prop="productCategory" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" width="200" show-overflow-tooltip /> |
| | | <el-table-column label="éè´ååå·" prop="purchaseContractNumber" width="180" show-overflow-tooltip /> |
| | | <el-table-column label="产å大类" prop="productCategory" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" show-overflow-tooltip /> |
| | | <el-table-column label="åä½" prop="unit" width="70" show-overflow-tooltip /> |
| | | <el-table-column label="å
¥åºæ°é" prop="inboundNum" width="90" show-overflow-tooltip /> |
| | | <el-table-column label="åºåæ°é" prop="inboundNum0" width="90" show-overflow-tooltip /> |
| | | <el-table-column label="å«ç¨åä»·" prop="taxInclusiveUnitPrice" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å«ç¨æ»ä»·" prop="taxInclusiveTotalPrice" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="ç¨ç(%)" prop="taxRate" width="80" show-overflow-tooltip /> |
| | | <el-table-column label="ä¸å«ç¨æ»ä»·" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å
¥åºäºº" prop="createBy" width="80" show-overflow-tooltip /> |
| | | <el-table-column label="å©ä½åºå" prop="inboundNum0" width="90" show-overflow-tooltip /> |
| | | <el-table-column label="å«ç¨åä»·(å
)" prop="taxInclusiveUnitPrice" width="150"></el-table-column> |
| | | <el-table-column label="å«ç¨æ»ä»·(å
)" prop="taxInclusiveTotalPrice" width="150"></el-table-column> |
| | | <el-table-column fixed="right" label="æä½" min-width="60" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="openForm(scope.row);">é¢ç¨</el-button> |
| | |
| | | <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" :limit="page.size" @pagination="paginationChange" /> |
| | | </div> |
| | | <el-dialog v-model="dialogFormVisible" :title="'æ°å¢åºåº'" width="40%" @close="closeDia"> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="ææåºåº" name="manual"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title ml10">产å大类ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.productCategory" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">æç´¢</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange" |
| | | :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%" |
| | | :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)"> |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column label="æ¹æ¬¡å·" prop="code" width="130" show-overflow-tooltip /> |
| | | <el-table-column label="产å大类" prop="productCategory" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" show-overflow-tooltip /> |
| | | <el-table-column label="åä½" prop="unit" width="70" show-overflow-tooltip /> |
| | | <el-table-column label="ç©åç±»å" prop="itemType" show-overflow-tooltip /> |
| | | <el-table-column label="å©ä½åºå" prop="inboundNum0" width="90" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="æä½" width="100" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="openForm(scope.row);">é¢ç¨</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" :limit="page.size" @pagination="paginationChange" /> |
| | | </div> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | <el-dialog v-model="dialogFormVisible" :title="getDialogTitle()" width="40%" @close="closeDia"> |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> |
| | | <el-form-item label="åºåºæ°éï¼" prop="salesContractNo"> |
| | | <div>{{getAvailableQuantityText()}}:{{currentRowNum}}</div> |
| | | <el-form-item :label="getQuantityLabel()" prop="salesContractNo"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="form.inboundQuantity" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | <el-form-item label="åºåºæ¥æï¼" prop="projectName"> |
| | | <el-form-item :label="getDateLabel()" prop="projectName"> |
| | | <el-date-picker style="width: 100%" v-model="form.inboundTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD" |
| | | type="date" placeholder="è¯·éæ©" clearable /> |
| | | </el-form-item> |
| | | <el-form-item label="åºåºäººï¼" prop="entryPerson"> |
| | | <el-select v-model="form.nickName" placeholder="è¯·éæ©" clearable> |
| | | <el-form-item :label="getPersonLabel()" prop="entryPerson"> |
| | | <el-select v-model="form.nickName" filterable |
| | | default-first-option |
| | | :reserve-keyword="false" placeholder="è¯·éæ©" clearable> |
| | | <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" /> |
| | | </el-select> |
| | | </el-form-item> |
| | |
| | | |
| | | <script setup> |
| | | import pagination from '@/components/PIMTable/Pagination.vue' |
| | | import { ref } from 'vue' |
| | | import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue' |
| | | import { ElMessageBox } from "element-plus"; |
| | | import useUserStore from '@/store/modules/user' |
| | | import { userListNoPageByTenantId } from "@/api/system/user.js"; |
| | | import { |
| | | getStockInPage |
| | | getStockInPage, |
| | | getStockInPageByProduction, |
| | | getStockInPageByCustom, getInPageByCustom |
| | | } from "@/api/inventoryManagement/stockIn.js"; |
| | | import { |
| | | getStockManagePage, |
| | |
| | | |
| | | // ç¨æ·ä¿¡æ¯è¡¨åå¼¹æ¡æ°æ® |
| | | const dialogFormVisible = ref(false) |
| | | const activeTab = ref('production') |
| | | const data = reactive({ |
| | | searchForm: { |
| | | supplierName: '', |
| | | customerName: '', |
| | | inboundQuantity:'', |
| | | inboundTime:'', |
| | | nickName: '', |
| | | userId: '', |
| | | timeStr: '', |
| | | productCategory:'', |
| | | timeStr: getCurrentDate(), |
| | | }, |
| | | form: { |
| | | productrecordId: '', |
| | |
| | | } |
| | | const getList = () => { |
| | | tableLoading.value = true |
| | | getStockInPage({ ...searchForm.value, ...page }).then(res => { |
| | | const params = { ...page } |
| | | if (activeTab.value === 'production') { |
| | | params.customerName = searchForm.value.customerName |
| | | params.timeStr = searchForm.value.timeStr |
| | | } else { |
| | | params.supplierName = searchForm.value.supplierName |
| | | params.timeStr = searchForm.value.timeStr |
| | | } |
| | | params.productCategory = searchForm.value.productCategory |
| | | let apiCall |
| | | if (activeTab.value === 'production') { |
| | | apiCall = getStockInPageByProduction(params) |
| | | } else if (activeTab.value === 'manual') { |
| | | apiCall = getInPageByCustom(params) |
| | | } else { |
| | | apiCall = getStockInPage(params) |
| | | } |
| | | apiCall.then(res => { |
| | | tableLoading.value = false |
| | | tableData.value = res.data.records |
| | | total.value = res.data.total |
| | | console.log('res', res.data.records) |
| | | }).catch(() => { |
| | | tableLoading.value = false |
| | | }) |
| | | } |
| | | |
| | | const handleTabChange = () => { |
| | | page.current = 1 |
| | | searchForm.value.supplierName = '' |
| | | searchForm.value.customerName = '' |
| | | searchForm.value.timeStr = '' |
| | | selectedRows.value = [] |
| | | searchForm.value.productCategory = '' |
| | | getList() |
| | | } |
| | | |
| | | const findNodeById = (nodes, productId) => { |
| | |
| | | } |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid && currentRowId.value) { |
| | | const typeMap = { production: 2, purchase: 1, manual: 3 } |
| | | const outData = { |
| | | id: currentRowId.value, // åå§è®°å½ID |
| | | salesLedgerProductId: salesLedgerProductId.value, |
| | | salesLedgerProductId: activeTab.value === 'manual' ? 0 : salesLedgerProductId.value, |
| | | quantity: form.value.inboundQuantity, // åºåºæ°é |
| | | time: form.value.inboundTime, // åºåºæ¶é´ |
| | | userId: form.value.nickName // æä½äºº |
| | | userId: form.value.nickName, // æä½äºº |
| | | type: typeMap[activeTab.value] // åºåºç±»åï¼éè´1ï¼ç产2ï¼èªå®ä¹3 |
| | | } |
| | | console.log(outData) |
| | | |
| | |
| | | type: 'warning', |
| | | } |
| | | ).then(() => { |
| | | proxy.download("/stockin/export", {}, 'å
¥åºå°è´¦.xlsx') |
| | | // æ ¹æ®ä¸åç tab ç±»åè°ç¨ä¸åçå¯¼åºæ¥å£ |
| | | let exportUrl = "/stockin/export" |
| | | if (activeTab.value === 'production') { |
| | | exportUrl = "/stockin/exportOne" |
| | | } else if (activeTab.value === 'manual') { |
| | | exportUrl = "/stockin/exportTwo" |
| | | } |
| | | proxy.download(exportUrl, {}, 'å
¥åºå°è´¦.xlsx') |
| | | }).catch(() => { |
| | | proxy.$modal.msg("已忶") |
| | | }) |
| | |
| | | const day = String(today.getDate()).padStart(2, '0'); |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | |
| | | // æ ¹æ®tabç±»åè·åå¼¹æ¡æ é¢ |
| | | const getDialogTitle = () => { |
| | | const titleMap = { |
| | | production: 'æ°å¢åè´§', |
| | | purchase: 'æ°å¢é¢ç¨', |
| | | manual: 'æ°å¢é¢ç¨' |
| | | }; |
| | | return titleMap[activeTab.value] || 'æ°å¢åºåº'; |
| | | }; |
| | | |
| | | // æ ¹æ®tabç±»åè·åå¯åºåºæ°éææ¬ |
| | | const getAvailableQuantityText = () => { |
| | | const textMap = { |
| | | production: 'å¯åè´§æ°é', |
| | | purchase: 'å¯é¢ç¨æ°é', |
| | | manual: 'å¯é¢ç¨æ°é' |
| | | }; |
| | | return textMap[activeTab.value] || 'å¯åºåºæ°é'; |
| | | }; |
| | | |
| | | // æ ¹æ®tabç±»åè·åæ°éåæ®µæ ç¾ |
| | | const getQuantityLabel = () => { |
| | | const labelMap = { |
| | | production: 'åè´§æ°éï¼', |
| | | purchase: 'é¢ç¨æ°éï¼', |
| | | manual: 'é¢ç¨æ°éï¼' |
| | | }; |
| | | return labelMap[activeTab.value] || 'åºåºæ°éï¼'; |
| | | }; |
| | | |
| | | // æ ¹æ®tabç±»åè·åæ¥æåæ®µæ ç¾ |
| | | const getDateLabel = () => { |
| | | const labelMap = { |
| | | production: 'åè´§æ¥æï¼', |
| | | purchase: 'é¢ç¨æ¥æï¼', |
| | | manual: 'é¢ç¨æ¥æï¼' |
| | | }; |
| | | return labelMap[activeTab.value] || 'åºåºæ¥æï¼'; |
| | | }; |
| | | |
| | | // æ ¹æ®tabç±»åè·å人ååæ®µæ ç¾ |
| | | const getPersonLabel = () => { |
| | | const labelMap = { |
| | | production: 'å货人ï¼', |
| | | purchase: 'é¢ç¨äººï¼', |
| | | manual: 'é¢ç¨äººï¼' |
| | | }; |
| | | return labelMap[activeTab.value] || 'åºåºäººï¼'; |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList() |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"></style> |
| | | |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog v-model="dialogFormVisible" :title="getDialogTitle()" width="70%" |
| | | @close="closeDia"> |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> |
| | | <el-form-item label="éè´è®¢åå·" prop="purchaseContractNumber"> |
| | | <el-select |
| | | v-model="form.purchaseContractNumber" |
| | | placeholder="è¯·éæ©éè´è®¢åå·" |
| | | clearable |
| | | filterable |
| | | :loading="loadingPurchaseOptions" |
| | | @change="handlePurchaseChange" |
| | | :disabled="operationType === 'edit'" |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="item in purchaseOptions" |
| | | :key="item.purchaseContractNumber" |
| | | :label="formatPurchaseOption(item)" |
| | | :value="item.purchaseContractNumber" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-table |
| | | :data="productList" |
| | | border |
| | | v-loading="loadingProducts" |
| | | @selection-change="handleSelectionChange" |
| | | > |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column |
| | | align="center" |
| | | label="åºå·" |
| | | type="index" |
| | | width="60" |
| | | /> |
| | | <el-table-column label="产å大类" prop="productCategory" /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" /> |
| | | <el-table-column label="åä½" prop="unit" width="70" /> |
| | | <!-- <el-table-column label="ä¾åºå" prop="supplierName" width="100" /> --> |
| | | <el-table-column label="éè´æ°é" prop="quantity" width="100" /> |
| | | <el-table-column label="å¾
å
¥åºæ°é" prop="quantity0" width="100" /> |
| | | <el-table-column label="æ¬æ¬¡å
¥åºæ°é" prop="quantityStock" width="150"> |
| | | <template #default="scope"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.quantityStock" @change="() => calculateTotalPrice(scope.row)" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç¨ç(%)" prop="taxRate" width="120" /> |
| | | <el-table-column label="åä»·(å
)" prop="taxInclusiveUnitPrice" width="150"> |
| | | <template #default="scope"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.taxInclusiveUnitPrice" @change="() => calculateTotalPrice(scope.row)" :disabled="operationType === 'edit'"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æ»ä»·(å
)" |
| | | :formatter="formattedNumber" |
| | | prop="taxInclusiveTotalPrice" |
| | | width="150" |
| | | > |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, toRefs, getCurrentInstance } from 'vue' |
| | | import useUserStore from '@/store/modules/user' |
| | | import { |
| | | updateStockIn, |
| | | addSutockIn, |
| | | selectProductRecordListByPuechaserId |
| | | } from "@/api/inventoryManagement/stockIn.js"; |
| | | import { purchaseListPage } from "@/api/procurementManagement/procurementLedger.js"; |
| | | |
| | | const userStore = useUserStore() |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close', 'success']) |
| | | |
| | | const operationType = ref('')// æä½ç±»å: 'add' æ 'edit' |
| | | const dialogFormVisible = ref(false)// å¼¹æ¡æ¾ç¤ºç¶æ |
| | | const productList = ref([]);// 产ååè¡¨æ°æ® |
| | | const loadingProducts = ref(false);// 产åå è½½ç¶æ |
| | | const selectedRows = ref([]) // 产åè¡¨æ ¼éä¸è¡ |
| | | const purchaseOptions = ref([]) |
| | | const loadingPurchaseOptions = ref(false) |
| | | const loading = ref(false); |
| | | |
| | | const data = reactive({ |
| | | form: { |
| | | id: null, |
| | | purchaseContractNumber: '', // éè´è®¢åå· |
| | | supplierId: null, // ä¾åºåID |
| | | supplierName: '', // ä¾åºååç§° |
| | | inboundTime: '', // å
¥åºæ¶é´ |
| | | inboundBatch: '', // å
¥åºæ¹æ¬¡ |
| | | recorderId: userStore.userId, // å½å
¥äººID |
| | | recorderName: userStore.name, // å½å
¥äººå§å |
| | | entryDate: getCurrentDate(), // å½å
¥æ¥æ |
| | | remark: '', // 夿³¨ |
| | | }, |
| | | rules: { |
| | | purchaseContractNumber: [{ required: true, message: "请è¾å
¥éè´ååå·", trigger: "blur" }], |
| | | supplierId: [{ required: true, message: "è¯·éæ©ä¾åºå", trigger: "change" }], |
| | | inboundTime: [{ required: true, message: "è¯·éæ©å
¥åºæ¶é´", trigger: "change" }], |
| | | inboundBatch: [{ required: true, message: "请è¾å
¥å
¥åºæ¹æ¬¡", trigger: "blur" }] |
| | | } |
| | | }) |
| | | const { form, rules } = toRefs(data) |
| | | |
| | | // å¨æè®¡ç®å¯¹è¯æ¡æ é¢ |
| | | const getDialogTitle = () => { |
| | | return operationType.value === 'add' ? 'æ°å¢å
¥åº' : 'ç¼è¾å
¥åº' |
| | | } |
| | | |
| | | const formatPurchaseOption = (item = {}) => { |
| | | const contract = item.purchaseContractNumber || '--'; |
| | | const supplier = item.supplierName ? ` · ${item.supplierName}` : ''; |
| | | return `${contract}${supplier}`; |
| | | }; |
| | | |
| | | const loadPurchaseOptions = async (keyword = '') => { |
| | | try { |
| | | loadingPurchaseOptions.value = true; |
| | | const res = await purchaseListPage({ |
| | | current: -1, |
| | | size: -1, |
| | | purchaseContractNumber: keyword, |
| | | }); |
| | | const records = res.data?.records || []; |
| | | purchaseOptions.value = records; |
| | | if ( |
| | | form.value.purchaseContractNumber && |
| | | !purchaseOptions.value.find( |
| | | (item) => item.purchaseContractNumber === form.value.purchaseContractNumber |
| | | ) |
| | | ) { |
| | | purchaseOptions.value.push({ |
| | | purchaseContractNumber: form.value.purchaseContractNumber, |
| | | supplierName: form.value.supplierName, |
| | | supplierId: form.value.supplierId, |
| | | }); |
| | | } |
| | | } finally { |
| | | loadingPurchaseOptions.value = false; |
| | | } |
| | | }; |
| | | |
| | | const handlePurchaseChange = (value) => { |
| | | form.value.purchaseContractNumber = value || ''; |
| | | const matched = purchaseOptions.value.find( |
| | | (item) => item.purchaseContractNumber === value |
| | | ); |
| | | if (matched) { |
| | | form.value.supplierName = matched.supplierName || form.value.supplierName; |
| | | form.value.supplierId = matched.supplierId || form.value.supplierId; |
| | | } |
| | | if (!value) { |
| | | productList.value = []; |
| | | return; |
| | | } |
| | | fetchProductsByContract(); |
| | | }; |
| | | |
| | | const exceedsAddLimit = (product) => { |
| | | const stock = Number(product?.quantityStock ?? 0); |
| | | const waiting = Number(product?.quantity0 ?? 0); |
| | | if (!Number.isFinite(stock) || !Number.isFinite(waiting)) { |
| | | return false; |
| | | } |
| | | return stock > waiting; |
| | | }; |
| | | |
| | | const exceedsEditLimit = (product) => { |
| | | const stock = Number(product?.quantityStock ?? 0); |
| | | const waiting = Number(product?.quantity0 ?? 0); |
| | | const original = Number(product?.originalQuantityStock ?? 0); |
| | | if (!Number.isFinite(stock) || !Number.isFinite(waiting) || !Number.isFinite(original)) { |
| | | return false; |
| | | } |
| | | return stock > waiting + original; |
| | | }; |
| | | |
| | | const formattedNumber = (row, column, cellValue) => { |
| | | return parseFloat(cellValue).toFixed(2); |
| | | }; |
| | | |
| | | // è®¡ç®æ»ä»· |
| | | const calculateTotalPrice = (row) => { |
| | | const quantityStock = Number(row?.quantityStock ?? 0); |
| | | const taxInclusiveUnitPrice = Number(row?.taxInclusiveUnitPrice ?? 0); |
| | | |
| | | if (Number.isFinite(quantityStock) && Number.isFinite(taxInclusiveUnitPrice)) { |
| | | row.taxInclusiveTotalPrice = quantityStock * taxInclusiveUnitPrice; |
| | | } else { |
| | | row.taxInclusiveTotalPrice = 0; |
| | | } |
| | | }; |
| | | |
| | | const fetchProductsByContract = async () => { |
| | | if (!form.value.purchaseContractNumber) { |
| | | proxy.$modal.msgWarning('è¯·éæ©ååå·') |
| | | return |
| | | } |
| | | try { |
| | | loadingProducts.value = true |
| | | const productRes = await selectProductRecordListByPuechaserId({ |
| | | purchaseContractNumber: form.value.purchaseContractNumber |
| | | }); |
| | | if (!productRes.data || productRes.data.length === 0) { |
| | | proxy.$modal.msgWarning('该åå䏿²¡æäº§åè®°å½') |
| | | productList.value = []; |
| | | return |
| | | } |
| | | productList.value = productRes.data.map(item => ({ |
| | | ...item, |
| | | quantityStock: 0, |
| | | taxInclusiveUnitPrice: Number(item?.taxInclusiveUnitPrice ?? 0), |
| | | taxInclusiveTotalPrice: 0, |
| | | originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? 0), |
| | | })) |
| | | } catch (error) { |
| | | console.error('æ¥è¯¢äº§åè®°å½å¤±è´¥:', error) |
| | | proxy.$modal.msgError('æ¥è¯¢äº§åè®°å½å¤±è´¥') |
| | | productList.value = []; |
| | | } finally { |
| | | loadingProducts.value = false |
| | | } |
| | | } |
| | | |
| | | const updatePro = async () => { |
| | | if (selectedRows.value.length === 0) { |
| | | proxy.$modal.msgWarning('请å
éæ©äº§å'); |
| | | return; |
| | | } |
| | | const target = selectedRows.value[0]; |
| | | const stock = Number(target?.quantityStock ?? 0); |
| | | if (!Number.isFinite(stock) || stock <= 0) { |
| | | proxy.$modal.msgWarning('è¯·å¡«åææçå
¥åºæ°é'); |
| | | return; |
| | | } |
| | | if (exceedsEditLimit(target)) { |
| | | proxy.$modal.msgError('æ¬æ¬¡å
¥åºæ°éä¸è½è¶
è¿åå
¥åºæ°éä¸å¾
å
¥åºæ°éä¹å'); |
| | | return; |
| | | } |
| | | const stockInData = { |
| | | id: selectedRows.value[0].recordId, |
| | | quantityStock: Number(selectedRows.value[0].quantityStock), |
| | | }; |
| | | await updateStockIn(stockInData) |
| | | proxy.$modal.msgSuccess('ä¿®æ¹å
¥åºæå') |
| | | closeDia() |
| | | emit('success') |
| | | } |
| | | |
| | | const submitForm = async () => { |
| | | if (selectedRows.value.length === 0) { |
| | | proxy.$modal.msgWarning('请å
éæ©éè´ååå¹¶éæ©äº§å') |
| | | return |
| | | } |
| | | if(operationType.value !== 'add'){ |
| | | await updatePro() |
| | | return |
| | | } |
| | | try { |
| | | await proxy.$refs.formRef.validate() |
| | | const invalidProducts = selectedRows.value.filter((product) => { |
| | | const stock = Number(product?.quantityStock ?? 0); |
| | | if (!Number.isFinite(stock) || stock <= 0) { |
| | | return true; |
| | | } |
| | | return exceedsAddLimit(product); |
| | | }) |
| | | |
| | | if (invalidProducts.length > 0) { |
| | | proxy.$modal.msgError('æ¬æ¬¡å
¥åºæ°éé大äº0ï¼ä¸ä¸è½è¶
è¿å¾
å
¥åºæ°é') |
| | | return |
| | | } |
| | | |
| | | const stockInData = { |
| | | ...form.value, |
| | | inboundTime: formatDateTime(form.value.inboundTime), |
| | | nickName: userStore.nickName, |
| | | details: selectedRows.value.map(product => ({ |
| | | id: product.id, |
| | | inboundQuantity: Number(product.quantityStock), |
| | | taxInclusiveUnitPrice: Number(product.taxInclusiveUnitPrice), |
| | | taxInclusiveTotalPrice: Number(product.taxInclusiveTotalPrice) |
| | | })), |
| | | }; |
| | | loading.value = true |
| | | await addSutockIn(stockInData) |
| | | |
| | | proxy.$modal.msgSuccess('æ°å¢å
¥åºæå') |
| | | closeDia() |
| | | emit('success') |
| | | |
| | | } catch (error) { |
| | | console.error('æäº¤å¤±è´¥:', error) |
| | | if (!error.errors) { |
| | | proxy.$modal.msgError('æä½å¤±è´¥ï¼è¯·éè¯') |
| | | } |
| | | } finally { |
| | | loading.value = false |
| | | } |
| | | } |
| | | |
| | | const closeDia = () => { |
| | | proxy.$refs.formRef.resetFields() |
| | | dialogFormVisible.value = false |
| | | emit('close') |
| | | } |
| | | |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection.filter(item => item.id); |
| | | } |
| | | |
| | | function formatDateTime(date = new Date(), includeTime = true) { |
| | | const d = new Date(date); |
| | | const year = d.getFullYear(); |
| | | const month = String(d.getMonth() + 1).padStart(2, '0'); |
| | | const day = String(d.getDate()).padStart(2, '0'); |
| | | |
| | | if (!includeTime) { |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | |
| | | const hours = String(d.getHours()).padStart(2, '0'); |
| | | const minutes = String(d.getMinutes()).padStart(2, '0'); |
| | | const seconds = String(d.getSeconds()).padStart(2, '0'); |
| | | |
| | | return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; |
| | | } |
| | | |
| | | function getCurrentDate() { |
| | | return formatDateTime(new Date(), false); |
| | | } |
| | | |
| | | const openDialog = async (type, row) => { |
| | | operationType.value = type |
| | | dialogFormVisible.value = true |
| | | selectedRows.value = [] |
| | | await loadPurchaseOptions(); |
| | | |
| | | if (type === 'add') { |
| | | form.value = { |
| | | id: null, |
| | | purchaseContractNumber: '', |
| | | supplierId: null, |
| | | supplierName: '', |
| | | inboundTime: '', |
| | | inboundBatch: '', |
| | | recorderId: userStore.userId, |
| | | recorderName: userStore.name, |
| | | entryDate: getCurrentDate(), |
| | | remark: '' |
| | | } |
| | | productList.value = [] |
| | | } else { |
| | | form.value = JSON.parse(JSON.stringify(row)) |
| | | try { |
| | | loadingProducts.value = true |
| | | const res = await selectProductRecordListByPuechaserId({ |
| | | purchaseContractNumber: form.value.purchaseContractNumber, |
| | | id: row.id |
| | | }); |
| | | productList.value = res.data.map(item => ({ |
| | | ...item, |
| | | quantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0), |
| | | taxInclusiveUnitPrice: Number(item?.taxInclusiveUnitPrice ?? 0), |
| | | taxInclusiveTotalPrice: Number(item?.quantityStock ?? 0) * Number(item?.taxInclusiveUnitPrice ?? 0), |
| | | originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0), |
| | | })) |
| | | selectedRows.value = productList.value |
| | | } catch (error) { |
| | | console.error('å 载产å失败:', error) |
| | | proxy.$modal.msgError('å 载产å失败') |
| | | productList.value = [] |
| | | } finally { |
| | | loadingProducts.value = false |
| | | } |
| | | } |
| | | } |
| | | |
| | | defineExpose({ |
| | | openDialog, |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"></style> |
| | | |
| | | |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? 'æ°å¢èªå®ä¹å
¥åº' : 'ç¼è¾èªå®ä¹å
¥åº'" width="70%" |
| | | @close="closeDia"> |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> |
| | | <div style="margin-bottom: 10px;" v-if="operationType === 'add'"> |
| | | <el-button type="primary" @click="addProductRow">æ°å¢</el-button> |
| | | </div> |
| | | <el-table |
| | | :data="productList" |
| | | border |
| | | v-loading="loadingProducts" |
| | | > |
| | | <el-table-column |
| | | align="center" |
| | | label="åºå·" |
| | | type="index" |
| | | width="60" |
| | | /> |
| | | <el-table-column label="产å大类" prop="productCategory" width="200"> |
| | | <template #default="scope"> |
| | | <el-input v-model="scope.row.productCategory" placeholder="请è¾å
¥äº§å大类" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" width="200"> |
| | | <template #default="scope"> |
| | | <el-input v-model="scope.row.specificationModel" placeholder="请è¾å
¥è§æ ¼åå·" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åä½" prop="unit" width="100"> |
| | | <template #default="scope"> |
| | | <el-input v-model="scope.row.unit" placeholder="请è¾å
¥åä½" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ä¾åºå" prop="supplierName" width="200"> |
| | | <template #default="scope"> |
| | | <el-input v-model="scope.row.supplierName" placeholder="请è¾å
¥ä¾åºå" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç©åç±»å" prop="itemType" width="150"> |
| | | <template #default="scope"> |
| | | <el-select v-model="scope.row.itemType" filterable allow-create placeholder="è¯·éæ©ç©åç±»å" style="width: 100%"> |
| | | <el-option |
| | | v-for="item in itemTypeOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å
¥åºæ°é" prop="inboundNum" width="150"> |
| | | <template #default="scope"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.inboundNum" @change="() => calculateTotalPrice(scope.row)" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å
¥åºæ¥æ" prop="inboundDate" width="180"> |
| | | <template #default="scope"> |
| | | <el-date-picker |
| | | v-model="scope.row.inboundDate" |
| | | type="date" |
| | | placeholder="è¯·éæ©å
¥åºæ¥æ" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | style="width: 100%" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æ°é" prop="quantityStock" width="150"> |
| | | <template #default="scope"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.quantityStock" @change="() => calculateTotalPrice(scope.row)" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åä»·(å
)" prop="taxInclusiveUnitPrice" width="150"> |
| | | <template #default="scope"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.taxInclusiveUnitPrice" @change="() => calculateTotalPrice(scope.row)" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æ»ä»·(å
)" |
| | | prop="taxInclusiveTotalPrice" |
| | | width="150" |
| | | > |
| | | </el-table-column> |
| | | <el-table-column label="æä½" width="80" v-if="operationType === 'add'"> |
| | | <template #default="scope"> |
| | | <el-button type="danger" size="small" @click="removeProductRow(scope.$index)">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, toRefs, getCurrentInstance } from 'vue' |
| | | import useUserStore from '@/store/modules/user' |
| | | import { |
| | | addStockInCustom, |
| | | updateStockInCustom, |
| | | } from "@/api/inventoryManagement/stockIn.js"; |
| | | |
| | | const userStore = useUserStore() |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close', 'success']) |
| | | |
| | | const operationType = ref('')// æä½ç±»å: 'add' æ 'edit' |
| | | const dialogFormVisible = ref(false)// å¼¹æ¡æ¾ç¤ºç¶æ |
| | | const productList = ref([]);// 产ååè¡¨æ°æ® |
| | | const loadingProducts = ref(false);// 产åå è½½ç¶æ |
| | | const loading = ref(false); |
| | | |
| | | function formatDateTime(date = new Date(), includeTime = true) { |
| | | const d = new Date(date); |
| | | const year = d.getFullYear(); |
| | | const month = String(d.getMonth() + 1).padStart(2, '0'); |
| | | const day = String(d.getDate()).padStart(2, '0'); |
| | | |
| | | if (!includeTime) { |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | |
| | | const hours = String(d.getHours()).padStart(2, '0'); |
| | | const minutes = String(d.getMinutes()).padStart(2, '0'); |
| | | const seconds = String(d.getSeconds()).padStart(2, '0'); |
| | | |
| | | return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; |
| | | } |
| | | |
| | | function getCurrentDate() { |
| | | return formatDateTime(new Date(), false); |
| | | } |
| | | |
| | | const itemTypeOptions = [ |
| | | { label: 'ç©æ', value: 'ç©æ' }, |
| | | { label: 'åæ', value: 'åæ' }, |
| | | { label: 'æå', value: 'æå' }, |
| | | { label: 'å
¶ä»', value: 'å
¶ä»' }, |
| | | ] |
| | | |
| | | const taxRateOptions = [ |
| | | { label: '1', value: 1 }, |
| | | { label: '6', value: 6 }, |
| | | { label: '13', value: 13 }, |
| | | ] |
| | | |
| | | const data = reactive({ |
| | | form: { |
| | | id: null, |
| | | supplierId: null, // ä¾åºåID |
| | | supplierName: '', // ä¾åºååç§° |
| | | recorderId: userStore.userId, // å½å
¥äººID |
| | | recorderName: userStore.name, // å½å
¥äººå§å |
| | | entryDate: getCurrentDate(), // å½å
¥æ¥æ |
| | | remark: '', // 夿³¨ |
| | | }, |
| | | rules: { |
| | | supplierName: [{ required: true, message: "请è¾å
¥ä¾åºååç§°", trigger: "blur" }] |
| | | } |
| | | }) |
| | | const { form, rules } = toRefs(data) |
| | | |
| | | // æ°å¢äº§åè¡ |
| | | const addProductRow = () => { |
| | | productList.value.push({ |
| | | id: null, |
| | | productCategory: '', |
| | | specificationModel: '', |
| | | unit: '', |
| | | supplierName: form.value.supplierName || '', |
| | | itemType: '', |
| | | inboundNum: 0, |
| | | inboundDate: '', |
| | | quantityStock: 0, |
| | | taxInclusiveUnitPrice: 0, |
| | | taxInclusiveTotalPrice: 0, |
| | | taxRate: null, |
| | | taxExclusiveTotalPrice: 0, |
| | | }); |
| | | }; |
| | | |
| | | // å é¤äº§åè¡ |
| | | const removeProductRow = (index) => { |
| | | productList.value.splice(index, 1); |
| | | }; |
| | | |
| | | // è®¡ç®æ»ä»·ï¼æ ¹æ®æ°éãåä»·åå«ç¨åä»·ï¼ |
| | | const calculateTotalPrice = (row) => { |
| | | // è®¡ç®æ®éæ»ä»·ï¼quantityStock * taxInclusiveUnitPrice |
| | | const quantity = Number(row.quantityStock || 0); |
| | | const taxInclusiveUnitPrice = Number(row.taxInclusiveUnitPrice || 0); |
| | | row.taxInclusiveTotalPrice = quantity * taxInclusiveUnitPrice; |
| | | calculateExclusivePrice(row); |
| | | }; |
| | | |
| | | // 计ç®ä¸å«ç¨æ»ä»·ï¼æ ¹æ®å«ç¨æ»ä»·åç¨çï¼ |
| | | const calculateExclusivePrice = (row) => { |
| | | const taxInclusiveTotalPrice = Number(row.taxInclusiveTotalPrice || 0); |
| | | const taxRate = Number(row.taxRate || 0); |
| | | row.taxExclusiveTotalPrice = taxInclusiveTotalPrice / (1 + taxRate / 100); |
| | | }; |
| | | |
| | | const submitForm = async () => { |
| | | try { |
| | | await proxy.$refs.formRef.validate() |
| | | |
| | | if (!productList.value.length) { |
| | | proxy.$modal.msgError('请è³å°æ·»å 䏿¡äº§åæ°æ®') |
| | | return |
| | | } |
| | | |
| | | // éªè¯èªå®ä¹æ·»å çæ°æ®å¿
å¡«åæ®µ |
| | | for (let i = 0; i < productList.value.length; i++) { |
| | | const product = productList.value[i]; |
| | | if (!product.productCategory || !product.specificationModel || !product.unit) { |
| | | proxy.$modal.msgError(`第${i + 1}è¡äº§åæ°æ®æªå¡«å宿´ï¼äº§å大类ãè§æ ¼åå·ãåä½ä¸ºå¿
å¡«ï¼`) |
| | | return |
| | | } |
| | | if (!product.itemType) { |
| | | proxy.$modal.msgError(`第${i + 1}è¡è¯·éæ©ç©åç±»å`) |
| | | return |
| | | } |
| | | if (!product.inboundDate) { |
| | | proxy.$modal.msgError(`第${i + 1}è¡è¯·éæ©å
¥åºæ¥æ`) |
| | | return |
| | | } |
| | | const stock = Number(product?.inboundNum ?? 0); |
| | | if (!Number.isFinite(stock) || stock <= 0) { |
| | | proxy.$modal.msgError(`第${i + 1}è¡æ¬æ¬¡å
¥åºæ°éé大äº0`) |
| | | return |
| | | } |
| | | } |
| | | |
| | | const payloadList = productList.value.map(product => ({ |
| | | id: product.id ?? null, |
| | | inboundNum: Number(product.inboundNum), |
| | | productCategory: product.productCategory, |
| | | specificationModel: product.specificationModel, |
| | | unit: product.unit, |
| | | supplierName: product.supplierName || form.value.supplierName, |
| | | itemType: product.itemType, |
| | | inboundDate: formatDateTime(product.inboundDate, false), |
| | | taxRate: Number(product.taxRate || 0), |
| | | taxExclusiveTotalPrice: Number(product.taxExclusiveTotalPrice || 0), |
| | | taxInclusiveUnitPrice: Number(product.taxInclusiveUnitPrice || 0), |
| | | taxInclusiveTotalPrice: Number(product.taxInclusiveTotalPrice || 0), |
| | | })); |
| | | loading.value = true |
| | | if (operationType.value === 'edit') { |
| | | const editPayload = payloadList[0] |
| | | await updateStockInCustom(editPayload) |
| | | } else { |
| | | await addStockInCustom(payloadList) |
| | | } |
| | | |
| | | proxy.$modal.msgSuccess(operationType.value === 'edit' ? 'ç¼è¾èªå®ä¹å
¥åºæå' : 'æ°å¢èªå®ä¹å
¥åºæå') |
| | | closeDia() |
| | | emit('success') |
| | | |
| | | } catch (error) { |
| | | console.error('æäº¤å¤±è´¥:', error) |
| | | if (!error.errors) { |
| | | proxy.$modal.msgError('æä½å¤±è´¥ï¼è¯·éè¯') |
| | | } |
| | | } finally { |
| | | loading.value = false |
| | | } |
| | | } |
| | | |
| | | const closeDia = () => { |
| | | proxy.$refs.formRef.resetFields() |
| | | dialogFormVisible.value = false |
| | | productList.value = [] |
| | | emit('close') |
| | | } |
| | | |
| | | const openDialog = async (type, row) => { |
| | | operationType.value = type |
| | | dialogFormVisible.value = true |
| | | |
| | | if (type === 'add') { |
| | | form.value = { |
| | | id: null, |
| | | supplierId: null, |
| | | supplierName: '', |
| | | recorderId: userStore.userId, |
| | | recorderName: userStore.name, |
| | | entryDate: getCurrentDate(), |
| | | remark: '' |
| | | } |
| | | productList.value = [] |
| | | } else { |
| | | // ç¼è¾æ¨¡å¼ï¼å°è¡æ°æ®å¡«å
å°è¡¨æ ¼ä¸ä»¥æ¯æä¿®æ¹ |
| | | form.value = { |
| | | id: row?.id ?? null, |
| | | supplierId: row?.supplierId ?? null, |
| | | supplierName: row?.supplierName ?? '', |
| | | recorderId: userStore.userId, |
| | | recorderName: userStore.name, |
| | | entryDate: getCurrentDate(), |
| | | remark: row?.remark ?? '' |
| | | } |
| | | productList.value = [{ |
| | | id: row?.id ?? null, |
| | | productCategory: row?.productCategory ?? '', |
| | | specificationModel: row?.specificationModel ?? '', |
| | | unit: row?.unit ?? '', |
| | | supplierName: row?.supplierName ?? '', |
| | | itemType: row?.itemType ?? '', |
| | | inboundNum: Number(row?.inboundNum ?? row?.inboundQuantity ?? 0), |
| | | inboundDate: row?.inboundDate ?? row?.createTime ?? '', |
| | | quantityStock: Number(row?.quantityStock ?? 0), |
| | | taxRate: Number(row?.taxRate ?? 0), |
| | | taxInclusiveUnitPrice: Number(row?.taxInclusiveUnitPrice ?? 0), |
| | | taxInclusiveTotalPrice: Number(row?.taxInclusiveTotalPrice ?? 0), |
| | | taxExclusiveTotalPrice: Number(row?.taxExclusiveTotalPrice ?? 0), |
| | | }] |
| | | } |
| | | } |
| | | |
| | | defineExpose({ |
| | | openDialog, |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"></style> |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? 'æ°å¢èªå®ä¹å
¥åº' : 'ç¼è¾èªå®ä¹å
¥åº'" width="70%" |
| | | @close="closeDia"> |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> |
| | | <div style="margin-bottom: 10px;" v-if="operationType === 'add'"> |
| | | <el-button type="primary" @click="addProductRow">æ°å¢</el-button> |
| | | </div> |
| | | <el-table |
| | | :data="productList" |
| | | border |
| | | v-loading="loadingProducts" |
| | | > |
| | | <el-table-column |
| | | align="center" |
| | | label="åºå·" |
| | | type="index" |
| | | width="60" |
| | | /> |
| | | <el-table-column label="产å大类" prop="productCategory" width="200"> |
| | | <template #default="scope"> |
| | | <el-input v-model="scope.row.productCategory" placeholder="请è¾å
¥äº§å大类" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" width="200"> |
| | | <template #default="scope"> |
| | | <el-input v-model="scope.row.specificationModel" placeholder="请è¾å
¥è§æ ¼åå·" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åä½" prop="unit" width="100"> |
| | | <template #default="scope"> |
| | | <el-input v-model="scope.row.unit" placeholder="请è¾å
¥åä½" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å
¥åºæ°é" prop="inboundNum" width="150"> |
| | | <template #default="scope"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.inboundNum" @change="() => calculateTotalPrice(scope.row)" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å
¥åºæ¥æ" prop="inboundDate" width="180"> |
| | | <template #default="scope"> |
| | | <el-date-picker |
| | | v-model="scope.row.inboundDate" |
| | | type="date" |
| | | placeholder="è¯·éæ©å
¥åºæ¥æ" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | style="width: 100%" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åä»·(å
)" prop="unitPrice" width="150"> |
| | | <template #default="scope"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.unitPrice" @change="() => calculateTotalPrice(scope.row)" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æ»ä»·(å
)" |
| | | prop="totalPrice" |
| | | width="150" |
| | | > |
| | | </el-table-column> |
| | | <el-table-column label="æä½" width="80" v-if="operationType === 'add'"> |
| | | <template #default="scope"> |
| | | <el-button type="danger" size="small" @click="removeProductRow(scope.$index)">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, toRefs, getCurrentInstance } from 'vue' |
| | | import useUserStore from '@/store/modules/user' |
| | | import { |
| | | addStockInCustom, updateProduct |
| | | } from "@/api/inventoryManagement/stockIn.js"; |
| | | |
| | | const userStore = useUserStore() |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close', 'success']) |
| | | |
| | | const operationType = ref('')// æä½ç±»å: 'add' æ 'edit' |
| | | const dialogFormVisible = ref(false)// å¼¹æ¡æ¾ç¤ºç¶æ |
| | | const productList = ref([]);// 产ååè¡¨æ°æ® |
| | | const loadingProducts = ref(false);// 产åå è½½ç¶æ |
| | | const loading = ref(false); |
| | | |
| | | function formatDateTime(date = new Date(), includeTime = true) { |
| | | const d = new Date(date); |
| | | const year = d.getFullYear(); |
| | | const month = String(d.getMonth() + 1).padStart(2, '0'); |
| | | const day = String(d.getDate()).padStart(2, '0'); |
| | | |
| | | if (!includeTime) { |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | |
| | | const hours = String(d.getHours()).padStart(2, '0'); |
| | | const minutes = String(d.getMinutes()).padStart(2, '0'); |
| | | const seconds = String(d.getSeconds()).padStart(2, '0'); |
| | | |
| | | return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; |
| | | } |
| | | |
| | | function getCurrentDate() { |
| | | return formatDateTime(new Date(), false); |
| | | } |
| | | |
| | | const itemTypeOptions = [ |
| | | { label: 'ç©æ', value: 'ç©æ' }, |
| | | { label: 'åæ', value: 'åæ' }, |
| | | { label: 'æå', value: 'æå' }, |
| | | { label: 'å
¶ä»', value: 'å
¶ä»' }, |
| | | ] |
| | | |
| | | const taxRateOptions = [ |
| | | { label: '1', value: 1 }, |
| | | { label: '6', value: 6 }, |
| | | { label: '13', value: 13 }, |
| | | ] |
| | | |
| | | const data = reactive({ |
| | | form: { |
| | | id: null, |
| | | supplierId: null, // ä¾åºåID |
| | | supplierName: '', // ä¾åºååç§° |
| | | recorderId: userStore.userId, // å½å
¥äººID |
| | | recorderName: userStore.name, // å½å
¥äººå§å |
| | | entryDate: getCurrentDate(), // å½å
¥æ¥æ |
| | | remark: '', // 夿³¨ |
| | | }, |
| | | rules: { |
| | | supplierName: [{ required: true, message: "请è¾å
¥ä¾åºååç§°", trigger: "blur" }] |
| | | } |
| | | }) |
| | | const { form, rules } = toRefs(data) |
| | | |
| | | // æ°å¢äº§åè¡ |
| | | const addProductRow = () => { |
| | | productList.value.push({ |
| | | id: null, |
| | | productCategory: '', |
| | | specificationModel: '', |
| | | unit: '', |
| | | supplierName: form.value.supplierName || '', |
| | | itemType: '', |
| | | inboundNum: 0, |
| | | inboundDate: '', |
| | | quantityStock: 0, |
| | | unitPrice: 0, |
| | | totalPrice: 0, |
| | | taxRate: null, |
| | | taxExclusiveTotalPrice: 0, |
| | | }); |
| | | }; |
| | | |
| | | // å é¤äº§åè¡ |
| | | const removeProductRow = (index) => { |
| | | productList.value.splice(index, 1); |
| | | }; |
| | | |
| | | // è®¡ç®æ»ä»·ï¼æ ¹æ®æ°éãåä»·åå«ç¨åä»·ï¼ |
| | | const calculateTotalPrice = (row) => { |
| | | // è®¡ç®æ®éæ»ä»·ï¼inboundNum * unitPrice |
| | | const quantity = Number(row.inboundNum || 0); |
| | | const unitPrice = Number(row.unitPrice || 0); |
| | | row.totalPrice = quantity * unitPrice; |
| | | calculateExclusivePrice(row); |
| | | }; |
| | | |
| | | // 计ç®ä¸å«ç¨æ»ä»·ï¼æ ¹æ®å«ç¨æ»ä»·åç¨çï¼ |
| | | const calculateExclusivePrice = (row) => { |
| | | const totalPrice = Number(row.totalPrice || 0); |
| | | const taxRate = Number(row.taxRate || 0); |
| | | row.taxExclusiveTotalPrice = totalPrice / (1 + taxRate / 100); |
| | | }; |
| | | |
| | | const submitForm = async () => { |
| | | try { |
| | | await proxy.$refs.formRef.validate() |
| | | |
| | | if (!productList.value.length) { |
| | | proxy.$modal.msgError('请è³å°æ·»å 䏿¡äº§åæ°æ®') |
| | | return |
| | | } |
| | | |
| | | // éªè¯èªå®ä¹æ·»å çæ°æ®å¿
å¡«åæ®µ |
| | | for (let i = 0; i < productList.value.length; i++) { |
| | | const product = productList.value[i]; |
| | | if (!product.productCategory || !product.specificationModel || !product.unit) { |
| | | proxy.$modal.msgError(`第${i + 1}è¡äº§åæ°æ®æªå¡«å宿´ï¼äº§å大类ãè§æ ¼åå·ãåä½ä¸ºå¿
å¡«ï¼`) |
| | | return |
| | | } |
| | | if (!product.inboundDate) { |
| | | proxy.$modal.msgError(`第${i + 1}è¡è¯·éæ©å
¥åºæ¥æ`) |
| | | return |
| | | } |
| | | const stock = Number(product?.inboundNum ?? 0); |
| | | if (!Number.isFinite(stock) || stock <= 0) { |
| | | proxy.$modal.msgError(`第${i + 1}è¡æ¬æ¬¡å
¥åºæ°éé大äº0`) |
| | | return |
| | | } |
| | | } |
| | | |
| | | const payloadList = productList.value.map(product => ({ |
| | | id: product.id ?? null, |
| | | inboundNum: Number(product.inboundNum), |
| | | productCategory: product.productCategory, |
| | | specificationModel: product.specificationModel, |
| | | unit: product.unit, |
| | | supplierName: product.supplierName || form.value.supplierName, |
| | | itemType: product.itemType, |
| | | inboundDate: formatDateTime(product.inboundDate, false), |
| | | taxRate: Number(product.taxRate || 0), |
| | | taxExclusiveTotalPrice: Number(product.taxExclusiveTotalPrice || 0), |
| | | unitPrice: Number(product.unitPrice || 0), |
| | | })); |
| | | loading.value = true |
| | | if (operationType.value === 'edit') { |
| | | const editPayload = payloadList[0] |
| | | await updateProduct(editPayload) |
| | | } else { |
| | | await addStockInCustom(payloadList) |
| | | } |
| | | |
| | | proxy.$modal.msgSuccess(operationType.value === 'edit' ? 'ç¼è¾èªå®ä¹å
¥åºæå' : 'æ°å¢èªå®ä¹å
¥åºæå') |
| | | closeDia() |
| | | emit('success') |
| | | |
| | | } catch (error) { |
| | | console.error('æäº¤å¤±è´¥:', error) |
| | | if (!error.errors) { |
| | | proxy.$modal.msgError('æä½å¤±è´¥ï¼è¯·éè¯') |
| | | } |
| | | } finally { |
| | | loading.value = false |
| | | } |
| | | } |
| | | |
| | | const closeDia = () => { |
| | | proxy.$refs.formRef.resetFields() |
| | | dialogFormVisible.value = false |
| | | productList.value = [] |
| | | emit('close') |
| | | } |
| | | |
| | | const openDialog = async (type, row) => { |
| | | operationType.value = type |
| | | dialogFormVisible.value = true |
| | | |
| | | if (type === 'add') { |
| | | form.value = { |
| | | id: null, |
| | | supplierId: null, |
| | | supplierName: '', |
| | | recorderId: userStore.userId, |
| | | recorderName: userStore.name, |
| | | entryDate: getCurrentDate(), |
| | | remark: '' |
| | | } |
| | | productList.value = [] |
| | | } else { |
| | | // ç¼è¾æ¨¡å¼ï¼å°è¡æ°æ®å¡«å
å°è¡¨æ ¼ä¸ä»¥æ¯æä¿®æ¹ |
| | | form.value = { |
| | | id: row?.id ?? null, |
| | | supplierId: row?.supplierId ?? null, |
| | | supplierName: row?.supplierName ?? '', |
| | | recorderId: userStore.userId, |
| | | recorderName: userStore.name, |
| | | entryDate: getCurrentDate(), |
| | | remark: row?.remark ?? '' |
| | | } |
| | | productList.value = [{ |
| | | id: row?.id ?? null, |
| | | productCategory: row?.productCategory ?? '', |
| | | specificationModel: row?.specificationModel ?? '', |
| | | unit: row?.unit ?? '', |
| | | supplierName: row?.supplierName ?? '', |
| | | itemType: row?.itemType ?? '', |
| | | inboundNum: Number(row?.inboundNum ?? row?.inboundQuantity ?? 0), |
| | | inboundDate: row?.inboundDate ?? row?.createTime ?? '', |
| | | taxRate: Number(row?.taxRate ?? 0), |
| | | unitPrice: Number(row?.unitPrice ?? 0), |
| | | taxExclusiveTotalPrice: Number(row?.taxExclusiveTotalPrice ?? 0), |
| | | }] |
| | | } |
| | | } |
| | | |
| | | defineExpose({ |
| | | openDialog, |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"></style> |
| | | |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-tabs v-model="activeTab" @tab-change="handleTabChange"> |
| | | <el-tab-pane label="æåå
¥åº" name="production"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">ä¾åºååç§°ï¼</span> |
| | | <el-input v-model="searchForm.supplierName" style="width: 240px" placeholder="请è¾å
¥" @change="handleQuery" |
| | | clearable prefix-icon="Search" /> |
| | | <span class="search_title ml10">å
¥åºæ¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.timeStr" |
| | |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | <span class="search_title ml10">产å大类ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.productCategory" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">æç´¢</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add')">æ°å¢å
¥åº</el-button> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange" |
| | | :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%" |
| | | :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)"> |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column label="å
¥åºæ¶é´" prop="createTime" show-overflow-tooltip /> |
| | | <el-table-column label="éå®ååå·" prop="salesContractNo" width="180" show-overflow-tooltip /> |
| | | <el-table-column label="产å大类" prop="productCategory" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" show-overflow-tooltip /> |
| | | <el-table-column label="åä½" prop="unit" width="70" show-overflow-tooltip /> |
| | | <el-table-column label="å
¥åºæ°é" prop="inboundNum" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="åä»·(å
)" prop="unitPrice" width="150"></el-table-column> |
| | | <el-table-column label="æ»ä»·(å
)" prop="totalPrice" width="150"></el-table-column> |
| | | <el-table-column fixed="right" label="æä½" min-width="60" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="openForm('edit', scope.row, 'production');">ç¼è¾</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" :limit="page.size" @pagination="paginationChange" /> |
| | | </div> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="åæå
¥åº" name="purchase"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title ml10">å
¥åºæ¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.timeStr" |
| | | type="date" |
| | | placeholder="è¯·éæ©æ¥æ" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | <span class="search_title ml10">产å大类ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.productCategory" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">æç´¢</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add', 'purchase')">æ°å¢å
¥åº</el-button> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column label="å
¥åºæ¶é´" prop="createTime" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å
¥åºæ¹æ¬¡" prop="inboundBatches" width="160" show-overflow-tooltip /> |
| | | <el-table-column label="éè´ååå·" prop="purchaseContractNumber" width="180" show-overflow-tooltip /> |
| | | <el-table-column label="ä¾åºååç§°" prop="supplierName" width="240" show-overflow-tooltip /> |
| | | <el-table-column label="产å大类" prop="productCategory" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" width="200" show-overflow-tooltip /> |
| | | <el-table-column label="产å大类" prop="productCategory" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" show-overflow-tooltip /> |
| | | <el-table-column label="åä½" prop="unit" width="70" show-overflow-tooltip /> |
| | | <el-table-column label="å
¥åºæ°é" prop="inboundNum" width="90" show-overflow-tooltip /> |
| | | <el-table-column label="å«ç¨åä»·" prop="taxInclusiveUnitPrice" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å«ç¨æ»ä»·" prop="taxInclusiveTotalPrice" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="ç¨ç(%)" prop="taxRate" width="80" show-overflow-tooltip /> |
| | | <el-table-column label="ä¸å«ç¨æ»ä»·" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å
¥åºæ°é" prop="inboundNum" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å«ç¨åä»·(å
)" prop="taxInclusiveUnitPrice" width="150"></el-table-column> |
| | | <el-table-column label="å«ç¨æ»ä»·(å
)" prop="taxInclusiveTotalPrice" width="150"></el-table-column> |
| | | <el-table-column label="å
¥åºäºº" prop="createBy" width="80" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="æä½" min-width="60" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="openForm('edit', scope.row);" :disabled="scope.row.createUser !== userStore.id">ç¼è¾</el-button> |
| | | <el-button link type="primary" size="small" @click="openForm('edit', scope.row, 'purchase');">ç¼è¾</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" :limit="page.size" @pagination="paginationChange" /> |
| | | </div> |
| | | </el-tab-pane> |
| | | |
| | | <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? 'æ°å¢å
¥åº' : 'ç¼è¾å
¥åº'" width="70%" |
| | | @close="closeDia"> |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> |
| | | <el-form-item label="éè´è®¢åå·" prop="purchaseContractNumber"> |
| | | <el-select |
| | | v-model="form.purchaseContractNumber" |
| | | placeholder="è¯·éæ©éè´è®¢åå·" |
| | | <el-tab-pane label="ææå
¥åº" name="manual"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title ml10">å
¥åºæ¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.timeStr" |
| | | type="date" |
| | | placeholder="è¯·éæ©æ¥æ" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | filterable |
| | | remote |
| | | :remote-method="loadPurchaseOptions" |
| | | :loading="loadingPurchaseOptions" |
| | | @change="handlePurchaseChange" |
| | | :disabled="operationType === 'edit'" |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="item in purchaseOptions" |
| | | :key="item.purchaseContractNumber" |
| | | :label="formatPurchaseOption(item)" |
| | | :value="item.purchaseContractNumber" |
| | | @change="handleQuery" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-table |
| | | :data="productList" |
| | | border |
| | | v-loading="loadingProducts" |
| | | @selection-change="handleSelectionChange" |
| | | > |
| | | <span class="search_title ml10">产å大类ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.productCategory" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">æç´¢</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add', 'manual')">æ°å¢å
¥åº</el-button> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange" |
| | | :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%" |
| | | :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)"> |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column |
| | | align="center" |
| | | label="åºå·" |
| | | type="index" |
| | | width="60" |
| | | /> |
| | | <el-table-column label="产å大类" prop="productCategory" /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" /> |
| | | <el-table-column label="åä½" prop="unit" width="70" /> |
| | | <el-table-column label="ä¾åºå" prop="supplierName" width="100" /> |
| | | <el-table-column label="éè´æ°é" prop="quantity" width="100" /> |
| | | <el-table-column label="å¾
å
¥åºæ°é" prop="quantity0" width="100" /> |
| | | <el-table-column label="æ¬æ¬¡å
¥åºæ°é" prop="quantityStock" width="150"> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column label="å
¥åºæ¶é´" prop="inboundDate" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="æ¹æ¬¡å·" prop="code" width="130" show-overflow-tooltip /> |
| | | <el-table-column label="产å大类" prop="productCategory" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" show-overflow-tooltip /> |
| | | <el-table-column label="åä½" prop="unit" width="70" show-overflow-tooltip /> |
| | | <el-table-column label="ç©åç±»å" prop="itemType" show-overflow-tooltip /> |
| | | <el-table-column label="å
¥åºæ°é" prop="inboundNum" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å©ä½åºå" prop="inboundNum0" show-overflow-tooltip /> |
| | | <el-table-column label="åä»·(å
)" prop="taxInclusiveUnitPrice" width="150"></el-table-column> |
| | | <el-table-column label="æ»ä»·(å
)" prop="taxInclusiveTotalPrice" width="150"></el-table-column> |
| | | <el-table-column label="å
¥åºäºº" prop="createBy" width="80" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="æä½" width="100" align="center"> |
| | | <template #default="scope"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.quantityStock" /> |
| | | <el-button link type="primary" size="small" @click="openForm('edit', scope.row, 'manual');">ç¼è¾</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç¨ç(%)" prop="taxRate" width="120" /> |
| | | <el-table-column |
| | | label="å«ç¨åä»·(å
)" |
| | | prop="taxInclusiveUnitPrice" |
| | | :formatter="formattedNumber" |
| | | width="150" |
| | | /> |
| | | <el-table-column |
| | | label="å«ç¨æ»ä»·(å
)" |
| | | prop="taxInclusiveTotalPrice" |
| | | :formatter="formattedNumber" |
| | | width="150" |
| | | /> |
| | | <el-table-column |
| | | label="ä¸å«ç¨æ»ä»·(å
)" |
| | | prop="taxExclusiveTotalPrice" |
| | | :formatter="formattedNumber" |
| | | width="150" |
| | | /> |
| | | </el-table> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | | <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" :limit="page.size" @pagination="paginationChange" /> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | |
| | | <form-dia ref="formDia" @close="handleQuery" @success="handleQuery"></form-dia> |
| | | <form-dia-manual ref="formDiaManual" @close="handleQuery" @success="handleQuery"></form-dia-manual> |
| | | <form-dia-product ref="formDiaProduct" @close="handleQuery" @success="handleQuery"></form-dia-product> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import pagination from '@/components/PIMTable/Pagination.vue' |
| | | import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue' |
| | | import { ref, reactive, toRefs, onMounted, getCurrentInstance, nextTick } from 'vue' |
| | | import { ElMessageBox } from "element-plus"; |
| | | import useUserStore from '@/store/modules/user' |
| | | import dayjs from 'dayjs' |
| | | import { |
| | | getStockInPage, |
| | | updateStockIn, |
| | | addSutockIn, |
| | | getStockInPageByProduction, |
| | | delStockIn, |
| | | selectProductRecordListByPuechaserId |
| | | delStockInCustom, getInPageByCustom, |
| | | } from "@/api/inventoryManagement/stockIn.js"; |
| | | import { purchaseListPage } from "@/api/procurementManagement/procurementLedger.js"; |
| | | import FormDia from './components/formDia.vue' |
| | | import FormDiaManual from './components/formDiaManual.vue' |
| | | import FormDiaProduct from './components/formDiaProduct.vue' |
| | | |
| | | const userStore = useUserStore() |
| | | // è·åå½åæ¥æ |
| | | function getCurrentDate() { |
| | | return dayjs().format('YYYY-MM-DD') |
| | | } |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | | const tableData = ref([]) |
| | | const selectedRows = ref([]) |
| | | const userList = ref([]) |
| | | |
| | | const purchaseOptions = ref([]) |
| | | const loadingPurchaseOptions = ref(false) |
| | | |
| | | |
| | | const loading = ref(false); |
| | | const tableLoading = ref(false) |
| | | const formDia = ref() |
| | | const formDiaManual = ref() |
| | | const formDiaProduct = ref() |
| | | const activeTab = ref('production') // å½åæ¿æ´»ç tab |
| | | |
| | | const page = reactive({ |
| | | current: 1, |
| | |
| | | }) |
| | | const total = ref(0) |
| | | |
| | | // ç¨æ·ä¿¡æ¯è¡¨åå¼¹æ¡æ°æ® |
| | | const operationType = ref('')// æä½ç±»å: 'add' æ 'edit' |
| | | const dialogFormVisible = ref(false)// å¼¹æ¡æ¾ç¤ºç¶æ |
| | | const productList = ref([]);// 产ååè¡¨æ°æ® |
| | | const loadingProducts = ref(false);// 产åå è½½ç¶æ |
| | | const productSelectedRows = ref([]) // 产åè¡¨æ ¼éä¸è¡ |
| | | const data = reactive({ |
| | | searchForm: { |
| | | supplierName: '', |
| | | timeStr: '', |
| | | customerName: '', |
| | | productCategory:'', |
| | | timeStr: getCurrentDate(), |
| | | }, |
| | | form: { |
| | | id: null, |
| | | purchaseContractNumber: '', // éè´è®¢åå· |
| | | supplierId: null, // ä¾åºåID |
| | | supplierName: '', // ä¾åºååç§° |
| | | inboundTime: '', // å
¥åºæ¶é´ |
| | | inboundBatch: '', // å
¥åºæ¹æ¬¡ |
| | | recorderId: userStore.userId, // å½å
¥äººID |
| | | recorderName: userStore.name, // å½å
¥äººå§å |
| | | entryDate: getCurrentDate(), // å½å
¥æ¥æ |
| | | remark: '', // 夿³¨ |
| | | }, |
| | | rules: { |
| | | purchaseContractNumber: [{ required: true, message: "请è¾å
¥éè´ååå·", trigger: "blur" }], |
| | | supplierId: [{ required: true, message: "è¯·éæ©ä¾åºå", trigger: "change" }], |
| | | inboundTime: [{ required: true, message: "è¯·éæ©å
¥åºæ¶é´", trigger: "change" }], |
| | | inboundBatch: [{ required: true, message: "请è¾å
¥å
¥åºæ¹æ¬¡", trigger: "blur" }] |
| | | } |
| | | }) |
| | | const { searchForm, form, rules } = toRefs(data) |
| | | |
| | | const formatPurchaseOption = (item = {}) => { |
| | | const contract = item.purchaseContractNumber || '--'; |
| | | const supplier = item.supplierName ? ` · ${item.supplierName}` : ''; |
| | | return `${contract}${supplier}`; |
| | | }; |
| | | |
| | | const loadPurchaseOptions = async (keyword = '') => { |
| | | try { |
| | | loadingPurchaseOptions.value = true; |
| | | const res = await purchaseListPage({ |
| | | current: -1, |
| | | size: -1, |
| | | purchaseContractNumber: keyword, |
| | | }); |
| | | const records = res.data?.records || []; |
| | | purchaseOptions.value = records; |
| | | if ( |
| | | form.value.purchaseContractNumber && |
| | | !purchaseOptions.value.find( |
| | | (item) => item.purchaseContractNumber === form.value.purchaseContractNumber |
| | | ) |
| | | ) { |
| | | purchaseOptions.value.push({ |
| | | purchaseContractNumber: form.value.purchaseContractNumber, |
| | | supplierName: form.value.supplierName, |
| | | supplierId: form.value.supplierId, |
| | | }); |
| | | } |
| | | } finally { |
| | | loadingPurchaseOptions.value = false; |
| | | } |
| | | }; |
| | | |
| | | const handlePurchaseChange = (value) => { |
| | | form.value.purchaseContractNumber = value || ''; |
| | | const matched = purchaseOptions.value.find( |
| | | (item) => item.purchaseContractNumber === value |
| | | ); |
| | | if (matched) { |
| | | form.value.supplierName = matched.supplierName || form.value.supplierName; |
| | | form.value.supplierId = matched.supplierId || form.value.supplierId; |
| | | } |
| | | if (!value) { |
| | | productList.value = []; |
| | | return; |
| | | } |
| | | fetchProductsByContract(); |
| | | }; |
| | | const exceedsAddLimit = (product) => { |
| | | const stock = Number(product?.quantityStock ?? 0); |
| | | const waiting = Number(product?.quantity0 ?? 0); |
| | | if (!Number.isFinite(stock) || !Number.isFinite(waiting)) { |
| | | return false; |
| | | } |
| | | return stock > waiting; |
| | | }; |
| | | |
| | | const exceedsEditLimit = (product) => { |
| | | const stock = Number(product?.quantityStock ?? 0); |
| | | const waiting = Number(product?.quantity0 ?? 0); |
| | | const original = Number(product?.originalQuantityStock ?? 0); |
| | | if (!Number.isFinite(stock) || !Number.isFinite(waiting) || !Number.isFinite(original)) { |
| | | return false; |
| | | } |
| | | return stock > waiting + original; |
| | | }; |
| | | const formattedNumber = (row, column, cellValue) => { |
| | | return parseFloat(cellValue).toFixed(2); |
| | | }; |
| | | const { searchForm } = toRefs(data) |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | |
| | | } |
| | | const getList = () => { |
| | | tableLoading.value = true |
| | | getStockInPage({ ...searchForm.value, ...page }).then(res => { |
| | | const params = { ...page } |
| | | |
| | | // æ ¹æ®ä¸åç tab ç±»åä¼ éä¸åçæ¥è¯¢åæ° |
| | | if (activeTab.value === 'production') { |
| | | params.customerName = searchForm.value.customerName |
| | | params.timeStr = searchForm.value.timeStr |
| | | } else { |
| | | params.supplierName = searchForm.value.supplierName |
| | | params.timeStr = searchForm.value.timeStr |
| | | } |
| | | params.productCategory = searchForm.value.productCategory |
| | | |
| | | // æ ¹æ®ä¸åç tab ç±»åè°ç¨ä¸åçæ¥å£ |
| | | const apiCall = activeTab.value === 'production' |
| | | ? getStockInPageByProduction(params) |
| | | : activeTab.value === 'manual' |
| | | ? getInPageByCustom(params) |
| | | : getStockInPage(params) |
| | | |
| | | apiCall.then(res => { |
| | | tableLoading.value = false |
| | | tableData.value = res.data.records |
| | | |
| | | // åç«¯è®¡ç®æ»ä»·ï¼æ»ä»· = unitPrice * inboundNum |
| | | tableData.value = tableData.value.map(item => { |
| | | // 使ç¨å
¥åºæ°éè®¡ç®æ»ä»· |
| | | const inboundNum = Number(item.inboundNum) || 0 |
| | | const unitPrice = Number(item.unitPrice) || 0 |
| | | const taxInclusiveUnitPrice = Number(item.taxInclusiveUnitPrice) || 0 |
| | | |
| | | // æ ¹æ®æ ç¾é¡µç±»å计ç®ä¸åçæ»ä»· |
| | | if (activeTab.value === 'production') { |
| | | // æååºåï¼æ»ä»· = unitPrice * å
¥åºæ°é |
| | | item.totalPrice = (unitPrice * inboundNum).toFixed(2) |
| | | } else { |
| | | // åæåææåºåï¼å«ç¨æ»ä»· = taxInclusiveUnitPrice * å
¥åºæ°é |
| | | item.taxInclusiveTotalPrice = (taxInclusiveUnitPrice * inboundNum).toFixed(2) |
| | | } |
| | | |
| | | return item |
| | | }) |
| | | |
| | | total.value = res.data.total |
| | | console.log('tableData:', tableData.value) |
| | | }).catch(() => { |
| | | tableLoading.value = false |
| | | }) |
| | | } |
| | | |
| | | |
| | | // è°ç¨selectProductRecordListByPuechaserIdè¿ä¸ªæ¹æ³æ ¹æ®ååæ¥è¯¢å°idï¼åè°ç¨getProductRecordByhetongè¿ä¸ªæ¹æ³æ ¹æ®idæ¥è¯¢å°äº§å订åè®°å½ |
| | | // æ°å¢æ ¹æ®ååå·æ¥è¯¢äº§åè®°å½çæ¹æ³ |
| | | const fetchProductsByContract = async () => |
| | | { |
| | | if (!form.value.purchaseContractNumber) { |
| | | proxy.$modal.msgWarning('è¯·éæ©ååå·') |
| | | return |
| | | // 忢 tab |
| | | const handleTabChange = (tabName) => { |
| | | page.current = 1 |
| | | // 忢 tab æ¶æ¸
空æç´¢æ¡ä»¶ |
| | | searchForm.value.supplierName = '' |
| | | searchForm.value.customerName = '' |
| | | searchForm.value.timeStr = '' |
| | | searchForm.value.productCategory = '' |
| | | getList() |
| | | } |
| | | try { |
| | | loadingProducts.value = true |
| | | // æ ¹æ®ååæ¥è¯¢äº§åè®°å½ |
| | | const productRes = await selectProductRecordListByPuechaserId({ |
| | | purchaseContractNumber: form.value.purchaseContractNumber |
| | | }); |
| | | console.log('productRes:', productRes) |
| | | if (!productRes.data || productRes.data.length === 0) { |
| | | proxy.$modal.msgWarning('该åå䏿²¡æäº§åè®°å½') |
| | | productList.value = []; |
| | | return |
| | | } |
| | | // å¤çäº§åæ°æ®ï¼æ·»å æ¬æ¬¡å
¥åºæ°éåæ®µ |
| | | productList.value = productRes.data.map(item => ({ |
| | | ...item, |
| | | quantityStock: 0, |
| | | originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? 0), |
| | | })) |
| | | } catch (error) { |
| | | console.error('æ¥è¯¢äº§åè®°å½å¤±è´¥:', error) |
| | | proxy.$modal.msgError('æ¥è¯¢äº§åè®°å½å¤±è´¥') |
| | | productList.value = []; |
| | | } finally { |
| | | loadingProducts.value = false |
| | | } |
| | | } |
| | | |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openForm = async (type, row) => { |
| | | operationType.value = type |
| | | dialogFormVisible.value = true |
| | | selectedRows.value = [] |
| | | await loadPurchaseOptions(); |
| | | |
| | | if (type === 'add') { |
| | | // æ°å¢æ¶åå§å表å |
| | | form.value = { |
| | | id: null, |
| | | purchaseContractNumber: '', |
| | | supplierId: null, |
| | | supplierName: '', |
| | | inboundTime: '', |
| | | inboundBatch: '', |
| | | recorderId: userStore.userId, |
| | | recorderName: userStore.name, |
| | | entryDate: getCurrentDate(), |
| | | remark: '' |
| | | } |
| | | productList.value = [] // æ¸
空产åå表 |
| | | const openForm = async (type, row, tabType) => { |
| | | const currentTab = tabType || activeTab.value |
| | | await nextTick(() => { |
| | | if (currentTab === 'manual') { |
| | | formDiaManual.value?.openDialog(type, row) |
| | | } else if (currentTab === 'production') { |
| | | formDiaProduct.value?.openDialog(type, row) |
| | | } else { |
| | | form.value = JSON.parse(JSON.stringify(row)) |
| | | try { |
| | | loadingProducts.value = true |
| | | // æ ¹æ®ååå·å 载对åºç产åå表ï¼å设 getProductByContract æ¯å¯ç¨æ¥å£ï¼ |
| | | const res = await selectProductRecordListByPuechaserId({ |
| | | purchaseContractNumber: form.value.purchaseContractNumber, |
| | | id: row.id |
| | | }); |
| | | productList.value = res.data.map(item => ({ |
| | | ...item, |
| | | quantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0), |
| | | originalQuantityStock: Number(item.quantityStock ?? item.inboundQuantity ?? row.inboundNum ?? 0), |
| | | })) |
| | | selectedRows.value = productList.value |
| | | } catch (error) { |
| | | console.error('å 载产å失败:', error) |
| | | proxy.$modal.msgError('å 载产å失败') |
| | | productList.value = [] |
| | | } finally { |
| | | loadingProducts.value = false |
| | | formDia.value?.openDialog(type, row) |
| | | } |
| | | } |
| | | } |
| | | |
| | | const updatePro = async () => { |
| | | // åå¤æäº¤æ°æ® |
| | | // åå¤æäº¤æ°æ® - ä¿®æ¹ä¸ºå端éè¦çæ ¼å¼ |
| | | if (selectedRows.value.length === 0) { |
| | | proxy.$modal.msgWarning('请å
éæ©äº§å'); |
| | | return; |
| | | } |
| | | const target = selectedRows.value[0]; |
| | | const stock = Number(target?.quantityStock ?? 0); |
| | | if (!Number.isFinite(stock) || stock <= 0) { |
| | | proxy.$modal.msgWarning('è¯·å¡«åææçå
¥åºæ°é'); |
| | | return; |
| | | } |
| | | if (exceedsEditLimit(target)) { |
| | | proxy.$modal.msgError('æ¬æ¬¡å
¥åºæ°éä¸è½è¶
è¿åå
¥åºæ°éä¸å¾
å
¥åºæ°éä¹å'); |
| | | return; |
| | | } |
| | | const stockInData = { |
| | | id: selectedRows.value[0].recordId, |
| | | quantityStock: Number(selectedRows.value[0].quantityStock),// ä½¿ç¨æ°æ ¼å¼å彿° |
| | | }; |
| | | await updateStockIn(stockInData) |
| | | proxy.$modal.msgSuccess('ä¿®æ¹å
¥åºæå') |
| | | closeDia() |
| | | getList() // å·æ°å表 |
| | | } |
| | | |
| | | // æäº¤è¡¨å |
| | | const submitForm = async () => { |
| | | // éªè¯è³å°éæ©äºä¸ä¸ªäº§å |
| | | if (selectedRows.value.length === 0) { |
| | | proxy.$modal.msgWarning('请å
éæ©éè´ååå¹¶éæ©äº§å') |
| | | return |
| | | } |
| | | if(operationType.value !== 'add'){ |
| | | await updatePro() |
| | | return |
| | | } |
| | | try { |
| | | await proxy.$refs.formRef.validate() |
| | | // éªè¯å
¥åºæ°é |
| | | const invalidProducts = selectedRows.value.filter((product) => { |
| | | const stock = Number(product?.quantityStock ?? 0); |
| | | if (!Number.isFinite(stock) || stock <= 0) { |
| | | return true; |
| | | } |
| | | return exceedsAddLimit(product); |
| | | }) |
| | | |
| | | if (invalidProducts.length > 0) { |
| | | proxy.$modal.msgError('æ¬æ¬¡å
¥åºæ°éé大äº0ï¼ä¸ä¸è½è¶
è¿å¾
å
¥åºæ°é') |
| | | return |
| | | } |
| | | |
| | | // åå¤æäº¤æ°æ® - ä¿®æ¹ä¸ºå端éè¦çæ ¼å¼ |
| | | const stockInData = { |
| | | // å
¥åºååºæ¬ä¿¡æ¯ |
| | | ...form.value, |
| | | inboundTime: formatDateTime(form.value.inboundTime), |
| | | nickName: userStore.nickName, |
| | | details: selectedRows.value.map(product => ({ |
| | | id: product.id, |
| | | // id: product.salesLedgerProductId, |
| | | inboundQuantity: Number(product.quantityStock) |
| | | })), |
| | | }; |
| | | // è°ç¨API |
| | | loading.value = true |
| | | await addSutockIn(stockInData) |
| | | |
| | | proxy.$modal.msgSuccess('æ°å¢å
¥åºæå') |
| | | closeDia() |
| | | getList() // å·æ°å表 |
| | | |
| | | } catch (error) { |
| | | console.error('æäº¤å¤±è´¥:', error) |
| | | if (!error.errors) { |
| | | proxy.$modal.msgError('æä½å¤±è´¥ï¼è¯·éè¯') |
| | | } |
| | | } finally { |
| | | loading.value = false |
| | | } |
| | | } |
| | | |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | proxy.$refs.formRef.resetFields() |
| | | dialogFormVisible.value = false |
| | | |
| | | } |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | // è¿æ»¤æåæ°æ® |
| | | selectedRows.value = selection.filter(item => item.id); |
| | | selectedRows.value = selection.filter(item => item.id) |
| | | } |
| | | |
| | | const expandedRowKeys = ref([]) |
| | | |
| | | // 主表åè®¡æ¹æ³ |
| | | const summarizeMainTable = (param) => { |
| | | return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']); |
| | | }; |
| | | return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']) |
| | | } |
| | | |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm( |
| | | 'æ¯å¦ç¡®è®¤å¯¼åºï¼', |
| | | '导åº', { |
| | | ElMessageBox.confirm('æ¯å¦ç¡®è®¤å¯¼åºï¼', '导åº', { |
| | | confirmButtonText: '确认', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning', |
| | | }).then(() => { |
| | | // æ ¹æ®ä¸åç tab ç±»åè°ç¨ä¸åçå¯¼åºæ¥å£ |
| | | let exportUrl = "/stockin/export" |
| | | if (activeTab.value === 'production') { |
| | | exportUrl = "/stockin/exportOne" |
| | | } else if (activeTab.value === 'manual') { |
| | | exportUrl = "/stockin/exportTwo" |
| | | } |
| | | ).then(() => { |
| | | proxy.download("/stockin/export", {}, 'å
¥åºå°è´¦.xlsx') |
| | | proxy.download(exportUrl, {}, 'å
¥åºå°è´¦.xlsx') |
| | | }).catch(() => { |
| | | proxy.$modal.msg("已忶") |
| | | }) |
| | | } |
| | | |
| | | // å é¤ |
| | | const handleDelete = () => { |
| | | let ids = [] |
| | | if (selectedRows.value.length > 0) { |
| | | // æ£æ¥æ¯å¦æä»äººç»´æ¤çæ°æ® |
| | | const unauthorizedData = selectedRows.value.filter(item => item.createUser !== userStore.id); |
| | | if (unauthorizedData.length > 0) { |
| | | proxy.$modal.msgWarning("ä¸å¯å é¤ä»äººç»´æ¤çæ°æ®"); |
| | | return; |
| | | } |
| | | ids = selectedRows.value.map(item => item.id); |
| | | } else { |
| | | if (selectedRows.value.length === 0) { |
| | | proxy.$modal.msgWarning('è¯·éæ©æ°æ®') |
| | | return |
| | | } |
| | | ElMessageBox.confirm( |
| | | 'éä¸çå
容å°è¢«å é¤ï¼æ¯å¦ç¡®è®¤å é¤ï¼', |
| | | '导åº', { |
| | | const ids = selectedRows.value.map(item => item.id) |
| | | |
| | | ElMessageBox.confirm('éä¸çå
容å°è¢«å é¤ï¼æ¯å¦ç¡®è®¤å é¤ï¼', 'å é¤', { |
| | | confirmButtonText: '确认', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning', |
| | | }).then(() => { |
| | | // æ ¹æ®å½å tab ç±»åéæ©ä¸åçå 餿¥å£åtypeåæ° |
| | | let deleteApi, deleteParams |
| | | |
| | | if (activeTab.value === 'production') { |
| | | // æåå é¤ï¼typeä¼ 2 |
| | | deleteApi = delStockIn |
| | | deleteParams = { ids, type: 2 } |
| | | } else if (activeTab.value === 'purchase') { |
| | | // åæå é¤ï¼typeä¼ 1 |
| | | deleteApi = delStockIn |
| | | deleteParams = { ids, type: 1 } |
| | | } else { |
| | | // ææå
¥åº |
| | | deleteApi = delStockInCustom |
| | | deleteParams = { ids } |
| | | } |
| | | ).then(() => { |
| | | delStockIn({ids:ids}).then(res => { |
| | | |
| | | deleteApi(deleteParams).then(() => { |
| | | proxy.$modal.msgSuccess("å 餿å") |
| | | getList() |
| | | }).catch(() => { |
| | | proxy.$modal.msgError("å é¤å¤±è´¥") |
| | | }) |
| | | }).catch(() => { |
| | | proxy.$modal.msg("已忶") |
| | | }) |
| | | } |
| | | |
| | | // è·åå½åæ¥æå¹¶æ ¼å¼å为 YYYY-MM-DD |
| | | // ä¿®æ¹ä¸ºæ´éç¨çæ¥ææ¶é´æ ¼å¼å彿° |
| | | function formatDateTime(date = new Date(), includeTime = true) { |
| | | const d = new Date(date); |
| | | const year = d.getFullYear(); |
| | | const month = String(d.getMonth() + 1).padStart(2, '0'); |
| | | const day = String(d.getDate()).padStart(2, '0'); |
| | | |
| | | if (!includeTime) { |
| | | return `${year}-${month}-${day}`; // ä¿æåæ getCurrentDate åè½ |
| | | } |
| | | |
| | | // æ°å¢æ¶é´é¨åæ ¼å¼å |
| | | const hours = String(d.getHours()).padStart(2, '0'); |
| | | const minutes = String(d.getMinutes()).padStart(2, '0'); |
| | | const seconds = String(d.getSeconds()).padStart(2, '0'); |
| | | |
| | | return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; |
| | | } |
| | | |
| | | // ä¿æåæ getCurrentDate çå
¼å®¹æ§ |
| | | function getCurrentDate() { |
| | | return formatDateTime(new Date(), false); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | onMounted(() => { |
| | | getList() |
| | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"></style> |
| | | |
| | | |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog :model-value="dialogFormVisible" :title="operationType === 'add' ? 'æ°å¢ææåºå' : 'ç¼è¾ææåºå'" width="70%" |
| | | @update:model-value="$emit('update:dialogFormVisible', $event)" @close="closeDia"> |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="产å大类ï¼" prop="productCategory"> |
| | | <el-input disabled v-model="form.productCategory" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è§æ ¼åå·ï¼" prop="specificationModel"> |
| | | <el-input disabled v-model="form.specificationModel" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åä½ï¼" prop="unit"> |
| | | <el-input disabled v-model="form.unit" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç©åç±»åï¼" prop="itemType"> |
| | | <el-input disabled v-model="form.itemType" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¥åºæ¶é´ï¼" prop="createTime"> |
| | | <el-date-picker style="width: 100%" v-model="form.createTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD" |
| | | type="date" placeholder="è¯·éæ©" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåæ°éï¼" prop="inboundNum"> |
| | | <el-input v-model="form.inboundNum" placeholder="请è¾å
¥" clearable @input="calculateTotalPrice" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å·²åºåºæ°éï¼" prop="totalInboundNum"> |
| | | <el-input disabled v-model="form.totalInboundNum" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¾
åºåºæ°éï¼" prop="inboundNum0"> |
| | | <el-input disabled v-model="form.inboundNum0" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åä»·(å
)ï¼" prop="taxInclusiveUnitPrice"> |
| | | <el-input v-model="form.taxInclusiveUnitPrice" placeholder="请è¾å
¥" clearable @input="calculateTotalPrice" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ»ä»·(å
)ï¼" prop="taxInclusiveTotalPrice"> |
| | | <el-input disabled v-model="form.taxInclusiveTotalPrice" placeholder="èªå¨è®¡ç®" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, toRefs, watch } from 'vue' |
| | | |
| | | const props = defineProps({ |
| | | dialogFormVisible: Boolean, |
| | | operationType: String, |
| | | formData: Object |
| | | }) |
| | | |
| | | const emit = defineEmits(['update:dialogFormVisible', 'submit', 'close']) |
| | | |
| | | const formRef = ref() |
| | | |
| | | const data = reactive({ |
| | | form: { |
| | | productCategory: '', |
| | | specificationModel: '', |
| | | unit: '', |
| | | itemType: '', |
| | | createTime: '', |
| | | inboundNum: '', |
| | | totalInboundNum: '', |
| | | inboundNum0: '', |
| | | taxInclusiveUnitPrice: '', |
| | | taxInclusiveTotalPrice: '' |
| | | }, |
| | | rules: { |
| | | productCategory: [{ required: true, message: '请è¾å
¥äº§å大类', trigger: 'blur' }], |
| | | specificationModel: [{ required: true, message: '请è¾å
¥è§æ ¼åå·', trigger: 'blur' }], |
| | | unit: [{ required: true, message: '请è¾å
¥åä½', trigger: 'blur' }], |
| | | itemType: [{ required: true, message: '请è¾å
¥ç©åç±»å', trigger: 'blur' }], |
| | | createTime: [{ required: true, message: 'è¯·éæ©å
¥åºæ¶é´', trigger: 'change' }], |
| | | inboundNum: [{ required: true, message: '请è¾å
¥åºåæ°é', trigger: 'blur' }], |
| | | taxInclusiveUnitPrice: [{ required: true, message: '请è¾å
¥åä»·', trigger: 'blur' }] |
| | | } |
| | | }) |
| | | |
| | | const { form, rules } = toRefs(data) |
| | | |
| | | // è®¡ç®æ»ä»·ï¼æ»ä»· = åä»· à å©ä½åºå |
| | | const calculateTotalPrice = () => { |
| | | const unitPrice = parseFloat(form.value.taxInclusiveUnitPrice) || 0 |
| | | const stockQuantity = parseFloat(form.value.inboundNum) || 0 // åºåæ°é |
| | | const outboundQuantity = parseFloat(form.value.totalInboundNum) || 0 // å·²åºåºæ°é |
| | | const remainingStock = stockQuantity - outboundQuantity // å©ä½åºå |
| | | form.value.taxInclusiveTotalPrice = (unitPrice * remainingStock).toFixed(2) |
| | | } |
| | | |
| | | // çå¬formDataåå |
| | | watch(() => props.formData, (newVal) => { |
| | | if (newVal) { |
| | | form.value = { ...newVal } |
| | | // æ°æ®åååéæ°è®¡ç®æ»ä»· |
| | | calculateTotalPrice() |
| | | } |
| | | }, { immediate: true }) |
| | | |
| | | // æäº¤è¡¨å |
| | | const submitForm = () => { |
| | | formRef.value.validate(valid => { |
| | | if (valid) { |
| | | emit('submit', form.value) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | emit('close') |
| | | emit('update:dialogFormVisible', false) |
| | | } |
| | | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .dialog-footer { |
| | | text-align: center; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog :model-value="dialogFormVisible" :title="operationType === 'add' ? 'æ°å¢æååºå' : 'ç¼è¾æååºå'" width="70%" |
| | | @update:model-value="$emit('update:dialogFormVisible', $event)" @close="closeDia"> |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="产å大类ï¼" prop="productCategory"> |
| | | <el-input disabled v-model="form.productCategory" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è§æ ¼åå·ï¼" prop="specificationModel"> |
| | | <el-input disabled v-model="form.specificationModel" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åä½ï¼" prop="unit"> |
| | | <el-input disabled v-model="form.unit" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¥åºæ¶é´ï¼" prop="createTime"> |
| | | <el-date-picker style="width: 100%" v-model="form.createTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD" |
| | | type="date" placeholder="è¯·éæ©" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåæ°éï¼" prop="inboundNum"> |
| | | <el-input v-model="form.inboundNum" placeholder="请è¾å
¥" clearable @input="calculateTotalPrice" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å·²åºåºæ°éï¼" prop="totalInboundNum"> |
| | | <el-input disabled v-model="form.totalInboundNum" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¾
åºåºæ°éï¼" prop="inboundNum0"> |
| | | <el-input disabled v-model="form.inboundNum0" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åä»·(å
)ï¼" prop="unitPrice"> |
| | | <el-input v-model="form.unitPrice" placeholder="请è¾å
¥" clearable @input="calculateTotalPrice" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ»ä»·(å
)ï¼" prop="totalPrice"> |
| | | <el-input disabled v-model="form.totalPrice" placeholder="èªå¨è®¡ç®" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, toRefs, watch } from 'vue' |
| | | |
| | | const props = defineProps({ |
| | | dialogFormVisible: Boolean, |
| | | operationType: String, |
| | | formData: Object |
| | | }) |
| | | |
| | | const emit = defineEmits(['update:dialogFormVisible', 'submit', 'close']) |
| | | |
| | | const formRef = ref() |
| | | |
| | | const data = reactive({ |
| | | form: { |
| | | productCategory: '', |
| | | specificationModel: '', |
| | | unit: '', |
| | | createTime: '', |
| | | inboundNum: '', |
| | | totalInboundNum: '', |
| | | inboundNum0: '', |
| | | unitPrice: '', |
| | | totalPrice: '' |
| | | }, |
| | | rules: { |
| | | productCategory: [{ required: true, message: '请è¾å
¥äº§å大类', trigger: 'blur' }], |
| | | specificationModel: [{ required: true, message: '请è¾å
¥è§æ ¼åå·', trigger: 'blur' }], |
| | | unit: [{ required: true, message: '请è¾å
¥åä½', trigger: 'blur' }], |
| | | createTime: [{ required: true, message: 'è¯·éæ©å
¥åºæ¶é´', trigger: 'change' }], |
| | | inboundNum: [{ required: true, message: '请è¾å
¥åºåæ°é', trigger: 'blur' }], |
| | | unitPrice: [{ required: true, message: '请è¾å
¥åä»·', trigger: 'blur' }] |
| | | } |
| | | }) |
| | | |
| | | const { form, rules } = toRefs(data) |
| | | |
| | | // è®¡ç®æ»ä»·ï¼æ»ä»· = åä»· à å©ä½åºå |
| | | const calculateTotalPrice = () => { |
| | | const unitPrice = parseFloat(form.value.unitPrice) || 0 |
| | | const stockQuantity = parseFloat(form.value.inboundNum) || 0 // åºåæ°é |
| | | const outboundQuantity = parseFloat(form.value.totalInboundNum) || 0 // å·²åºåºæ°é |
| | | const remainingStock = stockQuantity - outboundQuantity // å©ä½åºå |
| | | form.value.totalPrice = (unitPrice * remainingStock).toFixed(2) |
| | | } |
| | | |
| | | // çå¬formDataåå |
| | | watch(() => props.formData, (newVal) => { |
| | | if (newVal) { |
| | | form.value = { ...newVal } |
| | | // æ°æ®åååéæ°è®¡ç®æ»ä»· |
| | | calculateTotalPrice() |
| | | } |
| | | }, { immediate: true }) |
| | | |
| | | // æäº¤è¡¨å |
| | | const submitForm = () => { |
| | | formRef.value.validate(valid => { |
| | | if (valid) { |
| | | emit('submit', form.value) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | emit('close') |
| | | emit('update:dialogFormVisible', false) |
| | | } |
| | | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .dialog-footer { |
| | | text-align: center; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog :model-value="dialogFormVisible" :title="operationType === 'add' ? 'æ°å¢åæåºå' : 'ç¼è¾åæåºå'" width="70%" |
| | | @update:model-value="$emit('update:dialogFormVisible', $event)" @close="closeDia"> |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="产å大类ï¼" prop="productCategory"> |
| | | <el-input disabled v-model="form.productCategory" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è§æ ¼åå·ï¼" prop="specificationModel"> |
| | | <el-input disabled v-model="form.specificationModel" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åä½ï¼" prop="unit"> |
| | | <el-input disabled v-model="form.unit" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¥åºæ¶é´ï¼" prop="createTime"> |
| | | <el-date-picker style="width: 100%" v-model="form.createTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD" |
| | | type="date" placeholder="è¯·éæ©" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåæ°éï¼" prop="inboundNum"> |
| | | <el-input v-model="form.inboundNum" placeholder="请è¾å
¥" clearable @input="calculateTotalPrice" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å·²åºåºæ°éï¼" prop="totalInboundNum"> |
| | | <el-input disabled v-model="form.totalInboundNum" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¾
åºåºæ°éï¼" prop="inboundNum0"> |
| | | <el-input disabled v-model="form.inboundNum0" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å«ç¨åä»·(å
)ï¼" prop="taxInclusiveUnitPrice"> |
| | | <el-input v-model="form.taxInclusiveUnitPrice" placeholder="请è¾å
¥" clearable @input="calculateTotalPrice" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å«ç¨æ»ä»·(å
)ï¼" prop="taxInclusiveTotalPrice"> |
| | | <el-input disabled v-model="form.taxInclusiveTotalPrice" placeholder="èªå¨è®¡ç®" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, toRefs, watch } from 'vue' |
| | | |
| | | const props = defineProps({ |
| | | dialogFormVisible: Boolean, |
| | | operationType: String, |
| | | formData: Object |
| | | }) |
| | | |
| | | const emit = defineEmits(['update:dialogFormVisible', 'submit', 'close']) |
| | | |
| | | const formRef = ref() |
| | | |
| | | const data = reactive({ |
| | | form: { |
| | | productCategory: '', |
| | | specificationModel: '', |
| | | unit: '', |
| | | createTime: '', |
| | | inboundNum: '', |
| | | totalInboundNum: '', |
| | | inboundNum0: '', |
| | | taxInclusiveUnitPrice: '', |
| | | taxInclusiveTotalPrice: '' |
| | | }, |
| | | rules: { |
| | | productCategory: [{ required: true, message: '请è¾å
¥äº§å大类', trigger: 'blur' }], |
| | | specificationModel: [{ required: true, message: '请è¾å
¥è§æ ¼åå·', trigger: 'blur' }], |
| | | unit: [{ required: true, message: '请è¾å
¥åä½', trigger: 'blur' }], |
| | | createTime: [{ required: true, message: 'è¯·éæ©å
¥åºæ¶é´', trigger: 'change' }], |
| | | inboundNum: [{ required: true, message: '请è¾å
¥åºåæ°é', trigger: 'blur' }], |
| | | taxInclusiveUnitPrice: [{ required: true, message: '请è¾å
¥å«ç¨åä»·', trigger: 'blur' }] |
| | | } |
| | | }) |
| | | |
| | | const { form, rules } = toRefs(data) |
| | | |
| | | // è®¡ç®æ»ä»·ï¼å«ç¨æ»ä»· = å«ç¨åä»· à å©ä½åºå |
| | | const calculateTotalPrice = () => { |
| | | const unitPrice = parseFloat(form.value.taxInclusiveUnitPrice) || 0 |
| | | const stockQuantity = parseFloat(form.value.inboundNum) || 0 // åºåæ°é |
| | | const outboundQuantity = parseFloat(form.value.totalInboundNum) || 0 // å·²åºåºæ°é |
| | | const remainingStock = stockQuantity - outboundQuantity // å©ä½åºå |
| | | form.value.taxInclusiveTotalPrice = (unitPrice * remainingStock).toFixed(2) |
| | | } |
| | | |
| | | // çå¬formDataåå |
| | | watch(() => props.formData, (newVal) => { |
| | | if (newVal) { |
| | | form.value = { ...newVal } |
| | | // æ°æ®åååéæ°è®¡ç®æ»ä»· |
| | | calculateTotalPrice() |
| | | } |
| | | }, { immediate: true }) |
| | | |
| | | // æäº¤è¡¨å |
| | | const submitForm = () => { |
| | | formRef.value.validate(valid => { |
| | | if (valid) { |
| | | emit('submit', form.value) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | emit('close') |
| | | emit('update:dialogFormVisible', false) |
| | | } |
| | | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .dialog-footer { |
| | | text-align: center; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-tabs v-model="activeTab" @tab-change="handleTabChange"> |
| | | <el-tab-pane label="æååºå" name="production"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">ä¾åºååç§°ï¼</span> |
| | | <el-input v-model="searchForm.supplierName" style="width: 240px" placeholder="请è¾å
¥" @change="handleQuery" |
| | | clearable prefix-icon="Search" /> |
| | | <span class="search_title ml10">å
¥åºæ¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.timeStr" |
| | |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | <span class="search_title ml10">产å大类ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.productCategory" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">æç´¢</el-button> |
| | | </div> |
| | | <div> |
| | | <!-- <el-button type="primary" @click="openForm('add')">æ°å¢</el-button> --> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | <!-- <el-button type="danger" plain @click="handleDelete">å é¤</el-button>--> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column label="å
¥åºæ¥æ" prop="createTime" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="ä¾åºååç§°" prop="supplierName" width="240" show-overflow-tooltip /> |
| | | <el-table-column label="产å大类" prop="productCategory" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" width="200" show-overflow-tooltip /> |
| | | <el-table-column label="éå®ååå·" prop="salesContractNo" width="180" show-overflow-tooltip /> |
| | | <el-table-column label="产å大类" prop="productCategory" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" show-overflow-tooltip /> |
| | | <el-table-column label="åä½" prop="unit" width="80" show-overflow-tooltip /> |
| | | <el-table-column label="åºåæ°é" prop="inboundNum0" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="åºåé¢è¦æ°é" prop="warnNum" width="130" show-overflow-tooltip /> |
| | | <el-table-column label="å«ç¨åä»·" prop="taxInclusiveUnitPrice" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å«ç¨æ»ä»·" prop="taxInclusiveTotalPrice" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="ç¨ç(%)" prop="taxRate" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="ä¸å«ç¨æ»ä»·" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å
¥åºäºº" prop="createBy" width="80" show-overflow-tooltip /> |
| | | <el-table-column label="å·²åºåºæ°é" prop="totalInboundNum" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å©ä½åºå" prop="inboundNum0" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="åä»·(å
)" prop="unitPrice" width="150"></el-table-column> |
| | | <el-table-column label="æ»ä»·(å
)" prop="totalPrice" width="150"></el-table-column> |
| | | <el-table-column fixed="right" label="æä½" min-width="60" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="openForm('edit', scope.row);" :disabled="scope.row.createUser !== userStore.id">ç¼è¾</el-button> |
| | | <el-button link type="primary" size="small" @click="openForm('edit', scope.row);">ç¼è¾</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" :limit="page.size" @pagination="paginationChange" /> |
| | | </div> |
| | | <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? 'æ°å¢åºå' : 'ç¼è¾åºå'" width="70%" |
| | | @close="closeDia"> |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¾åºååç§°ï¼" prop="supplierName"> |
| | | <el-input disabled v-model="form.supplierName" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="产å大类ï¼" prop="productId"> |
| | | <el-select disabled v-model="form.productCategory" placeholder="è¯·éæ©" clearable filterable> |
| | | <el-option v-for="item in productList" :key="item.id" :label="item.productName" |
| | | :value="item.productName" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è§æ ¼åå·ï¼" prop="productManageId"> |
| | | <el-select disabled v-model="form.specificationModel" placeholder="请å
éæ©äº§å大类" clearable filterable :disabled="!form.productCategory"> |
| | | <el-option v-for="item in productModelList" :key="item.id" :label="item.model" |
| | | :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åä½ï¼" prop="customerId"> |
| | | <el-input disabled v-model="form.unit" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåæ¶é´ï¼" prop="projectName"> |
| | | <el-date-picker style="width: 100%" v-model="form.updateTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD" |
| | | type="date" placeholder="è¯·éæ©" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¥åºæ¶é´ï¼" prop="projectName"> |
| | | <el-date-picker style="width: 100%" v-model="form.createTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD" |
| | | type="date" placeholder="è¯·éæ©" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | </el-tab-pane> |
| | | |
| | | <el-col :span="12"> |
| | | <el-form-item label="å«ç¨åä»·ï¼" prop="customerId"> |
| | | <el-input disabled v-model="form.taxInclusiveUnitPrice" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å«ç¨æ»ä»·ï¼" prop="customerContractNo"> |
| | | <el-input disabled v-model="form.taxInclusiveTotalPrice" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç¨çï¼" prop="customerId"> |
| | | <el-input disabled v-model="form.taxRate" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¸å«ç¨æ»ä»·ï¼" prop="entryDate"> |
| | | <el-input disabled v-model="form.taxExclusiveTotalPrice" placeholder="请è¾å
¥" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåºäººï¼" prop="entryPerson"> |
| | | <el-select v-model="form.createUser" placeholder="è¯·éæ©" clearable> |
| | | <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <!-- <el-col :span="12">--> |
| | | <!-- <el-form-item label="åºåé¢è¦æ°éï¼" prop="warnNum">--> |
| | | <!-- <el-input v-model="form.warnNum" placeholder="请è¾å
¥æä½åºå" clearable />--> |
| | | <!-- </el-form-item>--> |
| | | <!-- </el-col>--> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认</el-button> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | | <el-tab-pane label="åæåºå" name="purchase"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title ml10">å
¥åºæ¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.timeStr" |
| | | type="date" |
| | | placeholder="è¯·éæ©æ¥æ" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | <span class="search_title ml10">产å大类ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.productCategory" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">æç´¢</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <!-- <el-button type="danger" plain @click="handleDelete">å é¤</el-button>--> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange" |
| | | :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%" |
| | | :row-class-name="tableRowClassName" |
| | | :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)"> |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column label="å
¥åºæ¥æ" prop="createTime" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="éè´ååå·" prop="purchaseContractNumber" width="180" show-overflow-tooltip /> |
| | | <el-table-column label="产å大类" prop="productCategory" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" show-overflow-tooltip /> |
| | | <el-table-column label="åä½" prop="unit" width="80" show-overflow-tooltip /> |
| | | <el-table-column label="å·²åºåºæ°é" prop="totalInboundNum" show-overflow-tooltip /> |
| | | <el-table-column label="å©ä½åºå" prop="inboundNum0" show-overflow-tooltip /> |
| | | <el-table-column label="å«ç¨åä»·(å
)" prop="taxInclusiveUnitPrice" width="150"></el-table-column> |
| | | <el-table-column label="å«ç¨æ»ä»·(å
)" prop="taxInclusiveTotalPrice" width="150"></el-table-column> |
| | | </el-table> |
| | | <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" :limit="page.size" @pagination="paginationChange" /> |
| | | </div> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="ææåºå" name="manual"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title ml10">å
¥åºæ¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.timeStr" |
| | | type="date" |
| | | placeholder="è¯·éæ©æ¥æ" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | <span class="search_title ml10">产å大类ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.productCategory" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">æç´¢</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <!-- <el-button type="danger" plain @click="handleDelete">å é¤</el-button>--> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange" |
| | | :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%" |
| | | :row-class-name="tableRowClassName" |
| | | :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)"> |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column label="å
¥åºæ¥æ" prop="inboundDate" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="æ¹æ¬¡å·" prop="code" width="130" show-overflow-tooltip /> |
| | | <el-table-column label="产å大类" prop="productCategory" show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" show-overflow-tooltip /> |
| | | <el-table-column label="åä½" prop="unit" width="80" show-overflow-tooltip /> |
| | | <el-table-column label="ç©åç±»å" prop="itemType" width="120" show-overflow-tooltip /> |
| | | <el-table-column label="å·²åºåºæ°é" prop="totalInboundNum" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å©ä½åºå" prop="inboundNum0" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="åä»·(å
)" prop="taxInclusiveUnitPrice" width="150"></el-table-column> |
| | | <el-table-column label="æ»ä»·(å
)" prop="taxInclusiveTotalPrice" width="150"></el-table-column> |
| | | <el-table-column fixed="right" label="æä½" width="100" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="openForm('edit', scope.row);">ç¼è¾</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" :limit="page.size" @pagination="paginationChange" /> |
| | | </div> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | |
| | | <!-- æååºåå¼¹æ¡ --> |
| | | <FormDiaProduction |
| | | v-model:dialogFormVisible="productionDialogVisible" |
| | | :operationType="operationType" |
| | | :formData="form" |
| | | @submit="submitForm" |
| | | @close="closeDia" |
| | | /> |
| | | |
| | | <!-- åæåºåå¼¹æ¡ --> |
| | | <FormDiaPurchase |
| | | v-model:dialogFormVisible="purchaseDialogVisible" |
| | | :operationType="operationType" |
| | | :formData="form" |
| | | @submit="submitForm" |
| | | @close="closeDia" |
| | | /> |
| | | |
| | | <!-- ææåºåå¼¹æ¡ --> |
| | | <FormDiaManual |
| | | v-model:dialogFormVisible="manualDialogVisible" |
| | | :operationType="operationType" |
| | | :formData="form" |
| | | @submit="submitForm" |
| | | @close="closeDia" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | import { productTreeList,modelList } from "@/api/basicData/product.js" |
| | | import { |
| | | getStockManagePage, |
| | | getStockManagePageByProduction, |
| | | getStockManagePageByCustom, |
| | | delStockManage, |
| | | } from "@/api/inventoryManagement/stockManage.js"; |
| | | import { |
| | | updateManagement,updateStockIn |
| | | updateManagement, updateManagementByCustom, updateStockIn |
| | | } from "@/api/inventoryManagement/stockIn.js"; |
| | | |
| | | |
| | | // 导å
¥ä¸ä¸ªç¬ç«çå¼¹æ¡ç»ä»¶ |
| | | import FormDiaProduction from './components/FormDiaProduction.vue' |
| | | import FormDiaPurchase from './components/FormDiaPurchase.vue' |
| | | import FormDiaManual from './components/FormDiaManual.vue' |
| | | |
| | | const userStore = useUserStore() |
| | | const { proxy } = getCurrentInstance() |
| | |
| | | const loading = ref(false); |
| | | // ç¨æ·ä¿¡æ¯è¡¨åå¼¹æ¡æ°æ® |
| | | const operationType = ref('') |
| | | const dialogFormVisible = ref(false) |
| | | const activeTab = ref('production') |
| | | |
| | | // ä¸ä¸ªç¬ç«çå¼¹æ¡æ¾ç¤ºç¶æ |
| | | const productionDialogVisible = ref(false) |
| | | const purchaseDialogVisible = ref(false) |
| | | const manualDialogVisible = ref(false) |
| | | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | supplierName: '', |
| | | timeStr: '', |
| | | // supplierName: '', |
| | | productCategory:'', |
| | | customerName: '', |
| | | timeStr: getCurrentDate(), |
| | | }, |
| | | form: { |
| | | supplierId: null, |
| | | supplierName: '', |
| | | // supplierName: '', |
| | | productId: null, |
| | | productName: '', |
| | | userId: userStore.userId, |
| | |
| | | model: '', |
| | | unit: '', |
| | | productrecordId: null, |
| | | unitPrice: '', // æ·»å æååºåçåä»·åæ®µ |
| | | taxInclusiveUnitPrice: '', |
| | | taxInclusiveTotalPrice: '', |
| | | taxRate: '', |
| | |
| | | salesLedgerProductId: null, |
| | | }, |
| | | rules: { |
| | | supplierName: [{ required: true, message: '请è¾å
¥ä¾åºååç§°', trigger: 'blur' }], |
| | | // supplierName: [{ required: true, message: '请è¾å
¥ä¾åºååç§°', trigger: 'blur' }], |
| | | productCategory: [{ required: true, message: 'è¯·éæ©äº§å大类', trigger: 'change' }], |
| | | specificationModel: [{ required: true, message: '请è¾å
¥è§æ ¼åå·', trigger: 'blur' }], |
| | | unit: [{ required: true, message: '请è¾å
¥åä½', trigger: 'blur' }], |
| | | stockQuantity: [{ required: true, message: '请è¾å
¥åºåºæ°é', trigger: 'blur' }], |
| | | unitPrice: [{ required: true, message: '请è¾å
¥åä»·', trigger: 'blur' }], // æ·»å æååºååä»·çéªè¯è§å |
| | | taxInclusiveUnitPrice: [{ required: true, message: '请è¾å
¥å«ç¨åä»·', trigger: 'blur' }], |
| | | taxInclusiveTotalPrice: [{ required: true, message: '请è¾å
¥å«ç¨æ»ä»·', trigger: 'blur' }], |
| | | taxRate: [{ required: true, message: '请è¾å
¥ç¨ç', trigger: 'blur' }], |
| | |
| | | page.size = obj.limit; |
| | | getList() |
| | | } |
| | | const buildQueryParams = () => { |
| | | const params = { |
| | | ...page, |
| | | timeStr: searchForm.value.timeStr, |
| | | } |
| | | params.productCategory = searchForm.value.productCategory |
| | | if (activeTab.value === 'production') { |
| | | params.customerName = searchForm.value.customerName |
| | | } else { |
| | | // params.supplierName = searchForm.value.supplierName |
| | | } |
| | | return params |
| | | } |
| | | |
| | | const getList = () => { |
| | | tableLoading.value = true |
| | | getStockManagePage({ ...searchForm.value, ...page }).then(res => { |
| | | const params = buildQueryParams() |
| | | let apiCall |
| | | if (activeTab.value === 'production') { |
| | | apiCall = getStockManagePageByProduction(params) |
| | | } else if (activeTab.value === 'manual') { |
| | | apiCall = getStockManagePageByCustom(params) |
| | | } else { |
| | | apiCall = getStockManagePage(params) |
| | | } |
| | | apiCall.then(res => { |
| | | tableLoading.value = false |
| | | tableData.value = res.data.records |
| | | |
| | | // ä¸ºè¡¨æ ¼æ°æ®èªå¨è®¡ç®æ»ä»· |
| | | tableData.value = tableData.value.map(item => { |
| | | // 计ç®å©ä½åºå |
| | | const stockQuantity = parseFloat(item.inboundNum) || 0 |
| | | const outboundQuantity = parseFloat(item.totalInboundNum) || 0 |
| | | const remainingStock = Math.max(stockQuantity - outboundQuantity, 0) |
| | | |
| | | // æ ¹æ®æ ç¾é¡µç±»åè®¡ç®æ»ä»· |
| | | if (activeTab.value === 'production') { |
| | | // æååºåï¼æ»ä»· = åä»· à å©ä½åºå |
| | | const unitPrice = parseFloat(item.unitPrice) || 0 |
| | | item.totalPrice = (unitPrice * remainingStock).toFixed(2) |
| | | } else if (activeTab.value === 'purchase') { |
| | | // åæåºåï¼å«ç¨æ»ä»· = å«ç¨åä»· à å©ä½åºå |
| | | const taxInclusiveUnitPrice = parseFloat(item.taxInclusiveUnitPrice) || 0 |
| | | item.taxInclusiveTotalPrice = (taxInclusiveUnitPrice * remainingStock).toFixed(2) |
| | | } else if (activeTab.value === 'manual') { |
| | | // ææåºåï¼å«ç¨æ»ä»· = å«ç¨åä»· à å©ä½åºå |
| | | const taxInclusiveUnitPrice = parseFloat(item.taxInclusiveUnitPrice) || 0 |
| | | item.taxInclusiveTotalPrice = (taxInclusiveUnitPrice * remainingStock).toFixed(2) |
| | | } |
| | | |
| | | return item |
| | | }) |
| | | |
| | | total.value = res.data.total |
| | | // æ°æ®å è½½å®æåæ£æ¥åºå |
| | | // checkStockAndCreatePurchase(); |
| | | }).catch(() => { |
| | | tableLoading.value = false |
| | | }) |
| | | } |
| | | |
| | | // 忢 tab |
| | | const handleTabChange = () => { |
| | | page.current = 1 |
| | | // searchForm.value.supplierName = '' |
| | | searchForm.value.customerName = '' |
| | | searchForm.value.timeStr = '' |
| | | selectedRows.value = [] |
| | | searchForm.value.productCategory = '' |
| | | getList() |
| | | } |
| | | |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | |
| | | }) |
| | | } |
| | | form.value.entryDate = getCurrentDate() // 设置é»è®¤å½å
¥æ¥æä¸ºå½åæ¥æ |
| | | dialogFormVisible.value = true |
| | | |
| | | // æ ¹æ®å½åæ ç¾é¡µæ¾ç¤ºå¯¹åºçå¼¹æ¡ |
| | | if (activeTab.value === 'production') { |
| | | productionDialogVisible.value = true |
| | | } else if (activeTab.value === 'purchase') { |
| | | purchaseDialogVisible.value = true |
| | | } else if (activeTab.value === 'manual') { |
| | | manualDialogVisible.value = true |
| | | } |
| | | } |
| | | |
| | | // æäº¤è¡¨å |
| | | const submitForm = () => { |
| | | console.log(form.value) |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | const submitForm = (submittedData) => { |
| | | console.log('åç»ä»¶æäº¤çæ°æ®:', submittedData) |
| | | |
| | | updateManagement(form.value).then(res => { |
| | | // 使ç¨åç»ä»¶æäº¤çæ°æ®ï¼è䏿¯ç¶ç»ä»¶çform对象 |
| | | const submitData = { ...submittedData } |
| | | |
| | | // æ ¹æ®å½åæ ç¾é¡µç§»é¤å¯¹åºçæ»ä»·å段 |
| | | if (activeTab.value === 'production') { |
| | | // æååºåï¼ç§»é¤æ»ä»·å段 |
| | | delete submitData.totalPrice |
| | | } else if (activeTab.value === 'purchase') { |
| | | // åæåºåï¼ç§»é¤å«ç¨æ»ä»·å段 |
| | | delete submitData.taxInclusiveTotalPrice |
| | | } else if (activeTab.value === 'manual') { |
| | | // ææåºåï¼ç§»é¤å«ç¨æ»ä»·å段 |
| | | delete submitData.taxInclusiveTotalPrice |
| | | } |
| | | |
| | | // ç§»é¤å
¶ä»å¯è½çæ»ä»·å段 |
| | | delete submitData.taxExclusiveTotalPrice |
| | | |
| | | console.log('æäº¤ç»åç«¯çæ°æ®ï¼å·²ç§»é¤æ»ä»·å段ï¼:', submitData) |
| | | |
| | | // æ ¹æ®å½åæ ç¾é¡µè°ç¨ä¸åçæäº¤æ¥å£ |
| | | let apiCall |
| | | if (activeTab.value === 'production') { |
| | | // æååºåä½¿ç¨ updateManagement æ¥å£ |
| | | apiCall = updateManagement(submitData) |
| | | } else if (activeTab.value === 'manual') { |
| | | // ææåºåä½¿ç¨ updateManagementByCustom æ¥å£ |
| | | apiCall = updateManagementByCustom(submitData) |
| | | } else { |
| | | // åæåºåä½¿ç¨ updateManagementByCustom æ¥å£ |
| | | apiCall = updateManagementByCustom(submitData) |
| | | } |
| | | |
| | | apiCall.then(res => { |
| | | proxy.$modal.msgSuccess("æäº¤æå") |
| | | closeDia() |
| | | getList() |
| | | // æäº¤åæ£æ¥åºåå¹¶å°è¯å建请è´å |
| | | // checkStockAndCreatePurchase(); |
| | | }) |
| | | } |
| | | }).catch(error => { |
| | | console.error('æäº¤å¤±è´¥:', error) |
| | | proxy.$modal.msgError("æäº¤å¤±è´¥ï¼è¯·éè¯") |
| | | }) |
| | | } |
| | | // æ£æ¥åºåå¹¶å建请è´å |
| | |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef") |
| | | dialogFormVisible.value = false |
| | | productionDialogVisible.value = false |
| | | purchaseDialogVisible.value = false |
| | | manualDialogVisible.value = false |
| | | } |
| | | |
| | | // å¯¼åº |
| | |
| | | type: 'warning', |
| | | } |
| | | ).then(() => { |
| | | proxy.download("/stockin/exportCopy", {}, 'åºåä¿¡æ¯.xlsx') |
| | | const exportParams = buildQueryParams() |
| | | // æ ¹æ®ä¸åç tab ç±»åè°ç¨ä¸åçå¯¼åºæ¥å£ |
| | | let exportUrl = "/stockin/exportCopy" |
| | | if (activeTab.value === 'production') { |
| | | exportUrl = "/stockin/exportCopyOne" |
| | | } else if (activeTab.value === 'manual') { |
| | | exportUrl = "/stockin/exportCopyTwo" |
| | | } |
| | | proxy.download(exportUrl, exportParams, 'åºåä¿¡æ¯.xlsx') |
| | | }).catch(() => { |
| | | proxy.$modal.msg("已忶") |
| | | }) |
| | |
| | | const handleDelete = () => { |
| | | let ids = [] |
| | | if (selectedRows.value.length > 0) { |
| | | // æ£æ¥æ¯å¦æä»äººç»´æ¤çæ°æ® |
| | | const unauthorizedData = selectedRows.value.filter(item => item.createUser !== userStore.id); |
| | | if (unauthorizedData.length > 0) { |
| | | proxy.$modal.msgWarning("ä¸å¯å é¤ä»äººç»´æ¤çæ°æ®"); |
| | | return; |
| | | } |
| | | ids = selectedRows.value.map(item => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning('è¯·éæ©æ°æ®') |
| | |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | height="500" |
| | | :page="page" |
| | | @pagination="pagination" |
| | | > |
| | | </PIMTable> |
| | | <pagination |
| | | style="margin: 10px 0" |
| | | v-show="total > 0" |
| | | @pagination="paginationSearch" |
| | | :total="total" |
| | | :page="page.current" |
| | | :limit="page.size" |
| | | /> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | total: 0 |
| | | }); |
| | | const total = ref(0); |
| | | const tableData = ref([]); |
| | |
| | | currentId.value = row.id; |
| | | getList() |
| | | } |
| | | const paginationSearch = (obj) => { |
| | | const pagination = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | |
| | | const getList = () => { |
| | | fileListPage({accountId: currentId.value,accountType:accountType.value, ...page}).then(res => { |
| | | tableData.value = res.data.records; |
| | | total.value = res.data.total; |
| | | page.total = res.data.total; |
| | | }) |
| | | } |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import { onMounted, ref } from "vue"; |
| | | import { Search, UploadFilled } from "@element-plus/icons-vue"; |
| | | import { onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick } from "vue"; |
| | | import FormDia from "@/views/personnelManagement/contractManagement/components/formDia.vue"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { staffOnJobListPage } from "@/api/personnelManagement/employeeRecord.js"; |
| | | import { staffOnJobListPage, staffOnJobExportCopy } from "@/api/personnelManagement/employeeRecord.js"; |
| | | import dayjs from "dayjs"; |
| | | import { getToken } from "@/utils/auth.js"; |
| | | import FilesDia from "./filesDia.vue"; |
| | |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: 'right', |
| | | width: 120, |
| | | width: 180, |
| | | operation: [ |
| | | { |
| | | name: "详æ
", |
| | |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openFilesFormDia(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "ä¸è½½åå", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | handleDownloadContract(row); |
| | | }, |
| | | }, |
| | | ], |
| | |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | // ä¸è½½åå |
| | | const handleDownloadContract = (row) => { |
| | | const fileName = `${row.staffName || "åå"}å³å¨åå.docx`; |
| | | proxy.$modal?.loading?.("æ£å¨çæååï¼è¯·ç¨å..."); |
| | | staffOnJobExportCopy({ ...row }) |
| | | .then((res) => { |
| | | proxy.$modal?.closeLoading?.(); |
| | | if (res?.code === 200 && res?.msg) { |
| | | const javaApi = proxy.javaApi || import.meta.env.VITE_JAVA_API || ""; |
| | | const downloadPath = res.msg.startsWith("/") ? res.msg : `/${res.msg}`; |
| | | const downloadUrl = `${javaApi}${downloadPath}`; |
| | | const link = document.createElement("a"); |
| | | link.href = downloadUrl; |
| | | link.download = fileName; |
| | | link.target = "_blank"; |
| | | document.body.appendChild(link); |
| | | link.click(); |
| | | document.body.removeChild(link); |
| | | } else { |
| | | proxy.$modal.msgError(res?.msg || "ååçæå¤±è´¥"); |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal?.closeLoading?.(); |
| | | proxy.$modal.msgError("ååçæå¤±è´¥ï¼è¯·ç¨åéè¯"); |
| | | }); |
| | | }; |
| | | const upload = reactive({ |
| | | // æ¯å¦æ¾ç¤ºå¼¹åºå±ï¼åå导å
¥ï¼ |
| | | open: false, |
| | |
| | | <el-col :span="12"> |
| | | <div class="info-item"> |
| | | <span class="info-label">å§åï¼</span> |
| | | <el-select v-model="form.staffName" placeholder="è¯·éæ©äººå" style="width: 100%" @change="handleSelect"> |
| | | <el-select v-model="form.staffName" filterable |
| | | default-first-option |
| | | :reserve-keyword="false" placeholder="è¯·éæ©äººå" style="width: 100%" @change="handleSelect"> |
| | | <el-option |
| | | v-for="item in personList" |
| | | :key="item.id" |
| | |
| | | width="70%" |
| | | @close="closeDia" |
| | | > |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :tableLoading="tableLoading" |
| | | height="600" |
| | | ></PIMTable> |
| | | <el-descriptions class="detail-descriptions" :column="2" border size="small"> |
| | | <el-descriptions-item label="åå·¥ç¼å·">{{ formData.staffNo || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="å§å">{{ formData.staffName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="æ§å«">{{ formData.sex || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¹´é¾">{{ formData.age || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="身份è¯å·">{{ formData.identityCard || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="æ·ç±ä½å" :span="2">{{ formData.nativePlace || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="ç°ä½å" :span="2">{{ formData.adress || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="å²ä½">{{ formData.postJob || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="第ä¸å¦å">{{ formData.firstStudy || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="ä¸ä¸">{{ formData.profession || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="èç³»çµè¯">{{ formData.phone || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="ç´§æ¥è系人">{{ formData.emergencyContact || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="ç´§æ¥è系人çµè¯">{{ formData.emergencyContactPhone || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="ååç¾è®¢æ¥æ">{{ formData.signDate || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="å³å¨ååæééæ©"> |
| | | <span v-if="formData.dateSelect === 'A'">Aãæåºå®æé</span> |
| | | <span v-else-if="formData.dateSelect === 'B'">Bãæ åºå®æé</span> |
| | | <span v-else-if="formData.dateSelect === 'C'">Cã以宿ä¸å®å·¥ä½ä»»å¡ä¸ºæé</span> |
| | | <span v-else>-</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="ååå¹´é">{{ formattedContractTerm }}</el-descriptions-item> |
| | | <el-descriptions-item label="è¯ç¨æå¼å§æ¥æ" v-if="formData.dateSelect === 'A' || formData.dateSelect === 'B'"> |
| | | {{ formData.trialStartDate || '-' }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="è¯ç¨æç»ææ¥æ" v-if="formData.dateSelect === 'A' || formData.dateSelect === 'B'"> |
| | | {{ formData.trialEndDate || '-' }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="è¯ç¨æå·¥èµ" v-if="formData.dateSelect === 'A' || formData.dateSelect === 'B'"> |
| | | {{ formData.proSalary ? formData.proSalary.toFixed(2) : '-' }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="ååå¼å§æ¥æ">{{ calculatedContractStart }}</el-descriptions-item> |
| | | <el-descriptions-item label="ååç»ææ¥æ">{{ formData.contractEndTime || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="å·¥èµæ¥é
¬" :span="2"> |
| | | <span v-if="formData.salarySelect === 'A'"> |
| | | Aã乿¹çå·¥èµæ¥é
¬æç
§ç²æ¹ä¾æ³å¶å®çè§ç« å¶åº¦ä¸çå
é¨å·¥èµåé
åæ³ç¡®å®ï¼æ ¹æ®ä¹æ¹çå·¥ä½å²ä½ç¡®å®å
¶æ¯æå·¥èµã |
| | | </span> |
| | | <span v-else-if="formData.salarySelect === 'B'"> |
| | | Bãç²æ¹å¯¹ä¹æ¹å®è¡åºæ¬å·¥èµå绩æå·¥èµç¸ç»åçå
é¨å·¥èµåé
åæ³ï¼ä¹æ¹çæ¶å
¥å
æ¬åºæ¬å·¥èµã误é¤ã交éãçæ´»ä½å®¿çå项补å©ï¼å¦æå卿 ¹æ®å
é¨å·¥èµåé
åæ³è°æ´å
¶å·¥èµï¼ç»©æå·¥èµæ ¹æ®ä¹æ¹çå·¥ä½ä¸ç»©ãå³å¨ææåå®é
è´¡ç®æç
§å
é¨åé
åæ³èæ ¸ç¡®å®ã |
| | | </span> |
| | | <span v-else-if="formData.salarySelect === 'C'"> |
| | | Cãç²æ¹å®è¡è®¡ä»¶å·¥èµå¶ï¼ä»¥ç²æ¹æ¥å°è®¢ååå
¬å¸ç产计åï¼æç
§å®é¢å计件åä»·ï¼æ ¹æ®ä¹æ¹å®æçä¸ç»©ï¼ææ¶è¶³é¢æ¯ä»ä¹æ¹çå·¥èµæ¥é
‹ |
| | | </span> |
| | | <span v-else>-</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="ç¦å©å¾
é" :span="2">{{ formData.remark || '-' }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | | <el-button @click="closeDia">å
³é</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref} from "vue"; |
| | | import {staffOnJobInfo} from "@/api/personnelManagement/employeeRecord.js"; |
| | | const { proxy } = getCurrentInstance() |
| | | import {ref, reactive, computed} from "vue"; |
| | | import dayjs from "dayjs"; |
| | | const emit = defineEmits(['close']) |
| | | |
| | | const dialogFormVisible = ref(false); |
| | | const operationType = ref('') |
| | | const tableColumn = ref([ |
| | | // { |
| | | // label: "ååå¹´é", |
| | | // prop: "contractTerm", |
| | | // }, |
| | | { |
| | | label: "ååå¼å§æ¥æ", |
| | | prop: "contractStartTime", |
| | | }, |
| | | { |
| | | label: "ååç»ææ¥æ", |
| | | prop: "contractEndTime", |
| | | }, |
| | | ]); |
| | | const tableData = ref([]); |
| | | const tableLoading = ref(false); |
| | | const formData = reactive({ |
| | | staffNo: "", |
| | | staffName: "", |
| | | sex: "", |
| | | identityCard: "", |
| | | nativePlace: "", |
| | | postJob: "", |
| | | adress: "", |
| | | firstStudy: "", |
| | | profession: "", |
| | | age: 0, |
| | | phone: "", |
| | | emergencyContact: "", |
| | | emergencyContactPhone: "", |
| | | dateSelect: "", |
| | | trialStartDate: "", |
| | | trialEndDate: "", |
| | | proSalary: null, |
| | | signDate: "", |
| | | salarySelect: "", |
| | | contractStartTime: "", |
| | | contractEndTime: "", |
| | | contractTerm: null, |
| | | remark: "", |
| | | }); |
| | | |
| | | const formattedContractTerm = computed(() => { |
| | | const value = formData.contractTerm; |
| | | if (value === null || value === undefined || value === "") { |
| | | return "-"; |
| | | } |
| | | const numberValue = Number(value); |
| | | if (!isNaN(numberValue)) { |
| | | return `${numberValue}å¹´`; |
| | | } |
| | | return value; |
| | | }); |
| | | |
| | | const calculatedContractStart = computed(() => { |
| | | const endDate = formData.contractEndTime; |
| | | const termValue = formData.contractTerm; |
| | | const numberValue = Number(termValue); |
| | | if (!endDate || isNaN(numberValue)) { |
| | | return formData.contractStartTime || "-"; |
| | | } |
| | | const start = dayjs(endDate).subtract(numberValue, "year"); |
| | | if (!start.isValid()) { |
| | | return formData.contractStartTime || "-"; |
| | | } |
| | | return start.format("YYYY-MM-DD"); |
| | | }); |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = (type, row) => { |
| | | operationType.value = type; |
| | | dialogFormVisible.value = true; |
| | | if (operationType.value === 'edit') { |
| | | staffOnJobInfo({staffNo: row.staffNo}).then(res => { |
| | | tableData.value = res.data |
| | | }) |
| | | // éç½®è¡¨åæ°æ® |
| | | Object.keys(formData).forEach(key => { |
| | | if (key === 'age') { |
| | | formData[key] = 0; |
| | | } else if (["proSalary", "contractTerm"].includes(key)) { |
| | | formData[key] = null; |
| | | } else { |
| | | formData[key] = ""; |
| | | } |
| | | }); |
| | | |
| | | if (operationType.value === 'edit' && row) { |
| | | // ç´æ¥ä½¿ç¨ row æ°æ®èµå¼ |
| | | Object.assign(formData, row); |
| | | } |
| | | } |
| | | |
| | |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .detail-descriptions { |
| | | margin-bottom: 16px; |
| | | border-radius: 6px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .detail-descriptions :deep(.el-descriptions__cell) { |
| | | padding: 12px 16px !important; |
| | | } |
| | | |
| | | .detail-descriptions :deep(.el-descriptions__label) { |
| | | width: 140px; |
| | | color: #606266; |
| | | background-color: #f7f9fc; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .detail-descriptions :deep(.el-descriptions__content) { |
| | | color: #303133; |
| | | line-height: 20px; |
| | | } |
| | | </style> |
| | |
| | | <el-input v-model="form.emergencyContactPhone" placeholder="请è¾å
¥" clearable/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ååå¹´éï¼" prop="contractTerm"> |
| | | <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <!-- <el-col :span="12">--> |
| | | <!-- <el-form-item label="ååå¹´éï¼" prop="contractTermcontractTerm">--> |
| | | <!-- <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/>--> |
| | | <!-- </el-form-item>--> |
| | | <!-- </el-col>--> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | style="width: 100%" |
| | | @change="calculateContractTerm" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | style="width: 100%" |
| | | @change="calculateContractTerm" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | const openDialog = (type, row) => { |
| | | operationType.value = type; |
| | | dialogFormVisible.value = true; |
| | | form.value.id = '' |
| | | if (operationType.value === 'edit') { |
| | | getStaffJoinInfo(row.id).then(res => { |
| | | form.value = {...res.data} |
| | | // ç¼è¾æ¶ä¹è®¡ç®ä¸æ¬¡ååå¹´é |
| | | calculateContractTerm(); |
| | | // calculateContractTerm(); |
| | | }) |
| | | } else { |
| | | form.value.id = '' |
| | | } |
| | | } |
| | | // æäº¤äº§å表å |
| | |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="身份è¯å·ï¼" prop="identityCard"> |
| | | <el-input v-model="form.identityCard" placeholder="请è¾å
¥èº«ä»½è¯å·ç " clearable maxlength="18" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¹´é¾ï¼" prop="age"> |
| | | <el-input-number v-model="form.age" :precision="0" :step="1" style="width: 100%"/> |
| | | </el-form-item> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ååç¾è®¢æ¥æï¼" prop="trialStartDate"> |
| | | <el-form-item label="ååç¾è®¢æ¥æï¼" prop="signDate"> |
| | | <el-date-picker |
| | | v-model="form.trialStartDate" |
| | | v-model="form.signDate" |
| | | type="date" |
| | | placeholder="è¯·éæ©æ¥æ" |
| | | value-format="YYYY-MM-DD" |
| | |
| | | </el-row> |
| | | <el-row :gutter="30" v-if="showProbationDates"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è¯ç¨æå¼å§æ¥æï¼" prop="signDate"> |
| | | <el-form-item label="è¯ç¨æå¼å§æ¥æï¼" prop="trialStartDate"> |
| | | <el-date-picker |
| | | v-model="form.signDate" |
| | | v-model="form.trialStartDate" |
| | | type="date" |
| | | placeholder="è¯·éæ©æ¥æ" |
| | | value-format="YYYY-MM-DD" |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <!-- <el-row :gutter="30">--> |
| | | <!-- <el-col :span="12">--> |
| | | <!-- <el-form-item label="ååå¹´éï¼" prop="contractTerm">--> |
| | | <!-- <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/>--> |
| | | <!-- </el-form-item>--> |
| | | <!-- </el-col>--> |
| | | <!-- </el-row>--> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ååå¹´éï¼" prop="contractTerm"> |
| | | <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ååå¼å§æ¥æï¼" prop="contractStartTime"> |
| | |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | style="width: 100%" |
| | | @change="calculateContractTerm" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | style="width: 100%" |
| | | @change="calculateContractTerm" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | staffNo: "", |
| | | staffName: "", |
| | | sex: "", |
| | | identityCard: "", |
| | | nativePlace: "", |
| | | postJob: "", |
| | | adress: "", |
| | |
| | | emergencyContact: "", |
| | | emergencyContactPhone: "", |
| | | dateSelect: "", |
| | | signDate: "", |
| | | trialStartDate: "", |
| | | trialEndDate: "", |
| | | proSalary: null, |
| | | trialStartDate: "", |
| | | signDate: "", |
| | | salarySelect: "", |
| | | // contractTerm: 0, |
| | | contractTerm: 0, |
| | | contractStartTime: "", |
| | | contractEndTime: "", |
| | | staffState: "", |
| | | remark: "æ ", |
| | | }, |
| | | rules: { |
| | | staffNo: [{ required: true, message: "请è¾å
¥", trigger: "blur" },], |
| | | staffName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | sex: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | identityCard: [{ required: true, message: "请è¾å
¥èº«ä»½è¯å·ç ", trigger: "blur" }], |
| | | nativePlace: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | postJob: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | adress: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | |
| | | emergencyContact: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | remark: [{ required: false, message: "请è¾å
¥", trigger: "blur" }], |
| | | dateSelect: [{ required: true, message: "è¯·éæ©å³å¨ååæé", trigger: "change" }], |
| | | signDate: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | trialEndDate: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | trialStartDate: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | trialEndDate: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | signDate: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | salarySelect: [{ required: true, message: "è¯·éæ©å·¥èµæ¥é
¬æ¹å¼", trigger: "change" }], |
| | | // contractTerm: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | contractTerm: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | contractStartTime: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | contractEndTime: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | proSalary: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | }, |
| | | }); |
| | | const { form, rules } = toRefs(data); |
| | |
| | | const openDialog = (type, row) => { |
| | | operationType.value = type; |
| | | dialogFormVisible.value = true; |
| | | form.value.id = '' |
| | | if (operationType.value === 'edit') { |
| | | getStaffJoinInfo(row.id).then(res => { |
| | | form.value = {...res.data} |
| | | // ç¼è¾æ¶ä¹è®¡ç®ä¸æ¬¡ååå¹´é |
| | | // calculateContractTerm(); |
| | | calculateContractTerm(); |
| | | }) |
| | | } |
| | | } |
| | |
| | | }) |
| | | } |
| | | // 计ç®ååå¹´é |
| | | // const calculateContractTerm = () => { |
| | | // if (form.value.contractStartTime && form.value.contractEndTime) { |
| | | // const startDate = new Date(form.value.contractStartTime); |
| | | // const endDate = new Date(form.value.contractEndTime); |
| | | // |
| | | // if (endDate > startDate) { |
| | | // // 计ç®å¹´ä»½å·® |
| | | // const yearDiff = endDate.getFullYear() - startDate.getFullYear(); |
| | | // const monthDiff = endDate.getMonth() - startDate.getMonth(); |
| | | // const dayDiff = endDate.getDate() - startDate.getDate(); |
| | | // |
| | | // let years = yearDiff; |
| | | // |
| | | // // å¦æç»ææ¥æçææ¥å°äºå¼å§æ¥æçææ¥ï¼ååå»1å¹´ |
| | | // if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) { |
| | | // years = yearDiff - 1; |
| | | // } |
| | | // |
| | | // form.value.contractTerm = Math.max(0, years); |
| | | // } else { |
| | | // form.value.contractTerm = 0; |
| | | // } |
| | | // } else { |
| | | // form.value.contractTerm = 0; |
| | | // } |
| | | // }; |
| | | const calculateContractTerm = () => { |
| | | if (form.value.contractStartTime && form.value.contractEndTime) { |
| | | const startDate = new Date(form.value.contractStartTime); |
| | | const endDate = new Date(form.value.contractEndTime); |
| | | |
| | | if (endDate > startDate) { |
| | | // 计ç®å¹´ä»½å·® |
| | | const yearDiff = endDate.getFullYear() - startDate.getFullYear(); |
| | | const monthDiff = endDate.getMonth() - startDate.getMonth(); |
| | | const dayDiff = endDate.getDate() - startDate.getDate(); |
| | | |
| | | let years = yearDiff; |
| | | |
| | | // å¦æç»ææ¥æçææ¥å°äºå¼å§æ¥æçææ¥ï¼ååå»1å¹´ |
| | | if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) { |
| | | years = yearDiff - 1; |
| | | } |
| | | |
| | | form.value.contractTerm = Math.max(0, years); |
| | | } else { |
| | | form.value.contractTerm = 0; |
| | | } |
| | | } else { |
| | | form.value.contractTerm = 0; |
| | | } |
| | | }; |
| | | |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | |
| | | <script setup> |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import {onMounted, ref} from "vue"; |
| | | import FormDia from "@/views/personnelManagement/onboarding/components/formDia.vue"; |
| | | // import FormDia from "@/views/personnelManagement/onboarding/components/formDiaXJHT.vue"; // æ°çé£åå
¬å¸ç¨ç表å |
| | | // import FormDia from "@/views/personnelManagement/onboarding/components/formDia.vue"; |
| | | import FormDia from "@/views/personnelManagement/onboarding/components/formDiaXJHT.vue"; // æ°çé£åå
¬å¸ç¨ç表å |
| | | import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import dayjs from "dayjs"; |
| | |
| | | <el-select v-model="form.staffId" placeholder="è¯·éæ©äººå" style="width: 100%" @change="handleSelect" :disabled="operationType === 'edit'"> |
| | | <el-option |
| | | v-for="item in personList" |
| | | :key="item.id" |
| | | :label="item.staffName" |
| | | :value="item.id" |
| | | :key="item.userId" |
| | | :label="item.nickName" |
| | | :value="item.userId" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåºå¤å¤©æ°ï¼" prop="shouldAttendedNum"> |
| | | <el-input v-model="form.shouldAttendedNum" placeholder="请è¾å
¥" clearable type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å®é
åºå¤å¤©æ°ï¼" prop="actualAttendedNum"> |
| | | <el-input v-model="form.actualAttendedNum" placeholder="请è¾å
¥" clearable type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºæ¬å·¥èµï¼" prop="basicSalary"> |
| | | <el-input v-model="form.basicSalary" placeholder="请è¾å
¥" clearable type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å²ä½å·¥èµï¼" prop="postSalary"> |
| | | <el-input v-model="form.postSalary" placeholder="请è¾å
¥" clearable type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¥ç¦»èç¼ºå¤æ£æ¬¾ï¼" prop="deductionAbsenteeism"> |
| | | <el-input v-model="form.deductionAbsenteeism" placeholder="请è¾å
¥" clearable type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç
åæ£æ¬¾ï¼" prop="sickLeaveDeductions"> |
| | | <el-input v-model="form.sickLeaveDeductions" placeholder="请è¾å
¥" clearable type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="äºåæ£æ¬¾ï¼" prop="deductionPersonalLeave"> |
| | | <el-input v-model="form.deductionPersonalLeave" placeholder="请è¾å
¥" clearable type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¿è®°æå¡æ£æ¬¾ï¼" prop="forgetClockDeduct"> |
| | | <el-input v-model="form.forgetClockDeduct" style="width: 100%" type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="绩æå¾åï¼" prop="performanceScore"> |
| | | <el-input v-model="form.performanceScore" placeholder="请è¾å
¥" clearable type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="绩æå·¥èµï¼" prop="performancePay"> |
| | | <el-input v-model="form.performancePay" placeholder="请è¾å
¥" clearable type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåå计ï¼" prop="payableWages"> |
| | | <el-input v-model="form.payableWages" placeholder="请è¾å
¥" clearable type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="社ä¿ä¸ªäººï¼" prop="socialSecurityIndividuals"> |
| | | <el-input v-model="form.socialSecurityIndividuals" :precision="0" :step="1" style="width: 100%" type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="社ä¿å
¬å¸ï¼" prop="socialSecurityCompanies"> |
| | | <el-input v-model="form.socialSecurityCompanies" :precision="0" :step="1" style="width: 100%" type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="社ä¿å计ï¼" prop="socialSecurityTotal"> |
| | | <el-input v-model="form.socialSecurityTotal" :precision="0" :step="1" style="width: 100%" type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¬ç§¯é个人ï¼" prop="providentFundIndividuals"> |
| | | <el-input v-model="form.providentFundIndividuals" :precision="0" :step="1" style="width: 100%" type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¬ç§¯éå
¬å¸ï¼" prop="providentFundCompany"> |
| | | <el-input v-model="form.providentFundCompany" :precision="0" :step="1" style="width: 100%" type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¬ç§¯éå计ï¼" prop="providentFundTotal"> |
| | | <el-input v-model="form.providentFundTotal" :precision="0" :step="1" style="width: 100%" type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºç¨å·¥èµï¼" prop="taxableWaget"> |
| | | <el-input v-model="form.taxableWaget" :precision="0" :step="1" style="width: 100%" type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="个人æå¾ç¨ï¼" prop="personalIncomeTax"> |
| | | <el-input v-model="form.personalIncomeTax" :step="0.1" style="width: 100%" type="number"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å®åå·¥èµï¼" prop="actualWages"> |
| | | <el-input v-model="form.actualWages" style="width: 100%" type="number"/> |
| | |
| | | import {ref} from "vue"; |
| | | import {getStaffJoinInfo, getStaffOnJob, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js"; |
| | | import {compensationAdd, compensationUpdate} from "@/api/personnelManagement/payrollManagement.js"; |
| | | import {listUser} from "@/api/system/user.js"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | |
| | |
| | | payDate: "", |
| | | staffId: "", |
| | | name: "", |
| | | shouldAttendedNum: "", |
| | | actualAttendedNum: "", |
| | | basicSalary: "", |
| | | postSalary: "", |
| | | deductionAbsenteeism: "", |
| | | sickLeaveDeductions: "", |
| | | deductionPersonalLeave: "", |
| | | forgetClockDeduct: "", |
| | | performanceScore: "", |
| | | performancePay: "", |
| | | payableWages: "", |
| | | socialSecurityIndividuals: "", |
| | | socialSecurityCompanies: "", |
| | | socialSecurityTotal: "", |
| | | providentFundIndividuals: "", |
| | | providentFundCompany: "", |
| | | providentFundTotal: "", |
| | | taxableWaget: "", |
| | | personalIncomeTax: "", |
| | | actualWages: "", |
| | | }, |
| | | rules: { |
| | | payDate: [{ required: true, message: "è¯·éæ©", trigger: "change" },], |
| | | staffId: [{ required: true, message: "è¯·éæ©", trigger: "change" },], |
| | | staffName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | shouldAttendedNum: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | actualAttendedNum: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | basicSalary: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | postSalary: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | deductionAbsenteeism: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | sickLeaveDeductions: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | deductionPersonalLeave: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | forgetClockDeduct: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | performanceScore: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | performancePay: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | payableWages: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | socialSecurityIndividuals: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | socialSecurityCompanies: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | socialSecurityTotal: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | providentFundIndividuals: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | providentFundCompany: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | providentFundTotal: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | taxableWaget: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | personalIncomeTax: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | actualWages: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | }, |
| | | }); |
| | |
| | | const openDialog = (type, row) => { |
| | | operationType.value = type; |
| | | dialogFormVisible.value = true; |
| | | getStaffOnJob().then(res => { |
| | | personList.value = res.data |
| | | listUser().then(res => { |
| | | personList.value = res.rows |
| | | }) |
| | | form.value = {} |
| | | if (operationType.value === 'edit') { |
| | |
| | | } |
| | | } |
| | | const handleSelect = (value) => { |
| | | console.log('value', value) |
| | | const index = personList.value.findIndex(row => row.id === value) |
| | | const index = personList.value.findIndex(row => row.userId === value) |
| | | if (index > -1) { |
| | | form.value.name = personList.value[index].staffName |
| | | form.value.name = personList.value[index].nickName |
| | | } |
| | | } |
| | | // æäº¤äº§å表å |
| | |
| | | > |
| | | </div> |
| | | <div> |
| | | <el-button @click="handleExport" style="margin-right: 10px">导åº</el-button> |
| | | <el-button @click="handleImport">导å
¥</el-button> |
| | | <el-button type="primary" @click="openForm('add')">æ°å¢èªèµ</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | <el-button @click="handleExport">导åº</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | |
| | | ></PIMTable> |
| | | </div> |
| | | <form-dia ref="formDia" @close="handleQuery"></form-dia> |
| | | |
| | | <!-- 导å
¥å¼¹çª --> |
| | | <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body @close="handleUploadClose"> |
| | | <el-upload |
| | | ref="uploadRef" |
| | | :limit="1" |
| | | accept=".xlsx, .xls" |
| | | :headers="upload.headers" |
| | | :action="upload.url" |
| | | :disabled="upload.isUploading" |
| | | :on-progress="upload.onProgress" |
| | | :on-success="upload.onSuccess" |
| | | :on-error="upload.onError" |
| | | :on-change="upload.onChange" |
| | | :auto-upload="false" |
| | | drag |
| | | > |
| | | <el-icon class="el-icon--upload"><upload-filled /></el-icon> |
| | | <div class="el-upload__text">å°æä»¶æå°æ¤å¤ï¼æ<em>ç¹å»ä¸ä¼ </em></div> |
| | | <template #tip> |
| | | <div class="el-upload__tip text-center"> |
| | | <span>ä»
å
许导å
¥xlsãxlsxæ ¼å¼æä»¶ã</span> |
| | | <el-link |
| | | type="primary" |
| | | :underline="false" |
| | | style="font-size: 12px; vertical-align: baseline" |
| | | @click="importTemplate" |
| | | >ä¸è½½æ¨¡æ¿</el-link> |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitFileForm">ç¡® å®</el-button> |
| | | <el-button @click="handleUploadCancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import { Search, UploadFilled } from "@element-plus/icons-vue"; |
| | | import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue"; |
| | | import FormDia from "@/views/personnelManagement/payrollManagement/components/formDia.vue"; |
| | | import {staffJoinDel} from "@/api/personnelManagement/onboarding.js"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import dayjs from "dayjs"; |
| | | import {compensationDelete, compensationListPage} from "@/api/personnelManagement/payrollManagement.js"; |
| | | import { getToken } from "@/utils/auth.js"; |
| | | |
| | | const data = reactive({ |
| | | searchForm: { |
| | |
| | | { |
| | | label: "å§å", |
| | | prop: "name", |
| | | }, |
| | | { |
| | | label: "åºåºå¤å¤©æ°", |
| | | prop: "shouldAttendedNum", |
| | | width:100 |
| | | }, |
| | | { |
| | | label: "å®é
åºå¤å¤©æ°", |
| | | prop: "actualAttendedNum", |
| | | width:110 |
| | | }, |
| | | { |
| | | label: "åºæ¬å·¥èµ", |
| | | prop: "basicSalary", |
| | | }, |
| | | { |
| | | label: "å²ä½å·¥èµ", |
| | | prop: "postSalary", |
| | | width:100 |
| | | }, |
| | | { |
| | | label: "å
¥ç¦»èç¼ºå¤æ£æ¬¾", |
| | | prop: "deductionAbsenteeism", |
| | | width:130 |
| | | }, |
| | | { |
| | | label: "ç
åæ£æ¬¾", |
| | | prop: "sickLeaveDeductions", |
| | | width:100 |
| | | }, |
| | | { |
| | | label: "äºåæ£æ¬¾", |
| | | prop: "deductionPersonalLeave", |
| | | width:100 |
| | | }, |
| | | { |
| | | label: "å¿è®°æå¡æ£æ¬¾", |
| | | prop: "forgetClockDeduct", |
| | | width:110 |
| | | }, |
| | | { |
| | | label: "绩æå¾å", |
| | | prop: "performanceScore", |
| | | width:150 |
| | | }, |
| | | { |
| | | label: "绩æå·¥èµ", |
| | | prop: "performancePay", |
| | | width: 120 |
| | | }, |
| | | { |
| | | label: "åºåå计", |
| | | prop: "payableWages", |
| | | width:150 |
| | | }, |
| | | { |
| | | label: "社ä¿ä¸ªäºº", |
| | | prop: "socialSecurityIndividuals", |
| | | }, |
| | | { |
| | | label: "社ä¿å
¬å¸", |
| | | prop: "socialSecurityCompanies", |
| | | width: 120 |
| | | }, |
| | | { |
| | | label: "社ä¿å计", |
| | | prop: "socialSecurityTotal", |
| | | width: 120 |
| | | }, |
| | | { |
| | | label: "å
¬ç§¯é个人", |
| | | prop: "providentFundIndividuals", |
| | | width: 120 |
| | | }, |
| | | { |
| | | label: "å
¬ç§¯éå
¬å¸", |
| | | prop: "providentFundCompany", |
| | | width: 120 |
| | | }, |
| | | { |
| | | label: "å
¬ç§¯éå计", |
| | | prop: "providentFundTotal", |
| | | width: 120 |
| | | }, |
| | | { |
| | | label: "åºç¨å·¥èµ", |
| | | prop: "taxableWaget", |
| | | }, |
| | | { |
| | | label: "个人æå¾ç¨", |
| | | prop: "personalIncomeTax", |
| | | width: 120 |
| | | }, |
| | | { |
| | | label: "å®åå·¥èµ", |
| | |
| | | }); |
| | | const formDia = ref() |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | | // 导å
¥åè½é
ç½® |
| | | const upload = reactive({ |
| | | // æ¯å¦æ¾ç¤ºå¼¹åºå±ï¼èªèµå¯¼å
¥ï¼ |
| | | open: false, |
| | | // å¼¹åºå±æ é¢ï¼èªèµå¯¼å
¥ï¼ |
| | | title: "", |
| | | // æ¯å¦ç¦ç¨ä¸ä¼ |
| | | isUploading: false, |
| | | // 设置ä¸ä¼ ç请æ±å¤´é¨ |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | // ä¸ä¼ çå°å |
| | | url: import.meta.env.VITE_APP_BASE_API + "/compensationPerformance/importData", |
| | | // æä»¶ä¸ä¼ åçåè° |
| | | beforeUpload: (file) => { |
| | | // å¯ä»¥å¨æ¤å¤åæä»¶ç±»åæå¤§å°æ ¡éª |
| | | const isValid = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.name.endsWith('.xlsx') || file.name.endsWith('.xls'); |
| | | if (!isValid) { |
| | | proxy.$modal.msgError("åªè½ä¸ä¼ Excel æä»¶"); |
| | | } |
| | | return isValid; |
| | | }, |
| | | // æä»¶ç¶ææ¹åæ¶çåè° |
| | | onChange: (file, fileList) => { |
| | | console.log('æä»¶ç¶ææ¹å', file, fileList); |
| | | }, |
| | | // æä»¶ä¸ä¼ æåæ¶çåè° |
| | | onSuccess: (response, file, fileList) => { |
| | | upload.isUploading = false; |
| | | if(response.code === 200){ |
| | | proxy.$modal.msgSuccess("æä»¶ä¸ä¼ æå"); |
| | | handleUploadClose(); |
| | | getList(); |
| | | }else if(response.code === 500){ |
| | | proxy.$modal.msgError(response.msg); |
| | | }else{ |
| | | proxy.$modal.msgWarning(response.msg); |
| | | } |
| | | }, |
| | | // æä»¶ä¸ä¼ 失败æ¶çåè° |
| | | onError: (error, file, fileList) => { |
| | | console.error('ä¸ä¼ 失败', error, file, fileList); |
| | | upload.isUploading = false; |
| | | proxy.$modal.msgError("æä»¶ä¸ä¼ 失败"); |
| | | }, |
| | | // æä»¶ä¸ä¼ è¿åº¦åè° |
| | | onProgress: (event, file, fileList) => { |
| | | console.log('ä¸ä¼ ä¸...', event.percent); |
| | | } |
| | | }); |
| | | |
| | | const handleDateChange = (value,type) => { |
| | | searchForm.value.entryDateEnd = null |
| | |
| | | }); |
| | | }; |
| | | |
| | | /** 导å
¥æé®æä½ */ |
| | | function handleImport() { |
| | | upload.title = "èªèµå¯¼å
¥"; |
| | | upload.open = true; |
| | | } |
| | | |
| | | /** æäº¤ä¸ä¼ æä»¶ */ |
| | | function submitFileForm() { |
| | | upload.isUploading = true; |
| | | proxy.$refs["uploadRef"].submit(); |
| | | } |
| | | |
| | | /** ä¸è½½æ¨¡æ¿ */ |
| | | function importTemplate() { |
| | | proxy.download("/compensationPerformance/exportTemplate", {}, "èªèµå¯¼å
¥æ¨¡æ¿.xlsx"); |
| | | } |
| | | |
| | | // å¤çä¸ä¼ å¼¹æ¡åæ¶ |
| | | function handleUploadCancel() { |
| | | upload.open = false; |
| | | handleUploadClose(); |
| | | } |
| | | |
| | | // å¤çä¸ä¼ å¼¹æ¡å
³é |
| | | function handleUploadClose() { |
| | | upload.open = false; |
| | | upload.isUploading = false; |
| | | // æ¸
空ä¸ä¼ æä»¶ç¼å |
| | | if (proxy.$refs.uploadRef) { |
| | | proxy.$refs.uploadRef.clearFiles(); |
| | | } |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | |
| | | style="width: 150px" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="çæ¬¡ç±»åï¼"> |
| | | <el-select v-model="filterForm.shiftType" placeholder="è¯·éæ©çæ¬¡" clearable style="width: 120px"> |
| | | <el-option v-for="item in shift_type" :label="item.label" :value="item.value" :key="item.value"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="æ¥æèå´ï¼"> |
| | | <el-date-picker |
| | | v-model="filterForm.dateRange" |
| | | type="daterange" |
| | | range-separator="è³" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | style="width: 250px" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="handleFilter"> |
| | | <el-icon><Search/></el-icon> |
| | | çé |
| | | æç´¢ |
| | | </el-button> |
| | | <el-button @click="resetFilter"> |
| | | <el-icon><Refresh/></el-icon> |
| | | éç½® |
| | | </el-button> |
| | | <el-button @click="handleExport"> |
| | | <el-icon><Download/></el-icon> |
| | | å¯¼åº |
| | | </el-button> |
| | | <el-button type="primary" @click="openScheduleDialog('add')"> |
| | |
| | | @selection-change="handleSelectionChange" |
| | | > |
| | | <el-table-column type="selection" width="55"/> |
| | | <el-table-column prop="staffName" label="åå·¥å§å" width="120"/> |
| | | <el-table-column prop="staffNo" label="å工工å·" width="100"/> |
| | | <el-table-column prop="department" label="é¨é¨" width="120"> |
| | | <el-table-column prop="staffName" label="åå·¥å§å"/> |
| | | <!-- <el-table-column prop="staffNo" label="å工工å·" width="100"/> --> |
| | | <!-- <el-table-column prop="department" label="é¨é¨" width="120"> |
| | | <template #default="scope"> |
| | | {{ (department_type.find(i => i.value === String(scope.row.department)) || {}).label }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="shiftType" label="çæ¬¡ç±»å" width="100"> |
| | | </el-table-column> --> |
| | | <el-table-column prop="shiftType" label="çæ¬¡ç±»å" width="120"> |
| | | <template #default="scope"> |
| | | <el-tag :type="getShiftTagType(scope.row.shiftType)"> |
| | | {{ (shift_type.find(i => i.value === String(scope.row.shiftType)) || {}).label }} |
| | | {{ (shift_type.find(i => i.value === String(scope.row.shiftType)) || {}).label || 'æªç¥' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="workDate" label="工使¥æ" width="120"/> |
| | | <el-table-column prop="startTime" label="å¼å§æ¶é´" width="100"/> |
| | | <el-table-column prop="endTime" label="ç»ææ¶é´" width="100"/> |
| | | <el-table-column prop="workHours" label="工使¶é¿" width="100"> |
| | | <!-- <el-table-column prop="workDate" label="工使¥æ" width="120"/> --> |
| | | <el-table-column prop="workStartTime" label="å¼å§æ¶é´"/> |
| | | <el-table-column prop="workEndTime" label="ç»ææ¶é´"/> |
| | | <el-table-column prop="lunchTime" label="å伿¶é´(h)"> |
| | | <template #default="scope"> |
| | | {{ scope.row.lunchTime }}å°æ¶ |
| | | </template> |
| | | </el-table-column> |
| | | <!-- <el-table-column prop="workHours" label="工使¶é¿" width="100"> |
| | | <template #default="scope"> |
| | | {{ scope.row.workHours }}å°æ¶ |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="status" label="ç¶æ" width="100"> |
| | | </el-table-column> --> |
| | | <!-- <el-table-column prop="status" label="ç¶æ" width="100"> |
| | | <template #default="scope"> |
| | | <el-tag :type="getStatusTagType(scope.row.status)"> |
| | | {{ (schedule_status.find(i => i.value === String(scope.row.status)) || {}).label }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="remark" label="夿³¨" min-width="150"/> |
| | | <el-table-column label="æä½" width="200" fixed="right"> |
| | | </el-table-column> --> |
| | | <!-- <el-table-column prop="remark" label="夿³¨" min-width="150"/> --> |
| | | <el-table-column label="æä½" width="200" fixed="right" align="center"> |
| | | <template #default="scope"> |
| | | <el-button |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | @click="openScheduleDialog('edit', scope.row)" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button |
| | | link |
| | | type="danger" |
| | | size="small" |
| | | @click="handleDelete(scope.row)" |
| | | > |
| | | å é¤ |
| | |
| | | label-width="120px" |
| | | > |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åå·¥å§åï¼" prop="staffId"> |
| | | <el-select v-model="scheduleForm.staffId" placeholder="请è¾å
¥åå·¥å§å" style="width: 100%" |
| | | <el-col :span="24"> |
| | | <el-form-item label="åå·¥å§åï¼" prop="staffIds"> |
| | | <el-select v-model="scheduleForm.staffIds" placeholder="è¯·éæ©åå·¥å§å" style="width: 100%" |
| | | multiple filterable collapse-tags-tooltip |
| | | @change="handleSelectStaff"> |
| | | <el-option v-for="item in personList" :label="item.staffName" :value="item.id" :key="item.id"/> |
| | | <el-option v-for="item in personList" :label="item.nickName" :value="item.userId" :key="item.userId"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <!-- <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å工工å·ï¼" prop="staffNo"> |
| | | <el-input :disabled="true" v-model="scheduleForm.staffNo" placeholder=""/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-row> --> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="çæ¬¡ç±»åï¼" prop="shiftType"> |
| | | <el-select v-model="scheduleForm.shiftType" placeholder="è¯·éæ©çæ¬¡ç±»å" style="width: 100%"> |
| | | <el-option v-for="item in shift_type" :label="item.label" :value="item.value" :key="item.value"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <!-- <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é¨é¨ï¼" prop="department"> |
| | | <el-select v-model="scheduleForm.department" placeholder="è¯·éæ©é¨é¨" style="width: 100%"> |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-row> --> |
| | | |
| | | <el-row :gutter="20"> |
| | | <!-- <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="工使¥æï¼" prop="workDate"> |
| | | <el-date-picker |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-row> --> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¼å§æ¶é´ï¼" prop="startTime"> |
| | | <el-form-item label="å¼å§æ¶é´ï¼" prop="workStartTime"> |
| | | <el-time-picker |
| | | v-model="scheduleForm.startTime" |
| | | v-model="scheduleForm.workStartTime" |
| | | placeholder="éæ©å¼å§æ¶é´" |
| | | style="width: 100%" |
| | | format="HH:mm" |
| | | value-format="HH:mm" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»ææ¶é´ï¼" prop="endTime"> |
| | | <el-form-item label="ç»ææ¶é´ï¼" prop="workEndTime"> |
| | | <el-time-picker |
| | | v-model="scheduleForm.endTime" |
| | | v-model="scheduleForm.workEndTime" |
| | | placeholder="éæ©ç»ææ¶é´" |
| | | style="width: 100%" |
| | | format="HH:mm" |
| | | value-format="HH:mm" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å伿¶é´(h)ï¼" prop="lunchTime"> |
| | | <el-input-number |
| | | v-model="scheduleForm.lunchTime" |
| | | :min="0" |
| | | :max="8" |
| | | :step="0.5" |
| | | placeholder="请è¾å
¥å伿¶é´" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <!-- <el-row :gutter="20"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="夿³¨ï¼" prop="remark"> |
| | | <el-input |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-row> --> |
| | | </el-form> |
| | | |
| | | <template #footer> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref, reactive, computed, onMounted, getCurrentInstance} from 'vue' |
| | | import {ref, reactive, computed, onMounted, getCurrentInstance, watch} from 'vue' |
| | | import {ElMessage, ElMessageBox} from 'element-plus' |
| | | import {useDict} from "@/utils/dict.js" |
| | | import {Plus, Download, Search, Refresh} from '@element-plus/icons-vue' |
| | |
| | | import {getStaffOnJob} from "@/api/personnelManagement/onboarding.js"; |
| | | import dayjs from "dayjs"; |
| | | import pagination from "@/components/PIMTable/Pagination.vue"; |
| | | import {listUser} from "@/api/system/user.js"; |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | |
| | |
| | | // çé表å |
| | | const filterForm = reactive({ |
| | | staffName: '', |
| | | shiftType: '', |
| | | dateRange: [], |
| | | current:1, |
| | | size: 10 |
| | | }) |
| | |
| | | // æç表å |
| | | const scheduleForm = reactive({ |
| | | id: '', |
| | | staffId: '', |
| | | staffNo: '', |
| | | department: '', |
| | | staffIds: [], |
| | | // staffNo: '', |
| | | // department: '', |
| | | shiftType: '', |
| | | workDate: '', |
| | | startTime: '', |
| | | endTime: '', |
| | | // workDate: '', |
| | | workStartTime: '', |
| | | workEndTime: '', |
| | | workHours: 0, |
| | | status: '', |
| | | remark: '' |
| | | lunchTime: 3, |
| | | // workStartTime: '', |
| | | // workEndTime: '', |
| | | // workHours: 0, |
| | | // status: '', |
| | | // remark: '' |
| | | }) |
| | | |
| | | // 表åéªè¯è§å |
| | | const scheduleRules = reactive({ |
| | | staffId: [{required: true, message: 'è¯·éæ©åå·¥', trigger: 'change'}], |
| | | department: [{required: true, message: 'è¯·éæ©é¨é¨', trigger: 'change'}], |
| | | staffIds: [{required: true, message: 'è¯·éæ©åå·¥', trigger: 'change'}], |
| | | // department: [{required: true, message: 'è¯·éæ©é¨é¨', trigger: 'change'}], |
| | | shiftType: [{required: true, message: 'è¯·éæ©çæ¬¡ç±»å', trigger: 'change'}], |
| | | workDate: [{required: true, message: 'è¯·éæ©å·¥ä½æ¥æ', trigger: 'change'}], |
| | | startTime: [{required: true, message: 'è¯·éæ©å¼å§æ¶é´', trigger: 'change'}], |
| | | endTime: [{required: true, message: 'è¯·éæ©ç»ææ¶é´', trigger: 'change'}], |
| | | status: [{required: true, message: 'è¯·éæ©ç¶æ', trigger: 'change'}] |
| | | // workDate: [{required: true, message: 'è¯·éæ©å·¥ä½æ¥æ', trigger: 'change'}], |
| | | workStartTime: [{required: true, message: 'è¯·éæ©å¼å§æ¶é´', trigger: 'change'}], |
| | | workEndTime: [{required: true, message: 'è¯·éæ©ç»ææ¶é´', trigger: 'change'}], |
| | | lunchTime: [{required: true, message: '请è¾å
¥å伿¶é´', trigger: 'blur'}], |
| | | // status: [{required: true, message: 'è¯·éæ©ç¶æ', trigger: 'change'}] |
| | | }) |
| | | const tableLoading = ref(false) |
| | | |
| | |
| | | * è·åå½åå¨è人åå表 |
| | | */ |
| | | const getPersonList = () => { |
| | | getStaffOnJob().then(res => { |
| | | personList.value = res.data |
| | | listUser().then(res => { |
| | | personList.value = res.rows |
| | | }) |
| | | }; |
| | | const paginationChange = (obj) => { |
| | |
| | | }; |
| | | |
| | | const handleSelectStaff = (val) => { |
| | | let obj = personList.value.find(item => item.id === val) |
| | | scheduleForm.staffNo = obj.staffNo |
| | | |
| | | // å¤éåå·¥ï¼ä¸åèªå¨è®¾ç½®åå·¥å·¥å· |
| | | // let obj = personList.value.find(item => item.id === val) |
| | | // scheduleForm.staffNo = obj.staffNo |
| | | } |
| | | |
| | | // è·åçæ¬¡æ ç¾ç±»å |
| | |
| | | const handleFilter = async () => { |
| | | tableLoading.value = true |
| | | let searchForm = { |
| | | ...filterForm, |
| | | ...(filterForm.dateRange.length > 0 && { |
| | | startDate: filterForm.dateRange[0], |
| | | endDate: filterForm.dateRange[1], |
| | | }) |
| | | ...filterForm |
| | | } |
| | | let resp = await listPage(searchForm) |
| | | tableCount.value = resp.data.total |
| | | scheduleList.value = resp.data.records.map(it => { |
| | | return { |
| | | ...it, |
| | | 'startTime': dayjs(it.workStartTime).format('HH:mm'), |
| | | 'endTime': dayjs(it.workEndTime).format('HH:mm'), |
| | | // ä¿ååå§æ¶é´æ ¼å¼ç¨äºç¼è¾ |
| | | 'originalWorkStartTime': it.workStartTime, |
| | | 'originalWorkEndTime': it.workEndTime, |
| | | // æ ¼å¼åæ¶é´ç¨äºè¡¨æ ¼æ¾ç¤º |
| | | 'workStartTime': dayjs(it.workStartTime).format('HH:mm'), |
| | | 'workEndTime': dayjs(it.workEndTime).format('HH:mm'), |
| | | } |
| | | }) |
| | | tableLoading.value = false |
| | |
| | | // éç½®çé |
| | | const resetFilter = () => { |
| | | filterForm.staffName = '' |
| | | filterForm.shiftType = '' |
| | | filterForm.dateRange = [] |
| | | } |
| | | |
| | | // æå¼æçå¯¹è¯æ¡ |
| | |
| | | scheduleDialog.value = true |
| | | getPersonList() |
| | | if (type === 'edit' && data) { |
| | | // ç¼è¾æ¨¡å¼ï¼å¤å¶æ°æ® |
| | | Object.assign(scheduleForm, {...data}) |
| | | // ç¼è¾æ¨¡å¼ï¼å¤å¶æ°æ®ï¼å°åå·¥IDå符串转æ¢ä¸ºæ°ç»æ ¼å¼ï¼å¹¶å¤çæ¶é´å段 |
| | | Object.assign(scheduleForm, { |
| | | ...data, |
| | | lunchTime: Number(data.lunchTime), |
| | | staffIds: data.staffId ? data.staffId.split(',').map(id => parseInt(id)) : [], |
| | | // 使ç¨åå§æ¶é´å符串ï¼å ä¸ºè¡¨æ ¼ä¸æ¾ç¤ºçæ¯æ ¼å¼ååçHH:mm |
| | | workStartTime: data.originalWorkStartTime || '', |
| | | workEndTime: data.originalWorkEndTime || '' |
| | | }) |
| | | } else { |
| | | // æ°å¢æ¨¡å¼ï¼é置表å |
| | | Object.keys(scheduleForm).forEach(key => { |
| | | if (key === 'staffIds') { |
| | | scheduleForm[key] = [] |
| | | } else if (key === 'lunchTime') { |
| | | scheduleForm[key] = 3 |
| | | } else { |
| | | scheduleForm[key] = '' |
| | | } |
| | | }) |
| | | // scheduleForm.status = '已宿' |
| | | scheduleForm.workDate = new Date().toISOString().split('T')[0] |
| | | // scheduleForm.workDate = new Date().toISOString().split('T')[0] |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | // 计ç®å·¥ä½æ¶é¿ |
| | | const calculateWorkHours = () => { |
| | | if (scheduleForm.workDate && scheduleForm.startTime && scheduleForm.endTime) { |
| | | // ä½¿ç¨ workDate ä¸ startTime å endTime ç»å |
| | | const startDateTime = new Date(`${scheduleForm.workDate} ${scheduleForm.startTime}`) |
| | | const endDateTime = new Date(`${scheduleForm.workDate} ${scheduleForm.endTime}`) |
| | | if (!scheduleForm.workStartTime || !scheduleForm.workEndTime) { |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | // 使ç¨dayjsæ£ç¡®è§£ææ¶é´ |
| | | const startDayjs = dayjs(scheduleForm.workStartTime); |
| | | const endDayjs = dayjs(scheduleForm.workEndTime); |
| | | |
| | | if (!startDayjs.isValid() || !endDayjs.isValid()) { |
| | | return; |
| | | } |
| | | |
| | | const startDateTime = startDayjs.toDate(); |
| | | const endDateTime = endDayjs.toDate(); |
| | | |
| | | // å¤ç跨天æ
åµï¼ç»ææ¶é´æ©äºå¼å§æ¶é´ï¼ |
| | | if (endDateTime < startDateTime) { |
| | | // 跨天ï¼å°ç»ææ¥æå ä¸å¤© |
| | | endDateTime.setDate(endDateTime.getDate() + 1) |
| | | endDateTime.setDate(endDateTime.getDate() + 1); |
| | | } |
| | | // 计ç®å·¥ä½æ¶é¿ï¼å°æ¶ï¼ |
| | | const diffMs = endDateTime - startDateTime |
| | | const diffHours = diffMs / (1000 * 60 * 60) |
| | | scheduleForm.workHours = Math.round(diffHours * 100) / 100 |
| | | scheduleForm.workStartTime = dayjs(startDateTime).format("YYYY-MM-DD HH:mm:ss") |
| | | scheduleForm.workEndTime = dayjs(endDateTime).format("YYYY-MM-DD HH:mm:ss") |
| | | |
| | | // 计ç®å·¥ä½æ¶é¿ï¼å°æ¶ï¼ |
| | | const diffMs = endDateTime - startDateTime; |
| | | const diffHours = diffMs / (1000 * 60 * 60); |
| | | scheduleForm.workHours = Math.round(diffHours * 100) / 100; |
| | | } catch (error) { |
| | | console.error('æ¶é´è®¡ç®é误:', error); |
| | | } |
| | | } |
| | | |
| | | // ç嬿¶é´å段ååï¼èªå¨è®¡ç®å·¥ä½æ¶é¿ |
| | | watch( |
| | | () => [scheduleForm.workStartTime, scheduleForm.workEndTime], |
| | | () => { |
| | | calculateWorkHours() |
| | | }, |
| | | { deep: true } |
| | | ) |
| | | |
| | | // æäº¤æç表å |
| | | const submitScheduleForm = async () => { |
| | | const valid = await scheduleFormRef.value.validate() |
| | | if (!valid) return |
| | | |
| | | calculateWorkHours() |
| | | const newSchedule = {...scheduleForm} |
| | | // ç±äºåå·¥æ¯å¤éï¼éè¦ä¸ºæ¯ä¸ªéä¸çåå·¥å建æçè®°å½ |
| | | const selectedStaffIds = scheduleForm.staffIds || [] |
| | | |
| | | if (selectedStaffIds.length === 0) { |
| | | ElMessage.warning('请è³å°éæ©ä¸ä¸ªåå·¥') |
| | | return |
| | | } |
| | | |
| | | try { |
| | | // è·åéä¸çåå·¥å§åå表 |
| | | const selectedStaffNames = selectedStaffIds.map(staffId => { |
| | | const staff = personList.value.find(item => item.userId === staffId) |
| | | return staff ? staff.nickName : '' |
| | | }).filter(name => name !== '') |
| | | |
| | | // å°åå·¥å§åç»è£
æéå·åéçå符串 |
| | | const staffNameString = selectedStaffNames.join(',') |
| | | |
| | | // å建æçè®°å½ï¼å°åå·¥å§åä¿å为åç¬¦ä¸²æ ¼å¼ |
| | | const newSchedule = { |
| | | ...scheduleForm, |
| | | staffName: staffNameString, |
| | | staffId: selectedStaffIds.join(','), // å°åå·¥IDä¹ä¿å为éå·åéçå符串 |
| | | // 设置å
¶ä»å¿
è¦å段çé»è®¤å¼ |
| | | staffNo: '', // å¯ä»¥æ ¹æ®éè¦ä»personListä¸è·å |
| | | department: '', |
| | | shiftType: scheduleForm.shiftType, |
| | | workDate: '', |
| | | status: '', |
| | | remark: '' |
| | | } |
| | | |
| | | await save(newSchedule) |
| | | ElMessage.success('ä¿åæçæå') |
| | | |
| | | ElMessage.success(`æå为 ${selectedStaffNames.length} 个åå·¥å建æç`) |
| | | |
| | | handleFilter() |
| | | closeScheduleDialog() |
| | |
| | | // å¯¼åº |
| | | const handleExport = () => { |
| | | let searchForm = { |
| | | ...filterForm, |
| | | ...(filterForm.dateRange.length > 0 && { |
| | | startDate: filterForm.dateRange[0], |
| | | endDate: filterForm.dateRange[1], |
| | | }) |
| | | ...filterForm |
| | | } |
| | | proxy.download('/staff/staffScheduling/export', {}, '人åæç.xlsx') |
| | | } |
| | |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éè´ååå·ï¼" prop="purchaseLedgerNo"> |
| | | <el-input v-model="form.purchaseLedgerNo" disabled /> |
| | | <el-input v-model="form.purchaseLedgerNo" disabled placeholder="å¤ååæ¹éå¤çï¼å
·ä½ååå·è§äº§åå表ï¼" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="项ç®åç§°ï¼" prop="projectName"> |
| | | <el-input |
| | | v-model="form.projectName" |
| | | placeholder="èªå¨å¡«å
" |
| | | clearable |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <!-- <el-col :span="12">--> |
| | | <!-- <el-form-item label="项ç®åç§°ï¼" prop="projectName">--> |
| | | <!-- <el-input--> |
| | | <!-- v-model="form.projectName"--> |
| | | <!-- placeholder="èªå¨å¡«å
"--> |
| | | <!-- clearable--> |
| | | <!-- disabled--> |
| | | <!-- />--> |
| | | <!-- </el-form-item>--> |
| | | <!-- </el-col>--> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å票å·ï¼" prop="invoiceNumber"> |
| | | <el-input |
| | |
| | | <el-form-item label="å票éé¢(å
)ï¼" prop="invoiceAmount"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" |
| | | v-model="form.invoiceAmount" |
| | | placeholder="èªå¨å¡«å
" |
| | | placeholder="请è¾å
¥å票éé¢" |
| | | clearable |
| | | :disabled="true" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å½å
¥æ¥æï¼" prop="enterDate"> |
| | | <el-date-picker |
| | | style="width: 100%" |
| | | v-model="form.enterDate" |
| | | type="date" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¸ä¼ éä»¶"> |
| | | <FileUpload |
| | | :showTip="false" |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å½å
¥æ¥æï¼" prop="enterDate"> |
| | | <el-date-picker |
| | | style="width: 100%" |
| | | v-model="form.enterDate" |
| | | type="date" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | |
| | | </el-row> |
| | | <el-form-item label="产åä¿¡æ¯ï¼"> </el-form-item> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="columns" |
| | | :tableData="form.productData" |
| | | :summaryMethod="summarizeChildrenTable" |
| | | :isShowSummary="true" |
| | | height="auto" |
| | | <el-table |
| | | :data="form.productData" |
| | | border |
| | | show-summary |
| | | :summary-method="summarizeChildrenTable" |
| | | > |
| | | <template #ticketsNumRef="{ row }"> |
| | | <el-input-number |
| | | v-model="row.ticketsNum" |
| | | placeholder="请è¾å
¥" |
| | | :min="0" |
| | | :step="0.1" |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column label="æå±åå" prop="purchaseLedgerNo" width="200"> |
| | | <template #default="{ row }"> |
| | | <el-tag type="primary">{{ row.purchaseLedgerNo }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="产å大类" prop="productCategory" /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" width="150" /> |
| | | <el-table-column label="åä½" prop="unit" width="70" /> |
| | | <el-table-column label="æ°é" prop="quantity" width="70" /> |
| | | <el-table-column label="ç¨ç(%)" prop="taxRate" width="80" /> |
| | | <el-table-column |
| | | label="å«ç¨åä»·(å
)" |
| | | prop="taxInclusiveUnitPrice" |
| | | :formatter="formattedNumber" |
| | | /> |
| | | <el-table-column |
| | | label="å«ç¨æ»ä»·(å
)" |
| | | prop="taxInclusiveTotalPrice" |
| | | :formatter="formattedNumber" |
| | | /> |
| | | <el-table-column |
| | | label="ä¸å«ç¨æ»ä»·(å
)" |
| | | prop="taxExclusiveTotalPrice" |
| | | :formatter="formattedNumber" |
| | | /> |
| | | <el-table-column label="æ¬æ¬¡å¼ç¥¨æ°" prop="ticketsNum" width="180"> |
| | | <template #default="scope"> |
| | | <el-input-number :step="0.1" :min="0" style="width: 100%" |
| | | :precision="2" |
| | | clearable |
| | | style="width: 100%" |
| | | @change="invoiceNumBlur(row)" |
| | | v-model="scope.row.ticketsNum" |
| | | @change="invoiceNumBlur(scope.row)" |
| | | /> |
| | | </template> |
| | | <template #ticketsAmountRef="{ row }"> |
| | | <el-input-number |
| | | v-model="row.ticketsAmount" |
| | | placeholder="请è¾å
¥" |
| | | :min="0" |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æ¬æ¬¡å¼ç¥¨éé¢(å
)" |
| | | prop="ticketsAmount" |
| | | width="180" |
| | | > |
| | | <template #default="scope"> |
| | | <el-input-number :step="0.01" :min="0" style="width: 100%" |
| | | :precision="2" |
| | | :step="0.1" |
| | | clearable |
| | | style="width: 100%" |
| | | @change="invoiceAmountBlur(row)" |
| | | v-model="scope.row.ticketsAmount" |
| | | @change="invoiceAmountBlur(scope.row)" |
| | | /> |
| | | </template> |
| | | </PIMTable> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æªæ¥ç¥¨æ°" |
| | | prop="futureTickets" |
| | | :formatter="formattedNumber" |
| | | /> |
| | | <el-table-column |
| | | label="æ¬æ¬¡æ¥ç¥¨éé¢(å
)" |
| | | prop="ticketsAmount" |
| | | :formatter="formattedNumber" |
| | | /> |
| | | <el-table-column |
| | | label="æªæ¥ç¥¨æ°" |
| | | prop="futureTickets" |
| | | :formatter="formattedNumber" |
| | | /> |
| | | <el-table-column |
| | | label="æªæ¥ç¥¨éé¢(å
)" |
| | | prop="futureTicketsAmount" |
| | | :formatter="formattedNumber" |
| | | /> |
| | | </el-table> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button type="primary" :loading="modalLoading" @click="submitForm"> |
| | | {{ modalOptions.confirmText }} |
| | | 确认 |
| | | </el-button> |
| | | <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button> |
| | | <el-button @click="closeModal">åæ¶</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | |
| | | productData: [], // è¡¨æ ¼ |
| | | tempFileIds: [], // æä»¶ |
| | | }); |
| | | |
| | | const selectedContracts = ref([]); // åå¨éä¸çååæ°æ® |
| | | |
| | | const rules = ref({ |
| | | invoiceNumber: [ |
| | |
| | | width: 200, |
| | | }, |
| | | ]; |
| | | |
| | | const getTableData = async (type, id) => { |
| | | const formattedNumber = (row, column, cellValue) => { |
| | | if (cellValue == 0) { |
| | | return parseFloat(cellValue).toFixed(2); |
| | | } |
| | | if (cellValue) { |
| | | return parseFloat(cellValue).toFixed(2); |
| | | } else { |
| | | return cellValue; |
| | | } |
| | | }; |
| | | const getTableData = async (type, selectedRows) => { |
| | | if (type == "add") { |
| | | const { data } = await getPurchaseNoById({ id }); |
| | | form.purchaseLedgerNo = data.purchaseContractNumber; |
| | | form.invoiceAmount = data.invoiceAmount; |
| | | form.invoiceNumber = data.invoiceNumber; |
| | | form.entryDate = data.entryDate; |
| | | form.salesContractNoId = data.salesContractNoId; |
| | | // æ£æ¥ææéæ©çå忝å¦å
·æç¸åçä¾åºååç§° |
| | | const firstRow = selectedRows[0]; |
| | | const isSameSupplier = selectedRows.every(row => |
| | | row.supplierName === firstRow.supplierName |
| | | ); |
| | | |
| | | const { data: infoData } = await getInfo({ id }); |
| | | form.salesContractNo = infoData.salesContractNo; |
| | | form.projectName = infoData.projectName; |
| | | form.supplierName = infoData.supplierName; |
| | | form.productData = infoData.productData; |
| | | if (!isSameSupplier) { |
| | | proxy.$modal.msgError("è¯·éæ©ç¸åä¾åºååç§°çåå"); |
| | | return; |
| | | } |
| | | |
| | | // å
许ä¸åçéè´ååå·æ¹éå¤çï¼æ 鿣æ¥éå¤ |
| | | |
| | | // æ¸
ç©ºè¡¨åæ°æ® |
| | | Object.keys(form).forEach(key => { |
| | | if (key !== 'productData') { |
| | | form[key] = undefined; |
| | | } |
| | | }); |
| | | form.productData = []; |
| | | |
| | | // å è½½ææéä¸ååçäº§åæ°æ® |
| | | const promises = selectedRows.map(row => |
| | | getInfo({ id: row.id }) |
| | | ); |
| | | |
| | | Promise.all(promises).then(results => { |
| | | // åå¹¶ææååçäº§åæ°æ®ï¼å¹¶ä¸ºæ¯ä¸ªäº§åæ·»å 对åºçååä¿¡æ¯ |
| | | const allProductData = []; |
| | | results.forEach((result, index) => { |
| | | const contract = selectedRows[index]; |
| | | const contractId = contract.id; |
| | | if (result.data && result.data.productData) { |
| | | result.data.productData.forEach(item => { |
| | | allProductData.push({ |
| | | ...item, |
| | | id: contractId, // æç¡®è®¾ç½®ååID |
| | | purchaseLedgerNo: contract.purchaseContractNumber, // æ·»å éè´ååå· |
| | | supplierName: contract.supplierName, // æ·»å ä¾åºååç§° |
| | | projectName: contract.projectName // æ·»å 项ç®åç§° |
| | | }); |
| | | }); |
| | | } |
| | | }); |
| | | |
| | | // è®¾ç½®è¡¨åæ°æ®ï¼ä½¿ç¨ç¬¬ä¸ä¸ªååçåºæ¬ä¿¡æ¯ï¼éè´ååå·çç©ºï¼ |
| | | form.purchaseLedgerNo = ""; // éè´ååå·ç空ï¼å 为ä¼å¨äº§åè¡¨æ ¼ä¸å嫿¾ç¤º |
| | | form.invoiceAmount = 0; |
| | | form.invoiceNumber = ""; |
| | | form.entryDate = dayjs().format("YYYY-MM-DD"); |
| | | form.enterDate = dayjs().format("YYYY-MM-DD"); |
| | | form.salesContractNo = results[0].data.salesContractNo; |
| | | form.projectName = results[0].data.projectName; |
| | | form.supplierName = results[0].data.supplierName; |
| | | // ä¿çå½å
¥äººä¿¡æ¯ |
| | | form.issUerId = userStore.id; |
| | | form.issUer = userStore.nickName; |
| | | |
| | | form.productData = allProductData; |
| | | |
| | | // åå¨éä¸çååæ°æ® |
| | | selectedContracts.value = selectedRows; |
| | | }); |
| | | } else if (type == "edit") { |
| | | const id = Array.isArray(selectedRows) ? selectedRows[0].id : selectedRows; |
| | | const data = await getPurchaseById({ id, type: 2 }); |
| | | form.purchaseLedgerNo = data.purchaseContractNumber; |
| | | form.invoiceAmount = data.invoiceAmount; |
| | |
| | | form.invoiceAmount = invoiceAmountTotal.toFixed(2); |
| | | }; |
| | | |
| | | const open = (type, eid) => { |
| | | openModal(); |
| | | getTableData(type, eid); |
| | | id.value = eid; |
| | | const open = async (type, selectedRows) => { |
| | | visible.value = true; |
| | | |
| | | // å¦ææ¯æ¹éæä½ï¼è®¾ç½®æ é¢ |
| | | if (Array.isArray(selectedRows) && selectedRows.length > 1) { |
| | | modalOptions.title = `æ¹éæ°å¢ (${selectedRows.length}æ¡)`; |
| | | } else { |
| | | modalOptions.title = type == "add" ? "æ°å¢" : "ç¼è¾"; |
| | | } |
| | | |
| | | // 妿æ¯å个æä½ï¼è·åid |
| | | if (!Array.isArray(selectedRows) || selectedRows.length === 1) { |
| | | const idValue = Array.isArray(selectedRows) ? selectedRows[0].id : selectedRows; |
| | | id.value = idValue; |
| | | } |
| | | |
| | | await getTableData(type, selectedRows); |
| | | }; |
| | | |
| | | const uploadSuccess = (response) => { |
| | |
| | | }; |
| | | |
| | | const submitForm = () => { |
| | | formRef.value.validate(async (valid, fields) => { |
| | | proxy.$refs["formRef"].validate((valid) => { |
| | | if (valid) { |
| | | // modalLoading.value = true; |
| | | const { code } = await addOrUpdateRegistration({ |
| | | purchaseLedgerId: id.value, |
| | | purchaseContractNumber: form.purchaseLedgerNo, |
| | | // å¦ææ¯æ¹éæä½ï¼å°ææååçæ°æ®æ¾å¨ä¸ä¸ªæ°ç»éï¼åªè°ç¨ä¸æ¬¡æ¥å£ |
| | | if (selectedContracts.value.length > 1) { |
| | | // å建å
嫿æååæ°æ®çæ°ç» |
| | | const batchData = selectedContracts.value.map(contract => { |
| | | // çéåºå±äºå½åååçäº§åæ°æ® |
| | | const contractProductData = form.productData.filter(item => |
| | | item.id === contract.id |
| | | ); |
| | | |
| | | // 为æ¯ä¸ªéè´ååå建ç¬ç«ç对象 |
| | | return { |
| | | // åºç¡è¡¨åæ°æ® |
| | | invoiceNumber: form.invoiceNumber, |
| | | invoiceAmount: form.invoiceAmount, |
| | | salesContractNo: form.salesContractNo, |
| | | projectName: form.projectName, |
| | | productData: form.productData, |
| | | issueDate: form.entryDate, |
| | | entryDate: form.entryDate, |
| | | enterDate: form.enterDate, |
| | | issUerId: form.issUerId, // å½å
¥äººid |
| | | issUer: form.issUer, // å½å
¥äºº |
| | | salesContractNoId: form.salesContractNoId, |
| | | supplierName: form.supplierName, |
| | | tempFileIds: form.tempFileIds, |
| | | enterDate: form.enterDate, |
| | | type: 4, |
| | | |
| | | // ååå®é
ä¿¡æ¯ |
| | | purchaseLedgerId: contract.id, // 使ç¨idä½ä¸ºå段åï¼å¼ä¸ºpurchaseLedgerId |
| | | purchaseContractNumber: contract.purchaseContractNumber, // 使ç¨å®é
çéè´ååå· |
| | | salesContractNo: contract.salesContractNo, // 使ç¨å®é
çéå®ååå· |
| | | supplierName: contract.supplierName, // 使ç¨å®é
çä¾åºååç§° |
| | | projectName: contract.projectName, // 使ç¨å®é
ç项ç®åç§° |
| | | |
| | | // äº§åæ°æ® |
| | | productData: proxy.HaveJson(contractProductData), |
| | | |
| | | // æ¹éæ è¯ |
| | | isBatch: true, |
| | | type: 4 |
| | | }; |
| | | }); |
| | | |
| | | // åªè°ç¨ä¸æ¬¡æ¥å£ï¼ä¼ éå
嫿æååæ°æ®çæ°ç» |
| | | modalLoading.value = true; |
| | | addOrUpdateRegistration(batchData).then((res) => { |
| | | modalLoading.value = false; |
| | | if (code == 200) { |
| | | if (res.code === 200) { |
| | | proxy.$modal.msgSuccess("æ¹éç»è®°æå"); |
| | | closeAndRefresh(); |
| | | } |
| | | } else { |
| | | }).catch(() => { |
| | | modalLoading.value = false; |
| | | proxy.$modal.msgError("æ¹éç»è®°å¤±è´¥"); |
| | | }); |
| | | } else { |
| | | // å个ååæäº¤é»è¾ - 以æ°ç»æ ¼å¼ä¼ é |
| | | const singleContract = selectedContracts.value[0]; |
| | | const singleFormArray = [{ |
| | | // åºç¡è¡¨åæ°æ® |
| | | invoiceNumber: form.invoiceNumber, |
| | | invoiceAmount: form.invoiceAmount, |
| | | entryDate: form.entryDate, |
| | | enterDate: form.enterDate, |
| | | issUerId: form.issUerId, // å½å
¥äººid |
| | | issUer: form.issUer, // å½å
¥äºº |
| | | tempFileIds: form.tempFileIds, |
| | | |
| | | // ååå®é
ä¿¡æ¯ |
| | | purchaseLedgerId: singleContract.id, // 使ç¨idä½ä¸ºå段åï¼å¼ä¸ºpurchaseLedgerId |
| | | purchaseContractNumber: singleContract.purchaseContractNumber, // 使ç¨å®é
çéè´ååå· |
| | | salesContractNo: singleContract.salesContractNo, // 使ç¨å®é
çéå®ååå· |
| | | supplierName: singleContract.supplierName, // 使ç¨å®é
çä¾åºååç§° |
| | | projectName: singleContract.projectName, // 使ç¨å®é
ç项ç®åç§° |
| | | |
| | | // äº§åæ°æ® |
| | | productData: proxy.HaveJson(form.productData), |
| | | |
| | | // æ¹éæ è¯ |
| | | isBatch: false, |
| | | type: 4 |
| | | }]; |
| | | |
| | | modalLoading.value = true; |
| | | addOrUpdateRegistration(singleFormArray).then((res) => { |
| | | modalLoading.value = false; |
| | | if (res.code === 200) { |
| | | proxy.$modal.msgSuccess("ç»è®°æå"); |
| | | closeAndRefresh(); |
| | | } |
| | | }).catch(() => { |
| | | modalLoading.value = false; |
| | | proxy.$modal.msgError("ç»è®°å¤±è´¥"); |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="项ç®åç§°"> |
| | | <el-input |
| | | v-model="filters.projectName" |
| | | placeholder="请è¾å
¥é¡¹ç®åç§°" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="getTableData"> æç´¢ </el-button> |
| | | <el-button @click="resetFilters"> éç½® </el-button> |
| | |
| | | width:300 |
| | | }, |
| | | { |
| | | label: "项ç®åç§°", |
| | | prop: "projectName", |
| | | width:400 |
| | | }, |
| | | { |
| | | label: "å½å
¥äºº", |
| | | prop: "recorderName", |
| | | }, |
| | |
| | | }; |
| | | |
| | | const handleAdd = (type) => { |
| | | if (selectedRows.value.length !== 1) { |
| | | proxy.$modal.msgWarning("请å
éä¸ä¸æ¡æ°æ®"); |
| | | if (selectedRows.value.length < 1) { |
| | | proxy.$modal.msgWarning("请è³å°éä¸ä¸æ¡æ°æ®"); |
| | | return; |
| | | } |
| | | modalRef.value.open(type, selectedRows.value[0].id); |
| | | modalRef.value.open(type, selectedRows.value); |
| | | }; |
| | | |
| | | const handleEdit = (type, id) => { |
| | |
| | | size="small" |
| | | @click="changeEditType(scope.row)" |
| | | v-if="!scope.row.editType" |
| | | :disabled="scope.row.registrant !== userStore.nickName" |
| | | >ç¼è¾</el-button |
| | | > |
| | | <el-button |
| | |
| | | size="small" |
| | | @click="saveReceiptPayment(scope.row)" |
| | | v-if="scope.row.editType" |
| | | :disabled="scope.row.registrant !== userStore.nickName" |
| | | >ä¿å</el-button |
| | | > |
| | | <el-button |
| | |
| | | type="primary" |
| | | size="small" |
| | | @click="handleDelete(scope.row)" |
| | | :disabled="scope.row.registrant !== userStore.nickName" |
| | | >å é¤</el-button |
| | | > |
| | | </template> |
| | |
| | | v-model="form.registrant" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | const { form: searchForm } = useFormData({ |
| | | searchText: undefined, |
| | | purchaseContractNumber: undefined, |
| | | paymentDate: [], |
| | | paymentDateStart: undefined, |
| | | paymentDateEnd: undefined, |
| | | // è®¾ç½®ä»æ¬¾æ¥æèå´ä¸ºå½å¤© |
| | | paymentDate: [dayjs().startOf('day').format('YYYY-MM-DD'), dayjs().endOf('day').format('YYYY-MM-DD')], |
| | | paymentDateStart: dayjs().startOf('day').format('YYYY-MM-DD'), |
| | | paymentDateEnd: dayjs().endOf('day').format('YYYY-MM-DD'), |
| | | }); |
| | | |
| | | // æ¥è¯¢å表 |
| | |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | const { paymentDate, ...rest } = searchForm; |
| | | paymentHistoryListPage({ ...rest, ...page }).then((res) => { |
| | | const { total, ...pageParams } = page; |
| | | paymentHistoryListPage({ ...rest, ...pageParams }).then((res) => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.records; |
| | | page.total = res.total; |
| | |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å票å·ï¼"> |
| | | <el-input disabled v-model="form.invoiceNumber" /> |
| | | <el-input v-model="form.invoiceNumber" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | |
| | | ticketsNum: undefined, // æ¥ç¥¨æ° |
| | | ticketsAmount: undefined, // æ¥ç¥¨éé¢ |
| | | taxInclusiveUnitPrice: undefined, // å«ç¨åä»· |
| | | ticketRegistrationId: undefined, // å«ç¨åä»· |
| | | }); |
| | | |
| | | const load = async (id) => { |
| | |
| | | form.taxInclusiveUnitPrice = data.taxInclusiveUnitPrice; |
| | | form.futureTickets = data.futureTickets; |
| | | temFutureTickets.value = data.futureTickets; |
| | | form.ticketRegistrationId = data.ticketRegistrationId; |
| | | } |
| | | }; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog v-model="dialogVisible" title="éä»¶" width="50%" :before-close="handleClose"> |
| | | <el-table :data="tableData" border height="40vh"> |
| | | <el-table-column label="éä»¶åç§°" prop="name" min-width="400" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="æä½" width="200" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">ä¸è½½</el-button> |
| | | <el-button link type="primary" size="small" @click="lookFile(scope.row)">é¢è§</el-button> |
| | | <el-button link type="danger" size="small" @click="handleDelete(scope.row)">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-dialog> |
| | | <filePreview ref="filePreviewRef" /> |
| | | <UploadModal ref="uploadModalRef" @uploadSuccess="handleUploadSuccess" /> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref } from 'vue' |
| | | import { ElMessageBox, ElMessage } from 'element-plus' |
| | | import filePreview from '@/components/filePreview/index.vue' |
| | | import UploadModal from './Modal/UploadModal.vue' |
| | | import { delCommonFileInvoiceLedger} from '@/api/publicApi/commonFile.js' |
| | | |
| | | const dialogVisible = ref(false) |
| | | const tableData = ref([]) |
| | | const currentId = ref('') |
| | | const { proxy } = getCurrentInstance(); |
| | | const filePreviewRef = ref() |
| | | const uploadModalRef = ref() |
| | | |
| | | const handleClose = () => { |
| | | dialogVisible.value = false |
| | | } |
| | | |
| | | const open = (list, id = '') => { |
| | | dialogVisible.value = true |
| | | tableData.value = list |
| | | currentId.value = id |
| | | } |
| | | |
| | | const handleUpload = () => { |
| | | if (!currentId.value) { |
| | | ElMessage.warning('æ æ³è·åå½åè®°å½IDï¼è¯·å
³éåéæ°æå¼éä»¶çªå£') |
| | | return |
| | | } |
| | | uploadModalRef.value.handleImport(currentId.value) |
| | | } |
| | | |
| | | const handleUploadSuccess = (data) => { |
| | | ElMessage.success('ä¸ä¼ æå') |
| | | // è¿éå¯ä»¥æ·»å å·æ°éä»¶å表çé»è¾ |
| | | // ææ¶å
å
³éä¸ä¼ æ¨¡ææ¡ |
| | | } |
| | | |
| | | const downLoadFile = (row) => { |
| | | proxy.$download.name(row.url); |
| | | } |
| | | |
| | | const lookFile = (row) => { |
| | | filePreviewRef.value.open(row.url) |
| | | } |
| | | |
| | | // å é¤éä»¶ |
| | | const handleDelete = (row) => { |
| | | ElMessageBox.confirm(`确认å é¤éä»¶"${row.name}"åï¼`, 'å é¤ç¡®è®¤', { |
| | | confirmButtonText: '确认', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning', |
| | | }).then(() => { |
| | | delCommonFileInvoiceLedger([row.id]).then(() => { |
| | | ElMessage.success('å 餿å') |
| | | // ä»å表ä¸ç§»é¤å·²å é¤çéä»¶ |
| | | const index = tableData.value.findIndex(item => item.id === row.id) |
| | | if (index !== -1) { |
| | | tableData.value.splice(index, 1) |
| | | } |
| | | }).catch(() => { |
| | | ElMessage.error('å é¤å¤±è´¥') |
| | | }) |
| | | }).catch(() => { |
| | | proxy.$modal.msg('已忶å é¤') |
| | | }) |
| | | } |
| | | |
| | | defineExpose({ |
| | | open |
| | | }) |
| | | </script> |
| | | |
| | | <style></style> |
| | |
| | | <el-button link :icon="Files" type="danger"> éä»¶ </el-button> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item |
| | | v-if="row.commonFiles.length !== 0" |
| | | :icon="Download" |
| | | command="download" |
| | | > |
| | | ä¸è½½ |
| | | </el-dropdown-item> |
| | | <el-dropdown-item :icon="Upload" command="upload"> |
| | | ä¸ä¼ |
| | | </el-dropdown-item> |
| | |
| | | <template #operation="{ row }"> |
| | | <el-button |
| | | type="primary" |
| | | text |
| | | link |
| | | @click="openEdit(row)" |
| | | :disabled="row.issUerId !== userStore.id" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button link type="primary" size="small" @click="downLoadFile(row)">éä»¶</el-button> |
| | | <el-button |
| | | type="primary" |
| | | text |
| | | :disabled="row.issUerId !== userStore.id" |
| | | link |
| | | @click="handleDelete(row)" |
| | | > |
| | | å é¤ |
| | |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | <FileList ref="fileListRef" /> |
| | | <UploadModal ref="modalRef" @uploadSuccess="uploadSuccess"></UploadModal> |
| | | <EditModal ref="editmodalRef" @success="getTableData"></EditModal> |
| | | </div> |
| | |
| | | Search, |
| | | Upload, |
| | | EditPen, |
| | | Delete, |
| | | } from "@element-plus/icons-vue"; |
| | | import { |
| | | delRegistration, |
| | | productRecordPage, |
| | | productUploadFile, |
| | | } from "@/api/procurementManagement/procurementInvoiceLedger.js"; |
| | | import { delCommonFile } from "@/api/publicApi/commonFile.js"; |
| | | import { onMounted } from "vue"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { ElMessageBox, ElMessage } from "element-plus"; |
| | | import UploadModal from "./Modal/UploadModal.vue"; |
| | | import EditModal from "./Modal/EditModal.vue"; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import {delInvoiceLedgerByRegProductId} from "@/api/salesManagement/invoiceLedger.js"; |
| | | const userStore = useUserStore(); |
| | | import dayjs from "dayjs"; |
| | | import FileList from "./fileList.vue"; |
| | | |
| | | defineOptions({ |
| | | name: "æ¥ç¥¨å°è´¦", |
| | |
| | | { |
| | | purchaseContractNumber: undefined, // éè´ååå· |
| | | supplierName: undefined, // ä¾åºå |
| | | createdAt: [], // æ¥ç¥¨æ¥æ |
| | | // 设置æ¥ç¥¨æ¥æèå´ä¸ºå½å¤© |
| | | createdAt: [dayjs().startOf('day').format('YYYY-MM-DD'), dayjs().endOf('day').format('YYYY-MM-DD')], // æ¥ç¥¨æ¥æ |
| | | }, |
| | | [ |
| | | { |
| | |
| | | label: "éå®ååå·", |
| | | prop: "salesContractNo", |
| | | width: 150, |
| | | }, |
| | | { |
| | | label: "项ç®åç§°", |
| | | prop: "projectName", |
| | | width: 240, |
| | | }, |
| | | { |
| | | label: "ä¾åºååç§°", |
| | |
| | | }, |
| | | { |
| | | fixed: "right", |
| | | width: 150, |
| | | width: 190, |
| | | label: "æä½", |
| | | dataType: "slot", |
| | | slot: "operation", |
| | |
| | | const handleSelectionChange = (val) => { |
| | | multipleVal.value = val; |
| | | }; |
| | | |
| | | //éä»¶ç¸å
³ |
| | | const fileListRef = ref(null) |
| | | //æ¥çéä»¶ |
| | | const downLoadFile = (row) => { |
| | | fileListRef.value.open(row.commonFiles, row.id) |
| | | } |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | |
| | | console.log(row.commonFiles); |
| | | openUoload(row.ticketRegistrationId); |
| | | break; |
| | | case "delete": |
| | | // å 餿æéä»¶ |
| | | if (row.commonFiles.length > 0) { |
| | | ElMessageBox.confirm(`确认å é¤è¯¥è®°å½çææéä»¶åï¼`, 'æç¤º', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | // è·åææéä»¶çID |
| | | const fileIds = row.commonFiles.map(file => file.id); |
| | | |
| | | delCommonFile(fileIds).then(() => { |
| | | ElMessage.success('å 餿å') |
| | | // å·æ°æ°æ® |
| | | getTableData(); |
| | | }).catch(() => { |
| | | ElMessage.error('å é¤å¤±è´¥') |
| | | }) |
| | | }).catch(() => { |
| | | ElMessage.info('已忶å é¤') |
| | | }) |
| | | } |
| | | break; |
| | | } |
| | | }; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog v-model="dialogVisible" title="éä»¶" width="40%" :before-close="handleClose"> |
| | | <el-table :data="tableData" border height="40vh"> |
| | | <el-table-column label="éä»¶åç§°" prop="name" min-width="400" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="æä½" width="150" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">ä¸è½½</el-button> |
| | | <el-button link type="primary" size="small" @click="lookFile(scope.row)">é¢è§</el-button> |
| | | <el-button link type="danger" size="small" @click="handleDelete(scope.row)">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-dialog> |
| | | <filePreview ref="filePreviewRef" /> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref } from 'vue' |
| | | import { ElMessageBox, ElMessage } from 'element-plus' |
| | | import filePreview from '@/components/filePreview/index.vue' |
| | | import { delCommonFile } from '@/api/publicApi/commonFile.js' |
| | | |
| | | const dialogVisible = ref(false) |
| | | const tableData = ref([]) |
| | | const { proxy } = getCurrentInstance(); |
| | | const filePreviewRef = ref() |
| | | const handleClose = () => { |
| | | dialogVisible.value = false |
| | | } |
| | | const open = (list) => { |
| | | dialogVisible.value = true |
| | | tableData.value = list |
| | | } |
| | | const downLoadFile = (row) => { |
| | | proxy.$download.name(row.url); |
| | | |
| | | } |
| | | const lookFile = (row) => { |
| | | filePreviewRef.value.open(row.url) |
| | | } |
| | | // å é¤éä»¶ |
| | | const handleDelete = (row) => { |
| | | ElMessageBox.confirm(`确认å é¤éä»¶"${row.name}"åï¼`, 'å é¤ç¡®è®¤', { |
| | | confirmButtonText: '确认', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning', |
| | | }).then(() => { |
| | | delCommonFile([row.id]).then(() => { |
| | | ElMessage.success('å 餿å') |
| | | // ä»å表ä¸ç§»é¤å·²å é¤çéä»¶ |
| | | const index = tableData.value.findIndex(item => item.id === row.id) |
| | | if (index !== -1) { |
| | | tableData.value.splice(index, 1) |
| | | } |
| | | }).catch(() => { |
| | | ElMessage.error('å é¤å¤±è´¥') |
| | | }) |
| | | }).catch(() => { |
| | | proxy.$modal.msg('已忶å é¤') |
| | | }) |
| | | } |
| | | defineExpose({ |
| | | open |
| | | }) |
| | | </script> |
| | | |
| | | <style></style> |
| | |
| | | <el-input v-model="searchForm.salesContractNo" placeholder="请è¾å
¥" clearable prefix-icon="Search" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="项ç®åç§°ï¼"> |
| | | <el-input v-model="searchForm.projectName" placeholder="请è¾å
¥" clearable prefix-icon="Search" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="å½å
¥æ¥æï¼"> |
| | | <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" |
| | | placeholder="è¯·éæ©" clearable @change="changeDaterange" /> |
| | |
| | | show-summary |
| | | :summary-method="summarizeMainTable" |
| | | @expand-change="expandChange" |
| | | height="calc(100vh - 18.5em)" |
| | | height="calc(100vh - 19em)" |
| | | > |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column type="expand"> |
| | |
| | | <el-table-column |
| | | label="éå®ååå·" |
| | | prop="salesContractNo" |
| | | width="200" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="ä¾åºååç§°" |
| | | width="240" |
| | | prop="supplierName" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="项ç®åç§°" |
| | | prop="projectName" |
| | | width="420" |
| | | label="ç¾è®¢æ¥æ" |
| | | prop="executionDate" |
| | | width="100" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | |
| | | <el-table-column |
| | | label="å½å
¥äºº" |
| | | prop="recorderName" |
| | | width="100" |
| | | width="120" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | |
| | | <el-table-column |
| | | fixed="right" |
| | | label="æä½" |
| | | min-width="150" |
| | | width="180" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | |
| | | type="primary" |
| | | size="small" |
| | | @click="openForm('edit', scope.row)" |
| | | :disabled="scope.row.receiptPaymentAmount>0 || scope.row.recorderName !== userStore.nickName" |
| | | >ç¼è¾</el-button |
| | | > |
| | | <el-button |
| | |
| | | size="small" |
| | | @click="showQRCode(scope.row)" |
| | | >çæäºç»´ç </el-button |
| | | > |
| | | <el-button |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | @click="downLoadFile(scope.row)" |
| | | >éä»¶</el-button |
| | | > |
| | | |
| | | </template> |
| | |
| | | <el-select |
| | | v-model="form.salesLedgerId" |
| | | placeholder="è¯·éæ©" |
| | | filterable |
| | | clearable |
| | | @change="salesLedgerChange" |
| | | > |
| | | <el-option |
| | | v-for="item in salesContractList" |
| | |
| | | <el-select |
| | | v-model="form.supplierId" |
| | | placeholder="è¯·éæ©" |
| | | filterable |
| | | clearable |
| | | > |
| | | <el-option |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="项ç®åç§°ï¼" prop="projectName"> |
| | | <el-input |
| | | v-model="form.projectName" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="仿¬¾æ¹å¼"> |
| | | <el-input |
| | | v-model="form.paymentMethod" |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç¾è®¢æ¥æï¼" prop="executionDate"> |
| | | <el-date-picker |
| | |
| | | v-model="form.recorderId" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | disabled |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="项ç®åç§°ï¼" prop="projectName"> |
| | | <el-input |
| | | v-model="scanAddForm.projectName" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ååéé¢(å
)ï¼" prop="contractAmount"> |
| | | <el-input-number |
| | | v-model="scanAddForm.contractAmount" |
| | |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="项ç®åç§°ï¼"> |
| | | <el-input v-model="scanForm.projectName" disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ«ç æ¶é´ï¼"> |
| | | <el-input v-model="scanForm.scanTime" disabled /> |
| | | </el-form-item> |
| | |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <FileList ref="fileListRef" /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { userListNoPage } from "@/api/system/user.js"; |
| | | import FileList from "./fileList.vue"; |
| | | import { |
| | | getSalesLedgerWithProducts, |
| | | addOrUpdateSalesLedgerProduct, |
| | |
| | | supplierName: "", // ä¾åºååç§° |
| | | purchaseContractNumber: "", // éè´ååç¼å· |
| | | salesContractNo: "", // éå®ååç¼å· |
| | | projectName: "", // 项ç®åç§° |
| | | entryDate: null, // å½å
¥æ¥æ |
| | | entryDateStart: undefined, |
| | | entryDateEnd: undefined, |
| | |
| | | form: { |
| | | purchaseContractNumber: "", |
| | | salesLedgerId: "", |
| | | projectName: "", |
| | | recorderId: "", |
| | | entryDate: "", |
| | | productData: [], |
| | |
| | | purchaseContractNumber: [ |
| | | { required: true, message: "请è¾å
¥", trigger: "blur" }, |
| | | ], |
| | | projectName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | supplierId: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | entryDate: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | executionDate: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | }, |
| | | }); |
| | | const { form, rules } = toRefs(data); |
| | | const { form: searchForm } = useFormData(data.searchForm); |
| | | const { form: searchForm } = useFormData({ |
| | | ...data.searchForm, |
| | | // 设置å½å
¥æ¥æèå´ä¸ºå½å¤© |
| | | entryDate: [dayjs().startOf('day').format('YYYY-MM-DD'), dayjs().endOf('day').format('YYYY-MM-DD')], |
| | | entryDateStart: dayjs().startOf('day').format('YYYY-MM-DD'), |
| | | entryDateEnd: dayjs().endOf('day').format('YYYY-MM-DD') |
| | | }); |
| | | |
| | | // 产å表åå¼¹æ¡æ°æ® |
| | | const productFormVisible = ref(false); |
| | |
| | | { required: true, message: "请è¾å
¥", trigger: "blur" }, |
| | | ], |
| | | taxRate: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | warnNum: [{ required: false, message: "è¯·éæ©", trigger: "change" }], |
| | | warnNum: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | taxInclusiveTotalPrice: [ |
| | | { required: true, message: "请è¾å
¥", trigger: "blur" }, |
| | | ], |
| | |
| | | } |
| | | form.value.tempFileIds = tempFileIds; |
| | | form.value.type = 2; |
| | | |
| | | // 妿salesLedgerId为空ï¼åä¸ä¼ ésalesContractNo |
| | | if (!form.value.salesLedgerId) { |
| | | form.value.salesContractNo = '' |
| | | } |
| | | |
| | | addOrEditPurchase(form.value).then((res) => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | |
| | | var index = salesContractList.value.findIndex((item) => item.id == row); |
| | | console.log("index", index); |
| | | if (index > -1) { |
| | | form.value.projectName = salesContractList.value[index].projectName; |
| | | await querygProductInfoByContractNo(); |
| | | } |
| | | }; |
| | |
| | | productData.value = data; |
| | | } |
| | | }; |
| | | |
| | | const fileListRef = ref(null) |
| | | const downLoadFile = (row) => { |
| | | fileListRef.value.open(row.salesLedgerFiles) |
| | | } |
| | | |
| | | // æ¾ç¤ºäºç»´ç |
| | | const showQRCode = async (row) => { |
| | |
| | | scanContent: "", |
| | | purchaseContractNumber: "", |
| | | supplierName: "", |
| | | projectName: "", |
| | | contractAmount: "", |
| | | paymentMethod: "", |
| | | recorderName: "", |
| | |
| | | const scanAddRules = { |
| | | purchaseContractNumber: [{ required: true, message: "请è¾å
¥éè´ååå·", trigger: "blur" }], |
| | | supplierName: [{ required: true, message: "请è¾å
¥ä¾åºååç§°", trigger: "blur" }], |
| | | projectName: [{ required: true, message: "请è¾å
¥é¡¹ç®åç§°", trigger: "blur" }], |
| | | }; |
| | | |
| | | // æ«ç ç»è®°å¯¹è¯æ¡ç¸å
³åé |
| | |
| | | const scanForm = reactive({ |
| | | purchaseContractNumber: "", |
| | | supplierName: "", |
| | | projectName: "", |
| | | scanTime: "", |
| | | scannerName: "", |
| | | scanStatus: "æªæ«ç ", |
| | |
| | | scanAddForm.scanContent = ""; |
| | | scanAddForm.purchaseContractNumber = ""; |
| | | scanAddForm.supplierName = ""; |
| | | scanAddForm.projectName = ""; |
| | | scanAddForm.contractAmount = ""; |
| | | scanAddForm.paymentMethod = ""; |
| | | scanAddForm.recorderName = userStore.nickName; |
| | |
| | | if (!content) return; |
| | | |
| | | // 模æè§£æäºç»´ç å
容ï¼è¿éå¯ä»¥æ ¹æ®å®é
éæ±è°æ´è§£æé»è¾ |
| | | // å设æ«ç å
å®¹æ ¼å¼ä¸ºï¼ååå·|ä¾åºå|项ç®|éé¢|仿¬¾æ¹å¼ |
| | | // å设æ«ç å
å®¹æ ¼å¼ä¸ºï¼ååå·|ä¾åºå|éé¢|仿¬¾æ¹å¼ |
| | | const parts = content.split('|'); |
| | | if (parts.length >= 3) { |
| | | if (parts.length >= 2) { |
| | | scanAddForm.purchaseContractNumber = parts[0] || ""; |
| | | scanAddForm.supplierName = parts[1] || ""; |
| | | scanAddForm.projectName = parts[2] || ""; |
| | | scanAddForm.contractAmount = parts[3] || ""; |
| | | scanAddForm.paymentMethod = parts[4] || ""; |
| | | scanAddForm.contractAmount = parts[2] || ""; |
| | | scanAddForm.paymentMethod = parts[3] || ""; |
| | | } |
| | | }; |
| | | |
| | |
| | | const newData = { |
| | | purchaseContractNumber: scanAddForm.purchaseContractNumber, |
| | | supplierName: scanAddForm.supplierName, |
| | | projectName: scanAddForm.projectName, |
| | | contractAmount: scanAddForm.contractAmount, |
| | | paymentMethod: scanAddForm.paymentMethod, |
| | | recorderName: scanAddForm.recorderName, |
| | |
| | | const openScanDialog = (row) => { |
| | | scanForm.purchaseContractNumber = row.purchaseContractNumber; |
| | | scanForm.supplierName = row.supplierName; |
| | | scanForm.projectName = row.projectName; |
| | | scanForm.scanTime = getCurrentDateTime(); |
| | | scanForm.scannerName = userStore.nickName; |
| | | scanForm.scanStatus = "æªæ«ç "; |
| | |
| | | import { ref, reactive, onMounted } from 'vue' |
| | | import { ElMessage } from 'element-plus' |
| | | import { Document, List, TrendCharts, Shop, Search, Refresh, Download } from '@element-plus/icons-vue' |
| | | import dayjs from "dayjs"; |
| | | |
| | | // ååºå¼æ°æ® |
| | | const loading = ref(false) |
| | |
| | | } |
| | | |
| | | onMounted(() => { |
| | | // 设置é»è®¤æ¶é´èå´ä¸ºæè¿30天 |
| | | const endDate = new Date() |
| | | const startDate = new Date() |
| | | startDate.setDate(startDate.getDate() - 30) |
| | | |
| | | // 设置é»è®¤æ¶é´èå´ä¸ºå½å¤© |
| | | searchForm.dateRange = [ |
| | | startDate.toISOString().split('T')[0], |
| | | endDate.toISOString().split('T')[0] |
| | | dayjs().startOf('day').format('YYYY-MM-DD'), |
| | | dayjs().endOf('day').format('YYYY-MM-DD') |
| | | ] |
| | | }) |
| | | </script> |
| | |
| | | > |
| | | <el-button type="primary" @click="addRow" style="margin-bottom: 10px;">æ°å¢</el-button> |
| | | <span style="font-size: 18px;margin-left: 10px">å¾
æäº§æ°éï¼{{pendingNum}}</span> |
| | | <!-- <div style="margin-bottom: 10px; margin-left: 10px;">--> |
| | | <!-- <el-form-item label="é¢ç¨ï¼" style="margin-bottom: 0;">--> |
| | | <!-- <el-input v-model="receive" placeholder="请è¾å
¥é¢ç¨" style="width: 200px;" />--> |
| | | <!-- </el-form-item>--> |
| | | <!-- </div>--> |
| | | <el-table :data="tableData" border style="width: 100%" :summary-method="summarizeMainTable" show-summary :row-key="row => row.id"> |
| | | <el-table-column label="åºå·" width="60"> |
| | | <el-table-column label="åºå·" width="60" align="center"> |
| | | <template #default="scope"> |
| | | {{ scope.$index + 1 }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å·¥åº" prop="process"> |
| | | <el-table-column label="å·¥åº" prop="process" width="150"> |
| | | <template #default="scope"> |
| | | <el-input v-model="scope.row.process" placeholder="请è¾å
¥å·¥åº" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åä½" prop="unit"> |
| | | <el-table-column label="产线" prop="productionLine" width="150"> |
| | | <template #default="scope"> |
| | | <el-select |
| | | v-model="scope.row.productionLine" |
| | | placeholder="éæ©äº§çº¿" |
| | | style="width: 100%;" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="line in productionLines" |
| | | :key="line.value" |
| | | :label="line.label" |
| | | :value="line.value" |
| | | /> |
| | | </el-select> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åä½" prop="unit" width="90"> |
| | | <template #default="scope"> |
| | | <el-input v-model="scope.row.unit" placeholder="请è¾å
¥åä½" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å£å³/åå/è§æ ¼" prop="type" width="150"> |
| | | <template #default="scope"> |
| | | <el-input v-model="scope.row.type" placeholder="请è¾å
¥" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æäº§æ°é" width="200" prop="schedulingNum"> |
| | |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æäº§æ¥æ" prop="schedulingDate"> |
| | | <el-table-column label="æäº§æ¥æ" prop="schedulingDate" width="200"> |
| | | <template #default="scope"> |
| | | <el-date-picker v-model="scope.row.schedulingDate" type="date" placeholder="éæ©æ¥æ" style="width: 100%;" value-format="YYYY-MM-DD" format="YYYY-MM-DD"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æäº§äºº" prop="schedulingUserId"> |
| | | <el-table-column label="æäº§äºº" prop="schedulingUserId" width="150"> |
| | | <template #default="scope"> |
| | | <el-select |
| | | v-model="scope.row.schedulingUserId" |
| | | placeholder="éæ©äººå" |
| | | style="width: 100%;" |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | > |
| | | <el-option |
| | | v-for="user in userList" |
| | |
| | | :value="user.userId" |
| | | /> |
| | | </el-select> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="夿³¨" prop="remark" width="200"> |
| | | <template #default="scope"> |
| | | <el-input v-model="scope.row.remark" placeholder="请è¾å
¥å¤æ³¨" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" width="80"> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref} from "vue"; |
| | | import {ref, getCurrentInstance} from "vue"; |
| | | import {userListNoPageByTenantId} from "@/api/system/user.js"; |
| | | import {processScheduling} from "@/api/productionManagement/operationScheduling.js"; |
| | | const { proxy } = getCurrentInstance() |
| | |
| | | |
| | | const dialogFormVisible = ref(false); |
| | | const operationType = ref('') |
| | | const tableData = ref([ |
| | | { process: '', schedulingDate: '', schedulingNum: '', schedulingUserId: '', workHours: '', unit: '' } |
| | | ]); |
| | | const tableData = ref([]); |
| | | const unitFromRow = ref(''); |
| | | const idFromRow = ref(''); |
| | | const pendingNum = ref(''); |
| | | const specificationModelFromRow = ref(''); |
| | | const pendingNum = ref(0); |
| | | const userList = ref([]) |
| | | const receive = ref('') |
| | | const sunqianUserId = ref('') |
| | | // 产线é项 |
| | | const productionLines = ref([ |
| | | { label: '产线1', value: '产线1' }, |
| | | { label: '产线2', value: '产线2' }, |
| | | { label: '产线3', value: '产线3' }, |
| | | { label: '产线4', value: '产线4' } |
| | | ]) |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = (type, row) => { |
| | | operationType.value = type; |
| | | dialogFormVisible.value = true; |
| | | pendingNum.value = row?.pendingNum ?? 0; |
| | | unitFromRow.value = row?.unit ?? ''; |
| | | idFromRow.value = row?.id ?? ''; |
| | | specificationModelFromRow.value = row?.specificationModel ?? ''; |
| | | |
| | | userListNoPageByTenantId().then((res) => { |
| | | userList.value = res.data; |
| | | }); |
| | | pendingNum.value = row.pendingNum |
| | | if (row && row.unit !== undefined) { |
| | | unitFromRow.value = row.unit; |
| | | idFromRow.value = row.id; |
| | | tableData.value.forEach(item => { |
| | | item.unit = row.unit; |
| | | item.id = row.id; |
| | | }); |
| | | } else { |
| | | unitFromRow.value = ''; |
| | | // æ¾å°åå©çç¨æ·ID并设置为é»è®¤å¼ |
| | | const sunqianUser = userList.value.find(user => user.nickName === 'åå©'); |
| | | if (sunqianUser) { |
| | | sunqianUserId.value = sunqianUser.userId; |
| | | } |
| | | // å¨ç¨æ·å表å è½½å®æååå»ºè¡æ°æ®ï¼å¹¶å°äº§çº¿æ°æ®å¸¦å
¥ |
| | | tableData.value = [createRow(row)]; |
| | | }); |
| | | } |
| | | |
| | | const createRow = (row) => ({ |
| | | id: idFromRow.value, |
| | | process: 'å
è£
', |
| | | schedulingDate: '', |
| | | schedulingNum: null, |
| | | schedulingUserId: sunqianUserId.value, // é»è®¤è®¾ç½®ä¸ºåå©çç¨æ·ID |
| | | workHours: null, |
| | | unit: unitFromRow.value, |
| | | remark: '', |
| | | type: specificationModelFromRow.value, |
| | | productionLine: row?.productionLine ?? '', // ä»è¡æ°æ®ä¸è·åäº§çº¿ä¿¡æ¯ |
| | | }); |
| | | |
| | | const submitForm = () => { |
| | | // 1. æ£æ¥æ¯ä¸è¡æ¯å¦å¡«å宿´ |
| | | for (let i = 0; i < tableData.value.length; i++) { |
| | |
| | | row.schedulingNum === '' || row.schedulingNum === null || |
| | | !row.schedulingUserId || |
| | | row.workHours === '' || row.workHours === null || |
| | | !row.unit |
| | | !row.unit || |
| | | !row.productionLine |
| | | ) { |
| | | proxy.$modal.msgError(`第${i + 1}è¡æ°æ®æªå¡«å宿´`); |
| | | return; |
| | |
| | | proxy.$modal.msgError('æäº§æ°éå计ä¸è½è¶
è¿å¾
æäº§æ°é'); |
| | | return; |
| | | } |
| | | processScheduling(tableData.value).then((res) => { |
| | | // 3. å° receive åæ®µæ·»å å°æ¯æ¡æ°æ®ä¸ï¼å¹¶ç§»é¤ loss åæ®µ |
| | | const submitData = tableData.value.map(row => { |
| | | const { loss, ...rest } = row; |
| | | return { |
| | | ...rest, |
| | | receive: receive.value |
| | | }; |
| | | }); |
| | | processScheduling(submitData).then((res) => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | | }) |
| | |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | dialogFormVisible.value = false; |
| | | receive.value = ''; |
| | | tableData.value = []; |
| | | unitFromRow.value = ''; |
| | | idFromRow.value = ''; |
| | | specificationModelFromRow.value = ''; |
| | | pendingNum.value = 0; |
| | | emit('close') |
| | | }; |
| | | defineExpose({ |
| | |
| | | }); |
| | | |
| | | const addRow = () => { |
| | | tableData.value.push({ id: idFromRow.value, process: '', unit: unitFromRow.value, schedulingNum: '', workHours: '', schedulingDate: '', schedulingUserId: '' }); |
| | | tableData.value.push(createRow()); |
| | | }; |
| | | const removeRow = (index) => { |
| | | tableData.value.splice(index, 1); |
| | |
| | | style="width: 200px;" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="项ç®åç§°:"> |
| | | <el-input v-model="searchForm.projectName" placeholder="请è¾å
¥" clearable prefix-icon="Search" |
| | | <el-form-item label="ååå·:"> |
| | | <el-input v-model="searchForm.salesContractNo" placeholder="请è¾å
¥" clearable prefix-icon="Search" |
| | | style="width: 200px;" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <!-- <el-form-item label="项ç®åç§°:">--> |
| | | <!-- <el-input v-model="searchForm.projectName" placeholder="请è¾å
¥" clearable prefix-icon="Search"--> |
| | | <!-- style="width: 200px;"--> |
| | | <!-- @change="handleQuery" />--> |
| | | <!-- </el-form-item>--> |
| | | <el-form-item label="æ´¾å·¥æ¥æ:"> |
| | | <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" |
| | | placeholder="è¯·éæ©" clearable @change="changeDaterange" /> |
| | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | staffName: "", |
| | | customerName: "", |
| | | salesContractNo: "", |
| | | status: 1, |
| | | entryDate: null, // å½å
¥æ¥æ |
| | | entryDateStart: undefined, |
| | | entryDateEnd: undefined, |
| | | entryDate: [dayjs().format("YYYY-MM-DD"), dayjs().format("YYYY-MM-DD")], // å½å
¥æ¥æï¼é»è®¤å½å¤© |
| | | entryDateStart: dayjs().format("YYYY-MM-DD"), |
| | | entryDateEnd: dayjs().format("YYYY-MM-DD"), |
| | | }, |
| | | }); |
| | | const { searchForm } = toRefs(data); |
| | |
| | | prop: "salesContractNo", |
| | | width: 200, |
| | | }, |
| | | { |
| | | label: "客æ·ååå·", |
| | | prop: "customerContractNo", |
| | | width: 200, |
| | | }, |
| | | // { |
| | | // label: "客æ·ååå·", |
| | | // prop: "customerContractNo", |
| | | // width: 200, |
| | | // }, |
| | | { |
| | | label: "客æ·åç§°", |
| | | prop: "customerName", |
| | | width: 200, |
| | | }, |
| | | { |
| | | label: "项ç®åç§°", |
| | | prop: "projectName", |
| | | width:300 |
| | | }, |
| | | // { |
| | | // label: "项ç®åç§°", |
| | | // prop: "projectName", |
| | | // width:300 |
| | | // }, |
| | | { |
| | | label: "产å大类", |
| | | prop: "productCategory", |
| | |
| | | width: 150, |
| | | }, |
| | | { |
| | | label: "ç»å®æºå¨", |
| | | prop: "speculativeTradingName", |
| | | width: 220, |
| | | }, |
| | | // { |
| | | // label: "产线", |
| | | // prop: "productionLine", |
| | | // width: 220, |
| | | // }, |
| | | { |
| | | label: "åä½", |
| | | prop: "unit", |
| | | }, |
| | |
| | | clearable |
| | | prefix-icon="Search" |
| | | /> |
| | | <span class="search_title ml10">ååå·ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.salesContractNo" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | @change="handleQuery" |
| | | clearable |
| | | prefix-icon="Search" |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px" |
| | | >æç´¢</el-button |
| | | > |
| | |
| | | prop: "salesContractNo", |
| | | width: 220, |
| | | }, |
| | | { |
| | | label: "客æ·ååå·", |
| | | prop: "customerContractNo", |
| | | width: 250, |
| | | }, |
| | | // { |
| | | // label: "客æ·ååå·", |
| | | // prop: "customerContractNo", |
| | | // width: 250, |
| | | // }, |
| | | { |
| | | label: "客æ·åç§°", |
| | | prop: "customerName", |
| | | width: 250, |
| | | }, |
| | | { |
| | | label: "项ç®åç§°", |
| | | prop: "projectName", |
| | | width:300 |
| | | }, |
| | | // { |
| | | // label: "项ç®åç§°", |
| | | // prop: "projectName", |
| | | // width:300 |
| | | // }, |
| | | { |
| | | label: "产å大类", |
| | | prop: "productCategory", |
| | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | schedulingUserName: "", |
| | | salesContractNo: "", |
| | | entryDate: [ |
| | | dayjs().format("YYYY-MM-DD"), |
| | | dayjs().add(1, "day").format("YYYY-MM-DD"), |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog |
| | | v-model="dialogFormVisible" |
| | | title="èªå¨æ´¾å·¥" |
| | | width="80%" |
| | | @close="closeDia" |
| | | > |
| | | <el-form :model="form" label-width="140px" label-position="top" ref="formRef"> |
| | | <el-divider content-position="left">派工å表</el-divider> |
| | | |
| | | <el-table |
| | | :data="dispatchList" |
| | | border |
| | | style="width: 100%; margin-top: 20px;" |
| | | :row-class-name="tableRowClassName" |
| | | > |
| | | <el-table-column label="åºå·" type="index" width="60" align="center" /> |
| | | <el-table-column label="ååå·" prop="salesContractNo" width="200" /> |
| | | <el-table-column label="客æ·åç§°" prop="customerName" width="200" /> |
| | | <!-- <el-table-column label="项ç®åç§°" prop="projectName" width="250" /> --> |
| | | <el-table-column label="产å大类" prop="productCategory" width="150" /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" width="200" /> |
| | | <el-table-column label="ç»å®æºå¨" prop="speculativeTradingName" width="120" /> |
| | | <el-table-column label="æ»æ°é" prop="quantity" width="100" align="right" /> |
| | | <el-table-column label="å·²æäº§" prop="schedulingNum" width="100" align="right" fixed="right" /> |
| | | <el-table-column label="å¾
æäº§" prop="pendingQuantity" width="100" align="right" fixed="right" /> |
| | | <el-table-column label="æ¬æ¬¡æäº§" width="150" align="center" fixed="right"> |
| | | <template #default="{ row }"> |
| | | <el-input-number |
| | | v-model="row.schedulingNum" |
| | | :min="0" |
| | | :max="row.pendingQuantity" |
| | | :step="1" |
| | | :precision="0" |
| | | size="small" |
| | | style="width: 120px" |
| | | @change="(value) => changeCurrentNum(value, row)" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-form> |
| | | |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确认派工</el-button> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref, reactive, toRefs, computed} from "vue"; |
| | | import {productionDispatch, productionDispatchList} from "@/api/productionManagement/productionOrder.js"; |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | |
| | | const dialogFormVisible = ref(false); |
| | | const operationType = ref('') |
| | | |
| | | const data = reactive({ |
| | | form: {}, |
| | | dispatchList: [], // 派工åè¡¨æ°æ® |
| | | }); |
| | | |
| | | const { form, dispatchList } = toRefs(data); |
| | | |
| | | |
| | | // è¡¨æ ¼è¡æ ·å¼ |
| | | const tableRowClassName = ({ rowIndex }) => { |
| | | if (rowIndex % 2 === 1) { |
| | | return 'even-row' |
| | | } |
| | | return '' |
| | | } |
| | | |
| | | // ä¿®æ¹æ¬æ¬¡æäº§æ°é |
| | | const changeCurrentNum = (value, row) => { |
| | | if (value > row.pendingQuantity) { |
| | | row.schedulingNum = row.pendingQuantity |
| | | proxy.$modal.msgWarning('æäº§æ°éä¸å¯å¤§äºå¾
æäº§æ°é') |
| | | } |
| | | } |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = (type, rows) => { |
| | | operationType.value = type; |
| | | dialogFormVisible.value = true; |
| | | |
| | | // å¤çä¼ å
¥çæ°æ® |
| | | dispatchList.value = rows.map(row => ({ |
| | | ...row, |
| | | schedulingNum: 0, // åå§åæ¬æ¬¡æäº§æ°é为0 |
| | | pendingQuantity: (Number(row.quantity) || 0) - (Number(row.schedulingNum) || 0) // 计ç®å¾
æäº§æ°é |
| | | })) |
| | | } |
| | | |
| | | // æäº¤è¡¨å |
| | | const submitForm = () => { |
| | | // æ£æ¥æ¯å¦ææäº§æ°æ® |
| | | const hasSchedulingData = dispatchList.value.some(item => item.schedulingNum > 0) |
| | | if (!hasSchedulingData) { |
| | | proxy.$modal.msgWarning('请è³å°ä¸ºä¸æ¡è®°å½è®¾ç½®æäº§æ°é') |
| | | return |
| | | } |
| | | |
| | | // æé æäº¤æ°æ® - ç´æ¥ä¼ éæ°ç»ï¼ä¸è¿æ»¤ |
| | | const submitData = dispatchList.value |
| | | |
| | | console.log('æäº¤èªå¨æ´¾å·¥æ°æ®:', submitData) |
| | | |
| | | // è°ç¨APIï¼è¿ééè¦æ ¹æ®å®é
æ¥å£è°æ´ï¼ |
| | | productionDispatchList(submitData).then(res => { |
| | | proxy.$modal.msgSuccess(res.msg); |
| | | closeDia(); |
| | | }).catch(err => { |
| | | proxy.$modal.msgError("派工失败"); |
| | | console.error('派工失败:', err); |
| | | }) |
| | | } |
| | | |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef"); |
| | | dialogFormVisible.value = false; |
| | | dispatchList.value = [] |
| | | emit('close') |
| | | }; |
| | | |
| | | defineExpose({ |
| | | openDialog, |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | :deep(.even-row) { |
| | | background-color: #fafafa; |
| | | } |
| | | |
| | | :deep(.el-table .cell) { |
| | | padding: 8px 12px; |
| | | } |
| | | |
| | | :deep(.el-table th) { |
| | | background-color: #f5f7fa; |
| | | color: #606266; |
| | | font-weight: 600; |
| | | } |
| | | </style> |
| | |
| | | @close="closeDia" |
| | | > |
| | | <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> |
| | | <el-row :gutter="30"> |
| | | <!-- <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="项ç®åç§°ï¼" prop="projectName"> |
| | | <el-input v-model="form.projectName" placeholder="请è¾å
¥" clearable disabled/> |
| | |
| | | <el-col :span="12"> |
| | | <el-form-item label="产å大类ï¼" prop="productCategory"> |
| | | <el-input v-model="form.productCategory" placeholder="请è¾å
¥" clearable disabled/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> --> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è§æ ¼åå·ï¼" prop="specificationModel"> |
| | | <el-input v-model="form.specificationModel" placeholder="请è¾å
¥" clearable disabled/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»å®æºå¨ï¼" prop="speculativeTradingName"> |
| | | <el-input v-model="form.speculativeTradingName" placeholder="èªå¨è·å" clearable disabled/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="产å大类ï¼" prop="productCategory"> |
| | | <el-input v-model="form.productCategory" placeholder="请è¾å
¥" clearable disabled/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | |
| | | v-model="form.schedulingUserId" |
| | | placeholder="éæ©äººå" |
| | | style="width: 100%;" |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | > |
| | | <el-option |
| | | v-for="user in userList" |
| | |
| | | form: { |
| | | projectName: "", |
| | | productCategory: "", |
| | | specificationModel: "", // è§æ ¼åå· |
| | | quantity: "", |
| | | schedulingNum: "", |
| | | schedulingUserId: "", |
| | | schedulingDate: "", |
| | | pendingQuantity: "", |
| | | speculativeTradingName: "", // ç»å®æºå¨åç§° |
| | | }, |
| | | rules: { |
| | | schedulingNum: [{ required: true, message: "请è¾å
¥", trigger: "blur" },], |
| | |
| | | const userList = ref([]) |
| | | const userStore = useUserStore() |
| | | |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = (type, row) => { |
| | | operationType.value = type; |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <!-- çæº1-4 å±ç¤ºï¼æ»é / æ£å¨ç产é / 空ä½éï¼ --> |
| | | <div class="machines-grid"> |
| | | <div v-for="machine in machines" :key="machine.id" class="machine-card"> |
| | | <div class="machine-title">{{ machine.name }}</div> |
| | | <div class="machine-metrics"> |
| | | <div class="machine-control"> |
| | | <span>æ»é(kg)ï¼</span> |
| | | <el-input-number v-model="machineData[machine.name].workLoad" :min="0" :step="1" size="small" /> |
| | | </div> |
| | | <div><span> é¢è®¡æå
¥é(kg)ï¼</span><span>{{ machineData[machine.name].currentWorkLoad }}</span></div> |
| | | <div><span>空ä½å·¥ä½é(kg)ï¼</span><span>{{ machineData[machine.name].vacant }}</span></div> |
| | | </div> |
| | | </div> |
| | | <div class="save-button-container"> |
| | | <div class="loss-rate-container"> |
| | | <span class="loss-rate-label">æèç(%)ï¼</span> |
| | | <el-select v-model="rate" placeholder="è¯·éæ©æèç" style="width: 120px" size="small"> |
| | | <el-option label="6" :value="6" /> |
| | | <el-option label="7" :value="7" /> |
| | | <el-option label="8" :value="8" /> |
| | | <el-option label="9" :value="9" /> |
| | | <el-option label="10" :value="10" /> |
| | | </el-select> |
| | | </div> |
| | | <el-button type="primary" @click="saveMachineTotals" size="small">ä¿å设置</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">客æ·åç§°ï¼</span> |
| | |
| | | clearable |
| | | prefix-icon="Search" |
| | | /> |
| | | <span class="search_title ml10">项ç®åç§°ï¼</span> |
| | | <span class="search_title ml10">ååå·ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.projectName" |
| | | v-model="searchForm.salesContractNo" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | @change="handleQuery" |
| | | clearable |
| | | prefix-icon="Search" |
| | | /> |
| | | <!-- <span class="search_title ml10">项ç®åç§°ï¼</span>--> |
| | | <!-- <el-input--> |
| | | <!-- v-model="searchForm.projectName"--> |
| | | <!-- style="width: 240px"--> |
| | | <!-- placeholder="请è¾å
¥"--> |
| | | <!-- @change="handleQuery"--> |
| | | <!-- clearable--> |
| | | <!-- prefix-icon="Search"--> |
| | | <!-- />--> |
| | | <span class="search_title ml10">å½å
¥æ¥æï¼</span> |
| | | <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" |
| | | placeholder="è¯·éæ©" clearable @change="changeDaterange" /> |
| | | <el-checkbox |
| | | style="margin-left: 10px" |
| | | v-model="searchForm.status" |
| | | label="䏿¾ç¤ºå¾
ææ°é为0" |
| | | @change="handleQuery" |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">æç´¢</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" @click="openForm('add')">ç产派工</el-button> |
| | | <el-button type="success" @click="openAutoDispatch">èªå¨æ´¾å·¥</el-button> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | </div> |
| | | </div> |
| | |
| | | ></PIMTable> |
| | | </div> |
| | | <form-dia ref="formDia" @close="handleQuery"></form-dia> |
| | | <auto-dispatch-dia ref="autoDispatchDia" @close="handleQuery"></auto-dispatch-dia> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {onMounted, ref} from "vue"; |
| | | import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick, computed, watch} from "vue"; |
| | | import FormDia from "@/views/productionManagement/productionDispatching/components/formDia.vue"; |
| | | import AutoDispatchDia from "@/views/productionManagement/productionDispatching/components/autoDispatchDia.vue"; |
| | | import dayjs from "dayjs"; |
| | | import {schedulingListPage} from "@/api/productionManagement/productionOrder.js"; |
| | | import {schedulingListPage, schedulingList, addSpeculatTrading, updateSpeculatTrading, getLossRate, addLossRate, updateLossRate} from "@/api/productionManagement/productionOrder.js"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | customerName: "", |
| | | salesContractNo: "", |
| | | projectName: "", |
| | | entryDate: null, // å½å
¥æ¥æ |
| | | entryDateStart: undefined, |
| | | entryDateEnd: undefined, |
| | | status: true, |
| | | entryDate: [dayjs().format("YYYY-MM-DD"), dayjs().format("YYYY-MM-DD")], // å½å
¥æ¥æï¼é»è®¤å½å¤© |
| | | entryDateStart: dayjs().format("YYYY-MM-DD"), |
| | | entryDateEnd: dayjs().format("YYYY-MM-DD"), |
| | | }, |
| | | }); |
| | | const { searchForm } = toRefs(data); |
| | |
| | | width: 220, |
| | | }, |
| | | { |
| | | label: "客æ·ååå·", |
| | | prop: "customerContractNo", |
| | | width: 250, |
| | | }, |
| | | { |
| | | label: "客æ·åç§°", |
| | | prop: "customerName", |
| | | width: 250, |
| | | }, |
| | | { |
| | | label: "项ç®åç§°", |
| | | prop: "projectName", |
| | | width:300 |
| | | }, |
| | | { |
| | | label: "产å大类", |
| | |
| | | { |
| | | label: "è§æ ¼åå·", |
| | | prop: "specificationModel", |
| | | width: 220, |
| | | width: 120, |
| | | }, |
| | | { |
| | | label: "ç»å®æºå¨", |
| | | prop: "speculativeTradingName", |
| | | width: 160, |
| | | }, |
| | | { |
| | | label: "åä½", |
| | |
| | | label: "å½å
¥æ¥æ", |
| | | prop: "entryDate", |
| | | width: 120, |
| | | }, |
| | | { |
| | | label: "ç¶æ", |
| | | prop: "status", |
| | | dataType: "tag", |
| | | formatType: (params) => { |
| | | if (params == 'ç产ä¸') { |
| | | return "warning"; |
| | | } else if (params == 'æªå¼å§') { |
| | | return "danger"; |
| | | } else { |
| | | return "success"; |
| | | } |
| | | }, |
| | | }, |
| | | { |
| | | label: "ç产è¿åº¦", |
| | | prop: "progress", |
| | | formatData: (cellValue) => { |
| | | // 妿å¼ä¸ºç©ºæundefinedï¼æ¾ç¤ºç©ºå符串 |
| | | if (cellValue === null || cellValue === undefined || cellValue === '') { |
| | | return ''; |
| | | } |
| | | // ç´æ¥å¨æ°åå颿·»å ç¾åå· |
| | | return `${cellValue}%`; |
| | | } |
| | | }, |
| | | { |
| | | label: "æ°é", |
| | |
| | | label: "å¾
ææ°é", |
| | | prop: "pendingQuantity", |
| | | width: 100, |
| | | fixed: 'right', |
| | | }, |
| | | ]); |
| | | const tableData = ref([]); |
| | |
| | | total: 0, |
| | | }); |
| | | const formDia = ref() |
| | | const autoDispatchDia = ref() |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | | // çæºæ°æ® |
| | | const machineData = reactive({ |
| | | "çæº1": { workLoad: 0, currentWorkLoad: 0, vacant: 0 }, |
| | | "çæº2": { workLoad: 0, currentWorkLoad: 0, vacant: 0 }, |
| | | "çæº3": { workLoad: 0, currentWorkLoad: 0, vacant: 0 }, |
| | | "çæº4": { workLoad: 0, currentWorkLoad: 0, vacant: 0 } |
| | | }) |
| | | |
| | | // çæºé
ç½®æ°ç» |
| | | const machines = [ |
| | | { id: 1, name: 'çæº1' }, |
| | | { id: 2, name: 'çæº2' }, |
| | | { id: 3, name: 'çæº3' }, |
| | | { id: 4, name: 'çæº4' } |
| | | ] |
| | | |
| | | // ä¿åçæºæ»é设置 |
| | | const saveMachineTotals = () => { |
| | | // éªè¯æèçæ¯å¦å·²éæ© |
| | | if (rate.value === null || rate.value === undefined || isNaN(rate.value)) { |
| | | proxy.$message.warning('è¯·éæ©æèç'); |
| | | return; |
| | | } |
| | | |
| | | // æé ä¿åæ°æ®æ°ç»ï¼ä½¿ç¨machinesæ°ç»å¾ªç¯æå»º |
| | | const saveData = machines.map(machine => { |
| | | const saveItem = { |
| | | name: machine.name, // çæºåç§° |
| | | workLoad: machineData[machine.name].workLoad, // æ»é |
| | | currentWorkLoad: machineData[machine.name].currentWorkLoad, // é¢è®¡æå
¥é |
| | | vacant: machineData[machine.name].vacant // 空ä½é |
| | | }; |
| | | |
| | | // 妿æ¯ä¿®æ¹æä½ï¼éè¦ä¼ éidåæ®µ |
| | | if (hasQueryData.value) { |
| | | const queryData = getMachineQueryData(machine.id); |
| | | if (queryData && queryData.id) { |
| | | saveItem.id = queryData.id; |
| | | } |
| | | } |
| | | |
| | | return saveItem; |
| | | }); |
| | | |
| | | // æé æèçæ°æ® |
| | | const rateData = { |
| | | rate: rate.value |
| | | }; |
| | | |
| | | // 妿æIDï¼è¯´ææ¯ä¿®æ¹æä½ |
| | | if (rateId.value) { |
| | | rateData.id = rateId.value; |
| | | } |
| | | |
| | | // æ ¹æ®æ¯å¦ææ¥è¯¢æ°æ®å³å®è°ç¨æ°å¢æ¥å£è¿æ¯ä¿®æ¹æ¥å£ |
| | | const saveApi = hasQueryData.value ? updateSpeculatTrading : addSpeculatTrading; |
| | | const successMessage = hasQueryData.value ? 'çæºè®¾ç½®ä¿®æ¹æå' : 'çæºè®¾ç½®æ°å¢æå'; |
| | | |
| | | // æ ¹æ®æ¯å¦æIDå³å®è°ç¨æ°å¢æ¥å£è¿æ¯ä¿®æ¹æ¥å£ |
| | | const rateApi = rateId.value ? updateLossRate : addLossRate; |
| | | const rateSuccessMessage = rateId.value ? 'æèçä¿®æ¹æå' : 'æèçæ°å¢æå'; |
| | | |
| | | // å¹¶è¡è°ç¨ä¸¤ä¸ªæ¥å£ |
| | | Promise.all([ |
| | | saveApi(saveData), |
| | | rateApi(rateData) |
| | | ]).then(([saveRes, rateRes]) => { |
| | | proxy.$message.success(successMessage); |
| | | proxy.$message.success(rateSuccessMessage); |
| | | |
| | | // ä¿åæååï¼è®¾ç½®hasQueryData为trueï¼ä¸æ¬¡ä¿åå°è°ç¨ä¿®æ¹æ¥å£ |
| | | if (!hasQueryData.value) { |
| | | hasQueryData.value = true; |
| | | } |
| | | |
| | | // 妿è¿åäºIDï¼ä¿åèµ·æ¥ |
| | | if (rateRes && rateRes.data && rateRes.data.id) { |
| | | rateId.value = rateRes.data.id; |
| | | } |
| | | |
| | | // ä¿åæååéæ°è°ç¨æ¥è¯¢é¡µé¢ |
| | | getList(); |
| | | }).catch(err => { |
| | | proxy.$message.error('ä¿å失败'); |
| | | console.error('ä¿å失败:', err); |
| | | }); |
| | | } |
| | | |
| | | // è·åçæºæ¥è¯¢æ°æ® |
| | | const machineQueryData = ref([]); |
| | | |
| | | const getMachineQueryData = (machineId) => { |
| | | return machineQueryData.value.find(item => item.id === machineId); |
| | | }; |
| | | |
| | | const getMachineIndex = (item) => { |
| | | // å
¼å®¹å¤ç§å段å½åï¼è¿å 1-4 ä¹ä¸ï¼å¦åè¿å 0ï¼æªç¥ï¼ |
| | | const candidates = [item.machineId, item.machineNo, item.machine, item.deviceNo, item.deviceId] |
| | | for (const v of candidates) { |
| | | if (v === undefined || v === null) continue |
| | | const n = Number(String(v).replace(/[^\d]/g, "")) // æ½åæ°å |
| | | if ([1,2,3,4].includes(n)) return n |
| | | } |
| | | return 0 |
| | | } |
| | | |
| | | const computeTodaySummary = () => { |
| | | const todayStr = dayjs().format("YYYY-MM-DD") |
| | | |
| | | // éç½®ææçæºæ°æ® |
| | | machines.forEach(machine => { |
| | | machineData[machine.name] = { workLoad: 0, currentWorkLoad: 0, vacant: 0 } |
| | | }) |
| | | |
| | | tableData.value.forEach(item => { |
| | | // ä»
ç»è®¡å½å¤© |
| | | const isToday = dayjs(item.entryDate).format("YYYY-MM-DD") === todayStr |
| | | if (!isToday) return |
| | | |
| | | // ä½¿ç¨æ£ç¡®çåæ®µåï¼workLoadï¼çæºå·¥ä½éï¼, currentWorkLoadï¼çæºæ£å¨å·¥ä½éï¼ |
| | | const workLoad = Number(item.workLoad) || 0 |
| | | const currentWorkLoad = Number(item.currentWorkLoad) || 0 |
| | | const machineName = item.speculativeTradingName || 'çæº1' |
| | | |
| | | if (machineData[machineName]) { |
| | | machineData[machineName].workLoad += workLoad |
| | | machineData[machineName].currentWorkLoad += currentWorkLoad |
| | | machineData[machineName].vacant = machineData[machineName].workLoad - machineData[machineName].currentWorkLoad |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | |
| | | // æ¯å¦ææ¥è¯¢æ°æ® |
| | | const hasQueryData = ref(false) |
| | | // æèç |
| | | const rate = ref(6) |
| | | // æèçID |
| | | const rateId = ref(null) |
| | | |
| | | // è·åçæºæ£å¨å·¥ä½éæ°æ® |
| | | const getMachineProductionData = () => { |
| | | schedulingList().then((res) => { |
| | | // å¤ççæºæ£å¨å·¥ä½éæ°æ® |
| | | if (res.data && Array.isArray(res.data)) { |
| | | // 设置æ¯å¦ææ¥è¯¢æ°æ® |
| | | hasQueryData.value = res.data.length > 0 |
| | | |
| | | // ä¿åæ¥è¯¢æ°æ®å°machineQueryData |
| | | machineQueryData.value = res.data; |
| | | |
| | | // éç½®ææçæºæ°æ® |
| | | machines.forEach(machine => { |
| | | machineData[machine.name] = { workLoad: 0, currentWorkLoad: 0, vacant: 0 } |
| | | }); |
| | | |
| | | // éåæ°æ®ï¼æ ¹æ®æ¥è¯¢è¿åçæ°æ®ç»æå¤ç |
| | | res.data.forEach(item => { |
| | | // æ ¹æ®nameåæ®µç¡®å®çæº |
| | | const machineName = item.name || 'çæº1'; |
| | | |
| | | if (machineData[machineName]) { |
| | | // 妿æ¥è¯¢æ°æ®ä¸æworkLoadï¼ååå§åçæºæ»é |
| | | if (item.workLoad !== null && item.workLoad !== undefined) { |
| | | machineData[machineName].workLoad = Number(item.workLoad) || 0; |
| | | } |
| | | |
| | | // 妿æ¥è¯¢æ°æ®ä¸æcurrentWorkLoadï¼å设置æ£å¨å·¥ä½é |
| | | if (item.currentWorkLoad !== null && item.currentWorkLoad !== undefined) { |
| | | machineData[machineName].currentWorkLoad = Number(item.currentWorkLoad) || 0; |
| | | } |
| | | |
| | | // 计ç®ç©ºä½å·¥ä½é |
| | | machineData[machineName].vacant = machineData[machineName].workLoad - machineData[machineName].currentWorkLoad; |
| | | } |
| | | }); |
| | | } |
| | | }).catch(err => { |
| | | console.error('è·åçæºæ£å¨å·¥ä½éæ°æ®å¤±è´¥:', err); |
| | | }); |
| | | }; |
| | | |
| | | const changeDaterange = (value) => { |
| | | if (value) { |
| | | searchForm.value.entryDateStart = value[0]; |
| | |
| | | pendingQuantity: (Number(item.quantity) || 0) - (Number(item.schedulingNum) || 0) |
| | | })); |
| | | page.total = res.data.total; |
| | | computeTodaySummary() |
| | | |
| | | // åæ¶è·åçæºæ£å¨å·¥ä½éæ°æ® |
| | | getMachineProductionData(); |
| | | // è·åæèçæ°æ® |
| | | getLossRateData(); |
| | | }).catch(() => { |
| | | tableLoading.value = false; |
| | | }) |
| | | }; |
| | | |
| | | // è·åæèçæ°æ® |
| | | const getLossRateData = () => { |
| | | getLossRate().then((res) => { |
| | | const data = res.data || res; |
| | | if (data && data.rate !== undefined && data.rate !== null) { |
| | | rate.value = Number(data.rate); // ç¡®ä¿è½¬æ¢ä¸ºæ°å |
| | | rateId.value = data.id || null; |
| | | } else { |
| | | rate.value = 6; |
| | | rateId.value = null; |
| | | } |
| | | }).catch(err => { |
| | | console.error('è·åæèçæ°æ®å¤±è´¥:', err); |
| | | rate.value = 6; |
| | | rateId.value = null; |
| | | }); |
| | | }; |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | |
| | | }) |
| | | }; |
| | | |
| | | // æå¼èªå¨æ´¾å·¥å¼¹æ¡ |
| | | const openAutoDispatch = () => { |
| | | if (selectedRows.value.length === 0) { |
| | | proxy.$message.error("è¯·éæ©è³å°ä¸æ¡æ°æ®"); |
| | | return; |
| | | } |
| | | |
| | | // è¿æ»¤æå¾
æäº§æ°é为0çæ°æ® |
| | | const validRows = selectedRows.value.filter(row => row.pendingQuantity > 0); |
| | | |
| | | if (validRows.length === 0) { |
| | | proxy.$message.warning("éä¸çæ°æ®æ éæ´¾å·¥"); |
| | | return; |
| | | } |
| | | |
| | | nextTick(() => { |
| | | autoDispatchDia.value?.openDialog('auto', validRows) |
| | | }) |
| | | }; |
| | | |
| | | // å¯¼åº |
| | | const handleOut = () => { |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å¯¼åºï¼æ¯å¦ç¡®è®¤å¯¼åºï¼", "导åº", { |
| | |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | getLossRateData(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped></style> |
| | | <style scoped> |
| | | .summary-bar{ |
| | | display: flex; |
| | | gap: 16px; |
| | | margin: 10px 0 16px 0; |
| | | } |
| | | .summary-item{ |
| | | background: #f5f7fa; |
| | | border: 1px solid #ebeef5; |
| | | border-radius: 6px; |
| | | padding: 10px 16px; |
| | | min-width: 160px; |
| | | } |
| | | .summary-label{ |
| | | color: #909399; |
| | | font-size: 12px; |
| | | margin-bottom: 6px; |
| | | } |
| | | .summary-value{ |
| | | color: #303133; |
| | | font-size: 20px; |
| | | font-weight: 600; |
| | | } |
| | | .summary-control{ |
| | | display: flex; |
| | | align-items: center; |
| | | height: 28px; |
| | | } |
| | | .machines-grid{ |
| | | display: grid; |
| | | grid-template-columns: repeat(4, 1fr); |
| | | gap: 16px; |
| | | margin-bottom: 20px; |
| | | padding: 16px; |
| | | background: #f8f9fa; |
| | | border-radius: 8px; |
| | | border: 1px solid #e9ecef; |
| | | } |
| | | .machine-card{ |
| | | border: 1px solid #dee2e6; |
| | | border-radius: 8px; |
| | | padding: 16px; |
| | | background: #fff; |
| | | box-shadow: 0 2px 4px rgba(0,0,0,0.05); |
| | | transition: all 0.3s ease; |
| | | } |
| | | .machine-card:hover{ |
| | | transform: translateY(-2px); |
| | | box-shadow: 0 4px 8px rgba(0,0,0,0.1); |
| | | } |
| | | .machine-title{ |
| | | font-weight: 600; |
| | | font-size: 16px; |
| | | margin-bottom: 12px; |
| | | color: #2c3e50; |
| | | text-align: center; |
| | | padding-bottom: 8px; |
| | | border-bottom: 2px solid #3498db; |
| | | } |
| | | .machine-metrics{ |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 10px; |
| | | color: #495057; |
| | | } |
| | | .machine-control{ |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | gap: 8px; |
| | | padding: 8px 0; |
| | | border-bottom: 1px solid #f1f3f4; |
| | | } |
| | | .machine-control span{ |
| | | font-size: 14px; |
| | | white-space: nowrap; |
| | | color: #6c757d; |
| | | font-weight: 500; |
| | | } |
| | | .machine-metrics > div:not(.machine-control) { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 4px 0; |
| | | font-size: 14px; |
| | | } |
| | | .machine-metrics > div:not(.machine-control) span:first-child { |
| | | color: #6c757d; |
| | | } |
| | | .machine-metrics > div:not(.machine-control) span:last-child { |
| | | font-weight: 600; |
| | | color: #2c3e50; |
| | | } |
| | | .save-button-container{ |
| | | grid-column: 1 / -1; |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | gap: 16px; |
| | | margin-top: 16px; |
| | | padding-top: 16px; |
| | | border-top: 1px solid #e9ecef; |
| | | } |
| | | .loss-rate-container{ |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | } |
| | | .loss-rate-label{ |
| | | font-size: 14px; |
| | | color: #6c757d; |
| | | font-weight: 500; |
| | | white-space: nowrap; |
| | | } |
| | | </style> |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | |
| | | clearable |
| | | prefix-icon="Search" |
| | | /> |
| | | <span class="search_title ml10">项ç®åç§°ï¼</span> |
| | | <span class="search_title ml10">ååå·ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.projectName" |
| | | v-model="searchForm.salesContractNo" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | @change="handleQuery" |
| | | clearable |
| | | prefix-icon="Search" |
| | | /> |
| | | <!-- <span class="search_title ml10">项ç®åç§°ï¼</span>--> |
| | | <!-- <el-input--> |
| | | <!-- v-model="searchForm.projectName"--> |
| | | <!-- style="width: 240px"--> |
| | | <!-- placeholder="请è¾å
¥"--> |
| | | <!-- @change="handleQuery"--> |
| | | <!-- clearable--> |
| | | <!-- prefix-icon="Search"--> |
| | | <!-- />--> |
| | | <span class="search_title ml10">å½å
¥æ¥æï¼</span> |
| | | <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" |
| | | placeholder="è¯·éæ©" clearable @change="changeDaterange" /> |
| | |
| | | width: 120, |
| | | }, |
| | | { |
| | | label: "ååå·", |
| | | label: "éå®ååå·", |
| | | prop: "salesContractNo", |
| | | width: 220, |
| | | }, |
| | | { |
| | | label: "客æ·ååå·", |
| | | prop: "customerContractNo", |
| | | width: 250, |
| | | }, |
| | | // { |
| | | // label: "客æ·ååå·", |
| | | // prop: "customerContractNo", |
| | | // width: 250, |
| | | // }, |
| | | { |
| | | label: "客æ·åç§°", |
| | | prop: "customerName", |
| | | width: 250, |
| | | }, |
| | | { |
| | | label: "项ç®åç§°", |
| | | prop: "projectName", |
| | | width:300 |
| | | }, |
| | | // { |
| | | // label: "项ç®åç§°", |
| | | // prop: "projectName", |
| | | // width:300 |
| | | // }, |
| | | { |
| | | label: "仿¬¾ç¶æ", |
| | | prop: "status", |
| | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | customerName: "", |
| | | salesContractNo: "", |
| | | projectName: "", |
| | | entryDate: null, // å½å
¥æ¥æ |
| | | entryDateStart: undefined, |
| | | entryDateEnd: undefined, |
| | | status: "", |
| | | entryDate: [dayjs().format("YYYY-MM-DD"), dayjs().format("YYYY-MM-DD")], // å½å
¥æ¥æï¼é»è®¤å½å¤© |
| | | entryDateStart: dayjs().format("YYYY-MM-DD"), |
| | | entryDateEnd: dayjs().format("YYYY-MM-DD"), |
| | | }, |
| | | }); |
| | | const { searchForm } = toRefs(data); |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¾
ç产æ°éï¼" prop="pendingNum"> |
| | | <el-input v-model="form.pendingNum" placeholder="请è¾å
¥" clearable disabled/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¬æ¬¡ç产æ°éï¼" prop="finishedNum"> |
| | | <el-input-number |
| | | v-model="form.finishedNum" |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åä»·(å
)ï¼" prop="unitPrice"> |
| | | <el-input v-model="form.unitPrice" placeholder="请è¾å
¥" clearable @input="calculateTotalPrice"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¾
ç产æ°éï¼" prop="pendingNum"> |
| | | <el-input v-model="form.pendingNum" placeholder="请è¾å
¥" clearable disabled/> |
| | | <el-form-item label="æ»ä»·(å
)ï¼" prop="totalPrice"> |
| | | <el-input v-model="form.totalPrice" placeholder="请è¾å
¥" clearable disabled/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | v-model="form.schedulingUserId" |
| | | placeholder="éæ©äººå" |
| | | style="width: 100%;" |
| | | filterable |
| | | default-first-option |
| | | :reserve-keyword="false" |
| | | > |
| | | <el-option |
| | | v-for="user in userList" |
| | |
| | | finishedNum: "", |
| | | schedulingUserId: "", |
| | | schedulingDate: "", |
| | | unitPrice: "", |
| | | totalPrice: "", |
| | | }, |
| | | rules: { |
| | | schedulingNum: [{ required: true, message: "请è¾å
¥", trigger: "blur" },], |
| | |
| | | proxy.$modal.msgWarning('æ¬æ¬¡ç产æ°éä¸å¯å¤§äºæäº§æ°é') |
| | | } |
| | | form.value.pendingNum = form.value.schedulingNum - form.value.finishedNum; |
| | | calculateTotalPrice(); |
| | | } |
| | | |
| | | // è®¡ç®æ»ä»· |
| | | const calculateTotalPrice = () => { |
| | | const quantity = Number(form.value.finishedNum ?? 0); |
| | | const unitPrice = Number(form.value.unitPrice ?? 0); |
| | | |
| | | if (quantity > 0 && unitPrice > 0) { |
| | | form.value.totalPrice = (quantity * unitPrice).toFixed(2); |
| | | } else { |
| | | form.value.totalPrice = '0.00'; |
| | | } |
| | | } |
| | | // æäº¤äº§å表å |
| | | const submitForm = () => { |
| | |
| | | style="width: 200px;" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="项ç®åç§°:"> |
| | | <el-input v-model="searchForm.projectName" placeholder="请è¾å
¥" clearable prefix-icon="Search" |
| | | <el-form-item label="ååå·:"> |
| | | <el-input v-model="searchForm.salesContractNo" placeholder="请è¾å
¥" clearable prefix-icon="Search" |
| | | style="width: 200px;" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <!-- <el-form-item label="项ç®åç§°:">--> |
| | | <!-- <el-input v-model="searchForm.projectName" placeholder="请è¾å
¥" clearable prefix-icon="Search"--> |
| | | <!-- style="width: 200px;"--> |
| | | <!-- @change="handleQuery" />--> |
| | | <!-- </el-form-item>--> |
| | | <el-form-item label="æäº§æ¥æ:"> |
| | | <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" |
| | | placeholder="è¯·éæ©" clearable @change="changeDaterange" /> |
| | |
| | | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | staffName: "", |
| | | entryDate: null, // å½å
¥æ¥æ |
| | | entryDateStart: undefined, |
| | | entryDateEnd: undefined, |
| | | customerName: "", |
| | | salesContractNo: "", |
| | | projectName: "", |
| | | status: "", |
| | | entryDate: [dayjs().format("YYYY-MM-DD"), dayjs().format("YYYY-MM-DD")], // å½å
¥æ¥æï¼é»è®¤å½å¤© |
| | | entryDateStart: dayjs().format("YYYY-MM-DD"), |
| | | entryDateEnd: dayjs().format("YYYY-MM-DD"), |
| | | }, |
| | | }); |
| | | const { searchForm } = toRefs(data); |
| | |
| | | prop: "schedulingUserName", |
| | | }, |
| | | { |
| | | label: "产线", |
| | | prop: "productionLine", |
| | | }, |
| | | { |
| | | label: "ååå·", |
| | | prop: "salesContractNo", |
| | | width: 200, |
| | | }, |
| | | { |
| | | label: "客æ·ååå·", |
| | | prop: "customerContractNo", |
| | | width: 200, |
| | | }, |
| | | // { |
| | | // label: "客æ·ååå·", |
| | | // prop: "customerContractNo", |
| | | // width: 200, |
| | | // }, |
| | | { |
| | | label: "客æ·åç§°", |
| | | prop: "customerName", |
| | | width: 200, |
| | | }, |
| | | { |
| | | label: "项ç®åç§°", |
| | | prop: "projectName", |
| | | width:300 |
| | | }, |
| | | // { |
| | | // label: "项ç®åç§°", |
| | | // prop: "projectName", |
| | | // width:300 |
| | | // }, |
| | | { |
| | | label: "产å大类", |
| | | prop: "productCategory", |
| | |
| | | width: 150, |
| | | }, |
| | | { |
| | | label: "ç»å®æºå¨", |
| | | prop: "speculativeTradingName", |
| | | width: 220, |
| | | }, |
| | | { |
| | | label: "åä½", |
| | | prop: "unit", |
| | | }, |
| | | { |
| | | label: "å·¥åº", |
| | | prop: "process", |
| | | }, |
| | | // { |
| | | // label: "å£å³åç±»", |
| | | // prop: "type", |
| | | // width: 150, |
| | | // }, |
| | | { |
| | | label: "æè", |
| | | prop: "loss", |
| | | width: 150, |
| | | }, |
| | | { |
| | | label: "æäº§æ°é", |
| | |
| | | prop: "pendingFinishNum", |
| | | width: 100, |
| | | }, |
| | | { |
| | | label: "夿³¨", |
| | | prop: "remark", |
| | | width: 200, |
| | | }, |
| | | ]); |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | height="500" |
| | | :page="page" |
| | | @pagination="pagination" |
| | | > |
| | | </PIMTable> |
| | | <pagination |
| | | style="margin: 10px 0" |
| | | v-show="total > 0" |
| | | @pagination="paginationSearch" |
| | | :total="total" |
| | | :page="page.current" |
| | | :limit="page.size" |
| | | /> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | total: 0 |
| | | }); |
| | | const total = ref(0); |
| | | const tableData = ref([]); |
| | |
| | | currentId.value = row.id; |
| | | getList() |
| | | } |
| | | const paginationSearch = (obj) => { |
| | | const pagination = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | |
| | | const getList = () => { |
| | | qualityInspectFileListPage({inspectId: currentId.value}).then(res => { |
| | | tableData.value = res.data.records; |
| | | total.value = res.data.total; |
| | | page.total = res.data.total; |
| | | }) |
| | | } |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ£éªåï¼" prop="checkName"> |
| | | <el-select v-model="form.checkName" placeholder="è¯·éæ©" clearable> |
| | | <el-select v-model="form.checkName" filterable |
| | | default-first-option |
| | | :reserve-keyword="false" placeholder="è¯·éæ©" clearable> |
| | | <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" |
| | | :value="item.nickName"/> |
| | | </el-select> |
| | |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: "right", |
| | | width: 280, |
| | | width: 300, |
| | | operation: [ |
| | | { |
| | | name: "ç¼è¾", |
| | |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | height="500" |
| | | :page="page" |
| | | @pagination="pagination" |
| | | > |
| | | </PIMTable> |
| | | <pagination |
| | | style="margin: 10px 0" |
| | | v-show="total > 0" |
| | | @pagination="paginationSearch" |
| | | :total="total" |
| | | :page="page.current" |
| | | :limit="page.size" |
| | | /> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | |
| | | qualityInspectFileDel, |
| | | qualityInspectFileListPage |
| | | } from "@/api/qualityManagement/qualityInspectFile.js"; |
| | | import Pagination from "@/components/PIMTable/Pagination.vue"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | |
| | |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | total: 0 |
| | | }); |
| | | const total = ref(0); |
| | | const tableData = ref([]); |
| | |
| | | currentId.value = row.id; |
| | | getList() |
| | | } |
| | | const paginationSearch = (obj) => { |
| | | |
| | | const getList = () => { |
| | | qualityInspectFileListPage({inspectId: currentId.value}).then(res => { |
| | | tableData.value = res.data.records; |
| | | page.total = res.data.total; |
| | | }) |
| | | } |
| | | const pagination = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | const getList = () => { |
| | | qualityInspectFileListPage({inspectId: currentId.value}).then(res => { |
| | | tableData.value = res.data.records; |
| | | total.value = res.data.total; |
| | | }) |
| | | } |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ£éªåï¼" prop="checkName"> |
| | | <el-select v-model="form.checkName" placeholder="è¯·éæ©" clearable> |
| | | <el-select v-model="form.checkName" filterable |
| | | default-first-option |
| | | :reserve-keyword="false" placeholder="è¯·éæ©" clearable> |
| | | <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" |
| | | :value="item.nickName"/> |
| | | </el-select> |
| | |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: "right", |
| | | width: 280, |
| | | width: 300, |
| | | operation: [ |
| | | { |
| | | name: "ç¼è¾", |
| | |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | height="500" |
| | | :page="page" |
| | | @pagination="pagination" |
| | | > |
| | | </PIMTable> |
| | | <pagination |
| | | style="margin: 10px 0" |
| | | v-show="total > 0" |
| | | @pagination="paginationSearch" |
| | | :total="total" |
| | | :page="page.current" |
| | | :limit="page.size" |
| | | /> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="closeDia">åæ¶</el-button> |
| | |
| | | qualityInspectFileDel, |
| | | qualityInspectFileListPage |
| | | } from "@/api/qualityManagement/qualityInspectFile.js"; |
| | | import Pagination from "@/components/PIMTable/Pagination.vue"; |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | |
| | |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | total: 0 |
| | | }); |
| | | const total = ref(0); |
| | | const tableData = ref([]); |
| | |
| | | currentId.value = row.id; |
| | | getList() |
| | | } |
| | | const paginationSearch = (obj) => { |
| | | const pagination = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | |
| | | const getList = () => { |
| | | qualityInspectFileListPage({inspectId: currentId.value, ...page}).then(res => { |
| | | tableData.value = res.data.records; |
| | | total.value = res.data.total; |
| | | page.total = res.data.total; |
| | | }) |
| | | } |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: "right", |
| | | width: 280, |
| | | width: 300, |
| | | operation: [ |
| | | { |
| | | name: "ç¼è¾", |
| | |
| | | |
| | | <!-- è´¨éç»è®¡ --> |
| | | <div class="panel-header"> |
| | | <span class="panel-title">è´¨éç»è®¡</span> |
| | | <span class="panel-title">è¿4æè´¨éç»è®¡</span> |
| | | </div> |
| | | <div class="main-panel"> |
| | | <div class="panel-item-customers"> |
| | |
| | | </div> |
| | | |
| | | <div class="financial-header"> |
| | | <span class="financial-title">è´¢å¡åæ</span> |
| | | <span class="financial-title">è¿4æè´¢å¡åæ</span> |
| | | </div> |
| | | <div class="main-panel"> |
| | | <div class="panel-item-customers"> |
| | |
| | | <div class="panel-item-customers"> |
| | | <div style="display: flex;justify-content: space-between;margin-bottom: 20px;"> |
| | | <div class="section-title">åºæ¶åºä»ç»è®¡</div> |
| | | <el-radio-group v-model="radio1" size="large" @change="statisticsReceivable" class="custom-radio-group"> |
| | | <el-radio-button label="æå¨" :value="1" /> |
| | | <el-radio-button label="ææ" :value="2" /> |
| | | <el-radio-button label="æå£åº¦" :value="3" /> |
| | | </el-radio-group> |
| | | <!-- <el-radio-group v-model="radio1" size="large" @change="statisticsReceivable" class="custom-radio-group">--> |
| | | <!-- <el-radio-button label="æå¨" :value="1" />--> |
| | | <!-- <el-radio-button label="ææ" :value="2" />--> |
| | | <!-- <el-radio-button label="æå£åº¦" :value="3" />--> |
| | | <!-- </el-radio-group>--> |
| | | </div> |
| | | <Echarts ref="chart" |
| | | :color="barColors2" |
| | |
| | | |
| | | <!-- 忬¾ä¸å¼ç¥¨åæ --> |
| | | <div class="panel-header"> |
| | | <span class="panel-title">忬¾ä¸å¼ç¥¨åæ</span> |
| | | <span class="panel-title">è¿ä¸æå款ä¸å¼ç¥¨åæ</span> |
| | | </div> |
| | | <div class="panel-item-customers" style="padding-top: 60px;"> |
| | | <Echarts ref="chart" :chartStyle="chartStyle" :grid="grid" :legend="lineLegend" :series="lineSeries" |
| | |
| | | const barLegend = { |
| | | show: true, |
| | | textStyle: { color: '#B8C8E0' }, |
| | | data: ['åææä¸åæ ¼æ°', 'è¿ç¨ä¸åæ ¼æ°', 'åºåä¸åæ ¼æ°'] |
| | | data: ['åææåæ ¼æ°', 'è¿ç¨åæ ¼æ°', 'åºä¸åæ ¼æ°'] |
| | | } |
| | | const barLegend1 = { |
| | | show: true, |
| | |
| | | ]) |
| | | const barSeries1 = ref([ |
| | | { |
| | | name: 'åææä¸åæ ¼æ°', |
| | | name: 'åææåæ ¼æ°', |
| | | type: 'bar', |
| | | barGap: 0, |
| | | emphasis: { |
| | |
| | | data: [] |
| | | }, |
| | | { |
| | | name: 'è¿ç¨ä¸åæ ¼æ°', |
| | | name: 'è¿ç¨åæ ¼æ°', |
| | | type: 'bar', |
| | | emphasis: { |
| | | focus: 'series' |
| | |
| | | data: [] |
| | | }, |
| | | { |
| | | name: 'åºåä¸åæ ¼æ°', |
| | | name: 'åºååæ ¼æ°', |
| | | type: 'bar', |
| | | emphasis: { |
| | | focus: 'series' |
| | |
| | | getLedgerPage(params).then((res) => { |
| | | equipmentNum.value = res.data.total |
| | | }); |
| | | getRepairPage(params).then((res) => { |
| | | getRepairPage({...params, status:0}).then((res) => { |
| | | equipmentRepair.value = res.data.total |
| | | }); |
| | | getUpkeepPage(params).then((res) => { |
| | | getUpkeepPage({...params, status:0}).then((res) => { |
| | | equipmentMaintain.value = res.data.total |
| | | }); |
| | | measuringInstrumentListPage(params).then((res) => { |
| | |
| | | // 使ç¨nextTickç¡®ä¿DOMå®å
¨æ¸²æåååå§åå¾è¡¨ |
| | | nextTick(() => { |
| | | // åå§åautofitèªéåº |
| | | autofit.init({ dh: 1080, dw: 1920, el: '.data-dashboard', resize: true }, false) |
| | | autofit.init({ dh: 800, dw: 1280, el: '.data-dashboard', resize: true }, false) |
| | | |
| | | // æ·»å èªå¨æ»å¨å¨ç»ææ - 客æ·ä¿¡æ¯å表 |
| | | const contractList = refContractList.value |
| | |
| | | align: "center", |
| | | prop: "customerName", |
| | | }, |
| | | { |
| | | label: "项ç®åç§°", |
| | | align: "center", |
| | | prop: "projectName", |
| | | }, |
| | | // { |
| | | // label: "项ç®åç§°", |
| | | // align: "center", |
| | | // prop: "projectName", |
| | | // }, |
| | | { |
| | | label: "ååéé¢", |
| | | align: "center", |
| | |
| | | } |
| | | |
| | | onMounted(() => { |
| | | // è®¾ç½®ææ ç鿥æèå´é»è®¤å¼ä¸ºå½å¤© |
| | | const today = dayjs().format('YYYY-MM-DD') |
| | | indicatorFilter.dateRange = [today, today] |
| | | |
| | | nextTick(() => initIndicatorChart()) |
| | | }) |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog v-model="dialogVisible" title="éä»¶" width="40%" :before-close="handleClose"> |
| | | <el-table :data="tableData" border height="40vh"> |
| | | <el-table-column label="éä»¶åç§°" prop="name" min-width="400" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="æä½" width="150" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">ä¸è½½</el-button> |
| | | <el-button link type="primary" size="small" @click="lookFile(scope.row)">é¢è§</el-button> |
| | | <el-button link type="danger" size="small" @click="handleDelete(scope.row)">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-dialog> |
| | | <filePreview ref="filePreviewRef" /> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref } from 'vue' |
| | | import { ElMessageBox, ElMessage } from 'element-plus' |
| | | import filePreview from '@/components/filePreview/index.vue' |
| | | import { delCommonFileInvoiceLedger} from '@/api/publicApi/commonFile.js' |
| | | |
| | | const dialogVisible = ref(false) |
| | | const tableData = ref([]) |
| | | const { proxy } = getCurrentInstance(); |
| | | const filePreviewRef = ref() |
| | | const handleClose = () => { |
| | | dialogVisible.value = false |
| | | } |
| | | const open = (list) => { |
| | | dialogVisible.value = true |
| | | tableData.value = list |
| | | } |
| | | const downLoadFile = (row) => { |
| | | proxy.$download.name(row.url); |
| | | |
| | | } |
| | | const lookFile = (row) => { |
| | | filePreviewRef.value.open(row.url) |
| | | } |
| | | // å é¤éä»¶ |
| | | const handleDelete = (row) => { |
| | | ElMessageBox.confirm(`确认å é¤éä»¶"${row.name}"åï¼`, 'å é¤ç¡®è®¤', { |
| | | confirmButtonText: '确认', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning', |
| | | }).then(() => { |
| | | delCommonFileInvoiceLedger([row.id]).then(() => { |
| | | ElMessage.success('å 餿å') |
| | | // ä»å表ä¸ç§»é¤å·²å é¤çéä»¶ |
| | | const index = tableData.value.findIndex(item => item.id === row.id) |
| | | if (index !== -1) { |
| | | tableData.value.splice(index, 1) |
| | | } |
| | | }).catch(() => { |
| | | ElMessage.error('å é¤å¤±è´¥') |
| | | }) |
| | | }).catch(() => { |
| | | proxy.$modal.msg('已忶å é¤') |
| | | }) |
| | | } |
| | | defineExpose({ |
| | | open |
| | | }) |
| | | </script> |
| | | |
| | | <style></style> |
| | |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column label="éå®ååå·" prop="salesContractNo" show-overflow-tooltip width="180" /> |
| | | <el-table-column label="客æ·ååå·" prop="customerContractNo" show-overflow-tooltip width="180" /> |
| | | <el-table-column label="客æ·åç§°" prop="customerName" show-overflow-tooltip width="240" /> |
| | | <el-table-column label="项ç®" prop="projectName" width="320" /> |
| | | <!-- <el-table-column label="项ç®" prop="projectName" width="320" />--> |
| | | <el-table-column label="产å大类" prop="productCategory" width="200" /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" width="160" show-overflow-tooltip /> |
| | | <el-table-column label="å票å·" prop="invoiceNo" width="200" show-overflow-tooltip /> |
| | |
| | | <el-table-column label="å½å
¥äºº" prop="invoicePerson" show-overflow-tooltip /> |
| | | <el-table-column label="å½å
¥æ¥æ" prop="createTime" show-overflow-tooltip :formatter="formatDate" width="180" /> |
| | | <el-table-column label="å¼ç¥¨æ¥æ" prop="invoiceDate" show-overflow-tooltip width="120" /> |
| | | <el-table-column label="å票" prop="invoiceFileName" width="120" align="center" show-overflow-tooltip fixed="right"> |
| | | <!-- <el-table-column label="å票" prop="invoiceFileName" width="120" align="center" show-overflow-tooltip fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button v-if="scope.row.invoiceFileName" text bg type="primary" |
| | | @click="handleFile(scope.row.commonFiles)"> |
| | | æ¥çéä»¶ |
| | | </el-button> |
| | | <el-button v-else link type="primary" @click="handleDownload(scope.row)" :disabled="scope.row.invoicePerson !== userStore.nickName"> |
| | | <el-button v-else link type="primary" @click="handleDownload(scope.row)"> |
| | | ä¸ä¼ |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> --> |
| | | <el-table-column fixed="right" label="æä½" width="150" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="openForm(scope.row)" :disabled="scope.row.invoicePerson !== userStore.nickName">ç¼è¾</el-button> |
| | | <el-button link type="primary" size="small" @click="delInvoiceLedger(scope.row)" :disabled="scope.row.invoicePerson !== userStore.nickName">å é¤</el-button> |
| | | <el-button link type="primary" size="small" @click="openForm(scope.row)">ç¼è¾</el-button> |
| | | <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">éä»¶</el-button> |
| | | <el-button link type="primary" size="small" @click="delInvoiceLedger(scope.row)">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | <el-form-item label="éä»¶ææï¼" prop="remark"> |
| | | <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload |
| | | :headers="upload.headers" accept=".pdf" :limit="10" :before-upload="handleBeforeUpload" |
| | | :on-error="handleUploadError" :on-success="handleUploadSuccess" :on-remove="handleRemove"> |
| | | :on-error="handleUploadError" :on-success="handleUploadSuccess"> |
| | | <el-button type="primary">ä¸ä¼ </el-button> |
| | | <template #tip> |
| | | <!-- æä»¶æ ¼å¼æ¯æ docï¼docxï¼xlsï¼xlsxï¼pptï¼pptxï¼pdfï¼txtï¼xmlï¼jpgï¼jpegï¼pngï¼gifï¼bmpï¼rarï¼zipï¼7z--> |
| | |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <FileList ref="fileListRef" /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | commitFile, |
| | | registrationProductPage, |
| | | delInvoiceLedgerByRegProductId, |
| | | } from "../../../api/salesManagement/invoiceLedger.js"; |
| | | } from "@/api/salesManagement/invoiceLedger.js"; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import useFormData from "@/hooks/useFormData"; |
| | | import dayjs from "dayjs"; |
| | | import FileList from "./fileList.vue"; |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | const tableData = ref([]); |
| | |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | const { invoiceDate, ...rest } = searchForm; |
| | | registrationProductPage({ ...rest, ...page }).then((res) => { |
| | | // å°èå´æ¥æåæ®µä¼ éç»å端 |
| | | const params = { ...rest, ...page }; |
| | | // ç§»é¤å¼ç¥¨æ¥æçé»è®¤å¼è®¾ç½®ï¼åªä¿çèå´æ¥æå段 |
| | | delete params.invoiceDate; |
| | | registrationProductPage(params).then((res) => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records; |
| | | total.value = res.data.total; |
| | |
| | | invoiceLedgerProductInfo({ id: row.id }).then((res) => { |
| | | form.value = { ...res.data }; |
| | | fileList.value = res.data.fileList; |
| | | // ä¿åticketRegistrationIdå°è¡¨åæ°æ®ä¸ |
| | | if (row.ticketRegistrationId) { |
| | | form.value.ticketRegistrationId = row.ticketRegistrationId; |
| | | } |
| | | if (!form.value.invoicePerson) { |
| | | form.value.invoicePerson = userStore.nickName; |
| | | form.value.entryDate = getCurrentDate(); |
| | | // ç§»é¤å½å
¥æ¥æé»è®¤å¼è®¾ç½®ï¼åªå¤çèå´æ¥æå段 |
| | | } |
| | | if (!form.value.invoiceDate) { |
| | | form.value.invoiceDate = getCurrentDate(); |
| | | } |
| | | // ç§»é¤å¼ç¥¨æ¥æé»è®¤å¼è®¾ç½®ï¼åªå¤çèå´æ¥æå段 |
| | | }); |
| | | dialogFormVisible.value = true; |
| | | }; |
| | |
| | | }; |
| | | // ä¸ä¼ åæ ¡æ£ |
| | | function handleBeforeUpload(file) { |
| | | console.log("file", file); |
| | | // æ ¡æ£æä»¶å¤§å° |
| | | if (file.size > 1024 * 1024 * 10) { |
| | | proxy.$modal.msgError("ä¸ä¼ æä»¶å¤§å°ä¸è½è¶
è¿10MB!"); |
| | |
| | | proxy.$modal.msgError("æä»¶æ ¼å¼ä¸å¹é
"); |
| | | return false; |
| | | } |
| | | console.log('handleBeforeUpload'); |
| | | proxy.$modal.loading("æ£å¨ä¸ä¼ æä»¶ï¼è¯·ç¨å..."); |
| | | return true; |
| | | } |
| | |
| | | // ä¸ä¼ æååè° |
| | | function handleUploadSuccess(res, file, uploadFiles) { |
| | | proxy.$modal.closeLoading(); |
| | | console.log('handleUploadSuccess'); |
| | | if (res.code === 200) { |
| | | proxy.$refs["fileUpload"].handleRemove(file); |
| | | fileList.value.push(res.data); |
| | | proxy.$modal.msgSuccess("ä¸ä¼ æå"); |
| | | // å°ä¸ä¼ æåçæä»¶ä¿¡æ¯æ·»å å°fileListä¸ |
| | | const fileInfo = { |
| | | name: file.name, |
| | | url: res.data.url || file.response?.data?.url || file.url, |
| | | response: file.response |
| | | }; |
| | | // æ£æ¥æ¯å¦å·²åå¨ç¸åæä»¶ï¼é¿å
é夿·»å |
| | | const existingFileIndex = fileList.value.findIndex(f => f.name === fileInfo.name); |
| | | if (existingFileIndex === -1) { |
| | | fileList.value.push(fileInfo); |
| | | } else { |
| | | fileList.value[existingFileIndex] = fileInfo; |
| | | } |
| | | // ç¡®ä¿è¡¨åæ°æ®ä¸çfileList乿´æ° |
| | | form.value.fileList = fileList.value; |
| | | } else { |
| | | proxy.$modal.msgError(res.msg); |
| | | proxy.$refs.fileUpload.handleRemove(file); |
| | | } |
| | | } |
| | | // ç§»é¤æä»¶ |
| | | function handleRemove(file) { |
| | | let index = fileList.value.findIndex((item) => item.url === file.url); |
| | | if (index > -1) { |
| | | fileList.value.splice(index, 1); |
| | | } |
| | | } |
| | | // æäº¤è¡¨å |
| | |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | // æå¼éä»¶ä¸ä¼ å¼¹çª |
| | | const handleDownload = (val) => { |
| | | fileList.value = []; |
| | | uploadModal.value = true; |
| | | currentId.value = val.id; |
| | | }; |
| | | |
| | | // 确认æä»¶ä¸ä¼ |
| | |
| | | getList(); |
| | | }; |
| | | |
| | | //éä»¶ç¸å
³ |
| | | const fileListRef = ref(null) |
| | | //æ¥çéä»¶ |
| | | const downLoadFile = (row) => { |
| | | invoiceLedgerProductInfo({ id: row.id }).then((res) => { |
| | | fileListRef.value.open(res.data.fileList) |
| | | }); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | // 设置å¼ç¥¨æ¥æèå´é»è®¤å¼ä¸ºå½å¤© |
| | | const today = dayjs().format('YYYY-MM-DD'); |
| | | searchForm.invoiceDate = [today, today]; |
| | | // 设置èå´æ¥æå段çèµ·å§åç»ææ¶é´ |
| | | searchForm.invoiceDateStart = today; |
| | | searchForm.invoiceDateEnd = today; |
| | | getList(); |
| | | }); |
| | | </script> |
| | |
| | | @change="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="客æ·ååå·"> |
| | | <el-input |
| | | v-model="searchForm.customerContractNo" |
| | | placeholder="请è¾å
¥å®¢æ·ååå·" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="项ç®åç§°"> |
| | | <el-input |
| | | v-model="searchForm.projectName" |
| | | placeholder="请è¾å
¥é¡¹ç®åç§°" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-checkbox |
| | | v-model="searchForm.status" |
| | |
| | | label="éå®ååå·" |
| | | prop="salesContractNo" |
| | | show-overflow-tooltip |
| | | width="200" |
| | | /> |
| | | <el-table-column |
| | | label="客æ·ååå·" |
| | | prop="customerContractNo" |
| | | width="200" |
| | | show-overflow-tooltip |
| | | /> |
| | | <!-- <el-table-column--> |
| | | <!-- label="客æ·ååå·"--> |
| | | <!-- prop="customerContractNo"--> |
| | | <!-- width="200"--> |
| | | <!-- show-overflow-tooltip--> |
| | | <!-- />--> |
| | | <el-table-column |
| | | label="客æ·åç§°" |
| | | prop="customerName" |
| | | show-overflow-tooltip |
| | | width="240" |
| | | /> |
| | | <el-table-column label="ä¸å¡å" prop="salesman" show-overflow-tooltip width="90"/> |
| | | <el-table-column |
| | | label="项ç®åç§°" |
| | | prop="projectName" |
| | | show-overflow-tooltip |
| | | width="200" |
| | | /> |
| | | <el-table-column label="ä¸å¡å" prop="salesman" show-overflow-tooltip/> |
| | | <el-table-column |
| | | label="ååéé¢(å
)" |
| | | prop="contractAmount" |
| | | show-overflow-tooltip |
| | | :formatter="formattedNumber" |
| | | width="220" |
| | | |
| | | /> |
| | | <el-table-column |
| | |
| | | prop="invoiceTotal" |
| | | show-overflow-tooltip |
| | | :formatter="formattedNumber" |
| | | width="120" |
| | | /> |
| | | <el-table-column |
| | | label="æªå¼ç¥¨éé¢(å
)" |
| | |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éå®ååå·ï¼" prop="salesContractNo"> |
| | | <el-input v-model="form.salesContractNo" disabled></el-input> |
| | | <el-input v-model="form.salesContractNo" disabled placeholder="å¤ååæ¹éå¤çï¼å
·ä½ååå·è§äº§åå表ï¼"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | |
| | | <el-form-item label="ä¸å¡åï¼" prop="salesman"> |
| | | <el-input |
| | | v-model="form.salesman" |
| | | placeholder="èªå¨å¡«å
" |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="项ç®åç§°ï¼" prop="projectName"> |
| | | <el-input |
| | | v-model="form.projectName" |
| | | placeholder="èªå¨å¡«å
" |
| | | disabled |
| | | /> |
| | |
| | | type="index" |
| | | width="60" |
| | | /> |
| | | <el-table-column label="æå±åå" prop="salesContractNo" width="200"> |
| | | <template #default="{ row }"> |
| | | <el-tag type="primary">{{ row.salesContractNo }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="产å大类" prop="productCategory" /> |
| | | <el-table-column |
| | | label="è§æ ¼åå·" |
| | |
| | | createUer: undefined, // ç»è®°äºº |
| | | issueDate: undefined, // å¼ç¥¨æ¥æ |
| | | createTime: undefined, // å½å
¥æ¥æï¼ |
| | | productCategory: "", |
| | | isInvoice: 1 |
| | | }, |
| | | form: { |
| | | salesLedgerId: "", |
| | |
| | | invoiceNo: "", |
| | | createUer: userStore.nickName, |
| | | issueDate: dayjs().format("YYYY-MM-DD"), |
| | | selectedContractIds: [], // æ°å¢ï¼å卿æéä¸çååID |
| | | isBatch: false // æ°å¢ï¼æ è¯æ¯å¦ä¸ºæ¹éæä½ |
| | | }, |
| | | rules: { |
| | | salesLedgerId: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | createUer: [{ required: true, message: "è¯·éæ©", trigger: "blur" }], |
| | | issueDate: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | invoiceNo: [{ required: true, message: "请è¾å
¥", trigger: "change" }], |
| | |
| | | }; |
| | | // æå¼å¼¹æ¡ |
| | | const openForm = () => { |
| | | // 夿æ¯å¦å¤é |
| | | if (selectedRows.value.length != 1) { |
| | | proxy.$modal.msgError("è¯·éæ©ä¸æ¡åå"); |
| | | // 夿æ¯å¦éæ©äºåå |
| | | if (selectedRows.value.length === 0) { |
| | | proxy.$modal.msgError("请è³å°éæ©ä¸æ¡åå"); |
| | | return; |
| | | } |
| | | |
| | | // æ£æ¥ææéæ©çå忝å¦å
·æç¸åç客æ·åç§° |
| | | const firstRow = selectedRows.value[0]; |
| | | const isSameCustomer = selectedRows.value.every(row => |
| | | row.customerName === firstRow.customerName |
| | | ); |
| | | |
| | | if (!isSameCustomer) { |
| | | proxy.$modal.msgError("è¯·éæ©ç¸å客æ·åç§°çåå"); |
| | | return; |
| | | } |
| | | |
| | | // å
许ä¸åçéå®ååå·æ¹éå¤çï¼æ 鿣æ¥éå¤ |
| | | |
| | | form.value = {}; |
| | | productData.value = []; |
| | | getSalesLedgerWithProducts({ id: selectedRows.value[0].id }).then((res) => { |
| | | form.value = { ...res }; |
| | | |
| | | // å è½½ææéä¸ååçäº§åæ°æ® |
| | | const promises = selectedRows.value.map(row => |
| | | getSalesLedgerWithProducts({ id: row.id }) |
| | | ); |
| | | |
| | | Promise.all(promises).then(results => { |
| | | // åå¹¶ææååçäº§åæ°æ®ï¼å¹¶ä¸ºæ¯ä¸ªäº§åæ·»å 对åºçååä¿¡æ¯ |
| | | const allProductData = []; |
| | | results.forEach((result, index) => { |
| | | const contract = selectedRows.value[index]; |
| | | const contractId = contract.id; |
| | | if (result.productData) { |
| | | result.productData.forEach(item => { |
| | | allProductData.push({ |
| | | ...item, |
| | | id: contractId, // æç¡®è®¾ç½®ååID |
| | | salesContractNo: contract.salesContractNo, // æ·»å éå®ååå· |
| | | customerName: contract.customerName, // æ·»å 客æ·åç§° |
| | | customerContractNo: contract.customerContractNo // æ·»å 客æ·ååå· |
| | | }); |
| | | }); |
| | | } |
| | | }); |
| | | |
| | | // è®¾ç½®è¡¨åæ°æ®ï¼ä½¿ç¨ç¬¬ä¸ä¸ªååçåºæ¬ä¿¡æ¯ï¼éå®ååå·çç©ºï¼ |
| | | form.value = { ...results[0] }; |
| | | form.value.createTime = dayjs().format("YYYY-MM-DD"); |
| | | form.value.issueDate = dayjs().format("YYYY-MM-DD"); |
| | | form.value.createUer = userStore.nickName; |
| | | productData.value = form.value.productData.map((item) => { |
| | | return item; |
| | | }); |
| | | form.value.selectedContractIds = selectedRows.value.map(row => row.id); // å卿æéä¸çååID |
| | | form.value.salesContractNo = ""; // éå®ååå·ç空ï¼å 为ä¼å¨äº§åè¡¨æ ¼ä¸å嫿¾ç¤º |
| | | |
| | | productData.value = allProductData; |
| | | |
| | | dialogFormVisible.value = true; |
| | | console.log("productData.value ", productData.value); |
| | | }); |
| | |
| | | const submitForm = () => { |
| | | proxy.$refs["formRef"].validate((valid) => { |
| | | if (valid) { |
| | | form.value.productData = proxy.HaveJson(productData.value); |
| | | invoiceRegistrationSave(form.value).then((res) => { |
| | | // å¦ææ¯æ¹éæä½ï¼å°ææååçæ°æ®æ¾å¨ä¸ä¸ªæ°ç»éï¼åªè°ç¨ä¸æ¬¡æ¥å£ |
| | | if (selectedRows.value.length > 1) { |
| | | // å建å
嫿æååæ°æ®çæ°ç» |
| | | const batchData = selectedRows.value.map(contract => { |
| | | // çéåºå±äºå½åååçäº§åæ°æ® |
| | | const contractProductData = productData.value.filter(item => |
| | | item.salesLedgerId === contract.id |
| | | ); |
| | | |
| | | // 为æ¯ä¸ªéå®ååå·å建ç¬ç«ç对象 |
| | | return { |
| | | // åºç¡è¡¨åæ°æ® |
| | | issueDate: form.value.issueDate, |
| | | createTime: form.value.createTime, |
| | | createUer: form.value.createUer, |
| | | invoiceNo: form.value.invoiceNo, |
| | | |
| | | // ååå®é
ä¿¡æ¯ |
| | | id: contract.id, // 使ç¨idä½ä¸ºå段åï¼å¼ä¸ºsalesLedgerId |
| | | salesContractNo: contract.salesContractNo, // 使ç¨å®é
çéå®ååå· |
| | | customerName: contract.customerName, // 使ç¨å®é
ç客æ·åç§° |
| | | customerId: contract.customerId, // æ·»å 客æ·ID |
| | | customerContractNo: contract.customerContractNo, // 使ç¨å®é
ç客æ·ååå· |
| | | projectName: contract.projectName, // 使ç¨å®é
ç项ç®åç§° |
| | | salesman: contract.salesman, // 使ç¨å®é
çä¸å¡å |
| | | |
| | | // äº§åæ°æ® |
| | | productData: proxy.HaveJson(contractProductData), |
| | | |
| | | // æ¹éæ è¯ |
| | | isBatch: true |
| | | }; |
| | | }); |
| | | |
| | | // åªè°ç¨ä¸æ¬¡æ¥å£ï¼ä¼ éå
嫿æååæ°æ®çæ°ç» |
| | | invoiceRegistrationSave(batchData).then(() => { |
| | | proxy.$modal.msgSuccess("æ¹éæ°å¢æå"); |
| | | closeDia(); |
| | | getList(); |
| | | }); |
| | | } else { |
| | | // å个ååæäº¤é»è¾ - ä¹ä»¥æ°ç»å½¢å¼ä¼ é |
| | | const singleContract = selectedRows.value[0]; |
| | | const singleFormArray = [ |
| | | { |
| | | // åºç¡è¡¨åæ°æ® |
| | | issueDate: form.value.issueDate, |
| | | createTime: form.value.createTime, |
| | | createUer: form.value.createUer, |
| | | invoiceNo: form.value.invoiceNo, |
| | | |
| | | // ååå®é
ä¿¡æ¯ |
| | | id: singleContract.id, // 使ç¨idä½ä¸ºå段åï¼å¼ä¸ºsalesLedgerId |
| | | salesContractNo: singleContract.salesContractNo, // 使ç¨å®é
çéå®ååå· |
| | | customerName: singleContract.customerName, // 使ç¨å®é
ç客æ·åç§° |
| | | customerId: singleContract.customerId, // æ·»å 客æ·ID |
| | | customerContractNo: singleContract.customerContractNo, // 使ç¨å®é
ç客æ·ååå· |
| | | projectName: singleContract.projectName, // 使ç¨å®é
ç项ç®åç§° |
| | | salesman: singleContract.salesman, // 使ç¨å®é
çä¸å¡å |
| | | |
| | | // äº§åæ°æ® |
| | | productData: proxy.HaveJson(productData.value), |
| | | |
| | | // æ¹éæ è¯ |
| | | isBatch: false |
| | | } |
| | | ]; |
| | | invoiceRegistrationSave(singleFormArray).then((res) => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeDia(); |
| | | getList(); |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | |
| | | font-weight: bold; |
| | | } |
| | | </style> |
| | | |
| | | |
| | | |
| | | |
| | | |
| | |
| | | ¥{{ scope.row.amount.toFixed(2) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="paymentMethod" label="仿¬¾æ¹å¼" width="120" /> |
| | | <el-table-column prop="status" label="订åç¶æ" width="100"> |
| | | <template #default="scope"> |
| | | <el-tag :type="getStatusType(scope.row.status)"> |
| | |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="仿¬¾æ¹å¼" prop="paymentMethod"> |
| | | <el-select v-model="form.paymentMethod" placeholder="è¯·éæ©ä»æ¬¾æ¹å¼" style="width: 100%"> |
| | | <el-option label="å
¨æ¬¾å°ä»" value="å
¨æ¬¾å°ä»"></el-option> |
| | | <el-option label="åæä»æ¬¾" value="åæä»æ¬¾"></el-option> |
| | | <el-option label="æç»" value="æç»"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="订åç¶æ" prop="status"> |
| | | <el-select v-model="form.status" placeholder="è¯·éæ©ç¶æ" style="width: 100%"> |
| | |
| | | { |
| | | id: 1, |
| | | orderNo: 'ORD202312001', |
| | | customer: '䏿µ·ç§ææéå
¬å¸', |
| | | salesperson: 'éå¿å¼º', |
| | | customer: '广å·ç§æå
¬å¸', |
| | | salesperson: 'å¼ ä¸', |
| | | orderDate: '2023-12-01', |
| | | amount: 50000.00, |
| | | paymentMethod: 'å
¨æ¬¾å°ä»', |
| | | status: 'å¾
å®¡æ ¸', |
| | | remark: 'éè¦å®¢æ·è®¢å' |
| | | }, |
| | |
| | | salesperson: 'åé
å©·', |
| | | orderDate: '2023-12-02', |
| | | amount: 35000.00, |
| | | paymentMethod: 'åæä»æ¬¾', |
| | | status: 'å·²å®¡æ ¸', |
| | | remark: '常è§è®¢å' |
| | | }, |
| | |
| | | salesperson: 'ç建å½', |
| | | orderDate: '2023-12-03', |
| | | amount: 28000.00, |
| | | paymentMethod: 'æç»', |
| | | status: 'å·²åè´§', |
| | | remark: 'æ°å®¢æ·è®¢å' |
| | | } |
| | |
| | | salesperson: '', |
| | | orderDate: '', |
| | | amount: 0, |
| | | paymentMethod: '', |
| | | status: 'å¾
å®¡æ ¸', |
| | | remark: '' |
| | | }) |
| | |
| | | salesperson: [{ required: true, message: 'è¯·éæ©ä¸å¡å', trigger: 'change' }], |
| | | orderDate: [{ required: true, message: 'è¯·éæ©è®¢åæ¥æ', trigger: 'change' }], |
| | | amount: [{ required: true, message: '请è¾å
¥è®¢åéé¢', trigger: 'blur' }], |
| | | paymentMethod: [{ required: true, message: 'è¯·éæ©ä»æ¬¾æ¹å¼', trigger: 'change' }], |
| | | status: [{ required: true, message: 'è¯·éæ©ç¶æ', trigger: 'change' }] |
| | | } |
| | | |
| | |
| | | form.salesperson = '' |
| | | form.orderDate = '' |
| | | form.amount = 0 |
| | | form.paymentMethod = '' |
| | | form.status = 'å¾
å®¡æ ¸' |
| | | form.remark = '' |
| | | dialogVisible.value = true |
| | |
| | | ¥{{ scope.row.paidAmount }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="paymentMethod" label="仿¬¾æ¹å¼" width="120" /> |
| | | <el-table-column prop="paymentStatus" label="仿¬¾ç¶æ" width="100"> |
| | | <template #default="scope"> |
| | | <el-tag :type="getPaymentStatusType(scope.row.paymentStatus)"> |
| | |
| | | <el-col :span="12"> |
| | | <el-form-item label="订åéé¢" prop="orderAmount"> |
| | | <el-input-number v-model="form.orderAmount" :precision="2" :min="0" style="width: 100%"></el-input-number> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="仿¬¾æ¹å¼" prop="paymentMethod"> |
| | | <el-select v-model="form.paymentMethod" placeholder="è¯·éæ©ä»æ¬¾æ¹å¼" style="width: 100%"> |
| | | <el-option label="å
¨æ¬¾å°ä»" value="å
¨æ¬¾å°ä»"></el-option> |
| | | <el-option label="åæä»æ¬¾" value="åæä»æ¬¾"></el-option> |
| | | <el-option label="æç»" value="æç»"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | </el-form-item> |
| | | <el-form-item label="仿¬¾éé¢" prop="paymentAmount"> |
| | | <el-input-number v-model="paymentAmount" :precision="2" :min="0" :max="currentRecord.orderAmount" style="width: 100%"></el-input-number> |
| | | </el-form-item> |
| | | <el-form-item label="仿¬¾æ¹å¼" prop="paymentMethod"> |
| | | <el-select v-model="paymentMethod" placeholder="è¯·éæ©ä»æ¬¾æ¹å¼" style="width: 100%"> |
| | | <el-option label="ç°é" value="ç°é"></el-option> |
| | | <el-option label="é¶è¡è½¬è´¦" value="é¶è¡è½¬è´¦"></el-option> |
| | | <el-option label="æ¯ä»å®" value="æ¯ä»å®"></el-option> |
| | | <el-option label="微信æ¯ä»" value="微信æ¯ä»"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="仿¬¾å¤æ³¨" prop="paymentRemark"> |
| | | <el-input type="textarea" v-model="paymentRemark" rows="3" placeholder="请è¾å
¥ä»æ¬¾å¤æ³¨"></el-input> |
| | |
| | | orderNo: '', |
| | | customer: '', |
| | | orderAmount: 0, |
| | | paymentMethod: '', |
| | | paymentStatus: 'æªä»æ¬¾', |
| | | shippingStatus: 'å¾
åè´§', |
| | | shippingDate: '', |
| | |
| | | // orderNo: [{ required: true, message: '请è¾å
¥è®¢åå·', trigger: 'blur' }], |
| | | customer: [{ required: true, message: 'è¯·éæ©å®¢æ·', trigger: 'change' }], |
| | | orderAmount: [{ required: true, message: '请è¾å
¥è®¢åéé¢', trigger: 'blur' }], |
| | | paymentMethod: [{ required: true, message: 'è¯·éæ©ä»æ¬¾æ¹å¼', trigger: 'change' }], |
| | | paymentStatus: [{ required: true, message: 'è¯·éæ©ä»æ¬¾ç¶æ', trigger: 'change' }], |
| | | shippingStatus: [{ required: true, message: 'è¯·éæ©åè´§ç¶æ', trigger: 'change' }] |
| | | } |
| | |
| | | const shippingDialogVisible = ref(false) |
| | | const currentRecord = ref({}) |
| | | const paymentAmount = ref(0) |
| | | const paymentMethod = ref('') |
| | | const paymentRemark = ref('') |
| | | const shippingDate = ref('') |
| | | const logisticsCompany = ref('') |
| | |
| | | form.orderNo = '' |
| | | form.customer = '' |
| | | form.orderAmount = 0 |
| | | form.paymentMethod = '' |
| | | form.paymentStatus = 'æªä»æ¬¾' |
| | | form.shippingStatus = 'å¾
åè´§' |
| | | form.shippingDate = '' |
| | |
| | | const handlePayment = (row) => { |
| | | currentRecord.value = row |
| | | paymentAmount.value = row.orderAmount - row.paidAmount |
| | | paymentMethod.value = '' |
| | | paymentRemark.value = '' |
| | | paymentDialogVisible.value = true |
| | | } |
| | |
| | | } |
| | | |
| | | const savePayment = () => { |
| | | if (!paymentMethod.value) { |
| | | ElMessage.warning('è¯·éæ©ä»æ¬¾æ¹å¼') |
| | | return |
| | | } |
| | | currentRecord.value.paidAmount = Number(currentRecord.value.paidAmount) + paymentAmount.value |
| | | if(currentRecord.value.paidAmount == currentRecord.value.orderAmount){ |
| | | currentRecord.value.paymentStatus = '已仿¬¾' |
| | |
| | | prefix-icon="Search" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="客æ·ååå·"> |
| | | <el-input |
| | | v-model="searchForm.customerContractNo" |
| | | placeholder="请è¾å
¥" |
| | | @change="handleQuery" |
| | | clearable |
| | | prefix-icon="Search" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="项ç®åç§°"> |
| | | <el-input |
| | | v-model="searchForm.projectName" |
| | | placeholder="请è¾å
¥" |
| | | @change="handleQuery" |
| | | clearable |
| | | prefix-icon="Search" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-checkbox |
| | | v-model="searchForm.status" |
| | |
| | | size="small" |
| | | @click="changeEditType(scope.row)" |
| | | v-if="!scope.row.editType" |
| | | :disabled="scope.row.registrant !== userStore.nickName" |
| | | >ç¼è¾</el-button |
| | | > |
| | | <el-button |
| | |
| | | size="small" |
| | | @click="saveReceiptPayment(scope.row)" |
| | | v-if="scope.row.editType" |
| | | :disabled="scope.row.registrant !== userStore.nickName" |
| | | >ä¿å</el-button |
| | | > |
| | | <el-button |
| | |
| | | type="primary" |
| | | size="small" |
| | | @click="delReceiptRecord(scope.row)" |
| | | :disabled="scope.row.registrant !== userStore.nickName" |
| | | >å é¤</el-button |
| | | > |
| | | </template> |
| | |
| | | width="240" |
| | | /> |
| | | <el-table-column |
| | | label="客æ·ååå·" |
| | | prop="customerContractNo" |
| | | show-overflow-tooltip |
| | | width="240" |
| | | |
| | | /> |
| | | <el-table-column |
| | | label="客æ·åç§°" |
| | | prop="customerName" |
| | | show-overflow-tooltip |
| | | width="240" |
| | | /> |
| | | <el-table-column |
| | | label="项ç®åç§°" |
| | | prop="projectName" |
| | | show-overflow-tooltip |
| | | width="340" |
| | | /> |
| | | <el-table-column |
| | | label="忬¾ç¶æ" |
| | |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="产å大类" |
| | | prop="productCategory" |
| | | show-overflow-tooltip |
| | | width="100" |
| | | /> |
| | | <!-- <el-table-column--> |
| | | <!-- label="产å大类"--> |
| | | <!-- prop="productCategory"--> |
| | | <!-- show-overflow-tooltip--> |
| | | <!-- width="100"--> |
| | | <!-- />--> |
| | | <el-table-column |
| | | label="å票å·" |
| | | prop="invoiceNo" |
| | |
| | | v-model="form.registrant" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | console.log("selection", selection); |
| | | selectedRows.value = selection.filter( |
| | | (item) => item.customerContractNo !== null |
| | | ); |
| | | selectedRows.value = selection |
| | | }; |
| | | // 主表åè®¡æ¹æ³ |
| | | const summarizeMainTable = (param) => { |
| | |
| | | :prefix-icon="Search" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="客æ·ååå·"> |
| | | <el-input |
| | | v-model="searchForm.customerContractNo" |
| | | placeholder="è¾å
¥å®¢æ·ååå·" |
| | | @change="handleQuery" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="项ç®åç§°"> |
| | | <el-input |
| | | v-model="searchForm.projectName" |
| | | placeholder="è¾å
¥é¡¹ç®åç§°" |
| | | @change="handleQuery" |
| | | clearable |
| | | :prefix-icon="Search" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="忬¾æ¥æ"> |
| | | <el-date-picker |
| | | v-model="searchForm.receiptPaymentDate" |
| | |
| | | width:240 |
| | | }, |
| | | { |
| | | label: "客æ·ååå·", |
| | | prop: "customerContractNo", |
| | | width:240 |
| | | }, |
| | | { |
| | | label: "忬¾æ¥æ", |
| | | prop: "receiptPaymentDate", |
| | | width:100 |
| | |
| | | label: "客æ·åç§°", |
| | | prop: "customerName", |
| | | width:240 |
| | | }, |
| | | { |
| | | label: "项ç®åç§°", |
| | | prop: "projectName", |
| | | width:200 |
| | | }, |
| | | { |
| | | label: "忬¾éé¢ï¼å
ï¼", |
| | |
| | | receiptPaymentDate: [], |
| | | receiptPaymentDateStart: undefined, |
| | | receiptPaymentDateEnd: undefined, |
| | | customerContractNo: undefined, |
| | | projectName: undefined, |
| | | }); |
| | | const { receipt_payment_type } = proxy.useDict("receipt_payment_type"); |
| | | const isShowSummarySon = ref(true); |
| | |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | const { receiptPaymentDate, ...rest } = searchForm; |
| | | receiptPaymentHistoryListPage({ ...rest, ...page }).then((res) => { |
| | | // å°èå´æ¥æåæ®µä¼ éç»å端 |
| | | const params = { ...rest, ...page }; |
| | | // ç§»é¤åæ¬¾æ¥æçé»è®¤å¼è®¾ç½®ï¼åªä¿çèå´æ¥æå段 |
| | | delete params.receiptPaymentDate; |
| | | receiptPaymentHistoryListPage(params).then((res) => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.records; |
| | | page.total = res.total; |
| | |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | // è®¾ç½®åæ¬¾æ¥æèå´é»è®¤å¼ä¸ºå½å¤© |
| | | const today = dayjs().format('YYYY-MM-DD'); |
| | | searchForm.receiptPaymentDate = [today, today]; |
| | | // 设置èå´æ¥æå段çèµ·å§åç»ææ¶é´ |
| | | searchForm.receiptPaymentDateStart = dayjs(today).format('YYYY-MM-DD 00:00:00'); |
| | | searchForm.receiptPaymentDateEnd = dayjs(today).format('YYYY-MM-DD 23:59:59'); |
| | | getList(); |
| | | }); |
| | | </script> |
| | |
| | | <el-dialog v-model="dialogVisible" title="éä»¶" width="40%" :before-close="handleClose"> |
| | | <el-table :data="tableData" border height="40vh"> |
| | | <el-table-column label="éä»¶åç§°" prop="name" min-width="400" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="æä½" width="100" align="center"> |
| | | <el-table-column fixed="right" label="æä½" width="150" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">ä¸è½½</el-button> |
| | | <el-button link type="primary" size="small" @click="lookFile(scope.row)">é¢è§</el-button> |
| | | <el-button link type="danger" size="small" @click="handleDelete(scope.row)">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | |
| | | <script setup> |
| | | import { ref } from 'vue' |
| | | import { ElMessageBox, ElMessage } from 'element-plus' |
| | | import filePreview from '@/components/filePreview/index.vue' |
| | | import { delCommonFile } from '@/api/publicApi/commonFile.js' |
| | | |
| | | const dialogVisible = ref(false) |
| | | const tableData = ref([]) |
| | |
| | | const lookFile = (row) => { |
| | | filePreviewRef.value.open(row.url) |
| | | } |
| | | // å é¤éä»¶ |
| | | const handleDelete = (row) => { |
| | | ElMessageBox.confirm(`确认å é¤éä»¶"${row.name}"åï¼`, 'å é¤ç¡®è®¤', { |
| | | confirmButtonText: '确认', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning', |
| | | }).then(() => { |
| | | delCommonFile([row.id]).then(() => { |
| | | ElMessage.success('å 餿å') |
| | | // ä»å表ä¸ç§»é¤å·²å é¤çéä»¶ |
| | | const index = tableData.value.findIndex(item => item.id === row.id) |
| | | if (index !== -1) { |
| | | tableData.value.splice(index, 1) |
| | | } |
| | | }).catch(() => { |
| | | ElMessage.error('å é¤å¤±è´¥') |
| | | }) |
| | | }).catch(() => { |
| | | proxy.$modal.msg('已忶å é¤') |
| | | }) |
| | | } |
| | | defineExpose({ |
| | | open |
| | | }) |
| | |
| | | <el-input v-model="searchForm.customerName" placeholder="请è¾å
¥" clearable prefix-icon="Search" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="客æ·ååå·ï¼"> |
| | | <el-input v-model="searchForm.customerContractNo" placeholder="请è¾å
¥" clearable prefix-icon="Search" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="éå®ååå·ï¼"> |
| | | <el-input v-model="searchForm.salesContractNo" placeholder="请è¾å
¥" clearable prefix-icon="Search" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="项ç®åç§°ï¼"> |
| | | <el-input v-model="searchForm.projectName" placeholder="请è¾å
¥" clearable prefix-icon="Search" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="å½å
¥æ¥æï¼"> |
| | |
| | | </div> |
| | | <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange" |
| | | :expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" show-summary style="width: 100%" |
| | | :summary-method="summarizeMainTable" @expand-change="expandChange" height="calc(100vh - 18.5em)"> |
| | | :summary-method="summarizeMainTable" @expand-change="expandChange" height="calc(100vh - 21em)"> |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column type="expand"> |
| | | <template #default="props"> |
| | |
| | | </el-table-column> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column label="éå®ååå·" prop="salesContractNo" width="180" show-overflow-tooltip /> |
| | | <el-table-column label="客æ·ååå·" prop="customerContractNo" width="180" show-overflow-tooltip /> |
| | | <el-table-column label="客æ·åç§°" prop="customerName" width="300" show-overflow-tooltip /> |
| | | <el-table-column label="ä¸å¡å" prop="salesman" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="项ç®åç§°" prop="projectName" width="180" show-overflow-tooltip /> |
| | | <el-table-column label="仿¬¾æ¹å¼" prop="paymentMethod" show-overflow-tooltip /> |
| | | <el-table-column label="ååéé¢(å
)" prop="contractAmount" width="220" show-overflow-tooltip |
| | | :formatter="formattedNumber" /> |
| | | <el-table-column label="å½å
¥äºº" prop="entryPersonName" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å货车ç" prop="shippingCarNumber" width="120" show-overflow-tooltip> |
| | | <template #default="scope"> |
| | | <div> |
| | | <div v-if="scope.row.shippingCarNumber">{{ scope.row.shippingCarNumber }}</div> |
| | | <el-tag v-else type="warning">æªåè´§</el-tag> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åè´§æ¥æ" prop="shippingDate" width="120" show-overflow-tooltip /> |
| | | <el-table-column label="å½å
¥æ¥æ" prop="entryDate" width="120" show-overflow-tooltip /> |
| | | <el-table-column label="ç¾è®¢æ¥æ" prop="executionDate" width="120" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="æä½" min-width="200" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" :disabled="scope.row.invoiceTotal>0 || scope.row.entryPersonName !== userStore.nickName" @click="openForm('edit', scope.row)">ç¼è¾</el-button> |
| | | <el-button link type="primary" size="small" @click="openForm('edit', scope.row)">ç¼è¾</el-button> |
| | | <!-- <el-button link type="primary" size="small" @click="openForm('view', scope.row)">详æ
</el-button>--> |
| | | <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">éä»¶</el-button> |
| | | <el-button link type="primary" size="small" @click="openDeliveryForm(scope.row)">åè´§</el-button> |
| | | <el-button v-if="!scope.row.shippingCarNumber" link type="primary" size="small" @click="openDeliveryForm(scope.row)">åè´§</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¸å¡åï¼" prop="salesman"> |
| | | <el-select v-model="form.salesman" placeholder="è¯·éæ©" clearable :disabled="operationType === 'view'"> |
| | | <el-select v-model="form.salesman" filterable |
| | | default-first-option |
| | | :reserve-keyword="false" placeholder="è¯·éæ©" clearable :disabled="operationType === 'view'"> |
| | | <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" |
| | | :value="item.nickName" /> |
| | | </el-select> |
| | |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="客æ·ååå·ï¼" prop="customerContractNo"> |
| | | <el-input v-model="form.customerContractNo" placeholder="请è¾å
¥" clearable :disabled="operationType === 'view'"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="客æ·åç§°ï¼" prop="customerId"> |
| | | <el-select v-model="form.customerId" placeholder="è¯·éæ©" clearable :disabled="operationType === 'view'"> |
| | | <el-select v-model="form.customerId" placeholder="è¯·éæ©" clearable :disabled="operationType === 'view'" filterable> |
| | | <el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.id"> |
| | | {{ |
| | | item.customerName + "ââ" + item.taxpayerIdentificationNumber |
| | | }} |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="项ç®åç§°ï¼" prop="projectName"> |
| | | <el-input v-model="form.projectName" placeholder="请è¾å
¥" clearable :disabled="operationType === 'view'" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å½å
¥äººï¼" prop="entryPerson"> |
| | | <el-select v-model="form.entryPerson" placeholder="è¯·éæ©" clearable @change="changs" disabled> |
| | | <el-select v-model="form.entryPerson" filterable |
| | | default-first-option |
| | | :reserve-keyword="false" placeholder="è¯·éæ©" clearable @change="changs"> |
| | | <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" /> |
| | | </el-select> |
| | | </el-form-item> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="仿¬¾æ¹å¼"> |
| | | <el-input v-model="form.paymentMethod" placeholder="请è¾å
¥" clearable :disabled="operationType === 'view'" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row> |
| | | <el-form-item label="产åä¿¡æ¯ï¼" prop="entryDate"> |
| | | <el-button v-if="operationType !== 'view'" type="primary" @click="openProductForm('add')">æ·»å </el-button> |
| | |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column label="产å大类" prop="productCategory" /> |
| | | <el-table-column label="è§æ ¼åå·" prop="specificationModel" /> |
| | | <el-table-column label="ç»å®æºå¨" prop="speculativeTradingName" /> |
| | | <el-table-column label="åä½" prop="unit" /> |
| | | <el-table-column label="æ°é" prop="quantity" /> |
| | | <el-table-column label="ç¨ç(%)" prop="taxRate" /> |
| | |
| | | <el-select v-model="productForm.productModelId" placeholder="è¯·éæ©" clearable @change="getProductModel"> |
| | | <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="ç»å®æºå¨ï¼"> |
| | | <el-input v-model="productForm.speculativeTradingName" placeholder="请å
éæ©è§æ ¼åå·" clearable disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | <div v-for="(item, index) in printData" :key="index" class="print-page"> |
| | | <div class="delivery-note"> |
| | | <div class="header"> |
| | | <div class="company-name">é¼è¯çå®ä¸æé责任å
¬å¸</div> |
| | | <div class="company-name">æµ·å·å¼å¿é£åæéå
¬å¸</div> |
| | | <div class="document-title">é¶å®åè´§å</div> |
| | | </div> |
| | | |
| | |
| | | <span class="value">{{ formatDate(item.createTime) }}</span> |
| | | </div> |
| | | <div> |
| | | |
| | | <span class="label">客æ·åç§°ï¼</span> |
| | | <span class="value">{{ item.customerName || 'å¼ ç±æ' }}</span> |
| | | <span class="label">å货车çå·ï¼</span> |
| | | <span class="value">{{ item.shippingCarNumber }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="info-row"> |
| | | <div> |
| | | <span class="label">客æ·åç§°ï¼</span> |
| | | <span class="value">{{ item.customerName || 'å¼ ç±æ' }}</span> |
| | | </div> |
| | | <span class="label">åå·ï¼</span> |
| | | <span class="value">{{ item.salesContractNo }}</span> |
| | | </div> |
| | |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å货车çå·ï¼" prop="shippingCarNumber"> |
| | | <el-input |
| | | <el-select v-model="deliveryForm.shippingCarNumber" filterable allow-create placeholder="è¯·éæ©å货车çå·"> |
| | | <el-option key="1" label="æ°A H5153" value="æ°A H5153"/> |
| | | <el-option key="2" label="æ°A H4232" value="æ°A H4232"/> |
| | | <el-option key="3" label="æ°A H4001" value="æ°A H4001"/> |
| | | <el-option key="4" label="æ°A H6409" value="æ°A H6409"/> |
| | | <el-option key="5" label="æ°A G7446" value="æ°A G7446"/> |
| | | <el-option key="6" label="æ°H 80369" value="æ°H 80369"/> |
| | | </el-select> |
| | | <!-- <el-input |
| | | v-model="deliveryForm.shippingCarNumber" |
| | | placeholder="请è¾å
¥å货车çå·" |
| | | clearable |
| | | /> |
| | | /> --> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | customerName: "", // 客æ·åç§° |
| | | customerContractNo: "", // 客æ·ååç¼å· |
| | | salesContractNo: "", // éå®ååç¼å· |
| | | projectName: "", // 项ç®åç§° |
| | | entryDate: null, // å½å
¥æ¥æ |
| | | entryDateStart: undefined, |
| | | entryDateEnd: undefined, |
| | |
| | | form: { |
| | | salesContractNo: "", |
| | | salesman: "", |
| | | customerContractNo: "", |
| | | customerId: "", |
| | | projectName: "", |
| | | entryPerson: "", |
| | | entryDate: "", |
| | | maintenanceTime: "", |
| | | productData: [], |
| | | executionDate: "", |
| | | paymentMethod: "", |
| | | }, |
| | | rules: { |
| | | salesman: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | customerContractNo: [ |
| | | { required: true, message: "请è¾å
¥", trigger: "blur" }, |
| | | ], |
| | | customerId: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | projectName: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | entryPerson: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | entryDate: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | executionDate: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | |
| | | taxInclusiveTotalPrice: "", |
| | | taxExclusiveTotalPrice: "", |
| | | invoiceType: "", |
| | | speculativeTradingName: "", |
| | | }, |
| | | productRules: { |
| | | productCategory: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | // åªæå¨ç¹å»æç´¢æé®æ¶æé置页ç å°ç¬¬ä¸é¡µ |
| | | // é¿å
表ååæ®µchangeäºä»¶å¹²æ°å页 |
| | | if (arguments.length === 0) { |
| | | page.current = 1; |
| | | } |
| | | expandedRowKeys.value = []; |
| | | getList(); |
| | | }; |
| | |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | const { entryDate, ...rest } = searchForm; |
| | | ledgerListPage({ ...rest, ...page }) |
| | | // å°èå´æ¥æåæ®µä¼ éç»å端 |
| | | const params = { ...rest, ...page }; |
| | | // ç§»é¤å½å
¥æ¥æçé»è®¤å¼è®¾ç½®ï¼åªä¿çèå´æ¥æå段 |
| | | delete params.entryDate; |
| | | ledgerListPage(params) |
| | | .then((res) => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.records; |
| | |
| | | if (index !== -1) { |
| | | productForm.value.specificationModel = modelOptions.value[index].model; |
| | | productForm.value.unit = modelOptions.value[index].unit; |
| | | productForm.value.speculativeTradingName = modelOptions.value[index].speculativeTradingName || ""; |
| | | } else { |
| | | productForm.value.specificationModel = null; |
| | | productForm.value.unit = null; |
| | | productForm.value.speculativeTradingName = ""; |
| | | } |
| | | }; |
| | | const findNodeById = (nodes, productId) => { |
| | |
| | | // form.value.entryPerson = userAll.user.userId // 设置é»è®¤ä¸å¡å为å½åç¨æ· |
| | | // } |
| | | // }); |
| | | form.value.entryDate = getCurrentDate(); // 设置é»è®¤å½å
¥æ¥æä¸ºå½åæ¥æ |
| | | // ç§»é¤å½å
¥æ¥æé»è®¤å¼è®¾ç½®ï¼åªå¤çèå´æ¥æå段 |
| | | dialogFormVisible.value = true; |
| | | }; |
| | | function changs(val) { |
| | |
| | | <div class="print-page"> |
| | | <div class="delivery-note"> |
| | | <div class="header"> |
| | | <div class="company-name">é¼è¯çå®ä¸æé责任å
¬å¸</div> |
| | | <div class="company-name">æµ·å·å¼å¿é£åæéå
¬å¸</div> |
| | | <div class="document-title">é¶å®åè´§å</div> |
| | | </div> |
| | | |
| | |
| | | const openDeliveryForm = (row) => { |
| | | currentDeliveryRow.value = row; |
| | | deliveryForm.value = { |
| | | shippingDate: getCurrentDate(), |
| | | shippingDate: "", // ç§»é¤é»è®¤å¼è®¾ç½® |
| | | shippingCarNumber: "", |
| | | }; |
| | | deliveryFormVisible.value = true; |
| | |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | // 设置å½å
¥æ¥æèå´é»è®¤å¼ä¸ºå½å¤© |
| | | const today = dayjs().format('YYYY-MM-DD'); |
| | | searchForm.entryDate = [today, today]; |
| | | // 设置èå´æ¥æå段çèµ·å§åç»ææ¶é´ |
| | | searchForm.entryDateStart = today; |
| | | searchForm.entryDateEnd = today; |
| | | getList(); |
| | | }); |
| | | </script> |
| | |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="仿¬¾æ¹å¼" prop="paymentMethod"> |
| | | <el-select v-model="form.paymentMethod" placeholder="è¯·éæ©ä»æ¬¾æ¹å¼" style="width: 100%"> |
| | | <el-option label="å
¨æ¬¾å°ä»" value="å
¨æ¬¾å°ä»"></el-option> |
| | | <el-option label="åæä»æ¬¾" value="åæä»æ¬¾"></el-option> |
| | | <el-option label="æç»" value="æç»"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="交货æ" prop="deliveryPeriod"> |
| | | <el-date-picker |
| | | v-model="form.deliveryPeriod" |
| | |
| | | <el-descriptions-item label="ä¸å¡å">{{ currentQuotation.salesperson }}</el-descriptions-item> |
| | | <el-descriptions-item label="æ¥ä»·æ¥æ">{{ currentQuotation.quotationDate }}</el-descriptions-item> |
| | | <el-descriptions-item label="æææè³">{{ currentQuotation.validDate }}</el-descriptions-item> |
| | | <el-descriptions-item label="仿¬¾æ¹å¼">{{ currentQuotation.paymentMethod }}</el-descriptions-item> |
| | | <el-descriptions-item label="交货æ">{{ currentQuotation.deliveryPeriod }}</el-descriptions-item> |
| | | <!-- <el-descriptions-item label="æ¥ä»·ç¶æ">--> |
| | | <!-- <el-tag :type="getStatusType(currentQuotation.status)">{{ currentQuotation.status }}</el-tag>--> |
| | |
| | | salesperson: [{ required: true, message: 'è¯·éæ©ä¸å¡å', trigger: 'change' }], |
| | | quotationDate: [{ required: true, message: 'è¯·éæ©æ¥ä»·æ¥æ', trigger: 'change' }], |
| | | validDate: [{ required: true, message: 'è¯·éæ©æææ', trigger: 'change' }], |
| | | paymentMethod: [{ required: true, message: 'è¯·éæ©ä»æ¬¾æ¹å¼', trigger: 'change' }], |
| | | deliveryPeriod: [{ required: true, message: 'è¯·éæ©äº¤è´§æ', trigger: 'change' }] |
| | | } |
| | | const userList = ref([]); |
| | |
| | | const { VITE_APP_ENV } = env; |
| | | const baseUrl = |
| | | env.VITE_APP_ENV === "development" |
| | | ? "http://114.132.189.42:9036" |
| | | ? "http://192.168.1.147:7003" |
| | | : env.VITE_BASE_API; |
| | | const javaUrl = |
| | | env.VITE_APP_ENV === "development" |