Files
lone-services/services/analysis/internal/logic/analysisadmin/helpers.go
T
zzw 15a5616308
CI / changes (push) Successful in 1m31s
CI / ad (push) Successful in 0s
CI / admin (push) Successful in 0s
CI / aiserver (push) Successful in 0s
CI / analysis (push) Successful in 37s
CI / bff (push) Successful in 18s
CI / chore (push) Successful in 0s
CI / equipment (push) Successful in 0s
CI / express (push) Successful in 1s
CI / factory (push) Successful in 0s
CI / message (push) Successful in 0s
CI / order (push) Successful in 0s
CI / payment (push) Successful in 0s
CI / percutaneous (push) Successful in 0s
CI / product (push) Successful in 0s
CI / record (push) Successful in 1s
CI / sale (push) Successful in 0s
CI / store (push) Successful in 22s
CI / support (push) Successful in 0s
CI / task (push) Successful in 0s
CI / user (push) Successful in 21s
CI / water (push) Successful in 0s
CI / wecom (push) Successful in 0s
CI / ws (push) Successful in 0s
feat: scan graph
2026-11-04 11:46:54 +08:00

331 lines
8.4 KiB
Go

package analysisadminlogic
import (
"context"
"strconv"
"strings"
"lone-services/pkg/modelbase"
"lone-services/pkg/utils"
analysis "lone-services/rpc/analysis/pb"
storepb "lone-services/rpc/store/pb"
"lone-services/services/analysis/internal/dao"
"lone-services/services/analysis/internal/logic/common"
"lone-services/services/analysis/internal/model"
"lone-services/services/analysis/internal/svc"
"lone-services/services/analysis/validator"
jsoniter "github.com/json-iterator/go"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
)
const adminImageTimeLayout = "2006-01-02 15:04"
func outParams(msg string) *analysis.Response {
return common.OutResponse(utils.ErrorParams, msg)
}
func formatGender(gender uint32) string {
switch gender {
case 1:
return "男"
case 2:
return "女"
default:
return ""
}
}
func userStatus(row dao.User) int {
status := utils.NumberOne
if row.IsRegistered == uint8(utils.StatusOk) {
status = utils.NumberTwo
}
if row.IsFaceVerified == uint8(utils.StatusOk) {
status = utils.NumberThree
}
if row.IsProfileCompleted == uint8(utils.StatusOk) {
status = utils.NumberFour
}
return status
}
func idStrings(ids []int64) []string {
out := make([]string, 0, len(ids))
for _, id := range ids {
if id < utils.NumberOne {
continue
}
out = append(out, strconv.FormatInt(id, utils.NumberTen))
}
return out
}
func loadImageLogs(userIds []int64) (map[int64]dao.UserImageLog, error) {
out := make(map[int64]dao.UserImageLog, len(userIds))
if len(userIds) == utils.NumberZero {
return out, nil
}
var rows []dao.UserImageLog
err := model.UserImageLogModel{}.Init().Items(modelbase.Params{
In: map[string][]string{"user_id": idStrings(userIds)},
Order: "detection_time desc",
}, &rows)
if err != nil {
return nil, err
}
for _, row := range rows {
if _, ok := out[row.UserId]; ok {
continue
}
out[row.UserId] = row
}
return out, nil
}
func formatImageContents(data map[string]string) map[string]string {
result := make(map[string]string, len(data))
for k, v := range data {
switch k {
case "health_score":
parts := strings.Split(v, "/")
result[k] = strings.TrimSpace(parts[0])
default:
result[k] = strings.TrimSuffix(v, "%")
}
}
return result
}
func buildImageDetail(detail *dao.Image) dao.ImageDetailResource {
var images map[string]interface{}
if detail.Images != utils.StringEmpty {
_ = jsoniter.UnmarshalFromString(detail.Images, &images)
}
var contents map[string]string
if detail.Contents != utils.StringEmpty {
var raw map[string]string
if err := jsoniter.UnmarshalFromString(detail.Contents, &raw); err == nil {
contents = formatImageContents(raw)
} else {
contents = map[string]string{}
}
}
return dao.ImageDetailResource{
Id: detail.Id,
UserId: detail.UserId,
TaskId: detail.TaskId,
Images: images,
Contents: contents,
Cover: detail.Cover,
CreateTime: detail.CreateTime.Format(adminImageTimeLayout),
}
}
func outgoingWithIncomingMD(ctx context.Context) context.Context {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return ctx
}
return metadata.NewOutgoingContext(ctx, md.Copy())
}
type storePageRow struct {
Id int64 `json:"id"`
Name string `json:"name"`
UserName string `json:"user_name"`
UserMobile string `json:"user_mobile"`
District string `json:"district"`
Address string `json:"address"`
ProvinceName string `json:"province_name"`
CityName string `json:"city_name"`
CountyName string `json:"county_name"`
}
type storePageData struct {
Count int64 `json:"count"`
Items []storePageRow `json:"items"`
}
func loadStorePage(ctx context.Context, name string, page, size, storeStatus int32) (storePageData, error) {
out := storePageData{Items: []storePageRow{}}
svcName := utils.GetConfigString("services.store")
if svcName == utils.StringEmpty {
return out, status.Error(codes.FailedPrecondition, "store service empty")
}
cli, err := svc.GetRpcClient(svcName)
if err != nil {
return out, err
}
res, err := storepb.NewStoreClient(cli.Conn()).Items(outgoingWithIncomingMD(ctx), &storepb.ItemsRequest{
Name: name,
Page: page,
Size: size,
Status: storeStatus,
})
if err != nil {
return out, err
}
if res.GetCode() != utils.Ok.Code {
return out, status.Error(codes.Internal, res.GetMsg())
}
if res.GetData() == utils.StringEmpty {
return out, nil
}
if err = jsoniter.UnmarshalFromString(res.GetData(), &out); err != nil {
return storePageData{}, err
}
if out.Items == nil {
out.Items = []storePageRow{}
}
return out, nil
}
func loadStoresByIds(ctx context.Context, ids []int64) (map[int64]*storepb.InfoResponse, error) {
out := make(map[int64]*storepb.InfoResponse, len(ids))
if len(ids) == utils.NumberZero {
return out, nil
}
svcName := utils.GetConfigString("services.store")
if svcName == utils.StringEmpty {
return nil, status.Error(codes.FailedPrecondition, "store service empty")
}
cli, err := svc.GetRpcClient(svcName)
if err != nil {
return nil, err
}
res, err := storepb.NewStoreClient(cli.Conn()).GetInfoByIds(ctx, &storepb.IdsRequest{Ids: ids})
if err != nil {
if st, ok := status.FromError(err); ok && st.Message() == utils.ErrorNotFund.Msg {
return out, nil
}
return nil, err
}
for _, item := range res.GetItems() {
out[item.GetId()] = item
}
return out, nil
}
func storeDistrictTextFromInfo(info *storepb.InfoResponse) string {
if info == nil {
return utils.StringEmpty
}
parts := make([]string, 0, 3)
for _, name := range []string{info.GetProvinceName(), info.GetCityName(), info.GetCountyName()} {
if name != utils.StringEmpty {
parts = append(parts, name)
}
}
return strings.Join(parts, "")
}
func pageSlice[T any](items []T, page, size int32) (int64, []T) {
total := int64(len(items))
p := int(page)
s := int(size)
if p < modelbase.DefaultPage {
p = modelbase.DefaultPage
}
if s < utils.NumberOne {
s = modelbase.DefaultSize
}
start := (p - 1) * s
if start >= len(items) {
return total, []T{}
}
end := start + s
if end > len(items) {
end = len(items)
}
return total, items[start:end]
}
func queryAdminImageLogs(userId int64, page, size int32) ([]dao.ImageLogResource, error) {
var rows []dao.Image
_, err := model.ImageModel{}.Init().Page(modelbase.Params{
Eq: map[string]string{
"user_id": strconv.FormatInt(userId, utils.NumberTen),
"status": strconv.Itoa(utils.StatusOk),
},
Order: "id desc",
Page: int(page),
Size: int(size),
}, &rows)
if err != nil {
return nil, err
}
if len(rows) == utils.NumberZero {
return nil, nil
}
list := make([]dao.ImageLogResource, 0, len(rows))
for _, row := range rows {
contents := map[string]string{}
if row.Contents != utils.StringEmpty {
var raw map[string]string
if err = jsoniter.UnmarshalFromString(row.Contents, &raw); err == nil {
if formatted := formatImageContents(raw); formatted != nil {
contents = formatted
}
}
}
list = append(list, dao.ImageLogResource{
Id: row.Id,
UserId: row.UserId,
Cover: row.Cover,
Contents: contents,
TaskId: row.TaskId,
CreateTime: row.CreateTime.Format(adminImageTimeLayout),
})
}
return list, nil
}
func toAdminGraphTitles(items []*analysis.AdminGraphTitleItem) []validator.AdminGraphTitleItem {
out := make([]validator.AdminGraphTitleItem, 0, len(items))
for _, item := range items {
if item == nil {
continue
}
out = append(out, validator.AdminGraphTitleItem{
Name: item.GetName(),
Content: item.GetContent(),
})
}
return out
}
func toAdminGraphImages(items []*analysis.AdminGraphImageItem) []validator.AdminGraphImageItem {
out := make([]validator.AdminGraphImageItem, 0, len(items))
for _, item := range items {
if item == nil {
continue
}
out = append(out, validator.AdminGraphImageItem{
Url: item.GetUrl(),
Text: item.GetText(),
})
}
return out
}
func toDaoGraphTitles(items []validator.AdminGraphTitleItem) []dao.GraphTitleItem {
out := make([]dao.GraphTitleItem, 0, len(items))
for _, item := range items {
out = append(out, dao.GraphTitleItem{Name: item.Name, Content: item.Content})
}
return out
}
func toDaoGraphImages(items []validator.AdminGraphImageItem) []dao.GraphImageItem {
out := make([]dao.GraphImageItem, 0, len(items))
for _, item := range items {
out = append(out, dao.GraphImageItem{Url: item.Url, Text: item.Text})
}
return out
}