Merge branch 'master' into feature/REQ-3540

This commit is contained in:
xudawei 2025-04-28 16:56:40 +08:00
commit 5039cd9375
24 changed files with 1157 additions and 33 deletions

View File

@ -3,6 +3,8 @@ package cn.axzo.nanopart.doc.api.anonymous;
import javax.validation.Valid;
import cn.axzo.nanopart.doc.api.domain.IndexNodeInfo;
import cn.axzo.nanopart.doc.api.index.request.BatchGetNodeInfoRequest;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@ -17,6 +19,8 @@ import cn.axzo.nanopart.doc.api.index.request.GetNodeInfoRequest;
import cn.axzo.nanopart.doc.api.index.request.RenameNodeRequest;
import cn.azxo.framework.common.model.CommonResponse;
import java.util.Map;
/**
* @author yanglin
*/
@ -89,4 +93,10 @@ public interface DocAnonymousDatabaseApi {
@PostMapping("/api/anonymous/getNodeInfo")
CommonResponse<IndexNodeInfo> getNodeInfo(@RequestBody @Valid GetNodeInfoRequest request);
/**
* 批量获取节点信息集合
*/
@PostMapping("/api/anonymous/batchGetNodeInfo")
CommonResponse<Map<String, IndexNodeInfo>> batchGetNodeInfo(@RequestBody @Valid BatchGetNodeInfoRequest request);
}

View File

@ -0,0 +1,54 @@
package cn.axzo.nanopart.doc.api.bizattri;
import cn.axzo.nanopart.doc.api.bizattri.request.CreateNodeBizAttributesRequest;
import cn.axzo.nanopart.doc.api.bizattri.request.SearchNodeBizAttributesRequest;
import cn.axzo.nanopart.doc.api.bizattri.request.UpdateNodeBizAttributesRequest;
import cn.axzo.nanopart.doc.api.bizattri.request.UpsertNodeBizAttributesRequest;
import cn.axzo.nanopart.doc.api.bizattri.response.CreateNodeBizAttributesResponse;
import cn.axzo.nanopart.doc.api.bizattri.response.SearchNodeBizAttributesResponse;
import cn.axzo.nanopart.doc.api.bizattri.response.UpdateNodeBizAttributesResponse;
import cn.axzo.nanopart.doc.api.bizattri.response.UpsertNodeBizAttributesResponse;
import cn.azxo.framework.common.model.CommonResponse;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import javax.validation.Valid;
import java.util.List;
/**
* @author xudawei@axzo.cn
* @date 2025/03/27
*/
@FeignClient(name = "nanopart", url = "${axzo.service.nanopart:http://nanopart:8080}")
public interface NodeBizAttributesApi {
/**
* 创建结点配置信息
* @return 节点code
*/
@PostMapping("/api/nodeBizAttributes/create")
CommonResponse<CreateNodeBizAttributesResponse> createNodeBizAttributes(@RequestBody @Valid CreateNodeBizAttributesRequest request);
/**
* 更新结点配置信息
* @return 节点code
*/
@PostMapping("/api/nodeBizAttributes/update")
CommonResponse<UpdateNodeBizAttributesResponse> updateNodeBizAttributes(@RequestBody @Valid UpdateNodeBizAttributesRequest request);
/**
* 更新或者插入结点配置信息
* @return 节点code
*/
@PostMapping("/api/nodeBizAttributes/upsert")
CommonResponse<UpsertNodeBizAttributesResponse> upsertNodeBizAttributes(@RequestBody @Valid UpsertNodeBizAttributesRequest request);
/**
* 查询结点配置信息
* @return 节点code
*/
@PostMapping("/api/nodeBizAttributes/search")
CommonResponse<List<SearchNodeBizAttributesResponse>> searchNodeBizAttributes(@RequestBody @Valid SearchNodeBizAttributesRequest request);
}

View File

@ -0,0 +1,88 @@
package cn.axzo.nanopart.doc.api.bizattri.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author xudawei@axzo.cn
* @date 2025/3/27
* @description 创建图纸素材请求
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CreateNodeBizAttributesRequest {
/**
* 结点编码
*/
private String nodeCode;
/**
* 图纸素材
*/
private List<DrawMaterial> drawMaterials;
/**
* 创建人
*/
private Long createBy;
/**
* 更新人
*/
private Long updateBy;
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public static class DrawMaterial {
/**
* 标题
*/
private String title;
/**
* 图纸
*/
private String drawId;
/**
* 素材
*/
private List<Content> contents;
}
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public static class Content {
/**
* 图片的fileKey
*/
private String picFileKey;
/**
* dwg的url
*/
private String dwgUrl;
/**
* 名称
*/
private String name;
/**
* 素材
*/
private String annoId;
}
}

