This commit is contained in:
ageer
2024-01-16 12:38:04 +08:00
parent c36313513b
commit 1f7f97e86a
702 changed files with 59052 additions and 2 deletions

View File

@@ -0,0 +1,159 @@
package com.xmzs.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.collection.CollUtil;
import com.xmzs.common.core.constant.Constants;
import com.xmzs.common.core.domain.R;
import com.xmzs.common.core.domain.model.*;
import com.xmzs.common.core.utils.MapstructUtils;
import com.xmzs.common.core.utils.StreamUtils;
import com.xmzs.common.core.utils.StringUtils;
import com.xmzs.common.satoken.utils.LoginHelper;
import com.xmzs.common.tenant.helper.TenantHelper;
import com.xmzs.system.domain.bo.SysTenantBo;
import com.xmzs.system.domain.vo.LoginTenantVo;
import com.xmzs.system.domain.vo.SysTenantVo;
import com.xmzs.system.domain.vo.TenantListVo;
import com.xmzs.system.service.ISysTenantService;
import com.xmzs.system.service.SysLoginService;
import com.xmzs.system.service.SysRegisterService;
import com.xmzs.web.domain.vo.LoginVo;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.net.URL;
import java.util.List;
/**
* 认证
*
* @author Lion Li
*/
@SaIgnore
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/auth")
public class AuthController {
private final SysLoginService loginService;
private final SysRegisterService registerService;
private final ISysTenantService tenantService;
/**
* 登录方法
*
* @param body 登录信息
* @return 结果
*/
@PostMapping("/login")
public R<LoginVo> login(@Validated @RequestBody LoginBody body) {
body.setTenantId(Constants.TENANT_ID);
LoginVo loginVo = new LoginVo();
// 生成令牌
String token = loginService.login(
body.getTenantId(),
body.getUsername(), body.getPassword(),
body.getCode(), body.getUuid());
loginVo.setToken(token);
loginVo.setUserInfo(LoginHelper.getLoginUser());
return R.ok(loginVo);
}
/**
* 短信登录
*
* @param body 登录信息
* @return 结果
*/
@PostMapping("/smsLogin")
public R<LoginVo> smsLogin(@Validated @RequestBody SmsLoginBody body) {
LoginVo loginVo = new LoginVo();
// 生成令牌
String token = loginService.smsLogin(body.getTenantId(), body.getPhonenumber(), body.getSmsCode());
loginVo.setToken(token);
return R.ok(loginVo);
}
/**
* 邮件登录
*
* @param body 登录信息
* @return 结果
*/
@PostMapping("/emailLogin")
public R<LoginVo> emailLogin(@Validated @RequestBody EmailLoginBody body) {
LoginVo loginVo = new LoginVo();
// 生成令牌
String token = loginService.emailLogin(body.getTenantId(), body.getEmail(), body.getEmailCode());
loginVo.setToken(token);
return R.ok(loginVo);
}
/**
* 游客登录
*
* @param loginBody
* @return 结果
*/
@PostMapping("/visitorLogin")
public R<LoginVo> xcxLogin(@RequestBody VisitorLoginBody loginBody) {
return R.ok(loginService.visitorLogin(loginBody));
}
/**
* 退出登录
*/
@PostMapping("/logout")
public R<Void> logout() {
loginService.logout();
return R.ok("退出成功");
}
/**
* 用户注册
*/
@PostMapping("/register")
public R<Void> register(@Validated @RequestBody RegisterBody user) {
registerService.register(user);
return R.ok();
}
/**
* 重置密码
*/
@PostMapping("/reset/password")
@SaIgnore
public R<Void> resetPassWord(@Validated @RequestBody RegisterBody user) {
registerService.resetPassWord(user);
return R.ok();
}
/**
* 登录页面租户下拉框
*
* @return 租户列表
*/
@GetMapping("/tenant/list")
public R<LoginTenantVo> tenantList(HttpServletRequest request) throws Exception {
List<SysTenantVo> tenantList = tenantService.queryList(new SysTenantBo());
List<TenantListVo> voList = MapstructUtils.convert(tenantList, TenantListVo.class);
// 获取域名
String host = new URL(request.getRequestURL().toString()).getHost();
// 根据域名进行筛选
List<TenantListVo> list = StreamUtils.filter(voList, vo -> StringUtils.equals(vo.getDomain(), host));
// 返回对象
LoginTenantVo vo = new LoginTenantVo();
vo.setVoList(CollUtil.isNotEmpty(list) ? list : voList);
vo.setTenantEnabled(TenantHelper.isEnable());
return R.ok(vo);
}
}

