/
common.go
149 lines (130 loc) · 3.06 KB
/
common.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package shopping
// The type of ID for Item and User is int. To differ the two from others, we
// specify the field IDStr to indicate the its type is string, otherwise int.
import (
"bytes"
"strconv"
"strings"
)
type Item struct {
ID int `json:"id"`
Price int `json:"price"`
Stock int `json:"stock"`
}
type LoginJson struct {
Username string `json:"username"`
Password string `json:"password"`
}
type Order struct {
// if total < 0, then is a order
IDStr string `json:"id"`
Items []ItemCount `json:"items"`
Total int `json:"total"`
HasPaid bool `json:"paid"`
}
type ItemCount struct {
ItemID int `json:"item_id"`
Count int `json:"count"`
}
// OrderDetail is for GET /admin/orders
type OrderDetail struct {
Order
UserID int `json:"user_id"`
}
type CartIDJson struct {
IDStr string `json:"cart_id"`
}
type OrderIDJson struct {
IDStr string `json:"order_id"`
}
type UserIDAndPass struct {
ID int
Password string
}
func getCartKey(cartIDStr, token string) (cartKey string) {
cartKey = "cart:" + cartIDStr + ":" + token
return
}
func userID2Token(userID int) string {
return strconv.Itoa(userID)
}
func token2UserID(token string) int {
if id, err := strconv.Atoi(token); err == nil {
return id
} else {
panic(err)
}
}
func composeOrderValue(hasPaid bool, price, num int, detail map[int]int) string {
var info [3]string
if hasPaid {
info[0] = OrderPaidFlag
} else {
info[0] = OrderUnpaidFlag
}
info[1] = strconv.Itoa(price)
info[2] = composeCartValue(num, detail)
return strings.Join(info[:], "|")
}
func parseOrderValue(value string) (hasPaid bool, price, num int, detail map[int]int) {
info := strings.Split(value, "|")
if info[0] == OrderPaidFlag {
hasPaid = true
} else {
hasPaid = false
}
if len(info) != 3 {
panic(value)
}
price, _ = strconv.Atoi(info[1])
num, detail = parseCartValue(info[2])
return
}
// cartValue shouldn't be "". Otherwise return 0, blank map.
// 2.1:3;2:4
// 0
func parseCartValue(cartValue string) (num int, detail map[int]int) {
detail = make(map[int]int)
if cartValue == "" {
return 0, detail
}
vs := strings.Split(cartValue, ".")
num, _ = strconv.Atoi(vs[0])
cnt := 0
if len(vs) == 2 {
itemStrs := strings.Split(vs[1], ";")
for _, itemStr := range itemStrs {
info := strings.Split(itemStr, ":")
if len(info) != 2 {
panic("cartValue format error")
}
itemID, _ := strconv.Atoi(info[0])
itemCnt, _ := strconv.Atoi(info[1])
cnt += itemCnt
detail[itemID] = itemCnt
}
} else if len(vs) > 2 {
panic("cartValue format error")
}
if num != cnt {
panic("total value error")
}
return
}
func composeCartValue(num int, cartDetail map[int]int) (cartDetailStr string) {
cnt := 0
var buffer bytes.Buffer
buffer.WriteString(strconv.Itoa(num) + ".")
for itemID, itemCnt := range cartDetail {
cnt += itemCnt
buffer.WriteString(strconv.Itoa(itemID))
buffer.WriteString(":")
buffer.WriteString(strconv.Itoa(itemCnt))
buffer.WriteString(";")
}
buffer.Truncate(buffer.Len() - 1)
if num != cnt {
panic("total value error")
}
return buffer.String()
}