Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"jury_test.go",
"service_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/credit/conf:go_default_library",
"//app/admin/main/credit/model/blocked:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"blocked.go",
"extra_func.go",
"jury.go",
"labour.go",
"msg.go",
"service.go",
"user.go",
],
importpath = "go-common/app/admin/main/credit/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/credit/conf:go_default_library",
"//app/admin/main/credit/dao/account:go_default_library",
"//app/admin/main/credit/dao/blocked:go_default_library",
"//app/admin/main/credit/dao/manager:go_default_library",
"//app/admin/main/credit/dao/msg:go_default_library",
"//app/admin/main/credit/dao/relation:go_default_library",
"//app/admin/main/credit/dao/search:go_default_library",
"//app/admin/main/credit/dao/upload:go_default_library",
"//app/admin/main/credit/model:go_default_library",
"//app/admin/main/credit/model/blocked:go_default_library",
"//app/service/main/account/api:go_default_library",
"//app/service/main/account/model:go_default_library",
"//app/service/main/coin/api:go_default_library",
"//app/service/main/relation/model:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/metadata:go_default_library",
"//library/sync/errgroup:go_default_library",
"//library/time:go_default_library",
"//library/xstr:go_default_library",
"//vendor/github.com/jinzhu/gorm:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,153 @@
package service
import (
"context"
"fmt"
"sort"
creditMDL "go-common/app/admin/main/credit/model"
"go-common/app/admin/main/credit/model/blocked"
account "go-common/app/service/main/account/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/sync/errgroup"
"go-common/library/xstr"
)
// Infos deal info data.
func (s *Service) Infos(c context.Context, arg *blocked.ArgBlockedSearch) (list []*blocked.Info, pager *blocked.Pager, err error) {
var ids []int64
ids, pager, err = s.searchDao.Blocked(c, arg)
if err != nil {
log.Error("s.searchDao.Blocked error (%v)", err)
return
}
if len(ids) == 0 {
return
}
var (
infoMap map[int64]*account.Info
uids = make([]int64, len(ids))
)
ids = creditMDL.ArrayUnique(ids)
if err = s.blockedDao.ReadDB.Where("id IN (?)", ids).Order(fmt.Sprintf("%s %s", arg.Order, arg.Sort)).Find(&list).Error; err != nil {
if err != ecode.NothingFound {
log.Error("s.blockedDao(%s) error(%v)", xstr.JoinInts(ids), err)
return
}
log.Warn("search ids(%s) not in db", xstr.JoinInts(ids))
err = nil
return
}
for _, v := range list {
uids = append(uids, v.UID)
}
if infoMap, err = s.accDao.RPCInfos(c, uids); err != nil {
log.Error("s.accDao.RPCInfos(%s) error(%v)", xstr.JoinInts(uids), err)
err = nil
}
for _, v := range list {
v.OPName = s.Managers[v.OperID]
if v.OPName == "" {
v.OPName = v.OOPName
}
if in, ok := infoMap[v.UID]; ok {
v.UName = in.Name
}
v.ReasonTypeDesc = blocked.ReasonTypeDesc(v.ReasonType)
v.PublishStatusDesc = blocked.PStatusDesc[v.PublishStatus]
v.OriginTypeDesc = blocked.OriginTypeDesc[v.OriginType]
v.BlockedTypeDesc = blocked.BTypeDesc[v.BlockedType]
v.BlockedDaysDesc = blocked.BDaysDesc(v.BlockedDays, v.MoralNum, v.PunishType, v.BlockedForever)
}
return
}
// InfosEx export info list
func (s *Service) InfosEx(c context.Context, arg *blocked.ArgBlockedSearch) (list []*blocked.Info, err error) {
var (
count int
pager *blocked.Pager
g errgroup.Group
ps = 500
)
if list, pager, err = s.Infos(c, arg); err != nil {
log.Error("s.Infos(%+v) error(%v)", arg, err)
return
}
if pager == nil {
log.Warn("arg(%+v) info search data empty!", arg)
return
}
count = pager.Total / ps
if pager.Total%ps != 0 {
count++
}
lCh := make(chan []*blocked.Info, count)
for pn := 1; pn <= count; pn++ {
tmpPn := pn
g.Go(func() (err error) {
var gInfo []*blocked.Info
gArg := &blocked.ArgBlockedSearch{
Keyword: arg.Keyword,
UID: arg.UID,
OPID: arg.OPID,
OriginType: arg.OriginType,
BlockedType: arg.BlockedType,
PublishStatus: arg.PublishStatus,
Start: arg.Start,
End: arg.End,
PN: tmpPn,
PS: ps,
Order: arg.Order,
Sort: arg.Sort,
}
gInfo, _, err = s.Infos(c, gArg)
if err != nil {
log.Error("s.Infos(%+v) error(%v)", gArg, err)
err = nil
return
}
lCh <- gInfo
return
})
}
g.Wait()
close(lCh)
for bInfo := range lCh {
list = append(list, bInfo...)
}
sort.Slice(list, func(i int, j int) bool {
return list[i].ID < list[j].ID
})
return
}
// Publishs get publishs data
func (s *Service) Publishs(c context.Context, arg *blocked.ArgPublishSearch) (list []*blocked.Publish, pager *blocked.Pager, err error) {
var ids []int64
ids, pager, err = s.searchDao.Publish(c, arg)
if err != nil {
log.Error("s.searchDao.Publish error (%v)", err)
return
}
if len(ids) == 0 {
return
}
ids = creditMDL.ArrayUnique(ids)
if err = s.blockedDao.ReadDB.Where("id IN (?)", ids).Order(fmt.Sprintf("%s %s", arg.Order, arg.Sort)).Find(&list).Error; err != nil {
if err != ecode.NothingFound {
log.Error("s.blockedDao(%s) error(%v)", xstr.JoinInts(ids), err)
return
}
log.Warn("search ids(%s) not in db", xstr.JoinInts(ids))
err = nil
}
for _, v := range list {
v.OPName = s.Managers[v.OPID]
v.PublishTypeDesc = blocked.PTypeDesc[v.Type]
v.PublishStatusDesc = blocked.PStatusDesc[v.PublishStatus]
v.StickStatusDesc = blocked.SStatusDesc[v.StickStatus]
}
return
}

