diff --git a/cmd/diff_fiber_box.go b/cmd/diff_fiber_box.go new file mode 100644 index 0000000..a9e73bb --- /dev/null +++ b/cmd/diff_fiber_box.go @@ -0,0 +1,144 @@ +package cmd + +import ( + "cu-helper/wms/cryptokit" + "cu-helper/wms/model" + "github.com/go-resty/resty/v2" + "github.com/mizuki1412/go-core-kit/class/exception" + "github.com/mizuki1412/go-core-kit/init/initkit" + "github.com/mizuki1412/go-core-kit/library/commonkit" + "github.com/mizuki1412/go-core-kit/service/configkit" + "github.com/mizuki1412/go-core-kit/service/logkit" + "github.com/spf13/cast" + "github.com/spf13/cobra" + "github.com/tidwall/gjson" + "github.com/xuri/excelize/v2" + "golang.org/x/net/html" + "strings" + "time" +) + +func init() { + rootCmd.AddCommand(dfbCmd) + defFlagsDfb(dfbCmd) +} + +var dfbCmd = &cobra.Command{ + Use: "dfb", + Short: "Batch processing operations of the difficult fiber box", + Run: func(cmd *cobra.Command, args []string) { + initkit.BindFlags(cmd) + handleDfb() + }, +} + +func defFlagsDfb(cmd *cobra.Command) { + cmd.Flags().String("wms.token", "", "*Specify the token of WMS-ZJ(装维调度系统)") + cmd.Flags().String("path", "", "*Specify the file of excel") +} + +var dfbClient = resty.New().SetRetryCount(5).SetRetryWaitTime(10 * time.Second) + +func handleDfb() { + // Open the Excel file + excelPath := configkit.GetString("path", "") + if excelPath == "" { + panic(exception.New("EXCEL文件不存在或路径错误")) + } + f, err := excelize.OpenFile(excelPath) + if err != nil { + panic(exception.New(err.Error())) + } + rows, err := f.GetRows("Sheet1") + if err != nil { + panic(exception.New(err.Error())) + } + h := model.NewHeader() + header := h.GenReqParam() + for rowIndex, row := range rows { + if rowIndex <= 1 { + continue + } + _ = commonkit.RecoverFuncWrapper(func() { + no := row[8] //宽带编号 I列 + fo := model.NewGetOrderQueryList(no) + form := fo.GenReqParam() + logkit.Info("***开始请求*** " + no) + resp, err := dfbClient.R(). + SetHeaders(header).SetFormData(form).Post("http://132.151.160.87:10010/wms-zj/monitor/orderQueryListAjax.do") + if err != nil { + panic(exception.New(err.Error())) + } + if resp.StatusCode() != 200 { + panic(exception.New(resp.Status())) + } + totalNumber := gjson.Get(resp.String(), "pageObj.total").Int() + if totalNumber == 0 { + logkit.Error(no + " 该条记录不存在!") + return + } + list := gjson.Get(resp.String(), "list").Array() + if list[totalNumber-1].Get("ORDER_TYPE_NAME").String() == "改用户资料" { + totalNumber-- + } + if totalNumber == 0 { + logkit.Error(no + " 该条记录不存在!") + return + } + addId := list[totalNumber-1].Get("SEVEN_ADDR_ID").String() + addName := list[totalNumber-1].Get("SEVEN_ADDR").String() + woId := cryptokit.Encrypt(list[totalNumber-1].Get("WO_ID").String()) + shardingId := list[totalNumber-1].Get("SHARDING_ID").String() + resp, err = dfbClient.R(). + SetHeaders(header).SetQueryParams(map[string]string{ + "woIde": woId, + "hisFlag": "2", + "shardingId": shardingId, + }).Get("http://132.151.160.87:10010/wms-zj/common/installOrderDetailInfoQuery.do") + qrCode, gqpName := extractGQPInfo(resp.String()) + f.SetCellValue("Sheet1", "C"+cast.ToString(rowIndex+1), addId) + f.SetCellValue("Sheet1", "D"+cast.ToString(rowIndex+1), addName) + f.SetCellValue("Sheet1", "E"+cast.ToString(rowIndex+1), qrCode) + f.SetCellValue("Sheet1", "F"+cast.ToString(rowIndex+1), gqpName) + }) + } + // Save the file + if err = f.SaveAs(excelPath); err != nil { + panic(exception.New(err.Error())) + } + logkit.Info("生成结束...") +} + +// extractGQPInfo 解析 HTML 并提取光分线盒二维码和光分线盒名称 +func extractGQPInfo(htmlStr string) (qrCode, gqpName string) { + doc, err := html.Parse(strings.NewReader(htmlStr)) + if err != nil { + panic(exception.New(err.Error())) + } + var extractData func(*html.Node, string) string + extractData = func(n *html.Node, key string) string { + if n.Type == html.ElementNode && n.Data == "td" { + // 检查当前节点的文本内容是否匹配 key + if n.FirstChild != nil && n.FirstChild.Type == html.TextNode && strings.TrimSpace(n.FirstChild.Data) == key { + // 获取同一行的第三个 里的 title 属性 + if nextTd := n.NextSibling.NextSibling; nextTd != nil { + for _, attr := range nextTd.Attr { + if attr.Key == "title" { + return attr.Val + } + } + } + } + } + // 递归遍历所有子节点 + for c := n.FirstChild; c != nil; c = c.NextSibling { + if val := extractData(c, key); val != "" { + return val + } + } + return "" + } + qrCode = extractData(doc, "光分线盒二维码") + gqpName = extractData(doc, "光分线盒名称") + return +} diff --git a/wms/cryptokit/crypto.go b/wms/cryptokit/crypto.go new file mode 100644 index 0000000..ed92597 --- /dev/null +++ b/wms/cryptokit/crypto.go @@ -0,0 +1,33 @@ +package cryptokit + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "encoding/base64" + "github.com/mizuki1412/go-core-kit/class/exception" +) + +// Encrypt 实现 AES-CBC 加密(返回 Base64 编码结果) +func Encrypt(plainText string) string { + key := "1234567890123456" + iv := "1234567890123456" + block, err := aes.NewCipher([]byte(key)) + if err != nil { + panic(exception.New(err.Error())) + } + // PKCS7 填充 + paddedText := pkcs7Padding([]byte(plainText), block.BlockSize()) + // CBC 模式加密 + blockMode := cipher.NewCBCEncrypter(block, []byte(iv)) + ciphertext := make([]byte, len(paddedText)) + blockMode.CryptBlocks(ciphertext, paddedText) + // Base64 编码 + return base64.StdEncoding.EncodeToString(ciphertext) +} + +func pkcs7Padding(ciphertext []byte, blockSize int) []byte { + padding := blockSize - len(ciphertext)%blockSize + padtext := bytes.Repeat([]byte{byte(padding)}, padding) + return append(ciphertext, padtext...) +} diff --git a/wms/model/get_order_query_list.go b/wms/model/get_order_query_list.go new file mode 100644 index 0000000..a8fce57 --- /dev/null +++ b/wms/model/get_order_query_list.go @@ -0,0 +1,66 @@ +package model + +import "reflect" + +/* +http://132.151.160.87:10010/wms-zj/monitor/orderQueryListAjax.do +*/ + +/* +用途:宽带装机工单查询 +*/ + +type GetOrderQueryList struct { + Page string `map:"page"` + Rows string `map:"rows"` + OrgId string `map:"orgId"` + BusiNo string `map:"busiNo"` + BusiType string `map:"busiType"` + QueryFlag string `map:"queryFlag"` + OrdStatus string `map:"ordStatus"` + ParallelFlag string `map:"parallelFlag"` + QueryType string `map:"queryType"` + QueryValue string `map:"queryValue"` + ProdClass string `map:"prodClass"` + DelFlag string `map:"delFlag"` + IsCurrentArchive string `map:"isCurrentArchive"` //非当日报竣=2 当日报竣=1 +} + +func NewGetOrderQueryList(no string) *GetOrderQueryList { + return &GetOrderQueryList{ + Page: "1", + Rows: "10", + OrgId: "330106", + BusiNo: no, + BusiType: "1", + QueryFlag: "2", + OrdStatus: "0", + ParallelFlag: "0", + QueryType: "0", + QueryValue: "057101146896", + ProdClass: "-1", + DelFlag: "-1", + IsCurrentArchive: "2", + } +} + +func (th *GetOrderQueryList) GenReqParam() map[string]string { + return th.structToMap() +} + +func (th *GetOrderQueryList) structToMap() map[string]string { + result := make(map[string]string) + t := reflect.TypeOf(*th) + v := reflect.ValueOf(*th) + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + value := v.Field(i) + // Use the tag value as the key in the map, if it exists; otherwise, use the field name. + tag := field.Tag.Get("map") + if tag == "" { + tag = field.Name + } + result[tag] = value.String() + } + return result +}