quesManager.go 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. package quesManager
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "log"
  6. qu "qfw/util"
  7. mgdb "qfw/util/mongodb"
  8. "regexp"
  9. "strconv"
  10. "strings"
  11. "time"
  12. "github.com/go-xweb/xweb"
  13. "github.com/tealeg/xlsx"
  14. "gopkg.in/mgo.v2/bson"
  15. )
  16. type QuesM struct {
  17. *xweb.Action
  18. managerQues xweb.Mapper `xweb:"/center/managerQues"` //问题管理
  19. saveNewQues xweb.Mapper `xweb:"/center/question/saveNewQues"` //新建问题
  20. saveFeedbackSug xweb.Mapper `xweb:"/center/question/saveFeedbackSug"` //保存反馈意见
  21. closeQues xweb.Mapper `xweb:"/center/question/closeQues"` //关闭问题
  22. quesfile xweb.Mapper `xweb:"/center/question/quesfile"` //批量导入问题
  23. }
  24. const role_admin, role_examine, role_dev = 3, 2, 1 //管理员,审核员,开发员
  25. var REG = regexp.MustCompile(".*/(.+)\\.html.*")
  26. func (q *QuesM) ManagerQues() {
  27. if q.Method() == "POST" {
  28. start, _ := q.GetInteger("start")
  29. limit, _ := q.GetInteger("length")
  30. draw, _ := q.GetInteger("draw")
  31. searchStr := q.GetString("search[value]") //搜索内容
  32. search := strings.TrimSpace(searchStr)
  33. state, _ := q.GetInteger("state") //问题状态
  34. introStage, _ := q.GetInteger("introStage") //引入阶段
  35. //log.Println("start:", start, " limit:", limit, " draw:", draw, " search:", search, " state", state, " introStage", introStage)
  36. query := bson.M{}
  37. if state >= 0 && introStage >= 0 { //同时满足问题状态和引入阶段
  38. query = bson.M{
  39. "i_state": state,
  40. "i_introStage": introStage,
  41. }
  42. } else if state < 0 && introStage >= 0 { //仅仅搜索满足引入阶段,不搜索问题状态
  43. query = bson.M{
  44. "i_introStage": introStage,
  45. }
  46. } else if state >= 0 && introStage < 0 { //仅仅搜索满足问题状态,不搜索引入阶段
  47. query = bson.M{
  48. "i_state": state,
  49. }
  50. }
  51. if search != "" {
  52. query["$or"] = []interface{}{
  53. bson.M{"s_title": bson.M{"$regex": search}},
  54. bson.M{"s_id": bson.M{"$regex": search}},
  55. bson.M{"s_errFiled": bson.M{"$regex": search}},
  56. }
  57. }
  58. sort := `{"%s":%d}`
  59. orderIndex := q.GetString("order[0][column]")
  60. orderName := q.GetString(fmt.Sprintf("columns[%s][data]", orderIndex))
  61. orderType := 1
  62. if q.GetString("order[0][dir]") != "asc" {
  63. orderType = -1
  64. }
  65. sort = fmt.Sprintf(sort, orderName, orderType)
  66. ques := *mgdb.Find("question", query, sort, nil, false, start, limit)
  67. count := mgdb.Count("question", query)
  68. page := start / 10
  69. if ques != nil {
  70. for k, v := range ques {
  71. v["num"] = k + 1 + page*10
  72. i_state := v["i_state"]
  73. i_introStage := v["i_introStage"]
  74. if i_state == 0 { //未处理
  75. v["i_state"] = "未处理"
  76. } else if i_state == 1 { //已处理
  77. v["i_state"] = "已处理"
  78. } else if i_state == 2 { //暂不处理
  79. v["i_state"] = "暂不处理"
  80. } else if i_state == 4 { //关闭
  81. v["i_state"] = "关闭"
  82. }
  83. if i_introStage == 0 { //爬虫抓取阶段
  84. v["i_introStage"] = "爬虫抓取"
  85. } else if i_introStage == 1 { //数据抽取阶段
  86. v["i_introStage"] = "数据抽取"
  87. } else if i_introStage == 2 { //数据分类阶段
  88. v["i_introStage"] = "数据分类"
  89. }
  90. v["i_time"] = time.Unix(v["i_time"].(int64), 0).Format("2006-01-02 15:04:05")
  91. }
  92. }
  93. //log.Println("ques:", ques)
  94. q.ServeJson(map[string]interface{}{"draw": draw, "data": ques, "recordsFiltered": count, "recordsTotal": count})
  95. } else {
  96. q.Render("question.html")
  97. }
  98. }
  99. //新建问题
  100. func (q *QuesM) SaveNewQues() {
  101. auth := qu.IntAll(q.GetSession("auth"))
  102. if auth != role_admin {
  103. q.ServeJson("没有权限")
  104. return
  105. }
  106. title := q.GetString("info")
  107. id := q.GetString("id")
  108. addr := q.GetString("addr")
  109. introStageStr := q.GetString("intro")
  110. errFiled := q.GetString("errFiled")
  111. name := q.GetString("name")
  112. descript := q.GetString("descript")
  113. if id == "" { //解析地址
  114. id = getId(addr)
  115. } else if addr == "" { //加密id
  116. addr = getAddr(id)
  117. }
  118. log.Println("Save id:", id, " addr:", addr)
  119. if id == "" || addr == "" {
  120. q.ServeJson(map[string]interface{}{
  121. "state": "err",
  122. })
  123. return
  124. }
  125. newQues := make(map[string]interface{})
  126. newQues["s_title"] = title //标题
  127. newQues["s_id"] = id //id
  128. newQues["s_href"] = addr //地址
  129. introStage := -1
  130. if introStageStr == "grab" {
  131. introStage = 0
  132. } else if introStageStr == "extract" {
  133. introStage = 1
  134. } else if introStageStr == "classify" {
  135. introStage = 2
  136. }
  137. newQues["i_introStage"] = introStage //引入阶段
  138. newQues["s_errFiled"] = errFiled //错误字段
  139. newQues["s_feedbackPerson"] = name //反馈人
  140. newQues["s_descript"] = descript //描述
  141. newQues["i_time"] = time.Now().Unix() //录入时间
  142. newQues["i_state"] = 0 //问题状态(新建默认为未处理)
  143. newQues["s_sugesstion"] = "" //意见反馈
  144. //log.Println(title, id, addr, introStage, errFiled, name, descript, endTime)
  145. s := mgdb.Save("question", newQues)
  146. state := "err"
  147. if len(s) > 0 {
  148. state = "ok"
  149. }
  150. q.ServeJson(map[string]interface{}{
  151. "state": state,
  152. })
  153. }
  154. //保存反馈意见
  155. func (q *QuesM) SaveFeedbackSug() {
  156. _id := q.GetString("feedbackId")
  157. s_sugesstion := q.GetString("sug")
  158. state := q.GetString("feedbackState")
  159. i_state := -1
  160. if state == "未处理" {
  161. i_state = 0
  162. } else if state == "已处理" {
  163. i_state = 1
  164. } else if state == "暂不处理" {
  165. i_state = 2
  166. }
  167. query := bson.M{
  168. "_id": bson.ObjectIdHex(_id),
  169. }
  170. update := bson.M{
  171. "$set": bson.M{
  172. "i_state": i_state,
  173. "s_sugesstion": s_sugesstion,
  174. },
  175. }
  176. // log.Println(_id, s_sugesstion, state, query, update)
  177. b := mgdb.Update("question", query, update, false, false)
  178. log.Println("Save: ", _id, " 反馈意见", b)
  179. returnState := "false"
  180. if b {
  181. returnState = "ok"
  182. }
  183. q.ServeJson(map[string]interface{}{
  184. "state": returnState,
  185. })
  186. }
  187. //关闭问题
  188. func (q *QuesM) CloseQues() {
  189. _id := q.GetString("id")
  190. query := bson.M{
  191. "_id": bson.ObjectIdHex(_id),
  192. }
  193. update := bson.M{
  194. "$set": bson.M{
  195. "i_state": 4,
  196. },
  197. }
  198. b := mgdb.Update("question", query, update, false, false)
  199. log.Println("Close :", _id, " ", b)
  200. state := "false"
  201. if b {
  202. state = "ok"
  203. }
  204. q.ServeJson(map[string]interface{}{
  205. "state": state,
  206. })
  207. }
  208. //批量导入问题
  209. func (q *QuesM) Quesfile() {
  210. auth := qu.IntAll(q.GetSession("auth"))
  211. if auth != role_admin {
  212. q.ServeJson("没有权限")
  213. return
  214. }
  215. if q.Method() == "POST" {
  216. mf, _, err := q.GetFile("xlsx")
  217. errorinfo := map[string]interface{}{}
  218. if err == nil {
  219. binary, _ := ioutil.ReadAll(mf)
  220. xls, _ := xlsx.OpenBinary(binary)
  221. sheet := xls.Sheets[0]
  222. rows := sheet.Rows
  223. for rk, row := range rows {
  224. if rk != 0 { //excel表中第一行为标题字段舍去
  225. //log.Println(k, " row----", row)
  226. cells := row.Cells
  227. if len(cells) != 7 {
  228. errorinfo["data"+strconv.Itoa(rk)] = "第" + strconv.Itoa(rk+1) + "行数据填写不完整"
  229. continue
  230. }
  231. addr := cells[1].Value //地址
  232. id := cells[2].Value //id
  233. if addr == "" && id == "" {
  234. errorinfo["data"+strconv.Itoa(rk)] = "第" + strconv.Itoa(rk+1) + "行问题页面和信息id不能同时为空"
  235. continue
  236. }
  237. title := cells[0].Value //标题
  238. errField := cells[3].Value //错误字段
  239. descript := cells[4].Value //问题描述
  240. introStage := cells[5].Value //引入阶段
  241. feedbackPerson := cells[6].Value //反馈人
  242. if errField == "" || descript == "" || introStage == "" {
  243. errorinfo["data"+strconv.Itoa(rk)] = "第" + strconv.Itoa(rk+1) + "行数据填写不完整"
  244. continue
  245. }
  246. errStr := arrangeData(title, id, addr, errField, descript, introStage, feedbackPerson)
  247. if errStr != "" {
  248. errorinfo["data"+strconv.Itoa(rk)] = "第" + strconv.Itoa(rk+1) + "行" + errStr
  249. }
  250. //log.Println(title, descript, introStage, feedbackPerson)
  251. }
  252. }
  253. q.ServeJson(errorinfo)
  254. } else {
  255. q.ServeJson(false)
  256. }
  257. }
  258. }
  259. func arrangeData(title, id, addr, errField, descript, introStage, feedbackPerson string) string {
  260. fileQues := make(map[string]interface{})
  261. i_introStage := -1
  262. if id == "" { //解析地址
  263. id = getId(addr)
  264. } else if addr == "" { //加密id
  265. addr = getAddr(id)
  266. }
  267. if id == "" || addr == "" { //未解析成功
  268. return "网址或id解析错误"
  269. }
  270. fileQues["s_title"] = title //标题
  271. fileQues["s_id"] = id //id
  272. fileQues["s_href"] = addr //地址
  273. if introStage == "爬虫抓取阶段" {
  274. i_introStage = 0
  275. } else if introStage == "数据抽取阶段" {
  276. i_introStage = 1
  277. } else if introStage == "数据分类阶段" {
  278. i_introStage = 2
  279. }
  280. fileQues["i_introStage"] = i_introStage //引入阶段
  281. fileQues["s_errFiled"] = errField //错误字段
  282. fileQues["s_feedbackPerson"] = feedbackPerson //反馈人
  283. fileQues["s_descript"] = descript //描述
  284. fileQues["i_time"] = time.Now().Unix() //录入时间
  285. fileQues["i_state"] = 0 //问题状态(新建默认为未处理)
  286. fileQues["s_sugesstion"] = "" //意见反馈
  287. mgdb.Save("question", fileQues)
  288. return ""
  289. }
  290. //根据地址解析出id
  291. func getId(addr string) string {
  292. ins := REG.ReplaceAllString(addr, "$1")
  293. id := ""
  294. if ins != "" {
  295. res := qu.CommonDecodeArticle("content", ins)
  296. if res != nil && len(res) > 0 {
  297. id = res[0]
  298. }
  299. }
  300. return id
  301. }
  302. //根据id加密
  303. func getAddr(id string) string {
  304. addr := qu.EncodeArticleId2ByCheck(id)
  305. return "https://www.jianyu360.com/article/content/" + addr + ".html"
  306. }