补齐三套环境配置、测试环境部署门禁与 system_config 初始化,并按当前无企微应用的约束将企微凭据改为明文存储。 Constraint: 当前测试环境尚无企微应用及历史企微密文数据 Rejected: 使用启动环境变量加密企微凭据 | 用户明确要求直接明文保存并移除加密密钥 Confidence: high Scope-risk: moderate Directive: 企微真实闭环完成前保持两个旧审批入口开关为 true Tested: gofmt;git diff --check;bash -n;docker compose config;Gitea workflow YAML 解析;OpenAPI 重新生成 Not-tested: go test;常规 go build;LSP;实际数据库迁移;真实测试环境部署;企微真实联调
110 lines
4.7 KiB
Go
110 lines
4.7 KiB
Go
package wecom
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/clause"
|
|
|
|
"github.com/break/junhong_cmp_fiber/internal/model"
|
|
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
|
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
|
)
|
|
|
|
// ApplicationRepository 持久化企业微信应用配置。
|
|
type ApplicationRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
// NewApplicationRepository 创建企业微信应用 Repository。
|
|
func NewApplicationRepository(db *gorm.DB) *ApplicationRepository {
|
|
return &ApplicationRepository{db: db}
|
|
}
|
|
|
|
// FindByIdentityForUpdate 在事务中锁定企业与应用唯一配置。
|
|
func (r *ApplicationRepository) FindByIdentityForUpdate(ctx context.Context, tx *gorm.DB, corpID string, agentID int64) (*model.WeComApplication, error) {
|
|
var application model.WeComApplication
|
|
err := tx.WithContext(ctx).Clauses(clause.Locking{Strength: "UPDATE"}).
|
|
Where("corp_id = ? AND agent_id = ?", corpID, agentID).First(&application).Error
|
|
if err == gorm.ErrRecordNotFound {
|
|
return nil, nil
|
|
}
|
|
if err != nil {
|
|
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询企业微信应用配置失败")
|
|
}
|
|
return &application, nil
|
|
}
|
|
|
|
// Create 创建企业微信应用配置。
|
|
func (r *ApplicationRepository) Create(ctx context.Context, tx *gorm.DB, application *model.WeComApplication) error {
|
|
if err := tx.WithContext(ctx).Create(application).Error; err != nil {
|
|
return errors.Wrap(errors.CodeDatabaseError, err, "创建企业微信应用配置失败")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Update 更新企业微信应用配置及连接凭据。
|
|
func (r *ApplicationRepository) Update(ctx context.Context, tx *gorm.DB, application *model.WeComApplication) error {
|
|
updates := map[string]any{
|
|
"name": application.Name, "secret": application.Secret,
|
|
"callback_token": application.CallbackToken,
|
|
"encoding_aes_key": application.EncodingAESKey,
|
|
"default_creator_userid": application.DefaultCreatorUserID,
|
|
"default_creator_name": application.DefaultCreatorName,
|
|
"status": application.Status, "updated_by": application.UpdatedBy, "updated_at": application.UpdatedAt,
|
|
}
|
|
if err := tx.WithContext(ctx).Model(&model.WeComApplication{}).Where("id = ?", application.ID).Updates(updates).Error; err != nil {
|
|
return errors.Wrap(errors.CodeDatabaseError, err, "更新企业微信应用配置失败")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// UpdateDefaultCreator 更新应用默认审批发起人快照。
|
|
func (r *ApplicationRepository) UpdateDefaultCreator(ctx context.Context, tx *gorm.DB, applicationID uint, userID, name string, operatorID uint, updatedAt time.Time) error {
|
|
if err := tx.WithContext(ctx).Model(&model.WeComApplication{}).Where("id = ? AND deleted_at IS NULL", applicationID).Updates(map[string]any{
|
|
"default_creator_userid": userID,
|
|
"default_creator_name": name,
|
|
"updated_by": operatorID,
|
|
"updated_at": updatedAt,
|
|
}).Error; err != nil {
|
|
return errors.Wrap(errors.CodeDatabaseError, err, "更新企业微信默认审批发起人失败")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// List 分页查询企业微信应用配置及连接凭据。
|
|
func (r *ApplicationRepository) List(ctx context.Context, page, pageSize int) ([]model.WeComApplication, int64, error) {
|
|
query := r.db.WithContext(ctx).Model(&model.WeComApplication{})
|
|
var total int64
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, 0, errors.Wrap(errors.CodeDatabaseError, err, "统计企业微信应用配置失败")
|
|
}
|
|
var applications []model.WeComApplication
|
|
if err := query.Order("id ASC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&applications).Error; err != nil {
|
|
return nil, 0, errors.Wrap(errors.CodeDatabaseError, err, "查询企业微信应用列表失败")
|
|
}
|
|
return applications, total, nil
|
|
}
|
|
|
|
// GetEnabled 查询启用的企业微信应用及连接凭据。
|
|
func (r *ApplicationRepository) GetEnabled(ctx context.Context, applicationID uint) (*model.WeComApplication, error) {
|
|
var application model.WeComApplication
|
|
if err := r.db.WithContext(ctx).Where("id = ? AND status = ?", applicationID, constants.StatusEnabled).First(&application).Error; err != nil {
|
|
if err == gorm.ErrRecordNotFound {
|
|
return nil, errors.New(errors.CodeWeComApplicationNotFound)
|
|
}
|
|
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询企业微信应用配置失败")
|
|
}
|
|
return &application, nil
|
|
}
|
|
|
|
// MarkConnected 记录最近一次成功取得 access_token 的时间。
|
|
func (r *ApplicationRepository) MarkConnected(ctx context.Context, applicationID uint, connectedAt time.Time) error {
|
|
if err := r.db.WithContext(ctx).Model(&model.WeComApplication{}).Where("id = ?", applicationID).
|
|
Update("last_connected_at", connectedAt.UTC()).Error; err != nil {
|
|
return errors.Wrap(errors.CodeDatabaseError, err, "更新企业微信最近连接时间失败")
|
|
}
|
|
return nil
|
|
}
|