list.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. <template>
  2. <div class="app-container">
  3. <el-form ref="searchArr" :inline="true" :model="search" class="demo-form-inline">
  4. <el-form-item label="用戶名">
  5. <el-input v-model="search.nickname" clearable />
  6. </el-form-item>
  7. <el-form-item label="日期">
  8. <el-date-picker
  9. v-model="search.startTime"
  10. type="date"
  11. value-format="yyyy-MM-dd"
  12. placeholder="选择日期"
  13. />
  14. </el-form-item>
  15. <el-form-item label="序號">
  16. <el-input v-model="search.sign" clearable />
  17. </el-form-item>
  18. <el-form-item label="版本">
  19. <el-input v-model="search.version" clearable />
  20. </el-form-item>
  21. <el-form-item label="完成度">
  22. <el-input v-model="search.schedule" clearable />
  23. </el-form-item>
  24. <el-form-item>
  25. <el-button type="primary" size="small" @click="nextPage()">搜素</el-button>
  26. </el-form-item>
  27. <el-form-item>
  28. <el-button type="primary" size="small" @click="download()">下載</el-button>
  29. </el-form-item>
  30. <el-form-item>
  31. <el-button type="primary" size="small" @click="deleteC()">删除</el-button>
  32. </el-form-item>
  33. <el-form-item>
  34. <el-button type="primary" size="small" @click="back()">返回</el-button>
  35. </el-form-item>
  36. </el-form>
  37. <el-table
  38. ref="gamelog"
  39. v-loading="listLoading"
  40. :data="list"
  41. element-loading-text="Loading"
  42. border
  43. fit
  44. highlight-current-row
  45. @sort-change="sortChange"
  46. >
  47. <el-table-column
  48. type="selection"
  49. align="center"
  50. width="40"
  51. />
  52. <el-table-column align="center" label="ID" width="55">
  53. <template slot-scope="scope">
  54. {{ scope.row.id }}
  55. </template>
  56. </el-table-column>
  57. <el-table-column sortable align="center" prop="nickname" label="用戶名">
  58. <template slot-scope="scope">
  59. {{ scope.row.nickname }}
  60. </template>
  61. </el-table-column>
  62. <el-table-column sortable align="center" prop="sign" label="序號">
  63. <template slot-scope="scope">
  64. {{ scope.row.sign }}
  65. </template>
  66. </el-table-column>
  67. <el-table-column sortable align="center" prop="startTime" label="日期">
  68. <template slot-scope="scope">
  69. {{ scope.row.startTime.substring(0,10) }}
  70. </template>
  71. </el-table-column>
  72. <el-table-column sortable align="center" prop="version" label="版本">
  73. <template slot-scope="scope">
  74. {{ scope.row.version }}
  75. </template>
  76. </el-table-column>
  77. <el-table-column sortable align="center" prop="version" label="正確率">
  78. <template slot-scope="scope">
  79. {{ (scope.row.realCorrectRate != null ? (scope.row.realCorrectRate * 100).toFixed(2) : 0) + "" }}
  80. </template>
  81. </el-table-column>
  82. <el-table-column sortable align="center" prop="version" label="錯誤率">
  83. <template slot-scope="scope">
  84. {{ ((scope.row.wrongRate * 100).toFixed(2)) + "" }}
  85. </template>
  86. </el-table-column>
  87. <el-table-column sortable align="center" prop="version" label="錯失率">
  88. <template slot-scope="scope">
  89. {{ ((scope.row.missRate * 100).toFixed(2)) + "" }}
  90. </template>
  91. </el-table-column>
  92. <el-table-column sortable align="center" prop="version" label="反應時間">
  93. <template slot-scope="scope">
  94. {{ (changeTwoDecimal_f(scope.row.avgReaction)) + "" }}
  95. </template>
  96. </el-table-column>
  97. <el-table-column align="center" sortable label="主观正確率" prop="realCorrectRate">
  98. <template slot-scope="scope">
  99. {{ scope.row.correctRate * 100 }}
  100. </template>
  101. </el-table-column>
  102. <el-table-column align="center" sortable label="主觀信度" prop="realCorrectRate">
  103. <template slot-scope="scope">
  104. {{ scope.row.confidence * 100 }}
  105. </template>
  106. </el-table-column>
  107. <el-table-column sortable align="center" prop="startTime" label="開始時間">
  108. <template slot-scope="scope">
  109. {{ scope.row.startTime.substring(11,19) }}
  110. </template>
  111. </el-table-column>
  112. <el-table-column sortable align="center" prop="endTime" label="完成時間">
  113. <template slot-scope="scope">
  114. {{ scope.row.endTime.substring(11,19) }}
  115. </template>
  116. </el-table-column>
  117. <el-table-column sortable align="center" prop="sign" label="完成度">
  118. <template slot-scope="scope">
  119. {{ scope.row.schedule * 100 }}%
  120. </template>
  121. </el-table-column>
  122. <el-table-column align="center" label="設備號">
  123. <template slot-scope="scope">
  124. {{ scope.row.deviceId }}
  125. </template>
  126. </el-table-column>
  127. <el-table-column align="center" label="操作" width="260">
  128. <template slot-scope="{row}">
  129. <el-button v-if="checkPermission(['admin'])" size="mini" @click="openDel(row)">
  130. 删除
  131. </el-button>
  132. <el-button v-if="checkPermission(['admin'])" size="mini" @click="openDetail(row)">
  133. 查看詳情
  134. </el-button>
  135. </template>
  136. </el-table-column>
  137. </el-table>
  138. <pagination
  139. :total="page.total"
  140. :page.sync="page.pageNum"
  141. :limit.sync="page.size"
  142. @pagination="nextPage"
  143. />
  144. <el-dialog title="遊戲詳情" :visible.sync="gameVisible" width="80%">
  145. <span>用戶名:{{ detailNickName }}</span>>
  146. <span>序號:{{ detailId }}}</span>>
  147. <span>日期:{{ detailDate }}}</span>>
  148. <span>版本:{{ detailVersion }}}</span>>
  149. <span>正確率:{{ detailCorrectRate != null ? detailCorrectRate * 100 : 0 }}, </span>
  150. <span>錯誤率:{{ (getDetailWrongRate() * 100).toFixed(2) }}, </span>
  151. <span>錯失率:{{ (getDetailMissRate() * 100).toFixed(2) }}, </span>
  152. <span>反應時間:{{ changeTwoDecimal_f(detailReaction) }}</span>
  153. <el-table :data="detail" size="mini">
  154. <el-table-column
  155. type="index"
  156. width="50">
  157. </el-table-column>
  158. <!-- <el-table-column align="center" label="用戶名">-->
  159. <!-- <template slot-scope="scope">-->
  160. <!-- {{ scope.row.nickname }}-->
  161. <!-- </template>-->
  162. <!-- </el-table-column>-->
  163. <!-- <el-table-column align="center" label="日期">-->
  164. <!-- <template slot-scope="scope">-->
  165. <!-- {{ scope.row.startTime.substring(0,10) }}-->
  166. <!-- </template>-->
  167. <!-- </el-table-column>-->
  168. <!-- <el-table-column align="center" label="版本">-->
  169. <!-- <template slot-scope="scope">-->
  170. <!-- {{ scope.row.version }}-->
  171. <!-- </template>-->
  172. <!-- </el-table-column>-->
  173. <!-- <el-table-column align="center" label="序號">-->
  174. <!-- <template slot-scope="scope">-->
  175. <!-- {{ scope.row.sign }}-->
  176. <!-- </template>-->
  177. <!-- </el-table-column>-->
  178. <!-- <el-table-column align="center" label="開始時間">-->
  179. <!-- <template slot-scope="scope">-->
  180. <!-- {{ scope.row.startTime.substring(11,19) }}-->
  181. <!-- </template>-->
  182. <!-- </el-table-column>-->
  183. <!-- <el-table-column align="center" label="完成時間">-->
  184. <!-- <template slot-scope="scope">-->
  185. <!-- {{ scope.row.endTime.substring(11,19) }}-->
  186. <!-- </template>-->
  187. <!-- </el-table-column>-->
  188. <!-- <el-table-column align="center" label="完成度">-->
  189. <!-- <template slot-scope="scope">-->
  190. <!-- {{ scope.row.schedule*100 }}%-->
  191. <!-- </template>-->
  192. <!-- </el-table-column>-->
  193. <el-table-column align="center" label="抽取數字">
  194. {{ detailSelected }}
  195. </el-table-column>
  196. <el-table-column align="center" label="出現數字">
  197. <template slot-scope="scope">
  198. {{ scope.row.showNum }}
  199. </template>
  200. </el-table-column>
  201. <el-table-column align="center" label="用戶回答">
  202. <template slot-scope="scope">
  203. {{ scope.row.answer === 1 ? 'press' :'N-press' }}
  204. </template>
  205. </el-table-column>
  206. <el-table-column align="center" label="true/false/omission">
  207. <template slot-scope="scope">
  208. {{ scope.row.correct === 1 ? 'true' : scope.row.correct === 2 ? 'false' : 'omission' }}
  209. </template>
  210. </el-table-column>
  211. <el-table-column align="center" label="反應時間">
  212. <template slot-scope="scope">
  213. {{ scope.row.reaction }}
  214. </template>
  215. </el-table-column>
  216. </el-table>
  217. </el-dialog>
  218. </div>
  219. </template>
  220. <script>
  221. import Pagination from '@/components/Pagination'
  222. import { Message } from 'element-ui'
  223. import checkPermission from '@/utils/permission'
  224. import GameApi from '@/api/game'
  225. export default {
  226. name: 'List',
  227. components: { Pagination },
  228. data() {
  229. return {
  230. list: [],
  231. search: {},
  232. order: {},
  233. detail: [],
  234. page: { total: 0, size: 0, pageNum: 0 },
  235. listLoading: false,
  236. gameVisible: false,
  237. detailSelected: '',
  238. detailCorrectRate: 0.0,
  239. detailReaction: 0,
  240. detailNickName: '',
  241. detailId: 0,
  242. detailDate: '',
  243. detailVersion: ''
  244. }
  245. },
  246. created() {
  247. this.nextPage()
  248. },
  249. mounted() {
  250. },
  251. methods: {
  252. checkPermission,
  253. openDel(r) {
  254. this.$confirm('此操作将永久id爲 ' + r.id + '的遊戲記錄, 是否继续?', '提示', {
  255. confirmButtonText: '確定',
  256. cancelButtonText: '取消',
  257. type: 'warning'
  258. }).then(() => {
  259. this.delGameLog(r)
  260. }).catch(() => {
  261. this.$message({
  262. type: 'info',
  263. message: '已取消删除'
  264. })
  265. })
  266. },
  267. delGameLog(r) {
  268. GameApi.del({ id: r.id }).then(response => {
  269. Message({
  270. message: '刪除成功',
  271. type: 'success',
  272. duration: 2 * 1000
  273. })
  274. if (response.code === 200) {
  275. this.nextPage()
  276. }
  277. })
  278. },
  279. changeTwoDecimal_f(x) {
  280. var f_x = parseFloat(x)
  281. if (isNaN(f_x)) {
  282. return 0
  283. }
  284. f_x = Math.round(x * 100) / 100
  285. var s_x = f_x.toString()
  286. var pos_decimal = s_x.indexOf('.')
  287. if (pos_decimal < 0) {
  288. pos_decimal = s_x.length
  289. s_x += '.'
  290. }
  291. while (s_x.length <= pos_decimal + 2) {
  292. s_x += '0'
  293. }
  294. return s_x
  295. },
  296. openDetail(r) {
  297. GameApi.detail({ id: r.id }).then(response => {
  298. if (response.code === 200) {
  299. this.detail = response.data
  300. this.detailSelected = r.selected
  301. this.detailCorrectRate = r.realCorrectRate
  302. this.detailReaction = this.getAvgReaction()
  303. this.detailNickName = r.nickname
  304. this.detailDate = r.startTime.substring(0, 10)
  305. this.detailId = r.sign
  306. this.detailVersion = r.version
  307. this.gameVisible = true
  308. }
  309. })
  310. },
  311. nextPage() {
  312. this.listLoading = true
  313. GameApi.getList({ page: this.page.pageNum, search: JSON.stringify(this.search), order: JSON.stringify(this.order) }).then(response => {
  314. this.list = response.data.list
  315. this.page.total = response.data.total
  316. setTimeout(() => {
  317. this.listLoading = false
  318. }, 1 * 1000)
  319. })
  320. },
  321. getDetailWrongRate() {
  322. if (this.detail) {
  323. let size = 0
  324. this.detail.forEach((item, index) => {
  325. if (item.correct === 2) {
  326. size += 1
  327. }
  328. })
  329. return size === 0 ? 0 : size / this.detail.length
  330. } else {
  331. return 0
  332. }
  333. },
  334. getDetailMissRate() {
  335. if (this.detail) {
  336. let size = 0
  337. this.detail.forEach((item, index) => {
  338. if (item.correct === 3) {
  339. size += 1
  340. }
  341. })
  342. return size === 0 ? 0 : size / this.detail.length
  343. } else {
  344. return 0
  345. }
  346. },
  347. getAvgReaction() {
  348. if (this.detail) {
  349. let size = 0
  350. let react = 0
  351. this.detail.forEach((item, index) => {
  352. if (item.reaction !== -1) {
  353. react += item.reaction
  354. size += 1
  355. }
  356. })
  357. return react === 0 ? 0 : react / size
  358. } else {
  359. return 0
  360. }
  361. },
  362. sortChange(column) {
  363. this.order[column.prop] = column.order
  364. this.nextPage()
  365. },
  366. download() {
  367. GameApi.download({ search: JSON.stringify(this.search), order: JSON.stringify(this.order) }).then(response => {
  368. const url = window.URL.createObjectURL(new Blob([response.data]))
  369. const link = document.createElement('a')
  370. link.style.display = 'none'
  371. link.href = url
  372. link.setAttribute('download', response.headers['filename'])
  373. document.body.appendChild(link)
  374. link.click()
  375. })
  376. },
  377. deleteC() {
  378. const ids = this.$refs.gamelog.selection.map(function(elem, index) {
  379. return elem.id
  380. }).join(',')
  381. GameApi.deleteIds({ ids: ids }).then(response => {
  382. this.nextPage()
  383. })
  384. },
  385. back() {
  386. this.search = {}
  387. this.order = {}
  388. this.nextPage()
  389. }
  390. }
  391. }
  392. </script>
  393. <style scoped>
  394. </style>