Browse Source

深技师页面

11wqe1 1 day ago
parent
commit
1aff5ec1a3

+ 9 - 1
src/App.vue

@@ -1,7 +1,7 @@
 <script setup>
 <script setup>
 import { onMounted, ref, inject } from 'vue'
 import { onMounted, ref, inject } from 'vue'
 import { courseUrl, registerSetCourseUrl } from '@/composables/useCourseIframe'
 import { courseUrl, registerSetCourseUrl } from '@/composables/useCourseIframe'
-import { RouterLink, RouterView, useRoute } from 'vue-router'
+import { RouterLink, RouterView, useRoute, useRouter } from 'vue-router'
 import Header from './views/header.vue';
 import Header from './views/header.vue';
 import axios from 'axios';
 import axios from 'axios';
 import qs from 'qs';
 import qs from 'qs';
@@ -9,6 +9,7 @@ import { ElMessageBox } from 'element-plus'
 import { userInfoStore, userCurrentRole,userCurrent,pageGotype } from './stores/counter'
 import { userInfoStore, userCurrentRole,userCurrent,pageGotype } from './stores/counter'
 
 
 const route = useRoute()
 const route = useRoute()
+const router = useRouter()
 const store = userInfoStore()
 const store = userInfoStore()
 const CurrentRole = userCurrentRole()
 const CurrentRole = userCurrentRole()
 const Current = userCurrent()
 const Current = userCurrent()
