wangfei 6 vuotta sitten
vanhempi
commit
bbab293004

+ 5
- 0
.gitignore Näytä tiedosto

@@ -0,0 +1,5 @@
1
+*.exe
2
+*.exe~
3
+*.test
4
+*.log
5
+log

+ 25
- 0
bootstrap/bootstrap.go Näytä tiedosto

@@ -0,0 +1,25 @@
1
+package bootstrap
2
+
3
+import (
4
+	"support-game/models"
5
+	"support-game/routers"
6
+	"support-game/utils"
7
+)
8
+
9
+// SystemInit 系统初始化
10
+func SystemInit() {
11
+	// 数据库连接
12
+	models.InitDB()
13
+
14
+	// 系统日志
15
+	utils.LogInit()
16
+
17
+	// 微信
18
+	utils.InitWechat()
19
+
20
+	// 阿里云
21
+	utils.OssInit()
22
+
23
+	// 路由系统
24
+	routers.RouteInit()
25
+}

+ 23
- 0
conf/app.conf Näytä tiedosto

@@ -0,0 +1,23 @@
1
+appname = support-game
2
+httpport = 8080
3
+runmode = prod
4
+
5
+[cros]
6
+allowMode = dev
7
+allowCredentials = true
8
+allowOrigin = http://localhost:9528
9
+
10
+# GET, POST etc
11
+allowMethods = *
12
+
13
+[game]
14
+beginDate = 2018/12/07
15
+endDate = 2018/12/16
16
+gameNum = 10
17
+
18
+
19
+[alioss]
20
+Endpoint=oss-cn-shanghai.aliyuncs.com
21
+AccessKeyId=LTAIkc75dpkJw8Lb
22
+AccessKeySecret=v4bvXCaix6vSDTCFfwSAdqV53iFEQw
23
+Bucket=jingcheng-h5temp

+ 33
- 0
conf/db.conf Näytä tiedosto

@@ -0,0 +1,33 @@
1
+; 数据库类型,目前只支持mysql
2
+db_type      = mysql
3
+
4
+; 连接协议
5
+con_protocol = tcp
6
+
7
+; 数据库地址,可以使用IP
8
+# db_addr      = 47.101.36.130
9
+# db_addr        = 192.168.0.122
10
+db_addr = localhost
11
+# db_addr      = rm-uf6z3z6jq11x653d77o.mysql.rds.aliyuncs.com
12
+
13
+; 端口
14
+db_port      = 3306
15
+
16
+; 用户名
17
+username     = spaceofcheng
18
+
19
+; 密码
20
+password     = spaceofcheng
21
+# password     = c;a|vK)Xv/=L@c[6Fx,v[ITD5;WpR}+Y
22
+
23
+; 数据库名或者schema
24
+database     = support-game
25
+
26
+; 前缀,目前尚未使用
27
+dbprefix     = 
28
+
29
+; 模式,目前尚未使用
30
+db_debug     = false
31
+
32
+; 字符集
33
+char_set     = utf8mb4

+ 4
- 0
conf/log.conf Näytä tiedosto

@@ -0,0 +1,4 @@
1
+[common]
2
+filename="E:\\GoProject\\src\\support-game\\log\\common.log"
3
+# log level "emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"
4
+level="debug"

+ 4
- 0
conf/wechat.conf Näytä tiedosto

@@ -0,0 +1,4 @@
1
+appid = wx776f26b70b03902b
2
+secret = 36ad3e2017a77cb4005770bfa405d7b1
3
+wxid = gh_1ec36e12f0a9
4
+token = yansenisashit

+ 86
- 0
controllers/base.go Näytä tiedosto

@@ -0,0 +1,86 @@
1
+package controllers
2
+
3
+import (
4
+	"net/http"
5
+	"support-game/utils"
6
+
7
+	"github.com/astaxie/beego"
8
+	"github.com/astaxie/beego/config"
9
+)
10
+
11
+//BaseController 基础controller
12
+type BaseController struct {
13
+	beego.Controller
14
+	Context  *utils.Context
15
+	Configer map[string]config.Configer
16
+	RunMode  string
17
+}
18
+
19
+//Prepare 继承beego的
20
+func (c *BaseController) Prepare() {
21
+	// 读取配置文件
22
+	c.initConfig()
23
+
24
+	// 初始化上下文
25
+	c.initContext()
26
+
27
+	// 路由对应的实际 Controller 初始化
28
+	c.initController()
29
+}
30
+
31
+// ResponseJSON 返回JSON数据
32
+func (c *BaseController) ResponseJSON(data interface{}) {
33
+	c.ResponseData(data, "", http.StatusOK)
34
+}
35
+
36
+// ResponseError 返回错误
37
+func (c *BaseController) ResponseError(err error, code ...int) {
38
+	if len(code) > 0 {
39
+		c.ResponseData(nil, err, code[0])
40
+	}
41
+
42
+	c.ResponseData(nil, err, http.StatusBadRequest)
43
+}
44
+
45
+// ResponseRaw 返回
46
+func (c *BaseController) ResponseRaw(msg []byte, stop ...bool) {
47
+	c.Ctx.ResponseWriter.Write(msg)
48
+
49
+	if stop != nil && len(stop) > 0 {
50
+		if !stop[0] {
51
+			return
52
+		}
53
+	}
54
+
55
+	c.destroyContext(true)
56
+	c.StopRun()
57
+}
58
+
59
+// ResponseData 自定义的JSON返回
60
+func (c *BaseController) ResponseData(data interface{}, msg interface{}, code int) {
61
+	status := code
62
+
63
+	sendMessage := ""
64
+	switch msgVal := msg.(type) {
65
+	case error:
66
+		sendMessage = msgVal.Error()
67
+	case string:
68
+		sendMessage = msgVal
69
+	default:
70
+		sendMessage = ""
71
+	}
72
+
73
+	c.Data["json"] = JSONMessage{status, sendMessage, data}
74
+
75
+	c.destroyContext(status < http.StatusMultipleChoices)
76
+	c.crosPolicy()
77
+	c.ServeJSON()
78
+	c.StopRun()
79
+}
80
+
81
+// initAppController 执行当前路由请求对应的 Controller 初始化
82
+func (c *BaseController) initController() {
83
+	if ctrl, ok := c.AppController.(ControllerInterface); ok {
84
+		ctrl.Constructor()
85
+	}
86
+}

+ 37
- 0
controllers/config.go Näytä tiedosto

@@ -0,0 +1,37 @@
1
+package controllers
2
+
3
+import (
4
+	"support-game/utils"
5
+
6
+	"github.com/astaxie/beego/config"
7
+)
8
+
9
+// 配置文件列表
10
+const (
11
+	AppConf    = "app"
12
+	AliYunConf = "aliyun"
13
+	WeChatConf = "wechat"
14
+	SMSConf    = "sms"
15
+)
16
+
17
+func (c *BaseController) initConfig() {
18
+	// c.RunMode = beego.AppConfig.String("runmode")
19
+
20
+	if c.Configer == nil {
21
+		c.Configer = make(map[string]config.Configer)
22
+	}
23
+
24
+	// 系统
25
+	appConf, _ := utils.GetConfiger("conf/app.conf")
26
+	if appConf != nil {
27
+		c.Configer[AppConf] = appConf
28
+	}
29
+
30
+	c.RunMode = appConf.String("runmode")
31
+
32
+	// 微信
33
+	wechatConf, _ := utils.GetConfiger("conf/wechat.conf")
34
+	if wechatConf != nil {
35
+		c.Configer[WeChatConf] = wechatConf
36
+	}
37
+}

+ 33
- 0
controllers/context.go Näytä tiedosto

@@ -0,0 +1,33 @@
1
+package controllers
2
+
3
+import (
4
+	"support-game/models"
5
+	"support-game/utils"
6
+)
7
+
8
+/**
9
+* Context 说明
10
+* - 所有 stuct 类型均不是指针
11
+* - 包含内容如下
12
+**/
13
+
14
+// initContext 初始化 Context
15
+func (c *BaseController) initContext() {
16
+	c.Context = utils.NewContext(models.DBEngine, nil)
17
+	c.Context.Ready()
18
+}
19
+
20
+// initContext 销毁 Context
21
+func (c *BaseController) destroyContext(ok ...bool) {
22
+	if len(ok) == 0 || ok[0] {
23
+		c.Context.DB.Commit()
24
+	} else {
25
+		c.Context.DB.Rollback()
26
+	}
27
+
28
+	c.Context.Destroy()
29
+}
30
+
31
+func (c *BaseController) DestroyContext() {
32
+	c.destroyContext()
33
+}

+ 25
- 0
controllers/cros.go Näytä tiedosto

@@ -0,0 +1,25 @@
1
+package controllers
2
+
3
+// Options 解决跨域先发送 options
4
+func (c *BaseController) Options() {
5
+	c.ResponseJSON("")
6
+}
7
+
8
+// crosPolicy 跨域策略
9
+func (c *BaseController) crosPolicy() {
10
+	appConf, ok := c.Configer[AppConf]
11
+	if ok {
12
+		runMode := appConf.String("runmode")
13
+		allowMode := appConf.String("cros::allowMode")
14
+		allowMethods := appConf.String("cros::allowMethods")
15
+		allowOrigin := appConf.String("cros::allowOrigin")
16
+		allowCredentials := appConf.String("cros::allowCredentials")
17
+
18
+		if runMode == allowMode {
19
+			c.Ctx.Output.Header("Access-Control-Allow-Origin", allowOrigin)
20
+			c.Ctx.Output.Header("Access-Control-Allow-Methods", allowMethods)
21
+			c.Ctx.Output.Header("Access-Control-Allow-Credentials", allowCredentials)
22
+			c.Ctx.Output.Header("Access-Control-Allow-Headers", "X-Token,Authorization")
23
+		}
24
+	}
25
+}

