lex-xin vor 2 Jahren
Ursprung
Commit
05125e4b84

BIN
src/common/images/icon_uploader_video.png


+ 3 - 6
src/components/col-field/index.module.less

@@ -1,12 +1,6 @@
 .formTitle {
   font-size: 16px;
   color: #000;
-  // line-height: 24px;
-  // &::before {
-  //   content: '*';
-  //   color: #FF4E19;
-  //   font-size: 17px;
-  // }
   display: flex;
   align-items: center;
   justify-content: space-between;
@@ -16,6 +10,9 @@
     :global {
       .van-icon {
         margin-right: 5px;
+        & > img {
+          vertical-align: middle;
+        }
       }
     }
     .required {

+ 65 - 0
src/components/col-upload-video/index.module.less

@@ -0,0 +1,65 @@
+.uploader-section {
+  margin: 10px 0;
+  height: 145px;
+  border: 1px dashed #ccc;
+  border-radius: 10px;
+  box-sizing: border-box;
+  position: relative;
+  .img-close {
+    position: absolute;
+    top: 8px;
+    right: 10px;
+    z-index: 99;
+    font-size: 16px;
+    background-color: #333;
+    color: #fff;
+    width: 22px;
+    height: 22px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    border-radius: 50%;
+  }
+  .col-uploader {
+    width: 100%;
+    height: 100%;
+    align-items: center;
+    display: flex;
+    justify-content: center;
+  }
+  :global {
+    .van-uploader {
+      width: 100%;
+      height: 100%;
+      align-items: center;
+      display: flex;
+      justify-content: center;
+    }
+    .van-uploader__wrapper, .van-uploader__input-wrapper {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      width: inherit;
+      height: inherit;
+    }
+  }
+  .uploader {
+    // width: 300px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    flex-direction: column;
+    .uploaderText {
+      font-size: 14px;
+      color: #999999;
+      margin-top: 8px;
+    }
+  }
+
+  .uploadImg {
+    width: 100%;
+    height: 100%;
+    // border-radius: 10px;
+    overflow: hidden;
+  }
+}

+ 73 - 0
src/components/col-upload-video/index.tsx

@@ -0,0 +1,73 @@
+import request from "@/helpers/request";
+import { Icon, Toast, Uploader, Image } from "vant";
+import { defineComponent } from "vue";
+import styles from "./index.module.less";
+
+import iconUploader from '@common/images/icon_uploader_video.png';
+
+export default defineComponent({
+  name: "ColUploadVideo",
+  props: {
+    modelValue: String,
+    tips: {
+      type: String,
+      default: '点击上传'
+    },
+    size: {
+      type: Number,
+      default: 30
+    },
+    deletable: {
+      type: Boolean,
+      default: true
+    }
+  },
+  methods: {
+    beforeRead(file: any) {
+      const isLt2M = file.size / 1024 / 1024 < this.size
+      console.log(this.size)
+      if (!isLt2M) {
+        Toast(`上传视屏大小不能超过 ${this.size}MB`)
+        return false
+      }
+      return true
+    },
+    beforeDelete(file: any, detail: { index: any; }) {
+      // this.dataModel.splice(detail.index, 1)
+      return true
+    },
+    async afterRead(file: any, detail: any) {
+      try {
+        file.status = 'uploading';
+        file.message = '上传中...';
+        let formData = new FormData();
+        formData.append('file', file.file);
+        let res = await request.post('/api-teacher/uploadFile', {
+          data: formData
+        })
+        this.$emit('update:modelValue', res.data.url);
+      } catch (error) {
+        //
+      }
+    },
+    onClose(e: any) {
+      this.$emit('update:modelValue', null);
+      e.stopPropagation();
+    },
+  },
+  render() {
+    return (
+      <div class={styles['uploader-section']}>
+          {/* @ts-ignore */}
+          <Uploader accept=".mp4" afterRead={this.afterRead} beforeRead={this.beforeRead} beforeDelete={this.beforeDelete}
+            v-slots={{
+              default: () => (this.modelValue ? <Image fit="cover" position="center" class={styles.uploadImg} src={this.modelValue} /> : <div class={styles.uploader}>
+                <Icon name={iconUploader} size="32" />
+                <p class={styles.uploaderText}>{this.tips}</p>
+              </div>)
+            }}
+          />
+      </div>
+    )
+  }
+})

+ 1 - 1
src/components/col-upload/index.module.less

@@ -52,7 +52,7 @@
     .uploaderText {
       font-size: 14px;
       color: #999999;
-      margin-top: 14px;
+      margin-top: 8px;
     }
   }
 

+ 0 - 10
src/teacher/teacher-cert/cert-one.module.less

@@ -1,16 +1,6 @@
 .certOne {
-  margin: 0 14px;
-  border-radius: 10px;
-  overflow: hidden;
-  background-color: #fff;
-  padding: 20px;
-  padding-bottom: 0;
 
   :global {
-    .van-field {
-      padding-left: 0;
-      padding-right: 0;
-    }
     .van-button + .van-button {
       margin-top: 20px;
       color: #000 !important;

+ 7 - 2
src/teacher/teacher-cert/cert-one.tsx

@@ -5,6 +5,7 @@ import { checkIDCard } from "@/helpers/validate";
 import ColField from "@/components/col-field";
 import { teacherState } from "./teacherState";
 import styles from './cert-one.module.less';
+import ColFieldGroup from "@/components/col-field-group";
 
 export default defineComponent({
   name: 'certOne',
@@ -18,6 +19,10 @@ export default defineComponent({
   methods: {
     onIdCardValidate() {
       const idCardNo = teacherState.teacherCert.idCardNo
+      // 判断是否有身份证号
+      if(!idCardNo) {
+        return
+      }
       if (!checkIDCard(idCardNo || '')) {
         Toast('请填写正确的身份证号码');
         return false;
@@ -68,7 +73,7 @@ export default defineComponent({
   },
   render() {
     return (
-      <div class={styles.certOne}>
+      <ColFieldGroup class={styles.certOne}>
         <CellGroup border={false}>
           <ColField title="真实姓名" required>
             <Field
@@ -116,7 +121,7 @@ export default defineComponent({
             formatter={this.formatter}>
           </DatetimePicker>
         </Popup>
-      </div>
+      </ColFieldGroup>
     )
   }
 })

+ 0 - 6
src/teacher/teacher-cert/cert-three.module.less

@@ -1,10 +1,4 @@
 .items {
-  margin: 0 14px 12px;
-  border-radius: 10px;
-  overflow: hidden;
-  background-color: #fff;
-  padding: 12px;
-  padding-bottom: 0;
   :global {
     .van-field {
       padding-left: 0;

+ 9 - 8
src/teacher/teacher-cert/cert-three.tsx

@@ -1,4 +1,5 @@
 import ColField from "@/components/col-field";
+import ColFieldGroup from "@/components/col-field-group";
 import ColUpload from "@/components/col-upload";
 import { Field } from "vant";
 import { defineComponent } from "vue";
@@ -10,7 +11,7 @@ export default defineComponent({
   render() {
     return (
       <div class="cert-three">
-        <div class={styles.items}>
+        <ColFieldGroup class={styles.items}>
           <ColField title="毕业院校">
             <Field
               v-model={teacherState.teacherCert.graduateSchool}
@@ -26,25 +27,25 @@ export default defineComponent({
               placeholder="请输入您的专业"
             />
           </ColField>
-        </div>
+        </ColFieldGroup>
 
-        <div class={styles.items}>
+        <ColFieldGroup class={styles.items}>
           <ColField title="毕业证书">
             <ColUpload v-model={teacherState.teacherCert.gradCertificate} tips="点击上传学历证书" />
           </ColField>
-        </div>
+        </ColFieldGroup>
 
-        <div class={styles.items}>
+        <ColFieldGroup class={styles.items}>
           <ColField title="学位证书">
             <ColUpload v-model={teacherState.teacherCert.degreeCertificate} tips="点击上传学位证书" />
           </ColField>
-        </div>
+        </ColFieldGroup>
 
-        <div class={styles.items}>
+        <ColFieldGroup class={styles.items}>
           <ColField title="教师资格证">
             <ColUpload v-model={teacherState.teacherCert.teacherCertificate} tips="点击上传教师资格证" />
           </ColField>
-        </div>
+        </ColFieldGroup>
       </div>
     )
   }

+ 0 - 10
src/teacher/teacher-cert/cert-two.module.less

@@ -1,19 +1,9 @@
 .items {
-  margin: 0 14px 12px;
-  border-radius: 10px;
-  overflow: hidden;
-  background-color: #fff;
-  padding: 12px;
-  padding-bottom: 0;
   .select {
     padding: 0 12px;
     height: 24px;
   }
   :global {
-    .van-field {
-      padding-left: 0;
-      padding-right: 0;
-    }
     .van-tag {
       margin-right: 6px;
       margin-bottom: 6px;

+ 5 - 4
src/teacher/teacher-cert/cert-two.tsx

@@ -9,6 +9,7 @@ import icon1 from './images/icon_1.png';
 import icon2 from './images/icon_2.png';
 import ColPopup from "@/components/col-popup";
 import request from "@/helpers/request";
+import ColFieldGroup from "@/components/col-field-group";
 
 export default defineComponent({
   name: 'cert-two',
@@ -60,7 +61,7 @@ export default defineComponent({
   render() {
     return (
       <div>
-        <div class={styles.items}>
+        <ColFieldGroup class={styles.items}>
           <ColField title="可教授乐器(可多选)" border={false} required v-slots={{
             icon: () => <Icon name={icon1} size="24" />,
             right: () => <Button class={styles.select} round type="primary" size="small" onClick={this.onSubjectOpen}>选择</Button>
@@ -71,9 +72,9 @@ export default defineComponent({
               ))}
             </div> : null}
           </ColField>
-        </div>
+        </ColFieldGroup>
 
-        <div class={styles.items}>
+        <ColFieldGroup class={styles.items}>
           <ColField title="个人简介" border={false} v-slots={{
             icon: () => <Icon name={icon2} size="24" />,
             right: () => <div class={styles.limit}>{teacherState.teacherCert.introduction.length}/200</div>
@@ -86,7 +87,7 @@ export default defineComponent({
               placeholder="例:毕业于中国音乐学院长笛专业,曾获得中国青年管乐演奏大赛一等奖,具有8年教学经验,能够将专业知识通过简单易懂的方式教授给学员。"
             />
           </ColField>
-        </div>
+        </ColFieldGroup>
 
         <ColPopup v-model:popupStatus={this.subjectStatus}>
           <SubjectModel subjectList={this.subjectList} choiceSubjectIds={this.choiceSubjectIds} onChoice={this.onChoice} />

+ 32 - 0
src/teacher/video-class/class-content.module.less

@@ -1,6 +1,38 @@
 .class-content {
   margin-top: 12px;
 
+  .upload {
+    width: 150px;
+    height: 100px;
+    border-radius: 10px;
+    overflow: hidden;
+    margin: 0 0 12px;
+  }
+
+  .disabled {
+    opacity: 0.6;
+  }
+  .titleSection {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 12px 14px;
+  }
+  .title {
+    color: #333;
+    font-size: 16px;
+    &::before {
+      content: ' ';
+      display: inline-block;
+      width: 3px;
+      height: 16px;
+      background: #2DC7AA;
+      border-radius: 3px;
+      margin-right: 8px;
+      vertical-align: text-bottom;
+    }
+  }
+
   .add-item {
     margin: 0 14px 12px;
     width: calc(100% - 28px);

+ 59 - 26
src/teacher/video-class/class-content.tsx

@@ -1,40 +1,73 @@
 import ColField from "@/components/col-field";
 import ColFieldGroup from "@/components/col-field-group";
-import { Button, Field, Icon } from "vant";
+import ColUpload from "@/components/col-upload";
+import ColUploadVideo from "@/components/col-upload-video";
+import { Button, Col, Dialog, Field, Icon, Row } from "vant";
 import { defineComponent } from "vue";
 import styles from './class-content.module.less';
 
 export default defineComponent({
   name: "ClassContent",
+  data() {
+    return {
+      dataList: [1, 2]
+    }
+  },
+  methods: {
+    addItem() {
+      this.dataList.push(this.dataList.length + 1)
+    },
+    removeItem(index: number) {
+      // 最少一节课
+      if(this.dataList.length <= 1) return
+      Dialog.confirm({
+        title: '操作',
+        message: `确定删除该条数据吗?`,
+        confirmButtonColor: '#2DC7AA',
+      })
+      .then(() => {
+        // on confirm
+        this.dataList.splice(index, 1)
+      })
+    }
+  },
   render() {
     return (
       <div class={styles['class-content']}>
-        <ColFieldGroup>
-          <ColField title="课程标题" required>
-            <Field
-              name="课程标题"
-              placeholder="请输入您的课程标题"
-            />
-          </ColField>
-          <ColField title="课程内容" required>
-            <Field
-              name="课程内容"
-              placeholder="请输入您的课程内容"
-            />
-          </ColField>
-          <ColField title="课程视频及视频封面" required>
-            <Field
-              name="课程标题"
-              placeholder="请输入您的课程标题"
-            />
-          </ColField>
-        </ColFieldGroup>
+        {this.dataList.map((item: any, index: number) => (
+          <>
+            <div class={styles.titleSection}>
+              <span class={styles.title}>第{ index + 1 }课</span>
+              <Icon name="delete-o" class={this.dataList.length <= 1 ? styles.disabled : null} onClick={() => this.removeItem(index)} size={20} />
+            </div>
+            <ColFieldGroup>
+              <ColField title="课程标题" required>
+                <Field
+                  name="课程标题"
+                  placeholder="请输入您的课程标题"
+                />
+              </ColField>
+              <ColField title="课程内容" required>
+                <Field
+                  name="课程内容"
+                  placeholder="请输入您的课程内容"
+                />
+              </ColField>
+              <ColField title="课程视频及视频封面" required border={false}>
+                <Row justify="space-between" style={{ width: '100%', paddingTop: '12px' }}>
+                  <Col span={12}>
+                    <ColUploadVideo class={styles.upload} tips="点击上传视屏" />
+                  </Col>
+                  <Col span={12}>
+                    <ColUpload class={styles.upload} tips="点击上传视频封面" />
+                  </Col>
+                </Row>
+              </ColField>
+            </ColFieldGroup>
+          </>
+        ))}
 
-        {/* <div class={styles['add-item']}>
-          <Icon name="add-o" size={20} class={styles.add} />
-          <span>添加课程</span>
-        </div> */}
-        <Button class={styles['add-item']} block icon="add-o">添加课程</Button>
+        <Button class={styles['add-item']} block icon="add-o" onClick={this.addItem}>添加课程</Button>
       </div>
     )
   }

+ 3 - 0
src/teacher/video-class/create-submit.module.less

@@ -0,0 +1,3 @@
+.createSubmit {
+  // margin-bottom: 12px;
+}

+ 14 - 0
src/teacher/video-class/create-submit.tsx

@@ -0,0 +1,14 @@
+import { defineComponent } from "vue";
+import styles from "./create-submit.module.less";
+import UserDetail from "@/views/module/user-detail";
+
+export default defineComponent({
+  name: "CreateSubmit",
+  render() {
+    return (
+      <div class={[styles.createSubmit, 'mb12']}>
+        <UserDetail />
+      </div>
+    )
+  }
+})

+ 0 - 1
src/teacher/video-class/create.module.less

@@ -1,5 +1,4 @@
 .video-create {
-  padding-top: 15px;
   .gridName {
     font-size: 14px;
     font-weight: 500;

+ 12 - 3
src/teacher/video-class/create.tsx

@@ -8,18 +8,19 @@ import ClassContent from "./class-content";
 import nameActive from './images/icon_name_active.png'
 import education from './images/icon_education.png'
 import educationActive from './images/icon_education_active.png'
+import CreateSubmit from "./create-submit";
 
 export default defineComponent({
   name: 'Create',
   data() {
     return {
-      active: 2,
+      active: 3,
     }
   },
   render() {
     return (
       <div class={styles['video-create']}>
-        <Grid direction="horizontal" columnNum="2">
+        { this.active <= 2 ? <Grid style={{ paddingTop: '15px' }} direction="horizontal" columnNum="2">
           <GridItem v-slots={{
             default: () => (
               <>
@@ -36,7 +37,7 @@ export default defineComponent({
               </>
             )
           }} />
-        </Grid>
+        </Grid> : null }
         {/* 课程信息 */}
         { this.active === 1 ? <>
           <ClassInfo />
@@ -52,6 +53,14 @@ export default defineComponent({
             <Button block round type="primary">提交</Button>
           </div>
         </> : null }
+        {/* 预览 */}
+        { this.active === 3 ? <>
+          <CreateSubmit />
+          <div class={[styles.btnGroup, styles.btnMore]}>
+            <Button block round type="primary" plain>返回编辑</Button>
+            <Button block round type="primary">创建完成</Button>
+          </div>
+        </> : null }
 
       </div>
     )

+ 7 - 1
src/views/module/user-detail/index.module.less

@@ -1,5 +1,11 @@
+.banner {
+  width: 100%;
+  height: 210px;
+  overflow: hidden;
+  vertical-align: middle;
+}
+
 .userInfo {
-  border-radius: 12px;
   overflow: hidden;
 
   .avatar {

+ 20 - 17
src/views/module/user-detail/index.tsx

@@ -22,23 +22,26 @@ export default defineComponent({
   },
   render() {
     return (
-      <CellGroup class={styles.userInfo}>
-        <Cell v-slots={{
-          icon: () => <Image class={styles.avatar} src="https://daya.ks3-cn-beijing.ksyun.com/202201/SvB6tqR.png" />,
-          title: () => (<div class={styles.name}>张星</div>),
-          value: () => (<div class={styles.info}>开课时间:2月28日 19:30</div>),
-        }}></Cell>
-        <Cell v-slots={{
-          title: () => (<div class={styles.price}>
-            <div class={styles.number}>
-              <span class={styles.priceText}>¥</span>
-              <span class={styles.priceNum}>99</span>
-            </div>
-            <Tag color="#FFF1DE" textColor="#FF9300">12课时</Tag>
-          </div>),
-          value: () => (<div class={styles.info}>已购 6 人</div>),
-        }}></Cell>
-      </CellGroup>
+      <>
+        <Image class={[styles.banner]} src="https://daya.ks3-cn-beijing.ksyun.com/202201/SvB6tqR.png" fit="cover" />
+        <CellGroup class={styles.userInfo}>
+          <Cell v-slots={{
+            icon: () => <Image class={styles.avatar} src="https://daya.ks3-cn-beijing.ksyun.com/202201/SvB6tqR.png" />,
+            title: () => (<div class={styles.name}>张星</div>),
+            value: () => (<div class={styles.info}>开课时间:2月28日 19:30</div>),
+          }}></Cell>
+          <Cell v-slots={{
+            title: () => (<div class={styles.price}>
+              <div class={styles.number}>
+                <span class={styles.priceText}>¥</span>
+                <span class={styles.priceNum}>99</span>
+              </div>
+              <Tag color="#FFF1DE" textColor="#FF9300">12课时</Tag>
+            </div>),
+            value: () => (<div class={styles.info}>已购 6 人</div>),
+          }}></Cell>
+        </CellGroup>
+      </>
     )
   }
 })