View File

@@ -0,0 +1,90 @@
package service
import (
"bytes"
"context"
"encoding/csv"
"io"
"strconv"
"time"
coinclient "go-common/app/service/main/coin/api"
"go-common/library/log"
)
// FormatCSV format csv data.
func (s *Service) FormatCSV(records [][]string) (res []byte) {
buf := new(bytes.Buffer)
w := csv.NewWriter(buf)
for _, record := range records {
if err := w.Write(record); err != nil {
log.Error("error(%+v) writing record to csv:", err)
return
}
}
w.Flush()
res = buf.Bytes()
return
}
// Upload http upload file.
func (s *Service) Upload(c context.Context, fileName, fileType string, expire int64, body io.Reader) (location string, err error) {
if location, err = s.uploadDao.Upload(c, fileName, fileType, expire, body); err != nil {
log.Error("s.upload.Upload() error(%v)", err)
}
return
}
// AnnualCoins .
func (s *Service) AnnualCoins(c context.Context, reader *csv.Reader) (fmid []int64) {
for {
record, err := reader.Read()
if err == io.EOF {
log.Warn("AnnualCoins is over!")
err = nil
break
}
if err != nil {
log.Error("AnnualCoins(%+v) Error(%+v)", record, err)
err = nil
continue
}
log.Info("AnnualCoins record(%+v)", record)
if len(record) < 2 {
log.Error("AnnualCoins record(%+v) len<2", record)
continue
}
mid, err := strconv.ParseInt(record[0], 10, 64)
if err != nil {
log.Error("AnnualCoins strconv.ParseInt mid(%+v) err(%+v)", record, err)
err = nil
continue
}
coins, err := strconv.ParseInt(record[1], 10, 64)
if err != nil {
log.Error("AnnualCoins strconv.ParseInt coins(%+v) err(%+v)", record, err)
err = nil
continue
}
arg := &coinclient.ModifyCoinsReq{
Mid: mid,
Count: float64(coins),
Reason: "风纪委奖励",
IP: "",
Operator: "credit",
CheckZero: 1,
Ts: time.Now().Unix(),
}
_, err = s.coinClient.ModifyCoins(context.Background(), arg)
if err != nil {
fmid = append(fmid, mid)
log.Error("ModifyCoins arg(%+v), err(%+v)", arg, err)
continue
}
if err = s.msgDao.SendSysMsg(context.Background(), mid, "您的风纪委硬币礼包已到账", "Hi 风纪委员你好你的2018年风纪委硬币礼包已到账快进入你的硬币账户看看吧"); err != nil {
log.Error("SendSysMsg mid(%d), err(%+v)", mid, err)
}
time.Sleep(time.Duration(50) * time.Millisecond)
}
return
}

View File

