Parcourir la source

生产任务的其他生产说明可输入、申购详情功能

cz il y a 10 mois
Parent
commit
d6c00f758c

+ 209 - 0
src/components/PDF/SalaryConfirmationPDF.vue

@@ -0,0 +1,209 @@
+<template>
+  <div>
+    <div id="pdfDom" ref="pdfDom" style="padding: 20px 20px 0; text-align: center;font-size:12px;color:#333333" v-loading="loading">
+      <table border="1" style="width: 100%" class="table">
+        <tr>
+          <td :colspan="salaryStructureData.length+3" class="title">薪资确认单</td>
+        </tr>
+        <tr>
+          <td colspan="2">所属主体</td>
+          <td colspan="2">{{pdfData.companyName}}</td>
+          <td colspan="1">部门</td>
+          <td colspan="2">{{pdfData.deptName}}</td>
+          <td colspan="1">入职日期</td>
+          <td colspan="2">{{pdfData.createTime}}</td>
+        </tr>
+        <tr>
+          <td colspan="2">员工姓名</td>
+          <td colspan="2">{{pdfData.nickName}}</td>
+          <td colspan="1">岗位</td>
+          <td colspan="2">{{pdfData.post}}</td>
+          <td colspan="1">生效日期</td>
+          <td colspan="2">{{pdfData.effectiveDate}}</td>
+        </tr>
+        <tr>
+          <td colspan="2">学历</td>
+          <td colspan="2">{{pdfData.education}}</td>
+          <td colspan="1">试用期限</td>
+          <td colspan="2">{{pdfData.probationPeriod}}</td>
+          <td colspan="1">转正日期</td>
+          <td colspan="2">{{pdfData.fullTimeDate}}</td>
+        </tr>
+        <tr>
+          <td colspan="2">
+            上班时长
+          </td>
+          <td :colspan="salaryStructureData.length+3-2" style="text-align:center"></td>
+        </tr>
+        <tr>
+          <td rowspan="5" style="width:5%">
+            薪资
+          </td>
+          <td :colspan="salaryStructureData.length+2">
+            考勤结算 or 业绩/记件结算
+          </td>
+        </tr>
+        <tr>
+          <td rowspan="2" style="width:5%">考勤结算</td>
+          <td v-for="col in salaryStructureData" :key="col.value" :style="`width:${parseFloat(80/salaryStructureData.length).toFixed(2)}%`">
+            {{col.label}}
+          </td>
+          <td style="width:10%">合计</td>
+        </tr>
+        <tr>
+          <td v-for="col in salaryStructureData" :key="col.value" :style="`width:${parseFloat(80/salaryStructureData.length).toFixed(2)}%`">
+            {{col.label}}
+          </td>
+          <td>{{pdfData.amount}}</td>
+        </tr>
+        <tr>
+          <td rowspan="2">业绩/记件结算</td>
+          <td v-for="col in salaryStructureData" :key="col.value">
+            {{col.label}}
+          </td>
+          <td>合计</td>
+        </tr>
+        <tr>
+          <td v-for="col in salaryStructureData" :key="col.value">
+            {{col.label}}
+          </td>
+          <td>{{pdfData.amount}}</td>
+        </tr>
+
+        <tr>
+          <td colspan="2">
+            薪资说明
+          </td>
+          <td :colspan="salaryStructureData.length+3-2" style="text-align:center"></td>
+        </tr>
+        <tr>
+          <td colspan="2">
+            员工签字
+          </td>
+          <td colspan="3"></td>
+          <td colspan="1">
+            主管签字
+          </td>
+          <td colspan="4"></td>
+        </tr>
+        <tr>
+          <td colspan="2">
+            副总审批
+          </td>
+          <td colspan="3"></td>
+          <td colspan="1">
+            总经理审批
+          </td>
+          <td colspan="4"></td>
+        </tr>
+      </table>
+    </div>
+    <div style="text-align: center;margin-top:20px">
+      <el-button type="primary" v-print="printObj" size="default" v-debounce>打印</el-button>
+      <el-button type="primary" @click="clickDownload()" size="default" v-debounce>下载PDF</el-button>
+      <el-button type="primary" @click="exportExcel()" size="default" v-debounce>导出Excel</el-button>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import $ from "jquery";
+const { proxy } = getCurrentInstance();
+const pdfData = ref({});
+const props = defineProps({
+  rowData: Object,
+});
+const salaryStructureData = ref([]);
+const getData = () => {
+  proxy
+    .post("/salaryStructure/page", {
+      pageNum: 1,
+      pageSize: 999,
+    })
+    .then((res) => {
+      salaryStructureData.value = res.rows
+        .map((item) => {
+          return {
+            label: item.name,
+            value: item.id,
+          };
+        })
+        .reverse();
+    });
+};
+getData();
+
+const loading = ref(false);
+const getPdfData = (query) => {
+  loading.value = true;
+  proxy.post("/userSalaryManage/detail", query).then((res) => {
+    pdfData.value = res;
+    loading.value = false;
+  });
+};
+
+watch(
+  () => props.rowData,
+  (val) => {
+    if (props.rowData.id) {
+      getPdfData({ userId: props.rowData.id });
+    }
+  },
+  {
+    immediate: true,
+    deep: true,
+  }
+);
+
+const printObj = ref({
+  id: "pdfDom",
+  popTitle: "",
+  extraCss:
+    "https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css",
+  extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
+});
+
+const clickDownload = () => {
+  proxy.getPdf("薪资确认单PDF文件");
+};
+
+const pdfDom = ref(null);
+const exportExcel = () => {
+  // pdfDom.value.exportExcel();
+  // isShowImg.value = false;
+  loading.value = true;
+  setTimeout(() => {
+    $("#pdfDom").table2excel({
+      exclude: ".noExl",
+      sheetName: `${pdfData.value.nickName} 薪资确认单`,
+      filename: `${pdfData.value.nickName} 薪资确认单`,
+      exclude_img: false,
+      exclude_links: false,
+      exclude_inputs: true,
+    });
+    // isShowImg.value = true;
+    loading.value = false;
+  }, 500);
+};
+</script>
+
+<style lang="scss" scoped>
+.table {
+  .title {
+    font-size: 26px;
+    // font-weight: 700;
+  }
+  border-collapse: collapse;
+  border-spacing: 0;
+  width: 100%;
+  td {
+    text-align: center;
+    padding: 6px;
+    font-size: 12px;
+    // padding: 5px 10px;
+  }
+  .align-right {
+    text-align: right;
+  }
+}
+</style>

