Compare commits

...

22 Commits

Author SHA1 Message Date
gy
1c3e0b8f52 feat 修改头部字段 2025-09-10 13:24:06 +08:00
gy
e85207132f feat 增加一个jwt检验的校验绕过逻辑 2025-09-09 18:51:25 +08:00
e667837d6a Merge branch 'feat-xjj-aschatFunction#A116' 2025-09-01 11:23:50 +08:00
09a4df2b21 Update handler.go 2025-09-01 11:15:26 +08:00
d20cd6d41b Merge branch 'feat-xjj-aschatFunction#A116' 2025-09-01 10:03:15 +08:00
0e1c8df1ee Update check_login.go 2025-08-28 14:45:15 +08:00
645770c9fc Update check_login.go 2025-08-28 14:08:53 +08:00
077f743e54 Update check_login.go 2025-08-28 11:01:26 +08:00
fe9173b872 Update check_login.go 2025-08-28 10:43:19 +08:00
41e28c9aed Merge branch 'jng' 2025-08-27 13:59:21 +08:00
d54a3df245 Update reconciliation.go 2025-08-27 11:29:01 +08:00
e2962353b9 更新 2025-08-27 10:23:47 +08:00
07326e3af8 feat: 增加自动回复开关 2025-08-21 14:16:51 +08:00
c135849195 Merge branch 'feature-multicast-daiyb' 2025-08-13 09:18:53 +08:00
sxy
7488f76c08 Merge branch 'feat-sxy-import' 2025-08-13 09:17:03 +08:00
8aab8ff4e6 更新 pkg/service/upload/upload.go
增加日志
2025-08-12 06:03:27 +00:00
857b7712ae Merge branch 'jng' 2025-08-12 13:35:23 +08:00
adb956dacb update oss config 2025-08-12 11:59:31 +08:00
b063a38f76 Merge branch 'jng' 2025-08-11 16:41:50 +08:00
6c4578b8aa update oss config 2025-08-11 16:27:26 +08:00
25eed16be5 添加source 2025-08-07 11:59:25 +08:00
cdf4b77aa7 Update dubbogo.yaml 2025-07-07 15:28:30 +08:00
19 changed files with 2215 additions and 4021 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-triple. DO NOT EDIT. // Code generated by protoc-gen-go-triple. DO NOT EDIT.
// versions: // versions:
// - protoc-gen-go-triple v1.0.8 // - protoc-gen-go-triple v1.0.5
// - protoc v4.24.0--rc1 // - protoc v6.32.0
// source: pb/bundle.proto // source: pb/bundle.proto
package bundle package bundle

View File

@ -14,12 +14,12 @@ BosBaseDir = "fonchain-main"
BosHttp = "https://" BosHttp = "https://"
BosDomain = "cdns.fontree.cn" BosDomain = "cdns.fontree.cn"
[oss] [oss]
AccessKeyId = "LTAI5tCx628rkZ65oi5F5nxu" AccessKeyId = "${OSS_AK}"
AccessKeySecret = "WjSLa9tWs8RTdUmhKu3HLXIMogdUbo" AccessKeySecret = "${OSS_SK}"
Endpoint = "cdn-test.cdn.szjixun.cn" Endpoint = "${OSS_ENDPOINTT}"
BucketName = "fontree-test2" BucketName = "${OSS_BUCKETNAME}"
BaseDir = "fonchain-main" BaseDir = "fontree-fiee-test"
CdnHost = "https://cdn-test.szjixun.cn" CdnHost = "${OSS_CDN}"
[redis] [redis]
RedisDB = "2" RedisDB = "2"
RedisAddr = "127.0.0.1:6379" RedisAddr = "127.0.0.1:6379"

View File

@ -15,12 +15,12 @@ BosBaseDir = "fiee"
BosHttp = "https://" BosHttp = "https://"
BosDomain = "cdns.fontree.cn" BosDomain = "cdns.fontree.cn"
[oss] [oss]
AccessKeyId = "LTAI5tLz1fSK53FQAEC9uNSb" AccessKeyId = "OSS_AK"
AccessKeySecret = "oGB9chrQzQzITXR2IGv37Ji5WxZh4j" AccessKeySecret = "OSS_SK"
Endpoint = "oss-cn-hangzhou.aliyuncs.com" Endpoint = "OSS_ENDPOINTT"
BucketName = "fontree-test" BucketName = "OSS_BUCKETNAME"
BaseDir = "fiee" BaseDir = "fontree-fiee-test"
CdnHost = "https://cdn-test.szjixun.cn" CdnHost = "OSS_CDN"
[redis] [redis]
RedisDB = "2" RedisDB = "2"

View File

@ -4,7 +4,7 @@ dubbo:
protocol: zookeeper protocol: zookeeper
timeout: 3s timeout: 3s
# address: 121.229.45.214:9004 # address: 121.229.45.214:9004
address: 172.16.100.93:2181 address: 127.0.0.1:2181
# address: 127.0.0.1:2181 # address: 127.0.0.1:2181
# address: 114.218.158.24:2181 # address: 114.218.158.24:2181
consumer: consumer:

View File

