server.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. const fs = require('fs')
  2. const path = require('path')
  3. const Koa = require('koa')
  4. const Router = require('koa-router')
  5. const bodyParser = require('koa-bodyparser')
  6. const LRU = require('lru-cache')
  7. const WebSocket = require('ws')
  8. const koaStatic = require('koa-static')
  9. const { routerOptions, lruOptions, watchFileOptions, filePath, ports } = require('./config')
  10. const { dataPath, reviewDataPath, staticPath } = filePath
  11. const { appPort, wsPort } = ports
  12. const router = new Router(routerOptions)
  13. const cache = new LRU(lruOptions)
  14. let STATIC_DATA = ''
  15. const readFile = () => {
  16. fs.readFile(dataPath, (err, buf) => {
  17. if (err) {
  18. console.error(err)
  19. return
  20. }
  21. STATIC_DATA = buf.toString().replace('\n', '').split(',')
  22. })
  23. }
  24. readFile()
  25. setInterval(() => {
  26. readFile()
  27. }, 60 * 60 * 24e3)
  28. fs.watchFile(dataPath, watchFileOptions, (curr, prev) => {
  29. if (curr.mtime !== prev.mtime) {
  30. STATIC_DATA = ''
  31. fs.readFile(dataPath, (err, buf) => {
  32. if (err) {
  33. console.error(err)
  34. return
  35. }
  36. STATIC_DATA = buf.toString().split(',')
  37. })
  38. }
  39. })
  40. const app = new Koa()
  41. const wss = new WebSocket.Server({ port: wsPort })
  42. app.use(koaStatic(path.join(__dirname, staticPath)))
  43. wss.on('connection', ws => {
  44. ws.on('message', msg => {
  45. if (msg) {
  46. try {
  47. const res = JSON.parse(msg)
  48. console.log('msg: ', res)
  49. if (res.code) {
  50. const list = cache.get(res.code)
  51. if (res.status === 'update') {
  52. const data = JSON.stringify({ data: list })
  53. wss.clients.forEach(client => {
  54. if (client.readyState === WebSocket.OPEN) {
  55. client.send(data)
  56. }
  57. })
  58. } else if (res.status === 'over') {
  59. list.forEach(el => {
  60. el.status = 1
  61. })
  62. const data = JSON.stringify({ data: list })
  63. wss.clients.forEach(client => {
  64. if (client.readyState === WebSocket.OPEN) {
  65. client.send(data)
  66. }
  67. })
  68. }
  69. }
  70. } catch (error) {
  71. console.error(error)
  72. }
  73. }
  74. })
  75. })
  76. app.use(bodyParser())
  77. // 判断是不是api
  78. // app.use((ctx, next) => {
  79. // const url = ctx.url
  80. // const isApi = /^\/api/.test(url)
  81. // ctx.$isApi = isApi
  82. // next()
  83. // })
  84. router.get('/list', (ctx, next) => {
  85. const { code } = ctx.query
  86. let data
  87. if (cache.has(code)) {
  88. data = cache.get(code)
  89. } else {
  90. const jsonData = STATIC_DATA || ''
  91. const len = 25
  92. const sum = jsonData.length - len
  93. const arr = new Array(25).fill(1).map(el => Math.floor(Math.random() * sum))
  94. const groupList = [1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0]
  95. data = new Array(25).fill(1).map((el, i) => {
  96. const del = groupList.length ? Math.floor(Math.random() * groupList.length) : 0
  97. const group = groupList.splice(del, 1)[0]
  98. return {
  99. text: jsonData.splice(arr[i], 1)[0],
  100. status: 0,
  101. group
  102. }
  103. })
  104. cache.set(code, data)
  105. }
  106. ctx.body = {
  107. code,
  108. data
  109. }
  110. })
  111. router.put('/status/:code', ctx => {
  112. const { params, request } = ctx
  113. const { code } = params
  114. const { index } = request.body
  115. const list = cache.get(code) || []
  116. if (!index && index !== 0) {
  117. throw new Error('index is not find')
  118. }
  119. if (!list || !list.length) {
  120. throw new Error('cache list is not find')
  121. }
  122. list[index].status = list[index].status ? 0 : 1
  123. cache.set(code, list)
  124. ctx.body = { success: true, msg: '更新成功', data: list[index] }
  125. })
  126. router.post('/words', ctx => {
  127. const { request } = ctx
  128. const { words = '' } = request.body
  129. const wordsList = words.split(',')
  130. const noExist = []
  131. const exist = wordsList.filter(el => {
  132. if (STATIC_DATA.indexOf(el) !== -1) {
  133. return true
  134. }
  135. noExist.push(el)
  136. return false
  137. })
  138. const pushNewWords = noExist.join(',')
  139. fs.appendFile(reviewDataPath, pushNewWords, (err) => {
  140. if (err) {
  141. console.error('appendFile error:', err)
  142. }
  143. })
  144. let body = {}
  145. if (exist.length) {
  146. body = { success: false, exist }
  147. } else {
  148. body = { success: true }
  149. }
  150. ctx.body = body
  151. })
  152. router.get('/reviews', ctx => {
  153. const buf = fs.readFileSync(reviewDataPath)
  154. const text = buf.toString()
  155. let list = []
  156. if (text) {
  157. list = text.split(',')
  158. }
  159. ctx.body = { success: true, list }
  160. })
  161. router.post('/reviews', ctx => {
  162. const { request } = ctx
  163. const { words = '' } = request.body
  164. const wordsList = words.split(',')
  165. const noExist = []
  166. const exist = wordsList.filter(el => {
  167. if (STATIC_DATA.indexOf(el) !== -1) {
  168. return true
  169. }
  170. if (el) {
  171. noExist.push(el)
  172. }
  173. return false
  174. })
  175. try {
  176. fs.appendFileSync(dataPath, `,${noExist.join(',')}`)
  177. fs.writeFile(reviewDataPath, '', err => {
  178. if (err) {
  179. return console.error('clear reviewData error:', err)
  180. }
  181. })
  182. if (exist.length) {
  183. ctx.body = { success: true, msg: `${exist.join(',')} 添加失败,词已存在` }
  184. } else {
  185. ctx.body = { success: true, msg: '添加成功' }
  186. }
  187. } catch (error) {
  188. console.error('appendFile error:', error)
  189. ctx.body = { success: false, msg: JSON.stringify(error) }
  190. }
  191. })
  192. app.use(router.routes()).use(router.allowedMethods())
  193. app.on('error', err => console.error(err))
  194. app.listen(appPort)
  195. console.log(`http://127.0.0.1:${appPort}`)