作者 yangfu

feat: 打卡机数据解析

... ... @@ -4,6 +4,7 @@ go 1.16
require (
github.com/ajg/form v1.5.1 // indirect
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394
github.com/beego/beego/v2 v2.0.1
github.com/emirpasic/gods v1.12.0
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 // indirect
... ... @@ -11,6 +12,7 @@ require (
github.com/gavv/httpexpect v2.0.0+incompatible
github.com/go-pg/pg/v10 v10.9.0
github.com/google/go-querystring v1.1.0 // indirect
github.com/gookit/event v1.0.6
github.com/imkira/go-interpol v1.1.0 // indirect
github.com/linmadan/egglib-go v0.0.0-20210313060205-8b5e456b11f7
github.com/mattn/go-colorable v0.1.8 // indirect
... ... @@ -19,7 +21,7 @@ require (
github.com/onsi/gomega v1.11.0
github.com/sergi/go-diff v1.2.0 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/stretchr/testify v1.7.0
github.com/stretchr/testify v1.7.1
github.com/tal-tech/go-queue v1.0.5
github.com/tal-tech/go-zero v1.0.27
github.com/valyala/fasthttp v1.23.0 // indirect
... ...
... ... @@ -21,6 +21,8 @@ github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+Dx
github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc=
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
github.com/beanstalkd/go-beanstalk v0.1.0/go.mod h1:/G8YTyChOtpOArwLTQPY1CHB+i212+av35bkPXXj56Y=
github.com/beego/beego/v2 v2.0.1 h1:07a7Z0Ok5vbqyqh+q53sDPl9LdhKh0ZDy3gbyGrhFnE=
github.com/beego/beego/v2 v2.0.1/go.mod h1:8zyHi1FnWO1mZLwTn62aKRIZF/aIKvkCBB2JYs+eqQI=
... ... @@ -164,6 +166,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gookit/event v1.0.6 h1:/U95T1tBzt9RSSi23pg4VR3B9VWkyM4xv8TXAGi60IQ=
github.com/gookit/event v1.0.6/go.mod h1:7Udf/q/HQcrK9XE4JZUvbqi46rI1V8r/Pvao2NbPajA=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
... ... @@ -308,6 +312,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/qiniu/iconv v1.2.0 h1:2LJKwoF+4LJ3lNM+7cE3P1kNQzAI/HMZuWhkmFoY2U8=
github.com/qiniu/iconv v1.2.0/go.mod h1:5bxb2h9lptZt2eHLgY+Jw4X06TMtKb6tvvok0DwSwGA=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
... ... @@ -348,8 +354,9 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
github.com/tal-tech/go-queue v1.0.5 h1:cd2o0lPjAFJKIXuEbQvsGypUhzz6FLib4FVVAyxsMtY=
... ...
package command
import (
"fmt"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type TerminalReportCommand struct {
TerminalType string `json:"terminalType"`
TerminalId string `json:"terminalId"`
Command string `json:"command"`
Content string `json:"content"`
Table string `json:"table"`
CompanyId int64 `json:"companyId"`
OrgId int64 `json:"orgId"`
}
func (terminalReportCommand *TerminalReportCommand) Valid(validation *validation.Validation) {
}
func (terminalReportCommand *TerminalReportCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(terminalReportCommand)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(terminalReportCommand).Elem()
for _, validErr := range valid.Errors {
field, isExist := elem.FieldByName(validErr.Field)
if isExist {
return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
} else {
return fmt.Errorf(validErr.Message)
}
}
}
return nil
}
... ...
package service
import (
"bytes"
"fmt"
"github.com/axgle/mahonia"
"github.com/beego/beego/v2/adapter/utils"
"github.com/gookit/event"
"github.com/linmadan/egglib-go/core/application"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/terminal/command"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/log"
"io"
)
var GlobalTerminalManager *TerminalManager
func init() {
GlobalTerminalManager = NewTerminalManager()
event.On(domain.UserCreateEvent, event.ListenerFunc(func(e event.Event) error {
return nil
}))
event.On(domain.UserUpdateEvent, event.ListenerFunc(func(e event.Event) error {
return nil
}))
event.On(domain.UserDeleteEvent, event.ListenerFunc(func(e event.Event) error {
return nil
}))
event.On(domain.UserEnableEvent, event.ListenerFunc(func(e event.Event) error {
return nil
}))
event.On(domain.UserEnableEvent, event.ListenerFunc(func(e event.Event) error {
return nil
}))
event.On(DownEntityEvent, event.ListenerFunc(GlobalTerminalManager.DownEntityEvent))
}
type TerminalService struct {
}
func NewTerminalService(options map[string]interface{}) *TerminalService {
newUserService := &TerminalService{}
return newUserService
}
func (svr *TerminalService) TerminalReport(cmd *command.TerminalReportCommand) (interface{}, error) {
if err := cmd.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
response, err := terminalReport(cmd, transactionContext)
if err != nil {
log.Logger.Error(err.Error())
return nil, err
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return response, nil
}
func terminalReport(cmd *command.TerminalReportCommand, transactionContext application.TransactionContext) (interface{}, error) {
var (
response string = "OK"
)
switch cmd.Command {
case "getrequest":
device, ok := GlobalTerminalManager.GetDevice(cmd.TerminalId)
if !ok || device == nil {
break
}
if downEntity, ok := device.PopDownEntity(); ok && downEntity != nil {
response = downEntity.DownCommand()
}
break
case "cdata":
parseEntities := ParseData(cmd)
var (
down DownEntity
err error
handler Handler = ZKClockHandler{TransactionContext: transactionContext}
)
for _, entity := range parseEntities {
switch TableType(cmd.Table) {
case AttLOG:
down, err = handler.Attendance(entity.(AttLOGUpEntity))
case BIODATA:
down, err = handler.BioData(entity.(BIODATAEntity))
case OPERLOG:
//if v, ok := entity.(USEREntity); ok {
// down, err = handler.ReportUser(v)
//}
if v, ok := entity.(BIODATAEntity); ok {
down, err = handler.BioData(v)
}
}
if err != nil {
log.Logger.Error(err.Error())
continue
}
if down != nil {
response = down.DownCommand()
}
break
}
}
return map[string]interface{}{
"response": response,
}, nil
}
func ParseData(cmd *command.TerminalReportCommand) []interface{} {
result := make([]interface{}, 0)
buf := bytes.NewBufferString(cmd.Content)
for {
line, err := buf.ReadBytes('\n')
if err == io.EOF {
break
}
if err != nil {
log.Logger.Error(err.Error())
break
}
switch TableType(cmd.Table) {
case AttLOG:
columns := bytes.Split(line, ([]byte)("\t"))
if len(columns) != 11 { //10 + 1 空格
continue
}
result = append(result, AttLOGUpEntity{
Pin: string(columns[0]),
CompanyId: cmd.CompanyId,
OrgId: cmd.OrgId,
})
case BIODATA:
/*BIODATA Pin=3\tNo=0\tIndex=0\tValid=1\tDuress=0\tType=9\tMajorVer=39\tMinorVer=1\tFormat=
0\tTmp=apUBEBABQo4JACcBAWiOADA7dP4pU9F31Uxom7NAGjM4eO/8X5Ee4uahkIT11c3188+VguMsd3oCO0O29efRyxofdLiohI4QL7woK3U*/
columns := readLineToMap(line, "BIODATA")
result = append(result, BIODATAEntity{
Pin: columns["Pin"],
No: columns["No"],
Index: columns["Index"],
Duress: columns["Duress"],
Type: columns["Type"],
MinorVer: columns["MinorVer"],
MajorVer: columns["MajorVer"],
Format: columns["Format"],
Tmp: columns["Tmp"],
CompanyId: cmd.CompanyId,
OrgId: cmd.OrgId,
})
case OPERLOG:
if bytes.HasPrefix(line, []byte("FP")) {
/*
FP PIN=3 FID=6 Size=1336 Valid=1 TMP=SqtTUzIxAAAD6O8ECA
*/
columns := readLineToMap(line, "FP")
result = append(result, BIODATAEntity{
Pin: columns["PIN"],
Type: fmt.Sprintf("%v", BioDataType1),
Tmp: columns["TMP"],
CompanyId: cmd.CompanyId,
OrgId: cmd.OrgId,
})
} else if bytes.HasPrefix(line, []byte("USER")) {
/*
USER PIN=3 Name=杨xx Pri=14 Passwd= Card=3731588478 Grp=1 TZ=0000000100000000 Verify=-1 ViceCard= StartDatetime=0 EndDatetime=0
*/
columns := readLineToMap(line, "USER")
name := columns["Name"] //GbkToUtf8(columns["Name"])
result = append(result, USEREntity{
OPERLOGType: "USER",
Pin: columns["PIN"],
Name: name,
CompanyId: cmd.CompanyId,
OrgId: cmd.OrgId,
})
}
}
}
return result
}
func readLineToMap(line []byte, prefix string) map[string]string {
var result = make(map[string]string)
line = bytes.TrimLeft(line, prefix)
line = bytes.TrimSpace(line)
columns := bytes.Fields(line)
for i := range columns {
kv := bytes.SplitN(columns[i], []byte("="), 2)
if len(kv) < 2 {
continue
}
//if string(kv[0]) == "Name" {
// log.Logger.Debug(fmt.Sprintf("%x", kv[1]))
// log.Logger.Debug(fmt.Sprintf("%v", kv[1]))
// log.Logger.Debug(fmt.Sprintf("%s", string(kv[1])))
//}
result[string(kv[0])] = string(kv[1])
}
return result
}
type Handler interface {
Attendance(entity AttLOGUpEntity) (DownEntity, error)
BioData(entity BIODATAEntity) (DownEntity, error)
ReportUser(entity USEREntity) (DownEntity, error)
}
type ZKClockHandler struct {
TransactionContext application.TransactionContext
}
func (handler ZKClockHandler) Attendance(entity AttLOGUpEntity) (DownEntity, error) {
var (
userRepository, _, _ = factory.FastPgUser(handler.TransactionContext, 0)
userBaseRepository, _, _ = factory.FastPgUserBase(handler.TransactionContext, 0)
user *domain.User
userBase *domain.UserBase
err error
)
if user, err = userRepository.FindOne(map[string]interface{}{"companyId": entity.CompanyId, "orgId": entity.OrgId, "icCardNumber": entity.Pin}); err != nil {
return nil, err
}
if userBase, err = userBaseRepository.FindOne(map[string]interface{}{"userBaseId": user.UserBaseId}); err != nil {
return nil, err
}
var sendQuery bool
// 请求 人脸识别-用户画像
if len(userBase.UserInfo.FacePortrait) == 0 {
sendQuery = true
//event.Fire(DownEntityEvent, map[string]interface{}{"entity": NewQueryBIODATADownEntity(generateSn(), entity.Pin, BioDataType2)})
}
// 请求 人脸识别-指纹
if len(userBase.UserInfo.FingerprintPortrait) == 0 {
sendQuery = true
//event.Fire(DownEntityEvent, map[string]interface{}{"entity": NewQueryBIODATADownEntity(generateSn(), entity.Pin, BioDataType1)})
}
if sendQuery {
event.Fire(DownEntityEvent, map[string]interface{}{"entity": NewQueryUserInfoDownEntity(generateSn(), entity.Pin)})
}
return nil, nil
}
func (handler ZKClockHandler) BioData(entity BIODATAEntity) (DownEntity, error) {
var (
userRepository, _, _ = factory.FastPgUser(handler.TransactionContext, 0)
userBaseRepository, _, _ = factory.FastPgUserBase(handler.TransactionContext, 0)
user *domain.User
userBase *domain.UserBase
err error
updateFlag bool
)
if user, err = userRepository.FindOne(map[string]interface{}{"companyId": entity.CompanyId, "orgId": entity.OrgId, "icCardNumber": entity.Pin}); err != nil {
return nil, err
}
if userBase, err = userBaseRepository.FindOne(map[string]interface{}{"userBaseId": user.UserBaseId}); err != nil {
return nil, err
}
// 请求 人脸识别-用户画像
if len(userBase.UserInfo.FacePortrait) == 0 && len(entity.Tmp) > 0 && entity.Type == "9" {
userBase.UserInfo.FacePortrait = entity.Tmp
updateFlag = true
}
// 请求 人脸识别-指纹
if len(userBase.UserInfo.FingerprintPortrait) == 0 && len(entity.Tmp) > 0 && entity.Type == "1" {
userBase.UserInfo.FingerprintPortrait = entity.Tmp
updateFlag = true
}
if updateFlag {
_, err = userBaseRepository.Save(userBase)
if err != nil {
log.Logger.Error(err.Error())
}
}
return nil, err
}
func (handler ZKClockHandler) ReportUser(entity USEREntity) (DownEntity, error) {
var (
userRepository, _, _ = factory.FastPgUser(handler.TransactionContext, 0)
userBaseRepository, _, _ = factory.FastPgUserBase(handler.TransactionContext, 0)
user *domain.User
userBase *domain.UserBase
err error
updateFlag bool
)
if user, err = userRepository.FindOne(map[string]interface{}{"companyId": entity.CompanyId, "orgId": entity.OrgId, "icCardNumber": entity.Pin}); err != nil {
return nil, err
}
if userBase, err = userBaseRepository.FindOne(map[string]interface{}{"userBaseId": user.UserBaseId}); err != nil {
return nil, err
}
// 请求 人脸识别-用户画像
//if len(entity.Pin) > 0 && userBase.UserInfo.Pin != entity.Pin {
// updateFlag = true
// userBase.UserInfo.Pin = entity.Pin
//}
if updateFlag {
_, err = userBaseRepository.Save(userBase)
}
return nil, err
}
func generateSn() string {
return string(utils.RandomCreateBytes(10))
}
// GbkToUtf8 GBK 转 UTF-8
func GbkToUtf8(s string) string {
decoder := mahonia.NewDecoder("gbk")
_, data, _ := decoder.Translate([]byte(s), true)
//return decoder.ConvertString(s)
return string(data)
}
// Utf8ToGbk UTF-8 转 GBK
func Utf8ToGbk(s string) string {
encoder := mahonia.NewEncoder("gbk")
return encoder.ConvertString(s)
}
func ConvertToString(src string, srcCode string, tagCode string) string {
srcCoder := mahonia.NewDecoder(srcCode)
srcResult := srcCoder.ConvertString(src)
tagCoder := mahonia.NewDecoder(tagCode)
_, cdata, _ := tagCoder.Translate([]byte(srcResult), true)
result := string(cdata)
return result
}
... ...
package service
import (
"container/list"
"github.com/gookit/event"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/log"
"sync"
)
var (
DownEntityEvent = "down_entity"
)
type TerminalManager struct {
TerminalDeviceList []*TerminalDevice
TerminalDevices sync.Map
}
func NewTerminalManager() *TerminalManager {
return &TerminalManager{
TerminalDeviceList: make([]*TerminalDevice, 0),
TerminalDevices: sync.Map{},
}
}
func (term *TerminalManager) GetDevice(terminalId string) (*TerminalDevice, bool) {
device, ok := term.TerminalDevices.Load(terminalId)
if !ok {
device := NewTerminalDevice(terminalId)
term.TerminalDevices.Store(terminalId, device)
log.Logger.Debug("【TerminalManager】 add new device:"+terminalId, map[string]interface{}{"device": device})
term.TerminalDeviceList = append(term.TerminalDeviceList, device)
return nil, false
}
if v, ok := device.(*TerminalDevice); ok {
return v, ok
}
return nil, false
}
func (term *TerminalManager) PopDownEntityByDevice(sn string) (DownEntity, bool) {
device, ok := term.GetDevice(sn)
if !ok {
return nil, false
}
return device.PopDownEntity()
}
func (term *TerminalManager) AddDownEntityByDevice(sn string, entity interface{}) bool {
device, ok := term.GetDevice(sn)
if !ok {
return false
}
device.AddDownEntity(entity)
return true
}
func (term *TerminalManager) BroadcastDownEntity(downEntity interface{}) {
for i := range term.TerminalDeviceList {
term.TerminalDeviceList[i].AddDownEntity(downEntity)
}
}
// Listen Event
func (term *TerminalManager) DownEntityEvent(e event.Event) error {
//fmt.Printf("handle down entity event: %s\n", e.Name())
entity := e.Get("entity")
if entity != nil {
term.BroadcastDownEntity(entity)
}
return nil
}
type TerminalDevice struct {
Id string
DownEntityList *list.List
}
func NewTerminalDevice(terminalId string) *TerminalDevice {
return &TerminalDevice{
Id: terminalId,
DownEntityList: list.New(),
}
}
func (device *TerminalDevice) PopDownEntity() (DownEntity, bool) {
element := device.DownEntityList.Front()
if element == nil {
return nil, false
}
device.DownEntityList.Remove(element)
if v, ok := element.Value.(DownEntity); ok {
log.Logger.Debug("【TerminalManager】 pop down entity to Sender", map[string]interface{}{"entity": v})
return v, ok
}
return nil, false
}
func (device *TerminalDevice) AddDownEntity(downEntity interface{}) {
log.Logger.Debug("【TerminalManager】 add down entity to Profile", map[string]interface{}{"entity": downEntity})
device.DownEntityList.PushBack(downEntity)
}
... ...
package service
import (
"fmt"
"github.com/stretchr/testify/assert"
"testing"
)
func TestGbkToUtf8(t *testing.T) {
input := "刘"
out := Utf8ToGbk(input)
t.Log("gbk:" + out)
//"efbfbdeeb8a3"
t.Log(fmt.Sprintf("%v", []byte(out)))
out = GbkToUtf8(out)
t.Log("utf8:" + out)
t.Log("utf8:" + fmt.Sprintf("%v", []byte(out)))
assert.Equal(t, input, out)
}
... ...
package service
import "fmt"
type TableType string
var (
AttLOG TableType = "ATTLOG" // AttLOG 打卡记录
UserInfo TableType = "USERINFO" // 用户信息
FingerTMP TableType = "FINGERTMP" //指纹
Face TableType = "FACE" //脸部
OPERLOG TableType = "OPERLOG" //操作记录
BIODATA TableType = "BIODATA" //一体化数据 (人脸识别等)
)
// AttLOGUpEntity 打卡记录实体 - 上行命令
type AttLOGUpEntity struct {
Pin string
Time string
Status string
Verify string
Workcode string
Reserved1 string
Reserved2 string
MaskFlag string
Temperature string
ConvTemperature string
CompanyId int64 `json:"companyId"`
OrgId int64 `json:"orgId"`
}
// FPEntity 指纹 - 上行命令 OPERLOG
type FPEntity struct {
OPERLOGType string //"FP" "USER" "BIODATA"
Pin string
TFID string
TSize string
TValid string
TTMP string
CompanyId int64 `json:"companyId"`
OrgId int64 `json:"orgId"`
}
// USEREntity 用户 - 上行命令 OPERLOG
type USEREntity struct {
OPERLOGType string //"FP" "USER" "BIODATA"
Pin string `json:"pin"`
Name string `json:"Name"`
Pri string `json:"Pri"`
Passwd string `json:"Passwd"`
Grp string `json:"Grp"`
TZ string `json:"TZ"`
Verify string `json:"Verify"`
ViceCard string `json:"ViceCard"`
StartDatetime string `json:"StartDatetime"`
EndDatetime string `json:"EndDatetime"`
CompanyId int64 `json:"companyId"`
OrgId int64 `json:"orgId"`
}
// BIODATAEntity 一体化数据实体 - 上行命令 BIODATA
type BIODATAEntity struct {
Pin string `json:"pin"`
No string `json:"tNo"`
Index string `json:"tIndex"`
Valid string `json:"tValid"`
Duress string `json:"tDuress"`
Type string `json:"tType"`
MajorVer string `json:"tMajorVer"`
MinorVer string `json:"tMinorVer"`
Format string `json:"tFormat"`
Tmp string `json:"Tmp"`
CompanyId int64 `json:"companyId"`
OrgId int64 `json:"orgId"`
}
type DownEntity interface {
DownCommand() string
}
func QueryUserInfoRequest(sn string, entity AttLOGUpEntity) string {
return fmt.Sprintf("C:%v:DATA QUERY USERINFO PIN=%v", sn, entity.Pin)
}
// QueryUserInfoDownEntity 查询用户信息-下行命令
type QueryUserInfoDownEntity struct {
Sn string
Pin string
}
func (entity QueryUserInfoDownEntity) DownCommand() string {
return fmt.Sprintf("C:%v:DATA QUERY USERINFO PIN=%v", entity.Sn, entity.Pin)
}
func NewQueryUserInfoDownEntity(sn string, pin string) QueryUserInfoDownEntity {
return QueryUserInfoDownEntity{
Sn: sn,
Pin: pin,
}
}
type BioDataType int
var (
BioDataType0 BioDataType = 0 //通用
BioDataType1 BioDataType = 1 //指纹
BioDataType2 BioDataType = 0 //面部
BioDataType3 BioDataType = 3 //声纹
BioDataType4 BioDataType = 4 //虹膜
BioDataType5 BioDataType = 5 //视网膜
BioDataType6 BioDataType = 6 //掌纹
BioDataType7 BioDataType = 7 //指静脉
BioDataType8 BioDataType = 8 //手掌
BioDataType9 BioDataType = 9 //可见光面部
)
// QueryBioDataDownEntity 查询一体化-下行命令
type QueryBioDataDownEntity struct {
Sn string
Pin string
Type BioDataType
}
func (entity QueryBioDataDownEntity) DownCommand() string {
return fmt.Sprintf("C:%v:DATA QUERY BIODATA Type=%v PIN=%v", entity.Sn, entity.Type, entity.Pin)
}
func NewQueryBIODATADownEntity(sn string, pin string, t BioDataType) QueryBioDataDownEntity {
return QueryBioDataDownEntity{
Sn: sn,
Pin: pin,
Type: t,
}
}
// DeleteUserDownEntity 删除用户-下行命令
type DeleteUserDownEntity struct {
Sn string
Pin string
Table string
}
func (entity DeleteUserDownEntity) DownCommand() string {
return fmt.Sprintf("C:%v:DATA DELETE %v PIN=%v", entity.Sn, entity.Table, entity.Pin)
}
func NewClearUserDownEntity(sn string, pin string, t string) DeleteUserDownEntity {
return DeleteUserDownEntity{
Sn: sn,
Pin: pin,
Table: t,
}
}
... ...
... ... @@ -26,6 +26,14 @@ const (
UserStatusDestroy UserStatus = 3
)
const (
UserUpdateEvent = "user_update"
UserDeleteEvent = "user_delete"
UserCreateEvent = "user_create"
UserEnableEvent = "user_enable" //禁用启用事件
UserSyncEvent = "user_sync" // 用户同步
)
// 用户
type User struct {
// 用户Id 用户唯一标识
... ...
... ... @@ -13,9 +13,16 @@ type UserInfo struct {
// 员工类型 1:固定 2:派遣 3.临时
EmployeeType int `json:"employeeType,omitempty"`
// IC卡号
// IC卡号 = Pin
IcCardNumber string `json:"icCardNumber,omitempty"`
// 面部识别
FacePortrait string `json:"facePortrait,omitempty"`
// 指纹识别
FingerprintPortrait string `json:"fingerprintPortrait,omitempty"`
// 打卡机标识
// Pin string `json:"pin"`
Referer string `json:"-"`
// 部门
DepartmentName string `cname:"部门" json:"-"`
... ...
package controllers
import (
"github.com/linmadan/egglib-go/web/beego"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/terminal/command"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/terminal/service"
)
type TerminalController struct {
beego.BaseController
}
func (controller *TerminalController) TerminalReport() {
service := service.NewTerminalService(nil)
terminalReportCommand := &command.TerminalReportCommand{}
controller.Unmarshal(terminalReportCommand)
data, err := service.TerminalReport(terminalReportCommand)
controller.Response(data, err)
}
... ...
package routers
import (
"github.com/beego/beego/v2/server/web"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/port/beego/controllers"
)
func init() {
web.Router("/terminal/report", &controllers.TerminalController{}, "Post:TerminalReport")
}
... ...