diff --git a/backend/my_work/main.go b/backend/my_work/main.go index 77a70bf..042e1fb 100644 --- a/backend/my_work/main.go +++ b/backend/my_work/main.go @@ -66,7 +66,8 @@ func main() { //统一初始化 models.ConfigAllInit() - routers.ApiInit() + routers.ApiUserInit() //用户表先初始化这是必须的因为后面需要用到用户组 + routers.ApiScheduleInit() //创建必要目录 for _, path := range models.ConfigsFile.Pahts { diff --git a/backend/my_work/routers/api.go b/backend/my_work/routers/api.go index 186c24b..cf83551 100644 --- a/backend/my_work/routers/api.go +++ b/backend/my_work/routers/api.go @@ -54,7 +54,7 @@ func ApiRoot(r *gin.RouterGroup) { ApiUser(r.Group("/users")) ApiFiles(r.Group("/files")) ApiPurchase(r.Group("/purchase")) - + ApiSchedule(r.Group("/schedule")) r.GET("/", func(ctx *gin.Context) { ReturnJson(ctx, "apiOK", nil) }) diff --git a/backend/my_work/routers/apiSchedule.go b/backend/my_work/routers/apiSchedule.go new file mode 100644 index 0000000..f79fb0c --- /dev/null +++ b/backend/my_work/routers/apiSchedule.go @@ -0,0 +1,134 @@ +package routers + +//2026-4-2开始每个功能的数据表在各自的api路由下初始化 + +import ( + "encoding/json" + "fmt" + "ops/models" + "time" + + "github.com/gin-gonic/gin" + "github.com/mitchellh/mapstructure" + "gorm.io/gorm" +) + +type TabSchedule struct { + ID uint `gorm:"primarykey"` + UserID uint `gorm:"not null;comment:创建人ID"` + Title string `gorm:"size:200;not null;comment:日程标题"` + StartDate string `gorm:"size:10;not null;index;comment:开始日期 YYYY-MM-DD"` + EndDate string `gorm:"size:10;not null;index;comment:结束日期 YYYY-MM-DD"` + BgColor string `gorm:"size:50;default:#3788d9;comment:背景颜色"` + Remark string `gorm:"type:text;comment:备注"` + + CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime;comment:创建时间"` + UpdatedAt *time.Time `gorm:"type:datetime;autoUpdateTime;comment:最后修改时间"` + DeletedAt gorm.DeletedAt `gorm:"index"` +} + +type TabScheduleLog struct { + ID uint `gorm:"primarykey"` + ScheduleID uint `gorm:"not null;index;comment:关联日程ID"` + UserID uint `gorm:"not null;comment:操作人ID"` + ActionType string `gorm:"size:50;not null;comment:操作类型: create-创建 update-修改 delete-删除 query-查询"` + OldContent string `gorm:"type:text;comment:修改前内容(JSON)"` + NewContent string `gorm:"type:text;comment:修改后内容(JSON)"` + IP string `gorm:"size:50;comment:操作IP"` + Remark string `gorm:"size:500;comment:备注/操作描述"` + + CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime;comment:操作时间"` +} +type fromAddEvent struct { + Title string `json:"title" binding:"required"` // 日程标题 + Start string `json:"start" binding:"required"` // 开始日期 + End string `json:"end" binding:"required"` // 结束日期 + Color string `json:"color" binding:"required"` // 背景颜色 +} + +type fromGetEvents struct { + Start string `json:"start" binding:"required"` // 开始日期 + End string `json:"end" binding:"required"` // 结束日期 +} + +var ( + userGroup models.TabUserGroups_ +) + +func ApiScheduleInit() { + //先初始化数据表 + models.DB.AutoMigrate(&TabSchedule{}) + models.DB.AutoMigrate(&TabScheduleLog{}) + //获取管理员用户组id + //先检查用户组有没有这个key + userGroup.Name = "schedule_admin" + + if models.DB.Where(&userGroup).First(&userGroup).Error == nil { + + } else { + userGroup.Type = "usergroup" + models.DB.Create(&userGroup) + } +} + +func ApiSchedule(r *gin.RouterGroup) { + r.POST("/getevents", func(ctx *gin.Context) { + data, _ := SeparateData(ctx) + //fmt.Println(cookieval, data) + var from fromGetEvents + if err := mapstructure.Decode(data, &from); err == nil { + //fmt.Println(from) + //从数据库获取相关数据 + var list []TabSchedule + models.DB.Where("start_date <= ? AND end_date >= ?", from.End, from.Start).Where("deleted_at IS NULL").Find(&list) + fmt.Println(list) + //ReturnJson(ctx, "ApiOK", list) + ReturnJson(ctx, "apiOK", gin.H{"list": list}) + + } else { + ReturnJson(ctx, "jsonErr", nil) + } + + }) + + r.POST("/addevent", func(ctx *gin.Context) { + isAuth, user, data := AuthenticationAuthority(ctx) + if isAuth { + + var from fromAddEvent + if err := mapstructure.Decode(data, &from); err == nil { + + tosql := TabSchedule{ + UserID: user.ID, + Title: from.Title, + StartDate: from.Start, + EndDate: from.End, + BgColor: from.Color, + } + if models.DB.Create(&tosql).Error == nil { + //记录日志 + newContent, _ := json.Marshal(tosql) // 👈 转 JSON + tosqllog := TabScheduleLog{ + UserID: user.ID, + ScheduleID: tosql.ID, + ActionType: "create", + NewContent: string(newContent), // 👈 直接赋值 + OldContent: "", + IP: ctx.ClientIP(), + } + models.DB.Create(&tosqllog) + ReturnJson(ctx, "apiOK", nil) + } else { + ReturnJson(ctx, "apiErr", nil) + } + + } else { + ReturnJson(ctx, "jsonErr", nil) + } + } else { + ReturnJson(ctx, "userCookieError", nil) + } + + }) + +} diff --git a/backend/my_work/routers/apiUsers.go b/backend/my_work/routers/apiUsers.go index e576ad4..5e4562e 100644 --- a/backend/my_work/routers/apiUsers.go +++ b/backend/my_work/routers/apiUsers.go @@ -12,7 +12,7 @@ import ( "github.com/mitchellh/mapstructure" ) -func ApiInit() { +func ApiUserInit() { //用户模块初始化init fmt.Println("users init") @@ -110,33 +110,16 @@ func AuthenticationAuthorityFromCookie(c string) (*models.TabUser_, error) { } func AuthenticationAuthority(ctx *gin.Context) (bool, models.TabUser_, map[string]interface{}) { - var user models.TabUser_ data, cookieval := SeparateData(ctx) //fmt.Println("cookieis" + cookieval) + var user models.TabUser_ if cookieval != "" { - cookie := models.TabCookie_{ - Value: cookieval, - } - if models.DB.Where(&cookie).First(&cookie).Error == nil { - //找到cookie,验证cookie有效性,以及更新cookie - if models.CheckCookiesAndUpdate(&cookie) { - //cookie有效 - //载入user - user := models.TabUser_{ - ID: cookie.UserID, - } - models.DB.Where(&user).First(&user) - - return true, user, data - - } else { - ReturnJson(ctx, "userCookieExpired", nil) - return false, user, nil - } - + user_, error := AuthenticationAuthorityFromCookie(cookieval) + if error == nil { + user = *user_ + return true, user, data } else { - ReturnJson(ctx, "userCookieNotFund", nil) return false, user, nil } @@ -145,7 +128,6 @@ func AuthenticationAuthority(ctx *gin.Context) (bool, models.TabUser_, map[strin return false, user, nil } - //return false, user } func ApiUser(r *gin.RouterGroup) { @@ -261,26 +243,26 @@ func ApiUser(r *gin.RouterGroup) { } } - if is_save_ok { - //修改数据库内容 - var user_info_fund models.TabUserInfo_ - user_info_fund.UserID = user.ID + if is_save_ok { + //修改数据库内容 + var user_info_fund models.TabUserInfo_ + user_info_fund.UserID = user.ID - var user_update_avatar models.TabUserInfo_ - user_update_avatar.AvatarPath = file_hashi_name + file_extname + var user_update_avatar models.TabUserInfo_ + user_update_avatar.AvatarPath = file_hashi_name + file_extname + + //先查找是否有记录 + if models.DB.Where(&user_info_fund).First(&user_info_fund).Error == nil { + //有记录,更新 + models.DB.Model(&user_info_fund).Updates(&user_update_avatar) + } else { + //无记录,创建 + user_update_avatar.UserID = user.ID + models.DB.Create(&user_update_avatar) + } - //先查找是否有记录 - if models.DB.Where(&user_info_fund).First(&user_info_fund).Error == nil { - //有记录,更新 - models.DB.Model(&user_info_fund).Updates(&user_update_avatar) - } else { - //无记录,创建 - user_update_avatar.UserID = user.ID - models.DB.Create(&user_update_avatar) } - } - } else { ReturnJson(ctx, "postErr", nil) } diff --git a/frontend/ops_vue_js/src/api/schedule.js b/frontend/ops_vue_js/src/api/schedule.js new file mode 100644 index 0000000..bea41c2 --- /dev/null +++ b/frontend/ops_vue_js/src/api/schedule.js @@ -0,0 +1,13 @@ +import { api } from './index' + +export const scheduleApi = { + + getEvents(params = {}) { + return api.post('/schedule/getevents', params) + }, + + + addEvent(data) { + return api.post('/schedule/addevent', data) + }, +} \ No newline at end of file diff --git a/frontend/ops_vue_js/src/i18n/en.json b/frontend/ops_vue_js/src/i18n/en.json index 460dc62..b9d54e8 100644 --- a/frontend/ops_vue_js/src/i18n/en.json +++ b/frontend/ops_vue_js/src/i18n/en.json @@ -247,7 +247,7 @@ "source_code": "Source Code", "github": "GitHub", "author_home": "Author", - "copy": "Copyright © 2025 Operations. All rights reserved." + "copy": "Copyright © 2025 Operations. MIT Open Source License." }, "cost_type": { "unit_price": "Unit Price", diff --git a/frontend/ops_vue_js/src/i18n/zh-CN.json b/frontend/ops_vue_js/src/i18n/zh-CN.json index a6de0b1..4cac096 100644 --- a/frontend/ops_vue_js/src/i18n/zh-CN.json +++ b/frontend/ops_vue_js/src/i18n/zh-CN.json @@ -247,7 +247,7 @@ "source_code": "源码", "github": "GitHub", "author_home": "作者主页", - "copy": "版权 © 2025 Operations. 保留所有权利。" + "copy": "版权 © 2025 Operations. MIT开源协议。" }, "cost_type": { "unit_price": "单价", diff --git a/frontend/ops_vue_js/src/views/loginView.vue b/frontend/ops_vue_js/src/views/loginView.vue index 7883e33..42ac285 100644 --- a/frontend/ops_vue_js/src/views/loginView.vue +++ b/frontend/ops_vue_js/src/views/loginView.vue @@ -1,64 +1,79 @@ @@ -68,55 +83,94 @@ async function handleLogin() {
- {{ t('message.dont_have_account_yet') }}
-