studentList.vue 57 KB

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