This commit is contained in:
@@ -0,0 +1,416 @@
|
||||
package com.yunhai.svchall.service.impl;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.yunhai.platform.apistd.BizException;
|
||||
import com.yunhai.platform.utils.exception.ErrorCode;
|
||||
import com.yunhai.platform.utils.model.BoaUser;
|
||||
import com.yunhai.svchall.entity.ServiceApply;
|
||||
import com.yunhai.svchall.entity.ServiceForm;
|
||||
import com.yunhai.svchall.entity.ServiceItem;
|
||||
import com.yunhai.svchall.enums.ApplyFlowStatusEnum;
|
||||
import com.yunhai.svchall.enums.ServiceItemStatusEnum;
|
||||
import com.yunhai.svchall.model.svc.SvcModels.ApplyPageQuery;
|
||||
import com.yunhai.svchall.model.svc.SvcModels.ApplySubmitRequest;
|
||||
import com.yunhai.svchall.model.svc.SvcModels.ApplyVo;
|
||||
import com.yunhai.svchall.repository.ServiceApplyRepository;
|
||||
import com.yunhai.svchall.repository.ServiceItemRepository;
|
||||
import com.yunhai.svchall.service.FlowClient;
|
||||
import com.yunhai.svchall.service.SiteDirectory;
|
||||
import com.yunhai.svchall.service.SiteDirectory.SiteInfo;
|
||||
import com.yunhai.svchall.service.SiteGuard;
|
||||
import com.yunhai.svchall.utils.FormValidator;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* 办件服务(V2.0 Part B.4 + 验收报告 §四 D9/§四.2 范式对齐):用户发起(事项/表单快照落库 →
|
||||
* AFTER_COMMIT 后独立线程 FlowClient 代发起 → 回调驱动镜像状态)、我的办件/详情、管理端分页、
|
||||
* 重试(复用同一 bizId 命中 flow-center uk 幂等)。提交纪律:快照自包含(item_snapshot_json/
|
||||
* form_data_json),事项后续改名/下架不影响在途与历史办件;代发起出站不进 DB 事务(HTTP 长调用
|
||||
* 拖住连接 + 回调先于提交到达找不到行),成功回填走窄列 markApproving(终态不回退)。
|
||||
* 用户面撤回/催办/审批轨迹由前端直调 flow-center CAS 接口(同主域 cookie),本服务不代理。
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ServiceApplyService {
|
||||
|
||||
private final ServiceApplyRepository applyRepository;
|
||||
private final ServiceItemRepository itemRepository;
|
||||
private final ServiceFormService formService;
|
||||
private final AttachmentService attachmentService;
|
||||
private final FlowClient flowClient;
|
||||
private final SiteGuard siteGuard;
|
||||
private final SiteDirectory siteDirectory;
|
||||
private final com.yunhai.svchall.service.ApplyViewGuard applyViewGuard;
|
||||
private final ObjectMapper objectMapper;
|
||||
private final org.springframework.transaction.support.TransactionTemplate transactionTemplate;
|
||||
|
||||
/** 办事大厅前端对外地址(bizUrl 落地页用;projman 注入,本地默认 dev server) */
|
||||
@Value("${svchall.front.base-url:http://localhost:8087}")
|
||||
private String frontBaseUrl;
|
||||
|
||||
// ===== 用户面(CAS)=====
|
||||
|
||||
/**
|
||||
* 发起:本校成员 + 事项发布态 + 表单数据强校验 → 落 service_apply(PENDING, bizId=id)
|
||||
* → AFTER_COMMIT 后独立线程代发起(失败保留 PENDING 行,重试复用同一 id)。
|
||||
* 返回办件 VO(PENDING 态——代发起异步执行,状态秒级翻转,前端以"待提交/审批中"刷新可见)。
|
||||
*/
|
||||
@Transactional
|
||||
public ApplyVo submit(BoaUser user, ApplySubmitRequest req) {
|
||||
if (user == null || user.getId() == null) {
|
||||
throw new BizException(ErrorCode.PARAM_ERROR, "未获取到登录用户");
|
||||
}
|
||||
SiteInfo site = siteDirectory.requireSite(req.getSiteCode());
|
||||
siteGuard.requireSchoolMember(user, site.getSchId());
|
||||
ServiceItem item = itemRepository
|
||||
.findBySchIdAndSiteCodeAndItemCode(site.getSchId(), site.getSiteCode(), req.getItemCode())
|
||||
.orElseThrow(() -> new BizException(ErrorCode.PARAM_ERROR, "事项不存在"));
|
||||
if (item.getStatus() == null || item.getStatus() != ServiceItemStatusEnum.PUBLISHED.getCode()) {
|
||||
throw new BizException(ErrorCode.PARAM_ERROR, "事项未发布,不可办理");
|
||||
}
|
||||
if (item.getFlowGuid() == null || item.getFlowGuid().isEmpty()) {
|
||||
throw new BizException(ErrorCode.PARAM_ERROR, "该事项未开通在线办理");
|
||||
}
|
||||
// 表单解析 + 提交数据强校验(按最新已发布版本;发起时快照 form_version)
|
||||
ServiceForm form = null;
|
||||
if (item.getFormCode() != null && !item.getFormCode().isEmpty()) {
|
||||
form = formService.latestPublished(site.getSchId(), item.getFormCode())
|
||||
.orElseThrow(() -> new BizException(ErrorCode.PARAM_ERROR,
|
||||
"办理表单未发布,请联系管理员(事项 " + item.getItemCode() + ")"));
|
||||
FormValidator.validateSubmit(req.getFormData(), form.getSchemaJson());
|
||||
} else if (StringUtils.hasText(req.getFormData())) {
|
||||
throw new BizException(ErrorCode.PARAM_ERROR, "该事项无办理表单,不应提交表单数据");
|
||||
}
|
||||
|
||||
ServiceApply apply = new ServiceApply();
|
||||
apply.setSchId(site.getSchId());
|
||||
apply.setSiteCode(site.getSiteCode());
|
||||
apply.setItemId(item.getId());
|
||||
apply.setItemCode(item.getItemCode());
|
||||
apply.setItemTitle(item.getTitle());
|
||||
apply.setItemSnapshotJson(itemSnapshotJson(item));
|
||||
apply.setFormVersion(form == null ? null : form.getVersion());
|
||||
apply.setFormDataJson(req.getFormData());
|
||||
apply.setSubmitterId(user.getId());
|
||||
apply.setSubmitterName(user.getName());
|
||||
apply.setFlowGuid(item.getFlowGuid());
|
||||
apply = applyRepository.save(apply);
|
||||
|
||||
// 办件材料绑定(必须落库拿到 applyId 之后再绑)
|
||||
attachmentService.bindApply(site.getSchId(), apply.getId(), req.getAttachments());
|
||||
apply.setItemSnapshotJson(itemSnapshotJson(item, attachmentService
|
||||
.applyAttachments(site.getSchId(), apply.getId())));
|
||||
apply = applyRepository.save(apply);
|
||||
|
||||
flowSubmitAfterCommit(apply.getId());
|
||||
return ApplyVo.of(apply);
|
||||
}
|
||||
|
||||
/** 重试:PENDING 行复用同一 bizId 再次代发起(幂等);仅提交人本人可重试自己的办件(同步路径,无长事务) */
|
||||
public ApplyVo retry(BoaUser user, Integer applyId) {
|
||||
ServiceApply apply = applyRepository.findByIdAndSchId(applyId, userSchId(user))
|
||||
.orElseThrow(() -> new BizException(ErrorCode.PARAM_ERROR, "办件不存在"));
|
||||
if (!user.getId().equals(apply.getSubmitterId())) {
|
||||
throw new BizException(ErrorCode.FORBIDDEN, "仅可重试自己的办件");
|
||||
}
|
||||
if (apply.getFlowStatus() == null || apply.getFlowStatus() != ApplyFlowStatusEnum.PENDING.getCode()) {
|
||||
throw new BizException(ErrorCode.PARAM_ERROR, "该办件不在待提交状态,无需重试");
|
||||
}
|
||||
doFlowApply(applyId, false);
|
||||
return applyRepository.findById(applyId).map(ApplyVo::of).orElse(ApplyVo.of(apply));
|
||||
}
|
||||
|
||||
/**
|
||||
* 一键重提(P2-5/BP-R2-2):驳回(30)/撤回(40)后复用同一办件行重新发起——flow-center R4
|
||||
* 按 bizType+bizId 命中 30/40 → 重启推进(定义刷新、快照覆盖、version 自增、轨迹跨轮连续)。
|
||||
* 校验:提交人本人 + 终态 30/40 + flowGuid 非空;表单数据沿用原 formData
|
||||
* ("改后重提"属后续产品项,登记于验收报告)。出站失败保持原态可重入。
|
||||
*/
|
||||
public ApplyVo resubmit(BoaUser user, Integer applyId) {
|
||||
ServiceApply apply = applyRepository.findByIdAndSchId(applyId, userSchId(user))
|
||||
.orElseThrow(() -> new BizException(ErrorCode.PARAM_ERROR, "办件不存在"));
|
||||
if (!user.getId().equals(apply.getSubmitterId())) {
|
||||
throw new BizException(ErrorCode.FORBIDDEN, "仅可重提自己的办件");
|
||||
}
|
||||
Integer status = apply.getFlowStatus();
|
||||
if (status == null || (status != ApplyFlowStatusEnum.REJECTED.getCode()
|
||||
&& status != ApplyFlowStatusEnum.WITHDRAWN.getCode())) {
|
||||
throw new BizException(ErrorCode.PARAM_ERROR, "仅驳回/已撤回状态的办件可重新提交");
|
||||
}
|
||||
if (apply.getFlowGuid() == null || apply.getFlowGuid().isEmpty()) {
|
||||
throw new BizException(ErrorCode.PARAM_ERROR, "该办件未绑定流程,不可重提");
|
||||
}
|
||||
doFlowApply(applyId, true);
|
||||
return applyRepository.findById(applyId).map(ApplyVo::of).orElse(ApplyVo.of(apply));
|
||||
}
|
||||
|
||||
/** 我的办件(提交人视角,flowStatus 可选筛选) */
|
||||
public Map<String, Object> myApplies(BoaUser user, Integer flowStatus, Integer page, Integer pageSize) {
|
||||
int pageIndex = page == null || page < 1 ? 0 : page - 1;
|
||||
int size = pageSize == null || pageSize < 1 ? 10 : Math.min(pageSize, 100);
|
||||
Pageable pageable = PageRequest.of(pageIndex, size,
|
||||
Sort.by(Sort.Order.desc("createTime"), Sort.Order.desc("id")));
|
||||
Specification<ServiceApply> spec = (root, cq, cb) -> {
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
predicates.add(cb.equal(root.get("schId"), userSchId(user)));
|
||||
predicates.add(cb.equal(root.get("submitterId"), user.getId()));
|
||||
if (flowStatus != null) {
|
||||
predicates.add(cb.equal(root.get("flowStatus"), flowStatus));
|
||||
}
|
||||
return cb.and(predicates.toArray(new Predicate[0]));
|
||||
};
|
||||
Page<ServiceApply> result = applyRepository.findAll(spec, pageable);
|
||||
Map<String, Object> out = new HashMap<>();
|
||||
out.put("total", result.getTotalElements());
|
||||
List<ApplyVo> list = new ArrayList<>();
|
||||
for (ServiceApply apply : result.getContent()) {
|
||||
list.add(ApplyVo.of(apply));
|
||||
}
|
||||
out.put("list", list);
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情:提交人本人 / 管理员(type=1 或 roleId∈{2,5,7})/ 办理人(assigneeIds 实时含当前用户)
|
||||
* 三分支放行(BP-R2-3 修复,ApplyViewGuard=NoticeFlowGuard 同构;原先"同校即放行"越权已收紧)。
|
||||
*/
|
||||
public ApplyVo detail(BoaUser user, String siteCode, Integer id) {
|
||||
ServiceApply apply;
|
||||
if (isSuperAdmin(user)) {
|
||||
apply = applyRepository.findById(id)
|
||||
.orElseThrow(() -> new BizException(ErrorCode.PARAM_ERROR, "办件不存在"));
|
||||
} else {
|
||||
Long schId = userSchId(user);
|
||||
apply = applyRepository.findByIdAndSchId(id, schId)
|
||||
.orElseThrow(() -> new BizException(ErrorCode.PARAM_ERROR, "办件不存在"));
|
||||
applyViewGuard.requireVisible(apply, user);
|
||||
}
|
||||
return ApplyVo.of(apply);
|
||||
}
|
||||
|
||||
// ===== 管理面 =====
|
||||
|
||||
/**
|
||||
* 发起页数据(本校用户):事项发布态要点 + 绑定表单的已发布 schema。
|
||||
* 校验链与 submit 一致(同校成员/发布态/已绑流程),前端据此渲染动态表单。
|
||||
*/
|
||||
public Map<String, Object> applyItem(BoaUser user, String siteCode, String itemCode) {
|
||||
SiteInfo site = siteDirectory.requireSite(siteCode);
|
||||
siteGuard.requireSchoolMember(user, site.getSchId());
|
||||
ServiceItem item = itemRepository
|
||||
.findBySchIdAndSiteCodeAndItemCode(site.getSchId(), site.getSiteCode(), itemCode)
|
||||
.orElseThrow(() -> new BizException(ErrorCode.PARAM_ERROR, "事项不存在"));
|
||||
if (item.getStatus() == null || item.getStatus() != ServiceItemStatusEnum.PUBLISHED.getCode()) {
|
||||
throw new BizException(ErrorCode.PARAM_ERROR, "事项未发布,不可办理");
|
||||
}
|
||||
if (item.getFlowGuid() == null || item.getFlowGuid().isEmpty()) {
|
||||
throw new BizException(ErrorCode.PARAM_ERROR, "该事项未开通在线办理");
|
||||
}
|
||||
Map<String, Object> out = new HashMap<>();
|
||||
out.put("siteCode", site.getSiteCode());
|
||||
out.put("itemCode", item.getItemCode());
|
||||
out.put("title", item.getTitle());
|
||||
out.put("summary", item.getSummary());
|
||||
out.put("deptName", item.getDeptName());
|
||||
out.put("handleMode", item.getHandleMode());
|
||||
out.put("handleTimeLimit", item.getHandleTimeLimit());
|
||||
out.put("promiseTimeLimit", item.getPromiseTimeLimit());
|
||||
out.put("contactPhone", item.getContactPhone());
|
||||
out.put("coverImage", com.yunhai.svchall.utils.FileUtil.absolutizePlain(item.getCoverImage()));
|
||||
out.put("flowGuid", item.getFlowGuid());
|
||||
if (item.getFormCode() != null && !item.getFormCode().isEmpty()) {
|
||||
ServiceForm form = formService.latestPublished(site.getSchId(), item.getFormCode())
|
||||
.orElseThrow(() -> new BizException(ErrorCode.PARAM_ERROR,
|
||||
"办理表单未发布,请联系管理员"));
|
||||
out.put("formVersion", form.getVersion());
|
||||
out.put("schemaJson", form.getSchemaJson());
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
public Map<String, Object> adminPage(BoaUser user, ApplyPageQuery query) {
|
||||
SiteInfo site = siteGuard.requireSiteManager(user, query.getSiteCode());
|
||||
int pageIndex = query.getPage() == null || query.getPage() < 1 ? 0 : query.getPage() - 1;
|
||||
int size = query.getPageSize() == null || query.getPageSize() < 1 ? 10 : Math.min(query.getPageSize(), 100);
|
||||
Pageable pageable = PageRequest.of(pageIndex, size,
|
||||
Sort.by(Sort.Order.desc("createTime"), Sort.Order.desc("id")));
|
||||
Specification<ServiceApply> spec = (root, cq, cb) -> {
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
predicates.add(cb.equal(root.get("schId"), site.getSchId()));
|
||||
predicates.add(cb.equal(root.get("siteCode"), site.getSiteCode()));
|
||||
if (StringUtils.hasText(query.getItemCode())) {
|
||||
predicates.add(cb.equal(root.get("itemCode"), query.getItemCode().trim()));
|
||||
}
|
||||
if (query.getFlowStatus() != null) {
|
||||
predicates.add(cb.equal(root.get("flowStatus"), query.getFlowStatus()));
|
||||
}
|
||||
if (StringUtils.hasText(query.getKeyword())) {
|
||||
String like = "%" + query.getKeyword().trim() + "%";
|
||||
predicates.add(cb.or(cb.like(root.get("itemTitle"), like),
|
||||
cb.like(root.get("submitterName"), like)));
|
||||
}
|
||||
return cb.and(predicates.toArray(new Predicate[0]));
|
||||
};
|
||||
Page<ServiceApply> result = applyRepository.findAll(spec, pageable);
|
||||
Map<String, Object> out = new HashMap<>();
|
||||
out.put("total", result.getTotalElements());
|
||||
List<ApplyVo> list = new ArrayList<>();
|
||||
for (ServiceApply apply : result.getContent()) {
|
||||
list.add(ApplyVo.of(apply));
|
||||
}
|
||||
out.put("list", list);
|
||||
return out;
|
||||
}
|
||||
|
||||
// ===== 内部:代发起(D9 范式,Notice NoticeFlowService 同构)=====
|
||||
|
||||
/**
|
||||
* 提交动作专用单线程池(串行化避免并发双 apply;uk 幂等兜底)。
|
||||
* E2E 实测教训(验收报告 §四.1):afterCommit 回调若留在原请求线程执行,OSIV 绑定的
|
||||
* EntityManager 已随事务提交关闭,后续 repository 写会话静默丢失——提交动作一律切独立线程。
|
||||
*/
|
||||
private static final ExecutorService APPLY_EXECUTOR = Executors.newSingleThreadExecutor(r -> {
|
||||
Thread t = new Thread(r, "svchall-flow-submit");
|
||||
t.setDaemon(true);
|
||||
return t;
|
||||
});
|
||||
|
||||
/**
|
||||
* 事务提交后再代发起(出站 HTTP 不进 DB 事务,防长调用拖住连接;且 flow-center 收到 apply
|
||||
* 后会立即推送回调,须保证办件行已提交可见)。无活动事务时立即执行(测试/兜底)。
|
||||
*/
|
||||
private void flowSubmitAfterCommit(Integer applyId) {
|
||||
Runnable task = () -> tryApplyQuietly(applyId);
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
|
||||
@Override
|
||||
public void afterCommit() {
|
||||
APPLY_EXECUTOR.submit(task);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
task.run();
|
||||
}
|
||||
}
|
||||
|
||||
/** 异步路径提交失败静默保持 PENDING(行已落库不回滚;列表"待提交"态即提示,可重试) */
|
||||
private void tryApplyQuietly(Integer applyId) {
|
||||
try {
|
||||
doFlowApply(applyId, false);
|
||||
} catch (Exception e) {
|
||||
log.warn("[svc-hall] 代发起失败(保持待提交,可重试)applyId={}:{}", applyId, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 代发起(幂等:bizId=apply.id,flow-center uk 防重复建件)。
|
||||
* 成功回填走窄列 markApproving——整实体 save 是旧快照盲写,会覆盖出站期间并发送达的回调状态
|
||||
* (验收报告 §四.2);BizException 透传(retry 同步路径给用户提示,异步路径由静默包装消化)。
|
||||
* resubmit=true(一键重提):R4 命中 30/40 重启推进后改用 markResubmitted 回开为 10。
|
||||
*/
|
||||
private void doFlowApply(Integer applyId, boolean resubmit) {
|
||||
if (!flowClient.enabled()) {
|
||||
log.warn("[svc-hall] 流程中心未接入,办件保留待提交状态 applyId={}", applyId);
|
||||
return;
|
||||
}
|
||||
ServiceApply apply = applyRepository.findById(applyId)
|
||||
.orElseThrow(() -> new BizException(ErrorCode.PARAM_ERROR, "办件不存在"));
|
||||
try {
|
||||
FlowClient.ApplyResult result = flowClient.apply(
|
||||
apply.getSchId(),
|
||||
apply.getFlowGuid(),
|
||||
FlowCallbackService.BIZ_TYPE,
|
||||
String.valueOf(apply.getId()),
|
||||
apply.getSubmitterName() + "的" + apply.getItemTitle(),
|
||||
// 前端详情页是 hash 路由 + query 传参(routes.ts path="/apply-detail"、
|
||||
// Apply.vue router.replace("/apply-detail?id=")):路径参数形态会 no-match 空白页
|
||||
frontBaseUrl + "/#/apply-detail?id=" + apply.getId(),
|
||||
apply.getItemSnapshotJson(),
|
||||
apply.getSubmitterId(),
|
||||
apply.getSubmitterName(),
|
||||
apply.getFormDataJson());
|
||||
// @Modifying 更新须在事务内执行;本方法出站 HTTP 后运行在 AFTER_COMMIT 线程,
|
||||
// 无外层事务,用模板事务包住窄列回填( markApproving/markResubmitted)
|
||||
final Integer applyIdFinal = apply.getId();
|
||||
final Long instanceId = result.getInstanceId();
|
||||
transactionTemplate.executeWithoutResult(tx -> {
|
||||
if (resubmit) {
|
||||
applyRepository.markResubmitted(applyIdFinal, instanceId, LocalDateTime.now());
|
||||
} else {
|
||||
applyRepository.markApproving(applyIdFinal, instanceId, LocalDateTime.now());
|
||||
}
|
||||
});
|
||||
if (result.isDuplicated()) {
|
||||
log.info("[svc-hall] 代发起命中幂等(flow-center 返回既有办件)applyId={} instanceId={}",
|
||||
apply.getId(), result.getInstanceId());
|
||||
}
|
||||
} catch (BizException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
// PENDING 行保留:用户可重试(复用同一 bizId,flow-center uk 幂等防重复建件)
|
||||
log.error("[svc-hall] 代发起失败,办件保留待提交 applyId={}", applyId, e);
|
||||
throw new BizException(ErrorCode.PARAM_ERROR, "流程中心提交失败,请稍后重试");
|
||||
}
|
||||
}
|
||||
|
||||
// ===== 内部:快照与工具 =====
|
||||
|
||||
/** 事项要点快照(= biz_snapshot 内容源;附件清单仅文件名——flow-center biz_snapshot 内容边界) */
|
||||
private String itemSnapshotJson(ServiceItem item) {
|
||||
return itemSnapshotJson(item, new ArrayList<>());
|
||||
}
|
||||
|
||||
private String itemSnapshotJson(ServiceItem item, List<com.yunhai.svchall.model.svc.SvcModels.SvcItemAttachmentVo> attachments) {
|
||||
Map<String, Object> snapshot = new LinkedHashMap<>();
|
||||
snapshot.put("itemTitle", item.getTitle());
|
||||
snapshot.put("summary", item.getSummary());
|
||||
snapshot.put("deptName", item.getDeptName());
|
||||
snapshot.put("handleTimeLimit", item.getHandleTimeLimit());
|
||||
snapshot.put("contactPhone", item.getContactPhone());
|
||||
List<String> names = new ArrayList<>();
|
||||
for (com.yunhai.svchall.model.svc.SvcModels.SvcItemAttachmentVo a : attachments) {
|
||||
names.add(a.getFileName());
|
||||
}
|
||||
snapshot.put("attachmentNames", names);
|
||||
try {
|
||||
return objectMapper.writeValueAsString(snapshot);
|
||||
} catch (Exception e) {
|
||||
log.warn("[svc-hall] 事项快照序列化失败(存 null)itemCode={}", item.getItemCode());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Long userSchId(BoaUser user) {
|
||||
if (user == null || user.getCurrentRole() == null || user.getCurrentRole().getSchId() == null) {
|
||||
throw new BizException(ErrorCode.PARAM_ERROR, "当前用户无学校归属,无法操作办件");
|
||||
}
|
||||
return user.getCurrentRole().getSchId().longValue();
|
||||
}
|
||||
|
||||
private static boolean isSuperAdmin(BoaUser user) {
|
||||
return user != null && user.getType() != null && user.getType() == 1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user