+ 25
- 0
controllers/file.go Näytä tiedosto

@@ -0,0 +1,25 @@
1
+package controllers
2
+
3
+import (
4
+	"strconv"
5
+	"support-game/utils"
6
+	"time"
7
+)
8
+
9
+type ObjectController struct {
10
+	BaseController
11
+}
12
+
13
+// Post 上传图片
14
+func (c *ObjectController) Post() {
15
+	fNameExtra := strconv.FormatInt(time.Now().Unix(), 10)
16
+
17
+	fileURL, err := utils.UploadFileToBucket(c.Ctx.Request, "file", fNameExtra)
18
+	if err != nil {
19
+		c.ResponseError(err)
20
+	}
21
+
22
+	c.ResponseJSON(map[string]interface{}{
23
+		"url": fileURL,
24
+	})
25
+}

+ 101
- 0
controllers/game/support.go Näytä tiedosto

@@ -0,0 +1,101 @@
1
+package game
2
+
3
+import (
4
+	"net/url"
5
+	"support-game/controllers"
6
+	"support-game/service/game"
7
+	"support-game/utils"
8
+)
9
+
10
+// SupportController 活动
11
+type SupportController struct {
12
+	serv *game.SupportServ
13
+	controllers.BaseController
14
+}
15
+
16
+// Constructor 初始化 Controller
17
+// @Title Constructor
18
+// @Description 初始化 Controller, 系统自动调用
19
+func (c *SupportController) Constructor() {
20
+	c.serv = game.NewSupportServ(c.Context)
21
+}
22
+
23
+// GetCustomer 获取用户信息
24
+func (c *SupportController) GetCustomer() {
25
+	code := c.GetString(":code")
26
+	customer, err := c.serv.GetCustomerByCode(code)
27
+	if err != nil {
28
+		c.ResponseError(err)
29
+	}
30
+	c.ResponseJSON(customer)
31
+}
32
+
33
+// SignUp 注册
34
+func (c *SupportController) SignUp() {
35
+	customerid := c.GetString(":customerid")
36
+	name := c.GetString("name")
37
+	phone := c.GetString("phone")
38
+	address := c.GetString("address")
39
+	customer, err := c.serv.SignUp(customerid, name, phone, address)
40
+	if err != nil {
41
+		c.ResponseError(err)
42
+	}
43
+	c.ResponseJSON(customer)
44
+}
45
+
46
+// GetGame 获取主信息
47
+func (c *SupportController) GetGame() {
48
+	gameid := c.GetString(":gameid")
49
+	customerid := c.GetString(":customerid")
50
+	info, err := c.serv.GetGameInfo(gameid, customerid)
51
+	if err != nil {
52
+		c.ResponseError(err)
53
+	}
54
+	c.ResponseJSON(info)
55
+}
56
+
57
+// GetRecord 获取报名信息
58
+func (c *SupportController) GetRecord() {
59
+	recordid := c.GetString(":recordid")
60
+	info, err := c.serv.GetRecordInfo(recordid)
61
+	if err != nil {
62
+		c.ResponseError(err)
63
+	}
64
+	c.ResponseJSON(info)
65
+}
66
+
67
+// AddRecord 参加活动
68
+func (c *SupportController) AddRecord() {
69
+	customerid := c.GetString(":customerid")
70
+	gameid := c.GetString(":gameid")
71
+	record, err := c.serv.AddRecord(customerid, gameid)
72
+	if err != nil {
73
+		c.ResponseError(err)
74
+	}
75
+	c.ResponseJSON(record)
76
+}
77
+
78
+// AddSupport 助力
79
+func (c *SupportController) AddSupport() {
80
+	customerid := c.GetString(":customerid")
81
+	recordid := c.GetString(":recordid")
82
+	info, err := c.serv.AddSupport(recordid, customerid)
83
+	if err != nil {
84
+		c.ResponseError(err)
85
+	}
86
+	c.ResponseJSON(info)
87
+}
88
+
89
+// WechatInfo 微信接入
90
+func (c *SupportController) WechatInfo() {
91
+	echostr := c.GetString("echostr")
92
+	c.ResponseRaw([]byte(echostr))
93
+}
94
+
95
+// GetWxJsSDKSignature 获取 微信 jssdk 签名
96
+func (c *SupportController) GetWxJsSDKSignature() {
97
+	url, _ := url.QueryUnescape(c.GetString("url"))
98
+
99
+	res := utils.WxClient().GetJsTicketSignature(url)
100
+	c.ResponseJSON(res)
101
+}

+ 106
- 0
controllers/game/voting.go Näytä tiedosto

@@ -0,0 +1,106 @@
1
+package game
2
+
3
+import (
4
+	"errors"
5
+	"support-game/controllers"
6
+	gamemodel "support-game/models/game"
7
+	"support-game/models/model"
8
+	"support-game/service/game"
9
+)
10
+
11
+// VotingController 活动
12
+type VotingController struct {
13
+	serv *game.VotingServ
14
+	controllers.BaseController
15
+}
16
+
17
+// Constructor 初始化 Controller
18
+// @Title Constructor
19
+// @Description 初始化 Controller, 系统自动调用
20
+func (c *VotingController) Constructor() {
21
+	c.serv = game.NewVotingServ(c.Context)
22
+}
23
+
24
+// List 获取列表
25
+func (c *VotingController) List() {
26
+	// 活动
27
+	actID, _ := c.GetInt("actid")
28
+
29
+	// 分页
30
+	page, _ := c.GetInt("page")
31
+	if page < 1 {
32
+		page = 1
33
+	}
34
+	page -= 1
35
+
36
+	// tab 类型
37
+	tab, _ := c.GetInt("tab")
38
+
39
+	// 搜索条件
40
+	search := c.GetString("q")
41
+	list, err := c.serv.GetList(actID, search, tab, page)
42
+	if err != nil {
43
+		c.ResponseError(errors.New("查询列表失败, 请重试"))
44
+	}
45
+
46
+	c.ResponseJSON(list)
47
+}
48
+
49
+// Activities 活动详情
50
+func (c *VotingController) Activities() {
51
+	// 活动
52
+	actID, _ := c.GetInt(":actid")
53
+	activitie, err := c.serv.GetActivitiesInfo(actID)
54
+	if err != nil {
55
+		c.ResponseError(errors.New("查询活动失败,请重试"))
56
+	}
57
+
58
+	c.ResponseJSON(activitie)
59
+}
60
+
61
+// Detail 报名详情
62
+func (c *VotingController) Detail() {
63
+	// 活动
64
+	actID, _ := c.GetInt(":actid")
65
+	memberid, _ := c.GetInt(":memberid")
66
+	activitie, err := c.serv.GetMemberInfo(actID, memberid)
67
+	if err != nil {
68
+		c.ResponseError(errors.New("查询活动详情失败,请重试"))
69
+	}
70
+
71
+	c.ResponseJSON(activitie)
72
+}
73
+
74
+// Registe 报名
75
+func (c *VotingController) Registe() {
76
+	// 活动
77
+	actID, _ := c.GetInt(":actid")
78
+	member := gamemodel.MemInfo{}
79
+	if err := c.ParseForm(&member); err != nil {
80
+		c.ResponseError(errors.New("参数错误!"))
81
+	}
82
+	member.ActivityId = actID
83
+	err := c.serv.Registe(&member)
84
+	if err != nil {
85
+		c.ResponseError(errors.New("查询活动详情失败,请重试"))
86
+	}
87
+	c.ResponseJSON(member)
88
+}
89
+
90
+// Vote 投票
91
+func (c *VotingController) Vote() {
92
+	actID, _ := c.GetInt(":actid")
93
+	memberid, _ := c.GetInt(":memberid")
94
+	openid := c.GetString("openid")
95
+	record := model.TaVotingRecords{
96
+		ActivityId: actID,
97
+		MemberId:   memberid,
98
+		Openid:     openid,
99
+	}
100
+
101
+	err := c.serv.Vote(&record)
102
+	if err != nil {
103
+		c.ResponseError(errors.New("投票失败,请重试"))
104
+	}
105
+	c.ResponseJSON(record)
106
+}

+ 13
- 0
controllers/types.go Näytä tiedosto

@@ -0,0 +1,13 @@
1
+package controllers
2
+
3
+// JSONMessage 主要用于 Response 返回
4
+type JSONMessage struct {
5
+	Code    int         `json:"code"`
6
+	Message string      `json:"message"`
7
+	Result  interface{} `json:"result"`
8
+}
9
+
10
+// ControllerInterface 项目约定的 Controller 须满足的接口
11
+type ControllerInterface interface {
12
+	Constructor()
13
+}

+ 18
- 0
main.go Näytä tiedosto

@@ -0,0 +1,18 @@
1
+package main
2
+
3
+import (
4
+	"support-game/bootstrap"
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
+
15
+	bootstrap.SystemInit()
16
+
17
+	beego.Run()
18
+}

+ 16
- 0
models/constant.go Näytä tiedosto

@@ -0,0 +1,16 @@
1
+package models
2
+
3
+// 状态列表
4
+const (
5
+	// 删除
6
+	STATUS_DEL = iota - 1
7
+
8
+	// 进行中
9
+	STATUS_READY
10
+
11
+	// 已成功
12
+	STATUS_NORMAL
13
+
14
+	// 已失效
15
+	STATUS_INVALID
16
+)

+ 154
- 0
models/game/support.go Näytä tiedosto

