瀏覽代碼

基础组件

zq 1 年之前
父節點
當前提交
ae0509400c

+ 3 - 0
src/icons/svg/components/audio.svg

@@ -0,0 +1,3 @@
+<svg width="14" height="12" viewBox="0 0 14 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M13.3337 0V9.33333C13.3337 10.8061 12.1397 12 10.667 12C9.19426 12 8.00033 10.8061 8.00033 9.33333C8.00033 7.8606 9.19426 6.66667 10.667 6.66667C11.1527 6.66667 11.6081 6.79653 12.0003 7.0234V1.33333H6.00033V9.33333C6.00033 10.8061 4.80642 12 3.33366 12C1.8609 12 0.666992 10.8061 0.666992 9.33333C0.666992 7.8606 1.8609 6.66667 3.33366 6.66667C3.81937 6.66667 4.27476 6.79653 4.66699 7.0234V0H13.3337ZM3.33366 10.6667C4.07004 10.6667 4.66699 10.0697 4.66699 9.33333C4.66699 8.59693 4.07004 8 3.33366 8C2.59728 8 2.00033 8.59693 2.00033 9.33333C2.00033 10.0697 2.59728 10.6667 3.33366 10.6667ZM10.667 10.6667C11.4034 10.6667 12.0003 10.0697 12.0003 9.33333C12.0003 8.59693 11.4034 8 10.667 8C9.93059 8 9.33366 8.59693 9.33366 9.33333C9.33366 10.0697 9.93059 10.6667 10.667 10.6667Z" fill="black"/>
+</svg>

+ 3 - 0
src/icons/svg/components/chineseCharacter.svg

@@ -0,0 +1,3 @@
+<svg width="14" height="12" viewBox="0 0 14 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M12.9997 0C13.3679 0 13.6663 0.29848 13.6663 0.666667V11.3333C13.6663 11.7015 13.3679 12 12.9997 12H0.999674C0.631488 12 0.333008 11.7015 0.333008 11.3333V0.666667C0.333008 0.29848 0.631488 0 0.999674 0H12.9997ZM6.33301 6.66667H1.66634V10.6667H6.33301V6.66667ZM12.333 6.66667H7.66634V10.6667H12.333V6.66667ZM6.33301 1.33333H1.66634V5.33333H6.33301V1.33333ZM12.333 1.33333H7.66634V5.33333H12.333V1.33333Z" fill="black"/>
+</svg>

+ 3 - 0
src/icons/svg/components/label.svg

@@ -0,0 +1,3 @@
+<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M7.26979 0.398438L13.8695 1.34124L14.8123 7.9409L8.68399 14.0692C8.42366 14.3295 8.00159 14.3295 7.74119 14.0692L1.14155 7.4695C0.881201 7.20917 0.881201 6.78704 1.14155 6.5267L7.26979 0.398438ZM7.74119 1.81265L2.55577 6.9981L8.21259 12.655L13.3981 7.4695L12.691 2.51976L7.74119 1.81265ZM9.15546 6.0553C8.63473 5.53459 8.63473 4.69037 9.15546 4.16967C9.67613 3.64897 10.5203 3.64897 11.0411 4.16967C11.5617 4.69037 11.5617 5.53459 11.0411 6.0553C10.5203 6.57597 9.67613 6.57597 9.15546 6.0553Z" fill="black"/>
+</svg>

+ 3 - 0
src/icons/svg/components/picture.svg

@@ -0,0 +1,3 @@
+<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M1.33333 5.40033L2.66667 4.067L6.33333 7.73367L8.66667 5.40033L10.6667 7.40033V1.33333H1.33333V5.40033ZM1.33333 7.28593V10.6667H3.40033L5.39053 8.67647L2.66667 5.9526L1.33333 7.28593ZM5.28593 10.6667H10.6667V9.28593L8.66667 7.28593L5.28593 10.6667ZM0.666667 0H11.3333C11.7015 0 12 0.29848 12 0.666667V11.3333C12 11.7015 11.7015 12 11.3333 12H0.666667C0.29848 12 0 11.7015 0 11.3333V0.666667C0 0.29848 0.29848 0 0.666667 0ZM8.33333 4.66667C7.78107 4.66667 7.33333 4.21895 7.33333 3.66667C7.33333 3.11438 7.78107 2.66667 8.33333 2.66667C8.8856 2.66667 9.33333 3.11438 9.33333 3.66667C9.33333 4.21895 8.8856 4.66667 8.33333 4.66667Z" fill="black"/>
+</svg>

