gaoluyang
7 天以前 fab6326bf9df3c6db59718bad8f42b0212c73a9e
双奇点迁移仓库
已添加9个文件
已修改33个文件
5032 ■■■■■ 文件已修改
multiple/assets/favicon/SQDico.ico 补丁 | 查看 | 原始文档 | blame | 历史
multiple/assets/logo/SQDLogo.png 补丁 | 查看 | 原始文档 | blame | 历史
multiple/assets/screen/SQDView.png 补丁 | 查看 | 原始文档 | blame | 历史
multiple/config.json 418 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/inventoryManagement/stockIn.js 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/inventoryManagement/stockManage.js 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/salesManagement/salesLedger.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/PIMTable/PIMTable.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Upload/FileUpload.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/customerFile/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/product/ImportExcel/index.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/product/index.vue 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/supplierManage/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/noticeManagement/index.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/notificationManagement/index.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/customerService/feedbackRegistration/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/calibration/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index.vue 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/dispatchLog/index.vue 503 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/issueManagement/index.vue 305 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/receiptManagement/components/formDia.vue 398 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/receiptManagement/components/formDiaManual.vue 401 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue 303 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/receiptManagement/index.vue 1013 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/components/FormDiaManual.vue 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/components/FormDiaProduction.vue 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/components/FormDiaPurchase.vue 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/index.vue 591 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personnelManagement/contractManagement/filesDia.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/paymentEntry/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/paymentLedger/index.vue 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/procurementInvoiceLedger/Form/EditForm.vue 230 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/procurementInvoiceLedger/index.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/procurementLedger/index.vue 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionCosting/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionOrder/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionReporting/components/formDia.vue 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionReporting/index.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/invoiceLedger/index.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/receiptPayment/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/salesLedger/index.vue 115 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
multiple/assets/favicon/SQDico.ico
multiple/assets/logo/SQDLogo.png
multiple/assets/screen/SQDView.png
multiple/config.json
@@ -3,419 +3,19 @@
    "env": {
      "VITE_APP_TITLE": "芯导云(管理信息系统)"
    },
    "screen": "screen/JZYJView.png",
    "logo": "logo/HYSNLogo.png",
    "favicon": "favicon/HYSNico.ico"
    "screen": "screen/SQDView.png",
    "logo": "logo/SQDLogo.png",
    "favicon": "favicon/SQDico.ico"
  },
  "TEST": {
  "SQD": {
    "env": {
      "VITE_APP_TITLE": "中小企业数字化转型二级套餐包",
      "VITE_BASE_API": "http://114.132.189.42:9036",
      "VITE_JAVA_API": "http://114.132.189.42:9037"
    },
    "screen": "screen/HYSNView.png",
    "logo": "logo/ZGLTLogo.png",
    "favicon": "favicon/favicon.ico"
  },
  "LC": {
    "env": {
      "VITE_APP_TITLE": "中小企业数字化转型二级套餐包",
      "VITE_BASE_API": "http://114.132.189.42:9036",
      "VITE_JAVA_API": "http://114.132.189.42:9037"
    },
    "screen": "screen/HYSNView.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_APP_TITLE": "天津双奇点管理系统",
      "VITE_BASE_API": "http://114.132.189.42:9042",
      "VITE_JAVA_API": "http://114.132.189.42:9043"
      "VITE_JAVA_API": "http://114.132.189.42:9044"
    },
    "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"
  },
  "RTSW": {
    "env": {
      "VITE_APP_TITLE": "润泰生物信息管理系统",
      "VITE_BASE_API": "http://114.132.189.42:9066",
      "VITE_JAVA_API": "http://114.132.189.42:9064"
    },
    "screen": "screen/RTSWView.png",
    "logo": "logo/RTSWLogo.png",
    "favicon": "favicon/RTSWico.ico"
  },
  "HXSJ": {
    "env": {
      "VITE_APP_TITLE": "华玺砂浆信息管理系统",
      "VITE_BASE_API": "http://114.132.189.42:9066",
      "VITE_JAVA_API": "http://114.132.189.42:9062"
    },
    "screen": "screen/HXSJView.png",
    "logo": "logo/HXSJLogo.png",
    "favicon": "favicon/HXSJico.ico"
  },
  "QLMC": {
    "env": {
      "VITE_APP_TITLE": "祁连牧场信息管理系统",
      "VITE_BASE_API": "http://114.132.189.42:9066",
      "VITE_JAVA_API": "http://114.132.189.42:9060"
    },
    "screen": "screen/QLMCView.png",
    "logo": "logo/QLMCLogo.png",
    "favicon": "favicon/QLMCico.ico"
  },
  "AYNM": {
    "env": {
      "VITE_APP_TITLE": "安佑农牧信息管理系统",
      "VITE_BASE_API": "http://114.132.189.42:9066",
      "VITE_JAVA_API": "http://114.132.189.42:9058"
    },
    "screen": "screen/AYNMView.png",
    "logo": "logo/AYNMLogo.png",
    "favicon": "favicon/AYNMico.ico"
  },
  "JMSL": {
    "env": {
      "VITE_APP_TITLE": "金茂塑料包装信息管理系统",
      "VITE_BASE_API": "http://114.132.189.42:9066",
      "VITE_JAVA_API": "http://114.132.189.42:9058"
    },
    "screen": "screen/JMSLView.png",
    "logo": "logo/JMSLLogo.png",
    "favicon": "favicon/JMSLico.ico"
  },
  "TJKH": {
    "env": {
      "VITE_APP_TITLE": "天津凯华信息管理系统",
      "VITE_BASE_API": "http://114.132.189.42:9066",
      "VITE_JAVA_API": "http://114.132.189.42:9058"
    },
    "screen": "screen/TJKHView.png",
    "logo": "logo/TJKHLogo.png",
    "favicon": "favicon/TJKHico.ico"
  },
  "DZYS": {
    "env": {
      "VITE_APP_TITLE": "东泽印刷信息管理系统",
      "VITE_BASE_API": "http://114.132.189.42:9066",
      "VITE_JAVA_API": "http://114.132.189.42:9046"
    },
    "screen": "screen/DZYSView.png",
    "logo": "logo/DZYSLogo.png",
    "favicon": "favicon/DZYSico.ico"
    "screen": "screen/SQDView.png",
    "logo": "logo/SQDLogo.png",
    "favicon": "favicon/SQDico.ico"
  },
  "screen": "/src/assets/images/login-background.png",
  "logo": "/src/assets/logo/logo.png",
package.json
@@ -31,6 +31,7 @@
    "fuse.js": "6.6.2",
    "js-beautify": "1.14.11",
    "js-cookie": "3.0.5",
    "jsbarcode": "^3.12.1",
    "jsencrypt": "3.3.2",
    "nprogress": "0.2.0",
    "pinia": "2.1.7",
src/api/inventoryManagement/stockIn.js
@@ -9,6 +9,41 @@
    });
};
// æŸ¥è¯¢ç”Ÿäº§å…¥åº“信息列表
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({
@@ -26,6 +61,14 @@
        data,
    });
};
// ä¿®æ”¹ææ–™åº“存信息
export const updateManagementByCustom = (data) => {
    return request({
        url: "/stockin/updateManagementByCustom ",
        method: "post",
        data,
    });
};
// æ–°å¢žå•†å“å…¥åº“信息
export function addSutockIn(data) {
@@ -36,11 +79,46 @@
    })
}
// æ–°å¢žè‡ªå®šä¹‰å…¥åº“信息
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({
        url: '/stockin/del',
        method: 'post',
        data: ids
    })
}
// åˆ é™¤è‡ªå®šä¹‰å…¥åº“信息
export function delStockInCustom(ids) {
    return request({
        url: '/stockin/deleteCustom',
        method: 'delete',
        data: ids
    })
}
@@ -63,6 +141,23 @@
    })
}
// è‡ªå®šä¹‰å…¥åº“-详情
export function detailManagementByCustom(query) {
    return request({
        url: '/stockin/detailManagementByCustom',
        method: 'get',
        params: query
    })
}
// é‡‡è´­å…¥åº“-详情
export function stockinDetail(query) {
    return request({
        url: '/stockin/detail',
        method: 'get',
        params: query
    })
}
//
src/api/inventoryManagement/stockManage.js
@@ -9,6 +9,24 @@
    });
};
// æŸ¥è¯¢ç”Ÿäº§å…¥åº“库存信息列表
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) => {
@@ -38,7 +56,7 @@
    })
}
//出库接口
// å‡ºåº“管理-领用接口
export const stockOut = (data) => {
    return request({
        url: '/stockmanagement/stockout',
src/api/salesManagement/salesLedger.js
@@ -109,11 +109,3 @@
    params: query,
  });
}
// é”€å”®å°è´¦é¡µé¢å‘货,查询库存是否充足
export function getProductInventory(query) {
    return request({
        url: "/sales/ledger/getProductInventory",
        method: "get",
        params: query,
    });
}
src/components/PIMTable/PIMTable.vue
@@ -204,6 +204,7 @@
    </el-table-column>
  </el-table>
  <pagination
        v-if="isShowPage"
    :total="page.total"
    :layout="page.layout"
    :page="page.current"
@@ -267,6 +268,10 @@
    type: Boolean,
    default: false,
  },
    isShowPage: {
    type: Boolean,
    default: true,
  },
  isShowSummary: {
    type: Boolean,
    default: false,
src/components/Upload/FileUpload.vue
@@ -6,7 +6,7 @@
});
const props = defineProps({
  downloadTemplate: Function,
  // downloadTemplate: Function,
  showTips: Boolean,
  accept: {
    type: String,
@@ -31,7 +31,7 @@
    default: 1,
  },
});
const emits = defineEmits(["success", "remove"]);
const emits = defineEmits(["success", "remove",  "downloadTemplate"]);
const uploadRef = ref();
const fileList = ref([]);
@@ -85,7 +85,7 @@
          type="primary"
          link
          class="reset-margin"
          @click="props.downloadTemplate()"
          @click="emits('downloadTemplate')"
        >
          <span style="font-size: 12px; font-weight: normal">下载模板</span>
        </el-button>
src/views/basicData/customerFile/index.vue
@@ -306,6 +306,9 @@
        clickFun: (row) => {
          openForm("edit", row);
        },
                disabled: (row) => {
                    return row.maintainer !== userStore.nickName
                }
      },
    ],
  },
src/views/basicData/product/ImportExcel/index.vue
@@ -5,12 +5,13 @@
  <el-dialog v-model="upload.open" :title="upload.title">
    <FileUpload
      ref="fileUploadRef"
      accept=".xlsx, .xls"
      accept=".xlsx,.xls"
      :headers="upload.headers"
      :action="upload.url + '?updateSupport=' + upload.updateSupport"
      :disabled="upload.isUploading"
      :showTip="false"
      :showTip="true"
      @success="handleFileSuccess"
      @downloadTemplate="downloadTemplate"
    />
    <template #footer>
      <div class="dialog-footer">
@@ -22,11 +23,12 @@
</template>
<script setup>
import { reactive } from "vue";
import { reactive, ref, getCurrentInstance } from "vue";
import { getToken } from "@/utils/auth.js";
import { FileUpload } from "@/components/Upload";
import { ElMessage } from "element-plus";
const { proxy } = getCurrentInstance();
defineOptions({
  name: "产品维护导入",
});
@@ -44,6 +46,7 @@
  headers: { Authorization: "Bearer " + getToken() },
  // ä¸Šä¼ çš„地址
  url: import.meta.env.VITE_APP_BASE_API + "/system/supplier/import",
  updateSupport: true,
});
// ç‚¹å‡»å¯¼å…¥
const handleImport = () => {
@@ -51,6 +54,11 @@
  upload.title = "产品导入";
};
// ä¸‹è½½æ¨¡æ¿
const downloadTemplate = () =>{
  proxy.download("/basic/product/downloadTemplate", {}, "产品导入模板.xlsx");
}
const submitFileForm = () => {
  fileUploadRef.value.uploadApi();
};
src/views/basicData/product/index.vue
@@ -76,7 +76,7 @@
    <div class="right">
      <div style="margin-bottom: 10px" v-if="isShowButton">
        <el-button type="primary" @click="openModelDia('add')">
          æ–°å¢žè§„格型号
          æ–°å¢žäº§å“é«˜åº¦
        </el-button>
        <ImportExcel @uploadSuccess="getModelList" />
        <el-button
