上传代码

This commit is contained in:
2025-08-18 09:07:54 +08:00
commit 0822f8fa5c
309 changed files with 18123 additions and 0 deletions

33
school_lend_back_end/.gitignore vendored Normal file
View File

@ -0,0 +1,33 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/

Binary file not shown.

View File

@ -0,0 +1,289 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/>
</parent>
<groupId>com.bsz</groupId>
<artifactId>school_send_back_end</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>school_send_back_end</name>
<description>school_send_back_end</description>
<properties>
<java.version>17</java.version>
<spring-ai.version>1.0.0-M2</spring-ai.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.38.0.ALL</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.1</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version> <!-- 推荐稳定版 -->
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.9.21</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>3.5.12</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.109.Final</version>
</dependency>
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty</artifactId>
<version>1.1.13</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.16</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>sensitive-word</artifactId>
<version>0.23.0</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version> <!-- 或使用其他 Jakarta 版本,根据需要 -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-api</artifactId>
<version>2.1.0</version> <!-- 使用 Jakarta 版本的 WebSocket API -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.5.0</version> <!-- 或者选择最新的兼容版本 -->
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-core</artifactId>
<version>2.2.20</version>
</dependency>
<!--阿里AI-->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter</artifactId>
<version>1.0.0-M2.1</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spring-releases</id>
<url>https://repo.spring.io/release</url>
</repository>
<repository>
<id>knife4j</id>
<url>https://s01.oss.sonatype.org/content/repositories/releases/</url>
</repository>
<repository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2</url>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestone Repository</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,391 @@
create database school_send;
use school_send;
create table user
(
username varchar(256) null comment '用户昵称',
id bigint auto_increment comment 'id'
primary key,
unionId varchar(256) null comment '支付宝开放平台id',
openId varchar(256) null comment 'openId',
userAccount varchar(256) null comment '账号',
avatarUrl varchar(256) null comment '用户头像',
gender tinyint null comment '性别',
userPassword varchar(512) not null comment '密码',
phone varchar(128) null comment '电话',
email varchar(512) null comment '邮箱',
userStatus int default 0 not null comment '状态 0 -正常',
createTime datetime default CURRENT_TIMESTAMP null comment '创建时间',
updateTime datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP,
isDelete tinyint default 0 not null comment '是否删除',
userRole varchar(256) default 'user' not null comment 'user-普通用户business-商家admin-管理员',
index idx_openId (openId)
) comment '用户' collate = utf8mb4_unicode_ci;
-- 商家表
create table if not exists business
(
id bigint auto_increment comment 'id' primary key,
userId bigint not null comment '用户id',
businessName varchar(512) not null comment '门店名称',
businessAvatar varchar(1024) not null comment '门店头像',
businessPhone varchar(64) not null comment '门店手机号',
address varchar(512) not null comment '店铺详细地址',
businessProfile varchar(512) null comment '门店简介',
businessImages varchar(1024) null comment '商家相册',
categoryId bigint null comment '分类id',
startBusiness varchar(64) not null comment '开始营业时间',
endBusiness varchar(64) not null comment '结束营业时间',
state tinyint default 0 not null comment '状态:0审核中,1启用,2禁用',
storeStatus tinyint default 0 not null comment '店铺状态:0休业,1营业',
createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
isDelete tinyint default 0 not null comment '是否删除',
index idx_businessId (id),
index idx_userId (userId)
) comment '商家' collate = utf8mb4_unicode_ci;
-- 商家认证表
create table if not exists business_auth
(
id bigint auto_increment comment 'id' primary key,
businessId bigint not null comment '店铺id',
shopkeeper varchar(64) not null comment '店主名',
license varchar(1024) not null comment '营业执照',
frontIdCard varchar(1024) not null comment '身份证正面',
backIdCard varchar(1024) not null comment '身份证反面',
bankCard varchar(64) not null comment '银行卡号',
createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
isDelete tinyint default 0 not null comment '是否删除',
index idx_businessId (businessId)
) comment '商家认证' collate = utf8mb4_unicode_ci;
-- 系统
-- 分类表
create table if not exists category
(
id bigint auto_increment comment 'id' primary key,
name varchar(256) not null comment '分类名',
image varchar(512) not null comment '分类图片',
createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
index idx_categoryId (id)
) comment '分类表' collate = utf8mb4_unicode_ci;
-- 系统信息表
create table if not exists systemInfo
(
id bigint auto_increment comment 'id' primary key,
type tinyint not null comment '类型:0公告,1轮播图',
content varchar(256) not null comment '功能内容',
createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间'
) comment '系统信息' collate = utf8mb4_unicode_ci;
-- 操作日志表
create table if not exists systemLog
(
id bigint auto_increment comment 'id' primary key,
userId bigint not null comment '用户id',
content varchar(256) not null comment '操作内容',
ip varchar(64) not null comment 'ip地址',
createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
index idx_businessId (userId)
) comment '系统信息' collate = utf8mb4_unicode_ci;
-- 菜品
-- 菜品分组表
create table if not exists dishes_group
(
id bigint auto_increment comment 'id' primary key,
businessId bigint not null comment '商家id',
groupName varchar(128) not null comment '菜品分组名称',
isTopping tinyint default 0 not null comment '是否置顶:0不置顶,1置顶',
createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
isDelete tinyint default 0 not null comment '是否删除',
index idx_businessId (businessId)
) comment '菜品分组表' collate = utf8mb4_unicode_ci;
-- 菜品表
create table if not exists dishes
(
id bigint auto_increment comment 'id' primary key,
businessId bigint not null comment '商家id',
dishesGroupId bigint not null comment '菜品分组id',
dishesName varchar(128) not null comment '菜品名称',
dishesImage varchar(1024) null comment '菜品图片',
dishesPrice double not null comment '菜品价格',
packPrice double not null comment '打包费',
inventoryStatus int not null comment '库存数量',
status varchar(20) default '上架' not null comment '菜品状态:上架,下架',
createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
isDelete tinyint default 0 not null comment '是否删除',
index idx_businessId (businessId)
) comment '菜品表' collate = utf8mb4_unicode_ci;
-- 菜品和规格的中间表
create table if not exists specifications_dishes
(
id bigint auto_increment comment 'id' primary key,
dishesId bigint not null comment '菜品id',
specificationsId bigint not null comment '规格id',
createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
isDelete tinyint default 0 not null comment '是否删除',
index idx_dishesId (dishesId),
index idx_specificationsId (specificationsId)
) comment '菜品和规格的中间表' collate = utf8mb4_unicode_ci;
-- 规格表
create table if not exists specifications
(
id bigint auto_increment comment 'id' primary key,
businessId bigint not null comment '商家id',
specificationsName varchar(128) not null comment '规格名称',
createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
isDelete tinyint default 0 not null comment '是否删除',
index idx_businessId (businessId)
) comment '规格表' collate = utf8mb4_unicode_ci;
-- 属性表
create table if not exists attribute
(
id bigint auto_increment comment 'id' primary key,
businessId bigint not null comment '商家id',
specificationsId bigint not null comment '规格id',
attributeName varchar(128) not null comment '属性名称',
attributeStatus tinyint default 0 not null comment '属性状态:0在售,1停售',
createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
index idx_businessId (businessId)
) comment '属性表' collate = utf8mb4_unicode_ci;
-- 订单
-- 订单表
create table if not exists orders
(
id bigint auto_increment comment 'id' primary key,
pickupCode varchar(64) null comment '取餐码',
userName varchar(256) not null comment '姓名',
phone varchar(64) not null comment '手机号',
userId bigint not null comment '下单用户id',
businessId bigint not null comment '商家id',
errandId bigint null comment '跑腿id',
location varchar(256) null comment '配送地址',
totalPrice decimal(10, 2) not null comment '订单实际总价',
pickupMethod tinyint not null comment '取餐方式(0堂食 1自提)',
payMethod tinyint not null comment '支付方式0微信支付',
pickupTime datetime null comment '取餐时间',
notes varchar(128) null comment '备注',
state tinyint default 0 not null comment '订单状态: 0未支付 1已完成 2已退款 3已取消 4已出餐 5已完成',
createTime datetime default CURRENT_TIMESTAMP not null comment '下单时间',
updateTime datetime default CURRENT_TIMESTAMP not null comment '支付时间',
isDelete tinyint default 0 not null comment '是否删除',
index idx_businessId (businessId),
index idx_stateId (state)
) comment '订单表' collate = utf8mb4_unicode_ci;
-- 订单详情表
create table if not exists order_details
(
id bigint auto_increment comment 'id' primary key,
orderId bigint not null comment '关联的订单id',
dishesId bigint not null comment '关联的菜品id',
quantity int not null comment '购买数量',
price decimal(10, 2) not null comment '单价',
subtotal decimal(10, 2) not null comment '小计(单价 * 数量)',
attributeNames varchar(512) null comment '规格属性列表',
createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
isDelete tinyint default 0 not null comment '是否删除',
index idx_orderId (orderId)
) comment '订单详情表' collate = utf8mb4_unicode_ci;
-- 购物车表
create table if not exists cart
(
id bigint auto_increment comment 'id' primary key,
userId bigint not null comment '用户id',
businessId bigint not null comment '商家id',
createTime datetime default CURRENT_TIMESTAMP not null comment '加入购物车时间',
updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
dishesId bigint null comment '菜品id',
quantity int default 1 not null comment '商品数量',
price decimal(10, 2) not null comment '当前选择规格的价格',
subtotal decimal(10, 2) as ((`price` * `quantity`)) stored comment '小计(单价 * 数量)',
selectedOptions varchar(512) default '' not null comment '已选规格属性列表',
isDelete tinyint default 0 not null comment '是否删除',
index idx_userId (userId),
index idx_businessId (businessId)
) comment '购物车表' collate = utf8mb4_unicode_ci;
create table demo
(
id int auto_increment primary key,
name varchar(30) comment '姓名',
detail varchar(256) comment '详情'
);
-- 系统信息表
create table if not exists systemInfo
(
id bigint auto_increment comment 'id' primary key,
type tinyint not null comment '类型:0公告,1轮播图',
content varchar(256) not null comment '功能内容',
createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间'
) comment '系统信息' collate = utf8mb4_unicode_ci;
-- 聊天记录表
create table private_message
(
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'
) comment '收藏';
-- 用户评分表
create table user_rating
(
id bigint auto_increment comment 'id' primary key,
ratedEntityId bigint not null comment '评分对象的ID商家 跑腿',
userId bigint not null comment '用户id',
orderId bigint not null comment '订单id',
rating tinyint not null comment '评分',
review varchar(512) null comment '评论',
businessReview varchar(512) null comment '商家回复',
createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间'
) comment '用户评分' collate = utf8mb4_unicode_ci;
-- 商家等级表
create table business_level
(
id bigint auto_increment primary key comment 'id',
businessId bigint not null comment '商家id',
averageScore DECIMAL(3, 2) not null default 0 comment '综合评分',
level tinyint not null comment '等级',
createTime DATETIME default CURRENT_TIMESTAMP comment '创建时间',
updateTime DATETIME default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP comment '更新时间'
);
-- 系统信息表
create table if not exists businessInfo
(
id bigint auto_increment comment 'id' primary key,
businessId bigint not null comment '商家id',
content varchar(256) not null comment '功能内容',
createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间'
) comment '系统信息' collate = utf8mb4_unicode_ci;
-- 跑腿表
create table if not exists errand
(
id bigint auto_increment comment 'id' primary key,
userId bigint not null comment '用户id',
errandName varchar(256) not null comment '跑腿姓名',
errandAvatarUrl varchar(256) default 'http://154.8.193.216:9494/system/0/MRiFcIbr-R.jpg' comment '跑腿头像',
gender tinyint not null comment '性别',
phone varchar(128) not null comment '手机号',
distributionScope tinyint not null comment '配送范围',
totalOrders tinyint default 0 not null comment '接单量',
maxOrders tinyint default 15 not null comment '最大接单量',
totalPrice decimal(10, 2) default 0.00 not null comment '总金额',
state tinyint default 0 not null comment '审核状态 0-未审核 1-审核通过',
createTime DATETIME default CURRENT_TIMESTAMP comment '创建时间',
updateTime DATETIME default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP comment '更新时间',
isDelete tinyint default 0 not null comment '是否删除'
) comment '跑腿' collate = utf8mb4_unicode_ci;
-- 跑腿认证表
create table if not exists errand_auth
(
id bigint auto_increment primary key comment 'id',
errandId bigint not null comment '跑腿id',
bankCard varchar(64) not null comment '银行卡号',
frontIdCard varchar(1024) not null comment '身份证正面',
backIdCard varchar(1024) not null comment '身份证反面',
healthCertificate varchar(1024) null comment '健康证',
certificateStartTime datetime null comment '健康证开始时间',
certificateEndTime datetime null comment '健康证结束时间',
createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
isDelete tinyint default 0 not null comment '逻辑删除'
) comment '跑腿认证' collate = utf8mb4_unicode_ci;
-- 跑腿等级表
create table if not exists errand_level
(
id bigint auto_increment primary key comment 'id',
errandId bigint not null comment '跑腿Id',
averageScore DECIMAL(3, 2) not null default 0 comment '综合评分',
level tinyint not null comment '等级',
createTime DATETIME default CURRENT_TIMESTAMP comment '创建时间',
updateTime DATETIME default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP comment '更新时间'
) comment '跑腿等级' collate = utf8mb4_unicode_ci;
create table if not exists errand_income
(
id bigint auto_increment primary key comment 'id',
errandId bigint not null comment '跑腿id',
orderId bigint not null comment '订单id',
income decimal(10, 2) default 0 comment '综合评分',
state tinyint default 0 not null comment '0未结算 1已结算 2已提现',
createTime datetime default CURRENT_TIMESTAMP comment '创建时间'
) comment '跑腿收入' collate = utf8mb4_unicode_ci;
create table if not exists errand_order
(
id bigint auto_increment primary key comment 'id',
orderId bigint not null comment '订单ID',
errandState tinyint default 0 null comment '跑腿状态: 0无跑腿 1待抢单 2待取货 3待送达 4已送达 5再次抢单',
startTime datetime null comment '送餐开始时间',
endTime datetime null comment '送餐结束时间',
errandId bigint null comment '跑腿员ID',
createTime datetime default current_timestamp not null comment '任务创建时间',
updateTime datetime default current_timestamp not null on update current_timestamp comment '任务更新时间',
isDelete tinyint default 0 not null comment '是否删除'
) comment '跑腿任务表' collate = utf8mb4_unicode_ci;
create table if not exists order_image
(
orderId bigint auto_increment primary key comment 'id',
imageAddress varchar(256) not null comment '外卖地址'
) comment '外卖图片' collate = utf8mb4_unicode_ci;
create table if not exists errand_bill
(
id bigint auto_increment primary key comment 'id',
orderId bigint not null comment '订单Id',
userPhone varchar(128) not null comment '用户手机号',
income decimal(3, 2) default 0 comment '综合评分',
errandState tinyint default 0 comment '收入状态0-待结算 1-已结算',
orderStartTime Date not null comment '订单创建时间'
) comment '跑腿账单表' collate = utf8mb4_unicode_ci;
create table order_refunds (
id bigint auto_increment primary key comment '退款申请ID',
orderId bigint not null unique comment '订单号,唯一标识',
userId bigint not null comment '用户ID',
reason varchar(255) default null comment '退款原因',
amount decimal(10,2) not null comment '退款金额',
status tinyint not null default 0 comment '退款状态0-待审核, 1-已同意, 2-已拒绝',
createTime timestamp default current_timestamp comment '申请时间',
updateTime timestamp default current_timestamp on update current_timestamp comment '更新时间',
index idx_order_id (orderId),
index idx_user_id (userId)
) comment='退款申请表' collate = utf8mb4_unicode_ci;

View File

@ -0,0 +1,31 @@
package com.bsz.school_send_back_end;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.filter.ForwardedHeaderFilter;
@MapperScan("com.bsz.school_send_back_end.mapper")
@SpringBootApplication
@EnableScheduling
public class UserCenterApplication {
public static void main(String[] args) {
SpringApplication.run(UserCenterApplication.class, args);
}
@Bean
public ChatMemory chatMemory(){
return new InMemoryChatMemory();
}
@Bean
public ForwardedHeaderFilter forwardedHeaderFilter() {
return new ForwardedHeaderFilter();
}
}

View File

@ -0,0 +1,21 @@
package com.bsz.school_send_back_end.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 权限校验
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthCheck {
/**
* 必须有某个角色
* @return
*/
String mustRole() default "";
}

View File

@ -0,0 +1,19 @@
package com.bsz.school_send_back_end.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 系统日志
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SystemLog {
/**
* 操作步骤
*/
String executeStep() default "";
}

View File

@ -0,0 +1,92 @@
package com.bsz.school_send_back_end.aop;
import com.bsz.school_send_back_end.annotation.AuthCheck;
import com.bsz.school_send_back_end.common.ErrorCode;
import com.bsz.school_send_back_end.contant.UserConstant;
import com.bsz.school_send_back_end.exception.BusinessException;
import com.bsz.school_send_back_end.model.domain.User;
import com.bsz.school_send_back_end.model.enums.UserRoleEnum;
import com.bsz.school_send_back_end.service.UserService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Arrays;
/**
* 权限校验 AOP
*/
@Aspect
@Component
public class AuthInterceptor {
@Resource
private UserService userService;
/**
* 执行拦截
*/
@Around("@annotation(authCheck)")
public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {
String mustRole = authCheck.mustRole();
RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
String uri = request.getRequestURI();
// ✅ 如果是 Swagger 或 OpenAPI 相关请求,直接放行
if (uri.startsWith("/v3/api-docs") || uri.contains("/swagger") || uri.contains("/swagger-ui")) {
return joinPoint.proceed(); // 直接放行
}
// 当前登录用户
User loginUser = userService.getLoginUser(request);
// 必须有该权限才通过
UserRoleEnum mustUserRoleEnum = UserRoleEnum.getEnumByValue(mustRole);
String userRole = loginUser.getUserRole();
// 如果被封号,直接拒绝
if (UserRoleEnum.BAN.equals(UserRoleEnum.getEnumByValue(userRole))) {
throw new BusinessException(ErrorCode.NO_AUTH);
}
// 必须有Boss权限
if (UserRoleEnum.BOSS.equals(mustUserRoleEnum)) {
if (!mustRole.equals(userRole)) {
throw new BusinessException(ErrorCode.NO_AUTH);
}
}
// 必须有管理员权限
if (UserRoleEnum.ADMIN.equals(mustUserRoleEnum)) {
if (!mustRole.equals(userRole) && !UserConstant.BOSS_ROLE.equals(userRole)) {
throw new BusinessException(ErrorCode.NO_AUTH);
}
}
// 必须有商家或管理员权限
if (UserRoleEnum.BUSINESS.equals(mustUserRoleEnum)) {
if (!Arrays.asList(mustRole, UserConstant.ADMIN_ROLE, UserConstant.BOSS_ROLE).contains(userRole)) {
throw new BusinessException(ErrorCode.NO_AUTH);
}
}
//
if (UserRoleEnum.ERRAND.equals(mustUserRoleEnum)) {
if (!Arrays.asList(mustRole, UserConstant.ADMIN_ROLE, UserConstant.BOSS_ROLE).contains(userRole)) {
throw new BusinessException(ErrorCode.NO_AUTH);
}
}
if (UserRoleEnum.USER.equals(mustUserRoleEnum)) {
if (!Arrays.asList(mustRole, UserConstant.ADMIN_ROLE, UserConstant.BOSS_ROLE).contains(userRole)) {
throw new BusinessException(ErrorCode.NO_AUTH);
}
}
// 通过权限校验,放行
return joinPoint.proceed();
}
}

View File

@ -0,0 +1,73 @@
package com.bsz.school_send_back_end.aop;
import com.bsz.school_send_back_end.annotation.SystemLog;
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.exception.ThrowUtils;
import com.bsz.school_send_back_end.model.domain.Systemlog;
import com.bsz.school_send_back_end.model.domain.User;
import com.bsz.school_send_back_end.service.SystemlogService;
import com.bsz.school_send_back_end.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
/**
* 日志AOP
*/
@Slf4j
@Aspect
@Component
public class SystemLogInterceptor {
@Resource
private UserService userService;
@Resource
private SystemlogService systemlogService;
/**
* 执行拦截
*/
@Around("@annotation(systemLog)")
public Object doInterceptor(ProceedingJoinPoint joinPoint, SystemLog systemLog) throws Throwable {
// 获取执行操作
String executeStep = systemLog.executeStep();
ThrowUtils.throwIf(StringUtils.isEmpty(executeStep), ErrorCode.PARAMS_ERROR);
//获取请求
RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
HttpServletRequest httpServletRequest = ((ServletRequestAttributes) requestAttributes).getRequest();
String uri = httpServletRequest.getRequestURI();
// ✅ 如果是 Swagger 或 OpenAPI 相关请求,直接放行
if (uri.startsWith("/v3/api-docs") || uri.contains("/swagger") || uri.contains("/swagger-ui")) {
return joinPoint.proceed(); // 直接放行
}
//获取登录用户
User loginUser = userService.getLoginUser(httpServletRequest);
//写入系统日志
Systemlog systemlog = new Systemlog();
systemlog.setUserId(loginUser.getId());
systemlog.setContent(executeStep);
systemlog.setIp(httpServletRequest.getRemoteHost());
boolean save = systemlogService.save(systemlog);
if (!save) {
log.error("操作日志写入失败,执行操作:" + executeStep);
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "操作日志写入失败");
}
// 放行
return joinPoint.proceed();
}
}

View File

@ -0,0 +1,42 @@
package com.bsz.school_send_back_end.common;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
@Data
@Schema(description = "通用返回对象")
public class BaseResponse<T> implements Serializable {
@Schema(description = "状态码例如200 表示成功")
private int code;
@Schema(description = "返回的数据内容")
private T data;
@Schema(description = "提示消息")
private String message;
@Schema(description = "错误描述")
private String description;
public BaseResponse(int code, T data, String message, String description) {
this.code = code;
this.data = data;
this.message = message;
this.description = description;
}
public BaseResponse(int code, T data, String message) {
this(code, data, message, "");
}
public BaseResponse(int code, T data) {
this(code, data, "", "");
}
public BaseResponse(ErrorCode errorCode) {
this(errorCode.getCode(), null , errorCode.getMessage(), errorCode.getDescription());
}
}

View File

