server.js 5.0 KB

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