作者 linmadan

添加素币相关功能,完成任务验收接口

... ... @@ -12,3 +12,11 @@ func CreateTaskDao(options map[string]interface{}) (*dao.TaskDao, error) {
}
return dao.NewTaskDao(transactionContext)
}
func CreateEmployeeDao(options map[string]interface{}) (*dao.EmployeeDao, error) {
var transactionContext *pg.TransactionContext
if value, ok := options["transactionContext"]; ok {
transactionContext = value.(*pg.TransactionContext)
}
return dao.NewEmployeeDao(transactionContext)
}
... ...
... ... @@ -53,3 +53,11 @@ func CreateApplyCompleteTaskService(options map[string]interface{}) (service.App
}
return domainService.NewApplyCompleteTaskService(transactionContext)
}
func CreateAcceptanceTaskService(options map[string]interface{}) (service.AcceptanceTaskService, error) {
var transactionContext *pgTransaction.TransactionContext
if value, ok := options["transactionContext"]; ok {
transactionContext = value.(*pgTransaction.TransactionContext)
}
return domainService.NewAcceptanceTaskService(transactionContext)
}
... ...
... ... @@ -229,10 +229,22 @@ func (taskService *TaskService) AcceptanceTask(acceptanceTaskCommand *command.Ac
defer func() {
transactionContext.RollbackTransaction()
}()
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
var acceptanceTaskService service.AcceptanceTaskService
if value, err := factory.CreateAcceptanceTaskService(map[string]interface{}{
"transactionContext": transactionContext,
}); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
acceptanceTaskService = value
}
if task, err := acceptanceTaskService.Acceptance(acceptanceTaskCommand.TaskId, acceptanceTaskCommand.Operator, acceptanceTaskCommand.Participators, acceptanceTaskCommand.TaskPercentage, acceptanceTaskCommand.SolveReport, acceptanceTaskCommand.SolvePictureUrls); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return task, nil
}
return nil, nil
}
// 搜索任务
... ...
package service
import "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain"
type AcceptanceTaskService interface {
Acceptance(taskId int64, operatorUid int64, participators []int64, taskPercentage []*domain.TaskPercentageItem, solveReport string, solvePictureUrls []string) (*domain.Task, error)
}
... ...
... ... @@ -2,6 +2,11 @@ package domain
import "time"
const (
SU_MONEY_TRANSACTION_RECORD_TYPE_EXCHANGE = iota + 1 //兑换
SU_MONEY_TRANSACTION_RECORD_TYPE_AWARD //任务奖励
)
// 素币事务记录
type SuMoneyTransactionRecord struct {
// 素币事务记录ID
... ... @@ -9,11 +14,11 @@ type SuMoneyTransactionRecord struct {
// 记录类型
RecordType int `json:"recordType"`
// 记录关联员工
Employee *EmployeeInfo `json:"employeeInfo"`
Employee *EmployeeInfo `json:"employee"`
// 事务素币值
SuMoney float64 `json:"suMoney"`
// 操作人
Operator int64 `json:"operator"`
Operator *EmployeeInfo `json:"operator"`
// 素币事务记录描述
RecordDescription string `json:"recordDescription"`
// 创建时间
... ... @@ -32,4 +37,4 @@ func (suMoneyTransactionRecord *SuMoneyTransactionRecord) Identify() interface{}
return nil
}
return suMoneyTransactionRecord.SuMoneyTransactionRecordId
}
\ No newline at end of file
}
... ...
... ... @@ -6,4 +6,6 @@ type TaskPercentageItem struct {
Contributor *EmployeeInfo `json:"contributor"`
// 任务贡献占比
Percentage int `json:"percentage"`
// 分配到的奖励素币
SuMoney float64 `json:"suMoney"`
}
... ...
package dao
import (
"fmt"
"github.com/go-pg/pg"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
)
type EmployeeDao struct {
transactionContext *pgTransaction.TransactionContext
}
func (dao *EmployeeDao) TransferSuMoney(uid int64, suMoney float64) error {
tx := dao.transactionContext.PgTx
_, err := tx.QueryOne(
pg.Scan(),
"UPDATE employees SET su_money=su_money+? WHERE uid=?",
suMoney, uid)
return err
}
func NewEmployeeDao(transactionContext *pgTransaction.TransactionContext) (*EmployeeDao, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &EmployeeDao{
transactionContext: transactionContext,
}, nil
}
}
... ...
package domain_service
import (
"fmt"
coreDomain "github.com/linmadan/egglib-go/core/domain"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain"
"gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/dao"
"gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/repository"
"time"
)
type AcceptanceTaskService struct {
coreDomain.BaseEventPublisher
transactionContext *pgTransaction.TransactionContext
}
func (service *AcceptanceTaskService) Acceptance(taskId int64, operatorUid int64, participators []int64, taskPercentage []*domain.TaskPercentageItem, solveReport string, solvePictureUrls []string) (*domain.Task, error) {
var employeeRepository domain.EmployeeRepository
var taskRepository domain.TaskRepository
var suMoneyTransactionRecordRepository domain.SuMoneyTransactionRecordRepository
var employeeDao *dao.EmployeeDao
if repository, err := repository.NewEmployeeRepository(service.transactionContext); err != nil {
return nil, err
} else {
employeeRepository = repository
}
if repository, err := repository.NewTaskRepository(service.transactionContext); err != nil {
return nil, err
} else {
taskRepository = repository
}
if repository, err := repository.NewSuMoneyTransactionRecordRepository(service.transactionContext); err != nil {
return nil, err
} else {
suMoneyTransactionRecordRepository = repository
}
if dao, err := dao.NewEmployeeDao(service.transactionContext); err != nil {
return nil, err
} else {
employeeDao = dao
}
operator, err := employeeRepository.FindOne(map[string]interface{}{
"uid": operatorUid,
})
if err != nil {
return nil, err
}
if operator == nil {
return nil, fmt.Errorf("无效的操作者")
}
task, err := taskRepository.FindOne(map[string]interface{}{
"taskId": taskId,
})
if err != nil {
return nil, err
}
if task == nil {
return nil, fmt.Errorf("无效的任务")
}
var participatorInfos []*domain.EmployeeInfo
for _, participatorUid := range participators {
if participator, err := employeeRepository.FindOne(map[string]interface{}{
"uid": participatorUid,
}); err != nil {
return nil, err
} else {
if participator == nil {
return nil, fmt.Errorf("无效的参与人")
}
participatorInfos = append(participatorInfos, participator.EmployeeInfo)
}
}
if err := task.Acceptance(participatorInfos, taskPercentage, solveReport, solvePictureUrls); err != nil {
return nil, err
}
for _, taskPercentageItem := range taskPercentage {
suMoneyTransactionRecord := &domain.SuMoneyTransactionRecord{
RecordType: domain.SU_MONEY_TRANSACTION_RECORD_TYPE_AWARD,
Employee: taskPercentageItem.Contributor,
SuMoney: taskPercentageItem.SuMoney,
Operator: operator.EmployeeInfo,
RecordDescription: fmt.Sprintf("完成[%s]任务奖励", task.TaskName),
CreateTime: time.Now(),
}
if _, err := suMoneyTransactionRecordRepository.Save(suMoneyTransactionRecord); err != nil {
return nil, err
}
if err := employeeDao.TransferSuMoney(taskPercentageItem.Contributor.Uid, task.SuMoney); err != nil {
return nil, err
}
}
if task, err := taskRepository.Save(task); err != nil {
return nil, err
} else {
return task, nil
}
}
func NewAcceptanceTaskService(transactionContext *pgTransaction.TransactionContext) (*AcceptanceTaskService, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &AcceptanceTaskService{
transactionContext: transactionContext,
}, nil
}
}
... ...
... ... @@ -16,7 +16,7 @@ type SuMoneyTransactionRecord struct {
// 事务素币值
SuMoney float64
// 操作人
Operator int64
Operator *domain.EmployeeInfo
// 素币事务记录描述
RecordDescription string
// 创建时间
... ...
... ... @@ -65,7 +65,7 @@ func (repository *EmployeeRepository) FindOne(queryOptions map[string]interface{
}
if err := query.First(); err != nil {
if err.Error() == "pg: no rows in result set" {
return nil, fmt.Errorf("没有此资源")
return nil, fmt.Errorf("没有此员工")
} else {
return nil, err
}
... ...
... ... @@ -13,16 +13,9 @@ type OffTaskRecordRepository struct {
transactionContext *pgTransaction.TransactionContext
}
func (repository *OffTaskRecordRepository) nextIdentify() (int64, error) {
return 0, nil
}
func (repository *OffTaskRecordRepository) Save(offTaskRecord *domain.OffTaskRecord) (*domain.OffTaskRecord, error) {
tx := repository.transactionContext.PgTx
if offTaskRecord.Identify() == nil {
_, err := repository.nextIdentify()
if err != nil {
return offTaskRecord, err
}
if _, err := tx.QueryOne(
pg.Scan(&offTaskRecord.OffTaskRecordId, &offTaskRecord.Task.TaskId, &offTaskRecord.Operator, &offTaskRecord.OffReason, &offTaskRecord.CreateTime),
"INSERT INTO off_task_records (task_id, operator, off_reason, create_time) VALUES (?, ?, ?, ?) RETURNING id, task_id, operator, off_reason, create_time",
... ... @@ -57,7 +50,7 @@ func (repository *OffTaskRecordRepository) FindOne(queryOptions map[string]inter
}
if err := query.First(); err != nil {
if err.Error() == "pg: no rows in result set" {
return nil, fmt.Errorf("没有此资源")
return nil, fmt.Errorf("没有此关闭任务记录")
} else {
return nil, err
}
... ...
... ... @@ -13,26 +13,19 @@ type SuMoneyTransactionRecordRepository struct {
transactionContext *pgTransaction.TransactionContext
}
func (repository *SuMoneyTransactionRecordRepository) nextIdentify() (int64, error) {
return 0, nil
}
func (repository *SuMoneyTransactionRecordRepository) Save(suMoneyTransactionRecord *domain.SuMoneyTransactionRecord) (*domain.SuMoneyTransactionRecord, error) {
tx := repository.transactionContext.PgTx
if suMoneyTransactionRecord.Identify() == nil {
_, err := repository.nextIdentify()
if err != nil {
return suMoneyTransactionRecord, err
}
if _, err := tx.QueryOne(
pg.Scan(&suMoneyTransactionRecord.SuMoneyTransactionRecordId, &suMoneyTransactionRecord.RecordType, &suMoneyTransactionRecord.Employee, &suMoneyTransactionRecord.SuMoney, &suMoneyTransactionRecord.Operator, &suMoneyTransactionRecord.RecordDescription, &suMoneyTransactionRecord.CreateTime),
"INSERT INTO su_money_transaction_records (id, record_type, employee, su_money, operator, record_description, create_time) VALUES (?, ?, ?, ?, ?, ?, ?) RETURNING su_money_transaction_record_id, record_type, employee, su_money, operator, record_description, create_time",
suMoneyTransactionRecord.SuMoneyTransactionRecordId, suMoneyTransactionRecord.RecordType, suMoneyTransactionRecord.Employee, suMoneyTransactionRecord.SuMoney, suMoneyTransactionRecord.Operator, suMoneyTransactionRecord.RecordDescription, suMoneyTransactionRecord.CreateTime); err != nil {
"INSERT INTO su_money_transaction_records (record_type, employee, su_money, operator, record_description, create_time) VALUES (?, ?, ?, ?, ?, ?) RETURNING id, record_type, employee, su_money, operator, record_description, create_time",
suMoneyTransactionRecord.RecordType, suMoneyTransactionRecord.Employee, suMoneyTransactionRecord.SuMoney, suMoneyTransactionRecord.Operator, suMoneyTransactionRecord.RecordDescription, suMoneyTransactionRecord.CreateTime); err != nil {
return suMoneyTransactionRecord, err
}
} else {
if _, err := tx.QueryOne(
pg.Scan(&suMoneyTransactionRecord.SuMoneyTransactionRecordId, &suMoneyTransactionRecord.RecordType, &suMoneyTransactionRecord.Employee, &suMoneyTransactionRecord.SuMoney, &suMoneyTransactionRecord.Operator, &suMoneyTransactionRecord.RecordDescription, &suMoneyTransactionRecord.CreateTime),
"UPDATE su_money_transaction_records SET record_type=?, employee=?, su_money=?, operator=?, record_description=?, create_time=? WHERE id=? RETURNING su_money_transaction_record_id, record_type, employee, su_money, operator, record_description, create_time",
"UPDATE su_money_transaction_records SET record_type=?, employee=?, su_money=?, operator=?, record_description=?, create_time=? WHERE id=? RETURNING id, record_type, employee, su_money, operator, record_description, create_time",
suMoneyTransactionRecord.RecordType, suMoneyTransactionRecord.Employee, suMoneyTransactionRecord.SuMoney, suMoneyTransactionRecord.Operator, suMoneyTransactionRecord.RecordDescription, suMoneyTransactionRecord.CreateTime, suMoneyTransactionRecord.SuMoneyTransactionRecordId); err != nil {
return suMoneyTransactionRecord, err
}
... ... @@ -57,7 +50,7 @@ func (repository *SuMoneyTransactionRecordRepository) FindOne(queryOptions map[s
}
if err := query.First(); err != nil {
if err.Error() == "pg: no rows in result set" {
return nil, fmt.Errorf("没有此资源")
return nil, fmt.Errorf("没有此素币事务记录")
} else {
return nil, err
}
... ...
... ... @@ -72,7 +72,7 @@ func (repository *TaskRepository) FindOne(queryOptions map[string]interface{}) (
}
if err := query.First(); err != nil {
if err.Error() == "pg: no rows in result set" {
return nil, fmt.Errorf("没有此资源")
return nil, fmt.Errorf("没有此任务")
} else {
return nil, err
}
... ...
package task
import (
"github.com/go-pg/pg"
"gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain"
"net/http"
"time"
"github.com/gavv/httpexpect"
"github.com/go-pg/pg"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/pg"
)
var _ = Describe("验收任务", func() {
var taskId int64
BeforeEach(func() {
_, err := pG.DB.QueryOne(
pg.Scan(&taskId),
"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",
"testTaskId", "testCompanyId", "testTaskName", "testTaskType", "testSponsor", "testTaskStatus", "testReferenceResource", "testCustomerValue", "testTaskNature", "testSuMoney", "testAcceptanceStandard", "testTaskDescription", "testTaskPictureUrls", "testIsRewardTake", "testRobInfo", "testBidInfo", "testParticipators", "testTaskPercentage", "testSolveReport", "testSolvePictureUrls", "testCreateTime", "testReleaseTime")
Expect(err).NotTo(HaveOccurred())
})
Describe("验收任务", func() {
Context("", func() {
It("", func() {
Context("操作人对待验收的任务进行验收", func() {
BeforeEach(func() {
dayAfter, _ := time.ParseDuration("72h")
_, err := pG.DB.QueryOne(
pg.Scan(),
"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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
1, 101, "抢单任务1", 1, &domain.EmployeeInfo{
Uid: 2499036607974745088,
}, 4, "null", pg.Array([]string{"口感", "便利", "品牌", "售后服务"}), "面", 1000.00, "验收标准1", "任务描述1", pg.Array([]string{}), true, "null", "null", "", pg.Array([]string{}), 2499036607974745099, time.Now(), time.Now().Add(dayAfter))
Expect(err).NotTo(HaveOccurred())
_, err1 := pG.DB.QueryOne(
pg.Scan(),
"INSERT INTO employees (id, company_id, uid, employee_name, employee_account, su_money) VALUES (?, ?, ?, ?, ?, ?)",
1, 101, 2499036607974745088, "testEmployeeName", "testEmployeeAccount", 0)
Expect(err1).NotTo(HaveOccurred())
_, err2 := pG.DB.QueryOne(
pg.Scan(),
"INSERT INTO employees (id, company_id, uid, employee_name, employee_account, su_money) VALUES (?, ?, ?, ?, ?, ?)",
2, 101, 2499036607974745099, "testEmployeeName", "testEmployeeAccount", 0)
Expect(err2).NotTo(HaveOccurred())
_, err3 := pG.DB.QueryOne(
pg.Scan(),
"INSERT INTO rob_infos (id, task_id ,receiver) VALUES (?, ?, ?)",
1, 1, &domain.EmployeeInfo{
Uid: 2499036607974745099,
})
Expect(err3).NotTo(HaveOccurred())
_, err4 := pG.DB.QueryOne(
pg.Scan(),
"INSERT INTO employees (id, company_id, uid, employee_name, employee_account, su_money) VALUES (?, ?, ?, ?, ?, ?)",
3, 101, 2499036607974745077, "testEmployeeName", "testEmployeeAccount", 0)
Expect(err4).NotTo(HaveOccurred())
_, err5 := pG.DB.QueryOne(
pg.Scan(),
"INSERT INTO employees (id, company_id, uid, employee_name, employee_account, su_money) VALUES (?, ?, ?, ?, ?, ?)",
4, 101, 2499036607974745066, "testEmployeeName", "testEmployeeAccount", 0)
Expect(err5).NotTo(HaveOccurred())
})
It("验收成功", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
body := map[string]interface{}{
"operator": "int64",
"participators": "array",
"taskPercentage": "array",
"solveReport": "string",
"solvePictureUrls": "array",
"operator": 2499036607974745077,
"participators": []int64{
2499036607974745077,
2499036607974745066,
},
"taskPercentage": []*domain.TaskPercentageItem{
{
Contributor: &domain.EmployeeInfo{
Uid: 2499036607974745099,
},
Percentage: 50,
SuMoney: 500.00,
},
{
Contributor: &domain.EmployeeInfo{
Uid: 2499036607974745077,
},
Percentage: 25,
SuMoney: 250.00,
},
{
Contributor: &domain.EmployeeInfo{
Uid: 2499036607974745066,
},
Percentage: 25,
SuMoney: 250.00,
},
},
"solveReport": "解决报告",
"solvePictureUrls": []string{
"url-1",
"url-2",
},
}
httpExpect.POST("/tasks/{taskId}/acceptance").
httpExpect.POST("/tasks/1/acceptance").
WithJSON(body).
Expect().
Status(http.StatusOK).
... ... @@ -38,12 +97,23 @@ var _ = Describe("验收任务", func() {
Object().
ContainsKey("code").ValueEqual("code", 0).
ContainsKey("msg").ValueEqual("msg", "ok").
ContainsKey("data").Value("data").Object()
ContainsKey("data").Value("data").Object().
ContainsKey("taskStatus").ValueEqual("taskStatus", 5)
})
})
})
AfterEach(func() {
_, err := pG.DB.Exec("DELETE FROM tasks WHERE true")
Expect(err).NotTo(HaveOccurred())
_, err1 := pG.DB.Exec("DELETE FROM bid_infos WHERE true")
Expect(err1).NotTo(HaveOccurred())
_, err2 := pG.DB.Exec("DELETE FROM bidder_infos WHERE true")
Expect(err2).NotTo(HaveOccurred())
_, err3 := pG.DB.Exec("DELETE FROM employees WHERE true")
Expect(err3).NotTo(HaveOccurred())
_, err4 := pG.DB.Exec("DELETE FROM rob_infos WHERE true")
Expect(err4).NotTo(HaveOccurred())
_, err5 := pG.DB.Exec("DELETE FROM su_money_transaction_records WHERE true")
Expect(err5).NotTo(HaveOccurred())
})
})
... ...