@@ -28,8 +29,15 @@ onMounted(() => {
   let userid = getUrlParam(window.parent.location.href, 'userid') 
   let userid = getUrlParam(window.parent.location.href, 'userid') 
   // let userid = '0c3735c9-a2ef-11ef-9b30-005056b86db5'
   // let userid = '0c3735c9-a2ef-11ef-9b30-005056b86db5'
   let gotype = getUrlParam(window.parent.location.href, 'gotype')
   let gotype = getUrlParam(window.parent.location.href, 'gotype')
+  let cszy = getUrlParam(window.parent.location.href, 'cszy')
   console.log('gotype',gotype);
   console.log('gotype',gotype);
+  console.log('cszy',cszy);
+  
   setgotype.setpageType(gotype);
   setgotype.setpageType(gotype);
+
+  if (cszy) {
+    router.replace({ path: '/course' })
+  }
   
   
   axios.defaults.headers = { 'content-type': 'application/json;charset=utf-8' }
   axios.defaults.headers = { 'content-type': 'application/json;charset=utf-8' }
 
 

BIN
src/assets/img/begl.png


BIN
src/assets/img/coursedl.png


BIN
src/assets/img/cszylogo.png


BIN
src/assets/img/topl.png


+ 468 - 0
src/components/main/coursepage.vue

@@ -0,0 +1,468 @@
+<template>
+   
+  <div class="course_page">
+    <img src="../../assets/img/topl.png" alt="" class="top_img">
+    
+    <div class="grandTitle2"> 
+        信息与通信学院-人工智能系列课程
+    </div>
+    <div class="course_select_title">
+      <div class="course_select_button_container">
+        <span class="grandTitle">课程名称:</span>
+        <div class="course_select_button course_select_button_active">
+            <span class="course_select_button_text">人工智能应用基础</span>
+        </div>
+      </div>
+      <div class="course_select_button_container">
+        <span class="grandTitle">课程模块:</span>
+        <div class="course_select_button"
+            v-for="item in yearList"
+            :key="item.value"
+            :class="activeyear == item.value ? 'course_select_button_active' : ''"
+            @click="clickYear(item.value)"
+          >
+            <span class="course_select_button_text">{{ item.label }}</span>
+          </div>
+      </div>
+      
+    </div>
+
+    <div
+      class="course_select"
+      v-for="project in projectList"
+      :key="project.grade"
+    >
+      <span class="project_title">
+        <div class="cell_line"></div>
+        {{ project.title }}
+      </span>
+      <div v-loading="courseLoading">
+        <div v-if="getCoursesByGrade(project.grade).length > 0" class="listcor">
+          <div class="course_item" v-for="item in getCoursesByGrade(project.grade)" :key="item.id">
+            <div class="grid-content ep-bg-purple">
+              <img class="course_item_img" :src="getImageUrl(item.json.url)" alt="">
+              <div class="course_content">
+                <div class="div_title">
+                  <el-tooltip class="item" effect="dark" :content="item.json.title" placement="top">
+                    <div class="div_title_text">{{ item.json.title }}</div>
+                  </el-tooltip>
+                </div>
+                <div class="begin_course_container">
+                  <!-- <div class="begin_coursel"  @click="downloadcoupage(item.json.dataList)">
+                    <img class="begin_course_img" src="../../assets/img/coursedl.png" alt="">
+                    下载课件
+                  </div> -->
+                  <div class="begin_course"  @click="openCourseDetail(item.json.id)">
+                    <img class="begin_course_img" src="../../assets/img/begl.png" alt="">
+                    开始上课
+                  </div>
+                </div>
+               
+              </div>
+            </div>
+          </div>
+        </div>
+        <div v-else>
+          <el-empty :description="lang.ssNoCrsGrdTip" />
+        </div>
+      </div>
+    </div>
+
+    <selectTeachingClassDialog ref="DialogRef" @openCourse="openCourseIframe" />
+  </div>
+  
+</template>
+
+<script setup>
+import { addOp3 } from '@/mixins/mixin'
+import { ref, onMounted, watchEffect, inject } from 'vue'
+import { useRoute } from 'vue-router'
+import { userCurrentRole, userInfoStore, pageGotype } from '../../stores/counter'
+import DownloadImg from '@/assets/img/download.png'
+import selectTeachingClassDialog from '../dialog/selectTeachingClassDialog.vue'
+import axios from 'axios'
+import { openCourseIframe } from '@/composables/useCourseIframe'
+import { ElMessage } from 'element-plus'
+
+const lang = inject('lang')
+const route = useRoute()
+
+
+const user = userInfoStore()
+const CurrentRole = userCurrentRole()
+
+const isupdateCourse = ref(false)
+const DialogRef = ref(null)
+const courseLoading = ref(false)
+const activeyear = ref(route.query.yea || 'cszy1')
+const activeCurrentData = ref([])
+const projectList = ref([
+  { title: '项目一:AI初始与数据认知', grade: 0 },
+  { title: '项目二:人机协同多模态表达', grade: 1 },
+  { title: '项目三:AI输出核验与独立思辨', grade: 2 },
+  { title: '项目四:数据安全与算法责任', grade: 3 },
+  { title: '项目五:专业场景综合创新', grade: 4 },
+  { title: '项目六:岗位智能体与职业发展', grade: 5 }
+])
+
+const getCoursesByGrade = (grade) => {
+  return activeCurrentData.value.filter(item => item.grade == grade)
+}
+
+const yearList = ref([
+  { value: 'cszy1', label: '通用基础模块' },
+  // { value: 'cszy2', label: '专业进阶模块' }
+])
+
+const clickYear = (val) => {
+  activeyear.value = val
+  getCourseList()
+}
+
+onMounted(() => {
+//   getTimeCourse(1, { title: 'AI课程' })
+  getCourseList()
+})
+
+const getCourseList = () => {
+  courseLoading.value = true
+  const params = {
+    ter: 0,
+    gra: '',
+    ar: lang.lang,
+    typ: 0,
+    yea: activeyear.value
+  }
+  axios.get('https://pbl.cocorobo.cn/api/pbl/selectaisixCourse', { params })
+    .then(res => {
+      const data = res.data[0]
+      console.log(data)
+      data.forEach(item => {
+        item.json = JSON.parse(item.json)
+      })
+      activeCurrentData.value = data
+      courseLoading.value = false
+    })
+    .catch(err => {
+      console.error(err)
+      courseLoading.value = false
+    })
+}
+
+const getImageUrl = (url) => new URL(url, import.meta.url).href
+
+const getPblBaseUrl = () => {
+  if (lang.lang == 'hk') return 'https://pbl.cocorobo.hk'
+  if (lang.lang == 'en') return 'https://pbl.cocorobo.com'
+  return 'https://pbl.cocorobo.cn'
+}
+
+const buildCourseDetailUrl = (courseId) => {
+  const baseUrl = getPblBaseUrl()
+  return `${baseUrl}/pbl-student-table/dist/#/courseDetail?userid=${user.user.userid}&oid=${user.user.organizeid}&org=${user.user.org}&courseId=${courseId}&tType=1&cid=&screenType=2`
+}
+
+const getCourseModeType = (state) => {
+  const modeMap = {
+    1: 'course_stageMode_open',
+    2: 'course_taskMode_open',
+    3: 'course_easyMode_open',
+    5: 'course_aiMode_open',
+    6: 'course_aiEasyMode_open',
+    7: 'course_pptMode_open'
+  }
+  return modeMap[state] || ''
+}
+
+const checkClass = async () => {
+  if (user.user.org == '16ace517-b5c7-4168-a9bb-a9e0035df840') {
+    try {
+      const res = await axios.get('https://pbl.cocorobo.cn/api/pbl/checkClass', {
+        params: { userid: user.user.userid }
+      })
+      return res.data[0][0].result
+    } catch (err) {
+      console.error(err)
+    }
+  }
+  return 2
+}
+
+const getCourseid = (id) => {
+  axios.post('https://pbl.cocorobo.cn/api/pbl/getcopyCourseByUseridSz', { id: id + ',' + user.user.userid }, {
+    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+    withCredentials: true
+  })
+    .then(async res => {
+      if (res.data[0].length > 0) {
+        DialogRef.value.getClasslist(res.data[0][0])
+      } else {
+        const classResult = await checkClass()
+        if (classResult == 1) {
+          ElMessage({ message: lang.ssCreateCourseLimit, type: 'warning' })
+          return
+        }
+        getCourseid2(id)
+      }
+    })
+    .catch(err => console.log(err))
+}
+
+const getCourseid2 = (id) => {
+  axios.post('https://pbl.cocorobo.cn/api/pbl/copyCourseSz', { id: id + ',' + user.user.userid }, {
+    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+    withCredentials: true
+  })
+    .then(res => DialogRef.value.getClasslist(res.data[0][0]))
+    .catch(err => console.log(err))
+}
+const downloadCheckedFiles = async (urls) => {
+  for (let i = 0; i < urls.length; i++) {
+    fetch(urls[i].url)
+      .then(response => response.blob())
+      .then(blob => {
+        const url = window.URL.createObjectURL(blob)
+        const a = document.createElement('a')
+        a.href = url
+        a.download = urls[i].name
+        a.style.display = 'none'
+        document.body.appendChild(a)
+        a.click()
+        document.body.removeChild(a)
+        window.URL.revokeObjectURL(url)
+      })
+      .catch(console.error)
+  }
+}
+
+const downloadcoupage = async (dataList) => {
+  if (!Array.isArray(dataList) || !dataList.length) {
+    ElMessage({ message: lang.ssNoData || '暂无可下载文件', type: 'warning' })
+    return
+  }
+  await downloadCheckedFiles(dataList)
+}
+
+const openCourseDetail = (id) => {
+  axios.post('https://pbl.cocorobo.cn/api/pbl/getcopyCourseByUseridSz', { id: id + ',' + user.user.userid }, {
+    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+    withCredentials: true
+  })
+    .then(async res => {
+      if (res.data[0].length > 0) {
+        getCourseUrl(res.data[0][0])
+      } else {
+        const classResult = await checkClass()
+        if (classResult == 1) {
+          ElMessage({ message: lang.ssCreateCourseLimit, type: 'warning' })
+          return
+        }
+        updateCourseId(id)
+      }
+    })
+    .catch(err => console.log(err))
+}
+
+const getCourseUrl = (item) => {
+  addOp3('1', '', { courseid: item.courseId, type: getCourseModeType(item.state) }, 'success')
+  openCourseIframe(buildCourseDetailUrl(item.courseId))
+}
+
+const updateCourseId = (id) => {
+  axios.post('https://pbl.cocorobo.cn/api/pbl/copyCourseSz', { id: id + ',' + user.user.userid }, {
+    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+    withCredentials: true
+  })
+    .then(res => {
+      const course = res.data[0][0]
+      if (course.courseId != '') {
+        addOp3('1', '', { courseid: course.courseId, type: getCourseModeType(course.state) }, 'success')
+        openCourseIframe(buildCourseDetailUrl(course.courseId))
+      }
+    })
+    .catch(err => console.log(err))
+}
+
+
+
+
+
+watchEffect(() => {
+  if (JSON.stringify(user.user) != '{}') {
+    if (
+      CurrentRole.currentRole == 'edupersonnel' ||
+      CurrentRole.currentRole == 'areaAdministrator' ||
+      CurrentRole.currentRole == 'userAdministrator' ||
+      CurrentRole.currentRole == 'securityAuditor' ||
+      CurrentRole.currentRole == 'schoolAdministrator' ||
+      CurrentRole.currentRole == 'schoolSecurityAuditor' ||
+      CurrentRole.currentRole == 'teacher' ||
+      user.type != 2
+    ) {
+      isupdateCourse.value = true
+    }
+  }
+})
+</script>
+
+<style lang="scss" scoped>
+.course_page {
+  max-width: 1400px;
+  margin: 0 auto;
+  margin-bottom: 100px;
+  .top_img {
+    width: 100%;
+    height: auto;
+    display: block;
+  }
+}
+
+.course_select {
+  margin-top: 45px;
+  .grid-content {
+    border-radius: 4px;
+    min-height: 36px;
+    background: #fff;
+    cursor: pointer;
+    border-radius: 8px;
+    overflow: hidden;
+    .course_item_img {
+      width: 100%;
+      aspect-ratio: 16 / 9;
+      object-fit: cover;
+      display: block;
+    }
+    .course_content {
+      padding: 15px;
+      box-sizing: border-box;
+      .div_title {
+        margin-bottom: 10px;
+        .div_title_text {
+          color: #000002;
+          overflow: hidden;
+          font-size: 14px;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+        }
+      }
+    }
+  }
+
+ 
+}
+.begin_course_container {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  justify-content: space-between;
+}
+.begin_coursel {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  gap: 5px;
+  justify-content: center;
+  font-size: 14px;
+  color: #5080F6;
+  background: #F0F4FF;
+  padding: 5px 0px; 
+  border-radius: 5px;
+}
+.begin_course {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  gap: 5px;
+  justify-content: center;
+  font-size: 14px;
+  color: rgba(255, 255, 255, 1);
+  background: #548CFF;
+  padding: 5px 0px; 
+  border-radius: 5px;
+}
+
+.begin_course_img {
+  width: 12px !important;
+  height: 12px;
+}
+.Levelone {
+  background: #E0EAFB;
+  border-radius: 5px;
+  color: rgba(26, 37, 64, 1);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 33px;
+  font-size: 16px;
+  font-weight: 500;
+}
+
+.grandTitle2 {
+  font-size: 16px;
+  line-height: 28px;
+  margin-top: 20px;
+  margin-bottom: 20px;
+  color: #1F2329;
+}
+
+.cell_line {
+  width: 4px;
+  height: 20px;
+  border-radius: 2px;
+  background: rgba(74, 124, 246, 1);
+}
+
+.project_title {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  font-weight: 500;
+  font-size: 16px;
+  color: rgba(26, 37, 64, 1);
+}
+
+.listcor {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 20px;
+  margin-top: 10px;
+}
+
+.course_item {
+  box-sizing: border-box;
+  flex: 0 0 calc((100% - 80px) / 4);
+  min-width: min(100%, 280px);
+}
+.course_select_title {
+  background: rgba(255, 255, 255, 1);
+  padding: 15px 20px;
+  display: flex;
+  flex-direction: column;
+  gap: 15px;
+  border-radius: 10px;
+}
+.course_select_button_container {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+.grandTitle {
+  font-size: 14px;
+  color: rgba(90, 103, 133, 1);
+}
+
+  .course_select_button {
+    background: rgba(255, 255, 255, 1);
+    padding: 2px 6px;
+    border-radius: 5px;
+    font-size: 14px;
+    font-weight: 400;
+    color: rgba(54, 129, 252, 1);
+    cursor: pointer;
+  }
+
+  .course_select_button_active {
+    background: rgba(54, 129, 252, 1);
+    color: #fff;
+  }
+</style>

+ 5 - 0
src/router/index.js

@@ -29,6 +29,11 @@ const router = createRouter({
       // which is lazy-loaded when the route is visited.
       // which is lazy-loaded when the route is visited.
       component: () => import('../views/admin.vue')
       component: () => import('../views/admin.vue')
     },
     },
+    {
+      path: '/course',
+      name: 'course',
+      component: () => import('../views/coursepage.vue')
+    },
     {
     {
       path: "/iframe/:title/:id",
       path: "/iframe/:title/:id",
       name: "iframe",
       name: "iframe",

+ 95 - 0
src/views/coursepage.vue

@@ -0,0 +1,95 @@
+<template>
+  <!-- <Header v-if="!gotype.gotype"></Header> -->
+  <div class="course_page_header">
+    <div class="course_page_header_left">
+      <img src="../assets/img/cszylogo.png" alt="">
+      <div>深圳城市职业学院-AI智能教育平台</div>
+    </div>
+    <div class="course_page_header_right">
+      <div>{{ user.user.name }}</div>
+      <div class="one_letter">{{ user.user.name?.[0] }}</div>
+    </div>
+  </div>
+  <div class="course-page" >
+    <!-- <div v-if="gotype.gotype && gotype.gotype == 'CourseCon'" class="pgb">
+      <router-link to="/" class="pgbL">
+        <img src="../assets/icon/backPage.svg" alt="">
+        <div style="font-weight: 700;">AI通识课</div>
+      </router-link>
+    </div> -->
+    <CoursePage />
+  </div>
+</template>
+
+<script setup>
+import Header from './header.vue'
+import CoursePage from '@/components/main/coursepage.vue'
+import { pageGotype,userInfoStore } from '../stores/counter'
+
+const gotype = pageGotype()
+const user = userInfoStore()
+
+</script>
+
+<style scoped lang="scss">
+.course_page_header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 10px 3%;
+  background: #fff;
+}
+.course_page_header_left {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+.course_page_header_right {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+.course-page {
+  background: #F0F2F5;
+  padding: 20px 10%;
+  min-height: 100vh;
+  overflow: auto;
+}
+
+.liyuan {
+  min-height: 100vh;
+  padding: 20px 90px;
+}
+
+.pgb {
+  font-weight: bold;
+  font-size: 20px;
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  padding: 20px 0 0;
+  margin-bottom: 15px;
+}
+
+.pgbL {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  cursor: pointer;
+  color: #000;
+  font-family: '黑体';
+  text-decoration: none;
+}
+.one_letter {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 32px;
+  height: 32px;
+  font-size: 14px;
+  color: #fff;
+  background: #548CFF;
+  border-radius: 50%;
+  flex-shrink: 0;
+}
+</style>