Browse Source

ADD:保温箱管理、运单关联保温箱、导出运单

zoie 10 months ago
parent
commit
d7f8181b8a

+ 36 - 0
app/admin/controller/car.go

@@ -195,3 +195,39 @@ func (e CarController) Delete(c *gin.Context) {
 	}
 	e.OK(req.GetId(), "删除成功")
 }
+
+// BatchInsert 批量添加保温箱
+// @Summary 批量添加保温箱
+// @Description 批量添加保温箱
+// @Tags 保温箱
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.CoolerBoxInsertReq true "data"
+// @Success 200 {string} string	"{"code": 200, "message": "添加成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "添加失败"}"
+// @Router /api/CoolerBox [post]
+// @Security Bearer
+func (e CarController) BatchInsert(c *gin.Context) {
+	s := service.Car{}
+	req := dto.CarBatchInsertReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	p := actions.GetPermissionFromContext(c)
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+	req.SetDeptId(p.DeptId)
+	err = s.BatchInsert(&req)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(nil, "创建成功")
+}

+ 68 - 0
app/admin/controller/company.go

@@ -223,3 +223,71 @@ func (e CompanyController) Delete(c *gin.Context) {
 	}
 	e.OK(req.GetId(), "删除成功")
 }
+
+// GetMyCompany 通过id获取我的公司
+// @Summary 通过id获取我的公司
+// @Description 通过id获取我的公司
+// @Tags 公司
+// @Param id path string true "公司id"
+// @Success 200 {object} response.Response{data=model.SysDept} "{"code": 200, "data": [...]}"
+// @Router /api/company/{id} [get]
+// @Security Bearer
+func (e CompanyController) GetMyCompany(c *gin.Context) {
+	s := service.Company{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	//数据权限检查
+	p := actions.GetPermissionFromContext(c)
+	var object model.SysDept
+	//数据权限检查
+	err = s.Get(&dto.CompanyGetReq{Id: p.DeptId}, &object)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	e.OK(object, "查询成功")
+}
+
+
+// UpdateMyCompany 修改我的公司
+// @Summary 修改我的公司
+// @Description 修改我的公司
+// @Tags 公司
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.CompanyUpdateReq true "body"
+// @Success 200 {string} string	"{"code": 200, "message": "添加成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "添加失败"}"
+// @Router /api/company [put]
+// @Security Bearer
+func (e CompanyController) UpdateMyCompany(c *gin.Context) {
+	s := service.Company{}
+	req := dto.MyCompanyUpdateReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	req.Id = user.GetDeptId(c)
+	req.SetUpdateBy(user.GetUserId(c))
+	err = s.UpdateMyCompany(&req)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(req.GetId(), "更新成功")
+}

+ 231 - 0
app/admin/controller/cooler_box.go

@@ -0,0 +1,231 @@
+package controller
+
+import (
+	"cold-logistics/app/admin/model"
+	"cold-logistics/app/admin/service"
+	"cold-logistics/app/admin/service/dto"
+	"cold-logistics/common/actions"
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+	"gogs.baozhida.cn/zoie/OAuth-core/api"
+	"gogs.baozhida.cn/zoie/OAuth-core/pkg/jwtauth/user"
+	_ "gogs.baozhida.cn/zoie/OAuth-core/pkg/response"
+)
+
+type CoolerBoxController struct {
+	api.Api
+}
+
+// GetPage 获取保温箱列表
+// @Summary 获取保温箱列表
+// @Description 获取保温箱列表
+// @Tags 保温箱
+// @Param name query string false "保温箱名称"
+// @Param pageSize query int false "页条数"
+// @Param page query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]model.CoolerBox}} "{"code": 200, "data": [...]}"
+// @Router /api/CoolerBox [get]
+// @Security Bearer
+func (e CoolerBoxController) GetPage(c *gin.Context) {
+	s := service.CoolerBox{}
+	req := dto.CoolerBoxGetPageReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.Query).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	//数据权限检查
+	p := actions.GetPermissionFromContext(c)
+
+	list := make([]model.CoolerBox, 0)
+	var count int64
+
+	err = s.GetPage(&req, &list, &count, p)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}
+
+// Get 通过id获取保温箱
+// @Summary 通过id获取保温箱
+// @Description 通过id获取保温箱
+// @Tags 保温箱
+// @Param id path string true "保温箱id"
+// @Success 200 {object} response.Response{data=model.CoolerBox} "{"code": 200, "data": [...]}"
+// @Router /api/CoolerBox/{id} [get]
+// @Security Bearer
+func (e CoolerBoxController) Get(c *gin.Context) {
+	s := service.CoolerBox{}
+	req := dto.CoolerBoxGetReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var object model.CoolerBox
+	p := actions.GetPermissionFromContext(c)
+
+	//数据权限检查
+	err = s.Get(&req, &object, p)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	e.OK(object, "查询成功")
+}
+
+// Insert 添加保温箱
+// @Summary 添加保温箱
+// @Description 添加保温箱
+// @Tags 保温箱
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.CoolerBoxInsertReq true "data"
+// @Success 200 {string} string	"{"code": 200, "message": "添加成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "添加失败"}"
+// @Router /api/CoolerBox [post]
+// @Security Bearer
+func (e CoolerBoxController) Insert(c *gin.Context) {
+	s := service.CoolerBox{}
+	req := dto.CoolerBoxInsertReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	p := actions.GetPermissionFromContext(c)
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+	req.SetDeptId(p.DeptId)
+	err = s.Insert(&req)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(req.GetId(), "创建成功")
+}
+
+// Update 修改保温箱
+// @Summary 修改保温箱
+// @Description 修改保温箱
+// @Tags 保温箱
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.CoolerBoxUpdateReq true "body"
+// @Success 200 {string} string	"{"code": 200, "message": "添加成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "添加失败"}"
+// @Router /api/CoolerBox [put]
+// @Security Bearer
+func (e CoolerBoxController) Update(c *gin.Context) {
+	s := service.CoolerBox{}
+	req := dto.CoolerBoxUpdateReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	p := actions.GetPermissionFromContext(c)
+
+	req.SetUpdateBy(user.GetUserId(c))
+	err = s.Update(&req, p)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(req.GetId(), "更新成功")
+}
+
+// Delete 删除保温箱
+// @Summary 删除保温箱
+// @Description 删除保温箱
+// @Tags 保温箱
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.CoolerBoxDeleteReq true "body"
+// @Success 200 {string} string	"{"code": 200, "message": "删除成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "删除失败"}"
+// @Router /api/CoolerBox [delete]
+// @Security Bearer
+func (e CoolerBoxController) Delete(c *gin.Context) {
+	s := service.CoolerBox{}
+	req := dto.CoolerBoxDeleteReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON, nil).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	//数据权限检查
+	p := actions.GetPermissionFromContext(c)
+	err = s.Remove(&req, p)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
+
+// BatchInsert 批量添加保温箱
+// @Summary 批量添加保温箱
+// @Description 批量添加保温箱
+// @Tags 保温箱
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.CoolerBoxInsertReq true "data"
+// @Success 200 {string} string	"{"code": 200, "message": "添加成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "添加失败"}"
+// @Router /api/CoolerBox [post]
+// @Security Bearer
+func (e CoolerBoxController) BatchInsert(c *gin.Context) {
+	s := service.CoolerBox{}
+	req := dto.CoolerBoxBatchInsertReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	p := actions.GetPermissionFromContext(c)
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+	req.SetDeptId(p.DeptId)
+	err = s.BatchInsert(&req)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(nil, "创建成功")
+}

+ 1 - 1
app/admin/controller/customer.go