View File

@ -0,0 +1,26 @@
package cn.axzo.nanopart.doc.api.bizattri.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author xudawei@axzo.cn
* @date 2025/3/27
* @description 查询图纸素材请求
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SearchNodeBizAttributesRequest {
/**
* 结点编码
*/
private String nodeCode;
}

View File

@ -0,0 +1,52 @@
package cn.axzo.nanopart.doc.api.bizattri.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author xudawei@axzo.cn
* @date 2025/3/27
* @description 更新图纸素材请求
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UpdateNodeBizAttributesRequest {
/**
* 结点编码
*/
private String nodeCode;
/**
* 更新内容
*/
private UpdateNodeBizAttributes updateContent;
/**
* 更新人
*/
private Long updateBy;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class UpdateNodeBizAttributes {
/**
* 图纸素材
*/
private List<CreateNodeBizAttributesRequest.DrawMaterial> drawMaterials;
/**
* 更新人
*/
private Long updateBy;
}
}

View File

@ -0,0 +1,101 @@
package cn.axzo.nanopart.doc.api.bizattri.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import java.util.List;
/**
* @author xudawei@axzo.cn
* @date 2025/3/27
* @description 创建图纸素材请求
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UpsertNodeBizAttributesRequest {
/**
* 结点编码
*/
@NotBlank(message = "结点编码不能为空")
private String nodeCode;
/**
* 图纸素材
*/
private List<DrawMaterial> drawMaterials;
/**
* 创建人
*/
private Long createBy;
/**
* 更新人
*/
private Long updateBy;
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public static class DrawMaterial {
/**
* 标题
*/
private String title;
/**
* 图纸
*/
private String drawId;
/**
* 素材
*/
private List<Content> contents;
/**
* 创建时间
*/
private Long createAtTime;
/**
* 创建时间
*/
private String createAt;
}
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public static class Content {
/**
* 图片的fileKey
*/
private String picFileKey;
/**
* 名称
*/
private String name;
/**
* 素材
*/
private String annoId;
/**
* 创建时间
*/
private Long createAtTime;
/**
* 创建时间
*/
private String createAt;
}
}

View File

@ -0,0 +1,24 @@
package cn.axzo.nanopart.doc.api.bizattri.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author xudawei@axzo.cn
* @date 2025/3/27
* @description 创建图纸素材返回
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CreateNodeBizAttributesResponse {
/**
* 结点编码
*/
private String nodeCode;
}

View File

@ -0,0 +1,142 @@
package cn.axzo.nanopart.doc.api.bizattri.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Objects;
/**
* @author xudawei@axzo.cn
* @date 2025/3/27
* @description 查询图纸素材请求
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SearchNodeBizAttributesResponse {
/**
* 结点编码
*/
private String nodeCode;
/**
* 图纸素材
*/
private List<DrawMaterial> drawMaterials;
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public static class DrawMaterial implements Comparable<DrawMaterial>{
/**
* 标题
*/
private String title;
/**
* 图纸
*/
private String drawId;
/**
* 素材
*/
private List<Content> contents;
/**
* 创建时间
*/
private Long createAtTime;
/**
* 创建时间
*/
private String createAt;
@Override
public int compareTo(DrawMaterial o) {
Long first = this.getCreateAtTime();
Long second = o.getCreateAtTime();
if (Objects.isNull(first)) {
first = 0L;
}
if (Objects.isNull(second)) {
second = 0L;
}
if (Objects.equals(first, second)) {
return 0;
}
if (first > second) {
return -1;
}
return 1;
}
}
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public static class Content implements Comparable<Content>{
/**
* 图片的fileKey
*/
private String picFileKey;
/**
* 图片的url
*/
private String picUrl;
/**
* 名称
*/
private String name;
/**
* 素材
*/
private String annoId;
/**
* 创建时间
*/
private Long createAtTime;
/**
* 创建时间
*/
private String createAt;
@Override
public int compareTo(Content o) {
Long first = this.getCreateAtTime();
Long second = o.getCreateAtTime();
if (Objects.isNull(first)) {
first = 0L;
}
if (Objects.isNull(second)) {
second = 0L;
}
if (Objects.equals(first, second)) {
return 0;
}
if (first > second) {
return -1;
}
return 1;
}
}
}

