Compare commits

..

15 Commits

Author SHA1 Message Date
fuzhongyun 8895f29963 fix: 1.调整售后类型、费用承担着默认 2.售后金额string->float64 3.优化无数据响应 2025-11-27 10:09:21 +08:00
fuzhongyun 4656468e8a Merge branch 'v3' into test 2025-11-26 20:00:51 +08:00
renzhiyuan 4626efe7b2 Merge remote-tracking branch 'origin/test' into test 2025-11-26 10:51:36 +08:00
renzhiyuan 4619389f4f Merge branch 'v3' into test 2025-11-26 10:51:26 +08:00
renzhiyuan 33965dae47 feat: 优化任务模型与权限控制 2025-11-26 10:51:10 +08:00
fuzhongyun c086e9ba15 Merge branch 'v3' into test 2025-11-25 18:03:15 +08:00
fuzhongyun 9a1ff9d8a2 Merge branch 'v3' into test 2025-11-25 11:48:03 +08:00
fuzhongyun 65de970292 Merge branch 'v3' into test 2025-11-25 11:38:32 +08:00
fuzhongyun 17ff02d461 Merge branch 'v3' into test 2025-11-24 15:33:20 +08:00
fuzhongyun 4497e30a50 Merge branch 'v3' into test 2025-11-24 14:46:15 +08:00
fuzhongyun 1b423fc509 Merge branch 'v3' into test 2025-11-24 13:39:36 +08:00
fuzhongyun 9f132dc99c Merge branch 'v3' into test 2025-11-24 09:54:15 +08:00
wolter e34d7376c1 Merge branch 'refs/heads/v3' into test 2025-11-21 15:52:50 +08:00
renzhiyuan 599a2aad44 feat: 优化聊天功能与模型配置 2025-11-20 15:44:48 +08:00
renzhiyuan 386c565f01 feat: 优化聊天功能与模型配置 2025-11-20 15:44:06 +08:00
9 changed files with 104 additions and 49 deletions

View File

@ -7,7 +7,7 @@ ollama:
base_url: "http://127.0.0.1:11434" base_url: "http://127.0.0.1:11434"
model: "qwen3-coder:480b-cloud" model: "qwen3-coder:480b-cloud"
generate_model: "qwen3-coder:480b-cloud" generate_model: "qwen3-coder:480b-cloud"
vl_model: "qwen2.5vl:3b" vl_model: "qwen2.5vl:7b"
timeout: "120s" timeout: "120s"
level: "info" level: "info"
format: "json" format: "json"

View File

@ -16,7 +16,7 @@ CONFIG_FILE="config/config.yaml"
BRANCH="master" BRANCH="master"
if [ "$MODE" = "dev" ]; then if [ "$MODE" = "dev" ]; then
CONFIG_FILE="config/config_test.yaml" CONFIG_FILE="config/config_test.yaml"
BRANCH="v2" BRANCH="test"
fi fi
git fetch origin git fetch origin

View File