+ 3 - 0
src/icons/svg/components/pinyin.svg

@@ -0,0 +1,3 @@
+<svg width="12" height="13" viewBox="0 0 12 13" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M9.956 0.0239334L11.1107 0.6906L10.354 2H12V3.33333H10.6667V6H12V7.33333H10.6667V12H9.33333V7.33333L7.27713 7.3336C7.06093 9.24153 6.2348 10.9291 5.03107 12.1289L3.98907 11.2822C5.00207 10.3231 5.72007 8.93387 5.93387 7.33393L4.66667 7.33333V6L6 5.99933V3.33333H4.66667V2H6.31133L5.556 0.6906L6.71067 0.0239334L7.85133 2H8.814L9.956 0.0239334ZM1.33333 7.202L0 7.55933V6.17867L1.33333 5.82133V3.33333H0V2H1.33333V0H2.66667V2H4V3.33333H2.66667V5.46467L4 5.10733V6.48733L2.66667 6.84467V10.3333C2.66667 11.2538 1.92047 12 1 12H0V10.6667H1C1.16364 10.6667 1.29974 10.5487 1.32796 10.3933L1.33333 10.3333V7.202ZM9.33333 3.33333H7.33333V6H9.33333V3.33333Z" fill="black"/>
+</svg>

+ 3 - 0
src/icons/svg/components/spacing.svg

@@ -0,0 +1,3 @@
+<svg width="14" height="12" viewBox="0 0 14 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M10.333 12V9.33333H3.66634V12H2.33301V8.66667C2.33301 8.29847 2.63149 8 2.99967 8H10.9997C11.3679 8 11.6663 8.29847 11.6663 8.66667V12H10.333ZM3.66634 0V2.66667H10.333V0H11.6663V3.33333C11.6663 3.70152 11.3679 4 10.9997 4H2.99967C2.63149 4 2.33301 3.70152 2.33301 3.33333V0H3.66634ZM0.333008 4L2.99967 6L0.333008 8V4ZM13.6663 4V8L10.9997 6L13.6663 4Z" fill="black"/>
+</svg>

+ 3 - 0
src/icons/svg/components/switch.svg

@@ -0,0 +1,3 @@
+<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M7.00327 13.6693C3.32137 13.6693 0.336594 10.6845 0.336594 7.00258C0.336594 3.3207 3.32137 0.335938 7.00327 0.335938C10.6851 0.335938 13.6699 3.3207 13.6699 7.00258C13.6699 10.6845 10.6851 13.6693 7.00327 13.6693ZM7.00327 5.0026H4.33659V6.33592H10.3366L7.00327 3.0026V5.0026ZM3.66993 7.66925L7.00327 11.0026V9.00258H9.66994V7.66925H3.66993Z" fill="black" fill-opacity="0.16"/>
+</svg>

+ 3 - 0
src/icons/svg/components/video.svg

@@ -0,0 +1,3 @@
+<svg width="14" height="12" viewBox="0 0 14 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M0.333008 0.662267C0.333008 0.296507 0.636548 0 0.994208 0H13.0051C13.3703 0 13.6663 0.296633 13.6663 0.662267V11.3377C13.6663 11.7035 13.3628 12 13.0051 12H0.994208C0.629041 12 0.333008 11.7034 0.333008 11.3377V0.662267ZM1.66634 1.33333V10.6667H12.333V1.33333H1.66634ZM6.08094 3.60973L9.33354 5.77813C9.45607 5.8598 9.48921 6.0254 9.40747 6.14793C9.38794 6.1772 9.36281 6.20233 9.33354 6.22187L6.08094 8.39027C5.95841 8.472 5.79281 8.43887 5.71114 8.31633C5.68194 8.27253 5.66634 8.22107 5.66634 8.1684V3.83161C5.66634 3.68433 5.78574 3.56494 5.93301 3.56494C5.98567 3.56494 6.03714 3.58052 6.08094 3.60973Z" fill="black"/>
+</svg>

