zjxpcyc vor 6 Jahren
Commit
b7cf551cba

+ 5
- 0
.gitignore Datei anzeigen

@@ -0,0 +1,5 @@
1
+*.exe
2
+*.exe~
3
+*.zip
4
+*.tmp
5
+annual-lottery

+ 7
- 0
conf/app.conf Datei anzeigen

@@ -0,0 +1,7 @@
1
+appname = annual-lottery
2
+httpport = 8080
3
+runmode = dev
4
+autorender = false
5
+copyrequestbody = true
6
+EnableDocs = true
7
+sessionon = true

+ 29
- 0
conf/db.conf Datei anzeigen

@@ -0,0 +1,29 @@
1
+; 数据库类型,目前只支持mysql
2
+db_type      = mysql
3
+
4
+; 连接协议
5
+con_protocol = tcp
6
+
7
+; 数据库地址,可以使用IP
8
+db_addr      = 47.101.36.130
9
+
10
+; 端口
11
+db_port      = 3306
12
+
13
+; 用户名
14
+username     = annual_lottery
15
+
16
+; 密码
17
+password     = annual_lottery
18
+
19
+; 数据库名或者schema
20
+database     = annual_lottery
21
+
22
+; 前缀,目前尚未使用
23
+dbprefix     = 
24
+
25
+; 模式,目前尚未使用
26
+db_debug     = false
27
+
28
+; 字符集
29
+char_set     = utf8

+ 94
- 0
controllers/base.go Datei anzeigen

@@ -0,0 +1,94 @@
1
+package controllers
2
+
3
+import (
4
+	"annual-lottery/utils"
5
+	"bytes"
6
+	"errors"
7
+	"reflect"
8
+	"time"
9
+
10
+	"github.com/astaxie/beego"
11
+
12
+	"net/http"
13
+	"net/url"
14
+)
15
+
16
+//Message api统一的返回消息格式
17
+type Message struct {
18
+	Code    int         `json:"code"`
19
+	Message interface{} `json:"message"`
20
+}
21
+
22
+//BaseController 基础controller
23
+type BaseController struct {
24
+	beego.Controller
25
+}
26
+
27
+const (
28
+	SESSION_USER = "h5.user"
29
+	PAGENUM      = 10
30
+	LISTPAGENUM  = 20
31
+)
32
+
33
+// BaseControllerInterface 项目约定的 Controller 须满足的接口
34
+type BaseControllerInterface interface {
35
+	Constructor()
36
+}
37
+
38
+//Prepare 继承beego的
39
+func (c *BaseController) Prepare() {
40
+	// 路由对应的实际 Controller 初始化
41
+	c.initController()
42
+}
43
+
44
+// ResponseJson 自定义的JSON返回
45
+func (c *BaseController) ResponseJson(msg interface{}, code ...int) {
46
+	status := http.StatusOK
47
+	if len(code) > 0 {
48
+		status = code[0]
49
+	}
50
+
51
+	if reflect.ValueOf(msg).Type().String() == "*errors.errorString" {
52
+		err := msg.(error)
53
+		if status == http.StatusOK {
54
+			status = http.StatusInternalServerError
55
+		}
56
+
57
+		c.Data["json"] = Message{status, err.Error()}
58
+	} else {
59
+		c.Data["json"] = Message{status, msg}
60
+	}
61
+
62
+	c.ServeJSON()
63
+	c.StopRun()
64
+}
65
+
66
+// initAppController 执行当前路由请求对应的 Controller 初始化
67
+func (c *BaseController) initController() {
68
+	if ctrl, ok := c.AppController.(BaseControllerInterface); ok {
69
+		ctrl.Constructor()
70
+	}
71
+}
72
+
73
+// SaveToExcel 保存文件到 excel
74
+// 文件不落地, 对内存开销比较大, 如果文件过大, 服务可能会崩掉
75
+func (c *BaseController) SaveToExcel(fn string, excel *utils.TinyXLSXEngine) {
76
+	var buf bytes.Buffer
77
+	if err := excel.Write(&buf); err != nil {
78
+		beego.Error("写 xlsx buffer 失败: " + err.Error())
79
+		c.ResponseJson(errors.New("生成 excel 异常, 请重试"))
80
+	}
81
+
82
+	c.Ctx.Output.Header("Content-Disposition", "attachment; filename="+url.QueryEscape(fn))
83
+	c.Ctx.Output.Header("Content-Description", "File Transfer")
84
+	c.Ctx.Output.ContentType(".xlsx")
85
+	c.Ctx.Output.Header("Content-Transfer-Encoding", "binary")
86
+	c.Ctx.Output.Header("Expires", "0")
87
+	c.Ctx.Output.Header("Cache-Control", "must-revalidate")
88
+	c.Ctx.Output.Header("Pragma", "public")
89
+
90
+	r := bytes.NewReader(buf.Bytes())
91
+	http.ServeContent(c.Ctx.ResponseWriter, c.Ctx.Request, fn, time.Now().Local(), r)
92
+
93
+	c.StopRun()
94
+}

