dusenyao преди 2 години
родител
ревизия
eb31d423ba

+ 1 - 1
.vscode/settings.json

@@ -1,5 +1,5 @@
 {
-  "cSpell.words": ["AILP", "csitem", "GCLS", "KHPJ", "NNPE", "XYZP"],
+  "cSpell.words": ["AILP", "bookailp", "booknnpe", "booknpc", "csitem", "GCLS", "KHPJ", "NNPE", "XYZP"],
   "workbench.colorCustomizations": {
     "titleBar.activeBackground": "#42b883",
     "titleBar.activeForeground": "#15202b",

+ 37 - 46
package-lock.json

@@ -14,7 +14,7 @@
         "axios": "^0.27.2",
         "book-ui": "file:../book-ui-0.3.19.tgz",
         "core-js": "^3.26.1",
-        "dayjs": "^1.11.6",
+        "dayjs": "^1.11.7",
         "element-ui": "^2.15.12",
         "gcls-book-question-ui": "file:../gcls-book-question-ui-0.1.0.tgz",
         "jquery": "^3.6.1",
@@ -24,7 +24,7 @@
         "md5": "^2.3.0",
         "normalize.css": "^8.0.1",
         "nprogress": "^0.2.0",
-        "tinymce": "^5.10.6",
+        "tinymce": "^5.10.7",
         "vue": "^2.7.14",
         "vue-i18n": "^8.28.2",
         "vue-pdf": "^4.3.0",
@@ -58,7 +58,7 @@
         "sass": "^1.56.1",
         "sass-loader": "^10.4.1",
         "script-ext-html-webpack-plugin": "^2.1.5",
-        "stylelint": "^14.15.0",
+        "stylelint": "^14.16.0",
         "stylelint-config-prettier": "^9.0.4",
         "stylelint-config-recess-order": "^3.0.0",
         "stylelint-config-recommended-vue": "^1.4.0",
@@ -7650,10 +7650,9 @@
       }
     },
     "node_modules/dayjs": {
-      "version": "1.11.6",
-      "resolved": "https://repo.huaweicloud.com/repository/npm/dayjs/-/dayjs-1.11.6.tgz",
-      "integrity": "sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==",
-      "license": "MIT"
+      "version": "1.11.7",
+      "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.7.tgz",
+      "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ=="
     },
     "node_modules/de-indent": {
       "version": "1.0.2",
@@ -17563,11 +17562,10 @@
       }
     },
     "node_modules/postcss-selector-parser": {
-      "version": "6.0.10",
-      "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
-      "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
+      "version": "6.0.11",
+      "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz",
+      "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "cssesc": "^3.0.0",
         "util-deprecate": "^1.0.2"
@@ -20264,11 +20262,10 @@
       }
     },
     "node_modules/stylelint": {
-      "version": "14.15.0",
-      "resolved": "https://repo.huaweicloud.com/repository/npm/stylelint/-/stylelint-14.15.0.tgz",
-      "integrity": "sha512-JOgDAo5QRsqiOZPZO+B9rKJvBm64S0xasbuRPAbPs6/vQDgDCnZLIiw6XcAS6GQKk9k1sBWR6rmH3Mfj8OknKg==",
+      "version": "14.16.0",
+      "resolved": "https://registry.npmmirror.com/stylelint/-/stylelint-14.16.0.tgz",
+      "integrity": "sha512-X6uTi9DcxjzLV8ZUAjit1vsRtSwcls0nl07c9rqOPzvpA8IvTX/xWEkBRowS0ffevRrqkHa/ThDEu86u73FQDg==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "@csstools/selector-specificity": "^2.0.2",
         "balanced-match": "^2.0.0",
@@ -20283,7 +20280,7 @@
         "globby": "^11.1.0",
         "globjoin": "^0.1.4",
         "html-tags": "^3.2.0",
-        "ignore": "^5.2.0",
+        "ignore": "^5.2.1",
         "import-lazy": "^4.0.0",
         "imurmurhash": "^0.1.4",
         "is-plain-object": "^5.0.0",
@@ -20297,7 +20294,7 @@
         "postcss-media-query-parser": "^0.2.3",
         "postcss-resolve-nested-selector": "^0.1.1",
         "postcss-safe-parser": "^6.0.0",
-        "postcss-selector-parser": "^6.0.10",
+        "postcss-selector-parser": "^6.0.11",
         "postcss-value-parser": "^4.2.0",
         "resolve-from": "^5.0.0",
         "string-width": "^4.2.3",
@@ -20314,10 +20311,6 @@
       },
       "engines": {
         "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/stylelint"
       }
     },
     "node_modules/stylelint-config-html": {
@@ -20746,11 +20739,10 @@
       }
     },
     "node_modules/stylelint/node_modules/ignore": {
-      "version": "5.2.0",
-      "resolved": "https://repo.huaweicloud.com/repository/npm/ignore/-/ignore-5.2.0.tgz",
-      "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+      "version": "5.2.1",
+      "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.2.1.tgz",
+      "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">= 4"
       }
