backend
This commit is contained in:
parent
0afaed5089
commit
d74d27ab2d
|
@ -1,5 +1,14 @@
|
|||
#! /bin/bash
|
||||
name=${1%%\\*}
|
||||
|
||||
options=("backend")
|
||||
for option in "${options[@]}"; do
|
||||
if [ "$name" = "$option" ]; then
|
||||
echo "不能在"$name"里使用"
|
||||
exit
|
||||
fi
|
||||
done
|
||||
|
||||
echo $name
|
||||
goctl api go -api server_api/$name.api -dir server/$name --home ./goctl_template/
|
||||
# ctxName=server/$name/internal/svc/servicecontext.go
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#! /bin/bash
|
||||
name=${1%%\\*}
|
||||
options=("backend" "backend1" "backend2")
|
||||
options=("backend")
|
||||
for option in "${options[@]}"; do
|
||||
if [ "$name" = "$option" ]; then
|
||||
echo $name
|
||||
|
|
|
@ -20,7 +20,7 @@ func {{.HandlerName}}(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
|||
// 定义错误变量
|
||||
err error
|
||||
// 定义用户信息变量
|
||||
userinfo *auth.UserInfo
|
||||
userinfo *auth.BackendUserInfo
|
||||
)
|
||||
// 解析JWT token,并对空用户进行判断
|
||||
claims, err := svcCtx.ParseJwtToken(r)
|
||||
|
|
|
@ -27,8 +27,5 @@ func (c *FsCanteenProductModel) Create(ctx context.Context, data *FsCanteenProdu
|
|||
|
||||
func (c *FsCanteenProductModel) GetAllByCanteenTypeIdOrderAsc(ctx context.Context, typeId int64) (resp []FsCanteenProduct, err error) {
|
||||
err = c.db.WithContext(ctx).Model(&FsCanteenProduct{}).Where("`canteen_type` = ? and `status` = ?", typeId, 1).Order("sort asc").Find(&resp).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
return resp, err
|
||||
}
|
||||
|
|
|
@ -49,3 +49,8 @@ func (p *FsProductModel) GetRandomProductList(ctx context.Context, limit int) (r
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (p *FsProductModel) FindAllOnlyByIds(ctx context.Context, ids []int64) (resp []*FsProduct, err error) {
|
||||
err = p.db.WithContext(ctx).Model(&FsProduct{}).Where("`id` IN (?)", ids).Find(&resp).Error
|
||||
return resp, err
|
||||
}
|
||||
|
|
|
@ -71,3 +71,20 @@ func (p *FsProductPriceModel) GetPriceListByProductIds(ctx context.Context, prod
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 产品价格
|
||||
type ProductPrice struct {
|
||||
Id int64 `json:"id"`
|
||||
MinBuyNum int64 `json:"min_buy_num"`
|
||||
StepNum interface{} `json:"step_num"`
|
||||
StepPrice interface{} `json:"step_price"`
|
||||
ProductId int64 `json:"product_id"`
|
||||
SizeId int64 `json:"size_id"`
|
||||
EachBoxNum int64 `json:"each_box_num"`
|
||||
}
|
||||
|
||||
func (c *FsProductPriceModel) GetAllSelectBySizeId(ctx context.Context, sizeIds []int64) (prices []*ProductPrice, err error) {
|
||||
|
||||
err = c.db.WithContext(ctx).Model(&ProductPrice{}).Where("size_id IN (?) AND status = ?", sizeIds, 1).Select("id, min_buy_num, step_num, step_price, product_id, size_id, each_box_num").Find(&prices).Error
|
||||
return prices, err
|
||||
}
|
||||
|
|
|
@ -45,3 +45,13 @@ func (s *FsProductSizeModel) GetAllByProductIds(ctx context.Context, productIds
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
type CapacityId struct {
|
||||
Id int64 `json:"id"`
|
||||
Capacity string `json:"capacity"`
|
||||
}
|
||||
|
||||
func (c *FsProductSizeModel) GetAllSelectIdAndCapacityByIds(ctx context.Context, sizeIds []int64) (sizes []CapacityId, err error) {
|
||||
err = c.db.WithContext(ctx).Where("id IN ?", sizeIds).Select("id, capacity").Find(&sizes).Error
|
||||
return sizes, err
|
||||
}
|
||||
|
|
|
@ -1,2 +1,10 @@
|
|||
package gmodel
|
||||
// TODO: 使用model的属性做你想做的
|
||||
|
||||
import "context"
|
||||
|
||||
// TODO: 使用model的属性做你想做的
|
||||
|
||||
func (m *FsQuotationModel) FindOneOnlyById(ctx context.Context, quotationId int64) (resp FsQuotation, err error) {
|
||||
err = m.db.WithContext(ctx).Model(&resp).Where("`quotation_id` = ?", quotationId).Take(&resp).Error
|
||||
return resp, err
|
||||
}
|
||||
|
|
|
@ -1,2 +1,10 @@
|
|||
package gmodel
|
||||
// TODO: 使用model的属性做你想做的
|
||||
|
||||
import "context"
|
||||
|
||||
// TODO: 使用model的属性做你想做的
|
||||
|
||||
func (c *FsQuotationProductModel) GetAllByQuotationIdOrderAsc(ctx context.Context, quotationId int64) (resp []FsQuotationProduct, err error) {
|
||||
err = c.db.WithContext(ctx).Model(&FsQuotationProduct{}).Where("`quotation_id` = ? and `status` = ?", quotationId, 1).Order("sort asc").Find(&resp).Error
|
||||
return resp, err
|
||||
}
|
||||
|
|
|
@ -1,2 +1,10 @@
|
|||
package gmodel
|
||||
// TODO: 使用model的属性做你想做的
|
||||
|
||||
import "context"
|
||||
|
||||
// TODO: 使用model的属性做你想做的
|
||||
|
||||
func (c *FsQuotationRemarkTemplateModel) GetAllSelectContent(ctx context.Context) (content []string, err error) {
|
||||
err = c.db.WithContext(ctx).Model(&FsQuotationRemarkTemplate{}).Where("status = ?", 1).Select("content").Find(&content).Error
|
||||
return content, err
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ func QuotationDetailHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
|||
return
|
||||
}
|
||||
|
||||
var req types.Request
|
||||
var req types.RequestQuotationId
|
||||
// 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
package logic
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fusenapi/utils/auth"
|
||||
"fusenapi/utils/basic"
|
||||
"fusenapi/utils/collect"
|
||||
"strings"
|
||||
|
||||
"context"
|
||||
|
||||
"fusenapi/server/backend/internal/svc"
|
||||
"fusenapi/server/backend/internal/types"
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type QuotationDetailLogic struct {
|
||||
|
@ -26,9 +31,193 @@ func NewQuotationDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Q
|
|||
}
|
||||
}
|
||||
|
||||
func (l *QuotationDetailLogic) QuotationDetail(req *types.Request, userinfo *auth.BackendUserInfo) (resp *basic.Response) {
|
||||
func GetPrice(num int64, stepNum []int64, stepPrice []int64) int64 {
|
||||
//阶梯价计算
|
||||
if num > stepNum[len(stepNum)-1] {
|
||||
return stepPrice[len(stepPrice)-1]
|
||||
}
|
||||
for k, v := range stepNum {
|
||||
if num <= v {
|
||||
return stepPrice[k]
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (l *QuotationDetailLogic) QuotationDetail(req *types.RequestQuotationId, userinfo *auth.BackendUserInfo) (resp *basic.Response) {
|
||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||
// userinfo 传入值时, 一定不为null
|
||||
quot, err := l.svcCtx.AllModels.FsQuotation.FindOneOnlyById(l.ctx, req.QuotationId)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return resp.SetStatus(basic.CodeDbRecordNotFoundErr)
|
||||
}
|
||||
return resp.SetStatus(basic.CodeDbSqlErr)
|
||||
}
|
||||
|
||||
CanteenProduct, err := l.svcCtx.AllModels.FsCanteenProduct.GetAllByCanteenTypeIdOrderAsc(l.ctx, *quot.CanteenType)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return resp.SetStatus(basic.CodeDbRecordNotFoundErr)
|
||||
}
|
||||
return resp.SetStatus(basic.CodeDbSqlErr)
|
||||
}
|
||||
|
||||
quotation, err := l.svcCtx.AllModels.FsQuotationProduct.GetAllByQuotationIdOrderAsc(l.ctx, req.QuotationId)
|
||||
if err != nil {
|
||||
if err != gorm.ErrRecordNotFound {
|
||||
return resp.SetStatus(basic.CodeDbSqlErr)
|
||||
}
|
||||
}
|
||||
|
||||
var target any = quotation
|
||||
if len(quotation) == 0 {
|
||||
target = CanteenProduct
|
||||
}
|
||||
|
||||
jdata, err := json.Marshal(target)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatus(basic.CodeJsonErr)
|
||||
}
|
||||
|
||||
list := gjson.ParseBytes(jdata)
|
||||
|
||||
qFlag := len(quotation) > 0
|
||||
|
||||
//获取备注模板
|
||||
markList, err := l.svcCtx.AllModels.FsQuotationRemarkTemplate.GetAllSelectContent(l.ctx)
|
||||
|
||||
var productIds = collect.ArrayColumn[int64](CanteenProduct, "product_id")
|
||||
productList, err := l.svcCtx.AllModels.FsProduct.FindAllOnlyByIds(l.ctx, productIds)
|
||||
collect.Array2MapByKeyTag[int64](productList, "id")
|
||||
|
||||
//获取size信息
|
||||
var sizeIds = collect.ArrayColumn[int64](CanteenProduct, "SizeId")
|
||||
sizes, err := l.svcCtx.AllModels.FsProductSize.GetAllSelectIdAndCapacityByIds(l.ctx, sizeIds)
|
||||
|
||||
//获取价格信息
|
||||
productPrice, err := l.svcCtx.AllModels.FsProductPrice.GetAllSelectBySizeId(l.ctx, sizeIds)
|
||||
// product := []map[string]interface{}{}
|
||||
|
||||
product := []map[string]interface{}{}
|
||||
for _, parr := range list.Array() {
|
||||
|
||||
var priceList []map[string]int64
|
||||
|
||||
if !qFlag {
|
||||
|
||||
if price, ok := productPrice[parr.Get("size_id").Int()]; !ok {
|
||||
priceList = []map[string]int64{
|
||||
{"num": 1, "price": 0},
|
||||
{"num": 1, "price": 0},
|
||||
{"num": 1, "price": 0},
|
||||
}
|
||||
} else {
|
||||
|
||||
i := 0
|
||||
price.StepNum = collect.ArrayString2Int(strings.Split(price.StepNum.(string), ","))
|
||||
price.StepPrice = collect.ArrayString2Int(strings.Split(price.StepPrice.(string), ","))
|
||||
for price.MinBuyNum < int64(len(price.StepNum.([]string))+5) && i < 3 {
|
||||
priceList = append(priceList, map[string]int64{
|
||||
"num": int64(price.MinBuyNum * price.EachBoxNum),
|
||||
"price": GetPrice(price.MinBuyNum, price.StepNum.([]int64), price.StepPrice.([]int64)) / 100,
|
||||
})
|
||||
price.MinBuyNum++
|
||||
i++
|
||||
}
|
||||
if len(priceList) < 3 {
|
||||
for j := 0; j < 3-len(priceList); j++ {
|
||||
priceList = append(priceList, map[string]int64{"num": 1, "price": 0})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
var (
|
||||
Id any
|
||||
priceInfo any
|
||||
mark any
|
||||
sid any
|
||||
|
||||
isGift bool
|
||||
name any
|
||||
size any
|
||||
cycle any
|
||||
img any
|
||||
|
||||
num any
|
||||
)
|
||||
if qFlag {
|
||||
|
||||
Id = parr.Get("id")
|
||||
|
||||
err = json.Unmarshal([]byte(parr.Get("price_info").String()), &priceInfo)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatus(basic.CodeJsonErr)
|
||||
}
|
||||
|
||||
if parr.Get("sid").Exists() {
|
||||
sid = parr.Get("sid").Int()
|
||||
}
|
||||
|
||||
name = parr.Get("name").String()
|
||||
size = parr.Get("size").Int()
|
||||
cycle = parr.Get("cycle").Int()
|
||||
img = parr.Get("img").String()
|
||||
|
||||
if parr.Get("remark").Exists() {
|
||||
err = json.Unmarshal([]byte(parr.Get("remark").String()), &mark)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatus(basic.CodeJsonErr)
|
||||
}
|
||||
}
|
||||
|
||||
num = parr.Get("num").Int()
|
||||
|
||||
} else {
|
||||
|
||||
if parr.Get("sid").Exists() {
|
||||
sid = parr.Get("sid").Int()
|
||||
}
|
||||
|
||||
productList
|
||||
|
||||
$productList[$parr['product_id']]['title']
|
||||
|
||||
|
||||
}
|
||||
|
||||
product = append(product, map[string]interface{}{
|
||||
"id": Id,
|
||||
"s_id": sid,
|
||||
"is_gift": isGift,
|
||||
"name": name,
|
||||
"size": size,
|
||||
"cycle": cycle,
|
||||
"img": img,
|
||||
"mark": mark,
|
||||
"price_list": priceInfo,
|
||||
"num": num,
|
||||
})
|
||||
|
||||
// product = append(product, map[string]interface{}{
|
||||
// "id": qFlag ? parr.ID : nil,
|
||||
// "sId": parr.SID ? parr.SID : nil,
|
||||
// "isGift": qFlag && parr.IsGift,
|
||||
// "name": qFlag ? parr.Name : productList[parr.ProductID].Title,
|
||||
// "size": qFlag ? parr.Size : sizes[parr.SizeId].Capacity,
|
||||
// "cycle": qFlag ? parr.Cycle : productList[parr.ProductID].ProduceDays + productList[parr.ProductID].DeliveryDays,
|
||||
// "img": qFlag ? parr.Img : "",
|
||||
// "mark": qFlag && parr.Remark ? json.Unmarshal(parr.Remark) : nil,
|
||||
// "priceList": qFlag ? json.Unmarshal(parr.PriceInfo) : priceList,
|
||||
// "num": qFlag ? parr.Num : 1,
|
||||
// })
|
||||
}
|
||||
|
||||
return resp.SetStatus(basic.CodeOK)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import "basic.api"
|
|||
service backend {
|
||||
// 报价单详情
|
||||
@handler QuotationDetailHandler
|
||||
get /quotation/detail(request) returns (response);
|
||||
get /quotation/detail(RequestQuotationId) returns (response);
|
||||
|
||||
@handler BackendUserLoginHandler
|
||||
post /backend-user/login(RequestUserLogin) returns (response);
|
||||
|
|
82
utils/collect/collect.go
Normal file
82
utils/collect/collect.go
Normal file
|
@ -0,0 +1,82 @@
|
|||
package collect
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func ArrayColumn[R any, T any](arr []T, column string) []R {
|
||||
var result []R
|
||||
s := reflect.ValueOf(arr)
|
||||
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
e := s.Index(i)
|
||||
k := e.FieldByName(column)
|
||||
result = append(result, k.Interface().(R))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func ArrayIndex[T any](arr []T, index int) (result T, ok bool) {
|
||||
if index < len(arr) {
|
||||
result = arr[index]
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
ok = false
|
||||
return
|
||||
}
|
||||
|
||||
func ArrayString2Int(arr interface{}) (result []int64) {
|
||||
for _, a := range arr.([]string) {
|
||||
v, err := strconv.ParseInt(a, 10, 64)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
result = append(result, v)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func Array2MapByKey[KEY comparable, VALUE any](arrSrc []VALUE, fieldName string) (result map[KEY]VALUE) {
|
||||
result = make(map[KEY]VALUE)
|
||||
arr := reflect.ValueOf(arrSrc)
|
||||
|
||||
for i := 0; i < arr.Len(); i++ {
|
||||
srcv := arr.Index(i)
|
||||
fv := srcv.Elem().FieldByName(fieldName)
|
||||
k := fv.Interface().(KEY)
|
||||
result[k] = srcv.Interface().(VALUE)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func Array2MapByKeyTag[KEY comparable, VALUE any](arrSrc []VALUE, tag string) (result map[KEY]VALUE) {
|
||||
|
||||
arr := reflect.ValueOf(arrSrc)
|
||||
|
||||
if arr.Len() == 0 {
|
||||
return result
|
||||
}
|
||||
result = make(map[KEY]VALUE)
|
||||
|
||||
eleType := arr.Index(0).Elem().Type()
|
||||
|
||||
for j := 0; j < eleType.NumField(); j++ {
|
||||
if value, ok := eleType.Field(j).Tag.Lookup("json"); ok && value == tag {
|
||||
|
||||
for i := 0; i < arr.Len(); i++ {
|
||||
srcv := arr.Index(i)
|
||||
fv := srcv.Elem().Field(j)
|
||||
k := fv.Interface().(KEY)
|
||||
result[k] = srcv.Interface().(VALUE)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
32
utils/collect/collect_test.go
Normal file
32
utils/collect/collect_test.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
package collect
|
||||
|
||||
import (
|
||||
"log"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type ABC struct {
|
||||
A int64 `json:"a"`
|
||||
B string `json:"b"`
|
||||
C interface{} `json:"c"`
|
||||
}
|
||||
|
||||
func TestArray2MapByKey(t *testing.T) {
|
||||
var abcs []*ABC = []*ABC{
|
||||
{1, "2", 3},
|
||||
{3, "1", 2},
|
||||
}
|
||||
a := Array2MapByKey[string](abcs, "B")
|
||||
log.Printf("%##v", a)
|
||||
log.Println(len(a))
|
||||
}
|
||||
|
||||
func TestArray2MapByKeyTag(t *testing.T) {
|
||||
var abcs []*ABC = []*ABC{
|
||||
{1, "2", 3},
|
||||
{3, "1", 2},
|
||||
}
|
||||
a := Array2MapByKeyTag[int64](abcs, "a")
|
||||
log.Printf("%##v", a)
|
||||
log.Println(len(a))
|
||||
}
|
Loading…
Reference in New Issue
Block a user