+ 19 - 2
src/views/EHSD/procurement/purchasedEHSD/index.vue

@@ -920,12 +920,29 @@ const clickUpdate = (row) => {
   line-height: 24px;
   padding-left: 4px;
 }
+::v-deep(.redClass) {
+  // color: #fff !important;
+  background-color: #fbdbdb !important;
+  .el-table-fixed-column--left,
+  .el-table-fixed-column--right {
+    background-color: #fbdbdb;
+  }
+}
+
+::v-deep(.greenClass) {
+  // color: #fff !important;
+  background-color: #cab211 !important;
+  .el-table-fixed-column--left,
+  .el-table-fixed-column--right {
+    background-color: #cab211;
+  }
+}
 </style>
 <style>
-.redClass {
+/* .redClass {
   color: #f54a45 !important;
 }
 .greenClass {
   color: #cab211 !important;
-}
+} */
 </style>

+ 1 - 2
src/views/EHSD/saleContract/contractEHSD/index.vue

@@ -894,7 +894,7 @@ const config = computed(() => {
       attrs: {
         label: "评审状态",
         slot: "reviewStatus",
-        width: 160,
+        width: 180,
       },
       render(val) {
         return proxy.dictValueLabel(val, reviewStatusData.value);
@@ -1174,7 +1174,6 @@ const config = computed(() => {
                 },
               }
             : {},
-          // row.produceStatus == 1
           row.status == 30 &&
           row.produceStatus == 1 &&
           row.orderDistributeStatus == 1

+ 472 - 3
src/views/MES/productionTask/index.vue

@@ -86,7 +86,7 @@
 
       </el-tabs>
     </div>
-    <div v-if="['1','2','3','4'].includes(pageActiveName)">
+    <div v-if="['1','2','3','4'].includes(pageActiveName) && !isShowSeveral">
       <byTable :hideSearch="true" :otherHeight="80" :source="sourceList.data" :pagination="sourceList.pagination" :config="config" :loading="loading"
                highlight-current-row :selectConfig="[]" :action-list="[ 
               
@@ -221,7 +221,142 @@
       </byTable>
     </div>
 
-    <div v-else>
+    <div v-if="['1','2','3','4'].includes(pageActiveName) && isShowSeveral">
+      <byTable :hideSearch="true" :otherHeight="80" :source="sourceList.data" :pagination="sourceList.pagination" :config="configCopy"
+               :loading="loading" highlight-current-row :selectConfig="[]" :action-list="[ 
+              
+        ]" :table-events="{
+             select: selectRow,
+       'select-all':selectRow
+        }" :row-class-name="getRowClass" @get-list="getList">
+
+        <template #btn="{ item }">
+          <div style="width: 100%">
+            <el-button type="primary" text @click="startConfirm(item)">开工确认</el-button>
+            <el-button type="primary" text @click="printQrCode(item)">任务单</el-button>
+            <el-popover placement="bottom-start" title="" :width="300" trigger="hover">
+              <div style="width:100%">
+                {{item.remark || '无'}}
+              </div>
+              <template #reference>
+                <el-button type="primary" text @click="openRemark(item)">进度说明</el-button>
+              </template>
+            </el-popover>
+            <!-- <el-button type="primary" text @click="openRemark(item)" v-if="!item.remark">进度说明</el-button> -->
+            <el-button type="primary" text @click="handleChangeStatus(item)"><span
+                    :style="{color:item.reportLock==1?'red':''}">{{item.reportLock==1?'已':'未'}}锁定</span></el-button>
+          </div>
+        </template>
+
+        <template #orderCode="{ item }">
+          <div style="width: 100%" class="el-click" @click="lookDetails(item)">
+            {{item.orderCode}}
+          </div>
+        </template>
+
+        <template #pic="{ item }">
+          <div v-if="item.fileList &&item.fileList.length > 0">
+            <img :src="item.fileList[0].fileUrl" class="pic" @click="handleClickFile(item.fileList[0])" />
+          </div>
+          <div v-else></div>
+        </template>
+
+        <template #picOne="{ item }">
+          <div v-if="item.fileListOne &&item.fileListOne.length > 0">
+            <img :src="item.fileListOne[0].fileUrl" class="pic" @click="handleClickFile(item.fileListOne[0])" />
+          </div>
+          <div v-else></div>
+        </template>
+
+        <template #size="{ item }">
+          <div>
+            <span>{{ item.productLength }}</span>*
+            <span>{{ item.productWidth }}</span>*
+            <span>{{ item.productHeight }}</span>
+          </div>
+
+        </template>
+
+        <template #isOverdue="{item}">
+          <div style="width: 100%">
+            <span v-if="item.isOverdue=='1'" class="red"> 逾期 </span>
+            <span v-else> 未逾期 </span>
+          </div>
+        </template>
+
+        <template #produceStatus="{item}">
+          <div style="width: 100%">
+            <span :class="{
+              'red':item.produceStatus=='88' || item.produceStatus=='99'
+            }"> {{dictValueLabel(item.produceStatus, statusData)}} </span>
+          </div>
+        </template>
+
+        <template #progress="{item}">
+          <div style="width: 100%">
+            <el-progress type="circle" :percentage="item.percentage" width="60"
+                         :status="(Number(item.finishQuantity) / Number(item.quantity))*100 == 100 ? 'success' : ''" />
+          </div>
+        </template>
+
+        <template #prodTag="{ item }">
+          <div style="width: 100%">
+            <el-popover placement="top-start" :width="300" trigger="hover">
+              <div>
+                备注:{{item.prodRemark}}
+              </div>
+              <template #reference>
+                <div style="width:100%;display:inline-block">
+                  <el-tag style="margin-right: 8px" type="success" v-for="(tag, index) in item.prodTags" :key="index">
+                    {{ dictKeyValue(tag, contractTag) }}
+                  </el-tag>
+                </div>
+              </template>
+            </el-popover>
+          </div>
+        </template>
+
+        <template #logo="{item}">
+          <div style="width: 100%">
+            {{item.productLogoLength }} * {{item.productLogoWidth }}
+          </div>
+        </template>
+
+        <template #shortageMaterials="{item}">
+          <div style="width: 100%">
+            <span v-if="item.lackStatus=='1'" class="red" style="cursor:pointer" @click="lookDetail(item)">
+              欠料</span>
+            <span v-else>未欠料</span>
+          </div>
+        </template>
+
+        <template v-for="(slotItem, index) in processesData" v-slot:[slotItem.id]="{ item }" :key="slotItem.id">
+          <div style="width:100%">
+            <div v-if="pageActiveName !='4'">
+              <span v-if="isShowCotent(slotItem,item)" style="font-weight:700;min-width:50px;line-height:18px;display:inline-block;cursor:pointer"
+                    :class="showCotentQuantity(slotItem,item)" @contextmenu="(e)=>handleContextmenu(slotItem,item,e)">
+                {{showCotent(slotItem,item,'finishQuantity')}}
+              </span>
+              <div v-else class="no-bk">
+                -
+              </div>
+            </div>
+            <!-- style="border-top:1px solid #ebeef5;margin-top:3px" -->
+            <div v-else>
+              <div v-if="isShowCotent(slotItem,item)">
+                {{showCotentOne(slotItem,item,'balanceQuantity') || `&nbsp`}}
+              </div>
+              <div v-else class="no-bk">
+                -
+              </div>
+            </div>
+
+          </div>
+        </template>
+      </byTable>
+    </div>
+
+    <div v-if="!['1','2','3','4'].includes(pageActiveName) ">
       <byTable :hideSearch="true" :source="sourceListOne.data" :otherHeight="80" :pagination="sourceListOne.pagination" :config="configOne"
                :loading="loading" highlight-current-row :selectConfig="selectConfigOne" :action-list="[{
                 text: '排程',
@@ -488,7 +623,13 @@
               </tr>
               <tr>
                 <td colspan="7">
-                  其他生产说明:{{item.productRemark}}
+                  <div style="display:flex;align-items:center">
+                    <div style="width:91px"> 其他生产说明:</div>
+                    <div style="flex:1">
+                      <el-input v-model="item.otherProdRemark" placeholder=" " type="textarea" :rows="1"
+                                @change="(val)=>changeRemark(val,item.id)"></el-input>
+                    </div>
+                  </div>
                 </td>
               </tr>
               <tr>
@@ -1345,6 +1486,306 @@ const config = ref([
   // },
 ]);
 
+const configCopy = ref([
+  {
+    type: "selection",
+    attrs: {
+      checkAtt: "isCheck",
+      width: 60,
+    },
+  },
+  {
+    attrs: {
+      label: "操作",
+      width: "150",
+      slot: "btn",
+      align: "left",
+      // fixed: "right",
+    },
+    // renderHTML(row) {
+    //   return [
+    //     {
+    //       attrs: {
+    //         label: "打印任务单",
+    //         type: "primary",
+    //         text: true,
+    //       },
+    //       el: "button",
+    //       click() {
+    //         printQrCode(row);
+    //       },
+    //     },
+    //     {
+    //       attrs: {
+    //         label: "备注",
+    //         type: "primary",
+    //         text: true,
+    //       },
+    //       el: "button",
+    //       click() {
+    //         openRemark(row);
+    //       },
+    //     },
+    //   ];
+    // },
+  },
+  {
+    attrs: {
+      label: "客户名称",
+      prop: "customerName",
+      width: 150,
+      // fixed: "left",
+    },
+  },
+  {
+    attrs: {
+      label: "业务员",
+      prop: "saleUserName",
+      width: 100,
+      // align: "center",
+    },
+  },
+  {
+    attrs: {
+      label: "订单号",
+      slot: "orderCode",
+      width: 150,
+      fixed: "left",
+    },
+  },
+  {
+    attrs: {
+      label: "生产订单号",
+      prop: "code",
+      width: 150,
+      fixed: "left",
+    },
+  },
+  {
+    attrs: {
+      label: "产品名称",
+      prop: "productName",
+      "min-width": 200,
+      fixed: "left",
+    },
+  },
+  {
+    attrs: {
+      label: "业务公司",
+      prop: "contractCompanyName",
+      width: 110,
+    },
+  },
+  {
+    attrs: {
+      label: "业务部门",
+      prop: "contractDeptName",
+      width: 100,
+    },
+  },
+  {
+    attrs: {
+      label: "是否逾期",
+      slot: "isOverdue",
+      width: 80,
+      // fixed: "left",
+    },
+  },
+
+  {
+    attrs: {
+      label: "生产状态",
+      // prop: "produceStatus",
+      slot: "produceStatus",
+      width: 100,
+    },
+    render(val) {
+      return proxy.dictValueLabel(val, statusData.value);
+    },
+  },
+  {
+    attrs: {
+      label: "订单类型",
+      prop: "contractType",
+      width: 110,
+    },
+    render(val) {
+      return proxy.dictKeyValue(val, contractTypeData.value);
+    },
+  },
+  {
+    attrs: {
+      label: "工厂",
+      prop: "companyName",
+      width: 100,
+      // align: "center",
+    },
+  },
+  {
+    attrs: {
+      label: "欠料状态",
+      prop: "produceStatus",
+      slot: "shortageMaterials",
+      width: 100,
+    },
+  },
+
+  {
+    attrs: {
+      label: "产品图片",
+      slot: "pic",
+      width: 80,
+    },
+  },
+  {
+    attrs: {
+      label: "产品分类名称",
+      prop: "productClassifyNames",
+      width: 150,
+    },
+  },
+  // {
+  //   attrs: {
+  //     label: "设计图",
+  //     slot: "picOne",
+  //     width: 80,
+  //   },
+  // },
+  {
+    attrs: {
+      label: "产品编码",
+      prop: "productCode",
+      width: 130,
+    },
+  },
+  {
+    attrs: {
+      label: "规格尺寸(cm)",
+      slot: "size",
+      width: 160,
+    },
+  },
+  {
+    attrs: {
+      label: "产品颜色",
+      prop: "productColor",
+      width: 160,
+    },
+  },
+  {
+    attrs: {
+      label: "正面纹路",
+      prop: "productFrontalTexture",
+      width: 100,
+    },
+    render(val) {
+      return proxy.dictKeyValue(val, frontLinesData.value);
+    },
+  },
+  {
+    attrs: {
+      label: "背面纹路",
+      prop: "productReverseTexture",
+      width: 100,
+    },
+    render(val) {
+      return proxy.dictKeyValue(val, backLinesData.value);
+    },
+  },
+  {
+    attrs: {
+      label: "LOGO尺寸(cm)",
+      slot: "logo",
+      width: 130,
+    },
+  },
+  {
+    attrs: {
+      label: "生产件数",
+      prop: "quantity",
+      width: 100,
+    },
+  },
+  {
+    attrs: {
+      label: "完成进度",
+      slot: "progress",
+      width: 90,
+    },
+  },
+  {
+    attrs: {
+      label: "已完成",
+      prop: "finishQuantity",
+      width: 100,
+    },
+  },
+  {
+    attrs: {
+      label: "未完成",
+      prop: "incomplete",
+      width: 100,
+    },
+  },
+
+  {
+    attrs: {
+      label: "生产指示",
+      slot: "prodTag",
+      "min-width": 220,
+    },
+  },
+  {
+    attrs: {
+      label: "下单时间",
+      prop: "orderCreateTime",
+      width: 160,
+    },
+  },
+  {
+    attrs: {
+      label: "交期",
+      prop: "deliveryPeriod",
+      width: 100,
+    },
+    render(val) {
+      if (val) {
+        return val.slice(0, 10);
+      }
+      return "";
+    },
+  },
+  // {
+  //   attrs: {
+  //     label: "投产时间",
+  //     prop: "produceTime",
+  //     width: 160,
+  //   },
+  // },
+  {
+    attrs: {
+      label: "完成时间",
+      prop: "finishTime",
+      width: 160,
+    },
+  },
+
+  {
+    attrs: {
+      label: "生产用时",
+      prop: "usageTime",
+      width: 100,
+    },
+  },
+  // {
+  //   attrs: {
+  //     label: "备注",
+  //     prop: "remark",
+  //     "min-width": 200,
+  //   },
+  // },
+]);
+
 const sourceListOne = ref({
   data: [],
   pagination: {
@@ -1770,6 +2211,9 @@ const getProcesses = () => {
         config.value.push({
           attrs,
         });
+        if (ele.isShow == 1) {
+          configCopy.value.push({ attrs });
+        }
       }
 
       // config.value.push({
@@ -2496,6 +2940,14 @@ const submitConfirm = (flag) => {
       });
   }
 };
+
+const changeRemark = (otherProdRemark, id) => {
+  let data = {
+    otherProdRemark,
+    id,
+  };
+  proxy.post("/produceOrderDetail/editOtherProdRemark", data).then((res) => {});
+};
 </script>
 
 <style lang="scss" scoped>
@@ -2608,5 +3060,22 @@ const submitConfirm = (flag) => {
     text-align: center;
   }
 }
+:deep(#pdfDom .el-textarea__inner) {
+  background: transparent !important;
+  overflow-y: hidden;
+  padding: 0 4px !important;
+  resize: none;
+}
+:deep(#pdfDom .el-textarea) {
+  --el-input-focus-border: transparent;
+  --el-input-transparent-border: 0 0 0 0px;
+  --el-input-border-color: transparent;
+  --el-input-hover-border: 0px !important;
+  --el-input-hover-border-color: transparent;
+  --el-input-focus-border-color: transparent;
+  --el-input-clear-hover-color: transparent;
+  box-shadow: 0 0 0 0px !important;
+  --el-input-border: 0px;
+}
 </style>
 

+ 539 - 0
src/views/finance/salary/salaryManagement/index.vue

@@ -0,0 +1,539 @@
+<template>
+  <div class="pageIndexClass">
+    <div class="content">
+      <byTable :source="sourceList.data" :pagination="sourceList.pagination" :config="config" :loading="loading" highlight-current-row :action-list="[
+          {
+            text: '添加',
+            action: () => openModal('add'),
+          },
+        ]" @get-list="getList">
+      </byTable>
+    </div>
+
+    <el-dialog :title="modalType == 'add' ? '添加' : '编辑'" v-if="dialogVisible" v-model="dialogVisible" width="50%">
+      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit" v-loading="loadingDialog">
+        <template #detail>
+          <div style="width:100%">
+            <el-button type="primary" @click="handleAdd()" plain style="margin-bottom: 16px">添加</el-button>
+            <el-table :data="formData.data.userSalaryDetailList" style="width: 100%;">
+              <el-table-column label="结构名称">
+                <template #default="{ row, $index }">
+                  <el-form-item :prop="'userSalaryDetailList.' + $index + '.salaryStructureId'" :rules="rules.salaryStructureId"
+                                :inline-message="true" class="margin-b-0">
+                    <el-select v-model="row.salaryStructureId" placeholder="请选择" filterable style="width: 100%">
+                      <el-option v-for="item in salaryStructureData" :key="item.value" :label="item.label" :value="item.value" />
+                    </el-select>
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column label="金额" width="130">
+                <template #default="{ row, $index }">
+                  <div style="width: 100%">
+                    <el-form-item :prop="'userSalaryDetailList.' + $index + '.money'" :rules="rules.money" :inline-message="true"
+                                  class="margin-b-0 wid100">
+                      <el-input-number onmousewheel="return false;" v-model="row.money" placeholder="请输入" style="width: 100%" :precision="2"
+                                       :controls="false" :min="0" @change="handleChangeAmount" />
+                    </el-form-item>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="操作" width="60" align="center" fixed="right">
+                <template #default="{ $index }">
+                  <el-button type="primary" link @click="handleRemove($index)">删除</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="default">取 消</el-button>
+        <el-button type="primary" @click="submitForm()" size="default">确 定</el-button>
+      </template>
+    </el-dialog>
+
+    <el-dialog title="打印" v-if="openPrint" v-model="openPrint" width="920">
+      <SalaryConfirmationPDF :rowData="rowData"></SalaryConfirmationPDF>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { computed, ref } from "vue";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import useUserStore from "@/store/modules/user";
+import moment from "moment";
+import SalaryConfirmationPDF from "@/components/PDF/SalaryConfirmationPDF.vue";
+
+const { proxy } = getCurrentInstance();
+const accountCurrency = ref([]);
+const employeeTypeData = ref([
+  {
+    label: "实习员工",
+    value: "10",
+  },
+  {
+    label: "试用员工",
+    value: "20",
+  },
+  {
+    label: "正式员工",
+    value: "30",
+  },
+]);
+const userList = ref([]);
+const salaryStructureData = ref([]);
+const deptData = ref([]);
+const contractorData = ref([]);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+  },
+});
+const loading = ref(false);
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "员工姓名",
+        prop: "nickName",
+      },
+    },
+    {
+      attrs: {
+        label: "劳动关系",
+        prop: "employeeType",
+      },
+      render(val) {
+        return proxy.dictValueLabel(val, employeeTypeData.value);
+      },
+    },
+    {
+      attrs: {
+        label: "试用期薪资比例",
+        prop: "probationRatio",
+      },
+      render(val) {
+        if (val) {
+          return val + "%";
+        }
+      },
+    },
+    {
+      attrs: {
+        label: "实习期薪资比例",
+        prop: "internshipRatio",
+      },
+      render(val) {
+        if (val) {
+          return val + "%";
+        }
+      },
+    },
+    {
+      attrs: {
+        label: "合计金额",
+        prop: "amount",
+      },
+    },
+    // {
+    //   attrs: {
+    //     label: "修改时间",
+    //     prop: "createTime",
+    //   },
+    // },
+    {
+      attrs: {
+        label: "操作",
+        width: "120",
+        align: "center",
+      },
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "修改",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              update(row);
+            },
+          },
+          {
+            attrs: {
+              label: "确认单",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              clickPrint(row);
+            },
+          },
+          // {
+          //   attrs: {
+          //     label: "删除",
+          //     type: "danger",
+          //     text: true,
+          //   },
+          //   el: "button",
+          //   click() {
+          //     proxy
+          //       .msgConfirm()
+          //       .then((res) => {
+          //         proxy
+          //           .post("/userSalaryManage/delete", {
+          //             id: row.userId,
+          //           })
+          //           .then((res) => {
+          //             proxy.msgTip("操作成功", 1);
+          //             getList();
+          //           });
+          //       })
+          //       .catch((err) => {});
+          //   },
+          // },
+        ];
+      },
+    },
+  ];
+});
+const corporationList = ref([]);
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/userSalaryManage/page", sourceList.value.pagination)
+    .then((res) => {
+      sourceList.value.data = res.rows;
+      sourceList.value.pagination.total = res.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+getList();
+
+const getDeptData = () => {
+  proxy
+    .get("/tenantUser/listAll", {
+      pageNum: 1,
+      pageSize: 10000,
+      tenantId: proxy.useUserStore().user.tenantId,
+      // companyId: proxy.useUserStore().user.companyId,
+    })
+    .then((res) => {
+      userList.value = res.rows.map((item) => {
+        return {
+          label: item.nickName,
+          value: item.userId,
+        };
+      });
+    });
+  proxy
+    .post("/salaryStructure/page", {
+      pageNum: 1,
+      pageSize: 999,
+    })
+    .then((res) => {
+      salaryStructureData.value = res.rows.map((item) => {
+        return {
+          label: item.name,
+          value: item.id,
+        };
+      });
+    });
+};
+getDeptData();
+
+const modalType = ref("add");
+const dialogVisible = ref(false);
+const loadingDialog = ref(false);
+const submit = ref(null);
+const formOption = reactive({
+  inline: true,
+  labelWidth: 120,
+  itemWidth: 100,
+  rules: [],
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "title1",
+      title: "基本信息",
+    },
+    {
+      type: "select",
+      prop: "userId",
+      label: "员工姓名",
+      itemWidth: 50,
+      disabled: false,
+      data: userList.value,
+    },
+    {
+      type: "select",
+      prop: "employeeType",
+      label: "劳动关系",
+      itemWidth: 50,
+      disabled: false,
+      data: employeeTypeData.value,
+    },
+    {
+      type: "number",
+      prop: "probationRatio",
+      label: "试用期薪资比例",
+      precision: 2,
+      min: 0,
+      max: 100,
+      controls: false,
+      itemWidth: 50,
+    },
+    {
+      type: "number",
+      prop: "internshipRatio",
+      label: "实习期薪资比例",
+      precision: 2,
+      min: 0,
+      max: 100,
+      controls: false,
+      itemWidth: 50,
+    },
+    {
+      type: "date",
+      itemType: "date",
+      prop: "documentaryTime",
+      label: "入职日期",
+      disabled: false,
+      itemWidth: 50,
+    },
+    {
+      type: "date",
+      itemType: "date",
+      prop: "effectiveDate",
+      label: "生效日期",
+      disabled: false,
+      itemWidth: 50,
+    },
+    {
+      type: "date",
+      itemType: "date",
+      prop: "fullTimeDate",
+      label: "转正日期",
+      disabled: false,
+      itemWidth: 50,
+    },
+    {
+      type: "number",
+      prop: "probationPeriod",
+      label: "试用期限(月)",
+      precision: 0,
+      min: 0,
+      max: 12,
+      controls: false,
+      itemWidth: 50,
+    },
+    // {
+    //   type: "number",
+    //   prop: "amount",
+    //   label: "合计金额",
+    //   precision: 2,
+    //   controls: false,
+    //   itemWidth: 50,
+    //   disabled: true,
+    // },
+    // {
+    //   type: "title1",
+    //   title: "薪资结构",
+    // },
+    // {
+    //   type: "slot",
+    //   slotName: "detail",
+    // },
+  ];
+});
+const rules = ref({
+  userId: [{ required: true, message: "请选择员工姓名", trigger: "change" }],
+  employeeType: [
+    { required: true, message: "请选择劳动关系", trigger: "change" },
+  ],
+  probationRatio: [
+    { required: true, message: "请输入试用期薪资比例", trigger: "blur" },
+  ],
+  internshipRatio: [
+    { required: true, message: "请输入实习期薪资比例", trigger: "blur" },
+  ],
+  salaryStructureId: [
+    { required: true, message: "请选择结构名称", trigger: "change" },
+  ],
+  money: [{ required: true, message: "请输入金额", trigger: "blur" }],
+  fileList: [{ required: true, message: "请上传签字文件", trigger: "change" }],
+  // remark: [{ required: true, message: "请输入说明", trigger: "blur" }],
+});
+const formData = reactive({
+  data: {},
+});
+const openModal = (val) => {
+  modalType.value = val;
+  formData.data = {
+    userSalaryDetailList: [{ salaryStructureId: "", money: null }],
+    fileList: [],
+  };
+  loadingDialog.value = false;
+  dialogVisible.value = true;
+};
+
+const handleAdd = () => {
+  formData.data.userSalaryDetailList.push({
+    salaryStructureId: "",
+    money: null,
+  });
+};
+const handleChangeAmount = () => {
+  let money = 0;
+  if (
+    formData.data.userSalaryDetailList &&
+    formData.data.userSalaryDetailList.length > 0
+  ) {
+    for (let i = 0; i < formData.data.userSalaryDetailList.length; i++) {
+      if (formData.data.userSalaryDetailList[i].money) {
+        money = parseFloat(
+          Number(money) + Number(formData.data.userSalaryDetailList[i].money)
+        ).toFixed(2);
+      }
+    }
+  }
+  formData.data.amount = money;
+};
+
+const handleRemove = (index) => {
+  formData.data.userSalaryDetailList.splice(index, 1);
+  handleChangeAmount();
+};
+
+const clickBalance = () => {
+  if (
+    formData.data.accountRemainderList &&
+    formData.data.accountRemainderList.length > 0
+  ) {
+    formData.data.accountRemainderList.push({
+      currency: "",
+      remainder: undefined,
+    });
+  } else {
+    formData.data.accountRemainderList = [
+      { currency: "", remainder: undefined },
+    ];
+  }
+};
+
+const isRepeat = (arr) => {
+  var hash = {};
+  for (var i in arr) {
+    if (hash[arr[i].currency]) return true;
+    hash[arr[i].currency] = true;
+  }
+  return false;
+};
+
+const submitForm = () => {
+  submit.value.handleSubmit(() => {
+    // if (
+    //   !(
+    //     formData.data.userSalaryDetailList &&
+    //     formData.data.userSalaryDetailList.length > 0
+    //   )
+    // ) {
+    //   return proxy.msgTip("请添加薪资结构", 2);
+    // }
+    loadingDialog.value = true;
+    proxy.post("/userSalaryManage/edit", formData.data).then(
+      () => {
+        proxy.msgTip("操作成功", 1);
+        dialogVisible.value = false;
+        getList();
+      },
+      (err) => {
+        console.log(err);
+        loadingDialog.value = false;
+      }
+    );
+    // if (
+    //   formData.data.accountRemainderList &&
+    //   formData.data.accountRemainderList.length > 0
+    // ) {
+    //   if (isRepeat(formData.data.accountRemainderList)) {
+    //     return ElMessage("请勿重复添加货币余额");
+    //   } else {
+    //     loadingDialog.value = true;
+    //     proxy.post("/accountManagement/" + modalType.value, formData.data).then(
+    //       () => {
+    //         ElMessage({
+    //           message: modalType.value == "add" ? "添加成功" : "编辑成功",
+    //           type: "success",
+    //         });
+    //         dialogVisible.value = false;
+    //         getList();
+    //       },
+    //       (err) => {
+    //         console.log(err);
+    //         loadingDialog.value = false;
+    //       }
+    //     );
+    //   }
+    // } else {
+    //   return ElMessage("请添加至少一条类型余额");
+    // }
+  });
+};
+
+const update = (row) => {
+  loadingDialog.value = false;
+  modalType.value = "edit";
+  proxy.post("/userSalaryManage/detail", { userId: row.userId }).then((res) => {
+    formData.data = res;
+    proxy
+      .post("/fileInfo/getList", { businessIdList: [row.userId] })
+      .then((fileObj) => {
+        if (fileObj[row.userId] && fileObj[row.userId].length > 0) {
+          formData.data.fileList = fileObj[row.userId]
+            .filter((x) => x.businessType == "10")
+            .map((item) => {
+              return {
+                ...item,
+                name: item.fileName,
+                url: item.fileUrl,
+              };
+            });
+        } else {
+          formData.data.fileList = [];
+        }
+      });
+  });
+  dialogVisible.value = true;
+};
+
+const openPrint = ref(false);
+const rowData = ref({});
+const clickPrint = (row) => {
+  rowData.value = {
+    id: row.userId,
+  };
+  openPrint.value = true;
+};
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+::v-deep(.el-input-number .el-input__inner) {
+  text-align: left;
+}
+</style>

