classFeesIsOk.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. <!-- -->
  2. <template>
  3. <div class="m-container">
  4. <h2>
  5. <div class="squrt"></div>
  6. 课酬确认
  7. </h2>
  8. <div class="m-core">
  9. <div
  10. @click="openSalary"
  11. v-if="isOpen == 0"
  12. v-permission="'courseScheduleTeacherSalary/openSalaryConfirm'"
  13. class="newBand"
  14. >
  15. 开启课酬确认
  16. </div>
  17. <div
  18. v-if="isOpen == 1"
  19. @click="closeSalary"
  20. v-permission="'courseScheduleTeacherSalary/closeSalaryConfirm'"
  21. class="newBand"
  22. >
  23. 关闭课酬确认
  24. </div>
  25. <save-form
  26. :inline="true"
  27. @submit="search"
  28. @reset="onReSet"
  29. :model="searchForm"
  30. >
  31. <el-form-item>
  32. <el-input
  33. v-model.trim="searchForm.search"
  34. @keyup.enter.native="search"
  35. placeholder="课程编号、课程组名称"
  36. ></el-input>
  37. </el-form-item>
  38. <el-form-item prop="organId">
  39. <el-select
  40. class="multiple"
  41. v-model.trim="searchForm.organIdList"
  42. filterable
  43. clearable
  44. placeholder="请选择分部"
  45. >
  46. <el-option
  47. v-for="(item, index) in organList"
  48. :key="index"
  49. :label="item.name"
  50. :value="item.id"
  51. ></el-option>
  52. </el-select>
  53. </el-form-item>
  54. <el-form-item prop="organId">
  55. <el-select
  56. class="multiple"
  57. v-model.trim="searchForm.groupType"
  58. filterable
  59. clearable
  60. placeholder="请选择课程组类型"
  61. >
  62. <el-option
  63. v-for="(item, index) in groupTypeList"
  64. :key="index"
  65. :label="item.label"
  66. :value="item.value"
  67. ></el-option>
  68. </el-select>
  69. </el-form-item>
  70. <el-form-item>
  71. <el-select
  72. placeholder="老师姓名"
  73. v-model="searchForm.teacherId"
  74. clearable
  75. filterable
  76. >
  77. <el-option
  78. v-for="(item, index) in teacherList"
  79. :label="item.realName"
  80. :value="item.id"
  81. :key="index"
  82. ></el-option>
  83. </el-select>
  84. </el-form-item>
  85. <el-form-item>
  86. <el-select
  87. placeholder="正常签到"
  88. v-model="searchForm.signInStatus"
  89. clearable
  90. >
  91. <el-option label="是" value="1"></el-option>
  92. <el-option label="否" value="0"></el-option>
  93. </el-select>
  94. </el-form-item>
  95. <el-form-item>
  96. <el-select
  97. placeholder="正常签退"
  98. v-model="searchForm.signOutStatus"
  99. clearable
  100. >
  101. <el-option label="是" value="1"></el-option>
  102. <el-option label="否" value="0"></el-option>
  103. </el-select>
  104. </el-form-item>
  105. <el-form-item>
  106. <el-select
  107. placeholder="状态"
  108. v-model="searchForm.confirmStatus"
  109. clearable
  110. >
  111. <el-option label="待确定" value="1"></el-option>
  112. <el-option label="已确定" value="2"></el-option>
  113. <el-option label="已完成" value="3"></el-option>
  114. </el-select>
  115. </el-form-item>
  116. <el-form-item>
  117. <el-date-picker
  118. :clearable="false"
  119. v-model="searchForm.month"
  120. type="month"
  121. value-format="yyyy-MM"
  122. placeholder="选择年月"
  123. ></el-date-picker>
  124. </el-form-item>
  125. <el-form-item>
  126. <el-button type="danger" native-type="submit">搜索</el-button>
  127. <el-button native-type="reset" type="primary">重置</el-button>
  128. <!-- export/isSettlementCourseSalarys -->
  129. <el-button
  130. @click="onExport"
  131. type="primary"
  132. v-permission="'export/exercisesSituations'"
  133. style="background: #14928a; border: 1px solid #14928a"
  134. >导出</el-button
  135. >
  136. </el-form-item>
  137. </save-form>
  138. <div class="tableWrap">
  139. <el-table
  140. style="width: 100%"
  141. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  142. :data="tableList"
  143. >
  144. <el-table-column
  145. align="center"
  146. prop="organName"
  147. label="分部"
  148. ></el-table-column>
  149. <el-table-column
  150. align="center"
  151. prop="groupType"
  152. width="100"
  153. label="课程组类型"
  154. >
  155. <template slot-scope="scope">{{
  156. scope.row.groupType | coursesType
  157. }}</template>
  158. </el-table-column>
  159. <el-table-column
  160. align="center"
  161. prop="courseScheduleId"
  162. label="课程编号"
  163. ></el-table-column>
  164. <el-table-column
  165. align="center"
  166. prop="courseScheduleId"
  167. width="150"
  168. label="时间"
  169. >
  170. <template slot-scope="scope">{{
  171. scope.row.startClassTime | dateForMinFormat
  172. }}</template>
  173. </el-table-column>
  174. <el-table-column
  175. align="center"
  176. prop="courseName"
  177. width="120"
  178. label="课程名称"
  179. ></el-table-column>
  180. <el-table-column
  181. align="center"
  182. prop="teacherId"
  183. label="老师编号"
  184. ></el-table-column>
  185. <el-table-column
  186. align="center"
  187. prop="teacherName"
  188. label="老师姓名"
  189. ></el-table-column>
  190. <el-table-column
  191. align="center"
  192. prop="courseScheduleId"
  193. width="150"
  194. label="签到时间"
  195. >
  196. <template slot-scope="scope">
  197. <p :class="scope.row.signInStatus == 1 ? '' : 'red'">
  198. {{ scope.row.signInTime | dateForMinFormat }}
  199. </p>
  200. <p :class="scope.row.signInStatus == 1 ? '' : 'red'">
  201. {{ scope.row.signInStatus | attendanceType }}
  202. </p>
  203. <p
  204. class="red"
  205. v-if="!scope.row.signInStatus && scope.row.signInStatus != 0"
  206. >
  207. 未签到
  208. </p>
  209. </template>
  210. </el-table-column>
  211. <el-table-column
  212. align="center"
  213. prop="courseScheduleId"
  214. width="150"
  215. label="签退时间"
  216. >
  217. <template slot-scope="scope">
  218. <p :class="scope.row.signOutStatus == 1 ? '' : 'red'">
  219. {{ scope.row.signOutTime | dateForMinFormat }}
  220. </p>
  221. <p :class="scope.row.signOutStatus == 1 ? '' : 'red'">
  222. {{ scope.row.signOutStatus | attendanceOutType }}
  223. </p>
  224. <p
  225. class="red"
  226. v-if="!scope.row.signOutStatus && scope.row.signOutStatus != 0"
  227. >
  228. 未签退
  229. </p>
  230. </template>
  231. </el-table-column>
  232. <!-- <el-table-column align="center" prop="actualReceipts" label="实际收款">
  233. <template slot-scope="scope">{{(scope.row.actualReceipts ? scope.row.actualReceipts : 0) + '元'}}</template>
  234. </el-table-column> -->
  235. <!-- expectSalary -->
  236. <el-table-column align="center" prop="actualSalary" label="应发课酬">
  237. <template slot-scope="scope"
  238. >{{ scope.row.actualSalary | moneyFormat }}元</template
  239. >
  240. </el-table-column>
  241. <el-table-column align="center" prop="reduceSalary" label="课酬扣款">
  242. <template slot-scope="scope"
  243. >{{ scope.row.reduceSalary | moneyFormat }}元</template
  244. >
  245. </el-table-column>
  246. <el-table-column align="center" prop="finalSalary" label="结算课酬">
  247. <template slot-scope="scope"
  248. >{{ scope.row.finalSalary | moneyFormat }}元</template
  249. >
  250. </el-table-column>
  251. <el-table-column align="center" prop label="状态" fixed="right">
  252. <template slot-scope="scope">{{
  253. scope.row.confirmStatus | confirmFilter
  254. }}</template>
  255. </el-table-column>
  256. <el-table-column
  257. align="center"
  258. prop="memo"
  259. label="备注"
  260. width="300"
  261. fixed="right"
  262. ></el-table-column>
  263. <el-table-column align="center" label="操作" fixed="right">
  264. <template slot-scope="scope">
  265. <el-button type="text" @click="resetSalary(scope.row)"
  266. >课酬调整</el-button
  267. >
  268. </template>
  269. </el-table-column>
  270. </el-table>
  271. <pagination
  272. sync
  273. :total.sync="rules.total"
  274. :page.sync="rules.page"
  275. :limit.sync="rules.limit"
  276. :page-sizes="rules.page_size"
  277. @pagination="getList"
  278. />
  279. </div>
  280. </div>
  281. <el-dialog title="课酬调整" :visible.sync="dialogVisible" width="400px">
  282. <div>
  283. <el-form
  284. ref="visibleForm"
  285. :model="visibleForm"
  286. class="visibleForm"
  287. :inline="true"
  288. label-width="60px"
  289. >
  290. <el-form-item
  291. label="应发"
  292. :rules="[
  293. { required: true, message: '请填写应发数', trigger: 'blur' },
  294. ]"
  295. prop="actualSalary"
  296. >
  297. <el-input-number
  298. :controls="false"
  299. :min="0"
  300. :precision="2"
  301. v-model.trim="visibleForm.actualSalary"
  302. type="number"
  303. @mousewheel.native.prevent
  304. ></el-input-number>
  305. </el-form-item>
  306. <el-form-item
  307. label="扣款"
  308. :rules="[
  309. { required: true, message: '请填写扣款数', trigger: 'blur' },
  310. ]"
  311. prop="reduceSalary"
  312. >
  313. <el-input-number
  314. :controls="false"
  315. :min="0"
  316. :precision="2"
  317. v-model.trim="visibleForm.reduceSalary"
  318. type="number"
  319. @mousewheel.native.prevent
  320. ></el-input-number>
  321. </el-form-item>
  322. <el-form-item label="实发">
  323. <el-input-number
  324. :controls="false"
  325. :min="0"
  326. :precision="2"
  327. v-model.trim="visibleForm.finalSalary"
  328. disabled
  329. type="number"
  330. @mousewheel.native.prevent
  331. ></el-input-number>
  332. </el-form-item>
  333. <el-form-item
  334. label="说明"
  335. :rules="[
  336. { required: true, message: '请填写说明', trigger: 'blur' },
  337. ]"
  338. prop="memo"
  339. >
  340. <el-input
  341. type="textarea"
  342. :rows="5"
  343. v-model.trim="visibleForm.memo"
  344. ></el-input>
  345. </el-form-item>
  346. </el-form>
  347. </div>
  348. <div slot="footer">
  349. <el-button @click="dialogVisible = false">取 消</el-button>
  350. <el-button type="primary" @click="subreset">确 定</el-button>
  351. </div>
  352. </el-dialog>
  353. </div>
  354. </template>
  355. <script>
  356. import numeral from "numeral";
  357. import axios from "axios";
  358. import { getToken } from "@/utils/auth";
  359. import pagination from "@/components/Pagination/index";
  360. import load from "@/utils/loading";
  361. import { getTeacher, getEmployeeOrgan } from "@/api/buildTeam";
  362. import {
  363. findIsSettlementCourseSalarys,
  364. openSalaryConfirm,
  365. closeSalaryConfirm,
  366. teacherSalaryModifyLog,
  367. } from "@/api/journal";
  368. import { courseListType } from "@/utils/searchArray";
  369. export default {
  370. components: { pagination },
  371. data() {
  372. return {
  373. searchForm: {
  374. search: null,
  375. organIdList: null,
  376. groupType: null,
  377. teacherId: null,
  378. signInStatus: null,
  379. signOutStatus: null,
  380. month: null,
  381. confirmStatus: null,
  382. },
  383. dialogVisible: false,
  384. visibleForm: {
  385. finalSalary: null,
  386. reduceSalary: null,
  387. actualSalary: null,
  388. courseScheduleId: null,
  389. teacherId: null,
  390. memo: null,
  391. },
  392. isOpen: null,
  393. activeRow: null,
  394. teacherList: [],
  395. tableList: [],
  396. organList: [],
  397. groupTypeList: courseListType,
  398. rules: {
  399. // 分页规则
  400. limit: 10, // 限制显示条数
  401. page: 1, // 当前页
  402. total: 0, // 总条数
  403. page_size: [10, 20, 40, 50], // 选择限制显示条数
  404. },
  405. };
  406. },
  407. //生命周期 - 创建完成(可以访问当前this实例)
  408. created() {},
  409. //生命周期 - 挂载完成(可以访问DOM元素)
  410. mounted() {
  411. getTeacher().then((res) => {
  412. if (res.code == 200) {
  413. this.teacherList = res.data;
  414. }
  415. });
  416. getEmployeeOrgan().then((res) => {
  417. if (res.code == 200) {
  418. this.organList = res.data;
  419. }
  420. });
  421. // 获取分部
  422. this.init();
  423. },
  424. activated() {
  425. this.init();
  426. },
  427. methods: {
  428. init() {
  429. if (!this.searchForm.month) {
  430. var now = new Date();
  431. this.searchForm.month = new Date(
  432. Date.UTC(now.getFullYear(), now.getMonth(), now.getDate())
  433. )
  434. .toISOString()
  435. .slice(0, 7);
  436. }
  437. this.getList();
  438. },
  439. getList() {
  440. let obj = this.getDate();
  441. findIsSettlementCourseSalarys(obj).then((res) => {
  442. if (res.code == 200) {
  443. this.isOpen = res.data.isOpenConfirm;
  444. this.tableList = res.data.pageInfo.rows;
  445. this.rules.total = res.data.pageInfo.total;
  446. }
  447. });
  448. },
  449. search() {
  450. this.rules.page = 1;
  451. this.getList();
  452. },
  453. onReSet() {
  454. this.searchForm = {
  455. search: null,
  456. organIdList: null,
  457. groupType: null,
  458. teacherId: null,
  459. signInStatus: null,
  460. signOutStatus: null,
  461. month: null,
  462. confirmStatus: null,
  463. };
  464. this.search();
  465. },
  466. getDate() {
  467. let obj = {
  468. search: this.searchForm.search,
  469. organIdList: this.searchForm.organIdList || null,
  470. groupType: this.searchForm.groupType || null,
  471. teacherId: this.searchForm.teacherId || null,
  472. signInStatus: this.searchForm.signInStatus || null,
  473. signOutStatus: this.searchForm.signOutStatus || null,
  474. month: this.searchForm.month || null,
  475. confirmStatus: this.searchForm.confirmStatus || null,
  476. page: this.rules.page,
  477. rows: this.rules.limit,
  478. };
  479. return obj;
  480. },
  481. openSalary() {
  482. this.$confirm("您确定开启课酬确认?", "提示", {
  483. confirmButtonText: "确定",
  484. cancelButtonText: "取消",
  485. type: "warning",
  486. }).then(() => {
  487. openSalaryConfirm({ month: this.searchForm.month }).then((res) => {
  488. if (res.code == 200) {
  489. this.$message.success("开启成功");
  490. this.getList();
  491. }
  492. });
  493. });
  494. },
  495. closeSalary() {
  496. this.$confirm("您确定关闭课酬确认?", "提示", {
  497. confirmButtonText: "确定",
  498. cancelButtonText: "取消",
  499. type: "warning",
  500. }).then(() => {
  501. closeSalaryConfirm({ month: this.searchForm.month }).then((res) => {
  502. if (res.code == 200) {
  503. this.$message.success("关闭成功");
  504. this.getList();
  505. }
  506. });
  507. });
  508. },
  509. onExport() {
  510. let url = "/api-web/export/isSettlementCourseSalarys";
  511. let obj = this.getDate();
  512. const options = {
  513. method: "get",
  514. headers: {
  515. Authorization: getToken(),
  516. },
  517. url,
  518. params: obj,
  519. responseType: "blob",
  520. };
  521. this.$confirm("您确定导出列表?", "提示", {
  522. confirmButtonText: "确定",
  523. cancelButtonText: "取消",
  524. type: "warning",
  525. })
  526. .then(() => {
  527. load.startLoading();
  528. axios(options)
  529. .then((res) => {
  530. let blob = new Blob([res.data], {
  531. // type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8',
  532. type: "application/vnd.ms-excel;charset=utf-8",
  533. // word文档为application/msword,pdf文档为application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
  534. });
  535. let text = new Response(blob).text();
  536. text.then((res) => {
  537. // 判断是否报错
  538. if (res.indexOf("code") != -1) {
  539. let json = JSON.parse(res);
  540. this.$message.error(json.msg);
  541. } else {
  542. let objectUrl = URL.createObjectURL(blob);
  543. let link = document.createElement("a");
  544. let nowTime = new Date();
  545. let ymd =
  546. nowTime.getFullYear() +
  547. "" +
  548. (nowTime.getMonth() + 1) +
  549. "" +
  550. nowTime.getDate() +
  551. "" +
  552. nowTime.getHours() +
  553. "" +
  554. nowTime.getMinutes();
  555. let fname = ymd + "课酬确认";
  556. link.href = objectUrl;
  557. link.setAttribute("download", fname);
  558. document.body.appendChild(link);
  559. link.click();
  560. }
  561. });
  562. load.endLoading();
  563. })
  564. .catch((error) => {
  565. this.$message.error("导出数据失败,请联系管理员");
  566. load.endLoading();
  567. });
  568. })
  569. .catch(() => {});
  570. },
  571. resetSalary(row) {
  572. let obj = {
  573. finalSalary: row.actualSalary, // 实发
  574. reduceSalary: row.reduceSalary, // 扣款
  575. actualSalary: row.expectSalary, // 应发
  576. courseScheduleId: row.courseScheduleId,
  577. memo: row.memo,
  578. teacherId: row.teacherId,
  579. };
  580. this.$set(this, "visibleForm", obj);
  581. console.log(this.visibleForm.finalSalary);
  582. this.dialogVisible = true;
  583. },
  584. subreset() {
  585. this.$refs["visibleForm"].validate((flag) => {
  586. if (flag) {
  587. let obj = {
  588. courseScheduleId: this.visibleForm.courseScheduleId,
  589. currentExpectSalary: this.visibleForm.actualSalary,
  590. currentReduceSalary: this.visibleForm.reduceSalary,
  591. memo: this.visibleForm.memo,
  592. teacherId: this.visibleForm.teacherId,
  593. };
  594. teacherSalaryModifyLog(obj).then((res) => {
  595. if (res.code == 200) {
  596. this.dialogVisible = false;
  597. this.$message.success("调整成功");
  598. this.getList();
  599. }
  600. });
  601. }
  602. });
  603. },
  604. },
  605. filters: {
  606. confirmFilter(val) {
  607. if (val) {
  608. let template = {
  609. 1: "待确认",
  610. 2: "已确认",
  611. 3: "已完成",
  612. };
  613. return template[val];
  614. }
  615. },
  616. },
  617. computed: {
  618. getActualsalary() {
  619. // 应发
  620. return this.visibleForm.actualSalary;
  621. },
  622. getReduceSalary() {
  623. // 扣款
  624. return this.visibleForm.reduceSalary;
  625. },
  626. },
  627. watch: {
  628. getActualsalary(val) {
  629. var number = numeral(val);
  630. this.visibleForm.finalSalary = Math.max(
  631. number.subtract(this.getReduceSalary).value(),
  632. 0
  633. );
  634. },
  635. getReduceSalary(val) {
  636. var number = numeral(this.getActualsalary);
  637. this.visibleForm.finalSalary = Math.max(number.subtract(val).value(), 0);
  638. },
  639. dialogVisible(val) {
  640. if (!val) {
  641. this.visibleForm = {
  642. expectSalary: null,
  643. reduceSalary: null,
  644. actualSalary: null,
  645. courseScheduleId: null,
  646. teacherId: null,
  647. memo: null,
  648. };
  649. this.$refs["visibleForm"].resetFields();
  650. }
  651. },
  652. },
  653. };
  654. </script>
  655. <style lang='scss' scoped>
  656. .red {
  657. color: red;
  658. }
  659. .visibleForm {
  660. /deep/.el-input__inner,
  661. /deep/.el-textarea__inner {
  662. width: 225px !important;
  663. }
  664. }
  665. /deep/.el-input-number .el-input__inner {
  666. text-align: left;
  667. }
  668. </style>