Browse Source

add theme update

main
wangshaoping 1 year ago
parent
commit
e2602ccde4
  1. 2
      io.sc.platform.core.frontend/package.json
  2. 1
      io.sc.platform.core.frontend/src/platform/i18n/messages.json
  3. 1
      io.sc.platform.core.frontend/src/platform/i18n/messages_tw_CN.json
  4. 1
      io.sc.platform.core.frontend/src/platform/i18n/messages_zh_CN.json
  5. 85
      io.sc.platform.core.frontend/src/platform/layout/sub-layout/ChangePasswordDialog.vue
  6. 14
      io.sc.platform.core.frontend/src/platform/layout/sub-layout/Topper.vue
  7. 10
      io.sc.platform.core.frontend/src/platform/plugin/axios.ts
  8. 17
      io.sc.platform.core.frontend/src/platform/utils/Tools.ts
  9. 4
      io.sc.platform.core.frontend/template-project/package.json
  10. 3
      io.sc.platform.core.frontend/webpack.env.serve.cjs
  11. 3
      io.sc.platform.core/src/main/java/io/sc/platform/core/ApplicationLauncher.java
  12. 3
      io.sc.platform.core/src/main/java/io/sc/platform/core/PlatformSpringBootServletInitializer.java
  13. 4
      io.sc.platform.core/src/main/java/io/sc/platform/core/bean/GlobalExceptionHandler.java
  14. 2
      io.sc.platform.core/src/main/java/io/sc/platform/core/compiler/JavaMemeryFileManager.java
  15. 4
      io.sc.platform.core/src/main/java/io/sc/platform/core/compiler/JavaMemoryCompiler.java
  16. 22
      io.sc.platform.core/src/main/java/io/sc/platform/core/exception/PlatformRuntimeException.java
  17. 11
      io.sc.platform.core/src/main/java/io/sc/platform/core/i18n/MessageSourceBaseName.java
  18. 2
      io.sc.platform.core/src/main/java/io/sc/platform/core/i18n/PlatformResourceBundleMessageSource.java
  19. 5
      io.sc.platform.core/src/main/java/io/sc/platform/core/plugins/PluginParser.java
  20. 19
      io.sc.platform.core/src/main/java/io/sc/platform/core/response/ResponseWrapperBuilder.java
  21. 2
      io.sc.platform.core/src/main/java/io/sc/platform/core/util/BeanUtil.java
  22. 33
      io.sc.platform.core/src/main/java/io/sc/platform/core/util/CollectionUtil.java
  23. 2
      io.sc.platform.core/src/main/java/io/sc/platform/core/util/HttpServletRequestUtil.java
  24. 26
      io.sc.platform.core/src/main/java/io/sc/platform/core/util/IpUtil.java
  25. 1
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words.properties
  26. 3
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_tw_CN.properties
  27. 3
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_zh_CN.properties
  28. 20
      io.sc.platform.developer.doc/asciidoc/9999-appendix/java/java.adoc
  29. 2
      io.sc.platform.security.loginform/src/main/java/io/sc/platform/security/loginform/autoconfigure/WebSecurityAutoConfiguration.java
  30. 4
      io.sc.platform.security.oauth2.server.authorization/src/main/java/io/sc/platform/security/oauth2/server/authorization/configure/PlatformOauth2AuthorizationServerAutoConfiguration.java
  31. 154
      io.sc.platform.security.oauth2.server.authorization/src/main/java/io/sc/platform/security/oauth2/server/authorization/configure/support/PlatformSecurityProperties.java
  32. 2
      io.sc.platform.security.oauth2.server.resource/src/main/java/io/sc/platform/security/oauth2/server/resource/configure/PlatformOauth2ResourceServerAutoConfiguration.java
  33. 2
      io.sc.platform.security.oauth2.server.resource/src/main/java/io/sc/platform/security/oauth2/server/resource/configure/support/PlatformJwtAuthenticationConverter.java
  34. 2
      io.sc.platform.security/src/main/java/io/sc/platform/security/SecurityClaimNames.java
  35. 2
      io.sc.platform.security/src/main/java/io/sc/platform/security/SecurityProperties.java
  36. 1
      io.sc.platform.security/src/main/java/io/sc/platform/security/autoconfigure/PlatformWebSecurityAutoConfiguration.java
  37. 2
      io.sc.platform.security/src/main/java/io/sc/platform/security/util/SecurityUtil.java
  38. 2
      io.sc.platform.system.frontend/package.json
  39. 9
      io.sc.platform.system.frontend/src/i18n/messages.json
  40. 9
      io.sc.platform.system.frontend/src/i18n/messages_tw_CN.json
  41. 10
      io.sc.platform.system.frontend/src/i18n/messages_zh_CN.json
  42. 86
      io.sc.platform.system.frontend/src/views/user/ChangePasswordDialog.vue
  43. 59
      io.sc.platform.system.frontend/src/views/user/SetPasswordDialog.vue
  44. 104
      io.sc.platform.system.frontend/src/views/user/User.vue
  45. 6
      io.sc.platform.system/src/main/java/io/sc/platform/system/user/controller/UserWebController.java
  46. 16
      io.sc.platform.system/src/main/java/io/sc/platform/system/user/service/impl/UserServiceImpl.java

2
io.sc.platform.core.frontend/package.json

@ -1,6 +1,6 @@
{
"name": "platform-core",
"version": "8.1.60",
"version": "8.1.61",
"description": "前端核心包,用于快速构建前端的脚手架",
"//main": "库的主文件",
"main": "dist/platform-core.js",

1
io.sc.platform.core.frontend/src/platform/i18n/messages.json

@ -46,4 +46,5 @@
"tabs.close.all":"Close All Tab",
"theme": "Theme",
"upToTop": "Up to Top",
"passwordAndConfirmPasswordMustEqual": "Confrim Password and Password must equals"
}

1
io.sc.platform.core.frontend/src/platform/i18n/messages_tw_CN.json

@ -46,4 +46,5 @@
"tabs.close.all":"關閉所有標籤",
"theme": "主題",
"upToTop": "回到頂部",
"passwordAndConfirmPasswordMustEqual": "確認密碼和密碼必須一致"
}

1
io.sc.platform.core.frontend/src/platform/i18n/messages_zh_CN.json

@ -46,4 +46,5 @@
"tabs.close.all":"关闭所有标签",
"theme": "主题",
"upToTop": "回到顶部",
"passwordAndConfirmPasswordMustEqual": "确认密码和密码必须一致"
}

85
io.sc.platform.core.frontend/src/platform/layout/sub-layout/ChangePasswordDialog.vue

