杨磊
5 小时以前 afe2fbc5b0375c7c06853fc981deec74e04fd630
Merge branch 'master' of http://182.92.203.7:2001/r/xiehe_website
30个文件已修改
1763 ■■■■ 已修改文件
src/assets/js/config.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/middleGround/api/edu.js 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/middleGround/api/ugc.js 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/main.css 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/login.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/classManage/classHome.vue 63 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/classManage/components/questionDom.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/classManage/index.vue 133 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/classManage/infoList.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/classManage/interactionDetail.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/classManage/jobAnalysis.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/classManage/jobDetail.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/classManage/jobManage.vue 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/classManage/studentJob.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/classManage/talkDetail.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/classManage/talkingPoint.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/classManage/teachInteraction.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/classManage/teachingPlan.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/courseManage/components/class.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/courseManage/index.vue 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personalCenter/activeCode.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personalCenter/class.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personalCenter/course.vue 311 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personalCenter/index.vue 76 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personalCenter/myApply.vue 119 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personalCenter/myCart.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personalCenter/myCollection.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personalCenter/myOrder.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personalCenter/userInfo.vue 667 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/config.js
@@ -18,6 +18,12 @@
  /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/ // 电话号正则
export const reg_telphone = /^0\d{2}-\d{8}$|^0\d{3}-\d{7}$/ //座机号正则
// 自定义任务类型
const taskType = {
  teachingPlan: 'TeachingPlan', // 教学计划
  homeWork: 'HomeWork', // 作业
}
// refcode
const refCode = {
  // 收藏资源库
@@ -62,6 +68,12 @@
  recommendAudioStore: 'jilin_audiosLibrary\\jilin_recommendedAudio',
  recommendVideoStore: 'jilin_videosLibrary\\jilin_recommendedVideo',
  recommendModelStore: 'jilin_modelsLibrary\\jilin_recommendedModel',
  // 开课
  message: 'MessageCode', // 消息、通知
  talk: 'TalkCode', // 话题
  teachingPlan: 'teachingPlan', // 教学计划类型
  homework: 'homework', // 新建作业类型
  teachInteraction: 'TeachInteraction', //教学互动
}
const wxLogin = {
@@ -83,5 +95,6 @@
  refCode,
  wxLogin,
  reg_telphone,
  taskType,
}
export default config
src/assets/js/middleGround/api/edu.js
@@ -107,7 +107,7 @@
      data,
    })
  },
  //创建课程订单
  createCourseOrder(data) {
    return request({
@@ -179,6 +179,132 @@
      data,
    })
  },
  // 为班级新建任务
  newTask(data) {
    return request({
      url: '/edu/api/ApiNewTask',
      method: 'post',
      data,
    })
  },
  // 更新任务
  updateTask(data) {
    return request({
      url: '/edu/api/ApiUpdateTask',
      method: 'post',
      data,
    })
  },
  // 获取班级任务列表
  getTaskList(data) {
    return request({
      url: '/edu/api/ApiGetTaskList',
      method: 'post',
      data,
    })
  },
  // 删除班级任务列表
  delTask(data) {
    return request({
      url: '/edu/api/ApiDelTask',
      method: 'post',
      data,
    })
  },
  // 为任务新建资源
  newTaskCmsItem(data) {
    return request({
      url: '/edu/api/ApiNewTaskCmsItem',
      method: 'post',
      data,
    })
  },
  // 获取任务下的资源列表
  getTaskCmsItem(data) {
    return request({
      url: '/edu/api/ApiGetTaskCmsItem',
      method: 'post',
      data,
    })
  },
  // 删除任务下的资源列表
  removeTaskCmsItemList(data) {
    return request({
      url: '/edu/api/ApiRemoveTaskCmsItemList',
      method: 'post',
      data,
    })
  },
  // 为任务添加资源
  addTaskCmsItemList(data) {
    return request({
      url: '/edu/api/ApiAddTaskCmsItemList',
      method: 'post',
      data,
    })
  },
  // 获取任务提交列表
  getTaskSubmitList(data) {
    return request({
      url: '/edu/api/ApiGetTaskSubmitList',
      method: 'post',
      data,
    })
  },
  // 获取未提交任务列表
  getUnSubmitList(data) {
    return request({
      url: '/edu/api/ApiGetUnSubmitList',
      method: 'post',
      data,
    })
  },
  // 为任务新建提交
  newTaskSubmit(data) {
    return request({
      url: '/edu/api/ApiNewTaskSubmit',
      method: 'post',
      data,
    })
  },
  // 更新任务提交
  updateTaskSubmit(data) {
    return request({
      url: '/edu/api/ApiUpdateTaskSubmit',
      method: 'post',
      data,
    })
  },
  // 获取任务提交统计
  getTaskStatistics(data) {
    return request({
      url: '/edu/api/ApiGetTaskStatistics',
      method: 'post',
      data,
    })
  },
  // 获取用户提交统计列表
  getUserTaskList(data) {
    return request({
      url: '/edu/api/ApiGetUserTaskList',
      method: 'post',
      data,
    })
  },
}
export default eduApi
src/assets/js/middleGround/api/ugc.js
@@ -1,88 +1,106 @@
import request from "@/plugin/axios/index.ts";
import { tokenKey } from "@/assets/js/config.js";
import toolClass from "@/assets/js/toolClass.js";
import request from '@/plugin/axios/index.ts'
import { tokenKey } from '@/assets/js/config.js'
import toolClass from '@/assets/js/toolClass.js'
const ugcApi = {
  // 获取商品点赞Topic
  getProductLikesTopic(data) {
    return request({
      url: localStorage.getItem(tokenKey)
        ? "/ugc/api/ApiAppUserGetProductLikesTopic"
        : "/ugc/api/ApiGetProductLikesTopic",
      method: "post",
        ? '/ugc/api/ApiAppUserGetProductLikesTopic'
        : '/ugc/api/ApiGetProductLikesTopic',
      method: 'post',
      data,
    });
    })
  },
  // 获取商品评论Topic
  getProductCommentTopic(data) {
    return request({
      url: localStorage.getItem(tokenKey)
        ? "/ugc/api/ApiAppUserGetProductCommentTopic"
        : "/ugc/api/ApiGetProductCommentTopic",
      method: "post",
        ? '/ugc/api/ApiAppUserGetProductCommentTopic'
        : '/ugc/api/ApiGetProductCommentTopic',
      method: 'post',
      data,
    });
    })
  },
  // 获取MessageList
  getTopicMessageList(data) {
    return request({
      url: localStorage.getItem(tokenKey)
        ? "/ugc/api/ApiAppUserGetTopicMessageList"
        : "/ugc/api/ApiGetTopicMessageList",
      method: "post",
        ? '/ugc/api/ApiAppUserGetTopicMessageList'
        : '/ugc/api/ApiGetTopicMessageList',
      method: 'post',
      data,
    });
    })
  },
  // 获取子MessageList
  getTopicMessageSubList(data) {
    return request({
      url: '/ugc/api/ApiAppUserGetSubMessageList',
      method: 'post',
      data,
    })
  },
  // 获取MessageList子message
  getChildTopicMessageList(data) {
    return request({
      url: '/ugc/api/ApiAppUserGetSubMessageList',
      method: 'post',
      data,
    })
  },
  // 用户根据消息类型获取列表
  getMessageList(data) {
    return request({
      url: "/ugc/api/ApiGetMessageList",
      method: "post",
      url: '/ugc/api/ApiGetMessageList',
      method: 'post',
      data,
    });
    })
  },
  // 新建Message
  newTopicMessage(data) {
    return request({
      url: "/ugc/api/ApiNewTopicMessage",
      method: "post",
      url: '/ugc/api/ApiNewTopicMessage',
      method: 'post',
      data,
    });
    })
  },
  // 删除Message
  delTopicMessage(data) {
    return request({
      url: "/ugc/api/ApiDelTopicMessage",
      method: "post",
      url: '/ugc/api/ApiDelTopicMessage',
      method: 'post',
      data,
    });
    })
  },
  // 更新message
  updateTopicMessage(data) {
    return request({
      url:'/ugc/api/ApiUpdateTopicMessage',
      method:'post',
      data
      url: '/ugc/api/ApiUpdateTopicMessage',
      method: 'post',
      data,
    })
  },
  // 获取cms评论
  getCmsItemCommentTopic(data) {
    return request({
      url: "/ugc/api/ApiGetCmsItemCommentTopic",
      method: "post",
      url: '/ugc/api/ApiGetCmsItemCommentTopic',
      method: 'post',
      data,
    });
    })
  },
  // 获取用户提交的教学资源
  getProductUserSubmitTopic(data) {
    return request({
      url: "/ugc/api/ApiGetProductUserSubmitTopic",
      method: "post",
      url: '/ugc/api/ApiGetProductUserSubmitTopic',
      method: 'post',
      data,
    });
    })
  },
  //更新TOPICMESSAGE
@@ -93,6 +111,6 @@
  //     data,
  //   });
  // },
};
}
export default ugcApi;
export default ugcApi
src/assets/main.css
@@ -10,7 +10,7 @@
}
/* 基础样式 */
*{
* {
  outline: none;
}
@@ -51,13 +51,12 @@
}
.titleBox {
  height: 60px;
  background: #d8f7e6;
  line-height: 60px;
  padding: 0 40px;
  padding: 8px 10px;
  font-weight: 700;
  color: #00873c;
  font-size: 18px;
  font-size: 14px;
  box-sizing: border-box;
}
/* 富文本容器,保留富文本默认样式,所见即所得 */
@@ -179,7 +178,8 @@
  color: #00873C !important;
} */
.el-input-group__append, .el-input-group__prepend {
.el-input-group__append,
.el-input-group__prepend {
  /* vertical-align: initial !important; */
  /* align-items: stretch !important; */
}
@@ -221,7 +221,7 @@
}
.wait,
.main {
  color: #ff6d00;
  color: #019e58;
}
.grey {
  color: #949494;
src/layout/components/login.vue
@@ -649,7 +649,7 @@
}
.policy {
  cursor: pointer;
  color: #ff6c00;
  color: #019e58;
}
/** 注册表单 */
.signUp {
@@ -672,7 +672,7 @@
  h4 {
    font-size: 16px;
    color: #ff6c00;
    color: #019e58;
  }
  .logInBox {
src/main.js
@@ -12,7 +12,8 @@
import MG from '@/assets/js/middleGround/WebMiddleGroundApi.js'
import toolClass from '@/assets/js/toolClass.js'
import config from '@/assets/js/config.js'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
// import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import locale from 'element-plus/es/locale/lang/zh-cn'
const app = createApp(App)
@@ -27,7 +28,8 @@
app.use(ElementPlus)
app.use(createPinia())
app.use(router)
app.use(ElementPlus, {
  locale: zhCn,
})
// app.use(ElementPlus, {
//   locale: zhCn,
// })
app.use(ElementPlus, { locale })
app.mount('#app')
src/views/classManage/classHome.vue
@@ -69,7 +69,7 @@
              <span>班级通知</span>
              <el-icon
                style="cursor: pointer"
                color="#FF6D00"
                color="#019e58"
                v-if="noticeList.length > 0 && userInfo.role == 'Teacher'"
                @click="toInfo"
              >
@@ -98,7 +98,7 @@
              <span>班组话题</span>
              <el-icon
                style="cursor: pointer"
                color="#FF6D00"
                color="#019e58"
                v-if="messageList.length > 0"
                @click="toTalk"
              >
@@ -131,7 +131,7 @@
              <span>班级作业概览</span>
              <!-- <el-icon
                style="cursor: pointer"
                color="#FF6D00"
                color="#019e58"
                v-if="tableData.length > 0"
                @click="toWorkList"
              >
@@ -155,7 +155,7 @@
              <span>教学互动</span>
              <el-icon
                style="cursor: pointer"
                color="#FF6D00"
                color="#019e58"
                v-if="tableData.length > 0"
                @click="toTeaching"
              >
@@ -270,7 +270,7 @@
    await toClipboard(val.refCode)
    ElMessage({
      message: '复制成功',
      type: 'success'
      type: 'success',
    })
  } catch (e) {
    console.error(e)
@@ -281,7 +281,7 @@
const getData = () => {
  MG.edu
    .getCourseClass({
      ClassIdOrRefCode: String(classInfo.id)
      ClassIdOrRefCode: String(classInfo.id),
    })
    .then((res: any) => {
      if (res) {
@@ -302,17 +302,17 @@
const getTopicInfo = () => {
  const pramas = {
    classId: classInfo.id,
    refCodes: [config.refCodes.message, config.refCodes.talk]
    refCodes: [config.refCode.message, config.refCode.talk],
  }
  MG.edu.getClassTopic(pramas).then((res: any) => {
    const list = res
    messageTopicInfo.value = list.find((item: any) => item.refCode == config.refCodes.message)
    messageTopicInfo.value = list.find((item: any) => item.refCode == config.refCode.message)
    if (messageTopicInfo.value.id) {
      sessionStorage.messageId = messageTopicInfo.value.id
      noticeLoading.value = true
      getNotice()
    }
    talkTopicInfo.value = list.find((item: any) => item.refCode == config.refCodes.talk)
    talkTopicInfo.value = list.find((item: any) => item.refCode == config.refCode.talk)
    if (talkTopicInfo.value.id) {
      sessionStorage.talkId = talkTopicInfo.value.id
      messageLoading.value = true
@@ -331,8 +331,8 @@
    sort: {
      type: 'Desc',
      field: 'CreateDate',
      subSorts: []
    }
      subSorts: [],
    },
  }
  MG.ugc.getTopicMessageList(data).then((res: any) => {
    noticeLoading.value = false
@@ -340,7 +340,7 @@
    noticeList.value = list.map((item: any) => {
      return {
        ...item,
        createDate: moment(item.createDate).format('YYYY-MM-DD')
        createDate: moment(item.createDate).format('YYYY-MM-DD'),
      }
    })
  })
@@ -356,8 +356,8 @@
    sort: {
      type: 'Desc',
      field: 'CreateDate',
      subSorts: []
    }
      subSorts: [],
    },
  }
  MG.ugc.getTopicMessageList(data).then((res: any) => {
    messageLoading.value = false
@@ -374,7 +374,7 @@
        ...item,
        index: i + 1,
        createDate: moment(item.createDate).format('YYYY-MM-DD HH:mm:ss'),
        updateDate: moment(item.updateDate).format('YYYY-MM-DD HH:mm:ss')
        updateDate: moment(item.updateDate).format('YYYY-MM-DD HH:mm:ss'),
      }
    })
  })
@@ -391,9 +391,9 @@
      {
        value: 'Normal',
        field: 'State',
        subFilters: []
      }
    ]
        subFilters: [],
      },
    ],
  }
  MG.identity.getGroupUserList(data).then((res: any) => {
    const { datas } = res
@@ -424,7 +424,7 @@
        return {
          ...item,
          index: index + 1,
          createDate: moment(item.createDate).format('YYYY-MM-DD')
          createDate: moment(item.createDate).format('YYYY-MM-DD'),
        }
      })
    }
