Merge remote-tracking branch 'origin/dev' into dev

dev
huwei 2026-07-21 09:47:50 +08:00
commit 888bfe5b9e
64 changed files with 2369 additions and 173 deletions

View File

@ -772,6 +772,55 @@ create table `eval_sign_record` (
) engine=innodb default charset=utf8mb4 collate=utf8mb4_0900_ai_ci comment='项目签字记录表';
CREATE TABLE IF NOT EXISTS `qual_on_site_review` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`biz_type` varchar(64) DEFAULT NULL COMMENT '资质类型:add 新增 change:变更',
`biz_id` bigint DEFAULT NULL COMMENT '业务id',
`org_id` bigint NOT NULL COMMENT '受审查机构ID (关联机构表)',
`review_date_start` datetime NOT NULL COMMENT '现场审查开始时间',
`review_location` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '审查地点',
`review_members` varchar(512) DEFAULT NULL COMMENT '审查组成员名单',
`material_requirements` text COMMENT '材料准备要求',
`supervisor_contact` varchar(64) DEFAULT NULL COMMENT '监管联系人姓名',
`contact_phone` varchar(32) DEFAULT NULL COMMENT '监管联系电话',
`status` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '1' COMMENT '现场审查状态(AGENCY_PENDING_CONFIRMATION机构待确认、AGENCY_CONFIRMED机构已确认、REVIEW_PASSED核查通过、REVIEW_FAILED核查不通过)',
`review_opinion` varchar(256) DEFAULT NULL COMMENT '核查意见',
`delete_enum` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '删除标识true false',
`remarks` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注',
`create_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '创建人姓名',
`update_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '更新人姓名',
`tenant_id` bigint DEFAULT NULL COMMENT '租户id',
`version` int DEFAULT NULL COMMENT '版本',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
`create_id` bigint DEFAULT NULL COMMENT '创建人id',
`update_id` bigint DEFAULT NULL COMMENT '修改人id',
`env` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '环境',
PRIMARY KEY (`id`),
KEY `idx_review_date_start` (`review_date_start`),
KEY `idx_org_id` (`org_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='资质现场核查';
CREATE TABLE IF NOT EXISTS `qual_on_site_review_file` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`qual_on_site_review_id` bigint NOT NULL COMMENT '资质现场核查id',
`file_name` varchar(128) NOT NULL COMMENT '文件名称',
`file_url` varchar(1024) NOT NULL COMMENT '文件url',
`delete_enum` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '删除标识true false',
`remarks` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注',
`create_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '创建人姓名',
`update_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '更新人姓名',
`tenant_id` bigint DEFAULT NULL COMMENT '租户id',
`version` int DEFAULT NULL COMMENT '版本',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
`create_id` bigint DEFAULT NULL COMMENT '创建人id',
`update_id` bigint DEFAULT NULL COMMENT '修改人id',
`env` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '环境',
PRIMARY KEY (`id`),
KEY `idx_qual_on_site_review_id` (`qual_on_site_review_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='资质现场核查-文件信息';
set foreign_key_checks = 1;
-- =============================================

View File

@ -0,0 +1,121 @@
package org.qinan.safetyeval.adapter.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
*/
@Slf4j
@Configuration
public class WpsFilter extends OncePerRequestFilter {
private static final String WPS_TOKEN_HEADER = "X-Weboffice-Token";
private static final String AUTH_TOKEN_HEADER = "token";
private static final String AUTH_TOKEN_PREFIX = "jjb-saas-auth:oauth:";
@Bean
public FilterRegistrationBean<WpsFilter> wpsFilterRegistration() {
FilterRegistrationBean<WpsFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(this);
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
bean.addUrlPatterns("/safetyEval-h5/wsp/*");
bean.setName("wpsFilter");
return bean;
}
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
String uri = request.getRequestURI();
return uri == null || !uri.contains("/safetyEval-h5/wsp/");
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String wpsToken = request.getHeader(WPS_TOKEN_HEADER);
if (!StringUtils.hasText(wpsToken)) {
log.warn("WPS callback missing {}: {}", WPS_TOKEN_HEADER, request.getRequestURI());
filterChain.doFilter(request, response);
return;
}
String token = wpsToken.trim();
if (!token.startsWith(AUTH_TOKEN_PREFIX)) {
token = AUTH_TOKEN_PREFIX + token;
}
MutableHeaderRequestWrapper wrapped = new MutableHeaderRequestWrapper(request);
wrapped.putHeader(AUTH_TOKEN_HEADER, token);
log.info("WPS token mapped to header {} for {}", AUTH_TOKEN_HEADER, request.getRequestURI());
filterChain.doFilter(wrapped, response);
}
static final class MutableHeaderRequestWrapper extends HttpServletRequestWrapper {
private final Map<String, String> extraHeaders = new HashMap<>();
MutableHeaderRequestWrapper(HttpServletRequest request) {
super(request);
}
void putHeader(String name, String value) {
extraHeaders.put(name, value);
}
@Override
public String getHeader(String name) {
String value = findExtra(name);
return value != null ? value : super.getHeader(name);
}
@Override
public Enumeration<String> getHeaders(String name) {
String value = findExtra(name);
if (value != null) {
return Collections.enumeration(Collections.singletonList(value));
}
return super.getHeaders(name);
}
@Override
public Enumeration<String> getHeaderNames() {
Set<String> names = new HashSet<>();
Enumeration<String> original = super.getHeaderNames();
while (original.hasMoreElements()) {
names.add(original.nextElement());
}
names.addAll(extraHeaders.keySet());
return Collections.enumeration(names);
}
private String findExtra(String name) {
if (name == null) {
return null;
}
for (Map.Entry<String, String> entry : extraHeaders.entrySet()) {
if (entry.getKey().equalsIgnoreCase(name)) {
return entry.getValue();
}
}
return null;
}
}
}

View File

