memberList.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. <!-- -->
  2. <template>
  3. <div class="m-container">
  4. <h2>
  5. <div class="squrt"></div>
  6. 乐团会员列表
  7. </h2>
  8. <div class="m-core">
  9. <save-form
  10. :inline="true"
  11. :model="searchForm"
  12. ref="searchForm"
  13. @submit="search"
  14. @reset="onReSet"
  15. >
  16. <el-form-item prop="search">
  17. <el-input
  18. v-model.trim="searchForm.search"
  19. clearable
  20. @keyup.enter.native="search"
  21. placeholder="乐团/学员名称编号"
  22. ></el-input>
  23. </el-form-item>
  24. <!-- <el-form-item>
  25. <el-input
  26. v-model.trim="searchForm.search"
  27. @keyup.enter.native="search"
  28. placeholder="学员姓名/编号"
  29. ></el-input>
  30. </el-form-item> -->
  31. <el-form-item prop="organId">
  32. <el-select
  33. class="multiple"
  34. filterable
  35. v-model.trim="searchForm.organId"
  36. clearable
  37. placeholder="请选择分部"
  38. >
  39. <el-option
  40. v-for="(item, index) in selects.branchs"
  41. :key="index"
  42. :label="item.name"
  43. :value="item.id"
  44. ></el-option>
  45. </el-select>
  46. </el-form-item>
  47. <el-form-item prop="hasMember">
  48. <el-select
  49. class="multiple"
  50. v-model.trim="searchForm.hasMember"
  51. placeholder="会员状态"
  52. >
  53. <el-option label="已过期" value="0"></el-option>
  54. <el-option label="即将过期" value="1"></el-option>
  55. <el-option label="待生效" value="2"></el-option>
  56. <el-option label="生效中" value="3"></el-option>
  57. </el-select>
  58. </el-form-item>
  59. <el-form-item prop="visitTime">
  60. <el-date-picker
  61. v-model.trim="searchForm.visitTime"
  62. style="width: 410px"
  63. type="daterange"
  64. value-format="yyyy-MM-dd"
  65. :picker-options="{
  66. firstDayOfWeek: 1,
  67. }"
  68. range-separator="至"
  69. start-placeholder="回访开始日期"
  70. end-placeholder="回访结束日期"
  71. ></el-date-picker>
  72. </el-form-item>
  73. <!-- <el-form-item prop="isActive">
  74. <el-select
  75. class="multiple"
  76. v-model.trim="searchForm.isActive"
  77. clearable
  78. placeholder="会员是否即将过期"
  79. >
  80. <el-option label="是" value="true"></el-option>
  81. <el-option label="否" value="false"></el-option>
  82. </el-select>
  83. </el-form-item> -->
  84. <el-form-item>
  85. <el-button native-type="submit" type="primary">搜索</el-button>
  86. <el-button native-type="reset" type="danger">重置</el-button>
  87. </el-form-item>
  88. </save-form>
  89. <div class="tableWrap">
  90. <el-table
  91. style="width: 100%"
  92. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  93. :data="tableList"
  94. >
  95. <el-table-column
  96. align="center"
  97. prop="userId"
  98. label="学员编号"
  99. ></el-table-column>
  100. <el-table-column
  101. align="center"
  102. prop="username"
  103. label="学员姓名"
  104. ></el-table-column>
  105. <el-table-column
  106. align="center"
  107. prop="phone"
  108. label="手机号"
  109. ></el-table-column>
  110. <el-table-column
  111. align="center"
  112. prop="organName"
  113. label="所属分部"
  114. ></el-table-column>
  115. <el-table-column
  116. align="center"
  117. prop="musicGroupName"
  118. label="所属乐团"
  119. >
  120. <template slot-scope="scope">
  121. <el-button
  122. type="text"
  123. @click="gotoMusic(scope.row.musicGroupName)"
  124. >
  125. {{ scope.row.musicGroupName }}
  126. </el-button>
  127. </template>
  128. </el-table-column>
  129. <el-table-column align="center" prop="studentId" label="会员状态">
  130. <template slot-scope="scope">
  131. <div>
  132. {{ scope.row.hasMember | hasMemberFilter }}
  133. </div>
  134. </template>
  135. </el-table-column>
  136. <el-table-column
  137. align="center"
  138. prop="memberDay"
  139. label="会员有效期剩余天数"
  140. >
  141. <template slot-scope="scope">
  142. <div>
  143. {{ scope.row.memberDay >= 0 ? scope.row.memberDay : 0 }}
  144. </div>
  145. </template>
  146. </el-table-column>
  147. <el-table-column align="center" prop="memberDay" label="回访日期">
  148. <template slot-scope="scope">
  149. <div>
  150. {{ scope.row.visitTime | dayjsFormat }}
  151. </div>
  152. </template>
  153. </el-table-column>
  154. <el-table-column align="center" prop="studentId" label="操作">
  155. <template slot-scope="scope">
  156. <div>
  157. <!-- addVisit -->
  158. <auth :auths="'visit/add/4465'">
  159. <el-button type="text" @click="addVisit(scope.row)"
  160. >新增回访</el-button
  161. >
  162. </auth>
  163. <auth :auths="'visit/queryPage'" v-if="scope.row.visitTime">
  164. <el-button type="text" @click="lookVisit(scope.row)"
  165. >查看回访</el-button
  166. >
  167. </auth>
  168. <auth :auths="'musicGroupQuit/directQuitMusicGroup4463'">
  169. <el-button type="text" @click="quitTeam(scope.row)"
  170. >退团退费</el-button
  171. >
  172. </auth>
  173. <auth :auths="'musicGroupQuit/directQuitMusicGroup4462'">
  174. <el-button type="text" @click="quieTeams(scope.row)"
  175. >退团</el-button
  176. >
  177. </auth>
  178. </div>
  179. </template>
  180. </el-table-column>
  181. </el-table>
  182. <pagination
  183. sync
  184. :total.sync="rules.total"
  185. :page.sync="rules.page"
  186. :limit.sync="rules.limit"
  187. :page-sizes="rules.page_size"
  188. @pagination="getList"
  189. />
  190. </div>
  191. </div>
  192. <!-- 退团弹窗 -->
  193. <el-dialog title="退团信息确认" width="660px" :visible.sync="quitVisible">
  194. <quiteTeam :quitForm="quitForm" :activeRow="activeRow" ref="quitForm" />
  195. <p style="color:red;paddingLeft:150px">退费金额暂不进入账户余额</p>
  196. <span slot="footer" class="dialog-footer question">
  197. <div>
  198. <el-popover placement="right" width="500" trigger="click">
  199. <div class="popoverWrap">
  200. <p>乐团退团退费规则:</p>
  201. <p>退还云教练费用:报名缴费时缴费的云教练费用</p>
  202. <p>退还课程费用:缴费总额-已结束课时单价之和</p>
  203. <p>退还乐器费用:报名缴费时缴纳的乐器费用(团购、租金)</p>
  204. <p>退还教辅费用:报名缴费时缴费的教辅费用</p>
  205. <p v-if="tenantId == 1">退还乐保费用:报名缴费时缴费的乐保费用</p>
  206. </div>
  207. <el-button
  208. type="text"
  209. icon="el-icon-question"
  210. slot="reference"
  211. style="color: red"
  212. >退团退费说明</el-button
  213. >
  214. </el-popover>
  215. </div>
  216. <div>
  217. <el-button @click="quitVisible = false">取 消</el-button>
  218. <el-button type="primary" @click="chioseType">确 定</el-button>
  219. </div>
  220. </span>
  221. </el-dialog>
  222. <!-- 新增回访 -->
  223. <el-dialog
  224. title="新增回访"
  225. width="500px"
  226. :visible.sync="visitVisible"
  227. append-to-body
  228. >
  229. <visit
  230. v-if="visitVisible && activeRow"
  231. :detail="activeRow"
  232. :username="activeRow.username"
  233. @close="visitVisible = false"
  234. @submited="getList"
  235. :useVisitType="['其它', '会员续费']"
  236. />
  237. </el-dialog>
  238. </div>
  239. </template>
  240. <script>
  241. import axios from "axios";
  242. import { getToken } from "@/utils/auth";
  243. import pagination from "@/components/Pagination/index";
  244. import quiteTeam from "@/views/teamDetail/components/modals/quite-team";
  245. import { StudentQuit } from "@/api/buildTeam";
  246. import load from "@/utils/loading";
  247. import { getMusicMemberList } from "./api";
  248. import visit from "@/views/withdrawal-application/modals/visit";
  249. import { getTimes } from "@/utils";
  250. export default {
  251. components: { pagination, quiteTeam, visit },
  252. data() {
  253. return {
  254. searchForm: {
  255. search: null,
  256. organId: null,
  257. hasMember: '0',
  258. visitTime: [],
  259. },
  260. tableList: [{}],
  261. organList: [],
  262. rules: {
  263. // 分页规则
  264. limit: 10, // 限制显示条数
  265. page: 1, // 当前页
  266. total: 0, // 总条数
  267. page_size: [10, 20, 40, 50], // 选择限制显示条数
  268. },
  269. quitForm: {
  270. // 退团信息确认
  271. studentName:null,
  272. musicGroupName:null,
  273. isRefundCourseFee: null,
  274. isRefundInstrumentFee: null,
  275. isRefundTeachingAssistantsFee: null,
  276. isMaintenanceFee: null,
  277. cloudTeacherAmount: null,
  278. isCloudTeacherAmount: null,
  279. isRefundMemberFee: null,
  280. maintenanceFee: 0,
  281. reason: "",
  282. },
  283. quitVisible: false,
  284. activeRow: null,
  285. visitVisible: false,
  286. tenantId:''
  287. };
  288. },
  289. //生命周期 - 创建完成(可以访问当前this实例)
  290. created() {},
  291. //生命周期 - 挂载完成(可以访问DOM元素)
  292. mounted() {
  293. // 获取分部
  294. this.tenantId = this.$helpers.tenantId;
  295. this.$store.dispatch("setBranchs");
  296. this.init();
  297. },
  298. methods: {
  299. init() {
  300. if (this.$route.query.hasMember) {
  301. this.$set(this.searchForm, "hasMember", this.$route.query.hasMember);
  302. }
  303. this.getList();
  304. },
  305. async getList() {
  306. // 设置时间
  307. let { visitTime, ...rest } = this.searchForm;
  308. try {
  309. const res = await getMusicMemberList({
  310. ...rest,
  311. ...getTimes(visitTime, ["visitStartTime", "visitEndTime"]),
  312. page: this.rules.page,
  313. rows: this.rules.limit,
  314. });
  315. this.tableList = res.data.rows;
  316. this.rules.total = res.data.total;
  317. } catch (e) {
  318. console.log(e);
  319. }
  320. },
  321. search() {
  322. this.rules.page = 1;
  323. this.getList();
  324. },
  325. onReSet() {
  326. this.$refs["searchForm"].resetFields();
  327. this.search()
  328. },
  329. quitTeam(row) {
  330. this.activeRow = row;
  331. this.quitVisible = true;
  332. this.quitForm.cloudTeacherAmount = row.cloudTeacherAmount;
  333. this.quitForm.studentName = row.username
  334. this.quitForm.musicGroupName = row.musicGroupName
  335. },
  336. quieTeams(row) {
  337. this.$prompt("请输入退团原因", "提示", {
  338. confirmButtonText: "确定",
  339. cancelButtonText: "取消",
  340. inputPattern: /\S/,
  341. inputErrorMessage: "请输入退团原因",
  342. type: "warning",
  343. })
  344. .then((val) => {
  345. // 发请求 退团
  346. StudentQuit({
  347. musicGroupId: row.musicGroupId,
  348. userId: row.userId,
  349. reason: val.value,
  350. isRefundCourseFee: false,
  351. isRefundInstrumentFee: false,
  352. isRefundTeachingAssistantsFee: false,
  353. isRefundMemberFee: false,
  354. }).then((res) => {
  355. this.quitForm = {
  356. // 退团信息确认
  357. isRefundCourseFee: null,
  358. isRefundInstrumentFee: null,
  359. isRefundTeachingAssistantsFee: null,
  360. isMaintenanceFee: null,
  361. cloudTeacherAmount: null,
  362. isCloudTeacherAmount: null,
  363. isRefundMemberFee: null,
  364. maintenanceFee: 0,
  365. reason: "",
  366. };
  367. if (res.code == 200) {
  368. this.$message.success("退团成功");
  369. this.getList();
  370. this.quitVisible = false;
  371. }
  372. });
  373. })
  374. .catch(() => {});
  375. },
  376. chioseType() {
  377. this.$refs["quitForm"].$refs["quitForm"].validate((res) => {
  378. if (res) {
  379. this.$confirm("确定退团?", "提示", {
  380. confirmButtonText: "确定",
  381. cancelButtonText: "取消",
  382. type: "warning",
  383. })
  384. .then(() => {
  385. let row = this.activeRow;
  386. let params = {
  387. musicGroupId: row.musicGroupId,
  388. userId: row.userId,
  389. reason: this.quitForm.reason,
  390. isRefundCourseFee: this.quitForm.isRefundCourseFee,
  391. isRefundInstrumentFee: this.quitForm.isRefundInstrumentFee,
  392. isRefundTeachingAssistantsFee:
  393. this.quitForm.isRefundTeachingAssistantsFee,
  394. maintenanceFee: this.quitForm.maintenanceFee,
  395. isRefundMemberFee: this.quitForm.isRefundMemberFee,
  396. };
  397. // 退还云教练费用
  398. if (this.quitForm.isRefundMemberFee) {
  399. params.cloudTeacherAmount = this.quitForm.cloudTeacherAmount;
  400. } else {
  401. params.cloudTeacherAmount = 0;
  402. }
  403. // 发请求 退团
  404. StudentQuit(params).then((res) => {
  405. this.quitForm = {
  406. // 退团信息确认
  407. isRefundCourseFee: null,
  408. isRefundInstrumentFee: null,
  409. isRefundTeachingAssistantsFee: null,
  410. isMaintenanceFee: null,
  411. cloudTeacherAmount: null,
  412. isCloudTeacherAmount: null,
  413. isRefundMemberFee: null,
  414. maintenanceFee: 0,
  415. reason: "",
  416. };
  417. if (res.code == 200) {
  418. this.$message.success("退团成功");
  419. this.getList();
  420. this.quitVisible = false;
  421. }
  422. });
  423. })
  424. .catch(() => {});
  425. } else {
  426. }
  427. });
  428. // row.typeVisible = false;
  429. },
  430. addVisit(row) {
  431. this.visitVisible = true;
  432. this.activeRow = row;
  433. },
  434. gotoMusic(str) {
  435. this.$router.push({ path: "/teamList", query: { search: str } });
  436. },
  437. lookVisit(row) {
  438. this.$router.push({
  439. path: "/studentManager/returnVisitList",
  440. query: { search: row.userId,typeList:['其它', '会员续费'] },
  441. });
  442. },
  443. },
  444. watch: {
  445. quitVisible(val) {
  446. if (!val) {
  447. this.quitForm = {
  448. // 退团信息确认
  449. isRefundCourseFee: null,
  450. isRefundInstrumentFee: null,
  451. isRefundTeachingAssistantsFee: null,
  452. isMaintenanceFee: null,
  453. cloudTeacherAmount: null,
  454. isCloudTeacherAmount: null,
  455. maintenanceFee: 0,
  456. reason: "",
  457. };
  458. this.$refs["quitForm"].$refs["quitForm"].resetFields();
  459. }
  460. },
  461. },
  462. filters:{
  463. hasMemberFilter(val){
  464. const arr = ['已过期','即将过期','待生效','生效中']
  465. return arr[val]
  466. }
  467. }
  468. };
  469. </script>
  470. <style lang='scss' scoped>
  471. </style>