瀏覽代碼

add:物联网卡管理,库存管理库存不足预警,验证设备分类,入库类型区分入库和退库

zoie 3 天之前
父節點
當前提交
6dd5873d00

+ 0 - 10
conf/app.conf

@@ -18,16 +18,6 @@ MysqlServer_Password = "cHFeFmxFhZJdijDn"
 MysqlServer_MaxIdleConnections = 100
 MysqlServer_MaxOpenConnections = 200
 
-# NatsSubj_Prefix = ""
-
-
-# Mysql 线上
-# MysqlServer_UrlPort = "127.0.0.1:3316"
-# MysqlServer_Database = "erp_storage"
-# MysqlServer_Username = "erp_storage"
-# MysqlServer_Password = "cHFeFmxFhZJdijDn"
-# MysqlServer_MaxIdleConnections = 100
-# MysqlServer_MaxOpenConnections = 200
 
 # Mysql Mqtt
 MysqlMqtt_UrlPort = "203.34.49.130:3306"

+ 19 - 13
controllers/Basic.go

@@ -8,10 +8,10 @@ import (
 	"ERP_storage/models/Percentage"
 	"ERP_storage/models/Stock"
 	"fmt"
-	userlibs "gogs.baozhida.cn/zoie/ERP_libs/User"
-	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	"github.com/beego/beego/v2/adapter/orm"
 	beego "github.com/beego/beego/v2/server/web"
+	userlibs "gogs.baozhida.cn/zoie/ERP_libs/User"
+	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	"math"
 	"strconv"
 )
