接口开发

This commit is contained in:
liang.chao 2025-09-24 18:31:00 +08:00
parent d88ae6b2f6
commit 7576b5f4c2
15 changed files with 351 additions and 40 deletions

View File

@ -1,6 +1,7 @@
package com.bonus.framework.config;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -17,21 +18,23 @@ import com.bonus.framework.interceptor.RepeatSubmitInterceptor;
/**
* 通用配置
*
*
* @author ruoyi
*/
@Configuration
public class ResourcesConfig implements WebMvcConfigurer
{
public class ResourcesConfig implements WebMvcConfigurer {
@Autowired
private RepeatSubmitInterceptor repeatSubmitInterceptor;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
/** 本地文件上传路径 */
registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**")
.addResourceLocations("file:" + RuoYiConfig.getProfile() + "/");
public void addResourceHandlers(ResourceHandlerRegistry registry) {
String profilePath = RuoYiConfig.getProfile();
String filePath = "file:/" + profilePath.replace("\\", "/");
registry.addResourceHandler("/profile/**")
.addResourceLocations(filePath + "/")
.setCachePeriod(0);
/** swagger配置 */
registry.addResourceHandler("/swagger-ui/**")
@ -43,8 +46,7 @@ public class ResourcesConfig implements WebMvcConfigurer
* 自定义拦截规则
*/
@Override
public void addInterceptors(InterceptorRegistry registry)
{
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
}
@ -52,8 +54,7 @@ public class ResourcesConfig implements WebMvcConfigurer
* 跨域配置
*/
@Bean
public CorsFilter corsFilter()
{
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
// 设置访问源地址
config.addAllowedOriginPattern("*");
@ -69,4 +70,4 @@ public class ResourcesConfig implements WebMvcConfigurer
// 返回新的CorsFilter
return new CorsFilter(source);
}
}
}

View File

@ -19,27 +19,63 @@ import com.bonus.common.utils.StringUtils;
/**
* token过滤器 验证token有效性
*
* 支持从请求头和请求参数中获取token
*
* @author ruoyi
*/
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
{
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Autowired
private TokenService tokenService;
// Token在请求头中的名称
private static final String AUTH_HEADER = "Authorization";
// Token在请求参数中的名称
private static final String AUTH_PARAM = "token";
// Bearer token前缀
private static final String BEARER_PREFIX = "Bearer ";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException
{
LoginUser loginUser = tokenService.getLoginUser(request);
if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication()))
{
tokenService.verifyToken(loginUser);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
throws ServletException, IOException {
// 从多个来源获取token
String token = getTokenFromRequest(request);
if (StringUtils.isNotEmpty(token)) {
LoginUser loginUser = tokenService.getLoginUser(token);
if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) {
tokenService.verifyToken(loginUser);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
}
chain.doFilter(request, response);
}
/**
* 从请求中获取token支持多种方式
* 1. 请求头 Authorization: Bearer {token}
* 2. 请求参数 token={token}
*
* @param request HTTP请求
* @return token字符串
*/
private String getTokenFromRequest(HttpServletRequest request) {
String token = null;
// 方式1从Authorization请求头中获取
String authHeader = request.getHeader(AUTH_HEADER);
if (StringUtils.isNotEmpty(authHeader) && authHeader.startsWith(BEARER_PREFIX)) {
token = authHeader.substring(BEARER_PREFIX.length());
}
// 方式2从请求参数中获取如果请求头中没有找到
if (StringUtils.isEmpty(token)) {
token = request.getParameter(AUTH_PARAM);
}
return token;
}
}

View File

@ -25,7 +25,7 @@ import io.jsonwebtoken.SignatureAlgorithm;
/**
* token验证处理
*
*
* @author ruoyi
*/
@Component
@ -56,7 +56,7 @@ public class TokenService
/**
* 获取用户身份信息
*
*
* @return 用户信息
*/
public LoginUser getLoginUser(HttpServletRequest request)
@ -81,6 +81,27 @@ public class TokenService
}
return null;
}
public LoginUser getLoginUser(String token)
{
// 获取请求携带的令牌
if (StringUtils.isNotEmpty(token))
{
try
{
Claims claims = parseToken(token);
// 解析对应的权限以及用户信息
String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
String userKey = getTokenKey(uuid);
LoginUser user = redisCache.getCacheObject(userKey);
return user;
}
catch (Exception e)
{
log.error("获取用户信息异常'{}'", e.getMessage());
}
}
return null;
}
/**
* 设置用户身份信息
@ -107,7 +128,7 @@ public class TokenService
/**
* 创建令牌
*
*
* @param loginUser 用户信息
* @return 令牌
*/
@ -126,7 +147,7 @@ public class TokenService
/**
* 验证令牌有效期相差不足20分钟自动刷新缓存
*
*
* @param loginUser 登录信息
* @return 令牌
*/
@ -142,7 +163,7 @@ public class TokenService
/**
* 刷新令牌有效期
*
*
* @param loginUser 登录信息
*/
public void refreshToken(LoginUser loginUser)
@ -156,7 +177,7 @@ public class TokenService
/**
* 设置用户代理信息
*
*
* @param loginUser 登录信息
*/
public void setUserAgent(LoginUser loginUser)