@ -26,12 +26,12 @@ TelNum = "18021272627"
Password = "Gy.123456" Password = "Gy.123456"
[oss] [oss]
AccessKeyId = "LTAI5tHfjSmWXHqfWgaL7Uo5" AccessKeyId = "OSS_AK"
AccessKeySecret = "kOPctFZ3DHsbdSSym1fLyDK39hkzPI" AccessKeySecret = "OSS_SK"
Endpoint = "oss-cn-hangzhou.aliyuncs.com" Endpoint = "OSS_ENDPOINTT"
BucketName = "erp-k8s-store" BucketName = "OSS_BUCKETNAME"
BaseDir = "fiee" BaseDir = "fontree-fiee"
CdnHost = "https://e-cdn.fontree.cn" CdnHost = "OSS_CDN"
[stripe] [stripe]
Webhookkey = "whsec_Mol32WD1KcKHUdYsSwap0LR03q2g9qNY" Webhookkey = "whsec_Mol32WD1KcKHUdYsSwap0LR03q2g9qNY"

View File

@ -15,20 +15,12 @@ BosBaseDir = "fiee"
BosHttp = "https://" BosHttp = "https://"
BosDomain = "cdns.fontree.cn" BosDomain = "cdns.fontree.cn"
[oss] [oss]
AccessKeyId = "LTAI5tLz1fSK53FQAEC9uNSb" AccessKeyId = "OSS_AK"
AccessKeySecret = "oGB9chrQzQzITXR2IGv37Ji5WxZh4j" AccessKeySecret = "OSS_SK"
Endpoint = "oss-cn-hangzhou.aliyuncs.com" Endpoint = "OSS_ENDPOINTT"
BucketName = "fontree-test" BucketName = "OSS_BUCKETNAME"
BaseDir = "fiee" BaseDir = "fontree-fiee-test"
CdnHost = "https://cdn-test.szjixun.cn" CdnHost = "OSS_CDN"
[oss]
AccessKeyId="LTAI5tLz1fSK53FQAEC9uNSb"
AccessKeysecret ="oGB9chrQzQzITXR2IGv37Ji5WxZh4j"
Endpoint = "oss-cn-hangzhou.aliyuncs.com"
BucketName = "fontree-test"
BaseDir = "fiee"
CdnHost = "https://cdn-test.szjixun.cn"
[redis] [redis]
RedisDB = "2" RedisDB = "2"

View File

@ -4,9 +4,12 @@ import (
"fmt" "fmt"
"fonchain-fiee/pkg/common" "fonchain-fiee/pkg/common"
"github.com/spf13/viper" "github.com/spf13/viper"
"go.uber.org/zap"
"gopkg.in/ini.v1" "gopkg.in/ini.v1"
"os" "os"
"reflect"
"strconv" "strconv"
"strings"
) )
var ( var (
@ -249,5 +252,63 @@ func Viper(iniConf string) (err error) {
panic("viper.Unmarshal failed" + err.Error()) panic("viper.Unmarshal failed" + err.Error())
return return
} }
traverseFields(reflect.ValueOf(*ConfigData), "", ConfigData)
zap.L().Info("ConfigData", zap.Any("ConfigData", ConfigData))
fmt.Printf("ConfigData--%+v", ConfigData)
return return
} }
func traverseFields(value reflect.Value, prefix string, configPtr interface{}) {
valueType := value.Type()
prefixEnv := "${"
suffixEnv := "}"
// 遍历结构体的字段
for i := 0; i < valueType.NumField(); i++ {
field := valueType.Field(i)
fieldValue := value.Field(i)
// 拼接字段名(带有前缀)
fieldName := prefix + field.Name
// 判断字段的类型
if fieldValue.Kind() == reflect.Struct {
// 递归遍历嵌套结构体字段
traverseFields(fieldValue, fieldName+".", configPtr)
} else {
// 获取字段的值
fieldValueStr := fmt.Sprintf("%v", fieldValue.Interface())
// 判断是不是需要通过环境变量获取
if len(fieldValueStr) > 3 && strings.HasPrefix(fieldValueStr, prefixEnv) && strings.HasSuffix(fieldValueStr, suffixEnv) {
end := len(fieldValueStr) - len(suffixEnv)
var hasDefault bool
if strings.Index(fieldValueStr, "|") > 0 {
hasDefault = true
end = strings.Index(fieldValueStr, "|")
}
envStr := fieldValueStr[len(prefixEnv):end]
getValue := os.Getenv(envStr)
if getValue == "" && hasDefault {
getValue = fieldValueStr[end+1 : len(fieldValueStr)-len(suffixEnv)]
}
setSubFieldValue(configPtr, fieldName, getValue)
}
}
}
}
func setSubFieldValue(configPtr interface{}, fieldPath string, newValue interface{}) {
value := reflect.ValueOf(configPtr).Elem()
fields := strings.Split(fieldPath, ".")
for _, field := range fields {
value = value.FieldByName(field)
if !value.IsValid() {
return // 字段不存在,直接返回
}
if value.Kind() == reflect.Ptr {
value = value.Elem() // 解引用指针类型的字段
}
}
// 检查字段是否可设置
if value.CanSet() {
// 根据字段类型,将新值转换为对应类型并设置字段的值
newValue := reflect.ValueOf(newValue).Convert(value.Type())
value.Set(newValue)
}
}

