Skip to content

Commit b9b620f

Browse files
authored
合并 Dev 分支,准备发布新版本 (#286)
2 parents d1dc7ae + f11be44 commit b9b620f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1631
-34
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ cover.out
3535
/internal/cases/internal/integration/logs
3636
/internal/skill/internal/integration/logs
3737
/internal/feedback/internal/integration/logs
38+
/internal/ai/internal/integration/logs
39+
/internal/resume/internal/integration/logs
3840
/config/cert/
3941

4042
local_test.go

.run/webook.run.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
<working_directory value="$PROJECT_DIR$" />
55
<go_parameters value="--tags=mock" />
66
<parameters value="--config=config/local.yaml" />
7+
<envs>
8+
<env name="EGO_DEBUG" value="false" />
9+
</envs>
710
<kind value="PACKAGE" />
811
<package value="github.com/ecodeclub/webook" />
912
<directory value="$PROJECT_DIR$" />

.script/setup.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ test -x $TARGET_PUSH || chmod +x $TARGET_PUSH
2828
test -x $TARGET_COMMIT || chmod +x $TARGET_COMMIT
2929

3030
echo "安装 golangci-lint..."
31-
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.52.2
31+
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.0
3232

3333
echo "安装 goimports..."
3434
go install golang.org/x/tools/cmd/goimports@latest

internal/ai/internal/domain/jd.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package domain
2+
3+
const (
4+
AnalysisJDTech = "analysis_jd_tech"
5+
AnalysisJDBiz = "analysis_jd_biz"
6+
AnalysisJDPosition = "analysis_jd_position"
7+
)
8+
9+
type JDEvaluation struct {
10+
Score float64 `json:"score"`
11+
Analysis string `json:"analysis"`
12+
}
13+
14+
type JD struct {
15+
Amount int64
16+
TechScore *JDEvaluation
17+
BizScore *JDEvaluation
18+
PosScore *JDEvaluation
19+
}

internal/ai/internal/domain/llm.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ type LLMResponse struct {
4343
}
4444

4545
type BizConfig struct {
46+
Id int64
47+
Biz string
4648
// 使用的模型
4749
Model string
4850
// 多少分钱/1000 token

internal/ai/internal/errs/code.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package errs
2+
3+
var (
4+
SystemError = ErrorCode{Code: 516001, Msg: "系统错误"}
5+
InsufficientCredit = ErrorCode{Code: 516002, Msg: "积分不足"}
6+
)
7+
8+
type ErrorCode struct {
9+
Code int
10+
Msg string
11+
}
Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,306 @@
1+
package integration
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net/http"
7+
"testing"
8+
9+
"github.com/ecodeclub/ekit/iox"
10+
"github.com/ecodeclub/ginx/session"
11+
"github.com/ecodeclub/webook/internal/ai/internal/integration/startup"
12+
"github.com/ecodeclub/webook/internal/ai/internal/repository/dao"
13+
"github.com/ecodeclub/webook/internal/ai/internal/web"
14+
"github.com/ecodeclub/webook/internal/credit"
15+
"github.com/ecodeclub/webook/internal/test"
16+
testioc "github.com/ecodeclub/webook/internal/test/ioc"
17+
"github.com/gin-gonic/gin"
18+
"github.com/gotomicro/ego/core/econf"
19+
"github.com/gotomicro/ego/server/egin"
20+
"github.com/stretchr/testify/assert"
21+
"github.com/stretchr/testify/require"
22+
"github.com/stretchr/testify/suite"
23+
"gorm.io/gorm"
24+
)
25+
26+
type ConfigSuite struct {
27+
suite.Suite
28+
db *gorm.DB
29+
adminHandler *web.AdminHandler
30+
server *egin.Component
31+
}
32+
33+
func (s *ConfigSuite) SetupSuite() {
34+
db := testioc.InitDB()
35+
s.db = db
36+
err := dao.InitTables(db)
37+
s.NoError(err)
38+
// 先插入 BizConfig
39+
mou, err := startup.InitModule(s.db, nil, &credit.Module{})
40+
require.NoError(s.T(), err)
41+
s.adminHandler = mou.AdminHandler
42+
econf.Set("server", map[string]any{"contextTimeout": "1s"})
43+
server := egin.Load("server").Build()
44+
server.Use(func(ctx *gin.Context) {
45+
ctx.Set("_session", session.NewMemorySession(session.Claims{
46+
Uid: 123,
47+
}))
48+
})
49+
s.adminHandler.RegisterRoutes(server.Engine)
50+
s.server = server
51+
}
52+
53+
func (s *ConfigSuite) TestConfig_Save() {
54+
testCases := []struct {
55+
name string
56+
config web.ConfigRequest
57+
before func(t *testing.T)
58+
after func(t *testing.T, id int64)
59+
wantCode int
60+
id int64
61+
}{
62+
{
63+
name: "新增",
64+
config: web.ConfigRequest{
65+
Config: web.Config{
66+
Biz: "test",
67+
MaxInput: 10,
68+
Model: "testModel",
69+
Price: 100,
70+
Temperature: 0.5,
71+
TopP: 0.5,
72+
SystemPrompt: "testPrompt",
73+
PromptTemplate: "testTemplate",
74+
KnowledgeId: "testKnowledgeId",
75+
},
76+
},
77+
before: func(t *testing.T) {
78+
79+
},
80+
wantCode: 200,
81+
id: 1,
82+
after: func(t *testing.T, id int64) {
83+
var conf dao.BizConfig
84+
err := s.db.WithContext(context.Background()).
85+
Where("id = ?", id).First(&conf).Error
86+
require.NoError(t, err)
87+
s.assertBizConfig(dao.BizConfig{
88+
Id: 1,
89+
Biz: "test",
90+
MaxInput: 10,
91+
Model: "testModel",
92+
Price: 100,
93+
Temperature: 0.5,
94+
TopP: 0.5,
95+
SystemPrompt: "testPrompt",
96+
PromptTemplate: "testTemplate",
97+
KnowledgeId: "testKnowledgeId",
98+
}, conf)
99+
},
100+
},
101+
{
102+
name: "更新",
103+
config: web.ConfigRequest{
104+
Config: web.Config{
105+
Id: 2,
106+
Biz: "2_test",
107+
MaxInput: 102,
108+
Model: "2_testModel",
109+
Price: 102,
110+
Temperature: 2.5,
111+
TopP: 2.5,
112+
SystemPrompt: "testPrompt2",
113+
PromptTemplate: "testTemplate2",
114+
KnowledgeId: "testKnowledgeId2",
115+
},
116+
},
117+
before: func(t *testing.T) {
118+
err := s.db.WithContext(context.Background()).
119+
Table("ai_biz_configs").
120+
Create(dao.BizConfig{
121+
Id: 2,
122+
Biz: "test_2",
123+
MaxInput: 100,
124+
Model: "testModel",
125+
Price: 100,
126+
Temperature: 0.5,
127+
TopP: 0.5,
128+
SystemPrompt: "testPrompt",
129+
PromptTemplate: "testTemplate",
130+
KnowledgeId: "testKnowledgeId",
131+
Ctime: 11,
132+
Utime: 22,
133+
}).Error
134+
require.NoError(t, err)
135+
},
136+
after: func(t *testing.T, id int64) {
137+
var conf dao.BizConfig
138+
err := s.db.WithContext(context.Background()).
139+
Where("id = ?", id).
140+
Model(&dao.BizConfig{}).
141+
First(&conf).Error
142+
require.NoError(t, err)
143+
s.assertBizConfig(dao.BizConfig{
144+
Id: 2,
145+
Biz: "2_test",
146+
MaxInput: 102,
147+
Model: "2_testModel",
148+
Price: 102,
149+
Temperature: 2.5,
150+
TopP: 2.5,
151+
SystemPrompt: "testPrompt2",
152+
PromptTemplate: "testTemplate2",
153+
KnowledgeId: "testKnowledgeId2",
154+
}, conf)
155+
},
156+
wantCode: 200,
157+
id: 2,
158+
},
159+
}
160+
for _, tc := range testCases {
161+
s.T().Run(tc.name, func(t *testing.T) {
162+
tc.before(t)
163+
req, err := http.NewRequest(http.MethodPost,
164+
"/ai/config/save", iox.NewJSONReader(tc.config))
165+
req.Header.Set("content-type", "application/json")
166+
require.NoError(t, err)
167+
recorder := test.NewJSONResponseRecorder[int64]()
168+
s.server.ServeHTTP(recorder, req)
169+
require.Equal(t, tc.wantCode, recorder.Code)
170+
id := recorder.MustScan().Data
171+
assert.Equal(t, tc.id, id)
172+
tc.after(t, id)
173+
err = s.db.Exec("TRUNCATE TABLE `ai_biz_configs`").Error
174+
require.NoError(s.T(), err)
175+
})
176+
}
177+
}
178+
179+
func (s *ConfigSuite) TestConfig_List() {
180+
configs := make([]dao.BizConfig, 0, 32)
181+
for i := 1; i < 10; i++ {
182+
cfg := dao.BizConfig{
183+
Id: int64(i),
184+
Biz: fmt.Sprintf("biz_%d", i),
185+
MaxInput: 100,
186+
Model: fmt.Sprintf("test_model_%d", i),
187+
Price: 1000,
188+
Temperature: 37.5,
189+
TopP: 0.8,
190+
SystemPrompt: "test_prompt",
191+
PromptTemplate: "test_template",
192+
KnowledgeId: "test_knowledge",
193+
}
194+
configs = append(configs, cfg)
195+
}
196+
err := s.db.WithContext(context.Background()).Create(&configs).Error
197+
require.NoError(s.T(), err)
198+
req, err := http.NewRequest(http.MethodGet,
199+
"/ai/config/list", iox.NewJSONReader(nil))
200+
req.Header.Set("content-type", "application/json")
201+
require.NoError(s.T(), err)
202+
recorder := test.NewJSONResponseRecorder[[]web.Config]()
203+
s.server.ServeHTTP(recorder, req)
204+
require.Equal(s.T(), 200, recorder.Code)
205+
confs := recorder.MustScan().Data
206+
assert.Equal(s.T(), getWantConfigs(), confs)
207+
err = s.db.Exec("TRUNCATE TABLE `ai_biz_configs`").Error
208+
require.NoError(s.T(), err)
209+
}
210+
211+
func (s *ConfigSuite) Test_Detail() {
212+
testcases := []struct {
213+
name string
214+
req web.ConfigInfoReq
215+
before func(t *testing.T)
216+
wantCode int
217+
wantData web.Config
218+
}{
219+
{
220+
name: "获取配置",
221+
wantCode: 200,
222+
req: web.ConfigInfoReq{
223+
Id: 3,
224+
},
225+
before: func(t *testing.T) {
226+
err := s.db.WithContext(context.Background()).
227+
Table("ai_biz_configs").
228+
Create(dao.BizConfig{
229+
Id: 3,
230+
Biz: "test_3",
231+
MaxInput: 100,
232+
Model: "testModel",
233+
Price: 100,
234+
Temperature: 0.5,
235+
TopP: 0.5,
236+
SystemPrompt: "testPrompt",
237+
PromptTemplate: "testTemplate",
238+
KnowledgeId: "testKnowledgeId",
239+
Ctime: 11,
240+
Utime: 22,
241+
}).Error
242+
require.NoError(t, err)
243+
},
244+
wantData: web.Config{
245+
Id: 3,
246+
Biz: "test_3",
247+
MaxInput: 100,
248+
Model: "testModel",
249+
Price: 100,
250+
Temperature: 0.5,
251+
TopP: 0.5,
252+
SystemPrompt: "testPrompt",
253+
PromptTemplate: "testTemplate",
254+
KnowledgeId: "testKnowledgeId",
255+
},
256+
},
257+
}
258+
for _, tc := range testcases {
259+
s.T().Run(tc.name, func(t *testing.T) {
260+
tc.before(t)
261+
req, err := http.NewRequest(http.MethodPost,
262+
"/ai/config/detail", iox.NewJSONReader(tc.req))
263+
req.Header.Set("content-type", "application/json")
264+
require.NoError(t, err)
265+
recorder := test.NewJSONResponseRecorder[web.Config]()
266+
s.server.ServeHTTP(recorder, req)
267+
require.Equal(s.T(), 200, recorder.Code)
268+
conf := recorder.MustScan().Data
269+
assert.Equal(t, tc.wantData, conf)
270+
err = s.db.Exec("TRUNCATE TABLE `ai_biz_configs`").Error
271+
require.NoError(s.T(), err)
272+
})
273+
}
274+
}
275+
276+
func getWantConfigs() []web.Config {
277+
configs := make([]web.Config, 0, 32)
278+
for i := 9; i >= 1; i-- {
279+
cfg := web.Config{
280+
Id: int64(i),
281+
Biz: fmt.Sprintf("biz_%d", i),
282+
MaxInput: 100,
283+
Model: fmt.Sprintf("test_model_%d", i),
284+
Price: 1000,
285+
Temperature: 37.5,
286+
TopP: 0.8,
287+
SystemPrompt: "test_prompt",
288+
PromptTemplate: "test_template",
289+
KnowledgeId: "test_knowledge",
290+
}
291+
configs = append(configs, cfg)
292+
}
293+
return configs
294+
}
295+
296+
func (s *ConfigSuite) assertBizConfig(wantConfig dao.BizConfig, actualConfig dao.BizConfig) {
297+
assert.True(s.T(), actualConfig.Ctime > 0)
298+
assert.True(s.T(), actualConfig.Utime > 0)
299+
actualConfig.Ctime = 0
300+
actualConfig.Utime = 0
301+
assert.Equal(s.T(), wantConfig, actualConfig)
302+
}
303+
304+
func TestConfigSuite(t *testing.T) {
305+
suite.Run(t, new(ConfigSuite))
306+
}

0 commit comments

Comments
 (0)