增加报销模块功能

This commit is contained in:
2026-07-20 17:50:47 +08:00
parent f00ba9f9cc
commit a78666177a
15 changed files with 2706 additions and 248 deletions
+701
View File
@@ -0,0 +1,701 @@
package controllers
import (
"encoding/json"
"fmt"
"io"
"strconv"
"strings"
"time"
"server/models"
"server/pkg/jwtutil"
"github.com/beego/beego/v2/client/orm"
beego "github.com/beego/beego/v2/server/web"
)
// BackendReimburseController 报销及审批接口。
type BackendReimburseController struct {
beego.Controller
}
type reimbursementItemPayload struct {
ID uint64 `json:"id"`
ExpenseType string `json:"expense_type"`
ExpenseDate string `json:"expense_date"`
Amount float64 `json:"amount"`
Quantity int `json:"quantity"`
UnitPrice float64 `json:"unit_price"`
Description string `json:"description"`
ReceiptFlag int8 `json:"receipt_flag"`
ReceiptURL string `json:"receipt_url"`
}
type reimbursementPayload struct {
Title string `json:"title"`
DepartmentID *uint64 `json:"department_id"`
ExpenseType string `json:"expense_type"`
ApplyDate string `json:"apply_date"`
Description string `json:"description"`
Items []reimbursementItemPayload `json:"items"`
}
func (c *BackendReimburseController) claims() (*jwtutil.Claims, bool) {
auth := strings.TrimSpace(c.Ctx.Request.Header.Get("Authorization"))
parts := strings.SplitN(auth, " ", 2)
if len(parts) != 2 || parts[0] != "Bearer" {
return nil, false
}
claims, err := jwtutil.ParseToken(parts[1])
if err != nil || claims.UserType != "backend" || claims.TenantId <= 0 || claims.UserID <= 0 {
return nil, false
}
return claims, true
}
func (c *BackendReimburseController) reply(code int, msg string, data interface{}) {
if code != 200 {
c.Ctx.Output.SetStatus(code)
}
result := map[string]interface{}{"code": code, "msg": msg}
if data != nil {
result["data"] = data
}
c.Data["json"] = result
_ = c.ServeJSON()
}
func (c *BackendReimburseController) parsePayload() (reimbursementPayload, error) {
var payload reimbursementPayload
raw, err := io.ReadAll(c.Ctx.Request.Body)
if err != nil {
return payload, err
}
err = json.Unmarshal(raw, &payload)
return payload, err
}
func parseReimburseDate(value string) (time.Time, error) {
return time.Parse("2006-01-02", strings.TrimSpace(value))
}
func (c *BackendReimburseController) getID() (uint64, bool) {
id, err := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
return id, err == nil && id > 0
}
func (c *BackendReimburseController) findOwned(id uint64, claims *jwtutil.Claims) (*models.BackendReimbursement, error) {
row := &models.BackendReimbursement{}
err := models.Orm.QueryTable(new(models.BackendReimbursement)).
Filter("id", id).
Filter("tid", claims.TenantId).
Filter("user_id", claims.UserID).
Filter("is_deleted", 0).
One(row)
return row, err
}
func reimbursementItemDTO(item models.BackendReimbursementItem) map[string]interface{} {
return map[string]interface{}{
"id": item.ID, "reimbursement_id": item.ReimbursementID,
"expense_type": item.ExpenseType, "expense_date": item.ExpenseDate.Format("2006-01-02"),
"amount": item.Amount, "quantity": item.Quantity, "unit_price": item.UnitPrice,
"description": item.Description, "receipt_flag": item.ReceiptFlag, "receipt_url": item.ReceiptURL,
}
}
func reimbursementDTO(row models.BackendReimbursement, items []models.BackendReimbursementItem) map[string]interface{} {
result := map[string]interface{}{
"id": row.ID, "tid": row.Tid, "uid": row.UID, "user_id": row.UserID,
"department_id": row.DepartmentID, "title": row.Title, "total_amount": row.TotalAmount,
"status": row.Status, "expense_type": row.ExpenseType, "apply_date": row.ApplyDate.Format("2006-01-02"),
"description": row.Description, "current_approver_id": row.CurrentApproverID,
"current_step": row.CurrentStep, "create_time": row.CreateTime, "update_time": row.UpdateTime,
}
list := make([]map[string]interface{}, 0, len(items))
for _, item := range items {
list = append(list, reimbursementItemDTO(item))
}
result["items"] = list
return result
}
// List GET /backend/reimbursements
func (c *BackendReimburseController) List() {
claims, ok := c.claims()
if !ok {
c.reply(401, "未登录或无权限", nil)
return
}
page, _ := c.GetInt("page", 1)
pageSize, _ := c.GetInt("pageSize", 10)
if page < 1 {
page = 1
}
if pageSize < 1 || pageSize > 100 {
pageSize = 10
}
keyword := strings.TrimSpace(c.GetString("keyword"))
status, statusErr := c.GetInt("status")
hasStatus := statusErr == nil
qs := models.Orm.QueryTable(new(models.BackendReimbursement)).
Filter("tid", claims.TenantId).Filter("user_id", claims.UserID).Filter("is_deleted", 0)
if keyword != "" {
qs = qs.Filter("description__icontains", keyword)
}
if hasStatus {
qs = qs.Filter("status", status)
}
total, err := qs.Count()
if err != nil {
c.reply(500, "查询失败", nil)
return
}
var rows []models.BackendReimbursement
_, err = qs.OrderBy("-id").Limit(pageSize, (page-1)*pageSize).All(&rows)
if err != nil && err != orm.ErrNoRows {
c.reply(500, "查询失败", nil)
return
}
if rows == nil {
rows = []models.BackendReimbursement{}
}
list := make([]map[string]interface{}, 0, len(rows))
for _, row := range rows {
list = append(list, map[string]interface{}{
"id": row.ID,
"tid": row.Tid,
"uid": row.UID,
"user_id": row.UserID,
"department_id": row.DepartmentID,
"title": row.Title,
"total_amount": row.TotalAmount,
"status": row.Status,
"expense_type": row.ExpenseType,
"apply_date": row.ApplyDate.Format("2006-01-02"),
"description": row.Description,
"current_approver_id": row.CurrentApproverID,
"current_step": row.CurrentStep,
"create_time": row.CreateTime,
"update_time": row.UpdateTime,
})
}
c.reply(200, "success", map[string]interface{}{"list": list, "total": total})
}
// Detail GET /backend/reimbursements/:id
func (c *BackendReimburseController) Detail() {
claims, ok := c.claims()
if !ok {
c.reply(401, "未登录或无权限", nil)
return
}
id, ok := c.getID()
if !ok {
c.reply(400, "无效ID", nil)
return
}
row, err := c.findOwned(id, claims)
if err != nil {
c.reply(404, "报销单不存在", nil)
return
}
var items []models.BackendReimbursementItem
_, err = models.Orm.QueryTable(new(models.BackendReimbursementItem)).
Filter("reimbursement_id", id).Filter("tid", claims.TenantId).Filter("is_deleted", 0).
OrderBy("id").All(&items)
if err != nil && err != orm.ErrNoRows {
c.reply(500, "查询明细失败", nil)
return
}
c.reply(200, "success", reimbursementDTO(*row, items))
}
// Create POST /backend/reimbursements
func (c *BackendReimburseController) Create() {
claims, ok := c.claims()
if !ok {
c.reply(401, "未登录或无权限", nil)
return
}
payload, err := c.parsePayload()
if err != nil {
c.reply(400, "参数错误", nil)
return
}
applyDate, err := parseReimburseDate(payload.ApplyDate)
if err != nil {
c.reply(400, "申请日期格式错误", nil)
return
}
uid := uint64(claims.UserID)
row := &models.BackendReimbursement{
Tid: uint64(claims.TenantId), UID: &uid, UserID: uid, DepartmentID: payload.DepartmentID,
Title: "", TotalAmount: 0, Status: 0,
ExpenseType: strings.TrimSpace(payload.ExpenseType), ApplyDate: applyDate,
Description: nullableReimburseString(payload.Description),
}
if err := saveReimbursement(row); err != nil {
c.reply(500, "创建报销单失败", nil)
return
}
c.reply(200, "success", map[string]interface{}{"id": row.ID})
}
// Update POST /backend/reimbursements/:id
func (c *BackendReimburseController) Update() {
claims, ok := c.claims()
if !ok {
c.reply(401, "未登录或无权限", nil)
return
}
id, ok := c.getID()
if !ok {
c.reply(400, "无效ID", nil)
return
}
row, err := c.findOwned(id, claims)
if err != nil {
c.reply(404, "报销单不存在", nil)
return
}
if row.Status != 0 {
c.reply(400, "只有草稿可以编辑", nil)
return
}
payload, err := c.parsePayload()
if err != nil {
c.reply(400, "参数错误", nil)
return
}
applyDate, err := parseReimburseDate(payload.ApplyDate)
if err != nil {
c.reply(400, "申请日期格式错误", nil)
return
}
row.ApplyDate, row.Description = applyDate, nullableReimburseString(payload.Description)
if err := saveReimbursement(row); err != nil {
c.reply(500, "更新报销单失败", nil)
return
}
c.reply(200, "success", map[string]interface{}{"id": row.ID})
}
// Delete DELETE /backend/reimbursements/:id
func (c *BackendReimburseController) Delete() {
claims, ok := c.claims()
if !ok {
c.reply(401, "未登录或无权限", nil)
return
}
id, ok := c.getID()
if !ok {
c.reply(400, "无效ID", nil)
return
}
row, err := c.findOwned(id, claims)
if err != nil {
c.reply(404, "报销单不存在", nil)
return
}
if row.Status != 0 {
c.reply(400, "只有草稿可以删除", nil)
return
}
now := time.Now()
_, err = models.Orm.QueryTable(new(models.BackendReimbursement)).Filter("id", id).
Update(orm.Params{"is_deleted": 1, "delete_time": now, "update_time": now})
if err != nil {
c.reply(500, "删除失败", nil)
return
}
_, _ = models.Orm.QueryTable(new(models.BackendReimbursementItem)).
Filter("reimbursement_id", id).Update(orm.Params{"is_deleted": 1, "delete_time": now})
c.reply(200, "success", nil)
}
func (c *BackendReimburseController) parseItemPayload() (reimbursementItemPayload, error) {
var payload reimbursementItemPayload
raw, err := io.ReadAll(c.Ctx.Request.Body)
if err != nil {
return payload, err
}
err = json.Unmarshal(raw, &payload)
return payload, err
}
func (c *BackendReimburseController) getItemID() (uint64, bool) {
id, err := strconv.ParseUint(c.Ctx.Input.Param(":item_id"), 10, 64)
return id, err == nil && id > 0
}
func (c *BackendReimburseController) findOwnedItem(id, reimbursementID uint64, claims *jwtutil.Claims) (*models.BackendReimbursementItem, error) {
item := &models.BackendReimbursementItem{}
err := models.Orm.QueryTable(new(models.BackendReimbursementItem)).
Filter("id", id).
Filter("reimbursement_id", reimbursementID).
Filter("tid", claims.TenantId).
Filter("uid", claims.UserID).
Filter("is_deleted", 0).
One(item)
return item, err
}
func validateReimbursementItem(item reimbursementItemPayload) (time.Time, error) {
if strings.TrimSpace(item.ExpenseType) == "" {
return time.Time{}, fmt.Errorf("费用类型不能为空")
}
date, err := parseReimburseDate(item.ExpenseDate)
if err != nil {
return time.Time{}, fmt.Errorf("费用日期格式错误")
}
if item.Amount <= 0 {
return time.Time{}, fmt.Errorf("费用金额必须大于0")
}
return date, nil
}
func (c *BackendReimburseController) ensureDraftReimbursement(id uint64, claims *jwtutil.Claims) (*models.BackendReimbursement, bool) {
row, err := c.findOwned(id, claims)
if err != nil {
c.reply(404, "报销单不存在", nil)
return nil, false
}
if row.Status != 0 {
c.reply(400, "只有草稿可以维护费用明细", nil)
return nil, false
}
return row, true
}
func recalculateReimbursementTotal(id uint64) error {
var items []models.BackendReimbursementItem
_, err := models.Orm.QueryTable(new(models.BackendReimbursementItem)).
Filter("reimbursement_id", id).Filter("is_deleted", 0).All(&items)
if err != nil && err != orm.ErrNoRows {
return err
}
var total float64
for _, item := range items {
total += item.Amount
}
_, err = models.Orm.QueryTable(new(models.BackendReimbursement)).
Filter("id", id).Update(orm.Params{
"total_amount": total,
"update_time": time.Now(),
})
return err
}
// AddItem POST /backend/reimbursements/:id/items
func (c *BackendReimburseController) AddItem() {
claims, ok := c.claims()
if !ok {
c.reply(401, "未登录或无权限", nil)
return
}
reimbursementID, ok := c.getID()
if !ok {
c.reply(400, "无效报销单ID", nil)
return
}
if _, ok := c.ensureDraftReimbursement(reimbursementID, claims); !ok {
return
}
payload, err := c.parseItemPayload()
if err != nil {
c.reply(400, "参数错误", nil)
return
}
date, err := validateReimbursementItem(payload)
if err != nil {
c.reply(400, err.Error(), nil)
return
}
uid := uint64(claims.UserID)
quantity := payload.Quantity
if quantity <= 0 {
quantity = 1
}
item := &models.BackendReimbursementItem{
Tid: uint64(claims.TenantId), UID: &uid, ReimbursementID: reimbursementID,
ExpenseType: strings.TrimSpace(payload.ExpenseType), ExpenseDate: date,
Amount: payload.Amount, Quantity: quantity, UnitPrice: payload.UnitPrice,
Description: strings.TrimSpace(payload.Description), ReceiptFlag: payload.ReceiptFlag,
ReceiptURL: strings.TrimSpace(payload.ReceiptURL),
}
if _, err := models.Orm.Insert(item); err != nil {
c.reply(500, "新增费用明细失败", nil)
return
}
if err := recalculateReimbursementTotal(reimbursementID); err != nil {
c.reply(500, "更新报销总额失败", nil)
return
}
c.reply(200, "success", reimbursementItemDTO(*item))
}
// UpdateItem POST /backend/reimbursements/:id/items/:item_id
func (c *BackendReimburseController) UpdateItem() {
claims, ok := c.claims()
if !ok {
c.reply(401, "未登录或无权限", nil)
return
}
reimbursementID, ok := c.getID()
if !ok {
c.reply(400, "无效报销单ID", nil)
return
}
itemID, ok := c.getItemID()
if !ok {
c.reply(400, "无效费用明细ID", nil)
return
}
if _, ok := c.ensureDraftReimbursement(reimbursementID, claims); !ok {
return
}
item, err := c.findOwnedItem(itemID, reimbursementID, claims)
if err != nil {
c.reply(404, "费用明细不存在", nil)
return
}
payload, err := c.parseItemPayload()
if err != nil {
c.reply(400, "参数错误", nil)
return
}
date, err := validateReimbursementItem(payload)
if err != nil {
c.reply(400, err.Error(), nil)
return
}
quantity := payload.Quantity
if quantity <= 0 {
quantity = 1
}
item.ExpenseType = strings.TrimSpace(payload.ExpenseType)
item.ExpenseDate = date
item.Amount = payload.Amount
item.Quantity = quantity
item.UnitPrice = payload.UnitPrice
item.Description = strings.TrimSpace(payload.Description)
item.ReceiptFlag = payload.ReceiptFlag
item.ReceiptURL = strings.TrimSpace(payload.ReceiptURL)
if _, err := models.Orm.Update(item); err != nil {
c.reply(500, "更新费用明细失败", nil)
return
}
if err := recalculateReimbursementTotal(reimbursementID); err != nil {
c.reply(500, "更新报销总额失败", nil)
return
}
c.reply(200, "success", reimbursementItemDTO(*item))
}
// DeleteItem DELETE /backend/reimbursements/:id/items/:item_id
func (c *BackendReimburseController) DeleteItem() {
claims, ok := c.claims()
if !ok {
c.reply(401, "未登录或无权限", nil)
return
}
reimbursementID, ok := c.getID()
if !ok {
c.reply(400, "无效报销单ID", nil)
return
}
itemID, ok := c.getItemID()
if !ok {
c.reply(400, "无效费用明细ID", nil)
return
}
if _, ok := c.ensureDraftReimbursement(reimbursementID, claims); !ok {
return
}
item, err := c.findOwnedItem(itemID, reimbursementID, claims)
if err != nil {
c.reply(404, "费用明细不存在", nil)
return
}
now := time.Now()
_, err = models.Orm.QueryTable(new(models.BackendReimbursementItem)).
Filter("id", item.ID).Update(orm.Params{"is_deleted": 1, "delete_time": now, "update_time": now})
if err != nil {
c.reply(500, "删除费用明细失败", nil)
return
}
if err := recalculateReimbursementTotal(reimbursementID); err != nil {
c.reply(500, "更新报销总额失败", nil)
return
}
c.reply(200, "success", nil)
}
// Submit POST /backend/reimbursements/:id/submit
func (c *BackendReimburseController) Submit() {
claims, ok := c.claims()
if !ok {
c.reply(401, "未登录或无权限", nil)
return
}
id, ok := c.getID()
if !ok {
c.reply(400, "无效ID", nil)
return
}
row, err := c.findOwned(id, claims)
if err != nil {
c.reply(404, "报销单不存在", nil)
return
}
if row.Status != 0 {
c.reply(400, "当前状态不可提交", nil)
return
}
var flow models.BackendApprovalFlow
err = models.Orm.QueryTable(new(models.BackendApprovalFlow)).
Filter("tid", claims.TenantId).Filter("is_active", 1).Filter("is_deleted", 0).
OrderBy("step_order").One(&flow)
if err != nil {
c.reply(400, "尚未配置审批流程", nil)
return
}
now := time.Now()
_, err = models.Orm.QueryTable(new(models.BackendReimbursement)).Filter("id", id).Update(orm.Params{
"status": 1, "current_step": flow.StepOrder, "current_approver_id": 0, "update_time": now,
})
if err != nil {
c.reply(500, "提交失败", nil)
return
}
_, err = models.Orm.Insert(&models.BackendApprovalRecord{
Tid: uint64(claims.TenantId), UID: uint64Ptr(uint64(claims.UserID)), ReimbursementID: id,
ApproverID: uint64(claims.UserID), ApproverName: claims.Username, Action: 1,
Step: flow.StepOrder, PrevStep: 0,
})
if err != nil {
c.reply(500, "提交审批记录失败", nil)
return
}
c.reply(200, "success", nil)
}
// Records GET /backend/reimbursements/:id/records
func (c *BackendReimburseController) Records() {
claims, ok := c.claims()
if !ok {
c.reply(401, "未登录或无权限", nil)
return
}
id, ok := c.getID()
if !ok {
c.reply(400, "无效ID", nil)
return
}
if _, err := c.findOwned(id, claims); err != nil {
c.reply(404, "报销单不存在", nil)
return
}
var rows []models.BackendApprovalRecord
_, err := models.Orm.QueryTable(new(models.BackendApprovalRecord)).
Filter("tid", claims.TenantId).Filter("reimbursement_id", id).Filter("is_deleted", 0).
OrderBy("step", "id").All(&rows)
if err != nil && err != orm.ErrNoRows {
c.reply(500, "查询审批记录失败", nil)
return
}
if rows == nil {
rows = []models.BackendApprovalRecord{}
}
c.reply(200, "success", rows)
}
// Types GET /backend/reimbursements/types
func (c *BackendReimburseController) Types() {
claims, ok := c.claims()
if !ok {
c.reply(401, "未登录或无权限", nil)
return
}
var rows []models.BackendReimbursementExpenseType
_, err := models.Orm.QueryTable(new(models.BackendReimbursementExpenseType)).
Filter("tid", claims.TenantId).Filter("is_active", 1).Filter("is_deleted", 0).
OrderBy("sort_order", "id").All(&rows)
if err != nil && err != orm.ErrNoRows {
c.reply(500, "查询费用类型失败", nil)
return
}
if rows == nil {
rows = []models.BackendReimbursementExpenseType{}
}
c.reply(200, "success", rows)
}
// Flows GET /backend/reimbursements/flows
func (c *BackendReimburseController) Flows() {
claims, ok := c.claims()
if !ok {
c.reply(401, "未登录或无权限", nil)
return
}
var rows []models.BackendApprovalFlow
_, err := models.Orm.QueryTable(new(models.BackendApprovalFlow)).
Filter("tid", claims.TenantId).Filter("is_active", 1).Filter("is_deleted", 0).
OrderBy("step_order").All(&rows)
if err != nil && err != orm.ErrNoRows {
c.reply(500, "查询审批流程失败", nil)
return
}
if rows == nil {
rows = []models.BackendApprovalFlow{}
}
c.reply(200, "success", rows)
}
func validateItems(items []reimbursementItemPayload) (float64, error) {
var total float64
for i, item := range items {
if strings.TrimSpace(item.ExpenseType) == "" {
return 0, fmt.Errorf("第%d条费用类型不能为空", i+1)
}
if _, err := parseReimburseDate(item.ExpenseDate); err != nil {
return 0, fmt.Errorf("第%d条费用日期格式错误", i+1)
}
if item.Amount <= 0 {
return 0, fmt.Errorf("第%d条费用金额必须大于0", i+1)
}
if item.Quantity <= 0 {
item.Quantity = 1
}
total += item.Amount
}
return total, nil
}
func saveReimbursement(row *models.BackendReimbursement) error {
if row.ID == 0 {
id, err := models.Orm.Insert(row)
if err != nil {
return err
}
row.ID = uint64(id)
return nil
}
_, err := models.Orm.Update(row)
return err
}
func nullableReimburseString(value string) *string {
value = strings.TrimSpace(value)
if value == "" {
return nil
}
return &value
}
func uint64Ptr(value uint64) *uint64 {
return &value
}
+91 -86
View File
@@ -1,86 +1,91 @@
package models
import (
"fmt"
"github.com/beego/beego/v2/client/orm"
beego "github.com/beego/beego/v2/server/web"
_ "github.com/go-sql-driver/mysql"
)
// Orm 全局 ORM 对象,供业务层和控制器使用
var Orm orm.Ormer
// Init 初始化模型层资源(数据库连接、模型注册等)。
func Init(_ string) {
// 从配置读取数据库连接信息
user, _ := beego.AppConfig.String("mysqluser")
pass, _ := beego.AppConfig.String("mysqlpass")
urls, _ := beego.AppConfig.String("mysqlurls")
dbname, _ := beego.AppConfig.String("mysqldb")
if user == "" || urls == "" || dbname == "" {
panic("数据库配置(mysqluser/mysqlurls/mysqldb) 未正确设置")
}
// 组装 DSNuser:pass@tcp(host:port)/dbname?charset=utf8mb4&parseTime=True&loc=Local
dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", user, pass, urls, dbname)
// 注册默认数据库
if err := orm.RegisterDataBase("default", "mysql", dsn); err != nil {
panic("注册数据库失败: " + err.Error())
}
// 注册模型
orm.RegisterModel(
new(SystemTenant),
new(SystemTenantUser),
new(BackendErpOrganization),
new(BackendErpEmployee),
new(BackendErpPosition),
new(SystemMenu),
new(AdminUser),
new(AdminRole),
new(SystemFile),
new(SystemFilesCategory),
new(SystemSMSTask),
new(SystemOperationLog),
new(SystemDomainPool),
new(SystemTenantDomain),
new(SystemModules),
new(StorageConfig),
new(TenantSiteSetting),
new(ComplaintCategory),
new(PlatformComplaint),
new(SystemSoftwareUpgrade),
new(PlatformCursorEquipment),
new(PlatformCursorActivationCode),
new(PlatformCursorEquipmentIpLog),
new(PlatformAccountPoolKiro),
new(PlatformAccountPoolWindsurf),
new(PlatformAccountPoolCursor),
new(PlatformAccountPoolCodex),
new(PlatformNotebook),
new(CmsArticleCategory),
new(CmsArticle),
new(SystemReminderList),
new(SystemNormalSetting),
new(PlatformNormalSetting),
new(BackendNormalSetting),
new(PlatformSchedule),
new(PlatformScheduleReminder),
new(PlatformScheduleReminderSendLog),
new(BackendNotebook),
new(BackendSchedule),
new(BackendScheduleReminder),
new(BackendScheduleReminderSendLog),
)
// 创建全局 Ormer
Orm = orm.NewOrm()
}
package models
import (
"fmt"
"github.com/beego/beego/v2/client/orm"
beego "github.com/beego/beego/v2/server/web"
_ "github.com/go-sql-driver/mysql"
)
// Orm 全局 ORM 对象,供业务层和控制器使用
var Orm orm.Ormer
// Init 初始化模型层资源(数据库连接、模型注册等)。
func Init(_ string) {
// 从配置读取数据库连接信息
user, _ := beego.AppConfig.String("mysqluser")
pass, _ := beego.AppConfig.String("mysqlpass")
urls, _ := beego.AppConfig.String("mysqlurls")
dbname, _ := beego.AppConfig.String("mysqldb")
if user == "" || urls == "" || dbname == "" {
panic("数据库配置(mysqluser/mysqlurls/mysqldb) 未正确设置")
}
// 组装 DSNuser:pass@tcp(host:port)/dbname?charset=utf8mb4&parseTime=True&loc=Local
dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", user, pass, urls, dbname)
// 注册默认数据库
if err := orm.RegisterDataBase("default", "mysql", dsn); err != nil {
panic("注册数据库失败: " + err.Error())
}
// 注册模型
orm.RegisterModel(
new(SystemTenant),
new(SystemTenantUser),
new(BackendErpOrganization),
new(BackendErpEmployee),
new(BackendErpPosition),
new(BackendApprovalFlow),
new(BackendApprovalRecord),
new(BackendReimbursement),
new(BackendReimbursementItem),
new(BackendReimbursementExpenseType),
new(SystemMenu),
new(AdminUser),
new(AdminRole),
new(SystemFile),
new(SystemFilesCategory),
new(SystemSMSTask),
new(SystemOperationLog),
new(SystemDomainPool),
new(SystemTenantDomain),
new(SystemModules),
new(StorageConfig),
new(TenantSiteSetting),
new(ComplaintCategory),
new(PlatformComplaint),
new(SystemSoftwareUpgrade),
new(PlatformCursorEquipment),
new(PlatformCursorActivationCode),
new(PlatformCursorEquipmentIpLog),
new(PlatformAccountPoolKiro),
new(PlatformAccountPoolWindsurf),
new(PlatformAccountPoolCursor),
new(PlatformAccountPoolCodex),
new(PlatformNotebook),
new(CmsArticleCategory),
new(CmsArticle),
new(SystemReminderList),
new(SystemNormalSetting),
new(PlatformNormalSetting),
new(BackendNormalSetting),
new(PlatformSchedule),
new(PlatformScheduleReminder),
new(PlatformScheduleReminderSendLog),
new(BackendNotebook),
new(BackendSchedule),
new(BackendScheduleReminder),
new(BackendScheduleReminderSendLog),
)
// 创建全局 Ormer
Orm = orm.NewOrm()
}
+113
View File
@@ -0,0 +1,113 @@
package models
import "time"
// BackendApprovalFlow 审批流程配置表 yz_backend_approval_flows
type BackendApprovalFlow struct {
ID uint64 `orm:"column(id);pk;auto" json:"id"`
Tid uint64 `orm:"column(tid)" json:"tid"`
UID *uint64 `orm:"column(uid);null" json:"uid"`
FlowName string `orm:"column(flow_name);size(100)" json:"flow_name"`
StepOrder int8 `orm:"column(step_order);default(0)" json:"step_order"`
ApproverRole string `orm:"column(approver_role);size(50)" json:"approver_role"`
ApproverRule string `orm:"column(approver_rule);size(200)" json:"approver_rule"`
TimeoutHours int `orm:"column(timeout_hours);default(48)" json:"timeout_hours"`
IsActive int8 `orm:"column(is_active);default(1)" json:"is_active"`
IsDeleted int8 `orm:"column(is_deleted);default(0)" json:"is_deleted"`
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
UpdateTime *time.Time `orm:"column(update_time);null;type(datetime)" json:"update_time"`
DeleteTime *time.Time `orm:"column(delete_time);null;type(datetime)" json:"delete_time"`
}
func (m *BackendApprovalFlow) TableName() string {
return "yz_backend_approval_flows"
}
// BackendApprovalRecord 审批记录表 yz_backend_approval_records
type BackendApprovalRecord struct {
ID uint64 `orm:"column(id);pk;auto" json:"id"`
Tid uint64 `orm:"column(tid)" json:"tid"`
UID *uint64 `orm:"column(uid);null" json:"uid"`
ReimbursementID uint64 `orm:"column(reimbursement_id)" json:"reimbursement_id"`
ApproverID uint64 `orm:"column(approver_id)" json:"approver_id"`
ApproverName string `orm:"column(approver_name);size(100)" json:"approver_name"`
Action int8 `orm:"column(action);default(0)" json:"action"`
Comment *string `orm:"column(comment);null;type(text)" json:"comment"`
Step int8 `orm:"column(step);default(0)" json:"step"`
PrevStep int8 `orm:"column(prev_step);default(0)" json:"prev_step"`
IsDeleted int8 `orm:"column(is_deleted);default(0)" json:"is_deleted"`
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
UpdateTime *time.Time `orm:"column(update_time);null;type(datetime)" json:"update_time"`
DeleteTime *time.Time `orm:"column(delete_time);null;type(datetime)" json:"delete_time"`
}
func (m *BackendApprovalRecord) TableName() string {
return "yz_backend_approval_records"
}
// BackendReimbursement 报销单主表 yz_backend_reimbursements
type BackendReimbursement struct {
ID uint64 `orm:"column(id);pk;auto" json:"id"`
Tid uint64 `orm:"column(tid)" json:"tid"`
UID *uint64 `orm:"column(uid);null" json:"uid"`
UserID uint64 `orm:"column(user_id)" json:"user_id"`
DepartmentID *uint64 `orm:"column(department_id);null" json:"department_id"`
Title string `orm:"column(title);size(200)" json:"title"`
TotalAmount float64 `orm:"column(total_amount);type(decimal);digits(10);decimals(2)" json:"total_amount"`
Status int8 `orm:"column(status);default(0)" json:"status"`
ExpenseType string `orm:"column(expense_type);size(50)" json:"expense_type"`
ApplyDate time.Time `orm:"column(apply_date);type(date)" json:"apply_date"`
Description *string `orm:"column(description);null;type(text)" json:"description"`
CurrentApproverID uint64 `orm:"column(current_approver_id);default(0)" json:"current_approver_id"`
CurrentStep int8 `orm:"column(current_step);default(0)" json:"current_step"`
IsDeleted int8 `orm:"column(is_deleted);default(0)" json:"is_deleted"`
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
UpdateTime *time.Time `orm:"column(update_time);null;type(datetime)" json:"update_time"`
DeleteTime *time.Time `orm:"column(delete_time);null;type(datetime)" json:"delete_time"`
}
func (m *BackendReimbursement) TableName() string {
return "yz_backend_reimbursements"
}
// BackendReimbursementItem 报销费用明细表 yz_backend_reimbursement_items
type BackendReimbursementItem struct {
ID uint64 `orm:"column(id);pk;auto" json:"id"`
Tid uint64 `orm:"column(tid)" json:"tid"`
UID *uint64 `orm:"column(uid);null" json:"uid"`
ReimbursementID uint64 `orm:"column(reimbursement_id)" json:"reimbursement_id"`
ExpenseType string `orm:"column(expense_type);size(50)" json:"expense_type"`
ExpenseDate time.Time `orm:"column(expense_date);type(date)" json:"expense_date"`
Amount float64 `orm:"column(amount);type(decimal);digits(10);decimals(2)" json:"amount"`
Quantity int `orm:"column(quantity);default(1)" json:"quantity"`
UnitPrice float64 `orm:"column(unit_price);type(decimal);digits(10);decimals(2)" json:"unit_price"`
Description string `orm:"column(description);size(200)" json:"description"`
ReceiptFlag int8 `orm:"column(receipt_flag);default(0)" json:"receipt_flag"`
ReceiptURL string `orm:"column(receipt_url);size(500)" json:"receipt_url"`
IsDeleted int8 `orm:"column(is_deleted);default(0)" json:"is_deleted"`
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
UpdateTime *time.Time `orm:"column(update_time);null;type(datetime)" json:"update_time"`
DeleteTime *time.Time `orm:"column(delete_time);null;type(datetime)" json:"delete_time"`
}
func (m *BackendReimbursementItem) TableName() string {
return "yz_backend_reimbursement_items"
}
// BackendReimbursementExpenseType 报销费用类型表 yz_backend_reimbursement_expense_types
type BackendReimbursementExpenseType struct {
ID uint64 `orm:"column(id);pk;auto" json:"id"`
Tid uint64 `orm:"column(tid)" json:"tid"`
UID *uint64 `orm:"column(uid);null" json:"uid"`
Name string `orm:"column(name);size(50)" json:"name"`
SortOrder int `orm:"column(sort_order);default(0)" json:"sort_order"`
IsActive int8 `orm:"column(is_active);default(1)" json:"is_active"`
IsDeleted int8 `orm:"column(is_deleted);default(0)" json:"is_deleted"`
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
UpdateTime *time.Time `orm:"column(update_time);null;type(datetime)" json:"update_time"`
DeleteTime *time.Time `orm:"column(delete_time);null;type(datetime)" json:"delete_time"`
}
func (m *BackendReimbursementExpenseType) TableName() string {
return "yz_backend_reimbursement_expense_types"
}
+172 -162
View File
@@ -1,162 +1,172 @@
package backend
import (
"server/controllers"
beego "github.com/beego/beego/v2/server/web"
)
// Register 注册租户端(backend)路由。
// 该端不包含平台菜单配置接口。
func Register() {
RegisterAuthRoutes()
}
// RegisterAuthRoutes 注册 backend 认证相关路由。
func RegisterAuthRoutes() {
// 登录、注册与找回密码相关
beego.Router("/backend/login", &controllers.BackendAuthController{}, "post:LoginBackend")
beego.Router("/backend/sendLoginCode", &controllers.BackendAuthController{}, "post:SendLoginCode")
beego.Router("/backend/loginBySms", &controllers.BackendAuthController{}, "post:LoginBySms")
beego.Router("/backend/logout", &controllers.BackendAuthController{}, "post:Logout")
beego.Router("/backend/register", &controllers.BackendAuthController{}, "post:Register")
beego.Router("/backend/sendRegisterCode", &controllers.BackendAuthController{}, "post:SendRegisterCode")
beego.Router("/backend/resetPassword", &controllers.BackendAuthController{}, "post:ResetPassword")
beego.Router("/backend/sendResetCode", &controllers.BackendAuthController{}, "post:SendResetCode")
// 极验与登录验证配置
beego.Router("/backend/login/getGeetest3Infos", &controllers.BackendAuthController{}, "get:GetGeetest3Infos")
beego.Router("/backend/login/getGeetest4Infos", &controllers.BackendAuthController{}, "get:GetGeetest4Infos")
beego.Router("/backend/login/getOpenVerify", &controllers.BackendAuthController{}, "get:GetOpenVerify")
// 菜单接口
beego.Router("/backend/menu/:id", &controllers.BackendMenuController{}, "get:GetBackendMenu")
beego.Router("/backend/allmenu", &controllers.BackendMenuController{}, "get:GetAllBackendMenus")
// 操作日志(yz_system_operation_log
beego.Router("/backend/operationLogs", &controllers.BackendOperationLogController{}, "get:List")
beego.Router("/backend/operationLogs/statistics", &controllers.BackendOperationLogController{}, "get:Statistics")
beego.Router("/backend/operationLogs/:id", &controllers.BackendOperationLogController{}, "get:Detail;delete:Delete")
beego.Router("/backend/operationLogs/batchDelete", &controllers.BackendOperationLogController{}, "post:BatchDelete")
// 租户站点设置
beego.Router("/backend/normalInfos", &controllers.BackendSiteSettingsController{}, "get:GetNormalInfos")
beego.Router("/backend/saveNormalInfos", &controllers.BackendSiteSettingsController{}, "post:SaveNormalInfos")
beego.Router("/backend/legalInfos", &controllers.BackendSiteSettingsController{}, "get:GetLegalInfos")
beego.Router("/backend/saveLegalInfos", &controllers.BackendSiteSettingsController{}, "post:SaveLegalInfos")
beego.Router("/backend/companyInfos", &controllers.BackendSiteSettingsController{}, "get:GetCompanyInfos")
beego.Router("/backend/saveCompanyInfos", &controllers.BackendSiteSettingsController{}, "post:SaveCompanyInfos")
beego.Router("/backend/companySeo", &controllers.BackendSiteSettingsController{}, "get:GetCompanySeo")
beego.Router("/backend/saveCompanySeo", &controllers.BackendSiteSettingsController{}, "post:SaveCompanySeo")
beego.Router("/backend/loginVerifyInfos", &controllers.BackendLoginVerifyController{}, "get:GetLoginVerifyInfos")
beego.Router("/backend/saveloginVerifyInfos", &controllers.BackendLoginVerifyController{}, "post:SaveLoginVerifyInfos")
// 站内信(yz_system_reminderlist
beego.Router("/backend/sitereminder/myList", &controllers.BackendSiteReminderController{}, "get:GetMyList")
beego.Router("/backend/sitereminder/read", &controllers.BackendSiteReminderController{}, "post:MarkRead")
beego.Router("/backend/sitereminder/readall", &controllers.BackendSiteReminderController{}, "post:MarkAllRead")
beego.Router("/backend/sitereminder/delete", &controllers.BackendSiteReminderController{}, "post:Delete")
// 文件管理(yz_system_files / yz_system_files_category
beego.Router("/backend/usercate", &controllers.BackendFileController{}, "get:GetUserCate")
beego.Router("/backend/allfiles", &controllers.BackendFileController{}, "get:GetAllFiles")
beego.Router("/backend/catefiles/:id", &controllers.BackendFileController{}, "get:GetCateFiles")
beego.Router("/backend/file/:id", &controllers.BackendFileController{}, "get:GetFileByID")
beego.Router("/backend/deletefilepermanently/:id", &controllers.BackendFileController{}, "delete:DeleteFilePermanently")
beego.Router("/backend/uploadfile", &controllers.BackendFileController{}, "post:UploadFile")
beego.Router("/backend/uploadfiles", &controllers.BackendFileController{}, "post:UploadFile")
beego.Router("/backend/updatefile/:id", &controllers.BackendFileController{}, "post:UpdateFile")
beego.Router("/backend/deletefile/:id", &controllers.BackendFileController{}, "delete:DeleteFile")
beego.Router("/backend/movefile/:id", &controllers.BackendFileController{}, "get:MoveFile")
beego.Router("/backend/createfilecate", &controllers.BackendFileController{}, "post:CreateFileCate")
beego.Router("/backend/renamefilecate/:id", &controllers.BackendFileController{}, "post:RenameFileCate")
beego.Router("/backend/deletefilecate/:id", &controllers.BackendFileController{}, "delete:DeleteFileCate")
beego.Router("/backend/uploadavatar", &controllers.BackendFileController{}, "post:UploadAvatar")
beego.Router("/backend/uploadavatar/:id", &controllers.BackendFileController{}, "post:UpdateAvatar")
beego.Router("/backend/batchdeletefiles", &controllers.BackendFileController{}, "post:BatchDeleteFiles")
beego.Router("/backend/batchDeleteFilesPermanently", &controllers.BackendFileController{}, "post:BatchDeleteFilesPermanently")
beego.Router("/backend/batchMoveFiles", &controllers.BackendFileController{}, "post:BatchMoveFiles")
// 模块接口
beego.Router("/backend/modules/getTenantList", &controllers.BackendModulesController{}, "get:GetTenantList")
// 用户接口
beego.Router("/backend/getTenantUsers/:tid", &controllers.BackendAdminUserController{}, "get:GetTenantUsers")
beego.Router("/backend/getAllUsers", &controllers.BackendAdminUserController{}, "get:GetAllUsers")
beego.Router("/backend/getUserInfo/:id", &controllers.BackendAdminUserController{}, "get:GetUserInfo")
beego.Router("/backend/addUser", &controllers.BackendAdminUserController{}, "post:AddUser")
beego.Router("/backend/editUser/:id", &controllers.BackendAdminUserController{}, "post:EditUser")
beego.Router("/backend/deleteUser/:id", &controllers.BackendAdminUserController{}, "delete:DeleteUser")
beego.Router("/backend/changePassword", &controllers.BackendAdminUserController{}, "post:ChangePassword")
// ERP 接口
beego.Router("/backend/erp/getOrganization", &controllers.BackendErpController{}, "get:GetOrganization")
beego.Router("/backend/erp/getOrganizationDetail/:id", &controllers.BackendErpController{}, "get:GetOrganizationDetail")
beego.Router("/backend/erp/createOrganization", &controllers.BackendErpController{}, "post:CreateOrganization")
beego.Router("/backend/erp/editOrganization/:id", &controllers.BackendErpController{}, "post:EditOrganization")
beego.Router("/backend/erp/deleteOrganization/:id", &controllers.BackendErpController{}, "delete:DeleteOrganization")
beego.Router("/backend/erp/getCompanys", &controllers.BackendErpController{}, "get:GetCompanys")
beego.Router("/backend/erp/getDepartments", &controllers.BackendErpController{}, "get:GetDepartments")
beego.Router("/backend/erp/getEmployee", &controllers.BackendErpController{}, "get:GetEmployee")
beego.Router("/backend/erp/getEmployeeDetail/:id", &controllers.BackendErpController{}, "get:GetEmployeeDetail")
beego.Router("/backend/erp/createEmployee", &controllers.BackendErpController{}, "post:CreateEmployee")
beego.Router("/backend/erp/editEmployee/:id", &controllers.BackendErpController{}, "post:EditEmployee")
beego.Router("/backend/erp/deleteEmployee/:id", &controllers.BackendErpController{}, "delete:DeleteEmployee")
beego.Router("/backend/erp/getPosition", &controllers.BackendErpController{}, "get:GetPosition")
beego.Router("/backend/erp/getPositionDetail/:id", &controllers.BackendErpController{}, "get:GetPositionDetail")
beego.Router("/backend/erp/createPosition", &controllers.BackendErpController{}, "post:CreatePosition")
beego.Router("/backend/erp/editPosition/:id", &controllers.BackendErpController{}, "post:EditPosition")
beego.Router("/backend/erp/deletePosition/:id", &controllers.BackendErpController{}, "delete:DeletePosition")
// 文章管理
beego.Router("/backend/articlesList", &controllers.BackendArticleController{}, "get:List")
beego.Router("/backend/contentstats", &controllers.BackendArticleController{}, "get:ContentStats")
beego.Router("/backend/allarticles", &controllers.BackendArticleController{}, "get:ListAll")
beego.Router("/backend/articles/:id", &controllers.BackendArticleController{}, "get:Detail")
beego.Router("/backend/createarticle", &controllers.BackendArticleController{}, "post:Create")
beego.Router("/backend/editarticle/:id", &controllers.BackendArticleController{}, "post:Update")
beego.Router("/backend/deletearticle/:id", &controllers.BackendArticleController{}, "delete:Delete")
beego.Router("/backend/publisharticle/:id", &controllers.BackendArticleController{}, "post:Publish")
beego.Router("/backend/unPublisharticle/:id", &controllers.BackendArticleController{}, "post:Unpublish")
beego.Router("/backend/articleRecommend/:id", &controllers.BackendArticleController{}, "post:Recommend")
beego.Router("/backend/unArticleRecommend/:id", &controllers.BackendArticleController{}, "post:Unrecommend")
beego.Router("/backend/articleTop/:id", &controllers.BackendArticleController{}, "post:Top")
beego.Router("/backend/unArticleTop/:id", &controllers.BackendArticleController{}, "post:Untop")
beego.Router("/backend/categories", &controllers.BackendArticleCategoryController{}, "get:List")
beego.Router("/backend/allcategories", &controllers.BackendArticleCategoryController{}, "get:ListAll")
beego.Router("/backend/categories/:id", &controllers.BackendArticleCategoryController{}, "get:Detail;delete:Delete")
beego.Router("/backend/createCategory", &controllers.BackendArticleCategoryController{}, "post:Create")
beego.Router("/backend/editCategory/:id", &controllers.BackendArticleCategoryController{}, "post:Update")
beego.Router("/backend/categories/:id/status", &controllers.BackendArticleCategoryController{}, "patch:UpdateStatus")
// 域名管理(主域名池 / 租户域名)
beego.Router("/backend/domain/pool/index", &controllers.BackendDomainPoolController{}, "get:Index")
beego.Router("/backend/domain/pool/getEnabledDomains", &controllers.BackendDomainPoolController{}, "get:GetEnabledDomains")
beego.Router("/backend/domain/pool/create", &controllers.BackendDomainPoolController{}, "post:Create")
beego.Router("/backend/domain/pool/update", &controllers.BackendDomainPoolController{}, "post:Update")
beego.Router("/backend/domain/pool/delete/:id", &controllers.BackendDomainPoolController{}, "delete:Delete")
beego.Router("/backend/domain/pool/toggleStatus", &controllers.BackendDomainPoolController{}, "post:ToggleStatus")
beego.Router("/backend/domain/tenant/index", &controllers.BackendTenantDomainController{}, "get:Index")
beego.Router("/backend/domain/tenant/myDomains", &controllers.BackendTenantDomainController{}, "get:MyDomains")
beego.Router("/backend/domain/tenant/apply", &controllers.BackendTenantDomainController{}, "post:Apply")
beego.Router("/backend/domain/tenant/audit", &controllers.BackendTenantDomainController{}, "post:Audit")
beego.Router("/backend/domain/tenant/toggleStatus", &controllers.BackendTenantDomainController{}, "post:ToggleStatus")
beego.Router("/backend/domain/tenant/delete/:id", &controllers.BackendTenantDomainController{}, "delete:Delete")
// 记事本管理
beego.Router("/backend/notebook/list", &controllers.BackendNotebookController{}, "get:List")
beego.Router("/backend/notebook/detail/:id", &controllers.BackendNotebookController{}, "get:Detail")
beego.Router("/backend/notebook/create", &controllers.BackendNotebookController{}, "post:Create")
beego.Router("/backend/notebook/update/:id", &controllers.BackendNotebookController{}, "post:Update")
beego.Router("/backend/notebook/delete/:id", &controllers.BackendNotebookController{}, "delete:Delete")
// 日程提醒管理
beego.Router("/backend/reminder/list", &controllers.BackendReminderController{}, "get:GetReminderList")
beego.Router("/backend/reminder/test", &controllers.BackendReminderController{}, "post:TestReminder")
beego.Router("/backend/reminder/:id", &controllers.BackendReminderController{}, "get:GetReminderDetail;put:UpdateReminder;delete:DeleteReminder")
beego.Router("/backend/reminder", &controllers.BackendReminderController{}, "post:CreateReminder")
beego.Router("/backend/reminder/batchDelete", &controllers.BackendReminderController{}, "post:BatchDeleteReminder")
beego.Router("/backend/reminder/finish/:id", &controllers.BackendReminderController{}, "post:FinishReminder")
}
package backend
import (
"server/controllers"
beego "github.com/beego/beego/v2/server/web"
)
// Register 注册租户端(backend)路由。
// 该端不包含平台菜单配置接口。
func Register() {
RegisterAuthRoutes()
}
// RegisterAuthRoutes 注册 backend 认证相关路由。
func RegisterAuthRoutes() {
// 登录、注册与找回密码相关
beego.Router("/backend/login", &controllers.BackendAuthController{}, "post:LoginBackend")
beego.Router("/backend/sendLoginCode", &controllers.BackendAuthController{}, "post:SendLoginCode")
beego.Router("/backend/loginBySms", &controllers.BackendAuthController{}, "post:LoginBySms")
beego.Router("/backend/logout", &controllers.BackendAuthController{}, "post:Logout")
beego.Router("/backend/register", &controllers.BackendAuthController{}, "post:Register")
beego.Router("/backend/sendRegisterCode", &controllers.BackendAuthController{}, "post:SendRegisterCode")
beego.Router("/backend/resetPassword", &controllers.BackendAuthController{}, "post:ResetPassword")
beego.Router("/backend/sendResetCode", &controllers.BackendAuthController{}, "post:SendResetCode")
// 极验与登录验证配置
beego.Router("/backend/login/getGeetest3Infos", &controllers.BackendAuthController{}, "get:GetGeetest3Infos")
beego.Router("/backend/login/getGeetest4Infos", &controllers.BackendAuthController{}, "get:GetGeetest4Infos")
beego.Router("/backend/login/getOpenVerify", &controllers.BackendAuthController{}, "get:GetOpenVerify")
// 菜单接口
beego.Router("/backend/menu/:id", &controllers.BackendMenuController{}, "get:GetBackendMenu")
beego.Router("/backend/allmenu", &controllers.BackendMenuController{}, "get:GetAllBackendMenus")
// 操作日志(yz_system_operation_log
beego.Router("/backend/operationLogs", &controllers.BackendOperationLogController{}, "get:List")
beego.Router("/backend/operationLogs/statistics", &controllers.BackendOperationLogController{}, "get:Statistics")
beego.Router("/backend/operationLogs/:id", &controllers.BackendOperationLogController{}, "get:Detail;delete:Delete")
beego.Router("/backend/operationLogs/batchDelete", &controllers.BackendOperationLogController{}, "post:BatchDelete")
// 租户站点设置
beego.Router("/backend/normalInfos", &controllers.BackendSiteSettingsController{}, "get:GetNormalInfos")
beego.Router("/backend/saveNormalInfos", &controllers.BackendSiteSettingsController{}, "post:SaveNormalInfos")
beego.Router("/backend/legalInfos", &controllers.BackendSiteSettingsController{}, "get:GetLegalInfos")
beego.Router("/backend/saveLegalInfos", &controllers.BackendSiteSettingsController{}, "post:SaveLegalInfos")
beego.Router("/backend/companyInfos", &controllers.BackendSiteSettingsController{}, "get:GetCompanyInfos")
beego.Router("/backend/saveCompanyInfos", &controllers.BackendSiteSettingsController{}, "post:SaveCompanyInfos")
beego.Router("/backend/companySeo", &controllers.BackendSiteSettingsController{}, "get:GetCompanySeo")
beego.Router("/backend/saveCompanySeo", &controllers.BackendSiteSettingsController{}, "post:SaveCompanySeo")
beego.Router("/backend/loginVerifyInfos", &controllers.BackendLoginVerifyController{}, "get:GetLoginVerifyInfos")
beego.Router("/backend/saveloginVerifyInfos", &controllers.BackendLoginVerifyController{}, "post:SaveLoginVerifyInfos")
// 站内信(yz_system_reminderlist
beego.Router("/backend/sitereminder/myList", &controllers.BackendSiteReminderController{}, "get:GetMyList")
beego.Router("/backend/sitereminder/read", &controllers.BackendSiteReminderController{}, "post:MarkRead")
beego.Router("/backend/sitereminder/readall", &controllers.BackendSiteReminderController{}, "post:MarkAllRead")
beego.Router("/backend/sitereminder/delete", &controllers.BackendSiteReminderController{}, "post:Delete")
// 文件管理(yz_system_files / yz_system_files_category
beego.Router("/backend/usercate", &controllers.BackendFileController{}, "get:GetUserCate")
beego.Router("/backend/allfiles", &controllers.BackendFileController{}, "get:GetAllFiles")
beego.Router("/backend/catefiles/:id", &controllers.BackendFileController{}, "get:GetCateFiles")
beego.Router("/backend/file/:id", &controllers.BackendFileController{}, "get:GetFileByID")
beego.Router("/backend/deletefilepermanently/:id", &controllers.BackendFileController{}, "delete:DeleteFilePermanently")
beego.Router("/backend/uploadfile", &controllers.BackendFileController{}, "post:UploadFile")
beego.Router("/backend/uploadfiles", &controllers.BackendFileController{}, "post:UploadFile")
beego.Router("/backend/updatefile/:id", &controllers.BackendFileController{}, "post:UpdateFile")
beego.Router("/backend/deletefile/:id", &controllers.BackendFileController{}, "delete:DeleteFile")
beego.Router("/backend/movefile/:id", &controllers.BackendFileController{}, "get:MoveFile")
beego.Router("/backend/createfilecate", &controllers.BackendFileController{}, "post:CreateFileCate")
beego.Router("/backend/renamefilecate/:id", &controllers.BackendFileController{}, "post:RenameFileCate")
beego.Router("/backend/deletefilecate/:id", &controllers.BackendFileController{}, "delete:DeleteFileCate")
beego.Router("/backend/uploadavatar", &controllers.BackendFileController{}, "post:UploadAvatar")
beego.Router("/backend/uploadavatar/:id", &controllers.BackendFileController{}, "post:UpdateAvatar")
beego.Router("/backend/batchdeletefiles", &controllers.BackendFileController{}, "post:BatchDeleteFiles")
beego.Router("/backend/batchDeleteFilesPermanently", &controllers.BackendFileController{}, "post:BatchDeleteFilesPermanently")
beego.Router("/backend/batchMoveFiles", &controllers.BackendFileController{}, "post:BatchMoveFiles")
// 模块接口
beego.Router("/backend/modules/getTenantList", &controllers.BackendModulesController{}, "get:GetTenantList")
// 用户接口
beego.Router("/backend/getTenantUsers/:tid", &controllers.BackendAdminUserController{}, "get:GetTenantUsers")
beego.Router("/backend/getAllUsers", &controllers.BackendAdminUserController{}, "get:GetAllUsers")
beego.Router("/backend/getUserInfo/:id", &controllers.BackendAdminUserController{}, "get:GetUserInfo")
beego.Router("/backend/addUser", &controllers.BackendAdminUserController{}, "post:AddUser")
beego.Router("/backend/editUser/:id", &controllers.BackendAdminUserController{}, "post:EditUser")
beego.Router("/backend/deleteUser/:id", &controllers.BackendAdminUserController{}, "delete:DeleteUser")
beego.Router("/backend/changePassword", &controllers.BackendAdminUserController{}, "post:ChangePassword")
// ERP 接口
beego.Router("/backend/erp/getOrganization", &controllers.BackendErpController{}, "get:GetOrganization")
beego.Router("/backend/erp/getOrganizationDetail/:id", &controllers.BackendErpController{}, "get:GetOrganizationDetail")
beego.Router("/backend/erp/createOrganization", &controllers.BackendErpController{}, "post:CreateOrganization")
beego.Router("/backend/erp/editOrganization/:id", &controllers.BackendErpController{}, "post:EditOrganization")
beego.Router("/backend/erp/deleteOrganization/:id", &controllers.BackendErpController{}, "delete:DeleteOrganization")
beego.Router("/backend/erp/getCompanys", &controllers.BackendErpController{}, "get:GetCompanys")
beego.Router("/backend/erp/getDepartments", &controllers.BackendErpController{}, "get:GetDepartments")
beego.Router("/backend/erp/getEmployee", &controllers.BackendErpController{}, "get:GetEmployee")
beego.Router("/backend/erp/getEmployeeDetail/:id", &controllers.BackendErpController{}, "get:GetEmployeeDetail")
beego.Router("/backend/erp/createEmployee", &controllers.BackendErpController{}, "post:CreateEmployee")
beego.Router("/backend/erp/editEmployee/:id", &controllers.BackendErpController{}, "post:EditEmployee")
beego.Router("/backend/erp/deleteEmployee/:id", &controllers.BackendErpController{}, "delete:DeleteEmployee")
beego.Router("/backend/erp/getPosition", &controllers.BackendErpController{}, "get:GetPosition")
beego.Router("/backend/erp/getPositionDetail/:id", &controllers.BackendErpController{}, "get:GetPositionDetail")
beego.Router("/backend/erp/createPosition", &controllers.BackendErpController{}, "post:CreatePosition")
beego.Router("/backend/erp/editPosition/:id", &controllers.BackendErpController{}, "post:EditPosition")
beego.Router("/backend/erp/deletePosition/:id", &controllers.BackendErpController{}, "delete:DeletePosition")
// 文章管理
beego.Router("/backend/articlesList", &controllers.BackendArticleController{}, "get:List")
beego.Router("/backend/contentstats", &controllers.BackendArticleController{}, "get:ContentStats")
beego.Router("/backend/allarticles", &controllers.BackendArticleController{}, "get:ListAll")
beego.Router("/backend/articles/:id", &controllers.BackendArticleController{}, "get:Detail")
beego.Router("/backend/createarticle", &controllers.BackendArticleController{}, "post:Create")
beego.Router("/backend/editarticle/:id", &controllers.BackendArticleController{}, "post:Update")
beego.Router("/backend/deletearticle/:id", &controllers.BackendArticleController{}, "delete:Delete")
beego.Router("/backend/publisharticle/:id", &controllers.BackendArticleController{}, "post:Publish")
beego.Router("/backend/unPublisharticle/:id", &controllers.BackendArticleController{}, "post:Unpublish")
beego.Router("/backend/articleRecommend/:id", &controllers.BackendArticleController{}, "post:Recommend")
beego.Router("/backend/unArticleRecommend/:id", &controllers.BackendArticleController{}, "post:Unrecommend")
beego.Router("/backend/articleTop/:id", &controllers.BackendArticleController{}, "post:Top")
beego.Router("/backend/unArticleTop/:id", &controllers.BackendArticleController{}, "post:Untop")
beego.Router("/backend/categories", &controllers.BackendArticleCategoryController{}, "get:List")
beego.Router("/backend/allcategories", &controllers.BackendArticleCategoryController{}, "get:ListAll")
beego.Router("/backend/categories/:id", &controllers.BackendArticleCategoryController{}, "get:Detail;delete:Delete")
beego.Router("/backend/createCategory", &controllers.BackendArticleCategoryController{}, "post:Create")
beego.Router("/backend/editCategory/:id", &controllers.BackendArticleCategoryController{}, "post:Update")
beego.Router("/backend/categories/:id/status", &controllers.BackendArticleCategoryController{}, "patch:UpdateStatus")
// 域名管理(主域名池 / 租户域名)
beego.Router("/backend/domain/pool/index", &controllers.BackendDomainPoolController{}, "get:Index")
beego.Router("/backend/domain/pool/getEnabledDomains", &controllers.BackendDomainPoolController{}, "get:GetEnabledDomains")
beego.Router("/backend/domain/pool/create", &controllers.BackendDomainPoolController{}, "post:Create")
beego.Router("/backend/domain/pool/update", &controllers.BackendDomainPoolController{}, "post:Update")
beego.Router("/backend/domain/pool/delete/:id", &controllers.BackendDomainPoolController{}, "delete:Delete")
beego.Router("/backend/domain/pool/toggleStatus", &controllers.BackendDomainPoolController{}, "post:ToggleStatus")
beego.Router("/backend/domain/tenant/index", &controllers.BackendTenantDomainController{}, "get:Index")
beego.Router("/backend/domain/tenant/myDomains", &controllers.BackendTenantDomainController{}, "get:MyDomains")
beego.Router("/backend/domain/tenant/apply", &controllers.BackendTenantDomainController{}, "post:Apply")
beego.Router("/backend/domain/tenant/audit", &controllers.BackendTenantDomainController{}, "post:Audit")
beego.Router("/backend/domain/tenant/toggleStatus", &controllers.BackendTenantDomainController{}, "post:ToggleStatus")
beego.Router("/backend/domain/tenant/delete/:id", &controllers.BackendTenantDomainController{}, "delete:Delete")
// 记事本管理
beego.Router("/backend/notebook/list", &controllers.BackendNotebookController{}, "get:List")
beego.Router("/backend/notebook/detail/:id", &controllers.BackendNotebookController{}, "get:Detail")
beego.Router("/backend/notebook/create", &controllers.BackendNotebookController{}, "post:Create")
beego.Router("/backend/notebook/update/:id", &controllers.BackendNotebookController{}, "post:Update")
beego.Router("/backend/notebook/delete/:id", &controllers.BackendNotebookController{}, "delete:Delete")
// 报销与审批管理
beego.Router("/backend/reimbursements", &controllers.BackendReimburseController{}, "get:List;post:Create")
beego.Router("/backend/reimbursements/types", &controllers.BackendReimburseController{}, "get:Types")
beego.Router("/backend/reimbursements/flows", &controllers.BackendReimburseController{}, "get:Flows")
beego.Router("/backend/reimbursements/:id/items", &controllers.BackendReimburseController{}, "post:AddItem")
beego.Router("/backend/reimbursements/:id/items/:item_id", &controllers.BackendReimburseController{}, "post:UpdateItem;delete:DeleteItem")
beego.Router("/backend/reimbursements/:id", &controllers.BackendReimburseController{}, "get:Detail;post:Update;delete:Delete")
beego.Router("/backend/reimbursements/:id/submit", &controllers.BackendReimburseController{}, "post:Submit")
beego.Router("/backend/reimbursements/:id/records", &controllers.BackendReimburseController{}, "get:Records")
// 日程提醒管理
beego.Router("/backend/reminder/list", &controllers.BackendReminderController{}, "get:GetReminderList")
beego.Router("/backend/reminder/test", &controllers.BackendReminderController{}, "post:TestReminder")
beego.Router("/backend/reminder/:id", &controllers.BackendReminderController{}, "get:GetReminderDetail;put:UpdateReminder;delete:DeleteReminder")
beego.Router("/backend/reminder", &controllers.BackendReminderController{}, "post:CreateReminder")
beego.Router("/backend/reminder/batchDelete", &controllers.BackendReminderController{}, "post:BatchDeleteReminder")
beego.Router("/backend/reminder/finish/:id", &controllers.BackendReminderController{}, "post:FinishReminder")
}