View File

@@ -0,0 +1,139 @@
package com.xmzs.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.xmzs.common.core.constant.Constants;
import com.xmzs.common.core.constant.GlobalConstants;
import com.xmzs.common.core.domain.R;
import com.xmzs.common.core.utils.SpringUtils;
import com.xmzs.common.core.utils.StringUtils;
import com.xmzs.common.core.utils.reflect.ReflectUtils;
import com.xmzs.common.mail.config.properties.MailProperties;
import com.xmzs.common.mail.utils.MailUtils;
import com.xmzs.common.redis.utils.RedisUtils;
import com.xmzs.common.sms.config.properties.SmsProperties;
import com.xmzs.common.sms.core.SmsTemplate;
import com.xmzs.common.sms.entity.SmsResult;
import com.xmzs.common.web.config.properties.CaptchaProperties;
import com.xmzs.common.web.enums.CaptchaType;
import com.xmzs.web.domain.request.EmailRequest;
import com.xmzs.web.domain.vo.CaptchaVo;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.validation.annotation.Validated;
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.RestController;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
/**
* 验证码操作处理
*
* @author Lion Li
*/
@SaIgnore
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
public class CaptchaController {
private final CaptchaProperties captchaProperties;
private final SmsProperties smsProperties;
private final MailProperties mailProperties;
/**
* 短信验证码
*
* @param phonenumber 用户手机号
*/
@GetMapping("/resource/sms/code")
public R<Void> smsCode(@NotBlank(message = "{user.phonenumber.not.blank}") String phonenumber) {
if (!smsProperties.getEnabled()) {
return R.fail("当前系统没有开启短信功能!");
}
String key = GlobalConstants.CAPTCHA_CODE_KEY + phonenumber;
String code = RandomUtil.randomNumbers(4);
RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
// 验证码模板id 自行处理 (查数据库或写死均可)
String templateId = "";
Map<String, String> map = new HashMap<>(1);
map.put("code", code);
SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class);
SmsResult result = smsTemplate.send(phonenumber, templateId, map);
if (!result.isSuccess()) {
log.error("验证码短信发送异常 => {}", result);
return R.fail(result.getMessage());
}
return R.ok();
}
/**
* 邮箱验证码
*
* @param emailRequest 用户邮箱
*/
@PostMapping("/resource/email/code")
public R<Void> emailCode(@RequestBody @Valid EmailRequest emailRequest) {
if (!mailProperties.getEnabled()) {
return R.fail("当前系统没有开启邮箱功能!");
}
String key = GlobalConstants.CAPTCHA_CODE_KEY + emailRequest.getUsername();
String code = RandomUtil.randomNumbers(4);
RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
try {
MailUtils.sendText(emailRequest.getUsername(), "【GPT助手】登录验证码", "您本次验证码为:" + code + ",有效性为" + Constants.CAPTCHA_EXPIRATION + "分钟,请尽快填写。");
} catch (Exception e) {
log.error("验证码短信发送异常 => {}", e.getMessage());
return R.fail(e.getMessage());
}
return R.ok();
}
/**
* 生成验证码
*/
@GetMapping("/code")
public R<CaptchaVo> getCode() {
CaptchaVo captchaVo = new CaptchaVo();
boolean captchaEnabled = captchaProperties.getEnable();
if (!captchaEnabled) {
captchaVo.setCaptchaEnabled(false);
return R.ok(captchaVo);
}
// 保存验证码信息
String uuid = IdUtil.simpleUUID();
String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + uuid;
// 生成验证码
CaptchaType captchaType = captchaProperties.getType();
boolean isMath = CaptchaType.MATH == captchaType;
Integer length = isMath ? captchaProperties.getNumberLength() : captchaProperties.getCharLength();
CodeGenerator codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), length);
AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz());
captcha.setGenerator(codeGenerator);
captcha.createCode();
String code = captcha.getCode();
if (isMath) {
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(StringUtils.remove(code, "="));
code = exp.getValue(String.class);
}
RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
captchaVo.setUuid(uuid);
captchaVo.setImg(captcha.getImageBase64());
return R.ok(captchaVo);
}
}

View File

