Quellcode durchsuchen

Merge branch 'master' of http://110.41.163.243:9980/kd-aiot/kd-aiot-frontend-wt into dengfei

695593266@qq.com vor 10 Monaten
Ursprung
Commit
9e12269e72
26 geänderte Dateien mit 2824 neuen und 368 gelöschten Zeilen
  1. 16 1
      src/BIZComponents/inventoryTableDetails.vue
  2. 10 0
      src/BIZComponents/processSubmitDialog/api.js
  3. 297 0
      src/BIZComponents/processSubmitDialog/components/SHGDListDialog.vue
  4. 99 0
      src/BIZComponents/processSubmitDialog/components/work-search.vue
  5. 53 6
      src/BIZComponents/processSubmitDialog/processSubmitDialog.vue
  6. 20 0
      src/api/afterSales/index.js
  7. 198 145
      src/views/bpm/collaborative/detail.vue
  8. 16 10
      src/views/bpm/collaborative/index.vue
  9. 1 0
      src/views/bpm/handleTask/components/contractBook/detailDialog.vue
  10. 4 4
      src/views/bpm/handleTask/components/financialManage/payableManage/components/detailDialog.vue
  11. 4 4
      src/views/bpm/handleTask/components/financialManage/receivableManage/components/detailDialog.vue
  12. 9 1
      src/views/bpm/handleTask/components/productionWarehousing/submit.vue
  13. 1 0
      src/views/bpm/handleTask/components/saleOrder/detailDialog.vue
  14. 7 2
      src/views/bpm/handleTask/components/saleOrder/invoice/detailDialog.vue
  15. 1 1
      src/views/bpm/handleTask/components/saleOrder/returnGoods/detailDialog.vue
  16. 0 1
      src/views/bpm/handleTask/components/saleOrder/returnGoods/submit.vue
  17. 1 1
      src/views/bpm/handleTask/components/saleOrder/saleReturnGoods/detailDialog.vue
  18. 1145 0
      src/views/bpm/handleTask/components/salesServiceManagement/demand/salesServiceDialog.vue
  19. 474 0
      src/views/bpm/handleTask/components/salesServiceManagement/demand/sparePartsList.vue
  20. 200 0
      src/views/bpm/handleTask/components/salesServiceManagement/demand/submit.vue
  21. 224 172
      src/views/bpm/handleTask/formParser/formParserDialog.vue
  22. 7 0
      src/views/bpm/stockManagement/details.vue
  23. 34 18
      src/views/bpm/stockManagement/storage.vue
  24. 1 1
      src/views/bpm/tickets/repair/index.vue
  25. 1 0
      src/views/bpm/todo/index.vue
  26. 1 1
      vue.config.js

+ 16 - 1
src/BIZComponents/inventoryTableDetails.vue

@@ -148,6 +148,11 @@
             unitIdKey: 'saleUnitId'
             unitIdKey: 'saleUnitId'
           };
           };
         }
         }