@@ -418,7 +418,7 @@ func (e Customer) VerifyCode(c *gin.Context) {
 	code := pkg.GenerateRandomFigureKey6()
 
 	ss := sms.NewSMS(conf.ExtConfig.SubMail.Appid, conf.ExtConfig.SubMail.Signature)
-	content := fmt.Sprintf("【气瓶追溯管理系统】您的短信验证码:%s,请在10分钟内输入", code)
+	content := fmt.Sprintf("【冷链运输平台】您的短信验证码:%s,请在10分钟内输入", code)
 	res, err := ss.Send(req.Phone, content)
 	if err != nil || res.Status != sms.SUCCESS {
 		e.Logger.Error("发送短信验证码出现异常", zap.Any("res", res), zap.Error(err))

+ 106 - 0
app/admin/controller/device.go

@@ -1,9 +1,12 @@
 package controller
 
 import (
+	"cold-logistics/app/admin/model"
 	"cold-logistics/app/admin/service"
 	"cold-logistics/app/admin/service/dto"
 	"cold-logistics/common/actions"
+	cdto "cold-logistics/common/dto"
+	"cold-logistics/common/nats/nats_server"
 	"github.com/gin-gonic/gin"
 	"github.com/gin-gonic/gin/binding"
 	"gogs.baozhida.cn/zoie/OAuth-core/api"
@@ -72,3 +75,106 @@ func (e DeviceController) GetData(c *gin.Context) {
 	dataList, count, _ := s.GetData(req, p)
 	e.PageOK(dataList, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
 }
+
+// GetDevicePage 获取未绑定的设备列表
+// @Summary 获取保温箱列表
+// @Description 获取保温箱列表
+// @Tags 保温箱
+// @Param name query string false "保温箱名称"
+// @Param pageSize query int false "页条数"
+// @Param page query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]model.CoolerBox}} "{"code": 200, "data": [...]}"
+// @Router /api/CoolerBox [get]
+// @Security Bearer
+func (e DeviceController) GetDevicePage(c *gin.Context) {
+	coolerBoxSvc := service.CoolerBox{}
+	warehouseSvc := service.Warehouse{}
+	carSvc := service.Car{}
+	req := dto.DeviceGetPageReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&coolerBoxSvc.Service).
+		MakeService(&warehouseSvc.Service).
+		MakeService(&carSvc.Service).
+		Bind(&req, binding.Query).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	list := make([]nats_server.Device_R, 0)
+	p := actions.GetPermissionFromContext(c)
+
+	var coolerBoxCount int64
+	coolerBoxList := make([]model.CoolerBox, 0)
+	err = coolerBoxSvc.GetPage(&dto.CoolerBoxGetPageReq{Pagination: cdto.Pagination{PageSize: 9999}}, &coolerBoxList, &coolerBoxCount, p)
+
+	var warehouseCount int64
+	warehouseList := make([]model.Warehouse, 0)
+	err = warehouseSvc.GetPage(&dto.WarehouseGetPageReq{Pagination: cdto.Pagination{PageSize: 9999}}, &warehouseList, &warehouseCount, p)
+
+	var carCount int64
+	carList := make([]model.Car, 0)
+	err = carSvc.GetPage(&dto.CarGetPageReq{Pagination: cdto.Pagination{PageSize: 9999}}, &carList, &carCount, p)
+
+	var count int64
+	company, err := model.GetCompanyById(p.DeptId)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	list, count, err = nats_server.Cold_ReadDevice_List(req.Name, company.ColdKey, req.GetPageIndex(), 9999)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	var bindMap = make(map[string]struct{})
+	for _, v := range coolerBoxList {
+		bindMap[v.Sn] = struct{}{}
+	}
+	for _, v := range warehouseList {
+		bindMap[v.Sn] = struct{}{}
+	}
+	for _, v := range carList {
+		bindMap[v.Sn] = struct{}{}
+	}
+	// Fixme 测试完成之后删除
+	//for i := 0; i < 20; i++ {
+	//	list = append(list, nats_server.Device_R{
+	//		T_devName: fmt.Sprintf("保温箱%03d", i),
+	//		T_sn:      fmt.Sprintf("2024114956064%03d", i),
+	//	})
+	//}
+
+	list2 := make([]nats_server.Device_R, 0)
+	for i := 0; i < len(list); i++ {
+		if _, ok := bindMap[list[i].T_sn]; ok {
+			count--
+			continue
+		}
+		list2 = append(list2, list[i])
+	}
+
+	//if len(list2) == 0 {
+	//	e.PageOK(list2, len(list2), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+	//}
+
+	// 计算总页数
+	totalPages := (len(list2) + req.GetPageSize() - 1) / req.GetPageSize()
+
+	// 如果n超出范围,返回错误
+	if req.GetPageIndex() > totalPages {
+		req.Page = totalPages
+	}
+	// 计算当前页的数据
+	start := (req.GetPageIndex() - 1) * req.GetPageSize()
+	end := start + req.GetPageSize()
+	if end > len(list2) {
+		end = len(list2)
+	}
+	currentPage := list2[start:end]
+
+	e.PageOK(currentPage, len(list2), req.GetPageIndex(), req.GetPageSize(), "查询成功")
+}

+ 36 - 2
app/admin/controller/warehouse.go

@@ -173,12 +173,10 @@ func (e WarehouseController) Update(c *gin.Context) {
 func (e WarehouseController) Delete(c *gin.Context) {
 	s := service.Warehouse{}
 	req := dto.WarehouseDeleteReq{}
-	userSvc := service.SysUser{}
 	err := e.MakeContext(c).
 		MakeOrm().
 		Bind(&req, binding.JSON, nil).
 		MakeService(&s.Service).
-		MakeService(&userSvc.Service).
 		Errors
 	if err != nil {
 		e.Logger.Error(err)
@@ -195,3 +193,39 @@ func (e WarehouseController) Delete(c *gin.Context) {
 	}
 	e.OK(req.GetId(), "删除成功")
 }
+
+// BatchInsert 批量添加保温箱
+// @Summary 批量添加保温箱
+// @Description 批量添加保温箱
+// @Tags 保温箱
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.CoolerBoxInsertReq true "data"
+// @Success 200 {string} string	"{"code": 200, "message": "添加成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "添加失败"}"
+// @Router /api/CoolerBox [post]
+// @Security Bearer
+func (e WarehouseController) BatchInsert(c *gin.Context) {
+	s := service.Warehouse{}
+	req := dto.WarehouseBatchInsertReq{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		Bind(&req, binding.JSON).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	p := actions.GetPermissionFromContext(c)
+	// 设置创建人
+	req.SetCreateBy(user.GetUserId(c))
+	req.SetDeptId(p.DeptId)
+	err = s.BatchInsert(&req)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(nil, "创建成功")
+}

File diff suppressed because it is too large
+ 807 - 119
app/admin/controller/waybill.go


+ 27 - 0
app/admin/model/cooler_box.go

@@ -0,0 +1,27 @@
+package model
+
+import model2 "cold-logistics/common/model"
+
+// 仓库
+type CoolerBox struct {
+	model2.Model
+	Name      string            `json:"name" gorm:"size:128"`                                 // 商品名称
+	Sn        string            `json:"sn" gorm:"size:128"`                                   // sn
+	Status    string            `json:"status" gorm:"size:4;not null;default:'2';comment:状态"` // 1-停用 2-正启用
+	HistorySn model2.StringList `json:"historySn"`                                            // 历史绑定的sn
+
+	model2.ControlBy
+	model2.ModelTime
+	model2.DeptBy
+}
+type CoolerBoxOmit struct {
+	Id   int    `json:"id,omitempty"`   // 主键编码
+	Name string `json:"name,omitempty"` // 商品名称
+}
+
+func (CoolerBox) TableName() string {
+	return "cooler_box"
+}
+func (CoolerBoxOmit) TableName() string {
+	return "cooler_box"
+}

+ 9 - 7
app/admin/model/sys_dept.go

@@ -13,13 +13,15 @@ var GetCompanyKeyErr = errors.New("获取公司秘钥失败")
 
 type SysDept struct {
 	model2.Model
-	ParentId int    `json:"parentId" gorm:""`                        // 上级部门
-	Path     string `json:"-" gorm:"size:255;" swaggerignore:"true"` // 路径
-	Name     string `json:"name"  gorm:"size:128;"`                  // 部门名称
-	Sort     int    `json:"-" gorm:"size:4;"`                        // 排序
-	Status   int    `json:"-" gorm:"size:4;"`                        // 状态 1-停用 2-正常
-	Remark   string `json:"remark"  gorm:"size:1024;"`               // 备注
-	ColdKey  string `json:"coldKey"  gorm:"size:128;"`               // 冷链3.0key
+	ParentId       int    `json:"parentId" gorm:""`                        // 上级部门
+	Path           string `json:"-" gorm:"size:255;" swaggerignore:"true"` // 路径
+	Name           string `json:"name"  gorm:"size:128;"`                  // 部门名称
+	Sort           int    `json:"-" gorm:"size:4;"`                        // 排序
+	Status         int    `json:"-" gorm:"size:4;"`                        // 状态 1-停用 2-正常
+	Remark         string `json:"remark"  gorm:"size:1024;"`               // 备注
+	ColdKey        string `json:"coldKey"  gorm:"size:128;"`               // 冷链3.0key
+	PrintIntercept bool   `json:"printIntercept"`                          // 温湿度打印拦截 默认关闭
+	Logo           string `json:"logo"  gorm:"size:128;"`                  // 公司logo
 	model2.ControlBy
 	model2.ModelTime
 }

+ 1 - 0
app/admin/model/sys_user.go

@@ -15,6 +15,7 @@ var (
 	SysUserTypeSys       = 1
 	SysUserTypeWarehouse = 2
 	SysUserTypeDriver    = 3
+	TypeCoolerBox        = 4
 )
 
 type SysUser struct {

+ 15 - 8
app/admin/model/waybill.go

@@ -3,14 +3,17 @@ package model
 import model2 "cold-logistics/common/model"
 
 var (
-	WaybillStatusWaitDelivery = 1 // 待派单
-	WaybillStatusWaitTruck    = 2 // 待装车
-	WaybillStatusWaitStorage  = 3 // 待入库
-	WaybillStatusTruck        = 4 // 已装车
-	WaybillStatusStorage      = 5 // 已入库
-	WaybillStatusTruckOut     = 6 // 已下车
-	WaybillStatusStorageOut   = 7 // 已出库
-	WaybillStatusReceipt      = 8 // 已签收
+	WaybillStatusWaitDelivery = 1  // 待派单
+	WaybillStatusWaitTruck    = 2  // 待装车
+	WaybillStatusWaitStorage  = 3  // 待入库
+	WaybillStatusTruck        = 4  // 已装车
+	WaybillStatusStorage      = 5  // 已入库
+	WaybillStatusTruckOut     = 6  // 已下车
+	WaybillStatusStorageOut   = 7  // 已出库
+	WaybillStatusReceipt      = 8  // 已签收
+	WaybillStatusWaitVanning  = 9  // 待装箱
+	WaybillStatusVanning      = 10 // 已装箱
+	WaybillStatusVanningOut   = 11 // 已出箱
 	WaybillStatusMap          = map[int]string{
 		WaybillStatusWaitDelivery: "待派单",
 		WaybillStatusWaitTruck:    "待装车",
@@ -20,6 +23,9 @@ var (
 		WaybillStatusReceipt:      "已签收",
 		WaybillStatusTruckOut:     "已下车",
 		WaybillStatusStorageOut:   "已出库",
+		WaybillStatusWaitVanning:  "待装箱",
+		WaybillStatusVanning:      "已装箱",
+		WaybillStatusVanningOut:   "已出箱",
 	}
 )
 
@@ -62,6 +68,7 @@ type Waybill struct {
 	ReceiptTime             model2.Time `json:"receiptTime"  gorm:"size:128"`             // 签收时间
 	WarehouseId             int         `json:"warehouseId"  gorm:"size:128"`             // 仓库id
 	CarId                   int         `json:"carId"  gorm:"size:128"`                   // 仓库id
+	CoolerBoxId             int         `json:"coolerBoxId"  gorm:"size:128"`             // 保温箱id
 	ReceiptImg              string      `json:"ReceiptImg"  gorm:"size:text"`             // 签收图片
 
 	Freight   float64     `json:"freight"  gorm:"size:9"` //运费

+ 2 - 0
app/admin/model/waybill_logistics.go

@@ -12,11 +12,13 @@ type WaybillLogistics struct {
 	WaybillNo   string        `json:"waybillNo"  gorm:"size:128"`   // 单号
 	Status      int           `json:"status"  gorm:"size:128"`      //订单状态:1待派单 2待装车 3待入库 4已装车 5已入库 6已下车 7已出库 8已签收
 	WarehouseId int           `json:"warehouseId"  gorm:"size:128"` // 仓库id
+	CoolerBoxId int           `json:"coolerBoxId"  gorm:"size:128"` // 保温箱id
 	CarId       int           `json:"carId"  gorm:"size:128"`       // 仓库id
 	UserId      int           `json:"userId"  gorm:"size:128"`      // 司机/仓管id
 	Lng         string        `json:"lng" gorm:"size:128;"`         // 经度
 	Lat         string        `json:"lat" gorm:"size:128;"`         // 纬度
 	Address     string        `json:"address" gorm:"size:128;"`     // 地址
+	CoolerBox   CoolerBoxOmit `json:"coolerBox" gorm:"->;foreignkey:CoolerBoxId;references:Id"`
 	Warehouse   WarehouseOmit `json:"warehouse" gorm:"->;foreignkey:WarehouseId;references:Id"`
 	Car         CarOmit       `json:"car" gorm:"->;foreignkey:CarId;references:Id"`
 	model2.ControlBy

+ 2 - 0
app/admin/model/waybill_task.go

@@ -11,12 +11,14 @@ type WaybillTask struct {
 	WaybillNo        string                       `json:"waybillNo"  gorm:"size:128"`   // 单号
 	WarehouseId      int                          `json:"warehouseId"  gorm:"size:128"` // 仓库id
 	CarId            int                          `json:"carId"  gorm:"size:128"`       // 仓库id
+	CoolerBoxId      int                          `json:"coolerBoxId"  gorm:"size:128"` // 保温箱id
 	UserId           int                          `json:"userId"  gorm:"size:128"`      // 司机/仓管id
 	Sn               string                       `json:"sn" gorm:"size:128"`           // sn
 	StartTime        model2.Time                  `json:"startTime"  gorm:"size:128"`   // 签收时间
 	EndTime          model2.Time                  `json:"endTime"  gorm:"size:128"`     // 签收时间
 	Warehouse        WarehouseOmit                `json:"warehouse"`
 	Car              CarOmit                      `json:"car"`
+	CoolerBox        CoolerBoxOmit                `json:"coolerBox"`
 	DeviceSensorList []nats_server.DeviceSensor_R `json:"deviceSensorList,omitempty"  gorm:"-"` // 传感器列表
 	DataList         []nats_server.DeviceData_R   `json:"dataList,omitempty"  gorm:"-"`         // 传感器列表
 	model2.ControlBy

+ 2 - 0
app/admin/router/company.go

@@ -23,6 +23,8 @@ func registerCompanyRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddle
 		r.POST("", cont.Insert)
 		r.PUT("", cont.Update)
 		r.DELETE("", cont.Delete)
+		r.GET("/my", cont.GetMyCompany)
+		r.PUT("/my", cont.UpdateMyCompany)
 
 	}
 

+ 27 - 0
app/admin/router/cooler_box.go

@@ -0,0 +1,27 @@
+package router
+
+import (
+	"cold-logistics/app/admin/controller"
+	"cold-logistics/common/actions"
+	"github.com/gin-gonic/gin"
+	jwt "gogs.baozhida.cn/zoie/OAuth-core/pkg/jwtauth"
+)
+
+func init() {
+	routerCheckRole = append(routerCheckRole, registerCoolerBoxRouter)
+}
+
+// 需认证的路由代码
+func registerCoolerBoxRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	cont := controller.CoolerBoxController{}
+	r := v1.Group("/cooler-box").Use(authMiddleware.MiddlewareFunc()).Use(actions.PermissionAction())
+	{
+		r.GET("", cont.GetPage)
+		r.GET("/:id", cont.Get)
+		r.POST("", cont.Insert)
+		r.POST("/import", cont.BatchInsert)
+		r.PUT("", cont.Update)
+		r.DELETE("", cont.Delete)
+	}
+
+}

+ 1 - 0
app/admin/router/device.go

@@ -19,5 +19,6 @@ func registerDeviceRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddlew
 	{
 		r.GET("/sensor-list", cont.GetSensorList)
 		r.GET("/data", cont.GetData)
+		r.GET("", cont.GetDevicePage)
 	}
 }

+ 9 - 7
app/admin/router/waybill.go

@@ -24,13 +24,14 @@ func registerWaybillRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddle
 		r.POST("/delivery", cont.Delivery)
 		r.PUT("", cont.Update)
 		r.DELETE("", cont.Delete)
-		r.POST("/warehouse-in", cont.WarehouseIn)   // 入库
-		r.POST("/warehouse-out", cont.WarehouseOut) // 出库
-		r.POST("/car-in", cont.CarIn)               // 装车
-		r.POST("/car-out", cont.CarOut)             // 下车
-		r.POST("/receipt", cont.Receipt)            // 签收
-		r.GET("/customer", cont.GetCustomerPage)    // 客户下单列表
-		r.POST("/customer", cont.CustomerInsert)    // 客户下单
+		r.POST("/warehouse-in", cont.WarehouseIn) // 入库
+		//r.POST("/warehouse-out", cont.WarehouseOut) // 出库
+		r.POST("/car-in", cont.CarIn) // 装车
+		//r.POST("/car-out", cont.CarOut)             // 下车
+		r.POST("/cooler-box-in", cont.CoolerBoxIn) // 装箱
+		r.POST("/receipt", cont.Receipt)           // 签收
+		r.GET("/customer", cont.GetCustomerPage)   // 客户下单列表
+		r.POST("/customer", cont.CustomerInsert)   // 客户下单
 
 		r.GET("/applet", cont.GetAppletPage)           // app 运单列表
 		r.GET("/applet-count", cont.GetAppletCount)    // app 运单-统计
@@ -40,5 +41,6 @@ func registerWaybillRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddle
 		r.GET("/export", cont.Export)                  // 运单管理-导出
 		r.GET("/customer/export", cont.CustomerExport) // 客户下单
 		r.GET("/temperature-pdf", cont.TemperaturePDF) // 导出温湿度pdf
+		r.GET("/waybill-pdf", cont.WaybillPDF)         // 导出运单pdf
 	}
 }

+ 67 - 15
app/admin/service/car.go

@@ -29,18 +29,27 @@ func CarIsBindUserScopes(isBind bool) func(db *gorm.DB) *gorm.DB {
 func (e *Car) GetPage(c *dto.CarGetPageReq, list *[]model.Car, count *int64, p *actions.DataPermission) error {
 	var err error
 	var data model.Car
+	if c.PageSize == 9999 {
+		err = e.Orm.Model(&data).
+			Scopes(
+				actions.Permission(data.TableName(), p),
+			).
+			Find(list).Limit(-1).Offset(-1).
+			Count(count).Error
+	} else {
+		err = e.Orm.Model(&data).
+			Scopes(
+				cDto.MakeCondition(c.GetNeedSearch()),
+				cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+				actions.Permission(data.TableName(), p),
+				CarIsBindUserScopes(c.IsBind),
+			).
+			Joins("User").
+			Where("car_no like ? or User.nick_name like ?", "%"+c.Name+"%", "%"+c.Name+"%").
+			Find(list).Limit(-1).Offset(-1).
+			Count(count).Error
+	}
 
-	err = e.Orm.Model(&data).
-		Scopes(
-			cDto.MakeCondition(c.GetNeedSearch()),
-			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
-			actions.Permission(data.TableName(), p),
-			CarIsBindUserScopes(c.IsBind),
-		).
-		Joins("User").
-		Where("car_no like ? or User.nick_name like ?", "%"+c.Name+"%", "%"+c.Name+"%").
-		Find(list).Limit(-1).Offset(-1).
-		Count(count).Error
 	if err != nil {
 		e.Log.Errorf("db error: %s", err)
 		return global.GetFailedErr
@@ -114,7 +123,7 @@ func (e *Car) Insert(c *dto.CarInsertReq) error {
 		return err
 	}
 
-	// 添加仓库
+	// 添加车辆
 	c.Generate(&data)
 	data.HistorySn = []string{data.Sn}
 	err = tx.Create(&data).Error
@@ -142,7 +151,7 @@ func (e *Car) Update(c *dto.CarUpdateReq, p *actions.DataPermission) error {
 	}()
 
 	var carModel = model.Car{}
-	// 查询仓库是否存在
+	// 查询车辆是否存在
 	err = e.Orm.Scopes(actions.Permission(carModel.TableName(), p)).
 		First(&carModel, c.GetId()).Error
 	if err != nil {
@@ -211,7 +220,7 @@ func (e *Car) Remove(c *dto.CarDeleteReq, p *actions.DataPermission) error {
 
 	var carModel model.Car
 
-	// 查询仓库是否存在
+	// 查询车辆是否存在
 	err = e.Orm.Scopes(actions.Permission(carModel.TableName(), p)).
 		First(&carModel, c.GetId()).Error
 	if err != nil {
@@ -243,7 +252,7 @@ func (e *Car) GetUserList(c *dto.SysUserGetPageReq, p *actions.DataPermission, l
 	var carModel model.Car
 	var userModel model.SysUserForBind
 	var userIds []int
-	// 查询仓库是否存在
+	// 查询车辆是否存在
 	err = e.Orm.Model(&carModel).Select("user_id").Scopes(actions.Permission(carModel.TableName(), p)).
 		Find(&userIds).Error
 	if err != nil {
@@ -279,3 +288,46 @@ func (e *Car) GetUserList(c *dto.SysUserGetPageReq, p *actions.DataPermission, l
 	*list = userList
 	return nil
 }
+
+func (e *Car) BatchInsert(c *dto.CarBatchInsertReq) error {
+	var err error
+
+	tx := e.Orm.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	for _, car := range c.List {
+		var data model.Car
+
+		var k int64
+		err = tx.Model(&data).Where("sn = ?", car.Sn).Count(&k).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return global.CreateFailedErr
+		}
+		if k > 0 {
+			continue
+		}
+
+		// 添加车辆
+		car.CreateBy = c.CreateBy
+		car.DeptId = c.DeptId
+		car.Status = c.Status
+		car.UserId = c.UserId
+		car.Generate(&data)
+		data.HistorySn = []string{data.Sn}
+		err = tx.Create(&data).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return global.CreateFailedErr
+		}
+	}
+
+	return nil
+
+}

+ 31 - 0
app/admin/service/company.go

@@ -171,6 +171,37 @@ func (e *Company) Update(c *dto.CompanyUpdateReq) error {
 	return nil
 }
 
+// Update 修改SysDept对象
+func (e *Company) UpdateMyCompany(c *dto.MyCompanyUpdateReq) error {
+	var err error
+	var deptModel = model.SysDept{}
+	tx := e.Orm.Debug().Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	err = tx.First(&deptModel, c.GetId()).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return global.UpdateNotFoundOrNoPermissionErr
+		}
+		return global.UpdateFailedErr
+	}
+
+	c.Generate(&deptModel)
+	db := tx.Save(&deptModel)
+	if err = db.Error; err != nil {
+		e.Log.Errorf("UpdateSysDept error: %s", err)
+		return err
+	}
+	return nil
+}
+
 // Remove 删除SysDept
 // 删除部门 同时删除其子部门、部门下的用户
 func (e *Company) Remove(d *dto.CompanyDeleteReq, p *actions.DataPermission) error {

+ 234 - 0
app/admin/service/cooler_box.go

@@ -0,0 +1,234 @@
+package service
+
+import (
+	"cold-logistics/app/admin/model"
+	"cold-logistics/app/admin/service/dto"
+	"cold-logistics/common/actions"
+	cDto "cold-logistics/common/dto"
+	"cold-logistics/common/global"
+	"errors"
+	"gogs.baozhida.cn/zoie/OAuth-core/service"
+	"gorm.io/gorm"
+)
+
+type CoolerBox struct {
+	service.Service
+}
+
+// GetPage 获取CoolerBox列表
+func (e *CoolerBox) GetPage(c *dto.CoolerBoxGetPageReq, list *[]model.CoolerBox, count *int64, p *actions.DataPermission) error {
+	var err error
+	var data model.CoolerBox
+
+	if c.PageSize == 9999 {
+		err = e.Orm.Model(&data).
+			Scopes(
+				actions.Permission(data.TableName(), p),
+			).
+			Find(list).Limit(-1).Offset(-1).
+			Count(count).Error
+	} else {
+		err = e.Orm.Model(&data).
+			Scopes(
+				cDto.MakeCondition(c.GetNeedSearch()),
+				cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+				actions.Permission(data.TableName(), p),
+			).
+			Find(list).Limit(-1).Offset(-1).
+			Count(count).Error
+	}
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return global.GetFailedErr
+	}
+	return nil
+}
+
+// Get 获取CoolerBox对象
+func (e *CoolerBox) Get(d *dto.CoolerBoxGetReq, CoolerBoxModel *model.CoolerBox, p *actions.DataPermission) error {
+	err := e.Orm.
+		Scopes(actions.Permission(CoolerBoxModel.TableName(), p)).
+		First(CoolerBoxModel, d.GetId()).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return global.GetNotFoundOrNoPermissionErr
+		}
+		return global.GetFailedErr
+	}
+
+	return nil
+}
+
+// Insert 创建CoolerBox对象
+func (e *CoolerBox) Insert(c *dto.CoolerBoxInsertReq) error {
+	var err error
+	var data model.CoolerBox
+
+	tx := e.Orm.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	var k int64
+	err = tx.Model(&data).Where("sn = ?", c.Sn).Count(&k).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return global.CreateFailedErr
+	}
+	if k > 0 {
+		err = errors.New("该Sn已绑定!")
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+
+	// 添加保温箱
+	c.Generate(&data)
+	data.HistorySn = []string{data.Sn}
+	err = tx.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return global.CreateFailedErr
+	}
+	c.Id = data.Id
+
+	return nil
+
+}
+func (e *CoolerBox) BatchInsert(c *dto.CoolerBoxBatchInsertReq) error {
+	var err error
+
+	tx := e.Orm.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	for _, coolerBox := range c.List {
+		var data model.CoolerBox
+
+		var k int64
+		err = tx.Model(&data).Where("sn = ?", coolerBox.Sn).Count(&k).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return global.CreateFailedErr
+		}
+		if k > 0 {
+			continue
+		}
+
+		// 添加保温箱
+		coolerBox.CreateBy = c.CreateBy
+		coolerBox.DeptId = c.DeptId
+		coolerBox.Status = c.Status
+		coolerBox.Generate(&data)
+		data.HistorySn = []string{data.Sn}
+		err = tx.Create(&data).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return global.CreateFailedErr
+		}
+	}
+
+	return nil
+
+}
+
+// Update 修改CoolerBox对象
+func (e *CoolerBox) Update(c *dto.CoolerBoxUpdateReq, p *actions.DataPermission) error {
+	var err error
+
+	tx := e.Orm.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	var CoolerBoxModel = model.CoolerBox{}
+	// 查询保温箱是否存在
+	err = e.Orm.Scopes(actions.Permission(CoolerBoxModel.TableName(), p)).
+		First(&CoolerBoxModel, c.GetId()).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return global.UpdateNotFoundOrNoPermissionErr
+		}
+		return global.UpdateFailedErr
+	}
+
+	if CoolerBoxModel.Sn != c.Sn {
+		var k int64
+		var data = model.CoolerBox{}
+		err = tx.Model(&data).Where("sn = ?", c.Sn).Count(&k).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return global.CreateFailedErr
+		}
+		if k > 0 {
+			err = errors.New("该Sn已绑定!")
+			e.Log.Errorf("db error: %s", err)
+			return err
+		}
+
+		CoolerBoxModel.HistorySn = append(CoolerBoxModel.HistorySn, c.Sn)
+	}
+
+	c.Generate(&CoolerBoxModel)
+	err = tx.Save(&CoolerBoxModel).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return global.UpdateFailedErr
+	}
+
+	c.Id = CoolerBoxModel.Id
+	return nil
+}
+
+// Remove 删除CoolerBox
+func (e *CoolerBox) Remove(c *dto.CoolerBoxDeleteReq, p *actions.DataPermission) error {
+	var err error
+
+	tx := e.Orm.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	var CoolerBoxModel model.CoolerBox
+
+	// 查询保温箱是否存在
+	err = e.Orm.Scopes(actions.Permission(CoolerBoxModel.TableName(), p)).
+		First(&CoolerBoxModel, c.GetId()).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return global.DeleteNotFoundOrNoPermissionErr
+		}
+		return global.DeleteFailedErr
+	}
+
+	db := tx.Delete(&CoolerBoxModel)
+
+	if err = db.Error; err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return global.DeleteFailedErr
+	}
+	if db.RowsAffected == 0 {
+		return global.DeleteNotFoundOrNoPermissionErr
+	}
+
+	return nil
+}

