realname.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. package http
  2. import (
  3. "bytes"
  4. "encoding/csv"
  5. "fmt"
  6. "io/ioutil"
  7. "net/http"
  8. "strconv"
  9. "time"
  10. "go-common/app/admin/main/member/model"
  11. "go-common/library/ecode"
  12. "go-common/library/log"
  13. bm "go-common/library/net/http/blademaster"
  14. "github.com/pkg/errors"
  15. )
  16. func realnameList(ctx *bm.Context) {
  17. var (
  18. arg = &model.ArgRealnameList{}
  19. list []*model.RespRealnameApply
  20. total int
  21. err error
  22. )
  23. if err = ctx.Bind(arg); err != nil {
  24. return
  25. }
  26. if arg.PN <= 0 {
  27. arg.PN = 1
  28. }
  29. if arg.PS <= 0 || arg.PS > 100 {
  30. arg.PS = 10
  31. }
  32. // 没有指定实名认证申请状态State,默认查询所有
  33. if arg.State == "" {
  34. arg.State = model.RealnameApplyStateAll
  35. }
  36. // 如果没有使用 mid || card 则取默认7天前作为 TSFrom
  37. if arg.MID == 0 && arg.Card == "" {
  38. if arg.TSFrom <= 0 {
  39. arg.TSFrom = time.Now().Add(-time.Hour * 24 * 7).Unix()
  40. }
  41. }
  42. // 如果使用 mid 或 card 进行查询,则查询所有时间段对应的数据
  43. if arg.MID != 0 || arg.Card != "" {
  44. arg.TSFrom = 0
  45. arg.TSTo = 0
  46. }
  47. if list, total, err = svc.RealnameList(ctx, arg); err != nil {
  48. ctx.JSON(nil, err)
  49. return
  50. }
  51. res := map[string]interface{}{
  52. "list": list,
  53. "page": map[string]int{
  54. "num": arg.PN,
  55. "size": arg.PS,
  56. "total": total,
  57. },
  58. }
  59. ctx.JSON(res, nil)
  60. }
  61. func realnamePendingList(ctx *bm.Context) {
  62. var (
  63. arg = &model.ArgRealnamePendingList{}
  64. list []*model.RespRealnameApply
  65. total int
  66. err error
  67. )
  68. if err = ctx.Bind(arg); err != nil {
  69. return
  70. }
  71. if arg.PN <= 0 {
  72. arg.PN = 1
  73. }
  74. if arg.PS <= 0 || arg.PS > 100 {
  75. arg.PS = 10
  76. }
  77. if list, total, err = svc.RealnamePendingList(ctx, arg); err != nil {
  78. ctx.JSON(nil, err)
  79. return
  80. }
  81. res := map[string]interface{}{
  82. "list": list,
  83. "page": map[string]int{
  84. "num": arg.PN,
  85. "size": arg.PS,
  86. "total": total,
  87. },
  88. }
  89. ctx.JSON(res, nil)
  90. }
  91. func realnameAuditApply(ctx *bm.Context) {
  92. var (
  93. arg = &model.ArgRealnameAuditApply{}
  94. adminName string
  95. adminID int64
  96. data interface{}
  97. ok bool
  98. err error
  99. )
  100. if err = ctx.Bind(arg); err != nil {
  101. return
  102. }
  103. // 驳回必须有reason
  104. if arg.Action == model.RealnameActionReject && arg.Reason == "" {
  105. ctx.JSON(nil, ecode.RequestErr)
  106. return
  107. }
  108. if data, ok = ctx.Get("username"); !ok {
  109. ctx.JSON(nil, ecode.AccessDenied)
  110. return
  111. }
  112. if adminName, ok = data.(string); !ok {
  113. ctx.JSON(nil, ecode.ServerErr)
  114. return
  115. }
  116. if data, ok = ctx.Get("uid"); !ok {
  117. ctx.JSON(nil, ecode.AccessDenied)
  118. return
  119. }
  120. if adminID, ok = data.(int64); !ok {
  121. ctx.JSON(nil, ecode.ServerErr)
  122. return
  123. }
  124. ctx.JSON(nil, svc.RealnameAuditApply(ctx, arg, adminName, adminID))
  125. }
  126. func realnameReasonList(ctx *bm.Context) {
  127. var (
  128. arg = &model.ArgRealnameReasonList{}
  129. list []string
  130. total int
  131. err error
  132. )
  133. if err = ctx.Bind(arg); err != nil {
  134. return
  135. }
  136. if arg.PN <= 0 {
  137. arg.PN = 1
  138. }
  139. if arg.PS <= 0 || arg.PS > 100 {
  140. arg.PS = 20
  141. }
  142. if list, total, err = svc.RealnameReasonList(ctx, arg); err != nil {
  143. ctx.JSON(nil, err)
  144. return
  145. }
  146. res := map[string]interface{}{
  147. "list": list,
  148. "page": map[string]int{
  149. "num": arg.PN,
  150. "size": arg.PS,
  151. "total": total,
  152. },
  153. }
  154. ctx.JSON(res, nil)
  155. }
  156. func realnameSetReason(ctx *bm.Context) {
  157. var (
  158. arg = &model.ArgRealnameSetReason{}
  159. )
  160. if err := ctx.Bind(arg); err != nil {
  161. return
  162. }
  163. ctx.JSON(nil, svc.RealnameSetReason(ctx, arg))
  164. }
  165. func realnameImage(ctx *bm.Context) {
  166. var (
  167. arg = &model.ArgRealnameImage{}
  168. img []byte
  169. err error
  170. )
  171. if err = ctx.Bind(arg); err != nil {
  172. return
  173. }
  174. if img, err = svc.FetchRealnameImage(ctx, arg.Token); err != nil {
  175. ctx.JSON(nil, err)
  176. return
  177. }
  178. ctx.Bytes(http.StatusOK, http.DetectContentType(img), img)
  179. }
  180. func realnameImagePreview(ctx *bm.Context) {
  181. var (
  182. arg = &model.ArgRealnameImagePreview{}
  183. img []byte
  184. err error
  185. )
  186. if err = ctx.Bind(arg); err != nil {
  187. return
  188. }
  189. if arg.BorderSize <= 0 {
  190. arg.BorderSize = 1000
  191. }
  192. if img, err = svc.RealnameImagePreview(ctx, arg.Token, arg.BorderSize); err != nil {
  193. ctx.JSON(nil, err)
  194. return
  195. }
  196. ctx.Bytes(http.StatusOK, http.DetectContentType(img), img)
  197. }
  198. func realnameSearchCard(ctx *bm.Context) {
  199. var (
  200. arg = &model.ArgRealnameSearchCard{}
  201. err error
  202. )
  203. if err = ctx.Bind(arg); err != nil {
  204. return
  205. }
  206. if len(arg.Cards) > 50 {
  207. err = ecode.RequestErr
  208. return
  209. }
  210. ctx.JSON(svc.RealnameSearchCard(ctx, arg.Cards, arg.CardType, arg.Country))
  211. }
  212. func realnameUnbind(ctx *bm.Context) {
  213. var (
  214. arg = &model.ArgMid{}
  215. adminName string
  216. adminID int64
  217. data interface{}
  218. ok bool
  219. err error
  220. )
  221. if err = ctx.Bind(arg); err != nil {
  222. return
  223. }
  224. if data, ok = ctx.Get("username"); !ok {
  225. ctx.JSON(nil, ecode.AccessDenied)
  226. return
  227. }
  228. if adminName, ok = data.(string); !ok {
  229. ctx.JSON(nil, ecode.ServerErr)
  230. return
  231. }
  232. if data, ok = ctx.Get("uid"); !ok {
  233. ctx.JSON(nil, ecode.AccessDenied)
  234. return
  235. }
  236. if adminID, ok = data.(int64); !ok {
  237. ctx.JSON(nil, ecode.ServerErr)
  238. return
  239. }
  240. ctx.JSON(nil, svc.RealnameUnbind(ctx, arg.Mid, adminName, adminID))
  241. }
  242. func realnameExport(ctx *bm.Context) {
  243. arg := &model.ArgMids{}
  244. if err := ctx.Bind(arg); err != nil {
  245. return
  246. }
  247. if len(arg.Mid) > 1000 {
  248. ctx.JSON(nil, ecode.RequestErr)
  249. return
  250. }
  251. realnameExports, err := svc.RealnameExcel(ctx, arg.Mid)
  252. if err != nil {
  253. ctx.JSON(nil, err)
  254. return
  255. }
  256. data := make([][]string, 0, len(realnameExports))
  257. data = append(data, []string{"用户uid", "用户名", "昵称", "姓名", "手机号", "证件类型", "证件号"})
  258. for _, user := range realnameExports {
  259. fields := []string{
  260. strconv.FormatInt(user.Mid, 10),
  261. user.UserID,
  262. user.Uname,
  263. user.Realname,
  264. user.Tel,
  265. model.CardTypeString(user.CardType),
  266. avoidescape(user.CardNum),
  267. }
  268. data = append(data, fields)
  269. }
  270. buf := bytes.NewBuffer(nil)
  271. w := csv.NewWriter(buf)
  272. for _, record := range data {
  273. if err := w.Write(record); err != nil {
  274. ctx.JSON(nil, err)
  275. return
  276. }
  277. }
  278. w.Flush()
  279. res := buf.Bytes()
  280. ctx.Writer.Header().Set("Content-Type", "application/csv")
  281. ctx.Writer.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s.csv", "实名认证导出"))
  282. ctx.Writer.Write([]byte("\xEF\xBB\xBF")) // 写 UTF-8 的 BOM 头,别删,删了客服就找上门了
  283. ctx.Writer.Write(res)
  284. }
  285. func avoidescape(in string) string {
  286. return fmt.Sprintf("%s,", in)
  287. }
  288. func realnameSubmit(ctx *bm.Context) {
  289. arg := &model.ArgRealnameSubmit{}
  290. if err := ctx.Bind(arg); err != nil {
  291. return
  292. }
  293. ctx.JSON(nil, svc.RealnameSubmit(ctx, arg))
  294. }
  295. func realnameFileUpload(c *bm.Context) {
  296. arg := &model.ArgMid{}
  297. if err := c.Bind(arg); err != nil {
  298. return
  299. }
  300. mid := arg.Mid
  301. defer c.Request.Form.Del("img") // 防止日志不出现
  302. c.Request.ParseMultipartForm(32 << 20)
  303. imgBytes, err := func() ([]byte, error) {
  304. img := c.Request.FormValue("img")
  305. if img != "" {
  306. log.Info("Succeeded to parse img file from form value: mid: %d, length: %d", mid, len(img))
  307. return []byte(img), nil
  308. }
  309. log.Warn("Failed to parse img file from form value, fallback to form file: mid: %d", mid)
  310. f, _, err := c.Request.FormFile("img")
  311. if err != nil {
  312. return nil, errors.Wrapf(err, "parse img form file: mid: %d", mid)
  313. }
  314. defer f.Close()
  315. data, err := ioutil.ReadAll(f)
  316. if err != nil {
  317. return nil, errors.Wrapf(err, "read img form file: mid: %d", mid)
  318. }
  319. if len(data) <= 0 {
  320. return nil, errors.Wrapf(err, "form file data: mid: %d, length: %d", mid, len(data))
  321. }
  322. log.Info("Succeeded to parse file from form file: mid: %d, length: %d", mid, len(data))
  323. return data, nil
  324. }()
  325. if err != nil {
  326. log.Error("Failed to parse realname upload file: mid: %d: %+v", mid, err)
  327. c.JSON(nil, ecode.RequestErr)
  328. return
  329. }
  330. var resData struct {
  331. SRC string `json:"token"`
  332. }
  333. if resData.SRC, err = svc.RealnameFileUpload(c, arg.Mid, imgBytes); err != nil {
  334. log.Error("%+v", err)
  335. c.JSON(nil, err)
  336. return
  337. }
  338. c.JSON(resData, nil)
  339. }