u
This commit is contained in:
1 parent
fe15bfd35f
commit
52112bd277
21 files changed
+2781
-939
No files matched your search
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { onMounted } from 'vue'
|
||||
import { getAreaListApi } from './request/api/area'
|
||||
import { getPropertyListApi } from './request/api/peoperty'
|
||||
import { getPropertyListApi } from './request/api/industry'
|
||||
import { useCommonStore } from './store/common'
|
||||
|
||||
const commonOptions = useCommonStore()
|
||||
@@ -11,12 +11,12 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
function handleInitData() {
|
||||
// getAreaListApi().then((res) => {
|
||||
// commonOptions.areaOptions.splice(0, commonOptions.areaOptions.length, ...res.data || [])
|
||||
// })
|
||||
getAreaListApi().then((res) => {
|
||||
commonOptions.areaOptions.splice(0, commonOptions.areaOptions.length, ...res.data || [])
|
||||
})
|
||||
|
||||
getPropertyListApi().then((res) => {
|
||||
commonOptions.propertyOptions.splice(0, commonOptions.propertyOptions.length, ...res.data || [])
|
||||
commonOptions.industryOptions.splice(0, commonOptions.industryOptions.length, ...res.data || [])
|
||||
}).catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue'
|
||||
import type { Area, CompanyQuery, Property } from '@/types/company/index'
|
||||
import type { Area, CompanyQuery, Industry } from '@/types/company/index'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
@@ -8,8 +8,8 @@ const props = defineProps({
|
||||
type: Object as PropType<CompanyQuery>,
|
||||
required: true,
|
||||
},
|
||||
properties: {
|
||||
type: Object as PropType<Property[]>,
|
||||
industries: {
|
||||
type: Object as PropType<Industry[]>,
|
||||
required: false,
|
||||
},
|
||||
areas: {
|
||||
@@ -32,7 +32,7 @@ const query = computed({
|
||||
<div class="query">
|
||||
<div class="query-item">
|
||||
<el-select
|
||||
v-model="query.properties"
|
||||
v-model="query.industries"
|
||||
filterable
|
||||
placeholder="请选择行业"
|
||||
multiple
|
||||
@@ -41,7 +41,7 @@ const query = computed({
|
||||
:max-collapse-tags="2"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in props.properties"
|
||||
v-for="item in props.industries"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import type { IndustryResult } from '@/types/company/index'
|
||||
import { httpGet } from '../utils'
|
||||
|
||||
export function getPropertyListApi() {
|
||||
return httpGet<IndustryResult>(`/webProperty/list`)
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
import type { PropertyResult } from '@/types/company/index'
|
||||
import { httpGet } from '../utils'
|
||||
|
||||
export function getPropertyListApi() {
|
||||
return httpGet<PropertyResult>(`/webProperty/list`)
|
||||
}
|
||||
@@ -24,7 +24,7 @@ const router = createRouter({
|
||||
{
|
||||
path: '/auth/register',
|
||||
name: 'Register',
|
||||
component: () => import('@/views/auth/register.vue'),
|
||||
component: () => import('@/views/auth/register/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/auth/forget',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Area, CompanyQuery, Property } from '@/types/company/index'
|
||||
import type { Area, CompanyQuery, Industry } from '@/types/company/index'
|
||||
import { defineStore } from 'pinia'
|
||||
import { reactive, ref } from 'vue'
|
||||
|
||||
@@ -6,16 +6,16 @@ export const useCommonStore = defineStore(
|
||||
'common',
|
||||
() => {
|
||||
const areaOptions = reactive<Area[]>([])
|
||||
const propertyOptions = reactive<Property[]>([])
|
||||
const industryOptions = reactive<Industry[]>([])
|
||||
const companyQuery = ref<CompanyQuery>({
|
||||
properties: [],
|
||||
industries: [],
|
||||
areas: [],
|
||||
name: '',
|
||||
})
|
||||
|
||||
return {
|
||||
areaOptions,
|
||||
propertyOptions,
|
||||
industryOptions,
|
||||
companyQuery,
|
||||
}
|
||||
},
|
||||
|
||||
@@ -22,6 +22,12 @@ export const useUserStore = defineStore(
|
||||
}
|
||||
|
||||
const clearUserInfo = () => {
|
||||
userInfo.value.id = ""
|
||||
userInfo.value.account = ""
|
||||
userInfo.value.email = ""
|
||||
userInfo.value.name = ""
|
||||
userInfo.value.token = ""
|
||||
userInfo.value.avatar = ""
|
||||
}
|
||||
|
||||
// ✅ 如果需要同时验证多个字段
|
||||
|
||||
@@ -22,3 +22,24 @@ export interface registerApiParams {
|
||||
export interface forgetApiParams {
|
||||
forgetCredential: string
|
||||
}
|
||||
|
||||
export interface RegisterCompanyForm {
|
||||
name: string
|
||||
industry: string
|
||||
address: string
|
||||
phone: string
|
||||
email: string
|
||||
profile: string
|
||||
}
|
||||
|
||||
export interface RegisterAdminForm {
|
||||
name: string
|
||||
phone: string
|
||||
email: string
|
||||
emailCode: string
|
||||
|
||||
password: string
|
||||
confirmPassword: string
|
||||
|
||||
position: string
|
||||
}
|
||||
@@ -13,7 +13,12 @@ declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
HelloWorld: typeof import('./../components/HelloWorld.vue')['default']
|
||||
ICarbonAccessibility: typeof import('~icons/carbon/accessibility')['default']
|
||||
'IFa7Solid:userShield': typeof import('~icons/fa7-solid/user-shield')['default']
|
||||
'IIc:twotoneHeadphones': typeof import('~icons/ic/twotone-headphones')['default']
|
||||
'IMaterialSymbols:lockOpenRightSharp': typeof import('~icons/material-symbols/lock-open-right-sharp')['default']
|
||||
IMdiAccountBox: typeof import('~icons/mdi/account-box')['default']
|
||||
'IRi:buildingFill': typeof import('~icons/ri/building-fill')['default']
|
||||
'IRi:buildingLine': typeof import('~icons/ri/building-line')['default']
|
||||
'ITdesign:notification': typeof import('~icons/tdesign/notification')['default']
|
||||
'ITdesign:search': typeof import('~icons/tdesign/search')['default']
|
||||
QueryCompany: typeof import('./../components/QueryCompany.vue')['default']
|
||||
|
||||
@@ -6,14 +6,14 @@ export interface Area {
|
||||
|
||||
export type AreaResult = Area[]
|
||||
|
||||
export interface Property {
|
||||
export interface Industry {
|
||||
label: string
|
||||
value: string
|
||||
}
|
||||
export type PropertyResult = Property[]
|
||||
export type IndustryResult = Industry[]
|
||||
|
||||
export interface CompanyQuery {
|
||||
properties: string[]
|
||||
industries: string[]
|
||||
areas: string[]
|
||||
name: string
|
||||
}
|
||||
@@ -195,7 +195,6 @@ function onSubmit() {
|
||||
height: 70px;
|
||||
width: 160px;
|
||||
cursor: pointer;
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
|
||||
.main {
|
||||
|
||||
@@ -49,7 +49,8 @@ const form = reactive<{
|
||||
const formRef = ref<FormInstance>()
|
||||
const formRules = {
|
||||
loginCredential: [
|
||||
{ required: true, message: '邮箱 / 账号不能为空', trigger: 'blur' },
|
||||
{ required: true, message: '邮箱号不能为空', trigger: 'blur' },
|
||||
{ type: 'email', required: true, message: '邮箱格式错误', trigger: 'blur' },
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: '密码不能为空', trigger: 'blur' },
|
||||
@@ -130,7 +131,7 @@ function navigateTo(path: string) {
|
||||
登录
|
||||
</h4>
|
||||
<p class="title-extra">
|
||||
输入你的 邮箱/账号 和 密码 登录账户.
|
||||
输入你的 邮箱 和 密码 登录账户.
|
||||
</p>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
@@ -140,8 +141,8 @@ function navigateTo(path: string) {
|
||||
label-position="top"
|
||||
hide-required-asterisk
|
||||
>
|
||||
<el-form-item label="邮箱 / 账号" prop="loginCredential">
|
||||
<el-input v-model="form.loginCredential" placeholder="请输入邮箱 / 账号" size="large" />
|
||||
<el-form-item label="邮箱" prop="loginCredential">
|
||||
<el-input v-model="form.loginCredential" placeholder="请输入邮箱" size="large" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="password">
|
||||
@@ -244,7 +245,6 @@ function navigateTo(path: string) {
|
||||
height: 70px;
|
||||
width: 160px;
|
||||
cursor: pointer;
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
|
||||
.main {
|
||||
|
||||
@@ -1,367 +1,329 @@
|
||||
<script lang="ts" setup>
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { computed, onUnmounted, reactive, ref } from 'vue'
|
||||
import { reactive, ref } from 'vue'
|
||||
|
||||
import { useRouter } from 'vue-router'
|
||||
const activeStep = ref(0)
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const carouselList = [
|
||||
{
|
||||
title: '值得信赖',
|
||||
company: '恒星科技有限公司',
|
||||
content: '我们已经连续三年使用该平台,数据处理稳定高效,团队协作体验非常顺畅。',
|
||||
},
|
||||
{
|
||||
title: '安全 · 高效',
|
||||
company: '博越信息技术',
|
||||
content: '平台的权限管理做得很好,操作简单清晰,极大提升了内部管理效率。',
|
||||
},
|
||||
{
|
||||
title: '稳定可靠',
|
||||
company: '远航供应链集团',
|
||||
content: '系统运行非常稳定,几乎没有出现过宕机情况,客服响应速度也很快。',
|
||||
},
|
||||
{
|
||||
title: '智能化体验',
|
||||
company: '蓝海数据服务中心',
|
||||
content: '智能报表和自动化功能非常实用,减少了大量人工整理数据的时间。',
|
||||
},
|
||||
{
|
||||
title: '灵活易用',
|
||||
company: '中联创投有限公司',
|
||||
content: 'UI设计简洁友好,新员工上手很快,各项业务流程也能灵活配置。',
|
||||
},
|
||||
]
|
||||
|
||||
const form = reactive<{
|
||||
email: string
|
||||
code: string
|
||||
name: string
|
||||
account: string
|
||||
password: string
|
||||
confirmPassword: string
|
||||
}>({
|
||||
email: '',
|
||||
code: '',
|
||||
const companyForm = reactive({
|
||||
name: '',
|
||||
account: '',
|
||||
password: '',
|
||||
confirmPassword: '',
|
||||
industry: '',
|
||||
address: '',
|
||||
})
|
||||
const formRef = ref<FormInstance>()
|
||||
const formRules = {
|
||||
email: [
|
||||
{ required: true, message: '邮箱不能为空', trigger: 'blur' },
|
||||
{ type: 'email', message: '请输入正确的邮箱格式', trigger: ['blur', 'change'] },
|
||||
],
|
||||
code: [
|
||||
{ required: true, message: '验证码不能为空', trigger: 'blur' },
|
||||
],
|
||||
name: [
|
||||
{ required: true, message: '名称不能为空', trigger: 'blur' },
|
||||
{ min: 2, max: 20, message: '名称长度需在 2 到 20 个字符之间', trigger: 'blur' },
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: '密码不能为空', trigger: 'blur' },
|
||||
{ min: 6, max: 20, message: '密码长度需在 6 到 20 个字符之间', trigger: 'blur' },
|
||||
],
|
||||
confirmPassword: [
|
||||
{ required: true, message: '请再次输入密码', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (value !== form.password) {
|
||||
callback(new Error('两次输入的密码不一致'))
|
||||
}
|
||||
else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
],
|
||||
}
|
||||
const submitLoading = ref(false)
|
||||
|
||||
// --- 邮箱校验(简单正则) ---
|
||||
const emailRegex = /^\w+(?:[-.]\w+)*@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*$/
|
||||
const form = reactive({
|
||||
name: '',
|
||||
region: '',
|
||||
date1: '',
|
||||
date2: '',
|
||||
delivery: false,
|
||||
type: [],
|
||||
resource: '',
|
||||
desc: '',
|
||||
})
|
||||
|
||||
const isEmailValid = computed(() => emailRegex.test(form.email.trim()))
|
||||
|
||||
// --- 发送验证码状态 & 倒计时 ---
|
||||
const sending = ref(false)
|
||||
const countdown = ref(0)
|
||||
let timer: number | undefined
|
||||
|
||||
function startCountdown(seconds = 60) {
|
||||
countdown.value = seconds
|
||||
timer = window.setInterval(() => {
|
||||
countdown.value -= 1
|
||||
if (countdown.value <= 0) {
|
||||
clearInterval(timer)
|
||||
timer = undefined
|
||||
sending.value = false
|
||||
}
|
||||
}, 1000)
|
||||
function handleCompanySubmit() {
|
||||
activeStep.value += 1
|
||||
}
|
||||
|
||||
// 清理
|
||||
onUnmounted(() => {
|
||||
if (timer) {
|
||||
clearInterval(timer)
|
||||
timer = undefined
|
||||
function handlePrevStep() {
|
||||
if (activeStep.value > 0) {
|
||||
activeStep.value -= 1
|
||||
}
|
||||
})
|
||||
|
||||
function handleSendEmailCode() {
|
||||
sending.value = true
|
||||
startCountdown()
|
||||
}
|
||||
|
||||
async function submitForm(formEl: FormInstance | undefined) {
|
||||
if (!formEl)
|
||||
return
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
}
|
||||
})
|
||||
}
|
||||
function navigateTo(path: string) {
|
||||
router.push(path)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="auth-wrapper">
|
||||
<div class="auth-bg">
|
||||
<img src="/auth-bg.jpg">
|
||||
<div class="bg-content">
|
||||
<el-carousel
|
||||
height="150px"
|
||||
indicator-position="none"
|
||||
>
|
||||
<el-carousel-item v-for="(item, index) in carouselList" :key="index">
|
||||
<div class="carousel-item">
|
||||
<h2 class="title">
|
||||
{{ item.title }}
|
||||
</h2>
|
||||
<div class="auth-container">
|
||||
<div class="form-container">
|
||||
<div class="logo-area">
|
||||
<img src="/logo.png">
|
||||
</div>
|
||||
<el-steps finish-status="success" :active="activeStep" align-center>
|
||||
<el-step title="公司信息" />
|
||||
<el-step title="管理员信息" />
|
||||
<el-step title="确认信息" />
|
||||
</el-steps>
|
||||
|
||||
<span class="content">{{ item.content }}</span>
|
||||
<div v-if="activeStep === 0" class="section-area">
|
||||
<h2 class="section-title">
|
||||
公司基本信息
|
||||
</h2>
|
||||
|
||||
<span class="company"> - {{ item.company }}</span>
|
||||
</div>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
</div>
|
||||
<div class="login-form">
|
||||
<img src="/logo.png" class="logo" @click="navigateTo('/')">
|
||||
<el-form :model="form" label-width="auto" label-position="top">
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="公司全称">
|
||||
<el-input v-model="form.name" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属行业">
|
||||
<el-input v-model="form.name" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="公司地址">
|
||||
<el-input v-model="form.name" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系电话">
|
||||
<el-input v-model="form.name" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="公司邮箱">
|
||||
<el-input v-model="form.name" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="公司简介">
|
||||
<el-input v-model="form.name" type="textarea" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<div class="main">
|
||||
<h4 class="title">
|
||||
注册
|
||||
</h4>
|
||||
<p class="title-extra">
|
||||
请填写必要的注册信息,完成账户创建。
|
||||
</p>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
hide-required-asterisk
|
||||
label-width="auto"
|
||||
label-position="top"
|
||||
>
|
||||
<el-form-item
|
||||
label="邮箱"
|
||||
prop="email"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.email"
|
||||
placeholder="请输入邮箱"
|
||||
size="large"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="邮箱验证码"
|
||||
prop="code"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.account" placeholder="请输入邮箱验证码" size="large"
|
||||
class="email-code"
|
||||
:class="(!isEmailValid || sending) ? 'disabled' : ''"
|
||||
>
|
||||
<template #append>
|
||||
<el-button :disabled="!isEmailValid || sending" @click="handleSendEmailCode()">
|
||||
{{ sending ? `${countdown}s` : "发送验证码" }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="账号">
|
||||
<el-input v-model="form.account" placeholder="请输入账号" size="large" />
|
||||
</el-form-item> -->
|
||||
<el-form-item
|
||||
label="公司名称"
|
||||
prop="name"
|
||||
>
|
||||
<el-input v-model="form.name" placeholder="请输入公司名称" size="large" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="密码"
|
||||
prop="password"
|
||||
>
|
||||
<el-input v-model="form.password" placeholder="请输入密码" size="large" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="确认密码"
|
||||
prop="confirmPassword"
|
||||
>
|
||||
<el-input v-model="form.confirmPassword" placeholder="请输入确认密码" size="large" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="form-btn" @click="submitForm(formRef)">
|
||||
注册
|
||||
<div class="button-group">
|
||||
<div />
|
||||
<el-button type="primary" @click="handleCompanySubmit()">
|
||||
下一步
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
没有账号?前去
|
||||
<span class="back" @click="navigateTo('/auth/login')">登录</span>
|
||||
<div v-else-if="activeStep === 1" class="section-area">
|
||||
<h2 class="section-title">
|
||||
超级管理员信息
|
||||
</h2>
|
||||
<p class="section-subtitle">
|
||||
超级管理员将拥有系统的最高权限,请谨慎设置
|
||||
</p>
|
||||
|
||||
<el-form :model="form" label-width="auto" label-position="top">
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="管理员姓名">
|
||||
<el-input v-model="form.name" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="手机号">
|
||||
<el-input v-model="form.name" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="管理员邮箱">
|
||||
<el-input v-model="form.name" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="邮箱验证码">
|
||||
<el-input v-model="form.name" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="登录密码">
|
||||
<el-input v-model="form.name" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="确认密码">
|
||||
<el-input v-model="form.name" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="担任职务">
|
||||
<el-input v-model="form.name" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<div class="button-group">
|
||||
<el-button @click="handlePrevStep()">
|
||||
上一步
|
||||
</el-button>
|
||||
<el-button type="primary">
|
||||
下一步
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-sidebar">
|
||||
<div class="info-header">
|
||||
<h1 class="page-title">
|
||||
link56 注册说明
|
||||
</h1>
|
||||
<p class="page-description">
|
||||
请填写公司信息并创建超级管理员账户以完成系统初始化设置
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<ul class="info-list">
|
||||
<li class="info-item">
|
||||
<div class="info-item-header">
|
||||
<i-ri:building-fill />
|
||||
<div class="info-title">
|
||||
公司信息
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-content">
|
||||
请填写公司的法定全称、地址和联系方式,确保信息真实有效,这将用于系统备案和官方文件。
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="info-item">
|
||||
<div class="info-item-header">
|
||||
<i-fa7-solid:user-shield />
|
||||
<div class="info-title">
|
||||
超级管理员
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-content">
|
||||
超级管理员拥有系统的最高权限,可以创建和管理其他用户,分配角色和权限,请妥善保管账户信息。
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="info-item">
|
||||
<div class="info-item-header">
|
||||
<i-material-symbols:lock-open-right-sharp />
|
||||
<div class="info-title">
|
||||
账户安全
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-content">
|
||||
请设置强密码(至少8位,包含字母和数字),建议定期更换密码,不要将账户信息透露给他人。
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="info-item">
|
||||
<div class="info-item-header">
|
||||
<i-ic:twotone-headphones />
|
||||
<div class="info-title">
|
||||
技术支持
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-content">
|
||||
如果在注册过程中遇到问题,请联系我们的技术支持团队:<br>
|
||||
电话:400-123-4567<br>
|
||||
邮箱:support@example.com
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.email-code {
|
||||
:deep(.el-input-group__append) {
|
||||
background-color: #eceffd;
|
||||
color: #4041d1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
:deep(.el-input-group__append) {
|
||||
background-color: #f5f7fa;
|
||||
color: #c0c4cc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.auth-wrapper {
|
||||
background-color: #f2f4f6;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
|
||||
.auth-bg {
|
||||
width: 70%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.bg-content {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 10%;
|
||||
transform: translateX(-50%);
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
width: 600px;
|
||||
|
||||
.carousel-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.title {
|
||||
font-size: 28px;
|
||||
line-height: 28px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.content {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.company {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.form-label-flex {
|
||||
width: 100%;
|
||||
.auth-container {
|
||||
width: 1200px;
|
||||
border: 1px solid #ddd;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
|
||||
.forgot {
|
||||
color: #0f6fec;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.login-form {
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 36px;
|
||||
|
||||
.logo {
|
||||
height: 70px;
|
||||
width: 160px;
|
||||
cursor: pointer;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.main {
|
||||
.form-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
:deep(.el-form-item__label) {
|
||||
font-size: 16px;
|
||||
width: 100%;
|
||||
margin-bottom: 12px;
|
||||
padding: 28px 40px;
|
||||
border-right: 1px solid #e4e4e7;
|
||||
.logo-area {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 28px;
|
||||
img {
|
||||
width: 220px;
|
||||
height: 68px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.title-extra {
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
|
||||
.form-btn {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
font-size: 16px;
|
||||
.section-area {
|
||||
margin-top: 16px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
.section-title {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #e4e4e7;
|
||||
}
|
||||
.section-subtitle {
|
||||
color: #71717a;
|
||||
font-size: 13px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 29px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
font-size: 18px;
|
||||
color: #999;
|
||||
height: 48px;
|
||||
text-align: center;
|
||||
line-height: 48px;
|
||||
.info-sidebar {
|
||||
width: 350px;
|
||||
padding: 28px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #fafafa;
|
||||
|
||||
.back {
|
||||
color: #0f6fec;
|
||||
cursor: pointer;
|
||||
.info-header {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 26px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.022em;
|
||||
margin-bottom: 6px;
|
||||
color: #09090b;
|
||||
}
|
||||
.page-description {
|
||||
font-size: 14px;
|
||||
line-height: 1.55;
|
||||
color: #71717a;
|
||||
}
|
||||
|
||||
.info-list {
|
||||
list-style: none;
|
||||
flex-grow: 1;
|
||||
|
||||
.info-item {
|
||||
padding: 16px 0;
|
||||
border-bottom: 1px solid #e4e4e7;
|
||||
}
|
||||
.info-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.info-item-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 9px;
|
||||
}
|
||||
|
||||
.info-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #09090b;
|
||||
}
|
||||
|
||||
.info-content {
|
||||
color: #71717a;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,228 @@
|
||||
<script setup lang="ts">
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import type { RegisterAdminForm } from '@/types/auth'
|
||||
import { computed, onUnmounted, reactive, ref } from 'vue'
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'prev'): void
|
||||
(e: 'submit', value: RegisterAdminForm): void
|
||||
}>()
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
const form = reactive<RegisterAdminForm>({
|
||||
name: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
emailCode: '',
|
||||
|
||||
password: '',
|
||||
confirmPassword: '',
|
||||
position: '',
|
||||
})
|
||||
const formRules = {
|
||||
name: [
|
||||
{ required: true, message: '管理员名称不能为空', trigger: 'blur' },
|
||||
],
|
||||
email: [
|
||||
{ required: true, message: '邮箱不能为空', trigger: 'blur' },
|
||||
{ type: 'email', message: '请输入正确的邮箱格式', trigger: ['blur', 'change'] },
|
||||
],
|
||||
emailCode: [
|
||||
{ required: true, message: '邮箱验证码不能为空', trigger: 'blur' },
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: '密码不能为空', trigger: 'blur' },
|
||||
],
|
||||
confirmPassword: [
|
||||
{ required: true, message: '确认密码不能为空', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (value !== form.password) {
|
||||
callback(new Error('两次输入的密码不一致'))
|
||||
}
|
||||
else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
],
|
||||
}
|
||||
// 校验邮箱
|
||||
const emailRegex = /^\w+(?:[-.]\w+)*@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*$/
|
||||
|
||||
const isEmailValid = computed(() => emailRegex.test(form.email.trim()))
|
||||
|
||||
// --- 发送验证码状态 & 倒计时 ---
|
||||
const sending = ref(false)
|
||||
const countdown = ref(0)
|
||||
let timer: number | undefined
|
||||
|
||||
function startCountdown(seconds = 60) {
|
||||
countdown.value = seconds
|
||||
timer = window.setInterval(() => {
|
||||
countdown.value -= 1
|
||||
if (countdown.value <= 0) {
|
||||
clearInterval(timer)
|
||||
timer = undefined
|
||||
sending.value = false
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
function handleSendEmailCode() {
|
||||
sending.value = true
|
||||
startCountdown()
|
||||
}
|
||||
|
||||
// 清理
|
||||
onUnmounted(() => {
|
||||
if (timer) {
|
||||
clearInterval(timer)
|
||||
timer = undefined
|
||||
}
|
||||
})
|
||||
|
||||
async function handleSubmit(formEl: FormInstance | undefined) {
|
||||
if (!formEl)
|
||||
return
|
||||
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
emit('submit', form)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function handlePrev() {
|
||||
emit('prev')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="section-area">
|
||||
<div class="content">
|
||||
<h2 class="section-title">
|
||||
超级管理员信息
|
||||
</h2>
|
||||
<p class="section-subtitle">
|
||||
超级管理员将拥有系统的最高权限,请谨慎设置
|
||||
</p>
|
||||
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="auto"
|
||||
label-position="top"
|
||||
>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="管理员姓名" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="手机号" prop="phone">
|
||||
<el-input v-model="form.phone" placeholder="请输入手机号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="管理员邮箱" prop="email">
|
||||
<el-input v-model="form.email" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="邮箱验证码" prop="emailCode">
|
||||
<el-input
|
||||
v-model="form.emailCode" placeholder="请输入邮箱验证码"
|
||||
class="email-code"
|
||||
:class="(!isEmailValid || sending) ? 'disabled' : ''"
|
||||
>
|
||||
<template #append>
|
||||
<el-button :disabled="!isEmailValid || sending" @click="handleSendEmailCode()">
|
||||
{{ sending ? `${countdown}s` : "发送验证码" }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="登录密码" prop="password">
|
||||
<el-input v-model="form.password" placeholder="请输入登录密码" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="确认密码" prop="confirmPassword">
|
||||
<el-input v-model="form.confirmPassword" placeholder="请输入确认密码" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="担任职务" prop="position">
|
||||
<el-input v-model="form.position" placeholder="请输入担任职务" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="button-group">
|
||||
<el-button @click="handlePrev()">
|
||||
上一步
|
||||
</el-button>
|
||||
<el-button type="primary" @click="handleSubmit(formRef)">
|
||||
下一步
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.section-area {
|
||||
margin-top: 16px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.email-code {
|
||||
:deep(.el-input-group__append) {
|
||||
background-color: #409eff;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
:deep(.el-input-group__append) {
|
||||
background-color: #f5f7fa;
|
||||
color: #c0c4cc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
padding-bottom: 6px;
|
||||
border-bottom: 1px solid #e4e4e7;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.section-subtitle {
|
||||
color: #71717a;
|
||||
font-size: 13px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 29px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,155 @@
|
||||
<script setup lang="ts">
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import type { RegisterCompanyForm } from '@/types/auth'
|
||||
import { reactive, ref } from 'vue'
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'submit', value: RegisterCompanyForm): void
|
||||
}>()
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
const formRules = {
|
||||
name: [
|
||||
{ required: true, message: '公司名称不能为空', trigger: 'blur' },
|
||||
],
|
||||
industry: [
|
||||
{ required: true, message: '所属行业不能为空', trigger: 'blur' },
|
||||
],
|
||||
address: [
|
||||
{ required: true, message: '公司地址不能为空', trigger: 'blur' },
|
||||
],
|
||||
email: [{ validator: emailValidator, trigger: 'blur' }],
|
||||
}
|
||||
|
||||
function emailValidator(rule: any, value: any, callback: any) {
|
||||
// 未填写:直接通过
|
||||
if (!value) {
|
||||
callback()
|
||||
return
|
||||
}
|
||||
|
||||
// 填了就校验格式
|
||||
const emailReg
|
||||
= /^[\w.%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i
|
||||
|
||||
if (!emailReg.test(value)) {
|
||||
callback(new Error('邮箱格式不正确'))
|
||||
}
|
||||
else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
const form = reactive<RegisterCompanyForm>({
|
||||
name: '',
|
||||
industry: '',
|
||||
address: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
profile: '',
|
||||
})
|
||||
|
||||
async function handleSubmit(formEl: FormInstance | undefined) {
|
||||
if (!formEl)
|
||||
return
|
||||
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
emit('submit', form)
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="section-area">
|
||||
<div class="content">
|
||||
<h2 class="section-title">
|
||||
公司基本信息
|
||||
</h2>
|
||||
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
label-width="auto"
|
||||
label-position="top"
|
||||
>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="公司全称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入公司全称全称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属行业" prop="industry">
|
||||
<el-input v-model="form.industry" placeholder="请输入所属行业" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="公司地址" prop="address">
|
||||
<el-input v-model="form.address" placeholder="请输入公司地址" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系电话">
|
||||
<el-input v-model="form.phone" placeholder="请输入电话" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="公司邮箱" prop="email">
|
||||
<el-input v-model="form.email" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="公司简介">
|
||||
<el-input v-model="form.profile" type="textarea" placeholder="请输入简介" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="button-group">
|
||||
<div />
|
||||
<el-button type="primary" @click="handleSubmit(formRef)">
|
||||
下一步
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.section-area {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
padding-bottom: 6px;
|
||||
border-bottom: 1px solid #e4e4e7;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.section-subtitle {
|
||||
color: #71717a;
|
||||
font-size: 13px;
|
||||
margin: 10px 0px;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 29px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,157 @@
|
||||
<script setup lang="ts">
|
||||
import type { PropType } from 'vue'
|
||||
import type { RegisterAdminForm, RegisterCompanyForm } from '@/types/auth'
|
||||
import { ref } from 'vue'
|
||||
|
||||
defineProps({
|
||||
company: {
|
||||
type: Object as PropType<RegisterCompanyForm>,
|
||||
required: true,
|
||||
},
|
||||
admin: {
|
||||
type: Object as PropType<RegisterAdminForm>,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'prev'): void
|
||||
(e: 'submit'): void
|
||||
}>()
|
||||
|
||||
const isAgree = ref(false)
|
||||
|
||||
function handleSubmit() {
|
||||
emit('submit')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="section-area">
|
||||
<div class="content">
|
||||
<h2 class="section-title">
|
||||
公司信息
|
||||
</h2>
|
||||
|
||||
<el-row :gutter="16" style="padding: 12px 0px;">
|
||||
<el-col :span="8">
|
||||
公司全称:-
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
所属行业:-
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
公司地址:-
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
联系电话:-
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
公司邮箱:-
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
公司简介:-
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<h2 class="section-title">
|
||||
管理员信息
|
||||
</h2>
|
||||
|
||||
<el-row :gutter="16" style="padding: 12px 0px;">
|
||||
<el-col :span="8">
|
||||
管理员名称:-
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
管理员电话:-
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
管理员邮箱:-
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
登录密码:-
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
所属职务:-
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="terms">
|
||||
<el-checkbox v-model="isAgree" />
|
||||
<span
|
||||
@click="() => {
|
||||
isAgree = !isAgree
|
||||
}"
|
||||
>
|
||||
我同意并接受 服务条款 和 隐私政策,并确认所提供的信息真实有效。我了解超级管理员将拥有系统的最高权限,并会妥善保管账户信息。
|
||||
</span>
|
||||
</div>
|
||||
<div class="button-group">
|
||||
<el-button
|
||||
@click="() => {
|
||||
emit('prev')
|
||||
}"
|
||||
>
|
||||
上一步
|
||||
</el-button>
|
||||
<el-button type="primary" :disabled="!isAgree" @click="handleSubmit()">
|
||||
确认提交
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.section-area {
|
||||
margin-top: 16px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
:deep(.el-col) {
|
||||
word-break: break-all;
|
||||
padding: 3px 0px;
|
||||
}
|
||||
.content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
.section-title {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
padding-bottom: 6px;
|
||||
border-bottom: 1px solid #e4e4e7;
|
||||
}
|
||||
.section-subtitle {
|
||||
color: #71717a;
|
||||
font-size: 13px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.terms {
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
padding: 16px 0px;
|
||||
|
||||
:deep(.el-checkbox) {
|
||||
height: 22px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
span {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,21 @@
|
||||
<script lang="ts" setup>
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="result">
|
||||
<el-result
|
||||
icon="success"
|
||||
title="注册成功"
|
||||
sub-title="请注意查收邮箱,完成账户激活及审核流程。"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.result {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,347 @@
|
||||
<script lang="ts" setup>
|
||||
import type { RegisterAdminForm, RegisterCompanyForm } from '@/types/auth'
|
||||
import { reactive, ref } from 'vue'
|
||||
|
||||
import { useRouter } from 'vue-router'
|
||||
import AdminForm from './components/AdminForm.vue'
|
||||
import CompanyForm from './components/CompanyForm.vue'
|
||||
import ConfirmForm from './components/ConfirmForm.vue'
|
||||
import ResultForm from './components/ResultForm.vue'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const carouselList = [
|
||||
{
|
||||
title: '值得信赖',
|
||||
company: '恒星科技有限公司',
|
||||
content: '我们已经连续三年使用该平台,数据处理稳定高效,团队协作体验非常顺畅。',
|
||||
},
|
||||
{
|
||||
title: '安全 · 高效',
|
||||
company: '博越信息技术',
|
||||
content: '平台的权限管理做得很好,操作简单清晰,极大提升了内部管理效率。',
|
||||
},
|
||||
{
|
||||
title: '稳定可靠',
|
||||
company: '远航供应链集团',
|
||||
content: '系统运行非常稳定,几乎没有出现过宕机情况,客服响应速度也很快。',
|
||||
},
|
||||
{
|
||||
title: '智能化体验',
|
||||
company: '蓝海数据服务中心',
|
||||
content: '智能报表和自动化功能非常实用,减少了大量人工整理数据的时间。',
|
||||
},
|
||||
{
|
||||
title: '灵活易用',
|
||||
company: '中联创投有限公司',
|
||||
content: 'UI设计简洁友好,新员工上手很快,各项业务流程也能灵活配置。',
|
||||
},
|
||||
]
|
||||
|
||||
const activeStep = ref(0)
|
||||
|
||||
const adminForm = ref<RegisterAdminForm>({
|
||||
name: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
emailCode: '',
|
||||
|
||||
password: '',
|
||||
confirmPassword: '',
|
||||
position: '',
|
||||
})
|
||||
const companyForm = ref<RegisterCompanyForm>({
|
||||
name: '',
|
||||
industry: '',
|
||||
address: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
profile: '',
|
||||
})
|
||||
|
||||
function handleNextStep() {
|
||||
activeStep.value += 1
|
||||
}
|
||||
|
||||
function handlePrevStep() {
|
||||
if (activeStep.value > 0) {
|
||||
activeStep.value -= 1
|
||||
}
|
||||
}
|
||||
function navigateTo(path: string) {
|
||||
router.push(path)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="auth-wrapper">
|
||||
<div class="auth-bg">
|
||||
<img src="/auth-bg.jpg">
|
||||
<div class="bg-content">
|
||||
<el-carousel
|
||||
height="150px"
|
||||
indicator-position="none"
|
||||
>
|
||||
<el-carousel-item v-for="(item, index) in carouselList" :key="index">
|
||||
<div class="carousel-item">
|
||||
<h2 class="title">
|
||||
{{ item.title }}
|
||||
</h2>
|
||||
|
||||
<span class="content">{{ item.content }}</span>
|
||||
|
||||
<span class="company"> - {{ item.company }}</span>
|
||||
</div>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="auth-container">
|
||||
<div class="form-container">
|
||||
<div>
|
||||
<img src="/logo.png" class="logo">
|
||||
<el-steps finish-status="success" :active="activeStep" align-center>
|
||||
<el-step title="公司信息" />
|
||||
<el-step title="管理员信息" />
|
||||
<el-step title="确认信息" />
|
||||
</el-steps>
|
||||
</div>
|
||||
|
||||
<CompanyForm v-show="activeStep === 0" @submit="handleNextStep" />
|
||||
<AdminForm v-show="activeStep === 1" @submit="handleNextStep" @prev="handlePrevStep()" />
|
||||
<ConfirmForm v-show="activeStep === 2" :admin="adminForm" :company="companyForm" @prev="handlePrevStep()" @submit="handleNextStep()" />
|
||||
<ResultForm v-show="activeStep === 3" />
|
||||
|
||||
<div class="footer">
|
||||
已有账号?前去
|
||||
<span class="back" @click="navigateTo('/auth/login')">登录</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-sidebar">
|
||||
<div class="info-header">
|
||||
<h1 class="page-title">
|
||||
link56 注册说明
|
||||
</h1>
|
||||
<p class="page-description">
|
||||
请填写公司信息并创建超级管理员账户以完成系统初始化设置
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<ul class="info-list">
|
||||
<li class="info-item">
|
||||
<div class="info-item-header">
|
||||
<i-ri:building-fill />
|
||||
<div class="info-title">
|
||||
公司信息
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-content">
|
||||
请填写公司的法定全称、地址和联系方式,确保信息真实有效,这将用于系统备案和官方文件。
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="info-item">
|
||||
<div class="info-item-header">
|
||||
<i-fa7-solid:user-shield />
|
||||
<div class="info-title">
|
||||
超级管理员
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-content">
|
||||
超级管理员拥有系统的最高权限,可以创建和管理其他用户,分配角色和权限,请妥善保管账户信息。
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="info-item">
|
||||
<div class="info-item-header">
|
||||
<i-material-symbols:lock-open-right-sharp />
|
||||
<div class="info-title">
|
||||
账户安全
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-content">
|
||||
请设置强密码(至少8位,包含字母和数字),建议定期更换密码,不要将账户信息透露给他人。
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="info-item">
|
||||
<div class="info-item-header">
|
||||
<i-ic:twotone-headphones />
|
||||
<div class="info-title">
|
||||
技术支持
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-content">
|
||||
如果在注册过程中遇到问题,请联系我们的技术支持团队:<br>
|
||||
电话:400-123-4567<br>
|
||||
邮箱:support@example.com
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.auth-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
.auth-bg {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.bg-content {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 10%;
|
||||
transform: translateX(-50%);
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
width: 600px;
|
||||
|
||||
.carousel-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.title {
|
||||
font-size: 28px;
|
||||
line-height: 28px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.content {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.company {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.auth-container {
|
||||
border: 1px solid #ddd;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
|
||||
.form-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
padding: 36px;
|
||||
border-right: 1px solid #e4e4e7;
|
||||
|
||||
.logo {
|
||||
height: 70px;
|
||||
width: 160px;
|
||||
cursor: pointer;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.section-area {
|
||||
margin-top: 16px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
.section-title {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #e4e4e7;
|
||||
}
|
||||
.section-subtitle {
|
||||
color: #71717a;
|
||||
font-size: 13px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 29px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info-sidebar {
|
||||
width: 350px;
|
||||
padding: 28px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #fafafa;
|
||||
|
||||
.info-header {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 26px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.022em;
|
||||
margin-bottom: 6px;
|
||||
color: #09090b;
|
||||
}
|
||||
.page-description {
|
||||
font-size: 14px;
|
||||
line-height: 1.55;
|
||||
color: #71717a;
|
||||
}
|
||||
|
||||
.info-list {
|
||||
list-style: none;
|
||||
flex-grow: 1;
|
||||
|
||||
.info-item {
|
||||
padding: 16px 0;
|
||||
border-bottom: 1px solid #e4e4e7;
|
||||
}
|
||||
.info-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.info-item-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 9px;
|
||||
}
|
||||
|
||||
.info-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #09090b;
|
||||
}
|
||||
|
||||
.info-content {
|
||||
color: #71717a;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
font-size: 18px;
|
||||
color: #999;
|
||||
text-align: center;
|
||||
|
||||
.back {
|
||||
color: #0f6fec;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,369 @@
|
||||
<script lang="ts" setup>
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { computed, onUnmounted, reactive, ref } from 'vue'
|
||||
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const carouselList = [
|
||||
{
|
||||
title: '值得信赖',
|
||||
company: '恒星科技有限公司',
|
||||
content: '我们已经连续三年使用该平台,数据处理稳定高效,团队协作体验非常顺畅。',
|
||||
},
|
||||
{
|
||||
title: '安全 · 高效',
|
||||
company: '博越信息技术',
|
||||
content: '平台的权限管理做得很好,操作简单清晰,极大提升了内部管理效率。',
|
||||
},
|
||||
{
|
||||
title: '稳定可靠',
|
||||
company: '远航供应链集团',
|
||||
content: '系统运行非常稳定,几乎没有出现过宕机情况,客服响应速度也很快。',
|
||||
},
|
||||
{
|
||||
title: '智能化体验',
|
||||
company: '蓝海数据服务中心',
|
||||
content: '智能报表和自动化功能非常实用,减少了大量人工整理数据的时间。',
|
||||
},
|
||||
{
|
||||
title: '灵活易用',
|
||||
company: '中联创投有限公司',
|
||||
content: 'UI设计简洁友好,新员工上手很快,各项业务流程也能灵活配置。',
|
||||
},
|
||||
]
|
||||
|
||||
const form = reactive<{
|
||||
email: string
|
||||
code: string
|
||||
name: string
|
||||
account: string
|
||||
password: string
|
||||
confirmPassword: string
|
||||
}>({
|
||||
email: '',
|
||||
code: '',
|
||||
name: '',
|
||||
account: '',
|
||||
password: '',
|
||||
confirmPassword: '',
|
||||
})
|
||||
const formRef = ref<FormInstance>()
|
||||
const formRules = {
|
||||
email: [
|
||||
{ required: true, message: '邮箱不能为空', trigger: 'blur' },
|
||||
{ type: 'email', message: '请输入正确的邮箱格式', trigger: ['blur', 'change'] },
|
||||
],
|
||||
code: [
|
||||
{ required: true, message: '验证码不能为空', trigger: 'blur' },
|
||||
],
|
||||
name: [
|
||||
{ required: true, message: '名称不能为空', trigger: 'blur' },
|
||||
{ min: 2, max: 20, message: '名称长度需在 2 到 20 个字符之间', trigger: 'blur' },
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: '密码不能为空', trigger: 'blur' },
|
||||
{ min: 6, max: 20, message: '密码长度需在 6 到 20 个字符之间', trigger: 'blur' },
|
||||
],
|
||||
confirmPassword: [
|
||||
{ required: true, message: '请再次输入密码', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (value !== form.password) {
|
||||
callback(new Error('两次输入的密码不一致'))
|
||||
}
|
||||
else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
],
|
||||
}
|
||||
const submitLoading = ref(false)
|
||||
|
||||
// --- 邮箱校验(简单正则) ---
|
||||
const emailRegex = /^\w+(?:[-.]\w+)*@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*$/
|
||||
|
||||
const isEmailValid = computed(() => emailRegex.test(form.email.trim()))
|
||||
|
||||
// --- 发送验证码状态 & 倒计时 ---
|
||||
const sending = ref(false)
|
||||
const countdown = ref(0)
|
||||
let timer: number | undefined
|
||||
|
||||
function startCountdown(seconds = 60) {
|
||||
countdown.value = seconds
|
||||
timer = window.setInterval(() => {
|
||||
countdown.value -= 1
|
||||
if (countdown.value <= 0) {
|
||||
clearInterval(timer)
|
||||
timer = undefined
|
||||
sending.value = false
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
// 清理
|
||||
onUnmounted(() => {
|
||||
if (timer) {
|
||||
clearInterval(timer)
|
||||
timer = undefined
|
||||
}
|
||||
})
|
||||
|
||||
function handleSendEmailCode() {
|
||||
sending.value = true
|
||||
startCountdown()
|
||||
}
|
||||
|
||||
async function submitForm(formEl: FormInstance | undefined) {
|
||||
if (!formEl)
|
||||
return
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
}
|
||||
})
|
||||
}
|
||||
function navigateTo(path: string) {
|
||||
router.push(path)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="auth-wrapper">
|
||||
<div class="auth-bg">
|
||||
<img src="/auth-bg.jpg">
|
||||
<div class="bg-content">
|
||||
<el-carousel
|
||||
height="150px"
|
||||
indicator-position="none"
|
||||
>
|
||||
<el-carousel-item v-for="(item, index) in carouselList" :key="index">
|
||||
<div class="carousel-item">
|
||||
<h2 class="title">
|
||||
{{ item.title }}
|
||||
</h2>
|
||||
|
||||
<span class="content">{{ item.content }}</span>
|
||||
|
||||
<span class="company"> - {{ item.company }}</span>
|
||||
</div>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
</div>
|
||||
<div class="login-form">
|
||||
<img src="/logo.png" class="logo" @click="navigateTo('/')">
|
||||
|
||||
<div class="main">
|
||||
<h4 class="title">
|
||||
注册
|
||||
</h4>
|
||||
<p class="title-extra">
|
||||
请填写必要的注册信息,完成账户创建。
|
||||
</p>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
hide-required-asterisk
|
||||
label-width="auto"
|
||||
label-position="top"
|
||||
>
|
||||
<el-form-item
|
||||
label="邮箱"
|
||||
prop="email"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.email"
|
||||
placeholder="请输入邮箱"
|
||||
size="large"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="邮箱验证码"
|
||||
prop="code"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.account" placeholder="请输入邮箱验证码" size="large"
|
||||
class="email-code"
|
||||
:class="(!isEmailValid || sending) ? 'disabled' : ''"
|
||||
>
|
||||
<template #append>
|
||||
<el-button :disabled="!isEmailValid || sending" @click="handleSendEmailCode()">
|
||||
{{ sending ? `${countdown}s` : "发送验证码" }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="账号">
|
||||
<el-input v-model="form.account" placeholder="请输入账号" size="large" />
|
||||
</el-form-item> -->
|
||||
<el-form-item
|
||||
label="公司名称"
|
||||
prop="name"
|
||||
>
|
||||
<el-input v-model="form.name" placeholder="请输入公司名称" size="large" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="密码"
|
||||
prop="password"
|
||||
>
|
||||
<el-input v-model="form.password" placeholder="请输入密码" size="large" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="确认密码"
|
||||
prop="confirmPassword"
|
||||
>
|
||||
<el-input v-model="form.confirmPassword" placeholder="请输入确认密码" size="large" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="form-btn" @click="submitForm(formRef)">
|
||||
注册
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
没有账号?前去
|
||||
<span class="back" @click="navigateTo('/auth/login')">登录</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.email-code {
|
||||
:deep(.el-input-group__append) {
|
||||
background-color: #eceffd;
|
||||
color: #4041d1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
:deep(.el-input-group__append) {
|
||||
background-color: #f5f7fa;
|
||||
color: #c0c4cc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.auth-wrapper {
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
|
||||
.auth-bg {
|
||||
width: 70%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.bg-content {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 10%;
|
||||
transform: translateX(-50%);
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
width: 600px;
|
||||
|
||||
.carousel-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.title {
|
||||
font-size: 28px;
|
||||
line-height: 28px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.content {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.company {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.form-label-flex {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
|
||||
.forgot {
|
||||
color: #0f6fec;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.login-form {
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 36px;
|
||||
|
||||
.logo {
|
||||
height: 70px;
|
||||
width: 160px;
|
||||
cursor: pointer;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
:deep(.el-form-item__label) {
|
||||
font-size: 16px;
|
||||
width: 100%;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.title-extra {
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
|
||||
.form-btn {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
font-size: 16px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
font-size: 18px;
|
||||
color: #999;
|
||||
height: 48px;
|
||||
text-align: center;
|
||||
line-height: 48px;
|
||||
|
||||
.back {
|
||||
color: #0f6fec;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -28,7 +28,7 @@ const carouselList = [
|
||||
</div>
|
||||
|
||||
<div class="query">
|
||||
<QueryCompany v-model="commonStore.companyQuery" :properties="commonStore.propertyOptions" :areas="commonStore.areaOptions" />
|
||||
<QueryCompany v-model="commonStore.companyQuery" :industries="commonStore.industryOptions" :areas="commonStore.areaOptions" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user