@@ -298,6 +298,7 @@ func (c *BasicController) Product_Add() {
 	T_price, _ := c.GetFloat("T_price")
 	T_img := c.GetString("T_img")
 	T_remark := c.GetString("T_remark")
+	T_early_warning, _ := c.GetInt("T_early_warning")
 
 	if len(T_name) == 0 {
 		c.Data["json"] = lib.JSONS{Code: 202, Msg: "产品名称不能为空!"}
@@ -318,15 +319,16 @@ func (c *BasicController) Product_Add() {
 	}
 
 	var_ := Basic.Product{
-		T_name:        T_name,
-		T_class:       T_class,
-		T_model:       T_model,
-		T_spec:        T_spec,
-		T_price:       float32(T_price),
-		T_relation_sn: T_relation_sn,
-		T_img:         T_img,
-		T_remark:      T_remark,
-		T_State:       1,
+		T_name:          T_name,
+		T_class:         T_class,
+		T_model:         T_model,
+		T_spec:          T_spec,
+		T_price:         float32(T_price),
+		T_relation_sn:   T_relation_sn,
+		T_img:           T_img,
+		T_remark:        T_remark,
+		T_State:         1,
+		T_early_warning: T_early_warning,
 	}
 
 	Id, err := Basic.Add_Product(var_)
@@ -352,6 +354,7 @@ func (c *BasicController) Product_Edit() {
 	T_relation_sn, _ := c.GetInt("T_relation_sn")
 	T_img := c.GetString("T_img")
 	T_remark := c.GetString("T_remark")
+	T_early_warning, _ := c.GetInt("T_early_warning")
 
 	Product_r, err := Basic.Read_Product_ById(T_id)
 	if err != nil {
@@ -384,8 +387,12 @@ func (c *BasicController) Product_Edit() {
 	if T_price > 0 {
 		Product_r.T_price = float32(T_price)
 	}
+	if T_early_warning > 0 {
+		Product_r.T_early_warning = T_early_warning
+	}
 
-	if err = Basic.Update_Product(Product_r, "T_name", "T_class", "T_model", "T_spec", "T_price", "T_relation_sn", "T_img", "T_remark"); err != nil {
+	if err = Basic.Update_Product(Product_r, "T_name", "T_class", "T_model", "T_spec", "T_price",
+		"T_relation_sn", "T_img", "T_remark", "T_early_warning"); err != nil {
 		c.Data["json"] = lib.JSONS{Code: 203, Msg: "修改失败"}
 		c.ServeJSON()
 		return
@@ -456,7 +463,6 @@ func (c *BasicController) Product_Edit_Sort() {
 		return
 	}
 
-
 	NatsServer.AddUserLogs(c.User.T_uuid, "产品", "修改排序", Product_r)
 
 	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}

+ 334 - 0
controllers/IOTNetworkCard.go

@@ -0,0 +1,334 @@
+package controllers
+
+import (
+	"ERP_storage/Nats/NatsServer"
+	"ERP_storage/conf"
+	"ERP_storage/logs"
+	"ERP_storage/models/Account"
+	"ERP_storage/models/IOTNetworkCard"
+	"encoding/json"
+	"github.com/beego/beego/v2/adapter/orm"
+	beego "github.com/beego/beego/v2/server/web"
+	"github.com/xuri/excelize/v2"
+	userlibs "gogs.baozhida.cn/zoie/ERP_libs/User"
+	"gogs.baozhida.cn/zoie/ERP_libs/lib"
+	"math"
+	"strconv"
+	"time"
+)
+
+type IOTNetworkCardController struct {
+	beego.Controller
+	User userlibs.User
+}
+
+func (c *IOTNetworkCardController) Prepare() {
+	c.User = *Account.User_r
+}
+
+// 财务管理列表
+func (c *IOTNetworkCardController) IOTNetworkCard_List() {
+
+	// 分页参数 初始化
+	page, _ := c.GetInt("page")
+	if page < 1 {
+		page = 1
+	}
+	page_z, _ := c.GetInt("page_z")
+	if page_z < 1 {
+		page_z = conf.Page_size
+	}
+
+	// 查询
+	T_name := c.GetString("T_name")
+	T_state, _ := c.GetInt("T_state")
+
+	IOTNetworkCardDao := IOTNetworkCard.NewIOTNetworkCard(orm.NewOrm())
+	R_List, R_cnt := IOTNetworkCardDao.Read_IOTNetworkCard_List(T_name, T_state, page, page_z)
+
+	var r_jsons lib.R_JSONS
+	r_jsons.Num = R_cnt
+	r_jsons.Data = R_List
+	r_jsons.Page = page
+	r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(page_z)))
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
+	c.ServeJSON()
+	return
+}
+
+func (c *IOTNetworkCardController) IOTNetworkCard_Get() {
+
+	// 查询
+	T_id, _ := c.GetInt("T_id")
+	IOTNetworkCard_r, err := IOTNetworkCard.Read_IOTNetworkCard_ById(T_id)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: "T_id Err!"}
+		c.ServeJSON()
+		return
+	}
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: IOTNetworkCard.IOTNetworkCardToIOTNetworkCard_R(IOTNetworkCard_r)}
+	c.ServeJSON()
+	return
+}
+
+func (c *IOTNetworkCardController) IOTNetworkCard_Add() {
+
+	T_in_date := c.GetString("T_in_date")
+	T_meal_type := c.GetString("T_meal_type")
+	T_meal := c.GetString("T_meal")
+	T_expire := c.GetString("T_expire")
+	T_iccid := c.GetString("T_iccid")
+	T_MSISDN := c.GetString("T_MSISDN")
+	T_State, _ := c.GetInt("T_State")
+
+	var_ := IOTNetworkCard.IOTNetworkCard{
+		T_in_date:   T_in_date,
+		T_meal_type: T_meal_type,
+		T_meal:      T_meal,
+		T_expire:    T_expire,
+		T_iccid:     T_iccid,
+		T_MSISDN:    T_MSISDN,
+		T_State:     T_State,
+	}
+	// 添加入库记录
+	var record []IOTNetworkCard.IOTNetworkCardRecord
+	record = append(record, IOTNetworkCard.IOTNetworkCardRecord{
+		T_data:  time.Now().Format("2006-01-02"),
+		T_State: T_State,
+	})
+	recordB, _ := json.Marshal(&record)
+	var_.T_record = string(recordB)
+
+	card, err := IOTNetworkCard.Read_IOTNetworkCard_ByT_MSISDN(T_MSISDN)
+	if err != nil && err.Error() != orm.ErrNoRows.Error() {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "添加失败"}
+		c.ServeJSON()
+		return
+	}
+	if card.Id > 0 {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "此卡已入库"}
+		c.ServeJSON()
+		return
+	}
+	o := orm.NewOrm()
+
+	IOTNetworkCardDao := IOTNetworkCard.NewIOTNetworkCard(o)
+	Id, err := IOTNetworkCardDao.Add_IOTNetworkCard(var_)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: "添加失败"}
+		c.ServeJSON()
+		return
+	}
+
+	NatsServer.AddUserLogs(c.User.T_uuid, "物联网卡", "添加", var_)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: Id}
+	c.ServeJSON()
+	return
+}
+
+func (c *IOTNetworkCardController) IOTNetworkCard_Edit() {
+	T_id, _ := c.GetInt("T_id")
+	T_in_date := c.GetString("T_in_date")
+	T_meal_type := c.GetString("T_meal_type")
+	T_meal := c.GetString("T_meal")
+	T_expire := c.GetString("T_expire")
+	T_iccid := c.GetString("T_iccid")
+	T_MSISDN := c.GetString("T_MSISDN")
+	T_out_date := c.GetString("T_out_date")       // 出库日期
+	T_out_project := c.GetString("T_out_project") // 出库项目
+	T_receive := c.GetString("T_receive")         // 领用人
+	T_State, _ := c.GetInt("T_State")             // 状态
+
+	IOTNetworkCard_r, err := IOTNetworkCard.Read_IOTNetworkCard_ById(T_id)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: "T_id Err!"}
+		c.ServeJSON()
+		return
+	}
+	if len(T_in_date) > 0 {
+		IOTNetworkCard_r.T_in_date = T_in_date
+	}
+	if len(T_meal_type) > 0 {
+		IOTNetworkCard_r.T_meal_type = T_meal_type
+	}
+	if len(T_meal) > 0 {
+		IOTNetworkCard_r.T_meal = T_meal
+	}
+	if len(T_expire) > 0 {
+		IOTNetworkCard_r.T_expire = T_expire
+	}
+	if len(T_iccid) > 0 {
+		IOTNetworkCard_r.T_iccid = T_iccid
+	}
+	if len(T_MSISDN) > 0 {
+		IOTNetworkCard_r.T_MSISDN = T_MSISDN
+	}
+	if len(T_out_date) > 0 {
+		IOTNetworkCard_r.T_out_date = T_out_date
+	}
+	if len(T_out_project) > 0 {
+		IOTNetworkCard_r.T_out_project = T_out_project
+	}
+	if len(T_receive) > 0 {
+		IOTNetworkCard_r.T_receive = T_receive
+	}
+	if T_State > 0 && T_State != IOTNetworkCard_r.T_State {
+		IOTNetworkCard_r.T_State = T_State
+
+		// 添加入库记录
+		var record []IOTNetworkCard.IOTNetworkCardRecord
+		err = json.Unmarshal([]byte(IOTNetworkCard_r.T_record), &record)
+		if err != nil {
+			logs.Error("JSON 反序列化失败:", err)
+			return
+		}
+		record = append(record, IOTNetworkCard.IOTNetworkCardRecord{
+			T_data:   time.Now().Format("2006-01-02"),
+			T_State:  T_State,
+			T_remark: T_out_project,
+		})
+		recordB, _ := json.Marshal(&record)
+		IOTNetworkCard_r.T_record = string(recordB)
+
+	}
+
+	o := orm.NewOrm()
+	IOTNetworkCardDao := IOTNetworkCard.NewIOTNetworkCard(o)
+	if err = IOTNetworkCardDao.Update_IOTNetworkCard(IOTNetworkCard_r,
+		"T_in_date", "T_meal_type", "T_meal", "T_expire", "T_iccid", "T_MSISDN", "T_out_date", "T_out_project", "T_receive", "T_State", "T_record"); err != nil {
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: "修改失败"}
+		c.ServeJSON()
+		return
+	}
+
+	NatsServer.AddUserLogs(c.User.T_uuid, "物联网卡", "修改", IOTNetworkCard_r)
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
+	c.ServeJSON()
+	return
+}
+func (c *IOTNetworkCardController) IOTNetworkCard_Del() {
+
+	T_id, _ := c.GetInt("T_id")
+	IOTNetworkCard_r, err := IOTNetworkCard.Read_IOTNetworkCard_ById(T_id)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 203, Msg: "T_id Err!"}
+		c.ServeJSON()
+		return
+	}
+	o := orm.NewOrm()
+	IOTNetworkCardDao := IOTNetworkCard.NewIOTNetworkCard(o)
+	err = IOTNetworkCardDao.Delete_IOTNetworkCard(IOTNetworkCard_r)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "删除失败!"}
+		c.ServeJSON()
+		return
+	}
+
+	NatsServer.AddUserLogs(c.User.T_uuid, "物联网卡", "删除", strconv.Itoa(T_id))
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_id}
+	c.ServeJSON()
+	return
+}
+
+// 导入
+func (c *IOTNetworkCardController) IOTNetworkCard_Import() {
+	// 获取上传的文件
+	IOTNetworkCardDao := IOTNetworkCard.NewIOTNetworkCard(orm.NewOrm())
+	f, _, err := c.GetFile("file")
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 1201, Msg: "读取文件失败!", Data: nil}
+		c.ServeJSON()
+		return
+	}
+	defer f.Close()
+
+	// 读取 Excel 文件
+	reader, err := excelize.OpenReader(f)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 1201, Msg: "打开文件失败!", Data: nil}
+		c.ServeJSON()
+		return
+	}
+	defer func() {
+		if err = reader.Close(); err != nil {
+			c.Data["json"] = lib.JSONS{Code: 1201, Msg: "关闭文件失败!", Data: nil}
+			c.ServeJSON()
+			return
+		}
+	}()
+	sheetMap := reader.GetSheetMap()
+	for _, sheetName := range sheetMap {
+		//读取工作表中的数据
+		rows, errs := reader.GetRows(sheetName)
+		if errs != nil {
+			c.Data["json"] = lib.JSONS{Code: 1201, Msg: "读取工作表失败!", Data: nil}
+			c.ServeJSON()
+			return
+		}
+		for i, row := range rows {
+			if i < 2 {
+				continue // 忽略第一行和第二行
+			}
+			if len(row) >= 6 {
+				// 解析时间
+				t, errT := time.Parse("01-02-06", row[0])
+				if errT != nil {
+					c.Data["json"] = lib.JSONS{Code: 203, Msg: "解析入库时间失败"}
+					c.ServeJSON()
+					return
+				}
+				var_ := IOTNetworkCard.IOTNetworkCard{
+					T_in_date:   t.Format("2006-01-02"),
+					T_meal_type: row[1],
+					T_meal:      row[2],
+					T_expire:    row[3],
+					T_iccid:     row[4],
+					T_MSISDN:    row[5],
+					T_State:     IOTNetworkCard.IOTNetworkCardNewCardIn,
+				}
+				// 添加入库记录
+				var record []IOTNetworkCard.IOTNetworkCardRecord
+				record = append(record, IOTNetworkCard.IOTNetworkCardRecord{
+					T_data:  time.Now().Format("2006-01-02"),
+					T_State: IOTNetworkCard.IOTNetworkCardNewCardIn,
+				})
+
+				if len(row) >= 8 {
+					// 解析时间
+					outT, errOutT := time.Parse("01-02-06", row[6])
+					if errOutT != nil {
+						c.Data["json"] = lib.JSONS{Code: 203, Msg: "解析出库时间失败"}
+						c.ServeJSON()
+						return
+					}
+					var_.T_State = IOTNetworkCard.IOTNetworkCardOut
+					var_.T_out_date = outT.Format("2006-01-02")
+					var_.T_out_project = row[7]
+					record = append(record, IOTNetworkCard.IOTNetworkCardRecord{
+						T_data:   time.Now().Format("2006-01-02"),
+						T_State:  IOTNetworkCard.IOTNetworkCardOut,
+						T_remark: row[7],
+					})
+				}
+
+				recordB, _ := json.Marshal(&record)
+				var_.T_record = string(recordB)
+
+				_, err = IOTNetworkCardDao.Add_IOTNetworkCard(var_)
+				if err != nil {
+					c.Data["json"] = lib.JSONS{Code: 203, Msg: "添加失败"}
+					c.ServeJSON()
+					return
+				}
+			}
+		}
+	}
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "成功!", Data: nil}
+	c.ServeJSON()
+}