@ -0,0 +1,49 @@
package com.bsz.school_send_back_end.common;
/**
* 错误码
*/
public enum ErrorCode {
SUCCESS(0, "ok", ""),
PARAMS_ERROR(40000, "请求参数错误", ""),
NULL_ERROR(40001, "请求数据为空", ""),
NOT_LOGIN(40100, "未登录", ""),
NO_AUTH(40101, "无权限", ""),
NOT_FOUND_ERROR(40400,"请求数据不存在",""),
FORBIDDEN_ERROR(40300, "禁止访问",""),
SYSTEM_ERROR(50000, "系统内部异常", ""),
OPERATION_ERROR(50001, "操作失败", "");
/**
* 状态码
*/
private final int code;
/**
* 状态码信息
*/
private final String message;
/**
* 状态码的详细描述
*/
private final String description;
ErrorCode(int code, String message, String description) {
this.code = code;
this.message = message;
this.description = description;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
public String getDescription() {
return description;
}
}

View File

@ -0,0 +1,68 @@
package com.bsz.school_send_back_end.common;
import com.bsz.school_send_back_end.common.BaseResponse;
import com.bsz.school_send_back_end.common.ErrorCode;
/**
* 返回工具类
*/
public class ResultUtils {
/**
* 成功
*
* @param data
* @param <T>
* @return
*/
public static <T> BaseResponse<T> success(T data) {
return new BaseResponse<>(0, data, "ok");
}
public static <T> BaseResponse<T> success(T data, String message) {
return new BaseResponse<>(0, data, message);
}
/**
* 失败
*
* @param errorCode
* @return
*/
public static BaseResponse error(ErrorCode errorCode) {
return new BaseResponse<>(errorCode);
}
/**
* 失败
*
* @param code
* @param message
* @param description
* @return
*/
public static BaseResponse error(int code, String message, String description) {
return new BaseResponse(code, null, message, description);
}
/**
* 失败
*
* @param errorCode
* @return
*/
public static BaseResponse error(ErrorCode errorCode, String message, String description) {
return new BaseResponse(errorCode.getCode(), null, message, description);
}
/**
* 失败
*
* @param errorCode
* @return
*/
public static BaseResponse error(ErrorCode errorCode, String description) {
return new BaseResponse(errorCode.getCode(), errorCode.getMessage(), description);
}
}

View File

@ -0,0 +1,66 @@
package com.bsz.school_send_back_end.config;
import com.bsz.school_send_back_end.model.domain.Dishes;
import com.bsz.school_send_back_end.model.domain.Orders;
import com.bsz.school_send_back_end.model.vo.BusinessVO;
import com.bsz.school_send_back_end.service.BusinessService;
import com.bsz.school_send_back_end.service.DishesService;
import com.bsz.school_send_back_end.service.LoggingService;
import com.bsz.school_send_back_end.service.OrdersService;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Description;
import java.util.List;
import java.util.function.Function;
@Configuration
public class AIConfig {
@Resource
private BusinessService businessService;
@Resource
private DishesService dishesService;
@Resource
private OrdersService ordersService;
@Bean
ChatClient chatClient(ChatClient.Builder builder, ChatMemory chatMemory) {
return builder.defaultSystem(
"""
你是食刻必达校快送小程序的助手,情谊轻松切愉快的语气与用户交流。
你可以给用户推荐一些商家和菜品
今天的日期是{current_date}。
请讲中文。
"""
)
.defaultAdvisors(
new PromptChatMemoryAdvisor(chatMemory),
new LoggingService()
)
.defaultFunctions("getBusinessByAI")
.build();
}
@Bean
@Description("推荐商家")
public Function<Void, List<BusinessVO>> getBusinessByAI() {
List<BusinessVO> allBusiness = businessService.findAllBusiness();
return unused -> allBusiness.stream()
.filter(businessVO -> businessVO.getLevel() == 5)
.toList();
}
// @Bean
// @Description("推荐菜品")
// public Function<Void, List<Dishes>> getDishesByAI() {
// new LocalTime
// }
}

View File

@ -0,0 +1,42 @@
package com.bsz.school_send_back_end.config;
import com.alipay.api.internal.util.AlipaySignature;
import org.springframework.context.annotation.Configuration;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class AliPayNotifyHandler {
public void aliPayNotifyUrl(HttpServletRequest request) {
// 将 HttpServletRequest 的参数转换为 Map<String, String>
Map<String, String> params = new HashMap<>();
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
String paramName = parameterNames.nextElement();
params.put(paramName, request.getParameter(paramName));
}
// 之后可以使用 params 进行业务处理
// 例如:
String alipayrsaPublicKey = "MIIBIjANBgKGhKiG9WOBAOEFAAOCAQ8AMIIBCgKCAOEAUQWP3y7DHD0Z+/K+TcGlki0/acP8";
try {
// 验证签名
boolean flag = AlipaySignature.rsaCheckV1(params, alipayrsaPublicKey, "UTF-8", "RSA2");
if (flag && "TRADE_SUCCESS".equals(params.get("trade_status"))) {
// 业务处理
System.out.println("success");
} else {
System.out.println("fail");
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("fail");
}
}
}

View File

@ -0,0 +1,39 @@
package com.bsz.school_send_back_end.config;
import com.alipay.api.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
public class AlipayClients {
//appid
public String appId = "2021004151684053";
//私钥
//上:沙箱公钥 下:支付宝公钥
// public String PublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3JKMG3clg/1MqewlIK/koEhiQiSLagckb/2/Dyvg+rJ2snGiAgzNvhvvc1GdVC+Xnn/P+U+2tAytyuvbOuhmGgNZjeObczJXpo/0D6LBdYDrg4PVMDxpStCxLUpaShHbc/l/IquaorBwd94UJxIPAbUQkUBCbo94mGbhDX+yU4FQ6k1yeUtn03jvZ3AY0BEHpenCxWKgr5S/CUAYEitMbi/r7extBy6f4FCR120NM7VaNEK1xpHbGHo6rDpyiAOR1lWFuiqOJ1hv14UL/SfOLlzvUZiiPysIxdNjycZyiyRvFRHP3n8GBAaJDm9vVHwDfgQ5s3Ig2ggBeYXkFHZqWwIDAQAB";
public String PublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1WYUUWEH+kW2pdYoBJa6j5G3iWe3uL/3L1QXPenzrp/NC1M9W/yvniJnAiYR4pdopZmlWfEm7FpHxbLaxxcXe0jTkspq9vv9vDldyXgKr13QZBJu4hD3w4QZNa+85paANXkfcVKXCpIh6sWTaW78lBE5p7Q0M6O26OCj/K3iPD7x4+KagqS5w9YYS8AXlQdsZPBh99bO3+KuQzcK4o4bFGI+ut4HLvd2IxdF5LwfjucloN6SRbU06vsDtpjtA+Oeoet5Y0CNfkpgbh7wvvNIbM6XEqMtfKCzevPaqRxwrFkS8WUQTMOaQbJXATbPQDt7MoWGujFd37lYz7ESQZed2wIDAQAB";
//公钥appPrivateKey
//上:沙箱私钥 下:支付宝私钥
// public String appPrivateKey = "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=";
public String appPrivateKey ="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCOoaURczOevheVDeG9tmdCZ+PSInYwCY+ak3Jcy5CG4wrbHHy30ejMv5jNnyX/iSyC3MYIfHQ2I5uxh7pO3QSiB8GpeM9Oy3bUCOtPVM8o7FJ+/pa6o0s25jmj+Lx6/Q4sAaDxhQPY8vUZdIitQyqNS4IVhDuIWAS1w3ngZWHhcbtCPrCk3wIJPCYbhHi8eTgCXTJ0TbJ/QR+Pj0SAiL46rwSRc9KB1alxL5RoTK4VWvdHlqbfowen6teQ6bo2W5UkUEP8kew6MH9a3QQZ3YdLKFHufSGMWk19Wh26CEsvnf/Mb6dnv6YzbmzZLtCHiKKvFN516peW8Exd9/EtJCu1AgMBAAECggEAPghReVhoL/cu3HXQIylsmXYDoIW6b0QJP8o25+Lk9bVTKF6oY24Y2MvPkkZQSWYIhNWuD0zJYi50bW7BecEoXawP7zwKtZNKGAfVB4i0HHFDo9XoCj4w3SyeDxGEL91VR5Bhxgj61mU8chi7xNc8b31SkzcSiUb2rXLZ091kB58/xtzQk2nZAhKhwms7gbX7qxm8+TWLRK9g4vWmsGVqbgFNj/sutqBURSeU/pHmW9PMqgcWvx6AwWWi+VgBUSoIgMnX7r7s6ZlgeDIgioii3JdCcr1nq39sVYPwFpwIe7a1DOCB58B+v2un1XoThC7ZNEcbwP5oYpUdFhSoxClrNQKBgQDJc/A1nz2yYiLUHUMJn2DhyTrOnCSclmowuzJVkyuo5gQPfZ3dTmjdPkM/fg09J3+zi3UCSwZd6dGMzJVHWooMniSiomZ/rY+o9SVTAJOjxt29N8jFN92b3fB43hbAWyBOuy4NMZMcr+4cADuqRHz2pKAeaALiZdpTbrTCzVXtqwKBgQC1QGS0sv8VU9fyBCyrYU4kQh8Fcvz0g6ObgUnHZi6UIL+Cy0/3JIGeIyvB/n47RF1wLUz4wykwW70e1qlMz7w21HM+DB8fVuzbO7SmQI3gDo024kQkWWGUhe3/w9ztzLF9ezleSN6wnrPeDbeMV+pURbsxIXA9xg7DYpZZ76ksHwKBgHQnF/oi7bTbpo88q/lxXq/wkaqtFuL+Sw378UKsD4Fb1j2ERTBj1Ey0aJvENyfqjVPddcKztWESvtL65pt0laI+0IrBLm4xiWJ2rmWUMIw+zn0aG/Wyh2Emb0+RZfbU0+TxQdUzn0nsGlMkw0IiKRcgxn2hpQAaj+6JJ0omkIPvAoGAZ2eGTKT17Cf6QgNprJiF6R+j7QruD11uoJABFHZSSoXoXGk7hMbZ/+sW0sUrJQrat93QVPeabxFXctmKmtzFBw7rdFGcC9gepvCIHnUju9jxbYdm0sn/ZqmF323RhAVMmUcMsqKmEWNpQFzZA4NAl7V0lxH5o/RzhbqgBk05WYcCgYEAny/umQs7+NYgwL/FztMJVljfQsGY81mhgrQyPhmg/7NiWmLodJtwQgSj3UitDVtUGhZRnuidO8P1XW0sUyDwc8xMLb+0qVxX4gMpM4J1B0UaIp+oPg7hCXeFGxkWQl8bPY0RFa3GOfT2/D63NpXqYw8Fe1lZWoIMz+PBdx0YN90=";
//应用证书
private String appCertPath;
//支付宝证书
private String alipayCertPath;
//支付宝根证书
private String alipayRootCertPath;
//回调地址
private String notify;
//字符集 签名
private String gateway = "https://openapi.alipay.com/gateway.do";
// 公私钥模式
@Bean
public AlipayClient alipayClient() throws AlipayApiException {
AlipayClient client = new DefaultAlipayClient(this.gateway, this.appId, this.appPrivateKey, AlipayConstants.FORMAT_JSON, AlipayConstants.CHARSET_UTF8, PublicKey, AlipayConstants.SIGN_TYPE_RSA2);
return client;
}
}

View File

@ -0,0 +1,28 @@
package com.bsz.school_send_back_end.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 全局跨域配置
*
*
* @author bsz
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 覆盖所有请求
registry.addMapping("/**")
// 允许发送 Cookie
.allowCredentials(true)
// 放行哪些域名(必须用 patterns否则 * 会和 allowCredentials 冲突)
.allowedOriginPatterns("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.exposedHeaders("*");
}
}

View File

@ -0,0 +1,28 @@
package com.bsz.school_send_back_end.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
/**
* Spring MVC Json 配置
*/
@JsonComponent
public class JsonConfig {
/**
* 添加 Long 转 json 精度丢失的配置
*/
@Bean
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
SimpleModule module = new SimpleModule();
module.addSerializer(Long.class, ToStringSerializer.instance);
module.addSerializer(Long.TYPE, ToStringSerializer.instance);
objectMapper.registerModule(module);
return objectMapper;
}
}

View File

@ -0,0 +1,25 @@
package com.bsz.school_send_back_end.config;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
/**
* @author xy
* Springdoc OpenAPI 配置
*
* http://localhost:6448/swagger-ui/index.html 接口文档地址
*/
@Configuration
@Profile({"dev", "test"}) // 版本控制访问
public class Knife4jConfig {
@Bean
public GroupedOpenApi defaultApi() {
return GroupedOpenApi.builder()
.group("xiaokuaisong")
.packagesToScan("com.bsz.school_send_back_end.controller") // 指定扫描的包路径
.build();
}
}

View File

@ -0,0 +1,27 @@
package com.bsz.school_send_back_end.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* MyBatis Plus 配置
*/
@Configuration
@MapperScan("com.bsz.school_send_back_end.mapper")
public class MyBatisPlusConfig {
/**
* 拦截器配置
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}

View File

@ -0,0 +1,98 @@
package com.bsz.school_send_back_end.config;
import com.bsz.school_send_back_end.contant.RabbitMQConstant;
import org.springframework.amqp.core.*;
import org.springframework.amqp.support.converter.DefaultClassMapper;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class RabbitMQConfig {
@Bean
public Queue topicQueue1() {
return QueueBuilder.durable(RabbitMQConstant.TOPIC_QUEUE1).build();
}
@Bean
public Queue topicQueue2() {
return QueueBuilder.durable(RabbitMQConstant.TOPIC_QUEUE2).build();
}
@Bean
public Queue orderReplyQueue() {
return QueueBuilder.durable(RabbitMQConstant.ORDER_REPLY_QUEUE).build();
}
@Bean
public Exchange topicExchange() {
return ExchangeBuilder.topicExchange(RabbitMQConstant.TOPIC_EXCHANGE).build();
}
@Bean
public Exchange responseExchange() {
return ExchangeBuilder.topicExchange(RabbitMQConstant.RESPONSE_EXCHANGE).build();
}
@Bean
public Binding topicBinding1() {
return BindingBuilder.bind(topicQueue1()).to(topicExchange()).with("topic.chat").noargs();
}
@Bean
public Binding topicBinding2() {
return BindingBuilder.bind(topicQueue2()).to(topicExchange()).with("topic.#").noargs();
}
@Bean
public Binding responseBinding() {
return BindingBuilder.bind(orderReplyQueue()).to(responseExchange()).with("response.#").noargs();
}
// /**
// * 声明一个 **延迟交换机**,类型必须为 `x-delayed-message`
// */
// @Bean
// public CustomExchange delayedExchange() {
// Map<String, Object> args = new HashMap<>();
// args.put("x-delayed-type", "direct"); // 交换机类型
// return new CustomExchange(RabbitMQConstant.DELAYED_EXCHANGE, "x-delayed-message", true, false, args);
// }
//
// /**
// * 声明队列
// */
// @Bean
// public Queue delayedQueue() {
// return new Queue(RabbitMQConstant.DELAYED_QUEUE, true);
// }
//
// /**
// * 绑定队列到延迟交换机
// */
// @Bean
// public Binding binding(Queue delayedQueue, CustomExchange delayedExchange) {
// return BindingBuilder.bind(delayedQueue).to(delayedExchange).with(RabbitMQConstant.DELAYED_ROUTING_KEY).noargs();
// }
@Bean
public MessageConverter jsonToMapMessageConverter() {
DefaultClassMapper defaultClassMapper = new DefaultClassMapper();
defaultClassMapper.setTrustedPackages("com.bsz.school_send_back_end.utils.MultiDelayMessage"); // trusted packages
Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
jackson2JsonMessageConverter.setClassMapper(defaultClassMapper);
return jackson2JsonMessageConverter;
}
@Bean
public MessageConverter messageConverter(){
return new Jackson2JsonMessageConverter();
}
}

View File

@ -0,0 +1,16 @@
package com.bsz.school_send_back_end.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "spring.rabbitmq")
@Data
public class RabbitMQConfigProperties {
private String host;
private int port;
private String username;
private String password;
private String virtualHost;
}

View File

@ -0,0 +1,30 @@
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.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisSessionRepositoryConfig {
@Bean("springSessionRedisSerializer")
public RedisSerializer<Object> getRedisSerializer()
{
return new GenericJackson2JsonRedisSerializer();
}
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate redisTemplate = new RedisTemplate<>();
//设置redis的连接工厂对象
redisTemplate.setConnectionFactory(redisConnectionFactory);
//设置redis key的序列化器
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
return redisTemplate;
}
}

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,18 @@
package com.bsz.school_send_back_end.contant;
/**
* 通用常量
*/
public interface CommonConstant {
/**
* 升序
*/
String SORT_ORDER_ASC = "ascend";
/**
* 降序
*/
String SORT_ORDER_DESC = " descend";
}

View File

@ -0,0 +1,24 @@
package com.bsz.school_send_back_end.contant;
/**
* 文件常量
*/
@SuppressWarnings("all")
public interface FileConstant {
/**
* COS 访问地址
*/
String COS_HOST = "xxxxxxxxxxxxxxxxxxxx";
/**
* 服务器访问地址
*/
String SERVER_HOST = "https://xiaoshitong.xyz";
/**
* 服务器上传路径
*/
String SERVER_UPLOAD_DIR = "/www/wwwroot/images";
}

View File

@ -0,0 +1,84 @@
package com.bsz.school_send_back_end.contant;
import java.util.List;
public interface RabbitMQConstant {
/**
* 聊天
*/
String TOPIC_QUEUE1 = "topic.chat";
/**
* 商家
*/
String TOPIC_QUEUE2 = "topic.order";
/**
* 跑腿
*/
String TOPIC_QUEUE3 = "topic.errand";
/**
* 交换机
*/
String TOPIC_EXCHANGE = "topicExchage";
/**
* 请求响应交换机,用于处理用户和商家之间的异步响应
*/
String RESPONSE_EXCHANGE = "responseExchange";
/**
* 订单响应队列,商家处理完成订单后,可以发送响应消息到这个队列
*/
String ORDER_REPLY_QUEUE = "orderReplyQueue";
// // 交换机名称
// String DELAYED_EXCHANGE = "delayed.exchange";
// // 队列名称
// String DELAYED_QUEUE = "delayed.queue";
// // 路由键
// String DELAYED_ROUTING_KEY = "delayed.routingKey";
// List<Long> DELAY_MILLIS = List.of(10000L, 10000L, 10000L, 15000L, 15000L, 30000L, 30000L, 60000L, 60000L, 120000L, 300000L, 600000L, 600000L));
// 堂食订单取消3分钟
List<Long> DINE_IN_DELAY_MILLIS = List.of(30000L, 30000L, 30000L, 30000L, 30000L, 30000L);
// 外卖订单退款30分钟多次检查
List<Long> DELIVERY_DELAY_MILLIS = List.of(600000L, 1200000L, 1800000L);
// 取消订单相关常量
String CANCEL_ORDER_EXCHANGE = "cancel_order_exchange"; // 取消订单交换机
String CANCEL_ORDER_QUEUE = "cancel_order_queue"; // 取消订单队列
String CANCEL_ORDER_ROUTING_KEY = "cancel_order_key"; // 取消订单路由键
// 外卖单相关常量
String DELIVERY_DELAY_EXCHANGE = "delivery_exchange"; // 外卖单交换机
String DELIVERY_ORDER_QUEUE = "delivery_queue"; // 外卖单队列
String DELIVERY_ORDER_ROUTING_KEY = "delivery_key"; // 外卖单路由键
// String DELAY_COUPON_QUEUE = "coupon.delay.queue";
//
// String DELAY_COUPON_ROUTING_KEY = "coupon.key";
//
// String DELAY_USER_COUPON_QUEUE = "userCoupon.delay.queue";
//
// String DELAY_USER_COUPON_ROUTING_KEY = "userCoupon.key";
//
// String DELAY_ADVANCE_ORDER_QUEUE = "advanceOrder.delay.queue";
//
// String DELAY_ADVANCE_ROUTING_KEY = "advanceOrder.key";
//
// String DELAY_CLOTHES_RENT_ORDER_QUEUE = "clothesRentOrder.delay.queue";
//
// String DELAY_CLOTHES_RENT_ORDER_ROUTING_KEY = "clothesRentOrder.key";
//
// String DELAY_CLOTHES_RENT_PERIOD_QUEUE = "clothesRentPeriod.delay.queue";
//
// String DELAY_CLOTHES_RENT_PERIOD_ROUTING_KEY = "clothesRentPeriod.key";
//
}

View File

@ -0,0 +1,17 @@
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";
String APPNAME = "appName";
}

View File

@ -0,0 +1,32 @@
package com.bsz.school_send_back_end.contant;
/**
* 正则表达式常量
*/
@SuppressWarnings("all")
public interface RegexConstant {
/**
* 手机号正则
*/
String PHONE_REGEX = "^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\\d{8}$";
/**
* 邮箱正则
*/
String EMAIL_REGEX = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$";
/**
* 18位身份证号正则
*/
String ID_CARD_REGEX = "^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9xX]$";
/**
* 验证码正则, 6位数字或字母
*/
String VERIFY_CODE_REGEX = "^[a-zA-Z\\d]{6}$";
/**
* 密码正则。4~32位的字母、数字、下划线
*/
String PASSWORD_REGEX = "^\\w{4,32}$";
}

View File

@ -0,0 +1,37 @@
package com.bsz.school_send_back_end.contant;
/**
* 系统日志通用常量
*/
public interface SystemLogConstant {
/**
* 添加菜品
*/
String ADD_DISHES = "添加菜品";
/**
* 删除菜品
*/
String DELETE_DISHES = "删除菜品";
/**
* 修改菜品
*/
String UPDATE_DISHES = "修改菜品";
/**
* 删除菜品分组
*/
String ADD_DISHES_GROUP = "添加菜品分组";
/**
* 删除菜品分组
*/
String DELETE_DISHES_GROUP = "删除菜品分组";
/**
* 修改菜品分组
*/
String UPDATE_DISHES_GROUP = "修改菜品分组";
}

View File

@ -0,0 +1,84 @@
package com.bsz.school_send_back_end.contant;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Set;
import static java.util.Map.entry;
/**
* 用户常量
*/
public interface UserConstant {
/**
* 盐值
*/
String USER_SALT = "bsz";
// ------- 权限 --------
/**
* 默认角色
*/
String DEFAULT_ROLE = "user";
/**
* 商家角色
*/
String BUSINESS_ROLE = "business";
/**
* 管理员角色
*/
String ADMIN_ROLE = "admin";
/**
* 跑腿角色
*/
String ERRAND_ROLE = "errand";
/**
* Boss
*/
String BOSS_ROLE = "boss";
/**
* 被封号
*/
String BAN_ROLE = "ban";
/**
* 配送地址
*/
Set<String> VALID_LOCATIONS = Set.of("1公寓", "2公寓", "3公寓","4公寓","5公寓","6公寓",
"7公寓","8公寓","9公寓","10公寓","11公寓","12公寓","育才大厦");
/**
* 公寓配送费
*/
Map<String, BigDecimal> DELIVERY_FEE_MAP = Map.ofEntries(
entry("1公寓", new BigDecimal("1.7")),
entry("2公寓", new BigDecimal("1.7")),
entry("11公寓", new BigDecimal("1.7")),
entry("12公寓", new BigDecimal("1.7")),
entry("5公寓", new BigDecimal("1.2")),
entry("6公寓", new BigDecimal("1.2")),
entry("7公寓", new BigDecimal("1.2")),
entry("3公寓", new BigDecimal("2.3")),
entry("4公寓", new BigDecimal("2.3")),
entry("9公寓", new BigDecimal("2.3")),
entry("10公寓", new BigDecimal("2.3")),
entry("8公寓", new BigDecimal("2.3")),
entry("育才大厦", new BigDecimal("2.5"))
);
/**
* 默认等级
*/
int DEFAULT_LEVEL = 1;
/**
* 默认平均分
*/
double DEFAULT_AVG_SCORE = 1.0;
}

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