+ 1 - 0
src/styles/variables.scss

@@ -17,6 +17,7 @@ $hanzi-writer-color: #de4444;
 $error-color: #f2555a;
 $right-color: #30a47d;
 $right-bc-color: #e8f7f2;
+$label-color: #076aff;
 
 // px
 $header-h: 64px;

+ 42 - 0
src/views/book/courseware/create/components/base/audio/Audio.vue

@@ -0,0 +1,42 @@
+<template>
+  <ModuleBase :type="data.type">
+    <template #content>
+      <span>音频</span>
+      <el-upload>
+        <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
+        <el-button size="small" type="primary">上传</el-button>
+        <el-divider />
+        <div slot="tip" class="el-upload__tip">支持上传mp3、acc、wma,等格式音频文件,单个文件最大100MB,总文件体积不超1G。</div>
+      </el-upload>
+    </template>
+  </ModuleBase>
+</template>
+
+<script>
+import { AudioData } from '@/views/book/courseware/data/audio';
+
+import ModuleMixin from '../../common/ModuleMixin';
+
+export default {
+  name: 'Divider',
+  components: {},
+  mixins: [ModuleMixin],
+  data() {
+    return {
+      data: AudioData,
+    };
+  },
+  computed: {
+    settingStyle() {
+      return {
+        margin: `${this.data.setting.height / 2}px 0`,
+        border: 'none',
+        borderTop: `1px ${this.data.setting.type} #ebebeb`,
+      };
+    },
+  },
+  methods: {},
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 76 - 0
src/views/book/courseware/create/components/base/audio/AudioSetting.vue

@@ -0,0 +1,76 @@
+<template>
+  <div>
+    <el-form :model="setting" :label-position="labelPosition" label-width="72px">
+      <el-form-item label="序号" class="serial-number">
+        <el-input v-model="setting.question_number" />
+        <SvgIcon icon-class="switch" size="14" />
+      </el-form-item>
+      <el-form-item>
+        <el-radio v-for="{ value, label } in questionNumberTypeList" :key="value" :label="value">
+          {{ label }}
+        </el-radio>
+      </el-form-item>
+      <el-form-item label="序号位置">
+        <el-radio v-for="{ value, label } in questionNumberTypeList" :key="value" :label="value">
+          {{ label }}
+        </el-radio>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import ModuleMixin from '../../common/ModuleMixin';
+
+export default {
+  name: 'DividerSetting',
+  mixins: [ModuleMixin],
+  data() {
+    return {
+      labelPosition: 'left',
+      isSet: false, // 父组件是否已设置
+      setting: {
+        height: 100,
+        type: 'solid',
+      },
+    };
+  },
+  watch: {
+    setting: {
+      handler(val) {
+        if (this.isSet) {
+          this.$emit('updateSetting', val);
+        }
+      },
+      deep: true,
+    },
+  },
+  methods: {
+    /**
+     * @description 设置属性
+     * @param {Object} setting 属性
+     */
+    setSetting(setting) {
+      this.isSet = true;
+      this.setting = setting;
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.el-form {
+  .serial-number {
+    :deep .el-form-item__content {
+      display: flex;
+      column-gap: 16px;
+      align-items: center;
+    }
+  }
+
+  .el-input {
+    width: 100px;
+    margin-right: 16px;
+  }
+}
+</style>

+ 10 - 1
src/views/book/courseware/create/components/base/divider/Divider.vue

@@ -1,7 +1,7 @@
 <template>
   <ModuleBase :type="data.type">
     <template #content>
-      <el-divider />
+      <hr :style="settingStyle" />
     </template>
   </ModuleBase>
 </template>
@@ -20,6 +20,15 @@ export default {
       data: DividerData,
     };
   },
+  computed: {
+    settingStyle() {
+      return {
+        margin: `${this.data.setting.height / 2}px 0`,
+        border: 'none',
+        borderTop: `1px ${this.data.setting.type} #ebebeb`,
+      };
+    },
+  },
   methods: {},
 };
 </script>

+ 2 - 2
src/views/book/courseware/create/components/base/divider/DividerSetting.vue

@@ -1,6 +1,6 @@
 <template>
   <div>
-    <el-form :model="setting" :label-position="labelPosition" label-width="80px">
+    <el-form :model="setting" :label-position="labelPosition" label-width="56px">
       <el-form-item label="高度">
         <el-input v-model="setting.height" />
       </el-form-item>
@@ -18,7 +18,7 @@ export default {
   name: 'DividerSetting',
   data() {
     return {
-      labelPosition: 'right',
+      labelPosition: 'left',
       isSet: false, // 父组件是否已设置
       setting: {
         height: 100,

+ 36 - 0
src/views/book/courseware/create/components/base/spacing/Spacing.vue

@@ -0,0 +1,36 @@
+<template>
+  <ModuleBase :type="data.type">
+    <template #content>
+      <div :style="settingStyle"></div>
+    </template>
+  </ModuleBase>
+</template>
+
+<script>
+import { SpacingData } from '@/views/book/courseware/data/spacing';
+
+import ModuleMixin from '../../common/ModuleMixin';
+
+export default {
+  name: 'Spacing',
+  components: {},
+  mixins: [ModuleMixin],
+  data() {
+    return {
+      data: SpacingData,
+    };
+  },
+  computed: {
+    settingStyle() {
+      return {
+        height: `${this.data.setting.height}px`,
+        width: '100%',
+        backgroundColor: '#f0f0f0',
+      };
+    },
+  },
+  methods: {},
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 46 - 0
src/views/book/courseware/create/components/base/spacing/SpacingSetting.vue

@@ -0,0 +1,46 @@
+<template>
+  <div>
+    <el-form :model="setting" :label-position="labelPosition" label-width="56px">
+      <el-form-item label="高度">
+        <el-input v-model="setting.height" />
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'SpacingSetting',
+  data() {
+    return {
+      labelPosition: 'left',
+      isSet: false, // 父组件是否已设置
+      setting: {
+        height: 40,
+      },
+    };
+  },
+  watch: {
+    setting: {
+      handler(val) {
+        if (this.isSet) {
+          this.$emit('updateSetting', val);
+        }
+      },
+      deep: true,
+    },
+  },
+  methods: {
+    /**
+     * @description 设置属性
+     * @param {Object} setting 属性
+     */
+    setSetting(setting) {
+      this.isSet = true;
+      this.setting = setting;
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 39 - 8
src/views/book/courseware/create/components/common/ModuleBase.vue

@@ -2,15 +2,15 @@
   <div class="module">
     <div class="module-top">
       <span class="title">{{ componentNameList[type] }}</span>
-      <div>
-        <span><SvgIcon icon-class="copy" size="14" /></span>
-        <span><SvgIcon icon-class="setup" size="14" /></span>
-        <span><SvgIcon icon-class="delete" size="14" /></span>
-      </div>
-      <div v-if="isShow">
-        <slot name="content"></slot>
+      <div class="module-icon">
+        <span><SvgIcon icon-class="copy" size="10" /></span>
+        <span class="active"><SvgIcon icon-class="setup" size="10" /></span>
+        <span><SvgIcon icon-class="delete" size="10" /></span>
       </div>
     </div>
+    <div class="module-content">
+      <slot name="content"></slot>
+    </div>
   </div>
 </template>
 
@@ -37,11 +37,42 @@ export default {
 <style lang="scss" scoped>
 .module {
   padding: 8px;
-  border: 1px solid #272727;
+  border: 1px solid #5a5a5a;
 
   &-top {
     display: flex;
     justify-content: space-between;
+    margin-bottom: 3px;
+
+    .title {
+      font-size: 12px;
+      color: $label-color;
+    }
+  }
+
+  &-icon {
+    display: flex;
+    column-gap: 8px;
+
+    span {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      width: 16px;
+      height: 16px;
+      cursor: pointer;
+      background-color: #fff;
+      border-radius: 20px;
+
+      &.active {
+        background-color: #c9c9c9;
+      }
+    }
+  }
+
+  &-content {
+    padding: 8px;
+    background-color: #fff;
   }
 }
 </style>

+ 4 - 1
src/views/book/courseware/create/components/common/ModuleMixin.js

@@ -1,9 +1,12 @@
 // 组件混入
 import ModuleBase from './ModuleBase.vue';
+import { questionNumberTypeList } from '@/views/book/courseware/data/common';
 
 const mixin = {
   data() {
-    return {};
+    return {
+      questionNumberTypeList,
+    };
   },
   props: {
     questionId: {

+ 3 - 3
src/views/book/courseware/create/index.vue

@@ -68,7 +68,7 @@ export default {
   &-left {
     display: flex;
     flex-direction: column;
-    width: 200px;
+    width: 180px;
     overflow: auto;
     background-color: #fff;
 
@@ -130,13 +130,13 @@ export default {
       width: 100%;
       min-height: 100%;
       padding: 24px;
-      background-color: #fff;
+      background-color: #f6f6f6;
       border-radius: 4px;
     }
   }
 
   &-right {
-    width: 200px;
+    width: 280px;
     padding: 16px 8px;
     background-color: #fff;
 

+ 8 - 0
src/views/book/courseware/data/audio.js

@@ -0,0 +1,8 @@
+export let AudioData = {
+  type: 'audio',
+  title: '音频',
+  setting: {
+    serialNumber: 1,
+    height: 40,
+  },
+};

+ 46 - 0
src/views/book/courseware/data/bookType.js

@@ -1,5 +1,9 @@
 import DividerPage from '../create/components/base/divider/Divider.vue';
 import DividerSetting from '../create/components/base/divider/DividerSetting.vue';
+import SpacingPage from '../create/components/base/spacing/Spacing.vue';
+import SpacingSetting from '../create/components/base/spacing/SpacingSetting.vue';
+import AudioPage from '../create/components/base/audio/Audio.vue';
+import AudioSetting from '../create/components/base/audio/AudioSetting.vue';
 
 export const bookTypeOption = [
   {
@@ -15,12 +19,54 @@ export const bookTypeOption = [
         set: '',
       },
       {
+        value: 'describe',
+        label: '描述',
+        icon: 'describe',
+        component: '',
+        set: '',
+      },
+      {
+        value: 'label',
+        label: '标签',
+        icon: 'label',
+        component: '',
+        set: '',
+      },
+      {
+        value: 'audio',
+        label: '音频',
+        icon: 'audio',
+        component: AudioPage,
+        set: AudioSetting,
+      },
+      {
+        value: 'video',
+        label: '视频',
+        icon: 'video',
+        component: '',
+        set: '',
+      },
+      {
+        value: 'picture',
+        label: '图片',
+        icon: 'picture',
+        component: '',
+        set: '',
+      },
+      {
         value: 'divider',
         label: '分割线',
         icon: 'divider',
         component: DividerPage,
         set: DividerSetting,
       },
+      {
+        value: 'spacing',
+        label: '间距',
+        icon: 'spacing',
+        component: SpacingPage,
+        set: SpacingSetting,
+      },
     ],
   },
   {

+ 5 - 0
src/views/book/courseware/data/common.js

@@ -0,0 +1,5 @@
+// 题号类型
+export const questionNumberTypeList = [
+  { value: 'recalculate', label: '重新计算' },
+  { value: 'follow', label: '跟随上题' },
+];

+ 2 - 2
src/views/book/courseware/data/divider.js

@@ -2,7 +2,7 @@ export let DividerData = {
   type: 'divider',
   title: '分割线',
   setting: {
-    height: 100,
-    type: 'solid',
+    height: 40,
+    type: 'solid', // dotted 虚线
   },
 };

+ 7 - 0
src/views/book/courseware/data/spacing.js

@@ -0,0 +1,7 @@
+export let SpacingData = {
+  type: 'spacing',
+  title: '间距',
+  setting: {
+    height: 40,
+  },
+};