+ 2 - 2
controllers/Percentage.go

@@ -9,10 +9,10 @@ import (
 	"ERP_storage/models/Percentage"
 	"ERP_storage/models/Stock"
 	"fmt"
-	userlibs "gogs.baozhida.cn/zoie/ERP_libs/User"
-	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	"github.com/beego/beego/v2/adapter/orm"
 	beego "github.com/beego/beego/v2/server/web"
+	userlibs "gogs.baozhida.cn/zoie/ERP_libs/User"
+	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	"math"
 )
 

+ 75 - 119
controllers/Stock.go

@@ -260,6 +260,29 @@ func (c *StockController) Stock_Detail_Excel() {
 			},
 		})
 
+	Style3, _ := f.NewStyle(
+		&excelize.Style{
+			Font:      &excelize.Font{Bold: true, Size: 10, Family: "宋体", Color: "FF0000"},
+			Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
+			Border: []excelize.Border{
+				{Type: "left", Color: "000000", Style: 1},
+				{Type: "top", Color: "000000", Style: 1},
+				{Type: "bottom", Color: "000000", Style: 1},
+				{Type: "right", Color: "000000", Style: 1},
+			},
+		})
+	Style4, _ := f.NewStyle(
+		&excelize.Style{
+			Font:      &excelize.Font{Size: 10, Family: "宋体"},
+			Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
+			Border: []excelize.Border{
+				{Type: "left", Color: "000000", Style: 1},
+				{Type: "top", Color: "000000", Style: 1},
+				{Type: "bottom", Color: "000000", Style: 1},
+				{Type: "right", Color: "000000", Style: 1},
+			},
+		})
+
 	StockMonthDao := Stock.NewStockMonth(orm.NewOrm())
 	StockOutDao := Stock.NewStockOut(orm.NewOrm())
 
@@ -323,24 +346,19 @@ func (c *StockController) Stock_Detail_Excel() {
 			f.SetCellValue(r.T_name, fmt.Sprintf("G%d", line), v.T_in)
 			f.SetCellValue(r.T_name, fmt.Sprintf("H%d", line), v.T_out)
 			f.SetCellValue(r.T_name, fmt.Sprintf("I%d", line), v.T_ending)
+			if product.T_early_warning > v.T_ending {
+				f.SetCellStyle(r.T_name, fmt.Sprintf("I%d", line), fmt.Sprintf("I%d", line), Style3)
+			} else {
+				f.SetCellStyle(r.T_name, fmt.Sprintf("I%d", line), fmt.Sprintf("I%d", line), Style4)
+
+			}
 			T_project := StockOutDao.Read_StockOut_T_project(T_depot_id, product.Id, v.T_month)
 			//f.SetCellValue(r.T_name, fmt.Sprintf("J%d", line), v.T_project)
 			f.SetCellValue(r.T_name, fmt.Sprintf("J%d", line), strings.Join(T_project, "\r\n"))
 
 		}
-		Style4, _ := f.NewStyle(
-			&excelize.Style{
-				Font:      &excelize.Font{Size: 10, Family: "宋体"},
-				Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
-				Border: []excelize.Border{
-					{Type: "left", Color: "000000", Style: 1},
-					{Type: "top", Color: "000000", Style: 1},
-					{Type: "bottom", Color: "000000", Style: 1},
-					{Type: "right", Color: "000000", Style: 1},
-				},
-			})
 
-		f.SetCellStyle(r.T_name, "A2", fmt.Sprintf("I%d", line), Style4)
+		f.SetCellStyle(r.T_name, "A2", fmt.Sprintf("H%d", line), Style4)
 
 		Style5, _ := f.NewStyle(
 			&excelize.Style{
@@ -500,12 +518,12 @@ func (c *StockController) StockIn_List_Product_Excel() {
 			},
 		})
 
-	f.MergeCell("Sheet1", "A1", "K1")
+	f.MergeCell("Sheet1", "A1", "L1")
 	f.SetRowStyle("Sheet1", 1, 1, Style1)
 	f.SetCellValue("Sheet1", "A1", fmt.Sprintf("入库明细单"))
 	f.SetRowHeight("Sheet1", 1, 30)
 	// 这里设置表头
-	f.SetCellStyle("Sheet1", "A2", "K2", Style2)
+	f.SetCellStyle("Sheet1", "A2", "L2", Style2)
 	f.SetRowHeight("Sheet1", 2, 20)
 
 	f.SetCellValue("Sheet1", "A2", "序号")
