Jelajahi Sumber

老师注册

Xiao_123 2 bulan lalu
induk
melakukan
8e3448199d

+ 32 - 0
src/api/school.js

@@ -0,0 +1,32 @@
+import request from '@/config/axios'
+
+// 获取学校基本信息
+export const getSchoolInformation = async () => {
+	return await request.post({
+		url: '/app-api/flames/school/information'
+	})
+}
+
+// 注册学校账号
+export const schoolRegister = async (data) => {
+	return await request.post({
+		url: '/app-api/flames/school/register',
+		data
+	})
+}
+
+// 学校认证信息被拒绝后修改
+export const schoolUpdate = async (data) => {
+	return await request.post({
+		url: '/app-api/flames/school/update',
+		data
+	})
+}
+
+// 根据学校id获取审核拒绝信息
+export const getSchoolAuditById = async (data) => {
+	return await request.post({
+		url: '/app-api/flames/user/auth/record/get',
+		data
+	})
+}

+ 1 - 1
src/components/Upload/img.vue

@@ -13,7 +13,7 @@
   <div v-else class="" style="position: relative;">
     <v-icon color="error" class="close" @click="handleClose">mdi-close-circle</v-icon>
     <v-img :src="src" width="100" height="100" rounded class="imgBox" :class="{'cursor-pointer': showCursor}" @click="emit('imgClick')"></v-img>
-    <div @click="emit('imgClick')" class="color-primary cursor-pointer text-center text-decoration-underline">点击预览</div>
+    <div @click="emit('imgClick', src)" class="color-primary cursor-pointer text-center text-decoration-underline mt-1">点击预览</div>
   </div>
 </template>
 

+ 6 - 6
src/components/VerificationCode/index.vue

@@ -168,12 +168,12 @@ const getSmsCode = async () => {
     phone: loginData.phone,
     scene: props.scene ? props.scene-0 : 30
   }
-  // try {
-  await sendSmsCode(query)
-  Snackbar.success(t('login.sendCode'))
-  // } catch (error) {
-  //   Snackbar.error(error.msg)
-  // }
+  try {
+    await sendSmsCode(query)
+    Snackbar.success(t('login.sendCode'))
+  } catch (error) {
+    Snackbar.error(error.msg)
+  }
 }
 const setTime = () => {
   showCode.value = false

+ 1 - 1
src/layout/personal/navBar.vue

@@ -176,7 +176,7 @@ const navList = ref([
   { title: '门墩儿招聘', path: '/recruit/personal/recommend', dealActive: true },
   { title: '门墩儿猎头', path: '/headhunting' },
   { title: '门墩儿商城', path: '/pointsExchange', isEdit: true },
-  { title: '火苗儿校企' },
+  { title: '火苗儿校企', path: '/flame' },
   { title: '了解门墩儿', path: '/about' }
 ])
 

+ 14 - 0
src/router/modules/recruit.js

@@ -123,6 +123,20 @@ const recruit = [
       }
     ]
   },
+  {
+    path: '/flame',
+    component: Layout,
+    children: [
+      {
+        path: '/flame',
+        component: () => import('@/views/flame/index'),
+        name: 'flame',
+        meta: {
+          title: '火苗儿校企'
+        }
+      }
+    ]
+  },
   {
     path: '/recruit/personal/position',
     component: Layout,

+ 36 - 0
src/router/modules/remaining.js

@@ -14,6 +14,15 @@ const remainingRouter = [
       title: '登录/注册'
     }
   },
+  {
+    path: '/flameLogin',
+    component: () => import('@/views/login/flameLogin'),
+    name: 'flameLogin',
+    meta: {
+      hidden: true,
+      title: '老师登录/注册'
+    }
+  },
   {
     path: '/register/selected',
     component: () => import('@/views/register/select.vue'),
@@ -32,6 +41,33 @@ const remainingRouter = [
       title: '个人用户选择角色'
     }
   },
