校快送 2024.11.19 v0.0.4

This commit is contained in:
tsukiyalo 2024-11-19 18:59:49 +08:00
parent 32e7432ba1
commit 65420d9f9e
40 changed files with 1695 additions and 110 deletions

View File

@ -106,7 +106,11 @@
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.3</version>
</dependency>
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
@ -130,14 +134,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.6.4</version>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>

View File

@ -239,9 +239,20 @@ create table if not exists systemInfo
-- 聊天记录表
create table private_message
(
id bigint auto_increment primary key,
from_userAccount varchar(255) not null comment '发消息者',
to_userAccount varchar(255) not null comment '接收消息者',
orderId BIGINT null comment '订单id',
message varchar(255) null comment '消息内容'
)comment '聊天记录' collate = utf8mb4_unicode_ci;
id bigint auto_increment comment 'id' primary key,
from_userAccount varchar(255) not null comment '发消息者',
to_userAccount varchar(255) not null comment '接收消息者',
orderId bigint null comment '订单id',
message varchar(255) null comment '消息内容',
from_user_deleted tinyint default false comment '发消息者是否删除',
to_user_deleted tinyint default false comment '接收消息者是否删除'
)
comment '聊天记录' collate = utf8mb4_unicode_ci;
# 收藏表
create table collect
(
id bigint auto_increment comment 'id' primary key ,
userId bigint not null comment '用户id',
businessId bigint not null comment '商家id'
)

View File

@ -0,0 +1,16 @@
package com.bsz.school_send_back_end.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
@Configuration
public class RedisSessionRepositoryConfig {
@Bean("springSessionRedisSerializer")
public RedisSerializer<Object> getRedisSerializer()
{
return new GenericJackson2JsonRedisSerializer();
}
}

View File

@ -0,0 +1,31 @@
package com.bsz.school_send_back_end.config;
import com.bsz.school_send_back_end.contant.WebsocketConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@Slf4j
@EnableWebSocketMessageBroker
public class WebsocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint(WebsocketConstant.ENDPOINT).setAllowedOriginPatterns(WebsocketConstant.ALLOWED_ORIGINS).withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
//基于内存的消息代理
registry.enableSimpleBroker(WebsocketConstant.SIMPLE_BROKER);
registry.setApplicationDestinationPrefixes(WebsocketConstant.DESTINATION_PREFIXES);
}
}

View File

@ -0,0 +1,16 @@
package com.bsz.school_send_back_end.contant;
public interface RedisKeyConstant {
// IP sessionId key 前缀
String USER_EXTRA_INFO = "user:extra:";
// Spring Session session 信息的后缀sessionId 前面
String SESSION_KEY_POSTFIX = "sessions";
// session 中保存的属性的前缀
String SESSION_ATTRIBUTE_PREFIX = "sessionAttr";
/**
* 用户登录态键
*/
String USER_LOGIN_STATE = "xiaokuaisong_user";
String IP = "ip";
String SESSION_ID = "sessionId";
}

View File

@ -0,0 +1,10 @@
package com.bsz.school_send_back_end.contant;
public interface WebsocketConstant {
//websocket
public static final String ENDPOINT = "/ws/xiaokuaisong";
public static final String ALLOWED_ORIGINS = "*";
public static final String SIMPLE_BROKER = "/topic";
public static final String DESTINATION_PREFIXES = "/ClientToServer";
}

View File