+ 272
- 0
controllers/lottery.go Datei anzeigen

@@ -0,0 +1,272 @@
1
+package controllers
2
+
3
+import (
4
+	"annual-lottery/models"
5
+	"annual-lottery/models/model"
6
+	"annual-lottery/utils"
7
+	"encoding/json"
8
+	"errors"
9
+	"net/http"
10
+	"strconv"
11
+
12
+	"github.com/astaxie/beego"
13
+)
14
+
15
+// LotteryController 基础controller
16
+type LotteryController struct {
17
+	dao *models.LotteryModel
18
+	BaseController
19
+}
20
+
21
+// Constructor 初始化
22
+func (c *LotteryController) Constructor() {
23
+	c.dao = new(models.LotteryModel)
24
+}
25
+
26
+// UserList 获取人员名单
27
+// @router /user [get]
28
+func (c *LotteryController) UserList() {
29
+	users, err := c.dao.UserList()
30
+	if err != nil {
31
+		beego.Error("获取人员名单失败,", err)
32
+		c.ResponseJson(errors.New("获取人员名单失败"))
33
+	}
34
+
35
+	c.ResponseJson(map[string]interface{}{
36
+		"users": users,
37
+	})
38
+}
39
+
40
+// PrizeSettingList 获取抽奖设置列表
41
+// @router /setting/prize [get]
42
+func (c *LotteryController) PrizeSettingList() {
43
+	ps, err := c.dao.PrizeSettingList()
44
+	if err != nil {
45
+		beego.Error("获取抽奖设置列表失败,", err)
46
+		c.ResponseJson(errors.New("获取抽奖设置列表失败"))
47
+	}
48
+
49
+	c.ResponseJson(map[string]interface{}{
50
+		"settings": ps,
51
+	})
52
+}
53
+
54
+// PrizeSetting 抽奖设置
55
+// @router /setting/prize/?:id [post,put,delete]
56
+func (c *LotteryController) PrizeSetting() {
57
+	id := c.GetString(":id")
58
+	bt := []byte(c.GetString("data"))
59
+
60
+	ps := model.TaPrizeSetting{}
61
+	mp := make(map[string]interface{})
62
+	if err := json.Unmarshal(bt, &mp); err != nil {
63
+		beego.Error("转换抽奖设置数据失败,", err)
64
+		c.ResponseJson(errors.New("接收抽奖配置失败"))
65
+	}
66
+
67
+	utils.Map2Struct(mp, &ps)
68
+
69
+	switch c.Ctx.Input.Method() {
70
+	case http.MethodPost:
71
+		ps.SettingId = 0
72
+		if err := c.dao.PrizeSetting(&ps, models.DATA_ADD); err != nil {
73
+			beego.Error("新增抽奖设置失败,", err)
74
+			c.ResponseJson(errors.New("新增抽奖设置失败"))
75
+		}
76
+	case http.MethodPut:
77
+		if id == "" {
78
+			c.ResponseJson(errors.New("抽奖设置ID不能为空"), http.StatusBadRequest)
79
+		}
80
+
81
+		ps.SettingId, _ = strconv.Atoi(id)
82
+		if err := c.dao.PrizeSetting(&ps, models.DATA_UPDATE); err != nil {
83
+			beego.Error("更新抽奖设置失败,", err)
84
+			c.ResponseJson(errors.New("更新抽奖设置失败"))
85
+		}
86
+	case http.MethodDelete:
87
+		if id == "" {
88
+			c.ResponseJson(errors.New("抽奖设置ID不能为空"), http.StatusBadRequest)
89
+		}
90
+
91
+		ps.PrizeId, _ = strconv.Atoi(id)
92
+		if err := c.dao.PrizeSetting(&ps, models.DATA_DELETE); err != nil {
93
+			beego.Error("删除抽奖设置失败,", err)
94
+			c.ResponseJson(errors.New("删除抽奖设置失败"))
95
+		}
96
+	default:
97
+		c.ResponseJson(errors.New("404"), http.StatusNotFound)
98
+	}
99
+
100
+	// 返回最新结果
101
+	c.PrizeSettingList()
102
+}
103
+
104
+// Draw 抽奖
105
+// @router /draw [post]
106
+func (c *LotteryController) Draw() {
107
+	pw, err := c.dao.Draw()
108
+	if err != nil {
109
+		beego.Error("抽奖失败,", err)
110
+		c.ResponseJson(errors.New("抽奖失败, 请重试"))
111
+	}
112
+
113
+	c.ResponseJson(map[string]interface{}{
114
+		"winner": pw,
115
+	})
116
+}
117
+
118
+// PrizeList 奖品列表
119
+// @router /prize [get]
120
+func (c *LotteryController) PrizeList() {
121
+	pl, err := c.dao.PrizeList()
122
+	if err != nil {
123
+		beego.Error("获取奖品列表失败,", err)
124
+		c.ResponseJson(errors.New("获取奖品列表失败"))
125
+	}
126
+
127
+	c.ResponseJson(map[string]interface{}{
128
+		"prizes": pl,
129
+	})
130
+}
131
+
132
+// PrizeEdit 奖品维护
133
+// @router /prize/?:id [post,put,delete]
134
+func (c *LotteryController) PrizeEdit() {
135
+	id := c.GetString(":id")
136
+	bt := []byte(c.GetString("data"))
137
+
138
+	ps := model.TaPrize{}
139
+	mp := make(map[string]interface{})
140
+	if err := json.Unmarshal(bt, &mp); err != nil {
141
+		beego.Error("转换奖品数据失败,", err)
142
+		c.ResponseJson(errors.New("接收奖品数据失败"))
143
+	}
144
+
145
+	utils.Map2Struct(mp, &ps)
146
+
147
+	switch c.Ctx.Input.Method() {
148
+	case http.MethodPost:
149
+		ps.PrizeId = 0
150
+		if err := c.dao.PrizeEdit(&ps, models.DATA_ADD); err != nil {
151
+			beego.Error("新增奖品数据失败,", err)
152
+			c.ResponseJson(errors.New("新增奖品数据失败"))
153
+		}
154
+	case http.MethodPut:
155
+		if id == "" {
156
+			c.ResponseJson(errors.New("奖品数据ID不能为空"), http.StatusBadRequest)
157
+		}
158
+
159
+		ps.PrizeId, _ = strconv.Atoi(id)
160
+		if err := c.dao.PrizeEdit(&ps, models.DATA_UPDATE); err != nil {
161
+			beego.Error("更新奖品数据失败,", err)
162
+			c.ResponseJson(errors.New("更新奖品数据失败"))
163
+		}
164
+	case http.MethodDelete:
165
+		if id == "" {
166
+			c.ResponseJson(errors.New("奖品数据ID不能为空"), http.StatusBadRequest)
167
+		}
168
+
169
+		ps.PrizeId, _ = strconv.Atoi(id)
170
+		if err := c.dao.PrizeEdit(&ps, models.DATA_DELETE); err != nil {
171
+			beego.Error("删除奖品数据失败,", err)
172
+			c.ResponseJson(errors.New("删除奖品数据失败"))
173
+		}
174
+	default:
175
+		c.ResponseJson(errors.New("404"), http.StatusNotFound)
176
+	}
177
+
178
+	// 返回最新结果
179
+	c.PrizeList()
180
+}
181
+
182
+// WinnerList 中奖人员名单
183
+// @router /winner [get]
184
+func (c *LotteryController) WinnerList() {
185
+	typ := c.GetString("type")
186
+	name := c.GetString("name")
187
+	delStr := c.GetString("del")
188
+	del, _ := strconv.Atoi(delStr)
189
+
190
+	var wl []model.TaPrizeWinner
191
+	var err error
192
+
193
+	if delStr == "" {
194
+		wl, err = c.dao.WinnerList(typ, name)
195
+		if err != nil {
196
+			beego.Error("获取中奖人员名单失败,", err)
197
+			c.ResponseJson(errors.New("获取中奖人员名单失败"))
198
+		}
199
+	} else {
200
+		wl, err = c.dao.WinnerList(typ, name, del)
201
+		if err != nil {
202
+			beego.Error("获取中奖人员名单失败,", err)
203
+			c.ResponseJson(errors.New("获取中奖人员名单失败"))
204
+		}
205
+	}
206
+
207
+	c.ResponseJson(map[string]interface{}{
208
+		"winners": wl,
209
+	})
210
+}
211
+
212
+// CancelWinner 作废中奖人员
213
+// @router /winner/:uid [delete]
214
+func (c *LotteryController) CancelWinner() {
215
+	pid, _ := c.GetInt("pid")
216
+	uid, _ := c.GetInt(":uid")
217
+
218
+	if err := c.dao.CancelWinner(pid, uid); err != nil {
219
+		beego.Error("作废中奖人员失败,", err)
220
+		c.ResponseJson(errors.New("作废中奖人员失败"))
221
+	}
222
+
223
+	c.ResponseJson(map[string]interface{}{
224
+		"result": "success",
225
+	})
226
+}
227
+
228
+// ExportWinners 导出中奖名单
229
+// @router /excel/winner [get]
230
+func (c *LotteryController) ExportWinners() {
231
+	typ := c.GetString("type")
232
+	del := models.STATUS_NORMAL
233
+
234
+	wl, err := c.dao.WinnerList(typ, "", del)
235
+	if err != nil {
236
+		beego.Error("获取中奖人员名单失败,", err)
237
+		c.ResponseJson(errors.New("获取中奖人员名单失败"))
238
+	}
239
+
240
+	excel, err := utils.NewTinyXLSXEngine()
241
+	if err != nil {
242
+		beego.Error("导出中奖人员名单失败,", err)
243
+		c.ResponseJson(errors.New("导出中奖人员名单失败"))
244
+	}
245
+
246
+	excel.SetCell(
247
+		excel.InsertRow(),
248
+		[]string{
249
+			"序号",
250
+			"中奖人",
251
+			"公司",
252
+			"部门",
253
+			"分类",
254
+			"奖品",
255
+		},
256
+	)
257
+
258
+	for k, w := range wl {
259
+		row := excel.InsertRow()
260
+
261
+		excel.SetCell(row, []string{
262
+			strconv.Itoa(k + 1),
263
+			w.UserName,
264
+			w.UserOrg,
265
+			w.UserDept,
266
+			w.PrizeType,
267
+			w.PrizeName,
268
+		})
269
+	}
270
+
271
+	c.SaveToExcel("中奖名单.xlsx", excel)
272
+}

