作者 yangfu

Merge remote-tracking branch 'origin/test' into dev

@@ -11,6 +11,7 @@ require ( @@ -11,6 +11,7 @@ require (
11 github.com/gavv/httpexpect v2.0.0+incompatible 11 github.com/gavv/httpexpect v2.0.0+incompatible
12 github.com/go-pg/pg/v10 v10.9.0 12 github.com/go-pg/pg/v10 v10.9.0
13 github.com/google/go-querystring v1.1.0 // indirect 13 github.com/google/go-querystring v1.1.0 // indirect
  14 + github.com/gookit/event v1.0.6
14 github.com/imkira/go-interpol v1.1.0 // indirect 15 github.com/imkira/go-interpol v1.1.0 // indirect
15 github.com/linmadan/egglib-go v0.0.0-20210313060205-8b5e456b11f7 16 github.com/linmadan/egglib-go v0.0.0-20210313060205-8b5e456b11f7
16 github.com/mattn/go-colorable v0.1.8 // indirect 17 github.com/mattn/go-colorable v0.1.8 // indirect
@@ -19,7 +20,7 @@ require ( @@ -19,7 +20,7 @@ require (
19 github.com/onsi/gomega v1.11.0 20 github.com/onsi/gomega v1.11.0
20 github.com/sergi/go-diff v1.2.0 // indirect 21 github.com/sergi/go-diff v1.2.0 // indirect
21 github.com/smartystreets/goconvey v1.6.4 // indirect 22 github.com/smartystreets/goconvey v1.6.4 // indirect
22 - github.com/stretchr/testify v1.7.0 23 + github.com/stretchr/testify v1.7.1
23 github.com/tal-tech/go-queue v1.0.5 24 github.com/tal-tech/go-queue v1.0.5
24 github.com/tal-tech/go-zero v1.0.27 25 github.com/tal-tech/go-zero v1.0.27
25 github.com/valyala/fasthttp v1.23.0 // indirect 26 github.com/valyala/fasthttp v1.23.0 // indirect
@@ -164,6 +164,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 @@ -164,6 +164,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
164 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 164 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
165 github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= 165 github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
166 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 166 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
  167 +github.com/gookit/event v1.0.6 h1:/U95T1tBzt9RSSi23pg4VR3B9VWkyM4xv8TXAGi60IQ=
  168 +github.com/gookit/event v1.0.6/go.mod h1:7Udf/q/HQcrK9XE4JZUvbqi46rI1V8r/Pvao2NbPajA=
167 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= 169 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
168 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 170 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
169 github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= 171 github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
@@ -348,8 +350,9 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV @@ -348,8 +350,9 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
348 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 350 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
349 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 351 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
350 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 352 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
351 -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=  
352 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 353 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
  354 +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
  355 +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
353 github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= 356 github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
354 github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= 357 github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
355 github.com/tal-tech/go-queue v1.0.5 h1:cd2o0lPjAFJKIXuEbQvsGypUhzz6FLib4FVVAyxsMtY= 358 github.com/tal-tech/go-queue v1.0.5 h1:cd2o0lPjAFJKIXuEbQvsGypUhzz6FLib4FVVAyxsMtY=
@@ -26,6 +26,8 @@ type CreateMenuCommand struct { @@ -26,6 +26,8 @@ type CreateMenuCommand struct {
26 IsPublish int `json:"isPublish" valid:"Required"` 26 IsPublish int `json:"isPublish" valid:"Required"`
27 // 启用状态(启用:1 禁用:2),默认启用 27 // 启用状态(启用:1 禁用:2),默认启用
28 EnableStatus int `json:"enableStatus" ` 28 EnableStatus int `json:"enableStatus" `
  29 + // 外链接(需要菜单跳转的时候使用)
  30 + Link string `json:"link"`
29 } 31 }
30 32
31 func (createMenuCommand *CreateMenuCommand) Valid(validation *validation.Validation) { 33 func (createMenuCommand *CreateMenuCommand) Valid(validation *validation.Validation) {
@@ -29,6 +29,8 @@ type UpdateMenuCommand struct { @@ -29,6 +29,8 @@ type UpdateMenuCommand struct {
29 IsPublish int `json:"isPublish,omitempty"` 29 IsPublish int `json:"isPublish,omitempty"`
30 // 启用状态(启用:1 禁用:2),默认启用 30 // 启用状态(启用:1 禁用:2),默认启用
31 EnableStatus int `json:"enableStatus"` 31 EnableStatus int `json:"enableStatus"`
  32 + // 外链接(需要菜单跳转的时候使用)
  33 + Link string `json:"link"`
32 } 34 }
33 35
34 func (updateMenuCommand *UpdateMenuCommand) Valid(validation *validation.Validation) { 36 func (updateMenuCommand *UpdateMenuCommand) Valid(validation *validation.Validation) {
  1 +package command
  2 +
  3 +import (
  4 + "fmt"
  5 + "reflect"
  6 + "strings"
  7 +
  8 + "github.com/beego/beego/v2/core/validation"
  9 +)
  10 +
  11 +type TerminalReportCommand struct {
  12 + TerminalType string `json:"terminalType"`
  13 + TerminalId string `json:"terminalId"`
  14 + Command string `json:"command"`
  15 + Content string `json:"content"`
  16 + Table string `json:"table"`
  17 +
  18 + CompanyId int64 `json:"companyId"`
  19 + OrgId int64 `json:"orgId"`
  20 +}
  21 +
  22 +func (terminalReportCommand *TerminalReportCommand) Valid(validation *validation.Validation) {
  23 +
  24 +}
  25 +
  26 +func (terminalReportCommand *TerminalReportCommand) ValidateCommand() error {
  27 + valid := validation.Validation{}
  28 + b, err := valid.Valid(terminalReportCommand)
  29 + if err != nil {
  30 + return err
  31 + }
  32 + if !b {
  33 + elem := reflect.TypeOf(terminalReportCommand).Elem()
  34 + for _, validErr := range valid.Errors {
  35 + field, isExist := elem.FieldByName(validErr.Field)
  36 + if isExist {
  37 + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
  38 + } else {
  39 + return fmt.Errorf(validErr.Message)
  40 + }
  41 + }
  42 + }
  43 + return nil
  44 +}
  1 +package service
  2 +
  3 +import (
  4 + "bytes"
  5 + "fmt"
  6 + "github.com/beego/beego/v2/adapter/utils"
  7 + "github.com/gookit/event"
  8 + "github.com/linmadan/egglib-go/core/application"
  9 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/factory"
  10 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/terminal/command"
  11 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
  12 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/log"
  13 + "io"
  14 +)
  15 +
  16 +var GlobalTerminalManager *TerminalManager
  17 +
  18 +func init() {
  19 + GlobalTerminalManager = NewTerminalManager()
  20 + event.On(domain.UserCreateEvent, event.ListenerFunc(GlobalTerminalManager.SyncUser))
  21 + event.On(domain.UserUpdateEvent, event.ListenerFunc(GlobalTerminalManager.SyncUser))
  22 + event.On(domain.UserEnableEvent, event.ListenerFunc(GlobalTerminalManager.EnableUser))
  23 + event.On(domain.UserSyncEvent, event.ListenerFunc(GlobalTerminalManager.SyncUser))
  24 + event.On(DownEntityEvent, event.ListenerFunc(GlobalTerminalManager.DownEntityEvent))
  25 +}
  26 +
  27 +type TerminalService struct {
  28 +}
  29 +
  30 +func NewTerminalService(options map[string]interface{}) *TerminalService {
  31 + newUserService := &TerminalService{}
  32 + return newUserService
  33 +}
  34 +
  35 +func (svr *TerminalService) TerminalReport(cmd *command.TerminalReportCommand) (interface{}, error) {
  36 + if err := cmd.ValidateCommand(); err != nil {
  37 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  38 + }
  39 + transactionContext, err := factory.CreateTransactionContext(nil)
  40 + if err != nil {
  41 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  42 + }
  43 + if err := transactionContext.StartTransaction(); err != nil {
  44 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  45 + }
  46 + defer func() {
  47 + transactionContext.RollbackTransaction()
  48 + }()
  49 + response, err := terminalReport(cmd, transactionContext)
  50 + if err != nil {
  51 + log.Logger.Error(err.Error())
  52 + return nil, err
  53 + }
  54 + if err := transactionContext.CommitTransaction(); err != nil {
  55 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  56 + }
  57 + return response, nil
  58 +}
  59 +
  60 +func terminalReport(cmd *command.TerminalReportCommand, transactionContext application.TransactionContext) (interface{}, error) {
  61 + var (
  62 + response string = "OK"
  63 + )
  64 +
  65 + switch cmd.Command {
  66 + case "getrequest":
  67 + device, ok := GlobalTerminalManager.GetDevice(cmd.TerminalId)
  68 + if !ok || device == nil {
  69 + break
  70 + }
  71 + if downEntity, ok := device.PopDownEntity(); ok && downEntity != nil {
  72 + response = downEntity.DownCommand()
  73 + }
  74 + break
  75 + case "cdata":
  76 + parseEntities := ParseData(cmd)
  77 + var (
  78 + down DownEntity
  79 + err error
  80 + handler Handler = ZKClockHandler{TransactionContext: transactionContext}
  81 + )
  82 + for _, entity := range parseEntities {
  83 + switch TableType(cmd.Table) {
  84 + case AttLOG:
  85 + down, err = handler.Attendance(entity.(AttLOGUpEntity))
  86 + case BIODATA:
  87 + down, err = handler.BioData(entity.(BIODATAEntity))
  88 + case OPERLOG:
  89 + //if v, ok := entity.(USEREntity); ok {
  90 + // down, err = handler.ReportUser(v)
  91 + //}
  92 + if v, ok := entity.(BIODATAEntity); ok {
  93 + down, err = handler.BioData(v)
  94 + }
  95 + }
  96 + if err != nil {
  97 + log.Logger.Error(err.Error())
  98 + continue
  99 + }
  100 + if down != nil {
  101 + response = down.DownCommand()
  102 + }
  103 + break
  104 + }
  105 + case "devicecmd":
  106 + log.Logger.Debug("【TerminalManager】 收到命令应答 cmd : " + cmd.Content)
  107 + }
  108 +
  109 + return map[string]interface{}{
  110 + "response": response,
  111 + }, nil
  112 +}
  113 +
  114 +func ParseData(cmd *command.TerminalReportCommand) []interface{} {
  115 + result := make([]interface{}, 0)
  116 + buf := bytes.NewBufferString(cmd.Content)
  117 + for {
  118 + line, err := buf.ReadBytes('\n')
  119 + if err == io.EOF {
  120 + break
  121 + }
  122 + if err != nil {
  123 + log.Logger.Error(err.Error())
  124 + break
  125 + }
  126 +
  127 + switch TableType(cmd.Table) {
  128 + case AttLOG:
  129 + columns := bytes.Split(line, ([]byte)("\t"))
  130 + if len(columns) != 11 { //10 + 1 空格
  131 + continue
  132 + }
  133 + result = append(result, AttLOGUpEntity{
  134 + Pin: string(columns[0]),
  135 + CompanyId: cmd.CompanyId,
  136 + OrgId: cmd.OrgId,
  137 + })
  138 + case BIODATA:
  139 + /*BIODATA Pin=3\tNo=0\tIndex=0\tValid=1\tDuress=0\tType=9\tMajorVer=39\tMinorVer=1\tFormat=
  140 + 0\tTmp=apUBEBABQo4JACcBAWiOADA7dP4pU9F31Uxom7NAGjM4eO/8X5Ee4uahkIT11c3188+VguMsd3oCO0O29efRyxofdLiohI4QL7woK3U*/
  141 + columns := readLineToMap(line, "BIODATA")
  142 + result = append(result, BIODATAEntity{
  143 + Pin: columns["Pin"],
  144 + No: columns["No"],
  145 + Index: columns["Index"],
  146 + Duress: columns["Duress"],
  147 + Type: columns["Type"],
  148 + MinorVer: columns["MinorVer"],
  149 + MajorVer: columns["MajorVer"],
  150 + Format: columns["Format"],
  151 + Tmp: columns["Tmp"],
  152 + CompanyId: cmd.CompanyId,
  153 + OrgId: cmd.OrgId,
  154 + })
  155 + case OPERLOG:
  156 + if bytes.HasPrefix(line, []byte("FP")) {
  157 + /*
  158 + FP PIN=3 FID=6 Size=1336 Valid=1 TMP=SqtTUzIxAAAD6O8ECA
  159 + */
  160 + columns := readLineToMap(line, "FP")
  161 + result = append(result, BIODATAEntity{
  162 + Pin: columns["PIN"],
  163 + Type: fmt.Sprintf("%v", BioDataType1),
  164 + Tmp: columns["TMP"],
  165 + CompanyId: cmd.CompanyId,
  166 + OrgId: cmd.OrgId,
  167 + })
  168 + } else if bytes.HasPrefix(line, []byte("USER")) {
  169 + /*
  170 + USER PIN=3 Name=杨xx Pri=14 Passwd= Card=3731588478 Grp=1 TZ=0000000100000000 Verify=-1 ViceCard= StartDatetime=0 EndDatetime=0
  171 + */
  172 + columns := readLineToMap(line, "USER")
  173 + name := columns["Name"] //GbkToUtf8(columns["Name"])
  174 + result = append(result, USEREntity{
  175 + OPERLOGType: "USER",
  176 + Pin: columns["PIN"],
  177 + Name: name,
  178 + CompanyId: cmd.CompanyId,
  179 + OrgId: cmd.OrgId,
  180 + })
  181 + }
  182 + }
  183 + }
  184 + return result
  185 +}
  186 +
  187 +func readLineToMap(line []byte, prefix string) map[string]string {
  188 + var result = make(map[string]string)
  189 + line = bytes.TrimLeft(line, prefix)
  190 + line = bytes.TrimSpace(line)
  191 + columns := bytes.Fields(line)
  192 + for i := range columns {
  193 + kv := bytes.SplitN(columns[i], []byte("="), 2)
  194 + if len(kv) < 2 {
  195 + continue
  196 + }
  197 + //if string(kv[0]) == "Name" {
  198 + // log.Logger.Debug(fmt.Sprintf("%x", kv[1]))
  199 + // log.Logger.Debug(fmt.Sprintf("%v", kv[1]))
  200 + // log.Logger.Debug(fmt.Sprintf("%s", string(kv[1])))
  201 + //}
  202 + result[string(kv[0])] = string(kv[1])
  203 + }
  204 + return result
  205 +}
  206 +
  207 +type Handler interface {
  208 + Attendance(entity AttLOGUpEntity) (DownEntity, error)
  209 + BioData(entity BIODATAEntity) (DownEntity, error)
  210 + ReportUser(entity USEREntity) (DownEntity, error)
  211 +}
  212 +
  213 +type ZKClockHandler struct {
  214 + TransactionContext application.TransactionContext
  215 +}
  216 +
  217 +func (handler ZKClockHandler) Attendance(entity AttLOGUpEntity) (DownEntity, error) {
  218 + var (
  219 + userRepository, _, _ = factory.FastPgUser(handler.TransactionContext, 0)
  220 + userBaseRepository, _, _ = factory.FastPgUserBase(handler.TransactionContext, 0)
  221 + user *domain.User
  222 + userBase *domain.UserBase
  223 + err error
  224 + )
  225 + if user, err = userRepository.FindOne(map[string]interface{}{"companyId": entity.CompanyId, "orgId": entity.OrgId, "icCardNumber": entity.Pin}); err != nil {
  226 + return nil, err
  227 + }
  228 + if userBase, err = userBaseRepository.FindOne(map[string]interface{}{"userBaseId": user.UserBaseId}); err != nil {
  229 + return nil, err
  230 + }
  231 + var sendQuery bool
  232 + // 请求 人脸识别-用户画像
  233 + if len(userBase.UserInfo.FacePortrait) == 0 {
  234 + sendQuery = true
  235 + //event.Fire(DownEntityEvent, map[string]interface{}{"entity": NewQueryBIODATADownEntity(generateSn(), entity.Pin, BioDataType2)})
  236 + }
  237 + // 请求 人脸识别-指纹
  238 + if len(userBase.UserInfo.FingerprintPortrait) == 0 {
  239 + sendQuery = true
  240 + }
  241 + if sendQuery {
  242 + event.Fire(DownEntityEvent, map[string]interface{}{"entity": NewQueryUserInfoDownEntity(generateSn(), entity.Pin)})
  243 + }
  244 + return nil, nil
  245 +}
  246 +
  247 +func (handler ZKClockHandler) BioData(entity BIODATAEntity) (DownEntity, error) {
  248 + var (
  249 + userRepository, _, _ = factory.FastPgUser(handler.TransactionContext, 0)
  250 + userBaseRepository, _, _ = factory.FastPgUserBase(handler.TransactionContext, 0)
  251 + user *domain.User
  252 + userBase *domain.UserBase
  253 + err error
  254 + updateFlag bool
  255 + )
  256 + if user, err = userRepository.FindOne(map[string]interface{}{"companyId": entity.CompanyId, "orgId": entity.OrgId, "icCardNumber": entity.Pin}); err != nil {
  257 + return nil, err
  258 + }
  259 + if userBase, err = userBaseRepository.FindOne(map[string]interface{}{"userBaseId": user.UserBaseId}); err != nil {
  260 + return nil, err
  261 + }
  262 + // 请求 人脸识别-用户画像
  263 + if len(userBase.UserInfo.FacePortrait) == 0 && len(entity.Tmp) > 0 && entity.Type == "9" {
  264 + userBase.UserInfo.FacePortrait = entity.Tmp
  265 + updateFlag = true
  266 + }
  267 + // 请求 人脸识别-指纹
  268 + if len(userBase.UserInfo.FingerprintPortrait) == 0 && len(entity.Tmp) > 0 && entity.Type == "1" {
  269 + userBase.UserInfo.FingerprintPortrait = entity.Tmp
  270 + updateFlag = true
  271 + }
  272 + if updateFlag {
  273 + _, err = userBaseRepository.Save(userBase)
  274 + if err != nil {
  275 + log.Logger.Error(err.Error())
  276 + }
  277 + }
  278 + return nil, err
  279 +}
  280 +
  281 +func (handler ZKClockHandler) ReportUser(entity USEREntity) (DownEntity, error) {
  282 + var (
  283 + userRepository, _, _ = factory.FastPgUser(handler.TransactionContext, 0)
  284 + userBaseRepository, _, _ = factory.FastPgUserBase(handler.TransactionContext, 0)
  285 + user *domain.User
  286 + userBase *domain.UserBase
  287 + err error
  288 + updateFlag bool
  289 + )
  290 + if user, err = userRepository.FindOne(map[string]interface{}{"companyId": entity.CompanyId, "orgId": entity.OrgId, "icCardNumber": entity.Pin}); err != nil {
  291 + return nil, err
  292 + }
  293 + if userBase, err = userBaseRepository.FindOne(map[string]interface{}{"userBaseId": user.UserBaseId}); err != nil {
  294 + return nil, err
  295 + }
  296 + // 请求 人脸识别-用户画像
  297 + //if len(entity.Pin) > 0 && userBase.UserInfo.Pin != entity.Pin {
  298 + // updateFlag = true
  299 + // userBase.UserInfo.Pin = entity.Pin
  300 + //}
  301 + if updateFlag {
  302 + _, err = userBaseRepository.Save(userBase)
  303 + }
  304 + return nil, err
  305 +}
  306 +
  307 +func generateSn() string {
  308 + return string(utils.RandomCreateBytes(10))
  309 +}
  1 +package service
  2 +
  3 +import (
  4 + "container/list"
  5 + "github.com/gookit/event"
  6 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
  7 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/log"
  8 + "sync"
  9 +)
  10 +
  11 +var (
  12 + DownEntityEvent = "down_entity"
  13 +)
  14 +
  15 +type TerminalManager struct {
  16 + TerminalDeviceList []*TerminalDevice
  17 + TerminalDevices sync.Map
  18 +}
  19 +
  20 +func NewTerminalManager() *TerminalManager {
  21 + return &TerminalManager{
  22 + TerminalDeviceList: make([]*TerminalDevice, 0),
  23 + TerminalDevices: sync.Map{},
  24 + }
  25 +}
  26 +
  27 +func (term *TerminalManager) GetDevice(terminalId string) (*TerminalDevice, bool) {
  28 + device, ok := term.TerminalDevices.Load(terminalId)
  29 + if !ok {
  30 + device := NewTerminalDevice(terminalId)
  31 + term.TerminalDevices.Store(terminalId, device)
  32 + log.Logger.Debug("【TerminalManager】 终端上线 add new device:"+terminalId, map[string]interface{}{"device": device})
  33 + term.TerminalDeviceList = append(term.TerminalDeviceList, device)
  34 + return nil, false
  35 + }
  36 + if v, ok := device.(*TerminalDevice); ok {
  37 + return v, ok
  38 + }
  39 + return nil, false
  40 +}
  41 +
  42 +func (term *TerminalManager) PopDownEntityByDevice(sn string) (DownEntity, bool) {
  43 + device, ok := term.GetDevice(sn)
  44 + if !ok {
  45 + return nil, false
  46 + }
  47 + return device.PopDownEntity()
  48 +}
  49 +
  50 +func (term *TerminalManager) AddDownEntityByDevice(sn string, entity interface{}) bool {
  51 + device, ok := term.GetDevice(sn)
  52 + if !ok {
  53 + return false
  54 + }
  55 + device.AddDownEntity(entity)
  56 + return true
  57 +}
  58 +
  59 +func (term *TerminalManager) BroadcastDownEntity(downEntity interface{}) {
  60 + if len(term.TerminalDeviceList) == 0 {
  61 + log.Logger.Debug("【TerminalManager】 当前在线终端:0 广播命令退出")
  62 + return
  63 + }
  64 + for i := range term.TerminalDeviceList {
  65 + term.TerminalDeviceList[i].AddDownEntity(downEntity)
  66 + }
  67 +}
  68 +
  69 +// Listen Event
  70 +
  71 +func (term *TerminalManager) DownEntityEvent(e event.Event) error {
  72 + entity := e.Get("entity")
  73 + if entity != nil {
  74 + term.BroadcastDownEntity(entity)
  75 + }
  76 + return nil
  77 +}
  78 +
  79 +func (term *TerminalManager) SyncUser(e event.Event) error {
  80 + user := e.Get("user")
  81 + userBase := e.Get("userBase")
  82 + if user != nil && userBase == nil {
  83 + assertUser := user.(*domain.User)
  84 + if assertUser.Ext.DepName != "制造中心" {
  85 + log.Logger.Debug("【TerminalManager】 当前用户部门不是 [制造中心] 不进行同步", map[string]interface{}{"user": user})
  86 + return nil
  87 + }
  88 + term.BroadcastDownEntity(NewUpdateUserDownEntity(generateSn(), assertUser.Ext.IcCardNumber, assertUser.Ext.UserName))
  89 + return nil
  90 + }
  91 + if user != nil && userBase != nil {
  92 + assertUser := user.(*domain.User)
  93 + assertUserBase := userBase.(*domain.UserBase)
  94 + if assertUser.Ext.DepName != "制造中心" {
  95 + log.Logger.Debug("【TerminalManager】 当前用户部门不是 [制造中心] 不进行同步", map[string]interface{}{"user": user})
  96 + return nil
  97 + }
  98 + if len(assertUser.Ext.IcCardNumber) == 0 {
  99 + return nil
  100 + }
  101 + if len(assertUserBase.UserInfo.FacePortrait) > 0 {
  102 + term.BroadcastDownEntity(NewUpdateUserFacePortraitDownEntity(generateSn(), assertUser.Ext.IcCardNumber, assertUserBase.UserInfo.FacePortrait))
  103 + }
  104 + if len(assertUserBase.UserInfo.FingerprintPortrait) > 0 {
  105 + term.BroadcastDownEntity(NewUpdateUserFingerprintPortraitDownEntity(generateSn(), assertUser.Ext.IcCardNumber, assertUserBase.UserInfo.FingerprintPortrait))
  106 + }
  107 + term.BroadcastDownEntity(NewUpdateUserDownEntity(generateSn(), assertUser.Ext.IcCardNumber, assertUserBase.UserInfo.UserName))
  108 + }
  109 + return nil
  110 +}
  111 +
  112 +func (term *TerminalManager) EnableUser(e event.Event) error {
  113 + user := e.Get("user")
  114 + if user != nil {
  115 + assertUser := user.(*domain.User)
  116 + if assertUser.EnableStatus == int(domain.UserStatusEnable) {
  117 + term.SyncUser(e)
  118 + } else if assertUser.EnableStatus == int(domain.UserStatusDisable) {
  119 + term.BroadcastDownEntity(NewDeleteDownEntity(generateSn(), assertUser.Ext.IcCardNumber, string(UserInfo)))
  120 + }
  121 + }
  122 + return nil
  123 +}
  124 +
  125 +func (term *TerminalManager) CreateUser(e event.Event) error {
  126 + return term.SyncUser(e)
  127 +}
  128 +
  129 +func (term *TerminalManager) UpdateUser(e event.Event) error {
  130 + return term.EnableUser(e)
  131 +}
  132 +
  133 +type TerminalDevice struct {
  134 + Id string
  135 + DownEntityList *list.List
  136 +}
  137 +
  138 +func NewTerminalDevice(terminalId string) *TerminalDevice {
  139 + return &TerminalDevice{
  140 + Id: terminalId,
  141 + DownEntityList: list.New(),
  142 + }
  143 +}
  144 +
  145 +func (device *TerminalDevice) PopDownEntity() (DownEntity, bool) {
  146 + element := device.DownEntityList.Front()
  147 + if element == nil {
  148 + return nil, false
  149 + }
  150 + device.DownEntityList.Remove(element)
  151 + if v, ok := element.Value.(DownEntity); ok {
  152 + log.Logger.Debug("【TerminalManager】 发送命令 pop down entity to Sender cmd:"+v.DownCommand(), map[string]interface{}{"entity": v})
  153 + return v, ok
  154 + }
  155 + return nil, false
  156 +}
  157 +
  158 +func (device *TerminalDevice) AddDownEntity(downEntity interface{}) {
  159 + v, ok := downEntity.(DownEntity)
  160 + var cmd string
  161 + if ok {
  162 + cmd = v.DownCommand()
  163 + }
  164 + log.Logger.Debug("【TerminalManager】 添加命令 add down entity to Profile cmd:"+cmd, map[string]interface{}{"entity": downEntity})
  165 + device.DownEntityList.PushBack(downEntity)
  166 +}
  1 +package service
  2 +
  3 +import "fmt"
  4 +
  5 +type TableType string
  6 +
  7 +var (
  8 + AttLOG TableType = "ATTLOG" // AttLOG 打卡记录
  9 + UserInfo TableType = "USERINFO" // 用户信息
  10 + FingerTMP TableType = "FINGERTMP" //指纹
  11 + Face TableType = "FACE" //脸部
  12 + OPERLOG TableType = "OPERLOG" //操作记录
  13 + BIODATA TableType = "BIODATA" //一体化数据 (人脸识别等)
  14 +)
  15 +
  16 +// AttLOGUpEntity 打卡记录实体 - 上行命令
  17 +type AttLOGUpEntity struct {
  18 + Pin string
  19 + Time string
  20 + Status string
  21 + Verify string
  22 + Workcode string
  23 + Reserved1 string
  24 + Reserved2 string
  25 + MaskFlag string
  26 + Temperature string
  27 + ConvTemperature string
  28 +
  29 + CompanyId int64 `json:"companyId"`
  30 + OrgId int64 `json:"orgId"`
  31 +}
  32 +
  33 +// FPEntity 指纹 - 上行命令 OPERLOG
  34 +type FPEntity struct {
  35 + OPERLOGType string //"FP" "USER" "BIODATA"
  36 + Pin string
  37 + TFID string
  38 + TSize string
  39 + TValid string
  40 + TTMP string
  41 +
  42 + CompanyId int64 `json:"companyId"`
  43 + OrgId int64 `json:"orgId"`
  44 +}
  45 +
  46 +// USEREntity 用户 - 上行命令 OPERLOG
  47 +type USEREntity struct {
  48 + OPERLOGType string //"FP" "USER" "BIODATA"
  49 + Pin string `json:"pin"`
  50 + Name string `json:"Name"`
  51 + Pri string `json:"Pri"`
  52 + Passwd string `json:"Passwd"`
  53 + Grp string `json:"Grp"`
  54 + TZ string `json:"TZ"`
  55 + Verify string `json:"Verify"`
  56 + ViceCard string `json:"ViceCard"`
  57 + StartDatetime string `json:"StartDatetime"`
  58 + EndDatetime string `json:"EndDatetime"`
  59 +
  60 + CompanyId int64 `json:"companyId"`
  61 + OrgId int64 `json:"orgId"`
  62 +}
  63 +
  64 +// BIODATAEntity 一体化数据实体 - 上行命令 BIODATA
  65 +type BIODATAEntity struct {
  66 + Pin string `json:"pin"`
  67 + No string `json:"tNo"`
  68 + Index string `json:"tIndex"`
  69 + Valid string `json:"tValid"`
  70 + Duress string `json:"tDuress"`
  71 + Type string `json:"tType"`
  72 + MajorVer string `json:"tMajorVer"`
  73 + MinorVer string `json:"tMinorVer"`
  74 + Format string `json:"tFormat"`
  75 + Tmp string `json:"Tmp"`
  76 +
  77 + CompanyId int64 `json:"companyId"`
  78 + OrgId int64 `json:"orgId"`
  79 +}
  80 +
  81 +type DownEntity interface {
  82 + DownCommand() string
  83 +}
  84 +
  85 +func QueryUserInfoRequest(sn string, entity AttLOGUpEntity) string {
  86 + return fmt.Sprintf("C:%v:DATA QUERY USERINFO PIN=%v", sn, entity.Pin)
  87 +}
  88 +
  89 +// QueryUserInfoDownEntity 查询用户信息-下行命令
  90 +type QueryUserInfoDownEntity struct {
  91 + Sn string
  92 + Pin string
  93 +}
  94 +
  95 +func (entity QueryUserInfoDownEntity) DownCommand() string {
  96 + return fmt.Sprintf("C:%v:DATA QUERY USERINFO PIN=%v", entity.Sn, entity.Pin)
  97 +}
  98 +
  99 +func NewQueryUserInfoDownEntity(sn string, pin string) QueryUserInfoDownEntity {
  100 + return QueryUserInfoDownEntity{
  101 + Sn: sn,
  102 + Pin: pin,
  103 + }
  104 +}
  105 +
  106 +type BioDataType int
  107 +
  108 +var (
  109 + BioDataType0 BioDataType = 0 //通用
  110 + BioDataType1 BioDataType = 1 //指纹
  111 + BioDataType2 BioDataType = 0 //面部
  112 + BioDataType3 BioDataType = 3 //声纹
  113 + BioDataType4 BioDataType = 4 //虹膜
  114 + BioDataType5 BioDataType = 5 //视网膜
  115 + BioDataType6 BioDataType = 6 //掌纹
  116 + BioDataType7 BioDataType = 7 //指静脉
  117 + BioDataType8 BioDataType = 8 //手掌
  118 + BioDataType9 BioDataType = 9 //可见光面部
  119 +)
  120 +
  121 +// QueryBioDataDownEntity 查询一体化-下行命令
  122 +type QueryBioDataDownEntity struct {
  123 + Sn string
  124 + Pin string
  125 + Type BioDataType
  126 +}
  127 +
  128 +func (entity QueryBioDataDownEntity) DownCommand() string {
  129 + return fmt.Sprintf("C:%v:DATA QUERY BIODATA Type=%v PIN=%v", entity.Sn, entity.Type, entity.Pin)
  130 +}
  131 +
  132 +func NewQueryBIODATADownEntity(sn string, pin string, t BioDataType) QueryBioDataDownEntity {
  133 + return QueryBioDataDownEntity{
  134 + Sn: sn,
  135 + Pin: pin,
  136 + Type: t,
  137 + }
  138 +}
  139 +
  140 +// DeleteDownEntity 删除-下行命令
  141 +type DeleteDownEntity struct {
  142 + Sn string
  143 + Pin string
  144 + Table string
  145 +}
  146 +
  147 +func (entity DeleteDownEntity) DownCommand() string {
  148 + return fmt.Sprintf("C:%v:DATA DELETE %v PIN=%v", entity.Sn, entity.Table, entity.Pin)
  149 +}
  150 +
  151 +func NewDeleteDownEntity(sn string, pin string, t string) DeleteDownEntity {
  152 + return DeleteDownEntity{
  153 + Sn: sn,
  154 + Pin: pin,
  155 + Table: t,
  156 + }
  157 +}
  158 +
  159 +// UpdateUserDownEntity 更新用户-下行命令
  160 +type UpdateUserDownEntity struct {
  161 + Sn string
  162 + Pin string
  163 + Name string
  164 + Card string
  165 +}
  166 +
  167 +func (entity UpdateUserDownEntity) DownCommand() string {
  168 + return fmt.Sprintf("C:%v:DATA UPDATE USERINFO PIN=%v\tName=%v\tCard=%v", entity.Sn, entity.Pin, entity.Name, entity.Pin)
  169 +}
  170 +
  171 +func NewUpdateUserDownEntity(sn string, pin string, name string) UpdateUserDownEntity {
  172 + return UpdateUserDownEntity{
  173 + Sn: sn,
  174 + Pin: pin,
  175 + Name: name,
  176 + }
  177 +}
  178 +
  179 +// UpdateUserFacePortraitDownEntity 更新用户-人脸识别 -下行命令
  180 +type UpdateUserFacePortraitDownEntity struct {
  181 + Sn string
  182 + Pin string
  183 + FacePortrait string
  184 +}
  185 +
  186 +func (entity UpdateUserFacePortraitDownEntity) DownCommand() string {
  187 + return fmt.Sprintf("C:%v:DATA UPDATE BIODATA Pin=%v\tNo=0\tType=9\tMajorVer=39\tMinorVer=1\tFormat=0\tIndex=0\tValid=1\tDuress=0\tTmp=%v", entity.Sn, entity.Pin, entity.FacePortrait)
  188 +}
  189 +
  190 +func NewUpdateUserFacePortraitDownEntity(sn string, pin string, facePortrait string) UpdateUserFacePortraitDownEntity {
  191 + return UpdateUserFacePortraitDownEntity{
  192 + Sn: sn,
  193 + Pin: pin,
  194 + FacePortrait: facePortrait,
  195 + }
  196 +}
  197 +
  198 +// UpdateUserFingerprintPortraitDownEntity 更新用户-指纹 -下行命令
  199 +type UpdateUserFingerprintPortraitDownEntity struct {
  200 + Sn string
  201 + Pin string
  202 + FingerprintPortrait string
  203 +}
  204 +
  205 +func (entity UpdateUserFingerprintPortraitDownEntity) DownCommand() string {
  206 + return fmt.Sprintf("C:%v:DATA UPDATE FINGERTMP PIN=%v\tFID=5\tSize=%v\tValid=1\tTMP=%v", entity.Sn, entity.Pin, len([]byte(entity.FingerprintPortrait)), entity.FingerprintPortrait)
  207 +}
  208 +
  209 +func NewUpdateUserFingerprintPortraitDownEntity(sn string, pin string, fingerprintPortrait string) UpdateUserFingerprintPortraitDownEntity {
  210 + return UpdateUserFingerprintPortraitDownEntity{
  211 + Sn: sn,
  212 + Pin: pin,
  213 + FingerprintPortrait: fingerprintPortrait,
  214 + }
  215 +}
  1 +package command
  2 +
  3 +import (
  4 + "fmt"
  5 + "github.com/beego/beego/v2/core/validation"
  6 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
  7 + "reflect"
  8 + "strings"
  9 +)
  10 +
  11 +type SyncToAttendanceMachineCommand struct {
  12 + OperateInfo *domain.OperateInfo `json:"-"`
  13 + // 用户关联的角色
  14 + Users []int64 `cname:"用户关联的角色" json:"userIds" valid:"Required"`
  15 +}
  16 +
  17 +func (syncToAttendance *SyncToAttendanceMachineCommand) Valid(validation *validation.Validation) {
  18 + //validation.SetError("CustomValid", "未实现的自定义认证")
  19 +}
  20 +
  21 +func (syncToAttendance *SyncToAttendanceMachineCommand) ValidateCommand() error {
  22 + valid := validation.Validation{}
  23 + b, err := valid.Valid(syncToAttendance)
  24 + if err != nil {
  25 + return err
  26 + }
  27 + if !b {
  28 + elem := reflect.TypeOf(syncToAttendance).Elem()
  29 + for _, validErr := range valid.Errors {
  30 + field, isExist := elem.FieldByName(validErr.Field)
  31 + if isExist {
  32 + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
  33 + } else {
  34 + return fmt.Errorf(validErr.Message)
  35 + }
  36 + }
  37 + }
  38 + return nil
  39 +}
@@ -34,6 +34,8 @@ type Menu struct { @@ -34,6 +34,8 @@ type Menu struct {
34 //IsPublish int `json:"isPublish,omitempty"` 34 //IsPublish int `json:"isPublish,omitempty"`
35 // 启用状态(启用:1 禁用:2),默认启用 35 // 启用状态(启用:1 禁用:2),默认启用
36 EnableStatus int `json:"enableStatus,omitempty"` 36 EnableStatus int `json:"enableStatus,omitempty"`
  37 + // 外链接(需要菜单跳转的时候使用)
  38 + Link string `json:"link"`
37 } 39 }
38 40
39 func (dto *UserAccessMenuDto) LoadDto(menus []*domain.Menu) error { 41 func (dto *UserAccessMenuDto) LoadDto(menus []*domain.Menu) error {
@@ -49,6 +51,7 @@ func (dto *UserAccessMenuDto) LoadDto(menus []*domain.Menu) error { @@ -49,6 +51,7 @@ func (dto *UserAccessMenuDto) LoadDto(menus []*domain.Menu) error {
49 Sort: v.Sort, 51 Sort: v.Sort,
50 EnableStatus: v.EnableStatus, 52 EnableStatus: v.EnableStatus,
51 ParentPath: v.ParentPath, 53 ParentPath: v.ParentPath,
  54 + Link: v.Link,
52 }) 55 })
53 } 56 }
54 57
  1 +package service
  2 +
  3 +import (
  4 + "github.com/gookit/event"
  5 + "github.com/linmadan/egglib-go/core/application"
  6 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/factory"
  7 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/user/command"
  8 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
  9 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/log"
  10 +)
  11 +
  12 +func (userService *UserService) SyncToAttendanceMachine(cmd *command.SyncToAttendanceMachineCommand) (interface{}, error) {
  13 + if err := cmd.ValidateCommand(); err != nil {
  14 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  15 + }
  16 + transactionContext, err := factory.CreateTransactionContext(nil)
  17 + if err != nil {
  18 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  19 + }
  20 + if err := transactionContext.StartTransaction(); err != nil {
  21 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  22 + }
  23 + defer func() {
  24 + transactionContext.RollbackTransaction()
  25 + }()
  26 + userRepository, _, _ := factory.FastPgUser(transactionContext, 0)
  27 +
  28 + _, users, err := userRepository.Find(map[string]interface{}{"companyId": cmd.OperateInfo.CompanyId, "inUserIds": cmd.Users})
  29 + if err != nil {
  30 + return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
  31 + }
  32 +
  33 + for i := range users {
  34 + _, userBase, err := factory.FastPgUserBase(transactionContext, users[i].UserBaseId)
  35 + if err != nil {
  36 + return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
  37 + }
  38 + if err, _ := event.Fire(domain.UserSyncEvent, event.M{"user": users[i], "userBase": userBase}); err != nil {
  39 + log.Logger.Error(err.Error())
  40 + return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
  41 + }
  42 + }
  43 +
  44 + if err := transactionContext.CommitTransaction(); err != nil {
  45 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  46 + }
  47 + return struct{}{}, nil
  48 +}
@@ -2,6 +2,7 @@ package service @@ -2,6 +2,7 @@ package service
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
  5 + "github.com/gookit/event"
5 "github.com/linmadan/egglib-go/core/application" 6 "github.com/linmadan/egglib-go/core/application"
6 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/factory" 7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/factory"
7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/user/command" 8 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/user/command"
@@ -66,7 +67,7 @@ func (userService *UserService) BatchAdd2(batchAddCommand *command.BatchAdd2Comm @@ -66,7 +67,7 @@ func (userService *UserService) BatchAdd2(batchAddCommand *command.BatchAdd2Comm
66 "transactionContext": transactionContext, 67 "transactionContext": transactionContext,
67 }) 68 })
68 var failRows []*domain.BatchAddUserItem 69 var failRows []*domain.BatchAddUserItem
69 - if failRows, err = batchAddUserService.BatchAddUser2(batchAddCommand.OperateInfo, batchAddCommand.Users, batchAddCommand.Password); err != nil { 70 + if failRows, err = batchAddUserService.BatchAddUser(batchAddCommand.OperateInfo, batchAddCommand.Users, batchAddCommand.Password); err != nil {
70 return batchAddCommand.Users, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) 71 return batchAddCommand.Users, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
71 } 72 }
72 if len(failRows) != 0 { 73 if len(failRows) != 0 {
@@ -110,6 +111,9 @@ func (userService *UserService) BatchEnable(batchEnableCommand *command.BatchEna @@ -110,6 +111,9 @@ func (userService *UserService) BatchEnable(batchEnableCommand *command.BatchEna
110 if _, err := userRepository.Save(user); err != nil { 111 if _, err := userRepository.Save(user); err != nil {
111 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) 112 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
112 } 113 }
  114 + if err, _ := event.Fire(domain.UserEnableEvent, map[string]interface{}{"user": user}); err != nil {
  115 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  116 + }
113 } 117 }
114 } 118 }
115 119
@@ -68,9 +68,10 @@ type Menu struct { @@ -68,9 +68,10 @@ type Menu struct {
68 ParentPath string `json:"parentPath,omitempty"` 68 ParentPath string `json:"parentPath,omitempty"`
69 // 菜单是否公开状态,[1:显示],[2:隐藏],默认显示 69 // 菜单是否公开状态,[1:显示],[2:隐藏],默认显示
70 IsPublish int `json:"isPublish,omitempty"` 70 IsPublish int `json:"isPublish,omitempty"`
71 - // 启用状态(启用:1 禁用:2),默认启用 71 + // 启用状态(启用:1 禁用:2),默认启用 (移除不使用,现在只有is_publish状态)
72 EnableStatus int `json:"enableStatus,omitempty"` 72 EnableStatus int `json:"enableStatus,omitempty"`
73 - 73 + // 外链接(需要菜单跳转的时候使用)
  74 + Link string `json:"link"`
74 // 父级菜单名称 75 // 父级菜单名称
75 ParentMenuName string `json:"parentMenuName,omitempty"` 76 ParentMenuName string `json:"parentMenuName,omitempty"`
76 } 77 }
@@ -3,6 +3,8 @@ package domain @@ -3,6 +3,8 @@ package domain
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/constant" 5 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/constant"
  6 + "strconv"
  7 + "strings"
6 "time" 8 "time"
7 ) 9 )
8 10
@@ -44,7 +46,7 @@ type Org struct { @@ -44,7 +46,7 @@ type Org struct {
44 OrgStatus int `json:"orgStatus,omitempty"` 46 OrgStatus int `json:"orgStatus,omitempty"`
45 // 父级ID 47 // 父级ID
46 ParentId int64 `json:"parentId,omitempty"` 48 ParentId int64 `json:"parentId,omitempty"`
47 - // 父级节点路径("0,11,12,") 49 + // 父级节点路径("11,12") 注意:parent_id为0时 parentPath "",公司级别的组织没有父级组织
48 ParentPath string `json:"parentPath,omitempty"` 50 ParentPath string `json:"parentPath,omitempty"`
49 51
50 // 企业id 52 // 企业id
@@ -197,6 +199,23 @@ func (org *Org) ID() string { @@ -197,6 +199,23 @@ func (org *Org) ID() string {
197 return org.GetFullPath() 199 return org.GetFullPath()
198 } 200 }
199 201
  202 +func (org *Org) IsChild(pid int64) bool {
  203 + paths := strings.Split(org.ParentPath, PathSegment)
  204 + pidStr := strconv.FormatInt(pid, 10)
  205 + if org.OrgId == pid {
  206 + return true
  207 + }
  208 + if org.ParentId == pid {
  209 + return true
  210 + }
  211 + for _, v := range paths {
  212 + if strings.EqualFold(pidStr, v) {
  213 + return true
  214 + }
  215 + }
  216 + return false
  217 +}
  218 +
200 /***** 2.缓存模块 *****/ 219 /***** 2.缓存模块 *****/
201 220
202 func (m *Org) CacheKeyFunc() string { 221 func (m *Org) CacheKeyFunc() string {
@@ -4,6 +4,5 @@ import "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain" @@ -4,6 +4,5 @@ import "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
4 4
5 // PgBatchAddUserService 批量添加用户服务 5 // PgBatchAddUserService 批量添加用户服务
6 type PgBatchAddUserService interface { 6 type PgBatchAddUserService interface {
7 - BatchAddUser(optUser *domain.OperateInfo, users []*domain.User, password string) error  
8 - BatchAddUser2(optUser *domain.OperateInfo, users []*domain.BatchAddUserItem, password string) ([]*domain.BatchAddUserItem, error) 7 + BatchAddUser(optUser *domain.OperateInfo, users []*domain.BatchAddUserItem, password string) ([]*domain.BatchAddUserItem, error)
9 } 8 }
@@ -26,6 +26,14 @@ const ( @@ -26,6 +26,14 @@ const (
26 UserStatusDestroy UserStatus = 3 26 UserStatusDestroy UserStatus = 3
27 ) 27 )
28 28
  29 +const (
  30 + UserUpdateEvent = "user_update"
  31 + UserDeleteEvent = "user_delete"
  32 + UserCreateEvent = "user_create"
  33 + UserEnableEvent = "user_enable" //禁用启用事件
  34 + UserSyncEvent = "user_sync" // 用户同步
  35 +)
  36 +
29 // 用户 37 // 用户
30 type User struct { 38 type User struct {
31 // 用户Id 用户唯一标识 39 // 用户Id 用户唯一标识
@@ -13,9 +13,16 @@ type UserInfo struct { @@ -13,9 +13,16 @@ type UserInfo struct {
13 13
14 // 员工类型 1:固定 2:派遣 3.临时 14 // 员工类型 1:固定 2:派遣 3.临时
15 EmployeeType int `json:"employeeType,omitempty"` 15 EmployeeType int `json:"employeeType,omitempty"`
16 - // IC卡号 16 + // IC卡号 = Pin
17 IcCardNumber string `json:"icCardNumber,omitempty"` 17 IcCardNumber string `json:"icCardNumber,omitempty"`
18 18
  19 + // 面部识别
  20 + FacePortrait string `json:"facePortrait,omitempty"`
  21 + // 指纹识别
  22 + FingerprintPortrait string `json:"fingerprintPortrait,omitempty"`
  23 + // 打卡机标识
  24 + // Pin string `json:"pin"`
  25 +
19 Referer string `json:"-"` 26 Referer string `json:"-"`
20 // 部门 27 // 部门
21 DepartmentName string `cname:"部门" json:"-"` 28 DepartmentName string `cname:"部门" json:"-"`
@@ -18,71 +18,71 @@ type PgBatchAddUserService struct { @@ -18,71 +18,71 @@ type PgBatchAddUserService struct {
18 // optUser 操作用户 18 // optUser 操作用户
19 // users 待添加用户列表数据 19 // users 待添加用户列表数据
20 // password 密码 20 // password 密码
21 -func (ptr *PgBatchAddUserService) BatchAddUser(optUser *domain.OperateInfo, users []*domain.User, password string) error {  
22 - var (  
23 - err error  
24 - )  
25 - orgRepository, err := repository.NewOrgRepository(ptr.transactionContext)  
26 - if err != nil {  
27 - return err  
28 - }  
29 - _, orgs, err := orgRepository.Find(map[string]interface{}{"companyId": optUser.CompanyId})  
30 - if err != nil {  
31 - return err  
32 - }  
33 - var mapOrg = make(map[int64]*domain.Org)  
34 - for i := range orgs {  
35 - mapOrg[orgs[i].OrgId] = orgs[i]  
36 - }  
37 -  
38 - createUserService, _ := NewPgCreateUserService(ptr.transactionContext)  
39 - for i := range users {  
40 - user := users[i]  
41 - if err = ptr.preCheck(user); err != nil {  
42 - return err  
43 - }  
44 - newUser := &domain.User{  
45 - CompanyId: user.CompanyId,  
46 - UserType: user.UserType,  
47 - UserCode: user.UserCode,  
48 - OrganizationId: user.OrganizationId,  
49 - DepartmentId: user.DepartmentId,  
50 - UserOrg: []*domain.Org{},  
51 - UserRole: []*domain.Role{},  
52 - FavoriteMenus: []string{},  
53 - CooperationInfo: user.CooperationInfo,  
54 - UserInfo: user.UserInfo,  
55 - EnableStatus: int(domain.UserStatusEnable),  
56 - Ext: &domain.Ext{  
57 - Phone: user.UserInfo.Phone,  
58 - UserName: user.UserInfo.UserName,  
59 - },  
60 - CreatedAt: time.Now(),  
61 - UpdatedAt: time.Now(),  
62 - }  
63 - if user.OrganizationId > 0 {  
64 - if v, ok := mapOrg[user.OrganizationId]; ok && v.CompanyId == user.CompanyId {  
65 - newUser.Ext.OrgName = v.OrgName  
66 - } else {  
67 - return fmt.Errorf("导入的组织机构不存在")  
68 - }  
69 - }  
70 - if user.DepartmentId > 0 {  
71 - if v, ok := mapOrg[user.DepartmentId]; ok && v.CompanyId == user.CompanyId {  
72 - newUser.Ext.DepName = v.OrgName  
73 - } else {  
74 - return fmt.Errorf("导入的所属部门不存在")  
75 - }  
76 - }  
77 -  
78 - if newUser, err = createUserService.CreateUser(nil, newUser, password); err != nil {  
79 - return err  
80 - }  
81 - }  
82 - return nil  
83 -} 21 +//func (ptr *PgBatchAddUserService) BatchAddUser(optUser *domain.OperateInfo, users []*domain.User, password string) error {
  22 +// var (
  23 +// err error
  24 +// )
  25 +// orgRepository, err := repository.NewOrgRepository(ptr.transactionContext)
  26 +// if err != nil {
  27 +// return err
  28 +// }
  29 +// _, orgs, err := orgRepository.Find(map[string]interface{}{"companyId": optUser.CompanyId})
  30 +// if err != nil {
  31 +// return err
  32 +// }
  33 +// var mapOrg = make(map[int64]*domain.Org)
  34 +// for i := range orgs {
  35 +// mapOrg[orgs[i].OrgId] = orgs[i]
  36 +// }
  37 +//
  38 +// createUserService, _ := NewPgCreateUserService(ptr.transactionContext)
  39 +// for i := range users {
  40 +// user := users[i]
  41 +// if err = ptr.preCheck(user); err != nil {
  42 +// return err
  43 +// }
  44 +// newUser := &domain.User{
  45 +// CompanyId: user.CompanyId,
  46 +// UserType: user.UserType,
  47 +// UserCode: user.UserCode,
  48 +// OrganizationId: user.OrganizationId,
  49 +// DepartmentId: user.DepartmentId,
  50 +// UserOrg: []*domain.Org{},
  51 +// UserRole: []*domain.Role{},
  52 +// FavoriteMenus: []string{},
  53 +// CooperationInfo: user.CooperationInfo,
  54 +// UserInfo: user.UserInfo,
  55 +// EnableStatus: int(domain.UserStatusEnable),
  56 +// Ext: &domain.Ext{
  57 +// Phone: user.UserInfo.Phone,
  58 +// UserName: user.UserInfo.UserName,
  59 +// },
  60 +// CreatedAt: time.Now(),
  61 +// UpdatedAt: time.Now(),
  62 +// }
  63 +// if user.OrganizationId > 0 {
  64 +// if v, ok := mapOrg[user.OrganizationId]; ok && v.CompanyId == user.CompanyId {
  65 +// newUser.Ext.OrgName = v.OrgName
  66 +// } else {
  67 +// return fmt.Errorf("导入的组织机构不存在")
  68 +// }
  69 +// }
  70 +// if user.DepartmentId > 0 {
  71 +// if v, ok := mapOrg[user.DepartmentId]; ok && v.CompanyId == user.CompanyId {
  72 +// newUser.Ext.DepName = v.OrgName
  73 +// } else {
  74 +// return fmt.Errorf("导入的所属部门不存在")
  75 +// }
  76 +// }
  77 +//
  78 +// if newUser, err = createUserService.CreateUser(nil, newUser, password); err != nil {
  79 +// return err
  80 +// }
  81 +// }
  82 +// return nil
  83 +//}
84 84
85 -func (ptr *PgBatchAddUserService) BatchAddUser2(optUser *domain.OperateInfo, users []*domain.BatchAddUserItem, password string) ([]*domain.BatchAddUserItem, error) { 85 +func (ptr *PgBatchAddUserService) BatchAddUser(optUser *domain.OperateInfo, users []*domain.BatchAddUserItem, password string) ([]*domain.BatchAddUserItem, error) {
86 var ( 86 var (
87 err error 87 err error
88 ) 88 )
@@ -99,6 +99,10 @@ func (ptr *PgBatchAddUserService) BatchAddUser2(optUser *domain.OperateInfo, use @@ -99,6 +99,10 @@ func (ptr *PgBatchAddUserService) BatchAddUser2(optUser *domain.OperateInfo, use
99 for i := range orgs { 99 for i := range orgs {
100 mapOrg[orgs[i].OrgCode] = orgs[i] 100 mapOrg[orgs[i].OrgCode] = orgs[i]
101 } 101 }
  102 + optUserOrg, err := orgRepository.FindOne(map[string]interface{}{"orgId": optUser.OrgId})
  103 + if err != nil {
  104 + return failRows, err
  105 + }
102 106
103 createUserService, _ := NewPgCreateUserService(ptr.transactionContext) 107 createUserService, _ := NewPgCreateUserService(ptr.transactionContext)
104 for i := range users { 108 for i := range users {
@@ -108,23 +112,31 @@ func (ptr *PgBatchAddUserService) BatchAddUser2(optUser *domain.OperateInfo, use @@ -108,23 +112,31 @@ func (ptr *PgBatchAddUserService) BatchAddUser2(optUser *domain.OperateInfo, use
108 failRows = append(failRows, user) 112 failRows = append(failRows, user)
109 continue 113 continue
110 } 114 }
111 - var org, dep *domain.Org 115 + var org = optUserOrg
  116 + var dep *domain.Org
112 var ok bool 117 var ok bool
113 - if org, ok = mapOrg[user.Org]; !ok {  
114 - user.FailReason = "导入的组织机构不存在:" + user.Org  
115 - failRows = append(failRows, user)  
116 - continue  
117 - } 118 + // 使用导入用户的组织作为默认组织
  119 + //if org, ok = mapOrg[user.Org]; !ok {
  120 + // user.FailReason = "导入的组织机构不存在:" + user.Org
  121 + // failRows = append(failRows, user)
  122 + // continue
  123 + //}
118 if dep, ok = mapOrg[user.Department]; !ok && user.UserType != domain.UserTypeCooperation { 124 if dep, ok = mapOrg[user.Department]; !ok && user.UserType != domain.UserTypeCooperation {
119 user.FailReason = "导入的所属部门不存在:" + user.Department 125 user.FailReason = "导入的所属部门不存在:" + user.Department
120 failRows = append(failRows, user) 126 failRows = append(failRows, user)
121 continue 127 continue
122 } 128 }
  129 + //TODO:子部门判断
  130 + //if dep != nil && !dep.IsChild(optUser.OrgId) {
  131 + // user.FailReason = fmt.Sprintf("导入的所属部门不是当前登录组织(%v)的子部门:%v", optUserOrg.OrgName, user.Department)
  132 + // failRows = append(failRows, user)
  133 + // continue
  134 + //}
123 newUser := &domain.User{ 135 newUser := &domain.User{
124 CompanyId: user.CompanyId, 136 CompanyId: user.CompanyId,
125 UserType: user.UserType, 137 UserType: user.UserType,
126 UserCode: user.UserCode, 138 UserCode: user.UserCode,
127 - OrganizationId: org.OrgId, 139 + OrganizationId: optUser.OrgId,
128 UserOrg: []*domain.Org{}, 140 UserOrg: []*domain.Org{},
129 UserRole: []*domain.Role{}, 141 UserRole: []*domain.Role{},
130 FavoriteMenus: []string{}, 142 FavoriteMenus: []string{},
@@ -172,24 +184,24 @@ func (ptr *PgBatchAddUserService) BatchAddUser2(optUser *domain.OperateInfo, use @@ -172,24 +184,24 @@ func (ptr *PgBatchAddUserService) BatchAddUser2(optUser *domain.OperateInfo, use
172 return failRows, nil 184 return failRows, nil
173 } 185 }
174 186
175 -func (ptr *PgBatchAddUserService) preCheck(user *domain.User) error {  
176 - if len(user.UserCode) == 0 {  
177 - return fmt.Errorf("导入的用户编码为空值")  
178 - }  
179 - if len(user.UserInfo.UserName) == 0 {  
180 - return fmt.Errorf("导入的用户姓名为空值")  
181 - }  
182 - if len(user.UserInfo.Phone) == 0 || len(user.UserInfo.Phone) != 11 {  
183 - return fmt.Errorf("导入的手机号不是有效手机号")  
184 - }  
185 - if user.OrganizationId == 0 {  
186 - return fmt.Errorf("导入的组织机构不存在")  
187 - }  
188 - if user.DepartmentId == 0 && user.UserType == domain.UserTypeEmployee {  
189 - return fmt.Errorf("导入的所属部门不存在")  
190 - }  
191 - return nil  
192 -} 187 +//func (ptr *PgBatchAddUserService) preCheck(user *domain.User) error {
  188 +// if len(user.UserCode) == 0 {
  189 +// return fmt.Errorf("导入的用户编码为空值")
  190 +// }
  191 +// if len(user.UserInfo.UserName) == 0 {
  192 +// return fmt.Errorf("导入的用户姓名为空值")
  193 +// }
  194 +// if len(user.UserInfo.Phone) == 0 || len(user.UserInfo.Phone) != 11 {
  195 +// return fmt.Errorf("导入的手机号不是有效手机号")
  196 +// }
  197 +// if user.OrganizationId == 0 {
  198 +// return fmt.Errorf("导入的组织机构不存在")
  199 +// }
  200 +// if user.DepartmentId == 0 && user.UserType == domain.UserTypeEmployee {
  201 +// return fmt.Errorf("导入的所属部门不存在")
  202 +// }
  203 +// return nil
  204 +//}
193 205
194 func (ptr *PgBatchAddUserService) preCheck2(user *domain.BatchAddUserItem) error { 206 func (ptr *PgBatchAddUserService) preCheck2(user *domain.BatchAddUserItem) error {
195 if len(user.UserCode) == 0 { 207 if len(user.UserCode) == 0 {
@@ -2,6 +2,7 @@ package domainService @@ -2,6 +2,7 @@ package domainService
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
  5 + "github.com/gookit/event"
5 pgTransaction "github.com/linmadan/egglib-go/transaction/pg" 6 pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
6 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain" 7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/repository" 8 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/repository"
@@ -96,6 +97,10 @@ func (ptr *PgCreateUserService) CreateUser(optUser *domain.User, newUser *domain @@ -96,6 +97,10 @@ func (ptr *PgCreateUserService) CreateUser(optUser *domain.User, newUser *domain
96 return nil, err 97 return nil, err
97 } 98 }
98 } 99 }
  100 + // 新建用户事件
  101 + if err, _ := event.Fire(domain.UserCreateEvent, event.M{"user": newUser, "userBase": userBase}); err != nil {
  102 + return nil, err
  103 + }
99 return user, nil 104 return user, nil
100 } 105 }
101 106
@@ -22,6 +22,7 @@ type PgRoleAccessMenusService struct { @@ -22,6 +22,7 @@ type PgRoleAccessMenusService struct {
22 func (ptr *PgRoleAccessMenusService) AccessMenus(options *domain.OperateInfo, roleIds []int64, option domain.AccessMenusOptions) ([]*domain.Menu, error) { 22 func (ptr *PgRoleAccessMenusService) AccessMenus(options *domain.OperateInfo, roleIds []int64, option domain.AccessMenusOptions) ([]*domain.Menu, error) {
23 var err error 23 var err error
24 var menus []*domain.Menu 24 var menus []*domain.Menu
  25 + var hasAdminRole bool = false
25 menuIdSet := hashset.New() 26 menuIdSet := hashset.New()
26 if len(roleIds) == 0 { 27 if len(roleIds) == 0 {
27 return menus, nil 28 return menus, nil
@@ -34,6 +35,9 @@ func (ptr *PgRoleAccessMenusService) AccessMenus(options *domain.OperateInfo, ro @@ -34,6 +35,9 @@ func (ptr *PgRoleAccessMenusService) AccessMenus(options *domain.OperateInfo, ro
34 if role, _ = roleRepository.FindOne(map[string]interface{}{"roleId": roleIds[i]}); role == nil { 35 if role, _ = roleRepository.FindOne(map[string]interface{}{"roleId": roleIds[i]}); role == nil {
35 continue 36 continue
36 } 37 }
  38 + if role.RoleType&domain.RoleTypeAdmin > 0 {
  39 + hasAdminRole = true
  40 + }
37 // 只要当前登录组织的有权限菜单 41 // 只要当前登录组织的有权限菜单
38 if option.OrgId > 0 && option.OrgId != role.OrgId { 42 if option.OrgId > 0 && option.OrgId != role.OrgId {
39 continue 43 continue
@@ -66,7 +70,7 @@ func (ptr *PgRoleAccessMenusService) AccessMenus(options *domain.OperateInfo, ro @@ -66,7 +70,7 @@ func (ptr *PgRoleAccessMenusService) AccessMenus(options *domain.OperateInfo, ro
66 if err != nil { 70 if err != nil {
67 return nil, err 71 return nil, err
68 } 72 }
69 - _, alias, err := customizeMenuRepository.Find(map[string]interface{}{"companyId": option.CompanyId}) 73 + _, menuAlias, err := customizeMenuRepository.Find(map[string]interface{}{"companyId": option.CompanyId})
70 if err != nil { 74 if err != nil {
71 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) 75 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
72 } 76 }
@@ -75,17 +79,22 @@ func (ptr *PgRoleAccessMenusService) AccessMenus(options *domain.OperateInfo, ro @@ -75,17 +79,22 @@ func (ptr *PgRoleAccessMenusService) AccessMenus(options *domain.OperateInfo, ro
75 var mapMenus = make(map[int64]*domain.Menu) 79 var mapMenus = make(map[int64]*domain.Menu)
76 for i := range menus { 80 for i := range menus {
77 menus[i].EnableStatus = domain.MenuStatusDisable 81 menus[i].EnableStatus = domain.MenuStatusDisable
  82 + if menus[i].IsPublish == domain.MenuPublic && hasAdminRole {
  83 + menus[i].EnableStatus = domain.MenuStatusEnable //管理员角色,返回所有权限
  84 + }
78 mapMenus[menus[i].MenuId] = menus[i] 85 mapMenus[menus[i].MenuId] = menus[i]
79 } 86 }
80 - for i := range alias {  
81 - if v, ok := mapMenus[alias[i].MenuId]; ok {  
82 - v.MenuName = alias[i].MenuAlias // 设置别名  
83 - v.Sort = alias[i].Sort 87 + // 4.1.设置别名
  88 + for i := range menuAlias {
  89 + if v, ok := mapMenus[menuAlias[i].MenuId]; ok {
  90 + v.MenuName = menuAlias[i].MenuAlias
  91 + v.Sort = menuAlias[i].Sort
84 } 92 }
85 } 93 }
  94 + // 4.2.设置菜单权限状态
86 values := menuIdSet.Values() 95 values := menuIdSet.Values()
87 for i := range values { 96 for i := range values {
88 - menuId := (values[i]).(int64) // 设置菜单权限状态 97 + menuId := (values[i]).(int64)
89 if v, ok := mapMenus[menuId]; ok { 98 if v, ok := mapMenus[menuId]; ok {
90 v.EnableStatus = domain.MenuStatusEnable 99 v.EnableStatus = domain.MenuStatusEnable
91 } 100 }
@@ -2,6 +2,7 @@ package domainService @@ -2,6 +2,7 @@ package domainService
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
  5 + "github.com/gookit/event"
5 pgTransaction "github.com/linmadan/egglib-go/transaction/pg" 6 pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
6 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain" 7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/repository" 8 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/repository"
@@ -108,6 +109,10 @@ func (ptr *PgUpdateUserService) UpdateUser(optUser *domain.OperateInfo, user *do @@ -108,6 +109,10 @@ func (ptr *PgUpdateUserService) UpdateUser(optUser *domain.OperateInfo, user *do
108 if user, err = userRepository.Save(user); err != nil { 109 if user, err = userRepository.Save(user); err != nil {
109 return nil, err 110 return nil, err
110 } 111 }
  112 + // 新建用户事件
  113 + if err, _ := event.Fire(domain.UserUpdateEvent, event.M{"user": user, "userBase": userBase}); err != nil {
  114 + return nil, err
  115 + }
111 return user, nil 116 return user, nil
112 } 117 }
113 118
@@ -28,6 +28,8 @@ type Menu struct { @@ -28,6 +28,8 @@ type Menu struct {
28 IsPublish int `comment:"菜单是否公开状态,[2:隐藏],[1:显示],默认显示"` 28 IsPublish int `comment:"菜单是否公开状态,[2:隐藏],[1:显示],默认显示"`
29 // 启用状态(启用:1 禁用:2),默认启用 29 // 启用状态(启用:1 禁用:2),默认启用
30 EnableStatus int `comment:"启用状态(启用:1 禁用:2),默认启用"` 30 EnableStatus int `comment:"启用状态(启用:1 禁用:2),默认启用"`
  31 + // 外链接(需要菜单跳转的时候使用)
  32 + Link string `json:"link"`
31 // 删除时间 33 // 删除时间
32 //DeletedAt time.Time `comment:"删除时间"` 34 //DeletedAt time.Time `comment:"删除时间"`
33 } 35 }
@@ -21,5 +21,6 @@ func TransformToMenuDomainModelFromPgModels(menuModel *models.Menu) (*domain.Men @@ -21,5 +21,6 @@ func TransformToMenuDomainModelFromPgModels(menuModel *models.Menu) (*domain.Men
21 ParentPath: menuModel.ParentPath, 21 ParentPath: menuModel.ParentPath,
22 IsPublish: menuModel.IsPublish, 22 IsPublish: menuModel.IsPublish,
23 EnableStatus: menuModel.EnableStatus, 23 EnableStatus: menuModel.EnableStatus,
  24 + Link: menuModel.Link,
24 }, nil 25 }, nil
25 } 26 }
@@ -204,6 +204,9 @@ func (repository *UserRepository) Find(queryOptions map[string]interface{}) (int @@ -204,6 +204,9 @@ func (repository *UserRepository) Find(queryOptions map[string]interface{}) (int
204 } 204 }
205 query.SetWhereByQueryOption("company_id=?", "companyId") 205 query.SetWhereByQueryOption("company_id=?", "companyId")
206 query.SetWhereByQueryOption("organization_id=?", "organizationId") 206 query.SetWhereByQueryOption("organization_id=?", "organizationId")
  207 + if v, ok := queryOptions["inUserIds"]; ok && len(v.([]int64)) > 0 {
  208 + query.Where(`user_id in (?)`, pg.In(v))
  209 + }
207 if v, ok := queryOptions["inOrgIds"]; ok && len(v.([]int64)) > 0 { 210 if v, ok := queryOptions["inOrgIds"]; ok && len(v.([]int64)) > 0 {
208 query.Where(`organization_id in (?)`, pg.In(v)) 211 query.Where(`organization_id in (?)`, pg.In(v))
209 } 212 }
  1 +package controllers
  2 +
  3 +import (
  4 + "github.com/linmadan/egglib-go/web/beego"
  5 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/terminal/command"
  6 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/terminal/service"
  7 +)
  8 +
  9 +type TerminalController struct {
  10 + beego.BaseController
  11 +}
  12 +
  13 +func (controller *TerminalController) TerminalReport() {
  14 + service := service.NewTerminalService(nil)
  15 + terminalReportCommand := &command.TerminalReportCommand{}
  16 + controller.Unmarshal(terminalReportCommand)
  17 + data, err := service.TerminalReport(terminalReportCommand)
  18 + controller.Response(data, err)
  19 +}
@@ -179,3 +179,12 @@ func (controller *UserController) UpdateAdminUser() { @@ -179,3 +179,12 @@ func (controller *UserController) UpdateAdminUser() {
179 data, err := userService.UpdateAdminUser(updateUserCommand) 179 data, err := userService.UpdateAdminUser(updateUserCommand)
180 controller.Response(data, err) 180 controller.Response(data, err)
181 } 181 }
  182 +
  183 +func (controller *UserController) SyncToAttendanceMachine() {
  184 + userService := service.NewUserService(nil)
  185 + cmd := &command.SyncToAttendanceMachineCommand{}
  186 + Must(controller.Unmarshal(cmd))
  187 + cmd.OperateInfo = ParseOperateInfo(controller.BaseController)
  188 + data, err := userService.SyncToAttendanceMachine(cmd)
  189 + controller.Response(data, err)
  190 +}
  1 +package routers
  2 +
  3 +import (
  4 + "github.com/beego/beego/v2/server/web"
  5 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/port/beego/controllers"
  6 +)
  7 +
  8 +func init() {
  9 + web.Router("/terminal/report", &controllers.TerminalController{}, "Post:TerminalReport")
  10 +}
@@ -21,6 +21,8 @@ func init() { @@ -21,6 +21,8 @@ func init() {
21 web.Router("/user/cooperator", &controllers.UserController{}, "Post:CreateCooperator") 21 web.Router("/user/cooperator", &controllers.UserController{}, "Post:CreateCooperator")
22 web.Router("/user/cooperator/:userId", &controllers.UserController{}, "Put:UpdateCooperator") 22 web.Router("/user/cooperator/:userId", &controllers.UserController{}, "Put:UpdateCooperator")
23 23
  24 + web.Router("/user/sync-to-attendance-machine", &controllers.UserController{}, "Post:SyncToAttendanceMachine")
  25 +
24 web.Router("/admin-user/", &controllers.UserController{}, "Post:CreateAdminUser") 26 web.Router("/admin-user/", &controllers.UserController{}, "Post:CreateAdminUser")
25 web.Router("/admin-user/:userId", &controllers.UserController{}, "Put:UpdateAdminUser") 27 web.Router("/admin-user/:userId", &controllers.UserController{}, "Put:UpdateAdminUser")
26 } 28 }