Эх сурвалжийг харах

修复供应商修改提交数量,计划中未更新

animeic 2 жил өмнө
parent
commit
1756268b77

+ 17 - 0
boxcost/api/bill-produce.go

@@ -222,6 +222,23 @@ func UpdateProduceBill(c *gin.Context, apictx *ApiSession) (interface{}, error)
 		bill.CompleteTime = time.Now()
 	}
 
+	// 更新供应商确定数量与plan中stage项的同步
+	if len(bill.Produces) > 0 {
+		idCounts := map[string]int{}
+		for _, produce := range bill.Produces {
+			if len(produce.Id) == 0 {
+				continue
+			}
+			idCounts[produce.Id] = produce.ConfirmCount
+		}
+		result, err := updateStageCount(bill.Id, bill.PlanId, idCounts, apictx)
+		if err != nil {
+			fmt.Println(err)
+			log.Error(err)
+		}
+		fmt.Println(result)
+	}
+
 	bill.UpdateTime = time.Now()
 	return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionBillProduce, bill.Id.Hex(), &bill)
 }

+ 17 - 0
boxcost/api/bill-product.go

@@ -227,6 +227,23 @@ func UpdateProductBill(c *gin.Context, apictx *ApiSession) (interface{}, error)
 		bill.Remark = " "
 	}
 
+	// 更新供应商确定数量与plan中stage项的同步
+	if len(bill.Products) > 0 {
+		idCounts := map[string]int{}
+		for _, product := range bill.Products {
+			if len(product.Id) == 0 {
+				continue
+			}
+			idCounts[product.Id] = product.ConfirmCount
+		}
+		result, err := updateStageCount(bill.Id, bill.PlanId, idCounts, apictx)
+		if err != nil {
+			fmt.Println(err)
+			log.Error(err)
+		}
+		fmt.Println(result)
+	}
+
 	bill.UpdateTime = time.Now()
 	return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionBillProduct, bill.Id.Hex(), &bill)
 }

+ 16 - 0
boxcost/api/bill.go

@@ -321,6 +321,22 @@ func UpdateBill(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	if bill.Remark == "" {
 		bill.Remark = " "
 	}
+	// 更新供应商确定数量与plan中stage项的同步
+	if len(bill.Paper) > 0 {
+		idCounts := map[string]int{}
+		for _, paper := range bill.Paper {
+			if len(paper.Id) == 0 {
+				continue
+			}
+			idCounts[paper.Id] = paper.ConfirmCount
+		}
+		result, err := updateStageCount(bill.Id, bill.PlanId, idCounts, apictx)
+		if err != nil {
+			fmt.Println(err)
+			log.Error(err)
+		}
+		fmt.Println(result)
+	}
 
 	bill.UpdateTime = time.Now()
 	return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionBillPurchase, bill.Id.Hex(), &bill)

+ 0 - 222
boxcost/api/mac-cpu.go