+ 15
- 0
main.go Datei anzeigen

@@ -0,0 +1,15 @@
1
+package main
2
+
3
+import (
4
+	_ "annual-lottery/routers"
5
+
6
+	"github.com/astaxie/beego"
7
+)
8
+
9
+func main() {
10
+	if beego.BConfig.RunMode == "dev" {
11
+		beego.BConfig.WebConfig.DirectoryIndex = true
12
+		beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger"
13
+	}
14
+	beego.Run()
15
+}

+ 188
- 0
models/lottery.go Datei anzeigen

@@ -0,0 +1,188 @@
1
+package models
2
+
3
+import (
4
+	"annual-lottery/models/model"
5
+	"annual-lottery/utils"
6
+	"time"
7
+)
8
+
9
+const (
10
+	STATUS_DELETE = iota - 1
11
+	STATUS_READY
12
+	STATUS_NORMAL
13
+)
14
+
15
+const (
16
+	DATA_DELETE = iota - 1
17
+	DATA_ADD
18
+	DATA_UPDATE
19
+)
20
+
21
+// LotteryModel model
22
+type LotteryModel struct{}
23
+
24
+// UserList 用户列表
25
+func (m *LotteryModel) UserList() ([]model.TaUser, error) {
26
+	users := make([]model.TaUser, 0)
27
+	err := Dao.Asc("user_id").Find(&users)
28
+	return users, err
29
+}
30
+
31
+// PrizeSettingList 奖品设置列表
32
+func (m *LotteryModel) PrizeSettingList() ([]model.TaPrizeSetting, error) {
33
+	ps := make([]model.TaPrizeSetting, 0)
34
+
35
+	err := Dao.Desc("create_date").Find(&ps)
36
+	return ps, err
37
+}
38
+
39
+// PrizeSetting 抽奖设置维护
40
+func (m *LotteryModel) PrizeSetting(s *model.TaPrizeSetting, typ int) error {
41
+	switch typ {
42
+	case DATA_ADD:
43
+		s.SettingId = 0
44
+		s.Status = STATUS_NORMAL
45
+		s.CreateDate = time.Now().Local()
46
+		_, err := Dao.Insert(s)
47
+		return err
48
+	case DATA_UPDATE:
49
+		cols := []string{"prize_id", "is_repeat", "prize_num", "status"}
50
+		_, err := Dao.Cols(cols...).Where("setting_id=?", s.SettingId).Update(s)
51
+		return err
52
+	default:
53
+		return nil
54
+	}
55
+}
56
+
57
+// Draw 抽奖
58
+// 因为没有库存的概念,因此奖品中奖后, 不会把奖品表中的数量减一
59
+func (m *LotteryModel) Draw() ([]model.TaPrizeWinner, error) {
60
+	// 获取当前可用抽奖设置
61
+	setting := model.TaPrizeSetting{}
62
+	if _, err := Dao.Where("status=?", STATUS_NORMAL).Get(&setting); err != nil {
63
+		return nil, err
64
+	}
65
+
66
+	// 获取奖品
67
+	prize := model.TaPrize{}
68
+	if _, err := Dao.Where("prize_id=?", setting.PrizeId).Get(&prize); err != nil {
69
+		return nil, err
70
+	}
71
+
72
+	// 获取参与抽奖人员
73
+	users := make([]model.TaUser, 0)
74
+	query := `select * from ta_user t`
75
+	if setting.IsRepeat == 0 {
76
+		// 如果不允许多次中奖
77
+		query += ` where not exists (
78
+			select * from ta_prize_winner s where t.user_id = s.user_id
79
+		)`
80
+	}
81
+	if err := Dao.SQL(query).Find(&users); err != nil {
82
+		return nil, err
83
+	}
84
+
85
+	pws := make([]model.TaPrizeWinner, 0)
86
+	randIDs := make([]int, 0)
87
+	randID := -1
88
+	for i := 0; i < setting.PrizeNum; i++ {
89
+		// 获取中奖人员
90
+		for {
91
+			randID = utils.RandNum(len(users))
92
+			if utils.IntSliceIndex(randIDs, randID) > -1 {
93
+				randIDs = append(randIDs, randID)
94
+				break
95
+			}
96
+		}
97
+
98
+		winner := users[randID]
99
+
100
+		// 组合中奖信息
101
+		pw := model.TaPrizeWinner{
102
+			UserId:     winner.UserId,
103
+			UserName:   winner.UserName,
104
+			UserOrg:    winner.UserOrg,
105
+			UserDept:   winner.UserDept,
106
+			PrizeId:    prize.PrizeId,
107
+			PrizeName:  prize.PrizeName,
108
+			PrizeType:  prize.PrizeType,
109
+			SettingId:  setting.SettingId,
110
+			Status:     STATUS_NORMAL,
111
+			CreateDate: time.Now().Local(),
112
+		}
113
+
114
+		pws = append(pws, pw)
115
+	}
116
+
117
+	// 更新抽奖配置
118
+	if _, err := Dao.Cols("status").
119
+		Update(&model.TaPrizeSetting{SettingId: setting.SettingId, Status: STATUS_NORMAL}); err != nil {
120
+		return nil, err
121
+	}
122
+
123
+	// 保存记录
124
+	if _, err := Dao.Insert(&pws); err != nil {
125
+		return nil, err
126
+	}
127
+
128
+	return pws, nil
129
+}
130
+
131
+// PrizeEdit 奖品维护
132
+func (m *LotteryModel) PrizeEdit(p *model.TaPrize, typ int) error {
133
+	switch typ {
134
+	case DATA_ADD:
135
+		p.CreateDate = time.Now().Local()
136
+		_, err := Dao.Insert(p)
137
+		return err
138
+	case DATA_UPDATE:
139
+		cols := []string{"prize_type", "prize_name", "picture", "stock"}
140
+		_, err := Dao.Cols(cols...).Where("prize_id=?", p.PrizeId).Update(p)
141
+		return err
142
+	default:
143
+		return nil
144
+	}
145
+}
146
+
147
+// PrizeList 奖品列表
148
+func (m *LotteryModel) PrizeList() ([]model.TaPrize, error) {
149
+	ps := make([]model.TaPrize, 0)
150
+	err := Dao.Desc("create_date").Find(&ps)
151
+	return ps, err
152
+}
153
+
154
+// WinnerList 中奖人员名单
155
+// typ 奖品类型
156
+// name 用户名称
157
+// del 是否有效记录
158
+func (m *LotteryModel) WinnerList(typ, name string, del ...int) ([]model.TaPrizeWinner, error) {
159
+	ws := make([]model.TaPrizeWinner, 0)
160
+	query := Dao.Where("1=1")
161
+
162
+	if typ != "" {
163
+		query = query.And("prize_type like '%" + typ + "%'")
164
+	}
165
+
166
+	if name != "" {
167
+		query = query.And("user_name like '%" + name + "%'")
168
+	}
169
+
170
+	if len(del) > 0 {
171
+		query = query.And("status=?", del[0])
172
+	}
173
+
174
+	err := query.Asc("prize_type").Desc("create_date").Find(&ws)
175
+	return ws, err
176
+}
177
+
178
+// CancelWinner 作废中奖人员
179
+func (m *LotteryModel) CancelWinner(prizeID, userID int) error {
180
+	// 作废记录
181
+	pw := model.TaPrizeWinner{Status: STATUS_DELETE}
182
+	if _, err := Dao.Cols("status").Where("prize_id=?", prizeID).
183
+		And("user_id=?", userID).Update(&pw); err != nil {
184
+		return err
185
+	}
186
+
187
+	return nil
188
+}

