First Commit
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
package quant.rich.emoney.controller;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.validation.BeanPropertyBindingResult;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.validation.Errors;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import quant.rich.emoney.controller.common.BaseController;
|
||||
import quant.rich.emoney.exception.PageNotFoundException;
|
||||
import quant.rich.emoney.interfaces.ConfigInfo;
|
||||
import quant.rich.emoney.interfaces.IConfig;
|
||||
import quant.rich.emoney.pojo.dto.R;
|
||||
import quant.rich.emoney.service.ConfigService;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/admin/v1/config")
|
||||
public class ConfigControllerV1 extends BaseController {
|
||||
|
||||
@Autowired
|
||||
Validator validator;
|
||||
|
||||
@Autowired
|
||||
ConfigService configService;
|
||||
|
||||
@GetMapping({ "/{configField}", "/{configField}/", "/{configField}/index" })
|
||||
public String configPage(@PathVariable String configField) {
|
||||
ConfigInfo info = configService.getConfigInfoByField(configField);
|
||||
if (info == null || !info.managed()) {
|
||||
throw new PageNotFoundException();
|
||||
}
|
||||
request.setAttribute("title", info.name());
|
||||
return "admin/v1/config/" + configField + "/index";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文件重载
|
||||
* @param configField
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@GetMapping("/reload/{configField}")
|
||||
@ResponseBody
|
||||
public <T extends IConfig<T>> R<?> reload(@PathVariable String configField) {
|
||||
return R.judge(() ->
|
||||
configService.saveOrUpdate((T)configService.getOrCreateConfig(configField))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存配置项统一接口
|
||||
* @throws Exception
|
||||
*/
|
||||
@PostMapping({ "/{configField}", "/{configField}/", "/{configField}/index" })
|
||||
@ResponseBody
|
||||
public <T extends IConfig<T>> R<?> saveConfig(@PathVariable String configField, @Validated @RequestBody JsonNode config) throws Exception {
|
||||
|
||||
Class<T> clazz = configService.getConfigClassByField(configField);
|
||||
if (clazz == null) {
|
||||
throw new PageNotFoundException();
|
||||
}
|
||||
|
||||
return R.judgeThrow(() -> {
|
||||
T newConfig = (T)new ObjectMapper().treeToValue(config, clazz);
|
||||
|
||||
Method method = this.getClass().getMethod("saveConfig", String.class, JsonNode.class);
|
||||
MethodParameter methodParameter = new MethodParameter(method, 1);
|
||||
|
||||
// 执行校验
|
||||
BindingResult bindingResult = new BeanPropertyBindingResult(newConfig, clazz.getSimpleName());
|
||||
validator.validate(newConfig, bindingResult);
|
||||
|
||||
if (bindingResult.hasErrors()) {
|
||||
throw new MethodArgumentNotValidException(methodParameter, bindingResult);
|
||||
}
|
||||
|
||||
T oldConfig = configService.getConfig(clazz);
|
||||
oldConfig.mergeFrom(newConfig);
|
||||
return oldConfig.saveOrUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package quant.rich.emoney.controller;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import quant.rich.emoney.controller.common.BaseController;
|
||||
import quant.rich.emoney.entity.config.PlatformConfig;
|
||||
import quant.rich.emoney.exception.RException;
|
||||
import quant.rich.emoney.pojo.dto.R;
|
||||
import quant.rich.emoney.service.ConfigService;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/admin/v1")
|
||||
public class IndexControllerV1 extends BaseController {
|
||||
|
||||
@Autowired
|
||||
PlatformConfig platformConfig;
|
||||
|
||||
@Autowired
|
||||
ConfigService configService;
|
||||
|
||||
@GetMapping({ "", "/", "/index" })
|
||||
public String index() {
|
||||
return "admin/v1/index";
|
||||
}
|
||||
|
||||
@PostMapping("/changeUserInfo")
|
||||
@ResponseBody
|
||||
public R<?> changeUserInfo(String newUsername, String oldPassword, String newPassword) {
|
||||
if (!platformConfig.getPassword().equals(oldPassword)) {
|
||||
throw RException.badRequest("密码错误");
|
||||
}
|
||||
if (StringUtils.isAllEmpty(newUsername, newPassword)) {
|
||||
throw RException.badRequest("未更改任何信息");
|
||||
}
|
||||
if (StringUtils.isNotEmpty(newUsername)) {
|
||||
platformConfig.setUsername(newUsername);
|
||||
}
|
||||
if (StringUtils.isNotEmpty(newPassword)) {
|
||||
platformConfig.setPassword(newPassword);
|
||||
}
|
||||
configService.saveOrUpdate(platformConfig);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package quant.rich.emoney.controller;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import jodd.util.Base64;
|
||||
import quant.rich.emoney.controller.common.BaseController;
|
||||
import quant.rich.emoney.entity.config.PlatformConfig;
|
||||
import quant.rich.emoney.pojo.dto.R;
|
||||
import quant.rich.emoney.service.AuthService;
|
||||
import quant.rich.emoney.service.ConfigService;
|
||||
import quant.rich.emoney.util.EncryptUtils;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/admin/v1")
|
||||
public class LoginControllerV1 extends BaseController {
|
||||
|
||||
@Autowired
|
||||
ConfigService configService;
|
||||
|
||||
@Autowired
|
||||
PlatformConfig platformConfig;
|
||||
|
||||
@Autowired
|
||||
AuthService authService;
|
||||
|
||||
@GetMapping("/login")
|
||||
public String login() {
|
||||
|
||||
if (isLogin()) {
|
||||
return "redirect:/admin/v1/index";
|
||||
}
|
||||
|
||||
if (!platformConfig.getIsInited()) {
|
||||
return "admin/v1/init";
|
||||
}
|
||||
|
||||
return "admin/v1/login";
|
||||
|
||||
}
|
||||
|
||||
@PostMapping("/login")
|
||||
@ResponseBody
|
||||
public R<?> login(String username, String password, String captcha, String redirect) throws LoginException {
|
||||
|
||||
// 登录流程
|
||||
if (platformConfig.getIsInited()) {
|
||||
|
||||
if (StringUtils.isBlank(captcha)) {
|
||||
throw new LoginException("验证码不能为空");
|
||||
}
|
||||
Object sessionCaptcha = session.getAttribute(AuthService.CAPTCHA);
|
||||
if (Objects.isNull(sessionCaptcha) || !captcha.equalsIgnoreCase(sessionCaptcha.toString())) {
|
||||
throw new LoginException("验证码错误");
|
||||
}
|
||||
if (StringUtils.isAnyBlank(username) || !passwordIsNotEmpty(password)) {
|
||||
throw new LoginException("用户名和密码不能为空");
|
||||
}
|
||||
if (!username.equals(platformConfig.getUsername())
|
||||
|| !password.equals(platformConfig.getPassword())) {
|
||||
session.removeAttribute(AuthService.CAPTCHA);
|
||||
throw new LoginException("用户名或密码错误");
|
||||
}
|
||||
String to = "/admin/v1";
|
||||
if (StringUtils.isNotEmpty(redirect)) {
|
||||
to = Base64.decodeToString(redirect);
|
||||
}
|
||||
|
||||
authService.setLogin(username, password);
|
||||
|
||||
session.removeAttribute(AuthService.CAPTCHA);
|
||||
return R.ok(to);
|
||||
}
|
||||
// 初始化流程
|
||||
|
||||
if (StringUtils.isAnyBlank(username) || !passwordIsNotEmpty(password)) {
|
||||
throw new LoginException("用户名和密码不能为空");
|
||||
}
|
||||
platformConfig.setUsername(username).setPassword(password).setIsInited(true);
|
||||
boolean success = configService.saveOrUpdate(platformConfig);
|
||||
if (!success) {
|
||||
throw new LoginException("无法配置用户名和密码,请检查");
|
||||
}
|
||||
|
||||
String to = Base64.decodeToString("/admin/v1/login");
|
||||
return R.ok(to);
|
||||
}
|
||||
|
||||
@GetMapping("/logout")
|
||||
public String logout() {
|
||||
return "redirect:/admin/v1/login";
|
||||
}
|
||||
|
||||
static final String EMPTY_PASSWORD = EncryptUtils.sha3("", 224);
|
||||
|
||||
static boolean passwordIsNotEmpty(String password) {
|
||||
return StringUtils.isNotEmpty(password) && !password.equalsIgnoreCase(EMPTY_PASSWORD);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
package quant.rich.emoney.controller.api;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.protobuf.nano.MessageNano;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import nano.BaseResponse.Base_Response;
|
||||
import quant.rich.emoney.entity.sqlite.ProtocolMatch;
|
||||
import quant.rich.emoney.exception.RException;
|
||||
import quant.rich.emoney.pojo.dto.EmoneyConvertResult;
|
||||
import quant.rich.emoney.pojo.dto.EmoneyProtobufBody;
|
||||
import quant.rich.emoney.service.sqlite.ProtocolMatchService;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/proto")
|
||||
@Slf4j
|
||||
public class ProtoDecodeControllerV1 {
|
||||
|
||||
@Autowired
|
||||
private ProtocolMatchService protocolMatchService;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@PostMapping("/request/decode")
|
||||
public <U extends MessageNano> EmoneyConvertResult requestDecode(
|
||||
@RequestBody(required=true)
|
||||
@NonNull
|
||||
EmoneyProtobufBody body) {
|
||||
|
||||
Integer protocolId = body.getProtocolId();
|
||||
if (Objects.isNull(protocolId)) {
|
||||
throw RException.badRequest("protocolId cannot be null");
|
||||
}
|
||||
|
||||
ProtocolMatch match = protocolMatchService.getById(protocolId);
|
||||
|
||||
if (Objects.isNull(match) || StringUtils.isBlank(match.getClassName())) {
|
||||
throw RException.badRequest("暂无对应 protocolId = " + protocolId + " 的记录,可等 response decoder 搜集到后重试");
|
||||
}
|
||||
|
||||
String className = new StringBuilder()
|
||||
.append("nano.")
|
||||
.append(match.getClassName())
|
||||
.append("Request$")
|
||||
.append(match.getClassName())
|
||||
.append("_Request")
|
||||
.toString();
|
||||
// IndexInflow -> nano.IndexInflowRequest$IndexInflow_Request
|
||||
|
||||
Class<U> clazz;
|
||||
try {
|
||||
clazz = (Class<U>)Class.forName(className);
|
||||
}
|
||||
catch (Exception e) {
|
||||
String msg = new StringBuilder()
|
||||
.append("无法根据给定的 protocolId = ")
|
||||
.append(protocolId)
|
||||
.append(", className = ")
|
||||
.append(className)
|
||||
.append("找到对应类").toString();
|
||||
log.warn(msg, e);
|
||||
throw RException.internalServerError(msg);
|
||||
}
|
||||
|
||||
byte[] buf;
|
||||
try {
|
||||
buf = body.protocolBodyToByte();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw RException.badRequest("转换 protocolBody 错误");
|
||||
}
|
||||
|
||||
try {
|
||||
U nano = (U)MessageNano.mergeFrom((MessageNano)
|
||||
clazz.getDeclaredConstructor().newInstance(), buf);
|
||||
return EmoneyConvertResult
|
||||
.ok(new ObjectMapper().valueToTree(nano))
|
||||
.setProtocolId(protocolId)
|
||||
.setSupposedClassName(className);
|
||||
}
|
||||
catch (Exception e) {
|
||||
String msg = new StringBuilder()
|
||||
.append("转换为类 ")
|
||||
.append(className)
|
||||
.append(" 时错误").toString();
|
||||
log.warn(msg, e);
|
||||
return EmoneyConvertResult.error(msg)
|
||||
.setProtocolId(protocolId)
|
||||
.setSupposedClassName(className);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@PostMapping("/response/decode")
|
||||
public <U extends MessageNano> EmoneyConvertResult responseDecode(
|
||||
@RequestBody(required=false)
|
||||
@NonNull
|
||||
EmoneyProtobufBody body) {
|
||||
|
||||
Integer protocolId = body.getProtocolId();
|
||||
ProtocolMatch match = null;
|
||||
if (Objects.isNull(protocolId)) {
|
||||
log.warn("protocolId is null, cannot update protocolMatch");
|
||||
}
|
||||
else {
|
||||
match = protocolMatchService.getById(protocolId);
|
||||
if (Objects.isNull(match)) {
|
||||
match = new ProtocolMatch().setProtocolId(protocolId);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] buf;
|
||||
try {
|
||||
buf = body.protocolBodyToByte();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw RException.badRequest("转换 protocolBody 错误");
|
||||
}
|
||||
|
||||
Base_Response baseResponse;
|
||||
try {
|
||||
baseResponse = Base_Response.parseFrom(buf);
|
||||
}
|
||||
catch (Exception e) {
|
||||
String msg = new StringBuilder()
|
||||
.append("转换 BaseResponse 发生错误")
|
||||
.toString();
|
||||
log.warn(msg, e);
|
||||
return EmoneyConvertResult
|
||||
.error(msg)
|
||||
.setProtocolId(protocolId);
|
||||
}
|
||||
|
||||
Class<U> clazz;
|
||||
String className =
|
||||
baseResponse.detail.getTypeUrl()
|
||||
.replace("type.googleapis.com/", "");
|
||||
|
||||
String rawClassName = className.substring(0, className.lastIndexOf('_'));
|
||||
if (Objects.nonNull(match) && StringUtils.isBlank(match.getClassName())) {
|
||||
match.setClassName(rawClassName);
|
||||
protocolMatchService.saveOrUpdate(match);
|
||||
}
|
||||
|
||||
className = new StringBuilder()
|
||||
.append("nano.")
|
||||
.append(rawClassName)
|
||||
.append("Response$")
|
||||
.append(className)
|
||||
.toString();
|
||||
|
||||
try {
|
||||
clazz = (Class<U>)Class.forName(className);
|
||||
}
|
||||
catch (Exception e) {
|
||||
String msg = new StringBuilder()
|
||||
.append("无法根据给定的 protocolId = ")
|
||||
.append(protocolId)
|
||||
.append(", className = ")
|
||||
.append(className)
|
||||
.append("找到对应类").toString();
|
||||
log.warn(msg, e);
|
||||
throw RException.internalServerError(msg);
|
||||
}
|
||||
|
||||
try {
|
||||
U nano = (U)MessageNano.mergeFrom(
|
||||
(MessageNano)clazz.getDeclaredConstructor().newInstance(),
|
||||
baseResponse.detail.getValue());
|
||||
return EmoneyConvertResult
|
||||
.ok(new ObjectMapper().valueToTree(nano))
|
||||
.setProtocolId(protocolId)
|
||||
.setSupposedClassName(className);
|
||||
}
|
||||
catch (Exception e) {
|
||||
String msg = new StringBuilder()
|
||||
.append("转换为类 ")
|
||||
.append(className)
|
||||
.append(" 时错误").toString();
|
||||
log.warn(msg, e);
|
||||
return EmoneyConvertResult.error(msg)
|
||||
.setProtocolId(protocolId)
|
||||
.setSupposedClassName(className);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package quant.rich.emoney.controller.common;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import quant.rich.emoney.service.AuthService;
|
||||
|
||||
@Controller
|
||||
public abstract class BaseController {
|
||||
|
||||
@Autowired
|
||||
protected HttpServletRequest request;
|
||||
|
||||
@Autowired
|
||||
protected HttpServletResponse response;
|
||||
|
||||
@Autowired
|
||||
protected HttpSession session;
|
||||
|
||||
@Autowired
|
||||
AuthService authService;
|
||||
|
||||
protected Boolean isLogin() {
|
||||
return authService.isLogin();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package quant.rich.emoney.controller.common;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.web.error.ErrorAttributeOptions;
|
||||
import org.springframework.boot.web.error.ErrorAttributeOptions.Include;
|
||||
import org.springframework.boot.web.servlet.error.ErrorAttributes;
|
||||
import org.springframework.boot.web.servlet.error.ErrorController;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
|
||||
import jakarta.servlet.RequestDispatcher;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.Map;
|
||||
|
||||
@Controller
|
||||
public class ErrorPageController implements ErrorController {
|
||||
|
||||
@Autowired
|
||||
ErrorAttributes errorAttributes;
|
||||
|
||||
public final static String ERROR_PATH = "/error";
|
||||
|
||||
@GetMapping(value = ERROR_PATH)
|
||||
@PostMapping(value = ERROR_PATH)
|
||||
public String errorHtml(HttpServletRequest request) {
|
||||
HttpStatus status = getStatus(request);
|
||||
String prefix = "error/";
|
||||
|
||||
return prefix + "error_400";
|
||||
|
||||
// switch (status) {
|
||||
// case BAD_REQUEST:
|
||||
// return prefix + "error_400";
|
||||
// case NOT_FOUND:
|
||||
// return prefix + "error_404";
|
||||
// case METHOD_NOT_ALLOWED:
|
||||
// return prefix + "error_405";
|
||||
// default:
|
||||
// return prefix + "error_5xx";
|
||||
// }
|
||||
}
|
||||
|
||||
@GetMapping(value = ERROR_PATH, produces = "application/json")
|
||||
@PostMapping(value = ERROR_PATH, produces = "application/json")
|
||||
@ResponseBody
|
||||
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
|
||||
Map<String, Object> body = getErrorAttributes(request, getTraceParameter(request));
|
||||
HttpStatus status = getStatus(request);
|
||||
return new ResponseEntity<Map<String, Object>>(body, status);
|
||||
}
|
||||
|
||||
private boolean getTraceParameter(HttpServletRequest request) {
|
||||
String parameter = request.getParameter("trace");
|
||||
if (parameter == null) {
|
||||
return false;
|
||||
}
|
||||
return !"false".equals(parameter.toLowerCase());
|
||||
}
|
||||
|
||||
protected Map<String, Object> getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) {
|
||||
WebRequest webRequest = new ServletWebRequest(request);
|
||||
if (includeStackTrace) {
|
||||
return this.errorAttributes.getErrorAttributes(webRequest,
|
||||
ErrorAttributeOptions.defaults().including(Include.STACK_TRACE));
|
||||
}
|
||||
return this.errorAttributes.getErrorAttributes(webRequest, ErrorAttributeOptions.defaults());
|
||||
}
|
||||
|
||||
private HttpStatus getStatus(HttpServletRequest request) {
|
||||
Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
|
||||
if (statusCode != null) {
|
||||
try {
|
||||
return HttpStatus.valueOf(statusCode);
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
return HttpStatus.INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package quant.rich.emoney.controller.common;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.google.code.kaptcha.impl.DefaultKaptcha;
|
||||
|
||||
import quant.rich.emoney.service.AuthService;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/captcha")
|
||||
public class KaptchaController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
DefaultKaptcha kaptcha;
|
||||
|
||||
@GetMapping(value = "/get", produces = MediaType.IMAGE_JPEG_VALUE)
|
||||
public byte[] getCaptcha() throws Exception {
|
||||
String createText = kaptcha.createText();
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
session.setAttribute(AuthService.CAPTCHA, createText);
|
||||
ImageIO.write(kaptcha.createImage(createText), "jpg", os);
|
||||
byte[] result = os.toByteArray();
|
||||
os.close();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package quant.rich.emoney.controller.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import quant.rich.emoney.controller.common.BaseController;
|
||||
import quant.rich.emoney.entity.config.ChromeVersionsConfig;
|
||||
import quant.rich.emoney.entity.config.DeviceInfoConfig;
|
||||
import quant.rich.emoney.pojo.dto.R;
|
||||
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping("/admin/v1/config/emoneyRequest")
|
||||
public class EmoneyRequestConfigControllerV1 extends BaseController {
|
||||
|
||||
@Autowired
|
||||
DeviceInfoConfig deviceInfoConfig;
|
||||
|
||||
@Autowired
|
||||
ChromeVersionsConfig chromeVersionsConfig;
|
||||
|
||||
@GetMapping("/getRandomDeviceInfo")
|
||||
@ResponseBody
|
||||
public R<?> getRandomDeviceInfo() {
|
||||
return R.judgeNonNull(deviceInfoConfig.getRandomDeviceInfo());
|
||||
}
|
||||
|
||||
@GetMapping("/getRandomChromeVersion")
|
||||
@ResponseBody
|
||||
public R<?> getRandomChromeVersion() {
|
||||
return R.judgeNonNull(chromeVersionsConfig.getRandomChromeVersion());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package quant.rich.emoney.controller.manage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
import quant.rich.emoney.controller.common.BaseController;
|
||||
import quant.rich.emoney.entity.config.IndexInfoConfig;
|
||||
import quant.rich.emoney.pojo.dto.LayPageResp;
|
||||
import quant.rich.emoney.pojo.dto.R;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/admin/v1/manage/indexInfo")
|
||||
public class IndexInfoControllerV1 extends BaseController {
|
||||
|
||||
@Autowired
|
||||
IndexInfoConfig indexInfo;
|
||||
|
||||
@GetMapping({"", "/", "/index"})
|
||||
public String index() {
|
||||
return "/admin/v1/manage/indexInfo/index";
|
||||
}
|
||||
|
||||
@GetMapping("/configIndOnline")
|
||||
@ResponseBody
|
||||
public R<?> configIndOnline(String url) throws IOException {
|
||||
|
||||
//return R.judge(() -> indexInfo.getOnlineConfigByUrl(url));
|
||||
return R.ok(indexInfo.getConfigIndOnline());
|
||||
}
|
||||
|
||||
@GetMapping("/getFields")
|
||||
@ResponseBody
|
||||
public R<?> getFields(@RequestParam("fields") String[] fields) {
|
||||
if (fields == null || fields.length == 0) {
|
||||
return R.ok(indexInfo);
|
||||
}
|
||||
ObjectNode indexInfoJson = new ObjectMapper().valueToTree(indexInfo);
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
for (String field : fields) {
|
||||
map.put(field, indexInfoJson.get(field));
|
||||
}
|
||||
return R.ok(map);
|
||||
}
|
||||
|
||||
@GetMapping("/getIndexDetail")
|
||||
@ResponseBody
|
||||
public R<?> getIndexDetail(String code) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/getConfigIndOnlineByUrl")
|
||||
@ResponseBody
|
||||
public R<?> getConfigOnlineByUrl(String url) {
|
||||
return R.judge(() -> indexInfo.getOnlineConfigByUrl(url));
|
||||
}
|
||||
|
||||
@GetMapping("/getIndexInfoConfig")
|
||||
@ResponseBody
|
||||
public R<?> getIndexInfoConfig() {
|
||||
return R.ok(indexInfo);
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@ResponseBody
|
||||
public LayPageResp<?> list() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
package quant.rich.emoney.controller.manage;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import quant.rich.emoney.controller.common.BaseController;
|
||||
import quant.rich.emoney.entity.sqlite.Plan;
|
||||
import quant.rich.emoney.exception.RException;
|
||||
import quant.rich.emoney.pojo.dto.LayPageReq;
|
||||
import quant.rich.emoney.pojo.dto.LayPageResp;
|
||||
import quant.rich.emoney.pojo.dto.R;
|
||||
import quant.rich.emoney.service.sqlite.PlanService;
|
||||
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping("/admin/v1/manage/plan")
|
||||
public class PlanControllerV1 extends BaseController {
|
||||
|
||||
@Autowired
|
||||
PlanService planService;
|
||||
|
||||
@GetMapping({"", "/", "/index"})
|
||||
public String index() {
|
||||
return "/admin/v1/manage/plan/index";
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@ResponseBody
|
||||
public LayPageResp<?> list(LayPageReq<Plan> pageReq) {
|
||||
Page<Plan> planPage = planService.page(pageReq);
|
||||
return new LayPageResp<>(planPage);
|
||||
}
|
||||
|
||||
@GetMapping("/getOne")
|
||||
@ResponseBody
|
||||
public R<?> getOne(String planId) {
|
||||
|
||||
// 如果 planId 是空,说明可能希望新建一个 Plan,需要返回默认实例化对象
|
||||
if (planId == null) {
|
||||
return R.ok(new Plan());
|
||||
}
|
||||
|
||||
// 否则从数据库取
|
||||
Plan plan = planService.getById(planId);
|
||||
return R.judge(plan != null, plan, "无法找到对应 ID 的 Plan");
|
||||
}
|
||||
|
||||
@PostMapping("/updateEnabledStatus")
|
||||
@ResponseBody
|
||||
public R<?> updateEnabledStatus(String planId, Boolean enabled) {
|
||||
if (planService.update(new LambdaUpdateWrapper<Plan>()
|
||||
.eq(Plan::getPlanId, planId)
|
||||
.set(Plan::getEnabled, enabled))) {
|
||||
return R.ok();
|
||||
}
|
||||
throw RException.badRequest();
|
||||
}
|
||||
|
||||
@PostMapping("/updateBool")
|
||||
@ResponseBody
|
||||
public R<?> updateBool(String planId, String field, Boolean value) {
|
||||
TableInfo tableInfo = TableInfoHelper.getTableInfo(Plan.class);
|
||||
try {
|
||||
Field declaredField = Plan.class.getDeclaredField(field);
|
||||
|
||||
Optional<TableFieldInfo> fieldInfo = tableInfo.getFieldList().stream()
|
||||
.filter(f -> f.getProperty().equals(field))
|
||||
.findFirst();
|
||||
if (declaredField.getType().equals(Boolean.class)) {
|
||||
planService.update(
|
||||
new UpdateWrapper<Plan>()
|
||||
.eq("plan_id", planId)
|
||||
.set(fieldInfo.get().getColumn(), value));
|
||||
return R.ok();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {}
|
||||
throw RException.badRequest();
|
||||
}
|
||||
|
||||
@PostMapping("/save")
|
||||
@ResponseBody
|
||||
public R<?> save(@RequestBody Plan plan) {
|
||||
if (StringUtils.isNotBlank(plan.getPlanId())) {
|
||||
planService.updateById(plan);
|
||||
}
|
||||
else {
|
||||
planService.save(plan.setPlanId(null));
|
||||
}
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
@ResponseBody
|
||||
public R<?> delete(String planId) {
|
||||
return R.judge(planService.removeById(planId), "删除失败,是否已删除?");
|
||||
}
|
||||
|
||||
@PostMapping("/batchOp")
|
||||
@ResponseBody
|
||||
public R<?> batchOp(
|
||||
@RequestParam(value="ids[]", required=true)
|
||||
String[] ids, String op) {
|
||||
if (Objects.isNull(ids) || ids.length == 0) {
|
||||
throw RException.badRequest("提供的计划 ID 不能为空");
|
||||
}
|
||||
List<String> idArray = Arrays.asList(ids);
|
||||
|
||||
if (StringUtils.isBlank(op)) {
|
||||
// op 为空是删除
|
||||
return R.judge(
|
||||
planService.removeBatchByIds(idArray));
|
||||
}
|
||||
|
||||
LambdaUpdateWrapper<Plan> uw = new LambdaUpdateWrapper<>();
|
||||
uw.in(Plan::getPlanId, idArray);
|
||||
|
||||
if ("enable".equals(op)) {
|
||||
uw.set(Plan::getEnabled, true);
|
||||
}
|
||||
else if ("disable".equals(op)) {
|
||||
uw.set(Plan::getEnabled, false);
|
||||
}
|
||||
else if ("enableOpenDayCheck".equals(op)) {
|
||||
uw.set(Plan::getOpenDayCheck, true);
|
||||
}
|
||||
else if ("disableOpenDayCheck".equals(op)) {
|
||||
uw.set(Plan::getOpenDayCheck, false);
|
||||
}
|
||||
else {
|
||||
throw RException.badRequest("未识别的操作");
|
||||
}
|
||||
|
||||
return R.judge(planService.update(uw));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package quant.rich.emoney.controller.manage;
|
||||
|
||||
import java.util.Objects;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import quant.rich.emoney.controller.common.BaseController;
|
||||
import quant.rich.emoney.entity.sqlite.Plan;
|
||||
import quant.rich.emoney.entity.sqlite.ProtocolMatch;
|
||||
import quant.rich.emoney.exception.RException;
|
||||
import quant.rich.emoney.pojo.dto.LayPageReq;
|
||||
import quant.rich.emoney.pojo.dto.LayPageResp;
|
||||
import quant.rich.emoney.pojo.dto.R;
|
||||
import quant.rich.emoney.service.sqlite.ProtocolMatchService;
|
||||
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping("/admin/v1/manage/protocolMatch")
|
||||
public class ProtocolMatchControllerV1 extends BaseController {
|
||||
|
||||
@Autowired
|
||||
ProtocolMatchService protocolMatchService;
|
||||
|
||||
@GetMapping({"", "/", "/index"})
|
||||
public String index() {
|
||||
return "/admin/v1/manage/protocolMatch/index";
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@ResponseBody
|
||||
public LayPageResp<?> list(LayPageReq<ProtocolMatch> pageReq) {
|
||||
Page<ProtocolMatch> planPage = protocolMatchService.page(pageReq);
|
||||
return new LayPageResp<>(planPage);
|
||||
}
|
||||
|
||||
@GetMapping("/getOne")
|
||||
@ResponseBody
|
||||
public R<?> getOne(Integer protocolId) {
|
||||
|
||||
// 如果 planId 是空,说明可能希望新建一个 Plan,需要返回默认实例化对象
|
||||
if (protocolId == null) {
|
||||
return R.ok(new ProtocolMatch());
|
||||
}
|
||||
|
||||
// 否则从数据库取
|
||||
ProtocolMatch protocolMatch = protocolMatchService.getById(protocolId);
|
||||
return R.judge(protocolMatch != null, protocolMatch, "无法找到对应 ID 的 ProtocolMatch");
|
||||
}
|
||||
|
||||
@PostMapping("/save")
|
||||
@ResponseBody
|
||||
public R<?> save(@RequestBody ProtocolMatch protocolMatch) {
|
||||
if (Objects.nonNull(protocolMatch.getProtocolId())) {
|
||||
return R.judge(
|
||||
protocolMatchService.saveOrUpdate(protocolMatch), "保存失败");
|
||||
}
|
||||
throw RException.badRequest("protocolId 不允许为空");
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
@ResponseBody
|
||||
public R<?> delete(Integer protocolMatchId) {
|
||||
return R.judge(protocolMatchService.removeById(protocolMatchId), "删除失败,是否已删除?");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user