Prechádzať zdrojové kódy

FUNC:运单管理、出入库、上下车

zoie 1 rok pred
rodič
commit
75f8f9199f

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

@@ -214,17 +214,6 @@ func (e CompanyController) Delete(c *gin.Context) {
 		return
 	}
 
-	var count int64
-	err = userSvc.GetCount(&dto.SysUserGetCountReq{DeptIds: []int{req.Id}}, &count)
-	if err != nil {
-		e.Error(500, err, err.Error())
-		return
-	}
-	if count > 0 {
-		e.Error(500, err, "有用户关联,禁止删除!")
-		return
-	}
-
 	//数据权限检查
 	//p := actions.GetPermissionFromContext(c)
 	err = s.Remove(&req, nil)

+ 431 - 0
app/admin/controller/customer.go

@@ -0,0 +1,431 @@
+package controller
+
+import (
+	"cold-logistics/app/admin/model"
+	"cold-logistics/app/admin/service"
+	"cold-logistics/app/admin/service/dto"
+	"cold-logistics/common/actions"
+	"cold-logistics/common/middleware/handler"
+	"cold-logistics/conf"
+	"errors"
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+	"go.uber.org/zap"
+	"gogs.baozhida.cn/zoie/OAuth-core/api"
+	"gogs.baozhida.cn/zoie/OAuth-core/pkg"
+	"gogs.baozhida.cn/zoie/OAuth-core/pkg/jwtauth/user"
+	_ "gogs.baozhida.cn/zoie/OAuth-core/pkg/response"
+	"gogs.baozhida.cn/zoie/OAuth-core/pkg/sms"
+	"golang.org/x/crypto/bcrypt"
+	"net/http"
+)
+
+// Customer 定义客户控制器
+type Customer struct {
+	api.Api
+}
+
+// GetPage 获取客户列表
+// @Summary 获取客户列表
+// @Description 获取客户列表
+// @Tags 客户
+// @Param username query string false "客户名"
+// @Param pageSize query int false "页条数"
+// @Param page query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]model.SysUser}}  "{"code": 200, "data": [...]}"
+// @Router /api/customer [get]
+// @Security Bearer
+func (e Customer) GetPage(c *gin.Context) {
+	s := service.Customer{}
+	req := dto.CustomerGetPageReq{}
+	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.SysUser, 0)
+	var count int64
+
+	err = s.GetPage(&req, p, &list, &count)
+	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 int true "客户id"
+// @Success 200 {object} response.Response{data=model.SysUser}  "{"code": 200, "data": [...]}"
+// @Router /api/customer/{id} [get]
+// @Security Bearer
+func (e Customer) Get(c *gin.Context) {
+	s := service.Customer{}
+	req := dto.CustomerGetReq{}
+	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
+	}
+
+	//数据权限检查
+	//p := actions.GetPermissionFromContext(c)
+
+	var object model.SysUser
+	err = s.Get(&req, nil, &object)
+	if err != nil {
+		e.Error(http.StatusUnprocessableEntity, err, err.Error())
+		return
+	}
+	e.OK(object, "查询成功")
+}
+
+// Insert 创建客户
+// @Summary 创建客户
+// @Description 创建客户
+// @Tags 客户
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.CustomerInsertReq true "客户数据"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/customer [post]
+// @Security Bearer
+func (e Customer) Insert(c *gin.Context) {
+	s := service.Customer{}
+	req := dto.CustomerInsertReq{}
+	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)
+	if p.DeptId == 0 {
+		err = errors.New("无权添加,请联系管理员!")
+		e.Error(500, err, err.Error())
+		return
+	}
+	// 设置创建人
+	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.CustomerUpdateReq true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/customer [put]
+// @Security Bearer
+func (e Customer) Update(c *gin.Context) {
+	s := service.Customer{}
+	req := dto.CustomerUpdateReq{}
+	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.SetUpdateBy(user.GetUserId(c))
+
+	//数据权限检查
+	//p := actions.GetPermissionFromContext(c)
+
+	err = s.Update(&req, nil)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(req.GetId(), "更新成功")
+}
+
+// Delete 通过id删除客户数据
+// @Summary 通过id删除客户数据
+// @Description 通过id删除客户数据
+// @Tags 客户
+// @Param data body dto.CustomerDeleteReq true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/customer [delete]
+// @Security Bearer
+func (e Customer) Delete(c *gin.Context) {
+	s := service.Customer{}
+	req := dto.CustomerDeleteReq{}
+	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
+	}
+	userId := user.GetUserId(c)
+	if userId == req.Id {
+		err := errors.New("禁止删除自己")
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	// 设置编辑人
+	req.SetUpdateBy(userId)
+	//数据权限检查
+	//p := actions.GetPermissionFromContext(c)
+
+	err = s.Remove(&req, nil)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(req.GetId(), "删除成功")
+}
+
+// ResetPwd 重置客户密码
+// @Summary 重置客户密码
+// @Description 重置客户密码
+// @Tags 客户
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.ResetCustomerPwdReq true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/user/pwd/reset [put]
+// @Security Bearer
+func (e Customer) ResetPwd(c *gin.Context) {
+	s := service.Customer{}
+	req := dto.ResetCustomerPwdReq{}
+	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
+	}
+
+	req.SetUpdateBy(user.GetUserId(c))
+
+	//数据权限检查
+	//p := actions.GetPermissionFromContext(c)
+
+	err = s.ResetPwd(&req, nil)
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	e.OK(req.GetId(), "更新成功")
+
+}
+
+// UpdatePwd 修改密码
+// @Summary 修改密码
+// @Description 修改密码
+// @Tags 个人中心
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.CustomerPassWord true "body"
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/customer/pwd/set [put]
+// @Security Bearer
+func (e Customer) UpdatePwd(c *gin.Context) {
+	s := service.Customer{}
+	req := dto.CustomerPassWord{}
+	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
+	}
+
+	var hash []byte
+	if hash, err = bcrypt.GenerateFromPassword([]byte(req.NewPassword), bcrypt.DefaultCost); err != nil {
+		req.NewPassword = string(hash)
+	}
+
+	err = s.UpdatePwd(user.GetUserId(c), req.OldPassword, req.NewPassword)
+	if err != nil {
+		e.Error(http.StatusForbidden, err, err.Error())
+		return
+	}
+
+	e.OK(nil, "密码修改成功")
+
+}
+
+// GetProfile 获取个人中心客户
+// @Summary 获取个人中心客户
+// @Description 获取个人中心客户
+// @Tags 个人中心
+// @Success 200 {object} response.Response{user=model.SysUser,role=model.SysRole}  "{"code": 200, "data": {"user":[...],"role":[...]}}"
+// @Router /api/user/profile [get]
+// @Security Bearer
+func (e Customer) GetProfile(c *gin.Context) {
+	s := service.Customer{}
+	req := dto.CustomerById{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+
+	req.Id = user.GetUserId(c)
+
+	sysUser := model.SysUser{}
+	err = s.GetProfile(&req, &sysUser)
+	if err != nil {
+		e.Logger.Errorf("get user profile error, %s", err.Error())
+		e.Error(500, err, "获取客户信息失败")
+		return
+	}
+	e.OK(gin.H{
+		"user": sysUser,
+	}, "查询成功")
+}
+
+// GetInfo 获取个人信息
+// @Summary 获取个人信息
+// @Description 获取个人信息
+// @Tags 个人中心
+// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /api/user/info [get]
+// @Security Bearer
+func (e Customer) GetInfo(c *gin.Context) {
+	req := dto.CustomerGetReq{}
+	s := service.Customer{}
+	r := service.SysRole{}
+	err := e.MakeContext(c).
+		MakeOrm().
+		MakeService(&r.Service).
+		MakeService(&s.Service).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	var roles = make([]string, 1)
+	roles[0] = user.GetRoleName(c)
+	var permissions = make([]string, 1)
+	permissions[0] = "*:*:*"
+	var buttons = make([]string, 1)
+	buttons[0] = "*:*:*"
+
+	var mp = make(map[string]interface{})
+	mp["roles"] = roles
+	list, _ := r.GetById(user.GetRoleId(c))
+	mp["permissions"] = list
+	mp["buttons"] = list
+
+	sysUser := model.SysUser{}
+	req.Id = user.GetUserId(c)
+
+	err = s.Get(&req, nil, &sysUser)
+	if err != nil {
+		e.Logger.Errorf("get user info error, %s", err.Error())
+		e.Error(http.StatusUnauthorized, err, err.Error())
+		return
+	}
+
+	mp["userName"] = sysUser.Username
+	mp["userId"] = sysUser.Id
+	mp["deptId"] = sysUser.DeptId
+	mp["name"] = sysUser.NickName
+	mp["code"] = 200
+	e.OK(mp, "查询成功")
+}
+
+// VerifyCode 获取短信验证码
+// @Summary 获取短信验证码
+// @Description 获取短信验证码
+// @Tags 登录
+// @Accept  application/json
+// @Product application/json
+// @Success 200 {string} string "{"code": 200, "data": "18888888888"}"
+// @Router /verify-code [get]
+// @Security Bearer
+func (e Customer) VerifyCode(c *gin.Context) {
+	s := service.Customer{}
+	req := dto.CustomerGetSMSVerifyCodeReq{}
+	err := e.MakeContext(c).
+		MakeService(&s.Service).
+		Bind(&req, binding.Query).
+		Errors
+	if err != nil {
+		e.Logger.Error(err)
+		e.Error(500, err, err.Error())
+		return
+	}
+	key := handler.GetVerifyCodeCacheKey(req.Phone)
+	_, err = e.Cache.Get(key)
+	// 验证吗缓存已存在
+	if err == nil {
+		e.Error(500, err, "验证吗已发送,请注意查收")
+		return
+	}
+
+	code := pkg.GenerateRandomFigureKey6()
+
+	ss := sms.NewSMS(conf.ExtConfig.SubMail.Appid, conf.ExtConfig.SubMail.Signature)
+	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))
+		e.Error(500, err, "验证吗发送失败,请重试")
+		return
+	}
+	_ = e.Cache.Set(key, code, 600)
+	e.OK(req.Phone, "发送成功")
+
+}

+ 2 - 30
app/admin/controller/sys_user.go

