diff --git a/link_homework/api/v1/record/Record.go b/link_homework/api/v1/record/Record.go index d0d2a62..1c9f0bd 100644 --- a/link_homework/api/v1/record/Record.go +++ b/link_homework/api/v1/record/Record.go @@ -1,6 +1,9 @@ package record -import "link_homework/internal/model/dto" +import ( + "github.com/gogf/gf/v2/os/gtime" + "link_homework/internal/model/dto" +) type GetRecordListReq struct { Id int `json:"id" orm:"" dc:"作业id"` @@ -44,3 +47,22 @@ type GetShopInfoByDeptIdRes struct { ShopId string `json:"shopId" orm:"db:cms;member_info;column:shopId" dc:"门店id"` ShopName string `json:"shopName" orm:"db:cms;member_info;column:shopName" dc:"门店名"` } + +type ExcelExportReq struct { + Jwcode int `json:"jwcode" dc:"精网号"` + Name string `json:"name" dc:"用户名字"` + DeptId string `json:"deptId" dc:"部门id"` + DeptName string `json:"deptName" dc:"部门名"` + ShopId string `json:"shopId" dc:"门店id"` + ShopName string `json:"shopName" dc:"门店名"` + Reply []Reply `json:"Reply" dc:"答案详情"` +} + +type Reply struct { + FormId int `json:"formId"` + Type int `json:"type"` + FormTitle string `json:"formTitle"` + ContentTitle string `json:"contentTitle"` + Content string `json:"content"` + SubmitTime gtime.Time `json:"submitTime"` +} diff --git a/link_homework/internal/cmd/cmd.go b/link_homework/internal/cmd/cmd.go index a7c3a17..9d6024a 100644 --- a/link_homework/internal/cmd/cmd.go +++ b/link_homework/internal/cmd/cmd.go @@ -37,6 +37,7 @@ var ( group.POST("/getrecordbycondition", record.NewManageRecord().GetRecordByCondition) group.POST("/getdeptinfo", record.NewManageRecord().GetDeptInfo) group.POST("/getshopinfo", record.NewManageRecord().GetShopInfo) + group.POST("/exceleexport", record.NewManageRecord().ExeclExport) group.POST("/get-homework-list", homework.Homework().GetHomeworkList) group.POST("/get-homework", homework.Homework().GetHomework) group.POST("/add-homework", homework.Homework().AddHomework) diff --git a/link_homework/internal/controller/clientPage/clientPage.go b/link_homework/internal/controller/clientPage/clientPage.go index 9329225..83f3a86 100644 --- a/link_homework/internal/controller/clientPage/clientPage.go +++ b/link_homework/internal/controller/clientPage/clientPage.go @@ -5,6 +5,7 @@ import ( CPage "link_homework/api/v1/ClientPage" "link_homework/internal/model/dto" "link_homework/internal/service" + "link_homework/utility" ) type ClientPage struct{} @@ -16,7 +17,15 @@ func NewClientPage() *ClientPage { // 查询作业列表 func (c *ClientPage) GetHomeworkList(r *ghttp.Request) { //请求中不需要携带任何参数 - result, err := service.Client().ClientGetHomeworkList(r.Context()) + token := r.Get("token").String() + jwcode, err := utility.GetJwcodeJSON(token) + if err != nil { + r.Response.WriteJsonExit(dto.Result{ + Code: 400, + Message: err.Error(), + }) + } + result, err := service.Client().ClientGetHomeworkList(r.Context(), jwcode) if err != nil { r.Response.WriteJsonExit(dto.Result{ Code: 400, @@ -54,7 +63,14 @@ func (c *ClientPage) GetHomeworkQuestion(r *ghttp.Request) { } func (c *ClientPage) CommitHomework(r *ghttp.Request) { - var jwcode int = 90038794 + token := r.Get("token").String() + jwcode, err := utility.GetJwcodeJSON(token) + if err != nil { + r.Response.WriteJsonExit(dto.Result{ + Code: 400, + Message: err.Error(), + }) + } var req CPage.CommitHomeworkReq if err := r.Parse(&req); err != nil { r.Response.WriteJsonExit(dto.Result{ @@ -63,7 +79,7 @@ func (c *ClientPage) CommitHomework(r *ghttp.Request) { }) } - err := service.Client().CommitHomework(r.Context(), req, jwcode) + err = service.Client().CommitHomework(r.Context(), req, jwcode) if err != nil { r.Response.WriteJsonExit(dto.Result{ Code: 400, diff --git a/link_homework/internal/controller/record/manageRecord.go b/link_homework/internal/controller/record/manageRecord.go index 528512e..1242c75 100644 --- a/link_homework/internal/controller/record/manageRecord.go +++ b/link_homework/internal/controller/record/manageRecord.go @@ -1,10 +1,14 @@ package record import ( + "github.com/360EntSecGroup-Skylar/excelize" "github.com/gogf/gf/v2/net/ghttp" "link_homework/api/v1/record" "link_homework/internal/model/dto" "link_homework/internal/service" + "log" + "net/http" + "strconv" ) type ManageRecord struct{} @@ -96,5 +100,170 @@ func (m *ManageRecord) GetShopInfo(r *ghttp.Request) { Message: "success", Data: result, }) +} + +func (m *ManageRecord) ExeclExport(r *ghttp.Request) { + //获取前端传来的参数 + var req record.GetRecordByConditionReq + if err := r.Parse(&req); err != nil { + r.Response.WriteJsonExit(dto.Result{ + Code: 400, + Message: err.Error(), + }) + } + //获取数据 + data, err := service.Record().GetRecordByCondition(r.Context(), req.Id, req.Jwcode, req.DeptId, req.ShopId, req.PageNo, req.PageSize) + if err != nil { + r.Response.WriteJsonExit(dto.Result{ + Code: 400, + Message: err.Error(), + }) + } + + //创建文件 + f := excelize.NewFile() + sheet := "Sheet1" + f.NewSheet(sheet) + + ////创建表头 + //var header []string + ////for _, field :=range reflect.Type(record.GetRecordListRes{}){ + //// header = append(header, field.Name) + ////} + //for i := 0; i < reflect.TypeOf(record.GetRecordListRes{}).NumField(); i++ { + // header = append(header, reflect.TypeOf(record.GetRecordListRes{}).Field(i).Name) + //} + + headers := []string{"精网号", "用户名字", "部门名", "门店名", "答案详情", "提交时间"} + headerStyle, err := f.NewStyle(`{"font":{"bold":true},"fill":{"type":"solid","color":"#4F81BD"}}`) + if err != nil { + r.Response.WriteJsonExit(dto.Result{ + Code: 400, + Message: err.Error(), + }) + } + for i, header := range headers { + cellName := getExcelColumnName(i) + "1" + f.SetCellValue(sheet, cellName, header) + f.SetCellStyle(sheet, cellName, cellName, headerStyle) + } + + //填充数据 + for rowIndex, row := range data { + // 假设 data 是一个 []GetRecordListRes 类型的切片 + rowData := row //.(record.GetRecordListRes) // 类型断言(这里需要确保 data 的类型是正确的) + // 或者使用反射,但更推荐使用标签和直接映射 + f.SetCellValue(sheet, getExcelColumnName(0)+strconv.Itoa(rowIndex+2), rowData.Jwcode) + f.SetCellValue(sheet, getExcelColumnName(1)+strconv.Itoa(rowIndex+2), rowData.Name) + f.SetCellValue(sheet, getExcelColumnName(2)+strconv.Itoa(rowIndex+2), rowData.DeptName) + f.SetCellValue(sheet, getExcelColumnName(3)+strconv.Itoa(rowIndex+2), rowData.ShopName) + f.SetCellValue(sheet, getExcelColumnName(4)+strconv.Itoa(rowIndex+2), rowData.Reply) + f.SetCellValue(sheet, getExcelColumnName(5)+strconv.Itoa(rowIndex+2), rowData.Reply[0].UpdatedAt.Format("2006-01-02 15:04:05")) + } + + ////定义表头样式,font:定义字体样式,如字体类型、字体大小、字体颜色等,Arial:字体家族为Arial. + ////fill:定义填充样式,如背景色 + //const ( + // headerStyleJSON = `{ + // "font": { + // "bold": true, + // "italic": false, + // "family": "Arial", + // "size": 14, + // "color": "#FFFFFF" //更换成你想要的字体font + // }, + // "fill": { + // "type": "solid", + // "color": "#4F81BD" // 更换为你想要的背景色 + // } + // }` + //) + + ////填充表头 + //headerStyle, err := f.NewStyle(headerStyleJSON) + //if err != nil { + // r.Response.WriteJsonExit(dto.Result{ + // Code: 400, + // Message: err.Error(), + // }) + //} + // + //for i, v := range header { + // cell := fmt.Sprintf("%s%d", getExcelColumnName(i), 1) + // f.SetCellValue(sheet, cell, v) + // f.SetCellStyle(sheet, cell, cell, headerStyle) + //} + // + ////填充数据 + //for i, row := range data { + // for j, col := range header { + // cell := fmt.Sprintf("%s%d", getExcelColumnName(j), i+2) + // //f.SetCellValue(sheet, cell, row[col]) + // f.SetCellValue(sheet, cell, row.FieldByName(col).Interface()) + // } + //} + + //设置默认打开的sheet + f.SetActiveSheet(f.GetSheetIndex(sheet)) + + // 将 Excel 文件作为 HTTP 响应发送给客户端 + r.Response.Header().Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") + r.Response.Header().Set("Content-Disposition", "attachment; filename=data.xlsx") + r.Response.WriteHeader(http.StatusOK) + if _, err := f.WriteTo(r.Response.Writer); err != nil { //这里有问题,说左右值数量不同,我加了个_ + // 处理错误(注意:这里可能无法再发送 JSON 响应,因为响应头已经发送) + log.Printf("Error writing Excel file to response: %v", err) + } + + ////保存文件 + //if err := f.SaveAs("data.xlsx"); err != nil { + // r.Response.WriteJsonExit(dto.Result{ + // Code: 400, + // Message: err.Error(), + // }) + //} + // + //r.Response.WriteJsonExit(dto.Result{ + // Code: 200, + // Message: "success", + // Data: "data.xlsx", + //}) + +} + +//func getExcelColumnName(index int) string { +// var result string +// for index > 0 { +// index-- +// result = string('A'+index%26) + result +// index /= 26 +// } +// return result +//} + +// getExcelColumnName 将整数索引转换为 Excel 列名 +func getExcelColumnName(index int) string { + if index <= 0 { + return "" + } + + const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + var columnName string + + for index > 0 { + // 取余数得到当前位的字母 + remainder := index % 26 + // 将字母添加到结果字符串的前面 + columnName = string(letters[remainder-1]) + columnName + // 去掉已经处理过的最低位(因为 Excel 列名是从 1 开始计数的,所以这里要减 1) + // 但由于我们是从后往前构建字符串,所以实际上是在下一次循环中处理 index/26 的结果 + index = (index - remainder) / 26 + // 由于上面的计算中 index-remainder 可能是 26 的倍数(当 remainder 为 0 时),这样会导致 index 多减 1, + // 所以当 remainder 为 0 时,我们需要将 index 加回 1(或者等价地,不执行 index-- 操作)。 + // 但由于我们在循环中每次都会执行 index = (index - remainder) / 26,并且当 remainder 为 0 时, + // (index - 0) / 26 实际上就是 index / 26,这是正确的。因此,我们不需要在这里对 remainder 为 0 的情况进行特殊处理。 + // 这里的注释主要是为了解释为什么上面的计算是正确的,以及为什么不需要对 remainder 为 0 的情况进行额外处理。 + } + return columnName } diff --git a/link_homework/internal/logic/client/client.go b/link_homework/internal/logic/client/client.go index f8f31ad..4973767 100644 --- a/link_homework/internal/logic/client/client.go +++ b/link_homework/internal/logic/client/client.go @@ -16,8 +16,8 @@ func init() { service.RegisterClient(&sClient{}) } -func (s *sClient) ClientGetHomeworkList(ctx context.Context) (homeworkList []ClientPage.GetHomeworkListRse, err error) { - var jwcode = 90038794 //需要从token中获取当前的数据 +func (s *sClient) ClientGetHomeworkList(ctx context.Context, jwcode int) (homeworkList []ClientPage.GetHomeworkListRse, err error) { + //var jwcode = 90038794 //需要从token中获取当前的数据 err = dao.ActivityInteractiveGroup.Ctx(ctx).Fields("id", "name", "DATE_FORMAT(end_date, '%Y-%m-%d') as end_date"). Where("end_date>?", gtime.Now()).OrderDesc("end_date").Scan(&homeworkList) if err != nil { diff --git a/link_homework/internal/logic/homework/homework.go b/link_homework/internal/logic/homework/homework.go index 5ee9927..de669b3 100644 --- a/link_homework/internal/logic/homework/homework.go +++ b/link_homework/internal/logic/homework/homework.go @@ -32,7 +32,7 @@ func (s *sHomework) GetHomeworkList(ctx context.Context, pageNo int, pageSize in if value.String() != "" { // 如果Redis中有数据,尝试解析为ActivityInteractiveGroup列表 err = json.Unmarshal(value.Bytes(), &homeworkList) //反序列化 - //homeworkList = UpdateHomework(ctx, homeworkList) + homeworkList = UpdateHomework(ctx, homeworkList) if err != nil { return nil, err } @@ -40,31 +40,34 @@ func (s *sHomework) GetHomeworkList(ctx context.Context, pageNo int, pageSize in } // 如果Redis中没有数据,查询数据库 - err = dao.ActivityInteractiveGroup.Ctx(ctx).With(entity.Live{}).Order("end_date desc, start_date desc").Page(pageNo, pageSize).Scan(&homeworkList) + err = dao.ActivityInteractiveGroup.Ctx(ctx).With(entity.Live{}).Order("status asc, start_date desc, end_date desc").Page(pageNo, pageSize).Scan(&homeworkList) err = g.DB("cms").Model("fx_article").Where("id", gdb.ListItemValuesUnique(homeworkList, "ArticleId")).ScanList(&homeworkList, "Article", "id:ArticleId") + homeworkList = UpdateHomework(ctx, homeworkList) if err != nil { return nil, err } - homeworkList = UpdateHomework(ctx, homeworkList) // 将查询到的作业列表序列化并存储到Redis,更新频繁变更的数据 homeworkListJson, _ := json.Marshal(homeworkList) _, err = g.Redis().Set(ctx, fmt.Sprintf("%d-%d homeworklist", pageNo, pageSize), homeworkListJson) - //homeworkList = UpdateHomework(ctx, homeworkList) return } func UpdateHomework(ctx context.Context, homeworkList []*entity.ActivityInteractiveGroup) []*entity.ActivityInteractiveGroup { for _, v := range homeworkList { - if v.StartDate.After(gtime.Now()) { - v.Status = 0 - } else if v.EndDate.Before(gtime.Now()) { - v.Status = 2 - } else { - v.Status = 1 + if v.Status != 2 { + if v.StartDate.After(gtime.Now()) { + v.Status = 0 + } else if v.EndDate.Before(gtime.Now()) { + v.Status = 2 + } else { + v.Status = 1 + } + if v.Status == 1 { + v.Count, _ = dao.ActivityInteractiveRecord.Ctx(ctx).Where("group_id", v.Id).Group("form_id").Limit(1).Count() + } } - v.Count, _ = dao.ActivityInteractiveRecord.Ctx(ctx).Where("group_id", v.Id).Group("form_id").Limit(1).Count() } return homeworkList } diff --git a/link_homework/internal/logic/middleware/interceptor.go b/link_homework/internal/logic/middleware/interceptor.go index 2401f5b..464f1ef 100644 --- a/link_homework/internal/logic/middleware/interceptor.go +++ b/link_homework/internal/logic/middleware/interceptor.go @@ -11,7 +11,7 @@ func MiddlewareCORS(r *ghttp.Request) { } func MiddlewareIsLogin(r *ghttp.Request) { - token := r.GetHeader("Authorization") + token := r.GetHeader("token") if token == "" { r.Response.WriteJsonExit(dto.Result{ Code: 401, diff --git a/link_homework/internal/logic/record/record.go b/link_homework/internal/logic/record/record.go index 0900281..3eea23d 100644 --- a/link_homework/internal/logic/record/record.go +++ b/link_homework/internal/logic/record/record.go @@ -24,8 +24,12 @@ func NewRecord() *sRecord { // 无条件全查 func (s *sRecord) GetRecordList(ctx context.Context, groupId, pageNo, pageSize int) (record []pkgRecord.GetRecordListRes, err error) { //从record表中查询出jwcode,根据group_id - err = dao.ActivityInteractiveRecord.Ctx(ctx).Fields("jwcode").Where("group_id", groupId).Group("jwcode"). - Page(pageNo, pageSize).Scan(&record) + if pageNo == 0 && pageSize == 0 { + err = dao.ActivityInteractiveRecord.Ctx(ctx).Fields("jwcode").Where("group_id", groupId).Group("jwcode").Scan(&record) + } else { + err = dao.ActivityInteractiveRecord.Ctx(ctx).Fields("jwcode").Where("group_id", groupId).Group("jwcode"). + Page(pageNo, pageSize).Scan(&record) + } if err != nil { return nil, errors.New("无条件查jwcode失败") } @@ -46,7 +50,7 @@ func (s *sRecord) GetRecordList(ctx context.Context, groupId, pageNo, pageSize i //根据jwcode,groupId在record表中查询最新的提交记录进行存放 var recordInfo []dto.RecordInfo err = dao.ActivityInteractiveRecord.Ctx(ctx).Fields("content", "content_title", "updated_at", "form_id"). - Where("jwcode", info.Jwcode).Where("group_id", groupId).Group("form_id").Order("updated_at desc").Scan(&recordInfo) //不是最新的,需要再改 + Where("jwcode", info.Jwcode).Where("group_id", groupId).Group("form_id").Order("updated_at desc").Scan(&recordInfo) if err != nil { return nil, err } @@ -62,7 +66,7 @@ func (s *sRecord) GetRecordList(ctx context.Context, groupId, pageNo, pageSize i return } -// 根据条件查询 +// 根据条件查询 对所有结果进行筛选 func (s *sRecord) GetRecordByCondition(ctx context.Context, groupId, jwcode int, deptId, shopId string, pageNo, pageSize int) (record []pkgRecord.GetRecordListRes, err error) { //全查 recordList, err := s.GetRecordList(ctx, groupId, pageNo, pageSize) diff --git a/link_homework/internal/service/client.go b/link_homework/internal/service/client.go index 57314c2..ce027c0 100644 --- a/link_homework/internal/service/client.go +++ b/link_homework/internal/service/client.go @@ -12,7 +12,7 @@ import ( type ( IClient interface { - ClientGetHomeworkList(ctx context.Context) (homeworkList []ClientPage.GetHomeworkListRse, err error) + ClientGetHomeworkList(ctx context.Context, jwcode int) (homeworkList []ClientPage.GetHomeworkListRse, err error) GetHomeworkQuestion(ctx context.Context, groupId int) (questions []ClientPage.GetHomeworkQuestionRes, err error) CommitHomework(ctx context.Context, req ClientPage.CommitHomeworkReq, jwcode int) (err error) } diff --git a/link_homework/internal/service/record.go b/link_homework/internal/service/record.go index ba08449..8e87bac 100644 --- a/link_homework/internal/service/record.go +++ b/link_homework/internal/service/record.go @@ -14,7 +14,7 @@ type ( IRecord interface { // 无条件全查 GetRecordList(ctx context.Context, groupId int, pageNo int, pageSize int) (record []pkgRecord.GetRecordListRes, err error) - // 根据条件查询 + // 根据条件查询 对所有结果进行筛选 GetRecordByCondition(ctx context.Context, groupId int, jwcode int, deptId string, shopId string, pageNo int, pageSize int) (record []pkgRecord.GetRecordListRes, err error) // 查询部门信息 GetDeptInfo(ctx context.Context) (depts []pkgRecord.GetDeptInfoRes, err error) diff --git a/link_homework/manifest/config/config.yaml b/link_homework/manifest/config/config.yaml index 824ea46..ebc5fd4 100644 --- a/link_homework/manifest/config/config.yaml +++ b/link_homework/manifest/config/config.yaml @@ -1,8 +1,6 @@ # https://goframe.org/docs/web/server-config-file-template server: - address: ":8080" - openapiPath: "/api.json" - swaggerPath: "/swagger" + address: ":8080" # https://goframe.org/docs/core/glog-config logger: