forecastName.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. <template>
  2. <div class="forecastName">
  3. <!-- <h2> m-container
  4. <el-page-header @back="onCancel" :content="teamName"></el-page-header>
  5. </h2> -->
  6. <!-- <p style="margin-bottom: 15px; font-size: 18px; font-weight: 400">
  7. 缴费截止时间:{{ '2020-12-12' | formatTimer }}
  8. </p> -->
  9. <div class="btnList">
  10. <auth :auths="['musicGroup/sendParentMeetingNotice']" v-if="isedit || $route.query.team_status=='PRE_BUILD_FEE'">
  11. <el-button type="primary" @click="extendPaymentStatus = true"
  12. >预报名家长会通知</el-button
  13. >
  14. </auth>
  15. <auth :auths="['forecastName/forecastLink']" v-if="isedit">
  16. <el-button type="primary" @click="codeStatus = true"
  17. >预报名问卷</el-button
  18. >
  19. </auth>
  20. <auth :auths="['studentRegistration/preRegisterExport']">
  21. <el-button type="primary" @click="downloadFile"
  22. >预报名信息导出</el-button
  23. >
  24. </auth>
  25. <auth :auths="['studentRegistration/queryPreApplySubjectList']">
  26. <el-button type="primary" @click="subjectVisible = true"
  27. >意向统计</el-button
  28. >
  29. </auth>
  30. <auth :auths="['musicGroup/finishPreApply']">
  31. <el-button type="primary" @click="onPaymentGroup" v-if="isedit"
  32. >乐团缴费</el-button
  33. >
  34. </auth>
  35. <auth :auths="['musicGroup/finishPreApply/item']" v-if="isedit">
  36. <el-button type="primary" @click="onPaymentGroup(1)"
  37. >特色乐团缴费</el-button
  38. >
  39. </auth>
  40. <el-button type="primary" @click="codedetailStatus = true" v-if="isedit"
  41. >预报名H5统计</el-button
  42. >
  43. </div>
  44. <div class="m-core">
  45. <save-form
  46. :inline="true"
  47. @reset="onReSet"
  48. @submit="search"
  49. :model="searchForm"
  50. save-key="/forecastName"
  51. ref="searchForm"
  52. >
  53. <el-form-item prop="name">
  54. <el-input
  55. v-model.trim="searchForm.name"
  56. clearable
  57. @keyup.enter.native="
  58. (e) => {
  59. e.target.blur();
  60. $refs.searchForm.save();
  61. search();
  62. }
  63. "
  64. placeholder="学生编号/姓名/手机号"
  65. ></el-input>
  66. </el-form-item>
  67. <el-form-item prop="isAllowAdjust">
  68. <el-select
  69. v-model.trim="searchForm.isAllowAdjust"
  70. clearable
  71. placeholder="是否允许调剂"
  72. >
  73. <el-option label="是" :value="1"></el-option>
  74. <el-option label="否" :value="0"></el-option>
  75. </el-select>
  76. </el-form-item>
  77. <el-form-item prop="teacherRecommandSubjectId">
  78. <el-select
  79. clearable
  80. v-model="searchForm.teacherRecommandSubjectId"
  81. placeholder="老师推荐声部"
  82. >
  83. <el-option
  84. v-for="item in subjectList"
  85. :value="item.id"
  86. :label="item.name"
  87. :key="item.id"
  88. ></el-option>
  89. </el-select>
  90. </el-form-item>
  91. <el-form-item prop="selectionSubjectId">
  92. <el-select
  93. clearable
  94. v-model="searchForm.selectionSubjectId"
  95. placeholder="选报声部"
  96. >
  97. <el-option
  98. v-for="item in selects.subjects"
  99. :value="item.id"
  100. :label="item.name"
  101. :key="item.id"
  102. ></el-option>
  103. </el-select>
  104. </el-form-item>
  105. <el-form-item prop="subjectId">
  106. <el-select
  107. clearable
  108. v-model="searchForm.subjectId"
  109. placeholder="所选专业"
  110. >
  111. <el-option
  112. v-for="item in selects.subjects"
  113. :value="item.id"
  114. :label="item.name"
  115. :key="item.id"
  116. ></el-option>
  117. </el-select>
  118. </el-form-item>
  119. <!-- kitPurchaseMethod -->
  120. <el-form-item prop="kitPurchaseMethod">
  121. <el-select
  122. v-model.trim="searchForm.kitPurchaseMethod"
  123. clearable
  124. placeholder="乐器准备方式"
  125. >
  126. <el-option label="团购" value="GROUP"></el-option>
  127. <el-option label="自备" value="OWNED"></el-option>
  128. </el-select>
  129. </el-form-item>
  130. <el-form-item prop="cloudTeacherMethod">
  131. <el-select
  132. v-model.trim="searchForm.cloudTeacherMethod"
  133. clearable
  134. placeholder="系统意向"
  135. >
  136. <el-option label="团购" value="GROUP"></el-option>
  137. <el-option label="自备" value="OWNED"></el-option>
  138. </el-select>
  139. </el-form-item>
  140. <el-form-item>
  141. <el-button type="danger" native-type="seach">搜索</el-button>
  142. <el-button native-type="reset" type="primary">重置</el-button>
  143. </el-form-item>
  144. </save-form>
  145. <div class="tableWrap">
  146. <el-table
  147. style="width: 100%"
  148. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  149. :data="tableList"
  150. >
  151. <el-table-column align="center" prop="userId" label="学员编号">
  152. <template slot-scope="scope">
  153. <copy-text>{{ scope.row.userId }}</copy-text>
  154. </template>
  155. </el-table-column>
  156. <el-table-column
  157. align="center"
  158. prop="userName"
  159. label="学员姓名"
  160. ></el-table-column>
  161. <el-table-column align="center" prop="gender" label="性别">
  162. <template slot-scope="scope">
  163. {{ scope.row.gender ? "男" : "女" }}
  164. </template>
  165. </el-table-column>
  166. <el-table-column align="center" prop="phone" label="联系电话">
  167. <template slot-scope="scope">
  168. <copy-text>{{ scope.row.phone }}</copy-text>
  169. </template>
  170. </el-table-column>
  171. <el-table-column align="center" label="年级班级">
  172. <template slot-scope="scope">
  173. {{ scope.row.currentGrade }}{{ scope.row.currentClass }}
  174. </template>
  175. </el-table-column>
  176. <el-table-column
  177. align="center"
  178. prop="teacherRecommandSubjectId"
  179. label="老师推荐声部"
  180. >
  181. <template slot-scope="scope">
  182. {{
  183. scope.row.teacherRecommandSubjectId
  184. ? scope.row.teacherRecommandSubjectName
  185. : null
  186. }}
  187. {{
  188. !scope.row.teacherRecommandSubjectName &&
  189. scope.row.teacherRecommandSubjectId == 999
  190. ? "听从老师安排"
  191. : null
  192. }}
  193. {{
  194. scope.row.teacherRecommandSubjectId == -1 &&
  195. !scope.row.teacherRecommandSubjectName
  196. ? "无"
  197. : null
  198. }}
  199. </template>
  200. </el-table-column>
  201. <el-table-column
  202. align="center"
  203. prop="selectionSubjectId"
  204. label="选报声部"
  205. >
  206. <template slot-scope="scope">
  207. {{
  208. scope.row.selectionSubjectId
  209. ? scope.row.selectionSubjectName
  210. : null
  211. }}
  212. {{
  213. !scope.row.selectionSubjectName &&
  214. scope.row.selectionSubjectId == 999
  215. ? "听从老师安排"
  216. : null
  217. }}
  218. {{
  219. !scope.row.selectionSubjectId && !scope.row.selectionSubjectName
  220. ? "无"
  221. : null
  222. }}
  223. </template>
  224. </el-table-column>
  225. <!-- <el-table-column
  226. align="center"
  227. prop="subjectFirstName"
  228. label="选报声部1"
  229. >
  230. <template slot-scope="scope">
  231. {{
  232. scope.row.subjectFirstName ? scope.row.subjectFirstName : null
  233. }}
  234. {{
  235. !scope.row.subjectFirstName && scope.row.subjectFirst == 999
  236. ? "听从老师安排"
  237. : null
  238. }}
  239. {{
  240. !scope.row.subjectFirstName && !scope.row.subjectFirst
  241. ? "无"
  242. : null
  243. }}
  244. </template>
  245. </el-table-column>
  246. <el-table-column
  247. align="center"
  248. prop="subjectSecondName"
  249. label="选报声部2"
  250. >
  251. <template slot-scope="scope">
  252. {{
  253. scope.row.subjectSecondName ? scope.row.subjectSecondName : null
  254. }}
  255. {{
  256. !scope.row.subjectSecondName && scope.row.subjectSecond == 999
  257. ? "听从老师安排"
  258. : null
  259. }}
  260. {{
  261. !scope.row.subjectSecondName && !scope.row.subjectSecond
  262. ? "无"
  263. : null
  264. }}
  265. </template>
  266. </el-table-column> -->
  267. <!-- <el-table-column
  268. align="center"
  269. prop="isAllowAdjust"
  270. label="是否服从调剂"
  271. >
  272. <template slot-scope="scope">
  273. {{ scope.row.isAllowAdjust ? "是" : "否" }}
  274. </template>
  275. </el-table-column> -->
  276. <el-table-column align="center" label="乐器准备方式">
  277. <template slot-scope="scope">
  278. {{ scope.row.kitPurchaseMethod | instrumentType }}
  279. </template>
  280. </el-table-column>
  281. <el-table-column align="center" label="系统意向">
  282. <template slot-scope="scope">
  283. {{ scope.row.cloudTeacherMethod | instrumentType }}
  284. </template>
  285. </el-table-column>
  286. <el-table-column
  287. align="center"
  288. prop="courseScheduleId"
  289. width="150"
  290. label="操作"
  291. v-if="isedit"
  292. >
  293. <!-- :router="['/business/forecastName']" -->
  294. <template slot-scope="scope">
  295. <auth :auths="['visit/add/teamForecastName']">
  296. <el-button type="text" @click="addVisited(scope.row)"
  297. >新增回访</el-button
  298. >
  299. </auth>
  300. </template>
  301. </el-table-column>
  302. </el-table>
  303. <pagination
  304. save-key="/forecastName"
  305. sync
  306. :total.sync="pageInfo.total"
  307. :page.sync="pageInfo.page"
  308. :limit.sync="pageInfo.limit"
  309. :page-sizes="pageInfo.page_size"
  310. @pagination="getList"
  311. />
  312. </div>
  313. </div>
  314. <!-- 预报名链接 -->
  315. <qr-code
  316. v-model="codeStatus"
  317. title="预报名问卷"
  318. :codeUrl="codeUrl"
  319. @preLook="preLook"
  320. :ispreLook="true"
  321. />
  322. <!-- 预报名详情 -->
  323. <qr-code
  324. v-model="codedetailStatus"
  325. title="预报名H5统计"
  326. :codeUrl="detailUrl"
  327. />
  328. <!-- 发送家长会通知 -->
  329. <el-dialog
  330. title="预报名家长会通知"
  331. :visible.sync="extendPaymentStatus"
  332. @close="onClose('extendForm')"
  333. width="400px"
  334. >
  335. <parentsMeeting
  336. v-if="extendPaymentStatus"
  337. ref="extendForm"
  338. :extendForm="extendForm"
  339. :sysMsgStr="sysMsgStr"
  340. :msg="'确认后该短信将发送给已填写预报名问卷的学员'"
  341. />
  342. <div slot="footer" class="dialog-footer">
  343. <el-button @click="extendPaymentStatus = false">取 消</el-button>
  344. <el-button type="primary" @click="onExtendPayment('extendForm')"
  345. >确 定</el-button
  346. >
  347. </div>
  348. </el-dialog>
  349. <!-- 回访记录 -->
  350. <el-dialog
  351. title="新增回访"
  352. width="760px"
  353. v-if="visitVisible"
  354. :close-on-click-modal="false"
  355. :visible.sync="visitVisible"
  356. >
  357. <visit-model
  358. v-if="visitVisible"
  359. @close="visitVisible = false"
  360. :detail="visitDetail"
  361. @submited="getList"
  362. />
  363. </el-dialog>
  364. <!-- 回访记录 -->
  365. <el-dialog
  366. title="意向统计"
  367. width="600px"
  368. :close-on-click-modal="false"
  369. :visible.sync="subjectVisible"
  370. v-if="subjectVisible"
  371. >
  372. <intention-model v-if="subjectVisible" @close="subjectVisible = false" />
  373. </el-dialog>
  374. <el-dialog
  375. title="预览"
  376. width="500px"
  377. :close-on-click-modal="false"
  378. append-to-body
  379. :visible.sync="preLookVisible"
  380. >
  381. <iframe
  382. width="100%"
  383. height="600px"
  384. :src="codeUrl + '&look=true'"
  385. frameborder="0"
  386. ></iframe>
  387. </el-dialog>
  388. </div>
  389. </template>
  390. <script>
  391. import pagination from "@/components/Pagination/index";
  392. import qrCode from "@/components/QrCode/index";
  393. import { permission } from "@/utils/directivePage";
  394. import { vaildStudentUrl, vaildTeachingUrl } from "@/utils/validate";
  395. import { Export } from "@/utils/downLoadFile";
  396. import visitModel from "@/views/withdrawal-application/modals/visit";
  397. import intentionModel from "./modals/intention";
  398. import parentsMeeting from './modals/parentsMeeting'
  399. import {
  400. queryPreApplyList,
  401. finishPreApply,
  402. sendParentMeetingNotice,
  403. getSysMessageConfig,
  404. } from "./api";
  405. export default {
  406. name: "forecastName",
  407. components: { pagination, qrCode, visitModel, intentionModel,parentsMeeting },
  408. props: ["isedit"],
  409. data() {
  410. const query = this.$route.query;
  411. return {
  412. codedetailStatus: false,
  413. teamName: query.name || null,
  414. codeStatus: false,
  415. musicGroupId: query.id,
  416. codeUrl:
  417. vaildStudentUrl() +
  418. "/project/forecastName/index.html?musicGroupId=" +
  419. query.id,
  420. searchForm: {
  421. name: null,
  422. subjectId: null,
  423. teacherRecommandSubjectId: null,
  424. selectionSubjectId: null,
  425. isAllowAdjust: null,
  426. cloudTeacherMethod: null,
  427. kitPurchaseMethod: null,
  428. },
  429. tableList: [],
  430. pageInfo: {
  431. // 分页规则
  432. limit: 10, // 限制显示条数
  433. page: 1, // 当前页
  434. total: 0, // 总条数
  435. page_size: [10, 20, 40, 50], // 选择限制显示条数
  436. },
  437. visitVisible: false,
  438. subjectVisible: false,
  439. visitDetail: null,
  440. extendPaymentStatus: false,
  441. extendForm: {
  442. meetingDate: null,
  443. address: null,
  444. },
  445. extendRule: {
  446. meetingDate: [
  447. { required: true, message: "请选择家长会时间", trigger: "change" },
  448. ],
  449. address: [
  450. { required: true, message: "请输入家长会地址", trigger: "blur" },
  451. ],
  452. },
  453. preLookVisible: false,
  454. sysMsg: "",
  455. subjectList: [],
  456. tenantId:null
  457. };
  458. },
  459. async mounted() {
  460. this.tenantId= this.$helpers.tenantId
  461. await this.$store.dispatch("setSubjects");
  462. // 获取短信推送模板
  463. this.subjectList = [...this.selects.subjects];
  464. this.subjectList.push({ id: -1, name: "无" });
  465. const rus = await getSysMessageConfig({
  466. type: "STUDENT_SMS_IM_MUSIC_GROUP_PARENT_MEETING_NOTICE",
  467. });
  468. this.sysMsg = rus.data?.content||'';
  469. this.getList();
  470. },
  471. methods: {
  472. permission,
  473. onReSet() {
  474. this.$refs["searchForm"].resetFields();
  475. this.search();
  476. },
  477. search() {
  478. this.pageInfo.page = 1;
  479. this.getList();
  480. },
  481. onCancel() {
  482. this.$store.dispatch("delVisitedViews", this.$route);
  483. this.$router.push({ path: "/teamList" });
  484. },
  485. downloadFile() {
  486. let params = this.searchForm;
  487. Export(
  488. this,
  489. {
  490. url: "/api-web/studentRegistration/preRegisterExport",
  491. params: {
  492. ...params,
  493. musicGroupId: this.musicGroupId,
  494. },
  495. fileName: "预报名列表.xls",
  496. },
  497. "是否确认导出报表?"
  498. );
  499. },
  500. async getList() {
  501. try {
  502. const result = await queryPreApplyList({
  503. ...this.searchForm,
  504. musicGroupId: this.musicGroupId,
  505. page: this.pageInfo.page,
  506. rows: this.pageInfo.limit,
  507. });
  508. this.tableList = result.data.rows;
  509. this.pageInfo.total = result.data.total;
  510. } catch (error) {}
  511. },
  512. async onPaymentGroup(type) {
  513. try {
  514. this.$confirm("您是否确定开启乐团缴费?", "提示", {
  515. confirmButtonText: "确定",
  516. cancelButtonText: "取消",
  517. type: "warning",
  518. }).then(async () => {
  519. const result = await finishPreApply({
  520. isCheckStudentNum: type == 1 ? false : true,
  521. musicGroupId: this.musicGroupId,
  522. });
  523. this.$store.dispatch("delVisitedViews", this.$route);
  524. this.$router.push({
  525. path: "/teamList",
  526. });
  527. });
  528. } catch (error) {}
  529. },
  530. addVisited(rows) {
  531. // 新增回访
  532. this.visitVisible = true;
  533. this.visitDetail = {
  534. musicGroupId: rows.musicGroupId,
  535. overview: "",
  536. purpose: "",
  537. userId: rows.userId,
  538. type: "",
  539. visitTime: "",
  540. visitType: "",
  541. feedback: "",
  542. realName: rows.userName,
  543. };
  544. // this.visitDetail = rows
  545. },
  546. onClose(formName) {
  547. this.extendForm= {
  548. meetingDate: null,
  549. address: null,
  550. }
  551. // this.$refs[formName].$refs[formName].resetFields();
  552. },
  553. onExtendPayment(formName) {
  554. // console.log(formName)
  555. // console.log(this.$refs)
  556. // return
  557. this.$refs[formName].$refs[formName].validate(async (valid) => {
  558. if (valid) {
  559. try {
  560. await this.$confirm("您是否确定发送家长会通知?", "提示", {
  561. confirmButtonText: "确定",
  562. cancelButtonText: "取消",
  563. type: "warning",
  564. });
  565. await sendParentMeetingNotice({
  566. ...this.extendForm,
  567. musicGroupId: this.musicGroupId,
  568. });
  569. this.$message.success("家长会通知已发送");
  570. this.extendPaymentStatus = false;
  571. } catch (error) {}
  572. }
  573. });
  574. },
  575. applyDates() {
  576. return {
  577. firstDayOfWeek: 1,
  578. disabledDate(time) {
  579. if (end) {
  580. return new Date(end).getTime() - 86400000 >= time.getTime();
  581. } else {
  582. return time.getTime() + 86400000 < Date.now();
  583. //开始时间不选时,结束时间最大值小于等于当天
  584. }
  585. },
  586. };
  587. },
  588. preLook(val) {
  589. this.preLookVisible = true;
  590. },
  591. },
  592. computed: {
  593. sysMsgStr() {
  594. let strArr = this.sysMsg.split("{}");
  595. if (strArr.length == 3) {
  596. return `${strArr[0]}<span style="color:red">"${
  597. this.extendForm.meetingDate ? this.extendForm.meetingDate : "--"
  598. }"</span>${strArr[1]}<span style="color:red">"${
  599. this.extendForm.address ? this.extendForm.address : "--"
  600. }"</span>
  601. ${strArr[2]}`;
  602. } else {
  603. return ``;
  604. }
  605. },
  606. detailUrl(){
  607. return vaildTeachingUrl() + "/#/preApplySubject?musicGroupId=" + this.$route.query.id+'&tenantId='+this.tenantId
  608. }
  609. },
  610. };
  611. </script>
  612. <style lang="less" scoped>
  613. .msgP {
  614. line-height: 24px;
  615. margin-top: 10px;
  616. }
  617. </style>