@ -1,6 +1,7 @@
package biz package biz
import ( import (
"ai_scheduler/internal/data/constants"
errors "ai_scheduler/internal/data/error" errors "ai_scheduler/internal/data/error"
"ai_scheduler/internal/data/impl" "ai_scheduler/internal/data/impl"
"ai_scheduler/internal/data/model" "ai_scheduler/internal/data/model"
@ -8,10 +9,11 @@ import (
"ai_scheduler/internal/pkg/l_request" "ai_scheduler/internal/pkg/l_request"
"context" "context"
"encoding/json" "encoding/json"
"gorm.io/gorm/utils"
"net/http" "net/http"
"strconv" "strconv"
"gorm.io/gorm/utils"
"xorm.io/builder" "xorm.io/builder"
"ai_scheduler/internal/config" "ai_scheduler/internal/config"
@ -33,9 +35,9 @@ func NewTaskBiz(conf *config.Config, taskRepo *impl.TaskImpl) *TaskBiz {
func (t *TaskBiz) TaskList(ctx context.Context, req *entitys.TaskRequest, auth string) (list []model.AiTask, err error) { func (t *TaskBiz) TaskList(ctx context.Context, req *entitys.TaskRequest, auth string) (list []model.AiTask, err error) {
tasks := make([]model.AiTask, 0) tasks := make([]model.AiTask, 0)
cond := builder.NewCond() cond := builder.NewCond()
cond = cond.And(builder.Eq{"status": 1}) cond = cond.And(builder.Eq{"status": constants.Enable})
cond = cond.And(builder.Eq{"sys_id": req.SysId}) cond = cond.And(builder.Eq{"sys_id": req.SysId})
cond = cond.And(builder.Eq{"is_show": constants.IsSHOW})
err = t.taskRepo.GetRangeToMapStruct(&cond, &tasks) err = t.taskRepo.GetRangeToMapStruct(&cond, &tasks)
codes, err := t.GetUserPermission(req, auth) codes, err := t.GetUserPermission(req, auth)
@ -55,20 +57,16 @@ func (t *TaskBiz) TaskList(ctx context.Context, req *entitys.TaskRequest, auth s
// 从统一登录平台获取用户权限 // 从统一登录平台获取用户权限
func (t *TaskBiz) GetUserPermission(req *entitys.TaskRequest, auth string) (codes []string, err error) { func (t *TaskBiz) GetUserPermission(req *entitys.TaskRequest, auth string) (codes []string, err error) {
var (
request l_request.Request
)
// 构建请求URL request := l_request.Request{
request.Url = t.conf.PermissionConfig.PermissionURL + strconv.Itoa(int(req.SysId)) Method: "GET",
Url: t.conf.PermissionConfig.PermissionURL + strconv.Itoa(int(req.SysId)),
request.Method = "GET" Headers: map[string]string{
request.Headers = map[string]string{ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", "Accept": "application/json, text/plain, */*",
"Accept": "application/json, text/plain, */*", "Authorization": auth,
"Authorization": auth, },
} }
// 发送请求 // 发送请求
res, err := request.Send() res, err := request.Send()
if err != nil { if err != nil {
@ -84,7 +82,7 @@ func (t *TaskBiz) GetUserPermission(req *entitys.TaskRequest, auth string) (code
type resp struct { type resp struct {
Codes []string `json:"codes"` Codes []string `json:"codes"`
} }
// 解析响应体 // 解析响应体s
var respBody resp var respBody resp
err = json.Unmarshal([]byte(res.Text), &respBody) err = json.Unmarshal([]byte(res.Text), &respBody)
if err != nil { if err != nil {

View File

@ -0,0 +1,11 @@
package constants
const (
IsSHOW = 1
NotShow = 2
)
const (
Enable = 1
Disable = 2
)

View File

@ -12,19 +12,21 @@ const TableNameAiTask = "ai_task"
// AiTask mapped from table <ai_task> // AiTask mapped from table <ai_task>
type AiTask struct { type AiTask struct {
TaskID int32 `gorm:"column:task_id;primaryKey" json:"task_id"` TaskID int32 `gorm:"column:task_id;primaryKey;autoIncrement:true" json:"task_id"`
SysID int32 `gorm:"column:sys_id;not null" json:"sys_id"` SysID int32 `gorm:"column:sys_id;not null" json:"sys_id"`
Name string `gorm:"column:name;not null" json:"name"` Name string `gorm:"column:name;not null" json:"name"`
Index string `gorm:"column:index;not null" json:"index"` Index string `gorm:"column:index;not null" json:"index"`
Desc string `gorm:"column:desc;not null" json:"desc"` Desc string `gorm:"column:desc;not null" json:"desc"`
Type int32 `gorm:"column:type;not null;comment:类型1api,2:知识库" json:"type"` // 类型1api,2:知识库 UseCase string `gorm:"column:use_case;not null;comment:适用场景" json:"use_case"` // 适用场景
Config string `gorm:"column:config" json:"config"` TempPrompt string `gorm:"column:temp_prompt;not null;comment:提示词模板" json:"temp_prompt"` // 提示词模板
CreateAt time.Time `gorm:"column:create_at;default:CURRENT_TIMESTAMP" json:"create_at"` Type int32 `gorm:"column:type;not null;default:1;comment:类型1api,2:知识库" json:"type"` // 类型1api,2:知识库
UpdateAt time.Time `gorm:"column:update_at;default:CURRENT_TIMESTAMP" json:"update_at"` Config string `gorm:"column:config" json:"config"`
Status int32 `gorm:"column:status;not null;default:1" json:"status"` TagType int32 `gorm:"column:tag_type;comment:标签类型1.AI日常 2.AI查询 3.AI执行" json:"tag_type"` // 标签类型1.AI日常 2.AI查询 3.AI执行
DeleteAt time.Time `gorm:"column:delete_at" json:"delete_at"` CreateAt time.Time `gorm:"column:create_at;default:CURRENT_TIMESTAMP" json:"create_at"`
UseCase string `gorm:"column:use_case;not null" json:"use_case"` // 适用场景 UpdatedAt time.Time `gorm:"column:updated_at;default:CURRENT_TIMESTAMP" json:"updated_at"`
TagType int32 `gorm:"column:tag_type;not null;default:1" json:"tag_type"` // 标签类型 1.AI日常 2.AI查询 3.AI执行 IsShow int32 `gorm:"column:is_show;not null;default:1;comment:是否展示1为展示2为不展示" json:"is_show"` // 是否展示1为展示2为不展示
Status int32 `gorm:"column:status;not null;default:1" json:"status"`
DeleteAt time.Time `gorm:"column:delete_at" json:"delete_at"`
} }
// TableName AiTask's table name // TableName AiTask's table name

View File

@ -26,3 +26,9 @@ func StringToInt(s string) int {
i, _ := strconv.Atoi(s) i, _ := strconv.Atoi(s)
return i return i
} }
// string 转 float64
func StringToFloat64(s string) float64 {
i, _ := strconv.ParseFloat(s, 64)
return i
}

View File

@ -68,7 +68,7 @@ type OrderAfterSaleResellerData struct {
Platforms map[int]string `json:"platforms"` Platforms map[int]string `json:"platforms"`
AfterType int `json:"afterType"` // 处理方式 1.退款 2.扣款 AfterType int `json:"afterType"` // 处理方式 1.退款 2.扣款
Remark string `json:"remark"` // 售后原因 Remark string `json:"remark"` // 售后原因
AfterAmount string `json:"afterAmount"` // 售后金额 AfterAmount float64 `json:"afterAmount"` // 售后金额
ResponsibleType int `json:"responsibleType"` // 费用承担者 1.供应商 2.商务 3.公司 4.无 ResponsibleType int `json:"responsibleType"` // 费用承担者 1.供应商 2.商务 3.公司 4.无
ResponsiblePerson string `json:"responsiblePerson"` // 费用承担供应商 ResponsiblePerson string `json:"responsiblePerson"` // 费用承担供应商
IsExistsAfterSale bool `json:"isExistsAfterSale"` // 是否已存在售后 IsExistsAfterSale bool `json:"isExistsAfterSale"` // 是否已存在售后
@ -107,8 +107,7 @@ type OrderAfterSaleResellerApiExtItem struct {
func (t *OrderAfterSaleResellerTool) Execute(ctx context.Context, requireData *entitys.RequireData) error { func (t *OrderAfterSaleResellerTool) Execute(ctx context.Context, requireData *entitys.RequireData) error {
var req OrderAfterSaleResellerRequest var req OrderAfterSaleResellerRequest
if err := json.Unmarshal([]byte(requireData.Match.Parameters), &req); err != nil { if err := json.Unmarshal([]byte(requireData.Match.Parameters), &req); err != nil {
entitys.ResError(requireData.Ch, t.Name(), "解析参数失败,请重试或联系管理员") return fmt.Errorf("解析参数失败,请重试或联系管理员")
return err
} }
if len(req.OrderNumber) == 0 && len(req.Account) == 0 { if len(req.OrderNumber) == 0 && len(req.Account) == 0 {
return fmt.Errorf("订单号 和 充值账号 不能同时为空") return fmt.Errorf("订单号 和 充值账号 不能同时为空")
@ -190,6 +189,11 @@ func (t *OrderAfterSaleResellerTool) checkOrderAfterSaleReseller(toolReq OrderAf
return fmt.Errorf("订单号 和 充值账号 不能同时为空") return fmt.Errorf("订单号 和 充值账号 不能同时为空")
} }
// 未查询到相应售后订单,请核实提供信息是否正确
if len(orderList) == 0 {
return fmt.Errorf("未查询到相应售后订单,请核实提供信息是否正确")
}
toolResp := OrderAfterSaleResellerResponse{ toolResp := OrderAfterSaleResellerResponse{
Code: 0, Code: 0,
Msg: "Success", Msg: "Success",
@ -231,6 +235,17 @@ func (t *OrderAfterSaleResellerTool) getAfterSaleResellerList(headers map[string
// 转换数据 // 转换数据
for _, item := range resp.Data.Data { for _, item := range resp.Data.Data {
// 处理方式
afterType := util.StringToInt(originInput.AfterType)
if afterType == 0 {
afterType = 1 // 默认退款
}
// 费用承担者
responsibleType := util.StringToInt(originInput.ResponsibleType)
if responsibleType == 0 {
responsibleType = 4 // 默认无
}
orderList = append(orderList, &OrderAfterSaleResellerData{ orderList = append(orderList, &OrderAfterSaleResellerData{
OrderType: item.OrderType, OrderType: item.OrderType,
OrderNumber: item.OrderNumber, OrderNumber: item.OrderNumber,
@ -244,10 +259,10 @@ func (t *OrderAfterSaleResellerTool) getAfterSaleResellerList(headers map[string
OurProductTitle: item.OurProductTitle, OurProductTitle: item.OurProductTitle,
Account: item.Account, Account: item.Account,
Platforms: item.Platforms, Platforms: item.Platforms,
AfterType: util.StringToInt(originInput.AfterType), AfterType: afterType,
Remark: originInput.AfterSalesReason, Remark: originInput.AfterSalesReason,
AfterAmount: originInput.AfterSalesPrice, AfterAmount: util.StringToFloat64(originInput.AfterSalesPrice),
ResponsibleType: util.StringToInt(originInput.ResponsibleType), ResponsibleType: responsibleType,
ResponsiblePerson: originInput.ResponsiblePerson, ResponsiblePerson: originInput.ResponsiblePerson,
}) })
} }

View File

@ -64,7 +64,7 @@ type OrderAfterSaleResellerBatchData struct {
Platforms map[int]string `json:"platforms"` Platforms map[int]string `json:"platforms"`
AfterType int `json:"afterType"` // 处理方式 1.退款 2.扣款 AfterType int `json:"afterType"` // 处理方式 1.退款 2.扣款
Remark string `json:"remark"` // 售后原因 Remark string `json:"remark"` // 售后原因
AfterAmount string `json:"afterAmount"` // 售后金额 AfterAmount float64 `json:"afterAmount"` // 售后金额
ResponsibleType int `json:"responsibleType"` // 费用承担者 1.供应商 2.商务 3.公司 4.无 ResponsibleType int `json:"responsibleType"` // 费用承担者 1.供应商 2.商务 3.公司 4.无
ResponsiblePerson string `json:"responsiblePerson"` // 费用承担供应商 ResponsiblePerson string `json:"responsiblePerson"` // 费用承担供应商
IsExistsAfterSale bool `json:"isExistsAfterSale"` // 是否已存在售后 IsExistsAfterSale bool `json:"isExistsAfterSale"` // 是否已存在售后
@ -103,8 +103,7 @@ type OrderAfterSaleResellerBatchApiExtItem struct {
func (t *OrderAfterSaleResellerBatchTool) Execute(ctx context.Context, requireData *entitys.RequireData) error { func (t *OrderAfterSaleResellerBatchTool) Execute(ctx context.Context, requireData *entitys.RequireData) error {
var req OrderAfterSaleResellerBatchRequest var req OrderAfterSaleResellerBatchRequest
if err := json.Unmarshal([]byte(requireData.Match.Parameters), &req); err != nil { if err := json.Unmarshal([]byte(requireData.Match.Parameters), &req); err != nil {
entitys.ResError(requireData.Ch, t.Name(), "解析参数失败,请重试或联系管理员") return fmt.Errorf("解析参数失败,请重试或联系管理员")
return err
} }
if len(req.OrderNumber) == 0 { if len(req.OrderNumber) == 0 {
return fmt.Errorf("批充订单号不能为空") return fmt.Errorf("批充订单号不能为空")
@ -137,7 +136,10 @@ func (t *OrderAfterSaleResellerBatchTool) checkOrderAfterSaleResellerBatch(toolR
return err return err
} }
if resp.Code != 200 { if resp.Code != 200 {
return fmt.Errorf("after sale supplier failed: %s", resp.Error) return fmt.Errorf("售后订单查询异常: %s", resp.Error)
}
if len(resp.Data.Data) == 0 {
return fmt.Errorf("未查询到相应售后订单,请核实订单号是否正确")
} }
toolResp := OrderAfterSaleResellerBatchResponse{ toolResp := OrderAfterSaleResellerBatchResponse{
@ -148,6 +150,17 @@ func (t *OrderAfterSaleResellerBatchTool) checkOrderAfterSaleResellerBatch(toolR
// 转换数据 // 转换数据
for _, item := range resp.Data.Data { for _, item := range resp.Data.Data {
// 处理方式
afterType := util.StringToInt(toolReq.AfterType)
if afterType == 0 {
afterType = 1 // 默认退款
}
// 费用承担者
responsibleType := util.StringToInt(toolReq.ResponsibleType)
if responsibleType == 0 {
responsibleType = 4 // 默认无
}
toolResp.Data = append(toolResp.Data, &OrderAfterSaleResellerBatchData{ toolResp.Data = append(toolResp.Data, &OrderAfterSaleResellerBatchData{
OrderType: item.OrderType, OrderType: item.OrderType,
OrderNumber: item.OrderNumber, OrderNumber: item.OrderNumber,
@ -161,10 +174,10 @@ func (t *OrderAfterSaleResellerBatchTool) checkOrderAfterSaleResellerBatch(toolR
OurProductTitle: item.OurProductTitle, OurProductTitle: item.OurProductTitle,
Account: item.Account, Account: item.Account,
Platforms: item.Platforms, Platforms: item.Platforms,
AfterType: util.StringToInt(toolReq.AfterType), AfterType: afterType,
Remark: toolReq.AfterSalesReason, Remark: toolReq.AfterSalesReason,
AfterAmount: toolReq.AfterSalesPrice, AfterAmount: util.StringToFloat64(toolReq.AfterSalesPrice),
ResponsibleType: util.StringToInt(toolReq.ResponsibleType), ResponsibleType: responsibleType,
ResponsiblePerson: toolReq.ResponsiblePerson, ResponsiblePerson: toolReq.ResponsiblePerson,
}) })
} }

View File

@ -64,7 +64,7 @@ type OrderAfterSaleSupplierData struct {
PlatformID int `json:"platformId"` // 上游平台id PlatformID int `json:"platformId"` // 上游平台id
SignCompanyName string `json:"signCompanyName"` // 签约主体名称 SignCompanyName string `json:"signCompanyName"` // 签约主体名称
Reason string `json:"reason"` // 售后原因 Reason string `json:"reason"` // 售后原因
SalePrice string `json:"salePrice"` // 售后金额 SalePrice float64 `json:"salePrice"` // 售后金额
SaleType int `json:"saleType"` // 处理方式 1.加款 2.扣款 SaleType int `json:"saleType"` // 处理方式 1.加款 2.扣款
ExecuteTime int `json:"executeTime"` // 流水创建时间 ExecuteTime int `json:"executeTime"` // 流水创建时间
IsExistsAfterSale bool `json:"isExistsAfterSale"` // 是否已存在售后 IsExistsAfterSale bool `json:"isExistsAfterSale"` // 是否已存在售后
@ -101,8 +101,7 @@ type OrderAfterSaleSupplierApiExtItem struct {
func (t *OrderAfterSaleSupplierTool) Execute(ctx context.Context, requireData *entitys.RequireData) error { func (t *OrderAfterSaleSupplierTool) Execute(ctx context.Context, requireData *entitys.RequireData) error {
var req OrderAfterSaleSupplierRequest var req OrderAfterSaleSupplierRequest
if err := json.Unmarshal([]byte(requireData.Match.Parameters), &req); err != nil { if err := json.Unmarshal([]byte(requireData.Match.Parameters), &req); err != nil {
entitys.ResError(requireData.Ch, t.Name(), "解析参数失败,请重试或联系管理员") return fmt.Errorf("解析参数失败,请重试或联系管理员")
return err
} }
if len(req.SerialNumber) == 0 && len(req.Account) == 0 { if len(req.SerialNumber) == 0 && len(req.Account) == 0 {
return fmt.Errorf("充值流水号 和 充值账号 不能同时为空") return fmt.Errorf("充值流水号 和 充值账号 不能同时为空")
@ -182,6 +181,11 @@ func (t *OrderAfterSaleSupplierTool) checkOrderAfterSaleSupplier(toolReq OrderAf
return fmt.Errorf("充值流水号 和 充值账号 不能同时为空") return fmt.Errorf("充值流水号 和 充值账号 不能同时为空")
} }
// 未查询到相应售后订单,请核实提供信息是否正确
if len(orderList) == 0 {
return fmt.Errorf("未查询到相应售后订单,请核实提供信息是否正确")
}
toolResp := OrderAfterSaleSupplierResponse{ toolResp := OrderAfterSaleSupplierResponse{
Code: 0, Code: 0,
Msg: "Success", Msg: "Success",
@ -223,6 +227,12 @@ func (t *OrderAfterSaleSupplierTool) getAfterSaleSupplierList(headers map[string
// 转换数据 // 转换数据
for _, item := range resp.Data.Data { for _, item := range resp.Data.Data {
// 处理方式
afterType := util.StringToInt(originInput.AfterType)
if afterType == 0 {
afterType = 1 // 默认退款
}
orderList = append(orderList, &OrderAfterSaleSupplierData{ orderList = append(orderList, &OrderAfterSaleSupplierData{
SerialNumber: item.SerialNumber, SerialNumber: item.SerialNumber,
PlatformName: item.PlatformName, PlatformName: item.PlatformName,
@ -235,8 +245,8 @@ func (t *OrderAfterSaleSupplierTool) getAfterSaleSupplierList(headers map[string
PlatformID: item.PlatformID, PlatformID: item.PlatformID,
SignCompanyName: item.SignCompanyName, SignCompanyName: item.SignCompanyName,
Reason: originInput.AfterSalesReason, Reason: originInput.AfterSalesReason,
SalePrice: originInput.AfterSalesPrice, SalePrice: util.StringToFloat64(originInput.AfterSalesPrice),
SaleType: util.StringToInt(originInput.AfterType), SaleType: afterType,
}) })
} }