Files
platforms/backend/api/internal/logic/gas/staff.go

314 lines
10 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package gas
import (
"time"
"git.apinb.com/bsm-sdk/core/errcode"
"git.apinb.com/bsm-sdk/core/infra"
"git.apinb.com/heqiapp/platforms/backend/api/internal/impl"
"git.apinb.com/heqiapp/platforms/backend/api/internal/logic/common"
"git.apinb.com/heqiapp/platforms/backend/api/internal/logic/upload"
"git.apinb.com/heqiapp/platforms/backend/api/internal/models"
"github.com/gin-gonic/gin"
)
var gasStaffRoles = map[string]bool{"installer": true, "delivery": true, "operations": true}
var gasWorkStatuses = map[string]bool{"on_duty": true, "off_duty": true}
func ListStaff(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
page, size := common.PageSize(ctx)
var list []models.StaffAccount
var total int64
query := common.ApplyKeywordFilter(ctx,
common.ActiveRecords(impl.DBService.Model(&models.StaffAccount{})).Where("gas_basic_id = ?", station.ID),
&models.StaffAccount{})
if roleCode := ctx.Query("role_code"); roleCode != "" {
if !gasStaffRoles[roleCode] {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return
}
query = query.Where("role_code = ?", roleCode)
}
if err := query.Count(&total).Error; err != nil {
infra.Response.Error(ctx, err)
return
}
if err := query.Order("created_at desc").Offset((page - 1) * size).Limit(size).Find(&list).Error; err != nil {
infra.Response.Error(ctx, err)
return
}
respondList(ctx, list, total)
}
func GetStaff(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
respondScopedRecord(ctx, common.ActiveRecords(impl.DBService).
Where("identity = ? AND gas_basic_id = ?", ctx.Param("identity"), station.ID), &models.StaffAccount{})
}
// GetStaffAvatar 返回当前气站范围内工作人员的受保护头像。
func GetStaffAvatar(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
var account models.StaffAccount
if err := common.ActiveRecords(impl.DBService).Select("avatar").
Where("identity = ? AND gas_basic_id = ?", ctx.Param("identity"), station.ID).
First(&account).Error; err != nil {
common.RespondRecordError(ctx, err)
return
}
upload.ServeAvatar(ctx, account.Avatar)
}
type staffRequest struct {
Username string `json:"username"`
Password string `json:"password"`
Name string `json:"name" binding:"required,max=64"`
Phone string `json:"phone" binding:"max=32"`
Avatar *string `json:"avatar" binding:"omitempty,max=512"`
RoleCode string `json:"role_code" binding:"required"`
DeliveryBasicIdentity string `json:"delivery_basic_identity"`
WorkStatus string `json:"work_status" binding:"required"`
}
func CreateStaff(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
var request staffRequest
if err := ctx.ShouldBindJSON(&request); err != nil || request.Username == "" ||
!common.IsValidAccountPassword(request.Password) || !gasStaffRoles[request.RoleCode] || !gasWorkStatuses[request.WorkStatus] {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return
}
var deliveryID uint64
if request.DeliveryBasicIdentity != "" {
delivery, ok := requireDelivery(ctx, request.DeliveryBasicIdentity, station.ID)
if !ok {
return
}
deliveryID = delivery.ID
}
hash, err := common.PasswordHash(request.Password)
if err != nil {
infra.Response.Error(ctx, err)
return
}
avatar := ""
if request.Avatar != nil {
avatar = *request.Avatar
}
staff := models.StaffAccount{
Entity: common.NewEntity(common.StatusEnable), Username: request.Username, PasswordHash: hash,
Name: request.Name, Phone: request.Phone, Avatar: avatar, RoleCode: request.RoleCode,
GasBasicID: station.ID, DeliveryBasicID: deliveryID, WorkStatus: request.WorkStatus,
}
if err := common.CreateStaffRecord(&staff); err != nil {
infra.Response.Error(ctx, err)
return
}
common.RespondCreatedResource(ctx, staff)
}
func UpdateStaff(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
if _, ok := requireStaff(ctx, ctx.Param("identity"), station.ID); !ok {
return
}
var request staffRequest
if err := ctx.ShouldBindJSON(&request); err != nil || !gasStaffRoles[request.RoleCode] || !gasWorkStatuses[request.WorkStatus] {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return
}
var deliveryID uint64
if request.DeliveryBasicIdentity != "" {
delivery, ok := requireDelivery(ctx, request.DeliveryBasicIdentity, station.ID)
if !ok {
return
}
deliveryID = delivery.ID
}
values := gin.H{
"name": request.Name, "phone": request.Phone, "role_code": request.RoleCode,
"delivery_basic_id": deliveryID, "work_status": request.WorkStatus,
}
// 未选择新头像时不提交 avatar避免编辑基础资料误清空现有头像。
if request.Avatar != nil {
values["avatar"] = *request.Avatar
}
common.UpdateAllowedByIdentityWithError(ctx, &models.StaffAccount{}, values, []string{"name", "phone", "avatar", "role_code", "delivery_basic_id", "work_status"}, common.StaffWriteError)
}
func UpdateStaffStatus(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
if _, ok := requireStaff(ctx, ctx.Param("identity"), station.ID); !ok {
return
}
common.UpdateRecordStatus(ctx, &models.StaffAccount{})
}
func ArchiveStaff(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
staff, ok := requireStaff(ctx, ctx.Param("identity"), station.ID)
if !ok {
return
}
var blocking int64
if err := impl.DBService.Model(&models.GasorderBasic{}).
Where("staff_account_id = ? AND order_status NOT IN ?", staff.ID, []int{common.StatusCompleted, common.StatusCancelled}).
Count(&blocking).Error; err != nil || blocking > 0 {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return
}
if err := impl.DBService.Model(&staff).Update("status", common.StatusArchived).Error; err != nil {
infra.Response.Error(ctx, err)
return
}
infra.Response.Success(ctx, gin.H{"archived": true})
}
func ListCredential(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
page, size := common.PageSize(ctx)
var list []models.StaffCredential
var total int64
query := common.ActiveRecords(impl.DBService.Model(&models.StaffCredential{})).
Joins("JOIN staff_account ON staff_account.id = staff_credential.staff_account_id").
Where("staff_account.gas_basic_id = ?", station.ID)
if err := query.Count(&total).Error; err != nil {
infra.Response.Error(ctx, err)
return
}
if err := query.Order("staff_credential.created_at desc").Offset((page - 1) * size).Limit(size).Find(&list).Error; err != nil {
infra.Response.Error(ctx, err)
return
}
respondList(ctx, list, total)
}
func GetCredential(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
query := common.ActiveRecords(impl.DBService.Model(&models.StaffCredential{})).
Joins("JOIN staff_account ON staff_account.id = staff_credential.staff_account_id").
Where("staff_credential.identity = ? AND staff_account.gas_basic_id = ?", ctx.Param("identity"), station.ID)
respondScopedRecord(ctx, query, &models.StaffCredential{})
}
type credentialRequest struct {
StaffAccountIdentity string `json:"staff_account_identity" binding:"required"`
CredentialType string `json:"credential_type" binding:"required,max=64"`
CredentialNo string `json:"credential_no" binding:"max=128"`
ExpiredAt *time.Time `json:"expired_at"`
}
func CreateCredential(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
var request credentialRequest
if err := ctx.ShouldBindJSON(&request); err != nil {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return
}
staff, ok := requireStaff(ctx, request.StaffAccountIdentity, station.ID)
if !ok {
return
}
credential := models.StaffCredential{
Entity: common.NewEntity(common.StatusEnable), StaffAccountID: staff.ID,
CredentialType: request.CredentialType, CredentialNo: request.CredentialNo, ExpiredAt: request.ExpiredAt,
}
if err := impl.DBService.Create(&credential).Error; err != nil {
infra.Response.Error(ctx, err)
return
}
common.RespondCreatedResource(ctx, credential)
}
func UpdateCredential(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
var existing models.StaffCredential
if err := common.ActiveRecords(impl.DBService.Model(&models.StaffCredential{})).
Select("staff_credential.*").
Joins("JOIN staff_account ON staff_account.id = staff_credential.staff_account_id").
Where("staff_credential.identity = ? AND staff_account.gas_basic_id = ?", ctx.Param("identity"), station.ID).
First(&existing).Error; err != nil {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return
}
var request credentialRequest
if err := ctx.ShouldBindJSON(&request); err != nil {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return
}
staff, ok := requireStaff(ctx, request.StaffAccountIdentity, station.ID)
if !ok {
return
}
common.UpdateAllowedByIdentity(ctx, &models.StaffCredential{}, gin.H{
"staff_account_id": staff.ID, "credential_type": request.CredentialType,
"credential_no": request.CredentialNo, "expired_at": request.ExpiredAt,
}, []string{"staff_account_id", "credential_type", "credential_no", "expired_at"})
}
func UpdateCredentialStatus(ctx *gin.Context) {
archiveCredentialWithStatus(ctx, 0, false)
}
func ArchiveCredential(ctx *gin.Context) {
archiveCredentialWithStatus(ctx, common.StatusArchived, true)
}
func archiveCredentialWithStatus(ctx *gin.Context, status int, fixed bool) {
station, ok := currentGas(ctx)
if !ok {
return
}
var count int64
if err := impl.DBService.Model(&models.StaffCredential{}).
Joins("JOIN staff_account ON staff_account.id = staff_credential.staff_account_id").
Where("staff_credential.identity = ? AND staff_account.gas_basic_id = ?", ctx.Param("identity"), station.ID).
Count(&count).Error; err != nil || count != 1 {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return
}
if fixed {
if err := impl.DBService.Model(&models.StaffCredential{}).Where("identity = ?", ctx.Param("identity")).Update("status", status).Error; err != nil {
infra.Response.Error(ctx, err)
return
}
infra.Response.Success(ctx, gin.H{"archived": true})
return
}
common.UpdateRecordStatus(ctx, &models.StaffCredential{})
}