@@ -129,7 +129,7 @@
    </el-dialog>
    <el-dialog
      v-model="modelDia"
      title="规格型号"
      title="产品高度"
      width="400px"
      @close="closeModelDia"
      @keydown.enter.prevent
@@ -143,10 +143,10 @@
      >
        <el-row>
          <el-col :span="24">
            <el-form-item label="规格型号:" prop="model">
            <el-form-item label="产品高度:" prop="model">
              <el-input
                v-model="modelForm.model"
                placeholder="请输入规格型号"
                placeholder="请输入产品高度"
                clearable
                @keydown.enter.prevent
              />
@@ -155,10 +155,10 @@
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="单位:" prop="unit">
            <el-form-item label="高度单位:" prop="unit">
              <el-input
                v-model="modelForm.unit"
                placeholder="请输入单位"
                placeholder="请输入高度单位"
                clearable
                @keydown.enter.prevent
              />
@@ -205,11 +205,11 @@
const expandedKeys = ref([]);
const tableColumn = ref([
  {
    label: "规格型号",
    label: "产品高度",
    prop: "model",
  },
  {
    label: "单位",
    label: "高度单位",
    prop: "unit",
  },
  {
@@ -281,7 +281,7 @@
    form.value.productName = data.productName;
  }
};
// æ‰“开规格型号弹框
// æ‰“开产品高度弹框
const openModelDia = (type, data) => {
  modelOperationType.value = type;
  modelDia.value = true;
src/views/basicData/supplierManage/index.vue
@@ -299,6 +299,9 @@
        clickFun: (row) => {
          openForm("edit", row);
        },
                disabled: (row) => {
                    return row.maintainUserName !== userStore.nickName
                }
      },
    ],
  },
src/views/collaborativeApproval/noticeManagement/index.vue
@@ -624,6 +624,7 @@
  color: #606266;
  line-height: 1.6;
  font-size: 14px;
  word-wrap: break-word;
}
.card-footer {
@@ -704,6 +705,15 @@
  border-left: 3px solid #409eff;
}
.card-remark span {
  flex: 1;
  min-width: 0;
  word-wrap: break-word;
  word-break: break-all;
  white-space: normal;
  line-height: 1.5;
}
.empty-state {
  text-align: center;
  padding: 60px 20px;
src/views/collaborativeApproval/notificationManagement/index.vue
@@ -549,6 +549,7 @@
        clickFun: (row) => {
          publishNotification(row);
        },
        // disabled: (row) => row.status === "published"
      },
      {
        name: "撤回",
@@ -556,6 +557,7 @@
        clickFun: (row) => {
          revokeNotification(row);
        },
        // disabled: (row) => row.status !== "published"
      }
    ]
  }
src/views/customerService/feedbackRegistration/index.vue
@@ -121,7 +121,7 @@
                    openForm("edit", row);
                },
                disabled: (row) => {
                    return row.status !== 1
                    return row.checkUserId !== userStore.id || row.status !== 1
                }
            },
        ],
src/views/equipmentManagement/calibration/index.vue
@@ -142,6 +142,9 @@
                type: "text",
                clickFun: (row) => {
                    openCalibrationDia("edit", row);
                },
                disabled: (row) => {
                    return row.userId !== userStore.id
                }
            },
        ],
src/views/index.vue
@@ -24,11 +24,11 @@
                        <div class="data-num">
                            <div>
                                <div class="data-desc">本月销售额/元</div>
                                <div class="data-value">{{businessInfo.monthSaleMoney}}</div>
                                <div class="data-value" :title="businessInfo.monthSaleMoney">{{businessInfo.monthSaleMoney}}</div>
                            </div>
                            <div>
                                <div class="data-desc">未开票金额/元</div>
                                <div class="data-value">{{businessInfo.monthSaleHaveMoney}}</div>
                                <div class="data-value" :title="businessInfo.monthSaleHaveMoney">{{businessInfo.monthSaleHaveMoney}}</div>
                            </div>
                        </div>
                        
@@ -38,24 +38,24 @@
                        <div class="data-num">
                            <div>
                                <div class="data-desc">本月采购额/元</div>
                                <div class="data-value">{{businessInfo.monthPurchaseMoney}}</div>
                                <div class="data-value" :title="businessInfo.monthPurchaseMoney">{{businessInfo.monthPurchaseMoney}}</div>
                            </div>
                            <div>
                                <div class="data-desc">待付款金额/元</div>
                                <div class="data-value">{{businessInfo.monthPurchaseHaveMoney}}</div>
                                <div class="data-value" :title="businessInfo.monthPurchaseHaveMoney">{{businessInfo.monthPurchaseHaveMoney}}</div>
                            </div>
                        </div>
                    </div>
                    <div class="data-card inventory">
                        <div class="data-title">库存数据</div>
                        <div class="data-title">采购库存</div>
                        <div class="data-num">
                            <div>
                                <div class="data-desc">当前库存总量/ä»¶</div>
                                <div class="data-value">{{businessInfo.inventoryNum}}</div>
                                <div class="data-value" :title="businessInfo.inventoryNum">{{businessInfo.inventoryNum}}</div>
                            </div>
                            <div>
                                <div class="data-desc">今日入库/ä»¶</div>
                                <div class="data-value">{{businessInfo.todayInventoryNum}}</div>
                                <div class="data-value" :title="businessInfo.todayInventoryNum">{{businessInfo.todayInventoryNum}}</div>
                            </div>
                        </div>
                    </div>
