Browse Source

init

master v0.1.0
guzeng 3 years ago
parent
commit
d4bcc5547f
6 changed files with 587 additions and 0 deletions
  1. +234
    -0
      commission.go
  2. +37
    -0
      commission_test.go
  3. +41
    -0
      order_sign.go
  4. +69
    -0
      order_sn.go
  5. +30
    -0
      order_sn_test.go
  6. +176
    -0
      order_status.go

+ 234
- 0
commission.go View File

@ -0,0 +1,234 @@
/**
* 计算佣金
* 2020/05/22
*/
package ordercalc
import (
"errors"
"strings"
)
/**
* 计算某一商品对分销商的分销价
* @param business 分销商信息
* @param productSpecialPrice 分销特殊价格
* @param distributionPrice 基础分销价
* @param percentage 分销比例
* @param productPrice 商品销售价
* 2020/05/22
* gz
*/
func DistributionPrice(business map[string]string, productSpecialPrice []map[string]string, distributionPrice interface{}, percentAge interface{}, productPrice interface{}) (float64, error) {
product_price := ToString(productPrice)
if len(business) < 1 {
return 0, errors.New("参数错误")
}
_, idExist := business["Id"]
_, levelIdExist := business["LevelId"]
if !idExist || !levelIdExist {
return 0, errors.New("分销商参数错误")
}
distribution_price := ToString(distributionPrice)
distribution_price_float, err := ToFloat64(distributionPrice)
if err != nil {
return 0, err
}
percent_age := ToString(percentAge)
if len(productSpecialPrice) < 1 && percent_age == "" {
return distribution_price_float, nil //没有特殊价格,没有分销比例,返回原分销价
}
var formula string //分销价计算公式
var is_special_price bool = false //是否使用特殊价格方式,因特殊价格中可能只能会员价,记录以供再次判断
var ok bool
if len(productSpecialPrice) > 0 { //特殊价格方式
is_special_price = true //有一条特殊价格,则是使用特殊价
for _, item := range productSpecialPrice {
if _, ok = item["BusinessId"]; ok {
if item["BusinessId"] != "0" && item["BusinessId"] == business["Id"] {
formula = item["DistributionPrice"]
break
}
}
if _, ok = item["BusinessLevelId"]; ok {
if item["BusinessLevelId"] != "0" && item["BusinessLevelId"] == business["LevelId"] {
formula = item["DistributionPrice"]
}
}
}
}
var price []string
var result float64 = 0 //最终分销价
if is_special_price {
if formula != "" {
formula = strings.Replace(formula, "#distribution_price#", distribution_price, 1)
} else {
formula = distribution_price
}
//计算表达式
switch {
case strings.Contains(formula, "+"):
price = strings.Split(formula, "+")
result = FloatAdd(price[0], price[1])
case strings.Contains(formula, "-"):
price = strings.Split(formula, "-")
result = FloatSub(price[0], price[1])
case strings.Contains(formula, "*"):
price = strings.Split(formula, "*")
result = FloatMul(price[0], price[1], 2)
case strings.Contains(formula, "/"):
price = strings.Split(formula, "/")
result = FloatQuo(price[0], price[1], 2)
default:
//使用固定价格或者使用基础分销价
if formula != "" {
result, _ = ToFloat64(formula)
} else {
result = distribution_price_float
}
}
} else {
//使用分销比例
if product_price == "" {
return 0, errors.New("商品价格错误")
}
price = strings.Split(percent_age, ":")
totalCommission := FloatSub(productPrice, distributionPrice) //总佣金
if totalCommission <= 0 {
return ToFloat64(productPrice) //总佣金为负,返回商品原价
}
if _, ok = business["Grade"]; ok {
level_count := len(price) //分销级数
var totalPercent, cent, commission float64 //总分配份数,分销比例,获得的佣金
switch level_count {
case 3:
totalPercent = FloatAdd(price[0], price[1], price[2])
if totalPercent <= 0 {
result = distribution_price_float //佣金分配比例为0,返回基础分销价
} else {
switch business["Grade"] {
case "1":
//一级分销商得到所有佣金
cent = 1 //分销比例
case "2":
//二级分销商得到所有佣金
cent = FloatQuo(FloatAdd(price[0], price[1]), totalPercent) //分销比例
case "0", "3":
//三级或无级别分销商得到所有佣金
cent = FloatQuo(price[0], totalPercent) //分销比例
}
commission = FloatMul(totalCommission, cent, 2)
result = FloatSub(productPrice, commission) //分销价=商品价-佣金
}
case 2:
totalPercent = FloatAdd(price[0], price[1])
if totalPercent <= 0 {
result = distribution_price_float //佣金分配比例为0,返回基础分销价
} else {
switch business["Grade"] {
case "1":
//一级分销商得到所有佣金
cent = 1 //分销比例
case "0", "2":
//二级或无级别分销商得到所有佣金
cent = FloatQuo(price[0], totalPercent) //分销比例
}
commission = FloatMul(totalCommission, cent, 2)
result = FloatSub(productPrice, commission) //分销价=商品价-佣金
}
case 1:
//只有一级
result = distribution_price_float
}
} else {
return 0, errors.New("分销商参数错误,没有分销级别")
}
}
if result < 0 {
result, _ = ToFloat64(productPrice)
}
return result, nil
}
/**
* 计算某一商品的VIP价
* @param productSpecialPrice 特殊价格
* @param productPrice 商品销售价
* 2020/06/05
* gz
*/
func VipPrice(productSpecialPrice []map[string]string, productPrice interface{}) (float64, error) {
product_price := ToString(productPrice)
product_price_float, _ := ToFloat64(productPrice)
if len(productSpecialPrice) < 1 {
return product_price_float, nil //没有特殊价格,返回原价
}
var formula string //VIP价计算公式
var ok bool
for _, item := range productSpecialPrice {
if _, ok = item["RetailPrice"]; ok {
if item["RetailPrice"] != "" {
formula = item["RetailPrice"]
break
}
}
}
if formula != "" {
formula = strings.Replace(formula, "#retail_price#", product_price, 1)
} else {
formula = product_price
}
//计算表达式
var price []string
var result float64 = 0 //最终VIP价
switch {
case strings.Contains(formula, "+"):
price = strings.Split(formula, "+")
result = FloatAdd(price[0], price[1])
case strings.Contains(formula, "-"):
price = strings.Split(formula, "-")
result = FloatSub(price[0], price[1])
case strings.Contains(formula, "*"):
price = strings.Split(formula, "*")
result = FloatMul(price[0], price[1], 2)
case strings.Contains(formula, "/"):
price = strings.Split(formula, "/")
result = FloatQuo(price[0], price[1], 2)
default:
result = product_price_float
}
if result < 0 || result > product_price_float {
result = product_price_float
}
return result, nil
}