@@ -0,0 +1,154 @@
1
+package game
2
+
3
+import (
4
+	"support-game/models"
5
+	"support-game/models/model"
6
+	"support-game/utils"
7
+	"time"
8
+
9
+	"github.com/go-xorm/xorm"
10
+)
11
+
12
+// SupportDao 当前数据库操作对象
13
+type SupportDao struct {
14
+	ctx *utils.Context
15
+	db  *xorm.Session
16
+}
17
+
18
+// NewSupportDao 初始化DAO
19
+func NewSupportDao(ctx *utils.Context) *SupportDao {
20
+	return &SupportDao{
21
+		ctx: ctx,
22
+		db:  ctx.DB,
23
+	}
24
+}
25
+
26
+// GetCustomerByOpenID 根据openid获取用户信息
27
+func (m *SupportDao) GetCustomerByOpenID(openid string) (*model.TaCustomer, error) {
28
+	var customer = model.TaCustomer{}
29
+	_, err := m.db.Where("openid=?", openid).Get(&customer)
30
+	return &customer, err
31
+}
32
+
33
+// SaveCustomer 保存用户信息
34
+func (m *SupportDao) SaveCustomer(customer model.TaCustomer) (*model.TaCustomer, error) {
35
+	customer.CustomerId = utils.GetGUID()
36
+	customer.CreateDate = time.Now()
37
+	_, err := m.db.Insert(customer)
38
+	return &customer, err
39
+}
40
+
41
+// UpdateCustomer 修改用户信息
42
+func (m *SupportDao) UpdateCustomer(customer *model.TaCustomer, cols []string) error {
43
+	_, err := m.db.Cols(cols...).Where("customer_id=?", customer.CustomerId).Update(customer)
44
+	return err
45
+}
46
+
47
+// UpdateRecord 修改活动信息
48
+func (m *SupportDao) UpdateRecord(record *model.TaGameRecord, cols []string) error {
49
+	_, err := m.db.Cols(cols...).Where("record_id=?", record.RecordId).Update(record)
50
+	return err
51
+}
52
+
53
+// GetCustomerByID 根据id获取用户信息
54
+func (m *SupportDao) GetCustomerByID(id string) (*model.TaCustomer, error) {
55
+	var customer = model.TaCustomer{}
56
+	_, err := m.db.Where("customer_id=?", id).Get(&customer)
57
+	return &customer, err
58
+}
59
+
60
+// GetRecordByID 根据id获取记录
61
+func (m *SupportDao) GetRecordByID(recordid string) (*model.TaGameRecord, error) {
62
+	var record model.TaGameRecord
63
+	_, err := m.db.Where("record_id=?", recordid).Get(&record)
64
+	return &record, err
65
+}
66
+
67
+// RecordSupport 助力记录
68
+type RecordSupport struct {
69
+	model.TaRecordSuppot `xorm:"extends"`
70
+	CustomerName         string
71
+	Name                 string
72
+	HeadImg              string
73
+}
74
+
75
+// GetSupportsByRecord 获取助力信息
76
+func (m *SupportDao) GetSupportsByRecord(recordid string) ([]RecordSupport, error) {
77
+	var supports []RecordSupport
78
+	sql := `select a.*,b.customer_name,b.name,b.head_img from ta_record_suppot a inner join ta_customer b on a.customer_id=b.customer_id where record_id=?`
79
+	err := m.db.Sql(sql, recordid).Find(&supports)
80
+	return supports, err
81
+}
82
+
83
+// GetTodayQuota 获取今天成功的活动
84
+func (m *SupportDao) GetTodayQuota(gameid string) ([]model.TaGameRecord, error) {
85
+	var records []model.TaGameRecord
86
+	sql := `select * from ta_game_record where date_format(create_date,'%Y-%m-%d') = date_format(now(),'%Y-%m-%d') and status = ? and game_id=?`
87
+	err := m.db.Sql(sql, models.STATUS_NORMAL, gameid).Find(&records)
88
+	return records, err
89
+}
90
+
91
+// GetTodayCustomerRecord 获取客户今天参与的活动
92
+func (m *SupportDao) GetTodayCustomerRecord(customerid, gameid string) ([]model.TaGameRecord, error) {
93
+	var records []model.TaGameRecord
94
+	sql := `select * from ta_game_record where date_format(create_date,'%Y-%m-%d') = date_format(now(),'%Y-%m-%d') and customer_id=? and game_id=?`
95
+	err := m.db.Sql(sql, customerid, gameid).Find(&records)
96
+	return records, err
97
+}
98
+
99
+// GetCustomerQuota 获取用户成功的活动
100
+func (m *SupportDao) GetCustomerQuota(customerid, gameid string) ([]model.TaGameRecord, error) {
101
+	var records []model.TaGameRecord
102
+	sql := `select * from ta_game_record where customer_id=? and status = ? and game_id=?`
103
+	err := m.db.Sql(sql, customerid, models.STATUS_NORMAL, gameid).Find(&records)
104
+	return records, err
105
+}
106
+
107
+// AddRecord 新增活动
108
+func (m *SupportDao) AddRecord(record model.TaGameRecord) (*model.TaGameRecord, error) {
109
+	record.RecordId = utils.GetGUID()
110
+	record.CreateDate = time.Now()
111
+	record.Status = models.STATUS_READY
112
+	_, err := m.db.Insert(record)
113
+	return &record, err
114
+}
115
+
116
+// AddSupport 新增助力
117
+func (m *SupportDao) AddSupport(support model.TaRecordSuppot) (*model.TaRecordSuppot, error) {
118
+	support.CreateDate = time.Now()
119
+	support.SupportId = utils.GetGUID()
120
+	_, err := m.db.Insert(support)
121
+	return &support, err
122
+}
123
+
124
+// GetCustomerSupport 获取用户当前活动的助力信息
125
+func (m *SupportDao) GetCustomerSupport(recordid, customerid string) ([]model.TaRecordSuppot, error) {
126
+	var supports []model.TaRecordSuppot
127
+	err := m.db.Where("record_id=?", recordid).And("customer_id=?", customerid).Find(&supports)
128
+	return supports, err
129
+}
130
+
131
+// GetGameByID 获取主活动信息
132
+func (m *SupportDao) GetGameByID(gameid string) (*model.TaGame, error) {
133
+	var game model.TaGame
134
+	_, err := m.db.Where("game_id=?", gameid).Get(&game)
135
+	return &game, err
136
+}
137
+
138
+// GetGameNote 获取活动今日信息
139
+func (m *SupportDao) GetGameNote(gameid string) (*model.TaGameNotes, error) {
140
+	var note model.TaGameNotes
141
+	_, err := m.db.Where("game_id=?", gameid).And("date_format(game_date,'%Y-%m-%d') = date_format(now(),'%Y-%m-%d')").Get(&note)
142
+	return &note, err
143
+}
144
+
145
+// UpdateLeftNum 更新活动剩余次数
146
+func (m *SupportDao) UpdateLeftNum(gameid string) (int64, error) {
147
+	sql := `update ta_game_notes set left_num = left_num-1 where date_format(game_date,'%Y-%m-%d') = date_format(now(),'%Y-%m-%d') and game_id=? and left_num>0`
148
+	s, err := m.db.Exec(sql, gameid)
149
+	if err != nil {
150
+		return 0, err
151
+	}
152
+	row, _ := s.RowsAffected()
153
+	return row, nil
154
+}

+ 339
- 0
models/game/voting.go Näytä tiedosto

