优化日程增加文件上传功能

This commit is contained in:
2026-09-09 09:55:05 +08:00
parent 04fc84dde6
commit d2643a3697
7 changed files with 513 additions and 15 deletions
+99
View File
@@ -299,6 +299,51 @@ type oaSchedulePayload struct {
Priority int8 `json:"priority"`
}
// oaScheduleImage 日程相关图片(截图/照片),只存文件引用,不存二进制。
type oaScheduleImage struct {
ID uint64 `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
}
const (
oaScheduleMaxImages = 20
oaScheduleMaxImageURL = 500
oaScheduleMaxImageName = 120
)
// normalizeOaScheduleImages 校验并序列化日程图片列表:
// 丢弃无 url 或超长的条目,条目数超限时返回 false。
func normalizeOaScheduleImages(list []oaScheduleImage) (string, bool) {
if len(list) > oaScheduleMaxImages {
return "", false
}
out := make([]oaScheduleImage, 0, len(list))
for _, img := range list {
img.URL = strings.TrimSpace(img.URL)
if img.URL == "" || len(img.URL) > oaScheduleMaxImageURL {
continue
}
img.Name = strings.TrimSpace(img.Name)
if utf8.RuneCountInString(img.Name) > oaScheduleMaxImageName {
img.Name = string([]rune(img.Name)[:oaScheduleMaxImageName])
}
out = append(out, img)
}
raw, err := json.Marshal(out)
if err != nil {
return "", false
}
return string(raw), true
}
// parseOaScheduleImages 解析 images 列;脏数据返回空数组,不阻断详情展示。
func parseOaScheduleImages(raw string) []oaScheduleImage {
list := make([]oaScheduleImage, 0)
_ = json.Unmarshal([]byte(raw), &list)
return list
}
// parseOaSchedulePayload 读取并校验新建/编辑日程的请求体;校验失败时直接输出错误响应。
func (c *BackendOaScheduleController) parseOaSchedulePayload() (oaSchedulePayload, bool) {
var payload oaSchedulePayload
@@ -442,6 +487,59 @@ func (c *BackendOaScheduleController) Update() {
c.oasOk(item)
}
// SetImages POST /backend/oa/schedule/images/:id
// 单独维护日程的相关图片(文件已先上传到文件管理,这里只存引用)。
// 与 Update 分开,避免编辑标题/时间等基础信息时把图片清空。
func (c *BackendOaScheduleController) SetImages() {
claims, err := c.oaScheduleClaims()
if err != nil {
c.oasJsonErr(401, 401, "未登录或无权限")
return
}
id, err := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
if err != nil || id == 0 {
c.oasJsonErr(400, 400, "无效ID")
return
}
var payload struct {
Images []oaScheduleImage `json:"images"`
}
raw, _ := io.ReadAll(c.Ctx.Request.Body)
if len(raw) > 0 && json.Unmarshal(raw, &payload) != nil {
c.oasJsonErr(400, 400, "参数错误")
return
}
imagesJSON, ok := normalizeOaScheduleImages(payload.Images)
if !ok {
c.oasJsonErr(400, 400, "图片数量过多")
return
}
var item models.OaSchedule
err = models.Orm.QueryTable(new(models.OaSchedule)).
Filter("id", id).
Filter("is_deleted", 0).
Filter("tid", claims.TenantId).
Filter("user_id", claims.UserID).
One(&item)
if err != nil {
c.oasJsonErr(404, 404, "日程不存在")
return
}
now := time.Now()
item.Images = imagesJSON
item.UpdateTime = &now
if _, err := models.Orm.Update(&item, "Images", "UpdateTime"); err != nil {
c.oasJsonErr(500, 500, "保存失败")
return
}
c.oasOk(map[string]interface{}{"images": parseOaScheduleImages(imagesJSON)})
}
// Delete DELETE /backend/oa/schedule/delete/:id 软删除日程。
func (c *BackendOaScheduleController) Delete() {
claims, err := c.oaScheduleClaims()
@@ -577,6 +675,7 @@ func carryOaSchedule(item *models.OaSchedule, targetDate string, claims *jwtutil
UserName: item.UserName,
Title: item.Title,
Content: item.Content,
Images: item.Images,
ScheduleDate: targetDate,
StartTime: item.StartTime,
EndTime: item.EndTime,