@@ -0,0 +1,546 @@
package service
import (
"context"
"encoding/json"
"fmt"
"reflect"
"sort"
"strconv"
"time"
creditMDL "go-common/app/admin/main/credit/model"
"go-common/app/admin/main/credit/model/blocked"
account "go-common/app/service/main/account/api"
relationmdl "go-common/app/service/main/relation/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
"go-common/library/sync/errgroup"
xtime "go-common/library/time"
"go-common/library/xstr"
)
// AddJury add jury to admin
func (s *Service) AddJury(c context.Context, arg *blocked.ArgAddJurys) (err error) {
arg.MIDs = creditMDL.ArrayUnique(arg.MIDs)
if len(arg.MIDs) == 0 {
return
}
items := []*blocked.Jury{}
if err = s.blockedDao.ReadDB.Where("mid IN (?)", arg.MIDs).Find(&items).Error; err != nil {
log.Error("s.blockedDao.juryByMIDs(%s) error(%v)", xstr.JoinInts(arg.MIDs), err)
err = nil
}
mids := make(map[int64]*blocked.Jury, len(arg.MIDs))
for _, v := range items {
mids[v.UID] = v
}
day, _ := time.ParseDuration("24h")
users := make([]*blocked.Jury, 0, len(arg.MIDs))
tx := s.DB.Begin()
defer func() {
if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}()
now := time.Now()
var multiple []interface{}
for _, mid := range arg.MIDs {
user := &blocked.Jury{
UID: mid,
Status: blocked.JuryStatusOn,
OPID: arg.OPID,
Remark: blocked.AddJuryRemark,
Expired: xtime.Time(now.Add(day * time.Duration(arg.Day)).Unix()),
}
if jury, ok := mids[mid]; ok {
user.ID = jury.ID
switch {
case jury.Black == blocked.JuryBlack:
continue
case jury.Black == blocked.JuryWhite:
user.Black = blocked.JuryWhite
}
user.CTime = jury.CTime
user.VoteTotal = jury.VoteTotal
user.VoteRight = jury.VoteRight
user.Total = jury.Total
single := map[string]interface{}{
"id": jury.ID,
"oper_id": arg.OPID,
"status": blocked.JuryStatusOn,
"black": user.Black,
"expired": now.Add(day * time.Duration(arg.Day)).Format(creditMDL.TimeFormatSec),
}
multiple = append(multiple, single)
}
if err = tx.Save(&user).Error; err != nil {
log.Error("s.DB.Create error(%v)", err)
return
}
s.AddNotify(func() {
s.Search.SearchUpdate(context.TODO(), blocked.BusinessBlockedJury, blocked.TableBlockedJury, multiple)
})
users = append(users, user)
}
if arg.Send == blocked.NeedSendMsg {
for _, u := range users {
msg := &blocked.SysMsg{
Type: blocked.MsgTypeGetJuryer,
MID: u.UID,
Day: arg.Day,
RemoteIP: metadata.String(c, metadata.RemoteIP),
}
s.MsgCh <- msg
}
}
return
}
// Cases deal case data.
func (s *Service) Cases(c context.Context, arg *blocked.ArgCaseSearch) (list []*blocked.Case, pager *blocked.Pager, err error) {
var ids []int64
ids, pager, err = s.searchDao.Case(c, arg)
if err != nil {
log.Error(" s.searchDao.Case error(%v)", err)
return
}
if len(ids) == 0 {
return
}
var (
accInfoMap map[int64]*account.Info
relationsMap map[int64]*relationmdl.Stat
uids = make([]int64, 0)
)
ids = creditMDL.ArrayUnique(ids)
if err = s.blockedDao.ReadDB.Where("id IN (?)", ids).Order(fmt.Sprintf("%s %s", arg.Order, arg.Sort)).Find(&list).Error; err != nil {
if err != ecode.NothingFound {
log.Error("s.blockedDao(%s) error(%v)", xstr.JoinInts(ids), err)
return
}
log.Warn("search ids(%s) not in db", xstr.JoinInts(ids))
err = nil
}
for _, v := range list {
if v.MID > 0 {
uids = append(uids, v.MID)
}
}
if accInfoMap, err = s.accDao.RPCInfos(c, uids); err != nil {
log.Error("s.accDao.RPCInfos(%s) error(%v)", xstr.JoinInts(uids), err)
err = nil
}
if relationsMap, err = s.RelationDao.RPCStats(c, uids); err != nil {
log.Error("s.RelationDao.RPCStats(%s) error(%v)", xstr.JoinInts(uids), err)
err = nil
}
for _, v := range list {
if accInfo, ok := accInfoMap[v.MID]; ok {
v.Uname = accInfo.Name
}
if relationInfo, ok := relationsMap[v.MID]; ok {
v.Fans = relationInfo.Follower
}
v.OPName = s.Managers[v.OPID]
v.StatusDesc = blocked.StatusDesc[v.Status]
v.OriginTypeDesc = blocked.OriginTypeDesc[v.OriginType]
v.ReasonTypeDesc = blocked.ReasonTypeDesc(v.ReasonType)
v.PunishDesc = blocked.PunishDesc[v.PunishResult]
v.CaseTypeDesc = blocked.CaseTypeDesc[v.CaseType]
v.VoteTotal = blocked.VoteTotal(v.VoteRule, v.VoteBreak, v.VoteDelete)
if v.VoteRule > 0 || v.VoteBreak > 0 || v.VoteDelete > 0 {
v.BlockedPercent = blocked.BreakPercent(v.VoteRule, v.VoteBreak, v.VoteDelete)
v.DeletePercent = blocked.DeletePercent(v.VoteRule, v.VoteBreak, v.VoteDelete)
v.RulePercent = blocked.RulePercent(v.VoteRule, v.VoteBreak, v.VoteDelete)
}
}
return
}
// Opinions is block opinions
func (s *Service) Opinions(c context.Context, arg *blocked.ArgOpinionSearch) (list []*blocked.Opinion, pager *blocked.Pager, err error) {
var ids []int64
ids, pager, err = s.searchDao.Opinion(c, arg)
if err != nil {
log.Error("s.blockedDao.Search appid(%s) error(%v)", "", err)
return
}
if len(ids) == 0 {
return
}
var (
accInfoMap map[int64]*account.Info
relationsMap map[int64]*relationmdl.Stat
uids = make([]int64, 0)
)
ids = creditMDL.ArrayUnique(ids)
if err = s.blockedDao.ReadDB.Where("id IN (?)", ids).Order(fmt.Sprintf("%s %s", arg.Order, arg.Sort)).Find(&list).Error; err != nil {
if err != ecode.NothingFound {
log.Error("s.blockedDao(%s) error(%v)", xstr.JoinInts(ids), err)
return
}
log.Warn("search ids(%s) not in db", xstr.JoinInts(ids))
err = nil
}
for _, v := range list {
if v.MID > 0 {
uids = append(uids, v.MID)
}
}
accInfoMap, err = s.accDao.RPCInfos(c, uids)
if err != nil {
log.Error("s.accDao.RPCInfos error(%v)", err)
err = nil
}
if relationsMap, err = s.RelationDao.RPCStats(c, uids); err != nil {
log.Error("s.RelationDao.RPCStats(%s) error(%v)", xstr.JoinInts(uids), err)
err = nil
}
for _, v := range list {
if opinion, ok := accInfoMap[v.MID]; ok {
v.UName = opinion.Name
}
if relationInfo, ok := relationsMap[v.MID]; ok {
v.Fans = relationInfo.Follower
}
v.OPName = s.Managers[v.OperID]
v.AttrDesc = blocked.AttrDesc[v.Attr]
v.VoteDesc = blocked.VoteDesc[v.Vote]
v.VoteStateDesc = blocked.VoteStateDesc[v.State]
}
return
}
// Jurys select jury lists.
func (s *Service) Jurys(c context.Context, arg *blocked.ArgJurySearch) (list []*blocked.Jury, pager *blocked.Pager, err error) {
var ids []int64
ids, pager, err = s.searchDao.Jury(c, arg)
if err != nil {
log.Error("s.searchDao.Jury error(%v)", err)
return
}
if len(ids) == 0 {
return
}
var (
accInfoMap map[int64]*account.Info
uids = make([]int64, len(ids))
)
ids = creditMDL.ArrayUnique(ids)
if err = s.blockedDao.ReadDB.Where("id IN (?)", ids).Order(fmt.Sprintf("%s %s", arg.Order, arg.Sort)).Find(&list).Error; err != nil {
if err != ecode.NothingFound {
log.Error("s.blockedDao(%s) error(%v)", xstr.JoinInts(ids), err)
return
}
log.Warn("search ids(%s) not in db", xstr.JoinInts(ids))
err = nil
}
for _, v := range list {
uids = append(uids, v.UID)
}
accInfoMap, err = s.accDao.RPCInfos(c, uids)
if err != nil {
log.Error("s.accDao.RPCInfos error(%v)", err)
err = nil
}
for _, v := range list {
if jury, ok := accInfoMap[v.UID]; ok {
v.UName = jury.Name
}
v.OPName = s.Managers[v.OPID]
v.EffectDay = xtime.Time(v.Expired.Time().AddDate(0, 0, -blocked.JuryDay).Unix())
if v.EffectDay < v.CTime {
v.EffectDay = v.CTime
}
if v.VoteTotal > 0 {
v.VoteRadio = strconv.FormatFloat(float64(v.VoteRight)/float64(v.VoteTotal)*100, 'f', 2, 64)
} else {
v.VoteRadio = "-1"
}
v.StatusDesc = blocked.JuryerStatus[v.Status]
v.BlackDesc = blocked.JuryerStyle[v.Black]
}
return
}
// JurysEx export jury list.
func (s *Service) JurysEx(c context.Context, arg *blocked.ArgJurySearch) (list []*blocked.Jury, err error) {
var (
ps = 500
count int
pager *blocked.Pager
g errgroup.Group
)
if list, pager, err = s.Jurys(c, arg); err != nil {
log.Error("s.Infos(%+v) error(%v)", arg, err)
return
}
if pager == nil {
log.Warn("arg(%+v) jury search data empty!", arg)
return
}
count = pager.Total / ps
if pager.Total%ps != 0 {
count++
}
lCh := make(chan []*blocked.Jury, count)
for pn := 1; pn <= count; pn++ {
tmpPn := pn
g.Go(func() (err error) {
var gJury []*blocked.Jury
gArg := &blocked.ArgJurySearch{
UID: arg.UID,
Status: arg.Status,
Black: arg.Black,
ExpiredFrom: arg.ExpiredFrom,
ExpiredTo: arg.ExpiredTo,
Order: arg.Order,
Sort: arg.Sort,
PN: tmpPn,
PS: ps,
}
gJury, _, err = s.Jurys(c, gArg)
if err != nil {
log.Error("s.Jurys(%+v) error(%v)", gJury, err)
err = nil
return
}
lCh <- gJury
return
})
}
g.Wait()
close(lCh)
for jInfo := range lCh {
list = append(list, jInfo...)
}
sort.Slice(list, func(i int, j int) bool {
return list[i].ID < list[j].ID
})
return
}
// UpCaseStatus update case status.
func (s *Service) UpCaseStatus(c context.Context, arg *blocked.ArgUpStatus) (err error) {
items := []blocked.Case{}
if err = s.blockedDao.ReadDB.Where("id IN(?)", arg.IDS).Find(&items).Error; err != nil {
log.Error("s.blockedDao.caseByIDs(%s) error(%v)", xstr.JoinInts(arg.IDS), err)
return
}
var multiple []interface{}
if arg.Status == blocked.CaseStatusGranting {
hour := s.CaseConfig(blocked.ConfigCaseGiveHours)
now := time.Now()
if err = s.DB.Model(blocked.Case{}).Where("id IN(?)", arg.IDS).Updates(
&blocked.Case{
Status: arg.Status,
OPID: arg.OID,
StartTime: xtime.Time(now.Unix()),
EndTime: xtime.Time(now.Add(time.Duration(hour) * time.Hour).Unix()),
}).Error; err != nil {
return
}
for _, item := range items {
single := map[string]interface{}{
"id": item.ID,
"oper_id": arg.OID,
"start_time": now.Format(creditMDL.TimeFormatSec),
"status": arg.Status,
"case_type": item.CaseType,
}
multiple = append(multiple, single)
}
} else {
if err = s.DB.Model(blocked.Case{}).Where("id IN(?)", arg.IDS).Updates(
&blocked.Case{
Status: arg.Status,
OPID: arg.OID,
}).Error; err != nil {
return
}
for _, item := range items {
single := map[string]interface{}{
"id": item.ID,
"oper_id": arg.OID,
"status": arg.Status,
"case_type": item.CaseType,
}
multiple = append(multiple, single)
}
}
s.AddNotify(func() {
s.Search.SearchUpdate(context.TODO(), blocked.BusinessBlockedCase, blocked.TableBlockedCase, multiple)
})
return
}
// CaseReason reason info.
func (s *Service) CaseReason(c context.Context) (cr map[int]string, err error) {
var reason []*blocked.Reason
cr = make(map[int]string)
if err = s.ReadDB.Select([]string{"id", "reason"}).Where("status = 0").Find(&reason).Error; err != nil {
if err == ecode.NothingFound {
err = nil
return
}
return
}
for _, v := range reason {
cr[v.ID] = v.Reason
}
return
}
// CaseConf caseconfig list.
func (s *Service) CaseConf(c context.Context) (cc map[string]string, err error) {
var configs []*blocked.Config
cc = make(map[string]string)
err = s.ReadDB.Select([]string{"config_key", "content"}).Find(&configs).Error
if err != nil || configs == nil {
return
}
for _, v := range configs {
cc[v.ConfigKey] = v.Content
}
return
}
// SetCaseConf update case config.
func (s *Service) SetCaseConf(c context.Context, cc *blocked.ArgCaseConf) (err error) {
v := reflect.ValueOf(cc).Elem()
tx := s.DB.Begin()
defer func() {
if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}()
for i := 0; i < v.NumField(); i++ {
fieldValue := strconv.Itoa(v.Field(i).Interface().(int))
tag := v.Type().Field(i).Tag.Get("form")
if err = tx.Model(&blocked.Config{}).Where("config_key = ?", tag).Updates(map[string]interface{}{"content": fieldValue, "oper_id": cc.OID}).Error; err != nil {
log.Error("caseConfig(%s,%d) update error(%v)", v.Field(i).Type().Name(), v.Field(i).Interface().(int64), err)
return
}
}
return
}
// CaseConfig get config by key.
func (s *Service) CaseConfig(ck string) (cv int64) {
if v, ok := s.caseConfCache[ck]; ok {
cv, _ = strconv.ParseInt(v, 10, 64)
}
return
}
// KPIPoint get kpi_point data
func (s *Service) KPIPoint(c context.Context, arg *blocked.ArgKpiPointSearch) (list []*blocked.KPIPoint, pager *blocked.Pager, err error) {
var ids []int64
ids, pager, err = s.searchDao.KPIPoint(c, arg)
if err != nil {
log.Error("s.searchDao.KPIPoint error (%v)", err)
return
}
if len(ids) == 0 {
return
}
ids = creditMDL.ArrayUnique(ids)
if err = s.blockedDao.ReadDB.Where("id IN (?)", ids).Order(fmt.Sprintf("%s %s", arg.Order, arg.Sort)).Find(&list).Error; err != nil {
if err != ecode.NothingFound {
log.Error("s.blockedDao(%s) error(%v)", xstr.JoinInts(ids), err)
return
}
log.Warn("search ids(%s) not in db", xstr.JoinInts(ids))
err = nil
}
return
}
// VotenumConf votenumConf list.
func (s *Service) VotenumConf(c context.Context) (cc string, err error) {
var bc = &blocked.Config{}
err = s.ReadDB.Select("content").Where("config_key = 'vote_num'").Find(&bc).Error
if err != nil || bc.Content == "" {
log.Error("s.VotenumConf(%s) error(%v)", cc, err)
return
}
cc = bc.Content
return
}
// SetVotenumConf .
func (s *Service) SetVotenumConf(c context.Context, vn *blocked.ArgVoteNum) (err error) {
v := blocked.VoteNum{}
v.RateS = vn.RateS
v.RateA = vn.RateA
v.RateB = vn.RateB
v.RateC = vn.RateC
v.RateD = vn.RateD
vnb, err := json.Marshal(v)
if err != nil {
log.Error("json.Marshal(%+v) error(%v)", v, err)
}
config := &blocked.Config{}
s.ReadDB.Where("config_key = 'vote_num'").Find(config)
var vconfig *blocked.Config
if config != nil && config.ID != 0 {
vconfig = &blocked.Config{
ID: config.ID,
ConfigKey: "vote_num",
Content: string(vnb),
OperID: vn.OID,
}
} else {
vconfig = &blocked.Config{
ConfigKey: "vote_num",
Content: string(vnb),
OperID: vn.OID,
}
}
if err = s.DB.Save(&vconfig).Error; err != nil {
log.Error("http.setAutoCaseConfig error(%v)", err)
return
}
return
}
// WebHook a webhook from work flow.
func (s *Service) WebHook(c context.Context, data []byte) (err error) {
wh := &blocked.WebHook{}
if err = json.Unmarshal(data, &wh); err != nil {
err = ecode.RequestErr
log.Error("webhook json rawmessage(%s) error(%v)", string(data), err)
return
}
if wh.Verb == "chall.SetResult" || wh.Verb == "chall.BatchSetResult" {
if wh.Target == nil || wh.Object == nil {
log.Warn("wh.Target or wh.Object is nil %v,%v", wh.Target, wh.Object)
return
}
// appeal state not changed .
if wh.Target.State == wh.Object.State {
log.Warn("appeal state not changed target=%d object=%d", wh.Target.State, wh.Object.State)
return
}
switch wh.Object.State {
case blocked.AppealStateSucc:
if err = s.blockedDao.DB.Model(&blocked.Info{}).Where("case_id =?", wh.Target.OID).Update("status", blocked.BlockStateClose).Error; err != nil {
log.Error("s.blockedDao.DB error(%v)", err)
return
}
s.MsgCh <- &blocked.SysMsg{Type: blocked.MsgTypeAppealSucc, MID: wh.Target.Mid, CID: wh.Target.OID, RemoteIP: metadata.String(c, metadata.RemoteIP)}
case blocked.AppealStateFail:
s.MsgCh <- &blocked.SysMsg{Type: blocked.MsgTypeAppealFail, MID: wh.Target.Mid, CID: wh.Target.OID, RemoteIP: metadata.String(c, metadata.RemoteIP)}
default:
log.Warn("unknown webhook state(%d) ", wh.Object.State)
}
}
return
}