+ 8 - 0
app/admin/service/dto/car.go

@@ -100,3 +100,11 @@ type CarDeleteReq struct {
 func (s *CarDeleteReq) GetId() interface{} {
 	return s.Id
 }
+
+type CarBatchInsertReq struct {
+	List             []CarInsertReq
+	Status           string `json:"status"` // 1-停用 2-正启用
+	UserId           int    `json:"userId"` // 绑定的用户id
+	common.ControlBy `swaggerignore:"true"`
+	common.DeptBy    `swaggerignore:"true"`
+}

+ 21 - 0
app/admin/service/dto/company.go

@@ -77,6 +77,27 @@ func (s *CompanyUpdateReq) GetId() interface{} {
 	return s.Id
 }
 
+type MyCompanyUpdateReq struct {
+	Id             int    `json:"id" comment:"编码"`                 // 编码
+	Logo           string `json:"logo" example:"https://xxxx.jpg"` //名称
+	PrintIntercept bool   `json:"printIntercept"`                  // 备注
+	common.ControlBy `swaggerignore:"true"`
+}
+
+// Generate 结构体数据转化 从 SysDeptControl 至 SysDept 对应的模型
+func (s *MyCompanyUpdateReq) Generate(model *model.SysDept) {
+	if s.Id != 0 {
+		model.Id = s.Id
+	}
+	model.Logo = s.Logo
+	model.PrintIntercept = s.PrintIntercept
+}
+
+// GetId 获取数据对应的ID
+func (s *MyCompanyUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
 type CompanyGetReq struct {
 	Id int `uri:"id"`
 }

+ 109 - 0
app/admin/service/dto/cooler_box.go

@@ -0,0 +1,109 @@
+package dto
+
+import (
+	"cold-logistics/app/admin/model"
+	"cold-logistics/common/dto"
+	common "cold-logistics/common/model"
+)
+
+type CoolerBoxGetPageReq struct {
+	dto.Pagination `search:"-"`
+	Name           string `form:"name" search:"type:contains;column:name;table:cooler_box"` // 保温箱
+	Sn             string `form:"sn" search:"type:contains;column:sn;table:cooler_box"`     // sn
+	CoolerBoxOrder
+}
+
+type CoolerBoxOrder struct {
+	CreatedAtOrder string `search:"type:order;column:created_at;table:cooler_box" form:"createdAtOrder" default:"desc"`
+}
+
+func (m *CoolerBoxGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type CoolerBoxInsertReq struct {
+	Id               int    `json:"id" comment:"编码" swaggerignore:"true"` // 编码
+	Name             string `json:"name"`                                   // 保温箱名称
+	Sn               string `json:"sn"`                                     // sn
+	Status           string `json:"status"`                                 // 1-停用 2-正启用
+	common.ControlBy `swaggerignore:"true"`
+	common.DeptBy    `swaggerignore:"true"`
+}
+
+func (s *CoolerBoxInsertReq) Generate(model *model.CoolerBox) {
+	if s.Id != 0 {
+		model.Id = s.Id
+	}
+	model.Name = s.Name
+	model.Sn = s.Sn
+	model.Status = s.Status
+	if s.ControlBy.UpdateBy != 0 {
+		model.UpdateBy = s.UpdateBy
+	}
+	if s.ControlBy.CreateBy != 0 {
+		model.CreateBy = s.CreateBy
+	}
+	if s.DeptBy.DeptId != 0 {
+		model.DeptId = s.DeptId
+	}
+}
+
+func (s *CoolerBoxInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type CoolerBoxUpdateReq struct {
+	Id               int    `json:"id" comment:"编码"` // 编码
+	Name             string `json:"Name"`              // 保温箱名称
+	Sn               string `json:"sn"`                // sn
+	Status           string `json:"status"`            // 1-停用 2-正启用
+	common.ControlBy `swaggerignore:"true"`
+}
+
+func (s *CoolerBoxUpdateReq) Generate(model *model.CoolerBox) {
+	if s.Id != 0 {
+		model.Id = s.Id
+	}
+	model.Name = s.Name
+	model.Sn = s.Sn
+	model.Status = s.Status
+	if s.ControlBy.UpdateBy != 0 {
+		model.UpdateBy = s.UpdateBy
+	}
+	if s.ControlBy.CreateBy != 0 {
+		model.CreateBy = s.CreateBy
+	}
+}
+
+func (s *CoolerBoxUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+type CoolerBoxGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *CoolerBoxGetReq) GetId() interface{} {
+	return s.Id
+}
+
+type CoolerBoxDeleteReq struct {
+	Id               int `json:"id"`
+	common.ControlBy `swaggerignore:"true"`
+}
+
+func (s *CoolerBoxDeleteReq) GetId() interface{} {
+	return s.Id
+}
+
+type DeviceGetPageReq struct {
+	dto.Pagination `search:"-"`
+	Name           string `form:"name" search:"-"`
+}
+
+type CoolerBoxBatchInsertReq struct {
+	List             []CoolerBoxInsertReq
+	Status           string `json:"status"` // 1-停用 2-正启用
+	common.ControlBy `swaggerignore:"true"`
+	common.DeptBy    `swaggerignore:"true"`
+}

+ 8 - 0
app/admin/service/dto/warehouse.go

@@ -105,3 +105,11 @@ type WarehouseDeleteReq struct {
 func (s *WarehouseDeleteReq) GetId() interface{} {
 	return s.Id
 }
+
+type WarehouseBatchInsertReq struct {
+	List             []WarehouseInsertReq
+	Status           string `json:"status"` // 1-停用 2-正启用
+	UserId           int    `json:"userId"` // 绑定的用户id
+	common.ControlBy `swaggerignore:"true"`
+	common.DeptBy    `swaggerignore:"true"`
+}

+ 3 - 1
app/admin/service/dto/waybill.go

@@ -58,6 +58,7 @@ type WaybillInsertReq struct {
 	Remark                  string `json:"remark"`                               //运输备注
 	CustomerId              int    `json:"customerId"`                           //下单客户id
 	CustomerName            string `json:"customerName"`                         //下单客户名称
+	CoolerBoxId             string `json:"coolerBoxId"`                          //保温箱id
 	model2.ControlBy        `swaggerignore:"true"`
 	model2.DeptBy
 }
@@ -146,8 +147,9 @@ func (s *WaybillUpdateReq) GetId() interface{} {
 
 type WaybillDeliveryReq struct {
 	WaybillIds       []int `json:"waybillIds"`  // 运单id
-	Type             int   `json:"type"`        // 派单类型 3司机 2仓管
+	Type             int   `json:"type"`        // 派单类型 3司机 2仓管 4保温箱
 	PrintUserId      int   `json:"printUserId"` // 制单人
+	CoolerBoxId      int   `json:"coolerBoxId"` // 保温箱id
 	model2.ControlBy `swaggerignore:"true"`
 	model2.DeptBy    `swaggerignore:"true"`
 }

+ 65 - 11
app/admin/service/warehouse.go

@@ -29,17 +29,28 @@ func WarehouseIsBindUserScopes(isBind bool) func(db *gorm.DB) *gorm.DB {
 func (e *Warehouse) GetPage(c *dto.WarehouseGetPageReq, list *[]model.Warehouse, count *int64, p *actions.DataPermission) error {
 	var err error
 	var data model.Warehouse
-	err = e.Orm.Model(&data).
-		Scopes(
-			cDto.MakeCondition(c.GetNeedSearch()),
-			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
-			actions.Permission(data.TableName(), p),
-			WarehouseIsBindUserScopes(c.IsBind),
-		).
-		Joins("User").
-		Where("name like ? or User.nick_name like ?", "%"+c.Name+"%", "%"+c.Name+"%").
-		Find(list).Limit(-1).Offset(-1).
-		Count(count).Error
+
+	if c.PageSize == 9999 {
+		err = e.Orm.Model(&data).
+			Scopes(
+				actions.Permission(data.TableName(), p),
+			).
+			Find(list).Limit(-1).Offset(-1).
+			Count(count).Error
+	} else {
+		err = e.Orm.Model(&data).
+			Scopes(
+				cDto.MakeCondition(c.GetNeedSearch()),
+				cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+				actions.Permission(data.TableName(), p),
+				WarehouseIsBindUserScopes(c.IsBind),
+			).
+			Joins("User").
+			Where("name like ? or User.nick_name like ?", "%"+c.Name+"%", "%"+c.Name+"%").
+			Find(list).Limit(-1).Offset(-1).
+			Count(count).Error
+	}
+
 	if err != nil {
 		e.Log.Errorf("db error: %s", err)
 		return global.GetFailedErr
@@ -276,3 +287,46 @@ func (e *Warehouse) GetUserList(c *dto.SysUserGetPageReq, p *actions.DataPermiss
 	*list = userList
 	return nil
 }
+
+func (e *Warehouse) BatchInsert(c *dto.WarehouseBatchInsertReq) error {
+	var err error
+
+	tx := e.Orm.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	for _, warehouse := range c.List {
+		var data model.Warehouse
+
+		var k int64
+		err = tx.Model(&data).Where("sn = ?", warehouse.Sn).Count(&k).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return global.CreateFailedErr
+		}
+		if k > 0 {
+			continue
+		}
+
+		// 添加保温箱
+		warehouse.CreateBy = c.CreateBy
+		warehouse.DeptId = c.DeptId
+		warehouse.Status = c.Status
+		warehouse.UserId = c.UserId
+		warehouse.Generate(&data)
+		data.HistorySn = []string{data.Sn}
+		err = tx.Create(&data).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return global.CreateFailedErr
+		}
+	}
+
+	return nil
+
+}

+ 480 - 34
app/admin/service/waybill.go

@@ -295,6 +295,20 @@ func (e *Waybill) AppletInsert(c *dto.WaybillInsertReq, p *actions.DataPermissio
 			return errors.New("获取仓库信息失败")
 		}
 	}
+
+	var coolerBox = model.CoolerBox{}
+	if c.DeliveryCondition == "保温箱" {
+		status = model.WaybillStatusWaitVanning
+		// 查询仓库信息
+		err = tx.Scopes(actions.Permission(warehouse.TableName(), p)).
+			Where("id = ?", c.CoolerBoxId).
+			First(&coolerBox).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New("获取保温箱信息失败")
+		}
+	}
+
 	data.PrintUserId = p.UserId
 
 	var no string
@@ -329,6 +343,7 @@ func (e *Waybill) AppletInsert(c *dto.WaybillInsertReq, p *actions.DataPermissio
 		Status:      data.Status,
 		CarId:       car.Id,
 		WarehouseId: warehouse.Id,
+		CoolerBoxId: coolerBox.Id,
 		UserId:      p.UserId,
 		ControlBy: model2.ControlBy{
 			CreateBy: p.UserId,
@@ -393,6 +408,49 @@ func (e *Waybill) Delivery(c *dto.WaybillDeliveryReq, p *actions.DataPermission)
 			tx.Commit()
 		}
 	}()
+	var car = model.Car{}
+	if c.Type == model.SysUserTypeDriver {
+		// 查询车辆库信息
+		err = tx.Scopes(actions.Permission(car.TableName(), p)).
+			Where("user_id = ?", c.PrintUserId).
+			First(&car).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New("获取车辆信息失败")
+		}
+	}
+	var warehouse = model.Warehouse{}
+	if c.Type == model.SysUserTypeWarehouse {
+		// 查询仓库信息
+		err = tx.Scopes(actions.Permission(warehouse.TableName(), p)).
+			Where("user_id = ?", c.PrintUserId).
+			First(&warehouse).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New("获取仓库信息失败")
+		}
+	}
+
+	var coolerBox = model.CoolerBox{}
+	if c.Type == model.TypeCoolerBox {
+		// 查询保温箱信息
+		err = tx.Scopes(actions.Permission(coolerBox.TableName(), p)).
+			Where("id = ?", c.CoolerBoxId).
+			First(&coolerBox).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New("获取保温箱信息失败")
+		}
+		var user = model.SysUser{}
+		// 查询保温箱信息
+		err = tx.Scopes(actions.Permission(user.TableName(), p)).
+			Where("id = ?", c.PrintUserId).
+			First(&user).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New("获取保温箱配送人失败")
+		}
+	}
 
 	for _, id := range c.WaybillIds {
 
@@ -407,39 +465,29 @@ func (e *Waybill) Delivery(c *dto.WaybillDeliveryReq, p *actions.DataPermission)
 			}
 			return global.UpdateFailedErr
 		}
