mh_goadmin_server/app/admin/models/sysuser.go
chenlin 4d18ca0416 1.修复缺陷,优化代码:
(1)优化库存列表查询sql,解决数据重复问题;
(2)报表查询入参增加串码筛选;
(3)系统管理员登录时返回所有门店列表;
2024-05-27 11:08:39 +08:00

518 lines
15 KiB
Go

package models
import (
"encoding/json"
"errors"
"fmt"
"gorm.io/gorm"
"log"
"sort"
"strings"
"time"
"golang.org/x/crypto/bcrypt"
orm "go-admin/common/global"
"go-admin/tools"
)
// User
type User struct {
// key
IdentityKey string
// 用户名
UserName string
FirstName string
LastName string
// 角色
Role string
}
type UserName struct {
Username string `gorm:"size:64" json:"username"` // 用户名
}
type PassWord struct {
Password string `gorm:"size:128" json:"password"` // 密码
}
type LoginM struct {
UserName
PassWord
}
type SysUserId struct {
UserId int `gorm:"primary_key;AUTO_INCREMENT" json:"userId"` // 编码
}
type SysUserB struct {
NickName string `gorm:"size:128" json:"nickName"` // 昵称
Phone string `gorm:"size:11" json:"phone"` // 手机号
RoleId int `gorm:"" json:"roleId"` // 角色编码
Salt string `gorm:"size:255" json:"salt"` // 盐
Avatar string `gorm:"size:255" json:"avatar"` // 头像
Sex string `gorm:"size:255" json:"sex"` // 性别
Email string `gorm:"size:128" json:"email"` // 邮箱
DeptId int `gorm:"" json:"deptId"` // 部门编码
PostId int `gorm:"" json:"postId"` // 职位编码
CreateBy string `gorm:"size:128" json:"createBy"` //
UpdateBy string `gorm:"size:128" json:"updateBy"` //
Remark string `gorm:"size:255" json:"remark"` // 备注
Status string `gorm:"size:4;" json:"status"` // 状态
StoreId uint32 `json:"store_id"` // 门店id
StoreName string `json:"store_name"` // 门店名称
CooperativeBusinessId uint32 `json:"cooperative_business_id" gorm:"index"` // 合作商id
CooperativeName string `json:"cooperative_name"` // 合作商名称
AccountType uint32 `json:"account_type"` // 账号类型:1-管理端
StoreData string `gorm:"type:json" json:"store_data,omitempty"` // 有效门店
StoreList []StoreInfo `json:"store_list" gorm:"-" ` // 有效门店列表
SalesCommRate float64 `json:"sales_comm_rate"` // 销售提成比例
Uid uint32 `json:"uid" gorm:"column:uid;unique_index"` // 用户uid todo 待添加
BaseModel
DataScope string `gorm:"-" json:"dataScope"`
Params string `gorm:"-" json:"params"`
}
type StoreInfo struct {
StoreID int `json:"storeId"` //门店id
StoreName string `json:"storeName"` //门店名称
ExpireTime string `json:"expireTime"` //有效期
}
type SysUser struct {
SysUserId
LoginM
SysUserB
}
type InsertSysUserReq struct {
SysUserId
LoginM
NickName string `json:"nickName"` // 昵称
Phone string `json:"phone"` // 手机号
RoleId int `json:"roleId"` // 角色编码
Salt string `json:"salt"` // 盐
Avatar string `json:"avatar"` // 头像
Sex string `json:"sex"` // 性别
Email string `json:"email"` // 邮箱
DeptId int `json:"deptId"` // 部门编码
PostId int `json:"postId"` // 职位编码
Remark string `json:"remark"` // 备注
Status string `json:"status"` // 状态
StoreId uint32 `json:"store_id"` // 门店id
StoreName string `json:"store_name"` // 门店名称
CooperativeBusinessId uint32 `json:"cooperative_business_id"` // 合作商id
CooperativeName string `json:"cooperative_name"` // 合作商名称
AccountType uint32 `json:"account_type"` // 账号类型:1-管理端
SalesCommRate string `json:"sales_comm_rate"` // 销售提成比例
StoreList []StoreInfo `json:"store_list"` // 有效门店
Uid uint32 `json:"uid"` // 用户uid
}
func (SysUser) TableName() string {
return "sys_user"
}
type SysUserPwd struct {
OldPassword string `json:"oldPassword"`
NewPassword string `json:"newPassword"`
}
type SysUserPage struct {
SysUserId
SysUserB
LoginM
DeptName string `gorm:"-" json:"deptName"`
}
type SysUserView struct {
SysUserId
SysUserB
LoginM
RoleName string `gorm:"column:role_name" json:"role_name"`
}
// 获取用户数据
func (e *SysUser) Get() (SysUserView SysUserView, err error) {
table := orm.Eloquent.Table(e.TableName()).Select([]string{"sys_user.*", "sys_role.role_name"})
table = table.Joins("left join sys_role on sys_user.role_id=sys_role.role_id")
if e.UserId != 0 {
table = table.Where("user_id = ?", e.UserId)
}
if e.Username != "" {
table = table.Where("username = ?", e.Username)
}
if e.Password != "" {
table = table.Where("password = ?", e.Password)
}
if e.RoleId != 0 {
table = table.Where("role_id = ?", e.RoleId)
}
if e.DeptId != 0 {
table = table.Where("dept_id = ?", e.DeptId)
}
if e.PostId != 0 {
table = table.Where("post_id = ?", e.PostId)
}
if err = table.First(&SysUserView).Error; err != nil {
return
}
SysUserView.Password = ""
if SysUserView.RoleName == "系统管理员" {
// 查询组合所有门店数据
stores := make([]Store, 0)
orm.Eloquent.Table("store").Where("cooperative_business_id = ?", SysUserView.CooperativeBusinessId).Find(&stores)
for _, item := range stores {
storeInfo := StoreInfo{
StoreID: int(item.ID),
StoreName: item.Name,
ExpireTime: "2099.12.30",
}
SysUserView.StoreList = append(SysUserView.StoreList, storeInfo)
}
} else { // 普通用户
if SysUserView.StoreData != "" {
SysUserView.StoreList = deserializeStoreData(SysUserView.StoreData)
}
}
return
}
func (e *SysUser) GetUserInfo() (SysUserView SysUserView, err error) {
table := orm.Eloquent.Table(e.TableName()).Select([]string{"sys_user.*", "sys_role.role_name"})
table = table.Joins("left join sys_role on sys_user.role_id=sys_role.role_id")
if e.UserId != 0 {
table = table.Where("user_id = ?", e.UserId)
}
if e.Username != "" {
table = table.Where("username = ?", e.Username)
}
if e.Password != "" {
table = table.Where("password = ?", e.Password)
}
if e.RoleId != 0 {
table = table.Where("role_id = ?", e.RoleId)
}
if e.DeptId != 0 {
table = table.Where("dept_id = ?", e.DeptId)
}
if e.PostId != 0 {
table = table.Where("post_id = ?", e.PostId)
}
if err = table.First(&SysUserView).Error; err != nil {
return
}
return
}
func (e *SysUser) GetList() (SysUserView []SysUserView, err error) {
table := orm.Eloquent.Table(e.TableName()).Select([]string{"sys_user.*", "sys_role.role_name"})
table = table.Joins("left join sys_role on sys_user.role_id=sys_role.role_id")
if e.UserId != 0 {
table = table.Where("user_id = ?", e.UserId)
}
if e.Username != "" {
table = table.Where("username = ?", e.Username)
}
if e.Password != "" {
table = table.Where("password = ?", e.Password)
}
if e.RoleId != 0 {
table = table.Where("role_id = ?", e.RoleId)
}
if e.DeptId != 0 {
table = table.Where("dept_id = ?", e.DeptId)
}
if e.PostId != 0 {
table = table.Where("post_id = ?", e.PostId)
}
if err = table.Find(&SysUserView).Error; err != nil {
return
}
return
}
type SysUserListResp struct {
Total int `json:"count"` // 总条数
PageIndex int `json:"pageIndex"` // 页码
PageSize int `json:"pageSize"` // 页面条数
List []SysUserPage `json:"list"` // 采购报表信息
}
func (e *SysUser) GetPage(pageSize int, pageIndex int) ([]SysUserPage, int, error) {
var doc []SysUserPage
table := orm.Eloquent.Select("sys_user.*,sys_dept.dept_name").Table(e.TableName())
table = table.Joins("left join sys_dept on sys_dept.dept_id = sys_user.dept_id") //es := orm.Eloquent.Select("sys_user.*,sys_dept.dept_name").Table(e.TableName()) //es = table.Joins("left join sys_dept on sys_dept.dept_id = sys_user.dept_id")
if e.Username != "" {
table = table.Where("username = ?", e.Username)
}
if e.Status != "" {
table = table.Where("sys_user.status = ?", e.Status)
}
if e.Phone != "" {
table = table.Where("sys_user.phone = ?", e.Phone)
}
if e.RoleId != 0 {
table = table.Where("sys_user.role_id = ?", e.RoleId)
}
if e.NickName != "" {
table = table.Where("sys_user.nick_name = ?", e.NickName)
}
if e.StoreId != 0 {
table = table.Where("JSON_CONTAINS(store_data, ?)", fmt.Sprintf(`{"storeId":%d}`, e.StoreId))
}
if e.DeptId != 0 {
table = table.Where("sys_user.dept_id in (select dept_id from sys_dept where dept_path like ? )", "%"+tools.IntToString(e.DeptId)+"%") //es = table.Where("sys_user.dept_id in (select dept_id from sys_dept where dept_path like ? )", "%"+tools.IntToString(e.DeptId)+"%")
}
// 数据权限控制(如果不需要数据权限请将此处去掉)
dataPermission := new(DataPermission)
dataPermission.UserId, _ = tools.StringToInt(e.DataScope)
table, err := dataPermission.GetDataScope(e.TableName(), table)
if err != nil {
return nil, 0, err
}
es := table
var count int64
err = es.Count(&count).Error
if err != nil {
//logger.Error("count err:", err)
return nil, 0, err
}
//if err := table.Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&doc).Order("sys_user.created_at DESC").Offset(-1).Limit(-1).Count(&count).Error; err != nil {
// return nil, 0, err
//}
if err = table.Order("sys_user.user_id DESC").Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&doc).Error; err != nil {
return nil, 0, err
}
// 反序列化 StoreData
for i, v := range doc {
if doc[i].StoreData != "" {
doc[i].StoreList = deserializeStoreData(v.StoreData)
doc[i].StoreData = ""
}
}
return doc, int(count), nil
}
// 反序列化 StoreData
func deserializeStoreData(storeData string) []StoreInfo {
var StoreData []StoreInfo
if err := json.Unmarshal([]byte(storeData), &StoreData); err != nil {
// 可以根据实际情况处理反序列化失败的情况
log.Println("反序列化 StoreData 失败:", err)
}
return StoreData
}
// 加密
func (e *SysUser) Encrypt() (err error) {
if e.Password == "" {
return
}
var hash []byte
if hash, err = bcrypt.GenerateFromPassword([]byte(e.Password), bcrypt.DefaultCost); err != nil {
return
} else {
e.Password = string(hash)
return
}
}
// 添加
func (e SysUser) Insert(begin *gorm.DB) (id int, err error) {
if err = e.Encrypt(); err != nil {
return
}
// check 用户名
var count int64
orm.Eloquent.Table(e.TableName()).Where("username = ?", e.Username).Count(&count)
if count > 0 {
err = errors.New("账户已存在!")
return
}
//添加数据
if err = begin.Table(e.TableName()).Create(&e).Error; err != nil {
return
}
id = e.UserId
return
}
// 修改
func (e *SysUser) Update(begin *gorm.DB, id int) (update SysUser, err error) {
if e.Password != "" {
if err = e.Encrypt(); err != nil {
return
}
}
if err = orm.Eloquent.Table(e.TableName()).First(&update, id).Error; err != nil {
return
}
if e.RoleId == 0 {
e.RoleId = update.RoleId
}
if len(e.StoreList) != 0 {
// 将 StoreData 转换为 JSON 字符串
storeDataJSON, err := json.Marshal(e.StoreList)
if err != nil {
return SysUser{}, err
}
e.StoreData = string(storeDataJSON)
}
if begin == nil {
begin = orm.Eloquent
}
//参数1:是要修改的数据
//参数2:是修改的数据
if err = begin.Table(e.TableName()).Model(&update).Updates(&e).Error; err != nil {
return
}
return
}
func (e *SysUser) BatchDelete(begin *gorm.DB, id []int) (Result bool, err error) {
if err = begin.Table(e.TableName()).Where("user_id in (?)", id).Delete(&SysUser{}).Error; err != nil {
return false, err
}
return true, nil
}
func (e *SysUser) SetPwd(pwd SysUserPwd) (Result bool, err error) {
user, err := e.GetUserInfo()
if err != nil {
tools.HasError(err, "获取用户数据失败(代码202)", 500)
}
_, err = tools.CompareHashAndPassword(user.Password, pwd.OldPassword)
if err != nil {
if strings.Contains(err.Error(), "hashedPassword is not the hash of the given password") {
tools.HasError(err, "密码错误(代码202)", 500)
}
log.Print(err)
return
}
e.Password = pwd.NewPassword
_, err = e.Update(nil, e.UserId)
tools.HasError(err, "更新密码失败(代码202)", 500)
return
}
func GetUserById(id uint32) *SysUserB {
var u = new(SysUserB)
orm.Eloquent.Table("sys_user").Where("user_id", id).First(u)
return u
}
// UpdateUserType 更新uid的user_type为2
func UpdateUserType(begin *gorm.DB, uid, nType, roleId uint32) error {
// 更新库存表
err := begin.Table("user").Where("uid = ?", uid).
Updates(map[string]interface{}{
"user_type": nType,
"xcx_role_id": roleId,
}).Error
if err != nil {
return err
}
return nil
}
// GetUserEffectiveStore 获取店员当前的有效门店(邀请客户时使用)
func GetUserEffectiveStore(uid uint32) ([]StoreInfo, error) {
user := new(SysUser)
err := orm.Eloquent.Table("sys_user").Where("uid", uid).Find(&user).Error
if err != nil {
log.Println("Error:", err, "UID:", uid)
return nil, err
}
// 解析门店数据
if err := json.Unmarshal([]byte(user.StoreData), &user.StoreList); err != nil {
return nil, err
}
if len(user.StoreList) == 0 {
return nil, errors.New("no stores found")
}
// 当前时间
now := time.Now()
// 过滤掉过期的门店
validStores := make([]StoreInfo, 0)
for _, store := range user.StoreList {
expireTime, err := time.Parse(StoreDateTimeFormat, store.ExpireTime)
if err != nil {
log.Println("Error parsing time:", err, "ExpireTime:", store.ExpireTime)
continue
}
// 包含当天有效时间
expireTime = expireTime.Add(24*time.Hour - time.Second)
if expireTime.After(now) {
validStores = append(validStores, store)
}
}
if len(validStores) == 0 {
return nil, nil
}
// 按有效时间和 store_id 排序
sort.Slice(validStores, func(i, j int) bool {
timeI, _ := time.Parse(StoreDateTimeFormat, validStores[i].ExpireTime)
timeJ, _ := time.Parse(StoreDateTimeFormat, validStores[j].ExpireTime)
if timeI.Equal(timeJ) {
return validStores[i].StoreID < validStores[j].StoreID
}
return timeI.Before(timeJ)
})
return validStores, nil
}