grade.vue 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995
  1. <template>
  2. <div class="content-box">
  3. <div class="left">
  4. <!-- <el-icon :size="23" class="camera"><VideoCameraFilled /></el-icon> -->
  5. <span class="cameratxt">成绩管理</span>
  6. </div>
  7. <div class="scrollId">
  8. <div class="middle">
  9. <div class="filter">
  10. <div class="condition">
  11. <el-input
  12. :clearable="true"
  13. @blur="searchBtn"
  14. @clear="searchBtn"
  15. v-model.trim="searchInput.keyWord"
  16. class="sel"
  17. placeholder="请输入学生姓名或学号"
  18. />
  19. </div>
  20. <el-button
  21. color="rgba(0, 97, 255, 1)"
  22. type="primary"
  23. class="search"
  24. @click="searchBtn"
  25. >
  26. <!-- <el-icon>
  27. <Search />
  28. </el-icon> -->
  29. 查询</el-button
  30. >
  31. <div class="condition">
  32. <span class="title">学期 : </span>
  33. <el-select
  34. v-model="searchInput.semester"
  35. class="sel"
  36. placeholder="请选择学期"
  37. style="width: 250px"
  38. @change="searchBtn"
  39. :clearable="true"
  40. >
  41. <el-option
  42. :label="i.name"
  43. :value="i.name"
  44. v-for="i in semesterData"
  45. />
  46. </el-select>
  47. </div>
  48. <div class="condition">
  49. <span class="title">年级 : </span>
  50. <el-select
  51. v-model="searchInput.grade"
  52. placeholder="请选择年级"
  53. style="width: 160px"
  54. @change="searchBtn"
  55. :clearable="true"
  56. >
  57. <el-option
  58. v-for="i in gradeData"
  59. :label="i.name"
  60. :value="`${i.name}-${i.id}`"
  61. >
  62. </el-option>
  63. </el-select>
  64. </div>
  65. <div class="condition">
  66. <span class="title">班级 : </span>
  67. <el-tooltip
  68. class="box-item"
  69. effect="dark"
  70. content="请先选择年级"
  71. placement="top"
  72. >
  73. <el-select
  74. v-model="searchInput.class"
  75. placeholder="请选择班级"
  76. style="width: 160px"
  77. @change="searchBtn"
  78. :clearable="true"
  79. >
  80. <el-option
  81. v-for="i in classsData"
  82. :label="i.name"
  83. :value="i.name"
  84. />
  85. </el-select>
  86. </el-tooltip>
  87. </div>
  88. <div class="condition">
  89. <span class="title">学科 : </span>
  90. <el-tooltip
  91. class="box-item"
  92. effect="dark"
  93. content="请先选择年级"
  94. placement="top"
  95. >
  96. <el-select
  97. v-model="searchInput.subject"
  98. class="sel"
  99. placeholder="请选择学科"
  100. style="width: 160px"
  101. @change="searchBtn"
  102. :clearable="true"
  103. >
  104. <el-option
  105. v-for="i in subjectData"
  106. :label="i.name"
  107. :value="i.name"
  108. />
  109. </el-select>
  110. </el-tooltip>
  111. </div>
  112. <div class="condition">
  113. <span class="title">考试类型 : </span>
  114. <el-tooltip
  115. class="box-item"
  116. effect="dark"
  117. content="请先选择年级"
  118. placement="top"
  119. >
  120. <el-select
  121. v-model="searchInput.examType"
  122. class="sel"
  123. placeholder="请选择考试类型"
  124. style="width: 160px"
  125. @change="searchBtn"
  126. :clearable="true"
  127. >
  128. <el-option
  129. v-for="i in examTypeData"
  130. :label="i.name"
  131. :value="i.name"
  132. /> </el-select
  133. ></el-tooltip>
  134. </div>
  135. <div class="condition grade">
  136. <span class="title">成绩 : </span>
  137. <el-input
  138. @clear="searchBtn"
  139. v-model.trim="searchInput.gradeLow"
  140. class="grade_left"
  141. placeholder="最低成绩"
  142. style="width: 90px"
  143. @blur="gradeNumWatch"
  144. />
  145. <span class="line">-</span>
  146. <el-input
  147. :clearable="true"
  148. @clear="gradeClear"
  149. v-model.trim="searchInput.gradeHigh"
  150. class="grade_right"
  151. placeholder="最高成绩"
  152. style="width: 90px"
  153. @blur="gradeNumWatch"
  154. />
  155. </div>
  156. </div>
  157. <!-- 按钮列表 -->
  158. <div class="gongneng">
  159. <el-button
  160. type="primary"
  161. color="rgba(0, 97, 255, 1)"
  162. plain
  163. @click="importFile"
  164. >成绩导入</el-button
  165. >
  166. <el-tooltip
  167. class="box-item"
  168. effect="dark"
  169. content="根据上面的筛选条件导出内容"
  170. placement="top-start"
  171. >
  172. <el-button
  173. type="primary"
  174. color="rgba(0, 97, 255, 1)"
  175. plain
  176. @click="importExcel"
  177. >成绩导出</el-button
  178. >
  179. </el-tooltip>
  180. <el-button
  181. type="primary"
  182. color="rgba(0, 97, 255, 1)"
  183. plain
  184. @click="addClick"
  185. >新增成绩</el-button
  186. >
  187. <el-button type="danger" @click="delClick" plain>勾选删除</el-button>
  188. </div>
  189. </div>
  190. <div class="footer" v-loading="loading">
  191. <el-table
  192. :row-class-name="tableRowClassName"
  193. :data="tableData.list"
  194. @selection-change="handleSelectionChange"
  195. style="width: 100%"
  196. :header-cell-style="{
  197. background: 'rgba(240, 243, 247, 1)',
  198. height: '50px',
  199. border: 0,
  200. }"
  201. >
  202. <el-table-column align="center" type="selection" width="80" />
  203. <el-table-column
  204. align="center"
  205. prop="semester"
  206. width="200"
  207. label="学期"
  208. />
  209. <el-table-column align="center" prop="grade" label="年级" />
  210. <el-table-column align="center" prop="schoolClass" label="班级" />
  211. <el-table-column align="center" prop="subjectStr" label="学科" />
  212. <el-table-column align="center" prop="examTypeStr" label="考试类型" />
  213. <el-table-column align="center" prop="name" label="姓名" />
  214. <el-table-column align="center" prop="cardNo" label="学号" />
  215. <el-table-column align="center" prop="score" label="成绩" />
  216. <el-table-column align="center" prop="status" label="操作">
  217. <template #default="scope">
  218. <div class="look" @click="editClick(scope.row)">编辑</div>
  219. </template>
  220. </el-table-column>
  221. </el-table>
  222. </div>
  223. <!-- 分页组件 -->
  224. <div class="pageSize">
  225. <span></span>
  226. <el-pagination
  227. background
  228. :current-page="currentPage"
  229. :page-size="pageSize"
  230. layout="total, prev, pager, next, jumper, slot"
  231. :total="total"
  232. @update:current-page="handleCurrentChange"
  233. />
  234. </div>
  235. <!-- 编辑按钮 -->
  236. <el-dialog
  237. class="editDialog"
  238. v-model="editVisible"
  239. :close-on-click-modal="false"
  240. :close-on-press-escape="false"
  241. :title="titleDialog"
  242. align-center
  243. width="650"
  244. :before-close="cancelEdit"
  245. >
  246. <el-form
  247. ref="editRef"
  248. :model="editRuleForm"
  249. :rules="editRules"
  250. label-width="100px"
  251. class="demo-ruleForm"
  252. :size="formSize"
  253. label-position="right"
  254. status-icon
  255. >
  256. <el-form-item label="学期 :" prop="semester">
  257. <!-- <el-input
  258. v-model.trim="editRuleForm.semester"
  259. placeholder="请输入学期"
  260. style="width: 400px"
  261. /> -->
  262. <el-select
  263. v-model="editRuleForm.semester"
  264. filterable
  265. allow-create
  266. default-first-option
  267. :reserve-keyword="false"
  268. placeholder="请选择学期"
  269. style="width: 400px"
  270. >
  271. <el-option
  272. :label="i.name"
  273. :value="`${i.name}-${i.id}`"
  274. v-for="i in semesterData"
  275. />
  276. </el-select>
  277. </el-form-item>
  278. <el-form-item label="姓名 :" prop="name">
  279. <el-select
  280. v-model="editRuleForm.name"
  281. popper-class="gradeSelect"
  282. filterable
  283. remote
  284. :remote-method="studentMethod"
  285. placeholder="请选择姓名"
  286. style="width: 400px"
  287. @change="changeName"
  288. clearable
  289. >
  290. <el-option
  291. v-for="item in studentData"
  292. :label="`${item.name}·${item.id}`"
  293. :value="`${item.name}·${item.id}`"
  294. :key="item.id"
  295. >
  296. <span style="float: left">{{ item.name }}</span>
  297. <span
  298. style="
  299. float: right;
  300. color: var(--el-text-color-secondary);
  301. font-size: 13px;
  302. "
  303. >{{ item.id }}</span
  304. >
  305. </el-option>
  306. <template #footer>
  307. <div class="addStudentMore">
  308. <el-button
  309. v-if="
  310. studentCurrentPage < studentTotalPage &&
  311. studentTotalPage != 0
  312. "
  313. @click="addStudentMore"
  314. >加载更多+</el-button
  315. >
  316. </div>
  317. </template>
  318. </el-select>
  319. </el-form-item>
  320. <el-form-item label="年级 :" prop="yearClass">
  321. <el-select
  322. v-model="editRuleForm.yearClass"
  323. placeholder="请选择年级"
  324. disabled
  325. style="width: 400px"
  326. @change="yearClassChange"
  327. >
  328. <el-option
  329. v-for="i in gradeData"
  330. :label="i.name"
  331. :value="`${i.name}-${i.id}`"
  332. >
  333. <!-- <span style="float: left">{{ i.name }}</span> -->
  334. <!-- <span
  335. style="color: var(--el-text-color-secondary); font-size: 13px"
  336. >{{ i.id }}</span
  337. > -->
  338. </el-option>
  339. </el-select>
  340. </el-form-item>
  341. <el-form-item label="班级 :" prop="class">
  342. <el-select
  343. v-model="editRuleForm.class"
  344. placeholder="请选择班级"
  345. disabled
  346. style="width: 400px"
  347. >
  348. <el-option
  349. v-for="i in classsData"
  350. :label="i.name"
  351. :value="`${i.name}-${i.id}`"
  352. />
  353. </el-select>
  354. </el-form-item>
  355. <el-form-item label="学号 :" prop="schoolNum">
  356. <el-input
  357. disabled
  358. v-model.trim="editRuleForm.schoolNum"
  359. placeholder="请输入学号"
  360. style="width: 400px"
  361. />
  362. </el-form-item>
  363. <el-form-item label="学科 :" prop="subject">
  364. <el-select
  365. v-model="editRuleForm.subject"
  366. placeholder="请选择学科"
  367. style="width: 400px"
  368. >
  369. <el-option
  370. v-for="i in studentSubDatas"
  371. :label="i.name"
  372. :value="i.id"
  373. />
  374. </el-select>
  375. </el-form-item>
  376. <el-form-item label="考试类型 :" prop="examType">
  377. <el-select
  378. v-model="editRuleForm.examType"
  379. placeholder="请选择考试类型"
  380. style="width: 400px"
  381. >
  382. <el-option
  383. v-for="i in studentExamTypeDatas"
  384. :label="i.name"
  385. :value="i.id"
  386. />
  387. </el-select>
  388. </el-form-item>
  389. <el-form-item label="成绩 :" prop="grade">
  390. <el-input
  391. v-model.trim="editRuleForm.grade"
  392. placeholder="请输入成绩"
  393. style="width: 400px"
  394. />
  395. </el-form-item>
  396. <el-form-item class="options">
  397. <el-button
  398. color="rgba(41, 109, 227, 1)"
  399. class="queding"
  400. type="primary"
  401. @click="confirmEdit(editRef)"
  402. >
  403. 确认
  404. </el-button>
  405. <el-button @click="cancelEdit(editRef)">取消</el-button>
  406. </el-form-item>
  407. </el-form>
  408. </el-dialog>
  409. <!-- 勾选删除 -->
  410. <el-dialog
  411. class="closeAccount"
  412. v-model="selDelVisible"
  413. :close-on-click-modal="false"
  414. :close-on-press-escape="false"
  415. title="勾选删除"
  416. align-center
  417. width="500"
  418. :before-close="cancelSelDel"
  419. >
  420. <div class="content">
  421. <img src="@/assets/images/warning.png" alt="" />
  422. <span>确定对选中的成绩进行删除吗?删除后将无法恢复。</span>
  423. </div>
  424. <div class="option">
  425. <el-button
  426. color="rgba(41, 109, 227, 1)"
  427. class="queding"
  428. type="primary"
  429. @click="confirmSelDel"
  430. >
  431. 确认
  432. </el-button>
  433. <el-button @click="cancelSelDel">取消</el-button>
  434. </div>
  435. </el-dialog>
  436. <!-- 导入弹窗 -->
  437. <el-dialog
  438. class="importXlsx"
  439. v-model="importXlsx"
  440. :close-on-click-modal="false"
  441. :close-on-press-escape="false"
  442. title="导入文件"
  443. align-center
  444. width="409"
  445. :before-close="closeXlsx"
  446. >
  447. <div class="btn">
  448. <el-button
  449. color="rgba(0, 97, 255,1)"
  450. @click="importTemp"
  451. plain
  452. class="importTemp"
  453. >
  454. 模板下载</el-button
  455. >
  456. <el-upload
  457. class="avatar-uploader"
  458. action=""
  459. ref="upload"
  460. :on-preview="handlePreview"
  461. :on-remove="handleRemove"
  462. :on-change="handleChange"
  463. :http-request="handleUpload"
  464. :before-upload="beforeAvatarUpload"
  465. :auto-upload="false"
  466. :limit="1"
  467. :on-exceed="handleExceed"
  468. >
  469. <template #trigger>
  470. <el-button color="rgba(0, 97, 255, 1)" @click="updateImg" plain>
  471. 导入文件</el-button
  472. >
  473. </template>
  474. <!-- <template #tip>
  475. <div class="el-upload__tip">
  476. (注:图片大小不超过10M,建议按3:2比例)
  477. </div>
  478. </template> -->
  479. </el-upload>
  480. </div>
  481. <div class="options">
  482. <el-button
  483. color="rgba(0, 97, 255, 1)"
  484. class="queding"
  485. type="primary"
  486. @click="importSuc()"
  487. >
  488. 确定
  489. </el-button>
  490. <el-button class="congzhi" @click="closeXlsx()">取消</el-button>
  491. </div>
  492. </el-dialog>
  493. </div>
  494. <div class="bgImg" v-if="bgImg">
  495. <el-carousel
  496. @click="bgImg = false"
  497. ref="bgImgs"
  498. indicator-position
  499. arrow="always"
  500. :autoplay="false"
  501. trigger
  502. >
  503. <el-carousel-item v-for="item in bgImgList" :key="item.id">
  504. <img :src="item.url" alt="" />
  505. </el-carousel-item>
  506. </el-carousel>
  507. </div>
  508. </div>
  509. <div v-for="item in msgList">
  510. <div v-for="i in item.list">
  511. {{ i.name }}
  512. </div>
  513. </div>
  514. </template>
  515. <script setup>
  516. import {
  517. ref,
  518. reactive,
  519. watch,
  520. nextTick,
  521. onBeforeMount,
  522. onUnmounted,
  523. } from "vue";
  524. import { useRouter } from "vue-router";
  525. import { ElMessage, ElMessageBox } from "element-plus";
  526. import { Calendar } from "@element-plus/icons-vue";
  527. import vidiconsApi from "@/api/vidicons.js";
  528. import { dayjs } from "element-plus";
  529. import eds from "@/utils/eds.js";
  530. import lodash from "lodash";
  531. import axios from "axios";
  532. import { useStore } from "vuex";
  533. const store = useStore();
  534. const api = ref("");
  535. const router = useRouter();
  536. // 表格数据
  537. const loading = ref(false);
  538. const tableData = reactive({
  539. list: [
  540. {
  541. xq: "2019-2020秋季学期(下学期)",
  542. nj: "七年级",
  543. bj: "一班",
  544. xk: "语文",
  545. ks: "期中考试",
  546. xm: "张三",
  547. xh: "000001",
  548. cj: "85",
  549. },
  550. ],
  551. });
  552. const semesterData = ref(); //学期下拉数据
  553. const gradeData = ref(); //年级下拉数据
  554. const classsData = ref(); //班级下拉数据
  555. const subjectData = ref(); //学科下拉数据
  556. const examTypeData = ref(); //考试类型数据
  557. const searchInput = reactive({
  558. keyWord: "",
  559. semester: "", // 学期
  560. grade: "", // 年级
  561. class: "", // 班级
  562. subject: "", // 学科
  563. examType: "", // 考试类型
  564. gradeLow: "", // 最低成绩
  565. gradeHigh: "", // 最高成绩
  566. }); // 搜索按钮数据
  567. // 失去焦点时成绩最低和最高判定
  568. const gradeNumWatch = () => {
  569. let reg = /^[0-9]*[1-9][0-9]*$/;
  570. // 最低成绩和最高成绩判定
  571. if (searchInput.gradeLow != "" && searchInput.gradeHigh != "") {
  572. if (reg.test(searchInput.gradeLow) && reg.test(searchInput.gradeHigh)) {
  573. if (Number(searchInput.gradeLow) < Number(searchInput.gradeHigh)) {
  574. getList();
  575. } else {
  576. ElMessage({
  577. type: "warning",
  578. showClose: true,
  579. message: "最低成绩不能大于最高成绩",
  580. center: true,
  581. });
  582. }
  583. } else {
  584. ElMessage({
  585. type: "warning",
  586. showClose: true,
  587. message: "请输入正确的成绩",
  588. center: true,
  589. });
  590. }
  591. }
  592. };
  593. const currentPage = ref(1); // 当前页
  594. const pageSize = ref(8);
  595. const total = ref(5); // 当前总数
  596. const selectData = reactive({ list: [] }); // 表格勾选的数据
  597. // 新增成绩中的学生分页列表
  598. const studentData = ref();
  599. const studentCurrentPage = ref(1);
  600. const studentPageSize = ref(50);
  601. const studentTotalPage = ref(); // 学生分页总共多少页,判断滚动到底是否还要加载
  602. const studentInput = ref(); // 学生分页下拉框中的搜索字段
  603. const studentExamTypeDatas = ref(); // 编辑中的考试类型数据
  604. const studentSubDatas = ref(); // 编辑中的学科数据
  605. // 编辑功能
  606. const titleDialog = ref("");
  607. const editVisible = ref(false);
  608. const editRef = ref();
  609. const editRuleForm = reactive({
  610. semester: "", // 学期
  611. yearClass: "", // 年级
  612. class: "", // 班级
  613. name: "", // 姓名
  614. schoolNum: "", // 学号
  615. subject: "", // 学科
  616. examType: "", // 考试类型
  617. grade: "", // 成绩
  618. id: "",
  619. });
  620. // 成绩验证
  621. const validateGrade = (rule, value, callback) => {
  622. if (/^(?!0+(?:\.0+)?$)(?:[1-9]\d*|0)(?:\.\d{1,2})?$/.test(value)) {
  623. callback();
  624. } else {
  625. callback(new Error("请输入正确的成绩"));
  626. }
  627. };
  628. // 表单验证
  629. const editRules = reactive({
  630. semester: [{ required: true, message: "学期不能为空", trigger: "blur" }],
  631. yearClass: [
  632. {
  633. required: true,
  634. message: "年级不能为空",
  635. trigger: "blur",
  636. },
  637. ],
  638. class: [
  639. {
  640. required: true,
  641. message: "班级不能为空",
  642. trigger: "blur",
  643. },
  644. ],
  645. name: [
  646. {
  647. required: true,
  648. message: "姓名不能为空",
  649. trigger: "blur",
  650. },
  651. ],
  652. schoolNum: [
  653. {
  654. required: true,
  655. message: "学号不能为空",
  656. trigger: "blur",
  657. },
  658. ],
  659. subject: [
  660. {
  661. required: true,
  662. message: "学科不能为空",
  663. trigger: "blur",
  664. },
  665. ],
  666. examType: [
  667. {
  668. required: true,
  669. message: "考试类型不能为空",
  670. trigger: "blur",
  671. },
  672. ],
  673. grade: [
  674. {
  675. required: true,
  676. message: "成绩不能为空",
  677. trigger: "blur",
  678. },
  679. { validator: validateGrade, trigger: "blur" },
  680. ],
  681. });
  682. // 删除弹窗
  683. const selDelVisible = ref(false);
  684. // 导入按钮
  685. const upload = ref(); // 导入按钮ref
  686. const fileXlsx = ref(); // 导入的文件file
  687. const importXlsx = ref(false); // 导入弹窗
  688. // 获取学期下拉
  689. const semesterList = async () => {
  690. let semester = await axios({
  691. method: "get",
  692. url: api.value + "/wanzai/api/smartScore/querySmartSemesters",
  693. headers: {
  694. token: sessionStorage.getItem("token"),
  695. user_head: sessionStorage.getItem("userhead"),
  696. },
  697. // params: data,
  698. });
  699. console.log(
  700. semester,
  701. JSON.parse(eds.decryptDes(semester.data.data)),
  702. "学期下拉数据"
  703. );
  704. semesterData.value = JSON.parse(eds.decryptDes(semester.data.data));
  705. };
  706. // 年级数据下拉
  707. const classDataList = async () => {
  708. semesterList();
  709. let grade = await axios({
  710. method: "get",
  711. url: api.value + "/wanzai/api/smartGrade/querySmartGrades",
  712. headers: {
  713. token: sessionStorage.getItem("token"),
  714. user_head: sessionStorage.getItem("userhead"),
  715. },
  716. // params: data,
  717. });
  718. console.log(
  719. grade,
  720. JSON.parse(eds.decryptDes(grade.data.data)),
  721. "年级下拉数据"
  722. );
  723. gradeData.value = JSON.parse(eds.decryptDes(grade.data.data));
  724. // classInfoList()// 班级下拉数据
  725. };
  726. // 改变年级选择
  727. const yearClassChange = async (value) => {
  728. console.log(value);
  729. editRuleForm.class = "";
  730. let arr = value.split("-");
  731. classInfoList(arr[1]);
  732. };
  733. // 班级数据下拉
  734. const classInfoList = async (value) => {
  735. let data = {
  736. gradeId: value,
  737. };
  738. let classs = await axios({
  739. method: "get",
  740. url: api.value + "/wanzai/api/smartClass/querySmartClasss",
  741. headers: {
  742. token: sessionStorage.getItem("token"),
  743. user_head: sessionStorage.getItem("userhead"),
  744. },
  745. params: data,
  746. });
  747. if (classs.data.code == 200) {
  748. console.log(
  749. classs,
  750. JSON.parse(eds.decryptDes(classs.data.data)),
  751. "班级下拉数据"
  752. );
  753. classsData.value = JSON.parse(eds.decryptDes(classs.data.data));
  754. } else {
  755. classsData.value = [];
  756. }
  757. };
  758. // 考试类型数据
  759. const examTypeList = async (value) => {
  760. if (searchInput.grade) {
  761. let examType = await axios({
  762. method: "get",
  763. url: api.value + "/wanzai/api/smartScore/queryExamTypes",
  764. headers: {
  765. token: sessionStorage.getItem("token"),
  766. user_head: sessionStorage.getItem("userhead"),
  767. },
  768. params: {
  769. gradeId: value,
  770. },
  771. });
  772. console.log(value);
  773. console.log(
  774. examType,
  775. JSON.parse(eds.decryptDes(examType.data.data)),
  776. "考试类型下拉数据"
  777. );
  778. if (examType.data.code == 200) {
  779. examTypeData.value = JSON.parse(eds.decryptDes(examType.data.data));
  780. }
  781. } else {
  782. examTypeData.value = [];
  783. }
  784. };
  785. // 学科数据
  786. const subjectList = async (value) => {
  787. if (searchInput.grade) {
  788. let subject = await axios({
  789. method: "get",
  790. url: api.value + "/wanzai/api/smartScore/querySubjects",
  791. headers: {
  792. token: sessionStorage.getItem("token"),
  793. user_head: sessionStorage.getItem("userhead"),
  794. },
  795. params: {
  796. gradeId: value,
  797. },
  798. });
  799. console.log(
  800. subject,
  801. JSON.parse(eds.decryptDes(subject.data.data)),
  802. "学科下拉数据"
  803. );
  804. subjectData.value = JSON.parse(eds.decryptDes(subject.data.data));
  805. } else {
  806. subjectData.value = [];
  807. }
  808. };
  809. // 获取成绩分页数据 (----------------------------------------------------------------)
  810. const getList = async () => {
  811. loading.value = true;
  812. if (searchInput.grade) {
  813. classInfoList(searchInput.grade.split("-")[1]);
  814. examTypeList(searchInput.grade.split("-")[1]);
  815. subjectList(searchInput.grade.split("-")[1]);
  816. } else {
  817. searchInput.class = "";
  818. searchInput.subject = "";
  819. searchInput.examType = "";
  820. subjectData.value = [];
  821. classsData.value = [];
  822. examTypeData.value = [];
  823. }
  824. let data = {
  825. currentPage: currentPage.value,
  826. pageCount: pageSize.value,
  827. name: searchInput.keyWord, // 用户名称
  828. semester: searchInput.semester,
  829. // grade: searchInput.grade,
  830. schoolClass: searchInput.class,
  831. subject: searchInput.subject,
  832. examType: searchInput.examType,
  833. MinScore: searchInput.gradeLow,
  834. MaxScore: searchInput.gradeHigh,
  835. };
  836. if (searchInput.grade) {
  837. data.grade = searchInput.grade.split("-")[0];
  838. }
  839. let res = await axios({
  840. method: "get",
  841. url: api.value + "/wanzai/api/smartScore/querySmartScorePage",
  842. headers: {
  843. token: sessionStorage.getItem("token"),
  844. user_head: sessionStorage.getItem("userhead"),
  845. },
  846. params: data,
  847. });
  848. console.log(res, JSON.parse(eds.decryptDes(res.data.data)), "成绩分页数据");
  849. if (res.data.code == 200) {
  850. loading.value = false;
  851. tableData.list = JSON.parse(eds.decryptDes(res.data.data)).list;
  852. total.value = JSON.parse(eds.decryptDes(res.data.data)).totalCount;
  853. // ElMessage({
  854. // type: "success",
  855. // showClose: true,
  856. // message: res.data.message,
  857. // center: true,
  858. // });
  859. } else {
  860. loading.value = false;
  861. ElMessage({
  862. type: "error",
  863. showClose: true,
  864. message: res.data.message,
  865. center: true,
  866. });
  867. }
  868. };
  869. // 搜索功能
  870. const searchBtn = lodash.debounce(async () => {
  871. getList();
  872. }, 300);
  873. // 搜索 清除年级数据时
  874. const nianJiClear = () => {
  875. if (searchInput.grade) {
  876. classInfoList(searchInput.grade.split("-")[1]);
  877. examTypeList(searchInput.grade.split("-")[1]);
  878. subjectList(searchInput.grade.split("-")[1]);
  879. getList();
  880. } else {
  881. subjectData.value = [];
  882. classsData.value = [];
  883. examTypeData.value = [];
  884. }
  885. };
  886. // 成绩查询
  887. const gradeClear = () => {
  888. searchInput.gradeLow = "";
  889. searchInput.gradeHigh = "";
  890. getList();
  891. };
  892. // 添加按钮 (-------------------------------------------)
  893. const addClick = async () => {
  894. titleDialog.value = "新增成绩";
  895. editVisible.value = true;
  896. studentCurrentPage.value = 1;
  897. studentList();
  898. // studentListScroll();
  899. editRuleForm.semester = "";
  900. editRuleForm.yearClass = "";
  901. editRuleForm.class = "";
  902. editRuleForm.name = "";
  903. editRuleForm.schoolNum = "";
  904. editRuleForm.subject = "";
  905. editRuleForm.examType = "";
  906. editRuleForm.grade = "";
  907. editRuleForm.id = "";
  908. classsData.value = []; // 新增时将班级下拉数据置为空
  909. };
  910. // 获取学生分页列表
  911. const studentList = async () => {
  912. let data = {
  913. currentPage: studentCurrentPage.value,
  914. pageCount: studentPageSize.value,
  915. name: studentInput.value, // 用户名称
  916. };
  917. let student = await axios({
  918. method: "get",
  919. url: api.value + "/wanzai/api/smartScore/querySmartSecordPage",
  920. headers: {
  921. token: sessionStorage.getItem("token"),
  922. user_head: sessionStorage.getItem("userhead"),
  923. },
  924. params: data,
  925. });
  926. console.log(
  927. student,
  928. JSON.parse(eds.decryptDes(student.data.data)),
  929. "学生分页数据"
  930. );
  931. studentData.value = JSON.parse(eds.decryptDes(student.data.data)).list;
  932. studentTotalPage.value = JSON.parse(
  933. eds.decryptDes(student.data.data)
  934. ).totalPage;
  935. };
  936. // 联系人下拉框搜索时加载
  937. const studentMethod = (query) => {
  938. console.log(query);
  939. studentInput.value = query;
  940. studentCurrentPage.value = 1;
  941. studentList(); // 调用学生分页接口
  942. };
  943. // 学生分页触底加载更多
  944. const studentListScroll = () => {
  945. nextTick(() => {
  946. const domElementNode = document.querySelector(
  947. ".gradeSelect .el-select-dropdown__wrap"
  948. );
  949. console.log(domElementNode);
  950. // 注册下拉滚动事件
  951. domElementNode.addEventListener("scroll", async () => {
  952. const isBottom =
  953. domElementNode.scrollHeight - domElementNode.scrollTop <=
  954. domElementNode.clientHeight;
  955. if (isBottom) {
  956. if (studentCurrentPage.value < studentTotalPage.value) {
  957. studentCurrentPage.value++;
  958. console.log(studentCurrentPage.value, "滚动里面");
  959. let data = {
  960. currentPage: studentCurrentPage.value,
  961. pageCount: studentPageSize.value,
  962. name: studentInput.value,
  963. };
  964. let res = await axios({
  965. method: "get",
  966. url: api.value + "/wanzai/api/smartScore/querySmartSecordPage",
  967. headers: {
  968. token: sessionStorage.getItem("token"),
  969. user_head: sessionStorage.getItem("userhead"),
  970. },
  971. params: data,
  972. });
  973. console.log(
  974. res,
  975. JSON.parse(eds.decryptDes(res.data.data)),
  976. "联系人数据"
  977. );
  978. studentData.value = [
  979. ...studentData.value,
  980. ...JSON.parse(eds.decryptDes(res.data.data)).list,
  981. ];
  982. } else {
  983. console.log("数据全部加载完成");
  984. }
  985. }
  986. });
  987. });
  988. };
  989. // 学生列表点击 加载更多
  990. const addStudentMore = async () => {
  991. if (studentCurrentPage.value < studentTotalPage.value) {
  992. studentCurrentPage.value++;
  993. console.log(studentCurrentPage.value, "滚动里面");
  994. let data = {
  995. currentPage: studentCurrentPage.value,
  996. pageCount: studentPageSize.value,
  997. name: studentInput.value,
  998. };
  999. let res = await axios({
  1000. method: "get",
  1001. url: api.value + "/wanzai/api/smartScore/querySmartSecordPage",
  1002. headers: {
  1003. token: sessionStorage.getItem("token"),
  1004. user_head: sessionStorage.getItem("userhead"),
  1005. },
  1006. params: data,
  1007. });
  1008. console.log(res, JSON.parse(eds.decryptDes(res.data.data)), "联系人数据");
  1009. studentData.value = [
  1010. ...studentData.value,
  1011. ...JSON.parse(eds.decryptDes(res.data.data)).list,
  1012. ];
  1013. }
  1014. };
  1015. //编辑按钮 (-------------------------------------------)
  1016. const editClick = async (row) => {
  1017. editVisible.value = true;
  1018. console.log(row, "编辑信息");
  1019. titleDialog.value = "编辑成绩";
  1020. studentCurrentPage.value = 1;
  1021. studentList(); // 学生分页
  1022. // studentListScroll(); // 学生分页触底加载更多
  1023. classInfoList(row.gradeId); // 班级下拉
  1024. // 考试类型
  1025. let examType = await axios({
  1026. method: "get",
  1027. url: api.value + "/wanzai/api/smartScore/queryExamTypes",
  1028. headers: {
  1029. token: sessionStorage.getItem("token"),
  1030. user_head: sessionStorage.getItem("userhead"),
  1031. },
  1032. params: {
  1033. gradeId: row.gradeId,
  1034. },
  1035. });
  1036. if (examType.data.code == 200) {
  1037. studentExamTypeDatas.value = JSON.parse(eds.decryptDes(examType.data.data));
  1038. } else {
  1039. studentExamTypeDatas.value = [];
  1040. }
  1041. // 学科数据
  1042. let subject = await axios({
  1043. method: "get",
  1044. url: api.value + "/wanzai/api/smartScore/querySubjects",
  1045. headers: {
  1046. token: sessionStorage.getItem("token"),
  1047. user_head: sessionStorage.getItem("userhead"),
  1048. },
  1049. params: {
  1050. gradeId: row.gradeId,
  1051. },
  1052. });
  1053. console.log(
  1054. subject,
  1055. JSON.parse(eds.decryptDes(subject.data.data)),
  1056. "学科下拉数据"
  1057. );
  1058. if (subject.data.code == 200) {
  1059. studentSubDatas.value = JSON.parse(eds.decryptDes(subject.data.data));
  1060. } else {
  1061. studentSubDatas.value = [];
  1062. }
  1063. editRuleForm.semester = `${row.semester}-${row.semesterId}`;
  1064. editRuleForm.yearClass = `${row.grade}-${row.gradeId}`;
  1065. editRuleForm.class = `${row.schoolClass}-${row.schoolClassId}`;
  1066. editRuleForm.name = `${row.name}·${row.userId}`;
  1067. editRuleForm.schoolNum = row.cardNo;
  1068. editRuleForm.subject = row.subject;
  1069. editRuleForm.examType = row.examType;
  1070. editRuleForm.grade = row.score;
  1071. editRuleForm.id = row.id;
  1072. };
  1073. // 取消编辑按钮
  1074. const cancelEdit = () => {
  1075. editVisible.value = false;
  1076. editRef.value.resetFields();
  1077. };
  1078. // 编辑中选择了姓名学号 默认填写
  1079. const changeName = async (value) => {
  1080. console.log(value);
  1081. editRuleForm.subject = "";
  1082. editRuleForm.examType = "";
  1083. editRuleForm.grade = "";
  1084. editRuleForm.yearClass = "";
  1085. editRuleForm.class = "";
  1086. editRuleForm.schoolNum = "";
  1087. if (value) {
  1088. let data = { id: value.split("·")[1] };
  1089. let res = await axios({
  1090. method: "get",
  1091. url: api.value + "/wanzai/api/smartUser/queryUserData",
  1092. headers: {
  1093. token: sessionStorage.getItem("token"),
  1094. user_head: sessionStorage.getItem("userhead"),
  1095. },
  1096. params: data,
  1097. });
  1098. if (res.data.code == 200) {
  1099. console.log(
  1100. JSON.parse(eds.decryptDes(res.data.data)),
  1101. "切换id获取学生信息"
  1102. );
  1103. let data = JSON.parse(eds.decryptDes(res.data.data));
  1104. editRuleForm.yearClass = data.grade + "-" + data.gradeId;
  1105. classInfoList(data.gradeId);
  1106. editRuleForm.class = data.schoolClass + "-" + data.schoolClassId;
  1107. editRuleForm.schoolNum = data.cardNo;
  1108. }
  1109. let examType = await axios({
  1110. method: "get",
  1111. url: api.value + "/wanzai/api/smartScore/queryExamTypes",
  1112. headers: {
  1113. token: sessionStorage.getItem("token"),
  1114. user_head: sessionStorage.getItem("userhead"),
  1115. },
  1116. params: {
  1117. gradeId: editRuleForm.yearClass.split("-")[1],
  1118. },
  1119. });
  1120. if (examType.data.code == 200) {
  1121. studentExamTypeDatas.value = JSON.parse(
  1122. eds.decryptDes(examType.data.data)
  1123. );
  1124. } else {
  1125. studentExamTypeDatas.value = [];
  1126. }
  1127. let subject = await axios({
  1128. method: "get",
  1129. url: api.value + "/wanzai/api/smartScore/querySubjects",
  1130. headers: {
  1131. token: sessionStorage.getItem("token"),
  1132. user_head: sessionStorage.getItem("userhead"),
  1133. },
  1134. params: {
  1135. gradeId: editRuleForm.yearClass.split("-")[1],
  1136. },
  1137. });
  1138. console.log(
  1139. subject,
  1140. JSON.parse(eds.decryptDes(subject.data.data)),
  1141. "学科下拉数据"
  1142. );
  1143. if (subject.data.code == 200) {
  1144. studentSubDatas.value = JSON.parse(eds.decryptDes(subject.data.data));
  1145. } else {
  1146. studentSubDatas.value = [];
  1147. }
  1148. }
  1149. };
  1150. // 确定编辑
  1151. const confirmEdit = (formEl) => {
  1152. if (!formEl) return;
  1153. formEl.validate(async (valid, fields) => {
  1154. if (valid) {
  1155. if (titleDialog.value == "新增成绩") {
  1156. let data = {
  1157. semester: editRuleForm.semester.split("-")[0], // 学期
  1158. semesterId: editRuleForm.semester.split("-")[1], // 学期id
  1159. grade: editRuleForm.yearClass.split("-")[0], // 年级
  1160. gradeId: editRuleForm.yearClass.split("-")[1], // 年级
  1161. schoolClass: editRuleForm.class.split("-")[0], // 班级
  1162. schoolClassId: editRuleForm.class.split("-")[1], // 班级
  1163. cardNo: editRuleForm.schoolNum, // 学号
  1164. userId: editRuleForm.name.split("·")[1], // 用户ID
  1165. subjectId: editRuleForm.subject, // 学科ID
  1166. examType: editRuleForm.examType, // 考试类型
  1167. score: editRuleForm.grade, // 成绩
  1168. };
  1169. let res = await axios({
  1170. method: "post",
  1171. url: api.value + "/wanzai/api/smartScore/insertSmartScore",
  1172. headers: {
  1173. token: sessionStorage.getItem("token"),
  1174. user_head: sessionStorage.getItem("userhead"),
  1175. },
  1176. data: data,
  1177. });
  1178. console.log(res, "新增成绩");
  1179. if (res.data.code == 200) {
  1180. getList();
  1181. semesterList();
  1182. editVisible.value = false;
  1183. editRef.value.resetFields();
  1184. ElMessage({
  1185. type: "success",
  1186. showClose: true,
  1187. message: res.data.message,
  1188. center: true,
  1189. });
  1190. } else {
  1191. ElMessage({
  1192. type: "error",
  1193. showClose: true,
  1194. message: res.data.message,
  1195. center: true,
  1196. });
  1197. }
  1198. } else if (titleDialog.value == "编辑成绩") {
  1199. let data = {
  1200. semester: editRuleForm.semester.split("-")[0], // 学期
  1201. semesterId: editRuleForm.semester.split("-")[1], // 学期id
  1202. grade: editRuleForm.yearClass.split("-")[0], // 年级
  1203. gradeId: editRuleForm.yearClass.split("-")[1], // 年级
  1204. schoolClass: editRuleForm.class.split("-")[0], // 班级
  1205. schoolClassId: editRuleForm.class.split("-")[1], // 班级
  1206. cardNo: editRuleForm.schoolNum, // 学号
  1207. userId: editRuleForm.name.split("·")[1], // 用户ID
  1208. subjectId: editRuleForm.subject, // 学科ID
  1209. examType: editRuleForm.examType, // 考试类型
  1210. score: editRuleForm.grade, // 成绩
  1211. id: editRuleForm.id,
  1212. };
  1213. let res = await axios({
  1214. method: "post",
  1215. url: api.value + "/wanzai/api/smartScore/updateSmartScoreById",
  1216. headers: {
  1217. token: sessionStorage.getItem("token"),
  1218. user_head: sessionStorage.getItem("userhead"),
  1219. },
  1220. data: data,
  1221. });
  1222. console.log(res, "编辑成绩");
  1223. if (res.data.code == 200) {
  1224. getList();
  1225. semesterList();
  1226. editVisible.value = false;
  1227. editRef.value.resetFields();
  1228. ElMessage({
  1229. type: "success",
  1230. showClose: true,
  1231. message: res.data.message,
  1232. center: true,
  1233. });
  1234. } else {
  1235. ElMessage({
  1236. type: "error",
  1237. showClose: true,
  1238. message: res.data.message,
  1239. center: true,
  1240. });
  1241. }
  1242. }
  1243. }
  1244. });
  1245. };
  1246. //删除按钮 (-------------------------------------------------------)
  1247. const delClick = async () => {
  1248. if (selectData.list.length >= 1) {
  1249. selDelVisible.value = true;
  1250. } else {
  1251. ElMessage({
  1252. type: "warning",
  1253. showClose: true,
  1254. message: "请先选定所需要删除的成绩!",
  1255. center: true,
  1256. });
  1257. }
  1258. };
  1259. // 确定删除
  1260. const confirmSelDel = async () => {
  1261. let userId = [];
  1262. selectData.list.forEach((i) => {
  1263. userId.push(i.id);
  1264. });
  1265. let data = {
  1266. ids: userId,
  1267. };
  1268. let res = await axios({
  1269. method: "post",
  1270. url: api.value + "/wanzai/api/smartScore/deleteSmartScoreByIds",
  1271. headers: {
  1272. token: sessionStorage.getItem("token"),
  1273. user_head: sessionStorage.getItem("userhead"),
  1274. },
  1275. data: data,
  1276. });
  1277. console.log(res, "删除成功");
  1278. if (res.data.code == 200) {
  1279. selDelVisible.value = false;
  1280. if (
  1281. selectData.list.length == tableData.list.length &&
  1282. currentPage.value != 1
  1283. ) {
  1284. currentPage.value = currentPage.value - 1;
  1285. }
  1286. getList();
  1287. ElMessage({
  1288. type: "success",
  1289. showClose: true,
  1290. message: res.data.message,
  1291. center: true,
  1292. });
  1293. } else {
  1294. ElMessage({
  1295. type: "error",
  1296. showClose: true,
  1297. message: res.data.message,
  1298. center: true,
  1299. });
  1300. }
  1301. };
  1302. const cancelSelDel = () => {
  1303. selDelVisible.value = false;
  1304. };
  1305. // 表格勾选删除成绩
  1306. const handleSelectionChange = (val) => {
  1307. console.log(val);
  1308. selectData.list = val;
  1309. };
  1310. //导出功能 (-----------------------------------------------------------------)
  1311. const importExcel = async () => {
  1312. let data = {
  1313. name: searchInput.keyWord,
  1314. semester: searchInput.semester,
  1315. grade: searchInput.grade,
  1316. schoolClass: searchInput.class,
  1317. subject: searchInput.subject,
  1318. examType: searchInput.examType,
  1319. MinScore: searchInput.gradeLow,
  1320. MaxScore: searchInput.gradeHigh,
  1321. };
  1322. let res = await axios({
  1323. method: "get",
  1324. url: api.value + "/wanzai/api/smartScore/smartUserExport",
  1325. headers: {
  1326. token: sessionStorage.getItem("token"),
  1327. user_head: sessionStorage.getItem("userhead"),
  1328. },
  1329. params: data,
  1330. responseType: "blob",
  1331. });
  1332. console.log(res, "导出用户");
  1333. if (res.status == 200) {
  1334. let name = `成绩表信息`;
  1335. var content = res.data;
  1336. var datas = new Blob([content]);
  1337. var downloadUrl = window.URL.createObjectURL(datas);
  1338. var anchor = document.createElement("a");
  1339. anchor.href = downloadUrl;
  1340. anchor.download = name + ".xlsx";
  1341. anchor.click();
  1342. window.URL.revokeObjectURL(datas);
  1343. ElMessage({
  1344. type: "success",
  1345. showClose: true,
  1346. message: "导出成功",
  1347. center: true,
  1348. });
  1349. } else {
  1350. ElMessage({
  1351. type: "error",
  1352. showClose: true,
  1353. message: "导出失败",
  1354. center: true,
  1355. });
  1356. }
  1357. };
  1358. // 添导入文件功能 (--------------------------------------------------------------------)
  1359. const importFile = () => {
  1360. importXlsx.value = true;
  1361. };
  1362. const closeXlsx = () => {
  1363. importXlsx.value = false;
  1364. fileXlsx.value = "";
  1365. upload.value.clearFiles();
  1366. };
  1367. // 导出模板
  1368. const importTemp = async () => {
  1369. let res = await axios({
  1370. method: "get",
  1371. url: api.value + "/wanzai/api/smartScore/downloadScoreExcel",
  1372. headers: {
  1373. token: sessionStorage.getItem("token"),
  1374. user_head: sessionStorage.getItem("userhead"),
  1375. },
  1376. // responseType: "blob",
  1377. });
  1378. console.log(res, "导出模板");
  1379. if (res.status == 200) {
  1380. var downloadPath = JSON.parse(eds.decryptDes(res.data.data));
  1381. window.location.href = downloadPath;
  1382. var downloadLink = document.createElement("a");
  1383. downloadLink.style.display = "none"; // 使其隐藏
  1384. downloadLink.href = downloadPath;
  1385. downloadLink.download = "";
  1386. downloadLink.click();
  1387. document.body.appendChild(downloadLink);
  1388. document.body.removeChild(downloadLink);
  1389. ElMessage({
  1390. type: "success",
  1391. showClose: true,
  1392. message: "导出成功",
  1393. center: true,
  1394. });
  1395. } else {
  1396. ElMessage({
  1397. type: "error",
  1398. showClose: true,
  1399. message: "导出失败",
  1400. center: true,
  1401. });
  1402. }
  1403. };
  1404. // upload http-request
  1405. const handleChange = (file, fileLists) => {
  1406. console.log(file, "file11111");
  1407. // let formData = new FormData(); //声明一个FormDate对象
  1408. // formData.append("formFile", file.raw);
  1409. // fileXlsx.value = formData;
  1410. fileXlsx.value = file.raw;
  1411. };
  1412. // 可以获取文件参数(封面图上传图片)
  1413. const handleUpload = (file) => {
  1414. console.log(file, "file22222");
  1415. };
  1416. // 移出文件
  1417. const handleRemove = (uploadFile, uploadFiles) => {
  1418. console.log(uploadFile, uploadFiles);
  1419. fileXlsx.value = "";
  1420. };
  1421. // 限制上传图片的大小类型
  1422. const beforeAvatarUpload = (rawFile) => {
  1423. console.log(rawFile.type);
  1424. if (
  1425. rawFile.type !==
  1426. "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
  1427. ) {
  1428. ElMessage.error("文件必须为xlsx格式!");
  1429. return false;
  1430. }
  1431. // else if (rawFile.size / 1024 / 1024 > 10) {
  1432. // ElMessage.error("图片的大小不能超过10MB!");
  1433. // return false;
  1434. // }
  1435. return true;
  1436. };
  1437. // 上传文件时多次上传会替换前一个文件
  1438. const handleExceed = (files) => {
  1439. console.log(files, "替换文件");
  1440. upload.value.clearFiles();
  1441. const file = files[0];
  1442. upload.value.handleStart(file);
  1443. // let formData = new FormData(); //声明一个FormDate对象
  1444. // formData.append("formFile", files.raw);
  1445. // fileXlsx.value = formData;
  1446. fileXlsx.value = files.raw;
  1447. };
  1448. // 确定导入文件
  1449. const importSuc = async () => {
  1450. console.log("确定导入");
  1451. let data = {
  1452. file: fileXlsx.value,
  1453. };
  1454. let res = await axios({
  1455. method: "post",
  1456. url: api.value + "/wanzai/api/smartScore/importSmartScoreExcel",
  1457. headers: {
  1458. token: sessionStorage.getItem("token"),
  1459. user_head: sessionStorage.getItem("userhead"),
  1460. "Content-Type": "multipart/form-data;charset=UTF-8",
  1461. },
  1462. data: data,
  1463. });
  1464. console.log(res);
  1465. if (res.data.code == 200) {
  1466. importXlsx.value = false;
  1467. upload.value.clearFiles();
  1468. getList();
  1469. ElMessage({
  1470. type: "success",
  1471. showClose: true,
  1472. message: res.data.message,
  1473. center: true,
  1474. });
  1475. } else {
  1476. ElMessage({
  1477. type: "error",
  1478. showClose: true,
  1479. message: res.data.message,
  1480. center: true,
  1481. });
  1482. }
  1483. };
  1484. // 表格斑马纹颜色修改
  1485. const tableRowClassName = ({ row, rowIndex }) => {
  1486. if (rowIndex % 2 === 0) {
  1487. return "even";
  1488. } else if (rowIndex % 2 !== 0) {
  1489. return "odd";
  1490. }
  1491. return "";
  1492. };
  1493. // 分页
  1494. const handleCurrentChange = (value) => {
  1495. // console.log(value);
  1496. currentPage.value = value;
  1497. getList();
  1498. };
  1499. onBeforeMount(async () => {
  1500. api.value = store.state.user.api;
  1501. getList();
  1502. classDataList();
  1503. });
  1504. onUnmounted(() => {
  1505. // document.removeEventListener("keyup", Enters);
  1506. });
  1507. </script>
  1508. <style scoped lang="scss">
  1509. .content-box {
  1510. min-width: 500px;
  1511. width: calc(100vw - 260px);
  1512. height: calc(100vh - 105px);
  1513. margin: 20px auto;
  1514. background-color: #fff;
  1515. color: #fff;
  1516. display: flex;
  1517. flex-direction: column;
  1518. box-shadow: 0px 3px 10px rgba(0, 97, 255, 0.2);
  1519. .left {
  1520. // width: calc(100wh - 40px);
  1521. display: flex;
  1522. align-items: center;
  1523. height: 60px;
  1524. margin: 0 30px;
  1525. border-bottom: 1px solid #ccc;
  1526. color: rgb(0, 0, 0);
  1527. font-size: 18px;
  1528. font-weight: 600;
  1529. span {
  1530. height: 60px;
  1531. display: block;
  1532. line-height: 60px;
  1533. margin-right: 20px;
  1534. }
  1535. .is_active {
  1536. color: rgba(111, 182, 184, 1);
  1537. }
  1538. }
  1539. .scrollId {
  1540. overflow: auto;
  1541. height: calc(100% - 61px);
  1542. }
  1543. .middle {
  1544. width: 96%;
  1545. margin: 0 auto;
  1546. color: #000;
  1547. // border-bottom: 1px solid rgb(231, 231, 231);
  1548. .filter {
  1549. display: flex;
  1550. flex-wrap: wrap;
  1551. align-items: center;
  1552. margin: 10px 0 0 0;
  1553. .search {
  1554. color: #fff;
  1555. }
  1556. .condition {
  1557. display: flex;
  1558. align-items: center;
  1559. margin: 10px 20px 10px 0;
  1560. :deep(.el-input .el-input__inner) {
  1561. font-size: 14px;
  1562. }
  1563. .title {
  1564. padding: 0 25px 0 0;
  1565. }
  1566. }
  1567. .grade {
  1568. .el-input {
  1569. :deep(.el-input__wrapper) {
  1570. box-shadow: none;
  1571. }
  1572. }
  1573. .grade_left {
  1574. border-top: 1px solid #dcdfe6;
  1575. border-bottom: 1px solid #dcdfe6;
  1576. border-left: 1px solid #dcdfe6;
  1577. border-top-left-radius: 4px;
  1578. border-bottom-left-radius: 4px;
  1579. }
  1580. .line {
  1581. display: block;
  1582. height: 32px;
  1583. line-height: 32px;
  1584. padding: 0 8px;
  1585. border-top: 1px solid #dcdfe6;
  1586. border-bottom: 1px solid #dcdfe6;
  1587. }
  1588. .grade_right {
  1589. border-top: 1px solid #dcdfe6;
  1590. border-bottom: 1px solid #dcdfe6;
  1591. border-right: 1px solid #dcdfe6;
  1592. border-top-right-radius: 4px;
  1593. border-bottom-right-radius: 4px;
  1594. }
  1595. }
  1596. .search {
  1597. margin-right: 20px;
  1598. }
  1599. }
  1600. .gongneng {
  1601. margin: 10px 0 20px 0;
  1602. span {
  1603. color: #fff;
  1604. }
  1605. .el-button {
  1606. margin-right: 10px;
  1607. }
  1608. }
  1609. :deep(.cont) {
  1610. width: 60%;
  1611. margin: 20px auto;
  1612. }
  1613. :deep(.download) {
  1614. display: flex;
  1615. align-items: center;
  1616. margin: 10px;
  1617. }
  1618. :deep(.download span) {
  1619. font-size: 16px;
  1620. margin-left: 20px;
  1621. }
  1622. :deep(.cont .el-button) {
  1623. margin-left: 60px;
  1624. margin-bottom: 30px;
  1625. }
  1626. :deep(.cont .accomplish) {
  1627. width: 100%;
  1628. display: flex;
  1629. justify-content: center;
  1630. }
  1631. :deep(.cont .accomplish .el-button) {
  1632. width: 50%;
  1633. margin: 0;
  1634. }
  1635. }
  1636. .footer {
  1637. width: 96%;
  1638. height: calc(100% - 270px);
  1639. min-height: 300px;
  1640. margin: 10px auto 30px;
  1641. .el-table--fit {
  1642. height: 100%;
  1643. :deep(.el-table__header-wrapper) {
  1644. background-color: #000;
  1645. font-size: 14px;
  1646. tr {
  1647. // color: #000;
  1648. }
  1649. }
  1650. :deep(.el-table__row) {
  1651. height: 50px;
  1652. font-size: 14px;
  1653. // color: #000;
  1654. &:hover {
  1655. td {
  1656. background-color: rgba(223, 236, 254, 1);
  1657. }
  1658. }
  1659. }
  1660. :deep(.el-table__row td) {
  1661. padding: 0;
  1662. border: 0;
  1663. .normal {
  1664. background-color: rgba(139, 195, 74, 1);
  1665. color: #fff;
  1666. padding: 4px;
  1667. }
  1668. }
  1669. .el-button--primary {
  1670. margin-left: 5px;
  1671. }
  1672. :deep(.el-table__body .even) {
  1673. background-color: #fff;
  1674. }
  1675. :deep(.el-table__body .odd) {
  1676. background-color: rgba(240, 243, 247, 1);
  1677. }
  1678. :deep(.edit) {
  1679. display: flex;
  1680. align-items: center;
  1681. justify-content: center;
  1682. color: rgba(111, 182, 184, 1);
  1683. }
  1684. :deep(.look) {
  1685. padding: 0 10px;
  1686. cursor: pointer;
  1687. color: rgba(30, 125, 251, 1);
  1688. }
  1689. .del {
  1690. padding: 0 10px;
  1691. color: rgba(212, 48, 48, 1);
  1692. cursor: pointer;
  1693. }
  1694. // :deep(.look):hover {
  1695. // color: red;
  1696. // }
  1697. // :deep(.del):hover {
  1698. // color: red;
  1699. // }
  1700. }
  1701. }
  1702. // 编辑按钮
  1703. :deep(.editDialog) {
  1704. // height: 420px;
  1705. border-radius: 11px;
  1706. .el-dialog__header {
  1707. border-radius: 11px 11px 0 0;
  1708. background: rgba(237, 241, 245, 1);
  1709. font-weight: 600;
  1710. margin: 0;
  1711. .el-dialog__headerbtn {
  1712. outline: none;
  1713. }
  1714. }
  1715. .el-dialog__body {
  1716. padding: 30px 30px 10px 30px;
  1717. .el-form-item__content {
  1718. width: 200px;
  1719. .el-input-group__append {
  1720. background-color: rgba(222, 234, 252, 1);
  1721. color: rgba(0, 97, 255, 1);
  1722. cursor: pointer;
  1723. user-select: none;
  1724. }
  1725. }
  1726. .el-form {
  1727. .typeTitle {
  1728. display: block;
  1729. color: red;
  1730. margin: 0 0 6px 100px;
  1731. }
  1732. .account {
  1733. display: flex;
  1734. justify-content: space-between;
  1735. .el-form-item {
  1736. .el-form-item__content {
  1737. width: 300px;
  1738. }
  1739. .el-input {
  1740. width: 300px;
  1741. }
  1742. }
  1743. }
  1744. }
  1745. .options {
  1746. margin: 50px 20px 20px 0;
  1747. width: 100%;
  1748. .el-form-item__content {
  1749. display: flex;
  1750. flex-direction: row-reverse;
  1751. }
  1752. .queding {
  1753. color: #fff;
  1754. margin-left: 15px;
  1755. }
  1756. }
  1757. }
  1758. }
  1759. // 删除成绩
  1760. :deep(.closeAccount) {
  1761. // height: 600px;
  1762. overflow: hidden;
  1763. border-radius: 11px;
  1764. .el-dialog__header {
  1765. border-radius: 11px 11px 0 0;
  1766. background: rgba(245, 249, 255, 1);
  1767. font-weight: 600;
  1768. height: 60px;
  1769. padding: 0 20px;
  1770. line-height: 60px;
  1771. margin: 0;
  1772. border-bottom: 1px solid rgba(230, 230, 230, 1);
  1773. .el-dialog__headerbtn {
  1774. outline: none;
  1775. }
  1776. }
  1777. .el-dialog__body {
  1778. padding: 0px 20px 20px 20px;
  1779. // height: 200px;
  1780. // display: flex;
  1781. // flex-direction: column-reverse;
  1782. .content {
  1783. height: 80px;
  1784. font-size: 16px;
  1785. padding: 20px 30px;
  1786. display: flex;
  1787. img {
  1788. width: 25px;
  1789. height: 25px;
  1790. margin: 0 8px 0 0;
  1791. }
  1792. }
  1793. .option {
  1794. display: flex;
  1795. flex-direction: row-reverse;
  1796. align-items: center;
  1797. margin: 10px 0;
  1798. .queding {
  1799. margin-left: 20px;
  1800. }
  1801. }
  1802. }
  1803. }
  1804. // 导入弹窗样式
  1805. :deep(.importXlsx) {
  1806. // height: 420px;
  1807. border-radius: 11px;
  1808. .el-dialog__header {
  1809. border-radius: 11px 11px 0 0;
  1810. background: rgba(237, 241, 245, 1);
  1811. font-weight: 600;
  1812. margin: 0;
  1813. .el-dialog__headerbtn {
  1814. outline: none;
  1815. }
  1816. }
  1817. .el-dialog__body {
  1818. padding: 20px 20px 10px 20px;
  1819. .btn {
  1820. display: flex;
  1821. .importTemp {
  1822. margin-right: 15px;
  1823. }
  1824. .avatar-uploader {
  1825. flex: 1;
  1826. }
  1827. }
  1828. .options {
  1829. margin: 15px 0;
  1830. .queding {
  1831. margin-left: 20px;
  1832. color: #fff;
  1833. }
  1834. display: flex;
  1835. flex-direction: row-reverse;
  1836. }
  1837. }
  1838. }
  1839. .pageSize {
  1840. display: flex;
  1841. align-items: center;
  1842. justify-content: space-between;
  1843. margin: 0 30px;
  1844. span {
  1845. color: #000;
  1846. }
  1847. .el-pagination {
  1848. // width: 1600px;
  1849. :deep(.el-pagination__total) {
  1850. color: #000;
  1851. }
  1852. :deep(.el-pagination__goto) {
  1853. color: #000;
  1854. }
  1855. :deep(.el-pagination__classifier) {
  1856. color: #000;
  1857. }
  1858. :deep(.el-input__wrapper) {
  1859. border: 1px solid rgba(0, 0, 0, 1);
  1860. border-radius: 5px;
  1861. box-shadow: none;
  1862. }
  1863. :deep(.el-pager li) {
  1864. margin: 0 5px;
  1865. border: 1px solid rgba(0, 0, 0, 1);
  1866. border-radius: 5px;
  1867. background-color: transparent;
  1868. }
  1869. :deep(.el-pager li.is-active) {
  1870. // background-color: rgba(0, 97, 255, 0.8);
  1871. border: 1px solid rgba(0, 97, 255, 1);
  1872. color: rgba(0, 97, 255, 1);
  1873. }
  1874. :deep(.btn-prev) {
  1875. margin-right: 5px;
  1876. border: 1px solid rgba(0, 0, 0, 1);
  1877. border-radius: 5px;
  1878. background-color: transparent;
  1879. }
  1880. :deep(.btn-next) {
  1881. margin-left: 5px;
  1882. border: 1px solid rgba(0, 0, 0, 1);
  1883. border-radius: 5px;
  1884. background-color: transparent;
  1885. }
  1886. }
  1887. }
  1888. }
  1889. .el-input {
  1890. width: 192px;
  1891. }
  1892. </style>
  1893. <style lang="scss">
  1894. //添加成员 联系人下拉框样式
  1895. .gradeSelect {
  1896. // border: 1px solid red;
  1897. .el-select-dropdown__wrap {
  1898. height: 200px;
  1899. // border: 1px solid red;
  1900. }
  1901. }
  1902. .el-popper {
  1903. .addStudentMore {
  1904. text-align: center;
  1905. }
  1906. }
  1907. </style>