作者 tangxvhui

新建项目

正在显示 57 个修改的文件 包含 2359 行增加0 行删除
# Binaries for programs and plugins
*.exe
*.dll
*.so
*.dylib
*.vscode
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
*.log
*debug
*wasm
*.idea
*.tmp
*.sum
opp
/vendor
/*.exe~
/log
... ...
FROM golang:latest
ENV APP_DIR $GOPATH/src/partnermg
RUN mkdir -p $APP_DIR
WORKDIR $APP_DIR/
COPY ./pkg pkg
COPY ./conf conf
COPY ./go.mod go.mod
COPY ./main.go main.go
RUN ["ln","-sf","/usr/share/zoneinfo/Asia/Shanghai","/etc/localtime"]
ENV GO111MODULE on
ENV GOPROXY https://goproxy.cn
RUN ["go","mod","tidy"]
RUN ["go","build"]
ENTRYPOINT ["./partnermg"]
\ No newline at end of file
... ...
# 合伙人项目
\ No newline at end of file
... ...
appname = partner
runmode = "${RUN_MODE||dev}"
httpport = "${HTTP_PORT||8080}"
#开启监控
EnableAdmin = false
#开启JSON请求
copyrequestbody = true
#防止跨站请求伪造 未启用
enablexsrf = false
xsrfkey = asdfioerjlasdfmFADFOEJF2323SDFF
xsrfexpire = 3600
[lang]
types = en-US|zh-CN
names = English|简体中文
\ No newline at end of file
... ...
#!/bin/bash
export PATH=/root/local/bin:$PATH
kubectl -n mmm-suplus-dev get pods | grep -q partner
if [ "$?" == "1" ];then
kubectl create -f /tmp/dev/partner/partner.yaml --record
kubectl -n mmm-suplus-dev get svc | grep -q partner
if [ "$?" == "0" ];then
echo "partner service install success!"
else
echo "partner service install fail!"
fi
kubectl -n mmm-suplus-dev get pods | grep -q partner
if [ "$?" == "0" ];then
echo "partner deployment install success!"
else
echo "partner deployment install fail!"
fi
else
kubectl delete -f /tmp/dev/partner/partner.yaml
kubectl -n mmm-suplus-dev get svc | grep -q partner
while [ "$?" == "0" ]
do
kubectl -n mmm-suplus-dev get svc | grep -q partner
done
kubectl -n mmm-suplus-dev get pods | grep -q partner
while [ "$?" == "0" ]
do
kubectl -n mmm-suplus-dev get pods | grep -q partner
done
kubectl create -f /tmp/dev/partner/partner.yaml --record
kubectl -n mmm-suplus-dev get svc | grep -q partner
if [ "$?" == "0" ];then
echo "partner service update success!"
else
echo "partner service update fail!"
fi
kubectl -n mmm-suplus-dev get pods | grep -q partner
if [ "$?" == "0" ];then
echo "partner deployment update success!"
else
echo "partner deployment update fail!"
fi
fi
\ No newline at end of file
... ...
apiVersion: v1
kind: Service
metadata:
name: partner
namespace: mmm-suplus-dev
labels:
k8s-app: partner
spec:
ports:
- name: "http"
port: 80
targetPort: 8082
selector:
k8s-app: partner
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: partner
namespace: mmm-suplus-dev
labels:
k8s-app: partner
spec:
replicas: 1
template:
metadata:
labels:
k8s-app: partner
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- preference: {}
weight: 100
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- cn-hangzhou.i-bp1djh1xn7taumbue1ze
- cn-hangzhou.i-bp1djh1xn7taumbue1zd
- cn-hangzhou.i-bp1euf5u1ph9kbhtndhb
- cn-hangzhou.i-bp1hyp5oips9cdwxxgxy
containers:
- name: partner
image: 192.168.0.243:5000/mmm/partner:dev
imagePullPolicy: Always
ports:
- containerPort: 8082
volumeMounts:
- mountPath: /opt/logs
name: accesslogs
env:
- name: POSTGRESQL_DB_NAME
value: "partner_dev"
- name: POSTGRESQL_USER
value: "postgres"
- name: POSTGRESQL_PASSWORD
value: "postgres_15432"
- name: POSTGRESQL_HOST
value: "101.37.68.23"
- name: POSTGRESQL_PORT
value: "15432"
- name: LOG_LEVEL
value: "debug"
- name: ERROR_BASE_CODE
value: "1"
- name: ERROR_BASE_CODE_MULTIPLE
value: "1000"
- name: ABILITY_SERVICE_HOST
value: "https://suplus-worth-app-gateway-dev.fjmaimaimai.com"
- name: MMM_OPEN_API_SERVICE_HOST
value: "http://mmm-open-api-dev.fjmaimaimai.com"
volumes:
- name: accesslogs
emptyDir: {}
\ No newline at end of file
... ...
#!/bin/bash
export PATH=/root/local/bin:$PATH
kubectl -n mmm-suplus-prd get pods | grep -q partner
if [ "$?" == "1" ];then
kubectl create -f /tmp/prd/partner/partner.yaml --record
kubectl -n mmm-suplus-prd get svc | grep -q partner
if [ "$?" == "0" ];then
echo "partner service install success!"
else
echo "partner service install fail!"
fi
kubectl -n mmm-suplus-prd get pods | grep -q partner
if [ "$?" == "0" ];then
echo "partner deployment install success!"
else
echo "partner deployment install fail!"
fi
else
kubectl delete -f /tmp/prd/partner/partner.yaml
kubectl -n mmm-suplus-prd get svc | grep -q partner
while [ "$?" == "0" ]
do
kubectl -n mmm-suplus-prd get svc | grep -q partner
done
kubectl -n mmm-suplus-prd get pods | grep -q partner
while [ "$?" == "0" ]
do
kubectl -n mmm-suplus-prd get pods | grep -q partner
done
kubectl create -f /tmp/prd/partner/partner.yaml --record
kubectl -n mmm-suplus-prd get svc | grep -q partner
if [ "$?" == "0" ];then
echo "partner service update success!"
else
echo "partner service update fail!"
fi
kubectl -n mmm-suplus-prd get pods | grep -q partner
if [ "$?" == "0" ];then
echo "partner deployment update success!"
else
echo "partner deployment update fail!"
fi
fi
\ No newline at end of file
... ...
apiVersion: v1
kind: Service
metadata:
name: partner
namespace: mmm-suplus-prd
labels:
k8s-app: partner
spec:
ports:
- name: "http"
port: 80
targetPort: 8082
selector:
k8s-app: partner
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: partner
namespace: mmm-suplus-prd
labels:
k8s-app: partner
spec:
replicas: 1
template:
metadata:
labels:
k8s-app: partner
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- preference: {}
weight: 100
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- cn-hangzhou.i-bp1djh1xn7taumbue1ze
- cn-hangzhou.i-bp1djh1xn7taumbue1zd
- cn-hangzhou.i-bp1euf5u1ph9kbhtndhb
- cn-hangzhou.i-bp1hyp5oips9cdwxxgxy
containers:
- name: partner
image: 192.168.0.243:5000/mmm/partner:master
imagePullPolicy: Always
ports:
- containerPort: 8082
volumeMounts:
- mountPath: /opt/logs
name: accesslogs
env:
- name: POSTGRESQL_DB_NAME
value: "partner"
- name: POSTGRESQL_USER
value: "postgres"
- name: POSTGRESQL_PASSWORD
value: "postgres_55_online"
- name: POSTGRESQL_HOST
value: "112.124.115.55"
- name: POSTGRESQL_PORT
value: "15432"
- name: LOG_LEVEL
value: "debug"
- name: ERROR_BASE_CODE
value: "1"
- name: ERROR_BASE_CODE_MULTIPLE
value: "1000"
- name: ABILITY_SERVICE_HOST
value: "https://ability.fjmaimaimai.com"
- name: MMM_OPEN_API_SERVICE_HOST
value: "https://public-interface.fjmaimaimai.com/openapi"
volumes:
- name: accesslogs
emptyDir: {}
\ No newline at end of file
... ...
#!/bin/bash
export PATH=/root/local/bin:$PATH
kubectl -n mmm-suplus-test get pods | grep -q partner
if [ "$?" == "1" ];then
kubectl create -f /tmp/test/partner/partner.yaml --record
kubectl -n mmm-suplus-test get svc | grep -q partner
if [ "$?" == "0" ];then
echo "partner service install success!"
else
echo "partner service install fail!"
fi
kubectl -n mmm-suplus-test get pods | grep -q partner
if [ "$?" == "0" ];then
echo "partner deployment install success!"
else
echo "partner deployment install fail!"
fi
else
kubectl delete -f /tmp/test/partner/partner.yaml
kubectl -n mmm-suplus-test get svc | grep -q partner
while [ "$?" == "0" ]
do
kubectl -n mmm-suplus-test get svc | grep -q partner
done
kubectl -n mmm-suplus-test get pods | grep -q partner
while [ "$?" == "0" ]
do
kubectl -n mmm-suplus-test get pods | grep -q partner
done
kubectl create -f /tmp/test/partner/partner.yaml --record
kubectl -n mmm-suplus-test get svc | grep -q partner
if [ "$?" == "0" ];then
echo "partner service update success!"
else
echo "partner service update fail!"
fi
kubectl -n mmm-suplus-test get pods | grep -q partner
if [ "$?" == "0" ];then
echo "partner deployment update success!"
else
echo "partner deployment update fail!"
fi
fi
\ No newline at end of file
... ...
apiVersion: v1
kind: Service
metadata:
name: partner
namespace: mmm-suplus-test
labels:
k8s-app: partner
spec:
ports:
- name: "http"
port: 80
targetPort: 8082
selector:
k8s-app: partner
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: partner
namespace: mmm-suplus-test
labels:
k8s-app: partner
spec:
replicas: 1
template:
metadata:
labels:
k8s-app: partner
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- preference: {}
weight: 100
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- cn-hangzhou.i-bp1djh1xn7taumbue1ze
- cn-hangzhou.i-bp1djh1xn7taumbue1zd
- cn-hangzhou.i-bp1euf5u1ph9kbhtndhb
- cn-hangzhou.i-bp1hyp5oips9cdwxxgxy
containers:
- name: partner
image: 192.168.0.243:5000/mmm/partner:test
imagePullPolicy: Always
ports:
- containerPort: 8082
volumeMounts:
- mountPath: /opt/logs
name: accesslogs
env:
- name: POSTGRESQL_DB_NAME
value: "partner_test"
- name: POSTGRESQL_USER
value: "postgres"
- name: POSTGRESQL_PASSWORD
value: "postgres_15432"
- name: POSTGRESQL_HOST
value: "101.37.68.23"
- name: POSTGRESQL_PORT
value: "15432"
- name: LOG_LEVEL
value: "debug"
- name: ERROR_BASE_CODE
value: "1"
- name: ERROR_BASE_CODE_MULTIPLE
value: "1000"
- name: ABILITY_SERVICE_HOST
value: "https://suplus-worth-app-gateway-test.fjmaimaimai.com"
- name: MMM_OPEN_API_SERVICE_HOST
value: "http://mmm-open-api-test.fjmaimaimai.com"
volumes:
- name: accesslogs
emptyDir: {}
\ No newline at end of file
... ...
module gitlab.fjmaimaimai.com/mmm-go/partnermg
go 1.14
require (
github.com/ajg/form v1.5.1 // indirect
github.com/astaxie/beego v1.12.1
github.com/dgrijalva/jwt-go v3.2.0+incompatible
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/v10 v10.0.0-beta.2
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/mattn/go-colorable v0.1.6 // indirect
github.com/moul/http2curl v1.0.0 // indirect
github.com/onsi/ginkgo v1.13.0
github.com/onsi/gomega v1.10.1
github.com/prometheus/common v0.10.0
github.com/sergi/go-diff v1.1.0 // indirect
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/valyala/fasthttp v1.14.0 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect
github.com/yudai/gojsondiff v1.0.0 // indirect
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
github.com/yudai/pp v2.0.1+incompatible // indirect
)
... ...
package main
import (
"github.com/astaxie/beego"
"github.com/astaxie/beego/logs"
_ "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg"
_ "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/log"
_ "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/port/beego"
)
func main() {
logs.Info("应用启动")
beego.Run()
}
... ...
package query
type GetAdminUserQuery struct {
Id int64 `json:"id"`
Admin_Account string `json:"admin_account"`
}
... ...
package query
//ListAdminUserQuery 获取用户列表
type ListAdminUserQuery struct {
//账号匹配
AdminAccountMatch string `json:"admin_account_match" form:"account_match"`
// 查询偏离量
Offset int `json:"offset" form:"offset"`
// 查询限制
Limit int `json:"limit" form:"limit"`
}
... ...
package service
import (
"github.com/linmadan/egglib-go/core/application"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/adminUser/query"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
)
//AdminUserService 管理员相关服务
type AdminUserService struct {
}
func NewAdminUserService(option map[string]interface{}) *AdminUserService {
newAdminUserService := new(AdminUserService)
return newAdminUserService
}
func (adminUserSrv AdminUserService) GetAdminUser(getAdminUserQuery *query.GetAdminUserQuery) (interface{}, error) {
//实际业务
var err error
if err != nil {
return nil, application.ThrowError(application.BUSINESS_ERROR, "业务逻辑错误")
}
return domain.AdminUser{}, nil
}
... ...
package factory
//func CreateTaskDao(options map[string]interface{}) (*dao.TaskDao, error) {
// var transactionContext *pg.TransactionContext
// if value, ok := options["transactionContext"]; ok {
// transactionContext = value.(*pg.TransactionContext)
// }
// return dao.NewTaskDao(transactionContext)
//}
... ...
package factory
import (
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/transaction"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/repository"
)
//CreatePartnerInfoRepository 合伙人信息
func CreatePartnerInfoRepository(options map[string]interface{}) (domain.PartnerInfoRepository, error) {
var transactionContext *transaction.TransactionContext
if value, ok := options["transactionContext"]; ok {
transactionContext = value.(*transaction.TransactionContext)
}
return repository.NewPartnerInfoRepository(transactionContext)
}
//CreateAdminUserRepository 管理员信息
func CreateAdminUserRepository(options map[string]interface{}) (domain.AdminUserRepository, error) {
var transactionContext *transaction.TransactionContext
if value, ok := options["transactionContext"]; ok {
transactionContext = value.(*transaction.TransactionContext)
}
return repository.NewAdminUserRepository(transactionContext)
}
... ...
package factory
import (
"github.com/linmadan/egglib-go/core/application"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/transaction"
)
func CreateTransactionContext(options map[string]interface{}) (application.TransactionContext, error) {
return &transaction.TransactionContext{
PgDd: pg.DB,
}, nil
}
... ...
package command
import (
"fmt"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
"github.com/astaxie/beego/validation"
)
type CreatePartnerInfoCommand struct {
domain.PartnerInfo
}
func (c *CreatePartnerInfoCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(c)
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 RemovePartnerInfoCommand struct {
// 合伙人ID
Id int `json:"id" valid:"Required"`
}
func (c *RemovePartnerInfoCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(c)
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"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
)
type UpdatePartnerInfoCommand struct {
// 合伙人Id
Id int `json:"id,omitempty"`
// 合伙人姓名
PartnerName string `json:"partnerName,omitempty"`
// 登录账号
Account string `json:"account,omitempty"`
// 登录密码
Password string `json:"password,omitempty"`
// 状态(1:启用或者0:禁用)
Status int `json:"status"`
// 合伙类别 (1.研发合伙人 2.业务合伙人 3.事业)
PartnerCategory int `json:"partnerCategory,omitempty"`
//关联业务员
Salesman []*domain.Salesman `json:"salesman,omitempty"`
}
func (c *UpdatePartnerInfoCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(c)
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 GetPartnerInfoQuery struct {
// 合伙人ID
Id int `json:"id" valid:"Required"`
}
func (q *GetPartnerInfoQuery) ValidateQuery() error {
valid := validation.Validation{}
b, err := valid.Valid(q)
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 ListPartnerInfoQuery struct {
//状态
Status int `json:"status,omitempty"`
// 合伙人类别
PartnerCategory int `json:"partnerCategory,omitempty"`
//按创建任务时间排序(ASC,DESC)
SortByCreateTime string `json:"sortByCreateTime,omitempty"`
//按创建任务时间排序(ASC,DESC)
SortByUpdateTime string `json:"sortByUpdateTime,omitempty"`
// 查询偏离量
Offset int `json:"offset,omitempty"`
// 查询限制
Limit int `json:"limit,omitempty"`
}
func (q *ListPartnerInfoQuery) ValidateQuery() error {
valid := validation.Validation{}
b, err := valid.Valid(q)
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/factory"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/partnerInfo/command"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/partnerInfo/query"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
"time"
)
// 客户价值服务
type PartnerInfoService struct {
}
// 创建客户价值
func (PartnerInfoService *PartnerInfoService) CreatePartnerInfo(command *command.CreatePartnerInfoCommand) (data interface{}, err error) {
var (
count int64
transactionContext, _ = factory.CreateTransactionContext(nil)
)
if err = command.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
if err = transactionContext.StartTransaction(); err != nil {
return nil, err
}
defer func() {
if err != nil {
transactionContext.RollbackTransaction()
}
}()
newPartnerInfo := &command.PartnerInfo
newPartnerInfo.CreateAt = time.Now()
newPartnerInfo.UpdateAt = time.Now()
var PartnerInfoRepository domain.PartnerInfoRepository
if PartnerInfoRepository, err = factory.CreatePartnerInfoRepository(map[string]interface{}{"transactionContext": transactionContext}); err != nil {
return nil, err
}
if count, _, err = PartnerInfoRepository.Find(map[string]interface{}{"account": command.Account}); err != nil {
return nil, err
}
if count > 0 {
return nil, fmt.Errorf("标签不可重复名称")
}
if data, err = PartnerInfoRepository.Save(newPartnerInfo); err != nil {
return
}
err = transactionContext.CommitTransaction()
return
}
// 返回客户价值
func (PartnerInfoService *PartnerInfoService) GetPartnerInfo(command *query.GetPartnerInfoQuery) (data interface{}, err error) {
var (
transactionContext, _ = factory.CreateTransactionContext(nil)
)
if err = command.ValidateQuery(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, err
}
defer func() {
if err != nil {
transactionContext.RollbackTransaction()
}
}()
var PartnerInfoRepository domain.PartnerInfoRepository
if PartnerInfoRepository, err = factory.CreatePartnerInfoRepository(map[string]interface{}{"transactionContext": transactionContext}); err != nil {
return nil, err
}
data, err = PartnerInfoRepository.FindOne(map[string]interface{}{"Id": command.Id})
if err != nil {
return nil, err
}
if data == nil {
return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(command.Id)))
}
err = transactionContext.CommitTransaction()
return
}
// 更新客户价值
func (PartnerInfoService *PartnerInfoService) UpdatePartnerInfo(updatePartnerInfoCommand *command.UpdatePartnerInfoCommand) (data interface{}, err error) {
var (
transactionContext, _ = factory.CreateTransactionContext(nil)
PartnerInfo *domain.PartnerInfo
)
if err = updatePartnerInfoCommand.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, err
}
defer func() {
if err != nil {
transactionContext.RollbackTransaction()
}
}()
var PartnerInfoRepository domain.PartnerInfoRepository
if PartnerInfoRepository, err = factory.CreatePartnerInfoRepository(map[string]interface{}{"transactionContext": transactionContext}); err != nil {
return nil, err
}
PartnerInfo, err = PartnerInfoRepository.FindOne(map[string]interface{}{"Id": updatePartnerInfoCommand.Id})
if err != nil {
return nil, err
}
if PartnerInfo == nil {
return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(updatePartnerInfoCommand.Id)))
}
//if count, PartnerInfos, err := PartnerInfoRepository.Find(map[string]interface{}{
// "PartnerInfoName": updatePartnerInfoCommand.PartnerInfoName,
// "companyId": PartnerInfo.CompanyId,
//}); err != nil {
// return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
//} else {
// if count > 0 && PartnerInfos[0].PartnerInfoId != PartnerInfo.PartnerInfoId {
// return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "标签不可重复名称")
// }
//}
if err := PartnerInfo.Update(tool_funs.SimpleStructToMap(updatePartnerInfoCommand)); err != nil {
return nil, err
}
if data, err = PartnerInfoRepository.Save(PartnerInfo); err != nil {
return nil, err
}
err = transactionContext.CommitTransaction()
return
}
// 移除客户价值
func (PartnerInfoService *PartnerInfoService) RemovePartnerInfo(removePartnerInfoCommand *command.RemovePartnerInfoCommand) (data interface{}, err error) {
var (
transactionContext, _ = factory.CreateTransactionContext(nil)
PartnerInfo *domain.PartnerInfo
)
if err = removePartnerInfoCommand.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
if err = transactionContext.StartTransaction(); err != nil {
return nil, err
}
defer func() {
if err != nil {
transactionContext.RollbackTransaction()
}
}()
var PartnerInfoRepository domain.PartnerInfoRepository
if PartnerInfoRepository, err = factory.CreatePartnerInfoRepository(map[string]interface{}{"transactionContext": transactionContext}); err != nil {
return nil, err
}
PartnerInfo, err = PartnerInfoRepository.FindOne(map[string]interface{}{"Id": removePartnerInfoCommand.Id})
if err != nil {
return nil, err
}
if PartnerInfo == nil {
return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removePartnerInfoCommand.Id)))
}
if data, err = PartnerInfoRepository.Remove(PartnerInfo); err != nil {
return nil, err
}
err = transactionContext.CommitTransaction()
return
}
// 返回客户价值列表
func (PartnerInfoService *PartnerInfoService) ListPartnerInfo(listPartnerInfoQuery *query.ListPartnerInfoQuery) (data interface{}, err error) {
var (
transactionContext, _ = factory.CreateTransactionContext(nil)
PartnerInfos []*domain.PartnerInfo
count int64
)
if err = listPartnerInfoQuery.ValidateQuery(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, err
}
defer func() {
if err != nil {
transactionContext.RollbackTransaction()
}
}()
var PartnerInfoRepository domain.PartnerInfoRepository
if PartnerInfoRepository, err = factory.CreatePartnerInfoRepository(map[string]interface{}{"transactionContext": transactionContext}); err != nil {
return nil, err
}
if count, PartnerInfos, err = PartnerInfoRepository.Find(tool_funs.SimpleStructToMap(listPartnerInfoQuery)); err != nil {
return nil, err
}
if err = transactionContext.CommitTransaction(); err != nil {
return nil, err
}
return map[string]interface{}{
"count": count,
"partnerInfos": PartnerInfos,
}, nil
}
func NewPartnerInfoService(options map[string]interface{}) *PartnerInfoService {
newPartnerInfoService := &PartnerInfoService{}
return newPartnerInfoService
}
... ...
package constant
import "os"
const SERVICE_NAME = "partnermg"
var LOG_LEVEL = "debug"
var LOG_File = "app.log"
func init() {
if os.Getenv("LOG_LEVEL") != "" {
LOG_LEVEL = os.Getenv("LOG_LEVEL")
}
}
... ...
package constant
import "os"
var POSTGRESQL_DB_NAME = "partner_dev"
var POSTGRESQL_USER = "postgres"
var POSTGRESQL_PASSWORD = "postgres_15432"
var POSTGRESQL_HOST = "101.37.68.23"
var POSTGRESQL_PORT = "15432"
var DISABLE_CREATE_TABLE = true
var DISABLE_SQL_GENERATE_PRINT = false
func init() {
if os.Getenv("POSTGRESQL_DB_NAME") != "" {
POSTGRESQL_DB_NAME = os.Getenv("POSTGRESQL_DB_NAME")
}
if os.Getenv("POSTGRESQL_USER") != "" {
POSTGRESQL_USER = os.Getenv("POSTGRESQL_USER")
}
if os.Getenv("POSTGRESQL_PASSWORD") != "" {
POSTGRESQL_PASSWORD = os.Getenv("POSTGRESQL_PASSWORD")
}
if os.Getenv("POSTGRESQL_HOST") != "" {
POSTGRESQL_HOST = os.Getenv("POSTGRESQL_HOST")
}
if os.Getenv("POSTGRESQL_PORT") != "" {
POSTGRESQL_PORT = os.Getenv("POSTGRESQL_PORT")
}
if os.Getenv("DISABLE_CREATE_TABLE") != "" {
DISABLE_CREATE_TABLE = true
}
if os.Getenv("DISABLE_SQL_GENERATE_PRINT") != "" {
DISABLE_SQL_GENERATE_PRINT = true
}
}
... ...
package domain
//权限代码
const (
PERMINSSION_ADMIN_USER string = "ADMIN_USER"
PERMINSSION_PARTNER string = "PARTNER"
)
//权限数据
var ConstAdminPermissions = map[string]AdminPermission{
PERMINSSION_ADMIN_USER: AdminPermission{
Code: PERMINSSION_ADMIN_USER,
Name: "管理员管理",
},
PERMINSSION_PARTNER: AdminPermission{
Code: PERMINSSION_PARTNER,
Name: "合伙人管理",
},
}
// 权限结构
type AdminPermission struct {
Code string `json:"code"`
Name string `json:"name"`
}
func (permission AdminPermission) GetPermissions(codes []string) []AdminPermission {
newPermissions := []AdminPermission{}
if len(codes) == 0 {
return newPermissions
}
for i := range codes {
code := codes[i]
if _, ok := ConstAdminPermissions[code]; ok {
newPermissions = append(newPermissions, ConstAdminPermissions[code])
}
}
return newPermissions
}
... ...
package domain
//AdminUser 管理员
type AdminUser struct {
//id
Id int64 `json:"id"`
//账号
Account string `json:"account"`
//密码
Password string `json:"password"`
//管理员名称
AdminName string `json:"admin_name"`
//是否是默认系统账号
IsDefault bool `json:"is_default"`
//账号是否可用
IsUsable bool `json:"is_userable"`
//创建时间
CreateAt string `json:"create_at"`
//用户权限
Permission []AdminPermission `json:"permission"`
}
type AdminUserFindQuery struct {
AccountLike string
Offset int
Limit int
}
type AdminUserFindOneQuery struct {
AdminUserId int64
AccountEqual string
}
type AdminUserRepository interface {
// Save(*AdminUser) (*AdminUser, error)
// Remove(user *AdminUser) (*AdminUser, error)
FindOne(qureyOptions AdminUserFindOneQuery) (*AdminUser, error)
// Find(queryOptions AdminUserFindQuery) (int, []*AdminUser, error)
}
... ...
package domain
import "time"
type PartnerInfoRepository interface {
Save(dm *PartnerInfo) (*PartnerInfo, error)
Remove(dm *PartnerInfo) (*PartnerInfo, error)
FindOne(queryOptions map[string]interface{}) (*PartnerInfo, error)
Find(queryOptions map[string]interface{}) (int64, []*PartnerInfo, error)
}
type PartnerInfo struct {
// 合伙人ID
Id int64 `json:"id"`
// 合伙人姓名
PartnerName string `json:"partnerName"`
// 登录账号
Account string `json:"account"`
// 登录密码
Password string `json:"password"`
// 状态(1:启用或者0:禁用)
Status int `json:"status"`
// 合伙类别 (1.研发合伙人 2.业务合伙人 3.事业)
PartnerCategory int `json:"partnerCategory"`
//创建时间
CreateAt time.Time `json:"createAt"`
//更新时间
UpdateAt time.Time `json:"updateAt"`
//关联业务员
Salesman []*Salesman `json:"salesman"`
}
func (m *PartnerInfo) Identify() interface{} {
if m.Id == 0 {
return nil
}
return m.Id
}
func (m *PartnerInfo) Update(data map[string]interface{}) error {
if partnerName, ok := data["partnerName"]; ok && partnerName != "" {
m.PartnerName = partnerName.(string)
}
if account, ok := data["account"]; ok && account != "" {
m.Account = account.(string)
}
if password, ok := data["account"]; ok && password != "" {
m.Password = password.(string)
}
if status, ok := data["status"]; ok && status != 0 {
m.Status = status.(int)
}
if partnerCategory, ok := data["partnerCategory"]; ok && partnerCategory != 0 {
m.PartnerCategory = partnerCategory.(int)
}
if salesman, ok := data["salesman"]; ok {
m.Salesman = salesman.([]*Salesman)
}
m.UpdateAt = time.Now()
return nil
}
... ...
package domain
//关联业务员
type Salesman struct {
//Id int64 `json:"id"`
Name string `json:"name"`
Telephone string `json:"telephone"`
}
... ...
package dao
//import (
// "fmt"
// "github.com/go-pg/pg/v10"
// pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
// "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/domain"
// "gitlab.fjmaimaimai.com/linmadan/mmm-worth/pkg/infrastructure/pg/models"
// "time"
//)
//
//type EmployeeDao struct {
// transactionContext *pgTransaction.TransactionContext
//}
//
//func (dao *EmployeeDao) BatchRemove(uids []int64) error {
// tx := dao.transactionContext.PgTx
// _, err := tx.QueryOne(
// pg.Scan(),
// "DELETE FROM employees WHERE uid IN (?)",
// pg.In(uids))
// return err
//}
//
//func (dao *EmployeeDao) BatchSetStatus(uids []int64, status int) error {
// tx := dao.transactionContext.PgTx
// _, err := tx.QueryOne(
// pg.Scan(),
// "UPDATE employees SET status=? WHERE uid IN (?)",
// status, pg.In(uids))
// return err
//}
//
//func (dao *EmployeeDao) ChangePrincipal(companyId int64, employeeAccount string) error {
// tx := dao.transactionContext.PgTx
// if _, err := tx.Query(
// pg.Scan(),
// "UPDATE employees SET is_principal=? WHERE company_id=?",
// false, companyId); err != nil {
// return err
// }
// if _, err := tx.QueryOne(
// pg.Scan(),
// "UPDATE employees SET is_principal=? WHERE company_id=? AND employee_account=?",
// true, companyId, employeeAccount); err != nil {
// return err
// }
// return nil
//}
//
//func (dao *EmployeeDao) TransferSuMoney(uid int64, suMoney float64) error {
// tx := dao.transactionContext.PgTx
// _, err := tx.QueryOne(
// pg.Scan(),
// "UPDATE employees SET su_money=su_money+? WHERE uid=?",
// suMoney, uid)
// return err
//}
//
//func (dao *EmployeeDao) CalculatePersonUnReadNotification(uid int64) (map[string]int, error) {
// var unReadSystemNotification int
// var unReadInteractionNotification int
// tx := dao.transactionContext.PgTx
// sentNotificationModel := new(models.SentNotification)
// if count, err := tx.Model(sentNotificationModel).Relation("Notification").
// Where(`sent_notification.receiver @> '{"uid":?}'`, uid).
// Where("notification.notification_type = ?", domain.NOTIFICATION_TYPE_SYSTEM).
// Where("sent_notification.is_read = ?", false).
// Count(); err != nil {
// return nil, err
// } else {
// unReadSystemNotification = count
// }
// if count, err := tx.Model(sentNotificationModel).Relation("Notification").
// Where(`sent_notification.receiver @> '{"uid":?}'`, uid).
// Where("notification.notification_type = ?", domain.NOTIFICATION_TYPE_INTERACTION).
// Where("sent_notification.is_read = ?", false).
// Count(); err != nil {
// return nil, err
// } else {
// unReadInteractionNotification = count
// }
// return map[string]int{
// "unReadSystemNotification": unReadSystemNotification,
// "unReadInteractionNotification": unReadInteractionNotification,
// }, nil
//}
//
//func (dao *EmployeeDao) CalculatePersonSuMoney(uid int64) (map[string]interface{}, error) {
// var incomeSuMoney float64
// var incomeSuMoneyOfYesterday float64
// tx := dao.transactionContext.PgTx
// suMoneyTransactionRecordModel := new(models.SuMoneyTransactionRecord)
// yesterday := time.Now().AddDate(0, 0, -1)
// if err := tx.Model(suMoneyTransactionRecordModel).
// ColumnExpr("sum(su_money_transaction_record.su_money) AS income_su_money").
// Where(`su_money_transaction_record.employee @> '{"uid":?}'`, uid).
// Where(`su_money_transaction_record.record_type = ?`, 2).
// Where(`su_money_transaction_record.create_time > ?`, time.Date(yesterday.Year(), yesterday.Month(), yesterday.Day(), 0, 0, 0, 0, yesterday.Location())).
// Where(`su_money_transaction_record.create_time < ?`, time.Date(yesterday.Year(), yesterday.Month(), yesterday.Day(), 23, 59, 59, 0, yesterday.Location())).
// Select(&incomeSuMoneyOfYesterday); err != nil {
// return nil, err
// }
// if err := tx.Model(suMoneyTransactionRecordModel).
// ColumnExpr("sum(su_money_transaction_record.su_money) AS income_su_money").
// Where(`su_money_transaction_record.employee @> '{"uid":?}'`, uid).
// Where(`su_money_transaction_record.record_type = ?`, 2).
// Select(&incomeSuMoney); err != nil {
// return nil, err
// }
// return map[string]interface{}{
// "incomeSuMoney": incomeSuMoney,
// "incomeSuMoneyOfYesterday": incomeSuMoneyOfYesterday,
// }, nil
//}
//
//func (dao *EmployeeDao) CalculateSuMoneyTransactionRecord(uid int64, transactionStartTime time.Time, transactionEndTime time.Time) (map[string]interface{}, error) {
// var incomeSuMoney float64
// var expendSuMoney float64
// tx := dao.transactionContext.PgTx
// suMoneyTransactionRecordModel := new(models.SuMoneyTransactionRecord)
// if err := tx.Model(suMoneyTransactionRecordModel).
// ColumnExpr("sum(su_money_transaction_record.su_money) AS income_su_money").
// Where(`su_money_transaction_record.employee @> '{"uid":?}'`, uid).
// Where(`su_money_transaction_record.record_type IN (?)`, pg.In([]int{2, 3})).
// Where(`su_money_transaction_record.create_time > ?`, transactionStartTime).
// Where(`su_money_transaction_record.create_time < ?`, transactionEndTime).
// Select(&incomeSuMoney); err != nil {
// return nil, err
// }
// if err := tx.Model(suMoneyTransactionRecordModel).
// ColumnExpr("sum(su_money_transaction_record.su_money) AS expend_su_money").
// Where(`su_money_transaction_record.employee @> '{"uid":?}'`, uid).
// Where(`su_money_transaction_record.record_type IN (?)`, pg.In([]int{1, 4})).
// Where(`su_money_transaction_record.create_time > ?`, transactionStartTime).
// Where(`su_money_transaction_record.create_time < ?`, transactionEndTime).
// Select(&expendSuMoney); err != nil {
// return nil, err
// }
// return map[string]interface{}{
// "incomeSuMoney": incomeSuMoney,
// "expendSuMoney": expendSuMoney,
// }, nil
//}
//
//func NewEmployeeDao(transactionContext *pgTransaction.TransactionContext) (*EmployeeDao, error) {
// if transactionContext == nil {
// return nil, fmt.Errorf("transactionContext参数不能为nil")
// } else {
// return &EmployeeDao{
// transactionContext: transactionContext,
// }, nil
// }
//}
... ...
package pg
import (
"context"
"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"
)
var DB *pg.DB
func init() {
DB = pg.Connect(&pg.Options{
User: constant.POSTGRESQL_USER,
Password: constant.POSTGRESQL_PASSWORD,
Database: constant.POSTGRESQL_DB_NAME,
Addr: fmt.Sprintf("%s:%s", constant.POSTGRESQL_HOST, constant.POSTGRESQL_PORT),
})
if !constant.DISABLE_SQL_GENERATE_PRINT {
DB.AddQueryHook(SqlGeneratePrintHook{})
}
if !constant.DISABLE_CREATE_TABLE {
for _, model := range []interface{}{
//(*models.Employee)(nil),
(*models.PartnerInfo)(nil),
} {
err := DB.CreateTable(model, &orm.CreateTableOptions{
Temp: false,
IfNotExists: true,
FKConstraints: true,
})
if err != nil {
panic(err)
}
}
}
}
type SqlGeneratePrintHook struct{}
func (hook SqlGeneratePrintHook) BeforeQuery(c context.Context, q *pg.QueryEvent) (context.Context, error) {
return c, nil
}
func (hook SqlGeneratePrintHook) AfterQuery(c context.Context, q *pg.QueryEvent) error {
data, err := q.FormattedQuery()
log.PrintSql(data)
return err
}
... ...
package models
import (
"context"
"time"
"github.com/go-pg/pg/v10"
)
type AdminUser struct {
tableName struct{} `pg:"admin_user"`
//id
Id int64 `pg:",pk"`
//用户账号
AdminAccount string `pg:",unique"`
//用户名称
AdminName string
//账号密码
Password string
//是否是默认账号
IsDefault bool `pg:",use_zero"`
//账号是否可用
IsUsable bool `json:"is_userable"`
CreateAt time.Time
UpdateAt time.Time
}
var _ pg.BeforeUpdateHook = (*AdminUser)(nil)
func (user *AdminUser) BeforeUpdate(ctx context.Context) (context.Context, error) {
user.UpdateAt = time.Now()
return ctx, nil
}
var _ pg.BeforeInsertHook = (*AdminUser)(nil)
func (user *AdminUser) BeforeInsert(ctx context.Context) (context.Context, error) {
user.CreateAt = time.Now()
user.UpdateAt = time.Now()
return ctx, nil
}
... ...
package models
import (
"time"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
)
type PartnerInfo struct {
tableName struct{} `pg:"partner_infos,alias:partner_info"`
// 合伙人ID
Id int64 `pg:",pk"`
// 合伙人姓名
PartnerName string
// 登录账号
Account string
// 登录密码
Password string
// 状态(1:启用或者0:禁用)
Status int `pg:",notnull,default:1"`
// 合伙类别 (1.研发合伙人 2.业务合伙人 3.事业)
PartnerCategory int `pg:",notnull,default:1"`
//创建时间
CreateAt time.Time
//更新时间
UpdateAt time.Time
//关联业务员
Salesman []*domain.Salesman
}
... ...
package transaction
import "github.com/go-pg/pg/v10"
type TransactionContext struct {
PgDd *pg.DB
PgTx *pg.Tx
}
func (transactionContext *TransactionContext) StartTransaction() error {
tx, err := transactionContext.PgDd.Begin()
if err != nil {
return err
}
transactionContext.PgTx = tx
return nil
}
func (transactionContext *TransactionContext) CommitTransaction() error {
err := transactionContext.PgTx.Commit()
return err
}
func (transactionContext *TransactionContext) RollbackTransaction() error {
err := transactionContext.PgTx.Rollback()
return err
}
func NewPGTransactionContext(pgDd *pg.DB) *TransactionContext {
return &TransactionContext{
PgDd: pgDd,
}
}
... ...
package repository
import (
"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 AdminUserRepository struct {
transactionContext *transaction.TransactionContext
}
var (
_ domain.AdminUserRepository = (*AdminUserRepository)(nil)
)
func NewAdminUserRepository(transactionContext *transaction.TransactionContext) (*AdminUserRepository, error) {
if transactionContext == nil {
return nil, ERR_EMPTY_TC
}
return &AdminUserRepository{transactionContext: transactionContext}, nil
}
func (reponsitory AdminUserRepository) transformPgModelToDomainModel(adminuserModel *models.AdminUser) (domain.AdminUser, error) {
result := domain.AdminUser{}
return result, nil
}
func (reponsitory AdminUserRepository) FindOne(queryOption domain.AdminUserFindOneQuery) (*domain.AdminUser, error) {
db := reponsitory.transactionContext.PgDd
adminuserModel := new(models.AdminUser)
query := db.Model(adminuserModel)
if queryOption.AdminUserId > 0 {
query = query.Where("id=?", queryOption.AdminUserId)
}
if len(queryOption.AccountEqual) > 0 {
query = query.Where("admin_account=?", queryOption.AccountEqual)
}
err := query.First()
if err != nil {
return nil, err
}
adminUser, err := reponsitory.transformPgModelToDomainModel(adminuserModel)
return &adminUser, err
}
... ...
package repository
import (
"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 PartnerInfoRepository struct {
transactionContext *transaction.TransactionContext
}
func (repository *PartnerInfoRepository) Save(dm *domain.PartnerInfo) (*domain.PartnerInfo, error) {
var (
err error
m = &models.PartnerInfo{}
tx = repository.transactionContext.PgTx
)
if err = GobModelTransform(m, dm); err != nil {
return nil, err
}
if dm.Identify() == nil {
if dm.Id, err = NewSnowflakeId(); err != nil {
return dm, err
}
m.Id = dm.Id
if err = tx.Insert(m); err != nil {
return nil, err
}
return dm, nil
}
if err = tx.Update(m); err != nil {
return nil, err
}
return dm, nil
}
func (repository *PartnerInfoRepository) Remove(PartnerInfo *domain.PartnerInfo) (*domain.PartnerInfo, error) {
var (
tx = repository.transactionContext.PgTx
PartnerInfoModel = &models.PartnerInfo{Id: PartnerInfo.Identify().(int64)}
)
if _, err := tx.Model(PartnerInfoModel).Where("id = ?", PartnerInfo.Id).Delete(); err != nil {
return PartnerInfo, err
}
return PartnerInfo, nil
}
func (repository *PartnerInfoRepository) FindOne(queryOptions map[string]interface{}) (*domain.PartnerInfo, error) {
tx := repository.transactionContext.PgTx
PartnerInfoModel := new(models.PartnerInfo)
query := NewQuery(tx.Model(PartnerInfoModel), queryOptions)
query.SetWhere("partner_info.id = ?", "id")
if err := query.First(); err != nil {
return nil, query.HandleError(err, "没有此合伙人")
}
if PartnerInfoModel.Id == 0 {
return nil, nil
}
return repository.transformPgModelToDomainModel(PartnerInfoModel)
}
func (repository *PartnerInfoRepository) Find(queryOptions map[string]interface{}) (int64, []*domain.PartnerInfo, error) {
tx := repository.transactionContext.PgTx
var PartnerInfoModels []*models.PartnerInfo
PartnerInfos := make([]*domain.PartnerInfo, 0)
query := NewQuery(tx.Model(&PartnerInfoModels), queryOptions)
query.
SetWhere("partner_info.account = ?", "account").
SetWhere(`partner_info.status = ?`, "status").
SetWhere(`partner_info.partner_category = ?`, "partnerCategory").
SetLimit().
SetOrder("partner_info.create_at", "sortByCreateTime").
SetOrder("partner_info.update_at", "sortByUpdateTime")
var err error
if query.AffectRow, err = query.SelectAndCount(); err != nil {
return 0, PartnerInfos, err
}
for _, PartnerInfoModel := range PartnerInfoModels {
if PartnerInfo, err := repository.transformPgModelToDomainModel(PartnerInfoModel); err != nil {
return 0, PartnerInfos, err
} else {
PartnerInfos = append(PartnerInfos, PartnerInfo)
}
}
return int64(query.AffectRow), PartnerInfos, nil
}
func (repository *PartnerInfoRepository) transformPgModelToDomainModel(PartnerInfoModel *models.PartnerInfo) (*domain.PartnerInfo, error) {
m := &domain.PartnerInfo{}
err := GobModelTransform(m, PartnerInfoModel)
return m, err
}
func NewPartnerInfoRepository(transactionContext *transaction.TransactionContext) (*PartnerInfoRepository, error) {
if transactionContext == nil {
return nil, ERR_EMPTY_TC
}
return &PartnerInfoRepository{transactionContext: transactionContext}, nil
}
... ...
package repository
import (
"bytes"
"encoding/gob"
"fmt"
"github.com/go-pg/pg/v10/orm"
"github.com/linmadan/egglib-go/utils/snowflake"
)
var (
ERR_EMPTY_TC = fmt.Errorf("transactionContext参数不能为nil")
)
type Query struct {
*orm.Query
queryOptions map[string]interface{}
AffectRow int
}
func NewQuery(query *orm.Query, queryOptions map[string]interface{}) *Query {
return &Query{
query,
queryOptions,
0,
}
}
func (query *Query) SetWhere(condition, key string) *Query {
if v, ok := query.queryOptions[key]; ok {
query.Where(condition, v)
}
return query
}
func (query *Query) SetLimit() *Query {
if offset, ok := query.queryOptions["offset"]; ok {
offset := offset.(int)
if offset > -1 {
query.Offset(offset)
}
} else {
query.Offset(0)
}
if limit, ok := query.queryOptions["limit"]; ok {
limit := limit.(int)
if limit > -1 {
query.Limit(limit)
} else {
query.Limit(20)
}
}
return query
}
func (query *Query) SetOrder(orderColumn string, key string) *Query {
//query.Order(condition...)
//return query
if v, ok := query.queryOptions[key]; ok {
query.Order(fmt.Sprintf("%v %v", orderColumn, v))
}
return query
}
func (query *Query) HandleError(err error, errMsg string) error {
if err.Error() == "pg: no rows in result set" {
return fmt.Errorf(errMsg)
} else {
return err
}
}
func NewSnowflakeId() (int64, error) {
IdWorker, err := snowflake.NewIdWorker(2)
if err != nil {
return 0, err
}
id, err := IdWorker.NextId()
return id, err
}
//GobModelTransform 模型转换
func GobModelTransform(dst interface{}, src interface{}) error {
var data bytes.Buffer
enc := gob.NewEncoder(&data)
if err := enc.Encode(src); err != nil {
return err
}
dec := gob.NewDecoder(&data)
if err := dec.Decode(dst); err != nil {
return err
}
return nil
}
... ...
package log
import (
"github.com/astaxie/beego"
"github.com/astaxie/beego/logs"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/constant"
)
func init() {
logs.SetLevel(logLevel(constant.LOG_LEVEL))
if beego.BConfig.RunMode == "prod" {
logs.SetLogFuncCall(false)
} else {
logs.SetLogFuncCallDepth(3)
}
logs.SetLogger("file", `{"filename":"log/partnermg.log"}`)
}
//LogLevel ...
func logLevel(s string) (i int) {
switch s {
case "info":
i = logs.LevelInfo
case "debug":
i = logs.LevelDebug
case "warning":
i = logs.LevelWarning
case "error":
i = logs.LevelError
default:
i = logs.LevelDebug
}
return
}
func PrintSql(bt []byte) {
logs.Debug(string(bt))
}
... ...
package beego
import (
"github.com/astaxie/beego"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/port/beego/middleware"
_ "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/port/beego/routers"
)
func init() {
beego.InsertFilter("/*", beego.BeforeRouter, middleware.AllowCors())
// beego.InsertFilter("/*", beego.BeforeExec, filters.CreateRequestBodyFilter())
// beego.InsertFilter("/*", beego.BeforeExec, log.CreateRequstLogFilter(Logger))
// beego.InsertFilter("/*", beego.AfterExec, log.CreateResponseLogFilter(Logger), false)
}
... ...
package controllers
import (
"errors"
"github.com/astaxie/beego/logs"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
)
type AdminUserController struct {
BaseController
}
////Prepare 重写 BaseController 的Prepare方法
func (c *AdminUserController) Prepare() {
c.BaseController.Prepare()
if ok := c.ValidJWTToken(); !ok {
return
}
if ok := c.ValidAdminPermission(domain.PERMINSSION_ADMIN_USER); !ok {
return
}
}
func (c *AdminUserController) Demo() {
//用与适配前端定义的数据结构
type Paramer struct {
}
var (
param Paramer
err error
)
if err = c.BindJsonData(&param); err != nil {
logs.Error(err)
c.ResponseError(errors.New("json数据解析失败"))
return
}
//Paramer转换为application要求的数据结构
//业务逻辑处理
c.ResponseData(nil)
}
... ...
package controllers
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"strconv"
"github.com/astaxie/beego"
"github.com/astaxie/beego/logs"
"github.com/prometheus/common/log"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/port/beego/lib"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/port/beego/protocol"
)
type BaseController struct {
beego.Controller
}
func (controller BaseController) BindJsonData(v interface{}) error {
bodyData := controller.Ctx.Input.GetData("requestBody")
bodyByte, ok := bodyData.([]byte)
if !ok {
return errors.New("requestBody is not []byte")
}
return json.Unmarshal(bodyByte, v)
}
func (controller BaseController) ResponseError(err error) {
controller.Data["json"] = protocol.ResponseData{
Code: "-1",
Msg: err.Error(),
Data: struct{}{},
}
controller.ServeJSON()
logs.Error(err)
}
func (controller BaseController) ResponseData(data interface{}) {
if data == nil {
data = struct{}{}
}
controller.Data["json"] = protocol.ResponseData{
Code: "0",
Msg: "ok",
Data: data,
}
controller.ServeJSON()
}
//Finish 重写 beego.Controller 的Finish 方法
func (controller *BaseController) Finish() {
strByte, _ := json.Marshal(controller.Data["json"])
length := len(strByte)
if length > 1500 {
logs.Info("<====Send to client: RspBodyData: %s......", string(strByte[:1500]))
} else {
logs.Info("<====Send to client: RspBodyData: %s......", string(strByte))
}
}
////Prepare 重写 beego.Controller 的Prepare方法
func (controller *BaseController) Prepare() {
log.Info("====>Recv Request:%s Method:%s", controller.Ctx.Input.URI(), controller.Ctx.Input.Method())
if controller.Ctx.Input.IsPost() || controller.Ctx.Input.IsPut() {
bodyByte, _ := ioutil.ReadAll(controller.Ctx.Request.Body)
controller.Ctx.Input.SetData("requestBody", bodyByte)
controller.Ctx.Request.Body.Close()
if len(bodyByte) > 1000 {
log.Info("====>Recv data from client: BodyData:\n %s ...", string(bodyByte[0:1000]))
} else {
log.Info("====>Recv data from client: BodyData: \n %s", string(bodyByte))
}
}
return
}
func (controller *BaseController) GetHeaderToken() string {
return controller.Ctx.Input.Header("Authorization")
}
func (controller *BaseController) GetUserId() int {
idV := controller.Ctx.Input.GetData("admin_user_id")
uid, _ := strconv.Atoi(fmt.Sprint(idV))
return uid
}
func (controller *BaseController) setUserId(id int) {
controller.Ctx.Input.SetData("admin_user_id", id)
}
func (controller *BaseController) ValidJWTToken() bool {
headerToken := controller.GetHeaderToken()
mytoken := lib.NewMyToken(0)
err := mytoken.ValidJWTToken(headerToken)
if err != nil {
if mytoken.IsJwtErrorExpired(err) {
//token超时
controller.Data["json"] = protocol.ResponseData{
Code: "2",
Msg: "token过期,请重新登录",
Data: struct{}{},
}
controller.ServeJSON()
} else {
controller.Data["json"] = protocol.ResponseData{
Code: "-1",
Msg: "token校验失败",
Data: struct{}{},
}
controller.ServeJSON()
}
return false
}
controller.setUserId(mytoken.UID)
return true
}
func (controller *BaseController) ValidAdminPermission(code string, excludeURL ...string) bool {
//排除掉的请求
reqUrl := controller.Ctx.Input.URL()
for i := range excludeURL {
if reqUrl == excludeURL[i] {
return true
}
}
//权限校验
//
var err error
if err != nil {
controller.Data["json"] = protocol.ResponseData{
Code: "-1",
Msg: "没有操作权限",
Data: struct{}{},
}
controller.ServeJSON()
}
return true
}
... ...
package controllers
type PartnerInfoController struct {
BaseController
}
//CreatePartnerInfo 创建合伙人
func (controller *PartnerInfoController) CreatePartnerInfo() {
// var (
// service = service.NewPartnerInfoService(nil)
// command = &command.CreatePartnerInfoCommand{}
// )
// controller.JsonUnmarshal(command)
// controller.HandlerResponse(service.CreatePartnerInfo(command))
}
//UpdatePartnerInfo 更新合伙人
func (controller *PartnerInfoController) UpdatePartnerInfo() {
// var (
// service = service.NewPartnerInfoService(nil)
// command = &command.UpdatePartnerInfoCommand{}
// )
// controller.JsonUnmarshal(command)
// id, _ := controller.GetInt(":id")
// command.Id = id
// controller.HandlerResponse(service.UpdatePartnerInfo(command))
}
//GetPartnerInfo 获取合伙人
func (controller *PartnerInfoController) GetPartnerInfo() {
// var (
// service = service.NewPartnerInfoService(nil)
// command = &query.GetPartnerInfoQuery{}
// )
// uid, _ := controller.GetInt(":id")
// command.Id = uid
// controller.HandlerResponse(service.GetPartnerInfo(command))
}
//GetPartnerInfo 移除合伙人
func (controller *PartnerInfoController) RemovePartnerInfo() {
// var (
// service = service.NewPartnerInfoService(nil)
// command = &command.RemovePartnerInfoCommand{}
// )
// uid, _ := controller.GetInt(":id")
// command.Id = uid
// controller.HandlerResponse(service.RemovePartnerInfo(command))
}
//ListPartnerInfo 合伙人列表
func (controller *PartnerInfoController) ListPartnerInfo() {
// var (
// service = service.NewPartnerInfoService(nil)
// command = &query.ListPartnerInfoQuery{}
// )
// command.PartnerCategory, _ = controller.GetInt("partnerCategory")
// command.Status, _ = controller.GetInt("status")
// command.SortByCreateTime = controller.GetString("sortByCreateTime")
// command.SortByUpdateTime = controller.GetString("sortByUpdateTime")
// command.Offset, command.Limit = controller.GetLimitInfo()
// controller.HandlerResponse(service.ListPartnerInfo(command))
}
... ...
package lib
import (
"fmt"
"time"
"github.com/dgrijalva/jwt-go"
)
var (
key []byte = []byte("sx87sda0w7x7sd")
)
//MyToken ...
type MyToken struct {
jwt.StandardClaims
UID int `json:"uid"` //管理员的id
}
func NewMyToken(id int) *MyToken {
return &MyToken{UID: id}
}
//CreateJWTToken ...
func (mytoken *MyToken) CreateJWTToken() (string, error) {
nowTime := time.Now().Unix()
mytoken.StandardClaims = jwt.StandardClaims{
NotBefore: nowTime,
IssuedAt: nowTime,
ExpiresAt: 60 * 60 * 3,
Issuer: "mmm_partnermg",
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, mytoken)
return token.SignedString(key)
}
//ValidJWTToken ...
func (mytoken *MyToken) ValidJWTToken(tokenString string) error {
token, err := jwt.ParseWithClaims(
tokenString,
&MyToken{},
func(token *jwt.Token) (interface{}, error) {
return key, nil
})
if err != nil {
return err
}
mytoken, ok := token.Claims.(*MyToken)
if ok && token.Valid {
// 验证成功,返回信息
return nil
}
// 验证失败
return fmt.Errorf("token Valid fail")
}
func (mytoken *MyToken) IsJwtErrorExpired(err error) bool {
ve, ok := err.(*jwt.ValidationError)
if ok && ve.Errors == jwt.ValidationErrorExpired {
return true
}
return false
}
... ...
package middleware
import (
"github.com/astaxie/beego/context"
"github.com/astaxie/beego/plugins/cors"
)
func AllowCors() func(ctx *context.Context) {
fn := cors.Allow(&cors.Options{
//允许访问所有源
AllowAllOrigins: true,
//可选参数"GET", "POST", "PUT", "DELETE", "OPTIONS" (*为所有)
//其中Options跨域复杂请求预检
AllowMethods: []string{"*"},
//指的是允许的Header的种类
AllowHeaders: []string{"*"},
//公开的HTTP标头列表
ExposeHeaders: []string{"Content-Length"},
//如果设置,则允许共享身份验证凭据,例如cookie
AllowCredentials: true,
})
return fn
}
... ...
package middleware
import (
"github.com/astaxie/beego/context"
)
//PermissionCheck 根据权限编码检验请求是否可以执行
//permissionCode:权限编码
//excludeURL:跳过url
func AdminPermissionCheck(permissionCode string, excludeURL ...string) func(ctx *context.Context) {
return func(ctx *context.Context) {
//根据code检查权限数据,并排除excludeUrl指定的url
//获取user 数据
}
}
... ...
package protocol
type ResponseData struct {
Code string `json:"code"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
}
... ...
package routers
import (
"github.com/astaxie/beego"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/port/beego/controllers"
)
func init() {
adminRouter := beego.NewNamespace("/admin_user",
// 其余的路由
beego.NSRouter("/get", &controllers.AdminUserController{}, "POST:Demo"),
)
//...
beego.AddNamespace(adminRouter)
}
... ...
package routers
import (
"github.com/astaxie/beego"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/port/beego/controllers"
)
func init() {
beego.Router("/partnerInfos/", &controllers.PartnerInfoController{}, "Post:CreatePartnerInfo")
beego.Router("/partnerInfos/:id", &controllers.PartnerInfoController{}, "Put:UpdatePartnerInfo")
beego.Router("/partnerInfos/:id", &controllers.PartnerInfoController{}, "Get:GetPartnerInfo")
beego.Router("/partnerInfos/:id", &controllers.PartnerInfoController{}, "Delete:RemovePartnerInfo")
beego.Router("/partnerInfos/", &controllers.PartnerInfoController{}, "Get:ListPartnerInfo")
}
... ...
package routers
import (
"github.com/astaxie/beego"
"gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/constant"
)
func init() {
beego.SetStaticPath("/log", constant.LOG_File)
}
... ...
package partnerInfo
import (
"github.com/gavv/httpexpect"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg"
"net/http"
)
var _ = Describe("创建新合伙人", func() {
Describe("创建新合伙人", func() {
Context("创建新合伙人", func() {
It("返回合伙人数据", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
body := map[string]interface{}{
"partnerName": "employeeName",
"account": "account123",
"password": "password",
"status": 1,
"partnerCategory": 1,
//"createAt":time.Now(),
//"updateAt":time.Now(),
"salesman": []map[string]interface{}{
{"name": "name", "telephone": "18860183051"},
{"name2": "name", "telephone": "18860183052j"},
},
}
httpExpect.POST("/partnerInfos").
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 partner_infos WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...
package partnerInfo
import (
"github.com/gavv/httpexpect"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg"
"net/http"
)
var _ = Describe("删除合伙人", func() {
BeforeEach(func() {
_, err := pG.DB.Exec(`INSERT INTO "public"."partner_infos"("id", "partner_name", "account", "password", "status", "partner_category", "create_at", "update_at", "salesman") VALUES (2929531956394199040, 'employeeName', 'account', 'password', 1, 1, '2020-06-19 15:23:31.616934+08', '2020-06-19 15:23:31.616934+08', '[{"name": "name", "telephone": "18860183051"}, {"name": "", "telephone": "18860183052j"}]');`)
Expect(err).NotTo(HaveOccurred())
})
Describe("删除合伙人", func() {
Context("删除合伙人", func() {
It("删除合伙人数据", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
body := map[string]interface{}{}
httpExpect.DELETE("/partnerInfos/2929531956394199040").
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 partner_infos WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...
package partnerInfo
import (
"github.com/gavv/httpexpect"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg"
"net/http"
)
var _ = Describe("获取合伙人", func() {
BeforeEach(func() {
_, err := pG.DB.Exec(`INSERT INTO "public"."partner_infos"("id", "partner_name", "account", "password", "status", "partner_category", "create_at", "update_at", "salesman") VALUES (2929531956394199040, 'employeeName', 'account', 'password', 1, 1, '2020-06-19 15:23:31.616934+08', '2020-06-19 15:23:31.616934+08', '[{"name": "name", "telephone": "18860183051"}, {"name": "", "telephone": "18860183052j"}]');`)
Expect(err).NotTo(HaveOccurred())
})
Describe("获取合伙人", func() {
Context("获取合伙人", func() {
It("返回合伙人数据", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
body := map[string]interface{}{}
httpExpect.GET("/partnerInfos/2929531956394199040").
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 partner_infos WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...
package partnerInfo
import (
"github.com/gavv/httpexpect"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg"
"net/http"
)
var _ = Describe("获取合伙人列表", func() {
BeforeEach(func() {
_, err := pG.DB.Exec(`INSERT INTO "public"."partner_infos"("id", "partner_name", "account", "password", "status", "partner_category", "create_at", "update_at", "salesman") VALUES (2929531956394199040, 'employeeName', 'account', 'password', 1, 1, '2020-06-19 15:23:31.616934+08', '2020-06-19 15:23:31.616934+08', '[{"name": "name", "telephone": "18860183051"}, {"name": "", "telephone": "18860183052j"}]');`)
Expect(err).NotTo(HaveOccurred())
})
Describe("获取合伙人列表", func() {
Context("获取合伙人列表", func() {
It("获取合伙人列表", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
body := map[string]interface{}{}
httpExpect.GET("/partnerInfos").
WithQuery("partnerCategory", 1).
WithQuery("status", 1).
WithQuery("status", 1).
WithQuery("sortByCreateTime", "DESC").
WithQuery("sortByUpdateTime", "DESC").
WithQuery("offset", 0).
WithQuery("limit", 20).
WithJSON(body).
Expect().
Status(http.StatusOK).
JSON().
Object().
ContainsKey("code").ValueEqual("code", 0).
ContainsKey("msg").ValueEqual("msg", "ok").
ContainsKey("data").Value("data").Object().ContainsKey("partnerInfos")
})
})
})
AfterEach(func() {
_, err := pG.DB.Exec("DELETE FROM partner_infos WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...
package partnerInfo
import (
"github.com/astaxie/beego"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"net/http"
"net/http/httptest"
"testing"
_ "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg"
_ "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/port/beego"
)
func TestPartnerInfo(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Beego Port Employee 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 partnerInfo
import (
"github.com/gavv/httpexpect"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg"
"net/http"
)
var _ = Describe("创建新合伙人", func() {
BeforeEach(func() {
_, err := pG.DB.Exec(`INSERT INTO "public"."partner_infos"("id", "partner_name", "account", "password", "status", "partner_category", "create_at", "update_at", "salesman") VALUES (2929531956394199040, 'employeeName', 'account', 'password', 1, 1, '2020-06-19 15:23:31.616934+08', '2020-06-19 15:23:31.616934+08', '[{"name": "name", "telephone": "18860183051"}, {"name": "", "telephone": "18860183052j"}]');`)
Expect(err).NotTo(HaveOccurred())
})
Describe("创建新合伙人", func() {
Context("创建新合伙人", func() {
It("返回合伙人数据", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
body := map[string]interface{}{
"partnerName": "employeeName",
"account": "account123",
"password": "password",
"status": 1,
"partnerCategory": 1,
"salesman": []map[string]interface{}{
{"name": "name", "telephone": "18860183051"},
{"name2": "name", "telephone": "18860183052j"},
},
}
httpExpect.PUT("/partnerInfos/2929531956394199040").
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 partner_infos WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...