123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 |
- package api
- import (
- "errors"
- "fmt"
- "oilseal-train/db/model"
- "oilseal-train/db/repo"
- "oilseal-train/log"
- "os"
- "strings"
- "time"
- "github.com/gin-gonic/gin"
- "github.com/xuri/excelize/v2"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
- )
- func Bank(r *GinRouter) {
- r.POSTJWT("/bank/create", BankAdd)
- r.GETJWT("/bank/list", BankList)
- r.POSTJWT("/bank/update", BankEdit)
- r.POSTJWT("/bank/delete/:id", BankDelete)
- r.GETJWT("/bank/exportXls/:bankId", BankExportXls)
- r.POSTJWT("/bank/importXls", BankImportXls)
- }
- func BankAdd(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- err := IsAdmin(apictx)
- if err != nil {
- return nil, err
- }
- var form model.Bank
- err = c.ShouldBindJSON(&form)
- if err != nil {
- return nil, errors.New("参数错误")
- }
- if form.Name == "" {
- return nil, errors.New("题库名称不能为空")
- }
- if form.State == 0 {
- form.State = 1
- }
- form.CreateTime = time.Now()
- form.UpdateTime = time.Now()
- return repo.RepoAddDoc(apictx.CreateRepoCtx(), repo.CollectionBank, &form)
- }
- func BankList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- // err := IsAdmin(apictx)
- // if err != nil {
- // return nil, err
- // }
- page, size, query := UtilQueryPageSize(c)
- if _name, ok := query["name"]; ok {
- query["name"] = bson.M{"$regex": _name.(string)}
- }
- return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
- CollectName: repo.CollectionBank,
- Page: page,
- Size: size,
- Query: query,
- Project: []string{"name", "state", "desc", "createTime", "updateTime"},
- Sort: bson.M{"_id": -1},
- })
- }
- func BankEdit(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- // 操作用户为admin
- err := IsAdmin(apictx)
- if err != nil {
- return nil, err
- }
- var form model.Bank
- err = c.ShouldBindJSON(&form)
- if err != nil {
- return nil, errors.New("参数错误")
- }
- if len(form.Id) != 12 {
- return nil, errors.New("id不正确")
- }
- return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionBank, form.Id.Hex(), &form)
- }
- // 删除用户
- func BankDelete(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- // 操作用户为admin
- err := IsAdmin(apictx)
- if err != nil {
- return nil, err
- }
- _id := c.Param("id")
- _, err = primitive.ObjectIDFromHex(_id)
- if err != nil {
- return nil, errors.New("id错误")
- }
- return repo.RepoDeleteDoc(apictx.CreateRepoCtx(), repo.CollectionBank, _id)
- }
- func BankExportXls(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- // 操作用户为admin
- err := IsAdmin(apictx)
- if err != nil {
- return nil, err
- }
- // 获取题库信息
- _bankId := c.Param("bankId")
- bankId, err := primitive.ObjectIDFromHex(_bankId)
- if err != nil || len(bankId) != 12 {
- return nil, errors.New("题库id错误")
- }
- bank := model.Bank{}
- found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
- CollectName: repo.CollectionBank,
- Query: repo.Map{"_id": bankId, "state": 1},
- }, &bank)
- if !found || err != nil {
- return nil, errors.New("未找到题库数据")
- }
- tests := make([]map[string]interface{}, 0)
- err = repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
- CollectName: repo.CollectionTest,
- Query: repo.Map{"bankId": bankId, "state": 1},
- Sort: bson.M{"_id": -1},
- Project: []string{"question", "type", "answerItem", "answer", "analyze"},
- }, &tests)
- if err != nil {
- return nil, err
- }
- if len(tests) < 1 {
- return nil, errors.New("该题库没有有效数据")
- }
- for _, test := range tests {
- for k, ts := range test {
- if k == "answerItem" {
- if a, ok := ts.(map[string]interface{})["A"]; ok {
- test["A"] = a
- }
- if b, ok := ts.(map[string]interface{})["B"]; ok {
- test["B"] = b
- }
- if c, ok := ts.(map[string]interface{})["C"]; ok {
- test["C"] = c
- }
- if d, ok := ts.(map[string]interface{})["D"]; ok {
- test["D"] = d
- }
- if _t, ok := ts.(map[string]interface{})["true"]; ok {
- test["true"] = _t
- }
- if _f, ok := ts.(map[string]interface{})["false"]; ok {
- test["false"] = _f
- }
- }
- if k == "answer" {
- for _, vi := range ts.(primitive.A) {
- if vi.(string) == "true" {
- test["formatAnswer"] = "正确"
- } else if vi.(string) == "false" {
- test["formatAnswer"] = "错误"
- } else {
- if test["formatAnswer"] != nil {
- test["formatAnswer"] = fmt.Sprintf("%v,%v", test["formatAnswer"], vi)
- } else {
- test["formatAnswer"] = fmt.Sprintf("%v", vi)
- }
- }
- }
- }
- if k == "type" {
- if ts.(int32) == 1 {
- test["formatType"] = "选择题"
- }
- if ts.(int32) == 2 {
- test["formatType"] = "判断题"
- }
- }
- }
- delete(test, "answerItem")
- delete(test, "answer")
- delete(test, "type")
- }
- f := excelize.NewFile()
- defer f.Close()
- // 表格名
- sheetName := bank.Name
- f.SetSheetName("Sheet1", sheetName)
- f.SetPageLayout(sheetName, excelize.PageLayoutOrientation("portrait"), excelize.PageLayoutPaperSize(9))
- f.SetHeaderFooter(sheetName, &excelize.FormatHeaderFooter{
- FirstHeader: bank.Name,
- FirstFooter: bank.Name,
- OddFooter: "第 &P 页,共 &N页",
- })
- center, _ := f.NewStyle(&excelize.Style{
- Alignment: &excelize.Alignment{
- Horizontal: "left",
- Vertical: "center",
- },
- })
- columns := []ExcelColumn{
- {
- Style: center,
- Width: 40,
- Header: "问题",
- Key: "question",
- },
- {
- Style: center,
- Width: 10,
- Header: "类型",
- Key: "formatType",
- },
- {
- Style: center,
- Width: 20,
- Header: "选项A",
- Key: "A",
- },
- {
- Style: center,
- Width: 20,
- Header: "选项B",
- Key: "B",
- },
- {
- Style: center,
- Width: 20,
- Header: "选项C",
- Key: "C",
- },
- {
- Style: center,
- Width: 20,
- Header: "选项D",
- Key: "D",
- },
- {
- Style: center,
- Width: 10,
- Header: "TRUE",
- Key: "true",
- },
- {
- Style: center,
- Width: 10,
- Header: "FALSE",
- Key: "false",
- },
- {
- Style: center,
- Width: 10,
- Header: "答案",
- Key: "formatAnswer",
- },
- {
- Style: center,
- Width: 30,
- Header: "解析",
- Key: "analyze",
- },
- }
- // 代表每列的单元格字符
- cos := []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"}
- // 设置列格式 和 表头内容(第一列)
- i := 1
- for k, col := range columns {
- f.SetColStyle(sheetName, cos[k], col.Style)
- f.SetColWidth(sheetName, cos[k], cos[k], col.Width) // A,A,10
- setstring := fmt.Sprintf("%s%d", cos[k], i)
- f.SetCellValue(sheetName, setstring, col.Header)
- }
- setCellKey := map[string]string{
- "A": "question",
- "B": "formatType",
- "C": "A",
- "D": "B",
- "E": "C",
- "F": "D",
- "G": "true",
- "H": "false",
- "I": "formatAnswer",
- "J": "analyze",
- }
- rowStyle, _ := f.NewStyle(&excelize.Style{
- Border: []excelize.Border{
- {Type: "bottom", Color: "#000000", Style: 2},
- },
- Alignment: &excelize.Alignment{
- Horizontal: "left",
- Vertical: "center",
- },
- })
- f.SetRowStyle(sheetName, i, len(tests)+1, rowStyle)
- i++
- // rows
- for _, test := range tests {
- // 每行的单元格
- for k, v := range test {
- f.SetRowHeight(sheetName, i, 25)
- for _, c := range cos {
- // "id" == "id" -- set A3
- if setCellKey[c] == k { // A,B,C与item.key的关系
- setString := fmt.Sprintf("%s%d", c, i)
- f.SetCellValue(sheetName, setString, v)
- }
- }
- }
- i++
- }
- // 另存为
- _ = os.MkdirAll("excel", os.ModePerm)
- // filename1 := time.Now().Format("20060102150405") + ".xlsx"
- filename1 := bank.Name + ".xlsx"
- err = f.SaveAs(filename1)
- if err != nil {
- return nil, err
- }
- filename := filename1
- // filename := time.Now().Format("20060102150405") + ".xlsx"
- c.Header("Content-Type", "application/octet-stream")
- c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
- c.Header("Content-Transfer-Encoding", "binary")
- err = f.Write(c.Writer)
- if err != nil {
- fmt.Println(err)
- return false, err
- }
- return true, nil
- }
- func BankImportXls(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- // 操作用户为admin
- err := IsAdmin(apictx)
- if err != nil {
- return nil, err
- }
- _id := c.PostForm("id")
- id, err := primitive.ObjectIDFromHex(_id)
- if err != nil {
- return nil, err
- }
- file, _, err := c.Request.FormFile("file")
- if err != nil {
- return nil, errors.New("文件错误")
- }
- excel, err := excelize.OpenReader(file)
- if err != nil {
- return nil, err
- }
- excelIndex := excel.GetActiveSheetIndex()
- sheetName := excel.GetSheetName(excelIndex)
- tests, err := excel.GetRows(sheetName)
- if err != nil {
- return nil, err
- }
- // return tests, nil
- errors := []string{}
- if len(tests) > 0 {
- for index, ts := range tests {
- // 标题行
- if index == 0 {
- continue
- }
- test := &model.Test{}
- test.Question = ts[0]
- if ts[1] == "选择题" {
- test.Type = 1
- test.AnswerItem = &model.AnswerItem{
- A: ts[2],
- B: ts[3],
- C: ts[4],
- D: ts[5],
- }
- // 答案 ts[8]
- test.Answer = strings.Split(ts[8], ",")
- }
- if ts[1] == "判断题" {
- test.Type = 2
- test.AnswerItem = &model.AnswerItem{
- True: ts[6],
- False: ts[7],
- }
- // 答案 ts[8]
- if ts[8] == "正确" {
- test.Answer = append(test.Answer, "true")
- }
- if ts[8] == "错误" {
- test.Answer = append(test.Answer, "false")
- }
- }
- test.BankId = id
- if len(ts) > 9 {
- test.Analyze = ts[9]
- }
- test.State = 1
- test.CreateTime = time.Now()
- test.UpdateTime = time.Now()
- rowNum := index + 1
- _, err = repo.RepoAddDoc(apictx.CreateRepoCtx(), repo.CollectionTest, test)
- if err != nil {
- errors = append(errors, fmt.Sprintf("第%d行错误: %s", rowNum, "保存数据失败"))
- log.Error(err)
- }
- }
- }
- return errors, nil
- }
|