View File

@ -67,11 +67,6 @@
<groupId>com.bonus</groupId>
<artifactId>bonus-system</artifactId>
</dependency>
<dependency>
<groupId>com.bonus</groupId>
<artifactId>water-design-const</artifactId>
<version>3.8.9</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>

View File

@ -0,0 +1,62 @@
package com.bonus.waterdesign.controller.utils;
import com.bonus.waterdesign.domain.FileDto;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.util.*;
/**
* 文件处理工具类
*
* @author bonus
*/
@Component
public class FileUtils {
private static String UPLOAD_DIR;
@Value("${ruoyi.profile}")
private String uploadDir;
@PostConstruct
public void init() {
UPLOAD_DIR = uploadDir;
}
public FileDto upload(MultipartFile file) throws IOException {
FileDto bean = new FileDto();
if (file != null && !file.isEmpty()) {
// 验证文件类型
String originalFileName = file.getOriginalFilename();
String fileExtension = originalFileName != null ? originalFileName.split("\\.")[1] : "";
File targetDir = new File(UPLOAD_DIR);
if (!targetDir.exists()) {
targetDir.mkdirs();
}
String fileName = file.getOriginalFilename();
// 构建本地存储路径
File uploadDir = new File(UPLOAD_DIR, "file");
if (!uploadDir.exists()) {
uploadDir.mkdirs();
}
File targetFile = new File(uploadDir, fileName);
file.transferTo(targetFile);
// 存储相对路径统一使用 "/"不使用 File.separator
String relativePath = "/file/" + fileName;
bean.setFilePath(relativePath);
bean.setFileName(fileName);
bean.setSuffixName(fileExtension);
return bean;
} else {
return bean;
}
}
}

View File