@ -19,8 +19,10 @@ import com.bsz.school_send_back_end.config.AlipayClients;
import com.bsz.school_send_back_end.contant.RedisKeyConstant;
import com.bsz.school_send_back_end.mapper.UserMapper;
import com.bsz.school_send_back_end.model.domain.User;
import com.bsz.school_send_back_end.model.vo.UserVO;
import com.bsz.school_send_back_end.utils.RandomNumberGenerator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@ -64,7 +66,7 @@ public class AlipayController {
* @throws AlipayApiException 支付宝api异常
*/
@GetMapping("/parseCode")
public BaseResponse<User> login(String authcode, HttpServletRequest req) throws AlipayApiException {
public BaseResponse<UserVO> login(String authcode, HttpServletRequest req) throws AlipayApiException {
String privateKey = appPrivateKey;
String alipayPublicKey = PublicKey;
AlipayConfig alipayConfig = new AlipayConfig();
@ -92,23 +94,30 @@ public class AlipayController {
AlipayUserInfoShareResponse response1 = alipayClient.execute(request1, authToken);
User oid = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getOpenId, response.getOpenId()));
UserVO userVO = new UserVO();
if (response1.isSuccess()) {
if (oid == null) {
User user = new User();
user.setOpenId(response.getOpenId());
user.setUsername(StringUtils.isAnyBlank(response1.getNickName()) ? "随机名字" + randomNumberGenerator.generateRandomNumber() : response1.getNickName());
user.setUserPassword("123456");
user.setUserAccount("用户" + randomNumberGenerator.generateRandomNumber());
user.setAvatarUrl(StringUtils.isAnyBlank(response1.getAvatar()) ? "https://tfs.alipayobjects.com/images/partner/ATuihpR50zu7UAAAAAAAAAAAAADtl2AA" : response1.getAvatar());
userMapper.insert(user);
req.getSession().setAttribute(RedisKeyConstant.USER_LOGIN_STATE,user);
return ResultUtils.success(user,"注册成功");
BeanUtils.copyProperties(user, userVO);
userVO.setSessionId(req.getSession().getId());
return ResultUtils.success(userVO,"注册成功");
}
req.getSession().setAttribute(RedisKeyConstant.USER_LOGIN_STATE,oid);
return ResultUtils.success(oid,"登录成功");
req.getSession().setAttribute(RedisKeyConstant.USER_LOGIN_STATE, oid);
BeanUtils.copyProperties(oid, userVO);
userVO.setSessionId(req.getSession().getId());
return ResultUtils.success(userVO,"登录成功");
}
req.getSession().setAttribute(RedisKeyConstant.USER_LOGIN_STATE,oid);
return ResultUtils.success(oid,"登录成功");
BeanUtils.copyProperties(oid, userVO);
userVO.setSessionId(req.getSession().getId());
return ResultUtils.success(userVO,"登录成功");
}
// @GetMapping("/login")
@ -218,7 +227,7 @@ public class AlipayController {
model.setOpAppId("2021004151684053");
///回调地址
request.setNotifyUrl("http://39.101.78.35:6271/Alipay/notifyUrl");
request.setNotifyUrl("http://39.101.78.35:6271/api/Alipay/notifyUrl");
request.setBizModel(model);
String tradeNo = "";
try {
@ -267,7 +276,7 @@ public class AlipayController {
request.setNotifyUrl(NOURL);
AlipayTradeRefundResponse response = clients.alipayClient().execute(request);
return "";
return response.getBody();
}
@GetMapping("/test/query")

View File

@ -152,7 +152,7 @@ public class BusinessController {
*/
@GetMapping("/getById")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<BusinessAdminVO> getBusinessById(long id) {
public BaseResponse<BusinessAdminVO> getBusinessById(@RequestParam Long id) {
if (id <= 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}

View File

@ -0,0 +1,95 @@
package com.bsz.school_send_back_end.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bsz.school_send_back_end.common.BaseResponse;
import com.bsz.school_send_back_end.common.ErrorCode;
import com.bsz.school_send_back_end.common.ResultUtils;
import com.bsz.school_send_back_end.exception.BusinessException;
import com.bsz.school_send_back_end.exception.ThrowUtils;
import com.bsz.school_send_back_end.model.domain.Collect;
import com.bsz.school_send_back_end.model.domain.User;
import com.bsz.school_send_back_end.model.dto.CommonRequest;
import com.bsz.school_send_back_end.model.dto.collect.CollectAddRequest;
import com.bsz.school_send_back_end.service.CollectService;
import com.bsz.school_send_back_end.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
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 javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@RestController
@Slf4j
@RequestMapping("/collect")
public class CollectController {
@Resource
private CollectService collectService;
@Resource
private UserService userService;
/**
* 添加收藏
*/
@PostMapping("/add")
public BaseResponse<Boolean> addCollect(@RequestBody CollectAddRequest collectAddRequest, HttpServletRequest request) {
if (collectAddRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
collectService.validCollect(collectAddRequest);
Collect collect = new Collect();
BeanUtils.copyProperties(collectAddRequest, collect);
Boolean result = collectService.addCollect(collect, request);
ThrowUtils.throwIf(!result, ErrorCode.SYSTEM_ERROR);
return ResultUtils.success(true);
}
/**
* 删除一条收藏
*/
@PostMapping("/delete")
public BaseResponse<Boolean> deleteCollect(@RequestBody CommonRequest commonRequest) {
if (commonRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long id = commonRequest.getId();
LambdaQueryWrapper<Collect> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Collect::getId, id);
boolean remove = collectService.remove(wrapper);
ThrowUtils.throwIf(!remove, ErrorCode.SYSTEM_ERROR);
return ResultUtils.success(true);
}
/**
* 删除所有收藏
*/
@PostMapping("/delete/all")
public BaseResponse<Boolean> deleteCollectAll(HttpServletRequest request) {
User loginUser = userService.getLoginUser(request);
Long loginUserId = loginUser.getId();
LambdaQueryWrapper<Collect> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Collect::getUserId, loginUserId);
boolean remove = collectService.remove(wrapper);
ThrowUtils.throwIf(!remove, ErrorCode.SYSTEM_ERROR);
return ResultUtils.success(true);
}
/**
* 查询所有收藏
*/
@PostMapping("/list")
public BaseResponse<List<Collect>> listCollect(HttpServletRequest request) {
User loginUser = userService.getLoginUser(request);
Long loginUserId = loginUser.getId();
LambdaQueryWrapper<Collect> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Collect::getUserId, loginUserId);
List<Collect> list = collectService.list(wrapper);
return ResultUtils.success(list);
}
}

View File

@ -32,7 +32,7 @@ public class FileController {
@Resource
private UserService userService;
@PostMapping("/upload/server/not_login")
public BaseResponse<String> uploadServerNotLogin (@RequestPart("file")MultipartFile multipartFile, @RequestBody UploadFileRequest uploadFileRequest) {
public BaseResponse<String> uploadServerNotLogin (@RequestPart("file")MultipartFile multipartFile, UploadFileRequest uploadFileRequest) {
//获取业务名称
String biz = uploadFileRequest.getBiz();
FileUploadBizEnum fileUploadBizEnum = FileUploadBizEnum.getEnumByValue(biz);
@ -67,7 +67,7 @@ public class FileController {
}
@PostMapping("/upload/server")
public BaseResponse<String> uploadServerFile(@RequestPart("file") MultipartFile multipartFile, @RequestBody UploadFileRequest uploadFileRequest, HttpServletRequest request) {
public BaseResponse<String> uploadServerFile(@RequestPart("file") MultipartFile multipartFile, UploadFileRequest uploadFileRequest, HttpServletRequest request) {
// 获取业务名称
String biz = uploadFileRequest.getBiz();
FileUploadBizEnum fileUploadBizEnum = FileUploadBizEnum.getEnumByValue(biz);
@ -125,23 +125,4 @@ public class FileController {
}
}
}

View File

@ -1,6 +1,7 @@
package com.bsz.school_send_back_end.controller;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsz.school_send_back_end.annotation.AuthCheck;
@ -14,8 +15,10 @@ import com.bsz.school_send_back_end.exception.ThrowUtils;
import com.bsz.school_send_back_end.model.domain.*;
import com.bsz.school_send_back_end.model.dto.CommonRequest;
import com.bsz.school_send_back_end.model.dto.order.*;
import com.bsz.school_send_back_end.model.vo.OrdersExcelVO;
import com.bsz.school_send_back_end.model.vo.OrdersVO;
import com.bsz.school_send_back_end.service.*;
import com.bsz.school_send_back_end.utils.ExcelUtils;
import com.bsz.school_send_back_end.utils.SqlUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
@ -126,7 +129,7 @@ public class OrdersController {
*/
@GetMapping("/get")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<OrdersVO> getOrderVOById(long id) {
public BaseResponse<OrdersVO> getOrderVOById(@RequestParam Long id) {
if (id <= 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
@ -302,6 +305,44 @@ public class OrdersController {
return getStringBaseResponse(type, startTime, endTime, queryWrapper);
}
@PostMapping("/download")
public void download(@RequestBody OrderQueryRequest orderQueryRequest, HttpServletResponse response) throws IOException {
String startTime = orderQueryRequest.getStartTime();
String endTime = orderQueryRequest.getEndTime();
Long businessId = orderQueryRequest.getBusinessId();
String sortOrder = orderQueryRequest.getSortOrder();
String sortField = orderQueryRequest.getSortField();
// 获取数据
QueryWrapper<Orders> wrapper = new QueryWrapper<>();
wrapper.ge(StringUtils.isNotBlank(startTime), "createTime", startTime);
wrapper.le(StringUtils.isNotBlank(endTime), "createTime", endTime);
wrapper.eq("businessId", businessId).and(item -> item.eq("state", 1).or().eq("state", 2));
wrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
sortField);
List<Orders> ordersList = ordersService.list(wrapper);
List<OrdersExcelVO> ordersExcelVOList = ordersList.stream().map(item -> {
OrdersExcelVO ordersExcelVO = new OrdersExcelVO();
BeanUtils.copyProperties(item, ordersExcelVO);
//改变订单支付状态
if (item.getState() == 1) {
ordersExcelVO.setState("已完成");
} else if (item.getState() == 2) {
ordersExcelVO.setState("已退款");
}
// Date转字符串
ordersExcelVO.setCreateTime(ExcelUtils.dateToString(item.getCreateTime()));
return ordersExcelVO;
}).collect(Collectors.toList());
// 设置导出名称
ExcelUtils.setExcelResponseProp(response, "订单信息");
// 获取输出流名称
OutputStream outputStream = response.getOutputStream();
// 这里 需要指定写用哪个class去写然后写到第一个sheet名字为模板 然后文件流会自动关闭
EasyExcel.write(outputStream, OrdersExcelVO.class) // 对应实体类
.sheet("订单数据") // sheet页名称
.doWrite(ordersExcelVOList); // 导出的数据集合
}
private BaseResponse<String> getStringBaseResponse(String type, String startTime, String endTime, QueryWrapper<Orders> queryWrapper) {
queryWrapper.ge(StringUtils.isNotBlank(startTime), "createTime", startTime);

View File

@ -0,0 +1,20 @@
package com.bsz.school_send_back_end.controller;
import com.bsz.school_send_back_end.model.domain.PrivateMessage;
import com.bsz.school_send_back_end.service.WebsocketService;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class PrivateChatController {
@Resource
private WebsocketService ws;
@MessageMapping("/privateChat")
public void singleChat (PrivateMessage message) {
ws.sendChatMessage(message);
}
}

View File

@ -0,0 +1,94 @@
package com.bsz.school_send_back_end.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bsz.school_send_back_end.common.BaseResponse;
import com.bsz.school_send_back_end.common.ErrorCode;
import com.bsz.school_send_back_end.common.ResultUtils;
import com.bsz.school_send_back_end.exception.ThrowUtils;
import com.bsz.school_send_back_end.model.domain.PrivateMessage;
import com.bsz.school_send_back_end.model.domain.User;
import com.bsz.school_send_back_end.service.PrivateMessageService;
import com.bsz.school_send_back_end.service.UserService;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/PrivateMessage")
public class PrivateMessageController {
@Resource
private PrivateMessageService privateMessageService;
@Resource
private UserService userService;
@Resource
private SimpMessagingTemplate template;
/**
* 添加一条消息
*/
@PostMapping("/save")
public BaseResponse<Boolean> saveOneMessage (@RequestBody PrivateMessage message) {
boolean save = privateMessageService.save(message);
ThrowUtils.throwIf(!save, ErrorCode.SYSTEM_ERROR);
return ResultUtils.success(true);
}
/**
* 查询私聊记录
*/
@GetMapping("/list/{fromUserAccount}/{toUserAccount}")
public BaseResponse<List<String>> listPrivateMessage(
@PathVariable("fromUserAccount") String fromUserAccount,
@PathVariable("toUserAccount") String toUserAccount) {
LambdaQueryWrapper<PrivateMessage> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.and(q -> q
.eq(PrivateMessage::getFrom_userAccount, fromUserAccount)
.eq(PrivateMessage::getTo_userAccount, toUserAccount)
)
.or(q -> q
.eq(PrivateMessage::getFrom_userAccount, toUserAccount)
.eq(PrivateMessage::getTo_userAccount, fromUserAccount)
);
List<PrivateMessage> list = privateMessageService.list(queryWrapper);
List<String> collect = list.stream().map(PrivateMessage::getMessage).collect(Collectors.toList());
return ResultUtils.success(collect);
}
/**
* 删除所有私聊聊天记录
*/
@PostMapping("/delete/{fromUserAccount}/{toUserAccount}")
public BaseResponse<Boolean> deleteAllMessage(
@PathVariable("fromUserAccount") String fromUserAccount,
@PathVariable("toUserAccount") String toUserAccount) {
// 更新当前用户的删除标志不影响另一个用户的查看状态
UpdateWrapper<PrivateMessage> updateWrapper = new UpdateWrapper<>();
updateWrapper
.and(q -> q.eq("from_userAccount", fromUserAccount)
.eq("to_userAccount", toUserAccount)
.set("from_user_deleted", 1)) // 更新发消息者的删除标志
.or(q -> q.eq("from_userAccount", toUserAccount)
.eq("to_userAccount", fromUserAccount)
.set("to_user_deleted", 1)); // 更新接收消息者的删除标志
boolean update = privateMessageService.update(updateWrapper);
ThrowUtils.throwIf(!update, ErrorCode.SYSTEM_ERROR);
// 只发送当前用户的删除消息通知不发送给另一方
User fromUser = userService.getOne(Wrappers.<User>lambdaQuery().eq(User::getUserAccount, fromUserAccount));
template.convertAndSend("/topic/ServerToClient.deleteMsg", fromUser);
return ResultUtils.success(true);
}
}

View File

@ -0,0 +1,352 @@
package com.bsz.school_send_back_end.controller;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeCloseModel;
import com.alipay.api.domain.AlipayTradeCreateModel;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.Query;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bsz.school_send_back_end.common.BaseResponse;
import com.bsz.school_send_back_end.common.ErrorCode;
import com.bsz.school_send_back_end.common.ResultUtils;
import com.bsz.school_send_back_end.config.AlipayClients;
import com.bsz.school_send_back_end.contant.RedisKeyConstant;
import com.bsz.school_send_back_end.contant.RedisKeyConstant;
import com.bsz.school_send_back_end.exception.BusinessException;
import com.bsz.school_send_back_end.exception.ThrowUtils;
import com.bsz.school_send_back_end.mapper.UserMapper;
import com.bsz.school_send_back_end.model.domain.Orders;
import com.bsz.school_send_back_end.model.domain.User;
import com.bsz.school_send_back_end.model.dto.CommonRequest;
import com.bsz.school_send_back_end.model.vo.UserVO;
import com.bsz.school_send_back_end.service.AliPayService;
import com.bsz.school_send_back_end.service.OrdersService;
import com.bsz.school_send_back_end.service.UserService;
import com.bsz.school_send_back_end.utils.RandomNumberGenerator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.*;
@RestController
@RequestMapping("/Alipay1")
public class TestAlipayController {
@Resource
private UserService userService;
@Resource
private OrdersService ordersService;
@Resource
private AliPayService aliPayService;
@Value("${alipay.appId}")
public String appId;
@Value("${alipay.appPrivateKey}")
public String appPrivateKey;
@Value("${alipay.alipayPublicKey}")
public String PublicKey;
@Resource
private UserMapper userMapper;
@Resource
private RandomNumberGenerator randomNumberGenerator;
private static String authToken;
public static final String NOURL = "http://39.101.78.35:6448/api/Alipay1/notifyUrl";
/**
* 解析code获取open_id和token
* @return aaa
* @throws AlipayApiException 支付宝api异常
*/
@GetMapping("/parseCode")
public BaseResponse<UserVO> login(String authcode, HttpServletRequest req) throws AlipayApiException {
String privateKey = appPrivateKey;
String alipayPublicKey = PublicKey;
AlipayConfig alipayConfig = new AlipayConfig();
//支付宝网关
alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
alipayConfig.setAppId(appId);
alipayConfig.setPrivateKey(privateKey);
alipayConfig.setFormat("json");
alipayConfig.setAlipayPublicKey(alipayPublicKey);
alipayConfig.setCharset("UTF-8");
alipayConfig.setSignType("RSA2");
AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
request.setCode(authcode);
request.setGrantType("authorization_code");
AlipaySystemOauthTokenResponse response = alipayClient.execute(request);
// System.out.println(response.getBody());打印所有响应
authToken = response.getAccessToken();
if (!response.isSuccess()) {
return ResultUtils.error(ErrorCode.PARAMS_ERROR);
}
AlipayUserInfoShareRequest request1 = new AlipayUserInfoShareRequest();
AlipayUserInfoShareResponse response1 = alipayClient.execute(request1, authToken);
User oid = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getOpenId, response.getOpenId()));
UserVO userVO = new UserVO();
if (response1.isSuccess()) {
if (oid == null) {
User user = new User();
user.setOpenId(response.getOpenId());
user.setUsername(StringUtils.isAnyBlank(response1.getNickName()) ? "随机名字" + randomNumberGenerator.generateRandomNumber() : response1.getNickName());
user.setUserPassword("123456");
user.setUserAccount("用户" + randomNumberGenerator.generateRandomNumber());
user.setAvatarUrl(StringUtils.isAnyBlank(response1.getAvatar()) ? "https://tfs.alipayobjects.com/images/partner/ATuihpR50zu7UAAAAAAAAAAAAADtl2AA" : response1.getAvatar());
userMapper.insert(user);
req.getSession().setAttribute(RedisKeyConstant.USER_LOGIN_STATE,user);
BeanUtils.copyProperties(user, userVO);
userVO.setSessionId(req.getSession().getId());
return ResultUtils.success(userVO,"注册成功");
}
req.getSession().setAttribute(RedisKeyConstant.USER_LOGIN_STATE, oid);
BeanUtils.copyProperties(oid, userVO);
userVO.setSessionId(req.getSession().getId());
return ResultUtils.success(userVO,"登录成功");
}
req.getSession().setAttribute(RedisKeyConstant.USER_LOGIN_STATE,oid);
BeanUtils.copyProperties(oid, userVO);
userVO.setSessionId(req.getSession().getId());
return ResultUtils.success(userVO,"登录成功");
}
/**
* 解析code获取open_id和token
* @return aaa
* @throws AlipayApiException 支付宝api异常
*/
@GetMapping("/parseCode1")
public BaseResponse<UserVO> login1(String authcode, HttpServletRequest req) throws AlipayApiException {
//String privateKey = appPrivateKey;
// String alipayPublicKey = PublicKey;
String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCc1rWOaCHl7KnDDMctWIgFJqerq9ZU8QsxSA+wQC4nrTfoQVSVZn8fDNosilCHda7yv910A9aJYqZKx0+NOXY9YvMbKYifWtO8TtzAQ9Q0EQXce85gnVQ3yn9evE1MVwfmMIiXJ2jx/dmGrxuADrLcsNB/U4xsusKcNQaA76vALtAYTnKwOODaDt5Qd2OC25PRcGtKupKIbir/f62tNquBkCX+Z5URBpy0rZY2hCu30v3uPv8I3OlpxegFwNDHpKMIY3+wjQtqsogQTn20E5wzeV3VNabNxbORq6B6nh8mvxlo9q14XvmMJDPUoWiJgyUUpaAPZFWSpRCrLvWQY/klAgMBAAECggEAZJ/Ahig7L2gClriZBXfadOuTAapS7dZkpu6j2iGjOyOATgu0N9I11vcI9zCab/5KC0abzzYzK5vWMv3jBSmLueDFNnUUSaEdXaB/Mv+RowIU75ujEgt+n/jUdTR8p3DjCYWz7L6FL1T9fdLU4vkLOlpauoYg/xVnjI7cqFacq8SWr3jiGj/I31O18y02/eDiyAb5RMlSlNGnzvDuRwJ3h2Sn1u7znbMCi6CydG3hx+I0GE2iJqVPymc1f0T0vm7Jy3l/zL84oNKLTgPCqG9k+eriC7RaMkbvPQFjWCDCuWxgYM2pi1L9ZDG+FkReTFsZw6r/TWc4sl2xtj3GDSrHYQKBgQD1NwFBMQwsUQ/aJP63R0gILWSFR0+yQ314vfRRVKoZTujbQr7RBAzgQff97DirINIxXCBeV0zifpc2IaAPaY29YjDnQU+xGqIO91EWPjMkQ6XUvGGesKnKDYkA5yBMyD3/BH8BwJruidW2DwtC2rGTW1hatkXNtYccEI79/00UOQKBgQCjvKIySZdRolOYUfSPHHipOygWClFy1DlI54XDnj0gRBoOrFkeqrXr+G8dYeXP6UnMqLWX8V3RuEJB8klwKGLkMtUWdqMQUFM5yvjuX2d1Y9R2ESw0ch70B/6aItMVv6aN4GjGwCJWD1XD54IpWxtAKJsUxbDiN+343cVqSQQETQKBgQDq9JBcMa3TTLyerbHuVPt88lmNpr2DNk2kAoZ142S0qTpO1M5XIcVgn3UKNWw69FDSgM529rkxkFA8ys0910q7erkW7Cp6rOU459onMOP5zGO5yeLTlbyqYHu0hMEbMQbOMjWrrSwGgcVnE1Ub8sYRRoYLLPkHWPcjee45C4WEaQKBgHkUUeDb+JD+d9DIsg9uH3ANdcwunyJJ+36E7q7EgjEtCxPUsSZzWIoBsbFJppbDzbYRABA3BYjDOAPqNhJBWzeiu16cJmM28wRmqwQi+q+dPgx9EHJL/cW5b7XtkKihi3mY/AIVLI71UhfHR8JrQ9CC9oM62V2/vDNvU8AP9G91AoGANdvRubukeWgvWryBTaPuUTpjkP1mOuJuHiHEW5/XePsURwS6gGP/qJ9bSbhYhQ6iDaMOQ8vahfYM3Q4jvDxgcKS/N1fxFTohcN4bVdvekq62YdTNqcGhNzaxMNboFZYt2dPeDm8PRRMP+abddrS2NqgVSOC3Ru5Kh9iRIs2LOgE=";
String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3JKMG3clg/1MqewlIK/koEhiQiSLagckb/2/Dyvg+rJ2snGiAgzNvhvvc1GdVC+Xnn/P+U+2tAytyuvbOuhmGgNZjeObczJXpo/0D6LBdYDrg4PVMDxpStCxLUpaShHbc/l/IquaorBwd94UJxIPAbUQkUBCbo94mGbhDX+yU4FQ6k1yeUtn03jvZ3AY0BEHpenCxWKgr5S/CUAYEitMbi/r7extBy6f4FCR120NM7VaNEK1xpHbGHo6rDpyiAOR1lWFuiqOJ1hv14UL/SfOLlzvUZiiPysIxdNjycZyiyRvFRHP3n8GBAaJDm9vVHwDfgQ5s3Ig2ggBeYXkFHZqWwIDAQAB";
AlipayConfig alipayConfig = new AlipayConfig();
//沙箱网关
alipayConfig.setServerUrl("https://openapi-sandbox.dl.alipaydev.com/gateway.do");
alipayConfig.setAppId("2021004151684053");
alipayConfig.setPrivateKey(privateKey);
alipayConfig.setFormat("json");
alipayConfig.setAlipayPublicKey(alipayPublicKey);
alipayConfig.setCharset("UTF-8");
alipayConfig.setSignType("RSA2");
AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
request.setCode(authcode);
request.setGrantType("authorization_code");
AlipaySystemOauthTokenResponse response = alipayClient.execute(request);
System.out.println(response.getBody());
authToken = response.getAccessToken();
if (!response.isSuccess()) {
return ResultUtils.error(ErrorCode.PARAMS_ERROR);
}
AlipayUserInfoShareRequest request1 = new AlipayUserInfoShareRequest();
AlipayUserInfoShareResponse response1 = alipayClient.execute(request1, authToken);
User oid = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getOpenId, response.getOpenId()));
UserVO userVO = new UserVO();
if (response1.isSuccess()) {
if (oid == null) {
User user = new User();
user.setOpenId(response.getOpenId());
user.setUsername(StringUtils.isAnyBlank(response1.getNickName()) ? "随机名字" + randomNumberGenerator.generateRandomNumber() : response1.getNickName());
user.setUserPassword("123456");
user.setUserAccount("用户" + randomNumberGenerator.generateRandomNumber());
user.setAvatarUrl(StringUtils.isAnyBlank(response1.getAvatar()) ? "https://tfs.alipayobjects.com/images/partner/ATuihpR50zu7UAAAAAAAAAAAAADtl2AA" : response1.getAvatar());
userMapper.insert(user);
req.getSession().setAttribute(RedisKeyConstant.USER_LOGIN_STATE,user);
BeanUtils.copyProperties(user, userVO);
userVO.setSessionId(req.getSession().getId());
return ResultUtils.success(userVO,"注册成功");
}
req.getSession().setAttribute(RedisKeyConstant.USER_LOGIN_STATE, oid);
BeanUtils.copyProperties(oid, userVO);
userVO.setSessionId(req.getSession().getId());
return ResultUtils.success(userVO,"登录成功");
}
req.getSession().setAttribute(RedisKeyConstant.USER_LOGIN_STATE,oid);
BeanUtils.copyProperties(oid, userVO);
userVO.setSessionId(req.getSession().getId());
return ResultUtils.success(userVO,"登录成功");
}
@GetMapping("/payment/create")
public BaseResponse<String> AlipayTradeCreate(@RequestParam Long id, HttpServletRequest request) throws AlipayApiException {
User loginUser = userService.getLoginUser(request);
String miniOpenId = loginUser.getOpenId();
ThrowUtils.throwIf(miniOpenId == null, ErrorCode.NOT_FOUND_ERROR, "不是小程序用户");
Long orderId = id;
Orders order = ordersService.getById(orderId);
ThrowUtils.throwIf(order == null, ErrorCode.NOT_FOUND_ERROR, "订单不存在");
ThrowUtils.throwIf(order.getState() != 0, ErrorCode.OPERATION_ERROR, "订单状态错误");
if (!loginUser.getId().equals(order.getUserId())) {
throw new BusinessException(ErrorCode.NO_AUTH, "你不是该订单用户!");
}
String tradeNo = aliPayService.createPayment(String.valueOf(orderId), miniOpenId, order.getTotalPrice());
return ResultUtils.success(tradeNo);
}
@GetMapping("/test/close")
public String closeOrder(String orderNo) throws AlipayApiException {
AlipayClients clients = new AlipayClients();
AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
AlipayTradeCloseModel model = new AlipayTradeCloseModel();
//model.setTradeNo(); 这是订单项
//订单项可能会有多个支付单
model.setTradeNo(orderNo);
request.setBizModel(model);
request.setNotifyUrl(NOURL);
AlipayTradeCloseResponse response = clients.alipayClient().execute(request);
//这里应该写进日志
return response.getBody();
}
@GetMapping("/test/refund")
public String test_refund(String orderNo) throws AlipayApiException {
AlipayClients clients = new AlipayClients();
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
AlipayTradeRefundModel model = new AlipayTradeRefundModel();
QueryWrapper<Orders> ordersQueryWrapper = new QueryWrapper<>();
ordersQueryWrapper.eq("pickupCode", orderNo);
Orders orders = ordersService.getOne(ordersQueryWrapper);
model.setOutTradeNo(orderNo);
model.setRefundAmount(String.valueOf(orders.getTotalPrice()));
//退款请求单号 要求唯一 需改
//model.setOutRequestNo("123");
request.setBizModel(model);
request.setNotifyUrl(NOURL);
AlipayTradeRefundResponse response = clients.alipayClient().execute(request);
String body = response.getBody();
orders.setState(2);
Date date = new Date();
orders.setUpdateTime(date);
boolean update = ordersService.updateById(orders);
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "修改订单状态失败");
return body;
}
@GetMapping("/test/query")
public String test_query (String orderNo) throws AlipayApiException {
AlipayClients clients = new AlipayClients();
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
AlipayTradeQueryModel model = new AlipayTradeQueryModel();
model.setOutTradeNo(orderNo);
request.setBizModel(model);
request.setNotifyUrl(NOURL);
AlipayTradeQueryResponse response = clients.alipayClient().execute(request);
String body = response.getBody();
return body;
}
@PostMapping("/notifyUrl")
@Transactional(rollbackFor = Exception.class)
public synchronized void aliPayNotifyUrl(HttpServletRequest request, HttpServletResponse response) {
// HttpServletRequest 的参数转换为 Map<String, String>
Map<String,String> params = new HashMap<>();Map<String, String[]> requestParams = request.getParameterMap();
for(String name : requestParams.keySet()) {
params.put(name, request.getParameter(name));
}
//修改订单信息
String out_trade_no = params.get("out_trade_no");
QueryWrapper<Orders> ordersQueryWrapper = new QueryWrapper<>();
ordersQueryWrapper.eq("pickupCode", out_trade_no);
Orders orders = ordersService.getOne(ordersQueryWrapper);
orders.setState(1);
Date date = new Date();
orders.setUpdateTime(date);
boolean update = ordersService.updateById(orders);
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "修改订单状态失败");
//TODO 商家通知
String resultInfo = "buyer_id=208****42&total_amount=0.01&body=***试&trade_no=20190329**941025940236&notify_time=2019-03-29 19:42:04&subject=**电脑网站支付&sign_type=RSA2&charset=UTF-8&auth_app_id=201****222&notify_type=trade_status_sync&invoice_amount=0.01&out_trade_no=20190329ygyg45484544100003&trade_status=TRADE_SUCCESS&gmt_payment=2019-03-29 19:42:03&version=1.0&point_amount=0.00&sign=LDDUIGQmc+1qNtk3oyoAKVeMUKTngdX3ZjVeZOK0EjiPDJ/+Nk+0WSqcE6J7/5xb96Z/vP0yY3pVhZUiFVJ1G45/ys/HAleHh+EERZ1lkCkule1sSyaGFTKQGKx4uHpTyqIgRB1bouf19RPbSx1EkA0VkCarSy9G/OEG5Qmg8UdL2dRulMhlbOHS7tdMJJycDA8vOspOUMeQmk/H6IK9R2Kou5hN2T3KR1GWLYFK+z1jeZhQB3q52lZynO0OFjSzU4aQUBMW5QskQppBYd/ghtY/2YP+2H6YVGNgVmaheZMQ3PVTBALEV+8rZa91salH9DkKN2UCYGvNSNDT1VGCTQ==&gmt_create=2019-03-29 19:42:00&buyer_pay_amount=0.01&receipt_amount=0.01&fund_bill_list=[{\"amount\":\"0.01\",\"fundChannel\":\"PCREDIT\"}]&seller_id=208****5&app_id=2014100***22&notify_id=20190329002221942040**8";
//编码格式
String charset="utf-8";
//支付宝公钥
String alipaypublicKey="";
//签名方式
String sign_type="RSA2";
//对待签名字符串数据通过&进行拆分
String [] temp = resultInfo.split("&");
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
//把拆分数据放在map集合内
for (int i = 0; i < temp.length; i++) {
String[] arr = temp[i].split("=", 2); //通过"="号分割成2个数据
String[] tempAagin = new String[arr.length]; //再开辟一个数组用来接收分割后的数据
for (int j = 0; j < arr.length; j++) {
tempAagin[j] = arr[j];
}
map.put(tempAagin[0], tempAagin[1]);
}
System.out.println(map);
String alipayrsaPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3JKMG3clg/1MqewlIK/koEhiQiSLagckb/2/Dyvg+rJ2snGiAgzNvhvvc1GdVC+Xnn/P+U+2tAytyuvbOuhmGgNZjeObczJXpo/0D6LBdYDrg4PVMDxpStCxLUpaShHbc/l/IquaorBwd94UJxIPAbUQkUBCbo94mGbhDX+yU4FQ6k1yeUtn03jvZ3AY0BEHpenCxWKgr5S/CUAYEitMbi/r7extBy6f4FCR120NM7VaNEK1xpHbGHo6rDpyiAOR1lWFuiqOJ1hv14UL/SfOLlzvUZiiPysIxdNjycZyiyRvFRHP3n8GBAaJDm9vVHwDfgQ5s3Ig2ggBeYXkFHZqWwIDAQAB";
try {
//验签方法
boolean signVerified = AlipaySignature.rsaCheckV1(params,PublicKey,charset,sign_type);
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
if (signVerified && "TRADE_SUCCESS".equals(params.get("trade_status"))) {
// 业务处理
writer.println("success");
} else {
writer.println("fail");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,31 @@
package com.bsz.school_send_back_end.listener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.messaging.SessionConnectedEvent;
import org.springframework.web.socket.messaging.SessionDisconnectEvent;
@Component
public class WebSocketEventListener {
@Autowired
private SimpMessageSendingOperations messagingTemplate;
public static Integer userNumber = 0;
@EventListener
public void handleWebSocketConnectListener(SessionConnectedEvent event) {
userNumber++;
messagingTemplate.convertAndSend("/topic/ServerToClient.showUserNumber", userNumber);
System.out.println("我来了哦~");
}
@EventListener
public void handleWebSocketDisconnectListener(SessionDisconnectEvent event) {
userNumber--;
messagingTemplate.convertAndSend("/topic/ServerToClient.showUserNumber", userNumber);
System.out.println("我走了哦~");
}
}

View File

@ -0,0 +1,153 @@
package com.bsz.school_send_back_end.manager;
import cn.hutool.core.util.StrUtil;
import com.bsz.school_send_back_end.model.domain.User;
import com.bsz.school_send_back_end.model.domain.UserLoginRedisInfo;
import com.bsz.school_send_back_end.service.UserService;
import com.bsz.school_send_back_end.utils.NetUtils;
import com.bsz.school_send_back_end.utils.RedisKeyUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.session.data.redis.RedisIndexedSessionRepository;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.concurrent.TimeUnit;
import static com.bsz.school_send_back_end.contant.RedisKeyConstant.*;
@Slf4j
@Component
public class SessionManager {
@Resource
private StringRedisTemplate stringRedisTemplate;
@Resource
private RedisIndexedSessionRepository sessionRepository;
@Value("${spring.session.timeout}")
private long sessionTimeout;
@Lazy
@Resource
private UserService userService;
/**
* 登录
*/
public String login (User user, HttpServletRequest request) {
String message = "登录成功";
String ipAddress = NetUtils.getIpAddress(request);
String oldSessionId = this.checkOtherLogin(user.getId(), ipAddress, request);
//不为空表示在其他端以登录
if (StrUtil.isNotBlank(oldSessionId)) {
//删除其他端的登录态
this.removeOtherSessionAttribute(oldSessionId, user.getId());
message += ",已移除其他设备的登录";
}
UserLoginRedisInfo build = UserLoginRedisInfo.builder()
.user(user)
.ip(ipAddress).
build();
this.setLoginAttribute(request, USER_LOGIN_STATE, build);
return message;
}
/**
* 退出登录
*/
public void logout (HttpServletRequest request) {
User loginUser = userService.getLoginUser(request);
removeAttribute(request, USER_LOGIN_STATE);
stringRedisTemplate.delete(RedisKeyUtils.getUserExtraInfoKey(loginUser.getId()));
}
/**
* 检查是否在其他端登录
*/
public String checkOtherLogin(Long userId, String currentIp, HttpServletRequest request) {
//校验sessionId
Object oldSessionIdObj = stringRedisTemplate.opsForHash().get(RedisKeyUtils.getUserExtraInfoKey(userId), SESSION_ID);
String oldSessionId = null;
if (oldSessionIdObj != null) {
oldSessionId = (String) oldSessionIdObj;
}
//校验ip
Object oldIpObj = stringRedisTemplate.opsForHash().get(RedisKeyUtils.getUserExtraInfoKey(userId), IP);
String oldIP = null;
if (oldIpObj != null) {
oldIP = (String) oldIpObj;
}
// 判断sessionId如果为空或相等返回null不等判断ip
// 如果ip为空或相等返回null不等返回oldSessionId
if (StrUtil.isBlank(oldSessionId) || oldSessionId.equals(request.getSession().getId())) {
return null;
}
else {
if (StrUtil.isBlank(oldIP) || oldIP.equals(currentIp)) {
return null;
}
}
return oldSessionId;
}
/**
* 删除其他设备登录态
*/
public void removeOtherSessionAttribute (String sessionId, Long userId) {
String sessionKey = RedisKeyUtils.getSessionKey(sessionId);
String sessionAttrKey = RedisKeyUtils.getSessionAttrKey(USER_LOGIN_STATE);
//删除用户的额外信息
Boolean userExtraDelete = stringRedisTemplate.delete(RedisKeyUtils.getUserExtraInfoKey(userId));
Long delete = sessionRepository.getSessionRedisOperations().opsForHash().delete(sessionKey, sessionAttrKey);
log.info("oldSessionId: {}user extra info delete result: {}user login state delete result: {}",
sessionId, userExtraDelete, delete);
}
/**
* 设置登录属性
*/
public void setLoginAttribute(HttpServletRequest request, String loginKey, UserLoginRedisInfo userLoginRedisInfo) {
setAttribute(request, loginKey, userLoginRedisInfo, true);
}
/**
* 设置属性
*/
public void setAttribute(HttpServletRequest request, String key, Object value, boolean login) {
HttpSession session = request.getSession();
if (login) {
UserLoginRedisInfo userLoginRedisInfo = (UserLoginRedisInfo) value;
User user = userLoginRedisInfo.getUser();
// 存储登录状态
session.setAttribute(key, user);
//存储sessionId和ip信息
String sessionId = session.getId();
String userExtraInfoKey = RedisKeyUtils.getUserExtraInfoKey(user.getId());
stringRedisTemplate.opsForHash().put(userExtraInfoKey, SESSION_ID, sessionId);
stringRedisTemplate.opsForHash().put(userExtraInfoKey, IP, userLoginRedisInfo.getIp());
stringRedisTemplate.expire(userExtraInfoKey, sessionTimeout, TimeUnit.SECONDS);
}
else {
session.setAttribute(key, value);
}
}
/**
* 删除属性
*/
public void removeAttribute(HttpServletRequest request, String key) {
HttpSession session = request.getSession();
session.removeAttribute(key);
}
}

View File

@ -0,0 +1,18 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.Collect;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author pc
* @description 针对表collect的数据库操作Mapper
* @createDate 2024-11-12 19:19:50
* @Entity com.bsz.school_send_back_end.model.domain.Collect
*/
public interface CollectMapper extends BaseMapper<Collect> {
}

View File

@ -0,0 +1,18 @@
package com.bsz.school_send_back_end.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bsz.school_send_back_end.model.domain.PrivateMessage;
/**
* @author pc
* @description 针对表private_message的数据库操作Mapper
* @createDate 2024-11-10 15:16:02
* @Entity com.bsz.school_send_back_end.model.domain.PrivateMessage
*/
public interface PrivateMessageMapper extends BaseMapper<PrivateMessage> {
}

View File

@ -0,0 +1,35 @@
package com.bsz.school_send_back_end.model.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;
/**
*
* @TableName collect
*/
@TableName(value ="collect")
@Data
public class Collect implements Serializable {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 用户id
*/
private Long userId;
/**
* 商家id
*/
private Long businessId;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,55 @@
package com.bsz.school_send_back_end.model.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;
/**
* 聊天记录
* @TableName private_message
*/
@TableName(value ="private_message")
@Data
public class PrivateMessage implements Serializable {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 发消息者
*/
private String from_userAccount;
/**
* 接收消息者
*/
private String to_userAccount;
/**
* 订单id
*/
private Long orderId;
/**
* 消息内容
*/
private String message;
/**
* 发消息者是否删除
*/
private Integer from_user_deleted;
/**
* 接收消息者是否删除
*/
private Integer to_user_deleted;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,13 @@
package com.bsz.school_send_back_end.model.domain;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class UserLoginRedisInfo {
private User user;
private String ip;
}

View File

@ -0,0 +1,14 @@
package com.bsz.school_send_back_end.model.dto.collect;
import lombok.Data;
import java.io.Serializable;
@Data
public class CollectAddRequest implements Serializable {
/**
* 商家id
*/
private Long businessId;
}

View File

@ -14,8 +14,7 @@ public class UploadFileRequest implements Serializable {
/**
* 业务
*/
@NotBlank(message = "业务名称不能为空")
@Schema(description = "业务标识例如user_avatardishescardsystem", example = "user_avatar")
@Schema(description = "业务标识例如user_avatardishescardsystem")
private String biz;
@Serial

View File

@ -0,0 +1,52 @@
package com.bsz.school_send_back_end.model.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.NumberFormat;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import lombok.Data;
import java.math.BigDecimal;
/**
* Excel订单信息导出
*
* @author ASUS
*/
@Data
public class OrdersExcelVO {
/**
* 订单编号
*/
@ColumnWidth(20)
@NumberFormat("#")
@ExcelProperty(value = "订单编号", index = 0)
private Long id;
/**
* 下单时间
*/
@ColumnWidth(20)
@ExcelProperty(value = "下单时间", index = 1)
private String createTime;
/**
* 手机号
*/
@ColumnWidth(20)
@ExcelProperty(value = "手机号", index = 2)
private String phone;
/**
* 支付状态
*/
@ExcelProperty(value = "支付状态", index = 3)
private String state;
/**
* 订单金额
*/
@NumberFormat("0.00")
@ExcelProperty(value = "订单金额")
private BigDecimal totalPrice;
}

View File

@ -0,0 +1,74 @@
package com.bsz.school_send_back_end.model.vo;
import lombok.Data;
import javax.servlet.http.HttpSession;
import java.io.Serializable;
@Data
public class UserVO implements Serializable {
/**
* id
*/
private Long id;
/**
* 支付宝开放平台id
*/
private String unionId;
/**
* openId
*/
private String openId;
/**
* 用户昵称
*/
private String username;
/**
* 账号
*/
private String userAccount;
/**
* 用户头像
*/
private String avatarUrl;
/**
* 性别
*/
private Integer gender;
/**
* 密码
*/
private String userPassword;
/**
* 电话
*/
private String phone;
/**
* 邮箱
*/
private String email;
/**
* 状态 0 -正常
*/
private Integer userStatus;
/**
* 登录态
*/
private String sessionId;
/**
* 用户角色 0 - 普通用户 1 - 管理员 2 - 商家
*/
private String userRole;
}

View File

@ -0,0 +1,8 @@
package com.bsz.school_send_back_end.service;
import java.math.BigDecimal;
public interface AliPayService {
String createPayment(String orderId, String miniOpenId, BigDecimal amount);
}

View File

@ -0,0 +1,28 @@
package com.bsz.school_send_back_end.service;
import com.bsz.school_send_back_end.model.domain.Collect;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bsz.school_send_back_end.model.dto.cart.CartAddRequest;
import com.bsz.school_send_back_end.model.dto.collect.CollectAddRequest;
import javax.servlet.http.HttpServletRequest;
import java.net.http.HttpClient;
/**
* @author pc
* @description 针对表collect的数据库操作Service
* @createDate 2024-11-12 19:19:50
*/
public interface CollectService extends IService<Collect> {
/**
* 校验
*/
void validCollect(CollectAddRequest collectAddRequest);
/**
* 添加收藏
*/
Boolean addCollect(Collect collect, HttpServletRequest request);
}

View File

@ -0,0 +1,13 @@
package com.bsz.school_send_back_end.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bsz.school_send_back_end.model.domain.PrivateMessage;
/**
* @author pc
* @description 针对表private_message的数据库操作Service
* @createDate 2024-11-10 15:16:02
*/
public interface PrivateMessageService extends IService<PrivateMessage> {
}

View File

@ -0,0 +1,36 @@
package com.bsz.school_send_back_end.service;
import com.bsz.school_send_back_end.common.ErrorCode;
import com.bsz.school_send_back_end.exception.BusinessException;
import com.bsz.school_send_back_end.model.domain.PrivateMessage;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class WebsocketService {
@Resource
private SimpMessagingTemplate template;
@Resource
private PrivateMessageService privateMessageService;
/**
* 简单点对点聊天
*/
public void sendChatMessage(PrivateMessage message) {
System.out.println("Sending message: " + message);
message.setMessage(message.getFrom_userAccount() + "发送:" + message.getMessage());
//使用template获取前端传来的参数来指定订阅地址
//一个参数是订阅地址 第二个参数是消息
template.convertAndSend("/topic/ServerToClient.private." + message.getTo_userAccount(), message);
//将消息存储到数据库中
boolean save = privateMessageService.save(message);
if (!save) {
throw new BusinessException(ErrorCode.SYSTEM_ERROR);
}
}
}

View File

@ -0,0 +1,91 @@
package com.bsz.school_send_back_end.service.impl;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradeCreateModel;
import com.alipay.api.request.AlipayTradeCreateRequest;
import com.alipay.api.response.AlipayTradeCreateResponse;
import com.bsz.school_send_back_end.common.ErrorCode;
import com.bsz.school_send_back_end.config.AlipayClients;
import com.bsz.school_send_back_end.exception.BusinessException;
import com.bsz.school_send_back_end.model.domain.OrderDetails;
import com.bsz.school_send_back_end.model.domain.Orders;
import com.bsz.school_send_back_end.service.AliPayService;
import com.bsz.school_send_back_end.service.BusinessService;
import com.bsz.school_send_back_end.service.OrderDetailsService;
import com.bsz.school_send_back_end.service.OrdersService;
import com.bsz.school_send_back_end.utils.RandomNumberGenerator;
import com.bsz.school_send_back_end.utils.UniqueNumberGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
@Slf4j
@Service
public class AlipayServiceImpl implements AliPayService {
@Resource
private OrdersService ordersService;
@Resource
private OrderDetailsService orderDetailsService;
@Resource
private BusinessService businessService;
@Override
@Transactional(rollbackFor = Exception.class)
public synchronized String createPayment(String orderId, String miniOpenId, BigDecimal amount) {
//创建客户
AlipayClients clients = new AlipayClients();
//AlipayClient client = clients.alipayClient();
//创建交易请求
AlipayTradeCreateRequest aliRequest = new AlipayTradeCreateRequest();
//创建实体类
AlipayTradeCreateModel model = new AlipayTradeCreateModel();
//请求参数 沙箱内部参数
String outTradeNo = UniqueNumberGenerator.generateNumber();
Orders order = ordersService.getById(orderId);
if (order == null) {
log.error("订单不存在");
throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "订单不存在,订单号:" + outTradeNo);
}
OrderDetails orderDetails = orderDetailsService.getById(orderId);
//给支付宝的订单号设置成取餐码
order.setPickupCode(outTradeNo);
model.setOutTradeNo(outTradeNo);
model.setTotalAmount(String.valueOf(amount));
model.setSubject(orderDetails.getAttributeNames());
model.setProductCode("JSAPI_PAY");
model.setSellerId("2088721037756350");
model.setBuyerId("2088722037756360");
model.setOpAppId("2021004151684053");
///回调地址
aliRequest.setNotifyUrl("http://39.101.78.35:6448/api/Alipay1/notifyUrl");
aliRequest.setBizModel(model);
String trade_no = null;
try {
AlipayTradeCreateResponse response = clients.alipayClient().execute(aliRequest);
trade_no = response.getTradeNo();
if (trade_no == null) {
throw new BusinessException(ErrorCode.NULL_ERROR, "未获取到trade_no");
}
} catch (AlipayApiException e) {
e.printStackTrace();
}
return trade_no;
}
}

View File

@ -0,0 +1,59 @@
package com.bsz.school_send_back_end.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bsz.school_send_back_end.common.ErrorCode;
import com.bsz.school_send_back_end.exception.ThrowUtils;
import com.bsz.school_send_back_end.model.domain.Business;
import com.bsz.school_send_back_end.model.domain.Collect;
import com.bsz.school_send_back_end.model.domain.User;
import com.bsz.school_send_back_end.model.dto.collect.CollectAddRequest;
import com.bsz.school_send_back_end.service.BusinessService;
import com.bsz.school_send_back_end.service.CollectService;
import com.bsz.school_send_back_end.mapper.CollectMapper;
import com.bsz.school_send_back_end.service.UserService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
/**
* @author xy
*/
@Service
public class CollectServiceImpl extends ServiceImpl<CollectMapper, Collect>
implements CollectService{
@Resource
private UserService userService;
@Resource
private BusinessService businessService;
@Override
public void validCollect(CollectAddRequest collectAddRequest) {
Long businessId = collectAddRequest.getBusinessId();
ThrowUtils.throwIf(businessId == null, ErrorCode.PARAMS_ERROR, "参数不全");
LambdaQueryWrapper<Business> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Business::getId, businessId);
long count = businessService.count(wrapper);
ThrowUtils.throwIf(count != 1, ErrorCode.PARAMS_ERROR, "填写的商家id不存在");
}
@Override
public Boolean addCollect(Collect collect, HttpServletRequest request) {
User loginUser = userService.getLoginUser(request);
Long loginUserId = loginUser.getId();
Long businessId = collect.getBusinessId();
LambdaQueryWrapper<Collect> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Collect::getBusinessId, businessId);
wrapper.eq(Collect::getUserId, loginUserId);
long count = this.count(wrapper);
ThrowUtils.throwIf(count > 0, ErrorCode.OPERATION_ERROR, "该商家已收藏");
collect.setUserId(loginUserId);
return this.save(collect);
}
}

View File

@ -0,0 +1,22 @@
package com.bsz.school_send_back_end.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bsz.school_send_back_end.model.domain.PrivateMessage;
import com.bsz.school_send_back_end.service.PrivateMessageService;
import com.bsz.school_send_back_end.mapper.PrivateMessageMapper;
import org.springframework.stereotype.Service;
/**
* @author pc
* @description 针对表private_message的数据库操作Service实现
* @createDate 2024-11-10 15:16:02
*/
@Service
public class PrivateMessageServiceImpl extends ServiceImpl<PrivateMessageMapper, PrivateMessage>
implements PrivateMessageService{
}

View File

@ -0,0 +1,83 @@
package com.bsz.school_send_back_end.utils;
import com.bsz.school_send_back_end.common.ErrorCode;
import com.bsz.school_send_back_end.exception.BusinessException;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Excel工具类
*
* @author bsz
* */
@SuppressWarnings("all")
public class ExcelUtils {
/**
* 获取路径
*
* @return 当前路径
*/
public static String getPath() {
return ExcelUtils.class.getResource("/").getPath();
}
/**
* 创建新文件
*
* @param pathName 文件名
* @return 文件
*/
public static File createNewFile(String pathName) {
File file = new File(getPath() + pathName);
if (file.exists()) {
file.delete();
} else {
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
}
return file;
}
/**
* 设置响应结果
*
* @param response 响应结果对象
* @param rawFileName 文件名
*/
public static void setExcelResponseProp(HttpServletResponse response, String rawFileName) throws IOException {
//设置内容类型
response.setContentType("application/vnd.vnd.ms-excel");
//设置编码格式
response.setCharacterEncoding("utf-8");
//设置导出文件名称避免乱码
String fileName = URLEncoder.encode(rawFileName.concat(".xlsx"), "UTF-8");
// 设置响应头
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);
}
/**
* Date转String
*
* @param date 日期
* @return 字符串
*/
public static String dateToString(Date date) {
if (date == null) {
throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
}
// Date转换为String
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-hh:mm");
return sdf.format(date);
}
}

View File

@ -0,0 +1,58 @@
package com.bsz.school_send_back_end.utils;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* 网络工具类
*
* @author <a href="https://github.com/liyupi">程序员鱼皮</a>
* @from <a href="https://yupi.icu">编程导航知识星球</a>
*/
@SuppressWarnings("all")
public class NetUtils {
/**
* 获取客户端 IP 地址
*
* @param request
* @return
*/
public static String getIpAddress(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
if (ip.equals("127.0.0.1")) {
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
if (inet != null) {
ip = inet.getHostAddress();
}
}
}
// 多个代理的情况下第一个ip为客户端真实ip多个ip按照,分割
if (ip != null && ip.length() > 15) {
if (ip.indexOf(",") > 0) {
ip = ip.substring(0,ip.indexOf(","));
}
}
if (ip == null) {
return "127.0.0.1";
}
return ip;
}
}

View File

@ -0,0 +1,29 @@
package com.bsz.school_send_back_end.utils;
import static com.bsz.school_send_back_end.contant.RedisKeyConstant.*;
import static org.springframework.session.data.redis.RedisIndexedSessionRepository.DEFAULT_NAMESPACE;
public class RedisKeyUtils {
/**
* 获取一登录用户的ip和sessionId对应的key
* @param userId
* @return
*/
public static String getUserExtraInfoKey(Long userId) {
return USER_EXTRA_INFO + String.valueOf(userId);
}
/**
* 获取session信息对应的key
* @param sessionId
* @return
*/
public static String getSessionKey(String sessionId) {
return DEFAULT_NAMESPACE + ":" + SESSION_KEY_POSTFIX + ":" + sessionId;
}
public static String getSessionAttrKey(String attrName) {
return SESSION_ATTRIBUTE_PREFIX + ":" + attrName;
}
}

View File

@ -0,0 +1,44 @@
package com.bsz.school_send_back_end.utils;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
/**
* 取餐码生成
* @author bsz
*/
@Component
public class UniqueNumberGenerator {
private static int sequenceNumber = 1; // 初始化每天的序列号从1开始
private static String lastDate = ""; // 记录上次生成数字的日期
private static final Random random = new Random(); // 随机数生成器
// 生成17位的唯一编号
public static String generateNumber() {
// 获取当前日期的年月日格式 (前8位)
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
String dateStr = dateFormat.format(new Date());
// 检查日期是否变更如果变更则重置序列号
if (!dateStr.equals(lastDate)) {
lastDate = dateStr;
sequenceNumber = 1; // 每天重置为0001
}
// 生成中间5位的随机数
int middleRandom = 10000 + random.nextInt(90000); // 生成10000到99999之间的随机数
// 格式化后四位的序列号
String sequenceStr = String.format("%04d", sequenceNumber);
// 更新序列号为下一次调用准备
sequenceNumber++;
// 组合并返回结果
return dateStr + middleRandom + sequenceStr;
}
}

View File

@ -1,7 +1,4 @@
spring:
web:
resources:
static-locations: file:D:\test\images
application:
name: school_send_back_end
datasource:
@ -22,10 +19,10 @@ spring:
pathmatch:
matching-strategy: ant_path_matcher
redis:
host: 39.101.78.35
host: 154.8.193.216
port: 6379
database: 3
password: 12345678
password: Cksys6509
timeout: 60000
profiles:
active: dev
@ -38,6 +35,7 @@ server:
port: 9999
servlet:
context-path: /api
mybatis-plus:
configuration:
map-underscore-to-camel-case: false
@ -50,7 +48,6 @@ mybatis-plus:
session:
timeout: 86400
aliyun:
oss:
file:

View File

@ -0,0 +1,16 @@
<?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="com.bsz.school_send_back_end.mapper.CollectMapper">
<resultMap id="BaseResultMap" type="com.bsz.school_send_back_end.model.domain.Collect">
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="userId" column="userId" jdbcType="BIGINT"/>
<result property="businessId" column="businessId" jdbcType="BIGINT"/>
</resultMap>
<sql id="Base_Column_List">
id,userId,businessId
</sql>
</mapper>

View File

@ -0,0 +1,22 @@
<?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="com.bsz.school_send_back_end.mapper.PrivateMessageMapper">
<resultMap id="BaseResultMap" type="com.bsz.school_send_back_end.model.domain.PrivateMessage">
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="from_userAccount" column="from_userAccount" jdbcType="VARCHAR"/>
<result property="to_userAccount" column="to_userAccount" jdbcType="VARCHAR"/>
<result property="orderId" column="orderId" jdbcType="BIGINT"/>
<result property="message" column="message" jdbcType="VARCHAR"/>
<result property="from_user_deleted" column="from_user_deleted" jdbcType="TINYINT"/>
<result property="to_user_deleted" column="to_user_deleted" jdbcType="TINYINT"/>
</resultMap>
<sql id="Base_Column_List">
id,from_userAccount,to_userAccount,
orderId,message,from_user_deleted,
to_user_deleted
</sql>
</mapper>

View File

@ -1,55 +0,0 @@
package com.bsz.school_send_back_end.service;
import com.bsz.school_send_back_end.model.domain.User;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.DigestUtils;
import javax.annotation.Resource;
/**
* 用户服务测试
*/
@SpringBootTest
class
UserServiceTest {
@Resource
private UserService userService;
@Test
void textInsertUser(){
for (int i = 0; i < 10; i ++ ) {
User user = new User();
user.setUsername("bsz" + i + "");
user.setUserAccount("bsz" + i + "");
user.setAvatarUrl("https://img.zcool.cn/community/01a6095f110b9fa8012066219b67d4.png@1280w_1l_2o_100sh.png");
user.setGender(0);
user.setUserPassword("64dafd451f41b8bcb260041b1a0a1551");
user.setPhone("0000000" + i);
user.setEmail(i + "00000000@qq.com");
boolean result = userService.save(user);
System.out.println("新增用户ID"+user.getId());
// 断言判断一下是否符合预期结果assertTrue是否保存成功
Assertions.assertTrue(result);
}
}
// @Test
// void userRegister() {
//// String userAccount = "yupi1";
//// String userPassword = "12345678";
//// String checkPassword = "12345678";
////
//// long l = userService.userRegister(userAccount, userPassword, checkPassword);
//// Assertions.assertTrue(l > 0);
//// System.out.println(1);
// }
}