+ 12
- 0
models/model/ta_prize.go Datei anzeigen

@@ -0,0 +1,12 @@
1
+package model
2
+
3
+import "time"
4
+
5
+type TaPrize struct {
6
+	PrizeId    int       `xorm:"not null pk autoincr INT(11)"`
7
+	PrizeType  string    `xorm:"VARCHAR(100)"`
8
+	PrizeName  string    `xorm:"VARCHAR(300)"`
9
+	Picture    string    `xorm:"TEXT"`
10
+	Stock      int       `xorm:"INT(11)"`
11
+	CreateDate time.Time `xorm:"DATETIME"`
12
+}

+ 12
- 0
models/model/ta_prize_setting.go Datei anzeigen

@@ -0,0 +1,12 @@
1
+package model
2
+
3
+import "time"
4
+
5
+type TaPrizeSetting struct {
6
+	SettingId  int       `xorm:"not null pk autoincr INT(11)"`
7
+	PrizeId    int       `xorm:"INT(11)"`
8
+	IsRepeat   int       `xorm:"SMALLINT(6)"`
9
+	PrizeNum   int       `xorm:"INT(11)"`
10
+	Status     int       `xorm:"SMALLINT(6)"`
11
+	CreateDate time.Time `xorm:"DATETIME"`
12
+}