View File

@ -0,0 +1,24 @@
package cn.axzo.nanopart.doc.api.bizattri.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author xudawei@axzo.cn
* @date 2025/3/27
* @description 更新图纸素材返回
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UpdateNodeBizAttributesResponse {
/**
* 结点编码
*/
private String nodeCode;
}

View File

@ -0,0 +1,24 @@
package cn.axzo.nanopart.doc.api.bizattri.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author xudawei@axzo.cn
* @date 2025/3/27
* @description 更新图纸素材返回
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UpsertNodeBizAttributesResponse {
/**
* 结点编码
*/
private String nodeCode;
}

View File

@ -130,6 +130,10 @@ public class IndexNodeInfo implements NodeValue, ValueContainer<IndexNodeInfo> {
private IndexNodeAttributes attributes;
private String ossFileKey;
private String ossFileUrl;
public Path path() {
return Path.wrap(path);
}
@ -150,6 +154,12 @@ public class IndexNodeInfo implements NodeValue, ValueContainer<IndexNodeInfo> {
return fileTemplateNodeInfo;
}
@JsonIgnore
@JSONField(serialize = false, deserialize = false)
public FileAttributes getOrCreateFileAttributes() {
return getOrCreateAttributes().getOrCreateFileAttributes();
}
@Override
public Long id() {
return id;

View File

@ -0,0 +1,14 @@
package cn.axzo.nanopart.doc.api.enums;
/**
* @author xudawei@axzo.cn
*/
public enum State {
// 有效的
VALID,
// 已删除
DELETED
}

View File

@ -0,0 +1,32 @@
package cn.axzo.nanopart.doc.api.index.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotEmpty;
import java.util.List;
/**
* @author xudawei@axzo.cn
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class BatchGetNodeInfoRequest {
/**
* 节点编码集合
*/
@NotEmpty(message = "节点编码集合不能为空")
private List<String> codes;
/**
* 是否需要fileUrltrue:需要,false:不需要
* 默认false
*/
private Boolean needFileUrl = false;
}

View File

@ -0,0 +1,149 @@
package cn.axzo.nanopart.doc.bizattri;
import cn.axzo.nanopart.doc.api.bizattri.NodeBizAttributesApi;
import cn.axzo.nanopart.doc.api.bizattri.request.CreateNodeBizAttributesRequest;
import cn.axzo.nanopart.doc.api.bizattri.request.SearchNodeBizAttributesRequest;
import cn.axzo.nanopart.doc.api.bizattri.request.UpdateNodeBizAttributesRequest;
import cn.axzo.nanopart.doc.api.bizattri.request.UpsertNodeBizAttributesRequest;
import cn.axzo.nanopart.doc.api.bizattri.response.CreateNodeBizAttributesResponse;
import cn.axzo.nanopart.doc.api.bizattri.response.SearchNodeBizAttributesResponse;
import cn.axzo.nanopart.doc.api.bizattri.response.UpdateNodeBizAttributesResponse;
import cn.axzo.nanopart.doc.api.bizattri.response.UpsertNodeBizAttributesResponse;
import cn.axzo.nanopart.doc.entity.NodeBizAttributes;
import cn.axzo.nanopart.doc.integration.DocOssGateway;
import cn.axzo.oss.http.model.ApiSignUrlDownloadRequest;
import cn.axzo.oss.http.model.ApiSignUrlDownloadResponse;
import cn.azxo.framework.common.model.CommonResponse;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @author yanglin
*/
@Slf4j
@RestController
@RequiredArgsConstructor
public class NodeBizAttributesApiController implements NodeBizAttributesApi {
private final NodeBizAttributesManager nodeBizAttributesManager;
private final DocOssGateway docOssGateway;
/**
* 创建结点配置信息
* @return 节点code
*/
@Override
public CommonResponse<CreateNodeBizAttributesResponse> createNodeBizAttributes(CreateNodeBizAttributesRequest request) {
return CommonResponse.success(CreateNodeBizAttributesResponse.builder().nodeCode(nodeBizAttributesManager.create(request)).build());
}
/**
* 更新结点配置信息
* @return 节点code
*/
@Override
public CommonResponse<UpdateNodeBizAttributesResponse> updateNodeBizAttributes(UpdateNodeBizAttributesRequest request) {
return CommonResponse.success(UpdateNodeBizAttributesResponse.builder().nodeCode(nodeBizAttributesManager.update(request)).build());
}
/**
* 更新或者插入结点配置信息
* @return 节点code
*/
@Override
public CommonResponse<UpsertNodeBizAttributesResponse> upsertNodeBizAttributes(UpsertNodeBizAttributesRequest request) {
return CommonResponse.success(UpsertNodeBizAttributesResponse.builder().nodeCode(nodeBizAttributesManager.upsert(request)).build());
}
/**
* 查询结点配置信息
* @return 节点code
*/
@Override
public CommonResponse<List<SearchNodeBizAttributesResponse>> searchNodeBizAttributes(SearchNodeBizAttributesRequest request) {
List<NodeBizAttributes> attributes = nodeBizAttributesManager.search(request);
return CommonResponse.success(convert(attributes));
}
/**
* 对象转换
*/
private List<SearchNodeBizAttributesResponse> convert(List<NodeBizAttributes> attributes) {
if (CollectionUtil.isEmpty(attributes)) {
return Collections.emptyList();
}
List<SearchNodeBizAttributesResponse> copyRespList = attributes.stream().map(item -> SearchNodeBizAttributesResponse.builder()
.nodeCode(item.getNodeCode())
.drawMaterials(BeanUtil.copyToList(item.getAttributes(), SearchNodeBizAttributesResponse.DrawMaterial.class))
.build()).collect(Collectors.toList());
List<SearchNodeBizAttributesResponse> responseList = copyRespList.stream().filter(item -> {
List<SearchNodeBizAttributesResponse.DrawMaterial> attributesList = item.getDrawMaterials().stream().filter(attr -> CollectionUtil.isNotEmpty(attr.getContents())).collect(Collectors.toList());
if (CollectionUtil.isNotEmpty(attributesList)) {
return true;
}
return false;
}).collect(Collectors.toList());
//dwgUrl/picUrl重新赋值
this.rechangeDwgPicUrl(responseList);
//排序
this.sort(responseList);
return responseList;
}
/**
* 排序
* @param responseList
*/
private void sort(List<SearchNodeBizAttributesResponse> responseList) {
for (SearchNodeBizAttributesResponse response : responseList) {
if (CollectionUtil.isNotEmpty(response.getDrawMaterials())) {
Collections.sort(response.getDrawMaterials());
for (SearchNodeBizAttributesResponse.DrawMaterial drawMaterial : response.getDrawMaterials()) {
if (CollectionUtil.isNotEmpty(drawMaterial.getContents())) {
Collections.sort(drawMaterial.getContents());
}
}
}
}
}
/**
* dwgUrl/picUrl重新赋值
*/
private void rechangeDwgPicUrl(List<SearchNodeBizAttributesResponse> responseList) {
List<SearchNodeBizAttributesResponse.DrawMaterial> drawMaterials = responseList.stream().flatMap(item -> item.getDrawMaterials().stream()).collect(Collectors.toList());
List<SearchNodeBizAttributesResponse.Content> contentList = drawMaterials.stream().flatMap(item -> item.getContents().stream()).collect(Collectors.toList());
Set<String> picFileKeyList = contentList.stream().map(SearchNodeBizAttributesResponse.Content::getPicFileKey).collect(Collectors.toSet());
if (CollectionUtil.isNotEmpty(picFileKeyList)) {
List<ApiSignUrlDownloadResponse> apiSignUrlDownloadResponses = docOssGateway.signUrlFetchDownload(ApiSignUrlDownloadRequest.builder().fileKeys(Lists.newArrayList(picFileKeyList)).build());
if (CollectionUtil.isNotEmpty(apiSignUrlDownloadResponses)) {
Map<String, String> collect = apiSignUrlDownloadResponses.stream().collect(Collectors.toMap(item -> item.getFileKey(), value -> value.getSignUrl(), (x, y) -> x));
contentList.forEach(item -> {
item.setPicUrl(StringUtils.isNotEmpty(collect.get(item.getPicFileKey())) ? collect.get(item.getPicFileKey()) : item.getPicFileKey());
});
}
}
}
}

View File

@ -0,0 +1,70 @@
package cn.axzo.nanopart.doc.bizattri;
import cn.axzo.nanopart.doc.api.bizattri.request.CreateNodeBizAttributesRequest;
import cn.axzo.nanopart.doc.api.bizattri.request.SearchNodeBizAttributesRequest;
import cn.axzo.nanopart.doc.api.bizattri.request.UpdateNodeBizAttributesRequest;
import cn.axzo.nanopart.doc.api.bizattri.request.UpsertNodeBizAttributesRequest;
import cn.axzo.nanopart.doc.api.util.BizAssertions;
import cn.axzo.nanopart.doc.bizattri.dto.NodeBizAttributesDto;
import cn.axzo.nanopart.doc.dao.NodeBizAttributesDao;
import cn.axzo.nanopart.doc.entity.NodeBizAttributes;
import cn.hutool.core.bean.BeanUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Objects;
/**
* @author xudawei@axzo.cn
*/
@Slf4j
@RestController
@RequiredArgsConstructor
public class NodeBizAttributesManager {
private final NodeBizAttributesDao nodeBizAttributesDao;
public String create(CreateNodeBizAttributesRequest request) {
NodeBizAttributes attributes = NodeBizAttributes.builder()
.nodeCode(request.getNodeCode())
.attributes(BeanUtil.copyToList(request.getDrawMaterials(), NodeBizAttributes.Attributes.class))
.createBy(request.getCreateBy())
.updateBy(request.getUpdateBy())
.build();
nodeBizAttributesDao.save(attributes);
return attributes.getNodeCode();
}
public String update(UpdateNodeBizAttributesRequest request) {
NodeBizAttributes attributes = nodeBizAttributesDao.getByNodeCode(request.getNodeCode());
BizAssertions.assertNotNull(attributes, "查询结点配置信息为空");
attributes.setAttributes(BeanUtil.copyToList(request.getUpdateContent().getDrawMaterials(), NodeBizAttributes.Attributes.class));
attributes.setUpdateBy(request.getUpdateBy());
nodeBizAttributesDao.saveOrUpdate(attributes);
return request.getNodeCode();
}
public String upsert(UpsertNodeBizAttributesRequest request) {
NodeBizAttributes attributes = nodeBizAttributesDao.getByNodeCode(request.getNodeCode());
if (Objects.isNull(attributes) || Objects.isNull(attributes.getId())) {
attributes = new NodeBizAttributes();
attributes.setNodeCode(request.getNodeCode());
attributes.setCreateBy(request.getCreateBy());
}
attributes.setAttributes(BeanUtil.copyToList(request.getDrawMaterials(), NodeBizAttributes.Attributes.class));
attributes.setUpdateBy((Objects.nonNull(request.getUpdateBy()) && !Objects.equals(request.getUpdateBy(), 0L)) ? request.getUpdateBy() : request.getCreateBy());
nodeBizAttributesDao.saveOrUpdate(attributes);
return request.getNodeCode();
}
public List<NodeBizAttributes> search(SearchNodeBizAttributesRequest request) {
return nodeBizAttributesDao.list(BeanUtil.copyProperties(request, NodeBizAttributesDto.class));
}
}

View File

@ -0,0 +1,24 @@
package cn.axzo.nanopart.doc.bizattri.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author xudawei@axzo.cn
* @date 2025/3/27
* @description 结点配置信息
*/
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class NodeBizAttributesDto {
/**
* 结点编码
*/
private String nodeCode;
}

View File

@ -5,6 +5,9 @@ import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import cn.axzo.nanopart.doc.api.enums.DatabaseScope;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;
@ -54,6 +57,15 @@ public class IndexNodeDao extends ServiceImpl<IndexNodeMapper, IndexNode> {
.one();
}
public List<IndexNode> findByCodes(List<String> codes) {
if (CollectionUtils.isEmpty(codes)) {
return Lists.newArrayList();
}
return lambdaQuery() //
.in(IndexNode::getCode, codes) //
.list();
}
public void updatePath(String code, String path) {
lambdaUpdate() //
.eq(IndexNode::getCode, code) //

View File

@ -0,0 +1,52 @@
package cn.axzo.nanopart.doc.dao;
import cn.axzo.nanopart.doc.bizattri.dto.NodeBizAttributesDto;
import cn.axzo.nanopart.doc.entity.NodeBizAttributes;
import cn.axzo.nanopart.doc.mapper.NodeBizAttributesMapper;
import com.aliyuncs.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @author xudawei@axzo.cn
* @date 2025/03/27
*/
@Slf4j
@Repository
public class NodeBizAttributesDao extends ServiceImpl<NodeBizAttributesMapper, NodeBizAttributes> {
/**
* 根据nodeCode获取对象
*/
public NodeBizAttributes getByNodeCode(String nodeCode) {
if (StringUtils.isEmpty(nodeCode)) {
return null;
}
LambdaQueryWrapper<NodeBizAttributes> last = this.queryWrapper(NodeBizAttributesDto.builder().nodeCode(nodeCode).build()).last("limit 1");
return this.list(last).stream().findFirst().orElse(null);
}
/**
* 通用查询目前只有nodeCode
*/
private LambdaQueryWrapper<NodeBizAttributes> queryWrapper(NodeBizAttributesDto dto) {
LambdaQueryWrapper<NodeBizAttributes> lambdaQueryWrapper = new LambdaQueryWrapper<NodeBizAttributes>();
lambdaQueryWrapper.eq(NodeBizAttributes::getNodeCode, dto.getNodeCode())
.eq(NodeBizAttributes::getIsDelete, 0L);
return lambdaQueryWrapper;
}
/**
* 查询对象列表
*/
public List<NodeBizAttributes> list(NodeBizAttributesDto dto) {
return this.list(this.queryWrapper(dto));
}
}

View File

@ -0,0 +1,117 @@
package cn.axzo.nanopart.doc.entity;
import cn.axzo.nanopart.doc.api.enums.State;
import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 结点配置信息
* @author xudawei@axzo.cn
* @date 2025/03/27
*/
@Data
@TableName(value = "doc_node_biz_attributes", autoResultMap = true)
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class NodeBizAttributes extends BaseEntity<NodeBizAttributes> {
/**
* 结点编码
*/
@TableField("node_code")
private String nodeCode;
/**
* 状态. VALID: 有效的, DELETED: 已删除
*/
@TableField("state")
private State state;
/**
* 属性
*/
@TableField(typeHandler = IgnorePropsJsonTypeHandler.class)
private List<Attributes> attributes;
/**
* 创建人
*/
@TableField("create_by")
private Long createBy;
/**
* 更新人
*/
@TableField("update_by")
private Long updateBy;
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public static class Attributes {
/**
* 标题
*/
private String title;
/**
* 图纸
*/
private String drawId;
/**
* 内容
*/
private List<Content> contents;
/**
* 创建时间
*/
private Long createAtTime;
/**
* 创建时间
*/
private String createAt;
}
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public static class Content {
/**
* 图片的fileKey
*/
private String picFileKey;
/**
* 名称
*/
private String name;
/**
* 素材
*/
private String annoId;
/**
* 创建时间
*/
private Long createAtTime;
/**
* 创建时间
*/
private String createAt;
}
}

View File

@ -1,8 +1,22 @@
package cn.axzo.nanopart.doc.file.anonymous;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Future;
import java.util.function.Function;
import java.util.stream.Collectors;
import cn.axzo.nanopart.doc.api.domain.IndexNodeInfo;
import cn.axzo.nanopart.doc.api.index.request.BatchGetNodeInfoRequest;
import cn.axzo.nanopart.doc.integration.OssClient;
import cn.axzo.oss.http.model.ApiSignUrlDownloadResponse;
import cn.hutool.core.bean.BeanUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RestController;
import cn.axzo.basics.common.BeanMapper;
@ -33,6 +47,7 @@ public class DocAnonymousDatabaseApiController implements DocAnonymousDatabaseAp
private final IndexManager indexManager;
private final AsyncUtils asyncUtils;
private final OssClient ossClient;
@Override
public CommonResponse<String> createDir(AnonymousCreateDirRequest request) {
@ -94,4 +109,46 @@ public class DocAnonymousDatabaseApiController implements DocAnonymousDatabaseAp
return CommonResponse.success(BeanMapper.copyBean(indexNode, IndexNodeInfo.class));
}
/**
* 批量获取节点信息集合
*/
@Override
public CommonResponse<Map<String, IndexNodeInfo>> batchGetNodeInfo(BatchGetNodeInfoRequest request) {
if (Objects.isNull(request) || CollectionUtils.isEmpty(request.getCodes())) {
return CommonResponse.success(Collections.emptyMap());
}
List<IndexNode> indexNodes = indexManager.findByCodes(request.getCodes());
if (CollectionUtils.isEmpty(indexNodes)) {
return CommonResponse.success(Collections.emptyMap());
}
List<IndexNodeInfo> indexNodeInfos = BeanUtil.copyToList(indexNodes, IndexNodeInfo.class);
//填充对象中的fileKey/fileUrl
this.fillFileKeyUrl(request, indexNodeInfos);
Map<String, IndexNodeInfo> nodeInfoMap = indexNodeInfos.stream()
.collect(Collectors.toMap(item -> item.getCode(), Function.identity(), (x, y) -> x));
return CommonResponse.success(nodeInfoMap);
}
/**
* 填充对象中的fileKey/fileUrl
*/
private void fillFileKeyUrl(BatchGetNodeInfoRequest request, List<IndexNodeInfo> indexNodeInfos) {
if (request.getNeedFileUrl()) {
Set<String> fileKeys = indexNodeInfos.stream().filter(item -> StringUtils.hasText(item.getOrCreateFileAttributes().getOssFileKey()))
.map(item -> item.getOrCreateFileAttributes().getOssFileKey())
.collect(Collectors.toSet());
if (CollectionUtils.isNotEmpty(fileKeys)) {
List<ApiSignUrlDownloadResponse> urlResponses = ossClient.batchGetOssUrl(fileKeys);
Map<String, String> fileKeyAndUrlMap = urlResponses.stream().collect(Collectors.toMap(key -> key.getFileKey(), value -> value.getSignUrl(), (x, y) -> x));
indexNodeInfos.stream().filter(item -> StringUtils.hasText(item.getOrCreateFileAttributes().getOssFileKey()))
.forEach(item -> {
item.setOssFileKey(item.getOrCreateFileAttributes().getOssFileKey());
item.setOssFileUrl(fileKeyAndUrlMap.get(item.getOssFileKey()));
});
}
}
}
}

View File

@ -257,6 +257,10 @@ public class IndexManager {
return indexNodeDao.getOrThrow(code);
}
public List<IndexNode> findByCodes(List<String> codes) {
return indexNodeDao.findByCodes(codes);
}
public void updateBizInfo(String code, String bizCode, String description, String icon) {
if (StringUtils.isBlank(bizCode) && StringUtils.isBlank(description) && StringUtils.isBlank(icon))
return;

View File

@ -8,6 +8,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
@ -152,4 +153,21 @@ public class OssClient {
docLogDao.log(context, subject, logContents);
}
public List<ApiSignUrlDownloadResponse> batchGetOssUrl(Set<String> ossFileKeys) {
if (CollectionUtils.isEmpty(ossFileKeys)) {
return Collections.emptyList();
}
ApiSignUrlDownloadRequest request = new ApiSignUrlDownloadRequest();
request.setFileKeys(Lists.newArrayList(ossFileKeys));
try {
log.info("OssClient-batchGetOssUrl params:{}", JSON.toJSONString(ossFileKeys));
CommonResponse<List<ApiSignUrlDownloadResponse>> response = serverFileServiceApi.signUrlFetchDownload(request);
log.info("OssClient-batchGetOssUrl params:{},result:{}", JSON.toJSONString(ossFileKeys), JSON.toJSONString(response));
return response.getData();
} catch (Exception e) {
log.warn("OssClient-batchGetOssUrl exception, fileKeys:{}", JSON.toJSONString(ossFileKeys), e);
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,16 @@
package cn.axzo.nanopart.doc.mapper;
import cn.axzo.nanopart.doc.entity.NodeBizAttributes;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 结点配置信息
* @author xudawei@axzo.cn
* @date 2025/03/27
*/
@Mapper
public interface NodeBizAttributesMapper extends BaseMapper<NodeBizAttributes> {
}

View File

@ -62,40 +62,41 @@ public class GuideTenantProcedureStatusServiceImpl extends ServiceImpl<GuideTena
return Collections.emptyList();
}
// 将租户操作步骤数量与模板操作步骤数量进行对比如果模板操作步骤数量大于租户操作步骤数量则根据模板为租户初始化新步骤点
if (templateList.size() > procedureStatusList.size()) {
// 将该租户未初始化的步骤点进行初始化
List<Long> procedureStatusIdList = procedureStatusList.stream().map(GuideTenantProcedureStatus::getProcedureId).collect(Collectors.toList());
respList.addAll(templateList.stream()
.filter(t -> !procedureStatusIdList.contains(t.getId()))
.map(t -> {
GuideTenantProcedureStatusCreateReq createReq = new GuideTenantProcedureStatusCreateReq();
createReq.setWorkspaceId(req.getWorkspaceId());
createReq.setCategoryCode(t.getCategoryCode());
createReq.setProcedureId(t.getId());
createReq.setProcedureName(t.getName());
createReq.setStatus(GuideProcedureStatus.TODO);
create(createReq);
return BeanUtil.copyProperties(createReq, GuideTenantProcedureStatusListResp.class);
})
.collect(Collectors.toList()));
} else if (templateList.size() < procedureStatusList.size()) {
log.warn("操作步骤模板:{},租户&分类:{},租户操作步骤状态:{}", JSONUtil.toJsonStr(templateList), JSONUtil.toJsonStr(req), JSONUtil.toJsonStr(procedureStatusList));
throw new ServiceException("数据异常,操作步骤不存在,请联系管理人员");
// 将租户操作步骤数量与模板操作步骤数量进行对比是否需要根据模板为租户初始化新步骤点
// 将该租户未初始化的步骤点进行初始化
List<Long> procedureStatusIdList = procedureStatusList.stream().map(GuideTenantProcedureStatus::getProcedureId).distinct().collect(Collectors.toList());
List<GuideTenantProcedureStatusListResp> newInitProcedures = templateList.stream()
.filter(t -> !procedureStatusIdList.contains(t.getId()))
.map(t -> {
GuideTenantProcedureStatusCreateReq createReq = new GuideTenantProcedureStatusCreateReq();
createReq.setWorkspaceId(req.getWorkspaceId());
createReq.setCategoryCode(t.getCategoryCode());
createReq.setProcedureId(t.getId());
createReq.setProcedureName(t.getName());
createReq.setStatus(GuideProcedureStatus.TODO);
create(createReq);
return BeanUtil.copyProperties(createReq, GuideTenantProcedureStatusListResp.class);
})
.collect(Collectors.toList());
if (CollUtil.isNotEmpty(newInitProcedures)) {
respList.addAll(newInitProcedures);
}
// 对租户操作步骤的权限码和跳转链接进行补充
Map<Long, GuideProcedureTemplateResp> templateMap = templateList.stream().collect(Collectors.toMap(GuideProcedureTemplateResp::getId, Function.identity(), (v1, v2) -> v1));
respList.forEach(r -> {
GuideProcedureTemplateResp t = templateMap.get(r.getProcedureId());
r.setDescription(t.getDescription());
r.setIsMust(t.getIsMust());
r.setAuthCode(t.getAuthCode());
r.setJumpUrl(t.getJumpUrl());
r.setJumpReport(t.getJumpReport());
r.setSort(t.getSort());
});
return respList;
return respList.stream()
.collect(Collectors.toMap(r -> r.getWorkspaceId() + "_" + r.getProcedureId(), Function.identity(), (v1, v2) -> v1))
.values().stream()
.peek(r -> {
GuideProcedureTemplateResp t = templateMap.get(r.getProcedureId());
r.setDescription(t.getDescription());
r.setIsMust(t.getIsMust());
r.setAuthCode(t.getAuthCode());
r.setJumpUrl(t.getJumpUrl());
r.setJumpReport(t.getJumpReport());
r.setSort(t.getSort());
})
.collect(Collectors.toList());
}
@Override
@ -127,12 +128,15 @@ public class GuideTenantProcedureStatusServiceImpl extends ServiceImpl<GuideTena
log.info("步骤已完成无需重复操作workspaceId: {}, procedureId{}", req.getWorkspaceId(), req.getProcedureId());
return;
}
tenantProcedure.setStatus(req.getStatus());
updateById(tenantProcedure);
lambdaUpdate()
.eq(GuideTenantProcedureStatus::getWorkspaceId, req.getWorkspaceId())
.eq(GuideTenantProcedureStatus::getProcedureId, req.getProcedureId())
.set(GuideTenantProcedureStatus::getStatus, req.getStatus())
.update();
}
@Override
public Long create(GuideTenantProcedureStatusCreateReq req) {
public synchronized Long create(GuideTenantProcedureStatusCreateReq req) {
// 若操作所属分类或操作名称为空则从对应模板获取
if (Objects.isNull(req.getCategoryCode()) || CharSequenceUtil.isBlank(req.getProcedureName())) {
GuideProcedureTemplateResp byProcedureId = procedureTemplateService.getByProcedureId(req.getProcedureId());