index.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. <template>
  2. <header class="header">
  3. <div class="container clearfix">
  4. <div class="logo logo--no" v-if="header.companyLogo">
  5. <img style="cursor: pointer; width: 162px; height: 33px" :src="$tools.splitImgHost(header.companyLogo)" alt=""
  6. @click="go('/')" />
  7. </div>
  8. <h1 class="logo" v-else @click="go('/')"></h1>
  9. <nav class="nav">
  10. <ul class="list">
  11. <li v-for="(item, index) in showNav(header.Nav)" :key="index">
  12. <a v-if="item.name == '首页'" @click="go('/index')">首页</a>
  13. <!-- <a v-if="item.name == '走进祥粤'" @click="go('/about')"
  14. :style="$route.path === '/about' ? 'color:red;' : ''">走进祥粤</a> -->
  15. <a v-if="item.name == '课程'" @click="go('/course-list')"
  16. :style="$route.path === '/course-list' ? 'color:red;' : ''">课程</a>
  17. <a v-if="item.name == '直播'" @click="go('/live-list')"
  18. :style="$route.path === '/live-list' ? 'color:red;' : ''">直播</a>
  19. <a v-if="item.name == '题库'" @click="go('/bank-list')"
  20. :style="$route.path === '/bank-list' ? 'color:red;' : ''">题库</a>
  21. </li>
  22. </ul>
  23. </nav>
  24. <div class="userinfo" v-if="userInfo">
  25. <!-- <a class="msg" @click="go('/person-center/my-message')">
  26. <i class="pi" v-if="msgCount > 0"></i>
  27. <i class="el-icon-message-solid icon"></i>
  28. <div @click.stop="" class="popover_style">
  29. {{ msgData.text }} <el-button style="float:right;" type="text">立即学习</el-button>
  30. </div>
  31. </a> -->
  32. <!-- <el-tooltip placement="bottom-end" v-model="msgShow" :hide-after="0" manual popper-class="tooltipStyle">
  33. <el-badge :is-dot="msgCount > 0 ? true : false" class="item" style="vertical-align: baseline">
  34. <el-button style="font-size: 20px; padding: 0px" icon="el-icon-message-solid" type="text"
  35. @click="go('/person-center/my-message')"></el-button>
  36. </el-badge>
  37. <div slot="content" class="dis_plays">
  38. <p style="max-width: 247px">{{ msgData.text }}</p>
  39. <div class="toolbth" @click="newGoToStudy">立即学习</div>
  40. <i style="font-size: 18px; cursor: pointer" class="el-icon-close" @click="clearMsg"></i>
  41. </div>
  42. </el-tooltip> -->
  43. <el-badge :is-dot="msgCount > 0 ? true : false" class="item" style="vertical-align: baseline">
  44. <el-button style="font-size: 20px; padding: 0px" icon="el-icon-message-solid" type="text"
  45. @click="go('/person-center/my-message')"></el-button>
  46. </el-badge>
  47. <el-dropdown @command="handleCommand">
  48. <span class="el-dropdown-link" @click="go('/person-center/my-course')"
  49. style="margin-left: 10px; cursor: pointer">
  50. <img style="width: 24px; vertical-align: middle" :src="
  51. userInfo
  52. ? userInfo.avatar
  53. ? $tools.splitImgHost(userInfo.avatar, true)
  54. : '@/assets/qrcode.png'
  55. : ''
  56. " alt="" />
  57. <span>{{ userInfo && userInfo.realname }}</span>
  58. </span>
  59. <el-dropdown-menu slot="dropdown">
  60. <el-dropdown-item command="1">我的课程</el-dropdown-item>
  61. <el-dropdown-item command="2">我的题库</el-dropdown-item>
  62. <el-dropdown-item command="3">个人中心</el-dropdown-item>
  63. <el-dropdown-item command="4">退出登录</el-dropdown-item>
  64. </el-dropdown-menu>
  65. </el-dropdown>
  66. </div>
  67. <div class="userinfo" v-else>
  68. <div class="text-list" v-if="!userInfo">
  69. <a @click="go('/login', { state: 1 })">登录</a>
  70. <a @click="go('/login', { state: 2 })">注册</a>
  71. </div>
  72. </div>
  73. <div class="search">
  74. <div class="search__select">
  75. <select v-model="type">
  76. <option value="1">课程</option>
  77. <option value="2">题库</option>
  78. <option value="6">直播</option>
  79. </select>
  80. </div>
  81. <div class="search__input">
  82. <input type="text" v-model="searchKey" autocomplete="off" />
  83. <input type="password" autocomplete="new-password" style="display: none" />
  84. </div>
  85. <el-button type="primary" @click="search" class="search__btn">搜索</el-button>
  86. </div>
  87. </div>
  88. <RebuildModal ref="rebuildModal" @rebuildSubmit="rebuildSubmit($event)"></RebuildModal>
  89. </header>
  90. </template>
  91. <script>
  92. import RebuildModal from "@/components/rebuildModal";
  93. import { mapGetters, mapMutations } from "vuex";
  94. export default {
  95. name: "Header",
  96. components: {
  97. RebuildModal,
  98. },
  99. data() {
  100. return {
  101. searchKey: "",
  102. type: "1",
  103. showBox: false,
  104. timer: null,
  105. msgData: {},
  106. sysTime: 0,
  107. msgShow: false,
  108. };
  109. },
  110. computed: {
  111. ...mapGetters(["header", "userInfo", "msgCount"]),
  112. showNav: function () {
  113. return function (list) {
  114. var newList = [];
  115. if (list) {
  116. newList = list.filter((item) => {
  117. return item.status === 1;
  118. });
  119. }
  120. return newList;
  121. };
  122. },
  123. },
  124. mounted() {
  125. if (this.$tools.isLogin()) {
  126. // this.$request.informUserselectLastUnStudyMsg().then((res) => {
  127. // if (res.data && res.data.id) {
  128. // let today = new Date(new Date().toLocaleDateString()).getTime();
  129. // if (localStorage.getItem("msg")) {
  130. // let ary = JSON.parse(localStorage.getItem("msg"));
  131. // if (ary.updateTime === today) {
  132. // this.msgShow = false;
  133. // return;
  134. // }
  135. // }
  136. // this.$nextTick(() => {
  137. // this.msgData = res.data;
  138. // this.msgShow = true;
  139. // });
  140. // } else {
  141. // this.msgShow = false;
  142. // }
  143. // });
  144. this.getMsgCount();
  145. }
  146. },
  147. methods: {
  148. ...mapMutations(["getMsgCount"]),
  149. rebuildSubmit(item) {
  150. this.$router.push({
  151. path: `/my-course-detail/${item.goodsId}`,
  152. query: {
  153. gradeId: item.gradeId,
  154. orderGoodsId: item.orderGoodsId,
  155. rebuild: 1,
  156. },
  157. });
  158. },
  159. getGoodsData() {
  160. return new Promise((resolve, reject) => {
  161. this.$request.goodsDetail(this.msgData.goodsId).then((res) => {
  162. resolve(res.data);
  163. });
  164. });
  165. },
  166. /**
  167. * 关闭消息
  168. */
  169. clearMsg() {
  170. let ary = {
  171. userId: this.msgData.userId,
  172. msgId: this.msgData.id,
  173. updateTime: new Date(new Date().toLocaleDateString()).getTime(),
  174. };
  175. localStorage.setItem("msg", JSON.stringify(ary));
  176. this.msgShow = false;
  177. },
  178. /**
  179. * 前往学习
  180. */
  181. async newGoToStudy() {
  182. let item = await this.getGoodsData();
  183. if (item.goodsType == 1) {
  184. this.sysTime = this.$tools.timest();
  185. item.orderGoodsId = this.msgData.orderGoodsId;
  186. this.canJump(item).then((res) => {
  187. this.clearMsg();
  188. this.$router.push({
  189. path: `/my-course-detail/${item.goodsId}`,
  190. query: {
  191. gradeId: item.gradeId,
  192. orderGoodsId: item.orderGoodsId,
  193. courseId: res.rows[0].courseId || "",
  194. },
  195. });
  196. });
  197. // arsty = '立刻学习';
  198. //题库
  199. } else if (item.goodsType == 2) {
  200. this.clearMsg();
  201. this.$router.push({
  202. path: "/person-center/my-bank/bank-detail/" + item.goodsId,
  203. query: {
  204. orderGoodsId: item.orderGoodsId,
  205. },
  206. });
  207. }
  208. },
  209. canJump(item) {
  210. return new Promise((resolve) => {
  211. this.$request
  212. .orderInfo({
  213. orderGoodsId: item.orderGoodsId,
  214. })
  215. .then(async (res) => {
  216. let items = res.data;
  217. let currentTime = this.$tools.timest();
  218. if (items.interfaceAccountId > 0) {
  219. //学习账号已开通
  220. if (items.learnStatus == 1) {
  221. //跳转第三方h5
  222. const confirmText = [
  223. "您的学习账号已经开通,请按照步骤操作,进行学习。",
  224. "1.点击【跳转学习网址】按钮",
  225. "2.打开学习网址后,选择【个人用户】进行登录",
  226. "(1)账号:您个人的身份证号码",
  227. "(2)密码:身份证号码,再加111111",
  228. ];
  229. const newDatas = [];
  230. const h = this.$createElement;
  231. for (const i in confirmText) {
  232. newDatas.push(h("p", null, confirmText[i]));
  233. }
  234. this.$confirm(h("div", null, newDatas), "温馨提示", {
  235. confirmButtonText: "跳转学习网址",
  236. cancelButtonText: "关闭",
  237. closeOnClickModal: false,
  238. closeOnPressEscape: false,
  239. distinguishCancelAndClose: false,
  240. showClose: false,
  241. })
  242. .then((_) => {
  243. window.open("http://admin.zhujianpeixun.com/", "_blank");
  244. })
  245. .catch((_) => { });
  246. return;
  247. } else {
  248. this.$message({
  249. type: "warning",
  250. message:
  251. "您的学习账号未开通,请稍后再尝试,有疑问,请联系020-87085982!",
  252. });
  253. return;
  254. }
  255. }
  256. // //内部系统
  257. // if (items.interfacePushId > 0 && items.officialStatus != 1) {
  258. // this.$message({
  259. // type: "warning",
  260. // message:
  261. // "机构正在为您报名中,请耐心等待,有疑问请联系020-87085982!",
  262. // });
  263. // return;
  264. // }
  265. if (items.goodsType !== 6) {
  266. if (
  267. this.sysTime <= items.serviceStartTime ||
  268. this.sysTime >= items.serviceEndTime
  269. ) {
  270. this.$message({
  271. type: "warning",
  272. message: "不在学习服务期,不能进入学习",
  273. });
  274. return;
  275. }
  276. if (
  277. (items.classStartTime &&
  278. this.sysTime <= items.classStartTime) ||
  279. (items.classEndTime && this.sysTime >= items.classEndTime)
  280. ) {
  281. this.$message({
  282. type: "warning",
  283. message: "不在班级有效期,不能进入学习",
  284. });
  285. return;
  286. }
  287. if (items.learningStatus == 2) {
  288. this.$message({
  289. type: "warning",
  290. message: "开放学习时间待定,不能进入学习",
  291. });
  292. return;
  293. }
  294. if (items.classStatus == 0) {
  295. this.$message({
  296. type: "warning",
  297. message: "尚未开班,不能进入学习",
  298. });
  299. return;
  300. }
  301. if (
  302. items.learningStatus == 3 &&
  303. this.sysTime < items.learningTimeStart
  304. ) {
  305. this.$message({
  306. type: "warning",
  307. message: "不在开放学习时间,不能进入学习",
  308. });
  309. return;
  310. }
  311. let rebuildStatus = await this.courseGoodsRebuildStatus(
  312. items.goodsId,
  313. items.gradeId
  314. );
  315. if (rebuildStatus == 0) {
  316. this.$refs.rebuildModal.showModal(items);
  317. return;
  318. }
  319. }
  320. // if (item.educationName == "继续教育") {
  321. this.$request
  322. .lockLockStatus({
  323. action: "jxjy",
  324. })
  325. .then((res) => {
  326. //有其他端在操作,不能学习
  327. this.$message({
  328. type: "warning",
  329. message: res.msg,
  330. });
  331. })
  332. .catch((err) => {
  333. //可以学习
  334. this.$request
  335. .courseCourseList({
  336. pageNum: 1,
  337. pageSize: 1,
  338. goodsId: items.goodsId,
  339. gradeId: items.gradeId,
  340. })
  341. .then((res) => {
  342. if (res.rows.length) {
  343. resolve(res);
  344. } else {
  345. this.$message({
  346. type: "warning",
  347. message: "课程内暂无可以学习的科目",
  348. });
  349. }
  350. });
  351. });
  352. // } else {
  353. // this.$request
  354. // .courseCourseList({
  355. // pageNum: 1,
  356. // pageSize: 1,
  357. // goodsId: items.goodsId,
  358. // gradeId: items.gradeId,
  359. // })
  360. // .then((res) => {
  361. // if (res.rows.length) {
  362. // resolve(res);
  363. // } else {
  364. // this.$message({
  365. // type: "warning",
  366. // message: "课程内暂无可以学习的科目",
  367. // });
  368. // }
  369. // });
  370. // }
  371. });
  372. });
  373. },
  374. /**
  375. * @param {Object} goodsId 商品id
  376. * 查询商品重修状态
  377. */
  378. courseGoodsRebuildStatus(goodsId, gradeId) {
  379. return new Promise((resolve) => {
  380. this.$request
  381. .courseGoodsRebuildStatus({
  382. goodsId: goodsId,
  383. gradeId: gradeId,
  384. })
  385. .then((res) => {
  386. resolve(res.data);
  387. });
  388. });
  389. },
  390. handleCommand(command) {
  391. switch (command) {
  392. case "1":
  393. this.go("/person-center/my-course");
  394. break;
  395. case "2":
  396. this.go("/person-center/my-bank");
  397. break;
  398. case "3":
  399. this.go("/person-center/my-info");
  400. break;
  401. case "4":
  402. this.$tools.exit();
  403. break;
  404. default:
  405. break;
  406. }
  407. },
  408. go(path, query) {
  409. if (path === this.$route.path) {
  410. this.$router.push({
  411. path: "refresh", //refresh路由地址和当前要刷新路由地址同级即可
  412. });
  413. return;
  414. }
  415. this.$router.push({
  416. path,
  417. query,
  418. });
  419. },
  420. search() {
  421. if (!this.searchKey.trim()) {
  422. this.$message({
  423. type: "warning",
  424. duration: 2000,
  425. message: "请输入搜索内容",
  426. });
  427. return;
  428. }
  429. let type = this.type;
  430. let path = this.$route.path;
  431. if (path == "/bank-list") {
  432. //在题库列表页面直接传参
  433. if (type == "2") {
  434. this.$emit("search", this.searchKey);
  435. } else if (type == "6") {
  436. this.$router.push({
  437. path: "/live-list",
  438. query: {
  439. searchKey: this.searchKey,
  440. },
  441. });
  442. } else {
  443. this.$router.push({
  444. path: "/course-list",
  445. query: {
  446. searchKey: this.searchKey,
  447. },
  448. });
  449. }
  450. } else if (path == "/course-list") {
  451. //在课程列表页面直接传参
  452. if (type == "1") {
  453. this.$emit("search", this.searchKey);
  454. } else if (type == "6") {
  455. this.$router.push({
  456. path: "/live-list",
  457. query: {
  458. searchKey: this.searchKey,
  459. },
  460. });
  461. } else {
  462. this.$router.push({
  463. path: "/bank-list",
  464. query: {
  465. searchKey: this.searchKey,
  466. },
  467. });
  468. }
  469. } else if (path == "/live-list") {
  470. //在课程列表页面直接传参
  471. if (type == "6") {
  472. this.$emit("search", this.searchKey);
  473. } else if (type == "1") {
  474. this.$router.push({
  475. path: "/course-list",
  476. query: {
  477. searchKey: this.searchKey,
  478. },
  479. });
  480. } else {
  481. this.$router.push({
  482. path: "/bank-list",
  483. query: {
  484. searchKey: this.searchKey,
  485. },
  486. });
  487. }
  488. } else {
  489. //根据类型跳转题库或者列表页面
  490. console.log(type);
  491. if (type == "1") {
  492. this.$router.push({
  493. path: "/course-list",
  494. query: {
  495. searchKey: this.searchKey,
  496. },
  497. });
  498. } else if (type == "6") {
  499. this.$router.push({
  500. path: "/live-list",
  501. query: {
  502. searchKey: this.searchKey,
  503. },
  504. });
  505. } else {
  506. this.$router.push({
  507. path: "/bank-list",
  508. query: {
  509. searchKey: this.searchKey,
  510. },
  511. });
  512. }
  513. }
  514. },
  515. mouseover() {
  516. clearTimeout(this.timer);
  517. this.showBox = true;
  518. },
  519. mouseLeave() {
  520. clearTimeout(this.timer);
  521. this.timer = setTimeout(() => {
  522. this.showBox = false;
  523. }, 500);
  524. },
  525. },
  526. };
  527. </script>
  528. <!-- Add "scoped" attribute to limit CSS to this component only -->
  529. <style scoped lang="scss">
  530. .header {
  531. position: relative;
  532. background: #fff;
  533. box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.04);
  534. .container {
  535. height: 80px;
  536. .logo {
  537. margin-top: 23px;
  538. float: left;
  539. cursor: pointer;
  540. width: 162px;
  541. height: 33px;
  542. background: url("~@/assets/logo.png") no-repeat center;
  543. &--no {
  544. background: none;
  545. }
  546. }
  547. .nav {
  548. float: left;
  549. margin-top: 30px;
  550. .list {
  551. margin-left: 146px;
  552. display: flex;
  553. li {
  554. a {
  555. margin: 0 20px;
  556. color: #333;
  557. }
  558. a:hover {
  559. color: #3f8dfd;
  560. }
  561. }
  562. }
  563. }
  564. .search {
  565. float: right;
  566. margin-right: 12px;
  567. margin-top: 20px;
  568. width: 324px;
  569. background: #fafbfc;
  570. border: 1px solid #3f8dfd;
  571. border-radius: 8px;
  572. display: flex;
  573. overflow: hidden;
  574. &__select {
  575. width: 76px;
  576. border-right: 1px solid #fff;
  577. select {
  578. text-align: center;
  579. width: 100%;
  580. height: 100%;
  581. border: 0;
  582. outline: none;
  583. }
  584. }
  585. &__input {
  586. flex: 1;
  587. input {
  588. width: 100%;
  589. height: 100%;
  590. }
  591. }
  592. &__btn {
  593. padding: 0;
  594. text-align: center;
  595. width: 80px;
  596. height: 40px;
  597. line-height: 40px;
  598. font-size: 14px;
  599. border-radius: 0;
  600. }
  601. }
  602. .userinfo {
  603. margin-top: 30px;
  604. float: right;
  605. white-space: nowrap;
  606. a {
  607. display: inline-block;
  608. margin-left: 20px;
  609. vertical-align: middle;
  610. &.msg {
  611. position: relative;
  612. margin-top: 2px;
  613. .icon {
  614. font-size: 20px;
  615. color: #3f8dfd;
  616. }
  617. .pi {
  618. display: inline-block;
  619. width: 10px;
  620. height: 10px;
  621. background: #ff3b30;
  622. border: 1px solid #ffffff;
  623. border-radius: 10px;
  624. position: absolute;
  625. top: 0;
  626. right: 0;
  627. }
  628. .popover_style {
  629. position: absolute;
  630. top: 150%;
  631. left: -100px;
  632. border-radius: 8px;
  633. background-color: #fff;
  634. border: 1px solid #333;
  635. padding: 0px 6px;
  636. width: 300px;
  637. white-space: normal;
  638. }
  639. }
  640. &.name {
  641. position: relative;
  642. z-index: 99;
  643. img {
  644. width: 24px;
  645. vertical-align: middle;
  646. }
  647. .modal-box {
  648. width: 162px;
  649. background: #ffffff;
  650. box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.1);
  651. border-radius: 8px;
  652. position: absolute;
  653. top: 55px;
  654. left: -40px;
  655. li {
  656. margin-left: 10px;
  657. border-bottom: 1px solid #eeeeee;
  658. height: 40px;
  659. line-height: 40px;
  660. cursor: pointer;
  661. padding-left: 5px;
  662. &:hover {
  663. background: #eeeeee;
  664. color: #3f8dfd;
  665. }
  666. &:nth-last-of-type(1) {
  667. border: 0;
  668. }
  669. }
  670. }
  671. }
  672. }
  673. }
  674. .text-list {
  675. text-align: right;
  676. font-size: 0;
  677. a {
  678. display: inline-block;
  679. margin: 0;
  680. color: #3f8dfd;
  681. font-size: 14px;
  682. padding: 0 14px;
  683. &:nth-last-of-type(1) {
  684. padding-right: 0;
  685. border-left: 1px solid #3f8dfd;
  686. }
  687. }
  688. }
  689. }
  690. }
  691. .fade-enter,
  692. .fade-leave-to {
  693. opacity: 0;
  694. height: 0;
  695. }
  696. .fade-enter-to,
  697. .fade-leave {
  698. opacity: 1;
  699. height: 122px;
  700. }
  701. .fade-enter-active,
  702. .fade-leave-active {
  703. transition: all 0.3s;
  704. }
  705. .dis_plays {
  706. display: flex;
  707. align-items: center;
  708. }
  709. .toolbth {
  710. border-radius: 55px;
  711. background-color: #fff;
  712. color: #3f8dfd;
  713. font-size: 14px;
  714. padding: 5px 14px;
  715. margin-right: 16px;
  716. user-select: none;
  717. cursor: pointer;
  718. }
  719. </style>
  720. <style lang="scss">
  721. .tooltipStyle {
  722. background-color: #3f8dfd !important;
  723. color: #fff;
  724. }
  725. .tooltipStyle .popper__arrow {
  726. border-bottom-color: #3f8dfd !important;
  727. }
  728. .tooltipStyle .popper__arrow::after {
  729. border-bottom-color: #3f8dfd !important;
  730. }
  731. </style>