@@ -287,7 +287,7 @@
    formatter: function (params) {
        // åŠ¨æ€ç”Ÿæˆæç¤ºä¿¡æ¯ï¼ŒåŸºäºŽæ•°æ®é¡¹çš„ name å±žæ€§
        const description = params.name === '本月回款金额' ? '本月回款金额' : '应收款金额';
        return `${description} ${formatNumber(params.value)}元 ${params.percent}%`;
        return `${description} ${formattedNumber(params.value)}元 ${params.percent}%`;
    },
    position: 'right'
})
@@ -365,6 +365,13 @@
        businessInfo.value = {...res.data}
    })
}
const formattedNumber = (row, column, cellValue) => {
    // å¦‚果只传了一个参数,直接格式化该参数
    if (column === undefined && cellValue === undefined) {
        return parseFloat(row).toFixed(2)
    }
    return parseFloat(cellValue).toFixed(2)
};
// åˆåŒé‡‘额
const analysisCustomer = () => {
    analysisCustomerContractAmounts().then((res) => {
@@ -425,7 +432,7 @@
    xAxis2.value[0].data = monthName.map(item => item.replace(/~/g, '\n~'));
    lineSeries.value = [
        {
            name: '开票',
            name: '回款',
            type: 'line',
            data: receiptAmount,
            stack: 'Total',
@@ -454,7 +461,7 @@
            showSymbol: true,
        },
        {
            name: '回款',
            name: '开票',
            type: 'line',
            data: invoiceAmount,
            stack: 'Total',
@@ -602,6 +609,9 @@
    color: #FFFFFF;
}
.data-value {
    max-width: 100px;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 18px;
    font-weight: 500;
    margin: 10px 0;
src/views/inventoryManagement/dispatchLog/index.vue
@@ -1,144 +1,208 @@
<template>
    <div class="app-container">
        <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"
                    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>
                <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"
                    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>
            <pagination
                v-show="total > 0"
                :total="total"
                layout="total, sizes, prev, pager, next, jumper"
                :page="page.current"
                :limit="page.size"
                @pagination="paginationChange"
            />
        </div>
        <el-tabs v-model="activeTab" @tab-change="handleTabChange">
            <!-- <el-tab-pane label="采购出库" name="production">
                <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" min-width="120" 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"
                        :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 @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 />
                        <el-table-column label="产品名称" prop="productCategory" show-overflow-tooltip />
                        <el-table-column label="产品高度" prop="specificationModel" width="100" show-overflow-tooltip>
                        <template #default="scope">
                            <div>{{ scope.row.specificationModel }}{{ scope.row.unit }}</div>
                        </template>
                        </el-table-column>
                        <el-table-column label="出库数量/ä»¶" prop="inboundNum" show-overflow-tooltip />
                        <el-table-column label="每件数量/支" prop="boxNum" width="100" show-overflow-tooltip />
                        <el-table-column label="单价(元)/支" prop="taxInclusiveUnitPrice" width="150"></el-table-column>
                        <el-table-column label="纸箱规格" prop="cartonSpecifications" 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-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="产品图片" width="100" align="center">
                            <template #default="scope">
                                <img class="barcode-img" :src="javaApiUrl+scope.row.url"></img>
                            </template>
                        </el-table-column>
                        <el-table-column label="出库日期" prop="createTime" width="150" show-overflow-tooltip />
                        <el-table-column label="产品名称" prop="productCategory" show-overflow-tooltip />
                        <el-table-column label="产品高度" prop="specificationModel" width="100" show-overflow-tooltip>
                        <template #default="scope">
                            <div>{{ scope.row.specificationModel }}{{ scope.row.unit }}</div>
                        </template>
                        </el-table-column>
                        <el-table-column label="出库数量/ä»¶" prop="inboundNum" width="150" show-overflow-tooltip />
                        <el-table-column label="每件数量/支" prop="boxNum" width="100" show-overflow-tooltip />
                        <el-table-column label="单价(美元)/ä»¶" prop="taxInclusiveUnitPrice" width="150"></el-table-column>
                        <el-table-column label="纸箱规格" prop="cartonSpecifications" width="150"></el-table-column>
                        <el-table-column label="出库人" prop="createBy" width="150" 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
@@ -163,7 +227,7 @@
                    <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>
                            
@@ -176,7 +240,7 @@
                                    <div>
                                        
                                        <span class="label">客户名称:</span>
                                        <span class="value">{{ item.supplierName || '张爱有' }}</span>
                                        <span class="value">{{ item.supplierName }}</span>
                                    </div>
                                </div>
                                <div class="info-row">
@@ -190,32 +254,32 @@
                                    <thead>
                                    <tr>
                                        <th>产品名称</th>
                                        <th>规格型号</th>
                                        <th>单位</th>
                                        <th>单价</th>
                                        <th>零售数量</th>
                                        <th>零售金额</th>
                                        <th>产品高度</th>
                                        <th>单价(美元)/ä»¶</th>
                                        <th>零售数量/ä»¶</th>
                                        <th>每件数量/支</th>
                                        <th>纸箱规格</th>
                                    </tr>
                                    </thead>
                                    <tbody>
                                    <tr>
                                        <td>{{ item.productCategory || '砂灰砖' }}</td>
                                        <td>{{ item.specificationModel || '标准' }}</td>
                                        <td>{{ item.unit || '块' }}</td>
                                        <td>{{ item.productCategory || '' }}</td>
                                        <td>{{ item.specificationModel || '' }}{{ item.unit || '' }}</td>
                                        <td>{{ item.taxInclusiveUnitPrice || '0' }}</td>
                                        <td>{{ item.inboundNum || '2000' }}</td>
                                        <td>{{ item.taxInclusiveTotalPrice || '0' }}</td>
                                        <td>{{ item.inboundNum || '0' }}</td>
                                        <td>{{ item.boxNum || '0' }}</td>
                                        <td>{{ item.cartonSpecifications || '0' }}</td>
                                    </tr>
                                    </tbody>
                                    <tfoot>
                                    <tr>
                                    <!-- <tr>
                                        <td class="label">合计</td>
                                        <td class="total-value"></td>
                                        <td class="total-value"></td>
                                        <td class="total-value"></td>
                                        <td class="total-value">{{ item.inboundNum || '2000' }}</td>
                                        <td class="total-value">{{ item.taxInclusiveTotalPrice || '0' }}</td>
                                    </tr>
                                    </tr> -->
                                    </tfoot>
                                </table>
                            </div>
@@ -258,17 +322,23 @@
<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 javaApiUrl = __BASE_API__;
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
const tableData = ref([]);
const activeTab = ref('purchase');
const selectedRows = ref([]);
const tableLoading = ref(false);
const page = reactive({
@@ -285,7 +355,9 @@
const data = reactive({
    searchForm: {
        supplierName: "",
        timeStr: "",
        customerName: "",
        productCategory:'',
        timeStr: getCurrentDate(),
    },
    form: {
        supplierId: null,
@@ -322,18 +394,56 @@
};
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 = getCurrentDate() // é‡ç½®ä¸ºå½“前日期
    selectedRows.value = []
      searchForm.value.productCategory = ''
    getList()
};
// è¡¨æ ¼é€‰æ‹©æ•°æ®
@@ -361,7 +471,14 @@
        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("已取消");
@@ -554,7 +671,7 @@
      <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>
          
@@ -566,49 +683,41 @@
              </div>
              <div>
                <span class="label">客户名称:</span>
                <span class="value">${item.supplierName || '张爱有'}</span>
                <span class="value">${item.supplierName}</span>
              </div>
            </div>
            <div class="info-row">
              <span class="label">单号:</span>
              <span class="value">${item.code || ''}</span>
              <span class="value">${item.code}</span>
            </div>
          </div>
          <div class="table-section">
            <table class="product-table">
              <thead>
                <tr>
                  <th>产品名称</th>
                  <th>规格型号</th>
                  <th>单位</th>
                  <th>单价</th>
                  <th>零售数量</th>
                  <th>零售金额</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td>${item.productCategory || '砂灰砖'}</td>
                  <td>${item.specificationModel || '标准'}</td>
                  <td>${item.unit || '块'}</td>
                  <td>${item.taxInclusiveUnitPrice || '0'}</td>
                  <td>${item.inboundNum || '2000'}</td>
                  <td>${item.taxInclusiveTotalPrice || '0'}</td>
                </tr>
              </tbody>
              <tfoot>
                <tr>
                  <td class="label">合计</td>
                  <td class="total-value"></td>
                  <td class="total-value"></td>
                  <td class="total-value"></td>
                  <td class="total-value">${item.inboundNum || '2000'}</td>
                  <td class="total-value">${item.taxInclusiveTotalPrice || '0'}</td>
                </tr>
              </tfoot>
            </table>
          </div>
            <table class="product-table">
                <thead>
                <tr>
                    <th>产品名称</th>
                    <th>产品高度</th>
                    <th>单价(美元)/ä»¶</th>
                    <th>零售数量/ä»¶</th>
                    <th>每件数量/支</th>
                    <th>纸箱规格</th>
                </tr>
                </thead>
                <tbody>
                <tr>
                    <td>{{ item.productCategory || '' }}</td>
                    <td>{{ item.specificationModel || '' }}{{ item.unit || '' }}</td>
                    <td>{{ item.taxInclusiveUnitPrice || '0' }}</td>
                    <td>{{ item.inboundNum || '0' }}</td>
                    <td>{{ item.boxNum || '0' }}</td>
                    <td>{{ item.cartonSpecifications || '0' }}</td>
                </tr>
                </tbody>
                <tfoot>
                </tfoot>
            </table>
        </div>
          <div class="footer-section">
            <div class="footer-row">
@@ -862,4 +971,12 @@
        page-break-after: avoid;
    }
}
.barcode-img{
  width: 80px;
  height: 80px;
  border-radius: 5px;
  background-color: #F5F5F5;
}
</style>
src/views/inventoryManagement/issueManagement/index.vue
@@ -1,67 +1,188 @@
<template>
  <div class="app-container">
    <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"
                    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" @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="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="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 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-tabs v-model="activeTab" @tab-change="handleTabChange">
      <!-- <el-tab-pane label="采购出库" name="production">
        <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>
          </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="createTime" width="100" 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 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-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>
         </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="100" show-overflow-tooltip />
            <el-table-column label="产品名称" prop="productCategory" show-overflow-tooltip />
            <el-table-column label="产品高度" prop="specificationModel" width="100" show-overflow-tooltip>
              <template #default="scope">
                <div>{{ scope.row.specificationModel }}{{ scope.row.unit }}</div>
              </template>
            </el-table-column>
                        <el-table-column label="入库数量/ä»¶" prop="inboundNum" width="100" show-overflow-tooltip />
                        <el-table-column label="每件数量/支" prop="boxNum" width="100" 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="cartonSpecifications" 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(scope.row);" :disabled="!scope.row.inboundNum0">领用</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="manual">
        <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"
              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>
          </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="产品图片" width="100" align="center">
              <template #default="scope">
                <img class="barcode-img" :src="javaApiUrl+scope.row.url"></img>
              </template>
            </el-table-column>
            <el-table-column label="入库时间" prop="inboundDate" width="100" show-overflow-tooltip />
            <el-table-column label="产品名称" prop="productCategory" show-overflow-tooltip />
            <el-table-column label="产品高度" prop="specificationModel" width="100" show-overflow-tooltip>
              <template #default="scope">
                <div>{{ scope.row.specificationModel }}{{ scope.row.unit }}</div>
              </template>
            </el-table-column>
                        <el-table-column label="入库数量/ä»¶" prop="inboundNum" width="100" show-overflow-tooltip />
                        <el-table-column label="每件数量/支" prop="boxNum" width="100" 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="cartonSpecifications" width="150"></el-table-column>
            <el-table-column label="入库人" prop="createBy" width="150" 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);" :disabled="!scope.row.inboundNum0">领用</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="'新增出库'" width="40%" @close="closeDia">
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
                <div>可出库数量:{{currentRowNum}}</div>
        <el-form-item label="出库数量:" prop="salesContractNo">
          <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="form.inboundQuantity" placeholder="请输入" clearable />
          <el-input-number :step="1" :min="0" :max="currentRowNum" style="width: 100%" v-model="form.inboundQuantity" placeholder="请输入" clearable />
        </el-form-item>
        <el-form-item label="出库日期:" 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-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>
@@ -78,18 +199,21 @@
<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,
    delStockManage,
    stockOut,
} from "@/api/inventoryManagement/stockManage.js";
const javaApiUrl = __BASE_API__;
const userStore = useUserStore()
const { proxy } = getCurrentInstance()
@@ -106,14 +230,17 @@
// ç”¨æˆ·ä¿¡æ¯è¡¨å•弹框数据
const dialogFormVisible = ref(false)
const activeTab = ref('purchase')
const data = reactive({
  searchForm: {
    supplierName: '',
    inboundQuantity:'',
    customerName: '',
    inboundQuantity:0,
    inboundTime:'',
    nickName: '',
    userId: '',
        timeStr: '',
    productCategory:'',
    timeStr: getCurrentDate(),
  },
  form: {
    productrecordId: '',
@@ -139,14 +266,40 @@
}
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 = getCurrentDate() // é‡ç½®ä¸ºå½“前日期
  selectedRows.value = []
  searchForm.value.productCategory = ''
  getList()
}
const findNodeById = (nodes, productId) => {
@@ -190,7 +343,7 @@
  // åˆå§‹åŒ–表单数据
  form.value = {
    productrecordId: '',
    inboundQuantity: '', // å‡ºåº“数量清空
    inboundQuantity: 0, // å‡ºåº“数量清空
    inboundTime: getCurrentDate(), // é»˜è®¤å½“前日期
    nickName: '', // é»˜è®¤å½“前用户
  }
@@ -208,16 +361,24 @@
const submitForm = () => {
  let num = Number(form.value.inboundQuantity)
  if(num <= 0 || num > currentRowNum.value){
    return proxy.$modal.msgWarning("请填入有效数字")
    return proxy.$modal.msgWarning("请填写出库数量")
  }
  if(!form.value.nickName){
    return proxy.$modal.msgWarning("请选择出库人")
  }
  if(!form.value.inboundTime){
    return proxy.$modal.msgWarning("请选择出库时间")
  }
  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)
@@ -247,7 +408,14 @@
    type: 'warning',
  }
  ).then(() => {
    proxy.download("/stockin/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("已取消")
  })
@@ -290,4 +458,11 @@
})
</script>
<style scoped lang="scss"></style>
<style scoped lang="scss">
  .barcode-img{
    width: 80px;
    height: 80px;
    border-radius: 5px;
    background-color: #F5F5F5;
  }
</style>
src/views/inventoryManagement/receiptManagement/components/formDia.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,398 @@
<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.msgWarning('本次入库数量不能大于待入库数量,且需大于0');
            return;
        }
        const stockInData = {
            ...form.value,
            inboundTime: formatDateTime(),
            nickName: userStore.nickName,
            details: selectedRows.value.map(product => ({
                id: product.id,
                inboundQuantity: Number(product.quantityStock),
                unitPrice: 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>
src/views/inventoryManagement/receiptManagement/components/formDiaManual.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,401 @@
<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="产品图片" align="center" prop="productCategory" width="100">
          <template #default="scope">
            <el-upload
              :action="uploadUrl"
              :before-upload="handleBeforeUpload"
              :on-success="(res,file)=>{handleUploadSuccess(res,file,scope.row)}"
              :on-error="handleUploadError"
              name="file"
              :show-file-list="false"
              :headers="headers"
              accept="image/*"
              :data="{ type: 9 }"
            >
              <img class="upload-img" v-if="scope.row.url" :src="javaApiUrl+scope.row.url"></img>
              <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
            </el-upload>
          </template>
        </el-table-column>
        <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="cartonSpecifications" width="200">
          <template #default="scope">
            <el-input v-model="scope.row.cartonSpecifications" placeholder="请输入纸箱规格" />
          </template>
        </el-table-column>
        <el-table-column label="入库数量-ä»¶" prop="inboundNum" width="150">
          <template #default="scope">
            <el-input-number :step="1" :min="0" style="width: 100%" v-model="scope.row.inboundNum" @change="() => calculateTotalPrice(scope.row)" />
          </template>
        </el-table-column>
        <el-table-column label="每件数量/支" prop="boxNum" width="150">
          <template #default="scope">
            <el-input-number :step="1" :min="0" style="width: 100%" v-model="scope.row.boxNum" @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="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="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";
import { getToken } from "@/utils/auth";
const headers = ref({
  Authorization: "Bearer " + getToken(),
});
const javaApiUrl = __BASE_API__;
const userStore = useUserStore()
const { proxy } = getCurrentInstance()
const emit = defineEmits(['close', 'success'])
const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // ä¸Šä¼ çš„图片服务器地址
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: '',
    cartonSpecifications:'',
    supplierName: form.value.supplierName || '',
    itemType: '',
    inboundNum: 0,
    inboundDate: '',
    quantityStock: 0,
    taxInclusiveUnitPrice: 0,
    taxInclusiveTotalPrice: 0,
    taxRate: null,
    taxExclusiveTotalPrice: 0,
    boxNum: 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) {
        proxy.$modal.msgError(`第${i + 1}行产品数据未填写完整(产品、产品高度、高度单位为必填)`)
        return
      }
      if (!product.url) {
        proxy.$modal.msgError(`第${i + 1}行产品未上传产品图片`)
        return
      }
      if (!product.cartonSpecifications) {
        proxy.$modal.msgError(`第${i + 1}行产品未填写纸箱规格`)
        return
      }
      // if (!product.itemType) {
      //   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 boxNum = Number(product?.boxNum ?? 0);
      if (!Number.isFinite(boxNum) || boxNum <= 0) {
        proxy.$modal.msgError(`第${i + 1}行每件数量/支需大于0`)
        return
      }
      const taxInclusiveUnitPrice = Number(product?.taxInclusiveUnitPrice ?? 0);
      if (!Number.isFinite(taxInclusiveUnitPrice) || taxInclusiveUnitPrice <= 0) {
        proxy.$modal.msgError(`第${i + 1}行单价(元)需大于0`)
        return
      }
      if (!product.inboundDate) {
        proxy.$modal.msgError(`第${i + 1}行请选择入库日期`)
        return
      }
    }
    const payloadList = productList.value.map(product => ({
      id: product.id ?? null,
            inboundNum: Number(product.inboundNum),
      productCategory: product.productCategory,
      specificationModel: product.specificationModel,
      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),
      boxNum:Number(product.boxNum),
      cartonSpecifications: product.cartonSpecifications,
      url: product.url||'',
    }));
    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')
}
// ä¸Šä¼ å‰æ ¡æ£€æ ¼å¼å’Œå¤§å°
function handleBeforeUpload(file) {
  const type = ["image/jpeg", "image/jpg", "image/png", "image/svg"];
  const isJPG = type.includes(file.type);
  //检验文件格式
  if (!isJPG) {
    proxy.$modal.msgError(`图片格式错误!`);
    return false;
  }
  return true;
}
const handleUploadSuccess = (res, file,item) => {
  // å¦‚果上传成功
  if (res.code == 200) {
    item.url = res.data?.tempPath||''
  } else {
    proxy.$modal.msgError("图片插入失败");
  }
}
// ä¸Šä¼ å¤±è´¥å¤„理
function handleUploadError() {
  proxy.$modal.msgError("图片插入失败");
}
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 ?? '',
      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),
      boxNum: Number(row?.boxNum ?? 0),
      cartonSpecifications: row?.cartonSpecifications ?? '',
      url: row?.url ?? '',
    }]
  }
}
defineExpose({
  openDialog,
})
</script>
<style scoped lang="scss">
  .upload-img{
    width: 80px;
    height: 80px;
    object-fit: contain;
  }
