finish
This commit is contained in:
1059
docs/docs.go
1059
docs/docs.go
File diff suppressed because it is too large
Load Diff
1059
docs/swagger.json
1059
docs/swagger.json
File diff suppressed because it is too large
Load Diff
@@ -54,6 +54,9 @@ definitions:
|
||||
createUser:
|
||||
description: 文章创建者id
|
||||
type: integer
|
||||
id:
|
||||
description: 文章id
|
||||
type: integer
|
||||
isDelete:
|
||||
description: 删除标志
|
||||
type: integer
|
||||
@@ -76,6 +79,138 @@ definitions:
|
||||
description: 文章标题
|
||||
type: string
|
||||
type: object
|
||||
models.BackLocation:
|
||||
properties:
|
||||
address:
|
||||
description: 地点的精确地址
|
||||
type: string
|
||||
createTime:
|
||||
description: 创建时间
|
||||
type: string
|
||||
createUser:
|
||||
description: 创建者
|
||||
type: integer
|
||||
id:
|
||||
description: ID
|
||||
type: integer
|
||||
isDelete:
|
||||
description: 删除标志
|
||||
type: integer
|
||||
modifyTime:
|
||||
description: 修改时间
|
||||
type: string
|
||||
modifyUser:
|
||||
description: 修改者
|
||||
type: integer
|
||||
name:
|
||||
description: 地点名
|
||||
type: string
|
||||
principalName:
|
||||
description: 负责人姓名
|
||||
type: string
|
||||
principalPhone:
|
||||
description: 负责人电话
|
||||
type: string
|
||||
region:
|
||||
description: 地点所在地区
|
||||
type: string
|
||||
type: object
|
||||
models.BackNotification:
|
||||
properties:
|
||||
content:
|
||||
type: string
|
||||
kind:
|
||||
type: string
|
||||
time:
|
||||
type: string
|
||||
type: object
|
||||
models.BackObservation:
|
||||
properties:
|
||||
address:
|
||||
description: 受观察者所在具体地点
|
||||
type: string
|
||||
age:
|
||||
description: 年龄
|
||||
type: integer
|
||||
contactPerson:
|
||||
description: 接触者id
|
||||
type: integer
|
||||
createTime:
|
||||
description: 创建时间
|
||||
type: string
|
||||
createUser:
|
||||
description: 创建者
|
||||
type: integer
|
||||
healthChangeTime:
|
||||
description: 患者健康状况转化时间
|
||||
type: string
|
||||
healthSituation:
|
||||
description: 被观察者的疫情状况:0- 其他,1-患者,2-密接,3-次密接
|
||||
type: integer
|
||||
id:
|
||||
description: ID
|
||||
type: integer
|
||||
identification:
|
||||
description: 身份证号
|
||||
type: string
|
||||
isDelete:
|
||||
description: 删除标志
|
||||
type: integer
|
||||
measureSituation:
|
||||
description: 受观察者被采取措施状况 :0-未采取措施,1-解除风险,2-正在治疗,3-集中隔离,4-居家隔离
|
||||
type: integer
|
||||
modifyTime:
|
||||
description: 修改时间
|
||||
type: string
|
||||
modifyUser:
|
||||
description: 修改者
|
||||
type: integer
|
||||
name:
|
||||
description: 姓名
|
||||
type: string
|
||||
phone:
|
||||
description: 手机号码
|
||||
type: string
|
||||
region:
|
||||
description: 受观察者所在区域
|
||||
type: string
|
||||
sex:
|
||||
description: 性别
|
||||
type: integer
|
||||
trajectory:
|
||||
description: 行程轨迹
|
||||
type: string
|
||||
type: object
|
||||
models.BackPcr:
|
||||
properties:
|
||||
createTime:
|
||||
description: 创建时间
|
||||
type: string
|
||||
createUser:
|
||||
description: 创建者
|
||||
type: integer
|
||||
detectResult:
|
||||
description: 核酸检测结果:0-未检测,1-阴性,2-阳性
|
||||
type: integer
|
||||
detectTime:
|
||||
description: 核酸检测时间
|
||||
type: string
|
||||
id:
|
||||
description: ID
|
||||
type: integer
|
||||
isDelete:
|
||||
description: 删除标志
|
||||
type: integer
|
||||
modifyTime:
|
||||
description: 修改时间
|
||||
type: string
|
||||
modifyUser:
|
||||
description: 修改者
|
||||
type: integer
|
||||
observation:
|
||||
description: 观察对象ID
|
||||
type: integer
|
||||
type: object
|
||||
models.BackUser:
|
||||
properties:
|
||||
approver:
|
||||
@@ -256,6 +391,8 @@ definitions:
|
||||
type: string
|
||||
createTime:
|
||||
type: string
|
||||
id:
|
||||
type: integer
|
||||
modifyTime:
|
||||
type: string
|
||||
resume:
|
||||
@@ -267,6 +404,129 @@ definitions:
|
||||
username:
|
||||
type: string
|
||||
type: object
|
||||
models.ListObservation:
|
||||
properties:
|
||||
address:
|
||||
description: 受观察者所在具体地点
|
||||
type: string
|
||||
age:
|
||||
description: 年龄
|
||||
type: integer
|
||||
contactPerson:
|
||||
description: 接触者id
|
||||
type: integer
|
||||
createTime:
|
||||
description: 创建时间
|
||||
type: string
|
||||
createUser:
|
||||
description: 创建者
|
||||
type: integer
|
||||
healthChangeTime:
|
||||
description: 患者健康状况转化时间
|
||||
type: string
|
||||
healthSituation:
|
||||
description: 被观察者的疫情状况:0- 其他,1-患者,2-密接,3-次密接
|
||||
type: integer
|
||||
id:
|
||||
type: integer
|
||||
identification:
|
||||
description: 身份证号
|
||||
type: string
|
||||
measureSituation:
|
||||
description: 受观察者被采取措施状况 :0-未采取措施,1-解除风险,2-正在治疗,3-集中隔离,4-居家隔离
|
||||
type: integer
|
||||
modifyTime:
|
||||
description: 修改时间
|
||||
type: string
|
||||
modifyUser:
|
||||
description: 修改者
|
||||
type: integer
|
||||
name:
|
||||
description: 姓名
|
||||
type: string
|
||||
pcrResult:
|
||||
description: 核酸结果:0-未检测,1-阴性,2-阳性
|
||||
type: integer
|
||||
pcrTime:
|
||||
description: 核酸时间
|
||||
type: string
|
||||
phone:
|
||||
description: 手机号码
|
||||
type: string
|
||||
record:
|
||||
description: 状态转换内容
|
||||
type: string
|
||||
recordTime:
|
||||
description: 状态转换时间
|
||||
type: string
|
||||
region:
|
||||
description: 受观察者所在区域
|
||||
type: string
|
||||
sex:
|
||||
description: 性别
|
||||
type: integer
|
||||
trajectory:
|
||||
description: 行程轨迹
|
||||
type: string
|
||||
type: object
|
||||
models.TreeObservation:
|
||||
properties:
|
||||
address:
|
||||
description: 受观察者所在具体地点
|
||||
type: string
|
||||
age:
|
||||
description: 年龄
|
||||
type: integer
|
||||
children:
|
||||
description: 子结点
|
||||
items:
|
||||
$ref: '#/definitions/models.TreeObservation'
|
||||
type: array
|
||||
contactPerson:
|
||||
description: 接触者id
|
||||
type: integer
|
||||
createTime:
|
||||
description: 创建时间
|
||||
type: string
|
||||
createUser:
|
||||
description: 创建者
|
||||
type: integer
|
||||
healthChangeTime:
|
||||
description: 患者健康状况转化时间
|
||||
type: string
|
||||
healthSituation:
|
||||
description: 被观察者的疫情状况:0- 其他,1-患者,2-密接,3-次密接
|
||||
type: integer
|
||||
id:
|
||||
type: integer
|
||||
identification:
|
||||
description: 身份证号
|
||||
type: string
|
||||
measureSituation:
|
||||
description: 受观察者被采取措施状况 :0-未采取措施,1-解除风险,2-正在治疗,3-集中隔离,4-居家隔离
|
||||
type: integer
|
||||
modifyTime:
|
||||
description: 修改时间
|
||||
type: string
|
||||
modifyUser:
|
||||
description: 修改者
|
||||
type: integer
|
||||
name:
|
||||
description: 姓名
|
||||
type: string
|
||||
phone:
|
||||
description: 手机号码
|
||||
type: string
|
||||
region:
|
||||
description: 受观察者所在区域
|
||||
type: string
|
||||
sex:
|
||||
description: 性别
|
||||
type: integer
|
||||
trajectory:
|
||||
description: 行程轨迹
|
||||
type: string
|
||||
type: object
|
||||
models.UserApprove:
|
||||
properties:
|
||||
email:
|
||||
@@ -480,6 +740,456 @@ paths:
|
||||
summary: get user's articles
|
||||
tags:
|
||||
- Article
|
||||
/management/faker/{patientId}:
|
||||
get:
|
||||
parameters:
|
||||
- description: Token
|
||||
in: header
|
||||
name: Token
|
||||
required: true
|
||||
type: string
|
||||
- description: Patient Id
|
||||
in: path
|
||||
name: patientId
|
||||
required: true
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/utils.GinResponse'
|
||||
summary: pull contact from faker
|
||||
tags:
|
||||
- Management
|
||||
/management/location/:
|
||||
get:
|
||||
parameters:
|
||||
- description: 地点的精确地址
|
||||
in: query
|
||||
name: address
|
||||
type: string
|
||||
- description: 创建时间
|
||||
in: query
|
||||
name: createTime
|
||||
type: string
|
||||
- description: 创建者
|
||||
in: query
|
||||
name: createUser
|
||||
type: integer
|
||||
- description: ID
|
||||
in: query
|
||||
name: id
|
||||
type: integer
|
||||
- description: 删除标志
|
||||
in: query
|
||||
name: isDelete
|
||||
type: integer
|
||||
- description: 修改时间
|
||||
in: query
|
||||
name: modifyTime
|
||||
type: string
|
||||
- description: 修改者
|
||||
in: query
|
||||
name: modifyUser
|
||||
type: integer
|
||||
- description: 地点名
|
||||
in: query
|
||||
name: name
|
||||
type: string
|
||||
- description: 负责人姓名
|
||||
in: query
|
||||
name: principalName
|
||||
type: string
|
||||
- description: 负责人电话
|
||||
in: query
|
||||
name: principalPhone
|
||||
type: string
|
||||
- description: 地点所在地区
|
||||
in: query
|
||||
name: region
|
||||
type: string
|
||||
- description: token
|
||||
in: header
|
||||
name: Token
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/utils.GinResponse'
|
||||
- properties:
|
||||
data:
|
||||
$ref: '#/definitions/models.BackLocation'
|
||||
type: object
|
||||
summary: list locations
|
||||
tags:
|
||||
- Management
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
parameters:
|
||||
- description: location
|
||||
in: body
|
||||
name: Location
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/models.BackLocation'
|
||||
- description: token
|
||||
in: header
|
||||
name: Token
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/utils.GinResponse'
|
||||
summary: insert location
|
||||
tags:
|
||||
- Management
|
||||
/management/location/{id}:
|
||||
delete:
|
||||
parameters:
|
||||
- description: token
|
||||
in: header
|
||||
name: Token
|
||||
required: true
|
||||
type: string
|
||||
- description: Id
|
||||
in: path
|
||||
name: Id
|
||||
required: true
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/utils.GinResponse'
|
||||
summary: delete location
|
||||
tags:
|
||||
- Management
|
||||
/management/observation/:
|
||||
get:
|
||||
parameters:
|
||||
- description: token
|
||||
in: header
|
||||
name: Token
|
||||
required: true
|
||||
type: string
|
||||
- description: 受观察者所在具体地点
|
||||
in: query
|
||||
name: address
|
||||
type: string
|
||||
- description: 年龄
|
||||
in: query
|
||||
name: age
|
||||
type: integer
|
||||
- description: 接触者id
|
||||
in: query
|
||||
name: contactPerson
|
||||
type: integer
|
||||
- description: 创建时间
|
||||
in: query
|
||||
name: createTime
|
||||
type: string
|
||||
- description: 创建者
|
||||
in: query
|
||||
name: createUser
|
||||
type: integer
|
||||
- description: 患者健康状况转化时间
|
||||
in: query
|
||||
name: healthChangeTime
|
||||
type: string
|
||||
- description: 被观察者的疫情状况:0- 其他,1-患者,2-密接,3-次密接
|
||||
in: query
|
||||
name: healthSituation
|
||||
type: integer
|
||||
- description: ID
|
||||
in: query
|
||||
name: id
|
||||
type: integer
|
||||
- description: 身份证号
|
||||
in: query
|
||||
name: identification
|
||||
type: string
|
||||
- description: 删除标志
|
||||
in: query
|
||||
name: isDelete
|
||||
type: integer
|
||||
- description: 受观察者被采取措施状况 :0-未采取措施,1-解除风险,2-正在治疗,3-集中隔离,4-居家隔离
|
||||
in: query
|
||||
name: measureSituation
|
||||
type: integer
|
||||
- description: 修改时间
|
||||
in: query
|
||||
name: modifyTime
|
||||
type: string
|
||||
- description: 修改者
|
||||
in: query
|
||||
name: modifyUser
|
||||
type: integer
|
||||
- description: 姓名
|
||||
in: query
|
||||
name: name
|
||||
type: string
|
||||
- description: 手机号码
|
||||
in: query
|
||||
name: phone
|
||||
type: string
|
||||
- description: 受观察者所在区域
|
||||
in: query
|
||||
name: region
|
||||
type: string
|
||||
- description: 性别
|
||||
in: query
|
||||
name: sex
|
||||
type: integer
|
||||
- description: 行程轨迹
|
||||
in: query
|
||||
name: trajectory
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/utils.GinResponse'
|
||||
- properties:
|
||||
data:
|
||||
items:
|
||||
$ref: '#/definitions/models.ListObservation'
|
||||
type: array
|
||||
type: object
|
||||
summary: list observations by query
|
||||
tags:
|
||||
- Management
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
parameters:
|
||||
- description: observation
|
||||
in: body
|
||||
name: Observation
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/models.BackObservation'
|
||||
- description: token
|
||||
in: header
|
||||
name: Token
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/utils.GinResponse'
|
||||
summary: insert observation
|
||||
tags:
|
||||
- Management
|
||||
put:
|
||||
consumes:
|
||||
- application/json
|
||||
parameters:
|
||||
- description: observation
|
||||
in: body
|
||||
name: Observation
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/models.BackObservation'
|
||||
- description: token
|
||||
in: header
|
||||
name: Token
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/utils.GinResponse'
|
||||
summary: update observation
|
||||
tags:
|
||||
- Management
|
||||
/management/observation/{id}:
|
||||
get:
|
||||
parameters:
|
||||
- description: token
|
||||
in: header
|
||||
name: token
|
||||
required: true
|
||||
type: string
|
||||
- description: id
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/utils.GinResponse'
|
||||
- properties:
|
||||
data:
|
||||
$ref: '#/definitions/models.BackObservation'
|
||||
type: object
|
||||
summary: get observation's info
|
||||
tags:
|
||||
- Management
|
||||
/management/observation/tree/{id}/{direction}:
|
||||
get:
|
||||
parameters:
|
||||
- description: token
|
||||
in: header
|
||||
name: Token
|
||||
required: true
|
||||
type: string
|
||||
- description: id
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
- description: direction
|
||||
enum:
|
||||
- up
|
||||
- down
|
||||
- all
|
||||
in: path
|
||||
name: direction
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/utils.GinResponse'
|
||||
- properties:
|
||||
data:
|
||||
$ref: '#/definitions/models.TreeObservation'
|
||||
type: object
|
||||
summary: get transform chain by user
|
||||
tags:
|
||||
- Management
|
||||
/management/pcr/:
|
||||
post:
|
||||
parameters:
|
||||
- description: Pcr
|
||||
in: body
|
||||
name: Pcr
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/models.BackPcr'
|
||||
- description: token
|
||||
in: header
|
||||
name: Token
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/utils.GinResponse'
|
||||
summary: insert pcr record
|
||||
tags:
|
||||
- Management
|
||||
/notify/{index}:
|
||||
delete:
|
||||
parameters:
|
||||
- description: token
|
||||
in: header
|
||||
name: Token
|
||||
required: true
|
||||
type: string
|
||||
- description: index
|
||||
in: path
|
||||
name: index
|
||||
required: true
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/utils.GinResponse'
|
||||
summary: delete the notify by index, if -1 delete all
|
||||
tags:
|
||||
- Notification
|
||||
/notify/{start}/{end}:
|
||||
get:
|
||||
parameters:
|
||||
- description: token
|
||||
in: header
|
||||
name: Token
|
||||
required: true
|
||||
type: string
|
||||
- description: start
|
||||
in: path
|
||||
name: start
|
||||
required: true
|
||||
type: integer
|
||||
- description: end
|
||||
in: path
|
||||
name: end
|
||||
required: true
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/utils.GinResponse'
|
||||
- properties:
|
||||
data:
|
||||
items:
|
||||
$ref: '#/definitions/models.BackNotification'
|
||||
type: array
|
||||
type: object
|
||||
summary: list the notification in the range
|
||||
tags:
|
||||
- Notification
|
||||
/notify/count/:
|
||||
get:
|
||||
parameters:
|
||||
- description: token
|
||||
in: header
|
||||
name: Token
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/utils.GinResponse'
|
||||
summary: count the notification
|
||||
tags:
|
||||
- Notification
|
||||
/statistics/china:
|
||||
get:
|
||||
produces:
|
||||
|
||||
@@ -12,6 +12,7 @@ type ServerConfig struct {
|
||||
Jwt JwtConfig `yaml:"jwt"`
|
||||
Email EmailConfig `yaml:"email"`
|
||||
Bos BosConfig `yaml:"bos"`
|
||||
Kafka KafkaCofig `yaml:"kafka"`
|
||||
}
|
||||
|
||||
type MySQLConfig struct {
|
||||
@@ -46,3 +47,9 @@ type BosConfig struct {
|
||||
SecretKey string `yaml:"secretKey"`
|
||||
Domain string `yaml:"domain"`
|
||||
}
|
||||
|
||||
type KafkaCofig struct {
|
||||
Servers []string `yaml:"servers"`
|
||||
Topic string `yaml:"topic"`
|
||||
Partition int `yaml:"partition"`
|
||||
}
|
||||
|
||||
@@ -4,12 +4,11 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/baidubce/bce-sdk-go/services/bos"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-redis/redis"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -76,4 +75,5 @@ var (
|
||||
"NEGATIVE": 1,
|
||||
"POSITIVE": 2,
|
||||
}
|
||||
KafkaProducerChan = make(chan []byte)
|
||||
)
|
||||
|
||||
19
go.mod
19
go.mod
@@ -18,7 +18,12 @@ require (
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/Shopify/sarama v1.32.0 // indirect
|
||||
github.com/baidubce/bce-sdk-go v0.9.112 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/eapache/go-resiliency v1.2.0 // indirect
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect
|
||||
github.com/eapache/queue v1.1.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
@@ -31,13 +36,21 @@ require (
|
||||
github.com/go-sql-driver/mysql v1.6.0 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
|
||||
github.com/jcmturner/gofork v1.0.0 // indirect
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.2 // indirect
|
||||
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.4 // indirect
|
||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.15.2 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/magiconair/properties v1.8.5 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
@@ -49,6 +62,8 @@ require (
|
||||
github.com/onsi/ginkgo v1.16.5 // indirect
|
||||
github.com/onsi/gomega v1.18.0 // indirect
|
||||
github.com/pelletier/go-toml v1.9.4 // indirect
|
||||
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||
github.com/spf13/afero v1.8.0 // indirect
|
||||
github.com/spf13/cast v1.4.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
@@ -59,8 +74,8 @@ require (
|
||||
github.com/ugorji/go/codec v1.2.6 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.7.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce // indirect
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
|
||||
golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f // indirect
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/tools v0.1.9 // indirect
|
||||
|
||||
52
go.sum
52
go.sum
@@ -44,6 +44,9 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/Shopify/sarama v1.32.0 h1:P+RUjEaRU0GMMbYexGMDyrMkLhbbBVUVISDywi+IlFU=
|
||||
github.com/Shopify/sarama v1.32.0/go.mod h1:+EmJJKZWVT/faR9RcOxJerP+LId4iWdQPBGLy1Y1Njs=
|
||||
github.com/Shopify/toxiproxy/v2 v2.3.0/go.mod h1:KvQTtB6RjCJY4zqNJn7C7JDFgsG5uoHYDirfUfpIm0c=
|
||||
github.com/agiledragon/gomonkey/v2 v2.3.1 h1:k+UnUY0EMNYUFUAQVETGY9uUTxjMdnUkP0ARyJS1zzs=
|
||||
github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY=
|
||||
github.com/baidubce/bce-sdk-go v0.9.112 h1:qHzFxG7fwGbXCv+1smcbWFhWl6iwoXDVzPn9TUtrlss=
|
||||
@@ -63,6 +66,12 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q=
|
||||
github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
@@ -71,6 +80,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
|
||||
@@ -144,6 +155,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
@@ -157,6 +170,7 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
@@ -180,6 +194,12 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
@@ -187,6 +207,17 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
|
||||
github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8=
|
||||
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||
github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.2 h1:6ZIM6b/JJN0X8UM43ZOM6Z4SJzla+a/u7scXFJzodkA=
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc=
|
||||
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
|
||||
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.3/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
@@ -203,6 +234,9 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.14.4/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.2 h1:3WH+AG7s2+T8o3nrM/8u2rdqUEcQhmga7smjrT41nAw=
|
||||
github.com/klauspost/compress v1.15.2/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
@@ -260,6 +294,8 @@ github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT9
|
||||
github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
|
||||
github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=
|
||||
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=
|
||||
github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@@ -268,6 +304,8 @@ github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qR
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
@@ -276,6 +314,7 @@ github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUA
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/spf13/afero v1.8.0 h1:5MmtuhAgYeU6qpa7w7bP0dv6MBYuup0vekhSpSkoq60=
|
||||
@@ -313,6 +352,9 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY
|
||||
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
|
||||
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.0/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
|
||||
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@@ -340,6 +382,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
@@ -347,6 +390,9 @@ golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+Wr
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI=
|
||||
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f h1:OeJjE6G4dgCY4PIXvIRQbE8+RX+uXZyGhUy/ksMGJoc=
|
||||
golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -419,10 +465,13 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba h1:6u6sik+bn/y7vILcYkK3iwTBWN7WtBvB0+SZswQnbf8=
|
||||
golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -456,6 +505,7 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -498,12 +548,14 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c=
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
|
||||
@@ -31,7 +31,7 @@ func SaveArticleHandler(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
colMap := models.MapJ2c[models.BackArticle](jsonMap, true)
|
||||
if ok := article.SaveArticle(colMap); !ok {
|
||||
if ok := article.SaveArticle(claims, colMap); !ok {
|
||||
ServerErr(c, "Save Failed")
|
||||
return
|
||||
}
|
||||
@@ -90,7 +90,7 @@ func ListArticlesByUser(c *gin.Context) {
|
||||
func DeleteArticleHandler(c *gin.Context) {
|
||||
id, err := strconv.Atoi(c.Param("id"))
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
if claims.Role == global.ROLE_ID_MAP["ADMIN"] {
|
||||
if claims.Role != global.ROLE_ID_MAP["ADMIN"] {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
@@ -140,7 +140,7 @@ func GetArticleHandler(c *gin.Context) {
|
||||
func PublishArticleHandler(c *gin.Context) {
|
||||
id, err := strconv.Atoi(c.Param("id"))
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
if claims.Role == global.ROLE_ID_MAP["ADMIN"] {
|
||||
if claims.Role != global.ROLE_ID_MAP["ADMIN"] {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"nCovTrack-Backend/global"
|
||||
"nCovTrack-Backend/service/management"
|
||||
"nCovTrack-Backend/utils"
|
||||
"strconv"
|
||||
@@ -8,8 +9,20 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
//PullContactHandler pull contact from faker
|
||||
// @Tags Management
|
||||
// @Produce json
|
||||
// @Summary pull contact from faker
|
||||
// @Success 200 {object} utils.GinResponse
|
||||
// @Router /management/faker/{patientId} [get]
|
||||
// @Param Token header string true "Token"
|
||||
// @Param patientId path int true "Patient Id"
|
||||
func PullContactHandler(c *gin.Context) {
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
if claims.Role != global.ROLE_ID_MAP["ADMIN"] {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
patientId, _ := strconv.Atoi(c.Param("patientId"))
|
||||
rowsAffected := management.PullFromFaker(claims, patientId)
|
||||
if rowsAffected == -1 {
|
||||
@@ -19,13 +32,82 @@ func PullContactHandler(c *gin.Context) {
|
||||
utils.Succ(c, map[string]interface{}{"pullAmount": rowsAffected})
|
||||
}
|
||||
|
||||
//GetObservationHandler get observation's info
|
||||
// @Tags Management
|
||||
// @Produce json
|
||||
// @Summary get observation's info
|
||||
// @Success 200 {object} utils.GinResponse{data=models.BackObservation}
|
||||
// @Router /management/observation/{id} [get]
|
||||
// @Param token header string true "token"
|
||||
// @Param id path int true "id"
|
||||
func GetObservationHandler(c *gin.Context) {
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
allowRows := []int{global.ROLE_ID_MAP["ADMIN"], global.ROLE_ID_MAP["WORKER"], global.ROLE_ID_MAP["VOLUNTEER"]}
|
||||
if !utils.Contains(allowRows, claims.Role) {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
id, _ := strconv.Atoi(c.Param("id"))
|
||||
utils.Succ(c, management.GetObservation(id))
|
||||
}
|
||||
|
||||
//ListObservationsHandler list observations by query
|
||||
// @Tags Management
|
||||
// @Produce json
|
||||
// @Summary list observations by query
|
||||
// @Success 200 {object} utils.GinResponse{data=[]models.ListObservation}
|
||||
// @Router /management/observation/ [get]
|
||||
// @Param Token header string true "token"
|
||||
// @Param queries query models.BackObservation true "queries"
|
||||
func ListObservationsHandler(c *gin.Context) {
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
allowRows := []int{global.ROLE_ID_MAP["ADMIN"], global.ROLE_ID_MAP["WORKER"], global.ROLE_ID_MAP["VOLUNTEER"]}
|
||||
if !utils.Contains(allowRows, claims.Role) {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
jsonMap := bindQuery(c)
|
||||
utils.Succ(c, management.ListObservation(jsonMap))
|
||||
}
|
||||
|
||||
//TreeifyObservationHandler get transform chain by user
|
||||
// @Tags Management
|
||||
// @Produce json
|
||||
// @Summary get transform chain by user
|
||||
// @Success 200 {object} utils.GinResponse{data=models.TreeObservation}
|
||||
// @Router /management/observation/tree/{id}/{direction} [get]
|
||||
// @Param Token header string true "token"
|
||||
// @Param id path int true "id"
|
||||
// @Param direction path string true "direction" Enums(up, down, all)
|
||||
func TreeifyObservationHandler(c *gin.Context) {
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
allowRows := []int{global.ROLE_ID_MAP["ADMIN"], global.ROLE_ID_MAP["WORKER"], global.ROLE_ID_MAP["VOLUNTEER"]}
|
||||
if !utils.Contains(allowRows, claims.Role) {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
id, _ := strconv.Atoi(c.Param("id"))
|
||||
direction := c.Param("direction")
|
||||
tree := management.TreeifyObservations(id, direction)
|
||||
utils.Succ(c, tree)
|
||||
}
|
||||
|
||||
//InsertObservationHandler insert observation
|
||||
// @Tags Management
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Summary insert observation
|
||||
// @Success 200 {object} utils.GinResponse
|
||||
// @Router /management/observation/ [post]
|
||||
// @Param Observation body models.BackObservation true "observation"
|
||||
// @Param Token header string true "token"
|
||||
func InsertObservationHandler(c *gin.Context) {
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
allowRows := []int{global.ROLE_ID_MAP["ADMIN"], global.ROLE_ID_MAP["WORKER"]}
|
||||
if !utils.Contains(allowRows, claims.Role) {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
observaion := bindJson(c)
|
||||
delete(observaion, "id")
|
||||
ok := management.InsertObservation(claims, observaion)
|
||||
@@ -36,18 +118,65 @@ func InsertObservationHandler(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func GetObservationHandler(c *gin.Context) {
|
||||
id, _ := strconv.Atoi(c.Param("id"))
|
||||
utils.Succ(c, management.GetObservation(id))
|
||||
//UpdateObservationHandler update observation
|
||||
// @Tags Management
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Summary update observation
|
||||
// @Success 200 {object} utils.GinResponse
|
||||
// @Router /management/observation/ [put]
|
||||
// @Param Observation body models.BackObservation true "observation"
|
||||
// @Param Token header string true "token"
|
||||
func UpdateObservationHandler(c *gin.Context) {
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
allowRows := []int{global.ROLE_ID_MAP["ADMIN"], global.ROLE_ID_MAP["WORKER"]}
|
||||
if !utils.Contains(allowRows, claims.Role) {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
observation := bindJson(c)
|
||||
ok := management.UpdateObservation(claims, observation)
|
||||
if ok {
|
||||
utils.Succ(c, nil)
|
||||
} else {
|
||||
OperationFailed(c)
|
||||
}
|
||||
}
|
||||
|
||||
//ListLocationHandler list locations
|
||||
// @Tags Management
|
||||
// @Produce json
|
||||
// @Summary list locations
|
||||
// @Success 200 {object} utils.GinResponse{data=models.BackLocation}
|
||||
// @Router /management/location/ [get]
|
||||
// @Param queries query models.BackLocation true "queries"
|
||||
// @Param Token header string true "token"
|
||||
func ListLocationHandler(c *gin.Context) {
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
allowRows := []int{global.ROLE_ID_MAP["ADMIN"], global.ROLE_ID_MAP["WORKER"], global.ROLE_ID_MAP["VOLUNTEER"]}
|
||||
if !utils.Contains(allowRows, claims.Role) {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
queryMap := bindQuery(c)
|
||||
utils.Succ(c, management.ListLocation(queryMap))
|
||||
}
|
||||
|
||||
//InsertLocationHandler insert location
|
||||
// @Tags Management
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Summary insert location
|
||||
// @Success 200 {object} utils.GinResponse
|
||||
// @Router /management/location/ [post]
|
||||
// @Param Location body models.BackLocation true "location"
|
||||
// @Param Token header string true "token"
|
||||
func InsertLocationHandler(c *gin.Context) {
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
if claims.Role != global.ROLE_ID_MAP["ADMIN"] {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
locationMap := bindJson(c)
|
||||
ok := management.InsertLocation(claims, locationMap)
|
||||
if ok {
|
||||
@@ -57,7 +186,20 @@ func InsertLocationHandler(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
//DeleteLocationHandler delete location
|
||||
// @Tags Management
|
||||
// @Produce json
|
||||
// @Summary delete location
|
||||
// @Success 200 {object} utils.GinResponse
|
||||
// @Router /management/location/{id} [delete]
|
||||
// @Param Token header string true "token"
|
||||
// @Param Id path int true "Id"
|
||||
func DeleteLocationHandler(c *gin.Context) {
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
if claims.Role != global.ROLE_ID_MAP["ADMIN"] {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
id, _ := strconv.Atoi(c.Param("id"))
|
||||
ok := management.DeleteLocation(id)
|
||||
if ok {
|
||||
@@ -66,3 +208,27 @@ func DeleteLocationHandler(c *gin.Context) {
|
||||
OperationFailed(c)
|
||||
}
|
||||
}
|
||||
|
||||
//InsertPcrHandler insert pcr record
|
||||
// @Tags Management
|
||||
// @Produce json
|
||||
// @Summary insert pcr record
|
||||
// @Success 200 {object} utils.GinResponse
|
||||
// @Router /management/pcr/ [post]
|
||||
// @Param Pcr body models.BackPcr true "Pcr"
|
||||
// @Param Token header string true "token"
|
||||
func InsertPcrHandler(c *gin.Context) {
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
allowRows := []int{global.ROLE_ID_MAP["ADMIN"], global.ROLE_ID_MAP["WORKER"]}
|
||||
if !utils.Contains(allowRows, claims.Role) {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
jsonMap := bindJson(c)
|
||||
ok := management.InsertPcr(claims, jsonMap)
|
||||
if ok {
|
||||
utils.Succ(c, nil)
|
||||
} else {
|
||||
OperationFailed(c)
|
||||
}
|
||||
}
|
||||
|
||||
65
handler/notify.go
Normal file
65
handler/notify.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"nCovTrack-Backend/models"
|
||||
"nCovTrack-Backend/service/notify"
|
||||
"nCovTrack-Backend/utils"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
//InsertNotificationHandler for test
|
||||
func InsertNotificationHandler(c *gin.Context) {
|
||||
sendNotify := models.SendInfo{Region: []string{"江苏 徐州"}, Channel: []int{1, 0}, Notification: models.BackNotification{Time: time.Now(), Kind: "测试", Content: "Test"}}
|
||||
notify.SendNotify(sendNotify)
|
||||
}
|
||||
|
||||
//CountNotificationHandler count the notification
|
||||
// @Tags Notification
|
||||
// @Produce json
|
||||
// @Summary count the notification
|
||||
// @Success 200 {object} utils.GinResponse
|
||||
// @Router /notify/count/ [get]
|
||||
// @Param Token header string true "token"
|
||||
func CountNotificationHandler(c *gin.Context) {
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
count := notify.QueryNotificationLen(claims.Region)
|
||||
utils.Succ(c, map[string]interface{}{"count": count})
|
||||
}
|
||||
|
||||
//ListNotificationHandler list the notifications in the range
|
||||
// @Tags Notification
|
||||
// @Produce json
|
||||
// @Summary list the notification in the range
|
||||
// @Success 200 {object} utils.GinResponse{data=[]models.BackNotification}
|
||||
// @Router /notify/{start}/{end} [get]
|
||||
// @Param Token header string true "token"
|
||||
// @Param start path int true "start"
|
||||
// @Param end path int true "end"
|
||||
func ListNotificationHandler(c *gin.Context) {
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
start, _ := strconv.Atoi(c.Param("start"))
|
||||
end, _ := strconv.Atoi(c.Param("end"))
|
||||
notifications := notify.ListNotifycation(claims.Region, start, end)
|
||||
utils.Succ(c, notifications)
|
||||
}
|
||||
|
||||
//DeleteNotificationHandler delete the notify by index
|
||||
// @Tags Notification
|
||||
// @Produce json
|
||||
// @Summary delete the notify by index, if -1 delete all
|
||||
// @Success 200 {object} utils.GinResponse
|
||||
// @Router /notify/{index} [delete]
|
||||
// @Param Token header string true "token"
|
||||
// @Param index path int true "index"
|
||||
func DeleteNotificationHandler(c *gin.Context) {
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
index, _ := strconv.Atoi(c.Param("index"))
|
||||
if index == -1 {
|
||||
notify.CleanNotification(claims.Region)
|
||||
}
|
||||
notify.DeleteNotification(claims.Region, index)
|
||||
utils.Succ(c, nil)
|
||||
}
|
||||
@@ -24,11 +24,13 @@ func UserRegisterHandler(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
registered := user.NoDuplicatePhoneOrEmail(jsonMap["phone"].(string), jsonMap["email"].(string))
|
||||
if registered {
|
||||
if !registered {
|
||||
utils.Success(c, 200, 200, "Registered", nil)
|
||||
return
|
||||
}
|
||||
colMap := models.MapJ2c[models.BackUser](jsonMap, true)
|
||||
user.Register(colMap)
|
||||
utils.Succ(c, nil)
|
||||
}
|
||||
|
||||
//UserApproveHandler admin approve account
|
||||
|
||||
@@ -10,6 +10,8 @@ func Initialize() *gin.Engine {
|
||||
initRedis()
|
||||
initBos()
|
||||
initCron()
|
||||
go initProducer()
|
||||
go initConsumer()
|
||||
g := initRouter()
|
||||
initSwagger()
|
||||
return g
|
||||
|
||||
70
initialize/kafka.go
Normal file
70
initialize/kafka.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"nCovTrack-Backend/global"
|
||||
"nCovTrack-Backend/service/notify"
|
||||
"time"
|
||||
|
||||
"github.com/Shopify/sarama"
|
||||
)
|
||||
|
||||
func initProducer() {
|
||||
config := sarama.NewConfig()
|
||||
config.Producer.RequiredAcks = sarama.WaitForAll
|
||||
config.Producer.Partitioner = sarama.NewRandomPartitioner
|
||||
config.Producer.Return.Successes = true
|
||||
config.Producer.Return.Errors = true
|
||||
producer, err := sarama.NewSyncProducer(global.ServerSettings.Kafka.Servers, config)
|
||||
if err != nil {
|
||||
panic("kafka init failed")
|
||||
}
|
||||
// defer producer.Close()
|
||||
for {
|
||||
select {
|
||||
case value := <-global.KafkaProducerChan:
|
||||
producer.SendMessage(&sarama.ProducerMessage{Topic: global.ServerSettings.Kafka.Topic, Key: nil, Value: sarama.ByteEncoder(value)})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func initConsumer() {
|
||||
config := sarama.NewConfig()
|
||||
config.Consumer.Offsets.CommitInterval = 1 * time.Second
|
||||
client, err := sarama.NewClient(global.ServerSettings.Kafka.Servers, config)
|
||||
if err != nil {
|
||||
panic("kafka init failed")
|
||||
}
|
||||
defer client.Close()
|
||||
offsetManager, err := sarama.NewOffsetManagerFromClient("", client)
|
||||
if err != nil {
|
||||
panic("kafka init failed")
|
||||
}
|
||||
defer offsetManager.Close()
|
||||
partitionOffsetManager, err := offsetManager.ManagePartition(global.ServerSettings.Kafka.Topic, int32(global.ServerSettings.Kafka.Partition))
|
||||
if err != nil {
|
||||
panic("kafka init failed")
|
||||
}
|
||||
defer partitionOffsetManager.Close()
|
||||
offsetNewest, _ := partitionOffsetManager.NextOffset()
|
||||
consumer, err := sarama.NewConsumer(global.ServerSettings.Kafka.Servers, config)
|
||||
if err != nil {
|
||||
panic("kafka init failed")
|
||||
}
|
||||
defer consumer.Close()
|
||||
partitionConsumer, err := consumer.ConsumePartition(global.ServerSettings.Kafka.Topic, int32(global.ServerSettings.Kafka.Partition), offsetNewest)
|
||||
if err != nil {
|
||||
panic("kafka init failed")
|
||||
}
|
||||
defer partitionConsumer.Close()
|
||||
for {
|
||||
select {
|
||||
case msg := <-partitionConsumer.Messages():
|
||||
ConsumeFunc(msg.Value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ConsumeFunc(msg []byte) {
|
||||
notify.HandleKafkaNotify(msg)
|
||||
}
|
||||
9
main.go
9
main.go
@@ -3,11 +3,20 @@ package main
|
||||
import (
|
||||
"nCovTrack-Backend/global"
|
||||
"nCovTrack-Backend/initialize"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// @title nCov Tracker
|
||||
// @version 1.0
|
||||
func main() {
|
||||
signals := make(chan os.Signal)
|
||||
signal.Notify(signals, os.Interrupt, syscall.SIGTERM)
|
||||
go func() {
|
||||
<-signals
|
||||
os.Exit(1)
|
||||
}()
|
||||
gin := initialize.Initialize()
|
||||
gin.Run(global.GetListenOn())
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
// BackArticle article struct
|
||||
type BackArticle struct {
|
||||
ID int `gorm:"primaryKey;column:id" json:"-"` // 文章id
|
||||
ID int `gorm:"primaryKey;column:id" json:"id"` // 文章id
|
||||
CreateTime time.Time `gorm:"column:create_time" json:"createTime"` // 文章新建时间
|
||||
CreateUser int `gorm:"column:create_user" json:"createUser"` // 文章创建者id
|
||||
ModifyTime time.Time `gorm:"column:modify_time" json:"modifyTime"` // 文章最后更新时间
|
||||
@@ -21,7 +21,7 @@ type BackArticle struct {
|
||||
}
|
||||
|
||||
type ListArticle struct {
|
||||
ID int `json:"-"`
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
CreateTime time.Time `json:"createTime"`
|
||||
ModifyTime time.Time `json:"modifyTime"`
|
||||
@@ -34,13 +34,3 @@ type ListArticle struct {
|
||||
func init() {
|
||||
initJcMap[BackArticle]()
|
||||
}
|
||||
|
||||
//func ArticleMapJ2c(jsonMap map[string]interface{}, ignoreNil bool) map[string]interface{} {
|
||||
// colMap := make(map[string]interface{})
|
||||
// for k, v := range jsonMap {
|
||||
// if colKey := colKey != "" && (!ignoreNil && v == nil) {
|
||||
// colMap[colKey] = v
|
||||
// }
|
||||
// }
|
||||
// return colMap
|
||||
//}
|
||||
|
||||
1
models/kafka.go
Normal file
1
models/kafka.go
Normal file
@@ -0,0 +1 @@
|
||||
package models
|
||||
@@ -63,7 +63,7 @@ type BackSituationRecord struct {
|
||||
IsDelete int `gorm:"column:is_delete" json:"isDelete"` // 删除标志
|
||||
}
|
||||
|
||||
type ListObeservation struct {
|
||||
type ListObservation struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"` // 姓名
|
||||
Age int `json:"age"` // 年龄
|
||||
@@ -81,10 +81,31 @@ type ListObeservation struct {
|
||||
CreateTime time.Time `json:"createTime"` // 创建时间
|
||||
ModifyUser int `json:"modifyUser"` // 修改者
|
||||
ModifyTime time.Time `json:"modifyTime"` // 修改时间
|
||||
PcrTime time.Time `json:"pcrTime"` //核酸时间
|
||||
PcrResult int `json:"pcrResult"` //核酸结果
|
||||
RecordTime time.Time `json:"recordTime"` //状态转换时间
|
||||
Record string `json:"record"` //状态转换内容
|
||||
PcrTime time.Time `json:"pcrTime"` // 核酸时间
|
||||
PcrResult int `json:"pcrResult"` // 核酸结果:0-未检测,1-阴性,2-阳性
|
||||
RecordTime time.Time `json:"recordTime"` // 状态转换时间
|
||||
Record string `json:"record"` // 状态转换内容
|
||||
}
|
||||
|
||||
type TreeObservation struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"` // 姓名
|
||||
Age int `json:"age"` // 年龄
|
||||
Sex int `json:"sex"` // 性别
|
||||
Phone string `json:"phone"` // 手机号码
|
||||
Identification string `json:"identification"` // 身份证号
|
||||
ContactPerson int `json:"contactPerson"` // 接触者id
|
||||
Region string `json:"region"` // 受观察者所在区域
|
||||
Address string `json:"address"` // 受观察者所在具体地点
|
||||
HealthSituation int `json:"healthSituation"` // 被观察者的疫情状况:0- 其他,1-患者,2-密接,3-次密接
|
||||
HealthChangeTime time.Time `json:"healthChangeTime"` // 患者健康状况转化时间
|
||||
MeasureSituation int `json:"measureSituation"` // 受观察者被采取措施状况 :0-未采取措施,1-解除风险,2-正在治疗,3-集中隔离,4-居家隔离
|
||||
Trajectory string `json:"trajectory"` // 行程轨迹
|
||||
CreateUser int `json:"createUser"` // 创建者
|
||||
CreateTime time.Time `json:"createTime"` // 创建时间
|
||||
ModifyUser int `json:"modifyUser"` // 修改者
|
||||
ModifyTime time.Time `json:"modifyTime"` // 修改时间
|
||||
Children []*TreeObservation `json:"children"` // 子结点
|
||||
}
|
||||
|
||||
type QueryObservation struct {
|
||||
|
||||
@@ -4,6 +4,12 @@ import "time"
|
||||
|
||||
type BackNotification struct {
|
||||
Time time.Time `json:"time"`
|
||||
Kind int `json:"kind"`
|
||||
Kind string `json:"kind"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type SendInfo struct {
|
||||
Region []string `json:"region"`
|
||||
Channel []int `json:"channel"`
|
||||
Notification BackNotification `json:"notification"`
|
||||
}
|
||||
|
||||
@@ -2,11 +2,13 @@ package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gorm.io/gorm"
|
||||
"nCovTrack-Backend/global"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var colNameReg, _ = regexp.Compile(".*column:(.*);?")
|
||||
@@ -124,7 +126,7 @@ func BeforeBatchSave(colMaps *[]map[string]interface{}, user int) {
|
||||
|
||||
func Upsert[T any](colMap map[string]interface{}) (ok bool, rowsAffected int64) {
|
||||
var tx *gorm.DB
|
||||
if colMap["id"] == nil || int(colMap["id"].(float64)) == 0 {
|
||||
if colMap["id"] == nil || getMapId(colMap["id"]) == 0 {
|
||||
tx = global.Db.Model(new(T)).Create(colMap)
|
||||
} else {
|
||||
tx = global.Db.Model(new(T)).Where("id = ?", colMap["id"]).Updates(colMap)
|
||||
@@ -169,7 +171,7 @@ func DeleteById[T any](id int) (ok bool, rowsAffected int64) {
|
||||
if tx.Error != nil {
|
||||
return false, 0
|
||||
}
|
||||
return true, rowsAffected
|
||||
return true, tx.RowsAffected
|
||||
}
|
||||
|
||||
func DropById[T any](id int) {
|
||||
@@ -253,3 +255,17 @@ func CountByOrm(tx *gorm.DB) int64 {
|
||||
tx.Count(&count)
|
||||
return count
|
||||
}
|
||||
|
||||
func getMapId(id interface{}) int {
|
||||
switch id.(type) {
|
||||
case int:
|
||||
return id.(int)
|
||||
case string:
|
||||
id, _ := strconv.Atoi(id.(string))
|
||||
return id
|
||||
case float64:
|
||||
return int(id.(float64))
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,18 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func managementPublicRouter(router *gin.RouterGroup) {
|
||||
func managementPrivateRouter(router *gin.RouterGroup) {
|
||||
managementRouter := router.Group("/management")
|
||||
{
|
||||
managementRouter.GET("/observation/contact/pull/:patientId", handler.PullContactHandler)
|
||||
managementRouter.GET("/faker/:patientId", handler.PullContactHandler)
|
||||
managementRouter.GET("/observation", handler.ListObservationsHandler)
|
||||
managementRouter.POST("/observation", handler.InsertObservationHandler)
|
||||
managementRouter.GET("/observation/:id", handler.GetObservationHandler)
|
||||
managementRouter.GET("/observation/tree/:id/:direction", handler.TreeifyObservationHandler)
|
||||
managementRouter.PUT("/observation", handler.UpdateObservationHandler)
|
||||
managementRouter.POST("/location/", handler.InsertLocationHandler)
|
||||
managementRouter.GET("/location/", handler.ListLocationHandler)
|
||||
managementRouter.DELETE("/location/", handler.DeleteLocationHandler)
|
||||
managementRouter.POST("/pcr/", handler.InsertPcrHandler)
|
||||
}
|
||||
}
|
||||
|
||||
17
router/notify.go
Normal file
17
router/notify.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"nCovTrack-Backend/handler"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func notifyPrivateRouter(router *gin.RouterGroup) {
|
||||
notifyRouter := router.Group("/notify")
|
||||
{
|
||||
notifyRouter.GET("/count", handler.CountNotificationHandler)
|
||||
notifyRouter.POST("/", handler.InsertNotificationHandler)
|
||||
notifyRouter.GET("/:start/:end", handler.ListNotificationHandler)
|
||||
notifyRouter.DELETE("/:index", handler.DeleteNotificationHandler)
|
||||
}
|
||||
}
|
||||
@@ -15,12 +15,13 @@ func BusiRouter() {
|
||||
statisticRouter(publicRouter)
|
||||
articlePublicRouter(publicRouter)
|
||||
userPublicRouter(publicRouter)
|
||||
managementPublicRouter(publicRouter)
|
||||
}
|
||||
|
||||
// Private
|
||||
{
|
||||
articlePrivateRouter(privateRouter)
|
||||
userPrivateRouter(privateRouter)
|
||||
notifyPrivateRouter(privateRouter)
|
||||
managementPrivateRouter(privateRouter)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,8 +39,8 @@ func listArticles(isPublish int, createUser int) *[]models.ListArticle {
|
||||
}
|
||||
|
||||
//SaveArticle save the articles
|
||||
func SaveArticle(article map[string]interface{}) (ok bool) {
|
||||
models.BeforeSave(article, -1)
|
||||
func SaveArticle(claims models.TokenClaims, article map[string]interface{}) (ok bool) {
|
||||
models.BeforeSave(article, claims.ID)
|
||||
ok, rows := models.Upsert[models.BackArticle](article)
|
||||
return ok && rows != 0
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
//fakerGetRequest Get data from faker
|
||||
func fakerGetRequest(uri string) string {
|
||||
resStr := utils.GetWhioutHeader(global.FACKER_HOST + uri)
|
||||
var res utils.GinResponse
|
||||
@@ -18,6 +19,7 @@ func fakerGetRequest(uri string) string {
|
||||
return string(dataStr)
|
||||
}
|
||||
|
||||
//queryHotelContacts Hotel contacts
|
||||
func queryHotelContacts(identification string) []models.HotelContactRequest {
|
||||
dataStr := fakerGetRequest("query/contacts/hotel/" + identification)
|
||||
var data []models.HotelContactRequest
|
||||
@@ -28,6 +30,7 @@ func queryHotelContacts(identification string) []models.HotelContactRequest {
|
||||
return data
|
||||
}
|
||||
|
||||
//queryRailwayContacts Railway contacts
|
||||
func queryRailwayContacts(identification string) []models.RailwayContactRequest {
|
||||
dataStr := fakerGetRequest("query/contacts/railway/" + identification)
|
||||
var data []models.RailwayContactRequest
|
||||
@@ -38,7 +41,8 @@ func queryRailwayContacts(identification string) []models.RailwayContactRequest
|
||||
return data
|
||||
}
|
||||
|
||||
func queryPatients(identification string) []models.PatientRequest {
|
||||
//queryPatients Patients
|
||||
func QueryPatients(identification string) []models.PatientRequest {
|
||||
dataStr := fakerGetRequest("query/contacts/railway/" + identification)
|
||||
var data []models.PatientRequest
|
||||
err := json.Unmarshal([]byte(dataStr), &data)
|
||||
@@ -48,6 +52,7 @@ func queryPatients(identification string) []models.PatientRequest {
|
||||
return data
|
||||
}
|
||||
|
||||
//queryContacts Resolve the diffrent of hotel and railway request
|
||||
func queryContacts(identification string) []models.BackObservation {
|
||||
hotelContacts := queryHotelContacts(identification)
|
||||
railwayContacts := queryRailwayContacts(identification)
|
||||
@@ -55,11 +60,13 @@ func queryContacts(identification string) []models.BackObservation {
|
||||
return observations
|
||||
}
|
||||
|
||||
//splitFakerAddress Extract the region
|
||||
func splitFakerAddress(fakerAddress string) string {
|
||||
addresses := strings.Split(fakerAddress, " ")
|
||||
return addresses[1] + " " + addresses[2]
|
||||
}
|
||||
|
||||
//fakerContacts2Observations Convvert structs
|
||||
func fakerContacts2Observations(contacts any) []models.BackObservation {
|
||||
var observations []models.BackObservation
|
||||
switch contacts.(type) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"nCovTrack-Backend/models"
|
||||
)
|
||||
|
||||
//InsertLocation Insert locations
|
||||
func InsertLocation(claims models.TokenClaims, locationJMap map[string]interface{}) bool {
|
||||
locationCMap := models.MapJ2c[models.BackLocation](locationJMap, true)
|
||||
models.BeforeSave(locationCMap, claims.ID)
|
||||
@@ -11,11 +12,13 @@ func InsertLocation(claims models.TokenClaims, locationJMap map[string]interface
|
||||
return (ok && rowsAffected != 0)
|
||||
}
|
||||
|
||||
//ListLocation List locations
|
||||
func ListLocation(queryJMap map[string]any) *[]map[string]any {
|
||||
queryCMap := models.MapJ2c[models.BackLocation](queryJMap, true)
|
||||
return models.ListField[models.BackLocation]([]map[string]any{queryCMap}, true, "is_delete")
|
||||
}
|
||||
|
||||
//DeleteLocation Delete locations
|
||||
func DeleteLocation(id int) bool {
|
||||
ok, rowsAffected := models.DeleteById[models.BackLocation](id)
|
||||
return (ok && rowsAffected != 0)
|
||||
|
||||
@@ -4,10 +4,12 @@ import (
|
||||
"fmt"
|
||||
"nCovTrack-Backend/global"
|
||||
"nCovTrack-Backend/models"
|
||||
"nCovTrack-Backend/service/notify"
|
||||
"nCovTrack-Backend/utils"
|
||||
"time"
|
||||
)
|
||||
|
||||
//PullFromFaker Pull observations from faker system
|
||||
func PullFromFaker(claims models.TokenClaims, patientId int) int64 {
|
||||
// Get patient's identification by id
|
||||
queryMap := []map[string]interface{}{{"id": patientId}}
|
||||
@@ -28,31 +30,39 @@ func PullFromFaker(claims models.TokenClaims, patientId int) int64 {
|
||||
observationsCMap := models.MapsJ2c[models.BackObservation](observationsJMap, false)
|
||||
models.BeforeBatchSave(&observationsCMap, claims.ID)
|
||||
_, rowsAffected := models.BatchInsert[models.BackObservation](observationsCMap)
|
||||
// Generate situation record
|
||||
// Generate situation record and send notify to the region
|
||||
if rowsAffected != 0 {
|
||||
pullSituationRecord(claims, observations)
|
||||
pullNotify(observations)
|
||||
}
|
||||
return rowsAffected
|
||||
}
|
||||
|
||||
func ListObservation(jsonMap map[string]interface{}) []models.ListObeservation {
|
||||
//ListObservation list observations with query
|
||||
func ListObservation(jsonMap map[string]interface{}) []models.ListObservation {
|
||||
colMap := models.MapJ2c[models.BackObservation](jsonMap, true)
|
||||
queryMap := []map[string]interface{}{colMap}
|
||||
return listObservation(queryMap)
|
||||
}
|
||||
|
||||
//GetObservation get observation by id
|
||||
func GetObservation(id int) map[string]interface{} {
|
||||
// Obseration
|
||||
observationCMap := models.GetField[models.BackObservation]([]map[string]interface{}{{"id": id}}, true, "is_delete")
|
||||
observationJMap := models.MapC2j[models.BackObservation](observationCMap, true)
|
||||
// Pcr record
|
||||
pcrRecordCMap := models.ListField[models.BackPcr]([]map[string]interface{}{{"observation": id}}, true, "is_delete")
|
||||
pcrRecordJMap := models.MapsC2j[models.BackPcr](*pcrRecordCMap, true)
|
||||
// Situation record
|
||||
situationRecordCMap := models.ListField[models.BackSituationRecord]([]map[string]interface{}{{"observation": id}}, true, "is_delete")
|
||||
situationRecordJMap := models.MapsC2j[models.BackSituationRecord](*situationRecordCMap, true)
|
||||
// Assemble
|
||||
observationJMap["pcrRecord"] = pcrRecordJMap
|
||||
observationJMap["situationRecord"] = situationRecordJMap
|
||||
return observationJMap
|
||||
}
|
||||
|
||||
//InsertObservation add observation
|
||||
func InsertObservation(claims models.TokenClaims, jsonMap map[string]interface{}) bool {
|
||||
colMap := models.MapJ2c[models.BackObservation](jsonMap, true)
|
||||
models.BeforeSave(colMap, claims.ID)
|
||||
@@ -65,17 +75,103 @@ func InsertObservation(claims models.TokenClaims, jsonMap map[string]interface{}
|
||||
}
|
||||
|
||||
func UpdateObservation(claims models.TokenClaims, jsonMap map[string]any) bool {
|
||||
// Pre actions
|
||||
colMap := models.MapJ2c[models.BackObservation](jsonMap, true)
|
||||
models.BeforeSave(colMap, claims.ID)
|
||||
oldMap := models.Get[models.BackObservation]([]map[string]interface{}{{"id": jsonMap["id"]}})
|
||||
insertSituationRecord(claims, oldMap, colMap)
|
||||
queryMap := []map[string]interface{}{{"id": jsonMap["id"]}}
|
||||
// Get old record
|
||||
oldMap := models.Get[models.BackObservation](queryMap)
|
||||
if oldMap == nil || len(oldMap) == 0 {
|
||||
return false
|
||||
}
|
||||
// Deal with region update
|
||||
if colMap["region"] != nil && oldMap["region"].(string) != colMap["region"].(string) {
|
||||
updateObservationRegion(colMap["region"].(string))
|
||||
}
|
||||
// Deal with situation update
|
||||
if colMap["health_situation"] != nil && int(colMap["health_situation"].(float64)) != oldMap["health_situation"].(int) ||
|
||||
colMap["measure_situation"] != nil && int(colMap["measure_situation"].(float64)) != oldMap["measure_situation"].(int) {
|
||||
updateSituation(claims, oldMap, colMap)
|
||||
}
|
||||
ok, rowsAffected := models.Update[models.BackObservation](queryMap, colMap)
|
||||
return ok && rowsAffected != 0
|
||||
}
|
||||
|
||||
// listObservation the queryMap need with table name
|
||||
// @Param queryMap the colMap of models.BackObservation
|
||||
func listObservation(queryMap []map[string]interface{}) []models.ListObeservation {
|
||||
var observations []models.ListObeservation
|
||||
//TreeifyObservations get the transmission chains of observations
|
||||
// Param direction: up, down, all
|
||||
func TreeifyObservations(observationId int, direction string) *models.TreeObservation {
|
||||
// Get arrays form back observation
|
||||
var observations []models.BackObservation
|
||||
if direction != "down" {
|
||||
observations = append(observations, treeifyObservations(observationId, true)...)
|
||||
}
|
||||
if direction != "up" {
|
||||
observations = append(observations, treeifyObservations(observationId, false)...)
|
||||
}
|
||||
// Treeify
|
||||
observationMap := map[int]*models.TreeObservation{}
|
||||
for _, observation := range observations {
|
||||
observationMap[observation.ID] = &models.TreeObservation{
|
||||
ID: observation.ID,
|
||||
Name: observation.Name,
|
||||
Age: observation.Age,
|
||||
Sex: observation.Sex,
|
||||
Phone: observation.Phone,
|
||||
Identification: observation.Identification,
|
||||
ContactPerson: observation.ContactPerson,
|
||||
Region: observation.Region,
|
||||
Address: observation.Address,
|
||||
HealthSituation: observation.HealthSituation,
|
||||
HealthChangeTime: observation.HealthChangeTime,
|
||||
CreateUser: observation.CreateUser,
|
||||
CreateTime: observation.CreateTime,
|
||||
ModifyUser: observation.ModifyUser,
|
||||
ModifyTime: observation.ModifyTime,
|
||||
}
|
||||
}
|
||||
var rootKey int
|
||||
for k := range observationMap {
|
||||
parentId := observationMap[k].ContactPerson
|
||||
parent := observationMap[parentId]
|
||||
if parent == nil {
|
||||
rootKey = k
|
||||
continue
|
||||
}
|
||||
parent.Children = append(parent.Children, observationMap[k])
|
||||
}
|
||||
return observationMap[rootKey]
|
||||
}
|
||||
|
||||
//treeifyObservations query tree data from db
|
||||
// Param direction up: true, down: false
|
||||
func treeifyObservations(observationId int, direction bool) []models.BackObservation {
|
||||
var res []models.BackObservation
|
||||
var directionCond string
|
||||
if direction {
|
||||
directionCond = "p.id = cte.contact_person"
|
||||
} else {
|
||||
directionCond = "cte.id = p.contact_person"
|
||||
}
|
||||
querySql := fmt.Sprintf(`
|
||||
WITH RECURSIVE cte (id, name, age, sex, phone, identification, contact_person, region, address, health_situation, health_change_time, trajectory, create_user, modify_user, create_time, modify_time) AS (
|
||||
SELECT id, name, age, sex, phone, identification, contact_person, region, address, health_situation, health_change_time, trajectory, create_user, modify_user, create_time, modify_time
|
||||
FROM back_observation
|
||||
WHERE contact_person = ?
|
||||
UNION ALL
|
||||
SELECT p.id, p.name, p.age, p.sex, p.phone, p.identification, p.contact_person, p.region, p.address, p.health_situation, p.health_change_time, p.trajectory, p.create_user, p.modify_user, p.create_time, p.modify_time
|
||||
FROM back_observation p
|
||||
INNER JOIN cte ON %s
|
||||
)
|
||||
SELECT * FROM cte
|
||||
`, directionCond)
|
||||
global.Db.Model(models.BackObservation{}).Raw(querySql, observationId).Scan(&res)
|
||||
return res
|
||||
}
|
||||
|
||||
//listObservation the queryMap need with table name
|
||||
// Param queryMap the colMap of models.BackObservation
|
||||
func listObservation(queryMap []map[string]interface{}) []models.ListObservation {
|
||||
var observations []models.ListObservation
|
||||
tx := global.Db.Model(new((models.BackObservation))).
|
||||
Select("back_observation.*, back_pcr.detect_time AS pcr_time, detect_result AS pcr_result," +
|
||||
"back_situation_record.create_time AS record_time, back_situation_record.record AS record").
|
||||
@@ -94,6 +190,7 @@ func listObservation(queryMap []map[string]interface{}) []models.ListObeservatio
|
||||
return observations
|
||||
}
|
||||
|
||||
//pullSituationRecord push situation record after pull observations
|
||||
func pullSituationRecord(claims models.TokenClaims, observations []models.BackObservation) {
|
||||
// Query observations' id
|
||||
var identifications []string
|
||||
@@ -104,7 +201,7 @@ func pullSituationRecord(claims models.TokenClaims, observations []models.BackOb
|
||||
observationMaps := models.ListField[models.BackObservation](queryMap, false, "id", "identification")
|
||||
// Assemble records
|
||||
var records []models.BackSituationRecord
|
||||
recordContent := record00_20()
|
||||
recordContent := record___20()
|
||||
for _, observationMap := range *observationMaps {
|
||||
record := models.BackSituationRecord{Observation: observationMap["id"].(int), Record: recordContent}
|
||||
records = append(records, record)
|
||||
@@ -115,20 +212,87 @@ func pullSituationRecord(claims models.TokenClaims, observations []models.BackOb
|
||||
recordsCMaps := models.MapsJ2c[models.BackSituationRecord](recordsJMaps, true)
|
||||
models.BeforeBatchSave(&recordsCMaps, claims.ID)
|
||||
models.BatchInsert[models.BackSituationRecord](recordsCMaps)
|
||||
// Notify the admin of pull region
|
||||
// Send email to the region admin
|
||||
}
|
||||
|
||||
//pullNotify send notify after pull observations
|
||||
func pullNotify(observations []models.BackObservation) {
|
||||
var regions []string
|
||||
for _, observation := range observations {
|
||||
regions = append(regions, observation.Region)
|
||||
}
|
||||
regions = utils.Distinct(regions)
|
||||
notification := models.BackNotification{Time: time.Now(), Kind: "疫情", Content: "出现了新的接触者,请及时登录系统进行处理"}
|
||||
sendInfo := models.SendInfo{Region: regions, Channel: []int{0, 1}, Notification: notification}
|
||||
notify.SendNotify(sendInfo)
|
||||
}
|
||||
|
||||
//updateObservationRegion send notify while update observation's region
|
||||
func updateObservationRegion(region string) {
|
||||
// Add to notify
|
||||
// Send email to the target region amdin
|
||||
notification := models.BackNotification{Time: time.Now(), Kind: "疫情", Content: "本地有新的接触者,请及时登录系统进行处理"}
|
||||
sendInfo := models.SendInfo{Region: []string{region}, Channel: []int{0, 1}, Notification: notification}
|
||||
notify.SendNotify(sendInfo)
|
||||
}
|
||||
|
||||
func updateWhileDiagnosis(claims models.TokenClaims, patientId int) {
|
||||
// Update sub contact to contact and nomeasure
|
||||
// Add to notify
|
||||
//updateSituation make some special resolve while situation update
|
||||
func updateSituation(claims models.TokenClaims, oldObservationMap, newObservationMap map[string]interface{}) {
|
||||
if newObservationMap["health_situation"] != nil {
|
||||
newHealthSituation := int(newObservationMap["health_situation"].(float64))
|
||||
oldHealthSituation := oldObservationMap["health_situation"].(int)
|
||||
// Update health situation change time and measure_situation
|
||||
if newHealthSituation != oldHealthSituation {
|
||||
newObservationMap["health_change_time"] = time.Now()
|
||||
newObservationMap["measure_situation"] = 0
|
||||
}
|
||||
// Deal with contact to patient
|
||||
if oldHealthSituation == 2 && newHealthSituation == 1 {
|
||||
// Query sub contacts
|
||||
queryMap := []map[string]interface{}{{"contact_person": oldObservationMap["id"].(int)}}
|
||||
subContacts := models.ListField[models.BackObservation](queryMap, false, "id", "region")
|
||||
// Get reginos and assemble situation record
|
||||
var regions []string
|
||||
var subContactRecords []models.BackSituationRecord
|
||||
for _, subContact := range *subContacts {
|
||||
regions = append(regions, subContact["region"].(string))
|
||||
subContactRecord := models.BackSituationRecord{
|
||||
Observation: int(newObservationMap["id"].(float64)),
|
||||
Record: record___20(),
|
||||
}
|
||||
subContactRecords = append(subContactRecords, subContactRecord)
|
||||
}
|
||||
// Update sub contact
|
||||
updateMap := map[string]interface{}{
|
||||
"health_situation": 2,
|
||||
"health_change_time": newObservationMap["health_change_time"],
|
||||
"measure_situation": 0,
|
||||
}
|
||||
models.Update[models.BackObservation](queryMap, updateMap)
|
||||
|
||||
// Insert subContacts' record
|
||||
var recordJMaps []map[string]interface{}
|
||||
utils.Strcut2Map(subContactRecords, &recordJMaps)
|
||||
recordCMap := models.MapsJ2c[models.BackSituationRecord](recordJMaps, true)
|
||||
models.BeforeBatchSave(&recordCMap, claims.ID)
|
||||
models.BatchInsert[models.BackSituationRecord](recordCMap)
|
||||
|
||||
// Send nofity
|
||||
regions = utils.Distinct(regions)
|
||||
notification := models.BackNotification{
|
||||
Time: newObservationMap["health_change_time"].(time.Time),
|
||||
Kind: "疫情",
|
||||
Content: "由于密接者转为患者,次密接者状态需要修改",
|
||||
}
|
||||
sendInfo := models.SendInfo{
|
||||
Region: regions,
|
||||
Channel: []int{0, 1},
|
||||
Notification: notification,
|
||||
}
|
||||
notify.SendNotify(sendInfo)
|
||||
}
|
||||
insertSituationRecord(claims, oldObservationMap, newObservationMap)
|
||||
}
|
||||
}
|
||||
|
||||
//insertSituationRecord insert situation record
|
||||
func insertSituationRecord(claims models.TokenClaims, oldObservation, newObservation map[string]interface{}) bool {
|
||||
var oldSituation, newSituation string
|
||||
if oldObservation["id"] == nil {
|
||||
@@ -154,20 +318,22 @@ func insertSituationRecord(claims models.TokenClaims, oldObservation, newObserva
|
||||
switch situationConvert {
|
||||
case "00_10":
|
||||
recordContent = record00_10()
|
||||
case "00_20":
|
||||
recordContent = record00_20()
|
||||
case "00_30":
|
||||
recordContent = record00_30()
|
||||
case "00_12":
|
||||
recordContent = record00_12(newObservation["region"].(string), newObservation["address"].(string))
|
||||
case "10_12":
|
||||
recordContent = record10_12(newObservation["region"].(string), newObservation["address"].(string))
|
||||
case "00_20", "33_20", "34_20":
|
||||
recordContent = record___20()
|
||||
case "12_01", "23_01", "24_01", "33_01", "34_01":
|
||||
recordContent = record___01()
|
||||
case "20_23", "30_33", "24_23", "34_33":
|
||||
recordContent = record____3(newObservation["region"].(string), newObservation["address"].(string))
|
||||
case "20_24", "30_34", "23_24", "33_34":
|
||||
recordContent = record____4(newObservation["region"].(string), newObservation["address"].(string))
|
||||
case "23_10", "24_10", "33_10", "34_10":
|
||||
recordContent = record___10()
|
||||
default:
|
||||
if oldSituation != "00" {
|
||||
models.Upsert[models.BackObservation](oldObservation)
|
||||
@@ -193,7 +359,7 @@ func record00_12(region, address string) string {
|
||||
date := utils.FormatDate(time.Now())
|
||||
return fmt.Sprintf("%s 于 %s %s 确诊为患者", date, region, address)
|
||||
}
|
||||
func record00_20() string {
|
||||
func record___20() string {
|
||||
date := utils.FormatDate(time.Now())
|
||||
return date + " 转为密接"
|
||||
}
|
||||
|
||||
10
service/management/pcr.go
Normal file
10
service/management/pcr.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package management
|
||||
|
||||
import "nCovTrack-Backend/models"
|
||||
|
||||
func InsertPcr(claims models.TokenClaims, jsonMap map[string]interface{}) bool {
|
||||
colMap := models.MapJ2c[models.BackPcr](jsonMap, true)
|
||||
models.BeforeSave(colMap, claims.ID)
|
||||
ok, rowsAffected := models.Upsert[models.BackPcr](colMap)
|
||||
return ok && rowsAffected != 0
|
||||
}
|
||||
@@ -4,35 +4,65 @@ import (
|
||||
"encoding/json"
|
||||
"nCovTrack-Backend/global"
|
||||
"nCovTrack-Backend/models"
|
||||
"strconv"
|
||||
"nCovTrack-Backend/utils"
|
||||
)
|
||||
|
||||
type NotifyFunc func([]string, models.BackNotification)
|
||||
|
||||
const (
|
||||
NOTIFY_KEY = "notification_"
|
||||
NOTIFY_DEL_VALUE = "notify_del"
|
||||
)
|
||||
|
||||
func InsertNotification(userId int, notification models.BackNotification) {
|
||||
key := NOTIFY_KEY + strconv.Itoa(userId)
|
||||
valueStr, _ := json.Marshal(notification)
|
||||
global.Redis.RPush(key, valueStr)
|
||||
var (
|
||||
NOTIFY_CHANNEL_FUNC_ARR = []NotifyFunc{notifyNotification, emailNotification}
|
||||
)
|
||||
|
||||
//emailNotification send email
|
||||
func emailNotification(regions []string, notification models.BackNotification) {
|
||||
queryMap := []map[string]interface{}{{"region": regions, "role": global.ROLE_ID_MAP["ADMIN"]}}
|
||||
observations := models.ListField[models.BackUser](queryMap, false, "email")
|
||||
var emails []string
|
||||
for _, observation := range *observations {
|
||||
emails = append(emails, observation["email"].(string))
|
||||
}
|
||||
utils.SendEmail(notification.Kind+"通知邮件", notification.Content, emails...)
|
||||
}
|
||||
|
||||
func DeleteNotification(userId int, index int) {
|
||||
key := NOTIFY_KEY + strconv.Itoa(userId)
|
||||
//notifyNotification add to notify system
|
||||
func notifyNotification(regions []string, notification models.BackNotification) {
|
||||
valueByte, _ := json.Marshal(notification)
|
||||
pipe := global.Redis.TxPipeline()
|
||||
for _, region := range regions {
|
||||
pipe.RPush(NOTIFY_KEY+region, valueByte)
|
||||
}
|
||||
pipe.Exec()
|
||||
}
|
||||
|
||||
//DeleteNotification delete notify by id
|
||||
func DeleteNotification(region string, index int) {
|
||||
key := NOTIFY_KEY + region
|
||||
pipe := global.Redis.TxPipeline()
|
||||
pipe.LSet(key, int64(index), NOTIFY_DEL_VALUE)
|
||||
pipe.LRem(key, 2, NOTIFY_DEL_VALUE)
|
||||
pipe.Exec()
|
||||
}
|
||||
|
||||
func QueryNotificationLen(userId int) int {
|
||||
key := NOTIFY_KEY + strconv.Itoa(userId)
|
||||
//CleanNotification delete all notify
|
||||
func CleanNotification(region string) {
|
||||
key := NOTIFY_KEY + region
|
||||
global.Redis.Del(key)
|
||||
}
|
||||
|
||||
//QueryNotificationLen query the count notification
|
||||
func QueryNotificationLen(region string) int {
|
||||
key := NOTIFY_KEY + region
|
||||
return int(global.Redis.LLen(key).Val())
|
||||
}
|
||||
|
||||
func ListNotifycation(userId int, start, end int) []models.BackNotification {
|
||||
key := NOTIFY_KEY + strconv.Itoa(userId)
|
||||
//ListNotifycation list the notifications ny range
|
||||
func ListNotifycation(region string, start, end int) []models.BackNotification {
|
||||
key := NOTIFY_KEY + region
|
||||
var notifications []models.BackNotification
|
||||
notificationStrArr := global.Redis.LRange(key, int64(start), int64(end)).Val()
|
||||
for _, notificationStr := range notificationStrArr {
|
||||
@@ -42,3 +72,18 @@ func ListNotifycation(userId int, start, end int) []models.BackNotification {
|
||||
}
|
||||
return notifications
|
||||
}
|
||||
|
||||
//SendNotify send notify to kafka
|
||||
func SendNotify(send models.SendInfo) {
|
||||
sendInfo, _ := json.Marshal(send)
|
||||
global.KafkaProducerChan <- sendInfo
|
||||
}
|
||||
|
||||
//HandleKafkaNotify handle kafka info
|
||||
func HandleKafkaNotify(sendInfoByte []byte) {
|
||||
var sendInfo models.SendInfo
|
||||
json.Unmarshal(sendInfoByte, &sendInfo)
|
||||
for _, channel := range sendInfo.Channel {
|
||||
NOTIFY_CHANNEL_FUNC_ARR[channel](sendInfo.Region, sendInfo.Notification)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,15 @@ package user
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/google/uuid"
|
||||
"nCovTrack-Backend/global"
|
||||
"nCovTrack-Backend/models"
|
||||
"nCovTrack-Backend/service/notify"
|
||||
"nCovTrack-Backend/utils"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -50,6 +52,15 @@ func Register(user map[string]interface{}) bool {
|
||||
user["approver"] = 0
|
||||
colMap := models.MapJ2c[models.BackUser](user, false)
|
||||
ok, rowsAffected := models.Upsert[models.BackUser](colMap)
|
||||
var sendRegion string
|
||||
if int(user["role"].(float64)) == global.ROLE_ID_MAP["ADMIN"] {
|
||||
sendRegion = strings.Split(user["region"].(string), " ")[0]
|
||||
} else {
|
||||
sendRegion = user["region"].(string)
|
||||
}
|
||||
notification := models.BackNotification{Time: time.Now(), Kind: "审批", Content: "有新的注册待审批"}
|
||||
sendInfo := models.SendInfo{Region: []string{sendRegion}, Channel: []int{0}, Notification: notification}
|
||||
notify.SendNotify(sendInfo)
|
||||
if !ok || rowsAffected == 0 {
|
||||
return false
|
||||
}
|
||||
@@ -95,7 +106,7 @@ func ApproveRegister(claims models.TokenClaims, email string, pass bool) bool {
|
||||
} else {
|
||||
approver = -claims.ID
|
||||
}
|
||||
updateMap := map[string]interface{}{"approver": approver}
|
||||
updateMap := map[string]interface{}{"approver": approver, "modify_time": time.Now()}
|
||||
ok, rowsAffected := models.Update[models.BackUser](queryMap, updateMap)
|
||||
if !ok || rowsAffected == 0 {
|
||||
return false
|
||||
@@ -111,11 +122,12 @@ func ChangePassword(changePwd map[string]interface{}) bool {
|
||||
}
|
||||
newPassword := utils.PasswordEncrypt(changePwd["newPassword"].(string))
|
||||
colMap := map[string]interface{}{
|
||||
"id": 1,
|
||||
"id": 1.0,
|
||||
"password": newPassword,
|
||||
}
|
||||
models.BeforeSave(colMap, -1)
|
||||
delete(colMap, "id")
|
||||
delete(colMap, "modify_user")
|
||||
rowAffected := global.Db.Model(models.BackUser{}).Where("email = ?", changePwd["email"]).Updates(colMap).RowsAffected
|
||||
if rowAffected == 0 {
|
||||
return false
|
||||
|
||||
@@ -32,3 +32,9 @@ bos:
|
||||
accessKey: 90dbff87c5aa4bdbb0d7a29e130b2808
|
||||
secretKey: e53a672a10294abc8ecabe1ef92625b1
|
||||
domain: bj.bcebos.com
|
||||
|
||||
kafka:
|
||||
servers:
|
||||
- myhost.fallen-angle.com:9092
|
||||
topic: ncov_track
|
||||
partition: 0
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
)
|
||||
|
||||
func SendEmail(subject string, text string, to ...string) bool {
|
||||
//TODO: add logs
|
||||
e := email.Email{
|
||||
From: "nCovTrack Server<1853633282@qq.com>",
|
||||
To: to,
|
||||
@@ -20,6 +19,7 @@ func SendEmail(subject string, text string, to ...string) bool {
|
||||
smtp.PlainAuth("", global.ServerSettings.Email.Account, global.ServerSettings.Email.Password, global.ServerSettings.Email.Host),
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println("Send failed")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
||||
@@ -31,7 +31,11 @@ func GetWithHeader(url string, header map[string]string) string {
|
||||
cost := time.Since(startTime)
|
||||
var logParams []interface{}
|
||||
logParams = append(logParams,
|
||||
"reqest", req,
|
||||
"reqest", map[string]interface{}{
|
||||
"url": req.URL,
|
||||
"method": req.Method,
|
||||
"header": req.Header,
|
||||
},
|
||||
"cost", cost.String(),
|
||||
)
|
||||
if err != nil {
|
||||
|
||||
@@ -15,3 +15,24 @@ func Map[T any, V any](arr []T, fun func(item T) V) []V {
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func Distinct[T comparable](arr []T) []T {
|
||||
set := map[T]interface{}{}
|
||||
for _, item := range arr {
|
||||
set[item] = nil
|
||||
}
|
||||
var res []T
|
||||
for k := range set {
|
||||
res = append(res, k)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func Contains[T comparable](arr []T, item T) bool {
|
||||
for _, a := range arr {
|
||||
if a == item {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
40
utils/set.go
40
utils/set.go
@@ -1,40 +0,0 @@
|
||||
package utils
|
||||
|
||||
type void struct{}
|
||||
|
||||
// This is set with generic
|
||||
|
||||
type Set[T comparable] struct {
|
||||
setMap map[T]void
|
||||
}
|
||||
|
||||
func NewSet[T comparable](eles ...T) *Set[T] {
|
||||
set := &Set[T]{setMap: make(map[T]void)}
|
||||
set.AddAll(eles...)
|
||||
return set
|
||||
}
|
||||
|
||||
func (set *Set[T]) Add(ele T) *Set[T] {
|
||||
set.setMap[ele] = void{}
|
||||
return set
|
||||
}
|
||||
|
||||
func (set *Set[T]) AddAll(eles ...T) *Set[T] {
|
||||
for _, ele := range eles {
|
||||
set.Add(ele)
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
func (set *Set[T]) Delete(ele T) *Set[T] {
|
||||
delete(set.setMap, ele)
|
||||
return set
|
||||
}
|
||||
|
||||
func (set *Set[T]) ToSlice() []T {
|
||||
var s []T
|
||||
for k, _ := range set.setMap {
|
||||
s = append(s, k)
|
||||
}
|
||||
return s
|
||||
}
|
||||
Reference in New Issue
Block a user