+ 17
- 0
models/model/ta_prize_winner.go Datei anzeigen

@@ -0,0 +1,17 @@
1
+package model
2
+
3
+import "time"
4
+
5
+type TaPrizeWinner struct {
6
+	RecId      int       `xorm:"not null pk autoincr INT(11)"`
7
+	UserId     int       `xorm:"INT(11)"`
8
+	UserName   string    `xorm:"VARCHAR(200)"`
9
+	UserOrg    string    `xorm:"VARCHAR(300)"`
10
+	UserDept   string    `xorm:"VARCHAR(300)"`
11
+	PrizeId    int       `xorm:"INT(11)"`
12
+	PrizeName  string    `xorm:"VARCHAR(200)"`
13
+	PrizeType  string    `xorm:"VARCHAR(100)"`
14
+	SettingId  int       `xorm:"INT(11)"`
15
+	Status     int       `xorm:"INT(11)"`
16
+	CreateDate time.Time `xorm:"DATETIME"`
17
+}

+ 8
- 0
models/model/ta_user.go Datei anzeigen

@@ -0,0 +1,8 @@
1
+package model
2
+
3
+type TaUser struct {
4
+	UserId   int    `xorm:"not null pk INT(11)"`
5
+	UserName string `xorm:"VARCHAR(100)"`
6
+	UserOrg  string `xorm:"VARCHAR(300)"`
7
+	UserDept string `xorm:"VARCHAR(300)"`
8
+}