+
+		// 待派单 待装车 待入库 待装箱
 		if waybillModel.Status != model.WaybillStatusWaitDelivery &&
 			waybillModel.Status != model.WaybillStatusWaitTruck &&
-			waybillModel.Status != model.WaybillStatusWaitStorage {
+			waybillModel.Status != model.WaybillStatusWaitStorage &&
+			waybillModel.Status != model.WaybillStatusWaitVanning {
 			//err = errors.New(fmt.Sprintf("运单状态为%s,禁止操作!", model.WaybillStatusMap[waybillModel.Status]))
 			//return err
 			continue
 		}
 
-		var car = model.Car{}
 		if c.Type == model.SysUserTypeDriver {
 			waybillModel.Status = model.WaybillStatusWaitTruck
-			// 查询车辆库信息
-			err = tx.Scopes(actions.Permission(car.TableName(), p)).
-				Where("user_id = ?", c.PrintUserId).
-				First(&car).Error
-			if err != nil {
-				e.Log.Errorf("db error: %s", err)
-				return errors.New("获取车辆信息失败")
-			}
 		}
 
-		var warehouse = model.Warehouse{}
 		if c.Type == model.SysUserTypeWarehouse {
 			waybillModel.Status = model.WaybillStatusWaitStorage
-			// 查询仓库信息
-			err = tx.Scopes(actions.Permission(warehouse.TableName(), p)).
-				Where("user_id = ?", c.PrintUserId).
-				First(&warehouse).Error
-			if err != nil {
-				e.Log.Errorf("db error: %s", err)
-				return errors.New("获取仓库信息失败")
-			}
 		}
+
+		if c.Type == model.TypeCoolerBox {
+			waybillModel.Status = model.WaybillStatusWaitVanning
+		}
+
 		waybillModel.PrintUserId = c.PrintUserId
 		err = tx.Save(&waybillModel).Error
 		if err != nil {
@@ -453,6 +501,7 @@ func (e *Waybill) Delivery(c *dto.WaybillDeliveryReq, p *actions.DataPermission)
 			Status:      waybillModel.Status,
 			CarId:       car.Id,
 			WarehouseId: warehouse.Id,
+			CoolerBoxId: coolerBox.Id,
 			UserId:      c.PrintUserId,
 			ControlBy: model2.ControlBy{
 				CreateBy: p.UserId,
@@ -1071,7 +1120,8 @@ func (e *Waybill) CarOut(c *dto.WaybillInOutReq, p *actions.DataPermission) erro
 
 	return nil
 }
-func (e *Waybill) Receipt(c *dto.WaybillReceiptReq, p *actions.DataPermission) error {
+
+func (e *Waybill) CoolerBoxIn(c *dto.WaybillInOutReq, p *actions.DataPermission) error {
 	var err error
 
 	tx := e.Orm.Begin()
@@ -1082,17 +1132,119 @@ func (e *Waybill) Receipt(c *dto.WaybillReceiptReq, p *actions.DataPermission) e
 			tx.Commit()
 		}
 	}()
-	// 查询仓库信息
-	var car = model.Car{}
-	// 查询运单是否存在
-	err = tx.Scopes(actions.Permission(car.TableName(), p)).
-		Where("user_id = ?", p.UserId).
-		First(&car).Error
-	if err != nil {
-		e.Log.Errorf("db error: %s", err)
-		return errors.New("获取车辆信息失败")
+
+	for _, waybillNo := range c.WaybillNoList {
+		var waybillModel = model.Waybill{}
+		// 查询运单是否存在
+		err = tx.Scopes(actions.Permission(waybillModel.TableName(), p)).
+			Where("waybill_no = ?", waybillNo).
+			First(&waybillModel).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			if errors.Is(err, gorm.ErrRecordNotFound) {
+				return errors.New(fmt.Sprintf("运单号%s不存在", waybillNo))
+			}
+			return errors.New(fmt.Sprintf("运单号%s查询失败", waybillNo))
+		}
+		if waybillModel.Status != model.WaybillStatusWaitVanning {
+			err = errors.New(fmt.Sprintf("运单号%s状态为%s,无法装箱!", waybillNo, model.WaybillStatusMap[waybillModel.Status]))
+			return err
+		}
+
+		// 查询保温箱信息
+		var coolerBox = model.CoolerBox{}
+		// 查询运单是否存在
+		err = tx.Scopes(actions.Permission(coolerBox.TableName(), p)).
+			Where("user_id = ?", p.UserId).
+			First(&coolerBox).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New("获取车辆绑定信息失败")
+		}
+
+		// 验证时间
+		var logistics model.WaybillLogistics
+		err = e.Orm.Where("waybill_no = ?", waybillNo).Last(&logistics).Error
+		if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+			e.Log.Errorf("获取运单日志失败: %s", err)
+			return err
+		}
+
+		var lng, lat string
+		lng, lat, err = e.GetSite(p.DeptId, coolerBox.Sn, c.StartTime.String())
+		if err != nil {
+			e.Log.Errorf("获取定位信息失败: %s", err)
+			return err
+		}
+
+		waybillModel.Status = model.WaybillStatusVanning
+		waybillModel.CoolerBoxId = coolerBox.Id
+		waybillModel.DeliveryTime = c.StartTime
+		err = tx.Save(&waybillModel).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New(fmt.Sprintf("保存运单信息失败:%s", err))
+		}
+
+		// 添加物流
+		Logistics := model.WaybillLogistics{
+			WaybillNo:   waybillNo,
+			Status:      model.WaybillStatusTruck,
+			CoolerBoxId: coolerBox.Id,
+			UserId:      p.UserId,
+			Lng:         lng,
+			Lat:         lat,
+			ControlBy: model2.ControlBy{
+				CreateBy: p.UserId,
+			},
+			DeptBy: model2.DeptBy{
+				DeptId: p.DeptId,
+			},
+			ModelTime: model2.ModelTime{
+				CreatedAt: c.StartTime,
+			},
+		}
+		err = tx.Create(&Logistics).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New(fmt.Sprintf("保存运单物流信息失败:%s", err))
+		}
+
+		// 添加任务
+		task := model.WaybillTask{
+			WaybillNo:   waybillNo,
+			CoolerBoxId: coolerBox.Id,
+			UserId:      p.UserId,
+			Sn:          coolerBox.Sn,
+			StartTime:   c.StartTime,
+			ControlBy: model2.ControlBy{
+				CreateBy: p.UserId,
+			},
+			DeptBy: model2.DeptBy{
+				DeptId: p.DeptId,
+			},
+		}
+		err = tx.Create(&task).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New(fmt.Sprintf("保存运单任务信息失败:%s", err))
+		}
 	}
 
