1037 lines
34 KiB
Go
1037 lines
34 KiB
Go
package service
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"github.com/gin-gonic/gin"
|
||
"psi/config"
|
||
"psi/database"
|
||
"psi/models"
|
||
systemReq "psi/models/request"
|
||
systemRes "psi/models/response"
|
||
"psi/utils"
|
||
"strconv"
|
||
"time"
|
||
)
|
||
|
||
type EmployeeService struct{}
|
||
|
||
// Login 管理员登录
|
||
func (s *EmployeeService) Login(req systemReq.LoginRequest, userType string, c *gin.Context) (*systemRes.LoginResponse, error) {
|
||
var employee models.Employee
|
||
|
||
result := database.DB.Where("username = ? AND deleted_at = ?", req.Username, 0).First(&employee)
|
||
if result.Error != nil {
|
||
return nil, utils.NewError("用户不存在")
|
||
} else if employee.Status != 1 {
|
||
return nil, utils.NewError("用户被禁用")
|
||
} else if employee.Fid != 0 {
|
||
var parentEmployeeLevel models.EmployeeLevel
|
||
if err := database.DB.Where("emp_id = ? AND is_del = ?", employee.Fid, 0).First(&parentEmployeeLevel).Error; err != nil {
|
||
return nil, utils.NewError("未找到主账号的等级信息")
|
||
}
|
||
// 检查主账号是否已过期
|
||
now := time.Now().Unix()
|
||
if parentEmployeeLevel.ExpireTime < now {
|
||
return nil, utils.NewError("主账号已过期,子账号无法登录")
|
||
}
|
||
if employee.ExpireTime > 0 && employee.ExpireTime < now {
|
||
return nil, utils.NewError("子账号已过期,无法登录")
|
||
}
|
||
}
|
||
|
||
if req.Type == 1 {
|
||
expectedRole := 255
|
||
if userType == "128" {
|
||
expectedRole = 128
|
||
}
|
||
|
||
if employee.Role != int64(expectedRole) {
|
||
return nil, utils.NewError("账号类型不匹配")
|
||
}
|
||
}
|
||
|
||
if !utils.CheckPasswordHash(req.Password, employee.Password) {
|
||
return nil, utils.NewError("用户名或密码错误")
|
||
}
|
||
|
||
ip := utils.GetClientIP(c)
|
||
now := time.Now().Unix()
|
||
updates := map[string]interface{}{
|
||
"last_login_at": now,
|
||
"last_login_ip": ip,
|
||
}
|
||
//if req.Type != 1 {
|
||
// if employee.Code != "" && employee.Code != req.Code {
|
||
// return nil, utils.NewError("设备与账号不匹配,请使用已绑定的设备登录")
|
||
// } else if employee.Code == "" && req.Code != "" {
|
||
// updates["code"] = req.Code
|
||
// }
|
||
//}
|
||
updates["code"] = req.Code
|
||
// 处理租户ID
|
||
aboutID := req.AboutID
|
||
if aboutID == 0 {
|
||
aboutID = employee.AboutId
|
||
}
|
||
|
||
// 如果有租户ID,确保租户数据库存在
|
||
if aboutID > 0 {
|
||
if _, err := database.GetTenantDB(aboutID); err != nil {
|
||
return nil, utils.NewError("租户数据库初始化失败: " + err.Error())
|
||
}
|
||
}
|
||
|
||
token, err := utils.GenerateJWT(employee.ID, employee.Username, employee.Role, aboutID)
|
||
if err != nil {
|
||
return nil, utils.NewError("生成令牌失败")
|
||
}
|
||
|
||
database.DB.Model(&employee).Updates(updates)
|
||
|
||
// 查询员工等级信息
|
||
var levelInfo *systemRes.EmployeeLevelInfo
|
||
var employeeLevel models.EmployeeLevel
|
||
levelResult := database.DB.Where("emp_id = ? AND is_del = ?", employee.ID, 0).First(&employeeLevel)
|
||
if levelResult.Error == nil {
|
||
levelInfo = &systemRes.EmployeeLevelInfo{
|
||
Level: employeeLevel.Level,
|
||
MaxNum: employeeLevel.MaxNum,
|
||
ExpireTime: employeeLevel.ExpireTime,
|
||
PayTime: employeeLevel.PayTime,
|
||
}
|
||
}
|
||
|
||
return &systemRes.LoginResponse{
|
||
ID: employee.ID,
|
||
EmployeeID: employee.EmployeeIDStr,
|
||
Fid: employee.Fid,
|
||
AboutId: strconv.FormatInt(employee.AboutId, 10),
|
||
Username: employee.Username,
|
||
Name: employee.Name,
|
||
Role: employee.Role,
|
||
Score: employee.Score,
|
||
From: employee.From,
|
||
Token: token,
|
||
ExpireIn: config.AppConfig.JWT.ExpireHours,
|
||
LevelInfo: levelInfo,
|
||
}, nil
|
||
}
|
||
|
||
// GetCurrentUser 获取当前用户信息
|
||
func (s *EmployeeService) GetCurrentUser(adminID int64) (*models.Employee, error) {
|
||
var employee models.Employee
|
||
|
||
result := database.DB.Where("id = ? AND deleted_at = ?", adminID, 0).First(&employee)
|
||
if result.Error != nil {
|
||
return nil, utils.NewError("用户不存在")
|
||
}
|
||
|
||
return &employee, nil
|
||
}
|
||
|
||
// GetEmployeeList 获取员工列表
|
||
func (s *EmployeeService) GetEmployeeList(req systemReq.GetEmployeeListRequest, id, about_id int64) (*systemRes.EmployeeListResponse, error) {
|
||
if req.Page < 1 {
|
||
req.Page = 1
|
||
}
|
||
if req.PageSize < 1 || req.PageSize > 100 {
|
||
req.PageSize = 20
|
||
}
|
||
|
||
type EmployeeWithRelations struct {
|
||
models.Employee
|
||
Settings string `gorm:"column:settings"`
|
||
LevelID int64 `gorm:"column:level_id"`
|
||
LevelLevel int8 `gorm:"column:level_level"`
|
||
MaxNum int64 `gorm:"column:max_num"`
|
||
LevelPayTime int64 `gorm:"column:level_pay_time"`
|
||
LevelExpireTime int64 `gorm:"column:level_expire_time"`
|
||
UserTypeID int8 `gorm:"column:user_type_id"`
|
||
UserTypeName string `gorm:"column:user_type_name"`
|
||
UserTypeIcon string `gorm:"column:user_type_icon"`
|
||
}
|
||
query := database.DB.Table("employees").
|
||
Select("employees.*, employees_settings.settings, employees_level.id as level_id, employees_level.level as level_level, employees_level.max_num, employees_level.pay_time as level_pay_time, employees_level.expire_time as level_expire_time, user_type.id as user_type_id, user_type.name as user_type_name, user_type.icon as user_type_icon").
|
||
Joins("LEFT JOIN employees_settings ON employees.id = employees_settings.emp_id AND employees_settings.is_del = 0").
|
||
Joins("LEFT JOIN employees_level ON employees.id = employees_level.emp_id AND employees_level.is_del = 0").
|
||
Joins("LEFT JOIN user_type ON employees.type_id = user_type.id AND user_type.deleted_at = 0").
|
||
Where("employees.deleted_at = ?", 0)
|
||
|
||
if about_id > 0 {
|
||
query = query.Where("employees.fid = ?", id)
|
||
} else if req.Fid != 0 {
|
||
query = query.Where("employees.fid = ?", req.Fid)
|
||
}
|
||
if req.Status != "" {
|
||
query = query.Where("employees.status = ?", req.Status)
|
||
}
|
||
if req.Keyword != "" {
|
||
query = query.Where("(employees.employee_id_str = ? OR employees.name LIKE ? OR employees.username LIKE ?)",
|
||
req.Keyword, "%"+req.Keyword+"%", "%"+req.Keyword+"%")
|
||
}
|
||
|
||
var total int64
|
||
if err := query.Count(&total).Error; err != nil {
|
||
return nil, utils.NewError("查询总数失败")
|
||
}
|
||
|
||
var employeesWithRelations []EmployeeWithRelations
|
||
offset := (req.Page - 1) * req.PageSize
|
||
if err := query.Order("employees.created_at DESC").Offset(offset).Limit(req.PageSize).Find(&employeesWithRelations).Error; err != nil {
|
||
return nil, utils.NewError("查询员工列表失败")
|
||
}
|
||
|
||
var employeeItems []systemRes.EmployeeItem
|
||
for _, emp := range employeesWithRelations {
|
||
item := systemRes.ConvertEmployeeToItem(emp.Employee)
|
||
|
||
// 添加设置信息
|
||
var settingsConfig models.EmployeeSettingsConfig
|
||
if emp.Settings != "" {
|
||
if err := json.Unmarshal([]byte(emp.Settings), &settingsConfig); err != nil {
|
||
settingsConfig = models.GetDefaultEmployeeSettingsConfig()
|
||
}
|
||
} else {
|
||
settingsConfig = models.GetDefaultEmployeeSettingsConfig()
|
||
}
|
||
item.Settings = settingsConfig
|
||
|
||
// 添加等级信息
|
||
if emp.LevelID > 0 {
|
||
item.LevelInfo = &systemRes.EmployeeLevelInfo{
|
||
Level: emp.LevelLevel,
|
||
MaxNum: emp.MaxNum,
|
||
ExpireTime: emp.LevelExpireTime,
|
||
PayTime: emp.LevelPayTime,
|
||
}
|
||
}
|
||
|
||
// 添加账号类型信息
|
||
if emp.UserTypeID > 0 {
|
||
item.UserType = &systemRes.UserTypeInfo{
|
||
ID: int64(emp.UserTypeID),
|
||
Name: emp.UserTypeName,
|
||
Icon: emp.UserTypeIcon,
|
||
}
|
||
}
|
||
|
||
employeeItems = append(employeeItems, item)
|
||
}
|
||
|
||
return &systemRes.EmployeeListResponse{
|
||
List: employeeItems,
|
||
Total: total,
|
||
Page: req.Page,
|
||
PageSize: req.PageSize,
|
||
}, nil
|
||
}
|
||
|
||
// AddEmployee 添加员工
|
||
func (s *EmployeeService) AddEmployee(req systemReq.AddEmployeeRequest) (*systemRes.AddEmployeeResponse, error) {
|
||
var lastEmployee models.Employee
|
||
var newEmployeeID string
|
||
seq := 1
|
||
|
||
if err := database.DB.Order("employee_id_str DESC").First(&lastEmployee).Error; err == nil {
|
||
if len(lastEmployee.EmployeeIDStr) == 5 {
|
||
if parsedSeq, err := strconv.Atoi(lastEmployee.EmployeeIDStr); err == nil {
|
||
seq = parsedSeq + 1
|
||
}
|
||
}
|
||
}
|
||
|
||
newEmployeeID = utils.GenerateEmployeeID(seq)
|
||
username := utils.GenerateUsername(newEmployeeID)
|
||
// 如果用户指定了用户名,直接使用
|
||
if req.UserName != "" {
|
||
username = req.UserName
|
||
// 检查指定的用户名是否已存在
|
||
var count int64
|
||
database.DB.Model(&models.Employee{}).Where("username = ? AND deleted_at = 0", username).Count(&count)
|
||
if count > 0 {
|
||
return nil, utils.NewError("用户名已存在")
|
||
}
|
||
} else {
|
||
// 自动生成用户名,确保唯一性
|
||
for i := 0; i < 100; i++ {
|
||
var count int64
|
||
database.DB.Model(&models.Employee{}).Where("username = ? AND deleted_at = 0", username).Count(&count)
|
||
if count == 0 {
|
||
break
|
||
}
|
||
seq++
|
||
newEmployeeID = utils.GenerateEmployeeID(seq)
|
||
username = utils.GenerateUsername(newEmployeeID)
|
||
}
|
||
|
||
// 最后再检查一次,确保生成的用户名确实不存在
|
||
var finalCount int64
|
||
database.DB.Model(&models.Employee{}).Where("username = ? AND deleted_at = 0", username).Count(&finalCount)
|
||
if finalCount > 0 {
|
||
return nil, utils.NewError("无法生成唯一的用户名,请稍后重试")
|
||
}
|
||
}
|
||
|
||
// 如果是创建子账号,检查主账号的子账号数量限制
|
||
if req.Fid != 0 {
|
||
var parentEmployeeLevel models.EmployeeLevel
|
||
if err := database.DB.Where("emp_id = ? AND is_del = ?", req.Fid, 0).First(&parentEmployeeLevel).Error; err != nil {
|
||
return nil, utils.NewError("未找到主账号的等级信息")
|
||
}
|
||
|
||
// 检查主账号是否已过期
|
||
now := time.Now().Unix()
|
||
if parentEmployeeLevel.ExpireTime < now {
|
||
return nil, utils.NewError("主账号已过期,无法创建子账号")
|
||
}
|
||
|
||
// 检查max_num限制,如果max_num为0表示没权限
|
||
if parentEmployeeLevel.MaxNum > 0 {
|
||
var currentSubCount int64
|
||
database.DB.Model(&models.Employee{}).Where("fid = ? AND deleted_at = 0", req.Fid).Count(¤tSubCount)
|
||
|
||
if currentSubCount >= parentEmployeeLevel.MaxNum {
|
||
return nil, utils.NewError(fmt.Sprintf("主账号已达到最大子账号数量限制(%d)", parentEmployeeLevel.MaxNum))
|
||
}
|
||
} else {
|
||
return nil, utils.NewError("主账号无权限创建子账号")
|
||
}
|
||
|
||
if parentEmployeeLevel.ExpireTime < req.ExpireTime {
|
||
return nil, utils.NewError("子账号的到期时间不能超过主账号的到期时间")
|
||
}
|
||
}
|
||
|
||
hashedPassword, err := utils.HashPassword(req.Password)
|
||
if err != nil {
|
||
return nil, utils.NewError("密码加密失败")
|
||
}
|
||
|
||
now := time.Now().Unix()
|
||
employee := models.Employee{
|
||
EmployeeIDStr: newEmployeeID,
|
||
Username: utils.Ternary(req.UserName == "", username, req.UserName),
|
||
Password: hashedPassword,
|
||
Name: req.Name,
|
||
Phone: req.Phone,
|
||
Role: int64(utils.Ternary(req.Fid == 0, 255, 128)),
|
||
Fid: req.Fid,
|
||
AboutId: req.AboutId,
|
||
Score: 0,
|
||
Status: 1,
|
||
From: utils.Ternary(req.From == "", "system", req.From),
|
||
CreatedAt: now,
|
||
UpdatedAt: now,
|
||
DeletedAt: 0,
|
||
ExpireTime: req.ExpireTime,
|
||
}
|
||
|
||
if err := database.DB.Create(&employee).Error; err != nil {
|
||
return nil, utils.NewError("创建员工失败: " + err.Error())
|
||
}
|
||
|
||
return &systemRes.AddEmployeeResponse{
|
||
EmployeeID: employee.EmployeeIDStr,
|
||
Username: employee.Username,
|
||
Name: employee.Name,
|
||
}, nil
|
||
}
|
||
|
||
// UpdatePasswordEmployee 修改员工密码
|
||
func (s *EmployeeService) UpdatePasswordEmployee(req systemReq.UpdatePasswordEmployeeRequest) error {
|
||
var employee models.Employee
|
||
|
||
result := database.DB.Where("id = ? AND deleted_at = ?", req.Id, 0).First(&employee)
|
||
if result.Error != nil {
|
||
return utils.NewError("用户不存在")
|
||
} else if employee.Status != 1 {
|
||
return utils.NewError("用户被禁用")
|
||
} else if employee.Fid != 0 {
|
||
if employee.AboutId != req.AboutId {
|
||
return utils.NewError("子账号所属主账户错误")
|
||
}
|
||
var parentEmployeeLevel models.EmployeeLevel
|
||
if err := database.DB.Where("emp_id = ? AND is_del = ?", employee.Fid, 0).First(&parentEmployeeLevel).Error; err != nil {
|
||
return utils.NewError("未找到主账号的等级信息")
|
||
}
|
||
// 检查主账号是否已过期
|
||
now := time.Now().Unix()
|
||
if parentEmployeeLevel.ExpireTime < now {
|
||
return utils.NewError("主账号已过期,子账号无法修改")
|
||
}
|
||
}
|
||
|
||
hashedPassword, err := utils.HashPassword(req.Password)
|
||
if err != nil {
|
||
return utils.NewError("密码加密失败")
|
||
}
|
||
|
||
if err := database.DB.Model(&employee).Updates(map[string]interface{}{
|
||
"password": hashedPassword,
|
||
"updated_at": time.Now().Unix(),
|
||
}).Error; err != nil {
|
||
return utils.NewError("更新员工信息失败: " + err.Error())
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// UpdateExpireTimeEmployee 修改员工过期时间
|
||
func (s *EmployeeService) UpdateExpireTimeEmployee(req systemReq.UpdateExpireTimeEmployeeRequest) error {
|
||
var employee models.Employee
|
||
|
||
result := database.DB.Where("id = ? AND deleted_at = ?", req.Id, 0).First(&employee)
|
||
if result.Error != nil {
|
||
return utils.NewError("用户不存在")
|
||
} else if employee.Status != 1 {
|
||
return utils.NewError("用户被禁用")
|
||
} else if employee.Fid != 0 {
|
||
if employee.AboutId != req.AboutId {
|
||
return utils.NewError("子账号所属主账户错误")
|
||
}
|
||
var parentEmployeeLevel models.EmployeeLevel
|
||
if err := database.DB.Where("emp_id = ? AND is_del = ?", employee.Fid, 0).First(&parentEmployeeLevel).Error; err != nil {
|
||
return utils.NewError("未找到主账号的等级信息")
|
||
}
|
||
// 检查主账号是否已过期
|
||
now := time.Now().Unix()
|
||
if parentEmployeeLevel.ExpireTime < now {
|
||
return utils.NewError("主账号已过期,子账号无法修改")
|
||
}
|
||
if parentEmployeeLevel.ExpireTime < req.ExpireTime {
|
||
return utils.NewError("子账号的到期时间不能超过主账号的到期时间")
|
||
}
|
||
}
|
||
|
||
if err := database.DB.Model(&employee).Updates(map[string]interface{}{
|
||
"expire_time": req.ExpireTime,
|
||
"updated_at": time.Now().Unix(),
|
||
}).Error; err != nil {
|
||
return utils.NewError("更新员工信息失败: " + err.Error())
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// CheckExpireTimeEmployee 校验员工过期时间
|
||
func (s *EmployeeService) CheckExpireTimeEmployee(id int64) error {
|
||
var employee models.Employee
|
||
|
||
result := database.DB.Where("id = ? AND deleted_at = ?", id, 0).First(&employee)
|
||
if result.Error != nil {
|
||
return utils.NewError("用户不存在")
|
||
} else if employee.Status != 1 {
|
||
return utils.NewError("用户被禁用")
|
||
} else {
|
||
var parentEmployeeLevel models.EmployeeLevel
|
||
if err := database.DB.Where("emp_id = ? AND is_del = ?", employee.Fid, 0).First(&parentEmployeeLevel).Error; err != nil {
|
||
return utils.NewError("未找到主账号的等级信息")
|
||
}
|
||
// 检查主账号是否已过期
|
||
now := time.Now().Unix()
|
||
if parentEmployeeLevel.ExpireTime < now {
|
||
return utils.NewError("主账号已过期")
|
||
}
|
||
// 检查子账号是否已过期
|
||
if employee.ExpireTime > 0 && employee.ExpireTime < now {
|
||
return utils.NewError("子账号已过期,无法登录")
|
||
}
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// CheckCodeEmployee 校验员工过期时间
|
||
func (s *EmployeeService) CheckCodeEmployee(req systemReq.CheckCodeEmployeeRequest) (string, error) {
|
||
var employee models.Employee
|
||
|
||
result := database.DB.Where("username = ? AND deleted_at = ?", req.UserName, 0).First(&employee)
|
||
if result.Error != nil {
|
||
return "", utils.NewError("用户不存在")
|
||
} else if employee.Status != 1 {
|
||
return "", utils.NewError("用户被禁用")
|
||
}
|
||
|
||
return employee.Code, nil
|
||
}
|
||
|
||
// ClearCodeEmployee 清除员工机械码
|
||
func (s *EmployeeService) ClearCodeEmployee(req systemReq.ClearCodeEmployeeRequest) error {
|
||
var employee models.Employee
|
||
|
||
result := database.DB.Where("username = ? AND deleted_at = ?", req.UserName, 0).First(&employee)
|
||
if result.Error != nil {
|
||
return utils.NewError("用户不存在")
|
||
} else if employee.Status != 1 {
|
||
return utils.NewError("用户被禁用")
|
||
} else if employee.Fid != 0 {
|
||
var parentEmployeeLevel models.EmployeeLevel
|
||
if err := database.DB.Where("emp_id = ? AND is_del = ?", employee.Fid, 0).First(&parentEmployeeLevel).Error; err != nil {
|
||
return utils.NewError("未找到主账号的等级信息")
|
||
}
|
||
// 检查主账号是否已过期
|
||
now := time.Now().Unix()
|
||
if parentEmployeeLevel.ExpireTime < now {
|
||
return utils.NewError("主账号已过期,子账号无法修改")
|
||
}
|
||
}
|
||
|
||
if err := database.DB.Model(&employee).Updates(map[string]interface{}{
|
||
"code": "",
|
||
"updated_at": time.Now().Unix(),
|
||
}).Error; err != nil {
|
||
return utils.NewError("更新员工信息失败: " + err.Error())
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// GetLevelConfig 获取等级配置
|
||
func GetLevelConfig(level int8) interface{} {
|
||
configs := map[int8]systemRes.EmployeeLevelConfigResponse{
|
||
1: {
|
||
Level: 1,
|
||
MaxNum: 5,
|
||
Price: 9800,
|
||
LevelName: "基础版(5个子账号,98元/30天)",
|
||
},
|
||
2: {
|
||
Level: 2,
|
||
MaxNum: 10,
|
||
Price: 15600,
|
||
LevelName: "专业版(10个子账号,156元/30天)",
|
||
},
|
||
3: {
|
||
Level: 3,
|
||
MaxNum: 15,
|
||
Price: 20500,
|
||
LevelName: "企业版(15个子账号,205元/30天)",
|
||
},
|
||
4: {
|
||
Level: 4,
|
||
MaxNum: 20,
|
||
Price: 23500,
|
||
LevelName: "旗舰版(20个子账号,235元/30天)",
|
||
},
|
||
5: {
|
||
Level: 5,
|
||
MaxNum: 25,
|
||
Price: 24500,
|
||
LevelName: "至尊版(25个子账号,245元/30天)",
|
||
},
|
||
}
|
||
|
||
if level == 0 {
|
||
var allConfigs []systemRes.EmployeeLevelConfigResponse
|
||
for i := int8(1); i <= 5; i++ {
|
||
allConfigs = append(allConfigs, configs[i])
|
||
}
|
||
return allConfigs
|
||
}
|
||
|
||
if config, exists := configs[level]; exists {
|
||
return &config
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// SetEmployeeLevel 设置员工等级
|
||
func (s *EmployeeService) SetEmployeeLevel(req systemReq.SetEmployeeLevelRequest, operatorID int64, operatorName string) error {
|
||
// 验证等级配置
|
||
levelConfigResult := GetLevelConfig(req.Level)
|
||
if levelConfigResult == nil {
|
||
return utils.NewError("无效的等级配置")
|
||
}
|
||
|
||
levelConfig := levelConfigResult.(*systemRes.EmployeeLevelConfigResponse)
|
||
|
||
// 验证时长
|
||
if req.Duration <= 0 {
|
||
return utils.NewError("时长必须大于0")
|
||
}
|
||
|
||
// 检查是否已存在等级记录
|
||
var employeeLevel models.EmployeeLevel
|
||
err := database.DB.Where("emp_id = ? AND is_del = ?", req.EmpId, 0).First(&employeeLevel).Error
|
||
|
||
now := time.Now().Unix()
|
||
|
||
// 保存旧数据用于日志记录
|
||
var oldLevel int8
|
||
var oldMaxNum int64
|
||
var oldExpireTime int64
|
||
|
||
switch req.OperationType {
|
||
case 1: // 开通
|
||
// 如果已存在记录且未过期,则不允许重复开通
|
||
if err == nil && employeeLevel.ExpireTime > now {
|
||
return utils.NewError("该员工等级未过期,无需重复开通")
|
||
}
|
||
|
||
oldLevel = 0
|
||
oldMaxNum = 0
|
||
oldExpireTime = 0
|
||
|
||
// 计算到期时间(按时长*30天计算)
|
||
expireTime := req.PayTime + req.Duration*30*24*3600
|
||
|
||
// 如果记录存在但已过期,更新记录;否则创建新记录
|
||
if err == nil {
|
||
// 记录存在但已过期,更新记录
|
||
updateData := map[string]interface{}{
|
||
"level": levelConfig.Level,
|
||
"max_num": levelConfig.MaxNum,
|
||
"pay_time": req.PayTime,
|
||
"expire_time": expireTime,
|
||
"updated_at": now,
|
||
"is_del": 0,
|
||
}
|
||
|
||
if err := database.DB.Model(&models.EmployeeLevel{}).Where("emp_id = ? AND is_del = ?", req.EmpId, 0).Updates(updateData).Error; err != nil {
|
||
return utils.NewError("更新员工等级记录失败: " + err.Error())
|
||
}
|
||
} else {
|
||
// 记录不存在,创建新记录
|
||
newEmployeeLevel := models.EmployeeLevel{
|
||
EmpId: req.EmpId,
|
||
Level: levelConfig.Level,
|
||
MaxNum: levelConfig.MaxNum,
|
||
PayTime: req.PayTime,
|
||
ExpireTime: expireTime,
|
||
CreatedAt: now,
|
||
UpdatedAt: now,
|
||
IsDel: 0,
|
||
}
|
||
|
||
if err := database.DB.Create(&newEmployeeLevel).Error; err != nil {
|
||
return utils.NewError("创建员工等级记录失败: " + err.Error())
|
||
}
|
||
}
|
||
|
||
// 记录开通日志
|
||
operationRemark := fmt.Sprintf("开通%s(等级%d),可创建子账号数量上限:%d,价格:%d元,时长:%d个月,到期时间:%s",
|
||
levelConfig.LevelName, levelConfig.Level, levelConfig.MaxNum, (levelConfig.Price*req.Duration)/100, req.Duration,
|
||
time.Unix(expireTime, 0).Format("2006-01-02"))
|
||
if err := s.createEmployeeLevelLog(req.EmpId, 1, oldLevel, levelConfig.Level, oldMaxNum, levelConfig.MaxNum, oldExpireTime, expireTime, levelConfig.Price*req.Duration, req.PayTime, operatorID, operatorName, operationRemark); err != nil {
|
||
return err
|
||
}
|
||
|
||
case 2: // 升级
|
||
if err != nil {
|
||
return utils.NewError("该员工未开通等级,无法升级")
|
||
}
|
||
|
||
// 检查是否已过期
|
||
if employeeLevel.ExpireTime <= now {
|
||
return utils.NewError("该员工等级已过期,请先续费或重新开通")
|
||
}
|
||
|
||
oldLevel = employeeLevel.Level
|
||
oldMaxNum = employeeLevel.MaxNum
|
||
oldExpireTime = employeeLevel.ExpireTime
|
||
|
||
// 验证是否是升级(新等级必须高于旧等级)
|
||
if req.Level <= oldLevel {
|
||
return utils.NewError("新等级必须高于当前等级")
|
||
}
|
||
|
||
// 计算到期时间(从当前到期时间或现在起,按时长*30天计算)
|
||
var expireTime int64
|
||
if oldExpireTime > now {
|
||
expireTime = oldExpireTime + req.Duration*30*24*3600
|
||
} else {
|
||
expireTime = req.PayTime + req.Duration*30*24*3600
|
||
}
|
||
|
||
// 更新记录
|
||
updateData := map[string]interface{}{
|
||
"level": levelConfig.Level,
|
||
"max_num": levelConfig.MaxNum,
|
||
"pay_time": req.PayTime,
|
||
"expire_time": expireTime,
|
||
"updated_at": now,
|
||
}
|
||
|
||
if err := database.DB.Model(&models.EmployeeLevel{}).Where("emp_id = ? AND is_del = ?", req.EmpId, 0).Updates(updateData).Error; err != nil {
|
||
return utils.NewError("更新员工等级记录失败: " + err.Error())
|
||
}
|
||
|
||
// 记录升级日志
|
||
operationRemark := fmt.Sprintf("等级从%d升级到%d(%s),子账号数量上限从%d调整为%d,价格:%d元,时长:%d个月,新到期时间:%s",
|
||
oldLevel, levelConfig.Level, levelConfig.LevelName, oldMaxNum, levelConfig.MaxNum, (levelConfig.Price*req.Duration)/100, req.Duration,
|
||
time.Unix(expireTime, 0).Format("2006-01-02"))
|
||
if err := s.createEmployeeLevelLog(req.EmpId, 2, oldLevel, levelConfig.Level, oldMaxNum, levelConfig.MaxNum, oldExpireTime, expireTime, levelConfig.Price*req.Duration, req.PayTime, operatorID, operatorName, operationRemark); err != nil {
|
||
return err
|
||
}
|
||
|
||
case 3: // 续费
|
||
if err != nil {
|
||
return utils.NewError("该员工未开通等级,无法续费")
|
||
}
|
||
|
||
oldLevel = employeeLevel.Level
|
||
oldMaxNum = employeeLevel.MaxNum
|
||
oldExpireTime = employeeLevel.ExpireTime
|
||
|
||
// 验证续费等级必须与当前等级相同
|
||
if req.Level != oldLevel {
|
||
// 获取当前等级对应的等级名称
|
||
oldLevelConfigResult := GetLevelConfig(oldLevel)
|
||
oldLevelName := ""
|
||
if oldLevelConfigResult != nil {
|
||
oldLevelConfig := oldLevelConfigResult.(*systemRes.EmployeeLevelConfigResponse)
|
||
oldLevelName = oldLevelConfig.LevelName
|
||
}
|
||
return utils.NewError(fmt.Sprintf("续费等级必须与当前等级相同,当前等级为%s", oldLevelName))
|
||
}
|
||
|
||
// 计算新的到期时间(从当前到期时间或现在起,按时长*30天累加)
|
||
var expireTime int64
|
||
if oldExpireTime > now {
|
||
expireTime = oldExpireTime + req.Duration*30*24*3600
|
||
} else {
|
||
expireTime = req.PayTime + req.Duration*30*24*3600
|
||
}
|
||
|
||
// 更新记录(只更新到期时间和支付时间)
|
||
updateData := map[string]interface{}{
|
||
"pay_time": req.PayTime,
|
||
"expire_time": expireTime,
|
||
"updated_at": now,
|
||
}
|
||
|
||
if err := database.DB.Model(&models.EmployeeLevel{}).Where("emp_id = ? AND is_del = ?", req.EmpId, 0).Updates(updateData).Error; err != nil {
|
||
return utils.NewError("续费失败: " + err.Error())
|
||
}
|
||
|
||
// 记录续费日志
|
||
operationRemark := fmt.Sprintf("续费%s(等级%d),续费时长:%d个月,价格:%d元,原到期时间:%s,新到期时间:%s",
|
||
levelConfig.LevelName, levelConfig.Level, req.Duration, (levelConfig.Price*req.Duration)/100,
|
||
time.Unix(oldExpireTime, 0).Format("2006-01-02"),
|
||
time.Unix(expireTime, 0).Format("2006-01-02"))
|
||
if err := s.createEmployeeLevelLog(req.EmpId, 3, oldLevel, levelConfig.Level, oldMaxNum, levelConfig.MaxNum, oldExpireTime, expireTime, levelConfig.Price*req.Duration, req.PayTime, operatorID, operatorName, operationRemark); err != nil {
|
||
return err
|
||
}
|
||
|
||
default:
|
||
return utils.NewError("无效的操作类型")
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// GetEmployeeSettings 获取员工设置
|
||
func (s *EmployeeService) GetEmployeeSettings(req systemReq.GetEmployeeSettingsRequest) *systemRes.EmployeeSettingsResponse {
|
||
var employeeSettings models.EmployeeSettings
|
||
result := database.DB.Where("emp_id = ?", req.EmpId).First(&employeeSettings)
|
||
|
||
if result.Error != nil || result.RowsAffected == 0 {
|
||
defaultConfig := models.GetDefaultEmployeeSettingsConfig()
|
||
return &systemRes.EmployeeSettingsResponse{
|
||
EmpID: req.EmpId,
|
||
Settings: defaultConfig,
|
||
}
|
||
}
|
||
|
||
var config models.EmployeeSettingsConfig
|
||
if err := json.Unmarshal([]byte(employeeSettings.Settings), &config); err != nil {
|
||
config = models.GetDefaultEmployeeSettingsConfig()
|
||
}
|
||
|
||
response := systemRes.ConvertEmployeeSettingsToResponse(employeeSettings, config)
|
||
return &response
|
||
}
|
||
|
||
// SaveEmployeeSettings 保存员工设置(新增或更新)
|
||
func (s *EmployeeService) SaveEmployeeSettings(req systemReq.SaveEmployeeSettingsRequest) error {
|
||
now := time.Now().Unix()
|
||
|
||
config := models.EmployeeSettingsConfig{
|
||
ShowPrice: req.ShowPrice,
|
||
ShowCategory: req.ShowCategory,
|
||
ShowCache: req.ShowCache,
|
||
CompareCount: req.CompareCount,
|
||
CompareCountEditable: req.CompareCountEditable,
|
||
PriceCompare: req.PriceCompare,
|
||
PriceValue: req.PriceValue,
|
||
PriceEditable: req.PriceEditable,
|
||
SellCountCompare: req.SellCountCompare,
|
||
SellCountValue: req.SellCountValue,
|
||
SellCountEditable: req.SellCountEditable,
|
||
BuyCountCompare: req.BuyCountCompare,
|
||
BuyCountValue: req.BuyCountValue,
|
||
BuyCountEditable: req.BuyCountEditable,
|
||
Condition: req.Condition,
|
||
ConditionEditable: req.ConditionEditable,
|
||
JingpinEnabled: req.JingpinEnabled,
|
||
JingpinPriceCompare: req.JingpinPriceCompare,
|
||
JingpinPriceValue: req.JingpinPriceValue,
|
||
JingpinPriceEditable: req.JingpinPriceEditable,
|
||
JingpinSellCountCompare: req.JingpinSellCountCompare,
|
||
JingpinSellCountValue: req.JingpinSellCountValue,
|
||
JingpinSellCountEditable: req.JingpinSellCountEditable,
|
||
JingpinBuyCountCompare: req.JingpinBuyCountCompare,
|
||
JingpinBuyCountValue: req.JingpinBuyCountValue,
|
||
JingpinBuyCountEditable: req.JingpinBuyCountEditable,
|
||
}
|
||
|
||
settingsJSON, err := json.Marshal(config)
|
||
if err != nil {
|
||
return utils.NewError("配置序列化失败: " + err.Error())
|
||
}
|
||
|
||
var employeeSettings models.EmployeeSettings
|
||
result := database.DB.Where("emp_id = ?", req.EmpId).First(&employeeSettings)
|
||
|
||
if result.Error == nil && result.RowsAffected > 0 {
|
||
updateData := map[string]interface{}{
|
||
"settings": string(settingsJSON),
|
||
"updated_at": now,
|
||
}
|
||
|
||
if err := database.DB.Model(&employeeSettings).Updates(updateData).Error; err != nil {
|
||
return utils.NewError("更新员工设置失败: " + err.Error())
|
||
}
|
||
} else {
|
||
newSettings := models.EmployeeSettings{
|
||
EmpID: req.EmpId,
|
||
Settings: string(settingsJSON),
|
||
CreatedAt: now,
|
||
UpdatedAt: now,
|
||
}
|
||
|
||
if err := database.DB.Create(&newSettings).Error; err != nil {
|
||
return utils.NewError("创建员工设置失败: " + err.Error())
|
||
}
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// createEmployeeLevelLog 创建员工等级变更日志
|
||
func (s *EmployeeService) createEmployeeLevelLog(empId int64, operationType int8, oldLevel, newLevel int8, oldMaxNum, newMaxNum int64, oldExpireTime, newExpireTime int64, price, payTime int64, operatorID int64, operatorName, remark string) error {
|
||
now := time.Now().Unix()
|
||
|
||
log := models.EmployeeLevelLog{
|
||
EmpId: empId,
|
||
OperationType: operationType,
|
||
OldLevel: oldLevel,
|
||
NewLevel: newLevel,
|
||
OldMaxNum: oldMaxNum,
|
||
NewMaxNum: newMaxNum,
|
||
OldExpireTime: oldExpireTime,
|
||
NewExpireTime: newExpireTime,
|
||
Price: price,
|
||
PayTime: payTime,
|
||
OperatorID: operatorID,
|
||
OperatorName: operatorName,
|
||
Remark: remark,
|
||
CreatedAt: now,
|
||
IsDel: 0,
|
||
}
|
||
|
||
if err := database.DB.Create(&log).Error; err != nil {
|
||
return utils.NewError("创建等级变更日志失败: " + err.Error())
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// GetUserList 获取用户列表(主库)
|
||
/*func (s *EmployeeService) GetUserList(req systemReq.GetUserListRequest) (*systemRes.GetUserListResponse, error) {
|
||
if req.Page < 1 {
|
||
req.Page = 1
|
||
}
|
||
if req.PageSize < 1 || req.PageSize > 100 {
|
||
req.PageSize = 20
|
||
}
|
||
|
||
query := database.DB.Model(&models.Employee{}).Where("deleted_at = ?", 0)
|
||
|
||
if req.Status != "" {
|
||
query = query.Where("status = ?", req.Status)
|
||
}
|
||
if req.Keyword != "" {
|
||
query = query.Where("(employee_id_str = ? OR name LIKE ? OR username LIKE ?)",
|
||
req.Keyword, "%"+req.Keyword+"%", "%"+req.Keyword+"%")
|
||
}
|
||
|
||
var total int64
|
||
if err := query.Count(&total).Error; err != nil {
|
||
return nil, utils.NewError("查询总数失败")
|
||
}
|
||
|
||
var employees []models.Employee
|
||
offset := (req.Page - 1) * req.PageSize
|
||
if err := query.Order("created_at DESC").Offset(offset).Limit(req.PageSize).Find(&employees).Error; err != nil {
|
||
return nil, utils.NewError("查询用户列表失败")
|
||
}
|
||
|
||
var items []systemRes.UserListItem
|
||
for _, emp := range employees {
|
||
items = append(items, systemRes.UserListItem{
|
||
ID: emp.ID,
|
||
EmployeeIDStr: emp.EmployeeIDStr,
|
||
Username: emp.Username,
|
||
Name: emp.Name,
|
||
Role: emp.Role,
|
||
Status: emp.Status,
|
||
SplitAccountConfigId: emp.SplitAccountConfigId,
|
||
})
|
||
}
|
||
|
||
return &systemRes.GetUserListResponse{
|
||
List: items,
|
||
Total: total,
|
||
Page: req.Page,
|
||
PageSize: req.PageSize,
|
||
}, nil
|
||
}
|
||
*/
|
||
func (s *EmployeeService) GetUserList(req systemReq.GetUserListRequest) (*systemRes.GetUserListResponse, error) {
|
||
if req.Page < 1 {
|
||
req.Page = 1
|
||
}
|
||
if req.PageSize < 1 || req.PageSize > 100 {
|
||
req.PageSize = 20
|
||
}
|
||
|
||
query := database.DB.Model(&models.Employee{}).Where("deleted_at = ?", 0)
|
||
|
||
if req.Status != "" {
|
||
query = query.Where("status = ?", req.Status)
|
||
}
|
||
if req.Username != "" {
|
||
query = query.Where("username LIKE ?", "%"+req.Username+"%")
|
||
}
|
||
if req.Tel != "" {
|
||
query = query.Where("phone LIKE ?", "%"+req.Tel+"%")
|
||
}
|
||
|
||
var total int64
|
||
if err := query.Count(&total).Error; err != nil {
|
||
return nil, utils.NewError("查询总数失败")
|
||
}
|
||
|
||
var employees []models.Employee
|
||
offset := (req.Page - 1) * req.PageSize
|
||
if err := query.Order("created_at DESC").Offset(offset).Limit(req.PageSize).Find(&employees).Error; err != nil {
|
||
return nil, utils.NewError("查询用户列表失败")
|
||
}
|
||
|
||
// 收集所有需要查询的分账配置ID
|
||
splitConfigIDs := make([]int64, 0)
|
||
for _, emp := range employees {
|
||
if emp.SplitAccountConfigId > 0 {
|
||
splitConfigIDs = append(splitConfigIDs, emp.SplitAccountConfigId)
|
||
}
|
||
}
|
||
|
||
// 批量查询分账配置
|
||
splitConfigMap := make(map[int64]*systemRes.SplitAccountConfigInfo)
|
||
if len(splitConfigIDs) > 0 {
|
||
var splitConfigs []models.SplitAccountConfig
|
||
database.DB.Where("id IN ? AND deleted_at = ?", splitConfigIDs, 0).Find(&splitConfigs)
|
||
|
||
for _, config := range splitConfigs {
|
||
splitConfigMap[config.ID] = &systemRes.SplitAccountConfigInfo{
|
||
ID: config.ID,
|
||
RuleName: config.RuleName,
|
||
RuleValue: json.RawMessage(config.RuleValue),
|
||
Status: config.Status,
|
||
Description: config.Description,
|
||
CreatedBy: config.CreatedBy,
|
||
UpdatedBy: config.UpdatedBy,
|
||
CreatedAt: config.CreatedAt,
|
||
UpdatedAt: config.UpdatedAt,
|
||
}
|
||
}
|
||
}
|
||
|
||
var items []systemRes.UserListItem
|
||
for _, emp := range employees {
|
||
item := systemRes.UserListItem{
|
||
ID: emp.ID,
|
||
EmployeeIDStr: emp.EmployeeIDStr,
|
||
Username: emp.Username,
|
||
Name: emp.Name,
|
||
Role: emp.Role,
|
||
Status: emp.Status,
|
||
SplitAccountConfigId: emp.SplitAccountConfigId,
|
||
}
|
||
|
||
// 如果有关联的分账配置,添加详情
|
||
if emp.SplitAccountConfigId > 0 {
|
||
if config, exists := splitConfigMap[emp.SplitAccountConfigId]; exists {
|
||
item.SplitAccountConfig = config
|
||
}
|
||
}
|
||
|
||
items = append(items, item)
|
||
}
|
||
|
||
return &systemRes.GetUserListResponse{
|
||
List: items,
|
||
Total: total,
|
||
Page: req.Page,
|
||
PageSize: req.PageSize,
|
||
}, nil
|
||
}
|
||
|
||
// UpdateEmployeeSplitAccountConfigByAboutId 根据about_id更新员工分账配置ID
|
||
func (s *EmployeeService) UpdateEmployeeSplitAccountConfigByAboutId(req systemReq.UpdateEmployeeSplitAccountConfigRequest, username string) (*systemRes.UpdateEmployeeSplitAccountConfigResponse, error) {
|
||
var employee models.Employee
|
||
result := database.DB.Where("about_id = ? AND deleted_at = ?", req.AboutId, 0).First(&employee)
|
||
if result.Error != nil {
|
||
return nil, utils.NewError("员工不存在")
|
||
}
|
||
|
||
updateData := map[string]interface{}{
|
||
"split_account_config_id": req.SplitAccountConfigId,
|
||
"updated_at": time.Now().Unix(),
|
||
}
|
||
|
||
if err := database.DB.Model(&employee).Updates(updateData).Error; err != nil {
|
||
return nil, utils.NewError("更新员工分账配置失败: " + err.Error())
|
||
}
|
||
|
||
// 重新查询更新后的员工数据
|
||
if err := database.DB.Where("id = ? AND deleted_at = ?", employee.ID, 0).First(&employee).Error; err != nil {
|
||
return nil, utils.NewError("查询更新后的员工数据失败")
|
||
}
|
||
|
||
return &systemRes.UpdateEmployeeSplitAccountConfigResponse{
|
||
ID: employee.ID,
|
||
EmployeeIDStr: employee.EmployeeIDStr,
|
||
Username: employee.Username,
|
||
Name: employee.Name,
|
||
Phone: employee.Phone,
|
||
AboutId: employee.AboutId,
|
||
SplitAccountConfigId: employee.SplitAccountConfigId,
|
||
Status: employee.Status,
|
||
UpdatedAt: employee.UpdatedAt,
|
||
}, nil
|
||
}
|
||
|
||
// ... existing code ...
|
||
/*func (s *EmployeeService) UpdateEmployeeSplitAccountConfigByAboutId(req systemReq.UpdateEmployeeSplitAccountConfigRequest, username string) error {
|
||
var employee models.Employee
|
||
result := database.DB.Where("about_id = ? AND deleted_at = ?", req.AboutId, 0).First(&employee)
|
||
if result.Error != nil {
|
||
return utils.NewError("员工不存在")
|
||
}
|
||
|
||
updateData := map[string]interface{}{
|
||
"split_account_config_id": req.SplitAccountConfigId,
|
||
"updated_at": time.Now().Unix(),
|
||
}
|
||
|
||
if err := database.DB.Model(&employee).Updates(updateData).Error; err != nil {
|
||
return utils.NewError("更新员工分账配置失败: " + err.Error())
|
||
}
|
||
|
||
return nil
|
||
}
|
||
*/
|