@@ -0,0 +1,339 @@
1
+package game
2
+
3
+import (
4
+	"encoding/json"
5
+	"errors"
6
+	"strconv"
7
+	"support-game/models"
8
+	"support-game/models/model"
9
+	"support-game/utils"
10
+	"time"
11
+
12
+	"github.com/go-xorm/xorm"
13
+)
14
+
15
+const (
16
+	// 默认图片类型
17
+	DefaultPhotoType = "main"
18
+
19
+	// 列表排序类型
20
+	OrderByDate = 1
21
+	OrderByVote = 2
22
+
23
+	// 活动限制规则
24
+	RuleOfLimitEveryday = "limiteveryday"
25
+
26
+	PageNum = 10
27
+)
28
+
29
+var (
30
+	ErrVoteLimit        = errors.New("votelimit")
31
+	ErrActivityNotStart = errors.New("Activity not start")
32
+	ErrActivityIsOver   = errors.New("Activity is over")
33
+)
34
+
35
+// VotingModel 当前数据库操作对象
36
+type VotingModel struct {
37
+	ctx *utils.Context
38
+	db  *xorm.Session
39
+}
40
+
41
+// NewVotingModel 初始化DAO
42
+func NewVotingModel(ctx *utils.Context) *VotingModel {
43
+	return &VotingModel{
44
+		ctx: ctx,
45
+		db:  ctx.DB,
46
+	}
47
+}
48
+
49
+type MemInfo struct {
50
+	model.TaVotingMember `xorm:"extends"`
51
+	Photo                string `xorm:"TEXT"`
52
+	Rank                 int
53
+}
54
+
55
+// List 报名列表
56
+func (m *VotingModel) List(actID int, search string, orderby, page int) (list []MemInfo, err error) {
57
+	query := `
58
+		SELECT t.*, s.photo
59
+		FROM
60
+			ta_voting_member t
61
+		JOIN ta_voting_member_photos s ON t.member_id = s.member_id
62
+			AND t.activity_id = s.activity_id
63
+			AND s.type = '` + DefaultPhotoType + `'
64
+			AND s.status = ` + strconv.Itoa(models.STATUS_NORMAL) + `
65
+		Where t.activity_id = '` + strconv.Itoa(actID) + `' AND 
66
+	`
67
+
68
+	// 依据 ID 或者 名称查询
69
+	// 全部列表的时候, 名称为空即可
70
+	if search != "" {
71
+		query += `(t.member_id like '%` + search + `%' or t.name like '%` + search + `%') AND`
72
+	}
73
+	query += " t.status = " + strconv.Itoa(models.STATUS_NORMAL)
74
+
75
+	// 排序
76
+	if orderby == OrderByVote {
77
+		query += " order by t.vote desc"
78
+		if page > 5 {
79
+			page = 5
80
+		}
81
+	} else {
82
+		query += " order by t.create_date desc"
83
+	}
84
+
85
+	// 分页
86
+	offset := (page - 1) * PageNum
87
+	if offset < 0 {
88
+		offset = 0
89
+	}
90
+
91
+	query += " limit " + strconv.Itoa(PageNum) + " offset " + strconv.Itoa(offset)
92
+
93
+	if err = m.db.Sql(query).Find(&list); err != nil {
94
+		return
95
+	}
96
+
97
+	return
98
+}
99
+
100
+// GetActivityInfo 查询活动
101
+func (m *VotingModel) GetActivityInfo(actID int) (act *model.TaVotingActivities, err error) {
102
+	_, err = m.db.Table("ta_voting_activities").Where("activity_id=?", actID).Get(act)
103
+	if err != nil {
104
+		return
105
+	}
106
+	return
107
+}
108
+
109
+// GetMemInfo 获取报名人员信息
110
+func (m *VotingModel) GetMemInfo(actID, memID int) (mem *MemInfo, err error) {
111
+	query := `
112
+		SELECT t.*, s.photo
113
+		FROM
114
+			ta_voting_member t
115
+		JOIN ta_voting_member_photos s ON t.member_id = s.member_id
116
+			AND t.activity_id = s.activity_id
117
+			AND s.type = '` + DefaultPhotoType + `'
118
+			AND s.status = ` + strconv.Itoa(models.STATUS_NORMAL) + `
119
+		Where t.activity_id = ? AND t.member_id = ?
120
+	`
121
+
122
+	if _, err = m.db.SQL(query, actID, memID).Get(mem); err != nil {
123
+		return
124
+	}
125
+
126
+	// 获取排名
127
+	cnt, e := m.db.Where("activity_id=?", actID).
128
+		And("status=?", models.STATUS_NORMAL).
129
+		And("vote>?", mem.Vote).
130
+		Count()
131
+	if e != nil {
132
+		// -1 代表发生错误
133
+		mem.Rank = -1
134
+		return
135
+	}
136
+
137
+	mem.Rank = int(cnt)
138
+	return
139
+}
140
+
141
+// Registe 报名保存
142
+func (m *VotingModel) Registe(memInfo *MemInfo) error {
143
+	if memInfo.ActivityId == 0 {
144
+		return errors.New("活动报名失败, 没有指定活动内容")
145
+	}
146
+	// 校验活动
147
+	if err := m.checkActivity(memInfo.ActivityId); err != nil {
148
+		return err
149
+	}
150
+
151
+	now := time.Now().Local()
152
+
153
+	mem := memInfo.TaVotingMember
154
+	photo := model.TaVotingMemberPhotos{
155
+		ActivityId: mem.ActivityId,
156
+		Photo:      memInfo.Photo,
157
+		Type:       DefaultPhotoType,
158
+		CreateDate: now,
159
+		Status:     models.STATUS_NORMAL,
160
+	}
161
+
162
+	// 检查已有最大值
163
+	maxID, err := m.getMaxMemID(mem.ActivityId)
164
+	if err != nil {
165
+		return err
166
+	}
167
+
168
+	mem.MemberId = int(maxID + 1)
169
+	mem.Vote = 0
170
+	photo.MemberId = mem.MemberId
171
+	memInfo.MemberId = mem.MemberId
172
+
173
+	if _, err := m.db.Insert(&photo); err != nil {
174
+		return err
175
+	}
176
+
177
+	if _, err := m.db.Insert(&mem); err != nil {
178
+		return err
179
+	}
180
+
181
+	// 反更新报名人数
182
+	// TODO
183
+
184
+	return nil
185
+}
186
+
187
+func (m *VotingModel) getMaxMemID(actID int) (maxID int64, err error) {
188
+	query := `
189
+		SELECT
190
+			max(start_id) as max_id
191
+		FROM
192
+			(
193
+				SELECT
194
+					max(t.member_id) AS start_id
195
+				FROM
196
+					ta_voting_member t
197
+				UNION
198
+					SELECT
199
+						s.start_id
200
+					FROM
201
+						ta_voting_activities s
202
+					WHERE
203
+						s.activity_id = ?
204
+			) a
205
+	`
206
+
207
+	if _, err = m.db.SQL(query, actID).Get(&maxID); err != nil {
208
+		return
209
+	}
210
+
211
+	return
212
+}
213
+
214
+// Vote 投票
215
+func (m *VotingModel) Vote(rec *model.TaVotingRecords) error {
216
+	// 校验活动
217
+	if err := m.checkActivity(rec.ActivityId); err != nil {
218
+		return err
219
+	}
220
+
221
+	rule, err := m.getActivityRule(rec.ActivityId)
222
+	if err != nil {
223
+		return err
224
+	}
225
+
226
+	var ruleParam map[string]interface{}
227
+	if err := json.Unmarshal([]byte(rule.RuleValue), &ruleParam); err != nil {
228
+		return err
229
+	}
230
+
231
+	// 如果有每天最大投票限制
232
+	if v, ok := ruleParam[RuleOfLimitEveryday]; ok {
233
+		limitEveryday := int64(v.(float64))
234
+
235
+		voteNum, err := m.getVoteNumOfMember(rec)
236
+		if err != nil {
237
+			return err
238
+		}
239
+
240
+		if voteNum >= limitEveryday {
241
+			return ErrVoteLimit
242
+		}
243
+	}
244
+
245
+	// 每天投票
246
+	rec.VoteDate = time.Now().Local()
247
+	if _, err := m.db.Insert(rec); err != nil {
248
+		return err
249
+	}
250
+
251
+	// 反更新次数
252
+	if err := m.updateVoteOfMember(rec.ActivityId, rec.MemberId); err != nil {
253
+		return err
254
+	}
255
+
256
+	return nil
257
+}
258
+
259
+// 获取投票规则
260
+func (m *VotingModel) getActivityRule(actID int) (rule *model.TaVotingRules, err error) {
261
+	query := `
262
+		SELECT
263
+			t.*
264
+		FROM
265
+			ta_voting_rules t
266
+		JOIN ta_voting_activities s ON t.rule_id = s.rule_id
267
+		AND s.activity_id = ?
268
+	`
269
+
270
+	if _, err = m.db.SQL(query, actID).Get(rule); err != nil {
271
+		return
272
+	}
273
+
274
+	if rule.RuleValue == "" {
275
+		rule.RuleValue = "{}"
276
+	}
277
+
278
+	return
279
+}
280
+
281
+// 获取当前人员投票数
282
+func (m *VotingModel) getVoteNumOfMember(rec *model.TaVotingRecords) (num int64, err error) {
283
+	query := `
284
+		SELECT
285
+			*
286
+		FROM
287
+			ta_voting_records t
288
+		WHERE
289
+			t.activity_id = ?
290
+		AND t.member_id = ?
291
+		AND t.openid = ?
292
+		AND date_format(t.vote_date, "%Y-%m-%d") = date_format(now(), "%Y-%m-%d")
293
+	`
294
+
295
+	num, err = m.db.SQL(query, rec.ActivityId, rec.MemberId, rec.Openid).Count()
296
+	if err != nil {
297
+		return
298
+	}
299
+
300
+	return
301
+}
302
+
303
+// 反更新投票次数
304
+func (m *VotingModel) updateVoteOfMember(actID, memID int) error {
305
+	query := `
306
+	UPDATE ta_voting_member t
307
+		SET t.vote = t.vote + 1
308
+		WHERE
309
+			t.activity_id = ?
310
+		AND t.member_id = ?
311
+	`
312
+
313
+	if _, err := m.db.Exec(query, actID, memID); err != nil {
314
+		return err
315
+	}
316
+
317
+	return nil
318
+}
319
+
320
+// 校验活动
321
+// 只校验活动时间
322
+func (m *VotingModel) checkActivity(actID int) error {
323
+	act := model.TaVotingActivities{}
324
+
325
+	if _, err := m.db.Where("activity_id=?", actID).Get(&act); err != nil {
326
+		return err
327
+	}
328
+
329
+	now := time.Now().Local()
330
+	if act.StartTime.After(now) {
331
+		return ErrActivityNotStart
332
+	}
333
+
334
+	if act.EndTime.Before(now) {
335
+		return ErrActivityIsOver
336
+	}
337
+
338
+	return nil
339
+}

+ 17
- 0
models/model/ta_customer.go Näytä tiedosto

@@ -0,0 +1,17 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaCustomer struct {
8
+	CustomerId   string    `xorm:"VARCHAR(64)"`
9
+	Openid       string    `xorm:"VARCHAR(200)"`
10
+	CreateDate   time.Time `xorm:"DATETIME"`
11
+	HeadImg      string    `xorm:"TEXT"`
12
+	CustomerName string    `xorm:"VARCHAR(50)"`
13
+	Name         string    `xorm:"VARCHAR(50)"`
14
+	Phone        string    `xorm:"VARCHAR(50)"`
15
+	Address      string    `xorm:"VARCHAR(500)"`
16
+	Sex          int       `xorm:"SMALLINT(6)"`
17
+}

+ 15
- 0
models/model/ta_game.go Näytä tiedosto

@@ -0,0 +1,15 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaGame struct {
8
+	GameId    string    `xorm:"VARCHAR(64)"`
9
+	GameName  string    `xorm:"VARCHAR(50)"`
10
+	BeginDate time.Time `xorm:"DATETIME"`
11
+	EndDate   time.Time `xorm:"DATETIME"`
12
+	DayNum    int       `xorm:"INT(11)"`
13
+	Status    int       `xorm:"SMALLINT(6)"`
14
+	UserNum   int       `xorm:"INT(11)"`
15
+}

+ 13
- 0
models/model/ta_game_notes.go Näytä tiedosto

