issue.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. package aftersale
  2. import (
  3. "time"
  4. "zhiyuan/pkg/app"
  5. "zhiyuan/pkg/config"
  6. "zhiyuan/pkg/db"
  7. orderParam "zhiyuan/pkg/param/order"
  8. "zhiyuan/pkg/utils"
  9. "zhiyuan/services/admin"
  10. "zhiyuan/services/aftersale"
  11. "zhiyuan/services/aftersale/order"
  12. "zhiyuan/services/form"
  13. "zhiyuan/services/material/brand"
  14. "zhiyuan/services/material/pkg"
  15. "zhiyuan/services/user"
  16. "github.com/gin-gonic/gin"
  17. "github.com/tealeg/xlsx/v3"
  18. )
  19. func IssueList(c *gin.Context) {
  20. type IssueList struct {
  21. ID int `json:"id"`
  22. IssueName string `json:"issue_name"`
  23. }
  24. issueList := make([]*IssueList, 0)
  25. aftersale.GetIssueList(nil, nil, app.Page{}, &issueList)
  26. app.Success(c, issueList)
  27. }
  28. func IssueAdd(c *gin.Context) {
  29. var form form.ASIssueAdd
  30. if app.Bind(c, &form) != nil {
  31. return
  32. }
  33. if id, err := aftersale.AddIssue(form); err != nil {
  34. app.Error(c, err.Error())
  35. return
  36. } else {
  37. app.Success(c, gin.H{"id": id})
  38. }
  39. }
  40. func IssueEdit(c *gin.Context) {
  41. id := utils.StrTo(c.Param("id")).MustInt()
  42. if id <= 0 {
  43. app.Error(c, "类型id有误")
  44. return
  45. }
  46. var form form.ASIssueAdd
  47. if app.Bind(c, &form) != nil {
  48. return
  49. }
  50. if _, err := aftersale.EditIssue(form, id); err != nil {
  51. app.ErrorMsg(c, err.Error(), nil)
  52. return
  53. }
  54. app.Success(c, nil)
  55. }
  56. func IssueExport(c *gin.Context) {
  57. where := map[string]string{
  58. "where": "o.deleted_at=0",
  59. "_order_by": "id desc",
  60. }
  61. params := make(map[string]interface{})
  62. // leader
  63. leaderID := utils.ToInt(c.Query("leader_id"))
  64. if leaderID > 0 {
  65. where["where"] += " AND o.leader={{leader_id}}"
  66. params["leader_id"] = leaderID
  67. }
  68. // state
  69. state := utils.ToInt(c.Query("state"))
  70. if state != 0 {
  71. where["where"] += " AND if(o.state=90,90,if(o.is_force=0,o.state,100))={{state}}"
  72. params["state"] = state
  73. }
  74. // is_force
  75. isForce := utils.ToInt(c.Query("is_force"))
  76. if isForce != 0 {
  77. if isForce == 2 {
  78. where["where"] += " AND o.is_force!=0"
  79. } else {
  80. where["where"] += " AND o.is_force={{isForce}}"
  81. params["isForce"] = isForce - 1
  82. }
  83. }
  84. // type
  85. typ := utils.ToInt(c.Query("type"))
  86. if typ != 0 {
  87. where["where"] += " AND o.type={{type}}"
  88. params["type"] = typ - 1
  89. }
  90. // address
  91. address := c.Query("address")
  92. if address != "" {
  93. where["where"] += " AND o.address LIKE {{address}}"
  94. params["address"] = "%" + address + "%"
  95. }
  96. // inWarranty
  97. inWarranty := utils.ToInt(c.Query("in_warranty"))
  98. if utils.IsContain([]int{0, 1}, inWarranty) {
  99. where["where"] += " AND o.in_warranty={{in_warranty}}"
  100. params["in_warranty"] = inWarranty
  101. }
  102. // user
  103. user1 := c.Query("user")
  104. if user1 != "" {
  105. where["where"] += " AND (o.link_name LIKE {{user}} OR o.link_phone LIKE {{user}})"
  106. params["user"] = "%" + user1 + "%"
  107. }
  108. // state
  109. finish_state := utils.ToInt(c.Query("finish_state"))
  110. if finish_state != 0 {
  111. switch finish_state {
  112. case 1:
  113. where["where"] += " AND (o.finish_state=1)"
  114. break
  115. case 2:
  116. where["where"] += " AND (o.finish_state=2)"
  117. break
  118. case 3:
  119. where["where"] += " AND (o.finish_state=1 AND UNIX_TIMESTAMP()<=o.end_time)"
  120. break
  121. case 4:
  122. where["where"] += " AND (o.finish_state=1 AND UNIX_TIMESTAMP()>o.end_time)"
  123. break
  124. case 5:
  125. where["_order_by"] = "o.incomplete_count desc"
  126. break
  127. }
  128. }
  129. createdDate := c.QueryArray("created_date[]")
  130. if createdDate != nil && len(createdDate) == 2 {
  131. where["where"] += " AND o.created_at BETWEEN {{created_at_min}} AND {{created_at_max}}"
  132. params["created_at_min"] = utils.DateParseUnix(createdDate[0], "Y-m-d")
  133. params["created_at_max"] = utils.DateParseUnix(createdDate[1], "Y-m-d") + 86399
  134. }
  135. if adminInfo := admin.GetAdminCache(c.GetInt("adminID")); adminInfo.SiteID > 0 {
  136. where["where"] += " AND (o.site_id={{site_id}} or o.site_id=0)"
  137. params["site_id"] = adminInfo.SiteID
  138. }
  139. type House struct {
  140. ID int `json:"id"`
  141. Address string `json:"address"`
  142. Designer int `json:"designer"`
  143. DesignerName string `json:"designer_name"`
  144. District int `json:"district"`
  145. DistrictName string `json:"district_name"`
  146. Supervisor int `json:"supervisor"`
  147. SupervisorName string `json:"supervisor_name"`
  148. ProjectManager int `json:"project_manager"`
  149. ProjectManagerName string `json:"project_manager_name"`
  150. ProjectLeader int `json:"project_leader"`
  151. ProjectLeaderName string `json:"project_leader_name"`
  152. ProjectStart string `json:"project_start"`
  153. ProjectEnd string `json:"project_end"`
  154. WarrantyStart string `json:"warranty_start"`
  155. PkgID int `json:"pkg_id"`
  156. }
  157. type Visit struct {
  158. OrderID int `json:"order_id"`
  159. Content string `json:"content"`
  160. FinishedAt string `json:"finished_at"`
  161. }
  162. type Detail struct {
  163. OrderID int `json:"order_id"`
  164. Address string `json:"address"`
  165. Content string `json:"content"`
  166. }
  167. type Repair struct {
  168. OrderID int `json:"order_id"`
  169. WorkerName string `json:"worker_name"`
  170. }
  171. type Orders struct {
  172. ID int `json:"id"`
  173. CreatedAt string `json:"created_at"`
  174. LinkName string `json:"link_name"`
  175. LinkPhone string `json:"link_phone"`
  176. UserID int `json:"user_id"`
  177. InWarranty int `json:"in_warranty"`
  178. Leader int `json:"leader"`
  179. LeaderName string `json:"leader_name"`
  180. HouseID int `json:"house_id"`
  181. House *House `json:"house"`
  182. Repair *Repair `json:"repair"`
  183. Director int `json:"director"`
  184. DirectorName string `json:"director_name"`
  185. IssueID int `json:"issue_id"`
  186. IssueName string `json:"issue_name"`
  187. IssueDesc string `json:"issue_desc"`
  188. Brand int `json:"brand"`
  189. BrandName string `json:"brand_name"`
  190. Detail *Detail `json:"detial"`
  191. Visit string `json:"visit"`
  192. IsForce int `json:"is_force"`
  193. }
  194. orderList := make([]*Orders, 0)
  195. err := order.GetIssueWidthOrder(where, params, &orderList)
  196. houseIds := make([]int, 0)
  197. orderIds := make([]int, 0)
  198. userIds := make([]int, 0)
  199. adminIds := make([]int, 0)
  200. brandIds := make([]int, 0)
  201. for _, v := range orderList {
  202. houseIds = append(houseIds, v.HouseID)
  203. orderIds = append(orderIds, v.ID)
  204. userIds = append(userIds, v.UserID)
  205. adminIds = append(adminIds, v.Leader)
  206. if v.Brand > 0 {
  207. brandIds = utils.AppendUniqueInt(brandIds, v.Brand)
  208. }
  209. }
  210. houseMap := make(map[int]*House, 0)
  211. if len(houseIds) > 0 {
  212. houseList := make([]*House, 0)
  213. user.GetHouseList(map[string]interface{}{"id in": houseIds}, nil, app.Page{}, &houseList)
  214. for _, v := range houseList {
  215. adminIds = append(adminIds, v.Designer, v.Supervisor, v.ProjectManager, v.ProjectLeader)
  216. houseMap[v.ID] = v
  217. }
  218. }
  219. userMap := make(map[int]string, 0)
  220. userSiteMap := make(map[int]int, 0)
  221. if len(userIds) > 0 {
  222. userList, _ := user.GetList(map[string]interface{}{"id in": userIds}, nil, app.Page{}, nil)
  223. for _, v := range userList {
  224. userMap[v.ID] = v.Name
  225. userSiteMap[v.ID] = v.SiteID
  226. }
  227. }
  228. type AdminInfo struct {
  229. Username string `json:"username"`
  230. State int `json:"state"`
  231. }
  232. adminMap := make(map[int]AdminInfo, 0)
  233. if len(adminIds) > 0 {
  234. adminList, _ := admin.GetAdmins(map[string]interface{}{"id in": adminIds}, nil, app.Page{}, nil)
  235. for _, v := range adminList {
  236. adminMap[v.ID] = AdminInfo{Username: v.Username, State: v.State}
  237. }
  238. }
  239. for k, v := range houseMap {
  240. if v.Designer > 0 {
  241. v.DesignerName = adminMap[v.Designer].Username
  242. }
  243. if v.Supervisor > 0 {
  244. v.SupervisorName = adminMap[v.Supervisor].Username
  245. }
  246. if v.ProjectLeader > 0 {
  247. v.ProjectLeaderName = adminMap[v.ProjectLeader].Username
  248. }
  249. if v.ProjectManager > 0 {
  250. v.ProjectManagerName = adminMap[v.ProjectManager].Username
  251. }
  252. if v.Supervisor > 0 {
  253. if adminMap[v.Supervisor].State == -1 {
  254. v.SupervisorName = "离职项目经理"
  255. } else {
  256. v.SupervisorName = adminMap[v.Supervisor].Username
  257. }
  258. }
  259. houseMap[k] = v
  260. }
  261. brandMap := make(map[int]string)
  262. if len(brandIds) > 0 {
  263. if brandList, err := brand.GetList(map[string]interface{}{"id in": brandIds}, nil, app.Page{}, nil); err == nil {
  264. for _, v := range brandList {
  265. brandMap[v.ID] = v.BrandName
  266. }
  267. }
  268. }
  269. issueDirectorMap := orderParam.GetIssueDirectorMap()
  270. issueMap := aftersale.GetIssueMapByCache()
  271. for _, v := range orderList {
  272. if v.Leader > 0 {
  273. v.LeaderName = adminMap[v.Leader].Username
  274. }
  275. if v.Director > 0 {
  276. v.DirectorName = issueDirectorMap[v.Director]
  277. }
  278. if v.IssueID > 0 {
  279. v.IssueName = issueMap[v.IssueID]
  280. }
  281. if v.Brand > 0 {
  282. v.BrandName = brandMap[v.Brand]
  283. }
  284. v.House = houseMap[v.HouseID]
  285. }
  286. wb := xlsx.NewFile()
  287. filename := "售后问题汇总表-" + db.ToString(time.Now().Unix()) + ".xlsx"
  288. fullPath := config.Cfg.App.ExportPath + filename
  289. styleBold := utils.GetCommonStyle(utils.StyleCfg{IsBold: true, FontSize: 10})
  290. styleCommon := utils.GetCommonStyle(utils.StyleCfg{FontSize: 9})
  291. sh, err := wb.AddSheet("Sheet1")
  292. if err != nil {
  293. app.Error(c, err.Error())
  294. return
  295. }
  296. var row *xlsx.Row
  297. height := float64(30)
  298. row = utils.AddRow(sh, utils.Row{Height: height})
  299. utils.AddCell(row, utils.Cell{Value: "售后问题汇总表", HMerge: 22, Style: styleBold})
  300. sh = utils.SetColWidth(sh, []float64{5, 5, 10, 15, 15, 15, 15, 20, 10, 15, 10, 10, 10, 10, 10, 10, 10, 10, 15, 15, 15, 15})
  301. row = utils.AddRow(sh, utils.Row{Height: height})
  302. utils.AddCell(row, utils.Cell{Value: "序号", Style: styleBold})
  303. utils.AddCell(row, utils.Cell{Value: "级别", Style: styleBold})
  304. utils.AddCell(row, utils.Cell{Value: "工地性质", Style: styleBold})
  305. utils.AddCell(row, utils.Cell{Value: "开工日期", Style: styleBold})
  306. utils.AddCell(row, utils.Cell{Value: "竣工", Style: styleBold})
  307. utils.AddCell(row, utils.Cell{Value: "保修卡时间", Style: styleBold})
  308. utils.AddCell(row, utils.Cell{Value: "报修时间", Style: styleBold})
  309. utils.AddCell(row, utils.Cell{Value: "工地名称", Style: styleBold})
  310. utils.AddCell(row, utils.Cell{Value: "业主姓名", Style: styleBold})
  311. utils.AddCell(row, utils.Cell{Value: "联系电话", Style: styleBold})
  312. utils.AddCell(row, utils.Cell{Value: "设计师", Style: styleBold})
  313. utils.AddCell(row, utils.Cell{Value: "工程主管", Style: styleBold})
  314. utils.AddCell(row, utils.Cell{Value: "队长", Style: styleBold})
  315. utils.AddCell(row, utils.Cell{Value: "项目经理", Style: styleBold})
  316. utils.AddCell(row, utils.Cell{Value: "渠道", Style: styleBold})
  317. utils.AddCell(row, utils.Cell{Value: "报修人", Style: styleBold})
  318. utils.AddCell(row, utils.Cell{Value: "年份", Style: styleBold})
  319. utils.AddCell(row, utils.Cell{Value: "是否过保修", Style: styleBold})
  320. utils.AddCell(row, utils.Cell{Value: "责任人", Style: styleBold})
  321. utils.AddCell(row, utils.Cell{Value: "问题原因", Style: styleBold})
  322. utils.AddCell(row, utils.Cell{Value: "详细原因", Style: styleBold})
  323. utils.AddCell(row, utils.Cell{Value: "主材", Style: styleBold})
  324. utils.AddCell(row, utils.Cell{Value: "套餐", Style: styleBold})
  325. utils.AddCell(row, utils.Cell{Value: "强制完结", Style: styleBold})
  326. type PkgList struct {
  327. ID int `json:"id"`
  328. PkgName string `json:"pkg_name"`
  329. }
  330. pkgList := make([]*PkgList, 0)
  331. pkg.GetPkgs(nil, nil, app.Page{}, &pkgList)
  332. pkgMap := make(map[int]string)
  333. for _, v := range pkgList {
  334. pkgMap[v.ID] = v.PkgName
  335. }
  336. for k, v := range orderList {
  337. v.CreatedAt = utils.DateS(v.CreatedAt, "YYYY/MM/DD")
  338. year := ""
  339. if v.House.ProjectStart == "0" {
  340. v.House.ProjectStart = ""
  341. } else {
  342. v.House.ProjectStart = utils.DateS(v.House.ProjectStart, "YYYY/MM/DD")
  343. }
  344. if v.House.ProjectEnd == "0" {
  345. v.House.ProjectEnd = ""
  346. } else {
  347. //year = utils.DateS(v.House.ProjectEnd, "YYYY")
  348. v.House.ProjectEnd = utils.DateS(v.House.ProjectEnd, "YYYY/MM/DD")
  349. }
  350. if v.House.WarrantyStart == "0" {
  351. v.House.WarrantyStart = ""
  352. } else {
  353. year = utils.DateS(v.House.WarrantyStart, "YYYY")
  354. v.House.WarrantyStart = utils.DateS(v.House.WarrantyStart, "YYYY/MM/DD")
  355. }
  356. row = utils.AddRow(sh, utils.Row{Height: height})
  357. utils.AddCell(row, utils.Cell{Value: utils.ToStr(k + 1), Style: styleCommon})
  358. utils.AddCell(row, utils.Cell{Value: "一级", Style: styleCommon})
  359. utils.AddCell(row, utils.Cell{Value: "全包", Style: styleCommon})
  360. utils.AddCell(row, utils.Cell{Value: v.House.ProjectStart, Style: styleCommon})
  361. utils.AddCell(row, utils.Cell{Value: v.House.ProjectEnd, Style: styleCommon})
  362. utils.AddCell(row, utils.Cell{Value: v.House.WarrantyStart, Style: styleCommon})
  363. utils.AddCell(row, utils.Cell{Value: v.CreatedAt, Style: styleCommon})
  364. utils.AddCell(row, utils.Cell{Value: v.House.Address, Style: styleCommon})
  365. utils.AddCell(row, utils.Cell{Value: v.LinkName, Style: styleCommon})
  366. utils.AddCell(row, utils.Cell{Value: v.LinkPhone, Style: styleCommon})
  367. utils.AddCell(row, utils.Cell{Value: v.House.DesignerName, Style: styleCommon})
  368. utils.AddCell(row, utils.Cell{Value: v.House.ProjectManagerName, Style: styleCommon})
  369. utils.AddCell(row, utils.Cell{Value: v.House.ProjectLeaderName, Style: styleCommon})
  370. utils.AddCell(row, utils.Cell{Value: v.House.SupervisorName, Style: styleCommon})
  371. utils.AddCell(row, utils.Cell{Value: "售后", Style: styleCommon})
  372. utils.AddCell(row, utils.Cell{Value: "客户", Style: styleCommon})
  373. utils.AddCell(row, utils.Cell{Value: year, Style: styleCommon})
  374. inWarranty := "是"
  375. if v.InWarranty > 0 {
  376. inWarranty = "否"
  377. }
  378. utils.AddCell(row, utils.Cell{Value: inWarranty, Style: styleCommon})
  379. utils.AddCell(row, utils.Cell{Value: v.DirectorName, Style: styleCommon})
  380. utils.AddCell(row, utils.Cell{Value: v.IssueName, Style: styleCommon})
  381. utils.AddCell(row, utils.Cell{Value: v.IssueDesc, Style: styleCommon})
  382. utils.AddCell(row, utils.Cell{Value: v.BrandName, Style: styleCommon})
  383. utils.AddCell(row, utils.Cell{Value: pkgMap[houseMap[v.HouseID].PkgID], Style: styleCommon})
  384. forceTypes := []string{"正常", "强制完结", "业主不交尾款", "业主不点击确认", "业主自行问题", "报修后联系不上业主", "维修完后联系不上业主"}
  385. isForce := forceTypes[v.IsForce]
  386. utils.AddCell(row, utils.Cell{Value: isForce, Style: styleCommon})
  387. }
  388. if err := wb.Save(fullPath); err != nil {
  389. app.Error(c, err.Error())
  390. return
  391. }
  392. app.Success(c, gin.H{"path": "export/" + filename, "filename": filename})
  393. }