Browse Source

h5老师注册

liushengqiang 1 năm trước cách đây
mục cha
commit
504ee58e80

+ 0 - 5
src/helpers/request.ts

@@ -69,11 +69,7 @@ request.interceptors.request.use(
 
 request.interceptors.response.use(
   async res => {
-    toast = setTimeout(() => {
-      closeToast();
-    }, 100);
     if (res.status > 299 || res.status < 200) {
-      clearTimeout(toast);
       const msg = '服务器错误,状态码' + res.status;
       showToast(msg);
       throw new Error(msg);
@@ -90,7 +86,6 @@ request.interceptors.response.use(
         }
       }
       if (!(data.code === 403 || data.code === 5000)) {
-        clearTimeout(toast);
         showToast(msg);
       }
       const browserInfo = browser();

+ 8 - 0
src/router/router-root.ts

@@ -111,6 +111,14 @@ export default [
     }
   },
   {
+    path: '/teaher-register',
+    name: 'teaher-register',
+    component: () => import('@/views/teaher-register/index'),
+    meta: {
+      title: '老师注册'
+    }
+  },
+  {
     path: '/:pathMatch(.*)*',
     component: () => import('@/views/404'),
     meta: {

+ 8 - 7
src/views/school-register/index.tsx

@@ -55,9 +55,10 @@ export default defineComponent({
       educationalAdministrationUsername: '', // 负责人姓名
       educationalAdministrationPhone: '', // 负责人联系方式
       genaral: '1', // 性别
-      smsCode: '', // 验证码
+      code: '', // 验证码
       buyGoods: true, // 是否购买商品
-      tenantId: route.query.id || '' // 机构
+      tenantId: route.query.id || '', // 机构
+      sourceForm: 'TEACHER'
     });
     const data = reactive({
       cityName: '', // 所属城市
@@ -318,10 +319,10 @@ export default defineComponent({
                 <Field
                   border
                   center
-                  name="smsCode"
+                  name="code"
                   label="验证码"
                   placeholder="请输入验证码"
-                  v-model={forms.smsCode}
+                  v-model={forms.code}
                   maxlength={6}
                   rules={[{ required: true, message: '请输入验证码' }]}>
                   {{
@@ -352,9 +353,9 @@ export default defineComponent({
                 areaList={data.areaList}
                 onCancel={() => (data.showArea = false)}
                 onConfirm={({ selectedOptions }) => {
-                  forms.provinceCode = selectedOptions[0].code;
-                  forms.cityCode = selectedOptions[1].code;
-                  forms.regionCode = selectedOptions[2].code;
+                  forms.provinceCode = selectedOptions[0].value;
+                  forms.cityCode = selectedOptions[1].value;
+                  forms.regionCode = selectedOptions[2].value;
                   data.cityName = selectedOptions
                     .map((item: any) => item.text)
                     .join('-');

+ 19 - 0
src/views/teaher-register/api.ts

@@ -0,0 +1,19 @@
+import request from '@/helpers/request';
+
+/** 获取省市区 */
+export const api_sysAreaQueryAllProvince = (): Promise<any> => {
+  return request.get('/edu-app/sysArea/queryAllProvince');
+};
+/** 新增老师 */
+export const api_teacherAdd = (params: any): Promise<any> => {
+  return request.post('/edu-app/teacher/add', {
+    data: params
+  });
+};
+/** 发送验证码 */
+export const api_openSendSms = (params: any): Promise<any> => {
+  return request.post('/edu-app/open/sendSms', {
+    data: params,
+    requestType: 'form',
+  });
+};

+ 80 - 0
src/views/teaher-register/component/success/index.module.less

@@ -0,0 +1,80 @@
+.container {
+    width: 100vw;
+    min-height: 100vh;
+    background-color: rgba(96, 166, 241, 1);
+    background-image: url('../../images/icon_bg.png');
+    background-repeat: no-repeat;
+    background-size: 100%;
+    padding-top: 50Px;
+    margin: 0 auto;
+
+    .titleIcon {
+        display: block;
+        max-width: 100%;
+        height: 26Px;
+        margin: 8px auto;
+    }
+}
+
+
+.teacherIcon {
+    position: relative;
+    width: 80vw;
+    margin: 0 auto;
+    padding: 48Px 0 60Px 0;
+
+    &>img {
+        display: block;
+        width: 100%;
+        height: 100%;
+    }
+}
+
+.contentWrap {
+    padding: 16Px;
+
+    .content {
+        background: rgba(255, 255, 255, 0.5);
+        border-radius: 20Px;
+        border: 2px solid #FFFFFF;
+        border-bottom: none;
+        padding: 6Px;
+    }
+
+    .group {
+        border-radius: 14Px;
+        overflow: hidden;
+        padding: 14Px 0 20Px;
+        min-height: 256Px;
+        display: flex;
+        flex-direction: column;
+    }
+    .title{
+        text-align: center;
+        & > img {
+            height: 19Px;
+        }
+    }
+    .url{
+        flex: 1;
+        padding: 30Px 20Px 10Px;
+        font-size: 16Px;
+        color: #777;
+    }
+
+
+}
+
+.submit {
+    padding: 20Px 15Px 0;
+
+    :global {
+        .van-button {
+            background: linear-gradient(135deg, #00B9FF 0%, #007AFF 100%);
+            height: 44Px;
+            color: #fff;
+            padding: 0;
+            border: none;
+        }
+    }
+}

+ 55 - 0
src/views/teaher-register/component/success/index.tsx

@@ -0,0 +1,55 @@
+import { defineComponent } from 'vue';
+import styles from './index.module.less';
+import { Button, CellGroup, Form, showToast } from 'vant';
+import icon_logo from '../../images/logo.png';
+import icon_success from '../../images/icon_success.png';
+import icon_pcTeacher from '../../images/icon_pcTeacher.png';
+import icon_url from '../../images/icon_url.png';
+
+export default defineComponent({
+  name: 'SchoolRegister',
+  setup() {
+    const url = `${location.origin}/classroom`;
+    const copyTo = () => {
+      const input = document.createElement('input');
+      input.value = url;
+      document.body.appendChild(input);
+      input.select();
+      input.setSelectionRange(0, input.value.length);
+      document.execCommand('Copy');
+      document.body.removeChild(input);
+      showToast('复制成功');
+    };
+    return () => (
+      <div class={styles.container}>
+        <img class={styles.titleIcon} src={icon_logo} />
+        <img
+          class={styles.titleIcon}
+          style={{ margin: '36Px auto', height: '68Px' }}
+          src={icon_success}
+        />
+        <div class={styles.teacherIcon}>
+          <img src={icon_pcTeacher} />
+        </div>
+
+        <div class={styles.contentWrap}>
+          <div class={styles.content}>
+            <Form>
+              <CellGroup class={styles.group} border={false}>
+                <div class={styles.title}>
+                  <img src={icon_url} />
+                </div>
+                <div class={styles.url}>{url}</div>
+                <div class={styles.submit}>
+                  <Button block onClick={copyTo}>
+                    复制链接
+                  </Button>
+                </div>
+              </CellGroup>
+            </Form>
+          </div>
+        </div>
+      </div>
+    );
+  }
+});

BIN
src/views/teaher-register/images/icon_arrow.png


BIN
src/views/teaher-register/images/icon_bg.png


BIN
src/views/teaher-register/images/icon_man.png


BIN
src/views/teaher-register/images/icon_pcTeacher.png


BIN
src/views/teaher-register/images/icon_rect.png


BIN
src/views/teaher-register/images/icon_school.png


BIN
src/views/teaher-register/images/icon_success.png


BIN
src/views/teaher-register/images/icon_title.png


BIN
src/views/teaher-register/images/icon_toggle.png


BIN
src/views/teaher-register/images/icon_url.png


BIN
src/views/teaher-register/images/icon_woman.png


BIN
src/views/teaher-register/images/logo.png


+ 234 - 0
src/views/teaher-register/index.module.less

@@ -0,0 +1,234 @@
+.container {
+    max-width: 750Px;
+    min-height: 100vh;
+    background-color: rgba(96,166,241,1);
+    background-image: url('./images/icon_bg.png');
+    background-repeat: no-repeat;
+    background-size: 100%;
+    padding-top: 50Px;
+    margin: 0 auto;
+
+    .titleIcon {
+        display: block;
+        max-width: 100%;
+        height: 26Px;
+        margin: 8px auto;
+    }
+}
+
+.schoolName {
+    font-size: 15px;
+    font-family: PingFangSC-Regular, PingFang SC;
+    font-weight: 400;
+    color: #FFFFFF;
+    line-height: 21px;
+    text-align: center;
+}
+
+
+.teacherIcon {
+    position: relative;
+    width: 265Px;
+    height: 277Px;
+    margin: 0 auto;
+
+    &>img {
+        display: block;
+        width: 100%;
+        height: 100%;
+    }
+}
+
+.toggleBtn {
+    position: absolute;
+    left: 50%;
+    bottom: 0;
+    width: 96Px;
+    height: 34Px;
+    background: url('./images/icon_rect.png') no-repeat center center / 100% 100%;
+    transform: translate(-50%, 0);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 16Px;
+    font-weight: 600;
+    color: #131415;
+
+    &>img {
+        width: 16Px;
+        height: 16Px;
+        margin-left: 8Px;
+    }
+}
+
+.contentWrap {
+    padding: 16Px;
+
+    .content {
+        background: rgba(255, 255, 255, 0.5);
+        border-radius: 20Px;
+        border: 2px solid #FFFFFF;
+        border-bottom: none;
+        padding: 6Px;
+    }
+
+    .group {
+        border-radius: 14Px;
+        overflow: hidden;
+        padding: 14Px 0 20Px;
+
+        :global {
+            .van-field__body {
+                background: #F1F7FC;
+                border-radius: 20Px;
+                height: 40Px;
+                padding: 0 15Px;
+
+            }
+
+            .van-field__control {
+                font-size: 14Px;
+            }
+
+            input::-webkit-input-placeholder {
+                color: #94ACC8;
+            }
+
+            .van-cell {
+                padding: 8Px 15Px;
+            }
+        }
+    }
+
+    .inputCode {
+        :global {
+            .van-field__control {
+                border-right: 1.5Px solid #1677FF;
+                height: 16Px;
+            }
+
+            .van-field__button {
+                height: 100%;
+            }
+            .van-button--disabled{
+                color: #94ACC8;
+            }
+        }
+    }
+
+    .sendBtn {
+        border: none;
+        background-color: transparent;
+        width: 100Px;
+        color: #1677FF;
+        font-size: 14Px;
+        padding: 0;
+        height: 100%;
+        &::before{
+            display: none;
+        }
+    }
+
+}
+
+.tips {
+    font-size: 12Px;
+    font-family: PingFangSC-Regular, PingFang SC;
+    font-weight: 400;
+    color: #FD5160;
+    line-height: 17Px;
+    padding: 6Px 0;
+    text-align: center;
+}
+.xieyiWrap{
+    display: flex;
+    justify-content: center;
+    padding: 6Px 0;
+    :global{
+        .van-checkbox__icon{
+            transform: scale(0.7);
+        }
+    }
+}
+.xieyi{
+    color: #94ACC8;
+    font-size: 12Px;
+}
+
+.submit {
+    padding: 20Px 15Px 0;
+
+    :global {
+        .van-button {
+            background: linear-gradient(135deg, #00B9FF 0%, #007AFF 100%);
+            height: 44Px;
+            color: #fff;
+            padding: 0;
+            border: none;
+        }
+    }
+}
+
+.successWrap {
+    position: relative;
+    max-width: 76vw;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+
+    .p1 {
+        position: absolute;
+        max-width: 94vw;
+        transform: translate(12Px, -84Px);
+    }
+
+    .p2 {
+        max-width: 100%;
+        position: relative;
+        z-index: 1;
+    }
+
+    .btnWrap {
+        position: relative;
+        top: -2Px;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        background-color: #fff;
+        width: 100%;
+        border-radius: 0 0 16Px 16Px;
+        padding: 0 0 20Px 0;
+
+        .btnTitle {
+            font-size: 17Px;
+            font-family: PingFangSC-Semibold, PingFang SC;
+            font-weight: 600;
+            color: #021F67;
+            line-height: 24Px;
+            padding: 15Px 0;
+            text-align: center;
+        }
+
+        .btnDes {
+            font-size: 15Px;
+            font-family: PingFangSC-Regular, PingFang SC;
+            font-weight: 400;
+            color: #777777;
+            line-height: 21Px;
+            text-align: center;
+            padding-bottom: 20Px;
+        }
+
+        .btn {
+            width: 172Px;
+            height: 40Px;
+            font-size: 16Px;
+            font-family: PingFangSC-Semibold, PingFang SC;
+            font-weight: 600;
+            color: #EEF8FE;
+            line-height: 22Px;
+            background: linear-gradient(135deg, #00B9FF 0%, #007AFF 100%);
+            margin: 0 auto;
+        }
+    }
+}

+ 305 - 0
src/views/teaher-register/index.tsx

@@ -0,0 +1,305 @@
+import { defineComponent, onMounted, reactive } from 'vue';
+import styles from './index.module.less';
+import {
+  Area,
+  Button,
+  CellGroup,
+  Checkbox,
+  Field,
+  Form,
+  Popup,
+  showToast
+} from 'vant';
+import icon_title from './images/icon_title.png';
+import icon_school from './images/icon_school.png';
+import icon_logo from './images/logo.png';
+import icon_man from './images/icon_man.png';
+import icon_woman from './images/icon_woman.png';
+import icon_toggle from './images/icon_toggle.png';
+import icon_arrow from './images/icon_arrow.png';
+import {
+  api_openSendSms,
+  api_teacherAdd,
+  api_sysAreaQueryAllProvince
+} from './api';
+import { useRoute } from 'vue-router';
+import { postMessage } from '@/helpers/native-message';
+import Success from './component/success/index';
+
+export default defineComponent({
+  name: 'SchoolRegister',
+  setup() {
+    const route = useRoute();
+    const forms = reactive({
+      regionCode: '', // 所属区域
+      cityCode: '', // 所属城市
+      provinceCode: '', // 所属省份
+      code: '', // 验证码
+      tenantId: route.query.tenantId || '', // 机构
+      phone: null,
+      schoolId: route.query.tenantId || '', // 学校id
+      nickname: null,
+      gender: 1
+    });
+    const data = reactive({
+      schoolName: route.query.schoolName || '',
+      cityName: '', // 所属城市
+      showArea: false,
+      checked: true,
+      success: false,
+      areaList: {} as any,
+      sendMsg: '获取验证码'
+    });
+    const formateArea = (area: any[]) => {
+      const province_list: { [_: string]: string } = {};
+      const city_list: { [_: string]: string } = {};
+      const county_list: { [_: string]: string } = {};
+      area.forEach((item: any) => {
+        province_list[item.code] = item.name;
+      });
+      area.forEach((item: any) => {
+        item.areas?.forEach((city: any) => {
+          city_list[city.code] = city.name;
+        });
+      });
+      area.forEach((item: any) => {
+        item.areas?.forEach((city: any) => {
+          city.areas?.forEach((county: any) => {
+            county_list[county.code] = county.name;
+          });
+        });
+      });
+      return {
+        province_list,
+        city_list,
+        county_list
+      };
+    };
+    const getAreaList = () => {
+      api_sysAreaQueryAllProvince().then(res => {
+        if (res?.code === 200) {
+          data.areaList = formateArea(res.data);
+        }
+      });
+    };
+    onMounted(() => {
+      getAreaList();
+    });
+    /** 发送验证码 */
+    const onSendSms = async () => {
+      if (!forms.phone) {
+        showToast('请输入手机号码');
+        return;
+      }
+      if (!/^1[3456789]\d{9}$/.test(forms.phone)) {
+        showToast('手机号码格式不正确');
+        return;
+      }
+      if (data.sendMsg.includes('s')) return;
+      try {
+        await api_openSendSms({
+          clientId: 'cooleshow-student',
+          type: 'REGISTER',
+          mobile: forms.phone
+        });
+        onCountDown();
+        showToast({
+          message: '验证码发送成功',
+          duration: 2000
+        });
+      } catch {
+        data.sendMsg = '重新发送';
+      }
+    };
+    const onCountDown = () => {
+      data.sendMsg = '30s';
+      let count = 30;
+      let timer = setInterval(() => {
+        count--;
+        data.sendMsg = `${count}s`;
+        if (count <= 0) {
+          data.sendMsg = '重新发送';
+          clearInterval(timer);
+        }
+      }, 1000);
+    };
+    const handleSubmit = async () => {
+      if (!data.checked) {
+        showToast('请勾选注册协议');
+        return;
+      }
+      if (!forms.nickname) {
+        showToast('请输入老师姓名');
+        return;
+      }
+      if (!forms.phone) {
+        showToast('请输入手机号码');
+        return;
+      }
+      if (!/^1[3456789]\d{9}$/.test(forms.phone)) {
+        showToast('手机号码格式不正确');
+        return;
+      }
+      if (!forms.code) {
+        showToast('请输入验证码');
+        return;
+      }
+      if (!forms.provinceCode) {
+        showToast('请选择城市');
+        return;
+      }
+      const res = await api_teacherAdd({ ...forms });
+      if (res?.code === 200) {
+        data.success = true;
+      }
+    };
+    return () => (
+      <div class={styles.container}>
+        <img class={styles.titleIcon} src={icon_logo} />
+        <img
+          class={styles.titleIcon}
+          style={{ margin: '16Px auto', height: '32Px' }}
+          src={icon_title}
+        />
+        <div class={styles.schoolName}>
+          <img
+            style={{
+              width: '16px',
+              height: '16px',
+              marginRight: '8px',
+              verticalAlign: 'middle'
+            }}
+            src={icon_school}
+          />
+          {data.schoolName}
+        </div>
+        <div class={styles.teacherIcon}>
+          <img src={forms.gender === 1 ? icon_man : icon_woman} />
+          <div
+            class={styles.toggleBtn}
+            onClick={() => (forms.gender = forms.gender === 1 ? 0 : 1)}>
+            <span>{forms.gender === 1 ? '男老师' : '女老师'}</span>
+            <img src={icon_toggle} />
+          </div>
+        </div>
+
+        <div class={styles.contentWrap}>
+          <div class={styles.content}>
+            <Form onSubmit={() => handleSubmit()}>
+              <CellGroup class={styles.group} border={false}>
+                <Field
+                  border={false}
+                  labelWidth="0"
+                  placeholder="请输入老师姓名"
+                  maxlength={20}
+                  v-model={forms.nickname}
+                />
+                <Field
+                  border={false}
+                  labelWidth="0"
+                  maxlength={11}
+                  placeholder="请输入手机号码"
+                  v-model={forms.phone}
+                />
+                <div class={styles.tips}>
+                  该手机号码即为酷乐秀课堂乐器老师端登录账号
+                </div>
+                <Field
+                  class={styles.inputCode}
+                  border={false}
+                  labelWidth={0}
+                  placeholder="请输入验证码"
+                  v-model={forms.code}
+                  maxlength={6}>
+                  {{
+                    button: () => (
+                      <Button
+                        disabled={data.sendMsg.includes('s')}
+                        class={styles.sendBtn}
+                        onClick={() => onSendSms()}>
+                        {data.sendMsg}
+                      </Button>
+                    )
+                  }}
+                </Field>
+                <Field
+                  border={false}
+                  labelWidth={0}
+                  placeholder="请选择城市"
+                  readonly
+                  v-model={data.cityName}
+                  onClick={() => (data.showArea = true)}>
+                  {{
+                    button: () => (
+                      <img
+                        style={{
+                          display: 'block',
+                          width: '8px',
+                          height: '6px',
+                          marginRight: '10px'
+                        }}
+                        src={icon_arrow}
+                      />
+                    )
+                  }}
+                </Field>
+                <div class={styles.xieyiWrap}>
+                  <Checkbox v-model={data.checked}>
+                    <div class={styles.xieyi}>
+                      <span>我已阅读并同意</span>
+                      <span
+                        style={{ color: '#1677FF' }}
+                        onClick={(e: Event) => {
+                          e.stopPropagation();
+                          postMessage({
+                            api: 'openWebView',
+                            content: {
+                              url: `${location.origin}${location.pathname}#/preview-protocol`,
+                              orientation: 1,
+                              isHideTitle: false
+                            }
+                          });
+                        }}>
+                        《酷乐秀课堂乐器学生端》
+                      </span>
+                      <span>注册协议</span>
+                    </div>
+                  </Checkbox>
+                </div>
+                <div class={styles.submit}>
+                  <Button block native-type="submit">
+                    注册
+                  </Button>
+                </div>
+              </CellGroup>
+            </Form>
+            <Popup v-model:show={data.showArea} position="bottom">
+              <Area
+                areaList={data.areaList}
+                onCancel={() => (data.showArea = false)}
+                onConfirm={({ selectedOptions }) => {
+                  forms.provinceCode = selectedOptions[0].value;
+                  forms.cityCode = selectedOptions[1].value;
+                  forms.regionCode = selectedOptions[2].value;
+                  data.cityName = selectedOptions
+                    .map((item: any) => item.text)
+                    .join('-');
+                  data.showArea = false;
+                }}
+              />
+            </Popup>
+
+            <Popup
+              style={{ margin: 0 }}
+              class="popup-custom van-scale"
+              transition="van-scale"
+              closeOnClickOverlay={false}
+              v-model:show={data.success}>
+              <Success />
+            </Popup>
+          </div>
+        </div>
+      </div>
+    );
+  }
+});