Merge remote-tracking branch 'origin/test' into dev
正在显示
28 个修改的文件
包含
1051 行增加
和
104 行删除
@@ -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 | +} |
pkg/application/terminal/service/terminal.go
0 → 100644
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 | +} |
pkg/application/terminal/service/types.go
0 → 100644
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 |
pkg/application/user/service/attendance.go
0 → 100644
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 | +} |
pkg/port/beego/routers/terminal_router.go
0 → 100644
@@ -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 | } |
-
请 注册 或 登录 后发表评论