vipList.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. <template>
  2. <div class="m-container">
  3. <h2>
  4. <div class="squrt"></div>VIP课列表
  5. </h2>
  6. <div class="newBand" v-permission="'/buildVip'" @click="gotoBuildVip">新建VIP课</div>
  7. <div class="newBand" v-permission="'export/vipGroupList'" @click="onVIPCourseExport">导出VIP课</div>
  8. <div class="m-core">
  9. <!-- 搜索类型 -->
  10. <el-form :inline="true" class="searchForm" v-model.trim="searchForm">
  11. <!-- 状态 指导老师 活动方案-->
  12. <el-form-item>
  13. <el-input v-model.trim="searchForm.search" @keyup.enter.native="search" placeholder="课程名称"></el-input>
  14. </el-form-item>
  15. <el-form-item prop="orgin">
  16. <el-select
  17. class="multiple"
  18. v-model.trim="searchForm.orgin"
  19. filterable
  20. clearable
  21. placeholder="请选择分部"
  22. >
  23. <el-option
  24. v-for="(item,index) in organList"
  25. :key="index"
  26. :label="item.name"
  27. :value="item.id"
  28. ></el-option>
  29. </el-select>
  30. </el-form-item>
  31. <!-- statusList -->
  32. <el-form-item prop="status">
  33. <el-select
  34. class="multiple"
  35. v-model.trim="searchForm.status"
  36. filterable
  37. clearable
  38. placeholder="请选课程状态"
  39. >
  40. <el-option
  41. v-for="(item,index) in statusList"
  42. :key="index"
  43. :label="item.lable"
  44. :value="item.value"
  45. ></el-option>
  46. </el-select>
  47. </el-form-item>
  48. <el-form-item>
  49. <el-select v-model.trim="searchForm.teacherId" clearable filterable placeholder="指导老师">
  50. <el-option
  51. v-for="(item,index) in teacherList"
  52. :key="index"
  53. :value="item.id"
  54. :label="item.realName"
  55. ></el-option>
  56. </el-select>
  57. </el-form-item>
  58. <el-form-item>
  59. <el-select v-model.trim="searchForm.activityId" clearable filterable placeholder="活动方案">
  60. <el-option
  61. v-for="(item,index) in activeList"
  62. :key="index"
  63. :value="item.id"
  64. :label="item.name"
  65. ></el-option>
  66. </el-select>
  67. </el-form-item>
  68. <el-form-item prop="status">
  69. <el-select
  70. class="multiple"
  71. v-model.trim="searchForm.hasEducationalTeacherId"
  72. filterable
  73. clearable
  74. placeholder="是否有教务老师"
  75. >
  76. <el-option label="是" value="true"></el-option>
  77. <el-option label="否" value="false"></el-option>
  78. </el-select>
  79. </el-form-item>
  80. <el-form-item>
  81. <el-button @click="search" type="danger">搜索</el-button>
  82. <el-button @click="onReSet" type="primary">重置</el-button>
  83. </el-form-item>
  84. </el-form>
  85. <!-- 查询列表 -->
  86. <!-- tab -->
  87. <div class="tableWrap">
  88. <el-table
  89. style="width: 100%"
  90. :header-cell-style="{background:'#EDEEF0',color:'#444'}"
  91. :data="tableData"
  92. >
  93. <el-table-column align="center" prop="id" label="课程组编号"></el-table-column>
  94. <el-table-column align="center" prop="name" label="课程名称"></el-table-column>
  95. <el-table-column align="center" prop="status" label="课程状态">
  96. <template slot-scope="scope">
  97. <div>{{ scope.row.status | formatterStatus}}</div>
  98. </template>
  99. </el-table-column>
  100. <el-table-column align="center" prop="userName" label="指导老师"></el-table-column>
  101. <el-table-column align="center" prop="educationalTeacherName" label="教务老师"></el-table-column>
  102. <el-table-column align="center" prop="studentNum" label="班级人数"></el-table-column>
  103. <el-table-column align="center" label="课程单价">
  104. <template slot-scope="scope">
  105. <div>
  106. <p>线上:{{scope.row.onlineClassesUnitPrice}}</p>
  107. <p>线下:{{scope.row.offlineClassesUnitPrice}}</p>
  108. </div>
  109. </template>
  110. </el-table-column>
  111. <el-table-column align="center" prop="vipGroupActivityName" label="活动方案"></el-table-column>
  112. <el-table-column align="center" label="当前课次">
  113. <template slot-scope="scope">
  114. <div>
  115. <p>{{scope.row.currentClassTimes + '/' + scope.row.totalClassTimes}}</p>
  116. </div>
  117. </template>
  118. </el-table-column>
  119. <el-table-column align="center" label="月均消耗">
  120. <template slot-scope="scope">{{ scope.row.monthConsumeRate }}%</template>
  121. </el-table-column>
  122. <el-table-column align="center" prop="paymentExpireDate" label="开课时间">
  123. <template slot-scope="scope">
  124. <div>
  125. <p>{{scope.row.courseStartDate | formatterTime}}</p>
  126. </div>
  127. </template>
  128. </el-table-column>
  129. <el-table-column align="center" prop="coursesExpireDate" label="结束时间">
  130. <template slot-scope="scope">
  131. <div>
  132. <p>{{scope.row.coursesExpireDate | formatterTime}}</p>
  133. </div>
  134. </template>
  135. </el-table-column>
  136. <el-table-column align="center" prop="createTime" label="申请时间">
  137. <template slot-scope="scope">
  138. <div>
  139. <p>{{scope.row.createTime | formatterTime}}</p>
  140. </div>
  141. </template>
  142. </el-table-column>
  143. <el-table-column align="center" width="150px" fixed="right" label="操作">
  144. <template slot-scope="scope">
  145. <div>
  146. <el-button
  147. type="text"
  148. v-permission="'/vipDetail'"
  149. @click="gotoVipDetail(scope.row)"
  150. >查看</el-button>
  151. <!--
  152. <el-button type="text">启动</el-button>-->
  153. <!-- <el-button type="text"
  154. v-if="scope.row.status <3"
  155. @click='closeVip(scope.row.id)'>关闭</el-button>-->
  156. <el-popover
  157. placement="top"
  158. width="160"
  159. v-permission="'vipGroupManage/stopVipGroup'"
  160. v-if="scope.row.status <3"
  161. :ref="scope.$index"
  162. >
  163. <p style="margin-bottom:10px;">确定停止该vip课?</p>
  164. <el-input v-model.trim="scope.row.stopReason" placeholder="请输入关闭原因"></el-input>
  165. <div style="text-align: right; margin-top: 20px">
  166. <el-button
  167. size="mini"
  168. type="text"
  169. @click="scope._self.$refs[scope.$index].doClose()"
  170. >取消</el-button>
  171. <el-button type="primary" size="mini" @click="closeVip(scope)">确定</el-button>
  172. </div>
  173. <el-button type="text" slot="reference">停止</el-button>
  174. </el-popover>
  175. <el-button
  176. type="text"
  177. v-if="scope.row.status > 1&&scope.row.status != 3"
  178. v-permission="'/vipReset'"
  179. @click="resetVip(scope.row)"
  180. >修改</el-button>
  181. </div>
  182. </template>
  183. </el-table-column>
  184. </el-table>
  185. <!-- 分页器 -->
  186. <pagination
  187. :total="rules.total"
  188. :page.sync="rules.page"
  189. :limit.sync="rules.limit"
  190. :page-sizes="rules.page_size"
  191. @pagination="getList"
  192. />
  193. </div>
  194. </div>
  195. </div>
  196. </template>
  197. <script>
  198. import pagination from "@/components/Pagination/index";
  199. import {
  200. getVipList,
  201. vipGroupActivity,
  202. closeVip,
  203. getVipGroupDetail
  204. } from "@/api/vipSeting";
  205. import { getTeacher, getEmployeeOrgan } from "@/api/buildTeam";
  206. import store from "@/store";
  207. import axios from "axios";
  208. import { getToken } from "@/utils/auth";
  209. export default {
  210. components: { pagination },
  211. name: "vipList",
  212. data() {
  213. return {
  214. organId: null,
  215. searchForm: {
  216. teacherId: null,
  217. activityId: null,
  218. search: null,
  219. orgin: null,
  220. status: null,
  221. hasEducationalTeacherId:null
  222. },
  223. teacherList: [],
  224. activeList: [],
  225. tableData: [],
  226. organList: [],
  227. rules: {
  228. // 分页规则
  229. limit: 10, // 限制显示条数
  230. page: 1, // 当前页
  231. total: 0, // 总条数
  232. page_size: [10, 20, 40, 50] // 选择限制显示条数
  233. },
  234. statusList: [
  235. { lable: "未开始", value: "0" },
  236. { lable: "报名中", value: "1" },
  237. { lable: "报名结束", value: "5" },
  238. { lable: "进行中", value: "2" },
  239. { lable: "已结束", value: "4" },
  240. { lable: "取消", value: "3" },
  241. { lable: "暂停", value: "6" }
  242. ]
  243. };
  244. },
  245. created() {
  246. if (this.$route.query.searchForm) {
  247. this.$route.query.searchForm instanceof Object
  248. ? (this.searchForm = this.$route.query.searchForm)
  249. : (this.searchForm = JSON.parse(this.$route.query.searchForm));
  250. }
  251. if (this.$route.query.rules) {
  252. this.$route.query.rules instanceof Object
  253. ? (this.rules = this.$route.query.rules)
  254. : (this.rules = JSON.parse(this.$route.query.rules));
  255. }
  256. },
  257. mounted() {
  258. this.init();
  259. },
  260. activated() {
  261. this.init();
  262. },
  263. methods: {
  264. init() {
  265. getEmployeeOrgan().then(res => {
  266. if (res.code == 200) {
  267. this.organList = res.data;
  268. }
  269. });
  270. // <!-- 状态 指导老师 活动方案-->
  271. getTeacher({ organId: this.organId }).then(res => {
  272. if (res.code == 200) {
  273. this.teacherList = res.data;
  274. }
  275. });
  276. // 获取活动方案
  277. vipGroupActivity({ organId: this.organId }).then(res => {
  278. if (res.code == 200) {
  279. this.activeList = res.data.rows;
  280. }
  281. });
  282. this.getList();
  283. },
  284. search() {
  285. this.rules.page = 1;
  286. this.getList();
  287. },
  288. onReSet() {
  289. this.searchForm = {
  290. teacherId: null,
  291. activityId: null,
  292. search: null,
  293. orgin: null,
  294. status: null
  295. };
  296. this.getList();
  297. },
  298. getList() {
  299. let params = this.searchForm;
  300. params.page = this.rules.page;
  301. params.rows = this.rules.limit;
  302. params.hasEducationalTeacherId = this.searchForm.hasEducationalTeacherId || null
  303. params.organId = this.searchForm.orgin || null;
  304. params.status = this.searchForm.status || null;
  305. getVipList(params).then(res => {
  306. if (res.code == 200) {
  307. this.tableData= []
  308. setTimeout(() => {
  309. this.tableData = res.data.rows;
  310. }, 50);
  311. this.rules.total = res.data.total;
  312. }
  313. });
  314. },
  315. // 跳转到vip详情
  316. gotoVipDetail(row) {
  317. let rules = JSON.stringify(this.rules);
  318. let searchForm = JSON.stringify(this.searchForm);
  319. let id = row.id;
  320. let name = row.name;
  321. this.$router.push({
  322. path: "/business/vipDetail",
  323. query: { id, name, rules, searchForm }
  324. });
  325. },
  326. closeVip(scope) {
  327. let id = scope.row.id;
  328. closeVip({ vipGroupId: id, stopReason: scope.row.stopReason }).then(
  329. res => {
  330. if (res.code == 200) {
  331. this.$message.success("停止课程成功");
  332. scope._self.$refs[scope.$index].doClose();
  333. this.getList();
  334. }
  335. }
  336. );
  337. },
  338. gotoBuildVip() {
  339. let rules = JSON.stringify(this.rules);
  340. let searchForm = JSON.stringify(this.searchForm);
  341. this.$router.push({
  342. path: "/business/buildVip",
  343. query: { rules, searchForm }
  344. });
  345. },
  346. onVIPCourseExport() {
  347. // 导出VIP课
  348. let searchForm = this.searchForm;
  349. let data = {
  350. teacherId: searchForm.teacherId || null,
  351. activityId: searchForm.activityId || null,
  352. organId: searchForm.orgin || null,
  353. status: searchForm.status || null,
  354. search: searchForm.search || null
  355. };
  356. let url = "/api-web/export/vipGroupList";
  357. const options = {
  358. method: "get",
  359. headers: {
  360. Authorization: getToken()
  361. },
  362. params: data,
  363. url,
  364. responseType: "blob"
  365. };
  366. this.$confirm("您确定导出报表", "提示", {
  367. confirmButtonText: "确定",
  368. cancelButtonText: "取消",
  369. type: "warning"
  370. })
  371. .then(() => {
  372. axios(options).then(res => {
  373. let blob = new Blob([res.data], {
  374. // type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
  375. type: "application/vnd.ms-excel;charset=utf-8"
  376. //word文档为application/msword,pdf文档为application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
  377. });
  378. let objectUrl = URL.createObjectURL(blob);
  379. let link = document.createElement("a");
  380. let fname = "VIP列表" + new Date().getTime(); //下载文件的名字
  381. link.href = objectUrl;
  382. link.setAttribute("download", fname);
  383. document.body.appendChild(link);
  384. link.click();
  385. });
  386. })
  387. .catch(() => {});
  388. },
  389. // 修改vip
  390. resetVip(row) {
  391. let id = row.id;
  392. let educationalTeacherId = row.educationalTeacherId;
  393. let rules = JSON.stringify(this.rules);
  394. let searchForm = JSON.stringify(this.searchForm);
  395. this.$router.push({
  396. path: "/business/vipReset",
  397. query: { id,educationalTeacherId, rules, searchForm }
  398. });
  399. }
  400. },
  401. filters: {
  402. formatterTime(val) {
  403. let result;
  404. if (val) {
  405. result = val.split(" ")[0];
  406. } else {
  407. result = "";
  408. }
  409. return result;
  410. },
  411. formatterStatus(val) {
  412. let arr = [
  413. "未开始",
  414. "报名中",
  415. "进行中",
  416. "取消",
  417. "已结束",
  418. "报名结束",
  419. "暂停"
  420. ];
  421. return arr[val];
  422. }
  423. }
  424. };
  425. </script>
  426. <style lang="scss" scoped>
  427. .m-container {
  428. box-sizing: border-box;
  429. background-color: #fff;
  430. // padding: 18px 95px 55px 60px;
  431. }
  432. .newBand {
  433. display: inline-block;
  434. }
  435. </style>