vipCourse.vue 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746
  1. <template>
  2. <div class="vipCourse">
  3. <div>
  4. <!-- <van-divider
  5. content-position="center"
  6. :style="{ padding: '0 16px', margin: '.05rem 0' }"
  7. >课程信息</van-divider
  8. > -->
  9. <div class="vip-title">课程信息</div>
  10. <van-field
  11. label="课程声部"
  12. input-align="right"
  13. placeholder="请选择课程声部"
  14. v-model="formName.subjectListName"
  15. @click="onSelect('subjectList')"
  16. readonly
  17. is-link
  18. />
  19. <van-field
  20. label="课程形式"
  21. v-model="formName.vipGroupCategoryName"
  22. input-align="right"
  23. placeholder="请选择课程形式"
  24. @click="onSelect('vipGroupCategory')"
  25. readonly
  26. is-link
  27. />
  28. <van-cell
  29. class="courseStudent"
  30. title="上课学员"
  31. @click="onCheckStudent"
  32. :readonly="true"
  33. input-align="right"
  34. :is-link="checkboxSelectDataList.length > 0 ? false : true"
  35. :value="checkboxSelectDataList.length > 0 ? '重新选择' : '请选择上课学员'"
  36. :value-class="checkboxSelectDataList.length > 0 ? 'studentColor' : null"
  37. />
  38. <div
  39. v-if="checkboxSelectDataList.length > 0"
  40. style="
  41. text-align: center;
  42. line-height: 1.8;
  43. padding: 0.05rem 0;
  44. background: #fafbff;
  45. "
  46. >
  47. <p
  48. style="color: #323233"
  49. v-for="(item, index) in checkboxSelectDataList"
  50. :key="index"
  51. >
  52. {{ item.username }} - {{ item.parentsPhone }}
  53. </p>
  54. </div>
  55. <van-field
  56. label="活动方案"
  57. v-model="formName.vipGroupActivityName"
  58. input-align="right"
  59. placeholder="请选择活动方案"
  60. @click="onSelect('vipGroupActivity')"
  61. readonly
  62. is-link
  63. />
  64. <!-- <van-divider
  65. content-position="center"
  66. :style="{ padding: '0 16px', margin: '.05rem 0' }"
  67. >课时组成</van-divider
  68. > -->
  69. <div class="vip-title">课时组成</div>
  70. <van-field
  71. label="课时总数"
  72. input-align="right"
  73. placeholder="请输入课时总数"
  74. readonly
  75. :value="
  76. loadData.vipGroupActivitySelect.maxCourseNum
  77. ? loadData.vipGroupActivitySelect.maxCourseNum + '节'
  78. : 0 + '节'
  79. "
  80. />
  81. <van-field
  82. label="课程时长"
  83. v-model="form.singleClassMinutes"
  84. input-align="right"
  85. placeholder="请选择课程时长"
  86. @click="onClickSingleClass"
  87. readonly
  88. is-link
  89. />
  90. <van-field
  91. v-if="statusList.hasOnline"
  92. v-model="form.onlineClassesNums"
  93. @keyup="onClassKeyUp"
  94. label="线上课"
  95. input-align="right"
  96. placeholder="请输入次数"
  97. type="number"
  98. />
  99. <van-field
  100. v-if="statusList.hasOffline"
  101. v-model="form.offlineClassesNums"
  102. @keyup="onClassKeyUp('offLine')"
  103. label="线下课"
  104. input-align="right"
  105. placeholder="请输入次数"
  106. type="number"
  107. />
  108. <van-field
  109. v-if="form.offlineClassesNums > 0"
  110. v-model="formName.teacherSchoolName"
  111. @click="onSelect('teacherSchool')"
  112. label="线下课地址"
  113. :readonly="true"
  114. input-align="right"
  115. is-link
  116. placeholder="请选择"
  117. />
  118. <van-field
  119. @click="dataForm.status = true"
  120. v-model="form.courseStart"
  121. label="排课开始时间"
  122. :readonly="true"
  123. input-align="right"
  124. is-link
  125. placeholder="请选择"
  126. />
  127. <van-cell
  128. title-class="title-time"
  129. v-for="(item, index) in scheduleList"
  130. :key="index"
  131. >
  132. <template slot="title">
  133. <span class="online">{{ item.type }}</span>
  134. <span class="week">{{ item.weekStr }}</span>
  135. <span class="timer">{{ item.startTime + "-" + item.endTime }}</span>
  136. </template>
  137. <template slot="default">
  138. <van-button
  139. type="warning"
  140. @click="onScheduleRemove(item)"
  141. round
  142. size="small"
  143. plain
  144. >删除</van-button
  145. >
  146. </template>
  147. </van-cell>
  148. <div class="add-plan van-cell" @click="onCourseShedule">
  149. <van-icon name="add-o" />课时安排
  150. </div>
  151. <van-field
  152. label="排课列表"
  153. v-if="scheduleList.length > 0"
  154. disabled
  155. input-align="right"
  156. @click="onShowTimeTable"
  157. is-link
  158. />
  159. <div style="margin: 16px">
  160. <van-button round block type="info" @click="onSubmit"
  161. >确认排课</van-button
  162. >
  163. </div>
  164. </div>
  165. <!-- 每课时长 -->
  166. <van-action-sheet
  167. v-model="statusList.classTimerStatus"
  168. :actions="loadData.classTimer"
  169. cancel-text="取消"
  170. @cancel="statusList.classTimerStatus = false"
  171. @select="onClassTimerSelect"
  172. />
  173. <!-- 报名开始时间&报名结束时间 -->
  174. <van-popup v-model="enlistForm.status" position="bottom">
  175. <van-datetime-picker
  176. v-model="enlistForm.currentDate"
  177. type="date"
  178. :min-date="enlistForm.minDate"
  179. :formatter="formatter"
  180. @cancel="enlistForm.status = false"
  181. @confirm="onEnlistConfirm"
  182. />
  183. </van-popup>
  184. <!-- 赠课类型 -->
  185. <van-action-sheet
  186. v-model="statusList.giveTeachModeStatus"
  187. :actions="loadData.giveTeachMode"
  188. cancel-text="取消"
  189. @cancel="statusList.giveTeachModeStatus = false"
  190. @select="onModeSelect"
  191. />
  192. <!-- 课程信息所用 :close-on-click-overlay="false" -->
  193. <van-popup v-model="sheetForm.sheetStatus" position="bottom">
  194. <van-picker
  195. :loading="sheetForm.loading"
  196. :default-index="sheetForm.index"
  197. :columns="sheetForm.columns"
  198. show-toolbar
  199. @cancel="sheetForm.sheetStatus = false"
  200. @confirm="onSheetConfirm"
  201. />
  202. </van-popup>
  203. <!-- 课时安排 -->
  204. <van-popup v-model="dataForm.status" position="bottom">
  205. <van-datetime-picker
  206. v-model="dataForm.currentDate"
  207. type="date"
  208. :min-date="dataForm.minDate"
  209. :formatter="formatter"
  210. @cancel="dataForm.status = false"
  211. @confirm="onCurrentConfirm"
  212. />
  213. </van-popup>
  214. <!-- 课时安排 -->
  215. <van-popup v-model="courseForm.teachingStatus" position="bottom">
  216. <van-picker
  217. :columns="courseForm.columns"
  218. show-toolbar
  219. @cancel="courseForm.teachingStatus = false"
  220. @confirm="onTeachinConfirm"
  221. />
  222. </van-popup>
  223. <!-- 选择上课学生 -->
  224. <van-popup
  225. v-model="statusList.studentStatus"
  226. :lock-scroll="true"
  227. position="bottom"
  228. :style="{ height: '180%' }"
  229. class="studentChiose"
  230. >
  231. <div v-if="statusList.studentStatus">
  232. <van-sticky>
  233. <van-search
  234. show-action
  235. shape="round"
  236. @search="onSearch"
  237. v-model="params.search"
  238. placeholder="请输入学生名或手机号"
  239. >
  240. <template #action>
  241. <div @click="onSearch">搜索</div>
  242. </template>
  243. </van-search>
  244. </van-sticky>
  245. <div class="paddingB80">
  246. <van-list
  247. v-model="loading"
  248. class="studentContainer"
  249. v-if="dataShow"
  250. key="data"
  251. :finished="finished"
  252. finished-text=""
  253. @load="getStudent"
  254. >
  255. <van-checkbox-group v-model="checkboxSelect">
  256. <van-cell-group>
  257. <van-cell
  258. v-for="(item, index) in dataList"
  259. :key="index"
  260. @click="onCheckboxSelect(item)"
  261. class="input-cell"
  262. :center="true"
  263. >
  264. <template slot="icon">
  265. <img
  266. class="logo"
  267. v-if="item.avatar"
  268. :src="item.avatar"
  269. alt=""
  270. />
  271. <img
  272. class="logo"
  273. v-else
  274. src="@/assets/images/icon_student.png"
  275. alt=""
  276. />
  277. </template>
  278. <template slot="title">
  279. {{ item.username }}
  280. </template>
  281. <template slot="label">
  282. <span>{{ desensitPhone(item.parentsPhone) }}</span>
  283. </template>
  284. <template slot="default">
  285. <van-checkbox :name="item.userId.toString()"></van-checkbox>
  286. </template>
  287. </van-cell>
  288. </van-cell-group>
  289. </van-checkbox-group>
  290. </van-list>
  291. <m-empty class="empty" msg="暂无学生" v-else key="data" />
  292. </div>
  293. <div class="button-group-popup">
  294. <span class="btn" @click="onPopupCancel">取消</span>
  295. <span class="btn primary" @click="onPopupSubmit">确定</span>
  296. </div>
  297. </div>
  298. </van-popup>
  299. <!-- 课表展示 -->
  300. <van-popup v-model="statusList.classTime" position="bottom">
  301. <van-row>
  302. <van-col span="12">上课类型</van-col>
  303. <van-col span="12">上课时间</van-col>
  304. </van-row>
  305. <div class="tableContainer">
  306. <van-row v-for="(item, index) in timeTable" :key="index">
  307. <van-col span="12">
  308. {{ item.teachMode == "ONLINE" ? "线上" : "线下" }}
  309. </van-col>
  310. <van-col span="12">
  311. {{ item.classDate }} {{ item.startClassTimeStr }}
  312. </van-col>
  313. </van-row>
  314. </div>
  315. </van-popup>
  316. </div>
  317. </template>
  318. <script>
  319. import dayjs from "dayjs";
  320. import cleanDeep from 'clean-deep'
  321. import { browser } from "@/common/common";
  322. import {
  323. findSubSubjects,
  324. vipGroupCategory,
  325. findVipSchoolByTeacher2
  326. } from "@/api/teacher";
  327. import { getStudents, createActivityVipGroup, getChildrenDayActivity } from "../api";
  328. import setLoading from "@/utils/loading";
  329. import MEmpty from "@/components/MEmpty";
  330. let minutes = []; // 分钟数
  331. for (let i = 0; i < 60; i++) {
  332. let mi = i < 10 ? "0" + i : i;
  333. minutes.push(mi + "分");
  334. }
  335. export default {
  336. components: {
  337. MEmpty },
  338. name: "apply",
  339. data() {
  340. return {
  341. dayjs,
  342. activityCourseType: null,
  343. subjectId: null,
  344. dataForm: {
  345. // 时间下拉框
  346. status: false,
  347. minDate: new Date(),
  348. currentDate: new Date(),
  349. },
  350. enlistForm: {
  351. // 时间下拉框
  352. updateStatus: "", // 修改哪个状态
  353. status: false,
  354. minDate: new Date(),
  355. currentDate: new Date(),
  356. },
  357. statusList: {
  358. // 散状态集合
  359. giveTeachModeStatus: false, // 赠课弹窗状态
  360. teachOnOrOff: false, // 是否显示赠课
  361. hasOnline: false, // 是否显示线上
  362. hasOffline: false, // 是否显示线下
  363. classTime: false, // 课表展示
  364. headerStatus: false, // 头部是否展示
  365. classTimerStatus: false, // 每课时长状态
  366. studentStatus: false, // 上课学生状态
  367. },
  368. loadData: {
  369. // 下拉加载数据
  370. subjectList: [], // 声部列表
  371. subjectListSelect: [], // 选中的声部JSON
  372. vipGroupCategory: [], // 课程形式
  373. vipGroupCategorySelect: [], // 选中的课程形式JSON
  374. vipGroupActivity: [], // 活动文案
  375. vipGroupActivitySelect: [], // 选中的活动文案JSON
  376. teacherSchool: [], // 线下课地址
  377. teacherSchoolSelect: [], // 选中的线下课地址JSON
  378. teacherList: [], // 线下课地址
  379. teacherListSelect: [], // 选中的线下课地址JSON
  380. giveTeachMode: [
  381. {
  382. name: "线上课",
  383. value: "ONLINE",
  384. },
  385. {
  386. name: "线下课",
  387. value: "OFFLINE",
  388. },
  389. ], // 赠课
  390. giveTeachModeSelect: [], // 选中的赠课JSON
  391. teacherCategory: [], // 老师课酬信息
  392. classTimer: [], // 每课时长
  393. },
  394. sheetForm: {
  395. // 上拉弹窗
  396. currentType: null, // 当前选择的类型
  397. sheetStatus: false,
  398. loading: true, // 加载数据
  399. index: 0, // 选中的索引值
  400. columns: [],
  401. },
  402. courseForm: {
  403. // 排课弹窗
  404. teachingStatus: false, // 课时安排状态
  405. columns: [
  406. {
  407. // 课程选项
  408. values: ["线上", "线下"],
  409. className: "type",
  410. },
  411. {
  412. values: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
  413. className: "week",
  414. },
  415. {
  416. values: [
  417. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  418. 20
  419. ],
  420. className: "hours",
  421. defaultIndex: 7,
  422. },
  423. {
  424. values: minutes,
  425. className: "minutes",
  426. },
  427. ],
  428. },
  429. form: {
  430. subjectIdList: null,
  431. vipGroupCategoryId: null,
  432. vipGroupActivityId: null,
  433. teacherSchoolId: null,
  434. educationalTeacherId: null,
  435. studentNum: null,
  436. singleClassMinutes: null,
  437. onlineClassesNums: null,
  438. offlineClassesNums: null,
  439. registrationStartTime: null,
  440. coursesExpireDate: null,
  441. totalClassTime: null,
  442. courseStart: null,
  443. giveTeachMode: null,
  444. onlineClassesUnitPrice: null,
  445. offlineClassesUnitPrice: null,
  446. onlineTeacherSalary: null,
  447. offlineTeacherSalary: null,
  448. totalCount: null,
  449. },
  450. formName: {
  451. subjectListName: null, // 声部名称
  452. subjectListIndex: 0, // 声部名称
  453. vipGroupCategoryName: null, // 课程形式
  454. vipGroupCategoryIndex: 0, // 课程形式
  455. vipGroupActivityName: null, // 活动文案
  456. vipGroupActivityIndex: 0, // 活动文案
  457. teacherSchoolName: null, // 线下课地址
  458. teacherSchoolIndex: 0, // 线下课地址
  459. giveTeachModeName: null, // 赠课类型
  460. },
  461. other: {
  462. onlineSalary: null, // 线上课课酬结算方式
  463. offlineSalary: null, // 线下课课酬结算方式
  464. giveNum: 0, // 赠送课时
  465. },
  466. scheduleList: [], // 课时安排
  467. timeTable: [], // 生成的课表
  468. onSubmitStatus: true, // 点击
  469. checkboxSelect: [],
  470. checkboxSelectIds: [],
  471. checkboxSelectList: [], //选中学生列表
  472. checkboxSelectDataList: [],
  473. loading: false,
  474. finished: false,
  475. params: {
  476. search: null,
  477. page: 1,
  478. rows: 20,
  479. },
  480. dataShow: true, // 是否有数据
  481. dataList: [],
  482. };
  483. },
  484. async mounted() {
  485. },
  486. watch: {
  487. 'form.singleClassMinutes'() {
  488. this.scheduleList = []
  489. }
  490. },
  491. methods: {
  492. onCheckStudent() {
  493. if(!this.form.subjectIdList) {
  494. this.$toast('请选择课程声部')
  495. return
  496. }
  497. if (!this.form.vipGroupCategoryId) {
  498. // 判断是否选择了课程形式
  499. this.$toast("请选择课程形式");
  500. return;
  501. }
  502. this.statusList.studentStatus = true;
  503. },
  504. onSelect(name) {
  505. let sheetForm = this.sheetForm;
  506. sheetForm.columns = [];
  507. if (!this.form.vipGroupCategoryId && name == "vipGroupActivity") {
  508. this.$toast("请选择课程形式");
  509. return;
  510. } else if (
  511. (!this.checkboxSelectDataList ||
  512. (this.checkboxSelectDataList &&
  513. this.checkboxSelectDataList.length <= 0)) &&
  514. name == "vipGroupActivity"
  515. ) {
  516. // 判断是否选择了课程形式
  517. this.$toast("请选择上课学生");
  518. return;
  519. }
  520. sheetForm.sheetStatus = true;
  521. sheetForm.loading = true;
  522. sheetForm.currentType = name;
  523. sheetForm.index = 0;
  524. let arr = this.loadData[name];
  525. if (arr && arr.length > 0) {
  526. sheetForm.columns = arr;
  527. sheetForm.index = this.formName[name + "Index"];
  528. sheetForm.loading = false;
  529. } else {
  530. this.onLoadingData(name);
  531. }
  532. this.sheetForm.status = true;
  533. },
  534. formatter(type, val) {
  535. if (type === "year") {
  536. return `${val}年`;
  537. } else if (type === "month") {
  538. return `${val}月`;
  539. } else if (type == "day") {
  540. return `${val}日`;
  541. }
  542. return val;
  543. },
  544. async onLoadingData() {
  545. // 加载数据
  546. let sheetForm = this.sheetForm;
  547. if (sheetForm.currentType == "subjectList") {
  548. // 请求声部
  549. await findSubSubjects().then((res) => {
  550. let result = res.data;
  551. if (result.code == 200 && result.data.length > 0) {
  552. let tempArr = [];
  553. result.data.forEach((item) => {
  554. item.value = item.id;
  555. item.text = item.name;
  556. tempArr.push(item);
  557. });
  558. this.loadData.subjectList = tempArr;
  559. sheetForm.columns = tempArr;
  560. sheetForm.loading = false;
  561. } else {
  562. this.$toast("暂无科目列表");
  563. sheetForm.loading = false;
  564. }
  565. });
  566. } else if (sheetForm.currentType == "vipGroupCategory") {
  567. // 课程形式
  568. vipGroupCategory().then((res) => {
  569. let result = res.data;
  570. if (result.code == 200 && result.data.length > 0) {
  571. let tempArr = [];
  572. result.data.forEach((item) => {
  573. if (item.name == "1v1" || item.name == "1v2") {
  574. item.value = item.id;
  575. item.text = item.name;
  576. tempArr.push(item);
  577. }
  578. });
  579. this.loadData.vipGroupCategory = tempArr;
  580. sheetForm.columns = tempArr;
  581. sheetForm.loading = false;
  582. } else {
  583. this.$toast("暂无课程形式");
  584. sheetForm.loading = false;
  585. }
  586. });
  587. } else if (sheetForm.currentType == "vipGroupActivity") {
  588. // 活动文案
  589. let studentIds = [];
  590. if (
  591. this.checkboxSelectDataList &&
  592. this.checkboxSelectDataList.length > 0
  593. ) {
  594. this.checkboxSelectDataList.forEach((item) => {
  595. studentIds.push(item.userId);
  596. });
  597. }
  598. getChildrenDayActivity({
  599. categoryId: this.form.vipGroupCategoryId,
  600. studentIds: studentIds.join(",")
  601. }).then((res) => {
  602. let result = res.data;
  603. if (result.code == 200 && result.data.length > 0) {
  604. let tempArr = [];
  605. let regStr = new RegExp("双十一");
  606. result.data.forEach((item) => {
  607. if (!regStr.test(item.name)) {
  608. item.value = item.id;
  609. item.text = item.name;
  610. (item.startTime = item.startTime
  611. ? item.startTime.split(" ")[0]
  612. : null), // 报名开始时间
  613. (item.endTime = item.endTime
  614. ? item.endTime.split(" ")[0]
  615. : null); // 报名结束时间
  616. tempArr.push(item);
  617. }
  618. });
  619. this.loadData.vipGroupActivity = tempArr;
  620. sheetForm.columns = tempArr;
  621. sheetForm.loading = false;
  622. } else {
  623. this.$toast("暂无活动方案");
  624. sheetForm.loading = false;
  625. }
  626. });
  627. } else if(sheetForm.currentType == "teacherSchool") {
  628. // 教师教学点
  629. findVipSchoolByTeacher2({ userId: this.teacherId }).then((res) => {
  630. let result = res.data;
  631. if (result.code == 200 && result.data.length > 0) {
  632. let tempArr = [];
  633. result.data.forEach((item) => {
  634. item.value = item.id;
  635. item.text = item.name;
  636. tempArr.push(item);
  637. });
  638. this.loadData.teacherSchool = tempArr;
  639. sheetForm.columns = tempArr;
  640. sheetForm.loading = false;
  641. } else {
  642. this.$toast("暂无教学点");
  643. sheetForm.loading = false;
  644. }
  645. });
  646. }
  647. },
  648. onSheetConfirm(value, index) {
  649. // 上拉弹窗
  650. let sheetForm = this.sheetForm,
  651. form = this.form,
  652. formName = this.formName,
  653. loadData = this.loadData;
  654. if (sheetForm.currentType == "subjectList") {
  655. // 科目名称赋值
  656. form.subjectIdList = value.value;
  657. formName.subjectListName = value.text;
  658. formName.subjectListIndex = index;
  659. loadData.subjectListSelect = value;
  660. // 重置上课学生
  661. this.dataList = []
  662. this.params.search = null
  663. this.loading = false
  664. this.finished = false
  665. this.dataShow = true
  666. this.params.page = 1
  667. this.checkboxSelect = [];
  668. this.checkboxSelectIds = [];
  669. this.checkboxSelectList = []; //选中学生列表
  670. this.checkboxSelectDataList = [];
  671. } else if(sheetForm.currentType == "vipGroupCategory") {
  672. form.vipGroupCategoryId = value.value;
  673. formName.vipGroupCategoryName = value.text;
  674. if(value.studentNum == 1){
  675. this.activityCourseType = 'vip1'
  676. }else if(value.studentNum == 2){
  677. this.activityCourseType = 'vip2'
  678. }
  679. formName.vipGroupCategoryIndex = index;
  680. loadData.vipGroupCategorySelect = value;
  681. form.studentNum = value.studentNum; // 每班人数
  682. // form.singleClassMinutes = value.singleClassMinutes // 每课时长
  683. form.onlineClassesUnitPrice = Math.ceil(value.onlineClassesUnitPrice);
  684. form.offlineClassesUnitPrice = Math.ceil(value.offlineClassesUnitPrice);
  685. // 每课时长赋值
  686. form.singleClassMinutes = null;
  687. loadData.classTimer = [];
  688. let tempSingle = value.singleClassMinutes.split(",");
  689. form.singleClassMinutes = tempSingle.length > 0 ? tempSingle[0] : null
  690. tempSingle.forEach((item) => {
  691. this.loadData.classTimer.push({
  692. name: item,
  693. value: item,
  694. });
  695. });
  696. // 重置上课学生
  697. this.dataList = []
  698. this.params.search = null
  699. this.loading = false
  700. this.finished = false
  701. this.dataShow = true
  702. this.params.page = 1
  703. this.checkboxSelect = [];
  704. this.checkboxSelectIds = [];
  705. this.checkboxSelectList = []; //选中学生列表
  706. this.checkboxSelectDataList = [];
  707. // 重置活动文案
  708. form.vipGroupActivityId = null;
  709. formName.vipGroupActivityName = null;
  710. formName.vipGroupActivityIndex = 0;
  711. loadData.vipGroupActivity = [];
  712. loadData.vipGroupActivitySelect = [];
  713. this.scheduleList = []
  714. this.timeTable = []
  715. } else if (sheetForm.currentType == "vipGroupActivity") {
  716. // 活动方案赋值
  717. // 重置线上课,线下课次数
  718. if (form.vipGroupActivityId != value.value) {
  719. form.offlineClassesNums = null;
  720. form.onlineClassesNums = null;
  721. }
  722. form.vipGroupActivityId = value.value;
  723. formName.vipGroupActivityName = value.text;
  724. formName.vipGroupActivityIndex = index;
  725. if(value.maxCourseNum <= 0) {
  726. value.maxCourseNum = 0
  727. }
  728. loadData.vipGroupActivitySelect = value;
  729. // 换活动之后单价重置
  730. form.onlineClassesUnitPrice = Math.ceil(
  731. loadData.vipGroupCategorySelect.onlineClassesUnitPrice
  732. );
  733. form.offlineClassesUnitPrice = Math.ceil(
  734. loadData.vipGroupCategorySelect.offlineClassesUnitPrice
  735. );
  736. this.onCalcClassTimes(value); // 计算时间等.........
  737. // this.getCalcClass(); // 课酬计算
  738. this.setTimeTable(); // 重新排课
  739. // 时间安排
  740. // form.registrationStartTime = value.startTime
  741. // form.coursesExpireDate = value.endTime
  742. } else if (sheetForm.currentType == "teacherSchool") {
  743. // 线下课地址
  744. form.teacherSchoolId = value.value;
  745. formName.teacherSchoolName = value.text;
  746. formName.teacherSchoolIndex = index;
  747. }
  748. sheetForm.sheetStatus = false;
  749. },
  750. onClassKeyUp(type) {
  751. // 线上课&线下课修改时
  752. if (type == "offLine" && this.form.offlineClassesNums <= 0) {
  753. this.form.teacherSchoolId = null;
  754. this.formName.teacherSchoolName = null;
  755. this.formName.teacherSchoolIndex = 0;
  756. }
  757. let vas = this.loadData.vipGroupActivitySelect;
  758. this.onCalcClassTimes(vas);
  759. // this.getCalcClass();
  760. this.setTimeTable();
  761. },
  762. onCalcClassTimes(vas) {
  763. // 计算课时总数
  764. let form = this.form,
  765. other = this.other,
  766. statusList = this.statusList;
  767. let totalCount =
  768. Number(form.onlineClassesNums) + Number(form.offlineClassesNums);
  769. // ...
  770. if (vas.salarySettlementJson) {
  771. let obj = JSON.parse(vas.salarySettlementJson);
  772. if (obj && obj.onlineSalarySettlement) {
  773. // 有线上课
  774. statusList.hasOnline = true;
  775. } else {
  776. statusList.hasOnline = false;
  777. }
  778. if (obj && obj.offlineSalarySettlement) {
  779. // 有线下课
  780. statusList.hasOffline = true;
  781. } else {
  782. statusList.hasOffline = false;
  783. }
  784. }
  785. if (vas.type == "GIVE_CLASS") {
  786. // 买赠活动
  787. this.statusList.teachOnOrOff = true; // 显示赠课
  788. if (totalCount >= Number(vas.attribute1)) {
  789. form.totalClassTime = totalCount + "+" + vas.attribute2;
  790. other.giveNum = vas.attribute2;
  791. } else {
  792. form.totalClassTime = totalCount;
  793. other.giveNum = 0;
  794. }
  795. } else {
  796. // 折扣活动
  797. form.totalClassTime = totalCount;
  798. other.giveNum = 0;
  799. this.statusList.teachOnOrOff = false; // 隐藏赠课
  800. }
  801. },
  802. onModeSelect(value) {
  803. // 赠课确认
  804. this.form.giveTeachMode = value.value;
  805. this.formName.giveTeachModeName = value.name;
  806. this.statusList.giveTeachModeStatus = false;
  807. // this.getCalcClass();
  808. },
  809. onClickSingleClass() {
  810. if (!this.formName.vipGroupCategoryName) {
  811. this.$toast("请选择课程形式");
  812. return;
  813. }
  814. this.statusList.classTimerStatus = true;
  815. },
  816. onClassTimerSelect(value) {
  817. // 每课时长设置
  818. if(this.form.singleClassMinutes != value.value) {
  819. this.timeTable = [] // 生成的课表
  820. this.scheduleList = []
  821. }
  822. this.form.singleClassMinutes = value.value;
  823. this.statusList.classTimerStatus = false;
  824. // this.getCalcClass();
  825. },
  826. onCurrentConfirm(value) {
  827. // 排课开始时间
  828. let selectDate = new Date(value);
  829. let tempMonth =
  830. selectDate.getMonth() + 1 >= 10
  831. ? selectDate.getMonth() + 1
  832. : "0" + (selectDate.getMonth() + 1);
  833. let tempDay =
  834. selectDate.getDate() >= 10
  835. ? selectDate.getDate()
  836. : "0" + selectDate.getDate();
  837. this.form.courseStart =
  838. selectDate.getFullYear() + "-" + tempMonth + "-" + tempDay;
  839. this.dataForm.status = false;
  840. },
  841. onEnlistConfirm(value) {
  842. // 报名开始/结束时间
  843. let selectDate = new Date(value);
  844. let tempMonth =
  845. selectDate.getMonth() + 1 >= 10
  846. ? selectDate.getMonth() + 1
  847. : "0" + (selectDate.getMonth() + 1);
  848. let tempDay =
  849. selectDate.getDate() >= 10
  850. ? selectDate.getDate()
  851. : "0" + selectDate.getDate();
  852. let enlistForm = this.enlistForm;
  853. let form = this.form;
  854. if (enlistForm.updateStatus == "start") {
  855. form.registrationStartTime =
  856. selectDate.getFullYear() + "-" + tempMonth + "-" + tempDay;
  857. if (form.coursesExpireDate) {
  858. let temps = new Date(
  859. form.registrationStartTime.replace(/-/gi, "/")
  860. ).getTime();
  861. let tempe = new Date(
  862. form.coursesExpireDate.replace(/-/gi, "/")
  863. ).getTime();
  864. // 如果开始时间大于结束时间,结束时间制空
  865. if (temps > tempe) {
  866. form.coursesExpireDate = null;
  867. }
  868. }
  869. } else if (enlistForm.updateStatus == "end") {
  870. form.coursesExpireDate =
  871. selectDate.getFullYear() + "-" + tempMonth + "-" + tempDay;
  872. }
  873. enlistForm.status = false;
  874. },
  875. onEnListShow(type, value) {
  876. // 报名开始/截止时间
  877. let enlistForm = this.enlistForm;
  878. if (type == "end") {
  879. if (this.form.registrationStartTime) {
  880. enlistForm.minDate = new Date(
  881. this.form.registrationStartTime.replace(/-/gi, "/")
  882. );
  883. } else {
  884. enlistForm.minDate = new Date();
  885. }
  886. } else if (type == "start") {
  887. // 开始时默认为当前时间
  888. enlistForm.minDate = new Date();
  889. }
  890. if (value) {
  891. enlistForm.currentDate = new Date(value.replace(/-/gi, "/"));
  892. } else {
  893. enlistForm.currentDate = new Date();
  894. }
  895. enlistForm.updateStatus = type;
  896. enlistForm.status = true;
  897. },
  898. onCourseShedule() {
  899. // 课时安排
  900. if (!this.form.singleClassMinutes) {
  901. this.$toast("请选每课时长");
  902. return;
  903. }
  904. if (this.other.giveNum > 0 && !this.form.giveTeachMode) {
  905. this.$toast("请选择赠课类型");
  906. return;
  907. }
  908. if (!this.form.courseStart) {
  909. this.$toast("请选择排课开始时间");
  910. return;
  911. }
  912. this.courseForm.teachingStatus = true;
  913. },
  914. onScheduleRemove(item) {
  915. // 删除课程安排
  916. let index = this.scheduleList.indexOf(item);
  917. if (index !== -1) {
  918. this.scheduleList.splice(index, 1);
  919. }
  920. },
  921. onTeachinConfirm(value) {
  922. // 添加课程
  923. let scheduleList = this.scheduleList;
  924. let startTime =
  925. (value[2] >= 10 ? value[2] : "0" + value[2]) +
  926. ":" +
  927. value[3].split("分")[0];
  928. let endTime = this.MinutesTest(
  929. value[2],
  930. value[3],
  931. this.form.singleClassMinutes
  932. );
  933. let isAdd = true;
  934. scheduleList.forEach((item) => {
  935. let isStartTime = this.timeIsrange(startTime, endTime, item.startTime);
  936. let isEndTime = this.timeIsrange(startTime, endTime, item.endTime);
  937. if (isAdd) {
  938. //
  939. if (value[1] == item.weekStr) {
  940. if (isStartTime || isEndTime) {
  941. isAdd = false;
  942. } else {
  943. isAdd = true;
  944. }
  945. } else if (value[1] != item.weekStr) {
  946. isAdd = true;
  947. }
  948. }
  949. });
  950. // 判断结束时间
  951. const endTime1 = endTime ? Number(endTime.split(":")[0]) : 0
  952. const endTime2 = endTime ? Number(endTime.split(":")[1]) : 0
  953. if(endTime1 >= 21 && endTime2 > 0) {
  954. this.$toast("课程安排结束时间超过21:00");
  955. return;
  956. }
  957. if (isAdd) {
  958. // 判断时间范围是否有重复
  959. scheduleList.push({
  960. type: value[0], // 线上还是线下
  961. weekStr: value[1],
  962. weekIndex: this.getWeek(value[1]),
  963. startTime: startTime,
  964. endTime: endTime,
  965. id: Date.now(),
  966. });
  967. this.courseForm.teachingStatus = false;
  968. this.setTimeTable();
  969. } else {
  970. this.$toast("该时间段已排课请重选时间");
  971. return;
  972. }
  973. },
  974. onShowTimeTable() {
  975. // 显示排课列表
  976. if (!this.checkCourseList()) {
  977. return;
  978. }
  979. this.statusList.classTime = true;
  980. this.setTimeTable();
  981. },
  982. setTimeTable() {
  983. if (!this.checkCourseList(false)) {
  984. return;
  985. }
  986. // return
  987. // 重置排课列表
  988. this.timeTable = [];
  989. let form = this.form,
  990. scheduleList = this.scheduleList;
  991. // if(!form.courseStart) {
  992. // this.$toast('请选择排课开始时间')
  993. // return
  994. // }
  995. // 拿到线上课数与线下课数 以及
  996. let online = parseInt(
  997. form.onlineClassesNums ? form.onlineClassesNums : 0
  998. );
  999. let offline = parseInt(
  1000. form.offlineClassesNums ? form.offlineClassesNums : 0
  1001. );
  1002. let giveNum = parseInt(this.other.giveNum);
  1003. let giveClassType = form.giveTeachMode;
  1004. if (giveClassType == "ONLINE") {
  1005. // 线上
  1006. online += giveNum;
  1007. } else if (giveClassType == "OFFLINE") {
  1008. offline += giveNum;
  1009. }
  1010. // 判断是否有课程安排
  1011. if (scheduleList.length <= 0) {
  1012. return;
  1013. }
  1014. let totalCount = Number(online) + Number(offline);
  1015. let tempCourseStart = form.courseStart.replace(/-/gi, "/");
  1016. let dateOperation = new Date(tempCourseStart);
  1017. let forMark = 0;
  1018. while (totalCount && totalCount > 0) {
  1019. for (let i = 0; i < scheduleList.length; i++) {
  1020. // console.log(totalCount, scheduleList)
  1021. if (online == 0 && offline == 0) break;
  1022. let num = scheduleList[i].weekIndex - dateOperation.getDay();
  1023. // 如果是同一天一个周期会出现排课都排到一天
  1024. if (forMark > 0 && num == 0 && i == 0) {
  1025. num = num + 7;
  1026. }
  1027. if (num < 0) {
  1028. // 如果为负数则为下周
  1029. num = num + 7;
  1030. }
  1031. let dataStr = this.getThinkDate(dateOperation, num);
  1032. // 判断是否大于当前时间
  1033. let nowGetTime = new Date().getTime();
  1034. let courseTime = new Date(
  1035. dataStr.replace(/-/gi, "/") +
  1036. " " +
  1037. scheduleList[i].startTime +
  1038. ":00"
  1039. ).getTime();
  1040. if (nowGetTime < courseTime) {
  1041. let tempArr = {
  1042. classDate: dataStr,
  1043. startClassTimeStr: scheduleList[i].startTime,
  1044. endClassTimeStr: scheduleList[i].endTime,
  1045. };
  1046. // console.log(scheduleList[i].type, online, offline)
  1047. if (scheduleList[i].type == "线上" && online > 0) {
  1048. tempArr.teachMode = "ONLINE";
  1049. this.timeTable.push(tempArr);
  1050. online--;
  1051. totalCount--;
  1052. } else if (scheduleList[i].type == "线下" && offline > 0) {
  1053. tempArr.teachMode = "OFFLINE";
  1054. this.timeTable.push(tempArr);
  1055. offline--;
  1056. totalCount--;
  1057. }
  1058. }
  1059. }
  1060. // 加一周
  1061. if (scheduleList.length == 1) {
  1062. dateOperation.setDate(dateOperation.getDate() + 7);
  1063. } else if (
  1064. scheduleList.every((item) => item.weekStr === scheduleList[0].weekStr)
  1065. ) {
  1066. // 标记循环次数(标记判断课程安排是不是同一天)
  1067. forMark++;
  1068. }
  1069. }
  1070. this.timeTable.sort((a, b) => {
  1071. let aStr = dayjs(
  1072. dayjs(a.classDate).format("YYYY-MM-DD") +
  1073. " " +
  1074. a.startClassTimeStr +
  1075. ":00"
  1076. ).valueOf();
  1077. let bStr = dayjs(
  1078. dayjs(b.classDate).format("YYYY-MM-DD") +
  1079. " " +
  1080. b.startClassTimeStr +
  1081. ":00"
  1082. ).valueOf();
  1083. return aStr - bStr;
  1084. });
  1085. },
  1086. onGiveMode() {
  1087. // 赠送课改变时
  1088. this.statusList.giveTeachModeStatus = true;
  1089. // this.getCalcClass();
  1090. },
  1091. getCalcClass() {
  1092. // 计算课酬
  1093. let loadData = this.loadData;
  1094. let form = this.form;
  1095. let vas = loadData.vipGroupActivitySelect, // 活动
  1096. // vcs = loadData.vipGroupCategorySelect, // 课程形式
  1097. tc = loadData.teacherCategory, // 老师基本信息
  1098. oncn = form.onlineClassesNums ? form.onlineClassesNums : 0, // 线上课次数
  1099. offcn = form.offlineClassesNums ? form.offlineClassesNums : 0, // 线下课次数
  1100. giveNum = parseInt(this.other.giveNum),
  1101. giveTeachMode = form.giveTeachMode; // 线下或线下
  1102. // 优惠活动
  1103. // ...
  1104. if (vas.salarySettlementJson) {
  1105. let obj = JSON.parse(vas.salarySettlementJson);
  1106. // 获取每课时长
  1107. // 每45Min计算一些课酬
  1108. // let b = form.singleClassMinutes ? (form.singleClassMinutes / 45) : 0
  1109. let tempPrice = 0;
  1110. if (Number(oncn) + Number(offcn) > 0) {
  1111. let countPrice =
  1112. oncn * form.onlineClassesUnitPrice +
  1113. offcn * form.offlineClassesUnitPrice;
  1114. if (giveNum > 0 && !giveTeachMode) {
  1115. countPrice = 0;
  1116. }
  1117. tempPrice =
  1118. (countPrice * form.studentNum) /
  1119. (Number(oncn) + Number(offcn) + Number(giveNum));
  1120. if (vas.type == "DISCOUNT") {
  1121. tempPrice =
  1122. (tempPrice * (vas.attribute1 ? Number(vas.attribute1) : 100)) /
  1123. 100;
  1124. }
  1125. }
  1126. // 课程按课来计算
  1127. if (obj && obj.onlineSalarySettlement) {
  1128. let onss = obj.onlineSalarySettlement;
  1129. // 有线上课
  1130. if (onss.salarySettlementType == "TEACHER_DEFAULT") {
  1131. form.onlineTeacherSalary = Math.round(tc.offlineClassesSalary); // 线上课酬
  1132. } else if (onss.salarySettlementType == "RATIO_DISCOUNT") {
  1133. // 老师课酬的折扣 如果有则不打折
  1134. // form.onlineTeacherSalary = Math.round(vcs.onlineClassesUnitPrice * (onss.settlementValue ? onss.settlementValue : 100) / 100)
  1135. form.onlineTeacherSalary = Math.round(
  1136. tempPrice
  1137. ? (tempPrice *
  1138. (onss.settlementValue ? onss.settlementValue : 100)) /
  1139. 100
  1140. : 0
  1141. );
  1142. } else if (onss.salarySettlementType == "FIXED_SALARY") {
  1143. form.onlineTeacherSalary = Math.round(onss.settlementValue);
  1144. }
  1145. form.onlineTeacherSalary = Number(form.onlineTeacherSalary);
  1146. } else {
  1147. form.onlineTeacherSalary = Math.round(tc.offlineClassesSalary);
  1148. }
  1149. if (obj && obj.offlineSalarySettlement) {
  1150. let offss = obj.offlineSalarySettlement;
  1151. // 有线下课
  1152. if (offss.salarySettlementType == "TEACHER_DEFAULT") {
  1153. form.offlineTeacherSalary = Math.round(tc.offlineClassesSalary); // 线上课酬
  1154. } else if (offss.salarySettlementType == "RATIO_DISCOUNT") {
  1155. // 老师课酬的折扣
  1156. // form.offlineTeacherSalary = Math.round((vcs.offlineClassesUnitPrice * (offss.settlementValue ? offss.settlementValue : 100) / 100))
  1157. form.offlineTeacherSalary = Math.round(
  1158. tempPrice
  1159. ? (tempPrice *
  1160. (offss.settlementValue ? offss.settlementValue : 100)) /
  1161. 100
  1162. : 0
  1163. );
  1164. } else if (offss.salarySettlementType == "FIXED_SALARY") {
  1165. form.offlineTeacherSalary = Math.round(offss.settlementValue);
  1166. }
  1167. form.offlineTeacherSalary = Number(form.offlineTeacherSalary);
  1168. } else {
  1169. form.offlineTeacherSalary = Math.round(tc.offlineClassesSalary);
  1170. }
  1171. }
  1172. if (vas.type == "GIVE_CLASS" || vas.type == "BASE_ACTIVITY") {
  1173. form.totalCount = Math.round(
  1174. oncn * form.onlineClassesUnitPrice +
  1175. offcn * form.offlineClassesUnitPrice
  1176. );
  1177. } else if (vas.type == "DISCOUNT") {
  1178. form.totalCount = Math.round(
  1179. ((oncn * form.onlineClassesUnitPrice +
  1180. offcn * form.offlineClassesUnitPrice) *
  1181. Number(vas.attribute1)) /
  1182. 100
  1183. );
  1184. }
  1185. form.totalCount = Number(form.totalCount);
  1186. },
  1187. getThinkDate(date, num) {
  1188. let Stamp = date;
  1189. Stamp.setDate(date.getDate() + num); // 获取当前月数的第几天
  1190. var year = Stamp.getFullYear(); //获取完整的年份(4位,1970-????)
  1191. var month = Stamp.getMonth() + 1; //获取当前月份(0-11,0代表1月)
  1192. var mvar = "";
  1193. if (month < 10) {
  1194. mvar = "0" + month;
  1195. } else {
  1196. mvar = month + "";
  1197. }
  1198. var day = Stamp.getDate();
  1199. var dvar = "";
  1200. if (day < 10) {
  1201. dvar = "0" + day;
  1202. } else {
  1203. dvar = day + "";
  1204. }
  1205. return year + "-" + mvar + "-" + dvar;
  1206. },
  1207. // 分钟小时相加减
  1208. MinutesTest(houer, mins, interval) {
  1209. let min = mins.split("分")[0];
  1210. let sdate1 = new Date(1900, 1, 1, houer, min);
  1211. sdate1.setMinutes(sdate1.getMinutes() + parseInt(interval));
  1212. let H = sdate1.getHours();
  1213. let M = sdate1.getMinutes();
  1214. if (H < 10) H = "0" + H;
  1215. if (M < 10) M = "0" + M;
  1216. return H + ":" + M;
  1217. },
  1218. // 判断时间是否在时间段内
  1219. timeIsrange(beginTime, endTime, nowTime) {
  1220. var strb = beginTime.split(":");
  1221. if (strb.length != 2) {
  1222. return false;
  1223. }
  1224. var stre = endTime.split(":");
  1225. if (stre.length != 2) {
  1226. return false;
  1227. }
  1228. var strn = nowTime.split(":");
  1229. if (stre.length != 2) {
  1230. return false;
  1231. }
  1232. var b = new Date();
  1233. var e = new Date();
  1234. var n = new Date();
  1235. b.setHours(strb[0]);
  1236. b.setMinutes(strb[1]);
  1237. e.setHours(stre[0]);
  1238. e.setMinutes(stre[1]);
  1239. n.setHours(strn[0]);
  1240. n.setMinutes(strn[1]);
  1241. if (n.getTime() - b.getTime() >= 0 && n.getTime() - e.getTime() <= 0) {
  1242. // 在时间范围内
  1243. return true;
  1244. } else {
  1245. // 不在时间范围内
  1246. return false;
  1247. }
  1248. },
  1249. getWeek(str) {
  1250. // 获取周几索引值
  1251. let template = {
  1252. '周一': 1,
  1253. '周二': 2,
  1254. '周三': 3,
  1255. '周四': 4,
  1256. '周五': 5,
  1257. '周六': 6,
  1258. '周日': 0,
  1259. };
  1260. return template[str];
  1261. },
  1262. async onSubmit() {
  1263. // 次数限制是否可以继续创建
  1264. let form = this.form;
  1265. let statusList = this.statusList;
  1266. if (!form.subjectIdList) {
  1267. this.$toast("请选择课程声部");
  1268. return false;
  1269. }
  1270. if (!form.vipGroupCategoryId) {
  1271. this.$toast("请选择课程形式");
  1272. return false;
  1273. }
  1274. if (this.checkboxSelectIds.length <= 0) {
  1275. this.$toast("请选择上课学生");
  1276. return;
  1277. }
  1278. if (!form.vipGroupActivityId) {
  1279. this.$toast("请选择活动方案");
  1280. return false;
  1281. }
  1282. if (!form.singleClassMinutes) {
  1283. this.$toast("请选择每课时长");
  1284. return false;
  1285. }
  1286. let onlineClassesStatus =
  1287. !form.onlineClassesNums && form.onlineClassesNums <= 0 ? true : false
  1288. let offlineClassesStatus =
  1289. !form.offlineClassesNums && form.offlineClassesNums <= 0 ? true : false
  1290. if (statusList.hasOnline) {
  1291. if (onlineClassesStatus) {
  1292. this.$toast("请输入线上课次数");
  1293. return false;
  1294. }
  1295. }
  1296. if (statusList.hasOffline) {
  1297. if (offlineClassesStatus) {
  1298. this.$toast("请输入线下课次数");
  1299. return false;
  1300. }
  1301. // 判断是否有线下
  1302. if (form.offlineClassesNums > 0 && !form.teacherSchoolId) {
  1303. this.$toast("请选择线下课地址");
  1304. return false;
  1305. }
  1306. }
  1307. let vipGroupActivitySelect = this.loadData.vipGroupActivitySelect
  1308. if (vipGroupActivitySelect.type == "GIVE_CLASS" && !form.giveTeachMode) {
  1309. this.$toast("请选择赠课类型");
  1310. return false;
  1311. }
  1312. if (this.scheduleList.length <= 0) {
  1313. this.$toast("课时安排不能为空");
  1314. return false;
  1315. }
  1316. if(vipGroupActivitySelect.maxCourseNum > 0) {
  1317. let tempCourseCount = parseInt(form.onlineClassesNums) + parseInt(form.offlineClassesNums);
  1318. if(tempCourseCount != vipGroupActivitySelect.maxCourseNum) {
  1319. this.$toast(`课时总数为${vipGroupActivitySelect.maxCourseNum}节`)
  1320. return
  1321. }
  1322. }
  1323. if(vipGroupActivitySelect.maxCourseNum <= 0) {
  1324. this.$toast('当前选择活动有误,请选择其它活动')
  1325. return
  1326. }
  1327. if (!this.checkCourseList()) {
  1328. return;
  1329. }
  1330. // 排课
  1331. this.setTimeTable();
  1332. if (form.giveTeachMode == "ONLINE") {
  1333. form.onlineClassesNum =
  1334. Number(form.onlineClassesNums) + Number(this.other.giveNum);
  1335. form.offlineClassesNum = Number(form.offlineClassesNums);
  1336. } else {
  1337. form.onlineClassesNum = Number(form.onlineClassesNums);
  1338. form.offlineClassesNum =
  1339. Number(form.offlineClassesNums) + Number(this.other.giveNum);
  1340. }
  1341. form.totalClassTimes =
  1342. Number(form.onlineClassesNums) +
  1343. Number(form.offlineClassesNums) +
  1344. Number(this.other.giveNum);
  1345. form.paymentExpireDate = form.coursesExpireDate;
  1346. form.studentIdList = this.checkboxSelectIds.join(",");
  1347. form.firstStudentId =
  1348. this.checkboxSelectDataList.length > 0
  1349. ? this.checkboxSelectDataList[0].userId
  1350. : null;
  1351. let params = {
  1352. courseSchedules: this.timeTable,
  1353. vipGroupApplyBaseInfo: {
  1354. ...form,
  1355. userId: this.teacherId,
  1356. activityCourseType: this.activityCourseType,
  1357. },
  1358. };
  1359. if (!this.onSubmitStatus) {
  1360. return;
  1361. }
  1362. this.onSubmitStatus = false;
  1363. setLoading(true);
  1364. await createActivityVipGroup(params)
  1365. .then((res) => {
  1366. let result = res.data;
  1367. setLoading(false);
  1368. if (result.code == 200) {
  1369. this.$toast("申请成功");
  1370. setTimeout(() => {
  1371. this.onSubmitStatus = true;
  1372. if (browser().iPhone) {
  1373. window.webkit.messageHandlers.DAYA.postMessage(
  1374. JSON.stringify({
  1375. api: "back",
  1376. })
  1377. );
  1378. } else if (browser().android) {
  1379. DAYA.postMessage(
  1380. JSON.stringify({
  1381. api: "back",
  1382. })
  1383. );
  1384. } else {
  1385. this.$router.push("/business");
  1386. }
  1387. }, 500);
  1388. } else {
  1389. this.onSubmitStatus = true;
  1390. this.$toast(result.msg);
  1391. }
  1392. })
  1393. .catch(() => {
  1394. this.onSubmitStatus = true;
  1395. setLoading(false);
  1396. });
  1397. },
  1398. checkCourseList(isShowToast = true) {
  1399. let form = this.form;
  1400. let scheduleList = this.scheduleList || [];
  1401. let hasOnLine = false; // 是否有线上课时安排
  1402. let hasOffLine = false;
  1403. scheduleList.forEach((item) => {
  1404. if (item.type == "线上") {
  1405. hasOnLine = true;
  1406. }
  1407. if (item.type == "线下") {
  1408. hasOffLine = true;
  1409. }
  1410. });
  1411. let statusList = this.statusList;
  1412. let onlineClassesStatus =
  1413. !form.onlineClassesNums && form.onlineClassesNums <= 0 ? true : false;
  1414. let offlineClassesStatus =
  1415. !form.offlineClassesNums && form.offlineClassesNums <= 0 ? true : false;
  1416. if (statusList.hasOnline) {
  1417. if (onlineClassesStatus) {
  1418. if (isShowToast) {
  1419. this.$toast("请输入线上课次数");
  1420. }
  1421. return false;
  1422. }
  1423. if (!onlineClassesStatus && !hasOnLine && form.onlineClassesNums > 0) {
  1424. if (isShowToast) {
  1425. this.$toast("课时安排缺少线上课类型");
  1426. }
  1427. return false;
  1428. }
  1429. }
  1430. if (statusList.hasOffline) {
  1431. if (offlineClassesStatus) {
  1432. if (isShowToast) {
  1433. this.$toast("请输入线下课次数");
  1434. }
  1435. return false;
  1436. }
  1437. if (
  1438. !offlineClassesStatus &&
  1439. !hasOffLine &&
  1440. form.offlineClassesNums > 0
  1441. ) {
  1442. if (isShowToast) {
  1443. this.$toast("课时安排缺少线下课类型");
  1444. }
  1445. return false;
  1446. }
  1447. }
  1448. return true;
  1449. },
  1450. // 搜索
  1451. onSearch() {
  1452. this.params.page = 1;
  1453. this.dataList = [];
  1454. this.dataShow = true;
  1455. this.loading = true;
  1456. this.finished = false;
  1457. this.getStudent();
  1458. },
  1459. getStudent() {
  1460. let params = this.params;
  1461. getStudents(cleanDeep({
  1462. ...params,
  1463. activityCourseType: this.activityCourseType,
  1464. subjectId:this.form.subjectIdList
  1465. })).then((res) => {
  1466. let result = res.data;
  1467. this.loading = false;
  1468. if (result.code == 200) {
  1469. if(this.dataList.length > 0 && result.data.pageNo == 1) {
  1470. return
  1471. }
  1472. params.page = result.data.pageNo;
  1473. this.dataList = this.dataList.concat(result.data.rows);
  1474. if (params.page >= result.data.totalPage) {
  1475. this.finished = true;
  1476. }
  1477. this.params.page++;
  1478. } else {
  1479. this.finished = true;
  1480. }
  1481. // 判断是否有数据
  1482. if (this.dataList.length <= 0) {
  1483. this.dataShow = false;
  1484. }
  1485. });
  1486. },
  1487. onPopupCancel() {
  1488. // 关闭弹窗
  1489. this.statusList.studentStatus = false;
  1490. // this.params.search = null
  1491. this.checkboxSelect = [];
  1492. this.checkboxSelectList = [];
  1493. },
  1494. onPopupSubmit() {
  1495. const vipGroupCategorySelect = this.loadData.vipGroupCategorySelect;
  1496. if (this.checkboxSelect.length != vipGroupCategorySelect.studentNum) {
  1497. this.$toast(
  1498. `请选择学生${vipGroupCategorySelect.studentNum}名,当前选择${this.checkboxSelect.length}名`
  1499. );
  1500. return;
  1501. }
  1502. this.checkboxSelectDataList = JSON.parse(
  1503. JSON.stringify(this.checkboxSelectList)
  1504. );
  1505. this.checkboxSelectIds = JSON.parse(JSON.stringify(this.checkboxSelect));
  1506. this.checkboxSelect = [];
  1507. this.checkboxSelectList = [];
  1508. this.loadData.vipGroupActivity = [];
  1509. this.formName.vipGroupActivityName = null;
  1510. this.formName.vipGroupCategoryIndex = 0;
  1511. this.form.vipGroupActivityId = null;
  1512. this.statusList.studentStatus = false;
  1513. },
  1514. onCheckboxSelect(value) {
  1515. if (this.checkboxSelect.includes(value.userId.toString())) {
  1516. this.checkboxSelect.forEach((item, index) => {
  1517. if (item == value.userId.toString()) {
  1518. this.checkboxSelect.splice(index, 1);
  1519. }
  1520. });
  1521. this.checkboxSelectList.forEach((item, index) => {
  1522. if (item.userId == value.userId) {
  1523. this.checkboxSelectList.splice(index, 1);
  1524. }
  1525. });
  1526. } else {
  1527. this.checkboxSelect.push(value.userId.toString());
  1528. this.checkboxSelectList.push(value);
  1529. }
  1530. // checkboxSelect = item.userId
  1531. },
  1532. desensitPhone(phone) {
  1533. // 手机号脱敏
  1534. let first = phone.substr(0, 3);
  1535. let last = phone.substr(-4);
  1536. return first + "****" + last;
  1537. },
  1538. }
  1539. };
  1540. </script>
  1541. <style lang="less" scoped>
  1542. // .vipCourse {
  1543. // min-height: calc(100vh - 44px - 0.44rem);
  1544. // }
  1545. @import url("../../../assets/commonLess/variable.less");
  1546. .studentContainer {
  1547. /deep/.van-cell__title {
  1548. font-size: 0.16rem;
  1549. color: @mFontColor;
  1550. flex: 1 auto;
  1551. }
  1552. .logo {
  1553. width: 0.35rem;
  1554. height: 0.35rem;
  1555. margin-right: 0.12rem;
  1556. border-radius: 100%;
  1557. }
  1558. .input-cell {
  1559. padding: 0.12rem 0.16rem 0.2rem;
  1560. .van-checkbox {
  1561. justify-content: flex-end;
  1562. }
  1563. }
  1564. /deep/.van-cell__value {
  1565. height: 0.2rem;
  1566. }
  1567. /deep/.van-checkbox__icon .van-icon {
  1568. border-color: @sFontColor;
  1569. }
  1570. /deep/.van-checkbox__icon--checked .van-icon {
  1571. border-color: #01C1B5;
  1572. }
  1573. .van-tag {
  1574. margin-left: 0.08rem;
  1575. }
  1576. }
  1577. .title-time {
  1578. display: flex;
  1579. align-items: center;
  1580. flex: 1 auto;
  1581. color: #4a4a4a;
  1582. .online {
  1583. color: @tFontColor;
  1584. }
  1585. .week {
  1586. padding-left: 0.4rem;
  1587. padding-right: 0.15rem;
  1588. }
  1589. }
  1590. .van-row {
  1591. line-height: 0.4rem;
  1592. border-top: 1px solid #edeef0;
  1593. text-align: center;
  1594. font-size: 0.14rem;
  1595. &:first-child {
  1596. border-top: 0;
  1597. background: #edeef0;
  1598. color: #444;
  1599. font-size: 0.15rem;
  1600. }
  1601. }
  1602. .tableContainer {
  1603. max-height: 2.44rem;
  1604. overflow: auto;
  1605. .van-row {
  1606. color: #444;
  1607. &:first-child {
  1608. border-top: 0;
  1609. background: #fff;
  1610. font-size: 0.14rem;
  1611. }
  1612. }
  1613. }
  1614. .button-group-popup {
  1615. position: fixed;
  1616. bottom: 0;
  1617. padding: 0.2rem 0;
  1618. width: 100%;
  1619. text-align: center;
  1620. background-color: #ffffff;
  1621. .btn {
  1622. padding: 0 0.45rem;
  1623. line-height: 0.4rem;
  1624. display: inline-block;
  1625. border: 1px solid @mColor;
  1626. border-radius: 1rem;
  1627. color: @mColor;
  1628. background: #fff;
  1629. font-size: 0.18rem;
  1630. &.primary {
  1631. color: #fff;
  1632. background: @mColor;
  1633. }
  1634. }
  1635. .btn + .btn {
  1636. margin-left: 0.1rem;
  1637. }
  1638. }
  1639. .add-plan {
  1640. display: flex;
  1641. align-items: center;
  1642. justify-content: center;
  1643. padding: 0.2rem 0;
  1644. font-size: 0.16rem;
  1645. color: @tFontColor;
  1646. .van-icon {
  1647. margin-right: 0.05rem;
  1648. font-size: 0.2rem;
  1649. }
  1650. }
  1651. /deep/.van-cell__title {
  1652. -webkit-box-flex: 0;
  1653. -webkit-flex: none;
  1654. flex: none;
  1655. box-sizing: border-box;
  1656. margin-right: 12px;
  1657. color: #646566;
  1658. text-align: left;
  1659. word-wrap: break-word;
  1660. font-size: 16px;
  1661. }
  1662. .studentColor {
  1663. color: @mColor !important;
  1664. }
  1665. .courseStudent {
  1666. .van-cell__value {
  1667. color: #c8c9cc;
  1668. font-size: .16rem;
  1669. }
  1670. }
  1671. .paddingB80 {
  1672. padding-bottom: .8rem;
  1673. }
  1674. /deep/.van-field__control {
  1675. font-size: .16rem;
  1676. }
  1677. /deep/.studentChiose {
  1678. border-radius: 0 0 0px 0px;
  1679. overflow: auto;
  1680. }
  1681. .vip-title {
  1682. padding: .06rem .14rem .04rem;
  1683. font-size: .14rem;
  1684. color: #808080;
  1685. }
  1686. </style>