first commit

This commit is contained in:
2022-03-17 15:59:24 +08:00
commit 2b0debb847
592 changed files with 73946 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
版本号`major.minor.patch`具体规则如下:
- major主版本号如有重大版本重构则该字段递增通常各主版本间接口不兼容。
- minor次版本号各次版本号间接口保持兼容如有接口新增或优化则该字段递增。
- patch补丁号如有功能改善或缺陷修复则该字段递增。
## version 0.2.3
**配置文件更新**
```toml
CdkMod = false # true 表示开启 cdk 模块, false 表示关闭
```
**Feature**
- cdk 模块设计开关 v0.2.3 2021_11_09
## version 0.2.0-0.2.2
**配置文件更新**
```toml
Env = "release"
[IdGenRPCClient]
RegAddrs = "127.0.0.1:2379"
Schema = "dtalk"
SrvName = "generator"
Dial = "1s"
Timeout = "1s"
```
**数据库更新**
新增两张表
- dtalk_cdk_info
- dtalk_cdk_list
**Feature**
- 新增 cdk 相关接口 v0.2.0 2021_10_22
- 新增接口参数约束, 每种优惠券兑换数量上限 v0.2.1 2021_10_31
- 异步处理订单, 后端查询交易是否成功 v0.2.2 2021_11_01
## version 0.1.0
- platform 从配置文件中获得 v0.1.0 2021_09_18
## version 0.0.10
init backend
## example x.x.x @yy.mm.dd
**Feature**
**Bug Fixes**
**Improvement**
**Breaking Change**

50
service/backend/Makefile Normal file
View File