@ -0,0 +1,85 @@
<template>
<w-dialog
ref="changePasswordDialogRef"
width="400px"
height="300px"
:title="$t('changePassword')"
:can-maximize="false"
:buttons="[
{
label: $t('submit'),
click: changePassword,
},
]"
>
<w-form
ref="changePasswordFormRef"
:cols-num="1"
:fields="[
{
name: 'rawPassword',
label: $t('rawPassword'),
type: 'password',
requiredIf: () => {
return true;
},
},
{
name: 'newPassword',
label: $t('newPassword'),
type: 'password',
requiredIf: () => {
return true;
},
},
{
name: 'confirmNewPassword',
label: $t('confirmNewPassword'),
type: 'password',
requiredIf: () => {
return true;
},
rules: [
(val) => {
return changePasswordFormRef.data.newPassword != val ? $t('passwordAndConfirmPasswordMustEqual') : true;
},
],
},
]"
class="p-2"
></w-form>
</w-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { Environment } from '@/platform/plugin/environment';
import { axios, NotifyManager } from '@/platform/plugin';
const { t } = useI18n();
const changePasswordDialogRef = ref();
const changePasswordFormRef = ref();
const changePassword = async () => {
const result = await changePasswordFormRef.value.validate();
if (result) {
axios.post(Environment.apiContextPath('/api/system/user/changePassword'), changePasswordFormRef.value.getData()).then((response) => {
hide();
NotifyManager.info(t('operationSuccess'));
});
}
};
const show = () => {
changePasswordDialogRef.value.show();
};
const hide = () => {
changePasswordDialogRef.value.hide();
};
defineExpose({
show,
hide,
});
</script>

14
io.sc.platform.core.frontend/src/platform/layout/sub-layout/Topper.vue

@ -128,11 +128,12 @@
</q-item-section>
</q-item>
<q-separator inset spaced />
<q-item v-close-popup clickable>
<q-item v-close-popup clickable @click="Environment.executeAction('changePassword')">
<q-item-section>
<q-item-label><q-icon name="verified_user" left size="20px"></q-icon>{{ t('changePassword') }}</q-item-label>
<q-item-label><q-icon name="bi-shield" left size="20px"></q-icon>{{ t('changePassword') }}</q-item-label>
</q-item-section>
</q-item>
<q-separator inset spaced />
<q-item v-close-popup clickable>
<q-item-section>
<q-item-label><q-icon name="group" left size="20px"></q-icon>{{ t('changeRole') }}</q-item-label>
@ -153,6 +154,8 @@
<About></About>
</q-dialog>
<ChangePasswordDialog ref="changePasswordDialog"></ChangePasswordDialog>
<q-form ref="logoutForm" :action="Environment.apiContextPath('/logout')" method="post"> </q-form>
</template>
@ -165,12 +168,14 @@ import { useI18n } from 'vue-i18n';
import { Environment, SessionManager, I18nMessageManager } from '@/platform';
import About from './About.vue';
import ChangePasswordDialog from './ChangePasswordDialog.vue';
const gc = Environment.getConfigure();
const quasar = useQuasar();
const router = useRouter();
const searchContent = ref('');
const showAboutDialog = ref(false);
const changePasswordDialog = ref();
const { t } = useI18n();
const session: UserSessionType = SessionManager.getSession() as UserSessionType;
const logoutForm = ref();
@ -224,6 +229,11 @@ const about = () => {
showAboutDialog.value = true;
};
const changePassword = () => {
changePasswordDialog.value.show();
};
Environment.registAction('about', about);
Environment.registAction('changePassword', changePassword);
Environment.registAction('logout', logout);
</script>

10
io.sc.platform.core.frontend/src/platform/plugin/axios.ts

@ -47,6 +47,7 @@ axios.interceptors.response.use(
} else {
// 业务错误
NotifyManager.error(i18n.global.t(data.errorMessageI18nKey));
return Promise.reject(data);
}
},
(error: any) => {
@ -55,16 +56,19 @@ axios.interceptors.response.use(
// 发生网络错误
const $t = i18n.global.t;
NotifyManager.error($t('NetworkError'));
return Promise.reject(error);
} else {
const status = error?.response?.status;
let messageKey = error?.response?.data?.errorMessageI18nKey;
const response = error?.response;
const data = response?.data;
let messageKey = data?.errorMessageI18nKey;
if (Tools.isUndefinedOrNull(messageKey)) {
messageKey = error?.response?.status;
messageKey = response?.status;
}
if (Tools.isUndefinedOrNull(messageKey)) {
messageKey = 'error';
}
NotifyManager.error(i18n.global.t(messageKey));
return Promise.reject(data);
}
},
);

17
io.sc.platform.core.frontend/src/platform/utils/Tools.ts

@ -750,6 +750,23 @@ class Tools {
}
return object;
}
/**
*
* @param objects
* @param propertyName
* @returns
*/
public static extractProperties(objects: object[], propertyName: string): object[] {
if (objects && objects.length > 0 && propertyName) {
const result = [];
for (const object of objects) {
result.push(object[propertyName]);
}
return result;
}
return [];
}
}
export { Tools };

4
io.sc.platform.core.frontend/template-project/package.json

@ -1,6 +1,6 @@
{
"name": "platform-core",
"version": "8.1.60",
"version": "8.1.61",
"description": "前端核心包,用于快速构建前端的脚手架",
"private": false,
"keywords": [],
@ -92,7 +92,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.60",
"platform-core": "8.1.61",
"quasar": "2.14.2",
"tailwindcss": "3.4.0",
"vue": "3.4.3",

3
io.sc.platform.core.frontend/webpack.env.serve.cjs

@ -12,6 +12,9 @@ module.exports = (env)=> merge(common, mf,{
devtool: 'eval',
devServer: {
client: {
overlay: false,
},
static: {
directory: path.join(__dirname, 'public'),
},

3
io.sc.platform.core/src/main/java/io/sc/platform/core/ApplicationLauncher.java

@ -1,6 +1,7 @@
package io.sc.platform.core;
import com.beust.jcommander.JCommander;
import io.sc.platform.core.exception.PlatformRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
@ -89,7 +90,7 @@ public class ApplicationLauncher {
try {
start();
} catch (IOException e) {
throw new RuntimeException(e);
throw new PlatformRuntimeException(e);
}
});
thread.start();

3
io.sc.platform.core/src/main/java/io/sc/platform/core/PlatformSpringBootServletInitializer.java

@ -1,5 +1,6 @@
package io.sc.platform.core;
import io.sc.platform.core.exception.PlatformRuntimeException;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@ -18,7 +19,7 @@ public abstract class PlatformSpringBootServletInitializer extends SpringBootSer
Environment.getInstance().init(this.getClass(),true);
return builder.sources(this.getClass());
} catch (IOException e) {
throw new RuntimeException(e);
throw new PlatformRuntimeException(e);
}
}
}