@@ -442,8 +442,8 @@
  router.push({
    path: '/talkingPoint',
    query: {
      classInfo: JSON.stringify(classInfo)
    }
      classInfo: JSON.stringify(classInfo),
    },
  })
}
@@ -453,8 +453,8 @@
  router.push({
    path: '/info',
    query: {
      classInfo: JSON.stringify(classInfo)
    }
      classInfo: JSON.stringify(classInfo),
    },
  })
}
@@ -469,7 +469,7 @@
    sort: {
      type: 'Desc',
      field: 'CreateDate',
      subSorts: []
      subSorts: [],
    },
    filterList: [
      // {
@@ -480,10 +480,10 @@
      {
        value: config.taskType.homeWork,
        field: 'Type',
        subFilters: []
      }
        subFilters: [],
      },
    ],
    groupId: classInfo?.id
    groupId: classInfo?.id,
  }
  MG.edu
    .getTaskList(data)
@@ -495,7 +495,7 @@
            return {
              ...item,
              beginDate: moment(item.beginDate).format('YYYY-MM-DD'),
              endDate: moment(item.endDate).format('YYYY-MM-DD')
              endDate: moment(item.endDate).format('YYYY-MM-DD'),
            }
          })
          .slice(0, 3)
@@ -517,6 +517,7 @@
}
.classManagePage-box {
  padding: 20px;
  box-sizing: border-box;
  .classManagePage-nav {
    padding-bottom: 20px;
    border-bottom: 1px solid #e6e8ed;
@@ -625,7 +626,7 @@
      .titleBox {
        display: flex;
        align-items: center;
        margin: 20px 0;
        margin: 10px 0;
        font-size: 16px;
        .title {
          width: 100%;
@@ -694,11 +695,11 @@
    }
    .copyIdBtn {
      background-color: #fff;
      color: #3b93fe;
      padding: 0 6px;
      padding: 10px;
      border-radius: 50px;
      overflow: hidden;
      cursor: pointer;
      font-size: 14px;
    }
  }
  .avatarList {
src/views/classManage/components/questionDom.vue
@@ -283,7 +283,7 @@
    .list-item-title {
      padding: 4px 0;
      padding-left: 10px;
      border-left: 4px solid #ff6c00;
      border-left: 4px solid #019e58;
      color: #000;
      margin: 15px 0;
    }
@@ -307,7 +307,7 @@
      margin-top: 3px;
    }
    .el-checkbox__input.is-checked + .el-checkbox__label {
      color: #ff6c00;
      color: #019e58;
    }
  }
src/views/classManage/index.vue
@@ -1,6 +1,5 @@
<template>
  <div class="layoutBox">
    <Header class="header"></Header>
  <div class="layoutBoxClass">
    <div class="layoutContentBox clear">
      <div class="classContentBox clear">
        <div class="leftList fl">
@@ -50,126 +49,119 @@
</template>
<script setup lang="ts">
import { ref, watch, provide, onMounted, inject } from "vue";
import { useRoute, useRouter, onBeforeRouteUpdate } from "vue-router";
import Header from "./components/headerPage.vue";
import { menu } from "./config";
import { getPublicImage } from "@/assets/js/middleGround/tool.js";
import defaultImg from "@/assets/images/default-book-img.png";
import { ref, watch, provide, onMounted, inject } from 'vue'
import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router'
import { menu } from './config'
import { getPublicImage } from '@/assets/js/middleGround/tool.js'
import defaultImg from '@/assets/images/default-book-img.png'
const router: any = useRouter();
const route: any = useRoute();
const MG: any = inject("MG");
const config: any = inject("config");
const routerVal = router.currentRoute.value;
const path = ref(routerVal.path);
const label = ref("");
const classInfo: any = ref();
const classIcon: any = ref();
const listMenu = ref([]);
const activeIndex = ref(0);
const userData = ref();
const router: any = useRouter()
const route: any = useRoute()
const MG: any = inject('MG')
const config: any = inject('config')
const routerVal = router.currentRoute.value
const path = ref(routerVal.path)
const label = ref('')
const classInfo: any = ref()
const classIcon: any = ref()
const listMenu = ref([])
const activeIndex = ref(0)
const userData = ref()
watch(router.currentRoute, (val) => {
  path.value = val.path;
  path.value = val.path
  if (val.query.classInfo) {
    const data: any = val.query.classInfo;
    const routerInfo: any = JSON.parse(data);
    activeIndex.value = routerInfo.index;
    const data: any = val.query.classInfo
    const routerInfo: any = JSON.parse(data)
    activeIndex.value = routerInfo.index
  }
});
})
watch(classInfo, (val) => {
  if (val) {
    activeIndex.value = val.index;
    activeIndex.value = val.index
  }
  if (!val.index) {
    activeIndex.value = 0;
    activeIndex.value = 0
  }
});
})
onBeforeRouteUpdate(async (to, from) => {
  path.value = to.path;
});
  path.value = to.path
})
onMounted(() => {
  classInfo.value = JSON.parse(route.query.classInfo);
  classIcon.value = classInfo.value.icon
    ? getPublicImage(classInfo.value.icon, 200)
    : defaultImg;
  classInfo.value = JSON.parse(route.query.classInfo)
  classIcon.value = classInfo.value.icon ? getPublicImage(classInfo.value.icon, 200) : defaultImg
  menu.forEach((item) => {
    if ("/" + item.path === path.value) {
      label.value = item.label;
    if ('/' + item.path === path.value) {
      label.value = item.label
    }
  });
  const userCache: any = localStorage.getItem(config.userInfoKey);
  const userInfo = JSON.parse(userCache);
  userData.value = userInfo;
  })
  const userCache: any = localStorage.getItem(config.userInfoKey)
  const userInfo = JSON.parse(userCache)
  userData.value = userInfo
  if (!userInfo) {
    router.push({
      path: "/",
    });
    return false;
      path: '/',
    })
    return false
  }
  if (userInfo.role != "Teacher") {
  if (userInfo.role != 'Teacher') {
    const data: any = menu.filter(
      (item: any) => item.path != "studentManage" && item.path != "jobAnalysis"
    );
    listMenu.value = data;
      (item: any) => item.path != 'studentManage' && item.path != 'jobAnalysis',
    )
    listMenu.value = data
  } else {
    const data: any = menu;
    const data: any = menu
    // if (!classInfo.bookRefCode) {
    //   // 融媒体图书,无数字阅读,无法跳转
    //   const list: any = menu.filter((item: any) => item.path != 'teachingPlan')
    //   listMenu.value = list;
    //   return false
    // }
    listMenu.value = data;
    listMenu.value = data
  }
});
})
const goRouter = (item: any, index: number) => {
  activeIndex.value = index;
  if (
    !localStorage.getItem(config.tokenKey) ||
    localStorage.getItem(config.tokenKey) == null
  ) {
  activeIndex.value = index
  if (!localStorage.getItem(config.tokenKey) || localStorage.getItem(config.tokenKey) == null) {
    router.push({
      path: "/home",
      path: '/home',
      query: {
        showLogin: "1",
        showLogin: '1',
      },
    });
    })
  } else {
    label.value = item.label;
    classInfo.value.index = index;
    label.value = item.label
    classInfo.value.index = index
    if (item.key == 5) {
      router.push({
        path: userData.value.role != "Teacher" ? "/studentJob" : "/jobManage",
        path: userData.value.role != 'Teacher' ? '/studentJob' : '/jobManage',
        query: {
          classInfo: JSON.stringify(classInfo.value),
        },
      });
      })
    } else {
      router.push({
        path: item.path,
        query: {
          classInfo: JSON.stringify(classInfo.value),
        },
      });
      })
    }
  }
};
}
const goBack = () => {
  router.go(-1);
};
  router.go(-1)
}
</script>
<style lang="less" scoped>
.layoutBox {
.layoutBoxClass {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: #fff;
@@ -255,7 +247,12 @@
        }
        .activeItem {
          background: linear-gradient(90deg, #019e58 0%, #144941 100%);
          background-size: 100% 100%;
          color: #fff;
          svg {
            fill: #fff;
          }
        }
      }
    }
src/views/classManage/infoList.vue
@@ -29,7 +29,7 @@
              <el-table-column prop="id" label="序号" width="70" />
              <el-table-column prop="name" label="通知" width="500" />
              <el-table-column prop="state" label="状态" #default="scope">
                <span style="color: #ff6d00" v-if="scope.row.state == 'WaitAudit'">待审核</span>
                <span style="color: #019e58" v-if="scope.row.state == 'WaitAudit'">待审核</span>
                <span style="color: #67c23a" v-if="scope.row.state == 'Normal'">已通过</span>
                <span style="color: red" v-if="scope.row.state == 'Reject'">已拒绝</span>
              </el-table-column>
@@ -244,7 +244,7 @@
          color: #333;
          line-height: 30px;
          text-align: left;
          border-left: 6px solid #ff6c00;
          border-left: 6px solid #019e58;
          padding-left: 10px;
        }
      }
