更新操作日志和登录日志的数据隔离
This commit is contained in:
@@ -46,7 +46,7 @@
|
||||
</div>
|
||||
|
||||
<el-table :data="pagedRows" v-loading="loading" stripe>
|
||||
<el-table-column prop="id" label="ID" width="70" align="center" />
|
||||
<!--<el-table-column prop="id" label="ID" width="70" align="center" />-->
|
||||
<el-table-column prop="position_code" label="职位编码" width="150" />
|
||||
<el-table-column prop="position_name" label="职位名称" min-width="140" />
|
||||
<el-table-column label="所属部门" min-width="150">
|
||||
|
||||
@@ -58,6 +58,15 @@
|
||||
<el-form-item label="企业名称" prop="companyname">
|
||||
<el-input v-model="companyname" placeholder="请输入企业名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="企业简称" prop="company_short_name">
|
||||
<el-input v-model="companyShortName" placeholder="请输入企业简称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="企业英文名称" prop="company_english_name">
|
||||
<el-input v-model="companyEnglishName" placeholder="请输入企业英文名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="企业英文简称" prop="company_english_short_name">
|
||||
<el-input v-model="companyEnglishShortName" placeholder="请输入企业英文简称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="企业介绍" prop="companyintroduction">
|
||||
<el-input v-model="companyintroduction" type="textarea" rows="5" placeholder="请输入企业介绍" />
|
||||
</el-form-item>
|
||||
@@ -95,6 +104,9 @@ const normalFormRef = ref<FormInstance>();
|
||||
|
||||
const sitename = ref("");
|
||||
const companyname = ref("");
|
||||
const companyShortName = ref("");
|
||||
const companyEnglishName = ref("");
|
||||
const companyEnglishShortName = ref("");
|
||||
const companyintroduction = ref("");
|
||||
const logo = ref("");
|
||||
const logow = ref("");
|
||||
@@ -106,6 +118,9 @@ const ico = ref("");
|
||||
const formData = {
|
||||
sitename,
|
||||
companyname,
|
||||
companyShortName,
|
||||
companyEnglishName,
|
||||
companyEnglishShortName,
|
||||
companyintroduction,
|
||||
logo,
|
||||
logow,
|
||||
@@ -145,6 +160,9 @@ const initNormalInfos = async () => {
|
||||
copyright.value = data.copyright || "";
|
||||
icp.value = data.icp || "";
|
||||
companyname.value = data.companyname || "";
|
||||
companyShortName.value = data.company_short_name || "";
|
||||
companyEnglishName.value = data.company_english_name || "";
|
||||
companyEnglishShortName.value = data.company_english_short_name || "";
|
||||
}
|
||||
};
|
||||
|
||||
@@ -197,6 +215,9 @@ const handleSaveNormalInfos = async () => {
|
||||
ico: ico.value,
|
||||
description: description.value,
|
||||
companyname: companyname.value,
|
||||
company_short_name: companyShortName.value,
|
||||
company_english_name: companyEnglishName.value,
|
||||
company_english_short_name: companyEnglishShortName.value,
|
||||
copyright: copyright.value,
|
||||
icp: icp.value,
|
||||
};
|
||||
@@ -227,6 +248,9 @@ const handleIconChange = (file: UploadFile) => {
|
||||
const resetnormalForm = () => {
|
||||
sitename.value = "";
|
||||
companyname.value = "";
|
||||
companyShortName.value = "";
|
||||
companyEnglishName.value = "";
|
||||
companyEnglishShortName.value = "";
|
||||
companyintroduction.value = "";
|
||||
logo.value = "";
|
||||
logow.value = "";
|
||||
@@ -239,6 +263,9 @@ const resetnormalForm = () => {
|
||||
defineExpose({
|
||||
sitename,
|
||||
companyname,
|
||||
companyShortName,
|
||||
companyEnglishName,
|
||||
companyEnglishShortName,
|
||||
companyintroduction,
|
||||
logo,
|
||||
logow,
|
||||
|
||||
@@ -80,8 +80,8 @@
|
||||
v-loading="loading"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column prop="id" label="ID" width="60" align="center" />
|
||||
<!--<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column prop="id" label="ID" width="60" align="center" />-->
|
||||
<el-table-column
|
||||
prop="user_name"
|
||||
label="用户姓名"
|
||||
|
||||
@@ -67,8 +67,8 @@
|
||||
v-loading="loading"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column prop="id" label="ID" width="60" align="center" />
|
||||
<!--<el-table-column type="selection" width="55" align="center" />-->
|
||||
<!--<el-table-column prop="id" label="ID" width="60" align="center" />-->
|
||||
<el-table-column
|
||||
prop="user_name"
|
||||
label="用户姓名"
|
||||
|
||||
@@ -2,11 +2,13 @@ package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"server/models"
|
||||
"server/pkg/jwtutil"
|
||||
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
@@ -17,6 +19,40 @@ type BackendErpContactController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
// contactClaims 从请求头解析登录态 JWT,返回后端用户 Claims
|
||||
func (c *BackendErpContactController) contactClaims() (*jwtutil.Claims, error) {
|
||||
auth := c.Ctx.Request.Header.Get("Authorization")
|
||||
if auth == "" {
|
||||
return nil, fmt.Errorf("未登录")
|
||||
}
|
||||
parts := strings.SplitN(auth, " ", 2)
|
||||
if len(parts) != 2 || !strings.EqualFold(parts[0], "Bearer") {
|
||||
return nil, fmt.Errorf("认证信息格式错误")
|
||||
}
|
||||
claims, err := jwtutil.ParseToken(parts[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("无效的token")
|
||||
}
|
||||
if claims.UserType != "backend" {
|
||||
return nil, fmt.Errorf("无权访问")
|
||||
}
|
||||
return claims, nil
|
||||
}
|
||||
|
||||
// contactTenantID 获取当前请求的租户ID:优先使用登录态 JWT 中的租户,
|
||||
// 仅当显式传入 tid 参数时才以参数为准(兼容管理端等显式指定场景)。
|
||||
func (c *BackendErpContactController) contactTenantID() (uint64, error) {
|
||||
claims, err := c.contactClaims()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
tid := uint64(claims.TenantId)
|
||||
if v, e := c.GetInt64("tid"); e == nil && v > 0 {
|
||||
tid = uint64(v)
|
||||
}
|
||||
return tid, nil
|
||||
}
|
||||
|
||||
type erpContactDTO struct {
|
||||
ID uint64 `json:"id"`
|
||||
Tid uint64 `json:"tid"`
|
||||
@@ -46,7 +82,11 @@ type erpContactDTO struct {
|
||||
// List 获取通讯录列表(支持分页、搜索、按组织筛选)
|
||||
// GET /backend/erp/contact/list
|
||||
func (c *BackendErpContactController) List() {
|
||||
tid, _ := c.GetInt64("tid")
|
||||
tid, err := c.contactTenantID()
|
||||
if err != nil {
|
||||
c.contactJsonError(401, "未登录或无权访问")
|
||||
return
|
||||
}
|
||||
page, _ := c.GetInt("page", 1)
|
||||
pageSize, _ := c.GetInt("page_size", 20)
|
||||
keyword := strings.TrimSpace(c.GetString("keyword"))
|
||||
@@ -62,10 +102,8 @@ func (c *BackendErpContactController) List() {
|
||||
|
||||
qs := models.Orm.QueryTable(new(models.BackendErpContact)).
|
||||
Filter("delete_time__isnull", true).
|
||||
Exclude("status", 0)
|
||||
if tid > 0 {
|
||||
qs = qs.Filter("tid", tid)
|
||||
}
|
||||
Exclude("status", 0).
|
||||
Filter("tid", tid)
|
||||
if orgID > 0 {
|
||||
qs = qs.Filter("org_id", orgID)
|
||||
}
|
||||
@@ -398,17 +436,19 @@ func (c *BackendErpContactController) SyncAllContacts() {
|
||||
// GetContactOrgTree 获取通讯录组织树(带各部门联系人数量)
|
||||
// GET /backend/erp/contact/orgTree
|
||||
func (c *BackendErpContactController) GetContactOrgTree() {
|
||||
tid, _ := c.GetInt64("tid")
|
||||
tid, err := c.contactTenantID()
|
||||
if err != nil {
|
||||
c.contactJsonError(401, "未登录或无权访问")
|
||||
return
|
||||
}
|
||||
|
||||
qs := models.Orm.QueryTable(new(models.BackendOrganization)).
|
||||
Filter("delete_time__isnull", true).
|
||||
Exclude("status", 0)
|
||||
if tid > 0 {
|
||||
qs = qs.Filter("tid", tid)
|
||||
}
|
||||
Exclude("status", 0).
|
||||
Filter("tid", tid)
|
||||
|
||||
var orgs []models.BackendOrganization
|
||||
_, err := qs.OrderBy("sort", "id").All(&orgs)
|
||||
_, err = qs.OrderBy("sort", "id").All(&orgs)
|
||||
if err != nil {
|
||||
c.contactJsonError(500, "查询组织架构失败: "+err.Error())
|
||||
return
|
||||
@@ -418,10 +458,8 @@ func (c *BackendErpContactController) GetContactOrgTree() {
|
||||
cqs := models.Orm.QueryTable(new(models.BackendErpContact)).
|
||||
Filter("delete_time__isnull", true).
|
||||
Exclude("status", 0).
|
||||
Filter("contact_type", 1)
|
||||
if tid > 0 {
|
||||
cqs = cqs.Filter("tid", tid)
|
||||
}
|
||||
Filter("contact_type", 1).
|
||||
Filter("tid", tid)
|
||||
|
||||
type orgCount struct {
|
||||
OrgID uint64 `orm:"column(org_id)"`
|
||||
@@ -437,6 +475,7 @@ func (c *BackendErpContactController) GetContactOrgTree() {
|
||||
for _, org := range orgs {
|
||||
cnt, _ := models.Orm.QueryTable(new(models.BackendErpContact)).
|
||||
Filter("org_id", org.ID).
|
||||
Filter("tid", tid).
|
||||
Filter("delete_time__isnull", true).
|
||||
Exclude("status", 0).
|
||||
Filter("contact_type", 1).
|
||||
|
||||
@@ -48,10 +48,13 @@ func (c *BackendOperationLogController) jsonErr(httpStatus, bizCode int, msg str
|
||||
|
||||
// List GET /backend/operationLogs?page=1&pageSize=20&keyword=&module=&action=&status=&startTime=&endTime=
|
||||
func (c *BackendOperationLogController) List() {
|
||||
if _, err := c.backendClaims(); err != nil {
|
||||
claims, err := c.backendClaims()
|
||||
if err != nil {
|
||||
c.jsonErr(401, 401, err.Error())
|
||||
return
|
||||
}
|
||||
uid := uint64(claims.UserID)
|
||||
tid := uint64(claims.TenantId)
|
||||
|
||||
page, _ := c.GetInt("page", 1)
|
||||
pageSize, _ := c.GetInt("pageSize", 20)
|
||||
@@ -72,7 +75,10 @@ func (c *BackendOperationLogController) List() {
|
||||
startTimeStr := strings.TrimSpace(c.GetString("startTime"))
|
||||
endTimeStr := strings.TrimSpace(c.GetString("endTime"))
|
||||
|
||||
qs := models.Orm.QueryTable(new(models.SystemOperationLog)).Filter("delete_time__isnull", true)
|
||||
qs := models.Orm.QueryTable(new(models.SystemOperationLog)).
|
||||
Filter("delete_time__isnull", true).
|
||||
Filter("tid", tid).
|
||||
Filter("user_id", uid)
|
||||
|
||||
// 条件拼装
|
||||
cond := orm.NewCondition()
|
||||
@@ -174,10 +180,13 @@ func (c *BackendOperationLogController) List() {
|
||||
|
||||
// Detail GET /backend/operationLogs/:id
|
||||
func (c *BackendOperationLogController) Detail() {
|
||||
if _, err := c.backendClaims(); err != nil {
|
||||
claims, err := c.backendClaims()
|
||||
if err != nil {
|
||||
c.jsonErr(401, 401, err.Error())
|
||||
return
|
||||
}
|
||||
uid := uint64(claims.UserID)
|
||||
tid := uint64(claims.TenantId)
|
||||
idStr := c.Ctx.Input.Param(":id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||
if err != nil || id == 0 {
|
||||
@@ -187,6 +196,8 @@ func (c *BackendOperationLogController) Detail() {
|
||||
var row models.SystemOperationLog
|
||||
err = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
||||
Filter("id", id).
|
||||
Filter("tid", tid).
|
||||
Filter("user_id", uid).
|
||||
Filter("delete_time__isnull", true).
|
||||
One(&row)
|
||||
if err != nil {
|
||||
@@ -219,10 +230,13 @@ func (c *BackendOperationLogController) Detail() {
|
||||
|
||||
// Delete DELETE /backend/operationLogs/:id
|
||||
func (c *BackendOperationLogController) Delete() {
|
||||
if _, err := c.backendClaims(); err != nil {
|
||||
claims, err := c.backendClaims()
|
||||
if err != nil {
|
||||
c.jsonErr(401, 401, err.Error())
|
||||
return
|
||||
}
|
||||
uid := uint64(claims.UserID)
|
||||
tid := uint64(claims.TenantId)
|
||||
idStr := c.Ctx.Input.Param(":id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||
if err != nil || id == 0 {
|
||||
@@ -232,6 +246,8 @@ func (c *BackendOperationLogController) Delete() {
|
||||
now := time.Now()
|
||||
n, err := models.Orm.QueryTable(new(models.SystemOperationLog)).
|
||||
Filter("id", id).
|
||||
Filter("tid", tid).
|
||||
Filter("user_id", uid).
|
||||
Filter("delete_time__isnull", true).
|
||||
Update(map[string]interface{}{"delete_time": now})
|
||||
if err != nil {
|
||||
@@ -252,10 +268,13 @@ type backendBatchDeletePayload struct {
|
||||
|
||||
// BatchDelete POST /backend/operationLogs/batchDelete
|
||||
func (c *BackendOperationLogController) BatchDelete() {
|
||||
if _, err := c.backendClaims(); err != nil {
|
||||
claims, err := c.backendClaims()
|
||||
if err != nil {
|
||||
c.jsonErr(401, 401, err.Error())
|
||||
return
|
||||
}
|
||||
uid := uint64(claims.UserID)
|
||||
tid := uint64(claims.TenantId)
|
||||
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
||||
if err != nil {
|
||||
c.jsonErr(400, 400, "参数错误")
|
||||
@@ -273,6 +292,8 @@ func (c *BackendOperationLogController) BatchDelete() {
|
||||
now := time.Now()
|
||||
_, err = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
||||
Filter("id__in", p.IDs).
|
||||
Filter("tid", tid).
|
||||
Filter("user_id", uid).
|
||||
Filter("delete_time__isnull", true).
|
||||
Update(map[string]interface{}{"delete_time": now})
|
||||
if err != nil {
|
||||
@@ -286,14 +307,19 @@ func (c *BackendOperationLogController) BatchDelete() {
|
||||
// Statistics GET /backend/operationLogs/statistics
|
||||
// 供前端筛选项:modules/actions
|
||||
func (c *BackendOperationLogController) Statistics() {
|
||||
if _, err := c.backendClaims(); err != nil {
|
||||
claims, err := c.backendClaims()
|
||||
if err != nil {
|
||||
c.jsonErr(401, 401, err.Error())
|
||||
return
|
||||
}
|
||||
uid := uint64(claims.UserID)
|
||||
tid := uint64(claims.TenantId)
|
||||
|
||||
var moduleRows []models.SystemOperationLog
|
||||
_, _ = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
||||
Filter("delete_time__isnull", true).
|
||||
Filter("tid", tid).
|
||||
Filter("user_id", uid).
|
||||
Filter("module__isnull", false).
|
||||
Limit(1000).
|
||||
All(&moduleRows, "Module")
|
||||
@@ -312,6 +338,8 @@ func (c *BackendOperationLogController) Statistics() {
|
||||
var actionRows []models.SystemOperationLog
|
||||
_, _ = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
||||
Filter("delete_time__isnull", true).
|
||||
Filter("tid", tid).
|
||||
Filter("user_id", uid).
|
||||
Filter("action__isnull", false).
|
||||
Limit(1000).
|
||||
All(&actionRows, "Action")
|
||||
|
||||
@@ -89,6 +89,9 @@ type backendNormalInfosOutput struct {
|
||||
Description string `json:"description"`
|
||||
Copyright string `json:"copyright"`
|
||||
Companyname string `json:"companyname"`
|
||||
CompanyShortName string `json:"company_short_name"`
|
||||
CompanyEnglishName string `json:"company_english_name"`
|
||||
CompanyEnglishShort string `json:"company_english_short_name"`
|
||||
Icp string `json:"icp"`
|
||||
Logo string `json:"logo"`
|
||||
Logow string `json:"logow"`
|
||||
@@ -156,6 +159,15 @@ func (c *BackendSiteSettingsController) GetNormalInfos() {
|
||||
out.Icp = r.Icp
|
||||
}
|
||||
|
||||
// 扩展字段(企业简称 / 企业英文名称 / 企业英文简称)存放在 yz_system_tenant_setting_items
|
||||
if ext, eerr := c.getBackendSettingItems(tid, []string{
|
||||
"company_short_name", "company_english_name", "company_english_short_name",
|
||||
}); eerr == nil {
|
||||
out.CompanyShortName = ext["company_short_name"]
|
||||
out.CompanyEnglishName = ext["company_english_name"]
|
||||
out.CompanyEnglishShort = ext["company_english_short_name"]
|
||||
}
|
||||
|
||||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": out}
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
@@ -172,6 +184,9 @@ type backendNormalInfosPayload struct {
|
||||
Description string `json:"description"`
|
||||
Copyright string `json:"copyright"`
|
||||
Companyname string `json:"companyname"`
|
||||
CompanyShortName string `json:"company_short_name"`
|
||||
CompanyEnglishName string `json:"company_english_name"`
|
||||
CompanyEnglishShort string `json:"company_english_short_name"`
|
||||
Icp string `json:"icp"`
|
||||
}
|
||||
|
||||
@@ -266,6 +281,16 @@ func (c *BackendSiteSettingsController) SaveNormalInfos() {
|
||||
}
|
||||
}
|
||||
|
||||
// 扩展字段(企业简称 / 企业英文名称 / 企业英文简称)
|
||||
if err = c.saveBackendSettingItems(tid, map[string]string{
|
||||
"company_short_name": strings.TrimSpace(p.CompanyShortName),
|
||||
"company_english_name": strings.TrimSpace(p.CompanyEnglishName),
|
||||
"company_english_short_name": strings.TrimSpace(p.CompanyEnglishShort),
|
||||
}); err != nil {
|
||||
c.jsonErr(500, 500, "保存扩展信息失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "保存成功"}
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
|
||||
BIN
Binary file not shown.
Reference in New Issue
Block a user