forked from free-lancers/electricity_bill_calc_service
Compare commits
161 Commits
0.1.19
...
12ec8d26bf
| Author | SHA1 | Date | |
|---|---|---|---|
| 12ec8d26bf | |||
| e67b9afa68 | |||
| 201af1cc25 | |||
| 183092b670 | |||
| 8caf069b8a | |||
| 11cc6f0de1 | |||
| 00e2664007 | |||
| 746a9bcaa9 | |||
| 7a8e8014ad | |||
| c028056458 | |||
| 5c1b26c77f | |||
| 122bc228bf | |||
| ba9c87d2b1 | |||
| e13193de6d | |||
| 4b08952916 | |||
| df9bf83bb8 | |||
| 0169419707 | |||
| 2ba64227d0 | |||
| c56e1128ff | |||
| 7e861ba4e6 | |||
| 712d704004 | |||
| 502a8bbcee | |||
| c306a749aa | |||
| 1385f0bbcb | |||
| 0e7333b104 | |||
| de6e24dcd3 | |||
| f3457c9ab2 | |||
| 022788bb44 | |||
| f4ee7cf8a4 | |||
| f8f8a0ced1 | |||
| 38ec847f55 | |||
| d47a052d39 | |||
| 9f68d3adea | |||
| c716de21aa | |||
| fa61f83c6a | |||
| f66782c87b | |||
| 875b013c2b | |||
| 8ec217534e | |||
| 2c182496fa | |||
| c7569fbc2c | |||
| 6740ab3f48 | |||
| aa3a4dc44e | |||
| d7f3e0f096 | |||
| efc0a605b7 | |||
| b5c2455af7 | |||
| a13193cfa4 | |||
| 794054b831 | |||
| aa5c43e51a | |||
| 8a070d4396 | |||
| 4620271fa5 | |||
| 7f585c0452 | |||
| d98e782f12 | |||
| cafed0c7f0 | |||
| 8bd9c2f46f | |||
| 0355300908 | |||
| 3742a445b7 | |||
| 01953132ca | |||
| ed83fbc77c | |||
| 308c9e959c | |||
| 1e04922cee | |||
| a9f93d5239 | |||
| d885538500 | |||
| f13ba3fca0 | |||
| 720bdd54fe | |||
| b638bc5f75 | |||
| 3f8ced5453 | |||
| ecd2238c9e | |||
| 2218e27838 | |||
| 710d285733 | |||
| 7b8ee5ddbd | |||
| e40ba55825 | |||
| 2aa6939186 | |||
| 1c0ebc9559 | |||
| 0d062560da | |||
| 9bbb58ae55 | |||
| d0d6c9f721 | |||
| 3f60376061 | |||
| cea90c5b29 | |||
| ffaccc4c88 | |||
| 60d2db6cdd | |||
| 805911f72b | |||
| df08c31278 | |||
| fc3f931362 | |||
| e250ef6792 | |||
| d778c4d3f3 | |||
| 7ce9abe1de | |||
| dba74ecd49 | |||
| 398e67a7bd | |||
| ab7ce6d0c6 | |||
| e2767501fb | |||
| 3d20ceb35a | |||
| c6c1423364 | |||
| cb2908435a | |||
| 92e8d312dd | |||
| ce7b69923d | |||
| f8025c5dea | |||
| 8687b462ff | |||
| b262042244 | |||
| ae6e6490b2 | |||
| 9380879ab5 | |||
| 4254d020b9 | |||
| 769882dce5 | |||
| a3a00d162a | |||
| a8430e012f | |||
| 85b9890168 | |||
| e3f6af886b | |||
| ac70adf92a | |||
| e1463de00d | |||
| ca5d306b88 | |||
| 0bd6c27ab9 | |||
| 5c0c77202c | |||
| 54b680f757 | |||
| 146ef4b7ef | |||
| e619d27559 | |||
| dce83d7e49 | |||
| 6d28740a51 | |||
| 8d190a3478 | |||
| 46494dd46e | |||
| d38b6ab064 | |||
| 4f11249b94 | |||
| c433652326 | |||
| 62a9fec43f | |||
| 466d21e8b4 | |||
| ab92f22c85 | |||
| 2e8bbf2b99 | |||
| c3324128d0 | |||
| 7be45d3ffc | |||
| 86de5fd3ad | |||
| b0c4984b21 | |||
| 97bad80784 | |||
| 0ec7f5fba1 | |||
| 0d2b1431b6 | |||
| 8aa4e38760 | |||
| 954285e426 | |||
| a4a9938675 | |||
| 8a21a2f469 | |||
| a1e9167cdf | |||
| 2a07db75c7 | |||
| 60280d0e06 | |||
| f0c22db31f | |||
| 2ea8443409 | |||
| bd1033ac47 | |||
| ae056f612a | |||
| a512773f11 | |||
| 901cbf23bb | |||
| c4ab500235 | |||
| 5332fc9b4f | |||
| 37971f6875 | |||
| 008ebcee79 | |||
| 41c4dcea2e | |||
| 13368eace9 | |||
| b162844159 | |||
| c9f8235339 | |||
| e1d55e4fc7 | |||
| 17bde54c7c | |||
| 7abf35ca97 | |||
| e150a22174 | |||
| e9a122fcda | |||
| b09b3f4f2d | |||
| 50c9195797 | |||
| bdddcec922 |
@@ -179,3 +179,5 @@ fabric.properties
|
|||||||
|
|
||||||
# Block sensitive configuration files
|
# Block sensitive configuration files
|
||||||
settings.local.yaml
|
settings.local.yaml
|
||||||
|
log/
|
||||||
|
__debug_bin
|
||||||
|
|||||||
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
// 使用 IntelliSense 了解相关属性。
|
||||||
|
// 悬停以查看现有属性的描述。
|
||||||
|
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Launch Service",
|
||||||
|
"type": "go",
|
||||||
|
"request": "launch",
|
||||||
|
"mode": "auto",
|
||||||
|
"buildFlags": "-tags=jsoniter",
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"program": "${workspaceRoot}/main.go",
|
||||||
|
"args": [
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Vendored
+14
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"sqltools.connections": [
|
||||||
|
{
|
||||||
|
"previewLimit": 50,
|
||||||
|
"server": "39.105.39.8",
|
||||||
|
"port": 9432,
|
||||||
|
"driver": "PostgreSQL",
|
||||||
|
"name": "Electricity@Archgrid",
|
||||||
|
"database": "electricity",
|
||||||
|
"username": "electricity",
|
||||||
|
"password": "nLgxPO5s8gK2tR0OL0Q"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ RUN apk update \
|
|||||||
ENV TZ=Asia/Shanghai
|
ENV TZ=Asia/Shanghai
|
||||||
RUN mkdir /app
|
RUN mkdir /app
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
VOLUME ["/app/log"]
|
||||||
COPY --from=builder /app/server .
|
COPY --from=builder /app/server .
|
||||||
COPY settings.yaml .
|
COPY settings.yaml .
|
||||||
COPY regions.csv .
|
COPY regions.csv .
|
||||||
|
|||||||
@@ -11,3 +11,18 @@
|
|||||||
项目详细设计方案见[详细设计方案](https://kdocs.cn/l/cawe22YUV3bJ),该设计方案未经许可,禁止私自修改。
|
项目详细设计方案见[详细设计方案](https://kdocs.cn/l/cawe22YUV3bJ),该设计方案未经许可,禁止私自修改。
|
||||||
|
|
||||||
项目任务分配与状态概览表见[任务概况](https://kdocs.cn/l/camrXvBMlCNs)。
|
项目任务分配与状态概览表见[任务概况](https://kdocs.cn/l/camrXvBMlCNs)。
|
||||||
|
|
||||||
|
## 项目代码编写要点
|
||||||
|
|
||||||
|
### 数据库访问
|
||||||
|
|
||||||
|
项目所式的数据库框架采用的是Bun,该框架采用贴近SQL语句的数据库方式,但是在使用过程中需注意以下几点。
|
||||||
|
|
||||||
|
1. 要执行一个语句,必须提供一个`context.Context`类型的上下文,推荐采用`context.WithTimeout()`生成。上下文中携带的超时时间应该能覆盖超时时间所需要运行的全部语句。
|
||||||
|
1. 语句中用来指定操作目标数据表的`Model()`方法,其接受的是一个目标变量的地址,如果传入的是一个slice,那么就一定需要使用`&`获取其地址,如果是使用`&struct{}`或者`new()`初始化的,则可以直接作为参数传入。
|
||||||
|
1. 数据库中的时间字段都是带有时区的,但是bun中都是使用UTC时间的,对于数据库中`timestamptz`类型的字段,可以正常的按照数据库配置的时区保存时间,但是对于没有携带时区的`date`类型,就不能直接向其中传入`time.Time`类型的参数了,必须手工将其转化为字符串形式。
|
||||||
|
1. 使用Relation关联获取其他数据表内容的时候,被`Relation()`提及的数据表中配置的`alias`名称将不起作用,语句中的数据别名实际上是被关联字段名称的snake_case形式。
|
||||||
|
1. 需要进行嵌套Relation选择的时候,嵌套的Relation可以采用`Relation("A.B")`的形式来指示使用数据模型A中的Relation B。
|
||||||
|
1. 如果需要只从Relation关联数据表中选择一部分字段,不能直接在主查询语句中使用`Column()`方法,必须在`Relation()`方法的第二个参数中声明。
|
||||||
|
1. 如果需要对Relation关联表中的字段设置`Where`条件子句,那么就必须使用`relation_name__column_name`的双下划线字段选择形式,直接在`Relation()`方法中设定`Where`子句行不通。
|
||||||
|
1. 定义数据模型的时候,数据字段尽可能不要提供默认值,如果确实需要默认值,要首先考虑在数据库中定义默认值约束,其次选择使用Hook来赋予默认值。直接定义在struct tag中的默认值可能会造成bun形成查询语句时意外的空值。
|
||||||
Binary file not shown.
Vendored
+17
-15
@@ -3,6 +3,7 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"electricity_bill_calc/global"
|
"electricity_bill_calc/global"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -23,24 +24,25 @@ const (
|
|||||||
func Cache[T interface{}](key string, value *T, expires time.Duration) error {
|
func Cache[T interface{}](key string, value *T, expires time.Duration) error {
|
||||||
var err error
|
var err error
|
||||||
if expires > 0 {
|
if expires > 0 {
|
||||||
setCmd := global.RedisConn.B().Set().
|
realExpires := expires + time.Duration(rand.Int63n(60))*time.Second
|
||||||
|
setCmd := global.Rd.B().Set().
|
||||||
Key(key).Value(rueidis.JSON(value)).
|
Key(key).Value(rueidis.JSON(value)).
|
||||||
ExSeconds(int64(expires.Seconds())).
|
ExSeconds(int64(realExpires.Seconds())).
|
||||||
Build()
|
Build()
|
||||||
err = global.RedisConn.Do(global.Ctx, setCmd).Error()
|
err = global.Rd.Do(global.Ctx, setCmd).Error()
|
||||||
} else {
|
} else {
|
||||||
setCmd := global.RedisConn.B().Set().
|
setCmd := global.Rd.B().Set().
|
||||||
Key(key).Value(rueidis.JSON(value)).
|
Key(key).Value(rueidis.JSON(value)).
|
||||||
Build()
|
Build()
|
||||||
err = global.RedisConn.Do(global.Ctx, setCmd).Error()
|
err = global.Rd.Do(global.Ctx, setCmd).Error()
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从Redis缓存中获取一个数据
|
// 从Redis缓存中获取一个数据
|
||||||
func Retreive[T interface{}](key string) (*T, error) {
|
func Retreive[T interface{}](key string) (*T, error) {
|
||||||
getCmd := global.RedisConn.B().Get().Key(key).Build()
|
getCmd := global.Rd.B().Get().Key(key).Build()
|
||||||
result := global.RedisConn.Do(global.Ctx, getCmd)
|
result := global.Rd.Do(global.Ctx, getCmd)
|
||||||
if result.Error() != nil {
|
if result.Error() != nil {
|
||||||
if rueidis.IsRedisNil(result.Error()) {
|
if rueidis.IsRedisNil(result.Error()) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@@ -58,8 +60,8 @@ func Retreive[T interface{}](key string) (*T, error) {
|
|||||||
|
|
||||||
// 检查Redis缓存中是否存在指定键的记录
|
// 检查Redis缓存中是否存在指定键的记录
|
||||||
func Exists(key string) (bool, error) {
|
func Exists(key string) (bool, error) {
|
||||||
existsCmd := global.RedisConn.B().Exists().Key(key).Build()
|
existsCmd := global.Rd.B().Exists().Key(key).Build()
|
||||||
result := global.RedisConn.Do(global.Ctx, existsCmd)
|
result := global.Rd.Do(global.Ctx, existsCmd)
|
||||||
if result.Error() != nil {
|
if result.Error() != nil {
|
||||||
return false, result.Error()
|
return false, result.Error()
|
||||||
}
|
}
|
||||||
@@ -70,8 +72,8 @@ func Exists(key string) (bool, error) {
|
|||||||
// 从Redis缓存中删除指定键
|
// 从Redis缓存中删除指定键
|
||||||
// ! 如果指定键已不存在,那么本函数一样会返回false
|
// ! 如果指定键已不存在,那么本函数一样会返回false
|
||||||
func Delete(key string) (bool, error) {
|
func Delete(key string) (bool, error) {
|
||||||
deleteCmd := global.RedisConn.B().Del().Key(key).Build()
|
deleteCmd := global.Rd.B().Del().Key(key).Build()
|
||||||
result := global.RedisConn.Do(global.Ctx, deleteCmd)
|
result := global.Rd.Do(global.Ctx, deleteCmd)
|
||||||
if result.Error() != nil {
|
if result.Error() != nil {
|
||||||
return false, result.Error()
|
return false, result.Error()
|
||||||
}
|
}
|
||||||
@@ -109,8 +111,8 @@ func DeleteAll(pattern string) error {
|
|||||||
sKeys []string
|
sKeys []string
|
||||||
)
|
)
|
||||||
for {
|
for {
|
||||||
scanCmd := global.RedisConn.B().Scan().Cursor(cursor).Match(pattern).Count(20).Build()
|
scanCmd := global.Rd.B().Scan().Cursor(cursor).Match(pattern).Count(20).Build()
|
||||||
results := global.RedisConn.Do(global.Ctx, scanCmd)
|
results := global.Rd.Do(global.Ctx, scanCmd)
|
||||||
cursor, sKeys, err = dissembleScan(results)
|
cursor, sKeys, err = dissembleScan(results)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -121,8 +123,8 @@ func DeleteAll(pattern string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delCmd := global.RedisConn.B().Del().Key(keys...).Build()
|
delCmd := global.Rd.B().Del().Key(keys...).Build()
|
||||||
err = global.RedisConn.Do(global.Ctx, delCmd).Error()
|
err = global.Rd.Do(global.Ctx, delCmd).Error()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+32
-23
@@ -1,49 +1,58 @@
|
|||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"electricity_bill_calc/global"
|
"fmt"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func assembleCountKey(entityName string) string {
|
type _CountRecord struct {
|
||||||
var keys = make([]string, 0)
|
Count int64
|
||||||
keys = append(keys, strings.ToUpper(entityName))
|
|
||||||
return CacheKey(TAG_COUNT, keys...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func assembleCountIdentification(additional ...string) string {
|
func assembleCountKey(entityName string, additional ...string) string {
|
||||||
return strings.Join(additional, ":")
|
var keys = make([]string, 0)
|
||||||
|
keys = append(keys, strings.ToUpper(entityName))
|
||||||
|
keys = append(keys, additional...)
|
||||||
|
var b strings.Builder
|
||||||
|
b.WriteString(TAG_COUNT)
|
||||||
|
for _, s := range keys {
|
||||||
|
fmt.Fprintf(&b, ":%s", s)
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 向缓存中缓存模型名称明确的包含指定条件的实体记录数量
|
// 向缓存中缓存模型名称明确的包含指定条件的实体记录数量
|
||||||
func CacheCount(relationNames []string, entityName string, count int64, conditions ...string) error {
|
func CacheCount(relationNames []string, entityName string, count int64, conditions ...string) error {
|
||||||
countKey := assembleCountKey(entityName)
|
countKey := assembleCountKey(entityName, conditions...)
|
||||||
identification := assembleCountIdentification(conditions...)
|
cacheInstance := &_CountRecord{Count: count}
|
||||||
cmd := global.RedisConn.B().Hset().Key(countKey).FieldValue().FieldValue(identification, strconv.FormatInt(count, 10)).Build()
|
err := Cache(countKey, cacheInstance, 5*time.Minute)
|
||||||
result := global.RedisConn.Do(global.Ctx, cmd)
|
|
||||||
for _, relationName := range relationNames {
|
for _, relationName := range relationNames {
|
||||||
CacheRelation(relationName, STORE_TYPE_HASH, countKey, identification)
|
CacheRelation(relationName, STORE_TYPE_KEY, countKey)
|
||||||
}
|
}
|
||||||
return result.Error()
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从缓存中获取模型名称明确的,包含指定条件的实体记录数量
|
// 从缓存中获取模型名称明确的,包含指定条件的实体记录数量
|
||||||
func RetreiveCount(entityName string, condtions ...string) (int64, error) {
|
func RetreiveCount(entityName string, condtions ...string) (int64, error) {
|
||||||
countKey := assembleCountKey(entityName)
|
countKey := assembleCountKey(entityName, condtions...)
|
||||||
identification := assembleCountIdentification(condtions...)
|
exist, err := Exists(countKey)
|
||||||
cmd := global.RedisConn.B().Hget().Key(countKey).Field(identification).Build()
|
|
||||||
result, err := global.RedisConn.Do(global.Ctx, cmd).AsInt64()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
return result, nil
|
if !exist {
|
||||||
|
return -1, nil
|
||||||
|
}
|
||||||
|
instance, err := Retreive[_CountRecord](countKey)
|
||||||
|
if instance != nil && err == nil {
|
||||||
|
return instance.Count, nil
|
||||||
|
} else {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除指定模型名称的数量缓存
|
// 删除指定模型名称的数量缓存
|
||||||
func AbolishCountEntity(entityName string) error {
|
func AbolishCountEntity(entityName string) error {
|
||||||
countKey := assembleCountKey(entityName)
|
pattern := fmt.Sprintf("%s:%s:*", TAG_COUNT, strings.ToUpper(entityName))
|
||||||
cmd := global.RedisConn.B().Del().Key(countKey).Build()
|
return DeleteAll(pattern)
|
||||||
err := global.RedisConn.Do(global.Ctx, cmd).Error()
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
-1
@@ -3,6 +3,7 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func assembleEntityKey(entityName, id string) string {
|
func assembleEntityKey(entityName, id string) string {
|
||||||
@@ -19,7 +20,7 @@ func assembleEntityKey(entityName, id string) string {
|
|||||||
// 缓存模型名称明确的,使用ID进行检索的实体内容。
|
// 缓存模型名称明确的,使用ID进行检索的实体内容。
|
||||||
func CacheEntity[T any](instance T, relationNames []string, entityName, id string) error {
|
func CacheEntity[T any](instance T, relationNames []string, entityName, id string) error {
|
||||||
entityKey := assembleEntityKey(entityName, id)
|
entityKey := assembleEntityKey(entityName, id)
|
||||||
err := Cache(entityKey, &instance, -1)
|
err := Cache(entityKey, &instance, 5*time.Minute)
|
||||||
for _, relationName := range relationNames {
|
for _, relationName := range relationNames {
|
||||||
CacheRelation(relationName, STORE_TYPE_KEY, entityKey)
|
CacheRelation(relationName, STORE_TYPE_KEY, entityKey)
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+20
-43
@@ -1,72 +1,49 @@
|
|||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"electricity_bill_calc/global"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/samber/lo"
|
||||||
)
|
)
|
||||||
|
|
||||||
func assembleExistsKey(entityName string) string {
|
func assembleExistsKey(entityName string, additional ...string) string {
|
||||||
var keys = make([]string, 0)
|
var keys = make([]string, 0)
|
||||||
keys = append(keys, strings.ToUpper(entityName))
|
keys = append(keys, strings.ToUpper(entityName))
|
||||||
return CacheKey(TAG_EXISTS, keys...)
|
keys = append(keys, additional...)
|
||||||
}
|
var b strings.Builder
|
||||||
|
b.WriteString(TAG_EXISTS)
|
||||||
func assembleExistsIdentification(additional ...string) string {
|
for _, s := range keys {
|
||||||
return strings.Join(additional, ":")
|
fmt.Fprintf(&b, ":%s", s)
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 缓存模型名称明确的、包含指定ID以及一些附加条件的记录
|
// 缓存模型名称明确的、包含指定ID以及一些附加条件的记录
|
||||||
func CacheExists(relationNames []string, entityName string, conditions ...string) error {
|
func CacheExists(relationNames []string, entityName string, conditions ...string) error {
|
||||||
existskey := assembleExistsKey(entityName)
|
existskey := assembleExistsKey(entityName, conditions...)
|
||||||
identification := assembleExistsIdentification(conditions...)
|
err := Cache(existskey, lo.ToPtr(true), 5*time.Minute)
|
||||||
cmd := global.RedisConn.B().Sadd().Key(existskey).Member(identification).Build()
|
|
||||||
err := global.RedisConn.Do(global.Ctx, cmd).Error()
|
|
||||||
for _, relationName := range relationNames {
|
for _, relationName := range relationNames {
|
||||||
CacheRelation(relationName, STORE_TYPE_SET, existskey, identification)
|
CacheRelation(relationName, STORE_TYPE_KEY, existskey)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从缓存中获取模型名称明确、包含指定ID以及一些附加条件的实体是否存在的标记,函数在返回false时不保证数据库中相关记录也不存在
|
// 从缓存中获取模型名称明确、包含指定ID以及一些附加条件的实体是否存在的标记,函数在返回false时不保证数据库中相关记录也不存在
|
||||||
func CheckExists(entityName string, condtions ...string) (bool, error) {
|
func CheckExists(entityName string, condtions ...string) (bool, error) {
|
||||||
existsKey := assembleExistsKey(entityName)
|
existsKey := assembleExistsKey(entityName, condtions...)
|
||||||
identification := assembleExistsIdentification(condtions...)
|
return Exists(existsKey)
|
||||||
cmd := global.RedisConn.B().Sismember().Key(existsKey).Member(identification).Build()
|
|
||||||
result, err := global.RedisConn.Do(global.Ctx, cmd).AsBool()
|
|
||||||
return result, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从缓存中删除模型名称明确、包含指定ID的全部实体存在标记
|
// 从缓存中删除模型名称明确、包含指定ID的全部实体存在标记
|
||||||
func AbolishExists(entityName, id string) error {
|
func AbolishExists(entityName, id string) error {
|
||||||
existsKey := assembleExistsKey(entityName)
|
pattern := fmt.Sprintf("%s:%s:%s:*", TAG_EXISTS, strings.ToUpper(entityName), id)
|
||||||
pattern := fmt.Sprintf("%s*", id)
|
return DeleteAll(pattern)
|
||||||
var (
|
|
||||||
err error
|
|
||||||
cursor int64
|
|
||||||
elems = make([]string, 0)
|
|
||||||
sElem []string
|
|
||||||
)
|
|
||||||
for {
|
|
||||||
cmd := global.RedisConn.B().Sscan().Key(existsKey).Cursor(cursor).Match(pattern).Count(20).Build()
|
|
||||||
result := global.RedisConn.Do(global.Ctx, cmd)
|
|
||||||
cursor, sElem, err = dissembleScan(result)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
elems = append(elems, sElem...)
|
|
||||||
if cursor == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cmd := global.RedisConn.B().Srem().Key(existsKey).Member(elems...).Build()
|
|
||||||
err = global.RedisConn.Do(global.Ctx, cmd).Error()
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从缓存中删除指定模型名称的全部存在标记
|
// 从缓存中删除指定模型名称的全部存在标记
|
||||||
func AbolishExistsEntity(entityName string) error {
|
func AbolishExistsEntity(entityName string) error {
|
||||||
existskey := assembleExistsKey(entityName)
|
pattern := fmt.Sprintf("%s:%s:*", TAG_EXISTS, strings.ToUpper(entityName))
|
||||||
_, err := Delete(existskey)
|
return DeleteAll(pattern)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+59
-8
@@ -2,6 +2,7 @@ package cache
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"electricity_bill_calc/global"
|
"electricity_bill_calc/global"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/rueian/rueidis"
|
"github.com/rueian/rueidis"
|
||||||
@@ -31,16 +32,16 @@ func assembleRelationIdentity(storeType, key string, field ...string) string {
|
|||||||
func CacheRelation(relationName, storeType, key string, field ...string) error {
|
func CacheRelation(relationName, storeType, key string, field ...string) error {
|
||||||
relationKey := assembleRelationKey(relationName)
|
relationKey := assembleRelationKey(relationName)
|
||||||
relationIdentity := assembleRelationIdentity(storeType, key, field...)
|
relationIdentity := assembleRelationIdentity(storeType, key, field...)
|
||||||
cmd := global.RedisConn.B().Sadd().Key(relationKey).Member(relationIdentity).Build()
|
cmd := global.Rd.B().Sadd().Key(relationKey).Member(relationIdentity).Build()
|
||||||
result := global.RedisConn.Do(global.Ctx, cmd)
|
result := global.Rd.Do(global.Ctx, cmd)
|
||||||
return result.Error()
|
return result.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从缓存中清理指定的关联键
|
// 从缓存中清理指定的关联键
|
||||||
func AbolishRelation(relationName string) error {
|
func AbolishRelation(relationName string) error {
|
||||||
relationKey := assembleRelationKey(relationName)
|
relationKey := assembleRelationKey(relationName)
|
||||||
cmd := global.RedisConn.B().Smembers().Key(relationKey).Build()
|
cmd := global.Rd.B().Smembers().Key(relationKey).Build()
|
||||||
relationItems, err := global.RedisConn.Do(global.Ctx, cmd).AsStrSlice()
|
relationItems, err := global.Rd.Do(global.Ctx, cmd).AsStrSlice()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -49,17 +50,67 @@ func AbolishRelation(relationName string) error {
|
|||||||
separated := strings.Split(item, ";")
|
separated := strings.Split(item, ";")
|
||||||
switch separated[0] {
|
switch separated[0] {
|
||||||
case STORE_TYPE_KEY:
|
case STORE_TYPE_KEY:
|
||||||
cmd := global.RedisConn.B().Del().Key(separated[1]).Build()
|
cmd := global.Rd.B().Del().Key(separated[1]).Build()
|
||||||
cmds = append(cmds, cmd)
|
cmds = append(cmds, cmd)
|
||||||
case STORE_TYPE_HASH:
|
case STORE_TYPE_HASH:
|
||||||
cmd := global.RedisConn.B().Hdel().Key(separated[1]).Field(separated[2:]...).Build()
|
cmd := global.Rd.B().Hdel().Key(separated[1]).Field(separated[2:]...).Build()
|
||||||
cmds = append(cmds, cmd)
|
cmds = append(cmds, cmd)
|
||||||
case STORE_TYPE_SET:
|
case STORE_TYPE_SET:
|
||||||
cmd := global.RedisConn.B().Srem().Key(separated[1]).Member(separated[2:]...).Build()
|
cmd := global.Rd.B().Srem().Key(separated[1]).Member(separated[2:]...).Build()
|
||||||
cmds = append(cmds, cmd)
|
cmds = append(cmds, cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
errs := global.RedisConn.DoMulti(global.Ctx, cmds...)
|
errs := global.Rd.DoMulti(global.Ctx, cmds...)
|
||||||
|
firstErr, has := lo.Find(errs, func(elem rueidis.RedisResult) bool {
|
||||||
|
return elem.Error() != nil
|
||||||
|
})
|
||||||
|
if has {
|
||||||
|
return firstErr.Error()
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ClearOrphanRelationItems() error {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
cursor int64
|
||||||
|
keys = make([]string, 0)
|
||||||
|
sKeys []string
|
||||||
|
)
|
||||||
|
for {
|
||||||
|
scanCmd := global.Rd.B().Scan().Cursor(cursor).Match(fmt.Sprintf("%s:*", TAG_RELATION)).Count(20).Build()
|
||||||
|
results := global.Rd.Do(global.Ctx, scanCmd)
|
||||||
|
cursor, sKeys, err = dissembleScan(results)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
keys = append(keys, sKeys...)
|
||||||
|
if cursor == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var cmds = make(rueidis.Commands, 0)
|
||||||
|
for _, key := range keys {
|
||||||
|
relationItemsCmd := global.Rd.B().Smembers().Key(key).Build()
|
||||||
|
results := global.Rd.Do(global.Ctx, relationItemsCmd)
|
||||||
|
relationItems, err := results.AsStrSlice()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, item := range relationItems {
|
||||||
|
separated := strings.Split(item, ";")
|
||||||
|
exist, err := Exists(separated[1])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !exist {
|
||||||
|
cmd := global.Rd.B().Srem().Key(key).Member(item).Build()
|
||||||
|
cmds = append(cmds, cmd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errs := global.Rd.DoMulti(global.Ctx, cmds...)
|
||||||
firstErr, has := lo.Find(errs, func(elem rueidis.RedisResult) bool {
|
firstErr, has := lo.Find(errs, func(elem rueidis.RedisResult) bool {
|
||||||
return elem.Error() != nil
|
return elem.Error() != nil
|
||||||
})
|
})
|
||||||
|
|||||||
Vendored
-33
@@ -1,33 +0,0 @@
|
|||||||
package cache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"electricity_bill_calc/config"
|
|
||||||
)
|
|
||||||
|
|
||||||
func CacheData[T interface{}](instance T, category string, key ...string) error {
|
|
||||||
var keys = make([]string, 0)
|
|
||||||
keys = append(keys, category)
|
|
||||||
keys = append(keys, key...)
|
|
||||||
cacheKey := CacheKey("cache", keys...)
|
|
||||||
if exists, _ := Exists(cacheKey); exists {
|
|
||||||
Delete(cacheKey)
|
|
||||||
}
|
|
||||||
return Cache(cacheKey, &instance, config.ServiceSettings.CacheLifeTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
func RetreiveData[T interface{}](category string, key ...string) (*T, error) {
|
|
||||||
var keys = make([]string, 0)
|
|
||||||
keys = append(keys, category)
|
|
||||||
keys = append(keys, key...)
|
|
||||||
return Retreive[T](CacheKey("cache", keys...))
|
|
||||||
}
|
|
||||||
|
|
||||||
func AbolishCacheData(category string, key ...string) {
|
|
||||||
var keys = make([]string, 0)
|
|
||||||
keys = append(keys, category)
|
|
||||||
keys = append(keys, key...)
|
|
||||||
cacheKey := CacheKey("cache", keys...)
|
|
||||||
if exists, _ := Exists(cacheKey); exists {
|
|
||||||
Delete(cacheKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
+2
-1
@@ -3,6 +3,7 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func assembleSearchKey(entityName string, additional ...string) string {
|
func assembleSearchKey(entityName string, additional ...string) string {
|
||||||
@@ -20,7 +21,7 @@ func assembleSearchKey(entityName string, additional ...string) string {
|
|||||||
// 缓存模型名称明确的,使用或者包含非ID检索条件的实体内容。
|
// 缓存模型名称明确的,使用或者包含非ID检索条件的实体内容。
|
||||||
func CacheSearch[T any](instance T, relationNames []string, entityName string, conditions ...string) error {
|
func CacheSearch[T any](instance T, relationNames []string, entityName string, conditions ...string) error {
|
||||||
searchKey := assembleSearchKey(entityName, conditions...)
|
searchKey := assembleSearchKey(entityName, conditions...)
|
||||||
err := Cache(searchKey, &instance, -1)
|
err := Cache(searchKey, &instance, 5*time.Minute)
|
||||||
for _, relationName := range relationNames {
|
for _, relationName := range relationNames {
|
||||||
CacheRelation(relationName, STORE_TYPE_KEY, searchKey)
|
CacheRelation(relationName, STORE_TYPE_KEY, searchKey)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import (
|
|||||||
"electricity_bill_calc/exceptions"
|
"electricity_bill_calc/exceptions"
|
||||||
"electricity_bill_calc/model"
|
"electricity_bill_calc/model"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func _retreiveSession(c *gin.Context) (*model.Session, error) {
|
func _retreiveSession(c *fiber.Ctx) (*model.Session, error) {
|
||||||
session, exists := c.Get("session")
|
session := c.Locals("session")
|
||||||
if !exists {
|
if session == nil {
|
||||||
return nil, exceptions.NewUnauthorizedError("用户会话不存在")
|
return nil, exceptions.NewUnauthorizedError("用户会话不存在")
|
||||||
}
|
}
|
||||||
userSession, ok := session.(*model.Session)
|
userSession, ok := session.(*model.Session)
|
||||||
|
|||||||
+31
-32
@@ -9,35 +9,33 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitializeChargesController(router *gin.Engine) {
|
func InitializeChargesController(app *fiber.App) {
|
||||||
router.GET("/charges", security.OPSAuthorize, listAllCharges)
|
app.Get("/charges", security.OPSAuthorize, listAllCharges)
|
||||||
router.POST("/charge", security.OPSAuthorize, recordNewCharge)
|
app.Post("/charge", security.OPSAuthorize, recordNewCharge)
|
||||||
router.PUT("/charge/:uid/:seq", security.OPSAuthorize, modifyChargeState)
|
app.Put("/charge/:uid/:seq", security.OPSAuthorize, modifyChargeState)
|
||||||
}
|
}
|
||||||
|
|
||||||
func listAllCharges(c *gin.Context) {
|
func listAllCharges(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestPage, err := strconv.Atoi(c.DefaultQuery("page", "1"))
|
requestPage, err := strconv.Atoi(c.Query("page", "1"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotAccept("查询参数[page]格式不正确。")
|
return result.NotAccept("查询参数[page]格式不正确。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
requestKeyword := c.DefaultQuery("keyword", "")
|
requestKeyword := c.Query("keyword", "")
|
||||||
requestBeginDate := c.DefaultQuery("begin", "")
|
requestBeginDate := c.Query("begin", "")
|
||||||
requestEndDate := c.DefaultQuery("end", "")
|
requestEndDate := c.Query("end", "")
|
||||||
charges, total, err := service.ChargeService.ListPagedChargeRecord(requestKeyword, requestBeginDate, requestEndDate, requestPage)
|
charges, total, err := service.ChargeService.ListPagedChargeRecord(requestKeyword, requestBeginDate, requestEndDate, requestPage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return result.NotFound(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(
|
return result.Json(
|
||||||
http.StatusOK, "已获取到符合条件的计费记录。",
|
http.StatusOK, "已获取到符合条件的计费记录。",
|
||||||
response.NewPagedResponse(requestPage, total).ToMap(),
|
response.NewPagedResponse(requestPage, total).ToMap(),
|
||||||
gin.H{"records": charges},
|
fiber.Map{"records": charges},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,13 +44,15 @@ type _NewChargeFormData struct {
|
|||||||
Fee decimal.NullDecimal `json:"fee" form:"fee"`
|
Fee decimal.NullDecimal `json:"fee" form:"fee"`
|
||||||
Discount decimal.NullDecimal `json:"discount" form:"discount"`
|
Discount decimal.NullDecimal `json:"discount" form:"discount"`
|
||||||
Amount decimal.NullDecimal `json:"amount" form:"amount"`
|
Amount decimal.NullDecimal `json:"amount" form:"amount"`
|
||||||
ChargeTo time.Time `json:"chargeTo" form:"chargeTo" time_format:"simple_date" time_location:"shanghai"`
|
ChargeTo model.Date `json:"chargeTo" form:"chargeTo"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func recordNewCharge(c *gin.Context) {
|
func recordNewCharge(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
formData := new(_NewChargeFormData)
|
formData := new(_NewChargeFormData)
|
||||||
c.BindJSON(formData)
|
if err := c.BodyParser(formData); err != nil {
|
||||||
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
|
}
|
||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
newRecord := &model.UserCharge{
|
newRecord := &model.UserCharge{
|
||||||
UserId: formData.UserId,
|
UserId: formData.UserId,
|
||||||
@@ -65,30 +65,29 @@ func recordNewCharge(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
err := service.ChargeService.CreateChargeRecord(newRecord, true)
|
err := service.ChargeService.CreateChargeRecord(newRecord, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Created("指定用户的服务已延期。")
|
return result.Created("指定用户的服务已延期。")
|
||||||
}
|
}
|
||||||
|
|
||||||
type _StateChangeFormData struct {
|
type _StateChangeFormData struct {
|
||||||
Cancelled bool `json:"cancelled"`
|
Cancelled bool `json:"cancelled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func modifyChargeState(c *gin.Context) {
|
func modifyChargeState(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
formData := new(_StateChangeFormData)
|
formData := new(_StateChangeFormData)
|
||||||
c.BindJSON(formData)
|
if err := c.BodyParser(formData); err != nil {
|
||||||
requestUserID := c.Param("uid")
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
requestChargeSeq, err := strconv.Atoi(c.Param("seq"))
|
}
|
||||||
if err != nil {
|
requestUserID := c.Params("uid")
|
||||||
result.Error(http.StatusNotAcceptable, "参数[记录流水号]解析错误。")
|
requestChargeSeq, err := strconv.Atoi(c.Params("seq", "-1"))
|
||||||
return
|
if err != nil || requestChargeSeq == -1 {
|
||||||
|
return result.Error(http.StatusNotAcceptable, "参数[记录流水号]解析错误。")
|
||||||
}
|
}
|
||||||
err = service.ChargeService.CancelCharge(int64(requestChargeSeq), requestUserID)
|
err = service.ChargeService.CancelCharge(int64(requestChargeSeq), requestUserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Updated("指定用户服务延期记录状态已经更新。")
|
return result.Updated("指定用户服务延期记录状态已经更新。")
|
||||||
}
|
}
|
||||||
|
|||||||
+100
-78
@@ -1,77 +1,81 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"electricity_bill_calc/excel"
|
"electricity_bill_calc/excel"
|
||||||
"electricity_bill_calc/global"
|
"electricity_bill_calc/global"
|
||||||
|
"electricity_bill_calc/model"
|
||||||
"electricity_bill_calc/response"
|
"electricity_bill_calc/response"
|
||||||
"electricity_bill_calc/security"
|
"electricity_bill_calc/security"
|
||||||
"electricity_bill_calc/service"
|
"electricity_bill_calc/service"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitializeEndUserController(router *gin.Engine) {
|
func InitializeEndUserController(router *fiber.App) {
|
||||||
router.GET("/report/:rid/submeter", security.EnterpriseAuthorize, fetchEndUserInReport)
|
router.Get("/report/:rid/submeter", security.EnterpriseAuthorize, fetchEndUserInReport)
|
||||||
router.GET("/report/:rid/meter/template", security.EnterpriseAuthorize, downloadEndUserRegisterTemplate)
|
router.Get("/report/:rid/meter/template", downloadEndUserRegisterTemplate)
|
||||||
router.POST("/report/:rid/meter/batch", security.EnterpriseAuthorize, uploadEndUserRegisterTemplate)
|
router.Post("/report/:rid/meter/batch", security.EnterpriseAuthorize, uploadEndUserRegisterTemplate)
|
||||||
router.PUT("/report/:rid/submeter/:pid/:mid", security.EnterpriseAuthorize, modifyEndUserRegisterRecord)
|
router.Put("/report/:rid/submeter/:pid/:mid", security.EnterpriseAuthorize, modifyEndUserRegisterRecord)
|
||||||
|
router.Get("/end/user/adjusts", security.MustAuthenticated, statEndUserInPeriod)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchEndUserInReport(c *gin.Context) {
|
func fetchEndUserInReport(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestReportId := c.Param("rid")
|
requestReportId := c.Params("rid")
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
if ensure, err := ensureReportBelongs(c, &result, requestReportId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
keyword := c.DefaultQuery("keyword", "")
|
keyword := c.Query("keyword")
|
||||||
requestPage, err := strconv.Atoi(c.DefaultQuery("page", "1"))
|
requestPage, err := strconv.Atoi(c.Query("page", "1"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotAccept("查询参数[page]格式不正确。")
|
return result.NotAccept("查询参数[page]格式不正确。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
endUsers, totalItem, err := service.EndUserService.SearchEndUserRecord(requestReportId, keyword, requestPage)
|
endUsers, totalItem, err := service.EndUserService.SearchEndUserRecord(requestReportId, keyword, requestPage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return result.NotFound(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(
|
return result.Json(
|
||||||
http.StatusOK,
|
http.StatusOK,
|
||||||
"已获取到符合条件的终端用户集合",
|
"已获取到符合条件的终端用户集合",
|
||||||
response.NewPagedResponse(requestPage, totalItem).ToMap(),
|
response.NewPagedResponse(requestPage, totalItem).ToMap(),
|
||||||
gin.H{"meters": endUsers},
|
fiber.Map{"meters": endUsers},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func downloadEndUserRegisterTemplate(c *gin.Context) {
|
func downloadEndUserRegisterTemplate(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestReportId := c.Param("rid")
|
requestReportId := c.Params("rid")
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
users, err := service.EndUserService.AllEndUserRecord(requestReportId)
|
users, err := service.EndUserService.AllEndUserRecord(requestReportId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return result.NotFound(err.Error())
|
||||||
return
|
}
|
||||||
|
reportIndex, err := service.ReportService.RetreiveReportIndex(requestReportId)
|
||||||
|
if err != nil {
|
||||||
|
return result.NotFound(err.Error())
|
||||||
|
}
|
||||||
|
park, err := service.ParkService.FetchParkDetail(reportIndex.ParkId)
|
||||||
|
if err != nil {
|
||||||
|
return result.NotFound(err.Error())
|
||||||
}
|
}
|
||||||
meterType, err := service.ReportService.RetreiveParkEndUserMeterType(requestReportId)
|
meterType, err := service.ReportService.RetreiveParkEndUserMeterType(requestReportId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if meterType == -1 {
|
if meterType == -1 {
|
||||||
result.NotFound("未能确定用户表计类型。")
|
return result.NotFound("未能确定用户表计类型。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Status(http.StatusOK)
|
c.Status(http.StatusOK)
|
||||||
c.Header("Content-Type", "application/octet-stream")
|
c.Set("Content-Type", "application/octet-stream")
|
||||||
c.Header("Content-Transfer-Encoding", "binary")
|
c.Set("Content-Transfer-Encoding", "binary")
|
||||||
c.Header("Content-Disposition", "attachment; filename=抄表记录.xlsx")
|
c.Set("Content-Disposition", fmt.Sprintf("attachment; filename=抄表记录-%s-%s.xlsx", park.Name, reportIndex.Period.Format("2006-01")))
|
||||||
|
|
||||||
gen := lo.Ternary[excel.ExcelTemplateGenerator](
|
gen := lo.Ternary[excel.ExcelTemplateGenerator](
|
||||||
meterType == 0,
|
meterType == 0,
|
||||||
@@ -80,49 +84,45 @@ func downloadEndUserRegisterTemplate(c *gin.Context) {
|
|||||||
)
|
)
|
||||||
defer gen.Close()
|
defer gen.Close()
|
||||||
gen.WriteMeterData(users)
|
gen.WriteMeterData(users)
|
||||||
gen.WriteTo(c.Writer)
|
gen.WriteTo(c.Response().BodyWriter())
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func uploadEndUserRegisterTemplate(c *gin.Context) {
|
func uploadEndUserRegisterTemplate(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestReportId := c.Param("rid")
|
requestReportId := c.Params("rid")
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
if ensure, err := ensureReportBelongs(c, &result, requestReportId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
meterType, err := service.ReportService.RetreiveParkEndUserMeterType(requestReportId)
|
meterType, err := service.ReportService.RetreiveParkEndUserMeterType(requestReportId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if meterType == -1 {
|
if meterType == -1 {
|
||||||
result.NotFound("未能确定用户表计类型。")
|
return result.NotFound("未能确定用户表计类型。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadedFile, err := c.FormFile("data")
|
uploadedFile, err := c.FormFile("data")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotAccept("没有接收到上传的档案文件。")
|
return result.NotAccept("没有接收到上传的档案文件。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
archiveFile, err := uploadedFile.Open()
|
archiveFile, err := uploadedFile.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if meterType == 0 {
|
if meterType == 0 {
|
||||||
errs := service.EndUserService.BatchImportNonPVRegister(requestReportId, archiveFile)
|
errs := service.EndUserService.BatchImportNonPVRegister(requestReportId, archiveFile)
|
||||||
if errs.Len() > 0 {
|
if errs.Len() > 0 {
|
||||||
result.Json(http.StatusInternalServerError, "上传抄表文件存在解析错误", gin.H{"errors": errs.Errs})
|
return result.Json(http.StatusInternalServerError, "上传抄表文件存在解析错误", fiber.Map{"errors": errs.Errs})
|
||||||
return
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
errs := service.EndUserService.BatchImportPVRegister(requestReportId, archiveFile)
|
errs := service.EndUserService.BatchImportPVRegister(requestReportId, archiveFile)
|
||||||
if errs.Len() > 0 {
|
if errs.Len() > 0 {
|
||||||
result.Json(http.StatusInternalServerError, "上传抄表文件存在解析错误", gin.H{"errors": errs.Errs})
|
return result.Json(http.StatusInternalServerError, "上传抄表文件存在解析错误", fiber.Map{"errors": errs.Errs})
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.Json(http.StatusOK, "已经成功完成抄表记录的导入。", gin.H{"errors": make([]error, 0)})
|
return result.Json(http.StatusOK, "已经成功完成抄表记录的导入。", fiber.Map{"errors": make([]error, 0)})
|
||||||
}
|
}
|
||||||
|
|
||||||
type ModifyEndUserRegisterFormData struct {
|
type ModifyEndUserRegisterFormData struct {
|
||||||
@@ -136,29 +136,28 @@ type ModifyEndUserRegisterFormData struct {
|
|||||||
AdjustValley decimal.NullDecimal `json:"adjustValley" form:"adjustValley"`
|
AdjustValley decimal.NullDecimal `json:"adjustValley" form:"adjustValley"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func modifyEndUserRegisterRecord(c *gin.Context) {
|
func modifyEndUserRegisterRecord(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestReportId := c.Param("rid")
|
requestReportId := c.Params("rid")
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
if ensure, err := ensureReportBelongs(c, &result, requestReportId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
meterType, err := service.ReportService.RetreiveParkEndUserMeterType(requestReportId)
|
meterType, err := service.ReportService.RetreiveParkEndUserMeterType(requestReportId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if meterType == -1 {
|
if meterType == -1 {
|
||||||
result.NotFound("未能确定用户表计类型。")
|
return result.NotFound("未能确定用户表计类型。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
requestParkId := c.Param("pid")
|
requestParkId := c.Params("pid")
|
||||||
requestMeterId := c.Param("mid")
|
requestMeterId := c.Params("mid")
|
||||||
formData := new(ModifyEndUserRegisterFormData)
|
formData := new(ModifyEndUserRegisterFormData)
|
||||||
c.BindJSON(formData)
|
if err := c.BodyParser(formData); err != nil {
|
||||||
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
|
}
|
||||||
meter, err := service.EndUserService.FetchSpecificEndUserRecord(requestReportId, requestParkId, requestMeterId)
|
meter, err := service.EndUserService.FetchSpecificEndUserRecord(requestReportId, requestParkId, requestMeterId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return result.NotFound(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if formData.CurrentPeriodOverall.Valid {
|
if formData.CurrentPeriodOverall.Valid {
|
||||||
meter.CurrentPeriodOverall = formData.CurrentPeriodOverall.Decimal
|
meter.CurrentPeriodOverall = formData.CurrentPeriodOverall.Decimal
|
||||||
@@ -186,30 +185,53 @@ func modifyEndUserRegisterRecord(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
valid, err := meter.Validate()
|
valid, err := meter.Validate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if !valid {
|
if !valid {
|
||||||
result.NotAccept("抄表数据合法性验证失败。")
|
return result.NotAccept("抄表数据合法性验证失败。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
tx := global.DBConn.NewSession()
|
ctx, cancel := global.TimeoutContext()
|
||||||
if err = tx.Begin(); err != nil {
|
defer cancel()
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
return
|
if err != nil {
|
||||||
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
}
|
}
|
||||||
defer tx.Close()
|
err = service.EndUserService.UpdateEndUserRegisterRecord(&tx, &ctx, *meter)
|
||||||
err = service.EndUserService.UpdateEndUserRegisterRecord(tx, *meter)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
err = tx.Commit()
|
err = tx.Commit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Success("指定终端用户抄表记录已经更新。")
|
return result.Success("指定终端用户抄表记录已经更新。")
|
||||||
|
}
|
||||||
|
|
||||||
|
func statEndUserInPeriod(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
session, err := _retreiveSession(c)
|
||||||
|
if err != nil {
|
||||||
|
return result.Unauthorized(err.Error())
|
||||||
|
}
|
||||||
|
requestUser := lo.
|
||||||
|
If(session.Type == model.USER_TYPE_ENT, session.Uid).
|
||||||
|
Else(c.Query("user"))
|
||||||
|
requestPark := c.Query("park")
|
||||||
|
if len(requestPark) > 0 && session.Type == model.USER_TYPE_ENT {
|
||||||
|
if ensure, err := ensureParkBelongs(c, &result, requestPark); !ensure {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startDate := c.Query("start")
|
||||||
|
endDate := c.Query("end")
|
||||||
|
stat, err := service.EndUserService.StatEndUserRecordInPeriod(requestUser, requestPark, startDate, endDate)
|
||||||
|
if err != nil {
|
||||||
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
return result.Success(
|
||||||
|
"已经完成终端用户的费用统计",
|
||||||
|
fiber.Map{"details": stat},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,176 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"electricity_bill_calc/exceptions"
|
||||||
|
"electricity_bill_calc/response"
|
||||||
|
"electricity_bill_calc/security"
|
||||||
|
"electricity_bill_calc/service"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitializeGodModeController(router *fiber.App) {
|
||||||
|
gmR := router.Group("/gm")
|
||||||
|
{
|
||||||
|
gmR.Delete("/report/:rid/summary", security.SingularityAuthorize, gmResetReportSummary)
|
||||||
|
gmR.Delete("/report/:rid/maintenance", security.SingularityAuthorize, gmResetReportMaintenance)
|
||||||
|
gmR.Delete("/report/:rid/meters", security.SingularityAuthorize, gmResetReportEndUserRecord)
|
||||||
|
gmR.Post("/report/:rid/meters", security.SingularityAuthorize, gmResynchronizeReportEndUserRecord)
|
||||||
|
gmR.Delete("/report/:rid", security.SingularityAuthorize, gmResetReport)
|
||||||
|
gmR.Delete("/report/:rid/force", security.SingularityAuthorize, gmDeleteReport)
|
||||||
|
gmR.Delete("/park/:pid/maintenance/:mid", security.SingularityAuthorize, gmDeleteSpecificMaintenance)
|
||||||
|
gmR.Delete("/park/:pid/maintenance", security.SingularityAuthorize, gmDeleteAllMaintenance)
|
||||||
|
gmR.Delete("/park/:pid/meters", security.SingularityAuthorize, gmDeleteAllMeters)
|
||||||
|
gmR.Delete("/park/:pid/force", security.SingularityAuthorize, gmDeletePark)
|
||||||
|
gmR.Delete("/enterprise/:uid/force", security.SingularityAuthorize, gmDeleteUser)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func gmResetReportSummary(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
requestReportId := c.Params("rid")
|
||||||
|
done, err := service.GodModeService.ClearReportSummary(requestReportId)
|
||||||
|
if err != nil {
|
||||||
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
if !done {
|
||||||
|
return result.Error(http.StatusInternalServerError, "未能成功重置指定报表的园区总览部分。")
|
||||||
|
}
|
||||||
|
return result.Success("指定报表的园区总览已经重置。")
|
||||||
|
}
|
||||||
|
|
||||||
|
func gmResetReportMaintenance(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
requestReportId := c.Params("rid")
|
||||||
|
done, err := service.GodModeService.ClearReportMaintenances(requestReportId)
|
||||||
|
if err != nil {
|
||||||
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
if !done {
|
||||||
|
return result.Error(http.StatusInternalServerError, "未能成功重置指定报表的配电维护费部分。")
|
||||||
|
}
|
||||||
|
return result.Success("指定报表的配电维护费已经重置。")
|
||||||
|
}
|
||||||
|
|
||||||
|
func gmResynchronizeReportEndUserRecord(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
requestReportId := c.Params("rid")
|
||||||
|
done, err := service.GodModeService.ResynchronizeEndUser(requestReportId)
|
||||||
|
if err != nil {
|
||||||
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
if !done {
|
||||||
|
return result.Error(http.StatusInternalServerError, "未能成功重置指定报表的抄表记录基本档案。")
|
||||||
|
}
|
||||||
|
return result.Success("指定报表的抄表记录基本档案已经重新同步。")
|
||||||
|
}
|
||||||
|
|
||||||
|
func gmResetReportEndUserRecord(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
requestReportId := c.Params("rid")
|
||||||
|
done, err := service.GodModeService.ResetEndUserRegisterRecords(requestReportId)
|
||||||
|
if err != nil {
|
||||||
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
if !done {
|
||||||
|
return result.Error(http.StatusInternalServerError, "未能成功重置指定报表的抄表记录部分。")
|
||||||
|
}
|
||||||
|
return result.Success("指定报表的抄表记录已经重置。")
|
||||||
|
}
|
||||||
|
|
||||||
|
func gmResetReport(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
requestReportId := c.Params("rid")
|
||||||
|
done, err := service.GodModeService.ResetReport(requestReportId)
|
||||||
|
if err != nil {
|
||||||
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
if !done {
|
||||||
|
return result.Error(http.StatusInternalServerError, "未能成功重置指定报表。")
|
||||||
|
}
|
||||||
|
return result.Success("指定报表已经重置。")
|
||||||
|
}
|
||||||
|
|
||||||
|
func gmDeleteReport(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
requestReportId := c.Params("rid")
|
||||||
|
done, err := service.GodModeService.DeleteReport(requestReportId)
|
||||||
|
if err != nil {
|
||||||
|
if ipErr, ok := err.(exceptions.ImproperOperateError); ok {
|
||||||
|
return result.NotAccept(ipErr.Message)
|
||||||
|
} else {
|
||||||
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !done {
|
||||||
|
return result.Error(http.StatusInternalServerError, "未能成功删除指定报表。")
|
||||||
|
}
|
||||||
|
return result.Success("指定报表已经删除。")
|
||||||
|
}
|
||||||
|
|
||||||
|
func gmDeleteSpecificMaintenance(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
requestParkId := c.Params("pid")
|
||||||
|
requestMaintenanceId := c.Params("mid")
|
||||||
|
done, err := service.GodModeService.RemoveSpecificMaintenance(requestParkId, requestMaintenanceId)
|
||||||
|
if err != nil {
|
||||||
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
if !done {
|
||||||
|
return result.Error(http.StatusInternalServerError, "未能成功删除指定的维护费用记录。")
|
||||||
|
}
|
||||||
|
return result.Success("指定维护费用记录已经删除。")
|
||||||
|
}
|
||||||
|
|
||||||
|
func gmDeleteAllMaintenance(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
requestParkId := c.Params("pid")
|
||||||
|
done, err := service.GodModeService.RemoveAllMaintenance(requestParkId)
|
||||||
|
if err != nil {
|
||||||
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
if !done {
|
||||||
|
return result.Error(http.StatusInternalServerError, "未能成功删除全部维护费用记录。")
|
||||||
|
}
|
||||||
|
return result.Success("全部维护费用记录已经删除。")
|
||||||
|
}
|
||||||
|
|
||||||
|
func gmDeleteAllMeters(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
requestParkId := c.Params("pid")
|
||||||
|
done, err := service.GodModeService.RemoveAllMeters(requestParkId)
|
||||||
|
if err != nil {
|
||||||
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
if !done {
|
||||||
|
return result.Error(http.StatusInternalServerError, "未能成功删除全部终端表计档案记录。")
|
||||||
|
}
|
||||||
|
return result.Success("全部终端表计档案记录已经删除。")
|
||||||
|
}
|
||||||
|
|
||||||
|
func gmDeletePark(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
requestParkId := c.Params("pid")
|
||||||
|
done, err := service.GodModeService.RemovePark(requestParkId)
|
||||||
|
if err != nil {
|
||||||
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
if !done {
|
||||||
|
return result.Error(http.StatusInternalServerError, "未能成功删除指定的园区。")
|
||||||
|
}
|
||||||
|
return result.Success("指定的园区已经删除。")
|
||||||
|
}
|
||||||
|
|
||||||
|
func gmDeleteUser(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
requestUserId := c.Params("uid")
|
||||||
|
done, err := service.GodModeService.DeleteUser(requestUserId)
|
||||||
|
if err != nil {
|
||||||
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
if !done {
|
||||||
|
return result.Error(http.StatusInternalServerError, "未能成功删除指定的用户。")
|
||||||
|
}
|
||||||
|
return result.Success("指定的用户及其关联信息已经删除。")
|
||||||
|
}
|
||||||
+110
-61
@@ -6,93 +6,108 @@ import (
|
|||||||
"electricity_bill_calc/security"
|
"electricity_bill_calc/security"
|
||||||
"electricity_bill_calc/service"
|
"electricity_bill_calc/service"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
|
"github.com/samber/lo"
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitializeMaintenanceFeeController(router *gin.Engine) {
|
func InitializeMaintenanceFeeController(router *fiber.App) {
|
||||||
router.GET("/maintenance/fee", security.EnterpriseAuthorize, listMaintenanceFees)
|
router.Get("/maintenance/fee", security.MustAuthenticated, listMaintenanceFees)
|
||||||
router.POST("/maintenance/fee", security.EnterpriseAuthorize, createMaintenanceFeeRecord)
|
router.Post("/maintenance/fee", security.EnterpriseAuthorize, createMaintenanceFeeRecord)
|
||||||
router.PUT("/maintenance/fee/:mid", security.EnterpriseAuthorize, modifyMaintenanceFeeRecord)
|
router.Put("/maintenance/fee/:mid", security.EnterpriseAuthorize, modifyMaintenanceFeeRecord)
|
||||||
router.PUT("/maintenance/fee/:mid/enabled", security.EnterpriseAuthorize, changeMaintenanceFeeState)
|
router.Put("/maintenance/fee/:mid/enabled", security.EnterpriseAuthorize, changeMaintenanceFeeState)
|
||||||
router.DELETE("/maintenance/fee/:mid", security.EnterpriseAuthorize, deleteMaintenanceFee)
|
router.Delete("/maintenance/fee/:mid", security.EnterpriseAuthorize, deleteMaintenanceFee)
|
||||||
|
router.Get("/additional/charges", security.MustAuthenticated, statAdditionalCharges)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ensureMaintenanceFeeBelongs(c *gin.Context, result *response.Result, requestMaintenanceFeeId string) bool {
|
func ensureMaintenanceFeeBelongs(c *fiber.Ctx, result *response.Result, requestMaintenanceFeeId string) (bool, error) {
|
||||||
userSession, err := _retreiveSession(c)
|
userSession, err := _retreiveSession(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Unauthorized(err.Error())
|
return false, result.Unauthorized(err.Error())
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
sure, err := service.MaintenanceFeeService.EnsureFeeBelongs(userSession.Uid, requestMaintenanceFeeId)
|
sure, err := service.MaintenanceFeeService.EnsureFeeBelongs(userSession.Uid, requestMaintenanceFeeId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return false, result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
if !sure {
|
if !sure {
|
||||||
result.Unauthorized("所操作维护费记录不属于当前用户。")
|
return false, result.Unauthorized("所操作维护费记录不属于当前用户。")
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
return true
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func listMaintenanceFees(c *gin.Context) {
|
func listMaintenanceFees(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
userSession, err := _retreiveSession(c)
|
userSession, err := _retreiveSession(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Unauthorized(err.Error())
|
return result.Unauthorized(err.Error())
|
||||||
return
|
}
|
||||||
|
requestPark := c.Query("park")
|
||||||
|
requestPeriod := c.Query("period")
|
||||||
|
requestPage, err := strconv.Atoi(c.Query("page", "1"))
|
||||||
|
if err != nil {
|
||||||
|
return result.Error(http.StatusInternalServerError, "不能解析给定的参数[page]。")
|
||||||
}
|
}
|
||||||
requestPark := c.DefaultQuery("park", "")
|
|
||||||
if len(requestPark) > 0 {
|
if len(requestPark) > 0 {
|
||||||
if !ensureParkBelongs(c, result, requestPark) {
|
if userSession.Type == model.USER_TYPE_ENT {
|
||||||
return
|
if ensure, err := ensureParkBelongs(c, &result, requestPark); !ensure {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fees, err := service.MaintenanceFeeService.ListMaintenanceFees([]string{requestPark})
|
fees, total, err := service.MaintenanceFeeService.ListMaintenanceFees([]string{requestPark}, requestPeriod, requestPage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(http.StatusOK, "已获取指定园区下的维护费记录", gin.H{"fees": fees})
|
return result.Json(
|
||||||
|
http.StatusOK,
|
||||||
|
"已获取指定园区下的维护费记录",
|
||||||
|
response.NewPagedResponse(requestPage, total).ToMap(),
|
||||||
|
fiber.Map{"fees": fees},
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
parkIds, err := service.ParkService.AllParkIds(userSession.Uid)
|
parkIds, err := service.ParkService.AllParkIds(userSession.Uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
fees, err := service.MaintenanceFeeService.ListMaintenanceFees(parkIds)
|
fees, total, err := service.MaintenanceFeeService.ListMaintenanceFees(parkIds, requestPeriod, requestPage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(http.StatusOK, "已获取指定用户下的所有维护费记录。", gin.H{"fees": fees})
|
return result.Json(
|
||||||
|
http.StatusOK,
|
||||||
|
"已获取指定用户下的所有维护费记录。",
|
||||||
|
response.NewPagedResponse(requestPage, total).ToMap(),
|
||||||
|
fiber.Map{"fees": fees},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type _FeeCreationFormData struct {
|
type _FeeCreationFormData struct {
|
||||||
ParkId string `json:"parkId" form:"parkId"`
|
ParkId string `json:"parkId" form:"parkId"`
|
||||||
Name string `json:"name" form:"name"`
|
Name string `json:"name" form:"name"`
|
||||||
|
Period string `json:"period" form:"period"`
|
||||||
Fee decimal.Decimal `json:"fee" form:"fee"`
|
Fee decimal.Decimal `json:"fee" form:"fee"`
|
||||||
Memo *string `json:"memo" form:"memo"`
|
Memo *string `json:"memo" form:"memo"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMaintenanceFeeRecord(c *gin.Context) {
|
func createMaintenanceFeeRecord(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
formData := new(_FeeCreationFormData)
|
formData := new(_FeeCreationFormData)
|
||||||
c.BindJSON(formData)
|
if err := c.BodyParser(formData); err != nil {
|
||||||
if !ensureParkBelongs(c, result, formData.ParkId) {
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
return
|
}
|
||||||
|
if ensure, err := ensureParkBelongs(c, &result, formData.ParkId); !ensure {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
newMaintenanceFee := &model.MaintenanceFee{}
|
newMaintenanceFee := &model.MaintenanceFee{}
|
||||||
copier.Copy(newMaintenanceFee, formData)
|
copier.Copy(newMaintenanceFee, formData)
|
||||||
err := service.MaintenanceFeeService.CreateMaintenanceFeeRecord(*newMaintenanceFee)
|
err := service.MaintenanceFeeService.CreateMaintenanceFeeRecord(*newMaintenanceFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Created("新维护费记录已经创建。")
|
return result.Created("新维护费记录已经创建。")
|
||||||
}
|
}
|
||||||
|
|
||||||
type _FeeModificationFormData struct {
|
type _FeeModificationFormData struct {
|
||||||
@@ -100,54 +115,88 @@ type _FeeModificationFormData struct {
|
|||||||
Memo *string `json:"memo" form:"memo"`
|
Memo *string `json:"memo" form:"memo"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func modifyMaintenanceFeeRecord(c *gin.Context) {
|
func modifyMaintenanceFeeRecord(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestFee := c.Param("mid")
|
requestFee := c.Params("mid")
|
||||||
formData := new(_FeeModificationFormData)
|
formData := new(_FeeModificationFormData)
|
||||||
c.BindJSON(formData)
|
if err := c.BodyParser(formData); err != nil {
|
||||||
if !ensureMaintenanceFeeBelongs(c, result, requestFee) {
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
return
|
}
|
||||||
|
if ensure, err := ensureMaintenanceFeeBelongs(c, &result, requestFee); !ensure {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
newFeeState := new(model.MaintenanceFee)
|
newFeeState := new(model.MaintenanceFee)
|
||||||
copier.Copy(newFeeState, formData)
|
copier.Copy(newFeeState, formData)
|
||||||
|
newFeeState.Id = requestFee
|
||||||
err := service.MaintenanceFeeService.ModifyMaintenanceFee(*newFeeState)
|
err := service.MaintenanceFeeService.ModifyMaintenanceFee(*newFeeState)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Updated("指定维护费条目已更新。")
|
return result.Updated("指定维护费条目已更新。")
|
||||||
}
|
}
|
||||||
|
|
||||||
type _FeeStateFormData struct {
|
type _FeeStateFormData struct {
|
||||||
Enabled bool `json:"enabled" form:"enabled"`
|
Enabled bool `json:"enabled" form:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func changeMaintenanceFeeState(c *gin.Context) {
|
func changeMaintenanceFeeState(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestFee := c.Param("mid")
|
requestFee := c.Params("mid")
|
||||||
formData := new(_FeeStateFormData)
|
formData := new(_FeeStateFormData)
|
||||||
c.BindJSON(formData)
|
if err := c.BodyParser(formData); err != nil {
|
||||||
if !ensureMaintenanceFeeBelongs(c, result, requestFee) {
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
return
|
}
|
||||||
|
if ensure, err := ensureMaintenanceFeeBelongs(c, &result, requestFee); !ensure {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
err := service.MaintenanceFeeService.ChangeMaintenanceFeeState(requestFee, formData.Enabled)
|
err := service.MaintenanceFeeService.ChangeMaintenanceFeeState(requestFee, formData.Enabled)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Updated("指定维护费条目状态已更新。")
|
return result.Updated("指定维护费条目状态已更新。")
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteMaintenanceFee(c *gin.Context) {
|
func deleteMaintenanceFee(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestFee := c.Param("mid")
|
requestFee := c.Params("mid")
|
||||||
if !ensureMaintenanceFeeBelongs(c, result, requestFee) {
|
if ensure, err := ensureMaintenanceFeeBelongs(c, &result, requestFee); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
err := service.MaintenanceFeeService.DeleteMaintenanceFee(requestFee)
|
err := service.MaintenanceFeeService.DeleteMaintenanceFee(requestFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Deleted("指定维护费条目已删除。")
|
return result.Deleted("指定维护费条目已删除。")
|
||||||
|
}
|
||||||
|
|
||||||
|
func statAdditionalCharges(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
session, err := _retreiveSession(c)
|
||||||
|
if err != nil {
|
||||||
|
return result.Unauthorized(err.Error())
|
||||||
|
}
|
||||||
|
requestUser := lo.
|
||||||
|
If(session.Type == model.USER_TYPE_ENT, session.Uid).
|
||||||
|
Else(c.Query("user"))
|
||||||
|
requestPark := c.Query("park")
|
||||||
|
if len(requestPark) > 0 && session.Type == model.USER_TYPE_ENT {
|
||||||
|
if ensure, err := ensureParkBelongs(c, &result, requestPark); !ensure {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
period := c.Query("period", "")
|
||||||
|
keyword := c.Query("keyword", "")
|
||||||
|
requestPage, err := strconv.Atoi(c.Query("page", "1"))
|
||||||
|
if err != nil {
|
||||||
|
return result.Error(http.StatusInternalServerError, "不能解析给定的参数[page]。")
|
||||||
|
}
|
||||||
|
fees, total, err := service.MaintenanceFeeService.QueryAdditionalCharges(requestUser, requestPark, period, keyword, requestPage)
|
||||||
|
if err != nil {
|
||||||
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
return result.Success(
|
||||||
|
"已经成功获取到物业附加费的统计记录。",
|
||||||
|
response.NewPagedResponse(requestPage, total).ToMap(),
|
||||||
|
fiber.Map{"charges": fees},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+66
-84
@@ -7,84 +7,72 @@ import (
|
|||||||
"electricity_bill_calc/security"
|
"electricity_bill_calc/security"
|
||||||
"electricity_bill_calc/service"
|
"electricity_bill_calc/service"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitializeMeter04kVController(router *gin.Engine) {
|
func InitializeMeter04kVController(router *fiber.App) {
|
||||||
router.GET("/park/:pid/meter/template", download04kvMeterArchiveTemplate)
|
router.Get("/park/:pid/meter/template", download04kvMeterArchiveTemplate)
|
||||||
router.GET("/park/:pid/meters", security.EnterpriseAuthorize, ListPaged04kVMeter)
|
router.Get("/park/:pid/meters", security.EnterpriseAuthorize, ListPaged04kVMeter)
|
||||||
router.GET("/park/:pid/meter/:code", security.EnterpriseAuthorize, fetch04kVMeterDetail)
|
router.Get("/park/:pid/meter/:code", security.EnterpriseAuthorize, fetch04kVMeterDetail)
|
||||||
router.POST("/park/:pid/meter", security.EnterpriseAuthorize, createSingle04kVMeter)
|
router.Post("/park/:pid/meter", security.EnterpriseAuthorize, createSingle04kVMeter)
|
||||||
router.PUT("/park/:pid/meter/:code", security.EnterpriseAuthorize, modifySingle04kVMeter)
|
router.Post("/park/:pid/meter/batch", security.EnterpriseAuthorize, batchImport04kVMeterArchive)
|
||||||
router.POST("/park/:pid/meter/batch", security.EnterpriseAuthorize, batchImport04kVMeterArchive)
|
router.Put("/park/:pid/meter/:code", security.EnterpriseAuthorize, modifySingle04kVMeter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func download04kvMeterArchiveTemplate(c *gin.Context) {
|
func download04kvMeterArchiveTemplate(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestParkId := c.Param("pid")
|
requestParkId := c.Params("pid")
|
||||||
// if !ensureParkBelongs(c, result, requestParkId) {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
parkDetail, err := service.ParkService.FetchParkDetail(requestParkId)
|
parkDetail, err := service.ParkService.FetchParkDetail(requestParkId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound("未找到指定的园区信息。")
|
return result.NotFound("未找到指定的园区信息。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
c.Status(http.StatusOK)
|
return c.Download("./assets/meter_04kv_template.xlsx", fmt.Sprintf("%s-户表档案.xlsx", parkDetail.Name))
|
||||||
c.Header("Content-Type", "application/octet-stream")
|
|
||||||
c.Header("Content-Transfer-Encoding", "binary")
|
|
||||||
c.FileAttachment("./assets/meter_04kv_template.xlsx", fmt.Sprintf("%s-户表档案.xlsx", parkDetail.Name))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListPaged04kVMeter(c *gin.Context) {
|
func ListPaged04kVMeter(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestParkId := c.Param("pid")
|
requestParkId := c.Params("pid")
|
||||||
if !ensureParkBelongs(c, result, requestParkId) {
|
if ensure, err := ensureParkBelongs(c, &result, requestParkId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
requestPage, err := strconv.Atoi(c.DefaultQuery("page", "1"))
|
requestPage, err := strconv.Atoi(c.Query("page", "1"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotAccept("查询参数[page]格式不正确。")
|
return result.NotAccept("查询参数[page]格式不正确。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
requestKeyword := c.DefaultQuery("keyword", "")
|
requestKeyword := c.Query("keyword", "")
|
||||||
meters, totalItem, err := service.Meter04kVService.ListMeterDetail(requestParkId, requestKeyword, requestPage)
|
meters, totalItem, err := service.Meter04kVService.ListMeterDetail(requestParkId, requestKeyword, requestPage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return result.NotFound(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(
|
return result.Json(
|
||||||
http.StatusOK,
|
http.StatusOK,
|
||||||
"已获取到符合条件的0.4kV表计集合。",
|
"已获取到符合条件的0.4kV表计集合。",
|
||||||
response.NewPagedResponse(requestPage, totalItem).ToMap(),
|
response.NewPagedResponse(requestPage, totalItem).ToMap(),
|
||||||
gin.H{"meters": meters},
|
fiber.Map{"meters": meters},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetch04kVMeterDetail(c *gin.Context) {
|
func fetch04kVMeterDetail(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestParkId := c.Param("pid")
|
requestParkId := c.Params("pid")
|
||||||
if !ensureParkBelongs(c, result, requestParkId) {
|
if ensure, err := ensureParkBelongs(c, &result, requestParkId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
requestMeterCode := c.Param("code")
|
requestMeterCode := c.Params("code")
|
||||||
meter, err := service.Meter04kVService.Get04kVMeterDetail(requestParkId, requestMeterCode)
|
meter, err := service.Meter04kVService.Get04kVMeterDetail(requestParkId, requestMeterCode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return result.NotFound(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if meter == nil {
|
if meter == nil {
|
||||||
result.Json(http.StatusNotFound, "指定的表计信息未能找到。", gin.H{"meter": nil})
|
return result.Json(http.StatusNotFound, "指定的表计信息未能找到。", fiber.Map{"meter": nil})
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(http.StatusOK, "指定的表计信息已找到。", gin.H{"meter": meter})
|
return result.Json(http.StatusOK, "指定的表计信息已找到。", fiber.Map{"meter": meter})
|
||||||
}
|
}
|
||||||
|
|
||||||
type _MeterModificationFormData struct {
|
type _MeterModificationFormData struct {
|
||||||
@@ -95,7 +83,6 @@ type _MeterModificationFormData struct {
|
|||||||
Ratio decimal.Decimal `json:"ratio" form:"ratio"`
|
Ratio decimal.Decimal `json:"ratio" form:"ratio"`
|
||||||
Seq int `json:"seq" form:"seq"`
|
Seq int `json:"seq" form:"seq"`
|
||||||
IsPublicMeter bool `json:"isPublicMeter" form:"isPublicMeter"`
|
IsPublicMeter bool `json:"isPublicMeter" form:"isPublicMeter"`
|
||||||
WillDilute bool `json:"willDilute" form:"willDilute"`
|
|
||||||
Enabled bool `json:"enabled" form:"enabled"`
|
Enabled bool `json:"enabled" form:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,83 +95,76 @@ type _MeterCreationFormData struct {
|
|||||||
Ratio decimal.Decimal `json:"ratio" form:"ratio"`
|
Ratio decimal.Decimal `json:"ratio" form:"ratio"`
|
||||||
Seq int `json:"seq" form:"seq"`
|
Seq int `json:"seq" form:"seq"`
|
||||||
IsPublicMeter bool `json:"isPublicMeter" form:"isPublicMeter"`
|
IsPublicMeter bool `json:"isPublicMeter" form:"isPublicMeter"`
|
||||||
WillDilute bool `json:"willDilute" form:"willDilute"`
|
|
||||||
Enabled bool `json:"enabled" form:"enabled"`
|
Enabled bool `json:"enabled" form:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSingle04kVMeter(c *gin.Context) {
|
func createSingle04kVMeter(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestParkId := c.Param("pid")
|
requestParkId := c.Params("pid")
|
||||||
if !ensureParkBelongs(c, result, requestParkId) {
|
if ensure, err := ensureParkBelongs(c, &result, requestParkId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
formData := new(_MeterCreationFormData)
|
formData := new(_MeterCreationFormData)
|
||||||
c.BindJSON(formData)
|
if err := c.BodyParser(formData); err != nil {
|
||||||
log.Printf("[controller|debug] form: %+v", formData)
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
|
}
|
||||||
newMeter := new(model.Meter04KV)
|
newMeter := new(model.Meter04KV)
|
||||||
copier.Copy(newMeter, formData)
|
copier.Copy(newMeter, formData)
|
||||||
newMeter.ParkId = requestParkId
|
newMeter.ParkId = requestParkId
|
||||||
log.Printf("[controller|debug] meter: %+v", newMeter)
|
|
||||||
err := service.Meter04kVService.CreateSingleMeter(*newMeter)
|
err := service.Meter04kVService.CreateSingleMeter(*newMeter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Created("新0.4kV表计已经添加完成。")
|
return result.Created("新0.4kV表计已经添加完成。")
|
||||||
}
|
}
|
||||||
|
|
||||||
func modifySingle04kVMeter(c *gin.Context) {
|
func modifySingle04kVMeter(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestParkId := c.Param("pid")
|
requestParkId := c.Params("pid")
|
||||||
if !ensureParkBelongs(c, result, requestParkId) {
|
if ensure, err := ensureParkBelongs(c, &result, requestParkId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
requestMeterCode := c.Param("code")
|
requestMeterCode := c.Params("code")
|
||||||
meterDetail, err := service.Meter04kVService.Get04kVMeterDetail(requestParkId, requestMeterCode)
|
meterDetail, err := service.Meter04kVService.Get04kVMeterDetail(requestParkId, requestMeterCode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return result.NotFound(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if meterDetail == nil {
|
if meterDetail == nil {
|
||||||
result.NotFound("指定表计的信息为找到,不能修改。")
|
return result.NotFound("指定表计的信息为找到,不能修改。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
formData := new(_MeterModificationFormData)
|
formData := new(_MeterModificationFormData)
|
||||||
c.BindJSON(formData)
|
if err := c.BodyParser(formData); err != nil {
|
||||||
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
|
}
|
||||||
copier.Copy(meterDetail, formData)
|
copier.Copy(meterDetail, formData)
|
||||||
err = service.Meter04kVService.UpdateSingleMeter(meterDetail)
|
err = service.Meter04kVService.UpdateSingleMeter(meterDetail)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Updated("指定0.4kV表计信息已经更新。")
|
return result.Updated("指定0.4kV表计信息已经更新。")
|
||||||
}
|
}
|
||||||
|
|
||||||
func batchImport04kVMeterArchive(c *gin.Context) {
|
func batchImport04kVMeterArchive(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestParkId := c.Param("pid")
|
requestParkId := c.Params("pid")
|
||||||
if !ensureParkBelongs(c, result, requestParkId) {
|
if ensure, err := ensureParkBelongs(c, &result, requestParkId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
uploadedFile, err := c.FormFile("data")
|
uploadedFile, err := c.FormFile("data")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotAccept("没有接收到上传的档案文件。")
|
return result.NotAccept("没有接收到上传的档案文件。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
archiveFile, err := uploadedFile.Open()
|
archiveFile, err := uploadedFile.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
analyzer, err := excel.NewMeterArchiveExcelAnalyzer(archiveFile)
|
analyzer, err := excel.NewMeterArchiveExcelAnalyzer(archiveFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
records, errs := analyzer.Analysis(*new(model.Meter04KV))
|
records, errs := analyzer.Analysis(*new(model.Meter04KV))
|
||||||
if len(errs) > 0 {
|
if len(errs) > 0 {
|
||||||
result.Json(http.StatusNotAcceptable, "上传的表计档案文件存在错误。", gin.H{"errors": errs})
|
return result.Json(http.StatusNotAcceptable, "上传的表计档案文件存在错误。", fiber.Map{"errors": errs})
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mergedMeters := lo.Map(records, func(meter model.Meter04KV, index int) model.Meter04KV {
|
mergedMeters := lo.Map(records, func(meter model.Meter04KV, index int) model.Meter04KV {
|
||||||
@@ -194,13 +174,15 @@ func batchImport04kVMeterArchive(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
errs = service.Meter04kVService.DuplicateMeterCodeValidate(mergedMeters)
|
errs = service.Meter04kVService.DuplicateMeterCodeValidate(mergedMeters)
|
||||||
if len(errs) > 0 {
|
if len(errs) > 0 {
|
||||||
result.Json(http.StatusNotAcceptable, "上传的表计档案文件存在错误。", gin.H{"errors": errs})
|
return result.Json(http.StatusNotAcceptable, "上传的表计档案文件存在错误。", fiber.Map{"errors": errs})
|
||||||
return
|
|
||||||
}
|
}
|
||||||
err = service.Meter04kVService.BatchCreateMeter(mergedMeters)
|
err = service.Meter04kVService.BatchCreateMeter(mergedMeters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(http.StatusOK, "上传的表计档案已经全部导入。", gin.H{"errors": make([]excel.ExcelAnalysisError, 0)})
|
return result.Json(
|
||||||
|
http.StatusOK,
|
||||||
|
"上传的表计档案已经全部导入。",
|
||||||
|
fiber.Map{"errors": make([]excel.ExcelAnalysisError, 0)},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+76
-84
@@ -8,88 +8,85 @@ import (
|
|||||||
"electricity_bill_calc/tools"
|
"electricity_bill_calc/tools"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitializeParkController(router *gin.Engine) {
|
func InitializeParkController(router *fiber.App) {
|
||||||
router.GET("/parks", security.EnterpriseAuthorize, listAllParksUnderSessionUser)
|
router.Get("/parks", security.EnterpriseAuthorize, listAllParksUnderSessionUser)
|
||||||
router.GET("/parks/:uid", security.MustAuthenticated, listAllParksUnderSpecificUser)
|
router.Get("/parks/:uid", security.MustAuthenticated, listAllParksUnderSpecificUser)
|
||||||
router.POST("/park", security.EnterpriseAuthorize, createNewPark)
|
router.Post("/park", security.EnterpriseAuthorize, createNewPark)
|
||||||
router.PUT("/park/:pid", security.EnterpriseAuthorize, modifyPark)
|
router.Put("/park/:pid", security.EnterpriseAuthorize, modifyPark)
|
||||||
router.GET("/park/:pid", security.EnterpriseAuthorize, fetchParkDetail)
|
router.Get("/park/:pid", security.EnterpriseAuthorize, fetchParkDetail)
|
||||||
router.PUT("/park/:pid/enabled", security.EnterpriseAuthorize, changeParkEnableState)
|
router.Put("/park/:pid/enabled", security.EnterpriseAuthorize, changeParkEnableState)
|
||||||
router.DELETE("/park/:pid", security.EnterpriseAuthorize, deleteSpecificPark)
|
router.Delete("/park/:pid", security.EnterpriseAuthorize, deleteSpecificPark)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ensureParkBelongs(c *gin.Context, result *response.Result, requestParkId string) bool {
|
func ensureParkBelongs(c *fiber.Ctx, result *response.Result, requestParkId string) (bool, error) {
|
||||||
userSession, err := _retreiveSession(c)
|
userSession, err := _retreiveSession(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Unauthorized(err.Error())
|
return false, result.Unauthorized(err.Error())
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
sure, err := service.ParkService.EnsurePark(userSession.Uid, requestParkId)
|
sure, err := service.ParkService.EnsurePark(userSession.Uid, requestParkId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return false, result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
if !sure {
|
if !sure {
|
||||||
result.Unauthorized("不能访问不属于自己的园区。")
|
return false, result.Unauthorized("不能访问不属于自己的园区。")
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
return true
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func listAllParksUnderSessionUser(c *gin.Context) {
|
func listAllParksUnderSessionUser(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
userSession, err := _retreiveSession(c)
|
userSession, err := _retreiveSession(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Unauthorized(err.Error())
|
return result.Unauthorized(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
parks, err := service.ParkService.ListAllParkBelongsTo(userSession.Uid)
|
keyword := c.Query("keyword")
|
||||||
|
parks, err := service.ParkService.ListAllParkBelongsTo(userSession.Uid, keyword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(http.StatusOK, "已获取到指定用户下的园区。", gin.H{"parks": parks})
|
return result.Json(http.StatusOK, "已获取到指定用户下的园区。", fiber.Map{"parks": parks})
|
||||||
}
|
}
|
||||||
|
|
||||||
func listAllParksUnderSpecificUser(c *gin.Context) {
|
func listAllParksUnderSpecificUser(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestUserId := c.Param("uid")
|
requestUserId := c.Params("uid")
|
||||||
parks, err := service.ParkService.ListAllParkBelongsTo(requestUserId)
|
keyword := c.Query("keyword")
|
||||||
|
parks, err := service.ParkService.ListAllParkBelongsTo(requestUserId, keyword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(http.StatusOK, "已获取到指定用户下的园区。", gin.H{"parks": parks})
|
return result.Json(http.StatusOK, "已获取到指定用户下的园区。", fiber.Map{"parks": parks})
|
||||||
}
|
}
|
||||||
|
|
||||||
type _ParkInfoFormData struct {
|
type _ParkInfoFormData struct {
|
||||||
Name string `json:"name" form:"name"`
|
Name string `json:"name" form:"name"`
|
||||||
Region *string `json:"region" form:"region"`
|
Region *string `json:"region" form:"region"`
|
||||||
Address *string `json:"address" form:"address"`
|
Address *string `json:"address" form:"address"`
|
||||||
Contact *string `json:"contact" form:"contact"`
|
Contact *string `json:"contact" form:"contact"`
|
||||||
Phone *string `json:"phone" from:"phone"`
|
Phone *string `json:"phone" from:"phone"`
|
||||||
Area decimal.NullDecimal `json:"area" from:"area"`
|
Area decimal.NullDecimal `json:"area" from:"area"`
|
||||||
Capacity decimal.NullDecimal `json:"capacity" from:"capacity"`
|
Capacity decimal.NullDecimal `json:"capacity" from:"capacity"`
|
||||||
Tenement decimal.NullDecimal `json:"tenement" from:"tenement"`
|
TenementQuantity decimal.NullDecimal `json:"tenement" from:"tenement"`
|
||||||
Category int `json:"category" form:"category"`
|
Category int8 `json:"category" form:"category"`
|
||||||
Submeter int `json:"submeter" form:"submeter"`
|
SubmeterType int8 `json:"submeter" form:"submeter"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func createNewPark(c *gin.Context) {
|
func createNewPark(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
userSession, err := _retreiveSession(c)
|
userSession, err := _retreiveSession(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Unauthorized(err.Error())
|
return result.Unauthorized(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
formData := new(_ParkInfoFormData)
|
formData := new(_ParkInfoFormData)
|
||||||
c.BindJSON(formData)
|
if err := c.BodyParser(formData); err != nil {
|
||||||
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
|
}
|
||||||
newPark := new(model.Park)
|
newPark := new(model.Park)
|
||||||
copier.Copy(newPark, formData)
|
copier.Copy(newPark, formData)
|
||||||
newPark.Id = uuid.New().String()
|
newPark.Id = uuid.New().String()
|
||||||
@@ -99,95 +96,90 @@ func createNewPark(c *gin.Context) {
|
|||||||
newPark.Enabled = true
|
newPark.Enabled = true
|
||||||
err = service.ParkService.SaveNewPark(*newPark)
|
err = service.ParkService.SaveNewPark(*newPark)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Created("新园区完成创建。")
|
return result.Created("新园区完成创建。")
|
||||||
}
|
}
|
||||||
|
|
||||||
func modifyPark(c *gin.Context) {
|
func modifyPark(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
userSession, err := _retreiveSession(c)
|
userSession, err := _retreiveSession(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Unauthorized(err.Error())
|
return result.Unauthorized(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
requestParkId := c.Param("pid")
|
requestParkId := c.Params("pid")
|
||||||
formData := new(_ParkInfoFormData)
|
formData := new(_ParkInfoFormData)
|
||||||
c.BindJSON(formData)
|
if err := c.BodyParser(formData); err != nil {
|
||||||
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
|
}
|
||||||
park, err := service.ParkService.FetchParkDetail(requestParkId)
|
park, err := service.ParkService.FetchParkDetail(requestParkId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if userSession.Uid != park.UserId {
|
if userSession.Uid != park.UserId {
|
||||||
result.Unauthorized("不能修改不属于自己的园区。")
|
return result.Unauthorized("不能修改不属于自己的园区。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
copier.Copy(park, formData)
|
copier.Copy(park, formData)
|
||||||
nameAbbr := tools.PinyinAbbr(formData.Name)
|
nameAbbr := tools.PinyinAbbr(formData.Name)
|
||||||
park.Abbr = &nameAbbr
|
park.Abbr = &nameAbbr
|
||||||
err = service.ParkService.UpdateParkInfo(park)
|
err = service.ParkService.UpdateParkInfo(park)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Updated("指定园区资料已更新。")
|
return result.Updated("指定园区资料已更新。")
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchParkDetail(c *gin.Context) {
|
func fetchParkDetail(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestParkId := c.Param("pid")
|
requestParkId := c.Params("pid")
|
||||||
if !ensureParkBelongs(c, result, requestParkId) {
|
if ensure, err := ensureParkBelongs(c, &result, requestParkId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
park, err := service.ParkService.FetchParkDetail(requestParkId)
|
park, err := service.ParkService.FetchParkDetail(requestParkId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(http.StatusOK, "已经获取到指定园区的信息。", gin.H{"park": park})
|
return result.Json(http.StatusOK, "已经获取到指定园区的信息。", fiber.Map{"park": park})
|
||||||
}
|
}
|
||||||
|
|
||||||
type _ParkStateFormData struct {
|
type _ParkStateFormData struct {
|
||||||
Enabled bool `json:"enabled" form:"enabled"`
|
Enabled bool `json:"enabled" form:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func changeParkEnableState(c *gin.Context) {
|
func changeParkEnableState(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
userSession, err := _retreiveSession(c)
|
userSession, err := _retreiveSession(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Unauthorized(err.Error())
|
return result.Unauthorized(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
requestParkId := c.Param("pid")
|
requestParkId := c.Params("pid")
|
||||||
if !ensureParkBelongs(c, result, requestParkId) {
|
if ensure, err := ensureParkBelongs(c, &result, requestParkId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
formData := new(_ParkStateFormData)
|
formData := new(_ParkStateFormData)
|
||||||
c.BindJSON(formData)
|
if err := c.BodyParser(formData); err != nil {
|
||||||
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
|
}
|
||||||
err = service.ParkService.ChangeParkState(userSession.Uid, requestParkId, formData.Enabled)
|
err = service.ParkService.ChangeParkState(userSession.Uid, requestParkId, formData.Enabled)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Updated("指定园区的可用性状态已成功更新。")
|
return result.Updated("指定园区的可用性状态已成功更新。")
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteSpecificPark(c *gin.Context) {
|
func deleteSpecificPark(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
userSession, err := _retreiveSession(c)
|
userSession, err := _retreiveSession(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Unauthorized(err.Error())
|
return result.Unauthorized(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
requestParkId := c.Param("pid")
|
requestParkId := c.Params("pid")
|
||||||
if !ensureParkBelongs(c, result, requestParkId) {
|
if ensure, err := ensureParkBelongs(c, &result, requestParkId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
err = service.ParkService.DeletePark(userSession.Uid, requestParkId)
|
err = service.ParkService.DeletePark(userSession.Uid, requestParkId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
}
|
}
|
||||||
result.Deleted("指定园区已成功删除。")
|
return result.Deleted("指定园区已成功删除。")
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-18
@@ -5,40 +5,36 @@ import (
|
|||||||
"electricity_bill_calc/service"
|
"electricity_bill_calc/service"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitializeRegionController(router *gin.Engine) {
|
func InitializeRegionController(router *fiber.App) {
|
||||||
router.GET("/region/:rid", fetchRegions)
|
router.Get("/region/:rid", fetchRegions)
|
||||||
router.GET("/regions/:rid", fetchAllLeveledRegions)
|
router.Get("/regions/:rid", fetchAllLeveledRegions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchRegions(c *gin.Context) {
|
func fetchRegions(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestParentId := c.Param("rid")
|
requestParentId := c.Params("rid")
|
||||||
regions, err := service.RegionService.FetchSubRegions(requestParentId)
|
regions, err := service.RegionService.FetchSubRegions(requestParentId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if len(regions) == 0 {
|
if len(regions) == 0 {
|
||||||
result.Json(http.StatusNotFound, "未能获取到相关的行政区划。", gin.H{"regions": make([]string, 0)})
|
return result.Json(http.StatusNotFound, "未能获取到相关的行政区划。", fiber.Map{"regions": make([]string, 0)})
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(http.StatusOK, "已经获取到相关的行政区划。", gin.H{"regions": regions})
|
return result.Json(http.StatusOK, "已经获取到相关的行政区划。", fiber.Map{"regions": regions})
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchAllLeveledRegions(c *gin.Context) {
|
func fetchAllLeveledRegions(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestRegionCode := c.Param("rid")
|
requestRegionCode := c.Params("rid")
|
||||||
regions, err := service.RegionService.FetchAllParentRegions(requestRegionCode)
|
regions, err := service.RegionService.FetchAllParentRegions(requestRegionCode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if len(regions) == 0 {
|
if len(regions) == 0 {
|
||||||
result.Json(http.StatusNotFound, "未能获取到相关的行政区划。", gin.H{"regions": make([]string, 0)})
|
return result.Json(http.StatusNotFound, "未能获取到相关的行政区划。", fiber.Map{"regions": make([]string, 0)})
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(http.StatusOK, "以及获取到相关的行政区划。", gin.H{"regions": regions})
|
return result.Json(http.StatusOK, "以及获取到相关的行政区划。", fiber.Map{"regions": regions})
|
||||||
}
|
}
|
||||||
|
|||||||
+123
-300
@@ -7,136 +7,115 @@ import (
|
|||||||
"electricity_bill_calc/security"
|
"electricity_bill_calc/security"
|
||||||
"electricity_bill_calc/service"
|
"electricity_bill_calc/service"
|
||||||
"electricity_bill_calc/tools"
|
"electricity_bill_calc/tools"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fufuok/utils"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitializeReportController(router *gin.Engine) {
|
func InitializeReportController(router *fiber.App) {
|
||||||
router.GET("/reports/with/drafts", security.EnterpriseAuthorize, fetchNewestReportOfParkWithDraft)
|
router.Get("/reports/with/drafts", security.EnterpriseAuthorize, fetchNewestReportOfParkWithDraft)
|
||||||
router.POST("/park/:pid/report", security.EnterpriseAuthorize, initializeNewReport)
|
router.Post("/park/:pid/report", security.EnterpriseAuthorize, initializeNewReport)
|
||||||
router.GET("/report/:rid/step/state", security.EnterpriseAuthorize, fetchReportStepStates)
|
router.Get("/report/:rid/step/state", security.EnterpriseAuthorize, fetchReportStepStates)
|
||||||
router.GET("/report/:rid/summary", security.EnterpriseAuthorize, fetchReportParkSummary)
|
router.Get("/report/:rid/summary", security.EnterpriseAuthorize, fetchReportParkSummary)
|
||||||
router.PUT("/report/:rid/summary", security.EnterpriseAuthorize, fillReportSummary)
|
router.Put("/report/:rid/summary", security.EnterpriseAuthorize, fillReportSummary)
|
||||||
router.GET("/report/:rid/summary/calculate", security.EnterpriseAuthorize, testCalculateReportSummary)
|
router.Get("/report/:rid/summary/calculate", security.EnterpriseAuthorize, testCalculateReportSummary)
|
||||||
router.POST("/report/:rid/summary/calculate", security.EnterpriseAuthorize, progressReportSummary)
|
router.Post("/report/:rid/summary/calculate", security.EnterpriseAuthorize, progressReportSummary)
|
||||||
router.GET("/report/:rid/maintenance", security.EnterpriseAuthorize, fetchWillDilutedFees)
|
router.Put("/report/:rid/step/meter/register", security.EnterpriseAuthorize, progressEndUserRegister)
|
||||||
router.POST("/report/:rid/maintenance", security.EnterpriseAuthorize, createTemporaryWillDilutedFee)
|
router.Post("/report/:rid/publish", security.EnterpriseAuthorize, publishReport)
|
||||||
router.POST("/report/:rid/maintenance/import", security.EnterpriseAuthorize, importPredefinedMaintenanceFees)
|
router.Get("/reports", security.MustAuthenticated, searchReports)
|
||||||
router.PUT("/report/:rid/maintenance/:mid", security.EnterpriseAuthorize, modifyWillDilutedFee)
|
router.Get("/report/:rid", security.MustAuthenticated, fetchReportPublicity)
|
||||||
router.DELETE("/report/:rid/maintenance/:mid", security.EnterpriseAuthorize, deleteTemporaryWillDilutedFee)
|
router.Post("/report/:rid/calculate", security.EnterpriseAuthorize, calculateReport)
|
||||||
router.PUT("/report/:rid/step/diluted/fees", security.EnterpriseAuthorize, progressReportWillDilutedFee)
|
|
||||||
router.PUT("/report/:rid/step/meter/register", security.EnterpriseAuthorize, progressEndUserRegister)
|
|
||||||
router.POST("/report/:rid/publish", security.EnterpriseAuthorize, publishReport)
|
|
||||||
router.GET("/reports", security.MustAuthenticated, searchReports)
|
|
||||||
router.GET("/report/:rid", security.MustAuthenticated, fetchReportPublicity)
|
|
||||||
router.POST("/report/:rid/calculate", security.EnterpriseAuthorize, calculateReport)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ensureReportBelongs(c *gin.Context, result *response.Result, requestReportId string) bool {
|
func ensureReportBelongs(c *fiber.Ctx, result *response.Result, requestReportId string) (bool, error) {
|
||||||
_, err := _retreiveSession(c)
|
_, err := _retreiveSession(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Unauthorized(err.Error())
|
return false, result.Unauthorized(err.Error())
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
requestReport, err := service.ReportService.RetreiveReportIndex(requestReportId)
|
requestReport, err := service.ReportService.RetreiveReportIndex(requestReportId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return false, result.NotFound(err.Error())
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
if requestReport == nil {
|
if requestReport == nil {
|
||||||
result.NotFound("指定报表未能找到。")
|
return false, result.NotFound("指定报表未能找到。")
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
return ensureParkBelongs(c, result, requestReport.ParkId)
|
return ensureParkBelongs(c, result, requestReport.ParkId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchNewestReportOfParkWithDraft(c *gin.Context) {
|
func fetchNewestReportOfParkWithDraft(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
userSession, err := _retreiveSession(c)
|
userSession, err := _retreiveSession(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Unauthorized(err.Error())
|
return result.Unauthorized(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
parks, err := service.ReportService.FetchParksWithNewestReport(userSession.Uid)
|
parks, err := service.ReportService.FetchParksWithNewestReport(userSession.Uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(http.StatusOK, "已获取到指定用户下所有园区的最新报表记录。", gin.H{"parks": parks})
|
return result.Json(http.StatusOK, "已获取到指定用户下所有园区的最新报表记录。", fiber.Map{"parks": parks})
|
||||||
}
|
}
|
||||||
|
|
||||||
func initializeNewReport(c *gin.Context) {
|
func initializeNewReport(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestParkId := c.Param("pid")
|
requestParkId := c.Params("pid")
|
||||||
userSession, err := _retreiveSession(c)
|
userSession, err := _retreiveSession(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Unauthorized(err.Error())
|
return result.Unauthorized(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if !ensureParkBelongs(c, result, requestParkId) {
|
if ensure, err := ensureParkBelongs(c, &result, requestParkId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
requestPeriod := c.Query("period")
|
requestPeriod := c.Query("period")
|
||||||
reportPeriod, err := time.Parse("2006-01", requestPeriod)
|
reportPeriod, err := time.Parse("2006-01", requestPeriod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotAccept("提供的初始化期数格式不正确。")
|
return result.NotAccept("提供的初始化期数格式不正确。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
valid, err := service.ReportService.IsNewPeriodValid(userSession.Uid, reportPeriod)
|
valid, err := service.ReportService.IsNewPeriodValid(userSession.Uid, requestParkId, reportPeriod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if !valid {
|
if !valid {
|
||||||
result.NotAccept("只能初始化已发布报表下一个月份的新报表。")
|
return result.NotAccept("只能初始化已发布报表下一个月份的新报表。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
newId, err := service.ReportService.InitializeNewReport(requestParkId, reportPeriod)
|
newId, err := service.ReportService.InitializeNewReport(requestParkId, reportPeriod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Created("新一期报表初始化成功。", gin.H{"reportId": newId})
|
return result.Created("新一期报表初始化成功。", fiber.Map{"reportId": newId})
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchReportStepStates(c *gin.Context) {
|
func fetchReportStepStates(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestReportId := c.Param("rid")
|
requestReportId := c.Params("rid")
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
if ensure, err := ensureReportBelongs(c, &result, requestReportId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
requestReport, err := service.ReportService.RetreiveReportIndex(requestReportId)
|
requestReport, err := service.ReportService.RetreiveReportIndex(requestReportId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return result.NotFound(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(http.StatusOK, "已经获取到指定报表的填写状态。", gin.H{"steps": requestReport.StepState})
|
return result.Json(http.StatusOK, "已经获取到指定报表的填写状态。", fiber.Map{"steps": requestReport.StepState})
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchReportParkSummary(c *gin.Context) {
|
func fetchReportParkSummary(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestReportId := c.Param("rid")
|
requestReportId := c.Params("rid")
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
if ensure, err := ensureReportBelongs(c, &result, requestReportId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
summary, err := service.ReportService.RetreiveReportSummary(requestReportId)
|
summary, err := service.ReportService.RetreiveReportSummary(requestReportId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return result.NotFound(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if summary == nil {
|
if summary == nil {
|
||||||
result.NotFound("指定报表未能找到。")
|
return result.NotFound("指定报表未能找到。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(http.StatusOK, "已经获取到指定报表中的园区概况。", gin.H{"summary": summary})
|
return result.Json(http.StatusOK, "已经获取到指定报表中的园区概况。", fiber.Map{"summary": summary})
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReportSummaryFormData struct {
|
type ReportSummaryFormData struct {
|
||||||
@@ -152,327 +131,171 @@ type ReportSummaryFormData struct {
|
|||||||
AdjustFee decimal.Decimal `json:"adjustFee" from:"adjustFee"`
|
AdjustFee decimal.Decimal `json:"adjustFee" from:"adjustFee"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func fillReportSummary(c *gin.Context) {
|
func fillReportSummary(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestReportId := c.Param("rid")
|
requestReportId := c.Params("rid")
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
if ensure, err := ensureReportBelongs(c, &result, requestReportId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
formData := new(ReportSummaryFormData)
|
formData := new(ReportSummaryFormData)
|
||||||
c.BindJSON(formData)
|
if err := c.BodyParser(formData); err != nil {
|
||||||
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
|
}
|
||||||
originSummary, err := service.ReportService.RetreiveReportSummary(requestReportId)
|
originSummary, err := service.ReportService.RetreiveReportSummary(requestReportId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return result.NotFound(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
copier.Copy(originSummary, formData)
|
copier.Copy(originSummary, formData)
|
||||||
|
originSummary.ReportId = requestReportId
|
||||||
err = service.ReportService.UpdateReportSummary(originSummary)
|
err = service.ReportService.UpdateReportSummary(originSummary)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Updated("指定电费公示报表中的园区概况基本数据已经完成更新。")
|
return result.Updated("指定电费公示报表中的园区概况基本数据已经完成更新。")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCalculateReportSummary(c *gin.Context) {
|
func testCalculateReportSummary(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestReportId := c.Param("rid")
|
requestReportId := c.Params("rid")
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
if ensure, err := ensureReportBelongs(c, &result, requestReportId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
summary, err := service.ReportService.RetreiveReportSummary(requestReportId)
|
summary, err := service.ReportService.RetreiveReportSummary(requestReportId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return result.NotFound(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
summary.CalculatePrices()
|
summary.CalculatePrices()
|
||||||
calcResults := tools.ConvertStructToMap(summary)
|
calcResults := tools.ConvertStructToMap(summary)
|
||||||
result.Json(http.StatusOK, "已完成园区概况的试计算。", gin.H{"result": lo.PickByKeys(calcResults, []string{"overallPrice", "criticalPrice", "peakPrice", "flat", "flatFee", "flatPrice", "valleyPrice"})})
|
return result.Json(
|
||||||
|
http.StatusOK,
|
||||||
|
"已完成园区概况的试计算。",
|
||||||
|
fiber.Map{
|
||||||
|
"result": lo.PickByKeys(
|
||||||
|
calcResults,
|
||||||
|
[]string{"overallPrice", "criticalPrice", "peakPrice", "flat", "flatFee", "flatPrice", "valleyPrice", "consumptionFee"},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func progressReportSummary(c *gin.Context) {
|
func progressReportSummary(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestReportId := c.Param("rid")
|
requestReportId := c.Params("rid")
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
if ensure, err := ensureReportBelongs(c, &result, requestReportId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
err := service.ReportService.CalculateSummaryAndFinishStep(requestReportId)
|
err := service.ReportService.CalculateSummaryAndFinishStep(requestReportId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if nfErr, ok := err.(exceptions.NotFoundError); ok {
|
if nfErr, ok := err.(exceptions.NotFoundError); ok {
|
||||||
result.NotFound(nfErr.Error())
|
return result.NotFound(nfErr.Error())
|
||||||
} else {
|
} else {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Success("已经完成园区概况的计算,并可以进行到下一步骤。")
|
return result.Success("已经完成园区概况的计算,并可以进行到下一步骤。")
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchWillDilutedFees(c *gin.Context) {
|
func progressEndUserRegister(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestReportId := c.Param("rid")
|
requestReportId := c.Params("rid")
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
if ensure, err := ensureReportBelongs(c, &result, requestReportId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
|
||||||
fees, err := service.ReportService.FetchWillDulutedMaintenanceFees(requestReportId)
|
|
||||||
if err != nil {
|
|
||||||
result.NotFound(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
result.Json(http.StatusOK, "待摊薄费用已经获取到。", gin.H{"fees": fees})
|
|
||||||
}
|
|
||||||
|
|
||||||
type DilutedFeeCreationFormData struct {
|
|
||||||
ParkId string `json:"parkId" form:"parkId"`
|
|
||||||
Name string `json:"name" form:"name"`
|
|
||||||
Fee decimal.Decimal `json:"fee" form:"fee"`
|
|
||||||
Memo *string `json:"memo" form:"memo"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func createTemporaryWillDilutedFee(c *gin.Context) {
|
|
||||||
result := response.NewResult(c)
|
|
||||||
requestReportId := c.Param("rid")
|
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
formData := new(DilutedFeeCreationFormData)
|
|
||||||
c.BindJSON(formData)
|
|
||||||
report, err := service.ReportService.RetreiveReportIndex(requestReportId)
|
|
||||||
if err != nil {
|
|
||||||
result.NotFound(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if formData.ParkId != report.ParkId {
|
|
||||||
result.NotAccept("选择的园区与公示报表所属的园区不一致。")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
newWillDilutedFee := new(model.WillDilutedFee)
|
|
||||||
copier.Copy(newWillDilutedFee, formData)
|
|
||||||
newWillDilutedFee.ReportId = report.Id
|
|
||||||
err = service.ReportService.CreateTemporaryWillDilutedMaintenanceFee(*newWillDilutedFee)
|
|
||||||
if err != nil {
|
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
result.Created("公示报表中所要使用的临时待摊薄费用已添加。")
|
|
||||||
}
|
|
||||||
|
|
||||||
func importPredefinedMaintenanceFees(c *gin.Context) {
|
|
||||||
result := response.NewResult(c)
|
|
||||||
requestReportId := c.Param("rid")
|
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
report, err := service.ReportService.RetreiveReportIndex(requestReportId)
|
report, err := service.ReportService.RetreiveReportIndex(requestReportId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return result.NotFound(err.Error())
|
||||||
return
|
|
||||||
}
|
|
||||||
maintenanceFees, err := service.MaintenanceFeeService.ListMaintenanceFees([]string{report.ParkId})
|
|
||||||
if err != nil {
|
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Printf("[cotroller] [debug] fees: %+v", maintenanceFees)
|
|
||||||
enabledMaintenanceFees := lo.Filter(
|
|
||||||
maintenanceFees,
|
|
||||||
func(elem model.MaintenanceFee, index int) bool {
|
|
||||||
return elem.Enabled
|
|
||||||
},
|
|
||||||
)
|
|
||||||
log.Printf("[cotroller] [debug] fees: %+v", enabledMaintenanceFees)
|
|
||||||
if len(enabledMaintenanceFees) == 0 {
|
|
||||||
result.NotFound("没有找到可供导入的配电维护费记录。")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dilutedFees := lo.Map(
|
|
||||||
enabledMaintenanceFees,
|
|
||||||
func(elem model.MaintenanceFee, index int) model.WillDilutedFee {
|
|
||||||
fee := &model.WillDilutedFee{
|
|
||||||
Id: utils.UUIDString(),
|
|
||||||
ReportId: report.Id,
|
|
||||||
SourceId: lo.ToPtr(elem.Id),
|
|
||||||
Name: elem.Name,
|
|
||||||
Fee: elem.Fee,
|
|
||||||
Memo: elem.Memo,
|
|
||||||
}
|
|
||||||
return *fee
|
|
||||||
},
|
|
||||||
)
|
|
||||||
err = service.ReportService.BatchSaveMaintenanceFee(report.Id, dilutedFees)
|
|
||||||
if err != nil {
|
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
result.Created("预定义的配电维护费已经导入。")
|
|
||||||
}
|
|
||||||
|
|
||||||
type DilutedFeeModificationFormData struct {
|
|
||||||
Name *string `json:"name,omitempty" form:"name"`
|
|
||||||
Fee decimal.Decimal `json:"fee" form:"fee"`
|
|
||||||
Memo *string `json:"memo,omitempty" form:"memo"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func modifyWillDilutedFee(c *gin.Context) {
|
|
||||||
result := response.NewResult(c)
|
|
||||||
requestReportId := c.Param("rid")
|
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
requestFeeId := c.Param("mid")
|
|
||||||
formData := new(DilutedFeeModificationFormData)
|
|
||||||
c.BindJSON(formData)
|
|
||||||
updateValues := tools.ConvertStructToMap(formData)
|
|
||||||
err := service.ReportService.UpdateMaintenanceFee(requestFeeId, updateValues)
|
|
||||||
if err != nil {
|
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
result.Updated("指定待摊薄费用信息已经更新。")
|
|
||||||
}
|
|
||||||
|
|
||||||
func deleteTemporaryWillDilutedFee(c *gin.Context) {
|
|
||||||
result := response.NewResult(c)
|
|
||||||
requestReportId := c.Param("rid")
|
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
requestFeeId := c.Param("mid")
|
|
||||||
err := service.ReportService.DeleteWillDilutedFee(requestFeeId)
|
|
||||||
if err != nil {
|
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
result.Deleted("指定待摊薄费用信息已经删除。")
|
|
||||||
}
|
|
||||||
|
|
||||||
func progressReportWillDilutedFee(c *gin.Context) {
|
|
||||||
result := response.NewResult(c)
|
|
||||||
requestReportId := c.Param("rid")
|
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
report, err := service.ReportService.RetreiveReportIndex(requestReportId)
|
|
||||||
if err != nil {
|
|
||||||
result.NotFound(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = service.ReportService.ProgressReportWillDilutedFee(*report)
|
|
||||||
if err != nil {
|
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
result.Success("待摊薄费用编辑步骤已经完成。")
|
|
||||||
}
|
|
||||||
|
|
||||||
func progressEndUserRegister(c *gin.Context) {
|
|
||||||
result := response.NewResult(c)
|
|
||||||
requestReportId := c.Param("rid")
|
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
report, err := service.ReportService.RetreiveReportIndex(requestReportId)
|
|
||||||
if err != nil {
|
|
||||||
result.NotFound(err.Error())
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
err = service.ReportService.ProgressReportRegisterEndUser(*report)
|
err = service.ReportService.ProgressReportRegisterEndUser(*report)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Success("终端用户抄表编辑步骤已经完成。")
|
return result.Success("终端用户抄表编辑步骤已经完成。")
|
||||||
}
|
}
|
||||||
|
|
||||||
func publishReport(c *gin.Context) {
|
func publishReport(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestReportId := c.Param("rid")
|
requestReportId := c.Params("rid")
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
if ensure, err := ensureReportBelongs(c, &result, requestReportId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
report, err := service.ReportService.RetreiveReportIndex(requestReportId)
|
report, err := service.ReportService.RetreiveReportIndex(requestReportId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return result.NotFound(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
err = service.ReportService.PublishReport(*report)
|
err = service.ReportService.PublishReport(*report)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Success("指定的公示报表已经发布。")
|
return result.Success("指定的公示报表已经发布。")
|
||||||
}
|
}
|
||||||
|
|
||||||
func searchReports(c *gin.Context) {
|
func searchReports(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
session, err := _retreiveSession(c)
|
session, err := _retreiveSession(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Unauthorized(err.Error())
|
return result.Unauthorized(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
requestUser := lo.
|
requestUser := lo.
|
||||||
If(session.Type == model.USER_TYPE_ENT, session.Uid).
|
If(session.Type == model.USER_TYPE_ENT, session.Uid).
|
||||||
Else(c.DefaultQuery("user", ""))
|
Else(c.Query("user"))
|
||||||
requestPark := c.DefaultQuery("park", "")
|
requestPark := c.Query("park")
|
||||||
if len(requestPark) > 0 && session.Type == model.USER_TYPE_ENT {
|
if len(requestPark) > 0 && session.Type == model.USER_TYPE_ENT {
|
||||||
if !ensureParkBelongs(c, result, requestPark) {
|
if ensure, err := ensureParkBelongs(c, &result, requestPark); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
requestPeriodString := c.DefaultQuery("period", "")
|
requestPeriodString := c.Query("period")
|
||||||
var requestPeriod *time.Time = nil
|
var requestPeriod *time.Time = nil
|
||||||
if len(requestPeriodString) > 0 {
|
if len(requestPeriodString) > 0 {
|
||||||
parsedPeriod, err := time.Parse("2006-01", requestPeriodString)
|
parsedPeriod, err := time.Parse("2006-01", requestPeriodString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotAccept("参数[period]的格式不正确。")
|
return result.NotAccept("参数[period]的格式不正确。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
requestPeriod = lo.ToPtr(parsedPeriod)
|
requestPeriod = lo.ToPtr(parsedPeriod)
|
||||||
}
|
}
|
||||||
requestKeyword := c.DefaultQuery("keyword", "")
|
requestKeyword := c.Query("keyword")
|
||||||
requestPage, err := strconv.Atoi(c.DefaultQuery("page", "1"))
|
requestPage, err := strconv.Atoi(c.Query("page", "1"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotAccept("查询参数[page]格式不正确。")
|
return result.NotAccept("查询参数[page]格式不正确。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
records, totalItems, err := service.ReportService.SearchReport(requestUser, requestPark, requestKeyword, requestPeriod, requestPage)
|
requestAllReports, err := strconv.ParseBool(c.Query("all", "false"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return result.NotAccept("查询参数[all]格式不正确。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Success(
|
records, totalItems, err := service.ReportService.SearchReport(requestUser, requestPark, requestKeyword, requestPeriod, requestPage, !requestAllReports)
|
||||||
|
if err != nil {
|
||||||
|
return result.NotFound(err.Error())
|
||||||
|
}
|
||||||
|
return result.Success(
|
||||||
"已经取得符合条件的公示报表记录。",
|
"已经取得符合条件的公示报表记录。",
|
||||||
response.NewPagedResponse(requestPage, totalItems).ToMap(),
|
response.NewPagedResponse(requestPage, totalItems).ToMap(),
|
||||||
gin.H{"reports": records},
|
fiber.Map{"reports": records},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchReportPublicity(c *gin.Context) {
|
func fetchReportPublicity(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestReportId := c.Param("rid")
|
requestReportId := c.Params("rid")
|
||||||
publicity, err := service.ReportService.AssembleReportPublicity(requestReportId)
|
publicity, err := service.ReportService.AssembleReportPublicity(requestReportId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if nfErr, ok := err.(exceptions.NotFoundError); ok {
|
if nfErr, ok := err.(exceptions.NotFoundError); ok {
|
||||||
result.NotFound(nfErr.Error())
|
return result.NotFound(nfErr.Error())
|
||||||
return
|
|
||||||
} else {
|
} else {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.Success("已经取得指定公示报表的发布版本。", tools.ConvertStructToMap(publicity))
|
return result.Success("已经取得指定公示报表的发布版本。", tools.ConvertStructToMap(publicity))
|
||||||
}
|
}
|
||||||
|
|
||||||
func calculateReport(c *gin.Context) {
|
func calculateReport(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestReportId := c.Param("rid")
|
requestReportId := c.Params("rid")
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
if ensure, err := ensureReportBelongs(c, &result, requestReportId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
err := service.CalculateService.ComprehensivelyCalculateReport(requestReportId)
|
err := service.CalculateService.ComprehensivelyCalculateReport(requestReportId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Success("指定公示报表中的数据已经计算完毕。")
|
return result.Success("指定公示报表中的数据已经计算完毕。")
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-23
@@ -7,34 +7,32 @@ import (
|
|||||||
"electricity_bill_calc/service"
|
"electricity_bill_calc/service"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitializeStatisticsController(router *gin.Engine) {
|
func InitializeStatisticsController(router *fiber.App) {
|
||||||
router.GET("/audits", security.OPSAuthorize, currentAuditAmount)
|
router.Get("/audits", security.OPSAuthorize, currentAuditAmount)
|
||||||
router.GET("/stat/reports", security.MustAuthenticated, statReports)
|
router.Get("/stat/reports", security.MustAuthenticated, statReports)
|
||||||
}
|
}
|
||||||
|
|
||||||
func currentAuditAmount(c *gin.Context) {
|
func currentAuditAmount(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
amount, err := service.WithdrawService.AuditWaits()
|
amount, err := service.WithdrawService.AuditWaits()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(http.StatusOK, "已经获取到指定的统计信息。", gin.H{
|
return result.Json(http.StatusOK, "已经获取到指定的统计信息。", fiber.Map{
|
||||||
"amounts": map[string]int64{
|
"amounts": map[string]int64{
|
||||||
"withdraw": amount,
|
"withdraw": amount,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func statReports(c *gin.Context) {
|
func statReports(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
session, err := _retreiveSession(c)
|
session, err := _retreiveSession(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Unauthorized(err.Error())
|
return result.Unauthorized(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
enterprises int64 = 0
|
enterprises int64 = 0
|
||||||
@@ -44,34 +42,29 @@ func statReports(c *gin.Context) {
|
|||||||
if session.Type != 0 {
|
if session.Type != 0 {
|
||||||
enterprises, err = service.StatisticsService.EnabledEnterprises()
|
enterprises, err = service.StatisticsService.EnabledEnterprises()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
parks, err = service.StatisticsService.EnabledParks()
|
parks, err = service.StatisticsService.EnabledParks()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
reports, err = service.StatisticsService.ParksNewestState()
|
reports, err = service.StatisticsService.ParksNewestState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
parks, err = service.StatisticsService.EnabledParks(session.Uid)
|
parks, err = service.StatisticsService.EnabledParks(session.Uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
reports, err = service.StatisticsService.ParksNewestState(session.Uid)
|
reports, err = service.StatisticsService.ParksNewestState(session.Uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result.Json(http.StatusOK, "已经完成园区报告的统计。", gin.H{
|
return result.Json(http.StatusOK, "已经完成园区报告的统计。", fiber.Map{
|
||||||
"statistics": gin.H{
|
"statistics": fiber.Map{
|
||||||
"enterprises": enterprises,
|
"enterprises": enterprises,
|
||||||
"parks": parks,
|
"parks": parks,
|
||||||
"reports": reports,
|
"reports": reports,
|
||||||
|
|||||||
+117
-131
@@ -8,28 +8,28 @@ import (
|
|||||||
"electricity_bill_calc/response"
|
"electricity_bill_calc/response"
|
||||||
"electricity_bill_calc/security"
|
"electricity_bill_calc/security"
|
||||||
"electricity_bill_calc/service"
|
"electricity_bill_calc/service"
|
||||||
|
"electricity_bill_calc/tools"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitializeUserController(router *gin.Engine) {
|
func InitializeUserController(router *fiber.App) {
|
||||||
router.DELETE("/password/:uid", security.OPSAuthorize, invalidUserPassword)
|
router.Delete("/password/:uid", security.OPSAuthorize, invalidUserPassword)
|
||||||
router.DELETE("/login", security.MustAuthenticated, logout)
|
router.Delete("/login", security.MustAuthenticated, logout)
|
||||||
router.PUT("/password", resetUserPassword)
|
router.Put("/password", resetUserPassword)
|
||||||
router.GET("/accounts", security.OPSAuthorize, listPagedUser)
|
router.Get("/accounts", security.ManagementAuthorize, listPagedUser)
|
||||||
router.POST("/login", login)
|
router.Post("/login", login)
|
||||||
router.PUT("/account/enabled/state", security.OPSAuthorize, switchUserEnabling)
|
router.Put("/account/enabled/state", security.OPSAuthorize, switchUserEnabling)
|
||||||
router.POST("/account", security.OPSAuthorize, createOPSAndManagementAccount)
|
router.Post("/account", security.OPSAuthorize, createOPSAndManagementAccount)
|
||||||
router.GET("/account/:uid", security.MustAuthenticated, getUserDetail)
|
router.Get("/account/:uid", security.MustAuthenticated, getUserDetail)
|
||||||
router.POST("/enterprise", security.OPSAuthorize, createEnterpriseAccount)
|
router.Post("/enterprise", security.OPSAuthorize, createEnterpriseAccount)
|
||||||
router.PUT("/account/:uid", security.OPSAuthorize, modifyAccountDetail)
|
router.Put("/account/:uid", security.OPSAuthorize, modifyAccountDetail)
|
||||||
router.GET("/enterprise/quick/search", security.OPSAuthorize, quickSearchEnterprise)
|
router.Get("/enterprise/quick/search", security.OPSAuthorize, quickSearchEnterprise)
|
||||||
router.GET("/expiration", security.EnterpriseAuthorize, fetchExpiration)
|
router.Get("/expiration", security.EnterpriseAuthorize, fetchExpiration)
|
||||||
}
|
}
|
||||||
|
|
||||||
type _LoginFormData struct {
|
type _LoginFormData struct {
|
||||||
@@ -38,16 +38,15 @@ type _LoginFormData struct {
|
|||||||
Type int8 `json:"type"`
|
Type int8 `json:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func login(c *gin.Context) {
|
func login(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
loginData := new(_LoginFormData)
|
loginData := new(_LoginFormData)
|
||||||
err := c.BindJSON(loginData)
|
if err := c.BodyParser(loginData); err != nil {
|
||||||
if err != nil {
|
return result.Error(http.StatusInternalServerError, "表单解析失败。")
|
||||||
result.Error(http.StatusInternalServerError, "表单解析失败。")
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
session *model.Session
|
session *model.Session
|
||||||
|
err error
|
||||||
)
|
)
|
||||||
if loginData.Type == model.USER_TYPE_ENT {
|
if loginData.Type == model.USER_TYPE_ENT {
|
||||||
session, err = service.UserService.ProcessEnterpriseUserLogin(loginData.Username, loginData.Password)
|
session, err = service.UserService.ProcessEnterpriseUserLogin(loginData.Username, loginData.Password)
|
||||||
@@ -57,51 +56,43 @@ func login(c *gin.Context) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
if authError, ok := err.(*exceptions.AuthenticationError); ok {
|
if authError, ok := err.(*exceptions.AuthenticationError); ok {
|
||||||
if authError.NeedReset {
|
if authError.NeedReset {
|
||||||
result.LoginNeedReset()
|
return result.LoginNeedReset()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Error(int(authError.Code), authError.Message)
|
return result.Error(int(authError.Code), authError.Message)
|
||||||
return
|
|
||||||
} else {
|
} else {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.LoginSuccess(session)
|
return result.LoginSuccess(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
func logout(c *gin.Context) {
|
func logout(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
session, exists := c.Get("session")
|
session := c.Locals("session")
|
||||||
if !exists {
|
if session == nil {
|
||||||
result.Success("用户会话已结束。")
|
return result.Success("用户会话已结束。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
_, err := cache.ClearSession(session.(*model.Session).Token)
|
_, err := cache.ClearSession(session.(*model.Session).Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Success("用户已成功登出系统。")
|
return result.Success("用户已成功登出系统。")
|
||||||
}
|
}
|
||||||
|
|
||||||
func invalidUserPassword(c *gin.Context) {
|
func invalidUserPassword(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
targetUserId := c.Param("uid")
|
targetUserId := c.Params("uid")
|
||||||
verifyCode, err := service.UserService.InvalidUserPassword(targetUserId)
|
verifyCode, err := service.UserService.InvalidUserPassword(targetUserId)
|
||||||
if _, ok := err.(exceptions.NotFoundError); ok {
|
if _, ok := err.(exceptions.NotFoundError); ok {
|
||||||
result.NotFound("未找到指定用户。")
|
return result.NotFound("未找到指定用户。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if _, ok := err.(exceptions.UnsuccessfulOperationError); ok {
|
if _, ok := err.(exceptions.UnsuccessfulOperationError); ok {
|
||||||
result.NotAccept("未能成功更新用户的密码。")
|
return result.NotAccept("未能成功更新用户的密码。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(http.StatusAccepted, "用户密码已经失效", gin.H{"verify": verifyCode})
|
return result.Json(http.StatusAccepted, "用户密码已经失效", fiber.Map{"verify": verifyCode})
|
||||||
}
|
}
|
||||||
|
|
||||||
type _ResetPasswordFormData struct {
|
type _ResetPasswordFormData struct {
|
||||||
@@ -110,47 +101,42 @@ type _ResetPasswordFormData struct {
|
|||||||
NewPassword string `json:"newPass"`
|
NewPassword string `json:"newPass"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func resetUserPassword(c *gin.Context) {
|
func resetUserPassword(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
resetForm := new(_ResetPasswordFormData)
|
resetForm := new(_ResetPasswordFormData)
|
||||||
c.BindJSON(resetForm)
|
if err := c.BodyParser(resetForm); err != nil {
|
||||||
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
|
}
|
||||||
verified, err := service.UserService.VerifyUserPassword(resetForm.Username, resetForm.VerifyCode)
|
verified, err := service.UserService.VerifyUserPassword(resetForm.Username, resetForm.VerifyCode)
|
||||||
if _, ok := err.(exceptions.NotFoundError); ok {
|
if _, ok := err.(exceptions.NotFoundError); ok {
|
||||||
result.NotFound("指定的用户不存在。")
|
return result.NotFound("指定的用户不存在。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if !verified {
|
if !verified {
|
||||||
result.Error(http.StatusUnauthorized, "验证码不正确。")
|
return result.Error(http.StatusUnauthorized, "验证码不正确。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
completed, err := service.UserService.ResetUserPassword(resetForm.Username, resetForm.NewPassword)
|
completed, err := service.UserService.ResetUserPassword(resetForm.Username, resetForm.NewPassword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if completed {
|
if completed {
|
||||||
result.Updated("用户凭据已更新。")
|
return result.Updated("用户凭据已更新。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.NotAccept("用户凭据未能成功更新。")
|
return result.NotAccept("用户凭据未能成功更新。")
|
||||||
}
|
}
|
||||||
|
|
||||||
func listPagedUser(c *gin.Context) {
|
func listPagedUser(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestPage, err := strconv.Atoi(c.DefaultQuery("page", "1"))
|
requestPage, err := strconv.Atoi(c.Query("page", "1"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotAccept("查询参数[page]格式不正确。")
|
return result.NotAccept("查询参数[page]格式不正确。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
requestKeyword := c.DefaultQuery("keyword", "")
|
requestKeyword := c.Query("keyword")
|
||||||
requestUserType, err := strconv.Atoi(c.DefaultQuery("type", "-1"))
|
requestUserType, err := strconv.Atoi(c.Query("type", "-1"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotAccept("查询参数[type]格式不正确。")
|
return result.NotAccept("查询参数[type]格式不正确。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
var requestUserStat *bool
|
var requestUserStat *bool
|
||||||
state, err := strconv.ParseBool(c.Query("state"))
|
state, err := strconv.ParseBool(c.Query("state"))
|
||||||
@@ -161,14 +147,13 @@ func listPagedUser(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
users, total, err := service.UserService.ListUserDetail(requestKeyword, requestUserType, requestUserStat, requestPage)
|
users, total, err := service.UserService.ListUserDetail(requestKeyword, requestUserType, requestUserStat, requestPage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return result.NotFound(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(
|
return result.Json(
|
||||||
http.StatusOK,
|
http.StatusOK,
|
||||||
"已取得符合条件的用户集合。",
|
"已取得符合条件的用户集合。",
|
||||||
response.NewPagedResponse(requestPage, total).ToMap(),
|
response.NewPagedResponse(requestPage, total).ToMap(),
|
||||||
gin.H{"accounts": users},
|
fiber.Map{"accounts": users},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,21 +162,21 @@ type _UserStateChangeFormData struct {
|
|||||||
Enabled bool `json:"enabled" form:"enabled"`
|
Enabled bool `json:"enabled" form:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func switchUserEnabling(c *gin.Context) {
|
func switchUserEnabling(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
switchForm := new(_UserStateChangeFormData)
|
switchForm := new(_UserStateChangeFormData)
|
||||||
c.BindJSON(switchForm)
|
if err := c.BodyParser(switchForm); err != nil {
|
||||||
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
|
}
|
||||||
err := service.UserService.SwitchUserState(switchForm.UserID, switchForm.Enabled)
|
err := service.UserService.SwitchUserState(switchForm.UserID, switchForm.Enabled)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if nfErr, ok := err.(*exceptions.NotFoundError); ok {
|
if nfErr, ok := err.(*exceptions.NotFoundError); ok {
|
||||||
result.NotFound(nfErr.Message)
|
return result.NotFound(nfErr.Message)
|
||||||
return
|
|
||||||
} else {
|
} else {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.Updated("用户状态已经更新。")
|
return result.Updated("用户状态已经更新。")
|
||||||
}
|
}
|
||||||
|
|
||||||
type _OPSAccountCreationFormData struct {
|
type _OPSAccountCreationFormData struct {
|
||||||
@@ -202,18 +187,18 @@ type _OPSAccountCreationFormData struct {
|
|||||||
Type int `json:"type" form:"type"`
|
Type int `json:"type" form:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func createOPSAndManagementAccount(c *gin.Context) {
|
func createOPSAndManagementAccount(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
creationForm := new(_OPSAccountCreationFormData)
|
creationForm := new(_OPSAccountCreationFormData)
|
||||||
c.BindJSON(creationForm)
|
if err := c.BodyParser(creationForm); err != nil {
|
||||||
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
|
}
|
||||||
exists, err := service.UserService.IsUsernameExists(creationForm.Username)
|
exists, err := service.UserService.IsUsernameExists(creationForm.Username)
|
||||||
if exists {
|
if exists {
|
||||||
result.Conflict("指定的用户名已经被使用了。")
|
return result.Conflict("指定的用户名已经被使用了。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
newUser := new(model.User)
|
newUser := new(model.User)
|
||||||
newUser.Username = creationForm.Username
|
newUser.Username = creationForm.Username
|
||||||
@@ -224,33 +209,30 @@ func createOPSAndManagementAccount(c *gin.Context) {
|
|||||||
newUserDetail.Contact = creationForm.Contact
|
newUserDetail.Contact = creationForm.Contact
|
||||||
newUserDetail.Phone = creationForm.Phone
|
newUserDetail.Phone = creationForm.Phone
|
||||||
newUserDetail.UnitServiceFee = decimal.Zero
|
newUserDetail.UnitServiceFee = decimal.Zero
|
||||||
newUserDetail.ServiceExpiration, _ = time.Parse("2006-01-02 15:04:05", "2099-12-31 23:59:59")
|
newUserDetail.ServiceExpiration, _ = model.ParseDate("2099-12-31")
|
||||||
verifyCode, err := service.UserService.CreateUser(newUser, newUserDetail)
|
verifyCode, err := service.UserService.CreateUser(newUser, newUserDetail)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("user")
|
cache.AbolishRelation("user")
|
||||||
result.Json(http.StatusCreated, "用户已经成功创建。", gin.H{"verify": verifyCode})
|
return result.Json(http.StatusCreated, "用户已经成功创建。", fiber.Map{"verify": verifyCode})
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUserDetail(c *gin.Context) {
|
func getUserDetail(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
targetUserId := c.Param("uid")
|
targetUserId := c.Params("uid")
|
||||||
exists, err := service.UserService.IsUserExists(targetUserId)
|
exists, err := service.UserService.IsUserExists(targetUserId)
|
||||||
if !exists {
|
if !exists {
|
||||||
result.NotFound("指定的用户不存在。")
|
return result.NotFound("指定的用户不存在。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
}
|
}
|
||||||
userDetail, err := service.UserService.FetchUserDetail(targetUserId)
|
userDetail, err := service.UserService.FetchUserDetail(targetUserId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(http.StatusOK, "用户详细信息已获取到。", gin.H{"user": userDetail})
|
return result.Json(http.StatusOK, "用户详细信息已获取到。", fiber.Map{"user": userDetail})
|
||||||
}
|
}
|
||||||
|
|
||||||
type _EnterpriseCreationFormData struct {
|
type _EnterpriseCreationFormData struct {
|
||||||
@@ -263,18 +245,18 @@ type _EnterpriseCreationFormData struct {
|
|||||||
UnitServiceFee *string `json:"unitServiceFee" form:"unitServiceFee"`
|
UnitServiceFee *string `json:"unitServiceFee" form:"unitServiceFee"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func createEnterpriseAccount(c *gin.Context) {
|
func createEnterpriseAccount(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
creationForm := new(_EnterpriseCreationFormData)
|
creationForm := new(_EnterpriseCreationFormData)
|
||||||
c.BindJSON(creationForm)
|
if err := c.BodyParser(creationForm); err != nil {
|
||||||
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
|
}
|
||||||
exists, err := service.UserService.IsUsernameExists(creationForm.Username)
|
exists, err := service.UserService.IsUsernameExists(creationForm.Username)
|
||||||
if exists {
|
if exists {
|
||||||
result.Conflict("指定的用户名已经被使用了。")
|
return result.Conflict("指定的用户名已经被使用了。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
newUser := new(model.User)
|
newUser := new(model.User)
|
||||||
newUser.Username = creationForm.Username
|
newUser.Username = creationForm.Username
|
||||||
@@ -286,18 +268,16 @@ func createEnterpriseAccount(c *gin.Context) {
|
|||||||
newUserDetail.Phone = creationForm.Phone
|
newUserDetail.Phone = creationForm.Phone
|
||||||
newUserDetail.UnitServiceFee, err = decimal.NewFromString(*creationForm.UnitServiceFee)
|
newUserDetail.UnitServiceFee, err = decimal.NewFromString(*creationForm.UnitServiceFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.BadRequest("用户月服务费无法解析。")
|
return result.BadRequest("用户月服务费无法解析。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
newUserDetail.ServiceExpiration = time.Now()
|
newUserDetail.ServiceExpiration = model.NewEmptyDate()
|
||||||
|
|
||||||
verifyCode, err := service.UserService.CreateUser(newUser, newUserDetail)
|
verifyCode, err := service.UserService.CreateUser(newUser, newUserDetail)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("user")
|
cache.AbolishRelation("user")
|
||||||
result.Json(http.StatusCreated, "用户已经成功创建。", gin.H{"verify": verifyCode})
|
return result.Json(http.StatusCreated, "用户已经成功创建。", fiber.Map{"verify": verifyCode})
|
||||||
}
|
}
|
||||||
|
|
||||||
type _AccountModificationFormData struct {
|
type _AccountModificationFormData struct {
|
||||||
@@ -309,63 +289,69 @@ type _AccountModificationFormData struct {
|
|||||||
UnitServiceFee *string `json:"unitServiceFee" form:"unitServiceFee"`
|
UnitServiceFee *string `json:"unitServiceFee" form:"unitServiceFee"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func modifyAccountDetail(c *gin.Context) {
|
func modifyAccountDetail(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
targetUserId := c.Param("uid")
|
targetUserId := c.Params("uid")
|
||||||
modForm := new(_AccountModificationFormData)
|
modForm := new(_AccountModificationFormData)
|
||||||
c.BindJSON(modForm)
|
if err := c.BodyParser(modForm); err != nil {
|
||||||
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
|
}
|
||||||
exists, err := service.UserService.IsUserExists(targetUserId)
|
exists, err := service.UserService.IsUserExists(targetUserId)
|
||||||
if !exists {
|
if !exists {
|
||||||
result.NotFound("指定的用户不存在。")
|
return result.NotFound("指定的用户不存在。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
newUserInfo := new(model.UserDetail)
|
newUserInfo := new(model.UserDetail)
|
||||||
|
newUserInfo.Id = targetUserId
|
||||||
newUserInfo.Name = &modForm.Name
|
newUserInfo.Name = &modForm.Name
|
||||||
|
if len(modForm.Name) > 0 {
|
||||||
|
abbr := tools.PinyinAbbr(modForm.Name)
|
||||||
|
newUserInfo.Abbr = &abbr
|
||||||
|
}
|
||||||
newUserInfo.Region = modForm.Region
|
newUserInfo.Region = modForm.Region
|
||||||
newUserInfo.Address = modForm.Address
|
newUserInfo.Address = modForm.Address
|
||||||
newUserInfo.Contact = modForm.Contact
|
newUserInfo.Contact = modForm.Contact
|
||||||
newUserInfo.Phone = modForm.Phone
|
newUserInfo.Phone = modForm.Phone
|
||||||
newUserInfo.UnitServiceFee, err = decimal.NewFromString(*modForm.UnitServiceFee)
|
newUserInfo.UnitServiceFee, err = decimal.NewFromString(*modForm.UnitServiceFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.BadRequest("用户月服务费无法解析。")
|
return result.BadRequest("用户月服务费无法解析。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
_, err = global.DBConn.ID(targetUserId).Update(newUserInfo)
|
_, err = global.DB.NewUpdate().Model(newUserInfo).
|
||||||
|
WherePK().
|
||||||
|
Column("name", "abbr", "region", "address", "contact", "phone", "unit_service_fee").
|
||||||
|
Exec(c.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("user")
|
cache.AbolishRelation(fmt.Sprintf("user:%s", targetUserId))
|
||||||
cache.AbolishRelation(fmt.Sprintf("user_%s", targetUserId))
|
return result.Updated("指定用户的信息已经更新。")
|
||||||
result.Updated("指定用户的信息已经更新。")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func quickSearchEnterprise(c *gin.Context) {
|
func quickSearchEnterprise(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
keyword := c.Query("keyword")
|
keyword := c.Query("keyword")
|
||||||
searchResult, err := service.UserService.SearchLimitUsers(keyword, 6)
|
searchResult, err := service.UserService.SearchLimitUsers(keyword, 6)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(http.StatusOK, "已查询到存在符合条件的企业", gin.H{"users": searchResult})
|
return result.Json(http.StatusOK, "已查询到存在符合条件的企业", fiber.Map{"users": searchResult})
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchExpiration(c *gin.Context) {
|
func fetchExpiration(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
session, err := _retreiveSession(c)
|
session, err := _retreiveSession(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Unauthorized(err.Error())
|
return result.Unauthorized(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
user, err := service.UserService.FetchUserDetail(session.Uid)
|
user, err := service.UserService.FetchUserDetail(session.Uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return result.NotFound(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(http.StatusOK, "已经取得用户的服务期限信息", gin.H{"expiration": user.ServiceExpiration.Format("2006-01-02")})
|
return result.Json(
|
||||||
|
http.StatusOK,
|
||||||
|
"已经取得用户的服务期限信息",
|
||||||
|
fiber.Map{"expiration": user.ServiceExpiration.Format("2006-01-02")},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-34
@@ -8,59 +8,53 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitializeWithdrawController(router *gin.Engine) {
|
func InitializeWithdrawController(router *fiber.App) {
|
||||||
router.DELETE("/publicity/:pid", security.EnterpriseAuthorize, applyReportWithdraw)
|
router.Delete("/publicity/:pid", security.EnterpriseAuthorize, applyReportWithdraw)
|
||||||
router.GET("/withdraws", security.OPSAuthorize, fetchWithdrawsWaitingAutdit)
|
router.Get("/withdraws", security.OPSAuthorize, fetchWithdrawsWaitingAutdit)
|
||||||
router.PUT("/withdraw/:rid", security.OPSAuthorize, auditWithdraw)
|
router.Put("/withdraw/:rid", security.OPSAuthorize, auditWithdraw)
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyReportWithdraw(c *gin.Context) {
|
func applyReportWithdraw(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestReportId := c.Param("pid")
|
requestReportId := c.Params("pid")
|
||||||
if !ensureReportBelongs(c, result, requestReportId) {
|
if ensure, err := ensureReportBelongs(c, &result, requestReportId); !ensure {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
deleted, err := service.WithdrawService.ApplyWithdraw(requestReportId)
|
deleted, err := service.WithdrawService.ApplyWithdraw(requestReportId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if nfErr, ok := err.(exceptions.NotFoundError); ok {
|
if nfErr, ok := err.(exceptions.NotFoundError); ok {
|
||||||
result.NotFound(nfErr.Error())
|
return result.NotFound(nfErr.Error())
|
||||||
return
|
|
||||||
} else if ioErr, ok := err.(exceptions.ImproperOperateError); ok {
|
} else if ioErr, ok := err.(exceptions.ImproperOperateError); ok {
|
||||||
result.NotAccept(ioErr.Error())
|
return result.NotAccept(ioErr.Error())
|
||||||
return
|
|
||||||
} else {
|
} else {
|
||||||
result.Error(http.StatusInternalServerError, err.Error())
|
return result.Error(http.StatusInternalServerError, err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !deleted {
|
if !deleted {
|
||||||
result.Error(http.StatusInternalServerError, "未能完成公示报表的申请撤回操作。")
|
return result.Error(http.StatusInternalServerError, "未能完成公示报表的申请撤回操作。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Success("指定的公示报表已经申请撤回。")
|
return result.Success("指定的公示报表已经申请撤回。")
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchWithdrawsWaitingAutdit(c *gin.Context) {
|
func fetchWithdrawsWaitingAutdit(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
keyword := c.DefaultQuery("keyword", "")
|
keyword := c.Query("keyword")
|
||||||
requestPage, err := strconv.Atoi(c.DefaultQuery("page", "1"))
|
requestPage, err := strconv.Atoi(c.Query("page", "1"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotAccept("查询参数[page]格式不正确。")
|
return result.NotAccept("查询参数[page]格式不正确。")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
reports, totalitems, err := service.WithdrawService.FetchPagedWithdrawApplies(requestPage, keyword)
|
reports, totalitems, err := service.WithdrawService.FetchPagedWithdrawApplies(requestPage, keyword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.NotFound(err.Error())
|
return result.NotFound(err.Error())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Json(
|
return result.Json(
|
||||||
http.StatusOK,
|
http.StatusOK,
|
||||||
"已经取得符合条件的等待审核的撤回申请。",
|
"已经取得符合条件的等待审核的撤回申请。",
|
||||||
response.NewPagedResponse(requestPage, totalitems).ToMap(),
|
response.NewPagedResponse(requestPage, totalitems).ToMap(),
|
||||||
gin.H{"records": reports},
|
fiber.Map{"records": reports},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,19 +62,20 @@ type WithdrawAuditFormData struct {
|
|||||||
Audit bool `json:"audit" form:"audit"`
|
Audit bool `json:"audit" form:"audit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func auditWithdraw(c *gin.Context) {
|
func auditWithdraw(c *fiber.Ctx) error {
|
||||||
result := response.NewResult(c)
|
result := response.NewResult(c)
|
||||||
requestReportId := c.Param("rid")
|
requestReportId := c.Params("rid")
|
||||||
formData := new(WithdrawAuditFormData)
|
formData := new(WithdrawAuditFormData)
|
||||||
c.BindJSON(formData)
|
if err := c.BodyParser(formData); err != nil {
|
||||||
|
return result.UnableToParse("无法解析提交的数据。")
|
||||||
|
}
|
||||||
err := service.WithdrawService.AuditWithdraw(requestReportId, formData.Audit)
|
err := service.WithdrawService.AuditWithdraw(requestReportId, formData.Audit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if nfErr, ok := err.(exceptions.NotFoundError); ok {
|
if nfErr, ok := err.(exceptions.NotFoundError); ok {
|
||||||
result.NotFound(nfErr.Error())
|
return result.NotFound(nfErr.Error())
|
||||||
} else {
|
} else {
|
||||||
result.NotAccept(err.Error())
|
return result.NotAccept(err.Error())
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
result.Success("指定公示报表的撤回申请已经完成审核")
|
return result.Success("指定公示报表的撤回申请已经完成审核")
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-2
@@ -4,6 +4,7 @@ import (
|
|||||||
"electricity_bill_calc/model"
|
"electricity_bill_calc/model"
|
||||||
"electricity_bill_calc/tools"
|
"electricity_bill_calc/tools"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -25,6 +26,7 @@ type ColumnRecognizer struct {
|
|||||||
Pattern []string
|
Pattern []string
|
||||||
Tag string
|
Tag string
|
||||||
MatchIndex int
|
MatchIndex int
|
||||||
|
MustFill bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExcelAnalyzer[T any] struct {
|
type ExcelAnalyzer[T any] struct {
|
||||||
@@ -126,8 +128,18 @@ func (a *ExcelAnalyzer[T]) Analysis(bean T) ([]T, []ExcelAnalysisError) {
|
|||||||
if alias, ok := field.Tag.Lookup("excel"); ok {
|
if alias, ok := field.Tag.Lookup("excel"); ok {
|
||||||
for _, recognizer := range a.Regconizers {
|
for _, recognizer := range a.Regconizers {
|
||||||
if alias == recognizer.Tag && recognizer.MatchIndex != -1 {
|
if alias == recognizer.Tag && recognizer.MatchIndex != -1 {
|
||||||
|
var matchValue string
|
||||||
actualField := instance.Elem().FieldByName(field.Name)
|
actualField := instance.Elem().FieldByName(field.Name)
|
||||||
matchValue := cols[recognizer.MatchIndex]
|
if recognizer.MatchIndex > len(cols)-1 {
|
||||||
|
if recognizer.MustFill {
|
||||||
|
errs = append(errs, ExcelAnalysisError{Row: rowIndex + 1, Col: recognizer.MatchIndex + 1, Err: AnalysisError{Err: errors.New("单元格内不能没有内容。")}})
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
matchValue = ""
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
matchValue = cols[recognizer.MatchIndex]
|
||||||
|
}
|
||||||
switch field.Type.String() {
|
switch field.Type.String() {
|
||||||
case "string":
|
case "string":
|
||||||
actualField.Set(reflect.ValueOf(matchValue))
|
actualField.Set(reflect.ValueOf(matchValue))
|
||||||
@@ -154,7 +166,9 @@ func (a *ExcelAnalyzer[T]) Analysis(bean T) ([]T, []ExcelAnalysisError) {
|
|||||||
errs = append(errs, ExcelAnalysisError{Row: rowIndex + 1, Col: recognizer.MatchIndex + 1, Err: AnalysisError{Err: fmt.Errorf("单元格内容应为纯数字内容。%w", err)}})
|
errs = append(errs, ExcelAnalysisError{Row: rowIndex + 1, Col: recognizer.MatchIndex + 1, Err: AnalysisError{Err: fmt.Errorf("单元格内容应为纯数字内容。%w", err)}})
|
||||||
actualField.Set(reflect.ValueOf((nullValue)))
|
actualField.Set(reflect.ValueOf((nullValue)))
|
||||||
} else {
|
} else {
|
||||||
actualField.Set(reflect.ValueOf(decimalValue))
|
value := decimal.NewNullDecimal(decimalValue)
|
||||||
|
value.Valid = true
|
||||||
|
actualField.Set(reflect.ValueOf(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "int64", "int":
|
case "int64", "int":
|
||||||
|
|||||||
+7
-3
@@ -7,12 +7,16 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
endUserNonPVRecognizers = []*ColumnRecognizer{
|
endUserNonPVRecognizers = []*ColumnRecognizer{
|
||||||
{Pattern: []string{"电表编号"}, Tag: "meterId", MatchIndex: -1},
|
{Pattern: []string{"电表编号"}, Tag: "meterId", MatchIndex: -1, MustFill: true},
|
||||||
{Pattern: []string{"本期", "(总)"}, Tag: "currentPeriodOverall", MatchIndex: -1},
|
{Pattern: []string{"上期", "(总)"}, Tag: "lastPeriodOverall", MatchIndex: -1, MustFill: true},
|
||||||
{Pattern: []string{"退补", "(总)"}, Tag: "adjustOverall", MatchIndex: -1},
|
{Pattern: []string{"本期", "(总)"}, Tag: "currentPeriodOverall", MatchIndex: -1, MustFill: true},
|
||||||
|
{Pattern: []string{"退补", "(总)"}, Tag: "adjustOverall", MatchIndex: -1, MustFill: true},
|
||||||
}
|
}
|
||||||
endUserPVRecognizers = append(
|
endUserPVRecognizers = append(
|
||||||
endUserNonPVRecognizers,
|
endUserNonPVRecognizers,
|
||||||
|
&ColumnRecognizer{Pattern: []string{"上期", "(尖峰)"}, Tag: "lastPeriodCritical", MatchIndex: -1},
|
||||||
|
&ColumnRecognizer{Pattern: []string{"上期", "(峰)"}, Tag: "lastPeriodPeak", MatchIndex: -1},
|
||||||
|
&ColumnRecognizer{Pattern: []string{"上期", "(谷)"}, Tag: "lastPeriodValley", MatchIndex: -1},
|
||||||
&ColumnRecognizer{Pattern: []string{"本期", "(尖峰)"}, Tag: "currentPeriodCritical", MatchIndex: -1},
|
&ColumnRecognizer{Pattern: []string{"本期", "(尖峰)"}, Tag: "currentPeriodCritical", MatchIndex: -1},
|
||||||
&ColumnRecognizer{Pattern: []string{"本期", "(峰)"}, Tag: "currentPeriodPeak", MatchIndex: -1},
|
&ColumnRecognizer{Pattern: []string{"本期", "(峰)"}, Tag: "currentPeriodPeak", MatchIndex: -1},
|
||||||
&ColumnRecognizer{Pattern: []string{"本期", "(谷)"}, Tag: "currentPeriodValley", MatchIndex: -1},
|
&ColumnRecognizer{Pattern: []string{"本期", "(谷)"}, Tag: "currentPeriodValley", MatchIndex: -1},
|
||||||
|
|||||||
@@ -6,15 +6,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var meter04kVExcelRecognizers = []*ColumnRecognizer{
|
var meter04kVExcelRecognizers = []*ColumnRecognizer{
|
||||||
{Pattern: []string{"表号"}, Tag: "code", MatchIndex: -1},
|
{Pattern: []string{"表号"}, Tag: "code", MatchIndex: -1, MustFill: true},
|
||||||
{Pattern: []string{"户名"}, Tag: "name", MatchIndex: -1},
|
{Pattern: []string{"户名"}, Tag: "name", MatchIndex: -1},
|
||||||
{Pattern: []string{"户址"}, Tag: "address", MatchIndex: -1},
|
{Pattern: []string{"户址"}, Tag: "address", MatchIndex: -1},
|
||||||
{Pattern: []string{"联系人"}, Tag: "contact", MatchIndex: -1},
|
{Pattern: []string{"联系人"}, Tag: "contact", MatchIndex: -1},
|
||||||
{Pattern: []string{"电话"}, Tag: "phone", MatchIndex: -1},
|
{Pattern: []string{"电话"}, Tag: "phone", MatchIndex: -1},
|
||||||
{Pattern: []string{"倍率"}, Tag: "ratio", MatchIndex: -1},
|
{Pattern: []string{"倍率"}, Tag: "ratio", MatchIndex: -1, MustFill: true},
|
||||||
{Pattern: []string{"序号"}, Tag: "seq", MatchIndex: -1},
|
{Pattern: []string{"序号"}, Tag: "seq", MatchIndex: -1, MustFill: true},
|
||||||
{Pattern: []string{"公用设备"}, Tag: "public", MatchIndex: -1},
|
{Pattern: []string{"公用设备"}, Tag: "public", MatchIndex: -1, MustFill: true},
|
||||||
{Pattern: []string{"摊薄"}, Tag: "dilute", MatchIndex: -1},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMeterArchiveExcelAnalyzer(file io.Reader) (*ExcelAnalyzer[model.Meter04KV], error) {
|
func NewMeterArchiveExcelAnalyzer(file io.Reader) (*ExcelAnalyzer[model.Meter04KV], error) {
|
||||||
|
|||||||
@@ -75,8 +75,8 @@ func (t *MeterNonPVExcelTemplateGenerator) WriteMeterData(meters []model.EndUser
|
|||||||
meter.MeterId,
|
meter.MeterId,
|
||||||
meter.Ratio,
|
meter.Ratio,
|
||||||
meter.LastPeriodOverall,
|
meter.LastPeriodOverall,
|
||||||
nil,
|
meter.CurrentPeriodOverall,
|
||||||
nil,
|
meter.AdjustOverall,
|
||||||
},
|
},
|
||||||
excelize.RowOpts{Height: 15},
|
excelize.RowOpts{Height: 15},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
|
|||||||
@@ -84,17 +84,17 @@ func (t *MeterPVExcelTemplateGenerator) WriteMeterData(meters []model.EndUserDet
|
|||||||
meter.MeterId,
|
meter.MeterId,
|
||||||
meter.Ratio,
|
meter.Ratio,
|
||||||
meter.LastPeriodOverall,
|
meter.LastPeriodOverall,
|
||||||
nil,
|
meter.CurrentPeriodOverall,
|
||||||
meter.LastPeriodCritical,
|
meter.LastPeriodCritical,
|
||||||
nil,
|
meter.CurrentPeriodCritical,
|
||||||
meter.LastPeriodPeak,
|
meter.LastPeriodPeak,
|
||||||
nil,
|
meter.CurrentPeriodPeak,
|
||||||
meter.LastPeriodValley,
|
meter.LastPeriodValley,
|
||||||
nil,
|
meter.CurrentPeriodValley,
|
||||||
nil,
|
meter.AdjustOverall,
|
||||||
nil,
|
meter.AdjustCritical,
|
||||||
nil,
|
meter.AdjustPeak,
|
||||||
nil,
|
meter.AdjustValley,
|
||||||
},
|
},
|
||||||
excelize.RowOpts{Height: 15},
|
excelize.RowOpts{Height: 15},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package global
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 生成一个超时时间为5秒的倍率的上下文,如果不传递任何值,默认生成6倍的上下文,即超时时间为30秒。
|
||||||
|
func TimeoutContext(multiply ...int64) (context.Context, context.CancelFunc) {
|
||||||
|
var ratio int64 = 6
|
||||||
|
if len(multiply) > 0 {
|
||||||
|
ratio = multiply[0]
|
||||||
|
}
|
||||||
|
timeout := time.Duration(ratio*5) * time.Second
|
||||||
|
return context.WithTimeout(context.TODO(), timeout)
|
||||||
|
}
|
||||||
+38
-33
@@ -1,55 +1,60 @@
|
|||||||
package global
|
package global
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"electricity_bill_calc/config"
|
"electricity_bill_calc/config"
|
||||||
|
"electricity_bill_calc/logger"
|
||||||
|
|
||||||
// _ "github.com/lib/pq"
|
"github.com/uptrace/bun"
|
||||||
_ "github.com/jackc/pgx/v5/stdlib"
|
"github.com/uptrace/bun/dialect/pgdialect"
|
||||||
"xorm.io/xorm"
|
"github.com/uptrace/bun/driver/pgdriver"
|
||||||
"xorm.io/xorm/log"
|
"go.uber.org/zap/zapcore"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
DBConn *xorm.Engine
|
DB *bun.DB
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetupDatabaseConnection() error {
|
func SetupDatabaseConnection() error {
|
||||||
var err error
|
// connStr := fmt.Sprintf(
|
||||||
// 以下连接方式是采用pgx驱动的时候使用的。
|
// "host=%s user=%s password=%s dbname=%s port=%d sslmode=disable TimeZone=Asia/Shanghai connect_timeout=0 tcp_user_timeout=180000",
|
||||||
DBConn, err = xorm.NewEngine("pgx", fmt.Sprintf(
|
|
||||||
"postgresql://%s:%s@%s:%d/%s?sslmode=disable&",
|
|
||||||
config.DatabaseSettings.User,
|
|
||||||
config.DatabaseSettings.Pass,
|
|
||||||
config.DatabaseSettings.Host,
|
|
||||||
config.DatabaseSettings.Port,
|
|
||||||
config.DatabaseSettings.DB,
|
|
||||||
))
|
|
||||||
// 以下连接方式是采用lib/pq驱动的时候使用的。
|
|
||||||
// DBConn, err = xorm.NewEngine("postgres", fmt.Sprintf(
|
|
||||||
// "host=%s user=%s password=%s dbname=%s port=%d sslmode=disable TimeZone=Asia/Shanghai connect_timeout=0",
|
|
||||||
// config.DatabaseSettings.Host,
|
// config.DatabaseSettings.Host,
|
||||||
// config.DatabaseSettings.User,
|
// config.DatabaseSettings.User,
|
||||||
// config.DatabaseSettings.Pass,
|
// config.DatabaseSettings.Pass,
|
||||||
// config.DatabaseSettings.DB,
|
// config.DatabaseSettings.DB,
|
||||||
// config.DatabaseSettings.Port,
|
// config.DatabaseSettings.Port,
|
||||||
// ))
|
// )
|
||||||
if err != nil {
|
pgconn := pgdriver.NewConnector(
|
||||||
return err
|
pgdriver.WithNetwork("tcp"),
|
||||||
}
|
pgdriver.WithAddr(fmt.Sprintf("%s:%d", config.DatabaseSettings.Host,
|
||||||
|
config.DatabaseSettings.Port)),
|
||||||
DBConn.Ping()
|
pgdriver.WithUser(config.DatabaseSettings.User),
|
||||||
DBConn.SetMaxIdleConns(config.DatabaseSettings.MaxIdleConns)
|
pgdriver.WithInsecure(true),
|
||||||
DBConn.SetMaxOpenConns(config.DatabaseSettings.MaxOpenConns)
|
pgdriver.WithPassword(config.DatabaseSettings.Pass),
|
||||||
DBConn.SetConnMaxLifetime(60 * time.Second)
|
pgdriver.WithDatabase(config.DatabaseSettings.DB),
|
||||||
|
pgdriver.WithDialTimeout(30*time.Second),
|
||||||
if strings.ToLower(config.ServerSettings.RunMode) == "debug" {
|
pgdriver.WithReadTimeout(3*time.Minute),
|
||||||
DBConn.ShowSQL(true)
|
pgdriver.WithWriteTimeout(10*time.Minute),
|
||||||
DBConn.Logger().SetLevel(log.LOG_DEBUG)
|
)
|
||||||
}
|
sqldb := sql.OpenDB(pgconn)
|
||||||
|
DB = bun.NewDB(sqldb, pgdialect.New())
|
||||||
|
DB.AddQueryHook(logger.NewQueryHook(logger.QueryHookOptions{
|
||||||
|
LogSlow: 3 * time.Second,
|
||||||
|
Logger: logger.Named("PG"),
|
||||||
|
QueryLevel: zapcore.DebugLevel,
|
||||||
|
ErrorLevel: zapcore.ErrorLevel,
|
||||||
|
SlowLevel: zapcore.WarnLevel,
|
||||||
|
ErrorTemplate: "{{.Operation}}[{{.Duration}}]: {{.Query}}: {{.Error}}",
|
||||||
|
MessageTemplate: "{{.Operation}}[{{.Duration}}]: {{.Query}}",
|
||||||
|
}))
|
||||||
|
DB.SetMaxIdleConns(config.DatabaseSettings.MaxIdleConns)
|
||||||
|
DB.SetMaxOpenConns(config.DatabaseSettings.MaxOpenConns)
|
||||||
|
DB.SetConnMaxIdleTime(10 * time.Minute)
|
||||||
|
DB.SetConnMaxLifetime(60 * time.Minute)
|
||||||
|
DB.Ping()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -9,13 +9,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
RedisConn rueidis.Client
|
Rd rueidis.Client
|
||||||
Ctx = context.Background()
|
Ctx = context.Background()
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetupRedisConnection() error {
|
func SetupRedisConnection() error {
|
||||||
var err error
|
var err error
|
||||||
RedisConn, err = rueidis.NewClient(rueidis.ClientOption{
|
Rd, err = rueidis.NewClient(rueidis.ClientOption{
|
||||||
InitAddress: []string{fmt.Sprintf("%s:%d", config.RedisSettings.Host, config.RedisSettings.Port)},
|
InitAddress: []string{fmt.Sprintf("%s:%d", config.RedisSettings.Host, config.RedisSettings.Port)},
|
||||||
Password: config.RedisSettings.Password,
|
Password: config.RedisSettings.Password,
|
||||||
SelectDB: config.RedisSettings.DB,
|
SelectDB: config.RedisSettings.DB,
|
||||||
@@ -23,8 +23,8 @@ func SetupRedisConnection() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
pingCmd := RedisConn.B().Ping().Build()
|
pingCmd := Rd.B().Ping().Build()
|
||||||
result := RedisConn.Do(Ctx, pingCmd)
|
result := Rd.Do(Ctx, pingCmd)
|
||||||
if result.Error() != nil {
|
if result.Error() != nil {
|
||||||
return result.Error()
|
return result.Error()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,8 @@ go 1.19
|
|||||||
require (
|
require (
|
||||||
github.com/deckarep/golang-set/v2 v2.1.0
|
github.com/deckarep/golang-set/v2 v2.1.0
|
||||||
github.com/fufuok/utils v0.7.13
|
github.com/fufuok/utils v0.7.13
|
||||||
github.com/gin-gonic/gin v1.8.1
|
github.com/gofiber/fiber/v2 v2.38.1
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
github.com/jackc/pgx/v5 v5.0.0-beta.1
|
|
||||||
github.com/jinzhu/copier v0.3.5
|
github.com/jinzhu/copier v0.3.5
|
||||||
github.com/liamylian/jsontime/v2 v2.0.0
|
github.com/liamylian/jsontime/v2 v2.0.0
|
||||||
github.com/mozillazg/go-pinyin v0.19.0
|
github.com/mozillazg/go-pinyin v0.19.0
|
||||||
@@ -15,31 +14,35 @@ require (
|
|||||||
github.com/samber/lo v1.27.0
|
github.com/samber/lo v1.27.0
|
||||||
github.com/shopspring/decimal v1.3.1
|
github.com/shopspring/decimal v1.3.1
|
||||||
github.com/spf13/viper v1.12.0
|
github.com/spf13/viper v1.12.0
|
||||||
|
github.com/valyala/fasthttp v1.40.0
|
||||||
github.com/xuri/excelize/v2 v2.6.1
|
github.com/xuri/excelize/v2 v2.6.1
|
||||||
xorm.io/builder v0.3.12
|
go.uber.org/zap v1.23.0
|
||||||
xorm.io/xorm v1.3.1
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||||
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
|
github.com/klauspost/compress v1.15.0 // indirect
|
||||||
|
github.com/rogpeppe/go-internal v1.8.0 // indirect
|
||||||
|
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
|
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||||
|
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
||||||
|
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||||
|
mellium.im/sasl v0.3.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
|
||||||
github.com/go-playground/locales v0.14.0 // indirect
|
|
||||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
|
||||||
github.com/go-playground/validator/v10 v10.11.0 // indirect
|
|
||||||
github.com/goccy/go-json v0.9.10 // indirect
|
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
|
||||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
|
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/leodido/go-urn v1.2.1 // indirect
|
|
||||||
github.com/magiconair/properties v1.8.6 // indirect
|
github.com/magiconair/properties v1.8.6 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||||
github.com/onsi/ginkgo v1.16.5 // indirect
|
|
||||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.0.2 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.2 // indirect
|
||||||
github.com/richardlehane/mscfb v1.0.4 // indirect
|
github.com/richardlehane/mscfb v1.0.4 // indirect
|
||||||
@@ -49,16 +52,18 @@ require (
|
|||||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/subosito/gotenv v1.3.0 // indirect
|
github.com/subosito/gotenv v1.3.0 // indirect
|
||||||
github.com/syndtr/goleveldb v1.0.0 // indirect
|
github.com/uptrace/bun v1.1.8
|
||||||
github.com/ugorji/go/codec v1.2.7 // indirect
|
github.com/uptrace/bun/dialect/pgdialect v1.1.8
|
||||||
|
github.com/uptrace/bun/driver/pgdriver v1.1.8
|
||||||
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 // indirect
|
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 // indirect
|
||||||
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect
|
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 // indirect
|
go.uber.org/atomic v1.10.0 // indirect
|
||||||
|
go.uber.org/multierr v1.8.0 // indirect
|
||||||
|
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d // indirect
|
||||||
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
|
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
|
||||||
golang.org/x/net v0.0.0-20220812174116-3211cb980234 // indirect
|
golang.org/x/net v0.0.0-20220812174116-3211cb980234 // indirect
|
||||||
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664 // indirect
|
golang.org/x/sys v0.0.0-20220907062415-87db552b00fd // indirect
|
||||||
golang.org/x/text v0.3.7 // indirect
|
golang.org/x/text v0.3.7 // indirect
|
||||||
google.golang.org/protobuf v1.28.1 // indirect
|
|
||||||
gopkg.in/ini.v1 v1.66.4 // indirect
|
gopkg.in/ini.v1 v1.66.4 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
|||||||
@@ -36,126 +36,42 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
|
|||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||||
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
|
||||||
gitee.com/travelliu/dm v1.8.11192/go.mod h1:DHTzyhCrM843x9VdKVbZ+GKXGRbKM2sJ4LxihRxShkE=
|
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
||||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
|
||||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
|
||||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
|
||||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
|
||||||
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
|
||||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
|
||||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
|
||||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
|
||||||
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
|
||||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
|
||||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
|
||||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
|
||||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
|
||||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
|
||||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||||
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
|
||||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
|
||||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
|
||||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
|
||||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
|
||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
|
||||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
|
||||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
|
||||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI=
|
github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI=
|
||||||
github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
|
github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
|
||||||
github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
|
||||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
|
||||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
|
||||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
|
||||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
|
||||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
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.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
|
||||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
|
||||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
|
||||||
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
||||||
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.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
|
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
|
||||||
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
|
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
|
||||||
github.com/fufuok/utils v0.7.13 h1:FGx8Mnfg0ZB8HdVz1X60JJ2kFu1rtcsFDYUxUTzNKkU=
|
github.com/fufuok/utils v0.7.13 h1:FGx8Mnfg0ZB8HdVz1X60JJ2kFu1rtcsFDYUxUTzNKkU=
|
||||||
github.com/fufuok/utils v0.7.13/go.mod h1:ztIaorPqZGdbvmW3YlwQp80K8rKJmEy6xa1KwpJSsmk=
|
github.com/fufuok/utils v0.7.13/go.mod h1:ztIaorPqZGdbvmW3YlwQp80K8rKJmEy6xa1KwpJSsmk=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
|
||||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
|
||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
|
||||||
github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
|
|
||||||
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/gofiber/fiber/v2 v2.38.1 h1:GEQ/Yt3Wsf2a30iTqtLXlBYJZso0JXPovt/tmj5H9jU=
|
||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/gofiber/fiber/v2 v2.38.1/go.mod h1:t0NlbaXzuGH7I+7M4paE848fNWInZ7mfxI/Er1fTth8=
|
||||||
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
|
||||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
|
||||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
|
||||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
|
||||||
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
|
|
||||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
|
||||||
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
|
||||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
|
||||||
github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2BOGlCyvTqsp/xIw=
|
|
||||||
github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
|
|
||||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
|
||||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
|
||||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
|
||||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
|
||||||
github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
|
||||||
github.com/goccy/go-json v0.9.10 h1:hCeNmprSNLB8B8vQKWl6DpuH0t60oEs+TAk9a7CScKc=
|
|
||||||
github.com/goccy/go-json v0.9.10/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
|
||||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
|
||||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
|
||||||
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
|
||||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
|
||||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
|
||||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
@@ -180,11 +96,6 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
|
|||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
|
||||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
|
||||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
|
||||||
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 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/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
@@ -195,9 +106,7 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
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.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
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 v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
@@ -214,170 +123,41 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe
|
|||||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||||
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
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/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/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
|
||||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
|
||||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
|
||||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
|
||||||
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
|
||||||
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
|
||||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
|
||||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
|
||||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
|
||||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
|
||||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
|
||||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
|
||||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
|
||||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
|
||||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
|
||||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
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/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
|
||||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
|
||||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
|
||||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
|
||||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
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/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
|
||||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
|
||||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
|
||||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
|
||||||
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
|
||||||
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
|
|
||||||
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
|
|
||||||
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
|
|
||||||
github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk=
|
|
||||||
github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
|
|
||||||
github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
|
|
||||||
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
|
|
||||||
github.com/jackc/pgconn v1.8.1/go.mod h1:JV6m6b6jhjdmzchES0drzCcYcAHS1OPD5xu3OZ/lE2g=
|
|
||||||
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
|
|
||||||
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
|
|
||||||
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
|
|
||||||
github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
|
|
||||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
|
||||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
|
||||||
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
|
|
||||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
|
|
||||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
|
|
||||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
|
||||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
|
||||||
github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
|
||||||
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
|
||||||
github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
|
||||||
github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
|
||||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
|
|
||||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
|
||||||
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
|
|
||||||
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
|
|
||||||
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
|
|
||||||
github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0=
|
|
||||||
github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po=
|
|
||||||
github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ=
|
|
||||||
github.com/jackc/pgtype v1.7.0/go.mod h1:ZnHF+rMePVqDKaOfJVI4Q8IVvAQMryDlDkZnKOI75BE=
|
|
||||||
github.com/jackc/pgtype v1.8.0/go.mod h1:PqDKcEBtllAtk/2p6z6SHdXW5UB+MhE75tUol2OKexE=
|
|
||||||
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
|
||||||
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
|
||||||
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
|
||||||
github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA=
|
|
||||||
github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o=
|
|
||||||
github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg=
|
|
||||||
github.com/jackc/pgx/v4 v4.11.0/go.mod h1:i62xJgdrtVDsnL3U8ekyrQXEwGNTRoG7/8r+CIdYfcc=
|
|
||||||
github.com/jackc/pgx/v4 v4.12.0/go.mod h1:fE547h6VulLPA3kySjfnSG/e2D861g/50JlVUa/ub60=
|
|
||||||
github.com/jackc/pgx/v5 v5.0.0-beta.1 h1:tQXW/iBC2BYQ/SZK/PBpiW1Cn5/6vMzLBv8Unphg2Xw=
|
|
||||||
github.com/jackc/pgx/v5 v5.0.0-beta.1/go.mod h1:QJ8xU09HYKHOccHeisi/6sXeRG4dd3AxuV7cmKET4WA=
|
|
||||||
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
|
||||||
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
|
||||||
github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
|
||||||
github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
|
||||||
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
|
||||||
github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg=
|
github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg=
|
||||||
github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
|
github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
|
||||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
|
||||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
|
||||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
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/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
|
||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
|
||||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
|
||||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
|
||||||
github.com/liamylian/jsontime/v2 v2.0.0 h1:3if2kDW/boymUdO+4Qj/m4uaXMBSF6np9KEgg90cwH0=
|
github.com/liamylian/jsontime/v2 v2.0.0 h1:3if2kDW/boymUdO+4Qj/m4uaXMBSF6np9KEgg90cwH0=
|
||||||
github.com/liamylian/jsontime/v2 v2.0.0/go.mod h1:UHp1oAPqCBfspokvGmaGe0IAl2IgOpgOgDaKPcvcGGY=
|
github.com/liamylian/jsontime/v2 v2.0.0/go.mod h1:UHp1oAPqCBfspokvGmaGe0IAl2IgOpgOgDaKPcvcGGY=
|
||||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
|
||||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
|
||||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
|
||||||
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
|
||||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
|
||||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
|
||||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
|
||||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
|
||||||
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
|
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
|
||||||
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
|
||||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
|
||||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
|
||||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
|
||||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
|
||||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
|
||||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
|
||||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
|
||||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
|
||||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
|
||||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
|
||||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
|
||||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
|
||||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
|
||||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
|
||||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
|
||||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
|
||||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
|
||||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
|
||||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
@@ -391,129 +171,42 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9
|
|||||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||||
github.com/mozillazg/go-pinyin v0.19.0 h1:p+J8/kjJ558KPvVGYLvqBhxf8jbZA2exSLCs2uUVN8c=
|
github.com/mozillazg/go-pinyin v0.19.0 h1:p+J8/kjJ558KPvVGYLvqBhxf8jbZA2exSLCs2uUVN8c=
|
||||||
github.com/mozillazg/go-pinyin v0.19.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc=
|
github.com/mozillazg/go-pinyin v0.19.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
|
||||||
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
|
||||||
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
|
|
||||||
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
|
|
||||||
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
|
|
||||||
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
|
||||||
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
|
||||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
|
||||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
|
||||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
|
||||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
|
||||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
|
||||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
|
||||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
|
||||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
|
||||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
|
||||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
|
||||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
|
||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
|
||||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
|
||||||
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
|
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
|
||||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
|
||||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
|
||||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
|
||||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
|
||||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
|
|
||||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
|
||||||
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
|
||||||
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
|
||||||
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
|
||||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
|
||||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw=
|
github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI=
|
github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI=
|
||||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
|
||||||
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
|
||||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
|
||||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
|
||||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
|
||||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
|
||||||
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
|
||||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
|
||||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
|
||||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
|
||||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
|
||||||
github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
|
github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
|
||||||
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
|
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
|
||||||
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
||||||
github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM=
|
github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM=
|
||||||
github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
||||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
|
||||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
|
||||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
|
||||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
|
||||||
github.com/rueian/rueidis v0.0.73 h1:+r0Z6C6HMnkquPgY3zaHVpTqmCyJL56Z36GSlyBrufk=
|
github.com/rueian/rueidis v0.0.73 h1:+r0Z6C6HMnkquPgY3zaHVpTqmCyJL56Z36GSlyBrufk=
|
||||||
github.com/rueian/rueidis v0.0.73/go.mod h1:FwnfDILF2GETrvXcYFlhIiru/7NmSIm1f+7C5kutO0I=
|
github.com/rueian/rueidis v0.0.73/go.mod h1:FwnfDILF2GETrvXcYFlhIiru/7NmSIm1f+7C5kutO0I=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
|
||||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
|
||||||
github.com/samber/lo v1.27.0 h1:GOyDWxsblvqYobqsmUuMddPa2/mMzkKyojlXol4+LaQ=
|
github.com/samber/lo v1.27.0 h1:GOyDWxsblvqYobqsmUuMddPa2/mMzkKyojlXol4+LaQ=
|
||||||
github.com/samber/lo v1.27.0/go.mod h1:it33p9UtPMS7z72fP4gw/EIfQB2eI8ke7GR2wc6+Rhg=
|
github.com/samber/lo v1.27.0/go.mod h1:it33p9UtPMS7z72fP4gw/EIfQB2eI8ke7GR2wc6+Rhg=
|
||||||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
|
||||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
|
||||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
|
||||||
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
|
||||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
|
||||||
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
|
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
|
||||||
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
|
||||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
|
||||||
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/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
|
||||||
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
|
||||||
github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
|
github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
|
||||||
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
|
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
|
||||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||||
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
||||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ=
|
github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ=
|
||||||
github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI=
|
github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI=
|
||||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
|
||||||
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
|
||||||
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
@@ -525,16 +218,25 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F
|
|||||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||||
github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI=
|
github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI=
|
||||||
github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs=
|
github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs=
|
||||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
|
||||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
|
||||||
github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M=
|
github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo=
|
||||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs=
|
||||||
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
github.com/uptrace/bun v1.1.8 h1:slxuaP4LYWFbPRUmTtQhfJN+6eX/6ar2HDKYTcI50SA=
|
||||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
github.com/uptrace/bun v1.1.8/go.mod h1:iT89ESdV3uMupD9ixt6Khidht+BK0STabK/LeZE+B84=
|
||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/uptrace/bun/dialect/pgdialect v1.1.8 h1:wayJhjYDPGv8tgOBLolbBtSFQ0TihFoo8E1T129UdA8=
|
||||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/uptrace/bun/dialect/pgdialect v1.1.8/go.mod h1:nNbU8PHTjTUM+CRtGmqyBb9zcuRAB8I680/qoFSmBUk=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/uptrace/bun/driver/pgdriver v1.1.8 h1:gyL22axRQfjJS2Umq0erzJnp0bLOdUE8/USKZHPQB8o=
|
||||||
|
github.com/uptrace/bun/driver/pgdriver v1.1.8/go.mod h1:4tHK0h7a/UoldBoe9J3GU4tEYjr3mkd62U3Kq3PVk3E=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
|
github.com/valyala/fasthttp v1.40.0 h1:CRq/00MfruPGFLTQKY8b+8SfdK60TxNztjRMnH0t1Yc=
|
||||||
|
github.com/valyala/fasthttp v1.40.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
|
||||||
|
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||||
|
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||||
|
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
|
||||||
|
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
|
||||||
|
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||||
|
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||||
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 h1:6932x8ltq1w4utjmfMPVj09jdMlkY0aiA6+Skbtl3/c=
|
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 h1:6932x8ltq1w4utjmfMPVj09jdMlkY0aiA6+Skbtl3/c=
|
||||||
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
|
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
|
||||||
github.com/xuri/excelize/v2 v2.6.1 h1:ICBdtw803rmhLN3zfvyEGH3cwSmZv+kde7LhTDT659k=
|
github.com/xuri/excelize/v2 v2.6.1 h1:ICBdtw803rmhLN3zfvyEGH3cwSmZv+kde7LhTDT659k=
|
||||||
@@ -545,51 +247,31 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
|||||||
github.com/yuin/goldmark v1.1.27/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=
|
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
|
||||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
|
||||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
|
||||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
|
||||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
|
||||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
|
||||||
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
|
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
|
||||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
||||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY=
|
||||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
|
||||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
|
||||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
||||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
|
||||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
|
||||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
|
||||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/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-20220817201139-bc19a97f63c8 h1:GIAS/yBem/gq2MUqgNIzUHW7cJMmx3TGZOrnyYaNQ6c=
|
|
||||||
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d h1:3qF+Z8Hkrw9sOhrFHti9TlB1Hkac1x+DNRkv0XQiFjo=
|
||||||
|
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/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-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-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
@@ -627,27 +309,18 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57 h1:LQmS1nU0twXLA96Kt7U9qtHJEbBk3z6Q0V4UXjZkpr4=
|
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
@@ -658,7 +331,6 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/
|
|||||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
@@ -669,6 +341,7 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
|
|||||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
|
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||||
golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E=
|
golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E=
|
||||||
golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
@@ -690,37 +363,19 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
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-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-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -736,24 +391,19 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664 h1:v1W7bwXHsnLLloWYTVEdvGvA7BHMeBYsPcF0GLDxIRs=
|
golang.org/x/sys v0.0.0-20220907062415-87db552b00fd h1:AZeIEzg+8RCELJYq8w+ODLVxFgLMMigSwO/ffKPEd9U=
|
||||||
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220907062415-87db552b00fd/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
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/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.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@@ -765,32 +415,24 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||||||
golang.org/x/text v0.3.6/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 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
@@ -798,7 +440,6 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn
|
|||||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
@@ -819,22 +460,15 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc
|
|||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||||
golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023 h1:0c3L82FDQ5rt1bjTBlchS8t6RQ6299/+5bWMnRLh+uI=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618=
|
|
||||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||||
@@ -855,7 +489,6 @@ google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ
|
|||||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||||
@@ -867,7 +500,6 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn
|
|||||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
|
||||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||||
@@ -899,15 +531,10 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D
|
|||||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
|
||||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||||
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
@@ -930,30 +557,16 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
|||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
|
||||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
|
||||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
|
||||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
|
||||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
|
||||||
gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4=
|
gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4=
|
||||||
gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
|
||||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
|
||||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
@@ -961,7 +574,6 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C
|
|||||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
@@ -969,122 +581,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU=
|
mellium.im/sasl v0.3.0 h1:0qoaTCTo5Py7u/g0cBIQZcMOgG/5LM71nshbXwznBh8=
|
||||||
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
mellium.im/sasl v0.3.0/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw=
|
||||||
modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.33.9/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.33.11/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.34.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.4/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.5/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.7/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.8/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.10/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.15/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.16/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.17/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/cc/v3 v3.35.18 h1:rMZhRcWrba0y3nVmdiQ7kxAgOOSq2m2f2VzjHLgEs6U=
|
|
||||||
modernc.org/cc/v3 v3.35.18/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
|
||||||
modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60=
|
|
||||||
modernc.org/ccgo/v3 v3.10.0/go.mod h1:c0yBmkRFi7uW4J7fwx/JiijwOjeAeR2NoSaRVFPmjMw=
|
|
||||||
modernc.org/ccgo/v3 v3.11.0/go.mod h1:dGNposbDp9TOZ/1KBxghxtUp/bzErD0/0QW4hhSaBMI=
|
|
||||||
modernc.org/ccgo/v3 v3.11.1/go.mod h1:lWHxfsn13L3f7hgGsGlU28D9eUOf6y3ZYHKoPaKU0ag=
|
|
||||||
modernc.org/ccgo/v3 v3.11.3/go.mod h1:0oHunRBMBiXOKdaglfMlRPBALQqsfrCKXgw9okQ3GEw=
|
|
||||||
modernc.org/ccgo/v3 v3.12.4/go.mod h1:Bk+m6m2tsooJchP/Yk5ji56cClmN6R1cqc9o/YtbgBQ=
|
|
||||||
modernc.org/ccgo/v3 v3.12.6/go.mod h1:0Ji3ruvpFPpz+yu+1m0wk68pdr/LENABhTrDkMDWH6c=
|
|
||||||
modernc.org/ccgo/v3 v3.12.8/go.mod h1:Hq9keM4ZfjCDuDXxaHptpv9N24JhgBZmUG5q60iLgUo=
|
|
||||||
modernc.org/ccgo/v3 v3.12.11/go.mod h1:0jVcmyDwDKDGWbcrzQ+xwJjbhZruHtouiBEvDfoIsdg=
|
|
||||||
modernc.org/ccgo/v3 v3.12.14/go.mod h1:GhTu1k0YCpJSuWwtRAEHAol5W7g1/RRfS4/9hc9vF5I=
|
|
||||||
modernc.org/ccgo/v3 v3.12.18/go.mod h1:jvg/xVdWWmZACSgOiAhpWpwHWylbJaSzayCqNOJKIhs=
|
|
||||||
modernc.org/ccgo/v3 v3.12.20/go.mod h1:aKEdssiu7gVgSy/jjMastnv/q6wWGRbszbheXgWRHc8=
|
|
||||||
modernc.org/ccgo/v3 v3.12.21/go.mod h1:ydgg2tEprnyMn159ZO/N4pLBqpL7NOkJ88GT5zNU2dE=
|
|
||||||
modernc.org/ccgo/v3 v3.12.22/go.mod h1:nyDVFMmMWhMsgQw+5JH6B6o4MnZ+UQNw1pp52XYFPRk=
|
|
||||||
modernc.org/ccgo/v3 v3.12.25/go.mod h1:UaLyWI26TwyIT4+ZFNjkyTbsPsY3plAEB6E7L/vZV3w=
|
|
||||||
modernc.org/ccgo/v3 v3.12.29/go.mod h1:FXVjG7YLf9FetsS2OOYcwNhcdOLGt8S9bQ48+OP75cE=
|
|
||||||
modernc.org/ccgo/v3 v3.12.36/go.mod h1:uP3/Fiezp/Ga8onfvMLpREq+KUjUmYMxXPO8tETHtA8=
|
|
||||||
modernc.org/ccgo/v3 v3.12.38/go.mod h1:93O0G7baRST1vNj4wnZ49b1kLxt0xCW5Hsa2qRaZPqc=
|
|
||||||
modernc.org/ccgo/v3 v3.12.43/go.mod h1:k+DqGXd3o7W+inNujK15S5ZYuPoWYLpF5PYougCmthU=
|
|
||||||
modernc.org/ccgo/v3 v3.12.46/go.mod h1:UZe6EvMSqOxaJ4sznY7b23/k13R8XNlyWsO5bAmSgOE=
|
|
||||||
modernc.org/ccgo/v3 v3.12.47/go.mod h1:m8d6p0zNps187fhBwzY/ii6gxfjob1VxWb919Nk1HUk=
|
|
||||||
modernc.org/ccgo/v3 v3.12.50/go.mod h1:bu9YIwtg+HXQxBhsRDE+cJjQRuINuT9PUK4orOco/JI=
|
|
||||||
modernc.org/ccgo/v3 v3.12.51/go.mod h1:gaIIlx4YpmGO2bLye04/yeblmvWEmE4BBBls4aJXFiE=
|
|
||||||
modernc.org/ccgo/v3 v3.12.53/go.mod h1:8xWGGTFkdFEWBEsUmi+DBjwu/WLy3SSOrqEmKUjMeEg=
|
|
||||||
modernc.org/ccgo/v3 v3.12.54/go.mod h1:yANKFTm9llTFVX1FqNKHE0aMcQb1fuPJx6p8AcUx+74=
|
|
||||||
modernc.org/ccgo/v3 v3.12.55/go.mod h1:rsXiIyJi9psOwiBkplOaHye5L4MOOaCjHg1Fxkj7IeU=
|
|
||||||
modernc.org/ccgo/v3 v3.12.56/go.mod h1:ljeFks3faDseCkr60JMpeDb2GSO3TKAmrzm7q9YOcMU=
|
|
||||||
modernc.org/ccgo/v3 v3.12.57/go.mod h1:hNSF4DNVgBl8wYHpMvPqQWDQx8luqxDnNGCMM4NFNMc=
|
|
||||||
modernc.org/ccgo/v3 v3.12.60/go.mod h1:k/Nn0zdO1xHVWjPYVshDeWKqbRWIfif5dtsIOCUVMqM=
|
|
||||||
modernc.org/ccgo/v3 v3.12.65/go.mod h1:D6hQtKxPNZiY6wDBtehSGKFKmyXn53F8nGTpH+POmS4=
|
|
||||||
modernc.org/ccgo/v3 v3.12.66/go.mod h1:jUuxlCFZTUZLMV08s7B1ekHX5+LIAurKTTaugUr/EhQ=
|
|
||||||
modernc.org/ccgo/v3 v3.12.67/go.mod h1:Bll3KwKvGROizP2Xj17GEGOTrlvB1XcVaBrC90ORO84=
|
|
||||||
modernc.org/ccgo/v3 v3.12.73/go.mod h1:hngkB+nUUqzOf3iqsM48Gf1FZhY599qzVg1iX+BT3cQ=
|
|
||||||
modernc.org/ccgo/v3 v3.12.81/go.mod h1:p2A1duHoBBg1mFtYvnhAnQyI6vL0uw5PGYLSIgF6rYY=
|
|
||||||
modernc.org/ccgo/v3 v3.12.82 h1:wudcnJyjLj1aQQCXF3IM9Gz2X6UNjw+afIghzdtn0v8=
|
|
||||||
modernc.org/ccgo/v3 v3.12.82/go.mod h1:ApbflUfa5BKadjHynCficldU1ghjen84tuM5jRynB7w=
|
|
||||||
modernc.org/ccorpus v1.11.1/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
|
||||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
|
||||||
modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
|
||||||
modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q=
|
|
||||||
modernc.org/libc v1.11.0/go.mod h1:2lOfPmj7cz+g1MrPNmX65QCzVxgNq2C5o0jdLY2gAYg=
|
|
||||||
modernc.org/libc v1.11.2/go.mod h1:ioIyrl3ETkugDO3SGZ+6EOKvlP3zSOycUETe4XM4n8M=
|
|
||||||
modernc.org/libc v1.11.5/go.mod h1:k3HDCP95A6U111Q5TmG3nAyUcp3kR5YFZTeDS9v8vSU=
|
|
||||||
modernc.org/libc v1.11.6/go.mod h1:ddqmzR6p5i4jIGK1d/EiSw97LBcE3dK24QEwCFvgNgE=
|
|
||||||
modernc.org/libc v1.11.11/go.mod h1:lXEp9QOOk4qAYOtL3BmMve99S5Owz7Qyowzvg6LiZso=
|
|
||||||
modernc.org/libc v1.11.13/go.mod h1:ZYawJWlXIzXy2Pzghaf7YfM8OKacP3eZQI81PDLFdY8=
|
|
||||||
modernc.org/libc v1.11.16/go.mod h1:+DJquzYi+DMRUtWI1YNxrlQO6TcA5+dRRiq8HWBWRC8=
|
|
||||||
modernc.org/libc v1.11.19/go.mod h1:e0dgEame6mkydy19KKaVPBeEnyJB4LGNb0bBH1EtQ3I=
|
|
||||||
modernc.org/libc v1.11.24/go.mod h1:FOSzE0UwookyT1TtCJrRkvsOrX2k38HoInhw+cSCUGk=
|
|
||||||
modernc.org/libc v1.11.26/go.mod h1:SFjnYi9OSd2W7f4ct622o/PAYqk7KHv6GS8NZULIjKY=
|
|
||||||
modernc.org/libc v1.11.27/go.mod h1:zmWm6kcFXt/jpzeCgfvUNswM0qke8qVwxqZrnddlDiE=
|
|
||||||
modernc.org/libc v1.11.28/go.mod h1:Ii4V0fTFcbq3qrv3CNn+OGHAvzqMBvC7dBNyC4vHZlg=
|
|
||||||
modernc.org/libc v1.11.31/go.mod h1:FpBncUkEAtopRNJj8aRo29qUiyx5AvAlAxzlx9GNaVM=
|
|
||||||
modernc.org/libc v1.11.34/go.mod h1:+Tzc4hnb1iaX/SKAutJmfzES6awxfU1BPvrrJO0pYLg=
|
|
||||||
modernc.org/libc v1.11.37/go.mod h1:dCQebOwoO1046yTrfUE5nX1f3YpGZQKNcITUYWlrAWo=
|
|
||||||
modernc.org/libc v1.11.39/go.mod h1:mV8lJMo2S5A31uD0k1cMu7vrJbSA3J3waQJxpV4iqx8=
|
|
||||||
modernc.org/libc v1.11.42/go.mod h1:yzrLDU+sSjLE+D4bIhS7q1L5UwXDOw99PLSX0BlZvSQ=
|
|
||||||
modernc.org/libc v1.11.44/go.mod h1:KFq33jsma7F5WXiYelU8quMJasCCTnHK0mkri4yPHgA=
|
|
||||||
modernc.org/libc v1.11.45/go.mod h1:Y192orvfVQQYFzCNsn+Xt0Hxt4DiO4USpLNXBlXg/tM=
|
|
||||||
modernc.org/libc v1.11.47/go.mod h1:tPkE4PzCTW27E6AIKIR5IwHAQKCAtudEIeAV1/SiyBg=
|
|
||||||
modernc.org/libc v1.11.49/go.mod h1:9JrJuK5WTtoTWIFQ7QjX2Mb/bagYdZdscI3xrvHbXjE=
|
|
||||||
modernc.org/libc v1.11.51/go.mod h1:R9I8u9TS+meaWLdbfQhq2kFknTW0O3aw3kEMqDDxMaM=
|
|
||||||
modernc.org/libc v1.11.53/go.mod h1:5ip5vWYPAoMulkQ5XlSJTy12Sz5U6blOQiYasilVPsU=
|
|
||||||
modernc.org/libc v1.11.54/go.mod h1:S/FVnskbzVUrjfBqlGFIPA5m7UwB3n9fojHhCNfSsnw=
|
|
||||||
modernc.org/libc v1.11.55/go.mod h1:j2A5YBRm6HjNkoSs/fzZrSxCuwWqcMYTDPLNx0URn3M=
|
|
||||||
modernc.org/libc v1.11.56/go.mod h1:pakHkg5JdMLt2OgRadpPOTnyRXm/uzu+Yyg/LSLdi18=
|
|
||||||
modernc.org/libc v1.11.58/go.mod h1:ns94Rxv0OWyoQrDqMFfWwka2BcaF6/61CqJRK9LP7S8=
|
|
||||||
modernc.org/libc v1.11.70/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw=
|
|
||||||
modernc.org/libc v1.11.71/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw=
|
|
||||||
modernc.org/libc v1.11.75/go.mod h1:dGRVugT6edz361wmD9gk6ax1AbDSe0x5vji0dGJiPT0=
|
|
||||||
modernc.org/libc v1.11.82/go.mod h1:NF+Ek1BOl2jeC7lw3a7Jj5PWyHPwWD4aq3wVKxqV1fI=
|
|
||||||
modernc.org/libc v1.11.86/go.mod h1:ePuYgoQLmvxdNT06RpGnaDKJmDNEkV7ZPKI2jnsvZoE=
|
|
||||||
modernc.org/libc v1.11.87 h1:PzIzOqtlzMDDcCzJ5cUP6h/Ku6Fa9iyflP2ccTY64aE=
|
|
||||||
modernc.org/libc v1.11.87/go.mod h1:Qvd5iXTeLhI5PS0XSyqMY99282y+3euapQFxM7jYnpY=
|
|
||||||
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
|
||||||
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
|
||||||
modernc.org/mathutil v1.4.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
|
||||||
modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8=
|
|
||||||
modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
|
||||||
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
|
|
||||||
modernc.org/memory v1.0.5 h1:XRch8trV7GgvTec2i7jc33YlUI0RKVDBvZ5eZ5m8y14=
|
|
||||||
modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM=
|
|
||||||
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
|
|
||||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
|
||||||
modernc.org/sqlite v1.14.2 h1:ohsW2+e+Qe2To1W6GNezzKGwjXwSax6R+CrhRxVaFbE=
|
|
||||||
modernc.org/sqlite v1.14.2/go.mod h1:yqfn85u8wVOE6ub5UT8VI9JjhrwBUUCNyTACN0h6Sx8=
|
|
||||||
modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
|
|
||||||
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
|
|
||||||
modernc.org/tcl v1.8.13/go.mod h1:V+q/Ef0IJaNUSECieLU4o+8IScapxnMyFV6i/7uQlAY=
|
|
||||||
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
|
|
||||||
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
|
||||||
modernc.org/z v1.2.19/go.mod h1:+ZpP0pc4zz97eukOzW3xagV/lS82IpPN9NGG5pNF9vY=
|
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
|
||||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
|
||||||
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
|
||||||
xorm.io/builder v0.3.12 h1:ASZYX7fQmy+o8UJdhlLHSW57JDOkM8DNhcAF5d0LiJM=
|
|
||||||
xorm.io/builder v0.3.12/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
|
||||||
xorm.io/xorm v1.3.1 h1:z5egKrDoOLqZFhMjcGF4FBHiTmE5/feQoHclfhNidfM=
|
|
||||||
xorm.io/xorm v1.3.1/go.mod h1:9NbjqdnjX6eyjRRhh01GHm64r6N9shTb/8Ak3YRt8Nw=
|
|
||||||
|
|||||||
@@ -0,0 +1,163 @@
|
|||||||
|
package logger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/uptrace/bun"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"go.uber.org/zap/zapcore"
|
||||||
|
)
|
||||||
|
|
||||||
|
// QueryHookOptions logging options
|
||||||
|
type QueryHookOptions struct {
|
||||||
|
LogSlow time.Duration
|
||||||
|
Logger *zap.Logger
|
||||||
|
QueryLevel zapcore.Level
|
||||||
|
SlowLevel zapcore.Level
|
||||||
|
ErrorLevel zapcore.Level
|
||||||
|
MessageTemplate string
|
||||||
|
ErrorTemplate string
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryHook wraps query hook
|
||||||
|
type QueryHook struct {
|
||||||
|
opts QueryHookOptions
|
||||||
|
errorTemplate *template.Template
|
||||||
|
messageTemplate *template.Template
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogEntryVars variables made available t otemplate
|
||||||
|
type LogEntryVars struct {
|
||||||
|
Timestamp time.Time
|
||||||
|
Query string
|
||||||
|
Operation string
|
||||||
|
Duration time.Duration
|
||||||
|
Error error
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewQueryHook returns new instance
|
||||||
|
func NewQueryHook(opts QueryHookOptions) *QueryHook {
|
||||||
|
h := new(QueryHook)
|
||||||
|
|
||||||
|
if opts.ErrorTemplate == "" {
|
||||||
|
opts.ErrorTemplate = "{{.Operation}}[{{.Duration}}]: {{.Query}}: {{.Error}}"
|
||||||
|
}
|
||||||
|
if opts.MessageTemplate == "" {
|
||||||
|
opts.MessageTemplate = "{{.Operation}}[{{.Duration}}]: {{.Query}}"
|
||||||
|
}
|
||||||
|
h.opts = opts
|
||||||
|
errorTemplate, err := template.New("ErrorTemplate").Parse(h.opts.ErrorTemplate)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
messageTemplate, err := template.New("MessageTemplate").Parse(h.opts.MessageTemplate)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
h.errorTemplate = errorTemplate
|
||||||
|
h.messageTemplate = messageTemplate
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
// BeforeQuery does nothing tbh
|
||||||
|
func (h *QueryHook) BeforeQuery(ctx context.Context, event *bun.QueryEvent) context.Context {
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
// AfterQuery convert a bun QueryEvent into a logrus message
|
||||||
|
func (h *QueryHook) AfterQuery(ctx context.Context, event *bun.QueryEvent) {
|
||||||
|
var level zapcore.Level
|
||||||
|
var isError bool
|
||||||
|
var msg bytes.Buffer
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
dur := now.Sub(event.StartTime)
|
||||||
|
|
||||||
|
switch event.Err {
|
||||||
|
case nil, sql.ErrNoRows:
|
||||||
|
isError = false
|
||||||
|
if h.opts.LogSlow > 0 && dur >= h.opts.LogSlow {
|
||||||
|
level = h.opts.SlowLevel
|
||||||
|
} else {
|
||||||
|
level = h.opts.QueryLevel
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
isError = true
|
||||||
|
level = h.opts.ErrorLevel
|
||||||
|
}
|
||||||
|
if level == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
args := &LogEntryVars{
|
||||||
|
Timestamp: now,
|
||||||
|
Query: string(event.Query),
|
||||||
|
Operation: eventOperation(event),
|
||||||
|
Duration: dur,
|
||||||
|
Error: event.Err,
|
||||||
|
}
|
||||||
|
|
||||||
|
if isError {
|
||||||
|
if err := h.errorTemplate.Execute(&msg, args); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := h.messageTemplate.Execute(&msg, args); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch level {
|
||||||
|
case zapcore.DebugLevel:
|
||||||
|
h.opts.Logger.Debug(msg.String(), zap.String("query", event.Query), zap.Any("args", event.QueryArgs))
|
||||||
|
case zapcore.InfoLevel:
|
||||||
|
h.opts.Logger.Info(msg.String(), zap.String("query", event.Query), zap.Any("args", event.QueryArgs))
|
||||||
|
case zapcore.WarnLevel:
|
||||||
|
h.opts.Logger.Warn(msg.String(), zap.String("query", event.Query), zap.Any("args", event.QueryArgs))
|
||||||
|
case zapcore.ErrorLevel:
|
||||||
|
h.opts.Logger.Error(msg.String(), zap.String("query", event.Query), zap.Any("args", event.QueryArgs), zap.Error(event.Err))
|
||||||
|
case zapcore.FatalLevel:
|
||||||
|
h.opts.Logger.Fatal(msg.String(), zap.String("query", event.Query), zap.Any("args", event.QueryArgs), zap.Error(event.Err))
|
||||||
|
case zapcore.PanicLevel:
|
||||||
|
h.opts.Logger.Panic(msg.String(), zap.String("query", event.Query), zap.Any("args", event.QueryArgs), zap.Error(event.Err))
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("unsupported level: %v", level))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// taken from bun
|
||||||
|
func eventOperation(event *bun.QueryEvent) string {
|
||||||
|
switch event.QueryAppender.(type) {
|
||||||
|
case *bun.SelectQuery:
|
||||||
|
return "SELECT"
|
||||||
|
case *bun.InsertQuery:
|
||||||
|
return "INSERT"
|
||||||
|
case *bun.UpdateQuery:
|
||||||
|
return "UPDATE"
|
||||||
|
case *bun.DeleteQuery:
|
||||||
|
return "DELETE"
|
||||||
|
case *bun.CreateTableQuery:
|
||||||
|
return "CREATE TABLE"
|
||||||
|
case *bun.DropTableQuery:
|
||||||
|
return "DROP TABLE"
|
||||||
|
}
|
||||||
|
return queryOperation(event.Query)
|
||||||
|
}
|
||||||
|
|
||||||
|
// taken from bun
|
||||||
|
func queryOperation(name string) string {
|
||||||
|
if idx := strings.Index(name, " "); idx > 0 {
|
||||||
|
name = name[:idx]
|
||||||
|
}
|
||||||
|
if len(name) > 16 {
|
||||||
|
name = name[:16]
|
||||||
|
}
|
||||||
|
return string(name)
|
||||||
|
}
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
package logger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"go.uber.org/zap/zapcore"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
logger *zap.Logger
|
||||||
|
sugaredLogger *zap.SugaredLogger
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
consoleWriterSync := zapcore.AddSync(os.Stderr)
|
||||||
|
rollingWriterSync := zapcore.AddSync(newRollingWriter())
|
||||||
|
|
||||||
|
consoleEncoderConfig := zap.NewProductionEncoderConfig()
|
||||||
|
consoleEncoderConfig.EncodeTime = zapcore.RFC3339TimeEncoder
|
||||||
|
consoleEncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
|
||||||
|
|
||||||
|
jsonEncoderConfig := zap.NewProductionEncoderConfig()
|
||||||
|
jsonEncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
||||||
|
|
||||||
|
consoleEncoder := zapcore.NewConsoleEncoder(consoleEncoderConfig)
|
||||||
|
jsonEncoder := zapcore.NewJSONEncoder(jsonEncoderConfig)
|
||||||
|
core := zapcore.NewTee(
|
||||||
|
zapcore.NewCore(
|
||||||
|
consoleEncoder,
|
||||||
|
consoleWriterSync,
|
||||||
|
zapcore.DebugLevel,
|
||||||
|
),
|
||||||
|
zapcore.NewCore(
|
||||||
|
jsonEncoder,
|
||||||
|
rollingWriterSync,
|
||||||
|
zapcore.DebugLevel,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
logger = zap.New(core).Named("App")
|
||||||
|
sugaredLogger = logger.Sugar()
|
||||||
|
logger.Info("Logger initialized.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetLogger() *zap.Logger {
|
||||||
|
return logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func Panic(msg string, fields ...zap.Field) {
|
||||||
|
logger.Panic(msg, fields...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fatal(msg string, fields ...zap.Field) {
|
||||||
|
logger.Fatal(msg, fields...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Error(msg string, fields ...zap.Field) {
|
||||||
|
logger.Error(msg, fields...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Warn(msg string, fields ...zap.Field) {
|
||||||
|
logger.Warn(msg, fields...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Info(msg string, fields ...zap.Field) {
|
||||||
|
logger.Info(msg, fields...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Debug(msg string, fields ...zap.Field) {
|
||||||
|
logger.Debug(msg, fields...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Panicr(v ...interface{}) {
|
||||||
|
sugaredLogger.Panic(v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Panicf(format string, v ...interface{}) {
|
||||||
|
sugaredLogger.Panicf(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Errorr(v ...interface{}) {
|
||||||
|
sugaredLogger.Panic(v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Errorf(format string, v ...interface{}) {
|
||||||
|
sugaredLogger.Panicf(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Warnr(v ...interface{}) {
|
||||||
|
sugaredLogger.Warn(v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Warnf(format string, v ...interface{}) {
|
||||||
|
sugaredLogger.Warnf(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Infor(v ...interface{}) {
|
||||||
|
sugaredLogger.Info(v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Infof(format string, v ...interface{}) {
|
||||||
|
sugaredLogger.Infof(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Debugr(v ...interface{}) {
|
||||||
|
sugaredLogger.Debug(v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Debugf(format string, v ...interface{}) {
|
||||||
|
sugaredLogger.Debugf(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Named(names ...string) *zap.Logger {
|
||||||
|
var l = logger
|
||||||
|
for _, name := range names {
|
||||||
|
l = l.Named(name)
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func NamedSugar(names ...string) *zap.SugaredLogger {
|
||||||
|
return Named(names...).Sugar()
|
||||||
|
}
|
||||||
|
|
||||||
|
func With(fields ...zap.Field) *zap.Logger {
|
||||||
|
return logger.With(fields...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithSugar(fields ...zap.Field) *zap.SugaredLogger {
|
||||||
|
return logger.With(fields...).Sugar()
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package logger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config defines the config for middleware
|
||||||
|
type LogMiddlewareConfig struct {
|
||||||
|
// Next defines a function to skip this middleware when returned true.
|
||||||
|
//
|
||||||
|
// Optional. Default: nil
|
||||||
|
Next func(c *fiber.Ctx) bool
|
||||||
|
|
||||||
|
// Logger defines zap logger instance
|
||||||
|
Logger *zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a new middleware handler
|
||||||
|
func NewLogMiddleware(config LogMiddlewareConfig) fiber.Handler {
|
||||||
|
var (
|
||||||
|
errPadding = 15
|
||||||
|
start, stop time.Time
|
||||||
|
once sync.Once
|
||||||
|
errHandler fiber.ErrorHandler
|
||||||
|
)
|
||||||
|
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
if config.Next != nil && config.Next(c) {
|
||||||
|
return c.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
once.Do(func() {
|
||||||
|
errHandler = c.App().Config().ErrorHandler
|
||||||
|
stack := c.App().Stack()
|
||||||
|
for m := range stack {
|
||||||
|
for r := range stack[m] {
|
||||||
|
if len(stack[m][r].Path) > errPadding {
|
||||||
|
errPadding = len(stack[m][r].Path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
start = time.Now()
|
||||||
|
|
||||||
|
chainErr := c.Next()
|
||||||
|
|
||||||
|
if chainErr != nil {
|
||||||
|
if err := errHandler(c, chainErr); err != nil {
|
||||||
|
_ = c.SendStatus(fiber.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stop = time.Now()
|
||||||
|
|
||||||
|
fields := []zap.Field{
|
||||||
|
zap.Namespace("context"),
|
||||||
|
zap.String("pid", strconv.Itoa(os.Getpid())),
|
||||||
|
zap.String("time", stop.Sub(start).String()),
|
||||||
|
zap.Object("response", Resp(c.Response())),
|
||||||
|
zap.Object("request", Req(c)),
|
||||||
|
}
|
||||||
|
|
||||||
|
if u := c.Locals("userId"); u != nil {
|
||||||
|
fields = append(fields, zap.Uint("userId", u.(uint)))
|
||||||
|
}
|
||||||
|
|
||||||
|
formatErr := ""
|
||||||
|
if chainErr != nil {
|
||||||
|
formatErr = chainErr.Error()
|
||||||
|
fields = append(fields, zap.String("error", formatErr))
|
||||||
|
config.Logger.With(fields...).Error(formatErr)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
config.Logger.With(fields...).Info("api.request")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
package logger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/valyala/fasthttp"
|
||||||
|
"go.uber.org/zap/zapcore"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getAllowedHeaders() map[string]bool {
|
||||||
|
return map[string]bool{
|
||||||
|
"User-Agent": true,
|
||||||
|
"X-Mobile": true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type resp struct {
|
||||||
|
code int
|
||||||
|
_type string
|
||||||
|
}
|
||||||
|
|
||||||
|
func Resp(r *fasthttp.Response) *resp {
|
||||||
|
return &resp{
|
||||||
|
code: r.StatusCode(),
|
||||||
|
_type: bytes.NewBuffer(r.Header.ContentType()).String(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *resp) MarshalLogObject(enc zapcore.ObjectEncoder) error {
|
||||||
|
enc.AddString("type", r._type)
|
||||||
|
enc.AddInt("code", r.code)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type req struct {
|
||||||
|
body string
|
||||||
|
fullPath string
|
||||||
|
user string
|
||||||
|
ip string
|
||||||
|
method string
|
||||||
|
route string
|
||||||
|
headers *headerbag
|
||||||
|
}
|
||||||
|
|
||||||
|
func Req(c *fiber.Ctx) *req {
|
||||||
|
reqq := c.Request()
|
||||||
|
var body []byte
|
||||||
|
buffer := new(bytes.Buffer)
|
||||||
|
err := json.Compact(buffer, reqq.Body())
|
||||||
|
if err != nil {
|
||||||
|
body = reqq.Body()
|
||||||
|
} else {
|
||||||
|
body = buffer.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
headers := &headerbag{
|
||||||
|
vals: make(map[string]string),
|
||||||
|
}
|
||||||
|
allowedHeaders := getAllowedHeaders()
|
||||||
|
reqq.Header.VisitAll(func(key, val []byte) {
|
||||||
|
k := bytes.NewBuffer(key).String()
|
||||||
|
if _, exist := allowedHeaders[k]; exist {
|
||||||
|
headers.vals[strings.ToLower(k)] = bytes.NewBuffer(val).String()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
var userEmail string
|
||||||
|
if u := c.Locals("userEmail"); u != nil {
|
||||||
|
userEmail = u.(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &req{
|
||||||
|
body: bytes.NewBuffer(body).String(),
|
||||||
|
fullPath: bytes.NewBuffer(reqq.RequestURI()).String(),
|
||||||
|
headers: headers,
|
||||||
|
ip: c.IP(),
|
||||||
|
method: c.Method(),
|
||||||
|
route: c.Route().Path,
|
||||||
|
user: userEmail,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *req) MarshalLogObject(enc zapcore.ObjectEncoder) error {
|
||||||
|
enc.AddString("fullPath", r.fullPath)
|
||||||
|
enc.AddString("ip", r.ip)
|
||||||
|
enc.AddString("method", r.method)
|
||||||
|
enc.AddString("route", r.route)
|
||||||
|
|
||||||
|
if r.body != "" {
|
||||||
|
enc.AddString("body", r.body)
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.user != "" {
|
||||||
|
enc.AddString("user", r.user)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := enc.AddObject("headers", r.headers)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type headerbag struct {
|
||||||
|
vals map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *headerbag) MarshalLogObject(enc zapcore.ObjectEncoder) error {
|
||||||
|
for k, v := range h.vals {
|
||||||
|
enc.AddString(k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package logger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"gopkg.in/natefinch/lumberjack.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newRollingWriter() io.Writer {
|
||||||
|
if err := os.MkdirAll("log", 0744); err != nil {
|
||||||
|
log.Println("不能创建用于保存日志的目录。")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &lumberjack.Logger{
|
||||||
|
Filename: "log/service.log",
|
||||||
|
MaxBackups: 366 * 10, // files
|
||||||
|
MaxSize: 200, // megabytes
|
||||||
|
MaxAge: 366 * 10, // days
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,81 +1,80 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"electricity_bill_calc/cache"
|
||||||
"electricity_bill_calc/config"
|
"electricity_bill_calc/config"
|
||||||
"electricity_bill_calc/global"
|
"electricity_bill_calc/global"
|
||||||
|
"electricity_bill_calc/logger"
|
||||||
|
"electricity_bill_calc/migration"
|
||||||
"electricity_bill_calc/model"
|
"electricity_bill_calc/model"
|
||||||
"electricity_bill_calc/router"
|
"electricity_bill_calc/router"
|
||||||
"electricity_bill_calc/service"
|
"electricity_bill_calc/service"
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
jsontime "github.com/liamylian/jsontime/v2/v2"
|
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
|
"github.com/uptrace/bun/migrate"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
l := logger.Named("Init")
|
||||||
err := config.SetupSetting()
|
err := config.SetupSetting()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Configuration load failed: %v", err)
|
l.Fatal("Configuration load failed.", zap.Error(err))
|
||||||
}
|
}
|
||||||
log.Println("Configuration loaded!")
|
l.Info("Configuration loaded!")
|
||||||
|
|
||||||
err = global.SetupDatabaseConnection()
|
err = global.SetupDatabaseConnection()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Main Database connect failed: %v", err)
|
l.Fatal("Main Database connect failed.", zap.Error(err))
|
||||||
}
|
}
|
||||||
log.Println("Main Database connected!")
|
l.Info("Main Database connected!")
|
||||||
|
|
||||||
err = global.DBConn.Sync(
|
migrator := migrate.NewMigrator(global.DB, migration.Migrations)
|
||||||
&model.Region{},
|
ctx, cancel := global.TimeoutContext(12)
|
||||||
&model.User{},
|
defer cancel()
|
||||||
&model.UserDetail{},
|
err = migrator.Init(ctx)
|
||||||
&model.UserCharge{},
|
|
||||||
&model.Park{},
|
|
||||||
&model.Meter04KV{},
|
|
||||||
&model.MaintenanceFee{},
|
|
||||||
&model.Report{},
|
|
||||||
&model.ReportSummary{},
|
|
||||||
&model.WillDilutedFee{},
|
|
||||||
&model.EndUserDetail{})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Database structure synchronize failed: %v", err)
|
l.Fatal("Database migration unable to initialized.", zap.Error(err))
|
||||||
|
}
|
||||||
|
group, err := migrator.Migrate(ctx)
|
||||||
|
if err != nil {
|
||||||
|
l.Fatal("Database migrate failed.", zap.Error(err))
|
||||||
|
}
|
||||||
|
if group.IsZero() {
|
||||||
|
l.Info("There are no new migrations to run (database is up to date)")
|
||||||
}
|
}
|
||||||
log.Println("Database structure synchronized.")
|
|
||||||
|
|
||||||
err = global.SetupRedisConnection()
|
err = global.SetupRedisConnection()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Main Cache Database connect failed: %v", err)
|
l.Fatal("Main Cache Database connect failed.", zap.Error(err))
|
||||||
}
|
}
|
||||||
log.Println("Main Cache Database connected!")
|
l.Info("Main Cache Database connected!")
|
||||||
|
|
||||||
err = initializeRegions()
|
err = initializeRegions()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Regions initialize failed: %v", err)
|
l.Fatal("Regions initialize failed.", zap.Error(err))
|
||||||
}
|
}
|
||||||
log.Println("Regions synchronized.")
|
l.Info("Regions synchronized.")
|
||||||
|
|
||||||
err = intializeSingularity()
|
err = intializeSingularity()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Singularity account intialize failed: %v", err)
|
l.Fatal("Singularity account intialize failed.", zap.Error(err))
|
||||||
}
|
}
|
||||||
log.Println("Singularity account intialized.")
|
l.Info("Singularity account intialized.")
|
||||||
|
|
||||||
timeZoneShanghai, _ := time.LoadLocation("Asia/Shanghai")
|
|
||||||
jsontime.AddTimeFormatAlias("simple_datetime", "2006-01-02 15:04:05")
|
|
||||||
jsontime.AddTimeFormatAlias("simple_date", "2006-01-02")
|
|
||||||
jsontime.AddLocaleAlias("shanghai", timeZoneShanghai)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func initializeRegions() error {
|
func initializeRegions() error {
|
||||||
log.Println("Synchronize regions...")
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
logger.Info("Synchronize regions...")
|
||||||
regionCsvFile, err := os.Open("regions.csv")
|
regionCsvFile, err := os.Open("regions.csv")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("region initialize file is not found: %w", err)
|
return fmt.Errorf("region initialize file is not found: %w", err)
|
||||||
@@ -83,15 +82,16 @@ func initializeRegions() error {
|
|||||||
defer regionCsvFile.Close()
|
defer regionCsvFile.Close()
|
||||||
|
|
||||||
var existRegions = make([]string, 0)
|
var existRegions = make([]string, 0)
|
||||||
err = global.DBConn.Table("region").Cols("code").Find(&existRegions)
|
err = global.DB.NewSelect().Model((*model.Region)(nil)).
|
||||||
|
Column("code").
|
||||||
|
Scan(ctx, &existRegions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to retreive regions from database: %w", err)
|
return fmt.Errorf("unable to retreive regions from database: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
regionCsv := csv.NewReader(regionCsvFile)
|
regionCsv := csv.NewReader(regionCsvFile)
|
||||||
transaction := global.DBConn.NewSession()
|
transaction, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
defer transaction.Close()
|
if err != nil {
|
||||||
if err = transaction.Begin(); err != nil {
|
|
||||||
return fmt.Errorf("unable to intiate database transaction: %w", err)
|
return fmt.Errorf("unable to intiate database transaction: %w", err)
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
@@ -106,7 +106,12 @@ func initializeRegions() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, err = transaction.Insert(&model.Region{Code: record[0], Name: record[1], Level: level, Parent: record[3]}); err != nil {
|
if _, err := transaction.NewInsert().Model(&model.Region{
|
||||||
|
Code: record[0],
|
||||||
|
Name: record[1],
|
||||||
|
Level: level,
|
||||||
|
Parent: record[3],
|
||||||
|
}).Exec(ctx); err != nil {
|
||||||
return fmt.Errorf("region synchronize in failed: %v, %w", record, err)
|
return fmt.Errorf("region synchronize in failed: %v, %w", record, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,7 +136,7 @@ func intializeSingularity() error {
|
|||||||
Enabled: true,
|
Enabled: true,
|
||||||
}
|
}
|
||||||
singularityName := "Singularity"
|
singularityName := "Singularity"
|
||||||
singularityExpires, err := time.Parse("2006-01-02 15:04:05", "2099-12-31 23:59:59")
|
singularityExpires, err := model.ParseDate("2099-12-31")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("singularity expires time parse failed: %w", err)
|
return fmt.Errorf("singularity expires time parse failed: %w", err)
|
||||||
}
|
}
|
||||||
@@ -144,22 +149,39 @@ func intializeSingularity() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("singularity account failed to create: %w", err)
|
return fmt.Errorf("singularity account failed to create: %w", err)
|
||||||
}
|
}
|
||||||
log.Printf("Singularity account created, use %s as verify code to reset password.", verifyCode)
|
logger.Info(
|
||||||
|
fmt.Sprintf("Singularity account created, use %s as verify code to reset password.", verifyCode),
|
||||||
|
zap.String("account", "singularity"),
|
||||||
|
zap.String("verifyCode", verifyCode),
|
||||||
|
)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DBConnectionKeepLive() {
|
func DBConnectionKeepLive() {
|
||||||
for range time.Tick(30 * time.Second) {
|
for range time.Tick(30 * time.Second) {
|
||||||
err := global.DBConn.Ping()
|
err := global.DB.Ping()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func RedisOrphanCleanup() {
|
||||||
go DBConnectionKeepLive()
|
cleanLogger := logger.Named("Cache").With(zap.String("function", "Cleanup"))
|
||||||
gin.SetMode(config.ServerSettings.RunMode)
|
for range time.Tick(2 * time.Minute) {
|
||||||
r := router.Router()
|
cleanLogger.Info("Proceeding cleanup orphan keys.")
|
||||||
r.Run(fmt.Sprintf(":%d", config.ServerSettings.HttpPort))
|
err := cache.ClearOrphanRelationItems()
|
||||||
|
if err != nil {
|
||||||
|
cleanLogger.Error("Orphan keys clear failed.")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// 本次停用检测的原因是:使用Ping来保持数据库链接看起来没有什么用处。
|
||||||
|
// go DBConnectionKeepLive()
|
||||||
|
go RedisOrphanCleanup()
|
||||||
|
app := router.App()
|
||||||
|
app.Listen(fmt.Sprintf(":%d", config.ServerSettings.HttpPort))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,240 @@
|
|||||||
|
create table if not exists region (
|
||||||
|
code varchar(15) not null primary key,
|
||||||
|
name varchar(50) not null,
|
||||||
|
level smallint not null default 0,
|
||||||
|
parent varchar(15) not null default '0'
|
||||||
|
);
|
||||||
|
|
||||||
|
create table if not exists `user` (
|
||||||
|
created_at timestamptz not null,
|
||||||
|
id varchar(120) not null primary key,
|
||||||
|
username varchar(30) not null,
|
||||||
|
password varchar(256) not null,
|
||||||
|
reset_needed boolean not null default false,
|
||||||
|
type smallint not null,
|
||||||
|
enabled boolean not null default true
|
||||||
|
);
|
||||||
|
|
||||||
|
create table if not exists user_detail (
|
||||||
|
created_at timestamptz not null,
|
||||||
|
created_by varchar(100),
|
||||||
|
last_modified_at timestamptz,
|
||||||
|
last_modified_by varchar(100),
|
||||||
|
deleted_at timestamptz,
|
||||||
|
deleted_by varchar(100),
|
||||||
|
id varchar(120) not null primary key,
|
||||||
|
name varchar(100),
|
||||||
|
abbr varchar(50),
|
||||||
|
region varchar(10),
|
||||||
|
address varchar(120),
|
||||||
|
contact varchar(100),
|
||||||
|
phone varchar(50),
|
||||||
|
unit_service_fee numeric(8,2) not null default 0,
|
||||||
|
service_expiration date not null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table if not exists user_charge (
|
||||||
|
created_at timestamptz not null,
|
||||||
|
seq bigserial not null primary key,
|
||||||
|
user_id varchar(120) not null,
|
||||||
|
fee numeric(12,2),
|
||||||
|
discount numeric(5,4),
|
||||||
|
amount numeric(12,2),
|
||||||
|
charge_to date not null,
|
||||||
|
settled boolean not null default false,
|
||||||
|
settled_at timestamptz,
|
||||||
|
cancelled boolean not null default false,
|
||||||
|
cancelled_at timestamptz,
|
||||||
|
refunded boolean not null default false,
|
||||||
|
refunded_at timestamptz
|
||||||
|
);
|
||||||
|
|
||||||
|
create table if not exists park (
|
||||||
|
created_at timestamptz not null,
|
||||||
|
created_by varchar(100),
|
||||||
|
last_modified_at timestamptz,
|
||||||
|
last_modified_by varchar(100),
|
||||||
|
deleted_at timestamptz,
|
||||||
|
deleted_by varchar(100),
|
||||||
|
id varchar(120) not null primary key,
|
||||||
|
user_id varchar(120) not null,
|
||||||
|
name varchar(70) not null,
|
||||||
|
abbr varchar(50),
|
||||||
|
area numeric(14,2),
|
||||||
|
tenement_quantity numeric(8,0),
|
||||||
|
capacity numeric(16,2),
|
||||||
|
category smallint not null default 0,
|
||||||
|
meter_04kv_type smallint not null default 0,
|
||||||
|
region varchar(10),
|
||||||
|
address varchar(120),
|
||||||
|
contact varchar(100),
|
||||||
|
phone varchar(50),
|
||||||
|
enabled boolean not null default true
|
||||||
|
);
|
||||||
|
|
||||||
|
create table if not exists meter_04kv (
|
||||||
|
created_at timestamptz not null,
|
||||||
|
created_by varchar(100),
|
||||||
|
last_modified_at timestamptz,
|
||||||
|
last_modified_by varchar(100),
|
||||||
|
code varchar(120) not null,
|
||||||
|
park_id varchar(120) not null,
|
||||||
|
address varchar(100),
|
||||||
|
customer_name varchar(100),
|
||||||
|
contact_name varchar(70),
|
||||||
|
contact_phone varchar(50),
|
||||||
|
ratio numeric(8,4) not null default 1,
|
||||||
|
seq bigint not null default 0,
|
||||||
|
public_meter boolean not null default false,
|
||||||
|
dilute boolean not null default false,
|
||||||
|
enabled boolean not null default true,
|
||||||
|
primary key (code, park_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table if not exists maintenance_fee (
|
||||||
|
created_at timestamptz not null,
|
||||||
|
created_by varchar(100),
|
||||||
|
last_modified_at timestamptz,
|
||||||
|
last_modified_by varchar(100),
|
||||||
|
deleted_at timestamptz,
|
||||||
|
deleted_by varchar(100),
|
||||||
|
id varchar(120) not null primary key,
|
||||||
|
park_id varchar(120) not null,
|
||||||
|
name varchar(50) not null,
|
||||||
|
fee numeric(8,2) not null default 0,
|
||||||
|
memo text,
|
||||||
|
enabled boolean not null default true
|
||||||
|
);
|
||||||
|
|
||||||
|
create table if not exists report (
|
||||||
|
created_at timestamptz not null,
|
||||||
|
created_by varchar(100),
|
||||||
|
last_modified_at timestamptz,
|
||||||
|
last_modified_by varchar(100),
|
||||||
|
id varchar(120) not null primary key,
|
||||||
|
park_id varchar(120) not null,
|
||||||
|
period date not null,
|
||||||
|
category smallint not null default 0,
|
||||||
|
meter_04kv_type smallint not null default 0,
|
||||||
|
step_state jsonb not null,
|
||||||
|
published boolean not null default false,
|
||||||
|
published_at timestamptz,
|
||||||
|
withdraw smallint not null default 0,
|
||||||
|
last_withdraw_applied_at timestamptz,
|
||||||
|
last_withdraw_audit_at timestamptz
|
||||||
|
);
|
||||||
|
|
||||||
|
create table if not exists report_summary (
|
||||||
|
report_id varchar(120) not null primary key,
|
||||||
|
overall numeric(14,2) not null default 0,
|
||||||
|
overall_fee numeric(14,2) not null default 0,
|
||||||
|
consumption_fee numeric(14,2),
|
||||||
|
overall_price numeric(16,8),
|
||||||
|
critical numeric(14,2) not null default 0,
|
||||||
|
critical_fee numeric(14,2) not null default 0,
|
||||||
|
critical_price numeric(16,8),
|
||||||
|
peak numeric(14,2) not null default 0,
|
||||||
|
peak_fee numeric(14,2) not null default 0,
|
||||||
|
peak_price numeric(16,8),
|
||||||
|
flat numeric(14,2) not null default 0,
|
||||||
|
flat_fee numeric(14,2) not null default 0,
|
||||||
|
flat_price numeric(16,8),
|
||||||
|
valley numeric(14,2) not null default 0,
|
||||||
|
valley_fee numeric(14,2) not null default 0,
|
||||||
|
valley_price numeric(16,8),
|
||||||
|
loss numeric(14,2),
|
||||||
|
loss_fee numeric(16,2),
|
||||||
|
loss_proportion numeric(16,15),
|
||||||
|
customer_consumption numeric(16,2),
|
||||||
|
customer_consumption_fee numeric(14,2),
|
||||||
|
customer_consumption_critical numeric(16,2),
|
||||||
|
customer_consumption_critical_fee numeric(14,2),
|
||||||
|
customer_consumption_peak numeric(16,2),
|
||||||
|
customer_consumption_peak_fee numeric(14,2),
|
||||||
|
customer_consumption_flat numeric(16,2),
|
||||||
|
customer_consumption_flat_fee numeric(14,2),
|
||||||
|
customer_consumption_valley numeric(16,2),
|
||||||
|
customer_consumption_valley_fee numeric(14,2),
|
||||||
|
public_consumption numeric(16,2),
|
||||||
|
public_consumption_fee numeric(14,2),
|
||||||
|
public_consumption_proportion numeric(16,15),
|
||||||
|
public_consumption_critical numeric(16,2),
|
||||||
|
public_consumption_critical_fee numeric(14,2),
|
||||||
|
public_consumption_peak numeric(16,2),
|
||||||
|
public_consumption_peak_fee numeric(14,2),
|
||||||
|
public_consumption_flat numeric(16,2),
|
||||||
|
public_consumption_flat_fee numeric(14,2),
|
||||||
|
public_consumption_valley numeric(16,2),
|
||||||
|
public_consumption_valley_fee numeric(14,2),
|
||||||
|
basic_fee numeric(14,2) not null default 0,
|
||||||
|
basic_diluted_price numeric(18,8),
|
||||||
|
adjust_fee numeric(14,2) not null default 0,
|
||||||
|
adjust_diluted_price numeric(18,8),
|
||||||
|
maintenance_diluted_price numeric(16,8),
|
||||||
|
loss_diluted_price numeric(16,8),
|
||||||
|
public_consumption_diluted_price numeric(16,8),
|
||||||
|
maintenance_overall numeric(16,8),
|
||||||
|
final_diluted_overall numeric(14,2)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table if not exists will_diluted_fee (
|
||||||
|
id varchar(120) not null primary key,
|
||||||
|
report_id varchar(120) not null,
|
||||||
|
source_id varchar(120),
|
||||||
|
name varchar(50) not null,
|
||||||
|
fee numeric(8,2) not null default 0,
|
||||||
|
memo text
|
||||||
|
);
|
||||||
|
|
||||||
|
create table if not exists end_user_detail (
|
||||||
|
created_at timestamptz not null,
|
||||||
|
created_by varchar(100),
|
||||||
|
last_modified_at timestamptz,
|
||||||
|
last_modified_by varchar(100),
|
||||||
|
report_id varchar(120) not null,
|
||||||
|
park_id varchar(120) not null,
|
||||||
|
meter_04kv_id varchar(120) not null,
|
||||||
|
seq bigint not null default 0,
|
||||||
|
ratio numeric(8,4) not null default 1,
|
||||||
|
address varchar(100),
|
||||||
|
customer_name varchar(100),
|
||||||
|
contact_name varchar(70),
|
||||||
|
contact_phone varcahar(50),
|
||||||
|
public_meter boolean not null default false,
|
||||||
|
dilute boolean not null default false,
|
||||||
|
last_period_overall numeric(14,2) not null default 0,
|
||||||
|
last_period_critical numeric(14,2) not null default 0,
|
||||||
|
last_period_peak numeric(14,2) not null default 0,
|
||||||
|
last_period_flat numeric(14,2) not null default 0,
|
||||||
|
last_period_valley numeric(14,2) not null default 0,
|
||||||
|
current_period_overall numeric(14,2) not null default 0,
|
||||||
|
current_period_critical numeric(14,2) not null default 0,
|
||||||
|
current_period_peak numeric(14,2) not null default 0,
|
||||||
|
current_period_flat numeric(14,2) not null default 0,
|
||||||
|
current_period_valley numeric(14,2) not null default 0,
|
||||||
|
adjust_overall numeric(14,2) not null default 0,
|
||||||
|
adjust_critical numeric(14,2) not null default 0,
|
||||||
|
adjust_peak numeric(14,2) not null default 0,
|
||||||
|
adjust_flat numeric(14,2) not null default 0,
|
||||||
|
adjust_valley numeric(14,2) not null default 0,
|
||||||
|
overall numeric(14,2),
|
||||||
|
overall_fee numeric(14,2),
|
||||||
|
overall_proportion numeric(16,15) not null default 0,
|
||||||
|
critical numeric(14,2),
|
||||||
|
critical_fee numeric(18,8),
|
||||||
|
peak numeric(14,2),
|
||||||
|
peak_fee numeric(18,8),
|
||||||
|
flat numeric(14,2),
|
||||||
|
flat_fee numeric(18,8),
|
||||||
|
valley numeric(14,2),
|
||||||
|
valley_fee numeric(18,8),
|
||||||
|
basic_fee_diluted numeric(18,8),
|
||||||
|
adjust_fee_diluted numeric(18,8),
|
||||||
|
loss_diluted numeric(18,8),
|
||||||
|
loss_fee_diluted numeric(18,8),
|
||||||
|
maintenance_fee_diluted numeric(18,8),
|
||||||
|
public_consumption_diluted numeric(18,8),
|
||||||
|
final_diluted numeric(14,2),
|
||||||
|
final_charge numeric(14,2),
|
||||||
|
primary key (report_id, park_id, meter_04kv_id)
|
||||||
|
);
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
drop table if exists region;
|
||||||
|
|
||||||
|
drop table if exists user;
|
||||||
|
|
||||||
|
drop table if exists user_detail;
|
||||||
|
|
||||||
|
drop table if exists user_charge;
|
||||||
|
|
||||||
|
drop table if exists park;
|
||||||
|
|
||||||
|
drop table if exists meter_04kv;
|
||||||
|
|
||||||
|
drop table if exists maintenance_fee;
|
||||||
|
|
||||||
|
drop table if exists report;
|
||||||
|
|
||||||
|
drop table if exists report_summary;
|
||||||
|
|
||||||
|
drop table if exists will_diluted_fee;
|
||||||
|
|
||||||
|
drop table if exists end_user_detail;
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
alter table if exists `user` add constraint user_type_check check (type in (0, 1, 2));
|
||||||
|
|
||||||
|
alter table if exists user_detail add constraint positive_service_fee check (unit_service_fee >= 0);
|
||||||
|
|
||||||
|
alter table if exists user_charge add constraint positive_fee check (fee >= 0);
|
||||||
|
|
||||||
|
alter table if exists user_charge add constraint positive_amount check (amount >= 0);
|
||||||
|
|
||||||
|
alter table if exists park add constraint positive_tenement check (tenement_quantity >= 0);
|
||||||
|
|
||||||
|
alter table if exists park add constraint positive_area check (area >= 0);
|
||||||
|
|
||||||
|
alter table if exists park add constraint positive_capacity check (capacity >= 0);
|
||||||
|
|
||||||
|
alter table if exists park add constraint category_check check (category in (0, 1, 2));
|
||||||
|
|
||||||
|
alter table if exists park add constraint meter_check check (meter_04kv_type in (0, 1));
|
||||||
|
|
||||||
|
alter table if exists meter_04kv add constraint positive_ratio check (ratio > 0);
|
||||||
|
|
||||||
|
alter table if exists maintenance_fee add constraint positive_fee check (fee >= 0);
|
||||||
|
|
||||||
|
alter table if exists report add constraint category_check check (category in (0, 1, 2));
|
||||||
|
|
||||||
|
alter table if exists report add constraint meter_check check (meter_04kv_type in (0, 1));
|
||||||
|
|
||||||
|
alter table if exists report add constraint withdraw_action_check check (withdraw in (0, 1, 2, 3));
|
||||||
|
|
||||||
|
alter table if exists will_diluted_fee add constraint positive_fee check (fee >= 0);
|
||||||
|
|
||||||
|
alter table if exists end_user_detail add constraint positive_ratio check (ratio > 0);
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
alter table if exists user drop constraint user_type_check;
|
||||||
|
|
||||||
|
alter table if exists user_detail drop constraint positive_service_fee;
|
||||||
|
|
||||||
|
alter table if exists user_charge drop constraint positive_fee;
|
||||||
|
|
||||||
|
alter table if exists user_charge drop constraint positive_amount;
|
||||||
|
|
||||||
|
alter table if exists park drop constraint positive_tenement;
|
||||||
|
|
||||||
|
alter table if exists park drop constraint positive_area;
|
||||||
|
|
||||||
|
alter table if exists park drop constraint positive_capacity;
|
||||||
|
|
||||||
|
alter table if exists park drop constraint category_check;
|
||||||
|
|
||||||
|
alter table if exists park drop constraint meter_check;
|
||||||
|
|
||||||
|
alter table if exists meter_04kv drop constraint positive_ratio;
|
||||||
|
|
||||||
|
alter table if exists maintenance_fee drop constraint positive_fee;
|
||||||
|
|
||||||
|
alter table if exists report drop constraint category_check;
|
||||||
|
|
||||||
|
alter table if exists report drop constraint meter_check;
|
||||||
|
|
||||||
|
alter table if exists report drop constraint withdraw_action_check;
|
||||||
|
|
||||||
|
alter table if exists will_diluted_fee drop constraint positive_fee;
|
||||||
|
|
||||||
|
alter table if exists end_user_detail drop constraint positive_ratio;
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
update report_summary
|
||||||
|
set
|
||||||
|
customer_consumption = nullif(trim(customers->>'consumption'), '')::numeric(16,2),
|
||||||
|
customer_consumption_fee = nullif(trim(customers->>'consumptionFee'), '')::numeric(14,2),
|
||||||
|
customer_consumption_critical = nullif(trim(customers->>'critical'), '')::numeric(16,2),
|
||||||
|
customer_consumption_critical_fee = nullif(trim(customers->>'criticalFee'), '')::numeric(14,2),
|
||||||
|
customer_consumption_peak = nullif(trim(customers->>'peak'), '')::numeric(16,2),
|
||||||
|
customer_consumption_peak_fee = nullif(trim(customers->>'peakFee'), '')::numeric(14,2),
|
||||||
|
customer_consumption_flat = nullif(trim(customers->>'flat'), '')::numeric(16,2),
|
||||||
|
customer_consumption_flat_fee = nullif(trim(customers->>'flatFee'), '')::numeric(14,2),
|
||||||
|
customer_consumption_valley = nullif(trim(customers->>'valley'), '')::numeric(16,2),
|
||||||
|
customer_consumption_valley_fee = nullif(trim(customers->>'valleyFee'), '')::numeric(14,2),
|
||||||
|
public_consumption = nullif(trim(publics->>'consumption'), '')::numeric(16,2),
|
||||||
|
public_consumption_fee = nullif(trim(publics->>'consumptionFee'), '')::numeric(14,2),
|
||||||
|
public_consumption_critical = nullif(trim(publics->>'critical'), '')::numeric(16,2),
|
||||||
|
public_consumption_critical_fee = nullif(trim(publics->>'criticalFee'), '')::numeric(14,2),
|
||||||
|
public_consumption_peak = nullif(trim(publics->>'peak'), '')::numeric(16,2),
|
||||||
|
public_consumption_peak_fee = nullif(trim(publics->>'peakFee'), '')::numeric(14,2),
|
||||||
|
public_consumption_flat = nullif(trim(publics->>'flat'), '')::numeric(16,2),
|
||||||
|
public_consumption_flat_fee = nullif(trim(publics->>'flatFee'), '')::numeric(14,2),
|
||||||
|
public_consumption_valley = nullif(trim(publics->>'valley'), '')::numeric(16,2),
|
||||||
|
public_consumption_valley_fee = nullif(trim(publics->>'valleyFee'), '')::numeric(14,2),
|
||||||
|
public_consumption_proportion = nullif(trim(publics->>'proportion'), '')::numeric(16,15);
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
alter table report_summary
|
||||||
|
add column if not exists customers jsonb,
|
||||||
|
add column if not exists publics jsonb,
|
||||||
|
add column if not exists diluteds jsonb;
|
||||||
|
|
||||||
|
update report_summary
|
||||||
|
set
|
||||||
|
customers = jsonb_build_object(
|
||||||
|
'consumption', customer_consumption,
|
||||||
|
'fee', customer_consumption_fee,
|
||||||
|
'critical', customer_consumption_critical,
|
||||||
|
'criticalFee', customer_consumption_critical_fee,
|
||||||
|
'peak', customer_consumption_peak,
|
||||||
|
'peakFee', customer_consumption_peak_fee,
|
||||||
|
'flat', customer_consumption_flat,
|
||||||
|
'flatFee', customer_consumption_flat_fee,
|
||||||
|
'valley', customer_consumption_valley,
|
||||||
|
'valleyFee', customer_consumption_valley_fee,
|
||||||
|
'proportion', null
|
||||||
|
),
|
||||||
|
diluteds = jsonb_build_object(
|
||||||
|
'consumption', public_consumption,
|
||||||
|
'fee', public_consumption_fee,
|
||||||
|
'critical', public_consumption_critical,
|
||||||
|
'criticalFee', public_consumption_critical_fee,
|
||||||
|
'peak', public_consumption_peak,
|
||||||
|
'peakFee', public_consumption_peak_fee,
|
||||||
|
'flat', public_consumption_flat,
|
||||||
|
'flatFee', public_consumption_flat_fee,
|
||||||
|
'valley', public_consumption_valley,
|
||||||
|
'valleyFee', public_consumption_valley_fee,
|
||||||
|
'proportion', public_consumption_proportion
|
||||||
|
),
|
||||||
|
publics = jsonb_build_object(
|
||||||
|
'consumption', null,
|
||||||
|
'fee', null,
|
||||||
|
'critical', null,
|
||||||
|
'criticalFee', null,
|
||||||
|
'peak', null,
|
||||||
|
'peakFee', null,
|
||||||
|
'flat', null,
|
||||||
|
'flatFee', null,
|
||||||
|
'valley', null,
|
||||||
|
'valleyFee', null,
|
||||||
|
'proportion', null
|
||||||
|
);
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
alter table meter_04kv
|
||||||
|
add column dilute boolean not null default false;
|
||||||
|
|
||||||
|
alter table end_user_detail
|
||||||
|
add column dilute boolean not null default false,
|
||||||
|
add column maintenance_fee_diluted numeric(18,8),
|
||||||
|
add column public_consumption_diluted numeric(18,8);
|
||||||
|
|
||||||
|
alter table maintenance_fee
|
||||||
|
drop column period;
|
||||||
|
|
||||||
|
alter table report_summary
|
||||||
|
drop column authorize_loss,
|
||||||
|
drop column authorize_loss_fee,
|
||||||
|
drop column authorize_loss_proportion;
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
alter table meter_04kv
|
||||||
|
drop column dilute;
|
||||||
|
|
||||||
|
alter table end_user_detail
|
||||||
|
drop column dilute,
|
||||||
|
drop column maintenance_fee_diluted,
|
||||||
|
drop column public_consumption_diluted;
|
||||||
|
|
||||||
|
alter table maintenance_fee
|
||||||
|
add column period varchar(10);
|
||||||
|
|
||||||
|
alter table report_summary
|
||||||
|
drop column customer_consumption,
|
||||||
|
drop column customer_consumption_fee,
|
||||||
|
drop column customer_consumption_critical,
|
||||||
|
drop column customer_consumption_critical_fee,
|
||||||
|
drop column customer_consumption_peak,
|
||||||
|
drop column customer_consumption_peak_fee,
|
||||||
|
drop column customer_consumption_flat,
|
||||||
|
drop column customer_consumption_flat_fee,
|
||||||
|
drop column customer_consumption_valley,
|
||||||
|
drop column customer_consumption_valley_fee,
|
||||||
|
drop column public_consumption,
|
||||||
|
drop column public_consumption_fee,
|
||||||
|
drop column public_consumption_critical,
|
||||||
|
drop column public_consumption_critical_fee,
|
||||||
|
drop column public_consumption_peak,
|
||||||
|
drop column public_consumption_peak_fee,
|
||||||
|
drop column public_consumption_flat,
|
||||||
|
drop column public_consumption_flat_fee,
|
||||||
|
drop column public_consumption_valley,
|
||||||
|
drop column public_consumption_valley_fee,
|
||||||
|
drop column public_consumption_proportion,
|
||||||
|
drop column diluteds,
|
||||||
|
add column authorize_loss numeric(14,2),
|
||||||
|
add column authorize_loss_fee numeric(16,2),
|
||||||
|
add column authorize_loss_proportion numeric(16,15);
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package migration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"electricity_bill_calc/logger"
|
||||||
|
"embed"
|
||||||
|
|
||||||
|
"github.com/uptrace/bun/migrate"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
//go:embed *.sql
|
||||||
|
sqlMigrations embed.FS
|
||||||
|
Migrations = migrate.NewMigrations()
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if err := Migrations.Discover(sqlMigrations); err != nil {
|
||||||
|
logger.Named("Migrations").Fatal("Unable to load migrations.", zap.Error(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
+87
-48
@@ -1,62 +1,77 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
|
"github.com/uptrace/bun"
|
||||||
)
|
)
|
||||||
|
|
||||||
type EndUserDetail struct {
|
type EndUserDetail struct {
|
||||||
CreatedAndModified `xorm:"extends"`
|
bun.BaseModel `bun:"table:end_user_detail,alias:eud"`
|
||||||
ReportId string `xorm:"varchar(120) pk not null" json:"reportId"`
|
CreatedAndModified `bun:"extend"`
|
||||||
ParkId string `xorm:"varchar(120) pk not null" json:"parkId"`
|
ReportId string `bun:",pk,notnull" json:"reportId"`
|
||||||
MeterId string `xorm:"meter_04kv_id varchar(120) pk not null" json:"meterId"`
|
ParkId string `bun:",pk,notnull" json:"parkId"`
|
||||||
Seq int64 `xorm:"bigint not null default 0" json:"seq"`
|
MeterId string `bun:"meter_04kv_id,pk,notnull" json:"meterId"`
|
||||||
Ratio decimal.Decimal `xorm:"numeric(8,4) not null default 1" json:"ratio"`
|
Seq int64 `bun:"type:bigint,notnull" json:"seq"`
|
||||||
Address *string `xorm:"varchar(100)" json:"address"`
|
Ratio decimal.Decimal `bun:"type:numeric,notnull" json:"ratio"`
|
||||||
CustomerName *string `xorm:"varchar(100)" json:"customerName"`
|
Address *string `json:"address"`
|
||||||
ContactName *string `xorm:"varchar(70)" json:"contactName"`
|
CustomerName *string `json:"customerName"`
|
||||||
ContactPhone *string `xorm:"varchar(50)" json:"contactPhone"`
|
ContactName *string `json:"contactName"`
|
||||||
IsPublicMeter bool `xorm:"'public_meter' bool not null default false" json:"isPublicMeter"`
|
ContactPhone *string `json:"contactPhone"`
|
||||||
WillDilute bool `xorm:"'dilute' bool not null default false" json:"willDilute"`
|
IsPublicMeter bool `bun:"public_meter,notnull" json:"isPublicMeter"`
|
||||||
LastPeriodOverall decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"lastPeriodOverall"`
|
LastPeriodOverall decimal.Decimal `bun:"type:numeric,notnull" json:"lastPeriodOverall"`
|
||||||
LastPeriodCritical decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"lastPeriodCritical"`
|
LastPeriodCritical decimal.Decimal `bun:"type:numeric,notnull" json:"lastPeriodCritical"`
|
||||||
LastPeriodPeak decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"lastPeriodPeak"`
|
LastPeriodPeak decimal.Decimal `bun:"type:numeric,notnull" json:"lastPeriodPeak"`
|
||||||
LastPeriodFlat decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"lastPeriodFlat"`
|
LastPeriodFlat decimal.Decimal `bun:"type:numeric,notnull" json:"lastPeriodFlat"`
|
||||||
LastPeriodValley decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"lastPeriodValley"`
|
LastPeriodValley decimal.Decimal `bun:"type:numeric,notnull" json:"lastPeriodValley"`
|
||||||
CurrentPeriodOverall decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"currentPeriodOverall"`
|
CurrentPeriodOverall decimal.Decimal `bun:"type:numeric,notnull" json:"currentPeriodOverall"`
|
||||||
CurrentPeriodCritical decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"currentPeriodCritical"`
|
CurrentPeriodCritical decimal.Decimal `bun:"type:numeric,notnull" json:"currentPeriodCritical"`
|
||||||
CurrentPeriodPeak decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"currentPeriodPeak"`
|
CurrentPeriodPeak decimal.Decimal `bun:"type:numeric,notnull" json:"currentPeriodPeak"`
|
||||||
CurrentPeriodFlat decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"currentPeriodFlat"`
|
CurrentPeriodFlat decimal.Decimal `bun:"type:numeric,notnull" json:"currentPeriodFlat"`
|
||||||
CurrentPeriodValley decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"currentPeriodValley"`
|
CurrentPeriodValley decimal.Decimal `bun:"type:numeric,notnull" json:"currentPeriodValley"`
|
||||||
AdjustOverall decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"adjustOverall"`
|
AdjustOverall decimal.Decimal `bun:"type:numeric,notnull" json:"adjustOverall"`
|
||||||
AdjustCritical decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"adjustCritical"`
|
AdjustCritical decimal.Decimal `bun:"type:numeric,notnull" json:"adjustCritical"`
|
||||||
AdjustPeak decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"adjustPeak"`
|
AdjustPeak decimal.Decimal `bun:"type:numeric,notnull" json:"adjustPeak"`
|
||||||
AdjustFlat decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"adjustFlat"`
|
AdjustFlat decimal.Decimal `bun:"type:numeric,notnull" json:"adjustFlat"`
|
||||||
AdjustValley decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"adjustValley"`
|
AdjustValley decimal.Decimal `bun:"type:numeric,notnull" json:"adjustValley"`
|
||||||
Overall decimal.NullDecimal `xorm:"numeric(14,2)" json:"overall"`
|
Overall decimal.NullDecimal `bun:"type:numeric" json:"overall"`
|
||||||
OverallFee decimal.NullDecimal `xorm:"numeric(14,2)" json:"overallFee"`
|
OverallFee decimal.NullDecimal `bun:"type:numeric" json:"overallFee"`
|
||||||
OverallProportion decimal.Decimal `xorm:"numeric(16,15) not null default 0" json:"-"`
|
OverallProportion decimal.Decimal `bun:"type:numeric,notnull" json:"-"`
|
||||||
Critical decimal.NullDecimal `xorm:"numeric(14,2)" json:"critical"`
|
Critical decimal.NullDecimal `bun:"type:numeric" json:"critical"`
|
||||||
CriticalFee decimal.NullDecimal `xorm:"numeric(18,8)" json:"criticalFee"`
|
CriticalFee decimal.NullDecimal `bun:"type:numeric" json:"criticalFee"`
|
||||||
Peak decimal.NullDecimal `xorm:"numeric(14,2)" json:"peak"`
|
Peak decimal.NullDecimal `bun:"type:numeric" json:"peak"`
|
||||||
PeakFee decimal.NullDecimal `xorm:"numeric(18,8)" json:"peakFee"`
|
PeakFee decimal.NullDecimal `bun:"type:numeric" json:"peakFee"`
|
||||||
Flat decimal.NullDecimal `xorm:"numeric(14,2)" json:"flat"`
|
Flat decimal.NullDecimal `bun:"type:numeric" json:"flat"`
|
||||||
FlatFee decimal.NullDecimal `xorm:"numeric(18,8)" json:"flatFee"`
|
FlatFee decimal.NullDecimal `bun:"type:numeric" json:"flatFee"`
|
||||||
Valley decimal.NullDecimal `xorm:"numeric(14,2)" json:"valley"`
|
Valley decimal.NullDecimal `bun:"type:numeric" json:"valley"`
|
||||||
ValleyFee decimal.NullDecimal `xorm:"numeric(18,8)" json:"valleyFee"`
|
ValleyFee decimal.NullDecimal `bun:"type:numeric" json:"valleyFee"`
|
||||||
BasicFeeDiluted decimal.NullDecimal `xorm:"numeric(18,8)" json:"basicFeeDiluted"`
|
BasicFeeDiluted decimal.NullDecimal `bun:"type:numeric" json:"basicFeeDiluted"`
|
||||||
AdjustFeeDiluted decimal.NullDecimal `xorm:"numeric(18,8)" json:"adjustFeeDiluted"`
|
AdjustFeeDiluted decimal.NullDecimal `bun:"type:numeric" json:"adjustFeeDiluted"`
|
||||||
LossDiluted decimal.NullDecimal `xorm:"numeric(18,8)" json:"lossDiluted"`
|
LossDiluted decimal.NullDecimal `bun:"type:numeric" json:"lossDiluted"`
|
||||||
LossFeeDiluted decimal.NullDecimal `xorm:"numeric(18,8)" json:"lossFeeDiluted"`
|
LossFeeDiluted decimal.NullDecimal `bun:"type:numeric" json:"lossFeeDiluted"`
|
||||||
MaintenanceFeeDiluted decimal.NullDecimal `xorm:"numeric(18,8)" json:"maintenanceFeeDiluted"`
|
FinalDiluted decimal.NullDecimal `bun:"type:numeric" json:"finalDiluted"`
|
||||||
PublicConsumptionDiluted decimal.NullDecimal `xorm:"numeric(18,8)" json:"publicConsumptionDiluted"`
|
FinalCharge decimal.NullDecimal `bun:"type:numeric" json:"finalCharge"`
|
||||||
FinalDiluted decimal.NullDecimal `xorm:"numeric(14,2)" json:"finalDiluted"`
|
Initialize bool `bun:"-" json:"-"`
|
||||||
FinalCharge decimal.NullDecimal `xorm:"numeric(14,2)" json:"finalCharge"`
|
Origin *Meter04KV `bun:"rel:belongs-to,join:park_id=park_id,join:meter_04kv_id=code" json:"-"`
|
||||||
|
Report *Report `bun:"rel:belongs-to,join:report_id=id" json:"-"`
|
||||||
|
Park *Park `bun:"rel:belongs-to,join:park_id=id" json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (EndUserDetail) TableName() string {
|
var _ bun.BeforeAppendModelHook = (*EndUserDetail)(nil)
|
||||||
return "end_user_detail"
|
|
||||||
|
func (d *EndUserDetail) BeforeAppendModel(ctx context.Context, query bun.Query) error {
|
||||||
|
oprTime := time.Now()
|
||||||
|
switch query.(type) {
|
||||||
|
case *bun.InsertQuery:
|
||||||
|
d.CreatedAt = oprTime
|
||||||
|
d.LastModifiedAt = &oprTime
|
||||||
|
case *bun.UpdateQuery:
|
||||||
|
d.LastModifiedAt = &oprTime
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d EndUserDetail) Validate() (bool, error) {
|
func (d EndUserDetail) Validate() (bool, error) {
|
||||||
@@ -72,6 +87,7 @@ func (d EndUserDetail) Validate() (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *EndUserDetail) CalculatePeriod() {
|
func (d *EndUserDetail) CalculatePeriod() {
|
||||||
|
d.LastPeriodFlat = d.LastPeriodOverall.Sub(d.LastPeriodCritical).Sub(d.LastPeriodPeak).Sub(d.LastPeriodValley)
|
||||||
d.CurrentPeriodFlat = d.CurrentPeriodOverall.Sub(d.CurrentPeriodCritical).Sub(d.CurrentPeriodPeak).Sub(d.CurrentPeriodValley)
|
d.CurrentPeriodFlat = d.CurrentPeriodOverall.Sub(d.CurrentPeriodCritical).Sub(d.CurrentPeriodPeak).Sub(d.CurrentPeriodValley)
|
||||||
d.Overall = decimal.NewNullDecimal(d.CurrentPeriodOverall.Sub(d.LastPeriodOverall).Mul(d.Ratio).Add(d.AdjustOverall).RoundBank(2))
|
d.Overall = decimal.NewNullDecimal(d.CurrentPeriodOverall.Sub(d.LastPeriodOverall).Mul(d.Ratio).Add(d.AdjustOverall).RoundBank(2))
|
||||||
d.Critical = decimal.NewNullDecimal(d.CurrentPeriodCritical.Sub(d.LastPeriodCritical).Mul(d.Ratio).Add(d.AdjustCritical).RoundBank(2))
|
d.Critical = decimal.NewNullDecimal(d.CurrentPeriodCritical.Sub(d.LastPeriodCritical).Mul(d.Ratio).Add(d.AdjustCritical).RoundBank(2))
|
||||||
@@ -82,7 +98,11 @@ func (d *EndUserDetail) CalculatePeriod() {
|
|||||||
|
|
||||||
type EndUserImport struct {
|
type EndUserImport struct {
|
||||||
MeterId string `excel:"meterId"`
|
MeterId string `excel:"meterId"`
|
||||||
|
LastPeriodOverall decimal.Decimal `excel:"lastPeriodOverall"`
|
||||||
CurrentPeriodOverall decimal.Decimal `excel:"currentPeriodOverall"`
|
CurrentPeriodOverall decimal.Decimal `excel:"currentPeriodOverall"`
|
||||||
|
LastPeriodCritical decimal.NullDecimal `excel:"lastPeriodCritical"`
|
||||||
|
LastPeriodPeak decimal.NullDecimal `excel:"lastPeriodPeak"`
|
||||||
|
LastPeriodValley decimal.NullDecimal `excel:"lastPeriodValley"`
|
||||||
CurrentPeriodCritical decimal.NullDecimal `excel:"currentPeriodCritical"`
|
CurrentPeriodCritical decimal.NullDecimal `excel:"currentPeriodCritical"`
|
||||||
CurrentPeriodPeak decimal.NullDecimal `excel:"currentPeriodPeak"`
|
CurrentPeriodPeak decimal.NullDecimal `excel:"currentPeriodPeak"`
|
||||||
CurrentPeriodValley decimal.NullDecimal `excel:"currentPeriodValley"`
|
CurrentPeriodValley decimal.NullDecimal `excel:"currentPeriodValley"`
|
||||||
@@ -92,3 +112,22 @@ type EndUserImport struct {
|
|||||||
AdjustFlat decimal.NullDecimal `excel:"adjustFlat"`
|
AdjustFlat decimal.NullDecimal `excel:"adjustFlat"`
|
||||||
AdjustValley decimal.NullDecimal `excel:"adjustValley"`
|
AdjustValley decimal.NullDecimal `excel:"adjustValley"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EndUserPeriodStat struct {
|
||||||
|
CustomerName string `json:"customerName"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
ParkId string `json:"parkId"`
|
||||||
|
MeterId string `bun:"meter_04kv_id" json:"meterId"`
|
||||||
|
IsPublicMeter bool `bun:"public_meter" json:"isPublicMeter"`
|
||||||
|
Kind int8 `bun:"-" json:"pvKind"`
|
||||||
|
Overall decimal.NullDecimal `json:"overall"`
|
||||||
|
Critical decimal.NullDecimal `json:"critical"`
|
||||||
|
Peak decimal.NullDecimal `json:"peak"`
|
||||||
|
Valley decimal.NullDecimal `json:"valley"`
|
||||||
|
OverallFee decimal.NullDecimal `json:"overallFee"`
|
||||||
|
CriticalFee decimal.NullDecimal `json:"criticalFee"`
|
||||||
|
PeakFee decimal.NullDecimal `json:"peakFee"`
|
||||||
|
ValleyFee decimal.NullDecimal `json:"valleyFee"`
|
||||||
|
AdjustFee decimal.NullDecimal `bun:"final_diluted" json:"adjustFee"`
|
||||||
|
AdjustProportion decimal.NullDecimal `bun:"-" json:"adjustProportion"`
|
||||||
|
}
|
||||||
|
|||||||
+38
-10
@@ -1,20 +1,48 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
|
"github.com/uptrace/bun"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MaintenanceFee struct {
|
type MaintenanceFee struct {
|
||||||
CreatedAndModified `xorm:"extends"`
|
bun.BaseModel `bun:"table:maintenance_fee,alias:m"`
|
||||||
Deleted `xorm:"extends"`
|
CreatedAndModified `bun:"extend"`
|
||||||
Id string `xorm:"varchar(120) pk not null" json:"id"`
|
Deleted `bun:"extend"`
|
||||||
ParkId string `xorm:"varchar(120) not null" json:"parkId"`
|
Id string `bun:",pk,notnull" json:"id"`
|
||||||
Name string `xorm:"varchar(50) not null" json:"name"`
|
ParkId string `bun:",notnull" json:"parkId"`
|
||||||
Fee decimal.Decimal `xorm:"numeric(8,2) not null" json:"fee"`
|
Name string `bun:",notnull" json:"name"`
|
||||||
Memo *string `xorm:"text" json:"memo"`
|
Period string `bun:",notnull" json:"period"`
|
||||||
Enabled bool `xorm:"bool not null" json:"enabled"`
|
Fee decimal.Decimal `bun:"type:numeric,notnull" json:"fee"`
|
||||||
|
Memo *string `bun:"type:text" json:"memo"`
|
||||||
|
Enabled bool `bun:",notnull" json:"enabled"`
|
||||||
|
Park Park `bun:"rel:belongs-to,join:park_id=id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (MaintenanceFee) TableName() string {
|
var _ bun.BeforeAppendModelHook = (*MaintenanceFee)(nil)
|
||||||
return "maintenance_fee"
|
|
||||||
|
func (f *MaintenanceFee) BeforeAppendModel(ctx context.Context, query bun.Query) error {
|
||||||
|
oprTime := time.Now()
|
||||||
|
switch query.(type) {
|
||||||
|
case *bun.InsertQuery:
|
||||||
|
f.CreatedAt = oprTime
|
||||||
|
f.LastModifiedAt = &oprTime
|
||||||
|
case *bun.UpdateQuery:
|
||||||
|
f.LastModifiedAt = &oprTime
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type AdditionalCharge struct {
|
||||||
|
ParkId string `json:"parkId"`
|
||||||
|
Period string `json:"period"`
|
||||||
|
Fee decimal.Decimal `json:"fee"`
|
||||||
|
Price decimal.Decimal `json:"price"`
|
||||||
|
QuarterPrice decimal.Decimal `json:"quarterPrice"`
|
||||||
|
SemiAnnualPrice decimal.Decimal `json:"semiAnnualPrice"`
|
||||||
|
Enterprise UserDetailSimplified `json:"user"`
|
||||||
|
Park Park `json:"park"`
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-14
@@ -1,24 +1,39 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
|
"github.com/uptrace/bun"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Meter04KV struct {
|
type Meter04KV struct {
|
||||||
CreatedAndModified `xorm:"extends"`
|
bun.BaseModel `bun:"table:meter_04kv,alias:mt"`
|
||||||
Code string `xorm:"varchar(120) pk not null" json:"code" excel:"code"`
|
CreatedAndModified `bun:"extend"`
|
||||||
ParkId string `xorm:"varchar(120) pk not null" json:"parkId"`
|
Code string `bun:",pk,notnull" json:"code" excel:"code"`
|
||||||
Address *string `xorm:"varchar(100)" json:"address" excel:"address"`
|
ParkId string `bun:",pk,notnull" json:"parkId"`
|
||||||
CustomerName *string `xorm:"varchar(100)" json:"customerName" excel:"name"`
|
Address *string `json:"address" excel:"address"`
|
||||||
ContactName *string `xorm:"varchar(70)" json:"contactName" excel:"contact"`
|
CustomerName *string `json:"customerName" excel:"name"`
|
||||||
ContactPhone *string `xorm:"varchar(50)" json:"contactPhone" excel:"phone"`
|
ContactName *string `json:"contactName" excel:"contact"`
|
||||||
Ratio decimal.Decimal `xorm:"numeric(8,4) not null default 1" json:"ratio" excel:"ratio"`
|
ContactPhone *string `json:"contactPhone" excel:"phone"`
|
||||||
Seq int64 `xorm:"bigint not null" json:"seq" excel:"seq"`
|
Ratio decimal.Decimal `bun:"type:numeric,notnull" json:"ratio" excel:"ratio"`
|
||||||
IsPublicMeter bool `xorm:"'public_meter' bool not null default false" json:"isPublicMeter" excel:"public"`
|
Seq int64 `bun:"type:bigint,notnull" json:"seq" excel:"seq"`
|
||||||
WillDilute bool `xorm:"'dilute' bool not null default false" json:"willDilute" excel:"dilute"`
|
IsPublicMeter bool `bun:"public_meter,notnull" json:"isPublicMeter" excel:"public"`
|
||||||
Enabled bool `xorm:"bool not null default true" json:"enabled"`
|
Enabled bool `bun:",notnull" json:"enabled"`
|
||||||
|
ParkDetail *Park `bun:"rel:belongs-to,join:park_id=id" json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Meter04KV) TableName() string {
|
var _ bun.BeforeAppendModelHook = (*Meter04KV)(nil)
|
||||||
return "meter_04kv"
|
|
||||||
|
func (m *Meter04KV) BeforeAppendModel(ctx context.Context, query bun.Query) error {
|
||||||
|
oprTime := time.Now()
|
||||||
|
switch query.(type) {
|
||||||
|
case *bun.InsertQuery:
|
||||||
|
m.CreatedAt = oprTime
|
||||||
|
m.LastModifiedAt = &oprTime
|
||||||
|
case *bun.UpdateQuery:
|
||||||
|
m.LastModifiedAt = &oprTime
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+62
-40
@@ -1,9 +1,12 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/jinzhu/copier"
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
|
"github.com/uptrace/bun"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -18,50 +21,69 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Park struct {
|
type Park struct {
|
||||||
CreatedAndModified `xorm:"extends"`
|
bun.BaseModel `bun:"table:park,alias:p"`
|
||||||
Deleted `xorm:"extends"`
|
CreatedAndModified `bun:"extend"`
|
||||||
Id string `xorm:"varchar(120) pk not null" json:"id"`
|
Deleted `bun:"extend"`
|
||||||
UserId string `xorm:"varchar(120) not null" json:"userId"`
|
Id string `bun:",pk,notnull" json:"id"`
|
||||||
Name string `xorm:"varchar(70) not null" json:"name"`
|
UserId string `bun:",notnull" json:"userId"`
|
||||||
Abbr *string `xorm:"varchar(50)" json:"abbr"`
|
Name string `bun:",notnull" json:"name"`
|
||||||
Area decimal.NullDecimal `xorm:"numeric(14,2)" json:"area"`
|
Abbr *string `json:"abbr"`
|
||||||
TenementQuantity decimal.NullDecimal `xorm:"numeric(8,0)" json:"tenement"`
|
Area decimal.NullDecimal `bun:"type:numeric" json:"area"`
|
||||||
Capacity decimal.NullDecimal `xorm:"numeric(16,2)" json:"capacity"`
|
TenementQuantity decimal.NullDecimal `bun:"type:numeric" json:"tenement"`
|
||||||
Category int8 `xorm:"smallint not null default 0" json:"category"`
|
Capacity decimal.NullDecimal `bun:"type:numeric" json:"capacity"`
|
||||||
SubmeterType int8 `xorm:"'meter_04kv_type' smallint not null default 0" json:"meter04kvType"`
|
Category int8 `bun:"type:smallint,notnull" json:"category"`
|
||||||
Region *string `xorm:"varchar(10)" json:"region"`
|
SubmeterType int8 `bun:"meter_04kv_type,type:smallint,notnull" json:"meter04kvType"`
|
||||||
Address *string `xorm:"varchar(120)" json:"address"`
|
Region *string `json:"region"`
|
||||||
Contact *string `xorm:"varchar(100)" json:"contact"`
|
Address *string `json:"address"`
|
||||||
Phone *string `xorm:"varchar(50)" json:"phone"`
|
Contact *string `json:"contact"`
|
||||||
Enabled bool `xorm:"bool not null" json:"enabled"`
|
Phone *string `json:"phone"`
|
||||||
}
|
Enabled bool `bun:",notnull" json:"enabled"`
|
||||||
|
EnterpriseIndex *User `bun:"rel:belongs-to,join:user_id=id" json:"-"`
|
||||||
func (Park) TableName() string {
|
Enterprise *UserDetail `bun:"rel:belongs-to,join:user_id=id" json:"-"`
|
||||||
return "park"
|
MaintenanceFees []*MaintenanceFee `bun:"rel:has-many,join:id=park_id" json:"-"`
|
||||||
|
Meters []*Meter04KV `bun:"rel:has-many,join:id=park_id" json:"-"`
|
||||||
|
Reports []*Report `bun:"rel:has-many,join:id=park_id" json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ParkSimplified struct {
|
type ParkSimplified struct {
|
||||||
Id string `xorm:"varchar(120) pk not null" json:"id"`
|
bun.BaseModel `bun:"table:park,alias:p"`
|
||||||
UserId string `xorm:"varchar(120) not null" json:"userId"`
|
Id string `bun:",pk,notnull" json:"id"`
|
||||||
Name string `xorm:"varchar(70) not null" json:"name"`
|
UserId string `bun:",notnull" json:"userId"`
|
||||||
Abbr *string `xorm:"varchar(50)" json:"abbr"`
|
Name string `bun:",notnull" json:"name"`
|
||||||
Area decimal.NullDecimal `xorm:"numeric(14,2)" json:"area"`
|
Abbr *string `json:"abbr"`
|
||||||
TenementQuantity decimal.NullDecimal `xorm:"numeric(8,0)" json:"tenement"`
|
Area decimal.NullDecimal `json:"area"`
|
||||||
Capacity decimal.NullDecimal `xorm:"numeric(16,2)" json:"capacity"`
|
TenementQuantity decimal.NullDecimal `json:"tenement"`
|
||||||
Category int8 `xorm:"smallint not null" json:"category"`
|
Capacity decimal.NullDecimal `json:"capacity"`
|
||||||
SubmeterType int8 `xorm:"'meter_04kv_type' smallint not null" json:"meter04kvType"`
|
Category int8 `bun:"type:smallint,notnull" json:"category"`
|
||||||
Region *string `xorm:"varchar(10)" json:"region"`
|
SubmeterType int8 `bun:"meter_04kv_type,type:smallint,notnull" json:"meter04kvType"`
|
||||||
Address *string `xorm:"varchar(120)" json:"address"`
|
Region *string `json:"region"`
|
||||||
Contact *string `xorm:"varchar(100)" json:"contact"`
|
Address *string `json:"address"`
|
||||||
Phone *string `xorm:"varchar(50)" json:"phone"`
|
Contact *string `json:"contact"`
|
||||||
}
|
Phone *string `json:"phone"`
|
||||||
|
|
||||||
func (ParkSimplified) TableName() string {
|
|
||||||
return "park"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ParkPeriodStatistics struct {
|
type ParkPeriodStatistics struct {
|
||||||
Id string `xorm:"varchar(120) not null" json:"id"`
|
Id string `bun:"park__id,notnull" json:"id"`
|
||||||
Name string `xorm:"varchar(120) not null" json:"name"`
|
Name string `bun:"park__name,notnull" json:"name"`
|
||||||
Period *time.Time `xorm:"date" json:"period" time_format:"simple_date" time_location:"shanghai"`
|
Period *Date `bun:"type:date" json:"period"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func FromPark(park Park) ParkSimplified {
|
||||||
|
dest := ParkSimplified{}
|
||||||
|
copier.Copy(&dest, park)
|
||||||
|
return dest
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ bun.BeforeAppendModelHook = (*Park)(nil)
|
||||||
|
|
||||||
|
func (p *Park) BeforeAppendModel(ctx context.Context, query bun.Query) error {
|
||||||
|
oprTime := time.Now()
|
||||||
|
switch query.(type) {
|
||||||
|
case *bun.InsertQuery:
|
||||||
|
p.CreatedAt = oprTime
|
||||||
|
p.LastModifiedAt = &oprTime
|
||||||
|
case *bun.UpdateQuery:
|
||||||
|
p.LastModifiedAt = &oprTime
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-37
@@ -41,7 +41,7 @@ type EndUserOverallPart struct {
|
|||||||
ValleyFee decimal.NullDecimal `json:"valleyFee"`
|
ValleyFee decimal.NullDecimal `json:"valleyFee"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PublicConsumptionOverallPart struct {
|
type ConsumptionOverallPart struct {
|
||||||
Overall decimal.Decimal `json:"overall"`
|
Overall decimal.Decimal `json:"overall"`
|
||||||
OverallPrice decimal.Decimal `json:"overallPrice"`
|
OverallPrice decimal.Decimal `json:"overallPrice"`
|
||||||
ConsumptionFee decimal.Decimal `json:"consumptionFee"`
|
ConsumptionFee decimal.Decimal `json:"consumptionFee"`
|
||||||
@@ -62,52 +62,55 @@ type PublicConsumptionOverallPart struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type LossPart struct {
|
type LossPart struct {
|
||||||
Quantity decimal.Decimal `json:"quantity"`
|
Quantity decimal.Decimal `json:"quantity"`
|
||||||
Price decimal.Decimal `json:"price"`
|
Price decimal.Decimal `json:"price"`
|
||||||
ConsumptionFee decimal.Decimal `json:"consumptionFee"`
|
ConsumptionFee decimal.Decimal `json:"consumptionFee"`
|
||||||
Proportion decimal.Decimal `json:"proportion"`
|
Proportion decimal.Decimal `json:"proportion"`
|
||||||
|
AuthorizeQuantity decimal.Decimal `json:"authorizeQuantity"`
|
||||||
|
AuthorizeConsumptionFee decimal.Decimal `json:"authorizeConsumptionFee"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OtherShouldCollectionPart struct {
|
type OtherShouldCollectionPart struct {
|
||||||
MaintenanceFee decimal.NullDecimal `json:"maintenanceFee"`
|
LossFee decimal.NullDecimal `json:"lossFee"`
|
||||||
BasicFees decimal.Decimal `json:"basicFees"`
|
BasicFees decimal.Decimal `json:"basicFees"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MaintenancePart struct {
|
type MaintenancePart struct {
|
||||||
BasicFees decimal.Decimal `json:"basicFees"`
|
BasicFees decimal.Decimal `json:"basicFees"`
|
||||||
LossFee decimal.Decimal `json:"lossFee"`
|
LossFee decimal.Decimal `json:"lossFee"`
|
||||||
PublicConsumptionFee decimal.Decimal `json:"publicConsumptionFee"`
|
AdjustFee decimal.Decimal `json:"adjustFee"`
|
||||||
MaintenanceFee decimal.Decimal `json:"maintenanceFee"`
|
LossProportion decimal.Decimal `json:"lossProportion"`
|
||||||
FinalMaintenance decimal.Decimal `json:"finalMaintenance"`
|
AdjustProportion decimal.Decimal `json:"adjustProportion"`
|
||||||
MaintenanceProportion decimal.Decimal `json:"maintenanceProportion"`
|
AdjustPrice decimal.Decimal `json:"adjustPrice"`
|
||||||
MaintenancePrice decimal.Decimal `json:"maintenancePrice"`
|
|
||||||
PriceRatio decimal.Decimal `json:"priceRatio"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type EndUserSummary struct {
|
type EndUserSummary struct {
|
||||||
CustomerName *string `json:"customerName"`
|
CustomerName *string `json:"customerName"`
|
||||||
Address *string `json:"address"`
|
Address *string `json:"address"`
|
||||||
MeterId string `json:"meterId"`
|
MeterId string `json:"meterId"`
|
||||||
Overall decimal.Decimal `json:"overall"`
|
IsPublicMeter bool `json:"isPublicMeter"`
|
||||||
OverallFee decimal.Decimal `json:"overallFee"`
|
Overall decimal.Decimal `json:"overall"`
|
||||||
Critical decimal.NullDecimal `json:"critical"`
|
OverallPrice decimal.Decimal `json:"overallPrice"`
|
||||||
CriticalFee decimal.NullDecimal `json:"criticalFee"`
|
OverallFee decimal.Decimal `json:"overallFee"`
|
||||||
Peak decimal.NullDecimal `json:"peak"`
|
Critical decimal.NullDecimal `json:"critical"`
|
||||||
PeakFee decimal.NullDecimal `json:"peakFee"`
|
CriticalFee decimal.NullDecimal `json:"criticalFee"`
|
||||||
Valley decimal.NullDecimal `json:"valley"`
|
Peak decimal.NullDecimal `json:"peak"`
|
||||||
ValleyFee decimal.NullDecimal `json:"valleyFee"`
|
PeakFee decimal.NullDecimal `json:"peakFee"`
|
||||||
Maintenance decimal.Decimal `json:"maintenance"`
|
Valley decimal.NullDecimal `json:"valley"`
|
||||||
|
ValleyFee decimal.NullDecimal `json:"valleyFee"`
|
||||||
|
Loss decimal.Decimal `json:"loss"`
|
||||||
|
LossFee decimal.Decimal `json:"lossFee"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Publicity struct {
|
type Publicity struct {
|
||||||
Report Report `json:"index"`
|
Report Report `json:"index"`
|
||||||
User UserDetail `json:"enterprise"`
|
User UserDetail `json:"enterprise"`
|
||||||
Park Park `json:"park"`
|
Park Park `json:"park"`
|
||||||
Paid PaidPart `json:"paid"`
|
Paid PaidPart `json:"paid"`
|
||||||
EndUser EndUserOverallPart `json:"endUserSum"`
|
EndUser ConsumptionOverallPart `json:"endUserSum"`
|
||||||
Loss LossPart `json:"loss"`
|
Loss LossPart `json:"loss"`
|
||||||
PublicConsumptionOverall PublicConsumptionOverallPart `json:"public"`
|
PublicConsumptionOverall ConsumptionOverallPart `json:"public"`
|
||||||
OtherCollections OtherShouldCollectionPart `json:"others"`
|
OtherCollections OtherShouldCollectionPart `json:"others"`
|
||||||
Maintenance MaintenancePart `json:"maintenance"`
|
Maintenance MaintenancePart `json:"maintenance"`
|
||||||
EndUserDetails []EndUserSummary `json:"endUser"`
|
EndUserDetails []EndUserSummary `json:"endUser"`
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-8
@@ -1,12 +1,11 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
type Region struct {
|
import "github.com/uptrace/bun"
|
||||||
Code string `xorm:"varchar(15) pk not null" json:"code"`
|
|
||||||
Name string `xorm:"varchar(50) not null" json:"name"`
|
|
||||||
Level int `xorm:"int not null default 0" json:"level"`
|
|
||||||
Parent string `xorm:"varchar(15) not null default '0'" json:"parent"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (Region) TableName() string {
|
type Region struct {
|
||||||
return "region"
|
bun.BaseModel `bun:"table:region,alias:r"`
|
||||||
|
Code string `bun:",pk,notnull" json:"code"`
|
||||||
|
Name string `bun:",notnull" json:"name"`
|
||||||
|
Level int `bun:",notnull" json:"level"`
|
||||||
|
Parent string `bun:",notnull" json:"parent"`
|
||||||
}
|
}
|
||||||
|
|||||||
+50
-41
@@ -1,6 +1,11 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/uptrace/bun"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
REPORT_NOT_WITHDRAW int8 = iota
|
REPORT_NOT_WITHDRAW int8 = iota
|
||||||
@@ -10,18 +15,23 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Report struct {
|
type Report struct {
|
||||||
CreatedAndModified `xorm:"extends"`
|
bun.BaseModel `bun:"table:report,alias:r"`
|
||||||
Id string `xorm:"varchar(120) pk not null" json:"id"`
|
CreatedAndModified `bun:"extend"`
|
||||||
ParkId string `xorm:"varchar(120) not null" json:"parkId"`
|
Id string `bun:",pk,notnull" json:"id"`
|
||||||
Period time.Time `xorm:"date not null" json:"period" time_format:"simple_date" time_location:"shanghai"`
|
ParkId string `bun:",notnull" json:"parkId"`
|
||||||
Category int8 `xorm:"smallint not null default 0" json:"category"`
|
Period time.Time `bun:"type:date,notnull" json:"period" time_format:"simple_date" time_location:"shanghai"`
|
||||||
SubmeterType int8 `xorm:"'meter_04kv_type' smallint not null default 0" json:"meter04kvType"`
|
Category int8 `bun:"type:smallint,notnull" json:"category"`
|
||||||
StepState Steps `xorm:"text not null json" json:"stepState"`
|
SubmeterType int8 `bun:"meter_04kv_type,type:smallint,notnull" json:"meter04kvType"`
|
||||||
Published bool `xorm:"bool not null default false" json:"published"`
|
StepState Steps `bun:"type:jsonb,notnull" json:"stepState"`
|
||||||
PublishedAt *time.Time `xorm:"timestampz" json:"publishedAt" time_format:"simple_datetime" time_location:"shanghai"`
|
Published bool `bun:",notnull" json:"published"`
|
||||||
Withdraw int8 `xorm:"smallint not null default 0" json:"withdraw"`
|
PublishedAt *time.Time `bun:"type:timestamptz,nullzero" json:"publishedAt" time_format:"simple_datetime" time_location:"shanghai"`
|
||||||
LastWithdrawAppliedAt *time.Time `xorm:"timestampz" json:"lastWithdrawAppliedAt" time_format:"simple_datetime" time_location:"shanghai"`
|
Withdraw int8 `bun:"type:smallint,notnull" json:"withdraw"`
|
||||||
LastWithdrawAuditAt *time.Time `xorm:"timestampz" json:"lastWithdrawAuditAt" time_format:"simple_datetime" time_location:"shanghai"`
|
LastWithdrawAppliedAt *time.Time `bun:"type:timestamptz,nullzero" json:"lastWithdrawAppliedAt" time_format:"simple_datetime" time_location:"shanghai"`
|
||||||
|
LastWithdrawAuditAt *time.Time `bun:"type:timestamptz,nullzero" json:"lastWithdrawAuditAt" time_format:"simple_datetime" time_location:"shanghai"`
|
||||||
|
Park *Park `bun:"rel:belongs-to,join:park_id=id" json:"-"`
|
||||||
|
Summary *ReportSummary `bun:"rel:has-one,join:id=report_id" json:"-"`
|
||||||
|
WillDilutedFees []*WillDilutedFee `bun:"rel:has-many,join:id=report_id" json:"-"`
|
||||||
|
EndUsers []*EndUserDetail `bun:"rel:has-many,join:id=report_id,join:park_id=park_id" json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Steps struct {
|
type Steps struct {
|
||||||
@@ -33,10 +43,6 @@ type Steps struct {
|
|||||||
Publish bool `json:"publish"`
|
Publish bool `json:"publish"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Report) TableName() string {
|
|
||||||
return "report"
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSteps() Steps {
|
func NewSteps() Steps {
|
||||||
return Steps{
|
return Steps{
|
||||||
Summary: false,
|
Summary: false,
|
||||||
@@ -49,12 +55,8 @@ func NewSteps() Steps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ParkNewestReport struct {
|
type ParkNewestReport struct {
|
||||||
Park Park `xorm:"extends" json:"park"`
|
Park Park `bun:"extends" json:"park"`
|
||||||
Report *Report `xorm:"extends" json:"report"`
|
Report *Report `bun:"extends" json:"report"`
|
||||||
}
|
|
||||||
|
|
||||||
func (ParkNewestReport) TableName() string {
|
|
||||||
return "park"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ParkNewestReport) AfterLoad() {
|
func (p *ParkNewestReport) AfterLoad() {
|
||||||
@@ -64,27 +66,34 @@ func (p *ParkNewestReport) AfterLoad() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ReportIndexSimplified struct {
|
type ReportIndexSimplified struct {
|
||||||
Id string `xorm:"varchar(120) pk not null" json:"id"`
|
bun.BaseModel `bun:"table:report,alias:r"`
|
||||||
ParkId string `xorm:"varchar(120) not null" json:"parkId"`
|
Id string `bun:",pk,notnull" json:"id"`
|
||||||
Period time.Time `xorm:"date not null" json:"period" time_format:"simple_date" time_location:"shanghai"`
|
ParkId string `bun:",notnull" json:"parkId"`
|
||||||
StepState Steps `xorm:"text not null json" json:"stepState"`
|
Period Date `bun:"type:date,notnull" json:"period"`
|
||||||
Published bool `xorm:"bool not null default false" json:"published"`
|
StepState Steps `bun:"type:jsonb,notnull" json:"stepState"`
|
||||||
PublishedAt *time.Time `xorm:"timestampz" json:"publishedAt" time_format:"simple_datetime" time_location:"shanghai"`
|
Published bool `bun:",notnull" json:"published"`
|
||||||
Withdraw int8 `xorm:"smallint not null default 0" json:"withdraw"`
|
PublishedAt *time.Time `bun:"type:timestampz" json:"publishedAt" time_format:"simple_datetime" time_location:"shanghai"`
|
||||||
LastWithdrawAppliedAt *time.Time `xorm:"timestampz" json:"lastWithdrawAppliedAt" time_format:"simple_datetime" time_location:"shanghai"`
|
Withdraw int8 `bun:"type:smallint,notnull" json:"withdraw"`
|
||||||
LastWithdrawAuditAt *time.Time `xorm:"timestampz" json:"lastWithdrawAuditAt" time_format:"simple_datetime" time_location:"shanghai"`
|
LastWithdrawAppliedAt *time.Time `bun:"type:timestamptz" json:"lastWithdrawAppliedAt" time_format:"simple_datetime" time_location:"shanghai"`
|
||||||
}
|
LastWithdrawAuditAt *time.Time `bun:"type:timestamptz" json:"lastWithdrawAuditAt" time_format:"simple_datetime" time_location:"shanghai"`
|
||||||
|
|
||||||
func (ReportIndexSimplified) TableName() string {
|
|
||||||
return "report"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type JoinedReportForWithdraw struct {
|
type JoinedReportForWithdraw struct {
|
||||||
Report Report `xorm:"extends" json:"report"`
|
Report Report `bun:"extends" json:"report"`
|
||||||
Park ParkSimplified `xorm:"extends" json:"park"`
|
Park ParkSimplified `bun:"extends" json:"park"`
|
||||||
User UserDetailSimplified `xorm:"extends" json:"user"`
|
User UserDetailSimplified `bun:"extends" json:"user"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (JoinedReportForWithdraw) TableName() string {
|
var _ bun.BeforeAppendModelHook = (*Report)(nil)
|
||||||
return "report"
|
|
||||||
|
func (p *Report) BeforeAppendModel(ctx context.Context, query bun.Query) error {
|
||||||
|
oprTime := time.Now()
|
||||||
|
switch query.(type) {
|
||||||
|
case *bun.InsertQuery:
|
||||||
|
p.CreatedAt = oprTime
|
||||||
|
p.LastModifiedAt = &oprTime
|
||||||
|
case *bun.UpdateQuery:
|
||||||
|
p.LastModifiedAt = &oprTime
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+65
-52
@@ -4,62 +4,75 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
|
"github.com/uptrace/bun"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ReportSummary struct {
|
type ReportSummary struct {
|
||||||
ReportId string `xorm:"varchar(120) pk not null" json:"-"`
|
bun.BaseModel `bun:"table:report_summary,alias:rs"`
|
||||||
Overall decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"overall"`
|
ReportId string `bun:",pk,notnull" json:"-"`
|
||||||
OverallFee decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"overallFee"`
|
Overall decimal.Decimal `bun:"type:numeric,notnull" json:"overall"`
|
||||||
ConsumptionFee decimal.NullDecimal `xorm:"numeric(14,2)" json:"consumptionFee"`
|
OverallFee decimal.Decimal `bun:"type:numeric,notnull" json:"overallFee"`
|
||||||
OverallPrice decimal.NullDecimal `xorm:"numeric(16,8)" json:"overallPrice"`
|
ConsumptionFee decimal.NullDecimal `bun:"type:numeric" json:"consumptionFee"`
|
||||||
Critical decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"critical"`
|
OverallPrice decimal.NullDecimal `bun:"type:numeric" json:"overallPrice"`
|
||||||
CriticalFee decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"criticalFee"`
|
Critical decimal.Decimal `bun:"type:numeric,notnull" json:"critical"`
|
||||||
CriticalPrice decimal.NullDecimal `xorm:"numeric(16,8)" json:"criticalPrice"`
|
CriticalFee decimal.Decimal `bun:"type:numeric,notnull" json:"criticalFee"`
|
||||||
Peak decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"peak"`
|
CriticalPrice decimal.NullDecimal `bun:"type:numeric" json:"criticalPrice"`
|
||||||
PeakFee decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"peakFee"`
|
Peak decimal.Decimal `bun:"type:numeric,notnull" json:"peak"`
|
||||||
PeakPrice decimal.NullDecimal `xorm:"numeric(16,8)" json:"peakPrice"`
|
PeakFee decimal.Decimal `bun:"type:numeric,notnull" json:"peakFee"`
|
||||||
Flat decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"flat"`
|
PeakPrice decimal.NullDecimal `bun:"type:numeric" json:"peakPrice"`
|
||||||
FlatFee decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"flatFee"`
|
Flat decimal.Decimal `bun:"type:numeric,notnull" json:"flat"`
|
||||||
FlatPrice decimal.NullDecimal `xorm:"numeric(16,8)" json:"flatPrice"`
|
FlatFee decimal.Decimal `bun:"type:numeric,notnull" json:"flatFee"`
|
||||||
Valley decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"valley"`
|
FlatPrice decimal.NullDecimal `bun:"type:numeric" json:"flatPrice"`
|
||||||
ValleyFee decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"valleyFee"`
|
Valley decimal.Decimal `bun:"type:numeric,notnull" json:"valley"`
|
||||||
ValleyPrice decimal.NullDecimal `xorm:"numeric(16,8)" json:"valleyPrice"`
|
ValleyFee decimal.Decimal `bun:"type:numeric,notnull" json:"valleyFee"`
|
||||||
Loss decimal.NullDecimal `xorm:"numeric(14,2)" json:"loss"`
|
ValleyPrice decimal.NullDecimal `bun:"type:numeric" json:"valleyPrice"`
|
||||||
LossFee decimal.NullDecimal `xorm:"numeric(16,2)" json:"lossFee"`
|
Loss decimal.NullDecimal `bun:"type:numeric" json:"loss"`
|
||||||
LossProportion decimal.NullDecimal `xorm:"numeric(16,15)" json:"lossProportion"`
|
LossFee decimal.NullDecimal `bun:"type:numeric" json:"lossFee"`
|
||||||
CustomerConsumption decimal.NullDecimal `xorm:"numeric(16,2)" json:"customerConsumption"`
|
LossProportion decimal.NullDecimal `bun:"type:numeric" json:"lossProportion"`
|
||||||
CustomerConsumptionFee decimal.NullDecimal `xorm:"numeric(14,2)" json:"customerConsumptionFee"`
|
AuthorizeLoss decimal.NullDecimal `bun:"type:numeric" json:"authorizeLoss"`
|
||||||
CustomerConsumptionCritical decimal.NullDecimal `xorm:"numeric(16,2)" json:"customerConsumptionCritical"`
|
AuthorizeLossFee decimal.NullDecimal `bun:"type:numeric" json:"authorizeLossFee"`
|
||||||
CustomerConsumptionCriticalFee decimal.NullDecimal `xorm:"numeric(14,2)" json:"customerConsumptionCriticalFee"`
|
AuthorizeLossProportion decimal.NullDecimal `bun:"type:numeric" json:"authorizeLossProportion"`
|
||||||
CustomerConsumptionPeak decimal.NullDecimal `xorm:"numeric(16,2)" json:"customerConsumptionPeak"`
|
BasicFee decimal.Decimal `bun:"type:numeric,notnull" json:"basicFee"`
|
||||||
CustomerConsumptionPeakFee decimal.NullDecimal `xorm:"numeric(14,2)" json:"customerConsumptionPeakFee"`
|
BasicDilutedPrice decimal.NullDecimal `bun:"type:numeric" json:"basicDilutedPrice"`
|
||||||
CustomerConsumptionFlat decimal.NullDecimal `xorm:"numeric(16,2)" json:"customerConsumptionFlat"`
|
AdjustFee decimal.Decimal `bun:"type:numeric,notnull" json:"adjustFee"`
|
||||||
CustomerConsumptionFlatFee decimal.NullDecimal `xorm:"numeric(14,2)" json:"customerConsumptionFlatFee"`
|
AdjustDilutedPrice decimal.NullDecimal `bun:"type:numeric" json:"adjustDilutedPrice"`
|
||||||
CustomerConsumptionValley decimal.NullDecimal `xorm:"numeric(16,2)" json:"customerConsumptionValley"`
|
MaintenanceDilutedPrice decimal.NullDecimal `bun:"type:numeric" json:"maintencanceDilutedPrice"`
|
||||||
CustomerConsumptionValleyFee decimal.NullDecimal `xorm:"numeric(14,2)" json:"customerConsumptionValleyFee"`
|
LossDilutedPrice decimal.NullDecimal `bun:"type:numeric" json:"lossDilutedPrice"`
|
||||||
PublicConsumption decimal.NullDecimal `xorm:"numeric(14,2)" json:"publicConsumption"`
|
PublicConsumptionDilutedPrice decimal.NullDecimal `bun:"type:numeric" json:"publicConsumptionDilutedPrice"`
|
||||||
PublicConsumptionFee decimal.NullDecimal `xorm:"numeric(14,2)" json:"publicConsumptionFee"`
|
MaintenanceOverall decimal.NullDecimal `bun:"type:numeric" json:"maintenanceOverall"`
|
||||||
PublicConsumptionProportion decimal.NullDecimal `xorm:"numeric(16,15)" json:"publicConsumptionProportion"`
|
FinalDilutedOverall decimal.NullDecimal `bun:"type:numeric" json:"finalDilutedOverall"`
|
||||||
PublicConsumptionCritical decimal.NullDecimal `xorm:"numeric(16,2)" json:"publicConsumptionCritical"`
|
Customers Consumptions `bun:"type:jsonb" json:"customers"`
|
||||||
PublicConsumptionCriticalFee decimal.NullDecimal `xorm:"numeric(14,2)" json:"publicConsumptionCriticalFee"`
|
Publics Consumptions `bun:"type:jsonb" json:"publics"`
|
||||||
PublicConsumptionPeak decimal.NullDecimal `xorm:"numeric(16,2)" json:"publicConsumptionPeak"`
|
|
||||||
PublicConsumptionPeakFee decimal.NullDecimal `xorm:"numeric(14,2)" json:"publicConsumptionPeakFee"`
|
|
||||||
PublicConsumptionFlat decimal.NullDecimal `xorm:"numeric(16,2)" json:"publicConsumptionFlat"`
|
|
||||||
PublicConsumptionFlatFee decimal.NullDecimal `xorm:"numeric(14,2)" json:"publicConsumptionFlatFee"`
|
|
||||||
PublicConsumptionValley decimal.NullDecimal `xorm:"numeric(16,2)" json:"publicConsumptionValley"`
|
|
||||||
PublicConsumptionValleyFee decimal.NullDecimal `xorm:"numeric(14,2)" json:"publicConsumptionValleyFee"`
|
|
||||||
BasicFee decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"basicFee"`
|
|
||||||
BasicDilutedPrice decimal.NullDecimal `xorm:"numeric(18,8)" json:"basicDilutedPrice"`
|
|
||||||
AdjustFee decimal.Decimal `xorm:"numeric(14,2) not null default 0" json:"adjustFee"`
|
|
||||||
AdjustDilutedPrice decimal.NullDecimal `xorm:"numeric(18,8)" json:"adjustDilutedPrice"`
|
|
||||||
MaintenanceDilutedPrice decimal.NullDecimal `xorm:"numeric(16,8)" json:"maintencanceDilutedPrice"`
|
|
||||||
LossDilutedPrice decimal.NullDecimal `xorm:"numeric(16,8)" json:"lossDilutedPrice"`
|
|
||||||
PublicConsumptionDilutedPrice decimal.NullDecimal `xorm:"numeric(16,8)" json:"publicConsumptionDilutedPrice"`
|
|
||||||
FinalDilutedOverall decimal.NullDecimal `xorm:"numeric(14,2)" json:"finalDilutedOverall"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ReportSummary) TableName() string {
|
type Consumptions struct {
|
||||||
return "report_summary"
|
Consumption decimal.NullDecimal `json:"consumption"`
|
||||||
|
ConsumptionFee decimal.NullDecimal `json:"fee"`
|
||||||
|
Critical decimal.NullDecimal `json:"critical"`
|
||||||
|
CriticalFee decimal.NullDecimal `json:"criticalFee"`
|
||||||
|
Peak decimal.NullDecimal `json:"peak"`
|
||||||
|
PeakFee decimal.NullDecimal `json:"peakFee"`
|
||||||
|
Flat decimal.NullDecimal `json:"flat"`
|
||||||
|
FlatFee decimal.NullDecimal `json:"flatFee"`
|
||||||
|
Valley decimal.NullDecimal `json:"valley"`
|
||||||
|
ValleyFee decimal.NullDecimal `json:"valleyFee"`
|
||||||
|
Proportion decimal.NullDecimal `json:"proportion"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewConsumptions() Consumptions {
|
||||||
|
return Consumptions{
|
||||||
|
Consumption: decimal.NewNullDecimal(decimal.Zero),
|
||||||
|
ConsumptionFee: decimal.NewNullDecimal(decimal.Zero),
|
||||||
|
Critical: decimal.NewNullDecimal(decimal.Zero),
|
||||||
|
Peak: decimal.NewNullDecimal(decimal.Zero),
|
||||||
|
PeakFee: decimal.NewNullDecimal(decimal.Zero),
|
||||||
|
Flat: decimal.NewNullDecimal(decimal.Zero),
|
||||||
|
CriticalFee: decimal.NewNullDecimal(decimal.Zero),
|
||||||
|
FlatFee: decimal.NewNullDecimal(decimal.Zero),
|
||||||
|
Valley: decimal.NewNullDecimal(decimal.Zero),
|
||||||
|
ValleyFee: decimal.NewNullDecimal(decimal.Zero),
|
||||||
|
Proportion: decimal.NewNullDecimal(decimal.Zero),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s ReportSummary) Validate() (bool, error) {
|
func (s ReportSummary) Validate() (bool, error) {
|
||||||
@@ -97,7 +110,7 @@ func (s *ReportSummary) CalculatePrices() {
|
|||||||
s.ValleyPrice = decimal.NewNullDecimal(decimal.Zero)
|
s.ValleyPrice = decimal.NewNullDecimal(decimal.Zero)
|
||||||
}
|
}
|
||||||
s.Flat = s.Overall.Sub(s.Critical).Sub(s.Peak).Sub(s.Valley)
|
s.Flat = s.Overall.Sub(s.Critical).Sub(s.Peak).Sub(s.Valley)
|
||||||
s.FlatFee = s.OverallFee.Sub(s.CriticalFee).Sub(s.PeakFee).Sub(s.ValleyFee)
|
s.FlatFee = s.ConsumptionFee.Decimal.Sub(s.CriticalFee).Sub(s.PeakFee).Sub(s.ValleyFee)
|
||||||
if s.Flat.GreaterThan(decimal.Zero) {
|
if s.Flat.GreaterThan(decimal.Zero) {
|
||||||
s.FlatPrice = decimal.NewNullDecimal(s.FlatFee.Div(s.Flat).RoundBank(8))
|
s.FlatPrice = decimal.NewNullDecimal(s.FlatFee.Div(s.Flat).RoundBank(8))
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+11
-11
@@ -3,30 +3,30 @@ package model
|
|||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
type Created struct {
|
type Created struct {
|
||||||
CreatedAt time.Time `xorm:"timestampz not null created" json:"createdAt" time_format:"simple_datetime" time_location:"shanghai"`
|
CreatedAt time.Time `bun:"type:timestamptz,notnull" json:"createdAt" time_format:"simple_datetime" time_location:"shanghai"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreatedWithUser struct {
|
type CreatedWithUser struct {
|
||||||
Created `xorm:"extends"`
|
Created `bun:"extend"`
|
||||||
CreatedBy *string `xorm:"varchar(100)" json:"createdBy"`
|
CreatedBy *string `json:"createdBy"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Deleted struct {
|
type Deleted struct {
|
||||||
DeletedAt *time.Time `xorm:"timestampz deleted" json:"deletedAt" time_format:"simple_datetime" time_location:"shanghai"`
|
DeletedAt *time.Time `bun:"type:timestamptz,soft_delete,nullzero" json:"deletedAt" time_format:"simple_datetime" time_location:"shanghai"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeletedWithUser struct {
|
type DeletedWithUser struct {
|
||||||
Deleted `xorm:"extends"`
|
Deleted `bun:"extend"`
|
||||||
DeletedBy *string `xorm:"varchar(120)" json:"deletedBy"`
|
DeletedBy *string `json:"deletedBy"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreatedAndModified struct {
|
type CreatedAndModified struct {
|
||||||
Created `xorm:"extends"`
|
Created `bun:"extend"`
|
||||||
LastModifiedAt *time.Time `xorm:"timestampz updated" json:"lastModifiedAt" time_format:"simple_datetime" time_location:"shanghai"`
|
LastModifiedAt *time.Time `bun:"type:timestamptz,nullzero" json:"lastModifiedAt" time_format:"simple_datetime" time_location:"shanghai"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreatedAndModifiedWithUser struct {
|
type CreatedAndModifiedWithUser struct {
|
||||||
CreatedAndModified `xorm:"extends"`
|
CreatedAndModified `bun:"extend"`
|
||||||
CreatedBy *string `xorm:"varchar(100)" json:"createdBy"`
|
CreatedBy *string `json:"createdBy"`
|
||||||
LastModifiedBy *string `xorm:"varchar(100)" json:"lastModifiedBy"`
|
LastModifiedBy *string `json:"lastModifiedBy"`
|
||||||
}
|
}
|
||||||
|
|||||||
+118
@@ -0,0 +1,118 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"database/sql/driver"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Date struct {
|
||||||
|
time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDate(t time.Time) Date {
|
||||||
|
loc, err := time.LoadLocation("Asia/Shanghai")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
t = t.In(loc)
|
||||||
|
return Date{
|
||||||
|
Time: time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, loc),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEmptyDate() Date {
|
||||||
|
loc, err := time.LoadLocation("Asia/Shanghai")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return Date{
|
||||||
|
Time: time.Time{}.In(loc),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseDate(t string) (Date, error) {
|
||||||
|
loc, err := time.LoadLocation("Asia/Shanghai")
|
||||||
|
if err != nil {
|
||||||
|
return NewEmptyDate(), fmt.Errorf("unable to load time zone, %w", err)
|
||||||
|
}
|
||||||
|
d, err := time.ParseInLocation("2006-01-02", t, loc)
|
||||||
|
if err != nil {
|
||||||
|
return NewEmptyDate(), fmt.Errorf("unable to parse given time, %w", err)
|
||||||
|
}
|
||||||
|
return Date{
|
||||||
|
Time: d,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Date) IsEmpty() bool {
|
||||||
|
return d.Time.IsZero()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Date) Format(fmt string) string {
|
||||||
|
return d.Time.Format(fmt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Date) ToString() string {
|
||||||
|
return d.Time.Format("2006-01-02")
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ driver.Valuer = (*Date)(nil)
|
||||||
|
|
||||||
|
func (d Date) Value() (driver.Value, error) {
|
||||||
|
loc, err := time.LoadLocation("Asia/Shanghai")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return d.In(loc).Format("2006-01-02"), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ sql.Scanner = (*Date)(nil)
|
||||||
|
|
||||||
|
// Scan scans the time parsing it if necessary using timeFormat.
|
||||||
|
func (d *Date) Scan(src interface{}) (err error) {
|
||||||
|
loc, err := time.LoadLocation("Asia/Shanghai")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
switch src := src.(type) {
|
||||||
|
case time.Time:
|
||||||
|
*d = NewDate(src)
|
||||||
|
return nil
|
||||||
|
case string:
|
||||||
|
d.Time, err = time.ParseInLocation("2006-01-02", src, loc)
|
||||||
|
return err
|
||||||
|
case []byte:
|
||||||
|
d.Time, err = time.ParseInLocation("2006-01-02", string(src), loc)
|
||||||
|
return err
|
||||||
|
case nil:
|
||||||
|
d.Time = time.Time{}
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupported data type: %T", src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ json.Marshaler = (*Date)(nil)
|
||||||
|
|
||||||
|
func (d Date) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(d.Time.Format("2006-01-02"))
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ json.Unmarshaler = (*Date)(nil)
|
||||||
|
|
||||||
|
func (d *Date) UnmarshalJSON(raw []byte) error {
|
||||||
|
loc, err := time.LoadLocation("Asia/Shanghai")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to load time zone, %w", err)
|
||||||
|
}
|
||||||
|
var s string
|
||||||
|
err = json.Unmarshal(raw, &s)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to unmarshal value, %w", err)
|
||||||
|
}
|
||||||
|
d.Time, err = time.ParseInLocation("2006-01-02", s, loc)
|
||||||
|
return err
|
||||||
|
}
|
||||||
+33
-20
@@ -1,5 +1,12 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/uptrace/bun"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
USER_TYPE_ENT int8 = iota
|
USER_TYPE_ENT int8 = iota
|
||||||
USER_TYPE_SUP
|
USER_TYPE_SUP
|
||||||
@@ -7,29 +14,35 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
Created `xorm:"extends"`
|
bun.BaseModel `bun:"table:user,alias:u"`
|
||||||
Id string `xorm:"varchar(120) pk not null" json:"id"`
|
Created `bun:"extend"`
|
||||||
Username string `xorm:"varchar(30) not null" json:"username"`
|
Id string `bun:",pk,notnull" json:"id"`
|
||||||
Password string `xorm:"varchar(256) not null" json:"-"`
|
Username string `bun:",notnull" json:"username"`
|
||||||
ResetNeeded bool `xorm:"bool not null" json:"resetNeeded"`
|
Password string `bun:",notnull" json:"-"`
|
||||||
Type int8 `xorm:"smallint not null" json:"type"`
|
ResetNeeded bool `bun:",notnull" json:"resetNeeded"`
|
||||||
Enabled bool `xorm:"bool not null" json:"enabled"`
|
Type int8 `bun:"type:smallint,notnull" json:"type"`
|
||||||
}
|
Enabled bool `bun:",notnull" json:"enabled"`
|
||||||
|
Detail *UserDetail `bun:"rel:has-one,join:id=id" json:"-"`
|
||||||
func (User) TableName() string {
|
Charges []*UserCharge `bun:"rel:has-many,join:id=user_id" json:"-"`
|
||||||
return "user"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserWithCredentials struct {
|
type UserWithCredentials struct {
|
||||||
Created `xorm:"extends"`
|
bun.BaseModel `bun:"table:user,alias:u"`
|
||||||
Id string `xorm:"varchar(120) pk not null" json:"id"`
|
Created `bun:"extend"`
|
||||||
Username string `xorm:"varchar(30) not null" json:"username"`
|
Id string `bun:",pk,notnull" json:"id"`
|
||||||
Password string `xorm:"varchar(256) not null" json:"credential"`
|
Username string `bun:",notnull" json:"username"`
|
||||||
ResetNeeded bool `xorm:"bool not null" json:"resetNeeded"`
|
Password string `bun:",notnull" json:"credential"`
|
||||||
Type int8 `xorm:"smallint not null" json:"type"`
|
ResetNeeded bool `bun:",notnull" json:"resetNeeded"`
|
||||||
Enabled bool `xorm:"bool not null" json:"enabled"`
|
Type int8 `bun:"type:smallint,notnull" json:"type"`
|
||||||
|
Enabled bool `bun:",notnull" json:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (UserWithCredentials) TableName() string {
|
var _ bun.BeforeAppendModelHook = (*User)(nil)
|
||||||
return "user"
|
|
||||||
|
func (u *User) BeforeAppendModel(ctx context.Context, query bun.Query) error {
|
||||||
|
switch query.(type) {
|
||||||
|
case *bun.InsertQuery:
|
||||||
|
u.CreatedAt = time.Now()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-21
@@ -1,36 +1,43 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
|
"github.com/uptrace/bun"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserCharge struct {
|
type UserCharge struct {
|
||||||
Created `xorm:"extends"`
|
bun.BaseModel `bun:"table:user_charge,alias:c"`
|
||||||
Seq int64 `xorm:"bigint pk not null autoincr" json:"seq"`
|
Created `bun:"extend"`
|
||||||
UserId string `xorm:"varchar(120) not null" json:"userId"`
|
Seq int64 `bun:"type:bigint,pk,notnull,autoincrement" json:"seq"`
|
||||||
Fee decimal.NullDecimal `xorm:"numeric(12,2)" json:"fee"`
|
UserId string `bun:",notnull" json:"userId"`
|
||||||
Discount decimal.NullDecimal `xorm:"numeric(5,4)" json:"discount"`
|
Fee decimal.NullDecimal `bun:"type:numeric" json:"fee"`
|
||||||
Amount decimal.NullDecimal `xorm:"numeric(12,2)" json:"amount"`
|
Discount decimal.NullDecimal `bun:"type:numeric" json:"discount"`
|
||||||
ChargeTo time.Time `xorm:"date not null" json:"chargeTo" time_format:"simple_date" time_location:"shanghai"`
|
Amount decimal.NullDecimal `bun:"type:numeric" json:"amount"`
|
||||||
Settled bool `xorm:"bool not null default false" json:"settled"`
|
ChargeTo Date `bun:"type:date,notnull" json:"chargeTo"`
|
||||||
SettledAt *time.Time `xorm:"timestampz" json:"settledAt" time_format:"simple_datetime" time_location:"shanghai"`
|
Settled bool `bun:",notnull" json:"settled"`
|
||||||
Cancelled bool `xorm:"bool not null default false" json:"cancelled"`
|
SettledAt *time.Time `bun:"type:timestamptz" json:"settledAt" time_format:"simple_datetime" time_location:"shanghai"`
|
||||||
CancelledAt *time.Time `xorm:"timestampz" json:"cancelledAt" time_format:"simple_datetime" time_location:"shanghai"`
|
Cancelled bool `bun:",notnull" json:"cancelled"`
|
||||||
Refunded bool `xorm:"bool not null default false" json:"refunded"`
|
CancelledAt *time.Time `bun:"type:timestamptz" json:"cancelledAt" time_format:"simple_datetime" time_location:"shanghai"`
|
||||||
RefundedAt *time.Time `xorm:"timestampz" json:"refundedAt" time_format:"simple_datetime" time_location:"shanghai"`
|
Refunded bool `bun:",notnull" json:"refunded"`
|
||||||
}
|
RefundedAt *time.Time `bun:"type:timestamptz" json:"refundedAt" time_format:"simple_datetime" time_location:"shanghai"`
|
||||||
|
Detail *UserDetail `bun:"rel:belongs-to,join:user_id=id" json:"-"`
|
||||||
func (UserCharge) TableName() string {
|
|
||||||
return "user_charge"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChargeWithName struct {
|
type ChargeWithName struct {
|
||||||
UserDetail `xorm:"extends"`
|
UserDetail `bun:"extend"`
|
||||||
UserCharge `xorm:"extends"`
|
UserCharge `bun:"extend"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ChargeWithName) TableName() string {
|
var _ bun.BeforeAppendModelHook = (*UserCharge)(nil)
|
||||||
return "user_detail"
|
|
||||||
|
func (uc *UserCharge) BeforeAppendModel(ctx context.Context, query bun.Query) error {
|
||||||
|
oprTime := time.Now()
|
||||||
|
switch query.(type) {
|
||||||
|
case *bun.InsertQuery:
|
||||||
|
uc.CreatedAt = oprTime
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+44
-35
@@ -1,60 +1,69 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/jinzhu/copier"
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
|
"github.com/uptrace/bun"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserDetail struct {
|
type UserDetail struct {
|
||||||
CreatedAndModifiedWithUser `xorm:"extends"`
|
bun.BaseModel `bun:"table:user_detail,alias:d"`
|
||||||
DeletedWithUser `xorm:"extends"`
|
CreatedAndModifiedWithUser `bun:"extend"`
|
||||||
Id string `xorm:"varchar(120) pk not null" json:"-"`
|
DeletedWithUser `bun:"extend"`
|
||||||
Name *string `xorm:"varchar(100)" json:"name"`
|
Id string `bun:",pk,notnull" json:"-"`
|
||||||
Abbr *string `xorm:"varchar(50)" json:"abbr"`
|
Name *string `json:"name"`
|
||||||
Region *string `xorm:"varchar(10)" json:"region"`
|
Abbr *string `json:"abbr"`
|
||||||
Address *string `xorm:"varchar(120)" json:"address"`
|
Region *string `json:"region"`
|
||||||
Contact *string `xorm:"varchar(100)" json:"contact"`
|
Address *string `json:"address"`
|
||||||
Phone *string `xorm:"varchar(50)" json:"phone"`
|
Contact *string `json:"contact"`
|
||||||
UnitServiceFee decimal.Decimal `xorm:"numeric(8,2) not null" json:"unitServiceFee"`
|
Phone *string `json:"phone"`
|
||||||
ServiceExpiration time.Time `xorm:"date not null" json:"serviceExpiration" time_format:"simple_date" time_location:"shanghai"`
|
UnitServiceFee decimal.Decimal `bun:"type:numeric,notnull" json:"unitServiceFee"`
|
||||||
}
|
ServiceExpiration Date `bun:"type:date,notnull" json:"serviceExpiration"`
|
||||||
|
|
||||||
func (UserDetail) TableName() string {
|
|
||||||
return "user_detail"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type JoinedUserDetail struct {
|
type JoinedUserDetail struct {
|
||||||
UserDetail `xorm:"extends"`
|
UserDetail `bun:"extend"`
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Type int8 `json:"type"`
|
Type int8 `json:"type"`
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (JoinedUserDetail) TableName() string {
|
|
||||||
return "user"
|
|
||||||
}
|
|
||||||
|
|
||||||
type FullJoinedUserDetail struct {
|
type FullJoinedUserDetail struct {
|
||||||
UserDetail `xorm:"extends"`
|
UserDetail `bun:"extend"`
|
||||||
User `xorm:"extends"`
|
User `bun:"extend"`
|
||||||
}
|
|
||||||
|
|
||||||
func (FullJoinedUserDetail) TableName() string {
|
|
||||||
return "user_detail"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserDetailSimplified struct {
|
type UserDetailSimplified struct {
|
||||||
Id string `xorm:"varchar(120) pk not null" json:"id"`
|
bun.BaseModel `bun:"table:user_detail,alias:d"`
|
||||||
Name *string `xorm:"varchar(100)" json:"name"`
|
Id string `bun:",pk,notnull" json:"id"`
|
||||||
Abbr *string `xorm:"varchar(50)" json:"abbr"`
|
Name *string `json:"name"`
|
||||||
Region *string `xorm:"varchar(10)" json:"region"`
|
Abbr *string `json:"abbr"`
|
||||||
Address *string `xorm:"varchar(120)" json:"address"`
|
Region *string `json:"region"`
|
||||||
Contact *string `xorm:"varchar(100)" json:"contact"`
|
Address *string `json:"address"`
|
||||||
Phone *string `xorm:"varchar(50)" json:"phone"`
|
Contact *string `json:"contact"`
|
||||||
|
Phone *string `json:"phone"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (UserDetailSimplified) TableName() string {
|
func FromUserDetail(user UserDetail) UserDetailSimplified {
|
||||||
return "user_detail"
|
dest := UserDetailSimplified{}
|
||||||
|
copier.Copy(&dest, user)
|
||||||
|
return dest
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ bun.BeforeAppendModelHook = (*UserDetail)(nil)
|
||||||
|
|
||||||
|
func (d *UserDetail) BeforeAppendModel(ctx context.Context, query bun.Query) error {
|
||||||
|
oprTime := time.Now()
|
||||||
|
switch query.(type) {
|
||||||
|
case *bun.InsertQuery:
|
||||||
|
d.CreatedAt = oprTime
|
||||||
|
d.LastModifiedAt = &oprTime
|
||||||
|
case *bun.UpdateQuery:
|
||||||
|
d.LastModifiedAt = &oprTime
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-10
@@ -1,17 +1,35 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import "github.com/shopspring/decimal"
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
"github.com/uptrace/bun"
|
||||||
|
)
|
||||||
|
|
||||||
type WillDilutedFee struct {
|
type WillDilutedFee struct {
|
||||||
CreatedAndModified `xorm:"extends"`
|
bun.BaseModel `bun:"table:will_diluted_fee,alias:w"`
|
||||||
Id string `xorm:"varchar(120) pk not null" json:"id"`
|
CreatedAndModified `bun:"extend"`
|
||||||
ReportId string `xorm:"varchar(120) not null" json:"reportId"`
|
Id string `bun:",pk,notnull" json:"diluteId"`
|
||||||
SourceId *string `xorm:"varchar(120)" json:"sourceId"`
|
ReportId string `bun:",notnull" json:"reportId"`
|
||||||
Name string `xorm:"varchar(50) not null" json:"name"`
|
SourceId *string `json:"sourceId"`
|
||||||
Fee decimal.Decimal `xorm:"numeric(8,2) not null default 0" json:"fee"`
|
Name string `bun:",notnull" json:"name"`
|
||||||
Memo *string `xorm:"text" json:"memo"`
|
Fee decimal.Decimal `bun:"type:numeric,notnull" json:"fee"`
|
||||||
|
Memo *string `bun:"type:text" json:"memo"`
|
||||||
|
Origin *MaintenanceFee `bun:"rel:belongs-to,join:source_id=id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (WillDilutedFee) TableName() string {
|
var _ bun.BeforeAppendModelHook = (*WillDilutedFee)(nil)
|
||||||
return "will_diluted_fee"
|
|
||||||
|
func (d *WillDilutedFee) BeforeAppendModel(ctx context.Context, query bun.Query) error {
|
||||||
|
oprTime := time.Now()
|
||||||
|
switch query.(type) {
|
||||||
|
case *bun.InsertQuery:
|
||||||
|
d.CreatedAt = oprTime
|
||||||
|
d.LastModifiedAt = &oprTime
|
||||||
|
case *bun.UpdateQuery:
|
||||||
|
d.LastModifiedAt = &oprTime
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+41
-32
@@ -2,13 +2,12 @@ package response
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"electricity_bill_calc/config"
|
"electricity_bill_calc/config"
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Result struct {
|
type Result struct {
|
||||||
Ctx *gin.Context
|
Ctx *fiber.Ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
type BaseResponse struct {
|
type BaseResponse struct {
|
||||||
@@ -22,11 +21,11 @@ type PagedResponse struct {
|
|||||||
Total int64 `json:"total"`
|
Total int64 `json:"total"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewResult(ctx *gin.Context) *Result {
|
func NewResult(ctx *fiber.Ctx) Result {
|
||||||
return &Result{Ctx: ctx}
|
return Result{Ctx: ctx}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Result) response(status, code int, msg string, payloads ...map[string]interface{}) {
|
func (r Result) response(status, code int, msg string, payloads ...map[string]interface{}) error {
|
||||||
var finalPayload = make(map[string]interface{}, 0)
|
var finalPayload = make(map[string]interface{}, 0)
|
||||||
finalPayload["code"] = code
|
finalPayload["code"] = code
|
||||||
finalPayload["message"] = msg
|
finalPayload["message"] = msg
|
||||||
@@ -37,68 +36,78 @@ func (r *Result) response(status, code int, msg string, payloads ...map[string]i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r.Ctx.JSON(status, finalPayload)
|
return r.Ctx.Status(status).JSON(finalPayload)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 禁止访问响应
|
||||||
|
func (r Result) Forbidden(msg string) error {
|
||||||
|
return r.response(fiber.StatusForbidden, fiber.StatusForbidden, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 操作出错(未成功)响应
|
// 操作出错(未成功)响应
|
||||||
func (r *Result) Failure(code int, msg string) {
|
func (r Result) Failure(code int, msg string) error {
|
||||||
r.response(http.StatusInternalServerError, code, msg)
|
return r.response(fiber.StatusInternalServerError, code, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 操作出错(未成功)响应
|
// 操作出错(未成功)响应
|
||||||
func (r *Result) Error(code int, msg string) {
|
func (r Result) Error(code int, msg string) error {
|
||||||
r.response(http.StatusOK, code, msg)
|
return r.response(fiber.StatusOK, code, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不能解析传入的参数
|
||||||
|
func (r Result) UnableToParse(msg string) error {
|
||||||
|
return r.response(fiber.StatusInternalServerError, fiber.StatusInternalServerError, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用户未获得授权)响应
|
// 用户未获得授权)响应
|
||||||
func (r *Result) Unauthorized(msg string) {
|
func (r *Result) Unauthorized(msg string) error {
|
||||||
r.response(http.StatusOK, http.StatusUnauthorized, msg)
|
return r.response(fiber.StatusOK, fiber.StatusUnauthorized, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 简易操作成功信息
|
// 简易操作成功信息
|
||||||
func (r *Result) Success(msg string, payloads ...map[string]interface{}) {
|
func (r *Result) Success(msg string, payloads ...map[string]interface{}) error {
|
||||||
r.response(http.StatusOK, http.StatusOK, msg, payloads...)
|
return r.response(fiber.StatusOK, fiber.StatusOK, msg, payloads...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数据成功创建
|
// 数据成功创建
|
||||||
func (r *Result) Created(msg string, payloads ...map[string]interface{}) {
|
func (r Result) Created(msg string, payloads ...map[string]interface{}) error {
|
||||||
r.response(http.StatusOK, http.StatusCreated, msg, payloads...)
|
return r.response(fiber.StatusOK, fiber.StatusCreated, msg, payloads...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数据成功更新
|
// 数据成功更新
|
||||||
func (r *Result) Updated(msg string) {
|
func (r Result) Updated(msg string) error {
|
||||||
r.response(http.StatusOK, http.StatusAccepted, msg)
|
return r.response(fiber.StatusOK, fiber.StatusAccepted, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数据已成功删除
|
// 数据已成功删除
|
||||||
func (r *Result) Deleted(msg string) {
|
func (r Result) Deleted(msg string) error {
|
||||||
r.response(http.StatusOK, http.StatusNoContent, msg)
|
return r.response(fiber.StatusOK, fiber.StatusNoContent, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 指定操作未被接受
|
// 指定操作未被接受
|
||||||
func (r *Result) BadRequest(msg string) {
|
func (r Result) BadRequest(msg string) error {
|
||||||
r.response(http.StatusOK, http.StatusBadRequest, msg)
|
return r.response(fiber.StatusOK, fiber.StatusBadRequest, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 指定操作未被接受
|
// 指定操作未被接受
|
||||||
func (r *Result) NotAccept(msg string) {
|
func (r Result) NotAccept(msg string) error {
|
||||||
r.response(http.StatusOK, http.StatusNotAcceptable, msg)
|
return r.response(fiber.StatusOK, fiber.StatusNotAcceptable, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数据未找到
|
// 数据未找到
|
||||||
func (r *Result) NotFound(msg string) {
|
func (r Result) NotFound(msg string) error {
|
||||||
r.response(http.StatusOK, http.StatusNotFound, msg)
|
return r.response(fiber.StatusOK, fiber.StatusNotFound, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数据存在冲突
|
// 数据存在冲突
|
||||||
func (r *Result) Conflict(msg string) {
|
func (r Result) Conflict(msg string) error {
|
||||||
r.response(http.StatusOK, http.StatusConflict, msg)
|
return r.response(fiber.StatusOK, fiber.StatusConflict, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 快速自由JSON格式响应
|
// 快速自由JSON格式响应
|
||||||
// ! 注意,给定的map中,同名的键会被覆盖。
|
// ! 注意,给定的map中,同名的键会被覆盖。
|
||||||
func (r *Result) Json(code int, msg string, payloads ...map[string]interface{}) {
|
func (r Result) Json(code int, msg string, payloads ...map[string]interface{}) error {
|
||||||
r.response(http.StatusOK, code, msg, payloads...)
|
return r.response(fiber.StatusOK, code, msg, payloads...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPagedResponse(page int, total int64) *PagedResponse {
|
func NewPagedResponse(page int, total int64) *PagedResponse {
|
||||||
@@ -106,7 +115,7 @@ func NewPagedResponse(page int, total int64) *PagedResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r PagedResponse) ToMap() map[string]interface{} {
|
func (r PagedResponse) ToMap() map[string]interface{} {
|
||||||
return gin.H{
|
return fiber.Map{
|
||||||
"current": r.Page,
|
"current": r.Page,
|
||||||
"pageSize": r.Size,
|
"pageSize": r.Size,
|
||||||
"total": r.Total,
|
"total": r.Total,
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package response
|
|||||||
import (
|
import (
|
||||||
"electricity_bill_calc/model"
|
"electricity_bill_calc/model"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LoginResponse struct {
|
type LoginResponse struct {
|
||||||
@@ -11,19 +13,19 @@ type LoginResponse struct {
|
|||||||
Session *model.Session `json:"session"`
|
Session *model.Session `json:"session"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Result) LoginSuccess(session *model.Session) {
|
func (r Result) LoginSuccess(session *model.Session) error {
|
||||||
res := &LoginResponse{}
|
res := &LoginResponse{}
|
||||||
res.Code = http.StatusOK
|
res.Code = http.StatusOK
|
||||||
res.Message = "用户已成功登录。"
|
res.Message = "用户已成功登录。"
|
||||||
res.NeedReset = false
|
res.NeedReset = false
|
||||||
res.Session = session
|
res.Session = session
|
||||||
r.Ctx.JSON(http.StatusOK, res)
|
return r.Ctx.Status(fiber.StatusOK).JSON(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Result) LoginNeedReset() {
|
func (r Result) LoginNeedReset() error {
|
||||||
res := &LoginResponse{}
|
res := &LoginResponse{}
|
||||||
res.Code = http.StatusUnauthorized
|
res.Code = http.StatusUnauthorized
|
||||||
res.Message = "用户凭据已失效。"
|
res.Message = "用户凭据已失效。"
|
||||||
res.NeedReset = true
|
res.NeedReset = true
|
||||||
r.Ctx.JSON(http.StatusOK, res)
|
return r.Ctx.Status(fiber.StatusOK).JSON(res)
|
||||||
}
|
}
|
||||||
|
|||||||
+66
-35
@@ -2,48 +2,79 @@ package router
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"electricity_bill_calc/controller"
|
"electricity_bill_calc/controller"
|
||||||
"electricity_bill_calc/response"
|
"electricity_bill_calc/logger"
|
||||||
"electricity_bill_calc/security"
|
"electricity_bill_calc/security"
|
||||||
"log"
|
"fmt"
|
||||||
"runtime/debug"
|
"runtime"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/gofiber/fiber/v2/middleware/compress"
|
||||||
|
"github.com/gofiber/fiber/v2/middleware/recover"
|
||||||
|
jsontime "github.com/liamylian/jsontime/v2/v2"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Router() *gin.Engine {
|
var json = jsontime.ConfigWithCustomTimeFormat
|
||||||
router := gin.Default()
|
|
||||||
router.Use(Recover)
|
|
||||||
router.Use(security.SessionRecovery)
|
|
||||||
|
|
||||||
controller.InitializeUserController(router)
|
func init() {
|
||||||
controller.InitializeRegionController(router)
|
timeZoneShanghai, _ := time.LoadLocation("Asia/Shanghai")
|
||||||
controller.InitializeChargesController(router)
|
jsontime.AddTimeFormatAlias("simple_datetime", "2006-01-02 15:04:05")
|
||||||
controller.InitializeParkController(router)
|
jsontime.AddTimeFormatAlias("simple_date", "2006-01-02")
|
||||||
controller.InitializeMaintenanceFeeController(router)
|
jsontime.AddLocaleAlias("shanghai", timeZoneShanghai)
|
||||||
controller.InitializeMeter04kVController(router)
|
|
||||||
controller.InitializeReportController(router)
|
|
||||||
controller.InitializeEndUserController(router)
|
|
||||||
controller.InitializeWithdrawController(router)
|
|
||||||
controller.InitializeStatisticsController(router)
|
|
||||||
|
|
||||||
return router
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 404
|
func App() *fiber.App {
|
||||||
func HandleNotFound(c *gin.Context) {
|
app := fiber.New(fiber.Config{
|
||||||
response.NewResult(c).NotFound("指定资源未找到。")
|
BodyLimit: 10 * 1024 * 1024,
|
||||||
|
EnablePrintRoutes: true,
|
||||||
|
EnableTrustedProxyCheck: false,
|
||||||
|
Prefork: false,
|
||||||
|
ErrorHandler: errorHandler,
|
||||||
|
JSONEncoder: json.Marshal,
|
||||||
|
JSONDecoder: json.Unmarshal,
|
||||||
|
})
|
||||||
|
app.Use(compress.New())
|
||||||
|
app.Use(recover.New(recover.Config{
|
||||||
|
EnableStackTrace: true,
|
||||||
|
StackTraceHandler: stackTraceHandler,
|
||||||
|
}))
|
||||||
|
app.Use(logger.NewLogMiddleware(logger.LogMiddlewareConfig{
|
||||||
|
Logger: logger.Named("App"),
|
||||||
|
}))
|
||||||
|
app.Use(security.SessionRecovery)
|
||||||
|
|
||||||
|
controller.InitializeUserController(app)
|
||||||
|
controller.InitializeRegionController(app)
|
||||||
|
controller.InitializeChargesController(app)
|
||||||
|
controller.InitializeParkController(app)
|
||||||
|
controller.InitializeMaintenanceFeeController(app)
|
||||||
|
controller.InitializeMeter04kVController(app)
|
||||||
|
controller.InitializeReportController(app)
|
||||||
|
controller.InitializeEndUserController(app)
|
||||||
|
controller.InitializeWithdrawController(app)
|
||||||
|
controller.InitializeStatisticsController(app)
|
||||||
|
controller.InitializeGodModeController(app)
|
||||||
|
|
||||||
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
// 500
|
// 全局错误处理
|
||||||
func Recover(c *gin.Context) {
|
func errorHandler(c *fiber.Ctx, err error) error {
|
||||||
defer func() {
|
code := fiber.StatusInternalServerError
|
||||||
if r := recover(); r != nil {
|
if e, ok := err.(*fiber.Error); ok {
|
||||||
//打印错误堆栈信息
|
code = e.Code
|
||||||
log.Printf("panic: %v\n", r)
|
}
|
||||||
debug.PrintStack()
|
e := c.Status(code).SendString(err.Error())
|
||||||
// response.NewResult(c).Error(500, "服务器内部错误")
|
if e != nil {
|
||||||
}
|
return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||||||
}()
|
}
|
||||||
//继续后续接口调用
|
return nil
|
||||||
c.Next()
|
}
|
||||||
|
|
||||||
|
// 处理Recover中间件输出的栈追踪信息
|
||||||
|
func stackTraceHandler(c *fiber.Ctx, e interface{}) {
|
||||||
|
buf := make([]byte, 1024)
|
||||||
|
buf = buf[:runtime.Stack(buf, false)]
|
||||||
|
logger.Named("App", "StackTrace").Warn(fmt.Sprintf("panic: %+v", e), zap.ByteString("trace", buf), zap.Any("origin", e))
|
||||||
}
|
}
|
||||||
|
|||||||
+32
-39
@@ -3,76 +3,69 @@ package security
|
|||||||
import (
|
import (
|
||||||
"electricity_bill_calc/cache"
|
"electricity_bill_calc/cache"
|
||||||
"electricity_bill_calc/model"
|
"electricity_bill_calc/model"
|
||||||
"net/http"
|
"electricity_bill_calc/response"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 用于解析Authorization头,并从缓存中获取用户会话信息注入上下文的中间件。
|
// 用于解析Authorization头,并从缓存中获取用户会话信息注入上下文的中间件。
|
||||||
// 如果没有获取到用户会话信息,将直接跳过会话信息注入。
|
// 如果没有获取到用户会话信息,将直接跳过会话信息注入。
|
||||||
// ! 仅通过该中间件是不能保证上下文中一定保存有用户会话信息的。
|
// ! 仅通过该中间件是不能保证上下文中一定保存有用户会话信息的。
|
||||||
func SessionRecovery(c *gin.Context) {
|
func SessionRecovery(c *fiber.Ctx) error {
|
||||||
auth := c.Request.Header.Get("Authorization")
|
if auth := c.Get("Authorization", ""); len(auth) > 0 {
|
||||||
if len(auth) > 0 {
|
|
||||||
token := strings.Fields(auth)[1]
|
token := strings.Fields(auth)[1]
|
||||||
session, err := cache.RetreiveSession(token)
|
session, err := cache.RetreiveSession(token)
|
||||||
|
|
||||||
if err == nil && session != nil {
|
if err == nil && session != nil {
|
||||||
c.Set("session", session)
|
c.Locals("session", session)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.Next()
|
return c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用于强制确定用户已经登录了系统,即具有有效的用户会话
|
// 用于强制确定用户已经登录了系统,即具有有效的用户会话
|
||||||
// ! 通过该中间件以后,是可以保证上下文中一定具有用户会话信息的。
|
// ! 通过该中间件以后,是可以保证上下文中一定具有用户会话信息的。
|
||||||
func MustAuthenticated(c *gin.Context) {
|
func MustAuthenticated(c *fiber.Ctx) error {
|
||||||
session, exists := c.Get("session")
|
if session, ok := c.Locals("session").(*model.Session); !ok || session == nil {
|
||||||
if !exists || session == nil {
|
return response.NewResult(c).Forbidden("用户必须在登录以后才能访问系统。")
|
||||||
c.AbortWithStatus(http.StatusForbidden)
|
|
||||||
}
|
}
|
||||||
if _, ok := session.(*model.Session); !ok {
|
return c.Next()
|
||||||
c.AbortWithStatus(http.StatusForbidden)
|
|
||||||
}
|
|
||||||
c.Next()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用于对用户会话进行是否企业用户的判断
|
// 用于对用户会话进行是否企业用户的判断
|
||||||
// ! 通过该中间件以后,是可以保证上下文中一定具有用户会话信息的。
|
// ! 通过该中间件以后,是可以保证上下文中一定具有用户会话信息的。
|
||||||
func EnterpriseAuthorize(c *gin.Context) {
|
func EnterpriseAuthorize(c *fiber.Ctx) error {
|
||||||
session, exists := c.Get("session")
|
if sess, ok := c.Locals("session").(*model.Session); !ok || sess.Type != model.USER_TYPE_ENT {
|
||||||
if !exists || session == nil {
|
return response.NewResult(c).Forbidden("指定接口资源只限企业用户访问。")
|
||||||
c.AbortWithStatus(http.StatusForbidden)
|
|
||||||
}
|
}
|
||||||
if sess, ok := session.(*model.Session); !ok || sess.Type != model.USER_TYPE_ENT {
|
return c.Next()
|
||||||
c.AbortWithStatus(http.StatusForbidden)
|
|
||||||
}
|
|
||||||
c.Next()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用于对用户会话进行是否监管用户或运维用户的判断
|
// 用于对用户会话进行是否监管用户或运维用户的判断
|
||||||
// ! 通过该中间件以后,是可以保证上下文中一定具有用户会话信息的。
|
// ! 通过该中间件以后,是可以保证上下文中一定具有用户会话信息的。
|
||||||
func ManagementAuthorize(c *gin.Context) {
|
func ManagementAuthorize(c *fiber.Ctx) error {
|
||||||
session, exists := c.Get("session")
|
if sess, ok := c.Locals("session").(*model.Session); !ok || (sess.Type != model.USER_TYPE_SUP && sess.Type != model.USER_TYPE_OPS) {
|
||||||
if !exists || session == nil {
|
r := response.NewResult(c)
|
||||||
c.AbortWithStatus(http.StatusForbidden)
|
return r.Forbidden("指定接口资源只限市场监管用户访问。")
|
||||||
}
|
}
|
||||||
if sess, ok := session.(*model.Session); !ok || (sess.Type != model.USER_TYPE_SUP && sess.Type != model.USER_TYPE_OPS) {
|
return c.Next()
|
||||||
c.AbortWithStatus(http.StatusForbidden)
|
|
||||||
}
|
|
||||||
c.Next()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用于对用户会话进行是否运维用户的判断
|
// 用于对用户会话进行是否运维用户的判断
|
||||||
// ! 通过该中间件以后,是可以保证上下文中一定具有用户会话信息的。
|
// ! 通过该中间件以后,是可以保证上下文中一定具有用户会话信息的。
|
||||||
func OPSAuthorize(c *gin.Context) {
|
func OPSAuthorize(c *fiber.Ctx) error {
|
||||||
session, exists := c.Get("session")
|
if sess, ok := c.Locals("session").(*model.Session); !ok || sess.Type != model.USER_TYPE_OPS {
|
||||||
if !exists {
|
return response.NewResult(c).Forbidden("指定接口资源只限系统运维用户访问。")
|
||||||
c.AbortWithStatus(http.StatusForbidden)
|
|
||||||
}
|
}
|
||||||
if sess, ok := session.(*model.Session); !ok || sess.Type != model.USER_TYPE_OPS {
|
return c.Next()
|
||||||
c.AbortWithStatus(http.StatusForbidden)
|
}
|
||||||
}
|
|
||||||
c.Next()
|
// 用于对用户会话进行是否核心运维用户的判断
|
||||||
|
// ! 通过该中间件以后,是可以保证上下文中一定具有用户会话信息的。
|
||||||
|
func SingularityAuthorize(c *fiber.Ctx) error {
|
||||||
|
if sess, ok := c.Locals("session").(*model.Session); !ok || sess.Type != model.USER_TYPE_OPS || sess.Uid != "000" {
|
||||||
|
return response.NewResult(c).Forbidden("指定接口资源只限系统核心运维用户访问。")
|
||||||
|
}
|
||||||
|
return c.Next()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
package service
|
|
||||||
|
|
||||||
func _postProcessSingle[T interface{}](instance *T, has bool, err error) (*T, error) {
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if has {
|
|
||||||
return instance, nil
|
|
||||||
} else {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+172
-158
@@ -1,6 +1,7 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"electricity_bill_calc/cache"
|
"electricity_bill_calc/cache"
|
||||||
"electricity_bill_calc/exceptions"
|
"electricity_bill_calc/exceptions"
|
||||||
"electricity_bill_calc/global"
|
"electricity_bill_calc/global"
|
||||||
@@ -8,8 +9,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
"xorm.io/builder"
|
|
||||||
"xorm.io/xorm/schemas"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type _CalculateService struct{}
|
type _CalculateService struct{}
|
||||||
@@ -17,221 +16,236 @@ type _CalculateService struct{}
|
|||||||
var CalculateService _CalculateService
|
var CalculateService _CalculateService
|
||||||
|
|
||||||
func (_CalculateService) ComprehensivelyCalculateReport(reportId string) (err error) {
|
func (_CalculateService) ComprehensivelyCalculateReport(reportId string) (err error) {
|
||||||
|
ctx, cancel := global.TimeoutContext(12)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
// 资料准备
|
// 资料准备
|
||||||
var reportIndex = new(model.Report)
|
var report = new(model.Report)
|
||||||
has, err := global.DBConn.ID(reportId).NoAutoCondition().Get(reportIndex)
|
err = global.DB.NewSelect().Model(report).
|
||||||
if err != nil || !has {
|
Relation("Summary").
|
||||||
|
Relation("WillDilutedFees").
|
||||||
|
Relation("EndUsers").
|
||||||
|
Where("r.id = ?", reportId).
|
||||||
|
Scan(ctx)
|
||||||
|
if err != nil || report == nil {
|
||||||
return exceptions.NewNotFoundErrorFromError("未找到指定的公示报表", err)
|
return exceptions.NewNotFoundErrorFromError("未找到指定的公示报表", err)
|
||||||
}
|
}
|
||||||
var summary = new(model.ReportSummary)
|
|
||||||
has, err = global.DBConn.ID(reportId).NoAutoCondition().Get(summary)
|
|
||||||
if err != nil || !has {
|
|
||||||
return exceptions.NewNotFoundErrorFromError("未找到指定的公示报表概览", err)
|
|
||||||
}
|
|
||||||
var maintenanceFeeRecords = make([]model.WillDilutedFee, 0)
|
|
||||||
err = global.DBConn.Where(builder.Eq{"report_id": reportId}).Find(&maintenanceFeeRecords)
|
|
||||||
if err != nil {
|
|
||||||
return exceptions.NewNotFoundErrorFromError("未能获取到公示报表对应的待摊薄费用信息", err)
|
|
||||||
}
|
|
||||||
var endUserDetails = make([]*model.EndUserDetail, 0)
|
|
||||||
err = global.DBConn.Where(builder.Eq{"report_id": reportId}).Find(&endUserDetails)
|
|
||||||
if err != nil {
|
|
||||||
return exceptions.NewNotFoundErrorFromError("未获取到公示报表对应的终端用户抄表信息", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 综合计算
|
// 综合计算
|
||||||
summary.CalculatePrices()
|
report.Summary.CalculatePrices()
|
||||||
|
|
||||||
// 计算维护费总计
|
// 计算维护费总计
|
||||||
maintenanceFeeTotal := decimal.NewFromInt(0)
|
maintenanceFeeTotal := decimal.NewFromInt(0)
|
||||||
for _, m := range maintenanceFeeRecords {
|
for _, m := range report.WillDilutedFees {
|
||||||
maintenanceFeeTotal = maintenanceFeeTotal.Add(m.Fee)
|
maintenanceFeeTotal = maintenanceFeeTotal.Add(m.Fee)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算终端用户信息与概览中的合计
|
// 计算终端用户信息与概览中的合计
|
||||||
summary.PublicConsumption = decimal.NewNullDecimal(decimal.Zero)
|
report.Summary.Customers = model.NewConsumptions()
|
||||||
summary.PublicConsumptionCritical = decimal.NewNullDecimal(decimal.Zero)
|
report.Summary.Publics = model.NewConsumptions()
|
||||||
summary.PublicConsumptionPeak = decimal.NewNullDecimal(decimal.Zero)
|
for _, eu := range report.EndUsers {
|
||||||
summary.PublicConsumptionFlat = decimal.NewNullDecimal(decimal.Zero)
|
|
||||||
summary.PublicConsumptionValley = decimal.NewNullDecimal(decimal.Zero)
|
|
||||||
summary.CustomerConsumption = decimal.NewNullDecimal(decimal.Zero)
|
|
||||||
summary.CustomerConsumptionCritical = decimal.NewNullDecimal(decimal.Zero)
|
|
||||||
summary.CustomerConsumptionPeak = decimal.NewNullDecimal(decimal.Zero)
|
|
||||||
summary.CustomerConsumptionFlat = decimal.NewNullDecimal(decimal.Zero)
|
|
||||||
summary.CustomerConsumptionValley = decimal.NewNullDecimal(decimal.Zero)
|
|
||||||
for _, eu := range endUserDetails {
|
|
||||||
eu.OverallFee = decimal.NewNullDecimal(
|
eu.OverallFee = decimal.NewNullDecimal(
|
||||||
eu.Overall.Decimal.Mul(summary.OverallPrice.Decimal).RoundBank(2),
|
eu.Overall.Decimal.Mul(report.Summary.OverallPrice.Decimal).RoundBank(2),
|
||||||
)
|
)
|
||||||
eu.CriticalFee = decimal.NewNullDecimal(
|
eu.CriticalFee = decimal.NewNullDecimal(
|
||||||
eu.Critical.Decimal.Mul(summary.CriticalPrice.Decimal).RoundBank(2),
|
eu.Critical.Decimal.Mul(report.Summary.CriticalPrice.Decimal).RoundBank(2),
|
||||||
)
|
)
|
||||||
eu.PeakFee = decimal.NewNullDecimal(
|
eu.PeakFee = decimal.NewNullDecimal(
|
||||||
eu.Peak.Decimal.Mul(summary.PeakPrice.Decimal).RoundBank(2),
|
eu.Peak.Decimal.Mul(report.Summary.PeakPrice.Decimal).RoundBank(2),
|
||||||
)
|
)
|
||||||
eu.FlatFee = decimal.NewNullDecimal(
|
eu.FlatFee = decimal.NewNullDecimal(
|
||||||
eu.Flat.Decimal.Mul(summary.FlatPrice.Decimal).RoundBank(2),
|
eu.Flat.Decimal.Mul(report.Summary.FlatPrice.Decimal).RoundBank(2),
|
||||||
)
|
)
|
||||||
eu.ValleyFee = decimal.NewNullDecimal(
|
eu.ValleyFee = decimal.NewNullDecimal(
|
||||||
eu.Valley.Decimal.Mul(summary.ValleyPrice.Decimal).RoundBank(2),
|
eu.Valley.Decimal.Mul(report.Summary.ValleyPrice.Decimal).RoundBank(2),
|
||||||
)
|
)
|
||||||
if eu.IsPublicMeter && eu.WillDilute {
|
if eu.IsPublicMeter {
|
||||||
summary.PublicConsumption.Decimal = summary.PublicConsumption.Decimal.Add(eu.Overall.Decimal)
|
report.Summary.Publics.Consumption.Decimal = report.Summary.Publics.Consumption.Decimal.Add(eu.Overall.Decimal)
|
||||||
summary.PublicConsumptionCritical.Decimal = summary.PublicConsumptionCritical.Decimal.Add(eu.Critical.Decimal)
|
report.Summary.Publics.Critical.Decimal = report.Summary.Publics.Critical.Decimal.Add(eu.Critical.Decimal)
|
||||||
summary.PublicConsumptionPeak.Decimal = summary.PublicConsumptionPeak.Decimal.Add(eu.Peak.Decimal)
|
report.Summary.Publics.Peak.Decimal = report.Summary.Publics.Peak.Decimal.Add(eu.Peak.Decimal)
|
||||||
summary.PublicConsumptionFlat.Decimal = summary.PublicConsumptionPeak.Decimal.Add(eu.Flat.Decimal)
|
report.Summary.Publics.Flat.Decimal = report.Summary.Publics.Flat.Decimal.Add(eu.Flat.Decimal)
|
||||||
summary.PublicConsumptionValley.Decimal = summary.PublicConsumptionValley.Decimal.Add(eu.Valley.Decimal)
|
report.Summary.Publics.Valley.Decimal = report.Summary.Publics.Valley.Decimal.Add(eu.Valley.Decimal)
|
||||||
} else {
|
} else {
|
||||||
summary.CustomerConsumption.Decimal = summary.CustomerConsumption.Decimal.Add(eu.Overall.Decimal)
|
report.Summary.Customers.Consumption.Decimal = report.Summary.Customers.Consumption.Decimal.Add(eu.Overall.Decimal)
|
||||||
summary.CustomerConsumptionCritical.Decimal = summary.CustomerConsumptionCritical.Decimal.Add(eu.Critical.Decimal)
|
report.Summary.Customers.Critical.Decimal = report.Summary.Customers.Critical.Decimal.Add(eu.Critical.Decimal)
|
||||||
summary.CustomerConsumptionPeak.Decimal = summary.CustomerConsumptionPeak.Decimal.Add(eu.Peak.Decimal)
|
report.Summary.Customers.Peak.Decimal = report.Summary.Customers.Peak.Decimal.Add(eu.Peak.Decimal)
|
||||||
summary.CustomerConsumptionFlat.Decimal = summary.CustomerConsumptionPeak.Decimal.Add(eu.Flat.Decimal)
|
report.Summary.Customers.Flat.Decimal = report.Summary.Customers.Flat.Decimal.Add(eu.Flat.Decimal)
|
||||||
summary.CustomerConsumptionValley.Decimal = summary.CustomerConsumptionValley.Decimal.Add(eu.Valley.Decimal)
|
report.Summary.Customers.Valley.Decimal = report.Summary.Customers.Valley.Decimal.Add(eu.Valley.Decimal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算户表总电费和公共总电费以及相应的摊薄
|
// 计算户表总电费和公共总电费以及相应的摊薄
|
||||||
summary.CustomerConsumptionFee = decimal.NewNullDecimal(
|
if report.SubmeterType == model.CUSTOMER_METER_NON_PV {
|
||||||
summary.CustomerConsumption.Decimal.Mul(summary.OverallPrice.Decimal).RoundBank(2),
|
// 计算终端用户部分
|
||||||
)
|
report.Summary.Customers.ConsumptionFee = decimal.NewNullDecimal(
|
||||||
summary.CustomerConsumptionCriticalFee = decimal.NewNullDecimal(
|
report.Summary.Customers.Consumption.Decimal.Mul(report.Summary.OverallPrice.Decimal).RoundBank(2),
|
||||||
summary.CustomerConsumptionCritical.Decimal.Mul(summary.OverallPrice.Decimal).RoundBank(2),
|
)
|
||||||
)
|
report.Summary.Customers.CriticalFee = decimal.NewNullDecimal(
|
||||||
summary.CustomerConsumptionPeakFee = decimal.NewNullDecimal(
|
report.Summary.Customers.Critical.Decimal.Mul(report.Summary.OverallPrice.Decimal).RoundBank(2),
|
||||||
summary.CustomerConsumptionPeak.Decimal.Mul(summary.OverallPrice.Decimal).RoundBank(2),
|
)
|
||||||
)
|
report.Summary.Customers.PeakFee = decimal.NewNullDecimal(
|
||||||
summary.CustomerConsumptionFlatFee = decimal.NewNullDecimal(
|
report.Summary.Customers.Peak.Decimal.Mul(report.Summary.OverallPrice.Decimal).RoundBank(2),
|
||||||
summary.CustomerConsumptionFlat.Decimal.Mul(summary.OverallPrice.Decimal).RoundBank(2),
|
)
|
||||||
)
|
report.Summary.Customers.FlatFee = decimal.NewNullDecimal(
|
||||||
summary.CustomerConsumptionValleyFee = decimal.NewNullDecimal(
|
report.Summary.Customers.Flat.Decimal.Mul(report.Summary.OverallPrice.Decimal).RoundBank(2),
|
||||||
summary.CustomerConsumptionValley.Decimal.Mul(summary.OverallPrice.Decimal).RoundBank(2),
|
)
|
||||||
)
|
report.Summary.Customers.ValleyFee = decimal.NewNullDecimal(
|
||||||
summary.PublicConsumptionFee = decimal.NewNullDecimal(
|
report.Summary.Customers.Valley.Decimal.Mul(report.Summary.OverallPrice.Decimal).RoundBank(2),
|
||||||
summary.PublicConsumption.Decimal.Mul(summary.OverallPrice.Decimal).RoundBank(2),
|
)
|
||||||
)
|
// 计算公共区域部分
|
||||||
summary.PublicConsumptionCriticalFee = decimal.NewNullDecimal(
|
report.Summary.Publics.ConsumptionFee = decimal.NewNullDecimal(
|
||||||
summary.PublicConsumptionCritical.Decimal.Mul(summary.OverallPrice.Decimal).RoundBank(2),
|
report.Summary.Publics.Consumption.Decimal.Mul(report.Summary.OverallPrice.Decimal).RoundBank(2),
|
||||||
)
|
)
|
||||||
summary.PublicConsumptionPeakFee = decimal.NewNullDecimal(
|
report.Summary.Publics.CriticalFee = decimal.NewNullDecimal(
|
||||||
summary.PublicConsumptionPeak.Decimal.Mul(summary.OverallPrice.Decimal).RoundBank(2),
|
report.Summary.Publics.Critical.Decimal.Mul(report.Summary.OverallPrice.Decimal).RoundBank(2),
|
||||||
)
|
)
|
||||||
summary.PublicConsumptionFlatFee = decimal.NewNullDecimal(
|
report.Summary.Publics.PeakFee = decimal.NewNullDecimal(
|
||||||
summary.PublicConsumptionFlat.Decimal.Mul(summary.OverallPrice.Decimal).RoundBank(2),
|
report.Summary.Publics.Peak.Decimal.Mul(report.Summary.OverallPrice.Decimal).RoundBank(2),
|
||||||
)
|
)
|
||||||
summary.PublicConsumptionValleyFee = decimal.NewNullDecimal(
|
report.Summary.Publics.FlatFee = decimal.NewNullDecimal(
|
||||||
summary.PublicConsumptionValley.Decimal.Mul(summary.OverallPrice.Decimal).RoundBank(2),
|
report.Summary.Publics.Flat.Decimal.Mul(report.Summary.OverallPrice.Decimal).RoundBank(2),
|
||||||
)
|
)
|
||||||
if summary.Overall.Abs().GreaterThan(decimal.Zero) {
|
report.Summary.Publics.ValleyFee = decimal.NewNullDecimal(
|
||||||
summary.PublicConsumptionProportion = decimal.NewNullDecimal(
|
report.Summary.Publics.Valley.Decimal.Mul(report.Summary.OverallPrice.Decimal).RoundBank(2),
|
||||||
summary.PublicConsumption.Decimal.Div(summary.Overall).RoundBank(15),
|
)
|
||||||
|
}
|
||||||
|
if report.SubmeterType == model.CUSTOMER_METER_PV {
|
||||||
|
// 计算终端用户部分
|
||||||
|
report.Summary.Customers.ConsumptionFee = decimal.NewNullDecimal(
|
||||||
|
report.Summary.Customers.Consumption.Decimal.Mul(report.Summary.OverallPrice.Decimal).RoundBank(2),
|
||||||
|
)
|
||||||
|
report.Summary.Customers.CriticalFee = decimal.NewNullDecimal(
|
||||||
|
report.Summary.Customers.Critical.Decimal.Mul(report.Summary.CriticalPrice.Decimal).RoundBank(2),
|
||||||
|
)
|
||||||
|
report.Summary.Customers.PeakFee = decimal.NewNullDecimal(
|
||||||
|
report.Summary.Customers.Peak.Decimal.Mul(report.Summary.PeakPrice.Decimal).RoundBank(2),
|
||||||
|
)
|
||||||
|
report.Summary.Customers.FlatFee = decimal.NewNullDecimal(
|
||||||
|
report.Summary.Customers.Flat.Decimal.Mul(report.Summary.FlatPrice.Decimal).RoundBank(2),
|
||||||
|
)
|
||||||
|
report.Summary.Customers.ValleyFee = decimal.NewNullDecimal(
|
||||||
|
report.Summary.Customers.Valley.Decimal.Mul(report.Summary.ValleyPrice.Decimal).RoundBank(2),
|
||||||
|
)
|
||||||
|
// 计算公共区域部分
|
||||||
|
report.Summary.Publics.ConsumptionFee = decimal.NewNullDecimal(
|
||||||
|
report.Summary.Publics.Consumption.Decimal.Mul(report.Summary.OverallPrice.Decimal).RoundBank(2),
|
||||||
|
)
|
||||||
|
report.Summary.Publics.CriticalFee = decimal.NewNullDecimal(
|
||||||
|
report.Summary.Publics.Critical.Decimal.Mul(report.Summary.CriticalPrice.Decimal).RoundBank(2),
|
||||||
|
)
|
||||||
|
report.Summary.Publics.PeakFee = decimal.NewNullDecimal(
|
||||||
|
report.Summary.Publics.Peak.Decimal.Mul(report.Summary.PeakPrice.Decimal).RoundBank(2),
|
||||||
|
)
|
||||||
|
report.Summary.Publics.FlatFee = decimal.NewNullDecimal(
|
||||||
|
report.Summary.Publics.Flat.Decimal.Mul(report.Summary.FlatPrice.Decimal).RoundBank(2),
|
||||||
|
)
|
||||||
|
report.Summary.Publics.ValleyFee = decimal.NewNullDecimal(
|
||||||
|
report.Summary.Publics.Valley.Decimal.Mul(report.Summary.ValleyPrice.Decimal).RoundBank(2),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if report.Summary.Overall.Abs().GreaterThan(decimal.Zero) {
|
||||||
|
report.Summary.Customers.Proportion = decimal.NewNullDecimal(
|
||||||
|
report.Summary.Customers.Consumption.Decimal.Div(report.Summary.Overall).RoundBank(15),
|
||||||
|
)
|
||||||
|
report.Summary.Publics.Proportion = decimal.NewNullDecimal(
|
||||||
|
report.Summary.Publics.Consumption.Decimal.Div(report.Summary.Overall).RoundBank(15),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算线损
|
// 计算线损
|
||||||
summary.Loss = decimal.NewNullDecimal(
|
report.Summary.Loss = decimal.NewNullDecimal(
|
||||||
summary.Overall.Sub(summary.PublicConsumption.Decimal).Sub(summary.CustomerConsumption.Decimal),
|
report.Summary.Overall.Sub(report.Summary.Publics.Consumption.Decimal).Sub(report.Summary.Customers.Consumption.Decimal),
|
||||||
)
|
)
|
||||||
summary.LossFee = decimal.NewNullDecimal(
|
report.Summary.LossFee = decimal.NewNullDecimal(
|
||||||
summary.Loss.Decimal.Mul(summary.OverallPrice.Decimal).RoundBank(8),
|
report.Summary.Loss.Decimal.Mul(report.Summary.OverallPrice.Decimal).RoundBank(8),
|
||||||
)
|
)
|
||||||
if summary.Overall.Abs().GreaterThan(decimal.Zero) {
|
if report.Summary.Overall.Abs().GreaterThan(decimal.Zero) {
|
||||||
summary.LossProportion = decimal.NewNullDecimal(
|
report.Summary.LossProportion = decimal.NewNullDecimal(
|
||||||
summary.Loss.Decimal.Div(summary.Overall).RoundBank(15),
|
report.Summary.Loss.Decimal.Div(report.Summary.Overall).RoundBank(15),
|
||||||
)
|
)
|
||||||
|
if report.Summary.LossProportion.Decimal.GreaterThan(decimal.NewFromFloat(0.1)) {
|
||||||
|
report.Summary.AuthorizeLoss = decimal.NewNullDecimal(
|
||||||
|
report.Summary.Overall.Mul(decimal.NewFromFloat(0.1)).RoundBank(8),
|
||||||
|
)
|
||||||
|
report.Summary.AuthorizeLossFee = decimal.NewNullDecimal(
|
||||||
|
report.Summary.AuthorizeLoss.Decimal.Mul(report.Summary.OverallPrice.Decimal).RoundBank(8),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
report.Summary.AuthorizeLoss = report.Summary.Loss
|
||||||
|
report.Summary.AuthorizeLossFee = report.Summary.LossFee
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if summary.CustomerConsumption.Decimal.Abs().GreaterThan(decimal.Zero) {
|
if report.Summary.Customers.Consumption.Decimal.Abs().GreaterThan(decimal.Zero) {
|
||||||
summary.LossDilutedPrice = decimal.NewNullDecimal(
|
report.Summary.LossDilutedPrice = decimal.NewNullDecimal(
|
||||||
summary.LossFee.Decimal.Div(summary.CustomerConsumption.Decimal).RoundBank(8),
|
report.Summary.AuthorizeLossFee.Decimal.Div(report.Summary.Customers.Consumption.Decimal).RoundBank(8),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算基本电费和调整电费等的摊薄
|
// 计算基本电费和调整电费等的摊薄
|
||||||
if summary.CustomerConsumption.Decimal.Abs().GreaterThan(decimal.Zero) {
|
if report.Summary.Customers.Consumption.Decimal.Abs().GreaterThan(decimal.Zero) {
|
||||||
summary.BasicDilutedPrice = decimal.NewNullDecimal(
|
report.Summary.BasicDilutedPrice = decimal.NewNullDecimal(
|
||||||
summary.BasicFee.Div(summary.CustomerConsumption.Decimal).RoundBank(8),
|
report.Summary.BasicFee.Div(report.Summary.Customers.Consumption.Decimal).RoundBank(8),
|
||||||
)
|
)
|
||||||
summary.AdjustDilutedPrice = decimal.NewNullDecimal(
|
report.Summary.AdjustDilutedPrice = decimal.NewNullDecimal(
|
||||||
summary.AdjustFee.Div(summary.CustomerConsumption.Decimal).RoundBank(8),
|
report.Summary.AdjustFee.Div(report.Summary.Customers.Consumption.Decimal).RoundBank(8),
|
||||||
)
|
)
|
||||||
summary.MaintenanceDilutedPrice = decimal.NewNullDecimal(
|
report.Summary.MaintenanceDilutedPrice = decimal.NewNullDecimal(
|
||||||
maintenanceFeeTotal.Div(summary.CustomerConsumption.Decimal).RoundBank(8),
|
maintenanceFeeTotal.Div(report.Summary.Customers.Consumption.Decimal).RoundBank(8),
|
||||||
)
|
|
||||||
summary.PublicConsumptionDilutedPrice = decimal.NewNullDecimal(
|
|
||||||
summary.PublicConsumptionFee.Decimal.Div(summary.CustomerConsumption.Decimal).RoundBank(8),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算摊薄总计
|
// 计算摊薄总计
|
||||||
summary.FinalDilutedOverall = decimal.NewNullDecimal(
|
report.Summary.MaintenanceOverall = decimal.NewNullDecimal(maintenanceFeeTotal)
|
||||||
summary.BasicFee.
|
report.Summary.FinalDilutedOverall = decimal.NewNullDecimal(
|
||||||
Add(summary.AdjustFee).
|
report.Summary.BasicFee.
|
||||||
Add(summary.PublicConsumptionFee.Decimal).
|
Add(report.Summary.AdjustFee).
|
||||||
Add(maintenanceFeeTotal).
|
Add(report.Summary.AuthorizeLossFee.Decimal),
|
||||||
Add(summary.LossFee.Decimal),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 计算终端用户的全部摊薄内容
|
// 计算终端用户的全部摊薄内容
|
||||||
for _, eu := range endUserDetails {
|
for _, eu := range report.EndUsers {
|
||||||
if eu.IsPublicMeter && eu.WillDilute {
|
// 计算户表表计的摊薄内容
|
||||||
// 计算需要摊薄的公共表计的摊薄内容
|
if report.Summary.Customers.Consumption.Decimal.Abs().GreaterThan(decimal.Zero) {
|
||||||
if summary.PublicConsumption.Decimal.Abs().GreaterThan(decimal.Zero) {
|
eu.OverallProportion = eu.Overall.Decimal.Div(report.Summary.Customers.Consumption.Decimal).RoundBank(15)
|
||||||
eu.OverallProportion = eu.Overall.Decimal.Div(summary.PublicConsumption.Decimal).RoundBank(15)
|
|
||||||
} else {
|
|
||||||
eu.OverallProportion = decimal.Zero
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// 计算户表表计的摊薄内容
|
eu.OverallProportion = decimal.Zero
|
||||||
if summary.CustomerConsumption.Decimal.Abs().GreaterThan(decimal.Zero) {
|
|
||||||
eu.OverallProportion = eu.Overall.Decimal.Div(summary.CustomerConsumption.Decimal).RoundBank(15)
|
|
||||||
} else {
|
|
||||||
eu.OverallProportion = decimal.Zero
|
|
||||||
}
|
|
||||||
eu.BasicFeeDiluted = decimal.NewNullDecimal(
|
|
||||||
eu.Overall.Decimal.Mul(summary.BasicDilutedPrice.Decimal).RoundBank(2),
|
|
||||||
)
|
|
||||||
eu.AdjustFeeDiluted = decimal.NewNullDecimal(
|
|
||||||
eu.Overall.Decimal.Mul(summary.AdjustDilutedPrice.Decimal).RoundBank(2),
|
|
||||||
)
|
|
||||||
eu.LossDiluted = decimal.NewNullDecimal(
|
|
||||||
summary.Loss.Decimal.Mul(eu.OverallProportion).RoundBank(8),
|
|
||||||
)
|
|
||||||
eu.LossDiluted = decimal.NewNullDecimal(
|
|
||||||
eu.Overall.Decimal.Mul(summary.LossDilutedPrice.Decimal).RoundBank(8),
|
|
||||||
)
|
|
||||||
eu.MaintenanceFeeDiluted = decimal.NewNullDecimal(
|
|
||||||
eu.Overall.Decimal.Mul(summary.MaintenanceDilutedPrice.Decimal).RoundBank(8),
|
|
||||||
)
|
|
||||||
eu.PublicConsumptionDiluted = decimal.NewNullDecimal(
|
|
||||||
eu.Overall.Decimal.Mul(summary.PublicConsumptionDilutedPrice.Decimal).RoundBank(8),
|
|
||||||
)
|
|
||||||
eu.FinalDiluted = decimal.NewNullDecimal(
|
|
||||||
eu.BasicFeeDiluted.Decimal.
|
|
||||||
Add(eu.AdjustFeeDiluted.Decimal).
|
|
||||||
Add(eu.LossFeeDiluted.Decimal).
|
|
||||||
Add(eu.MaintenanceFeeDiluted.Decimal).
|
|
||||||
Add(eu.PublicConsumptionDiluted.Decimal).
|
|
||||||
RoundBank(2),
|
|
||||||
)
|
|
||||||
eu.FinalCharge = decimal.NewNullDecimal(
|
|
||||||
eu.OverallFee.Decimal.Add(eu.FinalDiluted.Decimal).RoundBank(2),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
eu.BasicFeeDiluted = decimal.NewNullDecimal(
|
||||||
|
eu.Overall.Decimal.Mul(report.Summary.BasicDilutedPrice.Decimal).RoundBank(2),
|
||||||
|
)
|
||||||
|
eu.AdjustFeeDiluted = decimal.NewNullDecimal(
|
||||||
|
eu.Overall.Decimal.Mul(report.Summary.AdjustDilutedPrice.Decimal).RoundBank(2),
|
||||||
|
)
|
||||||
|
eu.LossDiluted = decimal.NewNullDecimal(
|
||||||
|
report.Summary.AuthorizeLoss.Decimal.Mul(eu.OverallProportion).RoundBank(8),
|
||||||
|
)
|
||||||
|
eu.LossFeeDiluted = decimal.NewNullDecimal(
|
||||||
|
eu.Overall.Decimal.Mul(report.Summary.LossDilutedPrice.Decimal).RoundBank(8),
|
||||||
|
)
|
||||||
|
eu.FinalDiluted = decimal.NewNullDecimal(
|
||||||
|
eu.BasicFeeDiluted.Decimal.
|
||||||
|
Add(eu.AdjustFeeDiluted.Decimal).
|
||||||
|
Add(eu.LossFeeDiluted.Decimal).
|
||||||
|
RoundBank(2),
|
||||||
|
)
|
||||||
|
eu.FinalCharge = decimal.NewNullDecimal(
|
||||||
|
eu.OverallFee.Decimal.Add(eu.FinalDiluted.Decimal).RoundBank(2),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 向数据库保存报表概况以及终端用户摊薄结果
|
// 向数据库保存报表概况以及终端用户摊薄结果
|
||||||
tx := global.DBConn.NewSession()
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
if err = tx.Begin(); err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer tx.Close()
|
|
||||||
|
|
||||||
_, err = tx.ID(reportId).Update(summary)
|
_, err = tx.NewUpdate().Model(report.Summary).WherePK().Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, eu := range endUserDetails {
|
for _, eu := range report.EndUsers {
|
||||||
_, err = tx.ID(schemas.NewPK(eu.ReportId, eu.ParkId, eu.MeterId)).Update(eu)
|
_, err = tx.NewUpdate().Model(eu).WherePK().Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return
|
return
|
||||||
@@ -243,6 +257,6 @@ func (_CalculateService) ComprehensivelyCalculateReport(reportId string) (err er
|
|||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cache.AbolishRelation(fmt.Sprintf("publicity_%s", reportId))
|
cache.AbolishRelation(fmt.Sprintf("publicity:%s", reportId))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+118
-94
@@ -1,10 +1,13 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
"electricity_bill_calc/cache"
|
"electricity_bill_calc/cache"
|
||||||
"electricity_bill_calc/config"
|
"electricity_bill_calc/config"
|
||||||
"electricity_bill_calc/exceptions"
|
"electricity_bill_calc/exceptions"
|
||||||
"electricity_bill_calc/global"
|
"electricity_bill_calc/global"
|
||||||
|
"electricity_bill_calc/logger"
|
||||||
"electricity_bill_calc/model"
|
"electricity_bill_calc/model"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -12,28 +15,32 @@ import (
|
|||||||
|
|
||||||
"github.com/fufuok/utils"
|
"github.com/fufuok/utils"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"xorm.io/builder"
|
"github.com/uptrace/bun"
|
||||||
"xorm.io/xorm"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type _ChargeService struct{}
|
type _ChargeService struct {
|
||||||
|
l *zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
var ChargeService _ChargeService
|
var ChargeService = _ChargeService{
|
||||||
|
l: logger.Named("Service", "Charge"),
|
||||||
|
}
|
||||||
|
|
||||||
func (c _ChargeService) CreateChargeRecord(charge *model.UserCharge, extendWithIgnoreSettle bool) error {
|
func (c _ChargeService) CreateChargeRecord(charge *model.UserCharge, extendWithIgnoreSettle bool) error {
|
||||||
tx := global.DBConn.NewSession()
|
ctx, cancel := global.TimeoutContext()
|
||||||
defer tx.Close()
|
defer cancel()
|
||||||
if err := tx.Begin(); err != nil {
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
charge.Seq = 0
|
_, err = tx.NewInsert().Model(charge).Exec(ctx)
|
||||||
_, err := tx.Insert(charge)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if extendWithIgnoreSettle {
|
if extendWithIgnoreSettle {
|
||||||
err := c.updateUserExpiration(tx, charge.UserId, charge.ChargeTo)
|
err := c.updateUserExpiration(&tx, ctx, charge.UserId, charge.ChargeTo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -48,26 +55,35 @@ func (c _ChargeService) CreateChargeRecord(charge *model.UserCharge, extendWithI
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c _ChargeService) SettleCharge(seq int64, uid string) error {
|
func (c _ChargeService) SettleCharge(seq int64, uid string) error {
|
||||||
var record *model.UserCharge
|
ctx, cancel := global.TimeoutContext()
|
||||||
has, err := global.DBConn.Where(builder.Eq{"seq": seq, "user_id": uid}).NoAutoCondition().Get(record)
|
defer cancel()
|
||||||
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var record = new(model.UserCharge)
|
||||||
|
err = tx.NewSelect().Model(&record).
|
||||||
|
Where("seq = ?", seq).
|
||||||
|
Where("user_id = ?", uid).
|
||||||
|
Scan(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if !has {
|
if record == nil {
|
||||||
return exceptions.NewNotFoundError("未找到匹配指定条件的计费记录。")
|
return exceptions.NewNotFoundError("未找到匹配指定条件的计费记录。")
|
||||||
}
|
}
|
||||||
tx := global.DBConn.NewSession()
|
|
||||||
defer tx.Close()
|
|
||||||
if err := tx.Begin(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
_, err = tx.Table(new(model.UserCharge)).Where(builder.Eq{"seq": seq, "user_id": uid}).Cols("settled", "settled_at").Update(&model.UserCharge{Settled: true, SettledAt: ¤tTime})
|
_, err = tx.NewUpdate().Model((*model.UserCharge)(nil)).
|
||||||
|
Where("seq = ?", seq).
|
||||||
|
Where("user_id = ?", uid).
|
||||||
|
Set("settled = ?", true).
|
||||||
|
Set("settled_at = ?", currentTime).
|
||||||
|
Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = c.updateUserExpiration(tx, uid, record.ChargeTo)
|
err = c.updateUserExpiration(&tx, ctx, uid, record.ChargeTo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -76,33 +92,38 @@ func (c _ChargeService) SettleCharge(seq int64, uid string) error {
|
|||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("charge")
|
cache.AbolishRelation(fmt.Sprintf("charge:%s:%d", uid, seq))
|
||||||
cache.AbolishRelation(fmt.Sprintf("charge_%s_%d", uid, seq))
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c _ChargeService) RefundCharge(seq int64, uid string) error {
|
func (c _ChargeService) RefundCharge(seq int64, uid string) error {
|
||||||
tx := global.DBConn.NewSession()
|
ctx, cancel := global.TimeoutContext()
|
||||||
defer tx.Close()
|
defer cancel()
|
||||||
if err := tx.Begin(); err != nil {
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
rows, err := tx.Table(new(model.UserCharge)).Where(builder.Eq{"seq": seq, "user_id": uid}).Cols("refunded", "refunded_at").Update(&model.UserCharge{Refunded: true, RefundedAt: ¤tTime})
|
res, err := tx.NewUpdate().Model((*model.UserCharge)(nil)).
|
||||||
|
Where("seq = ?", seq).
|
||||||
|
Where("user_id = ?", uid).
|
||||||
|
Set("refunded = ?", true).
|
||||||
|
Set("refunded_at = ?", currentTime).
|
||||||
|
Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if rows == 0 {
|
if rows, _ := res.RowsAffected(); rows == 0 {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return exceptions.NewNotFoundError("未找到匹配指定条件的计费记录。")
|
return exceptions.NewNotFoundError("未找到匹配指定条件的计费记录。")
|
||||||
}
|
}
|
||||||
lastValidExpriation, err := c.lastValidChargeTo(uid)
|
lastValidExpriation, err := c.lastValidChargeTo(&tx, &ctx, uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return exceptions.NewNotFoundError("未找到最后合法的计费时间。")
|
return exceptions.NewNotFoundError("未找到最后合法的计费时间。")
|
||||||
}
|
}
|
||||||
err = c.updateUserExpiration(tx, uid, lastValidExpriation)
|
err = c.updateUserExpiration(&tx, ctx, uid, lastValidExpriation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -111,24 +132,29 @@ func (c _ChargeService) RefundCharge(seq int64, uid string) error {
|
|||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("charge")
|
cache.AbolishRelation(fmt.Sprintf("charge:%s:%d", uid, seq))
|
||||||
cache.AbolishRelation(fmt.Sprintf("charge_%s_%d", uid, seq))
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c _ChargeService) CancelCharge(seq int64, uid string) error {
|
func (c _ChargeService) CancelCharge(seq int64, uid string) error {
|
||||||
tx := global.DBConn.NewSession()
|
ctx, cancel := global.TimeoutContext()
|
||||||
defer tx.Close()
|
defer cancel()
|
||||||
if err := tx.Begin(); err != nil {
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
rows, err := tx.Table(new(model.UserCharge)).Where(builder.Eq{"seq": seq, "user_id": uid}).Cols("cancelled", "cancelled_at").Update(&model.UserCharge{Cancelled: true, CancelledAt: ¤tTime})
|
res, err := tx.NewUpdate().Model((*model.UserCharge)(nil)).
|
||||||
|
Where("seq = ?", seq).
|
||||||
|
Where("user_id = ?", uid).
|
||||||
|
Set("cancelled = ?", true).
|
||||||
|
Set("cancelled_at = ?", currentTime).
|
||||||
|
Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if rows == 0 {
|
if rows, _ := res.RowsAffected(); rows == 0 {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return exceptions.NewNotFoundError("未找到匹配指定条件的计费记录。")
|
return exceptions.NewNotFoundError("未找到匹配指定条件的计费记录。")
|
||||||
}
|
}
|
||||||
@@ -137,16 +163,15 @@ func (c _ChargeService) CancelCharge(seq int64, uid string) error {
|
|||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tx = global.DBConn.NewSession()
|
tx, err = global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
defer tx.Close()
|
if err != nil {
|
||||||
if err := tx.Begin(); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
lastValidExpriation, err := c.lastValidChargeTo(uid)
|
lastValidExpriation, err := c.lastValidChargeTo(&tx, &ctx, uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return exceptions.NewNotFoundError("未找到最后合法的计费时间。")
|
return exceptions.NewNotFoundError("未找到最后合法的计费时间。")
|
||||||
}
|
}
|
||||||
err = c.updateUserExpiration(tx, uid, lastValidExpriation)
|
err = c.updateUserExpiration(&tx, ctx, uid, lastValidExpriation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -156,30 +181,38 @@ func (c _ChargeService) CancelCharge(seq int64, uid string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("user")
|
cache.AbolishRelation("user")
|
||||||
cache.AbolishRelation(fmt.Sprintf("user_%s", uid))
|
cache.AbolishRelation(fmt.Sprintf("user:%s", uid))
|
||||||
cache.AbolishRelation("charge")
|
cache.AbolishRelation("charge")
|
||||||
cache.AbolishRelation(fmt.Sprintf("charge_%s_%d", uid, seq))
|
cache.AbolishRelation(fmt.Sprintf("charge:%s:%d", uid, seq))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ChargeService) updateUserExpiration(tx *xorm.Session, uid string, expiration time.Time) error {
|
func (ch _ChargeService) updateUserExpiration(tx *bun.Tx, ctx context.Context, uid string, expiration model.Date) error {
|
||||||
_, err := tx.ID(uid).Cols("service_expiration").Update(&model.UserDetail{ServiceExpiration: expiration})
|
_, err := tx.NewUpdate().Model((*model.UserDetail)(nil)).
|
||||||
|
Set("service_expiration = ?", expiration).
|
||||||
|
Where("id = ?", uid).
|
||||||
|
Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("user")
|
cache.AbolishRelation(fmt.Sprintf("user:%s", uid))
|
||||||
cache.AbolishRelation(fmt.Sprintf("user_%s", uid))
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ChargeService) ListPagedChargeRecord(keyword, beginDate, endDate string, page int) ([]model.ChargeWithName, int64, error) {
|
func (_ChargeService) ListPagedChargeRecord(keyword, beginDate, endDate string, page int) ([]model.ChargeWithName, int64, error) {
|
||||||
var (
|
var (
|
||||||
cond = builder.NewCond()
|
cond = global.DB.NewSelect()
|
||||||
condition = make([]string, 0)
|
condition = make([]string, 0)
|
||||||
|
charges = make([]model.UserCharge, 0)
|
||||||
)
|
)
|
||||||
|
cond = cond.Model(&charges).Relation("Detail")
|
||||||
condition = append(condition, strconv.Itoa(page))
|
condition = append(condition, strconv.Itoa(page))
|
||||||
if len(keyword) != 0 {
|
if len(keyword) != 0 {
|
||||||
cond = cond.And(builder.Like{"d.name", keyword}.Or(builder.Like{"d.abbr", keyword}))
|
keywordCond := "%" + keyword + "%"
|
||||||
|
cond = cond.WhereGroup(" and ", func(q *bun.SelectQuery) *bun.SelectQuery {
|
||||||
|
return q.Where("detail.name like ?", keywordCond).
|
||||||
|
WhereOr("detail.abbr like ?", keywordCond)
|
||||||
|
})
|
||||||
condition = append(condition, keyword)
|
condition = append(condition, keyword)
|
||||||
}
|
}
|
||||||
if len(beginDate) != 0 {
|
if len(beginDate) != 0 {
|
||||||
@@ -188,7 +221,7 @@ func (_ChargeService) ListPagedChargeRecord(keyword, beginDate, endDate string,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return make([]model.ChargeWithName, 0), 0, err
|
return make([]model.ChargeWithName, 0), 0, err
|
||||||
}
|
}
|
||||||
cond = cond.And(builder.Gte{"c.created_at": beginTime})
|
cond = cond.Where("c.created_at >= ?", beginTime)
|
||||||
condition = append(condition, strconv.FormatInt(beginTime.Unix(), 10))
|
condition = append(condition, strconv.FormatInt(beginTime.Unix(), 10))
|
||||||
}
|
}
|
||||||
if len(endDate) != 0 {
|
if len(endDate) != 0 {
|
||||||
@@ -197,64 +230,55 @@ func (_ChargeService) ListPagedChargeRecord(keyword, beginDate, endDate string,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return make([]model.ChargeWithName, 0), 0, err
|
return make([]model.ChargeWithName, 0), 0, err
|
||||||
}
|
}
|
||||||
cond = cond.And(builder.Lte{"c.created_at": endTime})
|
cond = cond.Where("c.created_at <= ?", endTime)
|
||||||
condition = append(condition, strconv.FormatInt(endTime.Unix(), 10))
|
condition = append(condition, strconv.FormatInt(endTime.Unix(), 10))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cachedTotal, err := cache.RetreiveCount("charge_with_name", condition...); cachedTotal != -1 && err == nil {
|
||||||
|
if cachedCharges, _ := cache.RetreiveSearch[[]model.ChargeWithName]("charge_with_name", condition...); cachedCharges != nil {
|
||||||
|
return *cachedCharges, cachedTotal, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
startItem := (page - 1) * config.ServiceSettings.ItemsPageSize
|
startItem := (page - 1) * config.ServiceSettings.ItemsPageSize
|
||||||
var (
|
var (
|
||||||
total int64
|
total int
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
if cachedTotal, _ := cache.RetreiveCount("charge_with_name", condition...); cachedTotal != -1 {
|
ctx, cancel := global.TimeoutContext()
|
||||||
total = cachedTotal
|
defer cancel()
|
||||||
} else {
|
total, err = cond.Limit(config.ServiceSettings.ItemsPageSize).Offset(startItem).ScanAndCount(ctx)
|
||||||
total, err = global.DBConn.
|
|
||||||
Alias("d").
|
relations := []string{"charge"}
|
||||||
Join("INNER", []string{"user_charge", "c"}, "c.user_id=d.id").
|
chargesWithName := make([]model.ChargeWithName, 0)
|
||||||
Where(cond).
|
for _, c := range charges {
|
||||||
NoAutoCondition().
|
chargesWithName = append(chargesWithName, model.ChargeWithName{
|
||||||
Count(&model.ChargeWithName{})
|
UserCharge: c,
|
||||||
if err != nil {
|
UserDetail: *c.Detail,
|
||||||
return nil, -1, err
|
})
|
||||||
}
|
relations = append(relations, fmt.Sprintf("charge:%s:%d", c.UserId, c.Seq))
|
||||||
cache.CacheCount([]string{"charge"}, "charge_with_name", total, condition...)
|
|
||||||
}
|
}
|
||||||
charges := make([]model.ChargeWithName, 0)
|
|
||||||
if cachedCharges, _ := cache.RetreiveSearch[[]model.ChargeWithName]("charge_with_name", condition...); cachedCharges != nil {
|
cache.CacheCount(relations, "charge_with_name", int64(total), condition...)
|
||||||
return *cachedCharges, total, nil
|
cache.CacheSearch(chargesWithName, relations, "charge_with_name", condition...)
|
||||||
}
|
return chargesWithName, int64(total), err
|
||||||
err = global.DBConn.
|
|
||||||
Alias("d").
|
|
||||||
Join("INNER", []string{"user_charge", "c"}, "c.user_id=d.id").
|
|
||||||
Where(cond).
|
|
||||||
Limit(config.ServiceSettings.ItemsPageSize, startItem).
|
|
||||||
NoAutoCondition().
|
|
||||||
Find(&charges)
|
|
||||||
cache.CacheSearch(charges, []string{"charge"}, "charge_with_name", condition...)
|
|
||||||
return charges, total, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ChargeService) lastValidChargeTo(uid string) (time.Time, error) {
|
func (_ChargeService) lastValidChargeTo(tx *bun.Tx, ctx *context.Context, uid string) (model.Date, error) {
|
||||||
veryBlankTime, _ := time.Parse("2006-01-02 15:04:05", "0001-01-01 00:00:00")
|
var records []model.Date
|
||||||
var records []string
|
err := tx.NewSelect().Table("user_charge").
|
||||||
err := global.DBConn.
|
Where("settled = ? and cancelled = ? and refunded = ? and user_id = ?", true, false, false, uid).
|
||||||
Table(&model.UserCharge{}).
|
Column("charge_to").
|
||||||
Where(builder.Eq{"settled": true, "cancelled": false, "refunded": false, "user_id": uid}).
|
Scan(*ctx, &records)
|
||||||
Cols("charge_to").
|
|
||||||
Find(&records)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return veryBlankTime, nil
|
return model.NewEmptyDate(), nil
|
||||||
}
|
}
|
||||||
mappedRecords := lo.Map(records, func(elem string, index int) time.Time {
|
lastValid := lo.Reduce(records, func(acc, elem model.Date, index int) model.Date {
|
||||||
t, _ := time.Parse(time.RFC3339, elem)
|
if elem.Time.After(acc.Time) {
|
||||||
return utils.BeginOfDay(t)
|
|
||||||
})
|
|
||||||
lastValid := lo.Reduce(mappedRecords, func(acc, elem time.Time, index int) time.Time {
|
|
||||||
if elem.After(acc) {
|
|
||||||
return elem
|
return elem
|
||||||
} else {
|
} else {
|
||||||
return acc
|
return acc
|
||||||
}
|
}
|
||||||
}, veryBlankTime)
|
}, model.NewEmptyDate())
|
||||||
return lastValid, nil
|
return lastValid, nil
|
||||||
}
|
}
|
||||||
|
|||||||
+303
-77
@@ -1,80 +1,99 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
"electricity_bill_calc/cache"
|
"electricity_bill_calc/cache"
|
||||||
"electricity_bill_calc/config"
|
"electricity_bill_calc/config"
|
||||||
"electricity_bill_calc/excel"
|
"electricity_bill_calc/excel"
|
||||||
"electricity_bill_calc/exceptions"
|
"electricity_bill_calc/exceptions"
|
||||||
"electricity_bill_calc/global"
|
"electricity_bill_calc/global"
|
||||||
|
"electricity_bill_calc/logger"
|
||||||
"electricity_bill_calc/model"
|
"electricity_bill_calc/model"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
mapset "github.com/deckarep/golang-set/v2"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
"xorm.io/builder"
|
"github.com/uptrace/bun"
|
||||||
"xorm.io/xorm"
|
"go.uber.org/zap"
|
||||||
"xorm.io/xorm/schemas"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type _EndUserService struct{}
|
type _EndUserService struct {
|
||||||
|
l *zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
var EndUserService _EndUserService
|
type MeterAppears struct {
|
||||||
|
Meter string
|
||||||
|
Appears int64
|
||||||
|
}
|
||||||
|
|
||||||
|
var EndUserService = _EndUserService{
|
||||||
|
l: logger.Named("Service", "EndUser"),
|
||||||
|
}
|
||||||
|
|
||||||
func (_EndUserService) SearchEndUserRecord(reportId, keyword string, page int) ([]model.EndUserDetail, int64, error) {
|
func (_EndUserService) SearchEndUserRecord(reportId, keyword string, page int) ([]model.EndUserDetail, int64, error) {
|
||||||
var conditions = make([]string, 0)
|
var (
|
||||||
|
conditions = make([]string, 0)
|
||||||
|
endUsers = make([]model.EndUserDetail, 0)
|
||||||
|
cond = global.DB.NewSelect().Model(&endUsers)
|
||||||
|
)
|
||||||
conditions = append(conditions, reportId, strconv.Itoa(page))
|
conditions = append(conditions, reportId, strconv.Itoa(page))
|
||||||
cond := builder.NewCond().And(builder.Eq{"report_id": reportId})
|
cond = cond.Where("report_id = ?", reportId)
|
||||||
if len(keyword) > 0 {
|
if len(keyword) > 0 {
|
||||||
cond = cond.And(
|
keywordCond := "%" + keyword + "%"
|
||||||
builder.Like{"customer_name", keyword}.
|
cond = cond.WhereGroup(" and ", func(q *bun.SelectQuery) *bun.SelectQuery {
|
||||||
Or(builder.Like{"contact_name", keyword}).
|
return q.Where("customer_name like ?", keywordCond).
|
||||||
Or(builder.Like{"contact_phone", keyword}).
|
WhereOr("contact_name like ?", keywordCond).
|
||||||
Or(builder.Like{"meter_04kv_id", keyword}),
|
WhereOr("contact_phone like ?", keywordCond).
|
||||||
)
|
WhereOr("meter_04kv_id like ?", keywordCond)
|
||||||
|
})
|
||||||
conditions = append(conditions, keyword)
|
conditions = append(conditions, keyword)
|
||||||
}
|
}
|
||||||
var (
|
if cachedTotal, err := cache.RetreiveCount("end_user_detail", conditions...); cachedTotal != -1 && err == nil {
|
||||||
total int64
|
if cachedEndUsers, _ := cache.RetreiveSearch[[]model.EndUserDetail]("end_user_detail", conditions...); cachedEndUsers != nil {
|
||||||
err error
|
return *cachedEndUsers, cachedTotal, nil
|
||||||
)
|
|
||||||
if cachedTotal, _ := cache.RetreiveCount("end_user_detail", conditions...); cachedTotal != -1 {
|
|
||||||
total = cachedTotal
|
|
||||||
} else {
|
|
||||||
total, err = global.DBConn.
|
|
||||||
Table(&model.EndUserDetail{}).
|
|
||||||
Where(cond).
|
|
||||||
Count()
|
|
||||||
if err != nil {
|
|
||||||
return make([]model.EndUserDetail, 0), -1, err
|
|
||||||
}
|
}
|
||||||
cache.CacheCount([]string{"end_user", "report", "park"}, "end_user_detail", total, conditions...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
startItem := (page - 1) * config.ServiceSettings.ItemsPageSize
|
startItem := (page - 1) * config.ServiceSettings.ItemsPageSize
|
||||||
if cachedEndUsers, _ := cache.RetreiveSearch[[]model.EndUserDetail]("end_user_detail", conditions...); cachedEndUsers != nil {
|
total, err := cond.Limit(config.ServiceSettings.ItemsPageSize).
|
||||||
return *cachedEndUsers, total, nil
|
Offset(startItem).
|
||||||
|
Order("seq asc", "meter_04kv_id asc").
|
||||||
|
ScanAndCount(ctx)
|
||||||
|
|
||||||
|
relations := []string{"end_user", "report", "park"}
|
||||||
|
for _, eu := range endUsers {
|
||||||
|
relations = append(relations, fmt.Sprintf("end_user:%s:%s", eu.ReportId, eu.MeterId))
|
||||||
}
|
}
|
||||||
endUsers := make([]model.EndUserDetail, 0)
|
cache.CacheCount(relations, "end_user_detail", int64(total), conditions...)
|
||||||
err = global.DBConn.
|
cache.CacheSearch(endUsers, relations, "end_user_detail", conditions...)
|
||||||
Where(cond).
|
return endUsers, int64(total), err
|
||||||
Limit(config.ServiceSettings.ItemsPageSize, startItem).
|
|
||||||
Asc("seq").
|
|
||||||
Find(&endUsers)
|
|
||||||
cache.CacheSearch(endUsers, []string{"end_user", "report", "park"}, "end_user_detail", conditions...)
|
|
||||||
return endUsers, total, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_EndUserService) AllEndUserRecord(reportId string) ([]model.EndUserDetail, error) {
|
func (_EndUserService) AllEndUserRecord(reportId string) ([]model.EndUserDetail, error) {
|
||||||
if cachedEndUsers, _ := cache.RetreiveSearch[[]model.EndUserDetail]("end_user_detail", "report", reportId); cachedEndUsers != nil {
|
if cachedEndUsers, _ := cache.RetreiveSearch[[]model.EndUserDetail]("end_user_detail", "report", reportId); cachedEndUsers != nil {
|
||||||
return *cachedEndUsers, nil
|
return *cachedEndUsers, nil
|
||||||
}
|
}
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
users := make([]model.EndUserDetail, 0)
|
users := make([]model.EndUserDetail, 0)
|
||||||
err := global.DBConn.
|
err := global.DB.NewSelect().Model(&users).
|
||||||
Where(builder.Eq{"report_id": reportId}).
|
Where("report_id = ?", reportId).
|
||||||
Asc("seq").
|
Order("seq asc", "meter_04kv_id asc").
|
||||||
Find(&users)
|
Scan(ctx)
|
||||||
cache.CacheSearch(users, []string{"end_user_detail", "report", "park"}, "end_user_detail", "report", reportId)
|
relations := lo.Map(users, func(eu model.EndUserDetail, _ int) string {
|
||||||
|
return fmt.Sprintf("end_user:%s:%s", eu.ReportId, eu.MeterId)
|
||||||
|
})
|
||||||
|
relations = append(relations, "report", "park")
|
||||||
|
cache.CacheSearch(users, relations, "end_user_detail", "report", reportId)
|
||||||
return users, err
|
return users, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,37 +101,53 @@ func (_EndUserService) FetchSpecificEndUserRecord(reportId, parkId, meterId stri
|
|||||||
if cachedEndUser, _ := cache.RetreiveEntity[model.EndUserDetail]("end_user_detail", fmt.Sprintf("%s_%s_%s", reportId, parkId, meterId)); cachedEndUser != nil {
|
if cachedEndUser, _ := cache.RetreiveEntity[model.EndUserDetail]("end_user_detail", fmt.Sprintf("%s_%s_%s", reportId, parkId, meterId)); cachedEndUser != nil {
|
||||||
return cachedEndUser, nil
|
return cachedEndUser, nil
|
||||||
}
|
}
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
record := new(model.EndUserDetail)
|
record := new(model.EndUserDetail)
|
||||||
_, err := global.DBConn.
|
err := global.DB.NewSelect().Model(record).
|
||||||
ID(schemas.NewPK(reportId, parkId, meterId)).
|
Where("report_id = ?", reportId).
|
||||||
NoAutoCondition().
|
Where("park_id = ?", parkId).
|
||||||
Get(record)
|
Where("meter_04kv_id = ?", meterId).
|
||||||
cache.CacheEntity(record, []string{"end_user_detail", "report", "park"}, "end_user_detail", fmt.Sprintf("%s_%s_%s", reportId, parkId, meterId))
|
Scan(ctx)
|
||||||
|
cache.CacheEntity(record, []string{fmt.Sprintf("end_user:%s:%s", reportId, meterId), "report", "park"}, "end_user_detail", fmt.Sprintf("%s_%s_%s", reportId, parkId, meterId))
|
||||||
return record, err
|
return record, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_EndUserService) UpdateEndUserRegisterRecord(tx *xorm.Session, record model.EndUserDetail) (err error) {
|
func (_EndUserService) UpdateEndUserRegisterRecord(tx *bun.Tx, ctx *context.Context, record model.EndUserDetail) (err error) {
|
||||||
record.CalculatePeriod()
|
record.CalculatePeriod()
|
||||||
_, err = tx.ID(schemas.NewPK(record.ReportId, record.ParkId, record.MeterId)).
|
updateColumns := []string{
|
||||||
Cols(
|
"current_period_overall",
|
||||||
"current_period_overall",
|
"adjust_overall",
|
||||||
"adjust_overall",
|
"current_period_critical",
|
||||||
"current_period_critical",
|
"current_period_peak",
|
||||||
"current_period_peak",
|
"current_period_flat",
|
||||||
"current_period_flat",
|
"current_period_valley",
|
||||||
"current_perios_valley",
|
"adjust_critical",
|
||||||
"adjust_critical",
|
"adjust_peak",
|
||||||
"adjust_peak",
|
"adjust_flat",
|
||||||
"adjust_flat",
|
"adjust_valley",
|
||||||
"adjust_valley",
|
"overall",
|
||||||
"overall",
|
"critical",
|
||||||
"critical",
|
"peak",
|
||||||
"peak",
|
"flat",
|
||||||
"flat",
|
"valley",
|
||||||
"valley",
|
}
|
||||||
).
|
if record.Initialize {
|
||||||
Update(record)
|
updateColumns = append(updateColumns,
|
||||||
cache.AbolishRelation("end_user_detail")
|
"last_period_overall",
|
||||||
|
"last_period_critical",
|
||||||
|
"last_period_peak",
|
||||||
|
"last_period_flat",
|
||||||
|
"last_period_valley",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = tx.NewUpdate().Model(&record).
|
||||||
|
WherePK().
|
||||||
|
Column(updateColumns...).
|
||||||
|
Exec(*ctx)
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("end_user:%s:%s", record.ReportId, record.MeterId))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,12 +156,34 @@ func (_EndUserService) newVirtualExcelAnalysisError(err error) *excel.ExcelAnaly
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (es _EndUserService) BatchImportNonPVRegister(reportId string, file io.Reader) *exceptions.BatchError {
|
func (es _EndUserService) BatchImportNonPVRegister(reportId string, file io.Reader) *exceptions.BatchError {
|
||||||
|
ctx, cancel := global.TimeoutContext(120)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
errs := exceptions.NewBatchError()
|
errs := exceptions.NewBatchError()
|
||||||
users, err := es.AllEndUserRecord(reportId)
|
users, err := es.AllEndUserRecord(reportId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs.AddError(es.newVirtualExcelAnalysisError(err))
|
errs.AddError(es.newVirtualExcelAnalysisError(err))
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
var reportDetail = new(model.Report)
|
||||||
|
err = global.DB.NewSelect().Model(reportDetail).
|
||||||
|
Where("id = ?", reportId).
|
||||||
|
Scan(ctx)
|
||||||
|
if err != nil {
|
||||||
|
errs.AddError(es.newVirtualExcelAnalysisError(fmt.Errorf("未能找到相应的报表。%w", err)))
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
meterAppers := make([]MeterAppears, 0)
|
||||||
|
err = global.DB.NewSelect().Model((*model.EndUserDetail)(nil)).
|
||||||
|
ColumnExpr("meter_04kv_id as meter").
|
||||||
|
ColumnExpr("count(*) as appears").
|
||||||
|
Where("park_id = ?", reportDetail.ParkId).
|
||||||
|
Group("meter_04kv_id").
|
||||||
|
Scan(ctx, &meterAppers)
|
||||||
|
if err != nil {
|
||||||
|
errs.AddError(es.newVirtualExcelAnalysisError(err))
|
||||||
|
return errs
|
||||||
|
}
|
||||||
indexedUsers := lo.Reduce(
|
indexedUsers := lo.Reduce(
|
||||||
users,
|
users,
|
||||||
func(acc map[string]model.EndUserDetail, elem model.EndUserDetail, index int) map[string]model.EndUserDetail {
|
func(acc map[string]model.EndUserDetail, elem model.EndUserDetail, index int) map[string]model.EndUserDetail {
|
||||||
@@ -147,24 +204,37 @@ func (es _EndUserService) BatchImportNonPVRegister(reportId string, file io.Read
|
|||||||
}
|
}
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
tx := global.DBConn.NewSession()
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
if err = tx.Begin(); err != nil {
|
if err != nil {
|
||||||
errs.AddError(es.newVirtualExcelAnalysisError(err))
|
errs.AddError(es.newVirtualExcelAnalysisError(err))
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
defer tx.Close()
|
|
||||||
|
|
||||||
for _, im := range imports {
|
for _, im := range imports {
|
||||||
if elem, ok := indexedUsers[im.MeterId]; ok {
|
if elem, ok := indexedUsers[im.MeterId]; ok {
|
||||||
|
if appears, has := lo.Find(meterAppers, func(m MeterAppears) bool {
|
||||||
|
return m.Meter == elem.MeterId
|
||||||
|
}); has {
|
||||||
|
if appears.Appears <= 1 {
|
||||||
|
elem.LastPeriodOverall = im.LastPeriodOverall
|
||||||
|
elem.LastPeriodCritical = decimal.Zero
|
||||||
|
elem.LastPeriodPeak = decimal.Zero
|
||||||
|
elem.LastPeriodValley = decimal.Zero
|
||||||
|
elem.LastPeriodFlat = elem.LastPeriodOverall.Sub(elem.LastPeriodCritical).Sub(elem.LastPeriodPeak).Sub(elem.LastPeriodValley)
|
||||||
|
elem.Initialize = true
|
||||||
|
}
|
||||||
|
}
|
||||||
elem.CurrentPeriodOverall = im.CurrentPeriodOverall
|
elem.CurrentPeriodOverall = im.CurrentPeriodOverall
|
||||||
elem.AdjustOverall = im.AdjustOverall
|
elem.AdjustOverall = im.AdjustOverall
|
||||||
elem.CurrentPeriodCritical = decimal.Zero
|
elem.CurrentPeriodCritical = decimal.Zero
|
||||||
elem.CurrentPeriodPeak = decimal.Zero
|
elem.CurrentPeriodPeak = decimal.Zero
|
||||||
elem.CurrentPeriodValley = decimal.Zero
|
elem.CurrentPeriodValley = decimal.Zero
|
||||||
|
elem.CurrentPeriodFlat = elem.CurrentPeriodOverall.Sub(elem.CurrentPeriodCritical).Sub(elem.CurrentPeriodPeak).Sub(elem.CurrentPeriodValley)
|
||||||
elem.AdjustCritical = decimal.Zero
|
elem.AdjustCritical = decimal.Zero
|
||||||
elem.AdjustPeak = decimal.Zero
|
elem.AdjustPeak = decimal.Zero
|
||||||
elem.AdjustValley = decimal.Zero
|
elem.AdjustValley = decimal.Zero
|
||||||
err := es.UpdateEndUserRegisterRecord(tx, elem)
|
elem.AdjustFlat = elem.AdjustOverall.Sub(elem.AdjustCritical).Sub(elem.AdjustPeak).Sub(elem.AdjustValley)
|
||||||
|
err := es.UpdateEndUserRegisterRecord(&tx, &ctx, elem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs.AddError(es.newVirtualExcelAnalysisError(err))
|
errs.AddError(es.newVirtualExcelAnalysisError(err))
|
||||||
}
|
}
|
||||||
@@ -187,12 +257,32 @@ func (es _EndUserService) BatchImportNonPVRegister(reportId string, file io.Read
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (es _EndUserService) BatchImportPVRegister(reportId string, file io.Reader) *exceptions.BatchError {
|
func (es _EndUserService) BatchImportPVRegister(reportId string, file io.Reader) *exceptions.BatchError {
|
||||||
|
ctx, cancel := global.TimeoutContext(120)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
errs := exceptions.NewBatchError()
|
errs := exceptions.NewBatchError()
|
||||||
users, err := es.AllEndUserRecord(reportId)
|
users, err := es.AllEndUserRecord(reportId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs.AddError(es.newVirtualExcelAnalysisError(err))
|
errs.AddError(es.newVirtualExcelAnalysisError(err))
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
var reportDetail = new(model.Report)
|
||||||
|
err = global.DB.NewSelect().Model(reportDetail).Where("id = ?", reportId).Scan(ctx)
|
||||||
|
if err != nil {
|
||||||
|
errs.AddError(es.newVirtualExcelAnalysisError(fmt.Errorf("未能找到相应的报表。%w", err)))
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
meterAppers := make([]MeterAppears, 0)
|
||||||
|
err = global.DB.NewSelect().Model((*model.EndUserDetail)(nil)).
|
||||||
|
ColumnExpr("meter_04kv_id as meter").
|
||||||
|
ColumnExpr("count(*) as appears").
|
||||||
|
Where("park_id = ?", reportDetail.Id).
|
||||||
|
Group("meter_04kv_id").
|
||||||
|
Scan(ctx, &meterAppers)
|
||||||
|
if err != nil {
|
||||||
|
errs.AddError(es.newVirtualExcelAnalysisError(err))
|
||||||
|
return errs
|
||||||
|
}
|
||||||
indexedUsers := lo.Reduce(
|
indexedUsers := lo.Reduce(
|
||||||
users,
|
users,
|
||||||
func(acc map[string]model.EndUserDetail, elem model.EndUserDetail, index int) map[string]model.EndUserDetail {
|
func(acc map[string]model.EndUserDetail, elem model.EndUserDetail, index int) map[string]model.EndUserDetail {
|
||||||
@@ -201,7 +291,7 @@ func (es _EndUserService) BatchImportPVRegister(reportId string, file io.Reader)
|
|||||||
},
|
},
|
||||||
make(map[string]model.EndUserDetail, 0),
|
make(map[string]model.EndUserDetail, 0),
|
||||||
)
|
)
|
||||||
analyzer, err := excel.NewEndUserNonPVExcelAnalyzer(file)
|
analyzer, err := excel.NewEndUserPVExcelAnalyzer(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs.AddError(es.newVirtualExcelAnalysisError(err))
|
errs.AddError(es.newVirtualExcelAnalysisError(err))
|
||||||
return errs
|
return errs
|
||||||
@@ -213,24 +303,38 @@ func (es _EndUserService) BatchImportPVRegister(reportId string, file io.Reader)
|
|||||||
}
|
}
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
tx := global.DBConn.NewSession()
|
|
||||||
if err = tx.Begin(); err != nil {
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
errs.AddError(es.newVirtualExcelAnalysisError(err))
|
errs.AddError(es.newVirtualExcelAnalysisError(err))
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
defer tx.Close()
|
|
||||||
|
|
||||||
for _, im := range imports {
|
for _, im := range imports {
|
||||||
if elem, ok := indexedUsers[im.MeterId]; ok {
|
if elem, ok := indexedUsers[im.MeterId]; ok {
|
||||||
|
if appears, has := lo.Find(meterAppers, func(m MeterAppears) bool {
|
||||||
|
return m.Meter == elem.MeterId
|
||||||
|
}); has {
|
||||||
|
if appears.Appears <= 1 {
|
||||||
|
elem.LastPeriodOverall = im.LastPeriodOverall
|
||||||
|
elem.LastPeriodCritical = im.LastPeriodCritical.Decimal
|
||||||
|
elem.LastPeriodPeak = im.LastPeriodPeak.Decimal
|
||||||
|
elem.LastPeriodValley = im.LastPeriodValley.Decimal
|
||||||
|
elem.LastPeriodFlat = elem.LastPeriodOverall.Sub(elem.LastPeriodCritical).Sub(elem.LastPeriodPeak).Sub(elem.LastPeriodValley)
|
||||||
|
elem.Initialize = true
|
||||||
|
}
|
||||||
|
}
|
||||||
elem.CurrentPeriodOverall = im.CurrentPeriodOverall
|
elem.CurrentPeriodOverall = im.CurrentPeriodOverall
|
||||||
elem.AdjustOverall = im.AdjustOverall
|
elem.AdjustOverall = im.AdjustOverall
|
||||||
elem.CurrentPeriodCritical = im.CurrentPeriodCritical.Decimal
|
elem.CurrentPeriodCritical = im.CurrentPeriodCritical.Decimal
|
||||||
elem.CurrentPeriodPeak = im.CurrentPeriodPeak.Decimal
|
elem.CurrentPeriodPeak = im.CurrentPeriodPeak.Decimal
|
||||||
elem.CurrentPeriodValley = im.CurrentPeriodValley.Decimal
|
elem.CurrentPeriodValley = im.CurrentPeriodValley.Decimal
|
||||||
|
elem.CurrentPeriodFlat = elem.CurrentPeriodOverall.Sub(elem.CurrentPeriodCritical).Sub(elem.CurrentPeriodPeak).Sub(elem.CurrentPeriodValley)
|
||||||
elem.AdjustCritical = im.AdjustCritical.Decimal
|
elem.AdjustCritical = im.AdjustCritical.Decimal
|
||||||
elem.AdjustPeak = im.AdjustPeak.Decimal
|
elem.AdjustPeak = im.AdjustPeak.Decimal
|
||||||
elem.AdjustValley = im.AdjustValley.Decimal
|
elem.AdjustValley = im.AdjustValley.Decimal
|
||||||
err := es.UpdateEndUserRegisterRecord(tx, elem)
|
elem.AdjustFlat = elem.AdjustOverall.Sub(elem.AdjustCritical).Sub(elem.AdjustPeak).Sub(elem.AdjustValley)
|
||||||
|
err := es.UpdateEndUserRegisterRecord(&tx, &ctx, elem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs.AddError(es.newVirtualExcelAnalysisError(err))
|
errs.AddError(es.newVirtualExcelAnalysisError(err))
|
||||||
}
|
}
|
||||||
@@ -251,3 +355,125 @@ func (es _EndUserService) BatchImportPVRegister(reportId string, file io.Reader)
|
|||||||
cache.AbolishRelation("end_user_detail")
|
cache.AbolishRelation("end_user_detail")
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (es _EndUserService) StatEndUserRecordInPeriod(requestUser, requestPark, startDate, endDate string) ([]model.EndUserPeriodStat, error) {
|
||||||
|
var (
|
||||||
|
conditions = make([]string, 0)
|
||||||
|
relations = []string{
|
||||||
|
fmt.Sprintf("park:%s", requestPark),
|
||||||
|
"end_user_detail",
|
||||||
|
}
|
||||||
|
cond = global.DB.NewSelect().
|
||||||
|
Model((*model.EndUserDetail)(nil)).
|
||||||
|
Relation("Report", func(sq *bun.SelectQuery) *bun.SelectQuery {
|
||||||
|
return sq.ExcludeColumn("*")
|
||||||
|
}).
|
||||||
|
Relation("Park", func(sq *bun.SelectQuery) *bun.SelectQuery {
|
||||||
|
return sq.ExcludeColumn("*")
|
||||||
|
})
|
||||||
|
)
|
||||||
|
if len(requestUser) > 0 {
|
||||||
|
cond = cond.Where("park.user_id = ?", requestUser)
|
||||||
|
conditions = append(conditions, requestUser)
|
||||||
|
} else {
|
||||||
|
conditions = append(conditions, "_")
|
||||||
|
}
|
||||||
|
if len(requestPark) > 0 {
|
||||||
|
cond = cond.Where("eud.park_id = ?", requestPark)
|
||||||
|
conditions = append(conditions, requestPark)
|
||||||
|
} else {
|
||||||
|
conditions = append(conditions, "_")
|
||||||
|
}
|
||||||
|
if len(startDate) > 0 {
|
||||||
|
parseTime, err := time.Parse("2006-01", startDate)
|
||||||
|
if err != nil {
|
||||||
|
return make([]model.EndUserPeriodStat, 0), fmt.Errorf("不能解析给定的参数[startDate],%w", err)
|
||||||
|
}
|
||||||
|
start := model.NewDate(parseTime)
|
||||||
|
cond = cond.Where("report.period >= ?::date", start.ToString())
|
||||||
|
conditions = append(conditions, startDate)
|
||||||
|
} else {
|
||||||
|
conditions = append(conditions, "_")
|
||||||
|
}
|
||||||
|
if len(endDate) > 0 {
|
||||||
|
parseTime, err := time.Parse("2006-01", endDate)
|
||||||
|
if err != nil {
|
||||||
|
return make([]model.EndUserPeriodStat, 0), fmt.Errorf("不能解析给定的参数[endDate],%w", err)
|
||||||
|
}
|
||||||
|
end := model.NewDate(parseTime)
|
||||||
|
cond = cond.Where("report.period <= ?::date", end.ToString())
|
||||||
|
conditions = append(conditions, endDate)
|
||||||
|
}
|
||||||
|
if cached, err := cache.RetreiveSearch[[]model.EndUserPeriodStat]("end_user_stat", conditions...); cached != nil && err == nil {
|
||||||
|
return *cached, nil
|
||||||
|
}
|
||||||
|
ctx, cancel := global.TimeoutContext(120)
|
||||||
|
defer cancel()
|
||||||
|
var endUserSums []model.EndUserPeriodStat
|
||||||
|
err := cond.Column("eud.meter_04kv_id", "eud.park_id").
|
||||||
|
ColumnExpr("sum(?) as overall", bun.Ident("eud.overall")).
|
||||||
|
ColumnExpr("sum(?) as overall_fee", bun.Ident("eud.overall_fee")).
|
||||||
|
ColumnExpr("sum(?) as critical", bun.Ident("eud.critical")).
|
||||||
|
ColumnExpr("sum(?) as critical_fee", bun.Ident("eud.critical_fee")).
|
||||||
|
ColumnExpr("sum(?) as peak", bun.Ident("eud.peak")).
|
||||||
|
ColumnExpr("sum(?) as peak_fee", bun.Ident("eud.peak_fee")).
|
||||||
|
ColumnExpr("sum(?) as valley", bun.Ident("eud.valley")).
|
||||||
|
ColumnExpr("sum(?) as valley_fee", bun.Ident("eud.valley_fee")).
|
||||||
|
ColumnExpr("sum(?) as final_diluted", bun.Ident("eud.final_diluted")).
|
||||||
|
Where("report.published = ?", true).
|
||||||
|
Group("eud.meter_04kv_id", "eud.park_id").
|
||||||
|
Scan(ctx, &endUserSums)
|
||||||
|
if err != nil {
|
||||||
|
return make([]model.EndUserPeriodStat, 0), fmt.Errorf("未能完成终端用户在指定期限内的统计,%w", err)
|
||||||
|
}
|
||||||
|
parkIds := lo.Reduce(
|
||||||
|
endUserSums,
|
||||||
|
func(acc mapset.Set[string], elem model.EndUserPeriodStat, _ int) mapset.Set[string] {
|
||||||
|
acc.Add(elem.ParkId)
|
||||||
|
return acc
|
||||||
|
},
|
||||||
|
mapset.NewSet[string](),
|
||||||
|
)
|
||||||
|
meterArchives := make([]model.Meter04KV, 0)
|
||||||
|
if len(parkIds.ToSlice()) > 0 {
|
||||||
|
err = global.DB.NewSelect().
|
||||||
|
Model(&meterArchives).Relation("ParkDetail").
|
||||||
|
Where("park_id in (?)", bun.In(parkIds.ToSlice())).
|
||||||
|
Scan(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return make([]model.EndUserPeriodStat, 0), fmt.Errorf("未能获取到终端表计的最新基础档案,%w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filledStats := lo.Map(
|
||||||
|
endUserSums,
|
||||||
|
func(elem model.EndUserPeriodStat, _ int) model.EndUserPeriodStat {
|
||||||
|
archive, has := lo.Find(meterArchives, func(meter model.Meter04KV) bool {
|
||||||
|
return meter.Code == elem.MeterId
|
||||||
|
})
|
||||||
|
if has {
|
||||||
|
if archive.Address != nil {
|
||||||
|
elem.Address = *archive.Address
|
||||||
|
} else {
|
||||||
|
elem.Address = ""
|
||||||
|
}
|
||||||
|
if archive.CustomerName != nil {
|
||||||
|
elem.CustomerName = *archive.CustomerName
|
||||||
|
} else {
|
||||||
|
elem.CustomerName = ""
|
||||||
|
}
|
||||||
|
elem.IsPublicMeter = archive.IsPublicMeter
|
||||||
|
elem.Kind = archive.ParkDetail.SubmeterType
|
||||||
|
}
|
||||||
|
if elem.OverallFee.Valid && elem.AdjustFee.Valid && !elem.OverallFee.Decimal.IsZero() {
|
||||||
|
elem.AdjustProportion = decimal.NewNullDecimal(
|
||||||
|
elem.AdjustFee.Decimal.Div(elem.OverallFee.Decimal).RoundBank(8),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
elem.AdjustProportion = decimal.NullDecimal{}
|
||||||
|
}
|
||||||
|
return elem
|
||||||
|
},
|
||||||
|
)
|
||||||
|
cache.CacheSearch(filledStats, relations, "end_user_stat", conditions...)
|
||||||
|
return filledStats, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,875 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"electricity_bill_calc/cache"
|
||||||
|
"electricity_bill_calc/exceptions"
|
||||||
|
"electricity_bill_calc/global"
|
||||||
|
"electricity_bill_calc/logger"
|
||||||
|
"electricity_bill_calc/model"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/samber/lo"
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
"github.com/uptrace/bun"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type _GodModeService struct {
|
||||||
|
l *zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
var GodModeService = _GodModeService{
|
||||||
|
l: logger.Named("Service", "GodMode"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从此处开始为删除报表相关的部分
|
||||||
|
|
||||||
|
func (_GodModeService) resetReportIndex(tx *bun.Tx, ctx *context.Context, reportId string) (bool, error) {
|
||||||
|
var report = new(model.Report)
|
||||||
|
err := tx.NewSelect().Model(report).Where("id = ?", reportId).Scan(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, exceptions.NewNotFoundError("指定报表索引未找到。")
|
||||||
|
}
|
||||||
|
report.StepState.Summary = false
|
||||||
|
report.StepState.WillDiluted = false
|
||||||
|
report.StepState.Submeter = false
|
||||||
|
report.StepState.Calculate = false
|
||||||
|
report.StepState.Preview = false
|
||||||
|
report.StepState.Publish = false
|
||||||
|
report.Published = false
|
||||||
|
report.PublishedAt = nil
|
||||||
|
report.Withdraw = model.REPORT_NOT_WITHDRAW
|
||||||
|
report.LastWithdrawAppliedAt = nil
|
||||||
|
report.LastWithdrawAuditAt = nil
|
||||||
|
|
||||||
|
res, err := tx.NewUpdate().Model(report).
|
||||||
|
WherePK().
|
||||||
|
Column(
|
||||||
|
"step_state",
|
||||||
|
"published",
|
||||||
|
"published_at",
|
||||||
|
"withdraw",
|
||||||
|
"last_withdraw_applied_at",
|
||||||
|
"last_withdraw_audit_at",
|
||||||
|
).
|
||||||
|
Exec(*ctx)
|
||||||
|
|
||||||
|
if affected, _ := res.RowsAffected(); err != nil || affected == 0 {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_GodModeService) resetReportSummary(tx *bun.Tx, ctx *context.Context, reportId string) (bool, error) {
|
||||||
|
var summary = &model.ReportSummary{
|
||||||
|
ReportId: reportId,
|
||||||
|
}
|
||||||
|
_, err := tx.NewUpdate().Model(summary).WherePK().Exec(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
var report = new(model.Report)
|
||||||
|
err = tx.NewSelect().Model(report).Where("id = ?", reportId).Scan(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
report.StepState.Summary = false
|
||||||
|
res, err := tx.NewUpdate().Model(report).
|
||||||
|
Column("step_state").
|
||||||
|
WherePK().
|
||||||
|
Exec(*ctx)
|
||||||
|
rows, _ := res.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
}
|
||||||
|
return rows >= 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_GodModeService) flushReportMaintenances(tx *bun.Tx, ctx *context.Context, reportId string) (bool, error) {
|
||||||
|
_, err := tx.NewDelete().Model((*model.WillDilutedFee)(nil)).
|
||||||
|
Where("report_id = ?", reportId).
|
||||||
|
Exec(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
var report = new(model.Report)
|
||||||
|
err = tx.NewSelect().Model(report).Where("id = ?", reportId).Scan(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
report.StepState.WillDiluted = false
|
||||||
|
res, err := tx.NewUpdate().Model(report).
|
||||||
|
WherePK().
|
||||||
|
Column("step_state").
|
||||||
|
Exec(*ctx)
|
||||||
|
rows, _ := res.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
}
|
||||||
|
return rows >= 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g _GodModeService) resetSingleEndUserRecord(tx *bun.Tx, ctx *context.Context, record model.EndUserDetail, additionalColumns ...string) (bool, error) {
|
||||||
|
record.CurrentPeriodOverall = decimal.Zero
|
||||||
|
record.CurrentPeriodCritical = decimal.Zero
|
||||||
|
record.CurrentPeriodPeak = decimal.Zero
|
||||||
|
record.CurrentPeriodFlat = decimal.Zero
|
||||||
|
record.CurrentPeriodValley = decimal.Zero
|
||||||
|
record.AdjustOverall = decimal.Zero
|
||||||
|
record.AdjustCritical = decimal.Zero
|
||||||
|
record.AdjustPeak = decimal.Zero
|
||||||
|
record.AdjustFlat = decimal.Zero
|
||||||
|
record.AdjustValley = decimal.Zero
|
||||||
|
record.Overall = decimal.NewNullDecimal(decimal.Zero)
|
||||||
|
record.Overall.Valid = false
|
||||||
|
record.OverallFee = decimal.NewNullDecimal(decimal.Zero)
|
||||||
|
record.OverallFee.Valid = false
|
||||||
|
record.OverallProportion = decimal.Zero
|
||||||
|
record.Critical = decimal.NewNullDecimal(decimal.Zero)
|
||||||
|
record.Critical.Valid = false
|
||||||
|
record.CriticalFee = decimal.NewNullDecimal(decimal.Zero)
|
||||||
|
record.CriticalFee.Valid = false
|
||||||
|
record.Peak = decimal.NewNullDecimal(decimal.Zero)
|
||||||
|
record.Peak.Valid = false
|
||||||
|
record.PeakFee = decimal.NewNullDecimal(decimal.Zero)
|
||||||
|
record.PeakFee.Valid = false
|
||||||
|
record.Flat = decimal.NewNullDecimal(decimal.Zero)
|
||||||
|
record.Flat.Valid = false
|
||||||
|
record.FlatFee = decimal.NewNullDecimal(decimal.Zero)
|
||||||
|
record.FlatFee.Valid = false
|
||||||
|
record.Valley = decimal.NewNullDecimal(decimal.Zero)
|
||||||
|
record.Valley.Valid = false
|
||||||
|
record.ValleyFee = decimal.NewNullDecimal(decimal.Zero)
|
||||||
|
record.ValleyFee.Valid = false
|
||||||
|
record.BasicFeeDiluted = decimal.NewNullDecimal(decimal.Zero)
|
||||||
|
record.BasicFeeDiluted.Valid = false
|
||||||
|
record.AdjustFeeDiluted = decimal.NewNullDecimal(decimal.Zero)
|
||||||
|
record.AdjustFeeDiluted.Valid = false
|
||||||
|
record.LossDiluted = decimal.NewNullDecimal(decimal.Zero)
|
||||||
|
record.LossDiluted.Valid = false
|
||||||
|
record.LossFeeDiluted = decimal.NewNullDecimal(decimal.Zero)
|
||||||
|
record.LossFeeDiluted.Valid = false
|
||||||
|
record.FinalDiluted = decimal.NewNullDecimal(decimal.Zero)
|
||||||
|
record.FinalDiluted.Valid = false
|
||||||
|
record.FinalCharge = decimal.NewNullDecimal(decimal.Zero)
|
||||||
|
record.FinalCharge.Valid = false
|
||||||
|
|
||||||
|
columns := []string{
|
||||||
|
"current_period_overall",
|
||||||
|
"current_period_critical",
|
||||||
|
"current_period_peak",
|
||||||
|
"current_period_flat",
|
||||||
|
"current_period_valley",
|
||||||
|
"adjust_overall",
|
||||||
|
"adjust_critical",
|
||||||
|
"adjust_peak",
|
||||||
|
"adjust_flat",
|
||||||
|
"adjust_valley",
|
||||||
|
"overall",
|
||||||
|
"overall_fee",
|
||||||
|
"overall_proportion",
|
||||||
|
"critical",
|
||||||
|
"critical_fee",
|
||||||
|
"peak",
|
||||||
|
"peak_fee",
|
||||||
|
"flat",
|
||||||
|
"flat_fee",
|
||||||
|
"valley",
|
||||||
|
"valley_fee",
|
||||||
|
"basic_fee_diluted",
|
||||||
|
"adjust_fee_diluted",
|
||||||
|
"loss_diluted",
|
||||||
|
"loss_fee_diluted",
|
||||||
|
"maintenance_fee_diluted",
|
||||||
|
"public_consumption_diluted",
|
||||||
|
"final_diluted",
|
||||||
|
"final_charge",
|
||||||
|
}
|
||||||
|
columns = append(columns, additionalColumns...)
|
||||||
|
|
||||||
|
_, err := tx.NewUpdate().Model(&record).
|
||||||
|
WherePK().
|
||||||
|
Column(columns...).
|
||||||
|
Exec(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g _GodModeService) resynchronizeEndUserArchives(tx *bun.Tx, ctx *context.Context, reportId string) (bool, error) {
|
||||||
|
var currentRecords = make([]*model.EndUserDetail, 0)
|
||||||
|
err := tx.NewSelect().Model(¤tRecords).
|
||||||
|
Where("report_id = ?", reportId).
|
||||||
|
Scan(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
var report = new(model.Report)
|
||||||
|
err = tx.NewSelect().Model(report).
|
||||||
|
Where("id = ?", reportId).
|
||||||
|
Scan(*ctx)
|
||||||
|
if err != nil || report == nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
var latestArchives = make([]model.Meter04KV, 0)
|
||||||
|
err = tx.NewSelect().Model(&latestArchives).
|
||||||
|
Where("park_id = ?", report.ParkId).
|
||||||
|
Where("enabled = ?", true).
|
||||||
|
Scan(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, meter := range latestArchives {
|
||||||
|
record, has := lo.Find(currentRecords, func(rec *model.EndUserDetail) bool {
|
||||||
|
return rec.ParkId == meter.ParkId && rec.MeterId == meter.Code
|
||||||
|
})
|
||||||
|
if has {
|
||||||
|
record.CustomerName = meter.CustomerName
|
||||||
|
record.Address = meter.Address
|
||||||
|
record.Ratio = meter.Ratio
|
||||||
|
record.ContactName = meter.ContactName
|
||||||
|
record.ContactPhone = meter.ContactPhone
|
||||||
|
record.Seq = meter.Seq
|
||||||
|
record.IsPublicMeter = meter.IsPublicMeter
|
||||||
|
success, err := g.resetSingleEndUserRecord(
|
||||||
|
tx, ctx, *record,
|
||||||
|
"customer_name",
|
||||||
|
"address",
|
||||||
|
"ratio",
|
||||||
|
"contact_name",
|
||||||
|
"contact_phone",
|
||||||
|
"seq",
|
||||||
|
"public_meter",
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return success, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newEndUser := model.EndUserDetail{
|
||||||
|
ReportId: report.Id,
|
||||||
|
ParkId: report.ParkId,
|
||||||
|
MeterId: meter.Code,
|
||||||
|
Seq: meter.Seq,
|
||||||
|
Ratio: meter.Ratio,
|
||||||
|
Address: meter.Address,
|
||||||
|
CustomerName: meter.CustomerName,
|
||||||
|
ContactName: meter.ContactName,
|
||||||
|
ContactPhone: meter.ContactPhone,
|
||||||
|
IsPublicMeter: meter.IsPublicMeter,
|
||||||
|
LastPeriodOverall: decimal.Zero,
|
||||||
|
LastPeriodCritical: decimal.Zero,
|
||||||
|
LastPeriodPeak: decimal.Zero,
|
||||||
|
LastPeriodFlat: decimal.Zero,
|
||||||
|
LastPeriodValley: decimal.Zero,
|
||||||
|
}
|
||||||
|
_, err = tx.NewInsert().Model(&newEndUser).Exec(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
report.StepState.Submeter = false
|
||||||
|
res, err := tx.NewUpdate().Model(report).
|
||||||
|
WherePK().
|
||||||
|
Column("step_state").
|
||||||
|
Exec(*ctx)
|
||||||
|
rows, _ := res.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
}
|
||||||
|
return rows >= 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g _GodModeService) resetEndUserRecords(tx *bun.Tx, ctx *context.Context, reportId string) (bool, error) {
|
||||||
|
var records = make([]model.EndUserDetail, 0)
|
||||||
|
err := tx.NewSelect().Model(&records).
|
||||||
|
Where("report_id = ?", reportId).
|
||||||
|
Scan(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
for _, u := range records {
|
||||||
|
success, err := g.resetSingleEndUserRecord(tx, ctx, u)
|
||||||
|
if err != nil {
|
||||||
|
return success, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var report = new(model.Report)
|
||||||
|
err = tx.NewSelect().Model(report).
|
||||||
|
Where("id = ?", reportId).
|
||||||
|
Scan(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
report.StepState.Submeter = false
|
||||||
|
res, err := tx.NewUpdate().Model(report).
|
||||||
|
WherePK().
|
||||||
|
Column("step_state").
|
||||||
|
Exec(*ctx)
|
||||||
|
rows, _ := res.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
}
|
||||||
|
return rows >= 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReportPeriod struct {
|
||||||
|
Id string
|
||||||
|
Period time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_GodModeService) isTheLatestReport(ctx *context.Context, reportId string) (bool, error) {
|
||||||
|
var report = new(model.Report)
|
||||||
|
err := global.DB.NewSelect().Model(report).
|
||||||
|
Where("id = ?", reportId).
|
||||||
|
Scan(*ctx)
|
||||||
|
if err != nil || report == nil {
|
||||||
|
return false, exceptions.NewNotFoundErrorFromError("指定报表索引未找到,", err)
|
||||||
|
}
|
||||||
|
var maxPeriod time.Time
|
||||||
|
err = global.DB.NewSelect().Model((*model.Report)(nil)).
|
||||||
|
ColumnExpr("max(?)", bun.Ident("period")).
|
||||||
|
Where("park_id = ?", report.ParkId).
|
||||||
|
Scan(*ctx, &maxPeriod)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return maxPeriod.Equal(report.Period), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_GodModeService) forceDeleteReport(tx *bun.Tx, ctx *context.Context, reportId string) (bool, error) {
|
||||||
|
_, err := tx.NewDelete().Model((*model.EndUserDetail)(nil)).
|
||||||
|
Where("report_id = ?", reportId).
|
||||||
|
Exec(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
_, err = tx.NewDelete().Model((*model.WillDilutedFee)(nil)).
|
||||||
|
Where("report_id = ?", reportId).
|
||||||
|
Exec(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
_, err = tx.NewDelete().Model((*model.ReportSummary)(nil)).
|
||||||
|
Where("report_id = ?", reportId).
|
||||||
|
Exec(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
_, err = tx.NewDelete().Model((*model.Report)(nil)).
|
||||||
|
Where("id = ?", reportId).
|
||||||
|
Exec(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g _GodModeService) ClearReportSummary(reportId string) (bool, error) {
|
||||||
|
ctx, cancel := global.TimeoutContext(12)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
isLatest, err := g.isTheLatestReport(&ctx, reportId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if !isLatest {
|
||||||
|
return false, exceptions.NewImproperOperateError("不能操作非最新期数的报表。")
|
||||||
|
}
|
||||||
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := g.resetReportSummary(&tx, &ctx, reportId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("report:%s", reportId))
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g _GodModeService) ClearReportMaintenances(reportId string) (bool, error) {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
isLatest, err := g.isTheLatestReport(&ctx, reportId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if !isLatest {
|
||||||
|
return false, exceptions.NewImproperOperateError("不能操作非最新期数的报表。")
|
||||||
|
}
|
||||||
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := g.flushReportMaintenances(&tx, &ctx, reportId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("report:%s", reportId))
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g _GodModeService) ResynchronizeEndUser(reportId string) (bool, error) {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
isLatest, err := g.isTheLatestReport(&ctx, reportId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if !isLatest {
|
||||||
|
return false, exceptions.NewImproperOperateError("不能操作非最新期数的报表。")
|
||||||
|
}
|
||||||
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := g.resynchronizeEndUserArchives(&tx, &ctx, reportId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
cache.AbolishRelation("end_user_detail")
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("report:%s", reportId))
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g _GodModeService) ResetEndUserRegisterRecords(reportId string) (bool, error) {
|
||||||
|
ctx, cancel := global.TimeoutContext(48)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
isLatest, err := g.isTheLatestReport(&ctx, reportId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if !isLatest {
|
||||||
|
return false, exceptions.NewImproperOperateError("不能操作非最新期数的报表。")
|
||||||
|
}
|
||||||
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := g.resetEndUserRecords(&tx, &ctx, reportId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
cache.AbolishRelation("end_user_detail")
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("report:%s", reportId))
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g _GodModeService) ResetReport(reportId string) (bool, error) {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
isLatest, err := g.isTheLatestReport(&ctx, reportId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if !isLatest {
|
||||||
|
return false, exceptions.NewImproperOperateError("不能操作非最新期数的报表。")
|
||||||
|
}
|
||||||
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
var result = true
|
||||||
|
r, err := g.resetEndUserRecords(&tx, &ctx, reportId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
result = result && r
|
||||||
|
r, err = g.flushReportMaintenances(&tx, &ctx, reportId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
result = result && r
|
||||||
|
r, err = g.resetReportSummary(&tx, &ctx, reportId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
result = result && r
|
||||||
|
r, err = g.resetReportIndex(&tx, &ctx, reportId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
result = result && r
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
cache.AbolishRelation("end_user_detail")
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("report:%s", reportId))
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g _GodModeService) DeleteReport(reportId string) (bool, error) {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
isLatest, err := g.isTheLatestReport(&ctx, reportId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if !isLatest {
|
||||||
|
return false, exceptions.NewImproperOperateError("不能删除非最新期数的报表。")
|
||||||
|
}
|
||||||
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := g.forceDeleteReport(&tx, &ctx, reportId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
cache.AbolishRelation("end_user_detail")
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("report:%s", reportId))
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从此处开始为删除园区相关的内容部分
|
||||||
|
|
||||||
|
func (_GodModeService) deleteSpecificMaintenance(tx *bun.Tx, ctx *context.Context, parkId, maintenanceId string) (bool, error) {
|
||||||
|
res, err := tx.NewDelete().Model((*model.MaintenanceFee)(nil)).
|
||||||
|
Where("park_id = ?", parkId).
|
||||||
|
Where("id = ?", maintenanceId).
|
||||||
|
Exec(*ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if rows, err := res.RowsAffected(); err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
} else {
|
||||||
|
return rows >= 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_GodModeService) deleteAllMaintenance(tx *bun.Tx, ctx *context.Context, parkId string) (bool, error) {
|
||||||
|
res, err := tx.NewDelete().Model((*model.MaintenanceFee)(nil)).
|
||||||
|
Where("park_id = ?", parkId).
|
||||||
|
Exec(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if rows, err := res.RowsAffected(); err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
} else {
|
||||||
|
return rows >= 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_GodModeService) deleteAllMeters(tx *bun.Tx, ctx *context.Context, parkId string) (bool, error) {
|
||||||
|
res, err := tx.NewDelete().Model((*model.Meter04KV)(nil)).
|
||||||
|
Where("park_id = ?", parkId).
|
||||||
|
Exec(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if rows, err := res.RowsAffected(); err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
} else {
|
||||||
|
return rows >= 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_GodModeService) deletePark(tx *bun.Tx, ctx *context.Context, parkId string) (bool, error) {
|
||||||
|
res, err := tx.NewDelete().Model((*model.Park)(nil)).
|
||||||
|
Where("id = ?", parkId).
|
||||||
|
Exec(*ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if rows, err := res.RowsAffected(); err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
} else {
|
||||||
|
return rows >= 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g _GodModeService) RemoveSpecificMaintenance(parkId, maintenanceId string) (bool, error) {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := g.deleteSpecificMaintenance(&tx, &ctx, parkId, maintenanceId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("maintenance_fee:%s", maintenanceId))
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g _GodModeService) RemoveAllMaintenance(parkId string) (bool, error) {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := g.deleteAllMaintenance(&tx, &ctx, parkId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
cache.AbolishRelation("maintenance_fee")
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g _GodModeService) RemoveAllMeters(parkId string) (bool, error) {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := g.deleteAllMeters(&tx, &ctx, parkId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
cache.AbolishRelation("meter_04kv")
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g _GodModeService) erasePark(tx *bun.Tx, ctx *context.Context, parkId string) (bool, error) {
|
||||||
|
var reportIds = make([]string, 0)
|
||||||
|
err := tx.NewSelect().Model((*model.Report)(nil)).
|
||||||
|
Where("park_id = ?", parkId).
|
||||||
|
Column("id").
|
||||||
|
Scan(*ctx, &reportIds)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
var result = true
|
||||||
|
for _, id := range reportIds {
|
||||||
|
r, err := g.forceDeleteReport(tx, ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
result = result && r
|
||||||
|
}
|
||||||
|
r, err := g.deleteAllMaintenance(tx, ctx, parkId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
result = result && r
|
||||||
|
r, err = g.deleteAllMeters(tx, ctx, parkId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
result = result && r
|
||||||
|
r, err = g.deletePark(tx, ctx, parkId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
result = result && r
|
||||||
|
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g _GodModeService) RemovePark(parkId string) (bool, error) {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := g.erasePark(&tx, &ctx, parkId)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("park:%s", parkId))
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从此处开始为删除用户相关的部分
|
||||||
|
|
||||||
|
func (g _GodModeService) DeleteUser(userId string) (bool, error) {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var parkIds = make([]string, 0)
|
||||||
|
err = tx.NewSelect().Model((*model.Park)(nil)).
|
||||||
|
Where("user_id = ?", userId).
|
||||||
|
WhereAllWithDeleted().
|
||||||
|
Column("id").
|
||||||
|
Scan(ctx, &parkIds)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = true
|
||||||
|
for _, p := range parkIds {
|
||||||
|
r, err := g.erasePark(&tx, &ctx, p)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
result = result && r
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除用户服务计费数据。
|
||||||
|
res, err := tx.NewDelete().Model((*model.UserCharge)(nil)).
|
||||||
|
Where("user_id = ?", userId).
|
||||||
|
Exec(ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if rows, err := res.RowsAffected(); err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
} else {
|
||||||
|
result = result && (rows >= 0)
|
||||||
|
}
|
||||||
|
// 删除用户详细信息数据
|
||||||
|
res, err = tx.NewDelete().Model((*model.UserDetail)(nil)).
|
||||||
|
Where("id = ?", userId).
|
||||||
|
ForceDelete().
|
||||||
|
Exec(ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if rows, err := res.RowsAffected(); err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
} else {
|
||||||
|
result = result && (rows >= 0)
|
||||||
|
}
|
||||||
|
// 删除用户基本索引数据
|
||||||
|
res, err = tx.NewDelete().Model((*model.User)(nil)).
|
||||||
|
Where("id = ?", userId).
|
||||||
|
Exec(ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if rows, err := res.RowsAffected(); err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
} else {
|
||||||
|
result = result && (rows >= 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("user:%s", userId))
|
||||||
|
cache.AbolishRelation("user")
|
||||||
|
cache.AbolishRelation("park")
|
||||||
|
cache.AbolishRelation("report")
|
||||||
|
cache.AbolishRelation("charge")
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
+224
-45
@@ -2,42 +2,79 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"electricity_bill_calc/cache"
|
"electricity_bill_calc/cache"
|
||||||
|
"electricity_bill_calc/config"
|
||||||
"electricity_bill_calc/exceptions"
|
"electricity_bill_calc/exceptions"
|
||||||
"electricity_bill_calc/global"
|
"electricity_bill_calc/global"
|
||||||
|
"electricity_bill_calc/logger"
|
||||||
"electricity_bill_calc/model"
|
"electricity_bill_calc/model"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
mapset "github.com/deckarep/golang-set/v2"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"xorm.io/builder"
|
"github.com/samber/lo"
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
"github.com/uptrace/bun"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type _MaintenanceFeeService struct{}
|
type _MaintenanceFeeService struct {
|
||||||
|
l *zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
var MaintenanceFeeService _MaintenanceFeeService
|
var MaintenanceFeeService = _MaintenanceFeeService{
|
||||||
|
l: logger.Named("Service", "maintenance"),
|
||||||
|
}
|
||||||
|
|
||||||
func (_MaintenanceFeeService) ListMaintenanceFees(pid []string) ([]model.MaintenanceFee, error) {
|
func (_MaintenanceFeeService) ListMaintenanceFees(pid []string, period string, requestPage int) ([]model.MaintenanceFee, int64, error) {
|
||||||
cond := builder.NewCond()
|
conditions := []string{fmt.Sprintf("%d", requestPage)}
|
||||||
|
conditions = append(conditions, pid...)
|
||||||
|
conditions = append(conditions, period)
|
||||||
|
if cachedTotal, err := cache.RetreiveCount("maintenance_fee", conditions...); cachedTotal != -1 && err == nil {
|
||||||
|
if fees, _ := cache.RetreiveSearch[[]model.MaintenanceFee]("maintenance_fee", conditions...); fees != nil {
|
||||||
|
return *fees, cachedTotal, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
fees = make([]model.MaintenanceFee, 0)
|
||||||
|
cond = global.DB.NewSelect().Model(&fees)
|
||||||
|
)
|
||||||
if len(pid) > 0 {
|
if len(pid) > 0 {
|
||||||
cond = cond.And(builder.Eq{"park_id": pid})
|
cond = cond.Where("park_id in (?)", bun.In(pid))
|
||||||
} else {
|
} else {
|
||||||
return make([]model.MaintenanceFee, 0), exceptions.NewIllegalArgumentsError("必须给定所要请求的至少一个园区", "park_id")
|
return make([]model.MaintenanceFee, 0), 0, exceptions.NewIllegalArgumentsError("必须给定所要请求的至少一个园区", "park_id")
|
||||||
}
|
}
|
||||||
if fees, _ := cache.RetreiveSearch[[]model.MaintenanceFee]("maintenance_fee", pid...); fees != nil {
|
if len(period) > 0 {
|
||||||
return *fees, nil
|
cond = cond.Where("period = ?", period)
|
||||||
}
|
}
|
||||||
var fees = make([]model.MaintenanceFee, 0)
|
|
||||||
err := global.DBConn.Where(cond).Desc("created_at").Find(&fees)
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
startItem := (requestPage - 1) * config.ServiceSettings.ItemsPageSize
|
||||||
|
total, err := cond.Order("period desc", "created_at desc").
|
||||||
|
Limit(config.ServiceSettings.ItemsPageSize).
|
||||||
|
Offset(startItem).
|
||||||
|
ScanAndCount(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return make([]model.MaintenanceFee, 0), err
|
return make([]model.MaintenanceFee, 0), 0, fmt.Errorf("附加费查询出现错误,%w", err)
|
||||||
}
|
}
|
||||||
cache.CacheSearch(fees, []string{"maintenance_fee", "park"}, "maintenance_fee", pid...)
|
relations := lo.Map(fees, func(f model.MaintenanceFee, _ int) string {
|
||||||
return fees, nil
|
return fmt.Sprintf("maintenance_fee:%s", f.Id)
|
||||||
|
})
|
||||||
|
relations = append(relations, "maintenance_fee", "park")
|
||||||
|
|
||||||
|
cache.CacheCount(relations, "maintenance_fee", int64(total), conditions...)
|
||||||
|
cache.CacheSearch(fees, relations, "maintenance_fee", conditions...)
|
||||||
|
return fees, int64(total), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_MaintenanceFeeService) CreateMaintenanceFeeRecord(fee model.MaintenanceFee) error {
|
func (_MaintenanceFeeService) CreateMaintenanceFeeRecord(fee model.MaintenanceFee) error {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
fee.Id = uuid.New().String()
|
fee.Id = uuid.New().String()
|
||||||
fee.Enabled = true
|
fee.Enabled = true
|
||||||
_, err := global.DBConn.Insert(fee)
|
_, err := global.DB.NewInsert().Model(&fee).Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -46,44 +83,61 @@ func (_MaintenanceFeeService) CreateMaintenanceFeeRecord(fee model.MaintenanceFe
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (_MaintenanceFeeService) ModifyMaintenanceFee(fee model.MaintenanceFee) error {
|
func (_MaintenanceFeeService) ModifyMaintenanceFee(fee model.MaintenanceFee) error {
|
||||||
rows, err := global.DBConn.Table(&model.MaintenanceFee{}).NoAutoCondition().ID(fee.Id).Cols("fee", "memo").Update(fee)
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
res, err := global.DB.NewUpdate().Model(&fee).
|
||||||
|
WherePK().
|
||||||
|
Column("fee", "memo").
|
||||||
|
Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if rows == 0 {
|
if rows, _ := res.RowsAffected(); rows == 0 {
|
||||||
return exceptions.NewNotFoundError("未能找到匹配的维护费记录。")
|
return exceptions.NewNotFoundError("未能找到匹配的附加费记录。")
|
||||||
} else {
|
} else {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("maintenance_fee")
|
cache.AbolishRelation("maintenance_fee")
|
||||||
cache.AbolishRelation(fmt.Sprintf("maintenance_fee_%s", fee.Id))
|
cache.AbolishRelation(fmt.Sprintf("maintenance_fee:%s", fee.Id))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_MaintenanceFeeService) ChangeMaintenanceFeeState(fid string, state bool) error {
|
func (_MaintenanceFeeService) ChangeMaintenanceFeeState(fid string, state bool) error {
|
||||||
rows, err := global.DBConn.Table(&model.MaintenanceFee{}).ID(fid).Update(map[string]interface{}{"enabled": state})
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
res, err := global.DB.NewUpdate().Model((*model.MaintenanceFee)(nil)).
|
||||||
|
Where("id = ?", fid).
|
||||||
|
Set("enabled = ?", state).
|
||||||
|
Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if rows == 0 {
|
if rows, err := res.RowsAffected(); rows == 0 {
|
||||||
return exceptions.NewNotFoundError("未能找到匹配的维护费记录。")
|
return exceptions.NewNotFoundError("未能找到匹配的附加费记录。")
|
||||||
} else {
|
} else {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("maintenance_fee")
|
cache.AbolishRelation("maintenance_fee")
|
||||||
cache.AbolishRelation(fmt.Sprintf("maintenance_fee_%s", fid))
|
cache.AbolishRelation(fmt.Sprintf("maintenance_fee:%s", fid))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_MaintenanceFeeService) DeleteMaintenanceFee(fid string) error {
|
func (_MaintenanceFeeService) DeleteMaintenanceFee(fid string) error {
|
||||||
rows, err := global.DBConn.ID(fid).NoAutoCondition().Delete(new(model.MaintenanceFee))
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
res, err := global.DB.NewDelete().Model((*model.MaintenanceFee)(nil)).
|
||||||
|
Where("id = ?", fid).
|
||||||
|
Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if rows == 0 {
|
if rows, err := res.RowsAffected(); rows == 0 {
|
||||||
return exceptions.NewNotFoundError("未能找到匹配的维护费记录。")
|
return exceptions.NewNotFoundError("未能找到匹配的附加费记录。")
|
||||||
} else {
|
} else {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("maintenance_fee")
|
cache.AbolishRelation("maintenance_fee")
|
||||||
cache.AbolishRelation(fmt.Sprintf("maintenance_fee_%s", fid))
|
cache.AbolishRelation(fmt.Sprintf("maintenance_fee:%s", fid))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,26 +145,151 @@ func (_MaintenanceFeeService) EnsureFeeBelongs(uid, mid string) (bool, error) {
|
|||||||
if has, _ := cache.CheckExists("maintenance_fee", mid, uid); has {
|
if has, _ := cache.CheckExists("maintenance_fee", mid, uid); has {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
var fee = make([]model.MaintenanceFee, 0)
|
|
||||||
err := global.DBConn.
|
ctx, cancel := global.TimeoutContext()
|
||||||
ID(mid).Limit(1).Find(&fee)
|
defer cancel()
|
||||||
|
|
||||||
|
parks := make([]model.Park, 0)
|
||||||
|
err := global.DB.NewSelect().Model(&parks).
|
||||||
|
Relation("MaintenanceFees").
|
||||||
|
Where("p.user_id = ?", uid).
|
||||||
|
Scan(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if len(fee) == 0 {
|
exists := lo.Reduce(parks, func(acc bool, elem model.Park, _ int) bool {
|
||||||
return false, exceptions.NewNotFoundError("指定维护费条目未找到。")
|
for _, e := range elem.MaintenanceFees {
|
||||||
|
if e.Id == mid {
|
||||||
|
return acc || true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return acc || false
|
||||||
|
}, false)
|
||||||
|
if !exists {
|
||||||
|
return false, exceptions.NewNotFoundError("指定附加费所属园区未找到。")
|
||||||
}
|
}
|
||||||
var park = make([]model.Park, 0)
|
cache.CacheExists([]string{fmt.Sprintf("maintenance_fee:%s", mid), "maintenance_fee", "park"}, "maintenance_fee", mid, uid)
|
||||||
err = global.DBConn.
|
return exists, nil
|
||||||
ID(fee[0].ParkId).Limit(1).Find(&park)
|
}
|
||||||
if err != nil {
|
|
||||||
return false, err
|
type _FeeStat struct {
|
||||||
}
|
ParkId string
|
||||||
if len(park) == 0 {
|
Period string
|
||||||
return false, exceptions.NewNotFoundError("指定维护费所属园区未找到。")
|
Total decimal.Decimal
|
||||||
}
|
}
|
||||||
if park[0].UserId == uid {
|
|
||||||
cache.CacheExists([]string{"maintenance_fee", "park"}, "maintenance_fee", mid, uid)
|
func (f _MaintenanceFeeService) QueryAdditionalCharges(uid, pid, period, keyword string, requestPage int) ([]model.AdditionalCharge, int64, error) {
|
||||||
}
|
var (
|
||||||
return park[0].UserId == uid, nil
|
conditions = []string{fmt.Sprintf("%d", requestPage)}
|
||||||
|
statFees = make([]_FeeStat, 0)
|
||||||
|
cond = global.DB.NewSelect().
|
||||||
|
Model((*model.MaintenanceFee)(nil)).
|
||||||
|
Relation("Park", func(q *bun.SelectQuery) *bun.SelectQuery {
|
||||||
|
return q.ExcludeColumn("*")
|
||||||
|
}).
|
||||||
|
Relation("Park.Enterprise", func(q *bun.SelectQuery) *bun.SelectQuery {
|
||||||
|
return q.ExcludeColumn("*")
|
||||||
|
}).
|
||||||
|
Where("m.enabled = ?", true)
|
||||||
|
)
|
||||||
|
if len(uid) > 0 {
|
||||||
|
cond = cond.Where("park__enterprise.id = ?", uid)
|
||||||
|
conditions = append(conditions, uid)
|
||||||
|
} else {
|
||||||
|
conditions = append(conditions, "_")
|
||||||
|
}
|
||||||
|
if len(pid) > 0 {
|
||||||
|
cond = cond.Where("park.id = ?", pid)
|
||||||
|
conditions = append(conditions, pid)
|
||||||
|
} else {
|
||||||
|
conditions = append(conditions, "_")
|
||||||
|
}
|
||||||
|
if len(period) > 0 {
|
||||||
|
cond = cond.Where("m.period = ?", period)
|
||||||
|
conditions = append(conditions, period)
|
||||||
|
} else {
|
||||||
|
conditions = append(conditions, "_")
|
||||||
|
}
|
||||||
|
if len(keyword) > 0 {
|
||||||
|
keywordCond := "%" + keyword + "%"
|
||||||
|
cond = cond.WhereGroup(" and ", func(q *bun.SelectQuery) *bun.SelectQuery {
|
||||||
|
return q.Where("park__enterprise.name like ?", keywordCond).
|
||||||
|
WhereOr("park__enterprise.abbr like ?", keywordCond).
|
||||||
|
WhereOr("park.name like ?", keywordCond).
|
||||||
|
WhereOr("park.abbr like ?", keywordCond).
|
||||||
|
WhereOr("park.address like ?", keywordCond)
|
||||||
|
})
|
||||||
|
conditions = append(conditions, keyword)
|
||||||
|
} else {
|
||||||
|
conditions = append(conditions, "_")
|
||||||
|
}
|
||||||
|
|
||||||
|
if cachedTotal, err := cache.RetreiveCount("additional_charge", conditions...); cachedTotal != -1 && err == nil {
|
||||||
|
if cachedData, _ := cache.RetreiveSearch[[]model.AdditionalCharge]("additional_charge", conditions...); cachedData != nil {
|
||||||
|
return *cachedData, cachedTotal, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx, cancel := global.TimeoutContext(24)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
startItem := (requestPage - 1) * config.ServiceSettings.ItemsPageSize
|
||||||
|
|
||||||
|
total, err := cond.ColumnExpr("sum(?) as total", bun.Ident("fee")).
|
||||||
|
Column("park_id", "period").
|
||||||
|
Group("park_id", "period").
|
||||||
|
Order("period desc").
|
||||||
|
Limit(config.ServiceSettings.ItemsPageSize).
|
||||||
|
Offset(startItem).
|
||||||
|
ScanAndCount(ctx, &statFees)
|
||||||
|
if err != nil {
|
||||||
|
return make([]model.AdditionalCharge, 0), 0, fmt.Errorf("获取附加费统计信息出现错误,%w", err)
|
||||||
|
}
|
||||||
|
parkIds := lo.Reduce(
|
||||||
|
statFees,
|
||||||
|
func(acc mapset.Set[string], elem _FeeStat, _ int) mapset.Set[string] {
|
||||||
|
acc.Add(elem.ParkId)
|
||||||
|
return acc
|
||||||
|
},
|
||||||
|
mapset.NewSet[string](),
|
||||||
|
)
|
||||||
|
parks := make([]model.Park, 0)
|
||||||
|
if len(parkIds.ToSlice()) > 0 {
|
||||||
|
err = global.DB.NewSelect().Model(&parks).Relation("Enterprise").
|
||||||
|
Where("p.id in (?)", bun.In(parkIds.ToSlice())).
|
||||||
|
Scan(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return make([]model.AdditionalCharge, 0), 0, fmt.Errorf("获取园区信息出现错误,%w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assembledStat := lo.Reduce(
|
||||||
|
statFees,
|
||||||
|
func(acc []model.AdditionalCharge, elem _FeeStat, _ int) []model.AdditionalCharge {
|
||||||
|
park, has := lo.Find(parks, func(p model.Park) bool {
|
||||||
|
return p.Id == elem.ParkId
|
||||||
|
})
|
||||||
|
f.l.Debug("Park detection.", zap.Bool("has", has), zap.Any("park", park))
|
||||||
|
if has {
|
||||||
|
if !park.Area.Valid || park.Area.Decimal.Equal(decimal.Zero) {
|
||||||
|
return acc
|
||||||
|
}
|
||||||
|
price := elem.Total.Div(park.Area.Decimal).RoundBank(8)
|
||||||
|
return append(acc, model.AdditionalCharge{
|
||||||
|
ParkId: elem.ParkId,
|
||||||
|
Period: elem.Period,
|
||||||
|
Fee: elem.Total,
|
||||||
|
Price: price,
|
||||||
|
QuarterPrice: price.Div(decimal.NewFromInt(4)),
|
||||||
|
SemiAnnualPrice: price.Div(decimal.NewFromInt(2)),
|
||||||
|
Enterprise: model.FromUserDetail(*park.Enterprise),
|
||||||
|
Park: park,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return acc
|
||||||
|
}
|
||||||
|
},
|
||||||
|
make([]model.AdditionalCharge, 0),
|
||||||
|
)
|
||||||
|
cache.CacheCount([]string{"maintenance_fee"}, "additional_charge", int64(total), conditions...)
|
||||||
|
cache.CacheSearch(assembledStat, []string{"maintenance_fee"}, "additional_charge", conditions...)
|
||||||
|
return assembledStat, int64(total), nil
|
||||||
}
|
}
|
||||||
|
|||||||
+102
-66
@@ -1,61 +1,73 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
"electricity_bill_calc/cache"
|
"electricity_bill_calc/cache"
|
||||||
"electricity_bill_calc/config"
|
"electricity_bill_calc/config"
|
||||||
"electricity_bill_calc/excel"
|
"electricity_bill_calc/excel"
|
||||||
"electricity_bill_calc/global"
|
"electricity_bill_calc/global"
|
||||||
|
"electricity_bill_calc/logger"
|
||||||
"electricity_bill_calc/model"
|
"electricity_bill_calc/model"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
mapset "github.com/deckarep/golang-set/v2"
|
mapset "github.com/deckarep/golang-set/v2"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"xorm.io/builder"
|
"github.com/uptrace/bun"
|
||||||
"xorm.io/xorm"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type _Meter04kVService struct{}
|
type _Meter04kVService struct {
|
||||||
|
l *zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
var Meter04kVService _Meter04kVService
|
var Meter04kVService = _Meter04kVService{
|
||||||
|
l: logger.Named("Service", "Meter04KV"),
|
||||||
|
}
|
||||||
|
|
||||||
func (_Meter04kVService) ListMeterDetail(park, keyword string, page int) ([]model.Meter04KV, int64, error) {
|
func (_Meter04kVService) ListMeterDetail(park, keyword string, page int) ([]model.Meter04KV, int64, error) {
|
||||||
var condition = make([]string, 0)
|
var (
|
||||||
cond := builder.NewCond().And(builder.Eq{"park_id": park})
|
condition = make([]string, 0)
|
||||||
|
meters = make([]model.Meter04KV, 0)
|
||||||
|
)
|
||||||
|
cond := global.DB.NewSelect().Model(&meters).
|
||||||
|
Where("park_id = ?", park)
|
||||||
condition = append(condition, park, strconv.Itoa(page))
|
condition = append(condition, park, strconv.Itoa(page))
|
||||||
if len(keyword) > 0 {
|
if len(keyword) > 0 {
|
||||||
cond = cond.And(
|
keywordCond := "%" + keyword + "%"
|
||||||
builder.Like{"address", keyword}.
|
cond = cond.WhereGroup(" and ", func(q *bun.SelectQuery) *bun.SelectQuery {
|
||||||
Or(builder.Like{"customer_name", keyword}).
|
return q.Where("address like ?", keywordCond).
|
||||||
Or(builder.Like{"code", keyword}).
|
WhereOr("code like ?", keywordCond).
|
||||||
Or(builder.Like{"contact_name", keyword}).
|
WhereOr("customer_name like ?", keywordCond).
|
||||||
Or(builder.Like{"contact_phone", keyword}))
|
WhereOr("contact_name like ?", keywordCond).
|
||||||
|
WhereOr("contact_phone like ?", keywordCond)
|
||||||
|
})
|
||||||
condition = append(condition, keyword)
|
condition = append(condition, keyword)
|
||||||
}
|
}
|
||||||
var (
|
if cachedTotal, err := cache.RetreiveCount("meter_04kv", condition...); cachedTotal != -1 && err == nil {
|
||||||
total int64
|
if cachedMeters, _ := cache.RetreiveSearch[[]model.Meter04KV]("meter_04kv", condition...); cachedMeters != nil {
|
||||||
err error
|
return *cachedMeters, cachedTotal, nil
|
||||||
)
|
|
||||||
if cachedTotal, _ := cache.RetreiveCount("meter_04kv", condition...); cachedTotal != -1 {
|
|
||||||
total = cachedTotal
|
|
||||||
} else {
|
|
||||||
total, err = global.DBConn.Where(cond).NoAutoCondition().Count(new(model.Meter04KV))
|
|
||||||
if err != nil {
|
|
||||||
return make([]model.Meter04KV, 0), -1, err
|
|
||||||
}
|
}
|
||||||
cache.CacheCount([]string{"meter_04kv", "park"}, "meter_04kv", total, condition...)
|
|
||||||
}
|
}
|
||||||
var meters = make([]model.Meter04KV, 0)
|
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
startItem := (page - 1) * config.ServiceSettings.ItemsPageSize
|
startItem := (page - 1) * config.ServiceSettings.ItemsPageSize
|
||||||
if cachedMeters, _ := cache.RetreiveSearch[[]model.Meter04KV]("meter_04kv", condition...); cachedMeters != nil {
|
total, err := cond.
|
||||||
return *cachedMeters, total, nil
|
Order("seq asc", "code asc").
|
||||||
}
|
Limit(config.ServiceSettings.ItemsPageSize).
|
||||||
err = global.DBConn.
|
Offset(startItem).
|
||||||
Where(cond).
|
ScanAndCount(ctx)
|
||||||
Limit(config.ServiceSettings.ItemsPageSize, startItem).
|
|
||||||
Find(&meters)
|
relations := lo.Map(meters, func(m model.Meter04KV, _ int) string {
|
||||||
cache.CacheSearch(meters, []string{"meter_04kv", "park"}, "meter_04kv", condition...)
|
return fmt.Sprintf("meter_04kv:%s:%s", m.ParkId, m.Code)
|
||||||
return meters, total, err
|
})
|
||||||
|
relations = append(relations, "meter_04kv", "park")
|
||||||
|
|
||||||
|
cache.CacheCount(relations, "meter_04kv", int64(total), condition...)
|
||||||
|
cache.CacheSearch(meters, relations, "meter_04kv", condition...)
|
||||||
|
return meters, int64(total), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_Meter04kVService) Get04kVMeterDetail(park, code string) (*model.Meter04KV, error) {
|
func (_Meter04kVService) Get04kVMeterDetail(park, code string) (*model.Meter04KV, error) {
|
||||||
@@ -63,19 +75,21 @@ func (_Meter04kVService) Get04kVMeterDetail(park, code string) (*model.Meter04KV
|
|||||||
return cachedMeter, nil
|
return cachedMeter, nil
|
||||||
}
|
}
|
||||||
var meter = new(model.Meter04KV)
|
var meter = new(model.Meter04KV)
|
||||||
has, err := global.DBConn.Where(builder.Eq{"code": code, "park_id": park}).NoAutoCondition().Get(meter)
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
err := global.DB.NewSelect().Model(meter).
|
||||||
|
Where("code = ?", code).
|
||||||
|
Where("park_id = ?", park).
|
||||||
|
Scan(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !has {
|
cache.CacheEntity(meter, []string{fmt.Sprintf("meter_04kv:%s:%s", park, code), "park"}, "meter_04kv", fmt.Sprintf("%s_%s", park, code))
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
cache.CacheEntity(meter, []string{fmt.Sprintf("meter_04kv_%s_%s", park, code), "park"}, "meter_04kv", fmt.Sprintf("%s_%s", park, code))
|
|
||||||
return meter, nil
|
return meter, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_Meter04kVService) insertNewMeter(tx *xorm.Session, meter model.Meter04KV) error {
|
func (_Meter04kVService) insertNewMeter(tx *bun.Tx, ctx *context.Context, meter model.Meter04KV) error {
|
||||||
_, err := tx.Insert(meter)
|
_, err := tx.NewInsert().Model(&meter).Exec(*ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
}
|
}
|
||||||
@@ -83,28 +97,28 @@ func (_Meter04kVService) insertNewMeter(tx *xorm.Session, meter model.Meter04KV)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_Meter04kVService) updateMeter(tx *xorm.Session, meter model.Meter04KV) error {
|
func (_Meter04kVService) updateMeter(tx *bun.Tx, ctx *context.Context, meter model.Meter04KV) error {
|
||||||
_, err := tx.
|
_, err := tx.NewUpdate().Model(&meter).
|
||||||
Where(builder.Eq{"code": meter.Code, "park_id": meter.ParkId}).
|
Where("code = ?", meter.Code).
|
||||||
Cols("address", "customer_name", "contact_name", "contact_phone", "ratio", "seq", "public_meter", "dilute", "enabled").
|
Where("park_id = ?", meter.ParkId).
|
||||||
NoAutoCondition().
|
Column("address", "customer_name", "contact_name", "contact_phone", "ratio", "seq", "public_meter", "enabled").
|
||||||
Update(meter)
|
Exec(*ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("meter_04kv")
|
cache.AbolishRelation(fmt.Sprintf("meter_04kv:%s:%s", meter.ParkId, meter.Code))
|
||||||
cache.AbolishRelation(fmt.Sprintf("meter_04kv_%s_%s", meter.ParkId, meter.Code))
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m _Meter04kVService) CreateSingleMeter(meter model.Meter04KV) error {
|
func (m _Meter04kVService) CreateSingleMeter(meter model.Meter04KV) error {
|
||||||
tx := global.DBConn.NewSession()
|
ctx, cancel := global.TimeoutContext()
|
||||||
if err := tx.Begin(); err != nil {
|
defer cancel()
|
||||||
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer tx.Close()
|
|
||||||
|
|
||||||
err := m.insertNewMeter(tx, meter)
|
err = m.insertNewMeter(&tx, &ctx, meter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -114,18 +128,19 @@ func (m _Meter04kVService) CreateSingleMeter(meter model.Meter04KV) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("meter_04kv")
|
cache.AbolishRelation("meter_04kv")
|
||||||
cache.AbolishRelation(fmt.Sprintf("meter_04kv_%s_%s", meter.ParkId, meter.Code))
|
cache.AbolishRelation(fmt.Sprintf("meter_04kv:%s:%s", meter.ParkId, meter.Code))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m _Meter04kVService) UpdateSingleMeter(meter *model.Meter04KV) error {
|
func (m _Meter04kVService) UpdateSingleMeter(meter *model.Meter04KV) error {
|
||||||
tx := global.DBConn.NewSession()
|
ctx, cancel := global.TimeoutContext()
|
||||||
if err := tx.Begin(); err != nil {
|
defer cancel()
|
||||||
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer tx.Close()
|
|
||||||
|
|
||||||
err := m.updateMeter(tx, *meter)
|
err = m.updateMeter(&tx, &ctx, *meter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -134,8 +149,7 @@ func (m _Meter04kVService) UpdateSingleMeter(meter *model.Meter04KV) error {
|
|||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("meter_04kv")
|
cache.AbolishRelation(fmt.Sprintf("meter_04kv:%s:%s", meter.ParkId, meter.Code))
|
||||||
cache.AbolishRelation(fmt.Sprintf("meter_04kv_%s_%s", meter.ParkId, meter.Code))
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,27 +175,49 @@ func (m _Meter04kVService) BatchCreateMeter(meters []model.Meter04KV) error {
|
|||||||
}
|
}
|
||||||
parkId, _ := parkIds.Pop()
|
parkId, _ := parkIds.Pop()
|
||||||
|
|
||||||
|
ctx, cancel := global.TimeoutContext(120)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
allMeterCodes := make([]string, 0)
|
allMeterCodes := make([]string, 0)
|
||||||
err := global.DBConn.Table(&model.Meter04KV{}).Where(builder.Eq{"park_id": parkId}).Select("code").Find(&allMeterCodes)
|
err := global.DB.NewSelect().Model((*model.Meter04KV)(nil)).
|
||||||
|
Where("park_id = ?", parkId).
|
||||||
|
Column("code").
|
||||||
|
Scan(ctx, &allMeterCodes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
meterCodes := mapset.NewSet(allMeterCodes...)
|
meterCodes := mapset.NewSet(allMeterCodes...)
|
||||||
|
|
||||||
tx := global.DBConn.NewSession()
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
if err := tx.Begin(); err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer tx.Close()
|
|
||||||
|
|
||||||
|
var (
|
||||||
|
updates = make([]model.Meter04KV, 0)
|
||||||
|
inserts = make([]model.Meter04KV, 0)
|
||||||
|
)
|
||||||
for _, meter := range meters {
|
for _, meter := range meters {
|
||||||
var err error
|
|
||||||
if meterCodes.Contains(meter.Code) {
|
if meterCodes.Contains(meter.Code) {
|
||||||
err = m.updateMeter(tx, meter)
|
updates = append(updates, meter)
|
||||||
} else {
|
} else {
|
||||||
err = m.insertNewMeter(tx, meter)
|
inserts = append(inserts, meter)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if len(updates) > 0 {
|
||||||
|
_, err = tx.NewUpdate().Model(&updates).
|
||||||
|
Column("address", "customer_name", "contact_name", "contact_phone", "ratio", "seq", "public_meter", "enabled").
|
||||||
|
Bulk().
|
||||||
|
Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(inserts) > 0 {
|
||||||
|
_, err = tx.NewInsert().Model(&inserts).Exec(ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+81
-44
@@ -4,18 +4,26 @@ import (
|
|||||||
"electricity_bill_calc/cache"
|
"electricity_bill_calc/cache"
|
||||||
"electricity_bill_calc/exceptions"
|
"electricity_bill_calc/exceptions"
|
||||||
"electricity_bill_calc/global"
|
"electricity_bill_calc/global"
|
||||||
|
"electricity_bill_calc/logger"
|
||||||
"electricity_bill_calc/model"
|
"electricity_bill_calc/model"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"xorm.io/builder"
|
"github.com/uptrace/bun"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type _ParkService struct{}
|
type _ParkService struct {
|
||||||
|
l *zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
var ParkService _ParkService
|
var ParkService = _ParkService{
|
||||||
|
l: logger.Named("Service", "Park"),
|
||||||
|
}
|
||||||
|
|
||||||
func (_ParkService) SaveNewPark(park model.Park) error {
|
func (_ParkService) SaveNewPark(park model.Park) error {
|
||||||
_, err := global.DBConn.Insert(park)
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
_, err := global.DB.NewInsert().Model(&park).Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -24,68 +32,90 @@ func (_ParkService) SaveNewPark(park model.Park) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (_ParkService) UpdateParkInfo(park *model.Park) error {
|
func (_ParkService) UpdateParkInfo(park *model.Park) error {
|
||||||
rows, err := global.DBConn.
|
ctx, cancel := global.TimeoutContext()
|
||||||
Where(builder.Eq{"id": park.Id, "user_id": park.UserId}).
|
defer cancel()
|
||||||
Cols("name", "abbr", "region", "address", "contact", "phone", "capacity", "tenement_quantity", "category", "meter_04kv_type").
|
res, err := global.DB.NewUpdate().Model(park).
|
||||||
Update(park)
|
Where("id = ?", park.Id).
|
||||||
|
Where("user_id = ?", park.UserId).
|
||||||
|
Column("name", "abbr", "region", "area", "address", "contact", "phone", "capacity", "tenement_quantity", "category", "meter_04kv_type").
|
||||||
|
Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if rows == 0 {
|
if rows, _ := res.RowsAffected(); rows == 0 {
|
||||||
return exceptions.NewNotFoundError("未能找到符合条件的园区。")
|
return exceptions.NewNotFoundError("未能找到符合条件的园区。")
|
||||||
} else {
|
} else {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("park")
|
cache.AbolishRelation(fmt.Sprintf("park:%s", park.Id))
|
||||||
cache.AbolishRelation(fmt.Sprintf("park_%s", park.Id))
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ParkService) ChangeParkState(uid, pid string, state bool) error {
|
func (_ParkService) ChangeParkState(uid, pid string, state bool) error {
|
||||||
rows, err := global.DBConn.
|
ctx, cancel := global.TimeoutContext()
|
||||||
Table(&model.Park{}).
|
defer cancel()
|
||||||
Where(builder.Eq{"id": pid, "user_id": uid}).
|
res, err := global.DB.NewUpdate().Model((*model.Park)(nil)).
|
||||||
Update(map[string]interface{}{"enabled": state})
|
Where("id = ?", pid).
|
||||||
|
Where("user_id = ?", uid).
|
||||||
|
Set("enabled = ?", state).
|
||||||
|
Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if rows == 0 {
|
if rows, _ := res.RowsAffected(); rows == 0 {
|
||||||
return exceptions.NewNotFoundError("未能找到符合条件的园区。")
|
return exceptions.NewNotFoundError("未能找到符合条件的园区。")
|
||||||
} else {
|
} else {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("park")
|
cache.AbolishRelation(fmt.Sprintf("park:%s", pid))
|
||||||
cache.AbolishRelation(fmt.Sprintf("park_%s", pid))
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ParkService) DeletePark(uid, pid string) error {
|
func (_ParkService) DeletePark(uid, pid string) error {
|
||||||
rows, err := global.DBConn.
|
ctx, cancel := global.TimeoutContext()
|
||||||
Where(builder.Eq{"id": pid, "user_id": uid}).
|
defer cancel()
|
||||||
Delete(&model.Park{})
|
res, err := global.DB.NewDelete().Model((*model.Park)(nil)).
|
||||||
|
Where("id = ?", pid).
|
||||||
|
Where("user_id = ?", uid).
|
||||||
|
Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if rows == 0 {
|
if rows, _ := res.RowsAffected(); rows == 0 {
|
||||||
return exceptions.NewNotFoundError("未能找到符合条件的园区。")
|
return exceptions.NewNotFoundError("未能找到符合条件的园区。")
|
||||||
} else {
|
} else {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("park")
|
cache.AbolishRelation("park")
|
||||||
cache.AbolishRelation(fmt.Sprintf("park_%s", pid))
|
cache.AbolishRelation(fmt.Sprintf("park:%s", pid))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ParkService) ListAllParkBelongsTo(uid string) ([]model.Park, error) {
|
func (_ParkService) ListAllParkBelongsTo(uid, keyword string) ([]model.Park, error) {
|
||||||
if parks, _ := cache.RetreiveSearch[[]model.Park]("park", "belong", uid); parks != nil {
|
if parks, _ := cache.RetreiveSearch[[]model.Park]("park", "belong", uid, keyword); parks != nil {
|
||||||
return *parks, nil
|
return *parks, nil
|
||||||
}
|
}
|
||||||
parks := make([]model.Park, 0)
|
parks := make([]model.Park, 0)
|
||||||
err := global.DBConn.
|
cond := global.DB.NewSelect().Model(&parks).
|
||||||
Where(builder.Eq{"user_id": uid}).
|
Where("user_id = ?", uid)
|
||||||
NoAutoCondition().
|
if len(keyword) > 0 {
|
||||||
Find(&parks)
|
keywordCond := "%" + keyword + "%"
|
||||||
|
cond = cond.WhereGroup(" and ", func(q *bun.SelectQuery) *bun.SelectQuery {
|
||||||
|
return q.Where("name like ?", keywordCond).
|
||||||
|
WhereOr("abbr like ?", keywordCond).
|
||||||
|
WhereOr("address like ?", keywordCond).
|
||||||
|
WhereOr("contact like ?", keywordCond).
|
||||||
|
WhereOr("phone like ?", keywordCond)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
err := cond.Scan(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return make([]model.Park, 0), err
|
return make([]model.Park, 0), err
|
||||||
}
|
}
|
||||||
cache.CacheSearch(parks, []string{"park"}, "park", "belong", uid)
|
relations := []string{"park"}
|
||||||
|
for _, p := range parks {
|
||||||
|
relations = append(relations, fmt.Sprintf("park:%s", p.Id))
|
||||||
|
}
|
||||||
|
cache.CacheSearch(parks, relations, "park", "belong", uid, keyword)
|
||||||
return parks, nil
|
return parks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,15 +123,16 @@ func (_ParkService) FetchParkDetail(pid string) (*model.Park, error) {
|
|||||||
if park, _ := cache.RetreiveEntity[model.Park]("park", pid); park != nil {
|
if park, _ := cache.RetreiveEntity[model.Park]("park", pid); park != nil {
|
||||||
return park, nil
|
return park, nil
|
||||||
}
|
}
|
||||||
var park = &model.Park{}
|
ctx, cancel := global.TimeoutContext()
|
||||||
has, err := global.DBConn.ID(pid).NoAutoCondition().Get(park)
|
defer cancel()
|
||||||
|
var park = new(model.Park)
|
||||||
|
err := global.DB.NewSelect().Model(park).
|
||||||
|
Where("id = ?", pid).
|
||||||
|
Scan(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, exceptions.NewNotFoundErrorFromError("未找到符合条件的园区记录。", err)
|
||||||
}
|
}
|
||||||
if !has {
|
cache.CacheEntity(*park, []string{fmt.Sprintf("park:%s", pid)}, "park", pid)
|
||||||
return nil, exceptions.NewNotFoundError("未找到符合条件的园区记录。")
|
|
||||||
}
|
|
||||||
cache.CacheEntity(park, []string{"park"}, "park", pid)
|
|
||||||
return park, nil
|
return park, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,9 +140,14 @@ func (_ParkService) EnsurePark(uid, pid string) (bool, error) {
|
|||||||
if has, _ := cache.CheckExists("park", pid, uid); has {
|
if has, _ := cache.CheckExists("park", pid, uid); has {
|
||||||
return has, nil
|
return has, nil
|
||||||
}
|
}
|
||||||
has, err := global.DBConn.Table(&model.Park{}).Where(builder.Eq{"user_id": uid, "id": pid}).Exist()
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
has, err := global.DB.NewSelect().Model((*model.Park)(nil)).
|
||||||
|
Where("id = ?", pid).
|
||||||
|
Where("user_id = ?", uid).
|
||||||
|
Exists(ctx)
|
||||||
if has {
|
if has {
|
||||||
cache.CacheExists([]string{"park"}, "park", pid, uid)
|
cache.CacheExists([]string{fmt.Sprintf("park:%s", pid)}, "park", pid, uid)
|
||||||
}
|
}
|
||||||
return has, err
|
return has, err
|
||||||
}
|
}
|
||||||
@@ -120,12 +156,13 @@ func (_ParkService) AllParkIds(uid string) ([]string, error) {
|
|||||||
if ids, _ := cache.RetreiveSearch[[]string]("park", "belong", uid); ids != nil {
|
if ids, _ := cache.RetreiveSearch[[]string]("park", "belong", uid); ids != nil {
|
||||||
return *ids, nil
|
return *ids, nil
|
||||||
}
|
}
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
var ids = make([]string, 0)
|
var ids = make([]string, 0)
|
||||||
err := global.DBConn.
|
err := global.DB.NewSelect().Model((*model.Park)(nil)).
|
||||||
Table(new(model.Park)).
|
Where("user_id = ?", uid).
|
||||||
Where(builder.Eq{"user_id": uid}).
|
Column("id").
|
||||||
Cols("id").
|
Scan(ctx, &ids)
|
||||||
Find(&ids)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return make([]string, 0), err
|
return make([]string, 0), err
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-9
@@ -3,25 +3,37 @@ package service
|
|||||||
import (
|
import (
|
||||||
"electricity_bill_calc/cache"
|
"electricity_bill_calc/cache"
|
||||||
"electricity_bill_calc/global"
|
"electricity_bill_calc/global"
|
||||||
|
"electricity_bill_calc/logger"
|
||||||
"electricity_bill_calc/model"
|
"electricity_bill_calc/model"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"xorm.io/builder"
|
"github.com/samber/lo"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type _RegionService struct{}
|
type _RegionService struct {
|
||||||
|
l *zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
var RegionService _RegionService
|
var RegionService = _RegionService{
|
||||||
|
l: logger.Named("Service", "Region"),
|
||||||
|
}
|
||||||
|
|
||||||
func (_RegionService) FetchSubRegions(parent string) ([]model.Region, error) {
|
func (_RegionService) FetchSubRegions(parent string) ([]model.Region, error) {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
if regions, _ := cache.RetreiveSearch[[]model.Region]("region", "parent", parent); regions != nil {
|
if regions, _ := cache.RetreiveSearch[[]model.Region]("region", "parent", parent); regions != nil {
|
||||||
return *regions, nil
|
return *regions, nil
|
||||||
}
|
}
|
||||||
regions := make([]model.Region, 0)
|
regions := make([]model.Region, 0)
|
||||||
err := global.DBConn.Where(builder.Eq{"parent": parent}).Asc("code").Find(®ions)
|
err := global.DB.NewSelect().Model(®ions).Where("parent = ?", parent).Order("code asc").Scan(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return make([]model.Region, 0), err
|
return make([]model.Region, 0), err
|
||||||
}
|
}
|
||||||
cache.CacheSearch(regions, []string{"region"}, "region", "parent", parent)
|
relationNames := lo.Map(regions, func(r model.Region, index int) string {
|
||||||
|
return fmt.Sprintf("region:%s", r.Code)
|
||||||
|
})
|
||||||
|
cache.CacheSearch(regions, relationNames, "region", "parent", parent)
|
||||||
return regions, err
|
return regions, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,13 +55,16 @@ func (r _RegionService) FetchAllParentRegions(code string) ([]model.Region, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (_RegionService) fetchRegion(code string) (*model.Region, error) {
|
func (_RegionService) fetchRegion(code string) (*model.Region, error) {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
if cachedRegion, _ := cache.RetreiveSearch[model.Region]("region", code); cachedRegion != nil {
|
if cachedRegion, _ := cache.RetreiveSearch[model.Region]("region", code); cachedRegion != nil {
|
||||||
return cachedRegion, nil
|
return cachedRegion, nil
|
||||||
}
|
}
|
||||||
region := new(model.Region)
|
region := new(model.Region)
|
||||||
has, err := global.DBConn.ID(code).NoAutoCondition().Get(region)
|
err := global.DB.NewSelect().Model(region).Where("code = ?", code).Scan(ctx)
|
||||||
if has {
|
if err != nil {
|
||||||
cache.CacheSearch(region, []string{"region"}, "region", code)
|
relationName := fmt.Sprintf("region:%s", code)
|
||||||
|
cache.CacheSearch(region, []string{relationName}, "region", code)
|
||||||
}
|
}
|
||||||
return _postProcessSingle(region, has, err)
|
return region, err
|
||||||
}
|
}
|
||||||
|
|||||||
+362
-271
@@ -1,10 +1,12 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"electricity_bill_calc/cache"
|
"electricity_bill_calc/cache"
|
||||||
"electricity_bill_calc/config"
|
"electricity_bill_calc/config"
|
||||||
"electricity_bill_calc/exceptions"
|
"electricity_bill_calc/exceptions"
|
||||||
"electricity_bill_calc/global"
|
"electricity_bill_calc/global"
|
||||||
|
"electricity_bill_calc/logger"
|
||||||
"electricity_bill_calc/model"
|
"electricity_bill_calc/model"
|
||||||
"electricity_bill_calc/tools"
|
"electricity_bill_calc/tools"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -15,60 +17,74 @@ import (
|
|||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
"xorm.io/builder"
|
"github.com/uptrace/bun"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type _ReportService struct{}
|
type _ReportService struct {
|
||||||
|
l *zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
var ReportService _ReportService
|
var ReportService = _ReportService{
|
||||||
|
l: logger.Named("Service", "Report"),
|
||||||
|
}
|
||||||
|
|
||||||
func (_ReportService) FetchParksWithNewestReport(uid string) ([]model.ParkNewestReport, error) {
|
func (_ReportService) FetchParksWithNewestReport(uid string) ([]model.ParkNewestReport, error) {
|
||||||
if cachedParks, _ := cache.RetreiveSearch[[]model.ParkNewestReport]("park_newest_report", uid); cachedParks != nil {
|
if cachedParks, _ := cache.RetreiveSearch[[]model.ParkNewestReport]("park_newest_report", uid); cachedParks != nil {
|
||||||
return *cachedParks, nil
|
return *cachedParks, nil
|
||||||
}
|
}
|
||||||
parks := make([]model.ParkNewestReport, 0)
|
|
||||||
err := global.DBConn.
|
ctx, cancel := global.TimeoutContext()
|
||||||
Alias("p").
|
defer cancel()
|
||||||
Join("LEFT", []string{"report", "r"}, "r.park_id=p.id").
|
parks := make([]model.Park, 0)
|
||||||
Where(builder.Eq{"p.user_id": uid, "p.enabled": true}).
|
err := global.DB.NewSelect().Model(&parks).Relation("Reports").
|
||||||
Find(&parks)
|
Where("user_id = ?", uid).
|
||||||
|
Where("enabled = ?", true).
|
||||||
|
Order("created_at asc").
|
||||||
|
Scan(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return make([]model.ParkNewestReport, 0), err
|
return make([]model.ParkNewestReport, 0), err
|
||||||
}
|
}
|
||||||
|
|
||||||
reducedParks := lo.Reduce(
|
reducedParks := lo.Reduce(
|
||||||
parks,
|
parks,
|
||||||
func(acc map[string]model.ParkNewestReport, elem model.ParkNewestReport, index int) map[string]model.ParkNewestReport {
|
func(acc map[string]model.ParkNewestReport, elem model.Park, index int) map[string]model.ParkNewestReport {
|
||||||
if v, ok := acc[elem.Park.Id]; ok {
|
if _, ok := acc[elem.Id]; !ok {
|
||||||
if elem.Report != nil {
|
newestReport := lo.MaxBy(elem.Reports, func(a, b *model.Report) bool {
|
||||||
if v.Report == nil || (elem.Report.Period.After(v.Report.Period)) {
|
return a.Period.After(b.Period)
|
||||||
acc[elem.Park.Id] = elem
|
})
|
||||||
}
|
acc[elem.Id] = model.ParkNewestReport{
|
||||||
|
Report: newestReport,
|
||||||
|
Park: elem,
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
acc[elem.Park.Id] = elem
|
|
||||||
}
|
}
|
||||||
return acc
|
return acc
|
||||||
},
|
},
|
||||||
make(map[string]model.ParkNewestReport, 0),
|
make(map[string]model.ParkNewestReport, 0),
|
||||||
)
|
)
|
||||||
cache.CacheSearch(reducedParks, []string{"park", "report"}, "park_newest_report", uid)
|
relations := lo.Map(parks, func(r model.Park, _ int) string {
|
||||||
|
return fmt.Sprintf("park:%s", r.Id)
|
||||||
|
})
|
||||||
|
relations = append(relations, "park", "report")
|
||||||
|
cache.CacheSearch(reducedParks, relations, "park_newest_report", uid)
|
||||||
return lo.Values(reducedParks), nil
|
return lo.Values(reducedParks), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ReportService) IsNewPeriodValid(uid string, period time.Time) (bool, error) {
|
func (_ReportService) IsNewPeriodValid(uid, pid string, period time.Time) (bool, error) {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
reports := make([]model.Report, 0)
|
reports := make([]model.Report, 0)
|
||||||
if cachedReport, _ := cache.RetreiveSearch[[]model.Report]("report", "user", uid); cachedReport != nil {
|
if cachedReport, _ := cache.RetreiveSearch[[]model.Report]("report", "user", uid, "park", pid); cachedReport != nil {
|
||||||
reports = *cachedReport
|
reports = *cachedReport
|
||||||
} else {
|
} else {
|
||||||
err := global.DBConn.
|
err := global.DB.NewSelect().Model(&reports).Relation("Park").
|
||||||
Table("report").Alias("r").
|
Where("park.user_id = ?", uid).
|
||||||
Join("INNER", []string{"park", "p"}, "r.park_id=p.id").
|
Where("r.park_id = ?", pid).
|
||||||
Where(builder.Eq{"p.user_id": uid}).
|
Scan(ctx)
|
||||||
Find(&reports)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil
|
return false, err
|
||||||
}
|
}
|
||||||
cache.CacheSearch(reports, []string{"report", "park"}, "park", "user", uid)
|
cache.CacheSearch(reports, []string{"report", "park"}, "park", "user", uid, "park", pid)
|
||||||
}
|
}
|
||||||
// 检查给定的期数在目前的记录中是否已经存在
|
// 检查给定的期数在目前的记录中是否已经存在
|
||||||
exists := lo.Reduce(
|
exists := lo.Reduce(
|
||||||
@@ -122,12 +138,15 @@ func (_ReportService) IsNewPeriodValid(uid string, period time.Time) (bool, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (_ReportService) InitializeNewReport(parkId string, period time.Time) (string, error) {
|
func (_ReportService) InitializeNewReport(parkId string, period time.Time) (string, error) {
|
||||||
|
ctx, cancel := global.TimeoutContext(120)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
periods := make([]model.Report, 0)
|
periods := make([]model.Report, 0)
|
||||||
err := global.DBConn.
|
err := global.DB.NewSelect().Model(&periods).
|
||||||
Table("report").
|
Where("park_id = ?", parkId).
|
||||||
Where(builder.Eq{"park_id": parkId, "published": true}).
|
Where("published = ?", true).
|
||||||
Asc("period").
|
Order("period asc").
|
||||||
Find(&periods)
|
Scan(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -146,7 +165,9 @@ func (_ReportService) InitializeNewReport(parkId string, period time.Time) (stri
|
|||||||
if maxPublishedReport != nil {
|
if maxPublishedReport != nil {
|
||||||
// 获取上一期的所有户表信息,并获取当前已启用的所有用户
|
// 获取上一期的所有户表信息,并获取当前已启用的所有用户
|
||||||
lastPeriodCustomers := make([]model.EndUserDetail, 0)
|
lastPeriodCustomers := make([]model.EndUserDetail, 0)
|
||||||
err = global.DBConn.Where(builder.Eq{"report_id": maxPublishedReport.Id}).Find(&lastPeriodCustomers)
|
err = global.DB.NewSelect().Model(&lastPeriodCustomers).
|
||||||
|
Where("report_id = ?", maxPublishedReport.Id).
|
||||||
|
Scan(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -162,21 +183,25 @@ func (_ReportService) InitializeNewReport(parkId string, period time.Time) (stri
|
|||||||
indexedLastPeriodCustomers = make(map[string]model.EndUserDetail, 0)
|
indexedLastPeriodCustomers = make(map[string]model.EndUserDetail, 0)
|
||||||
}
|
}
|
||||||
currentActivatedCustomers := make([]model.Meter04KV, 0)
|
currentActivatedCustomers := make([]model.Meter04KV, 0)
|
||||||
err = global.DBConn.Where(builder.Eq{"park_id": parkId, "enabled": true}).Find(¤tActivatedCustomers)
|
err = global.DB.NewSelect().Model(¤tActivatedCustomers).
|
||||||
|
Where("park_id = ?", parkId).
|
||||||
|
Where("enabled = ?", true).
|
||||||
|
Scan(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
var parkInfo = new(model.Park)
|
var parkInfo = new(model.Park)
|
||||||
has, err := global.DBConn.ID(parkId).NoAutoCondition().Get(parkInfo)
|
err = global.DB.NewSelect().Model(parkInfo).
|
||||||
if err != nil || !has {
|
Where("id = ?", parkId).
|
||||||
|
Scan(ctx)
|
||||||
|
if err != nil || parkInfo == nil {
|
||||||
return "", exceptions.NewNotFoundError(fmt.Sprintf("指定园区未找到, %v", err))
|
return "", exceptions.NewNotFoundError(fmt.Sprintf("指定园区未找到, %v", err))
|
||||||
}
|
}
|
||||||
// 生成新一期的报表
|
// 生成新一期的报表
|
||||||
tx := global.DBConn.NewSession()
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
if err = tx.Begin(); err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
defer tx.Close()
|
|
||||||
// 插入已经生成的报表索引信息和园区概况信息
|
// 插入已经生成的报表索引信息和园区概况信息
|
||||||
newReport := model.Report{
|
newReport := model.Report{
|
||||||
Id: uuid.New().String(),
|
Id: uuid.New().String(),
|
||||||
@@ -191,12 +216,18 @@ func (_ReportService) InitializeNewReport(parkId string, period time.Time) (stri
|
|||||||
newReportSummary := model.ReportSummary{
|
newReportSummary := model.ReportSummary{
|
||||||
ReportId: newReport.Id,
|
ReportId: newReport.Id,
|
||||||
}
|
}
|
||||||
_, err = tx.Insert(newReport, newReportSummary)
|
_, err = tx.NewInsert().Model(&newReport).Exec(ctx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
_, err = tx.NewInsert().Model(&newReportSummary).Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
// 生成并插入户表信息
|
// 生成并插入户表信息
|
||||||
|
var inserts = make([]model.EndUserDetail, 0)
|
||||||
for _, customer := range currentActivatedCustomers {
|
for _, customer := range currentActivatedCustomers {
|
||||||
newEndUser := model.EndUserDetail{
|
newEndUser := model.EndUserDetail{
|
||||||
ReportId: newReport.Id,
|
ReportId: newReport.Id,
|
||||||
@@ -209,7 +240,6 @@ func (_ReportService) InitializeNewReport(parkId string, period time.Time) (stri
|
|||||||
ContactName: customer.ContactName,
|
ContactName: customer.ContactName,
|
||||||
ContactPhone: customer.ContactPhone,
|
ContactPhone: customer.ContactPhone,
|
||||||
IsPublicMeter: customer.IsPublicMeter,
|
IsPublicMeter: customer.IsPublicMeter,
|
||||||
WillDilute: customer.WillDilute,
|
|
||||||
LastPeriodOverall: decimal.Zero,
|
LastPeriodOverall: decimal.Zero,
|
||||||
LastPeriodCritical: decimal.Zero,
|
LastPeriodCritical: decimal.Zero,
|
||||||
LastPeriodPeak: decimal.Zero,
|
LastPeriodPeak: decimal.Zero,
|
||||||
@@ -223,7 +253,10 @@ func (_ReportService) InitializeNewReport(parkId string, period time.Time) (stri
|
|||||||
newEndUser.LastPeriodFlat = lastPeriod.CurrentPeriodFlat
|
newEndUser.LastPeriodFlat = lastPeriod.CurrentPeriodFlat
|
||||||
newEndUser.LastPeriodValley = lastPeriod.CurrentPeriodValley
|
newEndUser.LastPeriodValley = lastPeriod.CurrentPeriodValley
|
||||||
}
|
}
|
||||||
_, err = tx.Insert(newEndUser)
|
inserts = append(inserts, newEndUser)
|
||||||
|
}
|
||||||
|
if len(inserts) > 0 {
|
||||||
|
_, err = tx.NewInsert().Model(&inserts).Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return "", err
|
return "", err
|
||||||
@@ -242,70 +275,80 @@ func (_ReportService) RetreiveReportIndex(rid string) (*model.Report, error) {
|
|||||||
if cachedReport, _ := cache.RetreiveEntity[model.Report]("report", rid); cachedReport != nil {
|
if cachedReport, _ := cache.RetreiveEntity[model.Report]("report", rid); cachedReport != nil {
|
||||||
return cachedReport, nil
|
return cachedReport, nil
|
||||||
}
|
}
|
||||||
reports := make([]model.Report, 0)
|
ctx, cancel := global.TimeoutContext()
|
||||||
err := global.DBConn.Where(builder.Eq{"id": rid}).Find(&reports)
|
defer cancel()
|
||||||
|
var report = new(model.Report)
|
||||||
|
err := global.DB.NewSelect().Model(report).
|
||||||
|
Where("id = ?", rid).
|
||||||
|
Scan(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(reports) > 0 {
|
cache.CacheEntity(report, []string{fmt.Sprintf("report:%s", rid), "park"}, "report", rid)
|
||||||
cache.CacheEntity(reports[0], []string{fmt.Sprintf("report_%s", rid), "park"}, "report", rid)
|
return report, nil
|
||||||
return &reports[0], nil
|
|
||||||
} else {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ReportService) RetreiveReportSummary(rid string) (*model.ReportSummary, error) {
|
func (_ReportService) RetreiveReportSummary(rid string) (*model.ReportSummary, error) {
|
||||||
if cachedSummary, _ := cache.RetreiveEntity[model.ReportSummary]("report_summary", rid); cachedSummary != nil {
|
if cachedSummary, _ := cache.RetreiveEntity[model.ReportSummary]("report_summary", rid); cachedSummary != nil {
|
||||||
return cachedSummary, nil
|
return cachedSummary, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
var summary = new(model.ReportSummary)
|
var summary = new(model.ReportSummary)
|
||||||
_, err := global.DBConn.ID(rid).NoAutoCondition().Get(summary)
|
err := global.DB.NewSelect().Model(summary).
|
||||||
|
Where("report_id = ?", rid).
|
||||||
|
Scan(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cache.CacheEntity(summary, []string{fmt.Sprintf("report_%s", rid), "park"}, "report_summary", rid)
|
cache.CacheEntity(summary, []string{fmt.Sprintf("report:%s", rid), "park"}, "report_summary", rid)
|
||||||
return summary, nil
|
return summary, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ReportService) UpdateReportSummary(summary *model.ReportSummary) error {
|
func (_ReportService) UpdateReportSummary(summary *model.ReportSummary) error {
|
||||||
_, err := global.DBConn.ID(summary.ReportId).Cols("overall", "overall_fee", "critical", "critical_fee", "peak", "peak_fee", "valley", "valley_fee", "basic_fee", "adjust_fee").Update(summary)
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
_, err := global.DB.NewUpdate().Model(summary).
|
||||||
|
WherePK().
|
||||||
|
Column("overall", "overall_fee", "critical", "critical_fee", "peak", "peak_fee", "valley", "valley_fee", "basic_fee", "adjust_fee").
|
||||||
|
Exec(ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
cache.AbolishRelation(fmt.Sprintf("report_%s", summary.ReportId))
|
cache.AbolishRelation(fmt.Sprintf("report:%s", summary.ReportId))
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ReportService) CalculateSummaryAndFinishStep(reportId string) error {
|
func (_ReportService) CalculateSummaryAndFinishStep(reportId string) error {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
var report = new(model.Report)
|
var report = new(model.Report)
|
||||||
has, err := global.DBConn.ID(reportId).NoAutoCondition().Get(report)
|
err := global.DB.NewSelect().Model(report).Relation("Summary").
|
||||||
|
Where("r.id = ?", reportId).
|
||||||
|
Scan(ctx)
|
||||||
|
if err != nil || report == nil {
|
||||||
|
return exceptions.NewNotFoundErrorFromError("未找到指定报表", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !has {
|
|
||||||
return exceptions.NewNotFoundError("未找到指定报表")
|
report.Summary.CalculatePrices()
|
||||||
}
|
_, err = tx.NewUpdate().Model(report.Summary).
|
||||||
var summary = new(model.ReportSummary)
|
WherePK().
|
||||||
has, err = global.DBConn.ID(reportId).NoAutoCondition().Get(summary)
|
Column("overall_price", "critical_price", "peak_price", "flat", "flat_fee", "flat_price", "valley_price", "consumption_fee").
|
||||||
if err != nil {
|
Exec(ctx)
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !has {
|
|
||||||
return exceptions.NewNotFoundError("未找到指定报表的园区概况")
|
|
||||||
}
|
|
||||||
tx := global.DBConn.NewSession()
|
|
||||||
if err = tx.Begin(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer tx.Close()
|
|
||||||
summary.CalculatePrices()
|
|
||||||
_, err = tx.ID(summary.ReportId).Cols("overall_price", "critical_price", "peak_price", "flat", "flat_fee", "flat_price", "valley_price").Update(summary)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
report.StepState.Summary = true
|
report.StepState.Summary = true
|
||||||
_, err = tx.ID(report.Id).Cols("step_state").Update(report)
|
_, err = tx.NewUpdate().Model(report).
|
||||||
|
WherePK().
|
||||||
|
Column("step_state").
|
||||||
|
Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
@@ -315,7 +358,7 @@ func (_ReportService) CalculateSummaryAndFinishStep(reportId string) error {
|
|||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cache.AbolishRelation(fmt.Sprintf("report_%s", summary.ReportId))
|
cache.AbolishRelation(fmt.Sprintf("report:%s", reportId))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,37 +366,54 @@ func (_ReportService) FetchWillDulutedMaintenanceFees(reportId string) ([]model.
|
|||||||
if cachedFees, _ := cache.RetreiveSearch[[]model.WillDilutedFee]("will_diluted_fee", "report", reportId); cachedFees != nil {
|
if cachedFees, _ := cache.RetreiveSearch[[]model.WillDilutedFee]("will_diluted_fee", "report", reportId); cachedFees != nil {
|
||||||
return *cachedFees, nil
|
return *cachedFees, nil
|
||||||
}
|
}
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
fees := make([]model.WillDilutedFee, 0)
|
fees := make([]model.WillDilutedFee, 0)
|
||||||
err := global.DBConn.Where(builder.Eq{"report_id": reportId}).Asc("created_at").Find(&fees)
|
err := global.DB.NewSelect().Model(&fees).
|
||||||
|
Where("report_id = ?", reportId).
|
||||||
|
Order("created_at asc").
|
||||||
|
Scan(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return make([]model.WillDilutedFee, 0), nil
|
return make([]model.WillDilutedFee, 0), nil
|
||||||
}
|
}
|
||||||
cache.CacheSearch(fees, []string{"will_diluted_fee", fmt.Sprintf("report_%s", reportId), "park"}, "will_diluted_fee", "report", reportId)
|
relations := lo.Map(fees, func(f model.WillDilutedFee, _ int) string {
|
||||||
|
return fmt.Sprintf("will_diluted_fee:%s", f.Id)
|
||||||
|
})
|
||||||
|
relations = append(relations, fmt.Sprintf("report:will_diluted_fee:%s", reportId), fmt.Sprintf("report:%s", reportId), "park")
|
||||||
|
cache.CacheSearch(fees, relations, "will_diluted_fee", "report", reportId)
|
||||||
return fees, nil
|
return fees, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ReportService) CreateTemporaryWillDilutedMaintenanceFee(fee model.WillDilutedFee) error {
|
func (_ReportService) CreateTemporaryWillDilutedMaintenanceFee(fee model.WillDilutedFee) error {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
fee.Id = utils.UUIDString()
|
fee.Id = utils.UUIDString()
|
||||||
_, err := global.DBConn.Insert(fee)
|
_, err := global.DB.NewInsert().Model(&fee).Exec(ctx)
|
||||||
cache.AbolishRelation("will_diluted_fee")
|
cache.AbolishRelation(fmt.Sprintf("report:will_diluted_fee:%s", fee.ReportId))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ReportService) BatchSaveMaintenanceFee(reportId string, fees []model.WillDilutedFee) error {
|
func (_ReportService) BatchSaveMaintenanceFee(reportId string, fees []model.WillDilutedFee) error {
|
||||||
tx := global.DBConn.NewSession()
|
ctx, cancel := global.TimeoutContext()
|
||||||
if err := tx.Begin(); err != nil {
|
defer cancel()
|
||||||
|
|
||||||
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer tx.Close()
|
|
||||||
// 首先删除所有预定义的部分,条件是指定报表ID,SourceID不为空。
|
// 首先删除所有预定义的部分,条件是指定报表ID,SourceID不为空。
|
||||||
cond := builder.Eq{"report_id": reportId}.And(builder.NotNull{"source_id"})
|
_, err = tx.NewDelete().Model((*model.WillDilutedFee)(nil)).
|
||||||
_, err := tx.Table(new(model.WillDilutedFee)).Where(cond).Delete()
|
Where("report_id = ?", reportId).
|
||||||
|
Where("source_id is not null").
|
||||||
|
Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// 然后插入新的记录
|
// 然后插入新的记录
|
||||||
_, err = tx.Insert(fees)
|
_, err = tx.NewInsert().Model(&fees).Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -362,40 +422,69 @@ func (_ReportService) BatchSaveMaintenanceFee(reportId string, fees []model.Will
|
|||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("will_diluted_fee")
|
cache.AbolishRelation(fmt.Sprintf("report:will_diluted_fee:%s", reportId))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ReportService) UpdateMaintenanceFee(feeId string, updates map[string]interface{}) (err error) {
|
func (_ReportService) UpdateMaintenanceFee(feeId string, updates map[string]interface{}) (err error) {
|
||||||
_, err = global.DBConn.Table(new(model.WillDilutedFee)).ID(feeId).Update(updates)
|
ctx, cancel := global.TimeoutContext()
|
||||||
cache.AbolishRelation("will_diluted_fee")
|
defer cancel()
|
||||||
|
|
||||||
|
updates["last_modified_at"] = lo.ToPtr(time.Now())
|
||||||
|
_, err = global.DB.NewUpdate().Model(&updates).TableExpr("will_diluted_fee").
|
||||||
|
Where("id = ?", feeId).
|
||||||
|
Exec(ctx)
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("will_diluted_fee:%s", feeId))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ReportService) DeleteWillDilutedFee(fee string) (err error) {
|
func (_ReportService) DeleteWillDilutedFee(fee string) (err error) {
|
||||||
_, err = global.DBConn.ID(fee).NoAutoCondition().Delete(new(model.WillDilutedFee))
|
ctx, cancel := global.TimeoutContext()
|
||||||
cache.AbolishRelation("will_diluted_fee")
|
defer cancel()
|
||||||
|
|
||||||
|
_, err = global.DB.NewDelete().Model((*model.WillDilutedFee)(nil)).
|
||||||
|
Where("id = ?", fee).
|
||||||
|
Exec(ctx)
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("will_diluted_fee:%s", fee))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ReportService) ProgressReportWillDilutedFee(report model.Report) (err error) {
|
func (_ReportService) ProgressReportWillDilutedFee(report model.Report) (err error) {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
report.StepState.WillDiluted = true
|
report.StepState.WillDiluted = true
|
||||||
_, err = global.DBConn.ID(report.Id).Cols("step_state").Update(report)
|
_, err = global.DB.NewUpdate().Model(&report).
|
||||||
cache.AbolishRelation(fmt.Sprintf("report_%s", report.Id))
|
WherePK().
|
||||||
|
Column("step_state").
|
||||||
|
Exec(ctx)
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("report:%s", report.Id))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ReportService) ProgressReportRegisterEndUser(report model.Report) (err error) {
|
func (_ReportService) ProgressReportRegisterEndUser(report model.Report) (err error) {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
report.StepState.Submeter = true
|
report.StepState.Submeter = true
|
||||||
_, err = global.DBConn.ID(report.Id).Cols("step_state").Update(report)
|
_, err = global.DB.NewUpdate().Model(&report).
|
||||||
cache.AbolishRelation(fmt.Sprintf("report_%s", report.Id))
|
WherePK().
|
||||||
|
Column("step_state").
|
||||||
|
Exec(ctx)
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("report:%s", report.Id))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ReportService) ProgressReportCalculate(report model.Report) (err error) {
|
func (_ReportService) ProgressReportCalculate(report model.Report) (err error) {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
report.StepState.Calculate = true
|
report.StepState.Calculate = true
|
||||||
_, err = global.DBConn.ID(report.Id).Cols("step_state").Update(report)
|
_, err = global.DB.NewUpdate().Model(&report).
|
||||||
cache.AbolishRelation(fmt.Sprintf("report_%s", report.Id))
|
WherePK().
|
||||||
|
Column("step_state").
|
||||||
|
Exec(ctx)
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("report:%s", report.Id))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,92 +492,104 @@ func (_ReportService) RetreiveParkEndUserMeterType(reportId string) (int, error)
|
|||||||
if cachedType, _ := cache.RetreiveEntity[int]("park_end_user_meter_type", fmt.Sprintf("report_%s", reportId)); cachedType != nil {
|
if cachedType, _ := cache.RetreiveEntity[int]("park_end_user_meter_type", fmt.Sprintf("report_%s", reportId)); cachedType != nil {
|
||||||
return *cachedType, nil
|
return *cachedType, nil
|
||||||
}
|
}
|
||||||
var types = make([]int, 0)
|
ctx, cancel := global.TimeoutContext()
|
||||||
err := global.DBConn.
|
defer cancel()
|
||||||
Table("park").Alias("p").
|
|
||||||
Join("INNER", []string{"report", "r"}, "r.park_id=p.id").
|
var mType int
|
||||||
Where(builder.Eq{"r.id": reportId}).
|
err := global.DB.NewSelect().Model((*model.Report)(nil)).
|
||||||
Select("p.meter_04kv_type").
|
Relation("Park", func(q *bun.SelectQuery) *bun.SelectQuery {
|
||||||
Find(&types)
|
return q.Column("meter_04kv_type")
|
||||||
|
}).
|
||||||
|
ExcludeColumn("*").
|
||||||
|
Where("r.id = ?", reportId).
|
||||||
|
Scan(ctx, &mType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
if len(types) == 0 {
|
cache.CacheEntity(mType, []string{fmt.Sprintf("report:%s", reportId), "park"}, "park_end_user_meter_type", fmt.Sprintf("report_%s", reportId))
|
||||||
return -1, nil
|
return mType, nil
|
||||||
}
|
|
||||||
cache.CacheEntity(types[0], []string{fmt.Sprintf("report_%s", reportId), "park"}, "park_end_user_meter_type", fmt.Sprintf("report_%s", reportId))
|
|
||||||
return types[0], nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ReportService) PublishReport(report model.Report) (err error) {
|
func (_ReportService) PublishReport(report model.Report) (err error) {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
report.Published = true
|
report.Published = true
|
||||||
report.PublishedAt = lo.ToPtr(time.Now())
|
report.PublishedAt = lo.ToPtr(time.Now())
|
||||||
report.StepState.Publish = true
|
report.StepState.Publish = true
|
||||||
_, err = global.DBConn.ID(report.Id).Cols("step_state", "published", "published_at").Update(report)
|
_, err = global.DB.NewUpdate().Model(&report).
|
||||||
cache.AbolishRelation("report")
|
WherePK().
|
||||||
cache.AbolishRelation(fmt.Sprintf("report_%s", report.Id))
|
Column("step_state", "published", "published_at").
|
||||||
|
Exec(ctx)
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("report:%s", report.Id))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ReportService) SearchReport(requestUser, requestPark, requestKeyword string, requestPeriod *time.Time, requestPage int) ([]model.JoinedReportForWithdraw, int64, error) {
|
func (_ReportService) SearchReport(requestUser, requestPark, requestKeyword string, requestPeriod *time.Time, requestPage int, onlyPublished bool) ([]model.JoinedReportForWithdraw, int64, error) {
|
||||||
var conditions = make([]string, 0)
|
var (
|
||||||
|
conditions = make([]string, 0)
|
||||||
|
reports = make([]model.Report, 0)
|
||||||
|
cond = global.DB.NewSelect().
|
||||||
|
Model(&reports).
|
||||||
|
Relation("Park").Relation("Park.Enterprise")
|
||||||
|
)
|
||||||
conditions = append(conditions, strconv.Itoa(requestPage))
|
conditions = append(conditions, strconv.Itoa(requestPage))
|
||||||
cond := builder.NewCond().And(builder.Eq{"r.published": true})
|
if onlyPublished {
|
||||||
|
cond = cond.Where("r.published = ?", true)
|
||||||
|
}
|
||||||
|
conditions = append(conditions, strconv.FormatBool(onlyPublished))
|
||||||
if len(requestUser) > 0 {
|
if len(requestUser) > 0 {
|
||||||
cond = cond.And(builder.Eq{"u.id": requestUser})
|
cond = cond.Where("park.user_id = ?", requestUser)
|
||||||
conditions = append(conditions, requestUser)
|
conditions = append(conditions, requestUser)
|
||||||
}
|
}
|
||||||
if len(requestPark) > 0 {
|
if len(requestPark) > 0 {
|
||||||
cond = cond.And(builder.Eq{"p.id": requestPark})
|
cond = cond.Where("park.id = ?", requestPark)
|
||||||
conditions = append(conditions, requestPark)
|
conditions = append(conditions, requestPark)
|
||||||
}
|
}
|
||||||
if requestPeriod != nil {
|
if requestPeriod != nil {
|
||||||
cond = cond.And(builder.Eq{"r.period": *requestPeriod})
|
cond = cond.Where("r.period = ?", *requestPeriod)
|
||||||
conditions = append(conditions, strconv.FormatInt(requestPeriod.Unix(), 10))
|
conditions = append(conditions, strconv.FormatInt(requestPeriod.Unix(), 10))
|
||||||
}
|
}
|
||||||
if len(requestKeyword) > 0 {
|
if len(requestKeyword) > 0 {
|
||||||
cond = cond.And(
|
keywordCond := "%" + requestKeyword + "%"
|
||||||
builder.Like{"u.name", requestKeyword}.
|
cond = cond.WhereGroup(" and ", func(q *bun.SelectQuery) *bun.SelectQuery {
|
||||||
Or(builder.Like{"p.name", requestKeyword}).
|
return q.Where("park.name like ?", keywordCond).
|
||||||
Or(builder.Like{"u.abbr", requestKeyword}).
|
WhereOr("park__enterprise.name like ?", keywordCond).
|
||||||
Or(builder.Like{"p.abbr", requestKeyword}).
|
WhereOr("park__enterprise.abbr like ?", keywordCond).
|
||||||
Or(builder.Like{"u.address", requestKeyword}).
|
WhereOr("park.abbr like ?", keywordCond).
|
||||||
Or(builder.Like{"p.address", requestKeyword}),
|
WhereOr("park__enterprise.address like ?", keywordCond).
|
||||||
)
|
WhereOr("park.address like ?", keywordCond)
|
||||||
|
})
|
||||||
conditions = append(conditions, requestKeyword)
|
conditions = append(conditions, requestKeyword)
|
||||||
}
|
}
|
||||||
var (
|
if cachedTotal, err := cache.RetreiveCount("join_report_for_withdraw", conditions...); cachedTotal != -1 && err == nil {
|
||||||
total int64
|
if cachedRecords, _ := cache.RetreiveSearch[[]model.JoinedReportForWithdraw]("join_report_for_withdraw", conditions...); cachedRecords != nil {
|
||||||
err error
|
return *cachedRecords, cachedTotal, nil
|
||||||
)
|
|
||||||
if cachedTotal, _ := cache.RetreiveCount("join_report_for_withdraw", conditions...); cachedTotal != -1 {
|
|
||||||
total = cachedTotal
|
|
||||||
} else {
|
|
||||||
total, err := global.DBConn.
|
|
||||||
Table("report").Alias("r").
|
|
||||||
Join("INNER", []string{"park", "p"}, "p.id=r.park_id").
|
|
||||||
Join("INNER", []string{"user_detail", "u"}, "u.id=p.user_id").
|
|
||||||
Where(cond).
|
|
||||||
Count()
|
|
||||||
if err != nil {
|
|
||||||
return make([]model.JoinedReportForWithdraw, 0), -1, err
|
|
||||||
}
|
}
|
||||||
cache.CacheCount([]string{"report", "park"}, "join_report_for_withdraw", total, conditions...)
|
|
||||||
}
|
}
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
startItem := (requestPage - 1) * config.ServiceSettings.ItemsPageSize
|
startItem := (requestPage - 1) * config.ServiceSettings.ItemsPageSize
|
||||||
if cachedRecords, _ := cache.RetreiveSearch[[]model.JoinedReportForWithdraw]("join_report_for_withdraw", conditions...); cachedRecords != nil {
|
|
||||||
return *cachedRecords, total, nil
|
total, err := cond.Limit(config.ServiceSettings.ItemsPageSize).
|
||||||
}
|
Offset(startItem).
|
||||||
|
ScanAndCount(ctx)
|
||||||
|
|
||||||
records := make([]model.JoinedReportForWithdraw, 0)
|
records := make([]model.JoinedReportForWithdraw, 0)
|
||||||
err = global.DBConn.
|
relations := []string{"report", "park"}
|
||||||
Table("report").Alias("r").
|
for _, r := range reports {
|
||||||
Join("INNER", []string{"park", "p"}, "p.id=r.park_id").
|
records = append(records, model.JoinedReportForWithdraw{
|
||||||
Join("INNER", []string{"user_detail", "u"}, "u.id=p.user_id").
|
Report: r,
|
||||||
Where(cond).
|
Park: model.FromPark(*r.Park),
|
||||||
Limit(config.ServiceSettings.ItemsPageSize, startItem).
|
User: model.FromUserDetail(*r.Park.Enterprise),
|
||||||
Find(&records)
|
})
|
||||||
cache.CacheSearch(records, []string{"report", "park"}, "join_report_for_withdraw", conditions...)
|
relations = append(relations, fmt.Sprintf("report:%s", r.Id))
|
||||||
return records, total, err
|
}
|
||||||
|
|
||||||
|
cache.CacheCount(relations, "join_report_for_withdraw", int64(total), conditions...)
|
||||||
|
cache.CacheSearch(records, relations, "join_report_for_withdraw", conditions...)
|
||||||
|
return records, int64(total), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ReportService) AssembleReportPublicity(reportId string) (*model.Publicity, error) {
|
func (_ReportService) AssembleReportPublicity(reportId string) (*model.Publicity, error) {
|
||||||
@@ -496,147 +597,137 @@ func (_ReportService) AssembleReportPublicity(reportId string) (*model.Publicity
|
|||||||
return cachedPublicity, nil
|
return cachedPublicity, nil
|
||||||
}
|
}
|
||||||
// 资料准备
|
// 资料准备
|
||||||
var reportIndex = new(model.Report)
|
ctx, cancel := global.TimeoutContext()
|
||||||
has, err := global.DBConn.ID(reportId).NoAutoCondition().Get(reportIndex)
|
defer cancel()
|
||||||
if err != nil || !has {
|
|
||||||
|
var report = new(model.Report)
|
||||||
|
err := global.DB.NewSelect().Model(report).
|
||||||
|
Relation("Summary").Relation("WillDilutedFees").Relation("EndUsers").
|
||||||
|
Relation("Park").Relation("Park.Enterprise").
|
||||||
|
Where("r.id = ?", reportId).
|
||||||
|
Scan(ctx)
|
||||||
|
if err != nil {
|
||||||
return nil, exceptions.NewNotFoundErrorFromError("未找到指定的公示报表", err)
|
return nil, exceptions.NewNotFoundErrorFromError("未找到指定的公示报表", err)
|
||||||
}
|
}
|
||||||
var summary = new(model.ReportSummary)
|
|
||||||
has, err = global.DBConn.ID(reportId).NoAutoCondition().Get(summary)
|
|
||||||
if err != nil || !has {
|
|
||||||
return nil, exceptions.NewNotFoundErrorFromError("未找到指定的公示报表概览", err)
|
|
||||||
}
|
|
||||||
var maintenanceFeeRecords = make([]model.WillDilutedFee, 0)
|
|
||||||
err = global.DBConn.Where(builder.Eq{"report_id": reportId}).Find(&maintenanceFeeRecords)
|
|
||||||
if err != nil {
|
|
||||||
return nil, exceptions.NewNotFoundErrorFromError("未能获取到公示报表对应的待摊薄费用信息", err)
|
|
||||||
}
|
|
||||||
var endUserDetails = make([]model.EndUserDetail, 0)
|
|
||||||
err = global.DBConn.Where(builder.Eq{"report_id": reportId}).Find(&endUserDetails)
|
|
||||||
if err != nil {
|
|
||||||
return nil, exceptions.NewNotFoundErrorFromError("未获取到公示报表对应的终端用户抄表信息", err)
|
|
||||||
}
|
|
||||||
parkDetail, err := ParkService.FetchParkDetail(reportIndex.ParkId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, exceptions.NewNotFoundErrorFromError("未找到公示报表对应的园区信息", err)
|
|
||||||
}
|
|
||||||
userDetail, err := UserService.retreiveUserDetail(parkDetail.UserId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, exceptions.NewNotFoundErrorFromError("未找到公示报表对应的企业信息", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 组合数据
|
// 组合数据
|
||||||
paidPart := model.PaidPart{
|
paidPart := model.PaidPart{
|
||||||
Overall: summary.Overall,
|
Overall: report.Summary.Overall,
|
||||||
OverallPrice: summary.OverallPrice.Decimal,
|
OverallPrice: report.Summary.OverallPrice.Decimal,
|
||||||
ConsumptionFee: summary.ConsumptionFee.Decimal,
|
ConsumptionFee: report.Summary.ConsumptionFee.Decimal,
|
||||||
OverallFee: summary.OverallFee,
|
OverallFee: report.Summary.OverallFee,
|
||||||
Critical: decimal.NewNullDecimal(summary.Critical),
|
Critical: decimal.NewNullDecimal(report.Summary.Critical),
|
||||||
CriticalPrice: summary.CriticalPrice,
|
CriticalPrice: report.Summary.CriticalPrice,
|
||||||
CriticalFee: decimal.NewNullDecimal(summary.CriticalFee),
|
CriticalFee: decimal.NewNullDecimal(report.Summary.CriticalFee),
|
||||||
Peak: decimal.NewNullDecimal(summary.Peak),
|
Peak: decimal.NewNullDecimal(report.Summary.Peak),
|
||||||
PeakPrice: summary.PeakPrice,
|
PeakPrice: report.Summary.PeakPrice,
|
||||||
PeakFee: decimal.NewNullDecimal(summary.PeakFee),
|
PeakFee: decimal.NewNullDecimal(report.Summary.PeakFee),
|
||||||
Flat: decimal.NewNullDecimal(summary.Flat),
|
Flat: decimal.NewNullDecimal(report.Summary.Flat),
|
||||||
FlatPrice: summary.FlatPrice,
|
FlatPrice: report.Summary.FlatPrice,
|
||||||
FlatFee: decimal.NewNullDecimal(summary.FlatFee),
|
FlatFee: decimal.NewNullDecimal(report.Summary.FlatFee),
|
||||||
Valley: decimal.NewNullDecimal(summary.Valley),
|
Valley: decimal.NewNullDecimal(report.Summary.Valley),
|
||||||
ValleyPrice: summary.ValleyPrice,
|
ValleyPrice: report.Summary.ValleyPrice,
|
||||||
ValleyFee: decimal.NewNullDecimal(summary.ValleyFee),
|
ValleyFee: decimal.NewNullDecimal(report.Summary.ValleyFee),
|
||||||
BasicFee: summary.BasicFee,
|
BasicFee: report.Summary.BasicFee,
|
||||||
AdjustFee: summary.AdjustFee,
|
AdjustFee: report.Summary.AdjustFee,
|
||||||
}
|
}
|
||||||
endUserSummary := model.EndUserOverallPart{
|
endUserSummary := model.ConsumptionOverallPart{
|
||||||
Overall: summary.CustomerConsumption.Decimal,
|
Overall: report.Summary.Customers.Consumption.Decimal,
|
||||||
OverallPrice: summary.OverallPrice.Decimal,
|
OverallPrice: report.Summary.OverallPrice.Decimal,
|
||||||
OverallFee: summary.CustomerConsumptionFee.Decimal,
|
ConsumptionFee: report.Summary.Customers.ConsumptionFee.Decimal,
|
||||||
Critical: summary.CustomerConsumptionCritical,
|
OverallFee: report.Summary.Customers.ConsumptionFee.Decimal,
|
||||||
CriticalPrice: summary.CriticalPrice,
|
Critical: report.Summary.Customers.Critical,
|
||||||
CriticalFee: summary.CustomerConsumptionCriticalFee,
|
CriticalPrice: report.Summary.CriticalPrice,
|
||||||
Peak: summary.CustomerConsumptionPeak,
|
CriticalFee: report.Summary.Customers.CriticalFee,
|
||||||
PeakPrice: summary.PeakPrice,
|
Peak: report.Summary.Customers.Peak,
|
||||||
PeakFee: summary.CustomerConsumptionPeakFee,
|
PeakPrice: report.Summary.PeakPrice,
|
||||||
Flat: summary.CustomerConsumptionFlat,
|
PeakFee: report.Summary.Customers.PeakFee,
|
||||||
FlatPrice: summary.FlatPrice,
|
Flat: report.Summary.Customers.Flat,
|
||||||
FlatFee: summary.CustomerConsumptionFlatFee,
|
FlatPrice: report.Summary.FlatPrice,
|
||||||
Valley: summary.CustomerConsumptionValley,
|
FlatFee: report.Summary.Customers.FlatFee,
|
||||||
ValleyPrice: summary.ValleyPrice,
|
Valley: report.Summary.Customers.Valley,
|
||||||
ValleyFee: summary.CustomerConsumptionValleyFee,
|
ValleyPrice: report.Summary.ValleyPrice,
|
||||||
|
ValleyFee: report.Summary.Customers.ValleyFee,
|
||||||
|
Proportion: report.Summary.Customers.Proportion.Decimal,
|
||||||
}
|
}
|
||||||
lossPart := model.LossPart{
|
lossPart := model.LossPart{
|
||||||
Quantity: summary.Loss.Decimal,
|
Quantity: report.Summary.Loss.Decimal,
|
||||||
Price: summary.OverallPrice.Decimal,
|
Price: report.Summary.OverallPrice.Decimal,
|
||||||
ConsumptionFee: summary.LossFee.Decimal,
|
ConsumptionFee: report.Summary.LossFee.Decimal,
|
||||||
Proportion: summary.LossProportion.Decimal,
|
Proportion: report.Summary.LossProportion.Decimal,
|
||||||
|
AuthorizeQuantity: report.Summary.AuthorizeLoss.Decimal,
|
||||||
|
AuthorizeConsumptionFee: report.Summary.AuthorizeLossFee.Decimal,
|
||||||
}
|
}
|
||||||
publicSummary := model.PublicConsumptionOverallPart{
|
publicSummary := model.ConsumptionOverallPart{
|
||||||
Overall: summary.PublicConsumption.Decimal,
|
Overall: report.Summary.Publics.Consumption.Decimal,
|
||||||
OverallPrice: summary.OverallPrice.Decimal,
|
OverallPrice: report.Summary.OverallPrice.Decimal,
|
||||||
OverallFee: summary.PublicConsumptionFee.Decimal,
|
ConsumptionFee: report.Summary.Publics.ConsumptionFee.Decimal,
|
||||||
Critical: summary.PublicConsumptionCritical,
|
OverallFee: report.Summary.Publics.ConsumptionFee.Decimal,
|
||||||
CriticalPrice: summary.CriticalPrice,
|
Critical: report.Summary.Publics.Critical,
|
||||||
CriticalFee: summary.PublicConsumptionCriticalFee,
|
CriticalPrice: report.Summary.CriticalPrice,
|
||||||
Peak: summary.PublicConsumptionPeak,
|
CriticalFee: report.Summary.Publics.CriticalFee,
|
||||||
PeakPrice: summary.PeakPrice,
|
Peak: report.Summary.Publics.Peak,
|
||||||
PeakFee: summary.PublicConsumptionPeakFee,
|
PeakPrice: report.Summary.PeakPrice,
|
||||||
Flat: summary.PublicConsumptionFlat,
|
PeakFee: report.Summary.Publics.PeakFee,
|
||||||
FlatPrice: summary.FlatPrice,
|
Flat: report.Summary.Publics.Flat,
|
||||||
FlatFee: summary.PublicConsumptionFlatFee,
|
FlatPrice: report.Summary.FlatPrice,
|
||||||
Valley: summary.PublicConsumptionValley,
|
FlatFee: report.Summary.Publics.FlatFee,
|
||||||
ValleyPrice: summary.ValleyPrice,
|
Valley: report.Summary.Publics.Valley,
|
||||||
ValleyFee: summary.PublicConsumptionValleyFee,
|
ValleyPrice: report.Summary.ValleyPrice,
|
||||||
|
ValleyFee: report.Summary.Publics.ValleyFee,
|
||||||
|
Proportion: report.Summary.Publics.Proportion.Decimal,
|
||||||
}
|
}
|
||||||
otherCollection := model.OtherShouldCollectionPart{
|
otherCollection := model.OtherShouldCollectionPart{
|
||||||
MaintenanceFee: summary.FinalDilutedOverall,
|
LossFee: report.Summary.AuthorizeLossFee,
|
||||||
BasicFees: summary.BasicFee.Add(summary.AdjustFee),
|
BasicFees: report.Summary.BasicFee.Add(report.Summary.AdjustFee),
|
||||||
}
|
}
|
||||||
finalMaintenance := lossPart.ConsumptionFee.Add(publicSummary.ConsumptionFee).Add(otherCollection.MaintenanceFee.Decimal).Add(otherCollection.BasicFees)
|
finalAdjustFee := lossPart.AuthorizeConsumptionFee.Add(otherCollection.BasicFees)
|
||||||
var maintenancePrice = decimal.Zero
|
var adjustPrice = decimal.Zero
|
||||||
if !endUserSummary.Overall.Equal(decimal.Zero) {
|
if !endUserSummary.Overall.Equal(decimal.Zero) {
|
||||||
maintenancePrice = finalMaintenance.Div(endUserSummary.Overall).RoundBank(8)
|
adjustPrice = finalAdjustFee.Div(endUserSummary.Overall).RoundBank(8)
|
||||||
}
|
}
|
||||||
var maintenanceProportion = decimal.Zero
|
var adjustProportion = decimal.Zero
|
||||||
if !paidPart.OverallFee.Equal(decimal.Zero) || !otherCollection.MaintenanceFee.Decimal.Equal(decimal.Zero) {
|
if !paidPart.OverallFee.Equal(decimal.Zero) {
|
||||||
maintenanceProportion = finalMaintenance.Div(paidPart.OverallFee.Add(otherCollection.MaintenanceFee.Decimal)).RoundBank(8)
|
adjustProportion = finalAdjustFee.Div(paidPart.OverallFee.Add(finalAdjustFee)).RoundBank(8)
|
||||||
}
|
|
||||||
var priceRatio = decimal.Zero
|
|
||||||
if !summary.OverallPrice.Decimal.Equal(decimal.Zero) {
|
|
||||||
priceRatio = maintenancePrice.Div(summary.OverallPrice.Decimal).RoundBank(8)
|
|
||||||
}
|
}
|
||||||
maintenanceFees := model.MaintenancePart{
|
maintenanceFees := model.MaintenancePart{
|
||||||
BasicFees: otherCollection.BasicFees,
|
BasicFees: otherCollection.BasicFees,
|
||||||
LossFee: lossPart.ConsumptionFee,
|
LossFee: lossPart.AuthorizeConsumptionFee,
|
||||||
PublicConsumptionFee: publicSummary.ConsumptionFee,
|
AdjustFee: finalAdjustFee,
|
||||||
MaintenanceFee: otherCollection.MaintenanceFee.Decimal,
|
LossProportion: lossPart.Proportion,
|
||||||
FinalMaintenance: finalMaintenance,
|
AdjustPrice: adjustPrice,
|
||||||
MaintenanceProportion: maintenanceProportion,
|
AdjustProportion: adjustProportion,
|
||||||
MaintenancePrice: maintenancePrice,
|
}
|
||||||
PriceRatio: priceRatio,
|
if maintenanceFees.LossProportion.GreaterThan(decimal.NewFromFloat(0.1)) {
|
||||||
|
maintenanceFees.LossProportion = decimal.NewFromFloat(0.1)
|
||||||
}
|
}
|
||||||
endUsers := lo.Map(
|
endUsers := lo.Map(
|
||||||
endUserDetails,
|
report.EndUsers,
|
||||||
func(elem model.EndUserDetail, index int) model.EndUserSummary {
|
func(elem *model.EndUserDetail, index int) model.EndUserSummary {
|
||||||
return model.EndUserSummary{
|
return model.EndUserSummary{
|
||||||
CustomerName: elem.CustomerName,
|
CustomerName: elem.CustomerName,
|
||||||
Address: elem.Address,
|
Address: elem.Address,
|
||||||
MeterId: elem.MeterId,
|
MeterId: elem.MeterId,
|
||||||
Overall: elem.Overall.Decimal,
|
IsPublicMeter: elem.IsPublicMeter,
|
||||||
OverallFee: elem.OverallFee.Decimal,
|
Overall: elem.Overall.Decimal,
|
||||||
Critical: elem.Critical,
|
OverallPrice: report.Summary.OverallPrice.Decimal,
|
||||||
CriticalFee: elem.CriticalFee,
|
OverallFee: elem.OverallFee.Decimal,
|
||||||
Peak: elem.Peak,
|
Critical: elem.Critical,
|
||||||
PeakFee: elem.PeakFee,
|
CriticalFee: elem.CriticalFee,
|
||||||
Valley: elem.Valley,
|
Peak: elem.Peak,
|
||||||
ValleyFee: elem.ValleyFee,
|
PeakFee: elem.PeakFee,
|
||||||
Maintenance: elem.FinalDiluted.Decimal,
|
Valley: elem.Valley,
|
||||||
|
ValleyFee: elem.ValleyFee,
|
||||||
|
Loss: elem.LossDiluted.Decimal,
|
||||||
|
LossFee: elem.LossFeeDiluted.Decimal,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
publicity := &model.Publicity{
|
publicity := &model.Publicity{
|
||||||
Report: *reportIndex,
|
Report: *report,
|
||||||
Park: *parkDetail,
|
Park: *report.Park,
|
||||||
User: *userDetail,
|
User: *report.Park.Enterprise,
|
||||||
Paid: paidPart,
|
Paid: paidPart,
|
||||||
EndUser: endUserSummary,
|
EndUser: endUserSummary,
|
||||||
Loss: lossPart,
|
Loss: lossPart,
|
||||||
@@ -645,7 +736,7 @@ func (_ReportService) AssembleReportPublicity(reportId string) (*model.Publicity
|
|||||||
Maintenance: maintenanceFees,
|
Maintenance: maintenanceFees,
|
||||||
EndUserDetails: endUsers,
|
EndUserDetails: endUsers,
|
||||||
}
|
}
|
||||||
cache.CacheEntity(publicity, []string{fmt.Sprintf("publicity_%s", reportId), "report", "park"}, "publicity", reportId)
|
cache.CacheEntity(publicity, []string{fmt.Sprintf("publicity:%s", reportId), fmt.Sprintf("report:%s", reportId), "report", "park"}, "publicity", reportId)
|
||||||
|
|
||||||
return publicity, nil
|
return publicity, nil
|
||||||
}
|
}
|
||||||
|
|||||||
+41
-28
@@ -3,70 +3,83 @@ package service
|
|||||||
import (
|
import (
|
||||||
"electricity_bill_calc/cache"
|
"electricity_bill_calc/cache"
|
||||||
"electricity_bill_calc/global"
|
"electricity_bill_calc/global"
|
||||||
|
"electricity_bill_calc/logger"
|
||||||
"electricity_bill_calc/model"
|
"electricity_bill_calc/model"
|
||||||
|
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"xorm.io/builder"
|
"github.com/uptrace/bun"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type _StatisticsService struct{}
|
type _StatisticsService struct {
|
||||||
|
l *zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
var StatisticsService _StatisticsService
|
var StatisticsService = _StatisticsService{
|
||||||
|
l: logger.Named("Service", "Stat"),
|
||||||
|
}
|
||||||
|
|
||||||
func (_StatisticsService) EnabledEnterprises() (int64, error) {
|
func (_StatisticsService) EnabledEnterprises() (int64, error) {
|
||||||
if cachedCount, _ := cache.RetreiveCount("enabled_ent"); cachedCount != -1 {
|
if cachedCount, err := cache.RetreiveCount("enabled_ent"); cachedCount != -1 && err == nil {
|
||||||
return cachedCount, nil
|
return cachedCount, nil
|
||||||
}
|
}
|
||||||
c, err := global.DBConn.
|
ctx, cancel := global.TimeoutContext()
|
||||||
Table(new(model.User)).
|
defer cancel()
|
||||||
Where(builder.Eq{"type": 0, "enabled": true}).
|
|
||||||
Count()
|
c, err := global.DB.NewSelect().Model((*model.User)(nil)).
|
||||||
|
Where("type = ?", model.USER_TYPE_ENT).
|
||||||
|
Where("enabled = ?", true).
|
||||||
|
Count(ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
cache.CacheCount([]string{"user"}, "enabled_ent", c)
|
cache.CacheCount([]string{"user"}, "enabled_ent", int64(c))
|
||||||
}
|
}
|
||||||
return c, err
|
return int64(c), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_StatisticsService) EnabledParks(userIds ...string) (int64, error) {
|
func (_StatisticsService) EnabledParks(userIds ...string) (int64, error) {
|
||||||
if cachedParks, _ := cache.RetreiveCount("enabled_parks", userIds...); cachedParks != -1 {
|
if cachedParks, err := cache.RetreiveCount("enabled_parks", userIds...); cachedParks != -1 && err == nil {
|
||||||
return cachedParks, nil
|
return cachedParks, nil
|
||||||
}
|
}
|
||||||
cond := builder.NewCond().And(builder.Eq{"enabled": true})
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
query := global.DB.NewSelect().Model((*model.Park)(nil)).
|
||||||
|
Where("enabled = ?", true)
|
||||||
if len(userIds) > 0 {
|
if len(userIds) > 0 {
|
||||||
cond = cond.And(builder.Eq{"user_id": userIds})
|
query = query.Where("user_id in (?)", bun.In(userIds))
|
||||||
}
|
}
|
||||||
c, err := global.DBConn.
|
c, err := query.Count(ctx)
|
||||||
Table(new(model.Park)).
|
|
||||||
Where(cond).
|
|
||||||
Count()
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
cache.CacheCount([]string{"user", "park"}, "enabled_parks", c, userIds...)
|
cache.CacheCount([]string{"user", "park"}, "enabled_parks", int64(c), userIds...)
|
||||||
}
|
}
|
||||||
return c, err
|
return int64(c), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_StatisticsService) ParksNewestState(userIds ...string) ([]model.ParkPeriodStatistics, error) {
|
func (_StatisticsService) ParksNewestState(userIds ...string) ([]model.ParkPeriodStatistics, error) {
|
||||||
if cachedState, _ := cache.RetreiveSearch[[]model.ParkPeriodStatistics]("park_period_stat", userIds...); cachedState != nil {
|
if cachedState, _ := cache.RetreiveSearch[[]model.ParkPeriodStatistics]("park_period_stat", userIds...); cachedState != nil {
|
||||||
return *cachedState, nil
|
return *cachedState, nil
|
||||||
}
|
}
|
||||||
cond := builder.NewCond().And(builder.Eq{"p.enabled": true, "r.published": true})
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
query := global.DB.NewSelect().Model((*model.Report)(nil)).
|
||||||
|
Relation("Park", func(q *bun.SelectQuery) *bun.SelectQuery {
|
||||||
|
return q.Column("id", "name")
|
||||||
|
}).
|
||||||
|
Where("park.enabled = ?", true).
|
||||||
|
Where("r.published = ?", true)
|
||||||
if len(userIds) > 0 {
|
if len(userIds) > 0 {
|
||||||
cond = cond.And(builder.Eq{"p.user_id": userIds})
|
query = query.Where("park.user_id in (?)", bun.In(userIds))
|
||||||
}
|
}
|
||||||
parks := make([]model.ParkPeriodStatistics, 0)
|
parks := make([]model.ParkPeriodStatistics, 0)
|
||||||
groupedParks := make(map[string]model.ParkPeriodStatistics, 0)
|
groupedParks := make(map[string]model.ParkPeriodStatistics, 0)
|
||||||
err := global.DBConn.
|
err := query.Column("period").Scan(ctx, &parks)
|
||||||
Table("park").Alias("p").
|
|
||||||
Join("LEFT", []string{"report", "r"}, "r.park_id=p.id").
|
|
||||||
Where(cond).
|
|
||||||
Cols("p.id", "p.name", "r.period").
|
|
||||||
Find(&parks)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return make([]model.ParkPeriodStatistics, 0), err
|
return make([]model.ParkPeriodStatistics, 0), err
|
||||||
}
|
}
|
||||||
for _, p := range parks {
|
for _, p := range parks {
|
||||||
if c, ok := groupedParks[p.Id]; ok {
|
if c, ok := groupedParks[p.Id]; ok {
|
||||||
if c.Period != nil && p.Period != nil && p.Period.After(*c.Period) {
|
if c.Period != nil && p.Period != nil && p.Period.After(c.Period.Time) {
|
||||||
groupedParks[p.Id] = p
|
groupedParks[p.Id] = p
|
||||||
}
|
}
|
||||||
if c.Period == nil && p.Period != nil {
|
if c.Period == nil && p.Period != nil {
|
||||||
|
|||||||
+170
-111
@@ -1,10 +1,12 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"electricity_bill_calc/cache"
|
"electricity_bill_calc/cache"
|
||||||
"electricity_bill_calc/config"
|
"electricity_bill_calc/config"
|
||||||
"electricity_bill_calc/exceptions"
|
"electricity_bill_calc/exceptions"
|
||||||
"electricity_bill_calc/global"
|
"electricity_bill_calc/global"
|
||||||
|
"electricity_bill_calc/logger"
|
||||||
"electricity_bill_calc/model"
|
"electricity_bill_calc/model"
|
||||||
"electricity_bill_calc/tools"
|
"electricity_bill_calc/tools"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -13,12 +15,17 @@ import (
|
|||||||
|
|
||||||
"github.com/fufuok/utils"
|
"github.com/fufuok/utils"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"xorm.io/builder"
|
"github.com/uptrace/bun"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type _UserService struct{}
|
type _UserService struct {
|
||||||
|
l *zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
var UserService _UserService
|
var UserService = _UserService{
|
||||||
|
l: logger.Named("Service", "User"),
|
||||||
|
}
|
||||||
|
|
||||||
func (u _UserService) ProcessEnterpriseUserLogin(username, password string) (*model.Session, error) {
|
func (u _UserService) ProcessEnterpriseUserLogin(username, password string) (*model.Session, error) {
|
||||||
user, err := u.findUserWithCredentialsByUsername(username)
|
user, err := u.findUserWithCredentialsByUsername(username)
|
||||||
@@ -30,14 +37,14 @@ func (u _UserService) ProcessEnterpriseUserLogin(username, password string) (*mo
|
|||||||
return nil, exceptions.NewAuthenticationError(404, "用户不存在。")
|
return nil, exceptions.NewAuthenticationError(404, "用户不存在。")
|
||||||
}
|
}
|
||||||
if user.Type != 0 {
|
if user.Type != 0 {
|
||||||
return nil, exceptions.NewAuthenticationError(401, "用户类型不正确。")
|
return nil, exceptions.NewAuthenticationError(400, "用户类型不正确。")
|
||||||
}
|
}
|
||||||
if !user.Enabled {
|
if !user.Enabled {
|
||||||
return nil, exceptions.NewAuthenticationError(401, "用户已被禁用。")
|
return nil, exceptions.NewAuthenticationError(403, "用户已被禁用。")
|
||||||
}
|
}
|
||||||
hashedPassword := utils.Sha512Hex(password)
|
hashedPassword := utils.Sha512Hex(password)
|
||||||
if hashedPassword != user.Password {
|
if hashedPassword != user.Password {
|
||||||
return nil, exceptions.NewAuthenticationError(401, "用户凭据不正确。")
|
return nil, exceptions.NewAuthenticationError(402, "用户凭据不正确。")
|
||||||
}
|
}
|
||||||
if user.ResetNeeded {
|
if user.ResetNeeded {
|
||||||
authErr := exceptions.NewAuthenticationError(401, "用户凭据已失效。")
|
authErr := exceptions.NewAuthenticationError(401, "用户凭据已失效。")
|
||||||
@@ -45,8 +52,8 @@ func (u _UserService) ProcessEnterpriseUserLogin(username, password string) (*mo
|
|||||||
return nil, authErr
|
return nil, authErr
|
||||||
}
|
}
|
||||||
userDetial, _ := u.retreiveUserDetail(user.Id)
|
userDetial, _ := u.retreiveUserDetail(user.Id)
|
||||||
if userDetial.ServiceExpiration.Before(time.Now()) {
|
if userDetial.ServiceExpiration.Time.Before(time.Now()) {
|
||||||
return nil, exceptions.NewAuthenticationError(401, "用户服务期限已过。")
|
return nil, exceptions.NewAuthenticationError(406, "用户服务期限已过。")
|
||||||
}
|
}
|
||||||
session := &model.Session{
|
session := &model.Session{
|
||||||
Token: uuid.New().String(),
|
Token: uuid.New().String(),
|
||||||
@@ -72,14 +79,14 @@ func (u _UserService) ProcessManagementUserLogin(username, password string) (*mo
|
|||||||
return nil, exceptions.NewAuthenticationError(404, "用户不存在。")
|
return nil, exceptions.NewAuthenticationError(404, "用户不存在。")
|
||||||
}
|
}
|
||||||
if user.Type != 1 && user.Type != 2 {
|
if user.Type != 1 && user.Type != 2 {
|
||||||
return nil, exceptions.NewAuthenticationError(401, "用户类型不正确。")
|
return nil, exceptions.NewAuthenticationError(400, "用户类型不正确。")
|
||||||
}
|
}
|
||||||
if !user.Enabled {
|
if !user.Enabled {
|
||||||
return nil, exceptions.NewAuthenticationError(401, "用户已被禁用。")
|
return nil, exceptions.NewAuthenticationError(403, "用户已被禁用。")
|
||||||
}
|
}
|
||||||
hashedPassword := utils.Sha512Hex(password)
|
hashedPassword := utils.Sha512Hex(password)
|
||||||
if hashedPassword != user.Password {
|
if hashedPassword != user.Password {
|
||||||
return nil, exceptions.NewAuthenticationError(401, "用户凭据不正确。")
|
return nil, exceptions.NewAuthenticationError(402, "用户凭据不正确。")
|
||||||
}
|
}
|
||||||
if user.ResetNeeded {
|
if user.ResetNeeded {
|
||||||
authErr := exceptions.NewAuthenticationError(401, "用户凭据已失效。")
|
authErr := exceptions.NewAuthenticationError(401, "用户凭据已失效。")
|
||||||
@@ -106,17 +113,18 @@ func (u _UserService) InvalidUserPassword(uid string) (string, error) {
|
|||||||
if user == nil && err != nil {
|
if user == nil && err != nil {
|
||||||
return "", exceptions.NewNotFoundError("指定的用户不存在。")
|
return "", exceptions.NewNotFoundError("指定的用户不存在。")
|
||||||
}
|
}
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
verifyCode := tools.RandStr(10)
|
verifyCode := tools.RandStr(10)
|
||||||
user.Password = utils.Sha512Hex(verifyCode)
|
user.Password = utils.Sha512Hex(verifyCode)
|
||||||
user.ResetNeeded = true
|
user.ResetNeeded = true
|
||||||
affected, err := global.DBConn.ID(uid).Cols("password", "reset_needed").Update(user)
|
res, err := global.DB.NewUpdate().Model(user).WherePK().Column("password", "reset_needed").Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if affected > 0 {
|
if affected, _ := res.RowsAffected(); affected > 0 {
|
||||||
// ! 同一个用户在缓存中有两个键。
|
// ! 清除与此用户所有相关的记录。
|
||||||
cache.AbolishRelation(fmt.Sprintf("user_%s", uid))
|
cache.AbolishRelation(fmt.Sprintf("user:%s", uid))
|
||||||
cache.AbolishRelation("user")
|
|
||||||
return verifyCode, nil
|
return verifyCode, nil
|
||||||
} else {
|
} else {
|
||||||
return "", exceptions.NewUnsuccessfulOperationError()
|
return "", exceptions.NewUnsuccessfulOperationError()
|
||||||
@@ -141,15 +149,16 @@ func (u _UserService) ResetUserPassword(username, password string) (bool, error)
|
|||||||
if user == nil || err != nil {
|
if user == nil || err != nil {
|
||||||
return false, exceptions.NewNotFoundError("指定的用户不存在。")
|
return false, exceptions.NewNotFoundError("指定的用户不存在。")
|
||||||
}
|
}
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
user.Password = utils.Sha512Hex(password)
|
user.Password = utils.Sha512Hex(password)
|
||||||
user.ResetNeeded = false
|
user.ResetNeeded = false
|
||||||
affected, err := global.DBConn.ID(user.Id).Cols("password", "reset_needed").Update(user)
|
res, err := global.DB.NewUpdate().Model(user).WherePK().Column("password", "reset_needed").Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if affected > 0 {
|
if affected, _ := res.RowsAffected(); affected > 0 {
|
||||||
cache.AbolishRelation(fmt.Sprintf("user_%s", user.Id))
|
cache.AbolishRelation(fmt.Sprintf("user:%s", user.Id))
|
||||||
cache.AbolishRelation("user")
|
|
||||||
return true, nil
|
return true, nil
|
||||||
} else {
|
} else {
|
||||||
return false, nil
|
return false, nil
|
||||||
@@ -160,9 +169,11 @@ func (_UserService) IsUserExists(uid string) (bool, error) {
|
|||||||
if has, _ := cache.CheckExists("user", uid); has {
|
if has, _ := cache.CheckExists("user", uid); has {
|
||||||
return has, nil
|
return has, nil
|
||||||
}
|
}
|
||||||
has, err := global.DBConn.ID(uid).Exist(&model.User{})
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
has, err := global.DB.NewSelect().Model((*model.User)(nil)).Where("id = ?", uid).Exists(ctx)
|
||||||
if has {
|
if has {
|
||||||
cache.CacheExists([]string{fmt.Sprintf("user_%s", uid)}, "user", uid)
|
cache.CacheExists([]string{"user", fmt.Sprintf("user_%s", uid)}, "user", uid)
|
||||||
}
|
}
|
||||||
return has, err
|
return has, err
|
||||||
}
|
}
|
||||||
@@ -171,7 +182,9 @@ func (_UserService) IsUsernameExists(username string) (bool, error) {
|
|||||||
if has, _ := cache.CheckExists("user", username); has {
|
if has, _ := cache.CheckExists("user", username); has {
|
||||||
return has, nil
|
return has, nil
|
||||||
}
|
}
|
||||||
has, err := global.DBConn.Where(builder.Eq{"username": username}).Exist(&model.User{})
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
has, err := global.DB.NewSelect().Model((*model.User)(nil)).Where("username = ?", username).Exists(ctx)
|
||||||
if has {
|
if has {
|
||||||
cache.CacheExists([]string{"user"}, "user", username)
|
cache.CacheExists([]string{"user"}, "user", username)
|
||||||
}
|
}
|
||||||
@@ -199,18 +212,19 @@ func (u _UserService) CreateUser(user *model.User, detail *model.UserDetail) (st
|
|||||||
finalAbbr := tools.PinyinAbbr(*detail.Name)
|
finalAbbr := tools.PinyinAbbr(*detail.Name)
|
||||||
detail.Abbr = &finalAbbr
|
detail.Abbr = &finalAbbr
|
||||||
}
|
}
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
tx := global.DBConn.NewSession()
|
tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{})
|
||||||
defer tx.Close()
|
if err != nil {
|
||||||
if err := tx.Begin(); err != nil {
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
_, err = tx.Insert(user)
|
_, err = tx.NewInsert().Model(user).Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return "", fmt.Errorf("user create failed: %w", err)
|
return "", fmt.Errorf("user create failed: %w", err)
|
||||||
}
|
}
|
||||||
_, err = tx.Insert(detail)
|
_, err = tx.NewInsert().Model(detail).Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return "", fmt.Errorf("user Detail create failed: %w", err)
|
return "", fmt.Errorf("user Detail create failed: %w", err)
|
||||||
@@ -220,6 +234,7 @@ func (u _UserService) CreateUser(user *model.User, detail *model.UserDetail) (st
|
|||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return "", fmt.Errorf("transaction commit unsuccessful: %w", err)
|
return "", fmt.Errorf("transaction commit unsuccessful: %w", err)
|
||||||
}
|
}
|
||||||
|
// ! 广谱关联关系的废除必须是在有新记录加入或者有记录被删除的情况下。
|
||||||
cache.AbolishRelation("user")
|
cache.AbolishRelation("user")
|
||||||
return verifyCode, nil
|
return verifyCode, nil
|
||||||
}
|
}
|
||||||
@@ -233,73 +248,103 @@ func (u _UserService) SwitchUserState(uid string, enabled bool) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
newStateUser := new(model.User)
|
newStateUser := new(model.User)
|
||||||
|
newStateUser.Id = uid
|
||||||
newStateUser.Enabled = enabled
|
newStateUser.Enabled = enabled
|
||||||
_, err = global.DBConn.ID(uid).Cols("enabled").Update(newStateUser)
|
ctx, cancel := global.TimeoutContext()
|
||||||
if err != nil {
|
defer cancel()
|
||||||
cache.AbolishRelation("user")
|
res, err := global.DB.NewUpdate().Model(newStateUser).WherePK().Column("enabled").Exec(ctx)
|
||||||
cache.AbolishRelation(fmt.Sprintf("user_%s", uid))
|
if affected, _ := res.RowsAffected(); err == nil && affected > 0 {
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("user:%s", uid))
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_UserService) SearchLimitUsers(keyword string, limit int) ([]model.JoinedUserDetail, error) {
|
func (us _UserService) SearchLimitUsers(keyword string, limit int) ([]model.JoinedUserDetail, error) {
|
||||||
if cachedUsers, _ := cache.RetreiveSearch[[]model.JoinedUserDetail]("join_user_detail", keyword, strconv.Itoa(limit)); cachedUsers != nil {
|
if cachedUsers, _ := cache.RetreiveSearch[[]model.JoinedUserDetail]("join_user_detail", keyword, strconv.Itoa(limit)); cachedUsers != nil {
|
||||||
return *cachedUsers, nil
|
return *cachedUsers, nil
|
||||||
}
|
}
|
||||||
var users = make([]model.JoinedUserDetail, 0)
|
|
||||||
err := global.DBConn.
|
ctx, cancel := global.TimeoutContext()
|
||||||
Table("user_detail").Alias("d").
|
defer cancel()
|
||||||
Join("INNER", []string{"user", "u"}, "d.id=u.id").
|
|
||||||
Where(
|
var users = make([]model.User, 0)
|
||||||
builder.NewCond().
|
keywordCond := "%" + keyword + "%"
|
||||||
Or(builder.Like{"u.username", keyword}).
|
err := global.DB.NewSelect().Model(&users).Relation("Detail").
|
||||||
Or(builder.Like{"d.name", keyword}).
|
Where("u.type = ?", model.USER_TYPE_ENT).
|
||||||
Or(builder.Like{"d.abbr", keyword})).
|
WhereGroup(" and ", func(q *bun.SelectQuery) *bun.SelectQuery {
|
||||||
And(builder.Eq{"u.type": 0}).
|
return q.Where("u.username like ?", keywordCond).
|
||||||
Asc("u.created_at").
|
WhereOr("detail.name like ?", keywordCond).
|
||||||
Limit(limit, 0).
|
WhereOr("detail.abbr like ?", keywordCond).
|
||||||
Find(&users)
|
WhereOr("detail.contact like ?", keywordCond).
|
||||||
|
WhereOr("detail.address like ?", keywordCond)
|
||||||
|
}).
|
||||||
|
Order("u.created_at asc").
|
||||||
|
Limit(limit).
|
||||||
|
Offset(0).
|
||||||
|
Scan(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return make([]model.JoinedUserDetail, 0), err
|
return make([]model.JoinedUserDetail, 0), err
|
||||||
}
|
}
|
||||||
cache.CacheSearch(users, []string{"user"}, "join_user_detail", keyword, strconv.Itoa(limit))
|
var detailedUsers = make([]model.JoinedUserDetail, 0)
|
||||||
return users, nil
|
var relations = make([]string, 0)
|
||||||
|
// ! 这里的转换是为了兼容之前使用Xorm时构建的关联关系而存在的
|
||||||
|
for _, u := range users {
|
||||||
|
detailedUsers = append(detailedUsers, model.JoinedUserDetail{
|
||||||
|
UserDetail: *u.Detail,
|
||||||
|
Id: u.Id,
|
||||||
|
Username: u.Username,
|
||||||
|
Type: u.Type,
|
||||||
|
Enabled: u.Enabled,
|
||||||
|
})
|
||||||
|
relations = append(relations, fmt.Sprintf("user:%s", u.Id))
|
||||||
|
}
|
||||||
|
relations = append(relations, "user")
|
||||||
|
cache.CacheSearch(detailedUsers, relations, "join_user_detail", keyword, strconv.Itoa(limit))
|
||||||
|
return detailedUsers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_UserService) findUserWithCredentialsByUsername(username string) (*model.UserWithCredentials, error) {
|
func (_UserService) findUserWithCredentialsByUsername(username string) (*model.UserWithCredentials, error) {
|
||||||
if cachedUser, _ := cache.RetreiveSearch[model.UserWithCredentials]("user_with_credentials", username); cachedUser != nil {
|
if cachedUser, _ := cache.RetreiveSearch[model.UserWithCredentials]("user_with_credentials", username); cachedUser != nil {
|
||||||
return cachedUser, nil
|
return cachedUser, nil
|
||||||
}
|
}
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
user := new(model.UserWithCredentials)
|
user := new(model.UserWithCredentials)
|
||||||
has, err := global.DBConn.Where(builder.Eq{"username": username}).NoAutoCondition().Get(user)
|
err := global.DB.NewSelect().Model(user).Where("username = ?", username).Scan(ctx)
|
||||||
if has {
|
if err == nil {
|
||||||
cache.CacheSearch(*user, []string{"user"}, "user_with_credentials", username)
|
cache.CacheSearch(*user, []string{fmt.Sprintf("user:%s", user.Id)}, "user_with_credentials", username)
|
||||||
}
|
}
|
||||||
return _postProcessSingle(user, has, err)
|
return user, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_UserService) findUserByUsername(username string) (*model.User, error) {
|
func (u _UserService) findUserByUsername(username string) (*model.User, error) {
|
||||||
if cachedUser, _ := cache.RetreiveSearch[model.User]("user", username); cachedUser != nil {
|
if cachedUser, _ := cache.RetreiveSearch[model.User]("user", username); cachedUser != nil {
|
||||||
return cachedUser, nil
|
return cachedUser, nil
|
||||||
}
|
}
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
user := new(model.User)
|
user := new(model.User)
|
||||||
has, err := global.DBConn.Where(builder.Eq{"username": username}).NoAutoCondition().Get(user)
|
err := global.DB.NewSelect().Model(user).Where("username = ?", username).Scan(ctx)
|
||||||
if has {
|
if err == nil {
|
||||||
cache.CacheSearch(*user, []string{"user"}, "user", username)
|
cache.CacheSearch(*user, []string{fmt.Sprintf("user:%s", user.Id)}, "user", username)
|
||||||
}
|
}
|
||||||
return _postProcessSingle(user, has, err)
|
return user, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_UserService) retreiveUserDetail(uid string) (*model.UserDetail, error) {
|
func (_UserService) retreiveUserDetail(uid string) (*model.UserDetail, error) {
|
||||||
if cachedUser, _ := cache.RetreiveEntity[model.UserDetail]("user_detail", uid); cachedUser != nil {
|
if cachedUser, _ := cache.RetreiveEntity[model.UserDetail]("user_detail", uid); cachedUser != nil {
|
||||||
return cachedUser, nil
|
return cachedUser, nil
|
||||||
}
|
}
|
||||||
user := new(model.UserDetail)
|
ctx, cancel := global.TimeoutContext()
|
||||||
has, err := global.DBConn.ID(uid).NoAutoCondition().Get(user)
|
defer cancel()
|
||||||
if has {
|
user := &model.UserDetail{
|
||||||
cache.CacheEntity(*user, []string{fmt.Sprintf("user_%s", uid)}, "user_detail", uid)
|
Id: uid,
|
||||||
}
|
}
|
||||||
return _postProcessSingle(user, has, err)
|
err := global.DB.NewSelect().Model(user).WherePK().Scan(ctx)
|
||||||
|
if err == nil {
|
||||||
|
cache.CacheEntity(*user, []string{fmt.Sprintf("user:%s", uid)}, "user_detail", uid)
|
||||||
|
}
|
||||||
|
return user, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_UserService) findUserByID(uid string) (*model.User, error) {
|
func (_UserService) findUserByID(uid string) (*model.User, error) {
|
||||||
@@ -307,82 +352,96 @@ func (_UserService) findUserByID(uid string) (*model.User, error) {
|
|||||||
if cachedUser != nil {
|
if cachedUser != nil {
|
||||||
return cachedUser, nil
|
return cachedUser, nil
|
||||||
}
|
}
|
||||||
user := new(model.User)
|
ctx, cancel := global.TimeoutContext()
|
||||||
has, err := global.DBConn.ID(uid).NoAutoCondition().Get(user)
|
defer cancel()
|
||||||
if has {
|
user := &model.User{
|
||||||
cache.CacheEntity(*user, []string{fmt.Sprintf("user_%s", uid)}, "user", uid)
|
Id: uid,
|
||||||
}
|
}
|
||||||
return _postProcessSingle(user, has, err)
|
err := global.DB.NewSelect().Model(&user).WherePK().Scan(ctx)
|
||||||
|
if err == nil {
|
||||||
|
cache.CacheEntity(*user, []string{fmt.Sprintf("user:%s", uid)}, "user", uid)
|
||||||
|
}
|
||||||
|
return user, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_UserService) ListUserDetail(keyword string, userType int, userState *bool, page int) ([]model.JoinedUserDetail, int64, error) {
|
func (_UserService) ListUserDetail(keyword string, userType int, userState *bool, page int) ([]model.JoinedUserDetail, int64, error) {
|
||||||
var (
|
var (
|
||||||
cond = builder.NewCond()
|
cond = global.DB.NewSelect()
|
||||||
cacheConditions = make([]string, 0)
|
cacheConditions = make([]string, 0)
|
||||||
|
users = make([]model.User, 0)
|
||||||
)
|
)
|
||||||
|
cond = cond.Model(&users).Relation("Detail")
|
||||||
cacheConditions = append(cacheConditions, strconv.Itoa(page))
|
cacheConditions = append(cacheConditions, strconv.Itoa(page))
|
||||||
cond = cond.And(builder.Neq{"d.id": "000"})
|
cond = cond.Where("detail.id <> ?", "000")
|
||||||
if len(keyword) != 0 {
|
if len(keyword) != 0 {
|
||||||
keywordCond := builder.NewCond().
|
keywordCond := "%" + keyword + "%"
|
||||||
Or(builder.Like{"u.username", keyword}).
|
cond = cond.WhereGroup(" and ", func(q *bun.SelectQuery) *bun.SelectQuery {
|
||||||
Or(builder.Like{"d.name", keyword})
|
return q.Where("u.username like ?", keywordCond).
|
||||||
cond = cond.And(keywordCond)
|
WhereOr("detail.name like ?", keywordCond)
|
||||||
|
})
|
||||||
cacheConditions = append(cacheConditions, keyword)
|
cacheConditions = append(cacheConditions, keyword)
|
||||||
}
|
}
|
||||||
if userType != -1 {
|
if userType != -1 {
|
||||||
cond = cond.And(builder.Eq{"u.type": userType})
|
cond = cond.Where("u.type = ?", userType)
|
||||||
cacheConditions = append(cacheConditions, strconv.Itoa(userType))
|
cacheConditions = append(cacheConditions, strconv.Itoa(userType))
|
||||||
}
|
}
|
||||||
if userState != nil {
|
if userState != nil {
|
||||||
cond = cond.And(builder.Eq{"u.enabled": *userState})
|
cond = cond.Where("u.enabled = ?", *userState)
|
||||||
cacheConditions = append(cacheConditions, strconv.FormatBool(*userState))
|
cacheConditions = append(cacheConditions, strconv.FormatBool(*userState))
|
||||||
}
|
}
|
||||||
startItem := (page - 1) * config.ServiceSettings.ItemsPageSize
|
startItem := (page - 1) * config.ServiceSettings.ItemsPageSize
|
||||||
var (
|
|
||||||
total int64
|
// * 这里利用已经构建完成的条件集合从缓存中获取数据,如果所有数据都可以从缓存中获取,那么就直接返回了。
|
||||||
err error
|
if cacheCounts, err := cache.RetreiveCount("join_user_detail", cacheConditions...); cacheCounts != -1 && err == nil {
|
||||||
)
|
if cachedUsers, _ := cache.RetreiveSearch[[]model.JoinedUserDetail]("join_user_detail", cacheConditions...); cachedUsers != nil {
|
||||||
if cacheCounts, _ := cache.RetreiveCount("join_user_detail", cacheConditions...); cacheCounts != -1 {
|
return *cachedUsers, cacheCounts, nil
|
||||||
total = cacheCounts
|
|
||||||
} else {
|
|
||||||
total, err = global.DBConn.
|
|
||||||
Table("user_detail").Alias("d").
|
|
||||||
Join("INNER", []string{"user", "u"}, "d.id=u.id").
|
|
||||||
Where(cond).
|
|
||||||
Count(&model.User{})
|
|
||||||
if err != nil {
|
|
||||||
return nil, -1, err
|
|
||||||
}
|
}
|
||||||
cache.CacheCount([]string{"user"}, "join_user_detail", total, cacheConditions...)
|
|
||||||
}
|
}
|
||||||
users := make([]model.JoinedUserDetail, 0)
|
|
||||||
if cachedUsers, _ := cache.RetreiveSearch[[]model.JoinedUserDetail]("join_user_detail", cacheConditions...); cachedUsers != nil {
|
ctx, cancel := global.TimeoutContext()
|
||||||
return *cachedUsers, total, nil
|
defer cancel()
|
||||||
|
total, err := cond.
|
||||||
|
Limit(config.ServiceSettings.ItemsPageSize).Offset(startItem).
|
||||||
|
ScanAndCount(ctx)
|
||||||
|
|
||||||
|
var (
|
||||||
|
joinedUsers = make([]model.JoinedUserDetail, 0)
|
||||||
|
relations = []string{"user"}
|
||||||
|
)
|
||||||
|
for _, u := range users {
|
||||||
|
joinedUsers = append(joinedUsers, model.JoinedUserDetail{
|
||||||
|
UserDetail: *u.Detail,
|
||||||
|
Id: u.Id,
|
||||||
|
Username: u.Username,
|
||||||
|
Type: u.Type,
|
||||||
|
Enabled: u.Enabled,
|
||||||
|
})
|
||||||
|
relations = append(relations, fmt.Sprintf("user:%s", u.Id))
|
||||||
}
|
}
|
||||||
err = global.DBConn.
|
|
||||||
Table("user_detail").Alias("d").
|
cache.CacheCount(relations, "join_user_detail", int64(total), cacheConditions...)
|
||||||
Join("INNER", []string{"user", "u"}, "d.id=u.id").
|
cache.CacheSearch(joinedUsers, relations, "join_user_detail", cacheConditions...)
|
||||||
Where(cond).
|
return joinedUsers, int64(total), err
|
||||||
Limit(config.ServiceSettings.ItemsPageSize, startItem).
|
|
||||||
Find(&users)
|
|
||||||
cache.CacheSearch(users, []string{"user"}, "join_user_detail", cacheConditions...)
|
|
||||||
return users, total, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_UserService) FetchUserDetail(uid string) (*model.FullJoinedUserDetail, error) {
|
func (_UserService) FetchUserDetail(uid string) (*model.FullJoinedUserDetail, error) {
|
||||||
if cachedUser, _ := cache.RetreiveEntity[model.FullJoinedUserDetail]("full_join_user_detail", uid); cachedUser != nil {
|
if cachedUser, _ := cache.RetreiveEntity[model.FullJoinedUserDetail]("full_join_user_detail", uid); cachedUser != nil {
|
||||||
return cachedUser, nil
|
return cachedUser, nil
|
||||||
}
|
}
|
||||||
user := &model.FullJoinedUserDetail{}
|
|
||||||
has, err := global.DBConn.
|
ctx, cancel := global.TimeoutContext()
|
||||||
Table("user_detail").Alias("d").
|
defer cancel()
|
||||||
Join("INNER", []string{"user", "u"}, "d.id=u.id").
|
user := &model.User{}
|
||||||
Where(builder.Eq{"d.id": uid}).
|
err := global.DB.NewSelect().Model(user).Relation("Detail").
|
||||||
NoAutoCondition().
|
Where("u.id = ?", uid).
|
||||||
Get(user)
|
Scan(ctx)
|
||||||
if has {
|
if err == nil {
|
||||||
cache.CacheEntity(*user, []string{fmt.Sprintf("user_%s", uid)}, "full_join_user_detail", uid)
|
fullJoinedUser := &model.FullJoinedUserDetail{
|
||||||
return user, nil
|
User: *user,
|
||||||
|
UserDetail: *user.Detail,
|
||||||
|
}
|
||||||
|
cache.CacheEntity(*fullJoinedUser, []string{fmt.Sprintf("user:%s", uid)}, "full_join_user_detail", uid)
|
||||||
|
return fullJoinedUser, nil
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
+94
-84
@@ -5,146 +5,156 @@ import (
|
|||||||
"electricity_bill_calc/config"
|
"electricity_bill_calc/config"
|
||||||
"electricity_bill_calc/exceptions"
|
"electricity_bill_calc/exceptions"
|
||||||
"electricity_bill_calc/global"
|
"electricity_bill_calc/global"
|
||||||
|
"electricity_bill_calc/logger"
|
||||||
"electricity_bill_calc/model"
|
"electricity_bill_calc/model"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"xorm.io/builder"
|
"github.com/uptrace/bun"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type _WithdrawService struct{}
|
type _WithdrawService struct {
|
||||||
|
l *zap.Logger
|
||||||
|
}
|
||||||
|
|
||||||
var WithdrawService _WithdrawService
|
var WithdrawService = _WithdrawService{
|
||||||
|
l: logger.Named("Service", "Withdraw"),
|
||||||
|
}
|
||||||
|
|
||||||
func (_WithdrawService) ApplyWithdraw(reportId string) (bool, error) {
|
func (_WithdrawService) ApplyWithdraw(reportId string) (bool, error) {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
var report = new(model.Report)
|
var report = new(model.Report)
|
||||||
has, err := global.DBConn.ID(reportId).Get(report)
|
err := global.DB.NewSelect().Model(report).
|
||||||
if err != nil {
|
Where("id = ?", reportId).
|
||||||
return false, err
|
Scan(ctx)
|
||||||
}
|
if err != nil || report == nil {
|
||||||
if !has {
|
return false, exceptions.NewNotFoundErrorFromError("指定报表未能找到", err)
|
||||||
return false, exceptions.NewNotFoundError("指定报表未能找到")
|
|
||||||
}
|
}
|
||||||
if !report.Published {
|
if !report.Published {
|
||||||
return false, exceptions.NewImproperOperateError("指定报表尚未发布。")
|
return false, exceptions.NewImproperOperateError("指定报表尚未发布。")
|
||||||
}
|
}
|
||||||
reports := make([]model.Report, 0)
|
var maxPublished time.Time
|
||||||
err = global.DBConn.
|
err = global.DB.NewSelect().Model((*model.Report)(nil)).
|
||||||
Where(builder.Eq{"park_id": report.ParkId}).
|
ColumnExpr("max(period)").
|
||||||
Find(&reports)
|
Where("park_id = ?", report.ParkId).
|
||||||
|
Where("published = ?", true).
|
||||||
|
Scan(ctx, &maxPublished)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, exceptions.NewNotFoundError("未能找到匹配的系列报表。")
|
return false, exceptions.NewNotFoundError("未能找到匹配的系列报表。")
|
||||||
}
|
}
|
||||||
maxPublished := lo.Reduce(
|
if !report.Period.Equal(maxPublished) {
|
||||||
reports,
|
|
||||||
func(acc *time.Time, elem model.Report, index int) *time.Time {
|
|
||||||
if elem.Published {
|
|
||||||
if acc == nil || (acc != nil && elem.Period.After(*acc)) {
|
|
||||||
return &elem.Period
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return acc
|
|
||||||
},
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
if !report.Period.Equal(*maxPublished) {
|
|
||||||
return false, exceptions.NewImproperOperateError("申请撤回的报表必须是最新已发布的报表。")
|
return false, exceptions.NewImproperOperateError("申请撤回的报表必须是最新已发布的报表。")
|
||||||
}
|
}
|
||||||
|
|
||||||
report.Withdraw = model.REPORT_WITHDRAW_APPLIED
|
report.Withdraw = model.REPORT_WITHDRAW_APPLIED
|
||||||
report.LastWithdrawAppliedAt = lo.ToPtr(time.Now())
|
report.LastWithdrawAppliedAt = lo.ToPtr(time.Now())
|
||||||
_, err = global.DBConn.ID(report.Id).Cols("withdraw", "last_withdraw_applied_at").Update(report)
|
_, err = global.DB.NewUpdate().Model(report).
|
||||||
|
WherePK().
|
||||||
|
Column("withdraw", "last_withdraw_applied_at").
|
||||||
|
Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
cache.AbolishRelation("report")
|
cache.AbolishRelation("withdraw_stat")
|
||||||
cache.AbolishRelation(fmt.Sprintf("publicity_%s", reportId))
|
cache.AbolishRelation(fmt.Sprintf("report:%s", reportId))
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("publicity:%s", reportId))
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_WithdrawService) FetchPagedWithdrawApplies(page int, keyword string) ([]model.JoinedReportForWithdraw, int64, error) {
|
func (_WithdrawService) FetchPagedWithdrawApplies(page int, keyword string) ([]model.JoinedReportForWithdraw, int64, error) {
|
||||||
var conditions = make([]string, 0)
|
var (
|
||||||
cond := builder.NewCond()
|
conditions = make([]string, 0)
|
||||||
|
reports = make([]model.Report, 0)
|
||||||
|
cond = global.DB.NewSelect().Model(&reports).
|
||||||
|
Relation("Park").Relation("Park.Enterprise")
|
||||||
|
)
|
||||||
conditions = append(conditions, strconv.Itoa(int(model.REPORT_WITHDRAW_APPLIED)), strconv.Itoa(page))
|
conditions = append(conditions, strconv.Itoa(int(model.REPORT_WITHDRAW_APPLIED)), strconv.Itoa(page))
|
||||||
cond = cond.And(builder.Eq{"r.withdraw": model.REPORT_WITHDRAW_APPLIED})
|
cond = cond.Where("r.withdraw = ?", model.REPORT_WITHDRAW_APPLIED)
|
||||||
if len(keyword) > 0 {
|
if len(keyword) > 0 {
|
||||||
cond = cond.And(
|
keywordCond := "%" + keyword + "%"
|
||||||
builder.Like{"p.name", keyword}.
|
cond = cond.WhereGroup(" and ", func(q *bun.SelectQuery) *bun.SelectQuery {
|
||||||
Or(
|
return q.Where("p.name like ?", keywordCond).
|
||||||
builder.Like{"p.abbr", keyword},
|
WhereOr("p.abbr like ?", keywordCond).
|
||||||
builder.Like{"u.name", keyword},
|
WhereOr("d.name like ?", keywordCond).
|
||||||
builder.Like{"u.abbr", keyword},
|
WhereOr("d.abbr like ?", keywordCond)
|
||||||
),
|
})
|
||||||
)
|
|
||||||
conditions = append(conditions, keyword)
|
conditions = append(conditions, keyword)
|
||||||
}
|
}
|
||||||
var reports = make([]model.JoinedReportForWithdraw, 0)
|
if cachedTotal, err := cache.RetreiveCount("join_report_for_withdraw", conditions...); cachedTotal != -1 && err == nil {
|
||||||
var (
|
if cachedReports, _ := cache.RetreiveSearch[[]model.JoinedReportForWithdraw]("join_user_detail", conditions...); cachedReports != nil {
|
||||||
total int64
|
return *cachedReports, cachedTotal, err
|
||||||
err error
|
|
||||||
)
|
|
||||||
if cachedTotal, _ := cache.RetreiveCount("join_report_for_withdraw", conditions...); cachedTotal != -1 {
|
|
||||||
total = cachedTotal
|
|
||||||
} else {
|
|
||||||
total, err = global.DBConn.
|
|
||||||
Table(new(model.JoinedReportForWithdraw)).Alias("r").
|
|
||||||
Join("INNER", []string{"park", "p"}, "r.park_id=p.id").
|
|
||||||
Join("INNER", []string{"user_detail", "u"}, "p.user_id=u.id").
|
|
||||||
Where(cond).
|
|
||||||
Count()
|
|
||||||
if err != nil {
|
|
||||||
return nil, -1, err
|
|
||||||
}
|
}
|
||||||
cache.CacheCount([]string{"report", "park"}, "join_report_for_withdraw", total, conditions...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
startItem := (page - 1) * config.ServiceSettings.ItemsPageSize
|
startItem := (page - 1) * config.ServiceSettings.ItemsPageSize
|
||||||
if cachedReports, _ := cache.RetreiveSearch[[]model.JoinedReportForWithdraw]("join_user_detail", conditions...); cachedReports != nil {
|
total, err := cond.Limit(config.ServiceSettings.ItemsPageSize).
|
||||||
return *cachedReports, total, err
|
Offset(startItem).
|
||||||
|
ScanAndCount(ctx)
|
||||||
|
|
||||||
|
var (
|
||||||
|
joinedReports = make([]model.JoinedReportForWithdraw, 0)
|
||||||
|
relations = []string{"report", "park"}
|
||||||
|
)
|
||||||
|
for _, r := range reports {
|
||||||
|
joinedReports = append(joinedReports, model.JoinedReportForWithdraw{
|
||||||
|
Report: r,
|
||||||
|
Park: model.FromPark(*r.Park),
|
||||||
|
User: model.FromUserDetail(*r.Park.Enterprise),
|
||||||
|
})
|
||||||
|
relations = append(relations, fmt.Sprintf("report:%s", r.Id), fmt.Sprintf("publicity:%s", r.Id))
|
||||||
}
|
}
|
||||||
err = global.DBConn.
|
|
||||||
Alias("r").
|
cache.CacheCount(relations, "join_report_for_withdraw", int64(total), conditions...)
|
||||||
Join("INNER", []string{"park", "p"}, "r.park_id=p.id").
|
cache.CacheSearch(joinedReports, relations, "join_report_for_withdraw", conditions...)
|
||||||
Join("INNER", []string{"user_detail", "u"}, "p.user_id=u.id").
|
return joinedReports, int64(total), err
|
||||||
Where(cond).
|
|
||||||
Limit(config.ServiceSettings.ItemsPageSize, startItem).
|
|
||||||
Find(&reports)
|
|
||||||
cache.CacheSearch(reports, []string{"report", "park"}, "join_report_for_withdraw", conditions...)
|
|
||||||
return reports, total, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_WithdrawService) AuditWithdraw(reportId string, granted bool) error {
|
func (_WithdrawService) AuditWithdraw(reportId string, granted bool) error {
|
||||||
|
ctx, cancel := global.TimeoutContext()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
var report = new(model.Report)
|
var report = new(model.Report)
|
||||||
has, err := global.DBConn.ID(reportId).NoAutoCondition().Get(report)
|
err := global.DB.NewSelect().Model(report).
|
||||||
|
Where("id = ?", reportId).
|
||||||
|
Scan(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return exceptions.NewNotFoundErrorFromError("指定公示报表未找到。", err)
|
||||||
}
|
|
||||||
if !has {
|
|
||||||
return exceptions.NewNotFoundError("指定公示报表未找到。")
|
|
||||||
}
|
}
|
||||||
report.Withdraw = lo.If(granted, model.REPORT_WITHDRAW_GRANTED).Else(model.REPORT_WITHDRAW_DENIED)
|
report.Withdraw = lo.If(granted, model.REPORT_WITHDRAW_GRANTED).Else(model.REPORT_WITHDRAW_DENIED)
|
||||||
report.LastWithdrawAuditAt = lo.ToPtr(time.Now())
|
report.LastWithdrawAuditAt = lo.ToPtr(time.Now())
|
||||||
if granted {
|
if granted {
|
||||||
report.Published = false
|
report.Published = false
|
||||||
}
|
}
|
||||||
_, err = global.DBConn.ID(report.Id).Cols("withdraw", "last_withdraw_audit_at", "published").Update(report)
|
_, err = global.DB.NewUpdate().Model(report).
|
||||||
cache.AbolishRelation("report")
|
WherePK().
|
||||||
|
Column("withdraw", "last_withdraw_audit_at", "published").
|
||||||
|
Exec(ctx)
|
||||||
|
if err == nil {
|
||||||
|
cache.AbolishRelation("withdraw_stat")
|
||||||
|
cache.AbolishRelation(fmt.Sprintf("report:%s", reportId))
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_WithdrawService) AuditWaits() (int64, error) {
|
func (_WithdrawService) AuditWaits() (int64, error) {
|
||||||
if cachedWaits, _ := cache.RetreiveCount("withdraw_waits"); cachedWaits != -1 {
|
if cachedWaits, err := cache.RetreiveCount("withdraw_waits"); cachedWaits != -1 && err == nil {
|
||||||
return cachedWaits, nil
|
return cachedWaits, nil
|
||||||
}
|
}
|
||||||
cond := builder.NewCond()
|
ctx, cancel := global.TimeoutContext()
|
||||||
cond = cond.And(builder.Eq{"withdraw": model.REPORT_WITHDRAW_APPLIED})
|
defer cancel()
|
||||||
total, err := global.DBConn.
|
|
||||||
Table(new(model.JoinedReportForWithdraw)).
|
total, err := global.DB.NewSelect().Model((*model.Report)(nil)).
|
||||||
Where(cond).
|
Where("withdraw = ?", model.REPORT_WITHDRAW_APPLIED).
|
||||||
Count()
|
Count(ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
cache.CacheCount([]string{"report", "park"}, "withdraw_waits", total)
|
cache.CacheCount([]string{"withdraw_stat"}, "withdraw_waits", int64(total))
|
||||||
}
|
}
|
||||||
return total, err
|
return int64(total), err
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -4,8 +4,8 @@ Database:
|
|||||||
Host: postgres
|
Host: postgres
|
||||||
Port: 5432
|
Port: 5432
|
||||||
DB: electricity
|
DB: electricity
|
||||||
MaxIdleConns: 10
|
MaxIdleConns: 0
|
||||||
MaxOpenConns: 30
|
MaxOpenConns: 20
|
||||||
Server:
|
Server:
|
||||||
RunMode: release
|
RunMode: release
|
||||||
HttpPort: 8000
|
HttpPort: 8000
|
||||||
|
|||||||
@@ -38,3 +38,16 @@ func ConvertSliceToInterfaceSlice[T any](origin []T) []interface{} {
|
|||||||
}
|
}
|
||||||
return dest
|
return dest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 对指定的数组进行分区
|
||||||
|
func PartitionSlice[T any](slice []T, chunkSize int) [][]T {
|
||||||
|
var divided [][]T
|
||||||
|
for i := 0; i < len(slice); i += int(chunkSize) {
|
||||||
|
end := i + chunkSize
|
||||||
|
if end > len(slice) {
|
||||||
|
end = len(slice)
|
||||||
|
}
|
||||||
|
divided = append(divided, slice[i:end])
|
||||||
|
}
|
||||||
|
return divided
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user