@ -12,6 +12,8 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@ -30,12 +32,23 @@ public class ModelController extends BaseController {
*/
@PreAuthorize("@ss.hasPermi('model:list')")
@GetMapping("/list")
public TableDataInfo list(ProjectVo model)
{
public TableDataInfo list(ProjectVo model) {
List<ProjectVo> list = modelService.list(model);
return getDataTable(list);
}
@GetMapping("/listSelect")
public AjaxResult listSelect(ProjectVo model) {
List<ProjectVo> list = modelService.list(model);
List<ProjectVo> list1 = new ArrayList<>();
for (ProjectVo projectVo : list) {
if (projectVo.getNodelevel().equals(projectVo.getNodeCount().toString())) {
list1.add(projectVo);
}
}
return AjaxResult.success(list1);
}
/**
* 新增模型
*/
@ -60,6 +73,27 @@ public class ModelController extends BaseController {
}
@PostMapping("/openAllView")
public AjaxResult openAllView(@RequestBody PeojectNodes node) throws FactoryException, TransformException {
ProjectVo model = new ProjectVo();
List<String> ids = new ArrayList<>();
model.setProjectId(node.getProjectId());
List<ProjectVo> list = modelService.list(model);
for (ProjectVo projectVo : list) {
if (projectVo.getNodelevel().equals(projectVo.getNodeCount().toString())) {
ids.add(projectVo.getId());
}
}
if (ids.size() > 0) {
node.setIds(ids);
} else return AjaxResult.success(new ArrayList<>());
//获取所有的节点信息
List<CadData> listData = modelService.openAllView(node);
//返回list信息给前台
return AjaxResult.success(listData);
}
@PostMapping("/delete")
public AjaxResult delete(@RequestBody PeojectNodes node) {

View File

@ -40,6 +40,12 @@ public class ProjectController extends BaseController {
List<Project> list = projectService.selectProjectList(project);
return getDataTable(list);
}
@GetMapping("/listApp")
public AjaxResult listApp(Project project) {
// project.setCreateBy(getUserId().toString());
List<Project> list = projectService.selectProjectList(project);
return AjaxResult.success(list);
}
/**
* 获取项目下拉框

View File

@ -5,8 +5,10 @@ import com.bonus.common.core.controller.BaseController;
import com.bonus.common.core.domain.AjaxResult;
import com.bonus.common.core.page.TableDataInfo;
import com.bonus.common.enums.BusinessType;
import com.bonus.common.utils.file.FileUploadUtils;
import com.bonus.common.utils.DateUtils;
import com.bonus.common.utils.poi.ExcelUtil;
import com.bonus.waterdesign.controller.utils.FileUtils;
import com.bonus.waterdesign.domain.FileDto;
import com.bonus.waterdesign.domain.Survey;
import com.bonus.waterdesign.service.SurveyService;
import org.springframework.beans.factory.annotation.Autowired;
@ -31,6 +33,9 @@ public class SurveyController extends BaseController {
@Autowired
private SurveyService surveyService;
@Autowired
private FileUtils fileUtils;
/**
* 获取勘查列表
*/
@ -77,8 +82,20 @@ public class SurveyController extends BaseController {
@PreAuthorize("@ss.hasPermi('basic:survey:add')")
@Log(title = "勘查管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody Survey survey) {
public AjaxResult add(@RequestPart("file") MultipartFile file,
@RequestParam("projectId") String projectId,
@RequestParam("type") String type,
@RequestParam("selectedNodeId") String selectedNodeId,
@RequestParam("selectedNodeName") String selectedNodeName) throws IOException {
FileDto upload = fileUtils.upload(file);
Survey survey = new Survey();
survey.setCreateBy(getUsername());
survey.setSurveyUser(getUsername());
survey.setSurveyTime(DateUtils.getDate());
survey.setProId(Long.parseLong(projectId));
survey.setModelId(selectedNodeId);
survey.setModelName(selectedNodeName);
survey.setSurveyAttach(upload.getFilePath());
return toAjax(surveyService.insertSurvey(survey));
}

View File

@ -39,6 +39,7 @@ public class CadData {
* 多点坐标适用于 LWPOLYLINE
*/
private String points;
private String nodeId;
/**
* 完整 geometry JSON备份原始结构

View File

@ -0,0 +1,21 @@
package com.bonus.waterdesign.domain;
import lombok.Data;
import java.math.BigDecimal;
/**
* @Authorliang.chao
* @Date2025/9/17 - 13:56
*/
@Data
public class FileDto {
// 文件名称
private String fileName;
// 文件路径
private String filePath;
// 文件类型 1.图片 2.视频
private String fileType;
// 文件后缀名
private String suffixName;
}

View File

@ -3,6 +3,8 @@ package com.bonus.waterdesign.domain;
import lombok.Data;
import java.util.List;
@Data
public class PeojectNodes {
@ -11,6 +13,7 @@ public class PeojectNodes {
private String proName;
private String id;
private List<String> ids;
private String level;

View File

@ -4,6 +4,7 @@ import com.bonus.waterdesign.domain.CadData;
import com.bonus.waterdesign.domain.Model;
import com.bonus.waterdesign.domain.PeojectNodes;
import com.bonus.waterdesign.domain.ProjectVo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@ -19,4 +20,6 @@ public interface ModelMapper {
boolean update(PeojectNodes node);
List<CadData> openView(PeojectNodes node);
List<CadData> openAllView(@Param("ids") List<String> ids);
}

View File

@ -18,4 +18,5 @@ public interface ModelService {
boolean update(PeojectNodes node);
List<CadData> openView(PeojectNodes node) throws FactoryException, TransformException;
List<CadData> openAllView(PeojectNodes node) throws FactoryException, TransformException;
}

View File

@ -10,6 +10,8 @@ import com.bonus.waterdesign.mapper.ProjectMapper;
import com.bonus.waterdesign.service.ModelService;
import lombok.extern.slf4j.Slf4j;
import org.locationtech.proj4j.*;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.operation.TransformException;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@ -222,4 +224,90 @@ public class ModelServiceImpl implements ModelService {
}
return cadData;
}
@Override
public List<CadData> openAllView(PeojectNodes node) throws FactoryException, TransformException {
List<CadData> cadData = modelMapper.openAllView(node.getIds());
try {
CRSFactory crsFactory = new CRSFactory();
CoordinateTransformFactory ctFactory = new CoordinateTransformFactory();
// 定义坐标系CGCS2000 GK Zone 20 WGS84
CoordinateReferenceSystem gkZone20 = crsFactory.createFromParameters("EPSG:4498",
"+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs");
CoordinateReferenceSystem wgs84 = crsFactory.createFromName("EPSG:4326");
CoordinateTransform transform = ctFactory.createTransform(gkZone20, wgs84);
for (CadData cadDatum : cadData) {
String geometry = cadDatum.getGeometry();
JSONObject jsonObject = JSON.parseObject(geometry);
if (jsonObject.get("type").equals("LINE")) {
JSONArray startArray = jsonObject.getJSONArray("start");
JSONArray endArray = jsonObject.getJSONArray("end");
// 获取第一个元素X坐标
double x = startArray.getDouble(0);
// 获取第二个元素Y坐标
double y = startArray.getDouble(1);
// 获取第一个元素X坐标
double x1 = endArray.getDouble(0);
// 获取第二个元素Y坐标
double y1 = endArray.getDouble(1);
// 原始坐标
ProjCoordinate startGk = new ProjCoordinate(x, y);
ProjCoordinate endGk = new ProjCoordinate(x1, y1);
// 转换
ProjCoordinate startWgs84 = new ProjCoordinate();
ProjCoordinate endWgs84 = new ProjCoordinate();
transform.transform(startGk, startWgs84);
transform.transform(endGk, endWgs84);
startArray.set(0, startWgs84.x);
startArray.set(1, startWgs84.y);
endArray.set(0, endWgs84.x);
endArray.set(1, endWgs84.y);
cadDatum.setGeometry(jsonObject.toString());
}
if (jsonObject.get("type").equals("LWPOLYLINE")) {
JSONArray pointsArray = jsonObject.getJSONArray("points");
for (int i = 0; i < pointsArray.size(); i++) {
JSONArray point = pointsArray.getJSONArray(i);
double x = point.getDouble(0);
double y = point.getDouble(1);
// 原始坐标
ProjCoordinate pointstGk = new ProjCoordinate(x, y);
// 转换
ProjCoordinate pointstGkWgs84 = new ProjCoordinate();
transform.transform(pointstGk, pointstGkWgs84);
point.set(0, pointstGkWgs84.x);
point.set(1, pointstGkWgs84.y);
}
cadDatum.setGeometry(jsonObject.toString());
}
if (jsonObject.get("type").equals("CIRCLE")) {
JSONArray centerArray = jsonObject.getJSONArray("center");
// 获取第一个元素X坐标
double x = centerArray.getDouble(0);
// 获取第二个元素Y坐标
double y = centerArray.getDouble(1);
// 原始坐标
ProjCoordinate startGk = new ProjCoordinate(x, y);
ProjCoordinate startWgs84 = new ProjCoordinate();
transform.transform(startGk, startWgs84);
centerArray.set(0, startWgs84.x);
centerArray.set(1, startWgs84.y);
cadDatum.setGeometry(jsonObject.toString());
}
}
} catch (Exception e) {
e.printStackTrace();
}
return cadData;
}
}

View File

@ -159,4 +159,26 @@
WHERE
project_id = #{id}
</select>
<select id="openAllView" resultType="com.bonus.waterdesign.domain.CadData">
SELECT
id,
layer_name AS layerName,
entity_type AS entityType,
color,
lineweight,
thickness,
transparency,
start_point AS startPoint,
end_point AS endPoint,
center_point AS centerPoint,
radius,
points,
geometry,
project_id as nodeId
FROM cad_data
WHERE project_id IN
<foreach item="projectId" index="index" collection="ids" open="(" separator="," close=")">
#{projectId}
</foreach>
</select>
</mapper>