@ -0,0 +1,34 @@
package com.bsz.school_send_back_end.controller;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import java.time.LocalDate;
@Tag(name = "ai接口")
@RestController
@RequestMapping("/ai")
public class AIController {
@Resource
private ChatClient chatClient;
@GetMapping(value = "/chat/generateStreamAsString", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> generateStreamAsString(@RequestParam(value = "message", defaultValue = "介绍自己") String message) {
Flux<String> content = this.chatClient.prompt()
.system(promptSystemSpec -> promptSystemSpec.param("current_date", LocalDate.now().toString()))
.advisors(advisorSpec -> advisorSpec.param(AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY,100))
.user(message)
.stream()
.content();
return content.concatWith(Flux.just("[complete]"));
}
}

View File

@ -0,0 +1,72 @@
package com.bsz.school_send_back_end.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bsz.school_send_back_end.annotation.AuthCheck;
import com.bsz.school_send_back_end.common.BaseResponse;
import com.bsz.school_send_back_end.common.ResultUtils;
import com.bsz.school_send_back_end.contant.UserConstant;
import com.bsz.school_send_back_end.model.domain.Errand;
import com.bsz.school_send_back_end.model.domain.ErrandBill;
import com.bsz.school_send_back_end.model.domain.OrderRefunds;
import com.bsz.school_send_back_end.model.domain.Orders;
import com.bsz.school_send_back_end.service.ErrandBillService;
import com.bsz.school_send_back_end.service.ErrandService;
import com.bsz.school_send_back_end.service.OrdersService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;
@Tag(name = "跑腿流水接口")
@RestController
@RequestMapping("/bill")
@Slf4j
public class BillController {
@Resource
private ErrandService errandService;
@Resource
private ErrandBillService billService;
@Resource
private OrdersService ordersService;
/**
* 跑腿查询自己的账单
* @param request 网路请求
* @return 账单列表
*/
@PostMapping("/list")
@AuthCheck(mustRole = UserConstant.ERRAND_ROLE)
public BaseResponse<List<ErrandBill>> listBillByErrand(HttpServletRequest request) {
Errand loginErrand = errandService.getLoginErrand(request);
LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Orders::getErrandId, loginErrand.getId());
List<Orders> ordersList = ordersService.list(wrapper);
// 如果订单列表为空,直接返回空结果
if (ordersList.isEmpty()) {
return ResultUtils.success(Collections.emptyList());
}
List<Long> orderIds = ordersList.stream()
.map(Orders::getId)
.collect(Collectors.toList());
LambdaQueryWrapper<ErrandBill> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(ErrandBill::getOrderId, orderIds);
queryWrapper.orderByDesc(ErrandBill::getOrderStartTime);// 按 orderStartTime 降序排序
List<ErrandBill> bills = billService.list(queryWrapper);
return ResultUtils.success(bills);
}
}

View File

@ -0,0 +1,246 @@
package com.bsz.school_send_back_end.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsz.school_send_back_end.annotation.AuthCheck;
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.contant.UserConstant;
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.Business;
import com.bsz.school_send_back_end.model.domain.BusinessAuth;
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.business.BusinessAddRequest;
import com.bsz.school_send_back_end.model.dto.business.BusinessQueryRequest;
import com.bsz.school_send_back_end.model.dto.business.BusinessUpdateMyRequest;
import com.bsz.school_send_back_end.model.dto.business.BusinessUpdateRequest;
import com.bsz.school_send_back_end.model.vo.BusinessAdminVO;
import com.bsz.school_send_back_end.model.vo.BusinessVO;
import com.bsz.school_send_back_end.service.BusinessAuthService;
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.service.UserService;
import io.swagger.v3.oas.annotations.tags.Tag;
import jdk.jfr.Timestamp;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
import static com.bsz.school_send_back_end.contant.UserConstant.DEFAULT_ROLE;
import static com.bsz.school_send_back_end.contant.UserConstant.USER_SALT;
/**
* 商家接口
*/
@Tag(name = "商家接口")
@Slf4j
@RestController
@RequestMapping("/business")
public class BusinessController {
@Resource
private BusinessService businessService;
@Resource
private BusinessAuthService businessAuthService;
@Resource
private UserService userService;
@Resource
private CollectService collectService;
@PostMapping("/add")
public BaseResponse<Long> addBusiness(@RequestBody BusinessAddRequest businessAddRequest) {
ThrowUtils.throwIf(businessAddRequest == null,ErrorCode.PARAMS_ERROR);
User user = new User();
BeanUtils.copyProperties(businessAddRequest, user);
Business business = new Business();
BeanUtils.copyProperties(businessAddRequest, business);
BusinessAuth businessAuth = new BusinessAuth();
BeanUtils.copyProperties(businessAddRequest, businessAuth);
//对每个应该校验的业务进行校验
userService.validUser(user, true);
businessService.validBusiness(business, true);
businessService.validBusinessAuth(businessAuth, true);
//加密
String encryptPassword = DigestUtils.md5DigestAsHex((USER_SALT + user.getUserPassword()).getBytes());
user.setUserPassword(encryptPassword);
//更改用户权限为商家
user.setUserRole("business");
//往user表中补充商家信息
user.setUsername(business.getBusinessName());
user.setAvatarUrl(business.getBusinessAvatar());
user.setPhone(business.getBusinessPhone());
//插入到表中
businessService.addBusiness(user, business, businessAuth);
return ResultUtils.success(business.getId(),"添加商家成功");
}
/**
* 管理员更新商家
*/
@PostMapping("/update")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Boolean> updateBusiness (@RequestBody BusinessUpdateRequest businessUpdateRequest) {
if (businessUpdateRequest == null || businessUpdateRequest.getId() == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "传入参数为空");
}
Business business = new Business();
BeanUtils.copyProperties(businessUpdateRequest, business);
//更新不添加 只需要判断修改符不符合逻辑
businessService.validBusiness(business, false);
boolean updateById = businessService.updateById(business);
ThrowUtils.throwIf(!updateById, ErrorCode.OPERATION_ERROR);
return ResultUtils.success(true);
}
/**
* 商家更新个人信息
*/
@PostMapping("/update/my")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
public BaseResponse<Boolean> updateMyBusiness (@RequestBody BusinessUpdateMyRequest businessUpdateMyRequest, HttpServletRequest request) {
if (businessUpdateMyRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
// 获取当前登录商家信息
Business loginBusiness = businessService.getLoginBusiness(request);
ThrowUtils.throwIf(loginBusiness == null, ErrorCode.NOT_FOUND_ERROR);
Business business = new Business();
business.setId(loginBusiness.getId());
business.setUserId(loginBusiness.getUserId());
BeanUtils.copyProperties(businessUpdateMyRequest, business);
// 校验
businessService.validBusiness(business, false);
// 修改商家信息
boolean updateBusiness = businessService.updateById(business);
ThrowUtils.throwIf(!updateBusiness, ErrorCode.OPERATION_ERROR, "修改商家信息失败");
// 修改用户信息
User loginUser = userService.getById(loginBusiness.getUserId());
if (StringUtils.isNotBlank(business.getBusinessName())) {
loginUser.setUsername(business.getBusinessName());
}
if (StringUtils.isNotBlank(business.getBusinessPhone())) {
loginUser.setPhone(business.getBusinessPhone());
}
boolean updateUser = userService.updateById(loginUser);
ThrowUtils.throwIf(!updateUser, ErrorCode.OPERATION_ERROR, "修改用户信息失败");
return ResultUtils.success(true);
}
/**
* 根据id查询
*/
@GetMapping("/getById")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<BusinessAdminVO> getBusinessById(@RequestParam Long id) {
if (id <= 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Business business = businessService.getById(id);
ThrowUtils.throwIf(business == null , ErrorCode.NULL_ERROR);
BusinessAdminVO businessAdminVO = businessAuthService.getBusinessAdminVO(business);
return ResultUtils.success(businessAdminVO);
}
/**
* 根据当前登录用户获取商家信息
*/
@PostMapping("/get/current")
public BaseResponse<BusinessVO> getByBusiness (HttpServletRequest request) {
Business loginBusiness = businessService.getLoginBusiness(request);
BusinessVO businessVO = businessService.getBusinessVO(loginBusiness);
return ResultUtils.success(businessVO);
}
/**
* 查询所有商家
*/
@PostMapping("/list")
public BaseResponse<List<BusinessVO>> listBusinessAll(){
List<BusinessVO> business = businessService.findAllBusiness();
return new BaseResponse<>(0,business,"查询成功");
}
/**
* 分页查询
*/
@PostMapping("/list/page")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Page<Business>> listBusinessByPage (@RequestBody BusinessQueryRequest businessQueryRequest) {
Page<Business> businessPage = businessService.page(new Page<>(businessQueryRequest.getCurrent(), businessQueryRequest.getPageSize()),
businessService.getQueryWrapper(businessQueryRequest));
return ResultUtils.success(businessPage);
}
/**
* 分页获取商家列表(用户视图)
*/
@PostMapping("/list/page/vo")
public BaseResponse<Page<BusinessVO>> listBusinessVOByPage(@RequestBody BusinessQueryRequest businessQueryRequest) {
long current = businessQueryRequest.getCurrent();
long size = businessQueryRequest.getPageSize();
ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
QueryWrapper<Business> queryWrapper = businessService.getQueryWrapper(businessQueryRequest);
Page<Business> businessPage = businessService.page(new Page<>(current, size), queryWrapper);
Page<BusinessVO> businessVOPage = new Page<>(current, size, businessPage.getTotal());
List<BusinessVO> businessVOList = businessService.getBusinessVO(businessPage.getRecords());
businessVOPage.setRecords(businessVOList);
return ResultUtils.success(businessVOPage);
}
@GetMapping("/my/getById")
@AuthCheck(mustRole = DEFAULT_ROLE)
public BaseResponse<BusinessVO> getBusinessVO (@RequestParam Long businessId, HttpServletRequest request) {
User loginUser = userService.getLoginUser(request);
LambdaQueryWrapper<Business> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Business::getId, businessId);
long count = businessService.count(queryWrapper);
ThrowUtils.throwIf(count != 1, ErrorCode.PARAMS_ERROR, "商家id不正确");
Business business = businessService.getOne(queryWrapper);
BusinessVO businessVO = businessService.getBusinessVO(business);
long collect = collectService.count(Wrappers.<Collect>lambdaQuery()
.eq(Collect::getUserId, loginUser.getId())
.eq(Collect::getBusinessId, businessId));
businessVO.setIsCollected(collect > 0);
return ResultUtils.success(businessVO);
}
}

View File