@@ -513,24 +531,26 @@ func (c *StockController) StockIn_List_Product_Excel() {
 	f.SetCellValue("Sheet1", "C2", "经办人")
 	f.SetCellValue("Sheet1", "D2", "入库日期")
 	f.SetCellValue("Sheet1", "E2", "入库仓库")
-	f.SetCellValue("Sheet1", "F2", "产品名称")
-	f.SetCellValue("Sheet1", "G2", "产品型号")
-	f.SetCellValue("Sheet1", "H2", "数量")
-	f.SetCellValue("Sheet1", "I2", "是否关联SN")
-	f.SetCellValue("Sheet1", "J2", "备注")
-	f.SetCellValue("Sheet1", "K2", "SN")
+	f.SetCellValue("Sheet1", "F2", "入库类型")
+	f.SetCellValue("Sheet1", "G2", "产品名称")
+	f.SetCellValue("Sheet1", "H2", "产品型号")
+	f.SetCellValue("Sheet1", "I2", "数量")
+	f.SetCellValue("Sheet1", "J2", "是否关联SN")
+	f.SetCellValue("Sheet1", "K2", "备注")
+	f.SetCellValue("Sheet1", "L2", "SN")
 	// 设置列宽
 	f.SetColWidth("Sheet1", "A", "A", 10)
 	f.SetColWidth("Sheet1", "B", "B", 15)
 	f.SetColWidth("Sheet1", "C", "D", 10)
 	f.SetColWidth("Sheet1", "D", "D", 10)
 	f.SetColWidth("Sheet1", "E", "E", 10)
-	f.SetColWidth("Sheet1", "F", "F", 20)
-	f.SetColWidth("Sheet1", "G", "G", 15)
-	f.SetColWidth("Sheet1", "H", "H", 10)
-	f.SetColWidth("Sheet1", "I", "I", 12)
-	f.SetColWidth("Sheet1", "J", "J", 30)
-	f.SetColWidth("Sheet1", "K", "K", 100)
+	f.SetColWidth("Sheet1", "F", "F", 10)
+	f.SetColWidth("Sheet1", "G", "G", 20)
+	f.SetColWidth("Sheet1", "H", "H", 15)
+	f.SetColWidth("Sheet1", "I", "I", 10)
+	f.SetColWidth("Sheet1", "J", "J", 12)
+	f.SetColWidth("Sheet1", "K", "K", 30)
+	f.SetColWidth("Sheet1", "L", "L", 100)
 	line := 2
 
 	for _, product := range R_List {
@@ -540,9 +560,16 @@ func (c *StockController) StockIn_List_Product_Excel() {
 		f.SetCellValue("Sheet1", fmt.Sprintf("C%d", line), product.T_submit_name)
 		f.SetCellValue("Sheet1", fmt.Sprintf("D%d", line), product.T_date)
 		f.SetCellValue("Sheet1", fmt.Sprintf("E%d", line), product.T_depot_name)
-		f.SetCellValue("Sheet1", fmt.Sprintf("F%d", line), product.T_product_name)
-		f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), product.T_product_model)
-		f.SetCellValue("Sheet1", fmt.Sprintf("H%d", line), product.T_num)
+		var type_str string
+		if product.T_type == 1 {
+			type_str = "入库"
+		} else {
+			type_str = "退库"
+		}
+		f.SetCellValue("Sheet1", fmt.Sprintf("F%d", line), type_str)
+		f.SetCellValue("Sheet1", fmt.Sprintf("G%d", line), product.T_product_name)
+		f.SetCellValue("Sheet1", fmt.Sprintf("H%d", line), product.T_product_model)
+		f.SetCellValue("Sheet1", fmt.Sprintf("I%d", line), product.T_num)
 		var relation_sn string
 		if product.T_product_relation_sn == 1 {
 			relation_sn = "是"
@@ -550,12 +577,12 @@ func (c *StockController) StockIn_List_Product_Excel() {
 			relation_sn = "否"
 		}
 
-		f.SetCellValue("Sheet1", fmt.Sprintf("I%d", line), relation_sn)
-		f.SetCellValue("Sheet1", fmt.Sprintf("J%d", line), product.T_remark)
-		f.SetCellValue("Sheet1", fmt.Sprintf("K%d", line), product.T_relation_sn)
+		f.SetCellValue("Sheet1", fmt.Sprintf("J%d", line), relation_sn)
+		f.SetCellValue("Sheet1", fmt.Sprintf("K%d", line), product.T_remark)
+		f.SetCellValue("Sheet1", fmt.Sprintf("L%d", line), product.T_relation_sn)
 
 	}
-	f.SetCellStyle("Sheet1", "A3", fmt.Sprintf("K%d", line), Style3)
+	f.SetCellStyle("Sheet1", "A3", fmt.Sprintf("L%d", line), Style3)
 
 	// 保存文件
 	if err := f.SaveAs("ofile/" + filename + ".xlsx"); err != nil {
@@ -629,10 +656,11 @@ func (c *StockController) StockIn_Add() {
 	}
 
 	T_depot_id, _ := c.GetInt("T_depot_id")
+	T_type, _ := c.GetInt("T_type") // 1-入库 2-退库
 	T_date := c.GetString("T_date")
 	T_product := c.GetString("T_product")
 	T_remark := c.GetString("T_remark")
-	_, is := lib.DateStrToTime(T_date)
+	date, is := lib.DateStrToTime(T_date)
 	if !is {
 		c.Data["json"] = lib.JSONS{Code: 202, Msg: "日期格式错误!"}
 		c.ServeJSON()
@@ -643,6 +671,7 @@ func (c *StockController) StockIn_Add() {
 	var_ := Stock.StockIn{
 		T_number:   T_number,
 		T_depot_id: T_depot_id,
+		T_type:     T_type,
 		T_date:     T_date,
 		T_remark:   T_remark,
 		T_submit:   c.User.T_uuid,
@@ -697,6 +726,7 @@ func (c *StockController) StockIn_Add() {
 					T_iccid:           mqtt.Iccid,
 					T_imei:            mqtt.Imei,
 					T_State:           2,
+					CreateTime:        date,
 				}
 				_, err = DeviceDao.AddOrUpdate_Device(device, 2)
 				if err != nil {
@@ -963,7 +993,7 @@ func (c *StockController) StockIn_Edit() {
 						T_iccid:           mqtt.Iccid,
 						T_imei:            mqtt.Imei,
 						T_State:           2,
-						CreateTime:        stockIn.CreateTime,
+						CreateTime:        date,
 						UpdateTime:        stockIn.UpdateTime,
 					}
 					_, err = DeviceDao.AddOrUpdate_Device(device, 2)
@@ -1095,7 +1125,7 @@ func (c *StockController) StockIn_Edit() {
 						T_iccid:           mqtt.Iccid,
 						T_imei:            mqtt.Imei,
 						T_State:           2,
-						CreateTime:        stockIn.CreateTime,
+						CreateTime:        date,
 						UpdateTime:        stockIn.UpdateTime,
 					}
 					_, err = DeviceDao.AddOrUpdate_Device(device, 2)
@@ -1711,6 +1741,12 @@ func (c *StockController) StockOut_Add() {
 	T_signer_phone := c.GetString("T_signer_phone")
 	T_signer_date := c.GetString("T_signer_date")
 	T_courier_number := c.GetString("T_courier_number")
+	date, is := lib.DateStrToTime(T_date)
+	if !is {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "日期格式错误!"}
+		c.ServeJSON()
+		return
+	}
 
 	var_ := Stock.StockOut{
 		T_number:          T_number,
@@ -1790,6 +1826,7 @@ func (c *StockController) StockOut_Add() {
 					T_imei:            mqtt.Imei,
 					T_State:           1,
 					T_project:         T_project,
+					CreateTime:        date,
 				}
 				_, err = DeviceDao.AddOrUpdate_Device(device, 1)
 				if err != nil {
@@ -2095,7 +2132,7 @@ func (c *StockController) StockOut_Edit() {
 						T_iccid:           mqtt.Iccid,
 						T_imei:            mqtt.Imei,
 						T_State:           1,
-						CreateTime:        StockOut.CreateTime,
+						CreateTime:        date,
 						UpdateTime:        StockOut.UpdateTime,
 					}
 					_, err = DeviceDao.AddOrUpdate_Device(device, 1)
@@ -2227,7 +2264,7 @@ func (c *StockController) StockOut_Edit() {
 						T_iccid:           mqtt.Iccid,
 						T_imei:            mqtt.Imei,
 						T_State:           1,
-						CreateTime:        StockOut.CreateTime,
+						CreateTime:        date,
 						UpdateTime:        StockOut.UpdateTime,
 					}
 					_, err = DeviceDao.AddOrUpdate_Device(device, 1)
@@ -2733,87 +2770,6 @@ func Cron_StockMonth_Add() {
 
 }
 
-// 重写设备出入库记录
-func Cron_Device_Add() {
-
-	logs.Info("开始统计写入设备出入库数据")
-	o := orm.NewOrm()
-	o.Begin()
-	DeviceDao := Stock.NewDevice(o)
-	StockOutDao := Stock.NewStockOut(o)
-	StockInDao := Stock.NewStockIn(o)
-	StockOutProductDao := Stock.NewStockOutProduct(o)
-	StockInProductDao := Stock.NewStockInProduct(o)
-	// 添加入库设备信息
-	StockInList, _ := StockInDao.Read_StockIn_List(0, "", "", 0, 9999)
-	for _, stockIn := range StockInList {
-		productList := StockInProductDao.Read_StockInProduct_List_ByT_number(stockIn.T_number)
-		for _, product := range productList {
-			if len(product.T_relation_sn) == 0 {
-				continue
-			}
-			for _, sn := range lib.SplitString(product.T_relation_sn, ",") {
-				mqtt := Stock.Read_MqttUser(sn)
-				// 添加设备
-				device := Stock.Device{
-					T_contract_number: "",
-					T_out_number:      "",
-					T_product_id:      product.T_product_id,
-					T_in_number:       stockIn.T_number,
-					T_sn:              sn,
-					T_iccid:           mqtt.Iccid,
-					T_imei:            mqtt.Imei,
-					T_State:           2,
-					CreateTime:        product.CreateTime,
-					UpdateTime:        product.UpdateTime,
-				}
-				_, err := DeviceDao.AddOrUpdate_Device(device, 2)
-				if err != nil {
-					o.Rollback()
-					return
-				}
-
-			}
-		}
-
-	}
-	// 添加出库设备信息
-	StockOutList, _ := StockOutDao.Read_StockOut_List(0, "", "", "", 0, 9999)
-	for _, stockOut := range StockOutList {
-		productList := StockOutProductDao.Read_StockOutProduct_List(stockOut.T_number)
-		for _, product := range productList {
-			if len(product.T_relation_sn) == 0 {
-				continue
-			}
-			for _, sn := range lib.SplitString(product.T_relation_sn, ",") {
-				mqtt := Stock.Read_MqttUser(sn)
-				// 添加设备
-				device := Stock.Device{
-					T_contract_number: stockOut.T_contract_number,
-					T_product_id:      product.T_product_id,
-					T_out_number:      stockOut.T_number,
-					T_sn:              sn,
-					T_iccid:           mqtt.Iccid,
-					T_imei:            mqtt.Imei,
-					T_State:           1,
-					T_project:         stockOut.T_project,
-					CreateTime:        product.CreateTime,
-					UpdateTime:        product.UpdateTime,
-				}
-				_, err := DeviceDao.AddOrUpdate_Device(device, 1)
-				if err != nil {
-					o.Rollback()
-					return
-				}
-
-			}
-		}
-
-	}
-	o.Commit()
-
-}
-
 func generateMonthList(startMonth time.Time) []string {
 	var months []string
 	endMonth := time.Now().AddDate(0, 0, 0)

+ 30 - 67
controllers/Validation.go

@@ -32,69 +32,6 @@ func (c *ValidationController) Prepare() {
 	c.User = *Account.User_r
 }
 
-// AddValidation 查询设备是否存在在库存中,如果存在则修改设备状态为待使用,否则直接添加设备
-//
-//	func (c *ValidationController) AddValidation() {
-//		var ValidationList []validationtool.AddValidationTool
-//		err := json.Unmarshal(c.Ctx.Input.RequestBody, &ValidationList)
-//		if err != nil {
-//			c.Data["json"] = lib.JSONS{Code: 1201, Msg: "json 序列化失败!", Data: nil}
-//			c.ServeJSON()
-//			return
-//		}
-//		vali := validationtool.NewValidationTool(orm.NewOrm())
-//		for _, tool := range ValidationList {
-//			if len(tool.T_sn) <= 0 {
-//				c.Data["json"] = lib.JSONS{Code: 1201, Msg: "T_sn不能为空!", Data: nil}
-//				c.ServeJSON()
-//				return
-//			}
-//			r, err := vali.ReadValidationBytSn(tool.T_sn)
-//			if err != nil {
-//				if errors.Is(err, orm.ErrNoRows) {
-//					var validataiontool validationtool.ValidationTool
-//					atoi, _ := strconv.Atoi(tool.T_class)
-//					user := Stock.Read_MqttUser(tool.T_sn)
-//					validataiontool.T_iccid = user.Iccid
-//					validataiontool.T_imei = user.Imei
-//					validataiontool.T_uuid = c.User.T_uuid
-//					validataiontool.Validationnumber = tool.Validationnumber
-//					validataiontool.T_sn = tool.T_sn
-//					validataiontool.T_remark = tool.T_remark
-//					validataiontool.T_state = 2
-//					validataiontool.T_class = atoi
-//					validataiontool.UpdateTime = time.Now()
-//					_, err := vali.ADDValidationTool(validataiontool)
-//					if err != nil {
-//						c.Data["json"] = lib.JSONS{Code: 1201, Msg: "入库失败!", Data: nil}
-//						c.ServeJSON()
-//						return
-//					}
-//				}
-//			} else {
-//				//修改设备
-//				con := make(map[string]string)
-//				if len(tool.Validationnumber) != 0 {
-//					con["validationnumber"] = tool.Validationnumber
-//				}
-//				if r.T_state != 2 {
-//					con["t_state"] = "2" // 待使用
-//				}
-//				con["t_remark"] = tool.T_remark
-//				con["t_project"] = ""
-//				con["lend_user"] = ""
-//				err = vali.UpdateValidationTool(r.T_sn, con)
-//				if err != nil {
-//					c.Data["json"] = lib.JSONS{Code: 1201, Msg: "入库失败!", Data: nil}
-//					c.ServeJSON()
-//					return
-//				}
-//			}
-//		}
-//		c.Data["json"] = lib.JSONS{Code: 200, Msg: "入库成功!", Data: nil}
-//		c.ServeJSON()
-//		return
-//	}
 func (c *ValidationController) AddValidation() {
 	var ValidationList []validationtool.AddValidationTool
 	err := json.Unmarshal(c.Ctx.Input.RequestBody, &ValidationList)
@@ -119,7 +56,6 @@ func (c *ValidationController) AddValidation() {
 		if err != nil {
 			if errors.Is(err, orm.ErrNoRows) {
 				var validataiontool validationtool.ValidationTool
-				atoi, _ := strconv.Atoi(tool.T_class)
 				user := Stock.Read_MqttUser(tool.T_sn)
 				validataiontool.T_iccid = user.Iccid
 				validataiontool.T_imei = user.Imei
@@ -128,7 +64,7 @@ func (c *ValidationController) AddValidation() {
 				validataiontool.T_sn = tool.T_sn
 				validataiontool.T_remark = tool.T_remark
 				validataiontool.T_state = 2
-				validataiontool.T_class = atoi
+				validataiontool.T_class = tool.T_class
 				validataiontool.UpdateTime = time.Now()
 				_, err := vali.ADDValidationTool(validataiontool)
 				if err != nil {
@@ -358,7 +294,7 @@ func (c *ValidationController) UpdateValidationToolBySn() {
 	c.Data["json"] = lib.JSONS{Code: 200, Msg: "成功!", Data: nil}
 	c.ServeJSON()
 }
-func (c *ValidationController) ImportExecl() {
+func (c *ValidationController) ImportExcel() {
 	// 获取上传的文件
 	vali := validationtool.NewValidationTool(orm.NewOrm())
 	f, _, err := c.GetFile("excelFile")
@@ -419,7 +355,7 @@ func (c *ValidationController) ImportExecl() {
 	c.Data["json"] = lib.JSONS{Code: 200, Msg: "成功!", Data: nil}
 	c.ServeJSON()
 }
-func (c *ValidationController) ExportValidationListExecl() {
+func (c *ValidationController) ExportValidationListExcel() {
 
 	// 分页参数 初始化
 	page, _ := c.GetInt("page")
@@ -495,3 +431,30 @@ func (c *ValidationController) ExportValidationListExecl() {
 	c.Ctx.Output.Header("Content-Transfer-Encoding", "binary")
 	c.Ctx.Output.Download(filePath, fileName)
 }
+func (c *ValidationController) Read_ValidationClass_List() {
+
+	// 分页参数 初始化
+	page, _ := c.GetInt("page")
+	if page < 1 {
+		page = 1
+	}
+	page_z, _ := c.GetInt("page_z")
+	if page_z < 1 {
+		page_z = conf.Page_size
+	}
+
+	// 查询
+	T_name := c.GetString("T_name")
+
+	R_List, R_cnt := validationtool.Read_ValidationToolClass_List(T_name, page, page_z)
+
+	var r_jsons lib.R_JSONS
+	r_jsons.Num = R_cnt
+	r_jsons.Data = R_List
+	r_jsons.Page = page
+	r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(page_z)))
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
+	c.ServeJSON()
+	return
+}

+ 1 - 0
main.go

@@ -11,6 +11,7 @@ import (
 	_ "ERP_storage/models/Contract"
 	_ "ERP_storage/models/Property"
 	_ "ERP_storage/models/Stock"
+	_ "ERP_storage/models/validationtool"
 	_ "ERP_storage/routers"
 	"fmt"
 	"github.com/beego/beego/v2/adapter/orm"

+ 28 - 25
models/Basic/Product.go

@@ -6,31 +6,32 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	"github.com/astaxie/beego/cache"
 	_ "github.com/astaxie/beego/cache/redis"
 	"github.com/beego/beego/v2/adapter/orm"
 	orm2 "github.com/beego/beego/v2/client/orm"
 	_ "github.com/go-sql-driver/mysql"
+	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	"strconv"
 	"time"
 )
 
 // 仓库
 type Product struct {
-	Id            int       `orm:"column(ID);size(11);auto;pk"`
-	T_name        string    `orm:"size(256);null"`                                        // 名称
-	T_img         string    `orm:"size(256);null"`                                        // 图片
-	T_class       int       `orm:"size(20);default(0)"`                                   // 产品分类 T_class=0 冷链验证
-	T_model       string    `orm:"size(20);default(0)"`                                   // 产品型号
-	T_spec        string    `orm:"size(20);default(0)"`                                   // 产品规格
-	T_relation_sn int       `orm:"size(2);default(0)"`                                    // 关联sn 0-否 1-是
-	T_State       int       `orm:"size(2);default(1)"`                                    // 0 删除(伪删除)   1 正常
-	T_remark      string    `orm:"type(text);null"`                                       // 备注
-	T_price       float32   `orm:"digits(12);decimals(2)"`                                // 单价
-	T_sort        int       `orm:"size(20);default(0)"`                                         // 排序
-	CreateTime    time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
-	UpdateTime    time.Time `orm:"column(update_time);type(timestamp);null;auto_now"`     //auto_now 每次 model 保存时都会对时间自动更新
+	Id              int       `orm:"column(ID);size(11);auto;pk"`
+	T_name          string    `orm:"size(256);null"`                                        // 名称
+	T_img           string    `orm:"size(256);null"`                                        // 图片
+	T_class         int       `orm:"size(20);default(0)"`                                   // 产品分类 T_class=0 冷链验证
+	T_model         string    `orm:"size(20);default(0)"`                                   // 产品型号
+	T_spec          string    `orm:"size(20);default(0)"`                                   // 产品规格
+	T_relation_sn   int       `orm:"size(2);default(0)"`                                    // 关联sn 0-否 1-是
+	T_State         int       `orm:"size(2);default(1)"`                                    // 0 删除(伪删除)   1 正常
+	T_remark        string    `orm:"type(text);null"`                                       // 备注
+	T_price         float32   `orm:"digits(12);decimals(2)"`                                // 单价
+	T_sort          int       `orm:"size(20);default(0)"`                                   // 排序
+	T_early_warning int       `orm:"size(20);default(100)"`                                 // 预警数量
+	CreateTime      time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
+	UpdateTime      time.Time `orm:"column(update_time);type(timestamp);null;auto_now"`     //auto_now 每次 model 保存时都会对时间自动更新
 }
 
 func (t *Product) TableName() string {
@@ -97,17 +98,18 @@ func Redis_Product_DelK(Id int) (err error) {
 }
 
 type Product_R struct {
-	Id            int
-	T_name        string  // 名称
-	T_class       int     // 产品分类
-	T_class_name  string  // 产品分类名称
-	T_model       string  // 产品型号
-	T_spec        string  // 产品规格
-	T_price       float32 // 单价
-	T_relation_sn int     // 关联sn 0-否 1-是
-	T_img         string  // 图片
-	T_remark      string  // 备注
-	T_sort        int     // 排序
+	Id              int
+	T_name          string  // 名称
+	T_class         int     // 产品分类
+	T_class_name    string  // 产品分类名称
+	T_model         string  // 产品型号
+	T_spec          string  // 产品规格
+	T_price         float32 // 单价
+	T_relation_sn   int     // 关联sn 0-否 1-是
+	T_img           string  // 图片
+	T_remark        string  // 备注
+	T_sort          int     // 排序
+	T_early_warning int     // 预警
 }
 
 func ProductToProduct_R(t Product) (r Product_R) {
@@ -123,6 +125,7 @@ func ProductToProduct_R(t Product) (r Product_R) {
 	r.T_img = t.T_img
 	r.T_remark = t.T_remark
 	r.T_sort = t.T_sort
+	r.T_early_warning = t.T_early_warning
 	return r
 }
 

+ 212 - 0
models/IOTNetworkCard/IOTNetworkCard.go

@@ -0,0 +1,212 @@
+package IOTNetworkCard
+
+import (
+	"encoding/json"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	"gogs.baozhida.cn/zoie/ERP_libs/lib"
+	"time"
+
+	"ERP_storage/logs"
+	_ "github.com/astaxie/beego/cache/redis"
+	"github.com/beego/beego/v2/adapter/orm"
+	_ "github.com/go-sql-driver/mysql"
+)
+
+const (
+	Delete                  int = iota
+	IOTNetworkCardNewCardIn     // 新卡入库
+	IOTNetworkCardReturnIn      // 退还入库
+	IOTNetworkCardOut           // 已出库
+	IOTNetworkCardDamage        // 损坏退还
+	IOTNetworkCardWaitAnnul     // 待注销
+	IOTNetworkCardAnnul         // 已注销
+
+)
+
+var (
+	IOTNetworkCardStateMap = map[int]string{
+		IOTNetworkCardNewCardIn: "新卡入库",
+		IOTNetworkCardReturnIn:  "退还入库",
+		IOTNetworkCardOut:       "已出库",
+		IOTNetworkCardDamage:    "损坏退还",
+		IOTNetworkCardWaitAnnul: "待注销",
+		IOTNetworkCardAnnul:     "已注销",
+	}
+)
+
+// 物联网卡
+type IOTNetworkCard struct {
+	Id            int       `orm:"column(ID);size(11);auto;pk"`
+	T_in_date     string    `orm:"size(256);null"`                                        // 入库日期
+	T_out_date    string    `orm:"size(256);null"`                                        // 出库日期
+	T_meal_type   string    `orm:"size(256);null"`                                        // 套餐类型
+	T_meal        string    `orm:"size(256);null"`                                        // 套餐类型
+	T_expire      string    `orm:"size(256);null"`                                        // 到期&欠费
+	T_iccid       string    `orm:"size(256);null"`                                        // 串码
+	T_MSISDN      string    `orm:"size(256);null"`                                        // MSISDN
+	T_out_project string    `orm:"size(256);null"`                                        // 出库项目
+	T_record      string    `orm:"type(text);null"`                                       // 出入库记录
+	T_receive     string    `orm:"size(256);null"`                                        // 领取人
+	T_State       int       `orm:"size(2);default(1)"`                                    // 0 删除(伪删除)  1-新卡入库 2-退还入库 3-已出库 4-损坏退还 5-待注销 6-已注销
+	CreateTime    time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
+	UpdateTime    time.Time `orm:"column(update_time);type(timestamp);null;auto_now"`     //auto_now 每次 model 保存时都会对时间自动更新
+}
+
+type IOTNetworkCardRecord struct {
+	T_data       string //日期
+	T_State      int
+	T_State_name string
+	T_remark     string
+}
+
+func (t *IOTNetworkCard) TableName() string {
+	return "iot_network_card" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+type IOTNetworkCardDaoImpl struct {
+	orm orm.Ormer
+}
+
+func NewIOTNetworkCard(orm orm.Ormer) *IOTNetworkCardDaoImpl {
+	return &IOTNetworkCardDaoImpl{orm: orm}
+}
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(IOTNetworkCard))
+}
+
+type IOTNetworkCard_R struct {
+	Id            int
+	T_in_date     string                 // 入库日期
+	T_out_date    string                 // 出库日期
+	T_meal_type   string                 // 套餐类型
+	T_expire      string                 // 到期&欠费
+	T_iccid       string                 // 串码
+	T_MSISDN      string                 // MSISDN
+	T_out_project string                 // 出库项目
+	T_record      []IOTNetworkCardRecord // 出入库记录
+	T_State       int
+	T_State_name  string
+}
+
+func IOTNetworkCardToIOTNetworkCard_R(t IOTNetworkCard) (r IOTNetworkCard_R) {
+	r.Id = t.Id
+	r.T_in_date = t.T_in_date
+	r.T_out_date = t.T_out_date
+	r.T_meal_type = t.T_meal_type
+	r.T_expire = t.T_expire
+	r.T_iccid = t.T_iccid
+	r.T_MSISDN = t.T_MSISDN
+	r.T_out_project = t.T_out_project
+	var list []IOTNetworkCardRecord
+	if len(t.T_record) > 0 {
+		err := json.Unmarshal([]byte(t.T_record), &list)
+		if err != nil {
+			logs.Error("JSON 反序列化失败:", err)
+		}
+	}
+	for i := 0; i < len(list); i++ {
+		list[i].T_State_name = IOTNetworkCardStateMap[list[i].T_State]
+	}
+	r.T_record = list
+	r.T_State = t.T_State
+	r.T_State_name = IOTNetworkCardStateMap[t.T_State]
+	return r
+}
+
+// 添加
+func (dao *IOTNetworkCardDaoImpl) Add_IOTNetworkCard(r IOTNetworkCard) (id int64, err error) {
+	id, err = dao.orm.Insert(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+	return id, err
+}
+
+// 获取 ById
+func Read_IOTNetworkCard_ByT_MSISDN(T_MSISDN string) (r IOTNetworkCard, err error) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(IOTNetworkCard))
+
+	err = qs.Filter("T_MSISDN", T_MSISDN).Filter("T_State__gt", 0).One(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+	return
+}
+
+func Read_IOTNetworkCard_ById(Id int) (r IOTNetworkCard, err error) {
+	o := orm.NewOrm()
+	qs := o.QueryTable(new(IOTNetworkCard))
+	err = qs.Filter("Id", Id).One(&r)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+	return
+}
+
+// 修改
+func (dao *IOTNetworkCardDaoImpl) Update_IOTNetworkCard(m IOTNetworkCard, cols ...string) error {
+	_, err := dao.orm.Update(&m, cols...)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return err
+	}
+	return nil
+}
+
+// 删除
+func (dao *IOTNetworkCardDaoImpl) Delete_IOTNetworkCard(v IOTNetworkCard) error {
+	v.T_State = 0
+	_, err := dao.orm.Update(&v, "T_State")
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+	}
+	return err
+}
+
+// 获取列表
+func (dao *IOTNetworkCardDaoImpl) Read_IOTNetworkCard_List(T_name string, T_state, page, page_z int) (r_ []IOTNetworkCard_R, cnt int64) {
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	qs := o.QueryTable(new(IOTNetworkCard))
+	var offset int64
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+
+	// 过滤
+	cond := orm.NewCondition()
+	cond1 := cond.And("T_State__gt", 0)
+	if T_state > 0 {
+		cond1 = cond1.And("T_State", T_state)
+	}
+
+	if len(T_name) > 0 {
+		cond1 = cond1.AndCond(cond.Or("T_iccid__icontains", T_name).Or("T_MSISDN__icontains", T_name))
+	}
+
+	// 查询
+	var r []IOTNetworkCard
+	_, err := qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&r)
+
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	cnt, err = qs.SetCond((*orm2.Condition)(cond1)).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	for _, v := range r {
+		r_ = append(r_, IOTNetworkCardToIOTNetworkCard_R(v))
+	}
+
+	return r_, cnt
+}

+ 1 - 1
models/Percentage/Percentage.go

@@ -7,8 +7,8 @@ import (
 	"ERP_storage/models/Contract"
 	"encoding/json"
 	"fmt"
-	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	orm2 "github.com/beego/beego/v2/client/orm"
+	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	"strings"
 	"time"
 

+ 2 - 2
models/Property/IotCard.go

@@ -1,8 +1,8 @@
 package Property
 
 import (
-	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	orm2 "github.com/beego/beego/v2/client/orm"
+	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	"time"
 
 	"ERP_storage/logs"
@@ -11,7 +11,7 @@ import (
 	_ "github.com/go-sql-driver/mysql"
 )
 
-// 仓库
+// 物联网卡
 type IotCard struct {
 	Id         int       `orm:"column(ID);size(11);auto;pk"`
 	T_iccid    string    `orm:"size(256);null"`                                        // 编号

+ 55 - 54
models/Stock/Device.go

@@ -116,61 +116,62 @@ func (dao *DeviceDaoImpl) AddOrUpdate_Device(r Device, T_type int) (id int64, er
 	return
 
 }
-func (dao *DeviceDaoImpl) AddOrUpdate_Device1(r Device, T_type int) (id int64, err error) {
 
-	qs := dao.orm.QueryTable(new(Device))
-	var device Device
-
-	err = qs.Filter("T_sn", r.T_sn).One(&device)
-	if err != nil {
-		if err.Error() == orm.ErrNoRows.Error() {
-			r.T_remark = fmt.Sprintf("%s:%s(%s)|", time.Now().Format("2006-01-02"), "入库", r.T_in_number)
-			if len(r.T_project) > 0 {
-				r.T_project_log += r.T_project + "|"
-			}
-			id, err = dao.orm.Insert(&r)
-			if err != nil {
-				logs.Error(lib.FuncName(), err)
-			}
-			return
-		} else {
-			logs.Error(lib.FuncName(), err)
-			return
-		}
-	}
-
-	T_remark := ""
-	if T_type == 1 {
-		T_remark = fmt.Sprintf("%s:%s(%s)|", time.Now().Format("2006-01-02"), "出库", r.T_out_number)
-	}
-	if T_type == 2 {
-		T_remark = fmt.Sprintf("%s:%s(%s)|", time.Now().Format("2006-01-02"), "入库", device.T_in_number)
-	}
-
-	r.Id = device.Id
-	// T_State 1-出库 2-入库
-	r.T_State = T_type
-	// 出库时将入库编号服务给update结构体
-	if len(r.T_in_number) == 0 && len(device.T_in_number) > 0 {
-		r.T_in_number = device.T_in_number
-	}
-
-	r.T_remark = device.T_remark + T_remark
-	if len(r.T_project) > 0 {
-		r.T_project_log = device.T_project_log + r.T_project + "|"
-	} else {
-		r.T_project_log = device.T_project_log
-		r.T_project = device.T_project
-	}
-
-	_, err = dao.orm.Update(&r, "T_contract_number", "T_in_number", "T_out_number", "T_State", "T_remark", "T_project", "T_project_log")
-	if err != nil {
-		logs.Error(lib.FuncName(), err)
-		return
-	}
-
-	return
-}
+//func (dao *DeviceDaoImpl) AddOrUpdate_Device1(r Device, T_type int) (id int64, err error) {
+//
+//	qs := dao.orm.QueryTable(new(Device))
+//	var device Device
+//
+//	err = qs.Filter("T_sn", r.T_sn).One(&device)
+//	if err != nil {
+//		if err.Error() == orm.ErrNoRows.Error() {
+//			r.T_remark = fmt.Sprintf("%s:%s(%s)|", time.Now().Format("2006-01-02"), "入库", r.T_in_number)
+//			if len(r.T_project) > 0 {
+//				r.T_project_log += r.T_project + "|"
+//			}
+//			id, err = dao.orm.Insert(&r)
+//			if err != nil {
+//				logs.Error(lib.FuncName(), err)
+//			}
+//			return
+//		} else {
+//			logs.Error(lib.FuncName(), err)
+//			return
+//		}
+//	}
+//
+//	T_remark := ""
+//	if T_type == 1 {
+//		T_remark = fmt.Sprintf("%s:%s(%s)|", time.Now().Format("2006-01-02"), "出库", r.T_out_number)
+//	}
+//	if T_type == 2 {
+//		T_remark = fmt.Sprintf("%s:%s(%s)|", time.Now().Format("2006-01-02"), "入库", device.T_in_number)
+//	}
+//
+//	r.Id = device.Id
+//	// T_State 1-出库 2-入库
+//	r.T_State = T_type
+//	// 出库时将入库编号服务给update结构体
+//	if len(r.T_in_number) == 0 && len(device.T_in_number) > 0 {
+//		r.T_in_number = device.T_in_number
+//	}
+//
+//	r.T_remark = device.T_remark + T_remark
+//	if len(r.T_project) > 0 {
+//		r.T_project_log = device.T_project_log + r.T_project + "|"
+//	} else {
+//		r.T_project_log = device.T_project_log
+//		r.T_project = device.T_project
+//	}
+//
+//	_, err = dao.orm.Update(&r, "T_contract_number", "T_in_number", "T_out_number", "T_State", "T_remark", "T_project", "T_project_log")
+//	if err != nil {
+//		logs.Error(lib.FuncName(), err)
+//		return
+//	}
+//
+//	return
+//}
 
 func (dao *DeviceDaoImpl) Read_Device_ByT_sn(T_sn string) (r Device, err error) {
 	qs := dao.orm.QueryTable(new(Device))

+ 11 - 9
models/Stock/Stock.go

@@ -4,8 +4,8 @@ import (
 	"ERP_storage/models/Basic"
 	"errors"
 	"fmt"
-	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	orm2 "github.com/beego/beego/v2/client/orm"
+	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	"strconv"
 	"sync"
 	"time"
@@ -59,14 +59,15 @@ type Stock_R struct {
 	T_sort     int // 排序
 
 	// ---------产品信息-----------
-	T_product_id          int
-	T_product_name        string
-	T_product_class       int
-	T_product_class_name  string
-	T_product_model       string
-	T_product_spec        string
-	T_product_relation_sn int
-	T_product_img         string
+	T_product_id            int
+	T_product_name          string
+	T_product_class         int
+	T_product_class_name    string
+	T_product_model         string
+	T_product_spec          string
+	T_product_relation_sn   int
+	T_product_img           string
+	T_product_early_warning int
 }
 
 func StockToStock_R(t Stock) (r Stock_R) {
@@ -85,6 +86,7 @@ func StockToStock_R(t Stock) (r Stock_R) {
 	r.T_product_spec = product.T_spec
 	r.T_product_relation_sn = product.T_relation_sn
 	r.T_product_img = product.T_img
+	r.T_product_early_warning = product.T_early_warning
 	return r
 }
 

+ 3 - 1
models/Stock/StockInProduct.go

@@ -3,8 +3,8 @@ package Stock
 import (
 	"ERP_storage/models/Account"
 	"ERP_storage/models/Basic"
-	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	orm2 "github.com/beego/beego/v2/client/orm"
+	"gogs.baozhida.cn/zoie/ERP_libs/lib"
 	"strconv"
 	"time"
 
@@ -33,6 +33,7 @@ type StockInProductList struct {
 	T_number      string // StockIn - 入库单号
 	T_depot_id    int    // StockIn - 仓库id
 	T_depot_name  string // StockIn - 仓库名称
+	T_type        int    // StockIn - 入库类型
 	T_date        string // StockIn - 业务日期
 	T_submit      string // StockIn - 经办人
 	T_submit_name string // StockIn - 经办人名称
@@ -111,6 +112,7 @@ func StockInProductListToStockInProductList(t StockInProductList) (r StockInProd
 	r.Id = t.Id
 	r.T_number = t.T_number
 	r.T_depot_id = t.T_depot_id
+	r.T_type = t.T_type
 	r.T_depot_name = Basic.Read_Depot_Get(t.T_depot_id)
 	r.T_num = t.T_num
 	r.T_date = t.T_date

+ 1 - 0
models/init.go

@@ -21,6 +21,7 @@ func AutoMigrateDB() {
 			&ContractReview.ContractReview{},
 			&ContractReview.ContractReviewServiceItem{},
 			&validationtool.ValidationTool{},
+			&validationtool.ValidationToolClass{},
 		)
 	if err != nil {
 		log.Fatalf("migrate db fail: %v", err)

+ 1 - 1
models/validationtool/validation.go

@@ -54,7 +54,7 @@ type AddValidationTool struct {
 	T_sn             string `json:"T_sn"`
 	Validationnumber string `json:"Validationnumber"`
 	T_remark         string `json:"T_remark"`
-	T_class          string `json:"T_class"`
+	T_class          int    `json:"T_class"`
 }
 type LendValidationTool struct {
 	T_sn             string `json:"T_sn"`

+ 89 - 0
models/validationtool/validationClass.go

@@ -0,0 +1,89 @@
+package validationtool
+
+import (
+	"ERP_storage/logs"
+	_ "github.com/astaxie/beego/cache/redis"
+	"github.com/beego/beego/v2/adapter/orm"
+	orm2 "github.com/beego/beego/v2/client/orm"
+	_ "github.com/go-sql-driver/mysql"
+	"gogs.baozhida.cn/zoie/ERP_libs/lib"
+	"time"
+)
+
+// 验证设备分类
+type ValidationToolClass struct {
+	Id         int       `orm:"column(ID);size(11);auto;pk"`
+	T_name     string    `orm:"size(256);null"`                                        // 名称
+	T_State    int       `orm:"size(2);default(1)"`                                    // 0 删除(伪删除)   1 正常
+	CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
+	UpdateTime time.Time `orm:"column(update_time);type(timestamp);null;auto_now"`     //auto_now 每次 model 保存时都会对时间自动更新
+}
+
+func (t *ValidationToolClass) TableName() string {
+	return "validation_tool_class" // 数据库名称   // ************** 替换 FormulaList **************
+}
+
+func init() {
+	//注册模型
+	orm.RegisterModel(new(ValidationToolClass))
+}
+
+type ValidationClass_R struct {
+	Id      int
+	T_name  string // 名称
+	T_State int    // 0 删除(伪删除)   1 正常
+}
+
+func ValidationClassToValidationClass_R(t ValidationToolClass) (r ValidationClass_R) {
+	r.Id = t.Id
+	r.T_name = t.T_name
+	r.T_State = t.T_State
+	return r
+}
+
+// 获取列表
+func Read_ValidationToolClass_List(T_name string, page, page_z int) (r_ []ValidationClass_R, cnt int64) {
+	o := orm.NewOrm()
+	// 也可以直接使用 Model 结构体作为表名
+	qs := o.QueryTable(new(ValidationToolClass))
+	var offset int64
+	if page <= 1 {
+		offset = 0
+	} else {
+		offset = int64((page - 1) * page_z)
+	}
+
+	// 过滤
+	cond := orm.NewCondition()
+	cond = cond.And("T_State", 1)
+
+	if len(T_name) > 0 {
+		cond = cond.And("T_name__icontains", T_name)
+	}
+
+	// 查询
+	var r []ValidationToolClass
+	var err error
+	if page_z == 9999 {
+		_, err = qs.SetCond((*orm2.Condition)(cond)).OrderBy("-Id").All(&r)
+	} else {
+		_, err = qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond)).OrderBy("-Id").All(&r)
+	}
+
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	cnt, err = qs.SetCond((*orm2.Condition)(cond)).Count()
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return
+	}
+
+	for _, v := range r {
+		r_ = append(r_, ValidationClassToValidationClass_R(v))
+	}
+
+	return r_, cnt
+}

+ 19 - 0
routers/IOTNetworkCard.go

@@ -0,0 +1,19 @@
+package routers
+
+import (
+	"ERP_storage/controllers"
+	beego "github.com/beego/beego/v2/server/web"
+)
+
+func init() {
+
+	iotNetworkCard := beego.NewNamespace("/IOTNetworkCard",
+		beego.NSRouter("/List", &controllers.IOTNetworkCardController{}, "*:IOTNetworkCard_List"),     // 提成列表
+		beego.NSRouter("/Get", &controllers.IOTNetworkCardController{}, "*:IOTNetworkCard_Get"),       // 提成详情
+		beego.NSRouter("/Add", &controllers.IOTNetworkCardController{}, "*:IOTNetworkCard_Add"),       // 添加提成
+		beego.NSRouter("/Edit", &controllers.IOTNetworkCardController{}, "*:IOTNetworkCard_Edit"),     // 编辑提成
+		beego.NSRouter("/Del", &controllers.IOTNetworkCardController{}, "*:IOTNetworkCard_Del"),       // 删除提成
+		beego.NSRouter("/Import", &controllers.IOTNetworkCardController{}, "*:IOTNetworkCard_Import"), // 删除提成
+	)
+	beego.AddNamespace(iotNetworkCard)
+}

+ 7 - 6
routers/vaildationTool.go

@@ -7,15 +7,16 @@ import (
 
 func init() {
 
-	vaildationTool := beego.NewNamespace("/vaildationTool",
+	validationTool := beego.NewNamespace("/validationTool",
 		beego.NSRouter("/add", &controllers.ValidationController{}, "*:AddValidation"),                         // 添加验证工具
 		beego.NSRouter("/list", &controllers.ValidationController{}, "*:ValidationList"),                       // 获取验证工具列表
 		beego.NSRouter("/del", &controllers.ValidationController{}, "*:DeleteValidationTool"),                  // 删除验证工具
 		beego.NSRouter("/update", &controllers.ValidationController{}, "*:UpdateValidationTool"),               // 修改验证工具
-		beego.NSRouter("/readvaildation", &controllers.ValidationController{}, "*:GetValidationToolBySn"),      // 修改验证工具
-		beego.NSRouter("/updatevaildation", &controllers.ValidationController{}, "*:UpdateValidationToolBySn"), // 修改验证工具
-		beego.NSRouter("/ImportExecl", &controllers.ValidationController{}, "*:ImportExecl"),                   // 读取文件
-		beego.NSRouter("/exportExecl", &controllers.ValidationController{}, "*:ExportValidationListExecl"),     // 读取文件
+		beego.NSRouter("/readValidation", &controllers.ValidationController{}, "*:GetValidationToolBySn"),      // 修改验证工具
+		beego.NSRouter("/updateValidation", &controllers.ValidationController{}, "*:UpdateValidationToolBySn"), // 修改验证工具
+		beego.NSRouter("/ImportExcel", &controllers.ValidationController{}, "*:ImportExcel"),                   // 读取文件
+		beego.NSRouter("/exportExcel", &controllers.ValidationController{}, "*:ExportValidationListExcel"),     // 读取文件
+		beego.NSRouter("/class/list", &controllers.ValidationController{}, "*:Read_ValidationClass_List"),      // 读取文件
 	)
-	beego.AddNamespace(vaildationTool)
+	beego.AddNamespace(validationTool)
 }