src/views/classManage/interactionDetail.vue
@@ -187,7 +187,7 @@
}
onMounted(() => {
  defaultCmsPath.value = classInfo.bookRefCode ? 'jsek_digitalTextbooks' : 'defaultGoodsStore3'
  defaultCmsPath.value = classInfo.bookRefCode ? 'digitalTextbooks' : 'defaultGoodsStore3'
  getMessage()
})
@@ -200,7 +200,6 @@
      path: defaultCmsPath.value,
      queryType: '*',
      productId: classInfo.bookId,
      storeInfo: defaultCmsPath.value,
      cmsPath: item.path,
      itemFields: {
        Embedded_QuestionBank_AnalysisCon: [],
@@ -355,7 +354,7 @@
          color: #333;
          line-height: 30px;
          text-align: left;
          border-left: 6px solid #ff6c00;
          border-left: 6px solid #019e58;
          padding-left: 10px;
        }
      }
@@ -365,7 +364,7 @@
      box-sizing: border-box;
      min-height: 750px;
      .userName {
        color: #ff6d00;
        color: #019e58;
      }
    }
  }
src/views/classManage/jobAnalysis.vue
@@ -261,6 +261,7 @@
.classManagePage-box {
  width: 100%;
  padding: 20px;
  box-sizing: border-box;
  .classManagePage-nav {
    padding-bottom: 20px;
    border-bottom: 1px solid #e6e8ed;
src/views/classManage/jobDetail.vue
@@ -747,7 +747,7 @@
        display: flex;
        justify-content: flex-start;
        align-items: center;
        border-left: 4px solid #ff6d00;
        border-left: 4px solid #019e58;
        span {
          margin-right: 15px;
        }
@@ -787,7 +787,7 @@
        height: 3px;
      }
      .content-user-box::-webkit-scrollbar-thumb {
        background-color: #ff6d00;
        background-color: #019e58;
        cursor: pointer;
      }
      .content-user-box::-webkit-scrollbar-track-piece {
src/views/classManage/jobManage.vue
@@ -317,7 +317,7 @@
                </el-table-column>
                <el-table-column label="分数" width="120">
                  <template #default="scope">
                    <span style="color: #ff6c00">{{ scope.row.score }}</span>
                    <span style="color: #019e58">{{ scope.row.score }}</span>
                  </template>
                </el-table-column>
                <el-table-column label="设置" width="260">
@@ -642,7 +642,7 @@
  if (userCache) {
    userInfo.value = JSON.parse(userCache)
  }
  defaultCmsPath.value = classInfo.bookRefCode ? 'jsek_digitalTextbooks' : 'defaultGoodsStore3'
  defaultCmsPath.value = classInfo.bookRefCode ? '*' : 'defaultGoodsStore3'
  getTaskList()
})
@@ -1261,7 +1261,6 @@
    path: defaultCmsPath.value,
    queryType: '*',
    productId: String(classInfo?.bookId),
    storeInfo: defaultCmsPath.value,
    cmsPath: classInfo?.rootCmsItemId,
  }
  MG.store
@@ -1276,7 +1275,6 @@
          path: defaultCmsPath.value,
          queryType: '*',
          productId: String(classInfo?.bookId),
          storeInfo: defaultCmsPath.value,
          cmsPath: obj.productLinkPath,
        }
        MG.store
@@ -1311,7 +1309,6 @@
      path: defaultCmsPath.value,
      queryType: '*',
      productId: String(classInfo?.bookId),
      storeInfo: defaultCmsPath.value,
      cmsPath: item.productLinkPath,
      itemFields: {
        Embedded_QuestionBank_AnalysisCon: [],
@@ -1347,7 +1344,6 @@
      path: defaultCmsPath.value,
      queryType: '*',
      productId: String(classInfo?.bookId),
      storeInfo: defaultCmsPath.value,
      cmsPath,
      itemFields: {
        Embedded_QuestionBank_AnalysisCon: [],
@@ -1384,7 +1380,6 @@
      path: defaultCmsPath.value,
      queryType: '*',
      productId: String(classInfo?.bookId),
      storeInfo: defaultCmsPath.value,
      cmsPath: item.productLinkPath,
    }
    MG.store
@@ -1594,13 +1589,13 @@
          color: #333;
          line-height: 30px;
          text-align: left;
          border-left: 6px solid #ff6c00;
          border-left: 6px solid #019e58;
          padding-left: 10px;
        }
      }
      margin-top: 20px;
      ::v-deep .el-tabs__nav-wrap::after {
        background-color: #ff6d00;
        background-color: #019e58;
        height: 1px;
      }
@@ -1611,7 +1606,7 @@
      }
      ::v-deep .is-active {
        background-color: #ff6d00;
        background-color: #019e58;
        color: #fff;
        border-radius: 3px 3px 0 0;
      }
@@ -1748,6 +1743,7 @@
          background: #e0f2ff;
          overflow: auto;
          padding: 10px 18px;
          box-sizing: border-box;
          .searchBox {
            position: sticky;
            top: -10px;
@@ -1877,7 +1873,7 @@
    .leftBg {
      background-color: rgba(255, 173, 65, 0.1);
      border-radius: 5px 5px 5px 5px;
      color: #ff6c00 !important;
      color: #019e58 !important;
    }
    .pageBox {
      padding: 10px 0;
src/views/classManage/studentJob.vue
@@ -44,7 +44,7 @@
          <el-table-column label="序号" prop="id" width="70"> </el-table-column>
          <el-table-column label="名称" prop="name"> </el-table-column>
          <el-table-column label="作业完成情况" #default="scope">
            <span v-if="scope.row.submitState == 'WaitCheck'" style="color: #ff6d00">待批改</span>
            <span v-if="scope.row.submitState == 'WaitCheck'" style="color: #019e58">待批改</span>
            <span v-if="scope.row.submitState == 'Normal'" style="color: #67c23a">已批改</span>
            <span v-if="!scope.row.submitState" style="color: red">未提交</span>
          </el-table-column>
@@ -303,13 +303,13 @@
          color: #333;
          line-height: 30px;
          text-align: left;
          border-left: 6px solid #ff6c00;
          border-left: 6px solid #019e58;
          padding-left: 10px;
        }
      }
      margin-top: 20px;
      ::v-deep .el-tabs__nav-wrap::after {
        background-color: #ff6d00;
        background-color: #019e58;
        height: 1px;
      }
@@ -320,7 +320,7 @@
      }
      ::v-deep .is-active {
        background-color: #ff6d00;
        background-color: #019e58;
        color: #fff;
        border-radius: 3px 3px 0 0;
      }
