commit 0822f8fa5c658fbfb9da44396687ff6ab4fe9ab4
Author: tsukiyalo <2450026988@qq.com>
Date: Mon Aug 18 09:07:54 2025 +0800
上传代码
diff --git a/school_lend_back_end/.gitignore b/school_lend_back_end/.gitignore
new file mode 100644
index 0000000..549e00a
--- /dev/null
+++ b/school_lend_back_end/.gitignore
@@ -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/
diff --git a/school_lend_back_end/deps.txt b/school_lend_back_end/deps.txt
new file mode 100644
index 0000000..7bdfb56
Binary files /dev/null and b/school_lend_back_end/deps.txt differ
diff --git a/school_lend_back_end/pom.xml b/school_lend_back_end/pom.xml
new file mode 100644
index 0000000..adf5997
--- /dev/null
+++ b/school_lend_back_end/pom.xml
@@ -0,0 +1,289 @@
+
+
+ 4.0.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.5
+
+
+
+ com.bsz
+ school_send_back_end
+ 0.0.1-SNAPSHOT
+ school_send_back_end
+ school_send_back_end
+
+
+ 17
+ 1.0.0-M2
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 3.0.3
+
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ 3.5.5
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.12.0
+
+
+
+ com.alipay.sdk
+ alipay-sdk-java
+ 4.38.0.ALL
+
+
+
+ cn.hutool
+ hutool-all
+ 5.8.16
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+ true
+
+
+
+ mysql
+ mysql-connector-java
+ 8.0.16
+ runtime
+
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ com.aliyun.oss
+ aliyun-sdk-oss
+ 3.15.1
+
+
+
+ com.github.xiaoymin
+ knife4j-spring-boot-starter
+ 3.0.3
+
+
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+
+
+ org.aspectj
+ aspectjtools
+ 1.9.21
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.30
+
+
+
+ com.alibaba
+ easyexcel
+ 3.3.3
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+
+ org.springframework.session
+ spring-session-data-redis
+
+
+
+ org.springframework.boot
+ spring-boot-starter-websocket
+
+
+
+ org.springframework.boot
+ spring-boot-starter-amqp
+
+
+
+ io.projectreactor
+ reactor-core
+ 3.5.12
+
+
+
+ io.netty
+ netty-all
+ 4.1.109.Final
+
+
+
+ io.projectreactor.netty
+ reactor-netty
+ 1.1.13
+
+
+
+ com.aliyun
+ aliyun-java-sdk-core
+ 4.5.16
+
+
+
+ com.aliyun
+ aliyun-java-sdk-dysmsapi
+ 2.1.0
+
+
+
+ com.github.ulisesbocchio
+ jasypt-spring-boot-starter
+ 3.0.5
+
+
+
+ com.github.houbb
+ sensitive-word
+ 0.23.0
+
+
+
+ commons-net
+ commons-net
+ 3.3
+
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
+
+
+ jakarta.servlet
+ jakarta.servlet-api
+ 6.0.0
+ provided
+
+
+
+ jakarta.websocket
+ jakarta.websocket-api
+ 2.1.0
+ provided
+
+
+
+ org.springdoc
+ springdoc-openapi-starter-webmvc-ui
+ 2.5.0
+
+
+
+ org.springframework
+ spring-core
+
+
+
+ io.swagger.core.v3
+ swagger-core
+ 2.2.20
+
+
+
+
+ com.alibaba.cloud.ai
+ spring-ai-alibaba-starter
+ 1.0.0-M2.1
+
+
+
+
+
+
+
+
+ spring-releases
+ https://repo.spring.io/release
+
+
+ knife4j
+ https://s01.oss.sonatype.org/content/repositories/releases/
+
+
+ central
+ https://repo.maven.apache.org/maven2
+
+
+ spring-milestones
+ Spring Milestone Repository
+ https://repo.spring.io/milestone
+
+
+
+
+
+
+ org.springframework.ai
+ spring-ai-bom
+ ${spring-ai.version}
+ pom
+ import
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 17
+ 17
+
+
+
+
+
+
diff --git a/school_lend_back_end/sql/create_table.sql b/school_lend_back_end/sql/create_table.sql
new file mode 100644
index 0000000..906dadc
--- /dev/null
+++ b/school_lend_back_end/sql/create_table.sql
@@ -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;
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/UserCenterApplication.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/UserCenterApplication.java
new file mode 100644
index 0000000..3e8b72d
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/UserCenterApplication.java
@@ -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();
+ }
+}
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/annotation/AuthCheck.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/annotation/AuthCheck.java
new file mode 100644
index 0000000..793da80
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/annotation/AuthCheck.java
@@ -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 "";
+
+}
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/annotation/SystemLog.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/annotation/SystemLog.java
new file mode 100644
index 0000000..892175e
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/annotation/SystemLog.java
@@ -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 "";
+}
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/aop/AuthInterceptor.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/aop/AuthInterceptor.java
new file mode 100644
index 0000000..9b879cd
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/aop/AuthInterceptor.java
@@ -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();
+ }
+}
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/aop/SystemLogInterceptor.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/aop/SystemLogInterceptor.java
new file mode 100644
index 0000000..f973e24
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/aop/SystemLogInterceptor.java
@@ -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();
+ }
+
+}
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/common/BaseResponse.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/common/BaseResponse.java
new file mode 100644
index 0000000..fc88d5f
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/common/BaseResponse.java
@@ -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 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());
+ }
+}
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/common/ErrorCode.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/common/ErrorCode.java
new file mode 100644
index 0000000..186a988
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/common/ErrorCode.java
@@ -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;
+ }
+}
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/common/ResultUtils.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/common/ResultUtils.java
new file mode 100644
index 0000000..2c7b69b
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/common/ResultUtils.java
@@ -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
+ * @return
+ */
+ public static BaseResponse success(T data) {
+ return new BaseResponse<>(0, data, "ok");
+ }
+
+ public static BaseResponse 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);
+ }
+
+}
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/AIConfig.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/AIConfig.java
new file mode 100644
index 0000000..3ac4276
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/AIConfig.java
@@ -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> getBusinessByAI() {
+ List allBusiness = businessService.findAllBusiness();
+ return unused -> allBusiness.stream()
+ .filter(businessVO -> businessVO.getLevel() == 5)
+ .toList();
+ }
+
+// @Bean
+// @Description("推荐菜品")
+// public Function> getDishesByAI() {
+// new LocalTime
+// }
+}
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/AliPayNotifyHandler.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/AliPayNotifyHandler.java
new file mode 100644
index 0000000..7124d34
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/AliPayNotifyHandler.java
@@ -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
+ Map params = new HashMap<>();
+ Enumeration 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");
+ }
+ }
+}
\ No newline at end of file
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/AlipayClients.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/AlipayClients.java
new file mode 100644
index 0000000..42593be
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/AlipayClients.java
@@ -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;
+ }
+
+}
+
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/CorsConfig.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/CorsConfig.java
new file mode 100644
index 0000000..c9c2bec
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/CorsConfig.java
@@ -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("*");
+ }
+}
\ No newline at end of file
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/JsonConfig.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/JsonConfig.java
new file mode 100644
index 0000000..29d4503
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/JsonConfig.java
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/Knife4jConfig.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/Knife4jConfig.java
new file mode 100644
index 0000000..2428ecb
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/Knife4jConfig.java
@@ -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();
+ }
+}
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/MyBatisPlusConfig.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/MyBatisPlusConfig.java
new file mode 100644
index 0000000..450f301
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/MyBatisPlusConfig.java
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/RabbitMQConfig.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/RabbitMQConfig.java
new file mode 100644
index 0000000..954c0da
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/RabbitMQConfig.java
@@ -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 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();
+ }
+
+}
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/RabbitMQConfigProperties.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/RabbitMQConfigProperties.java
new file mode 100644
index 0000000..89f11ea
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/RabbitMQConfigProperties.java
@@ -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;
+}
diff --git a/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/RedisSessionRepositoryConfig.java b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/RedisSessionRepositoryConfig.java
new file mode 100644
index 0000000..1097b53
--- /dev/null
+++ b/school_lend_back_end/src/main/java/com/bsz/school_send_back_end/config/RedisSessionRepositoryConfig.java
@@ -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