@@ -0,0 +1,13 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaGameNotes struct {
8
+	NotesId  string    `xorm:"VARCHAR(64)"`
9
+	GameId   string    `xorm:"VARCHAR(64)"`
10
+	GameDate time.Time `xorm:"DATETIME"`
11
+	Num      int       `xorm:"INT(11)"`
12
+	LeftNum  int       `xorm:"INT(11)"`
13
+}

+ 14
- 0
models/model/ta_game_record.go Näytä tiedosto

@@ -0,0 +1,14 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaGameRecord struct {
8
+	RecordId   string    `xorm:"VARCHAR(64)"`
9
+	GameId     string    `xorm:"VARCHAR(64)"`
10
+	GameName   string    `xorm:"VARCHAR(50)"`
11
+	CustomerId string    `xorm:"VARCHAR(64)"`
12
+	CreateDate time.Time `xorm:"DATETIME"`
13
+	Status     int       `xorm:"SMALLINT(6)"`
14
+}

+ 12
- 0
models/model/ta_record_suppot.go Näytä tiedosto

@@ -0,0 +1,12 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaRecordSuppot struct {
8
+	SupportId  string    `xorm:"VARCHAR(64)"`
9
+	RecordId   string    `xorm:"VARCHAR(64)"`
10
+	CustomerId string    `xorm:"VARCHAR(64)"`
11
+	CreateDate time.Time `xorm:"DATETIME"`
12
+}

+ 27
- 0
models/model/ta_voting_activities.go Näytä tiedosto

@@ -0,0 +1,27 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaVotingActivities struct {
8
+	ActivityId int       `xorm:"not null pk autoincr SMALLINT(6)"`
9
+	RuleId     int       `xorm:"SMALLINT(6)"`
10
+	Music      string    `xorm:"TEXT"`
11
+	Name       string    `xorm:"VARCHAR(300)"`
12
+	Thumb      string    `xorm:"TEXT"`
13
+	Banner     string    `xorm:"TEXT"`
14
+	Desc       string    `xorm:"TEXT"`
15
+	Rules      string    `xorm:"TEXT"`
16
+	StartTime  time.Time `xorm:"DATETIME"`
17
+	EndTime    time.Time `xorm:"DATETIME"`
18
+	Remark     string    `xorm:"VARCHAR(500)"`
19
+	CreateDate time.Time `xorm:"DATETIME"`
20
+	Status     int       `xorm:"SMALLINT(6)"`
21
+	Members    int       `xorm:"INT(11)"`
22
+	StartId    int       `xorm:"INT(11)"`
23
+	AfterVote  string    `xorm:"TEXT"`
24
+	ShareTitle string    `xorm:"VARCHAR(100)"`
25
+	ShareIcon  string    `xorm:"TEXT"`
26
+	ShareDesc  string    `xorm:"VARCHAR(200)"`
27
+}

+ 19
- 0
models/model/ta_voting_member.go Näytä tiedosto

@@ -0,0 +1,19 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaVotingMember struct {
8
+	MemberId   int       `xorm:"not null pk INT(11)"`
9
+	ActivityId int       `xorm:"not null pk SMALLINT(6)"`
10
+	Name       string    `xorm:"VARCHAR(200)"`
11
+	Phone      string    `xorm:"VARCHAR(20)"`
12
+	Addr       string    `xorm:"TEXT"`
13
+	Message    string    `xorm:"TEXT"`
14
+	Remark     string    `xorm:"VARCHAR(500)"`
15
+	CreateDate time.Time `xorm:"DATETIME"`
16
+	Status     int       `xorm:"SMALLINT(6)"`
17
+	Vote       int       `xorm:"INT(11)"`
18
+	Openid     string    `xorm:"VARCHAR(64)"`
19
+}

+ 16
- 0
models/model/ta_voting_member_photos.go Näytä tiedosto

@@ -0,0 +1,16 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaVotingMemberPhotos struct {
8
+	PhotoId    int       `xorm:"not null pk autoincr INT(11)"`
9
+	MemberId   int       `xorm:"INT(11)"`
10
+	ActivityId int       `xorm:"SMALLINT(6)"`
11
+	Photo      string    `xorm:"TEXT"`
12
+	Type       string    `xorm:"VARCHAR(20)"`
13
+	Desc       string    `xorm:"VARCHAR(300)"`
14
+	CreateDate time.Time `xorm:"DATETIME"`
15
+	Status     int       `xorm:"SMALLINT(6)"`
16
+}

+ 15
- 0
models/model/ta_voting_records.go Näytä tiedosto

@@ -0,0 +1,15 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaVotingRecords struct {
8
+	VoteId     int       `xorm:"not null pk autoincr INT(11)"`
9
+	MemberId   int       `xorm:"INT(11)"`
10
+	ActivityId int       `xorm:"SMALLINT(6)"`
11
+	VoteDate   time.Time `xorm:"DATETIME"`
12
+	NickName   string    `xorm:"VARCHAR(200)"`
13
+	Avatar     string    `xorm:"TEXT"`
14
+	Openid     string    `xorm:"VARCHAR(64)"`
15
+}

+ 8
- 0
models/model/ta_voting_rules.go Näytä tiedosto

@@ -0,0 +1,8 @@
1
+package model
2
+
3
+type TaVotingRules struct {
4
+	RuleId    int    `xorm:"not null pk autoincr SMALLINT(6)"`
5
+	RuleValue string `xorm:"TEXT"`
6
+	Desc      string `xorm:"TEXT"`
7
+	Status    int    `xorm:"SMALLINT(6)"`
8
+}

+ 55
- 0
models/models.go Näytä tiedosto

@@ -0,0 +1,55 @@
1
+package models
2
+
3
+import (
4
+	"support-game/utils"
5
+
6
+	"github.com/astaxie/beego/config"
7
+	_ "github.com/go-sql-driver/mysql"
8
+	"github.com/go-xorm/xorm"
9
+)
10
+
11
+var (
12
+	DBEngine *xorm.Engine
13
+)
14
+
15
+func InitDB() {
16
+	DBEngine = NewDBEngine()
17
+}
18
+
19
+// NewDBEngine 初始化数据库连接
20
+func NewDBEngine() *xorm.Engine {
21
+	dbType := "mysql"
22
+	dns := getMySQLDNS()
23
+
24
+	engine, err := xorm.NewEngine(dbType, dns)
25
+	engine.ShowSQL()
26
+
27
+	if err != nil {
28
+		panic(err)
29
+	}
30
+
31
+	return engine
32
+}
33
+
34
+func getMySQLDNS() (dns string) {
35
+	appRoot := utils.GetAppRoot()
36
+	dbconf, _ := config.NewConfig("ini", appRoot+"/conf/db.conf")
37
+
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
+	charSet := dbconf.DefaultString("char_set", "utf8")
45
+
46
+	dns = userName
47
+
48
+	if len(password) > 0 {
49
+		dns += ":" + password
50
+	}
51
+
52
+	dns += "@" + conProt + "(" + dbAddr + ":" + dbPort + ")" + "/" + database + "?charset=" + charSet
53
+
54
+	return
55
+}

+ 38
- 0
routers/router.go Näytä tiedosto

@@ -0,0 +1,38 @@
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
+	"support-game/controllers"
12
+	"support-game/controllers/game"
13
+
14
+	"github.com/astaxie/beego"
15
+)
16
+
17
+func RouteInit() {
18
+	ns := beego.NewNamespace("api",
19
+		// 解决跨域时 先发送 options 问题
20
+		beego.NSRouter("*", &controllers.BaseController{}, "options:Options"),
21
+		beego.NSRouter("/wechat", &game.SupportController{}, "get:WechatInfo"),
22
+		beego.NSRouter("/game/:gameid/:customerid", &game.SupportController{}, "get:GetGame"),
23
+		beego.NSRouter("/customer/:code", &game.SupportController{}, "get:GetCustomer"),
24
+		beego.NSRouter("/signup/:customerid", &game.SupportController{}, "post:SignUp"),
25
+		beego.NSRouter("/record/:recordid", &game.SupportController{}, "get:GetRecord"),
26
+		beego.NSRouter("/record/:customerid/:gameid", &game.SupportController{}, "post:AddRecord"),
27
+		beego.NSRouter("/support/:customerid/:recordid", &game.SupportController{}, "post:AddSupport"),
28
+		beego.NSRouter("/wechat/jssdk/signature", &game.SupportController{}, "get:GetWxJsSDKSignature"),
29
+
30
+		beego.NSRouter("/voting", &game.VotingController{}, "get:List"),
31
+		beego.NSRouter("/voting/:actid", &game.VotingController{}, "get:Activities"),
32
+		beego.NSRouter("/voting/:actid/:memberid", &game.VotingController{}, "get:Detail"),
33
+		beego.NSRouter("/voting/:actid", &game.VotingController{}, "post:Registe"),
34
+		beego.NSRouter("/voting/:actid/:memberid", &game.VotingController{}, "post:Vote"),
35
+	)
36
+
37
+	beego.AddNamespace(ns)
38
+}

+ 317
- 0
service/game/support.go Näytä tiedosto

