七月迭代短暂完结,还有很多后端的关键东西没有弄,这是一版赶时间做的东西
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m26s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m26s
This commit is contained in:
@@ -30,6 +30,8 @@ type Config struct {
|
||||
PollingAutoTrigger PollingAutoTriggerConfig `mapstructure:"polling_auto_trigger"`
|
||||
Polling PollingConfig `mapstructure:"polling"`
|
||||
Worker WorkerConfig `mapstructure:"worker"`
|
||||
WeCom WeComConfig `mapstructure:"wecom"`
|
||||
Approval ApprovalConfig `mapstructure:"approval"`
|
||||
}
|
||||
|
||||
// ServerConfig HTTP 服务器配置
|
||||
@@ -168,6 +170,19 @@ type WorkerConfig struct {
|
||||
InstanceName string `mapstructure:"instance_name"` // Worker 实例名称,用于多实例日志区分
|
||||
}
|
||||
|
||||
// ApprovalConfig 审批新旧入口切换配置。
|
||||
type ApprovalConfig struct {
|
||||
LegacyRefundManualEnabled bool `mapstructure:"legacy_refund_manual_enabled"` // 是否保留退款人工通过与拒绝入口
|
||||
LegacyOfflineRechargePayEnabled bool `mapstructure:"legacy_offline_recharge_pay_enabled"` // 是否保留线下充值人工确认入口
|
||||
}
|
||||
|
||||
// WeComConfig 企业微信 Adapter 运行配置。
|
||||
type WeComConfig struct {
|
||||
BaseURL string `mapstructure:"base_url"` // 企业微信 API 基础地址
|
||||
Timeout time.Duration `mapstructure:"timeout"` // 外部请求超时时间
|
||||
CredentialEncryptionKey string `mapstructure:"credential_encryption_key"` // 数据库凭证 AES-256-GCM 加密密钥(Base64)
|
||||
}
|
||||
|
||||
// PollingConfig 轮询通用配置
|
||||
type PollingConfig struct {
|
||||
// VerboseLog 开启后,所有轮询 handler 在成功获取上游数据时以 Info 级别输出详细日志
|
||||
|
||||
@@ -137,3 +137,14 @@ polling_auto_trigger:
|
||||
worker:
|
||||
role: "all"
|
||||
instance_name: ""
|
||||
|
||||
# 审批新旧入口切换配置
|
||||
approval:
|
||||
legacy_refund_manual_enabled: true
|
||||
legacy_offline_recharge_pay_enabled: true
|
||||
|
||||
# 企业微信 Adapter 配置
|
||||
wecom:
|
||||
base_url: "https://qyapi.weixin.qq.com"
|
||||
timeout: "10s"
|
||||
credential_encryption_key: "" # 启用企微前必填:JUNHONG_WECOM_CREDENTIAL_ENCRYPTION_KEY(32 字节 Base64)
|
||||
|
||||
@@ -130,6 +130,11 @@ func bindEnvVariables(v *viper.Viper) {
|
||||
"polling_auto_trigger.auto_trigger_system_user_id",
|
||||
"worker.role",
|
||||
"worker.instance_name",
|
||||
"approval.legacy_refund_manual_enabled",
|
||||
"approval.legacy_offline_recharge_pay_enabled",
|
||||
"wecom.base_url",
|
||||
"wecom.timeout",
|
||||
"wecom.credential_encryption_key",
|
||||
"wechat.official_account.app_id",
|
||||
"wechat.official_account.app_secret",
|
||||
"wechat.official_account.token",
|
||||
|
||||
@@ -2,6 +2,54 @@ package constants
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
// ApprovalBusinessTypeRefund 表示退款审批业务场景。
|
||||
ApprovalBusinessTypeRefund = "refund_approval"
|
||||
// ApprovalBusinessTypeOfflineRecharge 表示员工线下代充值审批业务场景。
|
||||
ApprovalBusinessTypeOfflineRecharge = "offline_recharge_approval"
|
||||
)
|
||||
|
||||
const (
|
||||
// ApprovalFieldRechargeNo 表示线下代充值单号业务字段。
|
||||
ApprovalFieldRechargeNo = "recharge_no"
|
||||
// ApprovalFieldShopID 表示线下代充值目标店铺 ID 业务字段。
|
||||
ApprovalFieldShopID = "shop_id"
|
||||
// ApprovalFieldShopName 表示线下代充值目标店铺名称业务字段。
|
||||
ApprovalFieldShopName = "shop_name"
|
||||
// ApprovalFieldAmount 表示线下代充值元金额展示业务字段。
|
||||
ApprovalFieldAmount = "amount"
|
||||
// ApprovalFieldAmountCent 表示线下代充值分金额业务字段。
|
||||
ApprovalFieldAmountCent = "amount_cent"
|
||||
// ApprovalFieldPaymentVoucherKey 表示线下代充值凭证对象存储 Key 列表业务字段。
|
||||
ApprovalFieldPaymentVoucherKey = "payment_voucher_key"
|
||||
// ApprovalFieldRemark 表示线下代充值运营备注业务字段。
|
||||
ApprovalFieldRemark = "remark"
|
||||
// ApprovalFieldSubmitterID 表示真实业务提交人账号 ID 业务字段。
|
||||
ApprovalFieldSubmitterID = "submitter_id"
|
||||
// ApprovalFieldSubmitterName 表示真实业务提交人账号名称业务字段。
|
||||
ApprovalFieldSubmitterName = "submitter_name"
|
||||
// ApprovalFieldRefundNo 表示退款单号业务字段。
|
||||
ApprovalFieldRefundNo = "refund_no"
|
||||
// ApprovalFieldOrderID 表示退款关联订单 ID 业务字段。
|
||||
ApprovalFieldOrderID = "order_id"
|
||||
// ApprovalFieldOrderNo 表示退款关联订单号业务字段。
|
||||
ApprovalFieldOrderNo = "order_no"
|
||||
// ApprovalFieldAssetIdentifier 表示退款资产标识业务字段。
|
||||
ApprovalFieldAssetIdentifier = "asset_identifier"
|
||||
// ApprovalFieldAssetType 表示退款资产类型业务字段。
|
||||
ApprovalFieldAssetType = "asset_type"
|
||||
// ApprovalFieldActualReceivedAmount 表示退款实收金额业务字段。
|
||||
ApprovalFieldActualReceivedAmount = "actual_received_amount"
|
||||
// ApprovalFieldRequestedRefundAmount 表示申请退款金额业务字段。
|
||||
ApprovalFieldRequestedRefundAmount = "requested_refund_amount"
|
||||
// ApprovalFieldRefundVoucherKey 表示退款凭证对象存储 Key 列表业务字段。
|
||||
ApprovalFieldRefundVoucherKey = "refund_voucher_key"
|
||||
// ApprovalFieldRefundReason 表示退款原因业务字段。
|
||||
ApprovalFieldRefundReason = "refund_reason"
|
||||
// ApprovalFieldPackageUsageID 表示退款指定套餐使用记录 ID 业务字段。
|
||||
ApprovalFieldPackageUsageID = "package_usage_id"
|
||||
)
|
||||
|
||||
const (
|
||||
// ApprovalStatusSubmitting 表示审批申请等待渠道提交。
|
||||
ApprovalStatusSubmitting = 0
|
||||
|
||||
@@ -38,7 +38,6 @@ const (
|
||||
AssetAuditOpDeviceUnbindCard = "device_unbind_card" // 设备解绑卡
|
||||
AssetAuditOpDeviceStop = "device_stop" // 设备停机
|
||||
AssetAuditOpDeviceStart = "device_start" // 设备复机
|
||||
AssetAuditOpDeviceSpeedLimit = "device_speed_limit" // 设备限速
|
||||
AssetAuditOpDeviceSetWiFi = "device_set_wifi" // 设备 WiFi 设置
|
||||
AssetAuditOpDeviceSwitchCard = "device_switch_card" // 设备切卡
|
||||
AssetAuditOpDeviceSwitchMode = "device_switch_mode" // 设备切卡模式
|
||||
@@ -49,7 +48,9 @@ const (
|
||||
AssetAuditOpAssetRealnamePolicy = "asset_realname_policy" // 统一入口实名策略更新
|
||||
AssetAuditOpAssetPackageExpiresAt = "asset_package_expires_at" // 资产套餐过期时间更新
|
||||
AssetAuditOpAssetPackageUsage = "asset_package_usage" // 资产套餐已用量更新
|
||||
AssetAuditOpCardSpeedTier = "card_speed_tier" // IoT 卡固定限速档位设置
|
||||
AssetAuditOpDeviceImportTaskCreate = "device_import_task_create" // 设备导入任务创建
|
||||
AssetAuditOpDeviceBatchTaskCreate = "device_batch_task_create" // 设备CSV批量分配任务创建
|
||||
AssetAuditOpIotCardImportTaskCreate = "iot_card_import_task_create" // 卡导入任务创建
|
||||
)
|
||||
|
||||
|
||||
32
pkg/constants/asset_package_batch_order.go
Normal file
32
pkg/constants/asset_package_batch_order.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package constants
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
// StoragePurposeAssetPackageBatchOrder 表示资产套餐批量订购 CSV 上传用途。
|
||||
StoragePurposeAssetPackageBatchOrder = "batch_purchase"
|
||||
// AssetPackageBatchOrderStoragePrefix 表示资产套餐批量订购文件的对象存储目录。
|
||||
AssetPackageBatchOrderStoragePrefix = "batch-purchases"
|
||||
// AssetPackageBatchOrderMaxRows 表示单个批量订购 CSV 最大业务行数。
|
||||
AssetPackageBatchOrderMaxRows = 1000
|
||||
// AssetPackageBatchOrderMaxFileSize 表示单个批量订购 CSV 最大字节数(10MB)。
|
||||
AssetPackageBatchOrderMaxFileSize int64 = 10 * 1024 * 1024
|
||||
// AssetPackageBatchOrderTaskTimeout 表示单个批量订购任务的最长执行时间。
|
||||
AssetPackageBatchOrderTaskTimeout = 2 * time.Hour
|
||||
// AssetPackageBatchOrderItemStatusSuccess 表示批量订购单行已成功创建订单。
|
||||
AssetPackageBatchOrderItemStatusSuccess = 3
|
||||
// AssetPackageBatchOrderItemStatusFailed 表示批量订购单行已失败并记录原因。
|
||||
AssetPackageBatchOrderItemStatusFailed = 4
|
||||
)
|
||||
|
||||
// GetAssetPackageBatchOrderItemStatusName 返回批量订购单行状态中文名称。
|
||||
func GetAssetPackageBatchOrderItemStatusName(status int) string {
|
||||
switch status {
|
||||
case AssetPackageBatchOrderItemStatusSuccess:
|
||||
return "成功"
|
||||
case AssetPackageBatchOrderItemStatusFailed:
|
||||
return "失败"
|
||||
default:
|
||||
return "未知"
|
||||
}
|
||||
}
|
||||
@@ -69,8 +69,59 @@ const (
|
||||
IntegrationOperationGatewayTraffic = "query_flow" // 查询流量
|
||||
IntegrationOperationGatewayNetwork = "query_card_status" // 查询网络状态
|
||||
IntegrationOperationGatewayDeviceInfo = "query_device_info" // 查询设备信息
|
||||
IntegrationOperationGatewaySpeedTier = "set_speed_tier" // 设置或恢复固定限速档位
|
||||
)
|
||||
|
||||
// Gateway 固定限速档位编码。
|
||||
const (
|
||||
GatewaySpeedTierRestore = -1 // 恢复不限速
|
||||
GatewaySpeedTierZero = 0 // 限速为 0kbps
|
||||
GatewaySpeedTier128K = 1 // 限速为 128Kbps
|
||||
GatewaySpeedTier512K = 2 // 限速为 512Kbps
|
||||
GatewaySpeedTier1M = 3 // 限速为 1Mbps
|
||||
GatewaySpeedTier2M = 4 // 限速为 2Mbps
|
||||
GatewaySpeedTier10M = 5 // 限速为 10Mbps
|
||||
GatewaySpeedTier20M = 6 // 限速为 20Mbps
|
||||
GatewaySpeedTier50M = 7 // 限速为 50Mbps
|
||||
GatewaySpeedTier100M = 8 // 限速为 100Mbps
|
||||
)
|
||||
|
||||
// IsGatewaySpeedTier 判断编码是否为系统允许的固定限速档位。
|
||||
func IsGatewaySpeedTier(code int) bool {
|
||||
return code >= GatewaySpeedTierRestore && code <= GatewaySpeedTier100M
|
||||
}
|
||||
|
||||
// GetGatewaySpeedTierName 返回固定限速档位中文名称。
|
||||
func GetGatewaySpeedTierName(code int) string {
|
||||
switch code {
|
||||
case GatewaySpeedTierRestore:
|
||||
return "恢复不限速"
|
||||
case GatewaySpeedTierZero:
|
||||
return "0kbps"
|
||||
case GatewaySpeedTier128K:
|
||||
return "128Kbps"
|
||||
case GatewaySpeedTier512K:
|
||||
return "512Kbps"
|
||||
case GatewaySpeedTier1M:
|
||||
return "1Mbps"
|
||||
case GatewaySpeedTier2M:
|
||||
return "2Mbps"
|
||||
case GatewaySpeedTier10M:
|
||||
return "10Mbps"
|
||||
case GatewaySpeedTier20M:
|
||||
return "20Mbps"
|
||||
case GatewaySpeedTier50M:
|
||||
return "50Mbps"
|
||||
case GatewaySpeedTier100M:
|
||||
return "100Mbps"
|
||||
default:
|
||||
return "未知"
|
||||
}
|
||||
}
|
||||
|
||||
// GatewaySpeedTierUnknownRecoveryStrategy 表示限速超时后的人工核对策略。
|
||||
const GatewaySpeedTierUnknownRecoveryStrategy = "通过 Gateway 运维侧按 ICCID 核对当前限速档位后,再决定是否重试"
|
||||
|
||||
// 卡实名观测场景
|
||||
const (
|
||||
CardObservationSceneRealnamePolling = "realname_polling" // 实名轮询
|
||||
|
||||
@@ -73,7 +73,8 @@ const (
|
||||
TaskTypePackageDataReset = "package:data:reset" // 套餐流量重置
|
||||
|
||||
// 订单套餐失效任务类型
|
||||
TaskTypeOrderPackageInvalidate = "order:package:invalidate" // 批量失效订单套餐
|
||||
TaskTypeOrderPackageInvalidate = "order:package:invalidate" // 批量失效订单套餐
|
||||
TaskTypeAssetPackageBatchOrder = "asset:package:batch_order" // 资产套餐批量订购
|
||||
|
||||
// 订单超时任务类型
|
||||
TaskTypeOrderExpire = "order:expire" // 订单超时自动取消
|
||||
@@ -83,9 +84,12 @@ const (
|
||||
TaskTypeAlertCheck = "alert:check" // 告警检查
|
||||
TaskTypeDataCleanup = "data:cleanup" // 数据清理
|
||||
TaskTypeNotificationCleanup = "notification:cleanup" // 站内通知保留清理
|
||||
TaskTypePackageExpiryReminder = "package:expiry:reminder" // 套餐 15/7/3 天临期提醒
|
||||
TaskTypeDailyTrafficFlush = "traffic:daily:flush" // 每日流量落盘
|
||||
TaskTypeOutboxDeliver = "outbox:deliver" // 公共 Outbox 事件投递
|
||||
TaskTypeCardObservationSeries = "card_observation:series" // 卡观测事件序列尝试
|
||||
TaskTypeWeComApprovalSync = "wecom:approval:sync" // 企业微信审批详情异步同步
|
||||
TaskTypeWeComApprovalRecovery = "wecom:approval:recovery" // 企业微信审批主动恢复与轮询
|
||||
)
|
||||
|
||||
// 用户状态常量
|
||||
@@ -221,6 +225,7 @@ const (
|
||||
QueuePackageQueueActivation = TaskTypePackageQueueActivation // 主套餐排队激活任务队列
|
||||
QueuePackageDataReset = TaskTypePackageDataReset // 套餐流量重置任务队列
|
||||
QueueOrderPackageInvalidate = TaskTypeOrderPackageInvalidate // 批量失效订单套餐任务队列
|
||||
QueueAssetPackageBatchOrder = TaskTypeAssetPackageBatchOrder // 资产套餐批量订购任务队列
|
||||
QueueOrderExpire = TaskTypeOrderExpire // 订单超时取消任务队列
|
||||
QueueAutoPurchase = TaskTypeAutoPurchaseAfterRecharge // 充值后自动购包任务队列
|
||||
QueueAlertCheck = TaskTypeAlertCheck // 告警检查任务队列
|
||||
@@ -228,6 +233,7 @@ const (
|
||||
QueueDailyTrafficFlush = TaskTypeDailyTrafficFlush // 每日流量落盘任务队列
|
||||
QueueOutboxDeliver = TaskTypeOutboxDeliver // 公共 Outbox 投递队列
|
||||
QueueCardObservationSeries = TaskTypeCardObservationSeries // 卡观测事件序列队列
|
||||
QueueWeComApproval = "wecom:approval" // 企业微信审批同步与恢复队列
|
||||
|
||||
DefaultRetryMax = 5 // 默认任务最大重试次数
|
||||
DefaultTimeout = 10 * time.Minute // 默认任务超时时间
|
||||
@@ -275,6 +281,8 @@ func QueueForTaskType(taskType string) string {
|
||||
return QueuePackageDataReset
|
||||
case TaskTypeOrderPackageInvalidate:
|
||||
return QueueOrderPackageInvalidate
|
||||
case TaskTypeAssetPackageBatchOrder:
|
||||
return QueueAssetPackageBatchOrder
|
||||
case TaskTypeOrderExpire:
|
||||
return QueueOrderExpire
|
||||
case TaskTypeAutoPurchaseAfterRecharge:
|
||||
@@ -285,12 +293,16 @@ func QueueForTaskType(taskType string) string {
|
||||
return QueueDataCleanup
|
||||
case TaskTypeNotificationCleanup:
|
||||
return QueueDataCleanup
|
||||
case TaskTypePackageExpiryReminder:
|
||||
return QueueDataCleanup
|
||||
case TaskTypeDailyTrafficFlush:
|
||||
return QueueDailyTrafficFlush
|
||||
case TaskTypeOutboxDeliver:
|
||||
return QueueOutboxDeliver
|
||||
case TaskTypeCardObservationSeries:
|
||||
return QueueCardObservationSeries
|
||||
case TaskTypeWeComApprovalSync, TaskTypeWeComApprovalRecovery:
|
||||
return QueueWeComApproval
|
||||
default:
|
||||
return QueueDefault
|
||||
}
|
||||
@@ -306,6 +318,7 @@ func DefaultTaskQueueWeights() map[string]int {
|
||||
QueuePackageFirstActivation: 5,
|
||||
QueuePackageQueueActivation: 5,
|
||||
QueueOrderPackageInvalidate: 5,
|
||||
QueueAssetPackageBatchOrder: 5,
|
||||
QueueOrderExpire: 4,
|
||||
QueueEmailSend: 4,
|
||||
QueueExportDispatch: 4,
|
||||
@@ -326,6 +339,7 @@ func DefaultTaskQueueWeights() map[string]int {
|
||||
QueueDailyTrafficFlush: 1,
|
||||
QueueOutboxDeliver: 4,
|
||||
QueueCardObservationSeries: 2,
|
||||
QueueWeComApproval: 2,
|
||||
QueueDefault: 1,
|
||||
QueueLow: 1,
|
||||
}
|
||||
@@ -336,6 +350,15 @@ const (
|
||||
ExportTaskSceneDevice = "device" // 导出场景:设备
|
||||
ExportTaskSceneIotCard = "iot_card" // 导出场景:IoT 卡
|
||||
ExportTaskSceneOrder = "order" // 导出场景:订单
|
||||
ExportTaskScenePackage = "package" // 导出场景:套餐
|
||||
// ExportTaskSceneAgentWalletTransaction 表示代理主钱包流水导出场景。
|
||||
ExportTaskSceneAgentWalletTransaction = "agent_wallet_transaction"
|
||||
// ExportTaskSceneAgentRecharge 表示代理充值记录导出场景。
|
||||
ExportTaskSceneAgentRecharge = "agent_recharge"
|
||||
// ExportTaskSceneRefund 表示退款记录导出场景。
|
||||
ExportTaskSceneRefund = "refund"
|
||||
// ExportTaskSceneExchange 表示换货记录导出场景。
|
||||
ExportTaskSceneExchange = "exchange"
|
||||
)
|
||||
|
||||
// 导出文件格式常量
|
||||
|
||||
43
pkg/constants/device_batch_allocation.go
Normal file
43
pkg/constants/device_batch_allocation.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package constants
|
||||
|
||||
import "time"
|
||||
|
||||
// 设备导入任务业务类型。
|
||||
const (
|
||||
DeviceImportOperationCreate = "import" // 导入并创建设备
|
||||
DeviceImportOperationAssignShop = "assign_shop" // 按单列 CSV 分配目标代理店铺
|
||||
DeviceImportOperationAssignSeries = "assign_series" // 按单列 CSV 设置目标套餐系列
|
||||
)
|
||||
|
||||
// 设备批量分配 CSV 约束。
|
||||
const (
|
||||
StoragePurposeDeviceBatchAllocation = "device_batch_allocation" // 设备批量分配 CSV 上传用途
|
||||
DeviceBatchAllocationStoragePrefix = "device-batch-allocations" // 设备批量分配对象存储目录
|
||||
DeviceBatchAllocationMaxRows = 1000 // 单个 CSV 最大设备行数
|
||||
DeviceBatchAllocationMaxFileSize = int64(10 * 1024 * 1024) // 单个 CSV 最大字节数
|
||||
DeviceBatchAllocationTaskTimeout = 2 * time.Hour // 单个任务最长执行时间
|
||||
)
|
||||
|
||||
// IsDeviceImportOperation 判断是否为设备导入任务支持的业务类型。
|
||||
func IsDeviceImportOperation(operation string) bool {
|
||||
switch operation {
|
||||
case DeviceImportOperationCreate, DeviceImportOperationAssignShop, DeviceImportOperationAssignSeries:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// GetDeviceImportOperationName 返回设备导入任务业务类型中文名称。
|
||||
func GetDeviceImportOperationName(operation string) string {
|
||||
switch operation {
|
||||
case DeviceImportOperationCreate:
|
||||
return "导入设备"
|
||||
case DeviceImportOperationAssignShop:
|
||||
return "分配目标代理"
|
||||
case DeviceImportOperationAssignSeries:
|
||||
return "设置套餐系列"
|
||||
default:
|
||||
return "未知"
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,10 @@ const (
|
||||
NotificationTypeSystemNotice = "system.notice"
|
||||
// NotificationTypePackageExpiring 表示个人客户套餐临期提醒。
|
||||
NotificationTypePackageExpiring = "package.expiring"
|
||||
// NotificationTypeExchangeShippingCreated 表示个人客户物流换货待处理提醒。
|
||||
NotificationTypeExchangeShippingCreated = "exchange.shipping.created"
|
||||
// NotificationTypeAgentMainWalletLowBalance 表示代理主钱包余额低于固定阈值提醒。
|
||||
NotificationTypeAgentMainWalletLowBalance = "agent.main_wallet.low_balance"
|
||||
|
||||
// NotificationRefTypeSystemConfig 表示系统配置资源引用。
|
||||
NotificationRefTypeSystemConfig = "system_config"
|
||||
|
||||
67
pkg/constants/package_export.go
Normal file
67
pkg/constants/package_export.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package constants
|
||||
|
||||
// GetPackageTypeName 返回套餐类型中文名称。
|
||||
func GetPackageTypeName(packageType string) string {
|
||||
switch packageType {
|
||||
case PackageTypeFormal:
|
||||
return "正式套餐"
|
||||
case PackageTypeAddon:
|
||||
return "附加套餐"
|
||||
default:
|
||||
return "未知"
|
||||
}
|
||||
}
|
||||
|
||||
// GetPackageCalendarTypeName 返回套餐周期类型中文名称。
|
||||
func GetPackageCalendarTypeName(calendarType string) string {
|
||||
switch calendarType {
|
||||
case PackageCalendarTypeNaturalMonth:
|
||||
return "自然月"
|
||||
case PackageCalendarTypeByDay:
|
||||
return "按天"
|
||||
default:
|
||||
return "未知"
|
||||
}
|
||||
}
|
||||
|
||||
// GetPackageDataResetCycleName 返回套餐流量重置周期中文名称。
|
||||
func GetPackageDataResetCycleName(cycle string) string {
|
||||
switch cycle {
|
||||
case PackageDataResetDaily:
|
||||
return "每日"
|
||||
case PackageDataResetMonthly:
|
||||
return "每月"
|
||||
case PackageDataResetYearly:
|
||||
return "每年"
|
||||
case PackageDataResetNone:
|
||||
return "不重置"
|
||||
default:
|
||||
return "未知"
|
||||
}
|
||||
}
|
||||
|
||||
// GetPackageExpiryBaseName 返回套餐到期时间基准中文名称。
|
||||
func GetPackageExpiryBaseName(expiryBase string) string {
|
||||
switch expiryBase {
|
||||
case PackageExpiryBaseFromActivation:
|
||||
return "实名激活时起算"
|
||||
case PackageExpiryBaseFromPurchase:
|
||||
return "购买时起算"
|
||||
default:
|
||||
return "未知"
|
||||
}
|
||||
}
|
||||
|
||||
// GetPackagePriceConfigStatusName 返回套餐价格配置状态中文名称。
|
||||
func GetPackagePriceConfigStatusName(status int) string {
|
||||
switch status {
|
||||
case PackagePriceConfigStatusGiftZero:
|
||||
return "赠送0价"
|
||||
case PackagePriceConfigStatusConfigured:
|
||||
return "已配置非0"
|
||||
case PackagePriceConfigStatusUnconfigured:
|
||||
return "未配置"
|
||||
default:
|
||||
return "未知"
|
||||
}
|
||||
}
|
||||
@@ -553,3 +553,13 @@ func RedisSystemOperationPasswordKey() string {
|
||||
func RedisPaymentConfigKey(configID uint) string {
|
||||
return fmt.Sprintf("payment:config:%d", configID)
|
||||
}
|
||||
|
||||
// RedisWeComAccessTokenKey 返回企业微信应用 access_token 缓存 Key。
|
||||
func RedisWeComAccessTokenKey(applicationID uint) string {
|
||||
return fmt.Sprintf("wecom:application:%d:access_token", applicationID)
|
||||
}
|
||||
|
||||
// RedisWeComAccessTokenLockKey 返回企业微信应用 access_token 回源短锁 Key。
|
||||
func RedisWeComAccessTokenLockKey(applicationID uint) string {
|
||||
return fmt.Sprintf("wecom:application:%d:access_token:lock", applicationID)
|
||||
}
|
||||
|
||||
@@ -18,6 +18,12 @@ const (
|
||||
SystemConfigCacheTTL = 5 * time.Minute
|
||||
// SystemConfigModuleCarrierCallback 是运营商回调配置模块。
|
||||
SystemConfigModuleCarrierCallback = "carrier_callback"
|
||||
// SystemConfigModulePayment 是 C 端支付方式配置模块。
|
||||
SystemConfigModulePayment = "c2b.payment"
|
||||
// SystemConfigPaymentAllowedCard 定义卡资产允许的支付方式集合。
|
||||
SystemConfigPaymentAllowedCard = "c2b.payment.card_allowed_methods"
|
||||
// SystemConfigPaymentAllowedDevice 定义设备资产允许的支付方式集合。
|
||||
SystemConfigPaymentAllowedDevice = "c2b.payment.device_allowed_methods"
|
||||
// SystemConfigCarrierCallbackCTCCRealnameEnabled 控制电信实名回调是否执行业务处理。
|
||||
SystemConfigCarrierCallbackCTCCRealnameEnabled = "carrier_callback.ctcc_realname.enabled"
|
||||
// SystemConfigCarrierCallbackCMCCRealnameEnabled 控制移动实名回调是否执行业务处理。
|
||||
|
||||
@@ -12,6 +12,8 @@ import "fmt"
|
||||
const (
|
||||
AgentWalletTypeMain = "main" // 主钱包
|
||||
AgentWalletTypeCommission = "commission" // 分佣钱包
|
||||
// AgentMainWalletLowBalanceThreshold 表示主钱包低余额提醒阈值,单位为分(100 元)。
|
||||
AgentMainWalletLowBalanceThreshold int64 = 10000
|
||||
)
|
||||
|
||||
// 代理主钱包信用管理权限
|
||||
|
||||
71
pkg/constants/wallet_export.go
Normal file
71
pkg/constants/wallet_export.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package constants
|
||||
|
||||
// GetAgentTransactionTypeName 返回代理钱包交易类型中文名称。
|
||||
func GetAgentTransactionTypeName(transactionType string) string {
|
||||
switch transactionType {
|
||||
case AgentTransactionTypeRecharge:
|
||||
return "充值"
|
||||
case AgentTransactionTypeDeduct:
|
||||
return "扣款"
|
||||
case AgentTransactionTypeRefund:
|
||||
return "退款"
|
||||
case AgentTransactionTypeCommission:
|
||||
return "分佣"
|
||||
case AgentTransactionTypeWithdrawal:
|
||||
return "提现"
|
||||
case AgentTransactionTypeCommissionDeduct:
|
||||
return "退款佣金回扣"
|
||||
case AgentTransactionTypeAdjustment:
|
||||
return "人工余额调整"
|
||||
default:
|
||||
return "未知"
|
||||
}
|
||||
}
|
||||
|
||||
// GetTransactionStatusName 返回钱包交易状态中文名称。
|
||||
func GetTransactionStatusName(status int) string {
|
||||
switch status {
|
||||
case TransactionStatusSuccess:
|
||||
return "成功"
|
||||
case TransactionStatusFailed:
|
||||
return "失败"
|
||||
case TransactionStatusProcessing:
|
||||
return "处理中"
|
||||
default:
|
||||
return "未知"
|
||||
}
|
||||
}
|
||||
|
||||
// GetWalletAssetTypeName 返回钱包流水资产类型中文名称。
|
||||
func GetWalletAssetTypeName(assetType string) string {
|
||||
switch assetType {
|
||||
case AssetTypeIotCard:
|
||||
return "物联网卡"
|
||||
case AssetTypeDevice:
|
||||
return "设备"
|
||||
case "":
|
||||
return ""
|
||||
default:
|
||||
return "未知"
|
||||
}
|
||||
}
|
||||
|
||||
// GetBusinessPaymentMethodName 返回业务支付方式中文名称。
|
||||
func GetBusinessPaymentMethodName(method string) string {
|
||||
switch method {
|
||||
case PaymentMethodWallet:
|
||||
return "钱包支付"
|
||||
case RechargeMethodWechat:
|
||||
return "微信支付"
|
||||
case RechargeMethodAlipay:
|
||||
return "支付宝支付"
|
||||
case RechargeMethodBank:
|
||||
return "银行转账"
|
||||
case RechargeMethodOffline:
|
||||
return "线下支付"
|
||||
case "":
|
||||
return ""
|
||||
default:
|
||||
return "未知"
|
||||
}
|
||||
}
|
||||
86
pkg/constants/wecom.go
Normal file
86
pkg/constants/wecom.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package constants
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
// IntegrationProviderWeCom 表示企业微信外部系统。
|
||||
IntegrationProviderWeCom = "wecom"
|
||||
// IntegrationOperationWeComAccessToken 表示获取企业微信应用 access_token。
|
||||
IntegrationOperationWeComAccessToken = "get_access_token"
|
||||
// IntegrationOperationWeComVisibleMembers 表示获取应用可见成员。
|
||||
IntegrationOperationWeComVisibleMembers = "list_visible_members"
|
||||
// IntegrationOperationWeComTemplateDetail 表示获取企微审批模板详情。
|
||||
IntegrationOperationWeComTemplateDetail = "get_template_detail"
|
||||
// IntegrationOperationWeComAttachmentUpload 表示上传审批附件临时素材。
|
||||
IntegrationOperationWeComAttachmentUpload = "upload_approval_attachment"
|
||||
// IntegrationOperationWeComApprovalSubmit 表示提交企业微信审批申请。
|
||||
IntegrationOperationWeComApprovalSubmit = "submit_approval"
|
||||
// IntegrationOperationWeComApprovalCallback 表示接收企业微信审批状态回调。
|
||||
IntegrationOperationWeComApprovalCallback = "approval_callback"
|
||||
// IntegrationOperationWeComApprovalDetail 表示获取企业微信审批详情。
|
||||
IntegrationOperationWeComApprovalDetail = "get_approval_detail"
|
||||
// IntegrationOperationWeComApprovalInfo 表示按提交时间窗批量获取企业微信审批单号。
|
||||
IntegrationOperationWeComApprovalInfo = "get_approval_info"
|
||||
// WeComApplicationResourceType 表示企业微信应用配置资源。
|
||||
WeComApplicationResourceType = "wecom_application"
|
||||
// WeComApprovalSceneResourceType 表示企业微信审批场景配置资源。
|
||||
WeComApprovalSceneResourceType = "wecom_approval_scene"
|
||||
// WeComApprovalInstanceResourceType 表示企业微信审批申请资源。
|
||||
WeComApprovalInstanceResourceType = "wecom_approval"
|
||||
// WeComTokenRefreshAdvance 表示 access_token 提前刷新的安全窗口。
|
||||
WeComTokenRefreshAdvance = 5 * time.Minute
|
||||
// WeComTokenLockTTL 表示单应用并发回源短锁有效期。
|
||||
WeComTokenLockTTL = 10 * time.Second
|
||||
// WeComTokenWaitTimeout 表示等待其他实例完成 token 回源的最长时间。
|
||||
WeComTokenWaitTimeout = 2 * time.Second
|
||||
// WeComTokenWaitPollInterval 表示等待其他实例回填 token 时的轮询间隔。
|
||||
WeComTokenWaitPollInterval = 100 * time.Millisecond
|
||||
// WeComMaxResponseBodyBytes 表示企业微信响应正文允许读取的最大字节数。
|
||||
WeComMaxResponseBodyBytes int64 = 1 << 20
|
||||
// WeComDefaultHTTPTimeout 表示企业微信外呼默认超时时间。
|
||||
WeComDefaultHTTPTimeout = 10 * time.Second
|
||||
// WeComDirectoryMaxResponseBodyBytes 表示通讯录响应正文允许读取的最大字节数。
|
||||
WeComDirectoryMaxResponseBodyBytes int64 = 10 << 20
|
||||
// WeComRootDepartmentID 表示企业微信根部门 ID。
|
||||
WeComRootDepartmentID int64 = 1
|
||||
// WeComMemberSyncBatchSize 表示可见成员快照批量写入大小。
|
||||
WeComMemberSyncBatchSize = 500
|
||||
// WeComApprovalMaxAttachmentCount 表示单张企微审批单最多允许的附件数量。
|
||||
WeComApprovalMaxAttachmentCount = 6
|
||||
// WeComApprovalMaxAttachmentBytes 表示企微普通文件临时素材最大字节数。
|
||||
WeComApprovalMaxAttachmentBytes int64 = 20 << 20
|
||||
// WeComApprovalInfoMaxPageSize 表示批量获取审批单号接口单页上限。
|
||||
WeComApprovalInfoMaxPageSize = 100
|
||||
// WeComApprovalInfoMaxWindow 表示批量获取审批单号接口允许的最大时间跨度。
|
||||
WeComApprovalInfoMaxWindow = 31 * 24 * time.Hour
|
||||
// WeComApprovalRecoveryWindow 表示结果未知时围绕实际提交时刻查询的保守时间窗半径。
|
||||
WeComApprovalRecoveryWindow = 5 * time.Minute
|
||||
// WeComApprovalSendingLease 表示提交中记录在进入未知恢复前允许占用的最长时间。
|
||||
WeComApprovalSendingLease = 5 * time.Minute
|
||||
// WeComApprovalPollingInterval 表示未终态审批详情的最短轮询间隔。
|
||||
WeComApprovalPollingInterval = 2 * time.Minute
|
||||
// WeComApprovalRecoveryBatchSize 表示单次恢复扫描的本地记录上限。
|
||||
WeComApprovalRecoveryBatchSize = 100
|
||||
// WeComApprovalUnknownRecoveryBatchSize 表示单轮结果未知外部查询的记录上限。
|
||||
WeComApprovalUnknownRecoveryBatchSize = 10
|
||||
)
|
||||
|
||||
const (
|
||||
// WeComCreatorSourceBound 表示使用系统账号绑定的企微成员发起。
|
||||
WeComCreatorSourceBound = "bound"
|
||||
// WeComCreatorSourceDefault 表示使用应用配置的默认成员发起。
|
||||
WeComCreatorSourceDefault = "default"
|
||||
)
|
||||
|
||||
const (
|
||||
// WeComSubmissionStatusReady 表示企微审批等待提交。
|
||||
WeComSubmissionStatusReady = 0
|
||||
// WeComSubmissionStatusSending 表示提交请求已被 Worker 领取,禁止并发重发。
|
||||
WeComSubmissionStatusSending = 1
|
||||
// WeComSubmissionStatusSubmitted 表示企微已返回审批单号。
|
||||
WeComSubmissionStatusSubmitted = 2
|
||||
// WeComSubmissionStatusFailed 表示企微明确确认提交失败。
|
||||
WeComSubmissionStatusFailed = 3
|
||||
// WeComSubmissionStatusUnknown 表示请求可能已到达企微但结果未知。
|
||||
WeComSubmissionStatusUnknown = 4
|
||||
)
|
||||
@@ -166,6 +166,12 @@ const (
|
||||
CodeExchangeNewAssetNotInStock = 1204 // 新资产非在库状态
|
||||
CodeExchangeAssetNotExchanged = 1205 // 资产未处于已换货状态,不允许转新
|
||||
CodeExchangeMigrationFailed = 1206 // 数据迁移失败
|
||||
CodeExchangeActiveRefund = 1207 // 资产存在未终结退款申请
|
||||
CodePaymentMethodUnavailable = 1208 // 当前资产不支持所选支付方式
|
||||
|
||||
// 企业微信相关错误 (1210-1219)
|
||||
CodeWeComApplicationNotFound = 1210 // 企业微信应用配置不存在
|
||||
CodeWeComCredentialInvalid = 1211 // 企业微信加密凭据不可用
|
||||
|
||||
// 服务端错误 (2000-2999) -> 5xx HTTP 状态码
|
||||
CodeInternalError = 2001 // 内部服务器错误
|
||||
@@ -306,6 +312,10 @@ var allErrorCodes = []int{
|
||||
CodeExchangeNewAssetNotInStock,
|
||||
CodeExchangeAssetNotExchanged,
|
||||
CodeExchangeMigrationFailed,
|
||||
CodeExchangeActiveRefund,
|
||||
CodePaymentMethodUnavailable,
|
||||
CodeWeComApplicationNotFound,
|
||||
CodeWeComCredentialInvalid,
|
||||
CodeInternalError,
|
||||
CodeDatabaseError,
|
||||
CodeRedisError,
|
||||
@@ -439,6 +449,10 @@ var errorMessages = map[int]string{
|
||||
CodeExchangeNewAssetNotInStock: "新资产非在库状态,不可用于换货",
|
||||
CodeExchangeAssetNotExchanged: "资产当前状态不允许转新",
|
||||
CodeExchangeMigrationFailed: "换货数据迁移失败",
|
||||
CodeExchangeActiveRefund: "该资产存在退款申请",
|
||||
CodePaymentMethodUnavailable: "当前资产不支持所选支付方式",
|
||||
CodeWeComApplicationNotFound: "企业微信应用配置不存在或已禁用",
|
||||
CodeWeComCredentialInvalid: "企业微信凭据配置无效",
|
||||
CodeInvalidCredentials: "用户名或密码错误",
|
||||
CodeAccountLocked: "账号已锁定",
|
||||
CodePasswordExpired: "密码已过期",
|
||||
|
||||
@@ -71,9 +71,11 @@ func BuildDocHandlers() *bootstrap.Handlers {
|
||||
AgentRecharge: admin.NewAgentRechargeHandler(nil, nil),
|
||||
Refund: admin.NewRefundHandler(nil),
|
||||
OrderPackageInvalidate: admin.NewOrderPackageInvalidateHandler(nil),
|
||||
AssetPackageBatchOrder: admin.NewAssetPackageBatchOrderHandler(nil, nil),
|
||||
ClientWechat: app.NewClientWechatHandler(nil, nil, nil),
|
||||
SuperAdmin: admin.NewSuperAdminHandler(nil),
|
||||
SystemConfig: admin.NewSystemConfigHandler(nil, nil),
|
||||
WeCom: admin.NewWeComHandler(nil, nil),
|
||||
AgentOpenAPI: openapiHandler.NewHandler(nil, nil),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,15 @@ import (
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
|
||||
packageExpiryApp "github.com/break/junhong_cmp_fiber/internal/application/packageexpiry"
|
||||
"github.com/break/junhong_cmp_fiber/internal/exporter"
|
||||
"github.com/break/junhong_cmp_fiber/internal/gateway"
|
||||
"github.com/break/junhong_cmp_fiber/internal/infrastructure/integrationlog"
|
||||
"github.com/break/junhong_cmp_fiber/internal/infrastructure/messaging/outbox"
|
||||
notification "github.com/break/junhong_cmp_fiber/internal/infrastructure/notification"
|
||||
packageExpiryInfra "github.com/break/junhong_cmp_fiber/internal/infrastructure/packageexpiry"
|
||||
"github.com/break/junhong_cmp_fiber/internal/polling"
|
||||
packageExpiryQuery "github.com/break/junhong_cmp_fiber/internal/query/packageexpiry"
|
||||
iot_card_svc "github.com/break/junhong_cmp_fiber/internal/service/iot_card"
|
||||
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
|
||||
"github.com/break/junhong_cmp_fiber/internal/task"
|
||||
@@ -68,6 +72,7 @@ func (h *Handler) RegisterHandlers() *asynq.ServeMux {
|
||||
h.registerIotCardImportHandler()
|
||||
h.registerDeviceImportHandler()
|
||||
h.registerOrderPackageInvalidateHandler()
|
||||
h.registerAssetPackageBatchOrderHandler()
|
||||
h.registerExportHandlers()
|
||||
h.registerCommissionStatsHandlers()
|
||||
h.registerCommissionCalculationHandler()
|
||||
@@ -78,6 +83,7 @@ func (h *Handler) RegisterHandlers() *asynq.ServeMux {
|
||||
h.registerAlertCheckHandler()
|
||||
h.registerDataCleanupHandler()
|
||||
h.registerNotificationCleanupHandler()
|
||||
h.registerPackageExpiryReminderHandler()
|
||||
h.registerAutoPurchaseHandler()
|
||||
h.registerDailyTrafficFlushHandler()
|
||||
|
||||
@@ -119,6 +125,18 @@ func (h *Handler) registerOrderPackageInvalidateHandler() {
|
||||
h.logger.Info("注册订单套餐批量失效任务处理器", zap.String("task_type", constants.TaskTypeOrderPackageInvalidate))
|
||||
}
|
||||
|
||||
func (h *Handler) registerAssetPackageBatchOrderHandler() {
|
||||
handler := task.NewAssetPackageBatchOrderHandler(
|
||||
h.workerResult.Stores.AssetPackageBatchOrderTask,
|
||||
h.workerResult.Stores.Shop,
|
||||
h.workerResult.Services.AssetPackageOrderCreator,
|
||||
h.storage,
|
||||
h.logger,
|
||||
)
|
||||
h.mux.HandleFunc(constants.TaskTypeAssetPackageBatchOrder, handler.Handle)
|
||||
h.logger.Info("注册资产套餐批量订购任务处理器", zap.String("task_type", constants.TaskTypeAssetPackageBatchOrder))
|
||||
}
|
||||
|
||||
func (h *Handler) registerDeviceImportHandler() {
|
||||
deviceImportHandler := task.NewDeviceImportHandler(
|
||||
h.db,
|
||||
@@ -131,6 +149,7 @@ func (h *Handler) registerDeviceImportHandler() {
|
||||
h.workerResult.Stores.AssetIdentifier,
|
||||
h.storage,
|
||||
h.logger,
|
||||
h.workerResult.Services.DeviceBatchAllocator,
|
||||
)
|
||||
|
||||
h.mux.HandleFunc(constants.TaskTypeDeviceImport, deviceImportHandler.HandleDeviceImport)
|
||||
@@ -284,6 +303,15 @@ func (h *Handler) registerNotificationCleanupHandler() {
|
||||
h.logger.Info("注册站内通知保留清理任务处理器", zap.String("task_type", constants.TaskTypeNotificationCleanup))
|
||||
}
|
||||
|
||||
func (h *Handler) registerPackageExpiryReminderHandler() {
|
||||
query := packageExpiryQuery.NewQuery(h.db)
|
||||
publisher := packageExpiryInfra.NewReminderPublisher(h.db, outbox.NewRepository())
|
||||
service := packageExpiryApp.NewReminderService(query, publisher)
|
||||
handler := task.NewPackageExpiryReminderHandler(service, h.logger)
|
||||
h.mux.HandleFunc(constants.TaskTypePackageExpiryReminder, handler.Handle)
|
||||
h.logger.Info("注册套餐临期节点提醒任务处理器", zap.String("task_type", constants.TaskTypePackageExpiryReminder))
|
||||
}
|
||||
|
||||
func (h *Handler) registerAutoPurchaseHandler() {
|
||||
autoPurchaseHandler := task.NewAutoPurchaseHandler(
|
||||
h.db,
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
packagepkg "github.com/break/junhong_cmp_fiber/internal/service/package"
|
||||
pollingSvc "github.com/break/junhong_cmp_fiber/internal/service/polling"
|
||||
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
|
||||
"github.com/break/junhong_cmp_fiber/internal/task"
|
||||
)
|
||||
|
||||
// OrderExpirer 订单超时取消接口
|
||||
@@ -21,6 +22,7 @@ type OrderExpirer interface {
|
||||
// WorkerStores Worker 侧所有 Store 的集合
|
||||
type WorkerStores struct {
|
||||
AssetOperationLog *postgres.AssetOperationLogStore
|
||||
AssetAllocationRecord *postgres.AssetAllocationRecordStore
|
||||
IotCardImportTask *postgres.IotCardImportTaskStore
|
||||
IotCard *postgres.IotCardStore
|
||||
DeviceImportTask *postgres.DeviceImportTaskStore
|
||||
@@ -50,22 +52,25 @@ type WorkerStores struct {
|
||||
PersonalCustomer *postgres.PersonalCustomerStore
|
||||
PersonalCustomerPhone *postgres.PersonalCustomerPhoneStore
|
||||
OrderPackageInvalidateTask *postgres.OrderPackageInvalidateTaskStore
|
||||
AssetPackageBatchOrderTask *postgres.AssetPackageBatchOrderTaskStore
|
||||
}
|
||||
|
||||
// WorkerServices Worker 侧所有 Service 的集合
|
||||
type WorkerServices struct {
|
||||
CardObservation *cardObservationApp.Service
|
||||
CardObservationSeries *cardObservationApp.SeriesAttemptService
|
||||
ObservationSeriesEvents cardObservationApp.SeriesEventWriter
|
||||
CommissionCalculation *commission_calculation.Service
|
||||
CommissionStats *commission_stats.Service
|
||||
UsageService *packagepkg.UsageService
|
||||
ActivationService *packagepkg.ActivationService
|
||||
ResetService *packagepkg.ResetService
|
||||
AlertService *pollingSvc.AlertService
|
||||
CleanupService *pollingSvc.CleanupService
|
||||
StopResumeService packagepkg.StopResumeCallback // 停复机服务,用于注入 Scheduler
|
||||
OrderExpirer OrderExpirer // 订单超时取消服务(接口类型,避免循环依赖)
|
||||
CardObservation *cardObservationApp.Service
|
||||
CardObservationSeries *cardObservationApp.SeriesAttemptService
|
||||
ObservationSeriesEvents cardObservationApp.SeriesEventWriter
|
||||
CommissionCalculation *commission_calculation.Service
|
||||
CommissionStats *commission_stats.Service
|
||||
UsageService *packagepkg.UsageService
|
||||
ActivationService *packagepkg.ActivationService
|
||||
ResetService *packagepkg.ResetService
|
||||
AlertService *pollingSvc.AlertService
|
||||
CleanupService *pollingSvc.CleanupService
|
||||
StopResumeService packagepkg.StopResumeCallback // 停复机服务,用于注入 Scheduler
|
||||
OrderExpirer OrderExpirer // 订单超时取消服务(接口类型,避免循环依赖)
|
||||
AssetPackageOrderCreator task.AssetPackageBatchOrderCreator // 批量订购复用后台单笔订单规则
|
||||
DeviceBatchAllocator task.DeviceBatchAllocationExecutor // 设备CSV批量分配复用现有业务规则
|
||||
}
|
||||
|
||||
// WorkerBootstrapResult Worker Bootstrap 结果
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/pkg/config"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -35,6 +36,9 @@ func (s *Service) GenerateFileKey(purpose, fileName string) (string, error) {
|
||||
if ext == "" {
|
||||
ext = ".bin"
|
||||
}
|
||||
if (purpose == constants.StoragePurposeAssetPackageBatchOrder || purpose == constants.StoragePurposeDeviceBatchAllocation) && !strings.EqualFold(ext, ".csv") {
|
||||
return "", errors.New(errors.CodeInvalidParam, "批量业务文件必须为CSV格式")
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
id := uuid.New().String()
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package storage
|
||||
|
||||
import "github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
|
||||
type PresignResult struct {
|
||||
URL string `json:"url"`
|
||||
FileKey string `json:"file_key"`
|
||||
@@ -15,4 +17,6 @@ var PurposeMappings = map[string]PurposeMapping{
|
||||
"iot_import": {Prefix: "imports", ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
|
||||
"export": {Prefix: "exports", ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
|
||||
"attachment": {Prefix: "attachments", ContentType: ""},
|
||||
constants.StoragePurposeAssetPackageBatchOrder: {Prefix: constants.AssetPackageBatchOrderStoragePrefix, ContentType: "text/csv"},
|
||||
constants.StoragePurposeDeviceBatchAllocation: {Prefix: constants.DeviceBatchAllocationStoragePrefix, ContentType: "text/csv"},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user