4
io.sc.platform.core/src/main/java/io/sc/platform/core/bean/GlobalExceptionHandler.java

@ -4,12 +4,15 @@ import io.sc.platform.core.response.ResponseWrapper;
import io.sc.platform.core.response.ResponseWrapperBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import javax.servlet.http.HttpServletRequest;
/**
* 全局违例处理
* 仅处理进入 Controller 后发生的违例, 不处理进入 Controller 前发生的违例(例如:认证违例)
@ -19,6 +22,7 @@ public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(value =Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ResponseWrapper exceptionHandler(HttpServletRequest request, Exception e){
log.error("",e);

2
io.sc.platform.core/src/main/java/io/sc/platform/core/compiler/JavaMemeryFileManager.java

@ -10,7 +10,7 @@ import java.util.ArrayList;
import java.util.List;
public class JavaMemeryFileManager extends ForwardingJavaFileManager<JavaFileManager> {
private List<JavaMemeryClassObject> javaMemeryClassObjects = new ArrayList<JavaMemeryClassObject>();
private List<JavaMemeryClassObject> javaMemeryClassObjects = new ArrayList<>();
private JavaMemeryClassLoader classLoader;
protected JavaMemeryFileManager(JavaFileManager fileManager, JavaMemeryClassLoader classLoader) {

4
io.sc.platform.core/src/main/java/io/sc/platform/core/compiler/JavaMemoryCompiler.java

@ -11,7 +11,7 @@ public class JavaMemoryCompiler {
private Iterable<String> options;
boolean ignoreWarnings = false;
private Map<String, SourceCode> sourceCodeMap = new HashMap<String, SourceCode>();
private Map<String, SourceCode> sourceCodeMap = new HashMap<>();
public JavaMemoryCompiler() {
this.compiler = ToolProvider.getSystemJavaCompiler();
@ -97,7 +97,7 @@ public class JavaMemoryCompiler {
}
}
Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
Map<String, Class<?>> classes = new HashMap<>();
for (String className : sourceCodeMap.keySet()) {
classes.put(className, classLoader.loadClass(className));
}

22
io.sc.platform.core/src/main/java/io/sc/platform/core/exception/PlatformRuntimeException.java

@ -0,0 +1,22 @@
package io.sc.platform.core.exception;
public class PlatformRuntimeException extends RuntimeException{
public PlatformRuntimeException() {
}
public PlatformRuntimeException(String message) {
super(message);
}
public PlatformRuntimeException(String message, Throwable cause) {
super(message, cause);
}
public PlatformRuntimeException(Throwable cause) {
super(cause);
}
public PlatformRuntimeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

11
io.sc.platform.core/src/main/java/io/sc/platform/core/i18n/MessageSourceBaseName.java

@ -1,20 +1,19 @@
package io.sc.platform.core.i18n;
import io.sc.platform.core.plugins.PluginManager;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
import static org.springframework.util.StringUtils.trimAllWhitespace;
public class MessageSourceBaseName {
private MessageSourceBaseName(){}
public static String[] getBaseNames(String basename){
List<String> result =new ArrayList<String>();
List<String> result =new ArrayList<>();
//首先加载在 application.properties 中配置的 spring.messages.basename 列表
if (StringUtils.hasText(basename)) {
// if (StringUtils.hasText(basename)) {
// result.addAll(Arrays.asList(commaDelimitedListToStringArray(trimAllWhitespace(basename))));
}
// }
// 然后加载国际化消息插件
List<io.sc.platform.core.plugins.item.Message> messages = PluginManager.getInstance().getMessages();
if(messages!=null && !messages.isEmpty()){

2
io.sc.platform.core/src/main/java/io/sc/platform/core/i18n/PlatformResourceBundleMessageSource.java

@ -9,7 +9,7 @@ public class PlatformResourceBundleMessageSource extends ResourceBundleMessageSo
@Override
public void reload() {
// nothing to do
}
@Override

5
io.sc.platform.core/src/main/java/io/sc/platform/core/plugins/PluginParser.java

@ -3,6 +3,7 @@ package io.sc.platform.core.plugins;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import io.sc.platform.core.exception.PlatformRuntimeException;
import io.sc.platform.core.util.ObjectMapper4Json;
import org.springframework.core.io.Resource;
@ -25,7 +26,7 @@ public class PluginParser {
urls = Thread.currentThread().getContextClassLoader().getResources(location);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(location + " is NOT a validated plugin file.",e);
throw new PlatformRuntimeException(location + " is NOT a validated plugin file.",e);
}
if(urls==null){
@ -53,7 +54,7 @@ public class PluginParser {
}
}catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(url + " is NOT a validated plugin file.",e);
throw new PlatformRuntimeException(url + " is NOT a validated plugin file.",e);
}
}
return result;

19
io.sc.platform.core/src/main/java/io/sc/platform/core/response/ResponseWrapperBuilder.java

@ -1,8 +1,10 @@
package io.sc.platform.core.response;
public class ResponseWrapperBuilder {
public static <T> ResponseWrapper success(){
return new SuccessResponseWrapper();
private ResponseWrapperBuilder(){}
public static ResponseWrapper success(){
return new SuccessResponseWrapper<String>();
}
public static <T> ResponseWrapper success(T data){
@ -10,30 +12,29 @@ public class ResponseWrapperBuilder {
}
public static <T> ResponseWrapper success(T data,String messageI18nKey){
SuccessResponseWrapper wrapper =new SuccessResponseWrapper<T>(data);
SuccessResponseWrapper<T> wrapper =new SuccessResponseWrapper<T>(data);
wrapper.setMessageI18nKey(messageI18nKey);
return wrapper;
}
public static <T> ResponseWrapper success(T data,String messageI18nKey,String message){
SuccessResponseWrapper wrapper =new SuccessResponseWrapper<T>(data);
SuccessResponseWrapper<T> wrapper =new SuccessResponseWrapper<T>(data);
wrapper.setMessageI18nKey(messageI18nKey);
wrapper.setMessage(message);
return wrapper;
}
public static <T> ResponseWrapper error(Exception e){
ErrorResponseWrapper wrapper =new ErrorResponseWrapper(e);
return wrapper;
public static ResponseWrapper error(Exception e){
return new ErrorResponseWrapper(e);
}
public static <T> ResponseWrapper error(Exception e,String errorMessageI18nKey){
public static ResponseWrapper error(Exception e,String errorMessageI18nKey){
ErrorResponseWrapper wrapper =new ErrorResponseWrapper(e);
wrapper.setErrorMessageI18nKey(errorMessageI18nKey);
return wrapper;
}
public static <T> ResponseWrapper error(Exception e,String errorMessageI18nKey,String errorMessage){
public static ResponseWrapper error(Exception e,String errorMessageI18nKey,String errorMessage){
ErrorResponseWrapper wrapper =new ErrorResponseWrapper(e);
wrapper.setErrorMessageI18nKey(errorMessageI18nKey);
wrapper.setErrorMessage(errorMessage);

2
io.sc.platform.core/src/main/java/io/sc/platform/core/util/BeanUtil.java

@ -25,7 +25,7 @@ public class BeanUtil {
try {
beanClass = Class.forName(beanClassName);
} catch (ClassNotFoundException e) {
log.warn(beanClassName + " Class NOT found");
log.warn("{} Class NOT found",beanClassName);
return null;
}
try {

33
io.sc.platform.core/src/main/java/io/sc/platform/core/util/CollectionUtil.java

@ -1,17 +1,15 @@
package io.sc.platform.core.util;
import io.sc.platform.core.util.support.MapObjectKeyConvertor;
import io.sc.platform.core.util.support.MapObjectKeyValueConvertor;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.util.StringUtils;
import io.sc.platform.core.util.support.MapObjectKeyConvertor;
import io.sc.platform.core.util.support.MapObjectKeyValueConvertor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;
/**
* 集合工具类
@ -219,31 +217,4 @@ public class CollectionUtil {
}
return map;
}
public static void println(String prefix,Collection<?> list){
StringBuilder sb =new StringBuilder(prefix);
sb.append("[");
if(list!=null && !list.isEmpty()) {
for (Object o : list) {
sb.append(o.toString()).append(",");
}
if(sb.length()>0){
sb.setLength(sb.length()-1);
}
}
sb.append("]");
System.out.println(sb.toString());
}
public static void println(String prefix,Map<?,?> map){
StringBuilder sb =new StringBuilder(prefix);
sb.append("[").append("\n");
if(map!=null && !map.isEmpty()) {
for(Object key : map.keySet()){
sb.append("\t").append("{key=").append(key).append(",").append("value=").append(map.get(key)).append("}").append("\n");
}
}
sb.append("]");
System.out.println(sb.toString());
}
}

2
io.sc.platform.core/src/main/java/io/sc/platform/core/util/HttpServletRequestUtil.java

@ -9,6 +9,8 @@ import javax.servlet.http.HttpServletRequest;
* HttpServletRequest 工具类
*/
public class HttpServletRequestUtil {
private HttpServletRequestUtil(){}
/**
* 是否是页面请求(请求头 Accept 包含 text/html)
* @param request 请求头

26
io.sc.platform.core/src/main/java/io/sc/platform/core/util/IpUtil.java

@ -1,11 +1,9 @@
package io.sc.platform.core.util;
import javax.servlet.http.HttpServletRequest;
import inet.ipaddr.IPAddressString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.Inet6Address;
import java.net.InetAddress;
@ -20,8 +18,11 @@ import java.util.regex.Pattern;
*
*/
public class IpUtil {
private IpUtil(){}
private static final Logger logger = LoggerFactory.getLogger(IpUtil.class);
public static final String UNKNOW ="unknown";
public static final String UNKNOW_IP ="0.0.0.0";
private static final String ANYHOST_VALUE = "0.0.0.0";
private static final String LOCALHOST_VALUE = "127.0.0.1";
@ -36,16 +37,16 @@ public class IpUtil {
*/
public static String getRemoteIp(HttpServletRequest request){
String ip =request.getHeader("x-forwarded-for");
if(ip==null || ip.length()==0 || "unknown".equalsIgnoreCase(ip)){
if(ip==null || ip.length()==0 || UNKNOW.equalsIgnoreCase(ip)){
ip =request.getHeader("Proxy-Client-IP");
}
if(ip==null || ip.length()==0 || "unknown".equalsIgnoreCase(ip)){
if(ip==null || ip.length()==0 || UNKNOW.equalsIgnoreCase(ip)){
ip =request.getHeader("WL-Proxy-Client-IP");
}
if(ip==null || ip.length()==0 || "unknown".equalsIgnoreCase(ip)){
if(ip==null || ip.length()==0 || UNKNOW.equalsIgnoreCase(ip)){
ip =request.getRemoteAddr();
}
if(ip==null || ip.length()==0 || "unknown".equalsIgnoreCase(ip)){
if(ip==null || ip.length()==0 || UNKNOW.equalsIgnoreCase(ip)){
ip =UNKNOW_IP;
}
return ip;
@ -63,7 +64,7 @@ public class IpUtil {
if (addressItem != null) {
return addressItem.getHostAddress();
}
} catch (Throwable e) {
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
@ -91,15 +92,15 @@ public class IpUtil {
logger.error(e.getMessage(), e);
}
}
} catch (Throwable e) {
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
} catch (Throwable e) {
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
} catch (Throwable e) {
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return localAddress.getHostAddress();
@ -127,11 +128,10 @@ public class IpUtil {
return false;
}
String name = address.getHostAddress();
boolean result = (name != null
return (name != null
&& IP_PATTERN.matcher(name).matches()
&& !ANYHOST_VALUE.equals(name)
&& !LOCALHOST_VALUE.equals(name));
return result;
}
private static InetAddress normalizeV6Address(Inet6Address address) {

1
io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words.properties

@ -88,6 +88,7 @@ nextPage=Next Page
no=No
normal=Normal
oldValue=Old Value
operationSuccess=Operation Sucess
order=Order
org=Org
password=Password

3
io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_tw_CN.properties

@ -10,7 +10,7 @@ bottom-right=\u53F3\u4E0B
bottom=\u4E0B\u908A
cancel=\u53D6\u6D88
center=\u4E2D\u5FC3
changePassword=\u4FEE\u6539\u767B\u9304\u5BC6\u78BC
changePassword=\u4FEE\u6539\u5BC6\u78BC
changeRole=\u5207\u63DB\u89D2\u8272
className=\u985E\u540D
clone=\u8907\u88FD
@ -88,6 +88,7 @@ nextPage=\u4E0B\u4E00\u9801
no=\u5426
normal=\u6B63\u5E38
oldValue=\u539F\u503C
operationSuccess=\u64CD\u4F5C\u6210\u529F
order=\u9806\u5E8F
org=\u6A5F\u69CB
password=\u5BC6\u78BC

3
io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_zh_CN.properties

@ -10,7 +10,7 @@ bottom-right=\u53F3\u4E0B
bottom=\u4E0B\u8FB9
cancel=\u53D6\u6D88
center=\u4E2D\u5FC3
changePassword=\u4FEE\u6539\u767B\u5F55\u5BC6\u7801
changePassword=\u4FEE\u6539\u5BC6\u7801
changeRole=\u5207\u6362\u89D2\u8272
className=\u7C7B\u540D
clone=\u590D\u5236
@ -88,6 +88,7 @@ nextPage=\u4E0B\u4E00\u9875
no=\u5426
normal=\u6B63\u5E38
oldValue=\u539F\u503C
operationSuccess=\u64CD\u4F5C\u6210\u529F
order=\u987A\u5E8F
org=\u673A\u6784
password=\u5BC6\u7801

20
io.sc.platform.developer.doc/asciidoc/9999-appendix/java/java.adoc

@ -1,5 +1,25 @@
[appendix]
= JAVA
== 常用技巧
=== 日志输出模式
在日志输出时,在拼接字符串时,请使用字符串模版方式。
[source,java]
----
log.info(object + " message"); // not good
log.info("{} message", object); // good
----
=== 遍历 Map
[source,java]
----
Map<String,Object> map =new HashMap<>();
for (Map.Entry<String,Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
}
----
== Java 8 Time Api
Java 8 为 Date 和 Time 引入了新的 API,以解决旧 java.util.Date 和 java.util.Calendar 的缺点。

2
io.sc.platform.security.loginform/src/main/java/io/sc/platform/security/loginform/autoconfigure/WebSecurityAutoConfiguration.java

@ -7,7 +7,7 @@ import io.sc.platform.security.handler.PlatformAuthenticationEntryPoint;
import io.sc.platform.security.handler.PlatformAuthenticationFailureHandler;
import io.sc.platform.security.handler.PlatformAuthenticationSuccessHandler;
import io.sc.platform.security.service.SecurityConfigureService;
import io.sc.platform.security.support.SecurityProperties;
import io.sc.platform.security.SecurityProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;

4
io.sc.platform.security.oauth2.server.authorization/src/main/java/io/sc/platform/security/oauth2/server/authorization/configure/PlatformOauth2AuthorizationServerAutoConfiguration.java

@ -11,7 +11,7 @@ import io.sc.platform.security.oauth2.server.authorization.bean.PlatformRegister
import io.sc.platform.security.oauth2.server.authorization.configure.support.PlatformRedirectUriValidator;
import io.sc.platform.security.oauth2.server.authorization.jpa.repository.ClientRepository;
import io.sc.platform.security.service.SecurityConfigureService;
import io.sc.platform.security.support.SecurityProperties;
import io.sc.platform.security.SecurityProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
@ -20,7 +20,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
@ -32,7 +31,6 @@ import org.springframework.security.oauth2.server.authorization.settings.Authori
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.security.KeyPair;

154
io.sc.platform.security.oauth2.server.authorization/src/main/java/io/sc/platform/security/oauth2/server/authorization/configure/support/PlatformSecurityProperties.java

@ -1,154 +0,0 @@
package io.sc.platform.security.oauth2.server.authorization.configure.support;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("platform.security")
public class PlatformSecurityProperties {
private String userInfoUrl ="/api/user-info";
private final FormLogin formLogin = new FormLogin();
private final Logout logout = new Logout();
private final Oauth2 oauth2 = new Oauth2();
private final Rsa rsa = new Rsa();
public String getUserInfoUrl() {
return userInfoUrl;
}
public void setUserInfoUrl(String userInfoUrl) {
this.userInfoUrl = userInfoUrl;
}
public FormLogin getFormLogin() {
return formLogin;
}
public Logout getLogout() {
return logout;
}
public Oauth2 getOauth2() {
return oauth2;
}
public Rsa getRsa() {
return rsa;
}
public static class FormLogin {
private String loginPage ="/login";
private String loginProcessingUrl ="/login";
private String failureUrl ="/login?error";
public String getLoginPage() {
return loginPage;
}
public void setLoginPage(String loginPage) {
this.loginPage = loginPage;
}
public String getLoginProcessingUrl() {
return loginProcessingUrl;
}
public void setLoginProcessingUrl(String loginProcessingUrl) {
this.loginProcessingUrl = loginProcessingUrl;
}
public String getFailureUrl() {
return failureUrl;
}
public void setFailureUrl(String failureUrl) {
this.failureUrl = failureUrl;
}
}
public static class Logout {
private String logoutUrl ="/oauth2/logout";
private String logoutSuccessUrl ="/";
public String getLogoutUrl() {
return logoutUrl;
}
public void setLogoutUrl(String logoutUrl) {
this.logoutUrl = logoutUrl;
}
public String getLogoutSuccessUrl() {
return logoutSuccessUrl;
}
public void setLogoutSuccessUrl(String logoutSuccessUrl) {
this.logoutSuccessUrl = logoutSuccessUrl;
}
}
public static class Oauth2 {
private final AuthorizationServer authorizationServer =new AuthorizationServer();
public AuthorizationServer getAuthorizationServer() {
return authorizationServer;
}
}
public static class AuthorizationServer {
private String issuerUri ="http://localhost:8080";
private String jwkKeyId ="io.sc.platform.security.oauth2.server.keyId";
private final RedirectUriValidator redirectUriValidator = new RedirectUriValidator();
public String getIssuerUri() {
return issuerUri;
}
public void setIssuerUri(String issuerUri) {
this.issuerUri = issuerUri;
}
public String getJwkKeyId() {
return jwkKeyId;
}
public void setJwkKeyId(String jwkKeyId) {
this.jwkKeyId = jwkKeyId;
}
public RedirectUriValidator getRedirectUriValidator() {
return redirectUriValidator;
}
}
public static class RedirectUriValidator {
private boolean enable =true;
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
}
public static class Rsa {
private String publicKeyLocation ="classpath:/io/sc/platform/security/publicKey.txt";
private String privateKeyLocation ="classpath:/io/sc/platform/security/privateKey.txt";
public String getPublicKeyLocation() {
return publicKeyLocation;
}
public void setPublicKeyLocation(String publicKeyLocation) {
this.publicKeyLocation = publicKeyLocation;
}
public String getPrivateKeyLocation() {
return privateKeyLocation;
}
public void setPrivateKeyLocation(String privateKeyLocation) {
this.privateKeyLocation = privateKeyLocation;
}
}
}

2
io.sc.platform.security.oauth2.server.resource/src/main/java/io/sc/platform/security/oauth2/server/resource/configure/PlatformOauth2ResourceServerAutoConfiguration.java

@ -3,7 +3,7 @@ package io.sc.platform.security.oauth2.server.resource.configure;
import io.sc.platform.core.service.RuntimeService;
import io.sc.platform.security.service.SecurityConfigureService;
import io.sc.platform.security.support.SecurityProperties;
import io.sc.platform.security.SecurityProperties;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

2
io.sc.platform.security.oauth2.server.resource/src/main/java/io/sc/platform/security/oauth2/server/resource/configure/support/PlatformJwtAuthenticationConverter.java

@ -2,7 +2,7 @@ package io.sc.platform.security.oauth2.server.resource.configure.support;
import com.nimbusds.jose.shaded.json.JSONArray;
import com.nimbusds.jose.shaded.json.JSONObject;
import io.sc.platform.security.support.SecurityClaimNames;
import io.sc.platform.security.SecurityClaimNames;
import io.sc.platform.security.support.SecurityRole;
import io.sc.platform.security.support.SecurityUser;
import io.sc.platform.security.util.SecurityUtil;

2
io.sc.platform.security/src/main/java/io/sc/platform/security/support/SecurityClaimNames.java → io.sc.platform.security/src/main/java/io/sc/platform/security/SecurityClaimNames.java

@ -1,4 +1,4 @@
package io.sc.platform.security.support;
package io.sc.platform.security;
public class SecurityClaimNames {
public static final class User {

2
io.sc.platform.security/src/main/java/io/sc/platform/security/support/SecurityProperties.java → io.sc.platform.security/src/main/java/io/sc/platform/security/SecurityProperties.java

@ -1,4 +1,4 @@
package io.sc.platform.security.support;
package io.sc.platform.security;
import org.springframework.boot.context.properties.ConfigurationProperties;

1
io.sc.platform.security/src/main/java/io/sc/platform/security/autoconfigure/PlatformWebSecurityAutoConfiguration.java

@ -2,6 +2,7 @@ package io.sc.platform.security.autoconfigure;
import io.sc.platform.security.autoconfigure.support.EncodePasswordAuthenticationProvider;
import io.sc.platform.security.service.impl.UserDetailsServiceImpl;
import org.apache.catalina.security.SecurityConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;

2
io.sc.platform.security/src/main/java/io/sc/platform/security/util/SecurityUtil.java

@ -7,7 +7,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.Assert;
import io.sc.platform.core.util.StringUtil;
import io.sc.platform.security.support.SecurityClaimNames;
import io.sc.platform.security.SecurityClaimNames;
import io.sc.platform.security.support.SecurityRole;
import io.sc.platform.security.support.SecurityUser;

2
io.sc.platform.system.frontend/package.json

@ -78,7 +78,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.60",
"platform-core": "8.1.61",
"quasar": "2.14.2",
"tailwindcss": "3.4.0",
"vue": "3.4.3",

9
io.sc.platform.system.frontend/src/i18n/messages.json

@ -17,17 +17,24 @@
"menu.system.monitor.resources" : "Resources",
"menu.system.license" : "License",
"system.user.gridTitle":"User List",
"system.role.gridTitle":"Role List",
"system.org.gridTitle":"Org Tree",
"system.announcement.gridTitle":"Announcement List",
"system.monitor.auditlog.gridTitle":"Audit Log List",
"system.user.grid.title":"User List",
"system.user.action.addUser":"Add User",
"system.user.action.addAllUser":"Add All User",
"system.user.action.removeUser":"Remove User",
"system.user.action.removeAllUser":"Remove All User",
"system.user.action.setPassword":"Set Password",
"system.user.action.setAllPassword":"Set All Password",
"system.user.action.resetPassword":"Reset Password",
"system.user.action.resetAllPassword":"Reset All Password",
"system.user.confirm.resetPassword":"Are you sure to reset the user's password?",
"system.user.confirm.resetAllPassword":"Are you sure to reset ALL user's password?",
"system.user.entity.title":"User List",
"system.role.action.addRole":"Add Role",
"system.role.action.addAllRole":"Add All Role",

9
io.sc.platform.system.frontend/src/i18n/messages_tw_CN.json

@ -17,17 +17,22 @@
"menu.system.monitor.resources" : "系統資源",
"menu.system.license" : "許可證管理",
"system.user.gridTitle":"用戶列表",
"system.role.gridTitle":"角色列表",
"system.org.gridTitle":"機構樹",
"system.announcement.gridTitle":"公告列表",
"system.monitor.auditlog.gridTitle":"審計日誌列表",
"system.user.grid.title":"用戶列表",
"system.user.action.addUser":"添加用户",
"system.user.action.addAllUser":"添加所有用户",
"system.user.action.removeUser":"移除用户",
"system.user.action.removeAllUser":"移除所有用户",
"system.user.action.setPassword":"修改密碼",
"system.user.action.setPassword":"設置密碼",
"system.user.action.setAllPassword":"設置所有密碼",
"system.user.action.resetPassword":"重置密碼",
"system.user.action.resetAllPassword":"重置所有密碼",
"system.user.confirm.resetPassword":"您確認要重置用戶密碼嗎?",
"system.user.confirm.resetAllPassword":"您確認要重置所有用戶密碼嗎?",
"system.role.action.addRole":"添加角色",
"system.role.action.addAllRole":"添加所有角色",

10
io.sc.platform.system.frontend/src/i18n/messages_zh_CN.json

@ -17,17 +17,23 @@
"menu.system.monitor.resources" : "系统资源",
"menu.system.license" : "许可证管理",
"system.user.gridTitle":"用户列表",
"system.role.gridTitle":"角色列表",
"system.org.gridTitle":"机构树",
"system.announcement.gridTitle":"公告列表",
"system.monitor.auditlog.gridTitle":"审计日志列表",
"system.user.grid.title":"用户列表",
"system.user.action.addUser":"添加用户",
"system.user.action.addAllUser":"添加所有用户",
"system.user.action.removeUser":"移除用户",
"system.user.action.removeAllUser":"移除所有用户",
"system.user.action.setPassword":"修改密码",
"system.user.action.setPassword":"设置密码",
"system.user.action.setAllPassword":"设置所有密码",
"system.user.action.resetPassword":"重置密码",
"system.user.action.resetAllPassword":"重置所有密码",
"system.user.confirm.resetPassword":"您确定要重置用户密码吗?",
"system.user.confirm.resetAllPassword":"您确定要重置所有用户密码吗?",
"system.role.action.addRole":"添加角色",
"system.role.action.addAllRole":"添加所有角色",

86
io.sc.platform.system.frontend/src/views/user/ChangePasswordDialog.vue

@ -1,86 +0,0 @@
<template>
<div>
<q-dialog ref="dialogRef" allow-focus-outside v-bind="attrs">
<q-card
:style="{
width: attrs.maximized ? '100vw' : width,
'max-width': '100vw',
height: attrs.maximized ? '100vh' : height,
'max-height': '100vh',
}"
>
<q-card-section :style="headerStyle">
<div class="flex justify-between">
<div class="text-h6">{{ title }}</div>
<div class="flex justify-end q-gutter-md">
<q-btn v-close-popup dense flat icon="close" :title="$t('close')"> </q-btn>
</div>
</div>
</q-card-section>
<q-card-section class="q-pt-md" :style="bodyStyle">
<div class="row">
<div class="col-12">
<q-input v-model="model.rawPassword" type="password" label="原密码" outlined autocomplete="false" class="p-1" />
</div>
</div>
<div class="row">
<div class="col-12">
<q-input v-model="model.newPassword" type="password" label="新密码" outlined autocomplete="false" class="p-1" />
</div>
</div>
<div class="row">
<div class="col-12">
<q-input v-model="model.confirmNewPassword" type="password" label="确认新密码" outlined autocomplete="false" class="p-1" />
</div>
</div>
</q-card-section>
<q-card-section class="row justify-center items-start content-start q-gutter-md">
<q-btn :label="$t('confirm')" color="primary" style="width: 100px" @click="changePassword" />
<q-btn :label="$t('cancel')" style="width: 100px" @click="dialogRef.hide" />
</q-card-section>
</q-card>
</q-dialog>
</div>
</template>
<script setup lang="ts">
import { useAttrs, ref, reactive, toRaw } from 'vue';
import { useI18n } from 'vue-i18n';
import { axios, Environment } from 'platform-core';
const attrs = useAttrs();
const props = defineProps({
headerStyle: { type: String, default: 'width:100%;padding: 16px 8px 4px 16px' },
bodyStyle: { type: String, default: 'padding: 0px 8px 0px 8px;height:200px' },
title: { type: String, default: '' },
width: { type: String, default: '70%' },
height: { type: String, default: '70%' },
});
const { t } = useI18n();
const dialogRef = ref();
const model = reactive({
rawPassword: '',
newPassword: '',
confirmNewPassword: '',
});
const changePassword = () => {
axios.post(Environment.apiContextPath('/api/system/user/changePassword'), toRaw(model)).then(() => {
dialogRef.value.hide();
});
};
const show = (param: object) => {
dialogRef.value.show();
};
const hide = () => {
dialogRef.value.hide();
};
defineExpose({
show,
hide,
});
</script>

59
io.sc.platform.system.frontend/src/views/user/SetPasswordDialog.vue

@ -0,0 +1,59 @@
<template>
<w-dialog
ref="setPasswordDialogRef"
:title="$t('system.user.action.' + actionType)"
width="500px"
height="200px"
:can-maximize="false"
:buttons="[
{
label: $t('submit'),
click: () => {
axios
.post(Environment.apiContextPath('/api/system/user/' + actionType), {
userIds: userIds,
password: setPasswordFormRef.getData().password,
})
.then(() => {
setPasswordDialogRef.hide();
NotifyManager.info($t('operationSuccess'));
});
},
},
]"
>
<w-form
ref="setPasswordFormRef"
:cols-num="1"
:fields="[
{ name: 'password', label: $t('password'), type: 'password' },
{ name: 'confirmPassword', label: $t('confirmPassword'), type: 'password' },
]"
class="p-2"
></w-form>
</w-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { axios, Environment, NotifyManager, Tools } from 'platform-core';
const setPasswordDialogRef = ref();
const setPasswordFormRef = ref();
let actionType = ref();
let userIds = [];
const show = (type, users) => {
actionType.value = type;
userIds = Tools.extractProperties(users, 'id');
setPasswordDialogRef.value.show();
};
const hide = () => {
setPasswordDialogRef.value.hide();
};
defineExpose({
show,
hide,
});
</script>

104
io.sc.platform.system.frontend/src/views/user/User.vue

@ -1,5 +1,4 @@
<template>
<Ok @wsp="wsp"></Ok>
<q-splitter :model-value="70" class="w-full h-full">
<template #before>
<div class="px-1">
@ -56,46 +55,16 @@
</div>
</template>
<SelectRoleDialog ref="selectRoleDialog" title="可选角色列表" :maximized="false" width="50%" height="500px"></SelectRoleDialog>
<w-dialog
ref="changePasswordDialogRef"
title="修改密码"
width="500px"
height="250px"
:buttons="[
{
label: $t('submit'),
click: () => {
console.log(changePasswordFormRef.getData());
axios.post(Environment.apiContextPath('/api/system/user/changePassword'), changePasswordFormRef.getData()).then(() => {
changePasswordDialogRef.hide();
});
},
},
]"
>
<w-form
ref="changePasswordFormRef"
:cols-num="1"
:fields="[
{ name: 'rawPassword', label: $t('rawPassword'), type: 'password' },
{ name: 'newPassword', label: $t('newPassword'), type: 'password' },
{ name: 'confirmNewPassword', label: $t('confirmNewPassword'), type: 'password' },
]"
class="p-2"
></w-form>
</w-dialog>
<ChangePasswordDialog ref="changePasswordDialog2" title="修改密码" :maximized="false" width="450px" height="350px"></ChangePasswordDialog>
<SetPasswordDialog ref="setPasswordDialogRef"></SetPasswordDialog>
</q-splitter>
</template>
<script setup lang="ts">
import { ref, toRaw } from 'vue';
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { QBtn } from 'quasar';
import { Environment, axios, EnumTools } from 'platform-core';
import { Environment, axios, EnumTools, NotifyManager, DialogManager, Tools } from 'platform-core';
import SelectRoleDialog from './SelectRoleDialog.vue';
import ChangePasswordDialog from './ChangePasswordDialog.vue';
import SetPasswordDialog from './SetPasswordDialog.vue';
import UserStatusTag from './UserStatusTag.vue';
import Ok from './Ok.vue';
const { t } = useI18n();
@ -104,20 +73,14 @@ const roleGridRef = ref();
const orgTreeGridRef = ref();
const selectRoleDialog = ref();
const changePasswordDialogRef = ref();
const changePasswordFormRef = ref();
const selectedTabRef = ref('role');
const setPasswordDialogRef = ref();
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom', t);
const YesNoEnum = EnumTools.yesno(t);
const wsp = (v1, ss) => {
console.log(v1.ok(), v1.hello, ss);
};
const userGrid = {
title: t('system.user.gridTitle'),
title: t('system.user.grid.title'),
queryFormFields: [
{ name: 'loginName', label: t('loginName'), type: 'text' },
{ name: 'userName', label: t('userName'), type: 'text' },
@ -130,20 +93,67 @@ const userGrid = {
'refresh',
'separator',
'add',
'clone',
'edit',
'remove',
'separator',
{
name: 'setPassword',
label: t('system.user.action.setPassword'),
icon: 'bi-shield-exclamation',
enableIf: function (selected) {
return selected.length > 0;
icon: 'bi-shield-check',
enableIf: function (selecteds) {
return selecteds.length > 0;
},
click: function (selecteds) {
setPasswordDialogRef.value.show('setPassword', selecteds);
},
},
{
name: 'setAllPassword',
label: t('system.user.action.setAllPassword'),
icon: 'bi-shield',
enableIf: function (selecteds) {
return true;
},
click: function () {
setPasswordDialogRef.value.show('setAllPassword');
},
},
'separator',
{
name: 'resetPassword',
label: t('system.user.action.resetPassword'),
icon: 'bi-shield-fill-check',
enableIf: function (selecteds) {
return selecteds.length > 0;
},
click: function (selecteds) {
DialogManager.confirm(t('system.user.confirm.resetPassword'), () => {
const userIds = Tools.extractProperties(selecteds, 'id');
axios.post(Environment.apiContextPath('/api/system/user/resetPassword'), userIds).then(() => {
setPasswordDialogRef.value.hide();
NotifyManager.info(t('operationSuccess'));
});
});
},
},
{
name: 'resetAllPassword',
label: t('system.user.action.resetAllPassword'),
icon: 'bi-shield-fill',
enableIf: function (selecteds) {
return true;
},
click: function () {
changePasswordDialogRef.value.show();
DialogManager.confirm(t('system.user.confirm.resetAllPassword'), () => {
axios.post(Environment.apiContextPath('/api/system/user/resetAllPassword')).then(() => {
setPasswordDialogRef.value.hide();
NotifyManager.info(t('operationSuccess'));
});
});
},
},
'separator',
'view',
'export',
],

6
io.sc.platform.system/src/main/java/io/sc/platform/system/user/controller/UserWebController.java

@ -33,12 +33,12 @@ public class UserWebController extends RestCrudController<UserVo, UserEntity, St
/**
* 重置用户的登录密码
* @param loginNames 用户登录名集合
* @param userIds 用户ID集合
* @throws Exception 违例
*/
@PostMapping("resetPassword")
public void resetPassword(@RequestBody List<String> loginNames) throws Exception{
service.resetPassword(loginNames);
public void resetPassword(@RequestBody List<String> userIds) throws Exception{
service.resetPassword(userIds);
}
/**

16
io.sc.platform.system/src/main/java/io/sc/platform/system/user/service/impl/UserServiceImpl.java

@ -8,6 +8,7 @@ import io.sc.platform.orm.api.exception.UserRawPasswordNotMatchException;
import io.sc.platform.orm.service.impl.DaoServiceImpl;
import io.sc.platform.orm.service.support.QueryParameter;
import io.sc.platform.orm.service.support.QueryResult;
import io.sc.platform.security.SecurityProperties;
import io.sc.platform.security.util.SecurityUtil;
import io.sc.platform.system.api.menu.MenuRouteVo;
import io.sc.platform.system.api.menu.MenuVo;
@ -49,6 +50,7 @@ import java.util.Set;
@Service
public class UserServiceImpl extends DaoServiceImpl<UserEntity, String, UserRepository> implements UserService {
@Autowired private Environment environment;
@Autowired private SecurityProperties securityProperties;
@Autowired private MenuService menuService;
@Autowired private FrontEndService frontEndService;
@Autowired private I18nService i18nService;
@ -72,7 +74,11 @@ public class UserServiceImpl extends DaoServiceImpl<UserEntity, String, UserRepo
public UserEntity add(UserEntity entity) throws Exception {
if(entity!=null){
entity.setId(null);
if(StringUtils.hasText(entity.getPassword())) {
entity.setPassword(passwordEncoder.encode(entity.getPassword()));
}else{
entity.setPassword(passwordEncoder.encode(getApplicationDefaultPassword()));
}
}
return super.add(entity);
}
@ -83,7 +89,7 @@ public class UserServiceImpl extends DaoServiceImpl<UserEntity, String, UserRepo
if(newEntity.getPassword()!=null && !"".equals(newEntity.getPassword())){
newEntity.setPassword(passwordEncoder.encode(newEntity.getPassword()));
}else {
newEntity.setPassword(oldPassword);
newEntity.setPassword(passwordEncoder.encode(getApplicationDefaultPassword()));
}
super.copyEntityValues(oldEntity, newEntity);
}
@ -95,7 +101,7 @@ public class UserServiceImpl extends DaoServiceImpl<UserEntity, String, UserRepo
List<UserEntity> entities =repository.findAllById(userIds);
if(!entities.isEmpty()){
for(UserEntity entity : entities){
entity.setPassword(passwordEncoder.encode(environment.getProperty("application.default-password","")));
entity.setPassword(passwordEncoder.encode(getApplicationDefaultPassword()));
}
repository.saveAll(entities);
}
@ -106,7 +112,7 @@ public class UserServiceImpl extends DaoServiceImpl<UserEntity, String, UserRepo
@Transactional
public void resetAllPassword() throws Exception {
String sql ="update SYS_USER set PASSWORD_=?";
String password =passwordEncoder.encode(environment.getProperty("application.default-password",""));
String password =passwordEncoder.encode(getApplicationDefaultPassword());
jdbcTemplate.update(sql, new PreparedStatementSetter() {
@Override
public void setValues(PreparedStatement pstmt) throws SQLException {
@ -374,4 +380,8 @@ public class UserServiceImpl extends DaoServiceImpl<UserEntity, String, UserRepo
}
return Collections.emptyList();
}
private String getApplicationDefaultPassword(){
return environment.getProperty("application.default-password","");
}
}

Loading…
Cancel
Save