@@ -0,0 +1,317 @@
1
+package game
2
+
3
+import (
4
+	"errors"
5
+	"support-game/models"
6
+	"support-game/models/game"
7
+	"support-game/models/model"
8
+	"support-game/utils"
9
+	"time"
10
+)
11
+
12
+// SupportServ 活动serv
13
+type SupportServ struct {
14
+	ctx *utils.Context
15
+	dao *game.SupportDao
16
+}
17
+
18
+// NewSupportServ 初始化
19
+func NewSupportServ(ctx *utils.Context) *SupportServ {
20
+	return &SupportServ{
21
+		ctx: ctx,
22
+		dao: game.NewSupportDao(ctx),
23
+	}
24
+}
25
+
26
+// GetCustomerByCode 获取用户信息
27
+func (s *SupportServ) GetCustomerByCode(code string) (*model.TaCustomer, error) {
28
+	if code == "" {
29
+		return nil, errors.New("code为空")
30
+	}
31
+	data, err := utils.WxClient().GetUserInfo(code)
32
+	if err != nil {
33
+		utils.LogError("获取微信用户信息失败:", err)
34
+		return nil, err
35
+	}
36
+
37
+	openid := data["openid"].(string)
38
+	customer, err := s.dao.GetCustomerByOpenID(openid)
39
+	if err != nil {
40
+		utils.LogError("获取用户信息失败:", err)
41
+		return nil, err
42
+	}
43
+
44
+	if customer != nil && customer.CustomerId != "" && customer.CustomerName != "" {
45
+		return customer, nil
46
+	}
47
+
48
+	user := model.TaCustomer{}
49
+	user.Openid = openid
50
+
51
+	if data["sex"] != nil {
52
+		user.Sex = int(data["sex"].(float64))
53
+	}
54
+
55
+	if data["nickname"] != nil {
56
+		user.CustomerName = data["nickname"].(string)
57
+	}
58
+
59
+	if data["headimgurl"] != nil {
60
+		user.HeadImg = data["headimgurl"].(string)
61
+	}
62
+
63
+	if customer != nil && customer.CustomerId != "" {
64
+		user.CustomerId = customer.CustomerId
65
+		err = s.dao.UpdateCustomer(&user, []string{
66
+			"sex",
67
+			"customer_name",
68
+			"head_img",
69
+		})
70
+
71
+		if err != nil {
72
+			utils.LogError("修改用户信息失败", err)
73
+			return nil, err
74
+		}
75
+		return &user, nil
76
+	}
77
+
78
+	saveUser, err := s.dao.SaveCustomer(user)
79
+	if err != nil {
80
+		utils.LogError("保存用户信息失败", err)
81
+		return nil, err
82
+	}
83
+	return saveUser, nil
84
+}
85
+
86
+// SignUp 报名
87
+func (s *SupportServ) SignUp(customerid, name, phone, address string) (*model.TaCustomer, error) {
88
+	if customerid == "" {
89
+		return nil, errors.New("没有需要报名的用户信息")
90
+	}
91
+	customer, err := s.dao.GetCustomerByID(customerid)
92
+	if err != nil {
93
+		utils.LogError("获取用户信息失败", err)
94
+		return nil, err
95
+	}
96
+	customer.Phone = phone
97
+	customer.Name = name
98
+	customer.Address = address
99
+	err = s.dao.UpdateCustomer(customer, []string{
100
+		"name",
101
+		"phone",
102
+		"address",
103
+	})
104
+	if err != nil {
105
+		utils.LogError("报名失败:", err)
106
+		return nil, err
107
+	}
108
+	return customer, nil
109
+}
110
+
111
+// AddRecord 新增活动
112
+func (s *SupportServ) AddRecord(customerid, gameid string) (*model.TaGameRecord, error) {
113
+	game, err := s.dao.GetGameByID(gameid)
114
+	if err != nil {
115
+		utils.LogError("获取主信息信息失败", err)
116
+		return nil, err
117
+	}
118
+	if game.Status == models.STATUS_INVALID {
119
+		return nil, errors.New("活动已结束")
120
+	}
121
+	// 时间判断
122
+	if time.Now().Before(game.BeginDate) {
123
+		return nil, errors.New("活动未开始")
124
+	}
125
+	if time.Now().After(game.EndDate) {
126
+		return nil, errors.New("活动已结束")
127
+	}
128
+	todayNote, err := s.dao.GetGameNote(gameid)
129
+	if err != nil {
130
+		utils.LogError("获取活动设置信息失败:", err)
131
+		return nil, err
132
+	}
133
+	if todayNote == nil || todayNote.NotesId == "" {
134
+		utils.LogError("获取当天所有成功数据失败:", err)
135
+		return nil, errors.New("获取活动信息失败")
136
+	}
137
+	if todayNote.LeftNum <= 0 {
138
+		return nil, errors.New("今日活动已结束!请明日再来!")
139
+	}
140
+	// 判断当天是否已参与过活动
141
+	records, err := s.dao.GetTodayCustomerRecord(customerid, gameid)
142
+	if err != nil {
143
+		utils.LogError("判断当天是否参与过活动失败:", err)
144
+		return nil, err
145
+	}
146
+	if len(records) > 0 {
147
+		return nil, errors.New("您今天已参与过活动了,请明天再来吧!")
148
+	}
149
+	// 判断用户是否已成功
150
+	records, err = s.dao.GetCustomerQuota(customerid, gameid)
151
+	if err != nil {
152
+		utils.LogError("判断当天是否参与过活动失败:", err)
153
+		return nil, err
154
+	}
155
+	if len(records) > 0 {
156
+		return nil, errors.New("您已参加此次活动,请勿重复参加!")
157
+	}
158
+
159
+	var record = model.TaGameRecord{
160
+		CustomerId: customerid,
161
+		GameId:     gameid,
162
+		GameName:   game.GameName,
163
+	}
164
+
165
+	info, err := s.dao.AddRecord(record)
166
+	if err != nil {
167
+		utils.LogError("新增报名信息失败:", err)
168
+		return nil, err
169
+	}
170
+
171
+	return info, nil
172
+}
173
+
174
+// AddSupport 助力
175
+func (s *SupportServ) AddSupport(recordid, customerid string) (map[string]interface{}, error) {
176
+	// 判断活动是否已结束
177
+	record, err := s.dao.GetRecordByID(recordid)
178
+	if record.Status == models.STATUS_INVALID {
179
+		return nil, errors.New("当前活动已结束")
180
+	}
181
+	if record.Status == models.STATUS_NORMAL {
182
+		return nil, errors.New("当前活动已助力成功")
183
+	}
184
+	game, err := s.dao.GetGameByID(record.GameId)
185
+	if err != nil {
186
+		utils.LogError("获取活动信息失败:", err)
187
+		return nil, err
188
+	}
189
+	// 时间判断
190
+	if time.Now().Before(game.BeginDate) {
191
+		return nil, errors.New("活动未开始")
192
+	}
193
+	if time.Now().After(game.EndDate) {
194
+		return nil, errors.New("活动已结束")
195
+	}
196
+	// 判断用户信息
197
+	cust, err := s.dao.GetCustomerByID(customerid)
198
+	if err != nil {
199
+		utils.LogError("获取活动信息失败:", err)
200
+		return nil, err
201
+	}
202
+	if cust == nil || cust.CustomerId == "" {
203
+		return nil, errors.New("当前用户状态不正确!")
204
+	}
205
+	if cust.CustomerId == record.CustomerId {
206
+		return nil, errors.New("您不能给自己助力!")
207
+	}
208
+	// 判断是否助力过
209
+	support, err := s.dao.GetCustomerSupport(recordid, customerid)
210
+	if err != nil {
211
+		utils.LogError("获取用户助力信息失败:", err)
212
+		return nil, err
213
+	}
214
+	if len(support) > 0 {
215
+		return nil, errors.New("您已助力过此活动!")
216
+	}
217
+	// 助力
218
+	var addinfo = model.TaRecordSuppot{
219
+		RecordId:   recordid,
220
+		CustomerId: customerid,
221
+	}
222
+	info, err := s.dao.AddSupport(addinfo)
223
+	if err != nil {
224
+		utils.LogError("新增助力信息失败:", err)
225
+		return nil, err
226
+	}
227
+
228
+	supports, err := s.dao.GetSupportsByRecord(recordid)
229
+	if err != nil {
230
+		utils.LogError("获取助力信息失败:", err)
231
+		return nil, err
232
+	}
233
+	if len(supports) >= game.UserNum {
234
+		// 助力成功
235
+		record.Status = models.STATUS_NORMAL
236
+		err := s.dao.UpdateRecord(record, []string{
237
+			"status",
238
+		})
239
+		if err != nil {
240
+			utils.LogError("更新助力信息失败:", err)
241
+			return nil, err
242
+		}
243
+		// 更新当天的剩余次数
244
+		row, err := s.dao.UpdateLeftNum(record.GameId)
245
+		if err != nil {
246
+			utils.LogError("更新剩余天数失败:", err)
247
+			return nil, err
248
+		}
249
+		if row <= 0 {
250
+			return nil, errors.New("活动已结束")
251
+		}
252
+	}
253
+	return map[string]interface{}{
254
+		"record":  record,
255
+		"support": info,
256
+	}, nil
257
+}
258
+
259
+// GetRecordInfo 获取活动信息
260
+func (s *SupportServ) GetRecordInfo(recordid string) (map[string]interface{}, error) {
261
+	record, err := s.dao.GetRecordByID(recordid)
262
+	if err != nil {
263
+		utils.LogError("获取活动信息失败:", err)
264
+		return nil, err
265
+	}
266
+	supports, err := s.dao.GetSupportsByRecord(recordid)
267
+	if err != nil {
268
+		utils.LogError("获取助力信息失败:", err)
269
+		return nil, err
270
+	}
271
+	customer, err := s.dao.GetCustomerByID(record.CustomerId)
272
+	return map[string]interface{}{
273
+		"record":   record,
274
+		"supports": supports,
275
+		"customer": customer,
276
+	}, nil
277
+}
278
+
279
+// GetGameInfo 获取活动主信息
280
+func (s *SupportServ) GetGameInfo(gameid, customerid string) (map[string]interface{}, error) {
281
+	game, err := s.dao.GetGameByID(gameid)
282
+	if err != nil {
283
+		utils.LogError("获取主信息失败:", err)
284
+		return nil, err
285
+	}
286
+	note, err := s.dao.GetGameNote(gameid)
287
+	if err != nil {
288
+		utils.LogError("获取进入抽奖信息失败:", err)
289
+		return nil, err
290
+	}
291
+	// 获取用户的抽奖信息
292
+	records, err := s.dao.GetCustomerQuota(customerid, gameid)
293
+	if err != nil {
294
+		utils.LogError("获取用户抽奖信息失败:", err)
295
+		return nil, err
296
+	}
297
+	var nowRecord model.TaGameRecord
298
+	if len(records) > 0 {
299
+		nowRecord = records[0]
300
+	} else {
301
+		// 获取用户当天的抽奖信息
302
+		records, err = s.dao.GetTodayCustomerRecord(customerid, gameid)
303
+		if err != nil {
304
+			utils.LogError("获取用户当天抽奖信息失败:", err)
305
+			return nil, err
306
+		}
307
+		if len(records) > 0 {
308
+			nowRecord = records[0]
309
+		}
310
+	}
311
+
312
+	return map[string]interface{}{
313
+		"game":   game,
314
+		"note":   note,
315
+		"record": nowRecord,
316
+	}, nil
317
+}