src/views/classManage/talkDetail.vue
@@ -190,11 +190,11 @@
const getTopicInfo = () => {
  const pramas = {
    classId: classInfo.id,
    refCodes: [config.refCodes.talk]
    refCodes: [config.refCode.talk]
  }
  MG.edu.getClassTopic(pramas).then((res: any) => {
    const list = res
    talkTopicInfo.value = list.find((item: any) => item.refCode == config.refCodes.talk)
    talkTopicInfo.value = list.find((item: any) => item.refCode == config.refCode.talk)
    if (talkTopicInfo.value.id) {
      getMessage()
    }
@@ -395,6 +395,7 @@
        .MessageBox {
          width: 100%;
          padding: 0 30px;
          box-sizing: border-box;
          .MessageHeader {
            width: 100%;
            display: flex;
src/views/classManage/talkingPoint.vue
@@ -37,7 +37,7 @@
          <el-table-column prop="index" label="序号" width="70" />
          <el-table-column label="话题名称" width="500">
            <template #default="scope">
              <span style="color: #ff6c00" v-if="scope.row.name">{{ scope.row.name }}</span>
              <span style="color: #019e58" v-if="scope.row.name">{{ scope.row.name }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="createDate" label="发起日期" />
@@ -172,11 +172,11 @@
const getTopicInfo = () => {
  const pramas = {
    classId: classInfo.id,
    refCodes: [config.refCodes.talk]
    refCodes: [config.refCode.talk]
  }
  MG.edu.getClassTopic(pramas).then((res: any) => {
    const list = res
    talkTopicInfo.value = list.find((item: any) => item.refCode == config.refCodes.talk)
    talkTopicInfo.value = list.find((item: any) => item.refCode == config.refCode.talk)
    if (talkTopicInfo.value.id) {
      getMessage()
    }
src/views/classManage/teachInteraction.vue
@@ -40,7 +40,7 @@
          <el-table-column prop="name" label="标题" width="500" />
          <el-table-column prop="address" label="已互动学生数" #default="scoped">
            <div>
              <span style="color: #ff6d00">{{ scoped.row.subList.length }}</span>
              <span style="color: #019e58">{{ scoped.row.subList.length }}</span>
            </div>
          </el-table-column>
          <el-table-column prop="address" label="最后提交时间" #default="scoped">
@@ -122,7 +122,7 @@
  if (userCache) {
    userInfo.value = JSON.parse(userCache)
  }
  defaultCmsPath.value = classInfo.bookRefCode ? 'jsek_digitalTextbooks' : config.goodsStore
  defaultCmsPath.value = classInfo.bookRefCode ? '*' : config.goodsStore
  getData()
})
@@ -150,7 +150,6 @@
        path: defaultCmsPath.value,
        queryType: '*',
        productId: classInfo.bookId,
        storeInfo: defaultCmsPath.value,
        cmsPath: classInfo.rootCmsItemId
      })
      .then((res: any) => {
@@ -162,7 +161,6 @@
            .getProductDetail({
              path: defaultCmsPath.value,
              queryType: '*',
              storeInfo: defaultCmsPath.value,
              productId: classInfo.bookId,
              cmsPath: data.productLinkPath
            })
@@ -176,7 +174,6 @@
                    path: defaultCmsPath.value,
                    queryType: '*',
                    productId: classInfo.bookId,
                    storeInfo: defaultCmsPath.value,
                    cmsPath: dataTeach.productLinkPath
                  })
                  .then((res: any) => {
@@ -188,7 +185,6 @@
                            path: defaultCmsPath.value,
                            queryType: '*',
                            productId: classInfo.bookId,
                            storeInfo: defaultCmsPath.value,
                            cmsPath: item.productLinkPath,
                            cmsSort: {
                              ProductLinkOrder: 'Desc'
@@ -239,12 +235,12 @@
const getTopicInfo = () => {
  const pramas = {
    classId: classInfo.id,
    refCodes: [config.refCodes.teachInteraction]
    refCodes: [config.refCode.teachInteraction]
  }
  MG.edu.getClassTopic(pramas).then((res: any) => {
    const list = res
    teachInteractionInfo.value = list.find(
      (item: any) => item.refCode == config.refCodes.teachInteraction
      (item: any) => item.refCode == config.refCode.teachInteraction
    )
    if (teachInteractionInfo.value.id) {
      getMessage()
@@ -482,7 +478,7 @@
            color: #333;
            line-height: 30px;
            text-align: left;
            border-left: 6px solid #ff6c00;
            border-left: 6px solid #019e58;
            padding-left: 10px;
          }
        }
@@ -504,7 +500,7 @@
      box-sizing: border-box;
      overflow-y: auto;
      .userName {
        color: #ff6d00;
        color: #019e58;
      }
    }
  }
src/views/classManage/teachingPlan.vue
@@ -585,7 +585,7 @@
const getTypeByCode = () => {
  MG.resource
    .getCmsTypeByRefCode({
      refCodes: [config.refCodes.teachingPlan],
      refCodes: [config.refCode.teachingPlan],
    })
    .then((res: any) => {
      const data = res[0]?.cmsTypeLinks[0]?.children;
@@ -751,7 +751,7 @@
        name: taskItem.title,
        description: "",
        icon: "",
        type: config.refCodes.teachingPlan,
        type: config.refCode.teachingPlan,
        state: "Normal",
        order: 0,
        newDataListRequest: tool.worksDataBytool(
@@ -838,7 +838,7 @@
      }
    }
    .linkTitle {
      color: #ff6c00;
      color: #019e58;
      cursor: pointer;
    }
    .linkTitle:hover {
src/views/courseManage/components/class.vue
@@ -292,7 +292,7 @@
//   coursePages.loading = true
//   const searchData = [
//     {
//       keywords: 'jsek_digitalTextbooks',
//       keywords: 'digitalTextbooks',
//       field: 'ProductType'
//     }
//   ]
@@ -392,7 +392,7 @@
    min-height: 200px;
    .classItem {
      float: left;
      width: 49%;
      width: 48%;
      margin-bottom: 16px;
      margin-right: 1%;
      border-radius: 8px;
@@ -433,6 +433,7 @@
      .itemInfo {
        height: 128px;
        padding: 20px;
        box-sizing: border-box;
        flex: 1;
        display: flex;
        cursor: pointer;
src/views/courseManage/index.vue
@@ -15,7 +15,9 @@
        <img
          v-if="detailData?.linkProduct?.icon != 'default'"
          :src="
            detailData.linkProduct?.icon ? getPublicImage(detailData.linkProduct.icon, 80) : defaultImg
            detailData.linkProduct?.icon
              ? getPublicImage(detailData.linkProduct.icon, 80)
              : defaultImg
          "
        />
      </div>
@@ -85,10 +87,10 @@
      size: 999,
      sort: {
        type: 'Desc',
        field: 'CreateDate'
        field: 'CreateDate',
      },
      filterList: [],
      searchList: []
      searchList: [],
    })
    .then((res: any) => {
      numClass.value = res.datas.length
@@ -99,7 +101,7 @@
const getData = () => {
  MG.edu
    .getCourseById({
      courseId: query.courseId
      courseId: query.courseId,
    })
    .then((res: any) => {
      detailData.value = res
@@ -118,14 +120,14 @@
    productId: String(shopId),
    coverSize: {
      height: 300,
      width: 210
      width: 210,
    },
    fields: {
      seriesName: [],
      author: [],
      isbn: [],
      publicationDate: []
    }
      publicationDate: [],
    },
  }
  MG.store.getProductDetail(query).then(async (res: any) => {
    bookDetail.value = res.datas
@@ -138,6 +140,24 @@
</script>
<style lang="less" scoped>
.autoImgBox {
  width: 120px;
  height: 130px;
  margin-bottom: 10px;
  position: relative;
  img {
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 100%;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
  }
}
.courseManage {
  padding: 0 20px;
  .backBox {
src/views/personalCenter/activeCode.vue
@@ -171,7 +171,7 @@
          if (parentData.storeLinks[0].storeRefCode == "jsek_digitalCourses") {
            obj.type = "数字课程";
          }
          if (parentData.storeLinks[0].storeRefCode == "jsek_digitalTextbooks") {
          if (parentData.storeLinks[0].storeRefCode == "digitalTextbooks") {
            obj.type = "数字教材";
          }
          item.typeList.push(obj);
@@ -217,7 +217,7 @@
        bookName: parentData.name,
      },
    });
  } else if (parentData.storeLinks[0].storeRefCode == "jsek_digitalTextbooks") {
  } else if (parentData.storeLinks[0].storeRefCode == "digitalTextbooks") {
    router.push({
      name: "digitalTextbooksDetails",
      query: {
src/views/personalCenter/class.vue
@@ -313,7 +313,7 @@
// 获取教材详情
const getBookDetail = async (item: any) => {
  const path = item.refCode ? "jsek_digitalTextbooks" : config.goodsStore;
  const path = item.refCode ? "digitalTextbooks" : config.goodsStore;
  let query = {
    path,
    queryType: "*",
@@ -419,7 +419,8 @@
        }
      }
      .itemInfo {
        padding: 20px;
        padding: 15px;
        box-sizing: border-box;
        flex: 1;
        display: flex;
        cursor: pointer;
src/views/personalCenter/course.vue
@@ -3,20 +3,13 @@
    <div class="personalPage-title">我的课程</div>
    <div class="headerBox">
      <div class="searchBox">
        <el-input
          v-model="searchKey"
          clearable
          @clear="getData"
          placeholder="请输入关键字"
        >
        <el-input v-model="searchKey" clearable @clear="getData" placeholder="请输入关键字">
          <template #append>
            <el-button type="primary" class="searchBtn" :icon="Search" @click="getData" />
          </template>
        </el-input>
      </div>
      <el-button type="primary" class="applyStartClasses" @click="applyCourse"
        >申请开课</el-button
      >
      <el-button type="primary" class="applyStartClasses" @click="applyCourse">申请开课</el-button>
    </div>
    <div class="courseListBox" v-loading="pages.loading">
      <div
@@ -34,7 +27,7 @@
              <div style="width: 300px" v-html="item.reason"></div>
            </template>
            <span v-if="item.applyState == 'Reject'" style="color: red">
              拒绝原因:{{ item.reason != "" ? item.reason : "-" }}
              拒绝原因:{{ item.reason != '' ? item.reason : '-' }}
            </span>
          </el-tooltip>
          <el-button
@@ -63,11 +56,7 @@
            >
              审核中
            </div>
            <div
              class="stateIcon"
              v-if="item.applyState == 'Reject'"
              style="background-color: red"
            >
            <div class="stateIcon" v-if="item.applyState == 'Reject'" style="background-color: red">
              未通过
            </div>
            <img v-if="item.icon" :src="item.icon" />
@@ -97,13 +86,8 @@
    </div>
    <!-- 申请开课弹框 -->
    <el-dialog v-model="applyCourseDialog" width="750" align-center>
      <template #title>{{ editData ? "重新申请" : "申请开课" }}</template>
      <el-form
        :model="formData"
        label-position="left"
        ref="dialogFormRef"
        label-width="80px"
      >
      <template #title>{{ editData ? '重新申请' : '申请开课' }}</template>
      <el-form :model="formData" label-position="left" ref="dialogFormRef" label-width="80px">
        <el-form-item
          label="课程名称"
          prop="name"
@@ -137,9 +121,7 @@
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="applyCourseDialog = false">取消</el-button>
          <el-button type="primary" @click="submit" :loading="submitLoading"
            >提交</el-button
          >
          <el-button type="primary" @click="submit" :loading="submitLoading">提交</el-button>
        </div>
      </template>
    </el-dialog>
@@ -156,37 +138,21 @@
              placeholder="请输入关键字"
            >
              <template #append>
                <el-button
                  type="primary"
                  class="searchBtn"
                  :icon="Search"
                  @click="getTextBook"
                />
                <el-button type="primary" class="searchBtn" :icon="Search" @click="getTextBook" />
              </template>
            </el-input>
          </div>
        </div>
        <div style="min-height: 370px" v-if="textBookListData.length > 0">
          <div
            v-for="(item, index) in textBookListData"
            :key="index"
            class="textBookItem"
          >
            <el-checkbox
              class="checkBox"
              v-model="item.check"
              @change="selectChange(item)"
            />
          <div v-for="(item, index) in textBookListData" :key="index" class="textBookItem">
            <el-checkbox class="checkBox" v-model="item.check" @change="selectChange(item)" />
            <div class="imgBox autoImgBox">
              <img :src="item.img" />
            </div>
            <p>{{ item.product.name }}</p>
          </div>
        </div>
        <div
          class="nullBox"
          v-if="!textBookPages.loading && textBookListData.length == 0"
        >
        <div class="nullBox" v-if="!textBookPages.loading && textBookListData.length == 0">
          <el-empty />
        </div>
      </div>
@@ -211,137 +177,137 @@
</template>
<script setup lang="ts">
import { reactive, ref, onMounted, inject, watch } from "vue";
import { Search } from "@element-plus/icons-vue";
import { useRouter, useRoute } from "vue-router";
import { ElMessage } from "element-plus";
import { reactive, ref, onMounted, inject, watch } from 'vue'
import { Search } from '@element-plus/icons-vue'
import { useRouter, useRoute } from 'vue-router'
import { ElMessage } from 'element-plus'
// eslint-disable-next-line
import { getPublicImage } from "@/assets/js/middleGround/tool.js";
import { getPublicImage } from '@/assets/js/middleGround/tool.js'
// eslint-disable-next-line
import defaultImg from "@/assets/images/default-book-img.png";
import defaultImg from '@/assets/images/default-book-img.png'
const router: any = useRouter();
const route: any = useRoute();
const MG: any = inject("MG");
const selectName = ref("");
const router: any = useRouter()
const route: any = useRoute()
const MG: any = inject('MG')
const selectName = ref('')
// 申请开课防抖loading
const submitLoading = ref(false);
const submitLoading = ref(false)
const courseList: any = ref([]);
const courseList: any = ref([])
onMounted(() => {
  getData();
});
  getData()
})
const searchKey = ref("");
const searchKey = ref('')
const pages = reactive({
  page: 1,
  pageSize: 6,
  count: 0,
  loading: true,
});
})
// 获取课程
const getData = () => {
  pages.loading = true;
  pages.loading = true
  MG.edu
    .getAppCourseList({
      size: pages.pageSize,
      start: pages.pageSize * pages.page - pages.pageSize,
      sort: {
        type: "Desc",
        field: "CreateDate",
        type: 'Desc',
        field: 'CreateDate',
      },
      filterList: [],
      searchList: searchKey.value
        ? [
            {
              keywords: searchKey.value,
              field: "Name",
              compareType: "Contains",
              field: 'Name',
              compareType: 'Contains',
            },
          ]
        : [],
    })
    .then((res: any) => {
      pages.loading = false;
      pages.count = res.totalSize;
      pages.loading = false
      pages.count = res.totalSize
      courseList.value = res.datas.map((item: any) => {
        return {
          ...item,
          name: item.name,
          id: item.id,
          icon: item.icon != "default" ? getPublicImage(item.icon, 80) : defaultImg,
          icon: item.icon != 'default' ? getPublicImage(item.icon, 80) : defaultImg,
          introduction: item.description,
          reason: item.applyReturnMsg ? JSON.parse(item.applyReturnMsg).reason : "",
        };
      });
    });
};
          reason: item.applyReturnMsg ? JSON.parse(item.applyReturnMsg).reason : '',
        }
      })
    })
}
// 申请开课
const applyCourse = () => {
  editData.value = null;
  editData.value = null
  formData.value = {
    name: "",
    bookName: "",
    bookId: "",
    selectData: "",
    desc: "",
  };
  applyCourseDialog.value = true;
};
    name: '',
    bookName: '',
    bookId: '',
    selectData: '',
    desc: '',
  }
  applyCourseDialog.value = true
}
const editData: any = ref(null);
const editData: any = ref(null)
const reapplyCourse = (data: any) => {
  editData.value = data;
  editData.value = data
  formData.value = {
    name: data.name,
    bookName: data.linkProduct.name,
    bookId: data.linkProduct.id,
    selectData: "",
    selectData: '',
    desc: data.description,
  };
  applyCourseDialog.value = true;
};
  }
  applyCourseDialog.value = true
}
// 申请教材弹框
const applyCourseDialog = ref(false);
const selectTextBookDialog = ref(false);
const applyCourseDialog = ref(false)
const selectTextBookDialog = ref(false)
const formData = ref({
  name: "",
  bookName: "",
  bookId: "",
  selectData: "",
  desc: "",
});
  name: '',
  bookName: '',
  bookId: '',
  selectData: '',
  desc: '',
})
const selectChange = (select: any) => {
  for (let i = 0; i < textBookListData.value.length; i++) {
    const item: any = textBookListData.value[i];
    const item: any = textBookListData.value[i]
    if (item.id == select.id) {
      item.check = true;
      item.check = true
    } else {
      item.check = false;
      item.check = false
    }
  }
};
}
const selectTextBookSubmit = () => {
  const selectData: any = textBookListData.value.filter((item: any) => item.check)[0];
  const selectData: any = textBookListData.value.filter((item: any) => item.check)[0]
  if (!selectData?.product?.id) {
    ElMessage.warning("请选择开课教材!");
    return false;
    ElMessage.warning('请选择开课教材!')
    return false
  }
  formData.value.bookId = selectData.product.id;
  formData.value.bookName = selectData.product.name;
  formData.value.selectData = selectData;
  selectTextBookDialog.value = false;
};
  formData.value.bookId = selectData.product.id
  formData.value.bookName = selectData.product.name
  formData.value.selectData = selectData
  selectTextBookDialog.value = false
}
const submit = () => {
  submitLoading.value = true;
  submitLoading.value = true
  if (editData.value) {
    MG.edu
      .updateCourse({
@@ -359,36 +325,36 @@
            }),
          })
          .then((ares: any) => {
            ElMessage.success("课程已重新申请,等待管理员审核。");
            applyCourseDialog.value = false;
            getData();
          });
      });
            ElMessage.success('课程已重新申请,等待管理员审核。')
            applyCourseDialog.value = false
            getData()
          })
      })
  } else {
    if (formData.value.name == "") {
    if (formData.value.name == '') {
      ElMessage({
        type: "warning",
        message: "请填写课程名称",
      });
      submitLoading.value = false;
      return false;
        type: 'warning',
        message: '请填写课程名称',
      })
      submitLoading.value = false
      return false
    }
    if (!formData.value.bookId) {
      ElMessage({
        type: "warning",
        message: "请选择关联教材",
      });
      submitLoading.value = false;
      return false;
        type: 'warning',
        message: '请选择关联教材',
      })
      submitLoading.value = false
      return false
    }
    MG.edu
      .applyNewCourse({
        name: formData.value.name,
        description: formData.value.desc,
        content: "",
        icon: formData.value.selectData.product.icon ?? "default",
        type: "course",
        config: "",
        content: '',
        icon: formData.value.selectData.product.icon ?? 'default',
        type: 'course',
        config: '',
        applyData: JSON.stringify({
          textBookId: formData.value.bookId,
          textBookName: formData.value.bookName,
@@ -399,17 +365,17 @@
      })
      .then((res: any) => {
        if (res) {
          ElMessage.success("课程已申请,等待管理员审核。");
          applyCourseDialog.value = false;
          getData();
          ElMessage.success('课程已申请,等待管理员审核。')
          applyCourseDialog.value = false
          getData()
        }
      });
      })
  }
  formData.value.selectData = "";
  formData.value.selectData = ''
  setTimeout(() => {
    submitLoading.value = false;
  }, 1000);
};
    submitLoading.value = false
  }, 1000)
}
// 获取已购买的教材列表
const textBookPages = reactive({
@@ -417,77 +383,77 @@
  pageSize: 12,
  count: 0,
  loading: false,
});
const textBookListData = ref([]);
})
const textBookListData = ref([])
const getTextBook = () => {
  textBookPages.loading = true;
  textBookPages.loading = true
  const searchData = [
    {
      keywords: "digitalTextbooks",
      field: "ProductType",
      keywords: 'digitalTextbooks',
      field: 'ProductType',
    },
    {
      keywords: "mediaBook",
      field: "ProductType",
      keywords: 'mediaBook',
      field: 'ProductType',
    },
    {
      keywords: selectName.value,
      field: "ProductName",
      field: 'ProductName',
    },
  ];
  ]
  const data = {
    Size: textBookPages.pageSize,
    Start: textBookPages.pageSize * textBookPages.page - textBookPages.pageSize,
    sort: {
      type: "Desc",
      field: "CreateDate",
      type: 'Desc',
      field: 'CreateDate',
    },
    searchList: searchData,
  };
  }
  MG.store
    .getPurchasedProductList(data)
    .then((res: any) => {
      textBookPages.count = res.totalSize;
      textBookPages.count = res.totalSize
      textBookListData.value = res.datas.map((item: any) => {
        return {
          ...item,
          img: item.product.icon ? getPublicImage(item.product.icon, 80) : defaultImg,
        };
      });
      textBookPages.loading = false;
        }
      })
      textBookPages.loading = false
    })
    .catch(() => {
      textBookPages.loading = false;
    });
};
      textBookPages.loading = false
    })
}
// 选择教材
const selectBook = () => {
  selectTextBookDialog.value = true;
  textBookListData.value = [];
  getTextBook();
};
  selectTextBookDialog.value = true
  textBookListData.value = []
  getTextBook()
}
const pageChange = (val: any) => {
  pages.page = val;
  getData();
};
  pages.page = val
  getData()
}
const handleCurrentChange = (val: any) => {
  textBookPages.page = val;
  getTextBook();
};
  textBookPages.page = val
  getTextBook()
}
const gotoDetail = (data: any) => {
  if (data.applyState == "Normal") {
  if (data.applyState == 'Normal') {
    router.push({
      name: "courseDetail",
      name: 'courseDetail',
      query: {
        courseId: data.id,
      },
    });
    })
  }
};
}
</script>
<style lang="less" scoped>
@@ -520,7 +486,7 @@
    .courseItem {
      float: left;
      width: 46%;
      width: 45%;
      height: 210px;
      margin: 0 2% 20px;
      border-radius: 8px;
@@ -561,6 +527,7 @@
      .itemInfo {
        padding: 10px 20px;
        box-sizing: border-box;
        flex: 1;
        display: flex;
        .imgBox {
src/views/personalCenter/index.vue
@@ -41,58 +41,56 @@
</template>
<script setup lang="ts">
import { ArrowRight } from "@element-plus/icons-vue";
import { menu } from "./config.ts";
import { useRouter, onBeforeRouteUpdate } from "vue-router";
import { ref, onMounted, inject } from "vue";
const router = useRouter();
const routerVal = router.currentRoute.value;
const path = ref(routerVal.path);
const label = ref("");
const listMenu: any = ref([]);
const MG: any = inject("MG");
const config: any = inject("config");
import { ArrowRight } from '@element-plus/icons-vue'
import { menu } from './config'
import { useRouter, onBeforeRouteUpdate } from 'vue-router'
import { ref, onMounted, inject } from 'vue'
const router = useRouter()
const routerVal = router.currentRoute.value
const path = ref(routerVal.path)
const label = ref('')
const listMenu: any = ref([])
const MG: any = inject('MG')
const config: any = inject('config')
onBeforeRouteUpdate(async (to, from) => {
  path.value = to.fullPath;
});
  path.value = to.fullPath
})
onMounted(() => {
  menu.forEach((item) => {
    if ("/" + item.path === path.value) {
      label.value = item.label;
    if ('/' + item.path === path.value) {
      label.value = item.label
    }
  });
  const userCache: any = localStorage.getItem(config.userInfoKey);
  const userInfo = JSON.parse(userCache);
  })
  const userCache: any = localStorage.getItem(config.userInfoKey)
  const userInfo = JSON.parse(userCache)
  if (!userInfo) {
    router.push({
      path: "/",
    });
    return false;
      path: '/',
    })
    return false
  }
  if (userInfo.role == "Teacher") {
    const data: any = menu.filter((item) => item.path != "myClass");
    listMenu.value = data;
  } else {
    const data: any = menu.filter((item) => item.path != "myCourse");
    listMenu.value = data;
  }
});
  // if (userInfo.role == 'Teacher') {
  //   const data: any = menu.filter((item) => item.path != 'myClass')
  //   listMenu.value = data
  // } else {
  //   const data: any = menu.filter((item) => item.path != 'myCourse')
  //   listMenu.value = data
  // }
  listMenu.value = menu
})
const goRouter = (item: any) => {
  if (
    !localStorage.getItem(config.tokenKey) ||
    localStorage.getItem(config.tokenKey) == null
  ) {
  if (!localStorage.getItem(config.tokenKey) || localStorage.getItem(config.tokenKey) == null) {
    router.push({
      path: "/home",
      path: '/home',
      query: {
        showLogin: "1",
        showLogin: '1',
      },
    });
    })
  } else {
    label.value = item.label;
    router.push({ path: item.path });
    label.value = item.label
    router.push({ path: item.path })
  }
};
}
</script>
<style lang="less" scoped>
.breadcrumbBox {
src/views/personalCenter/myApply.vue
@@ -22,11 +22,7 @@
                  reviewstatusWait: item.state == 'WaitAudit',
                }"
                >{{
                  item.state == "WaitAudit"
                    ? "审核中"
                    : item.state == "Normal"
                    ? "通过"
                    : "拒绝"
                  item.state == 'WaitAudit' ? '审核中' : item.state == 'Normal' ? '通过' : '拒绝'
                }}</span
              >
            </div>
