This commit is contained in:
commit
a24edb78b8
|
@ -0,0 +1,29 @@
|
||||||
|
package l_ai_category
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"gitea.cdlsxd.cn/self-tools/l_ai_category/doubao"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetCategory(ctx context.Context, goodsName, key, model string, cateJson string) (categoryId int, err error) {
|
||||||
|
|
||||||
|
modelObj := doubao.NewDouBao(model, key)
|
||||||
|
text := []string{
|
||||||
|
"根据商品名称,从json中找到该商品对应的第三级分类[QUESTION]" + goodsName + "[/QUESTION]",
|
||||||
|
"-只需要返回类型的名称对应的id",
|
||||||
|
"-如果无法匹配,则返回数字0",
|
||||||
|
"-以下是 JSON 数据:" + cateJson,
|
||||||
|
}
|
||||||
|
category, err := modelObj.GetData(ctx, key, func(input string) (string, error) {
|
||||||
|
return input, nil
|
||||||
|
}, text...)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
categoryId, err = strconv.Atoi(category)
|
||||||
|
if err != nil {
|
||||||
|
categoryId = 0
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
package l_ai_category
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"gitea.cdlsxd.cn/self-tools/l_ai_category/utils_gorm"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
dns = "root:lansexiongdi6,@tcp(47.97.27.195:3306)/report?parseTime=True&loc=Local"
|
||||||
|
driver = "mysql"
|
||||||
|
table = "goods_category"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCategory(t *testing.T) {
|
||||||
|
catString := string(CategoryToJsonByte())
|
||||||
|
res, err := GetCategory(context.Background(), "金龙鱼御品珍珠米", "03320e58-6a0b-4061-a22b-902039f2190d", "deepseek-v3-250324", catString)
|
||||||
|
t.Log(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Category struct {
|
||||||
|
Id int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Level int `json:"level"`
|
||||||
|
Pid int `json:"pid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CategoryDic struct {
|
||||||
|
Category
|
||||||
|
Children []*CategoryDic `json:"children"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetCateGoryJson(t *testing.T) {
|
||||||
|
cateJsonByte := CategoryToJsonByte()
|
||||||
|
|
||||||
|
t.Log(string(cateJsonByte))
|
||||||
|
}
|
||||||
|
|
||||||
|
func CategoryToJsonByte() (cateJsonByte []byte) {
|
||||||
|
cates := cateAll()
|
||||||
|
var (
|
||||||
|
cateLevelPath = make([]map[int][]*CategoryDic, 3)
|
||||||
|
)
|
||||||
|
for _, v := range cates {
|
||||||
|
if cateLevelPath[v.Level-1] == nil {
|
||||||
|
cateLevelPath[v.Level-1] = make(map[int][]*CategoryDic)
|
||||||
|
}
|
||||||
|
if _, ex := cateLevelPath[v.Level-1][v.Pid]; !ex {
|
||||||
|
cateLevelPath[v.Level-1][v.Pid] = make([]*CategoryDic, 0)
|
||||||
|
}
|
||||||
|
cateLevelPath[v.Level-1][v.Pid] = append(cateLevelPath[v.Level-1][v.Pid], &CategoryDic{Category: v})
|
||||||
|
}
|
||||||
|
cate := cateIteration(cateLevelPath[0], cateIteration(cateLevelPath[1], cateLevelPath[2]))[0]
|
||||||
|
cateJsonByte, _ = json.Marshal(cate)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func cateIteration(parent map[int][]*CategoryDic, child map[int][]*CategoryDic) map[int][]*CategoryDic {
|
||||||
|
for _, v := range parent {
|
||||||
|
for _, vv := range v {
|
||||||
|
vv.Children = child[vv.Id]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parent
|
||||||
|
}
|
||||||
|
|
||||||
|
func cateAll() (data []Category) {
|
||||||
|
var (
|
||||||
|
row Category
|
||||||
|
)
|
||||||
|
db, err, clean := utils_gorm.DB(driver, dns)
|
||||||
|
defer clean()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
rows, _ := db.Raw(fmt.Sprintf("SELECT id,name,level,pid FROM `%s` where `type`=2", table)).Rows()
|
||||||
|
defer rows.Close()
|
||||||
|
for rows.Next() {
|
||||||
|
err = db.ScanRows(rows, &row)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
data = append(data, row)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package doubao
|
||||||
|
|
||||||
|
var UrlMap = map[UrlType]string{
|
||||||
|
Text: "https://ark.cn-beijing.volces.com/api/v3/chat/completions",
|
||||||
|
Video: "https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks",
|
||||||
|
Embedding: "https://ark.cn-beijing.volces.com/api/v3/embeddings",
|
||||||
|
Token: "https://ark.cn-beijing.volces.com/api/v3/tokenization",
|
||||||
|
}
|
||||||
|
|
||||||
|
type UrlType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
Text UrlType = "text"
|
||||||
|
Video UrlType = "video"
|
||||||
|
Embedding UrlType = "embedding"
|
||||||
|
Token UrlType = "token"
|
||||||
|
)
|
|
@ -0,0 +1,53 @@
|
||||||
|
package doubao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/volcengine/volcengine-go-sdk/service/arkruntime"
|
||||||
|
"github.com/volcengine/volcengine-go-sdk/service/arkruntime/model"
|
||||||
|
"github.com/volcengine/volcengine-go-sdk/volcengine"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DouBao struct {
|
||||||
|
Model string
|
||||||
|
Key string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDouBao(modelName string, key string) *DouBao {
|
||||||
|
return &DouBao{
|
||||||
|
Model: modelName,
|
||||||
|
Key: key,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *DouBao) GetData(ctx context.Context, key string, respHandle func(input string) (string, error), text ...string) (string, error) {
|
||||||
|
var Message = make([]*model.ChatCompletionMessage, len(text))
|
||||||
|
|
||||||
|
client := arkruntime.NewClientWithApiKey(
|
||||||
|
key,
|
||||||
|
//arkruntime.WithBaseUrl(UrlMap[url]),
|
||||||
|
arkruntime.WithRegion("cn-beijing"),
|
||||||
|
arkruntime.WithTimeout(2*time.Minute),
|
||||||
|
arkruntime.WithRetryTimes(2),
|
||||||
|
)
|
||||||
|
for k, v := range text {
|
||||||
|
Message[k] = &model.ChatCompletionMessage{
|
||||||
|
Role: model.ChatMessageRoleSystem,
|
||||||
|
Content: &model.ChatCompletionMessageContent{
|
||||||
|
StringValue: volcengine.String(v),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req := model.CreateChatCompletionRequest{
|
||||||
|
Model: o.Model,
|
||||||
|
Messages: Message,
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.CreateChatCompletion(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
result, err := respHandle(*resp.Choices[0].Message.Content.StringValue)
|
||||||
|
|
||||||
|
return result, err
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
module gitea.cdlsxd.cn/self-tools/l_ai_category
|
||||||
|
|
||||||
|
go 1.23.7
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/volcengine/volcengine-go-sdk v1.0.187
|
||||||
|
gorm.io/driver/mysql v1.5.7
|
||||||
|
gorm.io/gorm v1.25.12
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||||
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
|
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||||
|
github.com/volcengine/volc-sdk-golang v1.0.23 // indirect
|
||||||
|
golang.org/x/text v0.14.0 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.2.8 // indirect
|
||||||
|
)
|
|
@ -0,0 +1,22 @@
|
||||||
|
package utils_gorm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"gorm.io/driver/mysql"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DB(driver string, dns string) (*gorm.DB, error, func()) {
|
||||||
|
mysqlConn, err := sql.Open(driver, dns)
|
||||||
|
gormDB, err := gorm.Open(
|
||||||
|
mysql.New(mysql.Config{Conn: mysqlConn}),
|
||||||
|
)
|
||||||
|
return gormDB, err, func() {
|
||||||
|
if mysqlConn != nil {
|
||||||
|
if err := mysqlConn.Close(); err != nil {
|
||||||
|
fmt.Println("关闭 DB 失败:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
package utils_gorm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/logger"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CustomLogger struct {
|
||||||
|
gormLogger logger.Interface
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCustomLogger(db *gorm.DB) *CustomLogger {
|
||||||
|
return &CustomLogger{
|
||||||
|
gormLogger: logger.Default.LogMode(logger.Info),
|
||||||
|
db: db,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *CustomLogger) LogMode(level logger.LogLevel) logger.Interface {
|
||||||
|
newlogger := *l
|
||||||
|
newlogger.gormLogger = l.gormLogger.LogMode(level)
|
||||||
|
return &newlogger
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *CustomLogger) Info(ctx context.Context, msg string, data ...interface{}) {
|
||||||
|
l.gormLogger.Info(ctx, msg, data...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *CustomLogger) Warn(ctx context.Context, msg string, data ...interface{}) {
|
||||||
|
l.gormLogger.Warn(ctx, msg, data...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *CustomLogger) Error(ctx context.Context, msg string, data ...interface{}) {
|
||||||
|
l.gormLogger.Error(ctx, msg, data...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *CustomLogger) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) {
|
||||||
|
elapsed := time.Since(begin)
|
||||||
|
sql, _ := fc()
|
||||||
|
l.gormLogger.Trace(ctx, begin, fc, err)
|
||||||
|
operation := extractOperation(sql)
|
||||||
|
tableName := extractTableName(sql)
|
||||||
|
fmt.Println(tableName)
|
||||||
|
//// 将SQL语句保存到数据库
|
||||||
|
if operation == 0 || tableName == "sql_log" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//go l.db.Model(&SqlLog{}).Create(&SqlLog{
|
||||||
|
// OperatorID: 1,
|
||||||
|
// OperatorName: "test",
|
||||||
|
// SqlInfo: sql,
|
||||||
|
// TableNames: tableName,
|
||||||
|
// Type: operation,
|
||||||
|
//})
|
||||||
|
|
||||||
|
// 如果有需要,也可以根据执行时间(elapsed)等条件过滤或处理日志记录
|
||||||
|
if elapsed > time.Second {
|
||||||
|
//l.gormLogger.Warn(ctx, "Slow SQL (> 1s): %s", sql)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// extractTableName extracts the table name from a SQL query, supporting quoted table names.
|
||||||
|
func extractTableName(sql string) string {
|
||||||
|
// 使用非捕获组匹配多种SQL操作关键词
|
||||||
|
re := regexp.MustCompile(`(?i)\b(?:from|update|into|delete\s+from)\b\s+[\` + "`" + `"]?(\w+)[\` + "`" + `"]?`)
|
||||||
|
match := re.FindStringSubmatch(sql)
|
||||||
|
|
||||||
|
// 检查是否匹配成功
|
||||||
|
if len(match) > 1 {
|
||||||
|
return match[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// extractOperation extracts the operation type from a SQL query.
|
||||||
|
func extractOperation(sql string) int32 {
|
||||||
|
sql = strings.TrimSpace(strings.ToLower(sql))
|
||||||
|
var operation int32
|
||||||
|
if strings.HasPrefix(sql, "select") {
|
||||||
|
operation = 0
|
||||||
|
} else if strings.HasPrefix(sql, "insert") {
|
||||||
|
operation = 1
|
||||||
|
} else if strings.HasPrefix(sql, "update") {
|
||||||
|
operation = 3
|
||||||
|
} else if strings.HasPrefix(sql, "delete") {
|
||||||
|
operation = 2
|
||||||
|
}
|
||||||
|
return operation
|
||||||
|
}
|
Loading…
Reference in New Issue