浏览代码

新增兑换码

huangyuhao 1 年之前
父节点
当前提交
82e51cb837
共有 10 个文件被更改,包括 835 次插入122 次删除
  1. 2 2
      conf/neo/cfg_test.conf
  2. 5 0
      controllers/default.go
  3. 123 0
      controllers/exchangecode.go
  4. 28 10
      main.go
  5. 190 0
      models/exchangecode.go
  6. 111 0
      models/item.go
  7. 2 1
      routers/router.go
  8. 2 2
      run.sh
  9. 0 107
      views/base.ace
  10. 372 0
      views/exchangecode.tpl

+ 2 - 2
conf/neo/cfg_test.conf

@@ -10,8 +10,8 @@ days_event=300
10 10
 count=1
11 11
 host_0=127.0.0.1
12 12
 port_0=6381
13
-auth_0=aGMtbmVvLWRldi0yMDIzMDQwNw==
13
+auth_0=mCWJVNNBP7_jiami
14 14
 
15 15
 host_account=127.0.0.1
16 16
 port_account=6381
17
-auth_account=aGMtbmVvLWRldi0yMDIzMDQwNw==
17
+auth_account=mCWJVNNBP7_jiami

+ 5 - 0
controllers/default.go

@@ -144,6 +144,11 @@ func getIndex(permission int64) []*NavInfo {
144 144
 			Name: "版本更新",
145 145
 			Url:  "hotfix.html",
146 146
 		})
147
+		navInfo.IndexList = append(navInfo.IndexList, &IndexInfo{
148
+			Id:   models.ModelSystem,
149
+			Name: "兑换码",
150
+			Url:  "exchangecode.html",
151
+		})
147 152
 
148 153
 		navList = append(navList, navInfo)
149 154
 	}

+ 123 - 0
controllers/exchangecode.go

@@ -0,0 +1,123 @@
1
+// 实时数据
2
+package controllers
3
+
4
+import (
5
+	"box-gm/models"
6
+	"box-gm/utils"
7
+	"encoding/json"
8
+	"log"
9
+
10
+	"github.com/astaxie/beego"
11
+)
12
+
13
+type ExchangeCodeController struct {
14
+	beego.Controller
15
+}
16
+
17
+func (c *ExchangeCodeController) Get() {
18
+	userinfo := c.GetSession("user")
19
+	if userinfo == nil {
20
+		c.Ctx.Redirect(302, "/accountlogin")
21
+		return
22
+	}
23
+	c.Data["username"] = userinfo.(*LoginInfo).Username
24
+	c.Data["token"] = models.GetToken()
25
+	userPermission := models.GetPermission(userinfo.(*LoginInfo).Username)
26
+	if (userPermission & (1 << uint(models.ModelSystem))) == 0 {
27
+		c.Ctx.Redirect(302, "/accountlogin")
28
+		return
29
+	}
30
+
31
+	c.Data["ItemList"] = models.GetItemInfoList()
32
+	c.Data["infoList"] = models.GetExchangeCodeInfo()
33
+	c.TplName = "exchangecode.tpl"
34
+}
35
+
36
+func (c *ExchangeCodeController) Post() {
37
+	userinfo := c.GetSession("user")
38
+	log.Printf("ExchangeCodeController Post userinfo[%v]", userinfo)
39
+	if userinfo == nil {
40
+		c.Ctx.Redirect(302, "/accountlogin")
41
+		return
42
+	}
43
+	pcode := c.GetString("pcode")
44
+	log.Printf("ExchangeCodeController Post pcode[%s]", pcode)
45
+	hf := models.GetExchangeCodeInfoByCode(pcode)
46
+	if hf != nil {
47
+		c.Data["json"] = &map[string]interface{}{"status": false, "info": "新增失败:渠道已配置"}
48
+		c.ServeJSON()
49
+		return
50
+	}
51
+	awardTimes, _ := c.GetInt64("awardTimes")
52
+	expireTime := c.GetString("expireTime")
53
+	items := c.GetString("items")
54
+
55
+	u := new(models.ExchangeCodeInfo)
56
+	u.Pcode = pcode
57
+	u.AwardTimes = awardTimes
58
+	u.ExpireTime = utils.GetTime64(expireTime)
59
+	var eItems []*models.ExchangeItemsInfo
60
+	err := json.Unmarshal([]byte(items), &eItems)
61
+	if err != nil {
62
+		log.Printf("ExchangeCodeController items[%s] err[%v]", items, err)
63
+		c.Data["json"] = &map[string]interface{}{"status": false, "info": err.Error()}
64
+		c.ServeJSON()
65
+		return
66
+	}
67
+	u.Items = eItems
68
+
69
+	err = models.AddExchangeCodeInfo(u)
70
+	if err != nil {
71
+		c.Data["json"] = &map[string]interface{}{"status": false, "info": err.Error()}
72
+		c.ServeJSON()
73
+		return
74
+	}
75
+
76
+	c.Data["json"] = &map[string]interface{}{"status": true, "info": "新增兑换码成功"}
77
+	c.ServeJSON()
78
+}
79
+
80
+func (c *ExchangeCodeController) Put() {
81
+	userinfo := c.GetSession("user")
82
+	if userinfo == nil {
83
+		c.Ctx.Redirect(302, "/accountlogin")
84
+		return
85
+	}
86
+
87
+	u := new(models.HotfixInfo)
88
+	u.Id, _ = c.GetInt64("id")
89
+	u.Channel, _ = c.GetInt64("channel")
90
+	u.Version = c.GetString("version")
91
+	u.DowloadAddr = c.GetString("addr")
92
+	u.FileSize = c.GetString("filesize")
93
+
94
+	_, err := models.UpdateHotfixInfo(u)
95
+	if err != nil {
96
+		c.Data["json"] = &map[string]interface{}{"status": false, "info": err}
97
+		c.ServeJSON()
98
+		return
99
+	}
100
+	c.Data["json"] = &map[string]interface{}{"status": true, "info": "更新热更新参数成功"}
101
+	c.ServeJSON()
102
+}
103
+
104
+func (c *ExchangeCodeController) Delete() {
105
+	userinfo := c.GetSession("user")
106
+	if userinfo == nil {
107
+		c.Ctx.Redirect(302, "/accountlogin")
108
+		return
109
+	}
110
+
111
+	id, _ := c.GetInt64("id")
112
+	cp := models.GetHotfixInfoById(id)
113
+	if cp == nil {
114
+		c.Data["json"] = &map[string]interface{}{"status": false, "info": "参数不存在"}
115
+		c.ServeJSON()
116
+		return
117
+	}
118
+
119
+	models.DelHotfixInfoById(id)
120
+
121
+	c.Data["json"] = &map[string]interface{}{"status": true, "info": "删除热更新参成功"}
122
+	c.ServeJSON()
123
+}