@@ -21649,10 +21641,9 @@
       "license": "MIT"
     },
     "node_modules/tinymce": {
-      "version": "5.10.6",
-      "resolved": "https://repo.huaweicloud.com/repository/npm/tinymce/-/tinymce-5.10.6.tgz",
-      "integrity": "sha512-bnF2LUoycDsoZZLQBNHbOijrmoJuEeR1rQdqgo4s77BedufpOVnDh00OZKbseHeTMCxhVH05wvOqxLsi6vpeZw==",
-      "license": "LGPL-2.1"
+      "version": "5.10.7",
+      "resolved": "https://registry.npmmirror.com/tinymce/-/tinymce-5.10.7.tgz",
+      "integrity": "sha512-9UUjaO0R7FxcFo0oxnd1lMs7H+D0Eh+dDVo5hKbVe1a+VB0nit97vOqlinj+YwgoBDt6/DSCUoWqAYlLI8BLYA=="
     },
     "node_modules/tmpl": {
       "version": "1.0.5",
@@ -29113,9 +29104,9 @@
       }
     },
     "dayjs": {
-      "version": "1.11.6",
-      "resolved": "https://repo.huaweicloud.com/repository/npm/dayjs/-/dayjs-1.11.6.tgz",
-      "integrity": "sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ=="
+      "version": "1.11.7",
+      "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.7.tgz",
+      "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ=="
     },
     "de-indent": {
       "version": "1.0.2",
@@ -35953,9 +35944,9 @@
       "dev": true
     },
     "postcss-selector-parser": {
-      "version": "6.0.10",
-      "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
-      "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
+      "version": "6.0.11",
+      "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz",
+      "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==",
       "dev": true,
       "requires": {
         "cssesc": "^3.0.0",
@@ -37904,9 +37895,9 @@
       }
     },
     "stylelint": {
-      "version": "14.15.0",
-      "resolved": "https://repo.huaweicloud.com/repository/npm/stylelint/-/stylelint-14.15.0.tgz",
-      "integrity": "sha512-JOgDAo5QRsqiOZPZO+B9rKJvBm64S0xasbuRPAbPs6/vQDgDCnZLIiw6XcAS6GQKk9k1sBWR6rmH3Mfj8OknKg==",
+      "version": "14.16.0",
+      "resolved": "https://registry.npmmirror.com/stylelint/-/stylelint-14.16.0.tgz",
+      "integrity": "sha512-X6uTi9DcxjzLV8ZUAjit1vsRtSwcls0nl07c9rqOPzvpA8IvTX/xWEkBRowS0ffevRrqkHa/ThDEu86u73FQDg==",
       "dev": true,
       "requires": {
         "@csstools/selector-specificity": "^2.0.2",
@@ -37922,7 +37913,7 @@
         "globby": "^11.1.0",
         "globjoin": "^0.1.4",
         "html-tags": "^3.2.0",
-        "ignore": "^5.2.0",
+        "ignore": "^5.2.1",
         "import-lazy": "^4.0.0",
         "imurmurhash": "^0.1.4",
         "is-plain-object": "^5.0.0",
@@ -37936,7 +37927,7 @@
         "postcss-media-query-parser": "^0.2.3",
         "postcss-resolve-nested-selector": "^0.1.1",
         "postcss-safe-parser": "^6.0.0",
-        "postcss-selector-parser": "^6.0.10",
+        "postcss-selector-parser": "^6.0.11",
         "postcss-value-parser": "^4.2.0",
         "resolve-from": "^5.0.0",
         "string-width": "^4.2.3",
@@ -38029,9 +38020,9 @@
           }
         },
         "ignore": {
-          "version": "5.2.0",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/ignore/-/ignore-5.2.0.tgz",
-          "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+          "version": "5.2.1",
+          "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.2.1.tgz",
+          "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==",
           "dev": true
         },
         "map-obj": {
@@ -38862,9 +38853,9 @@
       "dev": true
     },
     "tinymce": {
-      "version": "5.10.6",
-      "resolved": "https://repo.huaweicloud.com/repository/npm/tinymce/-/tinymce-5.10.6.tgz",
-      "integrity": "sha512-bnF2LUoycDsoZZLQBNHbOijrmoJuEeR1rQdqgo4s77BedufpOVnDh00OZKbseHeTMCxhVH05wvOqxLsi6vpeZw=="
+      "version": "5.10.7",
+      "resolved": "https://registry.npmmirror.com/tinymce/-/tinymce-5.10.7.tgz",
+      "integrity": "sha512-9UUjaO0R7FxcFo0oxnd1lMs7H+D0Eh+dDVo5hKbVe1a+VB0nit97vOqlinj+YwgoBDt6/DSCUoWqAYlLI8BLYA=="
     },
     "tmpl": {
       "version": "1.0.5",

+ 3 - 3
package.json

@@ -19,7 +19,7 @@
     "axios": "^0.27.2",
     "book-ui": "file:../book-ui-0.3.19.tgz",
     "core-js": "^3.26.1",
-    "dayjs": "^1.11.6",
+    "dayjs": "^1.11.7",
     "element-ui": "^2.15.12",
     "gcls-book-question-ui": "file:../gcls-book-question-ui-0.1.0.tgz",
     "jquery": "^3.6.1",
@@ -29,7 +29,7 @@
     "md5": "^2.3.0",
     "normalize.css": "^8.0.1",
     "nprogress": "^0.2.0",
-    "tinymce": "^5.10.6",
+    "tinymce": "^5.10.7",
     "vue": "^2.7.14",
     "vue-i18n": "^8.28.2",
     "vue-pdf": "^4.3.0",
@@ -63,7 +63,7 @@
     "sass": "^1.56.1",
     "sass-loader": "^10.4.1",
     "script-ext-html-webpack-plugin": "^2.1.5",
-    "stylelint": "^14.15.0",
+    "stylelint": "^14.16.0",
     "stylelint-config-prettier": "^9.0.4",
     "stylelint-config-recess-order": "^3.0.0",
     "stylelint-config-recommended-vue": "^1.4.0",

+ 6 - 0
src/components/course/CoursewareView.vue

@@ -41,6 +41,12 @@
   </div>
 </template>
 
+<script>
+export default {
+  name: 'CoursewareView'
+};
+</script>
+
 <script setup>
 import { useShowCourseware } from './courseware';
 

+ 117 - 117
src/layouts/components/LayoutHeader.vue

@@ -57,130 +57,130 @@
 </template>
 
 <script>
-import { mapGetters } from 'vuex';
-import { getToken, removeToken, getConfig } from '@/utils/auth';
+export default {
+  name: 'LayoutHeader'
+};
+</script>
+
+<script setup>
+import { ref, inject } from 'vue';
+import { getToken, getConfig } from '@/utils/auth';
 import { GetLanguageList, GetChildSysList_CanEnter_PC } from '@/api/app';
 import { loadLanguageAsync } from '@/locales/i18n';
 import { IsExistMyMessage_NotRead } from '@/api/user';
+import store from '@/store';
+import { Message } from 'element-ui';
+
+const $t = inject('$t');
+let loginNav = ref('GCLS-Learn');
+let LoginNavIndex = ref(0); // 下拉框导航索引
+let projectName = ref('教学中心');
+let projectList = ref([]);
+let userMessage = ref(null);
+let userShow = ref(false);
+let language_list = ref([]);
+let isNotRead = ref(false);
+let lang = ref('');
+let language_type = store.getters.language_type;
+
+const { token, isHas } = getToken();
+if (isHas) {
+  userMessage.value = token;
+
+  setInterval(() => {
+    isExistMyMessage_NotRead();
+  }, 120000);
+
+  getLangList();
+}
 
-export default {
-  name: 'LayoutHeader',
-  data() {
-    return {
-      activeIndex: '2', // 主导航索引
-      loginNav: 'GCLS-Learn',
-      LoginNavIndex: 0, // 下拉框导航索引
-      projectName: '教学中心',
-      projectList: [],
-      userMessage: null,
-      userShow: false,
-      language_list: [],
-      isNotRead: false,
-      lang: ''
-    };
-  },
-  computed: {
-    ...mapGetters(['language_type'])
-  },
-  created() {
-    this.getChildSysList();
-    this.isExistMyMessage_NotRead();
-
-    const { token, isHas } = getToken();
-    if (isHas) {
-      this.userMessage = token;
-
-      setInterval(() => {
-        this.isExistMyMessage_NotRead();
-      }, 120000);
-
-      this.getLangList();
-    }
+const { token: config, isHas: isConfigHas } = getConfig();
+if (isConfigHas) {
+  const link = document.querySelector("link[rel*='icon']") || document.createElement('link');
+  link.type = 'image/x-icon';
+  link.rel = 'shortcut icon';
+  link.href = config.title_icon_url;
+  document.getElementsByTagName('head')[0].appendChild(link);
+}
 
-    const { token: config, isHas: isConfigHas } = getConfig();
-    if (isConfigHas) {
-      const link = document.querySelector("link[rel*='icon']") || document.createElement('link');
-      link.type = 'image/x-icon';
-      link.rel = 'shortcut icon';
-      link.href = config.title_icon_url;
-      document.getElementsByTagName('head')[0].appendChild(link);
-    }
-  },
-  methods: {
-    // 切换导航
-    handleSelect() {
-      window.location.href = '/';
-    },
-    // 改变下拉框导航索引
-    changeLoginNavIndex(key) {
-      if (!key) return;
-      this.loginNav = key;
-      this.LoginNavIndex = this.projectList.findIndex((item) => item.key === key);
-    },
-    // 切换项目
-    handleCommand(command) {
-      this.LoginNavIndex = command;
-      if (!this.userMessage) {
-        this.$message.warning(this.$i18n.t('Key573'));
-        this.projectName = this.$i18n.t('Key2');
-        window.location.href = '/';
-        return;
-      }
-      this.projectName = this.projectList[command].name;
-      const relative_path = this.projectList[command].relative_path;
-      location.href = relative_path;
-    },
-    goPersonal() {
-      window.location.href = `/GCLS-Personal/#/EnterSys`;
-    },
-    // 切换登录的注册
-    cutLoginReg() {
-      window.location.href = '/';
-    },
-    QuitLogin() {
-      this.$store.dispatch('user/signOut');
-      sessionStorage.removeItem('useragent_root_close');
-      this.userShow = false;
-      this.userMessage = null;
-      window.location.href = '/';
-    },
-    getLangList() {
-      GetLanguageList().then(({ language_list }) => {
-        this.language_list = language_list;
-        const curLang = language_list.find((el) => el.language_type === this.language_type);
-        this.lang = curLang ? curLang.language_name : '中文';
-      });
-    },
-    async changeLang({ language_name, language_type }) {
-      this.lang = language_name;
-      await loadLanguageAsync(language_type);
-      this.getChildSysList();
-    },
-
-    isExistMyMessage_NotRead() {
-      IsExistMyMessage_NotRead().then(({ is_exist }) => {
-        this.isNotRead = JSON.parse(is_exist);
-      });
-    },
-
-    getChildSysList() {
-      GetChildSysList_CanEnter_PC()
-        .then(({ child_sys_list }) => {
-          if (child_sys_list && child_sys_list.length > 0) {
-            this.projectList = child_sys_list;
-            this.projectList.forEach((item, index) => {
-              if (item.key === this.loginNav) {
-                this.LoginNavIndex = index;
-              }
-            });
+// 切换导航
+function handleSelect() {
+  window.location.href = '/';
+}
+
+// 改变下拉框导航索引
+function changeLoginNavIndex(key) {
+  if (!key) return;
+  loginNav.value = key;
+  LoginNavIndex.value = projectList.value.findIndex((item) => item.key === key);
+}
+
+// 切换项目
+function handleCommand(command) {
+  LoginNavIndex.value = command;
+  if (!userMessage.value) {
+    Message.warning($t('Key573'));
+    projectName.value = $t('Key2');
+    window.location.href = '/';
+    return;
+  }
+  projectName.value = projectList.value[command].name;
+  const relative_path = projectList.value[command].relative_path;
+  location.href = relative_path;
+}
+function goPersonal() {
+  window.location.href = `/GCLS-Personal/#/EnterSys`;
+}
+// 切换登录的注册
+function cutLoginReg() {
+  window.location.href = '/';
+}
+function QuitLogin() {
+  store.dispatch('user/signOut');
+  sessionStorage.removeItem('useragent_root_close');
+  userShow.value = false;
+  userMessage.value = null;
+  window.location.href = '/';
+}
+function getLangList() {
+  GetLanguageList().then(({ language_list: list }) => {
+    language_list.value = list;
+    const curLang = list.find((el) => el.language_type === language_type);
+    lang.value = curLang ? curLang.language_name : '中文';
+  });
+}
+async function changeLang({ language_name, language_type }) {
+  lang.value = language_name;
+  await loadLanguageAsync(language_type);
+  getChildSysList();
+}
+
+function isExistMyMessage_NotRead() {
+  IsExistMyMessage_NotRead().then(({ is_exist }) => {
+    isNotRead.value = JSON.parse(is_exist);
+  });
+}
+isExistMyMessage_NotRead();
+
+function getChildSysList() {
+  GetChildSysList_CanEnter_PC()
+    .then(({ child_sys_list }) => {
+      if (child_sys_list && child_sys_list.length > 0) {
+        projectList.value = child_sys_list;
+        projectList.value.forEach((item, index) => {
+          if (item.key === loginNav.value) {
+            LoginNavIndex.value = index;
           }
-        })
-        .catch((err) => {
-          console.log(err);
         });
-    }
-  }
-};
+      }
+    })
+    .catch((err) => {
+      console.log(err);
+    });
+}
+getChildSysList();
+
+defineExpose({ changeLoginNavIndex });
 </script>
 
 <style lang="scss" scoped>

+ 24 - 24
src/layouts/index.vue

@@ -1,10 +1,10 @@
 <template>
   <div class="app">
     <header class="app-header">
-      <layout-header ref="header" />
-      <bread-crumb :is-show-nav.sync="isShowNav" />
+      <LayoutHeader ref="header" />
+      <BreadCrumb :is-show-nav.sync="isShowNav" />
     </header>
-    <section ref="wrap" class="app-main" :style="{ height: `calc(100vh - 64px ${isShowNav ? '- 56px' : ''})` }">
+    <section class="app-main" :style="{ height: `calc(100vh - 64px ${isShowNav ? '- 56px' : ''})` }">
       <!-- <custom-scrollbar :wrap-height="100" :content-dis="100" :content-height="100" /> -->
       <transition name="fade-transfrom" mode="out-in">
         <router-view :key="key" />
@@ -14,31 +14,31 @@
 </template>
 
 <script>
+export default {
+  name: 'LayoutPage'
+};
+</script>
+
+<script setup>
+import { ref, computed, provide } from 'vue';
+import { useRoute } from 'vue-router/composables';
+
 import LayoutHeader from './components/LayoutHeader.vue';
 import BreadCrumb from './components/BreadCrumb.vue';
 
-export default {
-  name: 'Layout',
-  components: {
-    LayoutHeader,
-    BreadCrumb
-  },
-  data() {
-    return {
-      isShowNav: false
-    };
-  },
-  computed: {
-    key() {
-      return this.$route.path;
-    }
-  },
-  created() {
-    window.onerror = (msg, source, lineno, colno) => {
-      if (msg === 'Script error.' && lineno === 0 && colno === 0) return true;
-    };
-  }
+const route = useRoute();
+let isShowNav = ref(false);
+let key = computed(() => route.path);
+
+window.onerror = (msg, source, lineno, colno) => {
+  if (msg === 'Script error.' && lineno === 0 && colno === 0) return true;
 };
+
+let header = ref();
+function changeLoginNavIndex(...args) {
+  return header.value.changeLoginNavIndex(...args);
+}
+provide('changeLoginNavIndex', changeLoginNavIndex);
 </script>
 
 <style lang="scss">

+ 10 - 10
src/views/canvas/index.vue

@@ -7,10 +7,11 @@
 <script setup>
 import { ref, onMounted } from 'vue';
 import { paintData } from './data';
+
 const whiteboard = ref(null);
-const context = ref(null);
 
 function paint() {
+  let context = whiteboard.value.getContext('2d');
   paintData.forEach(({ action, value }) => {
     if (action !== 'draw') return;
     const { fileName, data } = value;
@@ -21,24 +22,23 @@ function paint() {
     color = `#${color.length < 6 ? '0'.repeat(6 - color.length) : ''}${color}`;
     if (draw.length <= 0) return;
 
-    context.value.beginPath();
-    context.value.moveTo(width * draw[0].x, height * draw[0].y);
+    context.beginPath();
+    context.moveTo(width * draw[0].x, height * draw[0].y);
     if (type === 10) {
-      context.value.lineWidth = (3 * 2 * (thickness * width)) / (draw[0].ppt_width || 1295);
+      context.lineWidth = (3 * 2 * (thickness * width)) / (draw[0].ppt_width || 1295);
     } else {
-      context.value.lineWidth = (thickness * width) / (draw[0].ppt_width || 1295);
+      context.lineWidth = (thickness * width) / (draw[0].ppt_width || 1295);
     }
-    context.value.lineJoin = 'round';
-    context.value.strokeStyle = type === 10 ? '#fff' : color;
+    context.lineJoin = 'round';
+    context.strokeStyle = type === 10 ? '#fff' : color;
     draw.forEach(({ x, y }) => {
-      context.value.lineTo(width * x, height * y);
+      context.lineTo(width * x, height * y);
     });
-    context.value.stroke();
+    context.stroke();
   });
 }
 
 onMounted(() => {
-  context.value = whiteboard.value.getContext('2d');
   paint();
 });
 </script>

+ 296 - 233
src/views/course_details/index.vue

@@ -90,9 +90,7 @@
                   <span class="price_1" v-text="changePrice('1', CourseData.price)"></span>
                   <span class="price_2" v-text="changePrice('2', CourseData.price)"></span>
                 </span>
-                <button class="get" @click="getPurchase">
-                  {{ is_buy ? $t('Key390') : $t('Key391') }}
-                </button>
+                <button class="get" @click="handleCourseStatus">{{ buttonName }}</button>
                 <span class="collection" @click="addOrDeleteMyCollection">
                   <svg-icon :icon-class="collection ? 'collection-solid' : 'collection'" />
                 </span>
@@ -292,6 +290,17 @@
 </template>
 
 <script>
+export default {
+  name: 'CourseDetails'
+};
+</script>
+
+<script setup>
+import { ref, inject, onBeforeUnmount, computed } from 'vue';
+import { useRoute, useRouter } from 'vue-router/composables';
+import { Message } from 'element-ui';
+import store from '@/store';
+
 import Audit from '@/components/payment/Audit.vue';
 import PreviewCourse from '@/components/preview/PreviewCourse.vue';
 import Payment from '@/components/payment/Payment.vue';
@@ -300,250 +309,304 @@ import {
   CheckMyGoodsBuyStatus,
   AddMyCollection,
   CancelMyGoodsCollection,
-  CheckMyGoodsCollectionStatus
+  CheckMyGoodsCollectionStatus,
+  ApplyJoinCourse
 } from '@/api/course';
 import { GetMyGoodsBuyInfo } from '@/api/user';
 
-export default {
-  name: 'CourseDetails',
-  components: {
-    Audit,
-    Payment,
-    PreviewCourse
-  },
-  data() {
-    const query = this.$route.query;
-
-    return {
-      goods_id: query.goods_id,
-      goods_type: Number(query.goods_type),
-      readonly: 'readonly' in query ? query.readonly === 'true' : false,
-      // 调用模块
-      invok_module: query.invok_module,
-      collection: false,
-      openList: [],
-      timer: null, // 获取倒计时
-      backTime: 0,
-      auditShow: false,
-      loading: false,
-      is_buy: false,
-      is_free_license: false, // 是否机构免费授权
-      CourseData: null,
-      isData: false,
-      courseContentList: [
-        { id: 'pre_task_list', name: 'Key353' },
-        { id: 'mid_task_list', name: 'Key354' },
-        { id: 'after_task_list', name: 'Key355' }
-      ],
-      visiblePay: false,
-      orderId: '',
-      visible: false,
-      fileId: '',
-      fileType: '',
-      previewGroupId: '[]'
-    };
-  },
-  created() {
-    // 获取课程详情
-    this.loading = true;
-    CheckMyGoodsBuyStatus({ goods_type: this.goods_type, goods_id: this.goods_id }).then(
-      ({ is_buy, is_free_license }) => {
-        this.is_buy = is_buy === 'true';
-        this.is_free_license = is_free_license === 'true';
-      }
-    );
-    GetCourseInfoBox({ id: this.goods_id })
-      .then((res) => {
-        this.CourseData = res;
-        this.isData = 'id' in res;
-        this.getBackTime();
-        this.checkMyGoodsCollectionStatus();
-        this.getMyGoodsBuyInfo(this.CourseData.book_list.map(({ book_id }) => book_id));
-        this.loading = false;
-      })
-      .catch(() => {
-        this.loading = false;
-      });
-  },
-  mounted() {
-    this.$parent.$refs.header.changeLoginNavIndex(this.invok_module);
-  },
-  beforeDestroy() {
-    // 清空定时器
-    clearInterval(this.timer);
-  },
-  // 方法集合
-  methods: {
-    // 课程任务的打开和关闭
-    handleChange(val) {
-      this.openList.includes(val) ? this.openList.splice(this.openList.indexOf(val), 1) : this.openList.push(val);
-    },
-    goBook(book_id, is_buy = false) {
-      if (!is_buy) {
-        window.location.href = `/GCLS-Book/#/GoodsDetail?goods_id=${book_id}&goods_type=101&invok_module=${
-          this.invok_module ? this.invok_module : 'GCLS-Learn'
-        }`;
-      }
-    },
+const $t = inject('$t');
+const route = useRoute();
+const router = useRouter();
+const query = route.query;
+const goods_id = query.goods_id;
+const goods_type = Number(query.goods_type);
+const readonly = 'readonly' in query ? query.readonly === 'true' : false;
+// 调用模块
+const invok_module = query.invok_module;
+let collection = ref(false);
+let openList = ref([]);
+let timer = null; // 获取倒计时
+let backTime = ref(0);
+let auditShow = ref(false);
+let loading = ref(true);
+let isData = ref(false);
+let courseContentList = ref([
+  { id: 'pre_task_list', name: 'Key353' },
+  { id: 'mid_task_list', name: 'Key354' },
+  { id: 'after_task_list', name: 'Key355' }
+]);
+let visiblePay = ref(false);
+let orderId = ref('');
+let visible = ref(false);
+let fileId = ref('');
+let fileType = ref('');
+let previewGroupId = ref('[]');
+
+const changeLoginNavIndex = inject('changeLoginNavIndex');
+changeLoginNavIndex(invok_module);
+
+let orderID = ref(''); // 订单 ID
+let is_buy = ref(false); // 是否购买
+let isFree = ref(false); // 是否机构免费授权
+let isCommon = ref(false); // 是否公开
+let isApplyJoin = ref(false); // 是否已申请加入
+let applyJoinAuditStatus = ref(0); // 申请加入审核状态 0 未审核,1,审核通过,2 审核拒绝
+let applyButtonNameList = ['已申请', '去支付', '重新申请'];
+let buttonName = computed(() => {
+  if (is_buy.value || (isFree.value && isCommon.value)) return $t('Key390');
+  if (!isFree.value && isCommon.value) return '购买';
+  if (isFree.value && !isCommon.value) {
+    if (!isApplyJoin.value) return '申请加入';
+    return applyButtonNameList[applyJoinAuditStatus.value];
+  }
+  if (!isFree.value && !isCommon.value) {
+    if (!isApplyJoin.value) return '申请加入';
+    return applyButtonNameList[applyJoinAuditStatus.value];
+  }
+  return '';
+});
+
+function checkMyGoodsBuyStatus() {
+  return CheckMyGoodsBuyStatus({ goods_type, goods_id }).then(
+    ({ is_buy: buy, price, student_enter_control_type, is_apply_join, apply_join_audit_status, order_id }) => {
+      is_buy.value = buy === 'true';
+      isFree.value = price <= 0;
+      isCommon.value = student_enter_control_type === 0;
+      isApplyJoin.value = is_apply_join === 'true';
+      applyJoinAuditStatus.value = apply_join_audit_status;
+      orderID.value = order_id;
+    }
+  );
+}
+checkMyGoodsBuyStatus();
+
+/**
+ * 处理课程状态
+ */
+function handleCourseStatus() {
+  if (is_buy.value) return router.push('/');
+  if (!backTime.value) return Message.warning($t('Key389'));
+  if (isFree.value && isCommon.value) {
+    applyJoinCourse().then(() => {
+      router.push('/');
+    });
+    return;
+  }
 
-    checkMyGoodsCollectionStatus() {
-      CheckMyGoodsCollectionStatus({ goods_type: this.goods_type, goods_id: this.CourseData.id }).then(
-        ({ is_collection }) => {
-          this.collection = is_collection === 'true';
-        }
-      );
-    },
-
-    // 处理价格
-    changePrice(type, item) {
-      const str = String(item);
-      if (type === '1') {
-        return str.includes('.') ? str.split('.')[0] : str;
+  if (!isFree.value && isCommon.value) {
+    applyJoinCourse().then(({ is_audited, order_id }) => {
+      if (is_audited === 'true') {
+        auditedSuccess(order_id);
       }
+    });
+    return;
+  }
 
-      if (type === '2') {
-        return str.includes('.') ? `.${str.split('.')[1]}` : '.00';
-      }
-    },
-    // 收藏
-    addOrDeleteMyCollection() {
-      if (this.collection) {
-        CancelMyGoodsCollection({ goods_type: this.goods_type, goods_id_list: [this.CourseData.id] }).then(() => {
-          this.$message.success(this.$i18n.t('Key396'));
-          this.collection = false;
-        });
-      } else {
-        let goods_person_name_desc = '';
-        this.CourseData.teacher_list.forEach((item) => {
-          goods_person_name_desc += item.teacher_name;
-        });
-
-        AddMyCollection({
-          goods_id: this.goods_id,
-          goods_type: this.goods_type,
-          goods_name: this.CourseData.name,
-          goods_person_name_desc,
-          goods_picture_id: this.CourseData.picture_id,
-          goods_price: this.CourseData.price
-        }).then(() => {
-          this.$message.success(this.$i18n.t('Key397'));
-          this.collection = true;
-        });
-      }
-    },
-    // 购买需要先加入课程 审核 审核通过之后才能购买课程
-    getPurchase() {
-      // 购买通道关闭
-      if (this.is_buy) {
-        return this.$router.push('/');
-      }
-      if (!this.backTime) {
-        this.$message.warning(this.$i18n.t('Key389'));
-        return;
-      }
-      this.auditShow = true;
-    },
-
-    getMyGoodsBuyInfo(goods_id_list) {
-      GetMyGoodsBuyInfo({ goods_type: 101, goods_id_list }).then(({ goods_id_list_buy }) => {
-        this.CourseData.book_list.forEach((book) => {
-          this.$set(book, 'is_buy', goods_id_list_buy.includes(book.book_id));
-        });
+  if (isFree.value && !isCommon.value) {
+    if (!isApplyJoin.value || (isApplyJoin.value && applyJoinAuditStatus.value === 2)) {
+      applyJoinCourse().then(() => {
+        checkMyGoodsBuyStatus();
       });
-    },
-
-    auditedSuccess(orderId) {
-      this.orderId = orderId;
-      this.auditShow = false;
-      this.visiblePay = true;
-    },
-
-    closePayment() {
-      this.visiblePay = false;
-      this.$refs.Confirmorder.clearData();
-    },
-
-    judgePayResult(bool) {
-      this.isPayment = false;
-      if (bool) {
-        this.$message.success(this.$t('Key657'));
-      } else {
-        this.$message.warning('支付失败');
-      }
-      CheckMyGoodsBuyStatus({ goods_type: this.goods_type, goods_id: this.goods_id }).then(({ is_buy }) => {
-        this.is_buy = is_buy === 'true';
+      return;
+    }
+    if (applyJoinAuditStatus.value === 0) return Message.warning('请等待审核通过');
+  }
+
+  if (!isFree.value && !isCommon.value) {
+    if (!isApplyJoin.value || (isApplyJoin.value && applyJoinAuditStatus.value === 2)) {
+      applyJoinCourse().then(() => {
+        checkMyGoodsBuyStatus();
+      });
+      return;
+    }
+    if (applyJoinAuditStatus.value === 0) return Message.warning('请等待审核通过');
+    if (applyJoinAuditStatus.value === 1) {
+      checkMyGoodsBuyStatus().then(() => {
+        auditedSuccess(orderID.value);
       });
-    },
+    }
+  }
+}
 
-    closeaudit() {
-      this.auditShow = false;
-    },
+/**
+ * 申请加入课程
+ */
+function applyJoinCourse() {
+  return ApplyJoinCourse({ course_id: goods_id });
+}
 
-    preview(fileId, fileType, goods_id, group_id_selected_info) {
-      if (fileType === 'courseware') {
-        CheckMyGoodsBuyStatus({ goods_id, goods_type: 101 }).then(({ is_buy }) => {
-          if (is_buy === 'false') {
-            return this.$message.warning('请先购买该课件对应的教材');
-          }
-          this.fileId = fileId;
-          this.fileType = fileType;
-          this.previewGroupId = group_id_selected_info ?? '[]';
-          this.visible = true;
-        });
-      }
+let CourseData = ref(null);
+GetCourseInfoBox({ id: goods_id })
+  .then((res) => {
+    CourseData.value = res;
+    isData.value = 'id' in res;
+    getBackTime();
+    checkMyGoodsCollectionStatus();
+    getMyGoodsBuyInfo(CourseData.value.book_list.map(({ book_id }) => book_id));
+  })
+  .finally(() => {
+    loading.value = false;
+  });
+
+// 课程任务的打开和关闭
+function handleChange(val) {
+  let index = openList.value.indexOf(val);
+  index === -1 ? openList.value.push(val) : openList.value.splice(index, 1);
+}
 
-      if (fileType === 'file') {
-        if (this.$store.state.user.user_type !== 'TEACHER' && !this.is_buy) {
-          this.$message.warning('请先购买该课程');
-          return;
-        }
-        this.fileId = fileId;
-        this.fileType = fileType;
-        this.visible = true;
-      }
-    },
-
-    dialogClose() {
-      this.visible = false;
-      this.fileId = '';
-      this.fileType = '';
-    },
-
-    // 获取当前时间到指定时间的倒计时
-    getBackTime() {
-      const date = new Date(this.CourseData.end_date);
-      const targetTime = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59).getTime();
-      // 目标时间戳 - 当前时间戳 = 倒计时
-      this.timer = setInterval(() => {
-        let backTime = targetTime - new Date().getTime();
-        if (backTime > 0) {
-          backTime = this.formatduring(backTime);
-          this.backTime = backTime;
-        } else {
-          this.backTime = 0;
-          clearInterval(this.timer);
-        }
-      }, 1000);
-    },
-    // 倒计时时间戳转换为 天 小时 分钟 秒
-    formatduring(mss) {
-      const days = parseInt(mss / (1000 * 60 * 60 * 24));
-      const hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
-      const minutes = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60));
-      const seconds = parseInt((mss % (1000 * 60)) / 1000);
-      // 如果到时间了返回false  关闭购买通道  无法购买
-      if (days <= 0 && hours <= 0 && minutes <= 0 && seconds <= 0) {
-        return false;
+function goBook(book_id, is_buy = false) {
+  if (!is_buy) {
+    window.location.href = `/GCLS-Book/#/GoodsDetail?goods_id=${book_id}&goods_type=101&invok_module=${
+      invok_module || 'GCLS-Learn'
+    }`;
+  }
+}
+
+function checkMyGoodsCollectionStatus() {
+  CheckMyGoodsCollectionStatus({ goods_type, goods_id: CourseData.value.id }).then(({ is_collection }) => {
+    collection.value = is_collection === 'true';
+  });
+}
+
+// 处理价格
+function changePrice(type, item) {
+  const str = String(item);
+  if (type === '1') {
+    return str.includes('.') ? str.split('.')[0] : str;
+  }
+
+  if (type === '2') {
+    return str.includes('.') ? `.${str.split('.')[1]}` : '.00';
+  }
+}
+// 收藏
+function addOrDeleteMyCollection() {
+  if (collection.value) {
+    CancelMyGoodsCollection({ goods_type, goods_id_list: [CourseData.value.id] }).then(() => {
+      Message.success($t('Key396'));
+      collection.value = false;
+    });
+  } else {
+    let goods_person_name_desc = '';
+    CourseData.value.teacher_list.forEach((item) => {
+      goods_person_name_desc += item.teacher_name;
+    });
+
+    AddMyCollection({
+      goods_id,
+      goods_type,
+      goods_name: CourseData.value.name,
+      goods_person_name_desc,
+      goods_picture_id: CourseData.value.picture_id,
+      goods_price: CourseData.value.price
+    }).then(() => {
+      Message.success($t('Key397'));
+      collection.value = true;
+    });
+  }
+}
+
+function getMyGoodsBuyInfo(goods_id_list) {
+  GetMyGoodsBuyInfo({ goods_type: 101, goods_id_list }).then(({ goods_id_list_buy }) => {
+    CourseData.value.book_list.forEach((book) => {
+      book['is_buy'] = goods_id_list_buy.includes(book.book_id);
+    });
+  });
+}
+
+function auditedSuccess(id) {
+  orderId.value = id;
+  auditShow.value = false;
+  visiblePay.value = true;
+}
+
+let Confirmorder = ref();
+function closePayment() {
+  visiblePay.value = false;
+  Confirmorder.value.clearData();
+}
+
+function judgePayResult(bool) {
+  if (bool) {
+    Message.success($t('Key657'));
+  } else {
+    Message.warning('支付失败');
+  }
+  CheckMyGoodsBuyStatus({ goods_type, goods_id }).then(({ is_buy: buy }) => {
+    is_buy.value = buy === 'true';
+  });
+}
+
+function closeaudit() {
+  auditShow.value = false;
+}
+
+function preview(fId, fType, goods_id, group_id_selected_info) {
+  if (fileType.value === 'courseware') {
+    CheckMyGoodsBuyStatus({ goods_id, goods_type: 101 }).then(({ is_buy }) => {
+      if (is_buy === 'false') {
+        return Message.warning('请先购买该课件对应的教材');
       }
-      return {
-        days,
-        hours,
-        minutes,
-        seconds
-      };
+      fileId.value = fId;
+      fileType.value = fType;
+      previewGroupId.value = group_id_selected_info ?? '[]';
+      visible.value = true;
+    });
+  }
+
+  if (fileType.value === 'file') {
+    if (store.state.user.user_type !== 'TEACHER' && !is_buy.value) {
+      Message.warning('请先购买该课程');
+      return;
     }
+    fileId.value = fId;
+    fileType.value = fType;
+    visible.value = true;
   }
-};
+}
+
+function dialogClose() {
+  visible.value = false;
+  fileId.value = '';
+  fileType.value = '';
+}
+
+// 获取当前时间到指定时间的倒计时
+function getBackTime() {
+  const date = new Date(CourseData.value.end_date);
+  const targetTime = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59).getTime();
+  // 目标时间戳 - 当前时间戳 = 倒计时
+  timer = setInterval(() => {
+    let diffTime = targetTime - new Date().getTime();
+    if (diffTime > 0) {
+      backTime.value = formatduring(diffTime);
+    } else {
+      backTime.value = 0;
+      clearInterval(timer);
+    }
+  }, 1000);
+}
+// 倒计时时间戳转换为 天 小时 分钟 秒
+function formatduring(mss) {
+  const days = parseInt(mss / (1000 * 60 * 60 * 24));
+  const hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
+  const minutes = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60));
+  const seconds = parseInt((mss % (1000 * 60)) / 1000);
+  // 如果到时间了返回false  关闭购买通道  无法购买
+  if (days <= 0 && hours <= 0 && minutes <= 0 && seconds <= 0) {
+    return false;
+  }
+  return {
+    days,
+    hours,
+    minutes,
+    seconds
+  };
+}
+
+onBeforeUnmount(() => {
+  clearInterval(timer);
+});
 </script>
 
 <style lang="scss" scoped>

+ 42 - 33
src/views/login/index.vue

@@ -43,7 +43,12 @@
         />
       </el-form-item>
 
-      <!-- <el-form-item class="dynamic_verification_code" prop="dynamic_verification_code">
+      <!-- 邮箱验证码 -->
+      <el-form-item
+        v-if="isEnableDynamicVerification"
+        class="dynamic_verification_code"
+        prop="dynamic_verification_code"
+      >
         <el-input v-model="loginForm.dynamic_verification_code" placeholder="邮箱验证码" />
         <div
           class="verificationCode-btn"
@@ -52,7 +57,7 @@
         >
           {{ verificationCodeShow ? time + 's' : '获取' }}
         </div>
-      </el-form-item> -->
+      </el-form-item>
 
       <el-row>
         <el-col :span="12">
@@ -90,6 +95,7 @@ export default {
 <script setup>
 import { ref, inject } from 'vue';
 import { GetVerificationCodeImage } from '@/api/app';
+import { getConfig } from '@/utils/auth';
 import { SendVerificationCode } from '@/api/user';
 import { getConfigInformation } from '@/utils/index';
 import { Message } from 'element-ui';
@@ -121,10 +127,13 @@ let loginRules = ref({
   // dynamic_verification_code: [{ required: true, trigger: 'blur', message: '邮箱验证码不能为空' }]
 });
 
-async function getConfig() {
+let isEnableDynamicVerification = ref(false);
+async function getConfigInfo() {
   await getConfigInformation();
+  const { isHas, token } = getConfig();
+  if (isHas) isEnableDynamicVerification.value = token.is_enable_dynamic_verification_code_for_user_login === 'true';
 }
-getConfig();
+getConfigInfo();
 
 // 图片验证码
 let image_content_base64 = ref('');
@@ -137,36 +146,36 @@ function updateVerificationCode() {
 updateVerificationCode();
 
 // 邮箱验证码
-// let verificationCodeShow = ref(false);
-// let time = ref(60);
-// function getVerificationCode() {
-//   if (time.value !== 60) return;
+let verificationCodeShow = ref(false);
+let time = ref(60);
+function getVerificationCode() {
+  if (time.value !== 60 || !isEnableDynamicVerification.value) return;
 
-//   if (!loginForm.value.user_name) {
-//     Message.warning('请先输入邮箱或手机号码');
-//     return;
-//   }
-//   verificationCodeShow.value = true;
-//   let timer = null;
-//   timer = setInterval(() => {
-//     time.value -= 1;
-//     if (time.value === 0) {
-//       verificationCodeShow.value = false;
-//       clearInterval(timer);
-//       timer = null;
-//       time.value = 60;
-//     }
-//   }, 1000);
-//   SendVerificationCode({
-//     verification_type: 'EMAIL',
-//     phone_or_email: loginForm.value.user_name
-//   }).catch(() => {
-//     verificationCodeShow.value = false;
-//     clearInterval(timer);
-//     timer = null;
-//     time.value = 60;
-//   });
-// }
+  if (!loginForm.value.user_name) {
+    Message.warning('请先输入邮箱或手机号码');
+    return;
+  }
+  verificationCodeShow.value = true;
+  let timer = null;
+  timer = setInterval(() => {
+    time.value -= 1;
+    if (time.value === 0) {
+      verificationCodeShow.value = false;
+      clearInterval(timer);
+      timer = null;
+      time.value = 60;
+    }
+  }, 1000);
+  SendVerificationCode({
+    verification_type: 'EMAIL',
+    phone_or_email: loginForm.value.user_name
+  }).catch(() => {
+    verificationCodeShow.value = false;
+    clearInterval(timer);
+    timer = null;
+    time.value = 60;
+  });
+}
 
 // 登录
 const router = useRouter();

+ 1 - 1
src/views/main/TaskList.vue

@@ -72,7 +72,7 @@
 
 <script>
 export default {
-  name: 'TaskList'
+  name: 'TaskPage'
 };
 </script>
 

+ 5 - 5
src/views/teacher/create_course/step_one/CourseInfo.vue

@@ -174,11 +174,6 @@ getMyOrgList().then(({ org_list }) => {
 if (id || is_use_template) {
   getCourseInfo_ContainCSItem(id ?? template_id);
 }
-// 创建课程时,默认授课教师是自己
-if (!id && !is_template) {
-  form.value.teacher_id_list.push(store.state.user.user_code);
-  getUserList();
-}
 
 let user_list = ref([]);
 let form = ref({
@@ -197,6 +192,11 @@ let form = ref({
   is_enable_KHPJ: false,
   is_enable_XYZP: false
 });
+// 创建课程时,默认授课教师是自己
+if (!id && !is_template) {
+  form.value.teacher_id_list.push(store.state.user.user_code);
+  getUserList();
+}
 function getCourseInfo_ContainCSItem(id) {
   GetCourseInfo_ContainCSItem({ id }).then(
     ({