View File

@ -129,7 +129,7 @@ func MakeThumbnail(imagePath, savePath string) error {
} }
func (u *Upload) PutBos(filePath string, mediaType string, needRemove bool) (url string, err error) { func (u *Upload) PutBos(filePath string, mediaType string, needRemove bool) (url string, err error) {
BOSClient, err := objstorage.NewOSS(config.ConfigData.Oss.AccessKeyId, config.ConfigData.Oss.AccessKeySecret, config.ConfigData.Oss.Endpoint) BOSClient, err := objstorage.NewOSS(os.Getenv(config.ConfigData.Oss.AccessKeyId), os.Getenv(config.ConfigData.Oss.AccessKeySecret), os.Getenv(config.ConfigData.Oss.Endpoint))
if err != nil { if err != nil {
logger.Errorf("PutBos NewOOS err ", err) logger.Errorf("PutBos NewOOS err ", err)
err = errors.New(e.GetMsg(e.ErrorUploadBos)) err = errors.New(e.GetMsg(e.ErrorUploadBos))
@ -148,14 +148,14 @@ func (u *Upload) PutBos(filePath string, mediaType string, needRemove bool) (url
} }
filePath = strings.Replace(filePath, "./runtime", "", 1) filePath = strings.Replace(filePath, "./runtime", "", 1)
var objectName string = fmt.Sprintf("%s/%s%s", config.ConfigData.Oss.BaseDir, config.Env, filePath) var objectName string = fmt.Sprintf("%s/%s%s", config.ConfigData.Oss.BaseDir, config.Env, filePath)
_, err = BOSClient.PutObjectFromBytes(config.ConfigData.Oss.BucketName, objectName, fileBytes) _, err = BOSClient.PutObjectFromBytes(os.Getenv(config.ConfigData.Oss.BucketName), objectName, fileBytes)
if err != nil { if err != nil {
logger.Errorf("PutBos PutObject err %+v", err.Error()) logger.Errorf("PutBos PutObject err %+v", err.Error())
err = errors.New(e.GetMsg(e.ErrorUploadBos)) err = errors.New(e.GetMsg(e.ErrorUploadBos))
return return
} }
//url = fmt.Sprintf("%s%s%s/%s", config.BosHttp, config.BosBucketName, config.BosUrl, objectName) //url = fmt.Sprintf("%s%s%s/%s", config.BosHttp, config.BosBucketName, config.BosUrl, objectName)
url = fmt.Sprintf("%s/%s", config.ConfigData.Oss.CdnHost, objectName) url = fmt.Sprintf("%s/%s", os.Getenv(config.ConfigData.Oss.CdnHost), objectName)
return return
} }

View File

@ -89,9 +89,10 @@ func CheckWebLogin(provider *account.AccountClientImpl) gin.HandlerFunc {
service.NotLoginRes(ctx, logic.ConvertLoginMsg(ctx, e.ErrNotLogin)) service.NotLoginRes(ctx, logic.ConvertLoginMsg(ctx, e.ErrNotLogin))
return return
} }
fmt.Println("authorization", authorization)
jwt, err := secret.GetJwtFromStr(authorization) jwt, err := secret.GetJwtFromStr(authorization)
fmt.Println("jwt", jwt)
fmt.Println("jwt_err", err)
logger.Info("---------end帐号转jwt:时间:", time.Now().Sub(startTime)) logger.Info("---------end帐号转jwt:时间:", time.Now().Sub(startTime))
if err != nil { if err != nil {
service.NotLoginRes(ctx, err.Error()) service.NotLoginRes(ctx, err.Error())
@ -107,20 +108,24 @@ func CheckWebLogin(provider *account.AccountClientImpl) gin.HandlerFunc {
info, err := service.AccountProvider.DecryptJwt(ctx, &req) info, err := service.AccountProvider.DecryptJwt(ctx, &req)
logger.Info("---------end帐号微服务解密:时间:", time.Now().Sub(startTime)) logger.Info("---------end帐号微服务解密:时间:", time.Now().Sub(startTime))
fmt.Println("DecryptJwt", info)
fmt.Println("DecryptJwtErr:----->", err)
if err != nil { if err != nil {
service.NotLoginRes(ctx, err.Error()) service.NotLoginRes(ctx, err.Error())
return return
} }
//if info.OfflineCode == e.OfflineSqueeze { //if info.OfflineCode == e.OfflineSqueeze {
// service.Error(ctx, e.NotLoginSqueeze, errors.New(e.ErrOfflineSqueeze)) // service.Error(ctx, e.NotLoginSqueeze, errors.New(e.ErrOfflineSqueeze))
// return // return
//} //}
if info.IsOffline == true { if info.IsOffline == true {
//如果是来自体制外的请求,过滤挤掉校验
if !(ctx != nil && (ctx.GetHeader("origin") == "https://erp-out.szjixun.cn")) {
service.ErrorWeb(ctx, e.NotLogin, errors.New(logic.ConvertOfflineMsg(ctx, e.ErrOffline))) service.ErrorWeb(ctx, e.NotLogin, errors.New(logic.ConvertOfflineMsg(ctx, e.ErrOffline)))
return return
} }
}
//1 获取用户的账号信息 //1 获取用户的账号信息
infoReq := &account.InfoRequest{ infoReq := &account.InfoRequest{
@ -130,7 +135,8 @@ func CheckWebLogin(provider *account.AccountClientImpl) gin.HandlerFunc {
} }
infoRes, err := service.AccountProvider.Info(ctx, infoReq) infoRes, err := service.AccountProvider.Info(ctx, infoReq)
fmt.Println("infoRes", infoRes)
fmt.Println("infoResErr", err)
logger.Info("---------end帐号info时间:", time.Now().Sub(startTime)) logger.Info("---------end帐号info时间:", time.Now().Sub(startTime))
if err != nil { if err != nil {

View File

@ -135,6 +135,8 @@ func NewRouter() *gin.Engine {
v1.POST("aschat/autoReplyRuler/update", asChat.Handler.UpdateChatAutoReplyRuler) v1.POST("aschat/autoReplyRuler/update", asChat.Handler.UpdateChatAutoReplyRuler)
v1.POST("aschat/autoReplyRuler/detail", asChat.Handler.GetChatAutoReplyRulerDetail) v1.POST("aschat/autoReplyRuler/detail", asChat.Handler.GetChatAutoReplyRulerDetail)
v1.POST("aschat/autoReplyRuler/query", asChat.Handler.GetChatAutoReplyRulerList) v1.POST("aschat/autoReplyRuler/query", asChat.Handler.GetChatAutoReplyRulerList)
v1.POST("aschat/autoReplyRuler/userSwitch/get", asChat.ChatHandlerIns.UserSwitchAutoReplyStatus) //获取自动回复开关状态
v1.POST("aschat/autoReplyRuler/userSwitch/set", asChat.ChatHandlerIns.SetSwitchAutoReplyStatus) //设置自动回复开关状态
v1.POST("/test/user/log/erp", asChat.Handler.ErpLoginDemo) v1.POST("/test/user/log/erp", asChat.Handler.ErpLoginDemo)
v1.POST("/test/user/log/fiee", asChat.Handler.FieeLoginDemo) v1.POST("/test/user/log/fiee", asChat.Handler.FieeLoginDemo)

View File

@ -17,6 +17,7 @@ import (
"github.com/goccy/go-json" "github.com/goccy/go-json"
"go.uber.org/zap" "go.uber.org/zap"
"log" "log"
"strconv"
"strings" "strings"
"sync" "sync"
"time" "time"
@ -25,6 +26,7 @@ import (
const CacheChatRecordKey = "fiee:chatRecord" const CacheChatRecordKey = "fiee:chatRecord"
const CacheSessionKey = "fiee:chatSession" const CacheSessionKey = "fiee:chatSession"
const CacheNewMsgStatKey = "fiee:newMsgStat" const CacheNewMsgStatKey = "fiee:newMsgStat"
const CacheAutoReplySwitchKey = "fiee:AutoReplySwitch"
var chatCacheLocker sync.RWMutex var chatCacheLocker sync.RWMutex
@ -248,3 +250,37 @@ func (cr ChatCache) coverOwnerNewMessageStat(ctx context.Context, ownerId int64,
err = cache.RedisClient.Set(cr.GetNewMsgStatCacheKey(ownerId), value, 0).Err() err = cache.RedisClient.Set(cr.GetNewMsgStatCacheKey(ownerId), value, 0).Err()
return return
} }
// -----------------------------------用户自动回复开关
// erp获取最新的消息统计
func (cr ChatCache) GetCacheAutoReplySwitchKey(userId int64) string {
return fmt.Sprintf("%s:%d", CacheAutoReplySwitchKey, userId)
}
func (cr ChatCache) SetAutoReplySwitch(ctx context.Context, ownerId int64, enableAutoReply bool) {
//chatCacheLocker.RLock()
//defer chatCacheLocker.RUnlock()
err := cache.RedisClient.Set(cr.GetCacheAutoReplySwitchKey(ownerId), enableAutoReply, 0).Err()
if err != nil {
log.Print("保存用户会话失败", zap.Error(err))
}
return
}
func (cr ChatCache) GetAutoReplySwitch(ctx context.Context, ownerId int64) (enableAutoReply bool) {
//chatCacheLocker.RLock()
//defer chatCacheLocker.RUnlock()
val, err := cache.RedisClient.Get(cr.GetCacheAutoReplySwitchKey(ownerId)).Bytes()
if err != nil {
log.Print("获取自动回复开关查询失败", zap.Error(err), zap.Int64("ownerId", ownerId))
return true
}
// 解析缓存值为布尔值
boolVal, err := strconv.ParseBool(string(val))
if err != nil {
log.Print("解析自动回复开关值失败", zap.Error(err), zap.String("value", string(val)), zap.Int64("ownerId", ownerId))
return true // 解析失败时也返回默认值true
}
return boolVal
}

View File

@ -35,6 +35,7 @@ type NewMessageRequest struct {
SessionId string `json:"sessionId"` SessionId string `json:"sessionId"`
Message Message
AtUserId int64 `json:"atUserId"` //指定发送给sessionId中的某一个用户 AtUserId int64 `json:"atUserId"` //指定发送给sessionId中的某一个用户
//EnableAutoReply bool `json:"-"`
} }
// 服务端接收到消息后使用websocket发送给userId关联的客户端通知客户端有新消息然后调用接口获取消息 // 服务端接收到消息后使用websocket发送给userId关联的客户端通知客户端有新消息然后调用接口获取消息
@ -218,3 +219,7 @@ type UserDetailResp struct {
Phone string `json:"phone"` Phone string `json:"phone"`
GroupPhoto string `json:"groupPhoto"` GroupPhoto string `json:"groupPhoto"`
} }
type UserSwitchAutoReplyReq struct {
EnableAutoReply bool `json:"enableAutoReply"`
}

View File

@ -612,3 +612,54 @@ func (cr ChatHandler) UserDetail(c *gin.Context) {
service.Success(c, detail) service.Success(c, detail)
} }
func (a *ChatHandler) UserSwitchAutoReplyStatus(c *gin.Context) {
chatUser, code := jwt.ParseToChatUser(c)
if code != 0 {
service.ErrWithCode(c, code)
return
}
var req dto.UserSwitchAutoReplyReq
if err := c.ShouldBindJSON(&req); err != nil {
service.Error(c, err)
return
}
enable := a.cache.GetAutoReplySwitch(c, chatUser.ID)
var resp = map[string]any{
"enableAutoReply": enable,
}
service.Success(c, resp)
}
func (a *ChatHandler) SetSwitchAutoReplyStatus(c *gin.Context) {
chatUser, code := jwt.ParseToChatUser(c)
if code != 0 {
service.ErrWithCode(c, code)
return
}
var req dto.UserSwitchAutoReplyReq
if err := c.ShouldBindJSON(&req); err != nil {
service.Error(c, err)
return
}
a.cache.SetAutoReplySwitch(c, chatUser.ID, req.EnableAutoReply)
msg := dto.Message{
MsgType: 1,
LocalStamp: time.Now().Unix(),
}
if req.EnableAutoReply {
msg.Text = "已退出人工"
} else {
msg.Text = "已进入人工,不会接收自动消息"
}
err := logic.NewMessage(c, &a.cache, chatUser, dto.NewMessageRequest{
Robot: true,
SessionId: fmt.Sprintf("%d", chatUser.ID),
Message: msg,
})
if err != nil {
service.Error(c, err)
return
}
service.Success(c)
}

View File

@ -165,6 +165,11 @@ func (r *Robot) Run() {
fmt.Printf("robot listen event:%#v\n", event) fmt.Printf("robot listen event:%#v\n", event)
r.mu.Lock() r.mu.Lock()
//加入聊天室规则 //加入聊天室规则
enableAutoReply := false
if event.Client != nil {
enableAutoReply = new(chatCache.ChatCache).GetAutoReplySwitch(context.Background(), event.Client.UserId)
}
if enableAutoReply {
hasHit := false hasHit := false
for _, rule := range r.joinSessionRules { for _, rule := range r.joinSessionRules {
hit := rule.Hit(event, r.Info) hit := rule.Hit(event, r.Info)
@ -217,6 +222,7 @@ func (r *Robot) Run() {
} }
} }
} }
}
r.mu.Unlock() r.mu.Unlock()
} }
} }