</style>
src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,303 @@
<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),
      dollarPrice: Number(row?.dollarPrice ?? 0),
    }]
  }
}
defineExpose({
  openDialog,
})
</script>
<style scoped lang="scss"></style>
src/views/inventoryManagement/receiptManagement/index.vue
@@ -1,129 +1,224 @@
<template>
  <div class="app-container">
    <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"
                    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" @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="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="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="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>
      <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-form-item label="采购订单号" prop="purchaseContractNumber">
              <el-select
                  v-model="form.purchaseContractNumber"
                  placeholder="请选择采购订单号"
                  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"
                />
              </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">
    <el-tabs v-model="activeTab" @tab-change="handleTabChange">
     <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>
       </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="100" show-overflow-tooltip />
          <el-table-column label="产品名称" prop="productCategory" show-overflow-tooltip />
          <el-table-column label="产品高度" prop="specificationModel" width="100" show-overflow-tooltip>
            <template #default="scope">
              <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.quantityStock" />
              <div>{{ scope.row.specificationModel }}{{ scope.row.unit }}</div>
            </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>
          <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="createBy" width="120" 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, 'purchase');">编辑</el-button>
                <!-- <el-button link type="success" size="small" @click="showQRCode(scope.row,1)">生成条形码</el-button>
                <el-button link type="success" size="small" @click="showERCode(scope.row,1)">生成二维码</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="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 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="产品图片" width="100" align="center">
              <template #default="scope">
                <img class="barcode-img" :src="javaApiUrl+scope.row.url"></img>
              </template>
            </el-table-column>
            <el-table-column label="入库时间" prop="inboundDate" width="100" show-overflow-tooltip />
            <el-table-column label="产品名称" prop="productCategory" show-overflow-tooltip />
            <el-table-column label="产品高度" prop="specificationModel" width="100" show-overflow-tooltip>
              <template #default="scope">
                <div>{{ scope.row.specificationModel }}{{ scope.row.unit }}</div>
              </template>
            </el-table-column>
                        <el-table-column label="入库数量/ä»¶" prop="inboundNum" width="100" show-overflow-tooltip />
                        <el-table-column label="每件数量/支" prop="boxNum" width="100" show-overflow-tooltip />
                        <el-table-column label="单价(元)/ä»¶" prop="taxInclusiveUnitPrice" width="150"></el-table-column>
                        <el-table-column label="纸箱规格" prop="cartonSpecifications" width="150"></el-table-column>
            <el-table-column label="入库人" prop="createBy" width="150" 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('edit', scope.row, 'manual');">编辑</el-button>
                <el-button link type="success" size="small" @click="showQRCode(scope.row,2)">生成条形码</el-button>
                <el-button link type="success" size="small" @click="showERCode(scope.row,2)">生成二维码</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>
    <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>
    <el-dialog
      v-model="qrCodeDialogVisible"
      title="商品条形码"
      width="400px"
      center
    >
      <div style="text-align: center;">
        <img id="barcode" style="width:200px;height: 50px;"/>
        <!-- <img :src="qrCodeUrl" alt="二维码" style="width:200px;height:200px;" /> -->
        <div style="margin: 20px;">
          <el-button type="primary" @click="downloadQRCode">下载条形码</el-button>
        </div>
      </div>
    </el-dialog>
    <!-- äºŒç»´ç æ˜¾ç¤ºå¯¹è¯æ¡† -->
    <el-dialog
      v-model="erCodeDialogVisible"
      title="商品二维码"
      width="400px"
      center
    >
      <div style="text-align: center;">
        <img :src="erCodeUrl" alt="二维码" style="width:200px;height:200px;" />
        <div style="margin: 20px;">
          <el-button type="primary" @click="downloadERCode">下载二维码图片</el-button>
        </div>
      </div>
    </el-dialog>
    <el-dialog v-model="barcodeDia" title="产品信息" width="40%" @close="closeBarcodeDia">
      <div>
        <el-row v-if="barcodeDetail.url" :gutter="30">
          <el-col :span="12">
            <div class="barcode-item">
              <div class="barcode-label">图片</div>
              <img class="barcode-img" :src="javaApiUrl+barcodeDetail.url"></img>
            </div>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <div class="barcode-item">
              <div class="barcode-label">名称</div>
              <div class="barcode-value">{{barcodeDetail.productCategory}}</div>
            </div>
          </el-col>
          <el-col :span="12">
            <div class="barcode-item">
              <div class="barcode-label">产品高度</div>
              <div class="barcode-value">{{barcodeDetail.specificationModel}}{{barcodeDetail.unit}}</div>
            </div>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <div class="barcode-item">
              <div class="barcode-label">单价</div>
              <div class="barcode-value">{{barcodeDetail.taxInclusiveUnitPrice}}美元/ä»¶</div>
            </div>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <div class="barcode-item">
              <div class="barcode-label">数量/ä»¶</div>
              <div class="barcode-value">{{barcodeDetail.inboundNum}}</div>
            </div>
          </el-col>
          <el-col :span="12">
            <div class="barcode-item">
              <div class="barcode-label">每件数量/支</div>
              <div class="barcode-value">{{barcodeDetail.boxNum}}</div>
            </div>
          </el-col>
        </el-row>
         <el-row :gutter="30">
          <el-col :span="12">
            <div class="barcode-item">
              <div class="barcode-label">纸箱规格</div>
              <div class="barcode-value">{{barcodeDetail.cartonSpecifications}}</div>
            </div>
          </el-col>
          <el-col :span="12">
            <div class="barcode-item">
              <div class="barcode-label">入库人</div>
              <div class="barcode-value">{{barcodeDetail.createBy}}</div>
            </div>
          </el-col>
        </el-row>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确认</el-button>
          <el-button @click="closeDia">取消</el-button>
          <el-button @click="closeBarcodeDia">关闭</el-button>
        </div>
      </template>
    </el-dialog>
@@ -132,31 +227,38 @@
<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'
const javaApiUrl = __BASE_API__;
import {
  getStockInPage,
  updateStockIn,
  addSutockIn,
  delStockIn,
  selectProductRecordListByPuechaserId
    getStockInPage,
    getStockInPageByProduction,
    delStockIn,
    delStockInCustom, getInPageByCustom,
  stockinDetail,detailManagementByCustom
} 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'
import QRCode from "qrcode";
import JsBarcode from "jsbarcode";
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('purchase') // å½“前激活的 tab
const page = reactive({
  current: 1,
@@ -164,107 +266,15 @@
})
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 = () => {
@@ -278,281 +288,320 @@
}
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
  }
  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
  }
// åˆ‡æ¢ tab
const handleTabChange = (tabName) => {
  page.current = 1
  // åˆ‡æ¢ tab æ—¶æ¸…空搜索条件
  searchForm.value.supplierName = ''
  searchForm.value.customerName = ''
  searchForm.value.timeStr = getCurrentDate() // é‡ç½®ä¸ºå½“前日期
  searchForm.value.productCategory = ''
  getList()
}
// æ‰“开弹框
  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 = [] // æ¸…空产品列表
    } 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
      }
const openForm = async (type, row, tabType) => {
  if(barcodeDia.value)return
  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 {
      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);
  }
const handleSelectionChange = (selection) => {
  selectedRows.value = selection.filter(item => item.id)
}
  const expandedRowKeys = ref([])
const expandedRowKeys = ref([])
// ä¸»è¡¨åˆè®¡æ–¹æ³•
  const summarizeMainTable = (param) => {
    return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']);
  };
const summarizeMainTable = (param) => {
  return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice'])
}
// å¯¼å‡º
  const handleOut = () => {
    ElMessageBox.confirm(
        '是否确认导出?',
        '导出', {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning',
        }
    ).then(() => {
      proxy.download("/stockin/export", {}, '入库台账.xlsx')
    }).catch(() => {
      proxy.$modal.msg("已取消")
    })
  }
const handleOut = () => {
  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"
    }
    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);
