作者 yangfu

feat: 同步用户到考勤机

  1 +
  2 +INSERT INTO "users"."menu"("menu_id", "parent_id", "menu_name", "code", "access_code", "menu_type", "icon", "sort", "remark", "category", "parent_path", "is_publish", "enable_status", "link") VALUES (274, 42, '同步考勤机', 'ADMIN_SYSTEM-MANAGE_BASE_USER_SYNC', 'w1-1-1-1-9', 'button', '', 9, '同步考勤机', '7', '37,39,40,42', 1, 0, NULL);
@@ -176,3 +176,12 @@ func (gateway HttpLibAlliedCreationUser) OrgSearch(param ReqOrgSearch) (int, []* @@ -176,3 +176,12 @@ func (gateway HttpLibAlliedCreationUser) OrgSearch(param ReqOrgSearch) (int, []*
176 err := gateway.FastDoRequest(url, method, param, &data) 176 err := gateway.FastDoRequest(url, method, param, &data)
177 return data.Count, data.Orgs, err 177 return data.Count, data.Orgs, err
178 } 178 }
  179 +
  180 +// TerminalReport 终端汇报
  181 +func (gateway HttpLibAlliedCreationUser) TerminalReport(param ReqTerminalReport) (DataTerminalReport, error) {
  182 + url := gateway.Host() + "/terminal/report"
  183 + method := "post"
  184 + var data DataTerminalReport
  185 + err := gateway.FastDoRequest(url, method, param, &data)
  186 + return data, err
  187 +}
@@ -163,3 +163,21 @@ type ( @@ -163,3 +163,21 @@ type (
163 Orgs []*models.Organization `json:"orgs"` 163 Orgs []*models.Organization `json:"orgs"`
164 } 164 }
165 ) 165 )
  166 +
  167 +//返回组织列表
  168 +type (
  169 + ReqTerminalReport struct {
  170 + TerminalType string `json:"terminalType"`
  171 + TerminalId string `json:"terminalId"`
  172 + Command string `json:"command"`
  173 + Content string `json:"content"`
  174 + Table string `json:"table"`
  175 +
  176 + CompanyId int64 `json:"companyId"`
  177 + OrgId int64 `json:"orgId"`
  178 + }
  179 +
  180 + DataTerminalReport struct {
  181 + Response string `json:"response"`
  182 + }
  183 +)