View File

@@ -0,0 +1,63 @@
package service
import (
"context"
"fmt"
"testing"
"go-common/app/admin/main/credit/model/blocked"
. "github.com/smartystreets/goconvey/convey"
)
func Test_SetCaseConf(t *testing.T) {
Convey("return someting", t, func() {
cc := new(blocked.ArgCaseConf)
cc.CaseCheckHours = 2
cc.CaseGiveHours = 24
cc.CaseJudgeRadio = 60
cc.CaseLoadMax = 20
cc.CaseLoadSwitch = 1
cc.CaseObtainMax = 100
cc.CaseVoteMax = 50
cc.CaseVoteMin = 50
cc.JuryApplyMax = 200
cc.JuryVoteRadio = 40
err := s.SetCaseConf(context.TODO(), cc)
fmt.Println(cc)
fmt.Println(err)
So(err, ShouldBeNil)
So(cc, ShouldNotBeEmpty)
})
}
func Test_CaseConfig(t *testing.T) {
Convey("return someting", t, func() {
cv := s.CaseConfig(blocked.ConfigCaseGiveHours)
fmt.Println(cv)
So(cv, ShouldNotBeEmpty)
})
}
func Test_VotenumConf(t *testing.T) {
Convey("return someting", t, func() {
cc, err := s.VotenumConf(context.TODO())
fmt.Println(cc)
fmt.Println(err)
So(err, ShouldBeNil)
So(cc, ShouldNotBeEmpty)
})
}
func Test_SetVotenumConf(t *testing.T) {
Convey("return someting", t, func() {
vn := new(blocked.ArgVoteNum)
vn.OID = 1
vn.RateS = 3
vn.RateA = 2
vn.RateB = 1
vn.RateC = 1
vn.RateD = 1
err := s.SetVotenumConf(context.TODO(), vn)
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1 @@
package service

View File

@@ -0,0 +1,43 @@
package service
import (
"context"
"time"
blkmodel "go-common/app/admin/main/credit/model/blocked"
"go-common/library/log"
)
func (s *Service) msgproc() {
// NOTE: chan
s.wg.Add(1)
go func() {
var (
c = context.TODO()
sysMsg *blkmodel.SysMsg
ok bool
title, content string
)
defer s.wg.Done()
for {
if sysMsg, ok = <-s.MsgCh; !ok {
log.Info("msgproc s.msgCh proc stop")
return
}
if sysMsg == nil {
select {
case <-time.After(3 * time.Minute):
continue
case <-s.stop:
return
}
}
title, content = blkmodel.MsgInfo(sysMsg)
if err := s.msgDao.SendSysMsg(c, sysMsg.MID, title, content); err != nil {
log.Info("mid(%d) title(%s) content(%s) send sysMsg error(%v)", sysMsg.MID, title, content, err)
continue
}
time.Sleep(100 * time.Millisecond)
}
}()
}

View File

@@ -0,0 +1,153 @@
package service
import (
"context"
"sync"
"time"
"go-common/app/admin/main/credit/conf"
accdao "go-common/app/admin/main/credit/dao/account"
blockedao "go-common/app/admin/main/credit/dao/blocked"
managerdao "go-common/app/admin/main/credit/dao/manager"
msgdao "go-common/app/admin/main/credit/dao/msg"
relationdao "go-common/app/admin/main/credit/dao/relation"
searchdao "go-common/app/admin/main/credit/dao/search"
uploaddao "go-common/app/admin/main/credit/dao/upload"
blkmodel "go-common/app/admin/main/credit/model/blocked"
coinclient "go-common/app/service/main/coin/api"
"go-common/library/log"
"github.com/jinzhu/gorm"
)
// Service struct of service.
type Service struct {
// conf
c *conf.Config
accDao *accdao.Dao
blockedDao *blockedao.Dao
managerDao *managerdao.Dao
searchDao *searchdao.Dao
uploadDao *uploaddao.Dao
msgDao *msgdao.Dao
RelationDao *relationdao.Dao
DB *gorm.DB
ReadDB *gorm.DB
Search *searchdao.Dao
caseConfCache map[string]string
Managers map[int64]string
caseReasons map[int]string
MsgCh chan *blkmodel.SysMsg
notifych chan func()
stop chan struct{}
// wait
wg sync.WaitGroup
coinClient coinclient.CoinClient
}
// New create service instance and return.
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
blockedDao: blockedao.New(c),
managerDao: managerdao.New(c),
accDao: accdao.New(c),
searchDao: searchdao.New(c),
uploadDao: uploaddao.New(c),
RelationDao: relationdao.New(c),
msgDao: msgdao.New(c),
MsgCh: make(chan *blkmodel.SysMsg, c.ChanSize.SysMsg),
notifych: make(chan func(), c.ChanSize.SysMsg),
stop: make(chan struct{}),
}
s.DB = s.blockedDao.DB
s.ReadDB = s.blockedDao.ReadDB
s.Search = s.searchDao
var err error
if s.coinClient, err = coinclient.NewClient(c.CoinClient); err != nil {
panic(err)
}
s.loadConfig()
s.loadManager()
go s.cacheproc()
go s.loadManagerproc()
go s.msgproc()
s.wg.Add(1)
go s.notifyproc()
return s
}
func (s *Service) cacheproc() {
for {
time.Sleep(3 * time.Minute)
s.loadConfig()
}
}
func (s *Service) loadManagerproc() {
for {
time.Sleep(1 * time.Hour)
s.loadManager()
}
}
func (s *Service) loadConfig() {
cc, err := s.CaseConf(context.TODO())
if err != nil {
log.Error("s.CaseConf error(%v)", err)
return
}
s.caseConfCache = cc
cr, err := s.CaseReason(context.TODO())
if err != nil {
log.Error("s.CaseReason error(%v)", err)
return
}
s.caseReasons = cr
}
func (s *Service) loadManager() {
managers, err := s.managerDao.Managers(context.TODO())
if err != nil {
log.Error("s.Managers error(%v)", err)
return
}
s.Managers = managers
}
// AddNotify .
func (s *Service) AddNotify(f func()) {
select {
case s.notifych <- f:
default:
log.Warn("addNotify chan full")
}
}
// notifyproc nofity clear cache
func (s *Service) notifyproc() {
defer s.wg.Done()
for {
f, ok := <-s.notifych
if !ok {
log.Warn("s.notifych chan is close")
return
}
f()
}
}
// Ping check server ok.
func (s *Service) Ping(c context.Context) error {
return s.blockedDao.Ping(c)
}
// Close dao.
func (s *Service) Close() {
s.blockedDao.Close()
close(s.MsgCh)
close(s.notifych)
close(s.stop)
time.Sleep(1 * time.Second)
s.wg.Wait()
}

View File

@@ -0,0 +1,149 @@
package service
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/admin/main/credit/conf"
"go-common/app/admin/main/credit/model/blocked"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
)
// func CleanCache() {
// //c := context.TODO()
// //pool := redis.NewPool(conf.Conf.Redis.Config)
// //pool.Get(c).Do("FLUSHDB")
// }
func init() {
dir, _ := filepath.Abs("../cmd/convey-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(time.Second)
}
// func WithService(f func(s *Service)) func() {
// return func() {
// Reset(func() { CleanCache() })
// f(s)
// }
// }
func TestService_loadConfig(t *testing.T) {
s = New(conf.Conf)
s.loadConfig()
s.loadManager()
//t.Logf("config (%+v)", s.c.Judge)
}
func Test_Infos(t *testing.T) {
arg := &blocked.ArgBlockedSearch{}
Convey("return someting", t, func() {
list, pager, err := s.Infos(context.TODO(), arg)
So(err, ShouldBeNil)
So(list, ShouldNotBeNil)
So(pager, ShouldNotBeNil)
})
}
func Test_InfosEx(t *testing.T) {
arg := &blocked.ArgBlockedSearch{}
Convey("return someting", t, func() {
list, err := s.InfosEx(context.TODO(), arg)
So(err, ShouldBeNil)
So(list, ShouldNotBeNil)
})
}
func Test_Publishs(t *testing.T) {
arg := &blocked.ArgPublishSearch{}
Convey("return someting", t, func() {
list, pager, err := s.Publishs(context.TODO(), arg)
So(err, ShouldBeNil)
So(list, ShouldNotBeNil)
So(pager, ShouldNotBeNil)
})
}
func Test_FormatCSV(t *testing.T) {
var records [][]string
record := []string{"sss", "ssss"}
records = append(records, record)
Convey("return someting", t, func() {
buf := s.FormatCSV(records)
So(buf, ShouldNotBeNil)
})
}
func Test_Upload(t *testing.T) {
Convey("return someting", t, func() {
_, err := s.Upload(context.TODO(), "blocked_info", "", 12313, nil)
So(err, ShouldBeNil)
})
}
func Test_AddJury(t *testing.T) {
arg := &blocked.ArgAddJurys{MIDs: []int64{111, 22}, OPID: 111, Day: 111, Send: 1}
Convey("return someting", t, func() {
err := s.AddJury(context.TODO(), arg)
So(err, ShouldBeNil)
})
}
func Test_Cases(t *testing.T) {
arg := &blocked.ArgCaseSearch{}
Convey("return someting", t, func() {
list, pager, err := s.Cases(context.TODO(), arg)
So(err, ShouldBeNil)
So(list, ShouldNotBeNil)
So(pager, ShouldNotBeNil)
})
}
func Test_Opinions(t *testing.T) {
arg := &blocked.ArgOpinionSearch{}
Convey("return someting", t, func() {
list, pager, err := s.Opinions(context.TODO(), arg)
So(err, ShouldBeNil)
So(list, ShouldNotBeNil)
So(pager, ShouldNotBeNil)
})
}
func Test_Jurys(t *testing.T) {
arg := &blocked.ArgJurySearch{}
Convey("return someting", t, func() {
list, pager, err := s.Jurys(context.TODO(), arg)
So(err, ShouldBeNil)
So(list, ShouldNotBeNil)
So(pager, ShouldNotBeNil)
})
}
func Test_JurysEx(t *testing.T) {
arg := &blocked.ArgJurySearch{}
Convey("return someting", t, func() {
res, err := s.JurysEx(context.TODO(), arg)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}
func Test_KPIPoint(t *testing.T) {
arg := &blocked.ArgKpiPointSearch{}
Convey("return someting", t, func() {
list, pager, err := s.KPIPoint(context.TODO(), arg)
So(err, ShouldBeNil)
So(list, ShouldNotBeNil)
So(pager, ShouldNotBeNil)
})
}

View File

@@ -0,0 +1,16 @@
package service
import (
"context"
account "go-common/app/service/main/account/api"
"go-common/library/log"
)
// UserInfo get account info.
func (s *Service) UserInfo(c context.Context, mid int64) (res *account.InfoReply, err error) {
if res, err = s.accDao.RPCInfo(c, mid); err != nil {
log.Error("s.accDao.RPCInfo error (%v)", err)
}
return
}