Student.vue 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. <style lang="less" scoped>
  2. @import "./Student.less";
  3. .loginDiv {
  4. background: rgba(75, 112, 136, 0.5);
  5. border-radius: 20px;
  6. overflow: hidden;
  7. margin-top: -100px;
  8. }
  9. .left-box {
  10. padding: 0px 55px;
  11. height: 400px;
  12. display: flex;
  13. align-items: center;
  14. justify-content: center;
  15. flex-direction: column;
  16. box-shadow: 2px 0px 15px 5px rgba(35, 57, 71, 0.3);
  17. }
  18. .right-box {
  19. padding: 40px 120px;
  20. // box-shadow: -2px 0px 15px 0px rgba(75, 113, 136, 0.9);
  21. display: flex;
  22. height: 400px;
  23. min-width: 600px;
  24. }
  25. .student-login-img {
  26. width: 180px;
  27. }
  28. .teacher-login-title {
  29. color: white;
  30. font-size: 40px;
  31. }
  32. .teacher-login-decr {
  33. color: white;
  34. font-size: 17px;
  35. font-weight: 200;
  36. }
  37. .loginForm {
  38. margin: auto;
  39. margin-top: 30px;
  40. width: 300px;
  41. }
  42. .formItem {
  43. margin-bottom: 8px;
  44. }
  45. .form-bottom {
  46. color: white;
  47. font-size: 12px;
  48. margin-top: -12px;
  49. padding: 0px 5px;
  50. }
  51. .form-bottom-link {
  52. float: right;
  53. margin-left: 10px;
  54. }
  55. .qrcode-login {
  56. cursor: pointer;
  57. }
  58. .other-login-box {
  59. display: flex;
  60. margin-top: 25px;
  61. }
  62. .other-login-item {
  63. width: 50%;
  64. color: white;
  65. text-align: center;
  66. cursor: pointer;
  67. }
  68. .other-login-icon {
  69. font-size: 50px;
  70. display: block;
  71. }
  72. .school-login-box {
  73. margin-left: 35px;
  74. }
  75. .tmd-login-box {
  76. margin-right: 35px;
  77. }
  78. .client-label {
  79. color: white;
  80. font-size: 30px;
  81. text-align: center;
  82. margin-top: -20px;
  83. margin-left: -7px;
  84. }
  85. </style>
  86. <style lang="less">
  87. .login-input-box .ivu-input,
  88. .login-input-box .ivu-select-selection {
  89. border-radius: 25px;
  90. line-height: 35px;
  91. height: 35px;
  92. padding: 0px 15px;
  93. }
  94. .login-input-box .ivu-input-prefix i,
  95. .login-input-box .ivu-input-suffix i {
  96. line-height: 35px;
  97. }
  98. .loginBox {
  99. .loginForm {
  100. .formItem {
  101. input,
  102. select {
  103. border-radius: 0;
  104. font-size: 12px;
  105. }
  106. .ivu-select-selection {
  107. border-radius: 0;
  108. }
  109. }
  110. .schoolAutoComplete {
  111. height: 170px;
  112. .schoolsBox {
  113. border-bottom: 1px solid #e9e9e9;
  114. padding: 5px 5px 5px 15px;
  115. .area {
  116. font-size: 12px;
  117. padding: 5px;
  118. }
  119. }
  120. }
  121. .ivu-select-dropdown {
  122. border-radius: 0;
  123. }
  124. }
  125. }
  126. .identityModal {
  127. .ivu-modal {
  128. .ivu-modal-content {
  129. background-color: #2a292e;
  130. padding: 12px;
  131. border: 1px solid #ccc;
  132. .ivu-modal-header,
  133. .ivu-modal-footer {
  134. border: 0;
  135. }
  136. .ivu-modal-footer {
  137. padding: 0;
  138. }
  139. .ivu-modal-header {
  140. padding: 5px 16px;
  141. p {
  142. color: whitesmoke;
  143. }
  144. }
  145. .identity-body {
  146. display: flex;
  147. justify-content: space-around;
  148. align-items: center;
  149. .ivu-btn {
  150. background-color: #1cc0f2;
  151. color: white;
  152. font-weight: bold;
  153. border: 0;
  154. padding: 0 22px;
  155. }
  156. }
  157. }
  158. }
  159. }
  160. .demo-spin-col .ivu-spin-main {
  161. background-color: transparent;
  162. padding: 0;
  163. }
  164. </style>
  165. <template>
  166. <div class="loginDiv">
  167. <div class="left-box">
  168. <!-- 这张图片需要裁剪顶部 -->
  169. <img src="@/assets/login/2-1.png" class="student-login-img" style="margin-top:-30px">
  170. <p class="client-label">学生端</p>
  171. </div>
  172. <div class="right-box">
  173. <div v-show="!qrloginFlag" class="tmd-login-box">
  174. <p class="teacher-login-title">醍摩豆账号登录</p>
  175. <p class="teacher-login-decr">系统管理者、教师、学生与家长登录</p>
  176. <Form class="loginForm" ref="loginForm" :model="loginForm" :rules="loginRule" :show-message="false" @keydown.enter.native="loginSubmit('loginForm')">
  177. <FormItem class="formItem" prop="id">
  178. <Input class="login-input-box" element-id="tmdID" v-model="loginForm.id" :placeholder="$t('login.placeholder.id')" />
  179. </FormItem>
  180. <FormItem class="formItem" prop="pass">
  181. <Input class="login-input-box" element-id="tmdpw" type="password" v-model="loginForm.pass" :placeholder="$t('login.placeholder.psw')">
  182. <Icon size="24" v-show="!loading && loginFormEnter" @click="loginSubmit('loginForm')" type="md-arrow-forward" slot="suffix" class="iconFrame" />
  183. <div v-show="loading" class="demo-spin-col" slot="suffix">
  184. <Spin>
  185. <Icon type="ios-loading" size="18" class="demo-spin-icon-load"></Icon>
  186. </Spin>
  187. </div>
  188. </Input>
  189. </FormItem>
  190. <div class="errlable">{{ loginErrText }}</div>
  191. </Form>
  192. <p class="form-bottom">
  193. <span class="qrcode-login" @click="chgLoginType()">
  194. <Icon size="14" custom="iconfont icon-qr-code" style="vertical-align: text-bottom;" />
  195. {{ $t('login.link.QRLogin') }}
  196. </span>
  197. <router-link to="/regist" class="form-bottom-link">
  198. {{$t('login.link.regist')}}
  199. </router-link>
  200. <router-link to="/forgotpw" href="" class="form-bottom-link">
  201. {{$t('login.link.forgetPsw')}}
  202. </router-link>
  203. </p>
  204. <div class="other-login-box">
  205. <div style="margin:auto" class="other-login-item" v-if="!(srvAdr == 'Global')" @click="oauthLogin('wechat')">
  206. <Icon custom="iconfont icon-wechat" class="other-login-icon" />
  207. <p class="other-login-text">或使用第三方平台登录</p>
  208. </div>
  209. </div>
  210. </div>
  211. <div v-show="qrloginFlag" class="tmd-login-box" style="width:300px;">
  212. <div style="width:fit-content;margin: auto;">
  213. <div class="title">
  214. <div class="logo">
  215. <img width="15" height="15" src="@/assets/icon/tmd_account.svg">
  216. </div>
  217. <h4 class="text">
  218. {{ qrloginFlag ? $t('login.title.QRLogin'): $t('login.title.IDLogin') }}
  219. </h4>
  220. <Tooltip class="tooltip" placement="right-end" :transfer="true" max-width="200">
  221. <img src="@/assets/icon/icon_info.svg" width="15" height="15">
  222. <div slot="content">
  223. <p style="font-size: 12px;">{{ $t('login.tooltip.text1') }}</p>
  224. </div>
  225. </Tooltip>
  226. </div>
  227. <h4 class="subTitle">
  228. {{ qrloginFlag ? $t('login.subTitle.QRLogin') : $t('login.subTitle.IDLogin')}}
  229. </h4>
  230. <div class="qrloginMode">
  231. <div class="qrcodeBox">
  232. <div id="qrcode" :class="{'qrcode': joinQRcode != undefined}" ref="qrcode"></div>
  233. <div class="expired" v-if="joinQRcode != undefined && !sseSurvive">
  234. <Icon size="40" type="md-refresh-circle" @click="SEELink()" />
  235. </div>
  236. </div>
  237. <div class="links">
  238. <div class="icon-a">
  239. <a @click="chgLoginType()">{{ $t('login.link.IDLogin') }}</a>
  240. </div>
  241. <router-link to="/regist">{{ $t('login.link.regist') }}</router-link>
  242. </div>
  243. </div>
  244. </div>
  245. </div>
  246. <div class="school-login-box">
  247. <p class="teacher-login-title">校内账号登入</p>
  248. <p class="teacher-login-decr">学校分配给学生使用的账号</p>
  249. <Form class="loginForm" ref="studForm" :model="studForm" :rules="studRule" :show-message="false" @keydown.enter.native="loginSubmit('studForm')">
  250. <FormItem class="formItem" prop="schoolCode">
  251. <Select class="login-input-box" v-show="!defaultSchool.code" v-model="studForm.schoolCode" :placeholder="$t('login.placeholder.schoolMenu')" filterable clearable>
  252. <template v-for="(item, index) in schoolList">
  253. <OptionGroup :label="item.province" :key="index">
  254. <Option v-for="school in item.schools" :key="school.id" :value="school.id">{{ school.name }}</Option>
  255. </OptionGroup>
  256. </template>
  257. </Select>
  258. </FormItem>
  259. <FormItem class="formItem" prop="id">
  260. <Input class="login-input-box" element-id="studId" v-model="studForm.id" :placeholder="$t('login.placeholder.schoolID')" />
  261. <input type="text" style="position:fixed;z-index:-10000;width:0;border:none" />
  262. </FormItem>
  263. <FormItem class="formItem" prop="pass">
  264. <input type="password" style="position:fixed;z-index:-10000;width:0;border:none" />
  265. <Input class="login-input-box" element-id="studpw" type="password" v-model="studForm.pass" :placeholder="$t('login.placeholder.schoolPsw')">
  266. <Icon size="24" v-show="!loading && studFormEnter" @click="loginSubmit('studForm')" type="md-arrow-forward" slot="suffix" class="iconFrame" />
  267. <div v-show="loading" class="demo-spin-col" slot="suffix">
  268. <Spin>
  269. <Icon type="ios-loading" size="18" class="demo-spin-icon-load"></Icon>
  270. </Spin>
  271. </div>
  272. </Input>
  273. </FormItem>
  274. <div class="errlable">{{ schoolErrText }}</div>
  275. </Form>
  276. </div>
  277. </div>
  278. <!-- <div class="schoolName">
  279. <div style="width: 100px;height: 100px;background-color: #69b0d0;border-radius: 4px;cursor: pointer;">
  280. <img style="display: block;width: 100%;height: 100%;" src="@/assets/icon/studentIcon.png">
  281. </div>
  282. </div>
  283. <div class="formDiv">
  284. <div class="loginBox">
  285. <div class="title">
  286. <div class="logo">
  287. <img width="15" height="15" src="@/assets/icon/tmd_account.svg">
  288. </div>
  289. <h4 class="text">
  290. {{ qrloginFlag ? $t('login.title.QRLogin'): $t('login.title.IDLogin') }}
  291. </h4>
  292. <Tooltip class="tooltip" placement="right-end" :transfer="true" max-width="200">
  293. <img src="@/assets/icon/icon_info.svg" width="15" height="15">
  294. <div slot="content">
  295. <p style="font-size: 12px;">{{ $t('login.tooltip.text1') }}</p>
  296. </div>
  297. </Tooltip>
  298. </div>
  299. <h4 class="subTitle">
  300. {{ qrloginFlag ? $t('login.subTitle.QRLogin') : $t('login.subTitle.IDLogin')}}
  301. </h4>
  302. <div v-show="!qrloginFlag">
  303. <Form class="loginForm" ref="loginForm" :model="loginForm" :rules="loginRule" :show-message="false" @keydown.enter.native="loginSubmit('loginForm')">
  304. <FormItem class="formItem" prop="id" >
  305. <Input element-id = "tmdID" v-model="loginForm.id" :placeholder="$t('login.placeholder.id')"/>
  306. </FormItem>
  307. <FormItem class="formItem" prop="pass">
  308. <Input element-id = "tmdpw" type="password" v-model="loginForm.pass" :placeholder="$t('login.placeholder.psw')" >
  309. <Icon size="24" v-show="!loading && loginFormEnter" @click="loginSubmit('loginForm')" type="md-arrow-forward" slot="suffix" class="iconFrame" />
  310. <div v-show="loading" class="demo-spin-col" slot="suffix">
  311. <Spin>
  312. <Icon type="ios-loading" size="18" class="demo-spin-icon-load"></Icon>
  313. </Spin>
  314. </div>
  315. </Input>
  316. </FormItem>
  317. <div class="errlable">{{ loginErrText }}</div>
  318. </Form>
  319. <div class="extra">
  320. <div class="qrlogin">
  321. <div class="logo">
  322. <img width="15" height="15" src="@/assets/icon/icon_qrcode.svg">
  323. </div>
  324. <a @click="chgLoginType()">{{ $t('login.link.QRLogin') }}</a>
  325. </div>
  326. <div class="link">
  327. <router-link to="/regist">{{ $t('login.link.regist') }}</router-link> | <router-link to="/forgotpw">{{ $t('login.link.forgetPsw') }}</router-link>
  328. </div>
  329. </div>
  330. <div class="communyLoging">
  331. <div class="description">{{ $t('login.communy.title')}}</div>
  332. <div class="links">
  333. <div v-if="!(srvAdr == 'China')" class="icon" @click="oauthLogin('facebook')">
  334. <img src="@/assets/icon/icon_fb.svg">
  335. <span>{{ $t('login.communy.fb')}}</span>
  336. </div>
  337. <div v-if="!(srvAdr == 'China')" class="icon" @click="oauthLogin('google')">
  338. <img src="@/assets/icon/icon_google.svg">
  339. <span>{{ $t('login.communy.google')}}</span>
  340. </div>
  341. <div v-if="!(srvAdr == 'Global')" class="icon" @click="oauthLogin('wechat')">
  342. <img src="@/assets/icon/icon_wechat.svg">
  343. <span>{{ $t('login.communy.wechat')}}</span>
  344. </div>
  345. </div>
  346. </div>
  347. </div>
  348. <div v-show="qrloginFlag">
  349. <div class="qrloginMode">
  350. <div class="qrcodeBox">
  351. <div id="qrcode" :class="{'qrcode': joinQRcode != undefined}" ref="qrcode"></div>
  352. <div class="expired" v-if="joinQRcode != undefined && !sseSurvive">
  353. <Icon size="40" type="md-refresh-circle" @click="SEELink()" />
  354. </div>
  355. </div>
  356. <div class="links">
  357. <div class="icon-a">
  358. <img src="@/assets/icon/icon_account.svg">
  359. <a @click="chgLoginType()">{{ $t('login.link.IDLogin') }}</a>
  360. </div>
  361. <router-link to="/regist">{{ $t('login.link.regist') }}</router-link>
  362. </div>
  363. </div>
  364. </div>
  365. </div>
  366. <div class="loginBox">
  367. <div class="title">
  368. <div class="logo">
  369. <img width="15" height="15" src="@/assets/icon/tmd_account.svg">
  370. </div>
  371. <h4 class="text">{{ $t('login.title.schoolLogin') }}</h4>
  372. <Tooltip class="tooltip" placement="right-end" :transfer="true" max-width="200">
  373. <img src="@/assets/icon/icon_info.svg" width="15" height="15">
  374. <div slot="content">
  375. <p style="font-size: 12px;">{{ $t('login.tooltip.text2') }}</p>
  376. </div>
  377. </Tooltip>
  378. </div>
  379. <h4 class="subTitle">{{ $t('login.subTitle.schoolLogin') }}</h4>
  380. <Form class="loginForm" ref="studForm" :model="studForm" :rules="studRule" :show-message="false" @keydown.enter.native="loginSubmit('studForm')">
  381. <FormItem class="formItem" style="margin-bottom: 15px;" prop="schoolCode">
  382. <Select v-show="!defaultSchool.code" v-model="studForm.schoolCode" :placeholder="$t('login.placeholder.schoolMenu')" filterable clearable >
  383. <template v-for="(item, index) in schoolList" >
  384. <OptionGroup :label="item.province" :key="index">
  385. <Option v-for="school in item.schools" :key="school.id" :value="school.id">{{ school.name }}</Option>
  386. </OptionGroup>
  387. </template>
  388. </Select>
  389. </FormItem>
  390. <FormItem class="formItem" prop="id" >
  391. <Input element-id = "studId" v-model="studForm.id" :placeholder="$t('login.placeholder.schoolID')"/>
  392. <input type="text" style="position:fixed;z-index:-10000;width:0;border:none"/>
  393. </FormItem>
  394. <FormItem class="formItem" prop="pass">
  395. <input type="password" style="position:fixed;z-index:-10000;width:0;border:none"/>
  396. <Input element-id="studpw" type="password" v-model="studForm.pass" :placeholder="$t('login.placeholder.schoolPsw')" >
  397. <Icon size="24" v-show="!loading && studFormEnter" @click="loginSubmit('studForm')" type="md-arrow-forward" slot="suffix" class="iconFrame" />
  398. <div v-show="loading" class="demo-spin-col" slot="suffix">
  399. <Spin>
  400. <Icon type="ios-loading" size="18" class="demo-spin-icon-load"></Icon>
  401. </Spin>
  402. </div>
  403. </Input>
  404. </FormItem>
  405. <div class="errlable">{{ schoolErrText }}</div>
  406. </Form>
  407. </div>
  408. </div> -->
  409. </div>
  410. </template>
  411. <script>
  412. import { EventSourcePolyfill } from 'event-source-polyfill';
  413. import QRCode from 'qrcodejs2'
  414. import { User } from '@/service/User'
  415. import { mapState, mapGetters } from 'vuex'
  416. export default {
  417. data() {
  418. const validateID = (rule, value, callback) => {
  419. if (value === '') {
  420. callback(new Error());
  421. this.loginErrText = this.$t('error.required')
  422. } else if (value.search(/^\+/) == 0) {
  423. callback(new Error());
  424. this.loginErrText = this.$t('error.format.default')
  425. } else {
  426. if (value.indexOf('@') >= 0) { //是否為Email
  427. var emailRule = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z]+$/;
  428. if (value.search(emailRule) != -1) {
  429. callback();
  430. this.loginErrText = ''
  431. } else {
  432. callback(new Error());
  433. this.loginErrText = this.$t('error.format.email')
  434. }
  435. } else {
  436. callback();
  437. this.loginErrText = ''
  438. }
  439. }
  440. };
  441. const validatePW = (rule, value, callback) => {
  442. if (value === '') {
  443. callback(new Error());
  444. this.loginErrText = this.$t('error.required')
  445. }
  446. else {
  447. callback();
  448. this.loginErrText = ''
  449. }
  450. };
  451. const validateStudID = (rule, value, callback) => {
  452. if (value === '') {
  453. callback(new Error());
  454. this.schoolErrText = this.$t('error.required')
  455. } else if (value.search(/^\+/) == 0) {
  456. callback(new Error());
  457. this.schoolErrText = this.$t('error.format.default')
  458. } else {
  459. if (value.indexOf('@') >= 0) { //是否為Email
  460. var emailRule = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z]+$/;
  461. if (value.search(emailRule) != -1) {
  462. callback();
  463. this.schoolErrText = ''
  464. } else {
  465. callback(new Error());
  466. this.schoolErrText = this.$t('error.format.email')
  467. }
  468. } else {
  469. callback();
  470. this.schoolErrText = ''
  471. }
  472. }
  473. };
  474. const validateStudPW = (rule, value, callback) => {
  475. if (value === '') {
  476. callback(new Error());
  477. this.schoolErrText = this.$t('error.required')
  478. }
  479. else {
  480. callback();
  481. this.schoolErrText = ''
  482. }
  483. };
  484. const validateStudSchoolCode = (rule, value, callback) => {
  485. if (value === '') {
  486. callback(new Error());
  487. this.schoolErrText = this.$t('error.required')
  488. }
  489. else {
  490. callback();
  491. this.schoolErrText = ''
  492. }
  493. };
  494. return {
  495. qrloginFlag: false,
  496. loginForm: {
  497. id: '',
  498. pass: '',
  499. },
  500. loginRule: {
  501. id: [
  502. { validator: validateID, trigger: 'blur' },
  503. ],
  504. pass: [
  505. { validator: validatePW, trigger: 'blur' },
  506. ]
  507. },
  508. studForm: {
  509. schoolCode: '',
  510. id: '',
  511. pass: ''
  512. },
  513. studRule: {
  514. schoolCode: [
  515. { validator: validateStudSchoolCode, trigger: 'blur' },
  516. ],
  517. id: [
  518. { validator: validateStudID, trigger: 'blur' },
  519. ],
  520. pass: [
  521. { validator: validateStudPW, trigger: 'blur' },
  522. ]
  523. },
  524. loginErrText: '',
  525. schoolErrText: '',
  526. userOauth: { // 社群帳號
  527. code: '',
  528. state: ''
  529. },
  530. schoolList: [],
  531. loading: false,
  532. sseSurvive: false,
  533. joinQRcode: undefined,
  534. defaultSchool: {
  535. name: '',
  536. code: ''
  537. },
  538. identityFlag: false
  539. }
  540. },
  541. computed: {
  542. ...mapState({
  543. config: state => state.config
  544. }),
  545. ...mapGetters({
  546. srvAdr: 'config/getSrvAdr'
  547. }),
  548. loginFormEnter: function () {
  549. let flag = false
  550. if (this.loginForm.id && this.loginForm.pass) flag = true
  551. return flag
  552. },
  553. studFormEnter: function () {
  554. let flag = false
  555. if (this.studForm.schoolCode && this.studForm.id && this.studForm.pass) flag = true
  556. return flag
  557. }
  558. },
  559. created() {
  560. // 此頁面為學生頁面
  561. localStorage.setItem('identity', 'student')
  562. // 建立學校LIST清單
  563. this.getSchools()
  564. // 取得學校設定簡碼
  565. this.setLoginSchoolCode()
  566. },
  567. methods: {
  568. chgLoginType: function () { // 變更登入類型
  569. this.qrloginFlag = !this.qrloginFlag
  570. if (this.qrloginFlag && !this.sseSurvive) {
  571. // SSE 連線
  572. this.SEELink()
  573. }
  574. },
  575. loginSubmit: function (name) { // 登入
  576. this.$refs[name].validate(async (valid) => {
  577. if (valid) {
  578. this.loading = true // 登入中動畫
  579. let result; // 輸出暫存
  580. let isFail = false // 失敗flag
  581. switch (name) {
  582. case 'loginForm':
  583. // 詢問帳號是否有效
  584. await this.$api.login.verification({ id: this.loginForm.id, pass: this.loginForm.pass }).then(res => {
  585. result = res
  586. }).catch(err => {
  587. isFail = true
  588. })
  589. console.log('res***', result)
  590. if (isFail) {
  591. this.loginErrText = this.$t('login.apiError.text1')
  592. this.loading = false
  593. } else {
  594. this.loginProcess(result, this.defaultSchool.code)
  595. }
  596. break;
  597. case 'studForm':
  598. // 學生登入大雲
  599. await this.$api.login.studLogin({ schoolCode: this.studForm.schoolCode, id: this.studForm.id, pw: this.studForm.pass }).then(res => {
  600. result = res
  601. }).catch(err => {
  602. isFail = true
  603. })
  604. if (isFail) {
  605. this.schoolErrText = this.$t('login.apiError.text1')
  606. this.loading = false
  607. } else {
  608. //設定權限並登入
  609. User.login(result).then(res => {
  610. if (res) {
  611. localStorage.setItem('identity', 'student')
  612. this.$router.push({ path: '/studentWeb' })
  613. }
  614. })
  615. }
  616. break;
  617. }
  618. return false;
  619. }
  620. })
  621. },
  622. oauthLogin: function (provider) { // 第三方登入
  623. let redirect_uri = window.location.origin + '/login';
  624. this.$api.BuildOauthUrl(provider, redirect_uri).then(res => {
  625. window.location.href = res
  626. })
  627. },
  628. SSOLogin: function (code) { // 快速登入
  629. this.$Spin.show(); //開啟加載畫面
  630. this.$api.SSOLogin(code).then(async res => {
  631. this.$Spin.hide(); // 關閉加載畫面
  632. if (!res.error) {
  633. // 登入大雲開始
  634. this.loginProcess(res, this.defaultSchool.code)
  635. } else {
  636. this.$Message.warning(this.$t('login.sse.error.text1'));
  637. }
  638. })
  639. },
  640. SEELink: function () { // 開啟SSE連結
  641. if (!this.sseSurvive) {
  642. let url = this.config[this.srvAdr].coreAPIUrl
  643. let es = new EventSourcePolyfill(url + '/service/sse', { headers: { 'X-Auth-Name': 'IES5' } });
  644. let _this = this;
  645. var closeSSE = function () {
  646. if (_this.sseSurvive) {
  647. es.close();
  648. _this.sseSurvive = false
  649. }
  650. }
  651. es.addEventListener('open', function (e) {
  652. _this.sseSurvive = true
  653. }, false);
  654. //取得登入網址
  655. es.addEventListener('message', function (e) {
  656. if (e.data) {
  657. let data = JSON.parse(e.data)
  658. if (data.sid) {
  659. let qrcodeURL = url + '/qrcode/login?sid=' + encodeURIComponent(data.sid, "utf-8") + '&info=' + encodeURIComponent(_this.$t('login.sse.text1'), "utf-8")
  660. _this.crtQrcode(qrcodeURL)
  661. } else if (data.code) {
  662. closeSSE()
  663. _this.SSOLogin(data.code)
  664. }
  665. }
  666. }, false);
  667. // 錯誤
  668. es.addEventListener('error', function (e) {
  669. closeSSE()
  670. }, false);
  671. // 設定五分鐘後關閉連接
  672. setTimeout(() => {
  673. closeSSE()
  674. }, 300000);
  675. }
  676. },
  677. crtQrcode: function (url) { // 開啟QRCODE
  678. this.$nextTick(() => {
  679. if (this.joinQRcode == undefined) {
  680. let qrcode = new QRCode('qrcode', {
  681. width: 200, // 设置宽度,单位像素
  682. height: 200, // 设置高度,单位像素
  683. text: url, // 设置二维码内容或跳转地址
  684. })
  685. this.joinQRcode = qrcode
  686. } else {
  687. this.joinQRcode.clear()
  688. this.joinQRcode.makeCode(url)
  689. }
  690. })
  691. },
  692. loginProcess: async function (item, schoolCode) { // 登入用function
  693. let result;
  694. await this.$api.login.loginIES(item, schoolCode).then(res => {
  695. result = res
  696. })
  697. console.log('////', result)
  698. //設定權限並登入
  699. User.login(result).then(res => {
  700. if (res) {
  701. this.saveUserCodes({
  702. TEAMModelId: result.id,
  703. name: result.name,
  704. schoolCode: result.defaultschool
  705. })
  706. this.$router.push({ path: '/studentWeb' })
  707. }
  708. })
  709. },
  710. saveUserCodes: function (res) {
  711. this.$store.commit('setUserInfo', res)
  712. },
  713. getSchools: function () { // 取得學校清單
  714. let _this = this
  715. this.$api.getSchoolList().then(res => {
  716. if (Array.isArray(res.schools) && res.schools.length > 0) {
  717. res.schools.forEach(function (item) {
  718. let isProvinceSame = _this.schoolList.find(function (val) {
  719. return val.province == item.province
  720. })
  721. if (isProvinceSame) {
  722. let index = _this.schoolList.indexOf(isProvinceSame)
  723. _this.schoolList[index].schools.push({
  724. id: item.id,
  725. name: item.name,
  726. })
  727. } else {
  728. let data = {
  729. province: item.province,
  730. schools: [
  731. {
  732. id: item.id,
  733. name: item.name,
  734. }
  735. ]
  736. }
  737. _this.schoolList.push(data)
  738. }
  739. })
  740. }
  741. })
  742. },
  743. setLoginSchoolCode: function () { // 設定預設的學校簡碼
  744. let schoolCode = this.$route.query.schoolcode == undefined ? '' : this.$route.query.schoolcode;
  745. if (schoolCode) {
  746. this.$api.login.getSchoolName({ schoolCode: schoolCode }).then(res => {
  747. this.defaultSchool.code = res.code
  748. this.defaultSchool.name = res.name
  749. this.studForm.schoolCode = this.defaultSchool.code
  750. })
  751. }
  752. },
  753. setDefSchool: function () {
  754. let defschool = sessionStorage.defaultSchool
  755. if (defschool) {
  756. defschool = JSON.parse(decodeURIComponent(defschool), "utf-8")
  757. this.defaultSchool.code = defSchool.code
  758. this.defaultSchool.name = defSchool.name
  759. }
  760. }
  761. }
  762. }
  763. </script>