Browse Source

对接分享接口和图片上传功能优化

dusenyao 1 year ago
parent
commit
bc1f13bd94

+ 9 - 9
package-lock.json

@@ -3952,9 +3952,9 @@
       }
       }
     },
     },
     "core-js": {
     "core-js": {
-      "version": "3.33.0",
-      "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.33.0.tgz",
-      "integrity": "sha512-HoZr92+ZjFEKar5HS6MC776gYslNOKHt75mEBKWKnPeFDpZ6nH5OeF3S6HFT1mUAUZKrzkez05VboaX8myjSuw=="
+      "version": "3.33.1",
+      "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.33.1.tgz",
+      "integrity": "sha512-qVSq3s+d4+GsqN0teRCJtM6tdEEXyWxjzbhVrCHmBS5ZTM0FS2MOS0D13dUXAWDUN6a+lHI/N1hF9Ytz6iLl9Q=="
     },
     },
     "core-js-compat": {
     "core-js-compat": {
       "version": "3.33.0",
       "version": "3.33.0",
@@ -5069,9 +5069,9 @@
       }
       }
     },
     },
     "eslint-plugin-vue": {
     "eslint-plugin-vue": {
-      "version": "9.17.0",
-      "resolved": "https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-9.17.0.tgz",
-      "integrity": "sha512-r7Bp79pxQk9I5XDP0k2dpUC7Ots3OSWgvGZNu3BxmKK6Zg7NgVtcOB6OCna5Kb9oQwJPl5hq183WD0SY5tZtIQ==",
+      "version": "9.18.0",
+      "resolved": "https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-9.18.0.tgz",
+      "integrity": "sha512-yUM8a2OD/7Qs0PiugkRaxgz5KBRvzMvWShity2UvVFAN0yk8029mGpTdg/TNARPiYzp335mEwDHwcAR8tQNe4g==",
       "dev": true,
       "dev": true,
       "requires": {
       "requires": {
         "@eslint-community/eslint-utils": "^4.4.0",
         "@eslint-community/eslint-utils": "^4.4.0",
@@ -11579,9 +11579,9 @@
       }
       }
     },
     },
     "vue-eslint-parser": {
     "vue-eslint-parser": {
-      "version": "9.3.1",
-      "resolved": "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-9.3.1.tgz",
-      "integrity": "sha512-Clr85iD2XFZ3lJ52/ppmUDG/spxQu6+MAeHXjjyI4I1NUYZ9xmenQp4N0oaHJhrA8OOxltCVxMRfANGa70vU0g==",
+      "version": "9.3.2",
+      "resolved": "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-9.3.2.tgz",
+      "integrity": "sha512-q7tWyCVaV9f8iQyIA5Mkj/S6AoJ9KBN8IeUSf3XEmBrOtxOZnfTg5s4KClbZBCK3GtnT/+RyCLZyDHuZwTuBjg==",
       "dev": true,
       "dev": true,
       "requires": {
       "requires": {
         "debug": "^4.3.4",
         "debug": "^4.3.4",

+ 2 - 2
package.json

@@ -11,7 +11,7 @@
   "dependencies": {
   "dependencies": {
     "@tinymce/tinymce-vue": "^3.2.8",
     "@tinymce/tinymce-vue": "^3.2.8",
     "axios": "^1.5.1",
     "axios": "^1.5.1",
-    "core-js": "^3.33.0",
+    "core-js": "^3.33.1",
     "element-ui": "^2.15.14",
     "element-ui": "^2.15.14",
     "js-cookie": "^3.0.5",
     "js-cookie": "^3.0.5",
     "md5": "^2.3.0",
     "md5": "^2.3.0",
@@ -35,7 +35,7 @@
     "compression-webpack-plugin": "^6.1.1",
     "compression-webpack-plugin": "^6.1.1",
     "eslint": "^8.52.0",
     "eslint": "^8.52.0",
     "eslint-plugin-prettier": "^5.0.1",
     "eslint-plugin-prettier": "^5.0.1",
-    "eslint-plugin-vue": "^9.17.0",
+    "eslint-plugin-vue": "^9.18.0",
     "patch-package": "^8.0.0",
     "patch-package": "^8.0.0",
     "postcss-html": "^1.5.0",
     "postcss-html": "^1.5.0",
     "prettier": "^3.0.3",
     "prettier": "^3.0.3",

+ 7 - 2
src/api/app.js

@@ -35,8 +35,13 @@ export function GetFileStoreInfo(data) {
  * @param {object} file 文件对象
  * @param {object} file 文件对象
  */
  */
 export function fileUpload(SecurityLevel, file) {
 export function fileUpload(SecurityLevel, file) {
-  const formData = new FormData();
-  formData.append(file.filename, file.file, file.file.name);
+  let formData = null;
+  if (file instanceof FormData) {
+    formData = file;
+  } else {
+    formData = new FormData();
+    formData.append(file.filename, file.file, file.file.name);
+  }
 
 
   return http.postForm('/GCLSFileServer/WebFileUpload', formData, {
   return http.postForm('/GCLSFileServer/WebFileUpload', formData, {
     params: {
     params: {

+ 7 - 0
src/api/exercise.js

@@ -70,3 +70,10 @@ export function GetQuestionInfo(data) {
 export function DeleteQuestion(data) {
 export function DeleteQuestion(data) {
   return http.post(`/TeachingServer/ExerciseManager/DeleteQuestion`, data);
   return http.post(`/TeachingServer/ExerciseManager/DeleteQuestion`, data);
 }
 }
+
+/**
+ * 创建分享记录
+ */
+export function CreateShareRecord(data) {
+  return http.post(`/TeachingServer/ExerciseManager/CreateShareRecord`, data);
+}

+ 24 - 0
src/components/common/RichText.vue

@@ -37,6 +37,7 @@ import 'tinymce/plugins/autoresize'; // 自动调整大小插件
 import 'tinymce/plugins/ax_wordlimit'; // 字数限制插件
 import 'tinymce/plugins/ax_wordlimit'; // 字数限制插件
 
 
 import { getRandomNumber } from '@/utils';
 import { getRandomNumber } from '@/utils';
+import { fileUpload } from '@/api/app';
 
 
 export default {
 export default {
   name: 'RichText',
   name: 'RichText',
@@ -91,6 +92,29 @@ export default {
         ax_wordlimit_callback(editor) {
         ax_wordlimit_callback(editor) {
           editor.execCommand('undo');
           editor.execCommand('undo');
         },
         },
+        /**
+         * 图片上传自定义逻辑函数
+         * @param {object} blobInfo 文件数据
+         * @param {Function} success 成功回调函数
+         * @param {Function} fail 失败回调函数
+         */
+        images_upload_handler(blobInfo, success, fail) {
+          let file = blobInfo.blob();
+          console.log(success);
+          const formData = new FormData();
+          formData.append(file.name, file, file.name);
+          fileUpload('Mid', formData)
+            .then(({ file_info_list }) => {
+              if (file_info_list.length > 0) {
+                success(file_info_list[0].file_url);
+              } else {
+                fail('上传失败');
+              }
+            })
+            .catch(() => {
+              fail('上传失败');
+            });
+        },
       },
       },
     };
     };
   },
   },

+ 45 - 0
src/components/common/SoundRecord.vue

@@ -0,0 +1,45 @@
+<!-- 录音 -->
+<template>
+  <div>
+    <span @click="startRecord">开始录音</span>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'SoundRecord',
+  data() {
+    return {
+      isRecording: false,
+      recordedAudio: null,
+      mediaRecorder: null,
+      chunks: [],
+    };
+  },
+  methods: {
+    // 开始录音
+    startRecord() {
+      navigator.mediaDevices
+        .getUserMedia({ audio: true })
+        .then((stream) => {
+          this.mediaRecorder = new MediaRecorder(stream);
+          this.mediaRecorder.start();
+          this.isRecording = true;
+          this.chunks = [];
+          this.mediaRecorder.addEventListener('dataavailable', (e) => {
+            this.chunks.push(e.data);
+          });
+          this.mediaRecorder.addEventListener('stop', () => {
+            this.recordedAudio = new Blob(this.chunks, { type: 'audio/mp3' });
+            this.isRecording = false;
+          });
+        })
+        .catch((err) => {
+          console.log(err);
+        });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 2 - 0
src/main.js

@@ -11,6 +11,8 @@ import { setupRouterGuard } from '@/router/guard';
 import ElementUI from 'element-ui';
 import ElementUI from 'element-ui';
 import '@/styles/element-variables.scss';
 import '@/styles/element-variables.scss';
 
 
+import '@/utils/filter';
+
 setupRouterGuard(router);
 setupRouterGuard(router);
 
 
 Vue.use(ElementUI, {
 Vue.use(ElementUI, {

+ 12 - 0
src/utils/filter.js

@@ -0,0 +1,12 @@
+import Vue from 'vue';
+
+// 创建一个全局过滤器,用于限制字符串只能输入数字,第二个参数是能输入的小数点位数,去除多余的字母和小数点、数字
+Vue.filter('number', (value, num = 0) => {
+  return value
+    .replace(/[^\d.]/g, '')
+    .replace(/\.{2,}/g, '.')
+    .replace('.', `$#$`)
+    .replace(/\./g, '')
+    .replace('$#$', '.')
+    .replace(new RegExp(`^(\\-)*(\\d+)\\.(\\d{${num}}).*$`), '$1$2.$3');
+});

+ 13 - 0
src/utils/index.js

@@ -2,3 +2,16 @@
 export function getRandomNumber() {
 export function getRandomNumber() {
   return Math.random().toString(36).substring(2, 10); // 生成一个随机字符串
   return Math.random().toString(36).substring(2, 10); // 生成一个随机字符串
 }
 }
+
+/**
+ * 下载文件
+ * @param {String} url 文件地址
+ * @param {String} downloadName 文件名称
+ */
+export function downloadFile(url, downloadName) {
+  const a = document.createElement('a');
+  a.href = url;
+  a.download = downloadName;
+  a.click();
+  a.remove();
+}

+ 4 - 0
src/views/exercise_questions/preview/JudgePreview.vue

@@ -61,6 +61,10 @@ export default {
     };
     };
   },
   },
   methods: {
   methods: {
+    getAnswer() {
+      return this.answer;
+    },
+
     isAnswer(mark, option_type) {
     isAnswer(mark, option_type) {
       return this.answer.some((li) => li.mark === mark && li.option_type === option_type);
       return this.answer.some((li) => li.mark === mark && li.option_type === option_type);
     },
     },

+ 3 - 0
src/views/exercise_questions/preview/SelectPreview.vue

@@ -47,6 +47,9 @@ export default {
     };
     };
   },
   },
   methods: {
   methods: {
+    getAnswer() {
+      return this.answer;
+    },
     isAnswer(mark) {
     isAnswer(mark) {
       return this.answer.indexOf(mark) !== -1;
       return this.answer.indexOf(mark) !== -1;
     },
     },

+ 110 - 9
src/views/home/personal_question/components/ExerciseLink.vue

@@ -1,17 +1,36 @@
 <!-- 练习题链接 -->
 <!-- 练习题链接 -->
 <template>
 <template>
-  <el-dialog :visible="visible" title="练习题链接" width="400px" @close="dialogClose">
-    <div class="exercise-link">sdfsf</div>
+  <el-dialog
+    :visible="visible"
+    title="练习题链接"
+    :width="shareData.type === 1 ? '400px' : '600px'"
+    :close-on-click-modal="false"
+    @close="dialogClose"
+  >
+    <div v-if="shareData.type === 2" class="exercise-link" :title="shareData.share_url">
+      <div>{{ $store.state.user.user_real_name }}邀请您完成练习题!</div>
+      <div>链接:{{ shareData.share_url }}</div>
+      <br />
+      <div>复制此链接到浏览器打开</div>
+    </div>
+
+    <div v-if="shareData.type === 1" class="qr-code">
+      <span>{{ $store.state.user.user_real_name }}邀请您完成练习题!</span>
+      <span>请扫描二维码</span>
+      <img :src="QRCodeImg" alt="二维码" />
+    </div>
 
 
     <div slot="footer" class="footer">
     <div slot="footer" class="footer">
       <el-button @click="dialogClose">取消</el-button>
       <el-button @click="dialogClose">取消</el-button>
-      <el-button v-show="linkType === 0" type="primary" @click="copy">复制</el-button>
-      <el-button v-show="linkType === 1" type="primary">下载二维码</el-button>
+      <el-button v-show="shareData.type === 1" type="primary" @click="downloadQRCode">下载二维码</el-button>
+      <el-button v-show="shareData.type === 2" type="primary" @click="writeClipboard">复制</el-button>
     </div>
     </div>
   </el-dialog>
   </el-dialog>
 </template>
 </template>
 
 
 <script>
 <script>
+import { downloadFile } from '@/utils/index';
+
 export default {
 export default {
   name: 'ExerciseLink',
   name: 'ExerciseLink',
   props: {
   props: {
@@ -19,16 +38,42 @@ export default {
       type: Boolean,
       type: Boolean,
       required: true,
       required: true,
     },
     },
-    linkType: {
-      type: Number,
-      required: true,
+    shareData: {
+      type: Object,
+      default: () => ({
+        type: '',
+        image_content_base64: '',
+      }),
     },
     },
   },
   },
   data() {
   data() {
     return {};
     return {};
   },
   },
+  computed: {
+    // 二维码图片地址
+    QRCodeImg() {
+      return `data:image/jpg;base64,${this.shareData.image_content_base64}`;
+    },
+  },
   methods: {
   methods: {
-    copy() {},
+    downloadQRCode() {
+      const byteArray = new Uint8Array(
+        atob(this.shareData.image_content_base64)
+          .split('')
+          .map((char) => char.charCodeAt(0)),
+      );
+
+      // 创建Blob对象
+      const blob = new Blob([byteArray], { type: 'image/jpg' });
+      // 创建URL
+      const imageUrl = URL.createObjectURL(blob);
+      downloadFile(imageUrl, '二维码.jpg');
+    },
+
+    async writeClipboard() {
+      await navigator.clipboard.writeText(this.shareData.share_url);
+      this.$message.success('复制成功');
+    },
 
 
     dialogClose() {
     dialogClose() {
       this.$emit('update:visible', false);
       this.$emit('update:visible', false);
@@ -37,4 +82,60 @@ export default {
 };
 };
 </script>
 </script>
 
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+.el-dialog {
+  :deep &__header {
+    padding: 16px;
+    border-bottom: 1px solid #ebebeb;
+  }
+
+  :deep &__headerbtn &__close {
+    color: #000;
+  }
+
+  :deep &__body {
+    padding: 40px 24px;
+
+    .exercise-link {
+      font-size: 16px;
+      color: #000;
+    }
+
+    .qr-code {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+
+      img {
+        width: 200px;
+        height: 200px;
+      }
+    }
+  }
+
+  :deep &__footer {
+    margin-top: 16px;
+  }
+
+  .footer {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+
+    .el-button {
+      width: 200px;
+      height: 34px;
+      border-radius: 20px;
+
+      + .el-button {
+        margin-left: 16px;
+      }
+
+      &--default {
+        color: $main-color;
+        background-color: #f3f7ff;
+      }
+    }
+  }
+}
+</style>

+ 137 - 67
src/views/home/personal_question/components/ShareDialog.vue

@@ -1,24 +1,28 @@
 <template>
 <template>
-  <el-dialog :visible="dialogVisible" title="分享" width="700px" @close="dialogClose">
+  <el-dialog :visible="dialogVisible" title="分享" width="700px" @close="dialogClose" @closed="dialogClosed">
     <div class="share-condition">
     <div class="share-condition">
       <div class="condition-top">
       <div class="condition-top">
         <span>开始日期</span>
         <span>开始日期</span>
         <el-date-picker v-model="begin_date" type="date" placeholder="选择日期" style="width: 100%" />
         <el-date-picker v-model="begin_date" type="date" placeholder="选择日期" style="width: 100%" />
         <span>有效期</span>
         <span>有效期</span>
-        <el-input v-model="period_validity" placeholder="请输入有效期" />
+        <el-input v-model.number="effective_days" placeholder="请输入有效期">
+          <span slot="suffix">天</span>
+        </el-input>
         <span>作答限时</span>
         <span>作答限时</span>
-        <el-input v-model="answer_limit" placeholder="请输入作答限时" />
+        <el-input v-model.number="answer_time_limit_minute" placeholder="请输入作答限时">
+          <span slot="suffix">分钟</span>
+        </el-input>
       </div>
       </div>
 
 
       <div
       <div
         class="condition-bottom"
         class="condition-bottom"
-        :style="{ 'grid-template': `30px 32px / repeat(auto-fill, ${send_mode === sendModes[0].type ? 272 : 300}px` }"
+        :style="{ 'grid-template': `30px 32px / repeat(auto-fill, ${send_type === sendModes[0].type ? 272 : 300}px` }"
       >
       >
         <span>发送方式</span>
         <span>发送方式</span>
-        <el-radio-group v-model="send_mode">
+        <el-radio-group v-model="send_type">
           <el-radio v-for="{ type, name } in sendModes" :key="type" :label="type">{{ name }}</el-radio>
           <el-radio v-for="{ type, name } in sendModes" :key="type" :label="type">{{ name }}</el-radio>
         </el-radio-group>
         </el-radio-group>
-        <template v-if="send_mode === sendModes[0].type">
+        <template v-if="send_type === sendModes[0].type">
           <span>作答模式</span>
           <span>作答模式</span>
           <el-radio-group v-model="answer_mode">
           <el-radio-group v-model="answer_mode">
             <el-radio v-for="{ type, name } in answerModes" :key="type" :label="type">
             <el-radio v-for="{ type, name } in answerModes" :key="type" :label="type">
@@ -26,9 +30,9 @@
             </el-radio>
             </el-radio>
           </el-radio-group>
           </el-radio-group>
         </template>
         </template>
-        <template v-if="send_mode === sendModes[1].type">
+        <template v-if="send_type === sendModes[1].type">
           <span>访问权限</span>
           <span>访问权限</span>
-          <el-radio-group v-model="access_permission">
+          <el-radio-group v-model="access_popedom">
             <el-radio v-for="{ type, name } in accessPermissions" :key="type" :label="type">
             <el-radio v-for="{ type, name } in accessPermissions" :key="type" :label="type">
               {{ name }}
               {{ name }}
             </el-radio>
             </el-radio>
@@ -37,30 +41,32 @@
       </div>
       </div>
     </div>
     </div>
 
 
-    <div v-show="send_mode === sendModes[0].type" class="select-course">
+    <div v-show="send_type === sendModes[0].type" class="select-course">
       <div class="title">选择课程</div>
       <div class="title">选择课程</div>
       <div></div>
       <div></div>
     </div>
     </div>
 
 
-    <div v-show="send_mode === sendModes[1].type" class="generate-condition">
+    <div v-show="send_type === sendModes[1].type" class="generate-condition">
       <span>访问人数</span>
       <span>访问人数</span>
-      <el-input v-model="visitors_number" placeholder="请输入访问人数" />
-      <span>可直接输入人数</span>
-      <span :class="{ disabled: access_permission === accessPermissions[0].type }">作答模式</span>
+      <el-input v-model.number="max_person_count" placeholder="不限制">
+        <span slot="suffix">人</span>
+      </el-input>
+      <span class="tips">可直接输入人数</span>
+      <span :class="{ disabled: access_popedom === accessPermissions[0].type }">作答模式</span>
       <el-radio-group
       <el-radio-group
         v-model="answer_mode"
         v-model="answer_mode"
-        :disabled="access_permission === accessPermissions[0].type"
-        :class="{ disabled: access_permission === accessPermissions[0].type }"
+        :disabled="access_popedom === accessPermissions[0].type"
+        :class="{ disabled: access_popedom === accessPermissions[0].type }"
       >
       >
         <el-radio v-for="{ type, name } in answerModes" :key="type" :label="type">{{ name }}</el-radio>
         <el-radio v-for="{ type, name } in answerModes" :key="type" :label="type">{{ name }}</el-radio>
       </el-radio-group>
       </el-radio-group>
     </div>
     </div>
 
 
     <div slot="footer" class="footer">
     <div slot="footer" class="footer">
-      <template v-if="send_mode === sendModes[0].type">
-        <el-button type="primary" @click="dialogClose">发送</el-button>
+      <template v-if="send_type === sendModes[0].type">
+        <el-button type="primary" @click="send">发送</el-button>
       </template>
       </template>
-      <template v-if="send_mode === sendModes[1].type">
+      <template v-if="send_type === sendModes[1].type">
         <el-button @click="generateLink(1)">生成二维码</el-button>
         <el-button @click="generateLink(1)">生成二维码</el-button>
         <el-button type="primary" @click="generateLink(2)">生成链接</el-button>
         <el-button type="primary" @click="generateLink(2)">生成链接</el-button>
       </template>
       </template>
@@ -69,9 +75,15 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { CreateShareRecord } from '@/api/exercise';
+
 export default {
 export default {
   name: 'ShareDialog',
   name: 'ShareDialog',
   props: {
   props: {
+    exerciseId: {
+      type: String,
+      default: '',
+    },
     dialogVisible: {
     dialogVisible: {
       type: Boolean,
       type: Boolean,
       default: false,
       default: false,
@@ -79,7 +91,7 @@ export default {
   },
   },
   data() {
   data() {
     return {
     return {
-      send_mode: 1, // 发送方式
+      send_type: 1, // 发送方式
       sendModes: [
       sendModes: [
         {
         {
           type: 1,
           type: 1,
@@ -95,7 +107,7 @@ export default {
         { type: 1, name: '练习模式' },
         { type: 1, name: '练习模式' },
         { type: 2, name: '考试模式' },
         { type: 2, name: '考试模式' },
       ],
       ],
-      access_permission: 1, // 访问权限
+      access_popedom: 1, // 访问权限
       accessPermissions: [
       accessPermissions: [
         {
         {
           type: 1,
           type: 1,
@@ -106,78 +118,136 @@ export default {
           name: '仅作答',
           name: '仅作答',
         },
         },
       ], // 访问权限
       ], // 访问权限
-      visitors_number: '', // 访问人数
-      begin_date: '',
-      period_validity: 50,
-      answer_limit: 30,
+      max_person_count: '', // 访问人数
+      begin_date: this.getNowDate(),
+      effective_days: 50,
+      answer_time_limit_minute: 30,
     };
     };
   },
   },
   methods: {
   methods: {
+    getNowDate() {
+      const date = new Date();
+      return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
+    },
     generateLink(type) {
     generateLink(type) {
-      this.$emit('generateLink', type);
+      CreateShareRecord({
+        exercise_id: this.exerciseId,
+        begin_date: this.begin_date,
+        effective_days: this.effective_days,
+        answer_time_limit_minute: this.answer_time_limit_minute,
+        send_type: this.send_type,
+        answer_mode: this.answer_mode,
+        access_popedom: this.access_popedom,
+        max_person_count: this.max_person_count,
+      }).then(({ status, ...data }) => {
+        this.$emit('generateLink', { ...data, type });
+      });
     },
     },
+    send() {},
     dialogClose() {
     dialogClose() {
       this.$emit('update:dialogVisible');
       this.$emit('update:dialogVisible');
     },
     },
+    dialogClosed() {
+      this.send_type = 1;
+      this.answer_mode = 1;
+      this.access_popedom = 1;
+      this.max_person_count = '';
+      this.begin_date = this.getNowDate();
+      this.effective_days = 50;
+      this.answer_time_limit_minute = 30;
+    },
   },
   },
 };
 };
 </script>
 </script>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
-.share-condition {
-  .condition-top {
-    display: grid;
-    grid-template: 30px 32px / repeat(auto-fill, 210px);
-    grid-auto-flow: column;
-    column-gap: 16px;
+.el-dialog {
+  :deep &__header {
+    padding: 16px;
+    border-bottom: 1px solid #ebebeb;
   }
   }
 
 
-  .condition-bottom {
-    display: grid;
-    grid-auto-flow: column;
-    padding: 0 16px;
-    margin-top: 36px;
+  :deep &__headerbtn &__close {
+    color: #000;
+  }
 
 
-    .el-radio-group {
-      display: flex;
+  :deep &__body {
+    padding: 40px 24px;
+
+    .share-condition {
+      .condition-top {
+        display: grid;
+        grid-template: 30px 32px / repeat(auto-fill, 210px);
+        grid-auto-flow: column;
+        column-gap: 16px;
+      }
+
+      .condition-bottom {
+        display: grid;
+        grid-auto-flow: column;
+        padding: 0 16px;
+        margin-top: 36px;
+
+        .el-radio-group {
+          display: flex;
+        }
+      }
     }
     }
-  }
-}
 
 
-.select-course {
-  margin-top: 16px;
-}
+    .select-course {
+      margin-top: 16px;
+    }
+
+    .generate-condition {
+      display: grid;
+      grid-template: 30px 32px 30px / repeat(auto-fill, 300px);
+      grid-auto-flow: column;
+      column-gap: 16px;
+      align-items: center;
+      margin-top: 16px;
 
 
-.generate-condition {
-  display: grid;
-  grid-template: 30px 32px 30px / repeat(auto-fill, 300px);
-  grid-auto-flow: column;
-  column-gap: 16px;
-  align-items: center;
-  margin-top: 16px;
+      .tips {
+        color: $text-color;
+      }
+
+      .disabled {
+        opacity: 0.5;
+      }
+    }
 
 
-  .disabled {
-    opacity: 0.5;
+    .el-input {
+      &__suffix-inner {
+        display: flex;
+        align-items: center;
+        height: 100%;
+        margin-right: 5px;
+        color: $font-color;
+      }
+    }
   }
   }
-}
 
 
-.footer {
-  display: flex;
-  align-items: center;
-  justify-content: center;
+  :deep &__footer {
+    margin-top: 16px;
 
 
-  .el-button {
-    width: 200px;
-    height: 34px;
-    border-radius: 20px;
+    .footer {
+      display: flex;
+      align-items: center;
+      justify-content: center;
 
 
-    + .el-button {
-      margin-left: 16px;
-    }
+      .el-button {
+        width: 200px;
+        height: 34px;
+        border-radius: 20px;
+
+        + .el-button {
+          margin-left: 16px;
+        }
 
 
-    &--default {
-      color: $main-color;
-      background-color: #f3f7ff;
+        &--default {
+          color: $main-color;
+          background-color: #f3f7ff;
+        }
+      }
     }
     }
   }
   }
 }
 }

+ 9 - 6
src/views/home/personal_question/index.vue

@@ -57,8 +57,8 @@
     </HomeCommon>
     </HomeCommon>
 
 
     <CreateExercise :dialog-visible.sync="dialogVisible" />
     <CreateExercise :dialog-visible.sync="dialogVisible" />
-    <ShareDialog :dialog-visible.sync="visibleShare" @generateLink="generateLink" />
-    <ExerciseLink :visible.sync="visibleLink" :link-type="linkType" />
+    <ShareDialog :dialog-visible.sync="visibleShare" :exercise-id="exerciseId" @generateLink="generateLink" />
+    <ExerciseLink :visible.sync="visibleLink" :share-data="shareData" />
   </div>
   </div>
 </template>
 </template>
 
 
@@ -98,9 +98,10 @@ export default {
       exercise_list: [],
       exercise_list: [],
       total_count: 0, // 总条数
       total_count: 0, // 总条数
       dialogVisible: false,
       dialogVisible: false,
+      exerciseId: '', // 分享id
       visibleShare: false, // 分享弹窗
       visibleShare: false, // 分享弹窗
       visibleLink: false, // 练习题链接弹窗
       visibleLink: false, // 练习题链接弹窗
-      linkType: 1, // 链接类型
+      shareData: undefined, // 分享数据
     };
     };
   },
   },
   methods: {
   methods: {
@@ -131,14 +132,16 @@ export default {
         })
         })
         .catch(() => {});
         .catch(() => {});
     },
     },
-    share() {
+    share(id) {
+      this.exerciseId = id;
       this.visibleShare = true;
       this.visibleShare = true;
     },
     },
     createExercise() {
     createExercise() {
       this.dialogVisible = true;
       this.dialogVisible = true;
     },
     },
-    generateLink(type) {
-      this.linkType = type;
+    generateLink(data) {
+      this.shareData = data;
+      this.share;
       this.visibleShare = false;
       this.visibleShare = false;
       this.visibleLink = true;
       this.visibleLink = true;
     },
     },