+ 72
- 0
service/game/voting.go Näytä tiedosto

@@ -0,0 +1,72 @@
1
+package game
2
+
3
+import (
4
+	"errors"
5
+	"support-game/models/game"
6
+	"support-game/models/model"
7
+	"support-game/utils"
8
+)
9
+
10
+// VotingServ 活动serv
11
+type VotingServ struct {
12
+	ctx *utils.Context
13
+	dao *game.VotingModel
14
+}
15
+
16
+// NewVotingServ 初始化
17
+func NewVotingServ(ctx *utils.Context) *VotingServ {
18
+	return &VotingServ{
19
+		ctx: ctx,
20
+		dao: game.NewVotingModel(ctx),
21
+	}
22
+}
23
+
24
+// GetList 投票列表信息
25
+func (s *VotingServ) GetList(actID int, search string, orderby, page int) ([]game.MemInfo, error) {
26
+	list, err := s.dao.List(actID, search, orderby, page)
27
+	if err != nil {
28
+		utils.LogError("获取投票列表失败:", err)
29
+		return nil, errors.New("获取投票列表失败,请重试")
30
+	}
31
+	return list, nil
32
+}
33
+
34
+// GetActivitiesInfo 获取活动详情
35
+func (s *VotingServ) GetActivitiesInfo(actid int) (*model.TaVotingActivities, error) {
36
+	info, err := s.dao.GetActivityInfo(actid)
37
+	if err != nil {
38
+		utils.LogError("获取投票详情失败:", err)
39
+		return nil, errors.New("获取投票详情失败,请重试")
40
+	}
41
+	return info, nil
42
+}
43
+
44
+// GetMemberIndo 获取报名详情
45
+func (s *VotingServ) GetMemberInfo(actid, memberid int) (*game.MemInfo, error) {
46
+	info, err := s.dao.GetMemInfo(actid, memberid)
47
+	if err != nil {
48
+		utils.LogError("获取报名详情失败:", err)
49
+		return nil, errors.New("获取报名详情失败,请重试")
50
+	}
51
+	return info, nil
52
+}
53
+
54
+// Registe 报名
55
+func (s *VotingServ) Registe(memInfo *game.MemInfo) error {
56
+	err := s.dao.Registe(memInfo)
57
+	if err != nil {
58
+		utils.LogError("报名失败:", err)
59
+		return errors.New("操作失败,请重试")
60
+	}
61
+	return nil
62
+}
63
+
64
+// Vote 投票
65
+func (s *VotingServ) Vote(rec *model.TaVotingRecords) error {
66
+	err := s.dao.Vote(rec)
67
+	if err != nil {
68
+		utils.LogError("投票失败:", err)
69
+		return errors.New("操作失败,请重试")
70
+	}
71
+	return nil
72
+}

+ 1
- 0
service/service.go Näytä tiedosto

@@ -0,0 +1 @@
1
+package service

+ 81
- 0
utils/aliyun.go Näytä tiedosto

@@ -0,0 +1,81 @@
1
+package utils
2
+
3
+import (
4
+	"errors"
5
+	"net/http"
6
+	"strings"
7
+
8
+	"github.com/aliyun/aliyun-oss-go-sdk/oss"
9
+	"github.com/astaxie/beego"
10
+)
11
+
12
+var ossCli *oss.Client
13
+
14
+func OssInit() {
15
+	cert, err := beego.AppConfig.GetSection("alioss")
16
+	if err != nil {
17
+		LogError("读取阿里 OSS 配置失败: ", err)
18
+		return
19
+	}
20
+
21
+	OssClientSingleton(cert["Endpoint"], cert["AccessKeyId"], cert["AccessKeySecret"])
22
+}
23
+
24
+func OssClientSingleton(endpoint, accessKeyID, accessKeySecret string) {
25
+	if ossCli == nil {
26
+		var err error
27
+		ossCli, err = oss.New(endpoint, accessKeyID, accessKeySecret)
28
+		if err != nil {
29
+			LogError("初始化阿里 OSS 失败: ", err)
30
+		}
31
+	}
32
+}
33
+
34
+// GetOssClient 获取 OSS 客户端
35
+func GetOssClient() *oss.Client {
36
+	return ossCli
37
+}
38
+
39
+// UploadFileToBucket 简单上传文件
40
+func UploadFileToBucket(req *http.Request, fromFront string, nameSuffix ...string) (string, error) {
41
+	bucket := beego.AppConfig.String("alioss::Bucket")
42
+	endpoint := beego.AppConfig.String("alioss::Endpoint")
43
+
44
+	if ossCli == nil {
45
+		LogError("未成功初始化OSS 客户端")
46
+		return "", errors.New("未成功初始化OSS 客户端")
47
+	}
48
+
49
+	bkt, err := ossCli.Bucket(bucket)
50
+	if err != nil {
51
+		LogError("初始化OSS Bucket 失败: ", err)
52
+		return "", errors.New("初始化OSS Bucket 失败")
53
+	}
54
+
55
+	file, fh, err := req.FormFile(fromFront)
56
+	if err != nil {
57
+		LogError("读取文件失败: ", err)
58
+		return "", errors.New("未读取到文件或读取失败")
59
+	}
60
+	defer file.Close()
61
+
62
+	fname := fh.Filename
63
+	if len(nameSuffix) > 0 && nameSuffix[0] != "" {
64
+		fArr := strings.Split(fname, ".")
65
+		fArr[0] = fArr[0] + nameSuffix[0]
66
+		fname = strings.Join(fArr, ".")
67
+	}
68
+
69
+	err = bkt.PutObject(fname, file)
70
+	if err != nil {
71
+		LogError("上传文件到 OSS 失败: ", err)
72
+		return "", errors.New("上传文件到 OSS 失败")
73
+	}
74
+
75
+	return strings.Join([]string{
76
+		"http://",
77
+		bucket + ".",
78
+		endpoint + "/",
79
+		fname,
80
+	}, ""), nil
81
+}

+ 15
- 0
utils/configer.go Näytä tiedosto

@@ -0,0 +1,15 @@
1
+package utils
2
+
3
+import (
4
+	"github.com/astaxie/beego/config"
5
+)
6
+
7
+// GetConfiger 获取配置
8
+func GetConfiger(file string) (config.Configer, error) {
9
+	conf, err := config.NewConfig("ini", file)
10
+	if err != nil {
11
+		return nil, LogError("读取配置文件失败", err.Error())
12
+	}
13
+
14
+	return conf, nil
15
+}

+ 59
- 0
utils/context.go Näytä tiedosto

@@ -0,0 +1,59 @@
1
+package utils
2
+
3
+import (
4
+	"github.com/go-xorm/xorm"
5
+)
6
+
7
+// Context 上下文
8
+// 只限制在每次 Request 内
9
+type Context struct {
10
+	DB  *xorm.Session
11
+	box map[string]interface{}
12
+}
13
+
14
+// NewContext 初始化上下文
15
+func NewContext(engine *xorm.Engine, opt map[string]interface{}) *Context {
16
+	return &Context{
17
+		DB:  engine.NewSession(),
18
+		box: opt,
19
+	}
20
+}
21
+
22
+// Get 获取
23
+func (c *Context) Get(key string, def ...interface{}) interface{} {
24
+	if c.box != nil {
25
+		if opt, has := c.box[key]; has {
26
+			return opt
27
+		}
28
+	}
29
+
30
+	if len(def) > 0 {
31
+		return def[0]
32
+	}
33
+
34
+	return nil
35
+}
36
+
37
+// Set 设置
38
+func (c *Context) Set(key string, val interface{}) {
39
+	if c.box == nil {
40
+		c.box = make(map[string]interface{})
41
+	}
42
+
43
+	c.box[key] = val
44
+}
45
+
46
+// Ready Request 级别初始化
47
+func (c *Context) Ready() error {
48
+	// 开启事务
49
+	if err := c.DB.Begin(); err != nil {
50
+		return err
51
+	}
52
+
53
+	return nil
54
+}
55
+
56
+// Destroy 析构函数
57
+func (c *Context) Destroy() {
58
+	c.DB.Close()
59
+}

+ 10
- 0
utils/guid.go Näytä tiedosto

@@ -0,0 +1,10 @@
1
+package utils
2
+
3
+import (
4
+	"github.com/pborman/uuid"
5
+)
6
+
7
+// GetGUID 获取GUID
8
+func GetGUID() string {
9
+	return uuid.New()
10
+}

+ 105
- 0
utils/log.go Näytä tiedosto

