2024-08-30 18:07:30 +08:00
|
|
|
|
<template>
|
2024-09-02 18:08:00 +08:00
|
|
|
|
<!-- 背景色覆盖整个页面,并且能够正常滚动内容,同时固定内层内容的位置 -->
|
|
|
|
|
<body style="margin: 0; padding: 0; overflow: auto">
|
|
|
|
|
<!-- 背景色层 -->
|
|
|
|
|
<div class="bg-gray-100" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: -1"></div>
|
|
|
|
|
<!-- 内容层 -->
|
|
|
|
|
<div class="flex justify-center" style="position: relative; margin: 20px auto">
|
|
|
|
|
<!-- 卡片盒子 -->
|
|
|
|
|
<div class="w-full max-w-3xl p-6 bg-white rounded-xl shadow-md">
|
|
|
|
|
<!-- type="card" -->
|
|
|
|
|
<a-tabs v-model:activeKey="activeKey" :tabBarGutter="300" centered>
|
|
|
|
|
<a-tab-pane key="1" tab="注册">
|
|
|
|
|
<div style="max-height: 500px; overflow-y: auto">
|
|
|
|
|
<a-form ref="formRef" name="custom-validation" :model="formState" :rules="rules" v-bind="layout" @finish="handleFinish" @validate="handleValidate" @finishFailed="handleFinishFailed">
|
|
|
|
|
<div style="height: 100%">
|
|
|
|
|
<a-form-item v-if="options.length > 0" label="行政区划">
|
|
|
|
|
<a-cascader
|
|
|
|
|
:field-names="{ label: 'label', value: 'value', children: 'children' }"
|
|
|
|
|
@change="cascaderChange"
|
|
|
|
|
style="width: 300px"
|
|
|
|
|
v-if="options.length > 0"
|
|
|
|
|
v-model:value="value"
|
|
|
|
|
:options="options"
|
|
|
|
|
:show-search="{ filter }"
|
2024-09-03 10:42:45 +08:00
|
|
|
|
placeholder="请选择行政区划"
|
2024-09-02 18:08:00 +08:00
|
|
|
|
/>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item v-else label="行政区划">
|
|
|
|
|
<!--  数据加载中~~~ -->
|
2024-08-30 18:07:30 +08:00
|
|
|
|
|
2024-09-02 18:08:00 +08:00
|
|
|
|
<div class="flex justify-center items-center" style="width: 200px"><a-spin /></div>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- 用户根据单位代码去查询 审核状态 -->
|
|
|
|
|
<a-form-item has-feedback label="单位代码" name="code">
|
|
|
|
|
<a-input v-model:value="formState.code" autocomplete="off" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item has-feedback label="单位名称" name="name">
|
|
|
|
|
<a-input v-model:value="formState.name" autocomplete="off" />
|
|
|
|
|
</a-form-item>
|
2024-08-30 18:07:30 +08:00
|
|
|
|
|
2024-09-02 18:08:00 +08:00
|
|
|
|
<a-form-item has-feedback label="详细地址" name="address">
|
|
|
|
|
<a-input v-model:value="formState.address" autocomplete="off" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item has-feedback label="联系人姓名" name="contactPersonInfo">
|
|
|
|
|
<a-input v-model:value="formState.contactPersonInfo.name" autocomplete="off" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item has-feedback label="联系人电话" name="contactPersonInfo">
|
|
|
|
|
<a-input v-model:value="formState.contactPersonInfo.telephone" autocomplete="off" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<!-- -->
|
2024-09-02 18:09:24 +08:00
|
|
|
|
|
2024-09-02 18:08:00 +08:00
|
|
|
|
<!-- -->
|
|
|
|
|
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
|
|
|
|
|
<a-button type="primary" html-type="submit">提交</a-button>
|
|
|
|
|
<a-button style="margin-left: 10px" @click="resetForm">重置表单</a-button>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
</a-form>
|
|
|
|
|
</div>
|
|
|
|
|
</a-tab-pane>
|
|
|
|
|
<a-tab-pane key="2" tab="查询注册结果">
|
|
|
|
|
<div class="flex items-center justify-center flex-col" style="max-height: 500px; overflow-y: auto">
|
|
|
|
|
<a-card v-if="isLogin" class="mb-8" style="width: 300px">
|
|
|
|
|
<div>账户:{{ account }}</div>
|
|
|
|
|
<div>密码:{{ password }}</div>
|
|
|
|
|
</a-card>
|
2024-09-03 10:42:45 +08:00
|
|
|
|
<a-input v-if="isHasAccount" class="w-40 mb-8" v-model:value="searchCode.code" autocomplete="off" placeholder="请输入单位代码查询" />
|
2024-09-02 18:08:00 +08:00
|
|
|
|
<a-button v-if="isHasAccount" size="large" type="primary" :loading="loading" @click="getCheckStatus"> 查询审核状态 </a-button>
|
|
|
|
|
<a-button v-if="isLogin" size="large" type="primary" @click="toLogin"> 去登录 </a-button>
|
|
|
|
|
</div>
|
|
|
|
|
</a-tab-pane>
|
|
|
|
|
</a-tabs>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</body>
|
2024-08-30 18:07:30 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
2024-09-02 18:08:00 +08:00
|
|
|
|
import { useRouter } from 'vue-router'
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
|
2024-08-30 18:07:30 +08:00
|
|
|
|
import { message } from 'ant-design-vue'
|
|
|
|
|
// import type { CascaderProps } from 'ant-design-vue';
|
|
|
|
|
import api from '@/axios/index.ts'
|
|
|
|
|
import type { ShowSearchType } from 'ant-design-vue/es/cascader'
|
2024-09-04 14:02:47 +08:00
|
|
|
|
import { onMounted, reactive, ref, defineComponent } from 'vue'
|
|
|
|
|
defineComponent({
|
|
|
|
|
name: 'Register',
|
|
|
|
|
})
|
2024-08-30 18:07:30 +08:00
|
|
|
|
onMounted(() => {
|
|
|
|
|
getTree()
|
|
|
|
|
})
|
|
|
|
|
const filter: ShowSearchType['filter'] = (inputValue, path) => {
|
|
|
|
|
return path.some((option) => option.title.toLowerCase().indexOf(inputValue.toLowerCase()) > -1)
|
|
|
|
|
}
|
|
|
|
|
const value = ref<string[]>([])
|
|
|
|
|
const options = ref<any[]>([])
|
|
|
|
|
const cascaderChange = (value: any, selectedOptions: any): void => {
|
|
|
|
|
formState.administrativeDivisionCodes = [...value]
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-03 10:05:40 +08:00
|
|
|
|
const dbName = 'myDatabase' // 定义数据库名称
|
|
|
|
|
const storeName = 'treeStore' // 定义存储空间名称
|
|
|
|
|
|
|
|
|
|
// 打开或创建 IndexedDB 数据库的函数
|
|
|
|
|
const openDB = () => {
|
|
|
|
|
return new Promise<IDBDatabase>((resolve, reject) => {
|
|
|
|
|
// 尝试打开名为 'myDatabase' 的数据库,如果不存在则创建
|
|
|
|
|
const request = indexedDB.open(dbName, 1)
|
|
|
|
|
|
|
|
|
|
// 如果数据库需要升级(例如第一次打开或版本号增加),会触发此事件
|
|
|
|
|
request.onupgradeneeded = (event) => {
|
|
|
|
|
const db = (event.target as IDBOpenDBRequest).result
|
|
|
|
|
// 创建一个新的对象存储空间(相当于数据库中的表)名为 'treeStore'
|
|
|
|
|
db.createObjectStore(storeName)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 成功打开数据库后执行此回调
|
|
|
|
|
request.onsuccess = (event) => {
|
|
|
|
|
// 将数据库实例传递给 resolve,供后续使用
|
|
|
|
|
resolve((event.target as IDBOpenDBRequest).result)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果打开数据库失败,执行此回调
|
|
|
|
|
request.onerror = (event) => {
|
|
|
|
|
// 将错误信息传递给 reject
|
|
|
|
|
reject((event.target as IDBOpenDBRequest).error)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将树形结构数据存储到 IndexedDB 中的函数
|
|
|
|
|
const storeTreeData = async (data: any) => {
|
|
|
|
|
const db = await openDB() // 打开数据库并获取数据库实例
|
|
|
|
|
const transaction = db.transaction(storeName, 'readwrite') // 创建一个读写事务
|
|
|
|
|
const store = transaction.objectStore(storeName) // 获取存储空间
|
|
|
|
|
|
|
|
|
|
// 使用 'treeData' 作为键,将数据存储到存储空间中
|
|
|
|
|
store.put(data, 'treeData')
|
|
|
|
|
|
|
|
|
|
// 事务完成后执行的回调
|
|
|
|
|
transaction.oncomplete = () => {
|
|
|
|
|
console.log('Data stored successfully') // 数据存储成功后输出信息
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 从 IndexedDB 中加载缓存数据的函数
|
|
|
|
|
const loadTreeFromCache = async (): Promise<any | null> => {
|
2024-09-03 10:42:45 +08:00
|
|
|
|
const db = await openDB()
|
|
|
|
|
const transaction = db.transaction(storeName, 'readonly')
|
|
|
|
|
const store = transaction.objectStore(storeName)
|
2024-09-03 10:05:40 +08:00
|
|
|
|
|
2024-09-03 10:42:45 +08:00
|
|
|
|
return new Promise<any | null>((resolve, reject) => {
|
|
|
|
|
const request = store.get('treeData')
|
2024-09-03 10:05:40 +08:00
|
|
|
|
|
2024-09-03 10:42:45 +08:00
|
|
|
|
request.onsuccess = () => {
|
|
|
|
|
// console.log('🚀 ~ loadTreeFromCache ~ request.result:', request.result)
|
|
|
|
|
if (request.result !== undefined) {
|
|
|
|
|
resolve(request.result) // 返回缓存数据
|
|
|
|
|
} else {
|
|
|
|
|
resolve(null) // 如果没有缓存数据,返回 null
|
|
|
|
|
}
|
2024-09-03 10:05:40 +08:00
|
|
|
|
}
|
2024-09-03 10:42:45 +08:00
|
|
|
|
|
|
|
|
|
request.onerror = () => {
|
|
|
|
|
reject(request.error)
|
|
|
|
|
}
|
|
|
|
|
})
|
2024-09-03 10:05:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取树形结构数据并存储在 IndexedDB 中的主函数
|
2024-08-30 18:07:30 +08:00
|
|
|
|
const getTree = async () => {
|
2024-09-03 10:05:40 +08:00
|
|
|
|
// 先尝试从缓存中加载数据
|
|
|
|
|
const cachedData = await loadTreeFromCache()
|
2024-09-03 10:42:45 +08:00
|
|
|
|
// console.log('🚀 ~ getTree ~ cachedData:', cachedData)
|
2024-09-03 10:05:40 +08:00
|
|
|
|
if (cachedData) {
|
2024-09-03 10:42:45 +08:00
|
|
|
|
console.log('未发请求')
|
2024-09-03 10:05:40 +08:00
|
|
|
|
// 如果缓存存在,直接使用缓存数据
|
|
|
|
|
options.value = cachedData
|
2024-09-03 10:42:45 +08:00
|
|
|
|
// console.log('Loaded from cache:', cachedData)
|
2024-09-03 10:05:40 +08:00
|
|
|
|
} else {
|
2024-09-03 10:42:45 +08:00
|
|
|
|
console.log('发起了请求')
|
2024-09-03 10:05:40 +08:00
|
|
|
|
// 如果缓存不存在,发起 API 请求
|
|
|
|
|
const res = await api.get<any>('/common/administrativeDivisionTree')
|
|
|
|
|
options.value = res.data
|
|
|
|
|
await storeTreeData(res.data)
|
|
|
|
|
}
|
2024-08-30 18:07:30 +08:00
|
|
|
|
}
|
|
|
|
|
import type { Rule } from 'ant-design-vue/es/form'
|
|
|
|
|
import type { FormInstance } from 'ant-design-vue'
|
2024-09-02 18:08:00 +08:00
|
|
|
|
|
2024-08-30 18:07:30 +08:00
|
|
|
|
interface FormState {
|
|
|
|
|
name: string
|
|
|
|
|
code: number | string
|
|
|
|
|
administrativeDivisionCodes: any[]
|
2024-09-02 18:08:00 +08:00
|
|
|
|
|
2024-08-30 18:07:30 +08:00
|
|
|
|
address: string
|
|
|
|
|
contactPersonInfo: ContactPersonInfo
|
|
|
|
|
}
|
|
|
|
|
const formRef = ref<FormInstance>()
|
|
|
|
|
interface ContactPersonInfo {
|
|
|
|
|
telephone: string
|
|
|
|
|
name: string
|
|
|
|
|
}
|
|
|
|
|
const formState = reactive<FormState>({
|
|
|
|
|
name: '',
|
|
|
|
|
code: '',
|
|
|
|
|
administrativeDivisionCodes: [],
|
|
|
|
|
// province: '',
|
|
|
|
|
// city: '',
|
|
|
|
|
// districts: '',
|
|
|
|
|
// street: '',
|
|
|
|
|
address: '',
|
|
|
|
|
contactPersonInfo: {
|
|
|
|
|
telephone: '',
|
|
|
|
|
name: '',
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const checkIsNull = async (_rule: Rule, value: string) => {
|
|
|
|
|
if (value === '') {
|
|
|
|
|
return Promise.reject('请输入')
|
|
|
|
|
} else {
|
|
|
|
|
return Promise.resolve()
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-02 18:08:00 +08:00
|
|
|
|
const checkOBJ = async (_rule: Rule, value: ContactPersonInfo) => {
|
2024-09-03 10:42:45 +08:00
|
|
|
|
// console.log('🚀 ~ checkOBJ ~ value:', value)
|
2024-09-02 18:08:00 +08:00
|
|
|
|
|
|
|
|
|
if (value.telephone !== '' && value.name !== '') {
|
|
|
|
|
return Promise.resolve()
|
|
|
|
|
} else {
|
|
|
|
|
// return Promise.reject('请填写完整的联系人信息')
|
|
|
|
|
// return Promise.reject('请输入')
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-08-30 18:07:30 +08:00
|
|
|
|
|
|
|
|
|
const rules: Record<string, Rule[]> = {
|
|
|
|
|
name: [{ required: true, validator: checkIsNull, trigger: 'change' }],
|
|
|
|
|
code: [{ required: true, validator: checkIsNull, trigger: 'change' }],
|
|
|
|
|
address: [{ required: true, validator: checkIsNull, trigger: 'change' }],
|
2024-09-02 18:08:00 +08:00
|
|
|
|
|
|
|
|
|
contactPersonInfo: [{ required: true, validator: checkOBJ, trigger: 'change' }],
|
2024-08-30 18:07:30 +08:00
|
|
|
|
}
|
|
|
|
|
const layout = {
|
|
|
|
|
labelCol: { span: 4 },
|
|
|
|
|
wrapperCol: { span: 14 },
|
|
|
|
|
}
|
2024-09-02 18:08:00 +08:00
|
|
|
|
|
|
|
|
|
const register = (values: any) => {
|
2024-08-30 18:07:30 +08:00
|
|
|
|
if (value.value.length === 0) {
|
|
|
|
|
message.error('请选择行政区划')
|
|
|
|
|
return
|
|
|
|
|
} else {
|
|
|
|
|
api.post<any>('/common/policeUnitRegister', { ...formState }).then((res) => {
|
|
|
|
|
console.log(res)
|
2024-09-02 18:08:00 +08:00
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
message.success('提交成功')
|
|
|
|
|
}
|
2024-08-30 18:07:30 +08:00
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-02 18:08:00 +08:00
|
|
|
|
|
|
|
|
|
const handleFinish = (values: FormState) => {
|
|
|
|
|
console.log(values, formState)
|
|
|
|
|
register(values)
|
|
|
|
|
}
|
2024-08-30 18:07:30 +08:00
|
|
|
|
const handleFinishFailed = (errors: any) => {
|
|
|
|
|
console.log(errors)
|
|
|
|
|
}
|
|
|
|
|
const resetForm = () => {
|
|
|
|
|
formRef.value.resetFields()
|
2024-09-03 10:42:45 +08:00
|
|
|
|
value.value = []
|
2024-08-30 18:07:30 +08:00
|
|
|
|
}
|
|
|
|
|
const handleValidate = (...args: any[]) => {
|
|
|
|
|
console.log(args)
|
|
|
|
|
}
|
2024-09-02 18:08:00 +08:00
|
|
|
|
|
|
|
|
|
const activeKey = ref('1')
|
|
|
|
|
const loading = ref<boolean>(false)
|
|
|
|
|
const account = ref<string>('')
|
|
|
|
|
const password = ref<string>('')
|
|
|
|
|
const isHasAccount = ref<boolean>(true)
|
|
|
|
|
const isLogin = ref<boolean>(false)
|
2024-09-03 10:42:45 +08:00
|
|
|
|
// const searchCode = ref<string>()
|
|
|
|
|
//
|
|
|
|
|
const searchCode = reactive({
|
2024-09-04 14:02:47 +08:00
|
|
|
|
// dawda
|
|
|
|
|
code: __APP_ENV.VITE_APP_ENV === 'development' ? '' : '',
|
2024-09-03 10:42:45 +08:00
|
|
|
|
})
|
2024-09-02 18:08:00 +08:00
|
|
|
|
|
|
|
|
|
const getCheckStatus = () => {
|
|
|
|
|
loading.value = true
|
2024-09-03 10:42:45 +08:00
|
|
|
|
api
|
|
|
|
|
.post<any>('/management/getCheckStatus', { onlyCode: searchCode.code, unitOptType: 'POLICE_UNIT' })
|
|
|
|
|
.then((res) => {
|
|
|
|
|
console.log('🚀 ~ api.post<any> ~ res:', res)
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
loading.value = false
|
|
|
|
|
isHasAccount.value = false
|
|
|
|
|
isLogin.value = true
|
|
|
|
|
account.value = res.data.account
|
|
|
|
|
password.value = res.data.password
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.finally(() => {
|
2024-09-02 18:08:00 +08:00
|
|
|
|
loading.value = false
|
2024-09-03 10:42:45 +08:00
|
|
|
|
})
|
2024-09-02 18:08:00 +08:00
|
|
|
|
}
|
|
|
|
|
const toLogin = () => {
|
2024-09-04 14:02:47 +08:00
|
|
|
|
router.replace({ path: '/login', query: { password: password.value, account: account.value } })
|
2024-09-02 18:08:00 +08:00
|
|
|
|
}
|
2024-08-30 18:07:30 +08:00
|
|
|
|
</script>
|