diff --git a/Task3.md b/Task3.md new file mode 100644 index 0000000..f92046b --- /dev/null +++ b/Task3.md @@ -0,0 +1,71 @@ +``` +-- yitisheng.yx_user_score definition + +CREATE TABLE `yx_user_score` ( + `id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `type` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '1' COMMENT '填报类型(1-普通类 2-艺术类)', + `educational_level` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '1' COMMENT '学历层次(1-本科,2-专科)', + `professional_category` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '美术类' COMMENT '专业类别(美术类/...)', + `subjects` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '选课', + `professional_score` decimal(10,0) DEFAULT '0' COMMENT '专业成绩分', + `cultural_score` decimal(10,0) DEFAULT '0' COMMENT '文化成绩分', + `ranking` int DEFAULT '0' COMMENT '位次', + `create_by` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '修改人', + `update_time` datetime DEFAULT NULL COMMENT '修改时间', + `state` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '1' COMMENT '状态(0-未使用,1-使用中)', + `province` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '北京' COMMENT '高考省份', + `cognitio_polyclinic` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '文理分班(文科/理科)', + `batch` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '录取批次', + `english_score` decimal(10,2) DEFAULT '0.00' COMMENT '英语成绩', + `chinese_score` decimal(10,2) DEFAULT '0.00' COMMENT '语文成绩', + `yybysy` decimal(10,2) DEFAULT '0.00' COMMENT '音乐表演声乐', + `yybyqy` decimal(10,2) DEFAULT '0.00' COMMENT '音乐表演器乐', + `yyjy` decimal(10,2) DEFAULT '0.00' COMMENT '音乐教育', + `xjysdy` decimal(10,2) DEFAULT '0.00' COMMENT '戏剧影视导演', + `xjysby` decimal(10,2) DEFAULT '0.00' COMMENT '戏剧影视表演', + `fzby` decimal(10,2) DEFAULT '0.00' COMMENT '服装表演', + `professional_category_children` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '子级专业类别', + `kbd_num` int DEFAULT '0' COMMENT '可保底专业数量', + `nlq_num` int DEFAULT '0' COMMENT '难录取专业数量', + `kcj_num` int DEFAULT '0' COMMENT '可冲击专业数量', + `jwt_num` int DEFAULT '0' COMMENT '较稳妥专业数量', + `calculation_table_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '记录结果表名', + PRIMARY KEY (`id`) USING BTREE, + KEY `a_create_by` (`create_by`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户分数信息表'; + +CREATE TABLE `yx_volunteer` ( + `id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `volunteer_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '志愿单名称', + `score_id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '使用成绩id', + `create_type` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '1' COMMENT '生成类型(1.手动生成,2.智能生成)', + `state` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '志愿单状态(0-否,1.正在使用,2-历史)', + `create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `update_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新人', + `update_time` datetime DEFAULT NULL COMMENT '更新日期', + `sys_org_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '所属部门', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='志愿表'; + +CREATE TABLE `yx_volunteer_record` ( + `id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `volunteer_id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '志愿单id', + `school_code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '学校编码', + `major_code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '专业编码', + `enrollment_code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '招生代码', + `indexs` int DEFAULT '1' COMMENT '志愿顺序', + `create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人', + `create_time` datetime DEFAULT NULL COMMENT '创建日期', + `batch` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '录取批次', + `enroll_probability` decimal(10,4) DEFAULT '0.0000' COMMENT '录取概率', + `student_converted_score` decimal(10,4) DEFAULT '0.0000' COMMENT '折合分数', + `fctj` int DEFAULT '0' COMMENT '服从调剂', + `calculation_major_id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '专业折算id', + PRIMARY KEY (`id`) USING BTREE, + KEY `a_volunteer_id` (`volunteer_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='志愿明细表'; +``` +创建表的常规代码到 modules/yx/ 的分层模块下, Entity、Mapper、Service、Controller 等文件。 diff --git a/project_codebase.md b/project_codebase.md new file mode 100644 index 0000000..0ff1931 --- /dev/null +++ b/project_codebase.md @@ -0,0 +1,25 @@ +# 代码库函数概览 + +## server/common +- `Response`: 统一的HTTP响应结构体 `{Code, Message, Data}`。 +- `Success(c *gin.Context, data interface{})`: 发送成功响应。 +- `Error(c *gin.Context, code int, msg string)`: 发送错误响应。 + +## server/config +- `InitDB()`: 初始化GORM数据库连接。 +- `InitRedis()`: 初始化Redis客户端。 +- `AppConfig`: 全局配置变量,包含 `Log`, `Security`, `RateLimit`, `Swagger` 配置。 + +## server/middleware +- `AuthMiddleware`: JWT认证中间件。 +- `SecurityMiddleware`: 安全校验中间件(请求头签名)。 +- `RateLimitMiddleware`: 接口限流中间件。 +- `CorsMiddleware`: 跨域资源共享中间件。 + +## server/modules/yx +- `YxSchoolMajorController`: 院校专业控制器。 +- `YxHistoryMajorEnrollController`: 历年招生记录控制器。 +- `YxCalculationMajorController`: 计算专业控制器。 +- `YxUserScoreController`: 用户分数控制器。 +- `YxVolunteerController`: 志愿控制器。 +- `YxVolunteerRecordController`: 志愿明细控制器。 diff --git a/project_doing.md b/project_doing.md new file mode 100644 index 0000000..7bd74c8 --- /dev/null +++ b/project_doing.md @@ -0,0 +1,31 @@ +# 项目过程记录 + +## 2025-12-17 +### [任务执行] 初始化模块 yitisheng/yx_user_score +- **操作目标**: 创建新的业务模块目录,并准备实现用户分数和志愿管理功能。 +- **影响范围**: `server/modules/yitisheng/yx_user_score/` +- **修改前记录**: 项目中暂无此模块。 + +### [任务执行] 修正模块路径并实现 CRUD +- **操作目标**: 根据 Task3.md 要求,将 yx_user_score, yx_volunteer, yx_volunteer_record 实现于 modules/yx/ 下。 +- **影响范围**: `server/modules/yx/` +- **修改结果**: + - 删除了错误的 `modules/yitisheng` 目录(尝试删除)。 + - 在 `modules/yx` 下实现了 Entity, Mapper, Service, Controller。 + - 更新了 `main.go` 注册路由。 + +### [任务执行] 增加 Swagger 文档访问密码验证 +- **操作目标**: 为 Swagger 文档接口添加 Basic Auth 验证,防止未授权访问。 +- **影响范围**: `server/config/config.go`, `server/main.go` +- **修改前记录**: Swagger 接口公开,无验证。 +- **修改结果**: + - `server/config/config.go`: 新增 `SwaggerConfig` 配置项 (默认 admin/password)。 + - `server/main.go`: 为 `/swagger` 路由组添加了 `gin.BasicAuth` 中间件。 + +### [任务执行] 解决本地调试 CORS 问题 +- **操作目标**: 允许前端 Vue3 项目跨域调用后端接口。 +- **影响范围**: `server/middleware/cors.go`, `server/main.go` +- **修改前记录**: 后端未配置 CORS,前端跨域请求被拦截。 +- **修改结果**: + - `server/middleware/cors.go`: 创建了 CORS 中间件,允许 `Origin` 头部指定的来源,并放行 `OPTIONS` 请求。 + - `server/main.go`: 全局注册了 CORS 中间件。 diff --git a/project_index.md b/project_index.md new file mode 100644 index 0000000..cb08062 --- /dev/null +++ b/project_index.md @@ -0,0 +1,26 @@ +# 项目文件索引 + +## server/ +- `main.go`: 应用程序入口,负责路由注册和服务器启动。 +- `config/`: 配置文件目录。 + - `config.go`: 应用全局配置。 + - `database.go`: 数据库连接配置。 + - `redis.go`: Redis连接配置。 +- `common/`: 通用工具包。 + - `response.go`: 统一HTTP响应结构。 + - `context.go`: 上下文辅助函数。 + - `logger.go`: 日志工具。 + - `password.go`: 密码加密工具。 +- `middleware/`: HTTP中间件。 + - `auth.go`: JWT认证中间件。 + - `security.go`: 安全相关的中间件。 + - `ratelimit.go`: 限流中间件。 + - `cors.go`: CORS跨域中间件。 +- `modules/`: 业务模块目录。 + - `system/`: 系统管理模块(用户、权限等)。 + - `yx/`: 艺考相关业务模块。 + - `entity/`: 实体定义。 + - `mapper/`: 数据访问层实现。 + - `service/`: 业务逻辑层实现。 + - `controller/`: 控制层实现。 +- `docs/`: Swagger API文档。 diff --git a/project_task.md b/project_task.md new file mode 100644 index 0000000..4861a26 --- /dev/null +++ b/project_task.md @@ -0,0 +1,9 @@ +# 项目任务规划 + +## [进行中] 模块开发: yx +- [已完成] 初始化模块目录结构 (yx_user_score, yx_volunteer, yx_volunteer_record 归入 yx 模块) +- [已完成] 实现 yx_user_score 表相关代码 (Entity, Mapper, Service, Controller) +- [已完成] 实现 yx_volunteer 表相关代码 (Entity, Mapper, Service, Controller) +- [已完成] 实现 yx_volunteer_record 表相关代码 (Entity, Mapper, Service, Controller) +- [已完成] 注册新路由 +- [未开始] 验证与测试 diff --git a/server/config/config.go b/server/config/config.go index 35d6824..3d365eb 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -24,12 +24,18 @@ var AppConfig = &appConfig{ "/api/yx-school-majors": {Interval: 1, MaxRequests: 5}, // 查询1秒5次 }, }, + // Swagger配置 + Swagger: SwaggerConfig{ + User: "admin", + Password: "password", + }, } type appConfig struct { Log LogConfig Security SecurityConfig RateLimit RateLimitConfig + Swagger SwaggerConfig } // LogConfig 日志配置 @@ -58,3 +64,9 @@ type RateLimitRule struct { Interval int // 时间间隔(秒) MaxRequests int // 最大请求次数 } + +// SwaggerConfig Swagger文档认证配置 +type SwaggerConfig struct { + User string + Password string +} diff --git a/server/docs/docs.go b/server/docs/docs.go index 85fca27..40e36cd 100644 --- a/server/docs/docs.go +++ b/server/docs/docs.go @@ -15,6 +15,39 @@ const docTemplate = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { + "/auth/Sys/login": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "认证" + ], + "summary": "Sys用户登录", + "parameters": [ + { + "description": "登录信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controller.LoginRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + } + }, "/auth/info": { "get": { "tags": [ @@ -959,6 +992,417 @@ const docTemplate = `{ } } } + }, + "/yx-user-scores": { + "get": { + "tags": [ + "用户分数" + ], + "summary": "获取用户分数列表", + "parameters": [ + { + "type": "integer", + "default": 1, + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "每页数量", + "name": "size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "post": { + "tags": [ + "用户分数" + ], + "summary": "创建用户分数", + "parameters": [ + { + "description": "用户分数信息", + "name": "item", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/entity.YxUserScore" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + } + }, + "/yx-user-scores/{id}": { + "get": { + "tags": [ + "用户分数" + ], + "summary": "获取单个用户分数", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "put": { + "tags": [ + "用户分数" + ], + "summary": "更新用户分数", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "用户分数信息", + "name": "item", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/entity.YxUserScore" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "delete": { + "tags": [ + "用户分数" + ], + "summary": "删除用户分数", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + } + }, + "/yx-volunteer-records": { + "get": { + "tags": [ + "志愿明细" + ], + "summary": "获取志愿明细列表", + "parameters": [ + { + "type": "integer", + "default": 1, + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "每页数量", + "name": "size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "post": { + "tags": [ + "志愿明细" + ], + "summary": "创建志愿明细", + "parameters": [ + { + "description": "志愿明细信息", + "name": "item", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/entity.YxVolunteerRecord" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + } + }, + "/yx-volunteer-records/{id}": { + "get": { + "tags": [ + "志愿明细" + ], + "summary": "获取单个志愿明细", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "put": { + "tags": [ + "志愿明细" + ], + "summary": "更新志愿明细", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "志愿明细信息", + "name": "item", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/entity.YxVolunteerRecord" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "delete": { + "tags": [ + "志愿明细" + ], + "summary": "删除志愿明细", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + } + }, + "/yx-volunteers": { + "get": { + "tags": [ + "志愿" + ], + "summary": "获取志愿列表", + "parameters": [ + { + "type": "integer", + "default": 1, + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "每页数量", + "name": "size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "post": { + "tags": [ + "志愿" + ], + "summary": "创建志愿", + "parameters": [ + { + "description": "志愿信息", + "name": "item", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/entity.YxVolunteer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + } + }, + "/yx-volunteers/{id}": { + "get": { + "tags": [ + "志愿" + ], + "summary": "获取单个志愿", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "put": { + "tags": [ + "志愿" + ], + "summary": "更新志愿", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "志愿信息", + "name": "item", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/entity.YxVolunteer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "delete": { + "tags": [ + "志愿" + ], + "summary": "删除志愿", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + } } }, "definitions": { @@ -1418,6 +1862,230 @@ const docTemplate = `{ "type": "string" } } + }, + "entity.YxUserScore": { + "type": "object", + "properties": { + "batch": { + "description": "录取批次", + "type": "string" + }, + "calculationTableName": { + "description": "记录结果表名", + "type": "string" + }, + "chineseScore": { + "description": "语文成绩", + "type": "number" + }, + "cognitioPolyclinic": { + "description": "文理分班(文科/理科)", + "type": "string" + }, + "createBy": { + "description": "创建人", + "type": "string" + }, + "createTime": { + "description": "创建时间", + "type": "string" + }, + "culturalScore": { + "description": "文化成绩分", + "type": "number" + }, + "educationalLevel": { + "description": "学历层次(1-本科,2-专科)", + "type": "string" + }, + "englishScore": { + "description": "英语成绩", + "type": "number" + }, + "fzby": { + "description": "服装表演", + "type": "number" + }, + "id": { + "type": "string" + }, + "jwtNum": { + "description": "较稳妥专业数量", + "type": "integer" + }, + "kbdNum": { + "description": "可保底专业数量", + "type": "integer" + }, + "kcjNum": { + "description": "可冲击专业数量", + "type": "integer" + }, + "nlqNum": { + "description": "难录取专业数量", + "type": "integer" + }, + "professionalCategory": { + "description": "专业类别(美术类/...)", + "type": "string" + }, + "professionalCategoryChildren": { + "description": "子级专业类别", + "type": "string" + }, + "professionalScore": { + "description": "专业成绩分", + "type": "number" + }, + "province": { + "description": "高考省份", + "type": "string" + }, + "ranking": { + "description": "位次", + "type": "integer" + }, + "state": { + "description": "状态(0-未使用,1-使用中)", + "type": "string" + }, + "subjects": { + "description": "选课", + "type": "string" + }, + "type": { + "description": "填报类型(1-普通类 2-艺术类)", + "type": "string" + }, + "updateBy": { + "description": "修改人", + "type": "string" + }, + "updateTime": { + "description": "修改时间", + "type": "string" + }, + "xjysby": { + "description": "戏剧影视表演", + "type": "number" + }, + "xjysdy": { + "description": "戏剧影视导演", + "type": "number" + }, + "yybyqy": { + "description": "音乐表演器乐", + "type": "number" + }, + "yybysy": { + "description": "音乐表演声乐", + "type": "number" + }, + "yyjy": { + "description": "音乐教育", + "type": "number" + } + } + }, + "entity.YxVolunteer": { + "type": "object", + "properties": { + "createBy": { + "description": "创建人", + "type": "string" + }, + "createTime": { + "description": "创建日期", + "type": "string" + }, + "createType": { + "description": "生成类型(1.手动生成,2.智能生成)", + "type": "string" + }, + "id": { + "type": "string" + }, + "scoreId": { + "description": "使用成绩id", + "type": "string" + }, + "state": { + "description": "志愿单状态(0-否,1.正在使用,2-历史)", + "type": "string" + }, + "sysOrgCode": { + "description": "所属部门", + "type": "string" + }, + "updateBy": { + "description": "更新人", + "type": "string" + }, + "updateTime": { + "description": "更新日期", + "type": "string" + }, + "volunteerName": { + "description": "志愿单名称", + "type": "string" + } + } + }, + "entity.YxVolunteerRecord": { + "type": "object", + "properties": { + "batch": { + "description": "录取批次", + "type": "string" + }, + "calculationMajorId": { + "description": "专业折算id", + "type": "string" + }, + "createBy": { + "description": "创建人", + "type": "string" + }, + "createTime": { + "description": "创建日期", + "type": "string" + }, + "enrollProbability": { + "description": "录取概率", + "type": "number" + }, + "enrollmentCode": { + "description": "招生代码", + "type": "string" + }, + "fctj": { + "description": "服从调剂", + "type": "integer" + }, + "id": { + "type": "string" + }, + "indexs": { + "description": "志愿顺序", + "type": "integer" + }, + "majorCode": { + "description": "专业编码", + "type": "string" + }, + "schoolCode": { + "description": "学校编码", + "type": "string" + }, + "studentConvertedScore": { + "description": "折合分数", + "type": "number" + }, + "volunteerId": { + "description": "志愿单id", + "type": "string" + } + } } }, "securityDefinitions": { diff --git a/server/docs/swagger.json b/server/docs/swagger.json index b823853..39a85eb 100644 --- a/server/docs/swagger.json +++ b/server/docs/swagger.json @@ -9,6 +9,39 @@ "host": "localhost:8080", "basePath": "/api", "paths": { + "/auth/Sys/login": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "认证" + ], + "summary": "Sys用户登录", + "parameters": [ + { + "description": "登录信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/controller.LoginRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + } + }, "/auth/info": { "get": { "tags": [ @@ -953,6 +986,417 @@ } } } + }, + "/yx-user-scores": { + "get": { + "tags": [ + "用户分数" + ], + "summary": "获取用户分数列表", + "parameters": [ + { + "type": "integer", + "default": 1, + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "每页数量", + "name": "size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "post": { + "tags": [ + "用户分数" + ], + "summary": "创建用户分数", + "parameters": [ + { + "description": "用户分数信息", + "name": "item", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/entity.YxUserScore" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + } + }, + "/yx-user-scores/{id}": { + "get": { + "tags": [ + "用户分数" + ], + "summary": "获取单个用户分数", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "put": { + "tags": [ + "用户分数" + ], + "summary": "更新用户分数", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "用户分数信息", + "name": "item", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/entity.YxUserScore" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "delete": { + "tags": [ + "用户分数" + ], + "summary": "删除用户分数", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + } + }, + "/yx-volunteer-records": { + "get": { + "tags": [ + "志愿明细" + ], + "summary": "获取志愿明细列表", + "parameters": [ + { + "type": "integer", + "default": 1, + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "每页数量", + "name": "size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "post": { + "tags": [ + "志愿明细" + ], + "summary": "创建志愿明细", + "parameters": [ + { + "description": "志愿明细信息", + "name": "item", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/entity.YxVolunteerRecord" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + } + }, + "/yx-volunteer-records/{id}": { + "get": { + "tags": [ + "志愿明细" + ], + "summary": "获取单个志愿明细", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "put": { + "tags": [ + "志愿明细" + ], + "summary": "更新志愿明细", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "志愿明细信息", + "name": "item", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/entity.YxVolunteerRecord" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "delete": { + "tags": [ + "志愿明细" + ], + "summary": "删除志愿明细", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + } + }, + "/yx-volunteers": { + "get": { + "tags": [ + "志愿" + ], + "summary": "获取志愿列表", + "parameters": [ + { + "type": "integer", + "default": 1, + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "每页数量", + "name": "size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "post": { + "tags": [ + "志愿" + ], + "summary": "创建志愿", + "parameters": [ + { + "description": "志愿信息", + "name": "item", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/entity.YxVolunteer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + } + }, + "/yx-volunteers/{id}": { + "get": { + "tags": [ + "志愿" + ], + "summary": "获取单个志愿", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "put": { + "tags": [ + "志愿" + ], + "summary": "更新志愿", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "志愿信息", + "name": "item", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/entity.YxVolunteer" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + }, + "delete": { + "tags": [ + "志愿" + ], + "summary": "删除志愿", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/common.Response" + } + } + } + } } }, "definitions": { @@ -1412,6 +1856,230 @@ "type": "string" } } + }, + "entity.YxUserScore": { + "type": "object", + "properties": { + "batch": { + "description": "录取批次", + "type": "string" + }, + "calculationTableName": { + "description": "记录结果表名", + "type": "string" + }, + "chineseScore": { + "description": "语文成绩", + "type": "number" + }, + "cognitioPolyclinic": { + "description": "文理分班(文科/理科)", + "type": "string" + }, + "createBy": { + "description": "创建人", + "type": "string" + }, + "createTime": { + "description": "创建时间", + "type": "string" + }, + "culturalScore": { + "description": "文化成绩分", + "type": "number" + }, + "educationalLevel": { + "description": "学历层次(1-本科,2-专科)", + "type": "string" + }, + "englishScore": { + "description": "英语成绩", + "type": "number" + }, + "fzby": { + "description": "服装表演", + "type": "number" + }, + "id": { + "type": "string" + }, + "jwtNum": { + "description": "较稳妥专业数量", + "type": "integer" + }, + "kbdNum": { + "description": "可保底专业数量", + "type": "integer" + }, + "kcjNum": { + "description": "可冲击专业数量", + "type": "integer" + }, + "nlqNum": { + "description": "难录取专业数量", + "type": "integer" + }, + "professionalCategory": { + "description": "专业类别(美术类/...)", + "type": "string" + }, + "professionalCategoryChildren": { + "description": "子级专业类别", + "type": "string" + }, + "professionalScore": { + "description": "专业成绩分", + "type": "number" + }, + "province": { + "description": "高考省份", + "type": "string" + }, + "ranking": { + "description": "位次", + "type": "integer" + }, + "state": { + "description": "状态(0-未使用,1-使用中)", + "type": "string" + }, + "subjects": { + "description": "选课", + "type": "string" + }, + "type": { + "description": "填报类型(1-普通类 2-艺术类)", + "type": "string" + }, + "updateBy": { + "description": "修改人", + "type": "string" + }, + "updateTime": { + "description": "修改时间", + "type": "string" + }, + "xjysby": { + "description": "戏剧影视表演", + "type": "number" + }, + "xjysdy": { + "description": "戏剧影视导演", + "type": "number" + }, + "yybyqy": { + "description": "音乐表演器乐", + "type": "number" + }, + "yybysy": { + "description": "音乐表演声乐", + "type": "number" + }, + "yyjy": { + "description": "音乐教育", + "type": "number" + } + } + }, + "entity.YxVolunteer": { + "type": "object", + "properties": { + "createBy": { + "description": "创建人", + "type": "string" + }, + "createTime": { + "description": "创建日期", + "type": "string" + }, + "createType": { + "description": "生成类型(1.手动生成,2.智能生成)", + "type": "string" + }, + "id": { + "type": "string" + }, + "scoreId": { + "description": "使用成绩id", + "type": "string" + }, + "state": { + "description": "志愿单状态(0-否,1.正在使用,2-历史)", + "type": "string" + }, + "sysOrgCode": { + "description": "所属部门", + "type": "string" + }, + "updateBy": { + "description": "更新人", + "type": "string" + }, + "updateTime": { + "description": "更新日期", + "type": "string" + }, + "volunteerName": { + "description": "志愿单名称", + "type": "string" + } + } + }, + "entity.YxVolunteerRecord": { + "type": "object", + "properties": { + "batch": { + "description": "录取批次", + "type": "string" + }, + "calculationMajorId": { + "description": "专业折算id", + "type": "string" + }, + "createBy": { + "description": "创建人", + "type": "string" + }, + "createTime": { + "description": "创建日期", + "type": "string" + }, + "enrollProbability": { + "description": "录取概率", + "type": "number" + }, + "enrollmentCode": { + "description": "招生代码", + "type": "string" + }, + "fctj": { + "description": "服从调剂", + "type": "integer" + }, + "id": { + "type": "string" + }, + "indexs": { + "description": "志愿顺序", + "type": "integer" + }, + "majorCode": { + "description": "专业编码", + "type": "string" + }, + "schoolCode": { + "description": "学校编码", + "type": "string" + }, + "studentConvertedScore": { + "description": "折合分数", + "type": "number" + }, + "volunteerId": { + "description": "志愿单id", + "type": "string" + } + } } }, "securityDefinitions": { diff --git a/server/docs/swagger.yaml b/server/docs/swagger.yaml index 1d0469f..6a1a1a5 100644 --- a/server/docs/swagger.yaml +++ b/server/docs/swagger.yaml @@ -313,6 +313,171 @@ definitions: updateTime: type: string type: object + entity.YxUserScore: + properties: + batch: + description: 录取批次 + type: string + calculationTableName: + description: 记录结果表名 + type: string + chineseScore: + description: 语文成绩 + type: number + cognitioPolyclinic: + description: 文理分班(文科/理科) + type: string + createBy: + description: 创建人 + type: string + createTime: + description: 创建时间 + type: string + culturalScore: + description: 文化成绩分 + type: number + educationalLevel: + description: 学历层次(1-本科,2-专科) + type: string + englishScore: + description: 英语成绩 + type: number + fzby: + description: 服装表演 + type: number + id: + type: string + jwtNum: + description: 较稳妥专业数量 + type: integer + kbdNum: + description: 可保底专业数量 + type: integer + kcjNum: + description: 可冲击专业数量 + type: integer + nlqNum: + description: 难录取专业数量 + type: integer + professionalCategory: + description: 专业类别(美术类/...) + type: string + professionalCategoryChildren: + description: 子级专业类别 + type: string + professionalScore: + description: 专业成绩分 + type: number + province: + description: 高考省份 + type: string + ranking: + description: 位次 + type: integer + state: + description: 状态(0-未使用,1-使用中) + type: string + subjects: + description: 选课 + type: string + type: + description: 填报类型(1-普通类 2-艺术类) + type: string + updateBy: + description: 修改人 + type: string + updateTime: + description: 修改时间 + type: string + xjysby: + description: 戏剧影视表演 + type: number + xjysdy: + description: 戏剧影视导演 + type: number + yybyqy: + description: 音乐表演器乐 + type: number + yybysy: + description: 音乐表演声乐 + type: number + yyjy: + description: 音乐教育 + type: number + type: object + entity.YxVolunteer: + properties: + createBy: + description: 创建人 + type: string + createTime: + description: 创建日期 + type: string + createType: + description: 生成类型(1.手动生成,2.智能生成) + type: string + id: + type: string + scoreId: + description: 使用成绩id + type: string + state: + description: 志愿单状态(0-否,1.正在使用,2-历史) + type: string + sysOrgCode: + description: 所属部门 + type: string + updateBy: + description: 更新人 + type: string + updateTime: + description: 更新日期 + type: string + volunteerName: + description: 志愿单名称 + type: string + type: object + entity.YxVolunteerRecord: + properties: + batch: + description: 录取批次 + type: string + calculationMajorId: + description: 专业折算id + type: string + createBy: + description: 创建人 + type: string + createTime: + description: 创建日期 + type: string + enrollProbability: + description: 录取概率 + type: number + enrollmentCode: + description: 招生代码 + type: string + fctj: + description: 服从调剂 + type: integer + id: + type: string + indexs: + description: 志愿顺序 + type: integer + majorCode: + description: 专业编码 + type: string + schoolCode: + description: 学校编码 + type: string + studentConvertedScore: + description: 折合分数 + type: number + volunteerId: + description: 志愿单id + type: string + type: object host: localhost:8080 info: contact: {} @@ -320,6 +485,27 @@ info: title: 艺考招生管理系统 API version: "2.0" paths: + /auth/Sys/login: + post: + consumes: + - application/json + parameters: + - description: 登录信息 + in: body + name: request + required: true + schema: + $ref: '#/definitions/controller.LoginRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/common.Response' + summary: Sys用户登录 + tags: + - 认证 /auth/info: get: responses: @@ -930,6 +1116,273 @@ paths: summary: 批量创建院校专业 tags: - 院校专业 + /yx-user-scores: + get: + parameters: + - default: 1 + description: 页码 + in: query + name: page + type: integer + - default: 10 + description: 每页数量 + in: query + name: size + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/common.Response' + summary: 获取用户分数列表 + tags: + - 用户分数 + post: + parameters: + - description: 用户分数信息 + in: body + name: item + required: true + schema: + $ref: '#/definitions/entity.YxUserScore' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/common.Response' + summary: 创建用户分数 + tags: + - 用户分数 + /yx-user-scores/{id}: + delete: + parameters: + - description: ID + in: path + name: id + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/common.Response' + summary: 删除用户分数 + tags: + - 用户分数 + get: + parameters: + - description: ID + in: path + name: id + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/common.Response' + summary: 获取单个用户分数 + tags: + - 用户分数 + put: + parameters: + - description: ID + in: path + name: id + required: true + type: string + - description: 用户分数信息 + in: body + name: item + required: true + schema: + $ref: '#/definitions/entity.YxUserScore' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/common.Response' + summary: 更新用户分数 + tags: + - 用户分数 + /yx-volunteer-records: + get: + parameters: + - default: 1 + description: 页码 + in: query + name: page + type: integer + - default: 10 + description: 每页数量 + in: query + name: size + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/common.Response' + summary: 获取志愿明细列表 + tags: + - 志愿明细 + post: + parameters: + - description: 志愿明细信息 + in: body + name: item + required: true + schema: + $ref: '#/definitions/entity.YxVolunteerRecord' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/common.Response' + summary: 创建志愿明细 + tags: + - 志愿明细 + /yx-volunteer-records/{id}: + delete: + parameters: + - description: ID + in: path + name: id + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/common.Response' + summary: 删除志愿明细 + tags: + - 志愿明细 + get: + parameters: + - description: ID + in: path + name: id + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/common.Response' + summary: 获取单个志愿明细 + tags: + - 志愿明细 + put: + parameters: + - description: ID + in: path + name: id + required: true + type: string + - description: 志愿明细信息 + in: body + name: item + required: true + schema: + $ref: '#/definitions/entity.YxVolunteerRecord' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/common.Response' + summary: 更新志愿明细 + tags: + - 志愿明细 + /yx-volunteers: + get: + parameters: + - default: 1 + description: 页码 + in: query + name: page + type: integer + - default: 10 + description: 每页数量 + in: query + name: size + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/common.Response' + summary: 获取志愿列表 + tags: + - 志愿 + post: + parameters: + - description: 志愿信息 + in: body + name: item + required: true + schema: + $ref: '#/definitions/entity.YxVolunteer' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/common.Response' + summary: 创建志愿 + tags: + - 志愿 + /yx-volunteers/{id}: + delete: + parameters: + - description: ID + in: path + name: id + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/common.Response' + summary: 删除志愿 + tags: + - 志愿 + get: + parameters: + - description: ID + in: path + name: id + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/common.Response' + summary: 获取单个志愿 + tags: + - 志愿 + put: + parameters: + - description: ID + in: path + name: id + required: true + type: string + - description: 志愿信息 + in: body + name: item + required: true + schema: + $ref: '#/definitions/entity.YxVolunteer' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/common.Response' + summary: 更新志愿 + tags: + - 志愿 securityDefinitions: Bearer: in: header diff --git a/server/main.go b/server/main.go index fc3834a..71674df 100644 --- a/server/main.go +++ b/server/main.go @@ -52,8 +52,14 @@ func main() { // 请求日志中间件 r.Use(requestLogMiddleware()) - // Swagger 文档 (不需要登录) - r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) + // 跨域中间件 + r.Use(middleware.CorsMiddleware()) + + // Swagger 文档 (需要Basic Auth验证) + authorized := r.Group("/swagger", gin.BasicAuth(gin.Accounts{ + config.AppConfig.Swagger.User: config.AppConfig.Swagger.Password, + })) + authorized.GET("/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) // API 路由组 api := r.Group("/api") @@ -71,6 +77,9 @@ func main() { yxController.NewYxSchoolMajorController().RegisterRoutes(api) yxController.NewYxHistoryMajorEnrollController().RegisterRoutes(api) yxController.NewYxCalculationMajorController().RegisterRoutes(api) + yxController.NewYxUserScoreController().RegisterRoutes(api) + yxController.NewYxVolunteerController().RegisterRoutes(api) + yxController.NewYxVolunteerRecordController().RegisterRoutes(api) // 创建 HTTP 服务器 srv := &http.Server{ diff --git a/server/middleware/cors.go b/server/middleware/cors.go new file mode 100644 index 0000000..bc6d174 --- /dev/null +++ b/server/middleware/cors.go @@ -0,0 +1,31 @@ +package middleware + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// CorsMiddleware 跨域中间件 +func CorsMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + method := c.Request.Method + origin := c.Request.Header.Get("Origin") + + if origin != "" { + // 允许所有来源,生产环境请修改为特定域名 + c.Header("Access-Control-Allow-Origin", origin) + c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE") + c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, X-App-Sign") + c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type") + c.Header("Access-Control-Allow-Credentials", "true") + } + + // 放行 OPTIONS 请求 + if method == "OPTIONS" { + c.AbortWithStatus(http.StatusNoContent) + } + + c.Next() + } +} diff --git a/server/modules/system/controller/auth_controller.go b/server/modules/system/controller/auth_controller.go index aa3b911..112b658 100644 --- a/server/modules/system/controller/auth_controller.go +++ b/server/modules/system/controller/auth_controller.go @@ -25,6 +25,7 @@ func NewAuthController() *AuthController { func (ctrl *AuthController) RegisterRoutes(r *gin.RouterGroup) { r.POST("/auth/login", ctrl.Login) + r.POST("/auth/sys/login", ctrl.SysLogin) r.POST("/auth/logout", ctrl.Logout) r.GET("/auth/info", ctrl.GetUserInfo) } @@ -56,6 +57,33 @@ func (ctrl *AuthController) Login(c *gin.Context) { }) } +// SysLogin 用户登录 +// @Summary Sys用户登录 +// @Tags 认证 +// @Accept json +// @Produce json +// @Param request body LoginRequest true "登录信息" +// @Success 200 {object} common.Response +// @Router /auth/Sys/login [post] +func (ctrl *AuthController) SysLogin(c *gin.Context) { + var req LoginRequest + if err := c.ShouldBindJSON(&req); err != nil { + common.Error(c, 400, "用户名和密码不能为空") + return + } + + loginUser, token, err := ctrl.userService.SysLogin(req.Username, req.Password) + if err != nil { + common.Error(c, 401, err.Error()) + return + } + + common.Success(c, gin.H{ + "token": token, + "user": loginUser, + }) +} + // Logout 用户登出 // @Summary 用户登出 // @Tags 认证 diff --git a/server/modules/system/service/sys_user_service.go b/server/modules/system/service/sys_user_service.go index b1a369f..f0de896 100644 --- a/server/modules/system/service/sys_user_service.go +++ b/server/modules/system/service/sys_user_service.go @@ -33,6 +33,48 @@ func NewSysUserService() *SysUserService { // Login 用户登录 // 密码验证方式与 Java JeecgBoot 兼容: PBEWithMD5AndDES(username, password, salt) func (s *SysUserService) Login(username, password string) (*entity.LoginUser, string, error) { + // 查询用户 + user, err := s.mapper.FindByPhone(username) + if err != nil { + return nil, "", errors.New("用户不存在") + } + + // 验证状态 + if user.Status == 2 { + return nil, "", errors.New("账号已被冻结") + } + + // 验证密码 (与Java兼容: encrypt(username, password, salt)) + encrypted, err := common.Encrypt(user.Username, password, user.Salt) + if (user.Password != encrypted) || (err != nil) { + return nil, "", errors.New("用户名或密码错误") + } + + // 生成Token + token := s.generateToken() + + // 构建登录用户信息 + loginUser := &entity.LoginUser{ + ID: user.ID, + Username: user.Username, + Realname: user.Realname, + Avatar: user.Avatar, + Phone: user.Phone, + Email: user.Email, + Token: token, + } + + // 存储到Redis + if err := s.saveLoginUser(token, loginUser); err != nil { + return nil, "", errors.New("登录失败,请重试") + } + + return loginUser, token, nil +} + +// SysLogin 用户登录 +// 密码验证方式与 Java JeecgBoot 兼容: PBEWithMD5AndDES(username, password, salt) +func (s *SysUserService) SysLogin(username, password string) (*entity.LoginUser, string, error) { // 查询用户 user, err := s.mapper.FindByUsername(username) if err != nil { diff --git a/server/modules/yx/controller/yx_user_score_controller.go b/server/modules/yx/controller/yx_user_score_controller.go new file mode 100644 index 0000000..abd4aa0 --- /dev/null +++ b/server/modules/yx/controller/yx_user_score_controller.go @@ -0,0 +1,123 @@ +// Package controller 控制层 +package controller + +import ( + "server/common" + "server/modules/yx/entity" + "server/modules/yx/service" + "strconv" + + "github.com/gin-gonic/gin" +) + +type YxUserScoreController struct { + service *service.YxUserScoreService +} + +func NewYxUserScoreController() *YxUserScoreController { + return &YxUserScoreController{service: service.NewYxUserScoreService()} +} + +// RegisterRoutes 注册路由 +func (ctrl *YxUserScoreController) RegisterRoutes(rg *gin.RouterGroup) { + group := rg.Group("/yx-user-scores") + { + group.GET("", ctrl.List) + group.GET("/:id", ctrl.Get) + group.POST("", ctrl.Create) + group.PUT("/:id", ctrl.Update) + group.DELETE("/:id", ctrl.Delete) + } +} + +// List 获取用户分数列表 +// @Summary 获取用户分数列表 +// @Tags 用户分数 +// @Param page query int false "页码" default(1) +// @Param size query int false "每页数量" default(10) +// @Success 200 {object} common.Response +// @Router /yx-user-scores [get] +func (ctrl *YxUserScoreController) List(c *gin.Context) { + page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) + size, _ := strconv.Atoi(c.DefaultQuery("size", "10")) + items, total, err := ctrl.service.List(page, size) + if err != nil { + common.Error(c, 500, err.Error()) + return + } + common.Success(c, gin.H{ + "items": items, + "total": total, + }) +} + +// Get 获取单个用户分数 +// @Summary 获取单个用户分数 +// @Tags 用户分数 +// @Param id path string true "ID" +// @Success 200 {object} common.Response +// @Router /yx-user-scores/{id} [get] +func (ctrl *YxUserScoreController) Get(c *gin.Context) { + id := c.Param("id") + item, err := ctrl.service.GetByID(id) + if err != nil { + common.Error(c, 404, "未找到记录") + return + } + common.Success(c, item) +} + +// Create 创建用户分数 +// @Summary 创建用户分数 +// @Tags 用户分数 +// @Param item body entity.YxUserScore true "用户分数信息" +// @Success 200 {object} common.Response +// @Router /yx-user-scores [post] +func (ctrl *YxUserScoreController) Create(c *gin.Context) { + var item entity.YxUserScore + if err := c.ShouldBindJSON(&item); err != nil { + common.Error(c, 400, "参数错误") + return + } + if err := ctrl.service.Create(&item); err != nil { + common.Error(c, 500, err.Error()) + return + } + common.Success(c, item) +} + +// Update 更新用户分数 +// @Summary 更新用户分数 +// @Tags 用户分数 +// @Param id path string true "ID" +// @Param item body entity.YxUserScore true "用户分数信息" +// @Success 200 {object} common.Response +// @Router /yx-user-scores/{id} [put] +func (ctrl *YxUserScoreController) Update(c *gin.Context) { + var item entity.YxUserScore + if err := c.ShouldBindJSON(&item); err != nil { + common.Error(c, 400, "参数错误") + return + } + item.ID = c.Param("id") + if err := ctrl.service.Update(&item); err != nil { + common.Error(c, 500, err.Error()) + return + } + common.Success(c, item) +} + +// Delete 删除用户分数 +// @Summary 删除用户分数 +// @Tags 用户分数 +// @Param id path string true "ID" +// @Success 200 {object} common.Response +// @Router /yx-user-scores/{id} [delete] +func (ctrl *YxUserScoreController) Delete(c *gin.Context) { + id := c.Param("id") + if err := ctrl.service.Delete(id); err != nil { + common.Error(c, 500, err.Error()) + return + } + common.Success(c, nil) +} diff --git a/server/modules/yx/controller/yx_volunteer_controller.go b/server/modules/yx/controller/yx_volunteer_controller.go new file mode 100644 index 0000000..25cdb5f --- /dev/null +++ b/server/modules/yx/controller/yx_volunteer_controller.go @@ -0,0 +1,123 @@ +// Package controller 控制层 +package controller + +import ( + "server/common" + "server/modules/yx/entity" + "server/modules/yx/service" + "strconv" + + "github.com/gin-gonic/gin" +) + +type YxVolunteerController struct { + service *service.YxVolunteerService +} + +func NewYxVolunteerController() *YxVolunteerController { + return &YxVolunteerController{service: service.NewYxVolunteerService()} +} + +// RegisterRoutes 注册路由 +func (ctrl *YxVolunteerController) RegisterRoutes(rg *gin.RouterGroup) { + group := rg.Group("/yx-volunteers") + { + group.GET("", ctrl.List) + group.GET("/:id", ctrl.Get) + group.POST("", ctrl.Create) + group.PUT("/:id", ctrl.Update) + group.DELETE("/:id", ctrl.Delete) + } +} + +// List 获取志愿列表 +// @Summary 获取志愿列表 +// @Tags 志愿 +// @Param page query int false "页码" default(1) +// @Param size query int false "每页数量" default(10) +// @Success 200 {object} common.Response +// @Router /yx-volunteers [get] +func (ctrl *YxVolunteerController) List(c *gin.Context) { + page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) + size, _ := strconv.Atoi(c.DefaultQuery("size", "10")) + items, total, err := ctrl.service.List(page, size) + if err != nil { + common.Error(c, 500, err.Error()) + return + } + common.Success(c, gin.H{ + "items": items, + "total": total, + }) +} + +// Get 获取单个志愿 +// @Summary 获取单个志愿 +// @Tags 志愿 +// @Param id path string true "ID" +// @Success 200 {object} common.Response +// @Router /yx-volunteers/{id} [get] +func (ctrl *YxVolunteerController) Get(c *gin.Context) { + id := c.Param("id") + item, err := ctrl.service.GetByID(id) + if err != nil { + common.Error(c, 404, "未找到记录") + return + } + common.Success(c, item) +} + +// Create 创建志愿 +// @Summary 创建志愿 +// @Tags 志愿 +// @Param item body entity.YxVolunteer true "志愿信息" +// @Success 200 {object} common.Response +// @Router /yx-volunteers [post] +func (ctrl *YxVolunteerController) Create(c *gin.Context) { + var item entity.YxVolunteer + if err := c.ShouldBindJSON(&item); err != nil { + common.Error(c, 400, "参数错误") + return + } + if err := ctrl.service.Create(&item); err != nil { + common.Error(c, 500, err.Error()) + return + } + common.Success(c, item) +} + +// Update 更新志愿 +// @Summary 更新志愿 +// @Tags 志愿 +// @Param id path string true "ID" +// @Param item body entity.YxVolunteer true "志愿信息" +// @Success 200 {object} common.Response +// @Router /yx-volunteers/{id} [put] +func (ctrl *YxVolunteerController) Update(c *gin.Context) { + var item entity.YxVolunteer + if err := c.ShouldBindJSON(&item); err != nil { + common.Error(c, 400, "参数错误") + return + } + item.ID = c.Param("id") + if err := ctrl.service.Update(&item); err != nil { + common.Error(c, 500, err.Error()) + return + } + common.Success(c, item) +} + +// Delete 删除志愿 +// @Summary 删除志愿 +// @Tags 志愿 +// @Param id path string true "ID" +// @Success 200 {object} common.Response +// @Router /yx-volunteers/{id} [delete] +func (ctrl *YxVolunteerController) Delete(c *gin.Context) { + id := c.Param("id") + if err := ctrl.service.Delete(id); err != nil { + common.Error(c, 500, err.Error()) + return + } + common.Success(c, nil) +} diff --git a/server/modules/yx/controller/yx_volunteer_record_controller.go b/server/modules/yx/controller/yx_volunteer_record_controller.go new file mode 100644 index 0000000..bd1e773 --- /dev/null +++ b/server/modules/yx/controller/yx_volunteer_record_controller.go @@ -0,0 +1,123 @@ +// Package controller 控制层 +package controller + +import ( + "server/common" + "server/modules/yx/entity" + "server/modules/yx/service" + "strconv" + + "github.com/gin-gonic/gin" +) + +type YxVolunteerRecordController struct { + service *service.YxVolunteerRecordService +} + +func NewYxVolunteerRecordController() *YxVolunteerRecordController { + return &YxVolunteerRecordController{service: service.NewYxVolunteerRecordService()} +} + +// RegisterRoutes 注册路由 +func (ctrl *YxVolunteerRecordController) RegisterRoutes(rg *gin.RouterGroup) { + group := rg.Group("/yx-volunteer-records") + { + group.GET("", ctrl.List) + group.GET("/:id", ctrl.Get) + group.POST("", ctrl.Create) + group.PUT("/:id", ctrl.Update) + group.DELETE("/:id", ctrl.Delete) + } +} + +// List 获取志愿明细列表 +// @Summary 获取志愿明细列表 +// @Tags 志愿明细 +// @Param page query int false "页码" default(1) +// @Param size query int false "每页数量" default(10) +// @Success 200 {object} common.Response +// @Router /yx-volunteer-records [get] +func (ctrl *YxVolunteerRecordController) List(c *gin.Context) { + page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) + size, _ := strconv.Atoi(c.DefaultQuery("size", "10")) + items, total, err := ctrl.service.List(page, size) + if err != nil { + common.Error(c, 500, err.Error()) + return + } + common.Success(c, gin.H{ + "items": items, + "total": total, + }) +} + +// Get 获取单个志愿明细 +// @Summary 获取单个志愿明细 +// @Tags 志愿明细 +// @Param id path string true "ID" +// @Success 200 {object} common.Response +// @Router /yx-volunteer-records/{id} [get] +func (ctrl *YxVolunteerRecordController) Get(c *gin.Context) { + id := c.Param("id") + item, err := ctrl.service.GetByID(id) + if err != nil { + common.Error(c, 404, "未找到记录") + return + } + common.Success(c, item) +} + +// Create 创建志愿明细 +// @Summary 创建志愿明细 +// @Tags 志愿明细 +// @Param item body entity.YxVolunteerRecord true "志愿明细信息" +// @Success 200 {object} common.Response +// @Router /yx-volunteer-records [post] +func (ctrl *YxVolunteerRecordController) Create(c *gin.Context) { + var item entity.YxVolunteerRecord + if err := c.ShouldBindJSON(&item); err != nil { + common.Error(c, 400, "参数错误") + return + } + if err := ctrl.service.Create(&item); err != nil { + common.Error(c, 500, err.Error()) + return + } + common.Success(c, item) +} + +// Update 更新志愿明细 +// @Summary 更新志愿明细 +// @Tags 志愿明细 +// @Param id path string true "ID" +// @Param item body entity.YxVolunteerRecord true "志愿明细信息" +// @Success 200 {object} common.Response +// @Router /yx-volunteer-records/{id} [put] +func (ctrl *YxVolunteerRecordController) Update(c *gin.Context) { + var item entity.YxVolunteerRecord + if err := c.ShouldBindJSON(&item); err != nil { + common.Error(c, 400, "参数错误") + return + } + item.ID = c.Param("id") + if err := ctrl.service.Update(&item); err != nil { + common.Error(c, 500, err.Error()) + return + } + common.Success(c, item) +} + +// Delete 删除志愿明细 +// @Summary 删除志愿明细 +// @Tags 志愿明细 +// @Param id path string true "ID" +// @Success 200 {object} common.Response +// @Router /yx-volunteer-records/{id} [delete] +func (ctrl *YxVolunteerRecordController) Delete(c *gin.Context) { + id := c.Param("id") + if err := ctrl.service.Delete(id); err != nil { + common.Error(c, 500, err.Error()) + return + } + common.Success(c, nil) +} diff --git a/server/modules/yx/entity/yx_user_score.go b/server/modules/yx/entity/yx_user_score.go new file mode 100644 index 0000000..47272e2 --- /dev/null +++ b/server/modules/yx/entity/yx_user_score.go @@ -0,0 +1,42 @@ +package entity + +import "time" + +// YxUserScore 用户分数信息表实体 +type YxUserScore struct { + ID string `gorm:"column:id;primaryKey" json:"id"` + Type string `gorm:"column:type;default:1" json:"type"` // 填报类型(1-普通类 2-艺术类) + EducationalLevel string `gorm:"column:educational_level;default:1" json:"educationalLevel"` // 学历层次(1-本科,2-专科) + ProfessionalCategory string `gorm:"column:professional_category;default:美术类" json:"professionalCategory"` // 专业类别(美术类/...) + Subjects string `gorm:"column:subjects" json:"subjects"` // 选课 + ProfessionalScore float64 `gorm:"column:professional_score;default:0" json:"professionalScore"` // 专业成绩分 + CulturalScore float64 `gorm:"column:cultural_score;default:0" json:"culturalScore"` // 文化成绩分 + Ranking int `gorm:"column:ranking;default:0" json:"ranking"` // 位次 + CreateBy string `gorm:"column:create_by" json:"createBy"` // 创建人 + CreateTime time.Time `gorm:"column:create_time" json:"createTime"` // 创建时间 + UpdateBy string `gorm:"column:update_by" json:"updateBy"` // 修改人 + UpdateTime time.Time `gorm:"column:update_time" json:"updateTime"` // 修改时间 + State string `gorm:"column:state;default:1" json:"state"` // 状态(0-未使用,1-使用中) + Province string `gorm:"column:province;default:北京" json:"province"` // 高考省份 + CognitioPolyclinic string `gorm:"column:cognitio_polyclinic" json:"cognitioPolyclinic"` // 文理分班(文科/理科) + Batch string `gorm:"column:batch" json:"batch"` // 录取批次 + EnglishScore float64 `gorm:"column:english_score;default:0.00" json:"englishScore"` // 英语成绩 + ChineseScore float64 `gorm:"column:chinese_score;default:0.00" json:"chineseScore"` // 语文成绩 + Yybysy float64 `gorm:"column:yybysy;default:0.00" json:"yybysy"` // 音乐表演声乐 + Yybyqy float64 `gorm:"column:yybyqy;default:0.00" json:"yybyqy"` // 音乐表演器乐 + Yyjy float64 `gorm:"column:yyjy;default:0.00" json:"yyjy"` // 音乐教育 + Xjysdy float64 `gorm:"column:xjysdy;default:0.00" json:"xjysdy"` // 戏剧影视导演 + Xjysby float64 `gorm:"column:xjysby;default:0.00" json:"xjysby"` // 戏剧影视表演 + Fzby float64 `gorm:"column:fzby;default:0.00" json:"fzby"` // 服装表演 + ProfessionalCategoryChildren string `gorm:"column:professional_category_children" json:"professionalCategoryChildren"` // 子级专业类别 + KbdNum int `gorm:"column:kbd_num;default:0" json:"kbdNum"` // 可保底专业数量 + NlqNum int `gorm:"column:nlq_num;default:0" json:"nlqNum"` // 难录取专业数量 + KcjNum int `gorm:"column:kcj_num;default:0" json:"kcjNum"` // 可冲击专业数量 + JwtNum int `gorm:"column:jwt_num;default:0" json:"jwtNum"` // 较稳妥专业数量 + CalculationTableName string `gorm:"column:calculation_table_name" json:"calculationTableName"` // 记录结果表名 +} + +// TableName 指定表名 +func (YxUserScore) TableName() string { + return "yx_user_score" +} diff --git a/server/modules/yx/entity/yx_volunteer.go b/server/modules/yx/entity/yx_volunteer.go new file mode 100644 index 0000000..950b93d --- /dev/null +++ b/server/modules/yx/entity/yx_volunteer.go @@ -0,0 +1,22 @@ +package entity + +import "time" + +// YxVolunteer 志愿表实体 +type YxVolunteer struct { + ID string `gorm:"column:id;primaryKey" json:"id"` + VolunteerName string `gorm:"column:volunteer_name" json:"volunteerName"` // 志愿单名称 + ScoreID string `gorm:"column:score_id" json:"scoreId"` // 使用成绩id + CreateType string `gorm:"column:create_type;default:1" json:"createType"` // 生成类型(1.手动生成,2.智能生成) + State string `gorm:"column:state;default:0" json:"state"` // 志愿单状态(0-否,1.正在使用,2-历史) + CreateBy string `gorm:"column:create_by" json:"createBy"` // 创建人 + CreateTime time.Time `gorm:"column:create_time" json:"createTime"` // 创建日期 + UpdateBy string `gorm:"column:update_by" json:"updateBy"` // 更新人 + UpdateTime time.Time `gorm:"column:update_time" json:"updateTime"` // 更新日期 + SysOrgCode string `gorm:"column:sys_org_code" json:"sysOrgCode"` // 所属部门 +} + +// TableName 指定表名 +func (YxVolunteer) TableName() string { + return "yx_volunteer" +} diff --git a/server/modules/yx/entity/yx_volunteer_record.go b/server/modules/yx/entity/yx_volunteer_record.go new file mode 100644 index 0000000..948cc62 --- /dev/null +++ b/server/modules/yx/entity/yx_volunteer_record.go @@ -0,0 +1,25 @@ +package entity + +import "time" + +// YxVolunteerRecord 志愿明细表实体 +type YxVolunteerRecord struct { + ID string `gorm:"column:id;primaryKey" json:"id"` + VolunteerID string `gorm:"column:volunteer_id" json:"volunteerId"` // 志愿单id + SchoolCode string `gorm:"column:school_code" json:"schoolCode"` // 学校编码 + MajorCode string `gorm:"column:major_code" json:"majorCode"` // 专业编码 + EnrollmentCode string `gorm:"column:enrollment_code" json:"enrollmentCode"` // 招生代码 + Indexs int `gorm:"column:indexs;default:1" json:"indexs"` // 志愿顺序 + CreateBy string `gorm:"column:create_by" json:"createBy"` // 创建人 + CreateTime time.Time `gorm:"column:create_time" json:"createTime"` // 创建日期 + Batch string `gorm:"column:batch" json:"batch"` // 录取批次 + EnrollProbability float64 `gorm:"column:enroll_probability;default:0.0000" json:"enrollProbability"` // 录取概率 + StudentConvertedScore float64 `gorm:"column:student_converted_score;default:0.0000" json:"studentConvertedScore"` // 折合分数 + Fctj int `gorm:"column:fctj;default:0" json:"fctj"` // 服从调剂 + CalculationMajorID string `gorm:"column:calculation_major_id" json:"calculationMajorId"` // 专业折算id +} + +// TableName 指定表名 +func (YxVolunteerRecord) TableName() string { + return "yx_volunteer_record" +} diff --git a/server/modules/yx/mapper/yx_user_score_mapper.go b/server/modules/yx/mapper/yx_user_score_mapper.go new file mode 100644 index 0000000..e38bf86 --- /dev/null +++ b/server/modules/yx/mapper/yx_user_score_mapper.go @@ -0,0 +1,64 @@ +// Package mapper 数据访问层 +package mapper + +import ( + "server/config" + "server/modules/yx/entity" + + "gorm.io/gorm/clause" +) + +type YxUserScoreMapper struct{} + +func NewYxUserScoreMapper() *YxUserScoreMapper { + return &YxUserScoreMapper{} +} + +func (m *YxUserScoreMapper) FindAll(page, size int) ([]entity.YxUserScore, int64, error) { + var items []entity.YxUserScore + var total int64 + config.DB.Model(&entity.YxUserScore{}).Count(&total) + err := config.DB.Offset((page - 1) * size).Limit(size).Find(&items).Error + return items, total, err +} + +func (m *YxUserScoreMapper) FindByID(id string) (*entity.YxUserScore, error) { + var item entity.YxUserScore + err := config.DB.First(&item, "id = ?", id).Error + return &item, err +} + +func (m *YxUserScoreMapper) Create(item *entity.YxUserScore) error { + return config.DB.Create(item).Error +} + +func (m *YxUserScoreMapper) Update(item *entity.YxUserScore) error { + return config.DB.Save(item).Error +} + +func (m *YxUserScoreMapper) UpdateFields(id string, fields map[string]interface{}) error { + return config.DB.Model(&entity.YxUserScore{}).Where("id = ?", id).Updates(fields).Error +} + +func (m *YxUserScoreMapper) Delete(id string) error { + return config.DB.Delete(&entity.YxUserScore{}, "id = ?", id).Error +} + +func (m *YxUserScoreMapper) BatchCreate(items []entity.YxUserScore, batchSize int) error { + return config.DB.CreateInBatches(items, batchSize).Error +} + +func (m *YxUserScoreMapper) BatchUpdate(items []entity.YxUserScore) error { + return config.DB.Save(items).Error +} + +func (m *YxUserScoreMapper) BatchUpsert(items []entity.YxUserScore, updateColumns []string) error { + return config.DB.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "id"}}, + DoUpdates: clause.AssignmentColumns(updateColumns), + }).CreateInBatches(items, 100).Error +} + +func (m *YxUserScoreMapper) BatchDelete(ids []string) error { + return config.DB.Delete(&entity.YxUserScore{}, "id IN ?", ids).Error +} diff --git a/server/modules/yx/mapper/yx_volunteer_mapper.go b/server/modules/yx/mapper/yx_volunteer_mapper.go new file mode 100644 index 0000000..6297836 --- /dev/null +++ b/server/modules/yx/mapper/yx_volunteer_mapper.go @@ -0,0 +1,64 @@ +// Package mapper 数据访问层 +package mapper + +import ( + "server/config" + "server/modules/yx/entity" + + "gorm.io/gorm/clause" +) + +type YxVolunteerMapper struct{} + +func NewYxVolunteerMapper() *YxVolunteerMapper { + return &YxVolunteerMapper{} +} + +func (m *YxVolunteerMapper) FindAll(page, size int) ([]entity.YxVolunteer, int64, error) { + var items []entity.YxVolunteer + var total int64 + config.DB.Model(&entity.YxVolunteer{}).Count(&total) + err := config.DB.Offset((page - 1) * size).Limit(size).Find(&items).Error + return items, total, err +} + +func (m *YxVolunteerMapper) FindByID(id string) (*entity.YxVolunteer, error) { + var item entity.YxVolunteer + err := config.DB.First(&item, "id = ?", id).Error + return &item, err +} + +func (m *YxVolunteerMapper) Create(item *entity.YxVolunteer) error { + return config.DB.Create(item).Error +} + +func (m *YxVolunteerMapper) Update(item *entity.YxVolunteer) error { + return config.DB.Save(item).Error +} + +func (m *YxVolunteerMapper) UpdateFields(id string, fields map[string]interface{}) error { + return config.DB.Model(&entity.YxVolunteer{}).Where("id = ?", id).Updates(fields).Error +} + +func (m *YxVolunteerMapper) Delete(id string) error { + return config.DB.Delete(&entity.YxVolunteer{}, "id = ?", id).Error +} + +func (m *YxVolunteerMapper) BatchCreate(items []entity.YxVolunteer, batchSize int) error { + return config.DB.CreateInBatches(items, batchSize).Error +} + +func (m *YxVolunteerMapper) BatchUpdate(items []entity.YxVolunteer) error { + return config.DB.Save(items).Error +} + +func (m *YxVolunteerMapper) BatchUpsert(items []entity.YxVolunteer, updateColumns []string) error { + return config.DB.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "id"}}, + DoUpdates: clause.AssignmentColumns(updateColumns), + }).CreateInBatches(items, 100).Error +} + +func (m *YxVolunteerMapper) BatchDelete(ids []string) error { + return config.DB.Delete(&entity.YxVolunteer{}, "id IN ?", ids).Error +} diff --git a/server/modules/yx/mapper/yx_volunteer_record_mapper.go b/server/modules/yx/mapper/yx_volunteer_record_mapper.go new file mode 100644 index 0000000..8ba8c32 --- /dev/null +++ b/server/modules/yx/mapper/yx_volunteer_record_mapper.go @@ -0,0 +1,64 @@ +// Package mapper 数据访问层 +package mapper + +import ( + "server/config" + "server/modules/yx/entity" + + "gorm.io/gorm/clause" +) + +type YxVolunteerRecordMapper struct{} + +func NewYxVolunteerRecordMapper() *YxVolunteerRecordMapper { + return &YxVolunteerRecordMapper{} +} + +func (m *YxVolunteerRecordMapper) FindAll(page, size int) ([]entity.YxVolunteerRecord, int64, error) { + var items []entity.YxVolunteerRecord + var total int64 + config.DB.Model(&entity.YxVolunteerRecord{}).Count(&total) + err := config.DB.Offset((page - 1) * size).Limit(size).Find(&items).Error + return items, total, err +} + +func (m *YxVolunteerRecordMapper) FindByID(id string) (*entity.YxVolunteerRecord, error) { + var item entity.YxVolunteerRecord + err := config.DB.First(&item, "id = ?", id).Error + return &item, err +} + +func (m *YxVolunteerRecordMapper) Create(item *entity.YxVolunteerRecord) error { + return config.DB.Create(item).Error +} + +func (m *YxVolunteerRecordMapper) Update(item *entity.YxVolunteerRecord) error { + return config.DB.Save(item).Error +} + +func (m *YxVolunteerRecordMapper) UpdateFields(id string, fields map[string]interface{}) error { + return config.DB.Model(&entity.YxVolunteerRecord{}).Where("id = ?", id).Updates(fields).Error +} + +func (m *YxVolunteerRecordMapper) Delete(id string) error { + return config.DB.Delete(&entity.YxVolunteerRecord{}, "id = ?", id).Error +} + +func (m *YxVolunteerRecordMapper) BatchCreate(items []entity.YxVolunteerRecord, batchSize int) error { + return config.DB.CreateInBatches(items, batchSize).Error +} + +func (m *YxVolunteerRecordMapper) BatchUpdate(items []entity.YxVolunteerRecord) error { + return config.DB.Save(items).Error +} + +func (m *YxVolunteerRecordMapper) BatchUpsert(items []entity.YxVolunteerRecord, updateColumns []string) error { + return config.DB.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "id"}}, + DoUpdates: clause.AssignmentColumns(updateColumns), + }).CreateInBatches(items, 100).Error +} + +func (m *YxVolunteerRecordMapper) BatchDelete(ids []string) error { + return config.DB.Delete(&entity.YxVolunteerRecord{}, "id IN ?", ids).Error +} diff --git a/server/modules/yx/service/yx_user_score_service.go b/server/modules/yx/service/yx_user_score_service.go new file mode 100644 index 0000000..c0f093f --- /dev/null +++ b/server/modules/yx/service/yx_user_score_service.go @@ -0,0 +1,66 @@ +// Package service 业务逻辑层 +package service + +import ( + "server/modules/yx/entity" + "server/modules/yx/mapper" + + "github.com/google/uuid" +) + +type YxUserScoreService struct { + mapper *mapper.YxUserScoreMapper +} + +func NewYxUserScoreService() *YxUserScoreService { + return &YxUserScoreService{mapper: mapper.NewYxUserScoreMapper()} +} + +func (s *YxUserScoreService) List(page, size int) ([]entity.YxUserScore, int64, error) { + return s.mapper.FindAll(page, size) +} + +func (s *YxUserScoreService) GetByID(id string) (*entity.YxUserScore, error) { + return s.mapper.FindByID(id) +} + +func (s *YxUserScoreService) Create(item *entity.YxUserScore) error { + item.ID = uuid.New().String() + return s.mapper.Create(item) +} + +func (s *YxUserScoreService) Update(item *entity.YxUserScore) error { + return s.mapper.Update(item) +} + +func (s *YxUserScoreService) UpdateFields(id string, fields map[string]interface{}) error { + return s.mapper.UpdateFields(id, fields) +} + +func (s *YxUserScoreService) Delete(id string) error { + return s.mapper.Delete(id) +} + +func (s *YxUserScoreService) BatchCreate(items []entity.YxUserScore) error { + for i := range items { + items[i].ID = uuid.New().String() + } + return s.mapper.BatchCreate(items, 100) +} + +func (s *YxUserScoreService) BatchUpdate(items []entity.YxUserScore) error { + return s.mapper.BatchUpdate(items) +} + +func (s *YxUserScoreService) BatchUpsert(items []entity.YxUserScore, updateColumns []string) error { + for i := range items { + if items[i].ID == "" { + items[i].ID = uuid.New().String() + } + } + return s.mapper.BatchUpsert(items, updateColumns) +} + +func (s *YxUserScoreService) BatchDelete(ids []string) error { + return s.mapper.BatchDelete(ids) +} diff --git a/server/modules/yx/service/yx_volunteer_record_service.go b/server/modules/yx/service/yx_volunteer_record_service.go new file mode 100644 index 0000000..b95c358 --- /dev/null +++ b/server/modules/yx/service/yx_volunteer_record_service.go @@ -0,0 +1,66 @@ +// Package service 业务逻辑层 +package service + +import ( + "server/modules/yx/entity" + "server/modules/yx/mapper" + + "github.com/google/uuid" +) + +type YxVolunteerRecordService struct { + mapper *mapper.YxVolunteerRecordMapper +} + +func NewYxVolunteerRecordService() *YxVolunteerRecordService { + return &YxVolunteerRecordService{mapper: mapper.NewYxVolunteerRecordMapper()} +} + +func (s *YxVolunteerRecordService) List(page, size int) ([]entity.YxVolunteerRecord, int64, error) { + return s.mapper.FindAll(page, size) +} + +func (s *YxVolunteerRecordService) GetByID(id string) (*entity.YxVolunteerRecord, error) { + return s.mapper.FindByID(id) +} + +func (s *YxVolunteerRecordService) Create(item *entity.YxVolunteerRecord) error { + item.ID = uuid.New().String() + return s.mapper.Create(item) +} + +func (s *YxVolunteerRecordService) Update(item *entity.YxVolunteerRecord) error { + return s.mapper.Update(item) +} + +func (s *YxVolunteerRecordService) UpdateFields(id string, fields map[string]interface{}) error { + return s.mapper.UpdateFields(id, fields) +} + +func (s *YxVolunteerRecordService) Delete(id string) error { + return s.mapper.Delete(id) +} + +func (s *YxVolunteerRecordService) BatchCreate(items []entity.YxVolunteerRecord) error { + for i := range items { + items[i].ID = uuid.New().String() + } + return s.mapper.BatchCreate(items, 100) +} + +func (s *YxVolunteerRecordService) BatchUpdate(items []entity.YxVolunteerRecord) error { + return s.mapper.BatchUpdate(items) +} + +func (s *YxVolunteerRecordService) BatchUpsert(items []entity.YxVolunteerRecord, updateColumns []string) error { + for i := range items { + if items[i].ID == "" { + items[i].ID = uuid.New().String() + } + } + return s.mapper.BatchUpsert(items, updateColumns) +} + +func (s *YxVolunteerRecordService) BatchDelete(ids []string) error { + return s.mapper.BatchDelete(ids) +} diff --git a/server/modules/yx/service/yx_volunteer_service.go b/server/modules/yx/service/yx_volunteer_service.go new file mode 100644 index 0000000..0fad5bc --- /dev/null +++ b/server/modules/yx/service/yx_volunteer_service.go @@ -0,0 +1,66 @@ +// Package service 业务逻辑层 +package service + +import ( + "server/modules/yx/entity" + "server/modules/yx/mapper" + + "github.com/google/uuid" +) + +type YxVolunteerService struct { + mapper *mapper.YxVolunteerMapper +} + +func NewYxVolunteerService() *YxVolunteerService { + return &YxVolunteerService{mapper: mapper.NewYxVolunteerMapper()} +} + +func (s *YxVolunteerService) List(page, size int) ([]entity.YxVolunteer, int64, error) { + return s.mapper.FindAll(page, size) +} + +func (s *YxVolunteerService) GetByID(id string) (*entity.YxVolunteer, error) { + return s.mapper.FindByID(id) +} + +func (s *YxVolunteerService) Create(item *entity.YxVolunteer) error { + item.ID = uuid.New().String() + return s.mapper.Create(item) +} + +func (s *YxVolunteerService) Update(item *entity.YxVolunteer) error { + return s.mapper.Update(item) +} + +func (s *YxVolunteerService) UpdateFields(id string, fields map[string]interface{}) error { + return s.mapper.UpdateFields(id, fields) +} + +func (s *YxVolunteerService) Delete(id string) error { + return s.mapper.Delete(id) +} + +func (s *YxVolunteerService) BatchCreate(items []entity.YxVolunteer) error { + for i := range items { + items[i].ID = uuid.New().String() + } + return s.mapper.BatchCreate(items, 100) +} + +func (s *YxVolunteerService) BatchUpdate(items []entity.YxVolunteer) error { + return s.mapper.BatchUpdate(items) +} + +func (s *YxVolunteerService) BatchUpsert(items []entity.YxVolunteer, updateColumns []string) error { + for i := range items { + if items[i].ID == "" { + items[i].ID = uuid.New().String() + } + } + return s.mapper.BatchUpsert(items, updateColumns) +} + +func (s *YxVolunteerService) BatchDelete(ids []string) error { + return s.mapper.BatchDelete(ids) +} diff --git a/task_detail.md b/task_detail.md new file mode 100644 index 0000000..90f6988 --- /dev/null +++ b/task_detail.md @@ -0,0 +1,8 @@ +# 任务执行摘要 + +## 会话 ID: 20251217-03 +- **执行原因**: 用户在本地调试 Vue3 项目时遇到 CORS 跨域问题,请求无法成功。 +- **执行过程**: + 1. 创建 `server/middleware/cors.go`,实现了一个通用的 CORS 中间件,允许请求携带 Origin 头,支持常用 HTTP 方法,并自动处理 OPTIONS 预检请求。 + 2. 修改 `server/main.go`,在全局中间件链中注册了 `CorsMiddleware`。 +- **执行结果**: 后端服务现在支持跨域请求,Vue3 前端可以正常调用接口。