@@ -8,7 +8,10 @@ import ( @@ -8,7 +8,10 @@ import (
8 "github.com/bwmarrin/snowflake" 8 "github.com/bwmarrin/snowflake"
9 jsonlib "github.com/linmadan/egglib-go/utils/json" 9 jsonlib "github.com/linmadan/egglib-go/utils/json"
10 "github.com/shopspring/decimal" 10 "github.com/shopspring/decimal"
  11 + "golang.org/x/text/encoding/simplifiedchinese"
  12 + "golang.org/x/text/transform"
11 "io" 13 "io"
  14 + "io/ioutil"
12 "reflect" 15 "reflect"
13 "strconv" 16 "strconv"
14 "strings" 17 "strings"
@@ -422,3 +425,21 @@ func Truncate(value float64, places int32) float64 { @@ -422,3 +425,21 @@ func Truncate(value float64, places int32) float64 {
422 rsp, _ := quantity.Float64() 425 rsp, _ := quantity.Float64()
423 return rsp 426 return rsp
424 } 427 }
  428 +
  429 +func Utf8ToGbk(s []byte) ([]byte, error) {
  430 + reader := transform.NewReader(bytes.NewReader(s), simplifiedchinese.GBK.NewEncoder())
  431 + d, e := ioutil.ReadAll(reader)
  432 + if e != nil {
  433 + return nil, e
  434 + }
  435 + return d, nil
  436 +}
  437 +
  438 +func GbkToUtf8(s []byte) ([]byte, error) {
  439 + reader := transform.NewReader(bytes.NewReader(s), simplifiedchinese.GBK.NewDecoder())
  440 + d, e := ioutil.ReadAll(reader)
  441 + if e != nil {
  442 + return nil, e
  443 + }
  444 + return d, nil
  445 +}
1 package controllers 1 package controllers
2 2
3 import ( 3 import (
  4 + "fmt"
  5 + "github.com/beego/beego/v2/server/web/context"
4 "github.com/linmadan/egglib-go/web/beego" 6 "github.com/linmadan/egglib-go/web/beego"
  7 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/constant"
5 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain" 8 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
  9 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/allied-lib/gateway/allied_creation_user"
6 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService" 10 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService"
  11 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils"
7 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log" 12 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
8 "strings" 13 "strings"
9 "time" 14 "time"
  15 + "unicode/utf8"
10 ) 16 )
11 17
12 type DeviceZKTecoController struct { 18 type DeviceZKTecoController struct {
@@ -21,7 +27,8 @@ func (controller *DeviceZKTecoController) PostCdata() { @@ -21,7 +27,8 @@ func (controller *DeviceZKTecoController) PostCdata() {
21 data := &domain.DeviceZkTeco{ 27 data := &domain.DeviceZkTeco{
22 Sn: sn, 28 Sn: sn,
23 } 29 }
24 - if len(bodyList) > 2 { 30 + table := controller.Ctx.Input.Query("table")
  31 + if len(bodyList) > 2 && table == "ATTLOG" {
25 data.UserNo = bodyList[0] 32 data.UserNo = bodyList[0]
26 //转成时间格式 33 //转成时间格式
27 mTime, err := time.ParseInLocation("2006-01-02 15:04:05", bodyList[1], time.Local) 34 mTime, err := time.ParseInLocation("2006-01-02 15:04:05", bodyList[1], time.Local)
@@ -36,6 +43,7 @@ func (controller *DeviceZKTecoController) PostCdata() { @@ -36,6 +43,7 @@ func (controller *DeviceZKTecoController) PostCdata() {
36 log.Logger.Debug(err.Error() + "data:" + bodyList[1]) 43 log.Logger.Debug(err.Error() + "data:" + bodyList[1])
37 } 44 }
38 } 45 }
  46 + RedirectToUserModule(controller.Ctx, false)
39 controller.Response(data, nil) 47 controller.Response(data, nil)
40 } 48 }
41 49
@@ -46,9 +54,72 @@ func (controller *DeviceZKTecoController) GetCdata() { @@ -46,9 +54,72 @@ func (controller *DeviceZKTecoController) GetCdata() {
46 54
47 func (controller *DeviceZKTecoController) GetRequest() { 55 func (controller *DeviceZKTecoController) GetRequest() {
48 //controller.Ctx.WriteString("C:11:DATA\tQUERY\tUSERINFO\tPIN=10086") 56 //controller.Ctx.WriteString("C:11:DATA\tQUERY\tUSERINFO\tPIN=10086")
49 - controller.Ctx.WriteString("OK") 57 + //controller.Ctx.WriteString("C:7EceWxtHB6:DATA QUERY USERINFO PIN=3")
  58 + //controller.Ctx.WriteString("OK")
  59 + RedirectToUserModule(controller.Ctx, true)
50 } 60 }
51 61
52 func (controller *DeviceZKTecoController) Ping() { 62 func (controller *DeviceZKTecoController) Ping() {
53 controller.Ctx.WriteString("OK") 63 controller.Ctx.WriteString("OK")
54 } 64 }
  65 +
  66 +func RedirectToUserModule(ctx *context.Context, useResult bool) {
  67 + var svr = allied_creation_user.NewHttpLibAlliedCreationUser(constant.ALLIED_CREATION_USER_HOST)
  68 + data := ctx.Input.RequestBody
  69 + uri := ctx.Request.URL.Path
  70 + sn := ctx.Input.Query("SN")
  71 + table := ""
  72 + cmd := uri
  73 + switch uri {
  74 + case "/zkteco/iclock/getrequest": // 获取下行命令
  75 + cmd = "getrequest"
  76 + case "/zkteco/iclock/cdata": // 上报数据
  77 + cmd = "cdata"
  78 + table = ctx.Input.Query("table")
  79 + case "/zkteco/iclock/devicecmd":
  80 + cmd = "devicecmd"
  81 + }
  82 + content := string(data)
  83 + if !utf8.Valid(data) {
  84 + utf8Content, _ := utils.GbkToUtf8(data) //ConvertToString(content, "gbk", "utf-8")
  85 + content = string(utf8Content)
  86 + }
  87 + param := allied_creation_user.ReqTerminalReport{
  88 + TerminalType: "zkteco",
  89 + TerminalId: sn,
  90 + Command: cmd,
  91 + CompanyId: int64(constant.MANUFACTURE_DEFAULT_COMPANYID),
  92 + OrgId: int64(constant.MANUFACTURE_DEFAULT_ORGID),
  93 + Table: table,
  94 + Content: content,
  95 + }
  96 + if !useResult {
  97 + log.Logger.Debug(fmt.Sprintf("命令透传(sn:%v)-命令:%v 命令(内容):%v 成功", sn, cmd, content))
  98 + go func() {
  99 + defer func() {
  100 + if p := recover(); p != nil {
  101 + log.Logger.Error(fmt.Sprintf("%v", p))
  102 + }
  103 + }()
  104 + svr.TerminalReport(param)
  105 + }()
  106 + return
  107 + }
  108 + response, err := svr.TerminalReport(param)
  109 + if err != nil {
  110 + log.Logger.Debug(fmt.Sprintf("命令透传(sn:%v)-命令:%v 命令(内容):%v 应答:%v 错误:%v", sn, cmd, string(data), response.Response, err.Error()))
  111 + ctx.WriteString("OK")
  112 + return
  113 + }
  114 + log.Logger.Debug(fmt.Sprintf("命令透传(sn:%v)-命令:%v 命令(内容):%v 应答:%v 成功", sn, cmd, string(data), response.Response))
  115 + gbkData, _ := utils.Utf8ToGbk([]byte(response.Response))
  116 + ctx.Output.Header("Content-Type", "text/plain;charset=gbk")
  117 + ack := string(gbkData)
  118 + ctx.WriteString(ack)
  119 +}
  120 +
  121 +func (controller *DeviceZKTecoController) DeviceCmd() {
  122 + //sn := controller.Ctx.Input.Query("SN")
  123 + RedirectToUserModule(controller.Ctx, false)
  124 + controller.Ctx.WriteString("OK")
  125 +}
@@ -21,4 +21,5 @@ func init() { @@ -21,4 +21,5 @@ func init() {
21 web.Router("/zkteco/iclock/cdata", &controllers.DeviceZKTecoController{}, "Get:GetCdata") 21 web.Router("/zkteco/iclock/cdata", &controllers.DeviceZKTecoController{}, "Get:GetCdata")
22 web.Router("/zkteco/iclock/getrequest", &controllers.DeviceZKTecoController{}, "Get:GetRequest") 22 web.Router("/zkteco/iclock/getrequest", &controllers.DeviceZKTecoController{}, "Get:GetRequest")
23 web.Router("/zkteco/iclock/ping", &controllers.DeviceZKTecoController{}, "Get:Ping") 23 web.Router("/zkteco/iclock/ping", &controllers.DeviceZKTecoController{}, "Get:Ping")
  24 + web.Router("/zkteco/iclock/devicecmd", &controllers.DeviceZKTecoController{}, "Post:DeviceCmd")
24 } 25 }