index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. <template>
  2. <NavHeader/>
  3. <bread-crumb/>
  4. <div class="w-1200px m-auto">
  5. <div class="flex items-center">
  6. <div class="w-360px">
  7. <el-date-picker
  8. v-model="exam_time"
  9. value-format="YYYY-MM-DD"
  10. type="daterange"
  11. range-separator="至"
  12. start-placeholder="开始时间"
  13. end-placeholder="结束时间"
  14. @change="handleDateChange"
  15. size="large"
  16. />
  17. </div>
  18. <el-select class="ml-10px" v-model="exam_type" placeholder="考试类型" size="large" @change="filterData">
  19. <el-option label="全部" value="0"
  20. />
  21. <el-option
  22. v-for="item in type_list"
  23. :key="item.value"
  24. :label="item.label"
  25. :value="item.value"
  26. />
  27. </el-select>
  28. <el-input
  29. v-model="keyword"
  30. class="ml-20px"
  31. style="width: 200px;"
  32. size="large"
  33. clearable
  34. @keyup.enter="filterData"
  35. @clear="filterData"
  36. placeholder="请输入关键字"
  37. />
  38. <el-button color="#003eee" class="ml-20px" type="primary" size="large" @click="filterData">搜索</el-button>
  39. </div>
  40. <div class="flex mt-20px justify-between">
  41. <button type="button" class="add-btn" @click="linkTo({name:'process-create'})">
  42. <el-icon class="inline-block align-middle">
  43. <Plus/>
  44. </el-icon>
  45. <span class="ml-5px inline-block align-middle">新建考试计划</span>
  46. </button>
  47. </div>
  48. <div class="mt-20px" v-if="listData.length > 0">
  49. <div class="process-list-table">
  50. <div class="head">
  51. <div class="w-340px text-left pl-20px">考试计划名称</div>
  52. <div class="w-250px">状态</div>
  53. <div class="w-130px">考试类型</div>
  54. <div class="w-220px">考试时间</div>
  55. <div class="w-300px">操作</div>
  56. </div>
  57. <div>
  58. <div v-for="(item,index) in listData" class="line">
  59. <div class="up">
  60. <div class="w-340px pl-20px text-left">{{item.ykj_ksrwmc}}</div>
  61. <div class="w-250px">
  62. <span class="inline-block align-middle">进行中</span>
  63. <div class="inline-block align-middle ml-10px process-state">
  64. <h3 class="state-line">
  65. <span style="width: 11%;"></span>
  66. </h3>
  67. </div>
  68. <span class="ml-10px inline-block align-middle">11%</span>
  69. </div>
  70. <div class="w-130px text-left">
  71. <span v-if="item.ykj_kslx === '1'">周考</span>
  72. <span v-if="item.ykj_kslx === '2'">月考</span>
  73. <span v-if="item.ykj_kslx === '3'">作业</span>
  74. <span v-if="item.ykj_kslx === '4'">测验</span>
  75. <span v-if="item.ykj_kslx === '5'">期中</span>
  76. <span v-if="item.ykj_kslx === '6'">期末</span>
  77. <span v-if="item.ykj_kslx === '7'">联考</span>
  78. </div>
  79. <div class="w-220px text-left">{{item.ykj_ksrq}}~{{item.ykj_jsrq}}</div>
  80. <div class="w-300px">
  81. <button type="button" class="op-btn">编辑</button>
  82. <button type="button" class="op-btn ml-10px" @click="linkTo({name:'process-detail-id',params:{id:item.ykj_id}})">详情</button>
  83. <div class="ml-10px relative op-btn cursor-pointer">
  84. <span class="inline-block align-middle leading-28px">更多</span>
  85. <div class="more-list">
  86. <ul>
  87. <li>扫描批阅进度</li>
  88. <li>考试分析</li>
  89. <li>删除</li>
  90. </ul>
  91. </div>
  92. </div>
  93. <button type="button" class="ml-10px inline-block align-middle arrow-btn" :class="item.showSub?'up':'down'" @click="toggleDown(index)"></button>
  94. </div>
  95. </div>
  96. <div class="down pt-15px pl-35px" v-if="item.showSub">
  97. <ul class="subject-list">
  98. <li v-for="items in item.lc">
  99. <span class="sub-del cursor-pointer" @click="del_sub(item.ykj_id,items.ykl_id)"></span>
  100. <div>
  101. <div class="subject-name m-auto">{{JSON.parse(items.ykl_lc).ze_xueke_name}}</div>
  102. <div class="mt-5px">
  103. <div class="inline-block align-middle process-state">
  104. <h3 class="state-line">
  105. <span style="width: 11%;"></span>
  106. </h3>
  107. </div>
  108. <span class="ml-10px text-14px inline-block align-middle">11%</span>
  109. </div>
  110. <div class="mt-5px text-center">
  111. <button type="button" class="op-btn">批阅任务</button>
  112. <button type="button" class="ml-10px op-btn">查看</button>
  113. </div>
  114. </div>
  115. </li>
  116. <li class="cursor-pointer" @click="addSubject(item,index)">
  117. <div class="subject-add-btn"></div>
  118. </li>
  119. </ul>
  120. </div>
  121. </div>
  122. </div>
  123. </div>
  124. <div class="mt-20px page-new flex justify-end">
  125. <el-pagination v-model:current-page="cur_page" v-model:page-size="limit" layout="total,prev, pager, next" :total="total" :background="true" @current-change="handleSelectionChange"></el-pagination>
  126. </div>
  127. </div>
  128. <div v-else class="no-data">
  129. <div>
  130. <h3 class="no-data-img"></h3>
  131. <h4 class="mt-25px text-18px text-hex-0048e5 text-center">暂无数据</h4>
  132. </div>
  133. </div>
  134. </div>
  135. <el-dialog
  136. v-model="dialogVisible"
  137. title="增加考试学科"
  138. width="500px"
  139. center
  140. append-to-body
  141. >
  142. <div>
  143. <el-form label-width="120px" size="large">
  144. <el-form-item label="请选择学科">
  145. <el-select v-model="add_sub" placeholder="请选择学科">
  146. <el-option v-for="item in sub_filter_list" :label="item.subject_name" :value="{value:item.subject_id,label:item.subject_name}" />
  147. </el-select>
  148. </el-form-item>
  149. </el-form>
  150. </div>
  151. <template #footer>
  152. <span class="dialog-footer text-right">
  153. <el-button @click="dialogVisible = false" size="large">取消</el-button>
  154. <el-button size="large" color="#003eee" :disabled="add_sub.value === '' || isSubmit" type="primary" @click="addSubmit">
  155. 确定
  156. </el-button>
  157. </span>
  158. </template>
  159. </el-dialog>
  160. <commonFooter/>
  161. </template>
  162. <route lang="json">
  163. {
  164. "meta":{
  165. "title":"阅卷流程",
  166. "breadcrumb": true
  167. }
  168. }
  169. </route>
  170. <script setup>
  171. import {project_list,subject,add_subject} from "~/pages/process/api";
  172. import { useRouter } from "vue-router";
  173. import {user} from "~/store";
  174. import request from "@/utils/request";
  175. const router = useRouter();
  176. console.log(router,87)
  177. const linkTo = (obj) => {
  178. router.push(obj);
  179. };
  180. let exam_time = $ref([])
  181. let exam_type = $ref('')
  182. let keyword = $ref('')
  183. let type_list = [{
  184. value: '1',
  185. label: '周考'
  186. }, {
  187. value: '2',
  188. label: '月考'
  189. }, {
  190. value: '3',
  191. label: '作业'
  192. },{
  193. value: '4',
  194. label: '测验'
  195. }, {
  196. value: '5',
  197. label: '期中'
  198. }, {
  199. value: '6',
  200. label: '期末'
  201. },{
  202. value: '7',
  203. label: '联考'
  204. }]
  205. let subject_list = $ref([])
  206. let noData = $ref(null)
  207. let limit = $ref(10)
  208. let total = $ref(0)
  209. let cur_page = $ref(1)
  210. let listData = $ref([])
  211. let dialogVisible = $ref(false)
  212. let sub_filter_list = $ref([])
  213. let allSub = $ref([])
  214. let add_sub = $ref({
  215. value:'',
  216. label:''
  217. })
  218. let isSubmit = $ref(false)
  219. let add_ykj_id = $ref('')
  220. function getSubject() {
  221. let data = {
  222. for_mistake:'1'
  223. }
  224. if(user.user_role_id < 72) {
  225. data.sm_id = user.sm_info.sm_id
  226. }
  227. subject(data).then(res =>{
  228. if(res.code === '1') {
  229. allSub = res.data;
  230. }
  231. })
  232. }
  233. getSubject();
  234. function getListData() {
  235. let data = {
  236. page:cur_page,
  237. limit:limit,
  238. keyword:keyword,
  239. ykj_ksrq:exam_time[0],
  240. ykj_jsrq:exam_time[1],
  241. ykj_kslx:exam_type
  242. };
  243. project_list(data).then(res=>{
  244. if(res.code === '1') {
  245. listData = res.data.page_data;
  246. for(let i in listData) {
  247. if(i == 0) {
  248. listData[i].showSub = true;
  249. } else {
  250. listData[i].showSub = false;
  251. }
  252. }
  253. // console.log(listData,87)
  254. total = Number(res.data.total_rows);
  255. cur_page = Number(res.data.page_now);
  256. }
  257. })
  258. }
  259. getListData();
  260. function filterData() {
  261. cur_page = 1;
  262. getListData();
  263. }
  264. const handleSelectionChange = (val) => {
  265. cur_page = val;
  266. getListData();
  267. };
  268. const handleDateChange = (val) => {
  269. if (val) {
  270. exam_time = [val[0],val[1]];
  271. } else {
  272. exam_time = [];
  273. }
  274. cur_page = 1;
  275. getListData();
  276. }
  277. function addSubject(item) {
  278. let filter_list = item.ykj_kskm.split(',');
  279. add_ykj_id = item.ykj_id;
  280. dialogVisible = true;
  281. add_sub = {
  282. label:'',
  283. value:''
  284. }
  285. for(let i in allSub) {
  286. if(allSub[i].grade == item.ykj_ksnj) {
  287. subject_list = allSub[i].subjects;
  288. sub_filter_list = subject_list.filter(item=>!filter_list.some(ele=>ele === item.subject_id))
  289. }
  290. }
  291. }
  292. function addSubmit() {
  293. isSubmit = true;
  294. let data = {
  295. ykj_id:add_ykj_id,
  296. ykj_kskm:add_sub.value,
  297. ykj_kskm_name:add_sub.label
  298. }
  299. add_subject(data).then(res =>{
  300. isSubmit = false;
  301. if(res.code === '1') {
  302. ElMessage.success("科目添加成功!");
  303. dialogVisible = false;
  304. getListData();
  305. }
  306. })
  307. }
  308. function del_sub(ykj_id,ykl_id) {
  309. ElMessageBox.confirm("确认删除该学科的考试?", "", {
  310. confirmButtonText: "确认",
  311. cancelButtonText: "取消",
  312. type: "warning",
  313. }).then(() => {
  314. request({
  315. url: "/yzy/ksjh/liankao_del_subject",
  316. data: {
  317. ykj_id: ykj_id,
  318. ykl_id: ykl_id
  319. },
  320. }).then((res) => {
  321. if (res.code === "1") {
  322. ElMessage({
  323. type: "success",
  324. message: "删除成功",
  325. });
  326. getListData();
  327. }
  328. });
  329. })
  330. }
  331. function toggleDown(index) {
  332. if(listData[index].showSub) {
  333. listData[index].showSub = false;
  334. } else {
  335. listData[index].showSub = true;
  336. }
  337. }
  338. </script>
  339. <style lang="scss" scoped>
  340. $color: #0048e5;
  341. ::v-deep .el-pagination.is-background .btn-next.is-active,
  342. ::v-deep .el-pagination.is-background .btn-prev.is-active,
  343. ::v-deep .el-pagination.is-background .el-pager li.is-active{
  344. background-color: $color;
  345. }
  346. .add-btn {
  347. width: 129px;
  348. height: 36px;
  349. background: #ffffff;
  350. border: 1px solid $color;
  351. border-radius: 4px;
  352. font-size: 14px;
  353. color: $color;
  354. text-align: center;
  355. }
  356. .del-btn {
  357. width: 92px;
  358. height: 36px;
  359. background: #ff0000;
  360. border-radius: 4px;
  361. font-size: 14px;
  362. color: #fff;
  363. text-align: center;
  364. &:disabled{
  365. opacity: .45;
  366. cursor: default;
  367. }
  368. }
  369. .process-list-table {
  370. width: 100%;
  371. min-height: 600px;
  372. .head {
  373. height: 50px;
  374. display: flex;
  375. background: $color;
  376. border-radius: 6px 6px 0 0;
  377. font-size: 16px;
  378. line-height: 50px;
  379. color: #fff;
  380. }
  381. .line {
  382. width: 100%;
  383. &:nth-child(odd) {
  384. >.up {
  385. border-radius: 4px;
  386. background: rgba(112, 175, 253, 0.1);
  387. }
  388. }
  389. >.up {
  390. display: flex;
  391. align-items: center;
  392. padding: 15px 0;
  393. font-size: 15px;
  394. color: #404040;
  395. }
  396. }
  397. }
  398. .set-check {
  399. position: relative;
  400. z-index: 40;
  401. width: 20px;
  402. height: 20px;
  403. margin: 15px auto 0;
  404. label {
  405. position: absolute;
  406. left: 0;
  407. width: 20px;
  408. height: 20px;
  409. cursor: pointer;
  410. border-radius: 3px;
  411. }
  412. input[type=checkbox] {
  413. width: 20px;
  414. height: 20px;
  415. opacity: 0;
  416. &:checked + label:after {
  417. }
  418. }
  419. &.all {
  420. label {
  421. border: 1px solid #fff;
  422. }
  423. input[type=checkbox] {
  424. &:checked + label {
  425. border-color: #fff;
  426. }
  427. &:checked + label:after {
  428. content: '';
  429. width: 14px;
  430. height: 8px;
  431. position: absolute;
  432. top: 3px;
  433. left: 2px;
  434. border: 2px solid #fff;
  435. border-top: none;
  436. border-right: none;
  437. -moz-transform: rotate(-45deg);
  438. -ms-transform: rotate(-45deg);
  439. -webkit-transform: rotate(-45deg);
  440. transform: rotate(-45deg);
  441. }
  442. }
  443. }
  444. &.single {
  445. margin: 0 auto;
  446. label {
  447. border: 1px solid #aaa;
  448. }
  449. input[type=checkbox] {
  450. &:checked + label {
  451. border-color: #003eee;
  452. }
  453. &:checked + label:after {
  454. content: '';
  455. width: 14px;
  456. height: 8px;
  457. position: absolute;
  458. top: 3px;
  459. left: 2px;
  460. border: 2px solid #003eee;
  461. border-top: none;
  462. border-right: none;
  463. -moz-transform: rotate(-45deg);
  464. -ms-transform: rotate(-45deg);
  465. -webkit-transform: rotate(-45deg);
  466. transform: rotate(-45deg);
  467. }
  468. }
  469. }
  470. }
  471. .process-state {
  472. width: 140px;
  473. .state-line {
  474. width: 100%;
  475. height: 5px;
  476. background: #e2e2e2;
  477. border-radius: 3px;
  478. span {
  479. display: block;
  480. height: 5px;
  481. background: #003eee;
  482. border-radius: 3px;
  483. }
  484. }
  485. .state-info {
  486. position: absolute;
  487. top: 8px;
  488. left: 0;
  489. width: 100%;
  490. font-size: 13px;
  491. color: #003eee;
  492. text-align: center;
  493. }
  494. }
  495. .op-btn {
  496. display: inline-block;
  497. vertical-align: middle;
  498. padding: 0 15px;
  499. height: 30px;
  500. background: #fff;
  501. border: 1px solid #003eee;
  502. border-radius: 4px;
  503. font-size: 14px;
  504. color: #003eee;
  505. text-align: center;
  506. &:disabled {
  507. background: #ccc;
  508. border-color: #ccc;
  509. color: #fff;
  510. cursor: default;
  511. }
  512. .more-list {
  513. display: none;
  514. position: absolute;
  515. left: 50%;
  516. top: 30px;
  517. margin-left: -50px;
  518. z-index: 50;
  519. width: 100px;
  520. padding-top: 5px;
  521. ul {
  522. width: 100%;
  523. background: #fff;
  524. box-shadow: 0 0 5px rgba(0, 0, 0, .3);
  525. li {
  526. width: 100%;
  527. height: 30px;
  528. font-size: 14px;
  529. color: #003eee;
  530. text-align: center;
  531. line-height: 30px;
  532. cursor: pointer;
  533. &.disabled {
  534. background: #fff !important;
  535. color: #ccc !important;
  536. cursor: default !important;
  537. pointer-events: none;
  538. }
  539. &:hover {
  540. background: #F0F7FF;
  541. }
  542. }
  543. }
  544. }
  545. &:hover {
  546. .more-list {
  547. display: block;
  548. }
  549. }
  550. }
  551. .arrow-btn{
  552. width: 21px;
  553. height: 13px;
  554. &.up{
  555. background: url("/images/arrow-up.png") center no-repeat;
  556. }
  557. &.down{
  558. background: url("/images/arrow-down.png") center no-repeat;
  559. }
  560. }
  561. .subject-list{
  562. display: flex;
  563. flex-wrap: wrap;
  564. li{
  565. position: relative;
  566. width: 205px;
  567. height: 280px;
  568. margin: 0 28px 23px 0;
  569. border: 2px solid $color;
  570. border-radius: 10px;
  571. display: flex;
  572. justify-content: center;
  573. align-items: center;
  574. }
  575. .sub-del{
  576. position: absolute;
  577. right: 3px;
  578. top: 3px;
  579. z-index: 50;
  580. width: 20px;
  581. height: 20px;
  582. background: url("/images/icon-close.png") center no-repeat;
  583. background-size: 20px 20px;
  584. }
  585. }
  586. .subject-add-btn{
  587. width: 57px;
  588. height: 57px;
  589. background: url("/images/icon-add.png") center no-repeat;
  590. }
  591. .no-data {
  592. width: 100%;
  593. height: 450px;
  594. display: flex;
  595. justify-content: center;
  596. align-items: center;
  597. .no-data-img {
  598. width: 233px;
  599. height: 199px;
  600. background: url("/images/no-data.png") center no-repeat;
  601. }
  602. }
  603. .subject-name{
  604. width: 138px;
  605. height: 195px;
  606. background: url("/images/subject-bg.png") center no-repeat;
  607. background-size: 138px 195px;
  608. padding: 20px 10px 0 10px;
  609. font-size: 22px;
  610. font-weight: bold;
  611. color: #fff;
  612. text-align: center;
  613. }
  614. </style>