浏览代码

bodycheck

胡轶钦 6 年前
父节点
当前提交
456a3a019c

+ 1
- 2
conf/app.conf 查看文件

@@ -1,10 +1,9 @@
1 1
 appname = services
2 2
 httpport = 8080
3
-runmode = dev
3
+runmode = prod
4 4
 autorender = false
5 5
 copyrequestbody = true
6 6
 EnableDocs = true
7
-sessionon = true
8 7
 excelpath = ./
9 8
 clienturl = http://dev.ycjcjy.com/c-v2
10 9
 

+ 36
- 177
controllers/auth.go 查看文件

@@ -1,205 +1,64 @@
1 1
 package controllers
2 2
 
3 3
 import (
4
-	"errors"
5 4
 	"net/http"
6
-	"spaceofcheng/services/models/model"
7 5
 	"spaceofcheng/services/service"
8
-	"spaceofcheng/services/utils"
9
-	"strings"
10
-
11
-	"github.com/astaxie/beego"
12 6
 )
13 7
 
14 8
 // Authenticate 权限验证
9
+// 其中 token 的处理方式是
10
+// 1、获取 request 中 token
11
+// 2、放入 Context 中
12
+// 3、校验 token
13
+// 4、结束后,设置过期并从 Context 中删除
14
+// 5、生成新的 token, 并放入 Context 中
15 15
 func (c *BaseController) authenticate() {
16
-
17
-	// 默认 service
18 16
 	serv := service.NewSysServ(c.Context)
19 17
 
20
-	orgID := c.GetString(":org")
21
-	if orgID == "" {
22
-		c.ResponseError(errors.New("接口地址访问不正确"))
23
-	}
24
-	serv.SetOrgByID(orgID)
25
-
26
-	// 客户端类型
27
-	clientType := utils.GetClientType(c.Ctx.Request)
28
-
29
-	switch clientType {
30
-	case utils.ClientAdmin:
31
-		c.authPCAdmin(serv)
32
-	case utils.ClientWechat:
33
-		c.authWechat(serv)
34
-	default:
35
-		c.ResponseError(
36
-			errors.New("暂不支持的 API 场景"),
37
-			http.StatusBadRequest,
38
-		)
39
-	}
40
-}
41
-
42
-// authPCAdmin PC管理端
43
-func (c *BaseController) authPCAdmin(serv *service.SysServ) {
44
-	if !c.needAuth() {
45
-		return
46
-	}
47
-
48
-	// 用户ID
49
-	userID := ""
50
-	userIDRaw := c.GetSession(SNUserID)
51
-	if userIDRaw != nil {
52
-		userID = userIDRaw.(string)
53
-	}
54
-
55
-	if userID == "" {
56
-		c.ResponseError(
57
-			errors.New("用户未登录"),
58
-			http.StatusUnauthorized,
59
-		)
60
-	}
61
-
62
-	if err := serv.SetUserProfile(userID); err != nil {
63
-		// utils.LogError(err.Error())
64
-
65
-		c.ResponseError(
66
-			utils.LogError(err.Error()),
67
-			http.StatusInternalServerError,
68
-		)
69
-	}
70
-
71
-	// 设置 Session
72
-	c.SetSession(SNUserID, userID)
73
-}
74
-
75
-// authWechat 微信端
76
-func (c *BaseController) authWechat(serv *service.SysServ) {
77
-	custID := ""
78
-	custIDRaw := c.GetSession(SNCustID)
79
-	if custIDRaw != nil {
80
-		custID = custIDRaw.(string)
81
-	}
18
+	// 鉴权 - 并初始化上下文
19
+	res := serv.AuthAndInitCtx(c.Ctx)
82 20
 
83
-	// 机构
84
-	org := c.Context.Get("org").(model.SysOrg)
85
-
86
-	// 微信配置
87
-	wxConf, err := serv.GetWeChatConfig(org.OrgId)
88
-	if err != nil {
89
-		utils.LogError("查询微信配置失败: " + err.Error())
90
-		c.ResponseError(
91
-			errors.New("没有找到微信相关配置"),
92
-			http.StatusBadRequest,
93
-		)
94
-	}
95
-	utils.WxClientSingleton(org.OrgId, wxConf)
96
-
97
-	// 用户微信信息
98
-	var wxDetail map[string]interface{}
99
-
100
-	detailRaw := c.GetSession("wechat_user")
101
-	if detailRaw != nil {
102
-		wxDetail = detailRaw.(map[string]interface{})
103
-	} else {
104
-		// DEV MODE
105
-		if c.RunMode == "dev" {
106
-			wxDetail = map[string]interface{}{
107
-				"openid":     "OPENID",
108
-				"nickname":   "NICKNAME",
109
-				"sex":        "1",
110
-				"province":   "PROVINCE",
111
-				"city":       "CITY",
112
-				"country":    "COUNTRY",
113
-				"headimgurl": "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
114
-				"unionid":    "o6_bmasdasdsad6_2sgVt7hMZOPfL",
115
-			}
116
-		} else {
117
-			wxDetail = c.getWechatDetail(org.OrgId, serv)
21
+	if res != nil {
22
+		code := http.StatusOK
23
+		if res["code"] != nil {
24
+			code = res["code"].(int)
118 25
 		}
119 26
 
120
-		c.SetSession("wechat_user", wxDetail)
121
-	}
27
+		if code != http.StatusOK {
28
+			err := res["error"].(error)
29
+			data := map[string]interface{}{}
122 30
 
123
-	c.Context.Set("wxInfo", wxDetail)
31
+			if res["message"] != nil {
32
+				data = res["message"].(map[string]interface{})
33
+			}
124 34
 
125
-	// 用户映射检查
126
-	userMap, err := serv.CheckWechatUserMapping(wxDetail)
127
-	if err != nil {
128
-		c.ResponseError(
129
-			utils.LogError("获取人员映射账户失败: "+err.Error()),
130
-			http.StatusInternalServerError,
131
-		)
132
-	}
133
-	c.Context.Set("userMap", *userMap)
35
+			// 设置旧 token 过期
36
+			c.SetTokenExipre()
134 37
 
135
-	if !c.needAuth() {
136
-		return
137
-	}
138
-	// 未登录或者绑定, 返回 406
139
-	if custID == "" && userMap.UserId == "" {
140
-		// 新增用户信息
141
-		cust, err := serv.SaveNewCustomer(wxDetail, userMap)
142
-		if err != nil {
143
-			c.ResponseError(err)
38
+			c.ResponseData(data, err, code)
144 39
 		}
145
-		custID = cust.CustomerId
146
-		// c.ResponseError(
147
-		// 	errors.New("用户未登录或绑定"),
148
-		// 	http.StatusNotAcceptable,
149
-		// )
150 40
 	}
151 41
 
152
-	if custID == "" {
153
-		custID = userMap.UserId
154
-	}
155
-	if custID != "" {
156
-		if err := serv.SetCustomer(custID); err != nil {
157
-			utils.LogError(err.Error())
42
+	// 设置旧 token 过期
43
+	c.SetTokenExipre()
158 44
 
159
-			c.ResponseError(
160
-				errors.New("内部错误, 请重试"),
161
-				http.StatusInternalServerError,
162
-			)
163
-		}
164
-
165
-		// 设置 Session
166
-		c.SetSession(SNCustID, custID)
167
-	}
45
+	// 生成新 token
46
+	c.CreateNewToken()
168 47
 }
169 48
 
170
-func (c *BaseController) needAuth() bool {
171
-	route := c.Ctx.Input.URL()
172
-	apiPrefix := beego.AppConfig.String("api::prefix")
173
-	guestAPI := beego.AppConfig.String("api::guest")
174
-
175
-	if strings.Index(route, apiPrefix+strings.Split(guestAPI, ":")[0]) > -1 {
176
-		return false
49
+// SetTokenExipre 设置 token 过期
50
+func (c *BaseController) SetTokenExipre() {
51
+	token := c.Context.Get("token")
52
+	if token != nil {
53
+		serv := service.NewSysServ(c.Context)
54
+		serv.UpdateTokenExpire(token.(string))
177 55
 	}
178 56
 
179
-	return true
57
+	c.Context.Set("token", "")
180 58
 }
181 59
 
182
-// getWechatDetail 获取微信个人信息详情
183
-func (c *BaseController) getWechatDetail(org string, serv *service.SysServ) map[string]interface{} {
184
-	// 微信 code
185
-	code := c.GetString("code")
186
-	if code == "" {
187
-		c.ResponseData(
188
-			map[string]interface{}{
189
-				"appid": utils.GetWxAppID(org),
190
-			},
191
-			errors.New("获取微信信息失败"),
192
-			http.StatusUnauthorized,
193
-		)
194
-	}
195
-
196
-	usr, err := utils.WxClientFor(org).GetUserInfo(code)
197
-	if err != nil {
198
-		c.ResponseError(
199
-			utils.LogError("获取微信个人信息失败: "+err.Error()),
200
-			http.StatusInternalServerError,
201
-		)
202
-	}
203
-
204
-	return usr
60
+// CreateNewToken 新 token
61
+func (c *BaseController) CreateNewToken() {
62
+	serv := service.NewSysServ(c.Context)
63
+	c.Context.Set("token", serv.NewToken())
205 64
 }

+ 9
- 1
controllers/base.go 查看文件

@@ -62,7 +62,15 @@ func (c *BaseController) ResponseData(data interface{}, msg interface{}, code in
62 62
 	}
63 63
 
64 64
 	c.Data["json"] = JSONMessage{status, sendMessage, data}
65
-	c.Ctx.Output.Header("Access-Control-Expose-Headers", "X-Token")
65
+	c.Ctx.Output.Header("Access-Control-Expose-Headers", utils.TokenHeader)
66
+
67
+	token := c.Context.Get("token")
68
+	if token != nil {
69
+		tk := token.(string)
70
+		if tk != "" {
71
+			c.Ctx.Output.Header(utils.TokenHeader, utils.TokenSchema+" "+tk)
72
+		}
73
+	}
66 74
 
67 75
 	c.crosPolicy()
68 76
 	c.ServeJSON()

+ 22
- 0
controllers/cases/signin.go 查看文件

@@ -42,3 +42,25 @@ func (c *SigninController) GetSigninWhere() {
42 42
 
43 43
 	c.ResponseJSON(res)
44 44
 }
45
+
46
+// AddSignin 存入签到记录
47
+func (c *SigninController) AddSignin() {
48
+	phone := c.GetString("phone");
49
+	openId := c.GetString("openId")
50
+	caseId := c.GetString("caseId")
51
+	activityId := c.GetString("activityId")
52
+
53
+	signin := model.TaCheckinRecord{}
54
+	signin.Phone = phone
55
+	signin.OpenId = openId
56
+
57
+	userMapping := c.Context.Get("userMap").(model.TaUserMapping)
58
+
59
+	res,err := c.dao.AddSignin(signin,caseId,activityId,&userMapping)
60
+
61
+	if err != nil {
62
+		c.ResponseError(err)
63
+	}
64
+	c.ResponseJSON(res)
65
+}
66
+

+ 0
- 1
controllers/context.go 查看文件

@@ -12,7 +12,6 @@ import (
12 12
 * user					SysUser 									用户基本信息
13 13
 * customer			TaCustomer 								会员基本信息
14 14
 * userMap				TaUserMapping 						用户/会员 映射第三方账户
15
-* wxInfo				map[string]interface{} 		微信信息
16 15
 * cases					[]SysUserCase 						用户所有案场信息
17 16
 * currentCase		SysUserCase 							当前案场
18 17
 * org						SysOrg 										用户当前组织

+ 22
- 0
controllers/coupon/coupon.go 查看文件

@@ -167,3 +167,25 @@ func (c *CouponController) GiveCoupon() {
167 167
 
168 168
 	c.ResponseJSON("ok")
169 169
 }
170
+
171
+// GetCouponBySendType 根据类型获取优惠券
172
+func (c *CouponController) GetCouponBySendType() {
173
+	sendtype := c.GetString(":type")
174
+	coupons, err := c.serv.GetCouponBySendType(sendtype)
175
+	if err != nil {
176
+		c.ResponseError(err)
177
+	}
178
+
179
+	c.ResponseJSON(coupons)
180
+}
181
+
182
+// GetCouponWithCustomer 获取优惠券领取信息
183
+func (c *CouponController) GetCouponWithCustomer() {
184
+	couponid := c.GetString(":id")
185
+	couponDetail, err := c.serv.GetCouponWithCustomer(couponid)
186
+	if err != nil {
187
+		c.ResponseError(err)
188
+	}
189
+
190
+	c.ResponseJSON(couponDetail)
191
+}

+ 23
- 0
controllers/file.go 查看文件

@@ -1,12 +1,14 @@
1 1
 package controllers
2 2
 
3 3
 import (
4
+	"bytes"
4 5
 	"errors"
5 6
 	"spaceofcheng/services/utils"
6 7
 	"strconv"
7 8
 	"time"
8 9
 
9 10
 	"net/http"
11
+	"net/url"
10 12
 )
11 13
 
12 14
 // FileUpload 文件上传
@@ -46,3 +48,24 @@ func (c *BaseController) uploadFileToOSS(field string) (string, error) {
46 48
 
47 49
 	return fileURL, nil
48 50
 }
51
+
52
+// SaveToExcel 保存文件到 excel
53
+func (c *BaseController) SaveToExcel(fn string, data interface{}, f func(interface{}) []interface{}) {
54
+	var buf bytes.Buffer
55
+	if err := utils.NewTinyXLSXEngine().SetTransFunc(f).SetData(data).Write(&buf); err != nil {
56
+		utils.LogError("写 xlsx buffer 失败: " + err.Error())
57
+		c.ResponseError(errors.New("生成 excel 异常, 请重试"))
58
+	}
59
+
60
+	c.Ctx.Output.Header("Content-Disposition", "attachment; filename="+url.QueryEscape(fn))
61
+	c.Ctx.Output.Header("Content-Description", "File Transfer")
62
+	c.Ctx.Output.ContentType(".xlsx")
63
+	c.Ctx.Output.Header("Content-Transfer-Encoding", "binary")
64
+	c.Ctx.Output.Header("Expires", "0")
65
+	c.Ctx.Output.Header("Cache-Control", "must-revalidate")
66
+	c.Ctx.Output.Header("Pragma", "public")
67
+
68
+	r := bytes.NewReader(buf.Bytes())
69
+	http.ServeContent(c.Ctx.ResponseWriter, c.Ctx.Request, fn, time.Now().Local(), r)
70
+	c.StopRun()
71
+}

+ 8
- 6
controllers/marketing/marketing.go 查看文件

@@ -23,7 +23,7 @@ func (c *MarketingController) Constructor() {
23 23
 // 获取 营销活动列表
24 24
 func (c *MarketingController) GetMarketingList(){
25 25
 	page, _ := c.GetInt("page")
26
-	pageSize, _ := c.GetInt("pagesize")
26
+	pageSize, _ := c.GetInt("pageSize")
27 27
 
28 28
 	marketings, err := c.serv.GetMarketingList(page,pageSize)
29 29
 	if err != nil {
@@ -36,17 +36,19 @@ func (c *MarketingController) GetMarketingList(){
36 36
 // SaveMarketing 保存营销活动
37 37
 func (c *MarketingController) SaveMarketing() {
38 38
 	marketing := model.SysActivity{}
39
-
39
+	// 机构
40
+	//org := c.Context.Get("org").([]model.SysOrg)
40 41
 	// 获取值
41 42
 	activityName := c.GetString("activityName")
42 43
 	activityType := c.GetString("activityType")
43 44
 	resourceDesc := c.GetString("resourceDesc") // 活动描述
45
+	caseId := c.GetString("CaseId")
44 46
 
45 47
 	// 赋值
46 48
 	marketing.ActivityName = activityName
47 49
 	marketing.ActivityType = activityType
48 50
 
49
-	newInfo,_, err := c.serv.SaveMarketing(marketing,resourceDesc)
51
+	newInfo,_, err := c.serv.SaveMarketing(marketing,resourceDesc,caseId)
50 52
 	if err != nil {
51 53
 		c.ResponseError(err)
52 54
 	}
@@ -88,7 +90,7 @@ func (c *MarketingController) UpdateMarketing(){
88 90
 
89 91
 // DelMarketing 删除
90 92
 func (c *MarketingController) DelMarketing(){
91
-	activityId := c.GetString("activityId")
93
+	activityId := c.GetString(":activityId")
92 94
 	err := c.serv.DelMarketing(activityId)
93 95
 	if err != nil {
94 96
 		c.ResponseError(err)
@@ -98,7 +100,7 @@ func (c *MarketingController) DelMarketing(){
98 100
 
99 101
 // DelMarketing 正常
100 102
 func (c *MarketingController) DelMarketingNormal(){
101
-	activityId := c.GetString("activityId")
103
+	activityId := c.GetString(":activityId")
102 104
 	err := c.serv.DelMarketingNormal(activityId)
103 105
 	if err != nil {
104 106
 		c.ResponseError(err)
@@ -108,7 +110,7 @@ func (c *MarketingController) DelMarketingNormal(){
108 110
 
109 111
 // DelMarketing 停用
110 112
 func (c *MarketingController) DelMarketingDisable(){
111
-	activityId := c.GetString("activityId")
113
+	activityId := c.GetString(":activityId")
112 114
 	err := c.serv.DelMarketingDisable(activityId)
113 115
 	if err != nil {
114 116
 		c.ResponseError(err)

+ 31
- 8
controllers/user/user.go 查看文件

@@ -182,8 +182,9 @@ func (c *UserController) SignIn() {
182 182
 		)
183 183
 	}
184 184
 
185
-	// 成功之后, 设置 session
186
-	c.SetSession(controllers.SNUserID, user.UserId)
185
+	// 成功之后, 生成新 token
186
+	c.Context.Set("user", *user)
187
+	c.CreateNewToken()
187 188
 
188 189
 	if token == "" && doRemember != 0 {
189 190
 		var err error
@@ -205,7 +206,7 @@ func (c *UserController) SignIn() {
205 206
 
206 207
 // SignOut 用户登出
207 208
 func (c *UserController) SignOut() {
208
-	c.DestroySession()
209
+	c.SetTokenExipre()
209 210
 	c.ResponseJSON("ok")
210 211
 }
211 212
 
@@ -251,11 +252,11 @@ func (c *UserController) GetUserByTel() {
251 252
 
252 253
 // GetForbidUsers 获取所有禁止人员信息
253 254
 func (c *UserController) GetForbidUsers() {
254
-	caseid := c.GetString("caseid")
255
-	if caseid == "" {
256
-		c.ResponseError(errors.New("没有案场信息"))
257
-	}
258
-	users, err := c.dao.GetForbidUsers(caseid)
255
+	// caseid := c.GetString("caseid")
256
+	// if caseid == "" {
257
+	// 	c.ResponseError(errors.New("没有案场信息"))
258
+	// }
259
+	users, err := c.dao.GetForbidUsers()
259 260
 	if err != nil {
260 261
 		utils.LogError("获取禁止人员信息失败: " + err.Error())
261 262
 		c.ResponseError(errors.New("获取禁止人员信息失败"))
@@ -286,3 +287,25 @@ func (c *UserController) OpenForbidUser() {
286 287
 	}
287 288
 	c.ResponseJSON("操作成功")
288 289
 }
290
+
291
+// GetCaseUserByType 根据用户类型获取用户信息
292
+func (c *UserController) GetCaseUserByType() {
293
+	usertype := c.GetString(":type")
294
+	users, err := c.dao.GetCaseUserByType(usertype)
295
+	if err != nil {
296
+		utils.LogError("获取人员信息失败: " + err.Error())
297
+		c.ResponseError(errors.New("获取人员信息失败"))
298
+	}
299
+	c.ResponseJSON(users)
300
+}
301
+
302
+// GetCaseUserByID 根据id获取用户详情
303
+func (c *UserController) GetCaseUserByID() {
304
+	userid := c.GetString(":id")
305
+	userdetail, err := c.dao.GetCaseUserByUserID(userid)
306
+	if err != nil {
307
+		utils.LogError("获取人员信息失败: " + err.Error())
308
+		c.ResponseError(errors.New("获取人员信息失败"))
309
+	}
310
+	c.ResponseJSON(userdetail)
311
+}

+ 53
- 6
models/card/card.go 查看文件

@@ -215,15 +215,62 @@ func (m *CardDAO) CheckCustCard(custID, CardID string, startDate, endDate time.T
215 215
 // 案场可用卡信息
216 216
 type CaseUsableCard struct {
217 217
 	model.TaCouponCard `xorm:"extends"`
218
-	UserSendCount      int
219
-	UserUsedCount      int
218
+	CustomerCard       []model.TaCustomerCard
220 219
 }
221 220
 
222 221
 // GetCaseUsableCard 获取案场可用卡信息
223
-func (m *CardDAO) GetCaseUsableCard(caseid string) ([]CaseUsableCard, error) {
222
+func (m *CardDAO) GetCaseUsableCard(caseid, userid string, page, pageSize int) ([]CaseUsableCard, error) {
224 223
 	var cards []CaseUsableCard
225
-	sql := `select * from ta_coupon_card where case_id=? and status=? and end_date>now() order by create_date limit `
226
-	err := m.db.Sql(sql).Find(&cards)
227
-	// err := m.db.Where("case_id=?", caseid).And("status=?", models.STATUS_NORMAL).And("end_date>now()").Desc("create_date").Find(&cards)
224
+	sql := `select * from ta_coupon_card where case_id=? and status=? and end_date>now() order by create_date limit ` + strconv.Itoa((page-1)*pageSize) + `, ` + strconv.Itoa(pageSize)
225
+	err := m.db.Sql(sql, caseid, models.STATUS_NORMAL).Find(&cards)
226
+	if userid != "" {
227
+		for inx, card := range cards {
228
+			cCards, err := m.GetCustomerCardByCardAndUser(card.CardId, userid)
229
+			if err != nil {
230
+				return nil, err
231
+			}
232
+			cards[inx].CustomerCard = cCards
233
+		}
234
+	}
228 235
 	return cards, err
229 236
 }
237
+
238
+// GetCustomerCardByCardAndUser 根据卡与用户获取领取的用户信息
239
+func (m *CardDAO) GetCustomerCardByCardAndUser(cardid, userid string) ([]model.TaCustomerCard, error) {
240
+	var customerCards []model.TaCustomerCard
241
+	err := m.db.Where("card_id=?", cardid).And("sales_id=?", userid).And("status>?", models.STATUS_DEL).Find(&customerCards)
242
+	return customerCards, err
243
+}
244
+
245
+// GetCardDetail 获取卡详情
246
+func (m *CardDAO) GetCardDetail(cardid string) (*CaseUsableCard, error) {
247
+	var card = new(CaseUsableCard)
248
+	sql := `select * from ta_coupon_card where card_id=? and status>?`
249
+	_, err := m.db.Sql(sql, cardid, models.STATUS_DEL).Get(&card)
250
+	if err != nil {
251
+		return nil, err
252
+	}
253
+	if card == nil || card.CardId == "" {
254
+		return nil, errors.New("无卡信息")
255
+	}
256
+	ccards, err := m.GetCustomerCardByCard(cardid)
257
+	if err != nil {
258
+		return nil, err
259
+	}
260
+	card.CustomerCard = ccards
261
+	return card, nil
262
+}
263
+
264
+// GetCustomerCardByCard 根据卡获取领取的用户信息
265
+func (m *CardDAO) GetCustomerCardByCard(cardid string) ([]model.TaCustomerCard, error) {
266
+	var customerCards []model.TaCustomerCard
267
+	err := m.db.Where("card_id=?", cardid).And("status>?", models.STATUS_DEL).Find(&customerCards)
268
+	return customerCards, err
269
+}
270
+
271
+// GetCustomerCardByUser 根据用户获取发送的卡信息
272
+func (m *CardDAO) GetCustomerCardByUser(caseid, userid string) ([]model.TaCustomerCard, error) {
273
+	var customerCards []model.TaCustomerCard
274
+	err := m.db.Where("case_id=?", caseid).And("sales_id=?", userid).And("status>?", models.STATUS_DEL).Find(&customerCards)
275
+	return customerCards, err
276
+}

+ 13
- 3
models/cases/signin.go 查看文件

@@ -3,9 +3,10 @@ package cases
3 3
 import (
4 4
 	"spaceofcheng/services/models/model"
5 5
 	"spaceofcheng/services/utils"
6
+	"spaceofcheng/services/models"
6 7
 	"strconv"
7 8
 	"strings"
8
-
9
+	"time"
9 10
 	"github.com/go-xorm/xorm"
10 11
 )
11 12
 
@@ -43,10 +44,10 @@ func NewSigninDAO(ctx *utils.Context) *SigninDAO {
43 44
 	}
44 45
 }
45 46
 
46
-// CaseInfo 案场
47
+// SigninInfo 案场
47 48
 type SigninInfo struct {
48 49
 	model.TaCheckinRecord `xorm:"extends"`
49
-	//CreateUserName string
50
+	UserId string
50 51
 }
51 52
 
52 53
 /**
@@ -95,3 +96,12 @@ func (m *SigninDAO) GetSigninWhere(selectType int, caseid string, page, pageSize
95 96
 	// }
96 97
 	return signin, err
97 98
 }
99
+
100
+// AddSignin 添加签到记录 
101
+func (m *SigninDAO) AddSignin(signin model.TaCheckinRecord)(model.TaCheckinRecord,error){
102
+	signin.CheckinId = utils.GetGUID()
103
+	signin.CreateDate = time.Now()
104
+	signin.Status = models.STATUS_NORMAL
105
+	_,err := m.db.Insert(signin)
106
+	return signin,err
107
+}

+ 6
- 0
models/constant.go 查看文件

@@ -139,6 +139,12 @@ const (
139 139
 	SYS_RESOURCE_GOODS  = "goods"
140 140
 )
141 141
 
142
+// dashboard 配置的使用者类型
143
+const (
144
+	DASH_SETTING_FOR_USER     = "user"
145
+	DASH_SETTING_FOR_USERTYPE = "user-type"
146
+)
147
+
142 148
 // 卡券状态
143 149
 const (
144 150
 	CARD_COUPON_RECEIVED = "received"

+ 85
- 0
models/coupon/coupon.go 查看文件

@@ -251,3 +251,88 @@ func (m *CouponDAO) SaveCouponRecoreds(recs []model.TaCouponGiveRecord) error {
251 251
 
252 252
 	return nil
253 253
 }
254
+
255
+// GetCouponBySendType 根据类型获取优惠券
256
+func (m *CouponDAO) GetCouponBySendType(caseids, sendtype string) ([]model.TaCoupon, error) {
257
+	var coupons []model.TaCoupon
258
+	err := m.db.Where("case_id in ('"+strings.Replace(caseids, ",", "','", -1)+"')").And("send_type=?", sendtype).And("status=?", models.STATUS_NORMAL).Find(&coupons)
259
+	return coupons, err
260
+}
261
+
262
+// GetCaseUsableCoupon 获取案场可用优惠券信息
263
+func (m *CouponDAO) GetCaseUsableCoupon(caseid, userid string, page, pageSize int) ([]CaseCouponDetail, error) {
264
+	var Coupons []CaseCouponDetail
265
+	sql := `select * from ta_coupon where case_id=? and status=? and end_date>now() order by create_date limit ` + strconv.Itoa((page-1)*pageSize) + `, ` + strconv.Itoa(pageSize)
266
+	err := m.db.Sql(sql, caseid, models.STATUS_NORMAL).Find(&Coupons)
267
+	if userid != "" {
268
+		for inx, Coupon := range Coupons {
269
+			cCoupons, err := m.GetCustomerCouponByCouponAndUser(Coupon.CouponId, userid)
270
+			if err != nil {
271
+				return nil, err
272
+			}
273
+			Coupons[inx].CustomerCoupon = cCoupons
274
+		}
275
+	}
276
+	return Coupons, err
277
+}
278
+
279
+// GetCustomerCouponByCouponAndUser 根据优惠券与用户获取领取的用户信息
280
+func (m *CouponDAO) GetCustomerCouponByCouponAndUser(couponid, userid string) ([]model.TaCustomerCoupon, error) {
281
+	var customerCoupons []model.TaCustomerCoupon
282
+	err := m.db.Where("coupon_id=?", couponid).And("sales_id=?", userid).And("status>?", models.STATUS_DEL).Find(&customerCoupons)
283
+	return customerCoupons, err
284
+}
285
+
286
+// GetCouponDetail 获取优惠券详情
287
+func (m *CouponDAO) GetCouponDetail(couponid string) (*CaseCouponDetail, error) {
288
+	var coupon = new(CaseCouponDetail)
289
+	sql := `select * from ta_coupon_Coupon where coupon_id=? and status>?`
290
+	_, err := m.db.Sql(sql, couponid, models.STATUS_DEL).Get(&coupon)
291
+	if err != nil {
292
+		return nil, err
293
+	}
294
+	if coupon == nil || coupon.CouponId == "" {
295
+		return nil, errors.New("无优惠券信息")
296
+	}
297
+	cCoupons, err := m.GetCustomerCouponByCoupon(couponid)
298
+	if err != nil {
299
+		return nil, err
300
+	}
301
+	coupon.CustomerCoupon = cCoupons
302
+	return coupon, nil
303
+}
304
+
305
+// GetCustomerCouponByCoupon 根据优惠券获取领取的用户信息
306
+func (m *CouponDAO) GetCustomerCouponByCoupon(couponid string) ([]model.TaCustomerCoupon, error) {
307
+	var customerCoupons []model.TaCustomerCoupon
308
+	err := m.db.Where("coupon_id=?", couponid).And("status>?", models.STATUS_DEL).Find(&customerCoupons)
309
+	return customerCoupons, err
310
+}
311
+
312
+// GetCustomerCouponByUser 根据用户获取领取的用户信息
313
+func (m *CouponDAO) GetCustomerCouponByUser(caseid, userid string) ([]model.TaCustomerCoupon, error) {
314
+	var customerCoupons []model.TaCustomerCoupon
315
+	err := m.db.Where("case_id=?", caseid).And("sales_id=?", userid).And("status>?", models.STATUS_DEL).Find(&customerCoupons)
316
+	return customerCoupons, err
317
+}
318
+
319
+// GetCouponWithCustomer 获取优惠券明细
320
+func (m CouponDAO) GetCouponWithCustomer(couponid string) (*CaseCouponDetail, error) {
321
+	var coupon = new(CaseCouponDetail)
322
+	sql := `select * from ta_coupon where coupin_id=?`
323
+	_, err := m.db.Sql(sql, couponid).Get(&coupon)
324
+	if err != nil {
325
+		return nil, err
326
+	}
327
+	if coupon == nil || coupon.CouponId == "" {
328
+		return nil, errors.New("无优惠券信息")
329
+	}
330
+	var customerCopons []model.TaCustomerCoupon
331
+	sql = `select * from ta_customer_coupon where coupon_id = ? and status>?`
332
+	err = m.db.Sql(sql, coupon, models.STATUS_DEL).Find(&customerCopons)
333
+	if err != nil {
334
+		return nil, err
335
+	}
336
+	coupon.CustomerCoupon = customerCopons
337
+	return coupon, nil
338
+}

+ 6
- 0
models/coupon/types.go 查看文件

@@ -18,3 +18,9 @@ type CouponInfo struct {
18 18
 	Images         []model.TaCouponImage
19 19
 	Rules          []model.TaCouponRule
20 20
 }
21
+
22
+// CaseUsableCoupon 案场可用优惠券信息
23
+type CaseCouponDetail struct {
24
+	model.TaCoupon `xorm:"extends"`
25
+	CustomerCoupon []model.TaCustomerCoupon
26
+}

+ 12
- 0
models/goods/orders.go 查看文件

@@ -262,3 +262,15 @@ func (m *GoodsDAO) UpdateOrdersMake(orders model.TaGoodsOrders) error {
262 262
 	_, err := m.db.Cols(cols...).Where("orders_id=?", orders.OrdersId).Update(orders)
263 263
 	return err
264 264
 }
265
+
266
+// GetOrderDetailByUser 获取用户所有下单信息
267
+func (m *GoodsDAO) GetOrderDetailByUser(caseid, userid string) ([]model.TaGoodsOrdersDetail, error) {
268
+	var details []model.TaGoodsOrdersDetail
269
+	sql := `select a.* from ta_goods_orders_detail a inner join ta_goods_orders b on a.orders_id=b.orders_id
270
+		inner join ta_customer c on b.user_id = c.customer_id
271
+	where c.user_id=? and b.status>? and b.case_id=?`
272
+	if err := m.db.Sql(sql, userid, models.STATUS_DEL, caseid).Find(&details); err != nil {
273
+		return nil, err
274
+	}
275
+	return details, nil
276
+}

+ 14
- 14
models/marketing/marketing.go 查看文件

@@ -10,7 +10,7 @@ import(
10 10
 
11 11
 // 活动类型
12 12
 const (
13
-	NEW_ACTIVITIES = 0 // 注册赠券
13
+	NEW_ACTIVITIES = 1 // 注册赠券
14 14
 
15 15
 )
16 16
 
@@ -19,7 +19,6 @@ const (
19 19
 	DELETE = -1 // 删除
20 20
 	NORMAL = 0 // 正常
21 21
 	DISABLE = 1 // 停用
22
-
23 22
 )
24 23
 
25 24
 // 赠券卡券
@@ -43,9 +42,14 @@ func NewMarketingDAO(ctx *utils.Context) *MarketingDAO {
43 42
 	}
44 43
 }
45 44
 
46
-// MarketingInfo 课程
45
+// MarketingInfo 
47 46
 type MarketingInfo struct {
48 47
 	model.SysActivity `xorm:"extends"`
48
+	CaseName		 string
49
+	ActionId     string
50
+	ActiveType  string
51
+	ResourceType string
52
+	ResourceDesc string
49 53
 	Actions []model.SysActivityAction
50 54
 }
51 55
 
@@ -53,7 +57,9 @@ type MarketingInfo struct {
53 57
 func (m *MarketingDAO) GetMarketingList(page int, pageSize int) ([]MarketingInfo ,error){
54 58
 
55 59
 	var news []MarketingInfo
56
-	sql := `select * from sys_activity new order by new.create_date desc limit ` + strconv.Itoa((page-1)*pageSize) + ", " + strconv.Itoa(pageSize)
60
+	//sql := `select * from sys_activity new order by new.create_date desc limit ` + strconv.Itoa((page-1)*pageSize) + ", " + strconv.Itoa(pageSize)
61
+	sql :=`SELECT sc.case_name,sa.*,sas.action_id,sas.active_type,sas.resource_type,sas.resource_desc from sys_activity sa LEFT JOIN sys_activity_action sas on sa.activity_id = sas.activity_id LEFT JOIN sys_case sc on sa.case_id = sc.case_id where sa.status != -1 order by sa.create_date desc limit ` + strconv.Itoa((page-1)*pageSize) + ", " + strconv.Itoa(pageSize)
62
+
57 63
 	err := m.db.Sql(sql).Find(&news)
58 64
 	return news, err
59 65
 
@@ -72,24 +78,18 @@ func (m *MarketingDAO) GetMarketingCount()(int64, error){
72 78
 
73 79
 
74 80
 // AddMarketing 添加
75
-func (m *MarketingDAO) AddMarketing(activity *model.SysActivity) (*model.SysActivity, error) {
81
+func (m *MarketingDAO) AddMarketing(activity model.SysActivity, caseId string) (*model.SysActivity, error) {
76 82
 	activity.ActivityId = utils.GetGUID()
77 83
 	activity.CreateDate = time.Now()
78 84
 	//activity.Status = models.STATUS_NORMAL
79 85
 	activity.Status = NORMAL // 状态为正常
80 86
 	org := m.ctx.Get("org").(model.SysOrg)
81 87
 	activity.OrgId = org.OrgId
82
-	caseinfo := m.ctx.Get("currentCase").(model.SysCase)
83
-	activity.CaseId = caseinfo.CaseId
84
-	//activity.CaseId = user.
88
+	activity.CaseId = caseId
85 89
 
86
-	_, err := m.db.Insert(activity)
90
+	_, err := m.db.Insert(&activity)
87 91
 
88
-	// // 添加活动动作数据
89
-	// var new model.SysActivityAction
90
-	// new.ActionId = activity.ActivityId
91
-	// new.ActiveType = activity.ActivityType
92
-	return activity, err
92
+	return &activity, err
93 93
 }
94 94
 
95 95
 

+ 3
- 2
models/marketing/work.go 查看文件

@@ -27,11 +27,12 @@ type WrokInfo struct {
27 27
 }
28 28
 
29 29
 // 添加 活动动作
30
-func (m *WorkDAO) AddWork(action *model.SysActivityAction) (*model.SysActivityAction,error){
30
+func (m *WorkDAO) AddWork(action model.SysActivityAction) (*model.SysActivityAction,error){
31 31
 	action.ActionId = utils.GetGUID()
32
+	println("service: 主键:" + action.ActionId + "活动ID"+action.ActivityId+" 活动类型-"+action.ActiveType+" 资源描述-"+action.ResourceDesc+" 资源类型-"+	action.ResourceType)
32 33
 	_,err := m.db.Insert(&action)
33 34
 
34
-	return action,err
35
+	return &action,err
35 36
 
36 37
 }
37 38
 

+ 15
- 15
models/model/sys_activity.go 查看文件

@@ -1,15 +1,15 @@
1
-package model
2
-
3
-import (
4
-	"time"
5
-)
6
-
7
-type SysActivity struct {
8
-	ActivityId   string    `xorm:"not null pk VARCHAR(64)"`
9
-	ActivityName string    `xorm:"VARCHAR(50)"`
10
-	ActivityType string    `xorm:"VARCHAR(64)"`
11
-	OrgId        string    `xorm:"VARCHAR(64)"`
12
-	CaseId       string    `xorm:"VARCHAR(64)"`
13
-	Status       int       `xorm:"SMALLINT(6)"`
14
-	CreateDate   time.Time `xorm:"DATETIME"`
15
-}
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type SysActivity struct {
8
+	ActivityId   string    `xorm:"not null pk VARCHAR(64)"`
9
+	ActivityName string    `xorm:"VARCHAR(50)"`
10
+	ActivityType string    `xorm:"VARCHAR(64)"`
11
+	OrgId        string    `xorm:"VARCHAR(64)"`
12
+	CaseId       string    `xorm:"VARCHAR(64)"`
13
+	Status       int       `xorm:"SMALLINT(6)"`
14
+	CreateDate   time.Time `xorm:"DATETIME"`
15
+}

+ 10
- 0
models/model/sys_token_log.go 查看文件

@@ -0,0 +1,10 @@
1
+package model
2
+
3
+import "time"
4
+
5
+type SysTokenLog struct {
6
+	TokenId    int       `xorm:"not null pk autoincr INT(11)"`
7
+	Token      string    `xorm:"TEXT"`
8
+	Status     int       `xorm:"SMALLINT(6)"`
9
+	CreateDate time.Time `xorm:"DATETIME"`
10
+}

+ 10
- 0
models/model/ta_dashboard_setting.go 查看文件

@@ -0,0 +1,10 @@
1
+package model
2
+
3
+type TaDashboardSetting struct {
4
+	SettingId   string `xorm:"not null pk VARCHAR(64)"`
5
+	SettingName string `xorm:"VARCHAR(255)"`
6
+	CompList    string `xorm:"TEXT"`
7
+	Owner       string `xorm:"VARCHAR(64)"`
8
+	ForType     string `xorm:"VARCHAR(100)"`
9
+	Status      int    `xorm:"SMALLINT(6)"`
10
+}

+ 45
- 0
models/statistics/other.go 查看文件

@@ -0,0 +1,45 @@
1
+package statistics
2
+
3
+import (
4
+	"spaceofcheng/services/models"
5
+	"spaceofcheng/services/models/model"
6
+	"strings"
7
+)
8
+
9
+// GetUserTypes 获取人员类型
10
+func (m *StatisticsDAO) GetUserTypes(id string) ([]model.SysUserType, error) {
11
+	if id == "" {
12
+		return nil, nil
13
+	}
14
+
15
+	var tps []model.SysUserType
16
+	if err := m.db.Where("user_id=?", id).Find(&tps); err != nil {
17
+		return nil, err
18
+	}
19
+
20
+	return tps, nil
21
+}
22
+
23
+// GetDashboardSetting 获取人员 dashboard 设置
24
+func (m *StatisticsDAO) GetDashboardSetting(userID string, userTypes []string) ([]model.TaDashboardSetting, error) {
25
+	filters := make([]string, 0)
26
+	if userID != "" {
27
+		filters = append(filters, "(for_type='"+models.DASH_SETTING_FOR_USER+"' AND owner='"+userID+"')")
28
+	}
29
+
30
+	if userTypes != nil {
31
+		filters = append(filters, "(for_type='"+models.DASH_SETTING_FOR_USERTYPE+"' AND owner in ('"+strings.Join(userTypes, "','")+"'))")
32
+	}
33
+
34
+	if len(filters) == 0 {
35
+		return nil, nil
36
+	}
37
+
38
+	var settings []model.TaDashboardSetting
39
+	query := `select * from ta_dashboard_setting where (` + strings.Join(filters, " OR ") + ") AND status = ?"
40
+	if err := m.db.SQL(query, models.STATUS_NORMAL).Find(&settings); err != nil {
41
+		return nil, err
42
+	}
43
+
44
+	return settings, nil
45
+}

+ 40
- 0
models/sys.go 查看文件

@@ -4,6 +4,7 @@ import (
4 4
 	"errors"
5 5
 	"spaceofcheng/services/models/model"
6 6
 	"spaceofcheng/services/utils"
7
+	"time"
7 8
 
8 9
 	"github.com/yl10/kit/guid"
9 10
 
@@ -165,3 +166,42 @@ func (m *SysDAO) GetWeChatConfig(org string) (*model.SysWechatConf, error) {
165 166
 
166 167
 	return conf, nil
167 168
 }
169
+
170
+// InsertToken 插入 token 生成记录
171
+func (m *SysDAO) InsertToken(token string) error {
172
+	tk := model.SysTokenLog{
173
+		Token:      token,
174
+		Status:     STATUS_NORMAL,
175
+		CreateDate: time.Now().Local(),
176
+	}
177
+
178
+	if _, err := m.db.Insert(&tk); err != nil {
179
+		return err
180
+	}
181
+
182
+	return nil
183
+}
184
+
185
+// UpdateTokenExpire 设置 token 过期
186
+func (m *SysDAO) UpdateTokenExpire(token string) error {
187
+	tk := model.SysTokenLog{
188
+		Status: STATUS_DEL,
189
+	}
190
+
191
+	if _, err := m.db.Cols("status").Where("token=?", token).Update(&tk); err != nil {
192
+		return err
193
+	}
194
+
195
+	return nil
196
+}
197
+
198
+// GetToken 获取 token
199
+func (m *SysDAO) GetToken(token string) (*model.SysTokenLog, error) {
200
+	tk := model.SysTokenLog{}
201
+
202
+	if _, err := m.db.Where("token=?", token).Get(&tk); err != nil {
203
+		return nil, err
204
+	}
205
+
206
+	return &tk, nil
207
+}

+ 27
- 1
models/system/user.go 查看文件

@@ -465,7 +465,7 @@ func (m *UserDAO) CheckUserName(userid, username, orgid string) (bool, error) {
465 465
 // GetForbidUsers 获取所有禁止人员信息
466 466
 func (m *UserDAO) GetForbidUsers(caseid string) ([]model.TaForbidUser, error) {
467 467
 	var forbiduser []model.TaForbidUser
468
-	err := m.db.Where("case_id=?", caseid).And("end_date > NOW()").And("status>" + strconv.Itoa(models.STATUS_DEL)).Find(&forbiduser)
468
+	err := m.db.Where("case_id=?", caseid).And("(end_date is null or end_date > NOW())").And("status>" + strconv.Itoa(models.STATUS_DEL)).Find(&forbiduser)
469 469
 	return forbiduser, err
470 470
 }
471 471
 
@@ -496,3 +496,29 @@ func (m *UserDAO) OpenForbidUser(forbid *model.TaForbidUser) error {
496 496
 	_, err := m.db.Cols(col...).Where("forbid_id=?", forbid.ForbidId).Update(forbid)
497 497
 	return err
498 498
 }
499
+
500
+// UserWithCouponAndCard 用户关联卡券信息
501
+type UserWithCouponAndCard struct {
502
+	model.SysUser  `xorm:"extends"`
503
+	CustomerCoupon []model.TaCustomerCoupon
504
+	CustomerCard   []model.TaCustomerCard
505
+	OrdersDetail   []model.TaGoodsOrdersDetail
506
+}
507
+
508
+// GetCaseUserByType 获取案场所有销售信息
509
+func (m *UserDAO) GetCaseUserByType(caseid, usertype string) ([]UserWithCouponAndCard, error) {
510
+	var users []UserWithCouponAndCard
511
+	sql := `select a.* from sys_user a inner join sys_user_type b on a.user_id=b.user_id
512
+	inner join sys_user_case c on a.user_id=c.user_id
513
+	where a.status>? and c.case_id =? and b.type_id=?`
514
+	err := m.db.Sql(sql, models.STATUS_DEL, caseid, usertype).Find(&users)
515
+	return users, err
516
+}
517
+
518
+// GetUserDetailByID 根据id获取案场销售
519
+func (m *UserDAO) GetUserDetailByID(userid string) (*UserWithCouponAndCard, error) {
520
+	var user UserWithCouponAndCard
521
+	sql := `select * from sys_user where status>? and user_id=?`
522
+	_, err := m.db.Sql(sql, models.STATUS_DEL, userid).Get(&user)
523
+	return &user, err
524
+}

+ 1
- 0
routers/common.go 查看文件

@@ -230,6 +230,7 @@ func getCommonRoutes() beego.LinkNamespace {
230 230
 		beego.NSRouter("/coupon/:id", &coupon.CouponController{}, "get:GetCouponByIDForAdmin"),
231 231
 		beego.NSRouter("/coupon/:id", &coupon.CouponController{}, "put:UpdateCoupon"),
232 232
 		beego.NSRouter("/coupon/:id/to/:users", &coupon.CouponController{}, "post:GiveCoupon"),
233
+		beego.NSRouter("/coupon/type/:type", &coupon.CouponController{}, "get:GetCouponBySendType"),
233 234
 
234 235
 		// 卡
235 236
 		beego.NSRouter("/card", &card.CardController{}, "get:ListByCase"),

+ 4
- 0
routers/wechat.go 查看文件

@@ -41,5 +41,9 @@ func getWechatRoutes() beego.LinkNamespace {
41 41
 		beego.NSRouter("/user/forbid", &user.UserController{}, "get:GetForbidUsers"),
42 42
 		beego.NSRouter("/user/forbid/:userid/:type", &user.UserController{}, "post:SaveForbidUser"),
43 43
 		beego.NSRouter("/user/forbid/:userid/:type", &user.UserController{}, "put:OpenForbidUser"),
44
+
45
+		// 用户
46
+		beego.NSRouter("/user/:type", &user.UserController{}, "get:GetCaseUserByType"),
47
+		beego.NSRouter("/user/detail/:id", &user.UserController{}, "get:GetCaseUserByID"),
44 48
 	)
45 49
 }

+ 62
- 1
service/cases/signin.go 查看文件

@@ -2,15 +2,19 @@ package cases
2 2
 
3 3
 import (
4 4
 	"spaceofcheng/services/models/cases"
5
+	"spaceofcheng/services/models/marketing"
5 6
 	"spaceofcheng/services/utils"
6
-
7
+	"spaceofcheng/services/models/model"
7 8
 	"github.com/astaxie/beego"
9
+	"encoding/json"
8 10
 )
9 11
 
10 12
 // SigninServ 系统处理
11 13
 type SigninServ struct {
12 14
 	ctx *utils.Context
13 15
 	dao *cases.SigninDAO
16
+	marDao  *marketing.MarketingDAO
17
+	caseDao     *cases.CaseDAO
14 18
 }
15 19
 
16 20
 // NewSigninServ 初始化
@@ -18,6 +22,8 @@ func NewSigninServ(ctx *utils.Context) *SigninServ {
18 22
 	return &SigninServ{
19 23
 		ctx: ctx,
20 24
 		dao: cases.NewSigninDAO(ctx),
25
+		marDao: marketing.NewMarketingDAO(ctx),
26
+		caseDao: cases.NewCaseDAO(ctx),
21 27
 	}
22 28
 }
23 29
 
@@ -47,3 +53,58 @@ func (s *SigninServ) GetSigninWhere(selectType int, caseids string, page, pageSi
47 53
 		"page":     page,
48 54
 	}, err
49 55
 }
56
+
57
+// 添加 签到记录
58
+func (s *SigninServ) AddSignin(signin model.TaCheckinRecord,caseId string,activityId string,userMap *model.TaUserMapping) (*model.TaCheckinRecord,error) {
59
+	if signin.OpenId == "" {
60
+		return nil, utils.LogError("没有OpenId")
61
+	}
62
+	if signin.Phone == "" {
63
+		return nil, utils.LogError("没有Phone手机号")
64
+	}
65
+	if caseId == "" {
66
+		return nil,utils.LogError("没有案场ID")
67
+	}
68
+	if activityId == ""  {
69
+		return nil,utils.LogError("没有活动ID")
70
+	}
71
+
72
+	// 获取上下文的用户
73
+	user := s.ctx.Get("user").(model.SysUser)
74
+	casesInfo,err := s.caseDao.GetCaseByID(caseId)
75
+	activityInfo,err := s.marDao.GetMarketingById(activityId)
76
+	
77
+	// 定义Map
78
+	var jsonMap = map[string]string{}
79
+	accountInfo := userMap.AccountInfo
80
+	// 转换JSON
81
+	var jsonBlob = []byte(accountInfo)
82
+	jsonErr := json.Unmarshal(jsonBlob, &jsonMap)
83
+
84
+	if jsonErr != nil {
85
+		return nil,utils.LogError("accountInfo转换json失败")
86
+	}
87
+	// openId
88
+	signin.OpenId = jsonMap["openid"]
89
+	// 微信昵称
90
+	signin.CustomerName = jsonMap["nickname"]
91
+	// 客户姓名
92
+	signin.Name = user.UserName
93
+	// 客户ID
94
+	signin.CustomerId = user.UserId
95
+
96
+	// 案场
97
+	signin.CaseId = casesInfo.CaseId
98
+	signin.CaseName = casesInfo.CaseName
99
+
100
+	// 活动
101
+	signin.ActivityId = activityInfo.ActivityId
102
+	signin.ActivityName = activityInfo.ActivityName
103
+
104
+	info, err := s.dao.AddSignin(signin)
105
+	if err != nil {
106
+		return nil,err
107
+	}
108
+
109
+	return &info,err
110
+}

+ 31
- 0
service/coupon/coupon.go 查看文件

@@ -350,3 +350,34 @@ func (s *CouponServ) GetCouponByIDWithCheck(cpID string) (*coupon.CouponInfo, er
350 350
 
351 351
 	return cp, nil
352 352
 }
353
+
354
+// GetCouponBySendType 根据发送类型获取优惠券
355
+func (s *CouponServ) GetCouponBySendType(sendtype string) ([]model.TaCoupon, error) {
356
+	cases := s.ctx.Get("cases").([]model.SysUserCase)
357
+	caseIDs := ""
358
+	for _, value := range cases {
359
+		if caseIDs != "" {
360
+			caseIDs = caseIDs + ","
361
+		}
362
+		caseIDs = caseIDs + value.CaseId
363
+	}
364
+	coupon, err := s.dao.GetCouponBySendType(caseIDs, sendtype)
365
+	if err != nil {
366
+		utils.LogError("获取优惠券失败: " + err.Error())
367
+		return nil, errors.New("校验优惠券失败")
368
+	}
369
+	return coupon, nil
370
+}
371
+
372
+// GetCouponWithCustomer 获取优惠券明细
373
+func (s *CouponServ) GetCouponWithCustomer(couponid string) (*coupon.CaseCouponDetail, error) {
374
+	if couponid == "" {
375
+		return nil, errors.New("没有券信息!")
376
+	}
377
+	couponDetail, err := s.dao.GetCouponDetail(couponid)
378
+	if err != nil {
379
+		utils.LogError("获取优惠券失败: " + err.Error())
380
+		return nil, errors.New("获取优惠券失败")
381
+	}
382
+	return couponDetail, nil
383
+}

+ 11
- 24
service/customer/customer.go 查看文件

@@ -1,6 +1,7 @@
1 1
 package customer
2 2
 
3 3
 import (
4
+	"encoding/json"
4 5
 	"errors"
5 6
 	"spaceofcheng/services/models"
6 7
 	"spaceofcheng/services/models/cases"
@@ -104,15 +105,14 @@ func (s *CustomerServ) BindWechatUser(userMap *model.TaUserMapping, phone string
104 105
 	}
105 106
 
106 107
 	if cust == nil {
107
-		wxInfoRaw := s.ctx.Get("wxInfo")
108
-		if wxInfoRaw == nil {
109
-			return nil, errors.New("请确定使用微信端登录")
108
+		wxInfo := utils.WechatUser{}
109
+		if err := json.Unmarshal([]byte(userMap.AccountInfo), &wxInfo); err != nil {
110
+			utils.LogError("解析用户微信映射信息失败: " + err.Error())
111
+			return nil, errors.New("系统数据异常")
110 112
 		}
111 113
 
112
-		wxInfo := wxInfoRaw.(map[string]interface{})
113 114
 		// 更新用户手机号码信息及userid信息
114
-		openid := wxInfo["openid"].(string)
115
-		customer, err := s.dao.GetCustWithWXByOpenID(openid)
115
+		customer, err := s.dao.GetCustWithWXByOpenID(wxInfo.OpenID)
116 116
 
117 117
 		newCust := model.TaCustomer{
118 118
 			CustomerId: customer.CustomerId,
@@ -128,11 +128,6 @@ func (s *CustomerServ) BindWechatUser(userMap *model.TaUserMapping, phone string
128 128
 			return nil, err
129 129
 		}
130 130
 
131
-		// newCust, err := s.SaveNewCustomer(wxInfo, "", "", user.Phone, user.UserId)
132
-		// if err != nil {
133
-		// 	utils.LogError(err.Error())
134
-		// 	return nil, err
135
-		// }
136 131
 		cust = &newCust
137 132
 	} else {
138 133
 		if cust.Status != models.STATUS_NORMAL {
@@ -168,16 +163,14 @@ func (s *CustomerServ) BindWechatCust(userMap *model.TaUserMapping, phone, caseI
168 163
 
169 164
 	// 用户不存在, 则新增
170 165
 	if cust == nil {
171
-		wxInfoRaw := s.ctx.Get("wxInfo")
172
-		if wxInfoRaw == nil {
173
-			return nil, errors.New("请确定使用微信端登录")
166
+		wxInfo := utils.WechatUser{}
167
+		if err := json.Unmarshal([]byte(userMap.AccountInfo), &wxInfo); err != nil {
168
+			utils.LogError("解析用户微信映射信息失败: " + err.Error())
169
+			return nil, errors.New("系统数据异常")
174 170
 		}
175 171
 
176
-		wxInfo := wxInfoRaw.(map[string]interface{})
177
-
178 172
 		// 更新用户手机号码信息及userid信息
179
-		openid := wxInfo["openid"].(string)
180
-		customer, err := s.dao.GetCustWithWXByOpenID(openid)
173
+		customer, err := s.dao.GetCustWithWXByOpenID(wxInfo.OpenID)
181 174
 		newCust := model.TaCustomer{
182 175
 			CustomerId:  customer.CustomerId,
183 176
 			Phone:       phone,
@@ -228,12 +221,6 @@ func (s *CustomerServ) BindWechatCust(userMap *model.TaUserMapping, phone, caseI
228 221
 			return nil, err
229 222
 		}
230 223
 
231
-		// newCust, err := s.SaveNewCustomer(wxInfo, caseID, userID, phone, "")
232
-		// if err != nil {
233
-		// 	utils.LogError(err.Error())
234
-		// 	return nil, err
235
-		// }
236
-
237 224
 		cust = &newCust
238 225
 	} else {
239 226
 		if cust.Status != models.STATUS_NORMAL {

+ 6
- 4
service/marketing/marketing.go 查看文件

@@ -21,10 +21,11 @@ func NewMarketingServ(ctx *utils.Context) *MarketingServ {
21 21
 	return &MarketingServ{
22 22
 		ctx: ctx,
23 23
 		dao: marketing.NewMarketingDAO(ctx),
24
+		wdao: marketing.NewWorkDAO(ctx),
24 25
 	}
25 26
 }
26 27
 
27
-// GetCustWithWXList 获取客户列表
28
+// GetMarketingList 获取活动列表
28 29
 func (s *MarketingServ) GetMarketingList(page int, pageSize int) (map[string]interface{}, error) {
29 30
 
30 31
 	if pageSize == 0 {
@@ -54,14 +55,14 @@ func (s *MarketingServ) GetMarketingList(page int, pageSize int) (map[string]int
54 55
 /**
55 56
 * resource_desc 活动描述
56 57
  */
57
-func (s *MarketingServ) SaveMarketing(activity model.SysActivity, resourceDesc string) (*model.SysActivity, *model.SysActivityAction, error) {
58
+func (s *MarketingServ) SaveMarketing(activity model.SysActivity, resourceDesc string, caseId string) (*model.SysActivity, *model.SysActivityAction, error) {
58 59
 
59 60
 	var newInfo *model.SysActivity
60 61
 	var newWoke *model.SysActivityAction
61 62
 
62 63
 	var err error
63 64
 	// 存储 营销活动
64
-	newInfo, err = s.dao.AddMarketing(&activity)
65
+	newInfo, err = s.dao.AddMarketing(activity,caseId)
65 66
 	if err != nil {
66 67
 		return nil, nil, err
67 68
 	}
@@ -70,9 +71,10 @@ func (s *MarketingServ) SaveMarketing(activity model.SysActivity, resourceDesc s
70 71
 	woke.ActivityId = newInfo.ActivityId
71 72
 	woke.ActiveType = newInfo.ActivityType
72 73
 	woke.ResourceDesc = resourceDesc
74
+	woke.ResourceType = "占位符"
73 75
 
74 76
 	// 存储 活动动作
75
-	newWoke, err = s.wdao.AddWork(&woke)
77
+	newWoke, err = s.wdao.AddWork(woke)
76 78
 	if err != nil {
77 79
 		return nil, nil, err
78 80
 	}

+ 1
- 2
service/marketing/work.go 查看文件

@@ -24,8 +24,7 @@ func NewWorkServ(ctx *utils.Context) *WorkServ {
24 24
 }
25 25
 
26 26
 // 保存 Work
27
-func (s *WorkServ) SaveWork(work *model.SysActivityAction)  (*model.SysActivityAction, error){
28
-		var newInfo *model.SysActivityAction
27
+func (s *WorkServ) SaveWork(work model.SysActivityAction)  (*model.SysActivityAction, error){
29 28
 		if work.ActivityId == "" {
30 29
 			return nil, utils.LogError("营销编号为空!")
31 30
 		}

+ 37
- 0
service/statistics/dashboard.go 查看文件

@@ -0,0 +1,37 @@
1
+package statistics
2
+
3
+// import (
4
+// 	"spaceofcheng/services/models/model"
5
+// 	"spaceofcheng/services/utils"
6
+// 	"strings"
7
+// )
8
+
9
+// // StaDashboard 控制板统计
10
+// func (s *StatisticsServ) StaDashboard() error {
11
+// 	user := s.ctx.Get("user").(model.SysUser)
12
+
13
+// }
14
+
15
+// // distinctDashSettings 去重 dashboard 配置
16
+// func (s *StatisticsServ) distinctDashSettings(settings []model.TaDashboardSetting) []string {
17
+// 	comps := make([]string, 0)
18
+
19
+// 	if settings == nil || len(settings) == 0 {
20
+// 		return comps
21
+// 	}
22
+
23
+// 	for _, s := range settings {
24
+// 		comps = append(comps, s.CompList)
25
+// 	}
26
+
27
+// 	allComps := strings.Split(strings.Join(comps, ","), ",")
28
+
29
+// 	res := make([]string, 0)
30
+// 	for _, cmp := range allComps {
31
+// 		if utils.StrSliceIndexOf(res, cmp) == -1 {
32
+// 			res = append(res, cmp)
33
+// 		}
34
+// 	}
35
+
36
+// 	return res
37
+// }

+ 6
- 0
service/statistics/setting.go 查看文件

@@ -0,0 +1,6 @@
1
+package statistics
2
+
3
+// StaticMapFrontComponent 每种统计映射的前端组件名称
4
+var StaticMapFrontComponent = map[string]string{
5
+	"": "",
6
+}

+ 20
- 0
service/statistics/statistics.go 查看文件

@@ -0,0 +1,20 @@
1
+package statistics
2
+
3
+import (
4
+	"spaceofcheng/services/models/statistics"
5
+	"spaceofcheng/services/utils"
6
+)
7
+
8
+// StatisticsServ 系统处理
9
+type StatisticsServ struct {
10
+	ctx *utils.Context
11
+	dao *statistics.StatisticsDAO
12
+}
13
+
14
+// NewStatisticsServ 初始化
15
+func NewStatisticsServ(ctx *utils.Context) *StatisticsServ {
16
+	return &StatisticsServ{
17
+		ctx: ctx,
18
+		dao: statistics.NewStatisticsDAO(ctx),
19
+	}
20
+}

+ 384
- 36
service/sys.go 查看文件

@@ -3,12 +3,17 @@ package service
3 3
 import (
4 4
 	"encoding/json"
5 5
 	"errors"
6
+	"net/http"
6 7
 	"spaceofcheng/services/models"
7 8
 	"spaceofcheng/services/models/customer"
8 9
 	"spaceofcheng/services/models/model"
9 10
 	"spaceofcheng/services/utils"
11
+	"strconv"
12
+	"strings"
13
+	"time"
10 14
 
11 15
 	"github.com/astaxie/beego"
16
+	"github.com/astaxie/beego/context"
12 17
 )
13 18
 
14 19
 const (
@@ -17,6 +22,7 @@ const (
17 22
 
18 23
 // SysServ 系统处理
19 24
 type SysServ struct {
25
+	org         model.SysOrg
20 26
 	ctx         *utils.Context
21 27
 	dao         *models.SysDAO
22 28
 	customerdao *customer.CustomerDAO
@@ -31,6 +37,363 @@ func NewSysServ(ctx *utils.Context) *SysServ {
31 37
 	}
32 38
 }
33 39
 
40
+// AuthAndInitCtx 鉴权
41
+// gctx 是 beego 框架中的 Context
42
+func (s *SysServ) AuthAndInitCtx(gctx *context.Context) map[string]interface{} {
43
+	// 确认机构
44
+	orgID := gctx.Input.Query(":org")
45
+	if orgID == "" {
46
+		return map[string]interface{}{
47
+			"code":  http.StatusBadRequest,
48
+			"error": errors.New("接口地址访问不正确"),
49
+		}
50
+	}
51
+	if err := s.SetOrgByID(orgID); err != nil {
52
+		return map[string]interface{}{
53
+			"code":  http.StatusInternalServerError,
54
+			"error": err,
55
+		}
56
+	}
57
+
58
+	// 客户端类型
59
+	// 通过 UA 判断
60
+	clientType := utils.GetClientType(gctx.Request)
61
+	if clientType == utils.ClientWechat {
62
+		// 初始化微信配置
63
+		if err := s.initWechatClient(s.org.OrgId); err != nil {
64
+			utils.LogError("初始化微信客户端失败: " + err.Error())
65
+
66
+			return map[string]interface{}{
67
+				"code":  http.StatusInternalServerError,
68
+				"error": errors.New("初始化微信客户端失败"),
69
+			}
70
+		}
71
+	}
72
+
73
+	// 获取 token
74
+	token, err := s.getToken(gctx, clientType)
75
+	if err != nil {
76
+		message := make(map[string]interface{})
77
+		if clientType == utils.ClientWechat {
78
+			message["appid"] = utils.GetWxAppID(s.org.OrgId)
79
+		}
80
+
81
+		// token 报错一律视为需要重新登录
82
+		return map[string]interface{}{
83
+			"code":    http.StatusUnauthorized,
84
+			"error":   err,
85
+			"message": message,
86
+		}
87
+	}
88
+
89
+	// pc 管理端
90
+	if clientType == utils.ClientAdmin {
91
+		return s.authPCAdmin(gctx, token)
92
+	}
93
+
94
+	// wechat 端
95
+	if clientType == utils.ClientWechat {
96
+		return s.authWechat(gctx, token)
97
+	}
98
+
99
+	return map[string]interface{}{
100
+		"code":  http.StatusBadRequest,
101
+		"error": errors.New("暂无该客户端的 API"),
102
+	}
103
+}
104
+
105
+// NewToken 设置 TOKEN
106
+// 15 分钟后过期
107
+func (s *SysServ) NewToken() string {
108
+	var token *utils.JWTToken
109
+	exp := time.Now().Local().Add(15 * time.Second)
110
+
111
+	if s.ctx.Get("userMap") != nil {
112
+		userMap := s.ctx.Get("userMap").(model.TaUserMapping)
113
+
114
+		token = &utils.JWTToken{
115
+			Guest:  false,
116
+			ID:     userMap.Openid,
117
+			Expire: exp,
118
+		}
119
+	} else if s.ctx.Get("user") != nil {
120
+		user := s.ctx.Get("user").(model.SysUser)
121
+
122
+		token = &utils.JWTToken{
123
+			Guest:  false,
124
+			ID:     user.UserId,
125
+			Expire: exp,
126
+		}
127
+	} else {
128
+		token = &utils.JWTToken{
129
+			Guest:  true,
130
+			Expire: exp,
131
+		}
132
+	}
133
+
134
+	tokenEncodeStr, err := utils.CreateToken(token.ToMap())
135
+	if err != nil {
136
+		utils.LogError("系统生成 Token 失败: " + err.Error())
137
+		return ""
138
+	}
139
+
140
+	// 入库
141
+	if !token.Guest {
142
+		if err := s.dao.InsertToken(tokenEncodeStr); err != nil {
143
+			utils.LogError("入库 Token 失败: " + err.Error())
144
+			return tokenEncodeStr
145
+		}
146
+	}
147
+
148
+	return tokenEncodeStr
149
+}
150
+
151
+// authPCAdmin
152
+// 管理端 API 校验
153
+func (s *SysServ) authPCAdmin(gctx *context.Context, token *utils.JWTToken) map[string]interface{} {
154
+	if !s.needAuth(gctx) {
155
+		return nil
156
+	}
157
+
158
+	if token.ID == "" || token.Guest == true {
159
+		return map[string]interface{}{
160
+			"code":  http.StatusUnauthorized,
161
+			"error": errors.New("用户未登录"),
162
+		}
163
+	}
164
+
165
+	if err := s.SetUserProfile(token.ID); err != nil {
166
+		return map[string]interface{}{
167
+			"code":  http.StatusInternalServerError,
168
+			"error": err,
169
+		}
170
+	}
171
+
172
+	return nil
173
+}
174
+
175
+func (s *SysServ) authWechat(gctx *context.Context, token *utils.JWTToken) map[string]interface{} {
176
+	// 微信 code
177
+	code := gctx.Input.Query("code")
178
+
179
+	var wxUser *utils.WechatUser
180
+	var openID string
181
+
182
+	// 未登录 或 未验证
183
+	if token.ID == "" {
184
+		// 微信用户信息
185
+		var err error
186
+		wxUser, err = s.wechartSignIn(gctx, code)
187
+		if err != nil {
188
+			if strings.Index(err.Error(), strconv.Itoa(http.StatusUnauthorized)) > -1 {
189
+				return map[string]interface{}{
190
+					"code":  http.StatusUnauthorized,
191
+					"error": errors.New("请授权微信用户登录"),
192
+					"message": map[string]interface{}{
193
+						"appid": utils.GetWxAppID(s.org.OrgId),
194
+					},
195
+				}
196
+			}
197
+
198
+			return map[string]interface{}{
199
+				"code":  http.StatusInternalServerError,
200
+				"error": err,
201
+			}
202
+		}
203
+
204
+		if wxUser == nil {
205
+			return map[string]interface{}{
206
+				"code":  http.StatusInternalServerError,
207
+				"error": errors.New("请先关注公众号"),
208
+			}
209
+		}
210
+
211
+		openID = wxUser.OpenID
212
+	} else {
213
+		openID = token.ID
214
+	}
215
+
216
+	// 查询数据库是否存在已有映射
217
+	userMapList, err := s.dao.GetUserMappingByOpenID(openID)
218
+	if err != nil {
219
+		utils.LogError("校验人员失败: " + err.Error())
220
+		return map[string]interface{}{
221
+			"code":  http.StatusInternalServerError,
222
+			"error": errors.New("校验人员失败"),
223
+		}
224
+	}
225
+
226
+	var userMapping *model.TaUserMapping
227
+	for _, ump := range userMapList {
228
+		if openID == ump.Openid && models.ACCMAP_WECHAT == ump.AccountType {
229
+			userMapping = &ump
230
+		}
231
+	}
232
+
233
+	// 如果尚无人员映射信息, 代表人员初次使用本系统
234
+	if userMapping == nil {
235
+		// 如果没有微信用户信息, 代表产生了未知异常
236
+		if wxUser == nil || wxUser.UnionID == "" {
237
+			return map[string]interface{}{
238
+				"code":  http.StatusInternalServerError,
239
+				"error": errors.New("系统异常, 请清空缓存后重试"),
240
+			}
241
+		}
242
+
243
+		wxInfoJSON, err := json.Marshal(wxUser)
244
+		if err != nil {
245
+			utils.LogError("转换微信json信息失败: " + err.Error())
246
+			return map[string]interface{}{
247
+				"code":  http.StatusInternalServerError,
248
+				"error": errors.New("微信信息异常"),
249
+			}
250
+		}
251
+
252
+		userMapping = &model.TaUserMapping{
253
+			AccountType: models.ACCMAP_WECHAT,
254
+			Openid:      openID,
255
+			Uuid:        wxUser.UnionID,
256
+			AccountInfo: string(wxInfoJSON),
257
+		}
258
+	}
259
+
260
+	// 更新映射信息, 没有的话则插入
261
+	err = s.dao.UpdateUserMapping(userMapping)
262
+	if err != nil {
263
+		utils.LogError("保存用户映射信息失败: " + err.Error())
264
+		return map[string]interface{}{
265
+			"code":  http.StatusInternalServerError,
266
+			"error": errors.New("更新用户信息失败"),
267
+		}
268
+	}
269
+	s.ctx.Set("userMap", *userMapping)
270
+
271
+	if !s.needAuth(gctx) {
272
+		return nil
273
+	}
274
+
275
+	var cust *model.TaCustomer
276
+
277
+	// 如果只有映射, 但是没有人员信息
278
+	// 则新增人员
279
+	if userMapping.UserId == "" {
280
+		cust, err = s.saveNewCustomer(wxUser, userMapping)
281
+		if err != nil {
282
+			return map[string]interface{}{
283
+				"code":  http.StatusInternalServerError,
284
+				"error": err,
285
+			}
286
+		}
287
+	} else {
288
+		cust, err = s.customerdao.GetCustomerByID(userMapping.UserId)
289
+		if err != nil {
290
+			utils.LogError("查询用户信息失败: " + err.Error())
291
+			return map[string]interface{}{
292
+				"code":  http.StatusInternalServerError,
293
+				"error": err,
294
+			}
295
+		}
296
+	}
297
+	s.ctx.Set("customer", *cust)
298
+
299
+	if cust.UserId != "" {
300
+		if err := s.SetUserProfile(cust.UserId); err != nil {
301
+			return map[string]interface{}{
302
+				"code":  http.StatusInternalServerError,
303
+				"error": err,
304
+			}
305
+		}
306
+	}
307
+
308
+	return nil
309
+}
310
+
311
+// wechartSignIn 使用 code 微信登录
312
+func (s *SysServ) wechartSignIn(gctx *context.Context, code string) (*utils.WechatUser, error) {
313
+	if beego.BConfig.RunMode == "dev" {
314
+		return &utils.WechatUser{
315
+			OpenID: "OPENID",
316
+		}, nil
317
+	}
318
+
319
+	if code == "" {
320
+		return nil, errors.New(strconv.Itoa(http.StatusUnauthorized))
321
+	}
322
+
323
+	// 获取 微信信息
324
+	// 可能出现的情况是 openid 获取到了, 但是详情没有获取到
325
+	wxUserMap, err := utils.WxClientFor(s.org.OrgId).GetUserInfo(code)
326
+	if err != nil {
327
+		utils.LogError("获取微信信息失败: " + err.Error())
328
+
329
+		if wxUserMap == nil {
330
+			return nil, errors.New("获取微信信息失败")
331
+		}
332
+	}
333
+
334
+	return utils.MapToWechatUser(wxUserMap), nil
335
+}
336
+
337
+func (s *SysServ) getToken(gctx *context.Context, clientType string) (*utils.JWTToken, error) {
338
+	if beego.BConfig.RunMode == "dev" {
339
+		id := "0"
340
+		if clientType == utils.ClientWechat {
341
+			id = "OPENID"
342
+		}
343
+
344
+		return &utils.JWTToken{
345
+			ID: id,
346
+		}, nil
347
+	}
348
+
349
+	tokenRaw := gctx.Input.Header(utils.TokenHeader)
350
+	if tokenRaw == "" {
351
+		return new(utils.JWTToken), nil
352
+	}
353
+
354
+	tokenEnStr := strings.Trim(strings.TrimLeft(tokenRaw, utils.TokenSchema), " ")
355
+	s.ctx.Set("token", tokenEnStr)
356
+
357
+	token, err := utils.PareseToken(tokenEnStr)
358
+	if err != nil {
359
+		utils.LogError("解析 Token 失败: " + err.Error())
360
+		return nil, errors.New("解析Token失败或已过期")
361
+	}
362
+
363
+	// 校验 token
364
+	tk, err := s.dao.GetToken(tokenEnStr)
365
+	if err != nil {
366
+		utils.LogError("查询 Token 失败: " + err.Error())
367
+		return nil, errors.New("校验Token失败或已过期")
368
+	}
369
+
370
+	if tk.Status == models.STATUS_DEL {
371
+		return nil, errors.New("超时 或者 Token 已过期")
372
+	}
373
+
374
+	return utils.MapToJWTToken(token), nil
375
+}
376
+
377
+// UpdateTokenExpire 更新 token 为过期
378
+// 如果发生错误, 此处选择忽略
379
+func (s *SysServ) UpdateTokenExpire(token string) {
380
+	if err := s.dao.UpdateTokenExpire(token); err != nil {
381
+		utils.LogError("更新 Token 过期失败: " + err.Error())
382
+	}
383
+}
384
+
385
+func (s *SysServ) needAuth(gctx *context.Context) bool {
386
+	route := gctx.Input.URL()
387
+	apiPrefix := beego.AppConfig.String("api::prefix")
388
+	guestAPI := beego.AppConfig.String("api::guest")
389
+
390
+	if strings.Index(route, apiPrefix+strings.Split(guestAPI, ":")[0]) > -1 {
391
+		return false
392
+	}
393
+
394
+	return true
395
+}
396
+
34 397
 // SetUserProfile 设置用户信息
35 398
 func (s *SysServ) SetUserProfile(id string) error {
36 399
 	user, err := s.dao.GetPureUserInfo(id)
@@ -60,32 +423,14 @@ func (s *SysServ) SetUserProfile(id string) error {
60 423
 	return nil
61 424
 }
62 425
 
63
-// SetCustomer 设置客户信息
64
-func (s *SysServ) SetCustomer(id string) error {
65
-	cust, err := s.dao.GetCustomer(id)
66
-	if err != nil {
67
-		return utils.LogError("获取客户基本信息失败: " + err.Error())
68
-	}
69
-
70
-	s.ctx.Set("customer", *cust)
71
-	return nil
72
-}
73
-
74
-// SaveNewCustomer 新增用户
75
-func (s *SysServ) SaveNewCustomer(wxInfo map[string]interface{}, userMap *model.TaUserMapping) (*model.TaCustomer, error) {
76
-	// 微信相关字段
77
-	nickyName := wxInfo["nickname"].(string)
78
-	sex := wxInfo["sex"].(float64)
79
-	headimgurl := wxInfo["headimgurl"].(string)
80
-
81
-	org := s.ctx.Get("org").(model.SysOrg)
82
-
426
+// saveNewCustomer 新增用户
427
+func (s *SysServ) saveNewCustomer(wxUser *utils.WechatUser, userMap *model.TaUserMapping) (*model.TaCustomer, error) {
83 428
 	cust := model.TaCustomer{
84
-		CustomerName: nickyName,
85
-		Name:         nickyName,
86
-		Sex:          int(sex),
87
-		Headimgurl:   headimgurl,
88
-		OrgId:        org.OrgId,
429
+		CustomerName: wxUser.NickName,
430
+		Name:         wxUser.NickName,
431
+		Sex:          int(wxUser.Sex),
432
+		Headimgurl:   wxUser.HeadImgURL,
433
+		OrgId:        s.org.OrgId,
89 434
 	}
90 435
 
91 436
 	if err := s.customerdao.SaveCustomer(&cust); err != nil {
@@ -130,7 +475,6 @@ func (s *SysServ) CheckWechatUserMapping(user map[string]interface{}) (*model.Ta
130 475
 
131 476
 	accountRaw, err := json.Marshal(user)
132 477
 	if err != nil {
133
-		beego.Error(err)
134 478
 		return nil, err
135 479
 	}
136 480
 	account := string(accountRaw)
@@ -146,7 +490,6 @@ func (s *SysServ) CheckWechatUserMapping(user map[string]interface{}) (*model.Ta
146 490
 	userMapList, err := s.dao.GetUserMappingByOpenID(openID)
147 491
 
148 492
 	if err != nil {
149
-		beego.Error(err)
150 493
 		return nil, err
151 494
 	}
152 495
 
@@ -172,28 +515,32 @@ func (s *SysServ) CheckWechatUserMapping(user map[string]interface{}) (*model.Ta
172 515
 	return &userMapping, nil
173 516
 }
174 517
 
175
-// GetWeChatConfig 获取微信配置
176
-func (s SysServ) GetWeChatConfig(org string) (map[string]string, error) {
177
-	conf, err := s.dao.GetWeChatConfig(org)
518
+// initWechatClient 初始化微信客户端
519
+func (s *SysServ) initWechatClient(orgID string) error {
520
+	conf, err := s.dao.GetWeChatConfig(orgID)
178 521
 	if err != nil {
179
-		return nil, err
522
+		utils.LogError("获取微信配置失败: " + err.Error())
523
+		return errors.New("获取微信配置失败")
180 524
 	}
181 525
 
182
-	if conf.ConfId == "" {
183
-		return nil, errors.New("未找到微信配置")
526
+	if conf == nil || conf.ConfId == "" {
527
+		return errors.New("未找到微信配置")
184 528
 	}
185 529
 
186
-	return map[string]string{
530
+	cert := map[string]string{
187 531
 		"appid":  conf.Appid,
188 532
 		"secret": conf.Secret,
189 533
 		"token":  conf.Token,
190 534
 		"aeskey": conf.Aeskey,
191 535
 		"wxid":   conf.Wxid,
192
-	}, nil
536
+	}
537
+
538
+	utils.WxClientSingleton(orgID, cert)
539
+	return nil
193 540
 }
194 541
 
195 542
 // SetOrgByID 获取组织
196
-func (s SysServ) SetOrgByID(orgID string) error {
543
+func (s *SysServ) SetOrgByID(orgID string) error {
197 544
 	orgID = utils.DecodeBase64NoTail(orgID)
198 545
 
199 546
 	org, err := s.dao.GetOrg(orgID)
@@ -203,6 +550,7 @@ func (s SysServ) SetOrgByID(orgID string) error {
203 550
 	}
204 551
 
205 552
 	s.ctx.Set("org", *org)
553
+	s.org = *org
206 554
 
207 555
 	return nil
208 556
 }

+ 101
- 3
service/user.go 查看文件

@@ -3,8 +3,11 @@ package service
3 3
 import (
4 4
 	"errors"
5 5
 	"spaceofcheng/services/models"
6
+	"spaceofcheng/services/models/card"
6 7
 	"spaceofcheng/services/models/cases"
8
+	"spaceofcheng/services/models/coupon"
7 9
 	"spaceofcheng/services/models/customer"
10
+	"spaceofcheng/services/models/goods"
8 11
 	"spaceofcheng/services/models/model"
9 12
 	"spaceofcheng/services/models/system"
10 13
 	"spaceofcheng/services/utils"
@@ -19,6 +22,9 @@ type UserServ struct {
19 22
 	dao         *system.UserDAO
20 23
 	casedao     *cases.CaseDAO
21 24
 	customerdao *customer.CustomerDAO
25
+	carddao     *card.CardDAO
26
+	coupondao   *coupon.CouponDAO
27
+	ordersdao   *goods.GoodsDAO
22 28
 }
23 29
 
24 30
 // NewUserServ 初始化
@@ -28,6 +34,9 @@ func NewUserServ(ctx *utils.Context) *UserServ {
28 34
 		dao:         system.NewUserDAO(ctx),
29 35
 		casedao:     cases.NewCaseDAO(ctx),
30 36
 		customerdao: customer.NewCustomerDAO(ctx),
37
+		carddao:     card.NewCardDAO(ctx),
38
+		coupondao:   coupon.NewCouponDAO(ctx),
39
+		ordersdao:   goods.NewGoodsDAO(ctx),
31 40
 	}
32 41
 }
33 42
 
@@ -411,11 +420,19 @@ func (s *UserServ) GetUserByTel(tel string) (*model.SysUser, error) {
411 420
 }
412 421
 
413 422
 // GetForbidUsers 获取所有禁止人员信息
414
-func (s *UserServ) GetForbidUsers(caseid string) ([]model.TaForbidUser, error) {
415
-	if err := utils.NewAuthEngine(s.ctx).CheckCase(caseid); err != nil {
423
+func (s *UserServ) GetForbidUsers() ([]model.TaForbidUser, error) {
424
+	customer := s.ctx.Get("customer").(model.TaCustomer)
425
+	if customer.CustomerId == "" || customer.UserId == "" {
426
+		return nil, errors.New("当前用户没有权限查看用户信息")
427
+	}
428
+	caseinfo, err := s.dao.GetUserBelongCase(customer.UserId)
429
+	if err != nil {
416 430
 		return nil, err
417 431
 	}
418
-	users, err := s.dao.GetForbidUsers(caseid)
432
+	// if err := utils.NewAuthEngine(s.ctx).CheckCase(caseid); err != nil {
433
+	// 	return nil, err
434
+	// }
435
+	users, err := s.dao.GetForbidUsers(caseinfo.CaseId)
419 436
 	return users, err
420 437
 }
421 438
 
@@ -508,3 +525,84 @@ func (s *UserServ) OpenForbidUser(userid string, forbidtype string) error {
508 525
 	err = s.dao.OpenForbidUser(&forbiduser)
509 526
 	return err
510 527
 }
528
+
529
+// GetCaseUserByType 根据用户类型获取人员信息
530
+func (s *UserServ) GetCaseUserByType(usertype string) ([]system.UserWithCouponAndCard, error) {
531
+	customer := s.ctx.Get("customer").(model.TaCustomer)
532
+	if customer.CustomerId == "" || customer.UserId == "" {
533
+		return nil, errors.New("当前用户没有权限查看用户信息")
534
+	}
535
+	caseinfo, err := s.dao.GetUserBelongCase(customer.UserId)
536
+	if err != nil {
537
+		utils.LogError("获取人员归属案场失败: " + err.Error())
538
+		return nil, errors.New("获取人员信息失败")
539
+	}
540
+
541
+	users, err := s.dao.GetCaseUserByType(caseinfo.CaseId, usertype)
542
+	if err != nil {
543
+		utils.LogError("获取人员信息失败: " + err.Error())
544
+		return nil, errors.New("获取人员信息失败")
545
+	}
546
+	for inx, user := range users {
547
+		err := s.GetUserWithDetail(caseinfo.CaseId, &user)
548
+		if err != nil {
549
+			return nil, err
550
+		}
551
+		users[inx] = user
552
+	}
553
+	return users, nil
554
+}
555
+
556
+// GetCaseUserByUserID 根据用户id获取人员信息
557
+func (s *UserServ) GetCaseUserByUserID(userid string) (*system.UserWithCouponAndCard, error) {
558
+	customer := s.ctx.Get("customer").(model.TaCustomer)
559
+	if customer.CustomerId == "" || customer.UserId == "" {
560
+		return nil, errors.New("当前用户没有权限查看用户信息")
561
+	}
562
+	caseinfo, err := s.dao.GetUserBelongCase(customer.UserId)
563
+	if err != nil {
564
+		utils.LogError("获取人员归属案场失败: " + err.Error())
565
+		return nil, errors.New("获取人员信息失败")
566
+	}
567
+	usercaseinfo, err := s.dao.GetUserBelongCase(userid)
568
+	if err != nil {
569
+		utils.LogError("获取人员归属案场失败: " + err.Error())
570
+		return nil, errors.New("获取人员信息失败")
571
+	}
572
+	if usercaseinfo.CaseId != caseinfo.CaseId {
573
+		return nil, errors.New("您没有权限查看此用户的数据!")
574
+	}
575
+	user, err := s.dao.GetUserDetailByID(userid)
576
+	if err != nil {
577
+		utils.LogError("获取人员信息失败: " + err.Error())
578
+		return nil, errors.New("获取人员信息失败")
579
+	}
580
+	err = s.GetUserWithDetail(usercaseinfo.CaseId, user)
581
+	if err != nil {
582
+		return nil, err
583
+	}
584
+	return user, nil
585
+}
586
+
587
+// GetUserWithDetail 获取用户详情
588
+func (s *UserServ) GetUserWithDetail(caseid string, user *system.UserWithCouponAndCard) error {
589
+	cards, err := s.carddao.GetCustomerCardByUser(caseid, user.UserId)
590
+	if err != nil {
591
+		utils.LogError("获取发送卡信息失败: " + err.Error())
592
+		return errors.New("获取人员信息失败")
593
+	}
594
+	user.CustomerCard = cards
595
+	coupons, err := s.coupondao.GetCustomerCouponByUser(caseid, user.UserId)
596
+	if err != nil {
597
+		utils.LogError("获取发送券信息失败: " + err.Error())
598
+		return errors.New("获取人员信息失败")
599
+	}
600
+	user.CustomerCoupon = coupons
601
+	details, err := s.ordersdao.GetOrderDetailByUser(caseid, user.UserId)
602
+	if err != nil {
603
+		utils.LogError("获取用户点单信息失败: " + err.Error())
604
+		return errors.New("获取人员信息失败")
605
+	}
606
+	user.OrdersDetail = details
607
+	return nil
608
+}

+ 68
- 0
utils/excel.go 查看文件

@@ -0,0 +1,68 @@
1
+package utils
2
+
3
+import (
4
+	"io"
5
+	"reflect"
6
+
7
+	"github.com/tealeg/xlsx"
8
+)
9
+
10
+// TinyXLSXEngine 简版 xlsx 处理器
11
+type TinyXLSXEngine struct {
12
+	xlsxFile *xlsx.File
13
+	toSlice  func(interface{}) []interface{}
14
+}
15
+
16
+// NewTinyXLSXEngine init
17
+func NewTinyXLSXEngine() *TinyXLSXEngine {
18
+	return &TinyXLSXEngine{}
19
+}
20
+
21
+// SetTransFunc 设置转换函数
22
+func (t *TinyXLSXEngine) SetTransFunc(f func(interface{}) []interface{}) *TinyXLSXEngine {
23
+	t.toSlice = f
24
+	return t
25
+}
26
+
27
+// SetData 设置数据
28
+func (t *TinyXLSXEngine) SetData(data interface{}) *TinyXLSXEngine {
29
+	file := xlsx.NewFile()
30
+	t.xlsxFile = file
31
+
32
+	sheet, err := file.AddSheet("sheet1")
33
+	if err != nil {
34
+		LogError("创建 xlsx sheet 失败: " + err.Error())
35
+		return t
36
+	}
37
+
38
+	if t.toSlice == nil {
39
+		t.toSlice = func(dt interface{}) []interface{} {
40
+			return nil
41
+		}
42
+	}
43
+
44
+	v := reflect.ValueOf(data)
45
+	if v.Kind() == reflect.Ptr {
46
+		v.Elem()
47
+	}
48
+
49
+	if v.Kind() == reflect.Slice && v.IsValid() {
50
+		l := v.Len()
51
+		for i := 0; i < l; i++ {
52
+			rowData := v.Index(i).Interface()
53
+			cols := t.toSlice(rowData)
54
+
55
+			row := sheet.AddRow()
56
+			for _, col := range cols {
57
+				row.AddCell().SetValue(col)
58
+			}
59
+		}
60
+	}
61
+
62
+	return t
63
+}
64
+
65
+// Write 写数据
66
+func (t *TinyXLSXEngine) Write(w io.Writer) error {
67
+	return t.xlsxFile.Write(w)
68
+}

+ 48
- 0
utils/jwt.go 查看文件

@@ -2,10 +2,16 @@ package utils
2 2
 
3 3
 import (
4 4
 	"errors"
5
+	"time"
5 6
 
6 7
 	jwt "github.com/dgrijalva/jwt-go"
7 8
 )
8 9
 
10
+const (
11
+	TokenHeader = "Authorization"
12
+	TokenSchema = "Bearer"
13
+)
14
+
9 15
 var tokenSignedKey = []byte(`Yansen is so handsome!`)
10 16
 
11 17
 // CreateToken 获取token
@@ -32,3 +38,45 @@ func PareseToken(token string) (map[string]interface{}, error) {
32 38
 
33 39
 	return nil, errors.New("Token 解析 未知错误")
34 40
 }
41
+
42
+// JWTToken token 内容
43
+type JWTToken struct {
44
+	Guest    bool
45
+	ID       string
46
+	Password string
47
+	Expire   time.Time
48
+}
49
+
50
+// ToMap 转 map
51
+func (t *JWTToken) ToMap() map[string]interface{} {
52
+	return map[string]interface{}{
53
+		"guest":    t.Guest,
54
+		"user":     t.ID,
55
+		"password": t.Password,
56
+		"exp":      t.Expire.Format("2006-01-02 15:04:05"),
57
+	}
58
+}
59
+
60
+// MapToJWTToken map 映射 Token
61
+func MapToJWTToken(data map[string]interface{}) *JWTToken {
62
+	token := JWTToken{}
63
+
64
+	if data["guest"] != nil {
65
+		token.Guest = data["guest"].(bool)
66
+	}
67
+
68
+	if data["user"] != nil {
69
+		token.ID = data["user"].(string)
70
+	}
71
+
72
+	if data["password"] != nil {
73
+		token.Password = data["password"].(string)
74
+	}
75
+
76
+	if data["exp"] != nil {
77
+		exp, _ := time.Parse("2006-01-02 15:04:05", data["exp"].(string))
78
+		token.Expire = exp
79
+	}
80
+
81
+	return &token
82
+}

+ 56
- 0
utils/wechat.go 查看文件

@@ -6,6 +6,17 @@ import (
6 6
 
7 7
 var wxClients map[string]*wx.Client
8 8
 
9
+type WechatUser struct {
10
+	OpenID     string  `json:"openid"`
11
+	NickName   string  `json:"nickname"`
12
+	Sex        float64 `json:"sex"`
13
+	Province   string  `json:"province"`
14
+	City       string  `json:"city"`
15
+	Country    string  `json:"country"`
16
+	HeadImgURL string  `json:"headimgurl"`
17
+	UnionID    string  `json:"unionid"`
18
+}
19
+
9 20
 // WxClientSingleton 初始化
10 21
 func WxClientSingleton(org string, cert map[string]string) {
11 22
 	if wxClients == nil {
@@ -32,3 +43,48 @@ func GetWxAppID(org string) string {
32 43
 func init() {
33 44
 	wx.SetLogInst(defaultLogger)
34 45
 }
46
+
47
+// MapToWechatUser 映射微信人员
48
+func MapToWechatUser(data map[string]interface{}) *WechatUser {
49
+	subscribe, has := data["subscribe"]
50
+	if has {
51
+		if subscribe == nil {
52
+			return nil
53
+		}
54
+
55
+		sub := subscribe.(float64)
56
+		if sub == 0 {
57
+			return nil
58
+		}
59
+	}
60
+
61
+	user := WechatUser{
62
+		OpenID: data["openid"].(string),
63
+	}
64
+
65
+	if data["sex"] != nil {
66
+		user.Sex = data["sex"].(float64)
67
+	}
68
+
69
+	if data["province"] != nil {
70
+		user.Province = data["province"].(string)
71
+	}
72
+
73
+	if data["city"] != nil {
74
+		user.City = data["city"].(string)
75
+	}
76
+
77
+	if data["country"] != nil {
78
+		user.Country = data["country"].(string)
79
+	}
80
+
81
+	if data["headimgurl"] != nil {
82
+		user.HeadImgURL = data["headimgurl"].(string)
83
+	}
84
+
85
+	if data["unionid"] != nil {
86
+		user.UnionID = data["unionid"].(string)
87
+	}
88
+
89
+	return &user
90
+}