@ -0,0 +1,150 @@
package com.bsz.school_send_back_end.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bsz.school_send_back_end.annotation.AuthCheck;
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.contant.UserConstant;
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.Business;
import com.bsz.school_send_back_end.model.domain.Businessinfo;
import com.bsz.school_send_back_end.model.dto.CommonRequest;
import com.bsz.school_send_back_end.model.dto.businessinfo.InfoAddRequest;
import com.bsz.school_send_back_end.model.dto.businessinfo.InfoQueryRequest;
import com.bsz.school_send_back_end.service.BusinessService;
import com.bsz.school_send_back_end.service.BusinessinfoService;
import com.github.houbb.sensitive.word.core.SensitiveWordHelper;
import io.swagger.v3.oas.annotations.tags.Tag;
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 jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
@Tag(name = "商家公告接口")
@RestController
@Slf4j
@RequestMapping("/businessInfo")
public class BusinessInfoController {
@Resource
private BusinessinfoService businessinfoService;
@Resource
private BusinessService businessService;
/**
* 添加公告
* @param addRequest 添加请求体
* @param request 网络请求
* @return 是否添加成功
*/
@PostMapping("/add")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
public BaseResponse<Boolean> addInfo (@RequestBody InfoAddRequest addRequest, HttpServletRequest request) {
if ( addRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Business loginBusiness = businessService.getLoginBusiness(request);
Businessinfo businessinfo = new Businessinfo();
String content = addRequest.getContent();
boolean contains = SensitiveWordHelper.contains(content);
ThrowUtils.throwIf(contains, ErrorCode.PARAMS_ERROR, "公告含有违禁词");
BeanUtils.copyProperties(addRequest, businessinfo);
businessinfo.setBusinessId(loginBusiness.getId());
boolean save = businessinfoService.save(businessinfo);
ThrowUtils.throwIf(!save, ErrorCode.SYSTEM_ERROR, "添加公告失败");
return ResultUtils.success(true);
}
/**
* 删除公告
* @param commonRequest 删除请求体
* @param request 网络请求
* @return 是否成功
*/
@PostMapping("/delete")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
public BaseResponse<Boolean> deleteInfo (@RequestBody CommonRequest commonRequest, HttpServletRequest request) {
if (commonRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Business loginBusiness = businessService.getLoginBusiness(request);
Long businessId = loginBusiness.getId();
Long id = commonRequest.getId();
LambdaQueryWrapper<Businessinfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Businessinfo::getId, id);
queryWrapper.eq(Businessinfo::getBusinessId, businessId);
long count = businessinfoService.count(queryWrapper);
ThrowUtils.throwIf(count != 1, ErrorCode.SYSTEM_ERROR, "当前公告未找到");
boolean remove = businessinfoService.remove(queryWrapper);
ThrowUtils.throwIf(!remove, ErrorCode.SYSTEM_ERROR, "删除失败");
return ResultUtils.success(true);
}
/**
* 查询公告列表 (仅商家)
* @param request 网络请求
* @return 查询列表
*/
@PostMapping("/list/my")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
public BaseResponse<List<Businessinfo>> selectMyInfo (HttpServletRequest request) {
Business loginBusiness = businessService.getLoginBusiness(request);
Long businessId = loginBusiness.getId();
LambdaQueryWrapper<Businessinfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Businessinfo::getBusinessId, businessId);
queryWrapper.orderByDesc(Businessinfo::getCreateTime);
List<Businessinfo> list = businessinfoService.list(queryWrapper);
return ResultUtils.success(list, "查询成功");
}
/**
* 查询公列表(仅管理员, 分页)
* @param infoQueryRequest 查询请求体
* @return 查询列表
*/
@PostMapping("/list/page")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Page<Businessinfo>> selectInfoByPage (@RequestBody InfoQueryRequest infoQueryRequest) {
if (infoQueryRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
long current = infoQueryRequest.getCurrent();
long pageSize = infoQueryRequest.getPageSize();
QueryWrapper<Businessinfo> queryWrapper = businessinfoService.getQueryWrapper(infoQueryRequest);
Page<Businessinfo> page = businessinfoService.page(new Page<>(current, pageSize), queryWrapper);
return ResultUtils.success(page, "查询成功");
}
/**
* 用户查询商家最新公告
* @return 查询列表
*/
@PostMapping("/list")
public BaseResponse<Businessinfo> selectInfo (@RequestBody CommonRequest commonRequest) {
if (commonRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long businessId = commonRequest.getId();
LambdaQueryWrapper<Businessinfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Businessinfo::getBusinessId, businessId);
queryWrapper.orderByDesc(Businessinfo::getCreateTime);
queryWrapper.last("LIMIT 1");
Businessinfo businessinfo = businessinfoService.getOne(queryWrapper);
return ResultUtils.success(businessinfo, "查询成功");
}
}

View File

@ -0,0 +1,184 @@
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.Cart;
import com.bsz.school_send_back_end.model.domain.User;
import com.bsz.school_send_back_end.model.dto.cart.CartAddRequest;
import com.bsz.school_send_back_end.model.dto.cart.CartDeleteRequest;
import com.bsz.school_send_back_end.model.dto.cart.CartQueryRequest;
import com.bsz.school_send_back_end.model.dto.cart.CartUpdateRequest;
import com.bsz.school_send_back_end.model.vo.CartVO;
import com.bsz.school_send_back_end.service.CartService;
import com.bsz.school_send_back_end.service.UserService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
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 jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
@Tag(name = "购物车接口")
@RestController
@Slf4j
@RequestMapping("/cart")
public class CartController {
@Resource
private CartService cartService;
@Resource
private UserService userService;
/**
* 添加剂购物车
* @param cartAddRequest 添加请求
* @param request 网络请求
* @return 购物车id
*/
@PostMapping("/add")
@Transactional(rollbackFor = Exception.class)
public BaseResponse<Long> addCart (@RequestBody CartAddRequest cartAddRequest, HttpServletRequest request) {
if (cartAddRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
//校验
cartService.validCart(cartAddRequest);
//添加菜品到购物车
Long cart = cartService.addCart(cartAddRequest, request);
return ResultUtils.success(cart);
}
/**
* 更新购物车
* @param cartUpdateRequest 更新请求
* @param request 网络请求
* @return 是否成功
*/
@PostMapping("/update")
@Transactional(rollbackFor = Exception.class)
public BaseResponse<Boolean> updateCart (@RequestBody CartUpdateRequest cartUpdateRequest, HttpServletRequest request){
if (cartUpdateRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
//校验
CartAddRequest cartAddRequest = new CartAddRequest();
BeanUtils.copyProperties(cartUpdateRequest,cartAddRequest);
cartService.validCart(cartAddRequest);
Boolean cart = cartService.updateCart(cartUpdateRequest, request);
return ResultUtils.success(cart);
}
/**
* 删除购物车
* @param cartDeleteRequest 删除请求
* @param request 网络请求
* @return 是否成功
*/
@PostMapping("/delete")
@Transactional(rollbackFor = Exception.class)
public BaseResponse<Boolean> deleteCart (@RequestBody CartDeleteRequest cartDeleteRequest, HttpServletRequest request) {
if (cartDeleteRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long id = cartDeleteRequest.getId();
Boolean cart = cartService.deleteCart(id, request);
ThrowUtils.throwIf(!cart, ErrorCode.OPERATION_ERROR);
return ResultUtils.success(true);
}
/**
* 根据商户id获取购物车脱敏列表
* @param cartQueryRequest 商户id
* @param request 网络请求
* @return 脱敏列表
*/
@PostMapping("/selectByBusinessId")
public BaseResponse<List<CartVO>> selectByBusinessId (@RequestBody CartQueryRequest cartQueryRequest, HttpServletRequest request) {
if (cartQueryRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long businessId = cartQueryRequest.getId();
User loginUser = userService.getLoginUser(request);
Long userId = loginUser.getId();
LambdaQueryWrapper<Cart> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Cart::getBusinessId, businessId);
queryWrapper.eq(Cart::getUserId, userId);
List<Cart> cartList = cartService.list(queryWrapper);
List<CartVO> cartVOList = cartService.getCartVOList(cartList);
return ResultUtils.success(cartVOList);
}
/**
* 根据用户查找购物车列表
* @param request 网络请求
* @return 脱敏列表
*/
@PostMapping("/selectByUserId")
public BaseResponse<List<CartVO>> selectByUserId (HttpServletRequest request) {
User loginUser = userService.getLoginUser(request);
Long userId = loginUser.getId();
LambdaQueryWrapper<Cart> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Cart::getUserId, userId);
List<Cart> cartList = cartService.list(wrapper);
List<CartVO> cartVOList = cartService.getCartVOList(cartList);
return ResultUtils.success(cartVOList);
}
/**
* 清空商家内的购物车
* @param cartQueryRequest 商家id
* @param request 网络请求
* @return 是否成功
*/
@PostMapping("/empty/business")
public BaseResponse<Boolean> emptyBusinessCart(@RequestBody CartQueryRequest cartQueryRequest, HttpServletRequest request) {
if (cartQueryRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long businessId = cartQueryRequest.getId();
User loginUser = userService.getLoginUser(request);
Long userId = loginUser.getId();
LambdaQueryWrapper<Cart> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Cart::getBusinessId, businessId);
queryWrapper.eq(Cart::getUserId, userId);
boolean remove = cartService.remove(queryWrapper);
ThrowUtils.throwIf(!remove, ErrorCode.OPERATION_ERROR);
return ResultUtils.success(true);
}
/**
* 清空用户购物车
* @param request 网络请求
* @return 是否成功
*/
@PostMapping("/empty/user")
public BaseResponse<Boolean> emptyUserCart(HttpServletRequest request) {
User loginUser = userService.getLoginUser(request);
Long userId = loginUser.getId();
LambdaQueryWrapper<Cart> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Cart::getUserId, userId);
boolean remove = cartService.remove(queryWrapper);
ThrowUtils.throwIf(!remove, ErrorCode.OPERATION_ERROR);
return ResultUtils.success(true);
}
}

View File

@ -0,0 +1,120 @@
package com.bsz.school_send_back_end.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bsz.school_send_back_end.annotation.AuthCheck;
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.contant.UserConstant;
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.Business;
import com.bsz.school_send_back_end.model.domain.Category;
import com.bsz.school_send_back_end.model.dto.category.CategoryAddRequest;
import com.bsz.school_send_back_end.model.dto.category.CategoryDeleteRequest;
import com.bsz.school_send_back_end.model.dto.category.CategoryUpdateRequest;
import com.bsz.school_send_back_end.service.BusinessService;
import com.bsz.school_send_back_end.service.CategoryService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import java.util.List;
@Tag(name = "餐厅接口")
@Slf4j
@RestController
@RequestMapping("/category")
public class CategoryController {
@Resource
private CategoryService categoryService;
@Resource
private BusinessService businessService;
/**
* 添加类别
* @param categoryAddRequest 添加请求体
* @return 是否成功
*/
@PostMapping("/add")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Long> addCategory (@RequestBody CategoryAddRequest categoryAddRequest) {
if (categoryAddRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Category category = new Category();
BeanUtils.copyProperties(categoryAddRequest, category);
categoryService.validCategory(category, true);
boolean save = categoryService.save(category);
ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR);
Long id = category.getId();
return ResultUtils.success(id,"添加成功");
}
/**
* 修改类别
* @param categoryUpdateRequest 修改请求体
* @return 返回修改后类别
*/
@PostMapping("/update")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Category> updateCategory (@RequestBody CategoryUpdateRequest categoryUpdateRequest) {
if (categoryUpdateRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Category category = new Category();
BeanUtils.copyProperties(categoryUpdateRequest, category);
categoryService.validCategory(category, false);
boolean update = categoryService.updateById(category);
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "操作失败");
return new BaseResponse<>(0,category,"修改成功");
}
/**
* 根据id删除
* @param categoryDeleteRequest 删除请求体
* @return 是否成功
*/
@PostMapping("/delete")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Boolean> deleteCategory (@RequestBody CategoryDeleteRequest categoryDeleteRequest) {
if (categoryDeleteRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
LambdaQueryWrapper<Business> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Business::getCategoryId, categoryDeleteRequest.getId());
long count = businessService.count(wrapper);
ThrowUtils.throwIf(count > 0, ErrorCode.OPERATION_ERROR, "该分类下拥有商家");
boolean remove = categoryService.removeById(categoryDeleteRequest.getId());
return ResultUtils.success(remove);
}
/**
* 根据id查询分类
*/
@GetMapping("/getById")
public BaseResponse<Category> getCategoryById (long id) {
if (id <= 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Category category = categoryService.getById(id);
ThrowUtils.throwIf(category == null, ErrorCode.NOT_FOUND_ERROR);
return ResultUtils.success(category);
}
/**
* 查询类别
*/
@GetMapping("/list")
public BaseResponse<List<Category>> listCategoryAll() {
List<Category> categoryList = categoryService.list();
return ResultUtils.success(categoryList);
}
}

View File

@ -0,0 +1,102 @@
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.model.vo.CollectVO;
import com.bsz.school_send_back_end.service.CollectService;
import com.bsz.school_send_back_end.service.UserService;
import io.swagger.v3.oas.annotations.tags.Tag;
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 jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
@Tag(name = "收藏接口")
@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, HttpServletRequest request) {
if (commonRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long id = commonRequest.getId();
User loginUser = userService.getLoginUser(request);
Long userId = loginUser.getId();
LambdaQueryWrapper<Collect> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Collect::getUserId, userId);
wrapper.eq(Collect::getBusinessId, 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<CollectVO>> listCollect(HttpServletRequest request) {
List<CollectVO> collectList = collectService.getCollectList(request);
if (collectList == null) {
collectList = new ArrayList<>();
}
return ResultUtils.success(collectList);
}
}

View File

@ -0,0 +1,209 @@
package com.bsz.school_send_back_end.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsz.school_send_back_end.annotation.AuthCheck;
import com.bsz.school_send_back_end.annotation.SystemLog;
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.contant.SystemLogConstant;
import com.bsz.school_send_back_end.contant.UserConstant;
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.Business;
import com.bsz.school_send_back_end.model.domain.Dishes;
import com.bsz.school_send_back_end.model.dto.Dishes.DishesAddRequest;
import com.bsz.school_send_back_end.model.dto.Dishes.DishesDeleteRequest;
import com.bsz.school_send_back_end.model.dto.Dishes.DishesQueryRequest;
import com.bsz.school_send_back_end.model.dto.Dishes.DishesUpdateRequest;
import com.bsz.school_send_back_end.model.vo.DishesVO;
import com.bsz.school_send_back_end.service.BusinessService;
import com.bsz.school_send_back_end.service.DishesService;
import com.bsz.school_send_back_end.service.SpecificationsDishesService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
@Tag(name = "菜品接口")
@Slf4j
@RestController
@RequestMapping("/dishes")
public class DishesController {
@Resource
private DishesService dishesService;
@Resource
private BusinessService businessService;
@Resource
private SpecificationsDishesService specificationsDishesService;
/**
*添加菜品
* @param dishesAddRequest 添加菜品请求体
* @return 是否成功
*/
@PostMapping("/add")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
@Transactional(rollbackFor = Exception.class)
@SystemLog(executeStep = SystemLogConstant.ADD_DISHES)
public BaseResponse<Boolean> addDishes (@RequestBody DishesAddRequest dishesAddRequest, HttpServletRequest request) {
if (dishesAddRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Dishes dishes = new Dishes();
BeanUtils.copyProperties(dishesAddRequest,dishes);
//校验
dishesService.validDishes(dishes,false);
//添加商家id
Business loginBusiness = businessService.getLoginBusiness(request);
Long businessId = loginBusiness.getId();
dishes.setBusinessId(businessId);
//保存菜品信息
Long dishesId = dishesService.addDishes(dishes);
//中间表中添加数据
List<Long> specificationsIds = dishesAddRequest.getSpecificationsIds();
specificationsDishesService.add(dishesId,specificationsIds);
return ResultUtils.success(true);
}
/**
* 删除菜品
* @param dishesDeleteRequest 删除请求
* @param request 网络请求
* @return 是否成功
*/
@PostMapping("/delete")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
@Transactional(rollbackFor = Exception.class)
@SystemLog(executeStep = SystemLogConstant.DELETE_DISHES)
public BaseResponse<Boolean> deleteDishes(@RequestBody DishesDeleteRequest dishesDeleteRequest,HttpServletRequest request) {
if (dishesDeleteRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long dishesId = dishesDeleteRequest.getId();
//获取商家id
Business business = businessService.getLoginBusiness(request);
Long businessId = business.getId();
//校验菜品是不是当前登录商家的
LambdaQueryWrapper<Dishes> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Dishes::getId, dishesId);
wrapper.eq(Dishes::getBusinessId, businessId);
Dishes dishes = dishesService.getOne(wrapper);
ThrowUtils.throwIf(dishes == null, ErrorCode.OPERATION_ERROR, "当前商家无权限删除该菜品");
//删除菜品
boolean dishesRemove = dishesService.removeById(dishesId);
ThrowUtils.throwIf(!dishesRemove, ErrorCode.OPERATION_ERROR);
//删除中间表信息
specificationsDishesService.deleteByDishesId(dishesId);
return ResultUtils.success(true);
}
/**
* 更新菜品
* @param dishesUpdateRequest 更新请求
* @param request 网络请求
* @return 是否成功
*/
@PostMapping("/update")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
@Transactional(rollbackFor = Exception.class)
@SystemLog(executeStep = SystemLogConstant.UPDATE_DISHES)
public BaseResponse<Boolean> updateDishes (@RequestBody DishesUpdateRequest dishesUpdateRequest, HttpServletRequest request) {
if (dishesUpdateRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Dishes dishes = new Dishes();
BeanUtils.copyProperties(dishesUpdateRequest, dishes);
//校验
dishesService.validDishes(dishes, true);
//添加商家id
Business loginBusiness = businessService.getLoginBusiness(request);
Long businessId = loginBusiness.getId();
dishes.setBusinessId(businessId);
//更新菜品
Boolean updateDishes = dishesService.updateDishes(dishes);
ThrowUtils.throwIf(!updateDishes, ErrorCode.OPERATION_ERROR);
//更新中间表的信息
Long dishesId = dishes.getId();
List<Long> specificationsIds = dishesUpdateRequest.getSpecificationsIds();
return ResultUtils.success(specificationsDishesService.updateByDishesId(dishesId, specificationsIds));
}
/**
* 更新菜品状态
* @param dishesUpdateRequest 菜品请求体
* @param request 前端请求
* @return 是否成功
*/
@PostMapping("/update/status")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
@SystemLog(executeStep = SystemLogConstant.UPDATE_DISHES)
public BaseResponse<Boolean> updateDishesStatus (@RequestBody DishesUpdateRequest dishesUpdateRequest, HttpServletRequest request) {
Long id = dishesUpdateRequest.getId();
String status = dishesUpdateRequest.getStatus();
if (id == null || StringUtils.isBlank(status)) {
throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "请补全参数");
}
//获取商家id
Business loginBusiness = businessService.getLoginBusiness(request);
Long businessId = loginBusiness.getId();
//更新状态
LambdaUpdateWrapper<Dishes> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(Dishes::getId, id);
wrapper.eq(Dishes::getBusinessId, businessId);
wrapper.set(Dishes::getStatus, status);
return ResultUtils.success(dishesService.update(wrapper));
}
/**
*获取菜品脱敏列表
* @param dishesQueryRequest 查询请求体
* @return 脱敏列表
*/
@PostMapping("/list/dishes")
public BaseResponse<List<Dishes>> dishesList(@RequestBody DishesQueryRequest dishesQueryRequest) {
Long businessId = dishesQueryRequest.getBusinessId();
if (businessId == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
//获取查询条件
QueryWrapper<Dishes> wrapper = dishesService.getWrapper(dishesQueryRequest);
//根据查询条件该商家的所有菜品
List<Dishes> list = dishesService.list(wrapper);
//获取菜品脱敏列表
return ResultUtils.success(list);
}
/**
*获取菜品脱敏列表
* @param dishesQueryRequest 查询请求体
* @return 分页列表
*/
@PostMapping("/list/page/dishesVO")
public BaseResponse<Page<DishesVO>> dishesVOPage(@RequestBody DishesQueryRequest dishesQueryRequest) {
long current = dishesQueryRequest.getCurrent();
long pageSize = dishesQueryRequest.getPageSize();
//获取查询条件
QueryWrapper<Dishes> wrapper = dishesService.getWrapper(dishesQueryRequest);
//获取商家多有菜品
Page<Dishes> dishesPage = dishesService.page(new Page<>(current, pageSize), wrapper);
//获取脱敏信息列表
List<Dishes> dishesList = dishesPage.getRecords();
long total = dishesPage.getTotal();
List<DishesVO> dishesVOList = dishesService.getDishesVOList(dishesList);
Page<DishesVO> dishesVOPage = new Page<>(current, pageSize, total);
dishesVOPage.setRecords(dishesVOList);
return ResultUtils.success(dishesVOPage);
}
}

View File

@ -0,0 +1,158 @@
package com.bsz.school_send_back_end.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bsz.school_send_back_end.annotation.AuthCheck;
import com.bsz.school_send_back_end.annotation.SystemLog;
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.contant.SystemLogConstant;
import com.bsz.school_send_back_end.contant.UserConstant;
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.Business;
import com.bsz.school_send_back_end.model.domain.Dishes;
import com.bsz.school_send_back_end.model.domain.DishesGroup;
import com.bsz.school_send_back_end.model.dto.DishesGroup.DishesGroupAddRequest;
import com.bsz.school_send_back_end.model.dto.DishesGroup.DishesGroupDeleteRequest;
import com.bsz.school_send_back_end.model.dto.DishesGroup.DishesGroupQueryRequest;
import com.bsz.school_send_back_end.model.dto.DishesGroup.DishesGroupUpdateRequest;
import com.bsz.school_send_back_end.service.BusinessService;
import com.bsz.school_send_back_end.service.DishesGroupService;
import com.bsz.school_send_back_end.service.DishesService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
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 jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
@Tag(name = "菜品分组接口")
@Slf4j
@RestController
@RequestMapping("/dishesGroup")
public class DishesGroupController {
@Resource
private BusinessService businessService;
@Resource
private DishesGroupService dishesGroupService;
@Resource
private DishesService dishesService;
/**
* 添加菜品分组
* @param dishesGroupAddRequest 添加请求
* @param request 网络请求
* @return 是否成功
*/
@PostMapping("/add")
@Transactional(rollbackFor = Exception.class)
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
@SystemLog(executeStep = SystemLogConstant.ADD_DISHES_GROUP)
public BaseResponse<Boolean> addDishesGroup(@RequestBody DishesGroupAddRequest dishesGroupAddRequest, HttpServletRequest request) {
if (dishesGroupAddRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
}
DishesGroup dishesGroup = new DishesGroup();
BeanUtils.copyProperties(dishesGroupAddRequest,dishesGroup);
//校验请求体
dishesGroupService.validDishesGroup(dishesGroup,false);
//添加分组
Boolean result = dishesGroupService.addDishesGroup(dishesGroup, request);
ThrowUtils.throwIf(!result,ErrorCode.OPERATION_ERROR);
return ResultUtils.success(true);
}
/**
* 删除菜品分组
* @param dishesGroupDeleteRequest 删除请求
* @param request 网络请求
* @return 是否成功
*/
@PostMapping("/delete")
@Transactional(rollbackFor = Exception.class)
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
@SystemLog(executeStep = SystemLogConstant.DELETE_DISHES_GROUP)
public BaseResponse<Boolean> deleteDishesGroup (@RequestBody DishesGroupDeleteRequest dishesGroupDeleteRequest, HttpServletRequest request) {
if (dishesGroupDeleteRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long id = dishesGroupDeleteRequest.getId();
//获取商家id
Business loginBusiness = businessService.getLoginBusiness(request);
Long businessId = loginBusiness.getId();
// 校验分组是否为当前商家的分组
QueryWrapper<DishesGroup> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id",id);
queryWrapper.eq("businessId",businessId);
DishesGroup dishesGroup = dishesGroupService.getOne(queryWrapper);
ThrowUtils.throwIf(dishesGroup == null,ErrorCode.OPERATION_ERROR,"当前商家无权删除该分组");
//删除分组
boolean byId = dishesGroupService.removeById(id);
ThrowUtils.throwIf(!byId,ErrorCode.OPERATION_ERROR);
//检查分组下是否有菜品
LambdaQueryWrapper<Dishes> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Dishes::getDishesGroupId, id);
long count = dishesService.count(wrapper);
ThrowUtils.throwIf(count > 0, ErrorCode.OPERATION_ERROR, "该分组下还有菜品");
//删除该分组的菜品以及中检表
dishesService.removeByDishesGroupId(id);
return ResultUtils.success(true);
}
/**
* 更行菜品分组
* @param dishesGroupUpdateRequest 更新请求
* @param request 网轮廓请求
* @return 是否成功
*/
@PostMapping("/update")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
@SystemLog(executeStep = SystemLogConstant.UPDATE_DISHES_GROUP)
public BaseResponse<Boolean> updateDishesGroup (@RequestBody DishesGroupUpdateRequest dishesGroupUpdateRequest,HttpServletRequest request){
if (dishesGroupUpdateRequest == null) {
throw new BusinessException(ErrorCode.OPERATION_ERROR);
}
DishesGroup dishesGroup = new DishesGroup();
BeanUtils.copyProperties(dishesGroupUpdateRequest,dishesGroup);
//校验
dishesGroupService.validDishesGroup(dishesGroup,true);
//更新菜品分组信息
Boolean result = dishesGroupService.updateDishesGroupById(dishesGroup, request);
ThrowUtils.throwIf(!result,ErrorCode.OPERATION_ERROR);
return ResultUtils.success(true);
}
/**
* 查询菜品分组脱敏列表
* @param dishesGroupQueryRequest 菜品分组请求体
* @return 脱敏列表
*/
@PostMapping("/list/dishesGroup")
public BaseResponse<List<DishesGroup>> dishesGroupList (@RequestBody DishesGroupQueryRequest dishesGroupQueryRequest){
//获取商家id
Long businessId = dishesGroupQueryRequest.getBusinessId();
Business business = businessService.getById(businessId);
if (business == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR,"该商家不存在");
}
//查询商家菜品分组信息
QueryWrapper<DishesGroup> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("businessId",businessId);
List<DishesGroup> list = dishesGroupService.list(queryWrapper);
// 获取菜品分组脱敏列表
return ResultUtils.success(list);
}
}

View File

@ -0,0 +1,108 @@
package com.bsz.school_send_back_end.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsz.school_send_back_end.annotation.AuthCheck;
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.contant.UserConstant;
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.Errand;
import com.bsz.school_send_back_end.model.domain.ErrandAuth;
import com.bsz.school_send_back_end.model.dto.errandAtuh.ErrandAuthAddRequest;
import com.bsz.school_send_back_end.model.dto.errandAtuh.ErrandAuthQueryRequest;
import com.bsz.school_send_back_end.service.ErrandAuthService;
import com.bsz.school_send_back_end.service.ErrandService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
@Tag(name = "快送员认证接口")
@Slf4j
@RestController
@RequestMapping("/errandAuth")
public class ErrandAuthController {
@Resource
private ErrandAuthService errandAuthService;
@Resource
private ErrandService errandService;
@PostMapping("/add")
public BaseResponse<Boolean> addErrandAuth(@RequestBody ErrandAuthAddRequest addRequest) {
if (addRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long errandId = addRequest.getErrandId();
LambdaQueryWrapper<ErrandAuth> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ErrandAuth::getErrandId, errandId);
long count = errandAuthService.count(queryWrapper);
ThrowUtils.throwIf(count > 0, ErrorCode.PARAMS_ERROR, "当前跑腿已认证");
ErrandAuth errandAuth = new ErrandAuth();
BeanUtils.copyProperties(addRequest, errandAuth);
errandAuthService.validErrandAuth(errandAuth,true);
boolean save = errandAuthService.save(errandAuth);
ThrowUtils.throwIf(!save, ErrorCode.SYSTEM_ERROR, "添加跑腿认证失败");
return ResultUtils.success(true);
}
@PostMapping("/update")
@AuthCheck(mustRole = UserConstant.ERRAND_ROLE)
public BaseResponse<Boolean> updateErrandAuth (@RequestBody ErrandAuthAddRequest updateRequest) {
if (updateRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
ErrandAuth errandAuth = new ErrandAuth();
BeanUtils.copyProperties(updateRequest, errandAuth);
errandAuthService.validErrandAuth(errandAuth, false);
LambdaUpdateWrapper<ErrandAuth> wrapper = errandAuthService.getUpdateWrapper(errandAuth);
boolean update = errandAuthService.update(wrapper);
ThrowUtils.throwIf(!update, ErrorCode.SYSTEM_ERROR, "更新跑腿认证信息失败");
return ResultUtils.success(true);
}
@PostMapping("/list/page")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Page<ErrandAuth>> listErrandAuthByPage(@RequestBody ErrandAuthQueryRequest errandAuthQueryRequest) {
if (errandAuthQueryRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
long pageSize = errandAuthQueryRequest.getPageSize();
long current = errandAuthQueryRequest.getCurrent();
QueryWrapper<ErrandAuth> queryWrapper = errandAuthService.getQueryWrapper(errandAuthQueryRequest);
Page<ErrandAuth> page = errandAuthService.page(new Page<>(current, pageSize),queryWrapper);
return ResultUtils.success(page);
}
@GetMapping("/getErrandAuthById")
public BaseResponse<ErrandAuth> getErrandAuthById (String errandId) {
Long errandId1 = Long.valueOf(errandId);
ErrandAuth errandAuth = errandAuthService.getErrandAuth(errandId1);
return ResultUtils.success(errandAuth);
}
@PostMapping("/get/my")
public BaseResponse<ErrandAuth> getMyErrandAuth (HttpServletRequest request) {
Errand loginErrand = errandService.getLoginErrand(request);
Long id = loginErrand.getId();
LambdaQueryWrapper<ErrandAuth> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ErrandAuth::getErrandId, id);
ErrandAuth errandAuth = errandAuthService.getOne(queryWrapper);
ThrowUtils.throwIf(errandAuth == null, ErrorCode.OPERATION_ERROR, "当前跑腿为认证");
return ResultUtils.success(errandAuth);
}
}

View File

@ -0,0 +1,325 @@
package com.bsz.school_send_back_end.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsz.school_send_back_end.annotation.AuthCheck;
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.contant.UserConstant;
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.*;
import com.bsz.school_send_back_end.model.dto.CommonRequest;
import com.bsz.school_send_back_end.model.dto.errand.ErrandAddRequest;
import com.bsz.school_send_back_end.model.dto.errand.ErrandQueryRequest;
import com.bsz.school_send_back_end.model.dto.errand.ErrandStateRequest;
import com.bsz.school_send_back_end.model.dto.errand.ErrandUpdateRequest;
import com.bsz.school_send_back_end.model.vo.ErrandVO;
import com.bsz.school_send_back_end.model.vo.OrdersVO;
import com.bsz.school_send_back_end.service.*;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
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 jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import static com.bsz.school_send_back_end.contant.UserConstant.*;
@Tag(name = "快送员接口")
@Slf4j
@RestController
@RequestMapping("/errand")
public class ErrandController {
@Resource
private ErrandService errandService;
@Resource
private UserService userService;
@Resource
private OrdersService ordersService;
@Resource
private ErrandAuthService errandAuthService;
@Resource
private ErrandOrderService errandOrderService;
/**
* 注册跑腿
* @param addRequest 注册请求体
* @return 是否成功
*/
@PostMapping("/add")
public BaseResponse<Boolean> addErrand(@RequestBody ErrandAddRequest addRequest) {
if (addRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
User user = new User();
Errand errand = new Errand();
BeanUtils.copyProperties(addRequest, user);
System.out.println("User account: " + user.getUserAccount());
BeanUtils.copyProperties(addRequest, errand);
userService.validUser(user, true);
errandService.validErrand(errand, true);
//加密
String encryptPassword = DigestUtils.md5DigestAsHex((USER_SALT + user.getUserPassword()).getBytes());
user.setUserPassword(encryptPassword);
//更改用户权限为跑腿
user.setUserRole("errand");
//往user表中补充跑腿信息
user.setUsername(errand.getErrandName());
user.setPhone(errand.getErrandPhone());
errandService.addErrand(user, errand);
return ResultUtils.success(true);
}
/**
* 删除跑腿信息
* @param request 当前登录用户
* @return 是否成功
*/
@PostMapping("/delete")
@AuthCheck(mustRole = UserConstant.ERRAND_ROLE)
@Transactional(rollbackFor = Exception.class)
public BaseResponse<Boolean> deleteErrand (HttpServletRequest request){
errandService.deleteErrand(request);
return ResultUtils.success(true);
}
/**
* 修改跑腿信息(管理员)
* @param updateRequest 修改请求体
* @return 是否修改成功
*/
@PostMapping("/update")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Boolean> updateErrand(@RequestBody ErrandUpdateRequest updateRequest) {
if (updateRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Boolean update = errandService.updateErrand(updateRequest);
ThrowUtils.throwIf(!update, ErrorCode.SYSTEM_ERROR,"更新跑腿失败");
return ResultUtils.success(true);
}
/**
* 修改跑腿信息(个人)
* @param updateRequest 修改请求体
* @param request 当前登录用户
* @return 是否修改成功
*/
@PostMapping("/update/my")
@AuthCheck(mustRole = UserConstant.ERRAND_ROLE)
public BaseResponse<Boolean> updateErrandByUser (@RequestBody ErrandUpdateRequest updateRequest, HttpServletRequest request ) {
if (updateRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Errand loginErrand = errandService.getLoginErrand(request);
Integer totalOrders = loginErrand.getTotalOrders();
ThrowUtils.throwIf(totalOrders > 0, ErrorCode.OPERATION_ERROR, "当前跑腿还有订单未送");
Boolean update = errandService.updateErrand(updateRequest);
Long errandId = loginErrand.getId();
Long id = updateRequest.getId();
ThrowUtils.throwIf(!id.equals(errandId), ErrorCode.PARAMS_ERROR, "修改的跑腿信息不是当前跑腿");
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "更新跑腿失败");
return ResultUtils.success(true);
}
/**
* 获取当前跑腿信息列表
* @return 跑腿信息列表
*/
@PostMapping("/list")
@AuthCheck(mustRole = ADMIN_ROLE)
public BaseResponse<List<Errand>> listErrand() {
List<Errand> list = errandService.list();
return ResultUtils.success(list);
}
/**
* 分页获取跑腿信息列表
* @param queryRequest 查询请求体
* @return 跑腿信息(分页)
*/
@PostMapping("/page")
@AuthCheck(mustRole = ADMIN_ROLE)
public BaseResponse<Page<Errand>> listErrandByPage (@RequestBody ErrandQueryRequest queryRequest) {
if (queryRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
long pageSize = queryRequest.getPageSize();
long current = queryRequest.getCurrent();
QueryWrapper<Errand> queryWrapper = errandService.getQueryWrapper(queryRequest);
Page<Errand> errandPage = errandService.page(new Page<>(current, pageSize), queryWrapper);
return ResultUtils.success(errandPage);
}
/**
* 抢单
* @param commonRequest 订单id
* @param request 当前登录用户
* @return 是否抢单成功
*/
@PostMapping("/get/order")
@AuthCheck(mustRole = UserConstant.ERRAND_ROLE)
@Transactional(rollbackFor = Exception.class)
public BaseResponse<Boolean> getOrder(@RequestBody CommonRequest commonRequest, HttpServletRequest request) {
if (commonRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long ordersId = commonRequest.getId();
Errand loginErrand = errandService.getLoginErrand(request);
Long loginErrandId = loginErrand.getId();
ErrandOrder errandOrder = errandOrderService.getOne(Wrappers.<ErrandOrder>lambdaQuery()
.eq(ErrandOrder::getOrderId, ordersId));
Integer state = loginErrand.getState();
if (state != 1) {
throw new BusinessException(ErrorCode.FORBIDDEN_ERROR, "当前跑腿不可抢单");
}
errandService.updateTotal(loginErrand, true);
// 开始事务
Orders orders = ordersService.getOrderWithPessimisticLock(ordersId);
// 判断订单是否已被抢
if (orders == null || orders.getErrandId() != null) {
return ResultUtils.success(false); // 订单已经被抢或不存在
}
// 更新订单的 errandId 和状态
orders.setErrandId(loginErrandId);
boolean update = ordersService.updateById(orders);
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "抢单失败");
errandOrder.setErrandId(loginErrandId);
errandOrder.setErrandState(2); // 2待取货
boolean update1 = errandOrderService.updateById(errandOrder);
ThrowUtils.throwIf(!update1, ErrorCode.OPERATION_ERROR, "更新跑腿订单关联失败");
return ResultUtils.success(true);
}
/**
* 修改订单
* @param errandStateRequest 订单id
* @param request 当前登录用户
* @return 是否修改成功
*/
@PostMapping("/update/state")
@AuthCheck(mustRole = ERRAND_ROLE)
public BaseResponse<Boolean> updateOrdersStateByErrand (@RequestBody ErrandStateRequest errandStateRequest, HttpServletRequest request) {
if (errandStateRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
errandService.orderToErrand(errandStateRequest, request);
return ResultUtils.success(true);
}
/**
* 根据当前登录用户获取跑腿信息
*/
@PostMapping("/get/current")
@AuthCheck(mustRole = ERRAND_ROLE)
public BaseResponse<ErrandVO> getByErrand (HttpServletRequest request) {
Errand loginErrand = errandService.getLoginErrand(request);
ErrandVO errandVO = errandService.getErrandVO(loginErrand);
return ResultUtils.success(errandVO);
}
/**
* 当前跑腿获取订单
*/
@PostMapping("/list/order")
@AuthCheck(mustRole = ERRAND_ROLE)
public BaseResponse<List<OrdersVO>> listOrdersByErrand(Integer errandState, HttpServletRequest request) {
Errand loginErrand = errandService.getLoginErrand(request);
String distributionScope = loginErrand.getDistributionScope();
// 创建 errand_order 表的查询条件
LambdaQueryWrapper<ErrandOrder> errandOrderQueryWrapper = new LambdaQueryWrapper<>();
errandOrderQueryWrapper.eq(ErrandOrder::getErrandState, errandState);
// 根据 errandState 的不同情况调整查询
if (errandState != 1) {
errandOrderQueryWrapper.eq(ErrandOrder::getErrandId, loginErrand.getId());
} else {
errandOrderQueryWrapper.isNull(ErrandOrder::getErrandId);
errandOrderQueryWrapper.ge(ErrandOrder::getEndTime, new Date());
}
// 查询符合条件的 errand_order 数据
List<ErrandOrder> errandOrderList = errandOrderService.list(errandOrderQueryWrapper);
// 获取符合条件的 orderId 列表
List<Long> orderIds = errandOrderList.stream().map(ErrandOrder::getOrderId).collect(Collectors.toList());
// 如果没有符合条件的订单,则返回空
if (orderIds.isEmpty()) {
return ResultUtils.success(Collections.emptyList());
}
// 查询 orders 表,获取相关订单信息
LambdaQueryWrapper<Orders> ordersQueryWrapper = new LambdaQueryWrapper<>();
ordersQueryWrapper.in(Orders::getId, orderIds);
ordersQueryWrapper.eq(Orders::getLocation, distributionScope);
// 获取订单数据
List<Orders> ordersList = ordersService.list(ordersQueryWrapper);
List<OrdersVO> ordersVO = ordersService.getOrdersVO(ordersList);
// 如果转换后的订单VO为空也返回空响应
if (CollectionUtils.isEmpty(ordersVO)) {
return ResultUtils.success(Collections.emptyList());
}
return ResultUtils.success(ordersVO);
}
/**
* 根据Id获取跑腿信息
* @return 跑腿信息
*/
@PostMapping("/get/id")
@AuthCheck(mustRole = ADMIN_ROLE)
public BaseResponse<ErrandVO> getErrandById (String errandId1) {
Long errandId = Long.valueOf(errandId1);
Errand errand = errandService.getOne(Wrappers.<Errand>lambdaQuery().eq(Errand::getId, errandId));
ThrowUtils.throwIf(errand == null, ErrorCode.PARAMS_ERROR, "当前跑腿id不正确");
ErrandVO errandVO = errandService.getErrandVO(errand);
ErrandAuth errandAuth = errandAuthService.getErrandAuth(errandId);
errandVO.setBackIdCard(errandAuth.getBackIdCard());
errandVO.setBankCard(errandAuth.getBankCard());
errandVO.setFrontIdCard(errandAuth.getFrontIdCard());
return ResultUtils.success(errandVO);
}
}

View File

@ -0,0 +1,137 @@
package com.bsz.school_send_back_end.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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;
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.contant.UserConstant;
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.Errand;
import com.bsz.school_send_back_end.model.domain.ErrandIncome;
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.erradnIncome.ErrandIncomeQueryRequest;
import com.bsz.school_send_back_end.service.ErrandIncomeService;
import com.bsz.school_send_back_end.service.ErrandService;
import com.bsz.school_send_back_end.service.UserService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
@Tag(name = "快送员收入接口")
@RestController
@Slf4j
@RequestMapping("/errandIncome")
public class ErrandIncomeController {
@Resource
private ErrandService errandService;
@Resource
private ErrandIncomeService errandIncomeService;
@Resource
private UserService userService;
@PostMapping("/count/number")
@AuthCheck(mustRole = UserConstant.ERRAND_ROLE)
public BaseResponse<Long> countIncomeNumber(HttpServletRequest request) {
Errand loginErrand = errandService.getLoginErrand(request);
LambdaQueryWrapper<ErrandIncome> queryWrapper = errandIncomeService.getQueryWrapper(loginErrand.getId());
long count = errandIncomeService.count(queryWrapper);
return ResultUtils.success(count);
}
@PostMapping("/count/money")
@AuthCheck(mustRole = UserConstant.ERRAND_ROLE)
public BaseResponse<BigDecimal> countIncomeMoney(HttpServletRequest request) {
Errand loginErrand = errandService.getLoginErrand(request);
LambdaQueryWrapper<ErrandIncome> queryWrapper = errandIncomeService.getQueryWrapper(loginErrand.getId());
queryWrapper.eq(ErrandIncome::getState, 1);
List<ErrandIncome> list = errandIncomeService.list(queryWrapper);
BigDecimal price = list.stream().map(ErrandIncome::getIncome).reduce(BigDecimal.ZERO, BigDecimal::add);
return ResultUtils.success(price);
}
@PostMapping("/count/total-money")
@AuthCheck(mustRole = UserConstant.ERRAND_ROLE)
public BaseResponse<BigDecimal> countTotalIncome(HttpServletRequest request) {
// 获取登录跑腿信息
Errand loginErrand = errandService.getLoginErrand(request);
// 从跑腿表直接获取总收入字段值
BigDecimal totalIncome = loginErrand.getTotalPrice();
// 返回结果
return ResultUtils.success(totalIncome);
}
@PostMapping("/list")
@AuthCheck(mustRole = UserConstant.ERRAND_ROLE)
public BaseResponse<List<ErrandIncome>> listErrandIncome(@RequestBody CommonRequest commonRequest, HttpServletRequest request) {
if (commonRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long errandId = commonRequest.getId();
User loginUser = userService.getLoginUser(request);
String userRole = loginUser.getUserRole();
if (userRole.equals(UserConstant.ERRAND_ROLE)) {
Errand loginErrand = errandService.getLoginErrand(request);
Long id = loginErrand.getId();
ThrowUtils.throwIf(!id.equals(errandId), ErrorCode.PARAMS_ERROR, "传输的跑腿id不正确");
}
LambdaQueryWrapper<ErrandIncome> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ErrandIncome::getErrandId, errandId);
List<ErrandIncome> list = errandIncomeService.list(queryWrapper);
if (list == null) {
list = new ArrayList<>();
}
return ResultUtils.success(list);
}
@PostMapping("/list/page")
@AuthCheck(mustRole = UserConstant.ERRAND_ROLE)
public BaseResponse<Page<ErrandIncome>> listErrandIncomeByPage(@RequestBody ErrandIncomeQueryRequest queryRequest) {
if (queryRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
long pageSize = queryRequest.getPageSize();
long current = queryRequest.getCurrent();
QueryWrapper<ErrandIncome> queryWrapper = errandIncomeService.getWrapper(queryRequest);
Page<ErrandIncome> page = errandIncomeService.page(new Page<>(current, pageSize), queryWrapper);
if (page == null) {
page = new Page<>();
}
return ResultUtils.success(page);
}
@PostMapping("/count/money/no")
@AuthCheck(mustRole = UserConstant.ERRAND_ROLE)
public BaseResponse<BigDecimal> countIncomeMoneyNo(HttpServletRequest request) {
Errand loginErrand = errandService.getLoginErrand(request);
LambdaQueryWrapper<ErrandIncome> queryWrapper = errandIncomeService.getQueryWrapper(loginErrand.getId());
queryWrapper.eq(ErrandIncome::getState, 0);
List<ErrandIncome> list = errandIncomeService.list(queryWrapper);
BigDecimal price = list.stream().map(ErrandIncome::getIncome).reduce(BigDecimal.ZERO, BigDecimal::add);
return ResultUtils.success(price);
}
}

View File

@ -0,0 +1,130 @@
package com.bsz.school_send_back_end.controller;
import cn.hutool.core.io.FileUtil;
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.contant.FileConstant;
import com.bsz.school_send_back_end.exception.BusinessException;
import com.bsz.school_send_back_end.model.domain.User;
import com.bsz.school_send_back_end.model.dto.file.UploadFileRequest;
import com.bsz.school_send_back_end.model.enums.FileUploadBizEnum;
import com.bsz.school_send_back_end.service.UserService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
/**
* 文件上传
*/
@Tag(name = "文件上传接口")
@Slf4j
@RestController
@RequestMapping("/file")
public class FileController {
@Resource
private UserService userService;
@PostMapping("/upload/server/not_login")
public BaseResponse<String> uploadServerNotLogin (@RequestPart("file")MultipartFile multipartFile, UploadFileRequest uploadFileRequest) {
//获取业务名称
String biz = uploadFileRequest.getBiz();
FileUploadBizEnum fileUploadBizEnum = FileUploadBizEnum.getEnumByValue(biz);
if (fileUploadBizEnum == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
//校验文件
validfile(multipartFile, fileUploadBizEnum);
//文件目录:根据业务,用户来划分
String uuid = RandomStringUtils.randomAlphabetic(8);
String fileName = uuid + "-" + multipartFile.getOriginalFilename();
String filePath = String.format("/%s/%s/%s", fileUploadBizEnum.getValue(), 0, fileName);
try {
//判断目录是否存在
File file = new File(FileConstant.SERVER_UPLOAD_DIR, filePath);
log.info("filepath:{}",file);
if (!file.exists()) {
boolean mkdirs = file.mkdirs();
if (!mkdirs) {
throw new BusinessException(ErrorCode.SYSTEM_ERROR,"创建目录失败");
}
}
multipartFile.transferTo(new File(FileConstant.SERVER_UPLOAD_DIR, filePath));
// 返回可访问地址
return ResultUtils.success(FileConstant.SERVER_HOST + filePath);
}
catch (IOException e) {
log.error("file upload error, filePath = " + filePath, e);
throw new BusinessException(ErrorCode.SYSTEM_ERROR,"上传失败");
}
}
@PostMapping("/upload/server")
public BaseResponse<String> uploadServerFile(@RequestPart("file") MultipartFile multipartFile, UploadFileRequest uploadFileRequest, HttpServletRequest request) {
// 获取业务名称
String biz = uploadFileRequest.getBiz();
FileUploadBizEnum fileUploadBizEnum = FileUploadBizEnum.getEnumByValue(biz);
if (fileUploadBizEnum == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "业务名称错误");
}
//校验文件
validfile(multipartFile,fileUploadBizEnum);
//校验用户是否登录
User loginUser = userService.getLoginUser(request);
if (loginUser == null) {
throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "未登录");
}
// 文件目录:根据业务、用户来划分
String uuid = RandomStringUtils.randomAlphabetic(8);
String fileName = uuid + "-" + multipartFile.getOriginalFilename();
String filePath = String.format("/%s/%s/%s", fileUploadBizEnum.getValue(), loginUser.getId(), fileName);
try {
File file = new File(FileConstant.SERVER_UPLOAD_DIR, filePath);
if (!file.exists()) {
//创建目录
boolean mkdirs = file.mkdirs();
if (!mkdirs) {
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "创建目录失败");
}
}
multipartFile.transferTo(new File(FileConstant.SERVER_UPLOAD_DIR,filePath));
//返回可访问的地址
return ResultUtils.success(FileConstant.SERVER_HOST + filePath);
}
catch (IOException e) {
log.error("file upload error, filepath = " + filePath, e);
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "上传失败");
}
}
/**
* 校验文件
*/
private void validfile(MultipartFile multipartFile, FileUploadBizEnum fileUploadBizEnum) {
//文件大小
long fileSize = multipartFile.getSize();
//文件后缀
String fileSuffix = FileUtil.getSuffix(multipartFile.getOriginalFilename());
final long TWO_M = 2*1024*1024L;
if (FileUploadBizEnum.USER_AVATAR.equals(fileUploadBizEnum)) {
if (fileSize > TWO_M) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件大小不能超过 2M");
}
if (!Arrays.asList("jpeg", "jpg", "svg", "png", "webp").contains(fileSuffix)) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件类型错误");
}
}
}
}

View File

@ -0,0 +1,629 @@
package com.bsz.school_send_back_end.controller;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsz.school_send_back_end.annotation.AuthCheck;
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.contant.CommonConstant;
import com.bsz.school_send_back_end.contant.UserConstant;
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.listener.RabbitMQSender;
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.*;
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;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
/**
* 订单相关接口
**/
@Tag(name = "订单相关接口")
@Slf4j
@RestController
@Tag(name = "订单接口")
@RequestMapping("/orders")
public class OrdersController {
@Resource
private UserService userService;
@Resource
private DishesService dishesService;
@Resource
private OrdersService ordersService;
@Resource
private BusinessService businessService;
@Resource
private OrderDetailsService orderDetailsService;
@Resource
private WebsocketService websocketService;
@Resource
private ErrandService errandService;
@Resource
private ErrandIncomeService errandIncomeService;
@Resource
private ErrandOrderService errandOrderService;
@Resource
private ErrandBillService billService;
@Resource
private RabbitMQSender rabbitMQSender;
/**
* 创建订单
*
* @return 订单id
*/
@PostMapping("/add")
public BaseResponse<Long> addOrders(@RequestBody OrderAddRequest orderAddRequest, HttpServletRequest request) {
if (orderAddRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
// 提取订单
Orders orders = new Orders();
User loginUser = userService.getLoginUser(request);
BeanUtils.copyProperties(orderAddRequest, orders);
orders.setUserId(loginUser.getId());
ordersService.validOrder(orders);
// 提取订单详情
List<OrderDetailAddRequest> detailAddRequest = orderAddRequest.getOrderDetailAddRequest();
List<OrderDetails> orderDetailsList = detailAddRequest.stream().map(item -> {
OrderDetails orderDetails = new OrderDetails();
BeanUtils.copyProperties(item, orderDetails);
orderDetailsService.validOrderDetail(orderDetails);
Long dishesId = orderDetails.getDishesId();
// 根据菜品设置价格
Dishes dishes = dishesService.getById(dishesId);
BigDecimal dishesPrice = BigDecimal.valueOf(dishes.getDishesPrice());
orderDetails.setPrice(dishesPrice);
double subtotal = dishes.getDishesPrice() * orderDetails.getQuantity();
orderDetails.setSubtotal(BigDecimal.valueOf(subtotal));
return orderDetails;
}).toList();
// 创建订单
long orderId = ordersService.addOrder(orders, orderDetailsList);
rabbitMQSender.sendCreateOrderMessage(orderId);
return ResultUtils.success(orderId, "订单创建成功");
}
/**
* 取消订单
*/
@PostMapping("/cancel")
public BaseResponse<Boolean> cancelOrder(@RequestBody CommonRequest commonRequest, HttpServletRequest request) {
Long orderId = commonRequest.getId();
if (orderId == null || orderId <= 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
// 校验订单
Orders orders = ordersService.getById(orderId);
ThrowUtils.throwIf(orders == null, ErrorCode.NOT_FOUND_ERROR);
ThrowUtils.throwIf(orders.getState() != 0, ErrorCode.OPERATION_ERROR, "订单状态错误");
// 判断是否为自己的订单
User loginUser = userService.getLoginUser(request);
if (!orders.getUserId().equals(loginUser.getId())) {
throw new BusinessException(ErrorCode.NO_AUTH);
}
// 修改订单状态
orders.setState(3);
boolean update = ordersService.updateById(orders);
ThrowUtils.throwIf(!update, ErrorCode.SYSTEM_ERROR);
return ResultUtils.success(true);
}
/**
* 根据 id 获取订单信息(仅管理员)
*/
@GetMapping("/get")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<OrdersVO> getOrderVOById(@RequestParam Long id) {
if (id <= 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Orders orders = ordersService.getById(id);
ThrowUtils.throwIf(orders == null, ErrorCode.NOT_FOUND_ERROR);
return ResultUtils.success(ordersService.getOrdersVO(orders));
}
/**
* 根据 id 获取订单信息
*/
@GetMapping("/get/my")
public BaseResponse<OrdersVO> getOrderVOByMyId(@RequestParam Long id, HttpServletRequest request) {
if (id <= 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
User loginUser = userService.getLoginUser(request);
Orders orders = ordersService.getOne(Wrappers.<Orders>lambdaQuery().eq(Orders::getId, id)
.eq(Orders::getUserId, loginUser.getId()));
ThrowUtils.throwIf(orders == null, ErrorCode.NOT_FOUND_ERROR);
return ResultUtils.success(ordersService.getOrdersVO(orders));
}
/**
* 分页获取订单列表(管理员)
*/
@PostMapping("/list/page")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Page<Orders>> listOrdersByPage(@RequestBody OrderQueryRequest orderQueryRequest) {
long current = orderQueryRequest.getCurrent();
long size = orderQueryRequest.getPageSize();
Page<Orders> ordersPage = ordersService.page(new Page<>(current, size),
ordersService.getQueryWrapper(orderQueryRequest));
return ResultUtils.success(ordersPage);
}
/**
* 获取我的订单
*/
@PostMapping("/my/page")
public BaseResponse<Page<OrdersVO>> getMyOrders(@RequestBody MyOrderQueryRequest myOrderQueryRequest, HttpServletRequest request) {
if (myOrderQueryRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
long current = myOrderQueryRequest.getCurrent();
long size = myOrderQueryRequest.getPageSize();
User loginUser = userService.getLoginUser(request);
OrderQueryRequest orderQueryRequest = new OrderQueryRequest();
BeanUtils.copyProperties(myOrderQueryRequest, orderQueryRequest);
QueryWrapper<Orders> queryWrapper = ordersService.getQueryWrapper(orderQueryRequest);
if (loginUser.getUserRole().equals(UserConstant.BUSINESS_ROLE)) {
// 商家获取订单
Business loginBusiness = businessService.getLoginBusiness(request);
queryWrapper.eq("businessId", loginBusiness.getId());
} else {
// 用户获取订单
queryWrapper.eq("userId", loginUser.getId());
}
Page<Orders> ordersPage = ordersService.page(new Page<>(current, size),
queryWrapper);
Page<OrdersVO> ordersVOPage = new Page<>(current, size, ordersPage.getTotal());
List<OrdersVO> ordersVOList = ordersService.getOrdersVO(ordersPage.getRecords());
ordersVOPage.setRecords(ordersVOList);
return ResultUtils.success(ordersVOPage);
}
/**
* 订单统计
*/
@PostMapping("/count")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
public BaseResponse<String> ordersCount(@RequestBody OrderCountRequest orderCountRequest) {
String type = orderCountRequest.getType();
Integer state = orderCountRequest.getState();
Long businessId = orderCountRequest.getBusinessId();
String startTime = orderCountRequest.getStartTime();
String endTime = orderCountRequest.getEndTime();
ThrowUtils.throwIf(StringUtils.isBlank(type), ErrorCode.PARAMS_ERROR);
QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(state != null, "state", state);
queryWrapper.eq(businessId != null, "businessId", businessId);
return getStringBaseResponse(type, startTime, endTime, queryWrapper);
}
/**
* 订单金额统计
*/
@PostMapping("/count/money")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
public BaseResponse<List<BigDecimal>> ordersCountMoney(@RequestBody OrderCountRequest orderCountRequest) {
// 获取查询类型
String type = orderCountRequest.getType();
ThrowUtils.throwIf(StringUtils.isBlank(type), ErrorCode.PARAMS_ERROR);
OrderQueryRequest orderQueryRequest = new OrderQueryRequest();
BeanUtils.copyProperties(orderCountRequest, orderQueryRequest);
List<BigDecimal> moneyCountList = new ArrayList<>();
if (type.equals("week")) {
LocalDate today = LocalDate.now();
DateTimeFormatter startFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00");
DateTimeFormatter endFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 23:59:59");
// 遍历查询7天数据放入数组
for (int i = 0; i <= 6; i++) {
LocalDate date = today.minusDays(i);
orderQueryRequest.setStartTime(date.format(startFormatter));
orderQueryRequest.setEndTime(date.format(endFormatter));
QueryWrapper<Orders> queryWrapper = ordersService.getQueryWrapper(orderQueryRequest);
List<Orders> orderList = ordersService.list(queryWrapper);
BigDecimal money = new BigDecimal("0");
for (Orders order : orderList) {
money = money.add(order.getTotalPrice());
}
moneyCountList.add(money);
}
} else {
QueryWrapper<Orders> queryWrapper = ordersService.getQueryWrapper(orderQueryRequest);
List<Orders> orderList = ordersService.list(queryWrapper);
BigDecimal money = new BigDecimal("0");
for (Orders order : orderList) {
money = money.add(order.getTotalPrice());
}
moneyCountList.add(money);
}
return ResultUtils.success(moneyCountList);
}
/**
* 订单数量统计
*/
@PostMapping("/count/number")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
public BaseResponse<List<Long>> ordersCountNumber(@RequestBody OrderCountRequest orderCountRequest) {
// 获取查询类型
String type = orderCountRequest.getType();
ThrowUtils.throwIf(StringUtils.isBlank(type), ErrorCode.PARAMS_ERROR);
OrderQueryRequest orderQueryRequest = new OrderQueryRequest();
BeanUtils.copyProperties(orderCountRequest, orderQueryRequest);
List<Long> numberCountList = new ArrayList<>();
if (type.equals("week")) {
LocalDate today = LocalDate.now();
DateTimeFormatter startFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00");
DateTimeFormatter endFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 23:59:59");
// 遍历查询7天数据放入数组
for (int i = 0; i <= 6; i++) {
LocalDate date = today.minusDays(i);
orderQueryRequest.setStartTime(date.format(startFormatter));
orderQueryRequest.setEndTime(date.format(endFormatter));
QueryWrapper<Orders> queryWrapper = ordersService.getQueryWrapper(orderQueryRequest);
long count = ordersService.count(queryWrapper );
numberCountList.add(count);
}
} else {
QueryWrapper<Orders> queryWrapper = ordersService.getQueryWrapper(orderQueryRequest);
long count = ordersService.count(queryWrapper);
numberCountList.add(count);
}
return ResultUtils.success(numberCountList);
}
/**
* 订单统计(web端)
*/
@PostMapping("/count/web")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
public BaseResponse<String> ordersCountByWeb(@RequestBody OrderCountRequest orderCountRequest) {
String type = orderCountRequest.getType();
Integer state = orderCountRequest.getState();
String businessName = orderCountRequest.getBusinessName();
Long businessState = orderCountRequest.getBusinessState();
String startTime = orderCountRequest.getStartTime();
String endTime = orderCountRequest.getEndTime();
Long categoryId = orderCountRequest.getCategoryId();
List<Long> businessIdList = new ArrayList<>();
ThrowUtils.throwIf(StringUtils.isBlank(type), ErrorCode.PARAMS_ERROR);
if (categoryId != null || businessName != null || businessState != null) {
QueryWrapper<Business> wrapper = new QueryWrapper<>();
wrapper.eq(StringUtils.isNotBlank(businessName), "businessName", businessName);
wrapper.eq(businessState != null, "state", businessState);
wrapper.eq(categoryId != null, "categoryId", categoryId);
List<Business> businessList = businessService.list(wrapper);
if (CollectionUtils.isEmpty(businessList)) {
return ResultUtils.success("0");
}
businessIdList = businessList.stream().map(Business::getId).collect(Collectors.toList());
}
QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(state != null, "state", state);
queryWrapper.in(!CollectionUtils.isEmpty(businessIdList), "businessId", businessIdList);
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);
wrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
sortField);
List<Orders> ordersList = ordersService.list(wrapper);
log.info("ordersList:" + ordersList);
List<OrdersExcelVO> ordersExcelVOList = ordersList.stream().map(item -> {
OrdersExcelVO ordersExcelVO = new OrdersExcelVO();
BeanUtils.copyProperties(item, ordersExcelVO);
//改变订单支付状态
String stateText = ExcelUtils.getStateText(item.getState());
ordersExcelVO.setState(stateText);
log.info("修改订单状态:" + ordersExcelVO.getState());
// Date转字符串
ordersExcelVO.setCreateTime(ExcelUtils.dateToString(item.getCreateTime()));
return ordersExcelVO;
}).collect(Collectors.toList());
// 设置导出名称
ExcelUtils.setExcelResponseProp(response, "订单信息");
log.info("响应头 Content-Type: {}", response.getContentType());
// 获取输出流名称
try (OutputStream outputStream = response.getOutputStream()) {
EasyExcel.write(outputStream, OrdersExcelVO.class)
.sheet("订单数据")
.doWrite(ordersExcelVOList);
response.flushBuffer();
} catch (Exception e) {
log.error("Excel 导出失败", e);
}
}
@PostMapping("/delete")
@AuthCheck(mustRole = UserConstant.DEFAULT_ROLE)
public BaseResponse<Boolean> deleteOrder (@RequestBody CommonRequest commonRequest, HttpServletRequest request) {
if (commonRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long orderId = commonRequest.getId();
LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Orders::getId, orderId);
Orders orders = ordersService.getOne(wrapper);
User loginUser = userService.getLoginUser(request);
Long loginUserId = loginUser.getId();
ThrowUtils.throwIf(!orders.getUserId().equals(loginUserId), ErrorCode.OPERATION_ERROR,
"当前用户不是该订单所有者");
log.info("oldOrders:" + orders);
LambdaUpdateWrapper<Orders> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(Orders::getIsDelete,1);
updateWrapper.eq(Orders::getId, orderId);
boolean update = ordersService.update(updateWrapper);
log.info("orders:" + orders);
ThrowUtils.throwIf(!update, ErrorCode.SYSTEM_ERROR);
return ResultUtils.success(true);
}
@PostMapping("/update")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
public BaseResponse<Boolean> updateOrderState(@RequestBody CommonRequest commonRequest,HttpServletRequest request) {
if (commonRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long id = commonRequest.getId();
LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Orders::getId, id);
Orders orders = ordersService.getOne(queryWrapper);
Business loginBusiness = businessService.getLoginBusiness(request);
Long businessId = loginBusiness.getId();
ThrowUtils.throwIf(!businessId.equals(orders.getBusinessId()), ErrorCode.FORBIDDEN_ERROR, "当前订单不属于当前登录用户");
LambdaUpdateWrapper<Orders> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(Orders::getState,4);
updateWrapper.eq(Orders::getId, id);
String location = orders.getLocation();
ErrandOrder errandOrder = errandOrderService.getOne(Wrappers.<ErrandOrder>lambdaQuery()
.eq(ErrandOrder::getOrderId, orders.getId()));
if (errandOrder != null) {
if (StringUtils.isNotBlank(location)) {
websocketService.sendOrderToErrand(orders);
errandOrder.setErrandState(1);//1待抢单
boolean update1 = errandOrderService.updateById(errandOrder);
ThrowUtils.throwIf(!update1, ErrorCode.OPERATION_ERROR, "更新跑腿关联失败");
}
boolean update = ordersService.update(updateWrapper);
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR,"修改订单状态失败");
}
return ResultUtils.success(true);
}
@PostMapping("/updateOrder")
public BaseResponse<Boolean> updateOrder(@RequestBody OrderUpdateRequest orderUpdateRequest, HttpServletRequest request) {
return ResultUtils.success(ordersService.OrderToUpdate(orderUpdateRequest, request));
}
@PostMapping("/update/state/user")
public BaseResponse<Boolean> updateStateByUser(@RequestBody CommonRequest commonRequest, HttpServletRequest request) {
if (commonRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long orderId = commonRequest.getId();
User loginUser = userService.getLoginUser(request);
Orders orders = ordersService.getById(orderId);
ThrowUtils.throwIf(orders.getState().equals(5), ErrorCode.OPERATION_ERROR, "订单已完成");
ThrowUtils.throwIf(!orders.getUserId().equals(loginUser.getId()), ErrorCode.PARAMS_ERROR,
"当前传送的订单id不正确或不属于当前用户");
Long errandId = orders.getErrandId();
if (errandId != null) {
Errand errand = errandService.getById(errandId);
LambdaQueryWrapper<ErrandIncome> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ErrandIncome::getOrderId, orderId);
ErrandIncome errandIncome = errandIncomeService.getOne(queryWrapper);
errandIncome.setState(1); // 收入已结算
boolean update = errandIncomeService.updateById(errandIncome);
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR,"修改跑腿收入失败");
BigDecimal totalPrice = errand.getTotalPrice();
BigDecimal income = errandIncome.getIncome();
totalPrice = totalPrice.add(income);
errand.setTotalPrice(totalPrice);
boolean update1 = errandService.updateById(errand);
ThrowUtils.throwIf(!update1, ErrorCode.OPERATION_ERROR, "修改跑腿总金额失败");
ErrandBill errandBill = new ErrandBill();
errandBill.setOrderId(orderId);
errandBill.setErrandState(errandIncome.getState());
errandBill.setIncome(errandIncome.getIncome());
errandBill.setUsername(loginUser.getUsername());
errandBill.setOrderStartTime(orders.getCreateTime());
boolean save = billService.save(errandBill);
ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR, "添加跑腿账单失败");
}
orders.setState(5);
boolean update = ordersService.updateById(orders);
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "修改订单状态失败");
return ResultUtils.success(true);
}
@PostMapping("/list/errand")
@AuthCheck(mustRole = UserConstant.ERRAND_ROLE)
public BaseResponse<List<OrderErrandVO>> listOrderErrandVO (HttpServletRequest request) {
Errand loginErrand = errandService.getLoginErrand(request);
Long errandId = loginErrand.getId();
List<ErrandOrder> errandOrders = errandOrderService.list(Wrappers.<ErrandOrder>lambdaQuery()
.eq(ErrandOrder::getErrandId, errandId)
.eq(ErrandOrder::getErrandState, 4));
List<Long> orderIds = errandOrders.stream()
.map(ErrandOrder::getOrderId)
.collect(Collectors.toList());
LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
wrapper.in(Orders::getId, orderIds);
List<Orders> ordersList = ordersService.list(wrapper);
List<OrderErrandVO> listOrderErrandVO = ordersService.getListOrderErrandVO(ordersList);
return ResultUtils.success(listOrderErrandVO);
}
@PostMapping("/list/status")
@AuthCheck(mustRole = UserConstant.DEFAULT_ROLE)
public BaseResponse<List<OrderStatusVO>> listOrderStatus (HttpServletRequest request) {
List<OrderStatusVO> liststatus = ordersService.liststatus(request);
return ResultUtils.success(liststatus);
}
@PostMapping("/list/numnber")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<List<OrdersPickVO>> getPickUpNum () {
List<OrdersPickVO> ordernumbers = ordersService.getOrdernumber();
ThrowUtils.throwIf(ordernumbers == null, ErrorCode.OPERATION_ERROR, "获取单量失败");
return ResultUtils.success(ordernumbers);
}
@PostMapping("/download/errand")
public void downloadByErrand(@RequestBody OrderQueryRequest orderQueryRequest, HttpServletResponse response) throws IOException {
String startTime = orderQueryRequest.getStartTime();
String endTime = orderQueryRequest.getEndTime();
Long errandId = orderQueryRequest.getErrandId();
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("errandId", errandId);
wrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
sortField);
List<Orders> ordersList = ordersService.list(wrapper);
Collection<Long> orderIds = ordersList.stream()
.map(Orders::getId)
.collect(Collectors.toList());
//获取errandState
LambdaQueryWrapper<ErrandOrder> wrapper1 = new LambdaQueryWrapper<>();
wrapper1.in(ErrandOrder::getOrderId, orderIds);
List<ErrandOrder> errandOrders = errandOrderService.list(wrapper1);
//先将errandOrder数据变成MAP提高查询效率
Map<Long, Integer> map = errandOrders.stream()
.collect(Collectors.toMap(ErrandOrder::getOrderId, ErrandOrder::getErrandState));
//获取跑腿收入
LambdaQueryWrapper<ErrandIncome> wrapper2 = new LambdaQueryWrapper<>();
wrapper2.in(ErrandIncome::getOrderId, orderIds);
List<ErrandIncome> errandIncomes = errandIncomeService.list(wrapper2);
Map<Long, BigDecimal> decimalMap = errandIncomes.stream()
.collect(Collectors.toMap(ErrandIncome::getOrderId, ErrandIncome::getIncome));
Collection<OrdersExcelByErrandVO> excelByErrandVOS = ordersList.stream()
.map(orders -> {
OrdersExcelByErrandVO ordersExcelByErrandVO = new OrdersExcelByErrandVO();
BeanUtils.copyProperties(orders, ordersExcelByErrandVO);
//改变订单支付状态
String stateText = ExcelUtils.getStateText(orders.getState());
ordersExcelByErrandVO.setState(stateText);
//改变跑腿订单状态
String errandStateText = ExcelUtils.getErrandStateText(map.getOrDefault(orders.getId(), 0));
ordersExcelByErrandVO.setErrandState(errandStateText);
ordersExcelByErrandVO.setErrandIncome(decimalMap.getOrDefault(orders.getId(), new BigDecimal("0.00")));
return ordersExcelByErrandVO;
}).collect(Collectors.toList());
// 设置导出名称
ExcelUtils.setExcelResponseProp(response, "跑腿订单信息");
// 获取输出流名称
try (OutputStream outputStream = response.getOutputStream()) {
EasyExcel.write(outputStream, OrdersExcelByErrandVO.class)
.sheet("订单数据")
.doWrite(excelByErrandVOS);
response.flushBuffer();
} catch (Exception e) {
log.error("Excel 导出失败", e);
}
}
@PostMapping("/count/errand")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<BigDecimal> countErrand (@RequestBody OrdersCountByErrandRequest errandRequest) {
if (errandRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long errandId = errandRequest.getErrandId();
Integer state = errandRequest.getState();
LambdaQueryWrapper<ErrandIncome> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ErrandIncome::getErrandId, errandId);
queryWrapper.eq(ObjectUtils.isNotEmpty(state), ErrandIncome::getState, state);
List<ErrandIncome> errandIncomes = errandIncomeService.list(queryWrapper);
// 计算 income 总和
BigDecimal totalIncome = errandIncomes.stream()
.map(ErrandIncome::getIncome) // 获取 income
.filter(Objects::nonNull) // 过滤掉 null 值
.reduce(BigDecimal.ZERO, BigDecimal::add); // 求和
return ResultUtils.success(totalIncome);
}
private BaseResponse<String> getStringBaseResponse(String type, String startTime, String endTime, QueryWrapper<Orders> queryWrapper) {
queryWrapper.ge(StringUtils.isNotBlank(startTime), "createTime", startTime);
queryWrapper.le(StringUtils.isNotBlank(endTime), "createTime", endTime);
if (type.equals("money")) {
List<Orders> orderList = ordersService.list(queryWrapper);
BigDecimal money = new BigDecimal("0");
for (Orders order : orderList) {
money = money.add(order.getTotalPrice());
}
String strMoney = String.valueOf(money);
return ResultUtils.success(strMoney);
} else if (type.equals("number")) {
long count = ordersService.count(queryWrapper);
String strNumber = String.valueOf(count);
return ResultUtils.success(strNumber);
} else {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "type不正确");
}
}
}

View File

@ -0,0 +1,42 @@
package com.bsz.school_send_back_end.controller;
import com.bsz.school_send_back_end.common.BaseResponse;
import com.bsz.school_send_back_end.service.OssService;
import com.bsz.school_send_back_end.common.ResultUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import jakarta.annotation.Resource;
@Tag(name = "阿里云文件上传接口")
@RestController
@RequestMapping("/fileOss")
public class OssController {
@Resource
private OssService ossService;
/**
* 上传头像
*
* @param file
* @return
*/
@ApiOperation(value = "文件上传")
@PostMapping("/upload")
public BaseResponse<String> uploadOssFile(@RequestParam(required = false) MultipartFile file) {
//获取上传的文件
if (file.isEmpty()) {
return null;
}
//返回上传到oss的路径
String url = ossService.uploadFileAvatar(file);
//返回r对象
return ResultUtils.success(url);
}
}

View File

@ -0,0 +1,22 @@
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 io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.web.bind.annotation.RestController;
import jakarta.annotation.Resource;
@Tag(name = "聊天接口")
@RestController
public class PrivateChatController {
@Resource
private WebsocketService ws;
@MessageMapping("/privateChat")
public void singleChat (PrivateMessage message) {
ws.sendChatMessage(message);
}
}

View File

@ -0,0 +1,96 @@
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 io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
@Tag(name = "私聊")
@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,142 @@
package com.bsz.school_send_back_end.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bsz.school_send_back_end.annotation.AuthCheck;
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.contant.UserConstant;
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.Business;
import com.bsz.school_send_back_end.model.domain.OrderRefunds;
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.refund.RefundAddRequest;
import com.bsz.school_send_back_end.model.dto.refund.RefundUpdateRequest;
import com.bsz.school_send_back_end.service.BusinessService;
import com.bsz.school_send_back_end.service.OrderRefundsService;
import com.bsz.school_send_back_end.service.OrdersService;
import com.bsz.school_send_back_end.service.UserService;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@Tag(name = "退款接口")
@RestController
@RequestMapping("/refund")
public class RefundController {
@Resource
private UserService userService;
@Resource
private OrderRefundsService refundsService;
@Resource
private OrdersService ordersService;
@Resource
private BusinessService businessService;
/**
* 用户申请退款
* @param refundAddRequest 退款请求
* @param request 网络请求
* @return 是否成功
*/
@PostMapping("/add")
public BaseResponse<Boolean> addRefund(@RequestBody RefundAddRequest refundAddRequest, HttpServletRequest request) {
User loginUser = userService.getLoginUser(request);
Long orderId = refundAddRequest.getOrderId();
LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Orders::getId, orderId);
Orders orders = ordersService.getOne(queryWrapper);
ThrowUtils.throwIf(orders == null, ErrorCode.NOT_FOUND_ERROR, "未找到退款申请");
ThrowUtils.throwIf(orders.getState() != 1, ErrorCode.SYSTEM_ERROR, "该订单未支付");
OrderRefunds orderRefunds = new OrderRefunds();
BeanUtils.copyProperties(refundAddRequest, orderRefunds);
orderRefunds.setUserId(loginUser.getId());
boolean save = refundsService.save(orderRefunds);
ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR, "创建退款单失败");
return ResultUtils.success(true, "申请退款成功,等待商家确认");
}
/**
* 商家查询退款单
* @param status 退款单的状态
* @param request 网络请求
* @return 退款列表
*/
@GetMapping("/list/business")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
public BaseResponse<List<OrderRefunds>> listRefundByBusiness(@RequestParam Integer status, HttpServletRequest request) {
Business loginBusiness = businessService.getLoginBusiness(request);
Long id = loginBusiness.getId();
LambdaQueryWrapper<OrderRefunds> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(OrderRefunds::getStatus, status)
.inSql(OrderRefunds::getOrderId, "SELECT id FROM orders WHERE businessId = " + id); // 根据商家ID过滤订单
List<OrderRefunds> list = refundsService.list(queryWrapper);
return ResultUtils.success(list);
}
@PostMapping("/update")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
public BaseResponse<Boolean> updateRefundByBusiness (@RequestBody RefundUpdateRequest updateRequest, HttpServletRequest request) {
if (updateRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long orderId = updateRequest.getOrderId();
Integer status = updateRequest.getStatus();
Business loginBusiness = businessService.getLoginBusiness(request);
Long businessId = loginBusiness.getId();
Orders orders = ordersService.getOne(Wrappers.<Orders>lambdaQuery()
.eq(Orders::getId, orderId));
ThrowUtils.throwIf(orders == null, ErrorCode.PARAMS_ERROR, "传入的订单id不正确");
ThrowUtils.throwIf(businessId.equals(orders.getBusinessId()), ErrorCode.PARAMS_ERROR, "当前订单不属于该商家");
LambdaQueryWrapper<OrderRefunds> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(OrderRefunds::getOrderId, orderId);
OrderRefunds refunds = refundsService.getOne(queryWrapper);
refunds.setStatus(status); // 1-已同意 2 - 已拒绝
ThrowUtils.throwIf(status == 2 && updateRequest.getRefuseReason() == null, ErrorCode.PARAMS_ERROR, "请填写退款原因");
boolean updateById = refundsService.updateById(refunds);
ThrowUtils.throwIf(!updateById, ErrorCode.OPERATION_ERROR, "修改退款单状态失败");
return ResultUtils.success(true);
}
@PostMapping("/list/reson")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<List<String>> getReasonByAdmin() {
// 获取今天的开始和结束时间
LocalDate today = LocalDate.now();
LocalDateTime startOfDay = today.atStartOfDay(); // 今天的00:00:00
LocalDateTime endOfDay = today.atTime(LocalTime.MAX); // 今天的23:59:59.999999999
// 将 LocalDateTime 转换为 Date
Date startOfDayDate = Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant());
Date endOfDayDate = Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant());
LambdaQueryWrapper<OrderRefunds> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.ge(OrderRefunds::getCreateTime, startOfDayDate);
queryWrapper.le(OrderRefunds::getCreateTime, endOfDayDate);
List<OrderRefunds> refunds = refundsService.list(queryWrapper);
List<String> collect = refunds.stream()
.map(OrderRefunds::getReason)
.collect(Collectors.toList());
return ResultUtils.success(collect);
}
}