@ -1,122 +1,156 @@
package org.qinan.safetyeval.adapter.web;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.jjb.saas.framework.auth.model.SSOUser;
import com.jjb.saas.framework.utils.JwtTokenUtils;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.fastjson2.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
import org.qinan.safetyeval.infrastructure.mapper.AccountMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.qinan.safetyeval.client.api.WpsApi;
import org.qinan.safetyeval.client.co.WpsDocOpenCO;
import org.qinan.safetyeval.infrastructure.dataobject.base.Req;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* <p>
* /safetyEval/images
* </p>
* WPS WebOffice WPS token
*
* @author safety-eval
*/
@Api(tags = "对外开放接口")
@Api(tags = "WPS回调接口")
@RestController
@RequestMapping("/safetyEval-h5/wsp")
@Slf4j
public class H5OpenController {
@Autowired
private AccountMapper accountMapper;
@Autowired
private FileStorageService fileStorageService;
@Resource
private WpsApi wpsApi;
@ApiOperation("wps回调预览")
@ApiOperation("wps回调-获取文件信息")
@GetMapping(value = "/v3/3rd/files/{file_id}", produces = MediaType.APPLICATION_JSON_VALUE)
public String getWpsInfoByFileId(@PathVariable("file_id") String file_id, HttpServletRequest request) {
log.info("token, {}", request.getHeader("token"));
log.info("Token, {}", request.getHeader("Token"));
String header = request.getHeader("X-Weboffice-Token");
log.info("X-Weboffice-Token, {}", request.getHeader("X-Weboffice-Token"));
String token = header;
log.info("2.5token不为空:{}", token);
token = token.replaceAll("jjb-saas-auth:oauth:", "").trim();
String json = null;
SSOUser ssoUser;
try {
json = JwtTokenUtils.parseToken(token);
} catch (Exception var41) {
}
if (null != json) {
ssoUser = (SSOUser) JSONUtil.toBean(json, SSOUser.class);
} else {
ssoUser = new SSOUser();
}
log.info("ssoUser:{}", ssoUser);
log.info("wps回调预览{}", file_id);
return accountMapper.getWps(1);
public String getWpsInfoByFileId(@PathVariable("file_id") String fileId) {
log.info("wps回调预览{}", fileId);
return toJson(wpsApi.getFileInfo(fileId));
}
@ApiOperation("wps回调下载")
@ApiOperation("wps回调-获取下载地址")
@GetMapping(value = "/v3/3rd/files/{file_id}/download", produces = MediaType.APPLICATION_JSON_VALUE)
public String getWpsDownloadByFileId(@PathVariable("file_id") String file_id) {
log.info("wps回调下载{}", file_id);
return accountMapper.getWps(2);
public String getWpsDownloadByFileId(@PathVariable("file_id") String fileId) {
log.info("wps回调下载{}", fileId);
return toJson(wpsApi.getDownload(fileId));
}
@ApiOperation("wps回调权限信息")
@ApiOperation("wps回调-文档权限")
@GetMapping(value = "/v3/3rd/files/{file_id}/permission", produces = MediaType.APPLICATION_JSON_VALUE)
public String getWpsPermissionByFileId(@PathVariable("file_id") String file_id) {
log.info("wps回调权限信息{}", file_id);
return accountMapper.getWps(3);
public String getWpsPermissionByFileId(@PathVariable("file_id") String fileId) {
log.info("wps回调权限信息{}", fileId);
return toJson(wpsApi.getPermission(fileId));
}
@ApiOperation("wps回调用户信息")
@ApiOperation("wps回调-批量用户信息")
@GetMapping(value = "/v3/3rd/users", produces = MediaType.APPLICATION_JSON_VALUE)
public String getWpsUsers(@RequestParam List<Long> user_ids) {
log.info("wps回调用户信息{}", user_ids);
return accountMapper.getWps(4);
public String getWpsUsers(@RequestParam("user_ids") List<String> userIds) {
log.info("wps回调用户信息{}", userIds);
return toJson(wpsApi.getUsers(userIds));
}
@ApiOperation("wps回调上传第一步")
@ApiOperation("wps回调-上传准备")
@GetMapping(value = "/v3/3rd/files/{file_id}/upload/prepare", produces = MediaType.APPLICATION_JSON_VALUE)
public String getWpsUpLoadOne(@PathVariable("file_id") String file_id) {
log.info("wps回调上传第一步{}", file_id);
return accountMapper.getWps(5);
public String getWpsUpLoadOne(@PathVariable("file_id") String fileId) {
log.info("wps回调上传第一步{}", fileId);
return toJson(wpsApi.uploadPrepare(fileId));
}
@ApiOperation("wps回调上传第二步")
@PostMapping(value = "/v3/3rd/files/{file_id}/upload/address")
public String getWpsUpLoadTwo(@PathVariable("file_id") String file_id, @RequestBody Map<String, Object> map) {
log.info("wps回调上传第二步{}, map: {}", file_id, JSON.toJSONString(map));
return accountMapper.getWps(6);
@ApiOperation("wps回调-获取上传地址")
@PostMapping(value = "/v3/3rd/files/{file_id}/upload/address", produces = MediaType.APPLICATION_JSON_VALUE)
public String getWpsUpLoadTwo(@PathVariable("file_id") String fileId,
@RequestBody Map<String, Object> body) {
log.info("wps回调上传第二步{}, body={}", fileId, body);
return toJson(wpsApi.uploadAddress(fileId, body));
}
@ApiOperation("wps回调上传第三步")
@PostMapping(value = "/v3/3rd/files/{file_id}/upload/complete")
public String getWpsUpLoadThree(@PathVariable("file_id") String file_id, @RequestBody Map<String, Object> map) {
String msg = accountMapper.getWps(7);
log.info("wps回调上传第三步{}, map: {}", file_id, msg);
return msg;
@ApiOperation("wps回调-上传完成")
@PostMapping(value = "/v3/3rd/files/{file_id}/upload/complete", produces = MediaType.APPLICATION_JSON_VALUE)
public String getWpsUpLoadThree(@PathVariable("file_id") String fileId,
@RequestBody Map<String, Object> body) {
log.info("wps回调上传第三步{}, body={}", fileId, body);
return toJson(wpsApi.uploadComplete(fileId, body));
}
@PutMapping(value = "/upload/{file_id}", consumes = "application/octet-stream")
public String uploadFile(@PathVariable("file_id") String file_id, HttpServletRequest request) throws IOException {
// 获取文件的二进制流
try (InputStream inputStream = request.getInputStream()) {
FileInfo upload = fileStorageService.of(inputStream, file_id).upload();
log.info("上传文件成功:{}", JSON.toJSONString(upload));
return "ok";
@ApiOperation("wps回调-PUT上传文件实体")
@PutMapping(value = "/upload/{file_id}", consumes = "application/octet-stream", produces = MediaType.APPLICATION_JSON_VALUE)
public String uploadFile(@PathVariable("file_id") String fileId, HttpServletRequest request) throws IOException {
log.info("wps PUT上传{}", fileId);
return toJson(wpsApi.uploadBinary(fileId, request.getInputStream()));
}
@ApiOperation("wps回调-历史版本列表")
@GetMapping(value = "/v3/3rd/files/{file_id}/versions", produces = MediaType.APPLICATION_JSON_VALUE)
public String getWpsVersions(@PathVariable("file_id") String fileId) {
log.info("wps回调历史版本列表{}", fileId);
return toJson(wpsApi.listVersions(fileId));
}
@ApiOperation("wps回调-指定历史版本")
@GetMapping(value = "/v3/3rd/files/{file_id}/versions/{version}", produces = MediaType.APPLICATION_JSON_VALUE)
public String getWpsVersion(@PathVariable("file_id") String fileId,
@PathVariable("version") Integer version) {
log.info("wps回调历史版本详情{}, version={}", fileId, version);
return toJson(wpsApi.getVersion(fileId, version));
}
@ApiOperation("wps回调-历史版本下载")
@GetMapping(value = "/v3/3rd/files/{file_id}/versions/{version}/download", produces = MediaType.APPLICATION_JSON_VALUE)
public String getWpsVersionDownload(@PathVariable("file_id") String fileId,
@PathVariable("version") Integer version) {
log.info("wps回调历史版本下载{}, version={}", fileId, version);
return toJson(wpsApi.getVersionDownload(fileId, version));
}
@ApiOperation("wps回调-文档重命名")
@PutMapping(value = "/v3/3rd/files/{file_id}/name", produces = MediaType.APPLICATION_JSON_VALUE)
public String renameWpsFile(@PathVariable("file_id") String fileId,
@RequestBody Map<String, Object> body) {
log.info("wps回调重命名{}, body={}", fileId, body);
return toJson(wpsApi.rename(fileId, body));
}
@ApiOperation("打开页当前用户有文档返回最近一份没有则创建空白docx")
@GetMapping(value = "/doc/my-or-create", produces = MediaType.APPLICATION_JSON_VALUE)
public SingleResponse<WpsDocOpenCO> myOrCreate(@RequestParam("docxUrl") String docxUrl) {
log.info("wps my-or-create");
return SingleResponse.of(wpsApi.myOrCreate(docxUrl));
}
@ApiOperation("始终新建一份空白docx")
@PostMapping(value = "/doc/create", produces = MediaType.APPLICATION_JSON_VALUE)
public SingleResponse<WpsDocOpenCO> createBlank(@RequestBody Req<String> req) {
log.info("wps create blank");
return SingleResponse.of(wpsApi.createBlank(req.getData()));
}
@ApiOperation("模版文档(固定)")
@PostMapping(value = "/doc/template")
public SingleResponse<Map<String, Object>> template() {
Map<String, Object> map = new HashMap<>();
map.put("安全预评价报告", "https://test-dragon-yf-pub.oss-cn-hangzhou.aliyuncs.com/jjb/6a5dd9010dc588e38bfb4cce.docx");
map.put("安全验收评价报告", "https://test-dragon-yf-pub.oss-cn-hangzhou.aliyuncs.com/jjb/6a5dd9010dc588e38bfb4cce.docx");
map.put("安全现状评价报告", "https://test-dragon-yf-pub.oss-cn-hangzhou.aliyuncs.com/jjb/6a5dd9010dc588e38bfb4cce.docx");
return SingleResponse.of(map);
}
private String toJson(Map<String, Object> result) {
try {
return JSONObject.toJSONString(result).toString();
} catch (Exception e) {
log.error("上传文件失败:{}", e.getMessage());
return "上传文件失败";
log.error("wps response serialize failed", e);
return "{\"code\":40001,\"message\":\"serialize error\"}";
}
}
}

View File

@ -8,9 +8,17 @@ import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.qinan.safetyeval.app.review.service.QualOnSiteReviewServiceI;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewAddCmd;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewMonitorPageQry;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewOrgPageQry;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewPageQry;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewResultUploadCmd;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewUpdateCmd;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewCo;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewMonitorCo;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewOrgCo;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewStatisticsCo;
import org.qinan.safetyeval.domain.constant.QualOnSiteReviewStatusEnum;
import org.qinan.safetyeval.infrastructure.adapter.ThreadLocalUserInfoAdapter;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -39,8 +47,23 @@ public class QualOnSiteReviewController implements Serializable {
@GetMapping("/monitor/page")
@ApiOperation("监管端-查询资质现场核查列表-分页")
public PageResponse<QualOnSiteReviewCo> monitorPage(@Validated QualOnSiteReviewPageQry qry) {
return qualOnSiteReviewServiceI.listQualOnSiteReviewPage(qry);
public org.qinan.safetyeval.client.dto.PageResponse<QualOnSiteReviewMonitorCo> monitorPage(
@Validated QualOnSiteReviewMonitorPageQry qry) {
return qualOnSiteReviewServiceI.monitorPage(qry);
}
@GetMapping("/org/page")
@ApiOperation("机构端-查询资质现场核查列表-分页")
public org.qinan.safetyeval.client.dto.PageResponse<QualOnSiteReviewOrgCo> orgPage(@Validated QualOnSiteReviewOrgPageQry qry) {
Long orgId = ThreadLocalUserInfoAdapter.getOrgId();
qry.setOrgId(orgId);
return qualOnSiteReviewServiceI.orgPage(qry);
}
@GetMapping("/monitor/page/statistics")
@ApiOperation("资质现场核查统计")
public SingleResponse<QualOnSiteReviewStatisticsCo> statistics(@RequestParam(required = false) Long orgId) {
return SingleResponse.of(qualOnSiteReviewServiceI.statistics(orgId));
}
@GetMapping("/{id}")
@ -52,6 +75,7 @@ public class QualOnSiteReviewController implements Serializable {
@PostMapping
@ApiOperation("新增资质现场核查")
public Response save(@Validated @RequestBody QualOnSiteReviewAddCmd qualOnSiteReviewAddCmd) {
qualOnSiteReviewAddCmd.setStatus(QualOnSiteReviewStatusEnum.AGENCY_PENDING_CONFIRMATION.getCode());
qualOnSiteReviewServiceI.saveQualOnSiteReview(qualOnSiteReviewAddCmd);
return Response.buildSuccess();
}
@ -63,6 +87,13 @@ public class QualOnSiteReviewController implements Serializable {
return Response.buildSuccess();
}
@PostMapping("/result-upload")
@ApiOperation("审查结果上传")
public Response uploadReviewResult(@Validated @RequestBody QualOnSiteReviewResultUploadCmd qualOnSiteReviewResultUploadCmd) {
qualOnSiteReviewServiceI.uploadReviewResult(qualOnSiteReviewResultUploadCmd);
return Response.buildSuccess();
}
@DeleteMapping("/{id}")
@ApiOperation("删除资质现场核查(单个)")
public Response deletedById(@PathVariable("id") Long id) {

View File

@ -9,6 +9,7 @@ import org.qinan.safetyeval.client.dto.QualFilingAddCmd;
import org.qinan.safetyeval.client.dto.QualFilingChangeAddCmd;
import org.qinan.safetyeval.domain.entity.QualFilingChangeEntity;
import org.qinan.safetyeval.domain.entity.QualFilingEntity;
import org.qinan.safetyeval.infrastructure.dataobject.QualFilingDO;
import java.util.List;
@ -69,4 +70,23 @@ public interface QualFilingChangeCmdConvertor {
@Mapping(target = "applyTypeCode", ignore = true)
@Mapping(target = "applyTypeName", ignore = true)
QualFilingAddCmd convertChangeEToFilingCmd(QualFilingChangeEntity changeEntity);
/**
* DOCmd使
* <p>
* BeanUtils.copyProperties(qualFilingDO, cmd, "id")
* - id
* - filingId DO.id
* - businessScope JSON List
*/
@Mapping(target = "id", ignore = true)
@Mapping(target = "filingId", source = "id")
@Mapping(target = "changeFilingId", ignore = true)
@Mapping(target = "businessScope", source = "businessScope", qualifiedByName = "jsonStringToList")
QualFilingChangeAddCmd convertDOToCmd(QualFilingDO qualFilingDO);
@Named("jsonStringToList")
default List<String> jsonStringToList(String json) {
return json == null ? null : JSON.parseArray(json, String.class);
}
}

View File

@ -8,6 +8,7 @@ import org.qinan.safetyeval.client.co.QualFilingCommitmentCO;
import org.qinan.safetyeval.client.dto.QualFilingCommitmentAddCmd;
import org.qinan.safetyeval.domain.change.model.QualFilingCommitmentChangeE;
import org.qinan.safetyeval.domain.entity.QualFilingCommitmentEntity;
import org.qinan.safetyeval.infrastructure.dataobject.QualFilingCommitmentDO;
import java.time.LocalDate;
import java.time.LocalDateTime;
@ -63,7 +64,18 @@ public interface QualFilingCommitmentChangeCmdConvertor {
*/
QualFilingCommitmentAddCmd convertChangeEToCmd(QualFilingCommitmentChangeE changeE);
/**
* DOCmd使
* signDate LocalDate LocalDateTime
*/
@Mapping(target = "filingChangeId", ignore = true)
QualFilingCommitmentChangeAddCmd convertDOToCmd(QualFilingCommitmentDO qualFilingCommitmentDO);
default LocalDate map(LocalDateTime dateTime) {
return dateTime == null ? null : dateTime.toLocalDate();
}
default LocalDateTime map(LocalDate date) {
return date == null ? null : date.atStartOfDay();
}
}

View File

@ -7,6 +7,7 @@ import org.qinan.safetyeval.client.change.request.QualFilingEquipmentChangeUpdat
import org.qinan.safetyeval.client.co.QualFilingEquipmentCO;
import org.qinan.safetyeval.domain.change.model.QualFilingEquipmentChangeE;
import org.qinan.safetyeval.domain.entity.QualFilingEquipmentEntity;
import org.qinan.safetyeval.infrastructure.dataobject.QualFilingEquipmentDO;
import java.util.List;
@ -60,4 +61,15 @@ public interface QualFilingEquipmentChangeCmdConvertor {
* CO
*/
List<QualFilingEquipmentCO> convertChangeEListToCOList(List<QualFilingEquipmentChangeE> changeEs);
/**
* DOCmd使
*/
@Mapping(target = "filingChangeId", ignore = true)
QualFilingEquipmentChangeAddCmd convertDOToCmd(QualFilingEquipmentDO qualFilingEquipmentDO);
/**
* DOCmd
*/
List<QualFilingEquipmentChangeAddCmd> convertDOListToCmdList(List<QualFilingEquipmentDO> qualFilingEquipmentDOs);
}

View File

@ -8,6 +8,7 @@ import org.qinan.safetyeval.client.co.QualFilingMaterialCO;
import org.qinan.safetyeval.client.dto.QualFilingMaterialAddCmd;
import org.qinan.safetyeval.domain.change.model.QualFilingMaterialChangeE;
import org.qinan.safetyeval.domain.entity.QualFilingMaterialEntity;
import org.qinan.safetyeval.infrastructure.dataobject.QualFilingMaterialDO;
import java.util.List;
@ -80,4 +81,15 @@ public interface QualFilingMaterialChangeCmdConvertor {
* Cmd
*/
List<QualFilingMaterialAddCmd> convertChangeEListToCmdList(List<QualFilingMaterialChangeE> changeEs);
/**
* DOCmd使
*/
@Mapping(target = "filingChangeId", ignore = true)
QualFilingMaterialChangeAddCmd convertDOToCmd(QualFilingMaterialDO qualFilingMaterialDO);
/**
* DOCmd
*/
List<QualFilingMaterialChangeAddCmd> convertDOListToCmdList(List<QualFilingMaterialDO> qualFilingMaterialDOs);
}

View File

@ -8,6 +8,7 @@ import org.qinan.safetyeval.client.co.QualFilingPersonnelCO;
import org.qinan.safetyeval.client.dto.QualFilingPersonnelAddCmd;
import org.qinan.safetyeval.domain.change.model.QualFilingPersonnelChangeE;
import org.qinan.safetyeval.domain.entity.QualFilingPersonnelEntity;
import org.qinan.safetyeval.infrastructure.dataobject.QualFilingPersonnelDO;
import java.time.LocalDate;
import java.time.LocalDateTime;
@ -84,7 +85,23 @@ public interface QualFilingPersonnelChangeCmdConvertor {
*/
List<QualFilingPersonnelAddCmd> convertChangeEListToCmdList(List<QualFilingPersonnelChangeE> changeEs);
/**
* DOCmd使
* birthDate / joinWorkDate LocalDate LocalDateTime
*/
@Mapping(target = "filingChangeId", ignore = true)
QualFilingPersonnelChangeAddCmd convertDOToCmd(QualFilingPersonnelDO qualFilingPersonnelDO);
/**
* DOCmd
*/
List<QualFilingPersonnelChangeAddCmd> convertDOListToCmdList(List<QualFilingPersonnelDO> qualFilingPersonnelDOs);
default LocalDate map(LocalDateTime dateTime) {
return dateTime == null ? null : dateTime.toLocalDate();
}
default LocalDateTime map(LocalDate date) {
return date == null ? null : date.atStartOfDay();
}
}

View File

@ -0,0 +1,36 @@
package org.qinan.safetyeval.app.convertor;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.qinan.safetyeval.client.co.WpsFileCO;
import org.qinan.safetyeval.client.co.WpsUserCO;
import org.qinan.safetyeval.domain.entity.AccountEntity;
import org.qinan.safetyeval.domain.entity.WpsDocEntity;
import org.qinan.safetyeval.domain.entity.WpsDocVersionEntity;
/**
* WPS App
*
* @author safety-eval
*/
@Mapper(componentModel = "spring")
public interface WpsCmdConvertor {
@Mapping(source = "fileId", target = "id")
@Mapping(source = "docVersion", target = "version")
@Mapping(source = "createTimeEpoch", target = "createTime")
@Mapping(source = "modifyTimeEpoch", target = "modifyTime")
WpsFileCO toFileCO(WpsDocEntity entity);
@Mapping(source = "fileId", target = "id")
@Mapping(source = "docVersion", target = "version")
@Mapping(source = "createTimeEpoch", target = "createTime")
@Mapping(source = "createTimeEpoch", target = "modifyTime")
@Mapping(target = "creatorId", ignore = true)
WpsFileCO toFileCO(WpsDocVersionEntity entity);
@Mapping(target = "id", expression = "java(entity.getId() == null ? null : String.valueOf(entity.getId()))")
@Mapping(source = "userName", target = "name")
@Mapping(source = "profileUrl", target = "avatarUrl")
WpsUserCO toUserCO(AccountEntity entity);
}

View File

@ -16,6 +16,7 @@ import org.qinan.safetyeval.client.dto.*;
import org.qinan.safetyeval.domain.constant.BooleanQAEnum;
import org.qinan.safetyeval.domain.constant.QualFilingApplyTypeEnum;
import org.qinan.safetyeval.domain.constant.QualFilingReviewResultEnum;
import org.qinan.safetyeval.domain.constant.QualFilingStatusEnum;
import org.qinan.safetyeval.domain.entity.*;
import org.qinan.safetyeval.domain.exception.BizException;
import org.qinan.safetyeval.domain.exception.ErrorCode;
@ -225,49 +226,8 @@ public class QualFilingExecutor implements QualFilingApi {
@Override
@Transactional(rollbackFor = Exception.class)
public void review(QualFilingReviewAddCmd cmd) {
qualFilingDomainService.review(cmd.getFilingId(), cmd.getReviewResult(), cmd.getReviewResultRemark(), cmd.getFilingExpertId(), cmd.getFilingExpertName(), cmd.getReviewOpinion());
if (QualFilingReviewResultEnum.PASS.getCode() == Integer.parseInt(cmd.getReviewResult())) {
// 审核通过,需要新增资质变更记录
AggregationSaveOrEditQualFilingChangeCmd cmdSync = new AggregationSaveOrEditQualFilingChangeCmd();
// 基本信息
QualFilingDO qualFilingDO = qualFilingMapper.selectById(cmd.getFilingId());
QualFilingChangeAddCmd qualFilingChangeAddCmd = new QualFilingChangeAddCmd();
BeanUtils.copyProperties(qualFilingDO, qualFilingChangeAddCmd, "id");
qualFilingChangeAddCmd.setBusinessScope(JSON.parseArray(qualFilingDO.getBusinessScope(), String.class));
qualFilingChangeAddCmd.setFilingId(qualFilingDO.getId());
cmdSync.setQualFilingChangeAddCmd(qualFilingChangeAddCmd);
// 备案承诺书
QualFilingCommitmentDO qualFilingCommitmentDO = qualFilingCommitmentMapper.selectOne(new LambdaQueryWrapper<QualFilingCommitmentDO>()
.eq(QualFilingCommitmentDO::getFilingId, cmd.getFilingId()));
QualFilingCommitmentChangeAddCmd qualFilingCommitmentChangeAddCmd = new QualFilingCommitmentChangeAddCmd();
BeanUtils.copyProperties(qualFilingCommitmentDO, qualFilingCommitmentChangeAddCmd);
cmdSync.setQualFilingCommitmentChangeAddCmd(qualFilingCommitmentChangeAddCmd);
// 备案装备
List<QualFilingEquipmentDO> qualFilingEquipmentDOs = qualFilingEquipmentMapper.selectList(new LambdaQueryWrapper<QualFilingEquipmentDO>()
.eq(QualFilingEquipmentDO::getFilingId, cmd.getFilingId()));
cmdSync.setQualFilingEquipmentChangeAddCmds(qualFilingEquipmentDOs.stream().map(item -> {
QualFilingEquipmentChangeAddCmd qualFilingEquipmentChangeAddCmd = new QualFilingEquipmentChangeAddCmd();
BeanUtils.copyProperties(item, qualFilingEquipmentChangeAddCmd);
return qualFilingEquipmentChangeAddCmd;
}).collect(Collectors.toList()));
// 备案材料清单
List<QualFilingMaterialDO> qualFilingMaterialDOs = qualFilingMaterialMapper.selectList(new LambdaQueryWrapper<QualFilingMaterialDO>()
.eq(QualFilingMaterialDO::getFilingId, cmd.getFilingId()));
cmdSync.setQualFilingMaterialChangeAddCmds(qualFilingMaterialDOs.stream().map(item -> {
QualFilingMaterialChangeAddCmd qualFilingMaterialChangeAddCmd = new QualFilingMaterialChangeAddCmd();
BeanUtils.copyProperties(item, qualFilingMaterialChangeAddCmd);
return qualFilingMaterialChangeAddCmd;
}).collect(Collectors.toList()));
// 备案人员
List<QualFilingPersonnelDO> qualFilingPersonnelDOs = qualFilingPersonnelMapper.selectList(new LambdaQueryWrapper<QualFilingPersonnelDO>()
.eq(QualFilingPersonnelDO::getFilingId, cmd.getFilingId()));
cmdSync.setQualFilingPersonnelChangeAddCmds(qualFilingPersonnelDOs.stream().map(item -> {
QualFilingPersonnelChangeAddCmd qualFilingPersonnelChangeAddCmd = new QualFilingPersonnelChangeAddCmd();
BeanUtils.copyProperties(item, qualFilingPersonnelChangeAddCmd);
return qualFilingPersonnelChangeAddCmd;
}).collect(Collectors.toList()));
qualFilingChangeExecutor.aggregationSaveOrEdit(cmdSync, true);
}
qualFilingDomainService.review(cmd.getFilingId(), cmd.getReviewResult()
, cmd.getReviewResultRemark(), cmd.getFilingExpertId(), cmd.getFilingExpertName(), cmd.getReviewOpinion());
}
@Override

View File

@ -0,0 +1,477 @@
package org.qinan.safetyeval.app.executor;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
import org.qinan.safetyeval.app.convertor.WpsCmdConvertor;
import org.qinan.safetyeval.client.api.WpsApi;
import org.qinan.safetyeval.client.co.WpsDocOpenCO;
import org.qinan.safetyeval.client.co.WpsFileCO;
import org.qinan.safetyeval.client.co.WpsPermissionCO;
import org.qinan.safetyeval.client.co.WpsUserCO;
import org.qinan.safetyeval.domain.entity.AccountEntity;
import org.qinan.safetyeval.domain.entity.FileStorage;
import org.qinan.safetyeval.domain.entity.WpsDocEntity;
import org.qinan.safetyeval.domain.entity.WpsDocVersionEntity;
import org.qinan.safetyeval.domain.exception.BizException;
import org.qinan.safetyeval.domain.exception.ErrorCode;
import org.qinan.safetyeval.domain.gateway.AccountGateway;
import org.qinan.safetyeval.domain.service.FileStorageDomainService;
import org.qinan.safetyeval.domain.service.WpsDocDomainService;
import org.qinan.safetyeval.infrastructure.adapter.ThreadLocalUserInfoAdapter;
import org.qinan.safetyeval.infrastructure.adapter.auth.AuthUserContextAdapter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* WPS WebOffice
*
* @author safety-eval
*/
@Slf4j
@Service
public class WpsExecutor implements WpsApi {
@Resource
private WpsDocDomainService wpsDocDomainService;
@Resource
private AccountGateway accountGateway;
@Resource
private WpsCmdConvertor wpsCmdConvertor;
@Resource
private FileStorageService fileStorageService;
@Resource
private FileStorageDomainService fileStorageDomainService;
@Value("${wps.upload-base-url:}")
private String uploadBaseUrl;
@Value("${wps.def-docx-url:}")
private String defDocxUrl;
@Override
public Map<String, Object> getFileInfo(String fileId) {
try {
WpsDocEntity doc = wpsDocDomainService.getByFileId(fileId);
return ok(wpsCmdConvertor.toFileCO(doc));
} catch (BizException e) {
return fail(e);
}
}
@Override
public Map<String, Object> getDownload(String fileId) {
try {
WpsDocEntity doc = wpsDocDomainService.getByFileId(fileId);
Map<String, Object> data = new LinkedHashMap<>();
data.put("url", resolveDownloadUrl(doc.getDownloadUrl(), doc.getResourceId()));
return ok(data);
} catch (BizException e) {
return fail(e);
}
}
@Override
public Map<String, Object> getPermission(String fileId) {
try {
wpsDocDomainService.getByFileId(fileId);
Long userId = AuthUserContextAdapter.getCurrentUserId();
if (userId == null) {
throw new BizException(ErrorCode.WPS_USER_NOT_LOGIN);
}
WpsPermissionCO permission = new WpsPermissionCO();
permission.setUserId(String.valueOf(userId));
permission.setRead(1);
permission.setUpdate(1);
permission.setDownload(1);
permission.setPrint(1);
permission.setCopy(1);
permission.setComment(1);
// 未实现重命名回调,保持 0
permission.setRename(1);
permission.setHistory(1);
permission.setSaveas(1);
return ok(permission);
} catch (BizException e) {
return fail(e);
}
}
@Override
public Map<String, Object> getUsers(List<String> userIds) {
try {
if (userIds == null || userIds.isEmpty()) {
return ok(Collections.emptyList());
}
List<Long> ids = userIds.stream()
.filter(StringUtils::hasText)
.map(Long::valueOf)
.distinct()
.collect(Collectors.toList());
List<AccountEntity> accounts = accountGateway.listByIds(ids);
List<WpsUserCO> users = new ArrayList<>();
for (AccountEntity account : accounts) {
users.add(wpsCmdConvertor.toUserCO(account));
}
return ok(users);
} catch (BizException e) {
return fail(e);
} catch (Exception e) {
log.error("wps getUsers failed, userIds={}", userIds, e);
return fail(ErrorCode.UNKNOWN_ERROR);
}
}
@Override
public Map<String, Object> uploadPrepare(String fileId) {
try {
wpsDocDomainService.getByFileId(fileId);
Map<String, Object> data = new LinkedHashMap<>();
data.put("digest_types", Collections.singletonList("sha1"));
return ok(data);
} catch (BizException e) {
return fail(e);
}
}
@Override
public Map<String, Object> uploadAddress(String fileId, Map<String, Object> body) {
try {
wpsDocDomainService.getByFileId(fileId);
if (!StringUtils.hasText(uploadBaseUrl)) {
log.error("wps.upload-base-url is empty");
return fail(ErrorCode.UNKNOWN_ERROR);
}
String base = uploadBaseUrl.endsWith("/") ? uploadBaseUrl.substring(0, uploadBaseUrl.length() - 1) : uploadBaseUrl;
Map<String, Object> data = new LinkedHashMap<>();
data.put("url", base + "/upload/" + fileId);
data.put("method", "PUT");
return ok(data);
} catch (BizException e) {
return fail(e);
}
}
@Override
public Map<String, Object> uploadBinary(String fileId, InputStream inputStream) {
try {
wpsDocDomainService.getByFileId(fileId);
FileInfo ossFileInfo = fileStorageService.of(inputStream, fileId).upload();
FileStorage fileStorage = FileStorageHelper.buildResource(ossFileInfo, fileId, true);
FileStorage saved = fileStorageDomainService.saveResource(fileStorage);
wpsDocDomainService.savePendingUpload(fileId, saved.getId(), saved.getUrl(), saved.getSize());
log.info("wps upload binary success, fileId={}, resourceId={}, url={}", fileId, saved.getId(), saved.getUrl());
Map<String, Object> data = new LinkedHashMap<>();
data.put("status", "ok");
return ok(data);
} catch (BizException e) {
return fail(e);
} catch (Exception e) {
log.error("wps upload binary failed, fileId={}", fileId, e);
return fail(ErrorCode.FILE_UPLOAD_FAILED);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public Map<String, Object> uploadComplete(String fileId, Map<String, Object> body) {
try {
WpsDocEntity doc = wpsDocDomainService.getByFileId(fileId);
if (doc.getPendingResourceId() == null) {
throw new BizException(ErrorCode.WPS_UPLOAD_PENDING_NOT_FOUND);
}
Integer pendingResourceId = doc.getPendingResourceId();
String pendingUrl = doc.getPendingDownloadUrl();
Long pendingSize = doc.getPendingSize();
Long userId = AuthUserContextAdapter.getCurrentUserId();
String modifierId = userId == null ? doc.getModifierId() : String.valueOf(userId);
long nowEpoch = System.currentTimeMillis() / 1000;
int nextVersion = (doc.getDocVersion() == null ? 1 : doc.getDocVersion()) + 1;
String name = doc.getName();
Boolean isManual = null;
String digestSha1 = null;
if (body != null && body.get("request") instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> request = (Map<String, Object>) body.get("request");
if (request.get("name") != null) {
name = String.valueOf(request.get("name"));
}
if (request.get("is_manual") != null) {
isManual = Boolean.valueOf(String.valueOf(request.get("is_manual")));
}
Object digestObj = request.get("digest");
if (digestObj instanceof Map) {
Object sha1 = ((Map<?, ?>) digestObj).get("sha1");
if (sha1 != null) {
digestSha1 = String.valueOf(sha1);
}
}
}
doc.setName(name);
doc.setDocVersion(nextVersion);
doc.setSize(pendingSize == null ? doc.getSize() : pendingSize);
doc.setResourceId(pendingResourceId);
doc.setDownloadUrl(pendingUrl);
doc.setModifierId(modifierId);
doc.setModifyTimeEpoch(nowEpoch);
WpsDocVersionEntity versionEntity = new WpsDocVersionEntity();
versionEntity.setOrgId(doc.getOrgId());
versionEntity.setFileId(fileId);
versionEntity.setDocVersion(nextVersion);
versionEntity.setName(name);
versionEntity.setSize(doc.getSize());
versionEntity.setResourceId(pendingResourceId);
versionEntity.setDownloadUrl(pendingUrl);
versionEntity.setDigestSha1(digestSha1);
versionEntity.setModifierId(modifierId);
versionEntity.setManualFlag(Boolean.TRUE.equals(isManual) ? 1 : 2);
versionEntity.setCreateTimeEpoch(nowEpoch);
versionEntity.setTenantId(doc.getTenantId());
WpsDocEntity updated = wpsDocDomainService.completeSave(doc, versionEntity);
log.info("wps upload complete, body={}", JSON.toJSONString(body));
return ok(wpsCmdConvertor.toFileCO(updated));
} catch (BizException e) {
return fail(e);
} catch (Exception e) {
log.error("wps upload complete failed, fileId={}", fileId, e);
return fail(ErrorCode.FILE_UPLOAD_FAILED);
}
}
@Override
public Map<String, Object> listVersions(String fileId) {
try {
WpsDocEntity doc = wpsDocDomainService.getByFileId(fileId);
List<WpsDocVersionEntity> versions = wpsDocDomainService.listVersions(fileId);
List<WpsFileCO> list = new ArrayList<>();
for (WpsDocVersionEntity version : versions) {
WpsFileCO co = wpsCmdConvertor.toFileCO(version);
co.setCreatorId(doc.getCreatorId());
co.setModifierId(version.getModifierId());
list.add(co);
}
return ok(list);
} catch (BizException e) {
return fail(e);
}
}
@Override
public Map<String, Object> getVersion(String fileId, Integer version) {
try {
WpsDocEntity doc = wpsDocDomainService.getByFileId(fileId);
WpsDocVersionEntity versionEntity = wpsDocDomainService.getVersion(fileId, version);
WpsFileCO co = wpsCmdConvertor.toFileCO(versionEntity);
co.setCreatorId(doc.getCreatorId());
co.setModifierId(versionEntity.getModifierId());
return ok(co);
} catch (BizException e) {
return fail(e);
}
}
@Override
public Map<String, Object> getVersionDownload(String fileId, Integer version) {
try {
WpsDocVersionEntity versionEntity = wpsDocDomainService.getVersion(fileId, version);
Map<String, Object> data = new LinkedHashMap<>();
data.put("url", resolveDownloadUrl(versionEntity.getDownloadUrl(), versionEntity.getResourceId()));
return ok(data);
} catch (BizException e) {
return fail(e);
}
}
@Override
public Map<String, Object> rename(String fileId, Map<String, Object> body) {
try {
String name = body == null || body.get("name") == null ? null : String.valueOf(body.get("name"));
wpsDocDomainService.rename(fileId, name);
return ok(Collections.emptyMap());
} catch (BizException e) {
return fail(e);
}
}
@Override
public WpsDocOpenCO myOrCreate(String docxUrl) {
try {
Long userId = requireUserId();
String creatorId = String.valueOf(userId);
WpsDocEntity existing = wpsDocDomainService.findLatestByCreatorId(creatorId);
if (existing != null) {
return toOpenCO(existing, false);
}
WpsDocEntity created = doCreateBlankDoc(userId, docxUrl);
return toOpenCO(created, true);
} catch (Exception e) {
log.error("wps myOrCreate failed", e);
throw new BizException(ErrorCode.UNKNOWN_ERROR);
}
}
@Override
public WpsDocOpenCO createBlank(String docxUrl) {
try {
Long userId = requireUserId();
WpsDocEntity created = doCreateBlankDoc(userId, docxUrl);
return toOpenCO(created, true);
} catch (Exception e) {
log.error("wps createBlank failed", e);
throw new BizException(ErrorCode.UNKNOWN_ERROR);
}
}
protected WpsDocEntity doCreateBlankDoc(Long userId, String docxUrl) {
String resDocxUrl = !StringUtils.hasText(docxUrl) ? defDocxUrl : docxUrl;
if (!StringUtils.hasText(resDocxUrl)) {
throw new BizException(ErrorCode.WPS_BLANK_DOCX_URL_EMPTY);
}
Long orgId = requireOrgId();
String creatorId = String.valueOf(userId);
String fileId = generateFileId();
String docName = "未命名文档.docx";
long nowEpoch = System.currentTimeMillis() / 1000;
FileStorage saved;
try (InputStream inputStream = new URL(resDocxUrl).openStream()) {
FileInfo ossFileInfo = fileStorageService.of(inputStream, docName).upload();
FileStorage fileStorage = FileStorageHelper.buildResource(ossFileInfo, docName, true);
saved = fileStorageDomainService.saveResource(fileStorage);
} catch (BizException e) {
throw e;
} catch (Exception e) {
log.error("download blank docx failed, url={}", resDocxUrl, e);
throw new BizException(ErrorCode.WPS_BLANK_DOCX_DOWNLOAD_FAILED, e);
}
WpsDocEntity doc = new WpsDocEntity();
doc.setFileId(fileId);
doc.setOrgId(orgId);
doc.setName(docName);
doc.setDocVersion(1);
doc.setSize(saved.getSize() == null ? 0L : saved.getSize());
doc.setResourceId(saved.getId());
doc.setDownloadUrl(saved.getUrl());
doc.setCreatorId(creatorId);
doc.setModifierId(creatorId);
doc.setCreateTimeEpoch(nowEpoch);
doc.setModifyTimeEpoch(nowEpoch);
doc.setTenantId(AuthUserContextAdapter.getCurrentTenantId());
WpsDocVersionEntity versionEntity = new WpsDocVersionEntity();
versionEntity.setOrgId(orgId);
versionEntity.setFileId(fileId);
versionEntity.setDocVersion(1);
versionEntity.setName(docName);
versionEntity.setSize(doc.getSize());
versionEntity.setResourceId(saved.getId());
versionEntity.setDownloadUrl(saved.getUrl());
versionEntity.setModifierId(creatorId);
versionEntity.setManualFlag(1);
versionEntity.setCreateTimeEpoch(nowEpoch);
versionEntity.setTenantId(doc.getTenantId());
return wpsDocDomainService.createInitial(doc, versionEntity);
}
private WpsDocOpenCO toOpenCO(WpsDocEntity doc, boolean created) {
WpsDocOpenCO co = new WpsDocOpenCO();
co.setFileId(doc.getFileId());
co.setName(doc.getName());
co.setCreated(created);
return co;
}
private String generateFileId() {
// 字母数字,不超过 47wps + 32位uuid = 35
return "wps" + UUID.randomUUID().toString().replace("-", "");
}
private Long requireUserId() {
Long userId = AuthUserContextAdapter.getCurrentUserId();
if (userId == null) {
throw new BizException(ErrorCode.WPS_USER_NOT_LOGIN);
}
return userId;
}
private Long requireOrgId() {
Long orgId = ThreadLocalUserInfoAdapter.get();
if (orgId != null) {
return orgId;
}
if (RequestContextHolder.getRequestAttributes() instanceof ServletRequestAttributes) {
orgId = ThreadLocalUserInfoAdapter.getOrgId();
}
if (orgId == null) {
throw new BizException(ErrorCode.ORG_INFO_NOT_FOUND);
}
return orgId;
}
private String resolveDownloadUrl(String downloadUrl, Integer resourceId) {
if (StringUtils.hasText(downloadUrl)) {
return downloadUrl;
}
if (resourceId == null) {
throw new BizException(ErrorCode.FILE_NOT_FOUND);
}
FileStorage resource = fileStorageDomainService.getResource(resourceId);
return resource.getUrl();
}
private Map<String, Object> ok(Object data) {
Map<String, Object> resp = new LinkedHashMap<>();
resp.put("code", 0);
resp.put("data", data);
return resp;
}
private Map<String, Object> fail(BizException e) {
Map<String, Object> resp = new LinkedHashMap<>();
resp.put("code", toWpsCode(e.getCode()));
resp.put("message", e.getMessage());
return resp;
}
private Map<String, Object> fail(ErrorCode errorCode) {
Map<String, Object> resp = new LinkedHashMap<>();
resp.put("code", toWpsCode(errorCode.getCode()));
resp.put("message", errorCode.getMessage());
return resp;
}
private int toWpsCode(String errorCode) {
if (ErrorCode.WPS_DOC_NOT_FOUND.getCode().equals(errorCode)
|| ErrorCode.WPS_VERSION_NOT_FOUND.getCode().equals(errorCode)
|| ErrorCode.FILE_NOT_FOUND.getCode().equals(errorCode)) {
return 40004;
}
if (ErrorCode.WPS_USER_NOT_LOGIN.getCode().equals(errorCode)) {
return 40005;
}
return 40001;
}
}

View File

@ -1,14 +1,32 @@
package org.qinan.safetyeval.app.review.executor.command;
import com.alibaba.cola.exception.BizException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.AllArgsConstructor;
import org.qinan.safetyeval.app.change.convertor.*;
import org.qinan.safetyeval.app.executor.QualFilingChangeExecutor;
import org.qinan.safetyeval.app.file.convertor.QualOnSiteReviewFileCmdConvertor;
import org.qinan.safetyeval.app.review.convertor.QualOnSiteReviewCmdConvertor;
import org.qinan.safetyeval.client.dto.AggregationSaveOrEditQualFilingChangeCmd;
import org.qinan.safetyeval.client.file.request.QualOnSiteReviewFileAddCmd;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewResultUploadCmd;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewUpdateCmd;
import org.qinan.safetyeval.domain.constant.QualFilingStatusEnum;
import org.qinan.safetyeval.domain.constant.QualOnSiteReviewStatusEnum;
import org.qinan.safetyeval.domain.entity.QualFilingEntity;
import org.qinan.safetyeval.domain.file.model.QualOnSiteReviewFileE;
import org.qinan.safetyeval.domain.gateway.QualFilingGateway;
import org.qinan.safetyeval.domain.review.ability.QualOnSiteReviewAbility;
import org.qinan.safetyeval.domain.review.model.QualOnSiteReviewE;
import org.qinan.safetyeval.infrastructure.dataobject.*;
import org.qinan.safetyeval.infrastructure.mapper.*;
import org.qinan.safetyeval.infrastructure.persistence.domainobject.QualOnSiteReviewDO;
import org.qinan.safetyeval.infrastructure.persistence.queryservice.QualOnSiteReviewQueryService;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.List;
/**
*
@ -22,6 +40,19 @@ public class QualOnSiteReviewUpdateCmdExe {
private final QualOnSiteReviewQueryService qualOnSiteReviewQueryService;
private final QualOnSiteReviewCmdConvertor qualOnSiteReviewCmdConvertor;
private final QualOnSiteReviewAbility qualOnSiteReviewAbility;
private final QualOnSiteReviewFileCmdConvertor qualOnSiteReviewFileCmdConvertor;
private final QualFilingGateway qualFilingGateway;
private final QualFilingMapper qualFilingMapper;
private final QualFilingCommitmentMapper qualFilingCommitmentMapper;
private final QualFilingEquipmentMapper qualFilingEquipmentMapper;
private final QualFilingMaterialMapper qualFilingMaterialMapper;
private final QualFilingPersonnelMapper qualFilingPersonnelMapper;
private final QualFilingChangeExecutor qualFilingChangeExecutor;
private final QualFilingChangeCmdConvertor qualFilingChangeCmdConvertor;
private final QualFilingCommitmentChangeCmdConvertor qualFilingCommitmentChangeCmdConvertor;
private final QualFilingEquipmentChangeCmdConvertor qualFilingEquipmentChangeCmdConvertor;
private final QualFilingMaterialChangeCmdConvertor qualFilingMaterialChangeCmdConvertor;
private final QualFilingPersonnelChangeCmdConvertor qualFilingPersonnelChangeCmdConvertor;
/**
*
@ -38,4 +69,100 @@ public class QualOnSiteReviewUpdateCmdExe {
}
return true;
}
/**
*
* <p>
* 1. (/)
* 2.
* 3.
*
* @param cmd
* @return
*/
@Transactional(rollbackFor = Exception.class)
public boolean execute(QualOnSiteReviewResultUploadCmd cmd) {
QualOnSiteReviewDO reviewDO = qualOnSiteReviewQueryService.getById(cmd.getId());
if (reviewDO == null) {
throw new BizException("资质现场核查记录不存在");
}
// 解析审查结论
boolean passed = cmd.getReviewResult();
String status = passed ? QualOnSiteReviewStatusEnum.REVIEW_PASSED.getCode()
: QualOnSiteReviewStatusEnum.REVIEW_FAILED.getCode();
// 更新现场核查状态及审查意见
QualOnSiteReviewE reviewE = QualOnSiteReviewE.of();
reviewE.setId(cmd.getId());
reviewE.setStatus(status);
reviewE.setReviewOpinion(cmd.getReviewOpinion());
Boolean updateRes = reviewE.update();
if (!updateRes) {
throw new BizException("数据已被更新,请刷新重试");
}
// 审查通过时,更新备案状态为已备案
if (passed && reviewDO.getBizId() != null) {
QualFilingEntity filingEntity = new QualFilingEntity();
filingEntity.setId(reviewDO.getBizId());
filingEntity.setFilingStatusCode(QualFilingStatusEnum.FILED.getCode());
filingEntity.setFilingStatusName(QualFilingStatusEnum.FILED.getName());
qualFilingGateway.modify(filingEntity);
// 审核通过,同步生成资质变更记录
passedSaveToChange(reviewDO.getOrgId());
}
// 保存审查结果文件
saveFileList(cmd.getId(), cmd.getFileList());
return true;
}
private void saveFileList(Long reviewId, List<QualOnSiteReviewFileAddCmd> fileList) {
if (CollectionUtils.isEmpty(fileList)) {
return;
}
for (QualOnSiteReviewFileAddCmd fileCmd : fileList) {
QualOnSiteReviewFileE fileE = qualOnSiteReviewFileCmdConvertor.convertCmdToE(fileCmd);
fileE.setQualOnSiteReviewId(reviewId);
boolean res = fileE.add();
if (!res) {
throw new BizException("审查结果文件保存失败");
}
}
}
private void passedSaveToChange(Long orgId) {
// 基本信息
QualFilingDO qualFilingDO = qualFilingMapper.selectByOrgIdLastOne(orgId);
if (qualFilingDO == null) {
throw new BizException("未找到该机构的资质备案记录");
}
Long filingId = qualFilingDO.getId();
// 审核通过,需要新增资质变更记录
AggregationSaveOrEditQualFilingChangeCmd cmdSync = new AggregationSaveOrEditQualFilingChangeCmd();
cmdSync.setQualFilingChangeAddCmd(qualFilingChangeCmdConvertor.convertDOToCmd(qualFilingDO));
// 备案承诺书
QualFilingCommitmentDO qualFilingCommitmentDO = qualFilingCommitmentMapper.selectOne(new LambdaQueryWrapper<QualFilingCommitmentDO>()
.eq(QualFilingCommitmentDO::getFilingId, filingId));
cmdSync.setQualFilingCommitmentChangeAddCmd(qualFilingCommitmentChangeCmdConvertor.convertDOToCmd(qualFilingCommitmentDO));
// 备案装备
List<QualFilingEquipmentDO> qualFilingEquipmentDOs = qualFilingEquipmentMapper.selectList(new LambdaQueryWrapper<QualFilingEquipmentDO>()
.eq(QualFilingEquipmentDO::getFilingId, filingId));
cmdSync.setQualFilingEquipmentChangeAddCmds(qualFilingEquipmentChangeCmdConvertor.convertDOListToCmdList(qualFilingEquipmentDOs));
// 备案材料清单
List<QualFilingMaterialDO> qualFilingMaterialDOs = qualFilingMaterialMapper.selectList(new LambdaQueryWrapper<QualFilingMaterialDO>()
.eq(QualFilingMaterialDO::getFilingId, filingId));
cmdSync.setQualFilingMaterialChangeAddCmds(qualFilingMaterialChangeCmdConvertor.convertDOListToCmdList(qualFilingMaterialDOs));
// 备案人员
List<QualFilingPersonnelDO> qualFilingPersonnelDOs = qualFilingPersonnelMapper.selectList(new LambdaQueryWrapper<QualFilingPersonnelDO>()
.eq(QualFilingPersonnelDO::getFilingId, filingId));
cmdSync.setQualFilingPersonnelChangeAddCmds(qualFilingPersonnelChangeCmdConvertor.convertDOListToCmdList(qualFilingPersonnelDOs));
qualFilingChangeExecutor.aggregationSaveOrEdit(cmdSync, true);
}
}

View File

@ -1,12 +1,21 @@
package org.qinan.safetyeval.app.review.executor.query;
import com.alibaba.cola.dto.PageResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewMonitorPageQry;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewOrgPageQry;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewPageQry;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewCo;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewMonitorCo;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewOrgCo;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewStatisticsCo;
import org.qinan.safetyeval.infrastructure.persistence.mapper.QualOnSiteReviewMapper;
import org.qinan.safetyeval.infrastructure.persistence.queryservice.QualOnSiteReviewQueryService;
import org.springframework.stereotype.Component;
import java.util.List;
/**
*
*
@ -18,15 +27,50 @@ import org.springframework.stereotype.Component;
public class QualOnSiteReviewPageQueryExe {
private final QualOnSiteReviewQueryService qualOnSiteReviewQueryService;
private final QualOnSiteReviewMapper qualOnSiteReviewMapper;
/**
*
*
* @param qualOnSiteReviewPageQry
* @return
* @param qualOnSiteReviewPageQry
* @return
*/
public PageResponse<QualOnSiteReviewCo> execute(QualOnSiteReviewPageQry qualOnSiteReviewPageQry) {
return qualOnSiteReviewQueryService.listQualOnSiteReviewPage(qualOnSiteReviewPageQry);
}
/**
* Co
*
* @param qry
* @return
*/
public org.qinan.safetyeval.client.dto.PageResponse<QualOnSiteReviewMonitorCo> execute(QualOnSiteReviewMonitorPageQry qry) {
Page<QualOnSiteReviewMonitorCo> page = new Page<>(qry.getCurrent(), qry.getSize());
List<QualOnSiteReviewMonitorCo> list = qualOnSiteReviewMapper.monitorPage(page, qry);
return org.qinan.safetyeval.client.dto.PageResponse.of(list, page.getTotal());
}
/**
* IDCo
*
* @param qry
* @return
*/
public org.qinan.safetyeval.client.dto.PageResponse<QualOnSiteReviewOrgCo> execute(QualOnSiteReviewOrgPageQry qry) {
Page<QualOnSiteReviewOrgCo> page = new Page<>(qry.getCurrent(), qry.getSize());
List<QualOnSiteReviewOrgCo> list = qualOnSiteReviewMapper.orgPage(page, qry);
return org.qinan.safetyeval.client.dto.PageResponse.of(list, page.getTotal());
}
/**
*
*
* @param orgId ID
* @return
*/
public QualOnSiteReviewStatisticsCo executeStatistics(Long orgId) {
return qualOnSiteReviewMapper.statistics(orgId);
}
}

View File

@ -2,9 +2,15 @@ package org.qinan.safetyeval.app.review.service;
import com.alibaba.cola.dto.PageResponse;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewAddCmd;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewMonitorPageQry;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewOrgPageQry;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewPageQry;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewResultUploadCmd;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewUpdateCmd;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewCo;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewMonitorCo;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewOrgCo;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewStatisticsCo;
/**
*
@ -21,6 +27,22 @@ public interface QualOnSiteReviewServiceI {
*/
PageResponse<QualOnSiteReviewCo> listQualOnSiteReviewPage(QualOnSiteReviewPageQry qualOnSiteReviewPageQry);
/**
*
*
* @param qualOnSiteReviewMonitorPageQry
* @return
*/
org.qinan.safetyeval.client.dto.PageResponse<QualOnSiteReviewMonitorCo> monitorPage(QualOnSiteReviewMonitorPageQry qualOnSiteReviewMonitorPageQry);
/**
* ID
*
* @param qualOnSiteReviewOrgPageQry
* @return
*/
org.qinan.safetyeval.client.dto.PageResponse<QualOnSiteReviewOrgCo> orgPage(QualOnSiteReviewOrgPageQry qualOnSiteReviewOrgPageQry);
/**
* ID
*
@ -61,5 +83,21 @@ public interface QualOnSiteReviewServiceI {
*/
boolean deletedQualOnSiteReviewByIds(Long[] ids);
/**
*
*
* @param qualOnSiteReviewResultUploadCmd
* @return
*/
boolean uploadReviewResult(QualOnSiteReviewResultUploadCmd qualOnSiteReviewResultUploadCmd);
/**
*
*
* @param orgId ID
* @return
*/
QualOnSiteReviewStatisticsCo statistics(Long orgId);
}

View File

@ -9,9 +9,15 @@ import org.qinan.safetyeval.app.review.executor.query.QualOnSiteReviewListQueryE
import org.qinan.safetyeval.app.review.executor.query.QualOnSiteReviewPageQueryExe;
import org.qinan.safetyeval.app.review.service.QualOnSiteReviewServiceI;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewAddCmd;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewMonitorPageQry;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewOrgPageQry;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewPageQry;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewResultUploadCmd;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewUpdateCmd;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewCo;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewMonitorCo;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewOrgCo;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewStatisticsCo;
import org.springframework.stereotype.Service;
/**
@ -35,6 +41,16 @@ public class QualOnSiteReviewServiceImpl implements QualOnSiteReviewServiceI {
return qualOnSiteReviewPageQueryExe.execute(qualOnSiteReviewPageQry);
}
@Override
public org.qinan.safetyeval.client.dto.PageResponse<QualOnSiteReviewMonitorCo> monitorPage(QualOnSiteReviewMonitorPageQry qualOnSiteReviewMonitorPageQry) {
return qualOnSiteReviewPageQueryExe.execute(qualOnSiteReviewMonitorPageQry);
}
@Override
public org.qinan.safetyeval.client.dto.PageResponse<QualOnSiteReviewOrgCo> orgPage(QualOnSiteReviewOrgPageQry qualOnSiteReviewOrgPageQry) {
return qualOnSiteReviewPageQueryExe.execute(qualOnSiteReviewOrgPageQry);
}
@Override
public QualOnSiteReviewCo getQualOnSiteReviewById(Long id) {
return qualOnSiteReviewListQueryExe.execute(id);
@ -60,4 +76,14 @@ public class QualOnSiteReviewServiceImpl implements QualOnSiteReviewServiceI {
return qualOnSiteReviewDelCommandExe.execute(ids);
}
@Override
public boolean uploadReviewResult(QualOnSiteReviewResultUploadCmd qualOnSiteReviewResultUploadCmd) {
return qualOnSiteReviewUpdateCommandExe.execute(qualOnSiteReviewResultUploadCmd);
}
@Override
public QualOnSiteReviewStatisticsCo statistics(Long orgId) {
return qualOnSiteReviewPageQueryExe.executeStatistics(orgId);
}
}

View File

@ -0,0 +1,49 @@
package org.qinan.safetyeval.client.api;
import org.qinan.safetyeval.client.co.WpsDocOpenCO;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
/**
* WPS WebOffice Client
*
* @author safety-eval
*/
public interface WpsApi {
Map<String, Object> getFileInfo(String fileId);
Map<String, Object> getDownload(String fileId);
Map<String, Object> getPermission(String fileId);
Map<String, Object> getUsers(List<String> userIds);
Map<String, Object> uploadPrepare(String fileId);
Map<String, Object> uploadAddress(String fileId, Map<String, Object> body);
Map<String, Object> uploadComplete(String fileId, Map<String, Object> body);
Map<String, Object> uploadBinary(String fileId, InputStream inputStream);
Map<String, Object> listVersions(String fileId);
Map<String, Object> getVersion(String fileId, Integer version);
Map<String, Object> getVersionDownload(String fileId, Integer version);
Map<String, Object> rename(String fileId, Map<String, Object> body);
/**
* docx
*/
WpsDocOpenCO myOrCreate(String docxUrl);
/**
* docx使
*/
WpsDocOpenCO createBlank(String docxUrl);
}

View File

@ -0,0 +1,23 @@
package org.qinan.safetyeval.client.co;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* / WPS
*
* @author safety-eval
*/
@Data
public class WpsDocOpenCO {
/** WPS file_id唯一 */
@ApiModelProperty(value = "WPS file_id唯一")
private String fileId;
/** 文档名称 */
@ApiModelProperty(value = "文档名称")
private String name;
/** 是否本次新建 */
@ApiModelProperty(value = "是否本次新建")
private Boolean created;
}

View File

@ -0,0 +1,30 @@
package org.qinan.safetyeval.client.co;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* WPS CO snake_case
*
* @author safety-eval
*/
@Data
public class WpsFileCO {
private String id;
private String name;
private Integer version;
private Long size;
@JsonProperty("create_time")
private Long createTime;
@JsonProperty("modify_time")
private Long modifyTime;
@JsonProperty("creator_id")
private String creatorId;
@JsonProperty("modifier_id")
private String modifierId;
}

View File

@ -0,0 +1,26 @@
package org.qinan.safetyeval.client.co;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* WPS CO permission
*
* @author safety-eval
*/
@Data
public class WpsPermissionCO {
@JsonProperty("user_id")
private String userId;
private Integer read;
private Integer update;
private Integer download;
private Integer rename;
private Integer history;
private Integer copy;
private Integer print;
private Integer saveas;
private Integer comment;
}

View File

@ -0,0 +1,19 @@
package org.qinan.safetyeval.client.co;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* WPS CO
*
* @author safety-eval
*/
@Data
public class WpsUserCO {
private String id;
private String name;
@JsonProperty("avatar_url")
private String avatarUrl;
}

View File

@ -32,4 +32,10 @@ public class QualOnSiteReviewFileAddCmd implements Serializable {
@NotBlank(message = "文件url不能为空")
@Size(max = 1024, message = "文件url不能超过1024个字符")
private String fileUrl;
/**
*
*/
@ApiModelProperty(value = "审查意见")
private String reviewOpinion;
}

View File

@ -36,4 +36,10 @@ public class QualOnSiteReviewFileUpdateCmd implements Serializable {
@NotBlank(message = "文件url不能为空")
@Size(max = 1024, message = "文件url不能超过1024个字符")
private String fileUrl;
/**
*
*/
@ApiModelProperty(value = "审查意见")
private String reviewOpinion;
}

View File

@ -31,6 +31,11 @@ public class QualOnSiteReviewFileCo extends ClientObject {
*/
@ApiModelProperty(value = "文件url")
private String fileUrl;
/**
*
*/
@ApiModelProperty(value = "审查意见")
private String reviewOpinion;
/**
*
*/

View File

@ -2,8 +2,10 @@ package org.qinan.safetyeval.client.review.request;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.qinan.safetyeval.domain.constant.QualOnSiteReviewStatusEnum;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.time.LocalDateTime;
@ -21,7 +23,14 @@ public class QualOnSiteReviewAddCmd implements Serializable {
* :add change:
*/
@ApiModelProperty(value = "资质类型:add 新增 change:变更")
@Size(max = 64, message = "资质类型不能超过64个字符")
private String bizType;
/**
* ID ()
*/
@ApiModelProperty(value = "受审查机构ID (关联机构表)", required = true)
@NotNull(message = "受审查机构ID不能为空")
private Long orgId;
/**
* id
*/
@ -37,11 +46,13 @@ public class QualOnSiteReviewAddCmd implements Serializable {
*
*/
@ApiModelProperty(value = "审查地点")
@Size(max = 512, message = "审查地点不能超过512个字符")
private String reviewLocation;
/**
*
*/
@ApiModelProperty(value = "审查组成员名单")
@Size(max = 512, message = "审查组成员名单不能超过512个字符")
private String reviewMembers;
/**
*
@ -52,22 +63,25 @@ public class QualOnSiteReviewAddCmd implements Serializable {
*
*/
@ApiModelProperty(value = "监管联系人姓名")
@Size(max = 64, message = "监管联系人姓名不能超过64个字符")
private String supervisorContact;
/**
*
*/
@ApiModelProperty(value = "监管联系电话")
@Size(max = 32, message = "监管联系电话不能超过32个字符")
private String contactPhone;
/**
* (AGENCY_PENDING_CONFIRMATIONAGENCY_CONFIRMEDREVIEW_PASSEDREVIEW_FAILED)
*/
@ApiModelProperty(value = "现场审查状态(AGENCY_PENDING_CONFIRMATION机构待确认、AGENCY_CONFIRMED机构已确认、REVIEW_PASSED核查通过、REVIEW_FAILED核查不通过)", required = true)
@NotNull(message = "现场审查状态(AGENCY_PENDING_CONFIRMATION机构待确认、AGENCY_CONFIRMED机构已确认、REVIEW_PASSED核查通过、REVIEW_FAILED核查不通过)不能为空")
private Long status;
@ApiModelProperty(value = QualOnSiteReviewStatusEnum.REMARKS, required = true)
@NotNull(message = "现场审查状态不能为空")
@Size(max = 64, message = "现场审查状态不能超过64个字符")
private String status;
/**
*
*
*/
@ApiModelProperty(value = "环境")
private String env;
@ApiModelProperty(value = "审查意见")
@Size(max = 256, message = "审查意见不能超过256个字符")
private String reviewOpinion;
}

View File

@ -0,0 +1,45 @@
package org.qinan.safetyeval.client.review.request;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.qinan.safetyeval.client.dto.BasePageQuery;
import java.time.LocalDateTime;
/**
* Qry
*
* @Author: ltq
* @date 2026-07-20 15:17:00
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class QualOnSiteReviewMonitorPageQry extends BasePageQuery {
private static final long serialVersionUID = 1L;
/**
* ()
*/
@ApiModelProperty(value = "机构名称(模糊查询)")
private String unitName;
/**
* (AGENCY_PENDING_CONFIRMATIONAGENCY_CONFIRMEDREVIEW_PASSEDREVIEW_FAILED)
*/
@ApiModelProperty(value = "现场审查状态(AGENCY_PENDING_CONFIRMATION机构待确认、AGENCY_CONFIRMED机构已确认、REVIEW_PASSED核查通过、REVIEW_FAILED核查不通过)")
private String status;
/**
* -
*/
@ApiModelProperty(value = "现场审查开始时间-起始")
private LocalDateTime reviewDateStartBegin;
/**
* -
*/
@ApiModelProperty(value = "现场审查开始时间-结束")
private LocalDateTime reviewDateStartEnd;
}

View File

@ -0,0 +1,47 @@
package org.qinan.safetyeval.client.review.request;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.qinan.safetyeval.client.dto.BasePageQuery;
import java.time.LocalDateTime;
/**
* Qry
*
* @Author: ltq
* @date 2026-07-20 15:17:00
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class QualOnSiteReviewOrgPageQry extends BasePageQuery {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ApiModelProperty(value = "机构ID", hidden = true)
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Long orgId;
/**
* (AGENCY_PENDING_CONFIRMATIONAGENCY_CONFIRMEDREVIEW_PASSEDREVIEW_FAILED)
*/
@ApiModelProperty(value = "现场审查状态(AGENCY_PENDING_CONFIRMATION机构待确认、AGENCY_CONFIRMED机构已确认、REVIEW_PASSED核查通过、REVIEW_FAILED核查不通过)")
private String status;
/**
* -
*/
@ApiModelProperty(value = "现场审查开始时间-起始")
private LocalDateTime reviewDateStartBegin;
/**
* -
*/
@ApiModelProperty(value = "现场审查开始时间-结束")
private LocalDateTime reviewDateStartEnd;
}

View File

@ -50,7 +50,7 @@ public class QualOnSiteReviewPageQry extends PageQuery {
* (AGENCY_PENDING_CONFIRMATIONAGENCY_CONFIRMEDREVIEW_PASSEDREVIEW_FAILED)
*/
@ApiModelProperty(value = "现场审查状态(AGENCY_PENDING_CONFIRMATION机构待确认、AGENCY_CONFIRMED机构已确认、REVIEW_PASSED核查通过、REVIEW_FAILED核查不通过)")
private Long status;
private String status;
/**
*
*/

View File

@ -0,0 +1,43 @@
package org.qinan.safetyeval.client.review.request;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.qinan.safetyeval.client.file.request.QualOnSiteReviewFileAddCmd;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.List;
/**
* -Cmd
*
* @Author: ltq
* @date 2026-07-20 15:17:00
*/
@Data
public class QualOnSiteReviewResultUploadCmd implements Serializable {
private static final long serialVersionUID = 1L;
@JsonFormat(shape = JsonFormat.Shape.STRING)
@NotNull(message = "资质现场核查id不能为空")
@ApiModelProperty(value = "资质现场核查id", required = true)
private Long id;
@NotBlank(message = "审查结论不能为空")
@ApiModelProperty(value = "审查结论:true通过/false不通过", required = true)
@NotNull
private Boolean reviewResult;
@ApiModelProperty(value = "审查意见")
private String reviewOpinion;
@ApiModelProperty(value = "审查结果文件")
@NotNull
@Size(max = 100)
@Valid
private List<QualOnSiteReviewFileAddCmd> fileList;
}

View File

@ -3,8 +3,10 @@ package org.qinan.safetyeval.client.review.request;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.qinan.safetyeval.domain.constant.QualOnSiteReviewStatusEnum;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.time.LocalDateTime;
@ -18,11 +20,13 @@ import java.time.LocalDateTime;
public class QualOnSiteReviewUpdateCmd implements Serializable {
private static final long serialVersionUID = 1L;
@JsonFormat(shape = JsonFormat.Shape.STRING)
@NotNull(message = "id不能为空")
private Long id;
/**
* :add change:
*/
@ApiModelProperty(value = "资质类型:add 新增 change:变更")
@Size(max = 64, message = "资质类型不能超过64个字符")
private String bizType;
/**
* id
@ -33,17 +37,20 @@ public class QualOnSiteReviewUpdateCmd implements Serializable {
*
*/
@ApiModelProperty(value = "现场审查开始时间", required = true)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
@NotNull(message = "现场审查开始时间不能为空")
private LocalDateTime reviewDateStart;
/**
*
*/
@ApiModelProperty(value = "审查地点")
@Size(max = 512, message = "审查地点不能超过512个字符")
private String reviewLocation;
/**
*
*/
@ApiModelProperty(value = "审查组成员名单")
@Size(max = 512, message = "审查组成员名单不能超过512个字符")
private String reviewMembers;
/**
*
@ -54,24 +61,25 @@ public class QualOnSiteReviewUpdateCmd implements Serializable {
*
*/
@ApiModelProperty(value = "监管联系人姓名")
@Size(max = 64, message = "监管联系人姓名不能超过64个字符")
private String supervisorContact;
/**
*
*/
@ApiModelProperty(value = "监管联系电话")
@Size(max = 32, message = "监管联系电话不能超过32个字符")
private String contactPhone;
/**
* (AGENCY_PENDING_CONFIRMATIONAGENCY_CONFIRMEDREVIEW_PASSEDREVIEW_FAILED)
*/
@ApiModelProperty(value = "现场审查状态(AGENCY_PENDING_CONFIRMATION机构待确认、AGENCY_CONFIRMED机构已确认、REVIEW_PASSED核查通过、REVIEW_FAILED核查不通过)", required = true)
@NotNull(message = "现场审查状态(AGENCY_PENDING_CONFIRMATION机构待确认、AGENCY_CONFIRMED机构已确认、REVIEW_PASSED核查通过、REVIEW_FAILED核查不通过)不能为空")
private Long status;
@ApiModelProperty(value = QualOnSiteReviewStatusEnum.REMARKS, required = true)
@NotNull(message = QualOnSiteReviewStatusEnum.REMARKS + "不能为空")
@Size(max = 64, message = "现场审查状态不能超过64个字符")
private String status;
/**
*
*
*/
@ApiModelProperty(value = "环境")
private String env;
@NotNull(message = "version不能为空")
@ApiModelProperty(value = "version")
private Integer version;
@ApiModelProperty(value = "审查意见")
@Size(max = 256, message = "审查意见不能超过256个字符")
private String reviewOpinion;
}

View File

@ -23,6 +23,12 @@ public class QualOnSiteReviewCo extends ClientObject {
*/
@ApiModelProperty(value = "资质类型:add 新增 change:变更")
private String bizType;
/**
* ID ()
*/
@ApiModelProperty(value = "受审查机构ID (关联机构表)")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Long orgId;
/**
* id
*/
@ -63,7 +69,12 @@ public class QualOnSiteReviewCo extends ClientObject {
* (AGENCY_PENDING_CONFIRMATIONAGENCY_CONFIRMEDREVIEW_PASSEDREVIEW_FAILED)
*/
@ApiModelProperty(value = "现场审查状态(AGENCY_PENDING_CONFIRMATION机构待确认、AGENCY_CONFIRMED机构已确认、REVIEW_PASSED核查通过、REVIEW_FAILED核查不通过)")
private Long status;
private String status;
/**
*
*/
@ApiModelProperty(value = "审查意见")
private String reviewOpinion;
/**
*
*/

View File

@ -0,0 +1,89 @@
package org.qinan.safetyeval.client.review.response;
import com.alibaba.cola.dto.ClientObject;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* Co
*
* @Author: ltq
* @date 2026-07-20 15:17:00
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class QualOnSiteReviewMonitorCo extends ClientObject {
private static final long serialVersionUID = 1L;
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Long id;
/**
* :add change:
*/
@ApiModelProperty(value = "资质类型:add 新增 change:变更")
private String bizType;
/**
* id
*/
@ApiModelProperty(value = "业务id")
private Long bizId;
/**
*
*/
@ApiModelProperty(value = "现场审查开始时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime reviewDateStart;
/**
*
*/
@ApiModelProperty(value = "审查地点")
private String reviewLocation;
/**
*
*/
@ApiModelProperty(value = "审查组成员名单")
private String reviewMembers;
/**
*
*/
@ApiModelProperty(value = "材料准备要求")
private String materialRequirements;
/**
*
*/
@ApiModelProperty(value = "监管联系人姓名")
private String supervisorContact;
/**
*
*/
@ApiModelProperty(value = "监管联系电话")
private String contactPhone;
/**
* (AGENCY_PENDING_CONFIRMATIONAGENCY_CONFIRMEDREVIEW_PASSEDREVIEW_FAILED)
*/
@ApiModelProperty(value = "现场审查状态(AGENCY_PENDING_CONFIRMATION机构待确认、AGENCY_CONFIRMED机构已确认、REVIEW_PASSED核查通过、REVIEW_FAILED核查不通过)")
private String status;
/**
*
*/
@ApiModelProperty(value = "审查意见")
private String reviewOpinion;
/**
*
*/
@ApiModelProperty(value = "环境")
private String env;
@ApiModelProperty(value = "version")
private Integer version;
/**
*
*/
@ApiModelProperty(value = "机构名称")
private String unitName;
}

View File

@ -0,0 +1,81 @@
package org.qinan.safetyeval.client.review.response;
import com.alibaba.cola.dto.ClientObject;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
/**
* Co
*
* @Author: ltq
* @date 2026-07-20 15:17:00
*/
@Data
public class QualOnSiteReviewOrgCo extends ClientObject {
private static final long serialVersionUID = 1L;
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Long id;
/**
* :add change:
*/
@ApiModelProperty(value = "资质类型:add 新增 change:变更")
private String bizType;
/**
* id
*/
@ApiModelProperty(value = "业务id")
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Long bizId;
/**
*
*/
@ApiModelProperty(value = "现场审查开始时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime reviewDateStart;
/**
*
*/
@ApiModelProperty(value = "审查地点")
private String reviewLocation;
/**
*
*/
@ApiModelProperty(value = "审查组成员名单")
private String reviewMembers;
/**
*
*/
@ApiModelProperty(value = "材料准备要求")
private String materialRequirements;
/**
*
*/
@ApiModelProperty(value = "监管联系人姓名")
private String supervisorContact;
/**
*
*/
@ApiModelProperty(value = "监管联系电话")
private String contactPhone;
/**
* (AGENCY_PENDING_CONFIRMATIONAGENCY_CONFIRMEDREVIEW_PASSEDREVIEW_FAILED)
*/
@ApiModelProperty(value = "现场审查状态(AGENCY_PENDING_CONFIRMATION机构待确认、AGENCY_CONFIRMED机构已确认、REVIEW_PASSED核查通过、REVIEW_FAILED核查不通过)")
private String status;
/**
*
*/
@ApiModelProperty(value = "审查意见")
private String reviewOpinion;
/**
*
*/
@ApiModelProperty(value = "环境")
private String env;
@ApiModelProperty(value = "version")
private Integer version;
}

View File

@ -0,0 +1,30 @@
package org.qinan.safetyeval.client.review.response;
import com.alibaba.cola.dto.ClientObject;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* Co
*
* @Author: ltq
* @Date: 2026-07-21
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class QualOnSiteReviewStatisticsCo extends ClientObject {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "通知总数")
private Integer totalCount;
@ApiModelProperty(value = "本年度累计")
private Integer annualCumulativeCount;
@ApiModelProperty(value = "未来30日待开展的审查")
private Integer pendingReviewNextThirtyDaysCount;
@ApiModelProperty(value = "已完成审查结果已归档")
private Integer completedArchivedCount;
}

View File

@ -0,0 +1,33 @@
package org.qinan.safetyeval.domain.entity;
import lombok.Data;
/**
* WPS 线
*
* @author safety-eval
*/
@Data
public class WpsDocEntity {
private Long id;
private String fileId;
private Long orgId;
private String name;
private Integer docVersion;
private Long size;
private Integer resourceId;
private String downloadUrl;
private String creatorId;
private String modifierId;
private Long createTimeEpoch;
private Long modifyTimeEpoch;
private Long tenantId;
/** 三阶段上传待确认 filestorage.id */
private Integer pendingResourceId;
/** 三阶段上传待确认 URL */
private String pendingDownloadUrl;
/** 三阶段上传待确认大小 */
private Long pendingSize;
}

View File

@ -0,0 +1,27 @@
package org.qinan.safetyeval.domain.entity;
import lombok.Data;
/**
* WPS
*
* @author safety-eval
*/
@Data
public class WpsDocVersionEntity {
private Long id;
private Long orgId;
private String fileId;
private Integer docVersion;
private String name;
private Long size;
private Integer resourceId;
private String downloadUrl;
private String digestSha1;
private String modifierId;
/** 1手动保存 2自动保存 */
private Integer manualFlag;
private Long createTimeEpoch;
private Long tenantId;
}

View File

@ -94,6 +94,15 @@ public enum ErrorCode {
FILE_URL_GENERATE_FAILED("03-01-007", "文件地址生成失败"),
FILE_SIZE_EXCEEDED("03-01-008", "文件大小超出限制"),
// ---- WPS ----
WPS_DOC_NOT_FOUND("05-01-001", "WPS文档不存在"),
WPS_USER_NOT_LOGIN("05-01-002", "WPS用户未登录"),
WPS_UPLOAD_PENDING_NOT_FOUND("05-01-003", "WPS上传结果不存在"),
WPS_VERSION_NOT_FOUND("05-01-004", "WPS文档版本不存在"),
WPS_DOC_NAME_INVALID("05-01-005", "WPS文档名称不合法"),
WPS_BLANK_DOCX_URL_EMPTY("05-01-006", "WPS空白模板地址未配置"),
WPS_BLANK_DOCX_DOWNLOAD_FAILED("05-01-007", "WPS空白模板下载失败"),
/**
*

View File

@ -32,6 +32,10 @@ public class QualOnSiteReviewFileE extends BaseE {
* url
*/
private String fileUrl;
/**
*
*/
private String reviewOpinion;
/**
*
*/

View File

@ -4,6 +4,8 @@ import org.qinan.safetyeval.domain.entity.AccountEntity;
import org.qinan.safetyeval.domain.query.AccountQuery;
import org.qinan.safetyeval.domain.query.PageResult;
import java.util.List;
/**
* GatewayDomain
*
@ -24,4 +26,6 @@ public interface AccountGateway {
PageResult<AccountEntity> page(AccountQuery query);
AccountEntity foundByPhone(String phone);
List<AccountEntity> listByIds(List<Long> ids);
}

View File

@ -0,0 +1,27 @@
package org.qinan.safetyeval.domain.gateway;
import org.qinan.safetyeval.domain.entity.WpsDocEntity;
/**
* WPS Gateway
*
* @author safety-eval
*/
public interface WpsDocGateway {
WpsDocEntity getByFileId(String fileId);
/**
* id
*/
WpsDocEntity getLatestByCreatorId(String creatorId);
WpsDocEntity save(WpsDocEntity entity);
WpsDocEntity modify(WpsDocEntity entity);
/**
* pending null
*/
void clearPending(Long id);
}

View File

@ -0,0 +1,19 @@
package org.qinan.safetyeval.domain.gateway;
import org.qinan.safetyeval.domain.entity.WpsDocVersionEntity;
import java.util.List;
/**
* WPS Gateway
*
* @author safety-eval
*/
public interface WpsDocVersionGateway {
WpsDocVersionEntity save(WpsDocVersionEntity entity);
WpsDocVersionEntity getByFileIdAndVersion(String fileId, Integer docVersion);
List<WpsDocVersionEntity> listByFileIdDesc(String fileId);
}

View File

@ -57,7 +57,11 @@ public class QualOnSiteReviewE extends BaseE {
/**
* (AGENCY_PENDING_CONFIRMATIONAGENCY_CONFIRMEDREVIEW_PASSEDREVIEW_FAILED)
*/
private Long status;
private String status;
/**
*
*/
private String reviewOpinion;
/**
*
*/

View File

@ -0,0 +1,108 @@
package org.qinan.safetyeval.domain.service;
import org.qinan.safetyeval.domain.entity.WpsDocEntity;
import org.qinan.safetyeval.domain.entity.WpsDocVersionEntity;
import org.qinan.safetyeval.domain.exception.BizException;
import org.qinan.safetyeval.domain.exception.ErrorCode;
import org.qinan.safetyeval.domain.gateway.WpsDocGateway;
import org.qinan.safetyeval.domain.gateway.WpsDocVersionGateway;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.List;
import java.util.regex.Pattern;
/**
* WPS
*
* @author safety-eval
*/
@Service
public class WpsDocDomainService {
private static final Pattern INVALID_NAME_CHARS = Pattern.compile("[\\\\/|:\"*?<>]");
@Resource
private WpsDocGateway wpsDocGateway;
@Resource
private WpsDocVersionGateway wpsDocVersionGateway;
public WpsDocEntity getByFileId(String fileId) {
WpsDocEntity entity = wpsDocGateway.getByFileId(fileId);
if (entity == null) {
throw new BizException(ErrorCode.WPS_DOC_NOT_FOUND);
}
return entity;
}
/**
* null
*/
public WpsDocEntity findLatestByCreatorId(String creatorId) {
return wpsDocGateway.getLatestByCreatorId(creatorId);
}
/**
* +
*/
@Transactional(rollbackFor = Exception.class)
public WpsDocEntity createInitial(WpsDocEntity doc, WpsDocVersionEntity versionEntity) {
WpsDocEntity saved = wpsDocGateway.save(doc);
versionEntity.setFileId(saved.getFileId());
versionEntity.setOrgId(saved.getOrgId());
versionEntity.setTenantId(saved.getTenantId());
wpsDocVersionGateway.save(versionEntity);
return saved;
}
public List<WpsDocVersionEntity> listVersions(String fileId) {
getByFileId(fileId);
return wpsDocVersionGateway.listByFileIdDesc(fileId);
}
public WpsDocVersionEntity getVersion(String fileId, Integer docVersion) {
getByFileId(fileId);
WpsDocVersionEntity version = wpsDocVersionGateway.getByFileIdAndVersion(fileId, docVersion);
if (version == null) {
throw new BizException(ErrorCode.WPS_VERSION_NOT_FOUND);
}
return version;
}
/**
* PUT pending
*/
public WpsDocEntity savePendingUpload(String fileId, Integer resourceId, String downloadUrl, Long size) {
WpsDocEntity doc = getByFileId(fileId);
doc.setPendingResourceId(resourceId);
doc.setPendingDownloadUrl(downloadUrl);
doc.setPendingSize(size);
return wpsDocGateway.modify(doc);
}
/**
* pending
*/
@Transactional(rollbackFor = Exception.class)
public WpsDocEntity completeSave(WpsDocEntity latest, WpsDocVersionEntity versionEntity) {
WpsDocEntity updated = wpsDocGateway.modify(latest);
wpsDocVersionGateway.save(versionEntity);
wpsDocGateway.clearPending(updated.getId());
return wpsDocGateway.getByFileId(updated.getFileId());
}
/**
*
*/
public WpsDocEntity rename(String fileId, String name) {
if (!StringUtils.hasText(name) || name.length() > 240 || INVALID_NAME_CHARS.matcher(name).find()) {
throw new BizException(ErrorCode.WPS_DOC_NAME_INVALID);
}
WpsDocEntity doc = getByFileId(fileId);
doc.setName(name.trim());
doc.setModifyTimeEpoch(System.currentTimeMillis() / 1000);
return wpsDocGateway.modify(doc);
}
}

View File

@ -0,0 +1,18 @@
package org.qinan.safetyeval.infrastructure.convertor;
import org.mapstruct.Mapper;
import org.qinan.safetyeval.domain.entity.WpsDocEntity;
import org.qinan.safetyeval.infrastructure.dataobject.WpsDocDO;
/**
* WPS Entity DO
*
* @author safety-eval
*/
@Mapper(componentModel = "spring")
public interface WpsDocDoConvertor {
WpsDocDO toDO(WpsDocEntity entity);
WpsDocEntity toEntity(WpsDocDO dataObject);
}

View File

@ -0,0 +1,22 @@
package org.qinan.safetyeval.infrastructure.convertor;
import org.mapstruct.Mapper;
import org.qinan.safetyeval.domain.entity.WpsDocVersionEntity;
import org.qinan.safetyeval.infrastructure.dataobject.WpsDocVersionDO;
import java.util.List;
/**
* WPS Entity DO
*
* @author safety-eval
*/
@Mapper(componentModel = "spring")
public interface WpsDocVersionDoConvertor {
WpsDocVersionDO toDO(WpsDocVersionEntity entity);
WpsDocVersionEntity toEntity(WpsDocVersionDO dataObject);
List<WpsDocVersionEntity> toEntityList(List<WpsDocVersionDO> dataObjects);
}

View File

@ -0,0 +1,47 @@
package org.qinan.safetyeval.infrastructure.dataobject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* WPS DO
*
* @author safety-eval
*/
@Data
@TableName("wps_doc")
public class WpsDocDO {
@TableId(type = IdType.AUTO)
private Long id;
private String fileId;
private Long orgId;
private String name;
private Integer docVersion;
private Long size;
private Integer resourceId;
private String downloadUrl;
private String creatorId;
private String modifierId;
private Long createTimeEpoch;
private Long modifyTimeEpoch;
private String deleteEnum;
private String remarks;
private String createName;
private String updateName;
private Long tenantId;
private Integer version;
private LocalDateTime createTime;
private LocalDateTime updateTime;
private Long createId;
private Long updateId;
private String env;
private Integer pendingResourceId;
private String pendingDownloadUrl;
private Long pendingSize;
}

View File

@ -0,0 +1,36 @@
package org.qinan.safetyeval.infrastructure.dataobject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* WPS DO
*
* @author safety-eval
*/
@Data
@TableName("wps_doc_version")
public class WpsDocVersionDO {
@TableId(type = IdType.AUTO)
private Long id;
private Long orgId;
private String fileId;
private Integer docVersion;
private String name;
private Long size;
private Integer resourceId;
private String downloadUrl;
private String digestSha1;
private String modifierId;
private Integer manualFlag;
private Long createTimeEpoch;
private String deleteEnum;
private Long tenantId;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}

View File

@ -109,6 +109,19 @@ public class AccountGatewayImpl implements AccountGateway {
return toEntity(dataObject);
}
@Override
public List<AccountEntity> listByIds(List<Long> ids) {
if (ids == null || ids.isEmpty()) {
return java.util.Collections.emptyList();
}
LambdaQueryWrapper<AccountDO> wrapper = new LambdaQueryWrapper<>();
wrapper.in(AccountDO::getId, ids);
wrapper.eq(AccountDO::getDeleteEnum, "false");
return accountMapper.selectList(wrapper).stream()
.map(this::toEntity)
.collect(Collectors.toList());
}
private AccountDO toDO(AccountEntity entity) {
AccountDO dataObject = new AccountDO();
dataObject.setUserName(entity.getUserName());

View File

@ -8,8 +8,8 @@ import org.qinan.safetyeval.domain.entity.*;
import org.qinan.safetyeval.domain.exception.BizException;
import org.qinan.safetyeval.domain.exception.ErrorCode;
import org.qinan.safetyeval.domain.gateway.QualFilingGateway;
import org.qinan.safetyeval.domain.query.QualFilingQuery;
import org.qinan.safetyeval.domain.query.PageResult;
import org.qinan.safetyeval.domain.query.QualFilingQuery;
import org.qinan.safetyeval.infrastructure.dataobject.*;
import org.qinan.safetyeval.infrastructure.mapper.*;
import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults;
@ -71,7 +71,8 @@ public class QualFilingGatewayImpl implements QualFilingGateway {
QualFilingDO dataObject = qualFilingMapper.selectById(id);
return toEntity(dataObject);
}
@Override
@Override
public QualFilingEntity getByFilingNo(String filingNo) {
LambdaQueryWrapper<QualFilingDO> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(QualFilingDO::getFilingNo, filingNo);
@ -156,11 +157,12 @@ public class QualFilingGatewayImpl implements QualFilingGateway {
/**
*
* @param entity
* @param commitmentEntity
* @param equipmentEntities
* @param materialEntities
* @param personnelEntities
*
* @param entity
* @param commitmentEntity
* @param equipmentEntities
* @param materialEntities
* @param personnelEntities
* @param personnelCertEntities
*/
@ -257,12 +259,13 @@ public class QualFilingGatewayImpl implements QualFilingGateway {
/**
*
* @param filingId id
* @param reviewResult (123)
*
* @param filingId id
* @param reviewResult (123)
* @param reviewResultRemark
* @param filingExpertId id
* @param filingExpertName
* @param reviewOpinion
* @param filingExpertId id
* @param filingExpertName
* @param reviewOpinion
*/
@Override
public void review(Long filingId, String reviewResult, String reviewResultRemark, Long filingExpertId, String filingExpertName, String reviewOpinion) {
@ -279,6 +282,8 @@ public class QualFilingGatewayImpl implements QualFilingGateway {
// 更新备案状态
QualFilingDO filing = new QualFilingDO();
QualFilingStatusEnum qualFilingStatusEnum = QualFilingStatusEnum.ofCode(Integer.valueOf(reviewResult));
qualFilingStatusEnum = qualFilingStatusEnum == QualFilingStatusEnum.FILED
? QualFilingStatusEnum.CONDITION_COMPLIANCE_PASS : qualFilingStatusEnum;
filing.setFilingStatusCode(qualFilingStatusEnum.getCode());
filing.setFilingStatusName(qualFilingStatusEnum.getName());
filing.setApproveTime(LocalDateTime.now());

View File

@ -0,0 +1,74 @@
package org.qinan.safetyeval.infrastructure.gatewayimpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.qinan.safetyeval.domain.entity.WpsDocEntity;
import org.qinan.safetyeval.domain.gateway.WpsDocGateway;
import org.qinan.safetyeval.infrastructure.convertor.WpsDocDoConvertor;
import org.qinan.safetyeval.infrastructure.dataobject.WpsDocDO;
import org.qinan.safetyeval.infrastructure.mapper.WpsDocMapper;
import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.LocalDateTime;
/**
* WPS Gateway
*
* @author safety-eval
*/
@Component
public class WpsDocGatewayImpl implements WpsDocGateway {
@Resource
private WpsDocMapper wpsDocMapper;
@Resource
private WpsDocDoConvertor wpsDocDoConvertor;
@Override
public WpsDocEntity getByFileId(String fileId) {
LambdaQueryWrapper<WpsDocDO> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(WpsDocDO::getFileId, fileId);
wrapper.eq(WpsDocDO::getDeleteEnum, "false");
return wpsDocDoConvertor.toEntity(wpsDocMapper.selectOne(wrapper));
}
@Override
public WpsDocEntity getLatestByCreatorId(String creatorId) {
LambdaQueryWrapper<WpsDocDO> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(WpsDocDO::getCreatorId, creatorId);
wrapper.eq(WpsDocDO::getDeleteEnum, "false");
wrapper.orderByDesc(WpsDocDO::getId);
wrapper.last("limit 1");
return wpsDocDoConvertor.toEntity(wpsDocMapper.selectOne(wrapper));
}
@Override
public WpsDocEntity save(WpsDocEntity entity) {
WpsDocDO dataObject = wpsDocDoConvertor.toDO(entity);
InsertFieldDefaults.apply(dataObject);
wpsDocMapper.insert(dataObject);
return wpsDocDoConvertor.toEntity(dataObject);
}
@Override
public WpsDocEntity modify(WpsDocEntity entity) {
WpsDocDO dataObject = wpsDocDoConvertor.toDO(entity);
dataObject.setId(entity.getId());
InsertFieldDefaults.applyForUpdate(dataObject);
wpsDocMapper.updateById(dataObject);
return getByFileId(entity.getFileId());
}
@Override
public void clearPending(Long id) {
LambdaUpdateWrapper<WpsDocDO> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(WpsDocDO::getId, id)
.set(WpsDocDO::getPendingResourceId, null)
.set(WpsDocDO::getPendingDownloadUrl, null)
.set(WpsDocDO::getPendingSize, null)
.set(WpsDocDO::getUpdateTime, LocalDateTime.now());
wpsDocMapper.update(null, wrapper);
}
}

View File

@ -0,0 +1,62 @@
package org.qinan.safetyeval.infrastructure.gatewayimpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.qinan.safetyeval.domain.entity.WpsDocVersionEntity;
import org.qinan.safetyeval.domain.gateway.WpsDocVersionGateway;
import org.qinan.safetyeval.infrastructure.convertor.WpsDocVersionDoConvertor;
import org.qinan.safetyeval.infrastructure.dataobject.WpsDocVersionDO;
import org.qinan.safetyeval.infrastructure.mapper.WpsDocVersionMapper;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
/**
* WPS Gateway
*
* @author safety-eval
*/
@Component
public class WpsDocVersionGatewayImpl implements WpsDocVersionGateway {
@Resource
private WpsDocVersionMapper wpsDocVersionMapper;
@Resource
private WpsDocVersionDoConvertor wpsDocVersionDoConvertor;
@Override
public WpsDocVersionEntity save(WpsDocVersionEntity entity) {
WpsDocVersionDO dataObject = wpsDocVersionDoConvertor.toDO(entity);
if (dataObject.getDeleteEnum() == null) {
dataObject.setDeleteEnum("false");
}
LocalDateTime now = LocalDateTime.now();
if (dataObject.getCreateTime() == null) {
dataObject.setCreateTime(now);
}
if (dataObject.getUpdateTime() == null) {
dataObject.setUpdateTime(now);
}
wpsDocVersionMapper.insert(dataObject);
return wpsDocVersionDoConvertor.toEntity(dataObject);
}
@Override
public WpsDocVersionEntity getByFileIdAndVersion(String fileId, Integer docVersion) {
LambdaQueryWrapper<WpsDocVersionDO> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(WpsDocVersionDO::getFileId, fileId);
wrapper.eq(WpsDocVersionDO::getDocVersion, docVersion);
wrapper.eq(WpsDocVersionDO::getDeleteEnum, "false");
return wpsDocVersionDoConvertor.toEntity(wpsDocVersionMapper.selectOne(wrapper));
}
@Override
public List<WpsDocVersionEntity> listByFileIdDesc(String fileId) {
LambdaQueryWrapper<WpsDocVersionDO> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(WpsDocVersionDO::getFileId, fileId);
wrapper.eq(WpsDocVersionDO::getDeleteEnum, "false");
wrapper.orderByDesc(WpsDocVersionDO::getDocVersion);
return wpsDocVersionDoConvertor.toEntityList(wpsDocVersionMapper.selectList(wrapper));
}
}

View File

@ -6,5 +6,4 @@ import org.qinan.safetyeval.infrastructure.dataobject.AccountDO;
@Mapper
public interface AccountMapper extends BaseMapper<AccountDO> {
String getWps(int i);
}

View File

@ -16,4 +16,12 @@ public interface QualFilingMapper extends BaseMapper<QualFilingDO> {
List<QualFilingCO> qualificationMonitoringPage(@Param("page") Page<QualFilingCO> page, @Param("query") QualificationMonitoringQuery query);
QualFilingStatisticsCO qualificationMonitoringPageStatistics();
/**
* id
*
* @param orgId id
* @return
*/
QualFilingDO selectByOrgIdLastOne(@Param("orgId") Long orgId);
}

View File

@ -0,0 +1,14 @@
package org.qinan.safetyeval.infrastructure.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.qinan.safetyeval.infrastructure.dataobject.WpsDocDO;
/**
* WPS Mapper
*
* @author safety-eval
*/
@Mapper
public interface WpsDocMapper extends BaseMapper<WpsDocDO> {
}

View File

@ -0,0 +1,14 @@
package org.qinan.safetyeval.infrastructure.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.qinan.safetyeval.infrastructure.dataobject.WpsDocVersionDO;
/**
* WPS Mapper
*
* @author safety-eval
*/
@Mapper
public interface WpsDocVersionMapper extends BaseMapper<WpsDocVersionDO> {
}

View File

@ -56,7 +56,11 @@ public class QualOnSiteReviewDO extends BaseDO {
/**
* (AGENCY_PENDING_CONFIRMATIONAGENCY_CONFIRMEDREVIEW_PASSEDREVIEW_FAILED)
*/
private Long status;
private String status;
/**
*
*/
private String reviewOpinion;
/**
*
*/

View File

@ -29,6 +29,10 @@ public class QualOnSiteReviewFileDO extends BaseDO {
* url
*/
private String fileUrl;
/**
*
*/
private String reviewOpinion;
/**
*
*/

View File

@ -1,9 +1,19 @@
package org.qinan.safetyeval.infrastructure.persistence.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewMonitorPageQry;
import org.qinan.safetyeval.client.review.request.QualOnSiteReviewOrgPageQry;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewCo;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewMonitorCo;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewOrgCo;
import org.qinan.safetyeval.client.review.response.QualOnSiteReviewStatisticsCo;
import org.qinan.safetyeval.infrastructure.persistence.domainobject.QualOnSiteReviewDO;
import java.util.List;
/**
* Mapper
*
@ -12,4 +22,18 @@ import org.qinan.safetyeval.infrastructure.persistence.domainobject.QualOnSiteRe
*/
@Mapper
public interface QualOnSiteReviewMapper extends BaseMapper<QualOnSiteReviewDO> {
List<QualOnSiteReviewMonitorCo> monitorPage(@Param("page") Page<QualOnSiteReviewMonitorCo> page,
@Param("query") QualOnSiteReviewMonitorPageQry query);
List<QualOnSiteReviewOrgCo> orgPage(@Param("page") Page<QualOnSiteReviewOrgCo> page,
@Param("query") QualOnSiteReviewOrgPageQry query);
/**
* SQL
*
* @param orgId ID
* @return
*/
QualOnSiteReviewStatisticsCo statistics(@Param("orgId") Long orgId);
}

View File

@ -40,12 +40,7 @@ public class QualOnSiteReviewFileRepositoryImpl extends BaseRepositoryImpl<QualO
if (ObjectUtil.isNotEmpty(qualOnSiteReviewFilePageQry.getFileName())) {
qualOnSiteReviewFileDoQueryWrapper.like("file_name", qualOnSiteReviewFilePageQry.getFileName());
}
if (ObjectUtil.isNotEmpty(qualOnSiteReviewFilePageQry.getFileUrl())) {
qualOnSiteReviewFileDoQueryWrapper.eq("file_url", qualOnSiteReviewFilePageQry.getFileUrl());
}
if (ObjectUtil.isNotEmpty(qualOnSiteReviewFilePageQry.getEnv())) {
qualOnSiteReviewFileDoQueryWrapper.eq("env", qualOnSiteReviewFilePageQry.getEnv());
}
qualOnSiteReviewFileDoQueryWrapper.eq("delete_enum", BooleanEnum.FALSE.getValue());
return qualOnSiteReviewFileMapper.selectPage(iPage, qualOnSiteReviewFileDoQueryWrapper);
}

View File

@ -34,12 +34,6 @@ public class QualOnSiteReviewRepositoryImpl extends BaseRepositoryImpl<QualOnSit
@Override
public IPage<QualOnSiteReviewDO> listQualOnSiteReviewPage(IPage iPage, QualOnSiteReviewPageQry qualOnSiteReviewPageQry) {
QueryWrapper<QualOnSiteReviewDO> qualOnSiteReviewDoQueryWrapper = new QueryWrapper<>();
if (ObjectUtil.isNotEmpty(qualOnSiteReviewPageQry.getBizType())) {
qualOnSiteReviewDoQueryWrapper.eq("biz_type", qualOnSiteReviewPageQry.getBizType());
}
if (ObjectUtil.isNotEmpty(qualOnSiteReviewPageQry.getBizId())) {
qualOnSiteReviewDoQueryWrapper.eq("biz_id", qualOnSiteReviewPageQry.getBizId());
}
if (ObjectUtil.isNotEmpty(qualOnSiteReviewPageQry.getReviewDateStart())) {
qualOnSiteReviewDoQueryWrapper.eq("review_date_start", qualOnSiteReviewPageQry.getReviewDateStart());
}

View File

@ -28,8 +28,5 @@
<sql id="Base_Column_List">
`id`, `user_name`, `account`, `phone`, `password`, `profile_url`, `type`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`
</sql>
<select id="getWps" resultType="java.lang.String">
SELECT val FROM `wps` WHERE `key` = #{id}
</select>
</mapper>

View File

@ -84,4 +84,14 @@
where info.delete_enum = 'false';
</select>
<select id="selectByOrgIdLastOne" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from qual_filing
where org_id = #{orgId}
and delete_enum = 'false'
order by id desc
limit 1
</select>
</mapper>

View File

@ -16,6 +16,7 @@
<result property="supervisorContact" column="supervisor_contact"/>
<result property="contactPhone" column="contact_phone"/>
<result property="status" column="status"/>
<result property="reviewOpinion" column="review_opinion"/>
<result property="deleteEnum" column="delete_enum"/>
<result property="remarks" column="remarks"/>
<result property="createName" column="create_name"/>
@ -41,6 +42,7 @@
supervisor_contact,
contact_phone,
status,
review_opinion,
delete_enum,
remarks,
create_name,
@ -54,4 +56,70 @@
env
from qual_on_site_review
</sql>
<select id="monitorPage" resultType="org.qinan.safetyeval.client.review.response.QualOnSiteReviewMonitorCo" >
select info.unit_name , review.*
from qual_on_site_review review
left join org_info info on info.id = review.org_id
where review.delete_enum = 'false'
<if test="query.unitName != null and query.unitName != ''">
and info.unit_name like concat('%', #{query.unitName}, '%')
</if>
<if test="query.status != null">
and review.status = #{query.status}
</if>
<if test="query.reviewDateStartBegin != null">
and review.review_date_start &gt;= #{query.reviewDateStartBegin}
</if>
<if test="query.reviewDateStartEnd != null">
and review.review_date_start &lt;= #{query.reviewDateStartEnd}
</if>
order by review.id desc
</select>
<select id="orgPage" resultType="org.qinan.safetyeval.client.review.response.QualOnSiteReviewOrgCo">
select review.id,
review.biz_type,
review.biz_id,
review.review_date_start,
review.review_location,
review.review_members,
review.material_requirements,
review.supervisor_contact,
review.contact_phone,
review.status,
review.env,
review.version
from qual_on_site_review review
where review.delete_enum = 'false'
and review.org_id = #{query.orgId}
<if test="query.status != null">
and review.status = #{query.status}
</if>
<if test="query.reviewDateStartBegin != null">
and review.review_date_start &gt;= #{query.reviewDateStartBegin}
</if>
<if test="query.reviewDateStartEnd != null">
and review.review_date_start &lt;= #{query.reviewDateStartEnd}
</if>
order by review.id desc
</select>
<!-- 资质现场核查统计单条SQL聚合返回全部指标 -->
<select id="statistics"
resultType="org.qinan.safetyeval.client.review.response.QualOnSiteReviewStatisticsCo">
select
count(*) as totalCount,
SUM(CASE WHEN YEAR(review_date_start) = YEAR(CURDATE()) THEN 1 ELSE 0 END) AS annualCumulativeCount,
SUM(CASE WHEN status IN ('AGENCY_PENDING_CONFIRMATION', 'AGENCY_CONFIRMED')
AND review_date_start BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY) THEN 1 ELSE 0 END)
AS pendingReviewNextThirtyDaysCount,
SUM(CASE WHEN status IN ('REVIEW_PASSED', 'REVIEW_FAILED') THEN 1 ELSE 0 END) AS completedArchivedCount
from qual_on_site_review
where delete_enum = 'false'
<if test="orgId != null">
and org_id = #{orgId}
</if>
</select>
</mapper>

View File

@ -171,3 +171,8 @@ def:
password: a123456
publicKey: 0402df2195296d4062ac85ad766994d73e871b887e18efb9a9a06b4cebc72372869b7da6c347c129dee2b46a0f279ff066b01c76208c2a052af75977c722a2ccee
reviewEnable: false
wps:
upload-base-url: ${WPS_UPLOAD_BASE_URL:https://gbs-gateway.qhdsafety.com/safetyEval-h5/wsp}
def-docx-url: https://test-dragon-yf-pub.oss-cn-hangzhou.aliyuncs.com/jjb/6a59d83ee4b0b4541389511f.docx