serverIndexList.vue 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. <!-- -->
  2. <template>
  3. <div class="m-container">
  4. <h2>
  5. <div class="titleWrap">
  6. <div class="squrt"></div>
  7. 服务指标
  8. </div>
  9. <el-button
  10. type="text"
  11. icon="el-icon-question"
  12. @click="lookServerDetail"
  13. style="color: red"
  14. >服务指标规则</el-button
  15. >
  16. </h2>
  17. <div class="m-core">
  18. <save-form
  19. ref='searchForm'
  20. :inline="true"
  21. :model="searchForm"
  22. @submit="search"
  23. @reset="onReSet"
  24. >
  25. <el-form-item>
  26. <remote-search
  27. :commit="'setTeachers'"
  28. v-model="searchForm.teacherId"
  29. />
  30. </el-form-item>
  31. <el-form-item>
  32. <el-input
  33. v-model.trim="searchForm.search"
  34. @keyup.enter.native="search"
  35. clearable
  36. placeholder="学生姓名"
  37. ></el-input>
  38. </el-form-item>
  39. <el-form-item label="周次选择">
  40. <el-date-picker
  41. v-model.trim="searchForm.timer"
  42. style="width: 400px"
  43. type="daterange"
  44. :picker-options="{
  45. firstDayOfWeek: 1,
  46. }"
  47. value-format="yyyy-MM-dd"
  48. range-separator="至"
  49. start-placeholder="周次开始日期"
  50. end-placeholder="周次结束日期"
  51. @change="getWeekTime"
  52. ></el-date-picker>
  53. </el-form-item>
  54. <el-form-item>
  55. <el-button
  56. :type="isSearch ? 'primary' : 'info'"
  57. icon="el-icon-circle-plus-outline"
  58. @click="showMove = true"
  59. >更多选项</el-button
  60. >
  61. <el-button type="danger" native-type="submit">搜索</el-button>
  62. <el-button native-type="reset" type="primary">重置</el-button>
  63. <el-button
  64. @click="onExport"
  65. type="primary"
  66. v-permission="'export/exercisesSituations'"
  67. style="background: #14928a; border: 1px solid #14928a"
  68. >导出</el-button
  69. >
  70. </el-form-item>
  71. </save-form>
  72. <div class="tableWrap">
  73. <el-table
  74. style="width: 100%"
  75. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  76. :data="tableList"
  77. >
  78. <el-table-column align="center" prop="studentId" label="学员编号">
  79. <template slot-scope="scope">
  80. <div>
  81. <copy-text>{{ scope.row.studentId }}</copy-text>
  82. </div>
  83. </template>
  84. </el-table-column>
  85. <el-table-column align="center" prop="studentName" label="学生姓名">
  86. <template slot-scope="scope">
  87. <div>
  88. <copy-text>{{ scope.row.studentName }}</copy-text>
  89. </div>
  90. </template>
  91. </el-table-column>
  92. <el-table-column align="center" prop="organName" label="所属分部">
  93. <template slot-scope="scope">
  94. <div>
  95. <copy-text>{{ scope.row.organName }}</copy-text>
  96. </div>
  97. </template>
  98. </el-table-column>
  99. <el-table-column align="center" prop="groupNames" label="乐团名称">
  100. <template slot-scope="scope">
  101. <overflow-text
  102. width="100%"
  103. :text="scope.row.groupNames"
  104. ></overflow-text>
  105. </template>
  106. </el-table-column>
  107. <el-table-column align="center" prop="teacherName" label="指导老师">
  108. <template slot-scope="scope">
  109. <div>
  110. <copy-text>{{ scope.row.teacherName }}</copy-text>
  111. </div>
  112. </template>
  113. </el-table-column>
  114. <el-table-column
  115. align="center"
  116. prop="educationalTeacherName"
  117. label="乐团主管"
  118. ></el-table-column>
  119. <el-table-column
  120. align="center"
  121. prop="courseIds"
  122. width="100"
  123. label="服务课程"
  124. >
  125. <template slot-scope="scope">
  126. <copy-text>{{ scope.row.courseIds || "课外训练" }}</copy-text>
  127. </template>
  128. </el-table-column>
  129. <el-table-column align="center" label="预期安排">
  130. <template slot-scope="scope">
  131. <div>{{ scope.row.expectExercisesNum + "次" }}</div>
  132. </template>
  133. </el-table-column>
  134. <el-table-column align="center" width="120" prop>
  135. <template slot="header" slot-scope="scope">
  136. <p style="position: relative">
  137. 实际安排
  138. <el-tooltip placement="top" popper-class="mTooltip">
  139. <div slot="content">
  140. 以周为单位,每周服务指标指定的课程布置作业记一次实际安排
  141. </div>
  142. <!-- <img :src="imageIcon"
  143. class="micon el-tooltip"
  144. style="width:8px height:8px"
  145. alt /> -->
  146. <i
  147. class="el-icon-question"
  148. style="font-size: 18px; color: #f56c6c"
  149. ></i>
  150. </el-tooltip>
  151. </p>
  152. </template>
  153. <template slot-scope="scope">
  154. <div>{{ scope.row.actualExercisesNum + "次" }}</div>
  155. </template>
  156. </el-table-column>
  157. <el-table-column align="center" prop label="提交次数">
  158. <template slot-scope="scope">
  159. <div>{{ scope.row.exercisesReplyNum + "次" }}</div>
  160. </template>
  161. </el-table-column>
  162. <el-table-column align="center" prop label="评价次数">
  163. <template slot-scope="scope">
  164. <div>{{ scope.row.exercisesMessageNum + "次" }}</div>
  165. </template>
  166. </el-table-column>
  167. <el-table-column align="center" prop label="及时评价次数">
  168. <template slot-scope="scope">
  169. <div>{{ scope.row.exercisesMessageTimelyNum + "次" }}</div>
  170. </template>
  171. </el-table-column>
  172. <el-table-column align="center" label="VIP课">
  173. <template slot-scope="scope">
  174. <div>{{ scope.row.existVipCourse + "节" }}</div>
  175. </template>
  176. </el-table-column>
  177. <el-table-column align="center" label="付费网管课">
  178. <template slot-scope="scope">
  179. <div>{{ scope.row.existPracticeCourse + "节" }}</div>
  180. </template>
  181. </el-table-column>
  182. <el-table-column align="center" label="作业提交时间">
  183. <template slot-scope="scope">
  184. <div>{{ scope.row.lastSubmitTime }}</div>
  185. </template>
  186. </el-table-column>
  187. <el-table-column align="center" width="120" label="服务周期">
  188. <template slot-scope="scope">
  189. <div>{{ dayjs(scope.row.monday).format("YYYY-MM-DD") }}</div>
  190. <div>{{ dayjs(scope.row.sunday).format("YYYY-MM-DD") }}</div>
  191. </template>
  192. </el-table-column>
  193. <el-table-column align="center" label="操作">
  194. <!-- -->
  195. <template slot-scope="scope">
  196. <div v-if="scope.row.actualExercisesNum > 0">
  197. <el-button type="text" @click="lookDetail(scope.row)"
  198. >查看</el-button
  199. >
  200. </div>
  201. </template>
  202. </el-table-column>
  203. </el-table>
  204. <pagination
  205. sync
  206. :total.sync="rules.total"
  207. :page.sync="rules.page"
  208. :limit.sync="rules.limit"
  209. :page-sizes="rules.page_size"
  210. @pagination="getList"
  211. />
  212. </div>
  213. </div>
  214. <el-dialog title="服务指标规则说明" :visible.sync="lookServer">
  215. <div class="serverInfo">
  216. <p>作业布置&服务指标优先级:<span>声部课>VIP课>合奏课>网管课</span></p>
  217. <p>
  218. <span>周一凌晨</span> 系统根据学员的排课情况生成布置作业路径及服务指标
  219. </p>
  220. <p>
  221. <span>多次课程</span>
  222. 只布置一次作业、统计一次服务指标(多乐团、多组VIP网管课除外)
  223. </p>
  224. <el-table
  225. border
  226. style="margin-top: 30px"
  227. :data="infoList"
  228. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  229. :span-method="arraySpanMethod"
  230. >
  231. <el-table-column
  232. align="center"
  233. prop="row1"
  234. label="总体课程情况"
  235. ></el-table-column>
  236. <el-table-column
  237. align="center"
  238. prop="row2"
  239. label="本周课程情况"
  240. ></el-table-column>
  241. <el-table-column
  242. align="center"
  243. prop="row3"
  244. label="作业布置路径"
  245. ></el-table-column>
  246. <el-table-column
  247. align="center"
  248. prop="row4"
  249. label="服务指标统计"
  250. ></el-table-column>
  251. </el-table>
  252. <div class="infoWrap">
  253. <h4>其他情况:</h4>
  254. <p>
  255. 1.学员在 <span>多个乐团时</span> ,剩余课程中
  256. <span>本周有声部课</span> 的乐团布置作业,
  257. <span>都有</span> 则都布置,
  258. <span>都没有</span> 则根据表格中的逻辑布置
  259. </p>
  260. <p>
  261. 2.学员存在 <span>多组VIP课</span> 时,若课程组
  262. <span>老师相同</span> ,则仅布置一次作业(网管课同理)
  263. </p>
  264. <p>
  265. 3.学员存在 <span>多组VIP课</span> 时,若课程组
  266. <span>老师不同,本周有课</span>
  267. 的VIP课程组布置作业,多个课程组本周都有课则布置多次(网管课同理)
  268. </p>
  269. <p>
  270. 4.学员存在 <span>多组VIP课</span> 时,若课程组
  271. <span>老师不同,本周都没有课</span> ,则所有VIP老师
  272. <span>都布置</span> 课外训练, <span>都统计</span> 服务指标
  273. </p>
  274. </div>
  275. <div class="infoWrap">
  276. <h4>课程调整:</h4>
  277. <p>
  278. 本周 <span>课程调整时</span> ,重新根据该学员的
  279. <span>本周课程情况更新</span> 作业布置路径及服务指标
  280. 则根据表格中的逻辑布置
  281. </p>
  282. </div>
  283. <div class="infoWrap">
  284. <h4>服务指标:</h4>
  285. <p>服务指标按 <span>周为单位</span> 统计</p>
  286. <p>
  287. <span>周六周日</span> 的服务指标
  288. <span>延迟到下周二更新</span>
  289. 实际安排数据(即周日的作业课程,在周二23:59:59时前布置作业都算一次实际安排)
  290. </p>
  291. </div>
  292. <div class="infoWrap">
  293. <h4>服务指标开启/关闭:</h4>
  294. <p>学员新增课程时,自动开启服务指标,</p>
  295. <p>手动关闭服务指标的学员新增课程时,不会自动开启服务指标</p>
  296. <p>
  297. 学员退团、乐团关闭、VIP课程组结束、网管课课程组结束时,若学员不在任何【进行中】乐团【在读】,且无任何未开始课程(乐团课、VIP课、网管课),则关闭服务指标
  298. </p>
  299. </div>
  300. <div class="infoWrap">
  301. <h4>服务指标解释:</h4>
  302. <p><span>若本周学员有多次服务指标则生成多条数据</span></p>
  303. <p>
  304. 预期安排:本周内服务指标次数(即本周应该给该学员布置的作业次数)
  305. </p>
  306. <p>实际安排:本周通过服务指标作业布置路径给该学员布置作业的次数</p>
  307. <p>提交次数:本周学员按照作业布置路径提交作业的次数</p>
  308. <p>评价次数:本周老师评价通过作业布置路径提交的作业的次数</p>
  309. <p>及时评价次数:学员提交作业后24小时内进行评价的次数</p>
  310. <p>VIP课:本周VIP课程课时数</p>
  311. <p>付费网管课:本周付费网管课课时数</p>
  312. <p>作业提交时间:学员提交作业的时间</p>
  313. <p>服务周期:本服务周期时间段</p>
  314. </div>
  315. </div>
  316. </el-dialog>
  317. <el-dialog
  318. title="更多选项"
  319. :visible.sync="showMove"
  320. v-if="showMove"
  321. width="700px"
  322. >
  323. <el-form
  324. :inline="true"
  325. class="searchForm"
  326. @submit="search"
  327. @reset="onReSet"
  328. ref="searchForm2"
  329. :model.sync="searchForm"
  330. label-width="120px"
  331. >
  332. <el-form-item prop="organId" label="分部">
  333. <el-select
  334. class="multiple"
  335. v-model.trim="searchForm.organIdList"
  336. filterable
  337. clearable
  338. placeholder="请选择分部"
  339. >
  340. <el-option
  341. v-for="(item, index) in selects.branchs"
  342. :key="index"
  343. :label="item.name"
  344. :value="item.id"
  345. ></el-option>
  346. </el-select>
  347. </el-form-item>
  348. <el-form-item label="实际安排">
  349. <el-select
  350. placeholder="实际安排"
  351. v-model="searchForm.actualExercisesNumIsAchieve"
  352. clearable
  353. >
  354. <el-option label="符合预期" value="1"></el-option>
  355. <el-option label="不符合预期" value="0"></el-option>
  356. </el-select>
  357. </el-form-item>
  358. <el-form-item label="提交次数">
  359. <el-select
  360. placeholder="提交次数"
  361. v-model="searchForm.exercisesReplyNumIsAchieve"
  362. clearable
  363. >
  364. <el-option label="符合预期" value="1"></el-option>
  365. <el-option label="不符合预期" value="0"></el-option>
  366. </el-select>
  367. </el-form-item>
  368. <el-form-item label="评价次数">
  369. <el-select
  370. placeholder="评价次数"
  371. v-model="searchForm.exercisesMessageNumIsAchieve"
  372. clearable
  373. >
  374. <el-option label="符合预期" value="1"></el-option>
  375. <el-option label="不符合预期" value="0"></el-option>
  376. </el-select>
  377. </el-form-item>
  378. <el-form-item label="及时评价">
  379. <el-select
  380. placeholder="及时评价"
  381. v-model="searchForm.exercisesMessageTimelyNumIsAchieve"
  382. clearable
  383. >
  384. <el-option label="符合预期" value="1"></el-option>
  385. <el-option label="不符合预期" value="0"></el-option>
  386. </el-select>
  387. </el-form-item>
  388. <el-form-item label="是否有VIP课">
  389. <el-select
  390. placeholder="是否有VIP课"
  391. v-model="searchForm.existVipCourse"
  392. clearable
  393. >
  394. <el-option label="是" value="1"></el-option>
  395. <el-option label="否" value="0"></el-option>
  396. </el-select>
  397. </el-form-item>
  398. <el-form-item label="有付费网管课">
  399. <el-select
  400. placeholder="是否有付费网管课"
  401. v-model="searchForm.existPracticeCourse"
  402. clearable
  403. >
  404. <el-option label="是" value="1"></el-option>
  405. <el-option label="否" value="0"></el-option>
  406. </el-select>
  407. </el-form-item>
  408. <el-form-item label="作业提交时间">
  409. <el-date-picker
  410. v-model.trim="searchForm.workTimer"
  411. style="width: 400px"
  412. type="daterange"
  413. :picker-options="{
  414. firstDayOfWeek: 1,
  415. }"
  416. value-format="yyyy-MM-dd"
  417. range-separator="至"
  418. start-placeholder="提交开始日期"
  419. end-placeholder="提交结束日期"
  420. ></el-date-picker>
  421. </el-form-item>
  422. </el-form>
  423. <span slot="footer" class="dialog-footer">
  424. <el-button @click="cancleMore">取 消</el-button>
  425. <el-button type="primary" @click="okMore">确 定</el-button>
  426. </span>
  427. </el-dialog>
  428. </div>
  429. </template>
  430. <script>
  431. import axios from "axios";
  432. import { getToken } from "@/utils/auth";
  433. import pagination from "@/components/Pagination/index";
  434. import load from "@/utils/loading";
  435. import dayjs from "dayjs";
  436. import { getEmployeeOrgan, getTeacher } from "@/api/buildTeam";
  437. import { infoList } from "./modals/infoList";
  438. import { findStudentExtracurricularExercisesSituations } from "@/api/afterSchool";
  439. // findStudentExtracurricularExercisesSituations
  440. let nowTime = new Date();
  441. nowTime =
  442. nowTime.getFullYear() +
  443. "-" +
  444. (nowTime.getMonth() + 1) +
  445. "-" +
  446. nowTime.getDate();
  447. export default {
  448. components: { pagination },
  449. data() {
  450. return {
  451. tableList: [],
  452. searchForm: {
  453. timer: [],
  454. search: null,
  455. organIdList: null,
  456. actualExercisesNumIsAchieve: null, // 训练次数
  457. exercisesMessageNumIsAchieve: null, //评价
  458. exercisesMessageTimelyNumIsAchieve: null, //及时评价
  459. exercisesReplyNumIsAchieve: null, // 提交次数
  460. teacherId: null,
  461. existVipCourse: null,
  462. existPracticeCourse: null,
  463. workTimer: [],
  464. },
  465. organList: [],
  466. teacherList: [],
  467. rules: {
  468. // 分页规则
  469. limit: 10, // 限制显示条数
  470. page: 1, // 当前页
  471. total: 0, // 总条数
  472. page_size: [10, 20, 40, 50], // 选择限制显示条数
  473. },
  474. lookServer: false,
  475. infoList: infoList,
  476. showMove: false,
  477. // imageIcon: require("@/assets/images/base/warning.png"),
  478. };
  479. },
  480. //生命周期 - 创建完成(可以访问当前this实例)
  481. created() {
  482. // 设置默认为当前周
  483. this.searchForm.timer = [];
  484. this.searchForm.timer.push(this.getNowDateAndMonday(nowTime));
  485. this.searchForm.timer.push(this.getNowDateAndSunday(nowTime));
  486. },
  487. //生命周期 - 挂载完成(可以访问DOM元素)
  488. mounted() {
  489. this.$store.dispatch("setBranchs");
  490. // getTeacher().then((res) => {
  491. // if (res.code == 200) {
  492. // this.teacherList = res.data;
  493. // }
  494. // });
  495. // getEmployeeOrgan().then((res) => {
  496. // if (res.code == 200) {
  497. // this.organList = res.data;
  498. // }
  499. // });
  500. // 获取分部 老师
  501. this.init();
  502. },
  503. activated() {
  504. this.init();
  505. },
  506. methods: {
  507. dayjs,
  508. init() {
  509. if (this.$route.query.teacherId) {
  510. this.searchForm.teacherId = this.$route.query.teacherId * 1;
  511. }
  512. if (this.$route.query.search) {
  513. this.$route.query.search instanceof Object
  514. ? (this.topForm = this.$route.query.search)
  515. : (this.topForm = JSON.parse(this.$route.query.search));
  516. }
  517. if (this.$route.query.rules) {
  518. this.$route.query.rules instanceof Object
  519. ? (this.rules = this.$route.query.rules)
  520. : (this.rules = JSON.parse(this.$route.query.rules));
  521. }
  522. this.getList();
  523. },
  524. getDate() {
  525. let obj = {
  526. search: this.searchForm.search || null,
  527. actualExercisesNumIsAchieve:
  528. this.searchForm.actualExercisesNumIsAchieve || null, // 训练次数
  529. exercisesMessageNumIsAchieve:
  530. this.searchForm.exercisesMessageNumIsAchieve || null, //评价
  531. exercisesMessageTimelyNumIsAchieve:
  532. this.searchForm.exercisesMessageTimelyNumIsAchieve || null, //及时评价
  533. exercisesReplyNumIsAchieve:
  534. this.searchForm.exercisesReplyNumIsAchieve || null, // 提交次数
  535. organIdList: this.searchForm.organIdList || null,
  536. teacherId: this.searchForm.teacherId,
  537. page: this.rules.page,
  538. rows: this.rules.limit,
  539. existVipCourse: this.searchForm.existVipCourse || null,
  540. existPracticeCourse: this.searchForm.existPracticeCourse || null,
  541. };
  542. if (this.searchForm.timer && this.searchForm.timer.length > 0) {
  543. obj.monday = this.searchForm.timer[0];
  544. obj.sunday = this.searchForm.timer[1];
  545. } else {
  546. this.$message.error("请选择周次");
  547. return false;
  548. }
  549. if (this.searchForm.workTimer && this.searchForm.workTimer.length > 0) {
  550. obj.submitStartDate = this.searchForm.workTimer[0];
  551. obj.submitEndDate = this.searchForm.workTimer[1];
  552. }
  553. return obj;
  554. },
  555. getList() {
  556. let obj = this.getDate();
  557. if (!obj) return;
  558. findStudentExtracurricularExercisesSituations(obj).then((res) => {
  559. if (res.code == 200) {
  560. this.tableList = res.data.rows;
  561. this.rules.total = res.data.total;
  562. }
  563. });
  564. },
  565. onReSet() {
  566. this.searchForm = {
  567. timer: [],
  568. search: null,
  569. actualExercisesNumIsAchieve: null, // 训练次数
  570. exercisesMessageNumIsAchieve: null, //评价
  571. exercisesMessageTimelyNumIsAchieve: null, //及时评价
  572. exercisesReplyNumIsAchieve: null, // 提交次数
  573. teacherId: null,
  574. existVipCourse: null,
  575. };
  576. this.searchForm.timer = [];
  577. this.searchForm.timer.push(this.getNowDateAndMonday(nowTime));
  578. this.searchForm.timer.push(this.getNowDateAndSunday(nowTime));
  579. this.search();
  580. },
  581. cancleMore() {
  582. // this.$refs.searchForm2.resetFields()
  583. this.showMove = false;
  584. },
  585. okMore() {
  586. this.getList();
  587. this.showMove = false;
  588. },
  589. onExport() {
  590. let url = "/api-web/export/exercisesSituations";
  591. let obj = this.getDate();
  592. const options = {
  593. method: "get",
  594. headers: {
  595. Authorization: getToken(),
  596. },
  597. url,
  598. params: obj,
  599. responseType: "blob",
  600. };
  601. this.$confirm("您确定导出列表?", "提示", {
  602. confirmButtonText: "确定",
  603. cancelButtonText: "取消",
  604. type: "warning",
  605. })
  606. .then(() => {
  607. load.startLoading();
  608. axios(options)
  609. .then((res) => {
  610. let blob = new Blob([res.data], {
  611. // type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8',
  612. type: "application/vnd.ms-excel;charset=utf-8",
  613. // word文档为application/msword,pdf文档为application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
  614. });
  615. let text = new Response(blob).text();
  616. text.then((res) => {
  617. // 判断是否报错
  618. if (res.indexOf("code") != -1) {
  619. let json = JSON.parse(res);
  620. this.$message.error(json.msg);
  621. } else {
  622. let objectUrl = URL.createObjectURL(blob);
  623. let link = document.createElement("a");
  624. let nowTime = new Date();
  625. let ymd =
  626. nowTime.getFullYear() +
  627. "" +
  628. (nowTime.getMonth() + 1) +
  629. "" +
  630. nowTime.getDate() +
  631. "" +
  632. nowTime.getHours() +
  633. "" +
  634. nowTime.getMinutes();
  635. let fname = ymd + "服务指标.xls";
  636. link.href = objectUrl;
  637. link.setAttribute("download", fname);
  638. document.body.appendChild(link);
  639. link.click();
  640. }
  641. });
  642. load.endLoading();
  643. })
  644. .catch((error) => {
  645. this.$message.error("导出数据失败,请联系管理员");
  646. load.endLoading();
  647. });
  648. })
  649. .catch(() => {});
  650. },
  651. search() {
  652. this.rules.page = 1;
  653. this.$refs.searchForm.save(this.searchForm);
  654. this.getList();
  655. },
  656. getNowDateAndMonday(time) {
  657. let timestamp = new Date(time.replace(/-/g, "/")).getTime();
  658. let serverDate = new Date(time);
  659. if (serverDate.getDay() == 0) {
  660. timestamp -= 7 * 24 * 60 * 60 * 1000;
  661. }
  662. let mondayTime =
  663. timestamp - (serverDate.getDay() - 1) * 24 * 60 * 60 * 1000;
  664. let mondayData = new Date(mondayTime);
  665. //年
  666. let mondayY = mondayData.getFullYear();
  667. //月
  668. let mondayM =
  669. mondayData.getMonth() + 1 < 10
  670. ? "0" + (mondayData.getMonth() + 1)
  671. : mondayData.getMonth() + 1;
  672. //日
  673. let mondayD =
  674. mondayData.getDate() < 10
  675. ? "0" + mondayData.getDate()
  676. : mondayData.getDate();
  677. let str = mondayY + "-" + mondayM + "-" + mondayD;
  678. return str;
  679. },
  680. getNowDateAndSunday(time) {
  681. let timestamp = new Date(time.replace(/-/g, "/")).getTime();
  682. let serverDate = new Date(time);
  683. let num = 7 - serverDate.getDay();
  684. if (num == 7) {
  685. num = 0;
  686. }
  687. let sundayTiem = timestamp + num * 24 * 60 * 60 * 1000;
  688. let SundayData = new Date(sundayTiem);
  689. //年
  690. let tomorrowY = SundayData.getFullYear(); //月
  691. let tomorrowM =
  692. SundayData.getMonth() + 1 < 10
  693. ? "0" + (SundayData.getMonth() + 1)
  694. : SundayData.getMonth() + 1;
  695. //日
  696. let tomorrowD =
  697. SundayData.getDate() < 10
  698. ? "0" + SundayData.getDate()
  699. : SundayData.getDate();
  700. let str = tomorrowY + "-" + tomorrowM + "-" + tomorrowD;
  701. return str;
  702. },
  703. getWeekTime(val) {
  704. if (val && val.length > 0) {
  705. let start = this.getNowDateAndMonday(val[0]);
  706. let end = this.getNowDateAndSunday(val[1]);
  707. this.searchForm.timer.splice(0, 1, start);
  708. this.searchForm.timer.splice(1, 1, end);
  709. }
  710. },
  711. lookDetail(row) {
  712. // this.afterSchoolVisible = true;
  713. let rules = JSON.stringify(this.rules);
  714. let searchForm = JSON.stringify(this.searchForm);
  715. this.$router.push({
  716. path: "/serverIndexDetail",
  717. query: {
  718. studentId: row.studentId,
  719. studentName: row.studentName,
  720. rules,
  721. searchForm,
  722. title: row.studentName,
  723. extracurricularExercisesId: "yes",
  724. startTime: this.searchForm.timer[0],
  725. endTime: this.searchForm.timer[1],
  726. },
  727. });
  728. },
  729. lookServerDetail() {
  730. this.lookServer = true;
  731. },
  732. arraySpanMethod({ row, column, rowIndex, columnIndex }) {
  733. if (columnIndex === 0) {
  734. if (rowIndex % 2 === 0) {
  735. return {
  736. rowspan: 2,
  737. colspan: 1,
  738. };
  739. } else {
  740. return {
  741. rowspan: 0,
  742. colspan: 0,
  743. };
  744. }
  745. }
  746. },
  747. },
  748. computed:{
  749. isSearch(){
  750. return this.searchForm.organIdList ||
  751. this.searchForm.actualExercisesNumIsAchieve ||
  752. this.searchForm.exercisesReplyNumIsAchieve ||
  753. this.searchForm.exercisesMessageNumIsAchieve ||
  754. this.searchForm.exercisesMessageTimelyNumIsAchieve ||
  755. this.searchForm.existVipCourse||
  756. this.searchForm.existPracticeCourse||
  757. this.searchForm.workTimer?.length>0
  758. }
  759. }
  760. };
  761. </script>
  762. <style lang='scss' scoped>
  763. .micon {
  764. position: absolute;
  765. top: 3px;
  766. right: 2px;
  767. }
  768. .serverInfo {
  769. line-height: 30px;
  770. span {
  771. color: #333;
  772. font-weight: bold;
  773. }
  774. }
  775. .infoWrap {
  776. margin-top: 30px;
  777. span {
  778. color: red;
  779. font-weight: normal;
  780. }
  781. }
  782. .titleWrap {
  783. display: flex;
  784. flex-direction: row;
  785. justify-content: flex-start;
  786. align-items: center;
  787. }
  788. .m-container {
  789. h2 {
  790. justify-content: space-between;
  791. }
  792. }
  793. </style>