作者 唐旭辉

Merge branch 'dev' of http://gitlab.fjmaimaimai.com/mmm-go/partnermg into dev

正在显示 76 个修改的文件 包含 3549 行增加201 行删除

要显示太多修改。

为保证性能只显示 76 of 76+ 个文件。

# 服务端工作交接事项
## 合伙人管理后台项目
# 合伙人管理后台项目
### 代码以及文档
## 代码以及文档
- [代码地址](http://gitlab.fjmaimaimai.com/mmm-go/partnermg.git)
- [项目原型svn](svn://218.106.157.184/repo/项目文件/项目【合伙人】)
- [yapi-合伙人前端](http://47.97.5.102:36666/project/209/interface/api)
... ... @@ -15,7 +14,10 @@
服务端测试环境地址:http://mmm-partnermg-test.fjmaimaimai.com
服务端正式环境地址:https://public-interface.fjmaimaimai.com/mmm-partnermg
```
### 项目整体
## 系统架构图
![diagram](http://gitlab.fjmaimaimai.com/chenzhiying/img-folder/raw/master/diagram.png)
## 项目整体
- 项目使用框架
- http框架:beego
- orm框架:go-pg
... ... @@ -57,7 +59,56 @@
│ └─consumer kafka消息订阅
└─vendor
```
### 系统对接的外部数据
## 领域驱动设计-战略建模
### 领域
### 限界上下文
### 上下文映射
## 领域驱动设计-战术建模
### 实体
实发订单实体:OrderBase
栏目设置实体:ColumnSetting
合伙人实体:Partner
用户实体:User
公司实体:Company
管理员实体:AdminUser
### 值对象
### 聚合根
### 领域服务
### 领域事件
## 领域驱动设计工程实现
### 模块
### 领域对象
### 资源库
### 防腐层
### 领域服务
### 数据流转
![avatar](http://gitlab.fjmaimaimai.com/chenzhiying/img-folder/raw/master/dto.png)
### 上下文集成
### 分离领域
![avatar](http://gitlab.fjmaimaimai.com/chenzhiying/img-folder/raw/master/dispatch.png)
## 系统对接的外部数据
1. 外部数据来源,接收企业平台发送过来的数据。目前接收的是公司和员工的数据
主要内容在文件夹
... ... @@ -78,11 +129,43 @@
主要内容在
partnermg/pkg/infrastructure/serviceGateway
### 系统入口
## 系统入口
- [测试环境--企业平台网站地址](https://enterprise-platform-dev.fjmaimaimai.com)
- [开发环境--企业平台网站地址](https://enterprise-platform-local.fjmaimaimai.com)
- 天联共创后台自身没有独立的登录入口,需要经过企业平台进行跳转登录
## 标准产品组工具使用
- 设置全局变量(替换YOUR-USER-PATH为你真实的项目路径)
1.生成路径(项目生成路径):/YOUR-USER-PATH/GolandProjects/
2.eggs根目录路径(领域描述语言DSL文档路径生成或引用路径):/YOUR-USER-PATH/GolandProjects/partnermg/document/
3.egg名称(通常为项目名称,同样是DSL文件夹名称):partnermg
- 应用描述语言生成
1.应用描述语言egg脚手架生成
2.生成属性(Attribute)
3.生成模式(Schema)
4.生成服务(Service)
5.生成接口(Api)
- 具体工程生成
1.生成接口文档(OpenApi)
2.生成项目代码脚手架
3.生成领域模型
4.生成应用服务
5.生成Http协议接口
## 建议
1. vendor 目前作用是存放依赖,加快在容器中的构建速度。
... ...
... ... @@ -52,10 +52,12 @@ spec:
ports:
- containerPort: 8082
- containerPort: 443
volumeMounts:
- mountPath: /opt/logs
name: accesslogs
# volumeMounts:
# - mountPath: /opt/logs
# name: accesslogs
env:
- name: HTTP_PORT
value: "8082"
- name: POSTGRESQL_DB_NAME
value: "partner_dev"
- name: POSTGRESQL_USER
... ... @@ -92,6 +94,6 @@ spec:
value: "[partnermg_dev]"
- name: APP_NAME
value: ""
volumes:
- name: accesslogs
emptyDir: {}
# volumes:
# - name: accesslogs
# emptyDir: {}
... ...
... ... @@ -53,6 +53,8 @@ spec:
- mountPath: /opt/logs
name: accesslogs
env:
- name: HTTP_PORT
value: "8082"
- name: POSTGRESQL_DB_NAME
value: "partner"
- name: POSTGRESQL_USER
... ...
... ... @@ -49,10 +49,12 @@ spec:
ports:
- containerPort: 8082
- containerPort: 443
volumeMounts:
- mountPath: /opt/logs
name: accesslogs
# volumeMounts:
# - mountPath: /opt/logs
# name: accesslogs
env:
- name: HTTP_PORT
value: "8082"
- name: POSTGRESQL_DB_NAME
value: "partner_test"
- name: POSTGRESQL_USER
... ... @@ -89,6 +91,6 @@ spec:
value: "[partnermg_test]"
- name: APP_NAME
value: "partnermg"
volumes:
- name: accesslogs
emptyDir: {}
# volumes:
# - name: accesslogs
# emptyDir: {}
... ...
swagger: "2.0"
info:
title: ""
description: 合伙人后管平台
contact:
name: SteveChan
email: steve.d.chan@qq.com
home: ""
version: 0.0.1
consumes:
- application/json
- application/xml
produces:
- application/json
- application/xml
paths:
/column-settings:
get:
tags:
- column_setting
summary: 返回栏目设置增删改查列表
description: 返回栏目设置增删改查列表
operationId: column_setting#listColumnSetting
parameters:
- name: offset
in: query
description: 查询偏离量
required: false
type: integer
- name: limit
in: query
description: 查询限制
required: false
type: integer
responses:
"200":
description: OK response.
schema:
$ref: '#/definitions/ColumnSettingListColumnSettingResponseBody'
schemes:
- http
post:
tags:
- column_setting
summary: 重置栏目设置
description: 重置栏目设置
operationId: column_setting#resetColumn
responses:
"200":
description: OK response.
schema:
$ref: '#/definitions/ColumnSettingResetColumnResponseBody'
schemes:
- http
/column-settings/{columnSettingId}:
get:
tags:
- column_setting
summary: 返回栏目设置增删改查
description: 返回栏目设置增删改查
operationId: column_setting#getColumnSetting
parameters:
- name: columnSettingId
in: path
description: 栏目设置id
required: true
type: integer
responses:
"200":
description: OK response.
schema:
$ref: '#/definitions/ColumnSettingGetColumnSettingResponseBody'
schemes:
- http
put:
tags:
- column_setting
summary: 更新栏目设置增删改查
description: 更新栏目设置增删改查
operationId: column_setting#updateColumnSetting
parameters:
- name: columnSettingId
in: path
description: 栏目设置id
required: true
type: integer
responses:
"200":
description: OK response.
schema:
$ref: '#/definitions/ColumnSettingUpdateColumnSettingResponseBody'
schemes:
- http
delete:
tags:
- column_setting
summary: 移除栏目设置增删改查
description: 移除栏目设置增删改查
operationId: column_setting#removeColumnSetting
parameters:
- name: columnSettingId
in: path
description: 栏目设置id
required: true
type: integer
responses:
"200":
description: OK response.
schema:
$ref: '#/definitions/ColumnSettingRemoveColumnSettingResponseBody'
schemes:
- http
definitions:
ColumnSettingCreateColumnSettingRequestBody:
title: ColumnSettingCreateColumnSettingRequestBody
type: object
properties:
description:
type: string
description: 栏目设置描述
required:
- description
userName:
type: string
description: 栏目设置关联用户名称
required:
- userName
ColumnSettingCreateColumnSettingResponseBody:
title: 'Mediatype identifier: ColumnSettingCreateColumnSettingResponseBody'
type: object
properties:
column_setting:
$ref: '#/definitions/column_settingResponseBody'
ColumnSettingGetColumnSettingResponseBody:
title: 'Mediatype identifier: ColumnSettingGetColumnSettingResponseBody'
type: object
properties:
column_setting:
$ref: '#/definitions/column_settingResponseBody'
ColumnSettingListColumnSettingResponseBody:
title: 'Mediatype identifier: ColumnSettingListColumnSettingResponseBody'
type: object
properties:
column_setting:
$ref: '#/definitions/column_settingResponseBody'
count:
type: integer
description: 匹配数目
required:
- count
ColumnSettingRemoveColumnSettingResponseBody:
title: 'Mediatype identifier: ColumnSettingRemoveColumnSettingResponseBody'
type: object
properties:
column_setting:
$ref: '#/definitions/column_settingResponseBody'
ColumnSettingResetColumnResponseBody:
title: 'Mediatype identifier: ColumnSettingResetColumnResponseBody'
type: object
properties:
column_setting:
$ref: '#/definitions/column_settingResponseBody'
ColumnSettingUpdateColumnSettingResponseBody:
title: 'Mediatype identifier: ColumnSettingUpdateColumnSettingResponseBody'
type: object
properties:
column_setting:
$ref: '#/definitions/column_settingResponseBody'
column_settingResponseBody:
title: column_settingResponseBody
type: object
properties:
columnSettingId:
type: integer
description: 栏目设置id
required:
- columnSettingId
companyId:
type: integer
description: 栏目设置关联用户公司id
required:
- companyId
createdAt:
type: string
description: 栏目设置创建时间
required:
- createdAt
description:
type: string
description: 栏目设置描述
required:
- description
key:
type: string
description: 栏目设置模块名称
required:
- key
uid:
type: integer
description: 栏目设置关联用户uid
required:
- uid
updatedAt:
type: string
description: 栏目设置更新时间
required:
- updatedAt
userName:
type: string
description: 栏目设置关联用户名称
required:
- userName
value:
type: array
items:
$ref: '#/definitions/columnResponseBody'
description: 栏目数组
description: 栏目设置
columnResponseBody:
title: columnResponseBody
type: object
properties:
columnId:
type: string
description: 列标记
required:
- columnId
paramCn:
type: string
description: 列标记中文
required:
- paramCn
paramFix:
type: integer
description: 列标记是否固定,1:固定,2:不固定
required:
- paramFix
description: 栏目项
... ...
version: v1
kind: HttpApi
metadata:
service: column_setting
path: /column-settings
endpoints:
- method: createColumnSetting
route:
post: /
- method: updateColumnSetting
route:
put: /{columnSettingId}
- method: getColumnSetting
route:
get: /{columnSettingId}
- method: removeColumnSetting
route:
delete: /{columnSettingId}
- method: resetColumn
route:
post: /
- method: listColumnSetting
route:
get: /
params:
- name: offset
- name: limit
... ...
version: v1
kind: Attribute
metadata:
name: columnId
description: 列标记
type:
primitive: string
... ...
version: v1
kind: Attribute
metadata:
name: paramCn
description: 列标记中文
type:
primitive: string
... ...
version: v1
kind: Attribute
metadata:
name: paramFix
description: 列标记是否固定,1:固定,2:不固定
type:
primitive: int
... ...
version: v1
kind: Attribute
metadata:
name: columnSettingId
description: 栏目设置id
type:
primitive: int64
... ...
version: v1
kind: Attribute
metadata:
name: companyId
description: 栏目设置关联用户公司id
type:
primitive: int32
... ...
version: v1
kind: Attribute
metadata:
name: createdAt
description: 栏目设置创建时间
type:
primitive: datetime
... ...
version: v1
kind: Attribute
metadata:
name: description
description: 栏目设置描述
type:
primitive: string
... ...
version: v1
kind: Attribute
metadata:
name: invalidValue
description: 无效的栏目数组
type:
array: column
... ...
version: v1
kind: Attribute
metadata:
name: key
description: 栏目设置模块名称
type:
primitive: string
... ...
version: v1
kind: Attribute
metadata:
name: uid
description: 栏目设置关联用户uid
type:
primitive: int64
... ...
version: v1
kind: Attribute
metadata:
name: updatedAt
description: 栏目设置更新时间
type:
primitive: datetime
... ...
version: v1
kind: Attribute
metadata:
name: userName
description: 栏目设置关联用户名称
type:
primitive: string
\ No newline at end of file
... ...
version: v1
kind: Attribute
metadata:
name: value
description: 栏目值对象数组
type:
array: column
... ...
version: v1
kind: Attribute
metadata:
name: count
description: 匹配数目
type:
primitive: int64
... ...
version: v1
kind: Attribute
metadata:
name: limit
description: 查询限制
type:
primitive: int
... ...
version: v1
kind: Attribute
metadata:
name: offset
description: 查询偏离量
type:
primitive: int
... ...
version: v1
kind: Project
metadata:
name: project
description: 合伙人后管平台
version: 0.0.1
repository: gitlab.fjmaimaimai.com/mmm-go/partnermg
contact:
name: SteveChan
email: steve.d.chan@qq.com
\ No newline at end of file
... ...
version: v1
kind: Schema
metadata:
name: column
description: 栏目项
attributes:
- ref: columnId
required: true
- ref: paramCn
required: true
- ref: paramFix
required: true
\ No newline at end of file
... ...
version: v1
kind: Schema
metadata:
name: column_setting
description: 栏目设置
attributes:
- ref: columnSettingId
required: true
- ref: companyId
required: true
- ref: createdAt
required: true
- ref: description
required: true
- ref: key
required: true
- ref: uid
required: true
- ref: updatedAt
required: true
- ref: userName
required: true
- name: value
description: 栏目数组
type:
array: column
- name: invalidValue
description: 无效栏目数组
type:
array: column
... ...
version: v1
kind: Method
metadata:
name: createColumnSetting
type: command
description: 创建栏目设置增删改查
payload:
- ref: description
required: true
- ref: userName
required: true
result:
- name: column_setting
type:
schema: column_setting
... ...
version: v1
kind: Method
metadata:
name: getColumnSetting
type: query
description: 返回栏目设置增删改查
payload:
- ref: columnSettingId
required: true
result:
- name: column_setting
type:
schema: column_setting
... ...
version: v1
kind: Method
metadata:
name: listColumnSetting
type: query
description: 返回栏目设置增删改查列表
payload:
- ref: offset
required: true
- ref: limit
required: true
result:
- ref: count
required: true
- name: column_setting
type:
schema: column_setting
... ...
version: v1
kind: Method
metadata:
name: removeColumnSetting
type: command
description: 移除栏目设置增删改查
payload:
- ref: columnSettingId
required: true
result:
- name: column_setting
type:
schema: column_setting
... ...
version: v1
kind: Method
metadata:
name: resetColumn
type: command
description: 重置栏目设置
result:
- name: column_setting
type:
schema: column_setting
... ...
version: v1
kind: Method
metadata:
name: updateColumnSetting
type: command
description: 更新栏目设置增删改查
payload:
- ref: columnSettingId
required: true
result:
- name: column_setting
type:
schema: column_setting
... ...
version: v1
kind: Service
metadata:
name: column_setting
description: 栏目设置
... ...
... ... @@ -13,17 +13,17 @@ require (
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/gavv/httpexpect v2.0.0+incompatible
github.com/go-pg/pg v8.0.6+incompatible
github.com/go-pg/pg/v10 v10.7.3
github.com/google/go-querystring v1.0.0 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/imkira/go-interpol v1.1.0 // indirect
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect
github.com/linmadan/egglib-go v0.0.0-20191217144343-ca4539f95bf9
github.com/linmadan/egglib-go v0.0.0-20201125083542-25358a549edb
github.com/mattn/go-colorable v0.1.6 // indirect
github.com/moul/http2curl v1.0.0 // indirect
github.com/onsi/ginkgo v1.14.2
github.com/onsi/gomega v1.10.3
github.com/sclevine/agouti v3.0.0+incompatible // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/shopspring/decimal v1.2.0
github.com/smartystreets/goconvey v1.6.4 // indirect
... ...
package command
import (
"fmt"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
"github.com/astaxie/beego/validation"
)
type CreateColumnSettingCommand struct {
// 公司id
CompanyId int `json:"companyId"`
// 用户uid
Uid int64 `json:"uid"`
// 栏目设置描述
Description string `json:"description"`
// 栏目设置关联用户名称
UserName string `json:"userName"`
// 默认栏目设置
Value []domain.Column `json:"value"`
// 无效栏目设置爱
InvalidValue []domain.Column `json:"invalidValue"`
// 模块键值
Key string `json:"key"`
}
//func (createColumnSettingCommand *CreateColumnSettingCommand) Valid(validation *validation.Validation) {
// _ = validation.SetError("CustomValid", "未实现的自定义认证")
//}
func (createColumnSettingCommand *CreateColumnSettingCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(createColumnSettingCommand)
if err != nil {
return err
}
if !b {
for _, validErr := range valid.Errors {
return fmt.Errorf("%s %s", validErr.Key, validErr.Message)
}
}
return nil
}
... ...
package command
import (
"fmt"
"github.com/astaxie/beego/validation"
)
type RemoveColumnSettingCommand struct {
// 栏目设置id
ColumnSettingId int64 `json:"columnSettingId"`
// 用户uid
Uid int64 `json:"uid"`
// 公司id
CompanyId int `json:"companyId"`
}
//func (removeColumnSettingCommand *RemoveColumnSettingCommand) Valid(validation *validation.Validation) {
// validation.SetError("CustomValid", "未实现的自定义认证")
//}
func (removeColumnSettingCommand *RemoveColumnSettingCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(removeColumnSettingCommand)
if err != nil {
return err
}
if !b {
for _, validErr := range valid.Errors {
return fmt.Errorf("%s %s", validErr.Key, validErr.Message)
}
}
return nil
}
... ...
package command
import (
"fmt"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
"github.com/astaxie/beego/validation"
)
type ResetColumnCommand struct {
// 公司id
CompanyId int `json:"companyId"`
// 用户uid
Uid int64 `json:"uid"`
// 默认栏目
Value []domain.Column `json:"value"`
// 默认无效栏目
InvalidValue []domain.Column `json:"invalidValue"`
}
//func (resetColumnCommand *ResetColumnCommand) Valid(validation *validation.Validation) {
// _ = validation.SetError("CustomValid", "未实现的自定义认证")
//}
func (resetColumnCommand *ResetColumnCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(resetColumnCommand)
if err != nil {
return err
}
if !b {
for _, validErr := range valid.Errors {
return fmt.Errorf("%s %s", validErr.Key, validErr.Message)
}
}
return nil
}
... ...
package command
import (
"fmt"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
"github.com/astaxie/beego/validation"
)
type UpdateColumnSettingCommand struct {
// 栏目设置id
ColumnSettingId int64 `json:"columnSettingId"`
// 公司id
CompanyId int `json:"companyId"`
// 用户uid
Uid int64 `json:"uid"`
// 选中的栏目
Selected []domain.Column `json:"selected"`
// 未选中的栏目
UnSelected []domain.Column `json:"unselected"`
// 栏目设置
Value []domain.Column `json:"value"`
// 无效栏目设置
InvalidValue []domain.Column `json:"invalidValue"`
// 栏目
OrderBaseColumns OrderBaseColumns `json:"orderBaseColumns"`
}
type OrderBaseColumns struct {
// 选中的栏目
Selected []domain.Column `json:"selected"`
// 未选中的栏目
UnSelected []domain.Column `json:"unselected"`
}
//func (updateColumnSettingCommand *UpdateColumnSettingCommand) Valid(validation *validation.Validation) {
// _ = validation.SetError("CustomValid", "未实现的自定义认证")
//}
func (updateColumnSettingCommand *UpdateColumnSettingCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(updateColumnSettingCommand)
if err != nil {
return err
}
if !b {
for _, validErr := range valid.Errors {
return fmt.Errorf("%s %s", validErr.Key, validErr.Message)
}
}
return nil
}
... ...
package query
import (
"fmt"
"github.com/astaxie/beego/validation"
)
type GetColumnSettingQuery struct {
// 栏目设置id
ColumnSettingId int64 `json:"columnSettingId"`
// 公司id
CompanyId int `json:"companyId"`
// 用户uid
Uid int64 `json:"uid"`
}
//func (getColumnSettingQuery *GetColumnSettingQuery) Valid(validation *validation.Validation) {
// _ = validation.SetError("CustomValid", "未实现的自定义认证")
//}
func (getColumnSettingQuery *GetColumnSettingQuery) ValidateQuery() error {
valid := validation.Validation{}
b, err := valid.Valid(getColumnSettingQuery)
if err != nil {
return err
}
if !b {
for _, validErr := range valid.Errors {
return fmt.Errorf("%s %s", validErr.Key, validErr.Message)
}
}
return nil
}
... ...
package query
import (
"fmt"
"github.com/astaxie/beego/validation"
)
type ListColumnSettingQuery struct {
// 查询偏离量
Offset int `json:"offset" valid:"Required"`
// 查询限制
Limit int `json:"limit" valid:"Required"`
}
//func (listColumnSettingQuery *ListColumnSettingQuery) Valid(validation *validation.Validation) {
// _ = validation.SetError("CustomValid", "未实现的自定义认证")
//}
func (listColumnSettingQuery *ListColumnSettingQuery) ValidateQuery() error {
valid := validation.Validation{}
b, err := valid.Valid(listColumnSettingQuery)
if err != nil {
return err
}
if !b {
for _, validErr := range valid.Errors {
return fmt.Errorf("%s %s", validErr.Key, validErr.Message)
}
}
return nil
}
... ...
package service
import (
"fmt"
"github.com/linmadan/egglib-go/core/application"
"github.com/linmadan/egglib-go/utils/tool_funs"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/columnSetting/command"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/columnSetting/query"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/factory"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/constant"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
"strconv"
"time"
)
// 栏目设置
type ColumnSettingService struct {
}
/**
* @Author SteveChan
* @Description //新增用户时,初始化栏目设置
* @Date 23:13 2021/1/26
* @Param
* @return
**/
func (columnSettingService *ColumnSettingService) CreateColumnSetting(createColumnSettingCommand *command.CreateColumnSettingCommand) (interface{}, error) {
if err := createColumnSettingCommand.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if errStart := transactionContext.StartTransaction(); errStart != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, errStart.Error())
}
defer func() {
_ = transactionContext.RollbackTransaction()
}()
newColumnSetting := &domain.ColumnSetting{
Description: createColumnSettingCommand.Description,
UserName: createColumnSettingCommand.UserName,
CompanyId: createColumnSettingCommand.CompanyId,
Uid: createColumnSettingCommand.Uid,
Key: constant.ORDER_BASE, // 订单栏目模块名称
Value: domain.DefaultColumns, // 栏目值数组,创建用户时使用默认栏目设置
InvalidValue: domain.DefaultInvalidColumns, // 初始化无效栏目数组
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
var columnSettingRepository domain.ColumnSettingRepository
if value, errFac := factory.CreateColumnSettingRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); errFac != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, errFac.Error())
} else {
columnSettingRepository = value
}
if columnSettingSaved, errSaved := columnSettingRepository.Save(newColumnSetting); errSaved != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, errSaved.Error())
} else {
if errCommit := transactionContext.CommitTransaction(); errCommit != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, errCommit.Error())
}
return columnSettingSaved, nil
}
}
/**
* @Author SteveChan
* @Description // 返回栏目设置
* @Date 23:14 2021/1/26
* @Param
* @return
**/
func (columnSettingService *ColumnSettingService) GetColumnSetting(getColumnSettingQuery *query.GetColumnSettingQuery) (interface{}, error) {
if err := getColumnSettingQuery.ValidateQuery(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
_ = transactionContext.RollbackTransaction()
}()
var columnSettingRepository domain.ColumnSettingRepository
if value, errFact := factory.CreateColumnSettingRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); errFact != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, errFact.Error())
} else {
columnSettingRepository = value
}
columnSettingFound, err := columnSettingRepository.FindOne(map[string]interface{}{"uid": getColumnSettingQuery.Uid, "companyId": getColumnSettingQuery.CompanyId})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if columnSettingFound == nil {
return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", strconv.FormatInt(getColumnSettingQuery.Uid, 10)))
} else {
if errCommit := transactionContext.CommitTransaction(); errCommit != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, errCommit.Error())
}
// 数据mapper
orderBaseColumns := map[string]interface{}{
"orderBaseColumns": map[string]interface{}{
"selected": columnSettingFound.Value,
"unselected": columnSettingFound.InvalidValue,
},
}
return orderBaseColumns, nil
}
}
// 返回栏目设置增删改查列表
func (columnSettingService *ColumnSettingService) ListColumnSetting(listColumnSettingQuery *query.ListColumnSettingQuery) (interface{}, error) {
if err := listColumnSettingQuery.ValidateQuery(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
var columnSettingRepository domain.ColumnSettingRepository
if value, err := factory.CreateColumnSettingRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
columnSettingRepository = value
}
if count, columnSettings, err := columnSettingRepository.Find(tool_funs.SimpleStructToMap(listColumnSettingQuery)); 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 map[string]interface{}{
"count": count,
"column_settings": columnSettings,
}, nil
}
}
/**
* @Author SteveChan
* @Description // 删除用户时移除栏目设置
* @Date 23:14 2021/1/26
* @Param
* @return
**/
func (columnSettingService *ColumnSettingService) RemoveColumnSetting(removeColumnSettingCommand *command.RemoveColumnSettingCommand) (interface{}, error) {
if err := removeColumnSettingCommand.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if errSt := transactionContext.StartTransaction(); errSt != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, errSt.Error())
}
defer func() {
_ = transactionContext.RollbackTransaction()
}()
var columnSettingRepository domain.ColumnSettingRepository
if value, errFac := factory.CreateColumnSettingRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); errFac != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, errFac.Error())
} else {
columnSettingRepository = value
}
columnSettingFound, err := columnSettingRepository.FindOne(map[string]interface{}{"uid": removeColumnSettingCommand.Uid, "companyId": removeColumnSettingCommand.CompanyId})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if columnSettingFound == nil {
return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", strconv.FormatInt(removeColumnSettingCommand.Uid, 10)))
}
if columnSettingRemoved, _, errRm := columnSettingRepository.Remove(columnSettingFound, nil); errRm != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, errRm.Error())
} else {
if errTr := transactionContext.CommitTransaction(); errTr != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, errRm.Error())
}
// 数据mapper
orderBaseColumns := map[string]interface{}{
"orderBaseColumns": map[string]interface{}{
"selected": columnSettingRemoved.Value,
"unselected": columnSettingRemoved.InvalidValue,
},
}
return orderBaseColumns, nil
}
}
/**
* @Author SteveChan
* @Description // 重置栏目设置
* @Date 23:15 2021/1/26
* @Param
* @return
**/
func (columnSettingService *ColumnSettingService) ResetColumn(resetColumnCommand *command.ResetColumnCommand) (interface{}, error) {
if err := resetColumnCommand.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if errStart := transactionContext.StartTransaction(); errStart != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, errStart.Error())
}
defer func() {
_ = transactionContext.RollbackTransaction()
}()
var columnSettingRepository domain.ColumnSettingRepository
if value, errFact := factory.CreateColumnSettingRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); errFact != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, errFact.Error())
} else {
columnSettingRepository = value
}
columnSettingFound, err := columnSettingRepository.FindOne(map[string]interface{}{"uid": resetColumnCommand.Uid, "companyId": resetColumnCommand.CompanyId})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if columnSettingFound == nil {
return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", strconv.FormatInt(resetColumnCommand.Uid, 10)))
}
if errUpdated := columnSettingFound.Update(tool_funs.SimpleStructToMap(resetColumnCommand)); errUpdated != nil {
return nil, application.ThrowError(application.BUSINESS_ERROR, errUpdated.Error())
}
if columnSettingSaved, errSaved := columnSettingRepository.Save(columnSettingFound); errSaved != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, errSaved.Error())
} else {
if errCommit := transactionContext.CommitTransaction(); errCommit != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, errCommit.Error())
}
// 数据mapper
orderBaseColumns := map[string]interface{}{
"orderBaseColumns": map[string]interface{}{
"selected": columnSettingSaved.Value,
"unselected": columnSettingSaved.InvalidValue,
},
}
return orderBaseColumns, nil
}
}
/**
* @Author SteveChan
* @Description // 更新栏目设置
* @Date 23:15 2021/1/26
* @Param
* @return
**/
func (columnSettingService *ColumnSettingService) UpdateColumnSetting(updateColumnSettingCommand *command.UpdateColumnSettingCommand) (interface{}, error) {
if err := updateColumnSettingCommand.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if errStart := transactionContext.StartTransaction(); errStart != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, errStart.Error())
}
defer func() {
_ = transactionContext.RollbackTransaction()
}()
var columnSettingRepository domain.ColumnSettingRepository
if value, errFact := factory.CreateColumnSettingRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); errFact != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, errFact.Error())
} else {
columnSettingRepository = value
}
updateColumnSettingCommand.Value = updateColumnSettingCommand.Selected
updateColumnSettingCommand.InvalidValue = updateColumnSettingCommand.UnSelected
columnSetting, err := columnSettingRepository.FindOne(map[string]interface{}{"uid": updateColumnSettingCommand.Uid, "companyId": updateColumnSettingCommand.CompanyId})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if columnSetting == nil {
return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", strconv.FormatInt(updateColumnSettingCommand.Uid, 10)))
}
if errUpdated := columnSetting.Update(tool_funs.SimpleStructToMap(updateColumnSettingCommand)); errUpdated != nil {
return nil, application.ThrowError(application.BUSINESS_ERROR, errUpdated.Error())
}
if columnSettingSaved, errSaved := columnSettingRepository.Save(columnSetting); errSaved != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, errSaved.Error())
} else {
if errCommit := transactionContext.CommitTransaction(); errCommit != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, errCommit.Error())
}
// 数据mapper
orderBaseColumns := map[string]interface{}{
"orderBaseColumns": map[string]interface{}{
"selected": columnSettingSaved.Value,
"unselected": columnSettingSaved.InvalidValue,
},
}
return orderBaseColumns, nil
}
}
func NewColumnSettingService(options map[string]interface{}) *ColumnSettingService {
newColumnSettingService := &ColumnSettingService{}
return newColumnSettingService
}
... ...
... ... @@ -104,3 +104,11 @@ func CreateOrderLogRepository(options map[string]interface{}) (domain.OrderLogRe
}
return repository.NewOrderLogRepository(transactionContext)
}
func CreateColumnSettingRepository(options map[string]interface{}) (domain.ColumnSettingRepository, error) {
var transactionContext *transaction.TransactionContext
if value, ok := options["transactionContext"]; ok {
transactionContext = value.(*transaction.TransactionContext)
}
return repository.NewColumnSettingRepository(transactionContext)
}
... ...
package command
import "errors"
import (
"errors"
"time"
)
//创建订单
type CreateOrderCommand struct {
... ... @@ -32,6 +35,8 @@ type CreateOrderCommand struct {
Code string `json:"code"`
//合伙人类型名称-错误信息返回
PartnerCategoryName string `json:"partnerCategoryName"`
//销售日期
SaleDate time.Time `json:"saleDate"`
}
func (postData *CreateOrderCommand) Valid() error {
... ...
package command
import "time"
//UpdateOrderPurposeCommand 更新订单单
type UpdateOrderCommand struct {
Id int64 `json:"id"`
... ... @@ -21,6 +23,8 @@ type UpdateOrderCommand struct {
Goods []OrderGoodData `json:"goods"`
//公司id
CompanyId int64 `json:"companyId"`
// 合伙人类型
//合伙人类型
PartnerCategory int64 `json:"partner_category"`
//销售日期
SaleDate time.Time `json:"saleDate"`
}
... ...
... ... @@ -8,7 +8,7 @@ package query
/**
* @Author SteveChan
* @Description //TODO 查询合伙人id
* @Description // 查询合伙人id
* @Date 23:18 2021/1/6
**/
type GetPartnerIdQuery struct {
... ...
... ... @@ -8,7 +8,7 @@ package query
/**
* @Author SteveChan
* @Description //TODO 查询产品id
* @Description //查询产品id
* @Date 23:18 2021/1/6
**/
type GetProductIdQuery struct {
... ...
... ... @@ -16,10 +16,14 @@ type ListOrderBaseQuery struct {
DeliveryCode string `json:"deliveryCode"`
//公司id
CompanyId int64 `json:"companyId"`
//用户uid
Uid int64 `json:"uid"`
//订单类型
OrderType int `json:"orderType"`
//合伙人分类
PartnerCategory int `json:"partnerCategory"`
//合伙人类型名称
PartnerCategoryName string `json:"partnerCategoryName"`
//更新时间开始
UpdateTimeBegin string `json:"updateTimeBegin"`
//更新时间截止
... ... @@ -28,4 +32,8 @@ type ListOrderBaseQuery struct {
CreateTimeBegin string `json:"createTimeBegin"`
//创建时间截止
CreateTimeEnd string `json:"createTimeEnd"`
//销售时间开始
SaleDateBegin string `json:"saleDateBegin"`
//销售时间结束
SaleDateEnd string `json:"sateDateEnd"`
}
... ...
/**
@author: stevechan
@date: 2021/1/27
@note:
**/
package query
type ListOrderForExcelQuery struct {
Type string `json:"type"` // 操作类型 ORDER_BASE
Where Where `json:"where"` // 导出条件
IDS []int `json:"ids"` // 勾选id
}
type Where struct {
PartnerName string `json:"partnerName"` // 合伙人姓名
OrderCode string `json:"orderCode"` // 订单号
DeliveryCode string `json:"deliveryCode"` // 发货单号
PartnerCategory int `json:"partnerCategory"` // 合伙人类型
PartnerCategoryName string `json:"partnerCategoryName"` // 合伙人类型名称
UpdateTime []string `json:"updateTime"` // 更新时间
CreateTime []string `json:"createTime"` // 创建时间
SaleDate []string `json:"saleDate"` // 销售日期
}
... ...
... ... @@ -2,6 +2,9 @@ package service
import (
"fmt"
"github.com/linmadan/egglib-go/core/application"
"strconv"
"time"
"github.com/astaxie/beego/logs"
... ... @@ -62,9 +65,11 @@ func (service OrderInfoService) PageListOrderBase(listOrderQuery query.ListOrder
listOrderQuery.PartnerName, // 合伙人姓名
listOrderQuery.OrderCode, // 订单号
listOrderQuery.DeliveryCode, // 发货单号
[2]string{listOrderQuery.UpdateTimeBegin, listOrderQuery.UpdateTimeEnd},
[2]string{listOrderQuery.CreateTimeBegin, listOrderQuery.CreateTimeEnd},
[2]string{listOrderQuery.UpdateTimeBegin, listOrderQuery.UpdateTimeEnd}, // 订单创建时间
[2]string{listOrderQuery.CreateTimeBegin, listOrderQuery.CreateTimeEnd}, // 订单更新时间
[2]string{listOrderQuery.SaleDateBegin, listOrderQuery.SaleDateEnd}, // 销售日期
listOrderQuery.PartnerCategory,
listOrderQuery.PartnerCategoryName,
listOrderQuery.Limit, listOrderQuery.Offset,
)
if err != nil {
... ... @@ -94,6 +99,7 @@ func (service OrderInfoService) PageListOrderBase(listOrderQuery query.ListOrder
"index": listIndex,
"createTime": orders[i].CreateTime.Local().Format("2006-01-02 15:04:05"),
"updateTime": orders[i].UpdateTime.Local().Format("2006-01-02 15:04:05"),
"saleDate": orders[i].SaleDate.Local().Format("2006-01-02 15:04:05"),
"buyer": orders[i].Buyer.BuyerName,
"id": fmt.Sprint(orders[i].Id),
"orderId": orders[i].OrderCode,
... ... @@ -188,7 +194,13 @@ func (service OrderInfoService) GetOrderDetail(getOrderQuery query.GetOrderQuery
return order, nil
}
//CreateNewOrder 创建订单
/**
* @Author SteveChan
* @Description // 创建订单,增加销售日期
* @Date 11:57 2021/1/26
* @Param
* @return
**/
func (service OrderInfoService) CreateNewOrder(cmd command.CreateOrderCommand) (*domain.OrderBase, error) {
var (
transactionContext, _ = factory.CreateTransactionContext(nil)
... ... @@ -255,7 +267,8 @@ func (service OrderInfoService) CreateNewOrder(cmd command.CreateOrderCommand) (
goodMap[goodname] = 1
}
newOrder := &domain.OrderBase{
OrderType: cmd.OrderType, OrderCode: cmd.OrderCode,
OrderType: cmd.OrderType,
OrderCode: cmd.OrderCode,
DeliveryCode: cmd.DeliveryCode,
Buyer: domain.Buyer{
BuyerName: cmd.BuyerName,
... ... @@ -263,6 +276,7 @@ func (service OrderInfoService) CreateNewOrder(cmd command.CreateOrderCommand) (
RegionInfo: domain.RegionInfo{
RegionName: cmd.OrderRegion,
},
SaleDate: cmd.SaleDate,
PartnerId: cmd.PartnerId,
PartnerInfo: partnerData.Partner,
SalesmanBonusPercent: cmd.SalesmanBonusPercent,
... ... @@ -277,15 +291,15 @@ func (service OrderInfoService) CreateNewOrder(cmd command.CreateOrderCommand) (
var cmdPartnerCategoryOk bool
for _, v := range partnerData.PartnerCategoryInfos {
if v.Id == cmd.PartnerCategory {
_, categorys, err := categoryRepository.Find(domain.PartnerCategoryFindQuery{
_, categories, err := categoryRepository.Find(domain.PartnerCategoryFindQuery{
Ids: []int64{v.Id},
})
if err != nil {
e := fmt.Sprintf("获取合伙人分类数据失败:%s", err)
return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
}
if len(categorys) > 0 {
newOrder.PartnerCategory = categorys[0]
if len(categories) > 0 {
newOrder.PartnerCategory = categories[0]
cmdPartnerCategoryOk = true
}
break
... ... @@ -393,6 +407,28 @@ func (service OrderInfoService) UpdateOrderData(cmd command.UpdateOrderCommand)
transactionContext.RollbackTransaction()
}()
// 获取合伙人类型
var PartnerCategoryRepository domain.PartnerCategoryRepository
if PartnerCategoryRepository, err = factory.CreatePartnerCategoryRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); err != nil {
return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
}
var partnerCategories []domain.PartnerCategory
_, partnerCategories, err = PartnerCategoryRepository.Find(domain.PartnerCategoryFindQuery{
Ids: []int64{},
})
if err != nil {
return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("检索合伙人类型数据失败"))
}
partnerCategoryMap := map[int64]interface{}{}
if len(partnerCategories) > 0 {
for _, partnerCategory := range partnerCategories {
partnerCategoryMap[partnerCategory.Id] = partnerCategory.Name
}
}
// 获取合伙人数据
var PartnerInfoRepository domain.PartnerInfoRepository
if PartnerInfoRepository, err = factory.CreatePartnerInfoRepository(map[string]interface{}{
"transactionContext": transactionContext,
... ... @@ -500,6 +536,7 @@ func (service OrderInfoService) UpdateOrderData(cmd command.UpdateOrderCommand)
var cmdPartnerCategoryOk bool
for _, v := range partnerData.PartnerCategoryInfos {
if v.Id == cmd.PartnerCategory {
v.Name = partnerCategoryMap[v.Id].(string)
oldOrderData.PartnerCategory = v
cmdPartnerCategoryOk = true
}
... ... @@ -511,6 +548,7 @@ func (service OrderInfoService) UpdateOrderData(cmd command.UpdateOrderCommand)
oldOrderData.DeliveryCode = cmd.DeliveryCode
oldOrderData.Buyer.BuyerName = cmd.BuyerName
oldOrderData.RegionInfo.RegionName = cmd.OrderRegion
oldOrderData.SaleDate = cmd.SaleDate
oldOrderData.PartnerId = cmd.PartnerId
oldOrderData.PartnerInfo = partnerData.Partner
oldOrderData.SalesmanBonusPercent = cmd.SalesmanBonusPercent
... ... @@ -519,7 +557,6 @@ func (service OrderInfoService) UpdateOrderData(cmd command.UpdateOrderCommand)
if err != nil {
return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("核算订单中合计的数值失败:%s", err))
}
err = orderBaseRepository.Save(oldOrderData)
if err != nil {
return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("保存订单数据失败:%s", err))
... ... @@ -883,7 +920,7 @@ func (service OrderInfoService) ListOrderBonusForExcel(listOrderQuery query.List
/**
* @Author SteveChan
* @Description // 导出订单数据
* @Description //根据栏目设置,导出订单数据
* @Date 22:05 2021/1/10
* @Param
* @return
... ... @@ -897,7 +934,7 @@ func (service OrderInfoService) ListOrderForExcel(listOrderQuery query.ListOrder
return nil, nil, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
_ = transactionContext.RollbackTransaction()
}()
var (
... ... @@ -916,61 +953,105 @@ func (service OrderInfoService) ListOrderForExcel(listOrderQuery query.ListOrder
listOrderQuery.DeliveryCode, // 发货单号
[2]string{listOrderQuery.UpdateTimeBegin, listOrderQuery.UpdateTimeEnd},
[2]string{listOrderQuery.CreateTimeBegin, listOrderQuery.CreateTimeEnd},
[2]string{listOrderQuery.SaleDateBegin, listOrderQuery.SaleDateEnd},
listOrderQuery.PartnerCategory,
listOrderQuery.PartnerCategoryName,
)
if err != nil {
return nil, nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
}
// 获取栏目设置
var columnSettingRepository domain.ColumnSettingRepository
if value, errFact := factory.CreateColumnSettingRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); errFact != nil {
return nil, nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
} else {
columnSettingRepository = value
}
columnSettingFound, err := columnSettingRepository.FindOne(map[string]interface{}{"uid": listOrderQuery.Uid, "companyId": listOrderQuery.CompanyId})
if err != nil {
return nil, nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
}
if columnSettingFound == nil {
return nil, nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", strconv.FormatInt(listOrderQuery.Uid, 10)))
}
err = transactionContext.CommitTransaction()
if err != nil {
return nil, nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
}
var resultMaps []map[string]string
for i := range ordersData {
t, _ := time.ParseInLocation("2006-01-02 15:04:05", ordersData[i].SaleDate, time.Local)
m := map[string]string{
"num": fmt.Sprint(i + 1),
"order_code": ordersData[i].OrderCode,
"delivery_code": ordersData[i].DeliveryCode,
"partner_name": ordersData[i].PartnerName,
"update_time": ordersData[i].UpdateTime,
"create_time": ordersData[i].CreateTime,
"plan_order_count": fmt.Sprint(ordersData[i].PlanOrderCount),
"use_order_count": "",
"region_name": fmt.Sprint(ordersData[i].RegionName),
"plan_order_amount": fmt.Sprintf("%10.2f", ordersData[i].PlanOrderAmount),
"use_order_amount": "",
"partner_category": ordersData[i].PartnerCategory,
"buyer_name": ordersData[i].BuyerName,
//"num": fmt.Sprint(i + 1),
//"order_code": ordersData[i].OrderCode,
//"delivery_code": ordersData[i].DeliveryCode,
//"partner_name": ordersData[i].PartnerName,
//"update_time": ordersData[i].UpdateTime,
//"create_time": ordersData[i].CreateTime,
//"sale_date": ordersData[i].SaleDate,
//"plan_order_count": fmt.Sprint(ordersData[i].PlanOrderCount),
//"use_order_count": "",
//"region_name": fmt.Sprint(ordersData[i].RegionName),
//"plan_order_amount": fmt.Sprintf("%10.2f", ordersData[i].PlanOrderAmount),
//"use_order_amount": "",
//"partner_category": ordersData[i].PartnerCategory,
//"buyer_name": ordersData[i].BuyerName,
"index": fmt.Sprint(i + 1),
"orderId": ordersData[i].OrderCode,
"shipmentsId": ordersData[i].DeliveryCode,
"partner": ordersData[i].PartnerName,
"update_time": ordersData[i].UpdateTime,
"create_time": ordersData[i].CreateTime,
"saleDate": t.Format("2006-01-02"),
"orderNum": fmt.Sprint(ordersData[i].PlanOrderCount),
"quantityControl": "",
"orderDist": fmt.Sprint(ordersData[i].RegionName),
"orderPrice": fmt.Sprintf("%10.2f", ordersData[i].PlanOrderAmount),
"priceControl": "",
"partnerCategory": ordersData[i].PartnerCategory,
"buyer": ordersData[i].BuyerName,
}
if ordersData[i].UseOrderCount >= 0 {
m["use_order_count"] = fmt.Sprint(ordersData[i].UseOrderCount)
m["quantityControl"] = fmt.Sprint(ordersData[i].UseOrderCount)
}
if ordersData[i].UseOrderAmount >= 0 {
m["use_order_amount"] = fmt.Sprintf("%10.2f", ordersData[i].UseOrderAmount)
m["priceControl"] = fmt.Sprintf("%10.2f", ordersData[i].UseOrderAmount)
}
resultMaps = append(resultMaps, m)
}
column := [][2]string{
[2]string{"num", "序号"},
[2]string{"order_code", "订单号"},
[2]string{"delivery_code", "发货单号"},
[2]string{"create_time", "创建时间"},
[2]string{"update_time", "更新时间"},
[2]string{"plan_order_count", "订单数量"},
[2]string{"use_order_count", "数量调整"},
[2]string{"plan_order_amount", "订单金额"},
[2]string{"use_order_amount", "金额调整"},
[2]string{"region_name", "订单区域"},
[2]string{"partner_category", "合伙人类型"},
[2]string{"buyer_name", "客户"},
[2]string{"partner_name", "合伙人"},
//column := [][2]string{
// [2]string{"num", "序号"},
// [2]string{"order_code", "订单号"},
// [2]string{"delivery_code", "发货单号"},
// [2]string{"create_time", "创建时间"},
// [2]string{"update_time", "更新时间"},
// [2]string{"sale_date", "销售时间"},
// [2]string{"plan_order_count", "订单数量"},
// [2]string{"use_order_count", "数量调整"},
// [2]string{"plan_order_amount", "订单金额"},
// [2]string{"use_order_amount", "金额调整"},
// [2]string{"region_name", "订单区域"},
// [2]string{"partner_category", "合伙人类型"},
// [2]string{"buyer_name", "客户"},
// [2]string{"partner_name", "合伙人"},
//}
var column [][2]string
for _, columnValue := range columnSettingFound.Value {
column = append(column, [2]string{columnValue.Id, columnValue.ParamCn})
}
return resultMaps, column, nil
}
/**
* @Author SteveChan
* @Description //TODO 批量导入创建订单
* @Description // 批量导入创建订单,增加销售时间
* @Date 11:00 2021/1/7
* @Param
* @return
... ... @@ -1122,6 +1203,7 @@ func (service OrderInfoService) CreateNewOrderByImport(createOrderCommands []*co
PartnerInfo: partnerData.Partner,
SalesmanBonusPercent: cmd.SalesmanBonusPercent,
CompanyId: cmd.CompanyId,
SaleDate: cmd.SaleDate,
}
// 批量校验合伙人分类数据
... ...
... ... @@ -85,6 +85,13 @@ func (s SyncOrderService) SyncOrderFromBestshop(cmd command.CreateOrderFromBests
return err
}
/**
* @Author SteveChan
* @Description //同步小程序订单,增加销售时间
* @Date 23:53 2021/1/26
* @Param
* @return
**/
func (s SyncOrderService) CreateOrderFromBestshop(cmd command.CreateOrderFromBestshop) error {
var (
transactionContext, _ = factory.CreateTransactionContext(nil)
... ... @@ -258,6 +265,8 @@ func (s SyncOrderService) copyOrderBestshopToOrderBase(orderBestshop *domain.Ord
// 默认设定为事业合伙人订单
orderbase.PartnerCategory = domain.PartnerCategory{Id: 1, Name: "事业合伙人"}
orderbase.Compute()
// 销售日期
//orderbase.SaleDate = orderBestshop.CreateTime
err = orderBaseRepository.Save(&orderbase)
if err != nil {
e := fmt.Sprintf("添加order_base数据失败%s", err)
... ...
... ... @@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/constant"
"time"
"github.com/astaxie/beego/logs"
... ... @@ -85,6 +86,13 @@ func NewSyncEmployeeService(option map[string]interface{}) *SyncEmployeeService
var _ SyncAction = (*SyncEmployeeService)(nil)
/**
* @Author SteveChan
* @Description //TODO 新增、导入用户初始化栏目设置
* @Date 23:54 2021/1/26
* @Param
* @return
**/
func (service SyncEmployeeService) DoAction(action string, byteData []byte) error {
switch action {
case "add":
... ... @@ -157,6 +165,13 @@ func (service SyncEmployeeService) DoAction(action string, byteData []byte) erro
}
}
/**
* @Author SteveChan
* @Description //TODO 初始化栏目设置
* @Date 00:07 2021/1/27
* @Param
* @return
**/
//addEmployeeData 添加用户
func (service SyncEmployeeService) addEmployeeData(datas []EmployeeData) error {
var (
... ... @@ -167,7 +182,7 @@ func (service SyncEmployeeService) addEmployeeData(datas []EmployeeData) error {
return err
}
defer func() {
transactionContext.RollbackTransaction()
_ = transactionContext.RollbackTransaction()
}()
var usersRepository domain.UsersRepository
if usersRepository, err = factory.CreateUsersRepository(map[string]interface{}{
... ... @@ -175,6 +190,12 @@ func (service SyncEmployeeService) addEmployeeData(datas []EmployeeData) error {
}); err != nil {
return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
}
var columnSettingRepository domain.ColumnSettingRepository
if columnSettingRepository, err = factory.CreateColumnSettingRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); err != nil {
return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
}
for i := range datas {
data := datas[i]
newUser := domain.Users{
... ... @@ -202,7 +223,24 @@ func (service SyncEmployeeService) addEmployeeData(datas []EmployeeData) error {
if err = usersRepository.Add(&newUser); err != nil {
return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
}
// 初始化栏目设置
newColumnSetting := &domain.ColumnSetting{
Description: "订单管理栏目设置",
UserName: data.Name,
CompanyId: int(data.CompanyId),
Uid: data.Id,
Key: constant.ORDER_BASE, // 订单栏目模块名称
Value: domain.DefaultColumns, // 栏目值数组,创建用户时使用默认栏目设置
InvalidValue: domain.DefaultInvalidColumns, // 初始化无效栏目数组
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
if _, err = columnSettingRepository.Save(newColumnSetting); err != nil {
return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
}
}
err = transactionContext.CommitTransaction()
return err
}
... ... @@ -303,7 +341,7 @@ func (service SyncEmployeeService) deleteEmployeeData(data DeleteUserData) error
return err
}
defer func() {
transactionContext.RollbackTransaction()
_ = transactionContext.RollbackTransaction()
}()
var usersRepository domain.UsersRepository
if usersRepository, err = factory.CreateUsersRepository(map[string]interface{}{
... ... @@ -314,6 +352,25 @@ func (service SyncEmployeeService) deleteEmployeeData(data DeleteUserData) error
if err = usersRepository.Remove(data.Ids); err != nil {
return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
}
// TODO 删除栏目设置
var columnSettingRepository domain.ColumnSettingRepository
if value, errFac := factory.CreateColumnSettingRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); errFac != nil {
return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
} else {
columnSettingRepository = value
}
_, columnSettingsFound, err := columnSettingRepository.Find(map[string]interface{}{"ids": data.Ids, "companyId": data.CompanyId})
if err != nil {
return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
}
if len(columnSettingsFound) == 0 {
return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
}
if _, _, errRm := columnSettingRepository.Remove(nil, columnSettingsFound); errRm != nil {
return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, errRm.Error())
}
err = transactionContext.CommitTransaction()
return err
}
... ... @@ -328,7 +385,7 @@ func (service SyncEmployeeService) updateUsersStatus(data ForbidAllowUserData) e
return err
}
defer func() {
transactionContext.RollbackTransaction()
_ = transactionContext.RollbackTransaction()
}()
var uDao *dao.UsersDao
if uDao, err = factory.CreateUsersDao(map[string]interface{}{
... ...
... ... @@ -16,11 +16,15 @@ var (
UCENTER_CHECK_ALT = "rsF0pL!6DwjBO735"
)
// 栏目常量设置
var ORDER_BASE = "order_base" // 订单管理栏目
var (
BUSINESS_ADMIN_HOST = "http://suplus-business-admin-test.fjmaimaimai.com" //企业平台的地址
)
var EXCEL_COLUMN = 12
// 导入excel文件列总数
var EXCEL_COLUMN = 13
func init() {
if os.Getenv("LOG_LEVEL") != "" {
... ...
... ... @@ -4,10 +4,10 @@ import "os"
var POSTGRESQL_DB_NAME = "partner_test"
var POSTGRESQL_USER = "postgres"
var POSTGRESQL_PASSWORD = "1993618jack" // eagle1010
var POSTGRESQL_HOST = "127.0.0.1" // 114.55.200.59
var POSTGRESQL_PORT = "5432" // 31543
var DISABLE_CREATE_TABLE = true
var POSTGRESQL_PASSWORD = "1993618jack" // eagle1010 1993618jack
var POSTGRESQL_HOST = "127.0.0.1" // 114.55.200.59 127.0.0.1
var POSTGRESQL_PORT = "5432" // 31543 5432
var DISABLE_CREATE_TABLE = false
var DISABLE_SQL_GENERATE_PRINT = false
func init() {
... ...
/**
@author: stevechan
@date: 2021/1/26
@note:
**/
package domain
// 栏目项值对象
type Column struct {
// 列标记
Id string `json:"id"`
// 列标记中文
ParamCn string `json:"paramCn"`
// 列标记是否固定,1:固定,2:不固定
ParamFix int `json:"paramFix"`
}
... ...
package domain
import "time"
// 默认选中栏目
var DefaultColumns = []Column{
{
Id: "index",
ParamCn: "序号",
ParamFix: 1,
}, {
Id: "orderId",
ParamCn: "订单号",
ParamFix: 1,
}, {
Id: "shipmentsId",
ParamCn: "发货单号",
ParamFix: 2,
}, {
Id: "saleDate",
ParamCn: "销售日期",
ParamFix: 2,
}, {
Id: "orderNum",
ParamCn: "订单数量",
ParamFix: 2,
}, {
Id: "quantityControl",
ParamCn: "数量调整",
ParamFix: 2,
}, {
Id: "orderPrice",
ParamCn: "订单金额",
ParamFix: 2,
}, {
Id: "priceControl",
ParamCn: "金额调整",
ParamFix: 2,
}, {
Id: "orderDist",
ParamCn: "订单区域",
ParamFix: 2,
}, {
Id: "partnerCategory",
ParamCn: "合伙人类型",
ParamFix: 2,
}, {
Id: "buyer",
ParamCn: "客户",
ParamFix: 2,
}, {
Id: "partner",
ParamCn: "合伙人",
ParamFix: 2,
},
}
// 默认未选中栏目
var DefaultInvalidColumns = []Column{
{
Id: "updateTime",
ParamCn: "更新时间",
ParamFix: 2,
}, {
Id: "createTime",
ParamCn: "创建时间",
ParamFix: 2,
},
}
// 栏目设置
type ColumnSetting struct {
// 栏目设置id
Id int64 `json:"id"`
// 栏目设置关联用户公司id
CompanyId int `json:"companyId"`
// 栏目设置创建时间
CreatedAt time.Time `json:"createdAt"`
// 栏目设置描述
Description string `json:"description"`
// 栏目设置模块名称
Key string `json:"key"`
// 栏目设置关联用户uid
Uid int64 `json:"uid"`
// 栏目设置更新时间
UpdatedAt time.Time `json:"updatedAt"`
// 栏目设置关联用户名称
UserName string `json:"userName"`
// 有效栏目数组
Value []Column `json:"value"`
// 无效栏目数组
InvalidValue []Column `json:"invalidValue"`
}
type ColumnSettingRepository interface {
Save(columnSetting *ColumnSetting) (*ColumnSetting, error)
Remove(columnSetting *ColumnSetting, columnSettings []*ColumnSetting) (*ColumnSetting, []*ColumnSetting, error)
FindOne(queryOptions map[string]interface{}) (*ColumnSetting, error)
Find(queryOptions map[string]interface{}) (int64, []*ColumnSetting, error)
}
func (columnSetting *ColumnSetting) Identify() interface{} {
if columnSetting.Id == 0 {
return nil
}
return columnSetting.Id
}
func (columnSetting *ColumnSetting) Update(data map[string]interface{}) error {
if companyId, ok := data["companyId"]; ok {
columnSetting.CompanyId = companyId.(int)
}
if createdAt, ok := data["createdAt"]; ok {
columnSetting.CreatedAt = createdAt.(time.Time)
}
if description, ok := data["description"]; ok {
columnSetting.Description = description.(string)
}
if key, ok := data["key"]; ok {
columnSetting.Key = key.(string)
}
if uid, ok := data["uid"]; ok {
columnSetting.Uid = uid.(int64)
}
if updatedAt, ok := data["updatedAt"]; ok {
columnSetting.UpdatedAt = updatedAt.(time.Time)
}
if userName, ok := data["userName"]; ok {
columnSetting.UserName = userName.(string)
}
if value, ok := data["value"]; ok {
columnSetting.Value = value.([]Column)
}
if invalidValue, ok := data["invalidValue"]; ok {
columnSetting.InvalidValue = invalidValue.([]Column)
}
return nil
}
... ...
... ... @@ -90,7 +90,8 @@ type OrderBase struct {
//订单区域信息
RegionInfo RegionInfo `json:"regionInfo"`
//订单对应的合伙人
PartnerId int64 `json:"partnerId"`
PartnerId int64 `json:"partnerId"`
//合伙人信息
PartnerInfo Partner `json:"partnerInfo"`
//业务员抽成比例
SalesmanBonusPercent float64 `json:"salesmanBonusPercent"`
... ... @@ -116,6 +117,8 @@ type OrderBase struct {
Remark OrderBaseRemark `json:"remark"`
//合伙人类型
PartnerCategory PartnerCategory `json:"partnerCategory"`
//销售日期
SaleDate time.Time `json:"saleDate"`
}
//GetCurrentPartnerBonus 获取当前合伙人应收分红
... ... @@ -327,7 +330,7 @@ type GoodErrInfo struct {
type OrderBaseRepository interface {
Save(order *OrderBase) error
FindOne(qureyOptions OrderBaseFindOneQuery) (*OrderBase, error)
FindOne(queryOptions OrderBaseFindOneQuery) (*OrderBase, error)
Find(queryOptions OrderBaseFindQuery) ([]OrderBase, int, error)
Remove(id int64, companyId int64) error
}
... ...
... ... @@ -21,7 +21,7 @@ type OrderBestShop struct {
BuyerAddress string `json:"buyerAddress"`
//买家备注
BuyerRemark string `json:"buyerRemark"`
//
//客户id
BuyerId int64 `json:"buyerId"`
//商品总数
OrderCount int `json:"orderCount"`
... ... @@ -30,12 +30,16 @@ type OrderBestShop struct {
//发货时间
DeliveryTime string `json:"deliveryTime"`
//创建时间
CreateTime time.Time `json:"createTime"`
PartnerId int64 `json:"partnerId"`
Goods []OrderGoodBestShop `json:"goods"`
CreateTime time.Time `json:"createTime"`
//合伙人id
PartnerId int64 `json:"partnerId"`
//订单产品
Goods []OrderGoodBestShop `json:"goods"`
//是否将数据同步到 order_base ,order_good
IsCopy bool `json:"isCopy"`
CompanyId int64 `json:"companyId"`
IsCopy bool `json:"isCopy"`
//公司id
CompanyId int64 `json:"companyId"`
//订单区域
OrderArea string `json:"orderArea"`
}
... ... @@ -55,6 +59,7 @@ func (order OrderBestShop) CopyToOrderBase(o *OrderBase) {
o.OrderCompute.PlanOrderAmount = order.OrderAmount
o.OrderCompute.PlanOrderCount = order.OrderCount
o.DeliveryTime, _ = time.Parse("2006-01-02 15:04:05", order.DeliveryTime)
o.SaleDate = order.CreateTime
o.RegionInfo.RegionName = order.OrderArea
return
}
... ...
... ... @@ -191,7 +191,7 @@ func (dao OrderBaseDao) OrderBonusListForExcel(companyId int64, orderType int, p
//@param updateTime 订单更新时间范围"[开始时间,结束时间]",时间格式"2006-01-02 15:04:05+07"
//@param createTime 订单的创建时间范围"[开始时间,结束时间]" 时间格式"2006-01-02 15:04:05+07"
func (dao OrderBaseDao) OrderListByCondition(companyId int64, orderType int, partnerName string, orderCode string, deliveryCode string,
updateTime [2]string, createTime [2]string, partnerCategory int, limit, offset int) ([]models.OrderBase, int, error) {
updateTime [2]string, createTime [2]string, saleDate [2]string, partnerCategory int, partnerCategoryName string, limit, offset int) ([]models.OrderBase, int, error) {
tx := dao.transactionContext.GetDB()
var orders []models.OrderBase
query := tx.Model(&orders).Where("order_base.company_id=?", companyId)
... ... @@ -203,6 +203,9 @@ func (dao OrderBaseDao) OrderListByCondition(companyId int64, orderType int, par
if partnerCategory > 0 {
query = query.Where(`order_base.partner_category@>'{"id":?}'`, partnerCategory)
}
if partnerCategoryName != "" {
query = query.Where(`order_base.partner_category->>'name' like ?`, "%"+partnerCategoryName+"%")
}
if len(updateTime[0]) > 0 {
query = query.Where(`order_base.update_time>=?`, updateTime[0])
}
... ... @@ -215,6 +218,12 @@ func (dao OrderBaseDao) OrderListByCondition(companyId int64, orderType int, par
if len(createTime[1]) > 0 {
query = query.Where(`order_base.create_time<=?`, createTime[1])
}
if len(saleDate[0]) > 0 {
query = query.Where(`order_base.sale_date>=?`, saleDate[0])
}
if len(saleDate[1]) > 0 {
query = query.Where(`order_base.sale_date<=?`, saleDate[1])
}
if len(partnerName) > 0 {
query = query.Join("LEFT JOIN partner_info as p ON order_base.partner_id=p.id").
Where("p.partner_name like ? ", "%"+partnerName+"%")
... ... @@ -249,6 +258,7 @@ type CustomOrderListForExcel struct {
DeliveryCode string //发货编号
UpdateTime string //更新时间
CreateTime string //创建时间
SaleDate string // 销售时间
PlanOrderCount int64 //货品总数
UseOrderCount int64 //货品总数调整
RegionName string //订单区域
... ... @@ -259,6 +269,13 @@ type CustomOrderListForExcel struct {
PartnerName string //合伙人
}
/**
* @Author SteveChan
* @Description // 导出到excel
* @Date 23:45 2021/1/26
* @Param
* @return
**/
//OrderListForExcel 获取实际订单列表用于excel导出
//@param companyId 公司id
//@param orderType 订单类型
... ... @@ -267,12 +284,13 @@ type CustomOrderListForExcel struct {
//@param updateTime 订单更新时间范围"[开始时间,结束时间]",时间格式"2006-01-02 15:04:05+07"
//@param createTime 订单的创建时间范围"[开始时间,结束时间]" 时间格式"2006-01-02 15:04:05+07"
func (dao OrderBaseDao) OrderListForExcel(companyId int64, partnerName string, orderCode string, deliveryCode string,
updateTime [2]string, createTime [2]string, partnerCategory int) (
updateTime [2]string, createTime [2]string, saleDate [2]string, partnerCategory int, partnerCategoryName string) (
result []CustomOrderListForExcel, err error) {
sqlstr := `
SELECT t1.order_code,t1.delivery_code
,to_char(t1.create_time AT TIME ZONE 'CCT' ,'YYYY-MM-DD HH24:MI:SS') AS create_time
,to_char(t1.update_time AT TIME ZONE 'CCT' ,'YYYY-MM-DD HH24:MI:SS') AS update_time
,to_char(t1.sale_date AT TIME ZONE 'CCT' ,'YYYY-MM-DD HH24:MI:SS') AS sale_date
,t1.plan_order_count,t1.use_order_count,t1.plan_order_amount,t1.use_order_amount
,t1.region_info->'regionName' AS region_name,t1.buyer->'buyerName' AS buyer_name
,t1.partner_category->'name' AS partner_category
... ... @@ -306,17 +324,18 @@ func (dao OrderBaseDao) OrderListForExcel(companyId int64, partnerName string, o
params = append(params, partnerCategory)
sqlstr += ` AND t1.partner_category@>'{"id":?}' `
}
if len(partnerCategoryName) > 0 {
params = append(params, partnerCategoryName)
sqlstr += ` AND t1.partner_category->> 'name' like ?`
}
if len(updateTime[0]) > 0 {
params = append(params, updateTime[0])
sqlstr += ` AND t1.update_time>=? `
}
if len(updateTime[1]) > 0 {
params = append(params, updateTime[1])
sqlstr += ` AND t1.update_time<=? `
}
if len(createTime[0]) > 0 {
params = append(params, createTime[0])
sqlstr += ` AND t1.create_time>=? `
... ... @@ -325,6 +344,14 @@ func (dao OrderBaseDao) OrderListForExcel(companyId int64, partnerName string, o
params = append(params, createTime[1])
sqlstr += ` AND t1.create_time<=? `
}
if len(saleDate[0]) > 0 {
params = append(params, saleDate[0])
sqlstr += ` AND t1.sale_date>=? `
}
if len(saleDate[1]) > 0 {
params = append(params, saleDate[1])
sqlstr += ` AND t1.sale_date<=? `
}
sqlstr += ` ORDER BY t1.create_time DESC limit 10000 `
tx := dao.transactionContext.GetDB()
_, err = tx.Query(&result, sqlstr, params...)
... ...
... ... @@ -5,7 +5,9 @@ import (
"fmt"
"github.com/go-pg/pg/v10"
"github.com/go-pg/pg/v10/orm"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/constant"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/models"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/log"
)
... ... @@ -21,6 +23,31 @@ func init() {
if !constant.DISABLE_SQL_GENERATE_PRINT {
DB.AddQueryHook(SqlGeneratePrintHook{})
}
if !constant.DISABLE_CREATE_TABLE {
for _, model := range []interface{}{
&models.ColumnSetting{},
&models.AdminPermission{},
&models.BusinessBonus{},
&models.Company{},
&models.OrderBase{},
&models.OrderBestshop{},
&models.OrderGood{},
&models.OrderGoodBestshop{},
&models.OrderLog{},
&models.PartnerCategoryInfo{},
&models.PartnerInfo{},
&models.Users{},
} {
err := DB.Model(model).CreateTable(&orm.CreateTableOptions{
Temp: false,
IfNotExists: true,
FKConstraints: true,
})
if err != nil {
panic(err)
}
}
}
}
type SqlGeneratePrintHook struct{}
... ...
package models
import (
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
"time"
)
type ColumnSetting struct {
// 栏目设置id
Id int64
// 栏目设置关联用户公司id
CompanyId int
// 栏目设置创建时间
CreatedAt time.Time
// 栏目设置描述
Description string
// 栏目设置模块名称
Key string
// 栏目设置关联用户uid
Uid int64
// 栏目设置更新时间
UpdatedAt time.Time
// 栏目设置关联用户名称
UserName string
// 栏目数组
Value []domain.Column `pg:",array"`
// 无效栏目数组
InvalidValue []domain.Column `pg:",array"`
}
... ...
... ... @@ -45,6 +45,8 @@ type OrderBase struct {
DeliveryTime time.Time
//更新时间
UpdateTime time.Time
//销售时间
SaleDate time.Time
//合伙人应收分红
PlanPartnerBonus float64 `pg:",use_zero"`
//调整后的合伙人应收分红 (初始值=-1);
... ... @@ -62,7 +64,8 @@ type OrderBase struct {
IsDisable int `pg:",use_zero"`
//分红支付状态
BonusStatus int
CompanyId int64
//公司id
CompanyId int64
//数据来源
DataFrom domain.OrderDataFrom ``
//备注
... ...
package repository
import (
"fmt"
"github.com/go-pg/pg"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/models"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/transaction"
)
type ColumnSettingRepository struct {
transactionContext *transaction.TransactionContext
}
//func (repository *ColumnSettingRepository) nextIdentify() (int64, error) {
// return 0, nil
//}
func (repository *ColumnSettingRepository) Save(columnSetting *domain.ColumnSetting) (*domain.ColumnSetting, error) {
tx := repository.transactionContext.PgTx
columnSettingModel := &models.ColumnSetting{
Id: columnSetting.Id,
CompanyId: columnSetting.CompanyId,
CreatedAt: columnSetting.CreatedAt,
Description: columnSetting.Description,
Key: columnSetting.Key,
Uid: columnSetting.Uid,
UpdatedAt: columnSetting.UpdatedAt,
UserName: columnSetting.UserName,
Value: columnSetting.Value,
InvalidValue: columnSetting.InvalidValue,
}
if columnSetting.Identify() == nil {
_, err := tx.Model(columnSettingModel).Insert()
if err != nil {
return nil, err
}
//_, err := repository.nextIdentify()
//if err != nil {
// return columnSetting, err
//}
//if _, errInsert := tx.QueryOne(
// pg.Scan(&columnSetting.Id, &columnSetting.CompanyId, &columnSetting.CreatedAt, &columnSetting.Description, &columnSetting.Key, &columnSetting.Uid, &columnSetting.UpdatedAt, &columnSetting.UserName, pg.Array(&columnSetting.Value), pg.Array(&columnSetting.InvalidValue)),
// "INSERT INTO column_settings (company_id, created_at, description, key, uid, updated_at, user_name, value, invalid_value) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING id, company_id, created_at, description, key, uid, updated_at, user_name, value, invalid_value",
// columnSetting.CompanyId, columnSetting.CreatedAt, columnSetting.Description, columnSetting.Key, columnSetting.Uid, columnSetting.UpdatedAt, columnSetting.UserName, pg.Array(columnSetting.Value), pg.Array(columnSetting.InvalidValue)); errInsert != nil {
// return columnSetting, errInsert
//}
} else {
//if _, errUpdate := tx.QueryOne(
// pg.Scan(&columnSetting.Id, &columnSetting.CompanyId, &columnSetting.CreatedAt, &columnSetting.Description, &columnSetting.Key, &columnSetting.Uid, &columnSetting.UpdatedAt, &columnSetting.UserName, pg.Array(&columnSetting.Value), pg.Array(&columnSetting.InvalidValue)),
// "UPDATE column_settings SET company_id=?, created_at=?, description=?, key=?, uid=?, updated_at=?, user_name=?, value=?, invalid_value=? WHERE id=? RETURNING id, company_id, created_at, description, key, uid, updated_at, user_name, value, invalid_value",
// columnSetting.CompanyId, columnSetting.CreatedAt, columnSetting.Description, columnSetting.Key, columnSetting.Uid, columnSetting.UpdatedAt, columnSetting.UserName, pg.Array(columnSetting.Value), pg.Array(columnSetting.InvalidValue), columnSetting.Identify()); errUpdate != nil {
// return columnSetting, errUpdate
//}
_, err := tx.Model(columnSettingModel).WherePK().
Column("company_id", "created_at", "description", "key", "uid", "updated_at", "user_name", "value", "invalid_value").Update()
if err != nil {
return nil, err
}
}
return columnSetting, nil
}
func (repository *ColumnSettingRepository) Remove(columnSetting *domain.ColumnSetting, columnSettings []*domain.ColumnSetting) (*domain.ColumnSetting, []*domain.ColumnSetting, error) {
tx := repository.transactionContext.PgTx
if columnSetting != nil {
// 单个删除
columnSettingModel := new(models.ColumnSetting)
columnSettingModel.Id = columnSetting.Identify().(int64)
if _, err := tx.Model(columnSettingModel).WherePK().Delete(); err != nil {
return columnSetting, nil, err
}
}
// 批量删除
if len(columnSettings) > 0 {
var columnSettingModels []*models.ColumnSetting
for _, setting := range columnSettings {
columnSettingModels = append(columnSettingModels, &models.ColumnSetting{
Id: setting.Identify().(int64),
})
}
if _, err := tx.Model(columnSettingModels).WherePK().Delete(); err != nil {
return nil, columnSettings, err
}
}
return columnSetting, columnSettings, nil
}
func (repository *ColumnSettingRepository) FindOne(queryOptions map[string]interface{}) (*domain.ColumnSetting, error) {
tx := repository.transactionContext.PgTx
columnSettingModel := new(models.ColumnSetting)
query := tx.Model(columnSettingModel)
if columnSettingId, ok := queryOptions["column_settingId"]; ok {
query = query.Where("column_setting.id = ?", columnSettingId)
}
if uid, ok := queryOptions["uid"]; ok {
query = query.Where("column_setting.uid = ?", uid)
}
if companyId, ok := queryOptions["companyId"]; ok {
query = query.Where("column_setting.company_id = ?", companyId)
}
if err := query.First(); err != nil {
if err.Error() == "pg: no rows in result set" {
return nil, fmt.Errorf("没有此资源")
} else {
return nil, err
}
}
if columnSettingModel.Id == 0 {
return nil, nil
} else {
return repository.transformPgModelToDomainModel(columnSettingModel)
}
}
func (repository *ColumnSettingRepository) Find(queryOptions map[string]interface{}) (int64, []*domain.ColumnSetting, error) {
tx := repository.transactionContext.PgTx
var columnSettingModels []*models.ColumnSetting
columnSettings := make([]*domain.ColumnSetting, 0)
query := tx.Model(&columnSettingModels)
if ids, ok := queryOptions["ids"]; ok {
query = query.Where("column_setting.uid IN (?)", pg.In(ids.(int64)))
}
if uid, ok := queryOptions["uid"]; ok {
query = query.Where("column_setting.uid = ?", uid)
}
if companyId, ok := queryOptions["companyId"]; ok {
query = query.Where("column_setting.company_id = ?", companyId)
}
if offset, ok := queryOptions["offset"]; ok {
queryOffset := offset.(int)
if queryOffset > -1 {
query = query.Offset(queryOffset)
}
} else {
query = query.Offset(0)
}
if limit, ok := queryOptions["limit"]; ok {
queryLimit := limit.(int)
if queryLimit > -1 {
query = query.Limit(queryLimit)
}
} else {
query = query.Limit(20)
}
if count, err := query.Order("id DESC").SelectAndCount(); err != nil {
return 0, columnSettings, err
} else {
for _, columnSettingModel := range columnSettingModels {
if columnSetting, errTrans := repository.transformPgModelToDomainModel(columnSettingModel); errTrans != nil {
return 0, columnSettings, errTrans
} else {
columnSettings = append(columnSettings, columnSetting)
}
}
return int64(count), columnSettings, nil
}
}
func (repository *ColumnSettingRepository) transformPgModelToDomainModel(columnSettingModel *models.ColumnSetting) (*domain.ColumnSetting, error) {
return &domain.ColumnSetting{
Id: columnSettingModel.Id,
CompanyId: columnSettingModel.CompanyId,
CreatedAt: columnSettingModel.CreatedAt,
Description: columnSettingModel.Description,
Key: columnSettingModel.Key,
Uid: columnSettingModel.Uid,
UpdatedAt: columnSettingModel.UpdatedAt,
UserName: columnSettingModel.UserName,
Value: columnSettingModel.Value, // 有效栏目设置
InvalidValue: columnSettingModel.InvalidValue, // 无效栏目设置
}, nil
}
func NewColumnSettingRepository(transactionContext *transaction.TransactionContext) (*ColumnSettingRepository, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &ColumnSettingRepository{
transactionContext: transactionContext,
}, nil
}
}
... ...
... ... @@ -23,12 +23,13 @@ func NewOrderBaseRepository(transactionContext *transaction.TransactionContext)
return &OrderBaseRepository{transactionContext: transactionContext}, nil
}
func (reponsitory OrderBaseRepository) transformPgModelToDomainModel(orderModel *models.OrderBase) (order domain.OrderBase, err error) {
func (repository OrderBaseRepository) transformPgModelToDomainModel(orderModel *models.OrderBase) (order domain.OrderBase, err error) {
order = domain.OrderBase{
Id: orderModel.Id, OrderType: orderModel.OrderType, OrderCode: orderModel.OrderCode,
DeliveryCode: orderModel.DeliveryCode, Buyer: orderModel.Buyer, RegionInfo: orderModel.RegionInfo,
PartnerId: orderModel.PartnerId, SalesmanBonusPercent: orderModel.SalesmanBonusPercent,
CreateTime: orderModel.CreateTime, DeliveryTime: orderModel.DeliveryTime, UpdateTime: orderModel.UpdateTime,
SaleDate: orderModel.SaleDate,
IsDisable: orderModel.IsDisable,
OrderCompute: domain.OrderCompute{
PlanPartnerBonus: orderModel.PlanPartnerBonus, UsePartnerBonus: orderModel.UsePartnerBonus,
... ... @@ -55,19 +56,37 @@ func (repository OrderBaseRepository) Save(orderInfo *domain.OrderBase) error {
tx = repository.transactionContext.PgTx
)
m := &models.OrderBase{
Id: orderInfo.Id, OrderType: orderInfo.OrderType, OrderCode: orderInfo.OrderCode,
DeliveryCode: orderInfo.DeliveryCode, Buyer: orderInfo.Buyer, RegionInfo: orderInfo.RegionInfo,
PartnerId: orderInfo.PartnerId, SalesmanBonusPercent: orderInfo.SalesmanBonusPercent,
SalesmanBonus: orderInfo.OrderCompute.SalesmanBonus, PlanOrderCount: orderInfo.OrderCompute.PlanOrderCount,
PlanOrderAmount: orderInfo.OrderCompute.PlanOrderAmount, UseOrderCount: orderInfo.OrderCompute.UseOrderCount,
UseOrderAmount: orderInfo.OrderCompute.UseOrderAmount, DeliveryTime: orderInfo.DeliveryTime,
PlanPartnerBonus: orderInfo.OrderCompute.PlanPartnerBonus, UsePartnerBonus: orderInfo.OrderCompute.UsePartnerBonus,
PartnerBonusHas: orderInfo.OrderCompute.PartnerBonusHas, PartnerBonusNot: orderInfo.OrderCompute.PartnerBonusNot,
PartnerBonusExpense: orderInfo.OrderCompute.PartnerBonusExpense, IsDisable: orderInfo.IsDisable,
CreateTime: orderInfo.CreateTime, BonusStatus: orderInfo.BonusStatus,
CompanyId: orderInfo.CompanyId, DataFrom: orderInfo.DataFrom,
Remark: orderInfo.Remark, PartnerCategory: orderInfo.PartnerCategory,
}
Id: orderInfo.Id,
OrderType: orderInfo.OrderType,
OrderCode: orderInfo.OrderCode,
DeliveryCode: orderInfo.DeliveryCode,
Buyer: orderInfo.Buyer,
RegionInfo: orderInfo.RegionInfo,
PartnerId: orderInfo.PartnerId,
SalesmanBonusPercent: orderInfo.SalesmanBonusPercent,
SalesmanBonus: orderInfo.OrderCompute.SalesmanBonus,
PlanOrderCount: orderInfo.OrderCompute.PlanOrderCount,
PlanOrderAmount: orderInfo.OrderCompute.PlanOrderAmount,
UseOrderCount: orderInfo.OrderCompute.UseOrderCount,
UseOrderAmount: orderInfo.OrderCompute.UseOrderAmount,
DeliveryTime: orderInfo.DeliveryTime,
PlanPartnerBonus: orderInfo.OrderCompute.PlanPartnerBonus,
UsePartnerBonus: orderInfo.OrderCompute.UsePartnerBonus,
PartnerBonusHas: orderInfo.OrderCompute.PartnerBonusHas,
PartnerBonusNot: orderInfo.OrderCompute.PartnerBonusNot,
PartnerBonusExpense: orderInfo.OrderCompute.PartnerBonusExpense,
IsDisable: orderInfo.IsDisable,
CreateTime: orderInfo.CreateTime,
SaleDate: orderInfo.SaleDate,
BonusStatus: orderInfo.BonusStatus,
CompanyId: orderInfo.CompanyId,
DataFrom: orderInfo.DataFrom,
Remark: orderInfo.Remark,
PartnerCategory: orderInfo.PartnerCategory,
}
//if m.OrderType > 2 { // TODO 非平台自建订单,默认销售日期取订单创建日期
// m.SaleDate = orderInfo.CreateTime
//}
if m.Id == 0 {
_, err = tx.Model(m).
Returning("*").
... ... @@ -75,6 +94,7 @@ func (repository OrderBaseRepository) Save(orderInfo *domain.OrderBase) error {
orderInfo.Id = m.Id
orderInfo.CreateTime = m.CreateTime
orderInfo.UpdateTime = m.UpdateTime
orderInfo.SaleDate = m.CreateTime
} else {
_, err = tx.Model(m).
WherePK().
... ... @@ -131,16 +151,16 @@ func (repository OrderBaseRepository) Find(queryOption domain.OrderBaseFindQuery
return ordersReturn, count, nil
}
func (repository OrderBaseRepository) FindOne(qureyOptions domain.OrderBaseFindOneQuery) (*domain.OrderBase, error) {
func (repository OrderBaseRepository) FindOne(queryOptions domain.OrderBaseFindOneQuery) (*domain.OrderBase, error) {
var (
err error
tx = repository.transactionContext.PgDd
)
m := new(models.OrderBase)
query := tx.Model(m).
Where("id=?", qureyOptions.OrderId)
if qureyOptions.CompanyId > 0 {
query = query.Where("company_id=?", qureyOptions.CompanyId)
Where("id=?", queryOptions.OrderId)
if queryOptions.CompanyId > 0 {
query = query.Where("company_id=?", queryOptions.CompanyId)
}
err = query.First()
if err != nil {
... ...
package controllers
import (
"encoding/json"
"errors"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
"github.com/astaxie/beego/logs"
"github.com/linmadan/egglib-go/web/beego/utils"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/columnSetting/command"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/columnSetting/query"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/columnSetting/service"
)
type ColumnSettingController struct {
BaseController
}
////Prepare 重写 BaseController 的Prepare方法
func (controller *ColumnSettingController) Prepare() {
controller.BaseController.Prepare()
if ok := controller.ValidJWTToken(); !ok {
return
}
if ok := controller.ValidAdminPermission(domain.PERMINSSION_PARTNER); !ok {
return
}
}
func (controller *ColumnSettingController) CreateColumnSetting() {
columnSettingService := service.NewColumnSettingService(nil)
createColumnSettingCommand := &command.CreateColumnSettingCommand{}
//_ = json.Unmarshal(controller.Ctx.Input.GetData("requestBody").([]byte), createColumnSettingCommand)
if err := controller.BindJsonData(&createColumnSettingCommand); err != nil {
logs.Error(err)
controller.ResponseError(errors.New("json数据解析失败"))
return
}
companyId := controller.GetUserCompany()
uid := controller.GetUserId()
createColumnSettingCommand.CompanyId = int(companyId)
createColumnSettingCommand.Uid = uid
data, err := columnSettingService.CreateColumnSetting(createColumnSettingCommand)
var response utils.JsonResponse
if err != nil {
response = utils.ResponseError(controller.Ctx, err)
} else {
response = utils.ResponseData(controller.Ctx, data)
}
controller.Data["json"] = response
controller.ServeJSON()
}
/**
* @Author SteveChan
* @Description // 更新栏目设置
* @Date 22:52 2021/1/26
* @Param
* @return
**/
func (controller *ColumnSettingController) UpdateColumnSetting() {
columnSettingService := service.NewColumnSettingService(nil)
updateColumnSettingCommand := &command.UpdateColumnSettingCommand{}
//_ = json.Unmarshal(controller.Ctx.Input.GetData("requestBody").([]byte), updateColumnSettingCommand)
if err := controller.BindJsonData(&updateColumnSettingCommand); err != nil {
logs.Error(err)
controller.ResponseError(errors.New("json数据解析失败"))
return
}
//columnSettingId, _ := controller.GetInt64(":columnSettingId")
companyId := controller.GetUserCompany()
uid := controller.GetUserId()
//updateColumnSettingCommand.ColumnSettingId = columnSettingId
updateColumnSettingCommand.CompanyId = int(companyId)
updateColumnSettingCommand.Uid = uid
updateColumnSettingCommand.Selected = updateColumnSettingCommand.OrderBaseColumns.Selected
updateColumnSettingCommand.UnSelected = updateColumnSettingCommand.OrderBaseColumns.UnSelected
data, err := columnSettingService.UpdateColumnSetting(updateColumnSettingCommand)
var response utils.JsonResponse
if err != nil {
response = utils.ResponseError(controller.Ctx, err)
} else {
response = utils.ResponseData(controller.Ctx, data)
}
controller.Data["json"] = response
controller.ServeJSON()
}
/**
* @Author SteveChan
* @Description // 获取栏目设置
* @Date 22:53 2021/1/26
* @Param
* @return
**/
func (controller *ColumnSettingController) GetColumnSetting() {
columnSettingService := service.NewColumnSettingService(nil)
getColumnSettingQuery := &query.GetColumnSettingQuery{}
//columnSettingId, _ := controller.GetInt64(":columnSettingId")
companyId := controller.GetUserCompany() // 公司id
uid := controller.GetUserId() // 用户id
//getColumnSettingQuery.ColumnSettingId = columnSettingId
getColumnSettingQuery.CompanyId = int(companyId)
getColumnSettingQuery.Uid = uid
data, err := columnSettingService.GetColumnSetting(getColumnSettingQuery)
var response utils.JsonResponse
if err != nil {
response = utils.ResponseError(controller.Ctx, err)
} else {
response = utils.ResponseData(controller.Ctx, data)
}
controller.Data["json"] = response
controller.ServeJSON()
}
func (controller *ColumnSettingController) RemoveColumnSetting() {
columnSettingService := service.NewColumnSettingService(nil)
removeColumnSettingCommand := &command.RemoveColumnSettingCommand{}
_ = json.Unmarshal(controller.Ctx.Input.GetData("requestBody").([]byte), removeColumnSettingCommand)
columnSettingId, _ := controller.GetInt64(":columnSettingId")
removeColumnSettingCommand.ColumnSettingId = columnSettingId
data, err := columnSettingService.RemoveColumnSetting(removeColumnSettingCommand)
var response utils.JsonResponse
if err != nil {
response = utils.ResponseError(controller.Ctx, err)
} else {
response = utils.ResponseData(controller.Ctx, data)
}
controller.Data["json"] = response
controller.ServeJSON()
}
/**
* @Author SteveChan
* @Description // 重置栏目设置
* @Date 22:52 2021/1/26
* @Param
* @return
**/
func (controller *ColumnSettingController) ResetColumn() {
columnSettingService := service.NewColumnSettingService(nil)
resetColumnCommand := &command.ResetColumnCommand{}
companyId := controller.GetUserCompany()
uid := controller.GetUserId()
//_ = json.Unmarshal(controller.Ctx.Input.GetData("requestBody").([]byte), resetColumnCommand)
resetColumnCommand.CompanyId = int(companyId)
resetColumnCommand.Uid = uid
resetColumnCommand.Value = domain.DefaultColumns // 还原默认栏目设置
resetColumnCommand.InvalidValue = domain.DefaultInvalidColumns // 还原默认无效栏目
data, err := columnSettingService.ResetColumn(resetColumnCommand)
var response utils.JsonResponse
if err != nil {
response = utils.ResponseError(controller.Ctx, err)
} else {
response = utils.ResponseData(controller.Ctx, data)
}
controller.Data["json"] = response
controller.ServeJSON()
}
/**
* @Author SteveChan
* @Description // 获取栏目列表
* @Date 14:03 2021/2/1
* @Param
* @return
**/
func (controller *ColumnSettingController) ListColumnSetting() {
columnSettingService := service.NewColumnSettingService(nil)
listColumnSettingQuery := &query.ListColumnSettingQuery{}
offset, _ := controller.GetInt("offset")
listColumnSettingQuery.Offset = offset
limit, _ := controller.GetInt("limit")
listColumnSettingQuery.Limit = limit
data, err := columnSettingService.ListColumnSetting(listColumnSettingQuery)
var response utils.JsonResponse
if err != nil {
response = utils.ResponseError(controller.Ctx, err)
} else {
response = utils.ResponseData(controller.Ctx, data)
}
controller.Data["json"] = response
controller.ServeJSON()
}
/**
* @Author SteveChan
* @Description //返回默认栏目设置
* @Date 14:06 2021/2/1
* @Param
* @return
**/
func (controller *ColumnSettingController) ListDefaultColumnSetting() {
data := map[string]interface{}{
"orderBaseColumns": map[string]interface{}{
"selected": domain.DefaultColumns,
"unselected": domain.DefaultInvalidColumns,
},
}
var response utils.JsonResponse
response = utils.ResponseData(controller.Ctx, data)
controller.Data["json"] = response
controller.ServeJSON()
}
... ...
... ... @@ -160,15 +160,16 @@ func (postData *postOrderPurposeDelivery) Valid() error {
**/
func (c *OrderInfoController) PageListOrderReal() {
type Parameter struct {
//SearchText string `json:"searchText"`
PartnerName string `json:"partnerName"` // 合伙人姓名
OrderCode string `json:"orderCode"` // 订单号
DeliveryCode string `json:"deliveryCode"` // 发货单号
PartnerCategory int `json:"PartnerCategory"`
PageSize int `json:"pageSize"`
PageNumber int `json:"pageNumber"`
UpdateTime []string `json:"updateTime"`
CreateTime []string `json:"createTime"`
PartnerName string `json:"partnerName"` // 合伙人姓名
OrderCode string `json:"orderCode"` // 订单号
DeliveryCode string `json:"deliveryCode"` // 发货单号
PartnerCategory int `json:"partnerCategory"` // 合伙人类型id
PartnerCategoryName string `json:"partnerCategoryName"` // 合伙人类型名称
PageSize int `json:"pageSize"`
PageNumber int `json:"pageNumber"`
UpdateTime []string `json:"updateTime"` // 订单更新时间
CreateTime []string `json:"createTime"` // 订单创建时间
SaleDate []string `json:"saleDate"` // 销售时间
}
var (
param Parameter
... ... @@ -185,6 +186,7 @@ func (c *OrderInfoController) PageListOrderReal() {
if param.PageSize == 0 {
param.PageSize = 20
}
// 订单更新时间处理
var (
updateTimeBegin string
updateTimeEnd string
... ... @@ -211,6 +213,7 @@ func (c *OrderInfoController) PageListOrderReal() {
updateTimeEnd = t.Format("2006-01-02 15:04:05-07")
}
}
// 订单创建时间处理
var (
createTimeBegin string
createTimeEnd string
... ... @@ -237,29 +240,57 @@ func (c *OrderInfoController) PageListOrderReal() {
createTimeEnd = t.Format("2006-01-02 15:04:05-07")
}
}
// 订单销售时间处理
var (
saleDateBegin string
saleDateEnd string
)
if len(param.SaleDate) > 0 {
if len(param.SaleDate[0]) > 0 {
t, err := time.ParseInLocation("2006-01-02", param.SaleDate[0], time.Local)
if err != nil {
c.ResponseError(errors.New("销售开始时间格式错误"))
return
}
saleDateBegin = t.Format("2006-01-02 15:04:05-07")
}
}
if len(param.SaleDate) > 1 {
if len(param.SaleDate[1]) > 0 {
t, err := time.ParseInLocation("2006-01-02", param.SaleDate[1], time.Local)
if err != nil {
c.ResponseError(errors.New("销售结束时间格式错误"))
return
}
//设定时间边界
t = t.Add(86399 * time.Second)
saleDateEnd = t.Format("2006-01-02 15:04:05-07")
}
}
companyId := c.GetUserCompany()
orderSrv := orderService.NewOrderInfoService(nil)
orderinfos, cnt, err := orderSrv.PageListOrderBase(orderQuery.ListOrderBaseQuery{
//PartnerOrCode: param.SearchText,
PartnerName: param.PartnerName,
OrderCode: param.OrderCode,
DeliveryCode: param.DeliveryCode,
OrderType: domain.OrderReal,
Limit: param.PageSize,
Offset: (param.PageNumber - 1) * param.PageSize,
CompanyId: companyId,
PartnerCategory: param.PartnerCategory,
UpdateTimeBegin: updateTimeBegin,
UpdateTimeEnd: updateTimeEnd,
CreateTimeBegin: createTimeBegin,
CreateTimeEnd: createTimeEnd,
orderInfos, cnt, err := orderSrv.PageListOrderBase(orderQuery.ListOrderBaseQuery{
PartnerName: param.PartnerName,
OrderCode: param.OrderCode,
DeliveryCode: param.DeliveryCode,
OrderType: domain.OrderReal,
Limit: param.PageSize,
Offset: (param.PageNumber - 1) * param.PageSize,
CompanyId: companyId,
PartnerCategory: param.PartnerCategory,
PartnerCategoryName: param.PartnerCategoryName,
UpdateTimeBegin: updateTimeBegin,
UpdateTimeEnd: updateTimeEnd,
CreateTimeBegin: createTimeBegin,
CreateTimeEnd: createTimeEnd,
SaleDateBegin: saleDateBegin,
SaleDateEnd: saleDateEnd,
})
if err != nil {
c.ResponseError(err)
return
}
c.ResponsePageList(orderinfos, cnt, param.PageNumber)
c.ResponsePageList(orderInfos, cnt, param.PageNumber)
return
}
... ... @@ -299,7 +330,8 @@ func (c *OrderInfoController) GetOrderReal() {
allGoods := []map[string]interface{}{}
for _, v := range orderinfo.Goods {
m := map[string]interface{}{
"id": fmt.Sprint(v.Id),
//"id": fmt.Sprint(v.Id),
"id": v.Id,
"productName": v.GoodName,
"orderNum": v.PlanGoodNumber,
"univalence": v.Price,
... ... @@ -330,8 +362,9 @@ func (c *OrderInfoController) GetOrderReal() {
"orderNumCountControl": "",
"orderAmountAdjustmentCountControl": "",
"product": allGoods,
"create_time": orderinfo.CreateTime.Local().Format("2006-01-02 15:04:06"),
"update_time": orderinfo.UpdateTime.Local().Format("2006-01-02 15:04:06"),
"create_time": orderinfo.CreateTime.Local().Format("2006-01-02 15:04:05"),
"update_time": orderinfo.UpdateTime.Local().Format("2006-01-02 15:04:05"),
"saleDate": orderinfo.SaleDate.Local().Format("2006-01-02 15:04:05"),
"partnerCategoryId": orderinfo.PartnerCategory.Id,
"partnerCategoryName": orderinfo.PartnerCategory.Name,
}
... ... @@ -350,6 +383,7 @@ type postRealOrderDetail struct {
postPurposeOrderDetail
PartnerCategoryId int64 `json:"partnerCategoryId"`
ShipmentsId string `json:"shipmentsId"` //发货单号
SaleDate string `json:"saleDate"` // 销售日期
}
func (postData *postRealOrderDetail) Valid() error {
... ... @@ -380,10 +414,18 @@ func (c *OrderInfoController) UpdateOrderReal() {
return
}
var orderDataReturn *domain.OrderBase
saleDate, err := time.ParseInLocation("2006-01-02 15:04:05", param.SaleDate, time.Local)
saleDateWithTz := time.Date(saleDate.Year(), saleDate.Month(), saleDate.Day(), time.Now().Hour(), time.Now().Minute(), time.Now().Second(), time.Now().Nanosecond(), time.Local)
if err != nil {
e := lib.ThrowError(lib.ARG_ERROR, err.Error())
c.ResponseError(e)
return
}
if param.Id == 0 {
orderDataReturn, err = c.addOrderReal(param)
orderDataReturn, err = c.addOrderReal(param, saleDateWithTz)
} else {
err = c.editOrderReal(param)
err = c.editOrderReal(param, saleDateWithTz)
}
if err != nil {
c.ResponseError(err)
... ... @@ -399,7 +441,7 @@ func (c *OrderInfoController) UpdateOrderReal() {
return
}
func (c *OrderInfoController) addOrderReal(param postRealOrderDetail) (*domain.OrderBase, error) {
func (c *OrderInfoController) addOrderReal(param postRealOrderDetail, saleDate time.Time) (*domain.OrderBase, error) {
orderSrv := orderService.NewOrderInfoService(nil)
newGoods := []orderCmd.OrderGoodData{}
for _, v := range param.Product {
... ... @@ -423,12 +465,13 @@ func (c *OrderInfoController) addOrderReal(param postRealOrderDetail) (*domain.O
Goods: newGoods,
CompanyId: companyId,
PartnerCategory: param.PartnerCategoryId,
SaleDate: saleDate,
}
orderData, err := orderSrv.CreateNewOrder(createcmd)
return orderData, err
}
func (c *OrderInfoController) editOrderReal(param postRealOrderDetail) error {
func (c *OrderInfoController) editOrderReal(param postRealOrderDetail, saleDate time.Time) error {
newGoods := []orderCmd.OrderGoodData{}
for _, v := range param.Product {
... ... @@ -453,6 +496,7 @@ func (c *OrderInfoController) editOrderReal(param postRealOrderDetail) error {
Goods: newGoods,
CompanyId: companyId,
PartnerCategory: param.PartnerCategoryId,
SaleDate: saleDate,
}
orderSrv := orderService.NewOrderInfoService(nil)
_, err := orderSrv.UpdateOrderData(updatecmd)
... ... @@ -527,17 +571,20 @@ func (c *OrderInfoController) RemoveOrderReal() {
//ListOrderForExcel excel 导出实际订单的列表
func (c *OrderInfoController) ListOrderForExcel() {
type Parameter struct {
//SearchText string `json:"searchText"`
PartnerName string `json:"partnerName"` // 合伙人姓名
OrderCode string `json:"orderCode"` // 订单号
DeliveryCode string `json:"deliveryCode"` // 发货单号
PartnerCategory int `json:"PartnerCategory"`
UpdateTime []string `json:"updateTime"`
CreateTime []string `json:"createTime"`
}
//type Parameter struct {
// PartnerName string `json:"partnerName"` // 合伙人姓名
// OrderCode string `json:"orderCode"` // 订单号
// DeliveryCode string `json:"deliveryCode"` // 发货单号
// PartnerCategory int `json:"partnerCategory"` // 合伙人类型
// PartnerCategoryName string `json:"partnerCategoryName"` // 合伙人类型名称
// UpdateTime []string `json:"updateTime"` // 更新时间
// CreateTime []string `json:"createTime"` // 创建时间
// SaleDate []string `json:"saleDate"` // 销售日期
//}
var (
param Parameter
//param Parameter
param orderQuery.ListOrderForExcelQuery
err error
)
if err = c.BindJsonData(&param); err != nil {
... ... @@ -545,13 +592,19 @@ func (c *OrderInfoController) ListOrderForExcel() {
c.ResponseError(errors.New("json数据解析失败"))
return
}
if param.Type != "ORDER_BASE" {
logs.Error(err)
c.ResponseError(errors.New("错误的操作类型"))
return
}
// 订单更新时间
var (
updateTimeBegin string
updateTimeEnd string
)
if len(param.UpdateTime) > 0 {
if len(param.UpdateTime[0]) > 0 {
t, err := time.ParseInLocation("2006-01-02", param.UpdateTime[0], time.Local)
if len(param.Where.UpdateTime) > 0 {
if len(param.Where.UpdateTime[0]) > 0 {
t, err := time.ParseInLocation("2006-01-02", param.Where.UpdateTime[0], time.Local)
if err != nil {
c.ResponseError(errors.New("UpdateTimeBegin 时间格式错误"))
return
... ... @@ -559,9 +612,9 @@ func (c *OrderInfoController) ListOrderForExcel() {
updateTimeBegin = t.Format("2006-01-02 15:04:05-07")
}
}
if len(param.UpdateTime) > 1 {
if len(param.UpdateTime[1]) > 0 {
t, err := time.ParseInLocation("2006-01-02", param.UpdateTime[1], time.Local)
if len(param.Where.UpdateTime) > 1 {
if len(param.Where.UpdateTime[1]) > 0 {
t, err := time.ParseInLocation("2006-01-02", param.Where.UpdateTime[1], time.Local)
if err != nil {
c.ResponseError(errors.New("UpdateTimeEnd 时间格式错误"))
return
... ... @@ -571,13 +624,14 @@ func (c *OrderInfoController) ListOrderForExcel() {
updateTimeEnd = t.Format("2006-01-02 15:04:05-07")
}
}
// 订单创建时间
var (
createTimeBegin string
createTimeEnd string
)
if len(param.CreateTime) > 0 {
if len(param.CreateTime[0]) > 0 {
t, err := time.ParseInLocation("2006-01-02", param.CreateTime[0], time.Local)
if len(param.Where.CreateTime) > 0 {
if len(param.Where.CreateTime[0]) > 0 {
t, err := time.ParseInLocation("2006-01-02", param.Where.CreateTime[0], time.Local)
if err != nil {
c.ResponseError(errors.New("UpdateTimeBegin 时间格式错误"))
return
... ... @@ -585,9 +639,9 @@ func (c *OrderInfoController) ListOrderForExcel() {
createTimeBegin = t.Format("2006-01-02 15:04:05-07")
}
}
if len(param.CreateTime) > 1 {
if len(param.CreateTime[1]) > 0 {
t, err := time.ParseInLocation("2006-01-02", param.CreateTime[1], time.Local)
if len(param.Where.CreateTime) > 1 {
if len(param.Where.CreateTime[1]) > 0 {
t, err := time.ParseInLocation("2006-01-02", param.Where.CreateTime[1], time.Local)
if err != nil {
c.ResponseError(errors.New("UpdateTimeEnd 时间格式错误"))
return
... ... @@ -597,21 +651,51 @@ func (c *OrderInfoController) ListOrderForExcel() {
createTimeEnd = t.Format("2006-01-02 15:04:05-07")
}
}
// 订单销售时间处理
var (
saleDateBegin string
saleDateEnd string
)
if len(param.Where.SaleDate) > 0 {
if len(param.Where.SaleDate[0]) > 0 {
t, err := time.ParseInLocation("2006-01-02", param.Where.SaleDate[0], time.Local)
if err != nil {
c.ResponseError(errors.New("销售开始时间格式错误"))
return
}
saleDateBegin = t.Format("2006-01-02 15:04:05-07")
}
}
if len(param.Where.SaleDate) > 1 {
if len(param.Where.SaleDate[1]) > 0 {
t, err := time.ParseInLocation("2006-01-02", param.Where.SaleDate[1], time.Local)
if err != nil {
c.ResponseError(errors.New("销售结束时间格式错误"))
return
}
//设定时间边界
t = t.Add(86399 * time.Second)
saleDateEnd = t.Format("2006-01-02 15:04:05-07")
}
}
companyId := c.GetUserCompany()
uid := c.GetUserId()
orderSrv := orderService.NewOrderInfoService(nil)
orderinfos, columns, err := orderSrv.ListOrderForExcel(orderQuery.ListOrderBaseQuery{
//PartnerOrCode: param.SearchText,
PartnerName: param.PartnerName,
OrderCode: param.OrderCode,
DeliveryCode: param.DeliveryCode,
OrderType: domain.OrderReal,
CompanyId: companyId,
PartnerCategory: param.PartnerCategory,
UpdateTimeBegin: updateTimeBegin,
UpdateTimeEnd: updateTimeEnd,
CreateTimeBegin: createTimeBegin,
CreateTimeEnd: createTimeEnd,
orderInfos, columns, err := orderSrv.ListOrderForExcel(orderQuery.ListOrderBaseQuery{
PartnerName: param.Where.PartnerName,
OrderCode: param.Where.OrderCode,
DeliveryCode: param.Where.DeliveryCode,
OrderType: domain.OrderReal,
CompanyId: companyId,
Uid: uid,
PartnerCategory: param.Where.PartnerCategory,
PartnerCategoryName: param.Where.PartnerCategoryName,
UpdateTimeBegin: updateTimeBegin,
UpdateTimeEnd: updateTimeEnd,
CreateTimeBegin: createTimeBegin,
CreateTimeEnd: createTimeEnd,
SaleDateBegin: saleDateBegin,
SaleDateEnd: saleDateEnd,
})
if err != nil {
c.ResponseError(err)
... ... @@ -627,8 +711,8 @@ func (c *OrderInfoController) ListOrderForExcel() {
}
excelMaker := exceltool.NewExcelMaker()
excelMaker.SetListHead(excelHeaders)
excelMaker.MakeListExcel(orderinfos)
c.ResponseExcelByFile(c.Ctx, excelMaker)
_ = excelMaker.MakeListExcel(orderInfos)
_ = c.ResponseExcelByFile(c.Ctx, excelMaker)
return
}
... ... @@ -667,7 +751,7 @@ func (c *OrderInfoController) DownloadTemplate() {
}
// 获取导入模板
req := httplib.Get("http://suplus-file-dev.fjmaimaimai.com/upload/file/2021010803305336443.xlsx")
req := httplib.Get("http://suplus-file-dev.fjmaimaimai.com/upload/file/2021020111293523855.xlsx")
err = req.ToFile(constant.IMPORT_EXCEL)
if err != nil {
logs.Error("could not save to file: ", err)
... ... @@ -708,8 +792,8 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
// 返回字段定义
ret := map[string]interface{}{}
// 返回信息表头定义 0: 订单号, 1: 发货单号, 2: 客户名称, 3: 订单区域, 4: 编号, 5: 合伙人, 6: 类型, 7: 业务员抽成比例, 8: 产品名称, 9: 数量, 10: 单价, 11: 合伙人分红比例
var tableHeader = []string{"错误详情", "行号", "订单号", "发货单号", "客户名称", "订单区域", "编号", "合伙人", "类型", "业务员抽成比例", "产品名称", "数量", "单价", "合伙人分红比例"}
// 返回信息表头定义 0: 订单号, 1: 发货单号, 2: 客户名称, 3: 订单区域, 4: 销售日期, 5: 编号, 6: 合伙人, 7: 类型, 8: 业务员抽成比例, 9: 产品名称, 10: 数量, 11: 单价, 12: 合伙人分红比例
var tableHeader = []string{"错误详情", "行号", "订单号", "发货单号", "客户名称", "订单区域", "销售日期", "编号", "合伙人", "类型", "业务员抽成比例", "产品名称", "数量", "单价", "合伙人分红比例"}
// 文件后缀名校验
ext := path.Ext(h.Filename)
... ... @@ -781,7 +865,7 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
nullCell := make([]interface{}, 0)
var myRow []string
for j, _ := range row {
if j != 7 { // 业务员抽成比例非必填
if j != 8 { // 业务员抽成比例非必填
if row[j] == "" || row[j] == " " { // 空字符补位
tmpRow[j] = ""
col := strconv.Itoa(j + 1)
... ... @@ -847,7 +931,7 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
col := strconv.Itoa(j + 1)
switch j {
case 0, 1, 2, 3, 4, 5, 8: // 订单号、发货单号、客户名称、订单区域、编号、合伙人、产品名称长度校验
case 0, 1, 2, 3, 5, 6, 9: // 订单号、发货单号、客户名称、订单区域、编号、合伙人、产品名称长度校验
{
cellStr := strings.TrimSpace(cell)
lenCellStr := utf8.RuneCountInString(cellStr)
... ... @@ -860,7 +944,19 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
myRow = tmpRow
}
}
case 6: // 合伙人类型校验(事业合伙、业务合伙、研发合伙、业务-产品应用合伙)
case 4: // 销售日期格式和有效性校验
{
regexpStr := `(\d{4})/(\d{2})/(\d{2})`
ok := regexp.MustCompile(regexpStr).MatchString(cell)
if !ok {
var tmpRow []string
tmpRow = append(tmpRow, "第"+r+"行第"+col+"列销售日期格式错误,请输入正确的销售日期") // 错误信息
tmpRow = append(tmpRow, r) // 行号
tmpRow = append(tmpRow, row...) // 错误行数据
myRow = tmpRow
}
}
case 7: // 合伙人类型校验(事业合伙、业务合伙、研发合伙、业务-产品应用合伙)
{
if !utils.IsContain(partnerType, cell) {
var tmpRow []string
... ... @@ -870,7 +966,7 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
myRow = tmpRow
}
}
case 7: // 业务员抽成比例,非必填,精确到小数点后两位
case 8: // 业务员抽成比例,非必填,精确到小数点后两位
{
if len(cell) > 0 {
... ... @@ -905,7 +1001,7 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
}
}
}
case 9: // 数量不超过16位正整数
case 10: // 产品数量不超过16位正整数
{
//参数类型转换
orderNum, err := strconv.ParseInt(cell, 10, 64)
... ... @@ -926,7 +1022,7 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
myRow = tmpRow
}
}
case 10: // 单价,精确到小数点后两位,小数点左侧最多可输入16位数字
case 11: // 单价,精确到小数点后两位,小数点左侧最多可输入16位数字
{
// 参数类型转换
... ... @@ -948,7 +1044,7 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
myRow = tmpRow
}
}
case 11: // 合伙人分红比例,精确到小数点后两位
case 12: // 合伙人分红比例,精确到小数点后两位
{
//参数类型转换
partnerRatio, parseErr := strconv.ParseFloat(cell, 64)
... ... @@ -1011,29 +1107,30 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
var orderCommands = make(map[string]*orderCmd.CreateOrderCommand, 0)
for i, row := range rows {
if i > 2 && len(row) == constant.EXCEL_COLUMN {
hashValue := md5.Sum([]byte(row[0] + row[1] + row[4] + row[6])) // 根据:订单号+发货单号+合伙人编号+合伙类型计算哈希值
hashValue := md5.Sum([]byte(row[0] + row[1] + row[5] + row[7])) // 根据:订单号+发货单号+合伙人编号+合伙类型计算哈希值
hashString := hex.EncodeToString(hashValue[:])
if _, ok := orderCommands[hashString]; !ok {
//订单相关,0: 订单号, 1: 发货单号, 2: 客户名称, 3: 订单区域, 4: 编号, 5: 合伙人, 6: 类型, 7: 业务抽成比例,
sbPercent, _ := strconv.ParseFloat(row[7], 64) //业务抽成比例
//订单相关,0: 订单号, 1: 发货单号, 2: 客户名称, 3: 订单区域, 4: 销售日期, 5: 编号, 6: 合伙人, 7: 类型, 8: 业务抽成比例,
sbPercent, _ := strconv.ParseFloat(row[8], 64) //业务抽成比例
//产品相关,8: 产品名称, 9: 数量, 10: 单价, 11: 合伙人分红比例
amount, _ := strconv.ParseInt(row[9], 10, 64) // 数量
price, _ := strconv.ParseFloat(row[10], 64) // 单价
percent, _ := strconv.ParseFloat(row[11], 64) // 合伙人分红比例
//产品相关,9: 产品名称, 10: 数量, 11: 单价, 12: 合伙人分红比例
amount, _ := strconv.ParseInt(row[10], 10, 64) // 数量
price, _ := strconv.ParseFloat(row[11], 64) // 单价
percent, _ := strconv.ParseFloat(row[12], 64) // 合伙人分红比例
// 获取partnerId
var partnerInfo *domain.PartnerInfo
// 5: 合伙人编号
orderQueryData := orderQuery.GetPartnerIdQuery{
Code: row[4],
Code: row[5],
PartnerCategory: 0,
CompanyId: companyId,
}
// 1: 事业合伙、2: 业务合伙、3: 研发合伙、4: 业务-产品应用合伙
switch row[6] {
// 7: 合伙人类型 1: 事业合伙、2: 业务合伙、3: 研发合伙、4: 业务-产品应用合伙
switch row[7] {
case "事业合伙":
orderQueryData.PartnerCategory = 1
case "业务合伙":
... ... @@ -1046,6 +1143,19 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
orderQueryData.PartnerCategory = 0
}
// 销售日期时间格式转换
timeValue, err := time.ParseInLocation("2006/01/02", row[4], time.Local)
if err != nil {
e := lib.ThrowError(lib.ARG_ERROR, err.Error())
c.ResponseError(e)
return
}
//saleDate, err := time.ParseInLocation("2006-01-02 15:04:05", param.SaleDate, time.Local)
saleDateWithTz := time.Date(timeValue.Year(), timeValue.Month(), timeValue.Day(), time.Now().Hour(), time.Now().Minute(), time.Now().Second(), time.Now().Nanosecond(), time.Local)
fmt.Print("销售日期:", saleDateWithTz, "\n")
// 初始化建订单命令集
orderCommands[hashString] = &orderCmd.CreateOrderCommand{
OrderType: 0,
... ... @@ -1053,11 +1163,12 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
DeliveryCode: row[1],
BuyerName: row[2],
OrderRegion: row[3],
SaleDate: saleDateWithTz,
PartnerId: 0, // 根据合伙人类型+合伙人编号查找合伙人id
SalesmanBonusPercent: sbPercent,
Goods: []orderCmd.OrderGoodData{
{
GoodName: row[8],
GoodName: row[9],
PlanGoodNumber: int(amount),
Price: price,
PartnerBonusPercent: percent,
... ... @@ -1082,14 +1193,14 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
orderCommands[hashString].PartnerId = partnerInfo.Partner.Id
}
} else {
//产品相关,8: 产品名称, 9: 数量, 10: 单价, 11: 合伙人分红比例
amount, _ := strconv.ParseInt(row[9], 10, 64) // 数量
price, _ := strconv.ParseFloat(row[10], 64) // 单价
percent, _ := strconv.ParseFloat(row[11], 64) // 合伙人分红比例
//产品相关,9: 产品名称, 10: 数量, 11: 单价, 12: 合伙人分红比例
amount, _ := strconv.ParseInt(row[10], 10, 64) // 数量
price, _ := strconv.ParseFloat(row[11], 64) // 单价
percent, _ := strconv.ParseFloat(row[12], 64) // 合伙人分红比例
// 记录同一笔订单产品
orderCommands[hashString].Goods = append(orderCommands[hashString].Goods, orderCmd.OrderGoodData{
GoodName: row[8],
GoodName: row[9],
PlanGoodNumber: int(amount),
Price: price,
PartnerBonusPercent: percent,
... ...
package routers
import (
"github.com/astaxie/beego"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/port/beego/controllers"
)
func init() {
beego.Router("/column-settings/", &controllers.ColumnSettingController{}, "Post:CreateColumnSetting")
beego.Router("/column-settings/:columnSettingId", &controllers.ColumnSettingController{}, "Put:UpdateColumnSetting")
beego.Router("/column-settings/:columnSettingId", &controllers.ColumnSettingController{}, "Get:GetColumnSetting")
beego.Router("/column-settings/:columnSettingId", &controllers.ColumnSettingController{}, "Delete:RemoveColumnSetting")
beego.Router("/column-settings/", &controllers.ColumnSettingController{}, "Post:ResetColumn")
beego.Router("/column-settings/", &controllers.ColumnSettingController{}, "Get:ListColumnSetting")
}
... ...
... ... @@ -41,8 +41,13 @@ func init() {
beego.NSRouter("/actual/del", &controllers.OrderInfoController{}, "POST:RemoveOrderReal"), // 删除实际订单
beego.NSRouter("/actual/update", &controllers.OrderInfoController{}, "POST:UpdateOrderReal"), // 新增实际订单
beego.NSRouter("/actual/close", &controllers.OrderInfoController{}, "POST:OrderDisable"),
beego.NSRouter("/fileImportTemplate", &controllers.OrderInfoController{}, "POST:DownloadTemplate"), // 下载导入模板
beego.NSRouter("/fileImport", &controllers.OrderInfoController{}, "POST:ImportOrderFromExcel"), // 导入订单数据
beego.NSRouter("/fileImportTemplate", &controllers.OrderInfoController{}, "POST:DownloadTemplate"), // 下载导入模板
beego.NSRouter("/fileImport", &controllers.OrderInfoController{}, "POST:ImportOrderFromExcel"), // 导入订单数据
beego.NSRouter("/actual/listColumn", &controllers.ColumnSettingController{}, "POST:GetColumnSetting"), // 返回栏目设置列表
beego.NSRouter("/actual/updateColumn", &controllers.ColumnSettingController{}, "POST:UpdateColumnSetting"), // 更新栏目设置
beego.NSRouter("/actual/resetColumn", &controllers.ColumnSettingController{}, "POST:ResetColumn"), // 重置栏目设置
beego.NSRouter("/actual/createColumn", &controllers.ColumnSettingController{}, "POST:CreateColumnSetting"), // 创建栏目设置,测试用
beego.NSRouter("/actual/listDefaultColumn", &controllers.ColumnSettingController{}, "POST:ListDefaultColumnSetting"), // 返回默认栏目设置
),
beego.NSNamespace("/common",
beego.NSRouter("/partner", &controllers.CommonController{}, "POST:GetPartnerList"),
... ...
package column_setting
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/astaxie/beego"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
_ "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg"
_ "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/port/beego"
)
func TestColumnSetting(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Beego Port ColumnSetting Correlations Test Case Suite")
}
var handler http.Handler
var server *httptest.Server
var _ = BeforeSuite(func() {
handler = beego.BeeApp.Handlers
server = httptest.NewServer(handler)
})
var _ = AfterSuite(func() {
server.Close()
})
... ...
package column_setting
import (
"net/http"
"github.com/gavv/httpexpect"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg"
)
var _ = Describe("创建栏目设置增删改查", func() {
Describe("提交数据创建栏目设置增删改查", func() {
Context("提交正确的新栏目设置数据", func() {
It("返回栏目设置数据", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
body := map[string]interface{}{
"description": "string",
"userName": "string",
}
httpExpect.POST("/column-settings/").
WithJSON(body).
Expect().
Status(http.StatusOK).
JSON().
Object().
ContainsKey("code").ValueEqual("code", 0).
ContainsKey("msg").ValueEqual("msg", "ok").
ContainsKey("data").Value("data").Object().
ContainsKey("id").ValueNotEqual("id", BeZero())
})
})
})
AfterEach(func() {
_, err := pG.DB.Exec("DELETE FROM column_settings WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...
package column_setting
import (
"net/http"
"github.com/gavv/httpexpect"
"github.com/go-pg/pg"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg"
)
var _ = Describe("返回栏目设置增删改查", func() {
var column_settingId int64
BeforeEach(func() {
_, err := pG.DB.QueryOne(
pg.Scan(&column_settingId),
"INSERT INTO column_settings (column_setting_id, company_id, created_at, description, key, uid, updated_at, user_name, value) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING id",
"testColumnSettingId", "testCompanyId", "testCreatedAt", "testDescription", "testKey", "testUid", "testUpdatedAt", "testUserName", "testValue")
Expect(err).NotTo(HaveOccurred())
})
Describe("根据column_settingId参数返回栏目设置", func() {
Context("传入有效的column_settingId", func() {
It("返回栏目设置数据", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
httpExpect.GET("/column-settings/{columnSettingId}").
Expect().
Status(http.StatusOK).
JSON().
Object().
ContainsKey("code").ValueEqual("code", 0).
ContainsKey("msg").ValueEqual("msg", "ok").
ContainsKey("data").Value("data").Object()
})
})
})
AfterEach(func() {
_, err := pG.DB.Exec("DELETE FROM column_settings WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...
package column_setting
import (
"net/http"
"github.com/gavv/httpexpect"
"github.com/go-pg/pg"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg"
)
var _ = Describe("返回栏目设置增删改查列表", func() {
var column_settingId int64
BeforeEach(func() {
_, err := pG.DB.QueryOne(
pg.Scan(&column_settingId),
"INSERT INTO column_settings (column_setting_id, company_id, created_at, description, key, uid, updated_at, user_name, value) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING id",
"testColumnSettingId", "testCompanyId", "testCreatedAt", "testDescription", "testKey", "testUid", "testUpdatedAt", "testUserName", "testValue")
Expect(err).NotTo(HaveOccurred())
})
Describe("根据参数返回栏目设置列表", func() {
Context("传入有效的参数", func() {
It("返回栏目设置数据列表", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
httpExpect.GET("/column-settings/").
WithQuery("offset", "int").
WithQuery("limit", "int").
Expect().
Status(http.StatusOK).
JSON().
Object().
ContainsKey("code").ValueEqual("code", 0).
ContainsKey("msg").ValueEqual("msg", "ok").
ContainsKey("data").Value("data").Object().
ContainsKey("count").ValueEqual("count", 1).
ContainsKey("column_settings").Value("column_settings").Array()
})
})
})
AfterEach(func() {
_, err := pG.DB.Exec("DELETE FROM column_settings WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...
package column_setting
import (
"net/http"
"github.com/gavv/httpexpect"
"github.com/go-pg/pg"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg"
)
var _ = Describe("移除栏目设置增删改查", func() {
var column_settingId int64
BeforeEach(func() {
_, err := pG.DB.QueryOne(
pg.Scan(&column_settingId),
"INSERT INTO column_settings (column_setting_id, company_id, created_at, description, key, uid, updated_at, user_name, value) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING id",
"testColumnSettingId", "testCompanyId", "testCreatedAt", "testDescription", "testKey", "testUid", "testUpdatedAt", "testUserName", "testValue")
Expect(err).NotTo(HaveOccurred())
})
Describe("根据参数移除栏目设置增删改查", func() {
Context("传入有效的column_settingId", func() {
It("返回被移除栏目设置的数据", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
httpExpect.DELETE("/column-settings/{columnSettingId}").
Expect().
Status(http.StatusOK).
JSON().
Object().
ContainsKey("code").ValueEqual("code", 0).
ContainsKey("msg").ValueEqual("msg", "ok").
ContainsKey("data").Value("data").Object()
})
})
})
AfterEach(func() {
_, err := pG.DB.Exec("DELETE FROM column_settings WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...
package column_setting
import (
"net/http"
"github.com/gavv/httpexpect"
"github.com/go-pg/pg"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg"
)
var _ = Describe("重置栏目设置", func() {
var column_settingId int64
BeforeEach(func() {
_, err := pG.DB.QueryOne(
pg.Scan(&column_settingId),
"INSERT INTO column_settings (column_setting_id, company_id, created_at, description, key, uid, updated_at, user_name, value) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING id",
"testColumnSettingId", "testCompanyId", "testCreatedAt", "testDescription", "testKey", "testUid", "testUpdatedAt", "testUserName", "testValue")
Expect(err).NotTo(HaveOccurred())
})
Describe("重置栏目设置", func() {
Context("", func() {
It("", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
body := map[string]interface{}{}
httpExpect.POST("/column-settings/").
WithJSON(body).
Expect().
Status(http.StatusOK).
JSON().
Object().
ContainsKey("code").ValueEqual("code", 0).
ContainsKey("msg").ValueEqual("msg", "ok").
ContainsKey("data").Value("data").Object()
})
})
})
AfterEach(func() {
_, err := pG.DB.Exec("DELETE FROM column_settings WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...
package column_setting
import (
"net/http"
"github.com/gavv/httpexpect"
"github.com/go-pg/pg"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg"
)
var _ = Describe("更新栏目设置增删改查", func() {
var column_settingId int64
BeforeEach(func() {
_, err := pG.DB.QueryOne(
pg.Scan(&column_settingId),
"INSERT INTO column_settings (column_setting_id, company_id, created_at, description, key, uid, updated_at, user_name, value) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING id",
"testColumnSettingId", "testCompanyId", "testCreatedAt", "testDescription", "testKey", "testUid", "testUpdatedAt", "testUserName", "testValue")
Expect(err).NotTo(HaveOccurred())
})
Describe("提交数据更新栏目设置增删改查", func() {
Context("提交正确的栏目设置数据", func() {
It("返回更新后的栏目设置数据", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
body := map[string]interface{}{}
httpExpect.PUT("/column-settings/{columnSettingId}").
WithJSON(body).
Expect().
Status(http.StatusOK).
JSON().
Object().
ContainsKey("code").ValueEqual("code", 0).
ContainsKey("msg").ValueEqual("msg", "ok").
ContainsKey("data").Value("data").Object().
ContainsKey("id").ValueEqual("id", column_settingId)
})
})
})
AfterEach(func() {
_, err := pG.DB.Exec("DELETE FROM column_settings WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...
validation
==============
validation is a form validation for a data validation and error collecting using Go.
## Installation and tests
Install:
go get github.com/astaxie/beego/validation
Test:
go test github.com/astaxie/beego/validation
## Example
Direct Use:
import (
"github.com/astaxie/beego/validation"
"log"
)
type User struct {
Name string
Age int
}
func main() {
u := User{"man", 40}
valid := validation.Validation{}
valid.Required(u.Name, "name")
valid.MaxSize(u.Name, 15, "nameMax")
valid.Range(u.Age, 0, 140, "age")
if valid.HasErrors() {
// validation does not pass
// print invalid message
for _, err := range valid.Errors {
log.Println(err.Key, err.Message)
}
}
// or use like this
if v := valid.Max(u.Age, 140, "ageMax"); !v.Ok {
log.Println(v.Error.Key, v.Error.Message)
}
}
Struct Tag Use:
import (
"github.com/astaxie/beego/validation"
)
// validation function follow with "valid" tag
// functions divide with ";"
// parameters in parentheses "()" and divide with ","
// Match function's pattern string must in "//"
type user struct {
Id int
Name string `valid:"Required;Match(/^(test)?\\w*@;com$/)"`
Age int `valid:"Required;Range(1, 140)"`
}
func main() {
valid := validation.Validation{}
// ignore empty field valid
// see CanSkipFuncs
// valid := validation.Validation{RequiredFirst:true}
u := user{Name: "test", Age: 40}
b, err := valid.Valid(u)
if err != nil {
// handle error
}
if !b {
// validation does not pass
// blabla...
}
}
Use custom function:
import (
"github.com/astaxie/beego/validation"
)
type user struct {
Id int
Name string `valid:"Required;IsMe"`
Age int `valid:"Required;Range(1, 140)"`
}
func IsMe(v *validation.Validation, obj interface{}, key string) {
name, ok:= obj.(string)
if !ok {
// wrong use case?
return
}
if name != "me" {
// valid false
v.SetError("Name", "is not me!")
}
}
func main() {
valid := validation.Validation{}
if err := validation.AddCustomFunc("IsMe", IsMe); err != nil {
// hadle error
}
u := user{Name: "test", Age: 40}
b, err := valid.Valid(u)
if err != nil {
// handle error
}
if !b {
// validation does not pass
// blabla...
}
}
Struct Tag Functions:
Required
Min(min int)
Max(max int)
Range(min, max int)
MinSize(min int)
MaxSize(max int)
Length(length int)
Alpha
Numeric
AlphaNumeric
Match(pattern string)
AlphaDash
Email
IP
Base64
Mobile
Tel
Phone
ZipCode
## LICENSE
BSD License http://creativecommons.org/licenses/BSD/
... ...
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package validation
import (
"fmt"
"reflect"
"regexp"
"strconv"
"strings"
)
const (
// ValidTag struct tag
ValidTag = "valid"
LabelTag = "label"
wordsize = 32 << (^uint(0) >> 32 & 1)
)
var (
// key: function name
// value: the number of parameters
funcs = make(Funcs)
// doesn't belong to validation functions
unFuncs = map[string]bool{
"Clear": true,
"HasErrors": true,
"ErrorMap": true,
"Error": true,
"apply": true,
"Check": true,
"Valid": true,
"NoMatch": true,
}
// ErrInt64On32 show 32 bit platform not support int64
ErrInt64On32 = fmt.Errorf("not support int64 on 32-bit platform")
)
func init() {
v := &Validation{}
t := reflect.TypeOf(v)
for i := 0; i < t.NumMethod(); i++ {
m := t.Method(i)
if !unFuncs[m.Name] {
funcs[m.Name] = m.Func
}
}
}
// CustomFunc is for custom validate function
type CustomFunc func(v *Validation, obj interface{}, key string)
// AddCustomFunc Add a custom function to validation
// The name can not be:
// Clear
// HasErrors
// ErrorMap
// Error
// Check
// Valid
// NoMatch
// If the name is same with exists function, it will replace the origin valid function
func AddCustomFunc(name string, f CustomFunc) error {
if unFuncs[name] {
return fmt.Errorf("invalid function name: %s", name)
}
funcs[name] = reflect.ValueOf(f)
return nil
}
// ValidFunc Valid function type
type ValidFunc struct {
Name string
Params []interface{}
}
// Funcs Validate function map
type Funcs map[string]reflect.Value
// Call validate values with named type string
func (f Funcs) Call(name string, params ...interface{}) (result []reflect.Value, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("%v", r)
}
}()
if _, ok := f[name]; !ok {
err = fmt.Errorf("%s does not exist", name)
return
}
if len(params) != f[name].Type().NumIn() {
err = fmt.Errorf("The number of params is not adapted")
return
}
in := make([]reflect.Value, len(params))
for k, param := range params {
in[k] = reflect.ValueOf(param)
}
result = f[name].Call(in)
return
}
func isStruct(t reflect.Type) bool {
return t.Kind() == reflect.Struct
}
func isStructPtr(t reflect.Type) bool {
return t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct
}
func getValidFuncs(f reflect.StructField) (vfs []ValidFunc, err error) {
tag := f.Tag.Get(ValidTag)
label := f.Tag.Get(LabelTag)
if len(tag) == 0 {
return
}
if vfs, tag, err = getRegFuncs(tag, f.Name); err != nil {
return
}
fs := strings.Split(tag, ";")
for _, vfunc := range fs {
var vf ValidFunc
if len(vfunc) == 0 {
continue
}
vf, err = parseFunc(vfunc, f.Name, label)
if err != nil {
return
}
vfs = append(vfs, vf)
}
return
}
// Get Match function
// May be get NoMatch function in the future
func getRegFuncs(tag, key string) (vfs []ValidFunc, str string, err error) {
tag = strings.TrimSpace(tag)
index := strings.Index(tag, "Match(/")
if index == -1 {
str = tag
return
}
end := strings.LastIndex(tag, "/)")
if end < index {
err = fmt.Errorf("invalid Match function")
return
}
reg, err := regexp.Compile(tag[index+len("Match(/") : end])
if err != nil {
return
}
vfs = []ValidFunc{{"Match", []interface{}{reg, key + ".Match"}}}
str = strings.TrimSpace(tag[:index]) + strings.TrimSpace(tag[end+len("/)"):])
return
}
func parseFunc(vfunc, key string, label string) (v ValidFunc, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("%v", r)
}
}()
vfunc = strings.TrimSpace(vfunc)
start := strings.Index(vfunc, "(")
var num int
// doesn't need parameter valid function
if start == -1 {
if num, err = numIn(vfunc); err != nil {
return
}
if num != 0 {
err = fmt.Errorf("%s require %d parameters", vfunc, num)
return
}
v = ValidFunc{vfunc, []interface{}{key + "." + vfunc + "." + label}}
return
}
end := strings.Index(vfunc, ")")
if end == -1 {
err = fmt.Errorf("invalid valid function")
return
}
name := strings.TrimSpace(vfunc[:start])
if num, err = numIn(name); err != nil {
return
}
params := strings.Split(vfunc[start+1:end], ",")
// the num of param must be equal
if num != len(params) {
err = fmt.Errorf("%s require %d parameters", name, num)
return
}
tParams, err := trim(name, key+"."+ name + "." + label, params)
if err != nil {
return
}
v = ValidFunc{name, tParams}
return
}
func numIn(name string) (num int, err error) {
fn, ok := funcs[name]
if !ok {
err = fmt.Errorf("doesn't exists %s valid function", name)
return
}
// sub *Validation obj and key
num = fn.Type().NumIn() - 3
return
}
func trim(name, key string, s []string) (ts []interface{}, err error) {
ts = make([]interface{}, len(s), len(s)+1)
fn, ok := funcs[name]
if !ok {
err = fmt.Errorf("doesn't exists %s valid function", name)
return
}
for i := 0; i < len(s); i++ {
var param interface{}
// skip *Validation and obj params
if param, err = parseParam(fn.Type().In(i+2), strings.TrimSpace(s[i])); err != nil {
return
}
ts[i] = param
}
ts = append(ts, key)
return
}
// modify the parameters's type to adapt the function input parameters' type
func parseParam(t reflect.Type, s string) (i interface{}, err error) {
switch t.Kind() {
case reflect.Int:
i, err = strconv.Atoi(s)
case reflect.Int64:
if wordsize == 32 {
return nil, ErrInt64On32
}
i, err = strconv.ParseInt(s, 10, 64)
case reflect.Int32:
var v int64
v, err = strconv.ParseInt(s, 10, 32)
if err == nil {
i = int32(v)
}
case reflect.Int16:
var v int64
v, err = strconv.ParseInt(s, 10, 16)
if err == nil {
i = int16(v)
}
case reflect.Int8:
var v int64
v, err = strconv.ParseInt(s, 10, 8)
if err == nil {
i = int8(v)
}
case reflect.String:
i = s
case reflect.Ptr:
if t.Elem().String() != "regexp.Regexp" {
err = fmt.Errorf("not support %s", t.Elem().String())
return
}
i, err = regexp.Compile(s)
default:
err = fmt.Errorf("not support %s", t.Kind().String())
}
return
}
func mergeParam(v *Validation, obj interface{}, params []interface{}) []interface{} {
return append([]interface{}{v, obj}, params...)
}
... ...
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package validation for validations
//
// import (
// "github.com/astaxie/beego/validation"
// "log"
// )
//
// type User struct {
// Name string
// Age int
// }
//
// func main() {
// u := User{"man", 40}
// valid := validation.Validation{}
// valid.Required(u.Name, "name")
// valid.MaxSize(u.Name, 15, "nameMax")
// valid.Range(u.Age, 0, 140, "age")
// if valid.HasErrors() {
// // validation does not pass
// // print invalid message
// for _, err := range valid.Errors {
// log.Println(err.Key, err.Message)
// }
// }
// // or use like this
// if v := valid.Max(u.Age, 140, "ageMax"); !v.Ok {
// log.Println(v.Error.Key, v.Error.Message)
// }
// }
//
// more info: http://beego.me/docs/mvc/controller/validation.md
package validation
import (
"fmt"
"reflect"
"regexp"
"strings"
)
// ValidFormer valid interface
type ValidFormer interface {
Valid(*Validation)
}
// Error show the error
type Error struct {
Message, Key, Name, Field, Tmpl string
Value interface{}
LimitValue interface{}
}
// String Returns the Message.
func (e *Error) String() string {
if e == nil {
return ""
}
return e.Message
}
// Implement Error interface.
// Return e.String()
func (e *Error) Error() string { return e.String() }
// Result is returned from every validation method.
// It provides an indication of success, and a pointer to the Error (if any).
type Result struct {
Error *Error
Ok bool
}
// Key Get Result by given key string.
func (r *Result) Key(key string) *Result {
if r.Error != nil {
r.Error.Key = key
}
return r
}
// Message Set Result message by string or format string with args
func (r *Result) Message(message string, args ...interface{}) *Result {
if r.Error != nil {
if len(args) == 0 {
r.Error.Message = message
} else {
r.Error.Message = fmt.Sprintf(message, args...)
}
}
return r
}
// A Validation context manages data validation and error messages.
type Validation struct {
// if this field set true, in struct tag valid
// if the struct field vale is empty
// it will skip those valid functions, see CanSkipFuncs
RequiredFirst bool
Errors []*Error
ErrorsMap map[string][]*Error
}
// Clear Clean all ValidationError.
func (v *Validation) Clear() {
v.Errors = []*Error{}
v.ErrorsMap = nil
}
// HasErrors Has ValidationError nor not.
func (v *Validation) HasErrors() bool {
return len(v.Errors) > 0
}
// ErrorMap Return the errors mapped by key.
// If there are multiple validation errors associated with a single key, the
// first one "wins". (Typically the first validation will be the more basic).
func (v *Validation) ErrorMap() map[string][]*Error {
return v.ErrorsMap
}
// Error Add an error to the validation context.
func (v *Validation) Error(message string, args ...interface{}) *Result {
result := (&Result{
Ok: false,
Error: &Error{},
}).Message(message, args...)
v.Errors = append(v.Errors, result.Error)
return result
}
// Required Test that the argument is non-nil and non-empty (if string or list)
func (v *Validation) Required(obj interface{}, key string) *Result {
return v.apply(Required{key}, obj)
}
// Min Test that the obj is greater than min if obj's type is int
func (v *Validation) Min(obj interface{}, min int, key string) *Result {
return v.apply(Min{min, key}, obj)
}
// Max Test that the obj is less than max if obj's type is int
func (v *Validation) Max(obj interface{}, max int, key string) *Result {
return v.apply(Max{max, key}, obj)
}
// Range Test that the obj is between mni and max if obj's type is int
func (v *Validation) Range(obj interface{}, min, max int, key string) *Result {
return v.apply(Range{Min{Min: min}, Max{Max: max}, key}, obj)
}
// MinSize Test that the obj is longer than min size if type is string or slice
func (v *Validation) MinSize(obj interface{}, min int, key string) *Result {
return v.apply(MinSize{min, key}, obj)
}
// MaxSize Test that the obj is shorter than max size if type is string or slice
func (v *Validation) MaxSize(obj interface{}, max int, key string) *Result {
return v.apply(MaxSize{max, key}, obj)
}
// Length Test that the obj is same length to n if type is string or slice
func (v *Validation) Length(obj interface{}, n int, key string) *Result {
return v.apply(Length{n, key}, obj)
}
// Alpha Test that the obj is [a-zA-Z] if type is string
func (v *Validation) Alpha(obj interface{}, key string) *Result {
return v.apply(Alpha{key}, obj)
}
// Numeric Test that the obj is [0-9] if type is string
func (v *Validation) Numeric(obj interface{}, key string) *Result {
return v.apply(Numeric{key}, obj)
}
// AlphaNumeric Test that the obj is [0-9a-zA-Z] if type is string
func (v *Validation) AlphaNumeric(obj interface{}, key string) *Result {
return v.apply(AlphaNumeric{key}, obj)
}
// Match Test that the obj matches regexp if type is string
func (v *Validation) Match(obj interface{}, regex *regexp.Regexp, key string) *Result {
return v.apply(Match{regex, key}, obj)
}
// NoMatch Test that the obj doesn't match regexp if type is string
func (v *Validation) NoMatch(obj interface{}, regex *regexp.Regexp, key string) *Result {
return v.apply(NoMatch{Match{Regexp: regex}, key}, obj)
}
// AlphaDash Test that the obj is [0-9a-zA-Z_-] if type is string
func (v *Validation) AlphaDash(obj interface{}, key string) *Result {
return v.apply(AlphaDash{NoMatch{Match: Match{Regexp: alphaDashPattern}}, key}, obj)
}
// Email Test that the obj is email address if type is string
func (v *Validation) Email(obj interface{}, key string) *Result {
return v.apply(Email{Match{Regexp: emailPattern}, key}, obj)
}
// IP Test that the obj is IP address if type is string
func (v *Validation) IP(obj interface{}, key string) *Result {
return v.apply(IP{Match{Regexp: ipPattern}, key}, obj)
}
// Base64 Test that the obj is base64 encoded if type is string
func (v *Validation) Base64(obj interface{}, key string) *Result {
return v.apply(Base64{Match{Regexp: base64Pattern}, key}, obj)
}
// Mobile Test that the obj is chinese mobile number if type is string
func (v *Validation) Mobile(obj interface{}, key string) *Result {
return v.apply(Mobile{Match{Regexp: mobilePattern}, key}, obj)
}
// Tel Test that the obj is chinese telephone number if type is string
func (v *Validation) Tel(obj interface{}, key string) *Result {
return v.apply(Tel{Match{Regexp: telPattern}, key}, obj)
}
// Phone Test that the obj is chinese mobile or telephone number if type is string
func (v *Validation) Phone(obj interface{}, key string) *Result {
return v.apply(Phone{Mobile{Match: Match{Regexp: mobilePattern}},
Tel{Match: Match{Regexp: telPattern}}, key}, obj)
}
// ZipCode Test that the obj is chinese zip code if type is string
func (v *Validation) ZipCode(obj interface{}, key string) *Result {
return v.apply(ZipCode{Match{Regexp: zipCodePattern}, key}, obj)
}
func (v *Validation) apply(chk Validator, obj interface{}) *Result {
if nil == obj {
if chk.IsSatisfied(obj) {
return &Result{Ok: true}
}
} else if reflect.TypeOf(obj).Kind() == reflect.Ptr {
if reflect.ValueOf(obj).IsNil() {
if chk.IsSatisfied(nil) {
return &Result{Ok: true}
}
} else {
if chk.IsSatisfied(reflect.ValueOf(obj).Elem().Interface()) {
return &Result{Ok: true}
}
}
} else if chk.IsSatisfied(obj) {
return &Result{Ok: true}
}
// Add the error to the validation context.
key := chk.GetKey()
Name := key
Field := ""
Label := ""
parts := strings.Split(key, ".")
if len(parts) == 3 {
Field = parts[0]
Name = parts[1]
Label = parts[2]
if len(Label) == 0 {
Label = Field
}
}
err := &Error{
Message: Label + " " + chk.DefaultMessage(),
Key: key,
Name: Name,
Field: Field,
Value: obj,
Tmpl: MessageTmpls[Name],
LimitValue: chk.GetLimitValue(),
}
v.setError(err)
// Also return it in the result.
return &Result{
Ok: false,
Error: err,
}
}
// key must like aa.bb.cc or aa.bb.
// AddError adds independent error message for the provided key
func (v *Validation) AddError(key, message string) {
Name := key
Field := ""
Label := ""
parts := strings.Split(key, ".")
if len(parts) == 3 {
Field = parts[0]
Name = parts[1]
Label = parts[2]
if len(Label) == 0 {
Label = Field
}
}
err := &Error{
Message: Label + " " + message,
Key: key,
Name: Name,
Field: Field,
}
v.setError(err)
}
func (v *Validation) setError(err *Error) {
v.Errors = append(v.Errors, err)
if v.ErrorsMap == nil {
v.ErrorsMap = make(map[string][]*Error)
}
if _, ok := v.ErrorsMap[err.Field]; !ok {
v.ErrorsMap[err.Field] = []*Error{}
}
v.ErrorsMap[err.Field] = append(v.ErrorsMap[err.Field], err)
}
// SetError Set error message for one field in ValidationError
func (v *Validation) SetError(fieldName string, errMsg string) *Error {
err := &Error{Key: fieldName, Field: fieldName, Tmpl: errMsg, Message: errMsg}
v.setError(err)
return err
}
// Check Apply a group of validators to a field, in order, and return the
// ValidationResult from the first one that fails, or the last one that
// succeeds.
func (v *Validation) Check(obj interface{}, checks ...Validator) *Result {
var result *Result
for _, check := range checks {
result = v.apply(check, obj)
if !result.Ok {
return result
}
}
return result
}
// Valid Validate a struct.
// the obj parameter must be a struct or a struct pointer
func (v *Validation) Valid(obj interface{}) (b bool, err error) {
objT := reflect.TypeOf(obj)
objV := reflect.ValueOf(obj)
switch {
case isStruct(objT):
case isStructPtr(objT):
objT = objT.Elem()
objV = objV.Elem()
default:
err = fmt.Errorf("%v must be a struct or a struct pointer", obj)
return
}
for i := 0; i < objT.NumField(); i++ {
var vfs []ValidFunc
if vfs, err = getValidFuncs(objT.Field(i)); err != nil {
return
}
var hasRequired bool
for _, vf := range vfs {
if vf.Name == "Required" {
hasRequired = true
}
currentField := objV.Field(i).Interface()
if objV.Field(i).Kind() == reflect.Ptr {
if objV.Field(i).IsNil() {
currentField = ""
} else {
currentField = objV.Field(i).Elem().Interface()
}
}
chk := Required{""}.IsSatisfied(currentField)
if !hasRequired && v.RequiredFirst && !chk {
if _, ok := CanSkipFuncs[vf.Name]; ok {
continue
}
}
if _, err = funcs.Call(vf.Name,
mergeParam(v, objV.Field(i).Interface(), vf.Params)...); err != nil {
return
}
}
}
if !v.HasErrors() {
if form, ok := obj.(ValidFormer); ok {
form.Valid(v)
}
}
return !v.HasErrors(), nil
}
// RecursiveValid Recursively validate a struct.
// Step1: Validate by v.Valid
// Step2: If pass on step1, then reflect obj's fields
// Step3: Do the Recursively validation to all struct or struct pointer fields
func (v *Validation) RecursiveValid(objc interface{}) (bool, error) {
//Step 1: validate obj itself firstly
// fails if objc is not struct
pass, err := v.Valid(objc)
if err != nil || !pass {
return pass, err // Stop recursive validation
}
// Step 2: Validate struct's struct fields
objT := reflect.TypeOf(objc)
objV := reflect.ValueOf(objc)
if isStructPtr(objT) {
objT = objT.Elem()
objV = objV.Elem()
}
for i := 0; i < objT.NumField(); i++ {
t := objT.Field(i).Type
// Recursive applies to struct or pointer to structs fields
if isStruct(t) || isStructPtr(t) {
// Step 3: do the recursive validation
// Only valid the Public field recursively
if objV.Field(i).CanInterface() {
pass, err = v.RecursiveValid(objV.Field(i).Interface())
}
}
}
return pass, err
}
func (v *Validation) CanSkipAlso(skipFunc string) {
if _, ok := CanSkipFuncs[skipFunc]; !ok {
CanSkipFuncs[skipFunc] = struct{}{}
}
}
... ...