This commit is contained in:
eson 2023-06-26 18:19:51 +08:00
parent 0afaed5089
commit d74d27ab2d
15 changed files with 377 additions and 12 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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{

View File

@ -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)
}

View File

@ -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
View 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
}

View 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))
}