@@ -0,0 +1,50 @@
# golang1.9 or latest
# 1. make help
# 2. make dep
# 3. make build
# ...
VERSION := $(shell echo $(shell cat cmd/main.go | grep "projectVersion =" | cut -d '=' -f2))
APP_NAME := backend
BUILD_DIR := build
APP := ${BUILD_DIR}/${APP_NAME}_v${VERSION}
PKG_NAME := ${APP_NAME}_v${VERSION}
PKG := ${PKG_NAME}.tar.gz
main_path = "main"
go_version = $(shell go version | awk '{ print $3 }')
build_time = $(shell date "+%Y-%m-%d %H:%M:%S %Z")
git_commit = $(shell git rev-parse --short=10 HEAD)
flags := -ldflags "-X '${main_path}.goVersion=${go_version}' \
-X '${main_path}.buildTime=${build_time}' \
-X '${main_path}.gitCommit=${git_commit}' \
-X 'google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn'"
.PHONY: clean build pkg
clean: ## Remove previous build
@rm -rf ${BUILD_DIR}
@go clean
swag:
swag init -g server/http/http.go
build: swag#checkgofmt ## Build the binary file
GOOS=linux GOARCH=amd64 GO111MODULE=on GOPROXY=https://goproxy.cn,direct GOSUMDB="sum.golang.google.cn" go build -v $(flags) -o $(APP) cmd/main.go
pkg: build ## Package
mkdir -p ${PKG_NAME}/bin
mkdir -p ${PKG_NAME}/etc
cp ${APP} ${PKG_NAME}/bin/
cp etc/* ${PKG_NAME}/etc/
tar zvcf ${PKG} ${PKG_NAME}
rm -rf ${PKG_NAME}
REMOTE_BIN_PATH := /opt/dtalk/srv/app/bin
upload: build
rsync -r $(APP) 107:$(REMOTE_BIN_PATH)
ssh 107 "cd $(REMOTE_BIN_PATH) && chmod 777 $(PKG_NAME) && ln -sf $(PKG_NAME) $(APP_NAME) && supervisorctl restart $(APP_NAME)"
run: swag
go run cmd/main.go -conf config/backend.toml

View File

@@ -0,0 +1,825 @@
// protoc -I=. -I=$GOPATH/src --go_out=plugins=grpc:. *.proto
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.27.1
// protoc v3.19.1
// source: api.proto
package backend
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type CreateRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Platform string `protobuf:"bytes,1,opt,name=platform,proto3" json:"platform,omitempty"`
Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
Force int32 `protobuf:"varint,3,opt,name=force,proto3" json:"force,omitempty"`
Url string `protobuf:"bytes,4,opt,name=url,proto3" json:"url,omitempty"`
VersionCode string `protobuf:"bytes,5,opt,name=version_code,json=versionCode,proto3" json:"version_code,omitempty"`
VersionName string `protobuf:"bytes,6,opt,name=version_name,json=versionName,proto3" json:"version_name,omitempty"`
DeviceType string `protobuf:"bytes,7,opt,name=device_type,json=deviceType,proto3" json:"device_type,omitempty"`
}
func (x *CreateRequest) Reset() {
*x = CreateRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CreateRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateRequest) ProtoMessage() {}
func (x *CreateRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateRequest.ProtoReflect.Descriptor instead.
func (*CreateRequest) Descriptor() ([]byte, []int) {
return file_api_proto_rawDescGZIP(), []int{0}
}
func (x *CreateRequest) GetPlatform() string {
if x != nil {
return x.Platform
}
return ""
}
func (x *CreateRequest) GetDescription() string {
if x != nil {
return x.Description
}
return ""
}
func (x *CreateRequest) GetForce() int32 {
if x != nil {
return x.Force
}
return 0
}
func (x *CreateRequest) GetUrl() string {
if x != nil {
return x.Url
}
return ""
}
func (x *CreateRequest) GetVersionCode() string {
if x != nil {
return x.VersionCode
}
return ""
}
func (x *CreateRequest) GetVersionName() string {
if x != nil {
return x.VersionName
}
return ""
}
func (x *CreateRequest) GetDeviceType() string {
if x != nil {
return x.DeviceType
}
return ""
}
type UpdateRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"`
Force int32 `protobuf:"varint,2,opt,name=force,proto3" json:"force,omitempty"`
Url string `protobuf:"bytes,3,opt,name=url,proto3" json:"url,omitempty"`
VersionCode string `protobuf:"bytes,4,opt,name=version_code,json=versionCode,proto3" json:"version_code,omitempty"`
VersionName string `protobuf:"bytes,5,opt,name=version_name,json=versionName,proto3" json:"version_name,omitempty"`
Id int64 `protobuf:"varint,6,opt,name=id,proto3" json:"id,omitempty"`
}
func (x *UpdateRequest) Reset() {
*x = UpdateRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UpdateRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateRequest) ProtoMessage() {}
func (x *UpdateRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpdateRequest.ProtoReflect.Descriptor instead.
func (*UpdateRequest) Descriptor() ([]byte, []int) {
return file_api_proto_rawDescGZIP(), []int{1}
}
func (x *UpdateRequest) GetDescription() string {
if x != nil {
return x.Description
}
return ""
}
func (x *UpdateRequest) GetForce() int32 {
if x != nil {
return x.Force
}
return 0
}
func (x *UpdateRequest) GetUrl() string {
if x != nil {
return x.Url
}
return ""
}
func (x *UpdateRequest) GetVersionCode() string {
if x != nil {
return x.VersionCode
}
return ""
}
func (x *UpdateRequest) GetVersionName() string {
if x != nil {
return x.VersionName
}
return ""
}
func (x *UpdateRequest) GetId() int64 {
if x != nil {
return x.Id
}
return 0
}
type ChangeStatusRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
Status int32 `protobuf:"varint,2,opt,name=status,proto3" json:"status,omitempty"`
DeviceType string `protobuf:"bytes,3,opt,name=device_type,json=deviceType,proto3" json:"device_type,omitempty"`
}
func (x *ChangeStatusRequest) Reset() {
*x = ChangeStatusRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ChangeStatusRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ChangeStatusRequest) ProtoMessage() {}
func (x *ChangeStatusRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ChangeStatusRequest.ProtoReflect.Descriptor instead.
func (*ChangeStatusRequest) Descriptor() ([]byte, []int) {
return file_api_proto_rawDescGZIP(), []int{2}
}
func (x *ChangeStatusRequest) GetId() int64 {
if x != nil {
return x.Id
}
return 0
}
func (x *ChangeStatusRequest) GetStatus() int32 {
if x != nil {
return x.Status
}
return 0
}
func (x *ChangeStatusRequest) GetDeviceType() string {
if x != nil {
return x.DeviceType
}
return ""
}
type CheckAndUpdateRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
DeviceType string `protobuf:"bytes,2,opt,name=device_type,json=deviceType,proto3" json:"device_type,omitempty"`
}
func (x *CheckAndUpdateRequest) Reset() {
*x = CheckAndUpdateRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CheckAndUpdateRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CheckAndUpdateRequest) ProtoMessage() {}
func (x *CheckAndUpdateRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CheckAndUpdateRequest.ProtoReflect.Descriptor instead.
func (*CheckAndUpdateRequest) Descriptor() ([]byte, []int) {
return file_api_proto_rawDescGZIP(), []int{3}
}
func (x *CheckAndUpdateRequest) GetId() int64 {
if x != nil {
return x.Id
}
return 0
}
func (x *CheckAndUpdateRequest) GetDeviceType() string {
if x != nil {
return x.DeviceType
}
return ""
}
type CreateReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
}
func (x *CreateReply) Reset() {
*x = CreateReply{}
if protoimpl.UnsafeEnabled {
mi := &file_api_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CreateReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateReply) ProtoMessage() {}
func (x *CreateReply) ProtoReflect() protoreflect.Message {
mi := &file_api_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateReply.ProtoReflect.Descriptor instead.
func (*CreateReply) Descriptor() ([]byte, []int) {
return file_api_proto_rawDescGZIP(), []int{4}
}
func (x *CreateReply) GetId() int64 {
if x != nil {
return x.Id
}
return 0
}
type UpdateReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Num int64 `protobuf:"varint,1,opt,name=num,proto3" json:"num,omitempty"`
}
func (x *UpdateReply) Reset() {
*x = UpdateReply{}
if protoimpl.UnsafeEnabled {
mi := &file_api_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UpdateReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateReply) ProtoMessage() {}
func (x *UpdateReply) ProtoReflect() protoreflect.Message {
mi := &file_api_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UpdateReply.ProtoReflect.Descriptor instead.
func (*UpdateReply) Descriptor() ([]byte, []int) {
return file_api_proto_rawDescGZIP(), []int{5}
}
func (x *UpdateReply) GetNum() int64 {
if x != nil {
return x.Num
}
return 0
}
type ChangeStatusReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Num int64 `protobuf:"varint,1,opt,name=num,proto3" json:"num,omitempty"`
}
func (x *ChangeStatusReply) Reset() {
*x = ChangeStatusReply{}
if protoimpl.UnsafeEnabled {
mi := &file_api_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ChangeStatusReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ChangeStatusReply) ProtoMessage() {}
func (x *ChangeStatusReply) ProtoReflect() protoreflect.Message {
mi := &file_api_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ChangeStatusReply.ProtoReflect.Descriptor instead.
func (*ChangeStatusReply) Descriptor() ([]byte, []int) {
return file_api_proto_rawDescGZIP(), []int{6}
}
func (x *ChangeStatusReply) GetNum() int64 {
if x != nil {
return x.Num
}
return 0
}
type CheckAndUpdateReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
Platform string `protobuf:"bytes,2,opt,name=platform,proto3" json:"platform,omitempty"`
Status int32 `protobuf:"varint,3,opt,name=status,proto3" json:"status,omitempty"`
DeviceType string `protobuf:"bytes,4,opt,name=device_type,json=deviceType,proto3" json:"device_type,omitempty"`
VersionCode string `protobuf:"bytes,5,opt,name=version_code,json=versionCode,proto3" json:"version_code,omitempty"`
Url string `protobuf:"bytes,6,opt,name=url,proto3" json:"url,omitempty"`
Force int32 `protobuf:"varint,7,opt,name=force,proto3" json:"force,omitempty"`
Description string `protobuf:"bytes,8,opt,name=description,proto3" json:"description,omitempty"`
OpeUser string `protobuf:"bytes,9,opt,name=ope_user,json=opeUser,proto3" json:"ope_user,omitempty"`
UpdateTime int64 `protobuf:"varint,10,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"`
CreateTime int64 `protobuf:"varint,11,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"`
}
func (x *CheckAndUpdateReply) Reset() {
*x = CheckAndUpdateReply{}
if protoimpl.UnsafeEnabled {
mi := &file_api_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CheckAndUpdateReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CheckAndUpdateReply) ProtoMessage() {}
func (x *CheckAndUpdateReply) ProtoReflect() protoreflect.Message {
mi := &file_api_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CheckAndUpdateReply.ProtoReflect.Descriptor instead.
func (*CheckAndUpdateReply) Descriptor() ([]byte, []int) {
return file_api_proto_rawDescGZIP(), []int{7}
}
func (x *CheckAndUpdateReply) GetId() int64 {
if x != nil {
return x.Id
}
return 0
}
func (x *CheckAndUpdateReply) GetPlatform() string {
if x != nil {
return x.Platform
}
return ""
}
func (x *CheckAndUpdateReply) GetStatus() int32 {
if x != nil {
return x.Status
}
return 0
}
func (x *CheckAndUpdateReply) GetDeviceType() string {
if x != nil {
return x.DeviceType
}
return ""
}
func (x *CheckAndUpdateReply) GetVersionCode() string {
if x != nil {
return x.VersionCode
}
return ""
}
func (x *CheckAndUpdateReply) GetUrl() string {
if x != nil {
return x.Url
}
return ""
}
func (x *CheckAndUpdateReply) GetForce() int32 {
if x != nil {
return x.Force
}
return 0
}
func (x *CheckAndUpdateReply) GetDescription() string {
if x != nil {
return x.Description
}
return ""
}
func (x *CheckAndUpdateReply) GetOpeUser() string {
if x != nil {
return x.OpeUser
}
return ""
}
func (x *CheckAndUpdateReply) GetUpdateTime() int64 {
if x != nil {
return x.UpdateTime
}
return 0
}
func (x *CheckAndUpdateReply) GetCreateTime() int64 {
if x != nil {
return x.CreateTime
}
return 0
}
var File_api_proto protoreflect.FileDescriptor
var file_api_proto_rawDesc = []byte{
0x0a, 0x09, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x64, 0x74, 0x61,
0x6c, 0x6b, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x22, 0xdc, 0x01, 0x0a, 0x0d, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08,
0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63,
0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64,
0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f,
0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65,
0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75,
0x72, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f,
0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x76, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69,
0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64,
0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xaf, 0x01, 0x0a, 0x0d, 0x55, 0x70,
0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x64,
0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a,
0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x66, 0x6f,
0x72, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x76, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69,
0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x22, 0x5e, 0x0a, 0x13, 0x43,
0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02,
0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01,
0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65,
0x76, 0x69, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x48, 0x0a, 0x15, 0x43,
0x68, 0x65, 0x63, 0x6b, 0x41, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x74,
0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63,
0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x1d, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52,
0x65, 0x70, 0x6c, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
0x52, 0x02, 0x69, 0x64, 0x22, 0x1f, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65,
0x70, 0x6c, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
0x52, 0x03, 0x6e, 0x75, 0x6d, 0x22, 0x25, 0x0a, 0x11, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53,
0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6e, 0x75,
0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6e, 0x75, 0x6d, 0x22, 0xc4, 0x02, 0x0a,
0x13, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x41, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52,
0x65, 0x70, 0x6c, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d,
0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05,
0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69,
0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64,
0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0b, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03,
0x75, 0x72, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x14,
0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x66,
0x6f, 0x72, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x5f, 0x75, 0x73,
0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x65, 0x55, 0x73, 0x65,
0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65,
0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69,
0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d,
0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54,
0x69, 0x6d, 0x65, 0x32, 0x56, 0x0a, 0x09, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72,
0x12, 0x49, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
0x6e, 0x12, 0x1c, 0x2e, 0x64, 0x74, 0x61, 0x6c, 0x6b, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e,
0x64, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x1a, 0x2e, 0x64, 0x74, 0x61, 0x6c, 0x6b, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, 0x29, 0x5a, 0x27, 0x67,
0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x33, 0x33, 0x2e, 0x63, 0x6e, 0x2f, 0x63, 0x68, 0x61, 0x74,
0x2f, 0x64, 0x74, 0x61, 0x6c, 0x6b, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x62,
0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_api_proto_rawDescOnce sync.Once
file_api_proto_rawDescData = file_api_proto_rawDesc
)
func file_api_proto_rawDescGZIP() []byte {
file_api_proto_rawDescOnce.Do(func() {
file_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_proto_rawDescData)
})
return file_api_proto_rawDescData
}
var file_api_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
var file_api_proto_goTypes = []interface{}{
(*CreateRequest)(nil), // 0: dtalk.backend.CreateRequest
(*UpdateRequest)(nil), // 1: dtalk.backend.UpdateRequest
(*ChangeStatusRequest)(nil), // 2: dtalk.backend.ChangeStatusRequest
(*CheckAndUpdateRequest)(nil), // 3: dtalk.backend.CheckAndUpdateRequest
(*CreateReply)(nil), // 4: dtalk.backend.CreateReply
(*UpdateReply)(nil), // 5: dtalk.backend.UpdateReply
(*ChangeStatusReply)(nil), // 6: dtalk.backend.ChangeStatusReply
(*CheckAndUpdateReply)(nil), // 7: dtalk.backend.CheckAndUpdateReply
}
var file_api_proto_depIdxs = []int32{
0, // 0: dtalk.backend.Generator.CreateVersion:input_type -> dtalk.backend.CreateRequest
4, // 1: dtalk.backend.Generator.CreateVersion:output_type -> dtalk.backend.CreateReply
1, // [1:2] is the sub-list for method output_type
0, // [0:1] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_api_proto_init() }
func file_api_proto_init() {
if File_api_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CreateRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpdateRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ChangeStatusRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CheckAndUpdateRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CreateReply); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpdateReply); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ChangeStatusReply); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CheckAndUpdateReply); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_api_proto_rawDesc,
NumEnums: 0,
NumMessages: 8,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_api_proto_goTypes,
DependencyIndexes: file_api_proto_depIdxs,
MessageInfos: file_api_proto_msgTypes,
}.Build()
File_api_proto = out.File
file_api_proto_rawDesc = nil
file_api_proto_goTypes = nil
file_api_proto_depIdxs = nil
}

View File

@@ -0,0 +1,67 @@
// protoc -I=. -I=$GOPATH/src --go_out=plugins=grpc:. *.proto
syntax = "proto3";
package dtalk.backend;
option go_package = "gitlab.33.cn/chat/dtalk/service/backend";
message CreateRequest{
string platform=1;
string description=2;
int32 force=3;
string url=4;
string version_code=5;
string version_name=6;
string device_type=7;
}
message UpdateRequest{
string description=1;
int32 force=2;
string url=3;
string version_code=4;
string version_name=5;
int64 id=6;
}
message ChangeStatusRequest{
int64 id=1;
int32 status=2;
string device_type=3;
}
message CheckAndUpdateRequest{
int64 id=1;
string device_type=2;
}
message CreateReply{
int64 id=1;
}
message UpdateReply{
int64 num=1;
}
message ChangeStatusReply{
int64 num=1;
}
message CheckAndUpdateReply{
int64 id=1;
string platform=2;
int32 status=3;
string device_type=4;
string version_code=5;
string url=6;
int32 force=7;
string description=8;
string ope_user=9;
int64 update_time=10;
int64 create_time=11;
}
service Generator {
rpc CreateVersion(CreateRequest) returns (CreateReply);
}

View File

@@ -0,0 +1,101 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
package backend
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// GeneratorClient is the client API for Generator service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type GeneratorClient interface {
CreateVersion(ctx context.Context, in *CreateRequest, opts ...grpc.CallOption) (*CreateReply, error)
}
type generatorClient struct {
cc grpc.ClientConnInterface
}
func NewGeneratorClient(cc grpc.ClientConnInterface) GeneratorClient {
return &generatorClient{cc}
}
func (c *generatorClient) CreateVersion(ctx context.Context, in *CreateRequest, opts ...grpc.CallOption) (*CreateReply, error) {
out := new(CreateReply)
err := c.cc.Invoke(ctx, "/dtalk.backend.Generator/CreateVersion", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// GeneratorServer is the server API for Generator service.
// All implementations must embed UnimplementedGeneratorServer
// for forward compatibility
type GeneratorServer interface {
CreateVersion(context.Context, *CreateRequest) (*CreateReply, error)
mustEmbedUnimplementedGeneratorServer()
}
// UnimplementedGeneratorServer must be embedded to have forward compatible implementations.
type UnimplementedGeneratorServer struct {
}
func (UnimplementedGeneratorServer) CreateVersion(context.Context, *CreateRequest) (*CreateReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateVersion not implemented")
}
func (UnimplementedGeneratorServer) mustEmbedUnimplementedGeneratorServer() {}
// UnsafeGeneratorServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to GeneratorServer will
// result in compilation errors.
type UnsafeGeneratorServer interface {
mustEmbedUnimplementedGeneratorServer()
}
func RegisterGeneratorServer(s grpc.ServiceRegistrar, srv GeneratorServer) {
s.RegisterService(&Generator_ServiceDesc, srv)
}
func _Generator_CreateVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GeneratorServer).CreateVersion(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/dtalk.backend.Generator/CreateVersion",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GeneratorServer).CreateVersion(ctx, req.(*CreateRequest))
}
return interceptor(ctx, in, info, handler)
}
// Generator_ServiceDesc is the grpc.ServiceDesc for Generator service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Generator_ServiceDesc = grpc.ServiceDesc{
ServiceName: "dtalk.backend.Generator",
HandlerType: (*GeneratorServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "CreateVersion",
Handler: _Generator_CreateVersion_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "api.proto",
}

View File

@@ -0,0 +1,6 @@
#!/bin/sh
protoc -I. -I$GOPATH/src \
--go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
*.proto

Binary file not shown.

View File

@@ -0,0 +1,89 @@
package main
import (
"context"
"flag"
"fmt"
"os"
"os/signal"
"syscall"
"time"
"github.com/inconshreveable/log15"
"gitlab.33.cn/chat/dtalk/service/backend/config"
"gitlab.33.cn/chat/dtalk/service/backend/server/http"
"gitlab.33.cn/chat/dtalk/service/backend/service"
)
const srvName = "backend"
var (
// projectVersion 项目版本
projectVersion = "0.2.3"
// goVersion go版本
goVersion = ""
// gitCommit git提交commit id
gitCommit = ""
// buildTime 编译时间
buildTime = ""
isShowVersion = flag.Bool("v", false, "show project version")
)
// showVersion 显示项目版本信息
func showVersion(isShow bool) {
if isShow {
fmt.Printf("Project: %s\n", srvName)
fmt.Printf(" Version: %s\n", projectVersion)
fmt.Printf(" Go Version: %s\n", goVersion)
fmt.Printf(" Git Commit: %s\n", gitCommit)
fmt.Printf(" Build Time: %s\n", buildTime)
os.Exit(0)
}
}
var log = log15.New("cmd", srvName)
// @Title 聊天单模块集成测试
// @Version 0.1
// @Description
// @SecurityDefinitions.ApiKey ApiKeyAuth
// @In header
// @Name Authorization
// @BasePath /
func main() {
flag.Parse()
showVersion(*isShowVersion)
if err := config.Init(); err != nil {
panic(err)
}
log.Info("config info:",
"Server", *config.Conf.Server)
// service init
svc := service.New(config.Conf)
httpSrv := http.Init(svc)
// init signal
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
s := <-c
log.Info("service get a signal %s", s.String())
switch s {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := httpSrv.Shutdown(ctx); err != nil {
log.Error("server shutdown:", "err", err)
}
time.Sleep(time.Second * 2)
log.Info(srvName + " server exit")
return
case syscall.SIGHUP:
// TODO reload
default:
return
}
}
}

View File

@@ -0,0 +1,36 @@
Env = "debug"
Platform = "谈信公安版"
CdkMod = false # true 表示开启 cdk 模块, false 表示关闭
[server]
addr = "0.0.0.0:18102"
[MySQL]
Host = "127.0.0.1" # changeme (mysql 服务地址)
Port = 3306 # changeme (mysql 服务端口)
User = "root" # changeme (mysql 账号)
Pwd = "123456" # changeme (mysql 密码)
Db = "dtalk"
[Debug]
Flag = false # changeme (线上环境为 false, 测试环境可以为 true)
[Release]
Key = "123321"
Issuer = "Bob"
TokenExpireDuration = 86400000000000
UserName = "root" # changeme (后台账号)
Password = "root" # changeme (后台密码)
[IdGenRPCClient]
RegAddrs = "127.0.0.1:2379" # changeme (generator 服务注册的 etcd 地址)
Schema = "dtalk"
SrvName = "generator"
Dial = "1s"
Timeout = "1s"
# CdkMod = false 可不配置
[chain33Client]
BlockChainAddr= "172.16.101.87:8902" # changeme (钱包查询服务的 rpc 端口)
Title="user.p.testproofv2."

View File

@@ -0,0 +1,116 @@
package config
import (
"flag"
"github.com/BurntSushi/toml"
xtime "gitlab.33.cn/chat/dtalk/pkg/time"
"time"
)
var (
confPath string
Conf *Config
)
func init() {
flag.StringVar(&confPath, "conf", "backend.toml", "default config path.")
}
// Init init config.
func Init() (err error) {
Conf = Default()
_, err = toml.DecodeFile(confPath, &Conf)
return
}
func Default() *Config {
return &Config{
Env: "debug",
Platform: "chat33pro",
Server: &HttpServer{
Addr: "0.0.0.0:18202",
},
MySQL: &MySQL{
Host: "127.0.0.1",
Port: 3306,
User: "root",
Pwd: "123456",
Db: "dtalk",
},
Debug: &Debug{
Flag: false,
},
Release: &Release{
Key: "123321",
Issuer: "Bob",
TokenExpireDuration: 86400000000000,
UserName: "root",
Password: "root",
},
IdGenRPCClient: &RPCClient{
RegAddrs: "127.0.0.1:2379",
Schema: "dtalk",
SrvName: "generator",
Dial: xtime.Duration(time.Second),
Timeout: xtime.Duration(time.Second),
},
CdkMaxNumber: 10,
Chain33Client: Chain33Client{
BlockChainAddr: "",
Title: "",
},
CdkMod: false,
}
}
type Config struct {
Env string
Platform string
Server *HttpServer
MySQL *MySQL
Debug *Debug
Release *Release
IdGenRPCClient *RPCClient
CdkMaxNumber int64
Chain33Client Chain33Client
CdkMod bool
}
type HttpServer struct {
Addr string
}
type MySQL struct {
Host string
Port int32
User string
Pwd string
Db string
}
type Debug struct {
Flag bool
}
type Release struct {
Key string
Issuer string
TokenExpireDuration time.Duration
UserName string
Password string
}
// RPCClient is RPC client config.
type RPCClient struct {
RegAddrs string // etcd addrs, seperate by ','
Schema string
SrvName string // call
Dial xtime.Duration
Timeout xtime.Duration
}
type Chain33Client struct {
BlockChainAddr string
Title string
}

View File

@@ -0,0 +1,418 @@
package dao
import (
"gitlab.33.cn/chat/dtalk/pkg/util"
"gitlab.33.cn/chat/dtalk/service/backend/model/db"
"gitlab.33.cn/utils/go-kit/convert"
"math"
"strings"
"time"
)
const (
_InsertCdkType = `INSERT INTO dtalk_cdk_info ( cdk_id, cdk_name, cdk_info, coin_name, exchange_rate, create_time, update_time, delete_time)VALUES( ?, ?, ?, ?, ?, ?, ?, ?)`
_GetCdkTypes = `SELECT * FROM dtalk_cdk_info WHERE delete_time = 0 AND coin_name LIKE ? ORDER BY create_time DESC LIMIT ?,?`
_DeleteCdkType = `UPDATE dtalk_cdk_info SET delete_time = ? WHERE cdk_id = ? AND delete_time = 0`
_InsertCdk = `INSERT INTO dtalk_cdk_list ( id, cdk_id, cdk_content, user_id, cdk_status, order_id, create_time, update_time, delete_time, exchange_time)VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
_GetCdks = `SELECT * FROM dtalk_cdk_list WHERE delete_time = 0 AND cdk_id = ? AND cdk_content LIKE ? ORDER BY create_time DESC LIMIT ?,?`
_DeleteCdk = `UPDATE dtalk_cdk_list SET delete_time = ? WHERE id = ? AND delete_time = 0`
_UpdateCdkStatus = `UPDATE dtalk_cdk_list SET cdk_status = ?, update_time = ? WHERE id = ? AND delete_time = 0`
_UpdateCdkUserId = `UPDATE dtalk_cdk_list SET user_id = ?, update_time = ? WHERE id = ? AND delete_time = 0`
_UpdateCdkOrderId = `UPDATE dtalk_cdk_list SET order_id = ?, cdk_status = 1, update_time = ? WHERE id = ? AND delete_time = 0`
_GetCdkTypesCount = `SELECT COUNT(*) FROM dtalk_cdk_info WHERE delete_time = 0 AND coin_name LIKE ?`
_GetCdksCount = `SELECT COUNT(*) FROM dtalk_cdk_list WHERE delete_time = 0 AND cdk_id = ?`
_GetCdksWithUserId = `SELECT * FROM dtalk_cdk_list WHERE delete_time = 0 AND user_id = ? AND cdk_status >= ? ORDER BY create_time DESC LIMIT ?,?`
_GetCdksCountWithUserId = `SELECT COUNT(*) FROM dtalk_cdk_list WHERE delete_time = 0 AND user_id = ? AND cdk_status >= ?`
_GetCdkTypesWithCoinName = `SELECT * FROM dtalk_cdk_info WHERE delete_time = 0 AND coin_name = ?`
_GetUnusedCdksCount = `SELECT COUNT(*) FROM dtalk_cdk_list WHERE delete_time = 0 AND cdk_id = ? AND cdk_status = 0`
_GetFrozenCdksCount = `SELECT COUNT(*) FROM dtalk_cdk_list WHERE delete_time = 0 AND cdk_id = ? AND cdk_status = 1`
_GetUsedCdksCount = `SELECT COUNT(*) FROM dtalk_cdk_list WHERE delete_time = 0 AND cdk_id = ? AND cdk_status >= 2`
_GetCdkType = `SELECT * FROM dtalk_cdk_info WHERE delete_time = 0 AND cdk_id = ?`
_DeleteCdks = `UPDATE dtalk_cdk_list SET delete_time = ? WHERE delete_time = 0 AND id in `
_DeleteCdkTypes = `UPDATE dtalk_cdk_info SET delete_time = ? WHERE delete_time = 0 AND cdk_id in `
_DeleteCdksByCdkIds = `UPDATE dtalk_cdk_list SET delete_time = ? WHERE delete_time = 0 AND cdk_id in `
_UpdateCdkType = `UPDATE dtalk_cdk_info SET cdk_name = ?, coin_name = ?, exchange_rate = ?, update_time = ? WHERE delete_time = 0 AND cdk_id = ?`
_GetCdksByOrderId = `SELECT * FROM dtalk_cdk_list WHERE delete_time = 0 AND order_id = ?`
_UpdateCdksStatus = `UPDATE dtalk_cdk_list SET cdk_status = ?, update_time = ?, exchange_time = ? WHERE delete_time = 0 AND id in `
_FrozenCdksStatus = `UPDATE dtalk_cdk_list SET cdk_status = ?, user_id = ?, order_id = ?, update_time = ? WHERE delete_time = 0 AND id in `
_GetUnusedCdks = `SELECT * FROM dtalk_cdk_list WHERE cdk_id = ? AND cdk_status = ? AND delete_time = 0 ORDER BY create_time ASC LIMIT 0,?`
_CheckCdkExist = `SELECT COUNT(*) FROM dtalk_cdk_list WHERE delete_time = 0 AND cdk_id = ? AND cdk_content = ?`
_GetFrozenCdks = `SElECT * FROM dtalk_cdk_list WHERE delete_time = 0 AND cdk_status = 1`
_CleanFrozenCdks = `UPDATE dtalk_cdk_list SET cdk_status = ?, update_time = ? WHERE delete_time = 0 AND order_id = ?`
_GetCdksCountByUserIdAndCdkId = `SELECT COUNT(*) FROM dtalk_cdk_list WHERE delete_time = 0 AND cdk_id = ? AND user_id = ? AND cdk_status >= 1`
)
func (d *Dao) InsertCdkType(cdkType *db.CdkType) error {
_, _, err := d.conn.Exec(_InsertCdkType, cdkType.CdkId, cdkType.CdkName, cdkType.CdkInfo, cdkType.CoinName, cdkType.ExchangeRate, cdkType.CreateTime, cdkType.UpdateTime, cdkType.DeleteTime)
return err
}
func (d *Dao) InsertCdk(cdk *db.Cdk) error {
_, _, err := d.conn.Exec(_InsertCdk, cdk.Id, cdk.CdkId, cdk.CdkContent, cdk.UserId, cdk.CdkStatus, cdk.OrderId, cdk.CreateTime, cdk.UpdateTime, cdk.DeleteTime, cdk.ExchangeTime)
return err
}
func (d *Dao) DeleteCdkType(cdkId int64, deleteTime int64) error {
_, _, err := d.conn.Exec(_DeleteCdkType, deleteTime, cdkId)
return err
}
func (d *Dao) DeleteCdk(id int64, deleteTime int64) error {
_, _, err := d.conn.Exec(_DeleteCdk, deleteTime, id)
return err
}
func (d *Dao) DeleteCdks(ids []int64, deleteTime int64) error {
idStrs := make([]string, 0, len(ids))
for _, id := range ids {
idStrs = append(idStrs, convert.ToString(id))
}
idStr := "(" + strings.Join(idStrs, ",") + ")"
execSql := _DeleteCdks + idStr
_, _, err := d.conn.Exec(execSql, deleteTime)
return err
}
func (d *Dao) DeleteCdkTypes(cdkIds []int64) error {
idStrs := make([]string, 0, len(cdkIds))
for _, id := range cdkIds {
idStrs = append(idStrs, convert.ToString(id))
}
idStr := "(" + strings.Join(idStrs, ",") + ")"
execSql := _DeleteCdkTypes + idStr
_, _, err := d.conn.Exec(execSql, d.getNowTime())
return err
}
func (d *Dao) DeleteCdksByCdkIds(cdkIds []int64) error {
idStrs := make([]string, 0, len(cdkIds))
for _, id := range cdkIds {
idStrs = append(idStrs, convert.ToString(id))
}
idStr := "(" + strings.Join(idStrs, ",") + ")"
execSql := _DeleteCdksByCdkIds + idStr
_, _, err := d.conn.Exec(execSql, d.getNowTime())
return err
}
func (d *Dao) UpdateCdkType(cdkId int64, cdkName, coinName string, exchangeRate int64) error {
_, _, err := d.conn.Exec(_UpdateCdkType, cdkName, coinName, exchangeRate, d.getNowTime(), cdkId)
return err
}
func (d *Dao) UpdateCdkStatus(id int64, cdkStatus int32) error {
_, _, err := d.conn.Exec(_UpdateCdkStatus, cdkStatus, d.getNowTime(), id)
return err
}
func (d *Dao) UpdateCdkUserId(id int64, userId int64) error {
_, _, err := d.conn.Exec(_UpdateCdkUserId, userId, d.getNowTime(), id)
return err
}
func (d *Dao) UpdateCdkOrderId(id int64, orderId int64) error {
_, _, err := d.conn.Exec(_UpdateCdkOrderId, orderId, d.getNowTime(), id)
return err
}
func (d *Dao) GetCdkType(cdkId int64) (*db.CdkType, error) {
var records []map[string]string
records, err := d.conn.Query(_GetCdkType, cdkId)
if err != nil {
return nil, err
}
response, err := d.ToCdkTypes(records)
if err != nil {
return nil, err
}
if len(response) == 0 {
return nil, nil
}
return &response[0], nil
}
func (d *Dao) GetCdkTypes(coinName string, page int64, size int64) ([]db.CdkType, int64, int64, error) {
var records []map[string]string
offset := page * size
if coinName == "" {
coinName = "%"
}
records, err := d.conn.Query(_GetCdkTypes, coinName, offset, size)
if err != nil {
return nil, 0, 0, err
}
response, err := d.ToCdkTypes(records)
if err != nil {
return nil, 0, 0, err
}
if coinName == "" {
coinName = "%"
}
recordsCount, err := d.conn.Query(_GetCdkTypesCount, coinName)
if err != nil {
return nil, 0, 0, err
}
totalElements := convert.ToInt64(recordsCount[0]["COUNT(*)"])
totalPages := int64(math.Ceil(float64(totalElements) / float64(size)))
return response, totalElements, totalPages, nil
}
func (d *Dao) GetCdks(cdkId int64, cdkContent string, page int64, size int64) ([]db.Cdk, int64, int64, error) {
var records []map[string]string
offset := page * size
cdkContent += "%"
records, err := d.conn.Query(_GetCdks, cdkId, cdkContent, offset, size)
if err != nil {
return nil, 0, 0, err
}
response, err := d.ToCdks(records)
if err != nil {
return nil, 0, 0, err
}
recordsCount, err := d.conn.Query(_GetCdksCount, cdkId)
if err != nil {
return nil, 0, 0, err
}
totalElements := convert.ToInt64(recordsCount[0]["COUNT(*)"])
totalPages := int64(math.Ceil(float64(totalElements) / float64(size)))
return response, totalElements, totalPages, nil
}
func (d *Dao) GetCdksWithUserId(userId string, page int64, size int64) ([]db.Cdk, int64, int64, error) {
var records []map[string]string
offset := page * size
records, err := d.conn.Query(_GetCdksWithUserId, userId, db.CdkFrozen, offset, size)
if err != nil {
return nil, 0, 0, err
}
response, err := d.ToCdks(records)
if err != nil {
return nil, 0, 0, err
}
recordsCount, err := d.conn.Query(_GetCdksCountWithUserId, userId, db.CdkFrozen)
if err != nil {
return nil, 0, 0, err
}
totalElements := convert.ToInt64(recordsCount[0]["COUNT(*)"])
totalPages := int64(math.Ceil(float64(totalElements) / float64(size)))
return response, totalElements, totalPages, nil
}
func (d *Dao) GetCdkTypesWithCoinName(coinName string) ([]db.CdkType, error) {
var records []map[string]string
records, err := d.conn.Query(_GetCdkTypesWithCoinName, coinName)
if err != nil {
return nil, err
}
response, err := d.ToCdkTypes(records)
if err != nil {
return nil, err
}
return response, nil
}
func (d *Dao) GetCdksCount(cdkId int64) (int64, int64, int64, error) {
res, err := d.conn.Query(_GetUnusedCdksCount, cdkId)
if err != nil {
return 0, 0, 0, err
}
Unused := convert.ToInt64(res[0]["COUNT(*)"])
res, err = d.conn.Query(_GetFrozenCdksCount, cdkId)
if err != nil {
return 0, 0, 0, err
}
Frozen := convert.ToInt64(res[0]["COUNT(*)"])
res, err = d.conn.Query(_GetUsedCdksCount, cdkId)
if err != nil {
return 0, 0, 0, err
}
Used := util.ToInt64(res[0]["COUNT(*)"])
return Unused, Frozen, Used, nil
}
func (d *Dao) GetUnusedCdksCount(cdkId string) (int64, error) {
recordsCount, err := d.conn.Query(_GetUnusedCdksCount, cdkId)
if err != nil {
return 0, err
}
response := convert.ToInt64(recordsCount[0]["COUNT(*)"])
return response, nil
}
func (d *Dao) GetFrozenCdksCount(cdkId string) (int64, error) {
recordsCount, err := d.conn.Query(_GetFrozenCdksCount, cdkId)
if err != nil {
return 0, err
}
response := convert.ToInt64(recordsCount[0]["COUNT(*)"])
return response, nil
}
func (d *Dao) GetUsedCdksCount(cdkId string) (int64, error) {
recordsCount, err := d.conn.Query(_GetUsedCdksCount, cdkId)
if err != nil {
return 0, err
}
response := convert.ToInt64(recordsCount[0]["COUNT(*)"])
return response, nil
}
func (d *Dao) ToCdkTypes(records []map[string]string) ([]db.CdkType, error) {
cdkTypes := make([]db.CdkType, len(records), len(records))
for i, record := range records {
cdkType := db.CdkType{
CdkId: convert.ToInt64(record["cdk_id"]),
CdkName: record["cdk_name"],
CdkInfo: record["cdl_info"],
CoinName: record["coin_name"],
ExchangeRate: convert.ToInt64(record["exchange_rate"]),
TimeInfo: db.TimeInfo{
CreateTime: convert.ToInt64(record["create_time"]),
UpdateTime: convert.ToInt64(record["update_time"]),
DeleteTime: convert.ToInt64(record["delete_time"]),
},
}
cdkTypes[i] = cdkType
}
return cdkTypes, nil
}
func (d *Dao) ToCdks(records []map[string]string) ([]db.Cdk, error) {
cdks := make([]db.Cdk, len(records), len(records))
for i, record := range records {
cdk := db.Cdk{
Id: convert.ToInt64(record["id"]),
CdkId: convert.ToInt64(record["cdk_id"]),
CdkContent: record["cdk_content"],
UserId: record["user_id"],
CdkStatus: convert.ToInt32(record["cdk_status"]),
OrderId: convert.ToInt64(record["order_id"]),
TimeInfo: db.TimeInfo{
CreateTime: convert.ToInt64(record["create_time"]),
UpdateTime: convert.ToInt64(record["update_time"]),
DeleteTime: convert.ToInt64(record["delete_time"]),
},
ExchangeTime: convert.ToInt64(record["exchange_time"]),
}
//fmt.Println(cdk)
cdks[i] = cdk
}
return cdks, nil
}
func (d *Dao) UpdateCdksStatus(ids []int64, status int64) error {
idStrs := make([]string, 0, len(ids))
for _, id := range ids {
idStrs = append(idStrs, convert.ToString(id))
}
idStr := "(" + strings.Join(idStrs, ",") + ")"
execSql := _UpdateCdksStatus + idStr
var exchangeTime int64
if status == db.CdkUsed || status == db.CdkExchange {
exchangeTime = d.getNowTime()
}
_, _, err := d.conn.Exec(execSql, status, d.getNowTime(), exchangeTime)
return err
}
func (d *Dao) GetCdksByOrderId(orderId int64) ([]db.Cdk, error) {
var records []map[string]string
records, err := d.conn.Query(_GetCdksByOrderId, orderId)
if err != nil {
return nil, err
}
response, err := d.ToCdks(records)
if err != nil {
return nil, err
}
return response, nil
}
func (d *Dao) GetUnusedCdks(cdkId int64, number int64) ([]db.Cdk, error) {
var records []map[string]string
records, err := d.conn.Query(_GetUnusedCdks, cdkId, db.CdkUnused, number)
if err != nil {
return nil, err
}
response, err := d.ToCdks(records)
if err != nil {
return nil, err
}
return response, nil
}
func (d *Dao) FrozenCdksStatus(ids []int64, userId string, orderId int64) error {
idStrs := make([]string, 0, len(ids))
for _, id := range ids {
idStrs = append(idStrs, convert.ToString(id))
}
idStr := "(" + strings.Join(idStrs, ",") + ")"
execSql := _FrozenCdksStatus + idStr
_, _, err := d.conn.Exec(execSql, db.CdkFrozen, userId, orderId, d.getNowTime())
return err
}
func (d *Dao) getNowTime() int64 {
return time.Now().UnixNano() / 1e6
}
func (d *Dao) CheckCdkExist(cdkId int64, cdkContent string) (bool, error) {
recordsCount, err := d.conn.Query(_CheckCdkExist, cdkId, cdkContent)
if err != nil {
return false, err
}
response := convert.ToInt64(recordsCount[0]["COUNT(*)"])
return response >= 1, nil
}
func (d *Dao) GetFrozenCdks() ([]db.Cdk, error) {
var records []map[string]string
records, err := d.conn.Query(_GetFrozenCdks)
if err != nil {
return nil, err
}
response, err := d.ToCdks(records)
if err != nil {
return nil, err
}
return response, nil
}
func (d *Dao) CleanFrozenCdks(orderId int64) error {
_, _, err := d.conn.Exec(_CleanFrozenCdks, db.CdkUnused, d.getNowTime(), orderId)
if err != nil {
return err
}
return nil
}
func (d *Dao) GetCdksCountByUserIdAndCdkId(cdkId int64, userId string) (int64, error) {
recordsCount, err := d.conn.Query(_GetCdksCountByUserIdAndCdkId, cdkId, userId)
if err != nil {
return 0, err
}
response := convert.ToInt64(recordsCount[0]["COUNT(*)"])
return response, nil
}

View File

@@ -0,0 +1,31 @@
package dao
import (
"fmt"
"github.com/inconshreveable/log15"
"gitlab.33.cn/chat/dtalk/pkg/mysql"
"gitlab.33.cn/chat/dtalk/service/backend/config"
)
type Dao struct {
log log15.Logger
conn *mysql.MysqlConn
}
func New(c *config.Config) *Dao {
d := &Dao{
log: log15.New("module", "backend/dao"),
conn: newDB(c.MySQL),
}
return d
}
func newDB(cfg *config.MySQL) *mysql.MysqlConn {
c, err := mysql.NewMysqlConn(cfg.Host, fmt.Sprintf("%v", cfg.Port),
cfg.User, cfg.Pwd, cfg.Db, "UTF8MB4")
if err != nil {
log15.Error("mysql init failed", "err", err)
panic(err)
}
return c
}

View File

@@ -0,0 +1,159 @@
package dao
import (
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
"gitlab.33.cn/chat/dtalk/pkg/util"
"gitlab.33.cn/chat/dtalk/service/backend/model"
"math"
)
const (
_InsertVersionInfo = `INSERT INTO dtalk_ver_backend ( platform, state, device_type, version_code, version_name, download_url, force_update,size,md5, description, ope_user, update_time, create_time)VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ,?,?)`
_UpdateVersionInfo = `UPDATE dtalk_ver_backend SET version_name=?,version_code=?,download_url=?,size=?,md5=?,description=?,force_update=?,update_time=?,ope_user=? WHERE id=?`
_ChangeVersionStatus = `UPDATE dtalk_ver_backend SET state=1,update_time=?,ope_user=? WHERE id=?`
_QueryOtherReleaseVersionInfo = `SELECT * FROM dtalk_ver_backend WHERE id!=? AND device_type=? AND platform=? AND state=1`
_ChangeOtherReleaseVersionStatus = `UPDATE dtalk_ver_backend SET state=0,update_time=?,ope_user=? WHERE id=?`
_GetVersionList = `SELECT * FROM dtalk_ver_backend WHERE platform LIKE ? AND device_type LIKE ? ORDER BY create_time DESC LIMIT ?,?`
_GetVersionCount = `SELECT COUNT(*) FROM dtalk_ver_backend WHERE platform LIKE ? AND device_type LIKE ?`
_GetForceVersionCount = `SELECT COUNT(*) AS force_num FROM dtalk_ver_backend WHERE force_update = 1 AND version_code > ? AND version_code < ?`
_GetReleaseVersionInfo = `SELECT * FROM dtalk_ver_backend WHERE device_type=? AND platform=? AND state = 1 ORDER BY id DESC LIMIT 1`
_QueryVersionInfoById = `SELECT * FROM dtalk_ver_backend WHERE id=?`
)
func (d *Dao) InsertVersion(form *model.VersionForm) (int64, int64, error) {
num, lastId, err := d.conn.Exec(_InsertVersionInfo, form.Platform, form.Status, form.DeviceType, form.VersionCode, form.VersionName, form.Url, form.Force, form.Size, form.Md5, form.Description.ToString(), form.OpeUser, form.UpdateTime, form.CreateTime)
return num, lastId, err
}
func (d *Dao) UpdateVersion(form *model.VersionForm) (*model.VersionForm, error) {
_, _, err := d.conn.Exec(_UpdateVersionInfo, form.VersionName, form.VersionCode, form.Url, form.Size, form.Md5, form.Description.ToString(), form.Force, form.UpdateTime, form.OpeUser, form.Id)
if err != nil {
return nil, err
}
records, err := d.conn.Query(_QueryVersionInfoById, form.Id)
if err != nil {
return nil, err
}
if len(records) < 1 {
return nil, xerror.NewError(xerror.ParamsError).SetExtMessage("无此id的记录")
}
record := records[0]
version, err := model.ConvertVersionForm(&record)
if err != nil {
return nil, err
}
return version, nil
}
func (d *Dao) ChangeVersionStatus(form *model.VersionForm) error {
tx, err := d.conn.NewTx()
if err != nil {
return err
}
_, _, err = tx.Exec(_ChangeVersionStatus, form.UpdateTime, form.OpeUser, form.Id)
if err != nil {
return err
}
records, err := tx.Query(_QueryVersionInfoById, form.Id)
if err != nil {
return err
}
if len(records) == 0 {
return xerror.NewError(xerror.ParamsError).SetExtMessage("无此id的记录")
}
deviceType := records[0]["device_type"]
platform := records[0]["platform"]
records, err = tx.Query(_QueryOtherReleaseVersionInfo, form.Id, deviceType, platform)
if err != nil {
return err
}
if len(records) == 0 {
err = tx.Commit()
if err != nil {
return err
}
return nil
}
id := util.ToInt64(records[0]["id"])
_, _, err = tx.Exec(_ChangeOtherReleaseVersionStatus, form.UpdateTime, form.OpeUser, id)
if err != nil {
return err
}
err = tx.Commit()
if err != nil {
return err
}
return nil
}
func (d *Dao) GetVersionList(form *model.VersionForm, page int64, size int64) (*[]model.VersionForm, int64, int64, error) {
var records []map[string]string
offset := page * size
records, err := d.conn.Query(_GetVersionList, form.Platform, form.DeviceType, offset, size)
if err != nil {
return nil, 0, 0, err
}
response, err := d.ConvertVersionList(&records)
if err != nil {
return nil, 0, 0, err
}
countRecords, err := d.conn.Query(_GetVersionCount, form.Platform, form.DeviceType)
if err != nil {
return nil, 0, 0, err
}
totalElements := util.ToInt64(countRecords[0]["COUNT(*)"])
totalPages := int64(math.Ceil(float64(totalElements) / float64(size)))
return response, totalElements, totalPages, nil
}
func (d *Dao) CheckAndUpdateVersion(form *model.VersionForm) (*model.VersionForm, error) {
records, err := d.conn.Query(_GetReleaseVersionInfo, form.DeviceType, form.Platform)
if err != nil {
return nil, err
}
if len(records) < 1 {
return &model.VersionForm{}, nil
}
record, err := model.ConvertVersionForm(&records[0])
if err != nil {
return nil, err
}
if !record.Force {
//判断期间是否包含强制更新版本
record.Force, _ = d.checkHaveForce(util.ToInt(form.VersionCode), util.ToInt(record.VersionCode))
}
return record, nil
}
func (d *Dao) ConvertVersionList(records *[]map[string]string) (*[]model.VersionForm, error) {
//var versionList []model.VersionForm
versionList := make([]model.VersionForm, len(*records), len(*records))
for i, record := range *records {
version, err := model.ConvertVersionForm(&record)
if err != nil {
return nil, err
}
versionList[i] = *version
}
return &versionList, nil
}
func (d *Dao) checkHaveForce(oldVer, newVer int) (bool, error) {
if oldVer >= newVer {
return false, nil
}
records, err := d.conn.Query(_GetForceVersionCount, oldVer, newVer)
if err != nil {
return false, err
}
if len(records) < 1 {
return false, nil
}
num := util.ToInt64(records[0]["force_num"])
return num > 0, nil
}

View File

@@ -0,0 +1,954 @@
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
// This file was generated by swaggo/swag
package docs
import (
"bytes"
"encoding/json"
"strings"
"github.com/alecthomas/template"
"github.com/swaggo/swag"
)
var doc = `{
"schemes": {{ marshal .Schemes }},
"swagger": "2.0",
"info": {
"description": "{{.Description}}",
"title": "{{.Title}}",
"contact": {},
"version": "{{.Version}}"
},
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/app/cdk/create-cdk-order": {
"post": {
"tags": [
"Cdk App"
],
"summary": "创建兑换订单",
"parameters": [
{
"type": "string",
"description": "MOCK",
"name": "FZM-SIGNATURE",
"in": "header",
"required": true
},
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.CreateCdkOrderReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.CreateCdkOrderResp"
}
}
}
]
}
}
}
}
},
"/app/cdk/deal-cdk-order": {
"post": {
"tags": [
"Cdk App"
],
"summary": "处理兑换订单",
"parameters": [
{
"type": "string",
"description": "MOCK",
"name": "FZM-SIGNATURE",
"in": "header",
"required": true
},
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.DealCdkOrderReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.DealCdkOrderResp"
}
}
}
]
}
}
}
}
},
"/app/cdk/get-cdk-type-by-coin-name": {
"post": {
"tags": [
"Cdk App"
],
"summary": "查询一个票券对应的 cdkType",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.GetCdkTypeByCoinNameReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.GetCdkTypeByCoinNameResp"
}
}
}
]
}
}
}
}
},
"/app/cdk/get-cdks-by-user-id": {
"post": {
"tags": [
"Cdk App"
],
"summary": "分页获得一个人拥有的 cdks",
"parameters": [
{
"type": "string",
"description": "MOCK",
"name": "FZM-SIGNATURE",
"in": "header",
"required": true
},
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.GetCdksByUserIdReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.GetCdksByUserIdResp"
}
}
}
]
}
}
}
}
},
"/backend/cdk/create-cdk-type": {
"post": {
"tags": [
"Cdk 后台"
],
"summary": "创建 CdkType",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.CreateCdkTypeReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.CreateCdkTypeResp"
}
}
}
]
}
}
}
}
},
"/backend/cdk/create-cdks": {
"post": {
"tags": [
"Cdk 后台"
],
"summary": "创建 Cdks",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.CreateCdksReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.CreateCdksResp"
}
}
}
]
}
}
}
}
},
"/backend/cdk/delete-cdk-types": {
"post": {
"tags": [
"Cdk 后台"
],
"summary": "删除 cdkTypes",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.DeleteCdkTypesReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.DeleteCdkTypesResp"
}
}
}
]
}
}
}
}
},
"/backend/cdk/delete-cdks": {
"post": {
"tags": [
"Cdk 后台"
],
"summary": "删除 cdks",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.DeleteCdksReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.DeleteCdksResp"
}
}
}
]
}
}
}
}
},
"/backend/cdk/exchange-cdks": {
"post": {
"tags": [
"Cdk 后台"
],
"summary": "兑换 cdks",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.ExchangeCdksReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.ExchangeCdksResp"
}
}
}
]
}
}
}
}
},
"/backend/cdk/get-cdk-types": {
"post": {
"tags": [
"Cdk 查询"
],
"summary": "分页获得 cdkType",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.GetCdkTypesReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.GetCdkTypesResp"
}
}
}
]
}
}
}
}
},
"/backend/cdk/get-cdks": {
"post": {
"tags": [
"Cdk 查询"
],
"summary": "分页获得 cdks",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.GetCdksReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.GetCdksResp"
}
}
}
]
}
}
}
}
},
"/backend/cdk/update-cdk-type": {
"post": {
"tags": [
"Cdk 后台"
],
"summary": "更新 cdkType",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.UpdateCdkTypeReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.UpdateCdkTypeResp"
}
}
}
]
}
}
}
}
}
},
"definitions": {
"types.Cdk": {
"type": "object",
"properties": {
"cdkContent": {
"type": "string"
},
"cdkId": {
"type": "string"
},
"cdkName": {
"type": "string"
},
"cdkStatus": {
"type": "integer"
},
"createTime": {
"type": "string"
},
"exchangeTime": {
"type": "string"
},
"id": {
"type": "string"
},
"orderId": {
"type": "string"
},
"userId": {
"type": "string"
}
}
},
"types.CdkType": {
"type": "object",
"properties": {
"cdkAvailable": {
"description": "未发放的cdk数量",
"type": "integer"
},
"cdkFrozen": {
"description": "冻结状态中的cdk数量",
"type": "integer"
},
"cdkId": {
"type": "string"
},
"cdkInfo": {
"type": "string"
},
"cdkName": {
"type": "string"
},
"cdkUsed": {
"description": "已发放的cdk数量",
"type": "integer"
},
"coinName": {
"type": "string"
},
"exchangeRate": {
"type": "integer"
}
}
},
"types.CreateCdkOrderReq": {
"type": "object",
"required": [
"cdkId",
"number"
],
"properties": {
"cdkId": {
"description": "cdk 种类编号",
"type": "string"
},
"number": {
"description": "兑换数量",
"type": "integer"
}
}
},
"types.CreateCdkOrderResp": {
"type": "object",
"properties": {
"orderId": {
"description": "订单编号",
"type": "string"
}
}
},
"types.CreateCdkTypeReq": {
"type": "object",
"required": [
"coinName",
"exchangeRate"
],
"properties": {
"cdkInfo": {
"type": "string"
},
"cdkName": {
"type": "string"
},
"coinName": {
"type": "string"
},
"exchangeRate": {
"type": "integer"
}
}
},
"types.CreateCdkTypeResp": {
"type": "object",
"properties": {
"cdkId": {
"type": "string"
}
}
},
"types.CreateCdksReq": {
"type": "object",
"required": [
"cdkContents",
"cdkId"
],
"properties": {
"cdkContents": {
"type": "array",
"items": {
"type": "string"
}
},
"cdkId": {
"type": "string"
}
}
},
"types.CreateCdksResp": {
"type": "object"
},
"types.DealCdkOrderReq": {
"type": "object",
"required": [
"orderId",
"transferHash"
],
"properties": {
"orderId": {
"description": "订单编号",
"type": "string"
},
"result": {
"description": "处理结果",
"type": "boolean"
},
"transferHash": {
"description": "转账记录 hash",
"type": "string"
}
}
},
"types.DealCdkOrderResp": {
"type": "object"
},
"types.DeleteCdkTypesReq": {
"type": "object",
"required": [
"cdkIds"
],
"properties": {
"cdkIds": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"types.DeleteCdkTypesResp": {
"type": "object"
},
"types.DeleteCdksReq": {
"type": "object",
"required": [
"ids"
],
"properties": {
"ids": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"types.DeleteCdksResp": {
"type": "object"
},
"types.ExchangeCdksReq": {
"type": "object",
"required": [
"ids"
],
"properties": {
"ids": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"types.ExchangeCdksResp": {
"type": "object"
},
"types.GeneralResponse": {
"type": "object",
"properties": {
"data": {
"type": "object"
},
"message": {
"type": "integer"
},
"result": {
"type": "integer"
}
}
},
"types.GetCdkTypeByCoinNameReq": {
"type": "object",
"required": [
"coinName"
],
"properties": {
"coinName": {
"type": "string"
}
}
},
"types.GetCdkTypeByCoinNameResp": {
"type": "object",
"properties": {
"cdkAvailable": {
"description": "未发放的cdk数量",
"type": "integer"
},
"cdkFrozen": {
"description": "冻结状态中的cdk数量",
"type": "integer"
},
"cdkId": {
"type": "string"
},
"cdkInfo": {
"type": "string"
},
"cdkName": {
"type": "string"
},
"cdkUsed": {
"description": "已发放的cdk数量",
"type": "integer"
},
"coinName": {
"type": "string"
},
"exchangeRate": {
"type": "integer"
}
}
},
"types.GetCdkTypesReq": {
"type": "object",
"properties": {
"coinName": {
"type": "string"
},
"page": {
"description": "页数",
"type": "integer"
},
"pageSize": {
"description": "每页数量",
"type": "integer"
}
}
},
"types.GetCdkTypesResp": {
"type": "object",
"properties": {
"cdkTypes": {
"type": "array",
"items": {
"$ref": "#/definitions/types.CdkType"
}
},
"totalElements": {
"type": "integer"
},
"totalPages": {
"type": "integer"
}
}
},
"types.GetCdksByUserIdReq": {
"type": "object",
"properties": {
"page": {
"description": "页数",
"type": "integer"
},
"pageSize": {
"description": "每页数量",
"type": "integer"
}
}
},
"types.GetCdksByUserIdResp": {
"type": "object",
"properties": {
"cdks": {
"type": "array",
"items": {
"$ref": "#/definitions/types.Cdk"
}
},
"totalElements": {
"type": "integer"
},
"totalPages": {
"type": "integer"
}
}
},
"types.GetCdksReq": {
"type": "object",
"required": [
"cdkId"
],
"properties": {
"cdkContent": {
"type": "string"
},
"cdkId": {
"type": "string"
},
"page": {
"description": "页数",
"type": "integer"
},
"pageSize": {
"description": "每页数量",
"type": "integer"
}
}
},
"types.GetCdksResp": {
"type": "object",
"properties": {
"cdks": {
"type": "array",
"items": {
"$ref": "#/definitions/types.Cdk"
}
},
"totalElements": {
"type": "integer"
},
"totalPages": {
"type": "integer"
}
}
},
"types.UpdateCdkTypeReq": {
"type": "object",
"required": [
"cdkId",
"cdkName",
"coinName",
"exchangeRate"
],
"properties": {
"cdkId": {
"type": "string"
},
"cdkName": {
"type": "string"
},
"coinName": {
"type": "string"
},
"exchangeRate": {
"type": "integer"
}
}
},
"types.UpdateCdkTypeResp": {
"type": "object"
}
}
}`
type swaggerInfo struct {
Version string
Host string
BasePath string
Schemes []string
Title string
Description string
}
// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo = swaggerInfo{
Version: "",
Host: "",
BasePath: "",
Schemes: []string{},
Title: "",
Description: "",
}
type s struct{}
func (s *s) ReadDoc() string {
sInfo := SwaggerInfo
sInfo.Description = strings.Replace(sInfo.Description, "\n", "\\n", -1)
t, err := template.New("swagger_info").Funcs(template.FuncMap{
"marshal": func(v interface{}) string {
a, _ := json.Marshal(v)
return string(a)
},
}).Parse(doc)
if err != nil {
return doc
}
var tpl bytes.Buffer
if err := t.Execute(&tpl, sInfo); err != nil {
return doc
}
return tpl.String()
}
func init() {
swag.Register(swag.Name, &s{})
}

View File

@@ -0,0 +1,887 @@
{
"swagger": "2.0",
"info": {
"contact": {}
},
"paths": {
"/app/cdk/create-cdk-order": {
"post": {
"tags": [
"Cdk App"
],
"summary": "创建兑换订单",
"parameters": [
{
"type": "string",
"description": "MOCK",
"name": "FZM-SIGNATURE",
"in": "header",
"required": true
},
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.CreateCdkOrderReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.CreateCdkOrderResp"
}
}
}
]
}
}
}
}
},
"/app/cdk/deal-cdk-order": {
"post": {
"tags": [
"Cdk App"
],
"summary": "处理兑换订单",
"parameters": [
{
"type": "string",
"description": "MOCK",
"name": "FZM-SIGNATURE",
"in": "header",
"required": true
},
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.DealCdkOrderReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.DealCdkOrderResp"
}
}
}
]
}
}
}
}
},
"/app/cdk/get-cdk-type-by-coin-name": {
"post": {
"tags": [
"Cdk App"
],
"summary": "查询一个票券对应的 cdkType",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.GetCdkTypeByCoinNameReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.GetCdkTypeByCoinNameResp"
}
}
}
]
}
}
}
}
},
"/app/cdk/get-cdks-by-user-id": {
"post": {
"tags": [
"Cdk App"
],
"summary": "分页获得一个人拥有的 cdks",
"parameters": [
{
"type": "string",
"description": "MOCK",
"name": "FZM-SIGNATURE",
"in": "header",
"required": true
},
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.GetCdksByUserIdReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.GetCdksByUserIdResp"
}
}
}
]
}
}
}
}
},
"/backend/cdk/create-cdk-type": {
"post": {
"tags": [
"Cdk 后台"
],
"summary": "创建 CdkType",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.CreateCdkTypeReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.CreateCdkTypeResp"
}
}
}
]
}
}
}
}
},
"/backend/cdk/create-cdks": {
"post": {
"tags": [
"Cdk 后台"
],
"summary": "创建 Cdks",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.CreateCdksReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.CreateCdksResp"
}
}
}
]
}
}
}
}
},
"/backend/cdk/delete-cdk-types": {
"post": {
"tags": [
"Cdk 后台"
],
"summary": "删除 cdkTypes",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.DeleteCdkTypesReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.DeleteCdkTypesResp"
}
}
}
]
}
}
}
}
},
"/backend/cdk/delete-cdks": {
"post": {
"tags": [
"Cdk 后台"
],
"summary": "删除 cdks",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.DeleteCdksReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.DeleteCdksResp"
}
}
}
]
}
}
}
}
},
"/backend/cdk/exchange-cdks": {
"post": {
"tags": [
"Cdk 后台"
],
"summary": "兑换 cdks",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.ExchangeCdksReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.ExchangeCdksResp"
}
}
}
]
}
}
}
}
},
"/backend/cdk/get-cdk-types": {
"post": {
"tags": [
"Cdk 查询"
],
"summary": "分页获得 cdkType",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.GetCdkTypesReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.GetCdkTypesResp"
}
}
}
]
}
}
}
}
},
"/backend/cdk/get-cdks": {
"post": {
"tags": [
"Cdk 查询"
],
"summary": "分页获得 cdks",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.GetCdksReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.GetCdksResp"
}
}
}
]
}
}
}
}
},
"/backend/cdk/update-cdk-type": {
"post": {
"tags": [
"Cdk 后台"
],
"summary": "更新 cdkType",
"parameters": [
{
"description": "body",
"name": "data",
"in": "body",
"schema": {
"$ref": "#/definitions/types.UpdateCdkTypeReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/types.GeneralResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/types.UpdateCdkTypeResp"
}
}
}
]
}
}
}
}
}
},
"definitions": {
"types.Cdk": {
"type": "object",
"properties": {
"cdkContent": {
"type": "string"
},
"cdkId": {
"type": "string"
},
"cdkName": {
"type": "string"
},
"cdkStatus": {
"type": "integer"
},
"createTime": {
"type": "string"
},
"exchangeTime": {
"type": "string"
},
"id": {
"type": "string"
},
"orderId": {
"type": "string"
},
"userId": {
"type": "string"
}
}
},
"types.CdkType": {
"type": "object",
"properties": {
"cdkAvailable": {
"description": "未发放的cdk数量",
"type": "integer"
},
"cdkFrozen": {
"description": "冻结状态中的cdk数量",
"type": "integer"
},
"cdkId": {
"type": "string"
},
"cdkInfo": {
"type": "string"
},
"cdkName": {
"type": "string"
},
"cdkUsed": {
"description": "已发放的cdk数量",
"type": "integer"
},
"coinName": {
"type": "string"
},
"exchangeRate": {
"type": "integer"
}
}
},
"types.CreateCdkOrderReq": {
"type": "object",
"required": [
"cdkId",
"number"
],
"properties": {
"cdkId": {
"description": "cdk 种类编号",
"type": "string"
},
"number": {
"description": "兑换数量",
"type": "integer"
}
}
},
"types.CreateCdkOrderResp": {
"type": "object",
"properties": {
"orderId": {
"description": "订单编号",
"type": "string"
}
}
},
"types.CreateCdkTypeReq": {
"type": "object",
"required": [
"coinName",
"exchangeRate"
],
"properties": {
"cdkInfo": {
"type": "string"
},
"cdkName": {
"type": "string"
},
"coinName": {
"type": "string"
},
"exchangeRate": {
"type": "integer"
}
}
},
"types.CreateCdkTypeResp": {
"type": "object",
"properties": {
"cdkId": {
"type": "string"
}
}
},
"types.CreateCdksReq": {
"type": "object",
"required": [
"cdkContents",
"cdkId"
],
"properties": {
"cdkContents": {
"type": "array",
"items": {
"type": "string"
}
},
"cdkId": {
"type": "string"
}
}
},
"types.CreateCdksResp": {
"type": "object"
},
"types.DealCdkOrderReq": {
"type": "object",
"required": [
"orderId",
"transferHash"
],
"properties": {
"orderId": {
"description": "订单编号",
"type": "string"
},
"result": {
"description": "处理结果",
"type": "boolean"
},
"transferHash": {
"description": "转账记录 hash",
"type": "string"
}
}
},
"types.DealCdkOrderResp": {
"type": "object"
},
"types.DeleteCdkTypesReq": {
"type": "object",
"required": [
"cdkIds"
],
"properties": {
"cdkIds": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"types.DeleteCdkTypesResp": {
"type": "object"
},
"types.DeleteCdksReq": {
"type": "object",
"required": [
"ids"
],
"properties": {
"ids": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"types.DeleteCdksResp": {
"type": "object"
},
"types.ExchangeCdksReq": {
"type": "object",
"required": [
"ids"
],
"properties": {
"ids": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"types.ExchangeCdksResp": {
"type": "object"
},
"types.GeneralResponse": {
"type": "object",
"properties": {
"data": {
"type": "object"
},
"message": {
"type": "integer"
},
"result": {
"type": "integer"
}
}
},
"types.GetCdkTypeByCoinNameReq": {
"type": "object",
"required": [
"coinName"
],
"properties": {
"coinName": {
"type": "string"
}
}
},
"types.GetCdkTypeByCoinNameResp": {
"type": "object",
"properties": {
"cdkAvailable": {
"description": "未发放的cdk数量",
"type": "integer"
},
"cdkFrozen": {
"description": "冻结状态中的cdk数量",
"type": "integer"
},
"cdkId": {
"type": "string"
},
"cdkInfo": {
"type": "string"
},
"cdkName": {
"type": "string"
},
"cdkUsed": {
"description": "已发放的cdk数量",
"type": "integer"
},
"coinName": {
"type": "string"
},
"exchangeRate": {
"type": "integer"
}
}
},
"types.GetCdkTypesReq": {
"type": "object",
"properties": {
"coinName": {
"type": "string"
},
"page": {
"description": "页数",
"type": "integer"
},
"pageSize": {
"description": "每页数量",
"type": "integer"
}
}
},
"types.GetCdkTypesResp": {
"type": "object",
"properties": {
"cdkTypes": {
"type": "array",
"items": {
"$ref": "#/definitions/types.CdkType"
}
},
"totalElements": {
"type": "integer"
},
"totalPages": {
"type": "integer"
}
}
},
"types.GetCdksByUserIdReq": {
"type": "object",
"properties": {
"page": {
"description": "页数",
"type": "integer"
},
"pageSize": {
"description": "每页数量",
"type": "integer"
}
}
},
"types.GetCdksByUserIdResp": {
"type": "object",
"properties": {
"cdks": {
"type": "array",
"items": {
"$ref": "#/definitions/types.Cdk"
}
},
"totalElements": {
"type": "integer"
},
"totalPages": {
"type": "integer"
}
}
},
"types.GetCdksReq": {
"type": "object",
"required": [
"cdkId"
],
"properties": {
"cdkContent": {
"type": "string"
},
"cdkId": {
"type": "string"
},
"page": {
"description": "页数",
"type": "integer"
},
"pageSize": {
"description": "每页数量",
"type": "integer"
}
}
},
"types.GetCdksResp": {
"type": "object",
"properties": {
"cdks": {
"type": "array",
"items": {
"$ref": "#/definitions/types.Cdk"
}
},
"totalElements": {
"type": "integer"
},
"totalPages": {
"type": "integer"
}
}
},
"types.UpdateCdkTypeReq": {
"type": "object",
"required": [
"cdkId",
"cdkName",
"coinName",
"exchangeRate"
],
"properties": {
"cdkId": {
"type": "string"
},
"cdkName": {
"type": "string"
},
"coinName": {
"type": "string"
},
"exchangeRate": {
"type": "integer"
}
}
},
"types.UpdateCdkTypeResp": {
"type": "object"
}
}
}

View File

@@ -0,0 +1,540 @@
definitions:
types.Cdk:
properties:
cdkContent:
type: string
cdkId:
type: string
cdkName:
type: string
cdkStatus:
type: integer
createTime:
type: string
exchangeTime:
type: string
id:
type: string
orderId:
type: string
userId:
type: string
type: object
types.CdkType:
properties:
cdkAvailable:
description: 未发放的cdk数量
type: integer
cdkFrozen:
description: 冻结状态中的cdk数量
type: integer
cdkId:
type: string
cdkInfo:
type: string
cdkName:
type: string
cdkUsed:
description: 已发放的cdk数量
type: integer
coinName:
type: string
exchangeRate:
type: integer
type: object
types.CreateCdkOrderReq:
properties:
cdkId:
description: cdk 种类编号
type: string
number:
description: 兑换数量
type: integer
required:
- cdkId
- number
type: object
types.CreateCdkOrderResp:
properties:
orderId:
description: 订单编号
type: string
type: object
types.CreateCdkTypeReq:
properties:
cdkInfo:
type: string
cdkName:
type: string
coinName:
type: string
exchangeRate:
type: integer
required:
- coinName
- exchangeRate
type: object
types.CreateCdkTypeResp:
properties:
cdkId:
type: string
type: object
types.CreateCdksReq:
properties:
cdkContents:
items:
type: string
type: array
cdkId:
type: string
required:
- cdkContents
- cdkId
type: object
types.CreateCdksResp:
type: object
types.DealCdkOrderReq:
properties:
orderId:
description: 订单编号
type: string
result:
description: 处理结果
type: boolean
transferHash:
description: 转账记录 hash
type: string
required:
- orderId
- transferHash
type: object
types.DealCdkOrderResp:
type: object
types.DeleteCdkTypesReq:
properties:
cdkIds:
items:
type: string
type: array
required:
- cdkIds
type: object
types.DeleteCdkTypesResp:
type: object
types.DeleteCdksReq:
properties:
ids:
items:
type: string
type: array
required:
- ids
type: object
types.DeleteCdksResp:
type: object
types.ExchangeCdksReq:
properties:
ids:
items:
type: string
type: array
required:
- ids
type: object
types.ExchangeCdksResp:
type: object
types.GeneralResponse:
properties:
data:
type: object
message:
type: integer
result:
type: integer
type: object
types.GetCdkTypeByCoinNameReq:
properties:
coinName:
type: string
required:
- coinName
type: object
types.GetCdkTypeByCoinNameResp:
properties:
cdkAvailable:
description: 未发放的cdk数量
type: integer
cdkFrozen:
description: 冻结状态中的cdk数量
type: integer
cdkId:
type: string
cdkInfo:
type: string
cdkName:
type: string
cdkUsed:
description: 已发放的cdk数量
type: integer
coinName:
type: string
exchangeRate:
type: integer
type: object
types.GetCdkTypesReq:
properties:
coinName:
type: string
page:
description: 页数
type: integer
pageSize:
description: 每页数量
type: integer
type: object
types.GetCdkTypesResp:
properties:
cdkTypes:
items:
$ref: '#/definitions/types.CdkType'
type: array
totalElements:
type: integer
totalPages:
type: integer
type: object
types.GetCdksByUserIdReq:
properties:
page:
description: 页数
type: integer
pageSize:
description: 每页数量
type: integer
type: object
types.GetCdksByUserIdResp:
properties:
cdks:
items:
$ref: '#/definitions/types.Cdk'
type: array
totalElements:
type: integer
totalPages:
type: integer
type: object
types.GetCdksReq:
properties:
cdkContent:
type: string
cdkId:
type: string
page:
description: 页数
type: integer
pageSize:
description: 每页数量
type: integer
required:
- cdkId
type: object
types.GetCdksResp:
properties:
cdks:
items:
$ref: '#/definitions/types.Cdk'
type: array
totalElements:
type: integer
totalPages:
type: integer
type: object
types.UpdateCdkTypeReq:
properties:
cdkId:
type: string
cdkName:
type: string
coinName:
type: string
exchangeRate:
type: integer
required:
- cdkId
- cdkName
- coinName
- exchangeRate
type: object
types.UpdateCdkTypeResp:
type: object
info:
contact: {}
paths:
/app/cdk/create-cdk-order:
post:
parameters:
- description: MOCK
in: header
name: FZM-SIGNATURE
required: true
type: string
- description: body
in: body
name: data
schema:
$ref: '#/definitions/types.CreateCdkOrderReq'
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/types.GeneralResponse'
- properties:
data:
$ref: '#/definitions/types.CreateCdkOrderResp'
type: object
summary: 创建兑换订单
tags:
- Cdk App
/app/cdk/deal-cdk-order:
post:
parameters:
- description: MOCK
in: header
name: FZM-SIGNATURE
required: true
type: string
- description: body
in: body
name: data
schema:
$ref: '#/definitions/types.DealCdkOrderReq'
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/types.GeneralResponse'
- properties:
data:
$ref: '#/definitions/types.DealCdkOrderResp'
type: object
summary: 处理兑换订单
tags:
- Cdk App
/app/cdk/get-cdk-type-by-coin-name:
post:
parameters:
- description: body
in: body
name: data
schema:
$ref: '#/definitions/types.GetCdkTypeByCoinNameReq'
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/types.GeneralResponse'
- properties:
data:
$ref: '#/definitions/types.GetCdkTypeByCoinNameResp'
type: object
summary: 查询一个票券对应的 cdkType
tags:
- Cdk App
/app/cdk/get-cdks-by-user-id:
post:
parameters:
- description: MOCK
in: header
name: FZM-SIGNATURE
required: true
type: string
- description: body
in: body
name: data
schema:
$ref: '#/definitions/types.GetCdksByUserIdReq'
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/types.GeneralResponse'
- properties:
data:
$ref: '#/definitions/types.GetCdksByUserIdResp'
type: object
summary: 分页获得一个人拥有的 cdks
tags:
- Cdk App
/backend/cdk/create-cdk-type:
post:
parameters:
- description: body
in: body
name: data
schema:
$ref: '#/definitions/types.CreateCdkTypeReq'
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/types.GeneralResponse'
- properties:
data:
$ref: '#/definitions/types.CreateCdkTypeResp'
type: object
summary: 创建 CdkType
tags:
- Cdk 后台
/backend/cdk/create-cdks:
post:
parameters:
- description: body
in: body
name: data
schema:
$ref: '#/definitions/types.CreateCdksReq'
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/types.GeneralResponse'
- properties:
data:
$ref: '#/definitions/types.CreateCdksResp'
type: object
summary: 创建 Cdks
tags:
- Cdk 后台
/backend/cdk/delete-cdk-types:
post:
parameters:
- description: body
in: body
name: data
schema:
$ref: '#/definitions/types.DeleteCdkTypesReq'
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/types.GeneralResponse'
- properties:
data:
$ref: '#/definitions/types.DeleteCdkTypesResp'
type: object
summary: 删除 cdkTypes
tags:
- Cdk 后台
/backend/cdk/delete-cdks:
post:
parameters:
- description: body
in: body
name: data
schema:
$ref: '#/definitions/types.DeleteCdksReq'
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/types.GeneralResponse'
- properties:
data:
$ref: '#/definitions/types.DeleteCdksResp'
type: object
summary: 删除 cdks
tags:
- Cdk 后台
/backend/cdk/exchange-cdks:
post:
parameters:
- description: body
in: body
name: data
schema:
$ref: '#/definitions/types.ExchangeCdksReq'
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/types.GeneralResponse'
- properties:
data:
$ref: '#/definitions/types.ExchangeCdksResp'
type: object
summary: 兑换 cdks
tags:
- Cdk 后台
/backend/cdk/get-cdk-types:
post:
parameters:
- description: body
in: body
name: data
schema:
$ref: '#/definitions/types.GetCdkTypesReq'
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/types.GeneralResponse'
- properties:
data:
$ref: '#/definitions/types.GetCdkTypesResp'
type: object
summary: 分页获得 cdkType
tags:
- Cdk 查询
/backend/cdk/get-cdks:
post:
parameters:
- description: body
in: body
name: data
schema:
$ref: '#/definitions/types.GetCdksReq'
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/types.GeneralResponse'
- properties:
data:
$ref: '#/definitions/types.GetCdksResp'
type: object
summary: 分页获得 cdks
tags:
- Cdk 查询
/backend/cdk/update-cdk-type:
post:
parameters:
- description: body
in: body
name: data
schema:
$ref: '#/definitions/types.UpdateCdkTypeReq'
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/types.GeneralResponse'
- properties:
data:
$ref: '#/definitions/types.UpdateCdkTypeResp'
type: object
summary: 更新 cdkType
tags:
- Cdk 后台
swagger: "2.0"

View File

@@ -0,0 +1,52 @@
package midware
import (
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
"gitlab.33.cn/chat/dtalk/pkg/api"
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
"gitlab.33.cn/chat/dtalk/service/backend/model"
"strings"
)
func JWTAuthMiddleWare(flag bool, key string) gin.HandlerFunc {
return func(c *gin.Context) {
if flag == true {
c.Next()
return
}
authHeader := c.GetHeader("Authorization")
if len(authHeader) == 0 {
c.Set(api.ReqError, xerror.NewError(xerror.TokenError).SetExtMessage("token is empty"))
c.Abort()
return
}
stringArray := strings.SplitN(authHeader, " ", 2)
if !(len(stringArray) == 2 && stringArray[0] == "Bearer") {
c.Set(api.ReqError, xerror.NewError(xerror.TokenError).SetExtMessage("The token's format is wrong"))
c.Abort()
return
}
claims, err := parseToken(stringArray[1], key)
if err != nil {
c.Set(api.ReqError, err)
c.Abort()
return
}
c.Set("userName", claims.Username)
c.Next()
}
}
func parseToken(tokenString string, key string) (*model.Claims, error) {
token, err := jwt.ParseWithClaims(tokenString, &model.Claims{}, func(token *jwt.Token) (i interface{}, err error) {
return []byte(key), nil
})
if err != nil {
return nil, xerror.NewError(xerror.TokenError).SetExtMessage("invalid token")
}
if claims, ok := token.Claims.(*model.Claims); ok && token.Valid {
return claims, nil
}
return nil, xerror.NewError(xerror.TokenError).SetExtMessage("invalid token")
}

View File

@@ -0,0 +1,98 @@
package biz
import (
"gitlab.33.cn/chat/dtalk/service/backend/model/db"
"gitlab.33.cn/chat/dtalk/service/backend/model/types"
"gitlab.33.cn/utils/go-kit/convert"
"time"
)
// 业务模型
// CdkType cdk 种类
type CdkType struct {
CdkId int64 `json:"cdkId,omitempty"`
CdkName string `json:"cdkName,omitempty"`
CoinName string `json:"coinName,omitempty"`
ExchangeRate int64 `json:"exchangeRate,omitempty"`
CdkInfo string `json:"cdkInfo,omitempty"`
// 未发放的cdk数量
CdkAvailable int64 `json:"cdkAvailable,omitempty"`
// 已发放的cdk数量
CdkUsed int64 `json:"cdkUsed,omitempty"`
// 冻结状态中的cdk数量
CdkFrozen int64 `json:"cdkFrozen,omitempty"`
}
func (cdkType *CdkType) ToTypes() *types.CdkType {
return &types.CdkType{
CdkId: convert.ToString(cdkType.CdkId),
CdkName: cdkType.CdkName,
CoinName: cdkType.CoinName,
ExchangeRate: cdkType.ExchangeRate,
CdkInfo: cdkType.CdkInfo,
CdkAvailable: cdkType.CdkAvailable,
CdkUsed: cdkType.CdkUsed,
CdkFrozen: cdkType.CdkFrozen,
}
}
// Cdk cdk 实例
type Cdk struct {
Id int64 `json:"id,omitempty"`
CdkId int64 `json:"cdkId,omitempty"`
CdkContent string `json:"cdkContent,omitempty"`
UserId string `json:"userId,omitempty"`
CdkStatus int32 `json:"cdkStatus,omitempty"`
OrderId int64 `json:"orderId,omitempty"`
CreateTime int64 `json:"createTime"`
UpdateTime int64
ExchangeTime int64 `json:"exchangeTime"`
}
func (cdk *Cdk) ToTypes() *types.Cdk {
return &types.Cdk{
Id: convert.ToString(cdk.Id),
CdkId: convert.ToString(cdk.CdkId),
CdkContent: cdk.CdkContent,
UserId: cdk.UserId,
CdkStatus: cdk.CdkStatus,
OrderId: convert.ToString(cdk.OrderId),
CreateTime: convert.ToString(cdk.CreateTime),
ExchangeTime: convert.ToString(cdk.ExchangeTime),
}
}
func (cdk *Cdk) CheckUserId(userId string) bool {
return cdk.UserId == userId
}
func (cdk *Cdk) CheckFrozen() bool {
return cdk.CdkStatus == db.CdkFrozen
}
type CdkOrderMessage struct {
PersonId string
CdkId int64
Number int64
Done chan *CdkOrder
}
func NewCdkOrderMessage(personId string, cdkId, number int64) *CdkOrderMessage {
return &CdkOrderMessage{
PersonId: personId,
CdkId: cdkId,
Number: number,
Done: make(chan *CdkOrder),
}
}
type CdkOrder struct {
Err error
OrderId int64
}
type ClearFrozenOrderMessage struct {
OrderId int64
Deadline time.Duration
}

View File

@@ -0,0 +1,8 @@
package biz
type TxResult struct {
Success bool
To string
Amount int64
Symbol string
}

View File

@@ -0,0 +1,6 @@
package model
const (
PlatformChat33Pro = "Chat33Pro"
Size = 20
)

View File

@@ -0,0 +1,47 @@
package db
// 数据库模型
// 持久化模型 PO
type TimeInfo struct {
CreateTime int64
UpdateTime int64
DeleteTime int64
}
type CdkType struct {
CdkId int64
CdkName string
CdkInfo string
CoinName string
ExchangeRate int64
TimeInfo
}
type Cdk struct {
Id int64
CdkId int64
CdkContent string
UserId string
CdkStatus int32
OrderId int64
TimeInfo
ExchangeTime int64
}
type CdkOrder struct {
Id int64
OrderId int64
TransferHash string
UserId string
OrderStatus int32
TimeInfo
ExchangeTime int64
}
const (
CdkUnused = 0
CdkFrozen = 1
CdkUsed = 2
CdkExchange = 3
)

View File

@@ -0,0 +1,201 @@
package types
type GeneralResponse struct {
Result int `json:"result"`
Message int `json:"message"`
Data interface{} `json:"data"`
}
// http 请求和返回
// CdkType cdk 种类
type CdkType struct {
CdkId string `json:"cdkId"`
CdkName string `json:"cdkName"`
CoinName string `json:"coinName"`
ExchangeRate int64 `json:"exchangeRate"`
CdkInfo string `json:"cdkInfo"`
// 未发放的cdk数量
CdkAvailable int64 `json:"cdkAvailable"`
// 已发放的cdk数量
CdkUsed int64 `json:"cdkUsed"`
// 冻结状态中的cdk数量
CdkFrozen int64 `json:"cdkFrozen"`
}
// Cdk cdk 实例
type Cdk struct {
Id string `json:"id"`
CdkId string `json:"cdkId"`
CdkName string `json:"cdkName"`
CdkContent string `json:"cdkContent"`
UserId string `json:"userId"`
CdkStatus int32 `json:"cdkStatus"`
OrderId string `json:"orderId"`
CreateTime string `json:"createTime"`
ExchangeTime string `json:"exchangeTime"`
}
// PageInfo 分页信息
type PageInfo struct {
// 页数
Page int64 `json:"page"`
// 每页数量
PageSize int64 `json:"pageSize"`
}
// -----------------------------backend-----------------------------
// CreateCdkTypeReq 创建 cdk 种类请求
type CreateCdkTypeReq struct {
CdkName string `json:"cdkName"`
CoinName string `json:"coinName" binding:"required"`
ExchangeRate int64 `json:"exchangeRate" binding:"required"`
CdkInfo string `json:"cdkInfo"`
}
// CreateCdkTypeResp 创建 cdk 种类响应
type CreateCdkTypeResp struct {
CdkId string `json:"cdkId"`
}
// GetCdkTypesReq 查询 cdk 种类请求
type GetCdkTypesReq struct {
PageInfo
CoinName string `json:"coinName"`
}
// GetCdkTypesResp 查询 cdk 种类响应
type GetCdkTypesResp struct {
TotalElements int64 `json:"totalElements"`
TotalPages int64 `json:"totalPages"`
CdkTypes []*CdkType `json:"cdkTypes"`
}
// CreateCdksReq 批量上传 cdk 请求
type CreateCdksReq struct {
CdkId string `json:"cdkId" binding:"required"`
CdkContents []string `json:"cdkContents" binding:"required"`
}
// CreateCdksResp 批量上传 cdk 响应
type CreateCdksResp struct {
}
// GetCdksReq 查询 cdk 实例请求
type GetCdksReq struct {
PageInfo
CdkId string `json:"cdkId" binding:"required"`
CdkContent string `json:"cdkContent"`
}
// GetCdksResp 查询 cdk 实例响应
type GetCdksResp struct {
TotalElements int64 `json:"totalElements"`
TotalPages int64 `json:"totalPages"`
Cdks []*Cdk `json:"cdks"`
}
// GetCdksWithCdkNameReq 根据 cdkName 查询 cdk 实例请求
//type GetCdksWithCdkNameReq struct {
// PageInfo
// CdkName string `json:"cdkName"`
//}
// GetCdksWithCdkNameResp 根据 cdkName 查询 cdk 实例响应
//type GetCdksWithCdkNameResp struct {
// TotalElements int64 `json:"totalElements"`
// TotalPages int64 `json:"totalPages"`
// Cdks []*Cdk `json:"cdks"`
//}
// DeleteCdksReq 删除 cdk 实例请求
type DeleteCdksReq struct {
Ids []string `json:"ids" binding:"required"`
}
// DeleteCdksResp 删除 cdk 实例响应
type DeleteCdksResp struct {
}
// DeleteCdkTypesReq 删除 cdkType 请求
type DeleteCdkTypesReq struct {
CdkIds []string `json:"cdkIds" binding:"required"`
}
// DeleteCdkTypesResp 删除 cdkType 响应
type DeleteCdkTypesResp struct {
}
type UpdateCdkTypeReq struct {
CdkId string `json:"cdkId" binding:"required"`
CdkName string `json:"cdkName" binding:"required"`
CoinName string `json:"coinName" binding:"required"`
ExchangeRate int64 `json:"exchangeRate" binding:"required"`
}
type UpdateCdkTypeResp struct {
}
type ExchangeCdksReq struct {
Ids []string `json:"ids" binding:"required"`
}
type ExchangeCdksResp struct {
}
// -----------------------------app-----------------------------
// GetCdksByUserIdReq 查询某人拥有的 cdk 实例请求
type GetCdksByUserIdReq struct {
PageInfo
//CdkId string `json:"cdkId" binding:"required"`
PersonId string `json:"-"`
}
// GetCdksByUserIdResp 查询某人拥有的 cdk 实例响应
type GetCdksByUserIdResp struct {
TotalElements int64 `json:"totalElements"`
TotalPages int64 `json:"totalPages"`
Cdks []*Cdk `json:"cdks"`
}
// GetCdkTypeByCoinNameReq 根据票券名称查询对应的 cdk 信息请求
type GetCdkTypeByCoinNameReq struct {
CoinName string `json:"coinName" binding:"required"`
}
// GetCdkTypeByCoinNameResp 根据票券名称查询对应的 cdk 信息响应
type GetCdkTypeByCoinNameResp struct {
*CdkType
}
// CreateCdkOrderReq 创建兑换券订单请求
type CreateCdkOrderReq struct {
PersonId string `json:"-"`
// cdk 种类编号
CdkId string `json:"cdkId" binding:"required"`
// 兑换数量
Number int64 `json:"number" binding:"required"`
}
// CreateCdkOrderResp 创建兑换券订单响应
type CreateCdkOrderResp struct {
// 订单编号
OrderId string `json:"orderId"`
}
// DealCdkOrderReq 处理兑换券订单请求
type DealCdkOrderReq struct {
PersonId string `json:"-"`
// 订单编号
OrderId string `json:"orderId" binding:"required"`
// 处理结果
Result bool `json:"result"`
// 转账记录 hash
TransferHash string `json:"transferHash" binding:"required"`
}
// DealCdkOrderResp 处理兑换券订单响应
type DealCdkOrderResp struct {
}

View File

@@ -0,0 +1,76 @@
package model
import (
"encoding/json"
"github.com/dgrijalva/jwt-go"
"gitlab.33.cn/chat/dtalk/pkg/util"
)
type Description []string
func (desc *Description) ToString() string {
b, err := json.Marshal(desc)
if err != nil {
return ""
}
return string(b)
}
func ConvertDescription(str string) (Description, error) {
var desc Description
err := json.Unmarshal([]byte(str), &desc)
if err != nil {
return nil, err
}
return desc, nil
}
type VersionForm struct {
Id int64 `json:"id"`
Platform string `json:"platform"`
Status int32 `json:"status"`
DeviceType string `json:"deviceType"`
VersionName string `json:"versionName"`
VersionCode int64 `json:"versionCode"`
Url string `json:"url"`
Force bool `json:"force"`
Description Description `json:"description"`
OpeUser string `json:"opeUser"`
Md5 string `json:"md5"`
Size int64 `json:"size"`
UpdateTime int64 `json:"updateTime"`
CreateTime int64 `json:"createTime"`
}
func ConvertVersionForm(record *map[string]string) (*VersionForm, error) {
description, err := ConvertDescription((*record)["description"])
if err != nil {
return nil, err
}
return &VersionForm{
Id: util.ToInt64((*record)["id"]),
Platform: (*record)["platform"],
Status: util.ToInt32((*record)["state"]),
DeviceType: (*record)["device_type"],
VersionName: (*record)["version_name"],
VersionCode: util.ToInt64((*record)["version_code"]),
Url: (*record)["download_url"],
Force: util.ToBool((*record)["force_update"]),
Description: description,
OpeUser: (*record)["ope_user"],
Md5: (*record)["md5"],
Size: util.ToInt64((*record)["size"]),
UpdateTime: util.ToInt64((*record)["update_time"]),
CreateTime: util.ToInt64((*record)["create_time"]),
}, nil
}
type Claims struct {
Username string `json:"username"`
jwt.StandardClaims
}
type UserInfo struct {
UserName string `json:"userName"`
Password string `json:"password"`
}

View File

@@ -0,0 +1,17 @@
package model
import (
"encoding/json"
"testing"
)
func Test_Marshal(t *testing.T) {
var desc Description = []string{"1", "2"}
b, err := json.Marshal(&desc)
if err != nil {
t.Error(err)
return
}
t.Log("success", string(b))
}

View File

@@ -0,0 +1,78 @@
package model
type VersionCreateRequest struct {
Platform string `json:"platform"`
Description []string `json:"description"`
Force bool `json:"force"`
Url string `json:"url"`
VersionCode int64 `json:"versionCode"`
VersionName string `json:"versionName"`
DeviceType string `json:"deviceType"`
OpeUser string `json:"opeUser"`
Md5 string `json:"md5"`
Size int64 `json:"size"`
}
type VersionUpdateRequest struct {
Description []string `json:"description"`
Force bool `json:"force"`
Url string `json:"url"`
VersionCode int64 `json:"versionCode"`
VersionName string `json:"versionName"`
Id int64 `json:"id"`
OpeUser string `json:"opeUser"`
Md5 string `json:"md5"`
Size int64 `json:"size"`
}
type VersionChangeStatusRequest struct {
Id int64 `json:"id"`
OpeUser string `json:"opeUser"`
}
type VersionCheckAndUpdateRequest struct {
VersionCode int64 `form:"versionCode" json:"versionCode"`
DeviceType string `json:"deviceType"`
}
type GetVersionListRequest struct {
Page int64 `json:"page"`
Platform string `json:"platform"`
DeviceType string `json:"deviceType"`
}
type GetTokenRequest struct {
UserName string `form:"userName" json:"userName"`
Password string `form:"password" json:"password"`
}
type VersionCreateResponse struct {
Version VersionForm `json:"version"`
}
type VersionUpdateResponse struct {
Version VersionForm `json:"version"`
}
type VersionChangeStatusResponse struct {
VersionList []VersionForm `json:"versionList"`
}
type VersionCheckAndUpdateResponse struct {
VersionForm
}
type GetVersionListResponse struct {
TotalElements int64 `json:"totalElements"`
TotalPages int64 `json:"totalPages"`
VersionList []VersionForm `json:"versionList"`
}
type GetTokenResponse struct {
UserInfo UserInfoResponse `json:"userInfo"`
}
type UserInfoResponse struct {
UserName string `json:"userName"`
Token string `json:"token"`
}

View File

@@ -0,0 +1,285 @@
package http
import (
"github.com/gin-gonic/gin"
"gitlab.33.cn/chat/dtalk/pkg/api"
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
"gitlab.33.cn/chat/dtalk/service/backend/model/types"
)
//userId, ok := c.Get(api.Address)
// if !ok {
// c.Set(api.ReqError, xerror.NewError(xerror.SignatureInvalid))
// return
// }
// @Summary 创建 CdkType
// @Author chy@33.cn
// @Tags Cdk 后台
// @Param FZM-SIGNATURE header string true "MOCK"
// @Param data body types.CreateGroupRequest false "body"
// @Success 200 {object} types.GeneralResponse{data=types.CreateGroupResponse}
// @Router /app/create-group [post]
// CreateCdkTypeHandler
// @Summary 创建 CdkType
// @Author chy@33.cn
// @Tags Cdk 后台
// @Param data body types.CreateCdkTypeReq false "body"
// @Success 200 {object} types.GeneralResponse{data=types.CreateCdkTypeResp}
// @Router /backend/cdk/create-cdk-type [post]
func CreateCdkTypeHandler(c *gin.Context) {
req := &types.CreateCdkTypeReq{}
err := c.ShouldBind(req)
if err != nil {
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
return
}
res, err := svc.CdkService.CreateCdkTypeSvc(req)
c.Set(api.ReqResult, res)
c.Set(api.ReqError, err)
}
// CreateCdksHandler
// @Summary 创建 Cdks
// @Author chy@33.cn
// @Tags Cdk 后台
// @Param data body types.CreateCdksReq false "body"
// @Success 200 {object} types.GeneralResponse{data=types.CreateCdksResp}
// @Router /backend/cdk/create-cdks [post]
func CreateCdksHandler(c *gin.Context) {
req := &types.CreateCdksReq{}
err := c.ShouldBind(req)
if err != nil {
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
return
}
res, err := svc.CdkService.CreateCdksSvc(req)
c.Set(api.ReqResult, res)
c.Set(api.ReqError, err)
}
// GetCdkTypesHandler
// @Summary 分页获得 cdkType
// @Author chy@33.cn
// @Tags Cdk 查询
// @Param data body types.GetCdkTypesReq false "body"
// @Success 200 {object} types.GeneralResponse{data=types.GetCdkTypesResp}
// @Router /backend/cdk/get-cdk-types [post]
func GetCdkTypesHandler(c *gin.Context) {
req := &types.GetCdkTypesReq{}
err := c.ShouldBind(req)
if err != nil {
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
return
}
res, err := svc.CdkService.GetCdkTypesSvc(req)
c.Set(api.ReqResult, res)
c.Set(api.ReqError, err)
}
// GetCdksHandler
// @Summary 分页获得 cdks
// @Author chy@33.cn
// @Tags Cdk 查询
// @Param data body types.GetCdksReq false "body"
// @Success 200 {object} types.GeneralResponse{data=types.GetCdksResp}
// @Router /backend/cdk/get-cdks [post]
func GetCdksHandler(c *gin.Context) {
req := &types.GetCdksReq{}
err := c.ShouldBind(req)
if err != nil {
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
return
}
res, err := svc.CdkService.GetCdksSvc(req)
c.Set(api.ReqResult, res)
c.Set(api.ReqError, err)
}
// DeleteCdksHandler
// @Summary 删除 cdks
// @Author chy@33.cn
// @Tags Cdk 后台
// @Param data body types.DeleteCdksReq false "body"
// @Success 200 {object} types.GeneralResponse{data=types.DeleteCdksResp}
// @Router /backend/cdk/delete-cdks [post]
func DeleteCdksHandler(c *gin.Context) {
req := &types.DeleteCdksReq{}
err := c.ShouldBind(req)
if err != nil {
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
return
}
res, err := svc.CdkService.DeleteCdksSvc(req)
c.Set(api.ReqResult, res)
c.Set(api.ReqError, err)
}
// DeleteCdkTypesHandler
// @Summary 删除 cdkTypes
// @Author chy@33.cn
// @Tags Cdk 后台
// @Param data body types.DeleteCdkTypesReq false "body"
// @Success 200 {object} types.GeneralResponse{data=types.DeleteCdkTypesResp}
// @Router /backend/cdk/delete-cdk-types [post]
func DeleteCdkTypesHandler(c *gin.Context) {
req := &types.DeleteCdkTypesReq{}
err := c.ShouldBind(req)
if err != nil {
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
return
}
res, err := svc.CdkService.DeleteCdkTypesSvc(req)
c.Set(api.ReqResult, res)
c.Set(api.ReqError, err)
}
// ExchangeCdksHandler
// @Summary 兑换 cdks
// @Author chy@33.cn
// @Tags Cdk 后台
// @Param data body types.ExchangeCdksReq false "body"
// @Success 200 {object} types.GeneralResponse{data=types.ExchangeCdksResp}
// @Router /backend/cdk/exchange-cdks [post]
func ExchangeCdksHandler(c *gin.Context) {
req := &types.ExchangeCdksReq{}
err := c.ShouldBind(req)
if err != nil {
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
return
}
res, err := svc.CdkService.ExchangeCdksSvc(req)
c.Set(api.ReqResult, res)
c.Set(api.ReqError, err)
}
// UpdateCdkTypeHandler
// @Summary 更新 cdkType
// @Author chy@33.cn
// @Tags Cdk 后台
// @Param data body types.UpdateCdkTypeReq false "body"
// @Success 200 {object} types.GeneralResponse{data=types.UpdateCdkTypeResp}
// @Router /backend/cdk/update-cdk-type [post]
func UpdateCdkTypeHandler(c *gin.Context) {
req := &types.UpdateCdkTypeReq{}
err := c.ShouldBind(req)
if err != nil {
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
return
}
res, err := svc.CdkService.UpdateCdkTypeSvc(req)
c.Set(api.ReqResult, res)
c.Set(api.ReqError, err)
}
// GetCdksByUserIdHandler
// @Summary 分页获得一个人拥有的 cdks
// @Author chy@33.cn
// @Tags Cdk App
// @Param FZM-SIGNATURE header string true "MOCK"
// @Param data body types.GetCdksByUserIdReq false "body"
// @Success 200 {object} types.GeneralResponse{data=types.GetCdksByUserIdResp}
// @Router /app/cdk/get-cdks-by-user-id [post]
func GetCdksByUserIdHandler(c *gin.Context) {
req := &types.GetCdksByUserIdReq{}
err := c.ShouldBind(req)
if err != nil {
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
return
}
userId, ok := c.Get(api.Address)
if !ok {
c.Set(api.ReqError, xerror.NewError(xerror.SignatureInvalid))
return
}
req.PersonId = userId.(string)
res, err := svc.CdkService.GetCdksByUserIdSvc(req)
c.Set(api.ReqResult, res)
c.Set(api.ReqError, err)
}
// GetCdkTypeByCoinNameHandler
// @Summary 查询一个票券对应的 cdkType
// @Author chy@33.cn
// @Tags Cdk App
// @Param data body types.GetCdkTypeByCoinNameReq false "body"
// @Success 200 {object} types.GeneralResponse{data=types.GetCdkTypeByCoinNameResp}
// @Router /app/cdk/get-cdk-type-by-coin-name [post]
func GetCdkTypeByCoinNameHandler(c *gin.Context) {
req := &types.GetCdkTypeByCoinNameReq{}
err := c.ShouldBind(req)
if err != nil {
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
return
}
res, err := svc.CdkService.GetCdkTypeByCoinNameSvc(req)
c.Set(api.ReqResult, res)
c.Set(api.ReqError, err)
}
// CreateCdkOrderHandler
// @Summary 创建兑换订单
// @Author chy@33.cn
// @Tags Cdk App
// @Param FZM-SIGNATURE header string true "MOCK"
// @Param data body types.CreateCdkOrderReq false "body"
// @Success 200 {object} types.GeneralResponse{data=types.CreateCdkOrderResp}
// @Router /app/cdk/create-cdk-order [post]
func CreateCdkOrderHandler(c *gin.Context) {
req := &types.CreateCdkOrderReq{}
err := c.ShouldBind(req)
if err != nil {
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
return
}
userId, ok := c.Get(api.Address)
if !ok {
c.Set(api.ReqError, xerror.NewError(xerror.SignatureInvalid))
return
}
req.PersonId = userId.(string)
res, err := svc.CdkService.CreateCdkOrderSvc(req)
c.Set(api.ReqResult, res)
c.Set(api.ReqError, err)
}
// DealCdkOrderHandler
// @Summary 处理兑换订单
// @Author chy@33.cn
// @Tags Cdk App
// @Param FZM-SIGNATURE header string true "MOCK"
// @Param data body types.DealCdkOrderReq false "body"
// @Success 200 {object} types.GeneralResponse{data=types.DealCdkOrderResp}
// @Router /app/cdk/deal-cdk-order [post]
func DealCdkOrderHandler(c *gin.Context) {
req := &types.DealCdkOrderReq{}
err := c.ShouldBind(req)
if err != nil {
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
return
}
userId, ok := c.Get(api.Address)
if !ok {
c.Set(api.ReqError, xerror.NewError(xerror.SignatureInvalid))
return
}
req.PersonId = userId.(string)
res, err := svc.CdkService.DealCdkOrderSvc(req)
c.Set(api.ReqResult, res)
c.Set(api.ReqError, err)
}

View File

@@ -0,0 +1,125 @@
package http
import (
"github.com/gin-gonic/gin"
"github.com/inconshreveable/log15"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
"gitlab.33.cn/chat/dtalk/pkg/api"
"gitlab.33.cn/chat/dtalk/service/backend/config"
_ "gitlab.33.cn/chat/dtalk/service/backend/docs"
"gitlab.33.cn/chat/dtalk/service/backend/midware"
"gitlab.33.cn/chat/dtalk/service/backend/service"
"net/http"
)
var (
svc *service.Service
log = log15.New("module", "backend/http")
)
func Init(s *service.Service) *http.Server {
addr := s.Config().Server.Addr
if s.Config().Env != "debug" {
gin.SetMode(gin.ReleaseMode)
}
engine := Default()
InitService(s)
SetupEngine(engine)
if s.Config().CdkMod {
setCdkRoute(engine)
}
srv := &http.Server{
Addr: addr,
Handler: engine,
}
go func() {
// service connections
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Error("engineInner.Start() error(%v)", err)
panic(err)
}
}()
return srv
}
// Default returns an Engine instance with the Logger and Recovery middleware already attached.
func Default() *gin.Engine {
router := gin.New()
// LoggerWithFormatter middleware will write the logs to gin.DefaultWriter
// By default gin.DefaultWriter = os.Stdout
router.Use(gin.LoggerWithFormatter(api.Chat33GinLogFormatter))
router.Use(gin.Recovery())
return router
}
func InitService(s *service.Service) {
svc = s
}
func SetupEngine(e *gin.Engine) *gin.Engine {
{
app := e.Group("/app", api.RespMiddleWare())
version := app.Group("/version")
//获取服务器列表
version.Use(api.HeaderMiddleWare())
{
version.POST("/check", CheckAndUpdateVersion)
}
}
{
backend := e.Group("/backend", api.RespMiddleWare())
token := backend.Group("/user")
{
token.POST("/login", GetToken)
}
version := backend.Group("/version")
version.Use(midware.JWTAuthMiddleWare(config.Conf.Debug.Flag, config.Conf.Release.Key))
{
version.POST("/create", CreateVersion)
version.PUT("/update", UpdateVersion)
version.PUT("/change-status", ChangeVersionStatus)
version.GET("/list", GetVersionList)
}
}
// swagger 文档接口
e.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
return e
}
func setCdkRoute(e *gin.Engine) *gin.Engine {
{
app := e.Group("/app", api.RespMiddleWare())
// cdk app
appCkd := app.Group("/cdk")
appCkd.Use(api.AuthMiddleWare())
{
appCkd.POST("get-cdks-by-user-id", GetCdksByUserIdHandler)
appCkd.POST("get-cdk-type-by-coin-name", GetCdkTypeByCoinNameHandler)
appCkd.POST("create-cdk-order", CreateCdkOrderHandler)
appCkd.POST("deal-cdk-order", DealCdkOrderHandler)
}
}
{
backend := e.Group("/backend", api.RespMiddleWare())
// cdk backend
bakCdk := backend.Group("/cdk")
bakCdk.POST("get-cdk-types", GetCdkTypesHandler)
bakCdk.POST("get-cdks", GetCdksHandler)
bakCdk.Use(midware.JWTAuthMiddleWare(config.Conf.Debug.Flag, config.Conf.Release.Key))
{
bakCdk.POST("create-cdk-type", CreateCdkTypeHandler)
bakCdk.POST("create-cdks", CreateCdksHandler)
bakCdk.POST("delete-cdks", DeleteCdksHandler)
bakCdk.POST("delete-cdk-types", DeleteCdkTypesHandler)
bakCdk.POST("update-cdk-type", UpdateCdkTypeHandler)
bakCdk.POST("exchange-cdks", ExchangeCdksHandler)
}
}
return e
}

View File

@@ -0,0 +1,103 @@
package http
import (
"github.com/gin-gonic/gin"
"gitlab.33.cn/chat/dtalk/pkg/api"
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
"gitlab.33.cn/chat/dtalk/pkg/util"
"gitlab.33.cn/chat/dtalk/service/backend/model"
)
//get all nodes
//func CheckVersion(c *gin.Context) {
// ret := svc.CheckVersion(c.MustGet(api.DeviceType).(string))
// c.Set(api.ReqResult, ret)
// c.Set(api.ReqError, nil)
//}
func CreateVersion(c *gin.Context) {
request := model.VersionCreateRequest{}
err := c.ShouldBind(&request)
request.OpeUser = c.GetString("userName")
if err != nil {
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage("ShouldBind"+err.Error()))
return
}
ret, err := svc.CreateVersion(&request)
c.Set(api.ReqResult, ret)
c.Set(api.ReqError, err)
}
func UpdateVersion(c *gin.Context) {
request := model.VersionUpdateRequest{}
err := c.ShouldBind(&request)
request.OpeUser = c.GetString("userName")
if err != nil {
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage("ShouldBind"+err.Error()))
return
}
ret, err := svc.UpdateVersion(&request)
c.Set(api.ReqResult, ret)
c.Set(api.ReqError, err)
}
func ChangeVersionStatus(c *gin.Context) {
request := model.VersionChangeStatusRequest{}
err := c.ShouldBind(&request)
request.OpeUser = c.GetString("userName")
if err != nil {
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage("ShouldBind"+err.Error()))
return
}
err = svc.ChangeVersionStatus(&request)
c.Set(api.ReqResult, nil)
c.Set(api.ReqError, err)
}
func GetVersionList(c *gin.Context) {
request := model.GetVersionListRequest{}
request.Platform = c.DefaultQuery("platform", "%")
request.DeviceType = c.DefaultQuery("deviceType", "%")
request.Page = util.ToInt64(c.DefaultQuery("page", "0"))
ret, err := svc.GetVersionList(&request)
c.Set(api.ReqResult, ret)
c.Set(api.ReqError, err)
}
func CheckAndUpdateVersion(c *gin.Context) {
request := model.VersionCheckAndUpdateRequest{}
err := c.ShouldBind(&request)
if err != nil {
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage("ShouldBind"+err.Error()))
return
}
deviceType, ok := c.Get(api.DeviceType)
if !ok {
c.Set(api.ReqError, xerror.NewError(xerror.DeviceTypeError))
return
}
request.DeviceType = deviceType.(string)
ret, err := svc.CheckAndUpdateVersion(&request)
c.Set(api.ReqResult, ret)
c.Set(api.ReqError, err)
}
func GetToken(c *gin.Context) {
request := model.GetTokenRequest{}
err := c.ShouldBind(&request)
if err != nil {
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage("ShouldBind"+err.Error()))
return
}
ret, err := svc.GetToken(&request)
c.Set(api.ReqResult, ret)
c.Set(api.ReqError, err)
}

View File

@@ -0,0 +1,57 @@
package cdk
import (
"gitlab.33.cn/chat/dtalk/service/backend/model/biz"
"time"
)
func (s *ServiceContent) CleanFrozenOrder() {
for range time.Tick(10 * time.Minute) {
// get frozen cdk
cdks, err := s.getFrozenCdks()
if err != nil {
continue
}
nowTime := time.Now().UnixNano() / 1e6
subTime := time.Now().Add(5*time.Minute).UnixNano()/1e6 - nowTime
OrderSet := make(map[int64]bool, 0)
for _, cdk := range cdks {
if nowTime-cdk.UpdateTime > subTime {
OrderSet[cdk.OrderId] = true
}
}
for k, _ := range OrderSet {
err := s.dao.CleanFrozenCdks(k)
if err != nil {
s.log.Err(err).Int64("orderId", k).Msg("CleanFrozenCdks Error")
}
}
}
}
func (s *ServiceContent) getFrozenCdks() ([]*biz.Cdk, error) {
cdkPos, err := s.dao.GetFrozenCdks()
if err != nil {
return nil, err
}
cdks := make([]*biz.Cdk, 0, len(cdkPos))
for _, cdkPo := range cdkPos {
cdk := &biz.Cdk{
Id: cdkPo.Id,
CdkId: cdkPo.CdkId,
CdkContent: cdkPo.CdkContent,
UserId: cdkPo.UserId,
CdkStatus: cdkPo.CdkStatus,
OrderId: cdkPo.OrderId,
CreateTime: cdkPo.CreateTime,
UpdateTime: cdkPo.UpdateTime,
ExchangeTime: cdkPo.ExchangeTime,
}
cdks = append(cdks, cdk)
}
return cdks, nil
}

View File

@@ -0,0 +1,147 @@
package cdk
import (
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
"gitlab.33.cn/chat/dtalk/service/backend/model/biz"
)
// GetCdkTypeByCoinName 通过 coinName 查询 cdkType
func (s *ServiceContent) GetCdkTypeByCoinName(coinName string) (*biz.CdkType, error) {
// 通过 coinName 查询 cdkType 信息
cdkTypePos, err := s.dao.GetCdkTypesWithCoinName(coinName)
if err != nil {
return nil, err
}
if len(cdkTypePos) == 0 {
return nil, xerror.NewError(xerror.CdkCoinNameErr)
}
cdkTypePo := cdkTypePos[0]
// 通过 cdkId 查询各种状态的 cdk 数量
unused, frozen, used, err := s.dao.GetCdksCount(cdkTypePo.CdkId)
if err != nil {
return nil, err
}
return &biz.CdkType{
CdkId: cdkTypePo.CdkId,
CdkName: cdkTypePo.CdkName,
CoinName: cdkTypePo.CoinName,
ExchangeRate: cdkTypePo.ExchangeRate,
CdkInfo: cdkTypePo.CdkInfo,
CdkAvailable: unused,
CdkUsed: used,
CdkFrozen: frozen,
}, nil
}
// GetCdkTypes 分页查询 CdkType 列表
func (s *ServiceContent) GetCdkTypes(coinName string, page, pageSize int64) ([]*biz.CdkType, int64, int64, error) {
cdkTypePos, totalElements, totalPages, err := s.dao.GetCdkTypes(coinName, page, pageSize)
if err != nil {
return nil, 0, 0, err
}
cdkTypes := make([]*biz.CdkType, 0, len(cdkTypePos))
for _, cdkTypePo := range cdkTypePos {
// 通过 cdkId 查询各种状态的 cdk 数量
unused, frozen, used, err := s.dao.GetCdksCount(cdkTypePo.CdkId)
if err != nil {
return nil, 0, 0, err
}
cdkType := &biz.CdkType{
CdkId: cdkTypePo.CdkId,
CdkName: cdkTypePo.CdkName,
CoinName: cdkTypePo.CoinName,
ExchangeRate: cdkTypePo.ExchangeRate,
CdkInfo: cdkTypePo.CdkInfo,
CdkAvailable: unused,
CdkUsed: used,
CdkFrozen: frozen,
}
cdkTypes = append(cdkTypes, cdkType)
}
return cdkTypes, totalElements, totalPages, nil
}
// GetCdks 分页查询 cdk 列表
func (s *ServiceContent) GetCdks(cdkId int64, cdkContent string, page, pageSize int64) ([]*biz.Cdk, int64, int64, error) {
cdkPos, totalElements, totalPages, err := s.dao.GetCdks(cdkId, cdkContent, page, pageSize)
if err != nil {
return nil, 0, 0, err
}
cdks := make([]*biz.Cdk, 0, len(cdkPos))
for _, cdkPo := range cdkPos {
cdk := &biz.Cdk{
Id: cdkPo.Id,
CdkId: cdkPo.CdkId,
CdkContent: cdkPo.CdkContent,
UserId: cdkPo.UserId,
CdkStatus: cdkPo.CdkStatus,
OrderId: cdkPo.OrderId,
CreateTime: cdkPo.CreateTime,
ExchangeTime: cdkPo.ExchangeTime,
}
cdks = append(cdks, cdk)
}
return cdks, totalElements, totalPages, nil
}
// GetCdkTypeByCdkId 通过 cdkId 查询 cdkType
func (s *ServiceContent) GetCdkTypeByCdkId(cdkId int64) (*biz.CdkType, error) {
cdkTypePo, err := s.dao.GetCdkType(cdkId)
if err != nil {
return nil, err
}
if cdkTypePo == nil {
return nil, xerror.NewError(xerror.CodeInnerError)
}
unused, frozen, used, err := s.dao.GetCdksCount(cdkTypePo.CdkId)
if err != nil {
return nil, err
}
cdkType := &biz.CdkType{
CdkId: cdkTypePo.CdkId,
CdkName: cdkTypePo.CdkName,
CoinName: cdkTypePo.CoinName,
ExchangeRate: cdkTypePo.ExchangeRate,
CdkInfo: cdkTypePo.CdkInfo,
CdkAvailable: unused,
CdkUsed: used,
CdkFrozen: frozen,
}
return cdkType, nil
}
// GetCdksWithCdkName 根据cdkName分页查询 cdk 列表
//func (s *ServiceContent) GetCdksWithCdkName(cdkName string, page, pageSize int64) ([]*biz.Cdk, int64, int64, error) {
// cdkPos, totalElements, totalPages, err := s.dao.GetCdksByCdkName(cdkName, page, pageSize)
// if err != nil {
// return nil, 0, 0, err
// }
//
// cdks := make([]*biz.Cdk, 0, len(cdkPos))
// for _, cdkPo := range cdkPos {
// cdk := &biz.Cdk{
// Id: cdkPo.Id,
// CdkId: cdkPo.CdkId,
// CdkContent: cdkPo.CdkContent,
// UserId: cdkPo.UserId,
// CdkStatus: cdkPo.CdkStatus,
// OrderId: cdkPo.OrderId,
// CreateTime: cdkPo.CreateTime,
// ExchangeTime: cdkPo.ExchangeTime,
// }
// cdks = append(cdks, cdk)
// }
//
// return cdks, totalElements, totalPages, nil
//}

View File

@@ -0,0 +1,158 @@
package cdk
import (
"fmt"
"github.com/pkg/errors"
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
"gitlab.33.cn/chat/dtalk/service/backend/model/biz"
"gitlab.33.cn/chat/dtalk/service/backend/model/types"
"gitlab.33.cn/utils/go-kit/convert"
)
// ListenOrder 监听创建订单消息队列
func (s *ServiceContent) ListenOrder() {
// 单线程模型, 保证发号正确
for {
select {
case msg := <-s.CdkOrderMessage:
msg.Done <- s.createOrder(msg)
}
}
}
// createOrder 处理创建订单消息
func (s *ServiceContent) createOrder(msg *biz.CdkOrderMessage) *biz.CdkOrder {
s.log.Info().Str("PersonId", msg.PersonId).
Int64("CdkId", msg.CdkId).
Int64("Number", msg.Number).
Msg("ListenOrder")
// 获得 orderId
orderId, err := s.idGenRPCClient.GetID()
if err != nil {
return &biz.CdkOrder{
Err: err,
OrderId: 0,
}
}
if msg.Number == 0 {
return &biz.CdkOrder{
Err: errors.New("number is zero"),
OrderId: 0,
}
}
// 判断这个人这种优惠券的数量
count, err := s.dao.GetCdksCountByUserIdAndCdkId(msg.CdkId, msg.PersonId)
if err != nil {
return &biz.CdkOrder{
Err: err,
OrderId: 0,
}
}
if count+msg.Number > s.CdkMaxNumber {
return &biz.CdkOrder{
Err: xerror.NewError(xerror.CdkMaxNumberErr).SetExtMessage(fmt.Sprintf("已有 %d 张, 将兑换 %d 张, 超出 %d 张", count, msg.Number, s.CdkMaxNumber)),
OrderId: 0,
}
}
// 得到 n 个未发放的 cdk
cdks, err := s.GetUnusedCdks(msg.CdkId, msg.Number)
if err != nil {
return &biz.CdkOrder{
Err: err,
OrderId: 0,
}
}
// 冻结 cdk
err = s.FrozenCdks(cdks, msg.PersonId, orderId)
if err != nil {
return &biz.CdkOrder{
Err: err,
OrderId: 0,
}
}
// 加入定时清理订单任务队列
return &biz.CdkOrder{
Err: nil,
OrderId: orderId,
}
}
// CreateCdkOrderSvc 创建订单 Svc
func (s *ServiceContent) CreateCdkOrderSvc(req *types.CreateCdkOrderReq) (resp *types.CreateCdkOrderResp, err error) {
personId := req.PersonId
cdkId := convert.ToInt64(req.CdkId)
number := req.Number
done := make(chan *biz.CdkOrder)
defer func() {
if err != nil {
s.log.Err(err).Interface("req", req).Str("personId", personId).Msg("CreateCdkOrderSvc")
} else {
s.log.Info().Interface("req", req).Str("personId", personId).Msg("CreateCdkOrderSvc")
}
}()
s.CdkOrderMessage <- &biz.CdkOrderMessage{
PersonId: personId,
CdkId: cdkId,
Number: number,
Done: done,
}
res := <-done
if res.Err != nil {
return nil, res.Err
}
return &types.CreateCdkOrderResp{
OrderId: convert.ToString(res.OrderId),
}, nil
}
// GetUnusedCdks 按顺序获得未发放的 cdk
func (s *ServiceContent) GetUnusedCdks(cdkId int64, number int64) ([]*biz.Cdk, error) {
cdkPos, err := s.dao.GetUnusedCdks(cdkId, number)
if err != nil {
return nil, err
}
if len(cdkPos) < int(number) {
return nil, xerror.NewError(xerror.CdkOutOfStock)
}
cdks := make([]*biz.Cdk, 0, len(cdkPos))
for _, cdkPo := range cdkPos {
cdk := &biz.Cdk{
Id: cdkPo.Id,
CdkId: cdkPo.CdkId,
CdkContent: cdkPo.CdkContent,
UserId: cdkPo.UserId,
CdkStatus: cdkPo.CdkStatus,
OrderId: cdkPo.OrderId,
}
cdks = append(cdks, cdk)
}
return cdks, nil
}
// FrozenCdks 冻结 cdk
func (s *ServiceContent) FrozenCdks(cdks []*biz.Cdk, userId string, orderId int64) error {
ids := make([]int64, 0, len(cdks))
for _, cdk := range cdks {
ids = append(ids, cdk.Id)
}
return s.dao.FrozenCdksStatus(ids, userId, orderId)
}
// TODO : 处理超时为完成支付的订单

View File

@@ -0,0 +1,35 @@
package cdk
import (
"gitlab.33.cn/chat/dtalk/service/backend/model/types"
"gitlab.33.cn/utils/go-kit/convert"
"sync"
"testing"
)
func TestCreateCdkOrder(t *testing.T) {
wg := sync.WaitGroup{}
for i := 0; i < 10; i++ {
wg.Add(1)
go func(i int) {
t.Log("start req", convert.ToString(i))
req := &types.CreateCdkOrderReq{
PersonId: convert.ToString(i),
CdkId: convert.ToString(i),
Number: convert.ToInt64(i),
}
resp, err := srv.CreateCdkOrderSvc(req)
if err != nil {
t.Log(err)
} else {
t.Log(resp)
}
t.Log("end req", convert.ToString(i))
wg.Done()
}(i)
}
wg.Wait()
}

View File

@@ -0,0 +1,58 @@
package cdk
import (
"gitlab.33.cn/chat/dtalk/service/backend/model/db"
"gitlab.33.cn/chat/dtalk/service/backend/model/types"
"gitlab.33.cn/utils/go-kit/convert"
"time"
)
func (s *ServiceContent) CreateCdksSvc(req *types.CreateCdksReq) (res *types.CreateCdksResp, err error) {
defer func() {
if err != nil {
s.log.Err(err).Interface("req", req).Msg("CreateCdksSvc")
} else {
s.log.Info().Interface("req", req).Msg("CreateCdksSvc")
}
}()
cdkId := convert.ToInt64(req.CdkId)
// 判断 cdkId 是否存在
_, err = s.GetCdkTypeByCdkId(cdkId)
if err != nil {
return nil, err
}
for _, c := range req.CdkContents {
ok, err := s.dao.CheckCdkExist(cdkId, c)
if err != nil || ok {
continue
}
id, err := s.idGenRPCClient.GetID()
if err != nil {
continue
}
cdk := &db.Cdk{
Id: id,
CdkId: cdkId,
CdkContent: c,
UserId: "",
CdkStatus: 0,
OrderId: 0,
TimeInfo: db.TimeInfo{
CreateTime: time.Now().UnixNano() / 1e6,
UpdateTime: time.Now().UnixNano() / 1e6,
DeleteTime: 0,
},
ExchangeTime: 0,
}
err = s.dao.InsertCdk(cdk)
if err != nil {
return nil, err
}
}
return nil, nil
}

View File

@@ -0,0 +1,51 @@
package cdk
import (
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
"gitlab.33.cn/chat/dtalk/service/backend/model/db"
"gitlab.33.cn/chat/dtalk/service/backend/model/types"
"gitlab.33.cn/utils/go-kit/convert"
"time"
)
func (s *ServiceContent) CreateCdkTypeSvc(req *types.CreateCdkTypeReq) (res *types.CreateCdkTypeResp, err error) {
defer func() {
if err != nil {
s.log.Err(err).Interface("req", req).Msg("CreateCdkTypeSvc")
} else {
s.log.Info().Interface("req", req).Msg("CreateCdkTypeSvc")
}
}()
cdkId, err := s.idGenRPCClient.GetID()
if err != nil {
return nil, err
}
_, err = s.GetCdkTypeByCoinName(req.CoinName)
if err != nil && err.Error() != xerror.NewError(xerror.CdkCoinNameErr).Error() {
return nil, err
}
cdkTypePo := &db.CdkType{
CdkId: cdkId,
CdkName: req.CdkName,
CdkInfo: req.CdkInfo,
CoinName: req.CoinName,
ExchangeRate: req.ExchangeRate,
TimeInfo: db.TimeInfo{
CreateTime: time.Now().UnixNano() / 1e6,
UpdateTime: time.Now().UnixNano() / 1e6,
DeleteTime: 0,
},
}
err = s.dao.InsertCdkType(cdkTypePo)
if err != nil {
return nil, err
}
res = &types.CreateCdkTypeResp{
CdkId: convert.ToString(cdkId),
}
return res, nil
}

View File

@@ -0,0 +1,165 @@
package cdk
import (
chainTypes "github.com/33cn/chain33/types"
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
"gitlab.33.cn/chat/dtalk/service/backend/model/biz"
"gitlab.33.cn/chat/dtalk/service/backend/model/db"
"gitlab.33.cn/chat/dtalk/service/backend/model/types"
"gitlab.33.cn/utils/go-kit/convert"
"time"
)
func (s *ServiceContent) DealCdkOrderSvc(req *types.DealCdkOrderReq) (res *types.DealCdkOrderResp, err error) {
personId := req.PersonId
orderId := convert.ToInt64(req.OrderId)
//result := req.Result
transferHash := req.TransferHash
defer func() {
if err != nil {
s.log.Err(err).Interface("req", req).Str("personId", personId).Msg("DealCdkOrderSvc")
} else {
s.log.Info().Interface("req", req).Str("personId", personId).Msg("DealCdkOrderSvc")
}
}()
// 根据 orderId 查询 cdks
cdks, err := s.getCdksByOrderId(orderId)
if err != nil {
return nil, err
}
// 判断 personId 是否一致
if cdks[0].CheckUserId(personId) == false {
return nil, xerror.NewError(xerror.CdkOrderError)
}
// 判断 cdk 是否处于冻结状态
if cdks[0].CheckFrozen() == false {
return nil, xerror.NewError(xerror.CdkStatusNotFrozen)
}
// 异步处理订单
ids := make([]int64, 0, len(cdks))
for _, cdk := range cdks {
ids = append(ids, cdk.Id)
}
go s.dealOrder(ids, transferHash, orderId)
// 根据 result 判断处理流程
//if result {
// err = s.dealSuccessCdkOrder(ids, req.TransferHash)
//} else {
// err = s.dealFailedCdkOrder(ids)
//}
//if err != nil {
// return nil, err
//}
return &types.DealCdkOrderResp{}, nil
}
// dealOrder 查询交易 hash 情况并处理订单
func (s *ServiceContent) dealOrder(ids []int64, hash string, orderId int64) {
i := 0
maxTryTimes := 20
for i = 0; i <= maxTryTimes; i++ {
res, err := s.checkBlockTxResult(hash)
if err != nil {
time.Sleep(1 * time.Second)
continue
}
if res.Success == true {
err = s.dealSuccessCdkOrder(ids)
if err != nil {
s.log.Error().Err(err).Int64("orderId", orderId).Str("hash", hash).Msg("dealSuccessCdkOrder err")
}
return
} else {
break
}
}
if i > maxTryTimes {
s.log.Error().Int64("orderId", orderId).Str("hash", hash).Msg("transfer hash not exist err")
} else {
s.log.Error().Int64("orderId", orderId).Str("hash", hash).Msg("transfer hash failed")
}
err := s.dealFailedCdkOrder(ids)
if err != nil {
s.log.Error().Err(err).Int64("orderId", orderId).Str("hash", hash).Msg("dealFailedCdkOrder err")
}
return
}
func (s *ServiceContent) dealSuccessCdkOrder(ids []int64) error {
//
return s.dao.UpdateCdksStatus(ids, db.CdkUsed)
}
func (s *ServiceContent) dealFailedCdkOrder(ids []int64) error {
return s.dao.UpdateCdksStatus(ids, db.CdkUnused)
}
func (s *ServiceContent) getCdksByOrderId(orderId int64) ([]*biz.Cdk, error) {
cdkPos, err := s.dao.GetCdksByOrderId(orderId)
if err != nil {
return nil, err
}
if len(cdkPos) == 0 {
return nil, xerror.NewError(xerror.CdkOrderError)
}
cdks := make([]*biz.Cdk, 0, len(cdkPos))
for _, cdkPo := range cdkPos {
cdk := &biz.Cdk{
Id: cdkPo.Id,
CdkId: cdkPo.CdkId,
CdkContent: cdkPo.CdkContent,
UserId: cdkPo.UserId,
CdkStatus: cdkPo.CdkStatus,
OrderId: cdkPo.OrderId,
}
cdks = append(cdks, cdk)
}
return cdks, nil
}
func (s *ServiceContent) checkBlockTxResult(hash string) (biz.TxResult, error) {
tx, err := s.chain33Client.GetRealTx(hash)
if err != nil {
return biz.TxResult{}, err
}
switch tx.Receipt.GetTy() {
case chainTypes.ExecOk:
to := ""
amount := int64(0)
symbol := ""
if tx.Tx != nil {
to = tx.Tx.To
}
if len(tx.Assets) > 0 {
assert1 := tx.Assets[0]
amount = assert1.Amount
symbol = assert1.GetSymbol()
}
return biz.TxResult{
Success: true,
To: to,
Amount: amount,
Symbol: symbol,
}, nil
case chainTypes.ExecErr:
case chainTypes.ExecPack:
}
return biz.TxResult{Success: false}, nil
}

View File

@@ -0,0 +1,94 @@
package cdk
import (
"reflect"
"testing"
chainTypes "github.com/33cn/chain33/types"
"github.com/rs/zerolog"
"gitlab.33.cn/chat/dtalk/pkg/tx"
"gitlab.33.cn/chat/dtalk/service/backend/model/biz"
)
func TestDealFailedCdkOrder(t *testing.T) {
ids := []int64{1, 2}
err := srv.dealFailedCdkOrder(ids)
if err != nil {
t.Log(err)
} else {
t.Log("success")
}
}
func TestServiceContent_checkBlockTxResult(t *testing.T) {
title := "user.p.testproofv2."
var config = tx.Config{
Grpc: tx.Grpc{
BlockChainAddr: "172.16.101.87:8902",
},
Chain: tx.Chain{
FeePrikey: "",
FeeAddr: "",
Title: title,
BaseExec: title + chainTypes.NoneX,
},
Encrypt: tx.Encrypt{
Seed: "",
SignType: 1,
},
}
type fields struct {
log zerolog.Logger
CdkOrderMessage chan *biz.CdkOrderMessage
CdkMaxNumber int64
chain33Client *tx.ChainClient
}
type args struct {
hash string
}
tests := []struct {
name string
fields fields
args args
want biz.TxResult
wantErr bool
}{
{
name: "",
fields: fields{
CdkOrderMessage: nil,
CdkMaxNumber: 0,
chain33Client: tx.MustNewChainClient(&config),
},
args: args{
hash: "",
},
want: biz.TxResult{
Success: true,
To: "19rJWrjA8qgczqHPWLfFaSxzsSYdsepoNg",
Amount: 100000000,
Symbol: "ZJY3TUY",
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &ServiceContent{
log: tt.fields.log,
CdkOrderMessage: tt.fields.CdkOrderMessage,
CdkMaxNumber: tt.fields.CdkMaxNumber,
chain33Client: tt.fields.chain33Client,
}
got, err := s.checkBlockTxResult(tt.args.hash)
if (err != nil) != tt.wantErr {
t.Errorf("checkBlockTxResult() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("checkBlockTxResult() got = %v, want %v", got, tt.want)
}
})
}
}

View File

@@ -0,0 +1,31 @@
package cdk
import (
"gitlab.33.cn/chat/dtalk/service/backend/model/types"
"gitlab.33.cn/utils/go-kit/convert"
"time"
)
func (s *ServiceContent) DeleteCdksSvc(req *types.DeleteCdksReq) (res *types.DeleteCdksResp, err error) {
defer func() {
if err != nil {
s.log.Err(err).Interface("req", req).Msg("DeleteCdksSvc")
} else {
s.log.Info().Interface("req", req).Msg("DeleteCdksSvc")
}
}()
ids := make([]int64, len(req.Ids), len(req.Ids))
for i, id := range req.Ids {
ids[i] = convert.ToInt64(id)
}
err = s.dao.DeleteCdks(ids, time.Now().UnixNano()/1e6)
if err != nil {
return nil, err
}
res = &types.DeleteCdksResp{}
return res, nil
}

View File

@@ -0,0 +1,35 @@
package cdk
import (
"gitlab.33.cn/chat/dtalk/service/backend/model/types"
"gitlab.33.cn/utils/go-kit/convert"
)
func (s *ServiceContent) DeleteCdkTypesSvc(req *types.DeleteCdkTypesReq) (res *types.DeleteCdkTypesResp, err error) {
defer func() {
if err != nil {
s.log.Err(err).Interface("req", req).Msg("DeleteCdkTypesSvc")
} else {
s.log.Info().Interface("req", req).Msg("DeleteCdkTypesSvc")
}
}()
cdkIds := make([]int64, len(req.CdkIds), len(req.CdkIds))
for i, id := range req.CdkIds {
cdkIds[i] = convert.ToInt64(id)
}
err = s.dao.DeleteCdkTypes(cdkIds)
if err != nil {
return nil, err
}
err = s.dao.DeleteCdksByCdkIds(cdkIds)
if err != nil {
return nil, err
}
res = &types.DeleteCdkTypesResp{}
return res, nil
}

View File

@@ -0,0 +1,31 @@
package cdk
import (
"gitlab.33.cn/chat/dtalk/service/backend/model/db"
"gitlab.33.cn/chat/dtalk/service/backend/model/types"
"gitlab.33.cn/utils/go-kit/convert"
)
func (s *ServiceContent) ExchangeCdksSvc(req *types.ExchangeCdksReq) (res *types.ExchangeCdksResp, err error) {
defer func() {
if err != nil {
s.log.Err(err).Interface("req", req).Msg("ExchangeCdksSvc")
} else {
s.log.Info().Interface("req", req).Msg("ExchangeCdksSvc")
}
}()
ids := make([]int64, len(req.Ids), len(req.Ids))
for i, id := range req.Ids {
ids[i] = convert.ToInt64(id)
}
err = s.dao.UpdateCdksStatus(ids, db.CdkExchange)
if err != nil {
return nil, err
}
res = &types.ExchangeCdksResp{}
return res, nil
}

View File

@@ -0,0 +1,34 @@
package cdk
import (
"gitlab.33.cn/chat/dtalk/service/backend/model/types"
"gitlab.33.cn/utils/go-kit/convert"
)
func (s *ServiceContent) GetCdksSvc(req *types.GetCdksReq) (res *types.GetCdksResp, err error) {
defer func() {
if err != nil {
s.log.Err(err).Interface("req", req).Msg("GetCdksSvc")
} else {
s.log.Info().Interface("req", req).Msg("GetCdksSvc")
}
}()
cdks, totalElements, totalPages, err := s.GetCdks(convert.ToInt64(req.CdkId), req.CdkContent, req.Page, req.PageSize)
if err != nil {
return nil, err
}
typesCdks := make([]*types.Cdk, len(cdks), len(cdks))
for i, cdk := range cdks {
typesCdk := cdk.ToTypes()
typesCdks[i] = typesCdk
}
res = &types.GetCdksResp{
TotalElements: totalElements,
TotalPages: totalPages,
Cdks: typesCdks,
}
return res, nil
}

View File

@@ -0,0 +1,70 @@
package cdk
import (
"gitlab.33.cn/chat/dtalk/service/backend/model/biz"
"gitlab.33.cn/chat/dtalk/service/backend/model/types"
)
func (s *ServiceContent) GetCdksByUserIdSvc(req *types.GetCdksByUserIdReq) (res *types.GetCdksByUserIdResp, err error) {
personId := req.PersonId
page := req.Page
pageSize := req.PageSize
defer func() {
if err != nil {
s.log.Error().Err(err).Str("personId", personId).Msg("GetCdksByUserIdSvc")
}
}()
cdks, totalElements, totalPages, err := s.GetCdksByUserId(personId, page, pageSize)
if err != nil {
return nil, err
}
cdkVos := make([]*types.Cdk, 0, len(cdks))
cdkNameMap := make(map[int64]string, 0)
for _, cdk := range cdks {
tcdk := cdk.ToTypes()
cdkName, ok := cdkNameMap[cdk.CdkId]
if !ok {
cdkType, err := s.GetCdkTypeByCdkId(cdk.CdkId)
if err != nil {
continue
}
cdkName = cdkType.CdkName
cdkNameMap[cdk.CdkId] = cdkName
}
tcdk.CdkName = cdkName
cdkVos = append(cdkVos, tcdk)
}
return &types.GetCdksByUserIdResp{
TotalElements: totalElements,
TotalPages: totalPages,
Cdks: cdkVos,
}, nil
}
func (s *ServiceContent) GetCdksByUserId(userId string, page, pageSize int64) ([]*biz.Cdk, int64, int64, error) {
cdkPos, totalElements, totalPages, err := s.dao.GetCdksWithUserId(userId, page, pageSize)
if err != nil {
return nil, 0, 0, err
}
cdks := make([]*biz.Cdk, 0, len(cdkPos))
for _, cdkPo := range cdkPos {
cdk := &biz.Cdk{
Id: cdkPo.Id,
CdkId: cdkPo.CdkId,
CdkContent: cdkPo.CdkContent,
UserId: cdkPo.UserId,
CdkStatus: cdkPo.CdkStatus,
OrderId: cdkPo.OrderId,
CreateTime: cdkPo.CreateTime,
ExchangeTime: cdkPo.ExchangeTime,
}
cdks = append(cdks, cdk)
}
return cdks, totalElements, totalPages, nil
}

View File

@@ -0,0 +1,22 @@
package cdk
import "gitlab.33.cn/chat/dtalk/service/backend/model/types"
func (s *ServiceContent) GetCdkTypeByCoinNameSvc(req *types.GetCdkTypeByCoinNameReq) (res *types.GetCdkTypeByCoinNameResp, err error) {
coinName := req.CoinName
defer func() {
if err != nil {
s.log.Error().Err(err).Str("coinName", coinName).Msg("GetCdkTypeByCoinNameSvc")
}
}()
cdkType, err := s.GetCdkTypeByCoinName(coinName)
if err != nil {
return nil, err
}
return &types.GetCdkTypeByCoinNameResp{
CdkType: cdkType.ToTypes(),
}, nil
}

View File

@@ -0,0 +1,31 @@
package cdk
import "gitlab.33.cn/chat/dtalk/service/backend/model/types"
func (s *ServiceContent) GetCdkTypesSvc(req *types.GetCdkTypesReq) (res *types.GetCdkTypesResp, err error) {
defer func() {
if err != nil {
s.log.Err(err).Interface("req", req).Msg("GetCdkTypesSvc")
} else {
s.log.Info().Interface("req", req).Msg("GetCdkTypesSvc")
}
}()
cdkTypes, totalElements, totalPages, err := s.GetCdkTypes(req.CoinName, req.Page, req.PageSize)
if err != nil {
return nil, err
}
typesCdks := make([]*types.CdkType, len(cdkTypes), len(cdkTypes))
for i, cdkType := range cdkTypes {
typesCdkType := cdkType.ToTypes()
typesCdks[i] = typesCdkType
}
res = &types.GetCdkTypesResp{
TotalElements: totalElements,
TotalPages: totalPages,
CdkTypes: typesCdks,
}
return res, nil
}

View File

@@ -0,0 +1,59 @@
package cdk
import (
chainTypes "github.com/33cn/chain33/types"
"github.com/rs/zerolog"
"gitlab.33.cn/chat/dtalk/pkg/logger"
"gitlab.33.cn/chat/dtalk/pkg/tx"
"gitlab.33.cn/chat/dtalk/service/backend/config"
"gitlab.33.cn/chat/dtalk/service/backend/dao"
"gitlab.33.cn/chat/dtalk/service/backend/model/biz"
idgen "gitlab.33.cn/chat/dtalk/service/generator/api"
)
type ServiceContent struct {
log zerolog.Logger
dao *dao.Dao
idGenRPCClient *idgen.Client
// cdk订单处理 channal
CdkOrderMessage chan *biz.CdkOrderMessage
CdkMaxNumber int64
chain33Client *tx.ChainClient
}
func NewServiceContent(env string, dao *dao.Dao, idgen *idgen.Client, cdkMaxNumber int64, chainCliConfig config.Chain33Client) *ServiceContent {
s := &ServiceContent{
log: logger.New(env, "cdkOrder"),
dao: dao,
idGenRPCClient: idgen,
CdkOrderMessage: make(chan *biz.CdkOrderMessage, 100),
CdkMaxNumber: cdkMaxNumber,
chain33Client: initChain33Client(chainCliConfig),
}
go s.ListenOrder()
go s.CleanFrozenOrder()
return s
}
func initChain33Client(chainCliConfig config.Chain33Client) *tx.ChainClient {
title := chainCliConfig.Title
cfg := tx.Config{
Grpc: tx.Grpc{
BlockChainAddr: chainCliConfig.BlockChainAddr,
},
Chain: tx.Chain{
FeePrikey: "",
FeeAddr: "",
Title: title,
BaseExec: title + chainTypes.NoneX,
},
Encrypt: tx.Encrypt{
Seed: "",
SignType: 1,
},
}
return tx.MustNewChainClient(&cfg)
}

View File

@@ -0,0 +1,26 @@
package cdk
import (
"gitlab.33.cn/chat/dtalk/service/backend/config"
"gitlab.33.cn/chat/dtalk/service/backend/dao"
idgen "gitlab.33.cn/chat/dtalk/service/generator/api"
"os"
"testing"
"time"
)
var (
cfg *config.Config
srv *ServiceContent
Dao *dao.Dao
idGenRPCClient *idgen.Client
)
func TestMain(m *testing.M) {
cfg = config.Default()
Dao = dao.New(cfg)
idGenRPCClient = idgen.New(cfg.IdGenRPCClient.RegAddrs, cfg.IdGenRPCClient.Schema, cfg.IdGenRPCClient.SrvName, time.Duration(cfg.IdGenRPCClient.Dial))
srv = NewServiceContent(cfg.Env, Dao, idGenRPCClient)
os.Exit(m.Run())
}

View File

@@ -0,0 +1,24 @@
package cdk
import (
"gitlab.33.cn/chat/dtalk/service/backend/model/types"
"gitlab.33.cn/utils/go-kit/convert"
)
func (s *ServiceContent) UpdateCdkTypeSvc(req *types.UpdateCdkTypeReq) (res *types.UpdateCdkTypeResp, err error) {
defer func() {
if err != nil {
s.log.Err(err).Interface("req", req).Msg("UpdateCdkTypeSvc")
} else {
s.log.Info().Interface("req", req).Msg("UpdateCdkTypeSvc")
}
}()
cdkId := convert.ToInt64(req.CdkId)
err = s.dao.UpdateCdkType(cdkId, req.CdkName, req.CoinName, req.ExchangeRate)
if err != nil {
return nil, err
}
return &types.UpdateCdkTypeResp{}, nil
}

View File

@@ -0,0 +1,44 @@
package service
import (
"github.com/inconshreveable/log15"
"gitlab.33.cn/chat/dtalk/service/backend/config"
"gitlab.33.cn/chat/dtalk/service/backend/dao"
"gitlab.33.cn/chat/dtalk/service/backend/service/cdk"
idgen "gitlab.33.cn/chat/dtalk/service/generator/api"
"time"
)
type Service struct {
log log15.Logger
cfg *config.Config
dao *dao.Dao
Platform string
idGenRPCClient *idgen.Client
CdkService *cdk.ServiceContent
}
func New(cfg *config.Config) *Service {
s := &Service{
log: log15.New("module", "backend/svc"),
cfg: cfg,
dao: dao.New(cfg),
Platform: cfg.Platform,
idGenRPCClient: idgen.New(cfg.IdGenRPCClient.RegAddrs, cfg.IdGenRPCClient.Schema, cfg.IdGenRPCClient.SrvName, time.Duration(cfg.IdGenRPCClient.Dial)),
}
if cfg.CdkMod {
s.CdkService = cdk.NewServiceContent(cfg.Env, s.dao, s.idGenRPCClient, cfg.CdkMaxNumber, cfg.Chain33Client)
}
return s
}
func (s *Service) Ping() error {
return nil
}
func (s Service) Config() *config.Config {
return s.cfg
}

View File

@@ -0,0 +1,192 @@
package service
import (
"github.com/dgrijalva/jwt-go"
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
"gitlab.33.cn/chat/dtalk/service/backend/config"
"gitlab.33.cn/chat/dtalk/service/backend/model"
"time"
)
func (s *Service) CreateVersion(request *model.VersionCreateRequest) (res *model.VersionCreateResponse, err error) {
defer func() {
if err != nil {
s.log.Error("CreateVersion", "err", err, "req", request)
} else {
s.log.Info("CreateVersion", "req", request)
}
}()
versionForm := model.VersionForm{
Platform: request.Platform,
DeviceType: request.DeviceType,
VersionName: request.VersionName,
VersionCode: request.VersionCode,
Url: request.Url,
Size: request.Size,
Md5: request.Md5,
Description: request.Description,
Force: request.Force,
OpeUser: request.OpeUser,
CreateTime: time.Now().UnixNano() / 1e6,
UpdateTime: time.Now().UnixNano() / 1e6,
}
_, id, err := s.dao.InsertVersion(&versionForm)
if err != nil {
return nil, err
}
versionForm.Id = id
return &model.VersionCreateResponse{
Version: versionForm,
}, err
}
func (s *Service) UpdateVersion(request *model.VersionUpdateRequest) (res *model.VersionUpdateResponse, err error) {
defer func() {
if err != nil {
s.log.Error("UpdateVersion", "err", err, "req", request)
} else {
s.log.Info("UpdateVersion", "req", request)
}
}()
versionForm := model.VersionForm{
Id: request.Id,
VersionName: request.VersionName,
VersionCode: request.VersionCode,
Url: request.Url,
Description: request.Description,
UpdateTime: time.Now().UnixNano() / 1e6,
Force: request.Force,
OpeUser: request.OpeUser,
Md5: request.Md5,
Size: request.Size,
}
result, err := s.dao.UpdateVersion(&versionForm)
if err != nil {
return nil, err
}
response := &model.VersionUpdateResponse{
Version: *result,
}
return response, err
}
func (s *Service) ChangeVersionStatus(request *model.VersionChangeStatusRequest) (err error) {
defer func() {
if err != nil {
s.log.Error("ChangeVersionStatus", "err", err, "req", request)
} else {
s.log.Info("ChangeVersionStatus", "req", request)
}
}()
versionForm := model.VersionForm{
Id: request.Id,
UpdateTime: time.Now().UnixNano() / 1e6,
OpeUser: request.OpeUser,
}
err = s.dao.ChangeVersionStatus(&versionForm)
return err
}
func (s *Service) GetVersionList(request *model.GetVersionListRequest) (res *model.GetVersionListResponse, err error) {
defer func() {
if err != nil {
s.log.Error("GetVersionList", "err", err, "req", request)
} else {
s.log.Info("GetVersionList", "req", request)
}
}()
versionForm := model.VersionForm{
Platform: request.Platform,
DeviceType: request.DeviceType,
}
versionList, totalElements, totalPages, err := s.dao.GetVersionList(&versionForm, request.Page, model.Size)
if err != nil {
return nil, err
}
response := &model.GetVersionListResponse{
TotalElements: totalElements,
TotalPages: totalPages,
VersionList: *versionList,
}
return response, err
}
func (s *Service) CheckAndUpdateVersion(request *model.VersionCheckAndUpdateRequest) (res *model.VersionCheckAndUpdateResponse, err error) {
defer func() {
if err != nil {
s.log.Error("CheckAndUpdateVersion", "err", err, "req", request)
} else {
s.log.Info("CheckAndUpdateVersion", "req", request)
}
}()
versionForm := model.VersionForm{
VersionCode: request.VersionCode,
DeviceType: request.DeviceType,
Platform: s.Platform,
}
result, err := s.dao.CheckAndUpdateVersion(&versionForm)
if err != nil {
return nil, err
}
response := &model.VersionCheckAndUpdateResponse{}
response.Id = result.Id
response.Platform = result.Platform
response.Status = result.Status
response.DeviceType = result.DeviceType
response.VersionName = result.VersionName
response.VersionCode = result.VersionCode
response.Url = result.Url
response.Force = result.Force
response.Description = result.Description
response.OpeUser = result.OpeUser
response.Md5 = result.Md5
response.Size = result.Size
response.UpdateTime = result.UpdateTime
response.CreateTime = result.CreateTime
return response, err
}
func (s *Service) GetToken(request *model.GetTokenRequest) (res *model.GetTokenResponse, err error) {
defer func() {
if err != nil {
s.log.Error("GetToken", "err", err, "req", request)
} else {
s.log.Info("GetToken", "req", request)
}
}()
userInfo := model.UserInfo{
UserName: request.UserName,
Password: request.Password,
}
if userInfo.UserName != config.Conf.Release.UserName || userInfo.Password != config.Conf.Release.Password {
return nil, xerror.NewError(xerror.ParamsError).SetExtMessage("用户名或密码错误")
}
token, err := s.createToken(userInfo.UserName)
if err != nil {
return nil, err
}
return &model.GetTokenResponse{
UserInfo: model.UserInfoResponse{
UserName: userInfo.UserName,
Token: token,
},
}, nil
}
func (s *Service) createToken(username string) (string, error) {
c := model.Claims{
Username: username,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(config.Conf.Release.TokenExpireDuration).Unix(),
Issuer: config.Conf.Release.Issuer,
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
return token.SignedString([]byte(config.Conf.Release.Key))
}

View File

@@ -0,0 +1,16 @@
package version
//var (
// // The full version string
// Version = "0.2.3"
//
// // GitCommit is set with --ldflags "-X main.gitCommit=$(git rev-parse --short=8 HEAD)"
// GitCommit string
//)
//
//func GetVersion() string {
// if GitCommit != "" {
// return Version + "-" + GitCommit
// }
// return Version
//}