index.vue 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996
  1. <template>
  2. <div class="pb_content" style="background: #f0f2f5;" v-loading="loading">
  3. <div class="pb_content_body" style="position: relative; margin: 0">
  4. <div class="right">
  5. <div class="courseTop">
  6. <div class="stepsNav">
  7. <el-breadcrumb separator-class="el-icon-arrow-right">
  8. <el-breadcrumb-item :to="{
  9. path:
  10. '/test?userid=' +
  11. userid +
  12. '&oid=' +
  13. oid +
  14. '&org=' +
  15. org +
  16. '&role=' +
  17. role,
  18. }">表单管理</el-breadcrumb-item>
  19. <el-breadcrumb-item>
  20. <span style="color: rgb(15, 126, 255)">查看表单</span>
  21. </el-breadcrumb-item>
  22. </el-breadcrumb>
  23. </div>
  24. <div class="r_pub_button_retrun" @click="retrunCourse">返回</div>
  25. </div>
  26. <div class="step_box" ref="stepBox" v-loading="pdfLoading">
  27. <div class="test_title">
  28. <div class="left">
  29. <div class="title">{{ testJson.title }}</div>
  30. <div class="info">
  31. <div class="info_box" v-if="testJson.typeN">
  32. <span>类型:</span>
  33. <span>{{ testJson.typeN }}</span>
  34. </div>
  35. <div class="info_box">
  36. <span>填写范围:</span>
  37. <span>{{ testJson.juriP ? testJson.juriP : '所有人' }}</span>
  38. </div>
  39. <div class="info_box" v-if="testJson.overtime">
  40. <span>截止时间:</span>
  41. <span>{{ testJson.overtime }}</span>
  42. </div>
  43. </div>
  44. </div>
  45. <div class="right">
  46. <div class="data_box">
  47. <span>提交数量</span>
  48. <span><span class="big">{{ works.length }}</span>份</span>
  49. </div>
  50. <div class="data_box" v-if="testJson.juriP">
  51. <span>表单完成率</span>
  52. <span><span class="big">{{ (iscount / pcount * 100).toFixed(0) }}</span>%</span>
  53. </div>
  54. <div class="data_box" v-if="testJson.juriP">
  55. <span>未完成人数</span>
  56. <span><span class="big">{{ pcount - iscount }}</span></span>
  57. </div>
  58. <div class="btn_box" @click="dialogVisibleShare = true">
  59. <span></span>
  60. <span>提醒</span>
  61. </div>
  62. </div>
  63. </div>
  64. <div class="search_nav">
  65. <div class="right">
  66. <span :class="{ active: stype == 1 }" @click="checkDataType(1)">按题目查看</span>
  67. <span :class="{ active: stype == 2 }" @click="checkDataType(2)">按人员查看</span>
  68. <span :class="{ active: stype == 3 }" @click="checkDataType(3)" v-show="false">按数量查看</span>
  69. </div>
  70. <div class="left">
  71. <div style="margin-right: 10px;position: relative;" v-if="stype == 2 || stype == 3">
  72. <el-input v-model="courseName" class="student_input" placeholder="请输入需要搜索的姓名"></el-input>
  73. <span class="serach_icon" @click="searchCourse"></span>
  74. </div>
  75. <div class="btnA" v-if="stype == 1 && !pdfLoading" @click="exportPDF">导出PDF</div>
  76. <div class="btnA" v-if="stype == 2" @mouseenter="btnDisplay = true" @mouseleave="btnDisplay = false">
  77. 导出数据
  78. <div v-show="btnDisplay" class="buttonBox">
  79. <div type="primary" @click="exportExcel">下载汇总表格</div>
  80. <div type="primary" @click="exportAllWord">导出人员数据</div>
  81. </div>
  82. </div>
  83. <div class="btnA" v-if="stype == 3" @click="exportAllWord2">导出人员数据</div>
  84. </div>
  85. </div>
  86. <div class="title_content" v-if="stype == 1">
  87. <div class="title_box" v-if="!testArray.length"
  88. style="display: flex;align-items: center;justify-content: center;height: 500px;">
  89. 暂无内容
  90. </div>
  91. <div class="title_box" v-for="(item, index) in testArray" :key="index">
  92. <div class="title">
  93. <el-tooltip :content="selectType(item)" placement="top" effect="dark">
  94. <span class="test_icon"
  95. :class="{ test_icon_check: item.type == 1 && item.atype == 2, test_icon_checkO: item.type == 1 && item.atype == 1, test_icon_gap: item.type == 3, test_icon_file: item.type == 5 }"></span>
  96. </el-tooltip>
  97. <span>{{ item.title }}</span>
  98. </div>
  99. <div class="detail" v-if="item.detail">{{ item.detail }}</div>
  100. <div class="content1" v-if="item.type == 1">
  101. <div class="left">
  102. <div class="title">
  103. <span>选项</span>
  104. <span>小计</span>
  105. <span>比例</span>
  106. </div>
  107. <div class="data" v-for="(data, index2) in item.array" :key="index + '-' + index2">
  108. <span>
  109. <el-tooltip :content="data.name" placement="top" effect="dark">
  110. <!-- content to trigger tooltip here -->
  111. <span>{{ data.name }}</span>
  112. </el-tooltip>
  113. </span>
  114. <span>{{ data.count }}</span>
  115. <span>
  116. <el-progress style="display: flex;align-items: center;" :stroke-width="12" color="#3681fc"
  117. :percentage="data.count ? parseFloat(((data.count / item.count) * 100).toFixed(2)) : 0"></el-progress>
  118. </span>
  119. </div>
  120. </div>
  121. <div class="right">
  122. <checkPie :dataJ="item.array"></checkPie>
  123. </div>
  124. </div>
  125. <div class="content2" v-if="item.type == 3">
  126. <div class="left">
  127. <div class="title">
  128. <span>序号</span>
  129. <span>词频</span>
  130. <span>答案文本</span>
  131. </div>
  132. <div class="data" v-for="(data, index2) in item.array" :key="index + '-' + index2">
  133. <span>{{ index2 + 1 }}</span>
  134. <span>{{ data.count }}次</span>
  135. <el-tooltip :content="data.name" placement="top" effect="dark">
  136. <!-- content to trigger tooltip here -->
  137. <span>{{ data.name }}</span>
  138. </el-tooltip>
  139. </div>
  140. </div>
  141. <div class="right">
  142. <wordcloud :data="item.array" nameKey="name" valueKey="count" :showTooltip="false"
  143. :wordClick="wordClickHandler">
  144. </wordcloud>
  145. </div>
  146. </div>
  147. <div class="content3" v-if="item.type == 5">
  148. <div class="file" v-for="(file, index2) in item.array" :key="index + '-' + index2"
  149. @click.stop="checkFile(file)">
  150. <img class="download" src="../../../../assets/icon/fileIcon/download.png"
  151. @click.stop="downloadFile(file)" :style="{ right: '10px' }" />
  152. <img class="img" :src="wordIcon" alt="" v-if="file.type == 1" />
  153. <img class="img" :src="videoIcon" alt="" v-if="file.type == 2" />
  154. <img class="img" :src="file.url" alt="" v-if="file.type == 3" />
  155. <img class="img" :src="wordIcon" alt="" v-if="file.type == 4" />
  156. <img class="img" :src="fileIcon" alt="" v-if="file.type == 5" />
  157. <div class="name">
  158. <el-tooltip :content="file.name" placement="top" effect="dark">
  159. <span>{{ file.name }}</span>
  160. </el-tooltip>
  161. </div>
  162. </div>
  163. </div>
  164. <div class="content4" v-if="item.type == 6">
  165. <div class="out_box" v-for="(item, index) in item.courseArray" :key="index + '-' + index2">
  166. <div class="tup">
  167. <img :src="item.cover != null && item.cover != ''
  168. ? JSON.parse(item.cover).length > 0
  169. ? JSON.parse(item.cover)[0].url
  170. : mr
  171. : mr
  172. " alt />
  173. <div class="bottom_box">
  174. <div>
  175. <el-tooltip :content="item.title" popper-class="text_tooltip" placement="top" effect="dark">
  176. <span>{{ item.title }}</span>
  177. </el-tooltip>
  178. </div>
  179. <div class="kc_t">
  180. <span>{{ item.username }}</span>
  181. <span>{{ item.state == 1 ? '阶段模式' : item.state == 2 ? '任务模式' : '极简模式' }}</span>
  182. </div>
  183. <div class="kc_time">
  184. <span style="color: #717C8D">创建日期:</span>{{ item.time }}
  185. </div>
  186. <div class="kc_time">
  187. <span style="color: #717C8D">修改日期:</span>{{ item.update_at }}
  188. </div>
  189. </div>
  190. </div>
  191. </div>
  192. <!-- <div class="courses" v-for="(courses, index2) in item.array" :key="index + '-' + index2">
  193. {{ courses }}
  194. </div> -->
  195. </div>
  196. </div>
  197. </div>
  198. <div class="table_content" v-if="stype == 2">
  199. <el-table class="el-table" ref="table" :data="worksArray" border :fit="true" :key="2" v-loading="isLoading"
  200. style="width: 100%" :header-cell-style="{ background: '#f1f1f1', fontSize: '17px' }"
  201. @filter-change="handleFilterChange">
  202. <el-table-column fixed label="序号" width="80px" align="left">
  203. <template slot-scope="scope">
  204. {{ scope.$index + 1 }}
  205. </template>
  206. </el-table-column>
  207. <el-table-column fixed prop="name" label="提交人" width="120px" align="left">
  208. </el-table-column>
  209. <el-table-column prop="time" label="提交时间" width="170px" align="left">
  210. </el-table-column>
  211. <el-table-column v-for="(item, index) in chapters" :key="index" :label="item.json.title"
  212. :min-width="item.type == 5 ? 200 : 150" align="left" :filters="item.type == 1 ? item.nameFilters : null"
  213. :filter-method="item.type == 1 ? (value, row) => { return filterName(value, row, index) } : null"
  214. :filter-placement="item.type == 1 ? filterPlacement : null">
  215. <template slot-scope="scope">
  216. <div v-if="scope.row.array[index].type == 1" style="display: flex; flex-wrap: wrap;">
  217. <span class="answer_type" v-for="(answer2, index2) in scope.row.array[index].json.answer2"
  218. :key="index + '-' + index2">{{ scope.row.array[index].json.array[answer2].option }}</span>
  219. </div>
  220. <div v-if="scope.row.array[index].type == 3" style="display: flex; flex-wrap: wrap;">
  221. {{ scope.row.array[index].json.answer2 }}
  222. </div>
  223. <div v-if="scope.row.array[index].type == 5" style="display: flex; flex-wrap: wrap;"
  224. class="table_file">
  225. <div class="file" v-for="(file, index2) in scope.row.array[index].json.file"
  226. :key="index + '-' + index2" @click.stop="checkFile(file)">
  227. <img class="download" src="../../../../assets/icon/fileIcon/download.png"
  228. @click.stop="downloadFile(file)" :style="{ right: '10px' }" />
  229. <img class="img" :src="wordIcon" alt="" v-if="file.type == 1" />
  230. <img class="img" :src="videoIcon" alt="" v-if="file.type == 2" />
  231. <img class="img" :src="file.url" alt="" v-if="file.type == 3" />
  232. <img class="img" :src="wordIcon" alt="" v-if="file.type == 4" />
  233. <img class="img" :src="fileIcon" alt="" v-if="file.type == 5" />
  234. <div class="name">
  235. <el-tooltip :content="file.name" placement="top" effect="dark">
  236. <span>{{ file.name }}</span>
  237. </el-tooltip>
  238. </div>
  239. </div>
  240. </div>
  241. <div v-if="scope.row.array[index].type == 6" style="display: flex; flex-wrap: wrap;">
  242. {{ scope.row.array[index].json.answer2 }}
  243. </div>
  244. <div v-if="scope.row.array[index].type == 7" style="display: flex; flex-wrap: wrap;">
  245. {{ getScore(scope.row.array[index].json) }}
  246. </div>
  247. </template>
  248. </el-table-column>
  249. <el-table-column label="操作" width="300px" fixed="right">
  250. <template slot-scope="scope">
  251. <el-button @click="getTest(scope.row)" type="primary" size="small">查看</el-button>
  252. <el-button @click="setWordHtml(scope.row)" type="primary" size="small">导出答题信息</el-button>
  253. <el-button @click="deleteTest(scope.row.id)" type="primary" size="small">删除</el-button>
  254. </template>
  255. </el-table-column>
  256. </el-table>
  257. </div>
  258. <div class="table_content" v-if="stype == 3">
  259. <div class="student_table">
  260. <el-table ref="table" :data="tableData" border :fit="true" v-loading="isLoading" style="width: 100%"
  261. :header-cell-style="{ background: '#f1f1f1', fontSize: '17px' }" :row-class-name="tableRowClassName">
  262. <el-table-column prop="username" label="提交人" min-width="15" align="center">
  263. </el-table-column>
  264. <el-table-column prop="time" label="提交时间" min-width="15" align="center">
  265. </el-table-column>
  266. <el-table-column label="是否批改" min-width="15" align="center">
  267. <template slot-scope="scope">
  268. <div>{{ scope.row.type == 3 ? '是' : '否' }}</div>
  269. </template>
  270. </el-table-column>
  271. <el-table-column label="操作" width="300px">
  272. <template slot-scope="scope">
  273. <el-button @click="getTest(scope.row)" type="primary" size="small">查看</el-button>
  274. <el-button @click="setWordHtml2(scope.row)" type="primary" size="small">导出答题信息</el-button>
  275. <el-button @click="deleteTest(scope.row.id)" type="primary" size="small">删除</el-button>
  276. </template>
  277. </el-table-column>
  278. </el-table>
  279. </div>
  280. <div class="student_page">
  281. <el-pagination background layout="prev, pager, next" :page-size="pageSize" :total="total"
  282. @current-change="handleCurrentChange">
  283. </el-pagination>
  284. </div>
  285. </div>
  286. </div>
  287. </div>
  288. </div>
  289. <share-box :testJson="testJson" :dialogVisibleShare.sync="dialogVisibleShare"></share-box>
  290. <wpdf :dialogVisiblePdf.sync="dialogVisiblePdf" :url="wurl"></wpdf>
  291. <wVideo :dialogVisibleVideo.sync="dialogVisibleVideo" :url="wurl"></wVideo>
  292. <wOffice :dialogVisibleOffice.sync="dialogVisibleOffice" :url="wurl"></wOffice>
  293. </div>
  294. </template>
  295. <script>
  296. import shareBox from '../shareBox/index.vue'
  297. import videoIcon from '../../../../assets/icon/fileIcon/isVideo.png'
  298. import wordIcon from '../../../../assets/icon/fileIcon/isWord.png'
  299. import fileIcon from '../../../../assets/icon/fileIcon/word2.png'
  300. import wVideo from "../file/wVideo.vue";
  301. import wpdf from "../file/wPdf2.vue";
  302. import wOffice from "../file/wOffice.vue";
  303. import wordcloud from 'vue-wordcloud';
  304. import checkPie from '../data/checkPie.vue';
  305. import { downloadPDF } from '../../../tools/pdf'
  306. import JSZip from "jszip";
  307. import FileSaver from "file-saver";
  308. import XLSX from "xlsx-js-style";
  309. export default {
  310. components: {
  311. shareBox,
  312. wVideo,
  313. wpdf,
  314. wOffice,
  315. checkPie,
  316. wordcloud
  317. },
  318. data() {
  319. return {
  320. userid: this.$route.query.userid,
  321. oid: this.$route.query.oid,
  322. org: this.$route.query.org,
  323. role: this.$route.query.role,
  324. cid: this.$route.query.cid,
  325. title: "",
  326. testType: [],
  327. see: false,
  328. cJson: [],
  329. loading: false,
  330. look: "",
  331. tableHeight: 500,
  332. isLoading: false,
  333. pageSize: 10,
  334. total: 0,
  335. page: 1,
  336. tableData: [],
  337. testJson: {},
  338. works: [],
  339. iscount: 0,
  340. pcount: 0,
  341. stype: 1,
  342. courseName: "",
  343. dialogVisibleShare: false,
  344. worksArray: [],
  345. testArray: [],
  346. options2: {
  347. 1: "选择题",
  348. // 2: "问答题",
  349. 3: "问答题",
  350. 4: "添加文档",
  351. 5: "附件"
  352. },
  353. videoIcon: videoIcon,
  354. wordIcon: wordIcon,
  355. fileIcon: fileIcon,
  356. dialogVisiblePdf: false,
  357. dialogVisibleVideo: false,
  358. dialogVisibleOffice: false,
  359. wurl: "",
  360. chapters: [],
  361. filterPlacement: 'bottom-end',
  362. pdfLoading: false,
  363. btnDisplay: false
  364. };
  365. },
  366. watch: {},
  367. computed: {
  368. // vcWords() {
  369. // return function (array) {
  370. // let _array = [];
  371. // if (array.length) {
  372. // for (var i = 0; i < array.length; i++) {
  373. // _array.push(
  374. // {
  375. // text: array[i].name,
  376. // weight: array[i].count,
  377. // }
  378. // )
  379. // }
  380. // }
  381. // console.log(_array);
  382. // return array.length ? _array : [];
  383. // };
  384. // },
  385. getScore() {
  386. return function (item) {
  387. let array = []
  388. for (var i = parseInt(item.small); i <= parseInt(item.big); i++) {
  389. array.push(i)
  390. }
  391. return item.answer2 ? array[item.answer2] : ''
  392. };
  393. },
  394. selectType() {
  395. return function (item) {
  396. if (item.type == 1 && item.atype == 2) {
  397. return '多选题'
  398. } else if (item.type == 1 && item.atype == 1) {
  399. return '单选题'
  400. } else if (item.type == 3) {
  401. return '问答题'
  402. } else if (item.type == 5) {
  403. return '附件'
  404. }
  405. };
  406. }
  407. },
  408. methods: {
  409. filterName(value, row, index) {
  410. let name = []
  411. for (var i = 0; i < row.array[index].json.answer2.length; i++) {
  412. name.push(row.array[index].json.array[row.array[index].json.answer2[i]].option)
  413. }
  414. console.log(name.indexOf(value) != -1);
  415. return name.indexOf(value) != -1;
  416. },
  417. wordClickHandler(name, value) {
  418. // this.$notify({
  419. // title: name,
  420. // message: "数量:"+value
  421. // });
  422. },
  423. retrunCourse() {
  424. this.goTo(
  425. "/test?userid=" +
  426. this.userid +
  427. "&oid=" +
  428. this.oid +
  429. "&org=" +
  430. this.org +
  431. "&role=" +
  432. this.role
  433. );
  434. },
  435. goTo(path) {
  436. this.$router.push(path);
  437. },
  438. tableRowClassName({ row, rowIndex }) {
  439. if ((rowIndex + 1) % 2 === 0) {
  440. return "even_row";
  441. } else {
  442. return "";
  443. }
  444. },
  445. changeHeight() {
  446. if (this.stype == 1) {
  447. return
  448. }
  449. this.tableHeight = this.$refs.stepBox.offsetHeight - 120;
  450. if (this.tableHeight <= 530) {
  451. this.tableHeight = 530;
  452. }
  453. // 监听窗口大小变化
  454. let self = this;
  455. window.onresize = function () {
  456. if (self.stype == 1) {
  457. return
  458. }
  459. self.tableHeight = this.$refs.stepBox.offsetHeight - 120;
  460. if (self.tableHeight <= 530) {
  461. self.tableHeight = 530;
  462. }
  463. };
  464. // this.$refs.table.$el.offsetTop:表格距离浏览器的高度 //200表示你想要调整的表格距离底部的高度(你可以自己随意调整),因为我们一般都有放分页组件的,所以需要给它留一个高度
  465. },
  466. handleCurrentChange(val) {
  467. this.page = val;
  468. this.getData2();
  469. },
  470. getTest(row) {
  471. this.$router.push(
  472. "/checkTest2?cid=" +
  473. row.courseid +
  474. "&userid=" +
  475. this.userid +
  476. "&userid2=" +
  477. row.userid +
  478. "&tid=" +
  479. row.id +
  480. "&oid=" +
  481. this.oid +
  482. "&org=" +
  483. this.org +
  484. "&type=2" +
  485. "&role=" +
  486. this.role
  487. );
  488. },
  489. checkDataType(type) {
  490. if (this.stype != type) {
  491. this.stype = type
  492. this.courseName = ''
  493. if (type == 3) {
  494. this.getData2();
  495. } else {
  496. this.getData();
  497. }
  498. this.changeHeight();
  499. }
  500. },
  501. searchCourse() {
  502. if (this.stype == 3) {
  503. this.getData2()
  504. } else {
  505. this.getData()
  506. }
  507. },
  508. getData() {
  509. this.isLoading = true;
  510. let params = {
  511. cid: this.cid,
  512. cn: this.courseName
  513. };
  514. this.ajax
  515. .get(this.$store.state.api + "getTestWorksNoPage", params)
  516. .then(async (res) => {
  517. this.isLoading = false;
  518. this.testJson = res.data[0][0]
  519. this.works = res.data[1]
  520. this.iscount = res.data[2][0].count
  521. this.pcount = res.data[3][0].count
  522. let chapters = this.setJSON(this.setJson2(JSON.parse(JSON.stringify(JSON.parse(res.data[0][0].chapters)))))
  523. this.chapters = this.setFilter(this.JSONSetting(JSON.parse(JSON.stringify(JSON.parse(res.data[0][0].chapters)))))
  524. let testArray = []
  525. let array = []
  526. for (let i = 0; i < this.works.length; i++) {
  527. let cJson = this.setJSON(JSON.parse(JSON.stringify(JSON.parse(this.works[i].courseJson))))
  528. if (JSON.stringify(cJson) == JSON.stringify(chapters)) {
  529. let _json = this.JSONSetting(JSON.parse(JSON.stringify(JSON.parse(this.works[i].courseJson))))
  530. for(var ja = 0; ja < _json.length; ja++){
  531. let _json2 = _json[ja].json
  532. if(_json[ja].type == 6){
  533. _json2.answer2 = await this.getCourse(_json2.answer2)
  534. }
  535. }
  536. array.push({
  537. courseid: this.works[i].courseid,
  538. id: this.works[i].id,
  539. userid: this.works[i].userid,
  540. name: this.works[i].username,
  541. time: this.works[i].time,
  542. array: _json,
  543. courseJson: JSON.parse(this.works[i].courseJson),
  544. })
  545. }
  546. }
  547. for (var i = 0; i < this.chapters.length; i++) {
  548. let el = this.chapters[i]
  549. let topic = {
  550. type: el.type,
  551. title: el.json ? el.json.title : '',
  552. detail: el.json ? el.json.detail : '',
  553. atype: el.json ? el.json.type : '',
  554. choice: el.json ? el.json.array : '',
  555. array: [],
  556. answer: el.json ? el.json.answer : '',
  557. count: 0,
  558. courses: el.json ? el.json.courses : [],
  559. }
  560. if (topic.type == 1) {
  561. for (var t = 0; t < topic.choice.length; t++) {
  562. topic.array.push({
  563. name: topic.choice[t].option,
  564. count: 0
  565. })
  566. }
  567. } else if (topic.type == 3) {
  568. } else if (topic.type == 5) {
  569. } else if (topic.type == 6) {
  570. let _answer = topic.courses
  571. topic.array = _answer
  572. topic.courseArray = [];
  573. topic.array.forEach(async i=>{
  574. let data = await this.getCourseDetail(i)
  575. data.update_at = new Date(data.update_at).toLocaleString().replace('/','-')
  576. topic.courseArray.push(data)
  577. })
  578. }
  579. for (var j = 0; j < array.length; j++) {
  580. let el2 = array[j]
  581. if (topic.type == 1) {
  582. let _answer = el2.array[i].json.answer2
  583. for (var k = 0; k < _answer.length; k++) {
  584. topic.array[_answer[k]].count++
  585. topic.count++
  586. }
  587. } else if (topic.type == 3) {
  588. let type3 = 1
  589. let _answer = el2.array[i].json.answer2
  590. if (_answer) {
  591. for (var k = 0; k < topic.array.length; k++) {
  592. if (topic.array[k].name == _answer) {
  593. topic.array[k].count++
  594. type3 = 2
  595. topic.count++
  596. break;
  597. }
  598. }
  599. if (type3 == 1) {
  600. topic.array.push({
  601. name: _answer,
  602. count: 1
  603. })
  604. }
  605. }
  606. } else if (topic.type == 5) {
  607. let _answer = el2.array[i].json.file ? el2.array[i].json.file : []
  608. for (var k = 0; k < _answer.length; k++) {
  609. topic.array.push(_answer[k])
  610. }
  611. }
  612. }
  613. console.log(topic)
  614. testArray.push(topic)
  615. }
  616. this.testArray = testArray
  617. this.worksArray = array
  618. })
  619. .catch((err) => {
  620. console.error(err);
  621. });
  622. },
  623. getData2() {
  624. this.isLoading = true;
  625. let params = {
  626. cid: this.cid,
  627. page: this.page,
  628. pageSize: this.pageSize,
  629. cn: this.courseName
  630. };
  631. this.ajax
  632. .get(this.$store.state.api + "getTestWorksPage3", params)
  633. .then((res) => {
  634. this.isLoading = false;
  635. this.total = res.data[0].length > 0 ? res.data[0][0].num : 0;
  636. this.tableData = res.data[0];
  637. })
  638. .catch((err) => {
  639. console.error(err);
  640. });
  641. },
  642. setJSON(json) {
  643. return json.filter((item) => {
  644. if (item.array) {
  645. item.array = item.array.filter((item2) => {
  646. if (item2.ttype == 1 && item2.json) {
  647. delete item2.json.answer2
  648. delete item2.json.score2
  649. delete item2.json.file
  650. }
  651. if (item2.array) {
  652. item2.array = item2.array.filter((item3) => {
  653. if (item3.ttype == 1 && item3.json) {
  654. delete item3.json.answer2
  655. delete item3.json.score2
  656. delete item3.json.file
  657. }
  658. return item3;
  659. });
  660. }
  661. return item2;
  662. });
  663. } else if (item.ttype == 1 && item.json) {
  664. delete item.json.answer2
  665. delete item.json.score2
  666. delete item.json.file
  667. }
  668. return item
  669. console.log(item.array);
  670. });
  671. },
  672. setJson2(json) {
  673. let _json = json;
  674. // this.type = _json[0].ttype;
  675. let checkArray = _json.filter((item) => {
  676. if (item.array) {
  677. item.array = item.array.filter((item2) => {
  678. if (item2.ttype == 1 && item2.json && !item2.json.answer2) {
  679. item2.json.answer2 = [];
  680. }
  681. if (item2.array) {
  682. item2.array = item2.array.filter((item3) => {
  683. if (item3.ttype == 1 && item3.json && !item3.json.answer2) {
  684. item3.json.answer2 = [];
  685. }
  686. return item3;
  687. });
  688. }
  689. return (
  690. (item2.ttype != 1 && item2.array.length > 0) || item2.ttype == 1
  691. );
  692. });
  693. }
  694. if (item.ttype == 1 && item.json && !item.json.answer2) {
  695. item.json.answer2 = [];
  696. }
  697. console.log(item.array);
  698. return (item.ttype != 1 && item.array.length > 0) || item.ttype == 1;
  699. });
  700. console.log(checkArray);
  701. return checkArray;
  702. },
  703. JSONSetting(json) {
  704. let _json = json
  705. let array = []
  706. _json.filter((item) => {
  707. if (item.array) {
  708. item.array = item.array.filter((item2) => {
  709. if (item2.ttype == 1 && item2.json) {
  710. array.push(item2)
  711. }
  712. if (item2.array) {
  713. item2.array = item2.array.filter((item3) => {
  714. if (item3.ttype == 1 && item3.json) {
  715. array.push(item3)
  716. }
  717. return item3;
  718. });
  719. }
  720. return item2;
  721. });
  722. }
  723. if (item.ttype == 1 && item.json) {
  724. array.push(item)
  725. }
  726. console.log(item.array);
  727. return item;
  728. });
  729. console.log(array);
  730. return array;
  731. },
  732. setFilter(json) {
  733. let _json = json
  734. let array = []
  735. _json.filter((item) => {
  736. item.nameFilters = [],
  737. item.filterParams = {
  738. name: [],
  739. }
  740. if (item.type == 1) {
  741. for (var i = 0; i < item.json.array.length; i++) {
  742. item.nameFilters.push({ text: item.json.array[i].option, value: item.json.array[i].option })
  743. }
  744. }
  745. array.push(item)
  746. return item;
  747. });
  748. return array
  749. },
  750. checkFile(item) {
  751. if (item.type == 3) {
  752. this.$hevueImgPreview(item.url);
  753. } else if (item.type == 5) {
  754. this.downloadFile(item);
  755. } else if (item.type == 1) {
  756. this.dialogVisibleOffice = true
  757. this.wurl = item.url
  758. } else if (item.type == 2) {
  759. this.dialogVisibleVideo = true
  760. this.wurl = item.url
  761. } else if (item.type == 4) {
  762. this.dialogVisiblePdf = true
  763. this.wurl = item.url
  764. }
  765. },
  766. downloadFile(f) {
  767. var credentials = {
  768. accessKeyId: "AKIATLPEDU37QV5CHLMH",
  769. secretAccessKey: "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",
  770. }; //秘钥形式的登录上传
  771. window.AWS.config.update(credentials);
  772. window.AWS.config.region = "cn-northwest-1"; //设置区域
  773. let url2 = f.url;
  774. let _url2 = "";
  775. if (
  776. url2.indexOf("https://view.officeapps.live.com/op/view.aspx?src=") != -1
  777. ) {
  778. _url2 = url2.split(
  779. "https://view.officeapps.live.com/op/view.aspx?src="
  780. )[1];
  781. } else {
  782. _url2 = url2;
  783. }
  784. let _this = this;
  785. _this.downLoading = _url2
  786. var s3 = new window.AWS.S3({ params: { Bucket: "ccrb" } });
  787. let name = decodeURIComponent(_url2.split("https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/")[1])
  788. var params = {
  789. Bucket: "ccrb",
  790. Key: name
  791. };
  792. s3.getObject(params, function (err, data) {
  793. _this.downLoading = ''
  794. if (err) console.log(err, err.stack); // an error occurred
  795. else {
  796. let url = window.URL.createObjectURL(new Blob([data.Body]));
  797. let a = document.createElement("a");
  798. a.name = f.name;
  799. a.href = url;
  800. a.download = f.name;
  801. a.click();
  802. console.log(data);
  803. } // sxuccessful response
  804. });
  805. },
  806. deleteTest(tid) {
  807. let _this = this
  808. _this
  809. .$confirm("确定删除此提交的表单么?", "提示", {
  810. confirmButtonText: "确定",
  811. cancelButtonText: "取消",
  812. type: "warning",
  813. })
  814. .then(() => {
  815. let params = [{
  816. tid: tid,
  817. }];
  818. _this.ajax
  819. .post(_this.$store.state.api + "deleteTestCourseWorks", params)
  820. .then((res) => {
  821. _this.$message.success("删除成功");
  822. if (_this.stype == 3) {
  823. _this.getData2();
  824. } else {
  825. _this.getData();
  826. }
  827. })
  828. .catch((err) => {
  829. console.error(err);
  830. });
  831. })
  832. .catch(() => {
  833. return;
  834. });
  835. },
  836. exportPDF() {
  837. this.pdfLoading = true
  838. var a = document.getElementsByTagName("img")
  839. for (var i = 0; i < a.length; i++) { a[i].crossOrigin = "*" }
  840. downloadPDF(this.$refs.stepBox, this.testJson.title, () => {
  841. var _a = document.getElementsByTagName("img")
  842. for (var i = 0; i < _a.length; i++) {
  843. _a[i].removeAttribute("crossorigin")
  844. }
  845. setTimeout(() => {
  846. this.pdfLoading = false
  847. }, 2000);
  848. })
  849. },
  850. score(json) {
  851. let score = 0
  852. json.forEach(el => {
  853. if ((el.ttype == 3 || el.ttype == 2) && el.array.length > 0) {
  854. el.array.forEach(item => {
  855. if (item.ttype == 2 && item.array.length > 0) {
  856. item.array.forEach(item2 => {
  857. if (item2.ttype == 1 && item2.json) {
  858. score += item2.json.score ? parseFloat(item2.json.score) : 0
  859. }
  860. })
  861. } else if (item.ttype == 1 && item.json) {
  862. score += item.json.score ? parseFloat(item.json.score) : 0
  863. }
  864. })
  865. } else if (el.ttype == 1 && el.json) {
  866. score += el.json.score ? parseFloat(el.json.score) : 0
  867. }
  868. })
  869. return score > 0 ? score + '分' : ''
  870. },
  871. score2(json) {
  872. let score = 0
  873. // let type = 1
  874. json.forEach(el => {
  875. if ((el.ttype == 3 || el.ttype == 2) && el.array.length > 0) {
  876. el.array.forEach(item => {
  877. if (item.ttype == 2 && item.array.length > 0) {
  878. item.array.forEach(item2 => {
  879. if (item2.ttype == 1 && item2.json) {
  880. score += item2.json.score2 ? parseFloat(item2.json.score2) : 0
  881. }
  882. })
  883. } else if (item.ttype == 1 && item.json) {
  884. score += item.json.score2 ? parseFloat(item.json.score2) : 0
  885. }
  886. })
  887. } else if (el.ttype == 1 && el.json) {
  888. score += el.json.score2 ? parseFloat(el.json.score2) : 0
  889. }
  890. })
  891. return score + '分'
  892. },
  893. setWordHtml(data) {
  894. let _data = data
  895. let _title = `<div style="font-size:40px;font-weight:bold;text-align:center;">${this.testJson.title}</div>`;
  896. let score = this.score(data.courseJson)
  897. let isScore = this.score2(data.courseJson)
  898. let scoreContent = score ? `<b>(得分/总分)${isScore}/${score}</b>` : ''
  899. let _content = `<div style="font-size:25px;text-align:center;margin-top: 20px;"><b style="margin-right:40px">(答题人)${_data.name}</b>${scoreContent}(填写范围)${this.testJson.juriP ? this.testJson.juriP : '所有人'}(提交时间)${_data.time}</div>`
  900. let _detail = this.testJson.brief ? `<div style="font-size:25px;text-align:center;margin-top: 20px;">${this.testJson.brief}</div>` : ''
  901. let _test = `<div style='margin-top:40px;'>`
  902. for (let i = 0; i < _data.array.length; i++) {
  903. let item = _data.array[i]
  904. let _div = `<div style='margin-top:20px;font-weight:bold;'>${i + 1}、${item.json.title}</div>`
  905. _test += _div
  906. if (item.type == 1) {
  907. for (let j = 0; j < item.json.array.length; j++) {
  908. let check = item.json.array[j]
  909. let _option = `<div style='margin:10px 0 0 40px;'>${(item.json.answer2 && item.json.answer2.indexOf(j) !== -1) ? '☑' : '☐'} ${check.option}</div>`
  910. _test += _option
  911. }
  912. } else if (item.type == 3 && item.json.answer2) {
  913. let _option = `<div style='margin:10px 0 0 40px;'>${item.json.answer2}</div>`
  914. _test += _option
  915. } else if (item.type == 5 && item.json.file) {
  916. for (let j = 0; j < item.json.file.length; j++) {
  917. let check = item.json.file[j]
  918. let _option = `<div style='margin:10px 0 0 40px;'>${check.name} <a href='${check.url}'>${check.url}</a></div>`
  919. _test += _option
  920. }
  921. }
  922. }
  923. _test += `</div>`
  924. let _html = _title + _content + _detail + _test;
  925. this.exportToWord(_data.name + '-' + _data.time, _html);
  926. },
  927. setWordHtml2(data) {
  928. let _data = data
  929. _data.array = this.JSONSetting(JSON.parse(JSON.stringify(JSON.parse(data.courseJson))))
  930. let _title = `<div style="font-size:40px;font-weight:bold;text-align:center;">${this.testJson.title}</div>`;
  931. let score = this.score(JSON.parse(data.courseJson))
  932. let isScore = this.score2(JSON.parse(data.courseJson))
  933. let scoreContent = score ? `<b>(得分/总分)${isScore}/${score}</b>` : ''
  934. let _content = `<div style="font-size:25px;text-align:center;margin-top: 20px;"><b style="margin-right:40px">(答题人)${_data.username}</b>${scoreContent}(填写范围)${this.testJson.juriP ? this.testJson.juriP : '所有人'}(提交时间)${_data.time}</div>`
  935. let _detail = this.testJson.brief ? `<div style="font-size:25px;text-align:center;margin-top: 20px;">${this.testJson.brief}</div>` : ''
  936. let _test = `<div style='margin-top:40px;'>`
  937. for (let i = 0; i < _data.array.length; i++) {
  938. let item = _data.array[i]
  939. let _div = `<div style='margin-top:20px;font-weight:bold;'>${i + 1}、${item.json.title}</div>`
  940. _test += _div
  941. if (item.type == 1) {
  942. for (let j = 0; j < item.json.array.length; j++) {
  943. let check = item.json.array[j]
  944. let _option = `<div style='margin:10px 0 0 40px;'>${(item.json.answer2 && item.json.answer2.indexOf(j) !== -1) ? '☑' : '☐'} ${check.option}</div>`
  945. _test += _option
  946. }
  947. } else if (item.type == 3 && item.json.answer2) {
  948. let _option = `<div style='margin:10px 0 0 40px;'>${item.json.answer2}</div>`
  949. _test += _option
  950. } else if (item.type == 5 && item.json.file) {
  951. for (let j = 0; j < item.json.file.length; j++) {
  952. let check = item.json.file[j]
  953. let _option = `<div style='margin:10px 0 0 40px;'>${check.name} <a href='${check.url}'>${check.url}</a></div>`
  954. _test += _option
  955. }
  956. }
  957. }
  958. _test += `</div>`
  959. let _html = _title + _content + _detail + _test;
  960. this.exportToWord(_data.username + '-' + _data.time, _html);
  961. },
  962. async exportToWord(a, html) {
  963. // 将html文件中需要用到的数据挂载到store上
  964. const content = `<!DOCTYPE html>
  965. <html lang="en">
  966. <head>
  967. <meta charset="UTF-8">
  968. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  969. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  970. <title>${a}</title>
  971. <style>
  972. </style>
  973. </head>
  974. <body>
  975. ${html}
  976. </body>
  977. </html>`;
  978. // debugger
  979. // 生成报告
  980. const link = document.createElement("a");
  981. let dname = a + ".doc";
  982. // link.download = "报告.html"; // 文件名
  983. link.download = dname; // 文件名
  984. link.style.display = "none";
  985. // 创建文件流
  986. // 创建bolb实例时,内容一定要放在[]中
  987. const blob = new Blob([content], {
  988. type: "text/plain;charset='utf-8'",
  989. });
  990. link.href = window.URL.createObjectURL(blob);
  991. document.body.appendChild(link);
  992. link.click();
  993. document.body.removeChild(link);
  994. },
  995. setWordHtmlAll(data) {
  996. let _data = data
  997. let _title = `<div style="font-size:40px;font-weight:bold;text-align:center;">${this.testJson.title}</div>`;
  998. let score = this.score(data.courseJson)
  999. let isScore = this.score2(data.courseJson)
  1000. let scoreContent = score ? `<b>(得分/总分)${isScore}/${score}</b>` : ''
  1001. let _content = `<div style="font-size:25px;text-align:center;margin-top: 20px;"><b style="margin-right:40px">(答题人)${_data.name}</b>${scoreContent}(填写范围)${this.testJson.juriP ? this.testJson.juriP : '所有人'}(提交时间)${_data.time}</div>`
  1002. let _detail = this.testJson.brief ? `<div style="font-size:25px;text-align:center;margin-top: 20px;">${this.testJson.brief}</div>` : ''
  1003. let _test = `<div style='margin-top:40px;'>`
  1004. for (let i = 0; i < _data.array.length; i++) {
  1005. let item = _data.array[i]
  1006. let _div = `<div style='margin-top:20px;font-weight:bold;'>${i + 1}、${item.json.title}</div>`
  1007. _test += _div
  1008. if (item.type == 1) {
  1009. for (let j = 0; j < item.json.array.length; j++) {
  1010. let check = item.json.array[j]
  1011. let _option = `<div style='margin:10px 0 0 40px;'>${(item.json.answer2 && item.json.answer2.indexOf(j) !== -1) ? '☑' : '☐'} ${check.option}</div>`
  1012. _test += _option
  1013. }
  1014. } else if (item.type == 3 && item.json.answer2) {
  1015. let _option = `<div style='margin:10px 0 0 40px;'>${item.json.answer2}</div>`
  1016. _test += _option
  1017. } else if (item.type == 5 && item.json.file) {
  1018. for (let j = 0; j < item.json.file.length; j++) {
  1019. let check = item.json.file[j]
  1020. let _option = `<div style='margin:10px 0 0 40px;'>${check.name} <a href='${check.url}'>${check.url}</a></div>`
  1021. _test += _option
  1022. }
  1023. }
  1024. }
  1025. _test += `</div>`
  1026. let _html = _title + _content + _detail + _test;
  1027. return this.exportToWordAll(_data.name + '-' + _data.time, _html);
  1028. },
  1029. setWordHtmlAll2(data) {
  1030. let _data = data
  1031. _data.array = this.JSONSetting(JSON.parse(JSON.stringify(JSON.parse(data.courseJson))))
  1032. let _title = `<div style="font-size:40px;font-weight:bold;text-align:center;">${this.testJson.title}</div>`;
  1033. let score = this.score(JSON.parse(data.courseJson))
  1034. let isScore = this.score2(JSON.parse(data.courseJson))
  1035. let scoreContent = score ? `<b>(得分/总分)${isScore}/${score}</b>` : ''
  1036. let _content = `<div style="font-size:25px;text-align:center;margin-top: 20px;"><b style="margin-right:40px">(答题人)${_data.username}</b>${scoreContent}(填写范围)${this.testJson.juriP ? this.testJson.juriP : '所有人'}(提交时间)${_data.time}</div>`
  1037. let _detail = this.testJson.brief ? `<div style="font-size:25px;text-align:center;margin-top: 20px;">${this.testJson.brief}</div>` : ''
  1038. let _test = `<div style='margin-top:40px;'>`
  1039. for (let i = 0; i < _data.array.length; i++) {
  1040. let item = _data.array[i]
  1041. let _div = `<div style='margin-top:20px;font-weight:bold;'>${i + 1}、${item.json.title}</div>`
  1042. _test += _div
  1043. if (item.type == 1) {
  1044. for (let j = 0; j < item.json.array.length; j++) {
  1045. let check = item.json.array[j]
  1046. let _option = `<div style='margin:10px 0 0 40px;'>${(item.json.answer2 && item.json.answer2.indexOf(j) !== -1) ? '☑' : '☐'} ${check.option}</div>`
  1047. _test += _option
  1048. }
  1049. } else if (item.type == 3 && item.json.answer2) {
  1050. let _option = `<div style='margin:10px 0 0 40px;'>${item.json.answer2}</div>`
  1051. _test += _option
  1052. } else if (item.type == 5 && item.json.file) {
  1053. for (let j = 0; j < item.json.file.length; j++) {
  1054. let check = item.json.file[j]
  1055. let _option = `<div style='margin:10px 0 0 40px;'>${check.name} <a href='${check.url}'>${check.url}</a></div>`
  1056. _test += _option
  1057. }
  1058. }
  1059. }
  1060. _test += `</div>`
  1061. let _html = _title + _content + _detail + _test;
  1062. return this.exportToWordAll(_data.username + '-' + _data.time, _html);
  1063. },
  1064. async exportToWordAll(a, html) {
  1065. // 将html文件中需要用到的数据挂载到store上
  1066. const content = `<!DOCTYPE html>
  1067. <html lang="en">
  1068. <head>
  1069. <meta charset="UTF-8">
  1070. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  1071. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  1072. <title>${a}</title>
  1073. <style>
  1074. </style>
  1075. </head>
  1076. <body>
  1077. ${html}
  1078. </body>
  1079. </html>`;
  1080. // debugger
  1081. // 生成报告
  1082. const link = document.createElement("a");
  1083. let dname = a + ".doc";
  1084. // link.download = "报告.html"; // 文件名
  1085. link.download = dname; // 文件名
  1086. link.style.display = "none";
  1087. // 创建文件流
  1088. // 创建bolb实例时,内容一定要放在[]中
  1089. const blob = new Blob([content], {
  1090. type: "text/plain;charset='utf-8'",
  1091. });
  1092. return blob;
  1093. },
  1094. exportAllWord() {
  1095. this.pdfLoading = true;
  1096. const _chapInfo = this.worksArray;
  1097. let url = [];
  1098. for (let i = 0; i < _chapInfo.length; i++) {
  1099. url.push({
  1100. name: _chapInfo[i].name + '-' + _chapInfo[i].time,
  1101. blob: this.setWordHtmlAll(_chapInfo[i]),
  1102. });
  1103. }
  1104. console.log(url);
  1105. this.downLoadAll(url);
  1106. },
  1107. exportAllWord2() {
  1108. this.pdfLoading = true;
  1109. let params = {
  1110. cid: this.cid,
  1111. page: 1,
  1112. pageSize: 999,
  1113. cn: this.courseName
  1114. };
  1115. this.ajax
  1116. .get(this.$store.state.api + "getTestWorksPage3", params)
  1117. .then((res) => {
  1118. const _chapInfo = res.data[0];
  1119. let url = [];
  1120. for (let i = 0; i < _chapInfo.length; i++) {
  1121. url.push({
  1122. name: _chapInfo[i].username + '-' + _chapInfo[i].time,
  1123. blob: this.setWordHtmlAll2(_chapInfo[i]),
  1124. });
  1125. }
  1126. console.log(url);
  1127. this.downLoadAll(url);
  1128. })
  1129. .catch((err) => {
  1130. console.error(err);
  1131. });
  1132. },
  1133. downLoadAll(url) {
  1134. const data = url; // 需要下载打包的路径, 可以是本地相对路径, 也可以是跨域的全路径
  1135. const zip = new JSZip();
  1136. const cache = {};
  1137. data.forEach((item) => {
  1138. // 下载文件, 并存成ArrayBuffer对象
  1139. const file_name = item.name; // 获取文件名
  1140. zip.file(file_name + '.doc', item.blob, { binary: true }); // 逐个添加文件
  1141. cache[file_name] = item.blob;
  1142. });
  1143. zip.generateAsync({ type: "blob" }).then((content) => {
  1144. // 生成二进制流
  1145. FileSaver.saveAs(content, this.testJson.title + ".zip"); // 利用file-saver保存文件 自定义文件名
  1146. setTimeout(() => {
  1147. this.pdfLoading = false;
  1148. }, 2000);
  1149. });
  1150. },
  1151. handleFilterChange() {
  1152. console.log(this.$refs.table.store.states.data);
  1153. },
  1154. exportExcel() {
  1155. let res = this.$refs.table.store.states.data
  1156. if (!res.length) {
  1157. this.$message.error('无导出数据')
  1158. return
  1159. }
  1160. this.isLoading = true;
  1161. let chapters = this.chapters
  1162. var array = [];
  1163. for (var i = 0; i < res.length; i++) {
  1164. var _json = {};
  1165. _json["序号"] = i + 1;
  1166. _json["提交人"] = res[i].name;
  1167. _json["提交时间"] = res[i].time;
  1168. for (var j = 0; j < chapters.length; j++) {
  1169. _json[j + 1 + "." + chapters[j].json.title] = '';
  1170. if (res[i].array[j].type == 1 && res[i].array[j].json.answer2) {
  1171. let a = []
  1172. for (var answer2 = 0; answer2 < res[i].array[j].json.answer2.length; answer2++) {
  1173. a.push(res[i].array[j].json.array[answer2].option)
  1174. }
  1175. _json[j + 1 + "." + chapters[j].json.title] = a.join('、')
  1176. } else if (res[i].array[j].type == 3 && res[i].array[j].json.answer2) {
  1177. _json[j + 1 + "." + chapters[j].json.title] = res[i].array[j].json.answer2
  1178. } else if (res[i].array[j].type == 5 && res[i].array[j].json.file) {
  1179. let files = []
  1180. for (let file = 0; file < res[i].array[j].json.file.length; file++) {
  1181. let check = res[i].array[j].json.file[file]
  1182. files.push(file + 1 + '.' + check.name + '----' + check.url)
  1183. }
  1184. _json[j + 1 + "." + chapters[j].json.title] = files.join('\n')
  1185. }
  1186. }
  1187. array.push(_json);
  1188. }
  1189. let widthJson = []
  1190. let widthArray = Object.keys(array[0])
  1191. for (let i = 0; i < widthArray.length; i++) {
  1192. if (i == 0) {
  1193. widthJson.push({ wch: 5 })
  1194. } else {
  1195. widthJson.push({ wch: 30 })
  1196. }
  1197. }
  1198. const workbook = XLSX.utils.book_new(); //创建一个新的工作簿对象
  1199. let ws = XLSX.utils.json_to_sheet(array); //将json对象数组转化成工作表
  1200. ws["!cols"] = widthJson;
  1201. const styleObj = {
  1202. alignment: {
  1203. horizontal: "center",
  1204. vertical: "center" // 设置垂直居中
  1205. }
  1206. }; // 设置居中对齐和加粗样式
  1207. for (let cell in ws) {
  1208. if (!cell[0].startsWith("!")) {
  1209. ws[cell]["s"] = styleObj;
  1210. }
  1211. }
  1212. XLSX.utils.book_append_sheet(workbook, ws, "sheet1"); //把sheet添加到workbook里,第三个参数是sheet名
  1213. XLSX.writeFile(workbook, this.testJson.title + ".xlsx");
  1214. this.isLoading = false;
  1215. this.$message({
  1216. message: "导出成功",
  1217. type: "success"
  1218. });
  1219. },
  1220. async getCourse(id) {
  1221. let params = {
  1222. cid: id,
  1223. };
  1224. let res = await this.ajax.get(this.$store.state.api + "getCourseInfoTest", params)
  1225. return res.data[0][0].title
  1226. },
  1227. async getCourseDetail(id){
  1228. let params = {
  1229. cid: id,
  1230. };
  1231. let res = await this.ajax.get(this.$store.state.api + "getCourseInfoTest", params)
  1232. return res.data[0][0]
  1233. }
  1234. },
  1235. beforeDestroy() {
  1236. document.getElementsByTagName('html')[0].style.overflow = ''
  1237. },
  1238. mounted() {
  1239. document.getElementsByTagName('html')[0].scrollTop = 0
  1240. document.getElementsByTagName('html')[0].style.overflow = 'hidden'
  1241. this.$nextTick(function () {
  1242. this.getData();
  1243. this.changeHeight()
  1244. });
  1245. },
  1246. };
  1247. </script>
  1248. <style scoped>
  1249. .pb_content {
  1250. height: 100% !important;
  1251. /* margin: 0 20px 0 20px; */
  1252. }
  1253. .pb_content_body {
  1254. width: 100% !important;
  1255. height: 100%;
  1256. }
  1257. .pb_content_body>.right {
  1258. height: 100%;
  1259. width: 100%;
  1260. display: flex;
  1261. overflow: hidden;
  1262. flex-direction: column;
  1263. }
  1264. .basic_box {
  1265. margin: 0 auto;
  1266. position: relative;
  1267. padding: 0 20px 0 20px;
  1268. }
  1269. .courseTop {
  1270. display: flex;
  1271. flex-direction: row;
  1272. justify-content: space-between;
  1273. align-items: center;
  1274. width: calc(100% - 40px);
  1275. margin: 0 auto;
  1276. padding: 10px 0;
  1277. }
  1278. .stepsNav {
  1279. display: flex;
  1280. flex-direction: row;
  1281. justify-content: flex-start;
  1282. align-items: center;
  1283. }
  1284. .step_box {
  1285. width: calc(100% - 40px);
  1286. margin: 0 auto;
  1287. height: calc(100% - 50px);
  1288. overflow: auto;
  1289. background: #ffff;
  1290. border-radius: 5px;
  1291. }
  1292. .el-table>>>.even_row {
  1293. background-color: #f1f1f1 !important;
  1294. }
  1295. .student_page {
  1296. margin-top: 10px;
  1297. }
  1298. .test_title {
  1299. display: flex;
  1300. padding: 15px 15px;
  1301. width: 100%;
  1302. box-sizing: border-box;
  1303. justify-content: space-between;
  1304. align-items: center;
  1305. flex-wrap: wrap;
  1306. margin-bottom: 10px;
  1307. }
  1308. .test_title .left {
  1309. max-width: 100%;
  1310. margin-top: 10px
  1311. }
  1312. .test_title .left .title {
  1313. width: 100%;
  1314. font-size: 24px;
  1315. font-weight: 700;
  1316. overflow: hidden;
  1317. text-overflow: ellipsis;
  1318. white-space: nowrap;
  1319. }
  1320. .test_title .left .info {
  1321. display: flex;
  1322. margin-top: 15px;
  1323. }
  1324. .test_title .left .info .info_box {
  1325. font-size: 14px;
  1326. }
  1327. .test_title .left .info .info_box+.info_box {
  1328. margin-left: 20px;
  1329. padding-left: 20px;
  1330. border-left: 1px solid #E7E7E7;
  1331. }
  1332. .test_title .left .info .info_box span:nth-child(1) {
  1333. color: #00000099;
  1334. }
  1335. .test_title .left .info .info_box span:nth-child(2) {}
  1336. .test_title .right {
  1337. display: flex;
  1338. align-items: center;
  1339. margin-top: 10px;
  1340. max-width: 100%;
  1341. }
  1342. .test_title .right .data_box {
  1343. margin-right: 15px;
  1344. width: 150px;
  1345. border: 1px solid #e7e7e7;
  1346. border-radius: 5px;
  1347. padding: 0 10px;
  1348. height: 57px;
  1349. font-size: 14px;
  1350. color: #00000099;
  1351. display: flex;
  1352. justify-content: space-between;
  1353. align-items: center;
  1354. }
  1355. .test_title .right .data_box span:nth-child(1) {}
  1356. .test_title .right .data_box span:nth-child(2) {}
  1357. .test_title .right .data_box span:nth-child(2) .big {
  1358. font-size: 22px;
  1359. }
  1360. .test_title .right .btn_box {
  1361. display: flex;
  1362. flex-direction: column;
  1363. width: 57px;
  1364. height: 57px;
  1365. background: #3681fc;
  1366. border-radius: 5px;
  1367. font-size: 14px;
  1368. cursor: pointer;
  1369. align-items: center;
  1370. justify-content: center;
  1371. color: #fff;
  1372. }
  1373. .test_title .right .btn_box span:nth-child(1) {
  1374. display: block;
  1375. width: 12px;
  1376. height: 14px;
  1377. margin-bottom: 5px;
  1378. background-image: url('../../../../assets/icon/test/icon_share.png');
  1379. background-size: 100% 100%;
  1380. }
  1381. .test_title .right .btn_box span:nth-child(2) {}
  1382. .search_nav {
  1383. border-bottom: 1px solid #E7E7E7;
  1384. width: 100%;
  1385. box-sizing: border-box;
  1386. padding: 0 15px 10px;
  1387. display: flex;
  1388. align-items: flex-end;
  1389. height: 50px;
  1390. }
  1391. .search_nav>.right {
  1392. display: flex;
  1393. align-items: center;
  1394. }
  1395. .search_nav>.right>span {
  1396. height: 24px;
  1397. font-size: 14px;
  1398. color: #000;
  1399. cursor: pointer;
  1400. position: relative;
  1401. }
  1402. .search_nav>.right>span+span {
  1403. margin-left: 35px;
  1404. }
  1405. .search_nav>.right>span.active {
  1406. color: #3681FC;
  1407. font-weight: 600;
  1408. }
  1409. .search_nav>.right>span.active::before {
  1410. content: "";
  1411. position: absolute;
  1412. bottom: -10px;
  1413. width: 15px;
  1414. height: 3px;
  1415. background: #3681fc;
  1416. left: 50%;
  1417. transform: translateX(-50%);
  1418. }
  1419. .search_nav>.left {
  1420. display: flex;
  1421. align-items: center;
  1422. margin-left: auto;
  1423. }
  1424. .student_input>>>.el-input__inner {
  1425. height: 40px;
  1426. width: 190px;
  1427. font-size: 13px;
  1428. padding: 0 35px 0 10px;
  1429. }
  1430. .serach_icon {
  1431. position: absolute;
  1432. right: 12px;
  1433. top: 50%;
  1434. transform: translateY(-50%);
  1435. width: 13px;
  1436. height: 13px;
  1437. background: url("../../../../assets/icon/test/test_search.png") no-repeat;
  1438. background-size: 100% 100%;
  1439. cursor: pointer;
  1440. }
  1441. .title_content {
  1442. padding-bottom: 10px;
  1443. }
  1444. .title_content>.title_box {
  1445. width: calc(100% - 48px);
  1446. margin: 20px auto 0;
  1447. }
  1448. .title_content>.title_box>.title {
  1449. font-size: 18px;
  1450. display: flex;
  1451. white-space: pre-line;
  1452. }
  1453. .title_content>.title_box>.title>.test_icon {
  1454. min-width: 20px;
  1455. height: 20px;
  1456. }
  1457. .title_content>.title_box>.detail {
  1458. font-size: 14px;
  1459. color: #00000099;
  1460. margin-top: 8px;
  1461. white-space: pre-line;
  1462. }
  1463. .title_content>.title_box>.content1 {
  1464. display: flex;
  1465. width: 100%;
  1466. margin-top: 10px;
  1467. }
  1468. .title_content>.title_box>.content1>>>.el-progress__text {
  1469. color: #3681FC;
  1470. min-width: 55px;
  1471. font-size: 16px !important;
  1472. }
  1473. .title_content>.title_box>.content1>.left {
  1474. width: calc(100% - 620px);
  1475. border: 1px solid #e7e7e7;
  1476. }
  1477. .title_content>.title_box>.content1>.left>div+div {
  1478. border-top: 1px solid #e7e7e7;
  1479. }
  1480. .title_content>.title_box>.content1>.left>.title,
  1481. .title_content>.title_box>.content1>.left>.data {
  1482. display: flex;
  1483. height: 40px;
  1484. align-items: center;
  1485. width: 100%;
  1486. padding: 0 15px;
  1487. box-sizing: border-box;
  1488. line-height: 16px;
  1489. }
  1490. .title_content>.title_box>.content1>.left>.title>span,
  1491. .title_content>.title_box>.content1>.left>.data>span {
  1492. overflow: hidden;
  1493. text-overflow: ellipsis;
  1494. white-space: nowrap;
  1495. }
  1496. .title_content>.title_box>.content1>.left>.title>span:nth-child(1),
  1497. .title_content>.title_box>.content1>.left>.data>span:nth-child(1) {
  1498. width: calc(100% - 320px - 110px);
  1499. }
  1500. .title_content>.title_box>.content1>.left>.title>span:nth-child(2),
  1501. .title_content>.title_box>.content1>.left>.data>span:nth-child(2) {
  1502. width: 110px;
  1503. }
  1504. .title_content>.title_box>.content1>.left>.title>span:nth-child(3),
  1505. .title_content>.title_box>.content1>.left>.data>span:nth-child(3) {
  1506. width: 320px;
  1507. }
  1508. .title_content>.title_box>.content1>.left>.title {
  1509. font-weight: 700;
  1510. background: #F9FAFB;
  1511. }
  1512. .title_content>.title_box>.content1>.right {
  1513. width: 600px;
  1514. margin-left: 20px;
  1515. border: 1px solid #e7e7e7;
  1516. min-height: 300px;
  1517. }
  1518. .title_content>.title_box>.content2 {
  1519. display: flex;
  1520. width: 100%;
  1521. margin-top: 10px;
  1522. }
  1523. .title_content>.title_box>.content2>.left {
  1524. width: calc(100% - 620px);
  1525. border: 1px solid #e7e7e7;
  1526. }
  1527. .title_content>.title_box>.content2>.left>div+div {
  1528. border-top: 1px solid #e7e7e7;
  1529. }
  1530. .title_content>.title_box>.content2>.left>.title,
  1531. .title_content>.title_box>.content2>.left>.data {
  1532. display: flex;
  1533. height: 40px;
  1534. align-items: center;
  1535. width: 100%;
  1536. padding: 0 15px;
  1537. box-sizing: border-box;
  1538. line-height: 16px;
  1539. }
  1540. .title_content>.title_box>.content2>.left>.title>span,
  1541. .title_content>.title_box>.content2>.left>.data>span {
  1542. overflow: hidden;
  1543. text-overflow: ellipsis;
  1544. white-space: nowrap;
  1545. }
  1546. .title_content>.title_box>.content2>.left>.title>span:nth-child(1),
  1547. .title_content>.title_box>.content2>.left>.data>span:nth-child(1) {
  1548. width: 55px;
  1549. }
  1550. .title_content>.title_box>.content2>.left>.title>span:nth-child(2),
  1551. .title_content>.title_box>.content2>.left>.data>span:nth-child(2) {
  1552. width: 110px;
  1553. }
  1554. .title_content>.title_box>.content2>.left>.title>span:nth-child(3),
  1555. .title_content>.title_box>.content2>.left>.data>span:nth-child(3) {
  1556. max-width: calc(100% - 110px - 55px);
  1557. }
  1558. .title_content>.title_box>.content2>.left>.title {
  1559. font-weight: 700;
  1560. background: #F9FAFB;
  1561. }
  1562. .title_content>.title_box>.content2>.right {
  1563. width: 600px;
  1564. margin-left: 20px;
  1565. border: 1px solid #e7e7e7;
  1566. }
  1567. .title_content>.title_box>.content2>.right>>>.wordCloud {
  1568. height: auto;
  1569. min-height: 300px;
  1570. }
  1571. .title_content>.title_box>.content3 {
  1572. display: flex;
  1573. width: 100%;
  1574. overflow: auto;
  1575. }
  1576. .title_content>.title_box>.content3>.file {
  1577. min-width: 200px;
  1578. width: 200px;
  1579. height: 140px;
  1580. margin: 10px 10px 10px 0px;
  1581. border-radius: 15px;
  1582. box-shadow: rgb(223, 218, 218) 0px 0px 6px 1px;
  1583. overflow: hidden;
  1584. margin-right: 15px;
  1585. position: relative;
  1586. display: flex;
  1587. flex-direction: column;
  1588. }
  1589. .title_content>.title_box>.content3>.file>.img {
  1590. width: 100%;
  1591. height: calc(100% - 35px);
  1592. object-fit: cover;
  1593. cursor: pointer;
  1594. }
  1595. .title_content>.title_box>.content3>.file>.del {
  1596. position: absolute;
  1597. width: 25px;
  1598. top: 10px;
  1599. right: 10px;
  1600. cursor: pointer;
  1601. }
  1602. .title_content>.title_box>.content3>.file>.download {
  1603. position: absolute;
  1604. width: 25px;
  1605. top: 10px;
  1606. right: 35px;
  1607. cursor: pointer;
  1608. opacity: .8;
  1609. }
  1610. .title_content>.title_box>.content3>.file>.name {
  1611. height: 35px;
  1612. width: 100%;
  1613. background: #f9f9f9;
  1614. display: flex;
  1615. align-items: center;
  1616. padding: 0 10px;
  1617. box-sizing: border-box;
  1618. }
  1619. .title_content>.title_box>.content3>.file>.name>span {
  1620. display: block;
  1621. text-overflow: ellipsis;
  1622. max-width: 100%;
  1623. white-space: nowrap;
  1624. overflow: hidden;
  1625. }
  1626. .table_content {
  1627. /* width: calc(100% - 48px);
  1628. margin: 20px auto 0; */
  1629. padding: 20px 24px;
  1630. width: 100%;
  1631. box-sizing: border-box;
  1632. }
  1633. .table_content>>>.el-table td {
  1634. padding: 5px 0;
  1635. }
  1636. .answer_type {
  1637. background: #F0F2F5;
  1638. padding: 5px 10px;
  1639. display: block;
  1640. border-radius: 3px;
  1641. margin: 5px;
  1642. }
  1643. .table_file>.file {
  1644. min-width: 100px;
  1645. width: 100px;
  1646. height: 70px;
  1647. margin: 10px 10px 10px 0px;
  1648. border-radius: 5px;
  1649. box-shadow: rgb(223, 218, 218) 0px 0px 6px 1px;
  1650. overflow: hidden;
  1651. margin-right: 15px;
  1652. position: relative;
  1653. display: flex;
  1654. flex-direction: column;
  1655. }
  1656. .table_file>.file>.img {
  1657. width: 100%;
  1658. height: calc(100% - 20px);
  1659. object-fit: cover;
  1660. cursor: pointer;
  1661. }
  1662. .table_file>.file>.del {
  1663. position: absolute;
  1664. width: 25px;
  1665. top: 10px;
  1666. right: 10px;
  1667. cursor: pointer;
  1668. }
  1669. .table_file>.file>.download {
  1670. position: absolute;
  1671. width: 25px;
  1672. top: 10px;
  1673. right: 35px;
  1674. cursor: pointer;
  1675. opacity: .8;
  1676. }
  1677. .table_file>.file>.name {
  1678. height: 20px;
  1679. width: 100%;
  1680. background: #f9f9f9;
  1681. display: flex;
  1682. align-items: center;
  1683. padding: 0 10px;
  1684. box-sizing: border-box;
  1685. font-size: 12px;
  1686. }
  1687. .table_file>.file>.name>span {
  1688. display: block;
  1689. text-overflow: ellipsis;
  1690. max-width: 100%;
  1691. white-space: nowrap;
  1692. overflow: hidden;
  1693. }
  1694. .btnA {
  1695. color: #fff;
  1696. background-color: #0061FF;
  1697. padding: 0 24px;
  1698. font-size: 14px;
  1699. min-width: 64px;
  1700. font-weight: 500;
  1701. border-radius: 4px;
  1702. box-sizing: border-box;
  1703. border: none;
  1704. cursor: pointer;
  1705. transition: all 0.2s ease-in-out;
  1706. height: 36px;
  1707. display: flex;
  1708. align-items: center;
  1709. justify-content: center;
  1710. line-height: 1;
  1711. margin-right: 10px;
  1712. position: relative;
  1713. }
  1714. .buttonBox {
  1715. position: absolute;
  1716. bottom: -0;
  1717. transform: translateY(100%);
  1718. background: #fff;
  1719. border-radius: 5px;
  1720. box-shadow: 0 0 3px 1px #e3e3e3;
  1721. width: 100%;
  1722. z-index: 999;
  1723. }
  1724. .buttonBox>div {
  1725. height: 40px;
  1726. line-height: 40px;
  1727. width: 100%;
  1728. text-align: center;
  1729. color: #000;
  1730. box-sizing: border-box;
  1731. }
  1732. .buttonBox>div+div {
  1733. border-top: 1px solid #e0e0e0;
  1734. }
  1735. .buttonBox>div:hover {
  1736. background: #f6f8ff;
  1737. }
  1738. .content4{
  1739. width: 100%;
  1740. height: auto;
  1741. display: flex;
  1742. flex-wrap: nowrap;
  1743. overflow: auto;
  1744. }
  1745. .out_box {
  1746. display: flex;
  1747. flex-direction: column;
  1748. flex-wrap: nowrap;
  1749. /* width: 200px; */
  1750. width: 280px;
  1751. background: #fff;
  1752. /* background-color: white; */
  1753. margin-right: 15px;
  1754. /* border: 1px solid #ccc; */
  1755. height: fit-content;
  1756. box-sizing: border-box;
  1757. border-radius: 0px 0px 5px 5px;
  1758. /* overflow: hidden; */
  1759. margin-bottom: 15px;
  1760. position: relative;
  1761. border-radius: 8px;
  1762. box-sizing: border-box;
  1763. overflow: hidden;
  1764. border: 1px solid #3682fc00;
  1765. cursor: pointer;
  1766. border: 1px solid #6a9ff5;
  1767. height: auto;
  1768. }
  1769. .out_boxActive{
  1770. box-sizing: border-box;
  1771. border: 3px solid #3681FC !important;
  1772. }
  1773. .out_box:hover {
  1774. border: 1px solid #3681FC;
  1775. }
  1776. .out_box:nth-child(5n) {
  1777. margin-right: 0;
  1778. }
  1779. .bottom_box {
  1780. width:100%;
  1781. display: flex;
  1782. padding: 10px;
  1783. flex-direction: column;
  1784. box-sizing: border-box;
  1785. height: 121px;
  1786. flex-wrap: nowrap;
  1787. justify-content: space-evenly;
  1788. }
  1789. .bottom_box>div:nth-child(1) {
  1790. width: 100%;
  1791. /* overflow: hidden;
  1792. text-overflow: ellipsis;
  1793. white-space: nowrap;
  1794. font-weight: bold; */
  1795. display: flex;
  1796. align-items: center;
  1797. justify-content: space-between;
  1798. }
  1799. .bottom_box>div:nth-child(1)>span:nth-child(1) {
  1800. max-width: 100%;
  1801. overflow: hidden;
  1802. text-overflow: ellipsis;
  1803. white-space: nowrap;
  1804. font-weight: bold;
  1805. }
  1806. .bottom_box>div:nth-child(1)>span:nth-child(2) {
  1807. min-width: fit-content;
  1808. font-size: 14px;
  1809. color: #8c8c8c;
  1810. }
  1811. .tup {
  1812. width: 100%;
  1813. height: auto;
  1814. margin: 0 auto;
  1815. overflow: hidden;
  1816. display: flex;
  1817. flex-direction: column;
  1818. align-items: center;
  1819. padding: 10px;
  1820. box-sizing: border-box;
  1821. }
  1822. .tup>img {
  1823. width: 100%;
  1824. height: 100%;
  1825. object-fit: cover;
  1826. }
  1827. .kc_time {
  1828. margin-top: 8px;
  1829. font-size: 14px;
  1830. color: #717C8D;
  1831. }
  1832. .kc_time+.kc_time {
  1833. margin-top: 0;
  1834. }
  1835. .kc_t {
  1836. margin-top: 5px;
  1837. width: 100%;
  1838. white-space: nowrap;
  1839. overflow: hidden;
  1840. text-overflow: ellipsis;
  1841. display: flex;
  1842. align-items: center;
  1843. justify-content: space-between;
  1844. }
  1845. .kc_t>span:nth-child(1) {
  1846. max-width: 100%;
  1847. overflow: hidden;
  1848. text-overflow: ellipsis;
  1849. white-space: nowrap;
  1850. }
  1851. .kc_t>span:nth-child(2) {
  1852. min-width: fit-content;
  1853. font-size: 14px;
  1854. color: #8c8c8c;
  1855. }
  1856. </style>