@@ -1,222 +0,0 @@
-package api
-
-import (
-	"box-cost/db/model"
-	"box-cost/db/repo"
-	"crypto"
-	"crypto/rand"
-	"crypto/rsa"
-	"crypto/sha256"
-	"crypto/x509"
-	"encoding/base64"
-	"encoding/json"
-	"encoding/pem"
-	"errors"
-	"fmt"
-	"io/ioutil"
-	"os"
-	"time"
-
-	"github.com/gin-gonic/gin"
-	"go.mongodb.org/mongo-driver/bson/primitive"
-)
-
-func Mac(r *GinRouter) {
-	r.POST("/get/code", GetCode)
-}
-
-type DeviceInfo struct {
-	DeviceId   string
-	CreateTime time.Time
-	AppName    string
-	AppVersion string
-}
-
-const SECRET_KEY = "DFDFEXVEG"
-
-func GetCode(c *gin.Context, apictx *ApiSession) (interface{}, error) {
-
-	form := model.RegCodeReq{}
-	err := c.ShouldBindJSON(&form)
-	if err != nil {
-		fmt.Println(err)
-		return nil, err
-	}
-	fmt.Println(form)
-
-	return nil, nil
-
-}
-
-func CreatePrivateKey() error {
-	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
-	if err != nil {
-		fmt.Println(err)
-		return err
-	}
-	// 将私钥编码为PEM格式
-	privateKeyPEM := pem.EncodeToMemory(&pem.Block{
-		Type:  "RSA PRIVATE KEY",
-		Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
-	})
-	// 将私钥保存到文件中
-	err = ioutil.WriteFile("certs/private_key.pem", privateKeyPEM, 0600)
-	if err != nil {
-		fmt.Println(err)
-		return err
-	}
-	return nil
-}
-
-func CreatePublicKey(c *gin.Context, apictx *ApiSession) (interface{}, error) {
-	// privateKeyFile, err := os.Open(fileName)
-	privateKeyFile, err := os.Open("certs/private_key.pem")
-	if err != nil {
-		fmt.Println(err)
-		return nil, err
-	}
-	defer privateKeyFile.Close()
-	privateKeyPEM, err := ioutil.ReadAll(privateKeyFile)
-	if err != nil {
-		fmt.Println(err)
-		return nil, err
-	}
-	privateKeyBlock, _ := pem.Decode(privateKeyPEM)
-	privateKey, err := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
-	if err != nil {
-		fmt.Println(err)
-		return nil, err
-	}
-	// 根据私钥生成公钥
-	publicKey1 := privateKey.PublicKey
-	// 根据index的 不同生成不同的publickey
-	index, err := repo.RepoCountDoc(apictx.CreateRepoCtx(), "reg-code", repo.Map{"status": 1})
-	if err != nil {
-		fmt.Println(err)
-		return nil, err
-	}
-	publicKey := rsa.PublicKey{
-		N: publicKey1.N,
-		E: 65537 + int(index),
-	}
-	publicKeyPEM := pem.EncodeToMemory(&pem.Block{
-		Type:  "RSA PUBLIC KEY",
-		Bytes: x509.MarshalPKCS1PublicKey(&publicKey),
-	})
-
-	// 将公钥保存到文件中
-	err = ioutil.WriteFile("public_key.pem", publicKeyPEM, 0644)
-	if err != nil {
-		fmt.Println(err)
-		return nil, err
-	}
-	return true, nil
-}
-
-// 生成激活码
-func CreateActiveCode(c *gin.Context, apictx *ApiSession) (interface{}, error) {
-	// 根据注册码生成激活码
-	// 解析注册码
-	type RegCodeReq struct {
-		Cipher string
-	}
-	form := RegCodeReq{}
-	err := c.ShouldBindJSON(&form)
-	if err != nil {
-		return nil, err
-	}
-	if len(form.Cipher) < 1 {
-		return nil, errors.New("注册码错误")
-	}
-
-	privateFile, err := os.Open("private_key.pem")
-	if err != nil {
-		fmt.Println(err)
-		return false, err
-	}
-	defer privateFile.Close()
-	privateKeyPEM, err := ioutil.ReadAll(privateFile)
-	if err != nil {
-		fmt.Println(err)
-		return false, errors.New("decode err")
-	}
-	privateKeyBlock, _ := pem.Decode(privateKeyPEM)
-	if privateKeyBlock == nil {
-		return false, errors.New("decode err")
-	}
-	privateKey, err := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
-	if err != nil {
-		return false, err
-	}
-
-	decrypted, err := rsa.DecryptOAEP(
-		sha256.New(),
-		rand.Reader,
-		privateKey,
-		[]byte(form.Cipher),
-		[]byte(""),
-	)
-	if err != nil {
-		fmt.Println(err)
-		return false, err
-	}
-
-	decoded, err := base64.StdEncoding.DecodeString(string(decrypted))
-	if err != nil {
-		return nil, err
-	}
-	regCodeReq := model.RegCodeReq{}
-	err = json.Unmarshal(decoded, &regCodeReq)
-	if err != nil {
-		return nil, err
-	}
-	fmt.Println(regCodeReq)
-	// 数据库操作
-	_id, err := repo.RepoAddDoc(apictx.CreateRepoCtx(), "reg-code", &model.RegCode{
-		UserId:     apictx.User.Parent,
-		AppId:      regCodeReq.AppId,
-		AppName:    regCodeReq.AppName,
-		AppVersion: regCodeReq.AppVersion,
-		DeviceId:   regCodeReq.DeviceId,
-		// RegCode:    form.Code,
-		// ActiveCode
-		IsPerm:     regCodeReq.IsPerm,
-		CreateTime: time.Now(),
-		UpdateTIme: time.Now(),
-		ExpireTime: regCodeReq.ExpireTime,
-		Status:     1,
-	})
-
-	if err != nil {
-		return nil, err
-	}
-
-	// 组装返回数据
-	id, _ := primitive.ObjectIDFromHex(_id)
-
-	// Calculate hash of ciphertext
-	hash := sha256.Sum256([]byte(form.Cipher))
-
-	// Generate signature
-	signature, err := rsa.SignPKCS1v15(
-		rand.Reader,
-		privateKey,
-		crypto.SHA256,
-		hash[:],
-	)
-	if err != nil {
-		fmt.Println(err)
-		return nil, err
-	}
-
-	resp := &model.RegCodeResp{
-		Id:         id,
-		AppId:      regCodeReq.AppId,
-		AppName:    regCodeReq.AppName,
-		AppVersion: regCodeReq.AppVersion,
-		Signature:  string(signature),
-		CipherText: form.Cipher,
-	}
-
-	return resp, nil
-}

