Skip to content

Commit 2a9bcf1

Browse files
Merge pull request #14 from xh-polaris/moonlight
fix:生产环境jieba dict缺失
2 parents 2a4eb33 + d0825a9 commit 2a9bcf1

File tree

9 files changed

+113
-8
lines changed

9 files changed

+113
-8
lines changed

Dockerfile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ WORKDIR /build
1313
ADD go.mod .
1414
ADD go.sum .
1515
RUN go mod download
16+
17+
# 重要:创建目录并复制字典文件
18+
RUN mkdir -p /build/dict
19+
# 复制gojieba的字典文件到构建目录
20+
RUN cp -r /go/pkg/mod/github.com/yanyiwu/gojieba@v1.4.6/deps/cppjieba/dict/* /build/dict/ || true
21+
1622
COPY . .
1723
RUN sh ./build.sh
1824

@@ -25,5 +31,8 @@ ENV TZ Asia/Shanghai
2531

2632
WORKDIR /app
2733
COPY --from=builder /build/output /app
34+
COPY --from=builder /build/dict /app/dict
35+
36+
ENV JIEBA_DICT_PATH=/app/dict
2837

2938
CMD ["sh", "./bootstrap.sh"]
File renamed without changes.

biz/application/service/dashboard.go

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ type IDashboardService interface {
4747

4848
// 对话记录
4949
DashboardUserConvRecords(ctx context.Context, req *core_api.DashboardUserConvRecordsReq) (*core_api.DashboardUserConvRecordsResp, error)
50+
DashboardUnitConvRecords(ctx context.Context, req *core_api.DashboardUnitConvRecordsReq) (*core_api.DashboardUnitConvRecordsResp, error)
5051
DashboardGetReport(ctx context.Context, req *core_api.DashboardGetReportReq) (*core_api.DashboardGetReportResp, error)
5152
}
5253

@@ -661,18 +662,19 @@ func (s *DashboardService) DashboardListClasses(ctx context.Context, req *core_a
661662
}
662663

663664
// 查询结果
664-
res, err := s.UserMapper.CountByClasses(ctx, unitOID, grades, classes)
665+
clsStats, err := s.UserMapper.CountByClasses(ctx, unitOID, grades, classes)
666+
clsTeachers, err := s.UserMapper.FindUnitClassTeachers(ctx, unitOID)
665667
if err != nil {
666668
return nil, errorx.New(errno.ErrCountUserByClasses)
667669
}
668670

669671
// 整理结果,构建响应
670672
return &core_api.DashboardListClassesResp{
671-
Grades: aggregateAndSort(res),
673+
Grades: aggregateAndSort(clsStats, clsTeachers),
672674
}, nil
673675
}
674676

675-
func aggregateAndSort(mapperRes []*user.ClassStatResult) []*core_api.GradeInfo {
677+
func aggregateAndSort(mapperRes []*user.ClassStatResult, clsTeachers user.ClassTeachers) []*core_api.GradeInfo {
676678
if len(mapperRes) == 0 {
677679
return make([]*core_api.GradeInfo, 0)
678680
}
@@ -696,8 +698,8 @@ func aggregateAndSort(mapperRes []*user.ClassStatResult) []*core_api.GradeInfo {
696698
Class: item.Info.Class,
697699
UserNum: uNum,
698700
AlarmNum: aNum,
699-
TeacherName: "",
700-
TeacherPhone: "",
701+
TeacherName: clsTeachers[item.Info.Grade][item.Info.Class].Name,
702+
TeacherPhone: clsTeachers[item.Info.Grade][item.Info.Class].Code,
701703
})
702704
}
703705

@@ -1035,3 +1037,30 @@ func (s *DashboardService) DashboardGetReport(ctx context.Context, req *core_api
10351037
Msg: "success",
10361038
}, nil
10371039
}
1040+
1041+
func (s *DashboardService) DashboardUnitConvRecords(ctx context.Context, req *core_api.DashboardUnitConvRecordsReq) (*core_api.DashboardUnitConvRecordsResp, error) {
1042+
if uid := req.GetUnitId(); uid != "" {
1043+
return s.getOneUnitConvs(ctx, req)
1044+
}
1045+
1046+
return s.getAllUnitsConvs(ctx, req)
1047+
}
1048+
1049+
// req包含unitId
1050+
func (s *DashboardService) getOneUnitConvs(ctx context.Context, req *core_api.DashboardUnitConvRecordsReq) (*core_api.DashboardUnitConvRecordsResp, error) {
1051+
unitOID, err := bson.ObjectIDFromHex(req.GetUnitId())
1052+
if err != nil {
1053+
return nil, errorx.New(errno.ErrInvalidParams, errorx.KV("field", "UnitId"), errorx.KV("value", "用户ID"))
1054+
}
1055+
1056+
_, err = s.ConversationMapper.CountByUnit(ctx, &unitOID)
1057+
if err != nil {
1058+
return nil, errorx.New(errno.ErrDashboardGetConversations)
1059+
}
1060+
1061+
return nil, errorx.New(errno.UnImplementErr)
1062+
}
1063+
1064+
func (s *DashboardService) getAllUnitsConvs(ctx context.Context, req *core_api.DashboardUnitConvRecordsReq) (*core_api.DashboardUnitConvRecordsResp, error) {
1065+
return nil, errorx.New(errno.UnImplementErr)
1066+
}

biz/cst/consts.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ const (
5252
Status = "status"
5353
DeletedStatus = -1
5454

55+
Student = "student"
56+
Teacher = "teacher"
57+
ClassTeacher = "class_teacher"
58+
5559
Emotion = "emotion"
5660
Meta = "$meta"
5761
TextScore = "textScore"

biz/domain/wordcld/wordcloud.go

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ package wordcld
33
import (
44
"bufio"
55
"context"
6-
"github.com/xh-polaris/psych-core-api/biz/application/dto/core_api"
76
"os"
87
"path/filepath"
98
"regexp"
109
"strings"
1110
"sync"
1211
"unicode/utf8"
1312

13+
"github.com/xh-polaris/psych-core-api/biz/application/dto/core_api"
14+
1415
"github.com/xh-polaris/psych-core-api/biz/cst"
1516
"github.com/xh-polaris/psych-core-api/biz/infra/mapper/message"
1617
"github.com/xh-polaris/psych-core-api/biz/infra/mapper/report"
@@ -107,10 +108,45 @@ func ensureStopWordsLoaded() {
107108
stopWordsOnce.Do(loadStopWords)
108109
}
109110

111+
// initJiebaInstance 初始化jieba实例
112+
func initJiebaInstance() *gojieba.Jieba {
113+
dictPath := os.Getenv("JIEBA_DICT_PATH")
114+
115+
// 在生产环境(Docker)中,必须使用自定义路径,因为默认的Go模块路径不存在
116+
// 如果没有设置环境变量,设置默认值为Docker中的字典路径
117+
if dictPath == "" {
118+
dictPath = "/app/dict"
119+
}
120+
121+
// 检查自定义字典目录是否存在并包含必要的字典文件
122+
requiredFiles := []string{
123+
"jieba.dict.utf8",
124+
"hmm_model.utf8",
125+
"user.dict.utf8",
126+
"idf.utf8",
127+
"stop_words.utf8",
128+
}
129+
130+
// 检查所有字典文件是否存在
131+
dictPaths := make([]string, 0, len(requiredFiles))
132+
for _, filename := range requiredFiles {
133+
fullPath := filepath.Join(dictPath, filename)
134+
if _, err := os.Stat(fullPath); os.IsNotExist(err) {
135+
// 如果字典文件不存在,尝试使用gojieba的默认配置(仅限开发环境)
136+
// 生产环境中这通常会失败,所以应该确保字典文件正确部署
137+
return gojieba.NewJieba()
138+
}
139+
dictPaths = append(dictPaths, fullPath)
140+
}
141+
142+
// 如果所有字典文件都存在,使用自定义路径
143+
return gojieba.NewJieba(dictPaths...)
144+
}
145+
110146
func NewWordCloudExtractor(rptMapper report.IMongoMapper) *WordCloudExtractor {
111147
Extractor = WordCloudExtractor{
112148
rptMapper: rptMapper,
113-
jieba: gojieba.NewJieba(),
149+
jieba: initJiebaInstance(),
114150
}
115151
return &Extractor
116152
}

biz/infra/mapper/user/mapper.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ type IMongoMapper interface {
3939
CountAlarmUsers(ctx context.Context, unitId *bson.ObjectID) (int32, error)
4040
CountAlarmUsersByPeriod(ctx context.Context, unitId *bson.ObjectID, start, end time.Time) (int32, error)
4141
RiskDistributionStats(ctx context.Context, unitId *bson.ObjectID) ([]*RiskStat, error)
42+
FindUnitClassTeachers(ctx context.Context, unitId bson.ObjectID) (ClassTeachers, error)
4243
}
4344

4445
type mongoMapper struct {
@@ -269,3 +270,25 @@ func (m *mongoMapper) RiskDistributionStats(ctx context.Context, unitId *bson.Ob
269270
}
270271
return results, nil
271272
}
273+
274+
type ClassTeachers map[int32]map[int32]*User
275+
276+
func (m *mongoMapper) FindUnitClassTeachers(ctx context.Context, unitId bson.ObjectID) (ClassTeachers, error) {
277+
filter := bson.M{
278+
cst.UnitID: unitId,
279+
cst.Role: RoleStoI[cst.ClassTeacher],
280+
}
281+
282+
clsTeacherUsers, err := m.FindAllByFields(ctx, filter)
283+
if err != nil {
284+
logs.Error("[user mapper] FindUnitClassTeachers err:%s", errorx.ErrorWithoutStack(err))
285+
return nil, err
286+
}
287+
288+
clsTeachers := make(map[int32]map[int32]*User)
289+
for _, u := range clsTeacherUsers {
290+
clsTeachers[u.Grade][u.Class] = u
291+
}
292+
293+
return clsTeachers, nil
294+
}

biz/infra/mapper/user/user.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ import (
1010
var (
1111
RiskLevelStoI = map[string]int32{cst.High: 1, cst.Medium: 2, cst.Low: 3, cst.Normal: 4}
1212
RiskLevelItoS = map[int32]string{1: cst.High, 2: cst.Medium, 3: cst.Low, 4: cst.Normal}
13+
14+
RoleStoI = map[string]int32{cst.Student: 0, cst.Teacher: 1, cst.ClassTeacher: 2}
15+
RoleItoS = map[int32]string{0: cst.Student, 1: cst.Teacher, 2: cst.ClassTeacher}
1316
)
1417

1518
type User struct {
@@ -24,6 +27,7 @@ type User struct {
2427
RiskLevel int `json:"riskLevel,omitempty" bson:"risk_level,omitempty"`
2528
Status int `json:"status,omitempty" bson:"status,omitempty"`
2629
EnrollYear int32 `json:"enrollYear,omitempty" bson:"enroll_year,omitempty"`
30+
Role int32 `json:"role,omitempty" bson:"role,omitempty"`
2731
Grade int32 `json:"grade,omitempty" bson:"grade,omitempty"`
2832
Class int32 `json:"class,omitempty" bson:"class,omitempty"`
2933
Options map[string]any `json:"option,omitempty" bson:"option,omitempty"`

types/errno/dashboard.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const (
1616
ErrDashboardEmotionRatio = 5009
1717
ErrDashboardGetUnitKeywords = 5010
1818
ErrDashboardGetUserInfo = 5011 // 获取用户信息失败
19-
ErrDashboardGetConversations = 5012 // 获取用户对话记录失败
19+
ErrDashboardGetConversations = 5012 // 获取对话记录失败
2020
ErrDashboardGetConvReports = 5014 // 获取对话报表失败
2121
ErrDashboardGenerateWordCloud = 5015 // 生成词云失败
2222
ErrDashboardGetReport = 5016 // 获取报表失败

0 commit comments

Comments
 (0)