+ 37
- 0
commission_test.go View File

@ -0,0 +1,37 @@
package ordercalc
import (
"testing"
)
func Test_DistributionPrice(t *testing.T) {
business := map[string]string{"Id": "4", "LevelId": "3", "Grade": "3"}
productSpecialPrice := make([]map[string]string, 0)
price := make(map[string]string)
price["BusinessId"] = "0"
price["BusinessLevelId"] = "2"
// price["DistributionPrice"] = "#distribution_price#+5"
price["DistributionPrice"] = "0.05"
// productSpecialPrice = append(productSpecialPrice, price)
price = make(map[string]string)
price["BusinessId"] = "0"
price["BusinessLevelId"] = "3"
price["DistributionPrice"] = "0.05"
// productSpecialPrice = append(productSpecialPrice, price)
price = make(map[string]string)
price["BusinessId"] = "0"
price["BusinessLevelId"] = ""
price["DistributionPrice"] = "12"
// productSpecialPrice = append(productSpecialPrice, price)
dis, err := DistributionPrice(business, productSpecialPrice, 0.07, "7:2:1", 0.5)
t.Log(dis)
t.Log(err)
}

+ 41
- 0
order_sign.go View File

@ -0,0 +1,41 @@
package ordercalc
import (
"crypto/md5"
"encoding/hex"
"strings"
)
/**
* 通知订单状态时签名
* 签名方式md5(order_sn-status--time---appid)
* 2020/08/21
*gz
*/
func Sign(order_sn, status, time, appid string) string {
return Md5Password(StringJoin(order_sn, "--", status, "--", time, "--", appid))
}
//密码加密
func Md5Password(password string) string {
h := md5.New()
h.Write([]byte(password)) // 需要加密的字符串
cipher2Str := h.Sum(nil)
sMd5 := hex.EncodeToString(cipher2Str) // 输出加密结果
return sMd5
}
/*
* 连接多个字符串
* 2019/05/05
*/
func StringJoin(s ...string) string {
var build strings.Builder
if len(s) > 0 {
for _, v := range s {
build.WriteString(v)
}
}
return build.String()
}

+ 69
- 0
order_sn.go View File

@ -0,0 +1,69 @@
package ordercalc
import (
"math/rand"
"strconv"
"strings"
"time"
)
/**
* 订单号规则
* id后4位随机4位+当前时间10
* 2020/08/10
*/
func NewOrderSn(user_id string) string {
var prefix string
if user_id != "" {
if len(user_id) > 4 {
prefix = user_id[len(user_id)-4:] //截取后4位
} else {
prefix = user_id
}
} else {
//随机4位
str := "123456789"
bytes := []byte(str)
result := []byte{}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < 4; i++ {
result = append(result, bytes[r.Intn(len(bytes))])
}
prefix = string(result)
}
//拼接
var build strings.Builder
build.WriteString(prefix)
build.WriteString(strconv.FormatInt(time.Now().Unix(), 10)) //当前时间
return build.String()
}
/**
* 核销码规则
* 随机2位+当前时间6
* 2020/08/10
*/
func VerifyNumber() string {
var prefix string
//随机4位
str := "123456789"
bytes := []byte(str)
result := []byte{}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < 1; i++ {
result = append(result, bytes[r.Intn(len(bytes))])
}
prefix = string(result)
//拼接
var build strings.Builder
build.WriteString(prefix)
build.WriteString(strconv.FormatInt(time.Now().UnixNano(), 10)[10:17]) //当前时间
return build.String()
}