+	return nil
+}
+func (e *Waybill) Receipt(c *dto.WaybillReceiptReq, p *actions.DataPermission) error {
+	var err error
+
+	tx := e.Orm.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
 	var waybillModel = model.Waybill{}
 	// 查询运单是否存在
 	err = tx.Scopes(actions.Permission(waybillModel.TableName(), p)).
@@ -1109,6 +1261,117 @@ func (e *Waybill) Receipt(c *dto.WaybillReceiptReq, p *actions.DataPermission) e
 	if waybillModel.Status == model.WaybillStatusReceipt {
 		return nil
 	}
+
+	// 保温箱配送 不需要中转
+	if waybillModel.CoolerBoxId > 0 {
+		// 查询车辆信息
+		var coolerBox = model.CoolerBox{}
+		// 查询运单是否存在
+		err = tx.Scopes(actions.Permission(coolerBox.TableName(), p)).
+			Where("id = ?", waybillModel.CoolerBoxId).
+			First(&coolerBox).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New("获取保温箱信息失败")
+		}
+
+		waybillModel.Status = model.WaybillStatusReceipt
+		waybillModel.CoolerBoxId = coolerBox.Id
+		waybillModel.ReceiptTime = c.StartTime
+		waybillModel.ReceiptImg = c.ReceiptImg
+		err = tx.Save(&waybillModel).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New(fmt.Sprintf("保存运单信息失败:%s", err))
+		}
+
+		var lng, lat string
+		lng, lat, err = e.GetSite(p.DeptId, coolerBox.Sn, c.StartTime.String())
+		if err != nil {
+			e.Log.Errorf("获取定位信息失败: %s", err)
+			return err
+		}
+
+		// 查询任务
+		var task model.WaybillTask
+		err = tx.Model(&task).Where("waybill_no = ? and cooler_box_id = ?", c.WaybillNo, coolerBox.Id).
+			Last(&task).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New(fmt.Sprintf("查询运单任务信息失败:%s", err))
+		}
+		// 未出箱 直接点签收
+		if time.Time(task.EndTime).IsZero() {
+			task.EndTime = model2.Time(time.Now())
+			task.UpdateBy = p.UserId
+			err = tx.Save(&task).Error
+			if err != nil {
+				e.Log.Errorf("db error: %s", err)
+				return errors.New(fmt.Sprintf("保存运单任务信息失败:%s", err))
+			}
+			// 添加下车物流记录
+			Logistics := model.WaybillLogistics{
+				WaybillNo:   c.WaybillNo,
+				Status:      model.WaybillStatusVanningOut,
+				CoolerBoxId: coolerBox.Id,
+				UserId:      p.UserId,
+				Lng:         lng,
+				Lat:         lat,
+				ControlBy: model2.ControlBy{
+					CreateBy: p.UserId,
+				},
+				DeptBy: model2.DeptBy{
+					DeptId: p.DeptId,
+				},
+				ModelTime: model2.ModelTime{
+					CreatedAt: c.StartTime,
+				},
+			}
+			err = tx.Create(&Logistics).Error
+			if err != nil {
+				e.Log.Errorf("db error: %s", err)
+				return errors.New(fmt.Sprintf("保存运单物流信息失败:%s", err))
+			}
+		}
+
+		// 添加签收记录
+		Logistics := model.WaybillLogistics{
+			WaybillNo:   c.WaybillNo,
+			Status:      model.WaybillStatusReceipt,
+			CoolerBoxId: coolerBox.Id,
+			UserId:      p.UserId,
+			Lng:         lng,
+			Lat:         lat,
+			ControlBy: model2.ControlBy{
+				CreateBy: p.UserId,
+			},
+			DeptBy: model2.DeptBy{
+				DeptId: p.DeptId,
+			},
+			ModelTime: model2.ModelTime{
+				CreatedAt: c.StartTime,
+			},
+		}
+		err = tx.Create(&Logistics).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New(fmt.Sprintf("保存运单物流信息失败:%s", err))
+		}
+
+		return nil
+	}
+
+	// 查询车辆信息
+	var car = model.Car{}
+	// 查询运单是否存在
+	err = tx.Scopes(actions.Permission(car.TableName(), p)).
+		Where("user_id = ?", p.UserId).
+		First(&car).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return errors.New("获取车辆信息失败")
+	}
+
 	waybillModel.Status = model.WaybillStatusReceipt
 	waybillModel.CarId = car.Id
 	waybillModel.ReceiptTime = c.StartTime