@@ -0,0 +1,105 @@
1
+package utils
2
+
3
+import (
4
+	"errors"
5
+	"fmt"
6
+	"runtime"
7
+
8
+	"github.com/astaxie/beego/config"
9
+	"github.com/astaxie/beego/logs"
10
+)
11
+
12
+var instances = make(map[string]*logs.BeeLogger)
13
+
14
+// NewLog 构造日志对象
15
+func NewLog(tp ...string) *logs.BeeLogger {
16
+	logType := "common"
17
+	if len(tp) > 0 {
18
+		if tp[0] != "" {
19
+			logType = tp[0]
20
+		}
21
+	}
22
+
23
+	if v, ok := instances[logType]; ok {
24
+		return v
25
+	}
26
+
27
+	log := logs.NewLogger()
28
+	instances[logType] = log
29
+
30
+	// 读取配置文件
31
+	conf, err := config.NewConfig("ini", GetAppRoot()+"/conf/log.conf")
32
+	if err != nil {
33
+		log.SetLogger(logs.AdapterConsole)
34
+		return log
35
+	}
36
+
37
+	// 读文件存储位置
38
+	filename := conf.String(logType + "::filename")
39
+	// 输出级别
40
+	level := conf.String(logType + "::level")
41
+	if level == "" {
42
+		level = "error"
43
+	}
44
+
45
+	if filename == "" {
46
+		filename = "./" + logType + ".log"
47
+	}
48
+
49
+	log.Async()
50
+	log.SetLogger(logs.AdapterFile, `{"filename":"`+filename+`"}`)
51
+	return log
52
+}
53
+
54
+// LogError 错误日志
55
+func LogError(v ...interface{}) error {
56
+	log := instances["common"]
57
+
58
+	preMsg := ""
59
+	_, file, line, ok := runtime.Caller(1)
60
+	if ok {
61
+		preMsg = fmt.Sprintf("file: %s    line=%d : ", file, line)
62
+	}
63
+
64
+	log.Error(preMsg, v...)
65
+
66
+	if len(v) > 0 {
67
+		firstV := v[0]
68
+
69
+		switch err := firstV.(type) {
70
+		case string:
71
+			return errors.New(err)
72
+		case error:
73
+			return err
74
+		default:
75
+			msg := "Unknown error type"
76
+			return errors.New(msg)
77
+		}
78
+	}
79
+
80
+	return nil
81
+}
82
+
83
+// LogInfo Info 日志
84
+func LogInfo(v ...interface{}) {
85
+	log := instances["common"]
86
+
87
+	preMsg := ""
88
+	_, file, line, ok := runtime.Caller(1)
89
+	if ok {
90
+		preMsg = fmt.Sprintf("file: %s    line=%d : ", file, line)
91
+	}
92
+
93
+	log.Info(preMsg, v...)
94
+}
95
+
96
+// GetDefaultLogger 获取默认 logger
97
+func GetDefaultLogger() *logs.BeeLogger {
98
+	log := instances["common"]
99
+	log.SetLogFuncCallDepth(4)
100
+	return log
101
+}
102
+
103
+func LogInit() {
104
+	NewLog()
105
+}

+ 194
- 0
utils/utils.go Näytä tiedosto

@@ -0,0 +1,194 @@
1
+package utils
2
+
3
+import (
4
+	"encoding/base64"
5
+	"math/rand"
6
+	"net/http"
7
+	"os"
8
+	"path/filepath"
9
+	"runtime"
10
+	"strconv"
11
+	"strings"
12
+	"time"
13
+)
14
+
15
+// 客户端类型
16
+const (
17
+	ClientAdmin  = "client-admin"
18
+	ClientWechat = "client-wechat"
19
+	ClientMini   = "client-mini"
20
+)
21
+
22
+// 一些 UA 列表
23
+const (
24
+	UAWechat      = "micromessenger"
25
+	UAMiniProgram = "miniprogram"
26
+)
27
+
28
+// GetClientType 获取客户端类型
29
+// 默认返回是 管理端
30
+func GetClientType(r *http.Request) string {
31
+	ua := strings.ToLower(r.Header.Get("User-Agent"))
32
+
33
+	if strings.Index(ua, UAWechat) > -1 {
34
+		// if strings.Index(ua, UAMiniProgram) > -1 {
35
+		// 	return ClientMini
36
+		// }
37
+
38
+		return ClientWechat
39
+	}
40
+
41
+	return ClientAdmin
42
+}
43
+
44
+// StrSliceIndexOf slice indexof
45
+func StrSliceIndexOf(s []string, t string) int64 {
46
+	if s == nil || len(s) == 0 {
47
+		return -1
48
+	}
49
+
50
+	for k, v := range s {
51
+		if v == t {
52
+			return int64(k)
53
+		}
54
+	}
55
+
56
+	return -1
57
+}
58
+
59
+// GUIID2IntString guid 转 int 字符串
60
+func GUIID2IntString(id string) []string {
61
+	if id == "" {
62
+		return nil
63
+	}
64
+
65
+	res := make([]string, 0)
66
+	for _, part := range strings.Split(id, "-") {
67
+		sum := 0
68
+		for _, r := range []rune(part) {
69
+			sum += int(r)
70
+		}
71
+
72
+		res = append(res, strconv.Itoa(sum))
73
+	}
74
+
75
+	return res
76
+}
77
+
78
+// EncodeBase64TrimTail base64 加密, 去除末尾 =
79
+func EncodeBase64TrimTail(src string) string {
80
+	if src == "" {
81
+		return ""
82
+	}
83
+
84
+	enStr := base64.StdEncoding.EncodeToString([]byte(src))
85
+
86
+	return strings.TrimRight(enStr, "=")
87
+}
88
+
89
+// DecodeBase64NoTail base64解密, 位数不够的, 自动补全
90
+func DecodeBase64NoTail(src string) string {
91
+	if src == "" {
92
+		return ""
93
+	}
94
+
95
+	pd := 4 - len(src)%4
96
+	if pd > 0 && pd != 4 {
97
+		src += strings.Repeat("=", pd)
98
+	}
99
+
100
+	res, err := base64.StdEncoding.DecodeString(src)
101
+	if err != nil {
102
+		LogError("解密 Base64 字串失败: " + err.Error())
103
+		return ""
104
+	}
105
+
106
+	return string(res)
107
+}
108
+
109
+// GetPageNaviLimit 获取 mysql limit 限定
110
+func GetPageNaviLimit(params ...int) []int {
111
+	page := 1
112
+	pagesize := 10
113
+
114
+	if params != nil {
115
+		pl := len(params)
116
+
117
+		if pl > 0 {
118
+			page = params[0]
119
+			if page < 1 {
120
+				page = 1
121
+			}
122
+		}
123
+
124
+		if pl > 1 {
125
+			pagesize = params[1]
126
+		}
127
+	}
128
+
129
+	return []int{
130
+		pagesize,
131
+		(page - 1) * pagesize,
132
+	}
133
+}
134
+
135
+// GenerateQRCode 生成二维码数字
136
+func GenerateQRCode() string {
137
+	var temp1 int = rand.Intn(9)*87 + 11
138
+	var temp2 int = rand.Intn(9)*89 + 13
139
+	nano := time.Now().UnixNano()
140
+	var nanostr string = strconv.FormatInt(nano, 10)
141
+	var temp3 string = nanostr[11:]
142
+	var temp4 string = "6"
143
+	var temp5 int = rand.Intn(9)*7 + 17
144
+	var code string = "66" + strconv.Itoa(temp1) + temp4 + strconv.Itoa(temp2) + temp3 + strconv.Itoa(temp5)
145
+	return code
146
+}
147
+
148
+// GetFiveSeconds 获取 5 秒钟的时间
149
+func GetFiveSeconds(t time.Time) string {
150
+	str := t.Format("20060102150405")
151
+	strLen := len(str)
152
+
153
+	lastNum, _ := strconv.Atoi(str[strLen-1:])
154
+	if lastNum < 5 {
155
+		lastNum = 0
156
+	} else {
157
+		lastNum = 5
158
+	}
159
+
160
+	return str[:strLen-1] + strconv.Itoa(lastNum)
161
+}
162
+
163
+// 当前运行环境
164
+var processEnv string
165
+var appRoot string
166
+
167
+// GetAppRoot 获取系统根目录
168
+func GetAppRoot() string {
169
+	if appRoot != "" {
170
+		return appRoot
171
+	}
172
+
173
+	if processEnv == "" {
174
+		for _, arg := range os.Args {
175
+			if strings.Index(arg, "-test.run") > -1 {
176
+				processEnv = "test"
177
+				break
178
+			}
179
+		}
180
+
181
+		if processEnv == "" {
182
+			processEnv = "production"
183
+		}
184
+	}
185
+
186
+	if processEnv == "test" {
187
+		_, file, _, _ := runtime.Caller(1)
188
+		appRoot, _ = filepath.Abs(filepath.Dir(filepath.Join(file, ".."+string(filepath.Separator))))
189
+	} else {
190
+		appRoot, _ = filepath.Abs(filepath.Dir(os.Args[0]))
191
+	}
192
+
193
+	return appRoot
194
+}

+ 37
- 0
utils/wechat.go Näytä tiedosto

@@ -0,0 +1,37 @@
1
+package utils
2
+
3
+import (
4
+	"github.com/astaxie/beego"
5
+	"github.com/zjxpcyc/wechat/wx"
6
+)
7
+
8
+var client *wx.Client
9
+
10
+// WxClientSingleton 初始化
11
+func WxClientSingleton(cert map[string]string) {
12
+	client = wx.NewClient(cert)
13
+}
14
+
15
+// WxClient 微信实例
16
+func WxClient() *wx.Client {
17
+	return client
18
+}
19
+
20
+// 初始化微信
21
+func InitWechat() {
22
+	appRoot := GetAppRoot()
23
+
24
+	wechatConf, _ := GetConfiger(appRoot + "/conf/wechat.conf")
25
+	if wechatConf == nil {
26
+		return
27
+	}
28
+	cert := map[string]string{
29
+		"appid":  wechatConf.String("appid"),
30
+		"secret": wechatConf.String("secret"),
31
+		"token":  wechatConf.String("token"),
32
+		"aeskey": "",
33
+		"wxid":   wechatConf.String("wxid"),
34
+	}
35
+	beego.Error(cert)
36
+	WxClientSingleton(cert)
37
+}