@@ -0,0 +1,91 @@
package com.xmzs.controller;
import com.xmzs.common.chat.domain.request.ChatRequest;
import com.xmzs.common.chat.domain.request.Dall3Request;
import com.xmzs.common.chat.entity.images.Item;
import com.xmzs.common.core.domain.R;
import com.xmzs.common.core.domain.model.LoginUser;
import com.xmzs.common.core.exception.base.BaseException;
import com.xmzs.common.mybatis.core.page.PageQuery;
import com.xmzs.common.mybatis.core.page.TableDataInfo;
import com.xmzs.common.satoken.utils.LoginHelper;
import com.xmzs.system.domain.bo.ChatMessageBo;
import com.xmzs.system.domain.vo.ChatMessageVo;
import com.xmzs.system.service.IChatMessageService;
import com.xmzs.system.service.SseService;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.util.List;
/**
* 描述:
*
* @author https:www.unfbx.com
* @date 2023-03-01
*/
@Controller
@Slf4j
@RequiredArgsConstructor
public class ChatController {
private final SseService sseService;
private final IChatMessageService chatMessageService;
/**
* 聊天接口
*/
@PostMapping("/chat")
@ResponseBody
public SseEmitter sseChat(@RequestBody @Valid ChatRequest chatRequest) {
if("gpt-4-all".equals(chatRequest.getModel())
|| chatRequest.getModel().startsWith("gpt-4-gizmo")
|| chatRequest.getModel().startsWith("net-")
){
return sseService.transitChat(chatRequest);
}
if("azure-gpt-3.5".equals(chatRequest.getModel())){
return sseService.azureChat(chatRequest);
}
return sseService.sseChat(chatRequest);
}
@PostMapping("/dall3")
@ResponseBody
public R<List<Item>> dall3(@RequestBody @Valid Dall3Request request) {
return R.ok(sseService.dall3(request));
}
@PostMapping("/mjTask")
@ResponseBody
public R<String> mjTask() {
sseService.mjTask();
return R.ok();
}
/**
* 聊天记录
*/
@PostMapping("/chatList")
@ResponseBody
public R<TableDataInfo<ChatMessageVo>> list(@RequestBody @Valid ChatMessageBo chatRequest,@RequestBody PageQuery pageQuery) {
// 默认查询当前登录用户消息记录
LoginUser loginUser = LoginHelper.getLoginUser();
if (loginUser == null) {
throw new BaseException("用户未登录!");
}
chatRequest.setUserId(loginUser.getUserId());
TableDataInfo<ChatMessageVo> chatMessageVoTableDataInfo = chatMessageService.queryPageList(chatRequest, pageQuery);
return R.ok(chatMessageVoTableDataInfo);
}
}

View File

@@ -0,0 +1,26 @@
package com.xmzs.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
/**
* 首页
*
* @author Lion Li
*/
@SaIgnore
@RequiredArgsConstructor
@Controller
public class IndexController {
/**
* 访问首页,提示语
*/
@GetMapping("/")
public String index() {
return "index.html";
}
}

View File

