Files
2026-10-22 00:27:26 +08:00

273 lines
6.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package controllers
import (
"encoding/json"
"io"
"strconv"
"strings"
"server/pkg/identity"
"server/services/dailyreport"
)
// OA 工作日报(小程序端)。与后台 /backend/oa/dailyreport/* 共用
// services/dailyreport 的权限与校验逻辑,仅在响应包装与上传入口上有差异。
// dailyReportCtx 解析移动端令牌并组装日报身份。
func (c *AppOaController) dailyReportCtx() (*dailyreport.UserContext, bool) {
claims, err := c.oaClaims()
if err != nil {
code := identity.Status(err)
c.oaErr(code, code, err.Error())
return nil, false
}
u, err := dailyreport.BuildContext(
uint64(claims.TenantId), uint64(claims.UserID), claims.Username, claims.UserType == "platform")
if err != nil {
code := dailyreport.StatusOf(err, 500)
msg := err.Error()
if code == 500 {
msg = "操作失败,请稍后重试"
}
c.oaErr(code, code, msg)
return nil, false
}
return u, true
}
func (c *AppOaController) dailyReportFail(err error) {
code := dailyreport.StatusOf(err, 500)
msg := err.Error()
if code == 500 {
msg = "操作失败,请稍后重试"
}
c.oaErr(code, code, msg)
}
func (c *AppOaController) dailyReportID() uint64 {
id, _ := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
if id == 0 {
c.oaErr(400, 400, "无效ID")
}
return id
}
// DailyReportProfile GET /api/oa/dailyreport/profile
func (c *AppOaController) DailyReportProfile() {
u, ok := c.dailyReportCtx()
if !ok {
return
}
teamOrgs := u.TeamOrgIDs
if teamOrgs == nil {
teamOrgs = []uint64{}
}
c.oaOk(map[string]interface{}{
"user_id": u.UID,
"user_name": u.Name,
"org_id": u.OrgID,
"org_name": u.OrgName,
"is_admin": u.IsAdmin,
"can_view_team": u.CanViewTeam,
"team_org_ids": teamOrgs,
"window_start": dailyreport.WindowStart(),
"window_end": dailyreport.Today(),
"backfill_days": dailyreport.BackfillDays,
})
}
// DailyReportMineList GET /api/oa/dailyreport/mine/list
func (c *AppOaController) DailyReportMineList() {
u, ok := c.dailyReportCtx()
if !ok {
return
}
page, _ := c.GetInt("page", 1)
pageSize, _ := c.GetInt("pageSize", 20)
res, err := dailyreport.ListMine(u, dailyreport.MineQuery{
StartDate: strings.TrimSpace(c.GetString("start_date")),
EndDate: strings.TrimSpace(c.GetString("end_date")),
Page: page,
PageSize: pageSize,
})
if err != nil {
c.dailyReportFail(err)
return
}
c.oaOk(res)
}
// DailyReportCalendar GET /api/oa/dailyreport/calendar
// 我的日报近期热力图:months 默认 3,返回区间内逐日状态(草稿/已提交)。
func (c *AppOaController) DailyReportCalendar() {
u, ok := c.dailyReportCtx()
if !ok {
return
}
months, _ := c.GetInt("months", 3)
res, err := dailyreport.Calendar(u, months)
if err != nil {
c.dailyReportFail(err)
return
}
c.oaOk(res)
}
// DailyReportSave POST /api/oa/dailyreport/save
func (c *AppOaController) DailyReportSave() {
u, ok := c.dailyReportCtx()
if !ok {
return
}
var in dailyreport.SaveInput
raw, err := io.ReadAll(c.Ctx.Request.Body)
if err != nil || json.Unmarshal(raw, &in) != nil {
c.oaErr(400, 400, "参数错误")
return
}
item, err := dailyreport.Save(u, in)
if err != nil {
c.dailyReportFail(err)
return
}
c.oaOk(item)
}
// DailyReportDetail GET /api/oa/dailyreport/detail/:id
func (c *AppOaController) DailyReportDetail() {
u, ok := c.dailyReportCtx()
if !ok {
return
}
id := c.dailyReportID()
if id == 0 {
return
}
detail, err := dailyreport.GetDetail(u, id)
if err != nil {
c.dailyReportFail(err)
return
}
c.oaOk(detail)
}
// DailyReportDelete DELETE /api/oa/dailyreport/delete/:id
func (c *AppOaController) DailyReportDelete() {
u, ok := c.dailyReportCtx()
if !ok {
return
}
id := c.dailyReportID()
if id == 0 {
return
}
if err := dailyreport.Delete(u, id); err != nil {
c.dailyReportFail(err)
return
}
c.oaOk(map[string]interface{}{"id": id})
}
// DailyReportWithdraw POST /api/oa/dailyreport/withdraw/:id
// 撤销提交:已提交日报退回草稿并留存本次提交的内容快照,改完需重新提交。
func (c *AppOaController) DailyReportWithdraw() {
u, ok := c.dailyReportCtx()
if !ok {
return
}
id := c.dailyReportID()
if id == 0 {
return
}
item, err := dailyreport.Withdraw(u, id)
if err != nil {
c.dailyReportFail(err)
return
}
c.oaOk(item)
}
// DailyReportTeamStatus GET /api/oa/dailyreport/team/status
func (c *AppOaController) DailyReportTeamStatus() {
u, ok := c.dailyReportCtx()
if !ok {
return
}
page, _ := c.GetInt("page", 1)
pageSize, _ := c.GetInt("pageSize", 20)
orgID, _ := c.GetInt64("org_id", 0)
res, err := dailyreport.TeamStatus(u, dailyreport.TeamQuery{
Date: strings.TrimSpace(c.GetString("date")),
OrgID: uint64(orgID),
Keyword: strings.TrimSpace(c.GetString("keyword")),
Page: page,
PageSize: pageSize,
})
if err != nil {
c.dailyReportFail(err)
return
}
c.oaOk(res)
}
// DailyReportTeamOrgs GET /api/oa/dailyreport/team/orgs
func (c *AppOaController) DailyReportTeamOrgs() {
u, ok := c.dailyReportCtx()
if !ok {
return
}
orgs, err := dailyreport.TeamOrgs(u)
if err != nil {
c.dailyReportFail(err)
return
}
c.oaOk(map[string]interface{}{"list": orgs})
}
// DailyReportComment POST /api/oa/dailyreport/comment
func (c *AppOaController) DailyReportComment() {
u, ok := c.dailyReportCtx()
if !ok {
return
}
var payload oaDailyReportCommentPayload
raw, err := io.ReadAll(c.Ctx.Request.Body)
if err != nil || json.Unmarshal(raw, &payload) != nil {
c.oaErr(400, 400, "参数错误")
return
}
if payload.ReportID == 0 {
c.oaErr(400, 400, "缺少日报ID")
return
}
comment, err := dailyreport.AddComment(u, payload.ReportID, payload.Content, payload.ReplyToID)
if err != nil {
c.dailyReportFail(err)
return
}
c.oaOk(comment)
}
// DailyReportCommentDelete DELETE /api/oa/dailyreport/comment/:id
func (c *AppOaController) DailyReportCommentDelete() {
u, ok := c.dailyReportCtx()
if !ok {
return
}
id := c.dailyReportID()
if id == 0 {
return
}
if err := dailyreport.DeleteComment(u, id); err != nil {
c.dailyReportFail(err)
return
}
c.oaOk(map[string]interface{}{"id": id})
}
// DailyReportUpload POST /api/oa/dailyreport/upload(multipart,字段名 file)
// 复用 OA 附件上传:图片 / PDF,单个文件 ≤10MB,落入租户文件管理。
func (c *AppOaController) DailyReportUpload() {
c.uploadTenantImage()
}