Przeglądaj źródła

Merge remote-tracking branch 'origin/master'

yusm 2 miesięcy temu
rodzic
commit
9d498805eb
16 zmienionych plików z 362 dodań i 124 usunięć
  1. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/vite.config.js
  2. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm/node_modules.zip
  3. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/vite.config.ts
  4. 18 4
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskController.java
  5. 2 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WeiXinCorpController.java
  6. 7 6
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Task.java
  7. 3 3
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DingDingServiceImpl.java
  8. 56 54
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TaskMapper.xml
  9. 3 2
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  10. 10 10
      fhKeeper/formulahousekeeper/timesheet-workshop/config/index.js
  11. 3 13
      fhKeeper/formulahousekeeper/timesheet/config/index.js
  12. 3 0
      fhKeeper/formulahousekeeper/timesheet/src/components/taskComponent.vue
  13. 166 9
      fhKeeper/formulahousekeeper/timesheet/src/views/leave/list.vue
  14. 8 0
      fhKeeper/formulahousekeeper/timesheet_h5/src/router/index.js
  15. 71 9
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/exaLeave/applyLeave.vue
  16. 10 10
      fhKeeper/formulahousekeeper/timesheet_h5/vue.config.js

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm-h5/vite.config.js

@@ -5,7 +5,7 @@ import Components from "unplugin-vue-components/vite";
 import { VantResolver } from "unplugin-vue-components/resolvers";
 import { postcssConfig } from "./postcss.config.js";
 
-// const target = 'http://192.168.2.7:10010';
+// const target = 'http://192.168.2.40:10099';
 // const target = 'http://192.168.2.3:10010';
 // const target = 'http://192.168.2.17:10010';
 const target = 'http://47.101.180.183:10014';

BIN
fhKeeper/formulahousekeeper/customerBuler-crm/node_modules.zip


+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/vite.config.ts

@@ -3,7 +3,7 @@ import vue from '@vitejs/plugin-vue';
 
 import { resolve } from 'path';
 
-// const target = 'http://192.168.2.28:10010';
+// const target = 'http://192.168.2.40:10099';
 // const target = 'http://192.168.2.17:10010';
 // const target = "http://127.0.0.1:10010";
 // const target = "http://192.168.2.178:10010";

+ 18 - 4
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskController.java

@@ -528,8 +528,23 @@ public class TaskController {
                 return msg;
             }
         }
-        //检查前置任务是否都已经完成
+        //检查是否要核验成果文件
+        Task curTask = taskMapper.selectById(task.getId());
+        if (curTask.getAttachFileRequired() && task.getTaskStatus() == 0) {
+            Integer cnt = taskFilesMapper.selectCount(new QueryWrapper<TaskFiles>().eq("task_id",task.getId()));
+            if (cnt == 0) {
+                msg.setError("当前任务必须要上传成果附件才可以完成");
+                return msg;
+            } else {
+                cnt = taskFilesMapper.selectCount(new QueryWrapper<TaskFiles>().eq("task_id",task.getId()).eq("final_charge_status",0));
+                if (cnt > 0) {
+                    msg.setError("当前任务存在尚未审核通过的成果附件,不可完成");
+                    return msg;
+                }
+            }
+        }
 
