DocumentSearchResult.go 12 KB

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