ProjectStatistic.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  1. <template>
  2. <section class="content" style="margin-top: -18px;">
  3. <div class="box box-info">
  4. <!-- 头信息 -->
  5. <div
  6. class="box-header with-border"
  7. style="background-color:#d3dce6;margin-bottom:20px;"
  8. >
  9. <h3 class="box-title">项目统计</h3>
  10. <div class="box-tools pull-right">
  11. <button type="button" class="btn btn-box-tool" data-widget="collapse">
  12. <i class="fa fa-minus"></i>
  13. </button>
  14. </div>
  15. </div>
  16. <!-- 正文信息 -->
  17. <div class="box-body">
  18. <el-form
  19. :model="formSearch"
  20. :inline="true"
  21. label-position="right"
  22. label-width="100px"
  23. >
  24. <el-form-item label="学校">
  25. <el-select
  26. :disabled="showGoBack"
  27. v-model="formSearch.orgId"
  28. placeholder="请选择"
  29. filterable
  30. clearable
  31. @change="searchExamList(formSearch.orgId);"
  32. >
  33. <el-option
  34. v-for="item in orgList"
  35. :label="item.orgName"
  36. :value="item.orgId"
  37. :key="item.orgId"
  38. ></el-option>
  39. </el-select>
  40. </el-form-item>
  41. <el-form-item label="考试">
  42. <el-select
  43. :disabled="showGoBack"
  44. v-model="formSearch.examId"
  45. placeholder="请选择"
  46. >
  47. <el-option
  48. v-for="item in examList"
  49. :label="item.examName"
  50. :value="item.examId"
  51. :key="item.examId"
  52. ></el-option>
  53. </el-select>
  54. </el-form-item>
  55. <el-form-item>
  56. <el-button
  57. size="small"
  58. type="primary"
  59. icon="el-icon-search"
  60. @click="searchRecords"
  61. >查询
  62. </el-button>
  63. <el-button
  64. size="small"
  65. type="primary"
  66. icon="el-icon-plus"
  67. :disabled="!hasPermit"
  68. @click="openOtherSettingDialog"
  69. >新增其他事项
  70. </el-button>
  71. <el-button
  72. size="small"
  73. type="primary"
  74. icon="el-icon-refresh"
  75. :disabled="!hasPermit"
  76. v-show="formSearch.examId != ''"
  77. @click="refreshStatistic"
  78. >刷新
  79. </el-button>
  80. <el-button
  81. size="small"
  82. type="primary"
  83. icon="el-icon-arrow-left"
  84. v-show="showGoBack"
  85. @click="goBack"
  86. >返回
  87. </el-button>
  88. </el-form-item>
  89. </el-form>
  90. <!-- 数据列表 -->
  91. <el-table
  92. v-loading="loading"
  93. :data="tableData"
  94. element-loading-text="数据加载中"
  95. style="width:100%;"
  96. border
  97. >
  98. <el-table-column width="60" label="类型" prop="type" />
  99. <el-table-column width="80" label="人科次" prop="totalStudent" />
  100. <el-table-column width="100" label="课程数量" prop="totalCourse" />
  101. <el-table-column width="100" label="试卷数量" prop="totalPaper" />
  102. <el-table-column width="100" label="印刷数量A3" prop="A3" />
  103. <el-table-column width="100" label="印刷数量A4" prop="A4" />
  104. <el-table-column width="100" label="总数(A3)" prop="sumA3" />
  105. <el-table-column width="80" label="试卷袋数" prop="totalPkg" />
  106. <el-table-column label="事项说明" prop="remark" />
  107. <el-table-column width="120" label="印刷供应商" prop="supplierName" />
  108. <el-table-column width="120" label="项目经理" prop="pmName" />
  109. <el-table-column width="180" label="操作" :context="_self">
  110. <template slot-scope="scope">
  111. <el-button
  112. size="mini"
  113. icon="el-icon-menu"
  114. v-if="scope.row.btnType == 'BACKUP'"
  115. @click="openBackupSettingDialog"
  116. :disabled="!hasPermit"
  117. >备份设置
  118. </el-button>
  119. <el-button
  120. size="mini"
  121. icon="el-icon-edit"
  122. v-if="scope.row.btnType == 'OTHER'"
  123. @click="openOtherSettingDialog(scope.row);"
  124. :disabled="!hasPermit"
  125. >修改
  126. </el-button>
  127. <el-button
  128. size="mini"
  129. type="danger"
  130. icon="el-icon-delete"
  131. v-if="scope.row.btnType == 'OTHER'"
  132. @click="removeOtherSetting(scope.row);"
  133. :disabled="!hasPermit"
  134. >删除
  135. </el-button>
  136. </template>
  137. </el-table-column>
  138. </el-table>
  139. </div>
  140. <!-- 备份设置弹窗 -->
  141. <el-dialog
  142. title="备份设置"
  143. width="500px"
  144. :visible.sync="backupSettingDialog"
  145. @close="closeBackupSettingDialog"
  146. >
  147. <el-form
  148. :model="backupSettingForm"
  149. ref="backupSettingForm"
  150. :rules="rules"
  151. label-position="right"
  152. label-width="80px"
  153. >
  154. <el-tabs v-model="eachPkgTab">
  155. <el-tab-pane name="first">
  156. <span slot="label"
  157. >每袋冗余设置
  158. <el-switch v-model="backupSettingForm.needEachPkg"></el-switch
  159. ></span>
  160. <el-form-item label="比例" prop="eachPkgPercent">
  161. <el-input
  162. v-model="backupSettingForm.eachPkgPercent"
  163. :disabled="!backupSettingForm.needEachPkg"
  164. ></el-input>
  165. </el-form-item>
  166. <el-form-item label="最大" prop="eachPkgMax">
  167. <el-input
  168. v-model="backupSettingForm.eachPkgMax"
  169. :disabled="!backupSettingForm.needEachPkg"
  170. ></el-input>
  171. </el-form-item>
  172. <el-form-item label="最小" prop="eachPkgMin">
  173. <el-input
  174. v-model="backupSettingForm.eachPkgMin"
  175. :disabled="!backupSettingForm.needEachPkg"
  176. ></el-input>
  177. </el-form-item>
  178. </el-tab-pane>
  179. </el-tabs>
  180. <el-tabs v-model="alonePkgTab">
  181. <el-tab-pane name="first">
  182. <span slot="label"
  183. >单独备份袋设置
  184. <el-switch v-model="backupSettingForm.needAlonePkg"></el-switch
  185. ></span>
  186. <el-form-item label="归集参数" prop="groupType">
  187. <el-select
  188. v-model="backupSettingForm.groupType"
  189. :disabled="!backupSettingForm.needAlonePkg"
  190. placeholder="请选择"
  191. >
  192. <el-option
  193. v-for="item in groupTypeList"
  194. :label="item.label"
  195. :value="item.value"
  196. :key="item.value"
  197. ></el-option>
  198. </el-select>
  199. </el-form-item>
  200. <el-form-item label="比例" prop="alonePkgPercent">
  201. <el-input
  202. v-model="backupSettingForm.alonePkgPercent"
  203. :disabled="!backupSettingForm.needAlonePkg"
  204. ></el-input>
  205. </el-form-item>
  206. <el-form-item label="最大" prop="alonePkgMax">
  207. <el-input
  208. v-model="backupSettingForm.alonePkgMax"
  209. :disabled="!backupSettingForm.needAlonePkg"
  210. ></el-input>
  211. </el-form-item>
  212. <el-form-item label="最小" prop="alonePkgMin">
  213. <el-input
  214. v-model="backupSettingForm.alonePkgMin"
  215. :disabled="!backupSettingForm.needAlonePkg"
  216. ></el-input>
  217. </el-form-item>
  218. </el-tab-pane>
  219. </el-tabs>
  220. </el-form>
  221. <div style="text-align: center;">
  222. <el-button type="primary" @click="editBackupSetting"
  223. >确 定
  224. </el-button>
  225. <el-button @click="closeBackupSettingDialog">取 消</el-button>
  226. </div>
  227. </el-dialog>
  228. <!-- 其它事项弹窗 -->
  229. <el-dialog
  230. title="其它事项"
  231. width="750px"
  232. :visible.sync="otherSettingDialog"
  233. @close="closeOtherSettingDialog"
  234. >
  235. <el-form
  236. :model="otherSettingForm"
  237. ref="otherSettingForm"
  238. :rules="rules"
  239. label-position="right"
  240. label-width="110px"
  241. >
  242. <el-form-item label="事项内容" prop="remark">
  243. <el-input
  244. type="textarea"
  245. :rows="8"
  246. v-model="otherSettingForm.remark"
  247. ></el-input>
  248. </el-form-item>
  249. </el-form>
  250. <div style="text-align: center">
  251. <el-button type="primary" @click="editOtherSetting">确 定 </el-button>
  252. <el-button @click="closeOtherSettingDialog">取 消</el-button>
  253. </div>
  254. </el-dialog>
  255. </div>
  256. </section>
  257. </template>
  258. <script>
  259. import { PRINT_API } from "@/constants/constants";
  260. import { userRole, groupTypeList } from "../constants/constants.js";
  261. import { mapState } from "vuex";
  262. export default {
  263. data() {
  264. let validateEachPkgPercent = (rule, value, callback) => {
  265. if (this.backupSettingForm.needEachPkg) {
  266. if (this.isEmptyNumber(this.backupSettingForm.eachPkgPercent)) {
  267. callback(new Error("请输入正确的数值!"));
  268. return;
  269. }
  270. }
  271. callback();
  272. };
  273. let validateEachPkgMax = (rule, value, callback) => {
  274. if (this.backupSettingForm.needEachPkg) {
  275. if (this.isEmptyNumber(this.backupSettingForm.eachPkgMax)) {
  276. callback(new Error("请输入正确的数值!"));
  277. return;
  278. }
  279. }
  280. callback();
  281. };
  282. let validateEachPkgMin = (rule, value, callback) => {
  283. if (this.backupSettingForm.needEachPkg) {
  284. if (this.isEmptyNumber(this.backupSettingForm.eachPkgMin)) {
  285. callback(new Error("请输入正确的数值!"));
  286. return;
  287. }
  288. }
  289. callback();
  290. };
  291. let validateAlonePkgPercent = (rule, value, callback) => {
  292. if (this.backupSettingForm.needAlonePkg) {
  293. if (this.isEmptyNumber(this.backupSettingForm.alonePkgPercent)) {
  294. callback(new Error("请输入正确的数值!"));
  295. return;
  296. }
  297. }
  298. callback();
  299. };
  300. let validateAlonePkgMax = (rule, value, callback) => {
  301. if (this.backupSettingForm.needAlonePkg) {
  302. if (this.isEmptyNumber(this.backupSettingForm.alonePkgMax)) {
  303. callback(new Error("请输入正确的数值!"));
  304. return;
  305. }
  306. }
  307. callback();
  308. };
  309. let validateAlonePkgMin = (rule, value, callback) => {
  310. if (this.backupSettingForm.needAlonePkg) {
  311. if (this.isEmptyNumber(this.backupSettingForm.alonePkgMin)) {
  312. callback(new Error("请输入正确的数值!"));
  313. return;
  314. }
  315. }
  316. callback();
  317. };
  318. let validateGroupType = (rule, value, callback) => {
  319. if (this.backupSettingForm.needAlonePkg) {
  320. if (this.isEmptyStr(this.backupSettingForm.groupType)) {
  321. callback(new Error("请选择归集参数!"));
  322. return;
  323. }
  324. }
  325. callback();
  326. };
  327. return {
  328. formSearch: {
  329. orgId: "",
  330. examId: ""
  331. },
  332. curUserRole: userRole,
  333. groupTypeList: groupTypeList,
  334. hasPermit: false,
  335. loading: false,
  336. showGoBack: false,
  337. tableData: [],
  338. projectId: "",
  339. eachPkgTab: "first",
  340. alonePkgTab: "first",
  341. orgList: [],
  342. examList: [],
  343. backupSettingDialog: false,
  344. backupSettingForm: {
  345. projectId: "",
  346. needAlonePkg: true,
  347. needEachPkg: true,
  348. eachPkgPercent: "",
  349. eachPkgMax: "",
  350. eachPkgMin: "",
  351. alonePkgPercent: "",
  352. alonePkgMax: "",
  353. alonePkgMin: "",
  354. groupType: ""
  355. },
  356. otherSettingDialog: false,
  357. otherSettingForm: {
  358. id: "",
  359. projectId: "",
  360. remark: ""
  361. },
  362. rules: {
  363. eachPkgPercent: [
  364. {
  365. type: "number",
  366. required: true,
  367. validator: validateEachPkgPercent,
  368. trigger: "blur"
  369. }
  370. ],
  371. eachPkgMax: [
  372. {
  373. type: "number",
  374. required: true,
  375. validator: validateEachPkgMax,
  376. trigger: "blur"
  377. }
  378. ],
  379. eachPkgMin: [
  380. {
  381. type: "number",
  382. required: true,
  383. validator: validateEachPkgMin,
  384. trigger: "blur"
  385. }
  386. ],
  387. alonePkgPercent: [
  388. {
  389. type: "number",
  390. required: true,
  391. validator: validateAlonePkgPercent,
  392. trigger: "blur"
  393. }
  394. ],
  395. alonePkgMax: [
  396. {
  397. type: "number",
  398. required: true,
  399. validator: validateAlonePkgMax,
  400. trigger: "blur"
  401. }
  402. ],
  403. alonePkgMin: [
  404. {
  405. type: "number",
  406. required: true,
  407. validator: validateAlonePkgMin,
  408. trigger: "blur"
  409. }
  410. ],
  411. groupType: [
  412. { required: true, validator: validateGroupType, trigger: "change" }
  413. ],
  414. remark: [
  415. { required: true, message: "请输入事项内容!", trigger: "blur" }
  416. ]
  417. }
  418. };
  419. },
  420. methods: {
  421. searchRecords() {
  422. /* 查询记录列表 */
  423. let orgId = this.formSearch.orgId;
  424. if (this.isEmptyNumber(orgId)) {
  425. this.$notify({
  426. message: "请选择学校!",
  427. type: "warning"
  428. });
  429. return;
  430. }
  431. let examId = this.formSearch.examId;
  432. if (this.isEmptyNumber(examId)) {
  433. this.$notify({
  434. message: "请选择考试!",
  435. type: "warning"
  436. });
  437. return;
  438. }
  439. this.loading = true;
  440. let url =
  441. PRINT_API + "/printing/project/statistic/" + orgId + "/" + examId;
  442. this.$http.post(url, this.formSearch).then(
  443. response => {
  444. this.tableData = [];
  445. this.projectId = response.data.projectId;
  446. this.renderTableColumns(response.data);
  447. this.loadOtherSetting(this.projectId);
  448. this.loading = false;
  449. },
  450. error => {
  451. console.log(error);
  452. this.loading = false;
  453. }
  454. );
  455. },
  456. renderTableColumns(data) {
  457. let normalColumn = {
  458. type: "常规",
  459. A3: data.normalA3,
  460. A4: data.normalA4,
  461. sumA3: data.summary,
  462. totalStudent: data.totalStudent,
  463. totalCourse: data.totalCourse,
  464. totalPaper: data.totalPaper,
  465. totalPkg: data.totalPkg,
  466. supplierName: data.supplierName,
  467. pmName: data.pmName
  468. };
  469. this.tableData.push(normalColumn);
  470. let backupColumn = {
  471. type: "备份",
  472. A3: data.backupA3,
  473. A4: data.backupA4,
  474. sumA3: data.backupSummary,
  475. btnType: "BACKUP"
  476. };
  477. this.tableData.push(backupColumn);
  478. let totalColumn = {
  479. type: "合计",
  480. A3: data.totalA3,
  481. A4: data.totalA4,
  482. sumA3: data.totalSummary
  483. };
  484. this.tableData.push(totalColumn);
  485. },
  486. searchExamList(orgId) {
  487. /* 查询考试列表 */
  488. this.formSearch.examId = "";
  489. this.examList = [];
  490. if (!this.isEmptyNumber(orgId)) {
  491. let url = PRINT_API + "/printing/project/exam/list?orgId=" + orgId;
  492. this.$http.post(url).then(response => {
  493. this.examList = response.data;
  494. });
  495. }
  496. },
  497. refreshStatistic() {
  498. /* 刷新当前统计信息 */
  499. this.$confirm("刷新当前统计信息?", "提示", {
  500. confirmButtonText: "确定",
  501. cancelButtonText: "取消",
  502. type: "warning"
  503. })
  504. .then(() => {
  505. let url =
  506. PRINT_API +
  507. "/printing/project/statistic/refresh/" +
  508. +this.formSearch.orgId +
  509. "/" +
  510. this.formSearch.examId;
  511. this.$http.post(url).then(
  512. () => {
  513. this.$notify({
  514. type: "success",
  515. message: "刷新成功!"
  516. });
  517. this.searchRecords();
  518. },
  519. () => {
  520. this.$notify({
  521. type: "error",
  522. message: "刷新失败!"
  523. });
  524. }
  525. );
  526. })
  527. .catch(() => {
  528. //ignore
  529. });
  530. },
  531. editBackupSetting() {
  532. /* 保存备份设置 */
  533. this.$refs.backupSettingForm.validate(valid => {
  534. if (!valid) {
  535. return false;
  536. }
  537. if (
  538. !this.backupSettingForm.needEachPkg &&
  539. !this.backupSettingForm.needAlonePkg
  540. ) {
  541. this.$notify({
  542. message: "请至少选择一种备份方式!",
  543. type: "warning"
  544. });
  545. return;
  546. }
  547. let url = PRINT_API + "/project/backup/setting/save";
  548. this.$http.post(url, this.backupSettingForm).then(
  549. () => {
  550. this.$notify({
  551. type: "success",
  552. message: "保存备份设置成功!"
  553. });
  554. this.backupSettingDialog = false;
  555. },
  556. error => {
  557. console.log(error);
  558. this.$notify({
  559. message: "保存备份设置失败!",
  560. type: "error"
  561. });
  562. }
  563. );
  564. });
  565. },
  566. openBackupSettingDialog() {
  567. /* 打开备份设置弹窗 */
  568. let url = PRINT_API + "/project/backup/setting/" + this.projectId;
  569. this.$http.post(url).then(
  570. response => {
  571. this.backupSettingForm = response.data;
  572. this.$refs.backupSettingForm.validate();
  573. },
  574. () => {
  575. this.backupSettingForm = {
  576. projectId: this.projectId,
  577. needAlonePkg: true,
  578. needEachPkg: true,
  579. eachPkgPercent: "",
  580. eachPkgMax: "",
  581. eachPkgMin: "",
  582. alonePkgPercent: "",
  583. alonePkgMax: "",
  584. alonePkgMin: "",
  585. groupType: ""
  586. };
  587. this.$refs.backupSettingForm.validate();
  588. }
  589. );
  590. this.backupSettingDialog = true;
  591. },
  592. closeBackupSettingDialog() {
  593. /* 关闭备份设置弹窗 */
  594. this.backupSettingDialog = false;
  595. },
  596. loadOtherSetting(projectId) {
  597. /* 查询其它事项列表 */
  598. let url =
  599. PRINT_API + "/project/other/setting/list?projectId=" + projectId;
  600. this.$http.post(url).then(
  601. response => {
  602. let list = response.data;
  603. if (!list || list.length < 1) {
  604. return;
  605. }
  606. for (let obj of list) {
  607. obj.type = "其它";
  608. obj.btnType = "OTHER";
  609. this.tableData.push(obj);
  610. }
  611. },
  612. error => {
  613. console.log(error);
  614. this.loading = false;
  615. }
  616. );
  617. },
  618. editOtherSetting() {
  619. /* 保存其它事项 */
  620. this.$refs.otherSettingForm.validate(valid => {
  621. if (!valid) {
  622. return false;
  623. }
  624. let url = PRINT_API + "/project/other/setting/save";
  625. this.$http.post(url, this.otherSettingForm).then(
  626. () => {
  627. this.$notify({
  628. type: "success",
  629. message: "保存其它事项成功!"
  630. });
  631. this.otherSettingDialog = false;
  632. this.searchRecords();
  633. },
  634. error => {
  635. console.log(error);
  636. this.$notify({
  637. message: "保存其它事项失败!",
  638. type: "error"
  639. });
  640. }
  641. );
  642. });
  643. },
  644. removeOtherSetting(row) {
  645. /* 删除某个其它事项 */
  646. this.$confirm("确定删除当前事项吗?", "提示", {
  647. confirmButtonText: "确定",
  648. cancelButtonText: "取消",
  649. type: "warning"
  650. })
  651. .then(() => {
  652. var url = PRINT_API + "/project/other/setting/delete/" + row.id;
  653. this.$http.post(url).then(
  654. () => {
  655. this.$notify({
  656. type: "success",
  657. message: "删除当前事项成功!"
  658. });
  659. this.searchRecords();
  660. },
  661. () => {
  662. this.$notify({
  663. type: "error",
  664. message: "删除当前事项失败!"
  665. });
  666. }
  667. );
  668. })
  669. .catch(() => {
  670. //ignore
  671. });
  672. },
  673. openOtherSettingDialog(row) {
  674. /* 打开其它事项弹窗 */
  675. this.otherSettingDialog = true;
  676. this.otherSettingForm.projectId = this.projectId;
  677. if (row) {
  678. this.otherSettingForm.id = row.id;
  679. this.otherSettingForm.remark = row.remark;
  680. } else {
  681. this.otherSettingForm.id = "";
  682. this.otherSettingForm.remark = "";
  683. }
  684. },
  685. closeOtherSettingDialog() {
  686. /* 关闭其它事项弹窗 */
  687. this.otherSettingDialog = false;
  688. },
  689. goBack() {
  690. /* 返回上级界面 */
  691. this.$router.push({ path: "/print/project/list" });
  692. }
  693. },
  694. computed: {
  695. ...mapState({ user: state => state.user })
  696. },
  697. created() {
  698. this.loadOrgList();
  699. this.loadUserRole(this.user);
  700. if (this.curUserRole.isSuperLeader || this.curUserRole.isPM) {
  701. this.hasPermit = true;
  702. } else {
  703. this.hasPermit = false;
  704. }
  705. /* 加载默认数据 */
  706. let orgId = this.$route.params.orgId;
  707. let examId = this.$route.params.examId;
  708. if (orgId != "0" || examId != "0") {
  709. this.searchExamList(orgId);
  710. this.showGoBack = true;
  711. this.formSearch.orgId = parseInt(orgId);
  712. this.formSearch.examId = parseInt(examId);
  713. this.searchRecords();
  714. }
  715. }
  716. };
  717. </script>
  718. <style scoped>
  719. .page {
  720. margin-top: 10px;
  721. }
  722. .pull-right {
  723. float: right;
  724. }
  725. .pull-left {
  726. float: left;
  727. }
  728. </style>