chore: 初始开源发布

iotlcm-app:小程序端 + 用户端服务。

- app/:uni-app 小程序前端(基于 unibest,MIT)
  - 微信 AppID → YOUR_WX_APPID,uni-app AppID → __UNI__YOURAPPID
  - 内网后端地址 → admin.iotlcm.example.com
  - 应用标题与 unibest 模板 README 重写(保留上游致谢与 MIT 声明)
- server/:GoFrame 用户端服务(基于 XiuAdmin,Apache-2.0)
  - module xiuadmin → git.5iot.com/iotlcm-public/iotlcm-app(360 文件)
  - 支付回调地址 → app.iotlcm.example.com,商户名与应用名泛化
  - 真实手机号 → 合法 11 位编造号(保留号段前 3 位 + 后 4 位)
  - 依赖号码尾部的断言同步更新
  - 补 server/LICENSE(Apache-2.0)
- 移除内部资产:CI 触发器
- 补根 README,LF 行尾 + .gitattributes

已知:TestSysDept_RefreshDeptAncestors 在源仓同一提交上同样失败,属既有缺陷。
This commit is contained in:
MiFaZhan
2026-10-26 14:01:25 +08:00
commit 2ed5dfa6a1
1013 changed files with 138466 additions and 0 deletions
@@ -0,0 +1,77 @@
package app
import (
"context"
"encoding/json"
"strings"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/library/rabbitmq"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
const (
appAsyncEventBalanceRechargePaid = "balance_recharge_paid"
appAsyncEventRenewCompleted = "card_renew_completed"
appAsyncEventChangeCompleted = "card_change_completed"
appAsyncEventAllocateCompleted = "card_allocate_completed"
)
type appBusinessAsyncEvent struct {
EventType string `json:"eventType"`
OrderSn string `json:"orderSn,omitempty"`
BatchNo string `json:"batchNo,omitempty"`
BatchType int `json:"batchType,omitempty"`
PayProvider string `json:"payProvider,omitempty"`
PayTradeNo string `json:"payTradeNo,omitempty"`
TenantId string `json:"tenantId,omitempty"`
UserId int64 `json:"userId,omitempty"`
DeptId int64 `json:"deptId,omitempty"`
Trigger string `json:"trigger,omitempty"`
CreatedAt string `json:"createdAt"`
}
func (s *sAppCard) publishAppBusinessAsyncEvent(ctx context.Context, event appBusinessAsyncEvent) error {
event.EventType = strings.TrimSpace(event.EventType)
if event.EventType == "" {
return nil
}
if event.CreatedAt == "" {
event.CreatedAt = gtime.Now().Format("Y-m-d H:i:s")
}
if !g.Cfg().MustGet(ctx, "appBusinessAsync.enabled", false).Bool() {
return nil
}
payload, err := json.Marshal(event)
if err != nil {
return gerror.Wrap(err, "序列化小程序业务异步事件失败")
}
provider := strings.ToLower(strings.TrimSpace(g.Cfg().MustGet(ctx, "appBusinessAsync.provider", "rabbitmq").String()))
queueName := strings.TrimSpace(g.Cfg().MustGet(ctx, "appBusinessAsync.queueName", "iotlcm.app.business").String())
failOnPublish := g.Cfg().MustGet(ctx, "appBusinessAsync.failOnPublish", false).Bool()
var publishErr error
switch provider {
case "log", "stdout":
g.Log().Infof(ctx, "小程序业务异步事件: queue=%s payload=%s", queueName, string(payload))
case "rabbitmq":
publishErr = rabbitmq.PublishBytes(ctx, queueName, payload)
if publishErr != nil {
g.Log().Warningf(ctx, "小程序业务异步事件 RabbitMQ 发布失败: queue=%s payload=%s err:%+v", queueName, string(payload), publishErr)
} else {
g.Log().Infof(ctx, "小程序业务异步事件 RabbitMQ 发布成功: queue=%s eventType=%s orderSn=%s batchNo=%s", queueName, event.EventType, event.OrderSn, event.BatchNo)
}
default:
publishErr = gerror.Newf("不支持的小程序业务异步事件发布器: %s", provider)
g.Log().Warningf(ctx, "%v: queue=%s payload=%s", publishErr, queueName, string(payload))
}
if publishErr != nil && failOnPublish {
return publishErr
}
return nil
}