@@ -37,23 +33,17 @@
              试用期限:<span>{{ item.updateDate }}</span> --
              <span>{{ item.feedBack.endDate }}</span>
            </div>
            <div style="color: orangered" v-if="item.isExpiry">
              阅读期限:<span>已过期</span>
            </div>
            <div style="color: orangered" v-if="item.isExpiry">阅读期限:<span>已过期</span></div>
            <div class="time">申请时间:{{ item.updateDate }}</div>
          </div>
          <div
            class="reasonForFailure"
            style="margin: 10px 0"
            v-if="item.state == 'Reject'"
          >
          <div class="reasonForFailure" style="margin: 10px 0" v-if="item.state == 'Reject'">
            <div class="centerVertically">未通过原因:</div>
            <div
              style="flex: 1"
              class="ellipsis-3"
              :title="item.feedBack.reason ? item.feedBack.reason : ' - '"
            >
              {{ item.feedBack.reason ? item.feedBack.reason : " - " }}
              {{ item.feedBack.reason ? item.feedBack.reason : ' - ' }}
            </div>
          </div>
        </div>
@@ -115,97 +105,98 @@
  </div>
</template>
<script setup lang="ts">
import { reactive, ref, onMounted, inject } from "vue";
import { getPublicImage } from "@/assets/js/middleGround/tool";
import { useRouter } from "vue-router";
const MG: any = inject("MG");
const config: any = inject("config");
const router = useRouter();
let listData = ref([]);
let loading = ref(false);
import { reactive, ref, onMounted, inject } from 'vue'
import { getPublicImage } from '@/assets/js/middleGround/tool'
import { useRouter } from 'vue-router'
import defaultImg from '@/assets/images/default-book-img.png'
const MG: any = inject('MG')
const config: any = inject('config')
const router = useRouter()
let listData = ref([])
let loading = ref(false)
let paginationData = reactive({
  page: 1,
  limit: 10,
  totalCount: 0,
  totalPage: 0,
});
let inputPage = ref(1);
})
let inputPage = ref(1)
const getTextBookList = () => {
  loading.value = true;
  let { page, limit } = paginationData;
  loading.value = true
  let { page, limit } = paginationData
  const data = {
    start: limit * page - limit,
    size: limit,
    topicIdOrRefCode: "applyDigitalBook",
    topicIdOrRefCode: 'applyDigitalBook',
    appRefCode: config.appRefCode,
    sort: {
      type: "Desc",
      field: "CreateDate",
      type: 'Desc',
      field: 'CreateDate',
    },
  };
  }
  MG.ugc.getTopicMessageList(data).then((res) => {
    loading.value = false;
    loading.value = false
    res.datas.forEach((item) => {
      item.icon = item.icon ? item.icon : getPublicImage(null);
      item.updateDate = item.updateDate.split("T")[0];
      item.icon = item.icon ? item.icon : getPublicImage(null)
      item.updateDate = item.updateDate.split('T')[0]
      if (item.feedBack) {
        item.feedBack = JSON.parse(item.feedBack);
        item.feedBack = JSON.parse(item.feedBack)
        if (item.feedBack.endDate) {
          let times = new Date(item.feedBack.endDate + " 23:59:59").getTime();
          let times = new Date(item.feedBack.endDate + ' 23:59:59').getTime()
          if (times < sessionStorage.currentDate) {
            item.isExpiry = true;
            item.isExpiry = true
          }
        }
      }
      if (item.content) {
        item.content = JSON.parse(item.content)[0] ?? {};
        item.content = JSON.parse(item.content)[0] ?? {}
        if (!item.content?.icon) {
          item.content.icon = require("@/assets/images/default-book-img.png");
          item.content.icon = defaultImg
        }
      }
    });
    paginationData.totalCount = res.totalSize;
    paginationData.totalPage = Math.ceil(res.totalSize / limit);
    listData.value = res.datas;
  });
};
    })
    paginationData.totalCount = res.totalSize
    paginationData.totalPage = Math.ceil(res.totalSize / limit)
    listData.value = res.datas
  })
}
onMounted(() => {
  getTextBookList();
});
  getTextBookList()
})
const toDetail = (item: any) => {
  router.push({
    name: "digitalTextbooks-textbooksDetail",
    name: 'digitalTextbooks-textbooksDetail',
    query: {
      id: item.id,
      rootCmsItemId: item.rootCmsItemId,
    },
  });
};
  })
}
const read = (pItem: any) => {
  let token = MG.tool.getCookie(config.tokenKey);
  window.open(config.textReaderUrl + "?bookId=" + pItem.refCode + "&token=" + token);
};
  let token = MG.tool.getCookie(config.tokenKey)
  window.open(config.textReaderUrl + '?bookId=' + pItem.refCode + '&token=' + token)
}
const handleSizeChange = (val: number) => {
  paginationData.limit = val;
  getTextBookList();
};
  paginationData.limit = val
  getTextBookList()
}
const handleCurrentChange = (val: number) => {
  paginationData.page = val;
  getTextBookList();
};
  paginationData.page = val
  getTextBookList()
}
const jumpFun = (event: any) => {
  event.target.blur();
  event.target.blur()
  if (inputPage.value <= 0) {
    inputPage.value = 1;
    inputPage.value = 1
  }
  if (inputPage.value > paginationData.totalPage) {
    inputPage.value = paginationData.totalPage;
    inputPage.value = paginationData.totalPage
  }
  paginationData.page = inputPage.value;
  getTextBookList();
};
  paginationData.page = inputPage.value
  getTextBookList()
}
</script>
<style scoped lang="less">
.myCarTopPage {
src/views/personalCenter/myCart.vue
@@ -246,7 +246,7 @@
//表单的样式
const cellStyle = ({ row, column, rowIndex, columnIndex }) => {
  if (columnIndex === 4) {
    return { color: "#FF6C00" };
    return { color: "#019e58" };
  }
};
@@ -262,7 +262,7 @@
  MG.store.getShoppingCartProductList(query).then((res) => {
    const newData = res.datas.map((item) => {
      console.log(item.saleMethod.type, "item.saleMethod.type");
      if (item.productMonWithLinkDto.links[0].storeRefCode == "jsek_digitalTextbooks") {
      if (item.productMonWithLinkDto.links[0].storeRefCode == "digitalTextbooks") {
        item.typeTxt = "数字教材";
        item.productType = "数字教材";
      } else if (
src/views/personalCenter/myCollection.vue
@@ -84,7 +84,7 @@
  count: 0,
  loading: false,
});
let linkType = ref("FavoriteTextBooks");
let linkType = ref("FavoriteBookCity");
const tabCart = (event: Event) => {
  pages.page = 1;
@@ -92,7 +92,7 @@
  collectList.value = [];
  currentCollect.value = event.props.name;
  if (currentCollect.value == "textBooks") {
    linkType.value = "FavoriteTextBooks";
    linkType.value = "FavoriteBookCity";
  }
  getDataList();
};
src/views/personalCenter/myOrder.vue
@@ -69,7 +69,7 @@
                      </div>
                      <span class="state">{{
                        pItem.orderSaleMethod.product.cmsTypeRefCode ==
                        "jsek_digitalTextbooks"
                        "digitalTextbooks"
                          ? "数字教材"
                          : pItem.orderSaleMethod.product.cmsTypeRefCode ==
                            "jsek_digitalCourses"
src/views/personalCenter/userInfo.vue
@@ -8,9 +8,7 @@
          <div class="info-box flex">
            <span class="label">用户名:</span>
            <span class="text">{{ userStore?.userInfo.name }}</span>
            <span class="change-info hover" @click="changeUserInfo('password')"
              >修改密码</span
            >
            <span class="change-info hover" @click="changeUserInfo('password')">修改密码</span>
          </div>
          <div class="info-box flex">
            <span class="label">微信认证:</span>
@@ -27,24 +25,23 @@
            }}</span>
            <span class="text no" v-else>未绑定</span>
            <span class="change-info hover" @click="changeUserInfo('phone')">{{
              userStore?.userInfo?.phoneNumber ? "更换手机号" : "绑定"
              userStore?.userInfo?.phoneNumber ? '更换手机号' : '绑定'
            }}</span>
          </div>
          <div class="info-box flex">
            <span class="label">邮箱:</span>
            <span class="text">{{
              userStore?.userInfo?.Email ? userStore.userInfo?.Email : "--"
              userStore?.userInfo?.Email ? userStore.userInfo?.Email : '--'
            }}</span>
            <span class="change-info hover" @click="changeUserInfo('email')">{{
              userStore?.userInfo?.Email ? "更换邮箱" : "绑定邮箱"
              userStore?.userInfo?.Email ? '更换邮箱' : '绑定邮箱'
            }}</span>
          </div>
        </div>
      </div>
      <div class="content-item">
      <!-- <div class="content-item">
        <div class="item-title flex jc-sb">
          <span>用户类型</span>
          <!-- <span class="change-info hover" @click="userTypeDialog = true">修改</span> -->
          <span class="change-info hover" @click="updateUserInfo()">修改</span>
        </div>
        <div class="item-box">
@@ -53,15 +50,12 @@
            <span class="text">{{ userInfo.userType }}</span>
          </div>
        </div>
      </div>
      </div> -->
      <div class="content-item">
        <div class="item-title flex jc-sb">
          <span>教师认证</span>
          <div>
            <span
              class="change-info hover"
              v-if="teacherState == ''"
              @click="showTeacherDialog()"
            <span class="change-info hover" v-if="teacherState == ''" @click="showTeacherDialog()"
              >认证</span
            >
            <span
@@ -109,11 +103,7 @@
      destroy-on-close
      v-model="userInfoDialog"
      :title="
        changeType == 'email'
          ? '更换邮箱'
          : changeType == 'password'
          ? '修改密码'
          : '更换手机号'
        changeType == 'email' ? '更换邮箱' : changeType == 'password' ? '修改密码' : '更换手机号'
      "
      width="500"
      class="myDialogs"
@@ -163,10 +153,10 @@
              >
                {{
                  countDown > 0
                    ? "验证码(" + countDown + "s)"
                    : changeType == "email"
                    ? "获取邮箱验证码"
                    : "获取短信验证码"
                    ? '验证码(' + countDown + 's)'
                    : changeType == 'email'
                      ? '获取邮箱验证码'
                      : '获取短信验证码'
                }}
              </el-button>
            </div>
@@ -179,11 +169,7 @@
              placeholder="请输入8-16位新密码,且不能为纯数字"
            />
          </el-form-item>
          <el-form-item
            label="确认密码:"
            prop="confirmPassword"
            v-if="changeType == 'password'"
          >
          <el-form-item label="确认密码:" prop="confirmPassword" v-if="changeType == 'password'">
            <el-input
              type="password"
              v-model="userInfoForm.confirmPassword"
@@ -196,11 +182,7 @@
      <template #footer>
        <span class="myDialogs-footer">
          <el-button @click="closeUserInfoDialog(userFormRef)">取消</el-button>
          <el-button
            type="primary"
            @click="confirmInfo(userFormRef)"
            :loading="subLoading"
          >
          <el-button type="primary" @click="confirmInfo(userFormRef)" :loading="subLoading">
            确定
          </el-button>
        </span>
@@ -261,9 +243,9 @@
          <li v-for="item in integralRecord.recordList" :key="item.key" class="body">
            <span class="label">{{ item.type }}</span>
            <span class="value" :class="item.value > 0 ? 'yes' : 'no'">{{
              item.value > 0 ? "+" + item.value : item.value
              item.value > 0 ? '+' + item.value : item.value
            }}</span>
            <span>{{ item.createDate ? item.createDate : "-" }}</span>
            <span>{{ item.createDate ? item.createDate : '-' }}</span>
          </li>
          <li class="total" v-if="integralRecord.recordList.length > 0">
            <span class="label">总计</span>
@@ -288,261 +270,261 @@
</template>
<script setup lang="ts">
import { reactive, ref, inject, onMounted, watch } from "vue";
import type { FormInstance, FormRules } from "element-plus";
import { reactive, ref, inject, onMounted, watch } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
// import verify from '@/components/sliderImg/component/verify.vue'
// import '@/components/sliderImg/sliderImg.js'
// import '@/components/sliderImg/sliderImg.css'
import { ElMessage } from "element-plus";
import tool from "@/assets/js/toolClass.js";
import { useUserStore } from "@/store";
import { ElMessage } from 'element-plus'
import tool from '@/assets/js/toolClass.js'
import { useUserStore } from '@/store'
// import wxlogin from 'vue-wxlogin'
import teacherCertification from "./teacherCertification.vue";
import teacherCertification from './teacherCertification.vue'
import login from '@/layout/components/login.vue'
const userStore = useUserStore();
import { useRoute } from "vue-router";
import moment from "moment";
const route = useRoute();
const MG: any = inject("MG");
const config: any = inject("config");
const userStore = useUserStore()
import { useRoute } from 'vue-router'
import moment from 'moment'
const route = useRoute()
const MG: any = inject('MG')
const config: any = inject('config')
const validatePhone = (rule: any, value: any, callback: any) => {
  if (value === "") {
    callback(new Error("请输入联系电话"));
  if (value === '') {
    callback(new Error('请输入联系电话'))
  } else {
    if (!config.reg_tel.test(value)) {
      callback(new Error("请输入正确格式的电话"));
      callback(new Error('请输入正确格式的电话'))
    }
    callback();
    callback()
  }
};
}
const validateEmail = (rule: any, value: any, callback: any) => {
  let myreg = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/;
  if (value === "") {
    callback(new Error("请输入电子邮箱"));
  let myreg = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/
  if (value === '') {
    callback(new Error('请输入电子邮箱'))
  } else {
    if (!myreg.test(value)) {
      callback(new Error("请输入正确格式的电子邮箱"));
      callback(new Error('请输入正确格式的电子邮箱'))
    }
    callback();
    callback()
  }
};
}
const validatePassword = (rule: any, value: any, callback: any) => {
  let myreg = /^(?!^\d+$)(?!^[a-zA-Z]+$)(?!^\W+$)[a-zA-Z\d\W]{8,16}$/;
  if (value === "") {
    callback(new Error("请输入密码"));
  let myreg = /^(?!^\d+$)(?!^[a-zA-Z]+$)(?!^\W+$)[a-zA-Z\d\W]{8,16}$/
  if (value === '') {
    callback(new Error('请输入密码'))
  } else {
    if (!myreg.test(value)) {
      callback(new Error("请输入正确格式的密码,8-16位,且不能为纯数字"));
      callback(new Error('请输入正确格式的密码,8-16位,且不能为纯数字'))
    }
    callback();
    callback()
  }
};
}
onMounted(() => {
  getWechatAuthenticationState();
  getIntegral();
  getWechatAuthenticationState()
  getIntegral()
  if (localStorage.getItem(config.tokenKey)) {
    getUserRole();
    getUserRole()
  }
});
})
// watch(route, () => {
//   bindWeChat()
// })
let subLoading = ref(false);
let subLoading = ref(false)
//用户信息
let weChatState = ref(false);
let weChatState = ref(false)
const userInfo = reactive({
  userType: "",
  userType: '',
  integral: 0,
});
})
//基础信息
const userInfoDialog = ref(false);
let changeType = ref("password");
const imgCode = ref<string>(); // 图形验证码url
let countDown = ref(0);
const userInfoDialog = ref(false)
let changeType = ref('password')
const imgCode = ref<string>() // 图形验证码url
let countDown = ref(0)
const changeUserInfo = (type) => {
  changeType.value = type;
  if (type == "password") {
  changeType.value = type
  if (type == 'password') {
    if (userStore.userInfo?.phoneNumber) {
      getImgCapcha();
      userInfoDialog.value = true;
      getImgCapcha()
      userInfoDialog.value = true
    } else {
      ElMessage({
        message: "修改密码需短信验证,请绑定手机号后再修改密码!",
        type: "warning",
      });
        message: '修改密码需短信验证,请绑定手机号后再修改密码!',
        type: 'warning',
      })
    }
  } else {
    getImgCapcha();
    userInfoDialog.value = true;
    getImgCapcha()
    userInfoDialog.value = true
  }
};
}
const getImgCapcha = () => {
  MG.identity.getImgCode().then((res) => {
    imgCode.value = "data:image/png;base64," + res;
  });
};
    imgCode.value = 'data:image/png;base64,' + res
  })
}
const userFormRef = ref<FormInstance>();
const userFormRef = ref<FormInstance>()
const userInfoForm = reactive({
  phone: "",
  email: "",
  captcha: "",
  code: "",
  password: "",
  confirmPassword: "",
});
const formDisabled = ref(false);
  phone: '',
  email: '',
  captcha: '',
  code: '',
  password: '',
  confirmPassword: '',
})
const formDisabled = ref(false)
const userFormRules = reactive<FormRules<userInfoForm>>({
  phone: [{ required: true, validator: validatePhone, trigger: "blur" }],
  email: [{ required: true, validator: validateEmail, trigger: "blur" }],
  phone: [{ required: true, validator: validatePhone, trigger: 'blur' }],
  email: [{ required: true, validator: validateEmail, trigger: 'blur' }],
  captcha: [
    { required: true, message: "图形验证码不能为空", trigger: "blur" },
    { min: 4, max: 4, message: "请输入 4 位验证码", trigger: "blur" },
    { required: true, message: '图形验证码不能为空', trigger: 'blur' },
    { min: 4, max: 4, message: '请输入 4 位验证码', trigger: 'blur' },
  ],
  code: [{ required: true, message: "验证码不能为空", trigger: "blur" }],
  password: [{ required: true, validator: validatePassword, trigger: "blur" }],
  confirmPassword: [{ required: true, message: "确认密码不能为空", trigger: "blur" }],
});
  code: [{ required: true, message: '验证码不能为空', trigger: 'blur' }],
  password: [{ required: true, validator: validatePassword, trigger: 'blur' }],
  confirmPassword: [{ required: true, message: '确认密码不能为空', trigger: 'blur' }],
})
const getVerifyCode = async () => {
  sliderImgDialogVisable.value = true;
};
  sliderImgDialogVisable.value = true
}
// 验证码倒计时
function getSecond(time: number) {
  let timer: ReturnType<typeof setInterval> | null = null;
  let timer: ReturnType<typeof setInterval> | null = null
  if (!timer) {
    countDown.value = time;
    countDown.value = time
    timer = setInterval(() => {
      countDown.value--;
      countDown.value--
      if (countDown.value == 0) {
        if (timer) clearInterval(timer);
        timer = null;
        if (timer) clearInterval(timer)
        timer = null
      }
    }, 1000);
    }, 1000)
  }
}
const closeUserInfoDialog = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  formEl.resetFields();
  countDown.value = 0;
  userInfoDialog.value = false;
};
  if (!formEl) return
  formEl.resetFields()
  countDown.value = 0
  userInfoDialog.value = false
}
const confirmInfo = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  if (!formEl) return
  await formEl.validate((valid, fields) => {
    if (valid) {
      subLoading.value = true;
      if (changeType.value == "password") {
      subLoading.value = true
      if (changeType.value == 'password') {
        if (userInfoForm.password != userInfoForm.confirmPassword) {
          ElMessage({
            message: "两次密码输入不一致",
            type: "warning",
          });
          return false;
            message: '两次密码输入不一致',
            type: 'warning',
          })
          return false
        }
        let query = {
          phoneNumber: userInfoForm.phone,
          phoneCaptcha: userInfoForm.code,
          password: userInfoForm.password,
        };
        }
        MG.identity.changePasswordByMobilePhone(query).then((res) => {
          if (res) {
            ElMessage({
              message: "密码重置成功!",
              type: "success",
            });
            userInfoDialog.value = false;
              message: '密码重置成功!',
              type: 'success',
            })
            userInfoDialog.value = false
          } else {
            ElMessage({
              message: "密码重置失败,请填写正确的验证码。",
              type: "error",
            });
              message: '密码重置失败,请填写正确的验证码。',
              type: 'error',
            })
          }
          subLoading.value = false;
        });
      } else if (changeType.value == "phone") {
          subLoading.value = false
        })
      } else if (changeType.value == 'phone') {
        let query = {
          phoneNumber: userInfoForm.phone,
          phoneCaptcha: userInfoForm.code,
        };
        }
        MG.identity.userSetPhoneNumber(query).then((res) => {
          if (res == "验证码过期或错误") {
          if (res == '验证码过期或错误') {
            ElMessage({
              message: res + ",请稍后重试",
              type: "error",
            });
          } else if (res == "此手机号码已被其它账号绑定") {
              message: res + ',请稍后重试',
              type: 'error',
            })
          } else if (res == '此手机号码已被其它账号绑定') {
            ElMessage({
              message: res + ",请更换其他手机号。",
              type: "error",
            });
              message: res + ',请更换其他手机号。',
              type: 'error',
            })
          } else {
            ElMessage({
              message: res,
              type: "success",
            });
              type: 'success',
            })
            userStore.setUserInfo({
              ...userStore.userInfo,
              phoneNumber: userInfoForm.phone,
            });
            userInfoDialog.value = false;
            })
            userInfoDialog.value = false
          }
          subLoading.value = false;
        });
      } else if (changeType.value == "email") {
          subLoading.value = false
        })
      } else if (changeType.value == 'email') {
        let query = {
          eMail: userInfoForm.email,
          captcha: userInfoForm.code,
        };
        }
        MG.identity.bindingEmail(query).then((res) => {
          if (res == "验证码过期") {
          if (res == '验证码过期') {
            ElMessage({
              message: res + ",请稍后重试",
              type: "error",
            });
          } else if (res == "此邮箱已被其它账号绑定") {
              message: res + ',请稍后重试',
              type: 'error',
            })
          } else if (res == '此邮箱已被其它账号绑定') {
            ElMessage({
              message: res + ",请更换其他邮箱。",
              type: "error",
            });
          } else if (res == "验证码无效") {
              message: res + ',请更换其他邮箱。',
              type: 'error',
            })
          } else if (res == '验证码无效') {
            ElMessage({
              message: res,
              type: "error",
            });
              type: 'error',
            })
          } else {
            ElMessage({
              message: res,
              type: "success",
            });
              type: 'success',
            })
            userStore.setUserInfo({
              ...userStore.userInfo,
              Email: userInfoForm.email,
            });
            userInfoDialog.value = false;
            })
            userInfoDialog.value = false
          }
          subLoading.value = false;
        });
          subLoading.value = false
        })
      }
    } else {
      subLoading.value = false;
      subLoading.value = false
    }
  });
};
  })
}
// 滑动验证
const sliderImgDialogVisable = ref<boolean>(false);
const sliderImgDialogVisable = ref<boolean>(false)
const loginImgVerify = (code: string) => {
  userInfoForm.captcha = code;
  sliderImgDialogVisable.value = false;
  if (changeType.value == "phone" || changeType.value == "password") {
  userInfoForm.captcha = code
  sliderImgDialogVisable.value = false
  if (changeType.value == 'phone' || changeType.value == 'password') {
    MG.identity
      .getPhoneCode({
        phoneNumber: userInfoForm.phone,
@@ -550,21 +532,21 @@
        appRefCode: config.appRefCode,
      })
      .then((res: any) => {
        if (res == "验证码发送成功") {
        if (res == '验证码发送成功') {
          ElMessage({
            message: res,
            type: "success",
          });
            type: 'success',
          })
          // 开启短信验证倒计时
          getSecond(60);
          getSecond(60)
        } else {
          ElMessage({
            message: res,
            type: "error",
          });
            type: 'error',
          })
        }
      });
  } else if (changeType.value == "email") {
      })
  } else if (changeType.value == 'email') {
    MG.identity
      .getEmailCode({
        sendEmail: userInfoForm.email,
@@ -574,50 +556,50 @@
      .then((res) => {
        if (res == true) {
          ElMessage({
            message: "邮件已发送",
            type: "success",
          });
            message: '邮件已发送',
            type: 'success',
          })
        } else {
          ElMessage({
            message: "邮件发送失败",
            type: "error",
          });
            message: '邮件发送失败',
            type: 'error',
          })
        }
      });
      })
  }
};
}
//微信认证
let wxLogin = reactive({
  appid: "wx5cfe8b007a3c6f8c",
  scope: "snsapi_login",
  redirectURL: encodeURIComponent(config.requestCtx + "/home/#/personalCenter"),
});
  appid: 'wx5cfe8b007a3c6f8c',
  scope: 'snsapi_login',
  redirectURL: encodeURIComponent(config.requestCtx + '/home/#/personalCenter'),
})
const getWechatAuthenticationState = () => {
  MG.identity.checkBuildingWeChat({}).then((res: any) => {
    if (res) {
      weChatState.value = true;
      weChatState.value = true
    } else {
      weChatState.value = false;
      weChatState.value = false
    }
  });
};
const weChartDialog = ref(false);
  })
}
const weChartDialog = ref(false)
function goBindWeChat() {
  window.location.href = `https://open.weixin.qq.com/connect/qrconnect?appid=${wxLogin.appid}&scope=${wxLogin.scope}&redirect_uri=${wxLogin.redirectURL}&state=WeChatScanningCodeBind`;
  window.location.href = `https://open.weixin.qq.com/connect/qrconnect?appid=${wxLogin.appid}&scope=${wxLogin.scope}&redirect_uri=${wxLogin.redirectURL}&state=WeChatScanningCodeBind`
}
//绑定微信
const bindWeChat = () => {
  var url = window.location.href;
  if (url.indexOf("WeChatScanningCodeBind") > -1) {
    var querys = url.substring(url.indexOf("?") + 1).split("&");
    var result = {};
  var url = window.location.href
  if (url.indexOf('WeChatScanningCodeBind') > -1) {
    var querys = url.substring(url.indexOf('?') + 1).split('&')
    var result = {}
    for (var i = 0; i < querys.length; i++) {
      var temp = querys[i].split("=");
      var temp = querys[i].split('=')
      if (temp.length < 2) {
        result[temp[0]] = "";
        result[temp[0]] = ''
      } else {
        result[temp[0]] = temp[1];
        result[temp[0]] = temp[1]
      }
    }
    if (result && result.code) {
@@ -628,162 +610,153 @@
        .then((res) => {
          if (res) {
            ElMessage({
              message: "绑定成功!",
              type: "success",
            });
            getWechatAuthenticationState();
            weChartDialog.value = false;
              message: '绑定成功!',
              type: 'success',
            })
            getWechatAuthenticationState()
            weChartDialog.value = false
          } else {
            ElMessage({
              message: "绑定失败,该微信已被绑定!",
              type: "error",
            });
              message: '绑定失败,该微信已被绑定!',
              type: 'error',
            })
          }
        });
        })
    }
  }
};
}
//用户类型
const loginRef = ref();
const loginRef = ref()
// const userTypeDialog = ref(false)
const userTypeActive = ref("");
const teacherType = ref("");
const userTypeActive = ref('')
const teacherType = ref('')
const teacherList = ref([
  {
    value: "vocSchoolTeachers",
    label: "中职教师",
    value: 'vocSchoolTeachers',
    label: '中职教师',
  },
  {
    value: "vocCollegeTeachers",
    label: "高职教师",
    value: 'vocCollegeTeachers',
    label: '高职教师',
  },
  {
    value: "ordUniversityTeachers",
    label: "本科教师",
    value: 'ordUniversityTeachers',
    label: '本科教师',
  },
  {
    value: "primarySchoolTeachers",
    label: "中小学教师",
    value: 'primarySchoolTeachers',
    label: '中小学教师',
  },
  {
    value: "kindergarteTeachers",
    label: "幼儿园教师",
    value: 'kindergarteTeachers',
    label: '幼儿园教师',
  },
]);
])
const userTypeList = ref([
  {
    value: "Teacher",
    label: "教师",
    value: 'Teacher',
    label: '教师',
    checked: false,
  },
  {
    value: "Student",
    label: "学生",
    value: 'Student',
    label: '学生',
    checked: false,
  },
  {
    value: "otherReaders",
    label: "其他读者",
    value: 'otherReaders',
    label: '其他读者',
    checked: false,
  },
]);
])
// 修改用户类型调用注册时用户信息填写弹窗
const updateUserInfo = () => {
  loginRef.value.updateUserInfo();
  loginRef.value.signUp();
};
  loginRef.value.updateUserInfo()
  loginRef.value.signUp()
}
//教师认证
let teacherDialog = ref(false); //弹窗
let loading = ref(false);
const teacherState = ref(null);
const reasonTxt = ref("");
const userId = ref();
let teacherDialog = ref(false) //弹窗
let loading = ref(false)
const teacherState = ref(null)
const reasonTxt = ref('')
const userId = ref()
const dialogReason = ref(false);
const dialogReason = ref(false)
//教师认证弹窗
function showTeacherDialog() {
  teacherDialog.value = true;
  teacherDialog.value = true
}
const dialogChange = (val: any) => {
  getTeacherInfo();
  getTeacherInfo()
  if (val == false) {
    teacherDialog.value = false;
    teacherDialog.value = false
  } else {
    teacherDialog.value = true;
    teacherDialog.value = true
  }
};
}
// 修改密码弹窗打开
const openChangePassword = () => {
  if (changeType.value == "password" && userStore.userInfo?.phoneNumber) {
    userInfoForm.phone = userStore.userInfo?.phoneNumber;
  if (changeType.value == 'password' && userStore.userInfo?.phoneNumber) {
    userInfoForm.phone = userStore.userInfo?.phoneNumber
  }
};
}
// 获取登录用户身份
function getUserRole() {
  loading.value = true;
  loading.value = true
  MG.identity.getCurrentAppUser().then((res: any) => {
    if (res) {
      if (res.lastLoginTime) {
        localStorage.setItem("lastLoginTime", res.lastLoginTime);
        localStorage.setItem('lastLoginTime', res.lastLoginTime)
      }
      //获取用户类型
      let userTypeData = res.infoList.find((item: any) => item.type == "userType");
      let userTypeData = res.infoList.find((item: any) => item.type == 'userType')
      if (userTypeData) {
        userTypeActive.value = JSON.parse(userTypeData.data).userType;
        if (
          userTypeActive.value !== "Student" &&
          userTypeActive.value !== "otherReaders"
        ) {
          const index = userTypeList.value.findIndex((item) => item.value === "Teacher");
        userTypeActive.value = JSON.parse(userTypeData.data).userType
        if (userTypeActive.value !== 'Student' && userTypeActive.value !== 'otherReaders') {
          const index = userTypeList.value.findIndex((item) => item.value === 'Teacher')
          if (index !== -1) {
            userTypeList.value[index].checked = true;
            teacherType.value = JSON.parse(userTypeData.data).userType;
            userTypeList.value[index].checked = true
            teacherType.value = JSON.parse(userTypeData.data).userType
          }
          userInfo.userType =
            teacherList.value.find((item) => item.value === userTypeActive.value)
              ?.label ?? "";
            teacherList.value.find((item) => item.value === userTypeActive.value)?.label ?? ''
        } else {
          const index = userTypeList.value.findIndex(
            (item) => item.value === userTypeActive.value
          );
          const index = userTypeList.value.findIndex((item) => item.value === userTypeActive.value)
          if (index !== -1) {
            userTypeList.value[index].checked = true;
            userTypeList.value[index].checked = true
          }
          userInfo.userType =
            userTypeList.value.find((item) => item.value === userTypeActive.value)
              ?.label ?? "";
            userTypeList.value.find((item) => item.value === userTypeActive.value)?.label ?? ''
        }
      } else {
        userInfo.userType = "-";
        userInfo.userType = '-'
      }
      getTeacherInfo();
      userId.value = res.userId;
      let customUser = res.infoList.find((item: any) => item.type == "userInfo");
      let teacherRole = res.roleLinks.find((item: any) => item.role.refCode == "teacher");
      let teacherInfos = res.infoList.find((item: any) => item.type == "teacherInfo");
      let wechatInfo = res.infoList.find((item: any) => item.type == "WeChat");
      let studentInfo = res.infoList.find((item: any) => item.type == "Default");
      let phoneInfo = res.secretList.find((item: any) => item.type == "MobilePhone");
      let emailInfo = res.secretList.find((item: any) => item.type == "EMail");
      getTeacherInfo()
      userId.value = res.userId
      let customUser = res.infoList.find((item: any) => item.type == 'userInfo')
      let teacherRole = res.roleLinks.find((item: any) => item.role.refCode == 'teacher')
      let teacherInfos = res.infoList.find((item: any) => item.type == 'teacherInfo')
      let wechatInfo = res.infoList.find((item: any) => item.type == 'WeChat')
      let studentInfo = res.infoList.find((item: any) => item.type == 'Default')
      let phoneInfo = res.secretList.find((item: any) => item.type == 'MobilePhone')
      let emailInfo = res.secretList.find((item: any) => item.type == 'EMail')
      const userData = {
        userName: customUser && customUser.data ? JSON.parse(customUser.data).name : "",
        school: customUser && customUser.data ? JSON.parse(customUser.data).school : "",
        cityCode:
          customUser && customUser.data ? JSON.parse(customUser.data).cityCode : "",
        address: customUser && customUser.data ? JSON.parse(customUser.data).address : "",
        userType:
          userTypeData && userTypeData.data ? JSON.parse(userTypeData.data).userType : "",
      };
        userName: customUser && customUser.data ? JSON.parse(customUser.data).name : '',
        school: customUser && customUser.data ? JSON.parse(customUser.data).school : '',
        cityCode: customUser && customUser.data ? JSON.parse(customUser.data).cityCode : '',
        address: customUser && customUser.data ? JSON.parse(customUser.data).address : '',
        userType: userTypeData && userTypeData.data ? JSON.parse(userTypeData.data).userType : '',
      }
      if (teacherRole && teacherInfos) {
        if (JSON.parse(teacherInfos.data).email && !emailInfo) {
          userInfoForm.email = JSON.parse(teacherInfos.data).email;
          formDisabled.value = true;
          userInfoForm.email = JSON.parse(teacherInfos.data).email
          formDisabled.value = true
        }
        userStore.setUserInfo({
          ...userData,
@@ -791,19 +764,19 @@
          phoneNumber: phoneInfo?.credential,
          Email: emailInfo ? emailInfo.credential : JSON.parse(teacherInfos.data).email,
          icon: wechatInfo?.icon,
          role: "Teacher",
          role: 'Teacher',
          roleId: teacherRole.role.id,
          userId: res.userId,
        });
        })
      } else if (wechatInfo) {
        userStore.setUserInfo({
          ...userData,
          ...wechatInfo,
          phoneNumber: phoneInfo?.credential,
          Email: emailInfo?.credential,
          role: "Student",
          role: 'Student',
          userId: res.userId,
        });
        })
      } else if (studentInfo) {
        userStore.setUserInfo({
          ...userData,
@@ -811,12 +784,12 @@
          icon: wechatInfo?.icon,
          phoneNumber: phoneInfo?.credential,
          Email: emailInfo?.credential,
          role: "Student",
          role: 'Student',
          userId: res.userId,
        });
        })
      }
    }
  });
  })
}
//教师信息
@@ -824,56 +797,56 @@
  const data = {
    start: 0,
    size: 10,
    topicIdOrRefCode: "teacherRoleApproval",
    topicIdOrRefCode: 'teacherRoleApproval',
    appRefCode: config.appRefCode,
    sort: {
      type: "Desc",
      field: "CreateDate",
      type: 'Desc',
      field: 'CreateDate',
    },
  };
  }
  MG.ugc.getTopicMessageList(data).then((res) => {
    try {
      const resData = res.datas.find((i) => i.appUserCreator.userId == userId.value);
      const resData = res.datas.find((i) => i.appUserCreator.userId == userId.value)
      if (resData) {
        teacherState.value = resData.state;
        teacherState.value = resData.state
        if (resData.feedBack != null) {
          reasonTxt.value = JSON.parse(resData.feedBack).reason;
          reasonTxt.value = JSON.parse(resData.feedBack).reason
        }
      } else {
        teacherState.value = "";
        teacherState.value = ''
      }
      loading.value = false;
      loading.value = false
    } catch (error) {
      loading.value = false;
      loading.value = false
    }
  });
  })
}
//原因查看
const lookReason = () => {
  dialogReason.value = true;
};
  dialogReason.value = true
}
//积分
function getIntegral() {
  MG.store
    .getUserWallet({
      type: "integral",
      type: 'integral',
    })
    .then((res) => {
      userInfo.integral = res.balance;
    });
      userInfo.integral = res.balance
    })
}
const integralRecord = reactive({
  recordDialog: false,
  recordList: [],
});
})
// 积分记录弹窗
function recordDialog() {
  integralRecord.recordDialog = true;
  getRecordList();
  integralRecord.recordDialog = true
  getRecordList()
}
//获取积分记录
@@ -883,38 +856,38 @@
      Size: 999,
      Start: 0,
      sort: {
        type: "Desc",
        field: "CreateDate",
        type: 'Desc',
        field: 'CreateDate',
      },
      type: "integral",
      type: 'integral',
    })
    .then((res) => {
      console.log(res, "积分记录");
      console.log(res, '积分记录')
      if (res.datas.length > 0) {
        res.datas.forEach((element) => {
          element.createDate = moment(element.createDate).format("YYYY-MM-DD HH:mm:ss");
          if (element.refType == "sign") {
            element.type = "每日登录";
          element.createDate = moment(element.createDate).format('YYYY-MM-DD HH:mm:ss')
          if (element.refType == 'sign') {
            element.type = '每日登录'
          }
          if (element.refType == "Reward") {
            element.type = "上传资源奖励";
          if (element.refType == 'Reward') {
            element.type = '上传资源奖励'
          }
          if (element.refType == "OrderCoinBonus") {
            element.type = "订单支付奖励";
          if (element.refType == 'OrderCoinBonus') {
            element.type = '订单支付奖励'
          }
          if (element.refType == "Order" && element.value < 0) {
            element.type = "订单支付抵扣";
          if (element.refType == 'Order' && element.value < 0) {
            element.type = '订单支付抵扣'
          }
          if (element.refType == "Order" && element.value > 0) {
            element.type = "订单取消退回";
          if (element.refType == 'Order' && element.value > 0) {
            element.type = '订单取消退回'
          }
          if (element.refType == "AdminRecharge") {
            element.type = "管理员充值";
          if (element.refType == 'AdminRecharge') {
            element.type = '管理员充值'
          }
        });
        integralRecord.recordList = res.datas;
        })
        integralRecord.recordList = res.datas
      }
    });
    })
}
</script>
<style lang="less" scoped>
@@ -923,7 +896,9 @@
    line-height: 20px;
    padding: 0 10px;
    border-left: 3px solid #019e58;
    font-family: Microsoft YaHei UI, Microsoft YaHei UI;
    font-family:
      Microsoft YaHei UI,
      Microsoft YaHei UI;
    font-weight: 400;
    font-size: 16px;
  }
@@ -933,7 +908,9 @@
    .info-box {
      padding: 10px 0;
      font-family: Microsoft YaHei UI, Microsoft YaHei UI;
      font-family:
        Microsoft YaHei UI,
        Microsoft YaHei UI;
      font-weight: 400;
      font-size: 14px;
      color: #333333;