pendant.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. package dao
  2. import (
  3. "bytes"
  4. "context"
  5. "database/sql"
  6. "fmt"
  7. "reflect"
  8. "strconv"
  9. "strings"
  10. "sync"
  11. "time"
  12. "go-common/app/admin/main/usersuit/model"
  13. xsql "go-common/library/database/sql"
  14. "go-common/library/xstr"
  15. "github.com/pkg/errors"
  16. )
  17. const (
  18. _inPdGroupSQL = "INSERT INTO pendant_group(name,rank,status) VALUES (?,?,?)"
  19. _inPdGroupRefSQL = "INSERT INTO pendant_group_ref(gid,pid) VALUES (?,?)"
  20. _inPdInfoSQL = "INSERT INTO pendant_info(name,image,image_model,status,rank) VALUES (?,?,?,?,?)"
  21. _inPdPriceSQL = "INSERT INTO pendant_price(pid,type,price) VALUES (?,?,?) ON DUPLICATE KEY UPDATE pid=?,type=?,price=?"
  22. _inPdPKGSQL = "INSERT INTO user_pendant_pkg(mid,pid,expires,type,status) VALUES (?,?,?,4,1) ON DUPLICATE KEY UPDATE expires = ?, type = 4, status = 1"
  23. _inPdPKGsSQL = "INSERT INTO user_pendant_pkg(mid,pid,expires,type,status) VALUES %s"
  24. _inPdEquipSQL = "INSERT INTO user_pendant_equip(mid,pid,expires) VALUES (?,?,?) ON DUPLICATE KEY UPDATE pid = ? ,expires = ?"
  25. _inPdOperationLogSQL = "INSERT INTO pendant_operation_log(oper_id,mid,pid,source_type,action) VALUES %s"
  26. _upPdGroupRefSQL = "UPDATE pendant_group_ref SET gid = ? WHERE pid = ?"
  27. _upPdPKGsSQL = "UPDATE user_pendant_pkg SET expires = CASE id %s END, type = 4, status = 1 WHERE id IN (%s)"
  28. _upPdGroupSQL = "UPDATE pendant_group SET name=?,rank=?,status=? WHERE id=?"
  29. _upPdGroupStatusSQL = "UPDATE pendant_group SET status=? WHERE id=?"
  30. _upPdInfoSQL = "UPDATE pendant_info SET name=?,image=?,image_model=?,status=?,rank=? WHERE id=?"
  31. _upPdInfoStatusSQL = "UPDATE pendant_info SET status=? WHERE id=?"
  32. _pdInfoAllSQL = `SELECT i.id,i.name,i.image,i.image_model,i.status,i.rank,g.id,g.name,g.rank FROM pendant_info AS i INNER JOIN pendant_group_ref AS r
  33. ON i.id = r.pid LEFT JOIN pendant_group AS g ON g.id = r.gid ORDER BY g.rank ,i.rank ASC,i.id DESC LIMIT ?,?`
  34. _pdGroupInfoTotalSQL = "SELECT COUNT(*) FROM pendant_info INNER JOIN pendant_group_ref ON pendant_info.id = pendant_group_ref.pid"
  35. _pdGroupsTotalSQL = "SELECT COUNT(*) FROM pendant_group"
  36. _pdGroupRefsTotalSQL = "SELECT COUNT(*) FROM pendant_group_ref"
  37. _pdGroupRefsGidTotalSQL = "SELECT COUNT(*) FROM pendant_group_ref WHERE gid = ?"
  38. _pdGroupsSQL = "SELECT id,name,rank,status FROM pendant_group ORDER BY rank ASC LIMIT ?,?"
  39. _pdGroupAllSQL = "SELECT id,name,rank,status FROM pendant_group ORDER BY rank ASC"
  40. _pdGroupIDsSQL = "SELECT id,name,rank,status FROM pendant_group WHERE id IN (%s)"
  41. _pdGroupIDSQL = "SELECT id,name,rank,status FROM pendant_group WHERE id = ?"
  42. _pdInfoIDsSQL = "SELECT id,name,image,image_model,status,rank FROM pendant_info WHERE id IN (%s) ORDER BY rank ASC"
  43. _pdPriceIDsSQL = "SELECT pid,type,price FROM pendant_price WHERE pid IN (%s)"
  44. _pdGroupRefRanksSQL = "SELECT pr.gid,pr.pid FROM pendant_group_ref AS pr INNER JOIN pendant_group AS pg WHERE pr.gid = pg.id ORDER BY pg.rank ASC LIMIT ?,?"
  45. _pdGroupRefsSQL = "SELECT pid FROM pendant_group_ref WHERE gid = ? LIMIT ?,?"
  46. _pdInfoIDSQL = "SELECT id,name,image,image_model,status,rank FROM pendant_info WHERE id = ?"
  47. _pdInfoAllNoPageSQL = "SELECT id,name,image,image_model,status,rank FROM pendant_info"
  48. _maxOrderHistorysSQL = "SELECT MAX(id) FROM user_pendant_order"
  49. _countOrderHistorysSQL = "SELECT COUNT(*) FROM user_pendant_order %s"
  50. _orderHistorysSQL = "SELECT mid,order_id,pay_id,appid,status,pid,time_length,cost,buy_time,pay_type FROM user_pendant_order %s"
  51. _pdPKGsUIDSQL = "SELECT mid,pid,expires,type,status,is_vip FROM user_pendant_pkg WHERE mid = ? ORDER BY mtime DESC"
  52. _pdPKGUIDsSQL = "SELECT id,mid,pid,expires,type,status,is_vip FROM user_pendant_pkg WHERE mid IN (%s) AND pid = ?"
  53. _pdPKGUIDSQL = "SELECT id,mid,pid,expires,type,status,is_vip FROM user_pendant_pkg WHERE mid = ? AND pid = ?"
  54. _pdEquipUIDSQL = "SELECT pid,expires FROM user_pendant_equip WHERE mid = ? AND expires >= ?"
  55. _pdOperationLogTotalSQL = "SELECT MAX(id) FROM pendant_operation_log"
  56. _pdOperationLogSQL = "SELECT oper_id,action,mid,pid,source_type,ctime,mtime FROM pendant_operation_log ORDER BY mtime DESC LIMIT ?,?"
  57. )
  58. // AddPendantGroup insert pendant group .
  59. func (d *Dao) AddPendantGroup(c context.Context, pg *model.PendantGroup) (gid int64, err error) {
  60. var res sql.Result
  61. if res, err = d.db.Exec(c, _inPdGroupSQL, pg.Name, pg.Rank, pg.Status); err != nil {
  62. err = errors.Wrapf(err, "AddPendantGroup d.db.Exec(%s,%d)", pg.Name, pg.Rank)
  63. return
  64. }
  65. return res.LastInsertId()
  66. }
  67. // TxAddPendantGroupRef tx insert pendant group ref.
  68. func (d *Dao) TxAddPendantGroupRef(tx *xsql.Tx, pr *model.PendantGroupRef) (affected int64, err error) {
  69. var res sql.Result
  70. if res, err = tx.Exec(_inPdGroupRefSQL, pr.GID, pr.PID); err != nil {
  71. err = errors.Wrapf(err, "TxAddPendantGroupRef itx.Exec(%d,%d)", pr.GID, pr.PID)
  72. return
  73. }
  74. return res.RowsAffected()
  75. }
  76. // TxAddPendantInfo insert pendant info.
  77. func (d *Dao) TxAddPendantInfo(tx *xsql.Tx, pi *model.PendantInfo) (pid int64, err error) {
  78. var res sql.Result
  79. if res, err = tx.Exec(_inPdInfoSQL, pi.Name, pi.Image, pi.ImageModel, pi.Status, pi.Rank); err != nil {
  80. err = errors.Wrapf(err, "TxAddPendantInfo tx.Exec(%s,%s,%s,%d)", pi.Name, pi.Image, pi.ImageModel, pi.Rank)
  81. return
  82. }
  83. return res.LastInsertId()
  84. }
  85. // TxAddPendantPrices insert pendant prices.
  86. func (d *Dao) TxAddPendantPrices(tx *xsql.Tx, pp *model.PendantPrice) (affected int64, err error) {
  87. var res sql.Result
  88. if res, err = tx.Exec(_inPdPriceSQL, pp.PID, pp.TP, pp.Price, pp.PID, pp.TP, pp.Price); err != nil {
  89. err = errors.Wrapf(err, "TxAddPendantPrices tx.Exec(%d,%d,%d)", pp.PID, pp.TP, pp.Price)
  90. return
  91. }
  92. return res.RowsAffected()
  93. }
  94. // AddPendantPKG insert pendant pkg.
  95. func (d *Dao) AddPendantPKG(c context.Context, pkg *model.PendantPKG) (affected int64, err error) {
  96. var res sql.Result
  97. if res, err = d.db.Exec(c, _inPdPKGSQL, pkg.UID, pkg.PID, pkg.Expires, pkg.Expires); err != nil {
  98. err = errors.Wrapf(err, "AddPendantPKG d.db.Exec(%d,%d,%d)", pkg.UID, pkg.PID, pkg.Expires)
  99. return
  100. }
  101. return res.RowsAffected()
  102. }
  103. // TxAddPendantPKGs multi insert pendant pkg.
  104. func (d *Dao) TxAddPendantPKGs(tx *xsql.Tx, pkgs []*model.PendantPKG) (affected int64, err error) {
  105. var (
  106. uids []int64
  107. pids map[int64]struct{}
  108. )
  109. l := len(pkgs)
  110. valueStrings := make([]string, 0, l)
  111. valueArgs := make([]interface{}, 0, l*3)
  112. pids = make(map[int64]struct{})
  113. for _, pkg := range pkgs {
  114. valueStrings = append(valueStrings, "(?,?,?,4,1)")
  115. valueArgs = append(valueArgs, strconv.FormatInt(pkg.UID, 10))
  116. valueArgs = append(valueArgs, strconv.FormatInt(pkg.PID, 10))
  117. valueArgs = append(valueArgs, strconv.FormatInt(pkg.Expires, 10))
  118. uids = append(uids, pkg.UID)
  119. pids[pkg.PID] = struct{}{}
  120. }
  121. stmt := fmt.Sprintf(_inPdPKGsSQL, strings.Join(valueStrings, ","))
  122. _, err = tx.Exec(stmt, valueArgs...)
  123. if err != nil {
  124. err = errors.Wrapf(err, "TxAddPendantPKGs tx.Exec(%s,%+v)", xstr.JoinInts(uids), reflect.ValueOf(pids).MapKeys())
  125. }
  126. return
  127. }
  128. // AddPendantEquip insert pendant equip.
  129. func (d *Dao) AddPendantEquip(c context.Context, pkg *model.PendantPKG) (affected int64, err error) {
  130. var res sql.Result
  131. if res, err = d.db.Exec(c, _inPdEquipSQL, pkg.UID, pkg.PID, pkg.Expires, pkg.PID, pkg.Expires); err != nil {
  132. err = errors.Wrapf(err, "AddPendantEquip d.db.Exec(%d,%d,%d)", pkg.UID, pkg.PID, pkg.Expires)
  133. return
  134. }
  135. return res.RowsAffected()
  136. }
  137. // AddPendantOperLog insert pendant operation log.
  138. func (d *Dao) AddPendantOperLog(c context.Context, oid int64, uids []int64, pid int64, action string) (affected int64, err error) {
  139. var res sql.Result
  140. l := len(uids)
  141. valueStrings := make([]string, 0, l)
  142. valueArgs := make([]interface{}, 0, l*5)
  143. for _, uid := range uids {
  144. valueStrings = append(valueStrings, "(?,?,?,?,?)")
  145. valueArgs = append(valueArgs, strconv.FormatInt(oid, 10))
  146. valueArgs = append(valueArgs, strconv.FormatInt(uid, 10))
  147. valueArgs = append(valueArgs, strconv.FormatInt(pid, 10))
  148. valueArgs = append(valueArgs, strconv.FormatInt(int64(model.PendantSourceTypeAdmin), 10))
  149. valueArgs = append(valueArgs, action)
  150. }
  151. stmt := fmt.Sprintf(_inPdOperationLogSQL, strings.Join(valueStrings, ","))
  152. res, err = d.db.Exec(c, stmt, valueArgs...)
  153. if err != nil {
  154. err = errors.Errorf("AddPendantOperLog tx.Exec(%s,%d,%s) error(%+v)", xstr.JoinInts(uids), pid, action, err)
  155. return
  156. }
  157. return res.RowsAffected()
  158. }
  159. // TxUpPendantGroupRef update pendant group ref.
  160. func (d *Dao) TxUpPendantGroupRef(tx *xsql.Tx, gid, pid int64) (affected int64, err error) {
  161. var res sql.Result
  162. if res, err = tx.Exec(_upPdGroupRefSQL, gid, pid); err != nil {
  163. err = errors.Wrapf(err, "UpPendantGroupRef tx.Exec(%d,%d)", gid, pid)
  164. return
  165. }
  166. return res.RowsAffected()
  167. }
  168. // TxUpPendantPKGs multi update pendant pkg.
  169. func (d *Dao) TxUpPendantPKGs(tx *xsql.Tx, pkgs []*model.PendantPKG) (affected int64, err error) {
  170. var ids []int64
  171. l := len(pkgs)
  172. valueStrings := make([]string, 0, l)
  173. valueArgs := make([]interface{}, 0, l*2)
  174. for _, pkg := range pkgs {
  175. valueStrings = append(valueStrings, "WHEN ? THEN ? ")
  176. valueArgs = append(valueArgs, strconv.FormatInt(pkg.ID, 10))
  177. valueArgs = append(valueArgs, strconv.FormatInt(pkg.Expires, 10))
  178. ids = append(ids, pkg.ID)
  179. }
  180. stmt := fmt.Sprintf(_upPdPKGsSQL, strings.Join(valueStrings, " "), xstr.JoinInts(ids))
  181. _, err = tx.Exec(stmt, valueArgs...)
  182. if err != nil {
  183. err = errors.Wrapf(err, "TxUpPendantPKGs tx.Exec(%s)", xstr.JoinInts(ids))
  184. }
  185. return
  186. }
  187. // UpPendantGroup update pendant group.
  188. func (d *Dao) UpPendantGroup(c context.Context, pg *model.PendantGroup) (affected int64, err error) {
  189. var res sql.Result
  190. if res, err = d.db.Exec(c, _upPdGroupSQL, pg.Name, pg.Rank, pg.Status, pg.ID); err != nil {
  191. err = errors.Wrapf(err, "UpPendantGroup tx.Exec(%s,%d,%d,%d)", pg.Name, pg.Rank, pg.Status, pg.ID)
  192. return
  193. }
  194. return res.RowsAffected()
  195. }
  196. // UpPendantGroupStatus update pendant group status.
  197. func (d *Dao) UpPendantGroupStatus(c context.Context, gid int64, status int8) (affected int64, err error) {
  198. var res sql.Result
  199. if res, err = d.db.Exec(c, _upPdGroupStatusSQL, status, gid); err != nil {
  200. err = errors.Wrapf(err, "UpPendantGroupStatus tx.Exec(%d,%d)", status, gid)
  201. return
  202. }
  203. return res.RowsAffected()
  204. }
  205. // TxUpPendantInfo update pendant info.
  206. func (d *Dao) TxUpPendantInfo(tx *xsql.Tx, pi *model.PendantInfo) (affected int64, err error) {
  207. var res sql.Result
  208. if res, err = tx.Exec(_upPdInfoSQL, pi.Name, pi.Image, pi.ImageModel, pi.Status, pi.Rank, pi.ID); err != nil {
  209. err = errors.Wrapf(err, "TxAddPendantPrices tx.Exec(%s,%s,%s,%d,%d,%d)", pi.Name, pi.Image, pi.ImageModel, pi.Status, pi.Rank, pi.ID)
  210. return
  211. }
  212. return res.RowsAffected()
  213. }
  214. // UpPendantInfoStatus update pendant info status.
  215. func (d *Dao) UpPendantInfoStatus(c context.Context, pid int64, status int8) (affected int64, err error) {
  216. var res sql.Result
  217. if res, err = d.db.Exec(c, _upPdInfoStatusSQL, status, pid); err != nil {
  218. err = errors.Wrapf(err, "UpPendantGroupStatus tx.Exec(%d,%d)", status, pid)
  219. return
  220. }
  221. return res.RowsAffected()
  222. }
  223. // PendantInfoAll pendant info all.
  224. func (d *Dao) PendantInfoAll(c context.Context, pn, ps int) (pis []*model.PendantInfo, pids []int64, err error) {
  225. var (
  226. gid, groupRank sql.NullInt64
  227. groupName sql.NullString
  228. rows *xsql.Rows
  229. offset = (pn - 1) * ps
  230. )
  231. if rows, err = d.db.Query(c, _pdInfoAllSQL, offset, ps); err != nil {
  232. err = errors.Wrapf(err, "PendantInfoAll d.db.Query(%d,%d)", offset, ps)
  233. return
  234. }
  235. defer rows.Close()
  236. for rows.Next() {
  237. pi := new(model.PendantInfo)
  238. if err = rows.Scan(&pi.ID, &pi.Name, &pi.Image, &pi.ImageModel, &pi.Status, &pi.Rank, &gid, &groupName, &groupRank); err != nil {
  239. err = errors.Wrap(err, "PendantInfoAll row.Scan()")
  240. return
  241. }
  242. pi.GID = gid.Int64
  243. pi.GroupName = groupName.String
  244. pi.GroupRank = int16(groupRank.Int64)
  245. pids = append(pids, pi.ID)
  246. pis = append(pis, pi)
  247. }
  248. err = rows.Err()
  249. return
  250. }
  251. // PendantGroupInfoTotal pendant group info total.
  252. func (d *Dao) PendantGroupInfoTotal(c context.Context) (count int64, err error) {
  253. row := d.db.QueryRow(c, _pdGroupInfoTotalSQL)
  254. if err = row.Scan(&count); err != nil {
  255. err = errors.Wrap(err, "d.dao.PendantGroupInfoTotal")
  256. }
  257. return
  258. }
  259. // PendantGroupsTotal pendant group total.
  260. func (d *Dao) PendantGroupsTotal(c context.Context) (count int64, err error) {
  261. row := d.db.QueryRow(c, _pdGroupsTotalSQL)
  262. if err = row.Scan(&count); err != nil {
  263. err = errors.Wrap(err, "d.dao.PendantGroupsTotal")
  264. }
  265. return
  266. }
  267. // PendantGroupRefsTotal pendant group refs total.
  268. func (d *Dao) PendantGroupRefsTotal(c context.Context) (count int64, err error) {
  269. row := d.db.QueryRow(c, _pdGroupRefsTotalSQL)
  270. if err = row.Scan(&count); err != nil {
  271. err = errors.Wrap(err, "d.dao.PendantGroupRefsTotal")
  272. }
  273. return
  274. }
  275. // PendantGroupRefsGidTotal pendant group refs total by gid.
  276. func (d *Dao) PendantGroupRefsGidTotal(c context.Context, gid int64) (count int64, err error) {
  277. row := d.db.QueryRow(c, _pdGroupRefsGidTotalSQL, gid)
  278. if err = row.Scan(&count); err != nil {
  279. err = errors.Wrap(err, "d.dao.PendantGroupRefsGidTotal")
  280. }
  281. return
  282. }
  283. // PendantGroups pendant group pagesize.
  284. func (d *Dao) PendantGroups(c context.Context, pn, ps int) (pgs []*model.PendantGroup, err error) {
  285. var (
  286. rows *xsql.Rows
  287. offset = (pn - 1) * ps
  288. )
  289. if rows, err = d.db.Query(c, _pdGroupsSQL, offset, ps); err != nil {
  290. err = errors.Wrapf(err, "PendantGroups d.db.Query(%d,%d)", offset, ps)
  291. return
  292. }
  293. defer rows.Close()
  294. for rows.Next() {
  295. pg := new(model.PendantGroup)
  296. if err = rows.Scan(&pg.ID, &pg.Name, &pg.Rank, &pg.Status); err != nil {
  297. err = errors.Wrap(err, "PendantGroups row.Scan()")
  298. return
  299. }
  300. pgs = append(pgs, pg)
  301. }
  302. err = rows.Err()
  303. return
  304. }
  305. // PendantGroupAll pendant all group .
  306. func (d *Dao) PendantGroupAll(c context.Context) (pgs []*model.PendantGroup, err error) {
  307. var rows *xsql.Rows
  308. if rows, err = d.db.Query(c, _pdGroupAllSQL); err != nil {
  309. err = errors.Wrap(err, "PendantGroupAll d.db.Query(%d,%d)")
  310. return
  311. }
  312. defer rows.Close()
  313. for rows.Next() {
  314. pg := new(model.PendantGroup)
  315. if err = rows.Scan(&pg.ID, &pg.Name, &pg.Rank, &pg.Status); err != nil {
  316. err = errors.Wrap(err, "PendantGroupAll row.Scan()")
  317. return
  318. }
  319. pgs = append(pgs, pg)
  320. }
  321. err = rows.Err()
  322. return
  323. }
  324. // PendantGroupIDs pendant group in ids.
  325. func (d *Dao) PendantGroupIDs(c context.Context, ids []int64) (pgs []*model.PendantGroup, err error) {
  326. var rows *xsql.Rows
  327. if rows, err = d.db.Query(c, fmt.Sprintf(_pdGroupIDsSQL, xstr.JoinInts(ids))); err != nil {
  328. err = errors.Wrapf(err, "PendantGroupIDs d.db.Query(%s)", xstr.JoinInts(ids))
  329. return
  330. }
  331. defer rows.Close()
  332. for rows.Next() {
  333. pg := new(model.PendantGroup)
  334. if err = rows.Scan(&pg.ID, &pg.Name, &pg.Rank, &pg.Status); err != nil {
  335. err = errors.Wrap(err, "PendantGroupIDs row.Scan()")
  336. return
  337. }
  338. pgs = append(pgs, pg)
  339. }
  340. err = rows.Err()
  341. return
  342. }
  343. // PendantGroupID pendant group by id.
  344. func (d *Dao) PendantGroupID(c context.Context, id int64) (pg *model.PendantGroup, err error) {
  345. row := d.db.QueryRow(c, _pdGroupIDSQL, id)
  346. if err != nil {
  347. err = errors.Wrapf(err, "PendantGroupID d.db.Query(%d)", id)
  348. return
  349. }
  350. pg = &model.PendantGroup{}
  351. if err = row.Scan(&pg.ID, &pg.Name, &pg.Rank, &pg.Status); err != nil {
  352. if err == sql.ErrNoRows {
  353. err = nil
  354. pg = nil
  355. return
  356. }
  357. err = errors.Wrap(err, "PendantGroupID row.Scan")
  358. }
  359. return
  360. }
  361. // PendantInfoIDs pendant info in ids.
  362. func (d *Dao) PendantInfoIDs(c context.Context, ids []int64) (pis []*model.PendantInfo, pim map[int64]*model.PendantInfo, err error) {
  363. var rows *xsql.Rows
  364. if rows, err = d.db.Query(c, fmt.Sprintf(_pdInfoIDsSQL, xstr.JoinInts(ids))); err != nil {
  365. err = errors.Wrapf(err, "PendantInfoIDs d.db.Query(%s)", xstr.JoinInts(ids))
  366. return
  367. }
  368. defer rows.Close()
  369. pim = make(map[int64]*model.PendantInfo, len(ids))
  370. for rows.Next() {
  371. pi := new(model.PendantInfo)
  372. if err = rows.Scan(&pi.ID, &pi.Name, &pi.Image, &pi.ImageModel, &pi.Status, &pi.Rank); err != nil {
  373. err = errors.Wrap(err, "PendantInfoIDs row.Scan()")
  374. return
  375. }
  376. pis = append(pis, pi)
  377. pim[pi.ID] = pi
  378. }
  379. err = rows.Err()
  380. return
  381. }
  382. // PendantPriceIDs pendant price in ids.
  383. func (d *Dao) PendantPriceIDs(c context.Context, ids []int64) (ppm map[int64][]*model.PendantPrice, err error) {
  384. var rows *xsql.Rows
  385. if rows, err = d.db.Query(c, fmt.Sprintf(_pdPriceIDsSQL, xstr.JoinInts(ids))); err != nil {
  386. err = errors.Wrapf(err, "PendantPriceIDs d.db.Query(%s)", xstr.JoinInts(ids))
  387. return
  388. }
  389. defer rows.Close()
  390. ppm = make(map[int64][]*model.PendantPrice, len(ids))
  391. for rows.Next() {
  392. pp := new(model.PendantPrice)
  393. if err = rows.Scan(&pp.PID, &pp.TP, &pp.Price); err != nil {
  394. err = errors.Wrap(err, "PendantPriceIDs row.Scan()")
  395. return
  396. }
  397. ppm[pp.PID] = append(ppm[pp.PID], pp)
  398. }
  399. err = rows.Err()
  400. return
  401. }
  402. // PendantGroupRefRanks pendant group ref pagesize by rank.
  403. func (d *Dao) PendantGroupRefRanks(c context.Context, pn, ps int) (prs []*model.PendantGroupRef, err error) {
  404. var (
  405. rows *xsql.Rows
  406. offset = (pn - 1) * ps
  407. )
  408. if rows, err = d.db.Query(c, _pdGroupRefRanksSQL, offset, ps); err != nil {
  409. err = errors.Wrapf(err, "PendantGroupRefRanks d.db.Query(%d,%d)", offset, ps)
  410. return
  411. }
  412. defer rows.Close()
  413. for rows.Next() {
  414. pr := new(model.PendantGroupRef)
  415. if err = rows.Scan(&pr.GID, &pr.PID); err != nil {
  416. err = errors.Wrap(err, "PendantGroupRefRanks row.Scan()")
  417. return
  418. }
  419. prs = append(prs, pr)
  420. }
  421. err = rows.Err()
  422. return
  423. }
  424. // PendantGroupPIDs pendant group ref pagesize.
  425. func (d *Dao) PendantGroupPIDs(c context.Context, gid int64, pn, ps int) (pids []int64, err error) {
  426. var (
  427. rows *xsql.Rows
  428. offset = (pn - 1) * ps
  429. )
  430. if rows, err = d.db.Query(c, _pdGroupRefsSQL, gid, offset, ps); err != nil {
  431. err = errors.Wrapf(err, "PendantGroupPIDs d.db.Query(%d,%d,%d)", gid, offset, ps)
  432. return
  433. }
  434. defer rows.Close()
  435. var pid int64
  436. for rows.Next() {
  437. if err = rows.Scan(&pid); err != nil {
  438. err = errors.Wrap(err, "PendantGroupPIDs row.Scan()")
  439. return
  440. }
  441. pids = append(pids, pid)
  442. }
  443. err = rows.Err()
  444. return
  445. }
  446. // PendantInfoID pendant info.
  447. func (d *Dao) PendantInfoID(c context.Context, id int64) (pi *model.PendantInfo, err error) {
  448. row := d.db.QueryRow(c, _pdInfoIDSQL, id)
  449. if err != nil {
  450. err = errors.Wrapf(err, "PendantInfoID d.db.QueryRow(%d)", id)
  451. return
  452. }
  453. pi = &model.PendantInfo{}
  454. if err = row.Scan(&pi.ID, &pi.Name, &pi.Image, &pi.ImageModel, &pi.Status, &pi.Rank); err != nil {
  455. if err == sql.ErrNoRows {
  456. err = nil
  457. pi = nil
  458. return
  459. }
  460. err = errors.Wrap(err, "PendantInfoID row.Scan")
  461. }
  462. return
  463. }
  464. // PendantInfoAllNoPage pendant info no page.
  465. func (d *Dao) PendantInfoAllNoPage(c context.Context) (pis []*model.PendantInfo, err error) {
  466. var rows *xsql.Rows
  467. if rows, err = d.db.Query(c, _pdInfoAllNoPageSQL); err != nil {
  468. err = errors.Wrap(err, "PendantInfoAllOnSale d.db.Query()")
  469. return
  470. }
  471. defer rows.Close()
  472. for rows.Next() {
  473. pi := new(model.PendantInfo)
  474. if err = rows.Scan(&pi.ID, &pi.Name, &pi.Image, &pi.ImageModel, &pi.Status, &pi.Rank); err != nil {
  475. err = errors.Wrap(err, "PendantInfoAllOnSale row.Scan()")
  476. return
  477. }
  478. pis = append(pis, pi)
  479. }
  480. err = rows.Err()
  481. return
  482. }
  483. // BuildOrderInfoSQL build a order sql string.
  484. func (d *Dao) BuildOrderInfoSQL(c context.Context, arg *model.ArgPendantOrder, tp string) (sql string, values []interface{}) {
  485. values = make([]interface{}, 0, 5)
  486. var (
  487. cond []string
  488. condStr string
  489. )
  490. if arg.UID != 0 {
  491. cond = append(cond, "mid = ?")
  492. values = append(values, arg.UID)
  493. }
  494. if arg.PID != 0 {
  495. cond = append(cond, "pid = ?")
  496. values = append(values, arg.PID)
  497. }
  498. if arg.Status != 0 {
  499. cond = append(cond, "status = ?")
  500. values = append(values, arg.Status)
  501. }
  502. if arg.PayID != "" {
  503. cond = append(cond, "pay_id = ?")
  504. values = append(values, arg.PayID)
  505. }
  506. if arg.Start != 0 {
  507. cond = append(cond, "mtime >= ?")
  508. values = append(values, arg.Start)
  509. }
  510. if arg.End != 0 {
  511. cond = append(cond, "mtime <= ?")
  512. values = append(values, arg.End)
  513. }
  514. if tp == "info" {
  515. condStr = d.joinStrings(cond)
  516. if condStr != "" {
  517. sql = fmt.Sprintf(_orderHistorysSQL+" %s %s ", "WHERE", condStr, "ORDER BY mtime DESC LIMIT ?,?")
  518. } else {
  519. sql = fmt.Sprintf(_orderHistorysSQL+" %s ", condStr, "ORDER BY mtime DESC LIMIT ?,?")
  520. }
  521. values = append(values, (arg.PN-1)*arg.PS, arg.PS)
  522. } else if tp == "count" {
  523. condStr = d.joinStrings(cond)
  524. if condStr != "" {
  525. sql = fmt.Sprintf(_countOrderHistorysSQL+" %s", "WHERE", condStr)
  526. } else {
  527. sql = fmt.Sprintf(_countOrderHistorysSQL, condStr)
  528. }
  529. }
  530. return
  531. }
  532. func (d *Dao) joinStrings(is []string) string {
  533. if len(is) == 0 {
  534. return ""
  535. }
  536. if len(is) == 1 {
  537. return is[0]
  538. }
  539. var bfPool = sync.Pool{
  540. New: func() interface{} {
  541. return bytes.NewBuffer([]byte{})
  542. },
  543. }
  544. buf := bfPool.Get().(*bytes.Buffer)
  545. for _, i := range is {
  546. buf.WriteString(i)
  547. buf.WriteString(" AND ")
  548. }
  549. if buf.Len() > 0 {
  550. buf.Truncate(buf.Len() - 4)
  551. }
  552. s := buf.String()
  553. buf.Reset()
  554. bfPool.Put(buf)
  555. return s
  556. }
  557. // MaxOrderHistory max order history.
  558. func (d *Dao) MaxOrderHistory(c context.Context) (max int64, err error) {
  559. row := d.db.QueryRow(c, _maxOrderHistorysSQL)
  560. if err != nil {
  561. err = errors.Wrap(err, "MaxOrderHistory d.db.QueryRow()")
  562. return
  563. }
  564. if err = row.Scan(&max); err != nil {
  565. if err == sql.ErrNoRows {
  566. err = nil
  567. max = 0
  568. return
  569. }
  570. err = errors.Wrap(err, "MaxOrderHistory row.Scan")
  571. }
  572. return
  573. }
  574. // CountOrderHistory count order history.
  575. func (d *Dao) CountOrderHistory(c context.Context, arg *model.ArgPendantOrder) (total int64, err error) {
  576. sqlstr, values := d.BuildOrderInfoSQL(c, arg, "count")
  577. row := d.db.QueryRow(c, sqlstr, values...)
  578. if err != nil {
  579. err = errors.Wrap(err, "CountOrderHistory d.db.QueryRow()")
  580. return
  581. }
  582. if err = row.Scan(&total); err != nil {
  583. if err == sql.ErrNoRows {
  584. err = nil
  585. total = 0
  586. return
  587. }
  588. err = errors.Wrap(err, "CountOrderHistory row.Scan")
  589. }
  590. return
  591. }
  592. // OrderHistorys get order historys.
  593. func (d *Dao) OrderHistorys(c context.Context, arg *model.ArgPendantOrder) (pos []*model.PendantOrder, pids []int64, err error) {
  594. var rows *xsql.Rows
  595. sqlstr, values := d.BuildOrderInfoSQL(c, arg, "info")
  596. if rows, err = d.db.Query(c, sqlstr, values...); err != nil {
  597. err = errors.Wrap(err, "OrderHistorys d.db.Query()")
  598. return
  599. }
  600. defer rows.Close()
  601. for rows.Next() {
  602. po := new(model.PendantOrder)
  603. if err = rows.Scan(&po.UID, &po.OrderID, &po.PayID, &po.AppID, &po.Status, &po.PID, &po.TimeLength, &po.Cost, &po.BuyTime, &po.PayType); err != nil {
  604. err = errors.Wrap(err, "OrderHistorys row.Scan()")
  605. return
  606. }
  607. pos = append(pos, po)
  608. pids = append(pids, po.PID)
  609. }
  610. err = rows.Err()
  611. return
  612. }
  613. // PendantPKGs get pendant pkgs.
  614. func (d *Dao) PendantPKGs(c context.Context, uid int64) (pkgs []*model.PendantPKG, err error) {
  615. var rows *xsql.Rows
  616. if rows, err = d.db.Query(c, _pdPKGsUIDSQL, uid); err != nil {
  617. err = errors.Wrapf(err, "PendantPKGs d.db.Query(%d)", uid)
  618. return
  619. }
  620. defer rows.Close()
  621. for rows.Next() {
  622. pkg := new(model.PendantPKG)
  623. if err = rows.Scan(&pkg.UID, &pkg.PID, &pkg.Expires, &pkg.TP, &pkg.Status, &pkg.IsVip); err != nil {
  624. err = errors.Wrap(err, "PendantPKGs row.Scan()")
  625. return
  626. }
  627. pkgs = append(pkgs, pkg)
  628. }
  629. err = rows.Err()
  630. return
  631. }
  632. // PendantPKGUIDs get pendant pkgs by muilti uid.
  633. func (d *Dao) PendantPKGUIDs(c context.Context, uids []int64, pid int64) (pkgs []*model.PendantPKG, err error) {
  634. var rows *xsql.Rows
  635. if rows, err = d.db.Query(c, fmt.Sprintf(_pdPKGUIDsSQL, xstr.JoinInts(uids)), pid); err != nil {
  636. err = errors.Wrapf(err, "PendantPKGUIDs d.db.Query(%s,%d)", xstr.JoinInts(uids), pid)
  637. return
  638. }
  639. defer rows.Close()
  640. for rows.Next() {
  641. pkg := new(model.PendantPKG)
  642. if err = rows.Scan(&pkg.ID, &pkg.UID, &pkg.PID, &pkg.Expires, &pkg.TP, &pkg.Status, &pkg.IsVip); err != nil {
  643. err = errors.Wrap(err, "PendantPKGUIDs row.Scan()")
  644. return
  645. }
  646. pkgs = append(pkgs, pkg)
  647. }
  648. err = rows.Err()
  649. return
  650. }
  651. // PendantPKG get pendant in pkg.
  652. func (d *Dao) PendantPKG(c context.Context, uid, pid int64) (pkg *model.PendantPKG, err error) {
  653. row := d.db.QueryRow(c, _pdPKGUIDSQL, uid, pid)
  654. if err != nil {
  655. err = errors.Wrapf(err, "PendantPKG d.db.QueryRow(%d,%d)", uid, pid)
  656. return
  657. }
  658. pkg = &model.PendantPKG{}
  659. if err = row.Scan(&pkg.ID, &pkg.UID, &pkg.PID, &pkg.Expires, &pkg.TP, &pkg.Status, &pkg.IsVip); err != nil {
  660. if err == sql.ErrNoRows {
  661. err = nil
  662. pkg = nil
  663. return
  664. }
  665. err = errors.Wrap(err, "PendantPKG row.Scan")
  666. }
  667. return
  668. }
  669. // PendantEquipUID pendant equip by uid.
  670. func (d *Dao) PendantEquipUID(c context.Context, uid int64) (pkg *model.PendantPKG, err error) {
  671. row := d.db.QueryRow(c, _pdEquipUIDSQL, uid, time.Now().Unix())
  672. if err != nil {
  673. err = errors.Wrapf(err, "PendantEquipUID d.db.QueryRow(%d)", uid)
  674. return
  675. }
  676. pkg = &model.PendantPKG{}
  677. if err = row.Scan(&pkg.PID, &pkg.Expires); err != nil {
  678. if err == sql.ErrNoRows {
  679. err = nil
  680. pkg = nil
  681. return
  682. }
  683. err = errors.Wrap(err, "PendantEquipUID row.Scan")
  684. }
  685. return
  686. }
  687. // PendantOperLog get pendant operation log.
  688. func (d *Dao) PendantOperLog(c context.Context, pn, ps int) (opers []*model.PendantOperLog, uids []int64, err error) {
  689. var (
  690. rows *xsql.Rows
  691. offset = (pn - 1) * ps
  692. )
  693. if rows, err = d.db.Query(c, _pdOperationLogSQL, offset, ps); err != nil {
  694. err = errors.Wrapf(err, "PendantOperLog d.db.Query(%d,%d)", offset, ps)
  695. return
  696. }
  697. defer rows.Close()
  698. for rows.Next() {
  699. oper := new(model.PendantOperLog)
  700. if err = rows.Scan(&oper.OID, &oper.Action, &oper.UID, &oper.PID, &oper.SourceType, &oper.CTime, &oper.MTime); err != nil {
  701. err = errors.Wrap(err, "PendantOperLog row.Scan()")
  702. return
  703. }
  704. opers = append(opers, oper)
  705. uids = append(uids, oper.UID)
  706. }
  707. err = rows.Err()
  708. return
  709. }
  710. // PendantOperationLogTotal pendant operation log total.
  711. func (d *Dao) PendantOperationLogTotal(c context.Context) (count int64, err error) {
  712. row := d.db.QueryRow(c, _pdOperationLogTotalSQL)
  713. if err = row.Scan(&count); err != nil {
  714. err = errors.Wrap(err, "d.dao.PendantOperationLogTotal")
  715. }
  716. return
  717. }