const handleDelete = () => {
  if (selectedRows.value.length === 0) {
    proxy.$modal.msgWarning('请选择数据')
    return
  }
  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 {
      proxy.$modal.msgWarning('请选择数据')
      // ææ–™å…¥åº“
      deleteApi = delStockInCustom
      deleteParams = [...ids]
    }
    deleteApi(deleteParams).then(() => {
      proxy.$modal.msgSuccess("删除成功")
      getList()
    }).catch(() => {
      proxy.$modal.msgError("删除失败")
    })
  }).catch(() => {
    proxy.$modal.msg("已取消")
  })
}
// äºŒç»´ç ç›¸å…³å˜é‡
const qrCodeDialogVisible = ref(false);
const qrCodeUrl = ref("");
const showQRCode = async (row,type) => {
  if(barcodeDia.value)return
  try {
    // æž„建二维码内容,只包含采购合同号(纯文本)
    let qrContent = row.id || '';
    // æ£€æŸ¥å†…容是否为空
    if (!qrContent) {
      proxy.$modal.msgWarning("该行商品id,无法生成条形码");
      return;
    }
    qrContent+=`,${type}`
    qrCodeDialogVisible.value = true;
    await nextTick();
    JsBarcode("#barcode", qrContent+'', {
      width:10,
      height:100,
      displayValue: false
    });
  } catch (error) {
    console.error('生成条形码失败:', error);
    proxy.$modal.msgError("生成条形码失败:" + error.message);
  }
};
const erCodeDialogVisible = ref(false);
const erCodeUrl = ref("");
const showERCode = async (row,type) => {
  if(barcodeDia.value)return
  let qrContent = row.id || '';
    // æ£€æŸ¥å†…容是否为空
  if (!qrContent) {
    proxy.$modal.msgWarning("该行商品id,无法生成二维码");
    return;
  }
  qrContent+=`,${type}`
  try {
    erCodeUrl.value = await QRCode.toDataURL(qrContent+'', {
      width: 200,
      margin: 2,
      color: {
        dark: '#000000',
        light: '#FFFFFF'
      }
    });
    erCodeDialogVisible.value = true;
  } catch (error) {
    console.error('生成二维码失败:', error);
    proxy.$modal.msgError("生成二维码失败:" + error.message);
  }
};
const downloadQRCode = () => {
  const imgSrc = document.getElementById('barcode').src
  const a = document.createElement('a');
  if(!imgSrc){
    proxy.$modal.msgWarning('暂无条形码')
    return
  }
  a.href = imgSrc;
  a.download = `商品条形码_${new Date().getTime()}.png`;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  proxy.$modal.msgSuccess("下载成功");
};
// ä¸‹è½½äºŒç»´ç 
const downloadERCode = () => {
  if (!erCodeUrl.value) {
    proxy.$modal.msgWarning("二维码未生成");
    return;
  }
  const a = document.createElement('a');
  a.href = erCodeUrl.value;
  a.download = `商品二维码_${new Date().getTime()}.png`;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  proxy.$modal.msgSuccess("下载成功");
};
//扫码相关参数
const barcodeDia = ref(false);
const scanBarcodeInput = ref('');
const barcodeDetail = ref({})
// æ‰«ç å‡½æ•°
function scanBarcode (e){
  if(!e||!e.target||!e.target.tagName){
    return;
  }
  if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') {
    return
  }
  if (e.key === 'Enter') {
    let _value = scanBarcodeInput.value
    getDetail(_value)
    scanBarcodeInput.value = ""
  } else {
    scanBarcodeInput.value += e.key
  }
}
const getDetail = (barcode)=>{
  if(barcode.indexOf(",")==-1){
    proxy.$modal.msgWarning("请扫描正确的条形码")
    return
  }
  let barcodeList = barcode.split(",")
  let barcodeId = barcodeList[0]
  let type = barcodeList[1]
  let detailApi = null
  if(type==1){
    detailApi = stockinDetail
  }else if(type==2){
    detailApi = detailManagementByCustom
  }
  if(!detailApi){
    proxy.$modal.msgWarning("请扫描正确的条形码")
    return
  }
  detailApi({id:barcodeId}).then((resp) => {
    if(!resp.data){
      proxy.$modal.msgError("商品不存在")
      return
    }
    ElMessageBox.confirm(
        '选中的内容将被删除,是否确认删除?',
        '导出', {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning',
        }
    ).then(() => {
      delStockIn({ids:ids}).then(res => {
        proxy.$modal.msgSuccess("删除成功")
        getList()
      })
    }).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()
    if(resp.code!=200){
      proxy.$modal.msgError(res.msg)
      return
    }
    barcodeDetail.value = resp.data
    barcodeDia.value = true
  }).catch(() => {
    proxy.$modal.msgError("查看详情失败")
  })
}
const closeBarcodeDia = () => {
  barcodeDia.value = false
}
onMounted(() => {
  // æ·»åŠ æ‰«ç æžªç›‘å¬äº‹ä»¶
  document.removeEventListener('keypress',scanBarcode)
  document.addEventListener('keypress', scanBarcode)
  getList()
})
</script>
<style scoped lang="scss"></style>
<style scoped lang="scss">
.barcode-item{
  display: flex;
  justify-content: space-between;
  padding: 5px 0;
}
.barcode-img{
  width: 80px;
  height: 80px;
  border-radius: 5px;
  background-color: #F5F5F5;
}
</style>
src/views/inventoryManagement/stockManagement/components/FormDiaManual.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,156 @@
<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-row>
      <el-row :gutter="30">
        <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-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-number :step="1" v-model="form.inboundNum" :min="form.totalInboundNum" style="width: 100%"
                                                             placeholder="请输入" clearable/>
          </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>
src/views/inventoryManagement/stockManagement/components/FormDiaProduction.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,147 @@
<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>
src/views/inventoryManagement/stockManagement/components/FormDiaPurchase.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,147 @@
<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>
src/views/inventoryManagement/stockManagement/index.vue
@@ -1,152 +1,201 @@
<template>
  <div class="app-container">
    <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"
                    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" @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="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="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 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>
      <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-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-tabs v-model="activeTab" @tab-change="handleTabChange">
      <!-- <el-tab-pane label="采购库存" name="production">
        <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>
          </div>
        </div>
      </template>
    </el-dialog>
        <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="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="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);">编辑</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">
          <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="productCategory" show-overflow-tooltip />
            <el-table-column label="产品高度" prop="specificationModel" width="100" show-overflow-tooltip>
              <template #default="scope">
                <div>{{ scope.row.specificationModel }}{{ scope.row.unit }}</div>
              </template>
            </el-table-column>
            <el-table-column label="每件数量/支" prop="boxNum" 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="totalInboundNum" width="100" show-overflow-tooltip />
            <el-table-column label="剩余库存" prop="inboundNum0" width="100" show-overflow-tooltip />
            <el-table-column label="纸箱规格" prop="cartonSpecifications" 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">供应商名称:</span>-->
            <!--            <el-input v-model="searchForm.supplierName" style="width: 240px" placeholder="请输入" @change="handleQuery"-->
            <!--              clearable prefix-icon="Search" />-->
            <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="产品图片" width="100" align="center">
              <template #default="scope">
                <img class="barcode-img" :src="javaApiUrl + scope.row.url"></img>
              </template>
            </el-table-column>
            <el-table-column label="产品名称" prop="productCategory" show-overflow-tooltip />
            <el-table-column label="产品高度" prop="specificationModel" width="100" show-overflow-tooltip>
              <template #default="scope">
                <div>{{ scope.row.specificationModel }}{{ scope.row.unit }}</div>
              </template>
            </el-table-column>
            <el-table-column label="单价(美元)/ä»¶" prop="taxInclusiveUnitPrice" width="150"></el-table-column>
            <el-table-column label="每件数量/支" prop="boxNum" width="100" show-overflow-tooltip />
            <el-table-column label="入库数量" prop="inboundNum" width="100" 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="cartonSpecifications" 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-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>
  <el-dialog v-model="barcodeDia" title="产品信息" width="70%" @close="closeBarcodeDia">
    <div>
      <el-row :gutter="30">
        <el-col :span="12">
          <div class="barcode-item">
            <div class="barcode-label">名称</div>
            <div class="barcode-value">{{ barcodeDetail.barcode }}</div>
          </div>
        </el-col>
        <el-col :span="12">
          <div class="barcode-item">
            <div class="barcode-label">单价</div>
            <div class="barcode-value">xxx元</div>
          </div>
        </el-col>
      </el-row>
      <el-row :gutter="30">
        <el-col :span="12">
          <div class="barcode-item">
            <div class="barcode-label">产品高度</div>
            <div class="barcode-value">222cm</div>
          </div>
        </el-col>
        <el-col :span="12">
          <div class="barcode-item">
            <div class="barcode-label">数量/ä»¶</div>
            <div class="barcode-value">120</div>
          </div>
        </el-col>
      </el-row>
      <el-row :gutter="30">
        <el-col :span="12">
          <div class="barcode-item">
            <div class="barcode-label">规格</div>
            <div class="barcode-value">12*20*30</div>
          </div>
        </el-col>
      </el-row>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="closeBarcodeDia">关闭</el-button>
      </div>
    </template>
  </el-dialog>