+ 30
- 0
order_sn_test.go View File

@ -0,0 +1,30 @@
package ordercalc
import (
"testing"
"time"
)
func Test_NewNumber(t *testing.T) {
t.Log(time.Now().UnixNano())
var set map[string]int
set = make(map[string]int)
var i, reply int = 0, 0
var num string
for i < 100000 {
i++
num = VerifyNumber()
if _, ok := set[num]; ok {
reply++
} else {
set[num] = i
}
}
t.Log("reply:", reply)
// t.Log(set)
}

+ 176
- 0
order_status.go View File

@ -0,0 +1,176 @@
package ordercalc
/**
'0': 待支付 下单尚未支付 created
'1':已支付 付款成功此状态可退款 payed
'5'已验证 虚拟订单验证核销码 using
'6'已完成 与供应商结算后订单结束配送订单配送完成 finished
'7'已取消 订单取消 canceled
'8'自动取消 到期未支付自动取消此状态可由管理员手动延期取消 autocanceled
'9'申请退款 用户自助申请退订单此状态可退款
'13'已退款 订单完成退款 refunded
'15'自动完成 使用时间过期自动完成 finished
cancel,received,payed,created,finished,using
## 发货
is_delivery 是否发货 '1': 已发货
delivery 发货时间
## 收货
is_received 是否收货 '1': 已收货
received 收货时间
*/
var statusList map[string]string = map[string]string{
"0": "created",
"1": "payed",
"5": "using",
"6": "finished",
"7": "canceled",
"8": "autocanceled",
"9": "askForRefund",
"13": "refunded",
"15": "autofinished",
}
var statusExtendList map[string]string = map[string]string{
"6": "received", //已收货归入已完成,
}
/*串货订单,供应商系统订单状态*/
var channelOrderStatusList map[string]string = map[string]string{
"1": "nosend",
"2": "created",
"3": "payed",
"4": "askForRefund",
"5": "refunded",
"6": "canceled",
"7": "finished",
"8": "payFailed", //支付失败
"9": "breakoff", //断开
"10": "fullRefund", //全额退款
"14": "autocanceled",
"15": "autofinished",
"16": "delivered",
}
func GetOrderStatusKey(status string) (key string) {
for k, val := range statusList {
if val == status {
key = k
break
}
}
if key == "" { //再找扩展的状态
for k, val := range statusExtendList {
if val == status {
key = k
break
}
}
}
return
}
func GetOrderStatusText(key string) (text string) {
for k, val := range statusList {
if k == key {
text = val
break
}
}
if text == "" { //再找扩展的状态
for k, val := range statusExtendList {
if k == key {
text = val
break
}
}
}
return
}
/**
* 返回订单状态描述
* 2021/01/28
*/
func GetOrderStatusDescByFlag(flag string) (text string) {
status := GetStatusText(flag)
return GetStatusDesc(status)
}
/**
* 返回订单状态描述
* 2020/10/22
*/
func GetOrderStatusDesc(key string) (text string) {
var statusDesc map[string]string = map[string]string{
"created": "已创建",
"payed": "已支付",
"askForRefund": "请求退款",
"using": "使用中",
"finished": "已完成",
"canceled": "已取消",
"autocanceled": "自动取消",
"refunded": "已退款",
"autofinished": "自动完成",
"received": "已收货",
}
for k, val := range statusDesc {
if k == key {
text = val
break
}
}
return
}
func GetChannelOrderStatusKey(status string) (key string) {
for k, val := range channelOrderStatusList {
if val == status {
key = k
break
}
}
return
}
func GetChannelOrderStatusText(key string) (text string) {
for k, val := range channelOrderStatusList {
if k == key {
text = val
break
}
}
return
}
/**
* 返回订单状态描述
* 2020/10/22
*/
func GetChannelOrderStatusDesc(key string) (text string) {
var statusDesc map[string]string = map[string]string{
"nosend": "未发送",
"created": "已创建",
"payed": "已支付",
"askForRefund": "请求退款",
"refunded": "已退款",
"canceled": "已取消",
"finished": "已完成",
"payFailed": "支付失败",
"breakoff": "断开",
"fullRefund": "全额退款",
"autocanceled": "自动取消",
"autofinished": "自动取消",
"delivered": "已发货",
}
for k, val := range statusDesc {
if k == key {
text = val
break
}
}
return
}

Loading…
Cancel
Save