diff --git a/admin/src/api/cmcust.js b/admin/src/api/cmcust.js index 7d996f4..f6bc494 100644 --- a/admin/src/api/cmcust.js +++ b/admin/src/api/cmcust.js @@ -26,6 +26,18 @@ export function cmcustUpdateApi(data) { }) } +/** + * cmcust更新 + * @param pram + */ +export function cmcustUpdateApiByFiles(data) { + return request({ + url: `autogencode/cmcust/updateByFiles`, + method: 'POST', + data + }) +} + /** * cmcust详情 * @param pram diff --git a/admin/src/api/cmcustitem.js b/admin/src/api/cmcustitem.js new file mode 100644 index 0000000..f1d3c94 --- /dev/null +++ b/admin/src/api/cmcustitem.js @@ -0,0 +1,63 @@ + +import request from '@/utils/request' + +/** + * 新增cmcustitem + * @param pram + */ +export function cmcustitemCreateApi(data) { + return request({ + url: `autogencode/cmcustitem/save`, + method: 'POST', + data + }) +} + +/** + * cmcustitem更新 + * @param pram + */ +export function cmcustitemUpdateApi(data) { + return request({ + url: `autogencode/cmcustitem/update`, + method: 'POST', + data + }) +} + +/** + * cmcustitem详情 + * @param pram + */ +export function cmcustitemDetailApi(id) { + return request({ + url: `autogencode/cmcustitem/info/${id}`, + method: 'GET' + }) +} + +/** + * cmcustitem批量删除 + * @param ids + */ +export function cmcustitemDeleteApi(ids) { + return request({ + url: `autogencode/cmcustitem/delete`, + method: 'POST', + data: ids + }) +} + + +/** + * cmcustitem列表 + * @param pram + */ +export function cmcustitemListApi(params) { + return request({ + url: `autogencode/cmcustitem/list`, + method: 'GET', + params + }) +} + diff --git a/admin/src/components/FileUploadVO/index.vue b/admin/src/components/FileUploadVO/index.vue index d99ef06..df3480f 100644 --- a/admin/src/components/FileUploadVO/index.vue +++ b/admin/src/components/FileUploadVO/index.vue @@ -50,13 +50,13 @@
- - {{ getFileName(file.oldName) }} - -
- 删除 -
+ + {{ getFileName(file.oldName) }} + +
+ 删除
+
@@ -117,18 +117,28 @@ export default { watch: { value: { handler(val) { + console.log('===== Watch value 触发 ====='); + console.log('原始 value:', val); if (val) { let temp = 1; const list = Array.isArray(val) ? val : [val]; - this.fileList = list.map(function (item) { - // 确保对象包含 oldName 和 attachFileUrl 属性 - item.oldName = item.oldName || '未知文件名'; - item.attachFileUrl = item.attachFileUrl || ''; - item.uid = item.uid || new Date().getTime() + temp++; - return item; + console.log('转换后的文件列表:', list); + // 深拷贝原始值,避免直接修改引用对象 + this.fileList = list.map(function (item, index) { + console.log(`处理文件项 ${index} 前:`, item); + // 创建新对象而不是直接修改原对象 + const newItem = JSON.parse(JSON.stringify(item)); + // 确保对象包含必要属性 + newItem.oldName = newItem.oldName || '未知文件名'; + newItem.attachFileUrl = newItem.attachFileUrl || ''; + + console.log(`处理文件项 ${index} 后:`, newItem); + return newItem; }); + console.log('最终 fileList:', this.fileList); } else { this.fileList = []; + console.log('值为空,清空fileList'); } }, deep: true, @@ -217,19 +227,31 @@ export default { }) var _this = this; - console.log(this.baseUrl); fileFileApi(formData, data).then(function (res) { loading.close() // 直接处理返回的文件信息,不再检查code字段 - // 从返回的响应中提取所需信息 + // 从返回的响应中提取所需信息,按照SystemAttachment格式构建 const fileInfo = res || {}; const newFile = { - id: fileInfo.id || '', + // SystemAttachment需要的字段 + // 确保attId和fileId是独立的字段,不会相互覆盖 + attId: fileInfo.attId || fileInfo.id || '', // 优先使用attId,fallback到id + fileId: fileInfo.fileId || fileInfo.id || '', // 优先使用fileId,fallback到id + // 记录详细信息用于调试 + debugInfo: { + originalFileInfo: JSON.parse(JSON.stringify(fileInfo)), + timestamp: new Date().toISOString() + }, + name: fileInfo.fileName || param.file.name, // 附件名称 + attDir: fileInfo.url || fileInfo.path || '', // 附件路径 + // 兼容原有字段名称,保持组件功能正常 oldName: fileInfo.fileName || param.file.name, - attachFileUrl: fileInfo.url || fileInfo.path || '', + attachFileUrl: fileInfo.url || fileInfo.path || '', remark: _this.uploadParame.remark || '', - uid: param.file.uid + // 额外添加SystemAttachment需要的字段 + attSize: param.file.size ? param.file.size.toString() : '', // 附件大小 + attType: param.file.name ? param.file.name.split('.').pop().toLowerCase() : '' // 附件类型 }; _this.uploadList.push(newFile); _this.uploadedSuccessfully(); @@ -239,21 +261,6 @@ export default { _this.$message.error('上传失败,请重试') }) }, - // 原有的成功回调方法保留但适配新的返回格式 - handleUploadSuccess(res, file) { - // 此方法可能不再需要,但保留以防万一 - if (res && res.code === 200) { - const newFile = { - id: res.id || '', - oldName: file.name, - attachFileUrl: res.url || '', - remark: this.uploadParame.remark || '', - uid: file.uid - }; - this.uploadList.push(newFile); - this.uploadedSuccessfully(); - } - }, handleRemove(file) { this.fileList = this.fileList.filter(function (item) { return item !== file; @@ -268,7 +275,11 @@ export default { // 上传结束处理 uploadedSuccessfully() { if (this.number > 0 && this.uploadList.length === this.number) { - this.fileList = this.fileList.concat(this.uploadList); + // 使用深拷贝确保不会修改原有文件对象的属性 + const updatedFileList = JSON.parse(JSON.stringify(this.fileList)); + // 将新上传的文件添加到列表中 + updatedFileList.push(...this.uploadList); + this.fileList = updatedFileList; this.uploadList = []; this.number = 0; this.$emit("input", this.fileList); @@ -285,16 +296,23 @@ export default { }, // 获取完整的文件URL getFullFileUrl(url) { - if (!url) return ''; - // 判断URL是否已经是完整的HTTP链接 - if (url.startsWith('http://') || url.startsWith('https://')) { - return url; + if (!url) return '#'; // 返回#避免无效链接跳转 + // 标准化路径处理 + let path = url; + if (!path.startsWith('/')) { + path = '/' + path; } - // 如果不是完整链接,则拼接baseUrl - // 避免重复添加斜杠 - const base = this.baseUrl.endsWith('/') ? this.baseUrl.slice(0, -1) : this.baseUrl; - const path = url.startsWith('/') ? url : '/' + url; - return base + path; + + // 确保baseUrl正确设置 + const base = this.baseUrl && this.baseUrl.trim() !== '' ? + (this.baseUrl.endsWith('/') ? this.baseUrl.slice(0, -1) : this.baseUrl) : + ''; + + // 构建最终URL + const fullUrl = base ? (base + path) : path; + console.log('构建的完整URL:', fullUrl); + + return fullUrl; }, // 对象转成指定字符串分隔 listToString(list, separator) { @@ -304,76 +322,6 @@ export default { strs += list[i].attachFileUrl + separator; } return strs !== '' ? strs.substr(0, strs.length - 1) : ''; - }, - // 处理文件下载 - handleFileDownload(file) { - // 显示加载状态 - this.$modal.loading("下载文件中,请稍候..."); - - // 获取token - const token = getToken(); - if (!token) { - this.$modal.closeLoading(); - this.$modal.msgError("未获取到登录凭证,请重新登录"); - return; - } - - // 创建XMLHttpRequest对象 - const xhr = new XMLHttpRequest(); - const fileUrl = this.getFullFileUrl(file.attachFileUrl); - - xhr.open('GET', fileUrl, true); - // 设置响应类型为blob - xhr.responseType = 'blob'; - // 设置请求头,携带token - xhr.setRequestHeader('X-Token', token); - - // 监听请求状态变化 - xhr.onreadystatechange = () => { - if (xhr.readyState === 4) { - this.$modal.closeLoading(); - - if (xhr.status === 200) { - // 创建下载链接 - const url = window.URL.createObjectURL(new Blob([xhr.response])); - const link = document.createElement('a'); - link.style.display = 'none'; - link.href = url; - // 设置文件名 - link.setAttribute('download', file.oldName || `file_${Date.now()}`); - document.body.appendChild(link); - link.click(); - - // 清理 - setTimeout(() => { - document.body.removeChild(link); - window.URL.revokeObjectURL(url); - }, 100); - } else { - // 错误处理 - let errorMsg = `文件下载失败,状态码: ${xhr.status}`; - try { - // 尝试解析错误响应 - const errorData = JSON.parse(xhr.responseText); - if (errorData.message) { - errorMsg = errorData.message; - } - } catch (e) { - // 非JSON响应 - } - this.$modal.msgError(errorMsg); - } - } - }; - - // 网络错误处理 - xhr.onerror = () => { - this.$modal.closeLoading(); - this.$modal.msgError("网络错误,文件下载失败"); - }; - - // 发送请求 - xhr.send(); } } }; diff --git a/admin/src/views/cm/cust/qualify/file/cmcustqualifyfile-add-and-update.vue b/admin/src/views/cm/cust/qualify/file/cmcustqualifyfile-add-and-update.vue index 465c9a8..9aa168f 100644 --- a/admin/src/views/cm/cust/qualify/file/cmcustqualifyfile-add-and-update.vue +++ b/admin/src/views/cm/cust/qualify/file/cmcustqualifyfile-add-and-update.vue @@ -1,162 +1,543 @@ + + diff --git a/admin/src/views/cm/cust/qualify/file/cmcustqualifyfile-detail.vue b/admin/src/views/cm/cust/qualify/file/cmcustqualifyfile-detail.vue new file mode 100644 index 0000000..1da4d4a --- /dev/null +++ b/admin/src/views/cm/cust/qualify/file/cmcustqualifyfile-detail.vue @@ -0,0 +1,366 @@ + + + + + diff --git a/admin/src/views/cm/cust/qualify/file/index.vue b/admin/src/views/cm/cust/qualify/file/index.vue index f90173a..f7efc4e 100644 --- a/admin/src/views/cm/cust/qualify/file/index.vue +++ b/admin/src/views/cm/cust/qualify/file/index.vue @@ -1,23 +1,32 @@ diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/config/JacksonConfig.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/config/JacksonConfig.java index b67e03a..d4439a7 100644 --- a/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/config/JacksonConfig.java +++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/config/JacksonConfig.java @@ -1,9 +1,12 @@ package com.zbkj.admin.config; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import java.math.BigDecimal; diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/config/WebConfig.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/config/WebConfig.java index a71594d..2e46c32 100644 --- a/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/config/WebConfig.java +++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/config/WebConfig.java @@ -92,11 +92,14 @@ public class WebConfig implements WebMvcConfigurer { /** 本地文件上传路径 */ registry.addResourceHandler(Constants.UPLOAD_TYPE_IMAGE + "/**") .addResourceLocations("file:" + crmebConfig.getImagePath() + "/" + Constants.UPLOAD_TYPE_IMAGE + "/"); - } + registry.addResourceHandler("/file/public/**") + .addResourceLocations("file:" + crmebConfig.getImagePath() + "file/public/"); + + } + @Bean public FilterRegistrationBean filterRegister() { - //注册过滤器 FilterRegistrationBean registration = new FilterRegistrationBean(responseFilter()); // 仅仅api前缀的请求才会拦截 registration.addUrlPatterns("/api/admin/*"); diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/config/WebSecurityConfig.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/config/WebSecurityConfig.java index 73912e8..2ea7106 100644 --- a/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/config/WebSecurityConfig.java +++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/config/WebSecurityConfig.java @@ -141,6 +141,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { .antMatchers("/captcha/get", "/captcha/check").anonymous() .antMatchers("/api/admin/payment/callback/**").anonymous() .antMatchers("/api/public/**").anonymous() + // 放行公共文件访问 + .antMatchers("/file/public/**").anonymous() // 除上面外的所有请求全部需要鉴权认证 .anyRequest().authenticated() .and() diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/controller/CmCustController.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/controller/CmCustController.java index ac62b93..71b2c54 100644 --- a/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/controller/CmCustController.java +++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/controller/CmCustController.java @@ -1,13 +1,20 @@ package com.zbkj.modules.autogencode.controller; -import java.util.Arrays; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zbkj.common.request.PageParamRequest; import com.zbkj.common.response.CommonResult; import com.zbkj.common.page.CommonPage; +import com.zbkj.modules.autogencode.entity.CmCustItem; +import com.zbkj.modules.autogencode.entity.CmCustQualify; +import com.zbkj.modules.autogencode.entity.CmCustQualifyFile; +import com.zbkj.modules.autogencode.service.CmCustItemService; +import com.zbkj.modules.autogencode.service.CmCustQualifyService; +import com.zbkj.modules.autogencode.service.CmCustQualifyFileService; +import com.zbkj.service.service.SystemAttachmentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -15,13 +22,9 @@ import io.swagger.annotations.ApiOperation; import org.springframework.security.access.prepost.PreAuthorize; - - -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zbkj.modules.autogencode.entity.CmCust; import com.zbkj.modules.autogencode.service.CmCustService; - - +import com.zbkj.common.model.system.SystemAttachment; /** @@ -33,6 +36,17 @@ public class CmCustController { @Autowired private CmCustService cmCustService; + @Autowired + private CmCustQualifyService cmCustQualifyService; + + @Autowired + private CmCustQualifyFileService cmCustQualifyFileService; + + @Autowired + private SystemAttachmentService systemAttachmentService; + + @Autowired + private CmCustItemService cmCustItemService; /** @@ -43,101 +57,185 @@ public class CmCustController { if (request == null) { return; } - + // 根据实体类字段自动生成查询条件 - + // 主键 if (request.getId() != null) { queryWrapper.eq(CmCust::getId, request.getId()); } - + // 客户代码 if (StrUtil.isNotBlank(request.getCustCode())) { queryWrapper.eq(CmCust::getCustCode, request.getCustCode()); } - + // 客户名称 if (StrUtil.isNotBlank(request.getCustName())) { queryWrapper.eq(CmCust::getCustName, request.getCustName()); } - + // 营业执照号码 if (StrUtil.isNotBlank(request.getLicenseNumber())) { queryWrapper.eq(CmCust::getLicenseNumber, request.getLicenseNumber()); } - + // 联系方式 if (StrUtil.isNotBlank(request.getContactWay())) { queryWrapper.eq(CmCust::getContactWay, request.getContactWay()); } - + // 状态 if (StrUtil.isNotBlank(request.getStatus())) { queryWrapper.eq(CmCust::getStatus, request.getStatus()); } - + // 联系人 if (StrUtil.isNotBlank(request.getContactPerson())) { queryWrapper.eq(CmCust::getContactPerson, request.getContactPerson()); } - + // 备注 if (StrUtil.isNotBlank(request.getRemark())) { queryWrapper.eq(CmCust::getRemark, request.getRemark()); } - + // 删除标志(0代表存在 2代表删除) if (StrUtil.isNotBlank(request.getDelFlag())) { queryWrapper.eq(CmCust::getDelFlag, request.getDelFlag()); } - + // 创建部门 if (request.getCreateDept() != null) { queryWrapper.eq(CmCust::getCreateDept, request.getCreateDept()); } - + // 创建人 if (request.getCreateBy() != null) { queryWrapper.eq(CmCust::getCreateBy, request.getCreateBy()); } - + // 创建时间 if (request.getCreateTime() != null) { queryWrapper.eq(CmCust::getCreateTime, request.getCreateTime()); } - + // 修改人 if (request.getUpdateBy() != null) { queryWrapper.eq(CmCust::getUpdateBy, request.getUpdateBy()); } - + // 修改时间 if (request.getUpdateTime() != null) { queryWrapper.eq(CmCust::getUpdateTime, request.getUpdateTime()); } - + // if (StrUtil.isNotBlank(request.getTenantId())) { queryWrapper.eq(CmCust::getTenantId, request.getTenantId()); } - + } /** * 分页显示客户信息 - * @param request 搜索条件 + * + * @param request 搜索条件 * @param pageParamRequest 分页参数 */ @ApiOperation(value = "分页列表") @RequestMapping(value = "/list", method = RequestMethod.GET) - public CommonResult> getList(@Validated CmCust request, @Validated PageParamRequest pageParamRequest) { + public CommonResult> getList(@Validated CmCust request, @Validated PageParamRequest pageParamRequest) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); - + // 应用搜索条件 condition(queryWrapper, request); - + CommonPage page = CommonPage.restPage(cmCustService.pageList(queryWrapper, pageParamRequest)); + + // 优化版:批量查询数据,减少数据库交互 + List supplierList = page.getList(); + if (supplierList.isEmpty()) { + return CommonResult.success(page); + } + + // 1. 提取所有供应商ID + List supplierIds = supplierList.stream().map(CmCust::getId).collect(Collectors.toList()); + + // 2. 批量查询所有供应商对应的供应商类别,构建custId到supplierItem的映射 + Map supplierItemMap = new HashMap<>(); + List allSupplierItems = cmCustItemService.list(new LambdaQueryWrapper() + .in(CmCustItem::getCustId, supplierIds)); + for (CmCustItem item : allSupplierItems) { + supplierItemMap.put(item.getCustId(), item); + } + + // 3. 收集所有需要的itemCode,批量查询对应的资质类型 + Set itemCodes = new HashSet<>(); + for (CmCustItem item : allSupplierItems) { + if (StrUtil.isNotBlank(item.getItemCode())) { + itemCodes.add(item.getItemCode()); + } + } + + // 构建itemCode到qualifies列表的映射 + Map> qualifyMap = new HashMap<>(); + if (!itemCodes.isEmpty()) { + List allQualifies = cmCustQualifyService.list(new LambdaQueryWrapper() + .in(CmCustQualify::getQualifyType, itemCodes)); + + for (CmCustQualify qualify : allQualifies) { + qualifyMap.computeIfAbsent(qualify.getQualifyType(), k -> new ArrayList<>()).add(qualify); + } + } + + // 4. 批量查询所有供应商已通过审核的资质文件 + Map> passedFilesMap = new HashMap<>(); + List allPassedFiles = cmCustQualifyFileService.list(new LambdaQueryWrapper() + .in(CmCustQualifyFile::getCustId, supplierIds) + .eq(CmCustQualifyFile::getStatus, 2)); + + for (CmCustQualifyFile file : allPassedFiles) { + passedFilesMap.computeIfAbsent(file.getCustId(), k -> new ArrayList<>()).add(file); + } + + // 5. 遍历供应商列表,使用映射数据设置资质状态 + for (CmCust supplier : supplierList) { + // 默认资质状态:0为资质不完整 + String qualifyStatus = "0"; + + // 获取供应商对应的类别 + CmCustItem supplierItem = supplierItemMap.get(supplier.getId()); + + if (supplierItem != null && StrUtil.isNotBlank(supplierItem.getItemCode())) { + // 获取该类别需要的资质列表 + List requiredQualifies = qualifyMap.getOrDefault(supplierItem.getItemCode(), Collections.emptyList()); + int requiredCount = requiredQualifies.size(); + + if (requiredCount > 0) { + // 获取该供应商已通过的资质文件 + List passedFiles = passedFilesMap.getOrDefault(supplier.getId(), Collections.emptyList()); + + // 统计已通过的不同资质类型数量 + Set passedQualifyIds = new HashSet<>(); + for (CmCustQualifyFile file : passedFiles) { + if (file.getQualifyId() != null) { + passedQualifyIds.add(file.getQualifyId()); + } + } + + // 判断资质状态:只有当所有必需的资质类型都有通过审核的文件时,才为1(资质完整) + if (passedQualifyIds.size() == requiredCount) { + qualifyStatus = "1"; + } + } + } + + // 直接设置资质状态到实体类的虚拟字段中 + supplier.setQualifyStatus(qualifyStatus); + } + return CommonResult.success(page); } @@ -146,8 +244,105 @@ public class CmCustController { * 详情数据 */ @RequestMapping(value = "/info/{id}", method = RequestMethod.GET) - public CommonResult info(@PathVariable("id") Long id){ - CmCust cmCust = cmCustService.getById(id); + public CommonResult info(@PathVariable("id") Long id) { + // 参数验证 + if (id == null) { + return CommonResult.failed("ID不能为空"); + } + + CmCust cmCust = cmCustService.getById(id); + + if (cmCust != null) { + // 1. 查询该供应商相关的所有资质类型 + List cmCustItems = cmCustItemService.list(new LambdaQueryWrapper() + .eq(CmCustItem::getCustId, cmCust.getId())); + + List itemCodeList = Optional.ofNullable(cmCustItems) + .orElse(Collections.emptyList()) // 集合为 null 时返回空集合 + .stream() + .filter(Objects::nonNull) // 过滤 null 的 CmCustItem 元素 + .map(CmCustItem::getItemCode) // 提取 itemCode + .filter(StrUtil::isNotBlank) // 过滤 null 或空的 itemCode + .collect(Collectors.toList()); + + // 只有当itemCodeList非空时才执行后续查询和处理 + if (!itemCodeList.isEmpty()) { + // 构建资质查询条件 + LambdaQueryWrapper qualifyQuery = new LambdaQueryWrapper() + .eq(CmCustQualify::getDelFlag, "0") + .in(CmCustQualify::getQualifyType, itemCodeList); + + List qualifyList = cmCustQualifyService.list(qualifyQuery); + + if (!qualifyList.isEmpty()) { + // 提取所有资质ID + List qualifyIds = qualifyList.stream() + .filter(Objects::nonNull) + .map(CmCustQualify::getId) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + // 2. 批量查询该供应商的所有资质文件 + LambdaQueryWrapper fileQuery = new LambdaQueryWrapper() + .eq(CmCustQualifyFile::getCustId, id) + .eq(CmCustQualifyFile::getDelFlag, "0"); + + // 只有当qualifyIds非空时才添加in条件 + if (!qualifyIds.isEmpty()) { + fileQuery.in(CmCustQualifyFile::getQualifyId, qualifyIds); + } + + List fileList = cmCustQualifyFileService.list(fileQuery); + + if (!fileList.isEmpty()) { + // 提取所有文件ID并转换为String类型 + List fileIds = fileList.stream() + .filter(Objects::nonNull) + .filter(file -> file.getFileId() != null) + .map(file -> file.getFileId().toString()) + .collect(Collectors.toList()); + + // 3. 批量查询所有系统附件,先检查fileIds是否为空 + List attachments = new ArrayList<>(); + if (!fileIds.isEmpty()) { + attachments = systemAttachmentService.list(new LambdaQueryWrapper() + .in(SystemAttachment::getFileId, fileIds)); + } + + // 构建文件ID到附件列表的映射 + Map> fileToAttachmentMap = attachments.stream() + .filter(Objects::nonNull) + .collect(Collectors.groupingBy(SystemAttachment::getFileId)); + + // 为每个资质文件设置附件列表 + for (CmCustQualifyFile file : fileList) { + if (file != null && file.getFileId() != null) { + file.setFiles(fileToAttachmentMap.getOrDefault(file.getFileId().toString(), Collections.emptyList())); + } + } + } + + // 构建资质ID到文件列表的映射 + Map> qualifyToFileMap = fileList.stream() + .filter(Objects::nonNull) + .filter(file -> file.getQualifyId() != null) + .collect(Collectors.groupingBy(CmCustQualifyFile::getQualifyId)); + + // 为每个资质设置文件列表 + for (CmCustQualify qualify : qualifyList) { + if (qualify != null && qualify.getId() != null) { + qualify.setCmCustQualifyFileList(qualifyToFileMap.getOrDefault(qualify.getId(), Collections.emptyList())); + } + } + } + + // 设置供应商的资质列表 + cmCust.setCmCustQualifyList(qualifyList); + } else { + // 如果没有资质类型,设置空列表避免空指针 + cmCust.setCmCustQualifyList(Collections.emptyList()); + } + } return CommonResult.success(cmCust); } @@ -156,7 +351,7 @@ public class CmCustController { * 新增数据 */ @RequestMapping(value = "/save", method = RequestMethod.POST) - public CommonResult save(@RequestBody CmCust cmCust){ + public CommonResult save(@RequestBody CmCust cmCust) { if (cmCustService.save(cmCust)) { return CommonResult.success(); } @@ -167,22 +362,72 @@ public class CmCustController { * 修改数据 */ @RequestMapping(value = "/update", method = RequestMethod.POST) - public CommonResult update(@RequestBody CmCust cmCust){ + public CommonResult update(@RequestBody CmCust cmCust) { if (cmCustService.updateById(cmCust)) { return CommonResult.success(); } return CommonResult.failed(); } + + /** + * 修改数据 + */ + @RequestMapping(value = "/updateByFiles", method = RequestMethod.POST) + public CommonResult updateByFiles(@RequestBody CmCust cmCust) { + List cmCustQualifyList = cmCust.getCmCustQualifyList(); + if (null != cmCustQualifyList && cmCustQualifyList.size() > 0) { + for (CmCustQualify cmQualify : cmCustQualifyList) { + List cmCustQualifyFileList = cmQualify.getCmCustQualifyFileList(); + + for (CmCustQualifyFile cmCustQualifyFile : cmCustQualifyFileList) { + if (null == cmCustQualifyFile.getId()) { + cmCustQualifyFile.setCustId(cmCust.getId()); + cmCustQualifyFile.setQualifyId(cmQualify.getId()); + cmCustQualifyFile.setQualifyName(cmQualify.getQualifyName()); + cmCustQualifyFileService.save(cmCustQualifyFile); + } + if (null != cmCustQualifyFile) { + updateFile(cmCustQualifyFile); + } + } + + } + } + return CommonResult.success(); + } + + private void updateFile(CmCustQualifyFile cmCustQualifyFile) { + Long newId = System.currentTimeMillis() + new Random().nextInt(100); + List files = cmCustQualifyFile.getFiles(); + if (null != files) { + for (SystemAttachment cmAttach : files) { + cmAttach.setFileId(String.valueOf(newId)); + } + systemAttachmentService.updateBatchById(files); + cmCustQualifyFile.setFileId(newId); + } + cmCustQualifyFileService.updateById(cmCustQualifyFile); + } + + private void setFile(CmCustQualifyFile cmCustQualifyFile) { + Long fileId = cmCustQualifyFile.getFileId(); + if (null != fileId) { + List list = systemAttachmentService.list(new LambdaQueryWrapper() + .eq(SystemAttachment::getFileId, fileId)); + cmCustQualifyFile.setFiles(list); + } + } + /** * 删除:根据id集合 */ @RequestMapping(value = "/delete", method = RequestMethod.POST) - public CommonResult delete(@RequestBody Long[] ids){ + public CommonResult delete(@RequestBody Long[] ids) { if (cmCustService.removeByIds(Arrays.asList(ids))) { return CommonResult.success(); } return CommonResult.failed(); } -} +} \ No newline at end of file diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/controller/CmCustItemController.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/controller/CmCustItemController.java new file mode 100644 index 0000000..86b444a --- /dev/null +++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/controller/CmCustItemController.java @@ -0,0 +1,183 @@ +package com.zbkj.modules.autogencode.controller; + +import java.util.Arrays; +import java.util.Map; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.zbkj.common.request.PageParamRequest; +import com.zbkj.common.response.CommonResult; +import com.zbkj.common.page.CommonPage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; + + + + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.zbkj.modules.autogencode.entity.CmCustItem; +import com.zbkj.modules.autogencode.service.CmCustItemService; + + + + +/** + * 客户子项信息表 控制器 + */ +@RestController +@RequestMapping("api/autogencode/cmcustitem") +public class CmCustItemController { + @Autowired + private CmCustItemService cmCustItemService; + + + + /** + * 条件设置 + * 根据实体类字段自动生成查询条件 + */ + private void condition(LambdaQueryWrapper queryWrapper, CmCustItem request) { + if (request == null) { + return; + } + + // 根据实体类字段自动生成查询条件 + + // id + if (request.getId() != null) { + queryWrapper.eq(CmCustItem::getId, request.getId()); + } + + // 客户id + if (request.getCustId() != null) { + queryWrapper.eq(CmCustItem::getCustId, request.getCustId()); + } + + // 子项代码 + if (StrUtil.isNotBlank(request.getItemCode())) { + queryWrapper.eq(CmCustItem::getItemCode, request.getItemCode()); + } + + // 子项值 + if (StrUtil.isNotBlank(request.getItemValue())) { + queryWrapper.eq(CmCustItem::getItemValue, request.getItemValue()); + } + + // 排序码 + if (request.getSortCode() != null) { + queryWrapper.eq(CmCustItem::getSortCode, request.getSortCode()); + } + + // 备注 + if (StrUtil.isNotBlank(request.getRemark())) { + queryWrapper.eq(CmCustItem::getRemark, request.getRemark()); + } + + // + if (StrUtil.isNotBlank(request.getTenantId())) { + queryWrapper.eq(CmCustItem::getTenantId, request.getTenantId()); + } + + // 项目类型 + if (StrUtil.isNotBlank(request.getItemType())) { + queryWrapper.eq(CmCustItem::getItemType, request.getItemType()); + } + + // 创建部门 + if (request.getCreateDept() != null) { + queryWrapper.eq(CmCustItem::getCreateDept, request.getCreateDept()); + } + + // 创建人 + if (request.getCreateBy() != null) { + queryWrapper.eq(CmCustItem::getCreateBy, request.getCreateBy()); + } + + // 创建时间 + if (request.getCreateTime() != null) { + queryWrapper.eq(CmCustItem::getCreateTime, request.getCreateTime()); + } + + // 修改人 + if (request.getUpdateBy() != null) { + queryWrapper.eq(CmCustItem::getUpdateBy, request.getUpdateBy()); + } + + // 修改时间 + if (request.getUpdateTime() != null) { + queryWrapper.eq(CmCustItem::getUpdateTime, request.getUpdateTime()); + } + + // 删除标志(0代表存在 2代表删除) + if (StrUtil.isNotBlank(request.getDelFlag())) { + queryWrapper.eq(CmCustItem::getDelFlag, request.getDelFlag()); + } + + } + + + /** + * 分页显示客户子项信息表 + * @param request 搜索条件 + * @param pageParamRequest 分页参数 + */ + @ApiOperation(value = "分页列表") + @RequestMapping(value = "/list", method = RequestMethod.GET) + public CommonResult> getList(@Validated CmCustItem request, @Validated PageParamRequest pageParamRequest) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); + + // 应用搜索条件 + condition(queryWrapper, request); + + CommonPage page = CommonPage.restPage(cmCustItemService.pageList(queryWrapper, pageParamRequest)); + return CommonResult.success(page); + } + + + /** + * 详情数据 + */ + @RequestMapping(value = "/info/{id}", method = RequestMethod.GET) + public CommonResult info(@PathVariable("id") Long id){ + CmCustItem cmCustItem = cmCustItemService.getById(id); + + return CommonResult.success(cmCustItem); + } + + /** + * 新增数据 + */ + @RequestMapping(value = "/save", method = RequestMethod.POST) + public CommonResult save(@RequestBody CmCustItem cmCustItem){ + if (cmCustItemService.save(cmCustItem)) { + return CommonResult.success(); + } + return CommonResult.failed(); + } + + /** + * 修改数据 + */ + @RequestMapping(value = "/update", method = RequestMethod.POST) + public CommonResult update(@RequestBody CmCustItem cmCustItem){ + if (cmCustItemService.updateById(cmCustItem)) { + return CommonResult.success(); + } + return CommonResult.failed(); + } + + /** + * 删除:根据id集合 + */ + @RequestMapping(value = "/delete", method = RequestMethod.POST) + public CommonResult delete(@RequestBody Long[] ids){ + if (cmCustItemService.removeByIds(Arrays.asList(ids))) { + return CommonResult.success(); + } + return CommonResult.failed(); + } + +} diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/dao/CmCustItemDao.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/dao/CmCustItemDao.java new file mode 100644 index 0000000..8adfd08 --- /dev/null +++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/dao/CmCustItemDao.java @@ -0,0 +1,13 @@ +package com.zbkj.modules.autogencode.dao; + +import com.zbkj.modules.autogencode.entity.CmCustItem; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 客户子项信息表 DAO 映射层 + */ +@Mapper +public interface CmCustItemDao extends BaseMapper { + +} diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/entity/CmCust.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/entity/CmCust.java index 913ebdf..572bf85 100644 --- a/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/entity/CmCust.java +++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/entity/CmCust.java @@ -1,11 +1,14 @@ package com.zbkj.modules.autogencode.entity; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModelProperty; import java.io.Serializable; import java.util.Date; +import java.util.List; + import lombok.Data; @@ -90,5 +93,18 @@ public class CmCust implements Serializable { */ @ApiModelProperty(value = "") private String tenantId; + + /** + * 资质状态(虚拟字段:0为资质不完整,1为资质完整) + */ + @ApiModelProperty(value = "资质状态(0为资质不完整,1为资质完整)") + @TableField(exist = false) + private String qualifyStatus; + + /** + * 资质类型 + */ + @TableField(exist = false) + private List cmCustQualifyList; } diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/entity/CmCustItem.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/entity/CmCustItem.java new file mode 100644 index 0000000..615fbdb --- /dev/null +++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/entity/CmCustItem.java @@ -0,0 +1,89 @@ +package com.zbkj.modules.autogencode.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModelProperty; + + import java.io.Serializable; +import java.util.Date; +import lombok.Data; + + +@Data +@TableName("cm_cust_item") +public class CmCustItem implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * id + */ + @ApiModelProperty(value = "id") + @TableId + private Long id; + /** + * 客户id + */ + @ApiModelProperty(value = "客户id") + private Long custId; + /** + * 子项代码 + */ + @ApiModelProperty(value = "子项代码") + private String itemCode; + /** + * 子项值 + */ + @ApiModelProperty(value = "子项值") + private String itemValue; + /** + * 排序码 + */ + @ApiModelProperty(value = "排序码") + private Integer sortCode; + /** + * 备注 + */ + @ApiModelProperty(value = "备注") + private String remark; + /** + * + */ + @ApiModelProperty(value = "") + private String tenantId; + /** + * 项目类型 + */ + @ApiModelProperty(value = "项目类型") + private String itemType; + /** + * 创建部门 + */ + @ApiModelProperty(value = "创建部门") + private Long createDept; + /** + * 创建人 + */ + @ApiModelProperty(value = "创建人") + private Long createBy; + /** + * 创建时间 + */ + @ApiModelProperty(value = "创建时间") + private Date createTime; + /** + * 修改人 + */ + @ApiModelProperty(value = "修改人") + private Long updateBy; + /** + * 修改时间 + */ + @ApiModelProperty(value = "修改时间") + private Date updateTime; + /** + * 删除标志(0代表存在 2代表删除) + */ + @ApiModelProperty(value = "删除标志(0代表存在 2代表删除)") + private String delFlag; + +} diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/entity/CmCustQualify.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/entity/CmCustQualify.java index bf855f8..878b73f 100644 --- a/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/entity/CmCustQualify.java +++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/entity/CmCustQualify.java @@ -1,11 +1,14 @@ package com.zbkj.modules.autogencode.entity; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModelProperty; import java.io.Serializable; import java.util.Date; +import java.util.List; + import lombok.Data; @@ -86,4 +89,10 @@ public class CmCustQualify implements Serializable { @ApiModelProperty(value = "租户ID") private String tenantId; + /** + * 资质文件 + */ + @TableField(exist = false) + private List cmCustQualifyFileList; + } diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/entity/CmCustQualifyFile.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/entity/CmCustQualifyFile.java index d2183db..fd3c206 100644 --- a/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/entity/CmCustQualifyFile.java +++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/entity/CmCustQualifyFile.java @@ -1,11 +1,16 @@ package com.zbkj.modules.autogencode.entity; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.zbkj.common.model.system.SystemAttachment; import io.swagger.annotations.ApiModelProperty; import java.io.Serializable; import java.util.Date; +import java.util.List; + import lombok.Data; @@ -48,6 +53,7 @@ public class CmCustQualifyFile implements Serializable { /** * 提交日期 */ + @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss") @ApiModelProperty(value = "提交日期") private Date submitDate; /** @@ -106,4 +112,10 @@ public class CmCustQualifyFile implements Serializable { @ApiModelProperty(value = "租户ID") private String tenantId; + /** + * 文件 + */ + @TableField(exist = false) + private List files; + } diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/service/CmCustItemService.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/service/CmCustItemService.java new file mode 100644 index 0000000..73d405d --- /dev/null +++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/service/CmCustItemService.java @@ -0,0 +1,25 @@ +package com.zbkj.modules.autogencode.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zbkj.modules.autogencode.entity.CmCustItem; +import com.zbkj.common.request.PageParamRequest; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; + + +import java.util.List; +import java.util.Map; + +/** + * 客户子项信息表 业务接口 + * +---------------------------------------------------------------------- + */ +public interface CmCustItemService extends IService { + + /** + * CmCustItem 列表查询 + * @param pageParamRequest 分页参数对象 + * @return + */ + List pageList(LambdaQueryWrapper queryWrapper, PageParamRequest pageParamRequest); +} + diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/service/impl/CmCustItemServiceImpl.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/service/impl/CmCustItemServiceImpl.java new file mode 100644 index 0000000..8d0b953 --- /dev/null +++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/service/impl/CmCustItemServiceImpl.java @@ -0,0 +1,42 @@ +package com.zbkj.modules.autogencode.service.impl; + +import com.github.pagehelper.PageHelper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import com.zbkj.modules.autogencode.dao.CmCustItemDao; +import com.zbkj.modules.autogencode.entity.CmCustItem; +import com.zbkj.modules.autogencode.service.CmCustItemService; +import com.zbkj.common.page.CommonPage; +import com.zbkj.common.request.PageParamRequest; + +import javax.annotation.Resource; +import java.util.Map; +import java.util.Arrays; +import java.util.List; + + +@Service("cmCustItemService") +public class CmCustItemServiceImpl extends ServiceImpl implements CmCustItemService { + + + @Resource + private CmCustItemDao dao; + + + /** + * 带分页参数的列表查询实现 + */ + @Override + public List pageList(LambdaQueryWrapper queryWrapper, PageParamRequest pageParamRequest) { + + PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit()); + + return dao.selectList(queryWrapper); + } + + +} diff --git a/crmeb/crmeb-admin/src/main/resources/mapper/autogencode/CmCustItemDao.xml b/crmeb/crmeb-admin/src/main/resources/mapper/autogencode/CmCustItemDao.xml new file mode 100644 index 0000000..fca649f --- /dev/null +++ b/crmeb/crmeb-admin/src/main/resources/mapper/autogencode/CmCustItemDao.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/crmeb/crmeb-common/src/main/java/com/zbkj/common/model/system/SystemAttachment.java b/crmeb/crmeb-common/src/main/java/com/zbkj/common/model/system/SystemAttachment.java index 6f38c0a..5c277a9 100644 --- a/crmeb/crmeb-common/src/main/java/com/zbkj/common/model/system/SystemAttachment.java +++ b/crmeb/crmeb-common/src/main/java/com/zbkj/common/model/system/SystemAttachment.java @@ -39,7 +39,7 @@ public class SystemAttachment implements Serializable { @ApiModelProperty(value = "附件名称") private String name; - @ApiModelProperty(value = "附件名称") + @ApiModelProperty(value = "附件id") private String fileId; @ApiModelProperty(value = "附件路径")