@@ -300,13 +300,13 @@ func (e SysUser) ResetPwd(c *gin.Context) {
 // @Tags 个人中心
 // @Accept  application/json
 // @Product application/json
-// @Param data body dto.PassWord true "body"
+// @Param data body dto.SysUserPassWord true "body"
 // @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
 // @Router /api/user/pwd/set [put]
 // @Security Bearer
 func (e SysUser) UpdatePwd(c *gin.Context) {
 	s := service.SysUser{}
-	req := dto.PassWord{}
+	req := dto.SysUserPassWord{}
 	err := e.MakeContext(c).
 		MakeOrm().
 		Bind(&req).
@@ -462,31 +462,3 @@ func (e SysUser) VerifyCode(c *gin.Context) {
 	e.OK(req.Phone, "发送成功")
 
 }
-
-// GetNewestToken 获取最新token
-// @Summary 获取最新token
-// @Description 获取最新token,提供给接入服务访问,用于单一认证检查
-// @Tags 用户
-// @Param serviceId header int true "服务id"
-// @Param userId path int true "用户id"
-// @Success 200 {string} string "{"code": 200, "data": "...token..."}"
-// @Router /newest-token [get]
-func (e SysUser) GetNewestToken(c *gin.Context) {
-	s := service.SysUser{}
-	req := dto.GetNewestTokenReq{}
-	err := e.MakeContext(c).
-		MakeService(&s.Service).
-		Bind(&req, nil).
-		Errors
-	if err != nil {
-		e.Logger.Error(err)
-		e.Error(500, err, err.Error())
-		return
-	}
-	key, err := handler.GetNewestToken(c, req.UserId)
-	if err != nil {
-		e.Error(500, err, err.Error())
-		return
-	}
-	e.OK(key, "查询成功")
-}

+ 372 - 0
app/admin/controller/waybill.go

@@ -0,0 +1,372 @@
+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 WaybillController struct {
+	api.Api
+}
+
+// GetPage 获取运单列表
+// @Summary 获取运单列表
+// @Description 获取运单列表
+// @Tags 运单
+// @Param no query string false "运单号"
+// @Param pageSize query int false "页条数"
+// @Param page query int false "页码"
+// @Success 200 {object} response.Response{data=response.Page{list=[]model.Waybill}} "{"code": 200, "data": [...]}"
+// @Router /api/waybill [get]
+// @Security Bearer
+func (e WaybillController) GetPage(c *gin.Context) {
+	s := service.Waybill{}
+	req := dto.WaybillGetPageReq{}
+	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.Waybill, 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.Waybill} "{"code": 200, "data": [...]}"
+// @Router /api/warehouse/{id} [get]
+// @Security Bearer
+func (e WaybillController) Get(c *gin.Context) {
+	s := service.Waybill{}
+	req := dto.WaybillGetReq{}
+	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.Waybill
+	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.WaybillInsertReq true "data"
+// @Success 200 {string} string	"{"code": 200, "message": "添加成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "添加失败"}"
+// @Router /api/waybill [post]
+// @Security Bearer
+func (e WaybillController) Insert(c *gin.Context) {
+	s := service.Waybill{}
+	req := dto.WaybillInsertReq{}
+	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.WaybillUpdateReq true "body"
+// @Success 200 {string} string	"{"code": 200, "message": "添加成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "添加失败"}"
+// @Router /api/waybill [put]
+// @Security Bearer
+func (e WaybillController) Update(c *gin.Context) {
+	s := service.Waybill{}
+	req := dto.WaybillUpdateReq{}
+	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(), "更新成功")
+}
+
+// Delivery 派单
+// @Summary 派单
+// @Description 派单
+// @Tags 运单
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.WaybillDeliveryReq true "body"
+// @Success 200 {string} string	"{"code": 200, "message": "添加成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "添加失败"}"
+// @Router /api/waybill [put]
+// @Security Bearer
+func (e WaybillController) Delivery(c *gin.Context) {
+	s := service.Waybill{}
+	req := dto.WaybillDeliveryReq{}
+	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.Delivery(&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.WaybillDeleteReq true "body"
+// @Success 200 {string} string	"{"code": 200, "message": "删除成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "删除失败"}"
+// @Router /api/waybill [delete]
+// @Security Bearer
+func (e WaybillController) Delete(c *gin.Context) {
+	s := service.Waybill{}
+	req := dto.WaybillDeleteReq{}
+	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)
+		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(), "删除成功")
+}
+
+// WarehouseIn 入库
+// @Summary 入库
+// @Description 入库
+// @Tags 运单
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.WaybillInOutReq true "body"
+// @Success 200 {string} string	"{"code": 200, "message": "删除成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "删除失败"}"
+// @Router /api/waybill/warehouse-in [post]
+// @Security Bearer
+func (e WaybillController) WarehouseIn(c *gin.Context) {
+	s := service.Waybill{}
+	req := dto.WaybillInOutReq{}
+	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.WarehouseIn(&req, p)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(req.WaybillNoList, "入库成功")
+}
+
+// WarehouseOut 出库
+// @Summary 出库
+// @Description 出库
+// @Tags 运单
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.WaybillInOutReq true "body"
+// @Success 200 {string} string	"{"code": 200, "message": "删除成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "删除失败"}"
+// @Router /api/waybill/warehouse-out [post]
+// @Security Bearer
+func (e WaybillController) WarehouseOut(c *gin.Context) {
+	s := service.Waybill{}
+	req := dto.WaybillInOutReq{}
+	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.WarehouseOut(&req, p)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(req.WaybillNoList, "出库成功")
+}
+
+// CarIn 上车
+// @Summary 上车
+// @Description 上车
+// @Tags 运单
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.WaybillInOutReq true "body"
+// @Success 200 {string} string	"{"code": 200, "message": "删除成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "删除失败"}"
+// @Router /api/waybill/car-in [post]
+// @Security Bearer
+func (e WaybillController) CarIn(c *gin.Context) {
+	s := service.Waybill{}
+	req := dto.WaybillInOutReq{}
+	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.CarIn(&req, p)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(req.WaybillNoList, "装车成功")
+}
+
+// CarOut 下车
+// @Summary 下车
+// @Description 下车
+// @Tags 运单
+// @Accept  application/json
+// @Product application/json
+// @Param data body dto.WaybillInOutReq true "body"
+// @Success 200 {string} string	"{"code": 200, "message": "删除成功"}"
+// @Success 200 {string} string	"{"code": -1, "message": "删除失败"}"
+// @Router /api/waybill/car-out [post]
+// @Security Bearer
+func (e WaybillController) CarOut(c *gin.Context) {
+	s := service.Waybill{}
+	req := dto.WaybillInOutReq{}
+	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.CarOut(&req, p)
+	if err != nil {
+		e.Error(500, err, err.Error())
+		return
+	}
+	e.OK(req.WaybillNoList, "下车成功")
+}

+ 6 - 0
app/admin/model/car.go

@@ -15,6 +15,12 @@ type Car struct {
 	model2.DeptBy
 }
 
+type CarOmit struct {
+	Id    int    `json:"id,omitempty"`    // 主键编码
+	CarNo string `json:"carNo,omitempty"` // 商品名称
+	Sn    string `json:"sn,omitempty"`    // sn
+}
+
 func (Car) TableName() string {
 	return "car"
 }

+ 13 - 3
app/admin/model/sys_user.go

@@ -9,12 +9,22 @@ import (
 	"gorm.io/gorm"
 )
 
+var (
+	UserTypeSys          = "sys"
+	UserTypeCustomer     = "customer"
+	SysUserTypeSys       = 1
+	SysUserTypeWarehouse = 2
+	SysUserTypeDriver    = 3
+)
+
 type SysUser struct {
 	model2.Model
 	coreModel.User
-	Type int     `json:"type" gorm:"size:128;comment:类型"` // 管理员1 仓管2 司机3
-	Dept SysDept `json:"dept" gorm:"->"`                  // 部门
-	Role SysRole `json:"-" gorm:"-"`                      // 角色
+	Type     int     `json:"type" gorm:"size:128;comment:类型"`         // 管理员1 仓管2 司机3
+	UserType string  `json:"userType" gorm:"size:128;comment:用户类型"`   // 系统用户-sys 客户-customer
+	Openid   string  `json:"openid" gorm:"size:128;comment:微信openid"` // 微信openid
+	Dept     SysDept `json:"dept" gorm:"->"`                          // 部门
+	Role     SysRole `json:"-" gorm:"-"`                              // 角色
 	model2.ControlBy
 	model2.ModelTime
 }

+ 0 - 16
app/admin/model/user_warehouse.go

@@ -1,16 +0,0 @@
-package model
-
-import model2 "cold-logistics/common/model"
-
-type UserWarehouse struct {
-	model2.Model
-	UserId           int         `json:"userId" gorm:"size:128;comment:用户id"`      // 用户id
-	WarehouseId      int         `json:"warehouseId" gorm:"size:128;comment:仓库id"` // 仓库id
-	User             SysUserOmit `json:"user"`
-	model2.ControlBy `json:"-"`
-	model2.ModelTime `json:"-"`
-}
-
-func (UserWarehouse) TableName() string {
-	return "user_warehouse"
-}

+ 11 - 5
app/admin/model/warehouse.go

@@ -5,15 +5,21 @@ import model2 "cold-logistics/common/model"
 // 仓库
 type Warehouse struct {
 	model2.Model
-	Name     string          `json:"name" gorm:"size:128"`                                 // 商品名称
-	Sn       string          `json:"sn" gorm:"size:128"`                                   // sn
-	Address  string          `json:"address" gorm:"size:255;"`                             // 地址
-	Status   string          `json:"status" gorm:"size:4;not null;default:'2';comment:状态"` // 1-停用 2-正启用
-	UserList []UserWarehouse `json:"userList" gorm:"-"`
+	Name    string      `json:"name" gorm:"size:128"`                                 // 商品名称
+	Sn      string      `json:"sn" gorm:"size:128"`                                   // sn
+	Address string      `json:"address" gorm:"size:255;"`                             // 地址
+	Status  string      `json:"status" gorm:"size:4;not null;default:'2';comment:状态"` // 1-停用 2-正启用
+	UserId  int         `json:"userId" gorm:"size:255;"`                              // 仓管id
+	User    SysUserOmit `json:"user"`
 	model2.ControlBy
 	model2.ModelTime
 	model2.DeptBy
 }
+type WarehouseOmit struct {
+	Id   int    `json:"id,omitempty"`   // 主键编码
+	Name string `json:"name,omitempty"` // 商品名称
+	Sn   string `json:"sn,omitempty"`   // sn
+}
 
 func (Warehouse) TableName() string {
 	return "warehouse"

+ 61 - 0
app/admin/model/waybill.go

@@ -0,0 +1,61 @@
+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 // 已签收
+	WaybillStatusMap          = map[int]string{
+		WaybillStatusWaitDelivery: "待派单",
+		WaybillStatusWaitTruck:    "待装车",
+		WaybillStatusWaitStorage:  "待入库",
+		WaybillStatusTruck:        "已装车",
+		WaybillStatusStorage:      "已入库",
+		WaybillStatusReceipt:      "已签收",
+		WaybillStatusTruckOut:     "已下车",
+		WaybillStatusStorageOut:   "已出库",
+	}
+)
+
+// 运单
+type Waybill struct {
+	model2.Model
+	WaybillNo               string      `json:"waybillNo"  gorm:"size:128"`               //单号
+	Status                  int         `json:"status"  gorm:"size:128"`                  //订单状态:1待派单 2待装车 3待入库 4已装车 5已入库 6已下车 7已出库 8已签收
+	SenderAddressId         int         `json:"senderAddressId"  gorm:"size:128"`         //发货地址Id
+	SenderAddressDetails    string      `json:"senderAddressDetails"  gorm:"size:128"`    //发货地址详情
+	SenderAddressName       string      `json:"senderAddressName"  gorm:"size:128"`       //发货地址名称
+	SenderAddressPhone      string      `json:"senderAddressPhone"  gorm:"size:128"`      //发货地址电话
+	ConsigneeAddressId      int         `json:"consigneeAddressId"  gorm:"size:128"`      //收货地址id
+	ConsigneeAddressDetails string      `json:"consigneeAddressDetails"  gorm:"size:128"` //收发货地址详情
+	ConsigneeAddressName    string      `json:"consigneeAddressName"  gorm:"size:128"`    //收发货地址名称
+	ConsigneeAddressPhone   string      `json:"consigneeAddressPhone"  gorm:"size:128"`   //收发货地址电话
+	CargoType               string      `json:"cargoType"  gorm:"size:128"`               //货物类型
+	TemperatureInterval     string      `json:"temperatureInterval"  gorm:"size:128"`     //温度要求
+	DeliveryCondition       string      `json:"deliveryCondition"  gorm:"size:128"`       //配送要求
+	Remark                  string      `json:"remark"  gorm:"size:128"`                  //运输备注
+	CustomerId              int         `json:"customerId" gorm:"size:4"`                 //下单客户id
+	CustomerName            string      `json:"customerName" gorm:"size:128"`             //下单客户名称
+	OrderTime               model2.Time `json:"orderTime"  gorm:"size:128"`               //签收时间
+	PrintUserId             int         `json:"printUserId"  gorm:"size:128"`             //打印人id
+	ReceiptTime             model2.Time `json:"receiptTime"  gorm:"size:128"`             //签收时间
+	WarehouseId             int         `json:"warehouseId"  gorm:"size:128"`             // 仓库id
+	CarId                   int         `json:"carId"  gorm:"size:128"`                   // 仓库id
+
+	Freight      float64 `json:"freight"  gorm:"size:9"`      //运费
+	LatestLogId  int     `json:"latestLogId"  gorm:"size:9"`  //最近一次定位
+	LatestTaskId int     `json:"latestTaskId"  gorm:"size:9"` //最近一次任务Id
+	model2.ControlBy
+	model2.ModelTime
+	model2.DeptBy
+}
+
+func (Waybill) TableName() string {
+	return "waybill"
+}

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

@@ -0,0 +1,24 @@
+package model
+
+import model2 "cold-logistics/common/model"
+
+// 运单物流
+type WaybillLogistics struct {
+	model2.Model
+	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
+	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;"`         // 纬度
+	Warehouse   WarehouseOmit `json:"warehouse"`
+	Car         CarOmit       `json:"car"`
+	model2.ControlBy
+	model2.ModelTime
+	model2.DeptBy
+}
+
+func (WaybillLogistics) TableName() string {
+	return "waybill_logistics"
+}

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

@@ -0,0 +1,24 @@
+package model
+
+import model2 "cold-logistics/common/model"
+
+// 运单任务
+type WaybillTask struct {
+	model2.Model
+	WaybillNo   string        `json:"waybillNo"  gorm:"size:128"`   // 单号
+	WarehouseId int           `json:"warehouseId"  gorm:"size:128"` // 仓库id
+	CarId       int           `json:"carId"  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"`
+	model2.ControlBy
+	model2.ModelTime
+	model2.DeptBy
+}
+
+func (WaybillTask) TableName() string {
+	return "waybill_task"
+}

+ 31 - 0
app/admin/router/customer.go

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

+ 0 - 28
app/admin/router/sys_dept.go

@@ -1,28 +0,0 @@
-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, registerCompanyRouter)
-}
-
-// 需认证的路由代码
-func registerCompanyRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
-	cont := controller.CompanyController{}
-
-	r := v1.Group("/company").Use(authMiddleware.MiddlewareFunc()).Use(actions.PermissionAction())
-	{
-		r.GET("", cont.GetPage)
-		r.GET("/:id", cont.Get)
-		r.POST("", cont.Insert)
-		r.PUT("", cont.Update)
-		r.DELETE("", cont.Delete)
-
-	}
-
-}