View File

@ -0,0 +1,53 @@
package com.bsz.school_send_back_end.controller;
import com.bsz.school_send_back_end.common.BaseResponse;
import com.bsz.school_send_back_end.common.ResultUtils;
import com.bsz.school_send_back_end.utils.AliyunSmsUtils;
import com.bsz.school_send_back_end.utils.RandomNumberGenerator;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import jakarta.annotation.Resource;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
@Tag(name = "阿里云短信接口")
@RestController
@Slf4j
@RequestMapping("/sms")
public class SmsController {
@Resource
private RedisTemplate redisTemplate;
@Resource
private RandomNumberGenerator randomNumberGenerator;
@Resource
private AliyunSmsUtils aliyunSmsUtils;
@GetMapping("/send/{phone}")
public BaseResponse<String> sendCode (@PathVariable String phone) {
String code = (String) redisTemplate.opsForValue().get(phone);
log.info("获取验证码:{}", code);
if (code == null) {
String fourBitRandom = randomNumberGenerator.getFourBitRandom();
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("code", fourBitRandom);
log.info("生成的验证码:" + fourBitRandom);
redisTemplate.opsForValue().set(phone, fourBitRandom, 5, TimeUnit.MINUTES);
boolean b = aliyunSmsUtils.sendSms(phone, hashMap);
log.info("短信发送状态,{}", b);
return ResultUtils.success("发送成功");
} else {
return ResultUtils.success("请勿重复发送验证码");
}
}
}

