Browse Source

学校端注册

liushengqiang 1 year ago
parent
commit
4239215bd8

+ 9 - 1
src/router/router-root.ts

@@ -37,7 +37,7 @@ export default [
       title: '课件播放'
     }
   },
-  
+
   {
     path: '/payment-result',
     name: 'payment-result',
@@ -103,6 +103,14 @@ export default [
     }
   },
   {
+    path: '/school-register',
+    name: 'school-register',
+    component: () => import('@/views/school-register/index'),
+    meta: {
+      title: '学校登记'
+    }
+  },
+  {
     path: '/:pathMatch(.*)*',
     component: () => import('@/views/404'),
     meta: {

+ 19 - 0
src/views/school-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_schoolAdd = (params: any): Promise<any> => {
+  return request.post('/edu-app/school/add', {
+    data: params
+  });
+};
+/** 发送验证码 */
+export const api_openSendSms = (params: any): Promise<any> => {
+  return request.post('/edu-app/open/sendSms', {
+    data: params,
+    requestType: 'form',
+  });
+};

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


BIN
src/views/school-register/images/icon_close.png


BIN
src/views/school-register/images/icon_p1.png


BIN
src/views/school-register/images/icon_p2.png


BIN
src/views/school-register/images/icon_person.png


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


BIN
src/views/school-register/images/icon_submit.png


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


+ 193 - 0
src/views/school-register/index.module.less

@@ -0,0 +1,193 @@
+.container {
+    min-height: 100vh;
+    background-color: #005CBA;
+    background-image: url('./images/icon_bg.png');
+    background-repeat: no-repeat;
+    background-size: 100%;
+    padding-top: 50Px;
+    .titleIcon{
+        display: block;
+        max-width: 100%;
+        height: 26Px;
+        margin: 8px auto;
+    }
+}
+
+.title {
+    font-size: 30px;
+    font-family: AlimamaShuHeiTi-Bold, AlimamaShuHeiTi;
+    font-weight: bold;
+    color: #021F67;
+    line-height: 36px;
+    padding: 12px 16px;
+    text-align: center;
+}
+
+.tagWrap {
+    display: flex;
+    justify-content: center;
+
+    .tag {
+        font-size: 16px;
+        font-family: Alibaba-PuHuiTi-M, Alibaba-PuHuiTi;
+        font-weight: normal;
+        color: #FFFFFF;
+        line-height: 22px;
+        background: linear-gradient(90deg, #02BAFF 0%, #007AFE 100%);
+        border-radius: 8px;
+        margin: 0 auto;
+        display: flex;
+        align-items: center;
+        padding: 4px 6px;
+
+        span {
+            font-size: 28Px;
+            color: #C5EEFD;
+        }
+    }
+}
+
+.contentWrap {
+    padding-top: 208px;
+    .content {
+        background: rgba(255, 255, 255, 0.5);
+        border-radius: 20Px 20Px 0 0;
+        border: 2px solid #FFFFFF;
+        border-bottom: none;
+        padding: 12px;
+        padding-bottom: 50Px;
+    }
+
+    .icon {
+        display: block;
+        max-width: 100%;
+        height: 26Px;
+        margin: 8px auto;
+    }
+
+    .group {
+        border-radius: 18Px;
+        overflow: hidden;
+        margin-bottom: 12Px;
+
+        :global {
+            .van-field__control {
+                justify-content: flex-end;
+            }
+
+            .van-field__label {
+                font-size: 16Px;
+                color: #666666;
+            }
+
+            .van-field__error-message {
+                text-align: right;
+            }
+        }
+    }
+
+    .radio {
+        padding: 4px 10px;
+        background: #F5F6FA;
+        border: none;
+        font-size: 14Px;
+        line-height: 22px;
+        color: #626264;
+        font-weight: 400;
+        border-radius: 6px;
+        margin: 0 6px;
+    }
+}
+
+.tips {
+    font-size: 13px;
+    font-family: PingFangSC-Regular, PingFang SC;
+    font-weight: 400;
+    color: #F64650;
+    line-height: 18px;
+    background: #FFEBEB;
+    border-radius: 8Px;
+    padding: 8Px;
+}
+
+.submit {
+    margin-top: 18Px;
+    background-color: transparent;
+    height: 50Px;
+    padding: 0;
+    border: none;
+
+    &::before {
+        display: none;
+    }
+}
+
+.submitIcon {
+    display: block;
+    max-width: 100%;
+    max-height: 50Px;
+}
+
+.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;
+        }
+    }
+}

