updates
This commit is contained in:
parent
44ddefd4c6
commit
9167b6a661
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"mcpServers": {
|
||||
"'codebase-mcp'": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@iflow-mcp/codebase-mcp",
|
||||
"start"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -55,7 +55,16 @@
|
|||
|
||||
如果是从0到1开发新的项目,尽可能使用下方给出的技术栈:
|
||||
|
||||
### 后端 - Java(主力)
|
||||
### 后端 - Go(主力)
|
||||
|
||||
| 配置项 | 要求 |
|
||||
| -------- | -------------------------------------- |
|
||||
| 语言版本 | Go 1.21+ |
|
||||
| 开发框架 | Gin |
|
||||
| ORM框架 | GORM |
|
||||
| 代码规范 | Google Go 编程规范 |
|
||||
|
||||
### 后端 - Java
|
||||
|
||||
| 配置项 | 要求 |
|
||||
| -------- | -------------------------------------- |
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
# 代码库函数概览
|
||||
|
||||
## server/common
|
||||
- `constants`: 存放全局常量,如 `RedisTokenPrefix`, `TokenHeader`, `StateActive` 等。
|
||||
- `id_utils`: ID 生成工具,提供 `GenerateLongID()` 和 `GenerateStringID()`。
|
||||
- `Response`: 统一的HTTP响应结构体 `{Code, Message, Data}`。
|
||||
- `Success(c *gin.Context, data interface{})`: 发送成功响应。
|
||||
- `Error(c *gin.Context, code int, msg string)`: 发送错误响应。
|
||||
|
||||
## server/config
|
||||
- `LoadConfig()`: 加载配置。
|
||||
- 优先级1:命令行参数 `-c` 或 `-config` 指定的文件。
|
||||
- 优先级2:环境变量 `GO_ENV` 决定的文件(查找顺序:`./config.{env}.yaml` -> `config/config.{env}.yaml` -> `../config/config.{env}.yaml`)。
|
||||
- `AppConfig`: 全局配置对象,包含 Log, Server, Database 等配置。
|
||||
- `InitDB()`: 初始化GORM数据库连接,支持 SQL 日志配置(自动写入 `logs/sql-YYYY-MM-DD.log`)。
|
||||
- `InitRedis()`: 初始化Redis客户端。
|
||||
- `AppConfig`: 全局配置变量,包含 `Log`, `Security`, `RateLimit`, `Swagger`, `Database`, `Redis` 配置。
|
||||
|
||||
## server/middleware
|
||||
- `AuthMiddleware`: JWT认证中间件。
|
||||
- `SecurityMiddleware`: 安全校验中间件(请求头签名)。
|
||||
- `RateLimitMiddleware`: 接口限流中间件。
|
||||
- `CorsMiddleware`: 跨域资源共享中间件。
|
||||
|
||||
## server/modules/yx
|
||||
- `YxSchoolMajorController`: 院校专业控制器。
|
||||
- `YxHistoryMajorEnrollController`: 历年招生记录控制器。
|
||||
- `YxCalculationMajorController`: 计算专业控制器。
|
||||
- `YxUserScoreController`: 用户分数控制器。
|
||||
- `YxVolunteerController`: 志愿控制器。
|
||||
- `YxVolunteerRecordController`: 志愿明细控制器。
|
||||
|
||||
## server/modules/yx/service
|
||||
- `YxCalculationMajorService`:
|
||||
- `BatchCreateBySchoolMajorDTO(tableName string, items []dto.SchoolMajorDTO, scoreID string)`: 根据 SchoolMajorDTO 列表批量创建计算专业数据,支持动态表名。
|
||||
- `BatchCreate(tableName string, items []entity.YxCalculationMajor)`: 批量创建计算专业数据,支持动态表名。
|
||||
|
||||
## server/modules/user/service
|
||||
- `UserScoreService`:
|
||||
- `GetActiveByID(userID string)`: 获取用户当前激活状态的成绩 VO。
|
||||
- `GetByID(id string)`: 根据 ID 获取特定成绩 VO。
|
||||
- `GetActiveScoreID(userID string)`: 获取用户当前激活的成绩ID。
|
||||
- `UpdateFields(id string, fields map[string]interface{})`: 更新成绩字段。
|
||||
- `Delete(id string)`: 删除成绩记录。
|
||||
- `SaveUserScore(req *dto.SaveScoreRequest)`: 保存用户成绩,返回保存后的 VO。
|
||||
- `ListByUser(userID string, page, size int)`: 分页获取用户的成绩列表。
|
||||
- `UserScoreVO`: 用户成绩视图对象,包含基础信息、选课列表及子专业成绩映射。
|
||||
|
||||
## server/modules/yx/service
|
||||
- `YxVolunteerService`:
|
||||
- `UpdateName(id, name, userID string)`: 编辑志愿单名称(权属校验)。
|
||||
- `ListByUser(userID string, page, size int)`: 获取当前用户志愿单列表(关联成绩数据)。
|
||||
- `DeleteVolunteer(...)`: 删除志愿单(级联删除计算表、成绩、明细)。
|
||||
- `SwitchVolunteer(id, userID string, scoreService IScoreService)`: 切换当前志愿单(同步同步成绩状态)。
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
### [任务执行] 服务端口配置化
|
||||
- **时间戳**: 2026-01-02
|
||||
- **关联任务**: 端口配置化
|
||||
- **操作目标**: 将服务启动端口从硬编码改为从配置文件读取。
|
||||
- **影响范围**:
|
||||
- `server/config/config.go`
|
||||
- `server/config/config.*.yaml`
|
||||
- `server/main.go`
|
||||
- **修改前记录**: `main.go` 中硬编码使用 `:8080`。
|
||||
- **修改结果**:
|
||||
- `AppConfig` 增加 `Server.Port` 字段。
|
||||
- 所有环境配置文件增加 `server.port: 8080` 配置。
|
||||
- `main.go` 读取配置端口启动,若未配置则默认为 8080。
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
# 项目文件索引
|
||||
|
||||
## server/
|
||||
- `main.go`: 应用程序入口,负责路由注册和服务器启动。
|
||||
- `config/`: 配置文件目录。
|
||||
- `config.go`: 应用配置结构定义与加载逻辑。
|
||||
- `config.dev.yaml`: 开发环境配置(开启 SQL 日志)。
|
||||
- `config.test.yaml`: 测试环境配置。
|
||||
- `config.prod.yaml`: 生产环境配置。
|
||||
- `database.go`: 数据库连接配置。
|
||||
- `redis.go`: Redis连接配置。
|
||||
- `tests/`: 单元测试与集成测试目录。
|
||||
- `init_test.go`: 测试环境初始化(自动连接 DB 和 Redis)。
|
||||
- `service_test.go`: 业务逻辑与数据访问测试用例。
|
||||
- `common/`: 通用工具包。
|
||||
- `constants.go`: 全局常量定义(Redis Key、业务状态等)。
|
||||
- `id_utils.go`: ID 生成工具(基于时间戳)。
|
||||
- `response.go`: 统一HTTP响应结构。
|
||||
- `context.go`: 上下文辅助函数。
|
||||
- `logger.go`: 日志工具。
|
||||
- `password.go`: 密码加密工具。
|
||||
- `middleware/`: HTTP中间件。
|
||||
- `auth.go`: JWT认证中间件。
|
||||
- `security.go`: 安全相关的中间件。
|
||||
- `ratelimit.go`: 限流中间件。
|
||||
- `cors.go`: CORS跨域中间件。
|
||||
- `modules/`: 业务模块目录。
|
||||
- `system/`: 系统管理模块(用户、权限等)。
|
||||
- `yx/`: 艺考相关业务模块。
|
||||
- `dto/`: 数据传输对象,用于接口请求/响应定义。
|
||||
- `entity/`: 实体定义。
|
||||
- `mapper/`: 数据访问层实现。
|
||||
- `service/`: 业务逻辑层实现。
|
||||
- `controller/`: 控制层实现。
|
||||
- `user/`: 用户相关业务扩展。
|
||||
- `vo/`: 视图对象,用于数据展示。
|
||||
- `service/`: 业务逻辑层。
|
||||
- `docs/`: Swagger API文档。
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# 项目任务规划
|
||||
|
||||
## [进行中] 模块开发: 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)
|
||||
- [已完成] 注册新路由
|
||||
- [进行中] 环境配置与部署准备
|
||||
- [已完成] 搭建开发、测试、生产环境配置体系
|
||||
- [已完成] 配置 SQL 日志打印
|
||||
- [进行中] 编写环境配置文档
|
||||
- [已完成] 完善用户志愿管理接口
|
||||
- [已完成] 编辑志愿单名称 (权属校验)
|
||||
- [已完成] 获取用户志愿单列表 (分页, 降序, 关联成绩)
|
||||
- [已完成] 删除志愿单 (级联删除, 状态校验)
|
||||
- [已完成] 切换当前志愿单 (状态切换, Redis 同步)
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ func (ctrl *UserMajorController) ListBySchool(c *gin.Context) {
|
|||
Probability: c.DefaultQuery("probability", ""),
|
||||
LoginUserId: common.GetLoginUser(c).ID,
|
||||
}
|
||||
userScoreVO, err := ctrl.userScoreService.GetActiveByID(schoolMajorQuery.LoginUserId)
|
||||
userScoreVO, err := ctrl.userScoreService.GetActiveScoreByUserID(schoolMajorQuery.LoginUserId)
|
||||
if err != nil {
|
||||
common.Error(c, 500, err.Error())
|
||||
return
|
||||
|
|
@ -99,11 +99,12 @@ func (ctrl *UserMajorController) List(c *gin.Context) {
|
|||
Probability: c.DefaultQuery("probability", ""),
|
||||
LoginUserId: common.GetLoginUser(c).ID,
|
||||
}
|
||||
userScoreVO, err := ctrl.userScoreService.GetActiveByID(schoolMajorQuery.LoginUserId)
|
||||
userScoreVO, err := ctrl.userScoreService.GetActiveScoreByUserID(schoolMajorQuery.LoginUserId)
|
||||
if err != nil {
|
||||
common.Error(c, 500, err.Error())
|
||||
common.Error(c, 500, err.Error()) // 获取用户成绩信息失败
|
||||
return
|
||||
}
|
||||
|
||||
schoolMajorQuery.UserScoreVO = userScoreVO
|
||||
items, total, probCount, err := ctrl.yxCalculationMajorService.RecommendMajorList(schoolMajorQuery)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ func (ctrl *UserScoreController) SaveUserScore(c *gin.Context) {
|
|||
// @Router /user/score [get]
|
||||
func (ctrl *UserScoreController) GetActive(c *gin.Context) {
|
||||
loginUserId := common.GetLoginUser(c).ID
|
||||
item, err := ctrl.userScoreService.GetActiveByID(loginUserId)
|
||||
item, err := ctrl.userScoreService.GetActiveScoreByUserID(loginUserId)
|
||||
if err != nil {
|
||||
common.Error(c, 404, "未找到激活成绩")
|
||||
return
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package controller
|
|||
import (
|
||||
"server/common"
|
||||
"server/modules/user/service"
|
||||
"server/modules/user/vo"
|
||||
yxDto "server/modules/yx/dto"
|
||||
"server/modules/yx/entity"
|
||||
yx_service "server/modules/yx/service"
|
||||
|
|
@ -64,9 +65,14 @@ func (ctrl *UserVolunteerController) SaveVolunteer(c *gin.Context) {
|
|||
keys = uniqueKeys
|
||||
|
||||
loginUserId := common.GetLoginUser(c).ID
|
||||
userScoreVO, err := ctrl.userScoreService.GetActiveByID(loginUserId)
|
||||
scoreObj, err := ctrl.userScoreService.GetActiveScoreID(loginUserId)
|
||||
if err != nil {
|
||||
common.Error(c, 500, err.Error())
|
||||
common.Error(c, 500, err.Error()) // 获取用户成绩信息失败
|
||||
return
|
||||
}
|
||||
userScoreVO, ok := scoreObj.(vo.UserScoreVO)
|
||||
if !ok {
|
||||
common.Error(c, 500, "成绩信息格式错误")
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -144,11 +150,16 @@ func (ctrl *UserVolunteerController) SaveVolunteer(c *gin.Context) {
|
|||
// @Router /user/volunteer/detail [get]
|
||||
func (ctrl *UserVolunteerController) GetVolunteerDetail(c *gin.Context) {
|
||||
loginUserId := common.GetLoginUser(c).ID
|
||||
userScoreVO, err := ctrl.userScoreService.GetActiveByID(loginUserId)
|
||||
scoreObj, err := ctrl.userScoreService.GetActiveScoreID(loginUserId)
|
||||
if err != nil {
|
||||
common.Error(c, 500, err.Error())
|
||||
return
|
||||
}
|
||||
userScoreVO, ok := scoreObj.(vo.UserScoreVO)
|
||||
if !ok {
|
||||
common.Error(c, 500, "成绩信息格式错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 查找当前激活的志愿表
|
||||
volunteer, err := ctrl.yxVolunteerService.FindActiveByScoreId(userScoreVO.ID)
|
||||
|
|
@ -250,9 +261,6 @@ func (ctrl *UserVolunteerController) GetVolunteerDetail(c *gin.Context) {
|
|||
groupedItems[groupKey] = append(groupedItems[groupKey], item)
|
||||
}
|
||||
|
||||
// Sort items by Indexs in each group? Records are already ordered by Indexs globally.
|
||||
// Within group, they should follow Indexs order naturally if iterated in order.
|
||||
|
||||
common.Success(c, map[string]interface{}{
|
||||
"volunteer": volunteer,
|
||||
"items": groupedItems,
|
||||
|
|
@ -321,7 +329,7 @@ func (ctrl *UserVolunteerController) DeleteVolunteer(c *gin.Context) {
|
|||
}
|
||||
|
||||
loginUserID := common.GetLoginUser(c).ID
|
||||
err := ctrl.yxVolunteerService.DeleteVolunteer(id, loginUserID, ctrl.userScoreService, ctrl.yxCalculationMajorService, ctrl.yxVolunteerRecordService)
|
||||
err := ctrl.yxVolunteerService.DeleteVolunteer(id, loginUserID)
|
||||
if err != nil {
|
||||
common.Error(c, 500, err.Error())
|
||||
return
|
||||
|
|
@ -345,7 +353,17 @@ func (ctrl *UserVolunteerController) SwitchVolunteer(c *gin.Context) {
|
|||
|
||||
loginUserID := common.GetLoginUser(c).ID
|
||||
// 1. 先判断是否已是该志愿单 (从 cache 或 db 中查找激活的)
|
||||
userScoreVO, _ := ctrl.userScoreService.GetActiveByID(loginUserID)
|
||||
scoreObj, err := ctrl.userScoreService.GetActiveScoreID(loginUserID)
|
||||
if err != nil {
|
||||
common.Error(c, 500, "获取用户成绩信息失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
userScoreVO, ok := scoreObj.(vo.UserScoreVO)
|
||||
if !ok {
|
||||
common.Error(c, 500, "成绩信息格式错误")
|
||||
return
|
||||
}
|
||||
|
||||
if userScoreVO.ID != "" {
|
||||
activeVolunteer, _ := ctrl.yxVolunteerService.FindActiveByScoreId(userScoreVO.ID)
|
||||
if activeVolunteer != nil && activeVolunteer.ID == id {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package service
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"server/common"
|
||||
"server/config"
|
||||
|
|
@ -14,6 +15,8 @@ import (
|
|||
"server/modules/yx/service"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type UserScoreService struct {
|
||||
|
|
@ -23,24 +26,63 @@ type UserScoreService struct {
|
|||
mapper *mapper.YxUserScoreMapper
|
||||
}
|
||||
|
||||
func (s *UserScoreService) GetUserScoreByUserId(id string) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (s *UserScoreService) GetActiveScoreID(userID string) string {
|
||||
obj, err := s.GetActiveByID(userID)
|
||||
// GetActiveScoreID 获取用户的激活成绩信息
|
||||
func (s *UserScoreService) GetActiveScoreID(userID string) (interface{}, error) {
|
||||
vo, err := s.GetActiveScoreByUserID(userID)
|
||||
if err != nil {
|
||||
return ""
|
||||
return nil, err
|
||||
}
|
||||
if voItem, ok := obj.(vo.UserScoreVO); ok {
|
||||
return voItem.ID
|
||||
}
|
||||
return ""
|
||||
return vo, nil
|
||||
}
|
||||
|
||||
func (s *UserScoreService) GetActiveByID(userID string) (interface{}, error) {
|
||||
// GetActiveScoreByID 获取用户的激活成绩实体(实现 IScoreService 接口)
|
||||
func (s *UserScoreService) GetActiveScoreByID(userID string) (entity.YxUserScore, error) {
|
||||
var score entity.YxUserScore
|
||||
// ... (logic remains same)
|
||||
// 明确指定字段,提高可读性
|
||||
err := config.DB.Model(&entity.YxUserScore{}).
|
||||
Where("create_by = ? AND state = ?", userID, "1").
|
||||
First(&score).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return entity.YxUserScore{}, fmt.Errorf("未找到激活的成绩记录")
|
||||
}
|
||||
return entity.YxUserScore{}, fmt.Errorf("查询成绩记录失败: %w", err)
|
||||
}
|
||||
return score, nil
|
||||
}
|
||||
|
||||
func (s *UserScoreService) GetActiveScoreByUserID(userID string) (vo.UserScoreVO, error) {
|
||||
var score entity.YxUserScore
|
||||
// 先从Redis获取是否存在
|
||||
scoreRedisData, err := config.RDB.Get(context.Background(), common.RedisUserScorePrefix+userID).Result()
|
||||
if err != nil {
|
||||
// 明确指定字段,提高可读性
|
||||
err := config.DB.Model(&entity.YxUserScore{}).
|
||||
Where("create_by = ? AND state = ?", userID, "1").
|
||||
First(&score).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return vo.UserScoreVO{}, fmt.Errorf("未找到激活的成绩记录")
|
||||
}
|
||||
return vo.UserScoreVO{}, fmt.Errorf("查询成绩记录失败: %w", err)
|
||||
}
|
||||
// 缓存到 Redis
|
||||
scoreRedisSetData, err := json.Marshal(score)
|
||||
if err != nil {
|
||||
return vo.UserScoreVO{}, fmt.Errorf("序列化成绩记录失败: %w", err)
|
||||
}
|
||||
err = config.RDB.Set(context.Background(), common.RedisUserScorePrefix+userID, scoreRedisSetData, common.RedisUserScoreExpire).Err()
|
||||
if err != nil {
|
||||
return vo.UserScoreVO{}, fmt.Errorf("缓存成绩记录失败: %w", err)
|
||||
}
|
||||
} else {
|
||||
if err := json.Unmarshal([]byte(scoreRedisData), &score); err != nil {
|
||||
return vo.UserScoreVO{}, fmt.Errorf("解析 Redis 数据失败: %w", err)
|
||||
}
|
||||
// 刷新过期时间
|
||||
config.RDB.Expire(context.Background(), common.RedisUserScorePrefix+userID, common.RedisUserScoreExpire)
|
||||
}
|
||||
|
||||
return s.convertEntityToVo(score), nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@ import (
|
|||
|
||||
type YxVolunteerRecordMapper struct{}
|
||||
|
||||
func (m *YxVolunteerRecordMapper) BatchDeleteByVolunteerId(id string) {
|
||||
config.DB.Delete(&entity.YxVolunteerRecord{}, "volunteer_id = ?", id)
|
||||
}
|
||||
|
||||
func NewYxVolunteerRecordMapper() *YxVolunteerRecordMapper {
|
||||
return &YxVolunteerRecordMapper{}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,18 +13,19 @@ import (
|
|||
// IScoreService 定义成绩服务的接口,用于解耦
|
||||
type IScoreService interface {
|
||||
GetByID(id string) (interface{}, error)
|
||||
GetActiveByID(userID string) (interface{}, error)
|
||||
GetActiveScoreID(userID string) string
|
||||
GetActiveScoreByID(userID string) (entity.YxUserScore, error)
|
||||
GetActiveScoreID(userID string) (interface{}, error)
|
||||
UpdateFields(id string, fields map[string]interface{}) error
|
||||
Delete(id string) error
|
||||
}
|
||||
|
||||
type YxVolunteerService struct {
|
||||
mapper *mapper.YxVolunteerMapper
|
||||
mapper *mapper.YxVolunteerMapper
|
||||
volunteerRecordMapper *mapper.YxVolunteerRecordMapper
|
||||
}
|
||||
|
||||
func NewYxVolunteerService() *YxVolunteerService {
|
||||
return &YxVolunteerService{mapper: mapper.NewYxVolunteerMapper()}
|
||||
return &YxVolunteerService{mapper: mapper.NewYxVolunteerMapper(), volunteerRecordMapper: mapper.NewYxVolunteerRecordMapper()}
|
||||
}
|
||||
|
||||
func (s *YxVolunteerService) List(page, size int) ([]entity.YxVolunteer, int64, error) {
|
||||
|
|
@ -116,7 +117,7 @@ func (s *YxVolunteerService) ListByUser(userID string, page, size int) ([]dto.Us
|
|||
return s.mapper.ListByUser(userID, page, size)
|
||||
}
|
||||
|
||||
func (s *YxVolunteerService) DeleteVolunteer(id, userID string, scoreService IScoreService, calculationService *YxCalculationMajorService, recordService *YxVolunteerRecordService) error {
|
||||
func (s *YxVolunteerService) DeleteVolunteer(id, userID string) error {
|
||||
volunteer, err := s.mapper.FindByID(id)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -127,13 +128,14 @@ func (s *YxVolunteerService) DeleteVolunteer(id, userID string, scoreService ISc
|
|||
if volunteer.State == "1" {
|
||||
return fmt.Errorf("激活状态的志愿单不可删除")
|
||||
}
|
||||
|
||||
s.volunteerRecordMapper.BatchDeleteByVolunteerId(id)
|
||||
s.mapper.Delete(id)
|
||||
// 1. 获取成绩单信息
|
||||
scoreObj, err := scoreService.GetByID(volunteer.ScoreId)
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取成绩单失败: %w", err)
|
||||
}
|
||||
_ = scoreObj // temporarily ignore until cascade logic is refined
|
||||
//scoreObj, err := scoreService.GetByID(volunteer.ScoreId)
|
||||
// if err != nil {
|
||||
// return fmt.Errorf("获取成绩单失败: %w", err)
|
||||
// }
|
||||
// _ = scoreObj // temporarily ignore until cascade logic is refined
|
||||
|
||||
// 这里需要从 scoreObj 中获取 CalculationTableName 和 ID
|
||||
// 由于是 interface{},可以通过反射或简单断言(如果能在 yx 定义共用结构最好)
|
||||
|
|
@ -141,7 +143,7 @@ func (s *YxVolunteerService) DeleteVolunteer(id, userID string, scoreService ISc
|
|||
|
||||
// 简化:这里我们假设 scoreObj 其实包含了这些信息。
|
||||
// 为了真正的解耦,我们可以在 scoreService 中增加专门的方法。
|
||||
return fmt.Errorf("暂不支持级联删除,请先手动处理关联数据") // 暂时回退复杂逻辑
|
||||
return nil // 暂时回退复杂逻辑
|
||||
}
|
||||
|
||||
func (s *YxVolunteerService) SwitchVolunteer(id, userID string, scoreService IScoreService) error {
|
||||
|
|
@ -158,7 +160,21 @@ func (s *YxVolunteerService) SwitchVolunteer(id, userID string, scoreService ISc
|
|||
}
|
||||
|
||||
// 获取之前的激活成绩并关闭
|
||||
activeScoreID := scoreService.GetActiveScoreID(userID)
|
||||
scoreObj, err := scoreService.GetActiveScoreID(userID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取激活成绩失败: %w", err)
|
||||
}
|
||||
var activeScoreID string
|
||||
if scoreObj != nil {
|
||||
// 尝试从 VO 对象中提取 ID
|
||||
if vo, ok := scoreObj.(map[string]interface{}); ok {
|
||||
if id, ok := vo["id"].(string); ok {
|
||||
activeScoreID = id
|
||||
}
|
||||
} else if vo, ok := scoreObj.(struct{ ID string }); ok {
|
||||
activeScoreID = vo.ID
|
||||
}
|
||||
}
|
||||
if activeScoreID != "" && activeScoreID != volunteer.ScoreId {
|
||||
scoreService.UpdateFields(activeScoreID, map[string]interface{}{"state": "0"})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
|
||||
## 会话 ID: 20260102-03
|
||||
- **执行原因**: 用户希望将服务端口号配置到配置文件中,避免硬编码。
|
||||
- **执行过程**:
|
||||
1. 修改 `server/config/config.go`,在 `AppConfig` 中添加 `ServerConfig` 结构体。
|
||||
2. 更新 `config.dev.yaml`、`config.prod.yaml` 和 `config.test.yaml`,添加 `server: port: 8080` 配置。
|
||||
3. 修改 `server/main.go`,使其从 `config.AppConfig.Server.Port` 读取端口号,并保留默认值 8080。
|
||||
- **执行结果**: 服务现在会使用配置文件中指定的端口启动。
|
||||
Loading…
Reference in New Issue