作者 linmadan

完成任务抢单接口

@@ -21,3 +21,11 @@ func CreateOffTaskService(options map[string]interface{}) (service.OffTaskServic @@ -21,3 +21,11 @@ func CreateOffTaskService(options map[string]interface{}) (service.OffTaskServic
21 } 21 }
22 return domainService.NewOffTaskService(transactionContext) 22 return domainService.NewOffTaskService(transactionContext)
23 } 23 }
  24 +
  25 +func CreateRobTaskService(options map[string]interface{}) (service.RobTaskService, error) {
  26 + var transactionContext *pgTransaction.TransactionContext
  27 + if value, ok := options["transactionContext"]; ok {
  28 + transactionContext = value.(*pgTransaction.TransactionContext)
  29 + }
  30 + return domainService.NewRobTaskService(transactionContext)
  31 +}
@@ -30,10 +30,22 @@ func (taskService *TaskService) RobTask(robTaskCommand *command.RobTaskCommand) @@ -30,10 +30,22 @@ func (taskService *TaskService) RobTask(robTaskCommand *command.RobTaskCommand)
30 defer func() { 30 defer func() {
31 transactionContext.RollbackTransaction() 31 transactionContext.RollbackTransaction()
32 }() 32 }()
33 - if err := transactionContext.CommitTransaction(); err != nil {  
34 - return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) 33 + var robTaskService service.RobTaskService
  34 + if value, err := factory.CreateRobTaskService(map[string]interface{}{
  35 + "transactionContext": transactionContext,
  36 + }); err != nil {
  37 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  38 + } else {
  39 + robTaskService = value
  40 + }
  41 + if task, err := robTaskService.Rob(robTaskCommand.TaskId, robTaskCommand.Receiver); err != nil {
  42 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  43 + } else {
  44 + if err := transactionContext.CommitTransaction(); err != nil {
  45 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  46 + }
  47 + return task, nil
35 } 48 }
36 - return nil, nil  
37 } 49 }
38 50
39 // 对任务进行竞标 51 // 对任务进行竞标
  1 +package service
  2 +
  3 +import "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain"
  4 +
  5 +type RobTaskService interface {
  6 + Rob(taskId int64, receiverUid int64) (*domain.Task, error)
  7 +}