+      },
+      //是否显示生产要求
+      isProductionRequirements: {
+        type: Boolean,
+        default: false
       }
       }
     },
     },
     data() {
     data() {
@@ -511,9 +516,19 @@
           {
           {
             minWidth: 160,
             minWidth: 160,
             prop: 'productionCodes',
             prop: 'productionCodes',
-            label: '生产编',
+            label: '生产编',
             align: 'center'
             align: 'center'
           },
           },
+          this.isProductionRequirements
+            ? {
+                minWidth: 280,
+                prop: 'productionRequirements',
+                label: '生产要求',
+                align: 'center'
+              }
+            : {
+                width: 1
+              },
           {
           {
             minWidth: 240,
             minWidth: 240,
             prop: 'taskName',
             prop: 'taskName',

+ 10 - 0
src/BIZComponents/processSubmitDialog/api.js

@@ -86,3 +86,13 @@ export async function contactPageUsages(params) {
   }
   }
   return Promise.reject(new Error(res.data.message));
   return Promise.reject(new Error(res.data.message));
 }
 }
+//获取工单
+export async function getSalesWorkOrder(data) {
+  const res = await request.get('/eom/afterSalesWorkOrder/page', {
+    params: data
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 297 - 0
src/BIZComponents/processSubmitDialog/components/SHGDListDialog.vue

@@ -0,0 +1,297 @@
+<template>
+  <ele-modal
+    title="售后工单查询"
+    custom-class="ele-dialog-form long-dialog-form"
+    :visible.sync="visible"
+    :before-close="handleClose"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    width="70%"
+    :maxable="true"
+    :resizable="true"
+  >
+    <el-card shadow="never" v-loading="loading">
+      <work-search
+        class="seep-search"
+        ref="workSearch"
+        :levelList="levelList"
+        @search="reload"
+      ></work-search>
+
+      <ele-pro-table
+        ref="table"
+        :columns="columns"
+        :datasource="datasource"
+        row-key="id"
+        height="calc(100vh - 500px)"
+        class="dict-table"
+      >
+        <template v-slot:toolbar></template>
+        <template v-slot:faultLevel="{ row }">
+          {{ levelData[row.faultLevel] || '' }}
+        </template>
+       <template v-slot:selection="{ row }">
+  <div class="radio-container">
+    <el-radio
+      v-model="selectedRowId"
+      :label="row.id"
+      @change="() => selectedRow = row"
+    ><span></span></el-radio>
+  </div>
+</template>
+      </ele-pro-table>
+    </el-card>
+
+    <div class="btns" slot="footer">
+      <el-button 
+        type="primary" 
+        size="small" 
+        :disabled="!selectedRow"
+        @click="handleConfirm"
+      >
+        确认
+      </el-button>
+      <el-button size="small" @click="handleClose">关闭</el-button>
+    </div>
+  </ele-modal>
+</template>
+
+<script>
+import workSearch from './work-search.vue';
+import { getSalesWorkOrder } from '@/BIZComponents/processSubmitDialog/api';
+import { getByCode } from '@/api/system/dictionary-data';
+import dictMixins from '@/mixins/dictMixins';
+
+export default {
+  mixins: [dictMixins],
+  components: {
+    workSearch
+  },
+  data() {
+    return {
+      visible: false,
+      loading: false,
+      levelData: {},
+      levelList: [],
+      selectedRowId: null,
+      selectedRow: null,  // 存储选中的完整行数据
+      columns: [
+        {
+          columnKey: 'selection',
+          label: '选择',
+          slot: 'selection',
+          align: 'center',
+          showOverflowTooltip: true,
+          fixed: 'left'  // 固定选择列在左侧,避免滚动后看不到
+        },
+        {
+          columnKey: 'index',
+          label: '序号',
+          type: 'index',
+          width: 55,
+          align: 'center',
+          showOverflowTooltip: true,
+          fixed: 'left'
+        },
+        {
+          prop: 'code',
+          label: '工单编号',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 150
+        },
+        {
+          prop: 'planCode',
+          label: '计划单号',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 110
+        },
+        {
+          prop: 'planName',
+          label: '计划名称',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 110
+        },
+        {
+          prop: 'executeUserName',
+          label: '报工人',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 110
+        },
+        {
+          prop: 'accepterUserName',
+          label: '验收人',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 110
+        },
+        {
+          slot: 'faultLevel',
+          prop: 'faultLevel',
+          label: '故障等级',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 110
+        },
+        {
+          prop: 'contactName',
+          label: '客户名称',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 110
+        },
+        {
+          prop: 'categoryName',
+          label: '设备名称',
+          align: 'center',
+          minWidth: 110,
+          showOverflowTooltip: true,
+          formatter: (row) => {
+            if (!row.deviceDetails) return '';
+            return row.deviceDetails.map((el) => el.categoryName).join(',');
+          }
+        },
+        {
+          prop: 'accepterTime',
+          label: '验收时间',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 110
+        },
+        {
+          prop: 'totalCost',
+          label: '费用( 元 )',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 110
+        },
+        {
+          columnKey: 'inFactDuration',
+          label: '工时',
+          align: 'center',
+          resizable: false,
+          showOverflowTooltip: true,
+          minWidth: 120,
+          formatter: (row) => {
+            if (row.inFactDuration || row.inFactDuration === 0) {
+              return `${((row.inFactDuration - 0) / 60).toFixed(1)} 小时`;
+            }
+            return '';
+          }
+        },
+        {
+          prop: 'orderStatus',
+          label: '状态',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 110,
+          formatter: (row) => {
+            const statusMap = {
+              0: '待执行',
+              1: '已接收',
+              2: '执行中',
+              3: '待验收',
+              4: '待评价',
+              5: '已完成',
+              6: '验收不通过'
+            };
+            return statusMap[row.orderStatus] || '';
+          }
+        }
+      ]
+    };
+  },
+  created() {
+    this.getLevelCode('fault_level');
+  },
+  methods: {
+    open() {
+      this.visible = true;
+      this.reload();
+    },
+    async getLevelCode(code) {
+      const res = await getByCode(code);
+      if (res?.code === '0') {
+        this.levelData = res.data.reduce((obj, el) => {
+          const key = Object.keys(el)[0];
+          obj[key] = Object.values(el)[0];
+          return obj;
+        }, {});
+        this.levelList = res.data.map((el) => ({
+          label: Object.values(el)[0],
+          value: Object.keys(el)[0]
+        }));
+      }
+    },
+    datasource({ page, limit, where }) {
+      this.loading = true;
+      const params = {
+        pageNum: page,
+        size: limit,
+        isDispatch:'0',
+        ...where
+      };
+      return getSalesWorkOrder(params).finally(() => {
+        this.loading = false;
+      });
+    },
+    reload(where = {}) {
+      this.$refs.table?.reload({
+        pageNum: 1,
+        where: where
+      });
+    },
+    handleConfirm() {
+      if (this.selectedRow) {
+        console.log(this.selectedRow)
+        
+        this.$emit('changeParent', this.selectedRow);
+        this.handleClose();  // 确认后关闭弹窗
+      }
+    },
+    handleClose() {
+      this.visible = false;
+      // 重置选中状态,避免下次打开残留选中
+      this.selectedRowId = null;
+      this.selectedRow = null;
+      this.$refs.table?.reload({ pageNum: 1 });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.seep-search {
+  margin-bottom: 16px;
+  ::v-deep .el-input__inner {
+    padding: 0 5px 0 10px;
+  }
+}
+
+.btns {
+  text-align: center;
+  padding: 10px 0;
+  button:first-child {  // 给确认按钮加右边距,和关闭按钮分隔
+    margin-right: 8px;
+  }
+}
+
+::v-deep .ele-pro-table {
+  margin-top: 8px;
+}
+
+::v-deep .el-radio {
+  vertical-align: middle;
+}
+.radio-container {
+  text-align: center; /* 让单选框居中 */
+  line-height: 1;     /* 消除行高导致的多余空间 */
+}
+::v-deep .radio-container .el-radio {
+  display: inline-block; /* 确保单选框独占空间 */
+}
+</style>

+ 99 - 0
src/BIZComponents/processSubmitDialog/components/work-search.vue

@@ -0,0 +1,99 @@
+<!-- 搜索表单 -->
+<template>
+  <seekPage ref="seekPage" :seekList="seekList" :formLength="3" @search="search"></seekPage>
+</template>
+<script>
+  export default {
+    data() {
+      return {};
+    },
+    props: {
+      levelList: {
+        type: Array,
+        default: () => []
+      }
+    },
+    computed: {
+      // 表格列配置
+      seekList() {
+        return [
+          {
+            label: '关键字:',
+            value: 'keyWord',
+            type: 'input',
+            placeholder: '单号/客户名称/设备名称'
+          },
+          {
+            label: '工单编号:',
+            value: 'code',
+            type: 'input',
+            placeholder: ''
+          },
+          {
+            label: '需求编码:',
+            value: 'demandCode',
+            type: 'input',
+            placeholder: ''
+          },
+          {
+            label: '客户名称:',
+            value: 'contactName',
+            type: 'input',
+            placeholder: ''
+          },
+          {
+            label: '设备名称:',
+            value: 'deviceName',
+            width: 380,
+            type: 'input',
+            placeholder: ''
+          },
+          {
+            label: '故障等级:',
+            value: 'faultLevel',
+            width: 380,
+            type: 'select',
+            planList: this.levelList,
+            placeholder: ''
+          },
+          {
+            label: '计划单号:',
+            value: 'planCode',
+            width: 380,
+            type: 'input',
+            placeholder: ''
+          },
+          {
+            label: '计划名称:',
+            value: 'planName',
+            width: 380,
+            type: 'input',
+            placeholder: ''
+          },
+          {
+            label: '报工人:',
+            value: 'executeUserName',
+            width: 380,
+            type: 'input',
+            placeholder: ''
+          },
+          {
+            label: '验收人:',
+            value: 'accepterUserName',
+            width: 380,
+            type: 'input',
+            placeholder: ''
+          }
+        ];
+      }
+    },
+    methods: {
+      /* 搜索 */
+      search(e) {
+        this.$emit('search', {
+          ...e
+        });
+      }
+    }
+  };
+</script>

+ 53 - 6
src/BIZComponents/processSubmitDialog/processSubmitDialog.vue

@@ -20,7 +20,7 @@
           :model="form"
           :model="form"
           label-width="90px"
           label-width="90px"
           :label-position="'left'"
           :label-position="'left'"
-          style="padding: 10px;"
+          style="padding: 10px"
         >
         >
           <el-row>
           <el-row>
             <el-col :span="24">
             <el-col :span="24">
@@ -115,7 +115,17 @@
               ></el-input>
               ></el-input>
             </div>
             </div>
           </template>
           </template>
-
+          <!-- 关联工单 -->
+          <template v-slot:manage_workorder="scope">
+            <div class="manage_workorder">
+              <el-input
+                v-model="scope.model.manage_workorder.code"
+                style="width: 100%"
+                @click.native="addWorkOrder('manage_workorder')"
+                placeholder="点击选择关联工单"
+              ></el-input>
+            </div>
+          </template>
           <!-- 差旅交通 -->
           <!-- 差旅交通 -->
           <template v-slot:blank_business_component="scope">
           <template v-slot:blank_business_component="scope">
             <businessComponent
             <businessComponent
@@ -390,6 +400,11 @@
       ref="parentRef"
       ref="parentRef"
       @changeParent="handleConcatConfirm"
       @changeParent="handleConcatConfirm"
     ></parentList>
     ></parentList>
+
+    <SHGDListDialog
+      ref="SHGDListDialogRef"
+      @changeParent="getSHGDData"
+    ></SHGDListDialog>
   </ele-modal>
   </ele-modal>
 </template>
 </template>
 <script>
 <script>
@@ -425,6 +440,9 @@
   import productSpecificationComponent from './components/productSpecificationComponent.vue';
   import productSpecificationComponent from './components/productSpecificationComponent.vue';
   import eventComponent from './components/eventComponent.vue';
   import eventComponent from './components/eventComponent.vue';
   import reissueComponent from './components/reissueComponent.vue';
   import reissueComponent from './components/reissueComponent.vue';
+  import SHGDListDialog from './components/SHGDListDialog.vue';
+  import { parameterGetByCode } from '@/api/main/index.js';
+
   export default {
   export default {
     name: 'processSubmitDialog',
     name: 'processSubmitDialog',
     components: {
     components: {
@@ -436,7 +454,8 @@
       useQualificationComponent,
       useQualificationComponent,
       productSpecificationComponent,
       productSpecificationComponent,
       eventComponent,
       eventComponent,
-      reissueComponent
+      reissueComponent,
+      SHGDListDialog
     },
     },
     mixins: [dictMixins],
     mixins: [dictMixins],
     props: {
     props: {
@@ -622,6 +641,27 @@ this.postOptions.push(...response.data);
         this.$refs.parentRef.open(item);
         this.$refs.parentRef.open(item);
       },
       },
 
 
+      async addWorkOrder(type) {
+        this.$refs.SHGDListDialogRef.open();
+      },
+      getSHGDData(workOrder) {
+        if (!workOrder?.code) {
+          this.$message.warning('选中的工单缺少编码,请重新选择');
+          return;
+        }
+        this.$refs.generateForm.getData(false).then((currentFormData) => {
+          currentFormData.manage_workorder = {
+            code: workOrder.code,
+            id: workOrder.id || '',
+            name: workOrder.name || ''
+          };
+          this.$refs.generateForm.setData({
+            manage_workorder: currentFormData.manage_workorder
+          });
+          this.form.valueJson.manage_workorder =
+            currentFormData.manage_workorder;
+        });
+      },
       async handleConcatConfirm(item) {
       async handleConcatConfirm(item) {
         console.log('选择的客户', item);
         console.log('选择的客户', item);
 
 
@@ -687,10 +727,17 @@ this.postOptions.push(...response.data);
       async getDefaultInfo(businessKey) {
       async getDefaultInfo(businessKey) {
         let info = await getModel(businessKey);
         let info = await getModel(businessKey);
         //let info = await getProcessDefinitionInfo({ id: businessKey });
         //let info = await getProcessDefinitionInfo({ id: businessKey });
+        parameterGetByCode({
+          code: 'wt_collaborative_bpm'
+        }).then((res) => {
+          if (!res.value||res.value=='1') {
+            this.form.FQLC = info?.id;
+            this.form.name = this.title;
+            this.form.key = info?.key;
+          }
+        });
         this.form.LCFL = info?.category;
         this.form.LCFL = info?.category;
-        this.form.FQLC = info?.id;
-        this.form.name = this.title;
-        this.form.key = info?.key;
+
         if (this.form.LCFL) await this.getProcessList(this.form.LCFL);
         if (this.form.LCFL) await this.getProcessList(this.form.LCFL);
       },
       },
       async getProcessList(val) {
       async getProcessList(val) {

+ 20 - 0
src/api/afterSales/index.js

@@ -42,4 +42,24 @@ export async function salesrealcostinfo(id) {
     return res.data.data;
     return res.data.data;
   }
   }
   return Promise.reject(new Error(res.data.message));
   return Promise.reject(new Error(res.data.message));
+}
+//售后服务 售后需求详情
+
+export async function getSalesDemandById(id) {
+  const res = await request.get(`/eom/afterSalesDemand/getById/${id}`);
+  if (res.data.code === "0") { 
+    return res.data; 
+  }
+  return Promise.reject(new Error(res.data.message || "获取售后需求详情失败"));
+}
+
+/**
+ * 获取客户信息详情
+ */
+export async function contactDetail(id) {
+  const res = await request.get(`/eom/contact/getById/${id}`, {});
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
 }
 }

+ 198 - 145
src/views/bpm/collaborative/detail.vue

@@ -35,7 +35,10 @@
           ref="generateForm"
           ref="generateForm"
         >
         >
           <template v-slot:blank_adopzrdd="scope">
           <template v-slot:blank_adopzrdd="scope">
-            <div v-for="(item, index) in scope.model.blank_adopzrdd" :key="index">
+            <div
+              v-for="(item, index) in scope.model.blank_adopzrdd"
+              :key="index"
+            >
               <div class="blank_adopzrdd">
               <div class="blank_adopzrdd">
                 <span>{{ index + 1 }}报销事项:</span>
                 <span>{{ index + 1 }}报销事项:</span>
                 <el-input
                 <el-input
@@ -55,45 +58,89 @@
             </div>
             </div>
           </template>
           </template>
           <!-- 客户名称 -->
           <!-- 客户名称 -->
-            <template v-slot:eom_contact="scope">
-              <div class="eom_contact">
-                <el-input
-                    v-model="scope.model.eom_contact.name"
-                    style="width: 100%"
-                  ></el-input>
-              </div>
-            </template>
-
-            <!-- 差旅 -->
-            <template v-slot:blank_business_component="scope">
-              <businessComponent  ref="blank_business_component" id="blank_business_component" :generateForm="$refs.generateForm" :info="scope.model" :view="view"></businessComponent>
-            </template>
+          <template v-slot:eom_contact="scope">
+            <div class="eom_contact">
+              <el-input
+                v-model="scope.model.eom_contact.name"
+                style="width: 100%"
+              ></el-input>
+            </div>
+          </template>
 
 
-            <!-- 印章使用 -->
-            <template v-slot:blank_use_seal="scope">
-              <useSealComponent  ref="blank_use_seal" id="blank_use_seal" :generateForm="$refs.generateForm" :info="scope.model" :view="view"></useSealComponent>
-            </template>
+          <!-- 关联工单 -->
+          <template v-slot:manage_workorder="scope">
+            <div class="manage_workorder">
+              <el-input
+                v-model="scope.model.manage_workorder.code"
+                style="width: 100%"
+              ></el-input>
+            </div>
+          </template>
+          <!-- 差旅 -->
+          <template v-slot:blank_business_component="scope">
+            <businessComponent
+              ref="blank_business_component"
+              id="blank_business_component"
+              :generateForm="$refs.generateForm"
+              :info="scope.model"
+              :view="view"
+            ></businessComponent>
+          </template>
 
 
-            <!-- 资质使用 -->
-            <template v-slot:blank_use_qualification="scope">
-              <useQualificationComponent  ref="blank_use_qualification" id="blank_use_qualification" :generateForm="$refs.generateForm" :info="scope.model" :view="view"></useQualificationComponent>
-            </template>
+          <!-- 印章使用 -->
+          <template v-slot:blank_use_seal="scope">
+            <useSealComponent
+              ref="blank_use_seal"
+              id="blank_use_seal"
+              :generateForm="$refs.generateForm"
+              :info="scope.model"
+              :view="view"
+            ></useSealComponent>
+          </template>
 
 
-            <!-- 产品规格 -->
-            <template v-slot:blank_product_specification="scope">
-              <productSpecificationComponent  ref="blank_product_specification" id="blank_product_specification" :generateForm="$refs.generateForm" :info="scope.model" :view="view"></productSpecificationComponent>
-            </template>
+          <!-- 资质使用 -->
+          <template v-slot:blank_use_qualification="scope">
+            <useQualificationComponent
+              ref="blank_use_qualification"
+              id="blank_use_qualification"
+              :generateForm="$refs.generateForm"
+              :info="scope.model"
+              :view="view"
+            ></useQualificationComponent>
+          </template>
 
 
-            <!-- 事件 -->
-            <template v-slot:blank_event_component="scope">
-              <eventComponent  ref="blank_event_component" id="blank_event_component" :generateForm="$refs.generateForm" :info="scope.model" :view="view"></eventComponent>
-            </template>
+          <!-- 产品规格 -->
+          <template v-slot:blank_product_specification="scope">
+            <productSpecificationComponent
+              ref="blank_product_specification"
+              id="blank_product_specification"
+              :generateForm="$refs.generateForm"
+              :info="scope.model"
+              :view="view"
+            ></productSpecificationComponent>
+          </template>
 
 
-            <!-- 补发 -->
-            <template v-slot:blank_reissue_component="scope">
-              <reissueComponent  ref="blank_reissue_component" id="blank_reissue_component" :generateForm="$refs.generateForm" :info="scope.model" :view="view"></reissueComponent>
-            </template>
+          <!-- 事件 -->
+          <template v-slot:blank_event_component="scope">
+            <eventComponent
+              ref="blank_event_component"
+              id="blank_event_component"
+              :generateForm="$refs.generateForm"
+              :info="scope.model"
+              :view="view"
+            ></eventComponent>
+          </template>
 
 
+          <!-- 补发 -->
+          <template v-slot:blank_reissue_component="scope">
+            <reissueComponent
+              ref="blank_reissue_component"
+              id="blank_reissue_component"
+              :generateForm="$refs.generateForm"
+              :info="scope.model"
+              :view="view"
+            ></reissueComponent>
+          </template>
         </fm-generate-form>
         </fm-generate-form>
       </div>
       </div>
       <div
       <div
@@ -118,14 +165,10 @@
         <span style="writing-mode: vertical-rl">选择流程</span>
         <span style="writing-mode: vertical-rl">选择流程</span>
       </div>
       </div>
       <div style="flex: 1" v-if="isRight">
       <div style="flex: 1" v-if="isRight">
-        <Detail
-          :view="true"
-          :id="form.id"
-          ref="formDetailDialogRef"
-        ></Detail>
+        <Detail :view="true" :id="form.id" ref="formDetailDialogRef"></Detail>
       </div>
       </div>
     </div>
     </div>
-    
+
     <outgoingDetails
     <outgoingDetails
       v-if="outgoingData.id"
       v-if="outgoingData.id"
       :business-id="outgoingData.id"
       :business-id="outgoingData.id"
@@ -137,121 +180,131 @@
   </ele-modal>
   </ele-modal>
 </template>
 </template>
 <script>
 <script>
-  import dictMixins from '@/mixins/dictMixins';
-  import { getToken } from '@/utils/token-util';
-  import outgoingDetails from '@/views/bpm/outgoingManagement/details.vue';
-  import storageApi from '@/api/warehouseManagement';
-
-  // 流程组件  需要在三个地方使用,审批流程,详情,提交流程
-  import businessComponent from '@/BIZComponents/processSubmitDialog/components/businessComponent.vue';
-  import useSealComponent from '@/BIZComponents/processSubmitDialog/components/useSealComponent.vue';
-  import useQualificationComponent from '@/BIZComponents/processSubmitDialog/components/useQualificationComponent.vue';
-  import productSpecificationComponent from '@/BIZComponents/processSubmitDialog/components/productSpecificationComponent.vue';
-  import eventComponent from '@/BIZComponents/processSubmitDialog/components/eventComponent.vue';
-  import reissueComponent from '@/BIZComponents/processSubmitDialog/components/reissueComponent.vue';
-  import Detail from '@/views/bpm/processInstance/detailNew.vue';
+import dictMixins from '@/mixins/dictMixins';
+import { getToken } from '@/utils/token-util';
+import outgoingDetails from '@/views/bpm/outgoingManagement/details.vue';
+import storageApi from '@/api/warehouseManagement';
 
 
-  
+// 流程组件  需要在三个地方使用,审批流程,详情,提交流程
+import businessComponent from '@/BIZComponents/processSubmitDialog/components/businessComponent.vue';
+import useSealComponent from '@/BIZComponents/processSubmitDialog/components/useSealComponent.vue';
+import useQualificationComponent from '@/BIZComponents/processSubmitDialog/components/useQualificationComponent.vue';
+import productSpecificationComponent from '@/BIZComponents/processSubmitDialog/components/productSpecificationComponent.vue';
+import eventComponent from '@/BIZComponents/processSubmitDialog/components/eventComponent.vue';
+import reissueComponent from '@/BIZComponents/processSubmitDialog/components/reissueComponent.vue';
+import Detail from '@/views/bpm/processInstance/detailNew.vue';
 
 
-  export default {
-    name: 'formDetailDialog',
-    components: {outgoingDetails, businessComponent, useSealComponent, useQualificationComponent, productSpecificationComponent, eventComponent, reissueComponent, Detail},
-    props: {
-      formDetailDialogFlag: {
-        type: Boolean,
-        default: false
-      },
-      view: {
-        type: Boolean,
-        default: false
-      },
+export default {
+  name: 'formDetailDialog',
+  components: {
+    outgoingDetails,
+    businessComponent,
+    useSealComponent,
+    useQualificationComponent,
+    productSpecificationComponent,
+    eventComponent,
+    reissueComponent,
+    Detail
+  },
+  props: {
+    formDetailDialogFlag: {
+      type: Boolean,
+      default: false
     },
     },
-    mixins: [dictMixins],
-    data() {
-      return {
-        form: {},
-        jsonData: {},
-        outgoingData:{},
-        isRight: false,
-      };
-    },
-    computed: {
-      // modelWidth() {
-      //   return (this.outgoingData?.id || this.jsonData.config?.platform && this.jsonData.config.platform === 'pc') ? '80%' : '400px';
-      // }
-      modelWidth() {
-        let width = this.jsonData.config?.platform && this.jsonData.config.platform === 'pc' ? 1100 : 450;
-        if(this.isRight) {
-          return width + 750 + 'px'
-        } else {
-          return width + 'px'
-        }
+    view: {
+      type: Boolean,
+      default: false
+    }
+  },
+  mixins: [dictMixins],
+  data() {
+    return {
+      form: {},
+      jsonData: {},
+      outgoingData: {},
+      isRight: false
+    };
+  },
+  computed: {
+    // modelWidth() {
+    //   return (this.outgoingData?.id || this.jsonData.config?.platform && this.jsonData.config.platform === 'pc') ? '80%' : '400px';
+    // }
+    modelWidth() {
+      let width =
+        this.jsonData.config?.platform && this.jsonData.config.platform === 'pc'
+          ? 1100
+          : 450;
+      if (this.isRight) {
+        return width + 750 + 'px';
+      } else {
+        return width + 'px';
+      }
+    }
+  },
+  methods: {
+    open(row) {
+      this.form = _.cloneDeep(row);
+      if (this.form.id) {
+        storageApi.getInfoBySourceBizNo(this.form.id).then((res) => {
+          this.outgoingData = res;
+        });
       }
       }
+      this.jsonData = JSON.parse(this.form.formJson.makingJson);
+      this.jsonData.config.dataSource &&
+        this.jsonData.config.dataSource.forEach((item) => {
+          item.headers = {
+            Authorization: getToken()
+          };
+          // item.url = item.url && item.url.replace('/api', this.APIUrl);
+        });
     },
     },
-    methods: {
-       open(row) {
-        this.form = _.cloneDeep(row);
-        if(this.form.id){
-          storageApi.getInfoBySourceBizNo(this.form.id).then(res=>{
-          this.outgoingData=res
-        })
-        }
-        this.jsonData = JSON.parse(this.form.formJson.makingJson);
-        this.jsonData.config.dataSource &&
-          this.jsonData.config.dataSource.forEach((item) => {
-            item.headers = {
-              Authorization: getToken()
-            };
-            // item.url = item.url && item.url.replace('/api', this.APIUrl);
-          });
-      },
-      getTimelineItemType(result) {
-        if (result === '通过') {
-          return 'success';
-        }
-        if (result === '不通过') {
-          return 'danger';
-        }
-        if (result === '取消') {
-          return 'info';
-        }
-        if (result === '处理中') {
-          return 'warning';
-        }
-
-        return '';
-      },
-      cancel() {
-        this.$emit('update:formDetailDialogFlag', false);
+    getTimelineItemType(result) {
+      if (result === '通过') {
+        return 'success';
+      }
+      if (result === '不通过') {
+        return 'danger';
+      }
+      if (result === '取消') {
+        return 'info';
+      }
+      if (result === '处理中') {
+        return 'warning';
       }
       }
+
+      return '';
+    },
+    cancel() {
+      this.$emit('update:formDetailDialogFlag', false);
     }
     }
-  };
+  }
+};
 </script>
 </script>
 <style scoped lang="scss">
 <style scoped lang="scss">
-  .eleModalBox {
-    height: 100%;
-    min-width: 300px;
-    overflow: auto;
-  }
+.eleModalBox {
+  height: 100%;
+  min-width: 300px;
+  overflow: auto;
+}
 
 
-  .form-box {
-    // max-height: 500px;
-    min-width: 400px;
-    overflow: auto;
-    background: #4298fd0d;
-  }
+.form-box {
+  // max-height: 500px;
+  min-width: 400px;
+  overflow: auto;
+  background: #4298fd0d;
+}
 
 
-  ::v-deep .el-dialog__header {
-    display: flex;
-    justify-content: space-between;
-  }
-  .blank_adopzrdd {
-    display: flex;
-    align-items: center;
-    > span {
-      display: inline-block;
-      width: 80px;
-    }
-    margin-bottom: 10px;
+::v-deep .el-dialog__header {
+  display: flex;
+  justify-content: space-between;
+}
+.blank_adopzrdd {
+  display: flex;
+  align-items: center;
+  > span {
+    display: inline-block;
+    width: 80px;
   }
   }
+  margin-bottom: 10px;
+}
 </style>
 </style>

+ 16 - 10
src/views/bpm/collaborative/index.vue

@@ -222,7 +222,13 @@
                     </div>
                     </div>
 
 
                     <div v-else-if="item.type == 'userSelect'">
                     <div v-else-if="item.type == 'userSelect'">
-                      {{ getUserName(row[item.model]) }}
+                      <el-link
+                        type="primary"
+                        :underline="false"
+                        @click="handleDetail(row)"
+                      >
+                        {{ getUserName(row[item.model]) }}
+                      </el-link>
                     </div>
                     </div>
                     <div v-else-if="item.type == 'deptAndUserCascader'">
                     <div v-else-if="item.type == 'deptAndUserCascader'">
                       {{ getDeptAndUserName(row[item.model]) }}
                       {{ getDeptAndUserName(row[item.model]) }}
@@ -392,7 +398,7 @@
                         >下载
                         >下载
                       </el-button>
                       </el-button>
                     </div>
                     </div>
-                    <div v-else-if="item.type == 'userSelect'">
+                     <div v-else-if="item.type == 'userSelect'">
                       {{ getUserName(row[item.model]) }}
                       {{ getUserName(row[item.model]) }}
                     </div>
                     </div>
                     <div v-else-if="item.type == 'deptAndUserCascader'">
                     <div v-else-if="item.type == 'deptAndUserCascader'">
@@ -750,14 +756,14 @@ export default {
           showOverflowTooltip: true,
           showOverflowTooltip: true,
           minWidth: 70
           minWidth: 70
         },
         },
-        {
-          prop: 'name',
-          label: '名称',
-          align: 'center',
-          slot: 'name',
-          showOverflowTooltip: true,
-          minWidth: 80
-        },
+        // {
+        //   prop: 'name',
+        //   label: '名称',
+        //   align: 'center',
+        //   slot: 'name',
+        //   showOverflowTooltip: true,
+        //   minWidth: 80
+        // },
         ...list,
         ...list,
         {
         {
           prop: 'result',
           prop: 'result',

+ 1 - 0
src/views/bpm/handleTask/components/contractBook/detailDialog.vue

@@ -169,6 +169,7 @@
       :pricingWay="form.pricingWay"
       :pricingWay="form.pricingWay"
       :isChangeCount="false"
       :isChangeCount="false"
       :isArrivalWay="true"
       :isArrivalWay="true"
+      :isProductionRequirements="form.type == '1'"
       :countObj="{
       :countObj="{
         countKey: 'contractCount',
         countKey: 'contractCount',
         unitKey: 'contractUnit',
         unitKey: 'contractUnit',

+ 4 - 4
src/views/bpm/handleTask/components/financialManage/payableManage/components/detailDialog.vue

@@ -145,8 +145,8 @@
         dialogType: '',
         dialogType: '',
         form: {
         form: {
           accountingSubjectCode: '',
           accountingSubjectCode: '',
-          accountingSubjectId: '1779719367139792004',
-          accountingSubjectName: '应付账款',
+          accountingSubjectId: '',
+          accountingSubjectName: '',
           contactId: '',
           contactId: '',
           contactName: '',
           contactName: '',
           files: [],
           files: [],
@@ -194,8 +194,8 @@
           invoiceData = await invoiceApplyInfoAPI(data.invoiceId);
           invoiceData = await invoiceApplyInfoAPI(data.invoiceId);
         }
         }
         this.form.accountingSubjectCode = invoiceData.accountingSubjectCode;
         this.form.accountingSubjectCode = invoiceData.accountingSubjectCode;
-        this.form.accountingSubjectId = invoiceData.accountingSubjectId || '1779719367139792004';
-        this.form.accountingSubjectName = invoiceData.accountingSubjectName || '应付账款';
+        this.form.accountingSubjectId = invoiceData.accountingSubjectId || '';
+        this.form.accountingSubjectName = invoiceData.accountingSubjectName || '';
       },
       },
       downloadFile(file) {
       downloadFile(file) {
         getFile({ objectName: file.storePath }, file.name);
         getFile({ objectName: file.storePath }, file.name);

+ 4 - 4
src/views/bpm/handleTask/components/financialManage/receivableManage/components/detailDialog.vue

@@ -149,8 +149,8 @@
         dialogType: '',
         dialogType: '',
         form: {
         form: {
           accountingSubjectCode: '',
           accountingSubjectCode: '',
-          accountingSubjectId: '1779719367139791006',
-          accountingSubjectName: '应收账款',
+          accountingSubjectId: '',
+          accountingSubjectName: '',
           contactId: '',
           contactId: '',
           contactName: '',
           contactName: '',
           files: [],
           files: [],
@@ -204,8 +204,8 @@
         }
         }
 
 
         this.form.accountingSubjectCode = invoiceData.accountingSubjectCode;
         this.form.accountingSubjectCode = invoiceData.accountingSubjectCode;
-        this.form.accountingSubjectId = invoiceData.accountingSubjectId || '1779719367139791006';
-        this.form.accountingSubjectName = invoiceData.accountingSubjectName || '应收账款';
+        this.form.accountingSubjectId = invoiceData.accountingSubjectId || '';
+        this.form.accountingSubjectName = invoiceData.accountingSubjectName || '';
       },
       },
       downloadFile(file) {
       downloadFile(file) {
         getFile({ objectName: file.storePath }, file.name);
         getFile({ objectName: file.storePath }, file.name);

+ 9 - 1
src/views/bpm/handleTask/components/productionWarehousing/submit.vue

@@ -76,9 +76,17 @@
         if (!storageData) {
         if (!storageData) {
           return;
           return;
         }
         }
+        console.log('res~~~~~~~~~~~~~~~~', res);
         // 入库来源isSkip 0-正常  1-外部(外部跳过内部审核流程)
         // 入库来源isSkip 0-正常  1-外部(外部跳过内部审核流程)
         storageData.isSkip = 1;
         storageData.isSkip = 1;
-        console.log(storageData);
+        console.log('storageData~~~~~~~~~~~~~~~~', storageData);
+        
+        // 验证outInDetailList中是否存在数量为空的情况
+        if (storageData.outInDetailList && storageData.outInDetailList.some(item => item.number ==undefined || item.number == '' || item.number == null)) {
+          this.$message.error('计量数量不为空');
+          return;
+        }
+        
         try {
         try {
           this.isSaveLoading = true;
           this.isSaveLoading = true;
           let res = await storageApi.storage(storageData);
           let res = await storageApi.storage(storageData);

+ 1 - 0
src/views/bpm/handleTask/components/saleOrder/detailDialog.vue

@@ -206,6 +206,7 @@
         :isCustomerMark="true"
         :isCustomerMark="true"
         :isDiscountTotalPrice="true"
         :isDiscountTotalPrice="true"
         :isArrivalWay="true"
         :isArrivalWay="true"
+        :isProductionRequirements="true"
       ></inventoryTabledetail>
       ></inventoryTabledetail>
       <headerTitle title="类型清单" v-if="form.needProduce == 4"></headerTitle>
       <headerTitle title="类型清单" v-if="form.needProduce == 4"></headerTitle>
 
 

+ 7 - 2
src/views/bpm/handleTask/components/saleOrder/invoice/detailDialog.vue

@@ -259,7 +259,6 @@
       };
       };
     },
     },
     computed: {
     computed: {
-
       columns() {
       columns() {
         let columnsVersion = this.columnsVersion;
         let columnsVersion = this.columnsVersion;
         return [
         return [
@@ -339,6 +338,12 @@
             label: '生产编号',
             label: '生产编号',
             align: 'center'
             align: 'center'
           },
           },
+          {
+            minWidth: 280,
+            prop: 'productionRequirements',
+            label: '生产要求',
+            align: 'center'
+          },
           {
           {
             width: 120,
             width: 120,
             prop: 'imgCode',
             prop: 'imgCode',
@@ -427,7 +432,7 @@
             align: 'center'
             align: 'center'
           },
           },
 
 
-           this.$store.state.user.info.clientEnvironmentId== '4'
+          this.$store.state.user.info.clientEnvironmentId == '4'
             ? {
             ? {
                 width: 120,
                 width: 120,
                 prop: 'blockCount',
                 prop: 'blockCount',

+ 1 - 1
src/views/bpm/handleTask/components/saleOrder/returnGoods/detailDialog.vue

@@ -153,7 +153,7 @@
 
 
     <div style="margin-top: 20px">
     <div style="margin-top: 20px">
       <add
       <add
-        v-if="taskDefinitionKey == 'warehouseManager'" 
+        v-if="taskDefinitionKey == 'warehouseManager'&&form.id" 
         ref="add"
         ref="add"
         :form="form"
         :form="form"
         :sourceBizNo="form.returnNo"
         :sourceBizNo="form.returnNo"

+ 0 - 1
src/views/bpm/handleTask/components/saleOrder/returnGoods/submit.vue

@@ -167,7 +167,6 @@
         // this.$emit('submit');
         // this.$emit('submit');
         let res = await this.getTableValue();
         let res = await this.getTableValue();
         let storageData = res.returnStorageData;
         let storageData = res.returnStorageData;
-   
         if (!storageData) {
         if (!storageData) {
           return;
           return;
         }
         }

+ 1 - 1
src/views/bpm/handleTask/components/saleOrder/saleReturnGoods/detailDialog.vue

@@ -140,7 +140,7 @@
     <keep-alive>
     <keep-alive>
       <add
       <add
         ref="add"
         ref="add"
-        v-if="activeComp == 'inoutBound'"
+        v-if="activeComp == 'inoutBound'&&form.id"
         :form="form"
         :form="form"
         :sourceBizNo="form.returnNo"
         :sourceBizNo="form.returnNo"
         :detailList="form.productList.filter((item) => item.packageId)"
         :detailList="form.productList.filter((item) => item.packageId)"

+ 1145 - 0
src/views/bpm/handleTask/components/salesServiceManagement/demand/salesServiceDialog.vue

@@ -0,0 +1,1145 @@
+<template>
+  <el-form
+    ref="form"
+    :model="form"
+    :rules="rules"
+    label-width="130px"
+    class="create-form"
+  >
+    <!-- 标题区域 -->
+    <headerTitle
+      title="基本信息"
+      style="margin-top: 8px"
+      v-if="isPurchaseNeed"
+    ></headerTitle>
+    <headerTitle
+      title="需求信息"
+      style="margin-top: 8px"
+      v-if="!isPurchaseNeed"
+    ></headerTitle>
+
+    <!-- 基本信息表单区域 -->
+    <el-row :gutter="24" v-if="source != '报工信息'">
+      <el-col :span="6">
+        <el-form-item label="需求编码:">
+          <el-input v-model="form.code" disabled />
+        </el-form-item>
+      </el-col>
+      <el-col :span="6">
+        <el-form-item label="关联类型:">
+          <el-select
+            style="width: 100%"
+            v-model="form.associationType"
+            placeholder="请选择"
+            disabled
+          >
+            <el-option
+              v-for="item in associationTypeList"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="6">
+        <el-form-item label="需求名称:">
+          <el-select
+            style="width: 100%"
+            v-model="form.name"
+            filterable
+            allow-create
+            default-first-option
+            placeholder="请选择需求名称"
+            disabled
+          >
+            <el-option
+              v-for="item in demandList"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="6">
+        <el-form-item label="客户名称:">
+          <el-input
+            v-model="form.contractInfo.contactName"
+            readonly
+            disabled
+            placeholder="请选择"
+          />
+        </el-form-item>
+      </el-col>
+
+      <!-- 关联类型对应的订单展示 -->
+      <el-col :span="6" v-if="form.associationType == '1'">
+        <el-form-item label="发货单:">
+          <el-input
+            v-model="form.orderCode"
+            readonly
+            disabled
+            placeholder="请选择"
+          />
+        </el-form-item>
+      </el-col>
+      <el-col :span="6" v-if="form.associationType == '2'">
+        <el-form-item label="销售订单:">
+          <el-input
+            v-model="form.orderCode"
+            readonly
+            disabled
+            placeholder="请选择"
+          />
+        </el-form-item>
+      </el-col>
+      <el-col :span="6" v-if="form.associationType == '3'">
+        <el-form-item label="产品:">
+          <el-input
+            v-model="form.orderCode"
+            readonly
+            disabled
+            placeholder="请选择"
+          />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="6">
+        <el-form-item label="客户编码:">
+          <el-input v-model="form.contractInfo.code" readonly disabled />
+        </el-form-item>
+      </el-col>
+      <el-col :span="6">
+        <el-form-item label="客户代号:">
+          <el-input v-model="form.contractInfo.serialNo" readonly disabled />
+        </el-form-item>
+      </el-col>
+      <el-col :span="6">
+        <el-form-item label="业务员:">
+          <el-select
+            style="width: 100%"
+            v-model="form.salespersonId"
+            placeholder="请选择业务员"
+            filterable
+            clearable
+            disabled
+          >
+            <el-option
+              v-for="item in userList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="6">
+        <el-form-item label="报修地址:">
+          <el-input v-model="form.contactAddress" readonly disabled />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="6">
+        <el-form-item label="故障等级:">
+          <DictSelection
+            dictName="故障等级"
+            disabled
+            v-model="form.faultLevel"
+          ></DictSelection>
+        </el-form-item>
+      </el-col>
+      <el-col :span="6">
+        <el-form-item label="期望解决时间:">
+          <el-date-picker
+            disabled
+            style="width: 100%"
+            v-model="form.expectedTime"
+            type="date"
+            :picker-options="pickerOptions"
+            placeholder="选择日期时间"
+          ></el-date-picker>
+        </el-form-item>
+      </el-col>
+      <el-col :span="6">
+        <el-form-item label="售后类型:">
+          <el-select
+            style="width: 100%"
+            v-model="form.aftertype"
+            placeholder="请选择"
+            disabled
+          >
+            <el-option
+              v-for="item in aftertypeList"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="6">
+        <el-form-item label="是否收费:">
+          <el-select
+            style="width: 100%"
+            v-model="form.charge"
+            placeholder="请选择"
+            disabled
+          >
+            <el-option
+              v-for="item in chargeList"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="6">
+        <el-form-item label="是否带配件:">
+          <el-select
+            style="width: 100%"
+            v-model="form.part"
+            placeholder="请选择"
+            disabled
+          >
+            <el-option
+              v-for="item in partList"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="6">
+        <el-form-item label="是否派车:">
+          <el-select
+            style="width: 100%"
+            v-model="form.car"
+            placeholder="请选择是否派车"
+            disabled
+          >
+            <el-option
+              v-for="item in carList"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="6" v-if="form.car == '1'">
+        <el-form-item label="派车类型:">
+          <el-select
+            style="width: 100%"
+            v-model="form.pietype"
+            placeholder="请选择"
+            disabled
+          >
+            <el-option
+              v-for="item in pietypeList"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="6">
+        <el-form-item label="是否外包:">
+          <el-select
+            style="width: 100%"
+            v-model="form.isOutsource"
+            placeholder="请选择是否外包"
+            disabled
+          >
+            <el-option
+              v-for="item in outsourceList"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="6" v-if="form.isOutsource == '1'">
+        <el-form-item label="供应商名称:">
+          <el-input
+            v-model="form.supplierName"
+            placeholder="请选择供应商名称"
+            readonly
+            disabled
+          ></el-input>
+        </el-form-item>
+      </el-col>
+      <el-col :span="6">
+        <el-form-item label="是否生成采购订单:">
+          <el-select
+            style="width: 100%"
+            v-model="form.isCreatePurchaseOrder"
+            placeholder="请选择是否生成采购订单"
+            disabled
+          >
+            <el-option
+              v-for="item in isCreatePurchaseOrderList"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="6">
+        <el-form-item label="涉及事业部门:">
+          <ele-tree-select
+            v-model="form.involveDeptId"
+            :data="deptTreeData"
+            label-key="name"
+            value-key="id"
+            clearable
+            default-expand-all
+            placeholder="请选择"
+            disabled
+          />
+        </el-form-item>
+      </el-col>
+      <el-col :span="6">
+        <el-form-item label="备注说明:" class="remark-input">
+          <el-input
+            v-model="form.remark"
+            type="textarea"
+            rows="2"
+            placeholder="请输入备注信息(选填)"
+            readonly
+            disabled
+          ></el-input>
+        </el-form-item>
+      </el-col>
+    </el-row>
+
+    <!-- 售后方案区域 -->
+    <headerTitle
+      title="售后方案"
+      style="margin-top: 10px"
+      v-if="isPurchaseNeed"
+    ></headerTitle>
+    <spareParts
+      ref="sparePartsRef"
+      type="view"
+      :source="source"
+      obtain="售后"
+      :is-after-sales="true"
+      v-if="isPurchaseNeed"
+    />
+
+    <!-- 售后对象/故障信息区域 -->
+    <div class="after_sales_target" v-if="salesShow">
+      <headerTitle
+        title="售后对象"
+        style="margin-top: 10px"
+        v-if="isPurchaseNeed"
+      ></headerTitle>
+      <ele-pro-table
+        ref="tableRef3"
+        :columns="columnsDetail"
+        :datasource="form.tableList"
+        :need-page="false"
+        :toolbar="false"
+        maxHeight="300px"
+        row-key="id"
+        default-expand-all
+      >
+        <template v-slot:measureQuantity="{ row }">
+          <el-input
+            v-model="row.measureQuantity"
+            type="number"
+            :min="1"
+            placeholder="请输入"
+            disabled
+          ></el-input>
+        </template>
+        <template v-slot:batchNo="{ row }">
+          <el-input
+            v-model="row.batchNo"
+            placeholder="请输入"
+            disabled
+          ></el-input>
+        </template>
+        <template v-slot:barcodes="{ row }">
+          <el-input
+            v-model="row.barcodes"
+            placeholder="请输入"
+            disabled
+          ></el-input>
+        </template>
+        <template v-slot:shipmentDate="{ row }">
+          <el-date-picker
+            v-model="row.shipmentDate"
+            type="datetime"
+            placeholder="选择结束时间"
+            format="yyyy-MM-dd HH:mm:ss"
+            value-format="yyyy-MM-dd HH:mm:ss"
+            disabled
+          ></el-date-picker>
+        </template>
+
+        <template v-slot:expand="{ row, $index }">
+          <div
+            style="
+              width: calc(100% - 55px);
+              min-height: 60px;
+              margin-left: 55px;
+            "
+            v-if="row.faultDetails && row.faultDetails.length > 0"
+          >
+            <ele-pro-table
+              :columns="faultList"
+              :datasource="row.faultDetails || []"
+              :need-page="false"
+              maxHeight="300px"
+              class="el-form-box"
+              :toolkit="[]"
+            >
+              <template v-slot:type="{ row }">
+                <el-select
+                  v-model="row.type"
+                  disabled
+                  :placeholder="
+                    form.aftertype === '3' ? '请选择质量类型' : '请选择故障类型'
+                  "
+                >
+                  <el-option
+                    v-for="item in form.aftertype === '3'
+                      ? qualityTypeOptions
+                      : typeOptions"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  ></el-option>
+                </el-select>
+              </template>
+              <template v-slot:faultPhenomenon="{ row }">
+                <el-input
+                  v-model="row.faultPhenomenon"
+                  placeholder="请输入"
+                  disabled
+                ></el-input>
+              </template>
+              <template v-slot:faultReason="{ row }">
+                <el-input
+                  v-model="row.faultReason"
+                  placeholder="请输入"
+                  disabled
+                ></el-input>
+              </template>
+              <template v-slot:maintenanceProcess="{ row }">
+                <el-input
+                  v-model="row.maintenanceProcess"
+                  placeholder="请输入"
+                  disabled
+                ></el-input>
+              </template>
+              <template v-slot:attachments="{ row }">
+                <fileMain v-model="row.attachments" type="view"></fileMain>
+              </template>
+
+              <template v-slot:headerType="{ column }">
+                <span>{{
+                  form.aftertype === '3' ? '质量类型' : column.label
+                }}</span>
+              </template>
+              <template v-slot:headerPhenomenon="{ column }">
+                <span>{{
+                  form.aftertype === '3' ? '质量问题反馈' : column.label
+                }}</span>
+              </template>
+              <template v-slot:headerMaintenance="{ column }">
+                <span>{{
+                  form.aftertype === '3' ? '质量处理方式' : column.label
+                }}</span>
+              </template>
+              <template v-slot:headerFaultReason="{ column }">
+                <span>{{
+                  form.aftertype === '3' ? '质量问题分析' : column.label
+                }}</span>
+              </template>
+            </ele-pro-table>
+          </div>
+        </template>
+
+        <template v-slot:useLocation="{ row }">
+          <el-input v-model="row.useLocation" disabled></el-input>
+        </template>
+      </ele-pro-table>
+    </div>
+
+    <div class="fault_infor" v-else>
+      <headerTitle
+        title="故障信息"
+        style="margin-top: 10px"
+        v-if="form.aftertype !== '3'"
+      ></headerTitle>
+      <headerTitle
+        title="质量反馈信息"
+        style="margin-top: 10px"
+        v-if="form.aftertype === '3'"
+      ></headerTitle>
+
+      <ele-pro-table
+        :columns="faultList"
+        :datasource="form.faultDetailList"
+        :need-page="false"
+        maxHeight="300px"
+        class="el-form-box"
+        :toolkit="[]"
+      >
+        <template v-slot:type="{ row }">
+          <el-select
+            v-model="row.type"
+            disabled
+            :placeholder="
+              form.aftertype === '3' ? '请选择质量类型' : '请选择故障类型'
+            "
+          >
+            <el-option
+              v-for="item in form.aftertype === '3'
+                ? qualityTypeOptions
+                : typeOptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+        </template>
+        <template v-slot:faultPhenomenon="{ row }">
+          <el-input
+            v-model="row.faultPhenomenon"
+            placeholder="请输入"
+            disabled
+          ></el-input>
+        </template>
+        <template v-slot:faultReason="{ row }">
+          <el-input
+            v-model="row.faultReason"
+            placeholder="请输入"
+            disabled
+          ></el-input>
+        </template>
+        <template v-slot:maintenanceProcess="{ row }">
+          <el-input
+            v-model="row.maintenanceProcess"
+            placeholder="请输入"
+            disabled
+          ></el-input>
+        </template>
+        <template v-slot:attachments="{ row }">
+          <fileMain v-model="row.attachments" type="view"></fileMain>
+        </template>
+
+        <template v-slot:headerType="{ column }">
+          <span>{{ form.aftertype === '3' ? '质量类型' : column.label }}</span>
+        </template>
+        <template v-slot:headerPhenomenon="{ column }">
+          <span>{{
+            form.aftertype === '3' ? '质量问题反馈' : column.label
+          }}</span>
+        </template>
+        <template v-slot:headerMaintenance="{ column }">
+          <span>{{
+            form.aftertype === '3' ? '质量处理方式' : column.label
+          }}</span>
+        </template>
+        <template v-slot:headerFaultReason="{ column }">
+          <span>{{
+            form.aftertype === '3' ? '质量问题分析' : column.label
+          }}</span>
+        </template>
+      </ele-pro-table>
+    </div>
+
+    <!-- 联系人信息区域 -->
+    <headerTitle
+      title="联系人信息"
+      style="margin-top: 10px"
+      v-if="isPurchaseNeed"
+    ></headerTitle>
+    <ele-pro-table
+      :style="{ marginTop: isPurchaseNeed ? 0 : '10px' }"
+      ref="table"
+      :columns="bankColumns"
+      :datasource="form.contactInfoVOS"
+      :toolkit="[]"
+      class="el-form-box"
+      :need-page="false"
+      v-if="source != '报工信息'"
+    >
+      <template v-slot:contactName="{ row }">
+        <el-input
+          v-model="row.contactName"
+          placeholder="请输入"
+          disabled
+          maxlength="50"
+        ></el-input>
+      </template>
+      <template v-slot:contactPhone="{ row }">
+        <el-input
+          v-model="row.contactPhone"
+          placeholder="请输入"
+          disabled
+        ></el-input>
+      </template>
+      <template v-slot:post="{ row }">
+        <el-input v-model="row.post" placeholder="请输入" disabled></el-input>
+      </template>
+      <template v-slot:telephone="{ row }">
+        <el-input
+          v-model="row.telephone"
+          placeholder="请输入"
+          disabled
+        ></el-input>
+      </template>
+      <template v-slot:email="{ row }">
+        <el-input v-model="row.email" placeholder="请输入" disabled></el-input>
+      </template>
+      <template v-slot:wechat="{ row }">
+        <el-input v-model="row.wechat" placeholder="请输入" disabled></el-input>
+      </template>
+      <template v-slot:deptName="{ row }">
+        <el-input
+          v-model="row.deptName"
+          placeholder="请输入"
+          disabled
+        ></el-input>
+      </template>
+      <template v-slot:remark="{ row }">
+        <el-input v-model="row.remark" placeholder="请输入" disabled></el-input>
+      </template>
+    </ele-pro-table>
+  </el-form>
+</template>
+
+<script>
+import fileMain from '@/components/addDoc/index.vue';
+import dictMixins from '@/mixins/dictMixins';
+import { mapGetters } from 'vuex';
+import spareParts from './sparePartsList.vue';
+import { getByCode } from '@/api/system/dictionary-data';
+import { listOrganizations } from '@/api/system/organization';
+import { getUserPage } from '@/api/system/organization';
+import { getSalesDemandById, contactDetail } from '@/api/afterSales/index';
+
+export default {
+  mixins: [dictMixins],
+  components: {
+    fileMain,
+    spareParts
+  },
+  computed: {
+    ...mapGetters(['getDictValue']),
+    sxtValueLabelMap() {
+      return this.sxtList.reduce((map, item) => {
+        map[item.value] = item.label;
+        return map;
+      }, {});
+    },
+    salesShow() {
+      if (this.form.associationType === '1') return true;
+      if (this.form.tableList.length > 0) return true;
+      if (this.form.associationType === '2' && !this.isOrder) return true;
+      return false;
+    },
+    bankColumns() {
+      return [
+        {
+          label: '序号',
+          type: 'index',
+          width: 55,
+          align: 'center'
+        },
+        {
+          label: '姓名',
+          prop: 'contactName',
+          slot: 'contactName',
+          align: 'center'
+        },
+        {
+          label: '手机',
+          prop: 'contactPhone',
+          slot: 'contactPhone',
+          align: 'center'
+        },
+        {
+          label: '电话',
+          prop: 'telephone',
+          slot: 'telephone',
+          align: 'center'
+        },
+        {
+          label: '微信号',
+          prop: 'wechat',
+          slot: 'wechat',
+          align: 'center'
+        },
+        {
+          label: '邮箱',
+          prop: 'email',
+          slot: 'email',
+          align: 'center'
+        },
+        {
+          label: '部门',
+          prop: 'deptName',
+          slot: 'deptName',
+          align: 'center'
+        },
+        {
+          label: '职务',
+          prop: 'post',
+          slot: 'post',
+          align: 'center'
+        },
+        {
+          label: '备注',
+          prop: 'remark',
+          slot: 'remark',
+          align: 'center'
+        }
+      ];
+    },
+    columnsDetail() {
+      return [
+        {
+          columnKey: 'index',
+          label: '序号',
+          type: 'index',
+          width: 55,
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          width: 45,
+          type: 'expand',
+          columnKey: 'expand',
+          align: 'center',
+          slot: 'expand'
+        },
+        {
+          prop: 'productCategoryName',
+          label: '类型',
+          align: 'center',
+          showOverflowTooltip: true,
+          width: 200
+        },
+        {
+          prop: 'categoryCode',
+          label: '编码',
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'categoryName',
+          label: '名称',
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'categoryModel',
+          label: '型号',
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          slot: 'batchNo',
+          prop: 'batchNo',
+          label: '批次号',
+          align: 'center',
+          minWidth: 135
+        },
+        {
+          slot: 'barcodes',
+          prop: 'barcodes',
+          label: '发货条码',
+          align: 'center',
+          minWidth: 135
+        },
+        {
+          slot: 'shipmentDate',
+          prop: 'shipmentDate',
+          label: '发货时间',
+          align: 'center',
+          minWidth: 180
+        },
+        {
+          prop: 'guaranteePeriodDeadline',
+          label: '有效期',
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'warrantyStatus',
+          label: '质保状态',
+          align: 'center',
+          showOverflowTooltip: true,
+          formatter: (_row) =>
+            _row.warrantyStatus === 1 ? '有效期外' : '有效期内'
+        },
+        {
+          slot: 'measureQuantity',
+          prop: 'measureQuantity',
+          label: '计量数量',
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'singlePrice',
+          label: '单价(元)',
+          align: 'center',
+          showOverflowTooltip: true
+        }
+      ];
+    },
+    faultList() {
+      const isQualityScene = this.form.aftertype === '3';
+      return [
+        {
+          type: 'index',
+          label: '序号',
+          align: 'center',
+          width: 60
+        },
+        {
+          prop: 'type',
+          slot: 'type',
+          label: isQualityScene ? '质量类型' : '故障类型',
+          align: 'center',
+          headerSlot: 'headerType',
+          showOverflowTooltip: true,
+          width: 120
+        },
+        {
+          prop: 'faultPhenomenon',
+          slot: 'faultPhenomenon',
+          headerSlot: 'headerPhenomenon',
+          label: isQualityScene ? '质量问题反馈' : '故障现象',
+          align: 'center',
+          minWidth: 240
+        },
+        {
+          prop: 'faultReason',
+          slot: 'faultReason',
+          headerSlot: 'headerFaultReason',
+          label: isQualityScene ? '质量问题分析' : '故障原因',
+          align: 'center',
+          minWidth: 340
+        },
+        {
+          prop: 'maintenanceProcess',
+          slot: 'maintenanceProcess',
+          headerSlot: 'headerMaintenance',
+          label: isQualityScene ? '质量处理方式' : '维修过程',
+          align: 'center',
+          width: 340
+        },
+        {
+          prop: 'imageUrl',
+          slot: 'imageUrl',
+          label: '查看拍照',
+          align: 'center',
+          width: 120
+        }
+      ];
+    },
+    tableOperate() {
+      return false;
+    },
+    faultOperate() {
+      return () => false;
+    },
+    change_permission() {
+      return true;
+    },
+    fileStr() {
+      return 'view';
+    },
+    imageUrleng() {
+      return (row) => (row.imageUrl ? row.imageUrl.length : 0);
+    }
+  },
+  props: {
+    businessId: {
+      default: '',
+      required: true
+    },
+    isPurchaseNeed: {
+      default: true,
+      type: Boolean
+    },
+    source: {
+      default: '',
+      type: String
+    },
+    demandList: {
+      type: Array,
+      default: () => []
+    }
+  },
+  watch: {
+    demandList: {
+      handler(val) {
+        this.demandList = val;
+      },
+      deep: true,
+      immediate: true
+    }
+  },
+  data() {
+    return {
+      userList: [],
+      pickerOptions: {
+        disabledDate(time) {
+          return time.getTime() < new Date().setHours(0, 0, 0, 0);
+        }
+      },
+      detailList: [],
+      chargeList: [
+        { label: '是', value: '1' },
+        { label: '否', value: '0' }
+      ],
+      partList: [
+        { label: '是', value: '1' },
+        { label: '否', value: '0' }
+      ],
+      carList: [
+        { label: '是', value: '1' },
+        { label: '否', value: '0' }
+      ],
+      typeOptions: [
+        { label: '维修', value: '1' },
+        { label: '保养', value: '2' },
+        { label: '安装', value: '3' }
+      ],
+      qualityTypeOptions: [],
+      outsourceList: [
+        { label: '是', value: '1' },
+        { label: '否', value: '0' }
+      ],
+      isCreatePurchaseOrderList: [
+        { label: '是', value: '1' },
+        { label: '否', value: '0' }
+      ],
+      sxtList: [
+        { label: '自制件', value: '1' },
+        { label: '采购件', value: '2' },
+        { label: '外协件', value: '3' },
+        { label: '受托件', value: '4' }
+      ],
+      form: {
+        contractInfo: {},
+        tableList: [],
+        contactInfoVOS: [],
+        faultDetailList: [],
+        associationType: '1',
+        aftertype: '',
+        salespersonName: '',
+        salespersonId: '',
+        charge: '',
+        part: '',
+        car: '',
+        pietype: '',
+        isOutsource: '0',
+        isCreatePurchaseOrder: '0',
+        supplierName: '',
+        supplierId: '',
+        supplierCode: '',
+        involveDeptId: '',
+        involveDeptName: '',
+        remark: ''
+      },
+      rules: {},
+      associationTypeList: [
+        { value: '1', label: '发货单' },
+        { value: '2', label: '销售订单' },
+        { value: '3', label: '客户' }
+      ],
+      isOrder: false,
+      aftertypeList: [],
+      pietypeList: [],
+      deptTreeData: []
+    };
+  },
+  async created() {
+    // 独立加载每个字典,单独捕获错误,不阻塞整体流程
+    await this.loadDict('after_sales_type', 'aftertypeList', '售后类型');
+    await this.loadDict('pie_car_type', 'pietypeList', '派车类型');
+    await this.loadDict('after_sale_quality_type', 'qualityTypeOptions', '质量类型');
+    
+    // 其他初始化操作
+    await this.getUserList().catch(err => {
+      this.$message.error(`获取用户列表失败:${err.message}`);
+    });
+    await this.getDeptTreeData().catch(err => {
+      this.$message.error(`获取部门数据失败:${err.message}`);
+    });
+  },
+  mounted() {
+    this.getDetail(this.businessId);
+  },
+  methods: {
+    async getDetail(id) {
+      try {
+        const res = await getSalesDemandById(id);
+        if (!res || res.code !== '0' || !res.data) {
+          this.$message.error('获取详情失败:接口返回异常');
+          return;
+        }
+        this.init(res.data);
+      } catch (err) {
+        this.$message.error(`获取详情失败:${err.message}`);
+      }
+    },
+    /**
+     * 通用字典加载方法(核心修改:兼容数组/对象两种数据格式)
+     * @param {String} dictCode - 字典编码(如pie_car_type)
+     * @param {String} targetKey - 存储字典的data属性名(如pietypeList)
+     * @param {String} dictName - 字典名称(用于错误提示)
+     */
+    async loadDict(dictCode, targetKey, dictName) {
+      try {
+        const res = await getByCode(dictCode);
+        // 1. 基础校验:接口是否返回成功且有数据
+        if (res.code !== '0' || !res.data) { // 注意:接口返回code是字符串"0",需匹配类型
+          throw new Error(`接口返回异常(code: ${res.code},data: ${res.data ? '存在' : '不存在'})`);
+        }
+
+        // 2. 核心修改:兼容数组/对象两种格式的data
+        let dictItems = [];
+        if (Array.isArray(res.data)) {
+          // 格式1:data是数组(如[{ "1": "工时" }, { "2": "零配件" }])
+          dictItems = res.data;
+        } else {
+          // 格式2:data是对象(如{ "1": "工时", "2": "零配件" })
+          dictItems = Object.values(res.data);
+        }
+
+        // 3. 解析字典数据:提取键值对,确保value为字符串
+        const dictData = dictItems.map(el => {
+          // 每个el是单个键值对对象(如{ "1": "工时" })
+          const key = Object.keys(el)[0];
+          const value = Object.values(el)[0];
+          return { 
+            label: value || '', // 防止label为空
+            value: String(key)  // 强制转为字符串,与表单value类型匹配
+          };
+        });
+
+        // 4. 赋值到目标变量
+        this[targetKey] = dictData;
+        console.log(`【${dictName}】字典加载成功:`, dictData); // 可选:调试用
+      } catch (err) {
+        // 单独提示某个字典失败,不影响其他功能
+        this.$message.warning(`获取${dictName}字典失败:${err.message}`);
+        // 赋值空数组,避免渲染报错
+        this[targetKey] = [];
+      }
+    },
+    async getDeptTreeData() {
+      const deptRes = await listOrganizations();
+      this.deptTreeData = this.$util.toTreeData({
+        data: deptRes || [],
+        idField: 'id',
+        parentIdField: 'parentId'
+      });
+    },
+    async getUserList() {
+      const res = await getUserPage({ pageNum: 1, pageSize: -1 });
+      this.userList = res?.list || [];
+    },
+    init(res) {
+      const productDetail = res.productDetail || [];
+      this.$set(this.form, 'tableList', productDetail);
+      this.$set(this.form, 'orderCode', res.orderCode);
+      this.$set(this.form, 'orderId', res.orderId);
+      this.$set(this.form, 'contactInfoVOS', res.contactInfoVOS || []);
+      this.$set(this.form, 'name', res.name);
+      this.$set(this.form, 'faultLevel', res.faultLevel ? String(res.faultLevel) : '');
+      this.$set(this.form, 'code', res.code);
+      this.$set(this.form, 'expectedTime', res.expectedTime);
+      this.$set(this.form, 'contactAddress', res.contactAddress || '');
+
+      this.contactDetail(res.contactId, 'init');
+      this.form.associationType = res.associationType ? String(res.associationType) : '1';
+      this.$set(this.form, 'faultDetailList', res.faultDetailList || []);
+      this.isOrder = res.faultDetailList?.length > 0;
+
+      this.$set(this.form, 'aftertype', res.afterSalesType ? String(res.afterSalesType) : '');
+      this.$set(this.form, 'charge', res.isFee !== undefined ? String(res.isFee) : '');
+      this.$set(this.form, 'part', res.isWithAccessories !== undefined ? String(res.isWithAccessories) : '');
+      this.$set(this.form, 'car', res.isPieCar !== undefined ? String(res.isPieCar) : '');
+      this.$set(this.form, 'pietype', res.pieCarType ? String(res.pieCarType) : '');
+      this.$set(this.form, 'salespersonName', res.salespersonName || '');
+      this.$set(this.form, 'salespersonId', res.salespersonId || '');
+      this.$set(this.form, 'isOutsource', res.isOutsource !== undefined ? String(res.isOutsource) : '0');
+      this.$set(this.form, 'isCreatePurchaseOrder', res.isCreatePurchaseOrder !== undefined ? String(res.isCreatePurchaseOrder) : '0');
+      this.$set(this.form, 'remark', res.remark || '');
+      this.$set(this.form, 'involveDeptId', res.involveDeptId ?? '');
+      this.$set(this.form, 'involveDeptName', res.involveDeptName ?? '');
+      this.$set(this.form, 'supplierId', res.supplierId ?? '');
+      this.$set(this.form, 'supplierName', res.supplierName ?? '');
+      this.$set(this.form, 'supplierCode', res.supplierCode ?? '');
+      this.$set(this, 'detailList', res.costListVOS || []);
+
+      this.$nextTick(() => {
+        if (this.$refs.sparePartsRef && this.detailList.length > 0) {
+          this.$refs.sparePartsRef.setTableValue(this.detailList);
+        }
+      });
+    },
+    async contactDetail(id, type) {
+      if (!id) {
+        this.contractInfo = {};
+        return;
+      }
+      try {
+        const { base, other } = await contactDetail(id);
+        base.contactName = base.name;
+        const addressName = `${other.addressName || ''}${other.address || ''}`;
+        this.$set(this.form, 'contractInfo', base);
+        if (type !== 'init') {
+          this.$set(this.form, 'contactAddress', addressName);
+        }
+      } catch (err) {
+        this.$message.error(`获取客户详情失败:${err.message}`);
+      }
+    },
+    getValue() {
+      return this.form;
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+:deep(.el-table__body .el-form-item__content) {
+  margin-left: 0px !important;
+}
+:deep(.el-table__body .el-form-item) {
+  margin-bottom: 0px !important;
+}
+.reserve {
+  margin-left: 16px;
+  color: #e6a23c;
+}
+:deep(.el-row) {
+  display: flex;
+  flex-wrap: wrap;
+}
+:deep(.remark-input .el-textarea__inner) {
+  color: #f56c6c !important;
+}
+:deep(.remark-input .el-textarea.is-disabled .el-textarea__inner) {
+  color: #f56c6c !important;
+}
+</style>

+ 474 - 0
src/views/bpm/handleTask/components/salesServiceManagement/demand/sparePartsList.vue

@@ -0,0 +1,474 @@
+<template>
+  <div class="ele-body">
+    <el-form ref="form" :model="form" label-width="100px" class="create-form">
+      <ele-pro-table
+        ref="tableRef2"
+        :columns="columnsDetail"
+        :datasource="form.tableList"
+        tool-class="ele-toolbar-form"
+        :initLoad="false"
+        :need-page="false"
+        height="300px"
+      >
+        <!-- 工具栏:仅保留合计显示,隐藏添加按钮 -->
+        <template v-slot:toolbar>
+          <div class="toobar toobar_r">
+            <span class="total_price">总计: {{ totalPrice }} (元)</span>
+          </div>
+        </template>
+
+        <!-- 项目类型:禁用下拉 -->
+        <template v-slot:typeId="scope">
+          <el-form-item
+            style="margin-bottom: 20px"
+            :prop="'tableList.' + scope.$index + '.typeId'"
+          >
+            <el-select
+              v-model="scope.row.typeId"
+              placeholder="请选择"
+              class="w100"
+              disabled
+            >
+              <el-option
+                v-for="item in typeIdList"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </template>
+
+        <!-- 费用类别:禁用下拉 -->
+        <template v-slot:feeType="scope">
+          <el-form-item
+            style="margin-bottom: 20px"
+            :prop="'tableList.' + scope.$index + '.feeType'"
+          >
+            <el-select
+              v-model="scope.row.feeType"
+              placeholder="请选择"
+              class="w100"
+              disabled
+            >
+              <el-option
+                v-for="item in feeTypeList"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </template>
+
+        <!-- 编码:纯文本展示 -->
+        <template v-slot:code="scope">
+          <el-form-item
+            style="margin-bottom: 20px"
+            :prop="'tableList.' + scope.$index + '.code'"
+          >
+            <span>{{ scope.row.code || '-' }}</span>
+          </el-form-item>
+        </template>
+
+        <!-- 名称:纯文本展示(隐藏选择按钮) -->
+        <template v-slot:name="scope">
+          <el-form-item
+            style="margin-bottom: 20px"
+            :prop="'tableList.' + scope.$index + '.name'"
+          >
+            <span>{{ scope.row.name || '-' }}</span>
+          </el-form-item>
+        </template>
+
+        <!-- 型号:纯文本展示 -->
+        <template v-slot:categoryModel="scope">
+          <el-form-item
+            style="margin-bottom: 20px"
+            :prop="'tableList.' + scope.$index + '.categoryModel'"
+          >
+            <span>{{ scope.row.categoryModel || '-' }}</span>
+          </el-form-item>
+        </template>
+
+        <!-- 规格:纯文本展示 -->
+        <template v-slot:specification="scope">
+          <el-form-item
+            style="margin-bottom: 20px"
+            :prop="'tableList.' + scope.$index + '.specification'"
+          >
+            <span>{{ scope.row.specification || '-' }}</span>
+          </el-form-item>
+        </template>
+
+        <!-- 详细内容:纯文本展示 -->
+        <template v-slot:content="scope">
+          <el-form-item
+            style="margin-bottom: 20px"
+            :prop="'tableList.' + scope.$index + '.content'"
+          >
+            <span>{{ scope.row.content || '-' }}</span>
+          </el-form-item>
+        </template>
+
+        <!-- 数量:纯文本展示 -->
+        <template v-slot:totalCount="scope">
+          <el-form-item
+            style="margin-bottom: 20px"
+            :prop="'tableList.' + scope.$index + '.totalCount'"
+          >
+            <span>{{ scope.row.totalCount || '0' }}</span>
+          </el-form-item>
+        </template>
+
+        <!-- 单位:纯文本展示 -->
+        <template v-slot:measureUnit="scope">
+          <el-form-item
+            style="margin-bottom: 20px"
+            :prop="'tableList.' + scope.$index + '.measureUnit'"
+          >
+            <span>{{ scope.row.measureUnit || '-' }}</span>
+          </el-form-item>
+        </template>
+
+        <!-- 单价:纯文本展示 -->
+        <template v-slot:singlePrice="scope">
+          <el-form-item
+            style="margin-bottom: 20px"
+            :prop="'tableList.' + scope.$index + '.singlePrice'"
+          >
+            <span>{{ scope.row.singlePrice || '0' }}</span>
+          </el-form-item>
+        </template>
+
+        <!-- 仓库:纯文本展示(显示仓库名称,隐藏下拉) -->
+        <template v-slot:warehouseId="scope">
+          <el-form-item
+            style="margin-bottom: 20px"
+            :prop="'tableList.' + scope.$index + '.warehouseId'"
+          >
+            <span>{{ scope.row.warehouseName || '-' }}</span>
+          </el-form-item>
+        </template>
+
+      </ele-pro-table>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import { getWarehouseOutStock, getIdWarehouseList } from '@/api/afterSales/index';
+import { getByCode } from '@/api/system/dictionary-data';
+
+export default {
+  components: {},
+  props: {
+    source: {
+      default: '',
+      type: String
+    },
+    detailList: {
+      type: Array,
+      default: () => []
+    },
+    obtain: {
+      type: String,
+      default: '主数据'
+    },
+    hideFeeType: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      loading: false,
+      form: {
+        tableList: [] // 展示用数据列表
+      },
+      totalPrice: 0, // 合计金额(保留展示)
+      typeIdList: [], // 项目类型字典(核心修复点)
+      feeTypeList: [ // 费用类别字典(硬编码,已适配字符串value)
+        { label: '收入', value: '1' },
+        { label: '支出', value: '2' }
+      ]
+    };
+  },
+  created() {
+    // 初始化项目类型字典(修复后)
+    if (this.source !== '配件回收') { // 配件回收场景固定字典,无需请求
+      this.getLevelCode('after_sales_project');
+    }
+  },
+  computed: {
+    // 表格列配置:隐藏操作列,调整展示逻辑
+    columnsDetail() {
+      return [
+        {
+          columnKey: 'index',
+          label: '序号',
+          type: 'index',
+          width: 55,
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'typeId',
+          label: '项目',
+          align: 'center',
+          width: 120,
+          slot: 'typeId',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'code',
+          label: '编码',
+          align: 'center',
+          slot: 'code',
+          minWidth: 150,
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'feeType',
+          label: '费用类别',
+          align: 'center',
+          slot: 'feeType',
+          minWidth: 150,
+          showOverflowTooltip: true,
+          show: !this.hideFeeType // 保留原隐藏逻辑
+        },
+        {
+          prop: 'name',
+          label: '名称',
+          align: 'center',
+          minWidth: 250,
+          slot: 'name',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'categoryModel',
+          label: '型号',
+          width: 150,
+          align: 'center',
+          slot: 'categoryModel',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'specification',
+          width: 150,
+          label: '规格',
+          slot: 'specification',
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'content',
+          minWidth: 300,
+          slot: 'content',
+          label: '详细内容',
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'warehouseId',
+          minWidth: 170,
+          slot: 'warehouseId',
+          label: '仓库',
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'warehouseNum',
+          minWidth: 100,
+          label: '库存',
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'totalCount',
+          slot: 'totalCount',
+          width: 100,
+          label: '数量',
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'measureUnit',
+          width: 120,
+          slot: 'measureUnit',
+          label: '单位',
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'singlePrice',
+          slot: 'singlePrice',
+          width: 120,
+          label: '单价(元)',
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'settlementPrice',
+          width: 80,
+          label: '合计(元)',
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        // 完全隐藏操作列
+        {
+          columnKey: 'action',
+          label: '操作',
+          width: 150,
+          align: 'center',
+          resizable: false,
+          slot: 'action',
+          fixed: 'right',
+          showOverflowTooltip: true,
+          show: false
+        }
+      ];
+    },
+    // 以下计算属性均返回固定值,确保操作元素不显示、组件禁用
+    chooseShow() {
+      return () => false; // 隐藏"选择"按钮
+    },
+    buttonJud() {
+      return false; // 隐藏"添加"按钮
+    },
+    schemeOperate() {
+      return () => false; // 隐藏"删除"按钮
+    },
+    schemeTableTool() {
+      return () => true; // 所有表格组件禁用
+    },
+    inputOperate() {
+      return () => true; // 所有输入组件禁用
+    }
+  },
+  watch: {
+    // 监听传入的详情数据,格式化后渲染(修复:类型Id转字符串)
+    detailList: {
+      handler(newVal) {
+        const formattedList = newVal.map((item) => ({
+          ...item,
+          feeType: (item.feeType || '1').toString(), // 费用类别转字符串
+          typeId: (item.typeId || '').toString(), // 项目类型转字符串(核心修复)
+          warehouseName: item.warehouseName || '', // 确保仓库名称有值
+          settlementPrice: item.settlementPrice || (Number(item.totalCount) * Number(item.singlePrice) || 0) // 补全合计金额(修复数字计算)
+        }));
+        this.form.tableList = formattedList;
+        this.calculatePrice(); // 计算合计
+      },
+      immediate: true
+    }
+  },
+  mounted() {
+    // 配件回收场景:固定项目类型为"零配件"(确保value是字符串)
+    if (this.source === '配件回收') {
+      this.typeIdList = [{ label: '零配件', value: '2' }];
+      // 触发一次数据格式化(防止watch未覆盖)
+      if (this.detailList.length > 0) {
+        this.watch.detailList.handler(this.detailList);
+      }
+    }
+  },
+  methods: {
+    // 初始化项目类型字典(核心修复:兼容接口格式+类型匹配)
+    async getLevelCode(code) {
+      try {
+        const res = await getByCode(code);
+        // 修复1:接口code是字符串"0",而非数字0
+        if (res.code !== '0' || !res.data) {
+          throw new Error(`接口返回异常(code: ${res.code})`);
+        }
+
+        // 修复2:兼容接口返回的"数组"或"对象"格式
+        let dictItems = [];
+        if (Array.isArray(res.data)) {
+          dictItems = res.data; // 格式1:[{ "1": "工时" }, { "2": "零配件" }]
+        } else {
+          dictItems = Object.values(res.data); // 格式2:{ "1": "工时", "2": "零配件" }
+        }
+
+        // 修复3:解析为label-value格式,确保value是字符串
+        this.typeIdList = dictItems.map(el => {
+          const key = Object.keys(el)[0];
+          const value = Object.values(el)[0];
+          return {
+            label: value || '', // 防止空label
+            value: String(key) // 强制转为字符串,与表单typeId匹配
+          };
+        });
+
+        console.log('项目类型字典加载成功:', this.typeIdList); // 调试用
+      } catch (err) {
+        this.$message.error(`获取项目类型字典失败:${err.message}`);
+        this.typeIdList = []; // 避免渲染报错
+      }
+    },
+    // 计算合计金额(修复:确保数字类型计算)
+    calculatePrice() {
+      this.totalPrice = this.form.tableList.reduce((total, item) => {
+        return total + (Number(item.settlementPrice) || 0); // 转为数字计算
+      }, 0);
+    },
+    // 接收外部数据并格式化(修复:项目类型转字符串)
+    async setTableValue(val) {
+      const tableList = JSON.parse(JSON.stringify(val));
+      for (const item of tableList) {
+        // 格式化基础字段(确保类型匹配)
+        item.feeType = (item.feeType || '1').toString();
+        item.typeId = (item.typeId || '').toString(); // 项目类型转字符串
+        item.categoryCode = item.categoryCode || item.code;
+        item.categoryName = item.categoryName || item.name;
+        item.settlementPrice = item.settlementPrice || (Number(item.totalCount) * Number(item.singlePrice) || 0);
+        
+        // 补充仓库数据(仅用于展示)
+        if (item.typeId === '2' && item.categoryId) {
+          try {
+            item.warehouseList = await getIdWarehouseList({ categoryId: item.categoryId });
+            if (item.warehouseId) {
+              item.warehouseNum = await getWarehouseOutStock({
+                warehouseId: item.warehouseId,
+                code: item.code
+              });
+            }
+          } catch (err) {
+            console.error('获取仓库数据失败:', err);
+            item.warehouseList = [];
+            item.warehouseNum = 0;
+          }
+        }
+      }
+      this.form.tableList = tableList;
+      this.calculatePrice(); // 重新计算合计
+    },
+    // 获取当前展示数据(保留用于外部获取数据)
+    getTableValue() {
+      return this.form.tableList;
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+:deep(.el-table__body .el-form-item__content) {
+  margin-left: 0px !important;
+}
+:deep(.el-table__body .el-form-item) {
+  margin-bottom: 0px !important;
+}
+.total_price {
+  margin-left: 24px;
+}
+.toobar {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding-right: 16px;
+}
+.toobar_r {
+  justify-content: flex-end;
+}
+</style>

+ 200 - 0
src/views/bpm/handleTask/components/salesServiceManagement/demand/submit.vue

@@ -0,0 +1,200 @@
+<template>
+  <el-col :span="16" :offset="6">
+    <el-form label-width="100px" ref="formRef" :model="form">
+      <el-form-item
+        label="审批建议"
+        style="margin-bottom: 20px"
+        :rules="{
+          required: true,
+          message: '请选择',
+          trigger: 'change'
+        }"
+      >
+        <el-input
+          type="textarea"
+          v-model="form.reason"
+          placeholder="请输入审批建议"
+        />
+      </el-form-item>
+    </el-form>
+    <div style="margin-left: 10%; margin-bottom: 20px; font-size: 14px">
+      <el-button
+        icon="el-icon-edit-outline"
+        type="success"
+        size="mini"
+        @click="handleAudit(1)"
+        v-if="taskDefinitionKey != 'storemanApprove'"
+        >通过
+      </el-button>
+      <el-button
+        icon="el-icon-edit-outline"
+        type="success"
+        size="mini"
+        @click="storemanApprove"
+        v-if="taskDefinitionKey == 'storemanApprove'"
+        >申请入库
+      </el-button>
+      <el-button
+        icon="el-icon-circle-close"
+        type="danger"
+        size="mini"
+        @click="approveTaskWithVariables(0)"
+        >驳回
+      </el-button>
+      <el-dropdown
+        @command="(command) => handleCommand(command)"
+        style="margin-left: 30px"
+      >
+        <span class="el-dropdown-link"
+          >更多<i class="el-icon-arrow-down el-icon--right"></i
+        ></span>
+        <el-dropdown-menu slot="dropdown">
+          <el-dropdown-item command="cancel">作废</el-dropdown-item>
+        </el-dropdown-menu>
+      </el-dropdown>
+    </div>
+  </el-col>
+</template>
+
+<script>
+  import {
+    approveTaskWithVariables,
+    rejectTask,
+    cancelTask
+  } from '@/api/bpm/task';
+
+  import storageApi from '@/api/warehouseManagement';
+  // 流程实例的详情页,可用于审批
+  export default {
+    name: '',
+    components: {
+      //   Parser
+    },
+    props: {
+      businessId: {
+        default: ''
+      },
+      taskId: {
+        default: ''
+      },
+      id: {
+        default: ''
+      },
+      taskDefinitionKey: {
+        default: ''
+      }
+    },
+    data() {
+      return {
+        form: {
+          technicianId: '',
+          reason: ''
+        },
+        activeComp: ''
+      };
+    },
+    async created() {},
+    methods: {
+      /** 处理转办审批人 */
+      handleUpdateAssignee() {
+        this.$emit('handleUpdateAssignee');
+      },
+      /** 退回 */
+      handleBackList() {
+        this.$emit('handleBackList');
+      },
+      async storemanApprove() {
+        let res = await this.getTableValue();
+        let storageData = res.returnStorageData;
+
+        if (!storageData) {
+          return;
+        }
+        // 入库来源isSkip 0-正常  1-外部(外部跳过内部审核流程)
+        storageData.isSkip = 1;
+
+        try {
+          this.isSaveLoading = true;
+          await storageApi.storage(storageData);
+          approveTaskWithVariables({
+            id: this.taskId,
+            reason: this.form.reason,
+            variables: {
+              pass: true
+            }
+          }).then((res) => {
+            if (res.code != '-1') {
+              this.$emit('handleAudit', {
+                status: 1,
+                title: '入库'
+              });
+            }
+            this.isSaveLoading = false;
+          });
+        } catch (error) {
+          this.isSaveLoading = false;
+          this.$message.error('保存失败');
+        }
+      },
+
+      async handleAudit(status) {
+        await this.approveTaskWithVariables(status);
+      },
+
+      async approveTaskWithVariables(status) {
+        let variables = {
+          pass: !!status
+        };
+        let API = !!status ? approveTaskWithVariables : rejectTask;
+        API({
+          id: this.taskId,
+          reason: this.form.reason,
+          variables
+        }).then((res) => {
+          if (res.code != '-1') {
+            this.$emit('handleAudit', {
+              status,
+              title: status === 0 ? '驳回' : ''
+            });
+          }
+        });
+      },
+
+      getTableValue() {
+        return new Promise((resolve, reject) => {
+          this.$emit('getTableValue', async (data) => {
+            resolve(await data);
+          });
+        });
+      },
+
+      //更多
+      handleCommand(command) {
+        if (command === 'cancel') {
+          this.$confirm('是否确认作废?', {
+            type: 'warning',
+            cancelButtonText: '取消',
+            confirmButtonText: '确定'
+          })
+            .then(() => {
+              cancelTask({
+                id: this.id,
+                taskId: this.taskId,
+                reason: this.form.reason,
+                businessId: this.businessId
+              })
+                .then(() => {
+                  this.$emit('handleClose');
+                })
+                .catch(() => {
+                  this.$message.error('流程作废失败');
+                });
+            })
+            .catch(() => {});
+        }
+      }
+    }
+  };
+</script>
+
+<style lang="scss"></style>

+ 224 - 172
src/views/bpm/handleTask/formParser/formParserDialog.vue

@@ -35,48 +35,91 @@
               style="width: calc(100% - 80px)"
               style="width: calc(100% - 80px)"
             ></el-input>
             ></el-input>
           </div>
           </div>
-
         </div>
         </div>
       </template>
       </template>
       <!-- 客户名称 -->
       <!-- 客户名称 -->
-            <template v-slot:eom_contact="scope">
-              <div class="eom_contact">
-                <el-input
-                    v-model="scope.model.eom_contact.name"
-                    style="width: 100%"
-                  ></el-input>
-              </div>
-            </template>
-
-            <!-- 差旅 -->
-            <template v-slot:blank_business_component="scope">
-              <businessComponent  ref="blank_business_component" id="blank_business_component" :generateForm="$refs.generateForm" :info="scope.model" :view="view"></businessComponent>
-            </template>
+      <template v-slot:eom_contact="scope">
+        <div class="eom_contact">
+          <el-input
+            v-model="scope.model.eom_contact.name"
+            style="width: 100%"
+          ></el-input>
+        </div>
+      </template>
+      <!-- 关联工单 -->
+      <template v-slot:manage_workorder="scope">
+        <div class="manage_workorder">
+          <el-input
+            v-model="scope.model.manage_workorder.code"
+            style="width: 100%"
+          ></el-input>
+        </div>
+      </template>
+      <!-- 差旅 -->
+      <template v-slot:blank_business_component="scope">
+        <businessComponent
+          ref="blank_business_component"
+          id="blank_business_component"
+          :generateForm="$refs.generateForm"
+          :info="scope.model"
+          :view="view"
+        ></businessComponent>
+      </template>
 
 
-            <!-- 印章使用 -->
-            <template v-slot:blank_use_seal="scope">
-              <useSealComponent  ref="blank_use_seal" id="blank_use_seal" :generateForm="$refs.generateForm" :info="scope.model" :view="view"></useSealComponent>
-            </template>
+      <!-- 印章使用 -->
+      <template v-slot:blank_use_seal="scope">
+        <useSealComponent
+          ref="blank_use_seal"
+          id="blank_use_seal"
+          :generateForm="$refs.generateForm"
+          :info="scope.model"
+          :view="view"
+        ></useSealComponent>
+      </template>
 
 
-            <!-- 资质使用 -->
-            <template v-slot:blank_use_qualification="scope">
-              <useQualificationComponent  ref="blank_use_qualification" id="blank_use_qualification" :generateForm="$refs.generateForm" :info="scope.model" :view="view"></useQualificationComponent>
-            </template>
+      <!-- 资质使用 -->
+      <template v-slot:blank_use_qualification="scope">
+        <useQualificationComponent
+          ref="blank_use_qualification"
+          id="blank_use_qualification"
+          :generateForm="$refs.generateForm"
+          :info="scope.model"
+          :view="view"
+        ></useQualificationComponent>
+      </template>
 
 
-            <!-- 产品规格 -->
-            <template v-slot:blank_product_specification="scope">
-              <productSpecificationComponent  ref="blank_product_specification" id="blank_product_specification" :generateForm="$refs.generateForm" :info="scope.model" :view="view"></productSpecificationComponent>
-            </template>
+      <!-- 产品规格 -->
+      <template v-slot:blank_product_specification="scope">
+        <productSpecificationComponent
+          ref="blank_product_specification"
+          id="blank_product_specification"
+          :generateForm="$refs.generateForm"
+          :info="scope.model"
+          :view="view"
+        ></productSpecificationComponent>
+      </template>
 
 
-            <!-- 事件 -->
-            <template v-slot:blank_event_component="scope">
-              <eventComponent  ref="blank_event_component" id="blank_event_component" :generateForm="$refs.generateForm" :info="scope.model" :view="view"></eventComponent>
-            </template>
+      <!-- 事件 -->
+      <template v-slot:blank_event_component="scope">
+        <eventComponent
+          ref="blank_event_component"
+          id="blank_event_component"
+          :generateForm="$refs.generateForm"
+          :info="scope.model"
+          :view="view"
+        ></eventComponent>
+      </template>
 
 
-            <!-- 补发 -->
-            <template v-slot:blank_reissue_component="scope">
-              <reissueComponent  ref="blank_reissue_component" id="blank_reissue_component" :generateForm="$refs.generateForm" :info="scope.model" :view="view"></reissueComponent>
-            </template>
+      <!-- 补发 -->
+      <template v-slot:blank_reissue_component="scope">
+        <reissueComponent
+          ref="blank_reissue_component"
+          id="blank_reissue_component"
+          :generateForm="$refs.generateForm"
+          :info="scope.model"
+          :view="view"
+        ></reissueComponent>
+      </template>
     </fm-generate-form>
     </fm-generate-form>
 
 
     <outboundXTBG
     <outboundXTBG
@@ -144,165 +187,174 @@
   </ele-modal>
   </ele-modal>
 </template>
 </template>
 <script>
 <script>
-  import Parser from '@/components/FormGenerator/components/parser/Parser.vue';
-  import outboundXTBG from '@/views/bpm/outgoingManagement/outboundXTBG.vue';
-  import {
-    approveTaskWithVariables,
-    cancelTask,
-    rejectTask
-  } from '@/api/bpm/task';
-  import { getToken } from '@/utils/token-util';
-  import storageApi from '@/api/warehouseManagement';
+import Parser from '@/components/FormGenerator/components/parser/Parser.vue';
+import outboundXTBG from '@/views/bpm/outgoingManagement/outboundXTBG.vue';
+import {
+  approveTaskWithVariables,
+  cancelTask,
+  rejectTask
+} from '@/api/bpm/task';
+import { getToken } from '@/utils/token-util';
+import storageApi from '@/api/warehouseManagement';
 
 
-  import businessComponent from '@/BIZComponents/processSubmitDialog/components/businessComponent.vue';
-  import useSealComponent from '@/BIZComponents/processSubmitDialog/components/useSealComponent.vue';
-  import useQualificationComponent from '@/BIZComponents/processSubmitDialog/components/useQualificationComponent.vue';
-  import productSpecificationComponent from '@/BIZComponents/processSubmitDialog/components/productSpecificationComponent.vue';
-  import eventComponent from '@/BIZComponents/processSubmitDialog/components/eventComponent.vue';
-  import reissueComponent from '@/BIZComponents/processSubmitDialog/components/reissueComponent.vue';
+import businessComponent from '@/BIZComponents/processSubmitDialog/components/businessComponent.vue';
+import useSealComponent from '@/BIZComponents/processSubmitDialog/components/useSealComponent.vue';
+import useQualificationComponent from '@/BIZComponents/processSubmitDialog/components/useQualificationComponent.vue';
+import productSpecificationComponent from '@/BIZComponents/processSubmitDialog/components/productSpecificationComponent.vue';
+import eventComponent from '@/BIZComponents/processSubmitDialog/components/eventComponent.vue';
+import reissueComponent from '@/BIZComponents/processSubmitDialog/components/reissueComponent.vue';
 
 
-  export default {
-    name: 'formParserDialog',
-    components: { Parser, outboundXTBG },
-    components: {businessComponent, useSealComponent, useQualificationComponent, productSpecificationComponent, eventComponent, reissueComponent},
-    props: {
-      businessId: {
-        default: ''
-      },
-      formParserDialogFlag: {
-        type: Boolean,
-        default: false
-      }
+export default {
+  name: 'formParserDialog',
+  components: { Parser, outboundXTBG },
+  components: {
+    businessComponent,
+    useSealComponent,
+    useQualificationComponent,
+    productSpecificationComponent,
+    eventComponent,
+    reissueComponent
+  },
+  props: {
+    businessId: {
+      default: ''
     },
     },
-    data() {
-      return {
-        form: {},
-        index: '',
-        jsonData: {},
-        width: '30%',
-        isSaveLoading: false
-      };
+    formParserDialogFlag: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      form: {},
+      index: '',
+      jsonData: {},
+      width: '30%',
+      isSaveLoading: false
+    };
+  },
+  modelWidth() {
+    let width =
+      this.jsonData.config?.platform && this.jsonData.config.platform === 'pc'
+        ? 1100
+        : 450;
+    if (this.form?.taskDefinitionKey == 'CGYSP') {
+      return (width = '70%');
+    }
+    return width + 'px';
+  },
+  methods: {
+    open(row) {
+      this.form = _.cloneDeep(row);
+      console.log(this.form.taskDefinitionKey, 'this.form.taskDefinitionKey');
+
+      this.jsonData = JSON.parse(this.form.formJson.makingJson);
+      this.jsonData.config.dataSource &&
+        this.jsonData.config.dataSource.forEach((item) => {
+          item.headers = {
+            Authorization: getToken()
+          };
+          // item.url = item.url && item.url.replace('/api', this.APIUrl);
+        });
     },
     },
-    modelWidth() {
-      let width = this.jsonData.config?.platform && this.jsonData.config.platform === 'pc' ? 1100 : 450;
-      if (this.form?.taskDefinitionKey == 'CGYSP') {
-        return width = '70%';
-      }
-      return width + 'px'
+    cancel() {
+      this.$emit('update:formParserDialogFlag', false);
+    },
+    async handleAudit(status) {
+      await this._approveTaskWithVariables(status);
     },
     },
-    methods: {
-      open(row) {
-        this.form = _.cloneDeep(row);
-        console.log(this.form.taskDefinitionKey, 'this.form.taskDefinitionKey');
-        
-        this.jsonData = JSON.parse(this.form.formJson.makingJson);
-        this.jsonData.config.dataSource &&
-          this.jsonData.config.dataSource.forEach((item) => {
-            item.headers = {
-              Authorization: getToken()
-            };
-            // item.url = item.url && item.url.replace('/api', this.APIUrl);
-          });
-      },
-      cancel() {
-        this.$emit('update:formParserDialogFlag', false);
-      },
-      async handleAudit(status) {
-        await this._approveTaskWithVariables(status);
-      },
-
-      async storemanApprove(status) {
-        let storageData = await this.$refs.outboundXTBGRef.getReturnStorage();
-        console.log(storageData);
-
-        // 出库来源isSkip 0-正常  1-外部(外部跳过内部审核流程)
-        storageData.isSkip = 1;
-        storageData.isMes = 1;
-        try {
-          this.isSaveLoading = true;
-          await storageApi.outStorage(storageData);
-          approveTaskWithVariables({
-            id: this.form.id,
-            reason: this.form.reason,
-            businessId: this.businessId,
-            variables: {
-              pass: true
-            }
-          }).then((res) => {
-            if (res.data.code != '-1') {
-       
-              this.$message.success(`出库成功!`);
-              this.$emit('reload');
-              this.cancel();
-            }
-            this.isSaveLoading = false;
-          });
-        } catch (error) {
-          this.isSaveLoading = false;
-          console.error('出库失败:', error);
-        }
-      },
 
 
-      async _approveTaskWithVariables(status) {
-        let variables = {
-          pass: !!status
-        };
-        let API = !!status ? approveTaskWithVariables : rejectTask;
+    async storemanApprove(status) {
+      let storageData = await this.$refs.outboundXTBGRef.getReturnStorage();
+      console.log(storageData);
 
 
-        API({
+      // 出库来源isSkip 0-正常  1-外部(外部跳过内部审核流程)
+      storageData.isSkip = 1;
+      storageData.isMes = 1;
+      try {
+        this.isSaveLoading = true;
+        await storageApi.outStorage(storageData);
+        approveTaskWithVariables({
           id: this.form.id,
           id: this.form.id,
           reason: this.form.reason,
           reason: this.form.reason,
           businessId: this.businessId,
           businessId: this.businessId,
-          variables
+          variables: {
+            pass: true
+          }
         }).then((res) => {
         }).then((res) => {
           if (res.data.code != '-1') {
           if (res.data.code != '-1') {
-            let params = {
-              status,
-              title: status === 0 ? '驳回' : ''
-            };
-            this.$message.success(`审批${params.title}成功!`);
+            this.$message.success(`出库成功!`);
             this.$emit('reload');
             this.$emit('reload');
             this.cancel();
             this.cancel();
           }
           }
+          this.isSaveLoading = false;
         });
         });
-      },
+      } catch (error) {
+        this.isSaveLoading = false;
+        console.error('出库失败:', error);
+      }
+    },
 
 
-      //更多
-      handleCommand(command) {
-        if (command === 'cancel') {
-          this.$confirm('是否确认作废?', {
-            type: 'warning',
-            cancelButtonText: '取消',
-            confirmButtonText: '确定'
-          })
-            .then(() => {
-              cancelTask({
-                taskId: this.form.id,
-                id: this.form.processInstance.id,
-                reason: this.form.reason
-              })
-                .then(() => {
-                  this.$emit('reload');
-                  this.cancel();
-                })
-                .catch(() => {
-                  this.$message.error('流程作废失败');
-                });
-            })
-            .catch(() => {});
+    async _approveTaskWithVariables(status) {
+      let variables = {
+        pass: !!status
+      };
+      let API = !!status ? approveTaskWithVariables : rejectTask;
+
+      API({
+        id: this.form.id,
+        reason: this.form.reason,
+        businessId: this.businessId,
+        variables
+      }).then((res) => {
+        if (res.data.code != '-1') {
+          let params = {
+            status,
+            title: status === 0 ? '驳回' : ''
+          };
+          this.$message.success(`审批${params.title}成功!`);
+          this.$emit('reload');
+          this.cancel();
         }
         }
+      });
+    },
+
+    //更多
+    handleCommand(command) {
+      if (command === 'cancel') {
+        this.$confirm('是否确认作废?', {
+          type: 'warning',
+          cancelButtonText: '取消',
+          confirmButtonText: '确定'
+        })
+          .then(() => {
+            cancelTask({
+              taskId: this.form.id,
+              id: this.form.processInstance.id,
+              reason: this.form.reason
+            })
+              .then(() => {
+                this.$emit('reload');
+                this.cancel();
+              })
+              .catch(() => {
+                this.$message.error('流程作废失败');
+              });
+          })
+          .catch(() => {});
       }
       }
     }
     }
-  };
+  }
+};
 </script>
 </script>
 <style scoped lang="scss">
 <style scoped lang="scss">
-  .blank_adopzrdd {
-    display: flex;
-    align-items: center;
-    > span {
-      display: inline-block;
-      width: 80px;
-    }
-    margin-bottom: 10px;
+.blank_adopzrdd {
+  display: flex;
+  align-items: center;
+  > span {
+    display: inline-block;
+    width: 80px;
   }
   }
+  margin-bottom: 10px;
+}
 </style>
 </style>

+ 7 - 0
src/views/bpm/stockManagement/details.vue

@@ -245,6 +245,13 @@
               :show-overflow-tooltip="true"
               :show-overflow-tooltip="true"
             >
             >
             </el-table-column>
             </el-table-column>
+             <el-table-column
+                label="生产要求"
+                align="center"
+                width="200"
+                prop="productionRequirements"
+                :show-overflow-tooltip="true"
+              ></el-table-column>
             <el-table-column label="机型" prop="modelKey" width="200">
             <el-table-column label="机型" prop="modelKey" width="200">
             </el-table-column>
             </el-table-column>
             <el-table-column label="颜色" prop="colorKey" width="200">
             <el-table-column label="颜色" prop="colorKey" width="200">

+ 34 - 18
src/views/bpm/stockManagement/storage.vue

@@ -120,7 +120,7 @@
               ></el-input>
               ></el-input>
             </el-form-item>
             </el-form-item>
           </el-col>
           </el-col>
-          <el-col :span="6">
+          <!-- <el-col :span="6">
             <el-form-item label="生产要求" prop="productionRequirements">
             <el-form-item label="生产要求" prop="productionRequirements">
               <el-input
               <el-input
                 v-model="formData.productionRequirements"
                 v-model="formData.productionRequirements"
@@ -131,7 +131,7 @@
                 disabled
                 disabled
               ></el-input>
               ></el-input>
             </el-form-item>
             </el-form-item>
-          </el-col>
+          </el-col> -->
         </el-row>
         </el-row>
       </el-form>
       </el-form>
       <div class="inbound_details">
       <div class="inbound_details">
@@ -228,13 +228,13 @@
                 align="center"
                 align="center"
                 width="100"
                 width="100"
                 prop="ifPackageOk"
                 prop="ifPackageOk"
+                v-if="isShowPackage"
               > 
               > 
                 <template slot-scope="{ row, $index }">
                 <template slot-scope="{ row, $index }">
-                  <template v-if="row.isSave">
-                    {{ row.ifPackageOk ? '是' : '否' }}
-                  </template>
+                  <!-- <template v-if="row.isSave">
+                    {{ row.ifPackageOk == 1 ? '是' : row.ifPackageOk == 0 ? '否' : '' }}
+                  </template> -->
                   <el-form-item
                   <el-form-item
-                    v-else
                     :prop="`productList.${$index}.ifPackageOk`"
                     :prop="`productList.${$index}.ifPackageOk`"
                     required
                     required
                   >
                   >
@@ -250,13 +250,13 @@
                 align="center"
                 align="center"
                 width="100"
                 width="100"
                 prop="unpackUserName"
                 prop="unpackUserName"
+                v-if="isShowPackage"
               >
               >
                 <template slot-scope="{ row, $index }">
                 <template slot-scope="{ row, $index }">
-                  <template v-if="row.isSave">
+                  <!-- <template v-if="row.isSave">
                     {{ row.unpackUserName }}
                     {{ row.unpackUserName }}
-                  </template>
+                  </template> -->
                   <el-form-item
                   <el-form-item
-                    v-else
                     :prop="`productList.${$index}.unpackUserName`"
                     :prop="`productList.${$index}.unpackUserName`"
                     required
                     required
                   >
                   >
@@ -461,6 +461,13 @@
                   <template slot="append"> </template>
                   <template slot="append"> </template>
                 </template>
                 </template>
               </el-table-column>
               </el-table-column>
+             <el-table-column
+                label="生产要求"
+                align="center"
+                width="200"
+                prop="productionRequirements"
+                :show-overflow-tooltip="true"
+              ></el-table-column>
               <el-table-column label="机型" prop="modelKey" width="300">
               <el-table-column label="机型" prop="modelKey" width="300">
                 <template slot-scope="{ row, $index }">
                 <template slot-scope="{ row, $index }">
                   <DictSelection
                   <DictSelection
@@ -1681,6 +1688,7 @@
                 batchNo: batchNo, // 批次号
                 batchNo: batchNo, // 批次号
                 supplierListOptions: supplierList[item.id], // 供应商列表
                 supplierListOptions: supplierList[item.id], // 供应商列表
                 supplierId: this.form.supplierId, // 供应商id
                 supplierId: this.form.supplierId, // 供应商id
+                productionRequirements:filtersItem.productionRequirements,//生产要求
                 supplierCode:
                 supplierCode:
                   this.bizType == 2 || this.bizType == 7
                   this.bizType == 2 || this.bizType == 7
                     ? filtersItem.supplierMark
                     ? filtersItem.supplierMark
@@ -1777,6 +1785,8 @@
           });
           });
           storageApi.getListByNameOrModeType({ codeList }).then(async (res) => {
           storageApi.getListByNameOrModeType({ codeList }).then(async (res) => {
             console.log(res, 'detailList-res');
             console.log(res, 'detailList-res');
+            console.log(this.form, 'this.form.warehouseId');
+            console.log(this.bizType, 'this.bizType~~~');
             // 获取批次号
             // 获取批次号
             const batchNo = await getCode('lot_number_code');
             const batchNo = await getCode('lot_number_code');
             // 获取供应商
             // 获取供应商
@@ -1796,11 +1806,12 @@
             // 获取相同仓库
             // 获取相同仓库
             let warehouseIds = [];
             let warehouseIds = [];
             let warehouseNames = [];
             let warehouseNames = [];
+            console.log(this.form.totalCount, 'this.form.warehouseId');
             for (let index = 0; index < this.form.totalCount; index++) {
             for (let index = 0; index < this.form.totalCount; index++) {
               warehouseIds.push(this.form.warehouseId);
               warehouseIds.push(this.form.warehouseId);
               warehouseNames.push(this.form.warehouseName);
               warehouseNames.push(this.form.warehouseName);
             }
             }
-            if (this.bizType == 4) {
+            if (this.bizType == 4 || this.bizType == 1) {
               warehouseIds.push(this.form.warehouseId);
               warehouseIds.push(this.form.warehouseId);
               warehouseNames.push(this.form.warehouseName);
               warehouseNames.push(this.form.warehouseName);
             }
             }
@@ -1915,8 +1926,7 @@
                 categoryModel: item.modelType, // 物品型号
                 categoryModel: item.modelType, // 物品型号
                 specification: item.specification, // 规格
                 specification: item.specification, // 规格
                 brandNum: item.brandNum, // 牌号
                 brandNum: item.brandNum, // 牌号
-                batchNo:
-                  this.bizType == 1 || this.bizType == 3
+                batchNo:[1,3,6].includes(this.bizType)
                     ? this.detailList[0]?.batchNo || batchNo
                     ? this.detailList[0]?.batchNo || batchNo
                     : batchNo, // 批次号
                     : batchNo, // 批次号
                 supplierListOptions: supplierList[item.id], // 供应商列表
                 supplierListOptions: supplierList[item.id], // 供应商列表
@@ -1930,6 +1940,7 @@
                   this.detailList.find((val) => val.categoryCode == item.code)
                   this.detailList.find((val) => val.categoryCode == item.code)
                     ?.supplierName || item.supplierName, // 供应商名称
                     ?.supplierName || item.supplierName, // 供应商名称
                 approvalNumber: item.approvalNumber, // 批准文号
                 approvalNumber: item.approvalNumber, // 批准文号
+                 productionRequirements:this.form.productionRequirements,
                 packingSpecification: item.packingSpecification, // 包装规格
                 packingSpecification: item.packingSpecification, // 包装规格
                 packingSpecificationOption: newSpecificationOption[index], // 包装规格选项
                 packingSpecificationOption: newSpecificationOption[index], // 包装规格选项
                 packingSpecificationLabel: packingSpecificationLabel, // 包装规格显示
                 packingSpecificationLabel: packingSpecificationLabel, // 包装规格显示
@@ -2425,7 +2436,14 @@
           this.$message.error('请先保存所有产品信息');
           this.$message.error('请先保存所有产品信息');
           return;
           return;
         }
         }
-
+        if(this.isShowPackage) {
+          const userNameLength = this.productList.filter(item => !item.unpackUserName).length
+          const packgeLength = this.productList.filter(item => !item.ifPackageOk).length
+          if(userNameLength || packgeLength) {
+            this.$message.error('请先填写拆包装责任人和包装完好与否');
+            return;
+          }
+        }
         // 处理包装数据
         // 处理包装数据
         let _packingList = [];
         let _packingList = [];
         _packingList = this.packingList.map((packingItem) => {
         _packingList = this.packingList.map((packingItem) => {
@@ -2924,10 +2942,6 @@
               `productList.${index}.warehouseId`,
               `productList.${index}.warehouseId`,
               
               
             ];
             ];
-            if(this.isShowPackage) {
-              fileds.push(`productList.${index}.unpackUserName`,
-              `productList.${index}.ifPackageOk`,)
-            }
             if (row.isSave) {
             if (row.isSave) {
               return Promise.resolve(true);
               return Promise.resolve(true);
             } else {
             } else {
@@ -3072,6 +3086,8 @@
             `productList.${index}.packingUnit`,
             `productList.${index}.packingUnit`,
             `productList.${index}.warehouseId`
             `productList.${index}.warehouseId`
           ];
           ];
+
+   
           Promise.all(
           Promise.all(
             fileds.map(
             fileds.map(
               (item) =>
               (item) =>
@@ -3160,7 +3176,7 @@
             }
             }
           }
           }
         } catch (error) {
         } catch (error) {
-          this.$message.error('批量保存失败,请检查必填项');
+          // this.$message.error('批量保存失败,请检查必填项');
         }
         }
       },
       },
       listSave(row, index) {
       listSave(row, index) {

+ 1 - 1
src/views/bpm/tickets/repair/index.vue

@@ -18,7 +18,7 @@
         <!-- 操作列 -->
         <!-- 操作列 -->
         <template v-slot:action="{ row }">
         <template v-slot:action="{ row }">
           <el-link
           <el-link
-            v-if="row.orderStatus == 3 && row.createUserId == userId"
+            v-if="row.orderStatus == 3 && row.requestUserId == userId"
             type="primary"
             type="primary"
             :underline="false"
             :underline="false"
             icon="el-icon-edit"
             icon="el-icon-edit"

+ 1 - 0
src/views/bpm/todo/index.vue

@@ -291,6 +291,7 @@
       /** 处理审批按钮 */
       /** 处理审批按钮 */
 
 
       handleAudit(type, row) {
       handleAudit(type, row) {
+        console.log(type,row)
         // return
         // return
 
 
         if (type == 'audit') {
         if (type == 'audit') {

+ 1 - 1
vue.config.js

@@ -40,7 +40,7 @@ module.exports = {
         // target: 'http://192.168.1.105:18086',
         // target: 'http://192.168.1.105:18086',
 
 
         // target: 'http://192.168.1.251:18186',
         // target: 'http://192.168.1.251:18186',
-        target: 'http://192.168.1.125:18086',
+        target: 'http://192.168.1.251:18086',
         // target: 'http://192.168.1.125:18086',
         // target: 'http://192.168.1.125:18086',
 
 
         // target: 'http://192.168.1.3:18086',
         // target: 'http://192.168.1.3:18086',