This commit is contained in:
六如
2024-10-11 09:59:52 +08:00
parent cff2ee120b
commit 35b3e6489d
13 changed files with 307 additions and 55 deletions

View File

@@ -0,0 +1,41 @@
package com.gitee.sop.adminbackend.common.jackson;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Locale;
import java.util.TimeZone;
/**
* 日期序列化配置类
*/
@Data
@ConfigurationProperties(prefix = "jackson")
public class DateConverterProperties {
/**
* Date/LocalDateTime 格式化
*/
private String dateTimeFormat = "yyyy-MM-dd HH:mm:ss";
/**
* localDate 格式化
*/
private String localDateFormat = "yyyy-MM-dd";
/**
* localTime 格式化
*/
private String localTimeFormat = "HH:mm:ss";
/**
* 时区, 默认 GMT+8
*/
private TimeZone timeZone = TimeZone.getTimeZone("GMT+8");
/**
* 地区, 默认 zh_CN
*/
private Locale locale = Locale.CHINA;
}

View File

@@ -0,0 +1,147 @@
package com.gitee.sop.adminbackend.common.jackson;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
/**
* 基于Jackson的日期格式配置
*/
@Slf4j
@Configuration
@EnableConfigurationProperties(DateConverterProperties.class)
public class JacksonDateConverterConfig {
@Autowired
private DateConverterProperties props;
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
log.info("@================= 初始化jackson日期序列化 ==================@");
log.info("Locale : 【{}】", props.getLocale());
log.info("TimeZone : 【{}】", props.getTimeZone().getDisplayName());
log.info("Date : 【{}】", props.getDateTimeFormat());
log.info("LocalDateTime : 【{}】", props.getDateTimeFormat());
log.info("LocalDate : 【{}】", props.getLocalDateFormat());
log.info("LocalTime : 【{}】", props.getLocalTimeFormat());
final DateTimeFormatter dateTimeFormatter = this.ofPattern(props.getDateTimeFormat());
final DateTimeFormatter localDateFormatter = this.ofPattern(props.getLocalDateFormat());
final DateTimeFormatter localTimeFormatter = this.ofPattern(props.getLocalTimeFormat());
final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(props.getDateTimeFormat());
return builder -> {
builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
// 地区
.locale(props.getLocale())
// 时区
.timeZone(props.getTimeZone());
// 序列化
builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter))
.serializerByType(LocalDate.class, new LocalDateSerializer(localDateFormatter))
.serializerByType(LocalTime.class, new LocalTimeSerializer(localTimeFormatter))
.serializerByType(Date.class, new DateSerializer(false, simpleDateFormat));
// 反序列化
builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter))
.deserializerByType(LocalDate.class, new LocalDateDeserializer(localDateFormatter))
.deserializerByType(LocalTime.class, new LocalTimeDeserializer(localTimeFormatter))
.deserializerByType(Date.class,
new DateDeserializers.DateDeserializer(DateDeserializers.DateDeserializer.instance,
simpleDateFormat, props.getDateTimeFormat()));
};
}
/**
* 根据字符串 获取 DateTimeFormatter
*
* @param pattern 日期格式字符串
* @return DateTimeFormatter
*/
private DateTimeFormatter ofPattern(String pattern) {
return DateTimeFormatter.ofPattern(pattern);
}
/**
* LocalDate转换器用于转换RequestParam和PathVariable参数
*/
@Bean
public Converter<String, LocalDate> localDateConverter() {
return new Converter<String, LocalDate>() {
@Override
public LocalDate convert(String source) {
return LocalDate.parse(source, DateTimeFormatter.ofPattern(props.getLocalDateFormat()));
}
};
}
/**
* LocalDateTime转换器用于转换RequestParam和PathVariable参数
*/
@Bean
public Converter<String, LocalDateTime> localDateTimeConverter() {
return new Converter<String, LocalDateTime>() {
@Override
public LocalDateTime convert(String source) {
return LocalDateTime.parse(source, DateTimeFormatter.ofPattern(props.getDateTimeFormat()));
}
};
}
/**
* LocalTime转换器用于转换RequestParam和PathVariable参数
*/
@Bean
public Converter<String, LocalTime> localTimeConverter() {
return new Converter<String, LocalTime>() {
@Override
public LocalTime convert(String source) {
return LocalTime.parse(source, DateTimeFormatter.ofPattern(props.getLocalTimeFormat()));
}
};
}
/**
* Date转换器用于转换RequestParam和PathVariable参数
*/
@Bean
public Converter<String, Date> dateConverter() {
return new Converter<String, Date>() {
@Override
public Date convert(String source) {
final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(props.getDateTimeFormat());
try {
return simpleDateFormat.parse(source);
} catch (ParseException e) {
log.error(">>>> init Converter String to Date error!", e);
throw new RuntimeException(e);
}
}
};
}
}