+ 388 - 0
src/views/school-register/index.tsx

@@ -0,0 +1,388 @@
+import { defineComponent, onMounted, reactive } from 'vue';
+import styles from './index.module.less';
+import MHeader from '@/components/m-header';
+import { Area, Button, CellGroup, Field, Form, Popup, showToast } from 'vant';
+import icon_school from './images/icon_school.png';
+import icon_person from './images/icon_person.png';
+import icon_submit from './images/icon_submit.png';
+import icon_logo from './images/logo.png';
+import icon_p1 from './images/icon_p1.png';
+import icon_p2 from './images/icon_p2.png';
+import {
+  api_openSendSms,
+  api_schoolAdd,
+  api_sysAreaQueryAllProvince
+} from './api';
+import { useRoute } from 'vue-router';
+
+export default defineComponent({
+  name: 'SchoolRegister',
+  setup() {
+    const route = useRoute();
+    const formOptions = {
+      /** 性质 */
+      nature: [
+        { label: '公立', value: 'PUBLIC' },
+        { label: '私立', value: 'PRIVATE' }
+      ],
+      types: [
+        { label: '小学', value: 'PRIMARY' },
+        { label: '初中', value: 'JUNIOR' },
+        { label: '小初一体', value: 'PRIMARY_JUNIOR' }
+      ],
+      grades: [
+        { label: '六年制', value: 'SIX_YEAR_SYSTEM' },
+        { label: '五年制', value: 'FIVE_YEAR_SYSTEM' }
+      ],
+      genaral: [
+        { label: '男', value: '1' },
+        { label: '女', value: '0' }
+      ]
+    };
+    const forms = reactive({
+      name: '', // 学校名称
+      regionCode: '', // 所属区域
+      cityCode: '', // 所属城市
+      provinceCode: '', // 所属省份
+      schoolNature: 'PUBLIC' as 'PUBLIC' | 'PRIVATE' | string, // 学校性质
+      schoolType: 'PRIMARY' as 'PRIMARY' | 'JUNIOR' | 'PRIMARY_JUNIOR' | string, // 学校类型
+      gradeYear: 'SIX_YEAR_SYSTEM' as
+        | 'FIVE_YEAR_SYSTEM'
+        | 'SIX_YEAR_SYSTEM'
+        | string, // 学年制
+      emergencyContact: '', // 校长姓名
+      emergencyContactPhone: '', // 校长联系方式
+      educationalAdministrationUsername: '', // 负责人姓名
+      educationalAdministrationPhone: '', // 负责人联系方式
+      genaral: '1', // 性别
+      smsCode: '', // 验证码
+      buyGoods: true, // 是否购买商品
+      tenantId: route.query.id || '' // 机构
+    });
+    const data = reactive({
+      cityName: '', // 所属城市
+      showArea: false,
+      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);
+          console.log('🚀 ~ data.areaList:', data.areaList);
+        }
+      });
+    };
+    onMounted(() => {
+      getAreaList();
+    });
+    /** 发送验证码 */
+    const onSendSms = async () => {
+      try {
+        await api_openSendSms({
+          clientId: 'cooleshow-student',
+          type: 'REGISTER',
+          mobile: forms.educationalAdministrationPhone
+        });
+        onCountDown();
+        showToast('验证码已发送');
+      } catch {
+        data.sendMsg = '重新发送';
+      }
+    };
+    const onCountDown = () => {
+      data.sendMsg = '30s';
+      let count = 30;
+      setInterval(() => {
+        count--;
+        data.sendMsg = `${count}s后重新发送`;
+        if (count <= 0) {
+          data.sendMsg = '重新发送';
+        }
+      }, 1000);
+    };
+    const handleSubmit = async () => {
+      const res = await api_schoolAdd({ ...forms });
+      if (res?.code === 200) {
+        showToast('提交成功');
+        data.success = true;
+      }
+    };
+    return () => (
+      <div class={styles.container}>
+        <img class={styles.titleIcon} src={icon_logo} />
+        <div class={styles.title}>{route.query.name}</div>
+        <div class={styles.tagWrap}>
+          <div class={styles.tag}>
+            <span>·</span> 课堂乐器学校登记 <span>·</span>
+          </div>
+        </div>
+
+        <div class={styles.contentWrap}>
+          <div class={styles.content}>
+            <Form onSubmit={() => handleSubmit()}>
+              <CellGroup class={styles.group}>
+                <img src={icon_school} class={styles.icon} />
+                <Field
+                  border
+                  name="name"
+                  label="学校全称"
+                  rows="1"
+                  autosize
+                  type="textarea"
+                  placeholder="请输入学校全称"
+                  inputAlign="right"
+                  v-model={forms.name}
+                  rules={[{ required: true, message: '请输入学校全称' }]}
+                />
+                <Field
+                  isLink
+                  border
+                  label="所属城市"
+                  placeholder="请选择"
+                  readonly
+                  inputAlign="right"
+                  v-model={data.cityName}
+                  onClick={() => (data.showArea = true)}
+                  rules={[{ required: true, message: '请选择' }]}></Field>
+                <Field center border name="schoolNature" label="办学性质">
+                  {{
+                    input: () => (
+                      <>
+                        {formOptions.nature.map(item => {
+                          return (
+                            <Button
+                              class={styles.radio}
+                              size="small"
+                              color={
+                                item.value === forms.schoolNature
+                                  ? '#198CFE'
+                                  : ''
+                              }
+                              onClick={() => (forms.schoolNature = item.value)}>
+                              {item.label}
+                            </Button>
+                          );
+                        })}
+                      </>
+                    )
+                  }}
+                </Field>
+
+                <Field center border label="学校类型" labelWidth="70px">
+                  {{
+                    input: () => (
+                      <>
+                        {formOptions.types.map(item => {
+                          return (
+                            <Button
+                              class={styles.radio}
+                              size="small"
+                              color={
+                                item.value === forms.schoolType ? '#198CFE' : ''
+                              }
+                              onClick={() => (forms.schoolType = item.value)}>
+                              {item.label}
+                            </Button>
+                          );
+                        })}
+                      </>
+                    )
+                  }}
+                </Field>
+                <Field center border label="学年制">
+                  {{
+                    input: () => (
+                      <>
+                        {formOptions.grades.map(item => {
+                          return (
+                            <Button
+                              class={styles.radio}
+                              size="small"
+                              color={
+                                item.value === forms.gradeYear ? '#198CFE' : ''
+                              }
+                              onClick={() => (forms.gradeYear = item.value)}>
+                              {item.label}
+                            </Button>
+                          );
+                        })}
+                      </>
+                    )
+                  }}
+                </Field>
+              </CellGroup>
+
+              <CellGroup class={styles.group}>
+                <img src={icon_person} class={styles.icon} />
+                <Field
+                  border
+                  name="emergencyContact"
+                  label="校长姓名"
+                  placeholder="请输入校长姓名"
+                  inputAlign="right"
+                  maxlength={6}
+                  v-model={forms.emergencyContact}
+                  rules={[{ required: true, message: '请输入校长姓名' }]}
+                />
+                <Field
+                  border
+                  name="emergencyContactPhone"
+                  label="校长联系方式"
+                  maxlength={11}
+                  placeholder="请输入校长手机号码"
+                  inputAlign="right"
+                  v-model={forms.emergencyContactPhone}
+                  rules={[
+                    { required: true, message: '请输入校长手机号码' },
+                    {
+                      pattern: /^1[3456789]\d{9}$/,
+                      message: '请输入正确的手机号码'
+                    }
+                  ]}
+                />
+                <Field
+                  border
+                  name="educationalAdministrationUsername"
+                  label="负责人姓名"
+                  placeholder="请输入负责人姓名"
+                  inputAlign="right"
+                  maxlength={6}
+                  v-model={forms.educationalAdministrationUsername}
+                  rules={[{ required: true, message: '请输入负责人姓名' }]}
+                />
+                <Field
+                  border
+                  name="educationalAdministrationPhone"
+                  label="负责人联系方式"
+                  labelWidth="40%"
+                  inputAlign="right"
+                  placeholder="请输入负责人手机号码"
+                  maxlength={11}
+                  v-model={forms.educationalAdministrationPhone}
+                  rules={[
+                    { required: true, message: '请输入负责人手机号码' },
+                    {
+                      pattern: /^1[3456789]\d{9}$/,
+                      message: '请输入正确的手机号码'
+                    }
+                  ]}
+                />
+                <Field center border label="性别">
+                  {{
+                    input: () => (
+                      <>
+                        {formOptions.genaral.map(item => {
+                          return (
+                            <Button
+                              class={styles.radio}
+                              size="small"
+                              color={
+                                item.value === forms.genaral ? '#198CFE' : ''
+                              }
+                              onClick={() => (forms.genaral = item.value)}>
+                              {item.label}
+                            </Button>
+                          );
+                        })}
+                      </>
+                    )
+                  }}
+                </Field>
+                <Field
+                  border
+                  center
+                  name="smsCode"
+                  label="验证码"
+                  placeholder="请输入验证码"
+                  v-model={forms.smsCode}
+                  maxlength={6}
+                  rules={[{ required: true, message: '请输入验证码' }]}>
+                  {{
+                    button: () => (
+                      <Button
+                        size="small"
+                        type="primary"
+                        color="#198CFE"
+                        onClick={() => onSendSms()}>
+                        {data.sendMsg}
+                      </Button>
+                    )
+                  }}
+                </Field>
+                <div style={{ padding: '10px 16px' }}>
+                  <div class={styles.tips}>
+                    负责人即为该学校酷乐秀课堂乐器老师端管理员,手机号即为酷乐秀课堂乐器老师端账号,默认密码为:ktyq+手机号后四位
+                  </div>
+                </div>
+              </CellGroup>
+
+              <Button class={styles.submit} round block native-type="submit">
+                <img class={styles.submitIcon} src={icon_submit} />
+              </Button>
+            </Form>
+            <Popup v-model:show={data.showArea} position="bottom">
+              <Area
+                areaList={data.areaList}
+                onCancel={() => (data.showArea = false)}
+                onConfirm={({ selectedOptions }) => {
+                  forms.provinceCode = selectedOptions[0].code;
+                  forms.cityCode = selectedOptions[1].code;
+                  forms.regionCode = selectedOptions[2].code;
+                  data.cityName = selectedOptions
+                    .map((item: any) => item.text)
+                    .join('-');
+                  data.showArea = false;
+                }}
+              />
+            </Popup>
+
+            <Popup
+              class="popup-custom van-scale"
+              transition="van-scale"
+              closeOnClickOverlay={false}
+              v-model:show={data.success}>
+              <div class={styles.successWrap}>
+                <img class={styles.p1} src={icon_p1} />
+                <img class={styles.p2} src={icon_p2} />
+                <div class={styles.btnWrap}>
+                  <div class={styles.btnTitle}>您已成功登记</div>
+                  <div class={styles.btnDes}>欢迎您使用酷乐秀课堂乐器~</div>
+                  <Button class={styles.btn} type="primary" round>
+                    我知道了
+                  </Button>
+                </div>
+              </div>
+            </Popup>
+          </div>
+        </div>
+      </div>
+    );
+  }
+});