</template>
<script setup>
@@ -155,16 +204,22 @@
import { ElMessageBox } from "element-plus";
import useUserStore from '@/store/modules/user'
import { userListNoPageByTenantId } from "@/api/system/user.js";
import { productTreeList,modelList } from "@/api/basicData/product.js"
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";
const javaApiUrl = __BASE_API__;
// å¯¼å…¥ä¸‰ä¸ªç‹¬ç«‹çš„弹框组件
import FormDiaProduction from './components/FormDiaProduction.vue'
import FormDiaPurchase from './components/FormDiaPurchase.vue'
import FormDiaManual from './components/FormDiaManual.vue'
const userStore = useUserStore()
const { proxy } = getCurrentInstance()
@@ -185,15 +240,22 @@
const loading = ref(false);
// ç”¨æˆ·ä¿¡æ¯è¡¨å•弹框数据
const operationType = ref('')
const dialogFormVisible = ref(false)
const activeTab = ref('purchase')
// ä¸‰ä¸ªç‹¬ç«‹çš„弹框显示状态
const productionDialogVisible = ref(false)
const purchaseDialogVisible = ref(false)
const manualDialogVisible = ref(false)
const data = reactive({
  searchForm: {
    supplierName: '',
        timeStr: '',
    // supplierName: '',
    productCategory: '',
    customerName: '',
  },
  form: {
    supplierId: null,
    supplierName: '',
    // supplierName: '',
    productId: null,
    productName: '',
    userId: userStore.userId,
@@ -202,6 +264,7 @@
    model: '',
    unit: '',
    productrecordId: null,
    unitPrice: '', // æ·»åŠ æˆå“åº“å­˜çš„å•ä»·å­—æ®µ
    taxInclusiveUnitPrice: '',
    taxInclusiveTotalPrice: '',
    taxRate: '',
@@ -210,15 +273,16 @@
    inboundBatch: '',
    stockQuantity: '',
    boundTime: '',
        warnNum: '', // æ–°å¢žæœ€ä½Žåº“存字段
    warnNum: '', // æ–°å¢žæœ€ä½Žåº“存字段
    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' }],
@@ -226,7 +290,7 @@
    boundTime: [{ required: true, message: '请选择库存时间', trigger: 'change' }],
    inboundTime: [{ required: true, message: '请选择入库时间', trigger: 'change' }],
    inboundPerson: [{ required: true, message: '请选择出库人', trigger: 'change' }],
        warnNum: [{ required: true, message: '请输入最低库存', trigger: 'blur' }],
    warnNum: [{ required: true, message: '请输入最低库存', trigger: 'blur' }],
  }
})
const { searchForm, form, rules } = toRefs(data)
@@ -242,17 +306,75 @@
  page.size = obj.limit;
  getList()
}
const buildQueryParams = () => {
  const params = {
    ...page,
  }
  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 = ''
  selectedRows.value = []
  searchForm.value.productCategory = ''
  getList()
}
// è¡¨æ ¼é€‰æ‹©æ•°æ®
@@ -288,9 +410,9 @@
  userList.value = userLists.data
  if (type === 'edit') {
    form.value = { ...row }
    productTreeList().then(res =>{
    productTreeList().then(res => {
      productList.value = res
      productList.value.forEach(i =>{
      productList.value.forEach(i => {
        if (i.label === row.productCategory) {
          modelList({ id: i.id }).then((res) => {
            productModelList.value = res;
@@ -300,23 +422,63 @@
    })
  }
  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 => {
        proxy.$modal.msgSuccess("提交成功")
        closeDia()
        getList()
        // æäº¤åŽæ£€æŸ¥åº“存并尝试创建请购单
        // checkStockAndCreatePurchase();
      })
    }
  // ä½¿ç”¨å­ç»„件提交的数据,而不是父组件的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)
  submitData.inboundNum = parseFloat(submitData.inboundNum) || 0
  // æ ¹æ®å½“前标签页调用不同的提交接口
  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("提交失败,请重试")
  })
}
// æ£€æŸ¥åº“存并创建请购单
@@ -344,7 +506,9 @@
// å…³é—­å¼¹æ¡†
const closeDia = () => {
  proxy.resetForm("formRef")
  dialogFormVisible.value = false
  productionDialogVisible.value = false
  purchaseDialogVisible.value = false
  manualDialogVisible.value = false
}
// å¯¼å‡º
@@ -357,7 +521,15 @@
    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("已取消")
  })
@@ -366,12 +538,6 @@
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('请选择数据')
@@ -385,7 +551,7 @@
    type: 'warning',
  }
  ).then(() => {
    delStockManage({ids:ids}).then(res => {
    delStockManage({ ids: ids }).then(res => {
      proxy.$modal.msgSuccess("删除成功")
      getList()
    })
@@ -401,16 +567,54 @@
  const day = String(today.getDate()).padStart(2, '0');
  return `${year}-${month}-${day}`;
}
//扫码相关参数
const barcodeDia = ref(false);
const scanBarcodeInput = ref('');
const barcodeDetail = ref({})
// æ‰«ç å‡½æ•°
const scanBarcode = (e) => {
  if (!e || !e.target || !e.target.tagName) {
    return;
  }
  if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') {
    return
  }
  if (e.key === 'Enter') {
    let _value = scanBarcodeInput.value
    getDetail(_value)
    scanBarcodeInput.value = ""
  } else {
    scanBarcodeInput.value += e.key
  }
}
const getDetail = (barcode) => {
  barcodeDetail.value = {
    barcode: barcode
  }
  barcodeDia.value = true
}
const closeBarcodeDia = () => {
  barcodeDia.value = false
}
onMounted(() => {
  // æ·»åŠ æ‰«ç æžªç›‘å¬äº‹ä»¶
  // document.addEventListener('keypress', scanBarcode)
  getList()
  // checkStockAndCreatePurchase();
    // æ¯å°æ—¶æ£€æŸ¥ä¸€æ¬¡åº“å­˜
    // const intervalId = setInterval(checkStockAndCreatePurchase, 60 * 60 * 1000);
  // æ¯å°æ—¶æ£€æŸ¥ä¸€æ¬¡åº“å­˜
  // const intervalId = setInterval(checkStockAndCreatePurchase, 60 * 60 * 1000);
// onUnmounted(() => {
//   // ç»„件卸载时清除定时器
//   clearInterval(intervalId);
// });
  // onUnmounted(() => {
  //   // ç»„件卸载时清除定时器
  //   clearInterval(intervalId);
  // });
})
onUnmounted(() => {
  // ç§»é™¤é”®ç›˜ç›‘听事件
  document.removeEventListener('keypress', scanBarcode)
  console.log('组件卸载')
})
</script>
@@ -423,4 +627,17 @@
:deep(.row-low-stock:hover > td) {
  background-color: #fcd4d4;
}
</style>
.barcode-item {
  display: flex;
  justify-content: space-between;
  padding: 5px 0;
}
.barcode-img {
  width: 80px;
  height: 80px;
  border-radius: 5px;
  background-color: #F5F5F5;
}
</style>
src/views/personnelManagement/contractManagement/filesDia.vue
@@ -28,6 +28,7 @@
          :tableData="tableData"
          :tableLoading="tableLoading"
          :isSelection="true"
                    :isShowPage="false"
          @selection-change="handleSelectionChange"
          height="500"
      >
src/views/procurementManagement/paymentEntry/index.vue
@@ -104,6 +104,7 @@
                                    size="small"
                                    @click="changeEditType(scope.row)"
                                    v-if="!scope.row.editType"
                                    :disabled="scope.row.registrant !== userStore.nickName"
                                >编辑</el-button
                                >
                                <el-button
@@ -112,6 +113,7 @@
                                    size="small"
                                    @click="saveReceiptPayment(scope.row)"
                                    v-if="scope.row.editType"
                                    :disabled="scope.row.registrant !== userStore.nickName"
                                >保存</el-button
                                >
                                <el-button
@@ -119,6 +121,7 @@
                                    type="primary"
                                    size="small"
                                    @click="handleDelete(scope.row)"
                                    :disabled="scope.row.registrant !== userStore.nickName"
                                >删除</el-button
                                >
                            </template>
src/views/procurementManagement/paymentLedger/index.vue
@@ -86,7 +86,8 @@
            :tableLoading="tableLoadingSon"
            :isShowSummary="isShowSummarySon"
            :summaryMethod="summarizeMainTable1"
                        height="calc(100vh - 18.5em)"
            :isShowPage="false"
            height="calc(100vh - 18.5em)"
          >
            <template #payableAmountSlot="{ row }">
              <el-text type="danger">
@@ -94,14 +95,14 @@
              </el-text>
            </template>
          </PIMTable>
          <pagination
            v-show="sonTotal > 0"
            :total="sonTotal"
            @pagination="sonPaginationSearch"
            :layout="page.layout"
            :page="sonPage.current"
            :limit="sonPage.size"
          />
<!--          <pagination-->
<!--            v-show="sonTotal > 0"-->
<!--            :total="sonTotal"-->
<!--            @pagination="sonPaginationSearch"-->
<!--            :layout="page.layout"-->
<!--            :page="sonPage.current"-->
<!--            :limit="sonPage.size"-->
<!--          />-->
        </div>
      </el-col>
    </el-row>
@@ -245,8 +246,6 @@
  paymentLedgerList({
    ...searchForm.value,
    ...page,
    detailPageNum: detailPageNum.value, // æ–°å¢ž
    detailPageSize: detailPageSize.value, // æ–°å¢ž
  }).then((res) => {
    let result = res.data;
    tableLoading.value = false;
src/views/procurementManagement/procurementInvoiceLedger/Form/EditForm.vue
@@ -1,48 +1,48 @@
<template>
  <el-form :model="form">
    <el-row :gutter="20">
      <el-col :span="12">
        <el-form-item label="采购合同号:">
          <el-tag size="large">{{ form.purchaseContractNumber }}</el-tag>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="销售合同号:">
          <el-text>{{ form.salesContractNo }}</el-text>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="含税单价(元):">
          <el-text type="primary">{{ form.taxInclusiveUnitPrice }}</el-text>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="创建时间:">
          <el-text>{{ form.createdAt }}</el-text>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="发票号:">
          <el-input disabled v-model="form.invoiceNumber" />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="来票数:">
          <el-input-number :step="0.1" :min="0" style="width: 100%" v-model="form.ticketsNum" @change="inputTicketsNum" :precision="2"/>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="本次来票金额(元):">
    <el-form :model="form">
        <el-row :gutter="20">
            <el-col :span="12">
                <el-form-item label="采购合同号:">
                    <el-tag size="large">{{ form.purchaseContractNumber }}</el-tag>
                </el-form-item>
            </el-col>
            <el-col :span="12">
                <el-form-item label="销售合同号:">
                    <el-text>{{ form.salesContractNo }}</el-text>
                </el-form-item>
            </el-col>
            <el-col :span="12">
                <el-form-item label="含税单价(元):">
                    <el-text type="primary">{{ form.taxInclusiveUnitPrice }}</el-text>
                </el-form-item>
            </el-col>
            <el-col :span="12">
                <el-form-item label="创建时间:">
                    <el-text>{{ form.createdAt }}</el-text>
                </el-form-item>
            </el-col>
            <el-col :span="12">
                <el-form-item label="发票号:">
                    <el-input v-model="form.invoiceNumber" />
                </el-form-item>
            </el-col>
            <el-col :span="12">
                <el-form-item label="来票数:">
                    <el-input-number :step="0.1" :min="0" style="width: 100%" v-model="form.ticketsNum" @change="inputTicketsNum" :precision="2"/>
                </el-form-item>
            </el-col>
            <el-col :span="12">
                <el-form-item label="本次来票金额(元):">
                    <el-input-number :step="0.1" :min="0" style="width: 100%" v-model="form.ticketsAmount" @change="inputTicketsAmount" :precision="2"/>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="未来票数:">
          <el-text type="success">{{ form.futureTickets }}</el-text>
        </el-form-item>
      </el-col>
    </el-row>
  </el-form>
                </el-form-item>
            </el-col>
            <el-col :span="12">
                <el-form-item label="未来票数:">
                    <el-text type="success">{{ form.futureTickets }}</el-text>
                </el-form-item>
            </el-col>
        </el-row>
    </el-form>
</template>
<script setup>
@@ -51,34 +51,43 @@
const { proxy } = getCurrentInstance()
defineOptions({
  name: "来票台账表单",
    name: "来票台账表单",
});
const temFutureTickets = ref(0)
const temFutureTickets = ref(0) // åˆå§‹æœªæ¥ç¥¨æ•°
const initialTicketsNum = ref(0) // åˆå§‹æ¥ç¥¨æ•°
const initialTicketsAmount = ref(0) // åˆå§‹æ¥ç¥¨é‡‘额
const quantity = ref(0) // æ€»æ•°é‡
const { form, resetForm } = useFormData({
  id: undefined,
  purchaseContractNumber: undefined, // é‡‡è´­åˆåŒå·
  salesContractNo: undefined, // é”€å”®åˆåŒå·
  createdAt: undefined, // åˆ›å»ºæ—¶é—´
  invoiceNumber: undefined, // å‘票号
  ticketsNum: undefined, // æ¥ç¥¨æ•°
  ticketsAmount: undefined, // æ¥ç¥¨é‡‘额
    id: undefined,
    purchaseContractNumber: undefined, // é‡‡è´­åˆåŒå·
    salesContractNo: undefined, // é”€å”®åˆåŒå·
    createdAt: undefined, // åˆ›å»ºæ—¶é—´
    invoiceNumber: undefined, // å‘票号
    ticketsNum: undefined, // æ¥ç¥¨æ•°
    ticketsAmount: undefined, // æ¥ç¥¨é‡‘额
    taxInclusiveUnitPrice: undefined, // å«ç¨Žå•ä»·
    ticketRegistrationId: undefined, // å«ç¨Žå•ä»·
});
const load = async (id) => {
  const { code, data } = await getProductRecordById({ id });
  if (code === 200) {
    form.id = data.id;
    form.purchaseContractNumber = data.purchaseContractNumber;
    form.salesContractNo = data.salesContractNo;
    form.createdAt = data.createdAt;
    form.invoiceNumber = data.invoiceNumber;
    form.ticketsNum = data.ticketsNum;
    form.ticketsAmount = data.ticketsAmount.toFixed(2);
    form.taxInclusiveUnitPrice = data.taxInclusiveUnitPrice;
    form.futureTickets = data.futureTickets;
    temFutureTickets.value = data.futureTickets;
  }
    const { code, data } = await getProductRecordById({ id });
    if (code === 200) {
        form.id = data.id;
        form.purchaseContractNumber = data.purchaseContractNumber;
        form.salesContractNo = data.salesContractNo;
        form.createdAt = data.createdAt;
        form.invoiceNumber = data.invoiceNumber;
        form.ticketsNum = data.ticketsNum;
        form.ticketsAmount = data.ticketsAmount ? Number(data.ticketsAmount).toFixed(2) : 0;
        form.taxInclusiveUnitPrice = data.taxInclusiveUnitPrice;
        form.futureTickets = data.futureTickets;
        temFutureTickets.value = data.futureTickets;
        initialTicketsNum.value = data.ticketsNum || 0;
        initialTicketsAmount.value = data.ticketsAmount || 0;
        form.ticketRegistrationId = data.ticketRegistrationId;
        // èŽ·å–æ€»æ•°é‡ï¼Œå¦‚æžœæ•°æ®ä¸­æœ‰ quantity å­—段则使用,否则使用来票数+未来票数
        quantity.value = data.quantity || (Number(data.ticketsNum || 0) + Number(data.futureTickets || 0));
    }
};
const inputTicketsNum = (val) => {
@@ -87,15 +96,44 @@
        proxy.$modal.msgWarning("含税单价不能为零或未定义");
        return;
    }
    if (Number(form.ticketsNum) > Number(temFutureTickets.value)) {
        proxy.$modal.msgWarning("开票数不得大于未开票数");
        form.ticketsNum = temFutureTickets.value
    const newTicketsNum = Number(form.ticketsNum) || 0;
    const currentTicketsNum = Number(initialTicketsNum.value) || 0;
    // è®¡ç®—新增的来票数
    const addedTicketsNum = newTicketsNum - currentTicketsNum;
    // è®¡ç®—新的未来票数 = åˆå§‹æœªæ¥ç¥¨æ•° - æ–°å¢žçš„æ¥ç¥¨æ•°
    const newFutureTickets = Number(temFutureTickets.value) - addedTicketsNum;
    // éªŒè¯ï¼šæ–°çš„æ¥ç¥¨æ•° + æ–°çš„æœªæ¥ç¥¨æ•° â‰¤ quantity
    if (newTicketsNum + newFutureTickets > Number(quantity.value)) {
        proxy.$modal.msgWarning(`来票数+未来票数不能大于总数量(${quantity.value})`);
        // é™åˆ¶æ¥ç¥¨æ•°ï¼Œä½¿å…¶æ»¡è¶³ï¼šæ¥ç¥¨æ•° + æœªæ¥ç¥¨æ•° â‰¤ quantity
        // æœ€å¤§æ¥ç¥¨æ•° = quantity - åˆå§‹æœªæ¥ç¥¨æ•° + åˆå§‹æ¥ç¥¨æ•°
        const maxTicketsNum = Number(quantity.value) - Number(temFutureTickets.value) + Number(initialTicketsNum.value);
        form.ticketsNum = Math.max(0, Math.min(maxTicketsNum, newTicketsNum));
        // é‡æ–°è®¡ç®—
        const recalculatedAddedTicketsNum = Number(form.ticketsNum) - Number(initialTicketsNum.value);
        const recalculatedFutureTickets = Number(temFutureTickets.value) - recalculatedAddedTicketsNum;
        form.futureTickets = Number(recalculatedFutureTickets.toFixed(2));
        const ticketsAmount = Number(form.ticketsNum) * Number(form.taxInclusiveUnitPrice);
        form.ticketsAmount = Number(ticketsAmount.toFixed(2));
        return;
    }
    // æ£€æŸ¥æ–°å¢žçš„æ¥ç¥¨æ•°æ˜¯å¦å¤§äºŽåˆå§‹æœªæ¥ç¥¨æ•°
    if (addedTicketsNum > Number(temFutureTickets.value)) {
        proxy.$modal.msgWarning("新增开票数不得大于未开票数");
        form.ticketsNum = Number(initialTicketsNum.value) + Number(temFutureTickets.value);
    }
    
    // ç¡®ä¿æ‰€æœ‰æ•°å€¼éƒ½è½¬æ¢ä¸ºæ•°å­—类型进行计算
    const ticketsAmount = Number(form.ticketsNum) * Number(form.taxInclusiveUnitPrice);
    const futureTickets = Number(temFutureTickets.value) - Number(form.ticketsNum);
    form.futureTickets = Number(futureTickets.toFixed(2));
    const finalTicketsNum = Number(form.ticketsNum) || 0;
    const finalAddedTicketsNum = finalTicketsNum - Number(initialTicketsNum.value);
    const finalFutureTickets = Number(temFutureTickets.value) - finalAddedTicketsNum;
    const ticketsAmount = finalTicketsNum * Number(form.taxInclusiveUnitPrice);
    form.futureTickets = Number(finalFutureTickets.toFixed(2));
    form.ticketsAmount = Number(ticketsAmount.toFixed(2));
};
const inputTicketsAmount = (val) => {
@@ -105,23 +143,53 @@
        return;
    }
    
    if (Number(val) > Number(form.futureTickets*form.taxInclusiveUnitPrice)) {
        proxy.$modal.msgWarning("本次来票金额不得大于总金额");
        form.ticketsAmount = (form.futureTickets*form.taxInclusiveUnitPrice).toFixed(2)
        const ticketsNum = Number(form.ticketsAmount) / Number(form.taxInclusiveUnitPrice);
        form.ticketsNum = Number(ticketsNum.toFixed(2))
    const newTicketsAmount = Number(val) || 0;
    // è®¡ç®—新的来票数
    const newTicketsNum = newTicketsAmount / Number(form.taxInclusiveUnitPrice);
    const currentTicketsNum = Number(initialTicketsNum.value) || 0;
    // è®¡ç®—新增的来票数
    const addedTicketsNum = newTicketsNum - currentTicketsNum;
    // è®¡ç®—新的未来票数 = åˆå§‹æœªæ¥ç¥¨æ•° - æ–°å¢žçš„æ¥ç¥¨æ•°
    const newFutureTickets = Number(temFutureTickets.value) - addedTicketsNum;
    // éªŒè¯ï¼šæ–°çš„æ¥ç¥¨æ•° + æ–°çš„æœªæ¥ç¥¨æ•° â‰¤ quantity
    if (newTicketsNum + newFutureTickets > Number(quantity.value)) {
        proxy.$modal.msgWarning(`来票数+未来票数不能大于总数量(${quantity.value})`);
        // é™åˆ¶æ¥ç¥¨æ•°ï¼Œä½¿å…¶æ»¡è¶³ï¼šæ¥ç¥¨æ•° + æœªæ¥ç¥¨æ•° â‰¤ quantity
        const maxTicketsNum = Number(quantity.value) - Number(temFutureTickets.value) + Number(initialTicketsNum.value);
        form.ticketsNum = Math.max(0, Math.min(maxTicketsNum, newTicketsNum));
        form.ticketsAmount = Number((form.ticketsNum * Number(form.taxInclusiveUnitPrice)).toFixed(2));
        const recalculatedAddedTicketsNum = Number(form.ticketsNum) - Number(initialTicketsNum.value);
        const recalculatedFutureTickets = Number(temFutureTickets.value) - recalculatedAddedTicketsNum;
        form.futureTickets = Number(recalculatedFutureTickets.toFixed(2));
        return;
    }
    // æ£€æŸ¥æ–°å¢žçš„æ¥ç¥¨é‡‘额是否大于初始未来票数对应的金额
    const maxAddedAmount = Number(temFutureTickets.value * form.taxInclusiveUnitPrice);
    if (addedTicketsNum > 0 && addedTicketsNum * Number(form.taxInclusiveUnitPrice) > maxAddedAmount) {
        proxy.$modal.msgWarning("新增来票金额不得大于未开票金额");
        form.ticketsAmount = Number((initialTicketsAmount.value + maxAddedAmount).toFixed(2));
        form.ticketsNum = Number((currentTicketsNum + Number(temFutureTickets.value)).toFixed(2));
        form.futureTickets = 0;
        return;
    }
    
    // ç¡®ä¿æ‰€æœ‰æ•°å€¼éƒ½è½¬æ¢ä¸ºæ•°å­—类型进行计算
    const ticketsNum = Number(val) / Number(form.taxInclusiveUnitPrice);
    form.ticketsNum = Number(ticketsNum.toFixed(2));
    const finalTicketsNum = Number(newTicketsNum.toFixed(2));
    const finalAddedTicketsNum = finalTicketsNum - Number(initialTicketsNum.value);
    const finalFutureTickets = Number(temFutureTickets.value) - finalAddedTicketsNum;
    form.ticketsNum = finalTicketsNum;
    form.futureTickets = Number(finalFutureTickets.toFixed(2));
};
defineExpose({
  load,
  form,
  resetForm,
    load,
    form,
    resetForm,
});
</script>
src/views/procurementManagement/procurementInvoiceLedger/index.vue
@@ -82,12 +82,14 @@
            type="primary"
            text
            @click="openEdit(row)"
                        :disabled="row.issUerId !== userStore.id"
          >
            ç¼–辑
          </el-button>
          <el-button
            type="primary"
            text
                        :disabled="row.issUerId !== userStore.id"
            @click="handleDelete(row)"
          >
            åˆ é™¤
src/views/procurementManagement/procurementLedger/index.vue
@@ -39,7 +39,7 @@
    <div class="table_list">
      <div style="display: flex;justify-content: flex-end;margin-bottom: 20px;">
        <el-button type="primary" @click="openForm('add')">新增台账</el-button>
        <el-button type="success" @click="openScanAddDialog">扫码新增</el-button>
        <!-- <el-button type="success" @click="openScanAddDialog">扫码新增</el-button> -->
        <el-button @click="handleOut">导出</el-button>
        <el-button type="danger" plain @click="handleDelete">删除</el-button>
      </div>
@@ -146,7 +146,7 @@
        <el-table-column
          fixed="right"
          label="操作"
          min-width="150"
          min-width="100"
          align="center"
        >
          <template #default="scope">
@@ -155,15 +155,16 @@
              type="primary"
              size="small"
              @click="openForm('edit', scope.row)"
                            :disabled="scope.row.receiptPaymentAmount>0 || scope.row.recorderName !== userStore.nickName"
              >编辑</el-button
            >
            <el-button
              link
              type="success"
              size="small"
              @click="showQRCode(scope.row)"
              >生成二维码</el-button
            >
<!--            <el-button-->
<!--              link-->
<!--              type="success"-->
<!--              size="small"-->
<!--              @click="showQRCode(scope.row)"-->
<!--              >生成二维码</el-button-->
<!--            >-->
          </template>
        </el-table-column>
@@ -225,8 +226,6 @@
                v-model="form.supplierId"
                placeholder="请选择"
                clearable
                filterable
                allow-create
              >
                <el-option
                  v-for="item in supplierList"
@@ -1155,6 +1154,7 @@
const getModels = (value) => {
  if (value) {
    productForm.value.productCategory = findNodeById(productOptions.value, value) || "";
    productForm.value.productId = value;
    modelList({ id: value }).then((res) => {
      modelOptions.value = res;
    });
src/views/productionManagement/productionCosting/index.vue
@@ -171,7 +171,7 @@
        type: "warning",
    })
        .then(() => {
            proxy.download("/basic/customer/export", {}, "生产核算.xlsx");
            proxy.download("/salesLedger/productionAccounting/export", {}, "生产核算.xlsx");
        })
        .catch(() => {
            proxy.$modal.msg("已取消");
src/views/productionManagement/productionOrder/index.vue
@@ -78,7 +78,7 @@
        width:300
    },
    {
        label: "付款状态",
        label: "生产状态",
        prop: "status",
        dataType: "tag",
        formatType: (params) => {
src/views/productionManagement/productionReporting/components/formDia.vue
@@ -31,7 +31,7 @@
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="待生产数量:" prop="pendingNum">
              <el-input v-model="form.pendingNum" placeholder="请输入" clearable disabled/>
              <el-input :value="form.pendingNum !== undefined && form.pendingNum !== null ? Number(form.pendingNum).toFixed(2) : ''" placeholder="请输入" clearable disabled/>
            </el-form-item>
          </el-col>
        </el-row>
@@ -88,6 +88,7 @@
const userList = ref([])
const dialogFormVisible = ref(false);
const operationType = ref('')
const pendingFinishNum = ref(0) // å¤–部传入的待生产数量(剩余可报工数量)
const data = reactive({
  form: {
        successNum: "",
@@ -110,14 +111,21 @@
        userList.value = res.data;
    });
    form.value = {...row}
  pendingFinishNum.value = Number(row?.pendingFinishNum || 0)
  // å°†å¾…生产数量带入表单,方便展示与校验,保留两位小数
  form.value.pendingNum = Number(pendingFinishNum.value.toFixed(2))
}
const changeNum = (value) => {
    if (value > form.value.schedulingNum) {
        form.value.finishedNum = form.value.schedulingNum;
        proxy.$modal.msgWarning('本次生产数量不可大于排产数量')
    const maxPending = Number(pendingFinishNum.value) || 0
    // ä¸Šé™ï¼šä¸èƒ½è¶…过待生产数量
    if (Number(value) > maxPending) {
        form.value.finishedNum = Number(maxPending.toFixed(2));
        proxy.$modal.msgWarning('本次生产数量不可大于待生产数量')
    }
    form.value.pendingNum = form.value.schedulingNum - form.value.finishedNum;
    // é‡æ–°è®¡ç®—剩余待生产数量,保留两位小数
    const finishedNum = Number(form.value.finishedNum) || 0
    form.value.pendingNum = Number((maxPending - finishedNum).toFixed(2));
}
// æäº¤äº§å“è¡¨å•
const submitForm = () => {
src/views/productionManagement/productionReporting/index.vue
@@ -112,6 +112,7 @@
                                    size="small"
                                    @click="changeEditType(scope.row)"
                                    v-if="!scope.row.editType"
                                    :disabled="scope.row.parentStatus === 3"
                                >编辑</el-button
                                >
                                <el-button
src/views/salesManagement/invoiceLedger/index.vue
@@ -12,7 +12,7 @@
            @change="changeDateRange" @clear="clearRange" />
        </el-form-item>
        <el-form-item label="录入日期">
          <el-date-picker style="width: 100%" v-model="searchForm.createTimeStart" value-format="YYYY-MM-DD HH:mm:ss"
          <el-date-picker style="width: 100%" v-model="searchForm.createTimeStart" value-format="YYYY-MM-DD"
            format="YYYY-MM-DD" type="date" placeholder="请选择" clearable @change="handleQuery" />
        </el-form-item>
        <el-form-item label="不显示有发票行">
@@ -49,15 +49,15 @@
              @click="handleFile(scope.row.commonFiles)">
              æŸ¥çœ‹é™„ä»¶
            </el-button>
            <el-button v-else link type="primary" @click="handleDownload(scope.row)">
            <el-button v-else link type="primary" @click="handleDownload(scope.row)" :disabled="scope.row.invoicePerson !== userStore.nickName">
              ä¸Šä¼ 
            </el-button>
          </template>
        </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)">编辑</el-button>
            <el-button link type="primary" size="small" @click="delInvoiceLedger(scope.row)">删除</el-button>
            <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>
          </template>
        </el-table-column>
      </el-table>
@@ -229,7 +229,7 @@
  return parseFloat(cellValue).toFixed(2);
};
const formatDate = (row, column, cellValue) => {
  return dayjs(cellValue).format("YYYY-MM-DD HH:mm:ss");
  return dayjs(cellValue).format("YYYY-MM-DD");
};
// æŸ¥è¯¢åˆ—表
/** æœç´¢æŒ‰é’®æ“ä½œ */
src/views/salesManagement/receiptPayment/index.vue
@@ -122,6 +122,7 @@
                    size="small"
                    @click="changeEditType(scope.row)"
                    v-if="!scope.row.editType"
                                        :disabled="scope.row.registrant !== userStore.nickName"
                    >编辑</el-button
                  >
                  <el-button
@@ -130,6 +131,7 @@
                    size="small"
                    @click="saveReceiptPayment(scope.row)"
                    v-if="scope.row.editType"
                                        :disabled="scope.row.registrant !== userStore.nickName"
                    >保存</el-button
                  >
                  <el-button
@@ -137,6 +139,7 @@
                    type="primary"
                    size="small"
                    @click="delReceiptRecord(scope.row)"
                                        :disabled="scope.row.registrant !== userStore.nickName"
                    >删除</el-button
                  >
                </template>
src/views/salesManagement/salesLedger/index.vue
@@ -47,14 +47,18 @@
          <template #default="props">
            <el-table :data="props.row.children" border show-summary :summary-method="summarizeChildrenTable">
              <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" />
              <el-table-column label="数量" prop="quantity" />
              <el-table-column label="产品名称" prop="productCategory"/>
              <el-table-column label="产品高度" prop="specificationModel" width="100">
                <template #default="scope">
                  <div>{{ scope.row.specificationModel }}{{ scope.row.unit }}</div>
                </template>
              </el-table-column>
              <el-table-column label="数量" prop="quantity"/>
              <el-table-column label="单价(美元)/ä»¶" prop="taxInclusiveUnitPrice" :formatter="formattedNumber"></el-table-column>
              <el-table-column label="税率(%)" prop="taxRate" />
              <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="taxInclusiveTotalPrice" :formatter="formattedNumber" />
              <el-table-column label="不含税总价(美元)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" />
            </el-table>
          </template>
        </el-table-column>
@@ -72,7 +76,7 @@
        <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" @click="openForm('edit', scope.row)">编辑</el-button>
            <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('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>
@@ -163,14 +167,18 @@
          :summary-method="summarizeMainTable">
          <el-table-column align="center" type="selection" width="55" v-if="operationType !== 'view'" />
          <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" />
          <el-table-column label="产品名称" prop="productCategory" />
          <el-table-column label="产品高度" prop="specificationModel">
            <template #default="scope">
              <div>{{ scope.row.specificationModel }}{{ scope.row.unit }}</div>
            </template>
          </el-table-column>
          <!-- <el-table-column label="单位" prop="unit" /> -->
          <el-table-column label="数量" prop="quantity" />
          <el-table-column label="税率(%)" prop="taxRate" />
          <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="taxRate" /> -->
          <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 fixed="right" label="操作" min-width="60" align="center" v-if="operationType !== 'view'">
            <template #default="scope">
              <el-button link type="primary" size="small" @click="openProductForm('edit', scope.row,scope.$index)">编辑</el-button>
@@ -214,7 +222,7 @@
      <el-form :model="productForm" label-width="140px" label-position="top" :rules="productRules" ref="productFormRef">
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="产品大类:" prop="productCategory">
            <el-form-item label="产品名称:" prop="productCategory">
              <!-- <el-select v-model="productForm.productCategory" placeholder="请选择" clearable>
                <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" :value="item.nickName"/>
              </el-select> -->
@@ -225,7 +233,7 @@
        </el-row>
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="规格型号:" prop="productModelId">
            <el-form-item label="产品高度:" prop="productModelId">
              <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>
@@ -234,7 +242,7 @@
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="单位:" prop="unit">
            <el-form-item label="高度单位:" prop="unit">
              <el-input v-model="productForm.unit" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
@@ -250,7 +258,7 @@
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="含税单价(元):" prop="taxInclusiveUnitPrice">
            <el-form-item label="单价(美元)/件:" prop="taxInclusiveUnitPrice">
              <el-input-number :step="0.01" :min="0" v-model="productForm.taxInclusiveUnitPrice" style="width: 100%"
                                                             :precision="2"
                                                             placeholder="请输入" clearable @change="calculateFromUnitPrice" />
@@ -258,20 +266,19 @@
          </el-col>
                    <el-col :span="12">
                        <el-form-item label="数量:" prop="quantity">
                            <el-input-number  :step="0.1" :min="0" v-model="productForm.quantity" placeholder="请输入" clearable
                                                                :precision="2"
                            <el-input-number  :min="0" v-model="productForm.quantity" placeholder="请输入" clearable
                                                                @change="calculateFromQuantity" style="width: 100%" />
                        </el-form-item>
                    </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="含税总价(元):" prop="taxInclusiveTotalPrice">
            <el-form-item label="含税总价(美元):" prop="taxInclusiveTotalPrice">
              <el-input v-model="productForm.taxInclusiveTotalPrice" placeholder="请输入" clearable @change="calculateFromTotalPrice" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="不含税总价(元):" prop="taxExclusiveTotalPrice">
            <el-form-item label="不含税总价(美元):" prop="taxExclusiveTotalPrice">
              <el-input v-model="productForm.taxExclusiveTotalPrice" placeholder="请输入" clearable @change="calculateFromExclusiveTotalPrice" />
            </el-form-item>
          </el-col>
@@ -317,7 +324,7 @@
                    <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>
                            
@@ -459,7 +466,7 @@
import pagination from "@/components/PIMTable/Pagination.vue";
import {onMounted, ref} from "vue";
import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
import {ElMessage, ElMessageBox} from "element-plus";
import { ElMessageBox } from "element-plus";
import useUserStore from "@/store/modules/user";
import { userListNoPage } from "@/api/system/user.js";
import FileList from "./fileList.vue";
@@ -472,7 +479,7 @@
  delLedger,
  addOrUpdateSalesLedgerProduct,
  delProduct,
  delLedgerFile, getProductInventory,
  delLedgerFile,
} from "@/api/salesManagement/salesLedger.js";
import { modelList, productTreeList } from "@/api/basicData/product.js";
import useFormData from "@/hooks/useFormData.js";
@@ -551,6 +558,7 @@
    taxInclusiveTotalPrice: "",
    taxExclusiveTotalPrice: "",
    invoiceType: "",
    cartonSpecifications:'',
  },
  productRules: {
    productCategory: [{ required: true, message: "请选择", trigger: "change" }],
@@ -563,6 +571,7 @@
    taxInclusiveUnitPrice: [
      { required: true, message: "请输入", trigger: "blur" },
    ],
    cartonSpecifications: [{ required: true, message: "请输入", trigger: "blur" }],
    taxRate: [{ required: true, message: "请选择", trigger: "change" }],
    taxInclusiveTotalPrice: [
      { required: true, message: "请输入", trigger: "blur" },
@@ -644,7 +653,7 @@
      tableLoading.value = false;
    });
};
// èŽ·å–äº§å“å¤§ç±»tree数据
// èŽ·å–äº§å“åç§°tree数据
const getProductOptions = () => {
  productTreeList().then((res) => {
    productOptions.value = convertIdToValue(res);
@@ -656,6 +665,7 @@
// èŽ·å–tree子数据
const getModels = (value) => {
  productForm.value.productCategory = findNodeById(productOptions.value, value);
  productForm.value.productId = value;
  modelList({ id: value }).then((res) => {
    modelOptions.value = res;
  });
@@ -868,6 +878,7 @@
        }else{
          productData.value[productIndex.value] = { ...productForm.value }
        }
        console.log('productData',productData)
        closeProductDia();
      }
    }
@@ -1166,7 +1177,7 @@
      <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>
          
@@ -1393,10 +1404,10 @@
// æ ¹æ®ä¸å«ç¨Žæ€»ä»·è®¡ç®—含税单价和数量
const calculateFromExclusiveTotalPrice = () => {
    if (!productForm.value.taxRate) {
        proxy.$modal.msgWarning("请先选择税率");
        return;
    }
    // if (!productForm.value.taxRate) {
    //     proxy.$modal.msgWarning("请先选择税率");
    //     return;
    // }
  if (isCalculating.value) return;
  
  const exclusiveTotalPrice = parseFloat(productForm.value.taxExclusiveTotalPrice);
@@ -1422,10 +1433,10 @@
// æ ¹æ®æ•°é‡å˜åŒ–计算总价
const calculateFromQuantity = () => {
    if (!productForm.value.taxRate) {
        proxy.$modal.msgWarning("请先选择税率");
        return;
    }
    // if (!productForm.value.taxRate) {
    //     proxy.$modal.msgWarning("请先选择税率");
    //     return;
    // }
  if (isCalculating.value) return;
  
  const quantity = parseFloat(productForm.value.quantity);
@@ -1454,10 +1465,10 @@
// æ ¹æ®å«ç¨Žå•价变化计算总价
const calculateFromUnitPrice = () => {
    if (!productForm.value.taxRate) {
        proxy.$modal.msgWarning("请先选择税率");
        return;
    }
    // if (!productForm.value.taxRate) {
    //     proxy.$modal.msgWarning("请先选择税率");
    //     return;
    // }
  if (isCalculating.value) return;
  
  const quantity = parseFloat(productForm.value.quantity);
@@ -1486,10 +1497,10 @@
// æ ¹æ®ç¨ŽçŽ‡å˜åŒ–è®¡ç®—ä¸å«ç¨Žæ€»ä»·
const calculateFromTaxRate = () => {
    if (!productForm.value.taxRate) {
        proxy.$modal.msgWarning("请先选择税率");
        return;
    }
    // if (!productForm.value.taxRate) {
    //     proxy.$modal.msgWarning("请先选择税率");
    //     return;
    // }
  if (isCalculating.value) return;
  
  const inclusiveTotalPrice = parseFloat(productForm.value.taxInclusiveTotalPrice);
@@ -1524,16 +1535,12 @@
// æ‰“开发货弹框
const openDeliveryForm = (row) => {
  getProductInventory({ salesLedgerId: row.id, type:1 }).then((res) => {
    currentDeliveryRow.value = row;
    deliveryForm.value = {
      shippingDate: getCurrentDate(),
      shippingCarNumber: "",
    };
    deliveryFormVisible.value = true;
  }).catch(err => {
    ElMessage.error(err.msg);
  });
  currentDeliveryRow.value = row;
  deliveryForm.value = {
    shippingDate: getCurrentDate(),
    shippingCarNumber: "",
  };
  deliveryFormVisible.value = true;
};
// æäº¤å‘货表单