Преглед изворни кода

feature:培训考试题库管理后端接口

liuyaqi пре 3 година
родитељ
комит
cb061e8c08
5 измењених фајлова са 661 додато и 2 уклоњено
  1. 102 0
      handler/learning/question.go
  2. 2 0
      main.go
  3. 45 0
      model/learning/learning_question.go
  4. 229 0
      service/learning/question.go
  5. 283 2
      swaggerui/swagger.yml

+ 102 - 0
handler/learning/question.go

@@ -0,0 +1,102 @@
+package learning
+
+import (
+	"context"
+	"lims_adapter/model/learning"
+	learningSrv "lims_adapter/service/learning"
+
+	"dashoo.cn/common_definition/comm_def"
+	"dashoo.cn/micro_libary/myerrors"
+	"github.com/gogf/gf/frame/g"
+)
+
+type LearningQuestion struct{}
+
+func (c *LearningQuestion) List(ctx context.Context, req *learning.LearningQuestionListReq, rsp *comm_def.CommonMsg) error {
+	g.Log().Infof("LearningQuestion.List request %v ", &req)
+	s, err := learningSrv.NewLearningQuestionService(ctx)
+	if err != nil {
+		return err
+	}
+	total, ent, err := s.List(ctx, req)
+	_, err, code, msg := myerrors.CheckError(err)
+	if err != nil {
+		return err
+	}
+	if ent == nil {
+		ent = []*learning.LearningQuestionGetRsp{}
+	}
+	rsp.Code = code
+	rsp.Msg = msg
+	rsp.Data = map[string]interface{}{
+		"total": total,
+		"list":  ent,
+	}
+	return nil
+}
+
+func (c *LearningQuestion) Get(ctx context.Context, req *learning.LearningQuestionGetReq, rsp *comm_def.CommonMsg) error {
+	g.Log().Infof("LearningQuestion.Get request %v ", &req)
+	s, err := learningSrv.NewLearningQuestionService(ctx)
+	if err != nil {
+		return err
+	}
+	ent, err := s.Get(ctx, req)
+	_, err, code, msg := myerrors.CheckError(err)
+	if err != nil {
+		return err
+	}
+	rsp.Code = code
+	rsp.Msg = msg
+	rsp.Data = ent
+	return nil
+}
+
+func (c *LearningQuestion) Add(ctx context.Context, req *learning.LearningQuestionAddReq, rsp *comm_def.CommonMsg) error {
+	g.Log().Infof("LearningQuestion.Add request %v ", &req)
+	s, err := learningSrv.NewLearningQuestionService(ctx)
+	if err != nil {
+		return err
+	}
+	id, err := s.Add(ctx, req)
+	_, err, code, msg := myerrors.CheckError(err)
+	if err != nil {
+		return err
+	}
+	rsp.Code = code
+	rsp.Msg = msg
+	rsp.Data = id
+	return nil
+}
+
+func (c *LearningQuestion) Update(ctx context.Context, req *learning.LearningQuestionUpdateReq, rsp *comm_def.CommonMsg) error {
+	g.Log().Infof("LearningQuestion.Add request %v ", &req)
+	s, err := learningSrv.NewLearningQuestionService(ctx)
+	if err != nil {
+		return err
+	}
+	err = s.Update(ctx, req)
+	_, err, code, msg := myerrors.CheckError(err)
+	if err != nil {
+		return err
+	}
+	rsp.Code = code
+	rsp.Msg = msg
+	return nil
+}
+
+func (c *LearningQuestion) Delete(ctx context.Context, req *learning.LearningQuestionDeleteReq, rsp *comm_def.CommonMsg) error {
+	g.Log().Infof("LearningQuestion.Add request %v ", &req)
+	s, err := learningSrv.NewLearningQuestionService(ctx)
+	if err != nil {
+		return err
+	}
+	err = s.Delete(ctx, req.Id)
+	_, err, code, msg := myerrors.CheckError(err)
+	if err != nil {
+		return err
+	}
+	rsp.Code = code
+	rsp.Msg = msg
+	return nil
+}

+ 2 - 0
main.go

@@ -60,6 +60,8 @@ func main() {
 		new((learning.LearningSkill)), "")
 	s.RegisterName("LearningMaterial",
 		new((learning.LearningMaterial)), "")
