You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

391 lines
11 KiB

  1. package couponusers
  2. import (
  3. "CouponBackendGo/api/v1/couponusers"
  4. "CouponBackendGo/internal/dao"
  5. "CouponBackendGo/internal/service"
  6. "context"
  7. "database/sql"
  8. "errors"
  9. "github.com/gogf/gf/v2/frame/g"
  10. "github.com/gogf/gf/v2/os/gtime"
  11. "github.com/xuri/excelize/v2"
  12. "mime/multipart"
  13. "strconv"
  14. "strings"
  15. )
  16. type sCouponUsers struct{}
  17. func init() {
  18. service.RegisterCouponUsers(&sCouponUsers{})
  19. }
  20. // 根据优惠券id查看拥有优惠券的用户
  21. func (s *sCouponUsers) GetCouponUsersByCondition(ctx context.Context, couponId, jwcode int, name string, pageNo, pageSize int) (users []couponusers.GetCouponUsersRes, err error) {
  22. //没有条件查询时,分页
  23. if jwcode == 0 && name == "" {
  24. /*查询所有数据*/
  25. //在coupon_users中查询出对应的jwcode
  26. err = dao.CouponUsers.Ctx(ctx).Fields("jwcode").
  27. Where("coupon_id = ", couponId).Page(pageNo, pageSize).Scan(&users)
  28. if err != nil {
  29. return nil, errors.New("根据卡券id搜索jwcode失败")
  30. }
  31. //根据jwcode查询用户信息
  32. for i, userInfo := range users {
  33. err = dao.MemberInfo.Ctx(ctx).Fields("jwcode", "name", "deptName", "shopName").
  34. Where("jwcode = ?", userInfo.Jwcode).Scan(&users[i])
  35. if err != nil {
  36. return nil, errors.New("根据jwcode搜索用户信息失败")
  37. }
  38. }
  39. /*查询所有数据*/
  40. return users, err
  41. } else { //有条件查询时,不在分页,全查后筛选
  42. /*查询所有数据*/
  43. //在coupon_users中查询出对应的jwcode
  44. err = dao.CouponUsers.Ctx(ctx).Fields("jwcode").
  45. Where("coupon_id = ", couponId).Scan(&users)
  46. if err != nil {
  47. return nil, errors.New("根据卡券id搜索jwcode失败")
  48. }
  49. //根据jwcode查询用户信息
  50. for i, userInfo := range users {
  51. err = dao.MemberInfo.Ctx(ctx).Fields("jwcode", "name", "deptName", "shopName").
  52. Where("jwcode = ?", userInfo.Jwcode).Scan(&users[i])
  53. if err != nil {
  54. return nil, errors.New("根据jwcode搜索用户信息失败")
  55. }
  56. }
  57. /*查询所有数据*/
  58. //条件查询
  59. if jwcode != 0 && name == "" {
  60. var result []couponusers.GetCouponUsersRes
  61. for _, user := range users {
  62. if user.Jwcode == jwcode {
  63. result = append(result, user)
  64. }
  65. }
  66. return result, err
  67. } else if jwcode == 0 && name != "" {
  68. var result []couponusers.GetCouponUsersRes
  69. for _, user := range users {
  70. if strings.Contains(user.Name, name) {
  71. result = append(result, user)
  72. }
  73. }
  74. return result, err
  75. } else if jwcode != 0 && name != "" {
  76. var result []couponusers.GetCouponUsersRes
  77. for _, user := range users {
  78. if user.Jwcode == jwcode && strings.Contains(user.Name, name) {
  79. result = append(result, user)
  80. }
  81. }
  82. return result, err
  83. }
  84. return users, err
  85. }
  86. }
  87. // 根据jwcode,优惠券id删除用户
  88. func (s *sCouponUsers) DeleteCouponUserByJwcode(ctx context.Context, couponId, jwcode int) (result sql.Result, err error) {
  89. if jwcode == 0 {
  90. return nil, errors.New("jwcode不能为空")
  91. }
  92. if couponId == 0 {
  93. return nil, errors.New("couponId不能为空")
  94. }
  95. result, err = dao.CouponUsers.Ctx(ctx).Where("coupon_id = ?", couponId).Where("jwcode = ?", jwcode).Delete()
  96. if err != nil {
  97. return nil, errors.New("删除用户失败")
  98. }
  99. return result, err
  100. }
  101. // 通过excel导入精网号
  102. func (s *sCouponUsers) InsertJwcodeByExcel(ctx context.Context, file multipart.File, couponId int) (num int, err error) {
  103. // func (s *sCouponUsers) InsertJwcodeByExcel(file multipart.File) (jwcodes []int, err error) {
  104. //打开文件并返回一个excelize.File对象,用于读取和操作Excel文件的内容
  105. f, err := excelize.OpenReader(file)
  106. if err != nil {
  107. return 0, errors.New("打开文件失败")
  108. }
  109. // 延时关闭文件
  110. defer func(f *excelize.File) {
  111. err := f.Close()
  112. if err != nil {
  113. return // 返回错误
  114. }
  115. }(f)
  116. //读取所有工作表名称
  117. GetSheetMap := f.GetSheetMap()
  118. if len(GetSheetMap) == 0 {
  119. return 0, errors.New("没有工作表")
  120. }
  121. rows, err := f.GetRows("Sheet1")
  122. if err != nil {
  123. return 0, err
  124. }
  125. // 将每行的第一列转换为int,并添加到切片中
  126. var jwcodes []int
  127. for i, row := range rows {
  128. //跳过第一行
  129. if i == 0 {
  130. continue
  131. }
  132. // 假设jwcode在每行的第一列
  133. /*参数校验*/
  134. //参数校验,检查每行是否有足够数据
  135. if len(row) == 0 {
  136. continue // 跳过空行
  137. }
  138. //参数校验,检查jwcode是否为非空字符串
  139. jwcodeStr := row[0]
  140. if jwcodeStr == "" {
  141. continue // 跳过空行
  142. }
  143. //将字符串转换为整数
  144. jwcode, err := strconv.Atoi(jwcodeStr)
  145. if err != nil {
  146. return 0, errors.New("参数转换失败")
  147. }
  148. jwcodes = append(jwcodes, jwcode)
  149. /*参数校验*/
  150. }
  151. /*给用户发放卡券*/
  152. num, err = s.InsertCouponUsersByJwcodes(ctx, jwcodes, couponId)
  153. /*给用户发放卡券*/
  154. //return //返回jwcodes切片
  155. return num, err
  156. }
  157. // 传来jwcodes字符串,解析并发放卡券
  158. func (s *sCouponUsers) InsertCouponUsersByJwcodeStr(ctx context.Context, jwcodeStr string, couponId int) (num int, err error) {
  159. //将字符串转换为切片
  160. jwcodes := strings.Split(jwcodeStr, ",")
  161. //转换成int
  162. var jwcodesInt []int
  163. for _, jwcode := range jwcodes {
  164. //参数校验,检查jwcode是否为非空字符串
  165. if jwcode == "" {
  166. continue
  167. }
  168. jwcodeInt, err := strconv.Atoi(jwcode)
  169. if err != nil {
  170. return 0, errors.New("参数转换失败")
  171. }
  172. jwcodesInt = append(jwcodesInt, jwcodeInt)
  173. }
  174. /*给用户发放卡券*/
  175. num, err = s.InsertCouponUsersByJwcodes(ctx, jwcodesInt, couponId)
  176. /*给用户发放卡券*/
  177. return
  178. }
  179. // 根据精网号发放用户优惠券,群发 //不被controller层调用了,但不能删除
  180. func (s *sCouponUsers) InsertCouponUsersByJwcodes(ctx context.Context, jwcodes []int, couponId int) (num int, err error) {
  181. //去重
  182. m := make(map[int]bool)
  183. var uniqueJwcodes []int //存放去重后的精网号
  184. for _, jwcode := range jwcodes {
  185. if _, exist := m[jwcode]; !exist {
  186. m[jwcode] = true
  187. uniqueJwcodes = append(uniqueJwcodes, jwcode)
  188. }
  189. }
  190. //插入数据
  191. for _, jwcode := range uniqueJwcodes {
  192. //检查数据库中是否存在
  193. count, err := dao.CouponUsers.Ctx(ctx).Where("jwcode = ?", jwcode).Where("coupon_id = ?", couponId).Count()
  194. if err != nil {
  195. return num, errors.New("检索数据库中是否已存在数据失败")
  196. }
  197. //不存在,可以插入
  198. if count == 0 {
  199. result, err := dao.CouponUsers.Ctx(ctx).Insert(g.Map{
  200. "jwcode": jwcode,
  201. "coupon_id": couponId,
  202. "time": gtime.Now().Unix(),
  203. })
  204. if err != nil {
  205. return num, errors.New("插入数据库失败")
  206. }
  207. //获取受影响的行数
  208. affected, err := result.RowsAffected()
  209. num += int(affected)
  210. }
  211. }
  212. return num, err //返回受影响的行数,即新增的条数
  213. }
  214. // 导入满足条件的用户jwcode到redis //不上传到redis了,上传到数据库表,到时候直接从表里查
  215. func (s *sCouponUsers) InsertJwcodesToRedisByExcel(file multipart.File) (err error) {
  216. var ctx g.Ctx
  217. //打开文件并返回一个excelize.File对象,用于读取和操作Excel文件的内容
  218. f, err := excelize.OpenReader(file)
  219. if err != nil {
  220. return errors.New("打开文件失败")
  221. }
  222. // 延时关闭文件
  223. defer func(f *excelize.File) {
  224. err := f.Close()
  225. if err != nil {
  226. // 处理关闭文件时的错误
  227. return
  228. }
  229. }(f)
  230. //读取所有工作表名称
  231. GetSheetMap := f.GetSheetMap()
  232. if len(GetSheetMap) == 0 {
  233. return errors.New("没有工作表")
  234. }
  235. // 读取第一个工作表
  236. rows, err := f.GetRows("Sheet1")
  237. if err != nil {
  238. return err
  239. }
  240. // 将每行的第一列转换为int,并添加到切片中
  241. //var jwcodes []int
  242. for i, row := range rows {
  243. //跳过第一行
  244. if i == 0 {
  245. continue
  246. }
  247. // 假设jwcode在每行的第一列
  248. /*参数校验*/
  249. //参数校验,检查每行是否有足够数据
  250. if len(row) == 0 {
  251. continue // 跳过空行
  252. }
  253. //参数校验,检查jwcode是否为非空字符串
  254. jwcodeStr := row[0]
  255. if jwcodeStr == "" {
  256. continue // 跳过空行
  257. }
  258. //将字符串转换为整数
  259. jwcode, err := strconv.Atoi(jwcodeStr)
  260. if err != nil {
  261. return errors.New("参数转换失败")
  262. }
  263. // 判断jwcode是否在表coupon_qualified_users中
  264. count, err := dao.CouponQualifiedUsers.Ctx(ctx).Where("jwcode = ?", jwcode).Count()
  265. if err != nil {
  266. return errors.New("检索数据库中是否已存在数据失败")
  267. }
  268. if count == 0 { //不存在,插入
  269. _, err = dao.CouponQualifiedUsers.Ctx(ctx).Insert(g.Map{
  270. "jwcode": jwcode,
  271. })
  272. }
  273. //jwcodes = append(jwcodes, jwcode)
  274. /*参数校验*/
  275. }
  276. return //返回nil表示成功
  277. }
  278. // 判断某用户能否抽到卡券
  279. func (s *sCouponUsers) IsEligibleUser(ctx context.Context, jwcode int, couponIds []int) (img string, err error) {
  280. //从数据库中获取符合条件的精网号EligibleJwcodes
  281. var EligibleJwcodes []couponusers.InsertCouponUserRes
  282. err = dao.CouponQualifiedUsers.Ctx(ctx).Fields("jwcode").Scan(&EligibleJwcodes)
  283. if err != nil {
  284. return "", errors.New("从数据库中获取符合条件的精网号失败")
  285. }
  286. if len(EligibleJwcodes) == 0 {
  287. return "", errors.New("核验数据库(满足条件)中数据为空")
  288. }
  289. //检查jwcode是否在EligibleJwcodes中
  290. for _, EligibleJwcode := range EligibleJwcodes {
  291. if EligibleJwcode.Jwcode == jwcode {
  292. //存在,有资格,判断是否抽取过
  293. for _, couponId := range couponIds {
  294. count, err := dao.CouponUsers.Ctx(ctx).Where("jwcode = ?", jwcode).Where("coupon_id = ?", couponId).Count()
  295. if err != nil {
  296. return "", errors.New("检索数据库中是否已存在数据失败")
  297. }
  298. //有记录,抽取过
  299. if count > 0 {
  300. err = dao.CouponUsers.Ctx(ctx).Fields("img_url").Where("jwcode = ?", jwcode).Where("coupon_id = ?", couponId).Scan(&img)
  301. return img, errors.New("该用户已领取过该卡券")
  302. }
  303. }
  304. //所有的都没有记录,没有抽取过
  305. return "", nil
  306. }
  307. }
  308. return "", errors.New("该用户不满足领取条件")
  309. }
  310. // 给单个用户发放卡券
  311. func (s *sCouponUsers) IssueCouponToUser(ctx context.Context, jwcode, couponId int) (err error) {
  312. //查看库中是否已经存在
  313. count, err := dao.CouponUsers.Ctx(ctx).Where("jwcode = ?", jwcode).Where("coupon_id = ?", couponId).Count()
  314. if err != nil {
  315. return errors.New("检索数据库中是否已存在数据失败")
  316. }
  317. //已存在 不添加,直接返回
  318. if count > 0 {
  319. return errors.New("该用户已领取该卡券")
  320. }
  321. //不存在 查看是否满足条件,满足就添加,不满足就返回
  322. //从数据库中获取符合条件的精网号EligibleJwcodes
  323. var EligibleJwcodes []couponusers.InsertCouponUserRes
  324. err = dao.CouponQualifiedUsers.Ctx(ctx).Fields("jwcode").Scan(&EligibleJwcodes)
  325. if err != nil {
  326. return errors.New("从数据库中获取符合条件的精网号失败")
  327. }
  328. if len(EligibleJwcodes) == 0 {
  329. return errors.New("核验数据库(满足条件)中数据为空")
  330. }
  331. //检查jwcode是否在EligibleJwcodes中
  332. for _, EligibleJwcode := range EligibleJwcodes {
  333. if EligibleJwcode.Jwcode == jwcode {
  334. //存在,可以插入
  335. _, err := dao.CouponUsers.Ctx(ctx).Insert(g.Map{
  336. "jwcode": jwcode,
  337. "coupon_id": couponId,
  338. "time": gtime.Now().Unix(),
  339. })
  340. if err != nil {
  341. return errors.New("插入数据库失败")
  342. }
  343. return err
  344. }
  345. }
  346. return errors.New("该用户精网号不符合领取条件") //遍历完了所有满足条件的用户,发现不在其中,不符合条件
  347. }
  348. /*未编写*/
  349. // 导出拥有卡券的用户列表
  350. func (s *sCouponUsers) ExportCouponUsers() {
  351. }