Sfoglia il codice sorgente

Merge branch 'master' of http://47.100.37.243:10191/wutt/manHourHousekeeper

QuYueTing 6 mesi fa
parent
commit
05ebc9c317

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/components/common/pullDownSelector.vue

@@ -168,7 +168,7 @@ function confirmClick() {
 onBeforeUpdate(() => {
   checkboxRefs.value = [];
 });
-
+console.log(props, '<=== ')
 onMounted(() => {
   selectChecked.value = props.multipleChoice ? [] : null;
   const isItAnArray = Array.isArray(props.options);

+ 2 - 1
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/hooks/useApi.js

@@ -56,4 +56,5 @@ export const OBTAIN_ORDER_RELATED_PRODUCTS = `/order/productWithOrder` // 获取
 
 export const SELL_AND_OBTAIN_RELATED_PRODUCTS = `/product/orderWithProduct` // 销售订单关联产品
 
-export const GET_CONTACTS_WITH_MORE_I_DS = `/contacts/getAllContacts` // 更具Id获取联系人
+export const GET_CONTACTS_WITH_MORE_I_DS = `/contacts/getAllContacts` // 更具Id获取联系人
+export const CONTACT_PERSON_ASSOCIATED_WITH_BUSINESS_OPPORTUNITY = `/business-opportunity/saveContactsId` // 联系人关联商机

+ 60 - 3
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/pageComponents/business/businessInfo.vue

@@ -19,7 +19,8 @@
       <van-cell title="备注" :value="info.remark" />
     </div>
     <div class="bottomButton">
-      <van-button type="primary" class="w-full block">关联联系人</van-button>
+      <van-button type="primary" class="w-full block" v-if="!info.contactsName"
+        @click="shoContactDialag()">关联联系人</van-button>
       <van-button type="warning" class="w-full block" v-if="info.inchargerName"
         @click="showDialogCli()">转移商机</van-button>
       <van-button type="primary" class="w-full block" v-if="!info.inchargerName"
@@ -37,17 +38,30 @@
       <div class="themeTextColor text-size-small pl-4 pt-2 pb-2">转移后,将看不到此商机了</div>
     </van-dialog>
 
+    <van-dialog v-model:show="showContactDialog" :title="`关联联系人`" show-cancel-button @confirm="relatedContacts"
+      :before-close="dialogCloseBefo">
+      <van-cell title="联系人" is-link @click="showContactSelect = true">
+        <template #value>
+          {{ dialogSelection.label }}
+        </template>
+      </van-cell>
+    </van-dialog>
+
     <!-- select 选择器 -->
     <van-popup v-model:show="showSelect" destroy-on-close position="bottom" :style="{ height: '80%' }">
       <PullDownSelector @change="selectChange" />
     </van-popup>
+
+    <van-popup v-model:show="showContactSelect" destroy-on-close position="bottom" :style="{ height: '80%' }">
+      <PullDownSelector :options="allContactsList" :doYouNeedTranslation="false" @change="selectChange" />
+    </van-popup>
   </div>
 </template>
 
 <script setup>
 import { ref } from 'vue';
 import { useLifecycle } from '@hooks/useCommon.js';
-import { BUSINESS_OPPORTUNITY_TRANSFER } from '@hooks/useApi'
+import { BUSINESS_OPPORTUNITY_TRANSFER, GET_CONTACTS_WITH_MORE_I_DS, CONTACT_PERSON_ASSOCIATED_WITH_BUSINESS_OPPORTUNITY } from '@hooks/useApi'
 import requests from "@common/requests";
 import useShowToast from '@hooks/useToast'
 import useInfoStore from '@store/useInfoStore'
@@ -64,7 +78,30 @@ const props = defineProps({
 
 const showDialog = ref(false);
 const showSelect = ref(false);
+const showContactSelect = ref(false);
+const showContactDialog = ref(false)
 const dialogSelection = ref({});
+const allContactsList = ref([]);
+
+function shoContactDialag() {
+  dialogSelection.value = {}
+  showContactDialog.value = true
+}
+
+function relatedContacts() {
+  if (!dialogSelection.value.label) {
+    return toastText('请选择要关联的联系人')
+  }
+
+  requests.post(CONTACT_PERSON_ASSOCIATED_WITH_BUSINESS_OPPORTUNITY, {
+    id: props.info.id,
+    contactsId: dialogSelection.value.value
+  }).then((res) => {
+    props.info.contactsName = dialogSelection.value.label
+    showContactDialog.value = false
+    toastSuccess('关联成功')
+  })
+}
 
 function confirmTransfer() {
   if (!dialogSelection.value.label) {
@@ -98,9 +135,11 @@ function selectChange(value, label) {
     value, label
   }
   showSelect.value = false
+  showContactSelect.value = false
 }
 
 function showDialogCli() {
+  dialogSelection.value = {}
   showDialog.value = true
 }
 
@@ -112,9 +151,27 @@ function dialogCloseBefo(val) {
   return true
 }
 
+function getAllContactsList() {
+  requests.get(`${GET_CONTACTS_WITH_MORE_I_DS}?customerId=${props.info.customerId}`).then(({ data = [] }) => {
+    let list = data.map(item => {
+      return {
+        label: item.name,
+        value: item.id,
+      }
+    })
+    if (!list.length) {
+      list = [{}]
+    }
+    allContactsList.value = list
+  })
+}
+
 useLifecycle({
   load: () => {
-    // 添加加载逻辑
+    getAllContactsList()
+  },
+  init: () => {
+    getAllContactsList()
   }
 });
 </script>

+ 6 - 1
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/pageComponents/tasks/addEditor.vue

@@ -62,7 +62,7 @@
             {{ vantFormVal.contactsIdName }}
           </template>
         </van-field>
-        <van-field v-model="vantFormVal.executorId" name="executorId" label="执行人" placeholder="请选择" is-link readonly class="resetStyles"
+        <van-field v-model="vantFormVal.executorId" name="executorId" label="执行人" placeholder="请选择" is-link readonly class="resetStyles" :disabled="!vantFormVal.priority && vantFormVal.priority != 0"
           @click="showSelectionBox('executorId', allContactsList)">
           <template #input v-if="vantFormVal.executorIdName && vantFormVal.executorIdName.length > 0">
             <TranslationComponent :openId="vantFormVal.executorIdName" />
@@ -429,6 +429,11 @@ function initializeData() {
     }
   })
   formVal.value = props.formValue
+  if((taskType || taskType == 0) && taskType != 3) {
+    const filed = taskType == 0 ? 'customId' : taskType == 1 ? 'businessOpportunityId' : taskType == 2 ? 'orderId' : 'clueId'
+    const value = taskType == 0 ? customId : taskType == 1 ? businessOpportunityId : taskType == 2 ? orderId : clueId
+    getContactData(filed, value)
+  }
 }
 
 useLifecycle({

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

@@ -21,6 +21,7 @@ import org.springframework.web.multipart.MultipartFile;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -94,8 +95,21 @@ public class ExpenseSheetController {
      * 导出
      */
     @RequestMapping("/export")
-    public void getExport(HttpServletResponse response) throws Exception {
-        FileZipUtil.exportZip(response,uploadPath , "报销凭证压缩包", ".zip");
+    public void getExport(ExpenseSheet sheet,Integer sendState,Integer projectId,String startDate, String endDate,HttpServletResponse response) throws Exception {
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "查看全部报销单");
+        if (functionList.size() == 0) {
+            //普通员工只能看自己的
+            if (sheet.getStatus() == null) {
+                sheet.setOwnerId(user.getId());
+            }
+        }
+        sheet.setCompanyId(user.getCompanyId());
+        List<String> fileNames= expenseSheetService.queryExportFileZipList(sheet,projectId, startDate, endDate);
+        if (!fileNames.isEmpty()){
+            FileZipUtil.exportZip(response,uploadPath ,fileNames, "报销凭证压缩包", ".zip");
+        }else return;
     }
 
 

+ 3 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ExpenseSheetService.java

@@ -6,6 +6,7 @@ import com.management.platform.util.HttpRespMsg;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.List;
 
 /**
  * <p>
@@ -38,4 +39,6 @@ public interface ExpenseSheetService extends IService<ExpenseSheet> {
     HttpRespMsg approveSingleProject(Integer id);
 
     HttpRespMsg denySingleProject(Integer id, String denyReason);
+
+    List<String> queryExportFileZipList(ExpenseSheet sheet, Integer projectId, String startDate, String endDate);
 }

+ 116 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ExpenseSheetServiceImpl.java

@@ -1335,4 +1335,120 @@ public class ExpenseSheetServiceImpl extends ServiceImpl<ExpenseSheetMapper, Exp
         saveNotifyToApplier(sheet, user);
         return new HttpRespMsg();
     }
+
+    @Override
+    public List<String> queryExportFileZipList(ExpenseSheet sheet, Integer projectId, String startDate, String endDate) {
+        QueryWrapper<ExpenseSheet> queryWrapper = new QueryWrapper<ExpenseSheet>();
+        //当前用户
+        String token = request.getHeader("TOKEN");
+        queryWrapper.eq("company_id", sheet.getCompanyId()).orderByDesc("id");
+        ExpenseAuditSetting expenseAuditSetting = expenseAuditSettingMapper.selectById(sheet.getCompanyId());
+        ArrayList<String> fileNameList = new ArrayList<>();
+        if (!StringUtils.isEmpty(sheet.getCode())) {
+            queryWrapper.eq("code", sheet.getCode());
+        }
+        //增加状态
+        if (sheet.getStatus() != null) {
+            queryWrapper.eq("status", sheet.getStatus());
+        }
+        if(sheet.getSendState()!=null){
+            queryWrapper.eq("send_state",sheet.getSendState());
+        }
+
+        if (expenseAuditSetting == null || expenseAuditSetting.getAuditType() == 0) {
+            if (sheet.getStatus() != null &&  sheet.getStatus() == 1) {
+                //待审核列表,检查是否有权限
+                User user = userMapper.selectById(token);
+                List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "费用审核");
+                if (functionList.size() == 0) {
+                    //无权查看待审核
+                    queryWrapper.eq("id", -1);
+                }
+            } else {
+                if (!StringUtils.isEmpty(sheet.getOwnerId())) {
+                    queryWrapper.eq("owner_id", sheet.getOwnerId());
+                }
+            }
+        } else if(expenseAuditSetting.getAuditType() == 1){
+            //增加按项目经理审核模式下,项目经理可以查看相关费用报销单的条件
+            if (sheet.getStatus() != null) {
+                //取待审核的
+                //项目经理审核模式下,只能查看自己项目的费用报销单
+                List<Integer> projectIds = projectMapper.selectList(new QueryWrapper<Project>().eq("incharger_id", token)).stream().map(Project::getId).collect(Collectors.toList());
+                System.out.println("项目经理的项目id"+projectIds);
+                if (projectIds.size() > 0) {
+                    List<Integer> expenseIds = expenseItemMapper.selectList(new QueryWrapper<ExpenseItem>().in("project_id", projectIds)).stream().map(ExpenseItem::getExpenseId).distinct().collect(Collectors.toList());
+                    System.out.println("项目经理的项目的费用报销单id"+expenseIds);
+                    queryWrapper.in("id", expenseIds);
+                } else {
+                    //没有项目的项目经理,不显示任何数据
+                    queryWrapper.eq("id", -1);
+                }
+                //按选择的人员过滤
+                if (!StringUtils.isEmpty(sheet.getOwnerId())) {
+                    queryWrapper.eq("owner_id", sheet.getOwnerId());
+                }
+            } else {
+                //按人员过滤
+                if (!StringUtils.isEmpty(sheet.getOwnerId())) {
+                    queryWrapper.eq("owner_id", sheet.getOwnerId());
+                }
+            }
+        }else if(expenseAuditSetting.getAuditType() == 2){
+            if (sheet.getStatus() != null) {
+                //增加多层审核人审核模式 过滤第一或者第二审核人为当前用户的数据
+                queryWrapper.and(wrapper->wrapper.and(wr->wr.eq("first_checker_id",token).eq("review_process",0)).or(wr->wr.eq("second_checker_id",token).eq("review_process",1)));
+                if (!StringUtils.isEmpty(sheet.getOwnerId())) {
+                    queryWrapper.eq("owner_id", sheet.getOwnerId());
+                }
+            }else {
+                //按人员过滤
+                if (!StringUtils.isEmpty(sheet.getOwnerId())) {
+                    queryWrapper.eq("owner_id", sheet.getOwnerId());
+                }
+            }
+        }
+
+        if (!StringUtils.isEmpty(sheet.getType())) {
+            queryWrapper.eq("type", sheet.getType());
+        }
+        if (!StringUtils.isEmpty(startDate) && !StringUtils.isEmpty(endDate)) {
+            queryWrapper.between("create_date", startDate, endDate);
+        }
+        if (projectId!=null){
+            QueryWrapper<ExpenseItem> q = new QueryWrapper<ExpenseItem>();
+            q.eq("project_id",projectId);
+            List<ExpenseItem> expenseItems = expenseItemMapper.selectList(q);
+            if (expenseItems.size()==0){
+                return new ArrayList<String>();
+            }else {
+                List<Integer> expenseIds = expenseItems.stream().map(ExpenseItem::getExpenseId).collect(Collectors.toList());
+                queryWrapper.in("id",expenseIds);
+                return getStrings(queryWrapper);
+            }
+        }else {
+            return getStrings(queryWrapper);
+        }
+    }
+
+    private ArrayList<String> getStrings(QueryWrapper<ExpenseSheet> queryWrapper) {
+        List<ExpenseSheet> records= expenseSheetMapper.selectList(queryWrapper);
+        ArrayList<String> fileNames = new ArrayList<>();
+        if (!records.isEmpty()){
+            List<Integer> sheetIdList = records.stream().map(ExpenseSheet::getId).distinct().collect(Collectors.toList());
+            if (!sheetIdList.isEmpty()){
+                QueryWrapper<ExpenseItem> itemQueryWrapper = new QueryWrapper<ExpenseItem>().in("expense_id", sheetIdList);
+                List<ExpenseItem> items = expenseItemMapper.selectList(itemQueryWrapper);
+                if (!items.isEmpty()){
+                    for (ExpenseItem item : items) {
+                        if (org.apache.commons.lang3.StringUtils.isNotEmpty(item.getPic())){
+                            String[] picNames = item.getPic().split(",");
+                            fileNames.addAll(Arrays.asList(picNames));
+                        }
+                    }
+                }
+            }
+        }
+        return fileNames;
+    }
 }

+ 36 - 25
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/FileZipUtil.java

@@ -8,7 +8,9 @@ import javax.servlet.http.HttpServletResponse;
 import java.io.*;
 import java.net.URLEncoder;
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
@@ -21,7 +23,7 @@ public class FileZipUtil {
      * @param fileName 下载时的文件名称
      * @param postfix 下载时的文件后缀 .zip/.rar
      */
-    public static void exportZip(HttpServletResponse response, String sourceFilePath, String fileName, String postfix) {
+    public static void exportZip(HttpServletResponse response, String sourceFilePath, List<String> fileNames, String fileName, String postfix) {
         // 默认文件名以时间戳作为前缀
         if(StringUtils.isBlank(fileName)){
             SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
@@ -32,7 +34,7 @@ public class FileZipUtil {
         try {
             OutputStream os = response.getOutputStream();
             // 接收压缩包字节
-            byte[] data = createZip(sourceFilePath);
+            byte[] data = createZip(sourceFilePath,fileNames);
             response.reset();
             response.setCharacterEncoding("UTF-8");
             response.addHeader("Access-Control-Allow-Origin", "*");
@@ -56,12 +58,12 @@ public class FileZipUtil {
      * @return byte[]
      * @throws Exception
      */
-    private static byte[] createZip(String sourceFilePath) throws Exception{
+    private static byte[] createZip(String sourceFilePath,List<String> fileNames) throws Exception{
         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         ZipOutputStream zip = new ZipOutputStream(outputStream);
         // 将目标文件打包成zip导出
         File file = new File(sourceFilePath);
-        handlerFile(zip, file,"");
+        handlerFile(zip, file,"",fileNames);
         // 无异常关闭流,它将无条件的关闭一个可被关闭的对象而不抛出任何异常。
         IOUtils.closeQuietly(zip);
         return outputStream.toByteArray();
@@ -74,32 +76,41 @@ public class FileZipUtil {
      * @param dir
      * @throws Exception
      */
-    private static void handlerFile(ZipOutputStream zip, File file, String dir) throws Exception {
-        // 如果当前的是文件夹,则循环里面的内容继续处理
-        if (file.isDirectory()) {
-            //得到文件列表信息
-            File[] fileArray = file.listFiles();
-            if (fileArray == null) {
-                return;
+    private static void handlerFile(ZipOutputStream zip, File file, String dir,List<String> fileNames) throws Exception {
+        // 得到文件列表信息
+        File[] fileArray = file.listFiles();
+
+        if (fileArray == null) {
+            extracted(zip, file, dir);
+        } else {
+            // 过滤出与 fileNames 匹配的文件
+            for (File f : fileArray) {
+                if (fileNames.contains(f.getName())) { // 使用 contains 方法检查
+                    extracted(zip, f, dir + f.getName()); // 打包处理匹配的文件
+                } else if (f.isDirectory()) {
+                    // 递归处理子目录
+                    handlerFile(zip, f, dir + f.getName() + "/", fileNames);
+                }
             }
-            //将文件夹添加到下一级打包目录
+        }
+
+            /*//将文件夹添加到下一级打包目录
             zip.putNextEntry(new ZipEntry(dir + "/"));
             dir = dir.length() == 0 ? "" : dir + "/";
             // 递归将文件夹中的文件打包
             for (File f : fileArray) {
-                handlerFile(zip, f, dir + f.getName());
-            }
-        } else {
-            // 如果当前的是文件,打包处理
-            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
-            ZipEntry entry = new ZipEntry(dir);
-            zip.putNextEntry(entry);
-            zip.write(FileUtils.readFileToByteArray(file));
-            IOUtils.closeQuietly(bis);
-            zip.flush();
-            zip.closeEntry();
-        }
-    }
+                handlerFile(zip, f, dir + f.getName(),fileNames);
+            }*/
 
+    }
 
+    private static void extracted(ZipOutputStream zip, File file, String dir) throws IOException {
+        // 如果当前的是文件,打包处理
+        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
+        ZipEntry entry = new ZipEntry(dir); // 使用完整路径(包含文件名)
+        zip.putNextEntry(entry);
+        zip.write(FileUtils.readFileToByteArray(file));
+        IOUtils.closeQuietly(bis);
+        zip.closeEntry(); // 关闭当前条目
+    }
 }