-
Notifications
You must be signed in to change notification settings - Fork 1
/
prepaid_card.go
156 lines (142 loc) · 4.02 KB
/
prepaid_card.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
150
151
152
153
154
155
156
package customer
import (
"time"
"github.com/webx-top/com"
"github.com/webx-top/db"
"github.com/webx-top/echo"
"github.com/webx-top/echo/code"
"github.com/webx-top/echo/middleware/tplfunc"
"github.com/admpub/errors"
"github.com/admpub/nging/v5/application/library/common"
"github.com/admpub/webx/application/dbschema"
)
var ErrCardNumberAlreadyExists = errors.New(`Card number already exists`)
func NewPrepaidCard(ctx echo.Context) *PrepaidCard {
m := &PrepaidCard{
OfficialCustomerPrepaidCard: dbschema.NewOfficialCustomerPrepaidCard(ctx),
}
return m
}
type PrepaidCard struct {
*dbschema.OfficialCustomerPrepaidCard
}
func (f *PrepaidCard) check() error {
ctx := f.Context()
if f.Uid < 1 {
return common.ErrUserNotLoggedIn
}
if f.Amount < 1 {
return ctx.NewError(code.InvalidParameter, `面值无效,必须大于0`).SetZone(`amount`)
}
if f.SalePrice <= 0 {
return ctx.NewError(code.InvalidParameter, `售价无效,必须大于0`).SetZone(`salePrice`)
}
exists, err := f.Exists(f.Number, f.Id)
if err != nil {
return err
}
if exists {
return ErrCardNumberAlreadyExists
}
return nil
}
func (f *PrepaidCard) UseCard(customerID uint64, number string, password string) error {
ctx := f.Context()
err := f.Get(nil, db.Cond{`number`: number})
if err != nil {
if err == db.ErrNoMoreRows {
return ctx.NewError(code.DataNotFound, `充值卡不存在`).SetZone(`number`)
}
return err
}
if f.Disabled == `Y` {
return ctx.NewError(code.DataUnavailable, `充值卡无效`).SetZone(`disabled`)
}
if f.Password != password {
return ctx.NewError(code.InvalidParameter, `充值卡密码错误`).SetZone(`password`)
}
if f.Used > 0 {
return ctx.NewError(code.DataHasExpired, `充值卡“%v”已经使用过了`, f.Number).SetZone(`used`)
}
now := uint(time.Now().Unix())
if f.Start > now {
if f.End > 0 {
err = errors.New(ctx.T(`该邀请码只能在“%s - %s”这段时间内使用`,
tplfunc.TsToDate(`2006/01/02 15:04:05`, f.Start),
tplfunc.TsToDate(`2006/01/02 15:04:05`, f.End),
))
} else {
err = errors.New(ctx.T(`该邀请码只能在“%s”之后使用`,
tplfunc.TsToDate(`2006/01/02 15:04:05`, f.Start),
))
}
return err
}
if f.End > 0 && f.End < now {
err = ctx.NewError(code.DataHasExpired, `该邀请码已过期`).SetZone(`expired`)
return err
}
kvset := echo.H{
`used`: uint(time.Now().Unix()),
`customer_id`: customerID,
}
return f.UpdateFields(nil, kvset, `id`, f.Id)
}
// BatchGenerate 批量生成
func (f *PrepaidCard) BatchGenerate(uid uint, count int, amount uint, salePrice float64, start uint, end uint, bgImage string) error {
for i := 0; i < count; i++ {
f.Reset()
f.Uid = uid
f.Amount = amount
f.SalePrice = salePrice
f.Start = start
f.End = end
f.BgImage = bgImage
_, err := f.Add()
if err != nil {
return err
}
}
return nil
}
func (f *PrepaidCard) Add() (pk interface{}, err error) {
f.Number, err = common.UniqueID()
if err != nil {
return nil, err
}
cardNumber := f.Number
var loopTimes int
loopMaxTimes := 10
LOOP:
if err = f.check(); err != nil {
if err == ErrCardNumberAlreadyExists {
if loopTimes >= loopMaxTimes {
return nil, errors.WithMessage(err, f.Number)
}
f.Number = cardNumber + com.RandomNumeric(2)
loopTimes++
goto LOOP
}
return nil, err
}
f.Password = com.RandomNumeric(8)
return f.OfficialCustomerPrepaidCard.Insert()
}
func (f *PrepaidCard) Exists(number string, excludeIDs ...uint64) (bool, error) {
cond := db.NewCompounds()
cond.AddKV(`number`, number)
if len(excludeIDs) > 0 && excludeIDs[0] > 0 {
cond.Add(db.Cond{`id`: db.NotEq(excludeIDs[0])})
}
return f.OfficialCustomerPrepaidCard.Exists(nil, cond.And())
}
func (f *PrepaidCard) Edit(mw func(db.Result) db.Result, args ...interface{}) error {
if err := f.check(); err != nil {
return err
}
return f.OfficialCustomerPrepaidCard.Update(mw, args...)
}
func (f *PrepaidCard) Delete(mw func(db.Result) db.Result, args ...interface{}) error {
err := f.OfficialCustomerPrepaidCard.Delete(mw, args...)
return err
}