sync: 对齐小程序 v1.0.2 生产代码并脱敏

This commit is contained in:
MiFaZhan
2026-10-29 15:15:12 +08:00
parent a7abd476f0
commit 5fcf74deb0
423 changed files with 15001 additions and 6382 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
// Package addons
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package addons
@@ -0,0 +1,35 @@
package allocaterequest
import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"regexp"
"sort"
"strings"
"github.com/gogf/gf/v2/errors/gerror"
)
var validID = regexp.MustCompile(`^[A-Za-z0-9_-]{16,96}$`)
func Key(tenant string, user int64, requestID string) (string, error) {
requestID = strings.TrimSpace(requestID)
if tenant == "" || user <= 0 || !validID.MatchString(requestID) {
return "", gerror.New("划拨请求标识无效")
}
value, err := json.Marshal([]any{tenant, user, "allocate", requestID})
if err != nil {
return "", gerror.Wrap(err, "生成划拨请求标识失败")
}
digest := sha256.Sum256(value)
return hex.EncodeToString(digest[:]), nil
}
func Fingerprint(cards []string, source, target int64, mode int, remark string) string {
sorted := append([]string(nil), cards...)
sort.Strings(sorted)
value, _ := json.Marshal([]any{sorted, source, target, mode, strings.TrimSpace(remark)})
digest := sha256.Sum256(value)
return hex.EncodeToString(digest[:])
}
@@ -0,0 +1,41 @@
package allocaterequest
import "testing"
func TestRequestIdentity(t *testing.T) {
requestID := "alloc_0123456789abcdef"
first, err := Key("A", 7, requestID)
if err != nil || len(first) != 64 {
t.Fatal(first, err)
}
same, _ := Key("A", 7, requestID)
if first != same {
t.Fatal("unstable identity")
}
for _, entry := range []struct {
tenant string
user int64
id string
}{{"B", 7, requestID}, {"A", 8, requestID}, {"A", 7, requestID + "2"}} {
other, err := Key(entry.tenant, entry.user, entry.id)
if err != nil || other == first {
t.Fatal("identity scope collision", err)
}
}
for _, id := range []string{"", "short", "0123456789abcdef/"} {
if _, err := Key("A", 7, id); err == nil {
t.Fatal("invalid identity accepted", id)
}
}
}
func TestFingerprint(t *testing.T) {
first := Fingerprint([]string{"B", "A"}, 1, 2, 2, " remark ")
if first != Fingerprint([]string{"A", "B"}, 1, 2, 2, "remark") {
t.Fatal("card order changed identity")
}
for _, other := range []string{Fingerprint([]string{"A"}, 1, 2, 2, "remark"), Fingerprint([]string{"A", "B"}, 2, 2, 2, "remark"), Fingerprint([]string{"A", "B"}, 1, 3, 2, "remark"), Fingerprint([]string{"A", "B"}, 1, 2, 1, "remark"), Fingerprint([]string{"A", "B"}, 1, 2, 2, "other")} {
if first == other {
t.Fatal("changed parameters accepted")
}
}
}
@@ -0,0 +1,25 @@
package allocaterequest
import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/dao"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model/entity"
)
func Find(ctx context.Context, tenant string, user int64, requestID string) (*entity.BatchMain, error) {
key, err := Key(tenant, user, requestID)
if err != nil {
return nil, err
}
var batch *entity.BatchMain
columns := dao.BatchMain.Columns()
scope := dao.BatchMain.Ctx(ctx).Where(columns.TenantId, tenant).Where(columns.CreatedBy, user)
if err = scope.Clone().Where(columns.BatchNo, "ALC"+key[:60]).Scan(&batch); err != nil {
return nil, gerror.Wrap(err, "查询历史划拨请求失败")
}
if batch != nil {
return batch, nil
}
return nil, nil
}
@@ -0,0 +1,141 @@
package allocationunits
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/errors/gerror"
"strings"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/dao"
)
// Fields 是日志展示契约,不增加数据库字段。
type Fields struct {
SourceDeptId int64 `json:"sourceDeptId" orm:"-"`
SourceDeptName string `json:"sourceDeptName" orm:"-"`
TargetDeptId int64 `json:"targetDeptId" orm:"-"`
TargetDeptName string `json:"targetDeptName" orm:"-"`
TargetDeptMode string `json:"targetDeptMode" orm:"-"`
}
type Unit struct {
Id int64 `orm:"dept_id"`
Key string `orm:"dept_key"`
Name string `orm:"dept_name"`
}
func Load(ctx context.Context, tenant string, ids []int64, tx ...gdb.TX) (map[int64]Unit, error) {
unique := map[int64]bool{}
for _, id := range ids {
if id > 0 {
unique[id] = true
}
}
result := map[int64]Unit{}
if len(unique) == 0 {
return result, nil
}
ids = nil
for id := range unique {
ids = append(ids, id)
}
var rows []Unit
if len(tx) > 0 {
result, err := tx[0].GetAll("SELECT dept_id,dept_key,dept_name FROM sys_dept WHERE tenant_id=? AND deleted_at IS NULL AND dept_id IN (?)", tenant, ids)
if err != nil {
return nil, gerror.Wrap(err, "读取划拨单位信息失败")
}
if err := result.Structs(&rows); err != nil {
return nil, err
}
units := map[int64]Unit{}
for _, row := range rows {
units[row.Id] = row
}
return units, nil
}
mod := dao.SysDept.Ctx(ctx)
if err := mod.WhereNull("deleted_at").Where("tenant_id", tenant).WhereIn("dept_id", ids).Fields("dept_id", "dept_key", "dept_name", "deleted_at").Scan(&rows); err != nil {
return nil, gerror.Wrap(err, "读取划拨单位信息失败")
}
for _, row := range rows {
result[row.Id] = row
}
return result, nil
}
// Snapshot 名称由服务端查询,仅在受理时记录,执行时不覆盖。
func Snapshot(ctx context.Context, tenant string, source, target int64, tx ...gdb.TX) (*gjson.Json, error) {
units, err := Load(ctx, tenant, []int64{source, target}, tx...)
if err != nil {
return nil, err
}
mode := "single"
if target <= 0 {
mode = "per_row"
}
return gjson.New(map[string]any{"sourceDeptId": source, "sourceDeptKey": units[source].Key, "sourceDeptName": units[source].Name, "targetDeptId": target, "targetDeptKey": units[target].Key, "targetDeptName": units[target].Name, "targetDeptMode": mode}), nil
}
func Resolve(info *gjson.Json, source, target int64) Fields {
f := Fields{SourceDeptId: source, TargetDeptId: target}
if info != nil {
if id := info.Get("sourceDeptId").Int64(); id > 0 {
f.SourceDeptId = id
}
if id := info.Get("targetDeptId").Int64(); id > 0 {
f.TargetDeptId = id
}
f.SourceDeptName = strings.TrimSpace(info.Get("sourceDeptName").String())
f.TargetDeptName = strings.TrimSpace(info.Get("targetDeptName").String())
f.TargetDeptMode = info.Get("targetDeptMode").String()
}
if f.TargetDeptMode == "" {
if f.TargetDeptId > 0 {
f.TargetDeptMode = "single"
} else {
f.TargetDeptMode = "per_row"
}
}
return f
}
// Fill 一页只补查一次旧数据的单位名称,不扫描卡片当前归属,不覆盖历史快照。
func Fill(ctx context.Context, tenant string, fields []*Fields) error {
ids := []int64{}
for _, f := range fields {
if f.SourceDeptName == "" {
ids = append(ids, f.SourceDeptId)
}
if f.TargetDeptName == "" {
ids = append(ids, f.TargetDeptId)
}
}
units, err := Load(ctx, tenant, ids)
if err != nil {
return err
}
for _, f := range fields {
if f.SourceDeptName == "" {
f.SourceDeptName = units[f.SourceDeptId].Name
}
if f.TargetDeptName == "" {
f.TargetDeptName = units[f.TargetDeptId].Name
}
}
return nil
}
func Merge(info, units *gjson.Json) *gjson.Json {
data := map[string]any{}
if info != nil {
for k, v := range info.Map() {
data[k] = v
}
}
if units != nil {
for k, v := range units.Map() {
data[k] = v
}
}
return gjson.New(data)
}
@@ -0,0 +1,55 @@
package allocationunits
import (
"context"
"encoding/json"
_ "github.com/gogf/gf/contrib/drivers/sqlite/v2"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"strings"
"testing"
)
func TestSnapshotAndLegacyFallback(t *testing.T) {
ctx := context.Background()
if err := gdb.SetConfig(gdb.Config{"default": gdb.ConfigGroup{{Type: "sqlite", Link: "sqlite::@file(:memory:)", MaxOpenConnCount: 1}}}); err != nil {
t.Fatal(err)
}
t.Cleanup(func() { _ = g.DB().Close(ctx) })
for _, sql := range []string{"CREATE TABLE sys_dept(dept_id INTEGER,tenant_id TEXT,dept_key TEXT,dept_name TEXT,deleted_at TEXT)", "INSERT INTO sys_dept VALUES(1,'A','a','划拨单位',NULL),(2,'A','b','接收单位',NULL),(3,'B','other','其他租户',NULL),(4,'A','gone','已删除单位','2026-01-01')"} {
if _, err := g.DB().Exec(ctx, sql); err != nil {
t.Fatal(err)
}
}
snapshot, err := Snapshot(ctx, "A", 1, 2)
if err != nil {
t.Fatal(err)
}
if _, err := g.DB().Exec(ctx, "UPDATE sys_dept SET dept_name='新名称' WHERE dept_id=2"); err != nil {
t.Fatal(err)
}
frozen := Resolve(snapshot, 0, 0)
legacy := Resolve(nil, 1, 2)
foreign := Resolve(nil, 3, 4)
if err := Fill(ctx, "A", []*Fields{&frozen, &legacy, &foreign}); err != nil {
t.Fatal(err)
}
if frozen.TargetDeptName != "接收单位" || legacy.TargetDeptName != "新名称" || foreign.SourceDeptName != "" || foreign.TargetDeptName != "" {
t.Fatalf("快照/回退/隔离错误: %+v %+v %+v", frozen, legacy, foreign)
}
if f := Resolve(gjson.New(map[string]any{"sourceDeptName": "历史名称"}), 1, 0); f.TargetDeptMode != "per_row" {
t.Fatal(f)
}
encoded, err := json.Marshal(frozen)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(string(encoded), "sourceDeptName") {
t.Fatal("JSON契约缺少单位字段")
}
merged := Merge(gjson.New(map[string]any{"jobRole": "allocate_parent"}), snapshot)
if merged.Get("jobRole").String() != "allocate_parent" || merged.Get("sourceDeptName").String() != "划拨单位" {
t.Fatal(merged)
}
}
@@ -3,6 +3,7 @@ package batchimport
import (
"context"
"strings"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/library/batchmetadata"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/consts"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/dao"
@@ -21,6 +22,9 @@ type PendingOptions struct {
}
func CreatePendingUpload(ctx context.Context, req SubmitRequest, p Processor, options PendingOptions) (*Result, error) {
if err := batchmetadata.ValidateCreation(req.SourceChannel, req.ExecutionMode); err != nil {
return nil, err
}
cfg := p.Config()
if req.File == nil {
return nil, gerror.New("请选择上传文件")
@@ -59,6 +63,9 @@ func CreatePendingUpload(ctx context.Context, req SubmitRequest, p Processor, op
}
func CreatePendingRows(ctx context.Context, req SubmitRequest, p Processor, rows []Row, options PendingOptions) (*Result, error) {
if err := batchmetadata.ValidateCreation(req.SourceChannel, req.ExecutionMode); err != nil {
return nil, err
}
batchNo, err := NextBatchNoContext(ctx, p.Config().BatchNoPrefix)
if err != nil {
return nil, err
@@ -103,6 +110,8 @@ func createPending(ctx context.Context, req *SubmitRequest, p Processor, rows []
BatchStatus: consts.BatchAsyncStatusPending,
BatchAsyncStatus: consts.BatchAsyncStatusPending,
SourceType: req.SourceType,
SourceChannel: batchmetadata.Channel(req.SourceChannel),
ExecutionMode: batchmetadata.NormalizeMode(req.ExecutionMode),
SourceBatchNo: sourceBatchNo,
IsCrossDept: 0,
TargetDeptId: req.TargetDeptId,
+12 -3
View File
@@ -3,17 +3,18 @@ package batchimport
import (
"context"
"fmt"
"io"
"os"
"strings"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/consts"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/dao"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/library/batchmetadata"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model/do"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model/entity"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/service"
"git.5iot.com/iotlcm-public/iotlcm-app/utility/hash"
"git.5iot.com/iotlcm-public/iotlcm-app/utility/iot_excelize"
"io"
"os"
"strings"
"github.com/gogf/gf/v2/crypto/gmd5"
"github.com/gogf/gf/v2/database/gdb"
@@ -25,6 +26,9 @@ import (
)
func SubmitAndRun(ctx context.Context, req SubmitRequest, p Processor) (*Result, error) {
if err := batchmetadata.ValidateCreation(req.SourceChannel, req.ExecutionMode); err != nil {
return nil, err
}
cfg := p.Config()
if req.File == nil {
return nil, gerror.New("请选择上传文件")
@@ -107,6 +111,9 @@ func SubmitAndRun(ctx context.Context, req SubmitRequest, p Processor) (*Result,
}
func RunRows(ctx context.Context, req SubmitRequest, p Processor, rows []Row, sourceName string) (*Result, error) {
if err := batchmetadata.ValidateCreation(req.SourceChannel, req.ExecutionMode); err != nil {
return nil, err
}
cfg := p.Config()
batchNo, err := NextBatchNoContext(ctx, cfg.BatchNoPrefix)
if err != nil {
@@ -268,6 +275,8 @@ func saveBatchAndExecute(ctx context.Context, req *SubmitRequest, p Processor, r
BatchStatus: batchStatusByImportStatus(result.ImportStatus),
BatchAsyncStatus: batchStatusByImportStatus(result.ImportStatus),
SourceType: req.SourceType,
SourceChannel: batchmetadata.Channel(req.SourceChannel),
ExecutionMode: batchmetadata.NormalizeMode(req.ExecutionMode),
SourceBatchNo: sourceBatchNo,
IsCrossDept: 0,
TargetDeptId: req.TargetDeptId,
@@ -10,6 +10,9 @@ import (
)
type SubmitRequest struct {
SourceChannel string
// ExecutionMode is the semantic size of the operation. Zero means the caller did not specify it.
ExecutionMode int
File *ghttp.UploadFile
BizParams any
SourceType int
@@ -0,0 +1,52 @@
package batchmetadata
import "github.com/gogf/gf/v2/errors/gerror"
const (
Console = "console"
MiniProgram = "mini_program"
API = "api"
System = "system"
Legacy = "legacy"
Unknown = 0
Single = 1
Bulk = 2
)
// NormalizeMode validates the explicit execution size supplied by the business entry point.
// Execution size is request metadata and must not be inferred from context or result counts.
func NormalizeMode(requested int) int {
if requested == Single || requested == Bulk {
return requested
}
return Unknown
}
func ValidChannel(value string) bool {
switch value {
case Console, MiniProgram, API, System, Legacy:
return true
}
return false
}
func Channel(value string) string {
if ValidChannel(value) {
return value
}
return Legacy
}
func ValidMode(value int) bool { return value >= Unknown && value <= Bulk }
// ValidateCreation rejects missing attribution for new work; historical reads
// and resumed work continue to use Channel/NormalizeMode for compatibility.
func ValidateCreation(channel string, mode int) error {
if !ValidChannel(channel) || channel == Legacy {
return gerror.New("新建批次发起渠道无效")
}
if mode != Single && mode != Bulk {
return gerror.New("新建批次必须指定单卡或批量操作规模")
}
return nil
}
@@ -0,0 +1,52 @@
package batchmetadata
import "testing"
func TestValidateCreation(t *testing.T) {
for _, channel := range []string{Console, MiniProgram, API, System} {
for _, mode := range []int{Single, Bulk} {
if err := ValidateCreation(channel, mode); err != nil {
t.Fatal(channel, mode, err)
}
}
}
for _, channel := range []string{"", Legacy} {
if err := ValidateCreation(channel, Single); err == nil {
t.Fatal("missing new batch attribution accepted", channel)
}
}
if ValidateCreation("worker", Single) == nil {
t.Fatal("invalid source accepted")
}
for _, mode := range []int{-1, Unknown, 3} {
if ValidateCreation(Console, mode) == nil {
t.Fatal("invalid new execution size accepted", mode)
}
}
}
func TestMetadata(t *testing.T) {
if NormalizeMode(0) != Unknown {
t.Fatal("unspecified entry mode must remain unknown")
}
if NormalizeMode(Single) != Single {
t.Fatal("single entry mode lost")
}
if NormalizeMode(Bulk) != Bulk {
t.Fatal("bulk entry mode lost")
}
if NormalizeMode(99) != Unknown {
t.Fatal("invalid entry mode accepted")
}
for _, c := range []string{Console, MiniProgram, API, System, Legacy} {
if Channel(c) != c {
t.Fatal(c)
}
}
if Channel("worker") != Legacy || Channel("") != Legacy {
t.Fatal("unknown source was attributed")
}
if ValidMode(-1) || ValidMode(3) {
t.Fatal("invalid mode accepted")
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
// Package bcache
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package bcache
@@ -1,16 +1,16 @@
// Package bcache
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package bcache
import (
"context"
"fmt"
"time"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/consts"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/library/cache"
"time"
"github.com/gogf/gf/v2/frame/g"
)
+1 -1
View File
@@ -1,7 +1,7 @@
// Package cache
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package cache
+1 -1
View File
@@ -1,7 +1,7 @@
// Package file
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package file
+2 -2
View File
@@ -1,15 +1,15 @@
// Package contexts
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package contexts
import (
"context"
"slices"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/consts"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model"
"slices"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
+1 -1
View File
@@ -1,7 +1,7 @@
// Package event
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package event
+1 -1
View File
@@ -1,7 +1,7 @@
// Package mcache
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
// 内存缓存管理
package mcache
@@ -1,17 +1,17 @@
// Package mcache
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package mcache
import (
"context"
"fmt"
"time"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/consts"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/library/event"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/service"
"time"
"github.com/gogf/gf/v2/frame/g"
)
@@ -28,7 +28,29 @@ func init() {
}
type requestAccessKey struct{}
type requestAccessSnapshot struct {
userId int64
codes []string
scopes []string
}
// WithFreshUserAccess 为小程序请求读取当前权限并保留请求内快照。
// 控制台清理本地缓存不会清理小程序进程内的权限缓存。
func WithFreshUserAccess(ctx context.Context, userId int64) (context.Context, error) {
codes, scopes, err := service.SysAuth().GetUserAccessCodeList(ctx, userId)
if err != nil {
return ctx, err
}
snapshot := requestAccessSnapshot{userId: userId, codes: ensureCurrentUserAccessCode(codes), scopes: scopes}
return context.WithValue(ctx, requestAccessKey{}, snapshot), nil
}
func GetUserAccessCodeList(ctx context.Context, userId int64) ([]string, []string, error) {
if snapshot, ok := ctx.Value(requestAccessKey{}).(requestAccessSnapshot); ok && snapshot.userId == userId {
return snapshot.codes, snapshot.scopes, nil
}
accessCodeList, err := Instance().Get(ctx, fmt.Sprintf(consts.MemCacheUserAccessCodeList, userId))
menuRoleDataAccessCodeList, err := Instance().Get(ctx, fmt.Sprintf(consts.MemCacheUserRoleDataAccessCodeList, userId))
if err != nil || accessCodeList == nil {
@@ -0,0 +1,19 @@
package mcache
import (
"context"
"reflect"
"testing"
)
func TestRequestAccessSnapshotOverridesProcessCache(t *testing.T) {
for _, codes := range [][]string{{"cpm:iot:tSimCardAllocate:batch:submit"}, {}} {
ctx := context.WithValue(context.Background(), requestAccessKey{}, requestAccessSnapshot{
userId: 123, codes: ensureCurrentUserAccessCode(codes), scopes: []string{"scope-current"},
})
got, scopes, err := GetUserAccessCodeList(ctx, 123)
if err != nil || !reflect.DeepEqual(got, ensureCurrentUserAccessCode(codes)) || !reflect.DeepEqual(scopes, []string{"scope-current"}) {
t.Fatalf("request snapshot was not respected: codes=%v scopes=%v err=%v", got, scopes, err)
}
}
}
@@ -1,20 +1,20 @@
// Package mcache
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package mcache
import (
"context"
"fmt"
"time"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/consts"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/library/contexts"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/library/event"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model/request"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/service"
"time"
)
func init() {
@@ -1,17 +1,17 @@
// Package mcache
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package mcache
import (
"context"
"fmt"
"time"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/consts"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/library/event"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/service"
"time"
)
func init() {
@@ -1,18 +1,18 @@
// Package mcache
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package mcache
import (
"context"
"fmt"
"time"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/consts"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/library/event"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/service"
"time"
"github.com/gogf/gf/v2/util/gconv"
)
@@ -3,6 +3,7 @@ package rabbitmq
import (
"context"
"encoding/json"
"fmt"
"sync"
"time"
@@ -41,6 +42,25 @@ func Publish(ctx context.Context, queue string, data any) error {
return PublishBytes(ctx, queue, body)
}
func PublishDelayed(ctx context.Context, delayQueue, targetQueue string, delay time.Duration, data any) error {
body, err := json.Marshal(data)
if err != nil {
return gerror.Wrap(err, "序列化延时工单消息失败")
}
ch, err := channel(ctx)
if err != nil {
return err
}
defer ch.Close()
if _, err = ch.QueueDeclare(targetQueue, true, false, false, false, nil); err != nil {
return gerror.Wrap(err, "声明工单目标队列失败")
}
if _, err = ch.QueueDeclare(delayQueue, true, false, false, false, amqp.Table{"x-dead-letter-exchange": "", "x-dead-letter-routing-key": targetQueue}); err != nil {
return gerror.Wrap(err, "声明工单延时队列失败")
}
return gerror.Wrap(ch.PublishWithContext(ctx, "", delayQueue, false, false, amqp.Publishing{ContentType: "application/json", DeliveryMode: amqp.Persistent, Expiration: fmt.Sprintf("%d", delay.Milliseconds()), Timestamp: time.Now(), Body: body}), "发送工单延时消息失败")
}
func PublishBytes(ctx context.Context, queue string, body []byte) error {
if queue == "" {
return gerror.New("RabbitMQ 队列名不能为空")
+1 -1
View File
@@ -1,7 +1,7 @@
// Package websocket
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package websocket
@@ -1,7 +1,7 @@
// Package websocket
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package websocket
@@ -1,7 +1,7 @@
// Package websocket
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package websocket
+2 -2
View File
@@ -1,14 +1,14 @@
// Package websocket
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package websocket
import (
"context"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/library/contexts"
"net/http"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/library/contexts"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
+1 -1
View File
@@ -1,7 +1,7 @@
// Package websocket
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package websocket
+1 -1
View File
@@ -1,7 +1,7 @@
// Package websocket
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package websocket
+1 -1
View File
@@ -1,7 +1,7 @@
// Package worker
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package worker
@@ -1,7 +1,7 @@
// package worker
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package worker
+1 -1
View File
@@ -1,7 +1,7 @@
// package worker
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package worker
@@ -1,7 +1,7 @@
// package genconsts
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package genconsts
@@ -1,7 +1,7 @@
// package genconsts
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package genconsts
@@ -1,7 +1,7 @@
// package gendao
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package gendao
@@ -1,7 +1,7 @@
// package genmodel
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package genmodel
@@ -1,7 +1,7 @@
// package genmodel
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package genmodel
@@ -1,7 +1,7 @@
// package genmodel
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package genmodel
@@ -1,15 +1,15 @@
// package genview
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package genview
import (
"context"
"strings"
gendao "git.5iot.com/iotlcm-public/iotlcm-app/internal/library/xgen/gen_dao"
genmodel "git.5iot.com/iotlcm-public/iotlcm-app/internal/library/xgen/gen_model"
"strings"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
@@ -1,7 +1,7 @@
// package genview
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package genview
@@ -1,7 +1,7 @@
// package genview
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package genview
@@ -1,12 +1,14 @@
// package genview
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package genview
import (
"context"
"runtime"
"strings"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/dao"
genconsts "git.5iot.com/iotlcm-public/iotlcm-app/internal/library/xgen/gen_consts"
genmodel "git.5iot.com/iotlcm-public/iotlcm-app/internal/library/xgen/gen_model"
@@ -15,8 +17,6 @@ import (
"git.5iot.com/iotlcm-public/iotlcm-app/utility"
"git.5iot.com/iotlcm-public/iotlcm-app/utility/tree"
version "git.5iot.com/iotlcm-public/iotlcm-app/utility/version"
"runtime"
"strings"
"github.com/gogf/gf/v2/container/gvar"
"github.com/gogf/gf/v2/database/gdb"
@@ -1,7 +1,7 @@
// package genview
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package genview
@@ -9,9 +9,9 @@ import (
"bytes"
"context"
"fmt"
"strings"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/dao"
genmodel "git.5iot.com/iotlcm-public/iotlcm-app/internal/library/xgen/gen_model"
"strings"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
@@ -1,7 +1,7 @@
// package genview
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package genview
@@ -1,7 +1,7 @@
// package genview
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package genview
@@ -9,9 +9,9 @@ import (
"bytes"
"context"
"fmt"
"strconv"
genmodel "git.5iot.com/iotlcm-public/iotlcm-app/internal/library/xgen/gen_model"
"git.5iot.com/iotlcm-public/iotlcm-app/utility"
"strconv"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
@@ -1,7 +1,7 @@
// package genview
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package genview
@@ -1,7 +1,7 @@
// package genview
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package genview
@@ -1,7 +1,7 @@
// package genview
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package genview
@@ -1,7 +1,7 @@
// package genview
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package genview
@@ -1,7 +1,7 @@
// package genview
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package genview
@@ -1,7 +1,7 @@
// package gohtml
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package gohtml
@@ -1,6 +1,6 @@
// package genview
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package gohtml
@@ -1,7 +1,7 @@
// package gohtml
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package gohtml
@@ -1,7 +1,7 @@
// package gohtml
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package gohtml
@@ -1,7 +1,7 @@
// package gohtml
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package gohtml
@@ -1,7 +1,7 @@
// package gohtml
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package gohtml
@@ -1,7 +1,7 @@
// package gohtml
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package gohtml
@@ -1,7 +1,7 @@
// package gohtml
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package gohtml
@@ -1,7 +1,7 @@
// package gohtml
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package gohtml
@@ -1,7 +1,7 @@
// package gohtml
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package gohtml
+3 -3
View File
@@ -1,13 +1,15 @@
// package xgen
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package xgen
import (
"context"
"fmt"
"sort"
"strings"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/library/addons"
genconsts "git.5iot.com/iotlcm-public/iotlcm-app/internal/library/xgen/gen_consts"
gendao "git.5iot.com/iotlcm-public/iotlcm-app/internal/library/xgen/gen_dao"
@@ -16,8 +18,6 @@ import (
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model/request"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/service"
"sort"
"strings"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
+1 -1
View File
@@ -1,7 +1,7 @@
// package xgen
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package xgen
+2 -2
View File
@@ -1,15 +1,15 @@
// package xgorm
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package xgorm
import (
"context"
"fmt"
"git.5iot.com/iotlcm-public/iotlcm-app/utility"
"slices"
"git.5iot.com/iotlcm-public/iotlcm-app/utility"
"reflect"
+2 -2
View File
@@ -1,15 +1,15 @@
// package xgorm
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package xgorm
import (
"context"
"slices"
gormmodel "git.5iot.com/iotlcm-public/iotlcm-app/internal/library/xgorm/gorm_model"
"git.5iot.com/iotlcm-public/iotlcm-app/utility/tree"
"slices"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
@@ -1,7 +1,7 @@
// package gormmodel
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package gormmodel
@@ -1,7 +1,7 @@
// package handler
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package handler
@@ -1,7 +1,7 @@
// package handler
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package handler
@@ -1,7 +1,7 @@
// package handler
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package handler
@@ -1,7 +1,7 @@
// package handler
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package handler
+1 -1
View File
@@ -1,7 +1,7 @@
// package hook
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2025 LiXiujie
// @Author Lxj <li@xiujie.cn>
// @Author Lxj <li@example.com>
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
package hook