index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. <template>
  2. <div class="m-container">
  3. <h2>
  4. <div class="squrt"></div>
  5. 退团申请
  6. <filter-search
  7. @reload="reloadSearch"
  8. :keys="['visitFlag']"
  9. :moreKeys="['organId']"
  10. />
  11. </h2>
  12. <div class="m-core">
  13. <save-form
  14. :inline="true"
  15. @submit="submit"
  16. @reset="onReSet"
  17. ref="searchForm"
  18. :model.sync="searchForm"
  19. >
  20. <el-form-item>
  21. <el-input
  22. v-model.trim="searchForm.search"
  23. clearable
  24. placeholder="学员(乐团)编号、名称"
  25. ></el-input>
  26. </el-form-item>
  27. <el-form-item prop="organId">
  28. <el-select
  29. class="multiple"
  30. style="width: 180px !important"
  31. v-model.trim="searchForm.organId"
  32. filterable
  33. clearable
  34. placeholder="请选择分部"
  35. >
  36. <el-option
  37. v-for="(item, index) in selects.branchs"
  38. :key="index"
  39. :label="item.name"
  40. :value="item.id"
  41. ></el-option>
  42. </el-select>
  43. </el-form-item>
  44. <el-form-item>
  45. <el-select
  46. v-model="searchForm.status"
  47. clearable
  48. placeholder="请选择状态"
  49. >
  50. <el-option
  51. v-for="(item, key) in withdrawalStatus"
  52. :key="key"
  53. :label="item"
  54. :value="key"
  55. ></el-option>
  56. </el-select>
  57. </el-form-item>
  58. <el-form-item>
  59. <el-select
  60. v-model="searchForm.currentApproveRole"
  61. clearable
  62. placeholder="请选择角色"
  63. >
  64. <el-option label="分部经理" value="3"></el-option>
  65. <el-option label="乐团主管" value="4"></el-option>
  66. </el-select>
  67. </el-form-item>
  68. <el-form-item>
  69. <el-button native-type="submit" type="danger">搜索</el-button>
  70. <el-button native-type="reset" type="primary">重置</el-button>
  71. <el-button
  72. @click="onExport"
  73. type="primary"
  74. v-permission="'export/musicGroupQuit'"
  75. >导出</el-button
  76. >
  77. </el-form-item>
  78. </save-form>
  79. <div class="btnList">
  80. <auth :auths="['musicGroupQuit/batchQuitMusicGroup']">
  81. <el-button type="primary" @click="quiteTeamAll">批量处理</el-button>
  82. </auth>
  83. </div>
  84. <el-table
  85. :data="list"
  86. style="width: 100%"
  87. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  88. @selection-change="handleSelectionChange"
  89. >
  90. <el-table-column
  91. type="selection"
  92. width="55"
  93. :selectable="checkSeleabled"
  94. >
  95. </el-table-column>
  96. <el-table-column prop="userId" label="学员编号">
  97. <copy-text slot-scope="scope">{{ scope.row.userId }}</copy-text>
  98. </el-table-column>
  99. <el-table-column prop="userId" label="学员姓名">
  100. <copy-text slot-scope="scope">{{
  101. scope.row.user.username
  102. }}</copy-text>
  103. </el-table-column>
  104. <el-table-column prop="organName" label="所属分部">
  105. <div slot-scope="scope">{{ scope.row.musicGroup.organName }}</div>
  106. </el-table-column>
  107. <el-table-column prop="musicGroupId" label="所属乐团">
  108. <copy-text slot-scope="scope">{{
  109. scope.row.musicGroup.name
  110. }}</copy-text>
  111. </el-table-column>
  112. <el-table-column prop="createTime" label="申请时间">
  113. <template slot-scope="scope">
  114. <div>
  115. {{ scope.row.createTime | dateForMinFormat }}
  116. </div>
  117. </template>
  118. </el-table-column>
  119. <el-table-column prop="applyUserName" label="申请人"></el-table-column>
  120. <el-table-column prop="createTime" label="退费金额">
  121. <template slot-scope="scope">
  122. <div>
  123. <p v-if="!scope.row.returnTotalFee">--</p>
  124. <p v-else>
  125. {{ scope.row.returnTotalFee | moneyFormat }}
  126. </p>
  127. </div>
  128. </template>
  129. </el-table-column>
  130. <el-table-column prop="userComment" label="退团原因">
  131. <overflow-text
  132. width="100%"
  133. slot-scope="scope"
  134. :text="scope.row.userComment"
  135. ></overflow-text>
  136. </el-table-column>
  137. <el-table-column label="状态">
  138. <template slot-scope="scope">
  139. <div>
  140. {{ scope.row.status | withdrawalStatus }}
  141. <span v-if="scope.row.status == 'PROCESSING'"
  142. >({{
  143. scope.row.currentApproveRole == 3 ? "分部经理" : "乐团主管"
  144. }})</span
  145. >
  146. </div>
  147. </template>
  148. </el-table-column>
  149. <el-table-column
  150. align="center"
  151. fixed="right"
  152. width="200px;"
  153. label="操作"
  154. v-if="
  155. permission('musicGroupQuit/quitMusicGroup/quit') ||
  156. permission('musicGroupQuit/quitMusicGroup/quit-only') ||
  157. permission('visit/add/tuituanliebiao')
  158. "
  159. >
  160. <template slot-scope="scope">
  161. <div>
  162. <el-button
  163. type="text"
  164. v-if="permission('musicGroupQuit/quitMusicGroup/quit')"
  165. :disabled="
  166. scope.row.status != 'PROCESSING' ||
  167. scope.row.status == 'DENIED' ||
  168. scope.row.status == 'CANCELED' ||
  169. (scope.row.status == 'PROCESSING' &&
  170. isManage == 'manage' &&
  171. scope.row.currentApproveRole == '4') ||
  172. (scope.row.status == 'PROCESSING' &&
  173. !isManage &&
  174. scope.row.currentApproveRole == '3')
  175. "
  176. @click="quieTeamMask(scope.row)"
  177. >立即处理</el-button
  178. >
  179. <el-button
  180. type="text"
  181. v-if="permission('musicGroupQuit/quitMusicGroup/quit')"
  182. :disabled="
  183. !(
  184. scope.row.status != 'PROCESSING' ||
  185. scope.row.status == 'DENIED' ||
  186. scope.row.status == 'CANCELED' ||
  187. (scope.row.status == 'PROCESSING' &&
  188. isManage == 'manage' &&
  189. scope.row.currentApproveRole == '4') ||
  190. (scope.row.status == 'PROCESSING' &&
  191. !isManage &&
  192. scope.row.currentApproveRole == '3')
  193. )
  194. "
  195. @click="quieTeamMask(scope.row, 'look')"
  196. >查看</el-button
  197. >
  198. <!-- <el-button
  199. type="text"
  200. v-if="permission('musicGroupQuit/quitMusicGroup/quit-only')"
  201. :disabled="scope.row.status != 'PROCESSING'"
  202. @click="quieTeam(scope.row)"
  203. >退团</el-button> -->
  204. <el-button
  205. type="text"
  206. v-if="permission('visit/add/tuituanliebiao')"
  207. @click="addVisit(scope.row)"
  208. >新增回访</el-button
  209. >
  210. </div>
  211. </template>
  212. </el-table-column>
  213. </el-table>
  214. <pagination
  215. sync
  216. :total.sync="rules.total"
  217. :page.sync="rules.page"
  218. :limit.sync="rules.limit"
  219. :page-sizes="rules.page_size"
  220. @pagination="FetchList"
  221. />
  222. </div>
  223. <el-dialog
  224. :title="isDisabled ? '查看' : '立即处理'"
  225. width="700px"
  226. :visible.sync="quitVisible"
  227. >
  228. <quitModal
  229. v-if="quitVisible"
  230. :quitForm="quitForm"
  231. @close="quitVisible = false"
  232. @submited="FetchList"
  233. :isDisabled="isDisabled"
  234. ref="musicForm"
  235. />
  236. <p style="color: red; paddingleft: 150px">退费金额暂不进入账户余额</p>
  237. <span slot="footer" class="dialog-footer question">
  238. <div>
  239. <el-popover placement="right" width="500" trigger="click">
  240. <div class="popoverWrap">
  241. <p>乐团退团退费规则:</p>
  242. <p>退还乐器练习云教练费用:报名缴费时缴费的乐器练习云教练费用</p>
  243. <p>退还课程费用:缴费总额-已结束课时单价之和</p>
  244. <p>退还乐器费用:报名缴费时缴纳的乐器费用(团购、租金)</p>
  245. <p>退还教辅费用:报名缴费时缴费的教辅费用</p>
  246. <p>退还乐保费用:报名缴费时缴费的乐保费用</p>
  247. </div>
  248. <el-button
  249. type="text"
  250. icon="el-icon-question"
  251. slot="reference"
  252. style="color: red"
  253. >退团退费说明</el-button
  254. >
  255. </el-popover>
  256. </div>
  257. <div v-if="!isDisabled">
  258. <el-button
  259. type="primary"
  260. v-permission="'musicGroupQuit/quitMusicGroup'"
  261. v-if="!isManage"
  262. @click="submitInfo('PROCESSING')"
  263. >提交审核</el-button
  264. >
  265. <el-button
  266. v-else
  267. type="primary"
  268. v-permission="'musicGroupQuit/quitMusicGroup'"
  269. @click="submitInfo('APPROVED')"
  270. >同意</el-button
  271. >
  272. <el-button
  273. type="danger"
  274. v-permission="'musicGroupQuit/quitMusicGroup'"
  275. @click="submitInfo('DENIED')"
  276. >拒绝</el-button
  277. >
  278. </div>
  279. </span>
  280. </el-dialog>
  281. <!-- <el-dialog title="退团" width="500px" :visible.sync="quitOnlyVisible">
  282. <quitOnlyModal
  283. v-if="quitOnlyVisible && detail"
  284. :detail="detail"
  285. @close="quitOnlyVisible = false"
  286. @submited="FetchList"
  287. />
  288. </el-dialog> -->
  289. <el-dialog title="新增回访" width="500px" :visible.sync="visitVisible">
  290. <visit
  291. v-if="visitVisible && detail"
  292. :detail="detail"
  293. @close="visitVisible = false"
  294. @submited="FetchList"
  295. />
  296. </el-dialog>
  297. </div>
  298. </template>
  299. <script>
  300. import pagination from "@/components/Pagination/index";
  301. import { permission } from "@/utils/directivePage";
  302. import quitModal from "@/views/teamDetail/components/modals/quite-team";
  303. import quitOnlyModal from "./modals/quitOnly";
  304. import visit from "./modals/visit";
  305. import { Export } from "@/utils/downLoadFile";
  306. import { quitMusicGroup } from "@/api/journal";
  307. import qs from "qs";
  308. import { musicGroupQuitQeryPage, batchQuitMusicGroup } from "./api";
  309. import cleanDeep from "clean-deep";
  310. import { musicGroupQuit } from "@/api/journal";
  311. import { withdrawalStatus } from "@/constant";
  312. const initSearch = {
  313. search: "",
  314. status: null,
  315. organId: "",
  316. };
  317. export default {
  318. components: { pagination, quitModal, quitOnlyModal, visit },
  319. data() {
  320. return {
  321. withdrawalStatus,
  322. quitVisible: false,
  323. quitOnlyVisible: false,
  324. visitVisible: false,
  325. detail: null,
  326. list: [],
  327. searchForm: {
  328. ...initSearch,
  329. },
  330. rules: {
  331. // 分页规则
  332. limit: 10, // 限制显示条数
  333. page: 1, // 当前页
  334. total: 0, // 总条数
  335. page_size: [10, 20, 40, 50], // 选择限制显示条数
  336. },
  337. quitForm: {
  338. // 退团信息确认
  339. isRefundCourseFee: null,
  340. isRefundInstrumentFee: null,
  341. isRefundTeachingAssistantsFee: null,
  342. reason: "",
  343. courseViewType: null,
  344. hasMaintenance: null,
  345. studentName: null,
  346. musicGroupName: null,
  347. isVisit: false,
  348. userComment: null,
  349. },
  350. isManage: false,
  351. isDisabled: false,
  352. multipleSelection: [],
  353. };
  354. },
  355. async mounted() {
  356. let isSuperAdmin = this.$store.getters.isSuperAdmin;
  357. let roles = this.$store.getters.roles;
  358. await this.$store.dispatch("setBranchs");
  359. if (isSuperAdmin) {
  360. this.isManage = "super";
  361. } else {
  362. if (roles.indexOf(3) != -1) {
  363. this.isManage = "manage";
  364. } else {
  365. this.isManage = false;
  366. }
  367. }
  368. if (roles.indexOf(3) != -1 && roles.indexOf(4) != -1) {
  369. this.isManage = "super";
  370. }
  371. this.FetchList();
  372. },
  373. methods: {
  374. permission,
  375. reloadSearch() {
  376. this.rules.page = 1;
  377. this.FetchList();
  378. },
  379. submit() {
  380. this.rules.page = 1;
  381. this.FetchList();
  382. },
  383. onReSet() {
  384. this.searchForm = { ...initSearch };
  385. this.submit();
  386. },
  387. async quieTeamMask(row, look) {
  388. await musicGroupQuit({ id: row.id }).then((res) => {
  389. if (res.code == 200) {
  390. if (look == "look") {
  391. this.isDisabled = true;
  392. } else {
  393. this.isDisabled = false;
  394. }
  395. this.musicForm = res.data;
  396. this.activeRow = { ...row, ...res.data.returnFeeDto };
  397. this.quitForm.courseViewType = res.data.musicGroup.courseViewType;
  398. this.quitForm.userComment = res.data.userComment;
  399. this.quitForm.isVisit = res.data.isVisit;
  400. this.quitForm.visitTime = res.data.visitTime;
  401. this.quitForm.studentName = res.data.user?.username;
  402. this.quitForm.musicGroupName = res.data.musicGroup?.name;
  403. this.quitForm.hasMaintenance = res.data.hasMaintenance;
  404. this.quitForm.reason = res.data.reason;
  405. this.quitForm.id = res.data.id;
  406. this.quitForm = { ...this.quitForm, ...res.data.returnFeeDto };
  407. this.quitVisible = true;
  408. } else {
  409. this.$message.error(res.msg);
  410. }
  411. });
  412. // this.detail = row;
  413. },
  414. quieTeam(row) {
  415. this.quitOnlyVisible = true;
  416. this.detail = row;
  417. },
  418. addVisit(row) {
  419. this.visitVisible = true;
  420. this.detail = row;
  421. },
  422. async FetchList() {
  423. try {
  424. const res = await musicGroupQuitQeryPage({
  425. page: this.rules.page,
  426. rows: this.rules.limit,
  427. visitFlag: this.$route.query.visitFlag,
  428. ...this.searchForm,
  429. });
  430. this.rules.total = res.data.total;
  431. this.list = res.data.rows;
  432. } catch (error) {}
  433. },
  434. onExport() {
  435. const { ...rest } = this.searchForm;
  436. Export(
  437. this,
  438. {
  439. url: "/api-web/export/musicGroupQuit",
  440. fileName: "退团申请.xls",
  441. method: "post",
  442. params: qs.stringify({
  443. visitFlag: this.$route.query.visitFlag,
  444. ...rest,
  445. }),
  446. },
  447. "您确定导出退团申请列表?"
  448. );
  449. },
  450. submitInfo(status) {
  451. this.$confirm("确定此操作吗?", "提示", {
  452. confirmButtonText: "确定",
  453. cancelButtonText: "取消",
  454. type: "warning",
  455. })
  456. .then(async () => {
  457. let query = this.quitForm;
  458. query.status = status;
  459. query.returnFeeDto = {
  460. accessoriesFee: query.accessoriesFee,
  461. courseFee: query.courseFee,
  462. isReturnAccessoriesFee: query.isReturnAccessoriesFee,
  463. isReturnCourseFee: query.isReturnCourseFee,
  464. isReturnMaintenanceFee: query.isReturnMaintenanceFee,
  465. isReturnMemberFee: query.isReturnMemberFee,
  466. isReturnMusicalFee: query.isReturnMusicalFee,
  467. maintenanceFee: query.maintenanceFee,
  468. memberFee: query.memberFee,
  469. musicalFee: query.musicalFee,
  470. };
  471. await quitMusicGroup(cleanDeep(query)).then((res) => {
  472. this.$message.success("处理成功");
  473. this.activeRow = null;
  474. if (this.$refs["musicForm"].$refs.quitForm) {
  475. this.$refs["musicForm"].$refs.quitForm.resetFields();
  476. }
  477. this.quitVisible = false;
  478. this.FetchList();
  479. });
  480. })
  481. .catch((e) => {
  482. console.log(e);
  483. });
  484. // 乐团主管这里
  485. },
  486. handleSelectionChange(val) {
  487. this.multipleSelection = val;
  488. },
  489. quiteTeamAll() {
  490. if (this.multipleSelection.length < 1) {
  491. this.$message.error("请至少选择一名学员");
  492. return;
  493. }
  494. let str = "";
  495. this.multipleSelection.forEach((stu) => {
  496. console.log(stu);
  497. str += stu.user.username + ",";
  498. });
  499. str += "的退团申请将批量处理";
  500. this.$prompt(str, "提示", {
  501. distinguishCancelAndClose: true,
  502. confirmButtonText: "同意",
  503. cancelButtonText: "拒绝",
  504. confirmButtonClass: "el-button--primary",
  505. cancelButtonClass: "el-button--danger",
  506. closeOnClickModal: false,
  507. inputPattern: /\S/,
  508. inputType: "textarea",
  509. inputErrorMessage: "请输入审批理由",
  510. inputPlaceholder: "请输入审批理由",
  511. beforeClose: async (val, instance, done) => {
  512. if (val == "confirm") {
  513. // reason
  514. let objList = this.multipleSelection.map((stu) => {
  515. return {
  516. id: stu.id,
  517. status: "APPROVED",
  518. reason: instance.inputValue,
  519. };
  520. });
  521. try {
  522. const res = await batchQuitMusicGroup(objList);
  523. this.$message.success("审批成功");
  524. done();
  525. } catch (e) {
  526. console.log(e);
  527. }
  528. } else if (val == "cancel") {
  529. instance.validate();
  530. let objList = this.multipleSelection.map((stu) => {
  531. return {
  532. id: stu.id,
  533. status: "DENIED",
  534. reason: instance.inputValue,
  535. };
  536. });
  537. try {
  538. const res = await batchQuitMusicGroup(objList);
  539. this.$message.success("审批成功");
  540. done();
  541. } catch (e) {
  542. console.log(e);
  543. }
  544. } else {
  545. done();
  546. }
  547. },
  548. })
  549. .then(() => {
  550. // 同意
  551. })
  552. .catch((msg) => {
  553. // close,cancel
  554. console.log(msg);
  555. });
  556. },
  557. checkSeleabled(row) {
  558. if (row.status == "PROCESSING"&&row.currentApproveRole=='3') {
  559. return 1;
  560. } else {
  561. return 0;
  562. }
  563. },
  564. },
  565. };
  566. </script>
  567. <style lang="scss" scoped>
  568. .dialog-footer.question {
  569. display: flex;
  570. flex-direction: row;
  571. justify-content: space-between;
  572. }
  573. .btnList {
  574. margin-bottom: 20px;
  575. }
  576. .confirmButton {
  577. color: #fff;
  578. background-color: #f56c6c;
  579. border-color: #f56c6c;
  580. }
  581. .cancelButton {
  582. color: #fff;
  583. background-color: #14928a;
  584. border-color: #14928a;
  585. }
  586. </style>