更新代码

This commit is contained in:
2026-09-15 10:44:31 +08:00
parent 9875832019
commit 943c3708b0
125 changed files with 2009 additions and 1728 deletions
+2 -5
View File
@@ -400,15 +400,12 @@ func (c *BackendAdminUserController) AddUser() {
// 关联角色(group_id):0 表示未分配,前端展示为"未分配/全权限"
if p.GroupID != nil && *p.GroupID > 0 {
models.EnsureTenantUserGroupColumn()
_, _ = models.Orm.QueryTable(new(models.SystemTenantUser)).
Filter("id", id).
Update(map[string]interface{}{"group_id": *p.GroupID})
} else if isDefault == 1 {
// 租户第一个账号(普通租户)即租户管理员:自动绑定「租户管理员」角色,
// 使"普通租户"与"租户管理员"合二为一(均可登录 backend 并拥有全权限)。
if adminRoleID, err := models.GetTenantAdminRole(p.Tid); err == nil && adminRoleID > 0 {
models.EnsureTenantUserGroupColumn()
// 租户的第一个账号即租户管理员:自动绑定全局「租户管理员」角色(拥有 backend 全权限)。
if adminRoleID, err := models.GetTenantAdminRole(); err == nil && adminRoleID > 0 {
_, _ = models.Orm.QueryTable(new(models.SystemTenantUser)).
Filter("id", id).
Update(map[string]interface{}{"group_id": adminRoleID})
-58
View File
@@ -81,16 +81,6 @@ func (c *BackendArticleCategoryController) cmsJSONErr(httpStatus, bizCode int, m
_ = c.ServeJSON()
}
func cmsEnsureTables(c *beego.Controller) bool {
if err := models.EnsureCmsArticleTables(); err != nil {
c.Ctx.Output.SetStatus(500)
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "初始化文章表失败: " + err.Error()}
_ = c.ServeJSON()
return false
}
return true
}
func cmsPortalTid(c *beego.Controller) uint64 {
if tid, err := c.GetUint64("tid"); err == nil && tid > 0 {
return tid
@@ -179,9 +169,6 @@ func cmsCategoryToMap(row models.CmsArticleCategory) map[string]interface{} {
// ContentStats GET /backend/contentstats
func (c *BackendArticleController) ContentStats() {
if !cmsEnsureTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -261,9 +248,6 @@ func (c *BackendArticleController) ContentStats() {
// List GET /backend/articlesList
func (c *BackendArticleController) List() {
if !cmsEnsureTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -348,9 +332,6 @@ func (c *BackendArticleController) ListAll() {
// Detail GET /backend/articles/:id
func (c *BackendArticleController) Detail() {
if !cmsEnsureTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -407,9 +388,6 @@ type cmsArticlePayload struct {
// Create POST /backend/createarticle
func (c *BackendArticleController) Create() {
if !cmsEnsureTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -479,9 +457,6 @@ func (c *BackendArticleController) Create() {
// Update POST /backend/editarticle/:id
func (c *BackendArticleController) Update() {
if !cmsEnsureTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -538,9 +513,6 @@ func (c *BackendArticleController) Update() {
// Delete DELETE /backend/deletearticle/:id
func (c *BackendArticleController) Delete() {
if !cmsEnsureTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -573,9 +545,6 @@ func (c *BackendArticleController) Delete() {
}
func (c *BackendArticleController) setArticleFlag(field string, value int8) {
if !cmsEnsureTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -609,9 +578,6 @@ func (c *BackendArticleController) setArticleFlag(field string, value int8) {
}
func (c *BackendArticleController) Publish() {
if !cmsEnsureTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -663,9 +629,6 @@ func (c *BackendArticleController) Publish() {
}
func (c *BackendArticleController) Unpublish() {
if !cmsEnsureTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -704,9 +667,6 @@ func (c *BackendArticleController) Untop() { c.setArticleFlag("top", 0) }
// List GET /backend/categories
func (c *BackendArticleCategoryController) List() {
if !cmsEnsureTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -763,9 +723,6 @@ func (c *BackendArticleCategoryController) List() {
// ListAll GET /backend/allcategories
func (c *BackendArticleCategoryController) ListAll() {
if !cmsEnsureTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -804,9 +761,6 @@ func (c *BackendArticleCategoryController) ListAll() {
// Detail GET /backend/categories/:id
func (c *BackendArticleCategoryController) Detail() {
if !cmsEnsureTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -850,9 +804,6 @@ type cmsCategoryPayload struct {
// Create POST /backend/createCategory
func (c *BackendArticleCategoryController) Create() {
if !cmsEnsureTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -904,9 +855,6 @@ func (c *BackendArticleCategoryController) Create() {
// Update POST /backend/editCategory/:id
func (c *BackendArticleCategoryController) Update() {
if !cmsEnsureTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -973,9 +921,6 @@ func (c *BackendArticleCategoryController) Update() {
// Delete DELETE /backend/categories/:id
func (c *BackendArticleCategoryController) Delete() {
if !cmsEnsureTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -1042,9 +987,6 @@ func (c *BackendArticleCategoryController) Delete() {
// UpdateStatus PATCH /backend/categories/:id/status
func (c *BackendArticleCategoryController) UpdateStatus() {
if !cmsEnsureTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -68,6 +68,7 @@ func crmIsSystemCategory(row *models.TenantCrmProductCategory) bool {
}
// crmEnsureDefaultProductCategories 确保租户存在系统默认分类(未分类 / 软件开发 / 软件产品 / 硬件产品):
// 【租户级初始化】新租户首次使用时补建默认业务数据(非表结构/全局预置数据;结构变更须走 docs/sql/ SQL 文件)。
// - 不存在(含曾被软删除)时创建 / 恢复,保证其始终可用(复用软删记录,避免唯一键冲突);
// - 已存在同名分类(租户此前自建)时升级为系统默认,并修复默认标记、状态与内置排序(历史数据升级自修复)。
func crmEnsureDefaultProductCategories(tenantID string) {
+1
View File
@@ -62,6 +62,7 @@ var crmDefaultUnits = []struct {
}
// crmEnsureDefaultUnits 租户首次使用(从未有过任何单位记录,含已软删除的)时写入默认单位。
// 【租户级初始化】新租户首次使用时补建默认业务数据(非表结构/全局预置数据;结构变更须走 docs/sql/ SQL 文件)。
// 用户手动清空后不再自动补,避免越删越有;需要恢复时用「恢复默认单位」接口。
// 已有记录时顺带修复存量默认单位的 is_default 标记(历史数据升级)。
func crmEnsureDefaultUnits(tenantID string) {
-5
View File
@@ -79,11 +79,6 @@ func (c *BackendFileController) effectiveTid(claims *jwtutil.Claims) uint64 {
return 0
}
// Prepare 所有接口执行前补齐文件存储分层所需字段,避免历史库缺列导致查询/写入报错
func (c *BackendFileController) Prepare() {
models.EnsureSystemFileStorageColumns()
}
// resolveTuid 解析归属用户 ID,返回 0 表示租户共享文件。
//
// 取值顺序:
-3
View File
@@ -77,9 +77,6 @@ func (c *BackendMenuController) GetMenu() {
}
func (c *BackendMenuController) GetBackendMenu() {
// 确保租户用户 group_id 列存在(老库兼容)
models.EnsureTenantUserGroupColumn()
var menus []models.SystemMenu
_, err := models.Orm.QueryTable(new(models.SystemMenu)).Filter("status", 1).All(&menus)
if err != nil {
-3
View File
@@ -49,9 +49,6 @@ func (c *BackendMenuFrontController) List() {
return
}
// 保证全局默认导航(tenant_id=0)齐全,缺失自动补齐
models.EnsureGlobalDefaultFrontMenus()
// 全局默认菜单(tenant_id=0,不可删改)+ 租户自定义菜单
var menus []models.BackendMenuFront
_, err := models.Orm.QueryTable("yz_backend_menu_front").
-6
View File
@@ -7,7 +7,6 @@ import (
"strconv"
"strings"
"server/models"
"server/pkg/jwtutil"
"server/services"
@@ -27,11 +26,6 @@ type BackendOaDocumentController struct {
beego.Controller
}
// Prepare 所有接口执行前确保文档相关表存在。
func (c *BackendOaDocumentController) Prepare() {
_ = models.EnsureOaDocumentTables()
}
func (c *BackendOaDocumentController) oaDocClaims() (*jwtutil.Claims, error) {
auth := c.Ctx.Request.Header.Get("Authorization")
if auth == "" {
-5
View File
@@ -21,11 +21,6 @@ type BackendOaNoticeController struct {
beego.Controller
}
// Prepare 所有接口执行前确保通知公告表存在。
func (c *BackendOaNoticeController) Prepare() {
_ = models.EnsureOaNoticeTable()
}
func (c *BackendOaNoticeController) oaNoticeClaims() (*jwtutil.Claims, error) {
auth := c.Ctx.Request.Header.Get("Authorization")
if auth == "" {
-5
View File
@@ -53,11 +53,6 @@ func (c *BackendOaScheduleController) oasOk(data interface{}) {
_ = c.ServeJSON()
}
// Prepare 所有日程接口执行前补齐顺延所需字段,避免历史库缺列导致查询报错。
func (c *BackendOaScheduleController) Prepare() {
_ = models.EnsureOaScheduleCarryColumns()
}
var (
oasDatePattern = regexp.MustCompile(`^\d{4}-\d{2}-\d{2}$`)
oasTimePattern = regexp.MustCompile(`^\d{2}:\d{2}$`)
-34
View File
@@ -43,16 +43,6 @@ func (c *BackendProductCategoryController) cmsJSONErr(httpStatus, bizCode int, m
_ = c.ServeJSON()
}
func cmsEnsureProductTables(c *beego.Controller) bool {
if err := models.EnsureCmsProductTables(); err != nil {
c.Ctx.Output.SetStatus(500)
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "初始化产品表失败: " + err.Error()}
_ = c.ServeJSON()
return false
}
return true
}
func cmsProductToMap(row models.CmsProduct) map[string]interface{} {
return map[string]interface{}{
"id": row.ID,
@@ -85,9 +75,6 @@ func cmsProductCateToMap(row models.CmsProductCategory) map[string]interface{} {
// List GET /backend/productsList
func (c *BackendProductController) List() {
if !cmsEnsureProductTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -153,9 +140,6 @@ type cmsProductPayload struct {
// Create POST /backend/addProducts
func (c *BackendProductController) Create() {
if !cmsEnsureProductTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -208,9 +192,6 @@ func (c *BackendProductController) Create() {
// Update PUT /backend/editProducts/:id
func (c *BackendProductController) Update() {
if !cmsEnsureProductTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -269,9 +250,6 @@ func (c *BackendProductController) Update() {
// Delete DELETE /backend/deleteProducts/:id
func (c *BackendProductController) Delete() {
if !cmsEnsureProductTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -305,9 +283,6 @@ func (c *BackendProductController) Delete() {
// List GET /backend/productsTypesList
func (c *BackendProductCategoryController) List() {
if !cmsEnsureProductTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -367,9 +342,6 @@ type cmsProductCategoryPayload struct {
// Create POST /backend/addProductsTypes
func (c *BackendProductCategoryController) Create() {
if !cmsEnsureProductTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -420,9 +392,6 @@ func (c *BackendProductCategoryController) Create() {
// Update PUT /backend/editProductsTypes/:id
func (c *BackendProductCategoryController) Update() {
if !cmsEnsureProductTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -482,9 +451,6 @@ func (c *BackendProductCategoryController) Update() {
// Delete DELETE /backend/deleteProductsTypes/:id
func (c *BackendProductCategoryController) Delete() {
if !cmsEnsureProductTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
+64 -7
View File
@@ -145,21 +145,20 @@ func (c *BackendRoleController) currentTenantID() (uint64, bool) {
return uint64(claims.TenantId), true
}
// GetAllRoles 获取当前租户的角色列表
// GetAllRoles 获取当前租户可见的角色列表
// GET /backend/allRoles
// 返回「全局角色(cid=2, tenant_id=0,所有租户共用)」+「本租户自建角色」;
// 全局角色由平台端统一维护,租户端只读。
func (c *BackendRoleController) GetAllRoles() {
tid, ok := c.currentTenantID()
if !ok {
return
}
// 懒加载补齐当前租户的默认角色(租户管理员/部门负责人/员工)
models.EnsureDefaultTenantRoles(tid)
var rows []models.AdminRole
_, err := models.Orm.QueryTable(new(models.AdminRole)).
Filter("cid", 2).
Filter("tenant_id", tid).
OrderBy("-id").
Filter("tenant_id__in", []uint64{0, tid}).
OrderBy("tenant_id", "is_custom", "id").
All(&rows)
if err != nil {
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "查询失败"}
@@ -188,7 +187,7 @@ func (c *BackendRoleController) GetRoleByID() {
if err := models.Orm.QueryTable(new(models.AdminRole)).
Filter("id", id).
Filter("cid", 2).
Filter("tenant_id", tid).
Filter("tenant_id__in", []uint64{0, tid}).
One(&role); err != nil {
c.Data["json"] = map[string]interface{}{"code": 404, "msg": "角色不存在"}
_ = c.ServeJSON()
@@ -218,6 +217,22 @@ func (c *BackendRoleController) CreateRole() {
_ = c.ServeJSON()
return
}
// 不能与本租户可见的角色重名(含平台默认的全局角色),避免混淆
dup, derr := models.Orm.QueryTable(new(models.AdminRole)).
Filter("cid", 2).
Filter("tenant_id__in", []uint64{0, tid}).
Filter("name", p.Name).
Count()
if derr != nil {
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "创建失败"}
_ = c.ServeJSON()
return
}
if dup > 0 {
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "已存在同名角色(含平台默认角色),请更换名称"}
_ = c.ServeJSON()
return
}
status := uint8(1)
if p.Status != nil {
@@ -282,6 +297,37 @@ func (c *BackendRoleController) UpdateRole() {
return
}
// 全局角色(tenant_id=0)由平台端统一维护,租户端只读
var target models.AdminRole
if e := models.Orm.QueryTable(new(models.AdminRole)).
Filter("id", id).
Filter("cid", 2).
One(&target); e == nil && target.TenantID == 0 {
c.Data["json"] = map[string]interface{}{"code": 403, "msg": "全局角色由平台端统一维护,租户端不能修改"}
_ = c.ServeJSON()
return
}
// 改名时不能与可见角色重名(含平台默认的全局角色,排除自身)
if newName, ok := update["name"]; ok {
dup, derr := models.Orm.QueryTable(new(models.AdminRole)).
Filter("cid", 2).
Filter("tenant_id__in", []uint64{0, tid}).
Filter("name", newName).
Exclude("id", id).
Count()
if derr != nil {
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "更新失败"}
_ = c.ServeJSON()
return
}
if dup > 0 {
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "已存在同名角色(含平台默认角色),请更换名称"}
_ = c.ServeJSON()
return
}
}
// 仅允许更新本租户名下的角色,防止越权改到其他租户
cnt, err := models.Orm.QueryTable(new(models.AdminRole)).
Filter("id", id).
@@ -316,6 +362,17 @@ func (c *BackendRoleController) DeleteRole() {
_ = c.ServeJSON()
return
}
// 全局角色(tenant_id=0)由平台端统一维护,租户端不能删除
var target models.AdminRole
if e := models.Orm.QueryTable(new(models.AdminRole)).
Filter("id", id).
Filter("cid", 2).
One(&target); e == nil && target.TenantID == 0 {
c.Data["json"] = map[string]interface{}{"code": 403, "msg": "全局角色由平台端统一维护,租户端不能删除"}
_ = c.ServeJSON()
return
}
// 仅允许删除本租户名下的角色
cnt, err := models.Orm.QueryTable(new(models.AdminRole)).
Filter("id", id).
-26
View File
@@ -311,35 +311,12 @@ func (c *BackendSiteSettingsController) resolveBackendTenantID(claims *jwtutil.C
return tid
}
func (c *BackendSiteSettingsController) ensureBackendSettingItemsTable() error {
_, err := models.Orm.Raw(`
CREATE TABLE IF NOT EXISTS yz_system_tenant_setting_items (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
tid BIGINT UNSIGNED NOT NULL DEFAULT 0,
setting_key VARCHAR(64) NOT NULL DEFAULT '',
setting_value LONGTEXT NULL,
create_time DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
delete_time DATETIME NULL DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_tid_key (tid, setting_key),
KEY idx_tid (tid),
KEY idx_delete_time (delete_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='租户站点扩展设置';
`).Exec()
return err
}
func (c *BackendSiteSettingsController) getBackendSettingItems(tid uint64, keys []string) (map[string]string, error) {
out := make(map[string]string, len(keys))
for _, key := range keys {
out[key] = ""
}
if err := c.ensureBackendSettingItemsTable(); err != nil {
return out, err
}
type rowItem struct {
SettingKey string
SettingValue string
@@ -360,9 +337,6 @@ func (c *BackendSiteSettingsController) getBackendSettingItems(tid uint64, keys
}
func (c *BackendSiteSettingsController) saveBackendSettingItems(tid uint64, values map[string]string) error {
if err := c.ensureBackendSettingItemsTable(); err != nil {
return err
}
for key, value := range values {
_, err := models.Orm.Raw(`
INSERT INTO yz_system_tenant_setting_items (tid, setting_key, setting_value, create_time, update_time)
-34
View File
@@ -43,16 +43,6 @@ func (c *BackendSolutionCategoryController) cmsJSONErr(httpStatus, bizCode int,
_ = c.ServeJSON()
}
func cmsEnsureSolutionTables(c *beego.Controller) bool {
if err := models.EnsureCmsSolutionTables(); err != nil {
c.Ctx.Output.SetStatus(500)
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "初始化解决方案表失败: " + err.Error()}
_ = c.ServeJSON()
return false
}
return true
}
func cmsSolutionToMap(row models.CmsSolution) map[string]interface{} {
return map[string]interface{}{
"id": row.ID,
@@ -85,9 +75,6 @@ func cmsSolutionCateToMap(row models.CmsSolutionCategory) map[string]interface{}
// List GET /backend/servicesList
func (c *BackendSolutionController) List() {
if !cmsEnsureSolutionTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -153,9 +140,6 @@ type cmsSolutionPayload struct {
// Create POST /backend/addServices
func (c *BackendSolutionController) Create() {
if !cmsEnsureSolutionTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -208,9 +192,6 @@ func (c *BackendSolutionController) Create() {
// Update PUT /backend/editServices/:id
func (c *BackendSolutionController) Update() {
if !cmsEnsureSolutionTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -269,9 +250,6 @@ func (c *BackendSolutionController) Update() {
// Delete DELETE /backend/deleteServices/:id
func (c *BackendSolutionController) Delete() {
if !cmsEnsureSolutionTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -305,9 +283,6 @@ func (c *BackendSolutionController) Delete() {
// List GET /backend/servicesTypesList
func (c *BackendSolutionCategoryController) List() {
if !cmsEnsureSolutionTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -367,9 +342,6 @@ type cmsSolutionCategoryPayload struct {
// Create POST /backend/addServicesTypes
func (c *BackendSolutionCategoryController) Create() {
if !cmsEnsureSolutionTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -420,9 +392,6 @@ func (c *BackendSolutionCategoryController) Create() {
// Update PUT /backend/editServicesTypes/:id
func (c *BackendSolutionCategoryController) Update() {
if !cmsEnsureSolutionTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
@@ -482,9 +451,6 @@ func (c *BackendSolutionCategoryController) Update() {
// Delete DELETE /backend/deleteServicesTypes/:id
func (c *BackendSolutionCategoryController) Delete() {
if !cmsEnsureSolutionTables(&c.Controller) {
return
}
claims, err := c.cmsClaims()
if err != nil {
c.cmsJSONErr(401, 401, err.Error())
-7
View File
@@ -265,7 +265,6 @@ func (c *IndexPortalController) GetFooterData() {
// GetNewsCenterTop4 GET /index/newscentertop4
func (c *IndexPortalController) GetNewsCenterTop4() {
tid := c.getTidByHost()
_ = models.EnsureCmsArticleTables()
var articles []models.CmsArticle
_, err := models.Orm.QueryTable(new(models.CmsArticle)).
@@ -293,7 +292,6 @@ func (c *IndexPortalController) GetNewsCenterTop4() {
// queryCmsArticles 统一的分页查询文章辅助方法
func (c *IndexPortalController) queryCmsArticles(categoryName string, categoryID int64) {
tid := c.getTidByHost()
_ = models.EnsureCmsArticleTables()
defaultLimit := templateNewsRow(tid)
@@ -366,7 +364,6 @@ func (c *IndexPortalController) GetTechnologyCenter() {
// GetTechnologyCategories GET /index/technologyCategories
func (c *IndexPortalController) GetTechnologyCategories() {
tid := c.getTidByHost()
_ = models.EnsureCmsArticleTables()
var categories []models.CmsArticleCategory
_, err := models.Orm.QueryTable(new(models.CmsArticleCategory)).
@@ -405,7 +402,6 @@ func (c *IndexPortalController) getArticleDetail() {
idStr := c.Ctx.Input.Param(":id")
id, _ := strconv.ParseUint(idStr, 10, 64)
tid := c.getTidByHost()
_ = models.EnsureCmsArticleTables()
var article models.CmsArticle
err := models.Orm.QueryTable(new(models.CmsArticle)).
@@ -433,7 +429,6 @@ func (c *IndexPortalController) AddLike() {
idStr := c.Ctx.Input.Param(":id")
id, _ := strconv.ParseUint(idStr, 10, 64)
tid := c.getTidByHost()
_ = models.EnsureCmsArticleTables()
_, _ = models.Orm.QueryTable(new(models.CmsArticle)).
Filter("id", id).
@@ -451,7 +446,6 @@ func (c *IndexPortalController) ReduceLike() {
idStr := c.Ctx.Input.Param(":id")
id, _ := strconv.ParseUint(idStr, 10, 64)
tid := c.getTidByHost()
_ = models.EnsureCmsArticleTables()
_, _ = models.Orm.QueryTable(new(models.CmsArticle)).
Filter("id", id).
@@ -470,7 +464,6 @@ func (c *IndexPortalController) AddViews() {
idStr := c.Ctx.Input.Param(":id")
id, _ := strconv.ParseUint(idStr, 10, 64)
tid := c.getTidByHost()
_ = models.EnsureCmsArticleTables()
_, _ = models.Orm.QueryTable(new(models.CmsArticle)).
Filter("id", id).
-5
View File
@@ -78,11 +78,6 @@ func (c *PlatformFileController) effectiveTid(claims *jwtutil.Claims) uint64 {
return 0
}
// Prepare 所有接口执行前补齐文件存储分层所需字段,避免历史库缺列导致查询/写入报错
func (c *PlatformFileController) Prepare() {
models.EnsureSystemFileStorageColumns()
}
func (c *PlatformFileController) jsonErr(httpStatus, bizCode int, msg string) {
c.Ctx.Output.SetStatus(httpStatus)
c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg}
+41 -13
View File
@@ -36,6 +36,30 @@ func (c *PlatformSiteReminderController) platformClaims() (*jwtutil.Claims, erro
return claims, nil
}
// mergeReminderTargetIDs 合并多选目标ID与旧版单值入参。
// 旧版:role → target_role_id,tenant → target_tenant_id;多选参数优先。
func mergeReminderTargetIDs(targetType string, targetIDs []uint64, legacyRoleID, legacyTenantID uint64) []uint64 {
ids := make([]uint64, 0, len(targetIDs)+1)
for _, id := range targetIDs {
if id > 0 {
ids = append(ids, id)
}
}
if len(ids) == 0 {
switch targetType {
case "role":
if legacyRoleID > 0 {
ids = append(ids, legacyRoleID)
}
case "tenant":
if legacyTenantID > 0 {
ids = append(ids, legacyTenantID)
}
}
}
return ids
}
func (c *PlatformSiteReminderController) jsonErr(httpStatus, bizCode int, msg string) {
c.Ctx.Output.SetStatus(httpStatus)
c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg}
@@ -97,11 +121,12 @@ func (c *PlatformSiteReminderController) Send() {
return
}
var p struct {
Title string `json:"title"`
Content string `json:"content"`
TargetType string `json:"target_type"` // platform, tenant_all, role, tenant
TargetRoleID uint64 `json:"target_role_id"`
TargetTenantID uint64 `json:"target_tenant_id"`
Title string `json:"title"`
Content string `json:"content"`
TargetType string `json:"target_type"` // all, platform, tenant_all, tenant_role, tenant, tenant_user
TargetIDs []uint64 `json:"target_ids"`
TargetRoleID uint64 `json:"target_role_id"` // 兼容旧入参
TargetTenantID uint64 `json:"target_tenant_id"` // 兼容旧入参
}
if err := json.Unmarshal(raw, &p); err != nil {
c.jsonErr(400, 400, "参数错误")
@@ -118,7 +143,8 @@ func (c *PlatformSiteReminderController) Send() {
return
}
err = services.SendSiteReminder(p.Title, p.Content, uint64(claims.UserID), "platform", p.TargetType, p.TargetRoleID, p.TargetTenantID)
targetIDs := mergeReminderTargetIDs(p.TargetType, p.TargetIDs, p.TargetRoleID, p.TargetTenantID)
err = services.SendSiteReminder(p.Title, p.Content, uint64(claims.UserID), "platform", p.TargetType, targetIDs)
if err != nil {
c.jsonErr(500, 500, "发送失败: "+err.Error())
return
@@ -275,12 +301,13 @@ func (c *PlatformSiteReminderController) UpdateSent() {
return
}
var p struct {
BatchID string `json:"batch_id"`
Title string `json:"title"`
Content string `json:"content"`
TargetType string `json:"target_type"`
TargetRoleID uint64 `json:"target_role_id"`
TargetTenantID uint64 `json:"target_tenant_id"`
BatchID string `json:"batch_id"`
Title string `json:"title"`
Content string `json:"content"`
TargetType string `json:"target_type"` // all, platform, tenant_all, tenant_role, tenant, tenant_user
TargetIDs []uint64 `json:"target_ids"`
TargetRoleID uint64 `json:"target_role_id"` // 兼容旧入参
TargetTenantID uint64 `json:"target_tenant_id"` // 兼容旧入参
}
if err := json.Unmarshal(raw, &p); err != nil {
c.jsonErr(400, 400, "参数错误")
@@ -297,7 +324,8 @@ func (c *PlatformSiteReminderController) UpdateSent() {
return
}
err = services.UpdateSentReminder(p.BatchID, p.Title, p.Content, p.TargetType, p.TargetRoleID, p.TargetTenantID)
targetIDs := mergeReminderTargetIDs(p.TargetType, p.TargetIDs, p.TargetRoleID, p.TargetTenantID)
err = services.UpdateSentReminder(p.BatchID, p.Title, p.Content, p.TargetType, targetIDs)
if err != nil {
c.jsonErr(500, 500, "修改失败: "+err.Error())
return
+2 -4
View File
@@ -208,10 +208,8 @@ func (c *PlatformTenantUserController) CreateTenantUser() {
}
if isDefault == 1 {
_ = services.SetDefaultTenant(p.Uid, p.Tid)
// 租户第一个账号(普通租户)即租户管理员:自动绑定「租户管理员」角色,
// 使"普通租户"与"租户管理员"合二为一(均可登录 backend 并拥有全权限)。
if adminRoleID, err := models.GetTenantAdminRole(p.Tid); err == nil && adminRoleID > 0 {
models.EnsureTenantUserGroupColumn()
// 租户的第一个账号即租户管理员:自动绑定全局「租户管理员」角色(拥有 backend 全权限)。
if adminRoleID, err := models.GetTenantAdminRole(); err == nil && adminRoleID > 0 {
_, _ = models.Orm.QueryTable(new(models.SystemTenantUser)).
Filter("id", id).
Update(map[string]interface{}{"group_id": adminRoleID})