+ 57
- 0
models/models.go Datei anzeigen

@@ -0,0 +1,57 @@
1
+package models
2
+
3
+import (
4
+	"github.com/astaxie/beego/config"
5
+	_ "github.com/go-sql-driver/mysql"
6
+	"github.com/go-xorm/xorm"
7
+)
8
+
9
+var (
10
+	Dao *xorm.Engine
11
+)
12
+
13
+func init() {
14
+	Dao = NewDAO()
15
+}
16
+
17
+// NewDAO 初始化数据库连接
18
+func NewDAO() *xorm.Engine {
19
+	dbType := "mysql"
20
+	dns := getMysqlDns()
21
+
22
+	dao, err := xorm.NewEngine(dbType, dns)
23
+	// dao.ShowSQL()
24
+
25
+	if err != nil {
26
+		panic(err)
27
+		return nil
28
+	}
29
+
30
+	Dao = dao
31
+	return dao
32
+}
33
+
34
+func getMysqlDns() string {
35
+	dbconf, _ := config.NewConfig("ini", "conf/db.conf")
36
+
37
+	// db_type  := dbconf.DefaultString("db_type", "mysql")
38
+	conProt := dbconf.DefaultString("con_protocol", "tcp")
39
+	dbAddr := dbconf.DefaultString("db_addr", "localhost")
40
+	dbPort := dbconf.DefaultString("db_port", "3306")
41
+	userName := dbconf.DefaultString("username", "root")
42
+	password := dbconf.String("password")
43
+	database := dbconf.String("database")
44
+	// dbprefix := dbconf.String("dbprefix")
45
+	// db_debug := dbconf.DefaultBool("db_debug", false)
46
+	charSet := dbconf.DefaultString("char_set", "utf8")
47
+
48
+	dns := userName
49
+
50
+	if len(password) > 0 {
51
+		dns += ":" + password
52
+	}
53
+
54
+	dns += "@" + conProt + "(" + dbAddr + ":" + dbPort + ")" + "/" + database + "?charset=" + charSet
55
+
56
+	return dns
57
+}

