studentList.vue 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640
  1. <template>
  2. <div class="m-container">
  3. <h2>
  4. <div class="squrt"></div>
  5. 学员管理
  6. </h2>
  7. <div class="m-core">
  8. <!-- 搜索标题 -->
  9. <save-form
  10. :inline="true"
  11. class="searchForm"
  12. @submit="onSearch"
  13. @reset="onReSet"
  14. ref="saveForm"
  15. :model.sync="searchForm"
  16. >
  17. <el-form-item>
  18. <el-input
  19. clearable
  20. placeholder="学生姓名或电话"
  21. @keydown.enter.native="
  22. (e) => {
  23. e.target.blur();
  24. $refs.saveForm.save();
  25. onSearch();
  26. }
  27. "
  28. v-model.trim="searchForm.search"
  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. multiple
  37. collapse-tags
  38. clearable
  39. placeholder="请选择分部"
  40. >
  41. <el-option
  42. v-for="(item, index) in selects.branchs"
  43. :key="index"
  44. :label="item.name"
  45. :value="item.id"
  46. ></el-option>
  47. </el-select>
  48. </el-form-item>
  49. <el-form-item>
  50. <remote-search
  51. :commit="'setTeachers'"
  52. v-model="searchForm.teacherId"
  53. :isForzenWithQueryCondition="true"
  54. />
  55. </el-form-item>
  56. <el-form-item prop="hasMember">
  57. <el-select
  58. class="multiple"
  59. v-model.trim="searchForm.hasMember"
  60. clearable
  61. placeholder="是否是会员"
  62. >
  63. <el-option label="是" value="1"></el-option>
  64. <el-option label="否" value="0"></el-option>
  65. <el-option label="未生效" value="2"></el-option>
  66. </el-select>
  67. </el-form-item>
  68. <el-form-item prop="isActive">
  69. <el-select
  70. class="multiple"
  71. v-model.trim="searchForm.isActive"
  72. clearable
  73. placeholder="是否激活"
  74. >
  75. <el-option label="是" value="true"></el-option>
  76. <el-option label="否" value="false"></el-option>
  77. </el-select>
  78. </el-form-item>
  79. <!-- <el-form-item prop="hasTeacher">
  80. <el-select
  81. class="multiple"
  82. v-model.trim="searchForm.hasTeacher"
  83. clearable
  84. placeholder="是否关联老师"
  85. >
  86. <el-option label="是" value="1"></el-option>
  87. <el-option label="否" value="0"></el-option>
  88. </el-select>
  89. </el-form-item> -->
  90. <el-form-item prop="operatingTag" v-if="tenantId == 1">
  91. <el-select
  92. class="multiple"
  93. v-model.trim="searchForm.operatingTag"
  94. clearable
  95. placeholder="是否运营"
  96. >
  97. <el-option label="是" :value="1"></el-option>
  98. <el-option label="否" :value="0"></el-option>
  99. </el-select>
  100. </el-form-item>
  101. <el-form-item prop="serviceTag" v-if="tenantId == 1">
  102. <el-select
  103. class="multiple"
  104. v-model.trim="searchForm.serviceTag"
  105. clearable
  106. placeholder="是否服务"
  107. >
  108. <el-option label="是" :value="1"></el-option>
  109. <el-option label="否" :value="0"></el-option>
  110. </el-select>
  111. </el-form-item>
  112. <el-form-item prop="carePackage">
  113. <el-select
  114. class="multiple"
  115. v-model.trim="searchForm.carePackage"
  116. clearable
  117. placeholder="关心包"
  118. >
  119. <el-option label="不可用" :value="0"></el-option>
  120. <el-option label="可用" :value="1"></el-option>
  121. <el-option label="已使用" :value="2"></el-option>
  122. </el-select>
  123. </el-form-item>
  124. <el-form-item prop="comeOnPackage">
  125. <el-select
  126. class="multiple"
  127. v-model.trim="searchForm.comeOnPackage"
  128. clearable
  129. placeholder="加油包"
  130. >
  131. <el-option label="不可用" :value="0"></el-option>
  132. <el-option label="可用" :value="1"></el-option>
  133. <el-option label="已使用" :value="2"></el-option>
  134. </el-select>
  135. </el-form-item>
  136. <el-form-item prop="isNewUser">
  137. <el-select
  138. class="multiple"
  139. v-model.trim="searchForm.isNewUser"
  140. clearable
  141. placeholder="是否是新用户"
  142. >
  143. <el-option label="是" :value="1"></el-option>
  144. <el-option label="否" :value="0"></el-option>
  145. </el-select>
  146. </el-form-item>
  147. <el-form-item prop="isRecord">
  148. <el-select
  149. class="multiple"
  150. v-model.trim="searchForm.isRecord"
  151. clearable
  152. placeholder="是否使用云教练"
  153. >
  154. <el-option label="是" value="1"></el-option>
  155. <el-option label="否" value="0"></el-option>
  156. </el-select>
  157. </el-form-item>
  158. <el-form-item>
  159. <el-button native-type="submit" type="danger">搜索</el-button>
  160. <el-button native-type="reset" type="primary">重置</el-button>
  161. <el-button
  162. type="primary"
  163. v-if="$helpers.permission('export/studentHasCourse')"
  164. @click="downLoadStudent"
  165. >导出名单</el-button
  166. >
  167. </el-form-item>
  168. </save-form>
  169. <el-button
  170. style="margin-bottom: 20px"
  171. type="primary"
  172. @click="addStudentMember"
  173. icon="el-icon-plus"
  174. >创建云教练缴费</el-button
  175. >
  176. <el-button
  177. v-if="$helpers.permission('studentManage/register')"
  178. @click="addStudent"
  179. type="primary"
  180. icon="el-icon-plus"
  181. style="margin-bottom: 20px"
  182. >
  183. 新增学员
  184. </el-button>
  185. <el-button
  186. @click="onCreateQRCode"
  187. type="primary"
  188. style="margin-bottom: 20px"
  189. >
  190. 学员激活列表
  191. </el-button>
  192. <!-- 列表 -->
  193. <div class="tableWrap">
  194. <el-table
  195. :data="tableList"
  196. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  197. @selection-change="handleSelectionChange"
  198. >
  199. <el-table-column type="selection" width="55"></el-table-column>
  200. <el-table-column type="expand">
  201. <template slot-scope="props">
  202. <el-form
  203. label-position="left"
  204. class="demo-table-expand"
  205. >
  206. <el-row>
  207. <el-col :span="6">
  208. <el-form-item label="所属学校">
  209. <div class="schoolWrap">
  210. <overflow-text
  211. width="100%"
  212. :text="props.row.cooperationOrganName"
  213. ></overflow-text>
  214. </div> </el-form-item
  215. ></el-col>
  216. <el-col :span="4">
  217. <el-form-item>
  218. <span slot="label"
  219. >是否激活
  220. <el-tooltip placement="top" popper-class="mTooltip">
  221. <div slot="content">学员是否设置密码</div>
  222. <i
  223. @click="
  224. () => {
  225. console.log('点击');
  226. }
  227. "
  228. class="el-icon-question question"
  229. style="
  230. font-size: 18px;
  231. color: #f56c6c;
  232. cursor: pointer;
  233. "
  234. ></i> </el-tooltip
  235. ></span>
  236. <div>{{ props.row.isActive ? "是" : "否" }}</div>
  237. </el-form-item></el-col
  238. >
  239. <el-col :span="4">
  240. <el-form-item label="课程余额(元)">
  241. <span>{{ props.row.courseBalance | moneyFormat }}</span>
  242. </el-form-item></el-col
  243. >
  244. <el-col :span="4">
  245. <el-form-item label="网管课剩余课时">
  246. <span>{{ props.row.noStartPracticeCourseNum }}</span>
  247. </el-form-item></el-col
  248. >
  249. <el-col :span="4">
  250. <el-form-item label="关心包">
  251. <span>
  252. {{ props.row.carePackage | studentPackage }}
  253. </span>
  254. </el-form-item></el-col
  255. >
  256. </el-row>
  257. <el-row>
  258. <el-col :span="6">
  259. <el-form-item label="VIP老师" v-if="tenantId == 1">
  260. <Tooltip :content='props.row.vipTeacherName ? props.row.vipTeacherName : "--" ' />
  261. </el-form-item></el-col
  262. >
  263. <el-col :span="4">
  264. <el-form-item label="网管课老师">
  265. <Tooltip :content='props.row.practiceTeacherName ? props.row.practiceTeacherName : "--"' />
  266. </el-form-item></el-col
  267. >
  268. <el-col :span="4">
  269. <el-form-item label="声部课老师">
  270. <Tooltip :content='props.row.normalTeacherName ? props.row.normalTeacherName : "--"' />
  271. </el-form-item></el-col
  272. >
  273. <el-col :span="4">
  274. <el-form-item label="合奏课老师">
  275. <Tooltip :content='props.row.mixTeacherName ? props.row.mixTeacherName : "--"' />
  276. </el-form-item></el-col
  277. >
  278. <el-col :span="4">
  279. <el-form-item label="是否运营" v-if="tenantId == 1">
  280. <span>{{ props.row.operatingTag ? "是" : "否" }}</span>
  281. </el-form-item></el-col
  282. >
  283. </el-row>
  284. <el-row>
  285. <el-col :span="6">
  286. <el-form-item label="账户余额(元)">
  287. <span>{{ props.row.balance | moneyFormat }}</span>
  288. </el-form-item></el-col
  289. >
  290. <el-col :span="4">
  291. <el-form-item label="vip课剩余课时">
  292. <span>{{ props.row.noStartVipCourseNum }}</span>
  293. </el-form-item></el-col
  294. >
  295. <el-col :span="4">
  296. <el-form-item label="加油包">
  297. <span>{{
  298. props.row.comeOnPackage | studentPackage
  299. }}</span>
  300. </el-form-item></el-col
  301. >
  302. <el-col :span="4">
  303. <el-form-item label="学员年级">
  304. <span>{{ props.row.currentGrade }}</span>
  305. </el-form-item></el-col
  306. >
  307. <el-col :span="4">
  308. <el-form-item label="学员班级">
  309. <span>{{ props.row.currentClass }}</span>
  310. </el-form-item></el-col
  311. >
  312. </el-row>
  313. <!-- <el-row>
  314. </el-row> -->
  315. </el-form>
  316. </template>
  317. </el-table-column>
  318. <el-table-column align="center" prop="organName" label="所属分部">
  319. <template slot-scope="scope">
  320. <copy-text>{{ scope.row.organName }}</copy-text>
  321. </template>
  322. </el-table-column>
  323. <el-table-column
  324. align="center"
  325. prop="userId"
  326. label="学员信息"
  327. width="140px"
  328. >
  329. <template slot-scope="scope">
  330. {{ scope.row.username }}
  331. ({{ scope.row.gender ? "男" : "女" }})<br />
  332. <copy-text>{{ scope.row.userId }}</copy-text>
  333. </template>
  334. </el-table-column>
  335. <!-- <el-table-column align="center" prop="username" label="学员姓名">
  336. <template slot-scope="scope"> </template>
  337. </el-table-column> -->
  338. <el-table-column
  339. align="center"
  340. prop="realName"
  341. label="家长信息"
  342. width="140px"
  343. >
  344. <template slot-scope="scope">
  345. {{ scope.row.realName }}
  346. <br />
  347. <copy-text>{{ scope.row.parentsPhone }}</copy-text>
  348. </template>
  349. </el-table-column>
  350. <el-table-column
  351. align="center"
  352. prop="subjectName"
  353. label="声部"
  354. ></el-table-column>
  355. <!-- <el-table-column
  356. align="center"
  357. prop="cooperationOrganName"
  358. label="所属学校"
  359. ></el-table-column> -->
  360. <!-- <el-table-column align="center" prop="teacherName" label="指导老师">
  361. <template slot-scope="scope">
  362. <copy-text>{{ scope.row.teacherName }}</copy-text>
  363. </template>
  364. </el-table-column> -->
  365. <!-- <el-table-column align="center" label="性别">
  366. <template slot-scope="scope"></template>
  367. </el-table-column> -->
  368. <!-- <el-table-column
  369. align="center"
  370. prop="leaveNum"
  371. label="本月请假次数"
  372. ></el-table-column> -->
  373. <!-- <el-table-column align="center">
  374. <template slot="header">
  375. <p style="position: relative">
  376. 是否激活
  377. <el-tooltip placement="top" popper-class="mTooltip">
  378. <div slot="content">学员是否设置密码</div>
  379. <i
  380. class="el-icon-question"
  381. style="font-size: 18px; color: #f56c6c"
  382. ></i>
  383. </el-tooltip>
  384. </p>
  385. </template>
  386. <template slot-scope="scope">{{
  387. scope.row.isActive ? "是" : "否"
  388. }}</template>
  389. </el-table-column> -->
  390. <el-table-column align="center" label="未上课时">
  391. <template slot-scope="scope">{{
  392. scope.row.hasCourse ? "有" : "无"
  393. }}</template>
  394. </el-table-column>
  395. <!-- <el-table-column align="center" label="预约网管课">
  396. <template slot-scope="scope">{{ scope.row.isMake ? '是' : '否' }}</template>
  397. </el-table-column> -->
  398. <!-- <el-table-column align="center" label="网管课剩余课时">
  399. <template slot-scope="scope">{{
  400. scope.row.noStartPracticeCourseNum
  401. }}</template>
  402. </el-table-column> -->
  403. <!-- <el-table-column align="center" label="vip课剩余课时">
  404. <template slot-scope="scope">{{
  405. scope.row.noStartVipCourseNum
  406. }}</template>
  407. </el-table-column> -->
  408. <!-- <el-table-column align="center" label="是否运营">
  409. <template slot-scope="scope">{{
  410. scope.row.operatingTag ? "是" : "否"
  411. }}</template>
  412. </el-table-column> -->
  413. <el-table-column align="center" label="是否服务" v-if="tenantId == 1">
  414. <template slot-scope="scope">{{
  415. scope.row.serviceTag ? "是" : "否"
  416. }}</template>
  417. </el-table-column>
  418. <el-table-column align="center" label="是否使用云教练">
  419. <template slot-scope="scope">{{
  420. scope.row.recordUserId > 0 ? "是" : "否"
  421. }}</template>
  422. </el-table-column>
  423. <el-table-column
  424. align="center"
  425. width="120px"
  426. prop="parentsPhone"
  427. label="会员截止日期(剩余天数)"
  428. >
  429. <template slot-scope="scope">
  430. <div v-if="scope.row.membershipEndTime">
  431. <div v-if="scope.row.membershipDay >= 0">
  432. {{ scope.row.membershipEndTime | dayjsFormat }}
  433. <p class="red">剩余{{ scope.row.membershipDay }}天</p>
  434. </div>
  435. <!-- 已过期 -->
  436. <div v-else>
  437. <!-- 有未生效 -->
  438. <div v-if="scope.row.hasNoStartCloudTeacher">
  439. <p>会员未生效</p>
  440. </div>
  441. <!-- 无未生效 -->
  442. <div v-else>
  443. {{ scope.row.membershipEndTime | dayjsFormat }}
  444. <p class="red" v-if="scope.row.membershipDay < 0">
  445. 已过期{{ Math.abs(scope.row.membershipDay) }}天
  446. </p>
  447. </div>
  448. </div>
  449. <!--
  450. <div></div>
  451. <p v-if="scope.row.hasNoStartCloudTeacher">
  452. {{ scope.row.membershipEndTime | dayjsFormat }}
  453. </p> -->
  454. </div>
  455. <div v-else class="red">
  456. <div v-if="scope.row.hasNoStartCloudTeacher">会员未生效</div>
  457. <div v-else>未购买会员</div>
  458. </div>
  459. </template>
  460. </el-table-column>
  461. <!-- <el-table-column
  462. label="会员试用结束日期(剩余天数)"
  463. align="center"
  464. width="120px;"
  465. >
  466. <template slot-scope="scope">
  467. <div>
  468. <p>
  469. {{ scope.row.experienceMembershipEndTime | dayjsFormat }}
  470. </p>
  471. <p
  472. class="red"
  473. v-if="
  474. scope.row.experienceMembershipEndTime &&
  475. scope.row.experienceMembershipDay >= 0
  476. "
  477. >
  478. 剩余{{ scope.row.experienceMembershipDay }}天
  479. </p>
  480. <p
  481. class="red"
  482. v-if="
  483. scope.row.membershipEndTime &&
  484. scope.row.experienceMembershipDay < 0
  485. "
  486. >
  487. 已过期{{ Math.abs(scope.row.experienceMembershipDay) }}天
  488. </p>
  489. </div>
  490. </template>
  491. </el-table-column> -->
  492. <el-table-column align="center" label="是否是新用户">
  493. <template slot="header">
  494. <p style="position: relative">
  495. 是否是新用户
  496. <el-tooltip placement="top" popper-class="mTooltip">
  497. <div slot="content">未购买VIP课程的学员为新用户</div>
  498. <i
  499. class="el-icon-question"
  500. style="font-size: 18px; color: #f56c6c; cursor: pointer"
  501. ></i>
  502. </el-tooltip>
  503. </p>
  504. </template>
  505. <template slot-scope="scope">
  506. {{ scope.row.isNewUser ? "是" : "否" }}
  507. </template>
  508. </el-table-column>
  509. <!-- <el-table-column
  510. align="center"
  511. prop="courseBalance"
  512. label="课程余额(元)"
  513. >
  514. <template slot-scope="scope">
  515. <div>
  516. {{ scope.row.courseBalance | moneyFormat }}
  517. </div>
  518. </template>
  519. </el-table-column> -->
  520. <!-- <el-table-column align="center" prop="balance" label="账户余额(元)">
  521. <template slot-scope="scope">
  522. <div>
  523. {{ scope.row.balance | moneyFormat }}
  524. </div>
  525. </template>
  526. </el-table-column> -->
  527. <!-- <el-table-column align="center" prop="carePackage" label="关心包">
  528. <template slot-scope="scope">{{
  529. scope.row.carePackage | studentPackage
  530. }}</template>
  531. </el-table-column>
  532. <el-table-column align="center" prop="comeOnPackage" label="加油包">
  533. <template slot-scope="scope">{{
  534. scope.row.comeOnPackage | studentPackage
  535. }}</template>
  536. </el-table-column> -->
  537. <el-table-column align="center" width="180px" label="操作">
  538. <template slot-scope="scope">
  539. <router-link
  540. v-if="$helpers.permission('/studentDetail')"
  541. class="el-button--text"
  542. :to="{
  543. path: `/business/studentDetail`,
  544. query: { ...scope.row },
  545. }"
  546. >查看</router-link
  547. >
  548. <el-button
  549. type="text"
  550. style="padding-left: 10px"
  551. v-if="
  552. $helpers.permission('studentManage/studentUpdate/setStudent')
  553. "
  554. @click="setStudent(scope.row)"
  555. >设置扩展声部</el-button
  556. >
  557. <el-button
  558. type="text"
  559. style="padding-left: 10px"
  560. v-if="$helpers.permission('studentManage/studentUpdate')"
  561. @click="resetStudent(scope.row)"
  562. >修改</el-button
  563. >
  564. <!-- api-auth/user/updatePassword2 -->
  565. <el-button
  566. v-if="$helpers.permission('api-auth/user/updatePassword2')"
  567. @click="resetPassWrod(scope.row)"
  568. type="text"
  569. >修改密码</el-button
  570. >
  571. <el-button
  572. v-if="
  573. scope.row.isSignedContract &&
  574. $helpers.permission('sysUserContracts/getLatest')
  575. "
  576. type="text"
  577. @click="lookContracts(scope.row)"
  578. >下载协议</el-button
  579. >
  580. </template>
  581. </el-table-column>
  582. </el-table>
  583. <pagination
  584. sync
  585. :total.sync="pageInfo.total"
  586. :page.sync="pageInfo.page"
  587. :limit.sync="pageInfo.limit"
  588. :page-sizes="pageInfo.page_size"
  589. @pagination="getList"
  590. />
  591. </div>
  592. </div>
  593. <el-dialog
  594. :title="maskName"
  595. width="700px"
  596. label-position="right"
  597. class="studentInfo"
  598. @close="onMaskClose('studentForm')"
  599. :close-on-click-modal="false"
  600. append-to-body
  601. :visible.sync="studentVisible"
  602. >
  603. <el-form
  604. :model="studentForm"
  605. :inline="true"
  606. label-width="130px"
  607. label-position="right"
  608. ref="studentForm"
  609. :rules="studentRules"
  610. >
  611. <el-alert
  612. title="基本信息"
  613. type="info"
  614. :closable="false"
  615. style="margin-bottom: 15px"
  616. ></el-alert>
  617. <el-form-item label="学生姓名" prop="name">
  618. <el-input v-model.trim="studentForm.name"></el-input>
  619. </el-form-item>
  620. <el-form-item label="学生性别" prop="sex">
  621. <el-select
  622. class="multiple"
  623. filterable
  624. v-model.trim="studentForm.sex"
  625. clearable
  626. placeholder="请选择性别"
  627. >
  628. <el-option :value="1" label="男"></el-option>
  629. <el-option :value="0" label="女"></el-option>
  630. </el-select>
  631. </el-form-item>
  632. <el-form-item label="出生日期" prop="date">
  633. <el-date-picker
  634. v-model.trim="studentForm.date"
  635. style="width: 185px"
  636. value-format="yyyy-MM-dd"
  637. type="date"
  638. :picker-options="{
  639. firstDayOfWeek: 1,
  640. }"
  641. placeholder="选择日期"
  642. ></el-date-picker>
  643. </el-form-item>
  644. <el-form-item label="学生声部" prop="subjectIdList">
  645. <el-select
  646. v-model.trim="studentForm.subjectIdList"
  647. filterable
  648. clearable
  649. placeholder="学员声部"
  650. >
  651. <el-option-group
  652. v-for="group in subjectList"
  653. :key="group.value"
  654. :label="group.label"
  655. >
  656. <el-option
  657. v-for="item in group.options"
  658. :key="item.value"
  659. :label="item.label"
  660. :value="item.value"
  661. ></el-option>
  662. </el-option-group>
  663. </el-select>
  664. </el-form-item>
  665. <el-form-item label="家长姓名" prop="parseName">
  666. <el-input
  667. v-model.trim="studentForm.parseName"
  668. :disabled="!isNew"
  669. ></el-input>
  670. </el-form-item>
  671. <el-form-item
  672. label="联系电话"
  673. prop="phone"
  674. :rules="[
  675. { required: true, message: '请输入手机号' },
  676. {
  677. pattern: /^1\d{10}$/,
  678. message: '请输入正确的手机号',
  679. trigger: 'blur',
  680. },
  681. ]"
  682. >
  683. <!-- @blur="checkPhone(studentForm.phone)" -->
  684. <el-input :maxlength="11" v-model.trim="studentForm.phone"></el-input>
  685. </el-form-item>
  686. <el-form-item label="所属分部" prop="organId">
  687. <el-select
  688. class="multiple"
  689. v-model.trim="studentForm.organId"
  690. filterable
  691. clearable
  692. placeholder="请选择分部"
  693. @change="changeStudentOrgan"
  694. >
  695. <el-option
  696. v-for="(item, index) in selects.branchs"
  697. :key="index"
  698. :label="item.name"
  699. :value="item.id"
  700. ></el-option>
  701. </el-select>
  702. </el-form-item>
  703. <el-form-item prop="school" label="所属学校">
  704. <el-select
  705. v-model.trim="studentForm.school"
  706. filterable
  707. clearable
  708. :disabled="!studentForm.organId"
  709. class="multiple"
  710. >
  711. <el-option
  712. v-for="(item, index) in cooperationList"
  713. :key="index"
  714. :label="item.name"
  715. :value="item.id"
  716. ></el-option>
  717. </el-select>
  718. </el-form-item>
  719. <el-form-item label="学员年级" prop="currentGradeNum">
  720. <el-select
  721. class="multiple"
  722. v-model.trim="studentForm.currentGradeNum"
  723. clearable
  724. filterable
  725. :disabled="!studentForm.organId"
  726. >
  727. <el-option
  728. v-for="(item, index) in studentGradeList"
  729. :label="item"
  730. :value="Number(index)"
  731. :key="index"
  732. ></el-option>
  733. </el-select>
  734. </el-form-item>
  735. <el-form-item label="学员班级" prop="currentClass">
  736. <el-select
  737. placeholder="班级"
  738. filterable
  739. clearable
  740. v-model.trim="studentForm.currentClass"
  741. style="width: 185px !important"
  742. >
  743. <el-option label="1班" value="1班"></el-option>
  744. <el-option label="2班" value="2班"></el-option>
  745. <el-option label="3班" value="3班"></el-option>
  746. <el-option label="4班" value="4班"></el-option>
  747. <el-option label="5班" value="5班"></el-option>
  748. <el-option label="6班" value="6班"></el-option>
  749. <el-option label="7班" value="7班"></el-option>
  750. <el-option label="8班" value="8班"></el-option>
  751. <el-option label="9班" value="9班"></el-option>
  752. <el-option label="10班" value="10班"></el-option>
  753. <el-option label="11班" value="11班"></el-option>
  754. <el-option label="12班" value="12班"></el-option>
  755. <el-option label="13班" value="13班"></el-option>
  756. <el-option label="14班" value="14班"></el-option>
  757. <el-option label="15班" value="15班"></el-option>
  758. <el-option label="16班" value="16班"></el-option>
  759. <el-option label="17班" value="17班"></el-option>
  760. <el-option label="18班" value="18班"></el-option>
  761. <el-option label="19班" value="19班"></el-option>
  762. <el-option label="20班" value="20班"></el-option>
  763. <el-option label="21班" value="21班"></el-option>
  764. <el-option label="22班" value="22班"></el-option>
  765. <el-option label="23班" value="23班"></el-option>
  766. <el-option label="24班" value="24班"></el-option>
  767. <el-option label="25班" value="25班"></el-option>
  768. <el-option label="26班" value="26班"></el-option>
  769. <el-option label="27班" value="27班"></el-option>
  770. <el-option label="28班" value="28班"></el-option>
  771. <el-option label="29班" value="29班"></el-option>
  772. <el-option label="30班" value="30班"></el-option>
  773. <el-option label="31班" value="31班"></el-option>
  774. <el-option label="32班" value="32班"></el-option>
  775. <el-option label="33班" value="33班"></el-option>
  776. <el-option label="34班" value="34班"></el-option>
  777. <el-option label="35班" value="35班"></el-option>
  778. <el-option label="36班" value="36班"></el-option>
  779. <el-option label="37班" value="37班"></el-option>
  780. <el-option label="38班" value="38班"></el-option>
  781. <el-option label="39班" value="39班"></el-option>
  782. <el-option label="40班" value="40班"></el-option>
  783. </el-select>
  784. <!-- <el-input
  785. v-model.trim="maskForm.course"
  786. placeholder="班级"
  787. ></el-input> -->
  788. </el-form-item>
  789. <!--
  790. <el-form-item label="指导老师" prop="teacherId">
  791. <el-select
  792. class="multiple"
  793. v-model.trim="studentForm.teacherId"
  794. clearable
  795. filterable
  796. :disabled="!studentForm.organId"
  797. >
  798. <el-option
  799. v-for="(item, index) in maskTeacherList"
  800. :label="item.realName"
  801. :value="item.id"
  802. :key="index"
  803. ></el-option>
  804. </el-select>
  805. </el-form-item> -->
  806. <el-alert
  807. title="运营信息"
  808. type="info"
  809. :closable="false"
  810. style="margin-bottom: 15px"
  811. ></el-alert>
  812. <el-form-item label="是否运营" prop="operatingTag" v-if="tenantId == 1">
  813. <el-select
  814. class="multiple"
  815. v-model.trim="studentForm.operatingTag"
  816. clearable
  817. >
  818. <el-option :value="1" label="是"></el-option>
  819. <el-option :value="0" label="否"></el-option>
  820. </el-select>
  821. </el-form-item>
  822. <el-form-item label="是否服务" prop="serviceTag" v-if="tenantId == 1">
  823. <el-select
  824. class="multiple"
  825. v-model.trim="studentForm.serviceTag"
  826. clearable
  827. >
  828. <el-option :value="1" label="是"></el-option>
  829. <el-option :value="0" label="否"></el-option>
  830. </el-select>
  831. </el-form-item>
  832. <el-form-item label="是否是新用户" prop="isNewUser">
  833. <template #label>
  834. <p style="position: relative; display: inline-block">
  835. 是否是新用户
  836. <el-tooltip placement="top" popper-class="mTooltip">
  837. <div slot="content">未购买VIP课程的学员为新用户</div>
  838. <i
  839. class="el-icon-question"
  840. style="font-size: 18px; color: #f56c6c"
  841. ></i>
  842. </el-tooltip>
  843. </p>
  844. </template>
  845. <el-select
  846. class="multiple"
  847. v-model.trim="studentForm.isNewUser"
  848. clearable
  849. >
  850. <el-option :value="1" label="是"></el-option>
  851. <el-option :value="0" label="否"></el-option>
  852. </el-select>
  853. </el-form-item>
  854. <el-form-item label="关心包" prop="carePackage">
  855. <el-select
  856. class="multiple"
  857. v-model.trim="studentForm.carePackage"
  858. clearable
  859. :disabled="!isNew && studentUpdatePackage.carePackage == 2"
  860. placeholder="请选择关心包"
  861. >
  862. <el-option label="不可用" :value="0"></el-option>
  863. <el-option label="可用" :value="1"></el-option>
  864. <el-option disabled label="已使用" :value="2"></el-option>
  865. </el-select>
  866. </el-form-item>
  867. <el-form-item label="加油包" prop="comeOnPackage">
  868. <el-select
  869. class="multiple"
  870. v-model.trim="studentForm.comeOnPackage"
  871. clearable
  872. :disabled="!isNew && studentUpdatePackage.comeOnPackage == 2"
  873. placeholder="请选择加油包"
  874. >
  875. <el-option label="不可用" :value="0"></el-option>
  876. <el-option label="可用" :value="1"></el-option>
  877. <el-option disabled label="已使用" :value="2"></el-option>
  878. </el-select>
  879. </el-form-item>
  880. </el-form>
  881. <div slot="footer" class="dialog-footer">
  882. <el-button @click="studentVisible = false">取 消</el-button>
  883. <el-button type="primary" v-if="isNew" @click="submitAddStudent"
  884. >确 定</el-button
  885. >
  886. <el-button type="primary" v-if="!isNew" @click="resetStudentSubmie"
  887. >确 定</el-button
  888. >
  889. </div>
  890. </el-dialog>
  891. <!-- 学员激活列表 -->
  892. <qr-code v-model="qrcodeStatus" title="学员激活列表" :codeUrl="qrcodeUrl" />
  893. <el-dialog
  894. title="修改密码"
  895. :visible.sync="passwrodVisiable"
  896. :before-close="closePassWord"
  897. width="400px"
  898. >
  899. <el-form :model="passwrodForm" ref="passwrodForm" :inline="true">
  900. <el-form-item
  901. label="手机号"
  902. prop="phone"
  903. label-width="120px"
  904. :rules="[
  905. { required: true, message: '手机号不能为空', trigger: 'blur' },
  906. {
  907. pattern: /^1\d{10}$/,
  908. message: '请输入正确的手机号',
  909. trigger: 'blur',
  910. },
  911. ]"
  912. >
  913. <copy-text>{{ passwrodForm.phone }}</copy-text>
  914. </el-form-item>
  915. <el-form-item
  916. label="输入密码"
  917. prop="password"
  918. label-width="120px"
  919. :rules="[
  920. { required: true, message: '密码不能为空', trigger: 'blur' },
  921. {
  922. pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/,
  923. message: '密码为6-20位数字和字母组合',
  924. trigger: 'blur',
  925. },
  926. ]"
  927. >
  928. <el-input v-model.trim="passwrodForm.password"></el-input>
  929. </el-form-item>
  930. <el-form-item
  931. label="再次输入"
  932. prop="password2"
  933. label-width="120px"
  934. :rules="[
  935. { required: true, message: '密码不能为空', trigger: 'blur' },
  936. {
  937. pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/,
  938. message: '密码为6-20位数字和字母组合',
  939. trigger: 'blur',
  940. },
  941. ]"
  942. >
  943. <el-input v-model.trim="passwrodForm.password2"></el-input>
  944. </el-form-item>
  945. </el-form>
  946. <span slot="footer" class="dialog-footer">
  947. <el-button @click="passwrodVisiable = false">取 消</el-button>
  948. <el-button type="primary" @click="submitResetPassWord">确 定</el-button>
  949. </span>
  950. </el-dialog>
  951. <el-dialog title="协议下载" :visible.sync="protocolVisible" width="650px">
  952. <protocol-model
  953. v-if="protocolVisible"
  954. @close="protocolVisible = false"
  955. :protocolVersions="protocolVersions"
  956. />
  957. </el-dialog>
  958. <el-dialog title="设置扩展分部" :visible.sync="extVisible" width="500px">
  959. <student-ext
  960. v-if="extVisible"
  961. :subjectList="subjectList"
  962. :detail="extDetail"
  963. @getList="getList"
  964. @close="extVisible = false"
  965. />
  966. </el-dialog>
  967. <el-dialog
  968. title="创建云教练缴费"
  969. width="500px"
  970. :visible.sync="memberVisible"
  971. >
  972. <createMember
  973. ref="addMember"
  974. v-if="memberVisible"
  975. :multipleSelection="multipleSelection"
  976. @close="memberVisible = false"
  977. @submited="getList"
  978. />
  979. <div slot="footer" class="dialog-footer">
  980. <el-button @click="memberVisible = false">取 消</el-button>
  981. <el-button type="primary" @click="submitAddMember">确 定</el-button>
  982. </div>
  983. </el-dialog>
  984. </div>
  985. </template>
  986. <script>
  987. import pagination from "@/components/Pagination/index";
  988. import protocolModel from "@/views/studentManager/modals/protocolModel";
  989. import {
  990. queryStudentList,
  991. getStudentInfoByPhone,
  992. registerStudent,
  993. updateStudent,
  994. getLatest,
  995. } from "@/api/studentManager";
  996. import { queryByOrganId } from "@/api/systemManage";
  997. import { getGradeList } from "@/views/2021memeberActionManager/api";
  998. import qrCode from "@/components/QrCode/index";
  999. import { vaildStudentUrl } from "@/utils/validate";
  1000. import { resetPassword2, getTeacher, getAgreement } from "@/api/buildTeam";
  1001. import {
  1002. organizationCloudTeacherFeeQueryPage,
  1003. subjectListTree,
  1004. } from "@/api/specialSetting";
  1005. import axios from "axios";
  1006. import qs from "qs";
  1007. import { getToken, getTenantId } from "@/utils/auth";
  1008. import load from "@/utils/loading";
  1009. import createMember from "./modals/createMember";
  1010. import studentExt from "./modals/studentExt";
  1011. import Tooltip from '@/components/Tooltip'
  1012. export default {
  1013. name: "studentManagerList",
  1014. components: { pagination, qrCode, createMember, protocolModel, studentExt,Tooltip },
  1015. data() {
  1016. return {
  1017. extVisible: false,
  1018. extDetail: {},
  1019. studentVisible: false,
  1020. searchForm: {
  1021. organId: [],
  1022. search: null,
  1023. studentName: null,
  1024. isActive: null,
  1025. hasCourse: null,
  1026. // isMake: null,
  1027. hasPracticeCourse: null,
  1028. operatingTag: null,
  1029. serviceTag: null,
  1030. teacherId: null,
  1031. carePackage: null,
  1032. comeOnPackage: null,
  1033. isNewUser: null,
  1034. hasTeacher: null,
  1035. isRecord: null,
  1036. hasMember:null
  1037. },
  1038. memberVisible: false,
  1039. multipleSelection: [],
  1040. searchList: [],
  1041. tableList: [],
  1042. organList: [],
  1043. teacherList: [],
  1044. maskTeacherList: [],
  1045. subjectList: [], // 声部列表
  1046. pageInfo: {
  1047. // 分页规则
  1048. limit: 10, // 限制显示条数
  1049. page: 1, // 当前页
  1050. total: 0, // 总条数
  1051. page_size: [10, 20, 40, 50], // 选择限制显示条数
  1052. },
  1053. studentForm: {
  1054. phone: "",
  1055. organId: [],
  1056. name: "",
  1057. sex: "",
  1058. parseName: "",
  1059. date: "",
  1060. serviceTag: null,
  1061. operatingTag: null,
  1062. teacherId: null,
  1063. subjectIdList: null,
  1064. isNewUser: 1,
  1065. carePackage: 0,
  1066. comeOnPackage: 0,
  1067. school: null,
  1068. currentClass: "",
  1069. currentGradeNum: "",
  1070. },
  1071. studentUpdatePackage: {
  1072. carePackage: 0,
  1073. comeOnPackage: 0,
  1074. },
  1075. studentRules: {
  1076. name: [{ required: true, message: "请输入学生姓名" }],
  1077. sex: [{ required: true, message: "请选择学生性别" }],
  1078. date: [{ required: true, message: "请选择出生日期" }],
  1079. organId: [{ required: true, message: "请选择分部" }],
  1080. subjectIdList: [{ required: true, message: "请选择声部" }],
  1081. serviceTag: [{ required: true, message: "请选择是否参与服务" }],
  1082. isNewUser: [{ required: true, message: "请选择是否是新用户" }],
  1083. operatingTag: [{ required: true, message: "请选择是否参与运营" }],
  1084. teacherId: [{ required: true, message: "请选择指导老师" }],
  1085. },
  1086. isNew: false,
  1087. active: null,
  1088. maskName: "新增学员",
  1089. qrcodeStatus: false,
  1090. qrcodeUrl: null,
  1091. activeRow: null,
  1092. passwrodVisiable: false,
  1093. passwrodForm: {
  1094. phone: "",
  1095. password: "",
  1096. password2: "",
  1097. },
  1098. activatedRow: null,
  1099. protocolVisible: false,
  1100. protocolVersions: [],
  1101. cooperationList: [],
  1102. tenantId: null,
  1103. studentGradeList: [],
  1104. };
  1105. },
  1106. mounted() {
  1107. if (this.$route.params.search) {
  1108. this.searchForm.search = this.$route.params.search;
  1109. }
  1110. if (this.$route.params.teacherId) {
  1111. this.searchForm.teacherId = this.$route.params.teacherId;
  1112. }
  1113. if (this.$route.params.hasTeacher) {
  1114. this.searchForm.hasTeacher = this.$route.params.hasTeacher;
  1115. }
  1116. if (this.$route.params.organId) {
  1117. this.searchForm.organId = [];
  1118. this.searchForm.organId = this.searchForm.organId.push(
  1119. this.$route.params.organId
  1120. );
  1121. }
  1122. this.$store.dispatch("setBranchs");
  1123. this.$store.dispatch("setTeachers");
  1124. this.getList();
  1125. this.getAgreement();
  1126. this.tenantId = this.$helpers.tenantId;
  1127. },
  1128. methods: {
  1129. async getAgreement() {
  1130. try {
  1131. const res = await getAgreement();
  1132. if (!res.data) {
  1133. this.$bus.$emit("showguide", ["agreement"]);
  1134. }
  1135. } catch (e) {}
  1136. },
  1137. handleSelectionChange(val) {
  1138. this.multipleSelection = val;
  1139. },
  1140. submitAddMember() {
  1141. this.$refs.addMember.submit();
  1142. },
  1143. addStudentMember() {
  1144. if (this.multipleSelection.length > 0) {
  1145. let organIds = [];
  1146. this.multipleSelection.forEach((m) => {
  1147. if (!organIds.includes(m.organId)) {
  1148. organIds.push(m.organId);
  1149. }
  1150. });
  1151. if (organIds.length == 1) {
  1152. this.memberVisible = true;
  1153. } else {
  1154. this.$message.error("所选学员只能是同一分部");
  1155. }
  1156. } else {
  1157. this.$message.error("请至少选择一名学员");
  1158. }
  1159. },
  1160. onSearch() {
  1161. this.pageInfo.page = 1;
  1162. this.getList();
  1163. },
  1164. onCreateQRCode() {
  1165. // 生成报名二维码
  1166. this.qrcodeStatus = true;
  1167. this.qrcodeUrl =
  1168. vaildStudentUrl() + `/#/queryStudentPer?tenantId=` + this.tenantId;
  1169. },
  1170. getList() {
  1171. let params = { ...this.searchForm };
  1172. params.rows = this.pageInfo.limit;
  1173. params.page = this.pageInfo.page;
  1174. params.organId = this.searchForm.organId.join(",");
  1175. queryStudentList(params).then((res) => {
  1176. if (res.code == 200) {
  1177. this.tableList = res.data.rows;
  1178. this.pageInfo.total = res.data.total;
  1179. }
  1180. });
  1181. },
  1182. onReSet() {
  1183. this.searchForm = {
  1184. organId: [],
  1185. search: null,
  1186. studentName: null,
  1187. isActive: null,
  1188. hasCourse: null,
  1189. // isMake: null,
  1190. hasPracticeCourse: null,
  1191. operatingTag: null,
  1192. serviceTag: null,
  1193. teacherId: null,
  1194. };
  1195. this.getList();
  1196. },
  1197. downLoadStudent() {
  1198. let url = "/api-web/export/studentHasCourse";
  1199. let searchForm = this.searchForm;
  1200. let data = {
  1201. organId: searchForm.organId.join(","),
  1202. search: searchForm.search + "" ? searchForm.search : null,
  1203. isActive: searchForm.isActive + "" ? searchForm.isActive : null,
  1204. hasCourse: searchForm.hasCourse == "" ? null : searchForm.hasCourse,
  1205. // isMake: searchForm.isMake ? searchForm.isMake : null,
  1206. hasPracticeCourse:
  1207. searchForm.hasPracticeCourse + ""
  1208. ? searchForm.hasPracticeCourse
  1209. : null,
  1210. operatingTag:
  1211. searchForm.operatingTag + "" ? searchForm.operatingTag : null,
  1212. serviceTag: searchForm.serviceTag + "" ? searchForm.serviceTag : null,
  1213. teacherId: searchForm.teacherId + "" ? searchForm.teacherId : null,
  1214. carePackage:
  1215. searchForm.carePackage + "" ? searchForm.carePackage : null,
  1216. comeOnPackage:
  1217. searchForm.comeOnPackage + "" ? searchForm.comeOnPackage : null,
  1218. isNewUser: searchForm.isNewUser + "" ? searchForm.isNewUser : null,
  1219. hasTeacher: searchForm.hasTeacher + "" ? searchForm.hasTeacher : null,
  1220. isRecord: searchForm.isRecord + "" ? searchForm.isRecord : null,
  1221. hasMember:searchForm.hasMember+""?searchForm.hasMember:null
  1222. };
  1223. const options = {
  1224. method: "POST",
  1225. headers: {
  1226. Authorization: getToken(),
  1227. tenantId: getTenantId(),
  1228. },
  1229. url,
  1230. data: qs.stringify(data),
  1231. responseType: "blob",
  1232. };
  1233. this.$confirm("确定导出学员名单?", "提示", {
  1234. confirmButtonText: "确定",
  1235. cancelButtonText: "取消",
  1236. type: "warning",
  1237. })
  1238. .then(() => {
  1239. load.startLoading();
  1240. axios(options)
  1241. .then((res) => {
  1242. let blob = new Blob([res.data], {
  1243. // type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8',
  1244. type: "application/vnd.ms-excel;charset=utf-8",
  1245. // word文档为application/msword,pdf文档为application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
  1246. });
  1247. let text = new Response(blob).text();
  1248. text.then((res) => {
  1249. // 判断是否报错
  1250. if (res.indexOf("code") != -1) {
  1251. let json = JSON.parse(res);
  1252. if (json.code == 403) {
  1253. this.$message.error(`登录过期,请重新登录!`);
  1254. setTimeout(() => {
  1255. this.$store.dispatch("user/resetToken").then(() => {
  1256. location.reload();
  1257. });
  1258. }, 1000);
  1259. return;
  1260. }
  1261. this.$message.error(json.msg);
  1262. } else {
  1263. let objectUrl = URL.createObjectURL(blob);
  1264. let link = document.createElement("a");
  1265. let nowTime = new Date();
  1266. let ymd =
  1267. nowTime.getFullYear() +
  1268. (nowTime.getMonth() + 1) +
  1269. nowTime.getDate();
  1270. let fname = `导出学员名单` + ymd + ".xls"; //下载文件的名字
  1271. link.href = objectUrl;
  1272. link.setAttribute("download", fname);
  1273. document.body.appendChild(link);
  1274. link.click();
  1275. }
  1276. });
  1277. load.endLoading();
  1278. })
  1279. .catch((error) => {
  1280. this.$message.error("导出数据失败,请联系管理员");
  1281. load.endLoading();
  1282. });
  1283. })
  1284. .catch(() => {});
  1285. },
  1286. checkPhone(val) {
  1287. var regu = /^1\d{10}$/;
  1288. var re = new RegExp(regu);
  1289. if (re.test(val)) {
  1290. getStudentInfoByPhone({ mobile: this.studentForm.phone }).then(
  1291. (res) => {
  1292. if (res.code == 200) {
  1293. if (res.data) {
  1294. this.studentForm = {
  1295. name: res.data.name,
  1296. sex: res.data.gender,
  1297. parseName: res.data.parentsName,
  1298. // sound: parseInt(res.data.subjectIdList),
  1299. phone: val,
  1300. date: res.data.birthdate,
  1301. };
  1302. }
  1303. }
  1304. }
  1305. );
  1306. }
  1307. },
  1308. submitAddStudent() {
  1309. const studentForm = this.studentForm;
  1310. // 效验 然后组数据提交
  1311. this.$refs["studentForm"].validate((item) => {
  1312. if (item) {
  1313. let obj = {
  1314. phone: studentForm.phone,
  1315. username: studentForm.name,
  1316. gender: studentForm.sex,
  1317. realName: studentForm.parseName,
  1318. birthdate: studentForm.date,
  1319. organId: studentForm.organId,
  1320. serviceTag: studentForm.serviceTag,
  1321. operatingTag: studentForm.operatingTag,
  1322. teacherId: studentForm.teacherId,
  1323. isNewUser: studentForm.isNewUser,
  1324. subjectIdList: studentForm.subjectIdList,
  1325. carePackage: studentForm.carePackage,
  1326. comeOnPackage: studentForm.comeOnPackage,
  1327. cooperationOrganId: studentForm.school,
  1328. currentClass: studentForm.currentClass,
  1329. currentGradeNum: studentForm.currentGradeNum,
  1330. };
  1331. registerStudent(obj).then((res) => {
  1332. if (res.code == 200) {
  1333. this.$message.success("添加成功");
  1334. this.studentVisible = false;
  1335. this.getList();
  1336. }
  1337. });
  1338. }
  1339. });
  1340. },
  1341. // 修改学生信息
  1342. resetStudentSubmie() {
  1343. const studentForm = this.studentForm;
  1344. this.$refs["studentForm"].validate((item) => {
  1345. if (item) {
  1346. let obj = {
  1347. phone: studentForm.phone,
  1348. username: studentForm.name,
  1349. gender: studentForm.sex,
  1350. realName: studentForm.parseName,
  1351. birthdate: studentForm.date,
  1352. organId: studentForm.organId,
  1353. id: this.active.userId,
  1354. serviceTag: studentForm.serviceTag,
  1355. operatingTag: studentForm.operatingTag,
  1356. teacherId: studentForm.teacherId,
  1357. isNewUser: studentForm.isNewUser,
  1358. subjectIdList: studentForm.subjectIdList,
  1359. carePackage: studentForm.carePackage,
  1360. comeOnPackage: studentForm.comeOnPackage,
  1361. cooperationOrganId: studentForm.school,
  1362. currentClass: studentForm.currentClass,
  1363. currentGradeNum: studentForm.currentGradeNum,
  1364. };
  1365. updateStudent(obj).then((res) => {
  1366. if (res.code == 200) {
  1367. this.$message.success("修改成功");
  1368. this.studentVisible = false;
  1369. this.getList();
  1370. }
  1371. });
  1372. }
  1373. });
  1374. },
  1375. async getSubjectList() {
  1376. try {
  1377. await subjectListTree({
  1378. delFlag: "NO",
  1379. rows: 9999,
  1380. }).then((res) => {
  1381. let result = res.data;
  1382. if (res.code == 200) {
  1383. let tempArray = [];
  1384. console.log(result.rows,'result')
  1385. result.rows.forEach((item, index) => {
  1386. let subject = [];
  1387. let nowSubject = item.subjects || []
  1388. nowSubject.forEach((s) => {
  1389. subject.push({
  1390. value: s.id,
  1391. label: s.name,
  1392. });
  1393. });
  1394. tempArray[index] = {
  1395. label: item.name,
  1396. value: item.id,
  1397. options: subject,
  1398. };
  1399. });
  1400. this.subjectList = tempArray;
  1401. }
  1402. });
  1403. // 获取 学生年级
  1404. } catch (e) {
  1405. console.log(e)
  1406. }
  1407. },
  1408. async getStudentGradeList(organId) {
  1409. try {
  1410. const res = await getGradeList({ id: organId });
  1411. this.studentGradeList = res.data;
  1412. } catch (e) {
  1413. console.log(e);
  1414. }
  1415. },
  1416. async addStudent() {
  1417. await this.getSubjectList();
  1418. this.isNew = true;
  1419. this.studentVisible = true;
  1420. this.maskName = "新增学员";
  1421. },
  1422. async resetStudent(row) {
  1423. this.studentVisible = true;
  1424. let organId = row.organId;
  1425. await this.getSubjectList();
  1426. await this.changeStudentOrgan(row.organId);
  1427. this.isNew = false;
  1428. this.active = row;
  1429. this.maskName = "修改学员";
  1430. this.$nextTick(() => {
  1431. this.studentForm = {
  1432. phone: row.parentsPhone || null,
  1433. name: row.username || null,
  1434. sex: row.gender,
  1435. parseName: row.realName || null,
  1436. date: row.birthdate || null,
  1437. organId: row.organId || null,
  1438. serviceTag: row.serviceTag,
  1439. operatingTag: row.operatingTag,
  1440. teacherId: row.teacherId || null,
  1441. isNewUser: row.isNewUser,
  1442. subjectIdList: Number(row.subjectIdList) || null,
  1443. carePackage: row.carePackage,
  1444. comeOnPackage: row.comeOnPackage,
  1445. school: row.cooperationOrganId || null,
  1446. extSubjectIds: row.extSubjectIds || null,
  1447. currentClass: row.currentClass || null,
  1448. currentGradeNum: row.currentGradeNum || null,
  1449. };
  1450. this.studentUpdatePackage = {
  1451. carePackage: row.carePackage,
  1452. comeOnPackage: row.comeOnPackage,
  1453. };
  1454. });
  1455. },
  1456. async setStudent(row) {
  1457. // 设置扩展分部
  1458. await this.getSubjectList();
  1459. this.extDetail = {
  1460. id: row.userId,
  1461. phone: row.parentsPhone || null,
  1462. name: row.username || null,
  1463. sex: row.gender,
  1464. parseName: row.realName || null,
  1465. date: row.birthdate || null,
  1466. organId: row.organId || null,
  1467. serviceTag: row.serviceTag,
  1468. operatingTag: row.operatingTag,
  1469. teacherId: row.teacherId || null,
  1470. isNewUser: row.isNewUser,
  1471. subjectIdList: Number(row.subjectIdList) || null,
  1472. carePackage: row.carePackage,
  1473. comeOnPackage: row.comeOnPackage,
  1474. cooperationOrganId: row.cooperationOrganId || null,
  1475. extSubjectIds: row.extSubjectIds,
  1476. };
  1477. this.extVisible = true;
  1478. },
  1479. onMaskClose(formName) {
  1480. this.$refs[formName].resetFields();
  1481. },
  1482. resetPassWrod(row) {
  1483. this.activatedRow = row;
  1484. this.passwrodForm.phone = row.parentsPhone;
  1485. this.passwrodVisiable = true;
  1486. },
  1487. closePassWord() {
  1488. this.activatedRow = null;
  1489. this.passwrodForm = {
  1490. phone: "",
  1491. password: "",
  1492. password2: "",
  1493. };
  1494. this.$refs["passwrodForm"].resetFields();
  1495. this.passwrodVisiable = false;
  1496. },
  1497. submitResetPassWord() {
  1498. if (this.passwrodForm.password !== this.passwrodForm.password2) {
  1499. this.$message.error("两次密码必须相同");
  1500. return;
  1501. }
  1502. this.$refs["passwrodForm"].validate((res) => {
  1503. if (res) {
  1504. // 发请求
  1505. resetPassword2({
  1506. mobile: this.passwrodForm.phone,
  1507. newPassword: this.passwrodForm.password,
  1508. userId: this.activatedRow.userId,
  1509. }).then((res) => {
  1510. if (res.code == 200) {
  1511. // 修改成功
  1512. this.$message.success("修改成功");
  1513. this.closePassWord();
  1514. }
  1515. });
  1516. }
  1517. });
  1518. },
  1519. async changeStudentOrgan(val) {
  1520. this.studentForm.teacherId = null;
  1521. this.studentForm.school = null;
  1522. if (val) {
  1523. await getTeacher({ organId: val }).then((res) => {
  1524. if (res.code == 200) {
  1525. this.maskTeacherList = res.data;
  1526. if (this.maskTeacherList <= 0) {
  1527. this.$nextTick(() => {
  1528. this.$bus.$emit("showguide", ["teacher"]);
  1529. });
  1530. }
  1531. }
  1532. });
  1533. queryByOrganId({ organId: val }).then((res) => {
  1534. if (res.code == 200) {
  1535. this.cooperationList = res.data;
  1536. }
  1537. });
  1538. this.getStudentGradeList(val);
  1539. } else {
  1540. this.maskTeacherList = [];
  1541. }
  1542. },
  1543. async lookContracts(row) {
  1544. await getLatest({ userId: row.userId }).then((res) => {
  1545. if (res.code == 200) {
  1546. if (res.data) {
  1547. this.protocolVersions = res.data;
  1548. this.protocolVisible = true;
  1549. }
  1550. }
  1551. });
  1552. },
  1553. checkDate(dateStr) {
  1554. let dayjs = this.$helpers.dayjs;
  1555. let nowDate = new Date().getTime();
  1556. return nowDate - dayjs(dateStr).valueOf() < 0;
  1557. },
  1558. },
  1559. };
  1560. </script>
  1561. <style lang="scss" scoped>
  1562. .newBand {
  1563. display: inline-block;
  1564. margin-right: 10px;
  1565. }
  1566. .right-code {
  1567. // width: 50%;
  1568. // float: left;
  1569. .title {
  1570. font-size: 18px;
  1571. text-align: center;
  1572. padding-bottom: 8px;
  1573. }
  1574. }
  1575. ::v-deep .studentInfo {
  1576. .multiple.el-select {
  1577. width: 185px !important;
  1578. }
  1579. }
  1580. .red {
  1581. color: red;
  1582. }
  1583. .demo-table-expand {
  1584. // font-size: 0;
  1585. }
  1586. .demo-table-expand label {
  1587. width: 150px;
  1588. color: #99a9bf;
  1589. }
  1590. .demo-table-expand .el-form-item {
  1591. margin-right: 0;
  1592. margin-bottom: 0;
  1593. overflow: hidden;
  1594. text-overflow: ellipsis;
  1595. white-space: nowrap;
  1596. padding-right: 10px;
  1597. position: relative;
  1598. }
  1599. .demo-table-expand .el-form-item__label {
  1600. z-index: 100;
  1601. }
  1602. ::v-deep .el-table__expanded-cell[class*="cell"] {
  1603. padding: 20px 0 20px 110px;
  1604. }
  1605. .schoolWrap {
  1606. // width: calc(100% - 75px) !important;
  1607. overflow: hidden;
  1608. text-overflow: ellipsis;
  1609. white-space: nowrap;
  1610. }
  1611. </style>