View File

@ -13,12 +13,13 @@ import (
"fonchain-fiee/pkg/service/bundle/logic" "fonchain-fiee/pkg/service/bundle/logic"
bundleModel "fonchain-fiee/pkg/service/bundle/model" bundleModel "fonchain-fiee/pkg/service/bundle/model"
"fonchain-fiee/pkg/service/upload" "fonchain-fiee/pkg/service/upload"
"github.com/360EntSecGroup-Skylar/excelize"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"github.com/360EntSecGroup-Skylar/excelize"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
) )
func DeleteBundleOrder(c *gin.Context) { func DeleteBundleOrder(c *gin.Context) {
@ -502,6 +503,7 @@ func OrderRecordsListV2(c *gin.Context) {
if u, ok := userMap[item.CustomerId]; ok { if u, ok := userMap[item.CustomerId]; ok {
item.CustomerName = u.Name item.CustomerName = u.Name
item.TelNum = u.TelNum item.TelNum = u.TelNum
item.SubNum = u.SubNum
} }
} }
} }
@ -583,6 +585,7 @@ func OrderRecordsListDownload(c *gin.Context) {
if u, ok := userMap[item.CustomerId]; ok { if u, ok := userMap[item.CustomerId]; ok {
item.CustomerName = u.Name item.CustomerName = u.Name
item.TelNum = u.TelNum item.TelNum = u.TelNum
item.SubNum = u.SubNum
} }
} }
} }
@ -606,7 +609,7 @@ func exportExcel(orderList []*bundle.OrderBundleRecordInfo) (*excelize.File, err
f.SetSheetName("Sheet1", sheetName) f.SetSheetName("Sheet1", sheetName)
headers := []string{ headers := []string{
"套餐订单号", "套餐类型", "套餐付款状态", "艺人手机号", "艺人", "套餐订单创建时间", "套餐支付时间", "套餐金额", "套餐订单号", "套餐类型", "套餐付款状态", "艺人手机号", "用户编号", "艺人", "套餐订单创建时间", "套餐支付时间", "套餐金额",
"增值服务订单号", "增值税服务金额", "支付金额", "币种", "手续费", "增值订单创建时间", "增值付款状态", "增值服务订单号", "增值税服务金额", "支付金额", "币种", "手续费", "增值订单创建时间", "增值付款状态",
} }
for i, h := range headers { for i, h := range headers {
@ -636,22 +639,22 @@ func exportExcel(orderList []*bundle.OrderBundleRecordInfo) (*excelize.File, err
f.SetCellValue(sheetName, fmt.Sprintf("B%d", rowIndex), bundleInfo.BundleName) f.SetCellValue(sheetName, fmt.Sprintf("B%d", rowIndex), bundleInfo.BundleName)
f.SetCellValue(sheetName, fmt.Sprintf("C%d", rowIndex), GetPayStatusText(bundleInfo.PayStatus)) f.SetCellValue(sheetName, fmt.Sprintf("C%d", rowIndex), GetPayStatusText(bundleInfo.PayStatus))
f.SetCellValue(sheetName, fmt.Sprintf("D%d", rowIndex), bundleInfo.TelNum) f.SetCellValue(sheetName, fmt.Sprintf("D%d", rowIndex), bundleInfo.TelNum)
f.SetCellValue(sheetName, fmt.Sprintf("E%d", rowIndex), bundleInfo.CustomerName) f.SetCellValue(sheetName, fmt.Sprintf("E%d", rowIndex), bundleInfo.SubNum)
f.SetCellValue(sheetName, fmt.Sprintf("F%d", rowIndex), bundleInfo.BundleCreateAt) f.SetCellValue(sheetName, fmt.Sprintf("F%d", rowIndex), bundleInfo.CustomerName)
f.SetCellValue(sheetName, fmt.Sprintf("G%d", rowIndex), bundleInfo.PayTime) f.SetCellValue(sheetName, fmt.Sprintf("G%d", rowIndex), bundleInfo.BundleCreateAt)
f.SetCellValue(sheetName, fmt.Sprintf("H%d", rowIndex), bundleInfo.Amount) f.SetCellValue(sheetName, fmt.Sprintf("H%d", rowIndex), bundleInfo.PayTime)
f.SetCellValue(sheetName, fmt.Sprintf("I%d", rowIndex), bundleInfo.Amount)
if addCount > 0 { if addCount > 0 {
for i, add := range bundleInfo.AddBundleInfo { for i, add := range bundleInfo.AddBundleInfo {
r := rowIndex + i r := rowIndex + i
f.SetCellValue(sheetName, fmt.Sprintf("I%d", r), add.OrderAddNo) f.SetCellValue(sheetName, fmt.Sprintf("J%d", r), add.OrderAddNo)
f.SetCellValue(sheetName, fmt.Sprintf("J%d", r), add.Amount) f.SetCellValue(sheetName, fmt.Sprintf("K%d", r), add.Amount)
f.SetCellValue(sheetName, fmt.Sprintf("K%d", r), add.SettlementAmount) f.SetCellValue(sheetName, fmt.Sprintf("L%d", r), add.SettlementAmount)
f.SetCellValue(sheetName, fmt.Sprintf("L%d", r), GetCurrencyTypeText(add.CurrencyType)) f.SetCellValue(sheetName, fmt.Sprintf("M%d", r), GetCurrencyTypeText(add.CurrencyType))
f.SetCellValue(sheetName, fmt.Sprintf("M%d", r), add.HandlingFee) f.SetCellValue(sheetName, fmt.Sprintf("N%d", r), add.HandlingFee)
//f.SetCellValue(sheetName, fmt.Sprintf("N%d", r), add.ExchangeRate) f.SetCellValue(sheetName, fmt.Sprintf("O%d", r), add.OrderAddCreateAt)
f.SetCellValue(sheetName, fmt.Sprintf("N%d", r), add.OrderAddCreateAt) f.SetCellValue(sheetName, fmt.Sprintf("P%d", r), GetPayStatusText(add.AddPayStatus))
f.SetCellValue(sheetName, fmt.Sprintf("O%d", r), GetPayStatusText(add.AddPayStatus))
} }
} else { } else {
for i := 8; i <= 15; i++ { for i := 8; i <= 15; i++ {

View File

@ -11,10 +11,11 @@ import (
"fonchain-fiee/pkg/service/bundle/logic" "fonchain-fiee/pkg/service/bundle/logic"
bundleModel "fonchain-fiee/pkg/service/bundle/model" bundleModel "fonchain-fiee/pkg/service/bundle/model"
"fonchain-fiee/pkg/utils" "fonchain-fiee/pkg/utils"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"strconv" "strconv"
"time" "time"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
) )
func GetReconciliationList(c *gin.Context) { func GetReconciliationList(c *gin.Context) {
@ -28,6 +29,29 @@ func GetReconciliationList(c *gin.Context) {
service.Error(c, detailErr) service.Error(c, detailErr)
return return
} }
var userIds []int64
for _, u := range detail.List {
userIds = append(userIds, int64(u.UserID))
}
userListResp, err := service.AccountFieeProvider.UserList(context.Background(), &accountFiee.UserListRequest{
Ids: userIds,
Domain: "app",
})
if err != nil {
service.Error(c, err)
return
}
userMap := make(map[int64]*accountFiee.UserListInfo, len(userListResp.UserList))
if len(userListResp.UserList) > 0 {
for _, u := range userListResp.UserList {
userMap[int64(u.Id)] = u
}
for _, u := range detail.List {
if user, ok := userMap[int64(u.UserID)]; ok {
u.SubNum = user.SubNum
}
}
}
service.Success(c, detail) service.Success(c, detail)
return return
@ -44,8 +68,31 @@ func GetReconciliationListDownload(c *gin.Context) {
service.Error(c, detailErr) service.Error(c, detailErr)
return return
} }
var userIds []int64
for _, u := range detail.List {
userIds = append(userIds, int64(u.UserID))
}
userListResp, err := service.AccountFieeProvider.UserList(context.Background(), &accountFiee.UserListRequest{
Ids: userIds,
Domain: "app",
})
if err != nil {
service.Error(c, err)
return
}
userMap := make(map[int64]*accountFiee.UserListInfo, len(userListResp.UserList))
if len(userListResp.UserList) > 0 {
for _, u := range userListResp.UserList {
userMap[int64(u.Id)] = u
}
for _, u := range detail.List {
if user, ok := userMap[int64(u.UserID)]; ok {
u.SubNum = user.SubNum
}
}
}
titleList := []string{ titleList := []string{
"关联套餐订单号", "关联增值服务订单号", "对账单创建时间", "艺人", "艺人手机号", "套餐", "支付金额", "手续费", "币种", "支付渠道", "支付时间", "支付状态", "流水号", "关联套餐订单号", "关联增值服务订单号", "对账单创建时间", "用户编号", "艺人", "艺人手机号", "套餐", "支付金额", "手续费", "币种", "支付渠道", "支付时间", "支付状态", "流水号",
} }
var dataList []interface{} var dataList []interface{}
@ -60,6 +107,7 @@ func GetReconciliationListDownload(c *gin.Context) {
i.BundleOrderOn, i.BundleOrderOn,
i.BundleAddOrderOn, i.BundleAddOrderOn,
i.CreationTime, i.CreationTime,
i.SubNum,
i.UserName, i.UserName,
i.UserTel, i.UserTel,
i.BundleName, i.BundleName,

View File

@ -11,9 +11,10 @@ import (
"fonchain-fiee/pkg/e" "fonchain-fiee/pkg/e"
modelCast "fonchain-fiee/pkg/model/cast" modelCast "fonchain-fiee/pkg/model/cast"
"fonchain-fiee/pkg/service" "fonchain-fiee/pkg/service"
"strconv"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"go.uber.org/zap" "go.uber.org/zap"
"strconv"
) )
func UpdateWorkImage(ctx *gin.Context) { func UpdateWorkImage(ctx *gin.Context) {
@ -50,6 +51,7 @@ func UpdateWorkImage(ctx *gin.Context) {
return return
} }
newCtx := NewCtxWithUserInfo(ctx) newCtx := NewCtxWithUserInfo(ctx)
req.Source = 1
resp, err := service.CastProvider.UpdateWorkImage(newCtx, req) resp, err := service.CastProvider.UpdateWorkImage(newCtx, req)
if err != nil { if err != nil {
service.Error(ctx, err) service.Error(ctx, err)
@ -93,6 +95,7 @@ func UpdateWorkVideo(ctx *gin.Context) {
req.ArtistPhone = infoResp.TelNum req.ArtistPhone = infoResp.TelNum
req.ArtistPhoneAreaCode = infoResp.TelAreaCode req.ArtistPhoneAreaCode = infoResp.TelAreaCode
newCtx := NewCtxWithUserInfo(ctx) newCtx := NewCtxWithUserInfo(ctx)
req.Source = 1
resp, err := service.CastProvider.UpdateWorkVideo(newCtx, req) resp, err := service.CastProvider.UpdateWorkVideo(newCtx, req)
if err != nil { if err != nil {
service.Error(ctx, err) service.Error(ctx, err)

View File

@ -217,14 +217,14 @@ func quickBos(file *multipart.FileHeader, mediaType string, mask string, source
} }
} }
var objectName string = fmt.Sprintf("%s/%s/%s", config.ConfigData.Oss.BaseDir, config.Env, filePath) var objectName string = fmt.Sprintf("%s/%s/%s", config.ConfigData.Oss.BaseDir, config.Env, filePath)
BOSClient, _ := objstorage.NewOSS(config.ConfigData.Oss.AccessKeyId, config.ConfigData.Oss.AccessKeySecret, config.ConfigData.Oss.Endpoint) BOSClient, _ := objstorage.NewOSS(os.Getenv(config.ConfigData.Oss.AccessKeyId), os.Getenv(config.ConfigData.Oss.AccessKeySecret), os.Getenv(config.ConfigData.Oss.Endpoint))
_, err = BOSClient.PutObjectFromBytes(config.ConfigData.Oss.BucketName, objectName, fileBytes) _, err = BOSClient.PutObjectFromBytes(os.Getenv(config.ConfigData.Oss.BucketName), objectName, fileBytes)
if err != nil { if err != nil {
//logger.Errorf("quickOss err", err) //logger.Errorf("quickOss err", err)
return return
} }
//url = fmt.Sprintf("%s%s%s/%s", config.BosHttp, config.BosBucketName, config.BosUrl, objectName) //url = fmt.Sprintf("%s%s%s/%s", config.BosHttp, config.BosBucketName, config.BosUrl, objectName)
url = fmt.Sprintf("%s/%s", config.ConfigData.Oss.CdnHost, objectName) url = fmt.Sprintf("%s/%s", os.Getenv(config.ConfigData.Oss.CdnHost), objectName)
return return
} }
@ -266,8 +266,9 @@ func BaiduCheckImage(imageByte []byte) (err error) {
return nil return nil
} }
func PutBos(filePath string, mediaType string, needRemove bool) (url string, err error) { func PutBos(filePath string, mediaType string, needRemove bool) (url string, err error) {
BOSClient, err := objstorage.NewOSS(config.ConfigData.Oss.AccessKeyId, config.ConfigData.Oss.AccessKeySecret, config.ConfigData.Oss.Endpoint) BOSClient, err := objstorage.NewOSS(os.Getenv(config.ConfigData.Oss.AccessKeyId), os.Getenv(config.ConfigData.Oss.AccessKeySecret), os.Getenv(config.ConfigData.Oss.Endpoint))
if err != nil { if err != nil {
fmt.Println("=== PutBos NewOss err ", err)
//logger.Errorf("PutBos NewOss err ", err) //logger.Errorf("PutBos NewOss err ", err)
err = errors.New(e.GetMsg(e.ErrorUploadBos)) err = errors.New(e.GetMsg(e.ErrorUploadBos))
return return
@ -290,14 +291,15 @@ func PutBos(filePath string, mediaType string, needRemove bool) (url string, err
} }
filePath = strings.Replace(filePath, model.MediaPath, "", 1) filePath = strings.Replace(filePath, model.MediaPath, "", 1)
var objectName string = fmt.Sprintf("%s/%s%s", config.ConfigData.Oss.BaseDir, config.Env, filePath) var objectName string = fmt.Sprintf("%s/%s%s", config.ConfigData.Oss.BaseDir, config.Env, filePath)
_, err = BOSClient.PutObjectFromBytes(config.ConfigData.Oss.BucketName, objectName, fileBytes) _, err = BOSClient.PutObjectFromBytes(os.Getenv(config.ConfigData.Oss.BucketName), objectName, fileBytes)
if err != nil { if err != nil {
fmt.Println("=== PutBos PutObject err ", err)
//logger.Errorf("PutBos PutObject err %+v", err.Error()) //logger.Errorf("PutBos PutObject err %+v", err.Error())
err = errors.New(e.GetMsg(e.ErrorUploadBos)) err = errors.New(e.GetMsg(e.ErrorUploadBos))
return return
} }
//url = fmt.Sprintf("%s%s%s/%s", config.BosHttp, config.BosBucketName, config.BosUrl, objectName) //url = fmt.Sprintf("%s%s%s/%s", config.BosHttp, config.BosBucketName, config.BosUrl, objectName)
url = fmt.Sprintf("%s/%s", config.ConfigData.Oss.CdnHost, objectName) url = fmt.Sprintf("%s/%s", os.Getenv(config.ConfigData.Oss.CdnHost), objectName)
return return
} }
func GetSnapshot(videoPath, snapshotPath string, frameNum int) (snapshotName string, err error) { func GetSnapshot(videoPath, snapshotPath string, frameNum int) (snapshotName string, err error) {
@ -331,14 +333,14 @@ func GetSnapshot(videoPath, snapshotPath string, frameNum int) (snapshotName str
} }
func UploadWithBuffer(fileBuffer *bytes.Buffer, cloudStoreSubPath string) (url string, err error) { func UploadWithBuffer(fileBuffer *bytes.Buffer, cloudStoreSubPath string) (url string, err error) {
Client, err := objstorage.NewOSS(config.ConfigData.Oss.AccessKeyId, config.ConfigData.Oss.AccessKeySecret, config.ConfigData.Oss.Endpoint) Client, err := objstorage.NewOSS(os.Getenv(config.ConfigData.Oss.AccessKeyId), os.Getenv(config.ConfigData.Oss.AccessKeySecret), os.Getenv(config.ConfigData.Oss.Endpoint))
if err != nil { if err != nil {
err = errors.New(fmt.Sprintf("云存储初始化失败:%s", err.Error())) err = errors.New(fmt.Sprintf("云存储初始化失败:%s", err.Error()))
return return
} }
cloudStoreSubPath = getEnvDir(cloudStoreSubPath) cloudStoreSubPath = getEnvDir(cloudStoreSubPath)
_, err = Client.PutObjectFromBytes(config.ConfigData.Oss.BucketName, cloudStoreSubPath, fileBuffer.Bytes()) _, err = Client.PutObjectFromBytes(os.Getenv(config.ConfigData.Oss.BucketName), cloudStoreSubPath, fileBuffer.Bytes())
url = config.ConfigData.Oss.CdnHost + "/" + cloudStoreSubPath url = os.Getenv(config.ConfigData.Oss.CdnHost) + "/" + cloudStoreSubPath
return return
} }
func getEnvDir(cloudStoreSubPath string) (ep string) { func getEnvDir(cloudStoreSubPath string) (ep string) {