+ 82
- 0
routers/commentsRouter_controllers.go Datei anzeigen

@@ -0,0 +1,82 @@
1
+package routers
2
+
3
+import (
4
+	"github.com/astaxie/beego"
5
+	"github.com/astaxie/beego/context/param"
6
+)
7
+
8
+func init() {
9
+
10
+	beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"] = append(beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"],
11
+		beego.ControllerComments{
12
+			Method: "Draw",
13
+			Router: `/draw`,
14
+			AllowHTTPMethods: []string{"post"},
15
+			MethodParams: param.Make(),
16
+			Params: nil})
17
+
18
+	beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"] = append(beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"],
19
+		beego.ControllerComments{
20
+			Method: "ExportWinners",
21
+			Router: `/excel/winner`,
22
+			AllowHTTPMethods: []string{"get"},
23
+			MethodParams: param.Make(),
24
+			Params: nil})
25
+
26
+	beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"] = append(beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"],
27
+		beego.ControllerComments{
28
+			Method: "PrizeList",
29
+			Router: `/prize`,
30
+			AllowHTTPMethods: []string{"get"},
31
+			MethodParams: param.Make(),
32
+			Params: nil})
33
+
34
+	beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"] = append(beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"],
35
+		beego.ControllerComments{
36
+			Method: "PrizeEdit",
37
+			Router: `/prize/?:id`,
38
+			AllowHTTPMethods: []string{"post","put","delete"},
39
+			MethodParams: param.Make(),
40
+			Params: nil})
41
+
42
+	beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"] = append(beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"],
43
+		beego.ControllerComments{
44
+			Method: "PrizeSettingList",
45
+			Router: `/setting/prize`,
46
+			AllowHTTPMethods: []string{"get"},
47
+			MethodParams: param.Make(),
48
+			Params: nil})
49
+
50
+	beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"] = append(beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"],
51
+		beego.ControllerComments{
52
+			Method: "PrizeSetting",
53
+			Router: `/setting/prize/?:id`,
54
+			AllowHTTPMethods: []string{"post","put","delete"},
55
+			MethodParams: param.Make(),
56
+			Params: nil})
57
+
58
+	beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"] = append(beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"],
59
+		beego.ControllerComments{
60
+			Method: "UserList",
61
+			Router: `/user`,
62
+			AllowHTTPMethods: []string{"get"},
63
+			MethodParams: param.Make(),
64
+			Params: nil})
65
+
66
+	beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"] = append(beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"],
67
+		beego.ControllerComments{
68
+			Method: "WinnerList",
69
+			Router: `/winner`,
70
+			AllowHTTPMethods: []string{"get"},
71
+			MethodParams: param.Make(),
72
+			Params: nil})
73
+
74
+	beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"] = append(beego.GlobalControllerRouter["annual-lottery/controllers:LotteryController"],
75
+		beego.ControllerComments{
76
+			Method: "CancelWinner",
77
+			Router: `/winner/:uid`,
78
+			AllowHTTPMethods: []string{"delete"},
79
+			MethodParams: param.Make(),
80
+			Params: nil})
81
+
82
+}

+ 23
- 0
routers/router.go Datei anzeigen

@@ -0,0 +1,23 @@
1
+// @APIVersion 1.0.0
2
+// @Title beego Test API
3
+// @Description beego has a very cool tools to autogenerate documents for your API
4
+// @Contact astaxie@gmail.com
5
+// @TermsOfServiceUrl http://beego.me/
6
+// @License Apache 2.0
7
+// @LicenseUrl http://www.apache.org/licenses/LICENSE-2.0.html
8
+package routers
9
+
10
+import (
11
+	"annual-lottery/controllers"
12
+
13
+	"github.com/astaxie/beego"
14
+)
15
+
16
+func init() {
17
+	ns := beego.NewNamespace("/api",
18
+		beego.NSInclude(&controllers.LotteryController{}),
19
+	)
20
+	beego.AddNamespace(ns)
21
+
22
+	// beego.Router("/", &controllers.BaseController{}, "*:Index")
23
+}

+ 37
- 0
tests/default_test.go Datei anzeigen

