DocumentSearchResult.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. package models
  2. import (
  3. "regexp"
  4. "strings"
  5. "time"
  6. "github.com/beego/beego/v2/client/orm"
  7. "github.com/beego/beego/v2/core/logs"
  8. "github.com/beego/beego/v2/server/web"
  9. )
  10. type DocumentSearchResult struct {
  11. DocumentId int `json:"doc_id"`
  12. DocumentName string `json:"doc_name"`
  13. // Identify 文档唯一标识
  14. Identify string `json:"identify"`
  15. Description string `json:"description"`
  16. Author string `json:"author"`
  17. ModifyTime time.Time `json:"modify_time"`
  18. CreateTime time.Time `json:"create_time"`
  19. BookId int `json:"book_id"`
  20. BookName string `json:"book_name"`
  21. BookIdentify string `json:"book_identify"`
  22. SearchType string `json:"search_type"`
  23. }
  24. var escape_re = regexp.MustCompile(`(?mi)(\bLIKE\s+\?)`)
  25. var escape_replace = "${1} ESCAPE '\\'"
  26. func need_escape(keyword string) bool {
  27. dbadapter, _ := web.AppConfig.String("db_adapter")
  28. if strings.EqualFold(dbadapter, "sqlite3") && (strings.Contains(keyword, "\\_") || strings.Contains(keyword, "\\%")) {
  29. return true
  30. }
  31. return false
  32. }
  33. func NewDocumentSearchResult() *DocumentSearchResult {
  34. return &DocumentSearchResult{}
  35. }
  36. // 分页全局搜索.
  37. func (m *DocumentSearchResult) FindToPager(keyword string, pageIndex, pageSize, memberId int) (searchResult []*DocumentSearchResult, totalCount int, err error) {
  38. o := orm.NewOrm()
  39. offset := (pageIndex - 1) * pageSize
  40. keyword = "%" + strings.Replace(keyword, " ", "%", -1) + "%"
  41. _need_escape := need_escape(keyword)
  42. escape_sql := func(sql string) string {
  43. if _need_escape {
  44. return escape_re.ReplaceAllString(sql, escape_replace)
  45. }
  46. return sql
  47. }
  48. if memberId <= 0 {
  49. sql1 := `SELECT count(doc.document_id) as total_count FROM md_documents AS doc
  50. LEFT JOIN md_books as book ON doc.book_id = book.book_id
  51. WHERE book.privately_owned = 0 AND (doc.document_name LIKE ? OR doc.release LIKE ?) `
  52. sql2 := `SELECT *
  53. FROM (
  54. SELECT
  55. doc.document_id,
  56. doc.modify_time,
  57. doc.create_time,
  58. doc.document_name,
  59. doc.identify,
  60. doc.release AS description,
  61. book.identify AS book_identify,
  62. book.book_name,
  63. rel.member_id,
  64. mdmb.account AS author,
  65. 'document' AS search_type
  66. FROM md_documents AS doc
  67. LEFT JOIN md_books AS book ON doc.book_id = book.book_id
  68. LEFT JOIN md_relationship AS rel ON book.book_id = rel.book_id AND rel.role_id = 0
  69. LEFT JOIN md_members AS mdmb ON rel.member_id = mdmb.member_id
  70. WHERE book.privately_owned = 0 AND (doc.document_name LIKE ? OR doc.release LIKE ?)
  71. UNION ALL
  72. SELECT
  73. book.book_id AS document_id,
  74. book.modify_time,
  75. book.create_time,
  76. book.book_name AS document_name,
  77. book.identify,
  78. book.description,
  79. book.identify AS book_identify,
  80. book.book_name,
  81. rel.member_id,
  82. mdmb.account AS author,
  83. 'book' AS search_type
  84. FROM md_books AS book
  85. LEFT JOIN md_relationship AS rel ON book.book_id = rel.book_id AND rel.role_id = 0
  86. LEFT JOIN md_members AS mdmb ON rel.member_id = mdmb.member_id
  87. WHERE book.privately_owned = 0 AND (book.book_name LIKE ? OR book.description LIKE ?)
  88. UNION ALL
  89. SELECT
  90. blog.blog_id AS document_id,
  91. blog.modify_time,
  92. blog.create_time,
  93. blog.blog_title as document_name,
  94. blog.blog_identify,
  95. blog.blog_release,
  96. blog.blog_identify,
  97. blog.blog_title as book_name,
  98. blog.member_id,
  99. mdmb.account,
  100. 'blog' AS search_type
  101. FROM md_blogs AS blog
  102. LEFT JOIN md_members AS mdmb ON blog.member_id = mdmb.member_id
  103. WHERE blog.blog_status = 'public' AND (blog.blog_release LIKE ? OR blog.blog_title LIKE ?)
  104. ) AS union_table
  105. ORDER BY create_time DESC
  106. LIMIT ? OFFSET ?;`
  107. err = o.Raw(escape_sql(sql1), keyword, keyword).QueryRow(&totalCount)
  108. if err != nil {
  109. logs.Error("查询搜索结果失败 -> ", err)
  110. return
  111. }
  112. sql3 := ` SELECT
  113. count(*)
  114. FROM md_blogs AS blog
  115. WHERE blog.blog_status = 'public' AND (blog.blog_release LIKE ? OR blog.blog_title LIKE ?);`
  116. c := 0
  117. err = o.Raw(escape_sql(sql3), keyword, keyword).QueryRow(&c)
  118. if err != nil {
  119. logs.Error("查询搜索结果失败 -> ", err)
  120. return
  121. }
  122. totalCount += c
  123. //查询项目的数量
  124. sql4 := `SELECT count(*) as total_count FROM md_books as book
  125. WHERE book.privately_owned = 0 AND (book.book_name LIKE ? OR book.description LIKE ?);`
  126. err = o.Raw(escape_sql(sql4), keyword, keyword).QueryRow(&c)
  127. if err != nil {
  128. logs.Error("查询搜索结果失败 -> ", err)
  129. return
  130. }
  131. totalCount += c
  132. _, err = o.Raw(escape_sql(sql2), keyword, keyword, keyword, keyword, keyword, keyword, pageSize, offset).QueryRows(&searchResult)
  133. if err != nil {
  134. logs.Error("查询搜索结果失败 -> ", err)
  135. return
  136. }
  137. } else {
  138. sql1 := `SELECT count(doc.document_id) as total_count FROM md_documents AS doc
  139. LEFT JOIN md_books as book ON doc.book_id = book.book_id
  140. LEFT JOIN md_relationship AS rel ON doc.book_id = rel.book_id AND rel.role_id = 0
  141. LEFT JOIN md_relationship AS rel1 ON doc.book_id = rel1.book_id AND rel1.member_id = ?
  142. left join (select * from (select book_id,team_member_id,role_id
  143. from md_team_relationship as mtr
  144. left join md_team_member as mtm on mtm.team_id=mtr.team_id and mtm.member_id=? order by role_id desc )as t group by t.role_id,t.team_member_id,t.book_id) as team
  145. on team.book_id = book.book_id
  146. WHERE (book.privately_owned = 0 OR rel1.relationship_id > 0 or team.team_member_id > 0) AND (doc.document_name LIKE ? OR doc.release LIKE ?);`
  147. sql2 := `SELECT *
  148. FROM (
  149. SELECT
  150. doc.document_id,
  151. doc.modify_time,
  152. doc.create_time,
  153. doc.document_name,
  154. doc.identify,
  155. doc.release AS description,
  156. book.identify AS book_identify,
  157. book.book_name,
  158. rel.member_id,
  159. mdmb.account AS author,
  160. 'document' AS search_type
  161. FROM md_documents AS doc
  162. LEFT JOIN md_books AS book ON doc.book_id = book.book_id
  163. LEFT JOIN md_relationship AS rel ON book.book_id = rel.book_id AND rel.role_id = 0
  164. LEFT JOIN md_members AS mdmb ON rel.member_id = mdmb.member_id
  165. LEFT JOIN md_relationship AS rel1 ON doc.book_id = rel1.book_id AND rel1.member_id = ?
  166. LEFT JOIN (SELECT *
  167. FROM (SELECT
  168. book_id,
  169. team_member_id,
  170. role_id
  171. FROM md_team_relationship AS mtr
  172. LEFT JOIN md_team_member AS mtm ON mtm.team_id = mtr.team_id AND mtm.member_id = ?
  173. ORDER BY role_id DESC) AS t
  174. GROUP BY t.role_id, t.team_member_id, t.book_id) AS team
  175. ON team.book_id = book.book_id
  176. WHERE (book.privately_owned = 0 OR rel1.relationship_id > 0 OR team.team_member_id > 0) AND
  177. (doc.document_name LIKE ? OR doc.release LIKE ?)
  178. UNION ALL
  179. SELECT
  180. book.book_id AS document_id,
  181. book.modify_time,
  182. book.create_time,
  183. book.book_name AS document_name,
  184. book.identify,
  185. book.description AS description,
  186. book.identify AS book_identify,
  187. book.book_name,
  188. rel.member_id,
  189. mdmb.account AS author,
  190. 'book' AS search_type
  191. FROM md_books AS book
  192. LEFT JOIN md_relationship AS rel ON book.book_id = rel.book_id AND rel.role_id = 0
  193. LEFT JOIN md_members AS mdmb ON rel.member_id = mdmb.member_id
  194. LEFT JOIN md_relationship AS rel1 ON book.book_id = rel1.book_id AND rel1.member_id = ?
  195. LEFT JOIN (SELECT *
  196. FROM (SELECT
  197. book_id,
  198. team_member_id,
  199. role_id
  200. FROM md_team_relationship AS mtr
  201. LEFT JOIN md_team_member AS mtm ON mtm.team_id = mtr.team_id AND mtm.member_id = ?
  202. ORDER BY role_id DESC) AS t
  203. GROUP BY t.role_id, t.team_member_id, t.book_id) AS team
  204. ON team.book_id = book.book_id
  205. WHERE (book.privately_owned = 0 OR rel1.relationship_id > 0 OR team.team_member_id > 0) AND
  206. (book.book_name LIKE ? OR book.description LIKE ?)
  207. UNION ALL
  208. SELECT
  209. blog.blog_id AS document_id,
  210. blog.modify_time,
  211. blog.create_time,
  212. blog.blog_title as document_name,
  213. blog.blog_identify as identify,
  214. blog.blog_release as description,
  215. blog.blog_identify AS book_identify,
  216. blog.blog_title as book_name,
  217. blog.member_id,
  218. mdmb.account,
  219. 'blog' AS search_type
  220. FROM md_blogs AS blog
  221. LEFT JOIN md_members AS mdmb ON blog.member_id = mdmb.member_id
  222. WHERE (blog.blog_status = 'public' OR blog.member_id = ?) AND blog.blog_type = 0 AND
  223. (blog.blog_release LIKE ? OR blog.blog_title LIKE ?)
  224. ) AS union_table
  225. ORDER BY create_time DESC
  226. LIMIT ? OFFSET ?;`
  227. err = o.Raw(escape_sql(sql1), memberId, memberId, keyword, keyword).QueryRow(&totalCount)
  228. if err != nil {
  229. return
  230. }
  231. sql3 := ` SELECT
  232. count(*)
  233. FROM md_blogs AS blog
  234. WHERE (blog.blog_status = 'public' OR blog.member_id = ?) AND blog.blog_type = 0 AND
  235. (blog.blog_release LIKE ? OR blog.blog_title LIKE ?);`
  236. c := 0
  237. err = o.Raw(escape_sql(sql3), memberId, keyword, keyword).QueryRow(&c)
  238. if err != nil {
  239. logs.Error("查询搜索结果失败 -> ", err)
  240. return
  241. }
  242. totalCount += c
  243. sql4 := `SELECT count(*) as total_count FROM md_books as book
  244. LEFT JOIN md_relationship AS rel ON book.book_id = rel.book_id AND rel.role_id = 0
  245. LEFT JOIN md_relationship AS rel1 ON book.book_id = rel1.book_id AND rel1.member_id = ?
  246. left join (select * from (select book_id,team_member_id,role_id
  247. from md_team_relationship as mtr
  248. left join md_team_member as mtm on mtm.team_id=mtr.team_id and mtm.member_id=? order by role_id desc )as t group by t.role_id,t.team_member_id,t.book_id) as team
  249. on team.book_id = book.book_id
  250. WHERE (book.privately_owned = 0 OR rel1.relationship_id > 0 or team.team_member_id > 0) AND (book.book_name LIKE ? OR book.description LIKE ?);`
  251. err = o.Raw(escape_sql(sql4), memberId, memberId, keyword, keyword).QueryRow(&c)
  252. if err != nil {
  253. logs.Error("查询搜索结果失败 -> ", err)
  254. return
  255. }
  256. totalCount += c
  257. _, err = o.Raw(escape_sql(sql2), memberId, memberId, keyword, keyword, memberId, memberId, keyword, keyword, memberId, keyword, keyword, pageSize, offset).QueryRows(&searchResult)
  258. if err != nil {
  259. return
  260. }
  261. }
  262. return
  263. }
  264. // 项目内搜索.
  265. func (m *DocumentSearchResult) SearchDocument(keyword string, bookId int) (docs []*DocumentSearchResult, err error) {
  266. o := orm.NewOrm()
  267. sql := "SELECT * FROM md_documents WHERE book_id = ? AND (document_name LIKE ? OR `release` LIKE ?) "
  268. keyword = "%" + keyword + "%"
  269. _need_escape := need_escape(keyword)
  270. escape_sql := func(sql string) string {
  271. if _need_escape {
  272. return escape_re.ReplaceAllString(sql, escape_replace)
  273. }
  274. return sql
  275. }
  276. _, err = o.Raw(escape_sql(sql), bookId, keyword, keyword).QueryRows(&docs)
  277. return
  278. }
  279. // 所有项目搜索.
  280. func (m *DocumentSearchResult) SearchAllDocument(keyword string) (docs []*DocumentSearchResult, err error) {
  281. o := orm.NewOrm()
  282. sql := "SELECT * FROM md_documents WHERE (document_name LIKE ? OR `release` LIKE ?) "
  283. keyword = "%" + keyword + "%"
  284. _need_escape := need_escape(keyword)
  285. escape_sql := func(sql string) string {
  286. if _need_escape {
  287. return escape_re.ReplaceAllString(sql, escape_replace)
  288. }
  289. return sql
  290. }
  291. _, err = o.Raw(escape_sql(sql), keyword, keyword).QueryRows(&docs)
  292. return
  293. }