+  {
+    path: '/register/school',
+    component: () => import('@/views/register/school.vue'),
+    name: 'registerShool',
+    meta: {
+      hidden: true,
+      title: '老师注册'
+    }
+  },
+  {
+    path: '/register/schoolIndex',
+    component: () => import('@/views/register/schoolForm.vue'),
+    name: 'registerShoolForm',
+    meta: {
+      hidden: true,
+      title: '老师注册'
+    }
+  },
+  {
+    path: '/register/school/inReview',
+    component: () => import('@/views/register/schoolInReview.vue'),
+    name: 'registerShoolInReview',
+    meta: {
+      hidden: true,
+      title: '老师注册详情'
+    }
+  },
   {
     path: '/register/person',
     component: () => import('@/views/register/person.vue'),

+ 46 - 6
src/store/user.js

@@ -19,6 +19,8 @@ import { updateEventList } from '@/utils/eventList'
 import { getBaseInfoDictOfName } from '@/utils/getText'
 import { checkPersonBaseInfo } from '@/utils/check'
 import { getStudentInfo } from '@/api/recruit/personal/resume'
+import { getSchoolInformation } from '@/api/school'
+import router from '@/router'
 // import Confirm from '@/plugins/confirm'
 
 // import { useIMStore } from './im'
@@ -38,6 +40,7 @@ export const useUserStore = defineStore('user',
       userAccount: {}, // 用户账户信息
       enterpriseUserAccount: {}, // 企业账户信息
       studentInfo: localStorage.getItem('studentInfo') ? JSON.parse(localStorage.getItem('studentInfo')) : {}, // 学生信息
+      schoolInfo: localStorage.getItem('schoolInfo') ? JSON.parse(localStorage.getItem('schoolInfo')) : {}, // 学校信息
     }),
     actions: {
       // 个人用户注册并登录
@@ -69,6 +72,7 @@ export const useUserStore = defineStore('user',
             updateEventList(true) // 获取规则配置跟踪列表
             await this.getUserInfos()
             await this.getUserBaseInfos('', { chooseRole: data.chooseRole })
+            if (data?.schoolRegister) await this.getSchoolInfo()
             resolve(res)
           }).catch(err => { reject(err) })
         })
@@ -116,11 +120,12 @@ export const useUserStore = defineStore('user',
           data = data || {}
           this.baseInfo = await this.getFieldText(data)
           localStorage.setItem('baseInfo', JSON.stringify(this.baseInfo))
-          localStorage.setItem('necessaryInfoReady', checkPersonBaseInfo(this.baseInfo) ? 'ready' : 'fddeaddc47868b') // 校验是否完善人才必填信息
-          // if (option?.chooseRole && import.meta.env.VITE_NODE_ENV !== 'production') {
+          localStorage.setItem('necessaryInfoReady', !option?.chooseRole || checkPersonBaseInfo(this.baseInfo) ? 'ready' : 'fddeaddc47868b')
+
+          if (option?.chooseRole && import.meta.env.VITE_NODE_ENV !== 'production') {
           //   // 刚注册时让用户选择学生用户还是求职者用户,角色不同填写的基本信息不同。
-          //   localStorage.setItem('chooseRole', 'showChooseRole')
-          // }
+            localStorage.setItem('chooseRole', 'showChooseRole')
+          }
           // 当前角色若为学生则获取学生信息
           if (data?.type && Number(data.type) === 1) this.getStudentInformation()
         } catch (error) {
@@ -218,7 +223,6 @@ export const useUserStore = defineStore('user',
         const data = await getEnterpriseUserAccount()
         if (!data) return
         this.enterpriseUserAccount = data
-        // this.getUserAccountBalance()
         localStorage.setItem('enterpriseUserAccount', JSON.stringify(data))
         return data // 方便直接获取
       },
@@ -243,7 +247,6 @@ export const useUserStore = defineStore('user',
         if (!data) return
         this.userAccount = data
         this.getUserAccountBalance()
-        // localStorage.setItem('userAccount', JSON.stringify(data))
       },
       // 获取账户余额
       async getUserAccountBalance () {
@@ -270,6 +273,43 @@ export const useUserStore = defineStore('user',
         } catch (error) {
           Snackbar.error(error.msg)
         }
+      },
+
+      // 获取学校基本信息
+      async getSchoolInfo () {
+        const data = await getSchoolInformation()
+        console.log(data, '学校基本信息========================')
+        this.schoolInfo = data
+        localStorage.setItem('schoolInfo', data ? JSON.stringify(data) : '{}')
+
+        // 没有注册过,直接跳转到学校注册页面
+        if (!data || !data.school || !Object.keys(data.school).length) {
+          console.log('没有注册过,直接跳转到学校注册页面')
+          router.push({ path: '/register/schoolIndex' })
+        }
+
+        // 审核中,等待审核
+        else if (data.school?.authStatus === '0') {
+          console.log('审核中,等待审核')
+          localStorage.setItem('registerSchoolInfo', JSON.stringify(data))
+          router.push({ path: '/register/school/inReview' })
+        }
+
+        // 审核通过直接进入首页
+        else if (data.school?.authStatus === '1') {
+          localStorage.setItem('schoolInfo', JSON.stringify(data))
+          console.log('审核通过直接进入首页')
+          router.push('/recruitHome') 
+        }
+
+        // 审核不通过,重新填写信息提交
+        else if (data.school?.authStatus === '2') {
+          console.log('审核不通过,重新填写信息提交')
+          localStorage.setItem('registerSchoolInfo', JSON.stringify(data))
+          router.push({ path: '/register/school/inReview' })
+        }
+
+        // return data
       }
     }
   },