+ 0 - 6
app/admin/router/sys_user.go

@@ -2,7 +2,6 @@ package router
 
 import (
 	"cold-logistics/common/actions"
-	"cold-logistics/common/middleware"
 	"github.com/gin-gonic/gin"
 
 	"cold-logistics/app/admin/controller"
@@ -37,11 +36,6 @@ func registerSysUserRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddle
 
 	}
 
-	r3 := v1.Group("/newest-token").Use(middleware.AuthCheckService())
-	{
-		r3.GET("/:userId", cont.GetNewestToken)
-	}
-
 }
 func registerSysUserRouter2(v1 *gin.RouterGroup) {
 	cont := controller.SysUser{}

+ 31 - 0
app/admin/router/waybill.go

@@ -0,0 +1,31 @@
+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, registerWaybillRouter)
+}
+
+// 派费管理
+// 需认证的路由代码
+func registerWaybillRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
+	cont := controller.WaybillController{}
+	r := v1.Group("/waybill").Use(authMiddleware.MiddlewareFunc()).Use(actions.PermissionAction())
+	{
+		r.GET("", cont.GetPage)
+		r.GET("/:id", cont.Get)
+		r.POST("", cont.Insert)
+		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.CarIn)              // 出库
+	}
+}

+ 40 - 13
app/admin/service/car.go

@@ -37,11 +37,11 @@ func (e *Car) GetPage(c *dto.CarGetPageReq, list *[]model.Car, count *int64, p *
 }
 
 // Get 获取Car对象