View File

@ -0,0 +1,149 @@
package com.bsz.school_send_back_end.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bsz.school_send_back_end.annotation.AuthCheck;
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.contant.UserConstant;
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.Business;
import com.bsz.school_send_back_end.model.domain.Specifications;
import com.bsz.school_send_back_end.model.domain.SpecificationsDishes;
import com.bsz.school_send_back_end.model.dto.attribute.AttributeAddRequest;
import com.bsz.school_send_back_end.model.dto.attribute.AttributeUpdateRequest;
import com.bsz.school_send_back_end.model.dto.specifications.SpecificationsAddRequest;
import com.bsz.school_send_back_end.model.dto.specifications.SpecificationsMyQueryRequest;
import com.bsz.school_send_back_end.model.dto.specifications.SpecificationsQueryRequest;
import com.bsz.school_send_back_end.model.dto.specifications.SpecificationsUpdateRequest;
import com.bsz.school_send_back_end.model.vo.SpecificationsVO;
import com.bsz.school_send_back_end.service.AttributeService;
import com.bsz.school_send_back_end.service.BusinessService;
import com.bsz.school_send_back_end.service.SpecificationsDishesService;
import com.bsz.school_send_back_end.service.SpecificationsService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
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 jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
@Slf4j
@RestController
@Tag(name = "规格接口")
@RequestMapping("/specifications")
public class SpecificationsController {
@Resource
private SpecificationsService specificationsService;
@Resource
private SpecificationsDishesService specificationsDishesService;
@Resource
private BusinessService businessService;
@Resource
private AttributeService attributeService;
/**
* 添加规格
* @param specificationsAddRequest 添加请求体
* @param request 网络请求
* @return 是否成功
*/
@PostMapping("/add")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
@Transactional(rollbackFor = Exception.class)
public BaseResponse<Boolean> addSpecifications(@RequestBody SpecificationsAddRequest specificationsAddRequest, HttpServletRequest request){
if (specificationsAddRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Specifications specifications = new Specifications();
BeanUtils.copyProperties(specificationsAddRequest,specifications);
//校验请求体
specificationsService.validSpecifications(specifications, false);
//添加规格和属性
List<AttributeAddRequest> attributeAddRequests = specificationsAddRequest.getAttributeAddRequests();
Boolean aBoolean = specificationsService.addSpecifications(specifications, attributeAddRequests, request);
ThrowUtils.throwIf(!aBoolean, ErrorCode.OPERATION_ERROR);
return ResultUtils.success(true);
}
/**·
* 更新规格
* @param specificationsUpdateRequest 更新请求体
* @param request 网络请求
* @return 是否成功
*/
@PostMapping("/update")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
@Transactional(rollbackFor = Exception.class)
public BaseResponse<Boolean> updateSpecifications(@RequestBody SpecificationsUpdateRequest specificationsUpdateRequest, HttpServletRequest request) {
if (specificationsUpdateRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Specifications specifications = new Specifications();
BeanUtils.copyProperties(specificationsUpdateRequest,specifications);
//校验
specificationsService.validSpecifications(specifications,true);
//更新规格和属性
List<AttributeUpdateRequest> attributeUpdateRequests = specificationsUpdateRequest.getAttributeUpdateRequests();
Boolean aBoolean = specificationsService.updateSpecifications(specifications, attributeUpdateRequests, request);
ThrowUtils.throwIf(!aBoolean, ErrorCode.OPERATION_ERROR);
return ResultUtils.success(true);
}
/**
* 根据菜品id获取规格脱敏信息
* @param specificationsMyQueryRequest 请求体
* @return 脱敏列表
*/
@PostMapping("/list/specificationsVOByDishesId")
public BaseResponse<List<SpecificationsVO>> specificationsVOByDishesId(@RequestBody SpecificationsMyQueryRequest specificationsMyQueryRequest) {
if (specificationsMyQueryRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long dishesId = specificationsMyQueryRequest.getId();
//根据id获取中间表数据
QueryWrapper<SpecificationsDishes> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("dishesId",dishesId);
List<SpecificationsDishes> list = specificationsDishesService.list(queryWrapper);
//根据中间表数据中的规格获取规格信息和属性
return ResultUtils.success(specificationsDishesService.getSpecificationsAddAttribute(list));
}
/**
* 获取脱敏列表
* @param specificationsQueryRequest 前端请求
* @param request 网络请求
* @return 脱敏列表
*/
@PostMapping("/list/specificationsVO")
public BaseResponse<List<SpecificationsVO>> specificationsVOList(@RequestBody SpecificationsQueryRequest specificationsQueryRequest, HttpServletRequest request) {
//获取商家id
Business loginBusiness = businessService.getLoginBusiness(request);
Long businessId = loginBusiness.getId();
//获取商家的规格表
String specificationsName = specificationsQueryRequest.getSpecificationsName();
QueryWrapper<Specifications> queryWrapper = new QueryWrapper<>();
queryWrapper.like(StringUtils.isNotBlank(specificationsName), "specificationsName", specificationsName);
queryWrapper.eq("businessId",businessId);
List<Specifications> list = specificationsService.list(queryWrapper);
//对规格信息脱敏
List<SpecificationsVO> specificationsVO = specificationsService.getSpecificationsVO(list);
//获取各规格的属性脱敏信息
return ResultUtils.success(attributeService.getBySpecificationsVoId(specificationsVO));
}
}

View File

@ -0,0 +1,79 @@
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.Systeminfo;
import com.bsz.school_send_back_end.model.dto.CommonRequest;
import com.bsz.school_send_back_end.model.dto.system.SystemAddRequest;
import com.bsz.school_send_back_end.model.dto.system.SystemQueryRequest;
import com.bsz.school_send_back_end.service.SysteminfoService;
import io.swagger.v3.oas.annotations.tags.Tag;
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 jakarta.annotation.Resource;
import java.util.List;
@Tag(name = "公告与轮播图接口")
@RestController
@Slf4j
@RequestMapping("/system")
public class SystemInfoController {
@Resource
private SysteminfoService systeminfoService;
/**
* 添加功能
*/
@PostMapping("/add")
public BaseResponse<Boolean> addInfo (@RequestBody SystemAddRequest systemAddRequest) {
if (systemAddRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Systeminfo systeminfo = new Systeminfo();
BeanUtils.copyProperties(systemAddRequest, systeminfo);
ThrowUtils.throwIf(systeminfo.getContent() == null, ErrorCode.PARAMS_ERROR, "内容为空");
boolean save = systeminfoService.save(systeminfo);
ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR);
return ResultUtils.success(true, "添加成功");
}
/**
* 删除功能
*/
@PostMapping("/delete")
public BaseResponse<Boolean> deleteInfo (@RequestBody CommonRequest commonRequest) {
if (commonRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
boolean remove = systeminfoService.removeById(commonRequest.getId());
ThrowUtils.throwIf(!remove, ErrorCode.OPERATION_ERROR, "添加失败");
return ResultUtils.success(true,"删除成功");
}
/**
*查询列表
*/
@PostMapping("/list")
public BaseResponse<List<Systeminfo>> selectInfo (@RequestBody SystemQueryRequest common) {
if (common == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
LambdaQueryWrapper<Systeminfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Systeminfo::getType, common.getType());
List<Systeminfo> list = systeminfoService.list(queryWrapper);
return ResultUtils.success(list,"查询成功");
}
}

View File

@ -0,0 +1,88 @@
package com.bsz.school_send_back_end.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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;
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.contant.UserConstant;
import com.bsz.school_send_back_end.exception.BusinessException;
import com.bsz.school_send_back_end.model.domain.Business;
import com.bsz.school_send_back_end.model.domain.Systemlog;
import com.bsz.school_send_back_end.model.dto.log.LogQueryRequest;
import com.bsz.school_send_back_end.model.vo.BusinessLogVO;
import com.bsz.school_send_back_end.service.BusinessService;
import com.bsz.school_send_back_end.service.SystemlogService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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 jakarta.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
@Tag(name = "系统日志接口")
@RestController
@RequestMapping("/log")
@Slf4j
public class SystemLogController {
@Resource
private BusinessService businessService;
@Resource
private SystemlogService systemlogService;
/**
* 分页获取商家系统日志列表
*/
@PostMapping("/business/logs")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Page<BusinessLogVO>> getLogByPage(@RequestBody LogQueryRequest logQueryRequest) {
if (logQueryRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
long current = logQueryRequest.getCurrent();
long pageSize = logQueryRequest.getPageSize();
//根据手机号获取用户id
String businessPhone = logQueryRequest.getBusinessPhone();
if (StringUtils.isNotBlank(businessPhone)) {
LambdaQueryWrapper<Business> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Business::getBusinessPhone, businessPhone);
Business business = businessService.getOne(wrapper);
if (business == null) {
logQueryRequest.setUserId((long) -1);
}
else {
logQueryRequest.setUserId(business.getUserId());
}
}
Page<Systemlog> systemlogPage = systemlogService.page(new Page<>(current, pageSize),
systemlogService.getQueryWrapper(logQueryRequest));
List<Systemlog> systemlogList = systemlogPage.getRecords();
List<BusinessLogVO> businessLogVOList = systemlogList.stream().map(item -> {
BusinessLogVO businessLogVO = new BusinessLogVO();
BeanUtils.copyProperties(item, businessLogVO);
//查询商家信息
Long userId = item.getUserId();
Business business = null;
if (userId != null && userId > -1) {
QueryWrapper<Business> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("userId", userId);
business = businessService.getOne(queryWrapper);
}
businessLogVO.setBusiness(business);
return businessLogVO;
}).collect(Collectors.toList());
Page<BusinessLogVO> businessLogVOPage = new Page<>(current, pageSize, systemlogPage.getTotal());
businessLogVOPage.setRecords(businessLogVOList);
return ResultUtils.success(businessLogVOPage);
}
}

View File

@ -0,0 +1,319 @@
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.*;
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.QueryWrapper;
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.config.AlipayClients;
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.listener.RabbitMQSender;
import com.bsz.school_send_back_end.mapper.UserMapper;
import com.bsz.school_send_back_end.model.domain.OrderRefunds;
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.vo.UserVO;
import com.bsz.school_send_back_end.service.*;
import com.bsz.school_send_back_end.utils.RandomNumberGenerator;
import com.bsz.school_send_back_end.utils.UniqueNumberGenerator;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.*;
@Tag(name = "支付宝支付相关接口")
@RestController
@Slf4j
@RequestMapping("/Alipay")
public class TestAlipayController {
@Resource
private UserService userService;
@Resource
private OrdersService ordersService;
@Resource
private AliPayService aliPayService;
@Resource
private WebsocketService websocketService;
@Resource
private OrderRefundsService refundsService;
@Resource
private RabbitMQSender rabbitMQSender;
@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 = "https://xiaokuaisong.shop/api/Alipay/notifyUrl";
/**
* 解析code获取open_id和token
* @return aaa
* @throws AlipayApiException 支付宝api异常
*/
@GetMapping("/parseCode")
public BaseResponse<UserVO> login(String authcode, HttpServletRequest req) throws AlipayApiException {
AlipayConfig alipayConfig = new AlipayConfig();
alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
alipayConfig.setAppId(appId);
alipayConfig.setPrivateKey(appPrivateKey);
alipayConfig.setFormat("json");
alipayConfig.setAlipayPublicKey(PublicKey);
alipayConfig.setCharset("UTF-8");
alipayConfig.setSignType("RSA2");
log.info("网关地址:" + alipayConfig.getServerUrl());
AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
request.setCode(authcode);
request.setGrantType("authorization_code");
AlipaySystemOauthTokenResponse response = alipayClient.execute(request);
System.out.println( "AlipaySystemOauthTokenResponse返回数据" + response.getBody()); //打印所有响应
authToken = response.getAccessToken();
if (!response.isSuccess()) {
return ResultUtils.error(ErrorCode.PARAMS_ERROR);
}
AlipayUserInfoShareRequest request1 = new AlipayUserInfoShareRequest();
AlipayUserInfoShareResponse response1 = alipayClient.execute(request1, authToken);
System.out.println( "AlipayUserInfoShareResponse返回数据" + response1.getBody());
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()) ? "RandomName" + randomNumberGenerator.generateRandomNumber() : response1.getNickName());
user.setUserPassword("123456");
user.setUserAccount("yonghu" + 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());
log.info("tradeNo:" + tradeNo);
return ResultUtils.success(tradeNo);
}
@GetMapping("/test/close")
public String closeOrder(String out_trade_no, Long orderId) throws AlipayApiException {
log.info("out_trade_no:" + out_trade_no);
AlipayClients clients = new AlipayClients();
AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
AlipayTradeCloseModel model = new AlipayTradeCloseModel();
//model.setTradeNo(); 这是订单项
//订单项可能会有多个支付单
model.setTradeNo(out_trade_no);
request.setBizModel(model);
// request.setNotifyUrl(NOURL + "/close");
LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Orders::getId, orderId);
Orders orders = ordersService.getOne(queryWrapper);
log.info("orders:" + orders);
ThrowUtils.throwIf(!orders.getState().equals(0),ErrorCode.SYSTEM_ERROR,"当前订单已支付或已退款");
orders.setState(3);
boolean update = ordersService.updateById(orders);
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "修改订单状态失败");
AlipayTradeCloseResponse response = clients.alipayClient().execute(request);
if (!response.isSuccess()) {
throw new BusinessException(ErrorCode.OPERATION_ERROR, "支付宝修改订单失败");
}
//这里应该写进日志
log.info("订单已取消");
return response.getBody();
}
@GetMapping("/test/refund")
@Transactional(rollbackFor = Exception.class)
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()));
//退款请求单号 要求唯一 需改
String number = UniqueNumberGenerator.generateNumber();
model.setOutRequestNo(number);
log.info("outRequestNo:" + number);
request.setBizModel(model);
ThrowUtils.throwIf(!orders.getState().equals(1),ErrorCode.SYSTEM_ERROR,"当前订单未支付");
orders.setState(2);
boolean update = ordersService.updateById(orders);
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "修改订单状态失败");
log.info("orderState:" + orders.getState());
OrderRefunds refunds = refundsService.getOne(Wrappers.<OrderRefunds>lambdaQuery()
.eq(OrderRefunds::getOrderId, orders.getId()));
ThrowUtils.throwIf(refunds == null, ErrorCode.OPERATION_ERROR, "没有退款");
refunds.setStatus(1); // 1-已同意
boolean updateById = refundsService.updateById(refunds);
ThrowUtils.throwIf(!updateById, ErrorCode.OPERATION_ERROR, "修改退款单失败");
AlipayTradeRefundResponse response = clients.alipayClient().execute(request);
String body = response.getBody();
if (!response.isSuccess()) {
throw new BusinessException(ErrorCode.OPERATION_ERROR, "支付宝退款失败");
}
log.info("退款成功");
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();
if (!response.isSuccess()) {
throw new BusinessException(ErrorCode.OPERATION_ERROR, "支付宝查询订单失败");
}
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);
if (orders.getPickupMethod() == 2) {
rabbitMQSender.sendCreateDeliveryOrderMessage(orders.getId());
}
orders.setState(1);
Date date = new Date();
orders.setUpdateTime(date);
boolean update = ordersService.updateById(orders);
log.info("修改前orders:" + orders);
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "修改订单状态失败");
log.info("修改后orders:" + orders);
//TODO 商家通知
websocketService.sendOrderMessage(orders);
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 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);
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,384 @@
package com.bsz.school_send_back_end.controller;
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;
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.contant.UserConstant;
import com.bsz.school_send_back_end.exception.ThrowUtils;
import com.bsz.school_send_back_end.model.vo.LoginUserVO;
import com.bsz.school_send_back_end.model.dto.user.*;
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.mapper.UserMapper;
import com.bsz.school_send_back_end.model.domain.User;
import com.bsz.school_send_back_end.service.UserService;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import static com.bsz.school_send_back_end.contant.UserConstant.*;
/**
* 用户接口
*/
@Tag(name = "用户接口")
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
@Resource
private UserMapper userMapper;
/**
* 用户注册请求接口
*
* @param userRegisterRequest
* @return
*/
@PostMapping("/register")
public BaseResponse<Long> userRegister(@RequestBody UserRegisterRequest userRegisterRequest) {
if (userRegisterRequest == null){
throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
}
String userAccount = userRegisterRequest.getUserAccount();
String userPassword = userRegisterRequest.getUserPassword();
String checkPassword = userRegisterRequest.getCheckPassword();
if (StringUtils.isAllBlank(userAccount, userPassword, checkPassword)) {
return ResultUtils.error(ErrorCode.PARAMS_ERROR);
}
long result = userService.userRegister(userAccount, userPassword, checkPassword);
return ResultUtils.success(result);
}
/**
* 用户登录请求接口
*
* @param userLoginRequest
* @param request 前端请求对象
* @return
*/
@PostMapping("/login")
public BaseResponse<String> userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
if (userLoginRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
}
String userAccount = userLoginRequest.getUserAccount();
String userPassword = userLoginRequest.getUserPassword();
String appName = userLoginRequest.getAppName();
if (StringUtils.isAllBlank(userAccount, userPassword)){
throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
}
String message = userService.userLogin(userAccount, userPassword, appName, request);
return ResultUtils.success(message);
}
/*
@GetMapping("/search")
public BaseResponse<List<User>> searchUsers( String username, HttpServletRequest request) {
if (!isAdmin(request)){
throw new BusinessException(ErrorCode.NO_AUTH, "缺少管理员权限");
}
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
if (StringUtils.isNotBlank(username)) {
queryWrapper.like("userAccount", username);
}
List<User> userList = userService.list(queryWrapper);
List<User> list = userList.stream().map(user -> userService.getSafetyUser(user)).collect(Collectors.toList());
return ResultUtils.success(list);
}*/
/**
* 查询用户
*
* @param searchRequest
* @param request
* @return
*/
@GetMapping("/search")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<List<User>> searchUsers(UserSearchRequest searchRequest, HttpServletRequest request) {
String username = searchRequest.getUsername();
String userAccount = searchRequest.getUserAccount();
Integer gender = searchRequest.getGender();
String phone = searchRequest.getPhone();
String email = searchRequest.getEmail();
Integer userStatus = searchRequest.getUserStatus();
String userRole = searchRequest.getUserRole();
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
Date updateTime = searchRequest.getUpdateTime();
Date createTime = searchRequest.getCreateTime();
//校验
// username
if (StringUtils.isNotBlank(username)) {
queryWrapper.like("username", username);
}
// userAccount
if (StringUtils.isNotBlank(userAccount)) {
queryWrapper.like("userAccount", userAccount);
}
// gender
if (gender != null) {
queryWrapper.eq("gender", gender);
}
// phone
if (StringUtils.isNotBlank(phone)) {
queryWrapper.like("phone", phone);
}
// email
if (StringUtils.isNotBlank(email)) {
queryWrapper.like("email", email);
}
// userStatus
if (userStatus != null) {
queryWrapper.eq("userStatus", userStatus);
}
//userRole
if (userRole != null) {
queryWrapper.eq("userRole", userRole);
}
if (updateTime != null) {
queryWrapper.like("updateTime", updateTime);
}
if (createTime != null) {
queryWrapper.like("createTime", createTime);
}
List<User> userList = userService.list(queryWrapper);
List<User> users = userList.stream().map(userService::getSafetyUser).collect(Collectors.toList());
return ResultUtils.success(users);
}
/**
* 用户注销的接口
*
* @param request
* @return
*/
@PostMapping("/logout")
public BaseResponse<Integer> userLogout(HttpServletRequest request) {
if (request == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
}
int logoutResult = userService.userLogout(request);
return ResultUtils.success(logoutResult);
}
/**
* 获取当前的用户
* @param request
* @return
*/
@GetMapping("/current")
public BaseResponse<LoginUserVO> getCurrenUser(HttpServletRequest request) {
//获取登录态
User user = userService.getLoginUser(request);
return ResultUtils.success(userService.getLoginUserVO(user));
}
/**
* 新增用户
*
* @param userAddRequest
* @param request
* @return
*/
@PostMapping("/add")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Long> addUser(@RequestBody UserAddRequest userAddRequest, HttpServletRequest request) {
if (userAddRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
}
User user = new User();
String userAccount = userAddRequest.getUserAccount();
String userPassword = userAddRequest.getUserPassword();
if (StringUtils.isAllEmpty(userAccount,userPassword)) {
throw new BusinessException(ErrorCode.PARAMS_ERROR,"未输入账号和密码");
}
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("userAccount", userAccount);
Long count = userMapper.selectCount(queryWrapper);
if (count > 0){
throw new BusinessException(ErrorCode.PARAMS_ERROR, "存在相同用户");
}
BeanUtils.copyProperties(userAddRequest, user);
String encryptPassword = DigestUtils.md5DigestAsHex((USER_SALT + userPassword).getBytes());
user.setUserPassword(encryptPassword);
boolean result = userService.save(user);
if (!result) {
throw new BusinessException(ErrorCode.OPERATION_ERROR, "操作失败");
}
return ResultUtils.success(user.getId());
}
/**
* 删除用户
*
* @param deleteRequest
* @param request
* @return
*/
@PostMapping("delete")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Boolean> deleteUser(@RequestBody UserDeleteRequest deleteRequest, HttpServletRequest request) {
if (deleteRequest == null || deleteRequest.getId() <= 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
boolean removeUser = userService.removeById(deleteRequest.getId());
return ResultUtils.success(removeUser);
}
/**
* 更新用户
*
* @param userUpdateRequest
* @param request
* @return
*/
@PostMapping("/update")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Boolean> updateUser(@RequestBody UserUpdateRequest userUpdateRequest , HttpServletRequest request) {
if (userUpdateRequest == null || userUpdateRequest.getId() == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
}
User user = new User();
BeanUtils.copyProperties(userUpdateRequest, user);
boolean result = userService.updateById(user);
if (!result) {
throw new BusinessException(ErrorCode.OPERATION_ERROR, "未找到该用户");
}
return ResultUtils.success(true);
}
/**
* 根据 id 获取用户(仅管理员)
*
* @param id id
* @return 用户信息
*/
@GetMapping("/getById")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<User> getUserById(@RequestParam long id) {
if (id <= 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
User user = userService.getById(id);
ThrowUtils.throwIf(user == null, ErrorCode.PARAMS_ERROR);
return ResultUtils.success(user);
}
/**
* 分页获取用户列表(仅管理员)
*
* @return 用户列表
*/
@PostMapping("/list/page")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Page<User>> listUserByPage(@RequestBody UserSearchRequest userSearchRequest, HttpServletRequest request) {
long current = userSearchRequest.getCurrent();
long size = userSearchRequest.getPageSize();
Page<User> userPage = userService.page(new Page<>(current, size),
userService.getQueryWrapper(userSearchRequest));
return ResultUtils.success(userPage);
}
/**
* 用户自己更新个人信息
*
* @param userUpdateMyRequest
* @param request
* @return
*/
@PostMapping("/update/my")
@ApiOperation(value = "用户更新信息")
public BaseResponse<Boolean> updateMyUser(@RequestBody UserUpdateMyRequest userUpdateMyRequest,
HttpServletRequest request) {
if (userUpdateMyRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
User loginUser = userService.getLoginUser(request);
User user = new User();
BeanUtils.copyProperties(userUpdateMyRequest, user);
user.setId(loginUser.getId());
boolean result = userService.updateById(user);
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
return ResultUtils.success(true);
}
/**
* 修改密码
*
* @param updatePasswordRequest
* @param request
* @return
*/
@PostMapping("/update/password")
@ApiOperation(value = "用户密码更改")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Boolean> updateUserPassword(@RequestBody UserUpdatePasswordRequest updatePasswordRequest,
HttpServletRequest request) {
boolean updateUserPassword = userService.updateUserPassword(updatePasswordRequest, request);
if (updateUserPassword) {
return ResultUtils.success(true);
} else {
return ResultUtils.error(ErrorCode.OPERATION_ERROR);
}
}
// /**
// * 用户登录(支付宝)
// */
// /**
// * 用户登录(支付宝)
// */
// @GetMapping("/login/alipay")
// public BaseResponse<LoginUserVO> userLoginByAlipay(HttpServletRequest request, @RequestParam("authCode") String authCode) {
// AlipaySystemOauthTokenResponse oauthTokenResponse;
// try {
// // 获取access_token 和 openId
// oauthTokenResponse = Factory.Base.OAuth().getToken(authCode);
// String accessToken = oauthTokenResponse.getAccessToken();
// // 获取用户信息
// JSONObject userInfo = AlipayUtils.getUserInfo(accessToken);
// String openId = userInfo.getStr("open_id");
// return ResultUtils.success(userService.userLoginByAlipay(openId, userInfo, request));
// } catch (Exception e) {
// throw new BusinessException(ErrorCode.SYSTEM_ERROR, "登录失败,系统错误");
// }
// }
}

View File

@ -0,0 +1,138 @@
package com.bsz.school_send_back_end.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bsz.school_send_back_end.annotation.AuthCheck;
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.contant.UserConstant;
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.User;
import com.bsz.school_send_back_end.model.domain.UserRating;
import com.bsz.school_send_back_end.model.dto.CommonRequest;
import com.bsz.school_send_back_end.model.dto.userRating.UserRatingAddRequest;
import com.bsz.school_send_back_end.model.dto.userRating.UserRatingReviewRequest;
import com.bsz.school_send_back_end.service.UserRatingService;
import com.bsz.school_send_back_end.service.UserService;
import io.swagger.v3.oas.annotations.tags.Tag;
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 jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
@Tag(name = "用户评分接口")
@RestController
@Slf4j
@RequestMapping("/level")
public class UserRatingController {
@Resource
private UserRatingService userRatingService;
@Resource
private UserService userService;
/**
* 添加用户评分
* @param userRatingAddRequest 用户评分请求
* @param request 当期那登录用户
* @return 是否添加成功
*/
@PostMapping("/add")
public BaseResponse<Boolean> addRating (@RequestBody UserRatingAddRequest userRatingAddRequest, HttpServletRequest request) {
if (userRatingAddRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
UserRating userRating = new UserRating();
BeanUtils.copyProperties(userRatingAddRequest, userRating);
userRatingService.validUserRating(userRating, request);
boolean save = userRatingService.save(userRating);
ThrowUtils.throwIf(!save, ErrorCode.SYSTEM_ERROR, "添加失败");
return ResultUtils.success(true);
}
/**
* 删除用户评分
* @param commonRequest 用户评分id
* @return 是否删除成功
*/
@PostMapping("/delete")
public BaseResponse<Boolean> deleteUserRating (@RequestBody CommonRequest commonRequest) {
if (commonRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
boolean remove = userRatingService.removeById(commonRequest.getId());
ThrowUtils.throwIf(!remove, ErrorCode.SYSTEM_ERROR, "删除失败");
return ResultUtils.success(true);
}
/**
* 展示当前用户评分
* @param request 当前用户
* @return 评分列表
*/
@PostMapping("/list")
public BaseResponse<List<UserRating>> listUserRating (@RequestBody CommonRequest commonRequest, HttpServletRequest request) {
if (commonRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long ratedEntityType = commonRequest.getId();
User loginUser = userService.getLoginUser(request);
Long userId = loginUser.getId();
List<UserRating> list = userRatingService.list(Wrappers.<UserRating>lambdaQuery()
.eq(UserRating::getUserId, userId).eq(UserRating::getRatedEntityType, ratedEntityType) );
return ResultUtils.success(list);
}
/**
* 展示当前用户评分
* @param request 当前用户
* @return 评分列表
*/
@PostMapping("/list/user")
public BaseResponse<List<UserRating>> listUserRatingByUser (HttpServletRequest request) {
List<UserRating> userRatings = userRatingService.listUserRatingByUser(request);
return ResultUtils.success(userRatings);
}
@PostMapping("/business/reply")
@AuthCheck(mustRole = UserConstant.BUSINESS_ROLE)
public BaseResponse<Boolean> businessReply (@RequestBody UserRatingReviewRequest userRatingReviewRequest, HttpServletRequest request) {
if (userRatingReviewRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long id = userRatingReviewRequest.getId();
String businessReview = userRatingReviewRequest.getBusinessReview();
userRatingService.validUserRatingByBusiness(id, request);
LambdaQueryWrapper<UserRating> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(UserRating::getId, id);
UserRating userRating = userRatingService.getOne(wrapper);
userRating.setBusinessReview(businessReview);
boolean update = userRatingService.updateById(userRating);
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR);
return ResultUtils.success(true);
}
@PostMapping("/list/business")
public BaseResponse<List<UserRating>> listUserRatingByBusiness (@RequestBody CommonRequest commonRequest) {
if (commonRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long businessId = commonRequest.getId();
List<UserRating> list = userRatingService.list(Wrappers.<UserRating>lambdaQuery()
.eq(UserRating::getRatedEntityId, businessId));
return ResultUtils.success(list);
}
}

View File

@ -0,0 +1,49 @@
package com.bsz.school_send_back_end.exception;
import com.bsz.school_send_back_end.common.ErrorCode;
/**
* 自定义异常类
*
*/
public class BusinessException extends RuntimeException {
/**
* 异常码
*/
private final int code;
/**
* 描述
*/
private final String description;
public BusinessException(String message, int code, String description) {
super(message);
this.code = code;
this.description = description;
}
public BusinessException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.code = errorCode.getCode();
this.description = errorCode.getDescription();
}
public BusinessException(ErrorCode errorCode, String description) {
super(errorCode.getMessage());
this.code = errorCode.getCode();
this.description = description;
}
public int getCode() {
return code;
}
public String getDescription() {
return description;
}
}

View File

@ -0,0 +1,30 @@
package com.bsz.school_send_back_end.exception;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 全局异常处理器
*
*/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public BaseResponse<?> businessExceptionHandler(BusinessException e) {
log.error("businessException: " + e.getMessage(), e);
return ResultUtils.error(e.getCode(), e.getMessage(), e.getDescription());
}
@ExceptionHandler(RuntimeException.class)
public BaseResponse<?> runtimeExceptionHandler(RuntimeException e) {
log.error("runtimeException", e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, e.getMessage(), "");
}
}

View File

@ -0,0 +1,44 @@
package com.bsz.school_send_back_end.exception;
import com.bsz.school_send_back_end.common.ErrorCode;
/**
* 抛异常工具类
*/
@SuppressWarnings("all")
public class ThrowUtils {
/**
* 条件成立则抛异常
*
* @param condition 条件
* @param runtimeException 运行时异常
*/
public static void throwIf(boolean condition, RuntimeException runtimeException) {
if (condition) {
throw runtimeException;
}
}
/**
* 条件成立则抛异常
*
* @param condition 条件
* @param errorCode 自定义异常
*/
public static void throwIf(boolean condition, ErrorCode errorCode) {
throwIf(condition, new BusinessException(errorCode));
}
/**
* 条件成立则抛异常
*
* @param condition 条件
* @param errorCode 自定义异常
* @param message 报错信息
*/
public static void throwIf(boolean condition, ErrorCode errorCode, String message) {
throwIf(condition, new BusinessException(errorCode, message));
}
}

View File

@ -0,0 +1,142 @@
package com.bsz.school_send_back_end.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bsz.school_send_back_end.common.ErrorCode;
import com.bsz.school_send_back_end.contant.RabbitMQConstant;
import com.bsz.school_send_back_end.exception.ThrowUtils;
import com.bsz.school_send_back_end.model.domain.Orders;
import com.bsz.school_send_back_end.model.domain.PrivateMessage;
import com.bsz.school_send_back_end.service.OrdersService;
import com.bsz.school_send_back_end.utils.MultiDelayMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;
import jakarta.annotation.Resource;
@Component
@Slf4j
public class RabbitMQReceiver {
@Resource
private OrdersService ordersService;
@Resource
private RabbitTemplate rabbitTemplate;
@RabbitListener(queues = RabbitMQConstant.TOPIC_QUEUE2)
public Orders receiveOrder (Orders message) {
log.info("接收数据:" + message);
return message;
}
@RabbitListener(queues = RabbitMQConstant.TOPIC_QUEUE1)
public PrivateMessage receive (PrivateMessage message) {
log.info("接收数据:" + message);
return message;
}
/**
* 过三分钟未支付自动取消
* @param msg
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(RabbitMQConstant.CANCEL_ORDER_QUEUE),
exchange = @Exchange(name = RabbitMQConstant.CANCEL_ORDER_EXCHANGE, delayed = "true"),
key = RabbitMQConstant.CANCEL_ORDER_ROUTING_KEY
))
public void handleExpiredOrder(MultiDelayMessage<Long> msg) {
Long orderId = msg.getData();
log.info("订单超时检查订单ID{}", orderId);
// 查询订单
LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Orders::getId, orderId);
Orders orders = ordersService.getOne(queryWrapper);
if (orders == null) {
log.warn("订单不存在订单ID{}", orderId);
return;
}
if (orders.getState() == 0) { // 订单仍未支付
if (msg.hasNextDelay()) {
// 还有下一个检查点,继续发送延迟消息
int nextDelay = msg.removeNextDelay().intValue();
rabbitTemplate.convertAndSend(RabbitMQConstant.CANCEL_ORDER_EXCHANGE,
RabbitMQConstant.CANCEL_ORDER_ROUTING_KEY, msg, message -> {
message.getMessageProperties().setDelay(nextDelay);
return message;
});
log.info("订单未支付,下一次检查延迟 {} 毫秒订单ID{}", nextDelay, orderId);
} else {
// **所有检查点都执行完,才执行订单取消**
log.info("订单超时未支付自动取消订单ID{}", orderId);
orders.setState(3); // 订单状态修改为已取消(假设 3 代表“已取消”)
boolean update = ordersService.updateById(orders);
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "订单取消失败");
log.info("订单超时已取消订单ID{}", orderId);
}
} else {
log.info("订单已支付无需取消订单ID{}", orderId);
}
}
/**
* 过三十分钟无人接单自动退款
* @param msg
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(RabbitMQConstant.DELIVERY_ORDER_QUEUE),
exchange = @Exchange(name = RabbitMQConstant.DELIVERY_DELAY_EXCHANGE, delayed = "true"),
key = RabbitMQConstant.DELIVERY_ORDER_ROUTING_KEY
))
public void handleExpiredDeliveryOrder(MultiDelayMessage<Long> msg) {
Long orderId = msg.getData();
log.info("外卖单超时检查订单ID{}", orderId);
// 查询订单
LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Orders::getId, orderId);
Orders orders = ordersService.getOne(queryWrapper);
if (orders == null) {
log.warn("外卖订单不存在订单ID{}", orderId);
return;
}
if (orders.getState() == 1) { // 外卖单仍未支付
// 外卖单超时退款逻辑
if (msg.hasNextDelay()) {
int nextDelay = msg.removeNextDelay().intValue();
rabbitTemplate.convertAndSend(RabbitMQConstant.DELIVERY_DELAY_EXCHANGE,
RabbitMQConstant.DELIVERY_ORDER_ROUTING_KEY, msg, message -> {
message.getMessageProperties().setDelay(nextDelay);
return message;
});
log.info("外卖单未接单,下一次检查延迟 {} 毫秒订单ID{}", nextDelay, orderId);
} else {
// 超过30分钟未接单自动退款
log.info("外卖单超时未接单自动退款订单ID{}", orderId);
orders.setState(2); // 订单状态修改为已退款
boolean update = ordersService.updateById(orders);
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "外卖单退款修改失败");
log.info("外卖单超时退款成功订单ID{}", orderId);
}
} else {
log.info("外卖单已支付无需退款订单ID{}", orderId);
}
}
}

View File

@ -0,0 +1,109 @@
package com.bsz.school_send_back_end.listener;
import com.bsz.school_send_back_end.contant.RabbitMQConstant;
import com.bsz.school_send_back_end.model.domain.Orders;
import com.bsz.school_send_back_end.model.domain.PrivateMessage;
import com.bsz.school_send_back_end.utils.MultiDelayMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;
import jakarta.annotation.Resource;
import java.util.*;
@Component
@Slf4j
public class RabbitMQSender {
@Resource
private AmqpTemplate amqpTemplate;
@Resource
private RabbitTemplate rabbitTemplate;
public void sendOrderMessage (Orders message) {
log.info("消息队列 MQSender 业务消息发送 send OrderMessage:" + message);
amqpTemplate.convertAndSend(RabbitMQConstant.TOPIC_QUEUE2,message, msg->{
msg.getMessageProperties().setReplyTo(RabbitMQConstant.ORDER_REPLY_QUEUE);
return msg;
});
}
public void sendPrivateMessage(PrivateMessage message) {
log.info("消息队列 MQSender 业务消息发送 send message:" + message);
amqpTemplate.convertAndSend(RabbitMQConstant.TOPIC_QUEUE1,message, msg->{
msg.getMessageProperties().setReplyTo(RabbitMQConstant.TOPIC_QUEUE1);
return msg;
});
}
// public void sendDelayedOrderMessage(long orderId, long delayMillis) {
// Map<String, Object> headers = new HashMap<>();
// headers.put("x-delay", delayMillis); // 设置延迟时间(毫秒)
//
// amqpTemplate.convertAndSend(
// RabbitMQConstant.DELAYED_EXCHANGE, // 交换机
// RabbitMQConstant.DELAYED_ROUTING_KEY, // 路由键
// orderId, // 消息内容(订单 ID
// message -> {
// message.getMessageProperties().getHeaders().putAll(headers); // 将延迟时间添加到消息头部
// return message;
// });
// log.info("发送延迟订单取消消息订单ID: " + orderId + ",延迟时间: " + delayMillis + "ms");
// }
//
//
// public void sendDelayedMessage() {
// // 设置延迟时间为 5 秒
// MessageProperties messageProperties = new MessageProperties();
// messageProperties.setHeader("x-delay", 5000); // 延迟时间(单位:毫秒)
// Message message = new Message("Hello, delayed world!".getBytes(), messageProperties);
//
// // 发送到延迟交换机
// amqpTemplate.send(RabbitMQConstant.DELAYED_EXCHANGE, RabbitMQConstant.DELAYED_ROUTING_KEY, message);
// log.info("发送延迟成功:" + new Date());
// }
public void sendCreateOrderMessage(Long orderId) {
// 复制 DELAY_MILLIS 到一个新的 ArrayList
List<Long> newDelayMillis = new ArrayList<>(RabbitMQConstant.DINE_IN_DELAY_MILLIS);
// 延迟检查订单状态信息
MultiDelayMessage<Long> msg = new MultiDelayMessage<>(orderId, newDelayMillis);
int delayValue = msg.removeNextDelay().intValue();
rabbitTemplate.convertAndSend(
RabbitMQConstant.CANCEL_ORDER_EXCHANGE,
RabbitMQConstant.CANCEL_ORDER_ROUTING_KEY,
msg,
message -> {
// 新版本设置延迟时间的方式
message.getMessageProperties()
.setHeader("x-delay", delayValue); // 单位:毫秒
return message;
}
);
log.info("发送成功orderID{}", orderId);
}
//自动退款30分钟未接单的
public void sendCreateDeliveryOrderMessage (Long orderId) {
List newDelayMillis = new ArrayList<>(RabbitMQConstant.DELIVERY_DELAY_MILLIS); // 假设延迟时间在此列表中
MultiDelayMessage msg = new MultiDelayMessage<>(orderId, newDelayMillis);
int delayValue = msg.removeNextDelay().intValue();
rabbitTemplate.convertAndSend(
RabbitMQConstant.DELIVERY_DELAY_EXCHANGE,
RabbitMQConstant.DELIVERY_ORDER_ROUTING_KEY,
msg,
message -> {
// 新版使用x-delay头设置延迟
message.getMessageProperties()
.setHeader("x-delay", delayValue); // 单位毫秒
return message;
}
);
log.info("外卖单延迟消息发送成功订单ID{}", orderId);
}
}

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,155 @@
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.RedisSessionRepository;
import org.springframework.stereotype.Component;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.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 RedisSessionRepository sessionRepository; // 正确,类型匹配
@Value("${spring.session.timeout}")
private long sessionTimeout;
@Lazy
@Resource
private UserService userService;
/**
* 登录
*/
public String login (User user, String appName, 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)
.appName(appName).
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.opsForHash().put(userExtraInfoKey, APPNAME,userLoginRedisInfo.getAppName());
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,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.Attribute;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface AttributeMapper extends BaseMapper<Attribute> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.BusinessAuth;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface BusinessAuthMapper extends BaseMapper<BusinessAuth> {
}

View File

@ -0,0 +1,17 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.BusinessLevel;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @author xy
*/
public interface BusinessLevelMapper extends BaseMapper<BusinessLevel> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.Business;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface BusinessMapper extends BaseMapper<Business> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bsz.school_send_back_end.model.domain.Businessinfo;
/**
* @author xy
*/
public interface BusinessinfoMapper extends BaseMapper<Businessinfo> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.Cart;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface CartMapper extends BaseMapper<Cart> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.Category;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface CategoryMapper extends BaseMapper<Category> {
}

View File

@ -0,0 +1,15 @@
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 xy
*/
public interface CollectMapper extends BaseMapper<Collect> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bsz.school_send_back_end.model.domain.DishesGroup;
/**
* @author xy
*/
public interface DishesGroupMapper extends BaseMapper<DishesGroup> {
}

View File

@ -0,0 +1,16 @@
package com.bsz.school_send_back_end.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bsz.school_send_back_end.model.domain.Dishes;
/**
* @author xy
*/
public interface DishesMapper extends BaseMapper<Dishes> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.ErrandAuth;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface ErrandAuthMapper extends BaseMapper<ErrandAuth> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.ErrandBill;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface ErrandBillMapper extends BaseMapper<ErrandBill> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.ErrandIncome;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface ErrandIncomeMapper extends BaseMapper<ErrandIncome> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.ErrandLevel;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface ErrandLevelMapper extends BaseMapper<ErrandLevel> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.Errand;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface ErrandMapper extends BaseMapper<Errand> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.ErrandOrder;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface ErrandOrderMapper extends BaseMapper<ErrandOrder> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.OrderDetails;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface OrderDetailsMapper extends BaseMapper<OrderDetails> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.OrderImage;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface OrderImageMapper extends BaseMapper<OrderImage> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.OrderRefunds;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface OrderRefundsMapper extends BaseMapper<OrderRefunds> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.Orders;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface OrdersMapper extends BaseMapper<Orders> {
}

View File

@ -0,0 +1,15 @@
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 xy
*/
public interface PrivateMessageMapper extends BaseMapper<PrivateMessage> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.SpecificationsDishes;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface SpecificationsDishesMapper extends BaseMapper<SpecificationsDishes> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bsz.school_send_back_end.model.domain.Specifications;
/**
* @author xy
*/
public interface SpecificationsMapper extends BaseMapper<Specifications> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.Systeminfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface SysteminfoMapper extends BaseMapper<Systeminfo> {
}

View File

@ -0,0 +1,15 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.Systemlog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author xy
*/
public interface SystemlogMapper extends BaseMapper<Systemlog> {
}

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.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
/**
* @author xy
*/
@Mapper
public interface UserMapper extends BaseMapper<User> {
}

View File

@ -0,0 +1,20 @@
package com.bsz.school_send_back_end.mapper;
import com.bsz.school_send_back_end.model.domain.UserRating;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
/**
* @author xy
*/
public interface UserRatingMapper extends BaseMapper<UserRating> {
@Select("select avg(rating) from school_send.user_rating where ratedEntityId = #{ratedEntityId}")
// @Select("select avg(rating) from xiaokuaisong.user_rating where ratedEntityId = #{ratedEntityId}")
Double findAvgByRatedEntityId(@Param("ratedEntityId") Long ratedEntityId);
}

View File

@ -0,0 +1,59 @@
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.Serial;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
* 属性表
* @TableName attribute
*/
@TableName(value ="attribute")
@Data
public class Attribute implements Serializable {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 商家id
*/
private Long businessId;
/**
* 规格id
*/
private Long specificationsId;
/**
* 属性名称
*/
private String attributeName;
/**
* 属性状态:0在售,1停售
*/
private Integer attributeStatus;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
@Serial
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,106 @@
package com.bsz.school_send_back_end.model.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 商家
*
* @TableName business
*/
@TableName(value = "business")
@Data
public class Business implements Serializable {
/**
* id
*/
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
* 用户id
*/
private Long userId;
/**
* 门店名称
*/
private String businessName;
/**
* 门店头像
*/
private String businessAvatar;
/**
* 门店手机号
*/
private String businessPhone;
/**
* 店铺详细地址
*/
private String address;
/**
* 门店简介
*/
private String businessProfile;
/**
* 商家相册
*/
private String businessImages;
/**
* 分类id
*/
private Long categoryId;
/**
* 开始营业时间
*/
private String startBusiness;
/**
* 结束营业时间
*/
private String endBusiness;
/**
* 状态:0禁用,1启用
*/
private Integer state;
/**
* 店铺状态:0休业,1营业
*/
private Integer storeStatus;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 是否删除
*/
@TableLogic
private Integer isDelete;
@Serial
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,72 @@
package com.bsz.school_send_back_end.model.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 商家
* @TableName business_auth
*/
@TableName(value ="business_auth")
@Data
public class BusinessAuth implements Serializable {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 店铺id
*/
private Long businessId;
/**
* 店主名
*/
private String shopkeeper;
/**
* 营业执照
*/
private String license;
/**
* 身份证正面
*/
private String frontIdCard;
/**
* 身份证反面
*/
private String backIdCard;
/**
* 银行卡号
*/
private String bankCard;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 是否删除
*/
@TableLogic
private Integer isDelete;
@Serial
@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.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import lombok.Data;
/**
*
* @TableName business_level
*/
@TableName(value ="business_level")
@Data
public class BusinessLevel implements Serializable {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 商家id
*/
private Long businessId;
/**
* 综合评分
*/
private BigDecimal averageScore;
/**
* 等级
*/
private Integer level;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
@TableField(exist = false)
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,41 @@
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 java.util.Date;
import lombok.Data;
/**
* 系统信息
* @TableName businessinfo
*/
@TableName(value ="businessinfo")
@Data
public class Businessinfo implements Serializable {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 商家id
*/
private Long businessId;
/**
* 功能内容
*/
private String content;
/**
* 创建时间
*/
private Date createTime;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,78 @@
package com.bsz.school_send_back_end.model.domain;
import com.baomidou.mybatisplus.annotation.*;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import lombok.Data;
/**
* 购物车表
* @TableName cart
*/
@TableName(value ="cart")
@Data
public class Cart implements Serializable {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 用户id
*/
private Long userId;
/**
* 商家id
*/
private Long businessId;
/**
* 加入购物车时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 菜品id
*/
private Long dishesId;
/**
* 商品数量
*/
private Integer quantity;
/**
* 当前选择规格的价格
*/
private BigDecimal price;
/**
* 小计(单价 * 数量)
*/
private BigDecimal subtotal;
/**
* 已选规格属性列表
*/
private String selectedOptions;
/**
* 是否删除
*/
@TableLogic
private Integer isDelete;
@Serial
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,46 @@
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 java.util.Date;
import lombok.Data;
/**
* 分类表
* @TableName category
*/
@TableName(value ="category")
@Data
public class Category implements Serializable {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 分类名
*/
private String name;
/**
* 分类图片
*/
private String image;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

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,83 @@
package com.bsz.school_send_back_end.model.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 菜品表
* @TableName dishes
*/
@TableName(value ="dishes")
@Data
public class Dishes implements Serializable {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 商家id
*/
private Long businessId;
/**
* 菜品分组id
*/
private Long dishesGroupId;
/**
* 菜品名称
*/
private String dishesName;
/**
* 菜品图片
*/
private String dishesImage;
/**
* 菜品价格
*/
private Double dishesPrice;
/**
* 打包费
*/
private Double packPrice;
/**
* 库存数量
*/
private Integer inventoryStatus;
/**
* 菜品状态:上架,下架
*/
private String status;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 是否删除
*/
@TableLogic
private Integer isDelete;
@Serial
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,57 @@
package com.bsz.school_send_back_end.model.domain;
import com.baomidou.mybatisplus.annotation.*;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
* 菜品分组表
* @TableName dishes_group
*/
@TableName(value ="dishes_group")
@Data
public class DishesGroup implements Serializable {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 商家id
*/
private Long businessId;
/**
* 菜品分组名称
*/
private String groupName;
/**
* 是否置顶:0不置顶,1置顶
*/
private Integer isTopping;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 是否删除
*/
@TableLogic
private Integer isDelete;
@Serial
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

Some files were not shown because too many files have changed in this diff Show More