View File

@@ -66,12 +66,12 @@ public class IsvInfoController {
/** /**
* 获取秘钥信息 * 获取秘钥信息
* *
* @param isvInfoId * @param isvId
* @return * @return
*/ */
@GetMapping("/getKeys") @GetMapping("/getKeys")
public Result<IsvKeysDTO> getKeys(Long isvInfoId) { public Result<IsvKeysDTO> getKeys(Long isvId) {
IsvKeysDTO isvKeysDTO = isvInfoService.getKeys(isvInfoId); IsvKeysDTO isvKeysDTO = isvInfoService.getKeys(isvId);
return Result.ok(isvKeysDTO); return Result.ok(isvKeysDTO);
} }

View File

@@ -3,6 +3,8 @@ package com.gitee.sop.adminbackend.controller.isv.req;
import lombok.Data; import lombok.Data;
import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
@@ -12,6 +14,13 @@ import javax.validation.constraints.NotNull;
@Data @Data
public class IsvInfoAddParam { public class IsvInfoAddParam {
/**
* 秘钥格式1PKCS8(JAVA适用)2PKCS1(非JAVA适用)
*/
@Min(value = 1, message = "秘钥格式错误")
@Max(value = 2, message = "秘钥格式错误")
private Integer keyFormat;
/** /**
* 1启用2禁用 * 1启用2禁用
*/ */

View File

@@ -23,7 +23,7 @@ public class IsvKeys {
/** /**
* isv_info.id * isv_info.id
*/ */
private Long isvInfoId; private Long isvId;
/** /**
* 秘钥格式1PKCS8(JAVA适用)2PKCS1(非JAVA适用) * 秘钥格式1PKCS8(JAVA适用)2PKCS1(非JAVA适用)

View File

@@ -24,7 +24,7 @@ public class PermIsvRole {
/** /**
* isv_info表id * isv_info表id
*/ */
private Long isvInfoId; private Long isvId;
/** /**
* 角色code * 角色code

View File

@@ -8,8 +8,8 @@ import com.gitee.sop.adminbackend.dao.entity.IsvKeys;
*/ */
public interface IsvKeysMapper extends BaseMapper<IsvKeys> { public interface IsvKeysMapper extends BaseMapper<IsvKeys> {
default IsvKeys getByAppId(String appId) { default IsvKeys getByIsvInfoId(Long isvId) {
return this.get(IsvKeys::getAppId, appId); return this.get(IsvKeys::getIsvId, isvId);
} }
} }

View File

@@ -43,6 +43,12 @@ public class IsvInfoService implements LambdaService<IsvInfo, IsvInfoMapper> {
return rsaTool.createKeys(); return rsaTool.createKeys();
} }
/**
* 添加ISV
* @param isvInfoAddDTO
* @return
* @throws Exception
*/
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public long add(IsvInfoAddDTO isvInfoAddDTO) throws Exception { public long add(IsvInfoAddDTO isvInfoAddDTO) throws Exception {
IsvInfo rec = CopyUtil.copyBean(isvInfoAddDTO, IsvInfo::new); IsvInfo rec = CopyUtil.copyBean(isvInfoAddDTO, IsvInfo::new);
@@ -53,25 +59,27 @@ public class IsvInfoService implements LambdaService<IsvInfo, IsvInfoMapper> {
if (CollectionUtils.isNotEmpty(isvInfoAddDTO.getRoleCodes())) { if (CollectionUtils.isNotEmpty(isvInfoAddDTO.getRoleCodes())) {
this.saveIsvRole(rec, isvInfoAddDTO.getRoleCodes()); this.saveIsvRole(rec, isvInfoAddDTO.getRoleCodes());
} }
IsvKeysGenDTO isvKeysGenVO = this.createIsvKeys(); // 生成秘钥
RSATool.KeyFormat keyFormat = RSATool.KeyFormat.of(isvInfoAddDTO.getKeyFormat());
IsvKeysGenDTO isvKeysGenVO = this.createIsvKeys(keyFormat);
IsvKeys isvKeys = new IsvKeys(); IsvKeys isvKeys = new IsvKeys();
isvKeys.setIsvInfoId(rec.getId()); isvKeys.setIsvId(rec.getId());
CopyUtil.copyPropertiesIgnoreNull(isvKeysGenVO, isvKeys); CopyUtil.copyPropertiesIgnoreNull(isvKeysGenVO, isvKeys);
isvKeysService.save(isvKeys); isvKeysService.save(isvKeys);
return rec.getId(); return rec.getId();
} }
private void saveIsvRole(IsvInfo isvInfo, List<String> roleCodeList) { private void saveIsvRole(IsvInfo isvInfo, List<String> roleCodeList) {
long isvInfoId = isvInfo.getId(); Long isvId = isvInfo.getId();
permIsvRoleService.query() permIsvRoleService.query()
.eq(PermIsvRole::getIsvInfoId, isvInfoId) .eq(PermIsvRole::getIsvId, isvId)
.delete(); .delete();
List<PermIsvRole> tobeSaveList = roleCodeList.stream() List<PermIsvRole> tobeSaveList = roleCodeList.stream()
.map(roleCode -> { .map(roleCode -> {
PermIsvRole rec = new PermIsvRole(); PermIsvRole rec = new PermIsvRole();
rec.setIsvInfoId(isvInfoId); rec.setIsvId(isvId);
rec.setRoleCode(roleCode); rec.setRoleCode(roleCode);
return rec; return rec;
}) })
@@ -88,10 +96,10 @@ public class IsvInfoService implements LambdaService<IsvInfo, IsvInfoMapper> {
// } // }
} }
private IsvKeysGenDTO createIsvKeys() throws Exception { private IsvKeysGenDTO createIsvKeys(RSATool.KeyFormat keyFormat) throws Exception {
IsvKeysGenDTO isvKeysGenDTO = new IsvKeysGenDTO(); IsvKeysGenDTO isvKeysGenDTO = new IsvKeysGenDTO();
RSATool.KeyStore keyStoreIsv = this.createKeys(RSATool.KeyFormat.PKCS8); RSATool.KeyStore keyStoreIsv = this.createKeys(keyFormat);
isvKeysGenDTO.setPublicKeyIsv(keyStoreIsv.getPublicKey()); isvKeysGenDTO.setPublicKeyIsv(keyStoreIsv.getPublicKey());
isvKeysGenDTO.setPrivateKeyIsv(keyStoreIsv.getPrivateKey()); isvKeysGenDTO.setPrivateKeyIsv(keyStoreIsv.getPrivateKey());
@@ -100,8 +108,8 @@ public class IsvInfoService implements LambdaService<IsvInfo, IsvInfoMapper> {
return isvKeysGenDTO; return isvKeysGenDTO;
} }
public IsvKeysDTO getKeys(Long isvInfoId) { public IsvKeysDTO getKeys(Long isvId) {
IsvKeys isvKeys = isvKeysService.get(IsvKeys::getIsvInfoId, isvInfoId); IsvKeys isvKeys = isvKeysService.get(IsvKeys::getIsvId, isvId);
return CopyUtil.copyBean(isvKeys, IsvKeysDTO::new); return CopyUtil.copyBean(isvKeys, IsvKeysDTO::new);
} }

View File

@@ -3,6 +3,8 @@ package com.gitee.sop.adminbackend.service.isv.dto;
import lombok.Data; import lombok.Data;
import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.util.List; import java.util.List;
@@ -13,6 +15,13 @@ import java.util.List;
@Data @Data
public class IsvInfoAddDTO { public class IsvInfoAddDTO {
/**
* 秘钥格式1PKCS8(JAVA适用)2PKCS1(非JAVA适用)
*/
@Min(value = 1, message = "秘钥格式错误")
@Max(value = 2, message = "秘钥格式错误")
private Integer keyFormat;
/** /**
* 1启用2禁用 * 1启用2禁用
*/ */

View File

@@ -2,3 +2,8 @@ export enum StatusEnum {
ENABLE = 1, ENABLE = 1,
DISABLE = 2 DISABLE = 2
} }
export enum KeyFormatEnum {
PKCS8 = 1,
PKCS1 = 2
}

View File

@@ -1,13 +1,14 @@
import { computed, ref } from "vue"; import { computed, type Ref, ref } from "vue";
import { import {
type ButtonsCallBackParams, type ButtonsCallBackParams,
type FieldValues, type FieldValues,
type OptionsRow,
type PageInfo, type PageInfo,
type PlusColumn, type PlusColumn,
useTable useTable
} from "plus-pro-components"; } from "plus-pro-components";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { StatusEnum } from "@/model/enums"; import { KeyFormatEnum, StatusEnum } from "@/model/enums";
import { api } from "@/api/isvList"; import { api } from "@/api/isvList";
const isAdd = ref(false); const isAdd = ref(false);
@@ -66,7 +67,7 @@ export const tableColumns: PlusColumn[] = [
{ {
label: "AppID", label: "AppID",
prop: "appId", prop: "appId",
width: 230 width: 250
}, },
{ {
label: "秘钥", label: "秘钥",
@@ -76,7 +77,7 @@ export const tableColumns: PlusColumn[] = [
{ {
label: "角色", label: "角色",
prop: "roleNames", prop: "roleNames",
width: 120 width: 200
}, },
{ {
label: "状态", label: "状态",
@@ -102,11 +103,13 @@ export const tableColumns: PlusColumn[] = [
}, },
{ {
label: "添加时间", label: "添加时间",
prop: "addTime" prop: "addTime",
width: 160
}, },
{ {
label: "修改时间", label: "修改时间",
prop: "updateTime" prop: "updateTime",
width: 160
} }
]; ];
// 表格按钮定义 // 表格按钮定义
@@ -165,52 +168,82 @@ export const dlgTitle = ref("");
// 表单值 // 表单值
const editFormDataGen = () => { const editFormDataGen = () => {
return { return {
id: "", id: 0,
appId: "", status: StatusEnum.ENABLE,
status: "", keyFormat: KeyFormatEnum.PKCS8,
remark: "", remark: ""
addTime: "",
updateTime: ""
}; };
}; };
export const editFormData = ref<FieldValues>(editFormDataGen()); export const editFormData = ref<FieldValues>(editFormDataGen());
export const editFormRules = { export const editFormRules = {};
id: [{ required: true, message: "请输入id" }],
appId: [{ required: true, message: "请输入appKey" }], // options推荐写法
status: [{ required: true, message: "请输入1启用2禁用" }] // 1. 定义一个 `ref`数组
const roleList: Ref<OptionsRow[]> = ref([]);
// 2. 异步函数获取到值赋值到 `ref`
const loadRole = async () => {
//
}; };
loadRole();
// 表单内容 // 表单内容
export const editFormColumns: PlusColumn[] = [ export const editFormColumns: PlusColumn[] = [
{
label: "id",
prop: "id",
valueType: "copy"
},
{ {
label: "AppID", label: "AppID",
prop: "appId", prop: "appId",
valueType: "copy" valueType: "copy",
fieldProps: {
disabled: true,
placeholder: "自动生成"
}
}, },
{ {
label: "1启用2禁用", label: "秘钥格式",
prop: "keyFormat",
valueType: "radio",
options: [
{
label: "PKCS8(Java适用)",
value: KeyFormatEnum.PKCS8
},
{
label: "PKCS1(非Java适用)",
value: KeyFormatEnum.PKCS1
}
]
},
{
label: "角色",
prop: "roleCodes",
valueType: "checkbox",
// options推荐写法
// 3. 用 computed 返回 ref 的 value
options: computed(() => roleList.value)
},
{
label: "状态",
prop: "status", prop: "status",
valueType: "copy" valueType: "radio",
options: [
{
label: "启用",
value: StatusEnum.ENABLE
},
{
label: "禁用",
value: StatusEnum.DISABLE
}
]
}, },
{ {
label: "备注", label: "备注",
prop: "remark", prop: "remark",
valueType: "copy" valueType: "textarea",
}, fieldProps: {
{ maxlength: 300,
label: "addTime", showWordLimit: true,
prop: "addTime", autosize: { minRows: 2, maxRows: 4 }
valueType: "copy" }
},
{
label: "updateTime",
prop: "updateTime",
valueType: "copy"
} }
]; ];

View File

@@ -77,7 +77,7 @@ export const showKeysFormColumns: PlusFormGroupRow[] = [
export const viewKeys = (row: any) => { export const viewKeys = (row: any) => {
const params = { const params = {
isvInfoId: row.id isvId: row.id
}; };
api.viewKeys(params).then(resp => { api.viewKeys(params).then(resp => {
showKeysFormData.value = resp.data; showKeysFormData.value = resp.data;

View File

@@ -271,14 +271,14 @@ public class IsvApi {
void saveIsvRole(IsvInfo isvInfo, List<String> roleCodeList) { void saveIsvRole(IsvInfo isvInfo, List<String> roleCodeList) {
Query query = new Query(); Query query = new Query();
long isvInfoId = isvInfo.getId(); Long isvId = isvInfo.getId();
query.eq("isv_id", isvInfoId); query.eq("isv_id", isvId);
permIsvRoleMapper.deleteByQuery(query); permIsvRoleMapper.deleteByQuery(query);
List<PermIsvRole> tobeSaveList = roleCodeList.stream() List<PermIsvRole> tobeSaveList = roleCodeList.stream()
.map(roleCode -> { .map(roleCode -> {
PermIsvRole rec = new PermIsvRole(); PermIsvRole rec = new PermIsvRole();
rec.setIsvId(isvInfoId); rec.setIsvId(isvId);
rec.setRoleCode(roleCode); rec.setRoleCode(roleCode);
return rec; return rec;
}) })