@@ -13,7 +13,7 @@ type TaskDao struct { @@ -13,7 +13,7 @@ type TaskDao struct {
13 transactionContext *pgTransaction.TransactionContext 13 transactionContext *pgTransaction.TransactionContext
14 } 14 }
15 15
16 -func (dao *TaskDao) addRobInfo(taskId int64, receiver *domain.EmployeeInfo) error { 16 +func (dao *TaskDao) AddRobInfo(taskId int64, receiver *domain.EmployeeInfo) error {
17 tx := dao.transactionContext.PgTx 17 tx := dao.transactionContext.PgTx
18 _, err := tx.QueryOne( 18 _, err := tx.QueryOne(
19 pg.Scan(), 19 pg.Scan(),
@@ -22,7 +22,7 @@ func (dao *TaskDao) addRobInfo(taskId int64, receiver *domain.EmployeeInfo) erro @@ -22,7 +22,7 @@ func (dao *TaskDao) addRobInfo(taskId int64, receiver *domain.EmployeeInfo) erro
22 return err 22 return err
23 } 23 }
24 24
25 -func (dao *TaskDao) addBidInfo(taskId int64, bidStartTime time.Time, bidEndTime time.Time) error { 25 +func (dao *TaskDao) AddBidInfo(taskId int64, bidStartTime time.Time, bidEndTime time.Time) error {
26 tx := dao.transactionContext.PgTx 26 tx := dao.transactionContext.PgTx
27 _, err := tx.QueryOne( 27 _, err := tx.QueryOne(
28 pg.Scan(), 28 pg.Scan(),
  1 +package domain_service
  2 +
  3 +import (
  4 + "fmt"
  5 + coreDomain "github.com/linmadan/egglib-go/core/domain"
  6 + pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
  7 + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain"
  8 + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/dao"
  9 + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/repository"
  10 +)
  11 +
  12 +type RobTaskService struct {
  13 + coreDomain.BaseEventPublisher
  14 + transactionContext *pgTransaction.TransactionContext
  15 +}
  16 +
  17 +func (service *RobTaskService) Rob(taskId int64, receiverUid int64) (*domain.Task, error) {
  18 + var employeeRepository domain.EmployeeRepository
  19 + var taskRepository domain.TaskRepository
  20 + var taskDao *dao.TaskDao
  21 + if repository, err := repository.NewEmployeeRepository(service.transactionContext); err != nil {
  22 + return nil, err
  23 + } else {
  24 + employeeRepository = repository
  25 + }
  26 + if repository, err := repository.NewTaskRepository(service.transactionContext); err != nil {
  27 + return nil, err
  28 + } else {
  29 + taskRepository = repository
  30 + }
  31 + if dao, err := dao.NewTaskDao(service.transactionContext); err != nil {
  32 + return nil, err
  33 + } else {
  34 + taskDao = dao
  35 + }
  36 + receiver, err := employeeRepository.FindOne(map[string]interface{}{
  37 + "uid": receiverUid,
  38 + })
  39 + if err != nil {
  40 + return nil, err
  41 + }
  42 + if receiver == nil {
  43 + return nil, fmt.Errorf("无效的领取人")
  44 + }
  45 + task, err := taskRepository.FindOne(map[string]interface{}{
  46 + "taskId": taskId,
  47 + })
  48 + if err != nil {
  49 + return nil, err
  50 + }
  51 + if task == nil {
  52 + return nil, fmt.Errorf("无效的任务")
  53 + }
  54 + if receiver.EmployeeInfo.Uid == task.Sponsor.Uid {
  55 + return nil, fmt.Errorf("无法领取自己发布的任务")
  56 + }
  57 + if task.RobInfo != nil && task.RobInfo.Receiver != nil{
  58 + return nil, fmt.Errorf("任务已经被人领取")
  59 + }
  60 + if err := task.Rob(receiver.EmployeeInfo); err != nil {
  61 + return nil, err
  62 + }
  63 + if err := taskDao.AddRobInfo(taskId, receiver.EmployeeInfo); err != nil {
  64 + return nil, fmt.Errorf("抢单失败,任务可能已经被人领取")
  65 + }
  66 + if task, err := taskRepository.Save(task); err != nil {
  67 + return nil, err
  68 + } else {
  69 + return task, nil
  70 + }
  71 +}
  72 +
  73 +func NewRobTaskService(transactionContext *pgTransaction.TransactionContext) (*RobTaskService, error) {
  74 + if transactionContext == nil {
  75 + return nil, fmt.Errorf("transactionContext参数不能为nil")
  76 + } else {
  77 + return &RobTaskService{
  78 + transactionContext: transactionContext,
  79 + }, nil
  80 + }
  81 +}
@@ -7,10 +7,10 @@ import ( @@ -7,10 +7,10 @@ import (
7 7
8 type RobInfo struct { 8 type RobInfo struct {
9 TableName string `pg:"rob_infos,alias:rob_info"` 9 TableName string `pg:"rob_infos,alias:rob_info"`
10 - Id int64 `pg:",pk"` 10 + Id int64 `pg:",pk"`
11 // 领取人 11 // 领取人
12 Receiver *domain.EmployeeInfo 12 Receiver *domain.EmployeeInfo
13 // 领取时间 13 // 领取时间
14 ReceiveTime time.Time 14 ReceiveTime time.Time
15 - TaskId int64 `pg:",unique"` 15 + TaskId int64 `pg:",unique"`
16 } 16 }
1 package task 1 package task
2 2
3 import ( 3 import (
  4 + "github.com/go-pg/pg"
  5 + "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain"
4 "net/http" 6 "net/http"
  7 + "time"
5 8
6 "github.com/gavv/httpexpect" 9 "github.com/gavv/httpexpect"
7 - "github.com/go-pg/pg"  
8 . "github.com/onsi/ginkgo" 10 . "github.com/onsi/ginkgo"
9 . "github.com/onsi/gomega" 11 . "github.com/onsi/gomega"
10 pG "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/pg" 12 pG "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/pg"
11 ) 13 )
12 14
13 var _ = Describe("对任务进行抢单", func() { 15 var _ = Describe("对任务进行抢单", func() {
14 - var taskId int64  
15 - BeforeEach(func() {  
16 - _, err := pG.DB.QueryOne(  
17 - pg.Scan(&taskId),  
18 - "INSERT INTO tasks (task_id, company_id, task_name, task_type, sponsor, task_status, reference_resource, customer_value, task_nature, su_money, acceptance_standard, task_description, task_picture_urls, is_reward_take, rob_info, bid_info, participators, task_percentage, solve_report, solve_picture_urls, create_time, release_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING id",  
19 - "testTaskId", "testCompanyId", "testTaskName", "testTaskType", "testSponsor", "testTaskStatus", "testReferenceResource", "testCustomerValue", "testTaskNature", "testSuMoney", "testAcceptanceStandard", "testTaskDescription", "testTaskPictureUrls", "testIsRewardTake", "testRobInfo", "testBidInfo", "testParticipators", "testTaskPercentage", "testSolveReport", "testSolvePictureUrls", "testCreateTime", "testReleaseTime")  
20 - Expect(err).NotTo(HaveOccurred())  
21 - })  
22 Describe("对任务进行抢单", func() { 16 Describe("对任务进行抢单", func() {
23 - Context("", func() {  
24 - It("", func() { 17 + Context("领取人对已发布的抢单类型任务进行抢单", func() {
  18 + BeforeEach(func() {
  19 + dayAfter, _ := time.ParseDuration("72h")
  20 + _, err := pG.DB.QueryOne(
  21 + pg.Scan(),
  22 + "INSERT INTO tasks (id, company_id, task_name, task_type, sponsor, task_status, reference_resource, customer_value, task_nature, su_money, acceptance_standard, task_description, task_picture_urls, is_reward_take, participators, task_percentage, solve_report, solve_picture_urls, receiver_uid, create_time, release_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
  23 + 1, 101, "抢单任务1", 1, &domain.EmployeeInfo{
  24 + Uid: 2499036607974745088,
  25 + }, 2, "null", pg.Array([]string{"口感", "便利", "品牌", "售后服务"}), "面", 1000.00, "验收标准1", "任务描述1", pg.Array([]string{}), true, []*domain.EmployeeInfo{
  26 + {
  27 + Uid: 2499036607974745077,
  28 + },
  29 + {
  30 + Uid: 2499036607974745066,
  31 + },
  32 + }, "null", "", pg.Array([]string{}), 0, time.Now(), time.Now().Add(dayAfter))
  33 + Expect(err).NotTo(HaveOccurred())
  34 + _, err1 := pG.DB.QueryOne(
  35 + pg.Scan(),
  36 + "INSERT INTO employees (id, company_id, uid, employee_name, employee_account, su_money) VALUES (?, ?, ?, ?, ?, ?)",
  37 + 1, 101, 2499036607974745088, "testEmployeeName", "testEmployeeAccount", 0)
  38 + Expect(err1).NotTo(HaveOccurred())
  39 + _, err2 := pG.DB.QueryOne(
  40 + pg.Scan(),
  41 + "INSERT INTO employees (id, company_id, uid, employee_name, employee_account, su_money) VALUES (?, ?, ?, ?, ?, ?)",
  42 + 2, 101, 2499036607974745099, "testEmployeeName", "testEmployeeAccount", 0)
  43 + Expect(err2).NotTo(HaveOccurred())
  44 + })
  45 + It("抢单成功", func() {
25 httpExpect := httpexpect.New(GinkgoT(), server.URL) 46 httpExpect := httpexpect.New(GinkgoT(), server.URL)
26 body := map[string]interface{}{ 47 body := map[string]interface{}{
27 - "receiver": "int64", 48 + "receiver": 2499036607974745099,
28 } 49 }
29 - httpExpect.POST("/tasks/{taskId}/rob"). 50 + httpExpect.POST("/tasks/1/rob").
30 WithJSON(body). 51 WithJSON(body).
31 Expect(). 52 Expect().
32 Status(http.StatusOK). 53 Status(http.StatusOK).
@@ -34,12 +55,72 @@ var _ = Describe("对任务进行抢单", func() { @@ -34,12 +55,72 @@ var _ = Describe("对任务进行抢单", func() {
34 Object(). 55 Object().
35 ContainsKey("code").ValueEqual("code", 0). 56 ContainsKey("code").ValueEqual("code", 0).
36 ContainsKey("msg").ValueEqual("msg", "ok"). 57 ContainsKey("msg").ValueEqual("msg", "ok").
37 - ContainsKey("data").Value("data").Object() 58 + ContainsKey("data").Value("data").Object().
  59 + ContainsKey("taskStatus").ValueEqual("taskStatus", 3).
  60 + ContainsKey("robInfo").Value("robInfo").Object().
  61 + ContainsKey("receiver").Value("receiver").Object().
  62 + ContainsKey("uid").ValueEqual("uid", 2499036607974745099)
  63 + })
  64 + })
  65 + Context("领取人对已经被领取的抢单类型任务进行抢单", func() {
  66 + BeforeEach(func() {
  67 + dayAfter, _ := time.ParseDuration("72h")
  68 + _, err := pG.DB.QueryOne(
  69 + pg.Scan(),
  70 + "INSERT INTO tasks (id, company_id, task_name, task_type, sponsor, task_status, reference_resource, customer_value, task_nature, su_money, acceptance_standard, task_description, task_picture_urls, is_reward_take, participators, task_percentage, solve_report, solve_picture_urls, receiver_uid, create_time, release_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
  71 + 1, 101, "抢单任务1", 1, &domain.EmployeeInfo{
  72 + Uid: 2499036607974745088,
  73 + }, 2, "null", pg.Array([]string{"口感", "便利", "品牌", "售后服务"}), "面", 1000.00, "验收标准1", "任务描述1", pg.Array([]string{}), true, []*domain.EmployeeInfo{
  74 + {
  75 + Uid: 2499036607974745077,
  76 + },
  77 + {
  78 + Uid: 2499036607974745066,
  79 + },
  80 + }, "null", "", pg.Array([]string{}), 0, time.Now(), time.Now().Add(dayAfter))
  81 + Expect(err).NotTo(HaveOccurred())
  82 + _, err1 := pG.DB.QueryOne(
  83 + pg.Scan(),
  84 + "INSERT INTO employees (id, company_id, uid, employee_name, employee_account, su_money) VALUES (?, ?, ?, ?, ?, ?)",
  85 + 1, 101, 2499036607974745088, "testEmployeeName", "testEmployeeAccount", 0)
  86 + Expect(err1).NotTo(HaveOccurred())
  87 + _, err2 := pG.DB.QueryOne(
  88 + pg.Scan(),
  89 + "INSERT INTO employees (id, company_id, uid, employee_name, employee_account, su_money) VALUES (?, ?, ?, ?, ?, ?)",
  90 + 2, 101, 2499036607974745099, "testEmployeeName", "testEmployeeAccount", 0)
  91 + Expect(err2).NotTo(HaveOccurred())
  92 + _, err3 := pG.DB.QueryOne(
  93 + pg.Scan(),
  94 + "INSERT INTO rob_infos (id, task_id) VALUES (?, ?)",
  95 + 1, 1)
  96 + Expect(err3).NotTo(HaveOccurred())
  97 + })
  98 + It("抢单失败", func() {
  99 + httpExpect := httpexpect.New(GinkgoT(), server.URL)
  100 + body := map[string]interface{}{
  101 + "receiver": 2499036607974745099,
  102 + }
  103 + httpExpect.POST("/tasks/1/rob").
  104 + WithJSON(body).
  105 + Expect().
  106 + Status(http.StatusOK).
  107 + JSON().
  108 + Object().
  109 + ContainsKey("code").ValueEqual("code", 501).
  110 + ContainsKey("msg").ValueEqual("msg", "内部服务出错:抢单失败,任务可能已经被人领取")
38 }) 111 })
39 }) 112 })
40 }) 113 })
41 AfterEach(func() { 114 AfterEach(func() {
42 _, err := pG.DB.Exec("DELETE FROM tasks WHERE true") 115 _, err := pG.DB.Exec("DELETE FROM tasks WHERE true")
43 Expect(err).NotTo(HaveOccurred()) 116 Expect(err).NotTo(HaveOccurred())
  117 + _, err1 := pG.DB.Exec("DELETE FROM bid_infos WHERE true")
  118 + Expect(err1).NotTo(HaveOccurred())
  119 + _, err2 := pG.DB.Exec("DELETE FROM bidder_infos WHERE true")
  120 + Expect(err2).NotTo(HaveOccurred())
  121 + _, err3 := pG.DB.Exec("DELETE FROM employees WHERE true")
  122 + Expect(err3).NotTo(HaveOccurred())
  123 + _, err4 := pG.DB.Exec("DELETE FROM rob_infos WHERE true")
  124 + Expect(err4).NotTo(HaveOccurred())
44 }) 125 })
45 }) 126 })