+ 28 - 10
main.go

@@ -1,17 +1,20 @@
1
-
2 1
 package main
3 2
 
4 3
 import (
5
-	"github.com/astaxie/beego"
6 4
 	"box-gm/utils"
5
+	"fmt"
6
+
7
+	"github.com/astaxie/beego"
8
+
7 9
 	// "github.com/drone/routes"
8
-	_ "box-gm/routers"
9 10
 	"box-gm/backup"
10
-	"os"
11
+	"box-gm/models"
12
+	_ "box-gm/routers"
13
+	"database/sql"
11 14
 	"log"
15
+	"os"
12 16
 	"time"
13
-	"database/sql"
14
-	"box-gm/models"
17
+
15 18
 	"github.com/astaxie/beego/orm"
16 19
 	_ "github.com/go-sql-driver/mysql"
17 20
 	_ "github.com/mattn/go-sqlite3"
@@ -37,6 +40,7 @@ func GetSelectStatus(id1 int64, id2 int64) string {
37 40
 	}
38 41
 	return ""
39 42
 }
43
+
40 44
 // 服务器状态
41 45
 func ServerStatus(s int) string {
42 46
 	if s == 1 {
@@ -90,6 +94,18 @@ func TimeCmdOperateStatus(s int) string {
90 94
 	return ""
91 95
 }
92 96
 
97
+// 权重物品列表
98
+func WeightItems(items []*models.ExchangeItemsInfo) string {
99
+	cnt := ""
100
+	for _, v := range items {
101
+		if cnt != "" {
102
+			cnt += "|"
103
+		}
104
+		cnt += fmt.Sprintf("%s%d,权重:%d", models.GetItemName(v.ItemId), v.Count, v.Weight)
105
+	}
106
+	return cnt
107
+}
108
+
93 109
 // 初始化beego fun
94 110
 func initBeegoFunMap() {
95 111
 	beego.AddFuncMap("TimeToStr", TimeToStr)
@@ -99,6 +115,7 @@ func initBeegoFunMap() {
99 115
 	beego.AddFuncMap("GetRoleNameById", GetRoleNameById)
100 116
 	beego.AddFuncMap("TimeCmdOperate", TimeCmdOperate)
101 117
 	beego.AddFuncMap("TimeCmdOperateStatus", TimeCmdOperateStatus)
118
+	beego.AddFuncMap("WeightItems", WeightItems)
102 119
 }
103 120
 
104 121
 func main() {
@@ -114,7 +131,7 @@ func main() {
114 131
 	}
115 132
 	utils.InitProject()
116 133
 	utils.InitRedis()
117
-	
134
+
118 135
 	// 注册sqlite
119 136
 	orm.RegisterDriver("sqlite3", orm.DRSqlite)
120 137
 	orm.RegisterDataBase("default", "sqlite3", dsn)
@@ -125,7 +142,8 @@ func main() {
125 142
 	// 初始化数据
126 143
 	models.InitHotfixInfo()
127 144
 	models.InitBanIPInfo()
128
-	
145
+	models.InitExchangeCodeInfo()
146
+
129 147
 	//模板初始化
130 148
 	initBeegoFunMap()
131 149
 
@@ -157,7 +175,7 @@ func initDb() {
157 175
 	orm.RunSyncdb("admin", true, true)
158 176
 
159 177
 	u := new(models.User)
160
-	u.Username = "hc"
178
+	u.Username = "admin"
161 179
 	u.Role = 1
162 180
 	u.Password = utils.Strtomd5("000000")
163 181
 	u.CreateTs = time.Now().Unix()
@@ -183,4 +201,4 @@ func patchDb() {
183 201
 	// o := orm.NewOrm()
184 202
 	// o.Insert(&models.SystemParameter{Key: "test_server", Value: ""})
185 203
 	// o.Insert(&models.SystemParameter{Key: "game_server", Value: ""})
186
-}
204
+}

+ 190 - 0
models/exchangecode.go

@@ -0,0 +1,190 @@
1
+package models
2
+
3
+// 兑换码
4
+import (
5
+	"box-gm/utils"
6
+	"encoding/json"
7
+	"errors"
8
+	"fmt"
9
+	"log"
10
+	"sync"
11
+	"time"
12
+
13
+	"github.com/astaxie/beego"
14
+	"github.com/astaxie/beego/validation"
15
+	"github.com/garyburd/redigo/redis"
16
+)
17
+
18
+type ExchangeItemsInfo struct {
19
+	ItemId int `json:"id"`     // 道具ID
20
+	Count  int `json:"count"`  // 数量
21
+	Weight int `json:"weight"` // 权重
22
+}
23
+type ExchangeCodeInfo struct {
24
+	Pcode      string               `json:"pcode"`      // 兑换码
25
+	AwardTimes int64                `json:"awardTimes"` // 领奖次数
26
+	CreateTime int64                `json:"creatTime"`  // 创建时间
27
+	ModifyTime int64                `json:"modifyTime"` // 修改时间
28
+	ExpireTime int64                `json:"expireTime"` // 过期时间
29
+	Items      []*ExchangeItemsInfo `json:"items"`      // 随机奖励列表
30
+
31
+}
32
+
33
+type ExchangeCodeInfoArray []*ExchangeCodeInfo
34
+
35
+var exchangeCodeList ExchangeCodeInfoArray
36
+var ecMutex sync.Mutex
37
+var MAIN_KEY = "exchange:code"
38
+
39
+// 初始化兑换码
40
+func InitExchangeCodeInfo() {
41
+	pool := utils.GetAccountRedisPool()
42
+	if pool == nil {
43
+		fmt.Println("get redis pool fail")
44
+		return
45
+	}
46
+	rd := pool.Get()
47
+	defer rd.Close()
48
+
49
+	result, err := redis.Values(rd.Do("hgetall", MAIN_KEY))
50
+	if err != nil {
51
+		return
52
+	}
53
+	for i := 0; i < len(result)/2; i++ {
54
+
55
+		info := &ExchangeCodeInfo{}
56
+		_err := json.Unmarshal(result[i*2+1].([]byte), info)
57
+		if _err == nil {
58
+			exchangeCodeList = append(exchangeCodeList, info)
59
+		}
60
+	}
61
+
62
+	beego.Info("load exchange code info", len(exchangeCodeList))
63
+}
64
+
65
+func checkExchangeCodeInfo(hf *ExchangeCodeInfo) (err error) {
66
+	valid := validation.Validation{}
67
+	b, _ := valid.Valid(&hf)
68
+	if !b {
69
+		for _, err := range valid.Errors {
70
+			log.Println(err.Key, err.Message)
71
+			return errors.New(err.Message)
72
+		}
73
+	}
74
+	return nil
75
+}
76
+
77
+// 新增兑换码
78
+func AddExchangeCodeInfo(hf *ExchangeCodeInfo) error {
79
+	pool := utils.GetAccountRedisPool()
80
+	if pool == nil {
81
+		return fmt.Errorf("get redis pool fail")
82
+	}
83
+	rd := pool.Get()
84
+	defer rd.Close()
85
+
86
+	if err := checkExchangeCodeInfo(hf); err != nil {
87
+		return err
88
+	}
89
+
90
+	hf.CreateTime = time.Now().Unix()
91
+	hf.ModifyTime = hf.CreateTime
92
+
93
+	buff, err := json.Marshal(hf)
94
+	_, err = rd.Do("hset", MAIN_KEY, hf.Pcode, buff)
95
+
96
+	if err == nil {
97
+		ecMutex.Lock()
98
+		exchangeCodeList = append(exchangeCodeList, hf)
99
+		ecMutex.Unlock()
100
+	}
101
+
102
+	return err
103
+}
104
+
105
+// 修改兑换码
106
+func UpdateExchangeCodeInfo(hf *ExchangeCodeInfo) error {
107
+	pool := utils.GetAccountRedisPool()
108
+	if pool == nil {
109
+		return fmt.Errorf("get redis pool fail")
110
+	}
111
+	rd := pool.Get()
112
+	defer rd.Close()
113
+
114
+	if err := checkExchangeCodeInfo(hf); err != nil {
115
+		return err
116
+	}
117
+
118
+	hf.ModifyTime = time.Now().Unix()
119
+
120
+	buff, err := json.Marshal(hf)
121
+	_, err = rd.Do("hset", MAIN_KEY, hf.Pcode, buff)
122
+	if err != nil {
123
+		return err
124
+	}
125
+
126
+	ecMutex.Lock()
127
+	for i := 0; i < len(exchangeCodeList); i++ {
128
+		if hf.Pcode == exchangeCodeList[i].Pcode {
129
+			old := exchangeCodeList[i]
130
+
131
+			old.AwardTimes = hf.AwardTimes
132
+			old.ModifyTime = hf.ModifyTime
133
+			old.ExpireTime = hf.ExpireTime
134
+			old.Items = hf.Items
135
+			break
136
+		}
137
+	}
138
+	ecMutex.Unlock()
139
+
140
+	return err
141
+
142
+}
143
+
144
+// 删除兑换码
145
+func DelExchangeCodeInfoById(pcode string) error {
146
+	pool := utils.GetAccountRedisPool()
147
+	if pool == nil {
148
+		return fmt.Errorf("get redis pool fail")
149
+	}
150
+	rd := pool.Get()
151
+	defer rd.Close()
152
+
153
+	ecMutex.Lock()
154
+	defer ecMutex.Unlock()
155
+
156
+	_, err := rd.Do("hdel", MAIN_KEY, pcode)
157
+	if err != nil {
158
+		log.Println(err)
159
+		return err
160
+	}
161
+
162
+	for i := 0; i < len(exchangeCodeList); i++ {
163
+		if pcode == exchangeCodeList[i].Pcode {
164
+			ii := i + 1
165
+			exchangeCodeList = append(exchangeCodeList[:i], exchangeCodeList[ii:]...)
166
+		}
167
+	}
168
+
169
+	return nil
170
+}
171
+
172
+// 获取兑换码信息
173
+func GetExchangeCodeInfoByCode(pcode string) (hf *ExchangeCodeInfo) {
174
+	ecMutex.Lock()
175
+	defer ecMutex.Unlock()
176
+
177
+	for i := 0; i < len(exchangeCodeList); i++ {
178
+		if pcode == exchangeCodeList[i].Pcode {
179
+			return exchangeCodeList[i]
180
+		}
181
+	}
182
+
183
+	return nil
184
+}
185
+func GetExchangeCodeInfo() ExchangeCodeInfoArray {
186
+	ecMutex.Lock()
187
+	defer ecMutex.Unlock()
188
+
189
+	return exchangeCodeList
190
+}

+ 111 - 0
models/item.go

@@ -0,0 +1,111 @@
1
+/*
2
+ * @Descripttion:
3
+ * @version:
4
+ * @Author: Neo,Huang
5
+ * @Date: 2023-11-18 22:52:59
6
+ * @LastEditors: Neo,Huang
7
+ * @LastEditTime: 2023-11-19 16:04:30
8
+ */
9
+package models
10
+
11
+import (
12
+	"github.com/astaxie/beego"
13
+	"github.com/bitly/go-simplejson"
14
+
15
+	"box-gm/utils"
16
+)
17
+
18
+type ItemConfig struct {
19
+	Id   int
20
+	Name string
21
+	Type int
22
+}
23
+
24
+type ItemConfigs []*ItemConfig
25
+
26
+var itemConfigMap map[int]*ItemConfig
27
+var itemConfigs ItemConfigs
28
+
29
+func init() {
30
+	itemConfigMap = make(map[int]*ItemConfig)
31
+
32
+	itemConfigMap[101] = &ItemConfig{
33
+		Id:   101,
34
+		Name: "金币",
35
+		Type: 1,
36
+	}
37
+	itemConfigMap[102] = &ItemConfig{
38
+		Id:   102,
39
+		Name: "绑金",
40
+		Type: 1,
41
+	}
42
+	itemConfigMap[103] = &ItemConfig{
43
+		Id:   103,
44
+		Name: "N1",
45
+		Type: 1,
46
+	}
47
+	itemConfigs = append(itemConfigs, itemConfigMap[101])
48
+	itemConfigs = append(itemConfigs, itemConfigMap[102])
49
+	itemConfigs = append(itemConfigs, itemConfigMap[103])
50
+}
51
+
52
+func InitItemConfig() (int, int) {
53
+	body := "{\"name\":\"user_query_item_config\"}"
54
+	host := utils.GetKeyConf("gameservers", "login")
55
+	sign := utils.Strtomd5(body + utils.GetKeyConf("app", "gameKey"))
56
+	url := "http://" + host + "/json?sign=" + sign
57
+	buff, err := utils.SendAndRecvHTTP("POST", url, body)
58
+	if err != nil {
59
+		return 0, 0
60
+	}
61
+
62
+	j, err := simplejson.NewJson(buff)
63
+	if err != nil {
64
+		return 0, 0
65
+	}
66
+	code, _ := j.Get("code").Int()
67
+	if code != 200 {
68
+		return 0, 0
69
+	}
70
+	arr, err1 := j.Get("config").Array()
71
+	if err1 != nil {
72
+		return 0, 0
73
+	}
74
+
75
+	oldCount := len(itemConfigs)
76
+
77
+	for i := 0; i < len(arr); i++ {
78
+		itype, _ := j.Get("config").GetIndex(i).Get("type").Int()
79
+		id, _ := j.Get("config").GetIndex(i).Get("id").Int()
80
+		//话费卡和红包不允许后台发放
81
+		// if realItem == "0" && (itype == 100 || itype == 73) {
82
+		// 	continue
83
+		// }
84
+
85
+		item := &ItemConfig{}
86
+		item.Id = id
87
+		item.Type = itype
88
+		item.Name, _ = j.Get("config").GetIndex(i).Get("name").String()
89
+		if itemConfigMap[item.Id] == nil {
90
+			itemConfigMap[item.Id] = item
91
+			itemConfigs = append(itemConfigs, item)
92
+		}
93
+	}
94
+
95
+	beego.Info("load item config, oldCount: ", oldCount, "newCount", len(itemConfigs))
96
+	return oldCount, len(itemConfigs)
97
+}
98
+
99
+func GetItemName(id int) string {
100
+	item, ok := itemConfigMap[id]
101
+	if !ok {
102
+		return ""
103
+	}
104
+	return item.Name
105
+}
106
+
107
+// 获取物品列表
108
+func GetItemInfoList() ItemConfigs {
109
+	// InitItemConfig()
110
+	return itemConfigs
111
+}

+ 2 - 1
routers/router.go

@@ -4,7 +4,7 @@
4 4
  * @Author: Neo,Huang
5 5
  * @Date: 2022-02-08 15:14:13
6 6
  * @LastEditors: Neo,Huang
7
- * @LastEditTime: 2022-03-24 11:23:51
7
+ * @LastEditTime: 2023-11-19 00:54:28
8 8
  */
9 9
 package routers
10 10
 
@@ -58,4 +58,5 @@ func init() {
58 58
 	beego.Router("/version", &controllers.VersionController{})
59 59
 	beego.Router("/client", &controllers.ClientController{})
60 60
 	beego.Router("/banip", &controllers.BanIPController{})
61
+	beego.Router("/exchangecode", &controllers.ExchangeCodeController{})
61 62
 }

+ 2 - 2
run.sh

@@ -3,8 +3,8 @@
3 3
 # @version:
4 4
 # @Author: Neo,Huang
5 5
 # @Date: 2020-11-06 09:53:23
6
-# @LastEditors: Neo,Huang
7
-# @LastEditTime: 2022-01-17 16:43:28
6
+ # @LastEditors: Neo,Huang
7
+ # @LastEditTime: 2023-11-18 22:15:29
8 8
 ###
9 9
 #!/bin/bash
10 10
 

+ 0 - 107
views/base.ace

@@ -1,107 +0,0 @@
1
-= doctype html
2
-html lang=en
3
-  head
4
-    meta charset=utf-8
5
-    title {{.title}}
6
-
7
-    link rel="stylesheet" href="static/css/bootstrap.css"
8
-    link rel="stylesheet" href="static/css/magic-check.css"
9
-    link rel="stylesheet" href="static/css/site.css"
10
-    link rel="stylesheet" href="static/css/bootstrap-responsive.css"
11
-    link rel="stylesheet" href="static/css/bootstrap-datetimepicker.min.css"
12
-
13
-    style type="text/css"
14
-    = css
15
-      html, body {
16
-        height: 100%;
17
-      }
18
-    = yield head
19
-  body
20
-    div.navbar.navbar-fixed-top
21
-      div.navbar-inner
22
-        div.container-fluid
23
-          a.brand href=index {{.title}}
24
-          div.btn-group.pull-right
25
-            a.btn href=index
26
-              i.icon-user
27
-              {{.username}}
28
-            a.btn.dropdown-toggle data-toggle=dropdown href=index
29
-              span.caret
30
-            ul.dropdown-menu
31
-              li
32
-                a href=modify_password 修改密码
33
-              li
34
-                a href=logout 退出
35
-    div.container-fluid
36
-      div.row-fluid
37
-        div.span2
38
-          div.well.sidebar-nav
39
-            ul.nav.nav-list
40
-              {{if .system_mgr}}
41
-              li.nav-header
42
-                i.icon-wrench
43
-                {{"【系统管理】"}}
44
-              {{end}}
45
-              {{range .system_mgr}}
46
-              li id=li{{.Id}}
47
-                a href={{.Url}} {{.Name}}
48
-              {{end}}
49
-            ul.nav.nav-list
50
-              {{if .player_mgr}}
51
-              li.nav-header
52
-                i.icon-user
53
-                {{"【游戏管理】玩家管理"}}
54
-              {{end}}
55
-              {{range .player_mgr}}
56
-              li id=li{{.Id}}
57
-                a href={{.Url}} {{.Name}}
58
-              {{end}}
59
-            ul.nav.nav-list
60
-              {{if .update_mgr}}
61
-              li.nav-header
62
-                i.icon-fire
63
-                {{"【开关管理】更新管理"}}
64
-              {{end}}
65
-              {{range .update_mgr}}
66
-              li id=li{{.Id}}
67
-                a href={{.Url}} {{.Name}}
68
-              {{end}}
69
-            ul.nav.nav-list
70
-              {{if .parameter_mgr}}
71
-              li.nav-header
72
-                i.icon-wrench
73
-                {{"【开关管理】在线参数"}}
74
-              {{end}}
75
-              {{range .parameter_mgr}}
76
-              li id=li{{.Id}}
77
-                a href={{.Url}} {{.Name}}
78
-              {{end}}
79
-            ul.nav.nav-list
80
-              {{if .acticity_mgr}}
81
-              li.nav-header
82
-                i.icon-star
83
-                {{"【游戏管理】运营管理"}}
84
-              {{end}}
85
-              {{range .acticity_mgr}}
86
-              li id=li{{.Id}}
87
-                a href={{.Url}} {{.Name}}
88
-              {{end}}
89
-            ul.nav.nav-list
90
-              {{if .push_mgr}}
91
-              li.nav-header
92
-                i.icon-star
93
-                {{"【其它管理】推送管理"}}
94
-              {{end}}
95
-              {{range .push_mgr}}
96
-              li id=li{{.Id}}
97
-                a href={{.Url}} {{.Name}}
98
-              {{end}}
99
-        div.span10
100
-          div.row-fluid
101
-            = yield index
102
-    script src="static/js/jquery.js"
103
-    script src="static/js/jquery.flot.js"
104
-    script src="static/js/jquery.flot.resize.js"
105
-    script src="static/js/bootstrap.min.js"
106
-    script src="static/js/bootstrap-datetimepicker.js"
107
-    script src="static/js/locales/bootstrap-datetimepicker.zh-CN.js"

+ 372 - 0
views/exchangecode.tpl

@@ -0,0 +1,372 @@
1
+<!DOCTYPE html>
2
+<html>
3
+    <head>
4
+        <meta charset="UTF-8" />
5
+        <title>欢迎页面-X-admin2.0</title>
6
+        <link rel="stylesheet" href="./static/css/font.css">
7
+        <link rel="stylesheet" href="./static/css/xadmin.css">
8
+        <script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
9
+        <script src="./static/lib/layui/layui.js" charset="utf-8"></script>
10
+        <script type="text/javascript" src="./static/js/xadmin.js"></script>
11
+    </head>
12
+    <body>
13
+    <input type="text" id="token" value={{.token}} hidden=true>
14
+
15
+    <dialog open id="modalAdd" class="x-body layui-anim layui-anim-up" hidden=true style = "center;">
16
+        <form action="exchangecode" method="post" class="layui-form layui-form-pane">
17
+            <input id="pcode" name="pcode" placeholder="兑换码"  type="text" lay-verify="required" class="layui-input" disabled="disabled">
18
+            <br>
19
+            <input class="layui-btn" type="button" onclick="randCode()" value=随机>
20
+            <hr class="hr15">
21
+            可领次数
22
+            <input id="awardTimes" name="awardTimes" placeholder="剩余领奖次数"  type="text" lay-verify="required" class="layui-input">
23
+            <br>
24
+            过期时间
25
+            <input id="expireTime" name="expireTime" placeholder="过期时间"  type="text" lay-verify="required" class="layui-input">
26
+            <br>
27
+            随机物品列表
28
+            <br>
29
+            <hr class="hr15">
30
+            <table class="radio-table" border="1" id="tb_item">
31
+              <thead>
32
+                <th style="width:100px;">物品ID</th>
33
+                <th style="width:100px;">物品数量</th>
34
+                <th style="width:100px;">权重</th>
35
+                <th style="width:256px;">操作</th>
36
+              </thead>
37
+            </table>
38
+            <br>
39
+            <input class="layui-btn" type="button" onclick="modalAddItem()" value=新增道具>
40
+            <hr class="hr15">
41
+            <input value="新增" class="layui-btn" style="width:100%;" type="button" onclick="addExchangeCode()">
42
+            <br>
43
+            <br>
44
+            <input value="关闭" class="layui-btn" style="width:100%;" type="button" onclick="closeModalAdd()">
45
+            <hr class="hr20" >
46
+        </form>
47
+    </dialog>
48
+
49
+    <dialog open id="modalModify" class="x-body layui-anim layui-anim-up" hidden=true style = "center;">
50
+        <form action="exchangecode" method="put" class="layui-form layui-form-pane">
51
+            <input id="pcode_modify" hidden=true type="text">
52
+            <input id="awardTimes_modify" name="awardTimes_modify" placeholder="渠道"  type="text" lay-verify="required" class="layui-input">
53
+            <br>
54
+            <input id="expireTime_modify" name="expireTime_modify" placeholder="版本"  type="text" lay-verify="required" class="layui-input">
55
+            <br>
56
+            <input id="items_modify" name="items_modify" placeholder="下载地址"  type="text" lay-verify="required" class="layui-input">
57
+            <br>
58
+            <input class="layui-btn" type="button" onclick="modalModifyItem()" value=修改>
59
+            <hr class="hr15">
60
+            <input value="修改" class="layui-btn" style="width:100%;" type="button" onclick="modifyExchangeCode()">
61
+            <br>
62
+            <br>
63
+            <input value="关闭" class="layui-btn" style="width:100%;" type="button" onclick="closeModalModify()">
64
+            <hr class="hr20" >
65
+        </form>
66
+    </dialog>
67
+    <dialog open id="modalItem" class="x-body layui-anim layui-anim-up" hidden=true style = "center;">
68
+        <form class="layui-form layui-form-pane">
69
+            <select name="" id="item_id" onchange="gradeItemChange(this.options[this.options.selectedIndex].value)">
70
+              {{range .ItemList}}
71
+                <option value={{.Id}}>{{.Name}}</option>
72
+              {{end}}
73
+            </select>
74
+            <br>
75
+            <input id="item_count" name="item_count" placeholder="物品数量"  type="number" lay-verify="required" class="layui-input">
76
+            <br>
77
+            <input id="weight" name="weight" placeholder="随机权重"  type="number" lay-verify="required" class="layui-input">
78
+            <hr class="hr15">
79
+            <input id="btn" value="新增" class="layui-btn" style="width:100%;" type="button" onclick="addItem()">
80
+            <br>
81
+            <br>
82
+            <input value="关闭" class="layui-btn" style="width:100%;" type="button" onclick="closeModalItem()">
83
+            <hr class="hr20" >
84
+        </form>
85
+    </dialog>
86
+
87
+    <br>
88
+    <br>
89
+    <input class="layui-btn" type="button" onclick="OpenAddItem()" value=新增>
90
+    <br>
91
+    <br>
92
+    <input class="layui-btn" type="button" onclick="Refresh()" value=刷新>
93
+    <br>
94
+    <br>
95
+    <table class="radio-table" border="1">
96
+      <thead>
97
+        <th style="width:256px;">操作</th>
98
+        <th style="width:64px;">兑换码</th>
99
+        <th style="width:128px;">剩余领奖次数</th>
100
+        <th style="width:256px;">创建时间</th>
101
+        <th style="width:256px;">修改时间</th>
102
+        <th style="width:256px;">过期时间</th>
103
+        <th style="width:256px;">随机奖励列表</th>
104
+      </thead>
105
+      <tbody>
106
+        {{range .infoList}}
107
+          <tr>
108
+            <td style = "text-align:center;">
109
+              <input class="layui-btn" type="button" onclick="OpenModifyItem({{.Pcode}}, {{.AwardTimes}}, {{.ExpireTime}}), {{.Items}}" value=修改>
110
+              {{"   | "}}
111
+              <input class="layui-btn" type="button" onclick="clickDelete({{.Pcode}})" value=删除>
112
+            </td>
113
+            <td style = "text-align:center;">{{.Pcode}}</td>
114
+            <td style = "text-align:center;">{{.AwardTimes}}</td>
115
+            <td style = "text-align:center;">{{TimeToStr .CreateTime}}</td>
116
+            <td style = "text-align:center;">{{TimeToStr .ModifyTime}}</td>
117
+            <td style = "text-align:center;">{{TimeToStr .ExpireTime}}</td>
118
+            <td style = "text-align:center;">{{WeightItems .Items}}</td>
119
+          </tr>
120
+        {{end}}
121
+      </tbody>
122
+    </table>
123
+    <script language="JavaScript">
124
+      function formaData(timer) {
125
+          const year = timer.getFullYear()
126
+          const month = (timer.getMonth() + 1).toString().padStart(2, '0') // 由于月份从0开始,因此需加1
127
+          const day = timer.getDate().toString().padStart(2, '0')
128
+          const hour = timer.getHours().toString().padStart(2, '0')
129
+          const minute = timer.getMinutes().toString().padStart(2, '0')
130
+          const second = timer.getSeconds().toString().padStart(2, '0')
131
+          return `${(year)}-${(month)}-${(day)} ${(hour)}:${(minute)}:${(second)}`
132
+      }
133
+      var randChats = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
134
+      function generateMixed(n) {
135
+          var res = "";
136
+          for(var i = 0; i < n ; i ++) {
137
+              var id = Math.ceil(Math.random()*(randChats.length-1));
138
+              res += randChats[id];
139
+          }
140
+          return res;
141
+      }
142
+
143
+      var codeItems = [];
144
+      // 刷新物品列表
145
+      function refreshTableItem() {
146
+        var obj = document.getElementById("tb_item")
147
+        var tbody = obj.getElementsByTagName("tbody")[0];
148
+        if (tbody) {
149
+          if (-[1,]) {
150
+            obj.removeChild(tbody);
151
+          }else{
152
+            obj.removeNode(tbody);
153
+          }
154
+        }
155
+
156
+        if (codeItems.length > 0 && codeItems[0] != "") {
157
+          tbody = document.createElement("tbody")
158
+          for (var i = 0; i < codeItems.length; i++){
159
+            var tr = document.createElement("tr")
160
+
161
+            var td1 = document.createElement("td")
162
+            td1.style = "text-align:center;"
163
+            td1.innerHTML = codeItems[i].id
164
+            tr.appendChild(td1)
165
+
166
+            var td2 = document.createElement("td")
167
+            td2.style = "text-align:center;"
168
+            td2.innerHTML = codeItems[i].count
169
+            tr.appendChild(td2)
170
+
171
+            var td3 = document.createElement("td")
172
+            td3.style = "text-align:center;"
173
+            td3.innerHTML = codeItems[i].weight
174
+            tr.appendChild(td3)
175
+
176
+            var td4 = document.createElement("td")
177
+            td4.style = "text-align:center;"
178
+            td4.innerHTML = '<input class="layui-btn" type="button" onclick="itemDelete(' + codeItems[i].id + ')" value=删除>'
179
+            tr.appendChild(td4)
180
+
181
+            tbody.appendChild(tr)
182
+          }
183
+          obj.appendChild(tbody)
184
+        }
185
+      }
186
+      // 物品弹窗
187
+      function modalAddItem() {
188
+        console.log("modalAddItem codeItems:"+codeItems)
189
+
190
+        refreshTableItem()
191
+
192
+        document.getElementById("modalItem").hidden = false;
193
+      }
194
+      function closeModalItem() {
195
+        document.getElementById("modalItem").hidden = true;
196
+      }
197
+      function addItem() {
198
+        var item_id = parseInt(document.getElementById("item_id").value);
199
+        var item_count = parseInt(document.getElementById("item_count").value);
200
+        var weight = parseInt(document.getElementById("weight").value);
201
+        console.log("addItem weight:"+weight)
202
+
203
+        if (item_id == null || item_id == 0){
204
+          alert("请选择道具");
205
+          return;
206
+        }
207
+        if (item_count == null || item_count <= 0){
208
+          alert("道具数量不能为空或负数");
209
+          return;
210
+        }
211
+        if (weight == null || weight <= 0){
212
+          alert("权重值错误!");
213
+          return;
214
+        }
215
+
216
+        var isMatch = false
217
+        for (var i = 0; i < codeItems.length; i ++) {
218
+          if (codeItems[i].id == item_id) {
219
+            isMatch = true;
220
+            codeItems[i].count += item_count;
221
+            break
222
+          }
223
+        }
224
+        if (isMatch == false) {
225
+          codeItems.push({'id':item_id, 'count':item_count, 'weight':weight})
226
+        }
227
+        refreshTableItem()
228
+        document.getElementById("modalItem").hidden = true;
229
+      }
230
+      // 删除物品
231
+      function itemDelete(itemId) {
232
+        var id = parseInt(itemId)
233
+        console.log("itemDelete itemId:" + itemId)
234
+        for (var i = 0; i < codeItems.length; i ++) {
235
+          if (codeItems[i].id == id) {
236
+            console.log("itemDelete 找到道具")
237
+            codeItems.splice(i, 1)
238
+            break
239
+          }
240
+        }
241
+        refreshTableItem()
242
+        document.getElementById("modalItem").hidden = true;
243
+      }
244
+
245
+      // 随机兑换码
246
+      function randCode() {
247
+        document.getElementById("pcode").value = generateMixed(6);
248
+      }
249
+      function OpenAddItem() {
250
+        document.getElementById("pcode").value = generateMixed(6);
251
+        document.getElementById("awardTimes").value = 100;
252
+
253
+        var dateTime = new Date();
254
+        dateTime = dateTime.setDate(dateTime.getDate()+30);
255
+        dateTime = new Date(dateTime);
256
+        document.getElementById("expireTime").value = formaData(dateTime);
257
+
258
+        document.getElementById("modalAdd").hidden = false;
259
+      }
260
+      function closeModalAdd() {
261
+        document.getElementById("modalAdd").hidden = true;
262
+      }
263
+      function addExchangeCode () {
264
+        var pcode = document.getElementById("pcode").value;
265
+        var awardTimes = parseInt(document.getElementById("awardTimes").value);
266
+        var expireTime = document.getElementById("expireTime").value;
267
+
268
+        if (pcode.length != 6){
269
+          alert("兑换码错误!请设置6位大写字母");
270
+          return;
271
+        }
272
+        if (awardTimes <= 0){
273
+          alert("请正确设置领奖次数");
274
+          return;
275
+        }
276
+        if (codeItems.length <= 0){
277
+          alert("奖励物品空!");
278
+          return;
279
+        }
280
+        // var items = ""
281
+        // for (var i = 0; i < codeItems.length; i ++) {
282
+        //   if (items != "") {
283
+        //     items += "|";
284
+        //   }
285
+        //   items += codeItems[i].id + "," + codeItems[i].count + "," + codeItems[i].weight
286
+        // }
287
+
288
+        var text = "token=" + encodeURI(token);
289
+        text += "&pcode=" + encodeURI(pcode);
290
+        text += "&awardTimes=" + encodeURI(awardTimes);
291
+        text += "&expireTime=" + encodeURI(expireTime);
292
+        text += "&items=" + encodeURI(JSON.stringify(codeItems));
293
+
294
+        $.ajax({
295
+          type:"post",
296
+          url:"/exchangecode?" + text,
297
+          success:function (data) {
298
+            // alert(data.status);
299
+            if (data.status){
300
+              window.location.href="/exchangecode";
301
+            }else{
302
+              if (data.info){
303
+                alert(data.info);
304
+              }else{
305
+                window.location.href="/accountlogin";
306
+              }
307
+            }
308
+          }
309
+        });
310
+      }
311
+
312
+      function OpenModifyItem(id, channel, version, addr, filesize) {
313
+        document.getElementById("modify_id").value = id;
314
+        document.getElementById("channelmodify").value = channel;
315
+        document.getElementById("versionmodify").value = version;
316
+        document.getElementById("addrmodify").value = addr;
317
+        document.getElementById("filesizemodify").value = filesize;
318
+        document.getElementById("modalModify").hidden = false;
319
+      }
320
+      function closeModifyItem() {
321
+        document.getElementById("modalModify").hidden = true;
322
+      }
323
+
324
+      function modifyItem () {
325
+        var id = document.getElementById("modify_id").value;
326
+        var channel = document.getElementById("channelmodify").value;
327
+        var version = document.getElementById("versionmodify").value;
328
+        var addr = document.getElementById("addrmodify").value;
329
+        var filesize = document.getElementById("filesizemodify").value;
330
+        var text = "channel=" + encodeURI(channel) + "&version=" + encodeURI(version) + "&addr=" + encodeURI(addr) + "&filesize=" + encodeURI(filesize) + "&id=" + encodeURI(id) + "&action=modify";
331
+
332
+        $.ajax({
333
+          type:"put",
334
+          url:"/exchangecode?" + text,
335
+          success:function (data) {
336
+            // alert(data.status);
337
+            if (data.status){
338
+              window.location.href="/exchangecode";
339
+            }else{
340
+              if (data.info){
341
+                alert(data.info);
342
+              }else{
343
+                window.location.href="/accountlogin";
344
+              }
345
+            }
346
+          }
347
+        });
348
+      }
349
+
350
+      function clickDelete (id) {
351
+        var text = "id=" + encodeURI(id) + "&action=delete";
352
+
353
+        $.ajax({
354
+          type:"delete",
355
+          url:"/exchangecode?" + text,
356
+          success:function (data) {
357
+            // alert(data.status);
358
+            if (data.status){
359
+              window.location.href="/exchangecode";
360
+            }else{
361
+              if (data.info){
362
+                alert(data.info);
363
+              }else{
364
+                window.location.href="/accountlogin";
365
+              }
366
+            }
367
+          }
368
+        });
369
+      }
370
+    </script>
371
+    </body>
372
+</html>