+	s.RegisterName("LearningQuestion",
+		new((learning.LearningQuestion)), "")
 
 	// 注册auth处理
 	s.AuthFunc = handleAuth

+ 45 - 0
model/learning/learning_question.go

@@ -5,6 +5,7 @@
 package learning
 
 import (
+	"lims_adapter/model"
 	"lims_adapter/model/learning/internal"
 )
 
@@ -12,3 +13,47 @@ import (
 type LearningQuestion internal.LearningQuestion
 
 // Fill with you ideas below.
+type LearningQuestionGetReq struct {
+	Id int `json:"id" v:"required#请输入题目Id"` // 题目 ID
+}
+
+type LearningQuestionOption struct {
+	Name      string `json:"name"`
+	Content   string `json:"content"`
+	IsCorrect bool   `json:"isCorrect"`
+}
+
+type LearningQuestionGetRsp struct {
+	LearningQuestion
+	Content interface{} `json:"content"`
+}
+
+type LearningQuestionListReq struct {
+	Page    *model.Page    `json:"page"`
+	OrderBy *model.OrderBy `json:"orderBy"`
+	SkillId int            `json:"skillId"`
+	Name    string         `json:"name"`
+}
+
+type LearningQuestionAddReq struct {
+	SkillId     int                      `json:"skillId" v:"required#请输入技能Id"`              // 技能 Id
+	Name        string                   `json:"name" v:"required#请输入题目内容"`                 // 题目内容
+	Type        int                      `json:"type" v:"required#请输入题型 in:1,2,3#请输入正确的题型"` // 题型 1 单选 2 多选 3 判断
+	Enable      int                      `json:"enable"`                                    // 是否启用
+	Content     []LearningQuestionOption `json:"content"  v:"required#请输入题目内容"`             // 题目内容
+	Explanation string                   `json:"explanation"`                               // 题目解析
+}
+
+type LearningQuestionUpdateReq struct {
+	Id          int                      `json:"id" v:"required#请输入题目Id"`    // Id
+	SkillId     int                      `json:"skillId"`                    // 技能 Id
+	Name        string                   `json:"name"`                       // 题目内容
+	Type        int                      `json:"type" v:"in:1,2,3#请输入正确的题型"` // 题型 1 单选 2 多选 3 判断
+	Enable      *int                     `json:"enable"`                     // 是否启用  0 未启用 1 启用
+	Content     []LearningQuestionOption `json:"content"`                    // 题目内容
+	Explanation string                   `json:"explanation"`                // 题目解析
+}
+
+type LearningQuestionDeleteReq struct {
+	Id int `json:"id" v:"required#请输入题目Id"`
+}

+ 229 - 0
service/learning/question.go

@@ -0,0 +1,229 @@
+package learning
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"lims_adapter/dao/learning"
+	"lims_adapter/model/learning"
+
+	"dashoo.cn/micro_libary/micro_srv"
+	"dashoo.cn/micro_libary/myerrors"
+	"dashoo.cn/micro_libary/request"
+	"github.com/gogf/gf/os/gtime"
+	"github.com/gogf/gf/util/gvalid"
+)
+
+type LearningQuestionService struct {
+	Dao      *dao.LearningQuestionDao
+	Tenant   string
+	userInfo request.UserInfo
+}
+
+func NewLearningQuestionService(ctx context.Context) (*LearningQuestionService, error) {
+	tenant, err := micro_srv.GetTenant(ctx)
+	if err != nil {
+		return nil, fmt.Errorf("获取组合码异常:%s", err.Error())
+	}
+	// 获取用户信息
+	userInfo, err := micro_srv.GetUserInfo(ctx)
+	if err != nil {
+		return nil, fmt.Errorf("获取用户信息异常:%s", err.Error())
+	}
+	return &LearningQuestionService{
+		Dao:      dao.NewLearningQuestionDao(tenant),
+		Tenant:   tenant,
+		userInfo: userInfo,
+	}, nil
+}
+
+func (s LearningQuestionService) Get(ctx context.Context, req *learning.LearningQuestionGetReq) (ent *learning.LearningQuestionGetRsp, err error) {
+	validErr := gvalid.CheckStruct(ctx, req, nil)
+	if validErr != nil {
+		return nil, validErr.Current()
+	}
+
+	q, err := s.Dao.Where("Id = ?", req.Id).One()
+	if err != nil {
+		return nil, err
+	}
+	if q == nil {
+		return nil, myerrors.NewMsgError(nil, "题目不存在")
+	}
+	content := []learning.LearningQuestionOption{}
+	err = json.Unmarshal([]byte(q.Content), &content)
+	return &learning.LearningQuestionGetRsp{
+		LearningQuestion: *q,
+		Content:          content,
+	}, err
+}
+
+func (s LearningQuestionService) List(ctx context.Context, req *learning.LearningQuestionListReq) (int, []*learning.LearningQuestionGetRsp, error) {
+	dao := &s.Dao.LearningQuestionDao
+	if req.Name != "" {
+		dao = dao.Where("Name LIKE ?", fmt.Sprintf("%%%s%%", req.Name))
+	}
+	if req.SkillId != 0 {
+		dao = dao.Where("SkillId = ?", req.SkillId)
+	}
+	total, err := dao.Count()
+	if err != nil {
+		return 0, nil, err
+	}
+
+	if req.Page != nil {
+		if req.Page.Current == 0 {
+			req.Page.Current = 1
+		}
+		if req.Page.Size == 0 {
+			req.Page.Size = 10
+		}
+		dao = dao.Page(req.Page.Current, req.Page.Size)
+	}
+
+	if req.OrderBy != nil && req.OrderBy.Value != "" {
+		order := "asc"
+		if req.OrderBy.Type == "desc" {
+			order = "desc"
+		}
+		dao = dao.Order(req.OrderBy.Value, order)
+	}
+	ent, err := dao.All()
+	if err != nil {
+		return 0, nil, err
+	}
+
+	var questions []*learning.LearningQuestionGetRsp
+	for _, q := range ent {
+		content := []learning.LearningQuestionOption{}
+		err = json.Unmarshal([]byte(q.Content), &content)
+		if err != nil {
+			return 0, nil, err
+		}
+		questions = append(questions, &learning.LearningQuestionGetRsp{
+			LearningQuestion: *q,
+			Content:          content,
+		})
+	}
+	return total, questions, err
+}
+
+func (s LearningQuestionService) Add(ctx context.Context, req *learning.LearningQuestionAddReq) (int, error) {
+	validErr := gvalid.CheckStruct(ctx, req, nil)
+	if validErr != nil {
+		return 0, validErr.Current()
+	}
+	if len(req.Content) < 2 {
+		return 0, myerrors.NewMsgError(nil, "至少需要两个选项")
+	}
+	correctCount := 0
+	for _, o := range req.Content {
+		if o.IsCorrect {
+			correctCount += 1
+		}
+	}
+	if correctCount < 1 {
+		return 0, myerrors.NewMsgError(nil, "正确答案未设置")
+	}
+	if (req.Type == 1 || req.Type == 3) && correctCount != 1 {
+		return 0, myerrors.NewMsgError(nil, "正确答案只能设置一个")
+	}
+
+	content, err := json.Marshal(req.Content)
+	if err != nil {
+		return 0, err
+	}
+	id, err := s.Dao.InsertAndGetId(learning.LearningQuestion{
+		SkillId:     req.SkillId,
+		Name:        req.Name,
+		Type:        req.Type,
+		Enable:      req.Enable,
+		Content:     string(content),
+		Explanation: req.Explanation,
+		OperateBy:   s.userInfo.RealName,
+		CreatedAt:   gtime.Now(),
+		UpdatedAt:   gtime.Now(),
+	})
+	if err != nil {
+		return 0, err
+	}
+	return int(id), err
+}
+
+func (s LearningQuestionService) Update(ctx context.Context, req *learning.LearningQuestionUpdateReq) error {
+	validErr := gvalid.CheckStruct(ctx, req, nil)
+	if validErr != nil {
+		return validErr.Current()
+	}
+	if len(req.Content) != 0 {
+		if len(req.Content) < 2 {
+			return myerrors.NewMsgError(nil, "至少需要两个选项")
+		}
+		correctCount := 0
+		for _, o := range req.Content {
+			if o.IsCorrect {
+				correctCount += 1
+			}
+		}
+		if correctCount < 1 {
+			return myerrors.NewMsgError(nil, "正确答案未设置")
+		}
+		if (req.Type == 1 || req.Type == 3) && correctCount != 1 {
+			return myerrors.NewMsgError(nil, "正确答案只能设置一个")
+		}
+	}
+
+	q, err := s.Dao.Where("Id = ?", req.Id).One()
+	if err != nil {
+		return err
+	}
+	if q == nil {
+		return myerrors.NewMsgError(nil, fmt.Sprintf("题目不存在: %d", req.Id))
+	}
+
+	if req.SkillId != 0 {
+		r, err := s.Dao.DB.Table("learning_skill").Where("Id", req.SkillId).One()
+		if err != nil {
+			return err
+		}
+		if r.IsEmpty() {
+			return myerrors.NewMsgError(nil, fmt.Sprintf("技能不存在: %d", req.SkillId))
+		}
+	}
+
+	dao := &s.Dao.LearningQuestionDao
+	toupdate := map[string]interface{}{}
+	if req.SkillId != 0 {
+		toupdate["SkillId"] = req.SkillId
+	}
+	if req.Name != "" {
+		toupdate["Name"] = req.Name
+	}
+	if req.Type != 0 {
+		toupdate["Type"] = req.Type
+	}
+	if req.Enable != nil {
+		toupdate["Enable"] = req.Enable
+	}
+	if req.Content != nil {
+		content, err := json.Marshal(req.Content)
+		if err != nil {
+			return err
+		}
+		toupdate["Content"] = content
+	}
+	if req.Explanation != "" {
+		toupdate["Explanation"] = req.Explanation
+	}
+	if len(toupdate) == 0 {
+		return nil
+	}
+	toupdate["OperateBy"] = s.userInfo.RealName
+	_, err = dao.Where("Id", req.Id).Data(toupdate).Update()
+	return err
+}
+
+func (s LearningQuestionService) Delete(ctx context.Context, id int) error {
+	_, err := s.Dao.Where("Id = ?", id).Delete()
+	return err
+}

