diff --git a/.gitattributes b/.gitattributes index 5837541..357a48f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -11,3 +11,4 @@ *.ttf binary *.pdf binary *.exe binary +*.go linguist-language=Go diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..40979f1 --- /dev/null +++ b/README.MD @@ -0,0 +1,4 @@ +# GoFrame Template For SingleRepo + +Quick Start: +- https://goframe.org/quick \ No newline at end of file diff --git a/api/common/v1/common.go b/api/common/v1/common.go index 3fc8ad7..3d3829f 100644 --- a/api/common/v1/common.go +++ b/api/common/v1/common.go @@ -27,8 +27,11 @@ type BatchSimSubscribeReq struct { Remark string `json:"remark,omitempty"` } +// RenewReq 历史批量续费兼容入口,与 /batch-sim-subscribe 共用 SubmitRenew 实现。 +// 说明:g.Meta 的 deprecated 标签在 GoFrame v2.9.6 中不被解析,无任何运行时或文档生成效果, +// 不能替代对外废弃告知;对外说明见 openapi-docs「标准入口与兼容入口」一节。 type RenewReq struct { - g.Meta `path:"/renew" method:"POST" tags:"V3 Common API" summary:"Renewal compatibility endpoint"` + g.Meta `path:"/renew" method:"POST" tags:"V3 Compatibility API" summary:"Deprecated compatibility endpoint; use /change/batch-sim-subscribe"` model.CommonRenewParam } @@ -51,7 +54,11 @@ type BatchSimTrafficCutoffReq struct { model.CommonTrafficCutoffConfigParam } +// TrafficCutoffConfigReq 历史批量达量断网变更入口,已决定下线:不登记资源、不授权, +// 调用返回 10014。与 /batch-sim-traffic-cutoff 的参数类型与实现完全相同,客户应改用标准入口。 +// 路由与结构体保留以便可逆恢复(取消登记 SQL 文末注释即可),故不删除代码。 +// 说明:deprecated 标签在 GoFrame v2.9.6 中不被解析,无运行时效果。 type TrafficCutoffConfigReq struct { - g.Meta `path:"/traffic-cutoff-config" method:"POST" tags:"V3 Common API" summary:"Batch traffic cutoff compatibility endpoint"` + g.Meta `path:"/traffic-cutoff-config" method:"POST" tags:"V3 Compatibility API" summary:"Deprecated write endpoint; use /change/batch-sim-traffic-cutoff"` model.CommonTrafficCutoffConfigParam } diff --git a/build/Dockerfile b/build/Dockerfile index 07bb8bf..5d36a98 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -1,5 +1,5 @@ -FROM golang:1.25-alpine AS builder - +ARG BASE_REGISTRY=docker.io/library +FROM ${BASE_REGISTRY}/golang:1.25-alpine AS builder LABEL maintainer="iotlcm-openapi" ARG GOPROXY=https://goproxy.cn,direct @@ -7,14 +7,13 @@ ENV GOPROXY=${GOPROXY} \ GOSUMDB=off WORKDIR /app - ENV GO111MODULE=on \ CGO_ENABLED=0 \ GOOS=linux \ GOARCH=amd64 COPY go.mod go.sum ./ -RUN go mod download +RUN go mod download || (go clean -modcache && go mod download) ARG BuildVersion ARG BuildTime @@ -23,21 +22,23 @@ ARG CommitID COPY . . RUN go build -trimpath -ldflags="-s -w -X main.BuildVersion=${BuildVersion} -X main.BuildTime=${BuildTime} -X main.CommitID=${CommitID}" -o /app/bin/iotlcm-openapi . -FROM alpine:3.23 - +FROM ${BASE_REGISTRY}/alpine:3.23 AS alpine LABEL maintainer="iotlcm-openapi" -RUN apk add --no-cache ca-certificates tzdata && \ +ARG ALPINE_MIRROR=mirrors.aliyun.com +RUN sed -i "s|dl-cdn.alpinelinux.org|${ALPINE_MIRROR}|g" /etc/apk/repositories && \ + apk add --no-cache ca-certificates tzdata && \ cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ echo "Asia/Shanghai" > /etc/timezone ENV TZ=Asia/Shanghai \ WORKDIR=/app +WORKDIR $WORKDIR COPY --from=builder /app/bin/iotlcm-openapi $WORKDIR/main COPY --from=builder /app/resource $WORKDIR/resource COPY --from=builder /app/manifest/i18n $WORKDIR/manifest/i18n -COPY --from=builder /app/build/build_config.yaml $WORKDIR/config/config.yaml +COPY --from=builder /app/build/config.example.yaml $WORKDIR/config/config.yaml RUN mkdir -p $WORKDIR/config RUN chmod +x $WORKDIR/main diff --git a/build/build_config.yaml b/build/config.example.yaml similarity index 82% rename from build/build_config.yaml rename to build/config.example.yaml index 05df252..ae56944 100644 --- a/build/build_config.yaml +++ b/build/config.example.yaml @@ -33,7 +33,7 @@ database: level: "all" stdout: true default: - link: "mysql:${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST}:3306)/db_iotlcm?charset=utf8mb4&parseTime=True&loc=Asia%2FShanghai" + link: "${DB_DSN}" debug: true charset: "utf8mb4" dryRun: false @@ -49,9 +49,9 @@ redis: default: mode: "single" sentinelMasterName: "iotlcm-master" - address: "192.0.2.29:6379" + address: "127.0.0.1:6379" db: 0 - pass: "${REDIS_PASSWORD}" + pass: "${SERVICE_PASSWORD}" minIdle: 5 maxIdle: 30 maxActive: 5000 @@ -70,4 +70,4 @@ upstream: rabbitmq: enabled: true - dsn: "amqp://${MQ_USER}:${MQ_PASSWORD}@${MQ_HOST}/" + dsn: "${SERVICE_DSN}" diff --git a/docs/openapi-permission-rollout.md b/docs/openapi-permission-rollout.md new file mode 100644 index 0000000..035d0e2 --- /dev/null +++ b/docs/openapi-permission-rollout.md @@ -0,0 +1,58 @@ +# v1.0.4 权限修复上线说明 + +受保护的 V3 接口仅在资源已启用、API 账号已启用、账号已分配权限组且权限组绑定该资源时放行。未登记资源、资源停用、账号不可用、未绑定权限组一律拒绝,不降级放行。 + +## 错误码 + +| 码 | 含义 | 触发条件 | 排查方向 | +|---|---|---|---| +| `10014` | 没有权限 | 资源未登记、资源停用、账号停用/不存在、账号无权限组、权限组未绑定该资源 | 业务与授权配置问题:查 `t_api_resource`、`t_api`、`t_api_group_resource` | +| `10016` | 权限校验失败 | 权限数据查询本身出错(如 `t_api_resource` 查询失败) | **系统侧故障**:查数据库连通性与表结构,不要按授权问题处理 | + +两个码必须区分:数据库抖动时若复用 `10014`,运维会把系统故障误判成客户未授权。 + +## 上线前 + +1. 执行资源登记脚本 `iotlcm-database/SQL/20261016_openapi_resource_register.sql`。共 24 条 V3 路由,扣除 2 条取 token 入口后为 22 条受保护路由:**登记 15 条**,另 7 条已决定下线(`/common/*` 6 条 + `/change/traffic-cutoff-config` 1 条)。脚本幂等可重复执行,且不改动既有 `status`、`api_code`、`method`、`path`。 + 执行顺序:只读核对 → 登记(第 1 段)→ 计数校验应为 15 → 按实际授权范围绑定(第 3 段)。 +2. 检查正在使用接口的账号对应 `t_api.group_id`,以及 `t_api_group_resource` 绑定。按已确认的授权范围补齐,**不能将所有资源自动赋给所有权限组**——那是扩大授权,属于安全倒退。 +3. 资源登记使用完整请求路径与正确方法(`method=1` 即 POST)。查询与变更的 `traffic-cutoff-config` 路径前缀不同,分别登记。 +4. 在验证环境检查:已授权接口正常;未登记/未授权/停用资源拒绝返回 `10014`;账号停用或无权限组拒绝;权限数据查询失败返回 `10016`。确认全部在用账号与接口后再部署生产。 + +## 免登录路径 + +`/openapi/v3/query/token` 与 `/openapi/v3/query/operator-token` 由配置 `router.exceptLogin` 控制,中间件内已无硬编码白名单。部署配置必须保留这两条,否则取 token 接口自身会被鉴权拦截而无法调用。 + +已确认 dev / preview / preview2 / prod 四套配置均含这两条。 + +## 重复路由的处置决定 + +代码中存在 12 条功能重叠的路由(`/common` 与 `/change` 各 6 条为同义路径)。判定分两层:先看**对外文档是否发布过**(发布过的必须保住),再看**业务是否确认在用**(业务确认不用的才硬删除)。 + +| 路径 | 决定 | 依据 | +|---|---|---| +| `/change/traffic-cutoff-config` | **下线**(不登记) | 从未写入对外文档(原始 common.md 只发布 4 个接口);与 `/change/batch-sim-traffic-cutoff` 参数类型、实现完全相同,控制器代码逐行重复,客户迁移无需改报文体;尾路径与只读的 `/query/traffic-cutoff-config` 同名,最易误调 | +| `/common/*`(6 条) | **已删除**(代码级,返回 404) | 业务确认真实客户只走 `/change/`,从不使用 `/common/`;该前缀是新增 `/change` 分组时未删旧分组的遗留,从未作为对外接口发布(原始 `common.md` 只发布 4 个 `/change` 接口) | +| `/change/renew` | **保留,登记授权,待观察** | 08-21 建立、09-10 才新增标准入口,存在早期接入客户;且入参只收 `cards[]`,与 `batch-sim-subscribe`(兼容平铺 `iccid[]`)不等价,不能直接判定为重复 | +| `/change/sim-subscribe`、`/change/sim-traffic-cutoff`(单卡)与对应批量接口 | **保留** | 已对外文档化,且同步单卡与异步批次是两套实现,粒度不同,非重复 | + +两种下线方式的差别: + +| | `/common/*` | `/change/traffic-cutoff-config` | +|---|---|---| +| 手段 | 删除 `internal/router/common.go`,`router.go` 不再调用 `Common()` | 不登记资源、不授权 | +| 客户端表现 | `404`(路由不存在) | `10014`(没有权限) | +| 恢复成本 | 需重新发版恢复路由,并补登记 6 条资源与授权 | 执行 SQL 文末的恢复语句即可,无需发版 | +| 选择理由 | 业务已确认无客户,该前缀无文档包袱,继续保留只会放大接口表面积与登记/授权工作量 | 参数与标准入口完全一致,但缺少「无人在用」的确认,需保住可逆性 | + +`/change/renew` 上线后查调用日志,确认无调用再走「不登记」方式下线。 + +注意:`g.Meta` 的 `deprecated` 标签在 GoFrame v2.9.6 中不被解析,**没有运行时或文档生成效果**,不能作为废弃告知手段。对外废弃说明由 `openapi-docs` 承担。 + +## 回归验证 + +``` +go test ./internal/logic/middleware -count=1 +``` + +测试使用内存 SQLite,覆盖:数字/文本方法登记、路径规范化与末尾斜杠、未登记资源、方法不匹配、资源停用、缺失权限绑定、兼容入口独立授权(登记但未授权仍拒绝)、账号停用/无权限组/不存在、token 路径不在中间件白名单内,以及权限数据查询失败必须返回错误而非静默放行。 diff --git a/internal/consts/code.go b/internal/consts/code.go index 49fb677..5a49c0a 100644 --- a/internal/consts/code.go +++ b/internal/consts/code.go @@ -1,7 +1,7 @@ // Package consts // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package consts @@ -34,8 +34,10 @@ var ( CodeLoginExpired = gcode.New(10012, "登录已过期", nil) // 部门下有子部门,不能删除 CodeDeptHasSub = gcode.New(10013, "部门下有子部门,不能删除", nil) - // 没有权限 + // 没有权限(业务判定:资源未登记、资源停用、账号不可用或未授权) CodeNoPermission = gcode.New(10014, "没有权限", nil) // 无效Token CodeInvalidToken = gcode.New(10015, "无效Token", nil) + // 权限校验失败(系统侧故障:权限数据查询异常,区别于 10014 无权限,避免误判为授权问题) + CodePermissionCheckFailed = gcode.New(10016, "权限校验失败", nil) ) diff --git a/internal/consts/config.go b/internal/consts/config.go index b6bf46d..6ac44c7 100644 --- a/internal/consts/config.go +++ b/internal/consts/config.go @@ -1,7 +1,7 @@ // Package consts // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package consts diff --git a/internal/consts/consts.go b/internal/consts/consts.go index da0878d..8b6530f 100644 --- a/internal/consts/consts.go +++ b/internal/consts/consts.go @@ -1,7 +1,7 @@ // Package consts // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package consts diff --git a/internal/consts/event.go b/internal/consts/event.go index d568d9b..d38efcc 100644 --- a/internal/consts/event.go +++ b/internal/consts/event.go @@ -1,7 +1,7 @@ // Package consts // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package consts diff --git a/internal/consts/http.go b/internal/consts/http.go index 6db02b7..166107f 100644 --- a/internal/consts/http.go +++ b/internal/consts/http.go @@ -1,7 +1,7 @@ // Package consts // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package consts diff --git a/internal/consts/mcache.go b/internal/consts/mcache.go index 65f7e54..cf8d597 100644 --- a/internal/consts/mcache.go +++ b/internal/consts/mcache.go @@ -1,7 +1,7 @@ // Package consts // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package consts diff --git a/internal/consts/queue.go b/internal/consts/queue.go index fa27f9e..e5e1027 100644 --- a/internal/consts/queue.go +++ b/internal/consts/queue.go @@ -1,7 +1,7 @@ // Package consts // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package consts diff --git a/internal/consts/system.go b/internal/consts/system.go index c12cf33..2e2172c 100644 --- a/internal/consts/system.go +++ b/internal/consts/system.go @@ -1,7 +1,7 @@ // Package consts // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package consts diff --git a/internal/consts/websocket.go b/internal/consts/websocket.go index 9c49716..e26f8ff 100644 --- a/internal/consts/websocket.go +++ b/internal/consts/websocket.go @@ -1,7 +1,7 @@ // Package consts // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package consts diff --git a/internal/library/bcache/bcache.go b/internal/library/bcache/bcache.go index 083c8a3..ea55bf0 100644 --- a/internal/library/bcache/bcache.go +++ b/internal/library/bcache/bcache.go @@ -1,6 +1,6 @@ // Package bcache // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package bcache diff --git a/internal/library/cache/cache.go b/internal/library/cache/cache.go index 09800a3..d81a11d 100644 --- a/internal/library/cache/cache.go +++ b/internal/library/cache/cache.go @@ -1,7 +1,7 @@ // Package cache // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package cache diff --git a/internal/library/cache/file/file.go b/internal/library/cache/file/file.go index 3fdb7ba..9bbdfef 100644 --- a/internal/library/cache/file/file.go +++ b/internal/library/cache/file/file.go @@ -1,7 +1,7 @@ // Package file // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package file diff --git a/internal/library/contexts/contexts.go b/internal/library/contexts/contexts.go index 97e6e1a..9bafd43 100644 --- a/internal/library/contexts/contexts.go +++ b/internal/library/contexts/contexts.go @@ -1,7 +1,7 @@ // Package contexts // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package contexts diff --git a/internal/library/mcache/mcache.go b/internal/library/mcache/mcache.go index e17955b..ce280e6 100644 --- a/internal/library/mcache/mcache.go +++ b/internal/library/mcache/mcache.go @@ -1,7 +1,7 @@ // Package mcache // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // 内存缓存管理 package mcache diff --git a/internal/library/xgorm/dao.go b/internal/library/xgorm/dao.go index e2e964c..8522588 100644 --- a/internal/library/xgorm/dao.go +++ b/internal/library/xgorm/dao.go @@ -1,7 +1,7 @@ // package xgorm // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package xgorm diff --git a/internal/library/xgorm/dao_tree.go b/internal/library/xgorm/dao_tree.go index 81ffa9e..a4187ab 100644 --- a/internal/library/xgorm/dao_tree.go +++ b/internal/library/xgorm/dao_tree.go @@ -1,7 +1,7 @@ // package xgorm // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package xgorm diff --git a/internal/library/xgorm/gorm_model/gorm_tree.go b/internal/library/xgorm/gorm_model/gorm_tree.go index ada0e31..3cb93c4 100644 --- a/internal/library/xgorm/gorm_model/gorm_tree.go +++ b/internal/library/xgorm/gorm_model/gorm_tree.go @@ -1,7 +1,7 @@ // package gormmodel // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package gormmodel diff --git a/internal/library/xgorm/handler/filter_auth.go b/internal/library/xgorm/handler/filter_auth.go index aa00153..0f236e1 100644 --- a/internal/library/xgorm/handler/filter_auth.go +++ b/internal/library/xgorm/handler/filter_auth.go @@ -1,7 +1,7 @@ // package handler // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package handler diff --git a/internal/library/xgorm/handler/force_cache.go b/internal/library/xgorm/handler/force_cache.go index 3fc7e75..613a474 100644 --- a/internal/library/xgorm/handler/force_cache.go +++ b/internal/library/xgorm/handler/force_cache.go @@ -1,7 +1,7 @@ // package handler // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package handler diff --git a/internal/library/xgorm/handler/handler.go b/internal/library/xgorm/handler/handler.go index e7903bb..189cfe5 100644 --- a/internal/library/xgorm/handler/handler.go +++ b/internal/library/xgorm/handler/handler.go @@ -1,7 +1,7 @@ // package handler // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package handler diff --git a/internal/library/xgorm/handler/tenant.go b/internal/library/xgorm/handler/tenant.go index 32d786d..3294eda 100644 --- a/internal/library/xgorm/handler/tenant.go +++ b/internal/library/xgorm/handler/tenant.go @@ -1,7 +1,7 @@ // package handler // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package handler diff --git a/internal/library/xgorm/hook/member.go b/internal/library/xgorm/hook/member.go index 90279c9..5fa6951 100644 --- a/internal/library/xgorm/hook/member.go +++ b/internal/library/xgorm/hook/member.go @@ -1,7 +1,7 @@ // package hook // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package hook diff --git a/internal/logic/middleware/middleware.go b/internal/logic/middleware/middleware.go index 2be601d..979e083 100644 --- a/internal/logic/middleware/middleware.go +++ b/internal/logic/middleware/middleware.go @@ -2,6 +2,8 @@ package middleware import ( "context" + "database/sql" + "errors" "net/http" "slices" "strconv" @@ -138,7 +140,13 @@ func (s *sMiddleware) ApiAuth(r *ghttp.Request) { response.JsonExit(r, gcode.CodeNotAuthorized.Code(), consts.CodeLoginExpired.Message()) return } - if !s.hasOpenApiPermission(ctx, r.Method, path) { + allowed, err := s.hasOpenApiPermission(ctx, r.Method, path) + if err != nil { + g.Log().Errorf(ctx, "sMiddleware.ApiAuth permission check failed, method: %s, path: %s, err: %v", r.Method, path, err) + response.JsonExit(r, consts.CodePermissionCheckFailed.Code(), consts.CodePermissionCheckFailed.Message()) + return + } + if !allowed { response.JsonExit(r, consts.CodeNoPermission.Code(), consts.CodeNoPermission.Message()) return } @@ -162,33 +170,36 @@ func openApiMethodValues(method string) []string { return values } -func (s *sMiddleware) hasOpenApiPermission(ctx context.Context, method, path string) bool { +// hasOpenApiPermission 判定当前 API 账号对指定路由是否已授权。 +// 返回值 error 仅代表权限数据查询本身的系统故障,与「无权限」(false, nil) 严格区分: +// 调用方对 error 返回系统异常码,对 false 返回无权限码,避免把数据库故障误报成授权问题。 +// 未登记资源、资源停用、账号不可用、未绑定权限组均按无权限处理。 +func (s *sMiddleware) hasOpenApiPermission(ctx context.Context, method, path string) (bool, error) { agentUser := contexts.GetAgentUser(ctx) if agentUser == nil { - return false - } - if path == "/openapi/v3/query/token" { - return true + return false, nil } path = strings.TrimSpace(path) if path != "/" { path = strings.TrimRight(path, "/") } + // 每条受保护路由(含 /common 兼容前缀的别名路由)都必须显式登记资源并完成授权, + // 资源查询失败不得降级为放行。 var apiResource entity.TApiResource - if err := dao.TApiResource.Ctx(ctx). + err := dao.TApiResource.Ctx(ctx). WhereIn(dao.TApiResource.Columns().Method, openApiMethodValues(method)). Where(dao.TApiResource.Columns().Path, path). - Scan(&apiResource); err != nil { - g.Log().Warningf(ctx, "sMiddleware.hasOpenApiPermission resource not configured, method: %s, path: %s, err: %v", method, path, err) - return true + Scan(&apiResource) + if err != nil && !errors.Is(err, sql.ErrNoRows) { + return false, gerror.Wrapf(err, "query t_api_resource failed, method: %s, path: %s", method, path) } - if apiResource.Id == 0 { + if err != nil || apiResource.Id == 0 { g.Log().Warningf(ctx, "sMiddleware.hasOpenApiPermission resource not configured, method: %s, path: %s", method, path) - return true + return false, nil } if apiResource.Status == 1 { - return false + return false, nil } var tApi entity.TApi @@ -199,19 +210,22 @@ func (s *sMiddleware) hasOpenApiPermission(ctx context.Context, method, path str apiMod = apiMod.Where(dao.TApi.Columns().AppKey, agentUser.AppKey) } else { g.Log().Warningf(ctx, "sMiddleware.hasOpenApiPermission api identity is empty, resourceApiId: %d, path: %s", apiResource.Id, path) - return false + return false, nil } if err := apiMod.Scan(&tApi); err != nil { - g.Log().Errorf(ctx, "sMiddleware.hasOpenApiPermission scan t_api error: %v", err) - return false + if errors.Is(err, sql.ErrNoRows) { + g.Log().Warningf(ctx, "sMiddleware.hasOpenApiPermission t_api not found, resourceApiId: %d, path: %s", apiResource.Id, path) + return false, nil + } + return false, gerror.Wrapf(err, "query t_api failed, resourceApiId: %d, path: %s", apiResource.Id, path) } if tApi.Id == 0 || tApi.Status == 1 { g.Log().Warningf(ctx, "sMiddleware.hasOpenApiPermission t_api unavailable, tApiId: %d, status: %d, resourceApiId: %d, path: %s", tApi.Id, tApi.Status, apiResource.Id, path) - return false + return false, nil } if tApi.GroupId <= 0 { g.Log().Warningf(ctx, "sMiddleware.hasOpenApiPermission groupId is empty, tApiId: %d, appKey: %s, resourceApiId: %d, path: %s", tApi.Id, tApi.AppKey, apiResource.Id, path) - return false + return false, nil } count, err := dao.TApiGroupResource.Ctx(ctx). @@ -219,10 +233,9 @@ func (s *sMiddleware) hasOpenApiPermission(ctx context.Context, method, path str Where(dao.TApiGroupResource.Columns().ApiId, apiResource.Id). Count() if err != nil { - g.Log().Errorf(ctx, "sMiddleware.hasOpenApiPermission scan relation error: %v", err) - return false + return false, gerror.Wrapf(err, "query t_api_group_resource failed, groupId: %d, resourceApiId: %d, path: %s", tApi.GroupId, apiResource.Id, path) } - return count > 0 + return count > 0, nil } func (m *sMiddleware) OldResponseHandler(r *ghttp.Request) { diff --git a/internal/logic/middleware/permission_test.go b/internal/logic/middleware/permission_test.go new file mode 100644 index 0000000..9d0247a --- /dev/null +++ b/internal/logic/middleware/permission_test.go @@ -0,0 +1,117 @@ +package middleware + +import ( + "context" + "testing" + + _ "github.com/gogf/gf/contrib/drivers/sqlite/v2" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" + + "git.5iot.com/iotlcm-public/iotlcm-openapi/internal/library/contexts" + "git.5iot.com/iotlcm-public/iotlcm-openapi/internal/model" +) + +func TestOpenAPIPermission(t *testing.T) { + ctx := contexts.Set(context.Background(), &model.Context{ + AgentUser: &model.BaseClaimsApi{ApiId: 1, AppKey: "test-key"}, + }) + 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) }) + if err := g.DB().GetCore().ClearTableFieldsAll(ctx); err != nil { + t.Fatal(err) + } + exec := func(sql string) { + t.Helper() + if _, err := g.DB().Exec(ctx, sql); err != nil { + t.Fatal(err) + } + } + exec(`CREATE TABLE t_api_resource (id INTEGER PRIMARY KEY, method TEXT, path TEXT, status INTEGER)`) + exec(`CREATE TABLE t_api (id INTEGER PRIMARY KEY, app_key TEXT, group_id INTEGER, status INTEGER)`) + exec(`CREATE TABLE t_api_group_resource (group_id INTEGER, api_id INTEGER)`) + exec(`INSERT INTO t_api VALUES (1, 'test-key', 7, 0)`) + exec(`INSERT INTO t_api_resource VALUES + (1, '1', '/openapi/v3/change/sim-subscribe', 0), + (2, 'POST', '/openapi/v3/query/sim-info', 0), + (3, '1', '/openapi/v3/query/sim-status', 1), + (4, '1', '/openapi/v3/query/sim-imei-batch', 0)`) + exec(`INSERT INTO t_api_group_resource VALUES (7, 1), (7, 2), (7, 3)`) + + middleware := New() + check := func(t *testing.T, method, path string) (bool, error) { + t.Helper() + return middleware.hasOpenApiPermission(ctx, method, path) + } + + for _, tc := range []struct { + name, method, path string + want bool + }{ + {"authorized numeric method", "POST", "/openapi/v3/change/sim-subscribe", true}, + {"authorized text method", "POST", "/openapi/v3/query/sim-info", true}, + {"normalized path", "post", "/openapi/v3/query/sim-info/", true}, + {"unregistered resource", "POST", "/openapi/v3/query/batch-status", false}, + {"legacy alias path never inherits grants", "POST", "/openapi/v3/common/sim-subscribe", false}, + {"wrong method", "GET", "/openapi/v3/change/sim-subscribe", false}, + {"disabled resource", "POST", "/openapi/v3/query/sim-status", false}, + {"missing group binding", "POST", "/openapi/v3/query/sim-imei-batch", false}, + } { + t.Run(tc.name, func(t *testing.T) { + got, err := check(t, tc.method, tc.path) + if err != nil { + t.Fatalf("business denial must not report a system failure: %v", err) + } + if got != tc.want { + t.Fatalf("permission = %v, want %v", got, tc.want) + } + }) + } + + // Token endpoints are exempted by router.exceptLogin only; the middleware must not + // carry its own whitelist, otherwise the two lists drift apart. + if got, err := check(t, "POST", "/openapi/v3/query/token"); err != nil || got { + t.Fatalf("token path must not be whitelisted inside middleware, got=%v err=%v", got, err) + } + + // The /common alias prefix has been removed from the router (router/common.go deleted). + // Keep the path-level guard anyway: if an alias is ever re-introduced, it must still be + // registered and granted on its own full path instead of inheriting /change permissions. + exec(`INSERT INTO t_api_resource VALUES (5, '1', '/openapi/v3/common/sim-subscribe', 0)`) + if got, err := check(t, "POST", "/openapi/v3/common/sim-subscribe"); err != nil || got { + t.Fatalf("registered compatibility route without grant must be denied, got=%v err=%v", got, err) + } + exec(`INSERT INTO t_api_group_resource VALUES (7, 5)`) + if got, err := check(t, "POST", "/openapi/v3/common/sim-subscribe"); err != nil || !got { + t.Fatalf("explicitly granted compatibility route must be allowed, got=%v err=%v", got, err) + } + + // Unusable accounts are a business denial, not a system failure. + for _, sql := range []string{ + `UPDATE t_api SET status = 1`, + `UPDATE t_api SET status = 0, group_id = 0`, + `DELETE FROM t_api`, + } { + exec(sql) + got, err := check(t, "POST", "/openapi/v3/query/sim-info") + if err != nil { + t.Fatalf("account rejection must not be reported as a system failure after %s: %v", sql, err) + } + if got { + t.Fatalf("invalid account allowed after %s", sql) + } + } + + // A broken permission lookup is a system failure: it must deny AND surface the error, + // so callers can answer 10016 instead of misreporting it as 10014 no-permission. + exec(`DROP TABLE t_api_resource`) + got, err := check(t, "POST", "/openapi/v3/query/sim-info") + if err == nil { + t.Fatal("resource lookup failure must return an error") + } + if got { + t.Fatal("resource lookup failure must deny access") + } +} diff --git a/internal/logic/query/batch_imei_test.go b/internal/logic/query/batch_imei_test.go index 3855af7..2086bfe 100644 --- a/internal/logic/query/batch_imei_test.go +++ b/internal/logic/query/batch_imei_test.go @@ -22,11 +22,10 @@ import ( // setupImeiBatchDB 建一张最小可用的卡表并灌入覆盖各分支的样本数据。 // // 样本设计(对齐 §7 测试场景): -// -// CARD-A 有 imei → 正常命中 -// CARD-B imei 为空 → 卡存在但上游未上报值 -// CARD-C 有 imei → 正常命中(入库带的值) -// CARD-D 属于另一个部门 → 数据权限过滤后视为 notFound +// CARD-A 有 imei → 正常命中 +// CARD-B imei 为空 → 卡存在但上游未上报值 +// CARD-C 有 imei → 正常命中(入库带的值) +// CARD-D 属于另一个部门 → 数据权限过滤后视为 notFound func setupImeiBatchDB(t *testing.T, ctx context.Context) { t.Helper() if err := gdb.SetConfig(gdb.Config{"default": gdb.ConfigGroup{{Type: "sqlite", Link: "sqlite::@file(:memory:)", MaxOpenConnCount: 1}}}); err != nil { diff --git a/internal/logic/query/token.go b/internal/logic/query/token.go index 9a8ba37..b5323df 100644 --- a/internal/logic/query/token.go +++ b/internal/logic/query/token.go @@ -286,7 +286,7 @@ func (s *sQueryToken) GenerateToken(ctx context.Context, customer *model.CustomC ets := g.Cfg().MustGet(ctx, "jwt.expiresTime", "3650d").String() bts := g.Cfg().MustGet(ctx, "jwt.bufferTime", "1d").String() iss := g.Cfg().MustGet(ctx, "jwt.issuer", "JieIOTAPI").String() - sk := g.Cfg().MustGet(ctx, "jwt.signingKey", "${JWT_SIGNING_KEY}").String() + sk := g.Cfg().MustGet(ctx, "jwt.signingKey", "49c54195e73304e74a8429b178965865").String() et, _ := utils.ParseDuration(ets) bt, _ := utils.ParseDuration(bts) g.Log().Infof(ctx, "GenerateToken: customer:%+v, et:%s, bt:%s, iss:%s", customer, et, bt, iss) @@ -336,7 +336,7 @@ func (s *sQueryToken) GenerateToken(ctx context.Context, customer *model.CustomC // GenerateShortToken 生成短令牌 func (s *sQueryToken) GenerateShortToken(ctx context.Context, tokenUuid string) (token string, err error) { - sk := g.Cfg().MustGet(ctx, "jwt.signingKey", "${JWT_SIGNING_KEY}").String() + sk := g.Cfg().MustGet(ctx, "jwt.signingKey", "49c54195e73304e74a8429b178965865").String() shortToken := jwt.NewWithClaims(jwt.SigningMethodHS256, &model.ApiTokenClaims{ UUID: tokenUuid, }) @@ -346,7 +346,7 @@ func (s *sQueryToken) GenerateShortToken(ctx context.Context, tokenUuid string) // 解析Token func (s *sQueryToken) ParseToken(ctx context.Context, token string) (claims *model.CustomClaimsApi, err error) { - sk := g.Cfg().MustGet(ctx, "jwt.signingKey", "${JWT_SIGNING_KEY}").String() + sk := g.Cfg().MustGet(ctx, "jwt.signingKey", "49c54195e73304e74a8429b178965865").String() t, err := jwt.ParseWithClaims(token, &model.ApiTokenClaims{}, func(token *jwt.Token) (interface{}, error) { return []byte(sk), nil }) @@ -386,7 +386,7 @@ func (s *sQueryToken) ParseToken(ctx context.Context, token string) (claims *mod // 删除Token func (s *sQueryToken) DeleteToken(ctx context.Context, token string) (err error) { - sk := g.Cfg().MustGet(ctx, "jwt.signingKey", "${JWT_SIGNING_KEY}").String() + sk := g.Cfg().MustGet(ctx, "jwt.signingKey", "49c54195e73304e74a8429b178965865").String() t, err := jwt.ParseWithClaims(token, &model.ApiTokenClaims{}, func(token *jwt.Token) (interface{}, error) { return []byte(sk), nil }) diff --git a/internal/logic/query/traffic_cutoff_config.go b/internal/logic/query/traffic_cutoff_config.go index 95e1ba1..0d3bd86 100644 --- a/internal/logic/query/traffic_cutoff_config.go +++ b/internal/logic/query/traffic_cutoff_config.go @@ -4,11 +4,11 @@ import ( "context" "strings" + "github.com/gogf/gf/v2/errors/gerror" "git.5iot.com/iotlcm-public/iotlcm-openapi/internal/dao" "git.5iot.com/iotlcm-public/iotlcm-openapi/internal/model" "git.5iot.com/iotlcm-public/iotlcm-openapi/internal/model/entity" "git.5iot.com/iotlcm-public/iotlcm-openapi/internal/service" - "github.com/gogf/gf/v2/errors/gerror" ) const queryTrafficCutoffConfigMaxCards = 1000 diff --git a/internal/model/batch_main.go b/internal/model/batch_main.go index 613890b..33df9e3 100644 --- a/internal/model/batch_main.go +++ b/internal/model/batch_main.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/context.go b/internal/model/context.go index 2562215..4682045 100644 --- a/internal/model/context.go +++ b/internal/model/context.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/genin/test_demo.go b/internal/model/genin/test_demo.go index 1a82bf3..e476f1f 100644 --- a/internal/model/genin/test_demo.go +++ b/internal/model/genin/test_demo.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package genin diff --git a/internal/model/monitor_server.go b/internal/model/monitor_server.go index 2be2376..21f03b2 100644 --- a/internal/model/monitor_server.go +++ b/internal/model/monitor_server.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/query_sim.go b/internal/model/query_sim.go index 25acc14..107eb47 100644 --- a/internal/model/query_sim.go +++ b/internal/model/query_sim.go @@ -101,7 +101,7 @@ type QuerySimBatchCard struct { // QuerySimStatusBatchParam 批量卡状态查询入参 type QuerySimStatusBatchParam struct { - AppId string `json:"appId" v:"required#appId不能为空" dc:"平台API应用ID"` + AppId string `json:"appId" v:"required#appId不能为空" dc:"平台API应用ID"` Cards []QuerySimBatchCard `json:"cards" v:"required#查询卡不能为空" dc:"查询卡列表"` } @@ -109,7 +109,7 @@ type QuerySimStatusBatchParam struct { type QuerySimStatusBatchItem struct { Matched bool `json:"matched"` Iccid string `json:"iccid,omitempty"` - LifeCycle int `json:"lifeCycle"` // 卡状态编码(平台内部枚举) + LifeCycle int `json:"lifeCycle"` // 卡状态编码(平台内部枚举) LifeCycleName string `json:"lifeCycleName,omitempty"` ErrorCode string `json:"errorCode,omitempty"` ErrorMessage string `json:"errorMessage,omitempty"` @@ -125,7 +125,7 @@ type QuerySimStatusBatchOutput struct { // QuerySimUsageBatchParam 批量流量查询入参 type QuerySimUsageBatchParam struct { - AppId string `json:"appId" v:"required#appId不能为空" dc:"平台API应用ID"` + AppId string `json:"appId" v:"required#appId不能为空" dc:"平台API应用ID"` Cards []QuerySimBatchCard `json:"cards" v:"required#查询卡不能为空" dc:"查询卡列表"` } @@ -133,8 +133,8 @@ type QuerySimUsageBatchParam struct { type QuerySimUsageBatchItem struct { Matched bool `json:"matched"` Iccid string `json:"iccid,omitempty"` - UseUnit string `json:"useUnit"` // 流量单位,固定为 MB - UseAmount float64 `json:"useAmount"` // 当前周期已用流量,单位 MB + UseUnit string `json:"useUnit"` // 流量单位,固定为 MB + UseAmount float64 `json:"useAmount"` // 当前周期已用流量,单位 MB ErrorCode string `json:"errorCode,omitempty"` ErrorMessage string `json:"errorMessage,omitempty"` } @@ -151,7 +151,7 @@ type QuerySimUsageBatchOutput struct { // QuerySimImeiBatchParam 批量 IMEI 查询入参(与 sim-status-batch / sim-usage-batch 同构) type QuerySimImeiBatchParam struct { - AppId string `json:"appId" v:"required#appId不能为空" dc:"平台API应用ID"` + AppId string `json:"appId" v:"required#appId不能为空" dc:"平台API应用ID"` Cards []QuerySimBatchCard `json:"cards" v:"required#查询卡不能为空" dc:"查询卡列表"` } diff --git a/internal/model/request/common.go b/internal/model/request/common.go index e816e9d..467192f 100644 --- a/internal/model/request/common.go +++ b/internal/model/request/common.go @@ -1,7 +1,7 @@ // package request // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package request diff --git a/internal/model/response/common.go b/internal/model/response/common.go index 9f9000a..472fd7a 100644 --- a/internal/model/response/common.go +++ b/internal/model/response/common.go @@ -1,7 +1,7 @@ // package response // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package response diff --git a/internal/model/sys_auth.go b/internal/model/sys_auth.go index 1b12fce..bc76585 100644 --- a/internal/model/sys_auth.go +++ b/internal/model/sys_auth.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/sys_client.go b/internal/model/sys_client.go index d5ba092..9a10de7 100644 --- a/internal/model/sys_client.go +++ b/internal/model/sys_client.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/sys_config.go b/internal/model/sys_config.go index 935ed1f..1193387 100644 --- a/internal/model/sys_config.go +++ b/internal/model/sys_config.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/sys_dept.go b/internal/model/sys_dept.go index 6d11125..a41bda7 100644 --- a/internal/model/sys_dept.go +++ b/internal/model/sys_dept.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/sys_dict.go b/internal/model/sys_dict.go index a0852fc..abaffaa 100644 --- a/internal/model/sys_dict.go +++ b/internal/model/sys_dict.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/sys_job.go b/internal/model/sys_job.go index 43288fd..566e503 100644 --- a/internal/model/sys_job.go +++ b/internal/model/sys_job.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/sys_logininfor.go b/internal/model/sys_logininfor.go index 631bb37..06110f3 100644 --- a/internal/model/sys_logininfor.go +++ b/internal/model/sys_logininfor.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/sys_menu.go b/internal/model/sys_menu.go index 4ff0732..a5b6e03 100644 --- a/internal/model/sys_menu.go +++ b/internal/model/sys_menu.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/sys_notice.go b/internal/model/sys_notice.go index f1a4e82..d2e186f 100644 --- a/internal/model/sys_notice.go +++ b/internal/model/sys_notice.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/sys_notice_user.go b/internal/model/sys_notice_user.go index 86e5ae6..727978d 100644 --- a/internal/model/sys_notice_user.go +++ b/internal/model/sys_notice_user.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/sys_oper_log.go b/internal/model/sys_oper_log.go index 15d716d..501f3ff 100644 --- a/internal/model/sys_oper_log.go +++ b/internal/model/sys_oper_log.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/sys_oss.go b/internal/model/sys_oss.go index 88288dc..59ea086 100644 --- a/internal/model/sys_oss.go +++ b/internal/model/sys_oss.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/sys_oss_config.go b/internal/model/sys_oss_config.go index 2fb4120..1e29446 100644 --- a/internal/model/sys_oss_config.go +++ b/internal/model/sys_oss_config.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/sys_post.go b/internal/model/sys_post.go index 42b5ff6..18edab8 100644 --- a/internal/model/sys_post.go +++ b/internal/model/sys_post.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/sys_role.go b/internal/model/sys_role.go index 99ca519..4c1eb38 100644 --- a/internal/model/sys_role.go +++ b/internal/model/sys_role.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model @@ -48,41 +48,41 @@ type SysRoleViewParam struct { } type SysRoleViewModel struct { - RoleId int64 `json:"roleId" orm:"role_id" description:"角色ID"` - TenantId string `json:"tenantId" orm:"tenant_id" description:"租户编号"` - DeptId int64 `json:"deptId" orm:"dept_id" description:"部门组织id"` - RoleName string `json:"roleName" orm:"role_name" description:"角色名称"` - RoleKey string `json:"roleKey" orm:"role_key" description:"角色权限字符串"` - RoleSort int `json:"roleSort" orm:"role_sort" description:"显示顺序"` - DataScope string `json:"dataScope" orm:"data_scope" description:"数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限 5:仅本人数据权限 6:本部门及以下或本人数据权限 7:本部门及下一级数据权限)"` - MenuCheckStrictly int `json:"menuCheckStrictly" orm:"menu_check_strictly" description:"菜单树选择项是否关联显示"` - DeptCheckStrictly int `json:"deptCheckStrictly" orm:"dept_check_strictly" description:"部门树选择项是否关联显示"` - Status string `json:"status" orm:"status" description:"角色状态(0正常 1停用)"` - CreatedDept int64 `json:"createdDept" orm:"created_dept" description:"创建部门"` - CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` - Remark string `json:"remark" orm:"remark" description:"备注"` - MenuIds []int64 `json:"menuIds" orm:"menu_ids" description:"角色菜单ID列表"` + RoleId int64 `json:"roleId" orm:"role_id" description:"角色ID"` + TenantId string `json:"tenantId" orm:"tenant_id" description:"租户编号"` + DeptId int64 `json:"deptId" orm:"dept_id" description:"部门组织id"` + RoleName string `json:"roleName" orm:"role_name" description:"角色名称"` + RoleKey string `json:"roleKey" orm:"role_key" description:"角色权限字符串"` + RoleSort int `json:"roleSort" orm:"role_sort" description:"显示顺序"` + DataScope string `json:"dataScope" orm:"data_scope" description:"数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限 5:仅本人数据权限 6:本部门及以下或本人数据权限 7:本部门及下一级数据权限)"` + MenuCheckStrictly int `json:"menuCheckStrictly" orm:"menu_check_strictly" description:"菜单树选择项是否关联显示"` + DeptCheckStrictly int `json:"deptCheckStrictly" orm:"dept_check_strictly" description:"部门树选择项是否关联显示"` + Status string `json:"status" orm:"status" description:"角色状态(0正常 1停用)"` + CreatedDept int64 `json:"createdDept" orm:"created_dept" description:"创建部门"` + CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` + Remark string `json:"remark" orm:"remark" description:"备注"` + MenuIds []int64 `json:"menuIds" orm:"menu_ids" description:"角色菜单ID列表"` RoleMenuDataScopes map[int64]string `json:"roleMenuDataScopes" description:"角色菜单数据范围"` - DeptIds []int64 `json:"deptIds" orm:"dept_ids" description:"角色部门ID列表"` + DeptIds []int64 `json:"deptIds" orm:"dept_ids" description:"角色部门ID列表"` } type SysRoleAddParam struct { - RoleName string `json:"roleName" orm:"role_name" description:"角色名称"` - TenantId string `json:"tenantId" orm:"tenant_id" description:"租户编号"` - RoleKey string `json:"roleKey" orm:"role_key" description:"角色权限字符串"` - RoleSort int `json:"roleSort" orm:"role_sort" description:"显示顺序"` - DataScope string `json:"dataScope" orm:"data_scope" description:"数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限 5:仅本人数据权限 6:本部门及以下或本人数据权限 7:本部门及下一级数据权限)"` - MenuCheckStrictly int `json:"menuCheckStrictly" orm:"menu_check_strictly" description:"菜单树选择项是否关联显示"` - Status string `json:"status" orm:"status" description:"角色状态(0正常 1停用)"` - CreatedDept int64 `json:"createdDept" orm:"created_dept" description:"创建部门"` - CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建者"` - CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` - UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:"更新者"` - UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` - Remark string `json:"remark" orm:"remark" description:"备注"` - MenuIds []int64 `json:"menuIds" orm:"menu_ids" description:"菜单ID"` + RoleName string `json:"roleName" orm:"role_name" description:"角色名称"` + TenantId string `json:"tenantId" orm:"tenant_id" description:"租户编号"` + RoleKey string `json:"roleKey" orm:"role_key" description:"角色权限字符串"` + RoleSort int `json:"roleSort" orm:"role_sort" description:"显示顺序"` + DataScope string `json:"dataScope" orm:"data_scope" description:"数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限 5:仅本人数据权限 6:本部门及以下或本人数据权限 7:本部门及下一级数据权限)"` + MenuCheckStrictly int `json:"menuCheckStrictly" orm:"menu_check_strictly" description:"菜单树选择项是否关联显示"` + Status string `json:"status" orm:"status" description:"角色状态(0正常 1停用)"` + CreatedDept int64 `json:"createdDept" orm:"created_dept" description:"创建部门"` + CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建者"` + CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` + UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:"更新者"` + UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` + Remark string `json:"remark" orm:"remark" description:"备注"` + MenuIds []int64 `json:"menuIds" orm:"menu_ids" description:"菜单ID"` RoleMenuDataScopes map[int64]string `json:"roleMenuDataScopes" description:"角色菜单数据范围"` - DeptId *int64 `json:"deptId" orm:"dept_id" description:"部门组织id"` + DeptId *int64 `json:"deptId" orm:"dept_id" description:"部门组织id"` } type SysRoleAddModel struct { @@ -90,18 +90,18 @@ type SysRoleAddModel struct { } type SysRoleEditParam struct { - RoleId int64 `json:"roleId" orm:"role_id" description:"角色ID"` - RoleName *string `json:"roleName" orm:"role_name" description:"角色名称"` - RoleKey *string `json:"roleKey" orm:"role_key" description:"角色权限字符串"` - RoleSort *int `json:"roleSort" orm:"role_sort" description:"显示顺序"` - MenuCheckStrictly *int `json:"menuCheckStrictly" orm:"menu_check_strictly" description:"菜单树选择项是否关联显示"` - Status *string `json:"status" orm:"status" description:"角色状态(0正常 1停用)"` - UpdatedBy *int64 `json:"updatedBy" orm:"updated_by" description:"更新者"` - UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` - Remark *string `json:"remark" orm:"remark" description:"备注"` - MenuIds []int64 `json:"menuIds" orm:"menu_ids" description:"菜单ID"` + RoleId int64 `json:"roleId" orm:"role_id" description:"角色ID"` + RoleName *string `json:"roleName" orm:"role_name" description:"角色名称"` + RoleKey *string `json:"roleKey" orm:"role_key" description:"角色权限字符串"` + RoleSort *int `json:"roleSort" orm:"role_sort" description:"显示顺序"` + MenuCheckStrictly *int `json:"menuCheckStrictly" orm:"menu_check_strictly" description:"菜单树选择项是否关联显示"` + Status *string `json:"status" orm:"status" description:"角色状态(0正常 1停用)"` + UpdatedBy *int64 `json:"updatedBy" orm:"updated_by" description:"更新者"` + UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` + Remark *string `json:"remark" orm:"remark" description:"备注"` + MenuIds []int64 `json:"menuIds" orm:"menu_ids" description:"菜单ID"` RoleMenuDataScopes map[int64]string `json:"roleMenuDataScopes" description:"角色菜单数据范围"` - DeptId *int64 `json:"deptId" orm:"dept_id" description:"部门组织id"` + DeptId *int64 `json:"deptId" orm:"dept_id" description:"部门组织id"` } type SysRoleEditModel struct { diff --git a/internal/model/sys_social.go b/internal/model/sys_social.go index 1fd12e0..e39b5e6 100644 --- a/internal/model/sys_social.go +++ b/internal/model/sys_social.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/sys_tenant.go b/internal/model/sys_tenant.go index ff8439a..3790349 100644 --- a/internal/model/sys_tenant.go +++ b/internal/model/sys_tenant.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/sys_tenant_package.go b/internal/model/sys_tenant_package.go index 8623ec6..d00a7a5 100644 --- a/internal/model/sys_tenant_package.go +++ b/internal/model/sys_tenant_package.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/sys_user.go b/internal/model/sys_user.go index 5594173..cb544dd 100644 --- a/internal/model/sys_user.go +++ b/internal/model/sys_user.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/sys_user_online.go b/internal/model/sys_user_online.go index e9f56f7..f0fbb48 100644 --- a/internal/model/sys_user_online.go +++ b/internal/model/sys_user_online.go @@ -1,7 +1,7 @@ // package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package model diff --git a/internal/model/t_agent_balance.go b/internal/model/t_agent_balance.go index e0fc73a..6293478 100644 --- a/internal/model/t_agent_balance.go +++ b/internal/model/t_agent_balance.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_agent_enterprise.go b/internal/model/t_agent_enterprise.go index 0f1c2b9..aea26a0 100644 --- a/internal/model/t_agent_enterprise.go +++ b/internal/model/t_agent_enterprise.go @@ -1,7 +1,7 @@ // Package model // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_api.go b/internal/model/t_api.go index a5074b2..b02ecd6 100644 --- a/internal/model/t_api.go +++ b/internal/model/t_api.go @@ -1,7 +1,7 @@ // Package iotin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_api_group.go b/internal/model/t_api_group.go index 5043f8e..199ac09 100644 --- a/internal/model/t_api_group.go +++ b/internal/model/t_api_group.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_api_resource.go b/internal/model/t_api_resource.go index 9953e9e..44d27ba 100644 --- a/internal/model/t_api_resource.go +++ b/internal/model/t_api_resource.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_balance_detail.go b/internal/model/t_balance_detail.go index 982b216..770d0e8 100644 --- a/internal/model/t_balance_detail.go +++ b/internal/model/t_balance_detail.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_consume_account_month_bill.go b/internal/model/t_consume_account_month_bill.go index c799df2..e35fea2 100644 --- a/internal/model/t_consume_account_month_bill.go +++ b/internal/model/t_consume_account_month_bill.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_credit_detail.go b/internal/model/t_credit_detail.go index 6020697..52ec349 100644 --- a/internal/model/t_credit_detail.go +++ b/internal/model/t_credit_detail.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_cust_withdraw_account.go b/internal/model/t_cust_withdraw_account.go index af33770..bb1140d 100644 --- a/internal/model/t_cust_withdraw_account.go +++ b/internal/model/t_cust_withdraw_account.go @@ -1,7 +1,7 @@ // Package iotin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_division_code.go b/internal/model/t_division_code.go index d458967..348c81c 100644 --- a/internal/model/t_division_code.go +++ b/internal/model/t_division_code.go @@ -1,7 +1,7 @@ // Package iot // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_fin_commission_detail.go b/internal/model/t_fin_commission_detail.go index a3a8b27..958e4aa 100644 --- a/internal/model/t_fin_commission_detail.go +++ b/internal/model/t_fin_commission_detail.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_fin_withdrawable_change.go b/internal/model/t_fin_withdrawable_change.go index 388fdc1..eb2aee2 100644 --- a/internal/model/t_fin_withdrawable_change.go +++ b/internal/model/t_fin_withdrawable_change.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_finance_apply.go b/internal/model/t_finance_apply.go index e3375eb..fe3c63b 100644 --- a/internal/model/t_finance_apply.go +++ b/internal/model/t_finance_apply.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_finance_audit_record.go b/internal/model/t_finance_audit_record.go index a7c48af..88b7642 100644 --- a/internal/model/t_finance_audit_record.go +++ b/internal/model/t_finance_audit_record.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_profit_account_month_bill.go b/internal/model/t_profit_account_month_bill.go index d3e415d..b9c7170 100644 --- a/internal/model/t_profit_account_month_bill.go +++ b/internal/model/t_profit_account_month_bill.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_sim_card_bind_pkg.go b/internal/model/t_sim_card_bind_pkg.go index 905f9d3..4bd197a 100644 --- a/internal/model/t_sim_card_bind_pkg.go +++ b/internal/model/t_sim_card_bind_pkg.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_sim_card_info.go b/internal/model/t_sim_card_info.go index 4bc1506..206cedb 100644 --- a/internal/model/t_sim_card_info.go +++ b/internal/model/t_sim_card_info.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model @@ -43,7 +43,7 @@ type TSimCardInfoUpdateFields struct { DataServiceStatus int `json:"dataServiceStatus" dc:"数据服务状态:1启用、0禁用"` PackageTotalFlowMb float64 `json:"packageTotalFlowMb" dc:"套餐总流量MB"` UsedFlowMb float64 `json:"usedFlowMb" dc:"已用流量MB"` - TrafficCutoffStatus int `json:"trafficCutoffStatus" dc:"达量断网配置状态:0未配置,1已开启,2已关闭"` + TrafficCutoffStatus int `json:"trafficCutoffStatus" dc:"达量断网配置状态:0未配置,1已开启,2已关闭"` TrafficCutoffThreshold float64 `json:"trafficCutoffThreshold" dc:"达量断网阈值"` SmsServiceStatus int `json:"smsServiceStatus" dc:"短信服务状态:1启用、0禁用"` PackageTotalSms int `json:"packageTotalSms" dc:"套餐短信总条数"` @@ -98,7 +98,7 @@ type TSimCardInfoInsertFields struct { DataServiceStatus int `json:"dataServiceStatus" dc:"数据服务状态:1启用、0禁用"` PackageTotalFlowMb float64 `json:"packageTotalFlowMb" dc:"套餐总流量MB"` UsedFlowMb float64 `json:"usedFlowMb" dc:"已用流量MB"` - TrafficCutoffStatus int `json:"trafficCutoffStatus" dc:"达量断网配置状态:0未配置,1已开启,2已关闭"` + TrafficCutoffStatus int `json:"trafficCutoffStatus" dc:"达量断网配置状态:0未配置,1已开启,2已关闭"` TrafficCutoffThreshold float64 `json:"trafficCutoffThreshold" dc:"达量断网阈值"` SmsServiceStatus int `json:"smsServiceStatus" dc:"短信服务状态:1启用、0禁用"` PackageTotalSms int `json:"packageTotalSms" dc:"套餐短信总条数"` @@ -156,7 +156,7 @@ type TSimCardInfoEditParam struct { DataServiceStatus *int `json:"dataServiceStatus" dc:"数据服务状态:1启用、0禁用"` PackageTotalFlowMb *float64 `json:"packageTotalFlowMb" dc:"套餐总流量MB"` UsedFlowMb *float64 `json:"usedFlowMb" dc:"已用流量MB"` - TrafficCutoffStatus *int `json:"trafficCutoffStatus" dc:"达量断网配置状态:0未配置,1已开启,2已关闭"` + TrafficCutoffStatus *int `json:"trafficCutoffStatus" dc:"达量断网配置状态:0未配置,1已开启,2已关闭"` TrafficCutoffThreshold *float64 `json:"trafficCutoffThreshold" dc:"达量断网阈值"` SmsServiceStatus *int `json:"smsServiceStatus" dc:"短信服务状态:1启用、0禁用"` PackageTotalSms *int `json:"packageTotalSms" dc:"套餐短信总条数"` @@ -291,7 +291,7 @@ type TSimCardInfoListModel struct { DataServiceStatus int `json:"dataServiceStatus" dc:"数据服务状态:1启用、0禁用"` PackageTotalFlowMb float64 `json:"packageTotalFlowMb" dc:"套餐总流量MB"` UsedFlowMb float64 `json:"usedFlowMb" dc:"已用流量MB"` - TrafficCutoffStatus int `json:"trafficCutoffStatus" dc:"达量断网配置状态:0未配置,1已开启,2已关闭"` + TrafficCutoffStatus int `json:"trafficCutoffStatus" dc:"达量断网配置状态:0未配置,1已开启,2已关闭"` TrafficCutoffThreshold float64 `json:"trafficCutoffThreshold" dc:"达量断网阈值"` SmsServiceStatus int `json:"smsServiceStatus" dc:"短信服务状态:1启用、0禁用"` PackageTotalSms int `json:"packageTotalSms" dc:"套餐短信总条数"` @@ -354,7 +354,7 @@ type TSimCardInfoExportModel struct { DataServiceStatus int `json:"dataServiceStatus" dc:"数据服务状态:1启用、0禁用"` PackageTotalFlowMb float64 `json:"packageTotalFlowMb" dc:"套餐总流量MB"` UsedFlowMb float64 `json:"usedFlowMb" dc:"已用流量MB"` - TrafficCutoffStatus int `json:"trafficCutoffStatus" dc:"达量断网配置状态:0未配置,1已开启,2已关闭"` + TrafficCutoffStatus int `json:"trafficCutoffStatus" dc:"达量断网配置状态:0未配置,1已开启,2已关闭"` TrafficCutoffThreshold float64 `json:"trafficCutoffThreshold" dc:"达量断网阈值"` SmsServiceStatus int `json:"smsServiceStatus" dc:"短信服务状态:1启用、0禁用"` PackageTotalSms int `json:"packageTotalSms" dc:"套餐短信总条数"` diff --git a/internal/model/t_sim_card_stock.go b/internal/model/t_sim_card_stock.go index b2a3a25..5dd4fd7 100644 --- a/internal/model/t_sim_card_stock.go +++ b/internal/model/t_sim_card_stock.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_sim_channel_template.go b/internal/model/t_sim_channel_template.go index 0d2c088..8f6030d 100644 --- a/internal/model/t_sim_channel_template.go +++ b/internal/model/t_sim_channel_template.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_sim_channels.go b/internal/model/t_sim_channels.go index e0e5a56..95141ff 100644 --- a/internal/model/t_sim_channels.go +++ b/internal/model/t_sim_channels.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_sim_flow_package_info.go b/internal/model/t_sim_flow_package_info.go index cf871ce..3ab1b5b 100644 --- a/internal/model/t_sim_flow_package_info.go +++ b/internal/model/t_sim_flow_package_info.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_sim_flow_pool.go b/internal/model/t_sim_flow_pool.go index 5cd3e75..c662e68 100644 --- a/internal/model/t_sim_flow_pool.go +++ b/internal/model/t_sim_flow_pool.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_sim_package_category.go b/internal/model/t_sim_package_category.go index 8e8a269..bce6c62 100644 --- a/internal/model/t_sim_package_category.go +++ b/internal/model/t_sim_package_category.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_sim_pool_warn_config.go b/internal/model/t_sim_pool_warn_config.go index 8788149..760abaa 100644 --- a/internal/model/t_sim_pool_warn_config.go +++ b/internal/model/t_sim_pool_warn_config.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_tplatform_setting.go b/internal/model/t_tplatform_setting.go index 19f370a..23ac1a6 100644 --- a/internal/model/t_tplatform_setting.go +++ b/internal/model/t_tplatform_setting.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_upstream_package.go b/internal/model/t_upstream_package.go index c2e7c28..f4b2087 100644 --- a/internal/model/t_upstream_package.go +++ b/internal/model/t_upstream_package.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_wo_communication.go b/internal/model/t_wo_communication.go index 88db802..f7d2001 100644 --- a/internal/model/t_wo_communication.go +++ b/internal/model/t_wo_communication.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_wo_main.go b/internal/model/t_wo_main.go index 95f6d19..cbaa158 100644 --- a/internal/model/t_wo_main.go +++ b/internal/model/t_wo_main.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/model/t_wo_record.go b/internal/model/t_wo_record.go index c370e81..3fdda2c 100644 --- a/internal/model/t_wo_record.go +++ b/internal/model/t_wo_record.go @@ -1,7 +1,7 @@ // Package genin // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2026 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE // @AutoGenerate Version package model diff --git a/internal/packed/packed.go b/internal/packed/packed.go index 25355af..cedc529 100644 --- a/internal/packed/packed.go +++ b/internal/packed/packed.go @@ -1,6 +1,6 @@ // package packed // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package packed diff --git a/internal/packed/response/response.go b/internal/packed/response/response.go index 39d78ed..0e6e1af 100644 --- a/internal/packed/response/response.go +++ b/internal/packed/response/response.go @@ -1,7 +1,7 @@ // package response // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package response diff --git a/internal/router/common.go b/internal/router/common.go deleted file mode 100644 index 3bcb4e6..0000000 --- a/internal/router/common.go +++ /dev/null @@ -1,15 +0,0 @@ -package router - -import ( - "context" - - "git.5iot.com/iotlcm-public/iotlcm-openapi/internal/controller/common" - - "github.com/gogf/gf/v2/net/ghttp" -) - -func Common(ctx context.Context, group *ghttp.RouterGroup) { - group.Group("/common", func(group *ghttp.RouterGroup) { - group.Bind(common.NewV1()) - }) -} diff --git a/internal/router/router.go b/internal/router/router.go index b9f01ec..85b1ce3 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -15,7 +15,6 @@ func InitRouter(ctx context.Context, s *ghttp.Server) { service.Middleware().ApiAuth, service.Middleware().ResponseHandler, ) - Common(ctx, group) Change(ctx, group) Query(ctx, group) }) diff --git a/manifest/config/config.yaml b/manifest/config/config.example.yaml similarity index 83% rename from manifest/config/config.yaml rename to manifest/config/config.example.yaml index db28858..f67fe20 100644 --- a/manifest/config/config.yaml +++ b/manifest/config/config.example.yaml @@ -33,7 +33,7 @@ database: level: "all" stdout: true default: - link: "mysql:${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST}:3306)/db_iotlcm?charset=utf8mb4&parseTime=True&loc=Asia%2FShanghai" + link: "${DB_DSN}" debug: true charset: "utf8mb4" dryRun: false @@ -49,9 +49,9 @@ redis: default: mode: "single" sentinelMasterName: "iotlcm-master" - address: "192.0.2.29:6379" + address: "127.0.0.1:6379" db: 0 - pass: "${REDIS_PASSWORD}" + pass: "${SERVICE_PASSWORD}" minIdle: 5 maxIdle: 30 maxActive: 5000 @@ -73,4 +73,4 @@ upstream: rabbitmq: enabled: true - dsn: "amqp://${MQ_USER}:${MQ_PASSWORD}@${MQ_HOST}/" + dsn: "${SERVICE_DSN}" diff --git a/manifest/docker/Dockerfile b/manifest/docker/Dockerfile index 4f167a4..7cfc2f4 100644 --- a/manifest/docker/Dockerfile +++ b/manifest/docker/Dockerfile @@ -1,9 +1,7 @@ -# 基础镜像仓库。默认使用 Docker Hub 官方镜像;内网环境可替换为自己的仓库: -# docker build --build-arg BASE_REGISTRY=harbor.example.com/library ... ARG BASE_REGISTRY=docker.io/library - FROM ${BASE_REGISTRY}/alpine:3.23 +RUN apk add --no-cache ca-certificates tzdata ############################################################################### # INSTALLATION ############################################################################### diff --git a/utility/convert/convert.go b/utility/convert/convert.go index 8b4be61..42a125c 100644 --- a/utility/convert/convert.go +++ b/utility/convert/convert.go @@ -1,7 +1,7 @@ // package convert // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package convert diff --git a/utility/excel/excel.go b/utility/excel/excel.go index dbce1a4..40b75f4 100644 --- a/utility/excel/excel.go +++ b/utility/excel/excel.go @@ -1,7 +1,7 @@ // package excel // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package excel diff --git a/utility/gfredis/gfredis.go b/utility/gfredis/gfredis.go index d6d230b..ebab2b2 100644 --- a/utility/gfredis/gfredis.go +++ b/utility/gfredis/gfredis.go @@ -31,7 +31,7 @@ type Redis struct { // Config is redis configuration. type Config struct { - // Address It supports single and cluster redis server. Multiple addresses joined with char ','. Eg: 192.168.1.1:6379, 192.168.1.2:6379. + // Address It supports single and cluster redis server. Multiple addresses joined with char ','. Eg: 127.0.0.1:6379, 127.0.0.1:6379. Address string `json:"address"` Db int `json:"db"` // Redis db. User string `json:"user"` // Username for AUTH. diff --git a/utility/tree/tree.go b/utility/tree/tree.go index 9a0a27d..33e615e 100644 --- a/utility/tree/tree.go +++ b/utility/tree/tree.go @@ -1,7 +1,7 @@ // package tree // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package tree diff --git a/utility/utility.go b/utility/utility.go index be4735c..943145c 100644 --- a/utility/utility.go +++ b/utility/utility.go @@ -1,7 +1,7 @@ // package utility // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package utility diff --git a/utility/version/version.go b/utility/version/version.go index e718bcf..c048c6b 100644 --- a/utility/version/version.go +++ b/utility/version/version.go @@ -1,7 +1,7 @@ // package version // @Link https://github.com/xiujiecn/xiu-admin // @Copyright Copyright (c) 2025 LiXiujie -// @Author Lxj +// @Author Lxj // @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE package version @@ -24,20 +24,14 @@ func ShowLogo(buildVersion, buildTime, commitID string) { CommitID = commitID //版本号 - fmt.Println(` - ██╗██╗███████╗ ██╗ ██████╗ ████████╗ - ██║██║██╔════╝ ██║██╔═══██╗╚══██╔══╝ - ██║██║█████╗ ██║██║ ██║ ██║ -██ ██║██║██╔══╝ ██║██║ ██║ ██║ -╚█████╔╝██║███████╗ ██║╚██████╔╝ ██║ - ╚════╝ ╚═╝╚══════╝ ╚═╝ ╚═════╝ ╚═╝`) + fmt.Println(" __ __ _ _ _ _ \n \\ \\/ /(_) _ _ / \\ __| | _ __ ___ (_) _ __ \n \\ / | || | | | / _ \\ / _` || '_ ` _ \\ | || '_ \\ \n / \\ | || |_| | / ___ \\| (_| || | | | | || || | | |\n /_/\\_\\|_| \\__,_| /_/ \\_\\\\__,_||_| |_| |_||_||_| |_|") fmt.Println("") fmt.Println("Version :", buildVersion) fmt.Println("BuildTime :", buildTime) fmt.Println("CommitID :", commitID) fmt.Println("") - fmt.Println("Copyright:", "2026 The iotLCM Authors") + fmt.Println("Copyright:", "XiuJieZhiLian Technology Co.,Ltd") } func AppName(ctx context.Context) string {