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

282 lines
8.9 KiB
Go

package gas
import (
"bytes"
"encoding/json"
"io"
"reflect"
"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"
platformgasorder "git.apinb.com/heqiapp/platforms/backend/api/internal/logic/platform/gasorder"
"git.apinb.com/heqiapp/platforms/backend/api/internal/models"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
func rewriteJSON(ctx *gin.Context, mutate func(map[string]any) bool) bool {
body, err := io.ReadAll(ctx.Request.Body)
if err != nil {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return false
}
var values map[string]any
if err := json.Unmarshal(body, &values); err != nil || !mutate(values) {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return false
}
body, err = json.Marshal(values)
if err != nil {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return false
}
ctx.Request.Body = io.NopCloser(bytes.NewReader(body))
return true
}
func scopedContract(ctx *gin.Context, identity string, gasID uint64) (models.GasorderContract, bool) {
var contract models.GasorderContract
if err := common.ActiveRecords(impl.DBService).Where("identity = ? AND gas_basic_id = ?", identity, gasID).First(&contract).Error; err != nil {
common.RespondRecordError(ctx, err)
return contract, false
}
return contract, true
}
func scopedOrder(ctx *gin.Context, identity string, gasID uint64) (models.GasorderBasic, bool) {
var order models.GasorderBasic
if err := common.ActiveRecords(impl.DBService).Where("identity = ? AND gas_basic_id = ?", identity, gasID).First(&order).Error; err != nil {
common.RespondRecordError(ctx, err)
return order, false
}
return order, true
}
func ListGasorderContract(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
listScoped(ctx, &models.GasorderContract{}, common.ActiveRecords(impl.DBService.Model(&models.GasorderContract{})).
Where("gas_basic_id = ?", station.ID), "gasorder_contract.created_at desc")
}
func GetGasorderContract(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
if _, ok := scopedContract(ctx, ctx.Param("identity"), station.ID); ok {
platformgasorder.GetGasorderContract(ctx)
}
}
func CreateGasorderContract(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
if !rewriteJSON(ctx, func(values map[string]any) bool {
userIdentity, _ := values["user_account_identity"].(string)
if _, _, valid := requireUser(ctx, userIdentity, station.ID); !valid {
return false
}
if deliveryIdentity, _ := values["delivery_basic_identity"].(string); deliveryIdentity != "" {
if _, valid := requireDelivery(ctx, deliveryIdentity, station.ID); !valid {
return false
}
}
values["gas_basic_identity"] = station.Identity
return true
}) {
return
}
platformgasorder.CreateGasorderContract(ctx)
}
func withContract(ctx *gin.Context, handler gin.HandlerFunc) {
station, ok := currentGas(ctx)
if !ok {
return
}
if _, ok := scopedContract(ctx, ctx.Param("identity"), station.ID); ok {
handler(ctx)
}
}
func UpdateGasorderContract(ctx *gin.Context) {
withContract(ctx, platformgasorder.UpdateGasorderContract)
}
func ActivateGasorderContract(ctx *gin.Context) {
withContract(ctx, platformgasorder.ActivateGasorderContract)
}
func RenewGasorderContract(ctx *gin.Context) {
withContract(ctx, platformgasorder.RenewGasorderContract)
}
func TerminateGasorderContract(ctx *gin.Context) {
withContract(ctx, platformgasorder.TerminateGasorderContract)
}
func BindGasorderContractProduct(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
if !rewriteJSON(ctx, func(values map[string]any) bool {
identity, _ := values["gasorder_contract_identity"].(string)
_, valid := scopedContract(ctx, identity, station.ID)
return valid
}) {
return
}
platformgasorder.BindGasorderContractProduct(ctx)
}
func UnbindGasorderContractProduct(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
var binding models.GasorderContractProduct
err := common.ActiveRecords(impl.DBService.Model(&models.GasorderContractProduct{})).
Select("gasorder_contract_product.*").
Joins("JOIN gasorder_contract ON gasorder_contract.id = gasorder_contract_product.gasorder_contract_id").
Where("gasorder_contract_product.identity = ? AND gasorder_contract.gas_basic_id = ?", ctx.Param("identity"), station.ID).
First(&binding).Error
if err != nil {
common.RespondRecordError(ctx, err)
return
}
platformgasorder.UnbindGasorderContractProduct(ctx)
}
func ListGasorderContractProduct(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
query := common.ActiveRecords(impl.DBService.Model(&models.GasorderContractProduct{})).
Joins("JOIN gasorder_contract ON gasorder_contract.id = gasorder_contract_product.gasorder_contract_id").
Where("gasorder_contract.gas_basic_id = ?", station.ID)
listScoped(ctx, &models.GasorderContractProduct{}, query, "gasorder_contract_product.created_at desc")
}
// ListContractProductCandidate 仅返回当前气站服务用户名下可用于合同绑定的气瓶。
func ListContractProductCandidate(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
query := common.ActiveRecords(impl.DBService.Model(&models.ProductInfo{})).
Joins("JOIN user_service_relation ON user_service_relation.user_account_id = product_info.user_account_id AND user_service_relation.status <> ?",
common.StatusArchived).
Where("user_service_relation.gas_basic_id = ?", station.ID)
listScoped(ctx, &models.ProductInfo{}, query, "product_info.created_at desc")
}
func ListGasorderContractRevision(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
query := common.ActiveRecords(impl.DBService.Model(&models.GasorderContractRevision{})).
Joins("JOIN gasorder_contract ON gasorder_contract.id = gasorder_contract_revision.gasorder_contract_id").
Where("gasorder_contract.gas_basic_id = ?", station.ID)
listScoped(ctx, &models.GasorderContractRevision{}, query, "gasorder_contract_revision.created_at desc")
}
func ListGasorderBasic(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
listScoped(ctx, &models.GasorderBasic{}, common.ActiveRecords(impl.DBService.Model(&models.GasorderBasic{})).
Where("gas_basic_id = ?", station.ID), "gasorder_basic.created_at desc")
}
func GetGasorderBasic(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
if _, ok := scopedOrder(ctx, ctx.Param("identity"), station.ID); ok {
platformgasorder.GetGasorderBasic(ctx)
}
}
func CreateGasorderBasic(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
if !rewriteJSON(ctx, func(values map[string]any) bool {
contractIdentity, _ := values["gasorder_contract_identity"].(string)
if _, valid := scopedContract(ctx, contractIdentity, station.ID); !valid {
return false
}
values["creator_type"] = "gas"
values["creator_identity"] = station.Identity
return true
}) {
return
}
platformgasorder.CreateGasorderBasic(ctx)
}
func withOrder(ctx *gin.Context, handler gin.HandlerFunc) {
station, ok := currentGas(ctx)
if !ok {
return
}
if _, ok := scopedOrder(ctx, ctx.Param("identity"), station.ID); ok {
handler(ctx)
}
}
func AssignGasorderBasic(ctx *gin.Context) {
station, ok := currentGas(ctx)
if !ok {
return
}
if _, ok := scopedOrder(ctx, ctx.Param("identity"), station.ID); !ok {
return
}
if !rewriteJSON(ctx, func(values map[string]any) bool {
deliveryIdentity, _ := values["delivery_basic_identity"].(string)
staffIdentity, _ := values["staff_account_identity"].(string)
_, deliveryOK := requireDelivery(ctx, deliveryIdentity, station.ID)
_, staffOK := requireStaff(ctx, staffIdentity, station.ID)
return deliveryOK && staffOK
}) {
return
}
platformgasorder.AssignGasorderBasic(ctx)
}
func GasorderStartFilling(ctx *gin.Context) { withOrder(ctx, platformgasorder.GasorderStartFilling) }
func GasorderReady(ctx *gin.Context) { withOrder(ctx, platformgasorder.GasorderReady) }
func GasorderException(ctx *gin.Context) { withOrder(ctx, platformgasorder.GasorderException) }
func GasorderRecover(ctx *gin.Context) { withOrder(ctx, platformgasorder.GasorderRecover) }
func GasorderCancel(ctx *gin.Context) { withOrder(ctx, platformgasorder.GasorderCancel) }
func listScoped(ctx *gin.Context, model any, query *gorm.DB, order string) {
page, size := common.PageSize(ctx)
var total int64
if err := common.ApplyKeywordFilter(ctx, query, model).Count(&total).Error; err != nil {
infra.Response.Error(ctx, err)
return
}
list := sliceForModel(model)
if err := common.ApplyKeywordFilter(ctx, query, model).Order(order).Offset((page - 1) * size).Limit(size).Find(list).Error; err != nil {
infra.Response.Error(ctx, err)
return
}
respondList(ctx, list, total)
}
func sliceForModel(model any) any {
return reflect.New(reflect.SliceOf(reflect.TypeOf(model).Elem())).Interface()
}