+ 283 - 2
swaggerui/swagger.yml

@@ -280,6 +280,131 @@ paths:
                   success:
                     $ref: "#/components/examples/success"
 
+    /LearningQuestion.Get:
+      post:
+        tags:
+          - 考试培训-题库
+        operationId: LearningQuestionGet
+        summary: 题库详情
+        requestBody:
+          required: true
+          content:
+            application/json:
+              schema:
+                oneOf:
+                  - $ref: '#/components/schemas/IdReq'
+              examples:
+                LearningQuestionGet:
+                  $ref: '#/components/examples/LearningQuestionGet'
+        responses:
+          200:
+            description: 请求成功
+            content:
+              application/json:
+                examples:
+                  success:
+                    $ref: "#/components/examples/success"
+
+    /LearningQuestion.List:
+      post:
+        tags:
+          - 考试培训-题库
+        operationId: LearningQuestionList
+        summary: 查询题库
+        requestBody:
+          required: true
+          content:
+            application/json:
+              schema:
+                oneOf:
+                  - $ref: '#/components/schemas/LearningQuestionList'
+              examples:
+                LearningQuestionList:
+                  $ref: '#/components/examples/LearningQuestionList'
+        responses:
+          200:
+            description: 请求成功
+            content:
+              application/json:
+                examples:
+                  success:
+                    $ref: "#/components/examples/success"
+
+    /LearningQuestion.Add:
+      post:
+        tags:
+          - 考试培训-题库
+        operationId: LearningQuestionAdd
+        summary: 添加题库
+        requestBody:
+          required: true
+          content:
+            application/json:
+              schema:
+                oneOf:
+                  - $ref: '#/components/schemas/LearningQuestionAdd'
+              examples:
+                LearningQuestionAdd:
+                  $ref: '#/components/examples/LearningQuestionAdd'
+        responses:
+          200:
+            description: 请求成功
+            content:
+              application/json:
+                examples:
+                  success:
+                    $ref: "#/components/examples/success"
+
+    /LearningQuestion.Update:
+      post:
+        tags:
+          - 考试培训-题库
+        operationId: LearningQuestionUpdate
+        summary: 更新题库
+        requestBody:
+          required: true
+          content:
+            application/json:
+              schema:
+                oneOf:
+                  - $ref: '#/components/schemas/LearningQuestionUpdate'
+              examples:
+                LearningQuestionUpdate:
+                  $ref: '#/components/examples/LearningQuestionUpdate'
+        responses:
+          200:
+            description: 请求成功
+            content:
+              application/json:
+                examples:
+                  success:
+                    $ref: "#/components/examples/success"
+
+    /LearningQuestion.Delete:
+      post:
+        tags:
+          - 考试培训-题库
+        operationId: LearningQuestionDelete
+        summary: 删除题库
+        requestBody:
+          required: true
+          content:
+            application/json:
+              schema:
+                oneOf:
+                  - $ref: '#/components/schemas/IdReq'
+              examples:
+                LearningQuestionDelete:
+                  $ref: '#/components/examples/LearningQuestionDelete'
+        responses:
+          200:
+            description: 请求成功
+            content:
+              application/json:
+                examples:
+                  success:
+                    $ref: "#/components/examples/success"
+
 # 添加这个 swagger ui 会显示授权按钮
 security:
   - bearerAuth: []