-func (e *Car) Get(d *dto.CarGetReq, warehouseModel *model.Car, p *actions.DataPermission) error {
+func (e *Car) Get(d *dto.CarGetReq, carModel *model.Car, p *actions.DataPermission) error {
 	err := e.Orm.
-		Scopes(actions.Permission(warehouseModel.TableName(), p)).
+		Scopes(actions.Permission(carModel.TableName(), p)).
 		Preload("User").
-		First(warehouseModel, d.GetId()).Error
+		First(carModel, d.GetId()).Error
 	if err != nil {
 		e.Log.Errorf("db error: %s", err)
 		if errors.Is(err, gorm.ErrRecordNotFound) {
@@ -90,6 +90,18 @@ func (e *Car) Insert(c *dto.CarInsertReq) error {
 		return err
 	}
 
+	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)
 	err = tx.Create(&data).Error
@@ -116,10 +128,10 @@ func (e *Car) Update(c *dto.CarUpdateReq, p *actions.DataPermission) error {
 		}
 	}()
 
-	var warehouseModel = model.Car{}
+	var carModel = model.Car{}
 	// 查询仓库是否存在
-	err = e.Orm.Scopes(actions.Permission(warehouseModel.TableName(), p)).
-		First(&warehouseModel, c.GetId()).Error
+	err = e.Orm.Scopes(actions.Permission(carModel.TableName(), p)).
+		First(&carModel, c.GetId()).Error
 	if err != nil {
 		e.Log.Errorf("db error: %s", err)
 		if errors.Is(err, gorm.ErrRecordNotFound) {
@@ -128,14 +140,29 @@ func (e *Car) Update(c *dto.CarUpdateReq, p *actions.DataPermission) error {
 		return global.UpdateFailedErr
 	}
 
-	c.Generate(&warehouseModel)
-	err = tx.Save(&warehouseModel).Error
+	if carModel.Sn != c.Sn {
+		var k int64
+		var data = model.Car{}
+		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(&carModel)
+	err = tx.Save(&carModel).Error
 	if err != nil {
 		e.Log.Errorf("db error: %s", err)
 		return global.UpdateFailedErr
 	}
 
-	c.Id = warehouseModel.Id
+	c.Id = carModel.Id
 	return nil
 }
 
@@ -152,11 +179,11 @@ func (e *Car) Remove(c *dto.CarDeleteReq, p *actions.DataPermission) error {
 		}
 	}()
 
-	var warehouseModel model.Car
+	var carModel model.Car
 
 	// 查询仓库是否存在
-	err = e.Orm.Scopes(actions.Permission(warehouseModel.TableName(), p)).
-		First(&warehouseModel, c.GetId()).Error
+	err = e.Orm.Scopes(actions.Permission(carModel.TableName(), p)).
+		First(&carModel, c.GetId()).Error
 	if err != nil {
 		e.Log.Errorf("db error: %s", err)
 		if errors.Is(err, gorm.ErrRecordNotFound) {
@@ -165,7 +192,7 @@ func (e *Car) Remove(c *dto.CarDeleteReq, p *actions.DataPermission) error {
 		return global.DeleteFailedErr
 	}
 
-	db := tx.Delete(&warehouseModel)
+	db := tx.Delete(&carModel)
 
 	if err = db.Error; err != nil {
 		e.Log.Errorf("db error: %s", err)

+ 310 - 0
app/admin/service/customer.go

@@ -0,0 +1,310 @@
+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/pkg"
+	"gogs.baozhida.cn/zoie/OAuth-core/pkg/utils"
+	"gogs.baozhida.cn/zoie/OAuth-core/service"
+	"gorm.io/gorm"
+)
+
+type Customer struct {
+	service.Service
+}
+
+// GetPage 获取Customer列表
+func (e *Customer) GetPage(c *dto.CustomerGetPageReq, p *actions.DataPermission, list *[]model.SysUser, count *int64) error {
+	var err error
+	var data model.SysUser
+	var userList []model.SysUser
+
+	err = e.Orm.
+		Scopes(
+			cDto.MakeCondition(c.GetNeedSearch()),
+			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
+			actions.UserPermission(data.TableName(), p),
+		).
+		Where("user_type = ?", model.UserTypeCustomer).
+		Find(&userList).Limit(-1).Offset(-1).
+		Count(count).Error
+
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return global.GetFailedErr
+	}
+
+	*list = userList
+	return nil
+}
+
+// Get 获取Customer对象
+func (e *Customer) Get(d *dto.CustomerGetReq, p *actions.DataPermission, userModel *model.SysUser) error {
+	var data model.SysUser
+	//var post model.SysPost
+	err := e.Orm.Model(&data).
+		Scopes(actions.UserPermission(data.TableName(), p)).
+		First(userModel, 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 创建Customer对象
+func (e *Customer) Insert(c *dto.CustomerInsertReq) error {
+	var err error
+	tx := e.Orm.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	var dept model.SysDept
+	var deptCount int64
+	err = e.Orm.Model(&dept).Where("id = ?", c.DeptId).Count(&deptCount).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return global.CreateFailedErr
+	}
+	if deptCount == 0 {
+		err = errors.New("公司不存在!")
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+
+	var data model.SysUser
+	var i int64
+	err = e.Orm.Model(&data).Where("username = ?", c.Username).Count(&i).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return global.CreateFailedErr
+	}
+	if i > 0 {
+		err = errors.New("用户名已存在!")
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+
+	var uuid string
+	for {
+		uuid = utils.GetUUID()
+		var j int64
+		err = e.Orm.Model(&data).Where("uuid = ?", uuid).Count(&j).Error
+		if err != nil {
+			continue
+		}
+		if j == 0 {
+			break
+		}
+	}
+	c.Generate(&data)
+	data.Uuid = uuid
+	err = tx.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return global.CreateFailedErr
+	}
+	c.Id = data.Id
+
+	return nil
+}
+
+// Update 修改Customer对象
+func (e *Customer) Update(c *dto.CustomerUpdateReq, p *actions.DataPermission) error {
+	var err error
+	tx := e.Orm.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+	var userModel model.SysUser
+	err = e.Orm.
+		Scopes(actions.UserPermission(userModel.TableName(), p)).
+		First(&userModel, 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
+	}
+
+	// TODO 1.1.1.8更新用户信息
+	// TODO 1.1.1.10送气人员绑定资质信息
+	// TODO 1.1.1.11货车司机绑定资质信息
+
+	c.Generate(&userModel)
+	err = tx.Model(&userModel).Where("id = ?", &userModel.Id).
+		Omit("password", "salt").Updates(&userModel).Error
+	if err != nil {
+		if errors.Is(err, model.ErrForbidUpdateSysRole) {
+			return model.ErrForbidUpdateSysRole
+		}
+		e.Log.Errorf("db error: %s", err)
+		return global.UpdateFailedErr
+	}
+	return nil
+}
+
+// UpdateStatus 更新用户状态
+func (e *Customer) UpdateStatus(c *dto.UpdateCustomerStatusReq, p *actions.DataPermission) error {
+	var userModel model.SysUser
+	err := e.Orm.
+		Scopes(actions.UserPermission(userModel.TableName(), p)).
+		First(&userModel, 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
+	}
+	err = e.Orm.Table(userModel.TableName()).Where("id = ? ", c.Id).Updates(c).Error
+	if err != nil {
+		if errors.Is(err, model.ErrForbidUpdateSysRole) {
+			return model.ErrForbidUpdateSysRole
+		}
+		e.Log.Errorf("db error: %s", err)
+		return global.UpdateFailedErr
+	}
+	return nil
+}
+
+// ResetPwd 重置用户密码
+func (e *Customer) ResetPwd(c *dto.ResetCustomerPwdReq, p *actions.DataPermission) error {
+	var userModel model.SysUser
+	err := e.Orm.
+		Scopes(actions.UserPermission(userModel.TableName(), p)).
+		First(&userModel, 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(&userModel)
+	err = e.Orm.Omit("username", "nick_name", "phone", "role_id", "avatar", "sex").Save(&userModel).Error
+	if err != nil {
+		if errors.Is(err, model.ErrForbidUpdateSysRole) {
+			return model.ErrForbidUpdateSysRole
+		}
+		e.Log.Errorf("db error: %s", err)
+		return global.UpdateFailedErr
+	}
+	return nil
+}
+
+// Remove 删除Customer
+func (e *Customer) Remove(c *dto.CustomerDeleteReq, p *actions.DataPermission) error {
+	var err error
+	tx := e.Orm.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+	var data model.SysUser
+	db := e.Orm.Model(&data).
+		Scopes(actions.UserPermission(data.TableName(), p)).
+		Find(&data, c.GetId())
+	if err = db.Error; err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	if db.RowsAffected == 0 {
+		return global.DeleteNotFoundOrNoPermissionErr
+	}
+
+	var car model.Car
+	var j int64
+	err = e.Orm.Model(&car).Where("user_id = ?", c.GetId()).Count(&j).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return global.CreateFailedErr
+	}
+	if j > 0 {
+		err = errors.New("该用户已绑定车辆,禁止删除!")
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+
+	if err := tx.Delete(&data, c.GetId()).Error; err != nil {
+		if errors.Is(err, model.ErrForbidDeleteSysRole) {
+			return model.ErrForbidDeleteSysRole
+		}
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	return nil
+}
+
+// UpdatePwd 修改Customer对象密码
+func (e *Customer) UpdatePwd(id int, oldPassword, newPassword string) error {
+	var err error
+
+	if newPassword == "" {
+		return nil
+	}
+	c := &model.SysUser{}
+
+	err = e.Orm.Model(c).
+		Select("id", "password", "salt").
+		First(c, id).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return global.UpdateNotFoundOrNoPermissionErr
+		}
+		return errors.New("密码修改失败")
+	}
+	var ok bool
+	ok, err = pkg.CompareHashAndPassword(c.Password, oldPassword)
+	if err != nil {
+		e.Log.Errorf("CompareHashAndPassword error, %s", err.Error())
+		return errors.New("密码修改失败")
+	}
+	if !ok {
+		err = errors.New("incorrect Password")
+		e.Log.Warnf("user[%d] %s", id, err.Error())
+		return err
+	}
+	c.Password = newPassword
+	db := e.Orm.Model(c).Where("id = ?", id).
+		Select("Password", "Salt").
+		Updates(c)
+	if err = db.Error; err != nil {
+		if errors.Is(err, model.ErrForbidUpdateSysRole) {
+			return model.ErrForbidUpdateSysRole
+		}
+		e.Log.Errorf("db error: %s", err)
+		return errors.New("密码修改失败")
+	}
+	return nil
+}
+
+func (e *Customer) GetProfile(c *dto.CustomerById, user *model.SysUser) error {
+	err := e.Orm.First(user, c.GetId()).Preload("Dept").Error
+	if err != nil {
+		return err
+	}
+
+	return nil
+}

+ 2 - 1
app/admin/service/dto/car.go

@@ -8,7 +8,8 @@ import (
 
 type CarGetPageReq struct {
 	dto.Pagination `search:"-"`
-	CarNo          string `form:"carNo" search:"type:contains;column:car_no;table:car"` // 商品名称
+	CarNo          string `form:"carNo" search:"type:contains;column:car_no;table:car"` // 车牌号
+	Sn             string `form:"sn" search:"type:contains;column:sn;table:car"`        // sn
 	CarOrder
 }
 

+ 192 - 0
app/admin/service/dto/customer.go

@@ -0,0 +1,192 @@
+package dto
+
+import (
+	"cold-logistics/app/admin/model"
+	dto2 "cold-logistics/common/dto"
+	model2 "cold-logistics/common/model"
+)
+
+type CustomerGetPageReq struct {
+	dto2.Pagination `search:"-"`
+	Username        string `form:"username" search:"type:contains;column:username;table:sys_user" comment:"用户名"`
+	Name            string `form:"name" search:"type:contains;column:nick_name;table:sys_user" comment:"昵称"`
+	Type            int    `form:"type" search:"type:exact;column:type;table:sys_user" comment:"状态"`
+	CustomerOrder
+}
+type CustomerOrder struct {
+	//UserIdOrder    string `search:"type:order;column:id;table:sys_user" form:"userIdOrder"`
+	//UsernameOrder  string `search:"type:order;column:username;table:sys_user" form:"usernameOrder"`
+	//StatusOrder    string `search:"type:order;column:status;table:sys_user" form:"statusOrder"`
+	CreatedAtOrder string `search:"type:order;column:created_at;table:sys_user" form:"createdAtOrder" default:"desc"`
+}
+
+func (m *CustomerGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type ResetCustomerPwdReq struct {
+	Id               int    `json:"id" example:"1" vd:"$>0"`                 // 用户ID
+	Password         string `json:"password" example:"123456" vd:"len($)>0"` // 密码
+	model2.ControlBy `swaggerignore:"true"`
+}
+
+func (s *ResetCustomerPwdReq) GetId() interface{} {
+	return s.Id
+}
+
+func (s *ResetCustomerPwdReq) Generate(userModel *model.SysUser) {
+	if s.Id != 0 {
+		userModel.Id = s.Id
+	}
+	userModel.Password = s.Password
+	if s.ControlBy.UpdateBy != 0 {
+		userModel.UpdateBy = s.UpdateBy
+	}
+	if s.ControlBy.CreateBy != 0 {
+		userModel.CreateBy = s.CreateBy
+	}
+}
+
+type UpdateCustomerStatusReq struct {
+	Id               int    `json:"id" example:"1" vd:"$>0"`          // 用户ID
+	Status           string `json:"status" example:"2" vd:"len($)>0"` // 状态 1-停用 2-正常
+	model2.ControlBy `swaggerignore:"true"`
+}
+
+func (s *UpdateCustomerStatusReq) GetId() interface{} {
+	return s.Id
+}
+
+func (s *UpdateCustomerStatusReq) Generate(userModel *model.SysUser) {
+	if s.Id != 0 {
+		userModel.Id = s.Id
+	}
+	userModel.Status = s.Status
+	if s.ControlBy.UpdateBy != 0 {
+		userModel.UpdateBy = s.UpdateBy
+	}
+	if s.ControlBy.CreateBy != 0 {
+		userModel.CreateBy = s.CreateBy
+	}
+}
+
+type CustomerInsertReq struct {
+	Id               int    `json:"id" swaggerignore:"true" comment:"用户ID"`                    // 用户ID
+	Username         string `json:"username" example:"username" vd:"@:len($)>0;msg:'用户名不能为空'"` // 用户名
+	Password         string `json:"password" example:"123456" vd:"@:len($)>5;msg:'密码格式不正确'"`   // 密码
+	Name             string `json:"name" vd:"@:len($)>0;msg:'姓名不能为空'"`                         // 姓名
+	Phone            string `json:"phone"`                                                     // 手机号
+	RoleId           int    `json:"roleId" example:"1" swaggerignore:"true"`                   // 角色id
+	DeptId           int    `json:"deptId" example:"1"`                                        // 机构id
+	Status           string `json:"status" example:"2" swaggerignore:"true"`                   // 状态 	// 货车司机绑定《道路运输从业人员从业资格证》信息
+	Type             int    `json:"type" example:"2"`                                          // 管理员1 仓管2 司机3
+	model2.ControlBy `swaggerignore:"true"`
+}
+
+// SetCreateBy 设置创建人id
+func (e *CustomerInsertReq) SetDeptId(deptId int) {
+	e.DeptId = deptId
+}
+
+func (s *CustomerInsertReq) Generate(userModel *model.SysUser) {
+	if s.Id != 0 {
+		userModel.Id = s.Id
+	}
+	userModel.Username = s.Username
+	userModel.Password = s.Password
+	userModel.NickName = s.Name
+	userModel.Phone = s.Phone
+	userModel.DeptId = s.DeptId
+	userModel.Status = "2"
+	userModel.Type = 0
+	userModel.UserType = model.UserTypeCustomer
+
+	if s.ControlBy.UpdateBy != 0 {
+		userModel.UpdateBy = s.UpdateBy
+	}
+	if s.ControlBy.CreateBy != 0 {
+		userModel.CreateBy = s.CreateBy
+	}
+}
+
+func (s *CustomerInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type CustomerUpdateReq struct {
+	Id               int    `json:"id"  comment:"用户ID"`                // 用户ID
+	Name             string `json:"name" vd:"@:len($)>0;msg:'姓名不能为空'"` // 姓名
+	Phone            string `json:"phone" swaggerignore:"true"`        // 手机号
+	model2.ControlBy `swaggerignore:"true"`
+}
+
+func (s *CustomerUpdateReq) Generate(userModel *model.SysUser) {
+	if s.Id != 0 {
+		userModel.Id = s.Id
+	}
+	userModel.NickName = s.Name
+	userModel.Phone = s.Phone
+	if s.ControlBy.UpdateBy != 0 {
+		userModel.UpdateBy = s.UpdateBy
+	}
+	if s.ControlBy.CreateBy != 0 {
+		userModel.CreateBy = s.CreateBy
+	}
+}
+
+func (s *CustomerUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+type CustomerGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *CustomerGetReq) GetId() interface{} {
+	return s.Id
+}
+
+type CustomerDeleteReq struct {
+	Id               int `json:"id"`
+	model2.ControlBy `swaggerignore:"true"`
+}
+
+func (s *CustomerDeleteReq) GetId() interface{} {
+	return s.Id
+}
+
+type CustomerById struct {
+	dto2.ObjectById
+	model2.ControlBy `swaggerignore:"true"`
+}
+
+func (s *CustomerById) GetIds() interface{} {
+	return s.Ids
+}
+
+func (s *CustomerById) GetId() interface{} {
+	if len(s.Ids) > 0 {
+		s.Ids = append(s.Ids, s.Id)
+		return s.Ids
+	}
+	return s.Id
+}
+
+func (s *CustomerById) GenerateM() (model2.ActiveRecord, error) {
+	return &model.SysUser{}, nil
+}
+
+// PassWord 密码
+type CustomerPassWord struct {
+	NewPassword string `json:"newPassword" example:"123456" vd:"len($)>0"`   // 新密码
+	OldPassword string `json:"oldPassword" example:"12345678" vd:"len($)>0"` // 旧密码
+}
+
+type CustomerGetSMSVerifyCodeReq struct {
+	Phone string `form:"phone" example:"13912345678"` //手机号
+}
+
+type CustomerWxLoginReq struct {
+	Phone string `json:"phone"` // 手机号
+	Code  string `json:"code"`  // 密码
+}

+ 2 - 26
app/admin/service/dto/sys_user.go

@@ -24,26 +24,6 @@ func (m *SysUserGetPageReq) GetNeedSearch() interface{} {
 	return *m
 }
 
-type SysUserGetDeliveryPageReq struct {
-	dto2.Pagination `search:"-"`
-	Name            string `form:"name" search:"type:contains;column:nick_name;table:sys_user" comment:"昵称"`
-	StoreId         string `form:"storeId" search:"type:exact;column:dept_id;table:sys_user" comment:"门店id"`
-}
-
-func (m *SysUserGetDeliveryPageReq) GetNeedSearch() interface{} {
-	return *m
-}
-
-type SysUserGetCountReq struct {
-	RoleIds []int `form:"roleId" search:"type:in;column:role_id;table:sys_user" comment:"角色ID"`
-	DeptIds []int `form:"deptId" search:"type:in;column:dept_id;table:sys_user" comment:"部门ID"`
-	PostIds []int `form:"postId" search:"type:in;column:post_id;table:sys_user" comment:"岗位ID"`
-}
-
-func (m *SysUserGetCountReq) GetNeedSearch() interface{} {
-	return *m
-}
-
 type ResetSysUserPwdReq struct {
 	Id               int    `json:"id" example:"1" vd:"$>0"`                 // 用户ID
 	Password         string `json:"password" example:"123456" vd:"len($)>0"` // 密码
@@ -115,6 +95,7 @@ func (s *SysUserInsertReq) Generate(userModel *model.SysUser) {
 	userModel.RoleId = s.RoleId
 	userModel.Status = "2"
 	userModel.Type = s.Type
+	userModel.UserType = model.UserTypeCustomer
 
 	if s.ControlBy.UpdateBy != 0 {
 		userModel.UpdateBy = s.UpdateBy
@@ -131,7 +112,6 @@ func (s *SysUserInsertReq) GetId() interface{} {
 type SysUserUpdateReq struct {
 	Id   int    `json:"id"  comment:"用户ID"`                // 用户ID
 	Name string `json:"name" vd:"@:len($)>0;msg:'姓名不能为空'"` // 姓名
-	Type int    `json:"type" example:"2"`                  // 管理员1 仓管2 司机3
 
 	model2.ControlBy `swaggerignore:"true"`
 }
@@ -141,7 +121,6 @@ func (s *SysUserUpdateReq) Generate(userModel *model.SysUser) {
 		userModel.Id = s.Id
 	}
 	userModel.NickName = s.Name
-	userModel.Type = s.Type
 	if s.ControlBy.UpdateBy != 0 {
 		userModel.UpdateBy = s.UpdateBy
 	}
@@ -193,7 +172,7 @@ func (s *SysUserById) GenerateM() (model2.ActiveRecord, error) {
 }
 
 // PassWord 密码
-type PassWord struct {
+type SysUserPassWord struct {
 	NewPassword string `json:"newPassword" example:"123456" vd:"len($)>0"`   // 新密码
 	OldPassword string `json:"oldPassword" example:"12345678" vd:"len($)>0"` // 旧密码
 }
@@ -201,6 +180,3 @@ type PassWord struct {
 type SysUserGetSMSVerifyCodeReq struct {
 	Phone string `form:"phone" example:"13912345678"` //手机号
 }
-type GetNewestTokenReq struct {
-	UserId int64 `uri:"userId" example:"1"` //手机号
-}

+ 6 - 3
app/admin/service/dto/warehouse.go

@@ -8,7 +8,8 @@ import (
 
 type WarehouseGetPageReq struct {
 	dto.Pagination `search:"-"`
-	Name           string `form:"name" search:"type:contains;column:name;table:warehouse"` // 商品名称
+	Name           string `form:"name" search:"type:contains;column:name;table:warehouse"` // 仓库名称
+	Sn             string `form:"sn" search:"type:contains;column:sn;table:warehouse"`     // sn
 	WarehouseOrder
 }
 
@@ -26,7 +27,7 @@ type WarehouseInsertReq struct {
 	Sn               string `json:"sn"`                                   // sn
 	Address          string `json:"address"`                              // 地址
 	Status           string `json:"status"`                               // 1-停用 2-正启用
-	UserIds          []int  `json:"userIds"`                              // 绑定的用户id
+	UserId           int    `json:"userId"`                               // 绑定的用户id
 	common.ControlBy `swaggerignore:"true"`
 	common.DeptBy    `swaggerignore:"true"`
 }
@@ -39,6 +40,7 @@ func (s *WarehouseInsertReq) Generate(model *model.Warehouse) {
 	model.Sn = s.Sn
 	model.Status = s.Status
 	model.Address = s.Address
+	model.UserId = s.UserId
 	if s.ControlBy.UpdateBy != 0 {
 		model.UpdateBy = s.UpdateBy
 	}
@@ -60,7 +62,7 @@ type WarehouseUpdateReq struct {
 	Sn               string `json:"sn"`              // sn
 	Address          string `json:"address"`         // 地址
 	Status           string `json:"status"`          // 1-停用 2-正启用
-	UserIds          []int  `json:"userIds"`         // 绑定的用户id
+	UserId           int    `json:"userId"`          // 绑定的用户id
 	common.ControlBy `swaggerignore:"true"`
 }
 
@@ -72,6 +74,7 @@ func (s *WarehouseUpdateReq) Generate(model *model.Warehouse) {
 	model.Sn = s.Sn
 	model.Address = s.Address
 	model.Status = s.Status
+	model.UserId = s.UserId
 	if s.ControlBy.UpdateBy != 0 {
 		model.UpdateBy = s.UpdateBy
 	}

+ 160 - 0
app/admin/service/dto/waybill.go

@@ -0,0 +1,160 @@
+package dto
+
+import (
+	"cold-logistics/app/admin/model"
+	"cold-logistics/common/dto"
+	common "cold-logistics/common/model"
+	model2 "cold-logistics/common/model"
+	"time"
+)
+
+// 运单
+
+type WaybillGetPageReq struct {
+	dto.Pagination `search:"-"`
+	WaybillNo      string `form:"waybillNo" search:"type:contains;column:waybill_no;table:waybill"`                      // 运单编号
+	Status         int    `form:"status" search:"type:exact;column:status;table:waybill"`                                // 状态
+	CustomerId     string `form:"customerId" search:"type:exact;column:customer_id;table:waybill"  swaggerignore:"true"` // 客户id
+	WaybillOrder
+}
+
+type WaybillOrder struct {
+	CreatedAtOrder string `search:"type:order;column:created_at;table:waybill" form:"createdAtOrder" default:"desc"`
+}
+
+func (m *WaybillGetPageReq) GetNeedSearch() interface{} {
+	return *m
+}
+
+type WaybillInsertReq struct {
+	Id                      int    `json:"id" comment:"编码" swaggerignore:"true"` // 编码
+	No                      string `json:"no" swaggerignore:"true"`              //单号
+	Status                  int    `json:"status" swaggerignore:"true"`          //订单状态:1-待处理;102-待装车 103-运输中 104-已签收
+	SenderAddressDetails    string `json:"senderAddressDetails"`                 //发货地址详情
+	SenderAddressName       string `json:"senderAddressName"`                    //发货地址名称
+	SenderAddressPhone      string `json:"senderAddressPhone"`                   //发货地址电话
+	ConsigneeAddressDetails string `json:"consigneeAddressDetails"`              //收发货地址详情
+	ConsigneeAddressName    string `json:"consigneeAddressName"`                 //收发货地址名称
+	ConsigneeAddressPhone   string `json:"consigneeAddressPhone"`                //收发货地址电话
+	CargoType               string `json:"cargoType"`                            //货物类型
+	TemperatureInterval     string `json:"temperatureInterval"`                  //温度要求
+	DeliveryCondition       string `json:"deliveryCondition"`                    //配送要求
+	Remark                  string `json:"remark"`                               //运输备注
+	CustomerId              int    `json:"customerId"`                           //下单客户id
+	CustomerName            string `json:"customerName"`                         //下单客户名称
+	model2.ControlBy        `swaggerignore:"true"`
+	model2.DeptBy           `swaggerignore:"true"`
+}
+
+func (s *WaybillInsertReq) Generate(m *model.Waybill) {
+	if s.Id != 0 {
+		m.Id = s.Id
+	}
+	m.Status = 1
+	m.SenderAddressDetails = s.SenderAddressDetails
+	m.SenderAddressName = s.SenderAddressName
+	m.SenderAddressPhone = s.SenderAddressPhone
+	m.ConsigneeAddressDetails = s.ConsigneeAddressDetails
+	m.ConsigneeAddressName = s.ConsigneeAddressName
+	m.ConsigneeAddressPhone = s.ConsigneeAddressPhone
+	m.CargoType = s.CargoType
+	m.TemperatureInterval = s.TemperatureInterval
+	m.DeliveryCondition = s.DeliveryCondition
+	m.Remark = s.Remark
+	m.CustomerId = s.CustomerId
+	m.CustomerName = s.CustomerName
+	m.OrderTime = model2.Time(time.Now())
+
+	if s.ControlBy.UpdateBy != 0 {
+		m.UpdateBy = s.UpdateBy
+	}
+	if s.ControlBy.CreateBy != 0 {
+		m.CreateBy = s.CreateBy
+	}
+	if s.DeptBy.DeptId != 0 {
+		m.DeptId = s.DeptId
+	}
+}
+
+func (s *WaybillInsertReq) GetId() interface{} {
+	return s.Id
+}
+
+type WaybillUpdateReq struct {
+	Id                      int    `json:"id" comment:"编码" swaggerignore:"true"` // 编码
+	SenderAddressDetails    string `json:"senderAddressDetails"`                 //发货地址详情
+	SenderAddressName       string `json:"senderAddressName"`                    //发货地址名称
+	SenderAddressPhone      string `json:"senderAddressPhone"`                   //发货地址电话
+	ConsigneeAddressDetails string `json:"consigneeAddressDetails"`              //收发货地址详情
+	ConsigneeAddressName    string `json:"consigneeAddressName"`                 //收发货地址名称
+	ConsigneeAddressPhone   string `json:"consigneeAddressPhone"`                //收发货地址电话
+	CargoType               string `json:"cargoType"`                            //货物类型
+	TemperatureInterval     string `json:"temperatureInterval"`                  //温度要求
+	DeliveryCondition       string `json:"deliveryCondition"`                    //配送要求
+	Remark                  string `json:"remark"`                               //运输备注
+	CustomerName            string `json:"customerName"`                         //下单客户名称
+	model2.ControlBy        `swaggerignore:"true"`
+	model2.DeptBy           `swaggerignore:"true"`
+}
+
+func (s *WaybillUpdateReq) Generate(m *model.Waybill) {
+	if s.Id != 0 {
+		m.Id = s.Id
+	}
+	m.SenderAddressDetails = s.SenderAddressDetails
+	m.SenderAddressName = s.SenderAddressName
+	m.SenderAddressPhone = s.SenderAddressPhone
+	m.ConsigneeAddressDetails = s.ConsigneeAddressDetails
+	m.ConsigneeAddressName = s.ConsigneeAddressName
+	m.ConsigneeAddressPhone = s.ConsigneeAddressPhone
+	m.CargoType = s.CargoType
+	m.TemperatureInterval = s.TemperatureInterval
+	m.DeliveryCondition = s.DeliveryCondition
+	m.Remark = s.Remark
+	m.CustomerName = s.CustomerName
+
+	if s.ControlBy.UpdateBy != 0 {
+		m.UpdateBy = s.UpdateBy
+	}
+	if s.ControlBy.CreateBy != 0 {
+		m.CreateBy = s.CreateBy
+	}
+}
+
+func (s *WaybillUpdateReq) GetId() interface{} {
+	return s.Id
+}
+
+type WaybillDeliveryReq struct {
+	WaybillIds       []int `json:"waybillIds" comment:"编码"`      // 运单id
+	Type             int   `json:"type"  gorm:"size:128"`        // 派单类型 3司机 2仓管
+	PrintUserId      int   `json:"printUserId"  gorm:"size:128"` // 制单人
+	model2.ControlBy `swaggerignore:"true"`
+	model2.DeptBy    `swaggerignore:"true"`
+}
+
+func (s *WaybillDeliveryReq) GetId() interface{} {
+	return s.WaybillIds
+}
+
+type WaybillGetReq struct {
+	Id int `uri:"id"`
+}
+
+func (s *WaybillGetReq) GetId() interface{} {
+	return s.Id
+}
+
+type WaybillDeleteReq struct {
+	Id               int `json:"id"`
+	common.ControlBy `swaggerignore:"true"`
+}
+
+func (s *WaybillDeleteReq) GetId() interface{} {
+	return s.Id
+}
+
+// 运单出入库/上下车
+type WaybillInOutReq struct {
+	WaybillNoList []string `json:"waybillNoList"  gorm:"size:128"` // 订单编号
+}

+ 2 - 79
app/admin/service/sys_user.go

@@ -28,6 +28,7 @@ func (e *SysUser) GetPage(c *dto.SysUserGetPageReq, p *actions.DataPermission, l
 				cDto.MakeCondition(c.GetNeedSearch()),
 				cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
 			).Where("create_by = ?", p.UserId).
+			Where("user_type = ?", model.UserTypeSys).
 			Find(&userList).Limit(-1).Offset(-1).
 			Count(count).Error
 	} else {
@@ -37,6 +38,7 @@ func (e *SysUser) GetPage(c *dto.SysUserGetPageReq, p *actions.DataPermission, l
 				cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
 				actions.UserPermission(data.TableName(), p),
 			).
+			Where("user_type = ?", model.UserTypeSys).
 			Find(&userList).Limit(-1).Offset(-1).
 			Count(count).Error
 	}
@@ -63,57 +65,6 @@ func (e *SysUser) GetPage(c *dto.SysUserGetPageReq, p *actions.DataPermission, l
 	return nil
 }
 
-// GetPage 获取送气员列表
-func (e *SysUser) GetDeliveryPage(c *dto.SysUserGetDeliveryPageReq, p *actions.DataPermission, list *[]model.SysUser, count *int64) error {
-	var err error
-	var data model.SysUser
-	var userList []model.SysUser
-
-	err = e.Orm.
-		Scopes(
-			cDto.MakeCondition(c.GetNeedSearch()),
-			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
-			actions.UserPermission(data.TableName(), p),
-		).Where("JSON_EXTRACT(prov_user, '$.userType') = 3 and JSON_EXTRACT(prov_user, '$.isorders') = 0").
-		Find(&userList).Limit(-1).Offset(-1).
-		Count(count).Error
-	if err != nil {
-		e.Log.Errorf("db error: %s", err)
-		return global.GetFailedErr
-	}
-
-	for i := 0; i < len(userList); i++ {
-		var dept model.SysDept
-		var role model.SysRole
-		//var post model.SysPost
-		err = e.Orm.First(&dept, userList[i].DeptId).Error
-		userList[i].Dept = dept
-
-		err = e.Orm.First(&role, userList[i].RoleId).Error
-		userList[i].Role = role
-
-		//err = e.Orm.First(&post, userList[i].PostId).Error
-		//userList[i].Post = post
-	}
-	*list = userList
-	return nil
-}
-
-func (e *SysUser) GetCount(c *dto.SysUserGetCountReq, count *int64) error {
-	var err error
-	var data model.SysUser
-	err = e.Orm.Model(&data).
-		Scopes(
-			cDto.MakeCondition(c.GetNeedSearch()),
-		).Count(count).Error
-	if err != nil {
-		e.Log.Errorf("db error: %s", err)
-		return global.GetFailedErr
-	}
-
-	return nil
-}
-
 // Get 获取SysUser对象
 func (e *SysUser) Get(d *dto.SysUserGetReq, p *actions.DataPermission, userModel *model.SysUser) error {
 	var data model.SysUser
@@ -141,30 +92,6 @@ func (e *SysUser) Get(d *dto.SysUserGetReq, p *actions.DataPermission, userModel
 
 	return nil
 }
-func (e *SysUser) GetByProvUserId(provUserId string, userModel *model.SysUser) error {
-	var data model.SysUser
-	var dept model.SysDept
-	//var role model.SysRole
-	//var post model.SysPost
-	err := e.Orm.Model(&data).Where("prov_user_id = ?", provUserId).Preload("Dept").First(userModel).Error
-	if err != nil {
-		e.Log.Errorf("db error: %s", err)
-		if errors.Is(err, gorm.ErrRecordNotFound) {
-			return global.GetNotFoundOrNoPermissionErr
-		}
-		return global.GetFailedErr
-	}
-	err = e.Orm.First(&dept, userModel.DeptId).Error
-	userModel.Dept = dept
-	//
-	//err = e.Orm.First(&role, userModel.RoleId).Error
-	//userModel.Role = role
-
-	//err = e.Orm.First(&post, userModel.PostId).Error
-	//userModel.Post = post
-
-	return nil
-}
 
 // Insert 创建SysUser对象
 func (e *SysUser) Insert(c *dto.SysUserInsertReq) error {
@@ -204,10 +131,6 @@ func (e *SysUser) Insert(c *dto.SysUserInsertReq) error {
 		return err
 	}
 
-	// TODO 1.1.1.7新增用户信息
-	// TODO 1.1.1.10送气人员绑定资质信息
-	// TODO 1.1.1.11货车司机绑定资质信息
-
 	var uuid string
 	for {
 		uuid = utils.GetUUID()

+ 48 - 63
app/admin/service/warehouse.go

@@ -26,6 +26,7 @@ func (e *Warehouse) GetPage(c *dto.WarehouseGetPageReq, list *[]model.Warehouse,
 			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
 			actions.Permission(data.TableName(), p),
 		).
+		Preload("User").
 		Find(list).Limit(-1).Offset(-1).
 		Count(count).Error
 	if err != nil {
@@ -39,6 +40,7 @@ func (e *Warehouse) GetPage(c *dto.WarehouseGetPageReq, list *[]model.Warehouse,
 func (e *Warehouse) Get(d *dto.WarehouseGetReq, warehouseModel *model.Warehouse, p *actions.DataPermission) error {
 	err := e.Orm.
 		Scopes(actions.Permission(warehouseModel.TableName(), p)).
+		Preload("User").
 		First(warehouseModel, d.GetId()).Error
 	if err != nil {
 		e.Log.Errorf("db error: %s", err)
@@ -47,13 +49,6 @@ func (e *Warehouse) Get(d *dto.WarehouseGetReq, warehouseModel *model.Warehouse,
 		}
 		return global.GetFailedErr
 	}
-	userWarehouse := make([]model.UserWarehouse, 0)
-	err = e.Orm.Model(&model.UserWarehouse{}).Where("warehouse_id = ?", d.GetId()).Preload("User").Find(&userWarehouse).Error
-	if err != nil {
-		e.Log.Errorf("db error: %s", err)
-		return global.GetFailedErr
-	}
-	warehouseModel.UserList = userWarehouse
 
 	return nil
 }
@@ -72,40 +67,50 @@ func (e *Warehouse) Insert(c *dto.WarehouseInsertReq) error {
 		}
 	}()
 
-	// 添加仓库
-	c.Generate(&data)
-	err = tx.Create(&data).Error
+	var i int64
+	err = tx.Model(&data).Where("name = ? and dept_id = ?", c.Name, c.DeptId).Count(&i).Error
 	if err != nil {
 		e.Log.Errorf("db error: %s", err)
 		return global.CreateFailedErr
 	}
-	c.Id = data.Id
-
-	// 添加用户和仓库的关联
-	var userList []model.SysUser
-	err = e.Orm.Where("id in (?) and dept_id = ?", c.UserIds, c.DeptId).Find(&userList).Error
+	if i > 0 {
+		err = errors.New("仓库名已存在!")
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+	var j int64
+	err = tx.Model(&data).Where("user_id = ?", c.UserId).Count(&j).Error
 	if err != nil {
-		return global.GetFailedErr
+		e.Log.Errorf("db error: %s", err)
+		return global.CreateFailedErr
 	}
-	if len(userList) == 0 {
-		return errors.New("用户不存在!")
+	if j > 0 {
+		err = errors.New("该用户已绑定其他仓库!")
+		e.Log.Errorf("db error: %s", err)
+		return err
 	}
 
-	var userWarehouseList []model.UserWarehouse
-	// 添加用户和仓库的关联
-	for _, v := range userList {
-		userWarehouseObj := model.UserWarehouse{
-			UserId:      v.Id,
-			WarehouseId: data.Id,
-		}
-		userWarehouseObj.SetCreateBy(c.CreateBy)
-		userWarehouseList = append(userWarehouseList, userWarehouseObj)
+	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
 	}
-	err = tx.Save(&userWarehouseList).Error
+	if k > 0 {
+		err = errors.New("该Sn已绑定其他仓库!")
+		e.Log.Errorf("db error: %s", err)
+		return err
+	}
+
+	// 添加仓库
+	c.Generate(&data)
+	err = tx.Create(&data).Error
 	if err != nil {
-		e.Log.Errorf("save userWarehouse userIds error, %s", err)
+		e.Log.Errorf("db error: %s", err)
 		return global.CreateFailedErr
 	}
+	c.Id = data.Id
+
 	return nil
 
 }
@@ -134,6 +139,20 @@ func (e *Warehouse) Update(c *dto.WarehouseUpdateReq, p *actions.DataPermission)
 		}
 		return global.UpdateFailedErr
 	}
+	if warehouseModel.Sn != c.Sn {
+		var k int64
+		var data = model.Warehouse{}
+		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(&warehouseModel)
 	err = tx.Save(&warehouseModel).Error
@@ -143,40 +162,6 @@ func (e *Warehouse) Update(c *dto.WarehouseUpdateReq, p *actions.DataPermission)
 	}
 
 	c.Id = warehouseModel.Id
-
-	// 删除用户和仓库的关联
-	err = tx.Where("warehouse_id = ?", warehouseModel.Id).Delete(&model.UserWarehouse{}).Error
-	if err != nil {
-		e.Log.Errorf("db error: %s", err)
-		return global.UpdateFailedErr
-	}
-
-	// 添加用户和仓库的关联
-	var userList []model.SysUser
-	err = e.Orm.Where("id in (?) and dept_id = ?", c.UserIds, warehouseModel.DeptId).Find(&userList).Error
-	if err != nil {
-		return global.GetFailedErr
-	}
-	if len(userList) == 0 {
-		return errors.New("用户不存在!")
-	}
-
-	var userWarehouseList []model.UserWarehouse
-	// 添加用户和仓库的关联
-	for _, v := range userList {
-		userWarehouseObj := model.UserWarehouse{
-			UserId:      v.Id,
-			WarehouseId: warehouseModel.Id,
-		}
-		userWarehouseObj.SetCreateBy(c.UpdateBy)
-		userWarehouseList = append(userWarehouseList, userWarehouseObj)
-	}
-	err = tx.Save(&userWarehouseList).Error
-	if err != nil {
-		e.Log.Errorf("save userWarehouse userIds error, %s", err)
-		return global.CreateFailedErr
-	}
-
 	return nil
 }
 

+ 637 - 0
app/admin/service/waybill.go

@@ -0,0 +1,637 @@
+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"
+	model2 "cold-logistics/common/model"
+	"cold-logistics/common/nats/nats_server"
+	"errors"
+	"fmt"
+	"gogs.baozhida.cn/zoie/OAuth-core/pkg/utils"
+	"gogs.baozhida.cn/zoie/OAuth-core/service"
+	"gorm.io/gorm"
+	"strings"
+	"time"
+)
+
+type Waybill struct {
+	service.Service
+}
+
+// GetPage 获取Waybill列表
+func (e *Waybill) GetPage(c *dto.WaybillGetPageReq, list *[]model.Waybill, count *int64, p *actions.DataPermission) error {
+	var err error
+	var data model.Waybill
+
+	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 获取Waybill对象
+func (e *Waybill) Get(d *dto.WaybillGetReq, waybillModel *model.Waybill, p *actions.DataPermission) error {
+	err := e.Orm.
+		Scopes(actions.Permission(waybillModel.TableName(), p)).
+		Preload("User").
+		First(waybillModel, 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 创建Waybill对象
+func (e *Waybill) Insert(c *dto.WaybillInsertReq) error {
+	var err error
+	var data model.Waybill
+
+	tx := e.Orm.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	var no string
+	for {
+		no = time.Now().Format("200601021504") + utils.GetRandString(6, "0123456789", 0)
+		var j int64
+		err = e.Orm.Model(&data).Where("waybill_no = ?", no).Count(&j).Error
+		if err != nil {
+			continue
+		}
+		if j == 0 {
+			break
+		}
+	}
+
+	// 添加运单
+	data.WaybillNo = no
+	c.Generate(&data)
+	err = tx.Create(&data).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return global.CreateFailedErr
+	}
+	c.Id = data.Id
+
+	return nil
+
+}
+
+// Update 修改Waybill对象
+func (e *Waybill) Update(c *dto.WaybillUpdateReq, 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 = e.Orm.Scopes(actions.Permission(waybillModel.TableName(), p)).
+		First(&waybillModel, 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(&waybillModel)
+	err = tx.Save(&waybillModel).Error
+	if err != nil {
+		e.Log.Errorf("db error: %s", err)
+		return global.UpdateFailedErr
+	}
+
+	c.Id = waybillModel.Id
+	return nil
+}
+func (e *Waybill) Delivery(c *dto.WaybillDeliveryReq, p *actions.DataPermission) error {
+	var err error
+
+	tx := e.Orm.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	for _, id := range c.WaybillIds {
+
+		var waybillModel = model.Waybill{}
+		// 查询运单是否存在
+		err = tx.Scopes(actions.Permission(waybillModel.TableName(), p)).
+			First(&waybillModel, id).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			if errors.Is(err, gorm.ErrRecordNotFound) {
+				return global.UpdateNotFoundOrNoPermissionErr
+			}
+			return global.UpdateFailedErr
+		}
+		if waybillModel.Status != model.WaybillStatusWaitDelivery {
+			return errors.New(fmt.Sprintf("运单状态为%s,禁止操作!", model.WaybillStatusMap[waybillModel.Status]))
+		}
+		if c.Type == model.SysUserTypeDriver {
+			waybillModel.Status = model.WaybillStatusWaitTruck
+		}
+		if c.Type == model.SysUserTypeWarehouse {
+			waybillModel.Status = model.WaybillStatusWaitStorage
+		}
+		waybillModel.PrintUserId = c.PrintUserId
+		err = tx.Save(&waybillModel).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return global.UpdateFailedErr
+		}
+	}
+
+	return nil
+}
+
+// Remove 删除Waybill
+func (e *Waybill) Remove(c *dto.WaybillDeleteReq, 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 = e.Orm.Scopes(actions.Permission(waybillModel.TableName(), p)).
+		First(&waybillModel, 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
+	}
+	if waybillModel.Status != model.WaybillStatusWaitDelivery && waybillModel.Status != model.WaybillStatusWaitTruck && waybillModel.Status != model.WaybillStatusWaitStorage {
+		return errors.New(fmt.Sprintf("运单状态为%s,禁止删除", model.WaybillStatusMap[waybillModel.Status]))
+	}
+
+	db := tx.Delete(&waybillModel)
+
+	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
+}
+
+func (e *Waybill) WarehouseIn(c *dto.WaybillInOutReq, p *actions.DataPermission) error {
+	var err error
+
+	tx := e.Orm.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+	// 查询仓库信息
+	var warehouse = model.Warehouse{}
+	// 查询运单是否存在
+	err = tx.Scopes(actions.Permission(warehouse.TableName(), p)).
+		Where("user_id = ?", p.UserId).
+		First(&warehouse).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.WarehouseId == warehouse.Id && waybillModel.Status == model.WaybillStatusStorage {
+			continue
+		}
+		waybillModel.Status = model.WaybillStatusStorage
+		waybillModel.WarehouseId = warehouse.Id
+		err = tx.Save(waybillModel).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New(fmt.Sprintf("保存运单信息失败:%s", err))
+		}
+		// 获取传感器信息
+		deviceSensorList, count, err := nats_server.Cold_CompanyDeviceSensor_List_ByKey(warehouse.Sn)
+		if err != nil || count == 0 {
+			return errors.New(fmt.Sprintf("查询设备定位信息失败:%s", err.Error()))
+		}
+		var lng, Lat string
+		if len(deviceSensorList[0].T_DeviceSensorData.T_site) > 0 {
+			site := strings.Split(deviceSensorList[0].T_DeviceSensorData.T_site, ",")
+			if len(site) == 2 {
+				lng = site[0]
+				Lat = site[1]
+			}
+		}
+
+		// 添加物流
+		Logistics := model.WaybillLogistics{
+			WaybillNo:   waybillNo,
+			Status:      model.WaybillStatusStorage,
+			WarehouseId: warehouse.Id,
+			UserId:      p.UserId,
+			Lng:         lng,
+			Lat:         Lat,
+			ControlBy: model2.ControlBy{
+				CreateBy: p.UserId,
+			},
+			DeptBy: model2.DeptBy{
+				DeptId: p.DeptId,
+			},
+		}
+		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,
+			WarehouseId: warehouse.Id,
+			UserId:      p.UserId,
+			Sn:          warehouse.Sn,
+			StartTime:   model2.Time(time.Now()),
+			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) WarehouseOut(c *dto.WaybillInOutReq, p *actions.DataPermission) error {
+	var err error
+
+	tx := e.Orm.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+	// 查询仓库信息
+	var warehouse = model.Warehouse{}
+	// 查询运单是否存在
+	err = tx.Scopes(actions.Permission(warehouse.TableName(), p)).
+		Where("user_id = ?", p.UserId).
+		First(&warehouse).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.WarehouseId != warehouse.Id {
+			return errors.New("请选择正确仓库出库!")
+		}
+
+		if waybillModel.WarehouseId == warehouse.Id && waybillModel.Status == model.WaybillStatusStorageOut {
+			continue
+		}
+		waybillModel.Status = model.WaybillStatusStorageOut
+		waybillModel.WarehouseId = warehouse.Id
+		err = tx.Save(waybillModel).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New(fmt.Sprintf("保存运单信息失败:%s", err))
+		}
+		// 获取传感器信息
+		deviceSensorList, count, err := nats_server.Cold_CompanyDeviceSensor_List_ByKey(warehouse.Sn)
+		if err != nil || count == 0 {
+			return errors.New(fmt.Sprintf("查询设备定位信息失败:%s", err.Error()))
+		}
+		var lng, Lat string
+		if len(deviceSensorList[0].T_DeviceSensorData.T_site) > 0 {
+			site := strings.Split(deviceSensorList[0].T_DeviceSensorData.T_site, ",")
+			if len(site) == 2 {
+				lng = site[0]
+				Lat = site[1]
+			}
+		}
+
+		// 添加物流
+		Logistics := model.WaybillLogistics{
+			WaybillNo:   waybillNo,
+			Status:      model.WaybillStatusStorageOut,
+			WarehouseId: warehouse.Id,
+			UserId:      p.UserId,
+			Lng:         lng,
+			Lat:         Lat,
+			ControlBy: model2.ControlBy{
+				CreateBy: p.UserId,
+			},
+			DeptBy: model2.DeptBy{
+				DeptId: p.DeptId,
+			},
+		}
+		err = tx.Create(&Logistics).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New(fmt.Sprintf("保存运单物流信息失败:%s", err))
+		}
+
+		// 查询任务
+		var task model.WaybillTask
+		err = tx.Model(&task).Where("waybill_no = ? and warehouse_id = ?", waybillNo, warehouse.Id).
+			First(&task).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New(fmt.Sprintf("查询运单任务信息失败:%s", err))
+		}
+		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))
+		}
+	}
+
+	return nil
+}
+func (e *Waybill) CarIn(c *dto.WaybillInOutReq, p *actions.DataPermission) error {
+	var err error
+
+	tx := e.Orm.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			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.CarId == car.Id && waybillModel.Status == model.WaybillStatusTruck {
+			continue
+		}
+		waybillModel.Status = model.WaybillStatusTruck
+		waybillModel.CarId = car.Id
+		err = tx.Save(waybillModel).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New(fmt.Sprintf("保存运单信息失败:%s", err))
+		}
+		// 获取传感器信息
+		deviceSensorList, count, err := nats_server.Cold_CompanyDeviceSensor_List_ByKey(car.Sn)
+		if err != nil || count == 0 {
+			return errors.New(fmt.Sprintf("查询设备定位信息失败:%s", err.Error()))
+		}
+		var lng, Lat string
+		if len(deviceSensorList[0].T_DeviceSensorData.T_site) > 0 {
+			site := strings.Split(deviceSensorList[0].T_DeviceSensorData.T_site, ",")
+			if len(site) == 2 {
+				lng = site[0]
+				Lat = site[1]
+			}
+		}
+
+		// 添加物流
+		Logistics := model.WaybillLogistics{
+			WaybillNo: waybillNo,
+			Status:    model.WaybillStatusTruck,
+			CarId:     car.Id,
+			UserId:    p.UserId,
+			Lng:       lng,
+			Lat:       Lat,
+			ControlBy: model2.ControlBy{
+				CreateBy: p.UserId,
+			},
+			DeptBy: model2.DeptBy{
+				DeptId: p.DeptId,
+			},
+		}
+		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,
+			CarId:     car.Id,
+			UserId:    p.UserId,
+			Sn:        car.Sn,
+			StartTime: model2.Time(time.Now()),
+			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) CarOut(c *dto.WaybillInOutReq, p *actions.DataPermission) error {
+	var err error
+
+	tx := e.Orm.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			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.CarId != car.Id {
+			return errors.New("请选择正确仓库出库!")
+		}
+
+		if waybillModel.CarId == car.Id && waybillModel.Status == model.WaybillStatusTruckOut {
+			continue
+		}
+		waybillModel.Status = model.WaybillStatusTruckOut
+		waybillModel.CarId = car.Id
+		err = tx.Save(waybillModel).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New(fmt.Sprintf("保存运单信息失败:%s", err))
+		}
+		// 获取传感器信息
+		deviceSensorList, count, err := nats_server.Cold_CompanyDeviceSensor_List_ByKey(car.Sn)
+		if err != nil || count == 0 {
+			return errors.New(fmt.Sprintf("查询设备定位信息失败:%s", err.Error()))
+		}
+		var lng, Lat string
+		if len(deviceSensorList[0].T_DeviceSensorData.T_site) > 0 {
+			site := strings.Split(deviceSensorList[0].T_DeviceSensorData.T_site, ",")
+			if len(site) == 2 {
+				lng = site[0]
+				Lat = site[1]
+			}
+		}
+
+		// 添加物流
+		Logistics := model.WaybillLogistics{
+			WaybillNo: waybillNo,
+			Status:    model.WaybillStatusTruckOut,
+			CarId:     car.Id,
+			UserId:    p.UserId,
+			Lng:       lng,
+			Lat:       Lat,
+			ControlBy: model2.ControlBy{
+				CreateBy: p.UserId,
+			},
+			DeptBy: model2.DeptBy{
+				DeptId: p.DeptId,
+			},
+		}
+		err = tx.Create(&Logistics).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New(fmt.Sprintf("保存运单物流信息失败:%s", err))
+		}
+
+		// 查询任务
+		var task model.WaybillTask
+		err = tx.Model(&task).Where("waybill_no = ? and car_id = ?", waybillNo, car.Id).
+			First(&task).Error
+		if err != nil {
+			e.Log.Errorf("db error: %s", err)
+			return errors.New(fmt.Sprintf("查询运单任务信息失败:%s", err))
+		}
+		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))
+		}
+	}
+
+	return nil
+}

+ 2 - 0
cmd/api/server.go

@@ -6,6 +6,7 @@ import (
 	global2 "cold-logistics/common/global"
 	"cold-logistics/common/middleware"
 	"cold-logistics/common/middleware/handler"
+	"cold-logistics/common/nats"
 	"cold-logistics/common/storage"
 	"context"
 	"fmt"
@@ -63,6 +64,7 @@ func setup() {
 		database.Setup,
 		storage.Setup,
 		file_store.QiniuSetup,
+		nats.Setup,
 	)
 	database.AutoMigrateDB()
 	//注册监听函数

+ 2 - 1
common/actions/permission.go

@@ -13,6 +13,7 @@ import (
 
 type DataPermission struct {
 	DataScope string
+	UserType  string
 	UserId    int
 	DeptId    int
 	RoleId    int
@@ -52,7 +53,7 @@ func newDataPermission(tx *gorm.DB, userId interface{}) (*DataPermission, error)
 	//	Where("sys_user.id = ?", userId).
 	//	Scan(p).Error
 	err = tx.Table("sys_user").
-		Select("sys_user.id as user_id", "sys_user.dept_id").
+		Select("sys_user.id as user_id", "sys_user.dept_id", "sys_user.user_type").
 		Where("sys_user.id = ?", userId).
 		Scan(p).Error
 	if err != nil {

+ 10 - 0
common/middleware/handler/auth.go

@@ -126,6 +126,16 @@ func Authenticator(c *gin.Context) (interface{}, error) {
 			return nil, jwt.ErrFailedSmsVerifyCode
 		}
 	}
+
+	if loginVals.Type == 3 {
+		u, role, dept, e = loginVals.GetUserByWX(ormDB)
+		if e != nil {
+			msg = e.Error()
+			status = "1"
+			log.Warnf("%s login failed!", username)
+			return nil, jwt.ErrFailedSmsVerifyCode
+		}
+	}
 	if loginVals.Type == 0 {
 		return nil, jwt.ErrFailedAuthentication
 	}

+ 84 - 9
common/middleware/handler/login.go

@@ -1,21 +1,27 @@
 package handler
 
 import (
+	"cold-logistics/conf"
+	"encoding/json"
 	"errors"
-	"gogs.baozhida.cn/zoie/OAuth-core/sdk"
-	"gorm.io/gorm"
-
+	"fmt"
+	"github.com/alibaba/sentinel-golang/util"
 	log "gogs.baozhida.cn/zoie/OAuth-core/logger"
+	coreModel "gogs.baozhida.cn/zoie/OAuth-core/model"
 	"gogs.baozhida.cn/zoie/OAuth-core/pkg"
+	"gogs.baozhida.cn/zoie/OAuth-core/sdk"
+	"gorm.io/gorm"
+	"net/http"
 )
 
 type Login struct {
-	Username   string `form:"UserName" json:"username"`     // 用户名
-	Password   string `form:"Password" json:"password"`     // 密码
-	Phone      string `form:"Phone" json:"phone"`           // 手机号
-	VerifyCode string `form:"VerifyCode" json:"verifyCode"` // 验证码
-	Type       int    `form:"Type" json:"type"`             // 1-密码  2-短信验证码
-	Mobile     bool   `form:"Mobile" json:"mobile"`         // 是否手机登录
+	Username          string `form:"UserName" json:"username"`                   // 用户名
+	Password          string `form:"Password" json:"password"`                   // 密码
+	Phone             string `form:"Phone" json:"phone"`                         // 手机号
+	VerifyCode        string `form:"VerifyCode" json:"verifyCode"`               // 验证码
+	Type              int    `form:"Type" json:"type"`                           // 1-密码  2-短信验证码 3-微信登录
+	Mobile            bool   `form:"Mobile" json:"mobile"`                       // 是否手机登录
+	AuthorizationCode string `form:"authorizationCode" json:"authorizationCode"` // 微信登录code
 }
 
 //Code     string `form:"Code" json:"code" binding:"required"`
@@ -98,3 +104,72 @@ func GetUserByID(tx *gorm.DB, id int64) (user SysUser, role SysRole, err error)
 	}
 	return
 }
+
+type AppletCustomerRegisterReq struct {
+	Type       int    `json:"type"`       // 类型  0-商户 1-私人
+	Phone      string `json:"phone"`      // 手机号
+	Password   string `json:"password"`   // 密码
+	VerifyCode string `json:"verifyCode"` // 验证码
+
+}
+
+type AppletCustomerLoginResp struct {
+	Openid      string `json:"openid"`      //用户唯一标识
+	Session_key string `json:"session_key"` // 会话密钥 session_key 是对用户数据进行 加密签名 的密钥
+	Unionid     string `json:"unionid"`     // 用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台帐号下会返回
+	Errcode     int    `json:"errcode"`     //错误码: -1、0、40029、 45011、 40226  (具体说明,请阅读 接口文档)
+	Errmsg      string `json:"errmsg"`      //错误信息
+}
+
+func (u *Login) GetUserByWX(tx *gorm.DB) (user SysUser, role SysRole, dept SysDept, err error) {
+
+	url := "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"
+	appid := conf.ExtConfig.Applet.Appid
+	appSecret := conf.ExtConfig.Applet.AppSecret
+	url = fmt.Sprintf(url, appid, appSecret, u.AuthorizationCode)
+	// 发起请求
+	res, _ := http.Get(url)
+
+	// 成功后获取openId
+	wxRes := AppletCustomerLoginResp{}
+	err = json.NewDecoder(res.Body).Decode(&wxRes)
+
+	if err != nil || wxRes.Openid == "" {
+		err = errors.New("获取openid失败")
+		return
+	}
+
+	err = tx.Where("username = ? and user_type = 'customer' and status = '2' and dept_id = 0", u.Phone).First(&user).Error
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			// 添加客户
+			user = SysUser{
+				User: coreModel.User{
+					Uuid:     util.NewUuid(),
+					Username: u.Phone,
+					Phone:    u.Phone,
+				},
+				UserType: "customer",
+				Openid:   wxRes.Openid,
+			}
+			err = tx.Create(&user).Error
+			if err != nil {
+				err = errors.New("添加个人信息失败")
+			}
+		} else {
+			err = errors.New("获取个人信息失败")
+			return
+		}
+	}
+
+	if user.Openid != wxRes.Openid {
+		user.Openid = wxRes.Openid
+		err = tx.Save(&user).Error
+		if err != nil {
+			err = errors.New("同步个人信息失败")
+			return
+		}
+	}
+
+	return
+}

+ 3 - 0
common/middleware/handler/user.go

@@ -9,6 +9,9 @@ import (
 type SysUser struct {
 	model.Model
 	coreModel.User
+	Type     int    `json:"type" gorm:"size:128;comment:类型"`         // 管理员1 仓管2 司机3
+	UserType string `json:"userType" gorm:"size:128;comment:用户类型"`   // 系统用户-sys 客户-customer
+	Openid   string `json:"openid" gorm:"size:128;comment:微信openid"` // 微信openid
 	model.ControlBy
 	model.ModelTime
 }

+ 22 - 0
common/nats/initialize.go

@@ -0,0 +1,22 @@
+package nats
+
+import (
+	"cold-logistics/conf"
+	"fmt"
+	"github.com/nats-io/nats.go"
+	"log"
+)
+
+var Nats *nats.Conn
+
+// Setup 配置storage组件
+func Setup() {
+	// 连接Nats服务器
+	var err error
+	Nats, err = nats.Connect("nats://" + conf.ExtConfig.Nats.Url)
+	if err != nil {
+		log.Fatalf("nats 连接失败!\n", err.Error())
+	}
+	fmt.Println("nats 连接成功!")
+
+}

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

@@ -0,0 +1,41 @@
+package nats_server
+
+import (
+	"cold-logistics/common/nats"
+	"cold-logistics/conf"
+	"github.com/vmihailenco/msgpack/v5"
+	"time"
+)
+
+func Cold_CompanyDeviceSensor_List_ByKey(T_sn string) (data []DeviceSensor_R, count int64, err error) {
+
+	type T_Req struct {
+		T_sn  string `xml:"T_sn"`
+		T_key string `xml:"T_key"`
+	}
+	t_Req := T_Req{
+		T_sn:  T_sn,
+		T_key: conf.ExtConfig.Nats.Key,
+	}
+	b, _ := msgpack.Marshal(&t_Req)
+
+	msg, err := nats.Nats.Request("Cold_CompanyDeviceSensor_List_ByKey", 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  []DeviceSensor_R `xml:"Data"` // 泛型
+	}
+	var t_R T_R
+
+	err = msgpack.Unmarshal(msg.Data, &t_R)
+	if err != nil {
+		return
+	}
+
+	return t_R.Data, t_R.Count, nil
+}

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

@@ -0,0 +1,98 @@
+package nats_server
+
+import (
+	"database/sql/driver"
+	"fmt"
+	"time"
+)
+
+type JsonTime struct {
+	time.Time
+}
+
+func (t JsonTime) MarshalJSON() ([]byte, error) {
+	str := fmt.Sprintf("\"%s\"", t.Format("2006-01-02 15:04:05"))
+	return []byte(str), nil
+}
+
+func (t JsonTime) Value() (driver.Value, error) {
+	var zeroTime time.Time
+	if t.Time.UnixNano() == zeroTime.UnixNano() {
+		return nil, nil
+	}
+	return t.Time, nil
+}
+
+func (t *JsonTime) Scan(v interface{}) error {
+	value, ok := v.(time.Time)
+	if ok {
+		*t = JsonTime{Time: value}
+		return nil
+	}
+	return fmt.Errorf("error %v", v)
+}
+
+type DeviceSensor_R struct {
+	T_sn   string // 设备序列号 KF开头,环境监测主机。 YD开头,温途监测主机
+	T_id   int    // 传感器编号
+	T_name string // 标题
+
+	T_pid      int    // 公司id
+	T_pid_name string // 公司名称
+
+	T_3dview   string // 3D 视图ID
+	T_sort     int    // 排序
+	T_Dattery  int    // 电量
+	T_Site     string // GPS
+	T_monitor  int    // 记录状态
+	T_online   int    // 在线状态 1 在线  0 离线
+	T_online_s int    // 在线状态-备用  0 未启用  1 在线  2 离线
+	T_datashow int    // 0 屏蔽数据展示  1 正常数据展示
+	T_type     int    // 类型
+	T_link     int    // 0:断开/故障 1连接 实时数据
+	T_State    int    // 0 屏蔽   1 正常  (屏蔽后 只有内部管理员才能看到,用户 输入SN\名称 搜索时 也能看到)
+
+	T_DeviceSensorData      DeviceData_R            // 传感器最新数据
+	T_DeviceSensorParameter DeviceSensorParameter_R //  设备参数
+}
+type DeviceData_R struct {
+	T_sn     string  // sn
+	T_id     int     // 传感器id
+	T_name   string  // 传感器名称
+	T_t      float32 // 温度
+	T_rh     float32 // 湿度
+	T_site   string  // GPS
+	T_tl     float32 // 温度下限
+	T_tu     float32 // 温度上限
+	T_rhl    float32 // 湿度下限
+	T_rhu    float32 // 湿度上限
+	T_time   string  // 采集时间
+	T_sp     int     // 传感器参数id
+	T_ist    int     // 温度   1开启   2关闭
+	T_ish    int     // 湿度   1开启   2关闭
+	T_remark string  // 备注
+}
+
+type DeviceSensorParameter_R struct {
+	Id     int
+	T_name string
+	// 报警
+	T_Tlower  float32 //  温度下限
+	T_Tupper  float32 //  温度上限
+	T_RHlower float32 //  湿度下限
+	T_RHupper float32 //  湿度上限
+	// 预警
+	T_enprel     int     // 是否启用预警
+	T_tprel      float32 //  温度预警下限
+	T_tpreu      float32 //  温度预警上限
+	T_hprel      float32 //  湿度预警下限
+	T_hpreu      float32 //  温度预警上限
+	T_enprelnote int     // 预警记录数据
+
+	//T_speed int // 传感器采样率   s(1~240) 默认:15 *
+	//T_sense int // 传感器灵敏度   s(0~10) 默认:5
+	T_en   int // en:是否启用传感器,
+	T_free int // free:监测点是否为闲置状态(空库,只监测不报警)
+
+	T_time JsonTime
+}

+ 12 - 0
conf/extend.go

@@ -12,6 +12,8 @@ var ExtConfig Extend
 type Extend struct {
 	SubMail SubMail `yaml:"subMail"`
 	Qiniu   Qiniu   `yaml:"qiniu"`
+	Applet  Applet  `yaml:"applet"`
+	Nats    Nats    `yaml:"nats"`
 }
 
 type SubMail struct {
@@ -28,3 +30,13 @@ type Qiniu struct {
 	// BucketName 桶名称 `json:""
 	BucketName string `json:"bucketName"`
 }
+
+type Applet struct {
+	Appid     string `json:"appid"`
+	AppSecret string `json:"appSecret"`
+}
+
+type Nats struct {
+	Url string `json:"url"`
+	Key string `json:"key"`
+}

+ 3 - 1
db/migration.go

@@ -21,8 +21,10 @@ func AutoMigrateDB() {
 			&model.Warehouse{},
 			&model.Address{},
 			&model.AddressDefault{},
-			&model.UserWarehouse{},
 			&model.Car{},
+			&model.Waybill{},
+			&model.WaybillLogistics{},
+			&model.WaybillTask{},
 		)
 	if err != nil {
 		zap.L().Panic("migrate db fail", zap.Error(err))

+ 13 - 9
go.mod

@@ -14,21 +14,21 @@ require (
 	github.com/mssola/user_agent v0.5.3
 	github.com/pkg/errors v0.9.1
 	github.com/qiniu/go-sdk/v7 v7.13.0
-	github.com/robfig/cron/v3 v3.0.1
+	github.com/robfig/cron/v3 v3.0.1 // indirect
 	github.com/spf13/cobra v1.5.0
 	github.com/swaggo/files v1.0.1
 	github.com/swaggo/gin-swagger v1.6.0
 	github.com/swaggo/swag v1.8.12
 	github.com/unrolled/secure v1.12.0
 	go.uber.org/zap v1.19.1
-	golang.org/x/crypto v0.5.0
+	golang.org/x/crypto v0.18.0
 	gorm.io/driver/mysql v1.3.5
 	gorm.io/gorm v1.23.8
 )
 
 require (
-	github.com/go-resty/resty/v2 v2.7.0
-	github.com/tealeg/xlsx v1.0.5
+	github.com/go-redis/redis/v7 v7.4.0
+	github.com/nats-io/nats.go v1.34.0
 	gogs.baozhida.cn/zoie/OAuth-core v0.0.0-00010101000000-000000000000
 )
 
@@ -58,7 +58,7 @@ require (
 	github.com/go-playground/locales v0.14.1 // indirect
 	github.com/go-playground/universal-translator v0.18.1 // indirect
 	github.com/go-playground/validator/v10 v10.11.2 // indirect
-	github.com/go-redis/redis/v7 v7.4.0 // indirect
+	github.com/go-resty/resty/v2 v2.7.0 // 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
@@ -72,6 +72,7 @@ require (
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
+	github.com/klauspost/compress v1.17.2 // indirect
 	github.com/klauspost/cpuid/v2 v2.0.9 // indirect
 	github.com/leodido/go-urn v1.2.1 // indirect
 	github.com/mailru/easyjson v0.7.7 // indirect
@@ -82,6 +83,8 @@ require (
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	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/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
@@ -95,14 +98,16 @@ require (
 	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
 	github.com/ugorji/go/codec v1.2.9 // indirect
 	github.com/urfave/cli v1.22.1 // indirect
+	github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
+	github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
 	go.uber.org/atomic v1.9.0 // indirect
 	go.uber.org/multierr v1.7.0 // indirect
 	golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
 	golang.org/x/image v0.0.0-20220722155232-062f8c9fd539 // indirect
-	golang.org/x/net v0.8.0 // indirect
+	golang.org/x/net v0.10.0 // indirect
 	golang.org/x/sync v0.1.0 // indirect
-	golang.org/x/sys v0.6.0 // indirect
-	golang.org/x/text v0.8.0 // indirect
+	golang.org/x/sys v0.16.0 // indirect
+	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
 	google.golang.org/protobuf v1.30.0 // indirect
@@ -115,5 +120,4 @@ require (
 
 replace gogs.baozhida.cn/zoie/OAuth-core => /Users/zoie/work/bzd_project/OAuth-core
 
-
 replace google.golang.org/grpc => google.golang.org/grpc v1.26.0

+ 19 - 10
go.sum

@@ -359,6 +359,8 @@ github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT
 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
 github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
+github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
 github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
 github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
 github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
@@ -452,8 +454,13 @@ github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY
 github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
 github.com/nats-io/nats-server/v2 v2.1.6/go.mod h1:BL1NOtaBQ5/y97djERRVWNouMW7GT3gxnmbE/eC8u8A=
 github.com/nats-io/nats.go v1.9.2/go.mod h1:AjGArbfyR50+afOUotNX2Xs5SYHf+CoOa5HH1eEl2HE=
+github.com/nats-io/nats.go v1.34.0 h1:fnxnPCNiwIG5w08rlMcEKTUw4AV/nKyGCOJE8TdhSPk=
+github.com/nats-io/nats.go v1.34.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8=
 github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
 github.com/nats-io/nkeys v0.1.4/go.mod h1:XdZpAbhgyyODYqjTawOnIOI7VlbKSarI9Gfy1tqEu/s=
+github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI=
+github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc=
+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/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
@@ -584,8 +591,6 @@ github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRd
 github.com/swaggo/swag v1.8.12 h1:pctzkNPu0AlQP2royqX3apjKCQonAnf7KGoxeO4y64w=
 github.com/swaggo/swag v1.8.12/go.mod h1:lNfm6Gg+oAq3zRJQNEMBE66LIJKM44mxFqhEEgy2its=
 github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
-github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
-github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM=
 github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ=
 github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
 github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
@@ -613,6 +618,10 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX
 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
 github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
 github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
+github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
+github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
+github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
+github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
 github.com/vultr/govultr v0.1.4/go.mod h1:9H008Uxr/C4vFNGLqKx232C206GL0PBHzOP0809bGNA=
 github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
 github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@@ -673,8 +682,8 @@ golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
-golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
+golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
+golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -731,8 +740,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
 golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
-golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
+golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -797,8 +806,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
-golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
+golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -809,8 +818,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
-golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=