+ 16 - 0
src/views/flame/index.vue

@@ -0,0 +1,16 @@
+<template>
+	<div class="pa-5">
+		<v-btn color="primary" to="/flameLogin">老师登录/注册</v-btn>
+	</div>
+</template>
+
+<script setup>
+defineOptions({ name: 'Flame'})
+
+
+const handleToLogin = () => {}
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 235 - 0
src/views/login/flameLogin.vue

@@ -0,0 +1,235 @@
+<template>
+  <div class="box" :style="{'background-image': 'url(' + logoBgUrl + ')'}">
+    <div class="content">
+      <div class="login-content">
+        <v-card height="392px" class="carousel mr-3" style="width: 792px; border-radius: 8px;">
+          <v-carousel show-arrows="hover" cycle :model-value="0">
+            <v-carousel-item v-for="(item, i) in carouselList" :key="i" @click="handleClick(item)">
+              <div style="height: 392px; overflow: hidden;" :class="{'cursor-pointer': item.link}">
+                <v-img :src="item.img" :lazy-src="item.src" cover style="height: 100%; overflow: hidden;">
+                  <template v-slot:placeholder>
+                    <v-row align="center" class="fill-height ma-0" justify="center">
+                      <v-progress-circular color="grey-lighten-5" indeterminate></v-progress-circular>
+                    </v-row>
+                  </template>
+                </v-img>
+              </div>
+            </v-carousel-item>
+          </v-carousel>
+        </v-card>
+        <div class="login-card">
+          <div class="login-tab">
+            <v-tabs v-model="tab" align-tabs="center" color="primary" class="mb-10">
+              <v-tab :value="0">老师手机验证码登录</v-tab>
+            </v-tabs>
+            <phoneFrom ref="phoneRef" openVerify @handleEnter="handleLogin"></phoneFrom>
+          </div>
+          <div class="font-size-14">
+            <span class="float-right color-error cursor-pointer border-bottom-error" @click="router.push('/register/school')">还没有登录账户?去注册</span>
+          </div>
+          <v-btn :loading="loginLoading" color="primary" class="white--text mt-5" min-width="350" @click.stop="handleLogin">
+            {{ $t('login.login') }}
+          </v-btn>
+          <div class="login-tips mt-3">
+              <v-icon v-if="isAgree" size="25" color="primary" class="mr-1" @click="isAgree = !isAgree">mdi-check-circle</v-icon>
+              <v-icon v-else size="25" color="grey" class="mr-1" @click="isAgree = !isAgree">mdi-circle-outline</v-icon>
+              {{ $t('login.agreeLogin') }}
+              <span class="color" style="cursor: pointer;" @click="windowOpen('/userAgreement')"> [{{ $t('login.userAgreement') }}] </span>和
+              <span class="color" style="cursor: pointer;" @click="windowOpen('/privacyPolicy')">[{{ $t('login.privacyPolicy') }}]</span>
+          </div>
+        </div>
+      </div>
+      <div class="aboutBox">
+        <about :showBanner="false"></about>
+      </div>
+    </div>
+    <navBar :showLoginBtn="false" class="navBar"></navBar>
+  </div>
+  <Verify
+    ref="verify"
+    captchaType="blockPuzzle"
+    :imgSize="{ width: '400px', height: '200px' }"
+    mode="pop"
+    @success="verifySuccess"
+  />
+</template>
+
+<script setup>
+defineOptions({ name: 'login-index' })
+import { ref } from 'vue'
+import phoneFrom from '@/components/VerificationCode'
+import { useUserStore } from '@/store/user'
+import { useRouter } from 'vue-router'
+import { useI18n } from '@/hooks/web/useI18n'
+import { getWebContent } from '@/api/common'
+import Snackbar from '@/plugins/snackbar'
+import navBar from '@/layout/personal/navBar.vue'
+import about from '@/views/about/index.vue'
+import Verify from '@/components/Verifition'
+
+// 获取轮播图、背景图
+const logoBgUrl = ref('')
+const preferred = ref({})
+const carouselList = ref([])
+const getSystemWebContent = async () => {
+  const data = await getWebContent()
+  logoBgUrl.value = data.pcLoginBackground && data.pcLoginBackground.length ? data.pcLoginBackground[0].img : 'https://minio.menduner.com/dev/menduner/login-bgc.jpg'
+  carouselList.value = data.pcLoginCarousel || []
+  preferred.value = data.appPreferredGroup || {}
+}
+getSystemWebContent()
+
+const handleClick = (item) => {
+  if (!item.link) return
+  if (item.link.includes('http')) return window.open(item.link)
+
+  // 优选集团
+  if (preferred.value && Object.keys(preferred.value).length > 0 && preferred.value[item.link]) window.open(`/recruit/personal/advertisement/${item.link}`)
+  else window.open(`/recruit/personal/company/details/${item.link}?key=briefIntroduction`)
+}
+
+const { t } = useI18n()
+const router = useRouter()
+const tab = ref(0)
+const isAgree = ref(false)
+
+
+// 验证码登录
+const phoneRef = ref()
+const loginLoading = ref(false)
+const userStore = useUserStore()
+
+
+const handleLogin = async () => {
+  const { valid } = await phoneRef.value.phoneForm.validate()
+  if (!valid) return
+  if (!isAgree.value) return Snackbar.warning('请阅读并勾选底部协议')
+
+  const params = {
+    ...phoneRef.value.loginData,
+    chooseRole: false,
+    schoolRegister: true
+  }
+  
+  loginLoading.value = true
+  try {
+    if (!params.captchaVerification && captchaStr.value) params.captchaVerification = captchaStr.value
+    if (!params.captchaVerification) {
+      getCode() // 验证码组件
+      return
+    }
+
+    await userStore.handleSmsLogin(params)
+    // Snackbar.success(t('login.loginSuccess'))
+  } catch (err) {
+    console.log(err)
+    captchaStr.value = '' // 清空人机验证
+
+    if (!err.code || (err?.message && err.message.includes('timeout'))) return
+
+    // 登录未注册过的账号跳转注册
+    const text = err.code === 1100016002 ? '您的手机号还未注册过' : '您的邮箱还未注册过'
+    Confirm('系统提示',  `${text},去注册?`, {
+      cancelCallback: true
+    }).then(() => {
+      localStorage.setItem('flameLoginAccount', phoneRef.value.loginData.phone)
+      router.push('/register/school')
+    }).catch(() => {})
+  } finally {
+    loginLoading.value = false
+  }
+}
+
+
+// 获取验证码
+const verify = ref()
+const getCode = async () => {
+  // 弹出验证码 // 已开启:则展示验证码;只有完成验证码的情况,才进行登录
+  verify.value.show()
+}
+
+const captchaStr = ref('')
+const verifySuccess = (params) => {
+  captchaStr.value = params.captchaVerification
+  handleLogin()
+}
+
+const windowOpen = (url) => {
+  if (url) window.open(url)
+}
+
+</script>
+
+<style lang="scss" scoped>
+.box {
+  position: relative;
+  width: 100%;
+  height: 100vh;
+  background-size: cover;
+  overflow: hidden;
+  .navBar {
+    position: absolute;
+    top: 0;
+  }
+}
+.content {
+  width: 100%;
+  height: 100%;
+  overflow-y: auto;
+}
+.login-content {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 100%;
+  height: 78vh;
+  // height: calc(100vh - 50px);
+  margin-top: 50px;
+}
+.login-change {
+  position: absolute;
+  top: 0;
+  right: 0;
+  margin: 15px 44px;
+  border-bottom: 1px solid orange;
+  color: orange; 
+  cursor: pointer;
+  font-weight: 400;
+  &:hover {
+    color: #fbb93e; 
+  }
+}
+.login-card {
+  position: relative;
+  width: 450px;
+  background-color: #fff;
+  border-radius: 8px;
+  padding: 36px 50px;
+}
+.left {
+  display: flex;
+}
+.login-tips {
+  width: 100%;
+  font-size: 12px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+.tips:hover {
+  border-bottom: 1px solid #666;
+}
+.color {
+  color: var(--v-primary-base); 
+}
+
+.aboutBox {
+  width: 100%;
+  background-color: #fff;
+}
+.carousel {
+  :deep(.v-window) {
+    height: 392px !important;
+  }
+}
+</style>

+ 0 - 3
src/views/login/index.vue

@@ -173,8 +173,6 @@ const handleLogin = async () => {
   loginLoading.value = true
   try {
     let params, api = {}
-    // if (tab.value === 1) { params = { ...phoneRef.value.loginData }; api = 'handleSmsLogin'}
-    // else { params = { ...passRef.value.loginData }; api = 'handlePasswordLogin'}
     if (isEnterpriseLogin.value) { params = { ...entPassRef.value.loginData }; api = 'handlePasswordLogin'}
     else { params = tab.value === 1 ? { ...phoneRef.value.loginData } : { ...passRef.value.loginData }; api = tab.value === 1 ? 'handleSmsLogin' : 'handlePasswordLogin'}
     if (!params.captchaVerification && captchaStr.value) params.captchaVerification = captchaStr.value
@@ -257,7 +255,6 @@ const verifySuccess = (params) => {
 }
 
 const windowOpen = (url) => {
-  // router.push(url)
   if (url) window.open(url)
 }
 

+ 15 - 4
src/views/register/person.vue

@@ -7,7 +7,7 @@
         <phoneFrom ref="phoneRef" openVerify @handleEnter="handleRegister" :phone="phone"></phoneFrom>
       </div>
       <div v-if="!isMobile" class="font-size-14 text-end">
-        <span class="tips color-primary cursor-pointer" @click="router.push('/login')">已有账号?去登录</span>
+        <span class="tips color-primary cursor-pointer" @click="router.push(isSchool ? '/flameLogin' : '/login')">已有账号?去登录</span>
       </div>
       <v-btn :loading="loading" color="primary" class="white--text mt-5" min-width="370" @click="handleRegister">{{ isCompany ? '下一步' : '注册' }}</v-btn>
       <div class="login-tips mt-3" v-if="!isCompany">
@@ -49,6 +49,10 @@ const props = defineProps({
   isLogin: {
     type: Boolean,
     default: false
+  },
+  isSchool: {
+    type: Boolean,
+    default: false
   }
 })
 
@@ -66,9 +70,16 @@ const handleRegister = async () => {
   if (!props.isCompany && !isAgree.value) return Snackbar.warning('请阅读并勾选底部协议')
   loading.value = true
   try {
-    // isLogin:企业注册申请被驳回后,再次提交时需先登录个人账号
-    // props.isLogin ? await userStore.handleSmsLogin({ ...phoneRef.value.loginData, autoRegister: true }) : await userStore.handleUserRegister({ ...phoneRef.value.loginData })
-    await userStore.handleSmsLogin({ ...phoneRef.value.loginData, autoRegister: true, chooseRole: true }) // 自动注册登录
+    await userStore.handleSmsLogin({ 
+      ...phoneRef.value.loginData,
+      autoRegister: true,
+      chooseRole: props.isSchool ? false : true,
+      schoolRegister: props.isSchool
+    })
+    // autoRegister 自动注册登录
+
+    if (props.isSchool) localStorage.setItem('schoolLoginAccount', JSON.stringify({ phone: phoneRef.value.loginData.phone }))
+
     Snackbar.success(props.isCompany ? '手机号验证成功' : '注册成功')
     if (!props.isCompany) {
       localStorage.setItem('simpleCompleteDialogHaveBeenShow', true) // 个人登录简易基本信息填写弹窗open-status

+ 42 - 0
src/views/register/school.vue

@@ -0,0 +1,42 @@
+<template>
+  <div class="box" style="overflow-x: hidden;" :style="{'background-image': 'url(' + webContent.loginBgUrl + ')'}">
+    <PhonePage :isCompany="true" :isSchool="true" @success="handleValidate"></PhonePage>
+  </div>
+</template>
+
+<script setup>
+defineOptions({ name: 'register-school'})
+import { ref, onMounted } from 'vue'
+import PhonePage from './person.vue'
+import { webContentStore } from '@/store/webContent'
+import { useUserStore } from '@/store/user'
+import { useRouter } from 'vue-router'
+
+const router = useRouter()
+const webContent = webContentStore()
+const userStore = useUserStore()
+const isMobile = ref(false)
+onMounted(async () => {
+  await webContent.getSystemWebContent()
+  const userAgent = navigator.userAgent
+  isMobile.value = /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i.test(userAgent)
+})
+
+// 手机验证码效验通过
+const handleValidate= async () => {
+	// 验证通过,跳转到学校信息填写页面
+	localStorage.setItem('necessaryInfoReady', 'ready')
+	// await userStore.handleSmsLogin()
+}
+</script>
+
+<style scoped lang="scss">
+.box {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  background-size: cover;
+  background-repeat: no-repeat;
+  background-position: center center;
+}
+</style>

+ 291 - 0
src/views/register/schoolForm.vue

@@ -0,0 +1,291 @@
+<template>
+  <div class="box" style="overflow-x: hidden;" :style="{'background-image': 'url(' + webContent.loginBgUrl + ')'}">
+		<navBar :showLoginBtn="false" class="navBar"></navBar>
+		<div class="content pa-5">
+			<div class="mb-10 mt-5" style="font-size: 22px; font-weight: bold; text-align: center;">学校(老师)注册</div>
+			<CtForm class="mt-5" ref="CtFormRef" :items="formItems">
+				<template #department>
+					<div class="pa-5 mb-3" style="width: 100%; border: 1px dashed #ccc; border-radius: 4px;">
+						<p class="color-999 font-size-14 mb-3">
+							<span class="color-error">*</span>
+							负责院系
+						</p>
+						<div v-for="(k, index) in departmentList" :key="index" class="d-flex align-center mb-5">
+							<TextInput v-model="k.departmentTitle" :item="textItem" />
+							<v-icon v-if="index > 0" class="ml-3 cursor-pointer" @click="handleDeleteDepartment(index)" color="error">mdi-close-circle</v-icon>
+						</div>
+						<v-btn class="mt-3" color="primary" prepend-icon="mdi-plus" size="small" @click="handleAddDepartment">添加院系</v-btn>
+					</div>
+				</template>
+				<template #tips>
+					<p class="font-size-14 color-warning mb-3">图片上传提示:支持jpg、jpeg、png格式,图片大小不得超过20M</p>
+				</template>
+				<template #jobImg="{ item }">
+					<div class="d-flex flex-column">
+						<p class="color-999 font-size-14 mb-3">
+							<span class="color-error">*</span>
+							在岗证明图片
+						</p>
+						<Img
+							class="upload-box"
+							tips="上传图片"
+							:value="item.value"
+							:showSnackbar="false"
+							@imgClick="handlePreview"
+							:showCursor="true"
+							@success="url => item.value = url"
+							@delete="item.value = null"
+						/>
+					</div>
+				</template>
+				<template #schoolLegalPersonIdCardImg1="{ item }">
+					<div class="d-flex flex-column">
+						<p class="color-999 font-size-14 mb-3">
+							<span class="color-error">*</span>
+							身份证正面图片
+						</p>
+						<Img
+							class="upload-box"
+							tips="上传图片"
+							:value="item.value"
+							:showSnackbar="false"
+							@imgClick="handlePreview"
+							:showCursor="true"
+							@success="url => item.value = url"
+							@delete="item.value = null"
+						/>
+					</div>
+				</template>
+				<template #schoolLegalPersonIdCardImg2="{ item }">
+					<div class="d-flex flex-column">
+						<p class="color-999 font-size-14 mb-3">
+							<span class="color-error">*</span>
+							身份证背面图片
+						</p>
+						<Img
+							class="upload-box"
+							tips="上传图片"
+							:value="item.value"
+							:showSnackbar="false"
+							@imgClick="handlePreview"
+							:showCursor="true"
+							@success="url => item.value = url"
+							@delete="item.value = null"
+						/>
+					</div>
+				</template>
+			</CtForm>
+			<div class="text-center my-10">
+				<v-btn color="primary" width="250" @click.stop="handleSubmit">提 交</v-btn>
+			</div>
+		</div>
+  </div>
+
+	<PreviewImage v-if="showPreview" :initialIndex="0" :urlList="[previewUrl]" @close="showPreview = !showPreview, previewUrl = ''" />
+</template>
+
+<script setup>
+defineOptions({ name: 'register-schoolForm'})
+import { ref, onMounted } from 'vue'
+import { webContentStore } from '@/store/webContent'
+import { getDict } from '@/hooks/web/useDictionaries'
+import Snackbar from '@/plugins/snackbar'
+import navBar from '@/layout/personal/navBar.vue'
+import { schoolRegister } from '@/api/school'
+import { useRouter } from 'vue-router'
+
+const router = useRouter()
+const webContent = webContentStore()
+
+const previewUrl = ref('')
+const showPreview = ref(false)
+const departmentList = ref([{ departmentTitle: '外语系' }, { departmentTitle: '计算机系' }, { departmentTitle: '经济管理系' }])
+const textItem = {
+	type: 'text',
+  key: 'departmentTitle',
+	width: 450,
+  label: '院系名称 *',
+	hideDetails: true,
+  rules: [v => !!v || '请输入您负责的院系名称']
+}
+
+
+const CtFormRef = ref()
+const formItems = ref({
+  options: [
+    {
+      type: 'text',
+      key: 'teacherNickname',
+      value: '林老师',
+      label: '昵称 *',
+			col: 6,
+      outlined: true,
+      rules: [v => !!v || '请输入您的昵称']
+    },
+    {
+      type: 'ifRadio',
+      key: 'sex',
+      value: '1',
+      label: '性别 *',
+      col: 6,
+			flexStyle: 'ml-5',
+      width: 50,
+      dictTypeName: 'menduner_sex',
+			rules: [v => !!v || '请选择您的性别'],
+      items: []
+    },
+    {
+      type: 'phoneNumber',
+      key: 'phone',
+      value: localStorage.getItem('schoolLoginAccount') ? JSON.parse(localStorage.getItem('schoolLoginAccount')).phone : '',
+      label: '联系电话 *',
+			col: 6,
+      outlined: true,
+      rules: [v => !!v || '请填写您的联系电话']
+    },
+    {
+      type: 'text',
+      key: 'schoolName',
+      value: '测试学校',
+      label: '所在学校 *',
+			col: 6,
+			flexStyle: 'ml-5',
+      outlined: true,
+      rules: [v => !!v || '请填写您所在的学校名称']
+    },
+		{
+      type: 'text',
+      key: 'schoolAdderss',
+      value: '华观路',
+      label: '学校地址',
+      outlined: true
+    },
+    {
+			slotName: 'department',
+      key: 'departmentTitle',
+			noParam: true,
+      label: '负责院系 *',
+      rules: [v => !!v || '请填写您在学校负责的院系']
+    },
+		{
+			slotName: 'tips',
+			noParam: true
+		},
+		{
+			slotName: 'jobImg',
+			key: 'jobImg',
+			value: 'https://menduner.citupro.com:3443/dev/person/1/img/37b12aab617b79d2c0b3d2e851bf941ecbb2882a374364ce1ca1ab4e545997d2.png',
+			col: 4,
+			rules: [v => !!v || '请上传您的在岗证明图片']
+		},
+		{
+			slotName: 'schoolLegalPersonIdCardImg1',
+			key: 'schoolLegalPersonIdCardImg1',
+			value: 'https://menduner.citupro.com:3443/dev/person/1/img/efe58e15ce8479d42389e94f245335910d417b0d6af70887b84b03643659a3af.png',
+			col: 4,
+			rules: [v => !!v || '请上传您的身份证正面图片']
+		},
+		{
+			slotName: 'schoolLegalPersonIdCardImg2',
+			key: 'schoolLegalPersonIdCardImg2',
+			value: 'https://menduner.citupro.com:3443/dev/person/1/img/c1e6d4d93ef29bf62e07eec698b8a44a1cf690aa1f5c0d36065f0f2fb1144956.png',
+			col: 4,
+			rules: [v => !!v || '请上传您的身份证背面图片']
+		}
+  ]
+})
+
+onMounted(async () => {
+  await webContent.getSystemWebContent()
+
+	// 获取性别字典数据
+	const sexItem = formItems.value.options.find(e => e.key === 'sex')
+	if (!sexItem || !Object.keys(sexItem).length) return
+	const { data } = await getDict(sexItem.dictTypeName)
+	sexItem.items = data || []
+})
+
+// 图片预览
+const handlePreview = (url) => {
+	previewUrl.value = url
+	showPreview.value = true
+}
+
+// 添加院系
+const handleAddDepartment = () => {
+	departmentList.value.push({ departmentTitle: '' })
+}
+// 删除院系
+const handleDeleteDepartment = (index) => {
+	departmentList.value.splice(index, 1)
+}
+
+// 提交注册
+const handleSubmit = async () => {
+	const { valid } = await CtFormRef.value.formRef.validate()
+	if (!valid) return
+	const isCheck = departmentList.value.every(item => item.departmentTitle)
+	if (!isCheck) return Snackbar.warning('请将院系信息填写完整')
+
+	let obj = {}
+	formItems.value.options.forEach(item => {
+		if (item.noParam) return
+		obj[item.key] = item.value
+	})
+
+	const params = {
+		school: {
+			schoolName: obj.schoolName,
+      schoolAdderss: obj.schoolAdderss,
+      userId: JSON.parse(localStorage.getItem('userInfo'))?.id,
+      teacherNickname: obj.teacherNickname,
+      teacherSex: obj.teacherSex,
+      phone: obj.phone
+		},
+		schoolQualificaions: {
+			jobImg: obj.jobImg,
+			schoolLegalPersonIdCardImg1: obj.schoolLegalPersonIdCardImg1,
+			schoolLegalPersonIdCardImg2: obj.schoolLegalPersonIdCardImg2,
+		},
+		schoolDepartments: departmentList.value
+	}
+	console.log(params, 'submit-query')
+
+	try {
+		const data = await schoolRegister(params)
+		console.log(data, 'submit-data提交成功,等待系统管理员审核')
+		Snackbar.success('提交成功,等待系统管理员审核!')
+		localStorage.setItem('registerSchoolInfo', JSON.stringify(data))
+		router.push('/register/school/inReview')
+	} catch {}
+}
+</script>
+
+<style scoped lang="scss">
+.navBar {
+  position: absolute;
+  top: 0;
+}
+.box {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  background-size: cover;
+  background-repeat: no-repeat;
+  background-position: center center;
+}
+.content {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  translate: -50% -50%;
+  width: 600px;
+  height: 80%;
+  overflow: auto;
+  background-color: #fff;
+  border-radius: 10px;
+}
+.upload-box {
+	width: 100px;
+}
+</style>

+ 115 - 0
src/views/register/schoolInReview.vue

@@ -0,0 +1,115 @@
+<!-- 注册企业进度 -->
+<template>
+  <div class="my-5">
+    <v-card class="default-width" elevation="3">
+      <div style="margin: 70px auto; width: 600px;">
+        <!-- 提交企业注册以后跳转显示页面 -->
+        <div v-if="applyInfo && applyInfo?.school?.authStatus === '0'" class="d-flex flex-column align-center">
+          <svg-icon name="submit" size="300"></svg-icon>
+          <div><strong class="color-primary font-size-20">已收到您的老师账号注册申请,</strong>审核时间预计在1~3个工作日内,申请结果会以短信方式通知到您的手机上,请注意查收。</div>
+          <div style="width: 100%;">
+            <div class="mt-5 mb-1">如有疑问请扫码添加下方企业微信联系我们:</div>
+            <div style="width: 150px; height: 150px; margin: auto;">
+              <v-img src="https://minio.menduner.com/dev/menduner/contact.png" width="150" height="150"></v-img>
+            </div>
+            <div class="text-center ml-5">潘青海先生(Peter Pan)</div> 
+          </div>
+        </div>
+
+        <!-- 审核不通过 -->
+        <div v-else-if="applyInfo?.school?.authStatus === '2'"> 
+          <div class="mb-3" style="color: red;">
+            您的老师账号注册申请<strong class="color-error font-size-20"> 审核不通过,</strong>
+            具体原因如下:{{ reason }}
+          </div>
+          <div class="mt-5">
+            <span>审核时间:{{ createTime }}</span>
+          </div>
+          <div style="width: 100%;">
+            <div class="mt-5 mb-1">如有疑问请扫码添加下方企业微信联系我们:</div>
+            <div style="width: 150px; height: 150px; margin: auto;">
+              <v-img src="https://minio.menduner.com/dev/menduner/contact.png" width="150" height="150"></v-img>
+            </div>
+            <div class="text-center ml-5">潘青海先生(Peter Pan)</div>
+          </div>
+        </div>
+
+        <div class="text-center">
+          <!-- 应把登录缓存清空 -->
+          <v-btn class="mt-16 mr-3 buttons" color="primary" to="/flame">回到火苗儿校企</v-btn>
+          <v-btn v-if="applyInfo.status === '2'" class="mt-16 buttons" color="primary" @click="handleConfirm">{{ $t('common.resubmit') }}</v-btn>
+        </div>
+      </div>
+    </v-card>
+  </div>
+</template>
+
+<script setup>
+defineOptions({ name: 'register-schoolForm'})
+import { ref, onMounted } from 'vue'
+import { webContentStore } from '@/store/webContent'
+import Snackbar from '@/plugins/snackbar'
+// import navBar from '@/layout/personal/navBar.vue'
+import { useRouter } from 'vue-router'
+import { getSchoolAuditById } from '@/api/school'
+import { timesTampChange } from '@/utils/date'
+
+const applyInfo = ref(localStorage.getItem('registerSchoolInfo') ? JSON.parse(localStorage.getItem('registerSchoolInfo')) : {})
+console.log(applyInfo.value, '注册审核信息')
+
+const reason = ref('')
+const createTime = ref('')
+
+const getRefuseInfo = async () => {
+  try {
+    const data = await getSchoolAuditById({ schoolId: applyInfo.value.school.schoolId })
+    reason.value = data.message
+    createTime.value = data?.createDate ? timesTampChange(data.createDate) : ''
+  } catch {}
+}
+// 获取申请被拒绝的原因
+if (applyInfo.value && applyInfo.value?.school?.authStatus === '2') {
+  getRefuseInfo()
+}
+
+const router = useRouter()
+const webContent = webContentStore()
+
+onMounted(async () => {
+  await webContent.getSystemWebContent()
+})
+
+// 重新提交
+const handleConfirm = async () => {
+
+}
+</script>
+
+<style scoped lang="scss">
+.navBar {
+  position: absolute;
+  top: 0;
+}
+.box {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  background-size: cover;
+  background-repeat: no-repeat;
+  background-position: center center;
+}
+.content {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  translate: -50% -50%;
+  width: 600px;
+  height: 80%;
+  overflow: auto;
+  background-color: #fff;
+  border-radius: 10px;
+}
+.upload-box {
+	width: 100px;
+}
+</style>