@@ -360,8 +485,6 @@ components:
           description: ID
     LearningMaterialList:
       type: object
-      required:
-        - id
       properties:
         page:
           type: object
@@ -407,6 +530,7 @@ components:
         - skillId
         - name
         - type
+        - enable
       properties:
           skillId:
             type: integer
@@ -488,6 +612,114 @@ components:
                 extend:
                   type: string
                   description: 文件扩展名
+    LearningQuestionList:
+      type: object
+      properties:
+        page:
+          type: object
+          description: 分页信息,不传默认不分页,返回所有数据
+          properties:
+            current:
+              type: integer
+              description: 当前页面
+            size:
+              type: integer
+              description: 每页条数
+        orderBy:
+          type: object
+          description: 排序
+          properties:
+            type:
+              type: string
+              description: 排序方式
+              enum:
+                - asc
+                - desc
+            value:
+              type: string
+              description: 字段名
+        skillId:
+          type: integer
+          description: 按技能 Id 查询
+        name:
+          type: string
+          description: 按题目名称模糊查询
+    LearningQuestionAdd:
+      type: object
+      required:
+        - skillId
+        - name
+        - type
+        - content
+      properties:
+        skillId:
+          type: integer
+          description: 技能 Id
+        name:
+          type: string
+          description: 题目名称
+        type:
+          type: integer
+          description: 题型 1 单选 2 多选 3 判断
+        enable:
+          type: integer
+          description: 是否启用 0 未启用 1 启用
+        content: 
+          type: array
+          description: 选项
+          items:
+            type: object
+            properties:
+              name:
+                type: string
+                description: 选项
+              content:
+                type: string
+                description: 内容
+              isCorrect:
+                type: boolean
+                description: 是否是答案
+        explanation:
+          type: string
+          description: 题目解析
+    LearningQuestionUpdate:
+      type: object
+      required:
+        - id
+      properties:
+        id:
+          type: integer
+          description: 题目 id
+        skillId:
+          type: integer
+          description: 技能 Id
+        name:
+          type: string
+          description: 题目名称
+        type:
+          type: integer
+          description: 题型 1 单选 2 多选 3 判断
+        enable:
+          type: integer
+          description: 是否启用 0 未启用 1 启用
+        content: 
+          type: array
+          description: 选项
+          items:
+            type: object
+            properties:
+              name:
+                type: string
+                description: 选项
+              content:
+                type: string
+                description: 内容
+              isCorrect:
+                type: boolean
+                description: 是否是答案
+        explanation:
+          type: string
+          description: 题目解析
 
   examples:
     success:
@@ -574,3 +806,52 @@ components:
     LearningMaterialDelete:
       value:
         id: 1
+    LearningQuestionGet:
+      value:
+        id: 1
+    LearningQuestionList:
+      value:
+        page:
+          current: 2
+          size: 2
+        orderBy:
+          type: desc
+          value: id
+        skillId: 2
+        name: "测试"
+    LearningQuestionAdd:
+      value:
+        skillId: 2
+        name: 测试
+        type: 1
+        enable: 1
+        content:
+          -
+            name: A
+            content: 测试A
+            isCorrect: true
+          -
+            name: B
+            content: 测试B
+            isCorrect: false
+        explanation: 测试
+    LearningQuestionUpdate:
+      value:
+        id: 1
+        skillId: 5
+        name: 测试修改
+        type: 2
+        enable: 1
+        content:
+          -
+            name: A
+            content: 测试测试修改A
+            isCorrect: true
+          -
+            name: B
+            content: 测试测试修改B
+            isCorrect: true
+        explanation: 测试测试修改
+    LearningQuestionDelete:
+      value:
+        id: 1