+ 35 - 0
boxcost/api/plan.go

@@ -113,6 +113,41 @@ func PlanAllocBatch(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 
 }
 
+// 更新供应商确定数量与plan中stage项的同步
+func updateStageCount(billId primitive.ObjectID, planId primitive.ObjectID, idCounts map[string]int, apictx *ApiSession) (interface{}, error) {
+	if len(idCounts) == 0 {
+		return true, nil
+	}
+
+	plan := model.ProductPlan{}
+	found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
+		CollectName: repo.CollectionProductPlan,
+		Query:       repo.Map{"_id": planId},
+	}, &plan)
+	if !found || err != nil {
+		return nil, errors.New("数据未找到")
+	}
+	for _, comp := range plan.Pack.Components {
+		if comp.Id == "" || len(comp.Stages) == 0 {
+			continue
+		}
+		for _, stage := range comp.Stages {
+			if v, ok := idCounts[stage.Id]; ok {
+				stage.ConfirmCount = v
+			}
+		}
+
+	}
+	fmt.Println(plan)
+	_, err = repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionProductPlan, planId.Hex(), &plan)
+	if err != nil {
+		log.Error(err)
+		fmt.Println(err)
+	}
+	return true, err
+
+}
+
 type SupplierPlanCost struct {
 	*model.ProductPlan
 	SupplierId string

+ 0 - 2
boxcost/api/router.go

@@ -58,8 +58,6 @@ func RegRouters(svc *Service) {
 	// 成品采购管理
 	Product(boxcost)
 
-	Mac(boxcost)
-
 	boxcost.GET("/apk/version", func(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 		out, err := repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
 			CollectName: "versions",

+ 0 - 11
boxcost/db/model/aggregate-test.go

@@ -1,11 +0,0 @@
-package model
-
-import "go.mongodb.org/mongo-driver/bson/primitive"
-
-type AggregateTest struct {
-	Id     primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
-	Name   string             `bson:"name,omitempty" json:"name"`
-	Age    int                `bson:"age,omitempty" json:"age"`
-	Sex    *int               `bson:"sex,omitempty" json:"sex"`
-	Salary int                `bson:"salary,omitempty" json:"salary"`
-}

+ 3 - 0
boxcost/db/model/bill.go

@@ -8,6 +8,7 @@ import (
 
 // 采购单
 type PaperBill struct {
+	Id string `bson:"id,omitempty" json:"id"`
 	//名字
 	Name string `bson:"name,omitempty" json:"name"`
 	//规格
@@ -85,6 +86,7 @@ type PurchaseBill struct {
 
 // 工艺生产数据
 type ProduceBillData struct {
+	Id string `bson:"id,omitempty" json:"id"`
 	//名字
 	Name string `bson:"name,omitempty" json:"name"`
 
@@ -217,6 +219,7 @@ type ProductBill struct {
 
 // 工艺生产数据
 type ProductBillData struct {
+	Id string `bson:"id,omitempty" json:"id"`
 	//名字
 	Name string `bson:"name,omitempty" json:"name"`
 

+ 0 - 45
boxcost/db/model/regCode.go

@@ -1,45 +0,0 @@
-package model
-
-import (
-	"time"
-
-	"go.mongodb.org/mongo-driver/bson/primitive"
-)
-
-type RegCodeReq struct {
-	AppId      string    `bson:"appId,omitempty" json:"appId"`
-	AppName    string    `bson:"appName,omitempty" json:"appName"`
-	AppKey     string    `bson:"appKey,omitempty" json:"appKey"`
-	AppVersion string    `bson:"appVersion,omitempty" json:"appVersion"`
-	DeviceId   string    `bson:"deviceId,omitempty" json:"deviceId"`
-	ExpireTime time.Time `bson:"expireTime,omitempty" json:"expireTime"`
-	IsPerm     *bool     `bson:"isPerm,omitempty" json:"isPerm"`
-}
-
-type RegCodeResp struct {
-	Id         primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
-	AppId      string             `bson:"appId,omitempty" json:"appId"`
-	AppName    string             `bson:"appName,omitempty" json:"appName"`
-	AppVersion string             `bson:"appVersion,omitempty" json:"appVersion"`
-	ActiveCode string             `bson:"activeCode,omitempty" json:"activeCode"`
-	CipherText string             `bson:"cipherText,omitempty" json:"cipherText"`
-	Signature  string             `bson:"signature,omitempty" json:"signature"`
-	CreateTime time.Time          `bson:"createTime,omitempty" json:"createTime"`
-}
-
-type RegCode struct {
-	Id         primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
-	UserId     string             `bson:"userId,omitempty" json:"userId"`
-	AppId      string             `bson:"appId,omitempty" json:"appId"`
-	AppName    string             `bson:"appName,omitempty" json:"appName"`
-	AppVersion string             `bson:"appVersion,omitempty" json:"appVersion"`
-	DeviceId   string             `bson:"deviceId,omitempty" json:"deviceId"`
-	Key        string             `bson:"key,omitempty" json:"key"`
-	RegCode    string             `bson:"code,omitempty" json:"code"`
-	ActiveCode string             `bson:"activeCode,omitempty" json:"activeCode"`
-	IsPerm     *bool              `bson:"isPerm,omitempty" json:"isPerm"`
-	CreateTime time.Time          `bson:"createTime,omitempty" json:"createTime"`
-	UpdateTIme time.Time          `bson:"updateTIme,omitempty" json:"updateTIme"`
-	ExpireTime time.Time          `bson:"expireTime,omitempty" json:"expireTime"`
-	Status     int                `bson:"status,omitempty" json:"status"`
-}

+ 186 - 0
boxcost/utils/reg-code.go

@@ -0,0 +1,186 @@
+package utils
+
+import (
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/md5"
+	"crypto/rand"
+	"crypto/sha1"
+	"encoding/base64"
+	"errors"
+	"fmt"
+	"io"
+	"strconv"
+	"strings"
+
+	"github.com/shirou/gopsutil/disk"
+	"github.com/shirou/gopsutil/net"
+)
+
+// 字符串生成md5
+func CreatMD5(s string) string {
+	data := []byte(s)
+	has := md5.Sum(data)
+	return fmt.Sprintf("%x", has)
+}
+
+func GetDiskId() string {
+	partitions, err := disk.Partitions(false)
+	if err != nil {
+		return ""
+	}
+	return disk.GetDiskSerialNumber(partitions[0].Device)
+
+}
+
+// 获取物理网卡mac地址
+func GetRealMacAddr() string {
+	netInterfaces, err := net.Interfaces()
+	if err != nil {
+		return ""
+	}
+	loindex := 0
+	for _, netInterface := range netInterfaces {
+		if netInterface.Name == "lo" {
+			loindex = netInterface.Index
+			break
+		}
+	}
+	if len(netInterfaces) < loindex+1 {
+		return ""
+	}
+	fmt.Println(netInterfaces[loindex].HardwareAddr)
+	return netInterfaces[loindex].HardwareAddr
+}
+
+func GetDeviceId() string {
+	// deviceId := fmt.Sprintf("%s:%s", GetRealMacAddr(), GetDiskId())
+	deviceId := GetRealMacAddr()
+	fmt.Println(deviceId)
+	return CreatMD5(deviceId)
+}
+
+// sha1()方法,返回的是byte转换的字符串,如果需要转成16进制,可以使用hex.EncodeToString
+func GetSha1(str string) string {
+	h := sha1.New()
+	io.WriteString(h, str)
+	return string(h.Sum(nil))
+}
+
+// 右边补全字符串实现方法,主要实现php的str_pad()方法
+func StrPadRight(input string, padLength int, padString string) string {
+	output := ""
+	inputLen := len(input)
+	if inputLen >= padLength {
+		return input
+	}
+	ll := padLength - inputLen
+	for i := 1; i <= ll; i = i + len(padString) {
+		output += padString
+	}
+	return input + output
+}
+
+// 生成密钥
+func GenSecretKey(appId string, appSecret string) (secretKey string) {
+	key := appId + "&" + appSecret
+	sha1_str := GetSha1(key)
+	str10 := "0"
+	pack64, _ := strconv.ParseUint(str10, 10, 32)
+	fmt.Println(pack64)
+	pack32 := uint32(pack64)
+	str_pad := StrPadRight(sha1_str, 32, string(rune(pack32)))
+	secretKey = base64.StdEncoding.EncodeToString([]byte(str_pad))
+	return secretKey
+}
+
+// 解密
+func GetCallbackData(secretKey string, encryptData string) (result_str string, err error) {
+	decodeSecretKeyByte, _ := base64.StdEncoding.DecodeString(secretKey)
+	decodeSecretKey := string(decodeSecretKeyByte)
+	orderSuccessPayInfoByte, err2 := DecodeAesGcm(encryptData, decodeSecretKey, "")
+	result_str = string(orderSuccessPayInfoByte)
+	if err2 != nil {
+		return result_str, errors.New("decode error")
+	}
+	return result_str, err
+}
+
+// 加密
+func SetCallbackData(secretKey string, data string) (result_str string, err error) {
+	decodeSecretKeyByte, _ := base64.StdEncoding.DecodeString(secretKey)
+	decodeSecretKey := string(decodeSecretKeyByte)
+	orderSuccessPayInfoByte, err2 := EncodeAesGcm(data, decodeSecretKey, "")
+	result_str = string(orderSuccessPayInfoByte)
+	if err2 != nil {
+		return result_str, errors.New("encode error")
+	}
+	return result_str, err
+}
+
+// url安全模式decode字符串
+func UrlSafeB64decode(str string) (result []byte) {
+	str = strings.Replace(str, "-", "+", -1)
+	str = strings.Replace(str, "_", "/", -1)
+	mod4 := len(str) % 4
+	if mod4 != 0 {
+		str = str + "===="[0:mod4]
+	}
+	result, _ = base64.StdEncoding.DecodeString(str)
+	return result
+}
+
+// base64字符串,替换转换为安全模式
+func UrlSafeB64encode(str string) (result string) {
+	str = strings.Replace(str, "+", "-", -1)
+	str = strings.Replace(str, "/", "_", -1)
+	return str
+}
+
+// 使用aes-256-gcm方式解密字符串
+func DecodeAesGcm(encryptData string, hex_key string, hex_add string) ([]byte, error) {
+	tagSize := 16 //nonceSize,tag的长度,用于open时候生成tag,默认12
+	key := []byte(hex_key)
+	add := []byte(hex_add)
+	block, err := aes.NewCipher(key) //生成加解密用的block
+	if err != nil {
+		return []byte(""), err
+	}
+	//根据不同加密算法,也有不同tag长度的方法设定和调用,比如NewGCMWithTagSize、newGCMWithNonceAndTagSize
+	aesgcm, err := cipher.NewGCMWithNonceSize(block, tagSize)
+	if err != nil {
+		return []byte(""), err
+	}
+	decodeEncryptStr := UrlSafeB64decode(encryptData)
+	ciphertext := decodeEncryptStr
+	if len(ciphertext) <= aesgcm.NonceSize() { // 长度应该>iv
+		return []byte(""), errors.New("string: too short") //解密失败
+	}
+	iv := ciphertext[:aesgcm.NonceSize()]        //分离出IV
+	ciphertext = ciphertext[aesgcm.NonceSize():] // 密文,tag是调用open方法时候通过密文和前面new时候传的size来进行截取的
+	plaintext, err := aesgcm.Open(nil, iv, ciphertext, add)
+	return plaintext, err
+}
+
+// 使用aes-256-gcm加密数据
+func EncodeAesGcm(data string, hex_key string, hex_add string) (result string, error error) {
+	tagSize := 16 //nonceSize,tag的长度,用于open时候生成tag,默认12
+	key := []byte(hex_key)
+	add := []byte(hex_add)
+	block, err := aes.NewCipher(key) //生成加解密用的block
+	if err != nil {
+		return result, err
+	}
+	//根据不同加密算法,也有不同tag长度的方法设定和调用,比如NewGCMWithTagSize、newGCMWithNonceAndTagSize
+	aesgcm, err := cipher.NewGCMWithNonceSize(block, tagSize)
+	if err != nil {
+		return result, err
+	}
+	plaintext := []byte(data)
+	iv := make([]byte, tagSize)                       // NonceSize=12
+	rand.Read(iv)                                     //获取随机值
+	ciphertext := aesgcm.Seal(iv, iv, plaintext, add) //加密,密文为:iv+密文+tag
+	result = base64.StdEncoding.EncodeToString(ciphertext)
+	result = UrlSafeB64encode(result)
+	return result, nil // 生成的BS64
+}