zjxpcyc 6 лет назад
Родитель
Сommit
e1279d43d8
100 измененных файлов: 4846 добавлений и 539 удалений
  1. 29
    0
      bootstrap/bootstrap.go
  2. 3
    1
      conf/app.conf
  3. 3
    2
      conf/db.conf
  4. 5
    0
      conf/wechat.conf
  5. 0
    21
      controllers/base.go
  6. 2
    7
      controllers/bodycheck/bodycheck.go
  7. 14
    1
      controllers/card/card.go
  8. 16
    12
      controllers/config.go
  9. 14
    1
      controllers/coupon/coupon.go
  10. 20
    6
      controllers/course/order.go
  11. 25
    0
      controllers/cros.go
  12. 2
    3
      controllers/customer/customer.go
  13. 75
    0
      controllers/customerremark/customerremark.go
  14. 49
    0
      controllers/file.go
  15. 217
    0
      controllers/flashbuy/flashbuy.go
  16. 23
    13
      controllers/goods/order.go
  17. 134
    1
      controllers/luckdraw/luckdraw.go
  18. 17
    2
      controllers/marketing/marketing.go
  19. 3
    1
      controllers/statistics/cardcoupon.go
  20. 9
    0
      controllers/user/user.go
  21. 1
    1
      controllers/verify/verify.go
  22. 21
    8
      controllers/vipcard/vipcard.go
  23. 4
    1
      main.go
  24. 16
    1
      models/card/card.go
  25. 1
    1
      models/channel/channel.go
  26. 64
    1
      models/constant.go
  27. 29
    3
      models/coupon/coupon.go
  28. 23
    7
      models/course/order.go
  29. 17
    0
      models/customer/account.go
  30. 35
    1
      models/customer/customer.go
  31. 1
    0
      models/customer/types.go
  32. 35
    0
      models/customer/vip.go
  33. 148
    0
      models/customerremark/customerremark.go
  34. 351
    0
      models/flashbuy/flashbuy.go
  35. 47
    44
      models/goods/orders.go
  36. 7
    0
      models/goods/types.go
  37. 678
    63
      models/luckdraw/luckdraw.go
  38. 2
    2
      models/luckdrawlist/luckdrawlist.go
  39. 11
    0
      models/marketing/marketing.go
  40. 1
    0
      models/model/sys_activity_action.go
  41. 13
    12
      models/model/sys_user.go
  42. 19
    0
      models/model/ta_customer_flash_buy.go
  43. 24
    0
      models/model/ta_customer_vip.go
  44. 22
    0
      models/model/ta_customer_vip_change.go
  45. 26
    0
      models/model/ta_flash_buy.go
  46. 14
    0
      models/model/ta_flash_buy_customer.go
  47. 23
    12
      models/model/ta_luckdraw.go
  48. 16
    0
      models/model/ta_luckdraw_customer.go
  49. 9
    0
      models/model/ta_luckdraw_img.go
  50. 4
    0
      models/model/ta_luckdraw_prize.go
  51. 18
    12
      models/model/ta_luckdraw_record.go
  52. 10
    0
      models/model/ta_luckdraw_tpl.go
  53. 17
    0
      models/model/ta_prize_default.go
  54. 19
    0
      models/model/ta_sale_customer.go
  55. 16
    0
      models/model/ta_sale_customer_remark.go
  56. 2
    0
      models/model/ta_vip_card.go
  57. 4
    0
      models/model/ta_vip_card_child.go
  58. 10
    0
      models/model/td_flashbuy_model.go
  59. 8
    5
      models/models.go
  60. 9
    9
      models/statistics/cardcoupon.go
  61. 2
    1
      models/statistics/goods.go
  62. 16
    0
      models/sys.go
  63. 40
    10
      models/system/user.go
  64. 43
    2
      models/vipcard/vipcard.go
  65. 32
    3
      routers/common.go
  66. 4
    3
      routers/guest.go
  67. 16
    5
      routers/router.go
  68. 25
    3
      routers/wechat.go
  69. 84
    11
      service/card/card.go
  70. 83
    11
      service/coupon/coupon.go
  71. 3
    0
      service/course/course.go
  72. 142
    54
      service/course/order.go
  73. 84
    63
      service/customer/customer.go
  74. 90
    0
      service/customerremark/customerremark.go
  75. 1
    0
      service/events/constant.go
  76. 38
    11
      service/events/events.go
  77. 85
    0
      service/events/giveCard.go
  78. 9
    6
      service/events/giveCoupon.go
  79. 377
    0
      service/flashbuy/flashbuy.go
  80. 3
    0
      service/goods/goods.go
  81. 150
    40
      service/goods/orders.go
  82. 331
    4
      service/luckdraw/luckdraw.go
  83. 29
    9
      service/marketing/marketing.go
  84. 0
    1
      service/sys.go
  85. 53
    24
      service/user.go
  86. 66
    3
      service/vipcard/vipcard.go
  87. 46
    0
      tests/cases_test.go
  88. 74
    0
      tests/courseorder_test.go
  89. 70
    0
      tests/goodsorder_test.go
  90. 27
    0
      tests/tests.go
  91. 231
    0
      tests/utils.go
  92. 1
    5
      utils/captcha.go
  93. 15
    0
      utils/configer.go
  94. 4
    8
      utils/log.go
  95. 24
    3
      utils/message.go
  96. 13
    0
      utils/rand.go
  97. 63
    0
      utils/rand_test.go
  98. 1
    5
      utils/sms.go
  99. 36
    0
      utils/utils.go
  100. 0
    0
      utils/wechat.go

+ 29
- 0
bootstrap/bootstrap.go Просмотреть файл

@@ -0,0 +1,29 @@
1
+package bootstrap
2
+
3
+import (
4
+	"spaceofcheng/services/models"
5
+	"spaceofcheng/services/routers"
6
+	"spaceofcheng/services/service/events"
7
+	"spaceofcheng/services/utils"
8
+)
9
+
10
+// SystemInit 系统初始化
11
+func SystemInit() {
12
+	// 数据库连接
13
+	models.InitDB()
14
+
15
+	// 系统日志
16
+	utils.LogInit()
17
+
18
+	// 微信系统
19
+	utils.WechatInit()
20
+
21
+	// 消息系统
22
+	utils.MessageInit()
23
+
24
+	// 事件系统
25
+	events.EventInit()
26
+
27
+	// 路由系统
28
+	routers.RouteInit()
29
+}

+ 3
- 1
conf/app.conf Просмотреть файл

@@ -5,13 +5,15 @@ autorender = false
5 5
 copyrequestbody = true
6 6
 EnableDocs = true
7 7
 excelpath = ./
8
-clienturl = http://dev.ycjcjy.com/c-v2
8
+clienturl = http://dev.ycjcjy.com/
9 9
 
10 10
 postwechatInfo = http://testapi.chioy.com.cn/api/network/postwechatInfo
11 11
 qrcodePrefix = bodycheck_
12 12
 followText = 您正在使用悦琦设备进行体检~
13 13
 resultURL = http://spaceofcheng.ycjcjy.com/wechat/bodyCheck.html
14 14
 
15
+defaultShareUserID = 1
16
+
15 17
 [cros]
16 18
 allowMode = dev
17 19
 allowCredentials = true

+ 3
- 2
conf/db.conf Просмотреть файл

@@ -5,8 +5,9 @@ db_type      = mysql
5 5
 con_protocol = tcp
6 6
 
7 7
 ; 数据库地址,可以使用IP
8
-db_addr      = 192.168.0.122
9
-# db_addr      = localhost
8
+db_addr      = 47.101.36.130
9
+# db_addr        = 192.168.0.122
10
+; db_addr = localhost
10 11
 # db_addr      = rm-uf6z3z6jq11x653d77o.mysql.rds.aliyuncs.com
11 12
 
12 13
 ; 端口

+ 5
- 0
conf/wechat.conf Просмотреть файл

@@ -1 +1,6 @@
1 1
 messageTplID = EB1Bto8JmW-vC-A0NTe8NtxgMFm6s86l3g2Bc-1OP6U
2
+
3
+# 中奖ID
4
+luckdrawMessageTplID = 8t7WQTrx-D566ohRD6RgdMkiu8DUiAxG_Jajg33YHVI
5
+luckdrawNoticeURL = http://dev.ycjcjy.com/game/luckdraw/#/lotteryList?tab=1
6
+flashBuyNoticeURL = http://dev.ycjcjy.com/game/luckdraw/#/lotteryList?tab=2

+ 0
- 21
controllers/base.go Просмотреть файл

@@ -97,27 +97,6 @@ func (c *BaseController) ResponseData(data interface{}, msg interface{}, code in
97 97
 	c.StopRun()
98 98
 }
99 99
 
100
-// Options 解决跨域先发送 options
101
-func (c *BaseController) Options() {
102
-	c.ResponseJSON("")
103
-}
104
-
105
-// crosPolicy 跨域策略
106
-func (c *BaseController) crosPolicy() {
107
-	runMode := beego.AppConfig.String("runmode")
108
-	allowMode := beego.AppConfig.String("cros::allowMode")
109
-	allowMethods := beego.AppConfig.String("cros::allowMethods")
110
-	allowOrigin := beego.AppConfig.String("cros::allowOrigin")
111
-	allowCredentials := beego.AppConfig.String("cros::allowCredentials")
112
-
113
-	if runMode == allowMode {
114
-		c.Ctx.Output.Header("Access-Control-Allow-Origin", allowOrigin)
115
-		c.Ctx.Output.Header("Access-Control-Allow-Methods", allowMethods)
116
-		c.Ctx.Output.Header("Access-Control-Allow-Credentials", allowCredentials)
117
-		c.Ctx.Output.Header("Access-Control-Allow-Headers", "X-Token,Authorization")
118
-	}
119
-}
120
-
121 100
 // initAppController 执行当前路由请求对应的 Controller 初始化
122 101
 func (c *BaseController) initController() {
123 102
 	if ctrl, ok := c.AppController.(ControllerInterface); ok {

+ 2
- 7
controllers/bodycheck/bodycheck.go Просмотреть файл

@@ -14,9 +14,9 @@ import (
14 14
 
15 15
 // 二维码不多次获取, 只获取一次即可
16 16
 // 临时的解决方案是放到全局单例对象中
17
-var qrCodes map[string]string
17
+var qrCodes = make(map[string]string)
18 18
 
19
-var mtx *sync.Mutex
19
+var mtx = new(sync.Mutex)
20 20
 
21 21
 // BodyCheckController 商品
22 22
 type BodyCheckController struct {
@@ -105,8 +105,3 @@ func (c *BodyCheckController) PostCheckResult() {
105 105
 		"Message": "",
106 106
 	})
107 107
 }
108
-
109
-func init() {
110
-	qrCodes = make(map[string]string)
111
-	mtx = new(sync.Mutex)
112
-}

+ 14
- 1
controllers/card/card.go Просмотреть файл

@@ -38,7 +38,11 @@ func (c *CardController) ListByCase() {
38 38
 		pagesize = 10
39 39
 	}
40 40
 
41
-	list, total, err := c.serv.GetCardList(caseid, page, pagesize)
41
+	sendtype := c.GetString("sendtype")
42
+	usetype := c.GetString("usetype")
43
+	usedid := c.GetString("usedid")
44
+
45
+	list, total, err := c.serv.GetCardList(caseid, sendtype, usetype, usedid, page, pagesize)
42 46
 	if err != nil {
43 47
 		c.ResponseError(err)
44 48
 	}
@@ -266,3 +270,12 @@ func (c *CardController) GetCustomerCardByCustomerAndSale() {
266 270
 	}
267 271
 	c.ResponseJSON(cards)
268 272
 }
273
+
274
+func (c *CardController) GetSysCardList() {
275
+	caseid := c.GetString(":caseId")
276
+	cards, err := c.serv.GetSysCardList(caseid)
277
+	if err != nil {
278
+		c.ResponseError(err)
279
+	}
280
+	c.ResponseJSON(cards)
281
+}

+ 16
- 12
controllers/config.go Просмотреть файл

@@ -3,44 +3,48 @@ package controllers
3 3
 import (
4 4
 	"spaceofcheng/services/utils"
5 5
 
6
-	"github.com/astaxie/beego"
7 6
 	"github.com/astaxie/beego/config"
8 7
 )
9 8
 
10 9
 // 配置文件列表
11 10
 const (
11
+	AppConf    = "app"
12 12
 	AliYunConf = "aliyun"
13 13
 	WeChatConf = "wechat"
14 14
 	SMSConf    = "sms"
15 15
 )
16 16
 
17 17
 func (c *BaseController) initConfig() {
18
-	c.RunMode = beego.AppConfig.String("runmode")
18
+	// c.RunMode = beego.AppConfig.String("runmode")
19 19
 
20 20
 	if c.Configer == nil {
21 21
 		c.Configer = make(map[string]config.Configer)
22 22
 	}
23 23
 
24
+	// 系统
25
+	appConf, _ := utils.GetConfiger("conf/app.conf")
26
+	if appConf != nil {
27
+		c.Configer[AppConf] = appConf
28
+	}
29
+
30
+	c.RunMode = appConf.String("runmode")
31
+
24 32
 	// 阿里云
25
-	aliConf := c.getConfig("conf/aliyun.conf")
33
+	aliConf, _ := utils.GetConfiger("conf/aliyun.conf")
26 34
 	if aliConf != nil {
27 35
 		c.Configer[AliYunConf] = aliConf
28 36
 	}
29 37
 
30 38
 	// 短信
31
-	smsConf := c.getConfig("conf/sms.conf")
39
+	smsConf, _ := utils.GetConfiger("conf/sms.conf")
32 40
 	if smsConf != nil {
33 41
 		c.Configer[SMSConf] = smsConf
34 42
 	}
35 43
 	utils.ResetSMSEngine(smsConf)
36
-}
37 44
 
38
-func (c *BaseController) getConfig(confPath string) config.Configer {
39
-	aliConf, err := config.NewConfig("ini", confPath)
40
-	if err != nil {
41
-		utils.LogError("读取配置文件失败: " + err.Error())
42
-		return nil
45
+	// 微信
46
+	wechatConf, _ := utils.GetConfiger("conf/wechat.conf")
47
+	if wechatConf != nil {
48
+		c.Configer[WeChatConf] = wechatConf
43 49
 	}
44
-
45
-	return aliConf
46 50
 }

+ 14
- 1
controllers/coupon/coupon.go Просмотреть файл

@@ -39,7 +39,11 @@ func (c *CouponController) ListByCase() {
39 39
 		pagesize = 10
40 40
 	}
41 41
 
42
-	list, total, err := c.serv.GetCouponList(caseID, page, pagesize)
42
+	sendtype := c.GetString("sendtype")
43
+	usetype := c.GetString("usetype")
44
+	usedid := c.GetString("usedid")
45
+
46
+	list, total, err := c.serv.GetCouponList(caseID, sendtype, usetype, usedid, page, pagesize)
43 47
 	if err != nil {
44 48
 		c.ResponseError(err)
45 49
 	}
@@ -277,3 +281,12 @@ func (c *CouponController) GetCustomerCouponByCustomerAndSale() {
277 281
 	}
278 282
 	c.ResponseJSON(Coupons)
279 283
 }
284
+
285
+func (c *CouponController) GetSysCouponByCase() {
286
+	caseId := c.GetString(":caseId")
287
+	coupon, err := c.serv.GetSysCouponByCase(caseId)
288
+	if err != nil {
289
+		c.ResponseError(err)
290
+	}
291
+	c.ResponseJSON(coupon)
292
+}

+ 20
- 6
controllers/course/order.go Просмотреть файл

@@ -8,6 +8,7 @@ import (
8 8
 	"spaceofcheng/services/utils"
9 9
 )
10 10
 
11
+// 下单
11 12
 func (c *CourseController) PostOrder() {
12 13
 	// 订单主信息
13 14
 	info := c.GetString("info")
@@ -15,10 +16,6 @@ func (c *CourseController) PostOrder() {
15 16
 		c.ResponseError(errors.New("无有效订单信息"))
16 17
 	}
17 18
 
18
-	// 订单优惠券
19
-	customercouponid := c.GetString("customercouponid")
20
-
21
-	//
22 19
 	var orderInfo model.TaCourseOrders
23 20
 	//	var orderCoupon []model.TaCourseOrdersCoupon
24 21
 
@@ -39,10 +36,27 @@ func (c *CourseController) PostOrder() {
39 36
 			http.StatusNotAcceptable,
40 37
 		)
41 38
 	}
39
+	newOrders, err := c.serv.PreOrders(&orderInfo)
40
+	if err != nil {
41
+		c.ResponseError(err)
42
+	}
43
+
44
+	c.ResponseJSON(newOrders)
45
+}
46
+
47
+// ConfirmOrders 确认订单
48
+func (c *CourseController) ConfirmOrders() {
49
+
50
+	// 订单优惠券
51
+	customercouponid := c.GetString("customercouponid")
52
+
53
+	// 订单id
54
+	ordersid := c.GetString(":ordersid")
42 55
 
43
-	if err := c.serv.Orders(&orderInfo, customercouponid); err != nil {
56
+	err := c.serv.ConfirmOrders(ordersid, customercouponid)
57
+	if err != nil {
44 58
 		c.ResponseError(err)
45 59
 	}
46 60
 
47
-	c.ResponseJSON("ok")
61
+	c.ResponseJSON("下单成功!")
48 62
 }

+ 25
- 0
controllers/cros.go Просмотреть файл

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

+ 2
- 3
controllers/customer/customer.go Просмотреть файл

@@ -110,8 +110,7 @@ func (c *CustomerController) SignIn() {
110 110
 func (c *CustomerController) SignUp() {
111 111
 	phone := c.GetString("phone")
112 112
 	captcha := c.GetString("captcha")
113
-	csID := c.GetString("case")
114
-	arID := c.GetString("sales")
113
+	recommendCode := c.GetString("recommendCode")
115 114
 
116 115
 	if phone == "" || captcha == "" {
117 116
 		c.ResponseError(errors.New("请填写完整注册信息"))
@@ -125,7 +124,7 @@ func (c *CustomerController) SignUp() {
125 124
 
126 125
 	userMapping := c.Context.Get("userMap").(model.TaUserMapping)
127 126
 
128
-	_, err := c.serv.BindWechatCust(&userMapping, phone, csID, arID)
127
+	_, err := c.serv.BindWechatCust(&userMapping, phone, recommendCode)
129 128
 	if err != nil {
130 129
 		c.ResponseError(err)
131 130
 	}

+ 75
- 0
controllers/customerremark/customerremark.go Просмотреть файл

@@ -0,0 +1,75 @@
1
+package customerremark
2
+
3
+import (
4
+	"spaceofcheng/services/controllers"
5
+	"spaceofcheng/services/models/model"
6
+	"spaceofcheng/services/service/customerremark"
7
+)
8
+
9
+// CaseController 信息
10
+type CustomerRemarkController struct {
11
+	dao *customerremark.CustomerRemarkServ
12
+	controllers.BaseController
13
+}
14
+
15
+// Constructor 初始化 Controller
16
+// @Title Constructor
17
+// @Description 初始化 Controller, 系统自动调用
18
+func (c *CustomerRemarkController) Constructor() {
19
+	c.dao = customerremark.NewCustomerRemarkServ(c.Context)
20
+}
21
+
22
+func (c *CustomerRemarkController) GetCustomerRemarkList() {
23
+	salesId := c.GetString(":salesId")
24
+	customerId := c.GetString(":customerId")
25
+	page, _ := c.GetInt("page")
26
+	pageSize, _ := c.GetInt("pagesize")
27
+	list, err := c.dao.GetCustomerRemarkList(salesId, customerId, page, pageSize)
28
+	if err != nil {
29
+		c.ResponseError(err)
30
+	}
31
+	c.ResponseJSON(list)
32
+}
33
+
34
+func (c *CustomerRemarkController) GetCustomerReceiveRecord() {
35
+	salesId := c.GetString(":salesId")
36
+	customerId := c.GetString(":customerId")
37
+	page, _ := c.GetInt("page")
38
+	pageSize, _ := c.GetInt("pagesize")
39
+	list, err := c.dao.GetCustomerReceiveRecord(salesId, customerId, page, pageSize)
40
+	if err != nil {
41
+		c.ResponseError(err)
42
+	}
43
+	c.ResponseJSON(list)
44
+}
45
+
46
+func (c *CustomerRemarkController) AddRemark() {
47
+	remark := model.TaSaleCustomerRemark{}
48
+	if err := c.ParseForm(&remark); err != nil {
49
+		c.ResponseError(err)
50
+	}
51
+	newRemark, err := c.dao.AddRemark(remark)
52
+	if err != nil {
53
+		c.ResponseError(err)
54
+	}
55
+	c.ResponseJSON(newRemark)
56
+}
57
+
58
+func (c *CustomerRemarkController) IsExist() {
59
+	recommendCode := c.GetString(":recommendCode")
60
+	num, err := c.dao.IsExist(recommendCode)
61
+	if err != nil {
62
+		c.ResponseError(err)
63
+	}
64
+	c.ResponseJSON(num)
65
+}
66
+
67
+func (c *CustomerRemarkController) SearchCustomer() {
68
+	salesId := c.GetString(":salesId")
69
+	customerInfo := c.GetString(":customerInfo")
70
+	customer, err := c.dao.SearchCustomer(customerInfo, salesId)
71
+	if err != nil {
72
+		c.ResponseError(err)
73
+	}
74
+	c.ResponseJSON(customer)
75
+}

+ 49
- 0
controllers/file.go Просмотреть файл

@@ -72,3 +72,52 @@ func (c *BaseController) SaveToExcel(fn string, excel *utils.TinyXLSXEngine) {
72 72
 	c.destroyContext(true)
73 73
 	c.StopRun()
74 74
 }
75
+
76
+// UploadBase64Image Upload base64-image to ali-oss
77
+// @Title Upload image to ali-oss
78
+// @Description 上传base64图片到阿里云
79
+// @Param   UpImgStr     form    string  true        "图片控件name"
80
+// @Success 200 { Url } 图片URL
81
+// @Failure >300 error message
82
+func (c *BaseController) UploadBase64Image() {
83
+	base64Str, err := url.QueryUnescape(c.GetString("base64str"))
84
+	if err != nil {
85
+		c.ResponseError(utils.LogError("上传 Base64 图片失败", err))
86
+	}
87
+
88
+	imgURL, err := c.uploadStringToAliOSS(base64Str)
89
+	if err != nil {
90
+		c.ResponseError(err)
91
+	}
92
+
93
+	resp := map[string]interface{}{
94
+		"url": imgURL,
95
+	}
96
+
97
+	c.ResponseJSON(resp)
98
+}
99
+
100
+// uploadStringToAliOSS 上传文件到阿里云
101
+func (c *BaseController) uploadStringToAliOSS(fStr string) (string, error) {
102
+	aliConf, ok := c.Configer[AliYunConf]
103
+	if !ok {
104
+		return "", errors.New("没有找到阿里云相关配置")
105
+	}
106
+
107
+	endpoint := aliConf.String("oss::Endpoint")
108
+	accessKeyID := aliConf.String("oss::AccessKeyId")
109
+	accessKeySecret := aliConf.String("oss::AccessKeySecret")
110
+	bucket := aliConf.String("oss::Bucket")
111
+
112
+	aliCli, err := utils.GetOssClient(endpoint, accessKeyID, accessKeySecret)
113
+	if err != nil {
114
+		return "", utils.LogError("配置阿里云客户端失败", err)
115
+	}
116
+
117
+	fileURL, err := utils.UploadStringToBucket(aliCli, bucket, fStr)
118
+	if err != nil {
119
+		return "", utils.LogError("上传文件到阿里云失败", err)
120
+	}
121
+
122
+	return fileURL, nil
123
+}

+ 217
- 0
controllers/flashbuy/flashbuy.go Просмотреть файл

@@ -0,0 +1,217 @@
1
+package flashbuy
2
+
3
+import (
4
+	"encoding/json"
5
+	"errors"
6
+	"net/http"
7
+	"spaceofcheng/services/controllers"
8
+	"spaceofcheng/services/models/model"
9
+	"spaceofcheng/services/service/flashbuy"
10
+	"spaceofcheng/services/utils"
11
+)
12
+
13
+// CaseController 信息
14
+type FlashBuyController struct {
15
+	dao *flashbuy.FlashBuyServ
16
+	controllers.BaseController
17
+}
18
+
19
+// Constructor 初始化 Controller
20
+// @Title Constructor
21
+// @Description 初始化 Controller, 系统自动调用
22
+func (c *FlashBuyController) Constructor() {
23
+	c.dao = flashbuy.NewFlashBuyServ(c.Context)
24
+}
25
+func (c *FlashBuyController) GetFlashBuyList() {
26
+	caseIDs := c.GetString("caseid")
27
+	if caseIDs == "" {
28
+		cases := c.Context.Get("cases").([]model.SysUserCase)
29
+		caseIDs = c.GetCaseIDs(cases)
30
+	}
31
+	flashBuyName := c.GetString("flashbuyname")
32
+	flashBuyStatus := c.GetString("flashbuystatus")
33
+	page, _ := c.GetInt("page")
34
+	pageSize, _ := c.GetInt("pagesize")
35
+	list, err := c.dao.GetFlashBuyList(caseIDs, flashBuyName, flashBuyStatus, page, pageSize)
36
+	if err != nil {
37
+		c.ResponseError(err)
38
+	}
39
+	c.ResponseJSON(list)
40
+}
41
+
42
+func (c *FlashBuyController) GetCustomerFlashBuyByCustomerId() {
43
+	userRaw := c.Context.Get("customer")
44
+	if userRaw == nil {
45
+		c.ResponseError(errors.New("系统内部错误"), http.StatusInternalServerError)
46
+	}
47
+
48
+	user := userRaw.(model.TaCustomer)
49
+	customerId := user.CustomerId
50
+	page, _ := c.GetInt("page")
51
+	pageSize, _ := c.GetInt("pagesize")
52
+	list, err := c.dao.GetCustomerFlashBuyByCustomerId(customerId, page, pageSize)
53
+	if err != nil {
54
+		c.ResponseError(err)
55
+	}
56
+	c.ResponseJSON(list)
57
+}
58
+
59
+func (c *FlashBuyController) GetCustomerFlashBuyList() {
60
+	flashBuyId := c.GetString(":flashBuyId")
61
+	phone := c.GetString("phone")
62
+	page, _ := c.GetInt("page")
63
+	pageSize, _ := c.GetInt("pagesize")
64
+	list, err := c.dao.GetCustomerFlashBuyById(flashBuyId, phone, page, pageSize)
65
+	if err != nil {
66
+		c.ResponseError(err)
67
+	}
68
+	c.ResponseJSON(list)
69
+
70
+}
71
+
72
+// GetFlashBuyById 获取抢购详情
73
+func (c *FlashBuyController) GetFlashBuyById() {
74
+	flashBuyId := c.GetString(":flashBuyId")
75
+	flashBuy, err := c.dao.GetFlashBuyById(flashBuyId)
76
+	if err != nil {
77
+		c.ResponseError(err)
78
+	}
79
+
80
+	c.ResponseJSON(flashBuy)
81
+}
82
+
83
+// GetWechatFlashBuyById
84
+func (c *FlashBuyController) GetWechatFlashBuyById() {
85
+	flashBuyId := c.GetString(":flashBuyId")
86
+	cust := c.Context.Get("customer").(model.TaCustomer)
87
+	flashBuy, err := c.dao.GetFlashBuyById(flashBuyId)
88
+	if err != nil {
89
+		c.ResponseError(err)
90
+	}
91
+	userinfo, err := c.dao.GetFlashByUser(flashBuyId)
92
+	if err != nil {
93
+		c.ResponseError(err)
94
+	}
95
+	flashCustomer, err := c.dao.IsFlashBuyCustomer(cust.CustomerId, flashBuyId)
96
+	if err != nil {
97
+		c.ResponseError(err)
98
+	}
99
+	c.ResponseJSON(map[string]interface{}{
100
+		"flashBuy":      flashBuy,
101
+		"userInfo":      userinfo,
102
+		"flashCustomer": flashCustomer,
103
+	})
104
+}
105
+
106
+func (c *FlashBuyController) GetCustomerFlashBuyId() {
107
+	flashBuyId := c.GetString(":customerFlashBuyId")
108
+	flashBuy, err := c.dao.GetCustomerFlashBuyId(flashBuyId)
109
+	if err != nil {
110
+		c.ResponseError(err)
111
+	}
112
+	c.ResponseJSON(flashBuy)
113
+}
114
+
115
+func (c *FlashBuyController) SaveFlashBuy() {
116
+	jsnStr := c.GetString("info")
117
+	if jsnStr == "" {
118
+		c.ResponseError(errors.New("未接收到保存内容"))
119
+	}
120
+	info := model.TaFlashBuy{}
121
+	if err := json.Unmarshal([]byte(jsnStr), &info); err != nil {
122
+		utils.LogError("抢购数据转换失败: " + err.Error())
123
+		c.ResponseError(err)
124
+	}
125
+	newFlashBuy, err := c.dao.SaveFlashBuy(info)
126
+	if err != nil {
127
+		c.ResponseError(err)
128
+	}
129
+	c.ResponseJSON(newFlashBuy)
130
+}
131
+
132
+func (c *FlashBuyController) DeleteFlashBuy() {
133
+	flashBuyId := c.GetString(":flashBuyId")
134
+	err := c.dao.DeleteFlashBuy(flashBuyId)
135
+	if err != nil {
136
+		c.ResponseError(err)
137
+	}
138
+	c.ResponseJSON("删除成功")
139
+}
140
+
141
+func (c *FlashBuyController) UpdateFlashBuy() {
142
+	flashBuyId := c.GetString(":flashBuyId")
143
+	flashBuyStatus := c.GetString(":flashBuyStatus")
144
+	err := c.dao.UpdateFlashBuy(flashBuyId, flashBuyStatus)
145
+	if err != nil {
146
+		c.ResponseError(err)
147
+	}
148
+	c.ResponseJSON("修改成功")
149
+}
150
+
151
+func (c *FlashBuyController) VerifyCustomerFlashBuyList() {
152
+	qrcode := c.GetString(":qrcode")
153
+	caseids := c.GetString(":caseId")
154
+	customerFlashBuy, err := c.dao.VerifyCustomerFlashBuyList(qrcode, caseids)
155
+	if err != nil {
156
+		c.ResponseError(err)
157
+	}
158
+	c.ResponseJSON(customerFlashBuy)
159
+}
160
+func (c *FlashBuyController) Verify() {
161
+	customerFlashBuyId := c.GetString(":customerFlashBuyId")
162
+	err := c.dao.Verify(customerFlashBuyId)
163
+	if err != nil {
164
+		c.ResponseError(err)
165
+	}
166
+	c.ResponseJSON("核销成功")
167
+}
168
+
169
+// FlashBuy 抢购
170
+func (c *FlashBuyController) FlashBuy() {
171
+	id := c.GetString(":id")
172
+
173
+	c.Context.Set("clienturl", c.Configer[controllers.WeChatConf].String("flashBuyNoticeURL"))
174
+	c.Context.Set("tplid", c.Configer[controllers.WeChatConf].String("luckdrawMessageTplID"))
175
+
176
+	err := c.dao.FlashBuy(id)
177
+	if err != nil {
178
+		c.ResponseError(err)
179
+	}
180
+	c.ResponseJSON("恭喜您!抢购成功!")
181
+}
182
+
183
+func (c *FlashBuyController) GetFlashModelList() {
184
+	model, err := c.dao.GetFlashModelList()
185
+	if err != nil {
186
+		c.ResponseError(err)
187
+	}
188
+	c.ResponseJSON(model)
189
+}
190
+
191
+func (c *FlashBuyController) AddNewFlashBuyCustomer() {
192
+	cust := c.Context.Get("customer").(model.TaCustomer)
193
+	flashBuyId := c.GetString(":flashBuyId")
194
+	err := c.dao.AddNewFlashBuyCustomer(cust, flashBuyId)
195
+	if err != nil {
196
+		c.ResponseError(err)
197
+	}
198
+	c.ResponseJSON("添加成功")
199
+}
200
+
201
+func (c *FlashBuyController) UpdateFlashBuyCustomer() {
202
+	cust := c.Context.Get("customer").(model.TaCustomer)
203
+	flashBuyId := c.GetString(":flashBuyId")
204
+	err := c.dao.UpdateFlashBuyCustomer(cust.CustomerId, flashBuyId)
205
+	if err != nil {
206
+		c.ResponseError(err)
207
+	}
208
+	c.ResponseJSON("修改成功")
209
+}
210
+
211
+func (c *FlashBuyController) IsNewCustomer() {
212
+	cust := c.Context.Get("customer").(model.TaCustomer)
213
+	if cust.Phone == "" {
214
+		c.ResponseError(errors.New("不是新用户"))
215
+	}
216
+	c.ResponseJSON("是新用户")
217
+}

+ 23
- 13
controllers/goods/order.go Просмотреть файл

@@ -12,7 +12,7 @@ import (
12 12
 	"time"
13 13
 )
14 14
 
15
-var mtx *sync.Mutex
15
+var mtx = new(sync.Mutex)
16 16
 
17 17
 // GetOrderList 获取商品订单
18 18
 // 管理端 - 统计查询
@@ -107,12 +107,6 @@ func (c *GoodsController) PostOrder() {
107 107
 		c.ResponseError(errors.New("无有效订单详情信息"))
108 108
 	}
109 109
 
110
-	// 订单优惠券
111
-	customercouponid := c.GetString("customercouponid")
112
-	if customercouponid == "undefined" {
113
-		customercouponid = ""
114
-	}
115
-
116 110
 	//
117 111
 	var orderInfo model.TaGoodsOrders
118 112
 	var orderDetail []model.TaGoodsOrdersDetail
@@ -140,11 +134,31 @@ func (c *GoodsController) PostOrder() {
140 134
 		)
141 135
 	}
142 136
 
143
-	if err := c.serv.Orders(&orderInfo, orderDetail, customercouponid, innerUser); err != nil {
137
+	newOrders, err := c.serv.PreOrders(&orderInfo, orderDetail, innerUser)
138
+	if err != nil {
144 139
 		c.ResponseError(err)
145 140
 	}
146 141
 
147
-	c.ResponseJSON("ok")
142
+	c.ResponseJSON(newOrders)
143
+}
144
+
145
+// ConfirmOrders 确认下单
146
+func (c *GoodsController) ConfirmOrders() {
147
+	ordersID := c.GetString(":ordersid")
148
+
149
+	// 备注
150
+	remark := c.GetString("remark")
151
+
152
+	// 订单优惠券
153
+	customercouponid := c.GetString("customercouponid")
154
+	if customercouponid == "undefined" {
155
+		customercouponid = ""
156
+	}
157
+	if err := c.serv.ConfirmOrder(ordersID, customercouponid, remark); err != nil {
158
+		c.ResponseError(err)
159
+	}
160
+
161
+	c.ResponseJSON("下单成功")
148 162
 }
149 163
 
150 164
 // GetOrdersByRecord 根据月记录导出订单信息
@@ -298,7 +312,3 @@ func (c *GoodsController) UpdateOrdersIntimidate() {
298 312
 	}
299 313
 	c.ResponseJSON("操作成功!")
300 314
 }
301
-
302
-func init() {
303
-	mtx = new(sync.Mutex)
304
-}

+ 134
- 1
controllers/luckdraw/luckdraw.go Просмотреть файл

@@ -1,13 +1,17 @@
1 1
 package luckdraw
2 2
 
3 3
 import (
4
+	"encoding/json"
4 5
 	"errors"
5 6
 	"net/http"
6 7
 	"spaceofcheng/services/controllers"
8
+	"spaceofcheng/services/models"
7 9
 	"spaceofcheng/services/models/customer"
10
+	luckdrawModel "spaceofcheng/services/models/luckdraw"
8 11
 	"spaceofcheng/services/models/model"
9 12
 	"spaceofcheng/services/service/luckdraw"
10 13
 	"spaceofcheng/services/utils"
14
+	"strconv"
11 15
 )
12 16
 
13 17
 // LuckdrawController 应用
@@ -25,6 +29,117 @@ func (c *LuckDrawController) Constructor() {
25 29
 	c.custDAO = customer.NewCustomerDAO(c.Context)
26 30
 }
27 31
 
32
+// GetLuckDrawTpl 获取抽奖模板
33
+func (c *LuckDrawController) GetLuckDrawTpl() {
34
+	tpls, err := c.serv.GetLuckDrawTpl()
35
+	if err != nil {
36
+		c.ResponseError(err)
37
+	}
38
+	c.ResponseJSON(tpls)
39
+}
40
+
41
+// GetLuckDrawList 获取抽奖列表
42
+func (c *LuckDrawController) GetLuckDrawList() {
43
+	caseids := c.GetString("caseid")
44
+	if caseids == "" {
45
+		cases := c.Context.Get("cases").([]model.SysUserCase)
46
+		caseids = c.GetCaseIDs(cases)
47
+	}
48
+	page, _ := c.GetInt("page")
49
+	pageSize, _ := c.GetInt("pagesize")
50
+	name := c.GetString("name")
51
+	status := c.GetString("status")
52
+	list, err := c.serv.GetLuckDrawList(caseids, name, status, page, pageSize)
53
+	if err != nil {
54
+		c.ResponseError(err)
55
+	}
56
+	c.ResponseJSON(list)
57
+}
58
+
59
+// GetLuckDrawRecordList 获取抽奖记录列表
60
+func (c *LuckDrawController) GetLuckDrawRecordList() {
61
+	luckdrawid := c.GetString(":luckdrawid")
62
+	page, _ := c.GetInt("page")
63
+	pageSize, _ := c.GetInt("pagesize")
64
+	tel := c.GetString("tel")
65
+	list, err := c.serv.GetLuckDrawRecordList(luckdrawid, tel, page, pageSize)
66
+	if err != nil {
67
+		c.ResponseError(err)
68
+	}
69
+	c.ResponseJSON(list)
70
+}
71
+
72
+// GetLuckDrawShareList 获取抽奖分享记录列表
73
+func (c *LuckDrawController) GetLuckDrawShareList() {
74
+	luckdrawid := c.GetString(":luckdrawid")
75
+	page, _ := c.GetInt("page")
76
+	pageSize, _ := c.GetInt("pagesize")
77
+	tel := c.GetString("tel")
78
+	list, err := c.serv.GetLuckDrawShareList(luckdrawid, tel, page, pageSize)
79
+	if err != nil {
80
+		c.ResponseError(err)
81
+	}
82
+	c.ResponseJSON(list)
83
+}
84
+
85
+// GetLuckDrawByID 根据id获取抽奖信息
86
+func (c *LuckDrawController) GetLuckDrawByID() {
87
+	id := c.GetString(":luckdrawid")
88
+	luckdraw, err := c.serv.GetLuckDrawInfoByID(id)
89
+	if err != nil {
90
+		c.ResponseError(err)
91
+	}
92
+	c.ResponseJSON(luckdraw)
93
+}
94
+
95
+// SaveLuckDraw 保存抽奖信息
96
+func (c *LuckDrawController) SaveLuckDraw() {
97
+	jsnStr := c.GetString("info")
98
+	if jsnStr == "" {
99
+		c.ResponseError(errors.New("未接收到保存内容"))
100
+	}
101
+	info := luckdrawModel.LuckDrawInfo{}
102
+	if err := json.Unmarshal([]byte(jsnStr), &info); err != nil {
103
+		utils.LogError("抽奖数据转换失败: " + err.Error())
104
+		c.ResponseError(err)
105
+	}
106
+	newinfo, err := c.serv.SaveLuckDraw(&info)
107
+	if err != nil {
108
+		c.ResponseError(err)
109
+	}
110
+	c.ResponseJSON(newinfo)
111
+}
112
+
113
+// DelLuckDraw 删除抽奖信息
114
+func (c *LuckDrawController) DelLuckDraw() {
115
+	luckdrawid := c.GetString(":luckdrawid")
116
+	err := c.serv.DelLuckDraw(luckdrawid)
117
+	if err != nil {
118
+		c.ResponseError(err)
119
+	}
120
+	c.ResponseJSON("操作成功!")
121
+}
122
+
123
+// OpenLuckDraw 抽奖启用
124
+func (c *LuckDrawController) OpenLuckDraw() {
125
+	luckdrawid := c.GetString(":luckdrawid")
126
+	err := c.serv.OpenLuckDraw(luckdrawid)
127
+	if err != nil {
128
+		c.ResponseError(err)
129
+	}
130
+	c.ResponseJSON("操作成功!")
131
+}
132
+
133
+// StopLuckDraw 抽奖启用
134
+func (c *LuckDrawController) StopLuckDraw() {
135
+	luckdrawid := c.GetString(":luckdrawid")
136
+	err := c.serv.StopLuckDraw(luckdrawid)
137
+	if err != nil {
138
+		c.ResponseError(err)
139
+	}
140
+	c.ResponseJSON("操作成功!")
141
+}
142
+
28 143
 // GetUserByCode 根据code获取用户信息
29 144
 func (c *LuckDrawController) GetUserByCode() {
30 145
 	userRaw := c.Context.Get("customer")
@@ -34,7 +149,7 @@ func (c *LuckDrawController) GetUserByCode() {
34 149
 
35 150
 	user := userRaw.(model.TaCustomer)
36 151
 	luckdrawid := c.GetString(":id")
37
-	record, err := c.serv.GetUserLuckDrawByLuckDraw(user.CustomerId, luckdrawid)
152
+	record, set, err := c.serv.GetUserLuckDrawByLuckDraw(user, luckdrawid)
38 153
 	if err != nil {
39 154
 		utils.LogError("获取用户抽奖信息失败: " + err.Error())
40 155
 		c.ResponseError(errors.New("获取用户抽奖信息失败"))
@@ -52,6 +167,7 @@ func (c *LuckDrawController) GetUserByCode() {
52 167
 		"user":   user,
53 168
 		"record": record,
54 169
 		"detail": detail,
170
+		"set":    set,
55 171
 	})
56 172
 }
57 173
 
@@ -76,6 +192,9 @@ func (c *LuckDrawController) LuckDraw() {
76 192
 
77 193
 	user := userRaw.(model.TaCustomer)
78 194
 
195
+	c.Context.Set("clienturl", c.Configer[controllers.WeChatConf].String("luckdrawNoticeURL"))
196
+	c.Context.Set("tplid", c.Configer[controllers.WeChatConf].String("luckdrawMessageTplID"))
197
+
79 198
 	prize, detail, err := c.serv.LuckDraw(id, &user)
80 199
 	if err != nil {
81 200
 		c.ResponseError(err)
@@ -249,5 +368,19 @@ func (c *LuckDrawController) SaveShareRecord() {
249 368
 		)
250 369
 	}
251 370
 
371
+	fromIsNew := c.GetString("isnew")
372
+
373
+	// 分享可以增加抽奖次数
374
+	if luckdraw.ShareType == models.SHARETYPE_NEWUSER && fromIsNew == strconv.Itoa(models.BOOL_TRUE) {
375
+		if err := c.serv.UpdateShareNum(luckdraw, fromID); err != nil {
376
+			utils.LogError("更新抽奖次数失败: " + err.Error())
377
+			c.ResponseData(
378
+				errIgnore,
379
+				"保存分享记录失败",
380
+				http.StatusBadRequest,
381
+			)
382
+		}
383
+	}
384
+
252 385
 	c.ResponseJSON("ok")
253 386
 }

+ 17
- 2
controllers/marketing/marketing.go Просмотреть файл

@@ -23,8 +23,11 @@ func (c *MarketingController) Constructor() {
23 23
 func (c *MarketingController) GetMarketingList() {
24 24
 	page, _ := c.GetInt("page")
25 25
 	pageSize, _ := c.GetInt("pageSize")
26
-	cases := c.Context.Get("cases").([]model.SysUserCase)
27
-	caseIDs := c.GetCaseIDs(cases)
26
+	caseIDs := c.GetString("caseid")
27
+	if caseIDs == "" {
28
+		cases := c.Context.Get("cases").([]model.SysUserCase)
29
+		caseIDs = c.GetCaseIDs(cases)
30
+	}
28 31
 	marketings, err := c.serv.GetMarketingList(caseIDs, page, pageSize)
29 32
 	if err != nil {
30 33
 		c.ResponseError(err)
@@ -43,10 +46,12 @@ func (c *MarketingController) SaveMarketing() {
43 46
 	activityType := c.GetString("activityType")
44 47
 	activeType := c.GetString("activeType")
45 48
 	resourceDesc := c.GetString("resourceDesc") // 活动描述
49
+	caseId := c.GetString("CaseId")
46 50
 
47 51
 	// 赋值
48 52
 	marketing.ActivityName = activityName
49 53
 	marketing.ActivityType = activityType
54
+	marketing.CaseId = caseId
50 55
 
51 56
 	newInfo, _, err := c.serv.SaveMarketing(marketing, activeType, resourceDesc)
52 57
 	if err != nil {
@@ -116,3 +121,13 @@ func (c *MarketingController) SetMarketingDisable() {
116 121
 	}
117 122
 	c.ResponseJSON("操作成功!")
118 123
 }
124
+
125
+func (c *MarketingController) GetUserCases() {
126
+	cases := c.Context.Get("cases").([]model.SysUserCase)
127
+	caseIDs := c.GetCaseIDs(cases)
128
+	sysCase, err := c.serv.GetUserCases(caseIDs)
129
+	if err != nil {
130
+		c.ResponseError(err)
131
+	}
132
+	c.ResponseJSON(sysCase)
133
+}

+ 3
- 1
controllers/statistics/cardcoupon.go Просмотреть файл

@@ -150,6 +150,7 @@ func (c *StatisticsController) CardCouponUsedStatisticsExcel() {
150 150
 		"获取方式",
151 151
 		"微信昵称",
152 152
 		"手机号",
153
+		"销售",
153 154
 		"有效期",
154 155
 		"获取时间",
155 156
 		"使用时间",
@@ -163,7 +164,7 @@ func (c *StatisticsController) CardCouponUsedStatisticsExcel() {
163 164
 		case "event":
164 165
 			receivetype = "系统"
165 166
 			break
166
-		case "case":
167
+		case "sales":
167 168
 			receivetype = "案场"
168 169
 			break
169 170
 		case "channel":
@@ -197,6 +198,7 @@ func (c *StatisticsController) CardCouponUsedStatisticsExcel() {
197 198
 			receivetype,
198 199
 			item.CustomerName,
199 200
 			item.Phone,
201
+			item.SalesName,
200 202
 			item.EndDate.Format("2006-01-02 15:04:05"),
201 203
 			item.ReceiveDate.Format("2006-01-02 15:04:05"),
202 204
 			item.UsedDate.Format("2006-01-02 15:04:05"),

+ 9
- 0
controllers/user/user.go Просмотреть файл

@@ -314,3 +314,12 @@ func (c *UserController) GetCaseUserByID() {
314 314
 	}
315 315
 	c.ResponseJSON(userdetail)
316 316
 }
317
+
318
+func (c *UserController) GetMyRecommendCode() {
319
+	user := c.Context.Get("user").(model.SysUser)
320
+	if user.UserId == "" {
321
+		utils.LogError("获取人员推荐码失败")
322
+		c.ResponseError(errors.New("获取人员推荐码失败"))
323
+	}
324
+	c.ResponseJSON(user.RecommendCode)
325
+}

+ 1
- 1
controllers/verify/verify.go Просмотреть файл

@@ -71,7 +71,7 @@ func (c *VerifyController) VerifyCourse() {
71 71
 			c.ResponseError(err)
72 72
 		}
73 73
 		if customerCard.VerifyStatus == models.VERIFY_USEABLE {
74
-			if customerCard.EndDate.After(time.Now()) {
74
+			if customerCard.EndDate.Before(time.Now()) {
75 75
 				customerCard.VerifyStatus = models.VERIFY_LATE
76 76
 				err := c.dao.UpdateCustomerCard(customerCard)
77 77
 				if err != nil {

+ 21
- 8
controllers/vipcard/vipcard.go Просмотреть файл

@@ -6,8 +6,8 @@ import (
6 6
 	"spaceofcheng/services/models"
7 7
 	"spaceofcheng/services/models/model"
8 8
 	"spaceofcheng/services/service/vipcard"
9
-	"time"
10 9
 	"spaceofcheng/services/utils"
10
+	"time"
11 11
 )
12 12
 
13 13
 // CaseController 信息
@@ -69,6 +69,10 @@ func (c *VipcardController) UserCharge() {
69 69
 		c.ResponseError(err)
70 70
 	}
71 71
 
72
+	if vipChild.Status != models.STATUS_READY {
73
+		c.ResponseError(errors.New("Vip卡已被激活!"))
74
+	}
75
+
72 76
 	customer, err := c.dao.FindCustomerByTel(tel)
73 77
 	if err != nil {
74 78
 		c.ResponseError(err)
@@ -91,10 +95,15 @@ func (c *VipcardController) UserCharge() {
91 95
 	if err != nil {
92 96
 		c.ResponseError(err)
93 97
 	}
94
-	err = c.dao.CustomerCharge(vipChild, createUser)
98
+	// 插入客户VIP卡
99
+	err = c.dao.SaveCustomerVip(vipChild, createUser)
95 100
 	if err != nil {
96 101
 		c.ResponseError(err)
97 102
 	}
103
+	// err = c.dao.CustomerCharge(vipChild, createUser)
104
+	// if err != nil {
105
+	// 	c.ResponseError(err)
106
+	// }
98 107
 	c.ResponseJSON("激活成功")
99 108
 
100 109
 }
@@ -109,9 +118,8 @@ func (c *VipcardController) GetVipByCode() {
109 118
 	c.ResponseJSON(vipChild)
110 119
 }
111 120
 
112
-
113 121
 // GetVipListExcel 导出VIP 列表
114
-func (c *VipcardController) GetVipListExcel(){
122
+func (c *VipcardController) GetVipListExcel() {
115 123
 
116 124
 	caseids := c.GetString("caseid")
117 125
 	if caseids == "" {
@@ -154,7 +162,7 @@ func (c *VipcardController) GetVipListExcel(){
154 162
 		statusToString := ""
155 163
 		if item.Status == 1 {
156 164
 			statusToString = "已激活"
157
-		}else{
165
+		} else {
158 166
 			statusToString = "未激活"
159 167
 		}
160 168
 
@@ -173,6 +181,11 @@ func (c *VipcardController) GetVipListExcel(){
173 181
 
174 182
 }
175 183
 
176
-
177
-
178
-
184
+// GetCustomerVips 获取客户vip卡
185
+func (c *VipcardController) GetCustomerVips() {
186
+	vips, err := c.dao.GetCustomerVips()
187
+	if err != nil {
188
+		c.ResponseError(err)
189
+	}
190
+	c.ResponseJSON(vips)
191
+}

+ 4
- 1
main.go Просмотреть файл

@@ -1,7 +1,7 @@
1 1
 package main
2 2
 
3 3
 import (
4
-	_ "spaceofcheng/services/routers"
4
+	"spaceofcheng/services/bootstrap"
5 5
 
6 6
 	"github.com/astaxie/beego"
7 7
 )
@@ -11,5 +11,8 @@ func main() {
11 11
 		beego.BConfig.WebConfig.DirectoryIndex = true
12 12
 		beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger"
13 13
 	}
14
+
15
+	bootstrap.SystemInit()
16
+
14 17
 	beego.Run()
15 18
 }

+ 16
- 1
models/card/card.go Просмотреть файл

@@ -481,7 +481,7 @@ func (m *CardDAO) GetCustomerCardByCustomerAndSaleCount(customerid, saleid strin
481 481
 // GetCustomerCardByCustomerAndSale 获取用户的领取记录
482 482
 func (m *CardDAO) GetCustomerCardByCustomerAndSale(customerid, saleid string, page, pageSize int) ([]model.TaCustomerCard, error) {
483 483
 	var customerCard []model.TaCustomerCard
484
-	err := m.db.Where("customer_id=?", customerid).And("sales_id=?", saleid).Desc("status").Limit(pageSize, (page-1)*pageSize).Find(&customerCard)
484
+	err := m.db.Where("customer_id=?", customerid).And("sales_id=?", saleid).OrderBy("status asc,receive_date desc").Limit(pageSize, (page-1)*pageSize).Find(&customerCard)
485 485
 	return customerCard, err
486 486
 }
487 487
 
@@ -528,3 +528,18 @@ func (m *CardDAO) SaveCardChannel(channelid, cardid string) error {
528 528
 	_, err := m.db.Insert(&cardChannel)
529 529
 	return err
530 530
 }
531
+
532
+func (m *CardDAO) GetSysCardList(caseid string) ([]model.TaCouponCard, error) {
533
+	var card []model.TaCouponCard
534
+	sql := `SELECT
535
+	* 
536
+FROM
537
+	ta_coupon_card 
538
+WHERE
539
+	send_type = '` + models.GIVE_TYPE_SYSTEM + `'
540
+	and case_id = '` + caseid + `'
541
+	and  status > ` + strconv.Itoa(models.STATUS_DEL)
542
+	err := m.db.Sql(sql).Find(&card)
543
+	return card, err
544
+
545
+}

+ 1
- 1
models/channel/channel.go Просмотреть файл

@@ -46,7 +46,7 @@ func (m *ChannelDAO) GetChannels(caseid string, page int, pageSize int) ([]Chann
46 46
 	from ta_channel a 
47 47
 	inner join sys_case b on a.case_id = b.case_id 
48 48
 	where a.case_id in('` + strings.Replace(caseid, ",", "','", -1) + `') and  a.status > ` + strconv.Itoa(models.STATUS_DEL)
49
-	sql += ` order by a.create_date desc limit ` + strconv.Itoa(page-1) + `, ` + strconv.Itoa(pageSize)
49
+	sql += ` order by a.create_date desc limit ` + strconv.Itoa((page-1)*pageSize) + `, ` + strconv.Itoa(pageSize)
50 50
 	err := m.db.Sql(sql).Find(&channels)
51 51
 	return channels, err
52 52
 }

+ 64
- 1
models/constant.go Просмотреть файл

@@ -55,7 +55,7 @@ const (
55 55
 	CONSUME_INNER       = "sys user"
56 56
 	CONSUME_COUPON      = "coupon"
57 57
 	CONSUME_POINTS      = "points"
58
-	CONSUME_COINCHG     = "cheng-coin"
58
+	CONSUME_COINCHG     = "cheng-coin" // 城币就是 VIP
59 59
 	CONSUME_COUPON_COIN = "coupon-coin"
60 60
 )
61 61
 
@@ -172,8 +172,71 @@ const (
172 172
 const (
173 173
 	QRCODE_TYPE_COURSE = "course"
174 174
 	QRCODE_TYPE_PRIZE  = "prize"
175
+	QRCODE_TYPE_FLASH  = "flash"
175 176
 )
176 177
 
177 178
 const (
178 179
 	ADMIN_ID = "1"
179 180
 )
181
+
182
+// 奖品类型
183
+const (
184
+	PRIZE_TYPE_COUPONCARD = "couponcard"
185
+	PRIZE_TYPE_THIRD      = "third"
186
+
187
+	PRIZE_TYPE_COUPON = "coupon"
188
+	PRIZE_TYPE_CARD   = "card"
189
+)
190
+
191
+// 参与类型设置
192
+const (
193
+	JOINTYPE_NEWUSER = "newuser"
194
+	JOINTYPE_NO      = "no"
195
+)
196
+
197
+// 抽奖分享设置
198
+const (
199
+	SHARETYPE_NEWUSER = "newuser"
200
+	SHARETYE_NO       = "no"
201
+)
202
+
203
+// 抢购用户类型
204
+const (
205
+	FLASHBUY_USER_NEW = "newuser"
206
+	FLASHBUY_USER_NO  = "no"
207
+)
208
+
209
+// 抽奖次数类型
210
+const (
211
+	NUMTYPE_REPART    = "repeat"
212
+	NUMTYPE_NOTREPART = "no_repeat"
213
+)
214
+
215
+const (
216
+	FLASH_BUY_ACTIVE   = "active"
217
+	FLASH_BUY_INACTIVE = "inactive"
218
+	FLASH_BUY_OVER     = "over"
219
+)
220
+
221
+const (
222
+	FLASH_VALIDATE_DAYS = "days"
223
+	FLASH_VALIDATE_DATE = "date"
224
+)
225
+
226
+const (
227
+	COUPONCARD_USETYPE_LUCKDRAW = "luckdraw"
228
+	COUPONCARD_USETYPE_SYS      = "sysactive"
229
+)
230
+
231
+const (
232
+	// 送券
233
+	ActGiveCoupon = "giveCoupon"
234
+	ActGiveCard   = "giveCard"
235
+)
236
+
237
+// 抽奖次数间隔
238
+const (
239
+	INTERVAL_DAY   = "day"
240
+	INTERVAL_WEEK  = "week"
241
+	INTERVAL_MONTH = "month"
242
+)

+ 29
- 3
models/coupon/coupon.go Просмотреть файл

@@ -236,6 +236,18 @@ func (m *CouponDAO) SaveCustomerCoupons(cps []model.TaCustomerCoupon) error {
236 236
 	return nil
237 237
 }
238 238
 
239
+// IncreseCouponUsedNum 增加优惠券使用数量
240
+func (m *CouponDAO) IncreseCouponUsedNum(cpID string, num ...int) error {
241
+	sql := `update ta_coupon set used_count=used_count+? where coupon_id=?`
242
+	numAdd := 1
243
+	if len(num) > 0 && num[0] != 0 {
244
+		numAdd = num[0]
245
+	}
246
+
247
+	_, err := m.db.Exec(sql, numAdd, cpID)
248
+	return err
249
+}
250
+
239 251
 // CheckCustCoupon 检查客户是否已经有了该卡券
240 252
 // 如果用户有了卡券, 但是用过了,或者卡券过期了,仍然可以再次拥有
241 253
 func (m *CouponDAO) CheckCustCoupon(custID, couponID string, startDate, endDate time.Time) ([]model.TaCustomerCoupon, error) {
@@ -301,7 +313,7 @@ func (m *CouponDAO) GetCouponBySendType(caseids, sendtype string) ([]model.TaCou
301 313
 // GetCaseUsableCoupon 获取案场可用优惠券信息
302 314
 func (m *CouponDAO) GetCaseUsableCoupon(caseid, userid string, page, pageSize int) ([]CaseCouponDetail, error) {
303 315
 	var Coupons []CaseCouponDetail
304
-	sql := `select * from ta_coupon where case_id=? and status=? and DATE_FORMAT(end_date, '%Y-%m-%d')>=DATE_FORMAT(NOW(), '%Y-%m-%d') and send_type=? order by create_date desc limit ` + strconv.Itoa((page-1)*pageSize) + `, ` + strconv.Itoa(pageSize)
316
+	sql := `select * from ta_coupon where case_id=? and status=? and (DATE_FORMAT(end_date, '%Y-%m-%d')>=DATE_FORMAT(NOW(), '%Y-%m-%d') or valid_days>0) and send_type=? order by create_date desc limit ` + strconv.Itoa((page-1)*pageSize) + `, ` + strconv.Itoa(pageSize)
305 317
 	err := m.db.Sql(sql, caseid, models.STATUS_NORMAL, models.GIVE_TYPE_CASE).Find(&Coupons)
306 318
 	for inx, coupon := range Coupons {
307 319
 		if userid != "" {
@@ -330,7 +342,7 @@ func (m *CouponDAO) GetCouponShareByCouponID(couponid string) (*model.TaCouponSh
330 342
 // GetCaseUsableCouponCount 获取案场可用优惠券数量
331 343
 func (m *CouponDAO) GetCaseUsableCouponCount(caseid, userid string) (int, error) {
332 344
 	var Coupons []CaseCouponDetail
333
-	sql := `select * from ta_coupon where case_id=? and status=? and DATE_FORMAT(end_date, '%Y-%m-%d')>=DATE_FORMAT(NOW(), '%Y-%m-%d') and send_type=?`
345
+	sql := `select * from ta_coupon where case_id=? and status=? and (DATE_FORMAT(end_date, '%Y-%m-%d')>=DATE_FORMAT(NOW(), '%Y-%m-%d') or valid_days>0) and send_type=?`
334 346
 	err := m.db.Sql(sql, caseid, models.STATUS_NORMAL, models.GIVE_TYPE_CASE).Find(&Coupons)
335 347
 
336 348
 	return len(Coupons), err
@@ -530,7 +542,7 @@ func (m *CouponDAO) GetCustomerCouponByCustomerAndSaleCount(customerid, saleid s
530 542
 // GetCustomerCouponByCustomerAndSale 获取用户的领取记录
531 543
 func (m *CouponDAO) GetCustomerCouponByCustomerAndSale(customerid, saleid string, page, pageSize int) ([]model.TaCustomerCoupon, error) {
532 544
 	var customerCoupon []model.TaCustomerCoupon
533
-	err := m.db.Where("customer_id=?", customerid).And("sales_id=?", saleid).Desc("status").Limit(pageSize, (page-1)*pageSize).Find(&customerCoupon)
545
+	err := m.db.Where("customer_id=?", customerid).And("sales_id=?", saleid).OrderBy("status asc,receive_date desc").Limit(pageSize, (page-1)*pageSize).Find(&customerCoupon)
534 546
 	return customerCoupon, err
535 547
 }
536 548
 
@@ -574,3 +586,17 @@ func (m *CouponDAO) SaveCouponChannel(channelid, couponid string) error {
574 586
 	_, err := m.db.Insert(&couponChannel)
575 587
 	return err
576 588
 }
589
+
590
+func (m *CouponDAO) GetSysCouponByCase(caseid string) ([]model.TaCoupon, error) {
591
+	var coupon []model.TaCoupon
592
+	sql := `SELECT
593
+	* 
594
+FROM
595
+	ta_coupon 
596
+WHERE
597
+	send_type = '` + models.GIVE_TYPE_SYSTEM + `'
598
+	and case_id = '` + caseid + `'
599
+	and status > ` + strconv.Itoa(models.STATUS_DEL)
600
+	err := m.db.Sql(sql).Find(&coupon)
601
+	return coupon, err
602
+}

+ 23
- 7
models/course/order.go Просмотреть файл

@@ -12,7 +12,7 @@ import (
12 12
 )
13 13
 
14 14
 // SaveCourseOrder 保存订单
15
-func (m *CourseDAO) SaveCourseOrder(order *model.TaCourseOrders) error {
15
+func (m *CourseDAO) SaveCourseOrder(order *model.TaCourseOrders) (*model.TaCourseOrders, error) {
16 16
 
17 17
 	if order.OrdersId == "" {
18 18
 		order.OrdersId = guid.NewGUIDString()
@@ -26,7 +26,7 @@ func (m *CourseDAO) SaveCourseOrder(order *model.TaCourseOrders) error {
26 26
 	order.OrdersNo = ordersno
27 27
 	order.CreateDate = time.Now()
28 28
 	_, err := m.db.Insert(order)
29
-	return err
29
+	return order, err
30 30
 }
31 31
 
32 32
 // GetOrderByID 根据id获取订单明细
@@ -62,12 +62,28 @@ func (m *CourseDAO) SaveOrdersCoupon(coupon *model.TaCourseOrdersCoupon, order *
62 62
 	coupon.OrdersCouponId = utils.GetGUID()
63 63
 	coupon.Status = models.STATUS_NORMAL
64 64
 	coupon.CreateDate = time.Now().Local()
65
-	if _, err := m.db.Insert(coupon); err != nil {
66
-		return err
65
+	_, err := m.db.Insert(coupon)
66
+	return err
67
+}
68
+
69
+// UpdateOrderPay 更新订单为已支付
70
+func (m *CourseDAO) UpdateOrderPay(info *model.TaCourseOrders) error {
71
+	if info.ActualAmount == "" {
72
+		info.ActualAmount = "0.0"
67 73
 	}
68 74
 
69
-	// 更新优惠券已使用信息
70
-	sql := `update ta_coupon set used_count=used_count+1 where coupon_id='` + coupon.CouponId + `'`
71
-	_, err := m.db.Exec(sql)
75
+	if info.CouponAmount == "" {
76
+		info.CouponAmount = "0.0"
77
+	}
78
+
79
+	info.IsPay = models.BOOL_TRUE
80
+	info.Status = models.STATUS_NORMAL
81
+	var cols = []string{
82
+		"is_pay",
83
+		"status",
84
+		"actual_amount",
85
+		"coupon_amount",
86
+	}
87
+	_, err := m.db.Cols(cols...).Where("orders_id=?", info.OrdersId).Update(info)
72 88
 	return err
73 89
 }

+ 17
- 0
models/customer/account.go Просмотреть файл

@@ -124,3 +124,20 @@ func (m *CustomerDAO) GetAccountByCust(id string) (*model.TaCustomerAccount, err
124 124
 
125 125
 	return acc, nil
126 126
 }
127
+
128
+// GetCustomerVipAmount 获取用户vip金额
129
+func (m *CustomerDAO) GetCustomerVipAmount(id string) (string, error) {
130
+	type amount struct {
131
+		Balance string
132
+	}
133
+	sql := `select sum(balance) as balance from ta_customer_vip where customer_id=?`
134
+	var vip = amount{}
135
+	_, err := m.db.Sql(sql, id).Get(&vip)
136
+	if err != nil {
137
+		return "0.00", err
138
+	}
139
+	if vip.Balance == "" {
140
+		vip.Balance = "0.00"
141
+	}
142
+	return vip.Balance, nil
143
+}

+ 35
- 1
models/customer/customer.go Просмотреть файл

@@ -5,6 +5,7 @@ import (
5 5
 	"spaceofcheng/services/models"
6 6
 	"spaceofcheng/services/models/model"
7 7
 	"spaceofcheng/services/utils"
8
+	"strconv"
8 9
 	"strings"
9 10
 	"time"
10 11
 
@@ -128,7 +129,7 @@ func (m *CustomerDAO) GetCustWithWXByOpenID(openid string) (*CustWithWX, error)
128 129
 
129 130
 	cust := CustWithWX{}
130 131
 	query := `
131
-	SELECT a.*,b.*, b.user_id as map_user,c.type_id as user_type_id,e.real_name
132
+	SELECT a.*,b.*, b.user_id as map_user,c.type_id as user_type_id,e.real_name,e.recommend_code
132 133
 	FROM
133 134
 		ta_user_mapping a
134 135
 	LEFT JOIN ta_customer b ON a.user_id = b.customer_id
@@ -262,3 +263,36 @@ func (m *CustomerDAO) GetCustomerByID(id string) (*model.TaCustomer, error) {
262 263
 
263 264
 	return cust, nil
264 265
 }
266
+
267
+func (m *CustomerDAO) GetSalesByRecommendCode(recommendCode string) (*model.SysUser, error) {
268
+	if recommendCode == "" {
269
+		return nil, errors.New("获取相关人员信息失败")
270
+	}
271
+	user := model.SysUser{}
272
+	has, err := m.db.Where("recommend_code=?", recommendCode).Get(&user)
273
+	if err != nil {
274
+		return nil, err
275
+	}
276
+
277
+	if !has {
278
+		return nil, nil
279
+	}
280
+
281
+	return &user, nil
282
+}
283
+
284
+func (m *CustomerDAO) GetSalesCaseById(userId string) (*model.SysUserCase, error) {
285
+	var userCase []model.SysUserCase
286
+	sql := `SELECT
287
+	* 
288
+FROM
289
+	sys_user_case 
290
+WHERE
291
+	is_belong = 1 
292
+	AND user_id = '` + userId + `'and status > ` + strconv.Itoa(models.STATUS_DEL)
293
+	err := m.db.Sql(sql).Find(&userCase)
294
+	if len(userCase) <= 0 {
295
+		return nil, err
296
+	}
297
+	return &userCase[0], err
298
+}

+ 1
- 0
models/customer/types.go Просмотреть файл

@@ -14,4 +14,5 @@ type CustWithWX struct {
14 14
 	BelongCaseId        string
15 15
 	BelongCaseStatus    int
16 16
 	RealName            string
17
+	RecommendCode       string
17 18
 }

+ 35
- 0
models/customer/vip.go Просмотреть файл

@@ -0,0 +1,35 @@
1
+package customer
2
+
3
+import (
4
+	"spaceofcheng/services/models"
5
+	"spaceofcheng/services/models/model"
6
+	"time"
7
+)
8
+
9
+// GetValidVIPCards 依据客户ID 获取 VIP 卡
10
+// 按照过期时间升序, 即 将到期的在最上面
11
+// VIP 卡可以跨案场使用
12
+func (m *CustomerDAO) GetValidVIPCards(custID string) (vips []model.TaCustomerVip, err error) {
13
+	now := time.Now().Local().Format("2006-01-02 15:04:05")
14
+
15
+	err = m.db.Where("customer_id=?", custID).
16
+		And("status=?", models.STATUS_NORMAL).
17
+		And(`DATE_FORMAT(begin_date, "%Y-%m-%d %T")<=?`, now).
18
+		And(`DATE_FORMAT(end_date, "%Y-%m-%d %T")>=?`, now).
19
+		And("balance>0").
20
+		Asc("end_date").
21
+		Find(&vips)
22
+	return
23
+}
24
+
25
+// UpdateCustVipCardAmount 更新VIP账户
26
+func (m *CustomerDAO) UpdateCustVipCardAmount(vip *model.TaCustomerVip, change float64) error {
27
+	sql := `UPDATE ta_customer_vip
28
+		SET balance = balance - ?,
29
+			pay_amount = pay_amount + ?
30
+		WHERE customer_vip_id = ?
31
+	`
32
+
33
+	_, err := m.db.Exec(sql, change, change, vip.CustomerVipId)
34
+	return err
35
+}

+ 148
- 0
models/customerremark/customerremark.go Просмотреть файл

@@ -0,0 +1,148 @@
1
+package customerremark
2
+
3
+import (
4
+	"spaceofcheng/services/models"
5
+	"spaceofcheng/services/models/model"
6
+	"spaceofcheng/services/utils"
7
+	"strconv"
8
+	"time"
9
+
10
+	"github.com/go-xorm/xorm"
11
+)
12
+
13
+// CustomerRemarkDAO 当前数据库操作对象
14
+type CustomerRemarkDAO struct {
15
+	ctx *utils.Context
16
+	db  *xorm.Session
17
+}
18
+type CustomerCardCoupon struct {
19
+	ItemName     string
20
+	VerifyStatus string
21
+	ReceiveDate  time.Time
22
+}
23
+type customerHistory struct {
24
+	model.TaSaleCustomerRemark `xorm:"extends"`
25
+	Name                       string
26
+	CustomerName               string
27
+	Phone                      string
28
+}
29
+
30
+// NewCustomerRemarkDAO New Inst
31
+func NewCustomerRemarkDAO(ctx *utils.Context) *CustomerRemarkDAO {
32
+	return &CustomerRemarkDAO{
33
+		ctx: ctx,
34
+		db:  ctx.DB,
35
+	}
36
+}
37
+func (m *CustomerRemarkDAO) GetRemarkList(salesId, customerId string, page, pageSize int) ([]customerHistory, error) {
38
+	var remark []customerHistory
39
+	sql := `SELECT
40
+	a.*,
41
+	b.name,
42
+	b.customer_name,
43
+	b.phone
44
+FROM
45
+	ta_sale_customer_remark a
46
+	INNER JOIN ta_customer b ON a.customer_id = b.customer_id
47
+WHERE
48
+	a.sales_id = '` + salesId + `'
49
+	and a.customer_id = '` + customerId + `'
50
+	order by a.create_date desc limit ` + strconv.Itoa((page-1)*pageSize) + `, ` + strconv.Itoa(pageSize)
51
+	err := m.db.Sql(sql).Find(&remark)
52
+	return remark, err
53
+}
54
+func (m *CustomerRemarkDAO) GetRemarkListCount(salesId, customerId string) (int, error) {
55
+	var remark []model.TaSaleCustomerRemark
56
+	sql := `SELECT
57
+	* 
58
+FROM
59
+	ta_sale_customer_remark 
60
+WHERE
61
+	sales_id = '` + salesId + `'
62
+	and customer_id = '` + customerId + `'`
63
+	err := m.db.Sql(sql).Find(&remark)
64
+	return len(remark), err
65
+}
66
+
67
+func (m *CustomerRemarkDAO) AddRemark(remark model.TaSaleCustomerRemark) (*model.TaSaleCustomerRemark, error) {
68
+	remark.SalesCustomerRemarkId = utils.GetGUID()
69
+	remark.CreateDate = time.Now()
70
+	remark.Status = models.STATUS_NORMAL
71
+	_, err := m.db.Insert(remark)
72
+	return &remark, err
73
+}
74
+
75
+func (m *CustomerRemarkDAO) SearchCustomer(customerInfo, salesId string) (model.TaCustomer, error) {
76
+	var customer model.TaCustomer
77
+	sql := `SELECT
78
+	* 
79
+FROM
80
+	ta_customer 
81
+WHERE
82
+	(phone = '` + customerInfo + `'
83
+	or name ='` + customerInfo + `')
84
+	and recommend_id = '` + salesId + `'`
85
+	err := m.db.Sql(sql).Find(&customer)
86
+	return customer, err
87
+}
88
+func (m *CustomerRemarkDAO) CustomerReceiveRecord(customerId, salesId string, page, pageSize int) ([]CustomerCardCoupon, error) {
89
+	var customerReceive []CustomerCardCoupon
90
+	sql := `SELECT
91
+	customer_card_name AS item_name,
92
+	verify_status,
93
+	receive_date 
94
+FROM
95
+	ta_customer_card 
96
+	Where customer_id ='` + customerId + `'
97
+	and sales_id = '` + salesId + `'
98
+	UNION
99
+SELECT
100
+	customer_coupon_name AS item_name,
101
+	CASE status 
102
+	WHEN 0 THEN 'expire'
103
+	WHEN 1 THEN 'usable'
104
+	WHEN 2 THEN 'used' END as verify_status,
105
+	receive_date 
106
+FROM
107
+	ta_customer_coupon
108
+	Where customer_id = '` + customerId + `'
109
+	and sales_id = '` + salesId + `'
110
+	order by receive_date desc limit ` + strconv.Itoa((page-1)*pageSize) + `, ` + strconv.Itoa(pageSize)
111
+	err := m.db.Sql(sql).Find(&customerReceive)
112
+	return customerReceive, err
113
+
114
+}
115
+func (m *CustomerRemarkDAO) CustomerReceiveRecordCount(customerId, salesId string) (int, error) {
116
+	var customerReceive []CustomerCardCoupon
117
+	sql := `SELECT
118
+	customer_card_name AS item_name,
119
+	verify_status,
120
+	receive_date 
121
+FROM
122
+	ta_customer_card 
123
+	Where customer_id ='` + customerId + `'
124
+	and sales_id = '` + salesId + `'
125
+	UNION
126
+SELECT
127
+	customer_coupon_name AS item_name,
128
+	CASE status 
129
+	WHEN 0 THEN 'expire'
130
+	WHEN 1 THEN 'usable'
131
+	WHEN 2 THEN 'used' END as verify_status,
132
+	receive_date 
133
+FROM
134
+	ta_customer_coupon
135
+	Where customer_id = '` + customerId + `'
136
+	and sales_id = '` + salesId + `'`
137
+	err := m.db.Sql(sql).Find(&customerReceive)
138
+	return len(customerReceive), err
139
+
140
+}
141
+
142
+func (m *CustomerRemarkDAO) IsExist(recommendCode string) (int, error) {
143
+	var user []model.SysUser
144
+	sql := `select * from sys_user where recommend_code = '` + recommendCode + `' 
145
+	and status > ` + strconv.Itoa(models.STATUS_DEL)
146
+	err := m.db.Sql(sql).Find(&user)
147
+	return len(user), err
148
+}

+ 351
- 0
models/flashbuy/flashbuy.go Просмотреть файл

@@ -0,0 +1,351 @@
1
+package flashbuy
2
+
3
+import (
4
+	"spaceofcheng/services/models"
5
+	"spaceofcheng/services/models/model"
6
+	"spaceofcheng/services/utils"
7
+	"strconv"
8
+	"strings"
9
+	"time"
10
+
11
+	"github.com/go-xorm/xorm"
12
+)
13
+
14
+// FlashbuyDAO 当前数据库操作对象
15
+type FlashbuyDAO struct {
16
+	ctx *utils.Context
17
+	db  *xorm.Session
18
+}
19
+
20
+// NewFlashbuyDAO New Inst
21
+func NewFlashbuyDAO(ctx *utils.Context) *FlashbuyDAO {
22
+	return &FlashbuyDAO{
23
+		ctx: ctx,
24
+		db:  ctx.DB,
25
+	}
26
+}
27
+
28
+type FlashBuy struct {
29
+	model.TaFlashBuy `xorm:"extends"`
30
+	CaseName         string
31
+}
32
+type CustomerFlashBuy struct {
33
+	model.TaCustomerFlashBuy `xorm:"extends"`
34
+	CaseName                 string
35
+	CustomerName             string
36
+	Phone                    string
37
+	FlashBuyName             string
38
+}
39
+type CustomerFlashResult struct {
40
+	model.TaCustomerFlashBuy `xorm:"extends"`
41
+	FlashBuyName             string
42
+}
43
+type CustomerFlashDetail struct {
44
+	model.TaCustomerFlashBuy `xorm:"extends"`
45
+	CustomerQrcode           string
46
+	CaseName                 string
47
+	IsAttend                 int
48
+}
49
+
50
+func (m *FlashbuyDAO) GetFlashBuyList(caseid, flashBuyName, flashBuyStatus string, page, pageSize int) ([]FlashBuy, error) {
51
+	var flashBuy []FlashBuy
52
+	sql := `SELECT
53
+	a.*,
54
+	b.case_name 
55
+FROM
56
+	ta_flash_buy a
57
+	INNER JOIN sys_case b ON a.case_id = b.case_id
58
+	Where a.status > ` + strconv.Itoa(models.STATUS_DEL) + `
59
+	and a.case_id in('` + strings.Replace(caseid, ",", "','", -1) + `')`
60
+	if flashBuyName != "" {
61
+		sql += ` and a.flash_buy_name like '%` + flashBuyName + `%'`
62
+	}
63
+	if flashBuyStatus != "" {
64
+		sql += ` and a.flash_buy_status ='` + flashBuyStatus + `'`
65
+	}
66
+	sql += ` order by a.create_date desc limit ` + strconv.Itoa((page-1)*pageSize) + `, ` + strconv.Itoa(pageSize)
67
+	err := m.db.Sql(sql).Find(&flashBuy)
68
+	return flashBuy, err
69
+}
70
+
71
+func (m *FlashbuyDAO) GetFlashBuyListCount(caseid, flashBuyName, flashBuyStatus string) (int, error) {
72
+	var flashBuy []model.TaFlashBuy
73
+	sql := `SELECT
74
+	a.*
75
+FROM
76
+	ta_flash_buy a
77
+	Where a.status > ` + strconv.Itoa(models.STATUS_DEL) + `
78
+	and a.case_id in('` + strings.Replace(caseid, ",", "','", -1) + `')`
79
+	if flashBuyName != "" {
80
+		sql += ` and a.flash_buy_name like '%` + flashBuyName + `%'`
81
+	}
82
+	if flashBuyStatus != "" {
83
+		sql += ` and a.flash_buy_status ='` + flashBuyStatus + `'`
84
+	}
85
+	err := m.db.Sql(sql).Find(&flashBuy)
86
+	return len(flashBuy), err
87
+}
88
+
89
+func (m *FlashbuyDAO) GetFlashBuyById(flashBuyId string) (*model.TaFlashBuy, error) {
90
+	var flashBuy []model.TaFlashBuy
91
+	err := m.db.Where("flash_buy_id = ?", flashBuyId).And("status > ?", models.STATUS_DEL).Find(&flashBuy)
92
+	if err != nil {
93
+		return nil, err
94
+	}
95
+	if len(flashBuy) > 0 {
96
+		return &flashBuy[0], nil
97
+	}
98
+	return nil, nil
99
+}
100
+
101
+func (m *FlashbuyDAO) AddNewFlashBuy(flashbuy model.TaFlashBuy) (*model.TaFlashBuy, error) {
102
+	flashbuy.FlashBuyId = utils.GetGUID()
103
+	flashbuy.Status = models.STATUS_NORMAL
104
+	flashbuy.CreateDate = time.Now()
105
+	_, err := m.db.Insert(flashbuy)
106
+	return &flashbuy, err
107
+}
108
+
109
+func (m *FlashbuyDAO) DeleteFlashBuy(flashBuyId string) error {
110
+	var flashBuy = model.TaFlashBuy{
111
+		FlashBuyId: flashBuyId,
112
+		Status:     models.STATUS_DEL,
113
+	}
114
+	var cols = []string{
115
+		"status",
116
+	}
117
+	_, err := m.db.Cols(cols...).Where("flash_buy_id = ?", flashBuy.FlashBuyId).Update(flashBuy)
118
+	return err
119
+}
120
+
121
+func (m *FlashbuyDAO) UpdateFlashBuy(flashBuyId, flashBuyStatus string) error {
122
+	var flashBuy = model.TaFlashBuy{
123
+		FlashBuyId:     flashBuyId,
124
+		FlashBuyStatus: flashBuyStatus,
125
+	}
126
+	var cols = []string{
127
+		"flash_buy_status",
128
+	}
129
+	_, err := m.db.Cols(cols...).Where("flash_buy_id =?", flashBuy.FlashBuyId).Update(flashBuy)
130
+	return err
131
+}
132
+
133
+func (m *FlashbuyDAO) EditFlashBuy(flashBuy model.TaFlashBuy) error {
134
+	var cols = []string{
135
+		"flash_buy_name",
136
+		"flash_buy_info",
137
+	}
138
+	_, err := m.db.Cols(cols...).Where("flash_buy_id = ?", flashBuy.FlashBuyId).Update(flashBuy)
139
+	return err
140
+}
141
+func (m *FlashbuyDAO) VerifyFlashBuy(customerFlashBuyId string) error {
142
+	var customerFlashBuy = model.TaCustomerFlashBuy{
143
+		CustomerFlashBuyId: customerFlashBuyId,
144
+		VerifyStatus:       models.VERIFY_USED,
145
+		VerifyDate:         time.Now(),
146
+	}
147
+	var cols = []string{
148
+		"verify_status",
149
+		"verify_date",
150
+	}
151
+	_, err := m.db.Cols(cols...).Where("customer_flash_buy_id = ?", customerFlashBuy.CustomerFlashBuyId).Update(customerFlashBuy)
152
+	return err
153
+}
154
+
155
+func (m *FlashbuyDAO) GetCustomerFlashBuyById(flashBuyId, phone string, page, pageSize int) ([]CustomerFlashBuy, error) {
156
+	var customerFlashBuy []CustomerFlashBuy
157
+	sql := `SELECT
158
+	a.*,
159
+	b.customer_name,
160
+	b.phone,
161
+	c.case_name,
162
+	d.flash_buy_id
163
+FROM
164
+	ta_customer_flash_buy a
165
+	INNER JOIN ta_customer b ON a.customer_id = b.customer_id
166
+	INNER JOIN sys_case c ON a.case_id = c.case_id
167
+	INNER JOIN ta_flash_buy d ON a.flash_buy_id = d.flash_buy_id
168
+WHERE
169
+	a.flash_buy_id = '` + flashBuyId + `' 
170
+	and a.status >` + strconv.Itoa(models.STATUS_DEL)
171
+	if phone != "" {
172
+		sql += ` and b.phone like '%` + phone + `%'`
173
+	}
174
+	sql += ` order by a.create_date desc  limit ` + strconv.Itoa((page-1)*pageSize) + `, ` + strconv.Itoa(pageSize)
175
+	err := m.db.Sql(sql).Find(&customerFlashBuy)
176
+	return customerFlashBuy, err
177
+
178
+}
179
+func (m *FlashbuyDAO) GetCustomerFlashBuyByIdCount(flashBuyId, phone string) (int, error) {
180
+	var customerFlashBuy []CustomerFlashBuy
181
+	sql := `SELECT
182
+	a.*,
183
+	b.customer_name,
184
+	b.phone,
185
+	c.case_name 
186
+FROM
187
+	ta_customer_flash_buy a
188
+	INNER JOIN ta_customer b ON a.customer_id = b.customer_id
189
+	INNER JOIN sys_case c ON a.case_id = c.case_id 
190
+WHERE
191
+	a.flash_buy_id = '` + flashBuyId + `' 
192
+	and a.status >` + strconv.Itoa(models.STATUS_DEL)
193
+	if phone != "" {
194
+		sql += ` and b.phone like '%` + phone + `%'`
195
+	}
196
+	err := m.db.Sql(sql).Find(&customerFlashBuy)
197
+	return len(customerFlashBuy), err
198
+}
199
+
200
+func (m *FlashbuyDAO) GetCustomerFlashBuyByQr(customerFlashBuyId, caseId string) (*CustomerFlashBuy, error) {
201
+	var customerFlashBuy []CustomerFlashBuy
202
+	sql := `SELECT
203
+	a.*,
204
+	b.customer_name,
205
+	b.phone,
206
+	c.case_name,
207
+	d.flash_buy_name
208
+FROM
209
+	ta_customer_flash_buy a
210
+	INNER JOIN ta_customer b ON a.customer_id = b.customer_id
211
+	INNER JOIN sys_case c ON a.case_id = c.case_id 
212
+	INNER JOIN ta_flash_buy d ON a.flash_buy_id = d.flash_buy_id
213
+WHERE
214
+	a.customer_flash_buy_id ='` + customerFlashBuyId + `' and a.case_id = '` + caseId + `'`
215
+	sql += ` and a.validate_start <= now() and a.validate_end >= now()`
216
+	err := m.db.Sql(sql).Find(&customerFlashBuy)
217
+	if len(customerFlashBuy) > 0 {
218
+		return &customerFlashBuy[0], err
219
+	}
220
+	return nil, nil
221
+}
222
+
223
+func (m *FlashbuyDAO) GetCustomerFlashBuyByCustomerId(customerId string, page, pageSize int) ([]CustomerFlashResult, error) {
224
+	var customerResult []CustomerFlashResult
225
+	sql := `select a.*,b.flash_buy_name
226
+	 from ta_customer_flash_buy a 
227
+	 inner join ta_flash_buy b 
228
+	 on a.flash_buy_id = b.flash_buy_id
229
+	 where a.customer_id = '` + customerId + `'`
230
+	sql += ` order by a.validate_start desc  limit ` + strconv.Itoa((page-1)*pageSize) + `, ` + strconv.Itoa(pageSize)
231
+	err := m.db.Sql(sql).Find(&customerResult)
232
+	return customerResult, err
233
+
234
+}
235
+
236
+func (m *FlashbuyDAO) GetCustomerFlashBuyByCustomerIdCount(customerId string) (int, error) {
237
+	var customerResult []CustomerFlashResult
238
+	sql := `select a.*,b.flash_buy_name
239
+	 from ta_customer_flash_buy a 
240
+	 inner join ta_flash_buy b 
241
+	 on a.flash_buy_id = b.flash_buy_id
242
+	 where a.customer_id = '` + customerId + `'`
243
+	err := m.db.Sql(sql).Find(&customerResult)
244
+	return len(customerResult), err
245
+
246
+}
247
+
248
+func (m *FlashbuyDAO) GetCustomerFlashBuyId(customerFlashBuyId string) (*CustomerFlashDetail, error) {
249
+	var customerDetail []CustomerFlashDetail
250
+	sql := `SELECT
251
+	a.*,
252
+	b.customer_qrcode,
253
+	c.case_name
254
+FROM
255
+	ta_customer_flash_buy a
256
+	INNER JOIN ta_customer_course_qrcode b ON a.customer_flash_buy_id = b.customer_course_id
257
+	INNER JOIN sys_case c ON a.case_id = c.case_id
258
+	WHERE a.customer_flash_buy_id = '` + customerFlashBuyId + `'`
259
+	err := m.db.Sql(sql).Find(&customerDetail)
260
+	if len(customerDetail) > 0 {
261
+		return &customerDetail[0], err
262
+	}
263
+	return nil, err
264
+}
265
+
266
+// GetCustomerFlashBuy 获取用户抢购信息
267
+func (m *FlashbuyDAO) GetCustomerFlashBuy(id, customerid string) ([]model.TaCustomerFlashBuy, error) {
268
+	var buys []model.TaCustomerFlashBuy
269
+	err := m.db.Where("flash_buy_id=?", id).And("customer_id=?", customerid).And("status>?", models.STATUS_DEL).Find(&buys)
270
+	return buys, err
271
+}
272
+
273
+// UpdateFlashBuyJoin 更新抢购参与人数
274
+func (m *FlashbuyDAO) UpdateFlashBuyJoin(id string) (int64, error) {
275
+	sql := `update ta_flash_buy set join_num = join_num + 1 where flash_buy_id=? and join_num < flash_buy_max_attendant`
276
+	result, err := m.db.Exec(sql, id)
277
+	if err != nil {
278
+		return 0, err
279
+	}
280
+
281
+	rowCount, err := result.RowsAffected()
282
+	return rowCount, err
283
+}
284
+
285
+// SaveCustomerFlashBuy 新增用户抢购信息
286
+func (m *FlashbuyDAO) SaveCustomerFlashBuy(cstFlashBuy model.TaCustomerFlashBuy) (*model.TaCustomerFlashBuy, error) {
287
+	cstFlashBuy.Status = models.STATUS_NORMAL
288
+	cstFlashBuy.CustomerFlashBuyId = utils.GetGUID()
289
+	cstFlashBuy.CreateDate = time.Now()
290
+	cstFlashBuy.VerifyStatus = models.VERIFY_USEABLE
291
+	_, err := m.db.Insert(cstFlashBuy)
292
+	return &cstFlashBuy, err
293
+}
294
+
295
+func (m *FlashbuyDAO) GetFlashModelList() ([]model.TdFlashbuyModel, error) {
296
+	var model []model.TdFlashbuyModel
297
+	sql := `select * from td_flashbuy_model`
298
+	err := m.db.Sql(sql).Find(&model)
299
+	return model, err
300
+}
301
+
302
+func (m *FlashbuyDAO) AddNewFlashBuyCustomer(customer model.TaFlashBuyCustomer) error {
303
+	customer.CreateDate = time.Now()
304
+	customer.FlashBuyCustomerId = utils.GetGUID()
305
+	customer.IsAttend = 1
306
+	_, err := m.db.Insert(customer)
307
+	return err
308
+}
309
+
310
+func (m *FlashbuyDAO) UpdateFlashBuyCustomer(customerId, flashBuyId string) error {
311
+	var customer = model.TaFlashBuyCustomer{
312
+		CustomerId: customerId,
313
+		IsNew:      0,
314
+		IsAttend:   0,
315
+	}
316
+	var cols = []string{
317
+		"is_new",
318
+		"is_attend",
319
+	}
320
+	_, err := m.db.Cols(cols...).Where("customer_id = ?", customer.CustomerId).And("flash_buy_id =?", flashBuyId).Update(customer)
321
+	return err
322
+}
323
+
324
+func (m *FlashbuyDAO) IsFlashBuyCustomer(customerId, flashBuyId string) (*model.TaFlashBuyCustomer, error) {
325
+	var customer []model.TaFlashBuyCustomer
326
+	sql := `SELECT
327
+	* 
328
+FROM
329
+	ta_flash_buy_customer 
330
+WHERE
331
+	customer_id = '` + customerId + `'
332
+	and flash_buy_id = '` + flashBuyId + `'`
333
+	err := m.db.Sql(sql).Find(&customer)
334
+	if len(customer) <= 0 {
335
+		return nil, err
336
+	}
337
+	return &customer[0], err
338
+}
339
+
340
+func (m *FlashbuyDAO) IsRecord(customerId, flashBuyId string) (int, error) {
341
+	var customer []model.TaFlashBuyCustomer
342
+	sql := `SELECT
343
+	* 
344
+FROM
345
+	ta_flash_buy_customer 
346
+WHERE
347
+	customer_id = '` + customerId + `'
348
+	and flash_buy_id = '` + flashBuyId + `'`
349
+	err := m.db.Sql(sql).Find(&customer)
350
+	return len(customer), err
351
+}

+ 47
- 44
models/goods/orders.go Просмотреть файл

@@ -47,8 +47,6 @@ func (m *GoodsDAO) SaveOrders(order *model.TaGoodsOrders) error {
47 47
 	// order.OrdersId = guid.NewGUIDString()
48 48
 	order.OrgId = caseInfo.OrgId
49 49
 	order.CreateDate = now
50
-	order.Status = models.STATUS_NORMAL
51
-	order.IsPay = models.BOOL_TRUE // 默认已支付
52 50
 	order.CouponAmount = "0"
53 51
 	order.IsIntimidate = INTIMIDATE_NO
54 52
 	order.DupKey = utils.GetFiveSeconds(now) + order.UserId + order.TableId + strconv.Itoa(order.Status)
@@ -77,6 +75,12 @@ func (m *GoodsDAO) UpdateOrdersIntimidate(id string) error {
77 75
 		"orders_id",
78 76
 		"is_intimidate",
79 77
 	}
78
+
79
+	return m.UpdateOrders(&orders, cols)
80
+}
81
+
82
+// UpdateOrders  更新订单
83
+func (m *GoodsDAO) UpdateOrders(orders *model.TaGoodsOrders, cols []string) error {
80 84
 	_, err := m.db.Cols(cols...).Where("orders_id=?", orders.OrdersId).Update(orders)
81 85
 	return err
82 86
 }
@@ -101,53 +105,29 @@ func (m *GoodsDAO) SaveOrdersDetail(list []model.TaGoodsOrdersDetail, ordersID s
101 105
 // SaveOrdersCoupon 保存订单优惠券
102 106
 func (m *GoodsDAO) SaveOrdersCoupon(coupon *model.TaGoodsOrdersCoupon, order *model.TaGoodsOrders) error {
103 107
 	if order.OrdersId == "" {
104
-		return errors.New("内部错误, 订单事务顺序出错")
108
+		return errors.New("保存订单券失败, 订单不存在")
105 109
 	}
106 110
 	coupon.OrdersCouponId = utils.GetGUID()
107 111
 	coupon.Status = models.STATUS_NORMAL
108 112
 	coupon.CreateDate = time.Now().Local()
109
-	if _, err := m.db.Insert(coupon); err != nil {
110
-		return err
111
-	}
113
+	_, err := m.db.Insert(coupon)
112 114
 
113
-	// 更新优惠券已使用信息
114
-	sql := `update ta_coupon set used_count=used_count+1 where coupon_id='` + coupon.CouponId + `'`
115
-	_, err := m.db.Exec(sql)
116 115
 	return err
116
+}
117 117
 
118
-	// var couponAmount float64 = 0
119
-
120
-	// // 补充优惠券表字段
121
-	// for inx := range coupons {
122
-	// 	coupons[inx].OrdersCouponId = guid.NewGUIDString()
123
-	// 	coupons[inx].OrdersId = order.OrdersId
124
-	// 	coupons[inx].OrdersNo = order.OrdersNo
125
-	// 	coupons[inx].OrgId = order.OrgId
126
-	// 	coupons[inx].Status = models.STATUS_NORMAL
127
-	// 	coupons[inx].CreateDate = time.Now().Local()
128
-
129
-	// 	userAmount, _ := strconv.ParseFloat(coupons[inx].UsedAmount, 64)
130
-	// 	couponAmount += userAmount
131
-	// }
132
-
133
-	// // 反向更新 订单主表
134
-	// totalAmount, _ := strconv.ParseFloat(order.Amount, 64)
135
-
136
-	// order.CouponAmount = strconv.FormatFloat(couponAmount, 'f', -1, 32)
137
-	// order.ActualAmount = strconv.FormatFloat((totalAmount - couponAmount), 'f', -1, 32)
138
-
139
-	// if _, err := m.db.Insert(&coupons); err != nil {
140
-	// 	return err
141
-	// }
142
-
143
-	// if _, err := m.db.
144
-	// 	Where("orders_id=?", order.OrdersId).
145
-	// 	Cols([]string{"coupon_amount", "actual_amount"}...).
146
-	// 	Update(order); err != nil {
147
-	// 	return err
148
-	// }
149
-
150
-	// return nil
118
+// GetCouponByOrdersID 获取优惠券订单
119
+func (m *GoodsDAO) GetCouponByOrdersID(ordersID string) ([]model.TaCoupon, error) {
120
+	var res []model.TaCoupon
121
+	query := `
122
+		SELECT t.*
123
+		FROM ta_coupon t
124
+		JOIN ta_goods_orders_coupon s ON t.coupon_id = s.coupon_id
125
+		WHERE s.orders_id = ?
126
+		ORDER BY t.create_date
127
+	`
128
+
129
+	err := m.db.SQL(query, ordersID).Find(&res)
130
+	return res, err
151 131
 }
152 132
 
153 133
 func (m *GoodsDAO) getCaseByID(caseID string) (*model.SysCase, error) {
@@ -237,6 +217,29 @@ func (m *GoodsDAO) GetOrdersByID(id string) (*OrdersWithGoods, error) {
237 217
 	return res, nil
238 218
 }
239 219
 
220
+func (m *GoodsDAO) GetOrdersDetailByID(id string, status ...int) (*OrdersDetail, error) {
221
+	sta := models.STATUS_NORMAL
222
+	if len(status) > 0 {
223
+		sta = status[0]
224
+	}
225
+
226
+	res := new(OrdersDetail)
227
+	if _, err := m.db.Table("ta_goods_orders").
228
+		Where("orders_id=?", id).
229
+		And("status=?", sta).
230
+		Get(res); err != nil {
231
+		return nil, err
232
+	}
233
+
234
+	details, err := m.GetOrderDetailByOrder(res.OrdersId)
235
+	if err != nil {
236
+		return nil, err
237
+	}
238
+
239
+	res.Goods = details
240
+	return res, nil
241
+}
242
+
240 243
 // GetOrdersByRecord 根据
241 244
 func (m *GoodsDAO) GetOrdersByRecord(recordid string) ([]OrdersWithGoods, error) {
242 245
 	var orderList []OrdersWithGoods
@@ -338,8 +341,8 @@ func (m *GoodsDAO) GetOrderDetailByUser(caseid, userid string) ([]model.TaGoodsO
338 341
 	var details []model.TaGoodsOrdersDetail
339 342
 	sql := `select a.* from ta_goods_orders_detail a inner join ta_goods_orders b on a.orders_id=b.orders_id
340 343
 		inner join ta_customer c on b.user_id = c.customer_id
341
-	where c.user_id=? and b.status>? and b.case_id=? and b.pay_type = ? order by b.create_date desc`
342
-	if err := m.db.Sql(sql, userid, models.STATUS_DEL, caseid, models.CONSUME_INNER).Find(&details); err != nil {
344
+	where c.user_id=? and b.status=? and b.case_id=? and b.pay_type = ? order by b.create_date desc`
345
+	if err := m.db.Sql(sql, userid, models.STATUS_NORMAL, caseid, models.CONSUME_INNER).Find(&details); err != nil {
343 346
 		return nil, err
344 347
 	}
345 348
 	return details, nil

+ 7
- 0
models/goods/types.go Просмотреть файл

@@ -46,3 +46,10 @@ type OrdersWithGoods struct {
46 46
 	AreaIconWhite       string
47 47
 	Goods               []DetailWithType
48 48
 }
49
+
50
+// OrdersDetail 订单详情
51
+type OrdersDetail struct {
52
+	model.TaGoodsOrders `xorm:"extends"`
53
+	Goods               []DetailWithType            `xorm:"-"`
54
+	Coupons             []model.TaGoodsOrdersCoupon `xorm:"-"`
55
+}

+ 678
- 63
models/luckdraw/luckdraw.go Просмотреть файл

@@ -6,8 +6,10 @@ import (
6 6
 	"spaceofcheng/services/models/model"
7 7
 	"spaceofcheng/services/utils"
8 8
 	"strconv"
9
+	"strings"
9 10
 	"time"
10 11
 
12
+	"github.com/astaxie/beego"
11 13
 	"github.com/go-xorm/xorm"
12 14
 )
13 15
 
@@ -29,12 +31,378 @@ func NewDAO(ctx *utils.Context) *LuckDrawDao {
29 31
 type LuckDraw struct {
30 32
 	model.TaLuckdraw `xorm:"extends"`
31 33
 	Prizes           []model.TaLuckdrawPrize
34
+	Imgs             []model.TaLuckdrawImg
32 35
 }
36
+
33 37
 type LuckInfo struct {
34 38
 	model.TaLuckdrawRecord `xorm:"extends"`
35 39
 	CustomerQrcode         string
36 40
 }
37 41
 
42
+// GetLuckDrawTpl 获取抽奖模板
43
+func (m *LuckDrawDao) GetLuckDrawTpl(orgid string) ([]model.TaLuckdrawTpl, error) {
44
+	var tpls []model.TaLuckdrawTpl
45
+	err := m.db.Where("org_id=?", orgid).And("status=?", models.STATUS_NORMAL).Find(&tpls)
46
+	return tpls, err
47
+}
48
+
49
+// GetLuckDrawList 获取抽奖列表
50
+func (m *LuckDrawDao) GetLuckDrawList(caseids, name, status string, page, pageSize int) ([]model.TaLuckdraw, error) {
51
+	var luckdraws []model.TaLuckdraw
52
+	dao := m.db.Where("case_id in ('"+strings.Replace(caseids, ",", "','", -1)+"')").And("status<>?", models.STATUS_DEL)
53
+	if name != "" {
54
+		dao.And("name like '%" + name + "%'")
55
+	}
56
+	if status != "" {
57
+		query := `status=?`
58
+		switch status {
59
+		case strconv.Itoa(models.STATUS_NORMAL):
60
+			query = query + " and end_date>now()"
61
+			break
62
+		case strconv.Itoa(models.STATUS_EXPIRE):
63
+			query = "(" + query + " or end_date<=now())"
64
+		}
65
+		dao.And(query, status)
66
+	}
67
+	err := dao.Desc("create_date").Limit(pageSize, (page-1)*pageSize).Find(&luckdraws)
68
+	return luckdraws, err
69
+}
70
+
71
+// GetLuckDrawCount 获取抽奖列表count
72
+func (m *LuckDrawDao) GetLuckDrawCount(caseids, name, status string) (int, error) {
73
+	var luckdraws []model.TaLuckdraw
74
+	dao := m.db.Where("case_id in ('"+strings.Replace(caseids, ",", "','", -1)+"')").And("status<>?", models.STATUS_DEL)
75
+	if name != "" {
76
+		dao.And("name like '%" + name + "%'")
77
+	}
78
+	if status != "" {
79
+		dao.And("status=?", status)
80
+	}
81
+	err := dao.Find(&luckdraws)
82
+	return len(luckdraws), err
83
+}
84
+
85
+// RecordWithPhone 抽奖记录
86
+type RecordWithPhone struct {
87
+	model.TaLuckdrawRecord `xorm:"extends"`
88
+	CustomerName           string
89
+	Phone                  string
90
+}
91
+
92
+// GetLuckDrawRecordCount 获取抽奖记录count
93
+func (m *LuckDrawDao) GetLuckDrawRecordCount(id, tel string) (int, error) {
94
+	var records []RecordWithPhone
95
+	sql := `select a.*,b.customer_name,b.phone from ta_luckdraw_record a inner join ta_customer b on a.user_id=b.customer_id where a.luckdraw_id=?`
96
+	if tel != "" {
97
+		sql = sql + ` and b.phone=` + tel
98
+	}
99
+
100
+	err := m.db.Sql(sql, id).Find(&records)
101
+	return len(records), err
102
+}
103
+
104
+// GetLuckDrawRecord 获取抽奖记录信息
105
+func (m *LuckDrawDao) GetLuckDrawRecord(id, tel string, page, pageSize int) ([]RecordWithPhone, error) {
106
+	var records []RecordWithPhone
107
+	sql := `select a.*,b.customer_name,b.phone from ta_luckdraw_record a inner join ta_customer b on a.user_id=b.customer_id where a.luckdraw_id=?`
108
+	if tel != "" {
109
+		sql = sql + ` and b.phone=` + tel
110
+	}
111
+	sql = sql + ` ORDER BY a.create_date desc limit ` + strconv.Itoa((page-1)*pageSize) + `, ` + strconv.Itoa(pageSize)
112
+
113
+	err := m.db.Sql(sql, id).Find(&records)
114
+	return records, err
115
+}
116
+
117
+// GetLuckDrawShareCount 获取分享记录count
118
+func (m *LuckDrawDao) GetLuckDrawShareCount(id, tel string) (int, error) {
119
+	var shares []model.TaShareLuckyRecord
120
+	dao := m.db.Where("luckydraw_id=?", id)
121
+	if tel != "" {
122
+		dao.And("from_customer_tel=?", tel)
123
+	}
124
+
125
+	err := dao.Find(&shares)
126
+	return len(shares), err
127
+}
128
+
129
+// GetLuckDrawShare 获取分享记录信息
130
+func (m *LuckDrawDao) GetLuckDrawShare(id, tel string, page, pageSize int) ([]model.TaShareLuckyRecord, error) {
131
+	var shares []model.TaShareLuckyRecord
132
+	dao := m.db.Where("luckydraw_id=?", id)
133
+	if tel != "" {
134
+		dao.And("from_customer_tel=?", tel)
135
+	}
136
+
137
+	err := dao.Desc("create_date").Limit(pageSize, (page-1)*pageSize).Find(&shares)
138
+	return shares, err
139
+}
140
+
141
+// PrizeWithDefaults 奖品关联内定
142
+type PrizeWithDefaults struct {
143
+	model.TaLuckdrawPrize `xorm:"extends"`
144
+	Defaults              []model.TaPrizeDefault
145
+}
146
+
147
+// LuckDrawInfo 抽奖info
148
+type LuckDrawInfo struct {
149
+	model.TaLuckdraw `xorm:"extends"`
150
+	Prizes           []PrizeWithDefaults
151
+	Imgs             []model.TaLuckdrawImg
152
+}
153
+
154
+// GetLuckDrawInfoByID 获取抽奖信息
155
+func (m *LuckDrawDao) GetLuckDrawInfoByID(id string) (*LuckDrawInfo, error) {
156
+	if id == "" {
157
+		return nil, errors.New("不存在抽奖信息!")
158
+	}
159
+	var luckdraw LuckDrawInfo
160
+	sql := `select * from ta_luckdraw where id= ?`
161
+	_, err := m.db.SQL(sql, id).Get(&luckdraw)
162
+	if err != nil {
163
+		return nil, err
164
+	}
165
+	if luckdraw.Id == "" {
166
+		return nil, nil
167
+	}
168
+	prizes, err := m.GetPrizesWithDefaults(id)
169
+	if err != nil {
170
+		utils.LogError("获取奖品信息失败:", err)
171
+		return nil, errors.New("获取奖品信息失败")
172
+	}
173
+	luckdraw.Prizes = prizes
174
+	imgs, err := m.GetLuckDrawImgs(id)
175
+	if err != nil {
176
+		utils.LogError("获取抽奖图片信息失败:", err)
177
+		return nil, errors.New("获取抽奖图片信息失败")
178
+	}
179
+	luckdraw.Imgs = imgs
180
+	// defaults, err := m.GetLuckDrawDefault(id)
181
+	// if err != nil {
182
+	// 	utils.LogError("获取奖品内置信息失败:", err)
183
+	// 	return nil, errors.New("获取奖品信息失败")
184
+	// }
185
+	// luckdraw.Defaults = defaults
186
+	return &luckdraw, err
187
+}
188
+
189
+// GetLuckDrawImgs 获取抽奖图片
190
+func (m *LuckDrawDao) GetLuckDrawImgs(luckdrawid string) ([]model.TaLuckdrawImg, error) {
191
+	var imgs []model.TaLuckdrawImg
192
+	err := m.db.Where("luckdraw_id=?", luckdrawid).Find(&imgs)
193
+	return imgs, err
194
+}
195
+
196
+// GetLuckDrawDefault 获取奖品默认信息
197
+func (m *LuckDrawDao) GetLuckDrawDefault(luckdrawid string) ([]model.TaPrizeDefault, error) {
198
+	var defaults []model.TaPrizeDefault
199
+	err := m.db.Where("luckdraw_id=?", luckdrawid).Find(&defaults)
200
+	return defaults, err
201
+}
202
+
203
+// InsertLuckdraw 新增抽奖信息
204
+func (m *LuckDrawDao) InsertLuckdraw(luckdraw model.TaLuckdraw) (*model.TaLuckdraw, error) {
205
+	luckdraw.Id = utils.GetGUID()
206
+	luckdraw.Status = models.STATUS_NORMAL
207
+	luckdraw.CreateDate = time.Now()
208
+
209
+	_, err := m.db.Insert(luckdraw)
210
+	return &luckdraw, err
211
+}
212
+
213
+// DelLuckDrawDefault 删除抽奖默认信息
214
+func (m *LuckDrawDao) DelLuckDrawDefault(luckdrawid string) error {
215
+	sql := `delete from ta_prize_default where luckdraw_id=?`
216
+	_, err := m.db.Exec(sql, luckdrawid)
217
+	return err
218
+}
219
+
220
+// DelLuckDrawImgs 删除抽奖图片信息
221
+func (m *LuckDrawDao) DelLuckDrawImgs(luckdrawid string) error {
222
+	sql := `delete from ta_luckdraw_img where luckdraw_id=?`
223
+	_, err := m.db.Exec(sql, luckdrawid)
224
+	return err
225
+}
226
+
227
+// DelLuckDrawPrize 删除奖品信息
228
+func (m *LuckDrawDao) DelLuckDrawPrize(luckdrawid string) error {
229
+	sql := `delete from ta_prize_detail where prize_id in (select id from ta_luckdraw_prize where luckdraw_id=?)`
230
+	_, err := m.db.Exec(sql, luckdrawid)
231
+	if err != nil {
232
+		return err
233
+	}
234
+	sql = `delete from ta_luckdraw_prize where luckdraw_id=?`
235
+	_, err = m.db.Exec(sql, luckdrawid)
236
+	return err
237
+}
238
+
239
+// DelLuckDrawSet 删除抽奖设置信息
240
+func (m *LuckDrawDao) DelLuckDrawSet(luckdrawid string) error {
241
+	sql := `delete from ta_luckdraw_customer where luckdraw_id=?`
242
+	_, err := m.db.Exec(sql, luckdrawid)
243
+	return err
244
+}
245
+
246
+// SaveLuckDrawImgs 保存抽奖图片
247
+func (m *LuckDrawDao) SaveLuckDrawImgs(imgs []model.TaLuckdrawImg, luckdrawid string) error {
248
+	for inx, img := range imgs {
249
+		if img.ImgId == "" {
250
+			imgs[inx].ImgId = utils.GetGUID()
251
+			org := m.ctx.Get("org").(model.SysOrg)
252
+			imgs[inx].OrgId = org.OrgId
253
+			imgs[inx].Status = models.STATUS_NORMAL
254
+			imgs[inx].LuckdrawId = luckdrawid
255
+		}
256
+	}
257
+	_, err := m.db.Insert(imgs)
258
+	return err
259
+}
260
+
261
+// SaveLuckDrawDefault 保存内定信息
262
+func (m *LuckDrawDao) SaveLuckDrawDefault(defaults []model.TaPrizeDefault, prize model.TaLuckdrawPrize) error {
263
+	for inx, d := range defaults {
264
+		if d.DefaultId == "" {
265
+			defaults[inx].DefaultId = utils.GetGUID()
266
+			defaults[inx].Status = models.STATUS_NORMAL
267
+			defaults[inx].CreateDate = time.Now()
268
+			defaults[inx].LuckdrawId = prize.LuckdrawId
269
+			defaults[inx].PrizeId = prize.Id
270
+		}
271
+	}
272
+	_, err := m.db.Insert(defaults)
273
+	return err
274
+}
275
+
276
+// SaveLuckDrawPrizes 保存奖品信息
277
+func (m *LuckDrawDao) SaveLuckDrawPrizes(prizes []PrizeWithDefaults, luckdraw *model.TaLuckdraw) error {
278
+	var saveprizes []model.TaLuckdrawPrize
279
+	for inx, prize := range prizes {
280
+		if prize.Id == "" {
281
+			prizes[inx].LuckdrawId = luckdraw.Id
282
+			prizes[inx].Id = utils.GetGUID()
283
+		}
284
+		prizes[inx].Remainder = prize.Stock
285
+		prizes[inx].Status = models.STATUS_NORMAL
286
+
287
+		if prize.PrizeType == models.PRIZE_TYPE_COUPONCARD {
288
+			valid, err := m.SavePrizeDetail(prizes[inx].TaLuckdrawPrize)
289
+			if err != nil {
290
+				return err
291
+			}
292
+			prizes[inx].ValidDays = valid.ValidDays
293
+			prizes[inx].VerificationStart = valid.VerificationStart
294
+			prizes[inx].VerificationEnd = valid.VerificationEnd
295
+		}
296
+		saveprizes = append(saveprizes, prizes[inx].TaLuckdrawPrize)
297
+		// 保存内定信息
298
+		if luckdraw.IsInternalDefault == models.BOOL_TRUE {
299
+			if len(prize.Defaults) > prize.Stock {
300
+				return errors.New("内置用户不能超过奖品数量!")
301
+			}
302
+
303
+			err := m.SaveLuckDrawDefault(prize.Defaults, prizes[inx].TaLuckdrawPrize)
304
+			if err != nil {
305
+				return err
306
+			}
307
+		}
308
+	}
309
+	_, err := m.db.Insert(saveprizes)
310
+	if err != nil {
311
+		return err
312
+	}
313
+	return err
314
+}
315
+
316
+// Verification 有效期
317
+type Verification struct {
318
+	ValidDays         int
319
+	VerificationStart time.Time
320
+	VerificationEnd   time.Time
321
+}
322
+
323
+// SavePrizeDetail 保存奖品明细
324
+func (m *LuckDrawDao) SavePrizeDetail(prize model.TaLuckdrawPrize) (*Verification, error) {
325
+	var verification = Verification{}
326
+	if prize.CouponCardType == models.PRIZE_TYPE_COUPON {
327
+		var coupon model.TaCoupon
328
+		_, err := m.db.Where("coupon_id=?", prize.CouponCardId).Get(&coupon)
329
+		if err != nil {
330
+			return nil, err
331
+		}
332
+		if coupon.UsedCount > 0 {
333
+			return nil, errors.New("卡券已被使用!不允许保存!")
334
+		}
335
+		verification.ValidDays = coupon.ValidDays
336
+		verification.VerificationStart = coupon.StartDate
337
+		verification.VerificationEnd = coupon.EndDate
338
+		var details []model.TaPrizeDetail
339
+		i := 0
340
+		for i < coupon.TotalCount {
341
+			unix := time.Now().UnixNano()
342
+			random := utils.GetRand(5) + strconv.Itoa(int(unix))
343
+			url := `/` + prize.CouponCardId + `/` + beego.AppConfig.String("defaultShareUserID") + `/` + prize.CouponCardType + `/` + random + `/receive`
344
+			var d = model.TaPrizeDetail{
345
+				Id:      utils.GetGUID(),
346
+				PrizeId: prize.Id,
347
+				Url:     url,
348
+				Status:  models.STATUS_READY,
349
+			}
350
+			details = append(details, d)
351
+			i = i + 1
352
+		}
353
+		m.db.Insert(details)
354
+	} else {
355
+		var card model.TaCouponCard
356
+		_, err := m.db.Where("card_id=?", prize.CouponCardId).Get(&card)
357
+		if err != nil {
358
+			return nil, err
359
+		}
360
+		if card.UsedCount > 0 {
361
+			return nil, errors.New("卡券已被使用!不允许保存!")
362
+		}
363
+		verification.ValidDays = 0
364
+		verification.VerificationStart = card.StartDate
365
+		verification.VerificationEnd = card.EndDate
366
+		var details []model.TaPrizeDetail
367
+		i := 0
368
+		for i < card.TotalCount {
369
+			unix := time.Now().UnixNano()
370
+			random := utils.GetRand(5) + strconv.Itoa(int(unix))
371
+			url := `/` + prize.CouponCardId + `/` + beego.AppConfig.String("defaultShareUserID") + `/` + prize.CouponCardType + `/` + random + `/receive`
372
+			var d = model.TaPrizeDetail{
373
+				Id:      utils.GetGUID(),
374
+				PrizeId: prize.Id,
375
+				Url:     url,
376
+				Status:  models.STATUS_READY,
377
+			}
378
+			details = append(details, d)
379
+			i = i + 1
380
+		}
381
+		m.db.Insert(details)
382
+	}
383
+
384
+	return &verification, nil
385
+}
386
+
387
+// UpdateLuckDraw 修改抽奖
388
+func (m *LuckDrawDao) UpdateLuckDraw(luckdraw model.TaLuckdraw, cols []string) error {
389
+	_, err := m.db.Cols(cols...).Where("id=?", luckdraw.Id).Update(luckdraw)
390
+	return err
391
+}
392
+
393
+// UpdatePrizeDesc 更新奖品描述
394
+func (m *LuckDrawDao) UpdatePrizeDesc(prizes []PrizeWithDefaults) error {
395
+	for _, prize := range prizes {
396
+		_, err := m.db.Cols([]string{
397
+			"prize_desc",
398
+		}...).Where("id=?", prize.Id).Update(prize.TaLuckdrawPrize)
399
+		if err != nil {
400
+			return err
401
+		}
402
+	}
403
+	return nil
404
+}
405
+
38 406
 // GetLuckDraw 获取抽奖信息
39 407
 func (m *LuckDrawDao) GetLuckDraw(id string) (*LuckDraw, error) {
40 408
 	if id == "" {
@@ -51,69 +419,121 @@ func (m *LuckDrawDao) GetLuckDraw(id string) (*LuckDraw, error) {
51 419
 		return nil, errors.New("获取奖品信息失败")
52 420
 	}
53 421
 	luckdraw.Prizes = prizes
422
+	imgs, err := m.GetLuckDrawImgs(id)
423
+	if err != nil {
424
+		utils.LogError("获取抽奖图片信息失败:", err)
425
+		return nil, errors.New("获取抽奖图片信息失败")
426
+	}
427
+	luckdraw.Imgs = imgs
54 428
 	return luckdraw, nil
55 429
 }
56 430
 
431
+// AddCustomerLuckDraw 保存用户抽奖配置信息
432
+func (m *LuckDrawDao) AddCustomerLuckDraw(custLuckDraw model.TaLuckdrawCustomer) (*model.TaLuckdrawCustomer, error) {
433
+	custLuckDraw.LuckdrawCustomerId = utils.GetGUID()
434
+	custLuckDraw.CreateDate = time.Now()
435
+	custLuckDraw.ShareNum = 0
436
+	custLuckDraw.ShareSurplusNum = 0
437
+	_, err := m.db.Insert(custLuckDraw)
438
+	return &custLuckDraw, err
439
+}
440
+
57 441
 // LuckDraw 抽奖
58 442
 func (m *LuckDrawDao) LuckDraw(id string, user *model.TaCustomer) (*model.TaLuckdrawPrize, *model.TaPrizeDetail, *model.TaLuckdrawRecord, error) {
59 443
 	luckdraw, err := m.GetLuckDrawByID(id)
60 444
 	if err != nil {
61 445
 		return nil, nil, nil, errors.New("获取抽奖信息失败!")
62 446
 	}
63
-	if luckdraw.Status != models.STATUS_NORMAL {
64
-		return nil, nil, nil, errors.New("当前抽奖活动状态异常!")
447
+	if luckdraw.Status == models.STATUS_READY {
448
+		return nil, nil, nil, errors.New("活动已结束!")
65 449
 	}
66 450
 	if time.Now().Before(luckdraw.BeginDate) {
67 451
 		return nil, nil, nil, errors.New("活动还未开始!")
68 452
 	}
69
-	if time.Now().After(luckdraw.EndDate) {
453
+	if luckdraw.Status == models.STATUS_EXPIRE || time.Now().After(luckdraw.EndDate) {
70 454
 		return nil, nil, nil, errors.New("活动已结束!")
71 455
 	}
72
-	// if user.Phone != "" {
73
-	// 	sysuser, err := m.GetUserByTel(user.Phone)
74
-	// 	if err != nil {
75
-	// 		return nil, nil, errors.New("获取信息失败!")
76
-	// 	}
77
-	// 	if sysuser != nil {
78
-	// 		return nil, nil, errors.New("内部人员不允许进行抽奖!")
79
-	// 	}
80
-	// }
81
-	userluckdraws, err := m.GetUserRecordByLuckDraw(user.CustomerId, id)
82
-	if err != nil {
83
-		utils.LogError("获取用户抽奖信息失败:", err)
84
-		return nil, nil, nil, errors.New("获取用户抽奖信息失败!")
456
+	if luckdraw.Status != models.STATUS_NORMAL {
457
+		return nil, nil, nil, errors.New("当前抽奖活动状态异常!")
85 458
 	}
86
-	if len(userluckdraws) > 0 {
87
-		return nil, nil, nil, errors.New("您已参与过此次抽奖,不允许重复抽奖!")
459
+	// 系统用户是否可以抽奖
460
+	if luckdraw.IsSysLuckdraw == models.BOOL_FALSE {
461
+		if user.Phone != "" {
462
+			sysuser, err := m.GetUserByTel(user.Phone)
463
+			if err != nil {
464
+				return nil, nil, nil, errors.New("获取信息失败!")
465
+			}
466
+			if sysuser != nil && sysuser.UserId != "" {
467
+				return nil, nil, nil, errors.New("内部人员不允许进行抽奖!")
468
+			}
469
+		}
88 470
 	}
89
-	prizes, err := m.GetPrizeStock(id)
471
+
472
+	// 判断当前用户是否为新用户
473
+	cstluckdrawSet, err := m.GetCustomerLuckDraw(id, user.CustomerId)
90 474
 	if err != nil {
91
-		utils.LogError("获取奖项失败:", err)
92
-		return nil, nil, nil, errors.New("获取奖项失败!")
475
+		utils.LogError("获取用户抽奖配置信息失败:", err)
476
+		return nil, nil, nil, errors.New("获取用户抽奖配置信息失败!")
477
+	}
478
+
479
+	if luckdraw.JoinType == models.JOINTYPE_NEWUSER {
480
+		if cstluckdrawSet.IsNew == models.BOOL_FALSE {
481
+			return nil, nil, nil, errors.New("您不是新用户,不允许抽奖!")
482
+		}
93 483
 	}
94
-	if len(prizes) == 0 {
95
-		err = m.UpdateLuckDrawEndDate(luckdraw.Id)
484
+
485
+	// 抽奖次数判断
486
+	if cstluckdrawSet.SurplusNum <= 0 {
487
+		return nil, nil, nil, errors.New("您的抽奖次数已用完!")
488
+	} else {
489
+		// 抽奖次数库存修改
490
+		err := m.UpdateCstLuckdrawSurplus(cstluckdrawSet)
96 491
 		if err != nil {
97
-			utils.LogError("操作失败,请刷新后重试:", err)
492
+			utils.LogError("更新抽奖次数库存失败:", err)
98 493
 			return nil, nil, nil, errors.New("操作失败,请刷新后重试!")
99 494
 		}
100
-		return nil, nil, nil, errors.New("活动已结束!")
101 495
 	}
102
-	prize, err := m.GetWinning(prizes)
496
+
497
+	// 判断是否内置用户
498
+	defaultPrize, err := m.GetPrizeDefaultByUser(id, user)
103 499
 	if err != nil {
104
-		utils.LogError("获取奖项失败:", err)
105
-		return nil, nil, nil, errors.New("获取奖项失败!")
500
+		utils.LogError("操作失败,请刷新后重试:", err)
501
+		return nil, nil, nil, errors.New("操作失败,请刷新后重试!")
502
+	}
503
+	var prize = new(model.TaLuckdrawPrize)
504
+	if defaultPrize.Id != "" {
505
+		// 内置用户,直接中奖
506
+		prize = &defaultPrize.TaLuckdrawPrize
507
+	} else {
508
+		prizes, err := m.GetPrizeStock(id)
509
+		if err != nil {
510
+			utils.LogError("获取奖项失败:", err)
511
+			return nil, nil, nil, errors.New("获取奖项失败!")
512
+		}
513
+		if len(prizes) == 0 {
514
+			// err = m.UpdateLuckDrawEndDate(luckdraw.Id)
515
+			// if err != nil {
516
+			// 	utils.LogError("操作失败,请刷新后重试:", err)
517
+			// 	return nil, nil, nil, errors.New("操作失败,请刷新后重试!")
518
+			// }
519
+			return nil, nil, nil, errors.New("活动已结束!")
520
+		}
521
+		prize, err = m.GetWinning(prizes)
522
+		if err != nil {
523
+			utils.LogError("获取奖项失败:", err)
524
+			return nil, nil, nil, err
525
+		}
106 526
 	}
107 527
 
108
-	// details, err := m.GetPrizeDetail(prize.Id)
109
-	// if err != nil {
110
-	// 	utils.LogError("获取奖项详情失败:", err)
111
-	// 	return nil, nil, errors.New("获取奖项详情失败!")
112
-	// }
528
+	details, err := m.GetPrizeDetail(prize.Id)
529
+	if err != nil {
530
+		utils.LogError("获取奖项详情失败:", err)
531
+		return nil, nil, nil, errors.New("获取奖项详情失败!")
532
+	}
113 533
 
114 534
 	// 保存中奖记录
115 535
 	var record = &model.TaLuckdrawRecord{}
116
-	// record.Id = utils.GetGUID()
536
+	record.Id = utils.GetGUID()
117 537
 	record.OrgId = luckdraw.OrgId
118 538
 	record.CaseId = luckdraw.CaseId
119 539
 	record.PrizeId = prize.Id
@@ -122,6 +542,20 @@ func (m *LuckDrawDao) LuckDraw(id string, user *model.TaCustomer) (*model.TaLuck
122 542
 	record.UserName = user.CustomerName
123 543
 	record.UserHeadImg = user.Headimgurl
124 544
 	record.LuckdrawId = luckdraw.Id
545
+	record.IsReality = prize.IsReality
546
+
547
+	if prize.IsReality != models.BOOL_FALSE {
548
+		if prize.ValidDays > 0 {
549
+			record.VerificationStart = time.Now().Local()
550
+			record.VerificationEnd = time.Now().Local().AddDate(0, 0, prize.ValidDays)
551
+		} else {
552
+			record.VerificationStart = prize.VerificationStart
553
+			record.VerificationEnd = prize.VerificationEnd
554
+		}
555
+	} else {
556
+		record.VerificationStart = time.Now().Local()
557
+		record.VerificationEnd = time.Now().Local()
558
+	}
125 559
 
126 560
 	utils.LogInfo("生成中奖记录:", *record)
127 561
 
@@ -130,32 +564,46 @@ func (m *LuckDrawDao) LuckDraw(id string, user *model.TaCustomer) (*model.TaLuck
130 564
 		utils.LogError("保存中奖纪录失败:", err)
131 565
 		return nil, nil, nil, err
132 566
 	}
133
-	// var detail = model.TaPrizeDetail{}
134
-	// if len(details) > 0 {
135
-	// 	// 更新中奖纪录明细
136
-	// 	details[0].ReceiveId = newrecord.Id
137
-	// 	err = m.UpdatePrizeDetail(details[0])
138
-	// 	if err != nil {
139
-	// 		utils.LogError("更新中奖纪录明细失败:", err)
140
-	// 		return nil, nil, errors.New("操作失败!")
141
-	// 	}
142
-	// 	detail = details[0]
143
-	// 	// 奖项自动核销,走卡券核销流程
144
-	// 	err = m.PrizeWriteOff(newrecord.Id, user.CustomerId)
145
-	// 	if err != nil {
146
-	// 		utils.LogError("卡券核销失败:", err)
147
-	// 		return nil, nil, errors.New("操作失败!")
148
-	// 	}
149
-	// }
567
+	// 更新参与人数
568
+	err = m.UpdateLuckDrawJoinedNum(id)
569
+	if err != nil {
570
+		utils.LogError("更新参与人数失败:", err)
571
+		return nil, nil, nil, errors.New("操作失败,请刷新后重试!")
572
+	}
573
+
574
+	// 更新内置信息
575
+	err = m.UpdatePrizeDefault(defaultPrize.DefaultId, record.Id)
576
+	if err != nil {
577
+		utils.LogError("更新内置信息失败:", err)
578
+		return nil, nil, nil, err
579
+	}
580
+
581
+	var detail = model.TaPrizeDetail{}
582
+	if len(details) > 0 {
583
+		// 更新中奖纪录明细
584
+		details[0].ReceiveId = record.Id
585
+		err = m.UpdatePrizeDetail(details[0])
586
+		if err != nil {
587
+			utils.LogError("更新中奖纪录明细失败:", err)
588
+			return nil, nil, nil, errors.New("操作失败!")
589
+		}
590
+		detail = details[0]
591
+		// 奖项自动核销,走卡券核销流程
592
+		err = m.PrizeWriteOff(record.Id, user.CustomerId)
593
+		if err != nil {
594
+			utils.LogError("卡券核销失败:", err)
595
+			return nil, nil, nil, errors.New("操作失败!")
596
+		}
597
+	}
150 598
 	// 更新库存
151 599
 	if prize.IsReality == 1 {
152
-		prize.Remainder = prize.Remainder - 1
600
+		// prize.Remainder = prize.Remainder - 1
153 601
 		err = m.UpdateStock(prize)
154 602
 		if err != nil {
155 603
 			utils.LogError("更新库存失败:", err)
156 604
 			return nil, nil, nil, err
157 605
 		}
158
-		stockprizes, err := m.GetPrizeStock(id)
606
+		stockprizes, err := m.GetPrizeStockAll(id)
159 607
 		if err != nil {
160 608
 			utils.LogError("更新库存失败:", err)
161 609
 			return nil, nil, nil, errors.New("操作失败,请刷新后重试!")
@@ -164,9 +612,88 @@ func (m *LuckDrawDao) LuckDraw(id string, user *model.TaCustomer) (*model.TaLuck
164 612
 			// 更新活动截止时间
165 613
 			err = m.UpdateLuckDrawEndDate(luckdraw.Id)
166 614
 		}
615
+	} else {
616
+		// 奖项自动核销,走卡券核销流程
617
+		err = m.PrizeWriteOff(record.Id, user.CustomerId)
618
+		if err != nil {
619
+			utils.LogError("卡券核销失败:", err)
620
+			return nil, nil, nil, errors.New("操作失败!")
621
+		}
167 622
 	}
168 623
 
169
-	return prize, nil, record, err
624
+	return prize, &detail, record, err
625
+}
626
+
627
+// UpdateCstLuckdrawSurplus 更新用户抽奖剩余次数
628
+func (m *LuckDrawDao) UpdateCstLuckdrawSurplus(cstLuckDraw *model.TaLuckdrawCustomer) error {
629
+	sql := `update ta_luckdraw_customer set share_surplus_num = (case when surplus_num > share_surplus_num then share_surplus_num else share_surplus_num - 1 end),
630
+	surplus_num = surplus_num - 1 where luckdraw_customer_id = ? and surplus_num>0`
631
+	res, err := m.db.Exec(sql, cstLuckDraw.LuckdrawCustomerId)
632
+	if err != nil {
633
+		return err
634
+	}
635
+	len, _ := res.RowsAffected()
636
+	if len < 1 {
637
+		return errors.New("您没有剩余次数!")
638
+	}
639
+	return nil
640
+}
641
+
642
+// UpdateLuckDrawJoinedNum 更新抽奖参与人数
643
+func (m *LuckDrawDao) UpdateLuckDrawJoinedNum(id string) error {
644
+	var records []model.TaLuckdrawRecord
645
+	sql := `select DISTINCT user_id from ta_luckdraw_record where luckdraw_id=?`
646
+	err := m.db.Sql(sql, id).Find(&records)
647
+	if err != nil {
648
+		return err
649
+	}
650
+	if len(records) > 0 {
651
+		sql = `update ta_luckdraw set joined_num=? where id=?`
652
+		_, err = m.db.Exec(sql, len(records), id)
653
+		return err
654
+	}
655
+	return nil
656
+}
657
+
658
+// PrizeWithDefault 默认奖品
659
+type PrizeWithDefault struct {
660
+	DefaultId             string
661
+	model.TaLuckdrawPrize `xorm:"extends"`
662
+}
663
+
664
+// GetPrizeDefaultByUser 获取默认用户
665
+func (m *LuckDrawDao) GetPrizeDefaultByUser(id string, customer *model.TaCustomer) (*PrizeWithDefault, error) {
666
+	var prize = PrizeWithDefault{}
667
+	sql := `select a.default_id,b.* from ta_prize_default a inner join ta_luckdraw_prize b on a.prize_id=b.id where a.luckdraw_id=? and a.tel=? and a.is_receive=?`
668
+	_, err := m.db.Sql(sql, id, customer.Phone, models.BOOL_FALSE).Get(&prize)
669
+	return &prize, err
670
+}
671
+
672
+// UpdatePrizeDefault 更新系统内置信息
673
+func (m *LuckDrawDao) UpdatePrizeDefault(id, recordid string) error {
674
+	var prizeDefault = model.TaPrizeDefault{
675
+		DefaultId:   id,
676
+		ReceiveDate: time.Now(),
677
+		ReceiveId:   recordid,
678
+		IsReceive:   models.BOOL_TRUE,
679
+	}
680
+	cols := []string{
681
+		"receive_id",
682
+		"receive_date",
683
+		"is_receive",
684
+	}
685
+	_, err := m.db.Cols(cols...).Where("default_id=?", prizeDefault.DefaultId).Update(prizeDefault)
686
+	return err
687
+}
688
+
689
+// GetCustomerLuckDraw 获取用户抽奖设置
690
+func (m *LuckDrawDao) GetCustomerLuckDraw(luckdrawid, customerid string) (*model.TaLuckdrawCustomer, error) {
691
+	var customerluckdraw model.TaLuckdrawCustomer
692
+	_, err := m.db.Where("luckdraw_id=?", luckdrawid).And("customer_id=?", customerid).Get(&customerluckdraw)
693
+	if err != nil {
694
+		return nil, err
695
+	}
696
+	return &customerluckdraw, nil
170 697
 }
171 698
 
172 699
 // PrizeWriteOff 奖品核销
@@ -196,7 +723,7 @@ func (m *LuckDrawDao) GetWinning(prizes []model.TaLuckdrawPrize) (*model.TaLuckd
196 723
 
197 724
 	for _, prize := range prizes {
198 725
 		// 有剩余的 并且 未过期的
199
-		if prize.Remainder > 0 && now.Before(prize.VerificationEnd) {
726
+		if (prize.Remainder > 0 && (now.Before(prize.VerificationEnd) || prize.ValidDays > 0)) || prize.IsReality == models.BOOL_FALSE {
200 727
 			p := map[string]interface{}{
201 728
 				"prize": prize,
202 729
 				"prob":  prize.Probability,
@@ -258,9 +785,11 @@ func (m *LuckDrawDao) UpdateLuckDrawEndDate(id string) error {
258 785
 	var luckdraw = model.TaLuckdraw{
259 786
 		Id:      id,
260 787
 		EndDate: time.Now(),
788
+		Status:  models.STATUS_EXPIRE,
261 789
 	}
262 790
 	cols := []string{
263 791
 		"end_date",
792
+		"status",
264 793
 	}
265 794
 	_, err := m.db.Cols(cols...).Where("id=?", id).Update(luckdraw)
266 795
 	return err
@@ -273,17 +802,56 @@ func (m *LuckDrawDao) GetPrizes(luckdrawid string) ([]model.TaLuckdrawPrize, err
273 802
 	return prizes, err
274 803
 }
275 804
 
805
+// GetPrizesWithDefaults 获取奖品
806
+func (m *LuckDrawDao) GetPrizesWithDefaults(luckdrawid string) ([]PrizeWithDefaults, error) {
807
+	var prizes []PrizeWithDefaults
808
+	sql := `select * from ta_luckdraw_prize where luckdraw_id=? and status=?`
809
+	err := m.db.Sql(sql, luckdrawid, models.STATUS_NORMAL).Find(&prizes)
810
+	if err != nil {
811
+		return nil, err
812
+	}
813
+	for inx, prize := range prizes {
814
+		defaults, err := m.GetDefaultsByPrize(prize.Id)
815
+		if err != nil {
816
+			return nil, err
817
+		}
818
+		prizes[inx].Defaults = defaults
819
+	}
820
+	return prizes, err
821
+}
822
+
823
+// GetDefaultsByPrize 根据奖品获取内定信息
824
+func (m *LuckDrawDao) GetDefaultsByPrize(prizeid string) ([]model.TaPrizeDefault, error) {
825
+	var defaults []model.TaPrizeDefault
826
+	err := m.db.Where("prize_id=?", prizeid).Find(&defaults)
827
+	return defaults, err
828
+}
829
+
276 830
 // UpdateStock 修改库存
277 831
 func (m *LuckDrawDao) UpdateStock(prize *model.TaLuckdrawPrize) error {
278
-	cols := []string{
279
-		"remainder",
280
-	}
281
-	_, err := m.db.Cols(cols...).Where("id=?", prize.Id).Update(prize)
832
+	sql := `update ta_luckdraw_prize set remainder = remainder - 1 where id=?`
833
+	_, err := m.db.Exec(sql, prize.Id)
834
+	// cols := []string{
835
+	// 	"remainder",
836
+	// }
837
+	// _, err := m.db.Cols(cols...).Where("id=?", prize.Id).Update(prize)
282 838
 	return err
283 839
 }
284 840
 
285 841
 // GetPrizeStock 判断奖项库存
286 842
 func (m *LuckDrawDao) GetPrizeStock(luckdrawid string) ([]model.TaLuckdrawPrize, error) {
843
+	var prizes []model.TaLuckdrawPrize
844
+	sql := `select a.remainder-(case when b.default_num is null then 0 else b.default_num end) as remainder,
845
+	a.* from ta_luckdraw_prize a 
846
+	left join (select prize_id,count(1) as default_num from ta_prize_default where luckdraw_id=? and is_receive=0 group by prize_id) b 
847
+	on a.id=b.prize_id where a.luckdraw_id=? and a.status=? and (a.remainder-(case when b.default_num is null then 0 else b.default_num end)>0 or is_reality=0)`
848
+	err := m.db.Sql(sql, luckdrawid, luckdrawid, models.STATUS_NORMAL).Find(&prizes)
849
+	// err := m.db.Where("luckdraw_id=?", luckdrawid).And("status=?", models.STATUS_NORMAL).And("(remainder>0 or is_reality=0)").Find(&prizes)
850
+	return prizes, err
851
+}
852
+
853
+// GetPrizeStockAll 获取奖项
854
+func (m *LuckDrawDao) GetPrizeStockAll(luckdrawid string) ([]model.TaLuckdrawPrize, error) {
287 855
 	var prizes []model.TaLuckdrawPrize
288 856
 	err := m.db.Where("luckdraw_id=?", luckdrawid).And("status=?", models.STATUS_NORMAL).And("(remainder>0 or is_reality=0)").Find(&prizes)
289 857
 	return prizes, err
@@ -300,7 +868,7 @@ func (m *LuckDrawDao) GetPrizeByID(id string) (model.TaLuckdrawPrize, error) {
300 868
 func (m *LuckDrawDao) SaveRecord(record model.TaLuckdrawRecord) (*model.TaLuckdrawRecord, error) {
301 869
 	record.CreateDate = time.Now()
302 870
 	record.Status = models.STATUS_READY
303
-	record.Id = utils.GetGUID()
871
+	// record.Id = utils.GetGUID()
304 872
 	_, err := m.db.Insert(&record)
305 873
 	return &record, err
306 874
 }
@@ -340,7 +908,7 @@ func (m *LuckDrawDao) UpdateRecord(record *LuckInfo) error {
340 908
 		"status",
341 909
 		"writeoff_date",
342 910
 	}
343
-	_, err := m.db.Cols(cols...).Where("id=?", record.Id).Update(record)
911
+	_, err := m.db.Cols(cols...).Where("id=?", record.Id).Update(record.TaLuckdrawRecord)
344 912
 	return err
345 913
 }
346 914
 
@@ -360,6 +928,37 @@ func (m *LuckDrawDao) GetUserRecordByLuckDraw(userid string, luckdrawid string)
360 928
 	return records, err
361 929
 }
362 930
 
931
+// GetUserLuckDrawSet 获取用户抽奖设置
932
+func (m *LuckDrawDao) GetUserLuckDrawSet(customer model.TaCustomer, luckdrawid string) (*model.TaLuckdrawCustomer, error) {
933
+	var cstluckdraw = model.TaLuckdrawCustomer{}
934
+	_, err := m.db.Where("customer_id=?", customer.CustomerId).And("luckdraw_id=?", luckdrawid).Get(&cstluckdraw)
935
+	if err != nil {
936
+		return nil, err
937
+	}
938
+	if cstluckdraw.CustomerId != "" {
939
+		return &cstluckdraw, nil
940
+	}
941
+	// 插入
942
+	luckdraw, err := m.GetLuckDrawByID(luckdrawid)
943
+	if err != nil {
944
+		return nil, err
945
+	}
946
+	surplusNum := luckdraw.LuckdrawNum
947
+	isnew := 0
948
+	if customer.Phone == "" {
949
+		isnew = 1
950
+	}
951
+	if luckdraw.JoinType == models.JOINTYPE_NEWUSER && isnew != 1 {
952
+		surplusNum = 0
953
+	}
954
+	cstluckdraw.CustomerId = customer.CustomerId
955
+	cstluckdraw.IsNew = isnew
956
+	cstluckdraw.LuckdrawId = luckdrawid
957
+	cstluckdraw.SurplusNum = surplusNum
958
+	newinfo, err := m.AddCustomerLuckDraw(cstluckdraw)
959
+	return newinfo, err
960
+}
961
+
363 962
 // GetUserLuckDrawByLuckDraw 获取用户的抽奖信息
364 963
 func (m *LuckDrawDao) GetUserLuckDrawByLuckDraw(userid string, luckdrawid string) (*model.TaLuckdrawRecord, error) {
365 964
 	var records []model.TaLuckdrawRecord
@@ -395,7 +994,7 @@ type UserRecord struct {
395 994
 // GetUserLuckDraw 获取用户的抽奖信息
396 995
 func (m *LuckDrawDao) GetUserLuckDraw(userid string) ([]UserRecord, error) {
397 996
 	var records []UserRecord
398
-	sql := `select a.*,b.url from ta_luckdraw_record a left join ta_prize_detail b on a.id=b.receive_id where a.user_id=? and a.status>` + strconv.Itoa(models.STATUS_DEL)
997
+	sql := `select a.*,b.url from ta_luckdraw_record a left join ta_prize_detail b on a.id=b.receive_id where a.user_id=? and a.status>` + strconv.Itoa(models.STATUS_DEL) + ` order by a.create_date desc`
399 998
 	err := m.db.Sql(sql, userid).Find(&records)
400 999
 	return records, err
401 1000
 }
@@ -438,7 +1037,7 @@ func (m *LuckDrawDao) SaveLuckDrawShareData(dt *model.TaShareLuckyRecord) error
438 1037
 	return nil
439 1038
 }
440 1039
 
441
-// GetLuckDrawShareData 获取用户分享内容
1040
+// GetLuckDrawShareData 获取用户分 享内容
442 1041
 func (m *LuckDrawDao) GetLuckDrawShareData(from, to, luckID, caseID string) ([]model.TaShareLuckyRecord, error) {
443 1042
 	var dts []model.TaShareLuckyRecord
444 1043
 
@@ -453,3 +1052,19 @@ func (m *LuckDrawDao) GetLuckDrawShareData(from, to, luckID, caseID string) ([]m
453 1052
 
454 1053
 	return dts, nil
455 1054
 }
1055
+
1056
+// UpdateShareNum 分享增加抽奖次数
1057
+func (m *LuckDrawDao) UpdateShareNum(luckdraw *LuckDraw, from string) error {
1058
+	num := strconv.Itoa(luckdraw.ShareAddNum)
1059
+	sql := `update ta_luckdraw_customer set share_num=share_num+` + num + `,share_surplus_num = share_surplus_num +` + num + ` ,surplus_num = surplus_num+` + num + ` where luckdraw_id=? and customer_id=?`
1060
+	_, err := m.db.Exec(sql, luckdraw.Id, from)
1061
+	return err
1062
+}
1063
+
1064
+// GetLuckDrawCustomerNum 获取抽奖人数
1065
+func (m *LuckDrawDao) GetLuckDrawCustomerNum(luckdrawid string) (int, error) {
1066
+	var records []model.TaLuckdrawRecord
1067
+	sql := `select DISTINCT user_id from ta_luckdraw_record where luckdraw_id=?`
1068
+	err := m.db.Sql(sql, luckdrawid).Find(&records)
1069
+	return len(records), err
1070
+}

+ 2
- 2
models/luckdrawlist/luckdrawlist.go Просмотреть файл

@@ -100,8 +100,8 @@ FROM
100 100
 	INNER JOIN ta_customer d ON a.user_id = d.customer_id
101 101
 	INNER JOIN ta_luckdraw_prize e ON e.id = a.prize_id 
102 102
 WHERE
103
-	 DATE_FORMAT( e.verification_start, '%Y-%m-%d' ) <= DATE_FORMAT( NOW( ), '%Y-%m-%d' )
104
-	 AND DATE_FORMAT( e.verification_end, '%Y-%m-%d' ) >= DATE_FORMAT( NOW( ), '%Y-%m-%d' )
103
+	 DATE_FORMAT( a.verification_start, '%Y-%m-%d' ) <= DATE_FORMAT( NOW( ), '%Y-%m-%d' )
104
+	 AND DATE_FORMAT( a.verification_end, '%Y-%m-%d' ) >= DATE_FORMAT( NOW( ), '%Y-%m-%d' )
105 105
 	 AND a.id = '` + luckdrawId + `'
106 106
 	 and b.case_id in ('` + strings.Replace(caseids, ",", "','", -1) + `')`
107 107
 	err := m.db.Sql(sql).Find(&luckdraw)

+ 11
- 0
models/marketing/marketing.go Просмотреть файл

@@ -136,3 +136,14 @@ func (m *MarketingDAO) UpdateMarketing(activity model.SysActivity) error {
136 136
 	_, err := m.db.Cols(cols...).Where("action_id=?", activity.ActivityId).Update(activity)
137 137
 	return err
138 138
 }
139
+
140
+func (m *MarketingDAO) GetUserCases(caseid string) ([]model.SysCase, error) {
141
+	var cases []model.SysCase
142
+	sql := `SELECT
143
+	* 
144
+FROM
145
+	sys_case 
146
+WHERE case_id in ('` + strings.Replace(caseid, ",", "','", -1) + `')`
147
+	err := m.db.Sql(sql).Find(&cases)
148
+	return cases, err
149
+}

+ 1
- 0
models/model/sys_activity_action.go Просмотреть файл

@@ -6,4 +6,5 @@ type SysActivityAction struct {
6 6
 	ActiveType   string `xorm:"comment('赠送还是取消赠送之类的') VARCHAR(5)"`
7 7
 	ResourceType string `xorm:"VARCHAR(20)"`
8 8
 	ResourceDesc string `xorm:"VARCHAR(500)"`
9
+	ResourceId   string `xorm:"VARCHAR(500)"`
9 10
 }

+ 13
- 12
models/model/sys_user.go Просмотреть файл

@@ -5,16 +5,17 @@ import (
5 5
 )
6 6
 
7 7
 type SysUser struct {
8
-	UserId     string    `xorm:"not null pk VARCHAR(64)"`
9
-	UserName   string    `xorm:"not null VARCHAR(50)"`
10
-	RealName   string    `xorm:"VARCHAR(50)"`
11
-	Pwd        string    `xorm:"VARCHAR(500)"`
12
-	OrgId      string    `xorm:"VARCHAR(64)"`
13
-	Sex        int       `xorm:"SMALLINT(6)"`
14
-	WorkNo     string    `xorm:"VARCHAR(100)"`
15
-	Email      string    `xorm:"VARCHAR(100)"`
16
-	Phone      string    `xorm:"VARCHAR(100)"`
17
-	Status     int       `xorm:"SMALLINT(6)"`
18
-	CreateDate time.Time `xorm:"DATETIME"`
19
-	Headimgurl string    `xorm:"TEXT"`
8
+	UserId        string    `xorm:"not null pk VARCHAR(64)"`
9
+	UserName      string    `xorm:"not null VARCHAR(50)"`
10
+	RealName      string    `xorm:"VARCHAR(50)"`
11
+	Pwd           string    `xorm:"VARCHAR(500)"`
12
+	OrgId         string    `xorm:"VARCHAR(64)"`
13
+	Sex           int       `xorm:"SMALLINT(6)"`
14
+	WorkNo        string    `xorm:"VARCHAR(100)"`
15
+	Email         string    `xorm:"VARCHAR(100)"`
16
+	Phone         string    `xorm:"VARCHAR(100)"`
17
+	Status        int       `xorm:"SMALLINT(6)"`
18
+	CreateDate    time.Time `xorm:"DATETIME"`
19
+	Headimgurl    string    `xorm:"TEXT"`
20
+	RecommendCode string    `xorm:"VARCHAR(32)"`
20 21
 }

+ 19
- 0
models/model/ta_customer_flash_buy.go Просмотреть файл

@@ -0,0 +1,19 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaCustomerFlashBuy struct {
8
+	CustomerFlashBuyId string    `xorm:"not null pk VARCHAR(64)"`
9
+	FlashBuyId         string    `xorm:"VARCHAR(64)"`
10
+	CustomerId         string    `xorm:"VARCHAR(64)"`
11
+	ValidateStart      time.Time `xorm:"DATETIME"`
12
+	ValidateEnd        time.Time `xorm:"DATETIME"`
13
+	CreateDate         time.Time `xorm:"DATETIME"`
14
+	Status             int       `xorm:"SMALLINT(6)"`
15
+	VerifyStatus       string    `xorm:"VARCHAR(32)"`
16
+	VerifyDate         time.Time `xorm:"DATETIME"`
17
+	CaseId             string    `xorm:"VARCHAR(64)"`
18
+	OrgId              string    `xorm:"VARCHAR(64)"`
19
+}

+ 24
- 0
models/model/ta_customer_vip.go Просмотреть файл

@@ -0,0 +1,24 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaCustomerVip struct {
8
+	CustomerVipId  string    `xorm:"not null VARCHAR(64)"`
9
+	CustomerId     string    `xorm:"VARCHAR(64)"`
10
+	VipCardId      string    `xorm:"VARCHAR(64)"`
11
+	VipCardChildId string    `xorm:"VARCHAR(64)"`
12
+	CustomerTel    string    `xorm:"VARCHAR(50)"`
13
+	CreateDate     time.Time `xorm:"DATETIME"`
14
+	Amount         string    `xorm:"DECIMAL(8,2)"`
15
+	BeginDate      time.Time `xorm:"DATETIME"`
16
+	EndDate        time.Time `xorm:"DATETIME"`
17
+	Balance        string    `xorm:"DECIMAL(8,2)"`
18
+	PayAmount      string    `xorm:"DECIMAL(8,2)"`
19
+	CaseId         string    `xorm:"VARCHAR(64)"`
20
+	OrgId          string    `xorm:"VARCHAR(64)"`
21
+	Status         int       `xorm:"SMALLINT(6)"`
22
+	SalesId        string    `xorm:"VARCHAR(64)"`
23
+	SalesName      string    `xorm:"VARCHAR(50)"`
24
+}

+ 22
- 0
models/model/ta_customer_vip_change.go Просмотреть файл

@@ -0,0 +1,22 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaCustomerVipChange struct {
8
+	ChangeId      string    `xorm:"not null VARCHAR(64)"`
9
+	CustomerVipId string    `xorm:"VARCHAR(64)"`
10
+	CustomerId    string    `xorm:"VARCHAR(64)"`
11
+	OrgId         string    `xorm:"VARCHAR(64)"`
12
+	CaseId        string    `xorm:"VARCHAR(64)"`
13
+	ChangeType    string    `xorm:"VARCHAR(20)"`
14
+	ChangeSource  string    `xorm:"VARCHAR(20)"`
15
+	SourceId      string    `xorm:"VARCHAR(64)"`
16
+	SourceName    string    `xorm:"VARCHAR(255)"`
17
+	Amount        string    `xorm:"DECIMAL(8,2)"`
18
+	FloatType     string    `xorm:"VARCHAR(5)"`
19
+	CreateDate    time.Time `xorm:"DATETIME"`
20
+	CreateUser    string    `xorm:"VARCHAR(64)"`
21
+	Status        int       `xorm:"SMALLINT(6)"`
22
+}

+ 26
- 0
models/model/ta_flash_buy.go Просмотреть файл

@@ -0,0 +1,26 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaFlashBuy struct {
8
+	FlashBuyId           string    `xorm:"not null pk VARCHAR(64)"`
9
+	ModelId              string    `xorm:"VARCHAR(64)"`
10
+	FlashBuyName         string    `xorm:"VARCHAR(64)"`
11
+	AttendantType        string    `xorm:"VARCHAR(32)"`
12
+	FlashBuyMaxAttendant int       `xorm:"INT(11)"`
13
+	JoinNum              int       `xorm:"INT(11)"`
14
+	FlashBuyStatus       string    `xorm:"VARCHAR(32)"`
15
+	StartDate            time.Time `xorm:"DATETIME"`
16
+	EndDate              time.Time `xorm:"DATETIME"`
17
+	ValidateType         string    `xorm:"VARCHAR(32)"`
18
+	ValidateDays         int       `xorm:"INT(11)"`
19
+	ValidateStart        time.Time `xorm:"DATETIME"`
20
+	ValidateEnd          time.Time `xorm:"DATETIME"`
21
+	Status               int       `xorm:"SMALLINT(6)"`
22
+	FlashBuyInfo         string    `xorm:"TEXT"`
23
+	CaseId               string    `xorm:"VARCHAR(64)"`
24
+	OrgId                string    `xorm:"VARCHAR(64)"`
25
+	CreateDate           time.Time `xorm:"DATETIME"`
26
+}

+ 14
- 0
models/model/ta_flash_buy_customer.go Просмотреть файл

@@ -0,0 +1,14 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaFlashBuyCustomer struct {
8
+	FlashBuyCustomerId string    `xorm:"not null VARCHAR(64)"`
9
+	FlashBuyId         string    `xorm:"VARCHAR(64)"`
10
+	CustomerId         string    `xorm:"VARCHAR(64)"`
11
+	IsNew              int       `xorm:"TINYINT(1)"`
12
+	IsAttend           int       `xorm:"TINYINT(1)"`
13
+	CreateDate         time.Time `xorm:"DATETIME"`
14
+}

+ 23
- 12
models/model/ta_luckdraw.go Просмотреть файл

@@ -5,16 +5,27 @@ import (
5 5
 )
6 6
 
7 7
 type TaLuckdraw struct {
8
-	Id           string    `xorm:"not null pk VARCHAR(64)"`
9
-	Name         string    `xorm:"VARCHAR(50)"`
10
-	ThemeId      string    `xorm:"VARCHAR(64)"`
11
-	LuckdrawRule string    `xorm:"TEXT"`
12
-	BeginDate    time.Time `xorm:"DATETIME"`
13
-	EndDate      time.Time `xorm:"DATETIME"`
14
-	OrgId        string    `xorm:"VARCHAR(64)"`
15
-	CaseId       string    `xorm:"VARCHAR(64)"`
16
-	CreateDate   time.Time `xorm:"DATETIME"`
17
-	CreateUser   string    `xorm:"VARCHAR(64)"`
18
-	Remark       string    `xorm:"TEXT"`
19
-	Status       int       `xorm:"SMALLINT(6)"`
8
+	Id                string    `xorm:"not null pk VARCHAR(64)"`
9
+	Name              string    `xorm:"VARCHAR(50)"`
10
+	ThemeId           string    `xorm:"VARCHAR(64)"`
11
+	LuckdrawRule      string    `xorm:"TEXT"`
12
+	BeginDate         time.Time `xorm:"DATETIME"`
13
+	EndDate           time.Time `xorm:"DATETIME"`
14
+	OrgId             string    `xorm:"VARCHAR(64)"`
15
+	CaseId            string    `xorm:"VARCHAR(64)"`
16
+	CreateDate        time.Time `xorm:"DATETIME"`
17
+	CreateUser        string    `xorm:"VARCHAR(64)"`
18
+	Remark            string    `xorm:"TEXT"`
19
+	Status            int       `xorm:"SMALLINT(6)"`
20
+	TplId             string    `xorm:"VARCHAR(64)"`
21
+	JoinedNum         int       `xorm:"default 0 INT(11)"`
22
+	JoinNum           int       `xorm:"default 0 INT(11)"`
23
+	JoinType          string    `xorm:"VARCHAR(20)"`
24
+	NumType           string    `xorm:"VARCHAR(20)"`
25
+	NumInterval       string    `xorm:"VARCHAR(20)"`
26
+	LuckdrawNum       int       `xorm:"default 0 INT(11)"`
27
+	ShareType         string    `xorm:"VARCHAR(20)"`
28
+	ShareAddNum       int       `xorm:"SMALLINT(6)"`
29
+	IsSysLuckdraw     int       `xorm:"TINYINT(1)"`
30
+	IsInternalDefault int       `xorm:"TINYINT(1)"`
20 31
 }

+ 16
- 0
models/model/ta_luckdraw_customer.go Просмотреть файл

@@ -0,0 +1,16 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaLuckdrawCustomer struct {
8
+	LuckdrawCustomerId string    `xorm:"not null VARCHAR(64)"`
9
+	LuckdrawId         string    `xorm:"VARCHAR(64)"`
10
+	CustomerId         string    `xorm:"VARCHAR(64)"`
11
+	IsNew              int       `xorm:"TINYINT(1)"`
12
+	ShareNum           int       `xorm:"INT(11)"`
13
+	ShareSurplusNum    int       `xorm:"INT(11)"`
14
+	SurplusNum         int       `xorm:"INT(11)"`
15
+	CreateDate         time.Time `xorm:"DATETIME"`
16
+}

+ 9
- 0
models/model/ta_luckdraw_img.go Просмотреть файл

@@ -0,0 +1,9 @@
1
+package model
2
+
3
+type TaLuckdrawImg struct {
4
+	ImgId      string `xorm:"not null VARCHAR(64)"`
5
+	LuckdrawId string `xorm:"VARCHAR(64)"`
6
+	ImgUrl     string `xorm:"TEXT"`
7
+	Status     int    `xorm:"SMALLINT(6)"`
8
+	OrgId      string `xorm:"VARCHAR(64)"`
9
+}

+ 4
- 0
models/model/ta_luckdraw_prize.go Просмотреть файл

@@ -16,6 +16,10 @@ type TaLuckdrawPrize struct {
16 16
 	PrizeLink         string    `xorm:"TEXT"`
17 17
 	Status            int       `xorm:"SMALLINT(6)"`
18 18
 	IsReality         int       `xorm:"SMALLINT(6)"`
19
+	ValidDays         int       `xorm:"INT(11)"`
19 20
 	VerificationStart time.Time `xorm:"DATETIME"`
20 21
 	VerificationEnd   time.Time `xorm:"DATETIME"`
22
+	PrizeType         string    `xorm:"VARCHAR(20)"`
23
+	CouponCardType    string    `xorm:"VARCHAR(20)"`
24
+	CouponCardId      string    `xorm:"VARCHAR(64)"`
21 25
 }

+ 18
- 12
models/model/ta_luckdraw_record.go Просмотреть файл

@@ -5,16 +5,22 @@ import (
5 5
 )
6 6
 
7 7
 type TaLuckdrawRecord struct {
8
-	Id           string    `xorm:"not null pk VARCHAR(64)"`
9
-	LuckdrawId   string    `xorm:"VARCHAR(64)"`
10
-	PrizeId      string    `xorm:"VARCHAR(64)"`
11
-	PrizeName    string    `xorm:"VARCHAR(50)"`
12
-	UserId       string    `xorm:"VARCHAR(64)"`
13
-	UserName     string    `xorm:"VARCHAR(50)"`
14
-	UserHeadImg  string    `xorm:"TEXT"`
15
-	CreateDate   time.Time `xorm:"DATETIME"`
16
-	Status       int       `xorm:"SMALLINT(6)"`
17
-	WriteoffDate time.Time `xorm:"DATETIME"`
18
-	OrgId        string    `xorm:"VARCHAR(64)"`
19
-	CaseId       string    `xorm:"VARCHAR(64)"`
8
+	Id                string    `xorm:"not null pk VARCHAR(64)"`
9
+	LuckdrawId        string    `xorm:"VARCHAR(64)"`
10
+	PrizeId           string    `xorm:"VARCHAR(64)"`
11
+	PrizeName         string    `xorm:"VARCHAR(50)"`
12
+	IsReality         int       `xorm:"SMALLINT(6)"`
13
+	UserId            string    `xorm:"VARCHAR(64)"`
14
+	UserName          string    `xorm:"VARCHAR(50)"`
15
+	UserHeadImg       string    `xorm:"TEXT"`
16
+	CreateDate        time.Time `xorm:"DATETIME"`
17
+	Status            int       `xorm:"SMALLINT(6)"`
18
+	WriteoffDate      time.Time `xorm:"DATETIME"`
19
+	OrgId             string    `xorm:"VARCHAR(64)"`
20
+	CaseId            string    `xorm:"VARCHAR(64)"`
21
+	PrizeType         string    `xorm:"VARCHAR(20)"`
22
+	CouponCardType    string    `xorm:"VARCHAR(20)"`
23
+	CouponCardId      string    `xorm:"VARCHAR(64)"`
24
+	VerificationStart time.Time `xorm:"DATETIME"`
25
+	VerificationEnd   time.Time `xorm:"DATETIME"`
20 26
 }

+ 10
- 0
models/model/ta_luckdraw_tpl.go Просмотреть файл

@@ -0,0 +1,10 @@
1
+package model
2
+
3
+type TaLuckdrawTpl struct {
4
+	TplId   string `xorm:"not null VARCHAR(128)"`
5
+	TplImg  string `xorm:"TEXT"`
6
+	MiniPic string `xorm:"TEXT"`
7
+	Status  int    `xorm:"SMALLINT(6)"`
8
+	OrgId   string `xorm:"VARCHAR(64)"`
9
+	TplName string `xorm:"VARCHAR(50)"`
10
+}

+ 17
- 0
models/model/ta_prize_default.go Просмотреть файл

@@ -0,0 +1,17 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaPrizeDefault struct {
8
+	DefaultId   string    `xorm:"not null VARCHAR(64)"`
9
+	LuckdrawId  string    `xorm:"VARCHAR(64)"`
10
+	PrizeId     string    `xorm:"VARCHAR(64)"`
11
+	Tel         string    `xorm:"VARCHAR(30)"`
12
+	Status      int       `xorm:"SMALLINT(6)"`
13
+	CreateDate  time.Time `xorm:"DATETIME"`
14
+	IsReceive   int       `xorm:"TINYINT(1)"`
15
+	ReceiveId   string    `xorm:"VARCHAR(64)"`
16
+	ReceiveDate time.Time `xorm:"DATETIME"`
17
+}

+ 19
- 0
models/model/ta_sale_customer.go Просмотреть файл

@@ -0,0 +1,19 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaSaleCustomer struct {
8
+	SaleCustomerId string    `xorm:"not null VARCHAR(64)"`
9
+	CustomerName   string    `xorm:"VARCHAR(32)"`
10
+	CustomerPhone  string    `xorm:"VARCHAR(32)"`
11
+	CustomerId     string    `xorm:"VARCHAR(64)"`
12
+	SalesPhone     string    `xorm:"VARCHAR(32)"`
13
+	SalesId        string    `xorm:"VARCHAR(64)"`
14
+	SalesName      string    `xorm:"VARCHAR(32)"`
15
+	Status         int       `xorm:"SMALLINT(6)"`
16
+	CreateDate     time.Time `xorm:"DATETIME"`
17
+	CaseId         string    `xorm:"VARCHAR(64)"`
18
+	OrgId          string    `xorm:"VARCHAR(64)"`
19
+}

+ 16
- 0
models/model/ta_sale_customer_remark.go Просмотреть файл

@@ -0,0 +1,16 @@
1
+package model
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+type TaSaleCustomerRemark struct {
8
+	SalesCustomerRemarkId string    `xorm:"not null VARCHAR(64)"`
9
+	SaleCustomerId        string    `xorm:"VARCHAR(64)"`
10
+	CustomerId            string    `xorm:"VARCHAR(64)"`
11
+	SalesId               string    `xorm:"VARCHAR(64)"`
12
+	RemarkTitle           string    `xorm:"VARCHAR(256)"`
13
+	Remark                string    `xorm:"TEXT"`
14
+	CreateDate            time.Time `xorm:"DATETIME"`
15
+	Status                int       `xorm:"SMALLINT(6)"`
16
+}

+ 2
- 0
models/model/ta_vip_card.go Просмотреть файл

@@ -13,4 +13,6 @@ type TaVipCard struct {
13 13
 	Status      int       `xorm:"SMALLINT(6)"`
14 14
 	CaseId      string    `xorm:"VARCHAR(64)"`
15 15
 	OrgId       string    `xorm:"VARCHAR(64)"`
16
+	BeginDate   time.Time `xorm:"DATETIME"`
17
+	EndDate     time.Time `xorm:"DATETIME"`
16 18
 }

+ 4
- 0
models/model/ta_vip_card_child.go Просмотреть файл

@@ -16,4 +16,8 @@ type TaVipCardChild struct {
16 16
 	Amount           string    `xorm:"DECIMAL(8,2)"`
17 17
 	SalesId          string    `xorm:"VARCHAR(64)"`
18 18
 	SalesName        string    `xorm:"VARCHAR(50)"`
19
+	BeginDate        time.Time `xorm:"DATETIME"`
20
+	EndDate          time.Time `xorm:"DATETIME"`
21
+	CaseId           string    `xorm:"VARCHAR(64)"`
22
+	OrgId            string    `xorm:"VARCHAR(64)"`
19 23
 }

+ 10
- 0
models/model/td_flashbuy_model.go Просмотреть файл

@@ -0,0 +1,10 @@
1
+package model
2
+
3
+type TdFlashbuyModel struct {
4
+	ModelId          string `xorm:"not null pk VARCHAR(64)"`
5
+	ModelName        string `xorm:"VARCHAR(64)"`
6
+	OrgId            string `xorm:"VARCHAR(64)"`
7
+	Status           int    `xorm:"SMALLINT(6)"`
8
+	ModelImgUrl      string `xorm:"TEXT"`
9
+	ModelLargeImgUrl string `xorm:"TEXT"`
10
+}

+ 8
- 5
models/models.go Просмотреть файл

@@ -1,6 +1,8 @@
1 1
 package models
2 2
 
3 3
 import (
4
+	"spaceofcheng/services/utils"
5
+
4 6
 	"github.com/astaxie/beego/config"
5 7
 	_ "github.com/go-sql-driver/mysql"
6 8
 	"github.com/go-xorm/xorm"
@@ -10,7 +12,7 @@ var (
10 12
 	DBEngine *xorm.Engine
11 13
 )
12 14
 
13
-func init() {
15
+func InitDB() {
14 16
 	DBEngine = NewDBEngine()
15 17
 }
16 18
 
@@ -29,8 +31,9 @@ func NewDBEngine() *xorm.Engine {
29 31
 	return engine
30 32
 }
31 33
 
32
-func getMySQLDNS() string {
33
-	dbconf, _ := config.NewConfig("ini", "conf/db.conf")
34
+func getMySQLDNS() (dns string) {
35
+	appRoot := utils.GetAppRoot()
36
+	dbconf, _ := config.NewConfig("ini", appRoot+"/conf/db.conf")
34 37
 
35 38
 	conProt := dbconf.DefaultString("con_protocol", "tcp")
36 39
 	dbAddr := dbconf.DefaultString("db_addr", "localhost")
@@ -40,7 +43,7 @@ func getMySQLDNS() string {
40 43
 	database := dbconf.String("database")
41 44
 	charSet := dbconf.DefaultString("char_set", "utf8")
42 45
 
43
-	dns := userName
46
+	dns = userName
44 47
 
45 48
 	if len(password) > 0 {
46 49
 		dns += ":" + password
@@ -48,5 +51,5 @@ func getMySQLDNS() string {
48 51
 
49 52
 	dns += "@" + conProt + "(" + dbAddr + ":" + dbPort + ")" + "/" + database + "?charset=" + charSet
50 53
 
51
-	return dns
54
+	return
52 55
 }

+ 9
- 9
models/statistics/cardcoupon.go Просмотреть файл

@@ -225,8 +225,8 @@ func (m *StatisticsDAO) CardCouponUsedStatistics(caseids, tel, name, receivetype
225 225
 							a.start_date,
226 226
 							a.end_date,
227 227
 							a.receive_date,
228
-							a.receive_date as used_date,
229
-							'used' as verify_status
228
+							a.verify_date as used_date,
229
+							a.verify_status
230 230
 						FROM
231 231
 							ta_customer_card a
232 232
 						INNER JOIN ta_coupon_card_target b ON b.card_id = a.card_id
@@ -265,7 +265,7 @@ func (m *StatisticsDAO) CardCouponUsedStatistics(caseids, tel, name, receivetype
265 265
 									) as used_date,
266 266
 									(
267 267
 										CASE
268
-										WHEN NOW() > a.end_date THEN
268
+										WHEN use_date IS NULL and NOW() > a.end_date THEN
269 269
 											'expire'
270 270
 										WHEN use_date IS NULL THEN
271 271
 											'useable'
@@ -278,8 +278,8 @@ func (m *StatisticsDAO) CardCouponUsedStatistics(caseids, tel, name, receivetype
278 278
 								INNER JOIN sys_case b ON a.case_id = b.case_id
279 279
 								INNER JOIN ta_customer cst ON a.customer_id = cst.customer_id
280 280
 								INNER JOIN ta_coupon cp ON a.coupon_id = cp.coupon_id
281
-								LEFT JOIN ta_goods_orders_coupon c ON a.coupon_id = c.coupon_id
282
-								LEFT JOIN ta_course_orders_coupon d ON a.coupon_id = d.coupon_id
281
+								LEFT JOIN ta_goods_orders_coupon c ON a.customer_coupon_id = c.customer_coupon_id
282
+								LEFT JOIN ta_course_orders_coupon d ON a.customer_coupon_id = d.customer_coupon_id
283 283
 								WHERE b.case_id in ('` + strings.Replace(caseids, ",", "','", -1) + `')`
284 284
 
285 285
 	sql := "select * from (" + cardsql + " union " + couponsql + ") tab where (1=1)"
@@ -325,7 +325,7 @@ func (m *StatisticsDAO) CardCouponUsedCountStatistics(caseids, tel, name, receiv
325 325
 							a.start_date,
326 326
 							a.end_date,
327 327
 							a.receive_date,
328
-							a.receive_date as used_date,
328
+							a.verify_date as used_date,
329 329
 							a.verify_status
330 330
 						FROM
331 331
 							ta_customer_card a
@@ -365,7 +365,7 @@ func (m *StatisticsDAO) CardCouponUsedCountStatistics(caseids, tel, name, receiv
365 365
 									) as used_date,
366 366
 									(
367 367
 										CASE
368
-										WHEN NOW() > a.end_date THEN
368
+										WHEN use_date IS NULL and NOW() > a.end_date THEN
369 369
 											'expire'
370 370
 										WHEN use_date IS NULL THEN
371 371
 											'useable'
@@ -378,8 +378,8 @@ func (m *StatisticsDAO) CardCouponUsedCountStatistics(caseids, tel, name, receiv
378 378
 								INNER JOIN sys_case b ON a.case_id = b.case_id
379 379
 								INNER JOIN ta_customer cst ON a.customer_id = cst.customer_id
380 380
 								INNER JOIN ta_coupon cp ON a.coupon_id = cp.coupon_id
381
-								LEFT JOIN ta_goods_orders_coupon c ON a.coupon_id = c.coupon_id
382
-								LEFT JOIN ta_course_orders_coupon d ON a.coupon_id = d.coupon_id
381
+								LEFT JOIN ta_goods_orders_coupon c ON a.customer_coupon_id = c.customer_coupon_id
382
+								LEFT JOIN ta_course_orders_coupon d ON a.customer_coupon_id = d.customer_coupon_id
383 383
 								WHERE b.case_id in ('` + strings.Replace(caseids, ",", "','", -1) + `')`
384 384
 
385 385
 	sql := "select * from (" + cardsql + " union " + couponsql + ") tab where (1=1)"

+ 2
- 1
models/statistics/goods.go Просмотреть файл

@@ -161,7 +161,8 @@ func (m *StatisticsDAO) GetGoodsOrderStatistics(status, usertype, caseids, begin
161 161
 					INNER JOIN sys_case d ON a.case_id = d.case_id
162 162
 					LEFT JOIN sys_user c ON b.user_id = c.user_id
163 163
 					LEFT JOIN sys_case_area e ON a.area_id =e.area_id
164
-					where d.case_id in ('` + strings.Replace(caseids, ",", "','", -1) + `')`
164
+					where d.case_id in ('` + strings.Replace(caseids, ",", "','", -1) + `')
165
+					and a.status > 0`
165 166
 
166 167
 	if usertype != "" {
167 168
 		sql = sql + ` and a.user_type='` + usertype + `'`

+ 16
- 0
models/sys.go Просмотреть файл

@@ -270,3 +270,19 @@ func GetAllCases() ([]model.SysCase, error) {
270 270
 	err := DBEngine.Where("status=?", STATUS_NORMAL).Asc("org_id").Find(&cases)
271 271
 	return cases, err
272 272
 }
273
+
274
+// GetCaseByID 获取案场
275
+func GetCaseByID(caseID string) (cs *model.SysCase, err error) {
276
+	cs = new(model.SysCase)
277
+
278
+	_, err = DBEngine.Where("case_id=?", caseID).Get(cs)
279
+	return cs, err
280
+}
281
+
282
+// GetAllOrgs 获取所有机构
283
+func GetAllOrgs() ([]model.SysOrg, error) {
284
+	var orgs []model.SysOrg
285
+	err := DBEngine.Where("status=?", STATUS_NORMAL).Asc("org_id").Find(&orgs)
286
+
287
+	return orgs, err
288
+}

+ 40
- 10
models/system/user.go Просмотреть файл

@@ -2,6 +2,7 @@ package system
2 2
 
3 3
 import (
4 4
 	"errors"
5
+	"math/rand"
5 6
 	"spaceofcheng/services/models"
6 7
 	"spaceofcheng/services/models/model"
7 8
 	"spaceofcheng/services/utils"
@@ -31,23 +32,30 @@ func NewUserDAO(ctx *utils.Context) *UserDAO {
31 32
 type UserListInfo struct {
32 33
 	model.SysUser `xorm:"extends"`
33 34
 	UserTypeNames string
35
+	CaseName      string
36
+}
37
+type CustomerInfo struct {
38
+	model.TaCustomer `xorm:"extends"`
39
+	Remark           string
34 40
 }
35 41
 
36 42
 // GetUserList 用户列表
37 43
 func (m *UserDAO) GetUserList(username, typeid, caseids string, page int, pageSize int) ([]UserListInfo, error) {
38 44
 	var users []UserListInfo
39
-	sql := `select user.*,c.user_type_names from sys_user user left join (
45
+	sql := `select user.*,c.user_type_names,d.case_name from sys_user user left join (
40 46
 		select a.user_id,GROUP_CONCAT(b.type_name) as user_type_names from sys_user_type a
41 47
 		INNER join td_user_type b on a.type_id = b.type_id
42
-		group by a.user_id) c on user.user_id = c.user_id where user.user_id != '` + models.ADMIN_ID + `' and
43
-		(status> ` + strconv.Itoa(models.STATUS_DEL) + ` and user_name like '%` + username + `%' and user.user_id in 
48
+		group by a.user_id) c on user.user_id = c.user_id
49
+		LEFT JOIN sys_user_case d on user.user_id=d.user_id and d.is_belong = 1
50
+		where user.user_id != '` + models.ADMIN_ID + `' and
51
+		(user.status> ` + strconv.Itoa(models.STATUS_DEL) + ` and user.user_name like '%` + username + `%' and user.user_id in 
44 52
 		(select user_id from sys_user_case where is_belong=1 and case_id in ('` + strings.Replace(caseids, ",", "','", -1) + `')))`
45 53
 
46 54
 	if typeid != "" {
47 55
 		sql = sql + " and user.user_id in (select user_id from sys_user_type where type_id = '" + typeid + "')"
48 56
 	}
49 57
 
50
-	sql = sql + " order by create_date desc limit " + strconv.Itoa((page-1)*pageSize) + ", " + strconv.Itoa(pageSize)
58
+	sql = sql + " order by user.create_date desc limit " + strconv.Itoa((page-1)*pageSize) + ", " + strconv.Itoa(pageSize)
51 59
 	err := m.db.Sql(sql).Find(&users)
52 60
 	return users, err
53 61
 }
@@ -171,6 +179,27 @@ func (m *UserDAO) AddUser(user model.SysUser) (*model.SysUser, error) {
171 179
 	return &user, err
172 180
 }
173 181
 
182
+func (m *UserDAO) GenerateRecommendCode() string {
183
+	var temp1 int = rand.Intn(9) * 87
184
+	var temp2 int = rand.Intn(9)
185
+	var temp3 int = rand.Intn(9) * 7
186
+	var code string = strconv.Itoa(temp1) + strconv.Itoa(temp2)
187
+	if len(code) < 4 {
188
+		code += strconv.Itoa(temp3)
189
+	}
190
+	if len(code) > 4 {
191
+		code = code[0:4]
192
+	}
193
+	return code
194
+}
195
+func (m *UserDAO) IsCodeExist(code string) (int, error) {
196
+	var user []model.SysUser
197
+	sql := `select * from sys_user where recommend_code = '` + code + `'`
198
+	err := m.db.Sql(sql).Find(&user)
199
+	return len(user), err
200
+
201
+}
202
+
174 203
 // UpdateUser 修改用户
175 204
 func (m *UserDAO) UpdateUser(user model.SysUser) error {
176 205
 	var col = []string{
@@ -389,11 +418,12 @@ func (m *UserDAO) UpdateCustomerHeadImg(customerid, username, imgurl string) err
389 418
 }
390 419
 
391 420
 // GetUserCustomer 获取我的推荐客户
392
-func (m *UserDAO) GetUserCustomer(userid, isrecommend, key string, page int, pageSize int) ([]model.TaCustomer, error) {
393
-	var customers []model.TaCustomer
394
-	sql := `select * from ta_customer where (recommend_id='` + userid + `'`
421
+func (m *UserDAO) GetUserCustomer(userid, isrecommend, key string, page int, pageSize int) ([]CustomerInfo, error) {
422
+	var customers []CustomerInfo
423
+	sql := `select a.*,
424
+	( SELECT remark FROM ta_sale_customer_remark b WHERE a.customer_id = b.customer_id ORDER BY b.create_date DESC LIMIT 1 ) AS remark from ta_customer a where (a.recommend_id='` + userid + `'`
395 425
 	if isrecommend == "" || isrecommend == "false" {
396
-		sql += ` or customer_id in (
426
+		sql += ` or a.customer_id in (
397 427
 			select customer_id from ta_customer_coupon where sales_id='` + userid + `'
398 428
 			union 
399 429
 			select customer_id from ta_customer_card where sales_id='` + userid + `'
@@ -401,10 +431,10 @@ func (m *UserDAO) GetUserCustomer(userid, isrecommend, key string, page int, pag
401 431
 	}
402 432
 	sql += ")"
403 433
 	if key != "" {
404
-		sql += ` and (customer_name like '%` + key + `%' or phone like '%` + key + `%' or name like '%` + key + `%')`
434
+		sql += ` and (a.customer_name like '%` + key + `%' or a.phone like '%` + key + `%' or a.name like '%` + key + `%')`
405 435
 	}
406 436
 	offset := (page - 1) * pageSize
407
-	sql += ` order by create_date desc LIMIT ` + strconv.Itoa(pageSize) + ` OFFSET ` + strconv.Itoa(offset)
437
+	sql += ` order by a.create_date desc LIMIT ` + strconv.Itoa(pageSize) + ` OFFSET ` + strconv.Itoa(offset)
408 438
 	err := m.db.Sql(sql).Find(&customers)
409 439
 	return customers, err
410 440
 }

+ 43
- 2
models/vipcard/vipcard.go Просмотреть файл

@@ -53,7 +53,7 @@ WHERE
53 53
 	}
54 54
 
55 55
 	if sellerName != "" {
56
-		sql = sql + ` and tc.recommend_name like '%` + sellerName + `%'`
56
+		sql = sql + ` and vcc.sales_name like '%` + sellerName + `%'`
57 57
 	}
58 58
 
59 59
 	if userName != "" {
@@ -83,7 +83,7 @@ WHERE
83 83
 	}
84 84
 
85 85
 	if sellerName != "" {
86
-		sql = sql + ` and tc.recommend_name like '%` + sellerName + `%'`
86
+		sql = sql + ` and vcc.sales_name like '%` + sellerName + `%'`
87 87
 	}
88 88
 
89 89
 	if userName != "" {
@@ -199,3 +199,44 @@ WHERE
199 199
 	err := m.db.Sql(sql).Find(&vipcards)
200 200
 	return vipcards, err
201 201
 }
202
+
203
+// AddCustomerVip 保存客户Vip卡信息
204
+func (m *VipcardDAO) AddCustomerVip(customerVip model.TaCustomerVip) (*model.TaCustomerVip, error) {
205
+	customerVip.CreateDate = time.Now()
206
+	customerVip.CustomerVipId = utils.GetGUID()
207
+	customerVip.Status = models.STATUS_NORMAL
208
+	_, err := m.db.Insert(customerVip)
209
+	return &customerVip, err
210
+}
211
+
212
+// InsertCustomerVipChange 保存客户Vip卡变动
213
+func (m *VipcardDAO) InsertCustomerVipChange(change model.TaCustomerVipChange) error {
214
+	change.ChangeId = utils.GetGUID()
215
+	change.Status = models.STATUS_NORMAL
216
+	change.CreateDate = time.Now()
217
+
218
+	_, err := m.db.Insert(change)
219
+	return err
220
+}
221
+
222
+// CustomerVipWithChange 用户vip卡关联变更
223
+type CustomerVipWithChange struct {
224
+	model.TaCustomerVip `xorm:"extends"`
225
+	Changes             []model.TaCustomerVipChange
226
+}
227
+
228
+// GetCustomerVips 获取客户vip卡信息
229
+func (m *VipcardDAO) GetCustomerVips(customerid string) ([]CustomerVipWithChange, error) {
230
+	var vips []CustomerVipWithChange
231
+	sql := `select * from ta_customer_vip where customer_id=? and status>?`
232
+	err := m.db.Sql(sql, customerid, models.STATUS_DEL).Find(&vips)
233
+	if err != nil {
234
+		return nil, err
235
+	}
236
+	for inx, vip := range vips {
237
+		var changes []model.TaCustomerVipChange
238
+		m.db.Where("customer_vip_id=?", vip.CustomerVipId).And("status>?", models.STATUS_DEL).Find(&changes)
239
+		vips[inx].Changes = changes
240
+	}
241
+	return vips, nil
242
+}

+ 32
- 3
routers/common.go Просмотреть файл

@@ -9,8 +9,10 @@ import (
9 9
 	"spaceofcheng/services/controllers/coupon"
10 10
 	"spaceofcheng/services/controllers/course"
11 11
 	"spaceofcheng/services/controllers/customer"
12
+	"spaceofcheng/services/controllers/flashbuy"
12 13
 	"spaceofcheng/services/controllers/goods"
13 14
 	"spaceofcheng/services/controllers/gymcard"
15
+	"spaceofcheng/services/controllers/luckdraw"
14 16
 	"spaceofcheng/services/controllers/luckdrawlist"
15 17
 	"spaceofcheng/services/controllers/marketing"
16 18
 	"spaceofcheng/services/controllers/message"
@@ -23,9 +25,7 @@ import (
23 25
 	"github.com/astaxie/beego"
24 26
 )
25 27
 
26
-func getCommonRoutes() beego.LinkNamespace {
27
-	prefix := beego.AppConfig.String("api::common")
28
-
28
+func getCommonRoutes(prefix string) beego.LinkNamespace {
29 29
 	return beego.NSNamespace(prefix,
30 30
 		// 商品分类
31 31
 		beego.NSRouter("/type/goods", &goods.GoodsController{}, "get:GetGoodsType"),
@@ -197,6 +197,19 @@ func getCommonRoutes() beego.LinkNamespace {
197 197
 		beego.NSRouter("luckdrawlist/verify/:luckdrawId", &luckdrawlist.LuckdrawlistController{}, "get:GetVerifyList"),
198 198
 		beego.NSRouter("luckdrawlist/verify/:luckdrawId", &luckdrawlist.LuckdrawlistController{}, "put:VerifyLuckdraw"),
199 199
 
200
+		beego.NSRouter("luckdrawtpl", &luckdraw.LuckDrawController{}, "get:GetLuckDrawTpl"),
201
+		beego.NSRouter("luckdraw", &luckdraw.LuckDrawController{}, "get:GetLuckDrawList"),
202
+		beego.NSRouter("luckdraw/:luckdrawid", &luckdraw.LuckDrawController{}, "get:GetLuckDrawByID"),
203
+		beego.NSRouter("luckdraw", &luckdraw.LuckDrawController{}, "post:SaveLuckDraw"),
204
+		beego.NSRouter("luckdraw/:luckdrawid", &luckdraw.LuckDrawController{}, "put:SaveLuckDraw"),
205
+		beego.NSRouter("luckdraw/:luckdrawid", &luckdraw.LuckDrawController{}, "delete:DelLuckDraw"),
206
+
207
+		beego.NSRouter("luckdraw/:luckdrawid/open", &luckdraw.LuckDrawController{}, "put:OpenLuckDraw"),
208
+		beego.NSRouter("luckdraw/:luckdrawid/stop", &luckdraw.LuckDrawController{}, "put:StopLuckDraw"),
209
+
210
+		beego.NSRouter("luckdraw/records/:luckdrawid", &luckdraw.LuckDrawController{}, "get:GetLuckDrawRecordList"),
211
+		beego.NSRouter("luckdraw/share/:luckdrawid", &luckdraw.LuckDrawController{}, "get:GetLuckDrawShareList"),
212
+
200 213
 		// bodychecklist 体检列表
201 214
 		beego.NSRouter("bodychecklist", &bodychecklist.BodychecklistController{}, "get:GetBodyCheckList"),
202 215
 		// role 角色
@@ -256,6 +269,7 @@ func getCommonRoutes() beego.LinkNamespace {
256 269
 		beego.NSRouter("/coupon/:id", &coupon.CouponController{}, "put:UpdateCoupon"),
257 270
 		beego.NSRouter("/coupon/:id/to/:users", &coupon.CouponController{}, "post:GiveCoupon"),
258 271
 		beego.NSRouter("/coupon/type/:type", &coupon.CouponController{}, "get:GetCouponBySendType"),
272
+		beego.NSRouter("/coupon/sys/:caseId", &coupon.CouponController{}, "get:GetSysCouponByCase"),
259 273
 
260 274
 		// 签到
261 275
 		beego.NSRouter("/case/signin", &cases.SigninController{}, "get:GetSigninWhere"),
@@ -267,11 +281,13 @@ func getCommonRoutes() beego.LinkNamespace {
267 281
 		beego.NSRouter("/card/:id", &card.CardController{}, "get:GetCardByIDForAdmin"),
268 282
 		beego.NSRouter("/card/:id", &card.CardController{}, "put:UpdateCard"),
269 283
 		beego.NSRouter("/card/:id/to/:users", &card.CardController{}, "post:GiveCard"),
284
+		beego.NSRouter("/card/sys/:caseId", &card.CardController{}, "get:GetSysCardList"),
270 285
 		// 赠送记录
271 286
 		beego.NSRouter("/record", &card.RecordController{}, "get:GetRecordList"),
272 287
 
273 288
 		// 文件
274 289
 		beego.NSRouter("/file", &controllers.BaseController{}, "post:FileUpload"),
290
+		beego.NSRouter("/file/base64", &controllers.BaseController{}, "post:UploadBase64Image"),
275 291
 
276 292
 		// 会员
277 293
 		beego.NSRouter("/customer", &customer.CustomerController{}, "get:CustWXList"),
@@ -288,6 +304,7 @@ func getCommonRoutes() beego.LinkNamespace {
288 304
 		beego.NSRouter("/marketing/normal/:activityId", &marketing.MarketingController{}, "put:SetMarketingNormal"),
289 305
 		beego.NSRouter("/marketing/disable/:activityId", &marketing.MarketingController{}, "put:SetMarketingDisable"),
290 306
 		beego.NSRouter("/marketing/:activityId", &marketing.MarketingController{}, "delete:DelMarketing"),
307
+		beego.NSRouter("/marketing/case", &marketing.MarketingController{}, "get:GetUserCases"),
291 308
 
292 309
 		// websocket
293 310
 		beego.NSRouter("/websocket/:grps/:id", &controllers.BaseController{}, "get:Ws"),
@@ -307,5 +324,17 @@ func getCommonRoutes() beego.LinkNamespace {
307 324
 		beego.NSRouter("/statistics/cardcouponused/excel", &statistics.StatisticsController{}, "get:CardCouponUsedStatisticsExcel"),
308 325
 		beego.NSRouter("/statistics/cardcouponverify", &statistics.StatisticsController{}, "get:CardCouponVerifyStatistics"),
309 326
 		beego.NSRouter("/statistics/cardcouponverify/excel", &statistics.StatisticsController{}, "get:CardCouponVerifyStatisticsExcel"),
327
+
328
+		// flashbuy 抢购
329
+		beego.NSRouter("/flashbuy", &flashbuy.FlashBuyController{}, "get:GetFlashBuyList"),
330
+		beego.NSRouter("/flashbuy/customer/:flashBuyId", &flashbuy.FlashBuyController{}, "get:GetCustomerFlashBuyList"),
331
+		beego.NSRouter("/flashbuy/:flashBuyId", &flashbuy.FlashBuyController{}, "get:GetFlashBuyById"),
332
+		beego.NSRouter("/flashbuy", &flashbuy.FlashBuyController{}, "post:SaveFlashBuy"),
333
+		beego.NSRouter("/flashbuy/edit", &flashbuy.FlashBuyController{}, "put:SaveFlashBuy"),
334
+		beego.NSRouter("/flashbuy/:flashBuyId", &flashbuy.FlashBuyController{}, "delete:DeleteFlashBuy"),
335
+		beego.NSRouter("/flashbuy/:flashBuyId/:flashBuyStatus", &flashbuy.FlashBuyController{}, "put:UpdateFlashBuy"),
336
+		beego.NSRouter("/flashbuy/verify/:qrcode/:caseId", &flashbuy.FlashBuyController{}, "get:VerifyCustomerFlashBuyList"),
337
+		beego.NSRouter("/flashbuy/verify/:customerFlashBuyId", &flashbuy.FlashBuyController{}, "put:Verify"),
338
+		beego.NSRouter("/flashbuy/model", &flashbuy.FlashBuyController{}, "get:GetFlashModelList"),
310 339
 	)
311 340
 }

+ 4
- 3
routers/guest.go Просмотреть файл

@@ -6,6 +6,7 @@ import (
6 6
 	"spaceofcheng/services/controllers/cases"
7 7
 	"spaceofcheng/services/controllers/course"
8 8
 	"spaceofcheng/services/controllers/customer"
9
+	"spaceofcheng/services/controllers/customerremark"
9 10
 	"spaceofcheng/services/controllers/goods"
10 11
 	"spaceofcheng/services/controllers/message"
11 12
 	"spaceofcheng/services/controllers/user"
@@ -13,9 +14,7 @@ import (
13 14
 	"github.com/astaxie/beego"
14 15
 )
15 16
 
16
-func getGuestRoutes() beego.LinkNamespace {
17
-	prefix := beego.AppConfig.String("api::guest")
18
-
17
+func getGuestRoutes(prefix string) beego.LinkNamespace {
19 18
 	return beego.NSNamespace(prefix,
20 19
 		// cms
21 20
 		beego.NSRouter("/cms/info", &message.MessageController{}, "get:GetCmsInfoByLocation"),
@@ -68,5 +67,7 @@ func getGuestRoutes() beego.LinkNamespace {
68 67
 		beego.NSRouter("/case/checkin", &cases.SigninController{}, "post:AddSignin"),
69 68
 		beego.NSRouter("/wechat", &controllers.WechatController{}, "get,post:WechatInfo"),
70 69
 		// beego.NSRouter("/wechat", &controllers.WechatController{}, "post:WxReceive"),
70
+
71
+		beego.NSRouter("/customerremark/:recommendCode", &customerremark.CustomerRemarkController{}, "get:IsExist"),
71 72
 	)
72 73
 }

+ 16
- 5
routers/router.go Просмотреть файл

@@ -9,25 +9,36 @@ package routers
9 9
 
10 10
 import (
11 11
 	"spaceofcheng/services/controllers"
12
+	"spaceofcheng/services/utils"
12 13
 
13 14
 	"github.com/astaxie/beego"
14 15
 )
15 16
 
16
-func init() {
17
-	prefix := beego.AppConfig.String("api::prefix")
17
+func RouteInit() {
18
+	appRoot := utils.GetAppRoot()
19
+
20
+	appConf, _ := utils.GetConfiger(appRoot + "/conf/app.conf")
21
+	if appConf == nil {
22
+		return
23
+	}
24
+
25
+	prefix := appConf.String("api::prefix")
26
+	guestPrefix := appConf.String("api::guest")
27
+	commonPrefix := appConf.String("api::common")
28
+	wechatPrefix := appConf.String("api::wechat")
18 29
 
19 30
 	ns := beego.NewNamespace(prefix,
20 31
 		// 解决跨域时 先发送 options 问题
21 32
 		beego.NSRouter("*", &controllers.BaseController{}, "options:Options"),
22 33
 
23 34
 		// 通用需要鉴权路由
24
-		getCommonRoutes(),
35
+		getCommonRoutes(commonPrefix),
25 36
 
26 37
 		// 微信路由
27
-		getWechatRoutes(),
38
+		getWechatRoutes(wechatPrefix),
28 39
 
29 40
 		// 不需要鉴权的路由
30
-		getGuestRoutes(),
41
+		getGuestRoutes(guestPrefix),
31 42
 	)
32 43
 
33 44
 	beego.AddNamespace(ns)

+ 25
- 3
routers/wechat.go Просмотреть файл

@@ -7,17 +7,18 @@ import (
7 7
 	"spaceofcheng/services/controllers/coupon"
8 8
 	"spaceofcheng/services/controllers/course"
9 9
 	"spaceofcheng/services/controllers/customer"
10
+	"spaceofcheng/services/controllers/customerremark"
11
+	"spaceofcheng/services/controllers/flashbuy"
10 12
 	"spaceofcheng/services/controllers/goods"
11 13
 	"spaceofcheng/services/controllers/gymcard"
12 14
 	"spaceofcheng/services/controllers/luckdraw"
13 15
 	"spaceofcheng/services/controllers/user"
16
+	"spaceofcheng/services/controllers/vipcard"
14 17
 
15 18
 	"github.com/astaxie/beego"
16 19
 )
17 20
 
18
-func getWechatRoutes() beego.LinkNamespace {
19
-	prefix := beego.AppConfig.String("api::wechat")
20
-
21
+func getWechatRoutes(prefix string) beego.LinkNamespace {
21 22
 	return beego.NSNamespace(prefix,
22 23
 		// 会员
23 24
 		beego.NSRouter("/customer", &customer.CustomerController{}, "get:GetCustWXByID"),
@@ -33,7 +34,9 @@ func getWechatRoutes() beego.LinkNamespace {
33 34
 
34 35
 		// 下单
35 36
 		beego.NSRouter("/order/goods", &goods.GoodsController{}, "post:PostOrder"),
37
+		beego.NSRouter("/order/goods/:ordersid", &goods.GoodsController{}, "put:ConfirmOrders"),
36 38
 		beego.NSRouter("/order/course", &course.CourseController{}, "post:PostOrder"),
39
+		beego.NSRouter("/order/course/:ordersid", &course.CourseController{}, "put:ConfirmOrders"),
37 40
 
38 41
 		// 课程
39 42
 		beego.NSRouter("/course/user", &course.CourseController{}, "get:GetCustomerCourse"),
@@ -59,6 +62,7 @@ func getWechatRoutes() beego.LinkNamespace {
59 62
 		// 用户
60 63
 		beego.NSRouter("/user/:type", &user.UserController{}, "get:GetCaseUserByType"),
61 64
 		beego.NSRouter("/user/detail/:id", &user.UserController{}, "get:GetCaseUserByID"),
65
+		beego.NSRouter("/user/code", &user.UserController{}, "get:GetMyRecommendCode"),
62 66
 
63 67
 		// 优惠券
64 68
 		beego.NSRouter("/coupon", &coupon.CouponController{}, "get:GetCaseUsableCoupon"),
@@ -74,6 +78,9 @@ func getWechatRoutes() beego.LinkNamespace {
74 78
 		beego.NSRouter("/card/:id", &card.CardController{}, "post:ReceiveCard"),
75 79
 		beego.NSRouter("/channel/card/:id", &card.CardController{}, "post:ChannelReceiveCard"),
76 80
 
81
+		// vip卡
82
+		beego.NSRouter("/vip", &vipcard.VipcardController{}, "get:GetCustomerVips"),
83
+
77 84
 		// 体检
78 85
 		beego.NSRouter("/GetCheckByUser", &bodycheck.BodyCheckController{}, "get:GetCheckByUser"),
79 86
 
@@ -88,5 +95,20 @@ func getWechatRoutes() beego.LinkNamespace {
88 95
 		beego.NSRouter("/luckdraw/record", &luckdraw.LuckDrawController{}, "get:GetRecordByLuckDraw"),
89 96
 		beego.NSRouter("/user/luckdraw/record", &luckdraw.LuckDrawController{}, "get:GetUserLuckDraw"),
90 97
 		beego.NSRouter("/user/luckdraw/record/:id", &luckdraw.LuckDrawController{}, "get:GetRecordByID"),
98
+
99
+		// 抢购
100
+		beego.NSRouter("/flashbuy/flash/:flashBuyId", &flashbuy.FlashBuyController{}, "get:GetWechatFlashBuyById"),
101
+		beego.NSRouter("/flashbuy/customer", &flashbuy.FlashBuyController{}, "get:GetCustomerFlashBuyByCustomerId"),
102
+		beego.NSRouter("/flashbuy/customerFlash/:customerFlashBuyId", &flashbuy.FlashBuyController{}, "get:GetCustomerFlashBuyId"),
103
+		beego.NSRouter("/flashbuy/:id", &flashbuy.FlashBuyController{}, "post:FlashBuy"),
104
+		beego.NSRouter("/flashbuy/customer/:flashBuyId", &flashbuy.FlashBuyController{}, "post:AddNewFlashBuyCustomer"),
105
+		beego.NSRouter("/flashbuy/customer/:flashBuyId", &flashbuy.FlashBuyController{}, "put:UpdateFlashBuyCustomer"),
106
+		beego.NSRouter("/flashbuy/newcustomer", &flashbuy.FlashBuyController{}, "get:IsNewCustomer"),
107
+
108
+		// 客户备注
109
+		beego.NSRouter("/customerremark/record/:salesId/:customerId", &customerremark.CustomerRemarkController{}, "get:GetCustomerReceiveRecord"),
110
+		beego.NSRouter("/customerremark/:salesId/:customerId", &customerremark.CustomerRemarkController{}, "get:GetCustomerRemarkList"),
111
+		beego.NSRouter("/customerremark/search/:salesId/:customerInfo", &customerremark.CustomerRemarkController{}, "get:SearchCustomer"),
112
+		beego.NSRouter("/customerremark", &customerremark.CustomerRemarkController{}, "post:AddRemark"),
91 113
 	)
92 114
 }

+ 84
- 11
service/card/card.go Просмотреть файл

@@ -11,9 +11,11 @@ import (
11 11
 	"spaceofcheng/services/models/system"
12 12
 	"spaceofcheng/services/service"
13 13
 	"spaceofcheng/services/utils"
14
+	"strconv"
14 15
 	"strings"
15 16
 	"time"
16 17
 
18
+	"github.com/astaxie/beego"
17 19
 	"github.com/yl10/kit/guid"
18 20
 )
19 21
 
@@ -40,7 +42,7 @@ func NewCardServ(ctx *utils.Context) *CardServ {
40 42
 }
41 43
 
42 44
 // GetCardList 获取卡列表
43
-func (s *CardServ) GetCardList(caseID string, pagenavi ...int) ([]model.TaCouponCard, int64, error) {
45
+func (s *CardServ) GetCardList(caseID, sendtype, usetype, usedid string, pagenavi ...int) ([]model.TaCouponCard, int64, error) {
44 46
 	filters := []string{}
45 47
 	if caseID != "" {
46 48
 		if err := utils.NewAuthEngine(s.ctx).CheckCase(caseID); err != nil {
@@ -66,7 +68,64 @@ func (s *CardServ) GetCardList(caseID string, pagenavi ...int) ([]model.TaCoupon
66 68
 			"case_id in ('" + strings.Join(caseIDs, "','") + "')",
67 69
 		}
68 70
 	}
69
-
71
+	if sendtype != "" {
72
+		filters = append(filters, "send_type='"+sendtype+"'")
73
+		if usetype != "" {
74
+			switch usetype {
75
+			case models.COUPONCARD_USETYPE_LUCKDRAW:
76
+				filters = append(filters,
77
+					`card_id not in (
78
+						SELECT
79
+						(
80
+							CASE
81
+							WHEN resource_id IS NULL THEN
82
+								''
83
+							ELSE
84
+								resource_id
85
+							END
86
+						)
87
+					FROM
88
+						sys_activity_action
89
+					WHERE
90
+						active_type = '`+models.ActGiveCard+`' and status>`+strconv.Itoa(models.STATUS_DEL)+`
91
+					union 
92
+						SELECT
93
+							a.coupon_card_id
94
+						FROM
95
+						ta_luckdraw_prize a inner join ta_luckdraw b on a.luckdraw_id = b.id
96
+						WHERE
97
+							a.coupon_card_type = '`+models.PRIZE_TYPE_CARD+`'
98
+							and a.luckdraw_id <> '`+usedid+`' and b.status>`+strconv.Itoa(models.STATUS_DEL)+`
99
+					) and used_count=0`)
100
+				break
101
+			case models.COUPONCARD_USETYPE_SYS:
102
+				filters = append(filters, `card_id not in (
103
+					SELECT
104
+					a.coupon_card_id
105
+					FROM
106
+					ta_luckdraw_prize a inner join ta_luckdraw b on a.luckdraw_id = b.id
107
+					WHERE
108
+					a.coupon_card_type = '`+models.PRIZE_TYPE_CARD+`' and b.status>`+strconv.Itoa(models.STATUS_DEL)+`
109
+					union 
110
+					SELECT
111
+						(
112
+							CASE
113
+							WHEN resource_id IS NULL THEN
114
+								''
115
+							ELSE
116
+								resource_id
117
+							END
118
+						)
119
+					FROM
120
+						sys_activity_action
121
+					WHERE
122
+						active_type = '`+models.ActGiveCard+`'
123
+						and action_id<>'`+usedid+`' and status>`+strconv.Itoa(models.STATUS_DEL)+`
124
+				) and used_count=0`)
125
+				break
126
+			}
127
+		}
128
+	}
70 129
 	limit := utils.GetPageNaviLimit(pagenavi...)
71 130
 	res, total, err := s.dao.GetCardList(filters, limit)
72 131
 	if err != nil {
@@ -392,6 +451,15 @@ func (s *CardServ) GetCustomerCardByID(id string) (*card.CustomerCardWithShare,
392 451
 	return card, nil
393 452
 }
394 453
 
454
+func (s *CardServ) GetSysCardList(caseid string) ([]model.TaCouponCard, error) {
455
+	cards, err := s.dao.GetSysCardList(caseid)
456
+	if err != nil {
457
+		utils.LogError("获取体验卡失败: " + err.Error())
458
+		return nil, errors.New("获取体验卡失败")
459
+	}
460
+	return cards, nil
461
+}
462
+
395 463
 // GetCaseUsableCard 获取案场可用卡
396 464
 func (s *CardServ) GetCaseUsableCard(page, pageSize int) (map[string]interface{}, error) {
397 465
 
@@ -471,13 +539,15 @@ func (s *CardServ) ReceiveCard(id, saleid, serialcode string) error {
471 539
 		utils.LogError("领取卡获取销售信息失败:", err)
472 540
 		return errors.New("log-error-领取卡失败!")
473 541
 	}
474
-	caseinfo, err := s.userDao.GetUserBelongCase(saleid)
475
-	if err != nil {
476
-		utils.LogError("领取卡获取销售案场信息失败:", err)
477
-		return errors.New("log-error-领取卡失败!")
478
-	}
479
-	if caseinfo.CaseId != card.CaseId {
480
-		return errors.New("log-error-销售不合法!")
542
+	if saleid != beego.AppConfig.String("defaultShareUserID") {
543
+		caseinfo, err := s.userDao.GetUserBelongCase(saleid)
544
+		if err != nil {
545
+			utils.LogError("领取卡获取销售案场信息失败:", err)
546
+			return errors.New("log-error-领取卡失败!")
547
+		}
548
+		if caseinfo.CaseId != card.CaseId {
549
+			return errors.New("log-error-销售不合法!")
550
+		}
481 551
 	}
482 552
 
483 553
 	// 验证码判断
@@ -489,7 +559,10 @@ func (s *CardServ) ReceiveCard(id, saleid, serialcode string) error {
489 559
 	if !isok {
490 560
 		return errors.New("log-error-该卡已被领取!")
491 561
 	}
492
-
562
+	salername := saler.RealName
563
+	if salername == "" {
564
+		salername = saler.UserName
565
+	}
493 566
 	// 领取
494 567
 	var customerCard = model.TaCustomerCard{
495 568
 		CustomerCardId:   utils.GetGUID(),
@@ -497,7 +570,7 @@ func (s *CardServ) ReceiveCard(id, saleid, serialcode string) error {
497 570
 		CustomerCardName: card.CardName,
498 571
 		CustomerId:       customer.CustomerId,
499 572
 		SalesId:          saler.UserId,
500
-		SalesName:        saler.UserName,
573
+		SalesName:        salername,
501 574
 		StartDate:        card.StartDate,
502 575
 		EndDate:          card.EndDate,
503 576
 		CaseId:           card.CaseId,

+ 83
- 11
service/coupon/coupon.go Просмотреть файл

@@ -9,9 +9,11 @@ import (
9 9
 	"spaceofcheng/services/models/system"
10 10
 	"spaceofcheng/services/service"
11 11
 	"spaceofcheng/services/utils"
12
+	"strconv"
12 13
 	"strings"
13 14
 	"time"
14 15
 
16
+	"github.com/astaxie/beego"
15 17
 	"github.com/yl10/kit/guid"
16 18
 )
17 19
 
@@ -34,7 +36,7 @@ func NewCouponServ(ctx *utils.Context) *CouponServ {
34 36
 }
35 37
 
36 38
 // GetCouponList 获取优惠券列表
37
-func (s *CouponServ) GetCouponList(caseID string, pagenavi ...int) ([]model.TaCoupon, int64, error) {
39
+func (s *CouponServ) GetCouponList(caseID, sendtype, usetype, usedid string, pagenavi ...int) ([]model.TaCoupon, int64, error) {
38 40
 	filters := []string{}
39 41
 
40 42
 	if caseID != "" {
@@ -61,7 +63,63 @@ func (s *CouponServ) GetCouponList(caseID string, pagenavi ...int) ([]model.TaCo
61 63
 			"case_id in ('" + strings.Join(caseIDs, "','") + "')",
62 64
 		}
63 65
 	}
64
-
66
+	if sendtype != "" {
67
+		filters = append(filters, "send_type='"+sendtype+"'")
68
+		if usetype != "" {
69
+			switch usetype {
70
+			case models.COUPONCARD_USETYPE_LUCKDRAW:
71
+				filters = append(filters, `coupon_id not in (
72
+					SELECT
73
+						(
74
+							CASE
75
+							WHEN resource_id IS NULL THEN
76
+								''
77
+							ELSE
78
+								resource_id
79
+							END
80
+						)
81
+					FROM
82
+						sys_activity_action
83
+					WHERE
84
+						active_type = '`+models.ActGiveCoupon+`' and status>`+strconv.Itoa(models.STATUS_DEL)+`
85
+					union 
86
+					SELECT
87
+						a.coupon_card_id
88
+					FROM
89
+					ta_luckdraw_prize a inner join ta_luckdraw b on a.luckdraw_id = b.id
90
+					WHERE
91
+						a.coupon_card_type = '`+models.PRIZE_TYPE_COUPON+`'
92
+						and a.luckdraw_id<>'`+usedid+`' and b.status>`+strconv.Itoa(models.STATUS_DEL)+`
93
+					) and used_count=0 `)
94
+				break
95
+			case models.COUPONCARD_USETYPE_SYS:
96
+				filters = append(filters, `coupon_id not in (
97
+					SELECT
98
+						a.coupon_card_id
99
+					FROM
100
+					ta_luckdraw_prize a inner join ta_luckdraw b on a.luckdraw_id = b.id
101
+					WHERE
102
+						a.coupon_card_type = '`+models.PRIZE_TYPE_COUPON+`' and b.status>`+strconv.Itoa(models.STATUS_DEL)+`
103
+					union
104
+					SELECT
105
+					(
106
+						CASE
107
+						WHEN resource_id IS NULL THEN
108
+							''
109
+						ELSE
110
+							resource_id
111
+						END
112
+					)
113
+				FROM
114
+					sys_activity_action
115
+				WHERE
116
+					active_type = '`+models.ActGiveCoupon+`'
117
+					and action_id<>'`+usedid+`' and status>`+strconv.Itoa(models.STATUS_DEL)+`
118
+				) and used_count=0`)
119
+				break
120
+			}
121
+		}
122
+	}
65 123
 	limit := utils.GetPageNaviLimit(pagenavi...)
66 124
 	res, total, err := s.dao.GetCouponList(filters, limit)
67 125
 	if err != nil {
@@ -514,13 +572,15 @@ func (s *CouponServ) ReceiveCoupon(id, saleid, serialcode string) error {
514 572
 		utils.LogError("领取优惠券获取销售信息失败:", err)
515 573
 		return errors.New("log-error-领取优惠券失败!")
516 574
 	}
517
-	caseinfo, err := s.userDao.GetUserBelongCase(saleid)
518
-	if err != nil {
519
-		utils.LogError("领取优惠券获取销售案场信息失败:", err)
520
-		return errors.New("log-error-领取优惠券失败!")
521
-	}
522
-	if caseinfo.CaseId != coupon.CaseId {
523
-		return errors.New("log-error-销售不合法!")
575
+	if saleid != beego.AppConfig.String("defaultShareUserID") {
576
+		caseinfo, err := s.userDao.GetUserBelongCase(saleid)
577
+		if err != nil {
578
+			utils.LogError("领取优惠券获取销售案场信息失败:", err)
579
+			return errors.New("log-error-领取优惠券失败!")
580
+		}
581
+		if caseinfo.CaseId != coupon.CaseId {
582
+			return errors.New("log-error-销售不合法!")
583
+		}
524 584
 	}
525 585
 
526 586
 	// 验证码判断
@@ -541,14 +601,17 @@ func (s *CouponServ) ReceiveCoupon(id, saleid, serialcode string) error {
541 601
 		hs := int64(coupon.ValidDays * 24)
542 602
 		endDate = time.Now().Local().Add(time.Hour * time.Duration(hs))
543 603
 	}
544
-
604
+	salername := saler.RealName
605
+	if salername == "" {
606
+		salername = saler.UserName
607
+	}
545 608
 	// 领取
546 609
 	var customerCoupon = model.TaCustomerCoupon{
547 610
 		CouponId:           coupon.CouponId,
548 611
 		CustomerCouponName: coupon.CouponName,
549 612
 		CustomerId:         customer.CustomerId,
550 613
 		SalesId:            saler.UserId,
551
-		SalesName:          saler.UserName,
614
+		SalesName:          salername,
552 615
 		StartDate:          startDate,
553 616
 		EndDate:            endDate,
554 617
 		CaseId:             coupon.CaseId,
@@ -678,3 +741,12 @@ func (s *CouponServ) GetCustomerCouponByCustomerAndSale(customerid string, page,
678 741
 		"page":     page,
679 742
 	}, nil
680 743
 }
744
+
745
+func (s *CouponServ) GetSysCouponByCase(caseid string) ([]model.TaCoupon, error) {
746
+	coupon, err := s.dao.GetSysCouponByCase(caseid)
747
+	if err != nil {
748
+		utils.LogError("获取系统赠送券失败: " + err.Error())
749
+		return nil, errors.New("获取系统赠送券失败")
750
+	}
751
+	return coupon, nil
752
+}

+ 3
- 0
service/course/course.go Просмотреть файл

@@ -9,6 +9,7 @@ import (
9 9
 	"spaceofcheng/services/models/customer"
10 10
 	"spaceofcheng/services/models/model"
11 11
 	"spaceofcheng/services/models/system"
12
+	"spaceofcheng/services/models/vipcard"
12 13
 	"spaceofcheng/services/service"
13 14
 	"spaceofcheng/services/utils"
14 15
 	"strings"
@@ -22,6 +23,7 @@ type CourseServ struct {
22 23
 	custDAO   *customer.CustomerDAO
23 24
 	userDAO   *system.UserDAO
24 25
 	couponDAO *coupon.CouponDAO
26
+	vipDAO    *vipcard.VipcardDAO
25 27
 }
26 28
 
27 29
 // NewCourseServ 初始化
@@ -33,6 +35,7 @@ func NewCourseServ(ctx *utils.Context) *CourseServ {
33 35
 		custDAO:   customer.NewCustomerDAO(ctx),
34 36
 		userDAO:   system.NewUserDAO(ctx),
35 37
 		couponDAO: coupon.NewCouponDAO(ctx),
38
+		vipDAO:    vipcard.NewVipcardDAO(ctx),
36 39
 	}
37 40
 }
38 41
 

+ 142
- 54
service/course/order.go Просмотреть файл

@@ -12,14 +12,13 @@ import (
12 12
 	"github.com/yl10/kit/guid"
13 13
 )
14 14
 
15
-// Orders 下单
16
-func (s *CourseServ) Orders(
15
+// PreOrders 预下单
16
+// 保存订单信息
17
+func (s *CourseServ) PreOrders(
17 18
 	couseOrder *model.TaCourseOrders,
18
-	customercouponid string,
19
-) error {
19
+) (*model.TaCourseOrders, error) {
20 20
 	org := s.ctx.Get("org").(model.SysOrg)
21 21
 	cust := s.ctx.Get("customer").(model.TaCustomer)
22
-
23 22
 	// 校验人员
24 23
 	couseOrder.CustomerId = cust.CustomerId
25 24
 	if cust.UserId != "" {
@@ -30,39 +29,71 @@ func (s *CourseServ) Orders(
30 29
 		// 默认是卡券支付
31 30
 		couseOrder.PayType = models.CONSUME_COUPON
32 31
 	}
33
-
34
-	// TODO
35
-	// 校验案场
36
-	// caseID := couseOrder.CaseId
37
-	// if err := utils.NewAuthEngine(s.ctx).CheckCase(caseID); err != nil {
38
-	// 	return err
39
-	// }
40
-
41 32
 	// 校验课程
42 33
 	course, err := s.validCourse(couseOrder)
43 34
 	if err != nil {
44
-		return err
35
+		return nil, err
45 36
 	}
46 37
 	if course.CourseDetail == nil || len(course.CourseDetail) == 0 {
47
-		return errors.New("定单课程尚未排课, 不能下单")
38
+		return nil, errors.New("定单课程尚未排课, 不能下单")
48 39
 	}
49
-
50 40
 	couseOrder.OrdersId = guid.NewGUIDString()
51 41
 	couseOrder.Price = course.Price // 课程价格, 即为订单价格
52 42
 	couseOrder.ActualAmount = course.Price
43
+	couseOrder.CouponAmount = "0.0"
53 44
 	couseOrder.CourseName = course.CourseName
54 45
 	couseOrder.CourseNum = course.CourseNum
55 46
 	couseOrder.OrgId = org.OrgId
56
-	couseOrder.Status = models.STATUS_NORMAL
57
-
58
-	// 默认是已支付
59
-	couseOrder.IsPay = models.BOOL_TRUE
47
+	couseOrder.Status = models.STATUS_READY
48
+	couseOrder.IsPay = models.BOOL_FALSE
60 49
 
61 50
 	if cust.Name != "" {
62 51
 		couseOrder.CustomerName = cust.Name
63 52
 	} else {
64 53
 		couseOrder.CustomerName = cust.CustomerName
65 54
 	}
55
+	// 入库
56
+	neworder, err := s.AddOrder(couseOrder)
57
+	if err != nil {
58
+		utils.LogError("课程下单失败: " + err.Error())
59
+		return nil, errors.New("下单失败, 请重试")
60
+	}
61
+	return neworder, nil
62
+}
63
+
64
+// ConfirmOrders 确认订单
65
+func (s *CourseServ) ConfirmOrders(ordersID, customercouponid string) error {
66
+
67
+	couseOrder, err := s.dao.GetOrderByID(ordersID)
68
+	if err != nil {
69
+		return utils.LogError("获取订单失败", err)
70
+	}
71
+
72
+	if couseOrder.Status != models.STATUS_READY {
73
+		return errors.New("没有订单信息")
74
+	}
75
+
76
+	if couseOrder.IsPay == models.BOOL_TRUE {
77
+		return errors.New("订单已付款,请勿重复付款!")
78
+	}
79
+
80
+	cust := s.ctx.Get("customer").(model.TaCustomer)
81
+
82
+	// TODO
83
+	// 校验案场
84
+	// caseID := couseOrder.CaseId
85
+	// if err := utils.NewAuthEngine(s.ctx).CheckCase(caseID); err != nil {
86
+	// 	return err
87
+	// }
88
+
89
+	// 校验课程
90
+	course, err := s.validCourse(couseOrder)
91
+	if err != nil {
92
+		return err
93
+	}
94
+	if course.CourseDetail == nil || len(course.CourseDetail) == 0 {
95
+		return errors.New("定单课程尚未排课, 不能下单")
96
+	}
66 97
 
67 98
 	account, err := s.custDAO.GetAccountByCust(cust.CustomerId)
68 99
 	if err != nil {
@@ -144,6 +175,18 @@ func (s *CourseServ) Orders(
144 175
 			utils.LogError("优惠券核销出错: " + err.Error())
145 176
 			return errors.New("优惠券核销出错")
146 177
 		}
178
+		// 券库存处理
179
+		var couponinfo = model.TaCoupon{
180
+			CouponId:  coupon.CouponId,
181
+			UsedCount: coupon.UsedCount + 1,
182
+		}
183
+		cols := []string{
184
+			"used_count",
185
+		}
186
+		if err := s.couponDAO.UpdateCoupon(&couponinfo, cols); err != nil {
187
+			utils.LogError("回填优惠券信息失败:", err)
188
+			return errors.New("回填优惠券信息失败!")
189
+		}
147 190
 	} else {
148 191
 		couseOrder.PayType = models.CONSUME_COINCHG
149 192
 		couseOrder.CouponAmount = "0.0"
@@ -165,19 +208,56 @@ func (s *CourseServ) Orders(
165 208
 
166 209
 	// 用户账户  -- 内部人员也可以购买
167 210
 	if actualAmount > 0 {
211
+		var leftPay = actualAmount
212
+		vips, err := s.custDAO.GetValidVIPCards(cust.CustomerId)
213
+		if err != nil {
214
+			return utils.LogError("查询用户 VIP卡 出错", err)
215
+		}
216
+
217
+		var vipAccount float64
218
+		if vips != nil && len(vips) > 0 {
219
+			for _, vip := range vips {
220
+				vipMoney, _ := strconv.ParseFloat(vip.Balance, 64)
221
+				vipAccount += vipMoney
222
+
223
+				// 当前扣款
224
+				var vipPay float64
225
+				if vipMoney > leftPay {
226
+					// 如果卡余额比 需要扣款的多, 那么就只扣这一张卡
227
+					// 通过 leftPay < 0.01 来判断
228
+					vipPay = leftPay
229
+					leftPay = 0
230
+				} else {
231
+					// 如果余额不够, 先扣掉本张卡余额, 继续循环
232
+					vipPay = vipMoney
233
+					leftPay -= vipMoney
234
+				}
235
+
236
+				if err := s.saveVipChangeRec(vipPay, &vip, couseOrder); err != nil {
237
+					return utils.LogError("VIP卡扣款失败", err.Error())
238
+				}
168 239
 
169
-		if actualAmount > accMoney {
170
-			return errors.New("账户余额不足")
240
+				if leftPay < 0.01 {
241
+					break
242
+				}
243
+			}
171 244
 		}
172 245
 
173
-		// 插入账户流水
174
-		if err := s.saveCustomerPayRec(account, couseOrder); err != nil {
175
-			utils.LogError("插入账户流水出错: " + err.Error())
176
-			return errors.New("写入账户流水出错")
246
+		// 如果 VIP 卡余额不足, 则使用账户余额
247
+		if leftPay > 0.01 {
248
+			if leftPay > accMoney {
249
+				return errors.New("账户余额不足")
250
+			}
251
+
252
+			// 插入账户流水
253
+			if err := s.saveCustomerPayRec(account, couseOrder, leftPay); err != nil {
254
+				utils.LogError("插入账户流水出错: " + err.Error())
255
+				return errors.New("写入账户流水出错")
256
+			}
177 257
 		}
178 258
 	}
179 259
 
180
-	// 入库
260
+	// 更新订单信息
181 261
 	if err := s.SaveOrder(couseOrder, course); err != nil {
182 262
 		utils.LogError("课程下单失败: " + err.Error())
183 263
 		return errors.New("下单失败, 请重试")
@@ -189,24 +269,32 @@ func (s *CourseServ) Orders(
189 269
 	return nil
190 270
 }
191 271
 
272
+// saveVipChangeRec 保存vip消费记录
273
+func (s *CourseServ) saveVipChangeRec(payMoney float64, custVIP *model.TaCustomerVip, info *model.TaCourseOrders) error {
274
+	vipChange := new(model.TaCustomerVipChange)
275
+	vipChange.CustomerVipId = custVIP.CustomerVipId
276
+	vipChange.CustomerId = info.CustomerId
277
+	vipChange.OrgId = info.OrgId
278
+	vipChange.CaseId = info.CaseId
279
+	vipChange.ChangeType = models.CONSUME_COINCHG
280
+	vipChange.FloatType = models.ACCOUNT_SPENT
281
+	vipChange.SourceId = info.OrdersId
282
+	vipChange.SourceName = "课程下单"
283
+	vipChange.Amount = strconv.FormatFloat(payMoney, 'f', -1, 64)
284
+
285
+	if err := s.vipDAO.InsertCustomerVipChange(*vipChange); err != nil {
286
+		return err
287
+	}
288
+
289
+	return s.custDAO.UpdateCustVipCardAmount(custVIP, payMoney)
290
+}
291
+
192 292
 // validCourse 校验课程
193 293
 func (s *CourseServ) validCourse(order *model.TaCourseOrders) (*course.CourseDetail, error) {
194 294
 	if order.CourseId == "" {
195 295
 		return nil, errors.New("没有获取到下单课程")
196 296
 	}
197 297
 
198
-	// custCourse, err := s.dao.GetCourseOfCustomer(order.CustomerId, order.CourseId)
199
-	// if err != nil {
200
-	// 	utils.LogError("校验用户课程失败: " + err.Error())
201
-	// 	return nil, errors.New("校验用户课程失败")
202
-	// }
203
-
204
-	// if custCourse != nil && custCourse.CustomerCourseId != "" {
205
-	// 	if custCourse.Status != models.STATUS_DEL {
206
-	// 		return nil, errors.New("用户已经拥有该课程, 不需要再次下单")
207
-	// 	}
208
-	// }
209
-
210 298
 	// 课程
211 299
 	course, err := s.dao.GetCourseInfo(order.CourseId)
212 300
 	if err != nil {
@@ -291,10 +379,10 @@ func (s *CourseServ) validBillCharges(
291 379
 }
292 380
 
293 381
 // saveCustomerPayRec 保存账户消费流水
294
-func (s *CourseServ) saveCustomerPayRec(account *model.TaCustomerAccount, info *model.TaCourseOrders) error {
382
+func (s *CourseServ) saveCustomerPayRec(account *model.TaCustomerAccount, info *model.TaCourseOrders, leftPay float64) error {
295 383
 	accBill := new(model.TaAccountChange)
296 384
 	accBill.AccountId = account.AccountId
297
-	accBill.Amount = info.ActualAmount
385
+	accBill.Amount = strconv.FormatFloat(leftPay, 'f', -1, 64)
298 386
 	accBill.CaseId = info.CaseId
299 387
 	accBill.ChangeSource = models.ACCSOURCE_COURSE_ORDERS
300 388
 	accBill.ChangeType = models.CONSUME_COINCHG
@@ -307,26 +395,26 @@ func (s *CourseServ) saveCustomerPayRec(account *model.TaCustomerAccount, info *
307 395
 	return s.custDAO.InsertAccountRecords(accBill)
308 396
 }
309 397
 
398
+// AddOrder 保存订单信息
399
+func (s *CourseServ) AddOrder(order *model.TaCourseOrders) (*model.TaCourseOrders, error) {
400
+	// 订单信息
401
+	order.Status = models.STATUS_READY
402
+	neworder, err := s.dao.SaveCourseOrder(order)
403
+	if err != nil {
404
+		utils.LogError("课程下单失败: " + err.Error())
405
+		return nil, errors.New("下单失败, 请重试")
406
+	}
407
+	return neworder, nil
408
+}
409
+
310 410
 // SaveOrder 保存订单明细
311 411
 func (s *CourseServ) SaveOrder(order *model.TaCourseOrders, course *course.CourseDetail) error {
312 412
 	// 订单信息
313
-	if err := s.dao.SaveCourseOrder(order); err != nil {
413
+	if err := s.dao.UpdateOrderPay(order); err != nil {
314 414
 		utils.LogError("课程下单失败: " + err.Error())
315 415
 		return errors.New("下单失败, 请重试")
316 416
 	}
317 417
 
318
-	// 默认城币购买
319
-	// courseObtaimType := models.COURSE_GETBY_COINCHG
320
-	// if coupons != nil && len(coupons) > 0 {
321
-	// 	for _, c := range coupons {
322
-	// 		if c.CouponType == models.COURSE_COUPON_CARD {
323
-	// 			courseObtaimType = models.COURSE_GETBY_CARD
324
-	// 		} else if c.CouponType == models.COURSE_COUPON_COUPON {
325
-	// 			courseObtaimType = models.COURSE_GETBY_COUPON
326
-	// 		}
327
-	// 	}
328
-	// }
329
-
330 418
 	// 我的课程信息
331 419
 	custCourse := model.TaCustomerCourse{
332 420
 		CourseId:         order.CourseId,

+ 84
- 63
service/customer/customer.go Просмотреть файл

@@ -175,86 +175,105 @@ func (s *CustomerServ) BindWechatUser(userMap *model.TaUserMapping, phone string
175 175
 }
176 176
 
177 177
 // BindWechatCust 绑定微信用户
178
-func (s *CustomerServ) BindWechatCust(userMap *model.TaUserMapping, phone, caseID, userID string) (*model.TaCustomer, error) {
178
+func (s *CustomerServ) BindWechatCust(userMap *model.TaUserMapping, phone, recommendCode string) (*model.TaCustomer, error) {
179 179
 	cust, err := s.dao.GetCustomerByPhone(phone)
180 180
 	if err != nil {
181 181
 		utils.LogError(err.Error())
182 182
 		return nil, err
183 183
 	}
184
+	if cust != nil {
185
+		return nil, errors.New("当前手机号已被绑定或者注册")
186
+	}
184 187
 
185 188
 	// 用户不存在, 则新增
186
-	if cust == nil {
187
-		wxInfo := utils.WechatUser{}
188
-		if err := json.Unmarshal([]byte(userMap.AccountInfo), &wxInfo); err != nil {
189
-			utils.LogError("解析用户微信映射信息失败: " + err.Error())
190
-			return nil, errors.New("系统数据异常")
191
-		}
189
+	wxInfo := utils.WechatUser{}
190
+	if err := json.Unmarshal([]byte(userMap.AccountInfo), &wxInfo); err != nil {
191
+		utils.LogError("解析用户微信映射信息失败: " + err.Error())
192
+		return nil, errors.New("系统数据异常")
193
+	}
192 194
 
193
-		// 更新用户手机号码信息及userid信息
194
-		customer, err := s.dao.GetCustWithWXByOpenID(wxInfo.OpenID)
195
-		newCust := model.TaCustomer{
196
-			CustomerId:  customer.CustomerId,
197
-			Phone:       phone,
198
-			BindingDate: time.Now(),
199
-		}
200
-		// 校验案场信息
201
-		if caseID != "" {
202
-			cs, err := s.casedao.GetCaseByID(caseID)
203
-			if err != nil {
204
-				utils.LogError(err.Error())
205
-				return nil, err
206
-			}
207
-
208
-			if cs == nil || cs.Status == models.STATUS_DEL {
209
-				return nil, errors.New("系统无该推荐案场")
210
-			}
211
-
212
-			newCust.OrgId = cs.OrgId
213
-			newCust.RecommendCase = cs.CaseId
214
-		}
195
+	// 更新用户手机号码信息及userid信息
196
+	customer, err := s.dao.GetCustWithWXByOpenID(wxInfo.OpenID)
197
+	if err != nil {
198
+		return nil, utils.LogError("获取用户信息失败", err.Error())
199
+	}
215 200
 
216
-		// 校验推荐人
217
-		if userID != "" {
218
-			ar, err := s.dao.GetUserByID(userID)
219
-			if err != nil {
220
-				utils.LogError(err.Error())
221
-				return nil, err
222
-			}
223
-
224
-			if ar == nil || ar.Status == models.STATUS_DEL {
225
-				return nil, errors.New("系统无该推荐人")
226
-			}
227
-
228
-			newCust.OrgId = ar.OrgId
229
-			newCust.RecommendId = ar.UserId
230
-			newCust.RecommendName = ar.RealName
231
-		}
201
+	newCust := customer.TaCustomer
202
+	newCust.Phone = phone
203
+	newCust.BindingDate = time.Now().Local()
232 204
 
233
-		err = s.dao.UpdateCustomer(&newCust, []string{
234
-			"phone",
235
-			"recommend_id",
236
-			"recommend_case",
237
-			"recommend_name",
238
-			"binding_date",
239
-		})
205
+	// 校验案场信息
206
+	if recommendCode != "" {
207
+		user, err := s.dao.GetSalesByRecommendCode(recommendCode)
208
+		if err != nil {
209
+			utils.LogError(err.Error())
210
+			return nil, err
211
+		}
212
+		userCase, err := s.dao.GetSalesCaseById(user.UserId)
213
+		cs, err := s.casedao.GetCaseByID(userCase.CaseId)
240 214
 		if err != nil {
241 215
 			utils.LogError(err.Error())
242 216
 			return nil, err
243 217
 		}
244 218
 
245
-		cust = &newCust
246
-	} else {
247
-		if cust.Status != models.STATUS_NORMAL {
248
-			return nil, errors.New("用户状态不正确")
219
+		if cs == nil || cs.Status == models.STATUS_DEL {
220
+			return nil, errors.New("系统无该推荐案场")
249 221
 		}
222
+		if cs.Status == 0 {
223
+			return nil, errors.New("该案场暂未开放")
224
+		}
225
+
226
+		newCust.OrgId = cs.OrgId
227
+		newCust.RecommendCase = cs.CaseId
228
+
229
+		if user == nil || user.Status == models.STATUS_DEL {
230
+			return nil, errors.New("系统无该推荐人")
231
+		}
232
+
233
+		newCust.OrgId = user.OrgId
234
+		newCust.RecommendId = user.UserId
235
+		newCust.RecommendName = user.RealName
250 236
 	}
251 237
 
252
-	// triggerRegiteEvent 触发注册事件
253
-	if cust.RecommendCase != "" {
254
-		evtEngID := utils.EngineIDBy(cust.OrgId, cust.RecommendCase)
255
-		utils.EventEngineBus(evtEngID).EmitEvent(events.EvtRegiste, *cust)
238
+	// 校验推荐人
239
+	// if userID != "" {
240
+	// 	ar, err := s.dao.GetUserByID(userID)
241
+	// 	if err != nil {
242
+	// 		utils.LogError(err.Error())
243
+	// 		return nil, err
244
+	// 	}
245
+
246
+	// 	if ar == nil || ar.Status == models.STATUS_DEL {
247
+	// 		return nil, errors.New("系统无该推荐人")
248
+	// 	}
249
+
250
+	// 	newCust.OrgId = ar.OrgId
251
+	// 	newCust.RecommendId = ar.UserId
252
+	// 	newCust.RecommendName = ar.RealName
253
+	// }
254
+
255
+	err = s.dao.UpdateCustomer(&newCust, []string{
256
+		"phone",
257
+		"recommend_id",
258
+		"recommend_case",
259
+		"recommend_name",
260
+		"binding_date",
261
+	})
262
+	if err != nil {
263
+		utils.LogError(err.Error())
264
+		return nil, err
256 265
 	}
257 266
 
267
+	cust = &newCust
268
+
269
+	// triggerRegiteEvent 触发注册事件
270
+	// if cust.RecommendCase != "" {
271
+	evtEngID := utils.EngineIDBy(customer.OrgId, "")
272
+	evtEngine := utils.EventEngineBus(evtEngID)
273
+
274
+	evtEngine.EmitEvent(events.EvtRegiste, *cust)
275
+	// }
276
+
258 277
 	// 如果客户ID 与映射表中一致, 说明已经绑定过了
259 278
 	if cust.CustomerId == userMap.UserId {
260 279
 		return cust, nil
@@ -401,9 +420,11 @@ func (s *CustomerServ) GetCustomerInfo() (map[string]interface{}, error) {
401 420
 		utils.LogError("获取用户卡信息失败:", err)
402 421
 		return nil, err
403 422
 	}
423
+	balance, err := s.dao.GetCustomerVipAmount(customer.CustomerId)
404 424
 	return map[string]interface{}{
405
-		"account":   account,
406
-		"cardsnum":  len(card),
407
-		"couponnum": len(coupon),
425
+		"account":    account,
426
+		"cardsnum":   len(card),
427
+		"couponnum":  len(coupon),
428
+		"vipbalance": balance,
408 429
 	}, nil
409 430
 }

+ 90
- 0
service/customerremark/customerremark.go Просмотреть файл

@@ -0,0 +1,90 @@
1
+package customerremark
2
+
3
+import (
4
+	"errors"
5
+	"spaceofcheng/services/models/customerremark"
6
+	"spaceofcheng/services/models/model"
7
+	"spaceofcheng/services/service"
8
+	"spaceofcheng/services/utils"
9
+)
10
+
11
+type CustomerRemarkServ struct {
12
+	ctx *utils.Context
13
+	dao *customerremark.CustomerRemarkDAO
14
+}
15
+
16
+// NewCustomerRemarkServ 初始化
17
+func NewCustomerRemarkServ(ctx *utils.Context) *CustomerRemarkServ {
18
+	return &CustomerRemarkServ{
19
+		ctx: ctx,
20
+		dao: customerremark.NewCustomerRemarkDAO(ctx),
21
+	}
22
+}
23
+
24
+func (s *CustomerRemarkServ) GetCustomerRemarkList(salesId, customerId string, page, pageSize int) (map[string]interface{}, error) {
25
+	if pageSize == 0 {
26
+		pageSize = service.PAGENUM
27
+	}
28
+	remarks, err := s.dao.GetRemarkList(salesId, customerId, page, pageSize)
29
+	if err != nil {
30
+		utils.LogError("获取客户备注列表失败: " + err.Error())
31
+		return nil, errors.New("获取客户备注列表失败")
32
+	}
33
+	total, err := s.dao.GetRemarkListCount(salesId, customerId)
34
+	if err != nil {
35
+		utils.LogError("获取客户备注列表失败: " + err.Error())
36
+		return nil, errors.New("获取客户备注列表失败")
37
+	}
38
+	return map[string]interface{}{
39
+		"list":     remarks,
40
+		"pageSize": pageSize,
41
+		"pagenum":  total,
42
+		"page":     page,
43
+	}, nil
44
+}
45
+
46
+func (s *CustomerRemarkServ) GetCustomerReceiveRecord(customerId, salesId string, page, pageSize int) (map[string]interface{}, error) {
47
+	if pageSize == 0 {
48
+		pageSize = service.PAGENUM
49
+	}
50
+	record, err := s.dao.CustomerReceiveRecord(customerId, salesId, page, pageSize)
51
+	if err != nil {
52
+		utils.LogError("获取客户领取列表失败: " + err.Error())
53
+		return nil, errors.New("获取客户领取列表失败")
54
+	}
55
+	total, err := s.dao.CustomerReceiveRecordCount(customerId, salesId)
56
+	if err != nil {
57
+		utils.LogError("获取客户领取列表失败: " + err.Error())
58
+		return nil, errors.New("获取客户领取列表失败")
59
+	}
60
+	return map[string]interface{}{
61
+		"list":     record,
62
+		"pageSize": pageSize,
63
+		"pagenum":  total,
64
+		"page":     page,
65
+	}, nil
66
+}
67
+func (s *CustomerRemarkServ) AddRemark(remark model.TaSaleCustomerRemark) (*model.TaSaleCustomerRemark, error) {
68
+	newRemark, err := s.dao.AddRemark(remark)
69
+	if err != nil {
70
+		utils.LogError("保存客户备注失败: " + err.Error())
71
+		return nil, errors.New("保存客户备注失败")
72
+	}
73
+	return newRemark, nil
74
+}
75
+func (s *CustomerRemarkServ) SearchCustomer(customerInfo, salesId string) (*model.TaCustomer, error) {
76
+	customer, err := s.dao.SearchCustomer(customerInfo, salesId)
77
+	if err != nil {
78
+		utils.LogError("获取客户信息失败: " + err.Error())
79
+		return nil, errors.New("获取客户信息失败")
80
+	}
81
+	return &customer, nil
82
+}
83
+func (s *CustomerRemarkServ) IsExist(recommendCode string) (int, error) {
84
+	num, err := s.dao.IsExist(recommendCode)
85
+	if err != nil {
86
+		utils.LogError("获取推荐人失败: " + err.Error())
87
+		return 0, errors.New("获取推荐人失败")
88
+	}
89
+	return num, nil
90
+}

+ 1
- 0
service/events/constant.go Просмотреть файл

@@ -13,4 +13,5 @@ const (
13 13
 
14 14
 	// 送券
15 15
 	ActGiveCoupon = "giveCoupon"
16
+	ActGiveCard   = "giveCard"
16 17
 )

+ 38
- 11
service/events/events.go Просмотреть файл

@@ -17,8 +17,11 @@ var EvtActions = map[string]tinyevent.Action{
17 17
 	// 测试
18 18
 	ActTest: tsAction,
19 19
 
20
-	// 赠送
20
+	// 赠送券
21 21
 	ActGiveCoupon: giveCoupon,
22
+
23
+	// 赠送卡
24
+	ActGiveCard: giveCard,
22 25
 }
23 26
 
24 27
 // ListenAllEvent 监听所有事件
@@ -26,11 +29,12 @@ func ListenAllEvent(orgID, caseID string) {
26 29
 	mtx.Lock()
27 30
 	defer mtx.Unlock()
28 31
 
29
-	evtEngID := utils.EngineIDBy(orgID, caseID)
32
+	// 2018年10月30日 yansen 不区分案场
33
+	evtEngID := utils.EngineIDBy(orgID, "")
30 34
 	evtEngine := utils.ResetEventEngineBus(evtEngID)
31 35
 
32 36
 	// 所有需要执行的事件
33
-	allEvts, err := getAllEvents(orgID, caseID)
37
+	allEvts, err := getAllEvents(orgID, "")
34 38
 	if err != nil {
35 39
 		utils.LogError(err)
36 40
 	}
@@ -39,6 +43,7 @@ func ListenAllEvent(orgID, caseID string) {
39 43
 	for evt, acts := range allEvts {
40 44
 		for _, actKey := range acts {
41 45
 			act, ok := EvtActions[actKey]
46
+
42 47
 			if ok {
43 48
 				evtEngine.ListenEvent(evt, act)
44 49
 			}
@@ -54,7 +59,7 @@ func getAllEvents(orgID, caseID string) (map[string][]string, error) {
54 59
 	var acts []model.SysActivityAction
55 60
 
56 61
 	if err := db.Where("org_id=?", orgID).
57
-		And("case_id=?", caseID).
62
+		// And("case_id=?", caseID).
58 63
 		And("status=?", models.STATUS_NORMAL).
59 64
 		Find(&evts); err != nil {
60 65
 		utils.LogError("查询营销活动配置表失败: " + err.Error())
@@ -63,7 +68,11 @@ func getAllEvents(orgID, caseID string) (map[string][]string, error) {
63 68
 
64 69
 	res := make(map[string][]string)
65 70
 	for _, evtSetting := range evts {
66
-		res[evtSetting.ActivityType] = make([]string, 0)
71
+		tpEvts, ok := res[evtSetting.ActivityType]
72
+		if !ok {
73
+			tpEvts = make([]string, 0)
74
+		}
75
+
67 76
 		acts = make([]model.SysActivityAction, 0)
68 77
 
69 78
 		if err := db.Where("activity_id=?", evtSetting.ActivityId).Find(&acts); err != nil {
@@ -72,8 +81,15 @@ func getAllEvents(orgID, caseID string) (map[string][]string, error) {
72 81
 		}
73 82
 
74 83
 		for _, act := range acts {
75
-			res[evtSetting.ActivityType] = append(res[evtSetting.ActivityType], act.ActiveType)
84
+			utils.LogInfo(act)
85
+
86
+			// 加入 tpEvts 需要去重
87
+			if utils.StrSliceIndexOf(tpEvts, act.ActiveType) == -1 {
88
+				tpEvts = append(tpEvts, act.ActiveType)
89
+			}
76 90
 		}
91
+
92
+		res[evtSetting.ActivityType] = tpEvts
77 93
 	}
78 94
 
79 95
 	return res, nil
@@ -85,14 +101,25 @@ var tsAction = func(e tinyevent.Event) error {
85 101
 	return nil
86 102
 }
87 103
 
88
-func init() {
89
-	cases, err := models.GetAllCases()
104
+func EventInit() {
105
+	// cases, err := models.GetAllCases()
106
+	// if err != nil {
107
+	// 	utils.LogError("获取有效案场列表失败: " + err.Error())
108
+	// 	return
109
+	// }
110
+
111
+	// for _, cs := range cases {
112
+	// 	ListenAllEvent(cs.OrgId, cs.CaseId)
113
+	// }
114
+
115
+	// 不区分案场
116
+	orgs, err := models.GetAllOrgs()
90 117
 	if err != nil {
91
-		utils.LogError("获取有效案场列表失败: " + err.Error())
118
+		utils.LogError("获取机构列表失败: " + err.Error())
92 119
 		return
93 120
 	}
94 121
 
95
-	for _, cs := range cases {
96
-		ListenAllEvent(cs.OrgId, cs.CaseId)
122
+	for _, org := range orgs {
123
+		ListenAllEvent(org.OrgId, "")
97 124
 	}
98 125
 }

+ 85
- 0
service/events/giveCard.go Просмотреть файл

@@ -0,0 +1,85 @@
1
+package events
2
+
3
+import (
4
+	"encoding/json"
5
+	"errors"
6
+	"spaceofcheng/services/models"
7
+	"spaceofcheng/services/models/model"
8
+	"spaceofcheng/services/service/card"
9
+	"spaceofcheng/services/utils"
10
+
11
+	"github.com/zjxpcyc/tinyevent"
12
+)
13
+
14
+var giveCard = func(e tinyevent.Event) error {
15
+	utils.LogInfo("开始卡赠送操作...")
16
+
17
+	ctx := NewContext()
18
+	defer DestroyContext(ctx, false)
19
+
20
+	if e.Payload == nil {
21
+		utils.LogError("注册送卡失败, 没有用户信息")
22
+		return errors.New("注册送卡失败, 没有用户信息")
23
+	}
24
+	cust := e.Payload.(model.TaCustomer)
25
+	// caseID := cust.RecommendCase
26
+	orgID := cust.OrgId
27
+
28
+	utils.LogInfo("被赠送人: " + cust.CustomerId)
29
+
30
+	// 不区分案场,随便送
31
+	// 2018年10月30日 yansen 按照产品要求
32
+	query := `
33
+		SELECT
34
+			t.*
35
+		FROM
36
+			sys_activity_action t
37
+		JOIN sys_activity s ON t.activity_id = s.activity_id
38
+		WHERE
39
+		t.active_type = 'giveCard'
40
+		AND	s.org_id = ?
41
+		AND s.status = ?
42
+		AND s.activity_type = ?
43
+	`
44
+
45
+	var acts []model.SysActivityAction
46
+	if err := models.DBEngine.SQL(query, orgID, models.STATUS_NORMAL, e.Name).Find(&acts); err != nil {
47
+		utils.LogError("检查营销活动失败: " + err.Error())
48
+		return errors.New("检查营销活动失败")
49
+	}
50
+
51
+	fromUser := model.SysUser{
52
+		UserId:   "SYSTEM",
53
+		UserName: "system",
54
+	}
55
+	cpServ := card.NewCardServ(ctx)
56
+	for _, act := range acts {
57
+		switch act.ActiveType {
58
+		case ActGiveCard:
59
+			res := make(map[string]interface{})
60
+			if err := json.Unmarshal([]byte(act.ResourceDesc), &res); err != nil {
61
+				utils.LogError("解析体验卡赠送规则失败: " + err.Error())
62
+				continue
63
+			}
64
+
65
+			cpID, has := res["giftValue"]
66
+			if !has {
67
+				continue
68
+			}
69
+
70
+			cp, err := cpServ.GetCardByID(cpID.(string))
71
+			if err != nil {
72
+				utils.LogError("获取体验卡失败: " + err.Error())
73
+				continue
74
+			}
75
+
76
+			if err := cpServ.GiveCardTo(&fromUser, &cust, cp); err != nil {
77
+				utils.LogError("送卡失败: " + err.Error())
78
+				continue
79
+			}
80
+		default:
81
+			utils.LogError("暂不支持的赠送类型")
82
+		}
83
+	}
84
+	return nil
85
+}

+ 9
- 6
service/events/giveCoupon.go Просмотреть файл

@@ -7,6 +7,7 @@ import (
7 7
 	"spaceofcheng/services/models/model"
8 8
 	"spaceofcheng/services/service/coupon"
9 9
 	"spaceofcheng/services/utils"
10
+	"strings"
10 11
 
11 12
 	"github.com/zjxpcyc/tinyevent"
12 13
 )
@@ -14,7 +15,7 @@ import (
14 15
 // giveCoupon 赠送卡券
15 16
 // Event.Payload.customer  = model.TaCustomer
16 17
 var giveCoupon = func(e tinyevent.Event) error {
17
-	utils.LogInfo("开始券赠送操作...")
18
+	utils.LogInfo("开始券赠送操作...")
18 19
 
19 20
 	ctx := NewContext()
20 21
 	defer DestroyContext(ctx, false)
@@ -25,11 +26,13 @@ var giveCoupon = func(e tinyevent.Event) error {
25 26
 	}
26 27
 
27 28
 	cust := e.Payload.(model.TaCustomer)
28
-	caseID := cust.RecommendCase
29
+	// caseID := cust.RecommendCase
29 30
 	orgID := cust.OrgId
30 31
 
31 32
 	utils.LogInfo("被赠送人: " + cust.CustomerId)
32 33
 
34
+	// 不区分案场,随便送
35
+	// 2018年10月30日 yansen 按照产品要求
33 36
 	query := `
34 37
 		SELECT
35 38
 			t.*
@@ -37,14 +40,14 @@ var giveCoupon = func(e tinyevent.Event) error {
37 40
 			sys_activity_action t
38 41
 		JOIN sys_activity s ON t.activity_id = s.activity_id
39 42
 		WHERE
40
-			s.org_id = ?
41
-		AND s.case_id = ?
43
+		t.active_type = 'giveCoupon'
44
+		AND	s.org_id = ?
42 45
 		AND s.status = ?
43 46
 		AND s.activity_type = ?
44 47
 	`
45 48
 
46 49
 	var acts []model.SysActivityAction
47
-	if err := models.DBEngine.SQL(query, orgID, caseID, models.STATUS_NORMAL, e.Name).Find(&acts); err != nil {
50
+	if err := models.DBEngine.SQL(query, orgID, models.STATUS_NORMAL, e.Name).Find(&acts); err != nil {
48 51
 		utils.LogError("检查营销活动失败: " + err.Error())
49 52
 		return errors.New("检查营销活动失败")
50 53
 	}
@@ -60,7 +63,7 @@ var giveCoupon = func(e tinyevent.Event) error {
60 63
 		switch act.ActiveType {
61 64
 		case ActGiveCoupon:
62 65
 			res := make(map[string]interface{})
63
-			if err := json.Unmarshal([]byte(act.ResourceDesc), &res); err != nil {
66
+			if err := json.Unmarshal([]byte(strings.Replace(act.ResourceDesc, "\n", "\\n", -1)), &res); err != nil {
64 67
 				utils.LogError("解析优惠券赠送规则失败: " + err.Error())
65 68
 				continue
66 69
 			}

+ 377
- 0
service/flashbuy/flashbuy.go Просмотреть файл

@@ -0,0 +1,377 @@
1
+package flashbuy
2
+
3
+import (
4
+	"errors"
5
+	"fmt"
6
+	"spaceofcheng/services/models"
7
+	"spaceofcheng/services/models/course"
8
+	"spaceofcheng/services/models/flashbuy"
9
+	"spaceofcheng/services/models/model"
10
+	"spaceofcheng/services/models/verify"
11
+	"spaceofcheng/services/service"
12
+	"spaceofcheng/services/utils"
13
+	"time"
14
+)
15
+
16
+// FlashBuyServ 系统处理
17
+type FlashBuyServ struct {
18
+	ctx       *utils.Context
19
+	dao       *flashbuy.FlashbuyDAO
20
+	vdao      *verify.VerifyDAO
21
+	courseDAO *course.CourseDAO
22
+}
23
+
24
+// NewFlashBuyServ 初始化
25
+func NewFlashBuyServ(ctx *utils.Context) *FlashBuyServ {
26
+	return &FlashBuyServ{
27
+		ctx:       ctx,
28
+		dao:       flashbuy.NewFlashbuyDAO(ctx),
29
+		vdao:      verify.NewVerifyDAO(ctx),
30
+		courseDAO: course.NewCourseDAO(ctx),
31
+	}
32
+}
33
+
34
+func (s *FlashBuyServ) GetFlashBuyList(caseid, flashBuyName, flashBuyStatus string, page, pageSize int) (map[string]interface{}, error) {
35
+	if pageSize == 0 {
36
+		pageSize = service.PAGENUM
37
+	}
38
+	flashbuys, err := s.dao.GetFlashBuyList(caseid, flashBuyName, flashBuyStatus, page, pageSize)
39
+	if err != nil {
40
+		utils.LogError("获取抢购活动列表失败: " + err.Error())
41
+		return nil, errors.New("获取抢购活动列表失败")
42
+	}
43
+	total, err := s.dao.GetFlashBuyListCount(caseid, flashBuyName, flashBuyStatus)
44
+	if err != nil {
45
+		utils.LogError("获取抢购活动列表失败: " + err.Error())
46
+		return nil, errors.New("获取抢购活动列表失败")
47
+	}
48
+	return map[string]interface{}{
49
+		"list":     flashbuys,
50
+		"pageSize": pageSize,
51
+		"pagenum":  total,
52
+		"page":     page,
53
+	}, nil
54
+}
55
+func (s *FlashBuyServ) GetFlashBuyById(flashBuyId string) (*model.TaFlashBuy, error) {
56
+	flashbuy, err := s.dao.GetFlashBuyById(flashBuyId)
57
+	if err != nil {
58
+		utils.LogError("获取抢购活动信息失败: " + err.Error())
59
+		return nil, errors.New("获取抢购活动信息失败")
60
+	}
61
+	return flashbuy, nil
62
+}
63
+
64
+// GetFlashByUser 获取用户的抢购信息
65
+func (s *FlashBuyServ) GetFlashByUser(id string) ([]model.TaCustomerFlashBuy, error) {
66
+	cst := s.ctx.Get("customer")
67
+	if cst == nil {
68
+		return nil, errors.New("系统内部错误")
69
+	}
70
+	flashbuys, err := s.dao.GetCustomerFlashBuy(id, cst.(model.TaCustomer).CustomerId)
71
+	return flashbuys, err
72
+}
73
+
74
+func (s *FlashBuyServ) SaveFlashBuy(flashbuy model.TaFlashBuy) (*model.TaFlashBuy, error) {
75
+	var newFlashBuy *model.TaFlashBuy
76
+	var err error
77
+	if flashbuy.CaseId == "" {
78
+		return nil, utils.LogError("请选择所属案场!")
79
+	}
80
+	if flashbuy.FlashBuyName == "" {
81
+		return nil, utils.LogError("请输入活动标题!")
82
+	}
83
+	if flashbuy.FlashBuyInfo == "" {
84
+		return nil, utils.LogError("请输入活动说明!")
85
+	}
86
+	if flashbuy.ModelId == "" {
87
+		return nil, utils.LogError("请选择活动模板!")
88
+	}
89
+	if flashbuy.FlashBuyId == "" {
90
+		org := s.ctx.Get("org").(model.SysOrg)
91
+		flashbuy.OrgId = org.OrgId
92
+		newFlashBuy, err = s.dao.AddNewFlashBuy(flashbuy)
93
+	} else {
94
+		err = s.dao.EditFlashBuy(flashbuy)
95
+		newFlashBuy = &flashbuy
96
+	}
97
+	if err != nil {
98
+		utils.LogError("保存抢购活动信息失败: " + err.Error())
99
+		return nil, errors.New("保存抢购活动信息失败")
100
+	}
101
+	return newFlashBuy, nil
102
+}
103
+
104
+func (s *FlashBuyServ) UpdateFlashBuy(flashBuyId, flashBuyStatus string) error {
105
+	err := s.dao.UpdateFlashBuy(flashBuyId, flashBuyStatus)
106
+	if err != nil {
107
+		utils.LogError("更新活动状态失败: " + err.Error())
108
+		return errors.New("更新活动状态失败")
109
+	}
110
+	return err
111
+}
112
+func (s *FlashBuyServ) DeleteFlashBuy(flashBuyId string) error {
113
+	err := s.dao.DeleteFlashBuy(flashBuyId)
114
+	if err != nil {
115
+		utils.LogError("删除抢购活动信息失败: " + err.Error())
116
+		return errors.New("删除抢购活动信息失败")
117
+	}
118
+	return err
119
+}
120
+
121
+func (s *FlashBuyServ) GetCustomerFlashBuyById(flashBuyId, phone string, page, pageSize int) (map[string]interface{}, error) {
122
+	if pageSize == 0 {
123
+		pageSize = service.PAGENUM
124
+	}
125
+	flashbuys, err := s.dao.GetCustomerFlashBuyById(flashBuyId, phone, page, pageSize)
126
+	if err != nil {
127
+		utils.LogError("获取记录列表失败: " + err.Error())
128
+		return nil, errors.New("获取获取记录列表失败")
129
+	}
130
+	total, err := s.dao.GetCustomerFlashBuyByIdCount(flashBuyId, phone)
131
+	if err != nil {
132
+		utils.LogError("获取记录列表失败: " + err.Error())
133
+		return nil, errors.New("获取获取记录列表失败")
134
+	}
135
+	return map[string]interface{}{
136
+		"list":     flashbuys,
137
+		"pageSize": pageSize,
138
+		"pagenum":  total,
139
+		"page":     page,
140
+	}, nil
141
+}
142
+
143
+func (s *FlashBuyServ) VerifyCustomerFlashBuyList(qrcode, caseId string) (*flashbuy.CustomerFlashBuy, error) {
144
+	var err error
145
+	var customerFlashBuyId string
146
+	var customerVerify *flashbuy.CustomerFlashBuy
147
+	customerFlashBuyId, err = s.vdao.GetCustomerCourseIdByQrcode(qrcode)
148
+	if err != nil {
149
+		utils.LogError("获取核销列表失败: " + err.Error())
150
+		return nil, errors.New("获取核销列表失败")
151
+	}
152
+	customerVerify, err = s.dao.GetCustomerFlashBuyByQr(customerFlashBuyId, caseId)
153
+	if err != nil {
154
+		utils.LogError("获取核销列表失败: " + err.Error())
155
+		return nil, errors.New("获取核销列表失败")
156
+	}
157
+	if customerVerify == nil {
158
+		return nil, errors.New("未查到奖品信息")
159
+	}
160
+	return customerVerify, nil
161
+
162
+}
163
+
164
+func (s *FlashBuyServ) Verify(customerFlashBuyId string) error {
165
+	err := s.dao.VerifyFlashBuy(customerFlashBuyId)
166
+	if err != nil {
167
+		utils.LogError("核销失败: " + err.Error())
168
+		return errors.New("核销失败")
169
+	}
170
+	return nil
171
+}
172
+
173
+func (s *FlashBuyServ) GetCustomerFlashBuyByCustomerId(customerId string, page, pageSize int) (map[string]interface{}, error) {
174
+	if pageSize == 0 {
175
+		pageSize = service.PAGENUM
176
+	}
177
+	flashbuys, err := s.dao.GetCustomerFlashBuyByCustomerId(customerId, page, pageSize)
178
+	if err != nil {
179
+		utils.LogError("获取抢购活动列表失败: " + err.Error())
180
+		return nil, errors.New("获取抢购活动列表失败")
181
+	}
182
+	total, err := s.dao.GetCustomerFlashBuyByCustomerIdCount(customerId)
183
+	if err != nil {
184
+		utils.LogError("获取抢购活动列表失败: " + err.Error())
185
+		return nil, errors.New("获取抢购活动列表失败")
186
+	}
187
+	return map[string]interface{}{
188
+		"list":     flashbuys,
189
+		"pageSize": pageSize,
190
+		"pagenum":  total,
191
+		"page":     page,
192
+	}, nil
193
+}
194
+
195
+func (s *FlashBuyServ) GetCustomerFlashBuyId(customerFlashBuyId string) (*flashbuy.CustomerFlashDetail, error) {
196
+	flashbuy, err := s.dao.GetCustomerFlashBuyId(customerFlashBuyId)
197
+	if err != nil {
198
+		utils.LogError("获取抢购活动信息失败: " + err.Error())
199
+		return nil, errors.New("获取抢购活动信息失败")
200
+	}
201
+	return flashbuy, nil
202
+}
203
+
204
+// FlashBuy 抢购
205
+func (s *FlashBuyServ) FlashBuy(id string) error {
206
+	flashbuy, err := s.dao.GetFlashBuyById(id)
207
+	if err != nil {
208
+		utils.LogError("获取抢购活动信息失败: " + err.Error())
209
+		return errors.New("获取抢购活动信息失败!")
210
+	}
211
+	if flashbuy.Status != models.STATUS_NORMAL {
212
+		return errors.New("抢购活动状态异常!")
213
+	}
214
+	if time.Now().After(flashbuy.EndDate) {
215
+		return errors.New("活动已结束!")
216
+	}
217
+	if flashbuy.FlashBuyStatus != models.FLASH_BUY_ACTIVE {
218
+		return errors.New("活动已停用!")
219
+	}
220
+	if time.Now().Before(flashbuy.StartDate) {
221
+		return errors.New("活动还未开始!")
222
+	}
223
+	customer := s.ctx.Get("customer").(model.TaCustomer)
224
+	if flashbuy.AttendantType == models.FLASHBUY_USER_NEW {
225
+		flashCustomer, err := s.dao.IsFlashBuyCustomer(customer.CustomerId, id)
226
+		if err != nil {
227
+			utils.LogError("获取客户抢购信息失败: " + err.Error())
228
+			return errors.New("获取客户抢购信息失败!")
229
+		}
230
+		if flashCustomer.IsNew == models.BOOL_FALSE {
231
+			return errors.New("此活动仅限新用户参加!")
232
+		}
233
+	}
234
+
235
+	buys, err := s.dao.GetCustomerFlashBuy(id, customer.CustomerId)
236
+	if err != nil {
237
+		utils.LogError("获取客户抢购信息失败: " + err.Error())
238
+		return errors.New("获取客户抢购信息失败!")
239
+	}
240
+	if len(buys) > 0 {
241
+		return errors.New("您已参与过该活动!")
242
+	}
243
+	if flashbuy.JoinNum >= flashbuy.FlashBuyMaxAttendant {
244
+		err = s.dao.UpdateFlashBuy(flashbuy.FlashBuyId, models.FLASH_BUY_OVER)
245
+		if err != nil {
246
+			utils.LogError("更新状态失败: " + err.Error())
247
+		}
248
+		return errors.New("活动已结束!")
249
+	}
250
+	var customerFlashBuy model.TaCustomerFlashBuy
251
+	customerFlashBuy.FlashBuyId = flashbuy.FlashBuyId
252
+	customerFlashBuy.CustomerId = customer.CustomerId
253
+	customerFlashBuy.CaseId = flashbuy.CaseId
254
+	customerFlashBuy.OrgId = flashbuy.OrgId
255
+	if flashbuy.ValidateType == models.FLASH_VALIDATE_DATE {
256
+		customerFlashBuy.ValidateStart = flashbuy.ValidateStart
257
+		customerFlashBuy.ValidateEnd = flashbuy.ValidateEnd
258
+	} else {
259
+		customerFlashBuy.ValidateStart = time.Now().Local()
260
+		customerFlashBuy.ValidateEnd = time.Now().Local().AddDate(0, 0, flashbuy.ValidateDays)
261
+	}
262
+	recored, err := s.dao.SaveCustomerFlashBuy(customerFlashBuy)
263
+	if err != nil {
264
+		utils.LogError("保存用户抢购信息失败: " + err.Error())
265
+		return errors.New("抢购失败!")
266
+	}
267
+	num, err := s.dao.UpdateFlashBuyJoin(flashbuy.FlashBuyId)
268
+	if err != nil {
269
+		utils.LogError("抢购失败: " + err.Error())
270
+		return errors.New("抢购失败!")
271
+	}
272
+	if num < 1 {
273
+		err = s.dao.UpdateFlashBuy(flashbuy.FlashBuyId, models.FLASH_BUY_OVER)
274
+		if err != nil {
275
+			utils.LogError("更新状态失败: " + err.Error())
276
+		}
277
+		return errors.New("活动已结束!")
278
+	}
279
+	custQRCode := model.TaCustomerCourseQrcode{
280
+		CustomerCourseId: recored.CustomerFlashBuyId,
281
+		CustomerQrcode:   utils.GenerateQRCode(),
282
+		CreateDate:       time.Now().Local(),
283
+		Status:           models.STATUS_NORMAL,
284
+		QrcodeType:       models.QRCODE_TYPE_FLASH,
285
+	}
286
+
287
+	if err := s.courseDAO.SaveCustomerCourseQrcode(&custQRCode); err != nil {
288
+		utils.LogError("插入中奖二维码失败: " + err.Error())
289
+		return errors.New("写入中奖二维码失败")
290
+	}
291
+	// ---------------推送消息
292
+
293
+	// 推送微信消息
294
+	userMap := s.ctx.Get("userMap").(model.TaUserMapping)
295
+	clienturl := s.ctx.Get("clienturl").(string)
296
+	tplID := s.ctx.Get("tplid").(string)
297
+
298
+	cs, err := models.GetCaseByID(recored.CaseId)
299
+	if err != nil {
300
+		utils.LogError("推送微信消息失败, 查询案场信息出错: " + err.Error())
301
+		// 但是不返回错误
302
+		return nil
303
+	}
304
+
305
+	caseName := cs.CaseName
306
+	remarkTpl := "请在%s日前, 前往%s兑换"
307
+
308
+	message := utils.Message{
309
+		To: utils.ClientID{ID: userMap.Openid},
310
+		Data: map[string]interface{}{
311
+			"orgid": recored.OrgId,
312
+			"tplid": tplID,
313
+			"link":  clienturl,
314
+			"data": map[string]string{
315
+				"first":    "抢券成功提醒",
316
+				"keyword1": flashbuy.FlashBuyName,
317
+				"keyword2": time.Now().Local().Format("2006-01-02"),
318
+				"remark":   fmt.Sprintf(remarkTpl, recored.ValidateEnd.Format("2006-01-02"), caseName),
319
+			},
320
+		},
321
+	}
322
+	go utils.SendWechat(message)
323
+
324
+	return nil
325
+}
326
+
327
+func (s *FlashBuyServ) GetFlashModelList() ([]model.TdFlashbuyModel, error) {
328
+	model, err := s.dao.GetFlashModelList()
329
+	if err != nil {
330
+		utils.LogError("获取抢购活动模板失败: " + err.Error())
331
+		return nil, errors.New("获取抢购活动模板失败")
332
+	}
333
+	return model, nil
334
+}
335
+
336
+func (s *FlashBuyServ) AddNewFlashBuyCustomer(customer model.TaCustomer, flashBuyId string) error {
337
+	count, err := s.dao.IsRecord(customer.CustomerId, flashBuyId)
338
+	if err != nil {
339
+		utils.LogError("存储用户抢购记录失败: " + err.Error())
340
+		return errors.New("存储用户抢购记录失败")
341
+	}
342
+	if count <= 0 {
343
+		var flashBuyCustomer = model.TaFlashBuyCustomer{
344
+			FlashBuyId: flashBuyId,
345
+			CustomerId: customer.CustomerId,
346
+		}
347
+		if customer.Phone == "" {
348
+			flashBuyCustomer.IsNew = 1
349
+		} else {
350
+			flashBuyCustomer.IsNew = 0
351
+		}
352
+		err := s.dao.AddNewFlashBuyCustomer(flashBuyCustomer)
353
+		if err != nil {
354
+			utils.LogError("存储用户抢购记录失败: " + err.Error())
355
+			return errors.New("存储用户抢购记录失败")
356
+		}
357
+	}
358
+
359
+	return nil
360
+}
361
+func (s *FlashBuyServ) UpdateFlashBuyCustomer(customerId, flashBuyId string) error {
362
+	err := s.dao.UpdateFlashBuyCustomer(customerId, flashBuyId)
363
+	if err != nil {
364
+		utils.LogError("更新用户抢购记录失败: " + err.Error())
365
+		return errors.New("更新用户抢购记录失败")
366
+	}
367
+	return nil
368
+}
369
+
370
+func (s *FlashBuyServ) IsFlashBuyCustomer(customerId, flashBuyId string) (*model.TaFlashBuyCustomer, error) {
371
+	flashBuyCustomer, err := s.dao.IsFlashBuyCustomer(customerId, flashBuyId)
372
+	if err != nil {
373
+		utils.LogError("判断是否参与失败: " + err.Error())
374
+		return nil, errors.New("判断是否参与失败")
375
+	}
376
+	return flashBuyCustomer, nil
377
+}

+ 3
- 0
service/goods/goods.go Просмотреть файл

@@ -9,6 +9,7 @@ import (
9 9
 	"spaceofcheng/services/models/goods"
10 10
 	"spaceofcheng/services/models/model"
11 11
 	"spaceofcheng/services/models/system"
12
+	"spaceofcheng/services/models/vipcard"
12 13
 	"spaceofcheng/services/utils"
13 14
 	"strings"
14 15
 )
@@ -21,6 +22,7 @@ type GoodsServ struct {
21 22
 	custDAO   *customer.CustomerDAO
22 23
 	userDAO   *system.UserDAO
23 24
 	couponDAO *coupon.CouponDAO
25
+	vipDAO    *vipcard.VipcardDAO
24 26
 }
25 27
 
26 28
 // NewGoodsServ 初始化
@@ -32,6 +34,7 @@ func NewGoodsServ(ctx *utils.Context) *GoodsServ {
32 34
 		custDAO:   customer.NewCustomerDAO(ctx),
33 35
 		userDAO:   system.NewUserDAO(ctx),
34 36
 		couponDAO: coupon.NewCouponDAO(ctx),
37
+		vipDAO:    vipcard.NewVipcardDAO(ctx),
35 38
 	}
36 39
 }
37 40
 

+ 150
- 40
service/goods/orders.go Просмотреть файл

@@ -16,46 +16,85 @@ import (
16 16
 	"github.com/yl10/kit/guid"
17 17
 )
18 18
 
19
-// Orders 下单
20
-func (s *GoodsServ) Orders(
19
+// PreOrders 下单
20
+func (s *GoodsServ) PreOrders(
21 21
 	info *model.TaGoodsOrders,
22 22
 	details []model.TaGoodsOrdersDetail,
23
-	customercouponid,
24
-	innerUser string) error {
25
-	// org := s.ctx.Get("org").(model.SysOrg)
23
+	innerUser string,
24
+) (*model.TaGoodsOrders, error) {
26 25
 	cust := s.ctx.Get("customer").(model.TaCustomer)
27 26
 
28 27
 	info.OrdersId = guid.NewGUIDString()
29 28
 	info.MakeStatus = goods.MAKESTATUS_NOTSTARTED
30 29
 	info.UserId = cust.CustomerId
30
+	info.IsPay = models.BOOL_FALSE
31
+	info.ActualAmount = "0.0"
32
+	info.CouponAmount = "0.0"
31 33
 	num, err := s.dao.GetOrderNumByUserNow(info.UserId)
32 34
 	if err != nil {
33 35
 		utils.LogError("获取5秒钟内是否下单错误:", err)
34
-		return errors.New("获取5秒钟内是否下单错误")
36
+		return nil, errors.New("获取5秒钟内是否下单错误")
35 37
 	}
36 38
 	if num > 0 {
37
-		return errors.New("5 秒内不能频繁下单")
39
+		return nil, errors.New("5 秒内不能频繁下单")
38 40
 	}
39 41
 
40 42
 	// 校验下单内容
41 43
 	if err := s.validOrdersInfo(info); err != nil {
42
-		return err
44
+		return nil, err
43 45
 	}
44 46
 
45 47
 	// 校验案场信息
46 48
 	if err := s.validOrdersCase(info, cust); err != nil {
47
-		return err
49
+		return nil, err
48 50
 	}
49 51
 
50 52
 	// 校验各种金额
51 53
 	if err := s.validBillCharges(info, details); err != nil {
52
-		return err
54
+		return nil, err
53 55
 	}
54 56
 
55 57
 	if innerUser == "sales" {
56 58
 		info.PayType = models.CONSUME_INNER
57 59
 		// 内部人员, 可以直接购买
58 60
 		// TODO
61
+	} else {
62
+		info.PayType = models.CONSUME_COUPON
63
+	}
64
+
65
+	// 保存主订单
66
+	if err := s.dao.SaveOrders(info); err != nil {
67
+		return nil, err
68
+	}
69
+
70
+	// 保存订单明细
71
+	if err := s.dao.SaveOrdersDetail(details, info.OrdersId); err != nil {
72
+		return nil, err
73
+	}
74
+
75
+	return info, nil
76
+}
77
+
78
+// ConfirmOrder 订单确认
79
+func (s *GoodsServ) ConfirmOrder(ordersID, customercouponid, remark string) error {
80
+	info, err := s.dao.GetOrdersByID(ordersID)
81
+	if err != nil {
82
+		return utils.LogError("获取订单失败", err)
83
+	}
84
+
85
+	if info.Status != models.STATUS_READY {
86
+		return errors.New("没有订单信息")
87
+	}
88
+
89
+	if info.IsPay == models.BOOL_TRUE {
90
+		return errors.New("订单已付款,请勿重复付款!")
91
+	}
92
+
93
+	info.Remark = remark
94
+
95
+	if info.PayType == models.CONSUME_INNER {
96
+		// 内部人员, 可以直接购买
97
+		// TODO
59 98
 	} else {
60 99
 		// 普通客户
61 100
 		account, err := s.custDAO.GetAccountByCust(info.UserId)
@@ -103,12 +142,12 @@ func (s *GoodsServ) Orders(
103 142
 				Price:   "0.0",
104 143
 				GoodsId: "",
105 144
 			}
106
-			for _, detail := range details {
145
+			for _, detail := range info.Goods {
107 146
 				if coupon.IsAll == 1 {
108 147
 					dyprice, _ := strconv.ParseFloat(dyGoods.Price, 64)
109 148
 					detailprice, _ := strconv.ParseFloat(detail.Price, 64)
110 149
 					if dyprice < detailprice {
111
-						dyGoods = detail
150
+						dyGoods = detail.TaGoodsOrdersDetail
112 151
 					}
113 152
 				} else {
114 153
 					for _, target := range coupon.Targets {
@@ -116,7 +155,7 @@ func (s *GoodsServ) Orders(
116 155
 							dyprice, _ := strconv.ParseFloat(dyGoods.Price, 64)
117 156
 							detailprice, _ := strconv.ParseFloat(detail.Price, 64)
118 157
 							if dyprice < detailprice {
119
-								dyGoods = detail
158
+								dyGoods = detail.TaGoodsOrdersDetail
120 159
 							}
121 160
 						}
122 161
 					}
@@ -135,7 +174,7 @@ func (s *GoodsServ) Orders(
135 174
 					UsedAmount:       dyGoods.Price,
136 175
 					CustomerCouponId: customerCoupon.CustomerCouponId,
137 176
 				}
138
-				if err := s.dao.SaveOrdersCoupon(&ordersCoupon, info); err != nil {
177
+				if err := s.dao.SaveOrdersCoupon(&ordersCoupon, &info.TaGoodsOrders); err != nil {
139 178
 					utils.LogError("保存优惠信息出错: " + err.Error())
140 179
 					return errors.New("保存优惠信息出错")
141 180
 				}
@@ -148,6 +187,18 @@ func (s *GoodsServ) Orders(
148 187
 					utils.LogError("优惠券核销出错: " + err.Error())
149 188
 					return errors.New("优惠券核销出错")
150 189
 				}
190
+				// 券库存处理
191
+				var couponinfo = model.TaCoupon{
192
+					CouponId:  coupon.CouponId,
193
+					UsedCount: coupon.UsedCount + 1,
194
+				}
195
+				cols := []string{
196
+					"used_count",
197
+				}
198
+				if err := s.couponDAO.UpdateCoupon(&couponinfo, cols); err != nil {
199
+					utils.LogError("回填优惠券信息失败:", err)
200
+					return errors.New("回填优惠券信息失败!")
201
+				}
151 202
 			} else {
152 203
 				return errors.New("优惠券不可抵用商品")
153 204
 			}
@@ -161,39 +212,79 @@ func (s *GoodsServ) Orders(
161 212
 		couponAmount, _ := strconv.ParseFloat(info.CouponAmount, 64)
162 213
 		payMoney, _ := strconv.ParseFloat(info.Amount, 64)
163 214
 		payMoney = payMoney - couponAmount
164
-		if accMoney < payMoney {
165
-			return errors.New("账户余额不足")
166
-		}
167
-
168
-		info.ActualAmount = strconv.FormatFloat(payMoney, 'f', -1, 64)
169
-		if payMoney > 0 && couponAmount > 0 && info.PayType != models.CONSUME_INNER {
170
-			info.PayType = models.CONSUME_COUPON_COIN
171
-		}
172 215
 
173 216
 		// 如果是城币, 则插入用户账户消费记录
174 217
 		if payMoney > 0 {
175
-			if err := s.saveCustomerPayRec(account, info); err != nil {
176
-				return err
218
+			var leftPay = payMoney
219
+			vips, err := s.custDAO.GetValidVIPCards(info.UserId)
220
+			if err != nil {
221
+				return utils.LogError("查询用户 VIP卡 出错", err)
222
+			}
223
+
224
+			var vipAccount float64
225
+			if vips != nil && len(vips) > 0 {
226
+				for _, vip := range vips {
227
+					vipMoney, _ := strconv.ParseFloat(vip.Balance, 64)
228
+					vipAccount += vipMoney
229
+
230
+					// 当前扣款
231
+					var vipPay float64
232
+					if vipMoney > leftPay {
233
+						// 如果卡余额比 需要扣款的多, 那么就只扣这一张卡
234
+						// 通过 leftPay < 0.01 来判断
235
+						vipPay = leftPay
236
+						leftPay = 0
237
+					} else {
238
+						// 如果余额不够, 先扣掉本张卡余额, 继续循环
239
+						vipPay = vipMoney
240
+						leftPay -= vipMoney
241
+					}
242
+
243
+					if err := s.saveVipChangeRec(vipPay, &vip, &info.TaGoodsOrders); err != nil {
244
+						return utils.LogError("VIP卡扣款失败", err.Error())
245
+					}
246
+
247
+					if leftPay < 0.01 {
248
+						break
249
+					}
250
+				}
251
+			}
252
+			// 如果 VIP 卡余额不足, 则使用账户余额
253
+			if leftPay > 0.01 {
254
+				if leftPay > accMoney {
255
+					return errors.New("账户余额不足")
256
+				}
257
+
258
+				// 插入账户流水
259
+				if err := s.saveCustomerPayRec(leftPay, account, &info.TaGoodsOrders); err != nil {
260
+					utils.LogError("插入账户流水出错: " + err.Error())
261
+					return errors.New("写入账户流水出错")
262
+				}
177 263
 			}
178 264
 		}
179 265
 	}
180 266
 
181
-	// 保存主订单
182
-	if err := s.dao.SaveOrders(info); err != nil {
183
-		return err
267
+	// 更新订单
268
+	orders := info.TaGoodsOrders
269
+	orders.IsPay = models.BOOL_TRUE
270
+	orders.Status = models.STATUS_NORMAL
271
+	orders.Remark = info.Remark
272
+
273
+	if orders.ActualAmount == "" {
274
+		orders.ActualAmount = "0.0"
184 275
 	}
185 276
 
186
-	// 保存订单明细
187
-	if err := s.dao.SaveOrdersDetail(details, info.OrdersId); err != nil {
277
+	if orders.CouponAmount == "" {
278
+		orders.CouponAmount = "0.0"
279
+	}
280
+
281
+	if err := s.dao.UpdateOrders(&orders, []string{
282
+		"status", "is_pay", "coupon_amount", "actual_amount", "remark",
283
+	}); err != nil {
284
+		utils.LogError("修改订单状态失败:", err.Error())
188 285
 		return err
189 286
 	}
190 287
 
191
-	// 通知后端有新订单 - websocket
192
-	// orderList, err := s.GetOnLineOrders(info.CaseId, false)
193
-	// if err != nil {
194
-	// 	utils.LogError("获取新单列表出错: " + err.Error())
195
-	// 	return nil
196
-	// }
197 288
 	newOrder, err := s.GetNewGoods(info.OrdersId)
198 289
 	if err != nil {
199 290
 		// 下单流程已经结束, 不反馈错误
@@ -218,10 +309,12 @@ func (s *GoodsServ) Orders(
218 309
 }
219 310
 
220 311
 // saveCustomerPayRec 保存账户消费流水
221
-func (s *GoodsServ) saveCustomerPayRec(account *model.TaCustomerAccount, info *model.TaGoodsOrders) error {
312
+func (s *GoodsServ) saveCustomerPayRec(payMoney float64, account *model.TaCustomerAccount, info *model.TaGoodsOrders) error {
313
+	actAmount := strconv.FormatFloat(payMoney, 'f', -1, 64)
314
+
222 315
 	accBill := new(model.TaAccountChange)
223 316
 	accBill.AccountId = account.AccountId
224
-	accBill.Amount = info.ActualAmount
317
+	accBill.Amount = actAmount
225 318
 	accBill.CaseId = info.CaseId
226 319
 	accBill.ChangeSource = models.ACCSOURCE_GOODS_ORDERS
227 320
 	accBill.ChangeType = models.CONSUME_COINCHG
@@ -234,6 +327,26 @@ func (s *GoodsServ) saveCustomerPayRec(account *model.TaCustomerAccount, info *m
234 327
 	return s.custDAO.InsertAccountRecords(accBill)
235 328
 }
236 329
 
330
+// saveVipChangeRec 保存vip消费记录
331
+func (s *GoodsServ) saveVipChangeRec(payMoney float64, custVIP *model.TaCustomerVip, info *model.TaGoodsOrders) error {
332
+	vipChange := new(model.TaCustomerVipChange)
333
+	vipChange.CustomerVipId = custVIP.CustomerVipId
334
+	vipChange.CustomerId = info.UserId
335
+	vipChange.OrgId = info.OrgId
336
+	vipChange.CaseId = info.CaseId
337
+	vipChange.ChangeType = models.CONSUME_COINCHG
338
+	vipChange.FloatType = models.ACCOUNT_SPENT
339
+	vipChange.SourceId = info.OrdersId
340
+	vipChange.SourceName = "商品下单"
341
+	vipChange.Amount = strconv.FormatFloat(payMoney, 'f', -1, 64)
342
+
343
+	if err := s.vipDAO.InsertCustomerVipChange(*vipChange); err != nil {
344
+		return err
345
+	}
346
+
347
+	return s.custDAO.UpdateCustVipCardAmount(custVIP, payMoney)
348
+}
349
+
237 350
 // validOrdersInfo 校验下单内容
238 351
 // 没有对金额, 数量的关系进行校验
239 352
 func (s *GoodsServ) validOrdersInfo(info *model.TaGoodsOrders) error {
@@ -311,9 +424,6 @@ func (s *GoodsServ) validOrdersInfo(info *model.TaGoodsOrders) error {
311 424
 				if info.UserName == "" {
312 425
 					info.UserName = cust.CustomerName
313 426
 				}
314
-				// if ut.CaseId == caseID {
315
-
316
-				// }
317 427
 			}
318 428
 		}
319 429
 

+ 331
- 4
service/luckdraw/luckdraw.go Просмотреть файл

@@ -2,10 +2,12 @@ package luckdraw
2 2
 
3 3
 import (
4 4
 	"errors"
5
+	"fmt"
5 6
 	"spaceofcheng/services/models"
6 7
 	"spaceofcheng/services/models/course"
7 8
 	"spaceofcheng/services/models/luckdraw"
8 9
 	"spaceofcheng/services/models/model"
10
+	"spaceofcheng/services/service"
9 11
 	"spaceofcheng/services/utils"
10 12
 	"time"
11 13
 )
@@ -26,6 +28,283 @@ func NewLuckdrawServ(ctx *utils.Context) *LuckdrawServ {
26 28
 	}
27 29
 }
28 30
 
31
+// GetLuckDrawTpl 获取抽奖模板
32
+func (s *LuckdrawServ) GetLuckDrawTpl() ([]model.TaLuckdrawTpl, error) {
33
+	org := s.ctx.Get("org").(model.SysOrg)
34
+	tpls, err := s.dao.GetLuckDrawTpl(org.OrgId)
35
+	return tpls, err
36
+}
37
+
38
+// GetLuckDrawList 获取抽奖列表
39
+func (s *LuckdrawServ) GetLuckDrawList(caseids, name, status string, page, pageSize int) (map[string]interface{}, error) {
40
+	if pageSize == 0 {
41
+		pageSize = service.PAGENUM
42
+	}
43
+	if page == 0 {
44
+		page = 1
45
+	}
46
+	list, err := s.dao.GetLuckDrawList(caseids, name, status, page, pageSize)
47
+	if err != nil {
48
+		utils.LogError("获取抽奖信息失败: " + err.Error())
49
+		return nil, errors.New("获取抽奖信息失败")
50
+	}
51
+	total, err := s.dao.GetLuckDrawCount(caseids, name, status)
52
+	if err != nil {
53
+		utils.LogError("获取抽奖信息失败: " + err.Error())
54
+		return nil, errors.New("获取抽奖信息失败")
55
+	}
56
+
57
+	return map[string]interface{}{
58
+		"list":     list,
59
+		"pagesize": pageSize,
60
+		"pagenum":  total,
61
+		"page":     page,
62
+	}, nil
63
+}
64
+
65
+// GetLuckDrawRecordList 获取抽奖记录列表
66
+func (s *LuckdrawServ) GetLuckDrawRecordList(luckdrawid, tel string, page, pageSize int) (map[string]interface{}, error) {
67
+	if pageSize == 0 {
68
+		pageSize = service.PAGENUM
69
+	}
70
+	if page == 0 {
71
+		page = 1
72
+	}
73
+	list, err := s.dao.GetLuckDrawRecord(luckdrawid, tel, page, pageSize)
74
+	if err != nil {
75
+		utils.LogError("获取抽奖记录信息失败: " + err.Error())
76
+		return nil, errors.New("获取抽奖记录信息失败")
77
+	}
78
+	total, err := s.dao.GetLuckDrawRecordCount(luckdrawid, tel)
79
+	if err != nil {
80
+		utils.LogError("获取抽奖记录信息失败: " + err.Error())
81
+		return nil, errors.New("获取抽奖记录信息失败")
82
+	}
83
+
84
+	return map[string]interface{}{
85
+		"list":     list,
86
+		"pagesize": pageSize,
87
+		"pagenum":  total,
88
+		"page":     page,
89
+	}, nil
90
+}
91
+
92
+// GetLuckDrawShareList 获取抽奖分享记录列表
93
+func (s *LuckdrawServ) GetLuckDrawShareList(luckdrawid, tel string, page, pageSize int) (map[string]interface{}, error) {
94
+	if pageSize == 0 {
95
+		pageSize = service.PAGENUM
96
+	}
97
+	if page == 0 {
98
+		page = 1
99
+	}
100
+	list, err := s.dao.GetLuckDrawShare(luckdrawid, tel, page, pageSize)
101
+	if err != nil {
102
+		utils.LogError("获取抽奖分享记录信息失败: " + err.Error())
103
+		return nil, errors.New("获取抽奖分享记录信息失败")
104
+	}
105
+	total, err := s.dao.GetLuckDrawShareCount(luckdrawid, tel)
106
+	if err != nil {
107
+		utils.LogError("获取抽奖分享记录信息失败: " + err.Error())
108
+		return nil, errors.New("获取抽奖分享记录信息失败")
109
+	}
110
+
111
+	return map[string]interface{}{
112
+		"list":     list,
113
+		"pagesize": pageSize,
114
+		"pagenum":  total,
115
+		"page":     page,
116
+	}, nil
117
+}
118
+
119
+// GetLuckDrawInfoByID 获取单个抽奖记录
120
+func (s *LuckdrawServ) GetLuckDrawInfoByID(luckdrawid string) (*luckdraw.LuckDrawInfo, error) {
121
+	info, err := s.dao.GetLuckDrawInfoByID(luckdrawid)
122
+	if err != nil {
123
+		utils.LogError("获取抽奖信息失败: " + err.Error())
124
+		return nil, errors.New("获取抽奖信息失败")
125
+	}
126
+	return info, nil
127
+}
128
+
129
+// SaveLuckDraw 保存抽奖信息
130
+func (s *LuckdrawServ) SaveLuckDraw(luckdraw *luckdraw.LuckDrawInfo) (*model.TaLuckdraw, error) {
131
+	if luckdraw.CaseId == "" {
132
+		return nil, utils.LogError("请选择所属案场!")
133
+	}
134
+	if luckdraw.Name == "" {
135
+		return nil, utils.LogError("请输入活动标题!")
136
+	}
137
+	if luckdraw.BeginDate.IsZero() || luckdraw.EndDate.IsZero() {
138
+		return nil, utils.LogError("请选择活动时间!")
139
+	}
140
+	if luckdraw.TplId == "" {
141
+		return nil, utils.LogError("请选择活动模板!")
142
+	}
143
+	if luckdraw.LuckdrawRule == "" {
144
+		return nil, utils.LogError("请填写规则说明!")
145
+	}
146
+	var newInfo *model.TaLuckdraw
147
+	var err error
148
+	if luckdraw.Id == "" {
149
+		org := s.ctx.Get("org").(model.SysOrg)
150
+		luckdraw.OrgId = org.OrgId
151
+		user := s.ctx.Get("user").(model.SysUser)
152
+		luckdraw.CreateUser = user.UserId
153
+		newInfo, err = s.dao.InsertLuckdraw(luckdraw.TaLuckdraw)
154
+		if err != nil {
155
+			utils.LogError("保存抽奖信息失败: " + err.Error())
156
+			return nil, errors.New("保存抽奖信息失败")
157
+		}
158
+	} else {
159
+		if luckdraw.JoinedNum > 0 {
160
+			var cols = []string{
161
+				"name",
162
+				"luckdraw_rule",
163
+				"remark",
164
+			}
165
+			err = s.dao.UpdateLuckDraw(luckdraw.TaLuckdraw, cols)
166
+			if err != nil {
167
+				utils.LogError("更新抽奖信息失败: " + err.Error())
168
+				return nil, errors.New("更新抽奖信息失败")
169
+			}
170
+
171
+			err = s.dao.UpdatePrizeDesc(luckdraw.Prizes)
172
+			if err != nil {
173
+				utils.LogError("更新抽奖信息失败: " + err.Error())
174
+				return nil, errors.New("更新抽奖信息失败")
175
+			}
176
+			return &luckdraw.TaLuckdraw, nil
177
+		}
178
+		var cols = []string{
179
+			"name",
180
+			"tpl_id",
181
+			"luckdraw_rule",
182
+			"begin_date",
183
+			"end_date",
184
+			"case_id",
185
+			"remark",
186
+			"join_num",
187
+			"join_type",
188
+			"num_type",
189
+			"num_interval",
190
+			"luckdraw_num",
191
+			"share_type",
192
+			"share_add_num",
193
+			"is_sys_luckdraw",
194
+			"is_internal_default"}
195
+		err = s.dao.UpdateLuckDraw(luckdraw.TaLuckdraw, cols)
196
+		if err != nil {
197
+			utils.LogError("更新抽奖信息失败: " + err.Error())
198
+			return nil, errors.New("更新抽奖信息失败")
199
+		}
200
+		newInfo = &luckdraw.TaLuckdraw
201
+		// 删除奖品内定信息
202
+		err = s.dao.DelLuckDrawDefault(luckdraw.Id)
203
+		if err != nil {
204
+			utils.LogError("删除抽奖内定信息失败: " + err.Error())
205
+			return nil, errors.New("更新抽奖信息失败")
206
+		}
207
+		// 删除抽奖图片信息
208
+		err = s.dao.DelLuckDrawImgs(luckdraw.Id)
209
+		if err != nil {
210
+			utils.LogError("删除抽奖图片信息失败: " + err.Error())
211
+			return nil, errors.New("更新抽奖信息失败")
212
+		}
213
+		// 删除奖品信息
214
+		err = s.dao.DelLuckDrawPrize(luckdraw.Id)
215
+		if err != nil {
216
+			utils.LogError("删除奖品信息失败: " + err.Error())
217
+			return nil, errors.New("更新奖品信息失败")
218
+		}
219
+
220
+		// 删除该抽奖对应的设置信息
221
+		err = s.dao.DelLuckDrawSet(luckdraw.Id)
222
+		if err != nil {
223
+			utils.LogError("删除奖品信息失败: " + err.Error())
224
+			return nil, errors.New("更新奖品信息失败")
225
+		}
226
+	}
227
+
228
+	// 保存抽奖图片信息
229
+	err = s.dao.SaveLuckDrawImgs(luckdraw.Imgs, newInfo.Id)
230
+	if err != nil {
231
+		utils.LogError("保存抽奖图片信息失败: " + err.Error())
232
+		return nil, errors.New("保存抽奖图片信息失败")
233
+	}
234
+
235
+	// 保存奖品信息
236
+	err = s.dao.SaveLuckDrawPrizes(luckdraw.Prizes, newInfo)
237
+	if err != nil {
238
+		utils.LogError("保存奖品信息失败: " + err.Error())
239
+		return nil, errors.New("保存奖品信息失败:" + err.Error())
240
+	}
241
+	return newInfo, nil
242
+}
243
+
244
+// OpenLuckDraw 启动游戏
245
+func (s *LuckdrawServ) OpenLuckDraw(id string) error {
246
+	ld, err := s.dao.GetLuckDrawByID(id)
247
+	if err != nil {
248
+		utils.LogError("获取游戏信息失败: " + err.Error())
249
+		return errors.New("获取游戏信息失败")
250
+	}
251
+	if ld.Status != models.STATUS_READY {
252
+		return errors.New("游戏状态异常,请刷新后重试!")
253
+	}
254
+	var luckdraw = model.TaLuckdraw{
255
+		Id:     id,
256
+		Status: models.STATUS_NORMAL,
257
+	}
258
+	err = s.dao.UpdateLuckDraw(luckdraw, []string{
259
+		"status",
260
+	})
261
+	return err
262
+}
263
+
264
+// StopLuckDraw 暂停游戏
265
+func (s *LuckdrawServ) StopLuckDraw(id string) error {
266
+	// 判断
267
+	ld, err := s.dao.GetLuckDrawByID(id)
268
+	if err != nil {
269
+		utils.LogError("获取游戏信息失败: " + err.Error())
270
+		return errors.New("获取游戏信息失败")
271
+	}
272
+	if ld.Status != models.STATUS_NORMAL {
273
+		return errors.New("游戏状态异常,请刷新后重试!")
274
+	}
275
+
276
+	var luckdraw = model.TaLuckdraw{
277
+		Id:     id,
278
+		Status: models.STATUS_READY,
279
+	}
280
+	err = s.dao.UpdateLuckDraw(luckdraw, []string{
281
+		"status",
282
+	})
283
+	return err
284
+}
285
+
286
+// DelLuckDraw 删除游戏
287
+func (s *LuckdrawServ) DelLuckDraw(id string) error {
288
+	// 判断
289
+	ld, err := s.dao.GetLuckDrawByID(id)
290
+	if err != nil {
291
+		utils.LogError("获取游戏信息失败: " + err.Error())
292
+		return errors.New("获取游戏信息失败")
293
+	}
294
+	if ld.Status != models.STATUS_READY {
295
+		return errors.New("游戏状态异常,请刷新后重试!")
296
+	}
297
+	var luckdraw = model.TaLuckdraw{
298
+		Id:     id,
299
+		Status: models.STATUS_DEL,
300
+	}
301
+	err = s.dao.UpdateLuckDraw(luckdraw, []string{
302
+		"status",
303
+	})
304
+	return err
305
+}
306
+
307
+// GetLuckDraw 获取抽奖信息
29 308
 func (s *LuckdrawServ) GetLuckDraw(id string) (*luckdraw.LuckDraw, error) {
30 309
 	luck, err := s.dao.GetLuckDraw(id)
31 310
 	if err != nil {
@@ -34,6 +313,7 @@ func (s *LuckdrawServ) GetLuckDraw(id string) (*luckdraw.LuckDraw, error) {
34 313
 	return luck, nil
35 314
 }
36 315
 
316
+// LuckDraw 抽奖
37 317
 func (s *LuckdrawServ) LuckDraw(id string, user *model.TaCustomer) (*model.TaLuckdrawPrize, *model.TaPrizeDetail, error) {
38 318
 	prize, prizeDetail, recored, err := s.dao.LuckDraw(id, user)
39 319
 	if err != nil {
@@ -56,6 +336,40 @@ func (s *LuckdrawServ) LuckDraw(id string, user *model.TaCustomer) (*model.TaLuc
56 336
 		return nil, nil, errors.New("写入中奖二维码失败")
57 337
 	}
58 338
 
339
+	if prize.IsReality == models.BOOL_TRUE {
340
+		// 推送微信消息
341
+		userMap := s.ctx.Get("userMap").(model.TaUserMapping)
342
+		clienturl := s.ctx.Get("clienturl").(string)
343
+		tplID := s.ctx.Get("tplid").(string)
344
+
345
+		cs, err := models.GetCaseByID(recored.CaseId)
346
+		if err != nil {
347
+			utils.LogError("推送微信消息失败, 查询案场信息出错: " + err.Error())
348
+			// 但是不返回错误
349
+			return nil, nil, nil
350
+		}
351
+
352
+		caseName := cs.CaseName
353
+		remarkTpl := "请在%s日前, 前往%s兑换"
354
+
355
+		message := utils.Message{
356
+			To: utils.ClientID{ID: userMap.Openid},
357
+			Data: map[string]interface{}{
358
+				"orgid": recored.OrgId,
359
+				"tplid": tplID,
360
+				"link":  clienturl,
361
+				"data": map[string]string{
362
+					"first":    "中奖成功提醒",
363
+					"keyword1": prize.PrizeName,
364
+					"keyword2": time.Now().Local().Format("2006-01-02"),
365
+					"remark":   fmt.Sprintf(remarkTpl, recored.VerificationEnd.Format("2006-01-02"), caseName),
366
+				},
367
+			},
368
+		}
369
+
370
+		go utils.SendWechat(message)
371
+	}
372
+
59 373
 	return prize, prizeDetail, nil
60 374
 }
61 375
 
@@ -194,13 +508,20 @@ func (s *LuckdrawServ) GetUserRecordByLuckDraw(userid string, luckdrawid string)
194 508
 	return record, nil
195 509
 }
196 510
 
197
-func (s *LuckdrawServ) GetUserLuckDrawByLuckDraw(userid string, luckdrawid string) (*model.TaLuckdrawRecord, error) {
198
-	record, err := s.dao.GetUserLuckDrawByLuckDraw(userid, luckdrawid)
511
+// GetUserLuckDrawByLuckDraw 获取用户抽奖信息
512
+func (s *LuckdrawServ) GetUserLuckDrawByLuckDraw(user model.TaCustomer, luckdrawid string) (*model.TaLuckdrawRecord, *model.TaLuckdrawCustomer, error) {
513
+	// 获取用户抽奖设置信息
514
+	customerSet, err := s.dao.GetUserLuckDrawSet(user, luckdrawid)
515
+	if err != nil {
516
+		utils.LogError("获取用户抽奖设置失败: " + err.Error())
517
+		return nil, nil, errors.New("获取用户抽奖设置失败")
518
+	}
519
+	record, err := s.dao.GetUserLuckDrawByLuckDraw(user.CustomerId, luckdrawid)
199 520
 	if err != nil {
200 521
 		utils.LogError("获取用户的抽奖信息失败: " + err.Error())
201
-		return nil, errors.New("获取用户的抽奖信息失败")
522
+		return nil, nil, errors.New("获取用户的抽奖信息失败")
202 523
 	}
203
-	return record, nil
524
+	return record, customerSet, nil
204 525
 }
205 526
 
206 527
 func (s *LuckdrawServ) GetDetailByRecord(recordid string) (*model.TaPrizeDetail, error) {
@@ -267,3 +588,9 @@ func (s *LuckdrawServ) GetLuckDrawShareData(luckID, from, to, caseID string) ([]
267 588
 	}
268 589
 	return share, nil
269 590
 }
591
+
592
+// UpdateShareNum 更新抽奖次数
593
+func (s *LuckdrawServ) UpdateShareNum(luckdraw *luckdraw.LuckDraw, fromid string) error {
594
+	err := s.dao.UpdateShareNum(luckdraw, fromid)
595
+	return err
596
+}

+ 29
- 9
service/marketing/marketing.go Просмотреть файл

@@ -4,6 +4,7 @@ import (
4 4
 	"encoding/json"
5 5
 	"errors"
6 6
 	"spaceofcheng/services/models"
7
+	"spaceofcheng/services/models/card"
7 8
 	"spaceofcheng/services/models/coupon"
8 9
 	"spaceofcheng/services/models/marketing"
9 10
 	"spaceofcheng/services/models/model"
@@ -11,6 +12,7 @@ import (
11 12
 	"spaceofcheng/services/service"
12 13
 	"spaceofcheng/services/service/events"
13 14
 	"spaceofcheng/services/utils"
15
+	"strings"
14 16
 
15 17
 	"github.com/astaxie/beego"
16 18
 )
@@ -22,6 +24,7 @@ type MarketingServ struct {
22 24
 	wdao      *marketing.WorkDAO
23 25
 	userdao   *system.UserDAO
24 26
 	couponDAO *coupon.CouponDAO
27
+	cardDAO   *card.CardDAO
25 28
 }
26 29
 
27 30
 // NewMarketingServ 初始化
@@ -32,6 +35,7 @@ func NewMarketingServ(ctx *utils.Context) *MarketingServ {
32 35
 		wdao:      marketing.NewWorkDAO(ctx),
33 36
 		userdao:   system.NewUserDAO(ctx),
34 37
 		couponDAO: coupon.NewCouponDAO(ctx),
38
+		cardDAO:   card.NewCardDAO(ctx),
35 39
 	}
36 40
 }
37 41
 
@@ -67,7 +71,7 @@ func (s *MarketingServ) GetMarketingList(caseids string, page int, pageSize int)
67 71
  */
68 72
 func (s *MarketingServ) SaveMarketing(activity model.SysActivity, activeType, resourceDesc string) (*model.SysActivity, *model.SysActivityAction, error) {
69 73
 	res := make(map[string]interface{})
70
-	if err := json.Unmarshal([]byte(resourceDesc), &res); err != nil {
74
+	if err := json.Unmarshal([]byte(strings.Replace(resourceDesc, "\n", "\\n", -1)), &res); err != nil {
71 75
 		utils.LogError("校验活动数据失败: " + err.Error())
72 76
 		return nil, nil, errors.New("校验活动数据失败")
73 77
 	}
@@ -96,18 +100,25 @@ func (s *MarketingServ) SaveMarketing(activity model.SysActivity, activeType, re
96 100
 		// 	return nil, nil, errors.New("赠送数量不能大于卡券总数的数量")
97 101
 		// }
98 102
 	}
103
+	if activeType == events.ActGiveCard {
104
+		cardID := res["giftValue"].(string)
105
+		if cardID == "" {
106
+			return nil, nil, errors.New("未指定赠送卡内容")
107
+		}
108
+	}
99 109
 
100 110
 	var newInfo *model.SysActivity
101 111
 	var newWoke *model.SysActivityAction
102 112
 
103
-	user := s.ctx.Get("user").(model.SysUser)
113
+	// user := s.ctx.Get("user").(model.SysUser)
104 114
 
105
-	caseinfo, err := s.userdao.GetUserBelongCase(user.UserId)
106
-	if err != nil {
107
-		return nil, nil, err
108
-	}
109
-	activity.CaseId = caseinfo.CaseId
115
+	// caseinfo, err := s.userdao.GetUserBelongCase(user.UserId)
116
+	// if err != nil {
117
+	// 	return nil, nil, err
118
+	// }
119
+	// activity.CaseId = caseinfo.CaseId
110 120
 	// 存储 营销活动
121
+	var err error
111 122
 	newInfo, err = s.dao.AddMarketing(activity)
112 123
 	if err != nil {
113 124
 		return nil, nil, err
@@ -118,7 +129,7 @@ func (s *MarketingServ) SaveMarketing(activity model.SysActivity, activeType, re
118 129
 	woke.ActiveType = activeType
119 130
 	woke.ResourceDesc = resourceDesc
120 131
 	woke.ResourceType = "占位符"
121
-
132
+	woke.ResourceId = res["giftValue"].(string)
122 133
 	// 存储 活动动作
123 134
 	newWoke, err = s.wdao.AddWork(woke)
124 135
 	if err != nil {
@@ -126,7 +137,7 @@ func (s *MarketingServ) SaveMarketing(activity model.SysActivity, activeType, re
126 137
 	}
127 138
 
128 139
 	// 重启事件
129
-	events.ListenAllEvent(activity.OrgId, activity.CaseId)
140
+	events.ListenAllEvent(newInfo.OrgId, newInfo.CaseId)
130 141
 
131 142
 	return newInfo, newWoke, err
132 143
 }
@@ -225,3 +236,12 @@ func (s *MarketingServ) UpdateMarketing(activity model.SysActivity) error {
225 236
 	err := s.dao.UpdateMarketing(activity)
226 237
 	return err
227 238
 }
239
+
240
+func (s *MarketingServ) GetUserCases(caseId string) ([]model.SysCase, error) {
241
+	cases, err := s.dao.GetUserCases(caseId)
242
+	if err != nil {
243
+		utils.LogError("获取用户案场失败: " + err.Error())
244
+		return nil, errors.New("获取用户案场失败")
245
+	}
246
+	return cases, nil
247
+}

+ 0
- 1
service/sys.go Просмотреть файл

@@ -182,7 +182,6 @@ func (s *SysServ) authWechat(gctx *context.Context) map[string]interface{} {
182 182
 
183 183
 		// 获取 token
184 184
 		token, err := s.getToken(gctx)
185
-		utils.LogError("token:", token)
186 185
 		if err != nil {
187 186
 			tokenStr := s.ctx.Get("token").(string)
188 187
 			if tokenStr != "" {

+ 53
- 24
service/user.go Просмотреть файл

@@ -70,7 +70,12 @@ func (s *UserServ) GetUserList(username, typeid, caseids string, page int, pageS
70 70
 // GetCurrentEnvVars 获取当前环境相关变量
71 71
 func (s *UserServ) GetCurrentEnvVars() (map[string]interface{}, error) {
72 72
 	// 当前用户信息
73
-	user := s.ctx.Get("user").(model.SysUser)
73
+	userRaw := s.ctx.Get("user")
74
+	if userRaw == nil {
75
+		return nil, utils.LogError("无有效用户信息")
76
+	}
77
+
78
+	user := userRaw.(model.SysUser)
74 79
 	user.Pwd = ""
75 80
 	// 当前用户案场
76 81
 	sessionCase := s.ctx.Get("cases").([]model.SysUserCase)
@@ -89,14 +94,13 @@ func (s *UserServ) GetCurrentEnvVars() (map[string]interface{}, error) {
89 94
 	// 当前用户角色
90 95
 	roles, err := s.dao.GetUserRole(user.UserId)
91 96
 	if err != nil {
92
-		beego.Error(err)
93
-		return nil, err
97
+		return nil, utils.LogError(err)
94 98
 	}
95 99
 	// 当前用户菜单
96 100
 	menus, err := s.dao.GetUserMenu(user.UserId)
97 101
 	if err != nil {
98 102
 		beego.Error(err)
99
-		return nil, err
103
+		return nil, utils.LogError(err)
100 104
 	}
101 105
 
102 106
 	rtn := map[string]interface{}{
@@ -117,28 +121,29 @@ func (s *UserServ) GetUserByID(userid string) (*system.UserInfo, error) {
117 121
 		beego.Error(err)
118 122
 		return nil, err
119 123
 	}
120
-	userinfo.Pwd = ""
121
-	usertype, err := s.dao.GetUserType(userid)
122
-	if err != nil {
123
-		beego.Error(err)
124
-		return nil, err
125
-	}
126
-	userinfo.UserType = usertype
124
+	if userinfo != nil {
125
+		userinfo.Pwd = ""
126
+		usertype, err := s.dao.GetUserType(userid)
127
+		if err != nil {
128
+			beego.Error(err)
129
+			return nil, err
130
+		}
131
+		userinfo.UserType = usertype
127 132
 
128
-	usertag, err := s.dao.GetUserTag(userid)
129
-	if err != nil {
130
-		beego.Error(err)
131
-		return nil, err
132
-	}
133
-	userinfo.UserTag = usertag
133
+		usertag, err := s.dao.GetUserTag(userid)
134
+		if err != nil {
135
+			beego.Error(err)
136
+			return nil, err
137
+		}
138
+		userinfo.UserTag = usertag
134 139
 
135
-	usercase, err := s.dao.GetUserCase(userid)
136
-	if err != nil {
137
-		beego.Error(err)
138
-		return nil, err
140
+		usercase, err := s.dao.GetUserCase(userid)
141
+		if err != nil {
142
+			beego.Error(err)
143
+			return nil, err
144
+		}
145
+		userinfo.UserCase = usercase
139 146
 	}
140
-	userinfo.UserCase = usercase
141
-
142 147
 	// userrole, err := s.dao.GetUserRole(userid)
143 148
 	// if err != nil {
144 149
 	// 	return nil, err
@@ -169,6 +174,22 @@ func (s *UserServ) SaveUser(user system.SysUserForm) (*model.SysUser, error) {
169 174
 	userInfo.Email = user.Email
170 175
 	userInfo.Phone = user.Phone
171 176
 	userInfo.Headimgurl = user.Headimgurl
177
+	var flag bool = true
178
+	for i := 0; i < 4; i++ {
179
+		code := s.dao.GenerateRecommendCode()
180
+		i, err := s.dao.IsCodeExist(code)
181
+		if err != nil {
182
+			return nil, errors.New("生成推荐码失败!请重新点击保存。")
183
+		}
184
+		if i <= 0 {
185
+			userInfo.RecommendCode = code
186
+			flag = false
187
+			break
188
+		}
189
+	}
190
+	if flag {
191
+		return nil, errors.New("生成推荐码失败!请重新点击保存。")
192
+	}
172 193
 
173 194
 	org := s.ctx.Get("org").(model.SysOrg)
174 195
 	user.OrgId = org.OrgId
@@ -232,6 +253,14 @@ func (s *UserServ) SaveUser(user system.SysUserForm) (*model.SysUser, error) {
232 253
 		}
233 254
 		newUSer = &userInfo
234 255
 	} else {
256
+		l, err := s.dao.IsCodeExist(userInfo.RecommendCode)
257
+		if err != nil {
258
+			beego.Error(err)
259
+			return nil, err
260
+		}
261
+		if l > 0 {
262
+			return nil, errors.New("此推荐码已被使用!")
263
+		}
235 264
 		newUSer, err = s.dao.AddUser(userInfo)
236 265
 		if err != nil {
237 266
 			beego.Error(err)
@@ -420,7 +449,7 @@ func (s *UserServ) SaveUserRole(userid, roleids string) error {
420 449
 }
421 450
 
422 451
 // GetUserCustomer 获取我的推荐客户
423
-func (s *UserServ) GetUserCustomer(userid, isrecommend, key string, page int, pageSize int) ([]model.TaCustomer, error) {
452
+func (s *UserServ) GetUserCustomer(userid, isrecommend, key string, page int, pageSize int) ([]system.CustomerInfo, error) {
424 453
 	if pageSize == 0 {
425 454
 		pageSize = PAGENUM
426 455
 	}

+ 66
- 3
service/vipcard/vipcard.go Просмотреть файл

@@ -85,6 +85,10 @@ func (s *VipcardServ) AddVipCard(vipCard model.TaVipCard) (*model.TaVipCard, err
85 85
 		vipChild.VipCardId = vipcard.VipCardId
86 86
 		vipChild.VipCardChildCode = s.dao.GenerateChildCode()
87 87
 		vipChild.Amount = vipCard.CardAmount
88
+		vipChild.BeginDate = vipCard.BeginDate
89
+		vipChild.EndDate = vipCard.EndDate
90
+		vipChild.CaseId = vipCard.CaseId
91
+		vipChild.OrgId = vipCard.OrgId
88 92
 		_, err := s.dao.AddVipChildCard(vipChild)
89 93
 		if err != nil {
90 94
 			utils.LogError("创建VIP卡失败: " + err.Error())
@@ -103,6 +107,56 @@ func (s *VipcardServ) FindCustomerByTel(tel string) (*model.TaCustomer, error) {
103 107
 	return customer, err
104 108
 }
105 109
 
110
+// SaveCustomerVip 保存用户vip
111
+func (s *VipcardServ) SaveCustomerVip(vipchild *model.TaVipCardChild, createUser model.SysUser) error {
112
+	customer, err := s.cdao.GetCustomerByPhone(vipchild.CustomerTel)
113
+	if err != nil {
114
+		utils.LogError("激活失败: " + err.Error())
115
+		return errors.New("激活失败")
116
+	}
117
+	var customerVip = model.TaCustomerVip{
118
+		CustomerId:     customer.CustomerId,
119
+		VipCardId:      vipchild.VipCardId,
120
+		VipCardChildId: vipchild.VipCardChildId,
121
+		CustomerTel:    customer.Phone,
122
+		Amount:         vipchild.Amount,
123
+		BeginDate:      vipchild.BeginDate,
124
+		EndDate:        vipchild.EndDate,
125
+		Balance:        vipchild.Amount,
126
+		CaseId:         vipchild.CaseId,
127
+		OrgId:          vipchild.OrgId,
128
+		SalesId:        vipchild.SalesId,
129
+		SalesName:      vipchild.SalesName,
130
+		PayAmount:      "0",
131
+	}
132
+	info, err := s.dao.AddCustomerVip(customerVip)
133
+	if err != nil {
134
+		utils.LogError("保存用户vip卡失败: " + err.Error())
135
+		return errors.New("激活失败")
136
+	}
137
+	// vip卡明细操作
138
+	var change = model.TaCustomerVipChange{
139
+		CustomerVipId: info.CustomerVipId,
140
+		CustomerId:    info.CustomerId,
141
+		OrgId:         info.OrgId,
142
+		CaseId:        info.CaseId,
143
+		ChangeType:    models.CONSUME_COINCHG,
144
+		ChangeSource:  models.ACCSOURCE_RECHARGE,
145
+		SourceId:      vipchild.VipCardChildId,
146
+		SourceName:    "充值",
147
+		Amount:        info.Amount,
148
+		FloatType:     models.ACCOUNT_INCOME,
149
+		CreateUser:    createUser.UserId,
150
+	}
151
+	err = s.dao.InsertCustomerVipChange(change)
152
+	if err != nil {
153
+		utils.LogError("保存用户vip卡明细信息失败: " + err.Error())
154
+		return errors.New("激活失败")
155
+	}
156
+
157
+	return err
158
+}
159
+
106 160
 // CustomerCharge 给用户充值
107 161
 func (s *VipcardServ) CustomerCharge(vipchild *model.TaVipCardChild, createUser model.SysUser) error {
108 162
 	customer, err := s.cdao.GetCustomerByPhone(vipchild.CustomerTel)
@@ -141,17 +195,26 @@ func (s *VipcardServ) CustomerCharge(vipchild *model.TaVipCardChild, createUser
141 195
 	return nil
142 196
 }
143 197
 
144
-
145 198
 // GetVipChildExcel 获取VIP卡列表
146 199
 func (s *VipcardServ) GetVipChildExcel(caseids, cardNo, sellerName, userName string) ([]vipcard.VipChild, error) {
147
-	
200
+
148 201
 	vipchild, err := s.dao.GetVipCardListExcel(caseids, cardNo, sellerName, userName)
149 202
 	if err != nil {
150 203
 		utils.LogError("获取VIP卡信息失败: " + err.Error())
151 204
 		return nil, errors.New("获取VIP卡信息失败")
152 205
 	}
153
-	
206
+
154 207
 	return vipchild, err
155 208
 }
156 209
 
210
+// GetCustomerVips 获取用户vip卡信息
211
+func (s *VipcardServ) GetCustomerVips() ([]vipcard.CustomerVipWithChange, error) {
212
+	customer := s.ctx.Get("customer").(model.TaCustomer)
213
+	vips, err := s.dao.GetCustomerVips(customer.CustomerId)
214
+	if err != nil {
215
+		utils.LogError("获取VIP卡信息失败: " + err.Error())
216
+		return nil, errors.New("获取VIP卡信息失败")
217
+	}
157 218
 
219
+	return vips, err
220
+}

+ 46
- 0
tests/cases_test.go Просмотреть файл

@@ -0,0 +1,46 @@
1
+package tests
2
+
3
+import (
4
+	"net/http"
5
+	"net/url"
6
+	"spaceofcheng/services/controllers"
7
+	"testing"
8
+
9
+	. "github.com/smartystreets/goconvey/convey"
10
+)
11
+
12
+func TestGetCmsCaseList(t *testing.T) {
13
+
14
+	Convey("获取案场列表", t, func() {
15
+		Convey("正常业务", func() {
16
+			params := url.Values{}
17
+			params.Add("orgid", "1")
18
+
19
+			result := &controllers.JSONMessage{}
20
+
21
+			code, _, err := NewRequestMock().Request(http.MethodGet, "/api/guest/MQ/cms/case", params, result)
22
+
23
+			// http 常规判断, 可以省略
24
+			So(code, ShouldEqual, http.StatusOK)
25
+			So(err, ShouldBeNil)
26
+
27
+			// 业务返回判断
28
+			So(result.Code, ShouldEqual, http.StatusOK)
29
+			So(result.Result, ShouldNotBeEmpty)
30
+		})
31
+
32
+		Convey("机构不传报错", func() {
33
+			result := &controllers.JSONMessage{}
34
+
35
+			code, _, err := NewRequestMock().Request(http.MethodGet, "/api/guest/MQ/cms/case", nil, result)
36
+
37
+			// http 常规判断, 可以省略
38
+			So(code, ShouldEqual, http.StatusOK)
39
+			So(err, ShouldBeNil)
40
+
41
+			// 业务返回判断
42
+			So(result.Code, ShouldNotEqual, http.StatusOK)
43
+		})
44
+
45
+	})
46
+}

+ 74
- 0
tests/courseorder_test.go Просмотреть файл

@@ -0,0 +1,74 @@
1
+package tests
2
+
3
+import (
4
+	"net/http"
5
+	"net/url"
6
+	"spaceofcheng/services/controllers"
7
+	"spaceofcheng/services/utils"
8
+	"testing"
9
+	"time"
10
+
11
+	"github.com/astaxie/beego"
12
+
13
+	. "github.com/smartystreets/goconvey/convey"
14
+)
15
+
16
+func TestPreCourseOrder(t *testing.T) {
17
+	Convey("课程下单", t, func() {
18
+
19
+		Convey("正常下单", func() {
20
+			params := url.Values{}
21
+			params.Add("info", `{"CourseId":"ecc55f91-52b4-4e9b-89a8-b9b3362730f9","CaseId":"10","Price":"2.00"}`)
22
+			result := &controllers.JSONMessage{}
23
+			api := "/api/wechat/MQ/order/course"
24
+
25
+			token := &utils.JWTToken{
26
+				Guest:   false,
27
+				ID:      "oMOpz0kgTrasoAA3G70R7phomn1g", // openid
28
+				Expire:  time.Now().Local().Add(24 * 30 * time.Hour),
29
+				BatchNo: "",
30
+			}
31
+
32
+			code, _, err := NewRequestMock().
33
+				AddToken(token.ToMap()).
34
+				AddWechatUA().
35
+				Request(http.MethodPost, api, params, result)
36
+
37
+			beego.Trace(result)
38
+
39
+			So(code, ShouldEqual, http.StatusOK)
40
+			So(err, ShouldBeNil)
41
+
42
+			// 业务返回判断
43
+			So(result.Code, ShouldEqual, http.StatusOK)
44
+			So(result.Result, ShouldNotBeEmpty)
45
+
46
+			orderID := result.Result.(map[string]interface{})["OrdersId"].(string)
47
+
48
+			Convey("下单确认", func() {
49
+				result := &controllers.JSONMessage{}
50
+				api := "/api/wechat/MQ/order/course/" + orderID
51
+
52
+				token := &utils.JWTToken{
53
+					Guest:   false,
54
+					ID:      "oMOpz0kgTrasoAA3G70R7phomn1g", // openid
55
+					Expire:  time.Now().Local().Add(24 * 30 * time.Hour),
56
+					BatchNo: "",
57
+				}
58
+
59
+				code, _, err := NewRequestMock().
60
+					AddToken(token.ToMap()).
61
+					AddWechatUA().
62
+					Request(http.MethodPut, api, nil, result)
63
+
64
+				beego.Trace(result)
65
+
66
+				So(code, ShouldEqual, http.StatusOK)
67
+				So(err, ShouldBeNil)
68
+
69
+				// 业务返回判断
70
+				So(result.Code, ShouldEqual, http.StatusOK)
71
+			})
72
+		})
73
+	})
74
+}

+ 70
- 0
tests/goodsorder_test.go Просмотреть файл

@@ -0,0 +1,70 @@
1
+package tests
2
+
3
+import (
4
+	"net/http"
5
+	"net/url"
6
+	"spaceofcheng/services/controllers"
7
+	"spaceofcheng/services/utils"
8
+	"testing"
9
+	"time"
10
+
11
+	. "github.com/smartystreets/goconvey/convey"
12
+)
13
+
14
+func TestPreGoodsOrder(t *testing.T) {
15
+	Convey("商品下单", t, func() {
16
+
17
+		Convey("正常下单", func() {
18
+			params := url.Values{}
19
+			params.Add("info", `{"CaseId":"1","AreaId":"12","AreaName":"吧台","TableId":"28","TableNo":"城咖啡水吧台","Amount":"23","OrdersNum":1,"Remark":"","OrgId":"1","UserName":"奥利奥","PayType":"coupon"}`)
20
+			params.Add("detail", `[{"GoodsId":"61","GoodsName":"美式","SpecId":"40","SpecName":"去冰","Number":1,"Price":"23"}]`)
21
+
22
+			result := &controllers.JSONMessage{}
23
+			api := "/api/wechat/MQ/order/goods"
24
+
25
+			token := &utils.JWTToken{
26
+				Guest:   false,
27
+				ID:      "oMOpz0kgTrasoAA3G70R7phomn1g", // openid
28
+				Expire:  time.Now().Local().Add(24 * 30 * time.Hour),
29
+				BatchNo: "",
30
+			}
31
+
32
+			code, _, err := NewRequestMock().
33
+				AddToken(token.ToMap()).
34
+				AddWechatUA().
35
+				Request(http.MethodPost, api, params, result)
36
+
37
+			So(code, ShouldEqual, http.StatusOK)
38
+			So(err, ShouldBeNil)
39
+
40
+			// 业务返回判断
41
+			So(result.Code, ShouldEqual, http.StatusOK)
42
+			So(result.Result, ShouldNotBeEmpty)
43
+
44
+			orderID := result.Result.(map[string]interface{})["OrdersId"].(string)
45
+
46
+			Convey("下单确认", func() {
47
+				result := &controllers.JSONMessage{}
48
+				api := "/api/wechat/MQ/order/goods/" + orderID
49
+
50
+				token := &utils.JWTToken{
51
+					Guest:   false,
52
+					ID:      "oMOpz0kgTrasoAA3G70R7phomn1g", // openid
53
+					Expire:  time.Now().Local().Add(24 * 30 * time.Hour),
54
+					BatchNo: "",
55
+				}
56
+
57
+				code, _, err := NewRequestMock().
58
+					AddToken(token.ToMap()).
59
+					AddWechatUA().
60
+					Request(http.MethodPut, api, nil, result)
61
+
62
+				So(code, ShouldEqual, http.StatusOK)
63
+				So(err, ShouldBeNil)
64
+
65
+				// 业务返回判断
66
+				So(result.Code, ShouldEqual, http.StatusOK)
67
+			})
68
+		})
69
+	})
70
+}

+ 27
- 0
tests/tests.go Просмотреть файл

@@ -0,0 +1,27 @@
1
+package tests
2
+
3
+/**
4
+*
5
+* 使用的测试框架为  http://labix.org/gocheck
6
+*
7
+**/
8
+
9
+import (
10
+	"spaceofcheng/services/bootstrap"
11
+	"spaceofcheng/services/utils"
12
+	"testing"
13
+
14
+	"github.com/astaxie/beego"
15
+	. "github.com/smartystreets/goconvey/convey"
16
+)
17
+
18
+func TestHelloWorld(t *testing.T) {
19
+	Convey("Hello go tester !", t, func() {
20
+		So(2, ShouldEqual, 2)
21
+	})
22
+}
23
+
24
+func init() {
25
+	bootstrap.SystemInit()
26
+	beego.TestBeegoInit(utils.GetAppRoot())
27
+}

+ 231
- 0
tests/utils.go Просмотреть файл

@@ -0,0 +1,231 @@
1
+package tests
2
+
3
+import (
4
+	"bytes"
5
+	"encoding/json"
6
+	"errors"
7
+	"fmt"
8
+	"io"
9
+	"io/ioutil"
10
+	"mime/multipart"
11
+	"net/http"
12
+	"net/http/httptest"
13
+	"net/url"
14
+	"os"
15
+	"spaceofcheng/services/utils"
16
+	"strconv"
17
+	"strings"
18
+	"time"
19
+
20
+	"github.com/astaxie/beego"
21
+)
22
+
23
+// RequestMock 模拟请求
24
+type RequestMock struct {
25
+	Headers map[string]string
26
+	Host    string
27
+}
28
+
29
+// NewRequestMock new inst
30
+func NewRequestMock() *RequestMock {
31
+	return &RequestMock{
32
+		Headers: make(map[string]string),
33
+	}
34
+}
35
+
36
+// SetHeaders 设置自定义请求头
37
+func (t *RequestMock) SetHeaders(headers map[string]string) *RequestMock {
38
+	if headers != nil {
39
+		for k, v := range headers {
40
+			t.Headers[k] = v
41
+		}
42
+	}
43
+
44
+	return t
45
+}
46
+
47
+// AddWechatUA 添加微信UA
48
+func (t *RequestMock) AddWechatUA() *RequestMock {
49
+	t.Headers["User-Agent"] = "Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12A365 MicroMessenger/5.4.1 NetType/WIFI"
50
+	return t
51
+}
52
+
53
+// AddToken 添加Token
54
+func (t *RequestMock) AddToken(dt map[string]interface{}) *RequestMock {
55
+	token, _ := utils.CreateToken(dt)
56
+	t.Headers[utils.TokenHeader] = utils.TokenSchema + " " + token
57
+	return t
58
+}
59
+
60
+// SetHost 设置 host 包含 port
61
+func (t *RequestMock) SetHost(host string) *RequestMock {
62
+	t.Host = host
63
+	return t
64
+}
65
+
66
+// Request 请求
67
+// 暂时只支持 params 是 url.Values 及 map[string]interface{} 两种类型
68
+// url.Values 将被理解为 content-type="application/x-www-form-urlencoded"
69
+// map[string]interface{} 将被理解为 content-type="multipart/form-data"
70
+func (t *RequestMock) Request(meth, addr string, params interface{}, result interface{}) (code int, body []byte, err error) {
71
+	var r *http.Request
72
+	defer t.SetHeaders(nil)
73
+
74
+	code = 0
75
+	body = nil
76
+	err = nil
77
+
78
+	if t.Host != "" {
79
+		addr = t.Host + addr
80
+	} else {
81
+		addr = "http://127.0.0.1:8080" + addr
82
+	}
83
+
84
+	switch meth {
85
+
86
+	// get 请求, 只支持 params 为 url.Values 的参数
87
+	case http.MethodGet:
88
+		if params != nil {
89
+			if dt, ok := params.(url.Values); ok {
90
+				searchStr := dt.Encode()
91
+				if strings.Index(addr, "?") > -1 {
92
+					searchStr = "&" + searchStr
93
+				} else {
94
+					searchStr = "?" + searchStr
95
+				}
96
+				r, _ = http.NewRequest(meth, addr+searchStr, nil)
97
+			}
98
+		} else {
99
+			r, _ = http.NewRequest(meth, addr, nil)
100
+		}
101
+
102
+	// post, put, delete
103
+	case http.MethodPost, http.MethodPut, http.MethodDelete:
104
+		rb, ct, e := GetBody(params)
105
+		if e != nil {
106
+			err = e
107
+			return
108
+		}
109
+
110
+		r, _ = http.NewRequest(meth, addr, rb)
111
+		if ct != "" {
112
+			r.Header.Set("Content-Type", ct)
113
+		}
114
+
115
+	// 其他的本系统没有使用
116
+	default:
117
+		err = errors.New("不支持的请求类型")
118
+		return
119
+	}
120
+
121
+	// 自定义的 header 头
122
+	if t.Headers != nil {
123
+		for k, v := range t.Headers {
124
+			r.Header.Set(k, v)
125
+		}
126
+	}
127
+
128
+	w := httptest.NewRecorder()
129
+	beego.BeeApp.Handlers.ServeHTTP(w, r)
130
+
131
+	code = w.Code
132
+	body, _ = ioutil.ReadAll(w.Result().Body)
133
+
134
+	beego.Trace("testing", meth+" - "+addr)
135
+
136
+	if result != nil {
137
+		err = json.Unmarshal(body, result)
138
+		return
139
+	}
140
+
141
+	return
142
+}
143
+
144
+func GetBody(params interface{}) (body io.Reader, contentType string, err error) {
145
+	body = nil
146
+	contentType = ""
147
+	err = nil
148
+
149
+	if params == nil {
150
+		return
151
+	}
152
+
153
+	t := fmt.Sprintf("%T", params)
154
+	switch t {
155
+
156
+	// 被会解析为 application/x-www-form-urlencoded
157
+	case "url.Values":
158
+		data, _ := params.(url.Values)
159
+		body = strings.NewReader(data.Encode())
160
+		contentType = "application/x-www-form-urlencoded"
161
+		return
162
+
163
+	// 被会解析为 multipart/form-data
164
+	case "map[string]interface {}":
165
+		var b bytes.Buffer
166
+		var fw io.Writer
167
+
168
+		w := multipart.NewWriter(&b)
169
+		data, _ := params.(map[string]interface{})
170
+
171
+		// 遍历字段
172
+		for k, v := range data {
173
+			switch x := v.(type) {
174
+
175
+			// 文件
176
+			case *os.File:
177
+				if fw, err = w.CreateFormFile(k, x.Name()); err != nil {
178
+					return
179
+				}
180
+
181
+				if _, err = io.Copy(fw, x); err != nil {
182
+					return
183
+				}
184
+
185
+			// 字符串
186
+			case string:
187
+				err = w.WriteField(k, x)
188
+				if err != nil {
189
+					return
190
+				}
191
+
192
+			// 整数, 暂不支持 int 各种原始类型, 比如 int32, int64 等
193
+			case int:
194
+				dt := strconv.Itoa(x)
195
+				err = w.WriteField(k, dt)
196
+				if err != nil {
197
+					return
198
+				}
199
+
200
+			// 小数, 暂时不支持其他类型的浮点数
201
+			case float64:
202
+				dt := strconv.FormatFloat(x, 'f', -1, 64)
203
+				err = w.WriteField(k, dt)
204
+				if err != nil {
205
+					return
206
+				}
207
+
208
+			// 时间
209
+			case time.Time:
210
+				dt := x.Format("2006-01-02 15:04:05")
211
+				err = w.WriteField(k, dt)
212
+				if err != nil {
213
+					return
214
+				}
215
+
216
+			// 其他
217
+			default:
218
+				err = fmt.Errorf("暂时不支持 key "+k+" 对应的数据类型 %T", x)
219
+				return
220
+			}
221
+		}
222
+
223
+		body = bytes.NewReader(b.Bytes())
224
+		contentType = w.FormDataContentType()
225
+		return
226
+
227
+	default:
228
+		err = fmt.Errorf("暂时不支持的参数类型 " + t)
229
+		return
230
+	}
231
+}

+ 1
- 5
utils/captcha.go Просмотреть файл

@@ -19,7 +19,7 @@ type CaptchaEngine struct {
19 19
 	capList map[string]cap
20 20
 }
21 21
 
22
-var capEngine *CaptchaEngine
22
+var capEngine = NewCaptchaEngine()
23 23
 
24 24
 // NewCaptchaEngine 创建验证码引擎
25 25
 func NewCaptchaEngine() *CaptchaEngine {
@@ -108,7 +108,3 @@ func (c *CaptchaEngine) DestoryCaptcha(phone string) {
108 108
 	// 如果成功, 则注销
109 109
 	delete(c.capList, phone)
110 110
 }
111
-
112
-func init() {
113
-	capEngine = NewCaptchaEngine()
114
-}

+ 15
- 0
utils/configer.go Просмотреть файл

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

+ 4
- 8
utils/log.go Просмотреть файл

@@ -9,8 +9,7 @@ import (
9 9
 	"github.com/astaxie/beego/logs"
10 10
 )
11 11
 
12
-var defaultLogger *logs.BeeLogger
13
-var instances map[string]*logs.BeeLogger
12
+var instances = make(map[string]*logs.BeeLogger)
14 13
 
15 14
 // NewLog 构造日志对象
16 15
 func NewLog(tp ...string) *logs.BeeLogger {
@@ -29,7 +28,7 @@ func NewLog(tp ...string) *logs.BeeLogger {
29 28
 	instances[logType] = log
30 29
 
31 30
 	// 读取配置文件
32
-	conf, err := config.NewConfig("ini", "./conf/log.conf")
31
+	conf, err := config.NewConfig("ini", GetAppRoot()+"/conf/log.conf")
33 32
 	if err != nil {
34 33
 		log.SetLogger(logs.AdapterConsole)
35 34
 		return log
@@ -91,7 +90,7 @@ func LogInfo(v ...interface{}) {
91 90
 		preMsg = fmt.Sprintf("file: %s    line=%d : ", file, line)
92 91
 	}
93 92
 
94
-	log.Error(preMsg, v...)
93
+	log.Info(preMsg, v...)
95 94
 }
96 95
 
97 96
 // GetDefaultLogger 获取默认 logger
@@ -101,9 +100,6 @@ func GetDefaultLogger() *logs.BeeLogger {
101 100
 	return log
102 101
 }
103 102
 
104
-func init() {
105
-	instances = make(map[string]*logs.BeeLogger)
103
+func LogInit() {
106 104
 	NewLog()
107
-
108
-	defaultLogger = GetDefaultLogger()
109 105
 }

+ 24
- 3
utils/message.go Просмотреть файл

@@ -2,6 +2,7 @@ package utils
2 2
 
3 3
 import (
4 4
 	"github.com/zjxpcyc/websocket"
5
+	"github.com/zjxpcyc/wechat/wx"
5 6
 )
6 7
 
7 8
 // ClientID 消息对象
@@ -29,22 +30,42 @@ func SendWs(message Message) {
29 30
 		Data: message.Data,
30 31
 	}
31 32
 
32
-	LogError("发送 Websocket 消息: ", msg)
33
-
34 33
 	websocket.Send(msg)
35 34
 }
36 35
 
36
+func SendWechat(message Message) {
37
+	dt := message.Data.(map[string]interface{})
38
+	org := dt["orgid"].(string)
39
+	tplID := dt["tplid"].(string)
40
+	tplLink := dt["link"].(string)
41
+	tplData := dt["data"].(map[string]string)
42
+
43
+	var data map[string]wx.TplMessageData
44
+	if tplData != nil {
45
+		data = make(map[string]wx.TplMessageData)
46
+		for k, v := range tplData {
47
+			data[k] = wx.TplMessageData{Value: v}
48
+		}
49
+	}
50
+
51
+	err := WxClientFor(org).SendTplMessage(message.To.ID, tplID, tplLink, data)
52
+	if err != nil {
53
+		LogError("推送微信消息失败: ", err)
54
+	}
55
+}
56
+
37 57
 // SendMessage 发送消息
38 58
 func SendMessage(message Message, msgType string) {
39 59
 	switch msgType {
40 60
 	case WsMessage:
41 61
 		SendWs(message)
42 62
 	case WechatMessage:
63
+
43 64
 	case SMSMessage:
44 65
 	default:
45 66
 	}
46 67
 }
47 68
 
48
-func init() {
69
+func MessageInit() {
49 70
 	go websocket.Run()
50 71
 }

+ 13
- 0
utils/rand.go Просмотреть файл

@@ -3,6 +3,8 @@ package utils
3 3
 import (
4 4
 	"math/rand"
5 5
 	"reflect"
6
+	"strconv"
7
+	"strings"
6 8
 	"time"
7 9
 )
8 10
 
@@ -30,6 +32,17 @@ func Shuffle(arr interface{}) interface{} {
30 32
 	return res.Interface()
31 33
 }
32 34
 
35
+// GetRand 获取随机数
36
+func GetRand(len int) string {
37
+	newSeed()
38
+	var r []string
39
+	for i := 0; i < len; i++ {
40
+		m := rnd.Intn(9)
41
+		r = append(r, strconv.Itoa(m))
42
+	}
43
+	return strings.Join(r, "")
44
+}
45
+
33 46
 // LuckyDraw 抽奖
34 47
 func LuckyDraw(pList []map[string]interface{}) interface{} {
35 48
 	// 奖池

+ 63
- 0
utils/rand_test.go Просмотреть файл

@@ -0,0 +1,63 @@
1
+package utils_test
2
+
3
+import (
4
+	"spaceofcheng/services/utils"
5
+	"testing"
6
+)
7
+
8
+func TestGetRand(t *testing.T) {
9
+	res1 := utils.GetRand(6)
10
+	res2 := utils.GetRand(6)
11
+
12
+	if res1 == res2 {
13
+		t.Fatalf("TestGetRand error, %s, %s", res1, res2)
14
+	}
15
+}
16
+
17
+func TestLuckyDraw(t *testing.T) {
18
+	prizeList := []map[string]interface{}{
19
+		map[string]interface{}{
20
+			"prize": "A",
21
+			"prob":  20,
22
+		},
23
+		map[string]interface{}{
24
+			"prize": "B",
25
+			"prob":  20,
26
+		},
27
+		map[string]interface{}{
28
+			"prize": "C",
29
+			"prob":  30,
30
+		},
31
+		map[string]interface{}{
32
+			"prize": "D",
33
+			"prob":  30,
34
+		},
35
+	}
36
+
37
+	theA := 0
38
+	theB := 0
39
+	theC := 0
40
+	theD := 0
41
+
42
+	for i := 0; i < 10000; i++ {
43
+		res := utils.LuckyDraw(prizeList).(string)
44
+
45
+		switch res {
46
+		case "A":
47
+			theA += 1
48
+		case "B":
49
+			theB += 1
50
+		case "C":
51
+			theC += 1
52
+		case "D":
53
+			theD += 1
54
+		default:
55
+		}
56
+
57
+		// bingoList = append(bingoList, utils.LuckyDraw(prizeList))
58
+	}
59
+
60
+	resStr := `A ==> %d  B ==> %d C ==> %d D ==> %d`
61
+
62
+	t.Fatalf(resStr, theA, theB, theC, theD)
63
+}

+ 1
- 5
utils/sms.go Просмотреть файл

@@ -19,7 +19,7 @@ type SMSEngine struct {
19 19
 }
20 20
 
21 21
 var defaultSMS *SMSEngine
22
-var mtx *sync.Mutex
22
+var mtx = new(sync.Mutex)
23 23
 
24 24
 // ResetSMSEngine 重置引擎
25 25
 func ResetSMSEngine(conf config.Configer) {
@@ -71,7 +71,3 @@ func SendSMS(smsType, tel string, messages ...string) {
71 71
 
72 72
 	}()
73 73
 }
74
-
75
-func init() {
76
-	mtx = new(sync.Mutex)
77
-}

+ 36
- 0
utils/utils.go Просмотреть файл

@@ -4,6 +4,9 @@ import (
4 4
 	"encoding/base64"
5 5
 	"math/rand"
6 6
 	"net/http"
7
+	"os"
8
+	"path/filepath"
9
+	"runtime"
7 10
 	"strconv"
8 11
 	"strings"
9 12
 	"time"
@@ -156,3 +159,36 @@ func GetFiveSeconds(t time.Time) string {
156 159
 
157 160
 	return str[:strLen-1] + strconv.Itoa(lastNum)
158 161
 }
162
+
163
+// 当前运行环境
164
+var processEnv string
165
+var appRoot string
166
+
167
+// GetAppRoot 获取系统根目录
168
+func GetAppRoot() string {
169
+	if appRoot != "" {
170
+		return appRoot
171
+	}
172
+
173
+	if processEnv == "" {
174
+		for _, arg := range os.Args {
175
+			if strings.Index(arg, "-test.run") > -1 {
176
+				processEnv = "test"
177
+				break
178
+			}
179
+		}
180
+
181
+		if processEnv == "" {
182
+			processEnv = "production"
183
+		}
184
+	}
185
+
186
+	if processEnv == "test" {
187
+		_, file, _, _ := runtime.Caller(1)
188
+		appRoot, _ = filepath.Abs(filepath.Dir(filepath.Join(file, ".."+string(filepath.Separator))))
189
+	} else {
190
+		appRoot, _ = filepath.Abs(filepath.Dir(os.Args[0]))
191
+	}
192
+
193
+	return appRoot
194
+}

+ 0
- 0
utils/wechat.go Просмотреть файл


Некоторые файлы не были показаны из-за большого количества измененных файлов