@@ -0,0 +1,37 @@
1
+package test
2
+
3
+import (
4
+	_ "annual-lottery/routers"
5
+	"net/http"
6
+	"net/http/httptest"
7
+	"path/filepath"
8
+	"runtime"
9
+	"testing"
10
+
11
+	"github.com/astaxie/beego"
12
+	. "github.com/smartystreets/goconvey/convey"
13
+)
14
+
15
+func init() {
16
+	_, file, _, _ := runtime.Caller(1)
17
+	apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".."+string(filepath.Separator))))
18
+	beego.TestBeegoInit(apppath)
19
+}
20
+
21
+// TestGet is a sample to run an endpoint test
22
+func TestGet(t *testing.T) {
23
+	r, _ := http.NewRequest("GET", "/v1/object", nil)
24
+	w := httptest.NewRecorder()
25
+	beego.BeeApp.Handlers.ServeHTTP(w, r)
26
+
27
+	beego.Trace("testing", "TestGet", "Code[%d]\n%s", w.Code, w.Body.String())
28
+
29
+	Convey("Subject: Test Station Endpoint\n", t, func() {
30
+		Convey("Status Code Should Be 200", func() {
31
+			So(w.Code, ShouldEqual, 200)
32
+		})
33
+		Convey("The Result Should Not Be Empty", func() {
34
+			So(w.Body.Len(), ShouldBeGreaterThan, 0)
35
+		})
36
+	})
37
+}

+ 55
- 0
utils/excel.go Datei anzeigen

@@ -0,0 +1,55 @@
1
+package utils
2
+
3
+import (
4
+	"errors"
5
+	"io"
6
+	"reflect"
7
+
8
+	"github.com/astaxie/beego"
9
+
10
+	"github.com/tealeg/xlsx"
11
+)
12
+
13
+// TinyXLSXEngine 简版 xlsx 处理器
14
+type TinyXLSXEngine struct {
15
+	xlsxFile *xlsx.File
16
+	sheet    *xlsx.Sheet
17
+}
18
+
19
+// NewTinyXLSXEngine init
20
+func NewTinyXLSXEngine() (*TinyXLSXEngine, error) {
21
+	file := xlsx.NewFile()
22
+
23
+	sheet, err := file.AddSheet("sheet1")
24
+	if err != nil {
25
+		beego.Error("创建 xlsx sheet 失败: " + err.Error())
26
+		return nil, errors.New("创建 xlsx sheet 失败")
27
+	}
28
+
29
+	return &TinyXLSXEngine{
30
+		xlsxFile: file,
31
+		sheet:    sheet,
32
+	}, nil
33
+}
34
+
35
+// InsertRow 新增行
36
+func (t *TinyXLSXEngine) InsertRow() *xlsx.Row {
37
+	return t.sheet.AddRow()
38
+}
39
+
40
+// SetCell 新增数据
41
+func (t *TinyXLSXEngine) SetCell(row *xlsx.Row, v interface{}) {
42
+	rv := reflect.ValueOf(v)
43
+	if rv.Kind() == reflect.Slice {
44
+		for i := 0; i < rv.Len(); i++ {
45
+			row.AddCell().SetValue(rv.Index(i).Interface())
46
+		}
47
+	} else {
48
+		row.AddCell().SetValue(v)
49
+	}
50
+}
51
+
52
+// Write 写数据
53
+func (t *TinyXLSXEngine) Write(w io.Writer) error {
54
+	return t.xlsxFile.Write(w)
55
+}

+ 28
- 0
utils/map2struct.go Datei anzeigen

@@ -0,0 +1,28 @@
1
+package utils
2
+
3
+import (
4
+	"reflect"
5
+)
6
+
7
+// Map2Struct map 转 struct
8
+// 必须保证 s 为 stuct 指针
9
+func Map2Struct(m map[string]interface{}, s interface{}) {
10
+	sv := reflect.ValueOf(s).Elem()
11
+
12
+	for k, t := range m {
13
+		f := sv.FieldByName(k)
14
+
15
+		if !f.IsValid() {
16
+			continue
17
+		}
18
+
19
+		switch v := t.(type) {
20
+		case string:
21
+			f.SetString(v)
22
+		case float64:
23
+			f.SetInt(int64(v))
24
+		default:
25
+			continue
26
+		}
27
+	}
28
+}

+ 12
- 0
utils/random.go Datei anzeigen

@@ -0,0 +1,12 @@
1
+package utils
2
+
3
+import (
4
+	"math/rand"
5
+	"time"
6
+)
7
+
8
+// RandNum 生成一个 [0, max) 的随机数
9
+func RandNum(max int) int {
10
+	src := rand.NewSource(time.Now().UnixNano())
11
+	return rand.New(src).Intn(max)
12
+}

+ 12
- 0
utils/slice.go Datei anzeigen

@@ -0,0 +1,12 @@
1
+package utils
2
+
3
+// IntSliceIndex 返回值 -1 未找到, 正数为 index
4
+func IntSliceIndex(is []int, s int) int {
5
+	for k, v := range is {
6
+		if v == s {
7
+			return k
8
+		}
9
+	}
10
+
11
+	return -1
12
+}