+ 364 - 0
src/views/finance/salary/salaryStructure/index.vue

@@ -0,0 +1,364 @@
+<template>
+  <div class="pageIndexClass">
+    <div class="content">
+      <byTable :source="sourceList.data" :pagination="sourceList.pagination" :config="config" :loading="loading" highlight-current-row :action-list="[
+          {
+            text: '添加',
+            action: () => openModal('add'),
+          },
+        ]" @get-list="getList">
+      </byTable>
+    </div>
+
+    <el-dialog :title="modalType == 'add' ? '添加' : '编辑'" v-if="dialogVisible" v-model="dialogVisible" width="50%">
+      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit" v-loading="loadingDialog">
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="default">取 消</el-button>
+        <el-button type="primary" @click="submitForm()" size="default">确 定</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { computed, ref } from "vue";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import useUserStore from "@/store/modules/user";
+import { ElMessage, ElMessageBox } from "element-plus";
+import moment from "moment";
+
+const { proxy } = getCurrentInstance();
+const accountCurrency = ref([]);
+const typeData = ref([
+  {
+    label: "收入",
+    value: "10",
+  },
+  {
+    label: "支出",
+    value: "20",
+  },
+]);
+const userList = ref([]);
+const deptData = ref([]);
+const contractorData = ref([]);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+  },
+});
+const loading = ref(false);
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "结构名称",
+        prop: "name",
+      },
+    },
+    {
+      attrs: {
+        label: "是否额外收入",
+        prop: "type",
+      },
+      render(val) {
+        return val == "1" ? "是" : "否";
+      },
+    },
+    {
+      attrs: {
+        label: "备注",
+        prop: "remark",
+      },
+    },
+    {
+      attrs: {
+        label: "创建时间",
+        prop: "createTime",
+      },
+    },
+    {
+      attrs: {
+        label: "操作",
+        width: "120",
+        align: "center",
+      },
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "修改",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              update(row);
+            },
+          },
+          {
+            attrs: {
+              label: "删除",
+              type: "danger",
+              text: true,
+            },
+            el: "button",
+            click() {
+              proxy
+                .msgConfirm()
+                .then((res) => {
+                  proxy
+                    .post("/salaryStructure/delete", {
+                      id: row.id,
+                    })
+                    .then((res) => {
+                      proxy.msgTip("操作成功", 1);
+                      getList();
+                    });
+                })
+                .catch((err) => {});
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+const corporationList = ref([]);
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/salaryStructure/page", sourceList.value.pagination)
+    .then((res) => {
+      sourceList.value.data = res.rows;
+      sourceList.value.pagination.total = res.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+getList();
+
+const getDeptData = () => {
+  proxy
+    .get("/tenantUser/listAll", {
+      pageNum: 1,
+      pageSize: 10000,
+      tenantId: proxy.useUserStore().user.tenantId,
+      // companyId: proxy.useUserStore().user.companyId,
+    })
+    .then((res) => {
+      userList.value = res.rows.map((item) => {
+        return {
+          label: item.nickName,
+          value: item.userId,
+        };
+      });
+    });
+
+  proxy
+    .get("/tenantDept/list", {
+      pageNum: 1,
+      pageSize: 9999,
+      keyword: "",
+      // ancestors: proxy.useUserStore().user.companyId,
+      tenantId: proxy.useUserStore().user.tenantId,
+      // type: 2,
+    })
+    .then((res) => {
+      deptData.value = proxy.handleTree(res.data, "deptId");
+    });
+
+  proxy
+    .post("/contractor/page", {
+      pageNum: 1,
+      pageSize: 999,
+    })
+    .then((res) => {
+      contractorData.value = res.rows.map((item) => {
+        return {
+          label: item.name,
+          value: item.id,
+        };
+      });
+    });
+};
+// getDeptData();
+
+const modalType = ref("add");
+const dialogVisible = ref(false);
+const loadingDialog = ref(false);
+const submit = ref(null);
+const formOption = reactive({
+  inline: true,
+  labelWidth: 110,
+  itemWidth: 100,
+  rules: [],
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "title1",
+      title: "基本信息",
+    },
+    {
+      type: "input",
+      prop: "name",
+      itemType: "text",
+      label: "名称",
+      itemWidth: 100,
+      disabled: false,
+    },
+    {
+      type: "radio",
+      prop: "type",
+      border: true,
+      label: "是否额外收入",
+      itemWidth: 100,
+      disabled: false,
+      data: [
+        { label: "是", value: "1" },
+        { label: "否", value: "0" },
+      ],
+    },
+    {
+      type: "input",
+      prop: "remark",
+      itemType: "textarea",
+      label: "备注",
+      itemWidth: 100,
+      disabled: false,
+    },
+  ];
+});
+const rules = ref({
+  name: [{ required: true, message: "请输入名称", trigger: "blur" }],
+  type: [{ required: true, message: "请选择是否额外收入", trigger: "change" }],
+});
+const formData = reactive({
+  data: {},
+});
+const openModal = (val) => {
+  modalType.value = val;
+  formData.data = {
+    applyTime: moment().format("YYYY-MM-DD"),
+    companyId: proxy.useUserStore().user.companyId,
+    deptId: proxy.useUserStore().user.dept.deptId,
+    createUser: proxy.useUserStore().user.userId,
+    fileList: [],
+  };
+  loadingDialog.value = false;
+  dialogVisible.value = true;
+};
+const clickBalance = () => {
+  if (
+    formData.data.accountRemainderList &&
+    formData.data.accountRemainderList.length > 0
+  ) {
+    formData.data.accountRemainderList.push({
+      currency: "",
+      remainder: undefined,
+    });
+  } else {
+    formData.data.accountRemainderList = [
+      { currency: "", remainder: undefined },
+    ];
+  }
+};
+const handleRemove = (index) => {
+  formData.data.accountRemainderList.splice(index, 1);
+};
+const isRepeat = (arr) => {
+  var hash = {};
+  for (var i in arr) {
+    if (hash[arr[i].currency]) return true;
+    hash[arr[i].currency] = true;
+  }
+  return false;
+};
+const submitForm = () => {
+  submit.value.handleSubmit(() => {
+    loadingDialog.value = true;
+    proxy.post("/salaryStructure/" + modalType.value, formData.data).then(
+      () => {
+        proxy.msgTip("操作成功", 1);
+        dialogVisible.value = false;
+        getList();
+      },
+      (err) => {
+        console.log(err);
+        loadingDialog.value = false;
+      }
+    );
+    // if (
+    //   formData.data.accountRemainderList &&
+    //   formData.data.accountRemainderList.length > 0
+    // ) {
+    //   if (isRepeat(formData.data.accountRemainderList)) {
+    //     return ElMessage("请勿重复添加货币余额");
+    //   } else {
+    //     loadingDialog.value = true;
+    //     proxy.post("/accountManagement/" + modalType.value, formData.data).then(
+    //       () => {
+    //         ElMessage({
+    //           message: modalType.value == "add" ? "添加成功" : "编辑成功",
+    //           type: "success",
+    //         });
+    //         dialogVisible.value = false;
+    //         getList();
+    //       },
+    //       (err) => {
+    //         console.log(err);
+    //         loadingDialog.value = false;
+    //       }
+    //     );
+    //   }
+    // } else {
+    //   return ElMessage("请添加至少一条类型余额");
+    // }
+  });
+};
+
+const update = (row) => {
+  loadingDialog.value = false;
+  modalType.value = "edit";
+  formData.data = proxy.deepClone(row);
+  // proxy.post("/epibolyBill/detail", { id: row.id }).then((res) => {
+  //   formData.data = res;
+  //   proxy
+  //     .post("/fileInfo/getList", { businessIdList: [row.id] })
+  //     .then((fileObj) => {
+  //       if (fileObj[row.id] && fileObj[row.id].length > 0) {
+  //         formData.data.fileList = fileObj[row.id]
+  //           .filter((x) => x.businessType == "0")
+  //           .map((item) => {
+  //             return {
+  //               ...item,
+  //               name: item.fileName,
+  //               url: item.fileUrl,
+  //             };
+  //           });
+  //       } else {
+  //         formData.data.fileList = [];
+  //       }
+  //     });
+  // });
+  dialogVisible.value = true;
+};
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+::v-deep(.el-input-number .el-input__inner) {
+  text-align: left;
+}
+</style>

+ 19 - 1
src/views/purchaseManage/purchaseManage/subscribe/index.vue

@@ -16,6 +16,12 @@
             {{ item.fileName }}
           </div>
         </template>
+        <template #subscribeCode="{ item }">
+          <div style="cursor: pointer; color: #409eff" @click="handleClickCode(item)">
+            {{ item.subscribeCode }}
+          </div>
+        </template>
+
         <template #size="{ item }">
           <div>
             <span>{{ item.productLength }}cm</span>*
@@ -187,7 +193,7 @@ const config = computed(() => {
     {
       attrs: {
         label: "申购单号",
-        prop: "subscribeCode",
+        slot: "subscribeCode",
         width: 150,
       },
     },
@@ -498,6 +504,18 @@ onBeforeUnmount(() => {
   // 取消订阅特定事件
   $bus.off("refreshTableData");
 });
+
+const handleClickCode = (row) => {
+  proxy.$router.replace({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "subscribe_flow",
+      id: row.flowId,
+      processType: 20,
+      businessId: row.subcribeId,
+    },
+  });
+};
 </script>
   
 <style lang="scss" scoped>