+        //检查前置任务是否都已经完成
         boolean isFinishTask = false;
         if (task.getTaskStatus() == 0) {
             task.setTaskStatus(1);
@@ -620,9 +635,8 @@ public class TaskController {
         }
 
         //如果是里程碑,需要更新项目完成度
-        task = taskMapper.selectById(task.getId());
-        if (task.getTaskType() == 1) {
-            Integer projectId = task.getProjectId();
+        if (curTask.getTaskType() == 1) {
+            Integer projectId = curTask.getProjectId();
             updateProjectProgress(projectId);
         }
         return msg;

+ 2 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WeiXinCorpController.java

@@ -1184,10 +1184,10 @@ public class WeiXinCorpController {
                             if (department.contains(",")) {
                                 String[] split = department.split(",");
                                 curUserWXDeptid = getMaxDeptIdFromArray(split);
-                            } else {
+                            } else if (!StringUtils.isEmpty(department)){
                                 curUserWXDeptid = Integer.valueOf(department);
                             }
-                        } else if (jsonObject.has("MainDepartment")) {
+                        } else if (jsonObject.has("MainDepartment") && !StringUtils.isEmpty(jsonObject.getString("MainDepartment"))) {
                             //取主部门
                             curUserWXDeptid = jsonObject.getInt("MainDepartment");
                         } else {

+ 7 - 6
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Task.java

@@ -15,18 +15,13 @@ import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 import org.springframework.format.annotation.DateTimeFormat;
 
-import java.io.Serializable;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.util.List;
-
 /**
  * <p>
  * 
  * </p>
  *
  * @author Seyason
- * @since 2025-01-04
+ * @since 2025-02-28
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -305,6 +300,12 @@ public class Task extends Model<Task> {
      * 任务的外置状态显示 1审核中[待审核+(审核通过)] 2驳回[存在驳回文件]  3审核通过[全部审核通过]
      * */
     private int fileChargeStatus;
+    /**
+     * 完成任务时,成果文件是否必传
+     */
+    @TableField("attach_file_required")
+    private Boolean attachFileRequired;
+
 
     @Override
     protected Serializable pkVal() {

+ 3 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DingDingServiceImpl.java

@@ -1364,18 +1364,18 @@ public class DingDingServiceImpl implements DingDingService {
                                         companyMapper.updateById(company);
                                     } else if ("RENEW".equals(orderType)) {
                                         System.out.println("==Push 推送事件 续费套餐=="+biz_data.toJSONString());
-                                        int serviceStopTime = biz_data.getIntValue("serviceStopTime");
+                                        long serviceStopTime = biz_data.getLongValue("serviceStopTime");
                                         company.setExpirationDate(LocalDateTime.ofEpochSecond(serviceStopTime/1000, 0, ZoneOffset.ofHours(8)));
                                         companyMapper.updateById(company);
                                     } else if ("RENEW_UPGRADE".equals(orderType)) {
                                         System.out.println("==Push 推送事件 续费升级套餐=="+biz_data.toJSONString());
-                                        int serviceStopTime = biz_data.getIntValue("serviceStopTime");
+                                        long serviceStopTime = biz_data.getLongValue("serviceStopTime");
                                         company.setStaffCountMax(subQuantity);
                                         company.setExpirationDate(LocalDateTime.ofEpochSecond(serviceStopTime/1000, 0, ZoneOffset.ofHours(8)));
                                         companyMapper.updateById(company);
                                     } else if ("RENEW_DEGRADE".equals(orderType)) {
                                         System.out.println("==Push 推送事件 续费降级套餐=="+biz_data.toJSONString());
-                                        int serviceStopTime = biz_data.getIntValue("serviceStopTime");
+                                        long serviceStopTime = biz_data.getLongValue("serviceStopTime");
                                         company.setStaffCountMax(subQuantity);
                                         company.setExpirationDate(LocalDateTime.ofEpochSecond(serviceStopTime/1000, 0, ZoneOffset.ofHours(8)));
                                         companyMapper.updateById(company);

+ 56 - 54
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TaskMapper.xml

@@ -33,7 +33,9 @@
         <result column="ahead_tid" property="aheadTid" />
         <result column="sap_task_code" property="sapTaskCode" />
         <result column="plan_cost" property="planCost" />
+        <result column="attach_file_required" property="attachFileRequired" />
     </resultMap>
+
     <resultMap id="timeResultMap" type="com.management.platform.entity.TimeTask" >
         <id column="id" property="id" />
         <result column="name" property="name" />
@@ -97,16 +99,16 @@
         <result column="sap_task_code" property="sapTaskCode" />
         <result column="stages_name" property="stagesName" />
         <result column="department_name" property="departmentName" />
-
-<!--        <result column="charge_one_id" property="chargeOneId" />-->
-<!--        <result column="charge_one_status" property="chargeOneStatus" />-->
-<!--        <result column="charge_one_time" property="chargeOneTime" />-->
-<!--        <result column="charge_two_id" property="chargeTwoId" />-->
-<!--        <result column="charge_two_status" property="chargeTwoStatus" />-->
-<!--        <result column="charge_two_time" property="chargeTwoTime" />-->
-<!--        <result column="charge_stage" property="chargeStage" />-->
-<!--        <result column="final_charge_status" property="finalChargeStatus" />-->
-<!--        <result column="file_reject_reason" property="fileRejectReason"></result>-->
+        <result column="attach_file_required" property="attachFileRequired" />
+        <!--        <result column="charge_one_id" property="chargeOneId" />-->
+        <!--        <result column="charge_one_status" property="chargeOneStatus" />-->
+        <!--        <result column="charge_one_time" property="chargeOneTime" />-->
+        <!--        <result column="charge_two_id" property="chargeTwoId" />-->
+        <!--        <result column="charge_two_status" property="chargeTwoStatus" />-->
+        <!--        <result column="charge_two_time" property="chargeTwoTime" />-->
+        <!--        <result column="charge_stage" property="chargeStage" />-->
+        <!--        <result column="final_charge_status" property="finalChargeStatus" />-->
+        <!--        <result column="file_reject_reason" property="fileRejectReason"></result>-->
     </resultMap>
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
@@ -679,61 +681,61 @@
     <select id="getTaskFileChargePageTotal" resultType="java.lang.Integer">
         select count(*)
         from
-            (
-                select tf.task_id
-                from task_files tf
-                         left join task on tf.task_id = task.id
-                         left join project p on task.project_id = p.id
-                <where>
-                    tf.need_file_charge = 1
-                    and tf.final_charge_status = 0
-                    and task.task_status = 0
-                    and task.company_id = #{queryBO.companyId}
-                    and case tf.charge_stage
-                    when 1 then tf.charge_one_id = #{queryBO.userId} and tf.charge_one_status = 0
-                    when 2 then tf.charge_two_id = #{queryBO.userId} and tf.charge_two_status = 0
-                    end
-                    <if test="queryBO.taskName != null and queryBO.taskName != ''">
-                        and task.name like concat('%',#{queryBO.taskName},'%')
-                    </if>
-                    <if test="deptIds!=null and deptIds.size()>0">
-                        and p.dept_id in
-                        <foreach collection="deptIds" open="(" close=")" separator="," item="item">
-                            #{item}
-                        </foreach>
-                    </if>
-                </where>
-                group by tf.task_id
-            )tmp1
+        (
+        select tf.task_id
+        from task_files tf
+        left join task on tf.task_id = task.id
+        left join project p on task.project_id = p.id
+        <where>
+            tf.need_file_charge = 1
+            and tf.final_charge_status = 0
+            and task.task_status = 0
+            and task.company_id = #{queryBO.companyId}
+            and case tf.charge_stage
+            when 1 then tf.charge_one_id = #{queryBO.userId} and tf.charge_one_status = 0
+            when 2 then tf.charge_two_id = #{queryBO.userId} and tf.charge_two_status = 0
+            end
+            <if test="queryBO.taskName != null and queryBO.taskName != ''">
+                and task.name like concat('%',#{queryBO.taskName},'%')
+            </if>
+            <if test="deptIds!=null and deptIds.size()>0">
+                and p.dept_id in
+                <foreach collection="deptIds" open="(" close=")" separator="," item="item">
+                    #{item}
+                </foreach>
+            </if>
+        </where>
+        group by tf.task_id
+        )tmp1
     </select>
     <select id="getProjectAllTaskTimeCost"
             resultType="com.management.platform.entity.vo.ProjectTaskTimeCostVO">
         SELECT task.id as taskId,ifnull(task_executor.`plan_hours`,0) as planHours,
-        (SELECT IFNULL(SUM(working_time),0) FROM report WHERE report.`task_id` = task.id AND report.`state` = 1
-                                                          and report.creator_id = task_executor.executor_id) AS realHours,
-        task_executor.executor_id as executorId
+               (SELECT IFNULL(SUM(working_time),0) FROM report WHERE report.`task_id` = task.id AND report.`state` = 1
+                                                                 and report.creator_id = task_executor.executor_id) AS realHours,
+               task_executor.executor_id as executorId
         FROM task
-        LEFT JOIN project ON project.id = task.`project_id`
-        left join task_executor on task_executor.task_id=task.id
+                 LEFT JOIN project ON project.id = task.`project_id`
+                 left join task_executor on task_executor.task_id=task.id
         WHERE task.project_id = #{projectId}
           and project.id = #{projectId}
     </select>
     <select id="getProjectTaskTimeCostByIds" resultType="com.management.platform.entity.vo.ProjectTimeCostVO">
         select project_id,sum(planHours) as planHoursSum,sum(realHours) as realHoursSum
         from
-            (
-                SELECT task.project_id,task.id as taskId,ifnull(task_executor.`plan_hours`,0) as planHours,
-                       (SELECT IFNULL(SUM(working_time),0) FROM report
-                        WHERE report.`task_id` = task.id AND report.`state` = 1 and report.creator_id = task_executor.executor_id) AS realHours,
-                       task_executor.executor_id as executorId
-                FROM task
-                         LEFT JOIN project ON project.id = task.`project_id`
-                         left join task_executor on task_executor.task_id=task.id
-                WHERE task.project_id in
-                      <foreach collection="projectIds" item="projectId" separator="," open="(" close=")">
-                            #{projectId}
-                        </foreach>
-            )tmp1
+        (
+        SELECT task.project_id,task.id as taskId,ifnull(task_executor.`plan_hours`,0) as planHours,
+        (SELECT IFNULL(SUM(working_time),0) FROM report
+        WHERE report.`task_id` = task.id AND report.`state` = 1 and report.creator_id = task_executor.executor_id) AS realHours,
+        task_executor.executor_id as executorId
+        FROM task
+        LEFT JOIN project ON project.id = task.`project_id`
+        left join task_executor on task_executor.task_id=task.id
+        WHERE task.project_id in
+        <foreach collection="projectIds" item="projectId" separator="," open="(" close=")">
+            #{projectId}
+        </foreach>
+        )tmp1
         group by project_id
     </select>
 </mapper>

+ 3 - 2
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -204,8 +204,9 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         List<Report> allFileProcReportList = reportMapper.selectList(new QueryWrapper<Report>().eq("plan_id", report.getPlanId()).eq("prod_procedure_id", report.getProdProcedureId()));
         final LocalDate fDate = targetDate;
         double allFileProcNum = allFileProcReportList.stream().filter(item->!(item.getCreatorId().equals(token) && item.getCreateDate().isEqual(fDate))).mapToDouble(Report::getFinishNum).sum();
-        if (allFileProcNum + report.getFinishNum() > plan.getNum()) {
-            httpRespMsg.setError("填报的件数超过了剩余可填报件数:"+(plan.getNum() - allFileProcNum)+", 请联系班组长协调解决");
+        double leftNum = new BigDecimal(plan.getNum() - allFileProcNum).setScale(2, RoundingMode.HALF_UP).doubleValue();
+        if (report.getFinishNum() > leftNum) {
+            httpRespMsg.setError("填报的件数超过了剩余可填报件数:"+leftNum+", 请联系班组长协调解决");
             return httpRespMsg;
         }
         //检查钢印号是否已经被同工序里面的其他人报过了

+ 10 - 10
fhKeeper/formulahousekeeper/timesheet-workshop/config/index.js

@@ -1,20 +1,20 @@
 var path = require('path')
 
-//  var ip = '192.168.2.12'
+ var ip = '192.168.2.11'
 // var ip = '47.101.180.183'
 // var ip = '47.100.37.243'
 // var ip = '192.168.10.2'
 //var ip = '192.168.2.12'
 
-var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
-for (var i in ifaces) {
-    for (var j in ifaces[i]) {
-        var val = ifaces[i][j]
-        if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
-            ip = val.address
-        }
-    }
-}
+// var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
+// for (var i in ifaces) {
+//     for (var j in ifaces[i]) {
+//         var val = ifaces[i][j]
+//         if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
+//             ip = val.address
+//         }
+//     }
+// }
 // 1196735749
 module.exports = {
   build: {

+ 3 - 13
fhKeeper/formulahousekeeper/timesheet/config/index.js

@@ -1,7 +1,8 @@
 var path = require('path')
 
-//  var ip = '192.168.2.12'
-var ip = '47.101.180.183'
+ var ip = '192.168.2.42'
+//  var ip = '192.168.2.49'
+// var ip = '47.101.180.183'
 // var ip = '47.100.37.243'
 // var ip = '192.168.10.2'
 // var ip = '192.168.2.11' 
@@ -60,17 +61,6 @@ module.exports = {
                 '^/api': '/' 
             }
         },
-
-
-
-        // '/ips': {    
-        //     target: 'http://'+ ip +':8080',
-        //     secure: true,
-        //     changeOrigin: true,
-        //     pathRewrite: {
-        //         '^/ips': '/' 
-        //     }
-        // },
     },
     cssSourceMap: false
   },

+ 3 - 0
fhKeeper/formulahousekeeper/timesheet/src/components/taskComponent.vue

@@ -41,6 +41,9 @@
                     </el-option>
                 </el-select>
             </el-form-item>
+            <el-form-item label="任务完成校验" v-if="user.timeType.taskFileCharge">
+                <el-checkbox v-model="addForm.attachFileRequired" >是否必须上传成果文件</el-checkbox>
+            </el-form-item>
             <el-form-item  :label="$t('taskdefinition')" prop="name">
                 <el-input v-model="addForm.name" :maxlength="40" :disabled="(this.addForm.id != null && user.id != this.addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement && !permissions.editAnyTask && !(groupResponsibleId == user.id)" :placeholder="$t('enterthetaskcontent')" clearable></el-input>
             </el-form-item>

+ 166 - 9
fhKeeper/formulahousekeeper/timesheet/src/views/leave/list.vue

@@ -103,7 +103,7 @@
     <!-- 上面部分 -->
     <div v-if="!displayTable && apk == false" class="tops" :style="'height:' +hubs+'px'">
         <!-- 公共 -->
-        <div class="ctons" style="width: 98%">
+        <div class="ctons" style="width: 98%;overflow: auto;">
             <!-- 表单 -->
             <el-form ref="addForm" :model="addForm" label-width="80px" :rules="addFormRules">
                 <!-- 请假类型 -->
@@ -170,6 +170,22 @@
                 <el-form-item :label="$t('bei-zhu')" style="width: 100%">
                     <el-input type="textarea" v-model="addForm.remark" :rows="5" style="width: 550px" maxlength="100" show-word-limit></el-input>
                 </el-form-item>
+                <el-form-item label="相关凭证" style="width: 100%">
+                  <el-upload action="#" list-type="picture-card" multiple ref="leaveApplicationFormUploadRef" :limit="5" :http-request="imageUpload" :file-list="leaveAndUploadPictures">
+                      <i slot="default" class="el-icon-plus"></i>
+                      <div slot="file" slot-scope="{file}">
+                        <img class="el-upload-list__item-thumbnail" :src="file.url" alt="">
+                        <span class="el-upload-list__item-actions">
+                          <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
+                            <i class="el-icon-zoom-in"></i>
+                          </span>
+                          <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
+                            <i class="el-icon-delete"></i>
+                          </span>
+                        </span>
+                      </div>
+                  </el-upload>
+                </el-form-item>
                 <!--请假流程显示-->
                 <el-form-item :label="$t('other.approvalProcess')" style="width: 100%;color:#606266" >
                   <span v-for="(item, index) in curWorkflowList" :key="item.id" >
@@ -195,7 +211,7 @@
     <!-- 下面部分 -->
     <div v-if="displayTable && apk == false" class="tops" :style="'height:' +hubs+'px'">
         <!-- 公共 -->
-        <div class="ctons" style="width: 98%;">
+        <div class="ctons" style="width: 98%;overflow: auto;">
           <div class="flex">
             <div>
               <el-select v-if="user.userNameNeedTranslate != 1" v-model="ownerIds" :placeholder="$t('pleaseselectthepersonaskingforleave')" clearable @change="chufas()" style="width: 120px" size="small" v-show="permissions.leaveAll" filterable="true">
@@ -292,14 +308,18 @@
                     </div>
                   </template>
                 </el-table-column>
-                <el-table-column prop="remark" :label="$t('bei-zhu')" min-width="200" header-align="center">
+                <el-table-column prop="remark" :label="$t('bei-zhu')" min-width="200">
                   <template slot-scope="scope">
-                    <!-- <div class="apls">{{scope.row.remark}}</div> -->
                     <el-popover placement="top-start"  width="200" trigger="hover" :content="scope.row.remark">
                       <div slot="reference" class="apls">{{scope.row.remark}}</div>
                     </el-popover>
                   </template>
                 </el-table-column>
+                <el-table-column label="相关凭证" min-width="200">
+                  <template slot-scope="scope">
+                    <el-button type="primary" size="mini" v-if="scope.row.fileUrlsList.length && scope.row.fileUrlsList[0].name" @click="clickToViewTheImage(scope.row.fileUrlsList)">点击查看</el-button>
+                  </template>
+                </el-table-column>
                 <el-table-column :label="$t('operation')" min-width="180" fixed="right" v-if="isAuditList && !isSyncData">
                     <template slot-scope="scope">
                       <div>
@@ -758,6 +778,22 @@
         <el-form-item :label="$t('bei-zhu')" style="width: 100%">
             <el-input type="textarea" v-model="addForm.remark" :rows="5" style="width: 62%" maxlength="100" show-word-limit></el-input>
         </el-form-item>
+        <el-form-item label="相关凭证" style="width: 100%">
+            <el-upload action="#" list-type="picture-card" multiple ref="leaveApplicationFormUploadDetailRef" :limit="5" :http-request="imageDetailUpload" :file-list="addForm.fileUrlsList">
+              <i slot="default" class="el-icon-plus"></i>
+              <div slot="file" slot-scope="{file}">
+                <img class="el-upload-list__item-thumbnail" :src="file.url" alt="">
+                <span class="el-upload-list__item-actions">
+                  <span class="el-upload-list__item-preview" @click="handlePictureCardDetailPreview(file)">
+                    <i class="el-icon-zoom-in"></i>
+                  </span>
+                  <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleDetailRemove(file)">
+                    <i class="el-icon-delete"></i>
+                  </span>
+                </span>
+              </div>
+          </el-upload>
+        </el-form-item>
     </el-form>
     <span slot="footer" class="dialog-footer">
       <el-button @click="dialog = false">{{ $t('btn.cancel') }}</el-button>
@@ -797,6 +833,13 @@
             <el-button  @click="denyReasonVisible = false" >{{ $t('btn.cancel') }}</el-button>
         </div>
     </el-dialog> -->
+
+    <!-- 文件图片显示 -->
+    <div v-show="false">
+      <viewer :images="excessiveImagesList">
+        <img ref="imgsaListRef" v-for="src in excessiveImagesList" :src="src.url">
+      </viewer>
+    </div>
   </section>
 </template>
 
@@ -811,6 +854,7 @@ import selectPersonnel from '../../components/selectPersonnel.vue';
 import vueCascader from "@/components/cascader.vue"
 
 import { getThemeColor } from '@/utils/commonMethod.js'
+import { del } from 'vue';
 export default {
   name: "expense",
   components: {
@@ -990,6 +1034,9 @@ export default {
       auditLogList:[],
       selectedAuuid: '',
       syncLeaveLoading:false,
+      relatedVouchersList: [],
+      excessiveImagesList: [],
+      leaveAndUploadPictures: []
     };
   },
   computed: {},
@@ -1022,6 +1069,85 @@ export default {
   },
   filters: {},
   methods: {
+    imageUpload(res) {
+      const row = res.file
+      const formData = new FormData();
+      formData.append('multipartFile', row);
+      this.$refs.leaveApplicationFormUploadRef.uploadFiles = [];
+      this.http.uploadFile(`/common/uploadFile`, formData, res => {
+        if (res.code == "ok") {
+          const url = res.data
+          this.leaveAndUploadPictures.push({
+            name: url,
+            url: `/upload/${url}`,
+          })
+        } else {
+            this.$message({ message: res.msg, type: "error" });
+        }
+      }, err => {
+        this.$message({ message: error, type: "error" });
+      })
+    },
+    imageDetailUpload(res) {
+      const row = res.file
+      const formData = new FormData();
+      formData.append('multipartFile', row);
+      this.$refs.leaveApplicationFormUploadDetailRef.uploadFiles = [];
+      this.http.uploadFile(`/common/uploadFile`, formData, res => {
+        if (res.code == "ok") {
+          const url = res.data
+          this.addForm.fileUrlsList.push({
+            name: url,
+            url: `/upload/${url}`,
+          })
+        } else {
+            this.$message({ message: res.msg, type: "error" });
+        }
+      }, err => {
+        this.$message({ message: error, type: "error" });
+      })
+    },
+    handlePictureCardPreview(file) {
+      const list = this.$refs.leaveApplicationFormUploadRef.uploadFiles || [];
+      const fileIndex = list.findIndex(item => item.uid === file.uid);
+      this.excessiveImagesList = list
+
+      setTimeout(() => {
+        this.$refs.imgsaListRef[fileIndex].click()
+      }, 200);
+    },
+    handlePictureCardDetailPreview(file) {
+      const list = this.$refs.leaveApplicationFormUploadDetailRef.uploadFiles || [];
+      const fileIndex = list.findIndex(item => item.uid === file.uid);
+      this.excessiveImagesList = list
+
+      setTimeout(() => {
+        this.$refs.imgsaListRef[fileIndex].click()
+      }, 200);
+    },
+    clickToViewTheImage(list) {
+      this.excessiveImagesList = list
+      setTimeout(() => {
+        this.$refs.imgsaListRef[0].click()
+      }, 200);
+    },
+    handleRemove(file) {
+      const list = this.$refs.leaveApplicationFormUploadRef.uploadFiles || [];
+      const fileIndex = list.findIndex(item => item.uid === file.uid);
+      if(list.length) {
+        console.log(list)
+        this.$refs.leaveApplicationFormUploadRef.uploadFiles.splice(fileIndex, 1);
+        this.leaveAndUploadPictures.splice(fileIndex, 1)
+      }
+    },
+    handleDetailRemove(file) {
+      const list = this.$refs.leaveApplicationFormUploadDetailRef.uploadFiles || [];
+      const fileIndex = list.findIndex(item => item.uid === file.uid);
+      if(list.length) {
+        this.$refs.leaveApplicationFormUploadDetailRef.uploadFiles.splice(fileIndex, 1);
+        this.addForm.fileUrlsList.splice(fileIndex, 1)
+      }
+    },
     showDenyReason(sheetId) {
       this.denyReasonVisible = true;
       this.auditLogList = [];
@@ -1762,6 +1888,8 @@ export default {
         this.apk2 = 9
         this.restTime()
       } 
+
+      this.leaveAndUploadPictures = []
     },
     auditList() {
       this.falg = 1
@@ -1784,7 +1912,13 @@ export default {
       this.http.post('/leave-sheet/auditList', param,
         res => {
             if (res.code == "ok") {
-              this.tableData = res.data.records
+              this.tableData = res.data.records.map(item => ({
+                ...item,
+                fileUrlsList: (item.fileUrls || '').split(',').map(em => ({
+                  name: em,
+                  url: `/upload/${em}`
+                }))
+              }));
               this.total = res.data.total
               this.loading = false
             } else {
@@ -1843,7 +1977,14 @@ export default {
       this.http.post('/leave-sheet/list', param,
         res => {
             if (res.code == "ok") {
-              this.tableData = res.data.records
+              this.tableData = res.data.records.map(item => ({
+                ...item,
+                fileUrlsList: (item.fileUrls || '').split(',').map(em => ({
+                  name: em,
+                  url: `/upload/${em}`
+                }))
+              }));
+              console.log(this.tableData)
               this.total = res.data.total
               this.loading = false
             } else {
@@ -1908,7 +2049,15 @@ export default {
           this.addForm.endDate = this.buling(this.addForm.endDate)
           this.addForm.startDate = this.buling(this.addForm.startDate)
           if (valid) {
-            this.http.post('/leave-sheet/add', this.addForm,
+            let formData = new FormData()
+            const fileList = this.leaveAndUploadPictures.map(item => item.name)
+            Object.keys(this.addForm).forEach(key => {
+              formData.append(key, this.addForm[key])
+            })
+
+            formData.append('fileUrls', fileList.join(','))
+
+            this.http.uploadFile('/leave-sheet/add', formData,
             res => {
                 if (res.code == "ok") {
                     this.$message({
@@ -1922,8 +2071,9 @@ export default {
                     this.addForm.leaveType = 0
                     this.addForm.timeHours = 8
                     this.addForm.remark = ''
-                    
                     this.flg = true
+                    this.$refs.leaveApplicationFormUploadRef.clearFiles()
+                    this.leaveAndUploadPictures = []
                 } else {
                     this.$message({
                       message: res.msg,
@@ -2250,6 +2400,7 @@ export default {
       });
     },
     editor(items) {
+      console.log(items, '<===== zhong-xin-ti-jiao')
       this.dialog = true
       this.addForm.ownerId = items.ownerId
       this.addForm.tel = items.tel
@@ -2259,11 +2410,16 @@ export default {
       this.addForm.timeDays = items.timeDays
       this.addForm.timeHours = items.timeHours
       this.addForm.remark = items.remark
+      this.addForm.fileUrlsList = items.fileUrlsList || []
       this.affId = items.id
     },
     determine () {
       var adl = this.addForm
       adl.id = this.affId
+      adl.fileUrls = this.addForm.fileUrlsList.map(item => {
+        return item.name
+      }).join(',')
+      delete adl.fileUrlsList
       this.http.post('/leave-sheet/add', adl,
           res => {
               if (res.code == "ok") {
@@ -2277,7 +2433,8 @@ export default {
                     leaveType: 0,
                     timeHours: '8',
                     tel: '',
-                    remark: ''
+                    remark: '',
+                    fileUrls: []
                   }
                   this.getUsers()
               } else {

+ 8 - 0
fhKeeper/formulahousekeeper/timesheet_h5/src/router/index.js

@@ -96,6 +96,14 @@ const router = new Router({
         },
         component: () => import("@/views/expense/details")
     },
+    {
+        path: "/customizedDetail",
+        name: "customizedDetail",
+        meta: {
+            title: "单据编辑"
+        },
+        component: () => import("@/views/expense/customizedDetail")
+    },
     {
         path: "/projectInside",
         name: "projectInside",

+ 71 - 9
fhKeeper/formulahousekeeper/timesheet_h5/src/views/exaLeave/applyLeave.vue

@@ -81,6 +81,12 @@
                 <van-field label="请假天数(天)" v-if="editForm.timeType == '0'" @blur="dayBlur()" v-model="editForm.timeDays" type="number" :rules="[{ required: true, message: '请输入请假天数' }]"></van-field>
                 <!-- 请假时长 -->
                 <van-field label="请假时长(小时)" v-else v-model="editForm.timeHours" @blur="hourBlur()" type="number" :rules="[{ required: true, message: '请输入请假时长' }]"></van-field>
+                <!-- 报销凭证 -->
+                <van-field label="相关凭证" v-if="!isCorpWX">
+                    <template #input>
+                        <van-uploader v-model="tupiansss" :after-read="uploaderAfterRead" :max-count="5" multiple :before-delete="imgDeleteFile" />
+                    </template>
+                </van-field>
                 <!-- 备注 -->
                 <van-field v-model="editForm.remark" label="备注" type="textarea" :autosize="{minHeight:100}"></van-field>
         </van-form>
@@ -111,6 +117,9 @@
                         <div><span>请假结束时间:</span><span>{{item.endDate}}</span></div>
                         <div><span>请假天数:</span><span>{{item.timeDays ? item.timeDays + '天' : '/'}}</span></div>
                         <div><span>请假时长:</span><span>{{item.timeHours ? item.timeHours + '小时' : '/'}}</span></div>
+                        <div v-if="!isCorpWX"><span>相关凭证:</span>
+                            <van-uploader v-model="item.fileUrlsList" :max-count="0" :deletable="false" />
+                        </div>
                         <div><span>备注:</span><span>{{item.remark}}</span></div>
                     </div>
                     <div class="operation" v-if="((item.status != 0 && item.ownerId == user.id) || leaveAll) && !isSyncData">
@@ -206,7 +215,8 @@ export default {
                 timeType: '0',
                 timeDays: 0,
                 timeHours: 8,
-                remark: ''
+                remark: '',
+                fileUrlsList: []
             },
             formshowText: {
                 name: '',
@@ -240,9 +250,9 @@ export default {
             denyParm: {
                 id: '',
                 denyReason: ''
-            }
-
-            
+            },
+            tupiansss: [],
+            isCorpWX: false
         }
     },
     mounted() {
@@ -271,6 +281,11 @@ export default {
                 this.active = '0'
             }
         }
+
+        var ua = navigator.userAgent.toLowerCase();
+        if (ua.indexOf("wxwork") > 0) {
+            this.isCorpWX = true;
+        }
         
         // if(!this.canExamine){
             this.editForm.ownerId = this.user.id
@@ -282,6 +297,33 @@ export default {
         // }
     },
     methods: {
+        imgDeleteFile(row, data) {
+            const { index } = data
+            this.editForm.fileUrlsList.splice(index, 1)
+            setTimeout(() => {
+                console.log(this.editForm);
+                console.log(this.tupiansss);
+            }, 2000)
+            return true
+        },
+        uploaderAfterRead(rowList) {
+            this.$toast('上传中...');
+            for(let i in rowList) {
+                const formData = new FormData()
+                formData.append('multipartFile', rowList[i].file);
+                this.$axios.post("/common/uploadFile", formData)
+                .then(res => {
+                    if(res.code == "ok") {
+                        this.editForm.fileUrlsList.push({
+                            url: `/upload/${res.data}`,
+                            name: res.data
+                        })
+                    } else {
+                        this.$toast.fail(res.msg);
+                    }
+                }).catch(err=> {console.log(err)});
+            }
+        },
         back(){
             history.back();
         },
@@ -403,9 +445,15 @@ export default {
                 if(!this.editForm.endDate) {
                     this.editForm.endDate = this.editForm.startDate
                 }
-                console.log(this.editForm, '<==== 将要提交的数据')
+                let formVal = {
+                    ...this.editForm,
+                    fileUrls: this.editForm.fileUrlsList.map(item => item.name).join(',')
+                }
+                delete formVal.fileUrlsList
                 this.submitLoading = true
-                this.$axios.post("/leave-sheet/add", this.editForm)
+                this.$axios.post("/leave-sheet/add", {
+                    ...formVal 
+                })
                 .then(res => {
                     this.submitLoading = false
                     if(res.code == "ok") {
@@ -418,8 +466,10 @@ export default {
                             timeType: '0',
                             timeDays: 0,
                             timeHours: this.user.timeType.allday,
-                            remark: ''
+                            remark: '',
+                            fileUrlsList: []
                         }
+                        this.tupiansss = []
                         this.formshowText.dateTitle = ''
                         this.$toast.success('提交成功');
                     } else {
@@ -438,8 +488,10 @@ export default {
                 timeType: '0',
                 timeDays: 0,
                 timeHours: this.user.timeType.allday,
-                remark: ''
+                remark: '',
+                fileUrlsList: []
             }
+            this.tupiansss = []
             this.formshowText.dateTitle = ''
         },
         getDingDingLeaveQt(){
@@ -497,6 +549,7 @@ export default {
         },
         submitAgain(item){
             this.editForm = item
+            this.tupiansss = item.fileUrlsList
             if(this.editForm.startDate && !this.editForm.endDate){
                 this.$set(this.editForm,'timeType','1')
             }else{
@@ -504,6 +557,7 @@ export default {
             }
             this.timeTypeChange()
             this.active = 0
+            this.editForm.fileUrls = item.fileUrlsList
         },
 // #endregion
 
@@ -578,7 +632,15 @@ export default {
             this.$axios.post("/leave-sheet/list", parameter)
             .then(res => {
                 if(res.code == "ok") {
-                    this.leaveList = res.data.records
+                    this.leaveList = res.data.records.map(item => {
+                        return {
+                            ...item,
+                            fileUrlsList: item.fileUrls ? item.fileUrls.split(',').map(em => {
+                                return { url: `/upload/${em}`, name: em}
+                            }) : []
+                        }
+                    })
+                    console.log(this.leaveList, '<===== 看看')
                 } else {
                     this.$toast.fail('获取失败:'+res.smg);
                 }

+ 10 - 10
fhKeeper/formulahousekeeper/timesheet_h5/vue.config.js

@@ -6,18 +6,18 @@ const Timestamp = new Date().getTime();
 
 // var ip = '47.101.180.183'
 // var ip = '47.100.37.243'
-// var ip = '192.168.2.8'
+var ip = '192.168.2.42'
 // var ip = '127.0.0.1'
 
-var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
-for (var i in ifaces) {
-    for (var j in ifaces[i]) {
-        var val = ifaces[i][j]
-        if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
-            ip = val.address
-        }
-    }
-}
+// var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
+// for (var i in ifaces) {
+//     for (var j in ifaces[i]) {
+//         var val = ifaces[i][j]
+//         if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
+//             ip = val.address
+//         }
+//     }
+// }
 
 module.exports = {
     runtimeCompiler: true,