完善基础代码
This commit is contained in:
parent
97e10edd80
commit
502c180912
@ -0,0 +1,24 @@
|
||||
package ink.wgink.interfaces.consts;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: IFileConstant
|
||||
* @Description: 文件常量
|
||||
* @Author: wanggeng
|
||||
* @Date: 2021/2/9 8:15 下午
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public interface IFileConstant {
|
||||
|
||||
/**
|
||||
* Excel .xls 后缀
|
||||
*/
|
||||
String EXCEL_SUFFIX_XLS = ".xls";
|
||||
/**
|
||||
* Excel .xlsx 后缀
|
||||
*/
|
||||
String EXCEL_SUFFIX_XLSX = ".xlsx";
|
||||
|
||||
}
|
@ -43,6 +43,22 @@ public interface IUserBaseService {
|
||||
*/
|
||||
List<UserDTO> listByUserIds(List<String> userIds);
|
||||
|
||||
/**
|
||||
* 用户列表
|
||||
*
|
||||
* @param usernames 用户名列表
|
||||
* @return
|
||||
*/
|
||||
List<UserDTO> listByUsernames(List<String> usernames);
|
||||
|
||||
/**
|
||||
* 用户列表
|
||||
*
|
||||
* @param params 参数
|
||||
* @return
|
||||
*/
|
||||
List<UserDTO> list(Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 用户分页列表
|
||||
*
|
||||
|
@ -4,6 +4,9 @@ import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
/**
|
||||
* @ClassName: RequestUtil
|
||||
@ -64,4 +67,25 @@ public class RequestUtil {
|
||||
return ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载
|
||||
*
|
||||
* @param response 响应
|
||||
* @param outFile 输出的文件
|
||||
* @param outFileName 输出的名字
|
||||
*/
|
||||
public static void download(HttpServletResponse response, File outFile, String outFileName) throws IOException {
|
||||
try (FileInputStream fileInputStream = new FileInputStream(outFile);
|
||||
OutputStream outputStream = response.getOutputStream()) {
|
||||
response.setHeader("content-type", "application/octet-stream");
|
||||
response.setContentType("application/octet-stream");
|
||||
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(outFileName, "UTF-8"));
|
||||
byte[] buf = new byte[1024];
|
||||
for (int readLength; (readLength = fileInputStream.read(buf)) > 0; ) {
|
||||
outputStream.write(buf, 0, readLength);
|
||||
}
|
||||
outputStream.flush();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,9 +4,12 @@ import com.alibaba.fastjson.JSON;
|
||||
import ink.wgink.common.enums.ErrorResultCodeEnum;
|
||||
import ink.wgink.exceptions.*;
|
||||
import ink.wgink.exceptions.base.SystemException;
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.pojo.result.ErrorResult;
|
||||
import ink.wgink.util.AesUtil;
|
||||
import ink.wgink.util.map.HashMapUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@ -20,7 +23,14 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.SQLSyntaxErrorException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
@ -43,6 +53,8 @@ public class ResponseAdvice {
|
||||
}
|
||||
if (e instanceof FileException) {
|
||||
LOG.error(e.getMessage());
|
||||
} else if(e instanceof ParamsException){
|
||||
LOG.error(e.getMessage());
|
||||
} else {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
@ -88,6 +100,7 @@ public class ResponseAdvice {
|
||||
}
|
||||
String contentType = request.getContentType();
|
||||
if (contentType != null && contentType.contains(MediaType.APPLICATION_JSON_VALUE)) {
|
||||
response.setCharacterEncoding(ISystemConstant.CHARSET_UTF8);
|
||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
response.setStatus(HttpStatus.BAD_REQUEST.value());
|
||||
response.getWriter().write(JSON.toJSONString(result));
|
||||
|
@ -0,0 +1,310 @@
|
||||
package ink.wgink.common.aspect;
|
||||
|
||||
import ink.wgink.annotation.*;
|
||||
import ink.wgink.exceptions.ParamsException;
|
||||
import ink.wgink.util.RegexUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.Signature;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: ApiParamsAspect
|
||||
* @Description: api接口
|
||||
* @Author: WangGeng
|
||||
* @Date: 2019/11/14 15:36
|
||||
* @Version: 1.0
|
||||
**/
|
||||
@Aspect
|
||||
@Component
|
||||
@Order(1)
|
||||
public class ApiParamsAspect {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ApiParamsAspect.class);
|
||||
|
||||
@Pointcut("execution(public * *..*Controller.*(..))")
|
||||
public void apiCutPoint() {
|
||||
}
|
||||
|
||||
@Before("apiCutPoint()")
|
||||
public void beforeApiCutPoint(JoinPoint joinPoint) throws ParamsException {
|
||||
beforeCutPoint(joinPoint);
|
||||
}
|
||||
|
||||
private void beforeCutPoint(JoinPoint joinPoint) throws ParamsException {
|
||||
Signature signature = joinPoint.getSignature();
|
||||
Object[] args = joinPoint.getArgs();
|
||||
Class<?> targetClazz = joinPoint.getTarget().getClass();
|
||||
Method method = getMethod(signature.getName(), targetClazz.getMethods(), args);
|
||||
if (method == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (method.isAnnotationPresent(CheckRequestBodyAnnotation.class)) {
|
||||
LOG.debug("校验参数");
|
||||
Parameter[] parameters = method.getParameters();
|
||||
for (Parameter parameter : parameters) {
|
||||
if (parameter.isAnnotationPresent(RequestBody.class)) {
|
||||
for (Object arg : args) {
|
||||
if (parameter.getType() == arg.getClass()) {
|
||||
checkField(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Method getMethod(String methodName, Method[] methods, Object[] args) {
|
||||
for (Method method : methods) {
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
// 方法名称相同
|
||||
if (StringUtils.equals(methodName, method.getName())) {
|
||||
// 参数长度相同
|
||||
if (args.length == parameterTypes.length) {
|
||||
// 参数类型顺序相同
|
||||
boolean isThisMethod = true;
|
||||
for (int argIndex = 0; argIndex < args.length; argIndex++) {
|
||||
if (!parameterTypes[argIndex].isInstance(args[argIndex])) {
|
||||
isThisMethod = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isThisMethod) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验字段
|
||||
*
|
||||
* @param object
|
||||
* @throws ParamsException
|
||||
*/
|
||||
public void checkField(Object object) throws ParamsException {
|
||||
Class<?> clazz = object.getClass();
|
||||
List<Field> fields = new ArrayList<>(Arrays.asList(clazz.getDeclaredFields()));
|
||||
setSuperClassField(clazz, fields);
|
||||
Method[] methods = clazz.getMethods();
|
||||
try {
|
||||
for (Field field : fields) {
|
||||
Method method = getGetMethodByField(methods, field.getName());
|
||||
if (method == null) {
|
||||
continue;
|
||||
}
|
||||
Object fieldValue = method.invoke(object);
|
||||
if (field.isAnnotationPresent(CheckNullAnnotation.class)) {
|
||||
CheckNullAnnotation checkNullAnnotation = field.getAnnotation(CheckNullAnnotation.class);
|
||||
if (fieldValue == null) {
|
||||
throw new ParamsException(String.format("%s不能为空", checkNullAnnotation.name()));
|
||||
}
|
||||
checkTypes(checkNullAnnotation.name(), fieldValue.toString(), checkNullAnnotation.types());
|
||||
} else if (field.isAnnotationPresent(CheckEmptyAnnotation.class)) {
|
||||
CheckEmptyAnnotation checkEmptyAnnotation = field.getAnnotation(CheckEmptyAnnotation.class);
|
||||
if (fieldValue == null || StringUtils.isBlank(fieldValue.toString())) {
|
||||
throw new ParamsException(String.format("%s不能为空或空串", checkEmptyAnnotation.name()));
|
||||
}
|
||||
checkRegular(checkEmptyAnnotation.name(), fieldValue.toString(), checkEmptyAnnotation.verifyType(), checkEmptyAnnotation.regex());
|
||||
checkTypes(checkEmptyAnnotation.name(), fieldValue.toString(), checkEmptyAnnotation.types());
|
||||
} else if (field.isAnnotationPresent(CheckNumberAnnotation.class)) {
|
||||
CheckNumberAnnotation checkNumberAnnotation = field.getAnnotation(CheckNumberAnnotation.class);
|
||||
if (fieldValue == null || !NumberUtils.isNumber(fieldValue.toString())) {
|
||||
throw new ParamsException(String.format("%s必须为数字", checkNumberAnnotation.name()));
|
||||
}
|
||||
Double value = Double.parseDouble(fieldValue.toString());
|
||||
if (value < checkNumberAnnotation.min()) {
|
||||
throw new ParamsException(String.format("%s最小值为%f", checkNumberAnnotation.name(), checkNumberAnnotation.min()));
|
||||
}
|
||||
if (value > checkNumberAnnotation.max()) {
|
||||
throw new ParamsException(String.format("%s最大值为%f", checkNumberAnnotation.name(), checkNumberAnnotation.max()));
|
||||
}
|
||||
checkTypes(checkNumberAnnotation.name(), fieldValue.toString(), checkNumberAnnotation.types());
|
||||
} else if (field.isAnnotationPresent(CheckBooleanAnnotation.class)) {
|
||||
CheckBooleanAnnotation checkBooleanAnnotation = field.getAnnotation(CheckBooleanAnnotation.class);
|
||||
if (fieldValue == null) {
|
||||
throw new ParamsException(String.format("%s必须为布尔", checkBooleanAnnotation.name()));
|
||||
}
|
||||
checkTypes(checkBooleanAnnotation.name(), fieldValue.toString(), checkBooleanAnnotation.types());
|
||||
} else if (field.isAnnotationPresent(CheckListAnnotation.class)) {
|
||||
CheckListAnnotation checkListAnnotation = field.getAnnotation(CheckListAnnotation.class);
|
||||
if (fieldValue == null) {
|
||||
throw new ParamsException(String.format("%s不能为空", checkListAnnotation.name()));
|
||||
}
|
||||
if (fieldValue instanceof List) {
|
||||
List fieldValueList = (List) fieldValue;
|
||||
if (fieldValueList.isEmpty()) {
|
||||
throw new ParamsException(String.format("%s不能为空", checkListAnnotation.name()));
|
||||
}
|
||||
for (Object obj : fieldValueList) {
|
||||
checkField(obj);
|
||||
}
|
||||
} else if (fieldValue instanceof String[]) {
|
||||
String[] fieldValueArray = (String[]) fieldValue;
|
||||
for (Object obj : fieldValueArray) {
|
||||
checkField(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
throw new ParamsException("系统错误");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查类型
|
||||
*
|
||||
* @param name
|
||||
* @param value
|
||||
* @param types
|
||||
* @throws ParamsException
|
||||
*/
|
||||
private void checkTypes(String name, String value, String[] types) throws ParamsException {
|
||||
if (types != null && types.length > 0) {
|
||||
StringBuilder typeSB = new StringBuilder();
|
||||
for (String type : types) {
|
||||
if (StringUtils.equals(value, type)) {
|
||||
return;
|
||||
}
|
||||
if (typeSB.length() > 0) {
|
||||
typeSB.append(",");
|
||||
}
|
||||
typeSB.append("\"").append(type).append("\"");
|
||||
}
|
||||
throw new ParamsException(String.format("%s必须是如下类型:[%s]", name, typeSB.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查正则
|
||||
*
|
||||
* @param name
|
||||
* @param value
|
||||
* @param verifyType
|
||||
* @param regex
|
||||
*/
|
||||
private void checkRegular(String name, String value, String verifyType, String regex) {
|
||||
if (StringUtils.isBlank(verifyType)) {
|
||||
return;
|
||||
}
|
||||
if (StringUtils.equals("username", verifyType)) {
|
||||
if (!RegexUtil.isUsername(value)) {
|
||||
throw new ParamsException(String.format("%s格式只能是字母、数字和下划线", name));
|
||||
}
|
||||
return;
|
||||
} else if (StringUtils.equals("phone", verifyType)) {
|
||||
if (!RegexUtil.isPhone(value)) {
|
||||
throw new ParamsException(String.format("%s格式非手机格式", name));
|
||||
}
|
||||
return;
|
||||
} else if (StringUtils.equals("email", verifyType)) {
|
||||
if (!RegexUtil.isEmail(value)) {
|
||||
throw new ParamsException(String.format("%s格式非邮件格式", name));
|
||||
}
|
||||
return;
|
||||
} else if (StringUtils.equals("url", verifyType)) {
|
||||
if (!RegexUtil.isUrl(value)) {
|
||||
throw new ParamsException(String.format("%s格式非url格式", name));
|
||||
}
|
||||
return;
|
||||
} else if (StringUtils.equals("number", verifyType)) {
|
||||
if (!NumberUtils.isNumber(value)) {
|
||||
throw new ParamsException(String.format("%s格式非数字格式", name));
|
||||
}
|
||||
return;
|
||||
} else if (StringUtils.equals("date", verifyType)) {
|
||||
if (!RegexUtil.isDate(value)) {
|
||||
throw new ParamsException(String.format("%s格式非日期格式", name));
|
||||
}
|
||||
return;
|
||||
} else if (StringUtils.equals("datetime", verifyType)) {
|
||||
if (!RegexUtil.isDatetime(value)) {
|
||||
throw new ParamsException(String.format("%s格式非时间戳格式", name));
|
||||
}
|
||||
return;
|
||||
} else if (StringUtils.equals("identity", verifyType)) {
|
||||
if (!RegexUtil.isIdentity(value)) {
|
||||
throw new ParamsException(String.format("%s格式非身份证格式", name));
|
||||
}
|
||||
return;
|
||||
} else if (StringUtils.equals("letter", verifyType)) {
|
||||
if (!RegexUtil.isLetter(value)) {
|
||||
throw new ParamsException(String.format("%s格式非字母格式", name));
|
||||
}
|
||||
return;
|
||||
} else if (StringUtils.equals("chinese", verifyType)) {
|
||||
if (!RegexUtil.isLetter(value)) {
|
||||
throw new ParamsException(String.format("%s格式非中文格式", name));
|
||||
}
|
||||
return;
|
||||
} else if (StringUtils.equals("custom", verifyType)) {
|
||||
if (StringUtils.isBlank(regex)) {
|
||||
return;
|
||||
}
|
||||
if (!Pattern.compile(regex).matcher(value).matches()) {
|
||||
throw new ParamsException(String.format("%s格式不正确", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过字段获取get方法
|
||||
*
|
||||
* @param methods
|
||||
* @param fieldName
|
||||
* @return
|
||||
*/
|
||||
public Method getGetMethodByField(Method[] methods, String fieldName) {
|
||||
String getMethodName = String.format("get%s", fieldName).toLowerCase();
|
||||
for (Method method : methods) {
|
||||
if (StringUtils.equals(getMethodName, method.getName().toLowerCase())) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置父类属性列表
|
||||
*
|
||||
* @param clazz
|
||||
* @param fields
|
||||
*/
|
||||
private void setSuperClassField(Class<?> clazz, List<Field> fields) {
|
||||
Class<?> superClazz = clazz.getSuperclass();
|
||||
if (superClazz == null) {
|
||||
return;
|
||||
}
|
||||
Field[] superFields = superClazz.getDeclaredFields();
|
||||
if (superFields == null) {
|
||||
return;
|
||||
}
|
||||
fields.addAll(Arrays.asList(superFields));
|
||||
setSuperClassField(superClazz, fields);
|
||||
}
|
||||
|
||||
}
|
@ -6,7 +6,10 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
@ -21,7 +24,7 @@ import java.util.Map;
|
||||
* @Date: 2018/9/27 下午3:47
|
||||
* @Version: 1.0
|
||||
**/
|
||||
@Component
|
||||
@Controller
|
||||
public class DefaultBaseController {
|
||||
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(DefaultBaseController.class);
|
||||
@ -29,6 +32,12 @@ public class DefaultBaseController {
|
||||
@Autowired
|
||||
private HttpSession httpSession;
|
||||
|
||||
@GetMapping("index")
|
||||
public ModelAndView goIndex() {
|
||||
ModelAndView mv = new ModelAndView("index");
|
||||
return mv;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求参数
|
||||
*
|
||||
|
@ -80,7 +80,11 @@ public class DefaultBaseService {
|
||||
*/
|
||||
protected void setUpdateInfo(Map<String, Object> params) {
|
||||
UserInfoBO userInfoBO = securityComponent.getCurrentUser();
|
||||
setUpdate(userInfoBO.getUserId(), params);
|
||||
if (userInfoBO != null) {
|
||||
setUpdate(userInfoBO.getUserId(), params);
|
||||
} else {
|
||||
setUpdate("1", params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
73
common/src/main/java/ink/wgink/common/config/BeanConfig.java
Normal file
73
common/src/main/java/ink/wgink/common/config/BeanConfig.java
Normal file
@ -0,0 +1,73 @@
|
||||
package ink.wgink.common.config;
|
||||
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import com.alibaba.fastjson.support.config.FastJsonConfig;
|
||||
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: BeanConfig
|
||||
* @Description: bean配置
|
||||
* @Author: wanggeng
|
||||
* @Date: 2021/2/5 6:44 下午
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Configuration
|
||||
public class BeanConfig {
|
||||
|
||||
@Bean
|
||||
public HttpMessageConverter configureMessageConverters() {
|
||||
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
|
||||
FastJsonConfig config = new FastJsonConfig();
|
||||
config.setSerializerFeatures(
|
||||
// 保留map空的字段
|
||||
SerializerFeature.WriteMapNullValue,
|
||||
// 将String类型的null转成""
|
||||
SerializerFeature.WriteNullStringAsEmpty,
|
||||
// 将Number类型的null转成0
|
||||
SerializerFeature.WriteNullNumberAsZero,
|
||||
// 将List类型的null转成[]
|
||||
SerializerFeature.WriteNullListAsEmpty,
|
||||
// 将Boolean类型的null转成false
|
||||
SerializerFeature.WriteNullBooleanAsFalse,
|
||||
// 避免循环引用
|
||||
SerializerFeature.DisableCircularReferenceDetect);
|
||||
|
||||
converter.setFastJsonConfig(config);
|
||||
converter.setDefaultCharset(Charset.forName("UTF-8"));
|
||||
List<MediaType> mediaTypeList = new ArrayList<>();
|
||||
// 解决中文乱码问题,相当于在Controller上的@RequestMapping中加了个属性produces = "application/json"
|
||||
mediaTypeList.add(MediaType.APPLICATION_JSON);
|
||||
converter.setSupportedMediaTypes(mediaTypeList);
|
||||
return converter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new PasswordEncoder() {
|
||||
@Override
|
||||
public String encode(CharSequence charSequence) {
|
||||
return charSequence.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(CharSequence charSequence, String s) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
// return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
}
|
@ -63,9 +63,10 @@ public class TransactionConfig {
|
||||
public TransactionInterceptor txAdvice() {
|
||||
DefaultTransactionAttribute required = new DefaultTransactionAttribute();
|
||||
required.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
|
||||
required.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
|
||||
|
||||
DefaultTransactionAttribute readOnly = new DefaultTransactionAttribute();
|
||||
readOnly.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
|
||||
required.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
|
||||
readOnly.setReadOnly(true);
|
||||
|
||||
List<String> saveList = transactionProperties.getSaveList();
|
||||
@ -104,11 +105,11 @@ public class TransactionConfig {
|
||||
|
||||
@Bean
|
||||
public Advisor txAdviceAdvisor() {
|
||||
StringBuilder expressionSB = new StringBuilder("execution(* ink.wgink..*.service..*(..))");
|
||||
List<String> servicePackageList = transactionProperties.getServicePackageList();
|
||||
for (String servicePackage : servicePackageList) {
|
||||
expressionSB.append(" or execution(* " + servicePackage + "..*.service..*(..))");
|
||||
}
|
||||
StringBuilder expressionSB = new StringBuilder("execution(* *..service..*(..))");
|
||||
// List<String> servicePackageList = transactionProperties.getServicePackageList();
|
||||
// for (String servicePackage : servicePackageList) {
|
||||
// expressionSB.append(" or execution(* " + servicePackage + "..*.service..*(..))");
|
||||
// }
|
||||
|
||||
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||
pointcut.setExpression(expressionSB.toString());
|
||||
|
31
common/src/main/java/ink/wgink/common/config/WebConfig.java
Normal file
31
common/src/main/java/ink/wgink/common/config/WebConfig.java
Normal file
@ -0,0 +1,31 @@
|
||||
package ink.wgink.common.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: WebConfig
|
||||
* @Description: Web配置
|
||||
* @Author: wanggeng
|
||||
* @Date: 2021/2/5 7:44 下午
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Configuration
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
registry.addViewController("/").setViewName("forward:/index");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/static/assets/").setCachePeriod(7 * 24 * 3600);
|
||||
}
|
||||
|
||||
}
|
@ -22,6 +22,11 @@ import java.util.Map;
|
||||
@Repository
|
||||
public interface IFileDao {
|
||||
|
||||
/**
|
||||
* 建表
|
||||
*/
|
||||
void createTable();
|
||||
|
||||
/**
|
||||
* 保存文件
|
||||
*
|
||||
@ -99,5 +104,4 @@ public interface IFileDao {
|
||||
*/
|
||||
List<FileInfoDTO> listByMd5(String fileMd5) throws SearchException;
|
||||
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package ink.wgink.module.file.excel.error;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import ink.wgink.module.file.service.IFileService;
|
||||
import ink.wgink.util.UUIDUtil;
|
||||
import ink.wgink.util.request.RequestUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -0,0 +1,45 @@
|
||||
package ink.wgink.module.file.startup;
|
||||
|
||||
import ink.wgink.module.file.dao.IFileDao;
|
||||
import ink.wgink.pojo.dtos.user.UserDTO;
|
||||
import ink.wgink.util.date.DateUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: ModuleFileStartUp
|
||||
* @Description: 文件模块启动
|
||||
* @Author: wanggeng
|
||||
* @Date: 2021/2/9 9:18 下午
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Component
|
||||
public class ModuleFileStartUp implements ApplicationRunner {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ModuleFileStartUp.class);
|
||||
|
||||
@Autowired
|
||||
private IFileDao fileDao;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
initTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* 建表
|
||||
*/
|
||||
private void initTable() {
|
||||
LOG.debug("创建 sys_file 表");
|
||||
fileDao.createTable();
|
||||
}
|
||||
}
|
279
module-file/src/main/resources/mybatis/mapper/file-mapper.xml
Normal file
279
module-file/src/main/resources/mybatis/mapper/file-mapper.xml
Normal file
@ -0,0 +1,279 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="ink.wgink.module.file.dao.IFileDao">
|
||||
|
||||
<cache/>
|
||||
|
||||
<resultMap id="filePO" type="ink.wgink.pojo.pos.FilePO">
|
||||
<id property="fileId" column="file_id"/>
|
||||
<result property="fileName" column="file_name"/>
|
||||
<result property="filePath" column="file_path"/>
|
||||
<result property="fileUrl" column="file_url"/>
|
||||
<result property="fileType" column="file_type"/>
|
||||
<result property="fileSize" column="file_size"/>
|
||||
<result property="fileSummary" column="file_summary"/>
|
||||
<result property="isBack" column="is_back"/>
|
||||
<result property="creator" column="creator"/>
|
||||
<result property="gmtCreate" column="gmt_create"/>
|
||||
<result property="modifier" column="modifier"/>
|
||||
<result property="gmtModified" column="gmt_modified"/>
|
||||
<result property="isDelete" column="is_delete"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="fileDTO" type="ink.wgink.module.file.pojo.dtos.FileDTO">
|
||||
<id property="fileId" column="file_id"/>
|
||||
<result property="fileName" column="file_name"/>
|
||||
<result property="fileUrl" column="file_url"/>
|
||||
<result property="fileType" column="file_type"/>
|
||||
<result property="fileSize" column="file_size"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="fileInfoDTO" type="ink.wgink.module.file.pojo.dtos.FileInfoDTO" extends="fileDTO">
|
||||
<id property="fileId" column="file_id"/>
|
||||
<result property="fileName" column="file_name"/>
|
||||
<result property="fileUrl" column="file_url"/>
|
||||
<result property="fileType" column="file_type"/>
|
||||
<result property="fileSize" column="file_size"/>
|
||||
<result property="fileUrl" column="file_url"/>
|
||||
<result property="filePath" column="file_path"/>
|
||||
<result property="fileSummary" column="file_summary"/>
|
||||
<result property="isBack" column="is_back"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 建表 -->
|
||||
<update id="createTable">
|
||||
CREATE TABLE IF NOT EXISTS `sys_file` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`file_id` char(36) NOT NULL,
|
||||
`file_name` varchar(255) DEFAULT NULL COMMENT '文件名称',
|
||||
`file_path` varchar(500) DEFAULT NULL COMMENT '文件路径',
|
||||
`file_url` varchar(500) DEFAULT NULL COMMENT '文件URL',
|
||||
`file_type` varchar(20) DEFAULT NULL COMMENT '文件类型',
|
||||
`file_size` varchar(100) DEFAULT NULL COMMENT '文件大小',
|
||||
`file_summary` varchar(255) DEFAULT NULL COMMENT '文件说明',
|
||||
`is_back` int(2) DEFAULT '0',
|
||||
`creator` char(36) DEFAULT NULL COMMENT '创建人',
|
||||
`gmt_create` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`modifier` char(36) DEFAULT NULL COMMENT '修改人',
|
||||
`gmt_modified` datetime DEFAULT NULL,
|
||||
`is_delete` int(2) DEFAULT '0',
|
||||
PRIMARY KEY (`id`,`file_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
</update>
|
||||
|
||||
<!-- 保存文件 -->
|
||||
<insert id="save" parameterType="map" flushCache="true">
|
||||
INSERT INTO sys_file(
|
||||
file_id,
|
||||
file_name,
|
||||
file_path,
|
||||
file_url,
|
||||
file_type,
|
||||
file_size,
|
||||
file_summary,
|
||||
is_back,
|
||||
creator,
|
||||
gmt_create,
|
||||
modifier,
|
||||
gmt_modified,
|
||||
is_delete
|
||||
) VALUES(
|
||||
#{fileId},
|
||||
#{fileName},
|
||||
#{filePath},
|
||||
#{fileUrl},
|
||||
#{fileType},
|
||||
#{fileSize},
|
||||
#{fileSummary},
|
||||
#{isBack},
|
||||
#{creator},
|
||||
#{gmtCreate},
|
||||
#{modifier},
|
||||
#{gmtModified},
|
||||
#{isDelete}
|
||||
)
|
||||
</insert>
|
||||
|
||||
<!-- 删除文件 -->
|
||||
<update id="remove" parameterType="map" flushCache="true">
|
||||
UPDATE
|
||||
sys_file
|
||||
SET
|
||||
is_delete = 1,
|
||||
modifier = #{modifier},
|
||||
gmt_modified = #{gmtModified}
|
||||
WHERE
|
||||
file_id IN
|
||||
<foreach collection="fileIds" index="index" open="(" separator="," close=")">
|
||||
#{fileIds[${index}]}
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
<!-- 删除文件(物理删除) -->
|
||||
<delete id="delete" parameterType="map" flushCache="true">
|
||||
DELETE FROM
|
||||
sys_file
|
||||
WHERE
|
||||
file_id IN
|
||||
<foreach collection="fileIds" index="index" open="(" separator="," close=")">
|
||||
#{fileIds[${index}]}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<!-- 更新文件描述 -->
|
||||
<update id="updateSummary" parameterType="map" flushCache="true">
|
||||
UPDATE
|
||||
sys_file
|
||||
SET
|
||||
file_summary = #{fileSummary}
|
||||
WHERE
|
||||
<if test="fileId != null and fileId != ''">
|
||||
file_id = #{fileId}
|
||||
</if>
|
||||
<if test="fileIds != null and fileIds.size > 0">
|
||||
file_id IN
|
||||
<foreach collection="fileIds" index="index" open="(" separator="," close=")">
|
||||
#{fileIds[${index}]}
|
||||
</foreach>
|
||||
</if>
|
||||
</update>
|
||||
|
||||
<!-- 获取文件 -->
|
||||
<select id="getPO" parameterType="map" resultMap="filePO" useCache="true">
|
||||
SELECT
|
||||
file_id,
|
||||
file_name,
|
||||
file_path,
|
||||
file_url,
|
||||
file_type,
|
||||
file_size,
|
||||
file_summary,
|
||||
is_back,
|
||||
creator,
|
||||
gmt_create,
|
||||
modifier,
|
||||
gmt_modified,
|
||||
is_delete
|
||||
FROM
|
||||
sys_file
|
||||
WHERE
|
||||
is_delete = 0
|
||||
AND
|
||||
file_id = #{fileId}
|
||||
</select>
|
||||
|
||||
<!-- 文件列表 -->
|
||||
<select id="list" parameterType="map" resultMap="fileDTO" useCache="true">
|
||||
SELECT
|
||||
file_id,
|
||||
file_name,
|
||||
file_path,
|
||||
file_url,
|
||||
file_type,
|
||||
file_size,
|
||||
file_summary,
|
||||
is_back,
|
||||
creator,
|
||||
gmt_create,
|
||||
modifier,
|
||||
gmt_modified,
|
||||
is_delete
|
||||
FROM
|
||||
sys_file
|
||||
WHERE
|
||||
is_delete = 0
|
||||
<if test="keywords != null and keywords != ''">
|
||||
AND
|
||||
file_name LIKE CONCAT('%', #{keywords}, '%')
|
||||
</if>
|
||||
<if test="fileSummary != null and fileSummary != ''">
|
||||
AND
|
||||
file_summary = #{fileSummary}
|
||||
</if>
|
||||
<if test="startTime != null and startTime != ''">
|
||||
AND
|
||||
LEFT(gmt_create, 10) <![CDATA[ >= ]]> #{startTime}
|
||||
</if>
|
||||
<if test="endTime != null and endTime != ''">
|
||||
AND
|
||||
LEFT(gmt_create, 10) <![CDATA[ <= ]]> #{endTime}
|
||||
</if>
|
||||
<if test="ids != null and ids.size > 0">
|
||||
AND
|
||||
file_id IN
|
||||
<foreach collection="ids" index="index" open="(" separator="," close=")">
|
||||
#{ids[${index}]}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="fileUrl != null and fileUrl != ''">
|
||||
AND
|
||||
file_url LIKE concat('%', #{fileUrl}, '%')
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<!-- 文件列表 -->
|
||||
<select id="listInfo" parameterType="map" resultMap="fileInfoDTO" useCache="false">
|
||||
SELECT
|
||||
file_id,
|
||||
file_name,
|
||||
file_path,
|
||||
file_url,
|
||||
file_type,
|
||||
file_size,
|
||||
file_summary,
|
||||
is_back,
|
||||
creator,
|
||||
gmt_create,
|
||||
modifier,
|
||||
gmt_modified,
|
||||
is_delete
|
||||
FROM
|
||||
sys_file
|
||||
WHERE
|
||||
is_delete = 0
|
||||
<if test="keywords != null and keywords != ''">
|
||||
AND
|
||||
file_name LIKE CONCAT('%', #{keywords}, '%')
|
||||
</if>
|
||||
<if test="startTime != null and startTime != ''">
|
||||
AND
|
||||
LEFT(gmt_create, 10) <![CDATA[ >= ]]> #{startTime}
|
||||
</if>
|
||||
<if test="endTime != null and endTime != ''">
|
||||
AND
|
||||
LEFT(gmt_create, 10) <![CDATA[ <= ]]> #{endTime}
|
||||
</if>
|
||||
<if test="fileIds != null and fileIds.size > 0">
|
||||
AND
|
||||
file_id IN
|
||||
<foreach collection="fileIds" index="index" open="(" separator="," close=")">
|
||||
#{fileIds[${index}]}
|
||||
</foreach>
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<!-- 文件列表 -->
|
||||
<select id="listByMd5" parameterType="java.lang.String" resultMap="fileInfoDTO" useCache="false">
|
||||
SELECT
|
||||
file_id,
|
||||
file_name,
|
||||
file_path,
|
||||
file_url,
|
||||
file_type,
|
||||
file_size,
|
||||
file_summary,
|
||||
is_back,
|
||||
creator,
|
||||
gmt_create,
|
||||
modifier,
|
||||
gmt_modified,
|
||||
is_delete
|
||||
FROM
|
||||
sys_file
|
||||
WHERE
|
||||
is_delete = 0
|
||||
AND
|
||||
file_summary = #{_parameter}
|
||||
</select>
|
||||
|
||||
</mapper>
|
@ -1,8 +1,12 @@
|
||||
package ink.wgink.module.user.controller.api;
|
||||
|
||||
import ink.wgink.annotation.CheckRequestBodyAnnotation;
|
||||
import ink.wgink.common.base.DefaultBaseController;
|
||||
import ink.wgink.exceptions.ParamsException;
|
||||
import ink.wgink.interfaces.consts.IFileConstant;
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.module.user.pojo.vos.RestPasswordVO;
|
||||
import ink.wgink.module.user.pojo.vos.UpdateUsernameVO;
|
||||
import ink.wgink.pojo.ListPage;
|
||||
import ink.wgink.pojo.dtos.user.UserDTO;
|
||||
import ink.wgink.pojo.result.ErrorResult;
|
||||
@ -10,15 +14,19 @@ import ink.wgink.pojo.result.SuccessResult;
|
||||
import ink.wgink.pojo.result.SuccessResultList;
|
||||
import ink.wgink.module.user.pojo.vos.UserVO;
|
||||
import ink.wgink.module.user.service.IUserService;
|
||||
import ink.wgink.pojo.result.UploadExcelResultDTO;
|
||||
import ink.wgink.util.RegexUtil;
|
||||
import io.swagger.annotations.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
@ -85,6 +93,41 @@ public class UserController extends DefaultBaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation(value = "重置密码", notes = "重置密码接口")
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@PutMapping("resetpassword/{userId}")
|
||||
@CheckRequestBodyAnnotation
|
||||
public SuccessResult resetPassword(@PathVariable("userId") String userId, @RequestBody RestPasswordVO restPasswordVO) {
|
||||
userService.resetPassword(userId, restPasswordVO);
|
||||
return new SuccessResult();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "修改用户名", notes = "修改用户名密码接口")
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@PutMapping("updateusername/{userId}")
|
||||
@CheckRequestBodyAnnotation
|
||||
public SuccessResult updateUsername(@PathVariable("userId") String userId, @RequestBody UpdateUsernameVO updateUsernameVO) throws Exception {
|
||||
userService.updateUsername(userId, updateUsernameVO);
|
||||
return new SuccessResult();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "导入Excel", notes = "导入Excel接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "excel", value = "文件名称", paramType = "query"),
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@PostMapping("importexcel")
|
||||
public UploadExcelResultDTO importExcel(MultipartFile excel) throws IOException {
|
||||
if (Objects.isNull(excel)) {
|
||||
throw new ParamsException("Excel不能为空");
|
||||
}
|
||||
if (!excel.getOriginalFilename().endsWith(IFileConstant.EXCEL_SUFFIX_XLS) &&
|
||||
!excel.getOriginalFilename().endsWith(IFileConstant.EXCEL_SUFFIX_XLSX)) {
|
||||
throw new ParamsException("文件格式为Excel");
|
||||
}
|
||||
return userService.importExcel(excel);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "用户列表", notes = "用户列表接口")
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@GetMapping("list")
|
||||
@ -109,4 +152,14 @@ public class UserController extends DefaultBaseController {
|
||||
return userService.listPage(page);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "用户详情", notes = "用户详情接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "userId", value = "用户ID", paramType = "path")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@GetMapping("get/{userId}")
|
||||
public UserDTO getUser(@PathVariable("userId") String userId) {
|
||||
return userService.get(userId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,72 @@
|
||||
package ink.wgink.module.user.controller.route;
|
||||
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.util.ResourceUtil;
|
||||
import ink.wgink.util.request.RequestUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: UserRouteController
|
||||
* @Description: 用户路由
|
||||
* @Author: wanggeng
|
||||
* @Date: 2021/2/5 7:50 下午
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "用户路由接口")
|
||||
@Controller
|
||||
@RequestMapping(ISystemConstant.ROUTE_PREFIX + "/user")
|
||||
public class UserRouteController {
|
||||
|
||||
@GetMapping("list")
|
||||
public ModelAndView list() {
|
||||
return new ModelAndView("user/list");
|
||||
}
|
||||
|
||||
@GetMapping("save")
|
||||
public ModelAndView save() {
|
||||
return new ModelAndView("user/save");
|
||||
}
|
||||
|
||||
@GetMapping("update")
|
||||
public ModelAndView update() {
|
||||
return new ModelAndView("user/update");
|
||||
}
|
||||
|
||||
@GetMapping("rest-password")
|
||||
public ModelAndView restPassword() {
|
||||
return new ModelAndView("user/rest-password");
|
||||
}
|
||||
|
||||
@GetMapping("update-username")
|
||||
public ModelAndView updateUsername() {
|
||||
return new ModelAndView("user/update-username");
|
||||
}
|
||||
|
||||
@GetMapping("update-password")
|
||||
public ModelAndView updatePassword() {
|
||||
return new ModelAndView("user/update-password");
|
||||
}
|
||||
|
||||
@GetMapping("upload/upload-excel")
|
||||
public ModelAndView uploadExcel() {
|
||||
return new ModelAndView("user/upload/upload-excel");
|
||||
}
|
||||
|
||||
@GetMapping("upload/upload-excel-template")
|
||||
public void excelTemplate(HttpServletResponse response) throws IOException {
|
||||
File template = ResourceUtil.getResourceFile("templates/user/upload/upload-excel-template.xls");
|
||||
RequestUtil.download(response, template, "用户导入模板.xls");
|
||||
}
|
||||
|
||||
}
|
@ -24,6 +24,13 @@ import java.util.Map;
|
||||
@Repository
|
||||
public interface IUserDao {
|
||||
|
||||
/**
|
||||
* 建表
|
||||
*
|
||||
* @throws UpdateException
|
||||
*/
|
||||
void createTable() throws UpdateException;
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*
|
||||
|
@ -0,0 +1,72 @@
|
||||
package ink.wgink.module.user.excel;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: UserExcel
|
||||
* @Description: 用户Excel
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/1/6 11:11 下午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
public class UserExcel {
|
||||
|
||||
@ExcelProperty(index = 0)
|
||||
private String userUsername;
|
||||
@ExcelProperty(index = 1)
|
||||
private String userName;
|
||||
@ExcelProperty(index = 2)
|
||||
private String userPhone;
|
||||
@ExcelProperty(index = 3)
|
||||
private String userEmail;
|
||||
|
||||
public String getUserUsername() {
|
||||
return userUsername == null ? "" : userUsername.trim().replaceAll("\\s", "");
|
||||
}
|
||||
|
||||
public void setUserUsername(String userUsername) {
|
||||
this.userUsername = userUsername;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName == null ? "" : userName.trim().replaceAll("\\s", "");
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getUserPhone() {
|
||||
return userPhone == null ? "" : userPhone.trim().replaceAll("\\s", "");
|
||||
}
|
||||
|
||||
public void setUserPhone(String userPhone) {
|
||||
this.userPhone = userPhone;
|
||||
}
|
||||
|
||||
public String getUserEmail() {
|
||||
return userEmail == null ? "" : userEmail.trim().replaceAll("\\s", "");
|
||||
}
|
||||
|
||||
public void setUserEmail(String userEmail) {
|
||||
this.userEmail = userEmail;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("{");
|
||||
sb.append("\"userUsername\":")
|
||||
.append("\"").append(userUsername).append("\"");
|
||||
sb.append(",\"userName\":")
|
||||
.append("\"").append(userName).append("\"");
|
||||
sb.append(",\"userPhone\":")
|
||||
.append("\"").append(userPhone).append("\"");
|
||||
sb.append(",\"userEmail\":")
|
||||
.append("\"").append(userEmail).append("\"");
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package ink.wgink.module.user.excel;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: UserExcelError
|
||||
* @Description: 人员Excel异常
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/1/7 12:28 下午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
public class UserExcelError {
|
||||
|
||||
@ExcelProperty(index = 0)
|
||||
private String userUsername;
|
||||
@ExcelProperty(index = 1)
|
||||
private String userName;
|
||||
@ExcelProperty(index = 2)
|
||||
private String userPhone;
|
||||
@ExcelProperty(index = 3)
|
||||
private String userEmail;
|
||||
@ExcelProperty(index = 4)
|
||||
private String reason;
|
||||
|
||||
public String getUserUsername() {
|
||||
return userUsername == null ? "" : userUsername.trim();
|
||||
}
|
||||
|
||||
public void setUserUsername(String userUsername) {
|
||||
this.userUsername = userUsername;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName == null ? "" : userName.trim();
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getUserPhone() {
|
||||
return userPhone == null ? "" : userPhone.trim();
|
||||
}
|
||||
|
||||
public void setUserPhone(String userPhone) {
|
||||
this.userPhone = userPhone;
|
||||
}
|
||||
|
||||
public String getUserEmail() {
|
||||
return userEmail == null ? "" : userEmail.trim();
|
||||
}
|
||||
|
||||
public void setUserEmail(String userEmail) {
|
||||
this.userEmail = userEmail;
|
||||
}
|
||||
|
||||
public String getReason() {
|
||||
return reason == null ? "" : reason.trim();
|
||||
}
|
||||
|
||||
public void setReason(String reason) {
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("{");
|
||||
sb.append("\"userUsername\":")
|
||||
.append("\"").append(userUsername).append("\"");
|
||||
sb.append(",\"userName\":")
|
||||
.append("\"").append(userName).append("\"");
|
||||
sb.append(",\"userPhone\":")
|
||||
.append("\"").append(userPhone).append("\"");
|
||||
sb.append(",\"userEmail\":")
|
||||
.append("\"").append(userEmail).append("\"");
|
||||
sb.append(",\"reason\":")
|
||||
.append("\"").append(reason).append("\"");
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package ink.wgink.module.user.excel;
|
||||
|
||||
import com.alibaba.excel.context.AnalysisContext;
|
||||
import com.alibaba.excel.event.AnalysisEventListener;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: UserExcelListener
|
||||
* @Description: 用户Excel监听器
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/1/6 11:06 下午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
public abstract class UserExcelListener extends AnalysisEventListener<UserExcel> {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UserExcelListener.class);
|
||||
private List<UserExcel> userExcels = new ArrayList<>(0);
|
||||
|
||||
@Override
|
||||
public void invoke(UserExcel userExcel, AnalysisContext analysisContext) {
|
||||
userExcels.add(userExcel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
|
||||
try {
|
||||
listUserExcel(userExcels);
|
||||
} catch (Exception e) {
|
||||
LOG.error(e.getMessage());
|
||||
}
|
||||
userExcels.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户列表
|
||||
*
|
||||
* @param userExcels
|
||||
*/
|
||||
public abstract void listUserExcel(List<UserExcel> userExcels) throws Exception;
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package ink.wgink.module.user.pojo.vos;
|
||||
|
||||
import ink.wgink.annotation.CheckEmptyAnnotation;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: UpdateUserUsernameVO
|
||||
* @Description: 修改用户名
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/5/21 10:04 下午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
@ApiModel
|
||||
public class RestPasswordVO {
|
||||
|
||||
@ApiModelProperty(name = "updateReason", value = "修改原因")
|
||||
@CheckEmptyAnnotation(name = "修改原因")
|
||||
private String updateReason;
|
||||
|
||||
public String getUpdateReason() {
|
||||
return updateReason == null ? "" : updateReason.trim();
|
||||
}
|
||||
|
||||
public void setUpdateReason(String updateReason) {
|
||||
this.updateReason = updateReason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("{");
|
||||
sb.append("\"updateReason\":\"")
|
||||
.append(updateReason).append('\"');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package ink.wgink.module.user.pojo.vos;
|
||||
|
||||
import ink.wgink.annotation.CheckEmptyAnnotation;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: UpdateUserUsernameVO
|
||||
* @Description: 修改用户名
|
||||
* @Author: WangGeng
|
||||
* @Date: 2020/5/21 10:04 下午
|
||||
* @Version: 1.0
|
||||
**/
|
||||
@ApiModel
|
||||
public class UpdateUsernameVO {
|
||||
|
||||
@ApiModelProperty(name = "username", value = "用户名")
|
||||
@CheckEmptyAnnotation(name = "用户名", regex = "username")
|
||||
private String username;
|
||||
@ApiModelProperty(name = "updateReason", value = "修改原因")
|
||||
@CheckEmptyAnnotation(name = "修改原因")
|
||||
private String updateReason;
|
||||
|
||||
public String getUsername() {
|
||||
return username == null ? "" : username.trim();
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getUpdateReason() {
|
||||
return updateReason == null ? "" : updateReason.trim();
|
||||
}
|
||||
|
||||
public void setUpdateReason(String updateReason) {
|
||||
this.updateReason = updateReason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("{");
|
||||
sb.append("\"username\":\"")
|
||||
.append(username).append('\"');
|
||||
sb.append(",\"updateReason\":\"")
|
||||
.append(updateReason).append('\"');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -1,9 +1,14 @@
|
||||
package ink.wgink.module.user.service;
|
||||
|
||||
import ink.wgink.interfaces.user.IUserBaseService;
|
||||
import ink.wgink.module.user.pojo.vos.RestPasswordVO;
|
||||
import ink.wgink.module.user.pojo.vos.UpdateUsernameVO;
|
||||
import ink.wgink.pojo.dtos.user.UserDTO;
|
||||
import ink.wgink.module.user.pojo.vos.UserVO;
|
||||
import ink.wgink.pojo.result.UploadExcelResultDTO;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -46,17 +51,36 @@ public interface IUserService extends IUserBaseService {
|
||||
/**
|
||||
* 修改用户
|
||||
*
|
||||
* @param userId
|
||||
* @param userVO
|
||||
* @param userId 用户ID
|
||||
* @param userVO 用户内容
|
||||
* @return
|
||||
*/
|
||||
void update(String userId, UserVO userVO);
|
||||
|
||||
/**
|
||||
* 用户列表
|
||||
* 重置用户密码
|
||||
*
|
||||
* @param params
|
||||
* @param userId 用户ID
|
||||
* @param restPasswordVO 重置密码
|
||||
* @return
|
||||
*/
|
||||
List<UserDTO> list(Map<String, Object> params);
|
||||
void resetPassword(String userId, RestPasswordVO restPasswordVO);
|
||||
|
||||
/**
|
||||
* 修改用户名
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param updateUsernameVO 更新用户名
|
||||
*/
|
||||
void updateUsername(String userId, UpdateUsernameVO updateUsernameVO);
|
||||
|
||||
/**
|
||||
* 导入Excel
|
||||
*
|
||||
* @param excel
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
UploadExcelResultDTO importExcel(MultipartFile excel) throws IOException;
|
||||
|
||||
}
|
||||
|
@ -1,23 +1,36 @@
|
||||
package ink.wgink.module.user.service.impl;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import ink.wgink.common.base.DefaultBaseService;
|
||||
import ink.wgink.exceptions.SearchException;
|
||||
import ink.wgink.module.file.excel.error.AbstractErrorExcelHandler;
|
||||
import ink.wgink.module.file.service.IFileService;
|
||||
import ink.wgink.module.user.dao.IUserDao;
|
||||
import ink.wgink.module.user.excel.UserExcel;
|
||||
import ink.wgink.module.user.excel.UserExcelError;
|
||||
import ink.wgink.module.user.excel.UserExcelListener;
|
||||
import ink.wgink.module.user.pojo.vos.RestPasswordVO;
|
||||
import ink.wgink.module.user.pojo.vos.UpdateUsernameVO;
|
||||
import ink.wgink.module.user.pojo.vos.UserVO;
|
||||
import ink.wgink.module.user.service.IUserService;
|
||||
import ink.wgink.pojo.ListPage;
|
||||
import ink.wgink.pojo.dtos.user.UserDTO;
|
||||
import ink.wgink.pojo.result.SuccessResultList;
|
||||
import ink.wgink.module.user.dao.IUserDao;
|
||||
import ink.wgink.module.user.pojo.vos.UserVO;
|
||||
import ink.wgink.module.user.service.IUserService;
|
||||
import ink.wgink.pojo.result.UploadExcelResultDTO;
|
||||
import ink.wgink.util.UUIDUtil;
|
||||
import ink.wgink.util.map.HashMapUtil;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -38,9 +51,13 @@ public class UserServiceImpl extends DefaultBaseService implements IUserService
|
||||
private IUserDao userDao;
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
@Value("${user.default-password:88888888}")
|
||||
private String defaultPassword;
|
||||
@Autowired
|
||||
private IFileService fileService;
|
||||
|
||||
@Override
|
||||
public synchronized void save(UserVO userVO) {
|
||||
public void save(UserVO userVO) {
|
||||
saveUser(userVO, false);
|
||||
}
|
||||
|
||||
@ -56,7 +73,7 @@ public class UserServiceImpl extends DefaultBaseService implements IUserService
|
||||
* @param isRegister 是否注册
|
||||
*/
|
||||
private void saveUser(UserVO userVO, boolean isRegister) {
|
||||
UserDTO userDTO = get(userVO.getUserUsername());
|
||||
UserDTO userDTO = getByUsername(userVO.getUserUsername());
|
||||
if (userDTO != null) {
|
||||
throw new SearchException("用户已经存在");
|
||||
}
|
||||
@ -75,7 +92,7 @@ public class UserServiceImpl extends DefaultBaseService implements IUserService
|
||||
@Override
|
||||
public void remove(List<String> ids) {
|
||||
Map<String, Object> params = getHashMap(2);
|
||||
params.put("ids", ids);
|
||||
params.put("userIds", ids);
|
||||
setUpdateInfo(params);
|
||||
userDao.remove(params);
|
||||
}
|
||||
@ -87,9 +104,88 @@ public class UserServiceImpl extends DefaultBaseService implements IUserService
|
||||
}
|
||||
Map<String, Object> params = HashMapUtil.beanToMap(userVO);
|
||||
setUpdateInfo(params);
|
||||
params.put("userId", userId);
|
||||
userDao.update(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetPassword(String userId, RestPasswordVO restPasswordVO) {
|
||||
UserDTO userDTO = get(userId);
|
||||
if (userDTO == null) {
|
||||
throw new SearchException("修改用户不存在");
|
||||
}
|
||||
Map<String, Object> params = getHashMap(4);
|
||||
params.put("userId", userId);
|
||||
params.put("userPassword", passwordEncoder.encode(DigestUtils.md5Hex(DigestUtils.md5Hex(DigestUtils.md5Hex(defaultPassword)))));
|
||||
userDao.updatePassword(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUsername(String userId, UpdateUsernameVO updateUsernameVO) {
|
||||
UserDTO oldUserDTO = get(userId);
|
||||
if (oldUserDTO == null) {
|
||||
throw new SearchException("用户不存在");
|
||||
}
|
||||
Map<String, Object> params = getHashMap(2);
|
||||
params.put("userUsername", updateUsernameVO.getUsername());
|
||||
UserDTO userDTO = userDao.get(params);
|
||||
if (userDTO != null && !StringUtils.equals(userId, userDTO.getUserId())) {
|
||||
throw new SearchException("新用户名已经存在");
|
||||
}
|
||||
params.put("userId", userId);
|
||||
userDao.updateUsername(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UploadExcelResultDTO importExcel(MultipartFile excel) throws IOException {
|
||||
Map<String, Object> params = getHashMap(16);
|
||||
// 错误列表
|
||||
List<UserExcelError> userExcelErrors = new ArrayList<>();
|
||||
long startTime = System.currentTimeMillis();
|
||||
LOG.debug("读取Excel");
|
||||
EasyExcel.read(excel.getInputStream(), UserExcel.class, new UserExcelListener() {
|
||||
@Override
|
||||
public void listUserExcel(List<UserExcel> userExcels) throws Exception {
|
||||
for (UserExcel userExcel : userExcels) {
|
||||
// 判断昵称存在
|
||||
String userUsername = userExcel.getUserUsername();
|
||||
String userName = userExcel.getUserName();
|
||||
if (StringUtils.isBlank(userUsername) || StringUtils.isBlank(userName)) {
|
||||
userExcelErrors.add(getUserExcelError(userExcel, "必填值存在空值,导入失败"));
|
||||
continue;
|
||||
}
|
||||
String userPhone = userExcel.getUserPhone();
|
||||
String userEmail = userExcel.getUserEmail();
|
||||
try {
|
||||
// 保存用户
|
||||
UserVO userVO = new UserVO();
|
||||
userVO.setUserUsername(userUsername);
|
||||
userVO.setUserName(userName);
|
||||
userVO.setUserPassword(defaultPassword);
|
||||
userVO.setUserPhone(userPhone);
|
||||
userVO.setUserEmail(userEmail);
|
||||
userVO.setUserType(2);
|
||||
userVO.setUserState(0);
|
||||
saveUser(userVO, false);
|
||||
} catch (Exception e) {
|
||||
userExcelErrors.add(getUserExcelError(userExcel, e.getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}).headRowNumber(2).sheet().doRead();
|
||||
long endTime = System.currentTimeMillis();
|
||||
String excelFileId = null;
|
||||
if (userExcelErrors.size() > 0) {
|
||||
excelFileId = new AbstractErrorExcelHandler<UserExcelError>(fileService) {
|
||||
@Override
|
||||
public List<List<String>> excelHeaderNames() {
|
||||
return simpleExcelHeader(new String[]{"用户名", "昵称", "手机", "邮箱", "错误原因"});
|
||||
}
|
||||
}.saveErrorExcel(userExcelErrors);
|
||||
}
|
||||
return new UploadExcelResultDTO(userExcelErrors.size(), endTime - startTime, excelFileId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDTO get(String userId) {
|
||||
Map<String, Object> params = getHashMap(2);
|
||||
@ -111,6 +207,13 @@ public class UserServiceImpl extends DefaultBaseService implements IUserService
|
||||
return list(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserDTO> listByUsernames(List<String> usernames) {
|
||||
Map<String, Object> params = getHashMap(2);
|
||||
params.put("userUsernames", usernames);
|
||||
return list(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserDTO> list(Map<String, Object> params) {
|
||||
return userDao.list(params);
|
||||
@ -124,4 +227,21 @@ public class UserServiceImpl extends DefaultBaseService implements IUserService
|
||||
return new SuccessResultList<>(userDTOs, pageInfo.getPageNum(), pageInfo.getTotal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Excel导入错误对象
|
||||
*
|
||||
* @param userExcel
|
||||
* @param reason
|
||||
* @return
|
||||
*/
|
||||
private UserExcelError getUserExcelError(UserExcel userExcel, String reason) {
|
||||
UserExcelError userExcelError = new UserExcelError();
|
||||
userExcelError.setUserUsername(userExcel.getUserUsername());
|
||||
userExcelError.setUserName(userExcel.getUserName());
|
||||
userExcelError.setUserPhone(userExcel.getUserPhone());
|
||||
userExcelError.setUserEmail(userExcel.getUserEmail());
|
||||
userExcelError.setReason(reason);
|
||||
return userExcelError;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,62 @@
|
||||
package ink.wgink.module.user.startup;
|
||||
|
||||
import ink.wgink.module.user.dao.IUserDao;
|
||||
import ink.wgink.pojo.dtos.user.UserDTO;
|
||||
import ink.wgink.util.date.DateUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* When you feel like quitting. Think about why you started
|
||||
* 当你想要放弃的时候,想想当初你为何开始
|
||||
*
|
||||
* @ClassName: ServiceUserStartUp
|
||||
* @Description: 用户业务
|
||||
* @Author: wanggeng
|
||||
* @Date: 2021/2/5 8:59 下午
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Component
|
||||
public class ServiceUserStartUp implements ApplicationRunner {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ServiceUserStartUp.class);
|
||||
|
||||
@Autowired
|
||||
private IUserDao userDao;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
initTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* 建表
|
||||
*/
|
||||
private void initTable() {
|
||||
LOG.debug("创建 sys_user 表");
|
||||
userDao.createTable();
|
||||
LOG.debug("检查 admin 是否存在");
|
||||
Map<String, Object> params = new HashMap<>(2);
|
||||
params.put("userUsername", "admin");
|
||||
UserDTO userDTO = userDao.get(params);
|
||||
if (userDTO == null) {
|
||||
LOG.debug("admin 不存在,新增");
|
||||
String currentDate = DateUtil.getTime();
|
||||
params.put("userId", "1");
|
||||
params.put("userPassword", "");
|
||||
params.put("userName", "超级管理员");
|
||||
params.put("gmtCreate", currentDate);
|
||||
params.put("creator", "1");
|
||||
params.put("gmtModified", currentDate);
|
||||
params.put("modifier", "1");
|
||||
params.put("isDelete", 0);
|
||||
userDao.save(params);
|
||||
}
|
||||
}
|
||||
}
|
@ -45,6 +45,43 @@
|
||||
<result property="gmtCreate" column="gmt_create"/>
|
||||
</resultMap>
|
||||
|
||||
<update id="createTable">
|
||||
CREATE TABLE IF NOT EXISTS `sys_user` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`user_id` char(36) NOT NULL,
|
||||
`user_username` varchar(255) NOT NULL COMMENT '用户名',
|
||||
`user_password` varchar(255) DEFAULT NULL COMMENT '密码',
|
||||
`user_name` varchar(255) DEFAULT NULL COMMENT '姓名',
|
||||
`user_phone` varchar(20) DEFAULT NULL COMMENT '电话',
|
||||
`user_email` varchar(255) DEFAULT NULL COMMENT '邮箱',
|
||||
`user_ukey` varchar(32) DEFAULT NULL COMMENT 'UKey',
|
||||
`user_ukey_electronic_secret_key` text COMMENT '用户UKey电子秘钥',
|
||||
`user_type` int(2) DEFAULT '2',
|
||||
`user_state` int(2) DEFAULT '0' COMMENT '用户状态',
|
||||
`user_avatar` char(36) DEFAULT NULL COMMENT '头像',
|
||||
`user_longitude` varchar(255) DEFAULT '0' COMMENT '经度',
|
||||
`user_latitude` varchar(255) DEFAULT '0' COMMENT '纬度',
|
||||
`last_login_address` varchar(255) DEFAULT NULL COMMENT '最后登录地址',
|
||||
`last_login_time` datetime DEFAULT NULL COMMENT '最后登录时间',
|
||||
`login_type` int(1) DEFAULT '1' COMMENT '登录类型',
|
||||
`gmt_password_modified` date DEFAULT NULL COMMENT '密码修改时间',
|
||||
`remarks` varchar(255) DEFAULT NULL COMMENT '备注',
|
||||
`creator` char(36) DEFAULT NULL,
|
||||
`gmt_create` datetime DEFAULT NULL,
|
||||
`modifier` char(36) DEFAULT NULL,
|
||||
`gmt_modified` datetime DEFAULT NULL,
|
||||
`is_delete` int(2) DEFAULT '0',
|
||||
PRIMARY KEY (`id`,`user_id`,`user_username`),
|
||||
UNIQUE KEY `user_username` (`user_username`) USING BTREE,
|
||||
KEY `user_id` (`user_id`) USING BTREE,
|
||||
KEY `user_name` (`user_name`) USING BTREE,
|
||||
KEY `user_id_2` (`user_id`,`user_username`,`user_name`) USING BTREE,
|
||||
KEY `user_id_3` (`user_id`,`user_name`) USING BTREE,
|
||||
KEY `user_id_4` (`user_id`,`user_name`,`user_avatar`) USING BTREE,
|
||||
KEY `is_delete_idx` (`is_delete`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
</update>
|
||||
|
||||
<!-- 保存用户 -->
|
||||
<insert id="save" parameterType="map" flushCache="true">
|
||||
INSERT INTO sys_user(
|
||||
|
349
service-user/src/main/resources/templates/user/list.html
Normal file
349
service-user/src/main/resources/templates/user/list.html
Normal file
@ -0,0 +1,349 @@
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<base th:href="${#request.getContextPath() + '/'}">
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
|
||||
<link rel="stylesheet" href="assets/js/vendor/viewer/viewer.min.css">
|
||||
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
|
||||
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-fluid layui-anim layui-anim-fadein">
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div class="layui-col-md12">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<div class="test-table-reload-btn" style="margin-bottom: 10px;">
|
||||
<div class="layui-inline">
|
||||
<input type="text" id="keywords" class="layui-input search-item" placeholder="输入关键字">
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<input type="text" id="startTime" class="layui-input search-item" placeholder="开始时间" readonly>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<input type="text" id="endTime" class="layui-input search-item" placeholder="结束时间" readonly>
|
||||
</div>
|
||||
<button type="button" id="search" class="layui-btn layui-btn-sm">
|
||||
<i class="fa fa-lg fa-search"></i> 搜索
|
||||
</button>
|
||||
<button type="button" class="layui-btn layui-btn-sm" id="uploadExcel" style="margin-left: 0;">
|
||||
<i class="fa fa-lg fa-cloud-upload"></i> 导入数据
|
||||
</button>
|
||||
</div>
|
||||
<table class="layui-hide" id="dataTable" lay-filter="dataTable"></table>
|
||||
<!-- 表头按钮组 -->
|
||||
<script type="text/html" id="headerToolBar">
|
||||
<div class="layui-btn-group">
|
||||
<button type="button" class="layui-btn layui-btn-sm" lay-event="saveEvent">
|
||||
<i class="fa fa-lg fa-plus"></i> 新增
|
||||
</button>
|
||||
<button type="button" class="layui-btn layui-btn-normal layui-btn-sm" lay-event="updateEvent">
|
||||
<i class="fa fa-lg fa-edit"></i> 编辑
|
||||
</button>
|
||||
<button type="button" class="layui-btn layui-btn-danger layui-btn-sm" lay-event="removeEvent">
|
||||
<i class="fa fa-lg fa-trash"></i> 删除
|
||||
</button>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="assets/layuiadmin/layui/layui.js"></script>
|
||||
<script>
|
||||
layui.config({
|
||||
base: 'assets/layuiadmin/'
|
||||
}).extend({
|
||||
index: 'lib/index'
|
||||
}).use(['index', 'table', 'laydate', 'upload'], function() {
|
||||
var $ = layui.$;
|
||||
var $win = $(window);
|
||||
var table = layui.table;
|
||||
var admin = layui.admin;
|
||||
var layer = layui.layer;
|
||||
var laydate = layui.laydate;
|
||||
var windowWidth = $(window).width();
|
||||
var windowHeight = $(window).height();
|
||||
var resizeTimeout = null;
|
||||
var tableUrl = 'api/user/listpage';
|
||||
|
||||
// 初始化表格
|
||||
function initTable() {
|
||||
table.render({
|
||||
elem: '#dataTable',
|
||||
id: 'dataTable',
|
||||
url: top.restAjax.path(tableUrl, []),
|
||||
width: admin.screen() > 1 ? '100%' : '',
|
||||
height: $win.height() - 90,
|
||||
limit: 20,
|
||||
limits: [20, 40, 60, 80, 100, 200],
|
||||
toolbar: '#headerToolBar',
|
||||
request: {
|
||||
pageName: 'page',
|
||||
limitName: 'rows'
|
||||
},
|
||||
cols: [
|
||||
[
|
||||
{type:'checkbox', fixed: 'left'},
|
||||
{field:'rowNum', width:80, title: '序号', fixed: 'left', align:'center', templet: '<span>{{d.LAY_INDEX}}</span>'},
|
||||
{field:'userUsername', width:140, title: '用户名', sort: true, align:'center',
|
||||
templet: function(rowData) {
|
||||
return '<a href="javascript:void(0);" lay-event="userUsernameEvent">'+ rowData.userUsername +'</a>';
|
||||
}
|
||||
},
|
||||
{field:'userName', width:140, title: '昵称', sort: true, align:'center'},
|
||||
{field:'userType', width:100, title: '类型', sort: true, align:'center',
|
||||
templet: function(item) {
|
||||
if(item.userType == 1) {
|
||||
return '<span class="layui-badge layui-bg-green">系统用户</span>';
|
||||
} else if(item.userType == 2) {
|
||||
return '<span class="layui-badge layui-bg-orange">普通用户</span>';
|
||||
}
|
||||
return '<span class="layui-badge">类型错误</span>';
|
||||
}
|
||||
},
|
||||
{field:'userState', width:80, title: '状态', sort: true, align:'center',
|
||||
templet: function(item) {
|
||||
var value;
|
||||
switch (item.userState) {
|
||||
case 1:
|
||||
value = '<span class="layui-badge">冻结</span>';
|
||||
break;
|
||||
case 2:
|
||||
value = '<span class="layui-badge layui-bg-green">锁定</span>';
|
||||
break;
|
||||
default:
|
||||
value = '<span class="layui-badge layui-bg-blue">正常</span>';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
},
|
||||
{field:'userPhone', width:140, title: '手机', sort: true, align:'center',
|
||||
templet: function(item) {
|
||||
if(!item.userPhone) {
|
||||
return '-';
|
||||
}
|
||||
return item.userPhone;
|
||||
}
|
||||
},
|
||||
{field:'userEmail', width: 160, title: '邮箱', sort: true, align:'center',
|
||||
templet: function(item) {
|
||||
if(!item.userEmail) {
|
||||
return '-';
|
||||
}
|
||||
return item.userEmail;
|
||||
}
|
||||
},
|
||||
{field:'lastLoginAddress', width:140, title: '登录地址', align:'center',
|
||||
templet: function(item) {
|
||||
if(!item.lastLoginAddress) {
|
||||
return '-';
|
||||
}
|
||||
return item.lastLoginAddress;
|
||||
}
|
||||
},
|
||||
{field:'lastLoginTime', width:200, title: '最后登录系统时间', align:'center',
|
||||
templet: function(item) {
|
||||
if(!item.lastLoginTime) {
|
||||
return '-';
|
||||
}
|
||||
return item.lastLoginTime;
|
||||
}
|
||||
},
|
||||
{field:'gmtCreate', width:200, title: '创建时间', align:'center',
|
||||
templet: function(item) {
|
||||
if(!item.gmtCreate) {
|
||||
return '-';
|
||||
}
|
||||
return item.gmtCreate;
|
||||
}
|
||||
},
|
||||
{field:'opition', width:120, title: '操作', fixed:'right', align:'center',
|
||||
templet: function(item) {
|
||||
return '<button type="button" class="layui-btn layui-btn-sm" lay-event="resetPasswordEvent">' +
|
||||
'<i class="fa fa-key"></i> 重置密码' +
|
||||
'</button>';
|
||||
}
|
||||
},
|
||||
]
|
||||
],
|
||||
page: true,
|
||||
parseData: function(data) {
|
||||
return {
|
||||
'code': 0,
|
||||
'msg': '',
|
||||
'count': data.total,
|
||||
'data': data.rows
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
// 重载表格
|
||||
function reloadTable(currentPage) {
|
||||
table.reload('dataTable', {
|
||||
url: top.restAjax.path(tableUrl, []),
|
||||
where: {
|
||||
keywords: $('#keywords').val(),
|
||||
startTime: $('#startTime').val(),
|
||||
endTime: $('#endTime').val()
|
||||
},
|
||||
page: {
|
||||
curr: currentPage
|
||||
},
|
||||
height: $win.height() - 90,
|
||||
});
|
||||
}
|
||||
// 初始化日期
|
||||
function initDate() {
|
||||
// 日期选择
|
||||
laydate.render({
|
||||
elem: '#startTime',
|
||||
format: 'yyyy-MM-dd'
|
||||
});
|
||||
laydate.render({
|
||||
elem: '#endTime',
|
||||
format: 'yyyy-MM-dd'
|
||||
});
|
||||
}
|
||||
// 删除
|
||||
function removeData(ids) {
|
||||
top.dialog.msg(top.dataMessage.delete, {
|
||||
time: 0,
|
||||
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
|
||||
shade: 0.3,
|
||||
yes: function (index) {
|
||||
top.dialog.close(index);
|
||||
var layIndex;
|
||||
top.restAjax.delete(top.restAjax.path('api/user/remove/{ids}', [ids]), {}, null, function (code, data) {
|
||||
top.dialog.msg(top.dataMessage.deleteSuccess, {time: 1000});
|
||||
reloadTable();
|
||||
}, function (code, data) {
|
||||
top.dialog.msg(data.msg);
|
||||
}, function () {
|
||||
layIndex = top.dialog.msg(top.dataMessage.deleting, {icon: 16, time: 0, shade: 0.3});
|
||||
}, function () {
|
||||
top.dialog.close(layIndex);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
initTable();
|
||||
initDate();
|
||||
// 事件 - 页面变化
|
||||
$win.on('resize', function() {
|
||||
clearTimeout(resizeTimeout);
|
||||
resizeTimeout = setTimeout(function() {
|
||||
reloadTable();
|
||||
}, 500);
|
||||
});
|
||||
// 事件 - 搜索
|
||||
$(document).on('click', '#search', function() {
|
||||
reloadTable(1);
|
||||
});
|
||||
$(document).on('click', '#uploadExcel', function() {
|
||||
top.dialog.open({
|
||||
url: top.restAjax.path('route/user/upload/upload-excel', []),
|
||||
title: '导入用户数据',
|
||||
width: '300px',
|
||||
height: '196px',
|
||||
onClose: function() {
|
||||
reloadTable();
|
||||
}
|
||||
});
|
||||
});
|
||||
// 事件 - 增删改
|
||||
table.on('toolbar(dataTable)', function(obj) {
|
||||
var layEvent = obj.event;
|
||||
var checkStatus = table.checkStatus('dataTable');
|
||||
var checkDatas = checkStatus.data;
|
||||
if(layEvent === 'saveEvent') {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: false,
|
||||
closeBtn: 0,
|
||||
area: ['100%', '100%'],
|
||||
shadeClose: true,
|
||||
anim: 2,
|
||||
content: top.restAjax.path('route/user/save', []),
|
||||
end: function() {
|
||||
reloadTable();
|
||||
}
|
||||
});
|
||||
} else if(layEvent === 'updateEvent') {
|
||||
if(checkDatas.length === 0) {
|
||||
top.dialog.msg(top.dataMessage.table.selectEdit);
|
||||
} else if(checkDatas.length > 1) {
|
||||
top.dialog.msg(top.dataMessage.table.selectOneEdit);
|
||||
} else {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: false,
|
||||
closeBtn: 0,
|
||||
area: ['100%', '100%'],
|
||||
shadeClose: true,
|
||||
anim: 2,
|
||||
content: top.restAjax.path('route/user/update?userId={id}', [checkDatas[0].userId]),
|
||||
end: function() {
|
||||
reloadTable();
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if(layEvent === 'removeEvent') {
|
||||
if(checkDatas.length === 0) {
|
||||
top.dialog.msg(top.dataMessage.table.selectDelete);
|
||||
} else {
|
||||
var ids = '';
|
||||
for(var i = 0, item; item = checkDatas[i++];) {
|
||||
if(i > 1) {
|
||||
ids += '_';
|
||||
}
|
||||
ids += item.userId;
|
||||
}
|
||||
removeData(ids);
|
||||
}
|
||||
}
|
||||
});
|
||||
table.on('tool(dataTable)', function(obj) {
|
||||
var layEvent = obj.event;
|
||||
var data = obj.data;
|
||||
if(layEvent === 'userUsernameEvent') {
|
||||
top.dialog.open({
|
||||
url: top.restAjax.path('route/user/update-username?userId={userId}', [data.userId]),
|
||||
title: '【'+ data.userName +'】修改用户名',
|
||||
width: '320px',
|
||||
height: '330px',
|
||||
onClose: function() {
|
||||
reloadTable();
|
||||
}
|
||||
});
|
||||
} else if(layEvent === 'resetPasswordEvent') {
|
||||
top.dialog.open({
|
||||
url: top.restAjax.path('route/user/rest-password?userId={userId}', [data.userId]),
|
||||
title: '【'+ data.userName +'】重置密码',
|
||||
width: '320px',
|
||||
height: '280px',
|
||||
onClose: function() {
|
||||
reloadTable();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
// 事件-排序
|
||||
table.on('sort(dataTable)', function(obj) {
|
||||
table.reload('dataTable', {
|
||||
initSort: obj,
|
||||
where: {
|
||||
sort: obj.field,
|
||||
order: obj.type
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,86 @@
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<base th:href="${#request.getContextPath() + '/'}">
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
|
||||
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
|
||||
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-fluid layui-anim layui-anim-fadein" style="padding: 0;overflow: hidden;">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body" style="padding: 15px;">
|
||||
<form class="layui-form layui-form-pane" lay-filter="dataForm">
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">修改原因</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="updateReason" required lay-verify="required" placeholder="请输入修改原因" class="layui-textarea" maxlength="80"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-layout-admin">
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-footer" style="left: 0;">
|
||||
<button type="button" class="layui-btn" lay-submit lay-filter="submitForm">提交编辑</button>
|
||||
<button type="button" class="layui-btn layui-btn-primary close">关闭窗口</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="assets/layuiadmin/layui/layui.js"></script>
|
||||
<script>
|
||||
layui.config({
|
||||
base: 'assets/layuiadmin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index', 'form'], function(){
|
||||
var $ = layui.$;
|
||||
var form = layui.form;
|
||||
var userId = top.restAjax.params(window.location.href).userId;
|
||||
|
||||
function closeBox() {
|
||||
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
form.on('submit(submitForm)', function(formData) {
|
||||
top.dialog.confirm(top.dataMessage.update, function(index) {
|
||||
top.dialog.close(index);
|
||||
var loadLayerIndex;
|
||||
top.restAjax.put(top.restAjax.path('api/user/resetpassword/{userId}', [userId]), formData.field, null, function(code, data) {
|
||||
var layerIndex = top.dialog.msg(top.dataMessage.updateSuccess, {
|
||||
time: 0,
|
||||
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
|
||||
shade: 0.3,
|
||||
yes: function(index) {
|
||||
top.dialog.close(index);
|
||||
window.location.reload();
|
||||
},
|
||||
btn2: function() {
|
||||
closeBox();
|
||||
}
|
||||
});
|
||||
}, function(code, data) {
|
||||
top.dialog.msg(data.msg);
|
||||
}, function() {
|
||||
loadLayerIndex = top.dialog.msg(top.dataMessage.updating, {icon: 16, time: 0, shade: 0.3});
|
||||
}, function() {
|
||||
top.dialog.close(loadLayerIndex);
|
||||
});
|
||||
});
|
||||
return false;
|
||||
});
|
||||
$('.close').on('click', function() {
|
||||
closeBox();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
169
service-user/src/main/resources/templates/user/save.html
Normal file
169
service-user/src/main/resources/templates/user/save.html
Normal file
@ -0,0 +1,169 @@
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<base th:href="${#request.getContextPath() + '/'}">
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
|
||||
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
|
||||
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-fluid layui-anim layui-anim-fadein">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">
|
||||
<span class="layui-breadcrumb" lay-filter="breadcrumb" style="visibility: visible;">
|
||||
<a class="close" href="javascript:void(0);">上级列表</a><span lay-separator="">/</span>
|
||||
<a href="javascript:void(0);"><cite>新增内容</cite></a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="layui-card-body" style="padding: 15px;">
|
||||
<form class="layui-form layui-form-pane" lay-filter="dataForm">
|
||||
<div class="layui-row">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">用户名 *</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="userUsername" lay-verify="userUsername" placeholder="请输入用户名" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">密码 *</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="password" name="userPassword" lay-verify="required" placeholder="请输入密码" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">昵称 *</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="userName" lay-verify="required" placeholder="请输入昵称" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item" pane>
|
||||
<label class="layui-form-label">类型 *</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="userType" value="1" title="系统用户">
|
||||
<input type="radio" name="userType" value="2" title="普通用户" checked>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">状态 *</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="userState" lay-verify="required">
|
||||
<option value="0">正常</option>
|
||||
<option value="1">冻结</option>
|
||||
<option value="2">锁定</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">手机</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="userPhone" placeholder="请输入手机" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">邮箱</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="userEmail" placeholder="请输入邮箱" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">头像</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-textarea">
|
||||
<img id="avatarImage" src="assets/images/profile-photo.jpg" title="点击修改头像">
|
||||
<input type="hidden" id="userAvatar" name="userAvatar">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-layout-admin">
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-footer" style="left: 0;">
|
||||
<button type="button" class="layui-btn" lay-submit lay-filter="submitForm">提交新增</button>
|
||||
<button type="button" class="layui-btn layui-btn-primary close">返回上级</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="assets/layuiadmin/layui/layui.js"></script>
|
||||
<script>
|
||||
layui.config({
|
||||
base: 'assets/layuiadmin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index', 'form', 'laydate'], function(){
|
||||
var $ = layui.$;
|
||||
var form = layui.form;
|
||||
function closeBox() {
|
||||
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
||||
}
|
||||
// 提交表单
|
||||
form.on('submit(submitForm)', function(formData) {
|
||||
var authorizedGrantTypes = top.restAjax.checkBoxToString(formData.field, 'authorizedGrantTypes');
|
||||
formData.field.authorizedGrantTypes = authorizedGrantTypes;
|
||||
top.dialog.confirm(top.dataMessage.commit, function(index) {
|
||||
top.dialog.close(index);
|
||||
var loadLayerIndex;
|
||||
top.restAjax.post(top.restAjax.path('api/user/save', []), formData.field, null, function(code, data) {
|
||||
var layerIndex = top.dialog.msg(top.dataMessage.commitSuccess, {
|
||||
time: 0,
|
||||
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
|
||||
shade: 0.3,
|
||||
yes: function(index) {
|
||||
top.dialog.close(index);
|
||||
window.location.reload();
|
||||
},
|
||||
btn2: function() {
|
||||
closeBox();
|
||||
}
|
||||
});
|
||||
}, function(code, data) {
|
||||
top.dialog.msg(data.msg);
|
||||
}, function() {
|
||||
loadLayerIndex = top.dialog.msg(top.dataMessage.committing, {icon: 16, time: 0, shade: 0.3});
|
||||
}, function() {
|
||||
top.dialog.close(loadLayerIndex);
|
||||
});
|
||||
});
|
||||
return false;
|
||||
});
|
||||
form.verify({
|
||||
userUsername: function(value, item) {
|
||||
if(!new RegExp('^[a-zA-Z0-9_\\s·]+$').test(value)) {
|
||||
return '用户名不能有特殊字符';
|
||||
}
|
||||
if(/(^\_)|(\__)|(\_+$)/.test(value)){
|
||||
return '用户名首尾不能出现下划线\'_\'';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#avatarImage').on('click', function() {
|
||||
top.dialog.open({
|
||||
url: 'route/file/uploadimage/v2?fileId='+ $('#userAvatar').val(),
|
||||
title: '上传头像',
|
||||
width: '800px',
|
||||
height: '470px',
|
||||
onClose: function() {
|
||||
var uploadImage = top.dialog.dialogData.uploadImage;
|
||||
if(typeof(uploadImage) != 'undefined' && null != uploadImage && '' != uploadImage) {
|
||||
$('#avatarImage').attr('src', 'route/file/downloadfile/false/' + uploadImage);
|
||||
$('#userAvatar').val(uploadImage);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
$('.close').on('click', function() {
|
||||
closeBox();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,104 @@
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<base th:href="${#request.getContextPath() + '/'}">
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
|
||||
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
|
||||
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-fluid layui-anim layui-anim-fadein" style="padding: 0;overflow: hidden;">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body" style="padding: 15px;">
|
||||
<form class="layui-form layui-form-pane" lay-filter="dataForm">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">旧密码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="password" name="oldPassword" lay-verify="required" placeholder="请输入旧密码" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">新密码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="password" id="newPassword" name="newPassword" lay-verify="required" placeholder="请输入新密码" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">确认密码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="password" name="confirmNewPassword" lay-verify="required|passwordSame" placeholder="请输入确认密码" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-layout-admin">
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-footer" style="left: 0;">
|
||||
<button type="button" class="layui-btn" lay-submit lay-filter="submitForm">提交编辑</button>
|
||||
<button type="button" class="layui-btn layui-btn-primary close">关闭窗口</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="assets/layuiadmin/layui/layui.js"></script>
|
||||
<script>
|
||||
layui.config({
|
||||
base: 'assets/layuiadmin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index', 'form'], function(){
|
||||
var $ = layui.$;
|
||||
var form = layui.form;
|
||||
|
||||
function closeBox() {
|
||||
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
form.on('submit(submitForm)', function(formData) {
|
||||
top.dialog.confirm(top.dataMessage.commit, function(index) {
|
||||
top.dialog.close(index);
|
||||
var loadLayerIndex;
|
||||
top.restAjax.put(top.restAjax.path('api/user/updateuserpassword', []), formData.field, null, function(code, data) {
|
||||
var layerIndex = top.dialog.msg(top.dataMessage.commitSuccess, {
|
||||
time: 0,
|
||||
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
|
||||
shade: 0.3,
|
||||
yes: function(index) {
|
||||
top.dialog.close(index);
|
||||
window.location.reload();
|
||||
},
|
||||
btn2: function() {
|
||||
closeBox();
|
||||
}
|
||||
});
|
||||
}, function(code, data) {
|
||||
top.dialog.msg(data.msg);
|
||||
}, function() {
|
||||
loadLayerIndex = top.dialog.msg(top.dataMessage.committing, {icon: 16, time: 0, shade: 0.3});
|
||||
}, function() {
|
||||
top.dialog.close(loadLayerIndex);
|
||||
});
|
||||
});
|
||||
return false;
|
||||
});
|
||||
form.verify({
|
||||
passwordSame: function(value, item) {
|
||||
if($('#newPassword').val() != value) {
|
||||
return '确认密码不一致';
|
||||
}
|
||||
},
|
||||
});
|
||||
$('.close').on('click', function() {
|
||||
closeBox();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,102 @@
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<base th:href="${#request.getContextPath() + '/'}">
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
|
||||
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
|
||||
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-fluid layui-anim layui-anim-fadein" style="padding: 0;overflow: hidden;">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body" style="padding: 15px;">
|
||||
<form class="layui-form layui-form-pane" lay-filter="dataForm">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">新用户名</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="username" name="username" lay-verify="username" placeholder="请输入新用户名" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">修改原因</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="updateReason" required lay-verify="required" placeholder="请输入修改原因" class="layui-textarea" maxlength="80"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-layout-admin">
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-footer" style="left: 0;">
|
||||
<button type="button" class="layui-btn" lay-submit lay-filter="submitForm">提交编辑</button>
|
||||
<button type="button" class="layui-btn layui-btn-primary close">关闭窗口</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="assets/layuiadmin/layui/layui.js"></script>
|
||||
<script>
|
||||
layui.config({
|
||||
base: 'assets/layuiadmin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index', 'form'], function(){
|
||||
var $ = layui.$;
|
||||
var form = layui.form;
|
||||
var userId = top.restAjax.params(window.location.href).userId;
|
||||
|
||||
function closeBox() {
|
||||
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
form.on('submit(submitForm)', function(formData) {
|
||||
top.dialog.confirm(top.dataMessage.update, function(index) {
|
||||
top.dialog.close(index);
|
||||
var loadLayerIndex;
|
||||
top.restAjax.put(top.restAjax.path('api/user/updateusername/{userId}', [userId]), formData.field, null, function(code, data) {
|
||||
var layerIndex = top.dialog.msg(top.dataMessage.updateSuccess, {
|
||||
time: 0,
|
||||
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
|
||||
shade: 0.3,
|
||||
yes: function(index) {
|
||||
top.dialog.close(index);
|
||||
window.location.reload();
|
||||
},
|
||||
btn2: function() {
|
||||
closeBox();
|
||||
}
|
||||
});
|
||||
}, function(code, data) {
|
||||
top.dialog.msg(data.msg);
|
||||
}, function() {
|
||||
loadLayerIndex = top.dialog.msg(top.dataMessage.updating, {icon: 16, time: 0, shade: 0.3});
|
||||
}, function() {
|
||||
top.dialog.close(loadLayerIndex);
|
||||
});
|
||||
});
|
||||
return false;
|
||||
});
|
||||
form.verify({
|
||||
userUsername: function(value, item) {
|
||||
if(!new RegExp('^[a-zA-Z0-9_\\s·]+$').test(value)) {
|
||||
return '用户名不能有特殊字符';
|
||||
}
|
||||
if(/(^\_)|(\__)|(\_+$)/.test(value)){
|
||||
return '用户名首尾不能出现下划线\'_\'';
|
||||
}
|
||||
}
|
||||
});
|
||||
$('.close').on('click', function() {
|
||||
closeBox();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
198
service-user/src/main/resources/templates/user/update.html
Normal file
198
service-user/src/main/resources/templates/user/update.html
Normal file
@ -0,0 +1,198 @@
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<base th:href="${#request.getContextPath() + '/'}">
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
|
||||
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
|
||||
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-fluid layui-anim layui-anim-fadein">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">
|
||||
<span class="layui-breadcrumb" lay-filter="breadcrumb" style="visibility: visible;">
|
||||
<a class="close" href="javascript:void(0);">上级列表</a><span lay-separator="">/</span>
|
||||
<a href="javascript:void(0);"><cite>编辑内容</cite></a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="layui-card-body" style="padding: 15px;">
|
||||
<form class="layui-form layui-form-pane" lay-filter="dataForm">
|
||||
<div class="layui-row">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">用户名 *</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="userUsername" lay-verify="userUsername" placeholder="请输入用户名" class="layui-input" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">新密码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="password" name="userPassword" placeholder="修改密码,请输入新密码,不修改为空" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">昵称 *</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="userName" lay-verify="required" placeholder="请输入昵称" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item" pane>
|
||||
<label class="layui-form-label">类型 *</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="userType" value="1" title="系统用户">
|
||||
<input type="radio" name="userType" value="2" title="普通用户">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">状态 *</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="userState" lay-verify="required">
|
||||
<option value="0">正常</option>
|
||||
<option value="1">冻结</option>
|
||||
<option value="2">锁定</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">手机</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="userPhone" placeholder="请输入手机" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">邮箱</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="userEmail" placeholder="请输入邮箱" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">头像</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-textarea">
|
||||
<img id="avatarImage" src="assets/images/profile-photo.jpg" title="点击修改头像">
|
||||
<input type="hidden" id="userAvatar" name="userAvatar">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-layout-admin">
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-footer" style="left: 0;">
|
||||
<button type="button" class="layui-btn" lay-submit lay-filter="submitForm">提交编辑</button>
|
||||
<button type="button" class="layui-btn layui-btn-primary close">返回上级</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="assets/layuiadmin/layui/layui.js"></script>
|
||||
<script>
|
||||
layui.config({
|
||||
base: 'assets/layuiadmin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index', 'form', 'laydate'], function(){
|
||||
var $ = layui.$;
|
||||
var form = layui.form;
|
||||
var userId = top.restAjax.params(window.location.href).userId;
|
||||
function closeBox() {
|
||||
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
||||
}
|
||||
// 初始化
|
||||
function initData() {
|
||||
var self = this;
|
||||
var loadLayerIndex;
|
||||
top.restAjax.get(top.restAjax.path('api/user/get/{userId}', [userId]), {}, null, function(code, data) {
|
||||
form.val('dataForm', {
|
||||
userAvatar: data.userAvatar,
|
||||
userUsername: data.userUsername,
|
||||
userName: data.userName,
|
||||
userType: data.userType +'',
|
||||
userState: data.userState +'',
|
||||
userPhone: data.userPhone,
|
||||
userEmail: data.userEmail.toString(),
|
||||
});
|
||||
form.render(null, 'dataForm');
|
||||
if($('#userAvatar').val() != '') {
|
||||
$('#avatarImage').attr('src', 'route/file/downloadfile/false/' + $('#userAvatar').val());
|
||||
} else {
|
||||
$('#userAvatar').val($('#userAvatar').val());
|
||||
}
|
||||
}, function(code, data) {
|
||||
top.dialog.msg(data.msg);
|
||||
}, function() {
|
||||
loadLayerIndex = top.dialog.msg(top.dataMessage.loading, {icon: 16, time: 0, shade: 0.3});
|
||||
}, function() {
|
||||
top.dialog.close(loadLayerIndex);
|
||||
});
|
||||
}
|
||||
initData();
|
||||
// 提交表单
|
||||
form.on('submit(submitForm)', function(formData) {
|
||||
var authorizedGrantTypes = top.restAjax.checkBoxToString(formData.field, 'authorizedGrantTypes');
|
||||
formData.field.authorizedGrantTypes = authorizedGrantTypes;
|
||||
top.dialog.confirm(top.dataMessage.commit, function(index) {
|
||||
top.dialog.close(index);
|
||||
var loadLayerIndex;
|
||||
top.restAjax.put(top.restAjax.path('api/user/update/{userId}', [userId]), formData.field, null, function(code, data) {
|
||||
var layerIndex = top.dialog.msg(top.dataMessage.commitSuccess, {
|
||||
time: 0,
|
||||
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
|
||||
shade: 0.3,
|
||||
yes: function(index) {
|
||||
top.dialog.close(index);
|
||||
window.location.reload();
|
||||
},
|
||||
btn2: function() {
|
||||
closeBox();
|
||||
}
|
||||
});
|
||||
}, function(code, data) {
|
||||
top.dialog.msg(data.msg);
|
||||
}, function() {
|
||||
loadLayerIndex = top.dialog.msg(top.dataMessage.committing, {icon: 16, time: 0, shade: 0.3});
|
||||
}, function() {
|
||||
top.dialog.close(loadLayerIndex);
|
||||
});
|
||||
});
|
||||
return false;
|
||||
});
|
||||
form.verify({
|
||||
userUsername: function(value, item) {
|
||||
if(!new RegExp('^[a-zA-Z0-9_\\s]+$').test(value)) {
|
||||
return '用户名不能有特殊字符';
|
||||
}
|
||||
if(/(^\_)|(\__)|(\_+$)/.test(value)){
|
||||
return '用户名首尾不能出现下划线\'_\'';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#avatarImage').on('click', function() {
|
||||
top.dialog.open({
|
||||
url: 'route/file/uploadimage/v2?fileId='+ $('#userAvatar').val(),
|
||||
title: '上传头像',
|
||||
width: '800px',
|
||||
height: '470px',
|
||||
onClose: function() {
|
||||
var uploadImage = top.dialog.dialogData.uploadImage;
|
||||
if(typeof(uploadImage) != 'undefined' && null != uploadImage && '' != uploadImage) {
|
||||
$('#avatarImage').attr('src', 'route/file/downloadfile/false/' + uploadImage);
|
||||
$('#userAvatar').val(uploadImage);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
$('.close').on('click', function() {
|
||||
closeBox();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
@ -0,0 +1,90 @@
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<base th:href="${#request.getContextPath() + '/'}">
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
|
||||
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
|
||||
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-anim layui-anim-fadein">
|
||||
<div class="layui-card" style="text-align: center;">
|
||||
<div class="layui-card-body" style="padding: 15px;">
|
||||
<blockquote class="layui-elem-quote">下载“下载模板”整理数据,点击“导入数据”上传,格式为xls或xlsx</blockquote>
|
||||
<button type="button" class="layui-btn layui-btn" onclick="window.open('route/user/upload/upload-excel-template')">
|
||||
<i class="fa fa-lg fa-cloud-download"></i> 下载模板
|
||||
</button>
|
||||
<button type="button" class="layui-btn layui-btn" id="uploadExcel">
|
||||
<i class="fa fa-lg fa-cloud-upload"></i> 导入数据
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="assets/layuiadmin/layui/layui.js"></script>
|
||||
<script>
|
||||
layui.config({
|
||||
base: 'assets/layuiadmin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index', 'upload'], function(){
|
||||
var $ = layui.$;
|
||||
var form = layui.form;
|
||||
|
||||
function closeBox() {
|
||||
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
||||
}
|
||||
|
||||
// 初始化Excel上传
|
||||
function initExcelUpload() {
|
||||
// Excel上传
|
||||
var uploadLoading;
|
||||
layui.upload.render({
|
||||
elem: '#uploadExcel',
|
||||
url: 'api/user/importexcel',
|
||||
accept: 'file',
|
||||
exts: 'xls|xlsx',
|
||||
field: 'excel',
|
||||
before: function() {
|
||||
uploadLoading = layer.msg('正在上传,请稍后...', {icon: 16, time: 0, shade: 0.3});
|
||||
},
|
||||
done: function(data) {
|
||||
layer.close(uploadLoading);
|
||||
if(data.failedCount > 0) {
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: false,
|
||||
closeBtn: 0,
|
||||
shadeClose: true,
|
||||
skin: '',
|
||||
content: '<div style="padding: 15px;">' +
|
||||
'<div>失败数量:'+ data.failedCount +'</div><br/>' +
|
||||
'<div><a href="javascript:void(0);" onclick="window.open(\'route/file/download/false/'+ data.errorExcel +'\');">点击下载错误信息</a></div>' +
|
||||
'</div>'
|
||||
});
|
||||
} else {
|
||||
layer.msg('导入成功', {time: 2000}, function() {
|
||||
closeBox();
|
||||
});
|
||||
}
|
||||
},
|
||||
error: function(data, index){
|
||||
layer.close(uploadLoading);
|
||||
if(data != null) {
|
||||
top.dialog.msg(data.msg);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
initExcelUpload();
|
||||
|
||||
$('.close').on('click', function() {
|
||||
closeBox();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user