@@ -1356,6 +1619,12 @@ func (e *Waybill) GetAllData(c *dto.WaybillGetByWaybillNoReq) ([]nats_server.Dev
 		return dataList, waybillPDF, err
 	}
 
+	// 创建名称到权重的映射
+	orderMap := make(map[string]int)
+	for i, v := range taskList {
+		orderMap[v.Sn] = i
+	}
+
 	for i := 0; i < len(taskList); i++ {
 		// 获取传感器信息
 		deviceSensorList, _, _ := nats_server.Cold_CompanyDeviceSensor_List_ByKey(taskList[i].Sn, company.ColdKey)
@@ -1390,7 +1659,7 @@ func (e *Waybill) GetAllData(c *dto.WaybillGetByWaybillNoReq) ([]nats_server.Dev
 				if waybill.Status == model.WaybillStatusReceipt {
 					for k := len(list) - 1; k >= 0; k-- {
 						if v.T_id == list[k].T_id {
-							if taskList[k].Id == lastWaybillTask.Id && list[k].T_time != taskList[i].EndTime.String() && !time.Time(taskList[i].EndTime).IsZero() {
+							if taskList[i].Id == lastWaybillTask.Id && list[k].T_time != taskList[i].EndTime.String() && !time.Time(taskList[i].EndTime).IsZero() {
 								lastData := list[k]
 								lastData.T_time = taskList[i].EndTime.String()
 								lastMap[v.T_id] = lastData
@@ -1410,6 +1679,13 @@ func (e *Waybill) GetAllData(c *dto.WaybillGetByWaybillNoReq) ([]nats_server.Dev
 		for _, v := range lastMap {
 			list = append(list, v)
 		}
+		sort.Slice(list, func(x, y int) bool {
+			if list[x].T_time == list[y].T_time {
+				// 如果时间相同,则按预设顺序排序
+				return orderMap[list[x].T_sn] < orderMap[list[y].T_sn]
+			}
+			return list[x].T_time > list[y].T_time
+		})
 
 		dataList = append(dataList, list...)
 		waybillPDF = append(waybillPDF, WaybillPDF{
@@ -1418,11 +1694,142 @@ func (e *Waybill) GetAllData(c *dto.WaybillGetByWaybillNoReq) ([]nats_server.Dev
 			Task:             taskList[i],
 		})
 	}
+
+	sort.Slice(dataList, func(i, j int) bool {
+		if dataList[i].T_time == dataList[j].T_time {
+			// 如果时间相同,则按预设顺序排序
+			return orderMap[dataList[i].T_sn] < orderMap[dataList[j].T_sn]
+		}
+		return dataList[i].T_time < dataList[j].T_time
+	})
+
+	return dataList, waybillPDF, nil
+}
+
+// 获取前两个探头数据
+func (e *Waybill) GetTwoDeviceSensorData(c *dto.WaybillGetByWaybillNoReq) ([]nats_server.DeviceData_R, []DeviceDataPdf, []WaybillPDF, error) {
+	var err error
+	var data model.WaybillTask
+	var waybill model.Waybill
+	var taskList []model.WaybillTask
+	var deviceDataPdf []DeviceDataPdf
+	var waybillPDF []WaybillPDF
+	dataList := make([]nats_server.DeviceData_R, 0)
+
+	err = e.Orm.Model(&waybill).Where("waybill_no = ?", c.WaybillNo).First(&waybill).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return dataList, deviceDataPdf, waybillPDF, errors.New("获取运单信息失败")
+	}
+
+	// 未签收,不返回数据
+	if waybill.Status != model.WaybillStatusReceipt {
+		return dataList, deviceDataPdf, waybillPDF, nil
+	}
+
+	// 获取公司秘钥
+	var company model.SysDept
+	company, err = model.GetCompanyById(waybill.DeptId)
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return dataList, deviceDataPdf, waybillPDF, model.GetCompanyKeyErr
+	}
+
+	err = e.Orm.Model(&data).
+		Where("waybill_no = ?", c.WaybillNo).
+		Order("id desc").
+		Find(&taskList).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return dataList, deviceDataPdf, waybillPDF, global.GetFailedErr
+	}
+
+	// 获取最后一个任务id
+	var lastWaybillTask model.WaybillTask
+	err = e.Orm.Model(&lastWaybillTask).Where("waybill_no = ?", c.WaybillNo).Last(&lastWaybillTask).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		err = errors.New("获取运单信息错误!")
+		return dataList, deviceDataPdf, waybillPDF, err
+	}
+
 	// 创建名称到权重的映射
 	orderMap := make(map[string]int)
 	for i, v := range taskList {
 		orderMap[v.Sn] = i
 	}
+
+	for i := 0; i < len(taskList); i++ {
+		// 获取传感器信息
+		deviceSensorList, _, _ := nats_server.Cold_CompanyDeviceSensor_List_ByKey(taskList[i].Sn, company.ColdKey)
+		var T_snid string
+		var list []nats_server.DeviceData_R
+		t_id_list := [2]int{-1, -2}
+		for j, r := range deviceSensorList {
+			if j >= 2 {
+				break
+			}
+			T_snid += fmt.Sprintf("%s,%d|", r.T_sn, r.T_id)
+			t_id_list[j] = r.T_id
+		}
+
+		var count int64
+		list, count, err = nats_server.Cold_ReadDeviceDataListBy_T_snid(T_snid, taskList[i].StartTime.String(), taskList[i].EndTime.String(), 0, 9999)
+		if err != nil {
+			e.Log.Errorf("nats 获取温湿度信息失败: %s", err)
+			return dataList, deviceDataPdf, waybillPDF, global.GetFailedErr
+		}
+
+		firstMap := map[int]nats_server.DeviceData_R{}
+		lastMap := map[int]nats_server.DeviceData_R{}
+		if count > 0 {
+			for _, v := range deviceSensorList {
+				for j := 0; j < len(list); j++ {
+					if v.T_id == list[j].T_id {
+						if list[j].T_time != taskList[i].StartTime.String() {
+							if i < len(taskList)-2 && list[j].T_time != taskList[i+1].EndTime.String() {
+								firstData := list[j]
+								firstData.T_time = taskList[i].StartTime.String()
+								firstMap[v.T_id] = firstData
+								count += 1
+							}
+						}
+						break
+					}
+				}
+				if waybill.Status == model.WaybillStatusReceipt {
+					for k := len(list) - 1; k >= 0; k-- {
+						if v.T_id == list[k].T_id {
+							if taskList[i].Id == lastWaybillTask.Id && list[k].T_time != taskList[i].EndTime.String() && !time.Time(taskList[i].EndTime).IsZero() {
+								lastData := list[k]
+								lastData.T_time = taskList[i].EndTime.String()
+								lastMap[v.T_id] = lastData
+								count += 1
+							}
+							break
+						}
+					}
+				}
+			}
+		}
+		for _, v := range firstMap {
+			list = append(list, v)
+		}
+
+		for _, v := range lastMap {
+			list = append(list, v)
+		}
+		deviceDataPdfList := DeviceSensorDataListToDeviceDataPdfList(list, t_id_list[0], t_id_list[1])
+		deviceDataPdf = append(deviceDataPdf, deviceDataPdfList...)
+		dataList = append(dataList, list...)
+		waybillPDF = append(waybillPDF, WaybillPDF{
+			Data:             list,
+			DeviceSensorList: deviceSensorList,
+			Task:             taskList[i],
+			DeviceDataPdf:    deviceDataPdfList,
+		})
+	}
+
 	sort.Slice(dataList, func(i, j int) bool {
 		if dataList[i].T_time == dataList[j].T_time {
 			// 如果时间相同,则按预设顺序排序
@@ -1431,11 +1838,50 @@ func (e *Waybill) GetAllData(c *dto.WaybillGetByWaybillNoReq) ([]nats_server.Dev
 		return dataList[i].T_time < dataList[j].T_time
 	})
 
-	return dataList, waybillPDF, nil
+	sort.Slice(deviceDataPdf, func(i, j int) bool {
+		return deviceDataPdf[i].T_time < deviceDataPdf[j].T_time
+	})
+
+	return dataList, deviceDataPdf, waybillPDF, nil
 }
 
 type WaybillPDF struct {
-	Data             []nats_server.DeviceData_R   `json:"data"`
-	DeviceSensorList []nats_server.DeviceSensor_R `json:"deviceSensorList"`
-	Task             model.WaybillTask            `json:"task"`
+	Data             []nats_server.DeviceData_R
+	DeviceSensorList []nats_server.DeviceSensor_R
+	Task             model.WaybillTask
+	DeviceDataPdf    []DeviceDataPdf
+}
+
+type DeviceDataPdf struct {
+	T_time string  // sn
+	T_id1  float32 // 传感器id1温度
+	T_id2  float32 // 传感器id2温度
+}
+
+func DeviceSensorDataListToDeviceDataPdfList(list []nats_server.DeviceData_R, T_id1 int, T_id2 int) []DeviceDataPdf {
+	// 创建一个 map 用于存储 DeviceData_Pdf 结果
+	resultMap := make(map[string]DeviceDataPdf)
+
+	// 遍历第一个列表,将数据存入 resultMap
+	for _, item := range list {
+		key := item.T_time
+		if _, ok := resultMap[key]; !ok {
+			resultMap[key] = DeviceDataPdf{T_time: item.T_time}
+		}
+		data := resultMap[key]
+		if item.T_id == T_id1 {
+			data.T_id1 = item.T_t
+		} else if item.T_id == T_id2 {
+			data.T_id2 = item.T_t
+		}
+		resultMap[key] = data
+	}
+
+	// 将 resultMap 转换为 DeviceData_Pdf 列表
+	var finalList []DeviceDataPdf
+	for _, v := range resultMap {
+		finalList = append(finalList, v)
+	}
+	return finalList
+
 }

+ 3 - 3
app/admin/service/waybill_task.go

@@ -177,12 +177,12 @@ func (e *WaybillTask) GetDataPage(c *dto.WaybillTaskGetDataPageReq) (list []nats
 	totalPages := (int(count) + c.PageSize - 1) / c.PageSize
 
 	// 如果n超出范围,返回错误
-	if c.Page < 1 {
-		c.Page = 1
-	}
 	if c.Page > totalPages {
 		c.Page = totalPages
 	}
+	if c.Page < 1 {
+		c.Page = 1
+	}
 	// 计算当前页的数据
 	start := (c.Page - 1) * c.PageSize
 	end := start + c.PageSize

+ 15 - 0
common/lib/lib.go

@@ -4,7 +4,9 @@ import (
 	"encoding/json"
 	"fmt"
 	"github.com/nats-io/nats.go"
+	"image"
 	"math/rand"
+	"net/http"
 	"os"
 	"path/filepath"
 	"runtime"
@@ -426,3 +428,16 @@ func GetDiffDays(t1, t2 time.Time) int {
 
 	return int(t1.Sub(t2).Hours() / 24)
 }
+
+func GetImage(url string) (image.Image, error) {
+	resp, err := http.Get(url)
+	if err != nil {
+		return nil, err
+	}
+	defer resp.Body.Close()
+	img, _, err := image.Decode(resp.Body)
+	if err != nil {
+		return nil, err
+	}
+	return img, nil
+}

+ 18 - 0
common/lib/libString.go

@@ -170,3 +170,21 @@ func IsSNAllSame(T_snid string) (string, []int, bool) {
 
 	return firstSN, ids, true
 }
+
+func MaskStr(s string) string {
+	if len([]rune(s)) > 1 {
+		firstChar := string([]rune(s)[0])
+		remainingStars := strings.Repeat("*", len([]rune(s))-1)
+		result := fmt.Sprintf("%s%s", firstChar, remainingStars)
+		return result
+	}
+	return s
+}
+
+func MaskPhoneNumber(phoneNumber string) string {
+	if len(phoneNumber) != 11 {
+		return phoneNumber // 11位手机号码
+	}
+	masked := phoneNumber[:3] + "****" + phoneNumber[7:]
+	return masked
+}

+ 41 - 0
common/nats/nats_server/NatsColdApi.go

@@ -175,3 +175,44 @@ func Cold_ReadDeviceDataListBy_T_snidForLocus(T_snid, startTime, endTime string,
 
 	return t_R.Data, t_R.Count, nil
 }
+func Cold_ReadDevice_List(name, T_key string, page, page_z int) (data []Device_R, count int64, err error) {
+
+	type T_Req struct {
+		Key    string `xml:"Key"`
+		Name   string `xml:"Name"`
+		Page   int    `xml:"Page"`
+		Page_z int    `xml:"Page_z"`
+	}
+	t_Req := T_Req{
+		Key:    T_key,
+		Name:   name,
+		Page:   page,
+		Page_z: page_z,
+	}
+	b, _ := msgpack.Marshal(&t_Req)
+
+	msg, err := nats.Nats.Request("Cold_ReadDevice_List", b, 3*time.Second)
+	if err != nil {
+		return
+	}
+
+	type T_R struct {
+		Code  int16      `xml:"Code"`
+		Msg   string     `xml:"Msg"`
+		Count int64      `xml:"Count"`
+		Data  []Device_R `xml:"Data"` // 泛型
+	}
+	var t_R T_R
+
+	err = msgpack.Unmarshal(msg.Data, &t_R)
+	if err != nil {
+		return
+	}
+	if t_R.Code != 200 {
+		err = errors.New(t_R.Msg)
+		return
+	}
+	list := t_R.Data
+
+	return list, t_R.Count, nil
+}

+ 30 - 0
common/nats/nats_server/models.go

@@ -111,3 +111,33 @@ type DeviceSensorParameter_R struct {
 
 	T_time JsonTime
 }
+
+type Device_R struct {
+	T_sn              string // 设备序列号 KF开头,环境监测主机。 YD开头,温途监测主机
+	T_devName         string // 设备名称
+	T_protocol        int    // 1 1.0协议  2 2.0协议
+	T_VerifyTime      string // 验证时间
+	T_CalibrationTime string // 校准时间
+	T_PatrolTime      string // 巡检时间
+	T_ist             int    // 温度   1开启   2关闭
+	T_ish             int    // 湿度   1开启   2关闭
+	T_Dattery         int    // 电量
+	T_Site            string // GPS
+	T_monitor         int    // 监控状态 0 未监控 1 监控 停止记录
+	T_online          int    // 在线状态 0 未启用  1 在线  2 离线
+	T_online_s        int    // 在线状态-备用  0 未启用  1 在线  2 离线
+	T_State           int    // 0 屏蔽   1 正常
+	// 硬件信息
+	T_model           string // KF200BG  产品型号
+	T_ProductTypeName string // 验证工具LoRa  产品统称 + 类型
+	T_sver            string // "1.0.0",//软件版本
+	T_hver            string // "1.0.0",//硬件版本
+	T_imei            string // "867387060327718",//模组imei
+	T_iccid           string // "89860477102170049750",//sim卡号
+	T_rssi            string // "80",//信号强度
+	CreateTime        string //auto_now_add 第一次保存时才设置时间
+	UpdateTime        string //auto_now 每次 model 保存时都会对时间自动更新
+
+	T_DeviceSensor_Num int // 传感器数量
+
+}

+ 5 - 0
conf/extend.go

@@ -16,6 +16,7 @@ type Extend struct {
 	Nats    Nats    `yaml:"nats"`
 	Amap    Amap    `yaml:"amap"`
 	Apk     Apk     `yaml:"apk"`
+	Service Service `yaml:"service"`
 }
 
 type SubMail struct {
@@ -48,3 +49,7 @@ type Amap struct {
 type Apk struct {
 	Path string `json:"path"`
 }
+
+type Service struct {
+	Domain string `json:"domain"`
+}

+ 1 - 0
db/migration.go

@@ -25,6 +25,7 @@ func AutoMigrateDB() {
 			&model.Waybill{},
 			&model.WaybillLogistics{},
 			&model.WaybillTask{},
+			&model.CoolerBox{},
 		)
 	if err != nil {
 		zap.L().Panic("migrate db fail", zap.Error(err))

+ 8 - 4
go.mod

@@ -28,12 +28,19 @@ require (
 
 require (
 	github.com/beego/beego/v2 v2.1.0
+	github.com/boombuler/barcode v1.0.1
 	github.com/go-redis/redis/v7 v7.4.0
 	github.com/go-resty/resty/v2 v2.7.0
+	github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
 	github.com/nats-io/nats.go v1.34.0
+	github.com/ser163/png2j v0.1.2-beta
+	github.com/signintech/gopdf v0.25.0
+	github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
 	github.com/vmihailenco/msgpack/v5 v5.4.1
+	github.com/wcharczuk/go-chart/v2 v2.1.1
 	github.com/xuri/excelize/v2 v2.8.1
 	gogs.baozhida.cn/zoie/OAuth-core v0.0.0-00010101000000-000000000000
+	gonum.org/v1/plot v0.14.0
 )
 
 require (
@@ -69,7 +76,6 @@ require (
 	github.com/go-playground/universal-translator v0.18.1 // indirect
 	github.com/go-playground/validator/v10 v10.11.2 // indirect
 	github.com/goccy/go-json v0.10.0 // indirect
-	github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
 	github.com/golang/protobuf v1.5.3 // indirect
 	github.com/golang/snappy v0.0.1 // indirect
 	github.com/henrylee2cn/ameda v1.4.10 // indirect
@@ -95,6 +101,7 @@ require (
 	github.com/mojocn/base64Captcha v1.3.1 // indirect
 	github.com/nats-io/nkeys v0.4.7 // indirect
 	github.com/nats-io/nuid v1.0.1 // indirect
+	github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
 	github.com/nsqio/go-nsq v1.0.8 // indirect
 	github.com/nyaruka/phonenumbers v1.0.55 // indirect
 	github.com/pelletier/go-toml/v2 v2.0.6 // indirect
@@ -107,7 +114,6 @@ require (
 	github.com/shamsher31/goimgext v1.0.0 // indirect
 	github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
 	github.com/shirou/gopsutil v2.19.12+incompatible // indirect
-	github.com/signintech/gopdf v0.25.0 // indirect
 	github.com/spf13/cast v1.3.1 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
 	github.com/tsuyoshiwada/go-gitcmd v0.0.0-20180205145712-5f1f5f9475df // indirect
@@ -115,7 +121,6 @@ require (
 	github.com/ugorji/go/codec v1.2.9 // indirect
 	github.com/urfave/cli v1.22.1 // indirect
 	github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
-	github.com/wcharczuk/go-chart/v2 v2.1.1 // indirect
 	github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 // indirect
 	github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 // indirect
 	go.uber.org/atomic v1.9.0 // indirect
@@ -128,7 +133,6 @@ require (
 	golang.org/x/text v0.14.0 // indirect
 	golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
 	golang.org/x/tools v0.7.0 // indirect
-	gonum.org/v1/plot v0.14.0 // indirect
 	google.golang.org/protobuf v1.30.0 // indirect
 	gopkg.in/AlecAivazis/survey.v1 v1.8.5 // indirect
 	gopkg.in/kyokomi/emoji.v1 v1.5.1 // indirect

+ 8 - 0
go.sum

@@ -81,6 +81,8 @@ github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngE
 github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
 github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
 github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
+github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
+github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
 github.com/bsm/redislock v0.5.0 h1:ODM11/cbuUXQqLgZWK6XQnufaTjsBE2UcwBc2EAFNDA=
 github.com/bsm/redislock v0.5.0/go.mod h1:qagqKlV+xiLy26iV34Y3zRPxRcJjQYbV7pZfWFeSZ8M=
 github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
@@ -481,6 +483,8 @@ github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDm
 github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
 github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
 github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
+github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
+github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 github.com/nlopes/slack v0.6.1-0.20191106133607-d06c2a2b3249/go.mod h1:JzQ9m3PMAqcpeCam7UaHSuBuupz7CmpjehYMayT6YOk=
 github.com/nrdcg/auroradns v1.0.0/go.mod h1:6JPXKzIRzZzMqtTDgueIhTi6rFf1QvYE/HzqidhOhjw=
@@ -572,6 +576,8 @@ github.com/sacloud/libsacloud v1.26.1/go.mod h1:79ZwATmHLIFZIMd7sxA3LwzVy/B77uj3
 github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
 github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
+github.com/ser163/png2j v0.1.2-beta h1:ri7e+tGw/Y1TV18x8O4uONqaHjyTv/L2rnI3Ft5bMeA=
+github.com/ser163/png2j v0.1.2-beta/go.mod h1:QusatApB4GgVnjdAL45Erna5GxAaAd7KsPv3mrswtp8=
 github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
 github.com/shamsher31/goimgext v1.0.0 h1:wFKf9GeeE0Xr6UQtliaPgYYgTju2izobM7XpCEgUCC8=
 github.com/shamsher31/goimgext v1.0.0/go.mod h1:rYLKgXuTGBIaH49z+jUVSWz7gUWIZmqvYUsdvJbNNOc=
@@ -585,6 +591,8 @@ github.com/signintech/gopdf v0.25.0/go.mod h1:d23eO35GpEliSrF22eJ4bsM3wVeQJTjXTH
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
+github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
 github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=

+ 1 - 1
main.go

@@ -10,7 +10,7 @@ import (
 //go:generate swag init --parseDependency --parseDepth=6
 // @title 冷链物流平台
 // @version 1.0
-// @description 气瓶追溯管理系统
+// @description 冷链物流平台
 // @Host 127.0.0.1:6270
 
 // @securityDefinitions.apikey Bearer

Some files were not shown because too many files changed in this diff