@@ -0,0 +1,151 @@
package com.xmzs.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import com.xmzs.common.config.PayConfig;
import com.xmzs.common.core.domain.R;
import com.xmzs.common.core.domain.model.LoginUser;
import com.xmzs.common.core.exception.base.BaseException;
import com.xmzs.common.core.utils.StringUtils;
import com.xmzs.common.oss.core.OssClient;
import com.xmzs.common.oss.entity.UploadResult;
import com.xmzs.common.oss.factory.OssFactory;
import com.xmzs.common.response.PayResponse;
import com.xmzs.common.satoken.utils.LoginHelper;
import com.xmzs.common.service.PayService;
import com.xmzs.common.utils.MD5Util;
import com.xmzs.system.domain.bo.PaymentOrdersBo;
import com.xmzs.system.domain.bo.SysUserBo;
import com.xmzs.system.domain.request.OrderRequest;
import com.xmzs.system.domain.vo.PaymentOrdersVo;
import com.xmzs.system.domain.vo.SysUserVo;
import com.xmzs.system.service.IPaymentOrdersService;
import com.xmzs.system.service.ISysUserService;
import com.xmzs.system.util.OrderNumberGenerator;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.List;
@RequiredArgsConstructor
@RestController
@RequestMapping("/pay")
@Slf4j
public class PayController {
private final PayService payService;
private final ISysUserService userService;
private final IPaymentOrdersService paymentOrdersService;
/**
* 获取支付二维码
*
* @Date 2023/7/3
* @param response
* @return void
**/
@PostMapping("/payUrl")
public R<PaymentOrdersVo> payUrl(HttpServletResponse response, @RequestBody OrderRequest orderRequest) {
LoginUser loginUser = LoginHelper.getLoginUser();
// 创建订单
PaymentOrdersBo paymentOrders = new PaymentOrdersBo();
paymentOrders.setOrderName(orderRequest.getName());
paymentOrders.setAmount(new BigDecimal(orderRequest.getMoney()));
String orderNo = OrderNumberGenerator.generate();
paymentOrders.setOrderNo(orderNo);
paymentOrders.setUserId(loginUser.getUserId());
// TODO 支付状态默认待支付 - 添加枚举
paymentOrders.setPaymentStatus("1");
paymentOrdersService.insertByBo(paymentOrders);
String payUrl = payService.getPayUrl(orderNo, orderRequest.getName(), Double.parseDouble(orderRequest.getMoney()), "192.168.1.6");
byte[] bytes = QrCodeUtil.generatePng(payUrl, 300, 300);
OssClient storage = OssFactory.instance();
UploadResult upload=storage.upload(bytes, storage.getPath("qrCode",".png"), "image/png");
PaymentOrdersVo paymentOrdersVo = new PaymentOrdersVo();
BeanUtil.copyProperties(paymentOrders,paymentOrdersVo);
paymentOrdersVo.setUrl(upload.getUrl());
return R.ok(paymentOrdersVo);
}
/**
* 跳转通知地址
*
* @Date 2023/7/3
* @param
* @return void
**/
@PostMapping("/notifyUrl")
public void notifyUrl() {
log.info("notifyUrl===========");
}
/**
* 获取订单信息
*
*/
@PostMapping("/orderInfo")
public R<PaymentOrdersVo> orderInfo(@RequestBody OrderRequest orderRequest) {
if(StringUtils.isEmpty(orderRequest.getOrderNo())){
throw new BaseException("订单号不能为空!");
}
PaymentOrdersBo paymentOrdersBo = new PaymentOrdersBo();
paymentOrdersBo.setOrderNo(orderRequest.getOrderNo());
List<PaymentOrdersVo> paymentOrdersList = paymentOrdersService.queryList(paymentOrdersBo);
if (CollectionUtil.isEmpty(paymentOrdersList)){
throw new BaseException("订单不存在!");
}
PaymentOrdersVo paymentOrdersVo = paymentOrdersList.get(0);
return R.ok(paymentOrdersVo);
}
/**
* 跳转通知地址
*
* @Date 2023/7/3
* @param payResponse
* @return void
**/
@GetMapping("/returnUrl")
public String returnUrl(PayResponse payResponse) {
// 校验签名
String mdString = "money=" + payResponse.getMoney() + "&name=" + payResponse.getName() +
"&out_trade_no=" + payResponse.getOut_trade_no() + "&pid=" + PayConfig.pid +
"&trade_no=" + payResponse.getTrade_no() + "&trade_status=" + payResponse.getTrade_status() +
"&type=" + payResponse.getType() + PayConfig.key;
String sign = MD5Util.GetMD5Code(mdString);
if(!sign.equals(payResponse.getSign())){
throw new BaseException("校验签名失败!");
}
double money = Double.parseDouble(payResponse.getMoney());
log.info("支付订单号{}",payResponse);
PaymentOrdersBo paymentOrdersBo = new PaymentOrdersBo();
paymentOrdersBo.setOrderNo(payResponse.getOut_trade_no());
List<PaymentOrdersVo> paymentOrdersList = paymentOrdersService.queryList(paymentOrdersBo);
if (CollectionUtil.isEmpty(paymentOrdersList)){
throw new BaseException("订单不存在!");
}
// 订单状态修改为已支付
PaymentOrdersVo paymentOrdersVo = paymentOrdersList.get(0);
paymentOrdersVo.setPaymentStatus("2");
paymentOrdersVo.setPaymentMethod(payResponse.getType());
BeanUtil.copyProperties(paymentOrdersVo,paymentOrdersBo);
paymentOrdersService.updateByBo(paymentOrdersBo);
SysUserVo sysUserVo = userService.selectUserById(paymentOrdersVo.getUserId());
sysUserVo.setUserBalance(sysUserVo.getUserBalance()+money);
SysUserBo sysUserBo = new SysUserBo();
BeanUtil.copyProperties(sysUserVo,sysUserBo);
// 设置为付费用户
sysUserBo.setUserGrade("1");
userService.updateUser(sysUserBo);
return "success";
}
}