store.register()"
>
-
+
+
+ {{
+ coldTime > 0 ? coldTime : '发送验证码'
+ }}
+
+
+
+
-
+
- 点击上传头像
+ 点击上传头像
/ 拖拽到此区域
@@ -115,9 +155,7 @@
class="flex flex-row items-center bg-gray-600 w-full h-10 justify-around rounded-b-md mt-4"
>
-
+
diff --git a/app/pages/login/components/ResetPart.vue b/app/pages/login/components/ResetPart.vue
index 022f93e..b53741f 100644
--- a/app/pages/login/components/ResetPart.vue
+++ b/app/pages/login/components/ResetPart.vue
@@ -1,47 +1,117 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ {{ coldTime > 0 ? coldTime : '发送验证码' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
-
-
+
+
+
diff --git a/app/pages/login/index.vue b/app/pages/login/index.vue
index cc2f58f..f0b2f84 100644
--- a/app/pages/login/index.vue
+++ b/app/pages/login/index.vue
@@ -6,14 +6,6 @@
const store = useLoginStore();
const { currentType } = storeToRefs(store);
- // watch(currentType, (val) => {
- // console.log(val);
- // });
-
- onMounted(() => {
- // useThemeStore().setTheme('test');
- // useThemeStore().setTheme('self');
- });
diff --git a/app/plugins/http.ts b/app/plugins/http.ts
new file mode 100644
index 0000000..58a3c5c
--- /dev/null
+++ b/app/plugins/http.ts
@@ -0,0 +1,72 @@
+import { APIResponseErrorException } from '~/utils/APIResponse';
+
+const fetch = $fetch.create({
+ onRequest(config) {
+ console.log('request config', config);
+ },
+ onResponse(context) {
+ const response = context.response;
+ console.log('响应数据:', response);
+ console.log('data:', response._data);
+ const data = response._data as APIResponse;
+ if (data.code !== 200) {
+ if (data.code === 301 || data.code === 302) {
+ useRouter()
+ .push(
+ data.message && data.message.length > 0 ? data.message : '/login',
+ )
+ .then();
+ throw new APIResponseErrorException(data);
+ }
+ if (response.status === 401) {
+ useRouter().push('/login').then();
+ throw new APIResponseErrorException(data);
+ }
+ if (data.message && data.message.length > 0)
+ MessagePlugin.error(data.message).then();
+ throw new APIResponseErrorException(data);
+ }
+ if (data.message && data.message.length > 0)
+ MessagePlugin.success(data.message).then();
+ },
+ onResponseError({ response }) {
+ console.error('响应错误:', response);
+ // eslint-disable-next-line no-debugger
+ debugger;
+ // 在这里可以处理错误,例如跳转到登录页面或显示错误提示
+ },
+});
+export type HTTP = {
+ GET: (
+ url: string,
+ records?: Record,
+ ) => Promise>;
+ POST: (
+ url: string,
+ body?: object,
+ ) => Promise>;
+};
+const baseURL = '/api';
+export const $http: HTTP = {
+ GET: async (url: string, records?: Record) => {
+ url = baseURL + url;
+ const result: APIResponse = await fetch(url, {
+ method: 'GET',
+ params: records,
+ });
+ return result;
+ },
+ POST: async (url: string, body?: object) => {
+ url = baseURL + url;
+ const result: APIResponse = await fetch(url, {
+ method: 'POST',
+ body: body,
+ });
+ return result;
+ },
+};
+
+export default defineNuxtPlugin((nuxtApp) => {
+ console.log('$http', $http);
+ nuxtApp.provide('http', $http);
+});
diff --git a/app/stores/login.ts b/app/stores/login.ts
index 1865e13..16f2f1d 100644
--- a/app/stores/login.ts
+++ b/app/stores/login.ts
@@ -1,20 +1,21 @@
interface RegisterData {
email: string;
username: string;
+ identifyingCode: string;
password: string;
passwordRepeat: string;
birth: string;
- avatarURL: string;
+ avatarFile: string;
}
interface LoginData {
- username: string;
+ usernameOrEmail: string;
password: string;
}
interface resetData {
- username: string;
- oldPassword: string;
+ usernameOrEmail: string;
+ identifyingCode: string;
password: string;
passwordRepeat: string;
}
@@ -34,18 +35,19 @@ export interface LoginStore {
export const useLoginStore = defineStore('Login', {
state: (): LoginStore => ({
- loginForm: { username: '', password: '' },
+ loginForm: { usernameOrEmail: '', password: '' },
registerForm: {
email: '',
+ identifyingCode: '',
username: '',
password: '',
passwordRepeat: '',
birth: '',
- avatarURL: '',
+ avatarFile: '',
},
resetForm: {
- username: '',
- oldPassword: '',
+ usernameOrEmail: '',
+ identifyingCode: '',
password: '',
passwordRepeat: '',
},
@@ -53,15 +55,83 @@ export const useLoginStore = defineStore('Login', {
}),
actions: {
async login() {
- console.log(this.loginForm);
- const router = useRouter();
- await router.push('/base/home');
+ const { $http } = useNuxtApp();
+ try {
+ await $http.POST('/login/', this.loginForm);
+ } catch {
+ return false;
+ }
+ return true;
+ },
+ async sendRegisterIdentifyingCode(): Promise {
+ const email = this.registerForm.email;
+ if (email === '') {
+ await MessagePlugin.error('请输入邮箱');
+ return false;
+ } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
+ await MessagePlugin.error('请输入正确的邮箱');
+ return false;
+ }
+ const { $http } = useNuxtApp();
+ let result: APIResponse;
+ try {
+ result = await $http.GET('/login/register/identifyingCode', {
+ email: email,
+ });
+ } catch (e) {
+ console.log(e);
+ return false;
+ }
+ if (result.code === 200) {
+ return true;
+ } else {
+ await MessagePlugin.error(result.message);
+ }
+ return false;
+ },
+ async sendResetIdentifyingCode(): Promise {
+ const { $http } = useNuxtApp();
+ const usernameOrEmail = this.resetForm.usernameOrEmail;
+ if (usernameOrEmail === '') {
+ await MessagePlugin.error('请输入用户名或邮箱');
+ return false;
+ }
+ const result = await $http.GET('/login/passwordReset/identifyingCode', {
+ usernameOrEmail: usernameOrEmail,
+ });
+ if (result.code === 200) {
+ return true;
+ } else {
+ await MessagePlugin.error(result.message);
+ }
+ return false;
},
async register() {
- console.log(this.registerForm);
+ const { $http } = useNuxtApp();
+ try {
+ await $http.POST('/login/register', this.registerForm);
+ } catch {
+ return;
+ }
},
async reset() {
console.log(this.resetForm);
+ const { $http } = useNuxtApp();
+ try {
+ await $http.POST('/login/passwordReset', this.resetForm);
+ } catch {
+ return;
+ }
+ },
+ async logout() {
+ const { $http } = useNuxtApp();
+ try {
+ await $http.GET('/login/logout');
+ } catch {
+ return;
+ }
+ const router = useRouter();
+ await router.push('/login');
},
},
getters: {
diff --git a/app/stores/people.ts b/app/stores/people.ts
new file mode 100644
index 0000000..9be7349
--- /dev/null
+++ b/app/stores/people.ts
@@ -0,0 +1,124 @@
+export interface PeopleInfo {
+ id: number;
+ date: string;
+ name: string;
+ province: string;
+ city: string;
+ address: string;
+ zip: string;
+}
+export interface BasicPagination {
+ current: number;
+ pageSize: number;
+ defaultPageSize: number;
+ total: number;
+ defaultCurrent: number;
+}
+export interface PeopleState {
+ peopleList: PeopleInfo[];
+ showAddPeople: boolean;
+ showEditPeople: boolean;
+ situation: string;
+ pagination: BasicPagination;
+ currentForm: PeopleInfo;
+}
+export const usePeopleStore = defineStore('People', {
+ state: (): PeopleState => ({
+ peopleList: [],
+ showAddPeople: false,
+ showEditPeople: false,
+ situation: '',
+ pagination: {
+ current: 1,
+ pageSize: 10,
+ defaultPageSize: 10,
+ total: 0,
+ defaultCurrent: 1,
+ },
+ currentForm: {
+ id: 0,
+ date: '',
+ name: '',
+ province: '',
+ city: '',
+ address: '',
+ zip: '',
+ },
+ }),
+ actions: {
+ async getPeopleList() {
+ const { $http } = useNuxtApp();
+ try {
+ const res = await $http.GET<{ records: PeopleInfo[] }>(
+ '/userManager/page',
+ {
+ page: '' + this.pagination!.current,
+ size: '' + this.pagination!.pageSize,
+ situation: this.situation,
+ },
+ );
+ this.peopleList = res.data.records;
+ console.log(this.peopleList);
+ } catch (error) {
+ console.error('Error fetching people list:', error);
+ }
+ },
+ async getTotal() {
+ const { $http } = useNuxtApp();
+ try {
+ const res = await $http.GET('/userManager/total', {
+ situation: this.situation,
+ });
+ this.pagination!.total = res.data;
+ if (
+ (this.pagination!.current - 1) * this.pagination!.pageSize >
+ this.pagination!.total
+ ) {
+ this.pagination!.current = Math.ceil(
+ this.pagination!.total / this.pagination!.pageSize,
+ );
+ this.getPeopleList();
+ }
+ } catch {
+ return;
+ }
+ },
+ async addPeople() {
+ console.log('add');
+ const { $http } = useNuxtApp();
+ try {
+ await $http.POST('/userManager/addUser', this.currentForm);
+ this.getTotal();
+ this.getPeopleList();
+ } catch (error) {
+ await MessagePlugin.error('Error adding people:' + error);
+ }
+ this.showEditPeople = false;
+ this.showAddPeople = false;
+ },
+
+ async updatePeople() {
+ const { $http } = useNuxtApp();
+ try {
+ await $http.POST('/userManager/updateUser', this.currentForm);
+ this.getTotal();
+ this.getPeopleList();
+ } catch (error) {
+ await MessagePlugin.error('Error updating people:' + error);
+ }
+ this.showEditPeople = false;
+ this.showAddPeople = false;
+ },
+
+ async deletePeople(peopleId: number) {
+ const { $http } = useNuxtApp();
+ try {
+ await $http.GET('/userManager/deleteUser', { id: '' + peopleId });
+ this.getTotal();
+ this.getPeopleList();
+ } catch (error) {
+ await MessagePlugin.error('Error deleting people:' + error);
+ }
+ },
+ },
+});
diff --git a/app/stores/user.ts b/app/stores/user.ts
index 450e597..7e85991 100644
--- a/app/stores/user.ts
+++ b/app/stores/user.ts
@@ -1,14 +1,53 @@
-export interface UserState {
+export interface UserInfo {
userId: string;
userName: string;
userEmail: string;
userAvatar: string;
+ userAmount: string;
+ lastGetTime: Date;
+}
+export interface UserState extends UserInfo {
+ usernameOrEmail: string;
}
export const useUserStore = defineStore('User', {
state: (): UserState => ({
+ usernameOrEmail: '',
userId: '',
- userName: '李晨鑫',
+ userName: '',
userEmail: '',
userAvatar: '',
+ userAmount: '',
+ lastGetTime: new Date(),
}),
+ actions: {
+ async getUserInfo() {
+ const { $http } = useNuxtApp();
+ try {
+ const res = await $http.GET('/user/info');
+ console.log(res.data);
+ this.userId = res.data.userId;
+ this.userName = res.data.userName;
+ this.userEmail = res.data.userEmail;
+ this.userAvatar = res.data.userAvatar;
+ this.userAmount = '500';
+ this.lastGetTime = new Date();
+ } catch (error) {
+ console.error('Error fetching user info:', error);
+ }
+ },
+ async getAvatarURL() {
+ const now = new Date();
+ if (now.getTime() - this.lastGetTime.getTime() < 1000 * 60 * 9) {
+ return this.userAvatar;
+ }
+ this.lastGetTime = now;
+ const { $http } = useNuxtApp();
+ try {
+ const res = await $http.GET('/user/avatar');
+ this.userAvatar = res.data;
+ } catch (error) {
+ console.error('Error fetching user avatar:', error);
+ }
+ },
+ },
});
diff --git a/app/types/auto-imports.d.ts b/app/types/auto-imports.d.ts
index 5fde0a5..1e3957b 100644
--- a/app/types/auto-imports.d.ts
+++ b/app/types/auto-imports.d.ts
@@ -7,106 +7,25 @@
export {}
declare global {
const APIResponse: typeof import('../utils/APIResponse')['APIResponse']
- const ApolloError: (typeof import('@apollo/client/core'))['ApolloError']
- const EffectScope: (typeof import('vue'))['EffectScope']
- const NetworkStatus: (typeof import('@apollo/client/core'))['NetworkStatus']
+ const APIResponseErrorException: typeof import('../utils/APIResponse')['APIResponseErrorException']
const PageType: typeof import('../stores/login')['PageType']
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
- const computed: (typeof import('vue'))['computed']
- const createApp: (typeof import('vue'))['createApp']
const createPinia: typeof import('pinia')['createPinia']
- const customRef: (typeof import('vue'))['customRef']
- const defineAsyncComponent: (typeof import('vue'))['defineAsyncComponent']
- const defineComponent: (typeof import('vue'))['defineComponent']
const defineStore: typeof import('pinia')['defineStore']
- const effectScope: (typeof import('vue'))['effectScope']
const getActivePinia: typeof import('pinia')['getActivePinia']
- const getCurrentInstance: (typeof import('vue'))['getCurrentInstance']
- const getCurrentScope: (typeof import('vue'))['getCurrentScope']
- const h: (typeof import('vue'))['h']
- const inject: (typeof import('vue'))['inject']
- const isProxy: (typeof import('vue'))['isProxy']
- const isReactive: (typeof import('vue'))['isReactive']
- const isReadonly: (typeof import('vue'))['isReadonly']
- const isRef: (typeof import('vue'))['isRef']
const mapActions: typeof import('pinia')['mapActions']
const mapGetters: typeof import('pinia')['mapGetters']
const mapState: typeof import('pinia')['mapState']
const mapStores: typeof import('pinia')['mapStores']
const mapWritableState: typeof import('pinia')['mapWritableState']
- const markRaw: (typeof import('vue'))['markRaw']
- const nextTick: (typeof import('vue'))['nextTick']
- const onActivated: (typeof import('vue'))['onActivated']
- const onAddToFavorites: (typeof import('@dcloudio/uni-app'))['onAddToFavorites']
- const onBackPress: (typeof import('@dcloudio/uni-app'))['onBackPress']
- const onBeforeMount: (typeof import('vue'))['onBeforeMount']
- const onBeforeUnmount: (typeof import('vue'))['onBeforeUnmount']
- const onBeforeUpdate: (typeof import('vue'))['onBeforeUpdate']
- const onDeactivated: (typeof import('vue'))['onDeactivated']
- const onError: (typeof import('@dcloudio/uni-app'))['onError']
- const onErrorCaptured: (typeof import('vue'))['onErrorCaptured']
- const onHide: (typeof import('@dcloudio/uni-app'))['onHide']
- const onLaunch: (typeof import('@dcloudio/uni-app'))['onLaunch']
- const onLoad: (typeof import('@dcloudio/uni-app'))['onLoad']
- const onMounted: (typeof import('vue'))['onMounted']
- const onNavigationBarButtonTap: (typeof import('@dcloudio/uni-app'))['onNavigationBarButtonTap']
- const onNavigationBarSearchInputChanged: (typeof import('@dcloudio/uni-app'))['onNavigationBarSearchInputChanged']
- const onNavigationBarSearchInputClicked: (typeof import('@dcloudio/uni-app'))['onNavigationBarSearchInputClicked']
- const onNavigationBarSearchInputConfirmed: (typeof import('@dcloudio/uni-app'))['onNavigationBarSearchInputConfirmed']
- const onNavigationBarSearchInputFocusChanged: (typeof import('@dcloudio/uni-app'))['onNavigationBarSearchInputFocusChanged']
- const onPageNotFound: (typeof import('@dcloudio/uni-app'))['onPageNotFound']
- const onPageScroll: (typeof import('@dcloudio/uni-app'))['onPageScroll']
- const onPullDownRefresh: (typeof import('@dcloudio/uni-app'))['onPullDownRefresh']
- const onReachBottom: (typeof import('@dcloudio/uni-app'))['onReachBottom']
- const onReady: (typeof import('@dcloudio/uni-app'))['onReady']
- const onRenderTracked: (typeof import('vue'))['onRenderTracked']
- const onRenderTriggered: (typeof import('vue'))['onRenderTriggered']
- const onResize: (typeof import('@dcloudio/uni-app'))['onResize']
- const onScopeDispose: (typeof import('vue'))['onScopeDispose']
- const onServerPrefetch: (typeof import('vue'))['onServerPrefetch']
- const onShareAppMessage: (typeof import('@dcloudio/uni-app'))['onShareAppMessage']
- const onShareTimeline: (typeof import('@dcloudio/uni-app'))['onShareTimeline']
- const onShow: (typeof import('@dcloudio/uni-app'))['onShow']
- const onTabItemTap: (typeof import('@dcloudio/uni-app'))['onTabItemTap']
- const onThemeChange: (typeof import('@dcloudio/uni-app'))['onThemeChange']
- const onUnhandledRejection: (typeof import('@dcloudio/uni-app'))['onUnhandledRejection']
- const onUnload: (typeof import('@dcloudio/uni-app'))['onUnload']
- const onUnmounted: (typeof import('vue'))['onUnmounted']
- const onUpdated: (typeof import('vue'))['onUpdated']
- const produce: (typeof import('immer'))['produce']
- const provide: (typeof import('vue'))['provide']
- const reactive: (typeof import('vue'))['reactive']
- const readonly: (typeof import('vue'))['readonly']
- const ref: (typeof import('vue'))['ref']
- const resolveComponent: (typeof import('vue'))['resolveComponent']
const setActivePinia: typeof import('pinia')['setActivePinia']
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
- const shallowReactive: (typeof import('vue'))['shallowReactive']
- const shallowReadonly: (typeof import('vue'))['shallowReadonly']
- const shallowRef: (typeof import('vue'))['shallowRef']
const storeToRefs: typeof import('pinia')['storeToRefs']
- const toRaw: (typeof import('vue'))['toRaw']
- const toRef: (typeof import('vue'))['toRef']
- const toRefs: (typeof import('vue'))['toRefs']
- const toValue: (typeof import('vue'))['toValue']
- const triggerRef: (typeof import('vue'))['triggerRef']
- const unref: (typeof import('vue'))['unref']
- const useApolloClient: (typeof import('@vue/apollo-composable'))['useApolloClient']
- const useAttrs: (typeof import('vue'))['useAttrs']
- const useCssModule: (typeof import('vue'))['useCssModule']
- const useCssVars: (typeof import('vue'))['useCssVars']
- const useLazyQuery: (typeof import('@vue/apollo-composable'))['useLazyQuery']
const useLoginStore: typeof import('../stores/login')['useLoginStore']
- const useMutation: (typeof import('@vue/apollo-composable'))['useMutation']
- const useQuery: (typeof import('@vue/apollo-composable'))['useQuery']
- const useSlots: (typeof import('vue'))['useSlots']
+ const usePeopleStore: typeof import('../stores/people')['usePeopleStore']
const useSystemStore: typeof import('../stores/system')['useSystemStore']
const useThemeStore: typeof import('../hooks/useTheme')['useThemeStore']
const useUserStore: typeof import('../stores/user')['useUserStore']
- const watch: (typeof import('vue'))['watch']
- const watchEffect: (typeof import('vue'))['watchEffect']
- const watchPostEffect: (typeof import('vue'))['watchPostEffect']
- const watchSyncEffect: (typeof import('vue'))['watchSyncEffect']
}
// for type re-export
declare global {
@@ -114,13 +33,16 @@ declare global {
export type { PageType, LoginStore } from '../stores/login'
import('../stores/login')
// @ts-ignore
+ export type { PeopleInfo, BasicPagination, PeopleState } from '../stores/people'
+ import('../stores/people')
+ // @ts-ignore
export type { SystemStore } from '../stores/system'
import('../stores/system')
// @ts-ignore
- export type { UserState } from '../stores/user'
+ export type { UserInfo, UserState } from '../stores/user'
import('../stores/user')
// @ts-ignore
- export type { APIResponse, IAPIResponse } from '../utils/APIResponse'
+ export type { APIResponse, APIResponseErrorException, IAPIResponse } from '../utils/APIResponse'
import('../utils/APIResponse')
}
@@ -130,6 +52,7 @@ declare module 'vue' {
interface GlobalComponents {}
interface ComponentCustomProperties {
readonly APIResponse: UnwrapRef
+ readonly APIResponseErrorException: UnwrapRef
readonly PageType: UnwrapRef
readonly acceptHMRUpdate: UnwrapRef
readonly createPinia: UnwrapRef
@@ -144,6 +67,7 @@ declare module 'vue' {
readonly setMapStoreSuffix: UnwrapRef
readonly storeToRefs: UnwrapRef
readonly useLoginStore: UnwrapRef
+ readonly usePeopleStore: UnwrapRef
readonly useSystemStore: UnwrapRef
readonly useThemeStore: UnwrapRef
readonly useUserStore: UnwrapRef
diff --git a/app/types/nuxt.d.ts b/app/types/nuxt.d.ts
new file mode 100644
index 0000000..2c6da93
--- /dev/null
+++ b/app/types/nuxt.d.ts
@@ -0,0 +1,14 @@
+// 文件:types/nuxt.d.ts
+import type { HTTP } from '~/plugins/http';
+
+declare module '#app' {
+ interface NuxtApp {
+ $http: HTTP;
+ }
+}
+
+declare module 'vue' {
+ interface ComponentCustomProperties {
+ $http: HTTP;
+ }
+}
diff --git a/app/utils/APIResponse.ts b/app/utils/APIResponse.ts
index a3a657e..927005e 100644
--- a/app/utils/APIResponse.ts
+++ b/app/utils/APIResponse.ts
@@ -8,3 +8,18 @@ export class APIResponse implements IAPIResponse {
message: string = '';
data: T = undefined as T;
}
+
+export class APIResponseErrorException
+ extends Error
+ implements IAPIResponse
+{
+ code: number;
+ override message: string;
+ data: T = undefined as T;
+ constructor(apiResponse: APIResponse) {
+ super();
+ this.code = apiResponse.code;
+ this.message = apiResponse.message;
+ this.data = apiResponse.data;
+ }
+}
diff --git a/nuxt.config.ts b/nuxt.config.ts
index 1439cb9..822c0a0 100644
--- a/nuxt.config.ts
+++ b/nuxt.config.ts
@@ -17,7 +17,7 @@ export default defineNuxtConfig({
transpile: ['tdesign-vue-next'],
},
- plugins: [],
+ plugins: ['~/plugins/http.ts'],
tailwindcss: {
configPath: './app/tailwind.config.js',
diff --git a/public/city.json b/public/city.json
new file mode 100644
index 0000000..1d3bef1
--- /dev/null
+++ b/public/city.json
@@ -0,0 +1,475 @@
+{
+ "00": {
+ "1": "北京",
+ "2": "天津",
+ "3": "河北省",
+ "4": "山西省",
+ "5": "内蒙古自治区",
+ "6": "辽宁省",
+ "7": "吉林省",
+ "8": "黑龙江省",
+ "9": "上海",
+ "10": "江苏省",
+ "11": "浙江省",
+ "12": "安徽省",
+ "13": "福建省",
+ "14": "江西省",
+ "15": "山东省",
+ "16": "河南省",
+ "17": "湖北省",
+ "18": "湖南省",
+ "19": "广东省",
+ "20": "广西壮族自治区",
+ "21": "海南省",
+ "22": "重庆",
+ "23": "四川省",
+ "24": "贵州省",
+ "25": "云南省",
+ "26": "西藏自治区",
+ "27": "陕西省",
+ "28": "甘肃省",
+ "29": "青海省",
+ "30": "宁夏回族自治区",
+ "31": "新疆维吾尔自治区",
+ "32": "台湾",
+ "33": "香港特别行政区",
+ "34": "澳门特别行政区",
+ "35": "海外"
+ },
+ "1": {
+ "36": "北京市"
+ },
+ "2": {
+ "37": "天津市"
+ },
+ "3": {
+ "38": "石家庄市",
+ "39": "唐山市",
+ "40": "秦皇岛市",
+ "41": "邯郸市",
+ "42": "邢台市",
+ "43": "保定市",
+ "44": "张家口市",
+ "45": "承德市",
+ "46": "沧州市",
+ "47": "廊坊市",
+ "48": "衡水市"
+ },
+ "4": {
+ "49": "太原市",
+ "50": "大同市",
+ "51": "阳泉市",
+ "52": "长治市",
+ "53": "晋城市",
+ "54": "朔州市",
+ "55": "晋中市",
+ "56": "运城市",
+ "57": "忻州市",
+ "58": "临汾市",
+ "59": "吕梁市"
+ },
+ "5": {
+ "60": "呼和浩特市",
+ "61": "包头市",
+ "62": "乌海市",
+ "63": "赤峰市",
+ "64": "通辽市",
+ "65": "鄂尔多斯市",
+ "66": "呼伦贝尔市",
+ "67": "巴彦淖尔市",
+ "68": "乌兰察布市",
+ "69": "兴安盟",
+ "70": "锡林郭勒盟",
+ "71": "阿拉善盟"
+ },
+ "6": {
+ "72": "沈阳市",
+ "73": "大连市",
+ "74": "鞍山市",
+ "75": "抚顺市",
+ "76": "本溪市",
+ "77": "丹东市",
+ "78": "锦州市",
+ "79": "营口市",
+ "80": "阜新市",
+ "81": "辽阳市",
+ "82": "盘锦市",
+ "83": "铁岭市",
+ "84": "朝阳市",
+ "85": "葫芦岛市"
+ },
+ "7": {
+ "86": "长春市",
+ "87": "吉林市",
+ "88": "四平市",
+ "89": "辽源市",
+ "90": "通化市",
+ "91": "白山市",
+ "92": "松原市",
+ "93": "白城市",
+ "94": "延边朝鲜族自治州"
+ },
+ "8": {
+ "95": "哈尔滨市",
+ "96": "齐齐哈尔市",
+ "97": "鸡西市",
+ "98": "鹤岗市",
+ "99": "双鸭山市",
+ "100": "大庆市",
+ "101": "伊春市",
+ "102": "佳木斯市",
+ "103": "七台河市",
+ "104": "牡丹江市",
+ "105": "黑河市",
+ "106": "绥化市",
+ "107": "大兴安岭地区"
+ },
+ "9": {
+ "108": "上海市"
+ },
+ "10": {
+ "109": "南京市",
+ "110": "无锡市",
+ "111": "徐州市",
+ "112": "常州市",
+ "113": "苏州市",
+ "114": "南通市",
+ "115": "连云港市",
+ "116": "淮安市",
+ "117": "盐城市",
+ "118": "扬州市",
+ "119": "镇江市",
+ "120": "泰州市",
+ "121": "宿迁市"
+ },
+ "11": {
+ "122": "杭州市",
+ "123": "宁波市",
+ "124": "温州市",
+ "125": "嘉兴市",
+ "126": "湖州市",
+ "127": "绍兴市",
+ "128": "金华市",
+ "129": "衢州市",
+ "130": "舟山市",
+ "131": "台州市",
+ "132": "丽水市"
+ },
+ "12": {
+ "133": "合肥市",
+ "134": "芜湖市",
+ "135": "蚌埠市",
+ "136": "淮南市",
+ "137": "马鞍山市",
+ "138": "淮北市",
+ "139": "铜陵市",
+ "140": "安庆市",
+ "141": "黄山市",
+ "142": "滁州市",
+ "143": "阜阳市",
+ "144": "宿州市",
+ "145": "六安市",
+ "146": "亳州市",
+ "147": "池州市",
+ "148": "宣城市"
+ },
+ "13": {
+ "149": "福州市",
+ "150": "厦门市",
+ "151": "莆田市",
+ "152": "三明市",
+ "153": "泉州市",
+ "154": "漳州市",
+ "155": "南平市",
+ "156": "龙岩市",
+ "157": "宁德市"
+ },
+ "14": {
+ "158": "南昌市",
+ "159": "景德镇市",
+ "160": "萍乡市",
+ "161": "九江市",
+ "162": "新余市",
+ "163": "鹰潭市",
+ "164": "赣州市",
+ "165": "吉安市",
+ "166": "宜春市",
+ "167": "抚州市",
+ "168": "上饶市"
+ },
+ "15": {
+ "169": "济南市",
+ "170": "青岛市",
+ "171": "淄博市",
+ "172": "枣庄市",
+ "173": "东营市",
+ "174": "烟台市",
+ "175": "潍坊市",
+ "176": "济宁市",
+ "177": "泰安市",
+ "178": "威海市",
+ "179": "日照市",
+ "180": "莱芜市",
+ "181": "临沂市",
+ "182": "德州市",
+ "183": "聊城市",
+ "184": "滨州市",
+ "185": "菏泽市"
+ },
+ "16": {
+ "186": "郑州市",
+ "187": "开封市",
+ "188": "洛阳市",
+ "189": "平顶山市",
+ "190": "安阳市",
+ "191": "鹤壁市",
+ "192": "新乡市",
+ "193": "焦作市",
+ "194": "濮阳市",
+ "195": "许昌市",
+ "196": "漯河市",
+ "197": "三门峡市",
+ "198": "南阳市",
+ "199": "商丘市",
+ "200": "信阳市",
+ "201": "周口市",
+ "202": "驻马店市"
+ },
+ "17": {
+ "203": "武汉市",
+ "204": "黄石市",
+ "205": "十堰市",
+ "206": "宜昌市",
+ "207": "襄阳市",
+ "208": "鄂州市",
+ "209": "荆门市",
+ "210": "孝感市",
+ "211": "荆州市",
+ "212": "黄冈市",
+ "213": "咸宁市",
+ "214": "随州市",
+ "215": "恩施土家族苗族自治州"
+ },
+ "18": {
+ "216": "长沙市",
+ "217": "株洲市",
+ "218": "湘潭市",
+ "219": "衡阳市",
+ "220": "邵阳市",
+ "221": "岳阳市",
+ "222": "常德市",
+ "223": "张家界市",
+ "224": "益阳市",
+ "225": "郴州市",
+ "226": "永州市",
+ "227": "怀化市",
+ "228": "娄底市",
+ "229": "湘西土家族苗族自治州"
+ },
+ "19": {
+ "230": "广州市",
+ "231": "韶关市",
+ "232": "深圳市",
+ "233": "珠海市",
+ "234": "汕头市",
+ "235": "佛山市",
+ "236": "江门市",
+ "237": "湛江市",
+ "238": "茂名市",
+ "239": "肇庆市",
+ "240": "惠州市",
+ "241": "梅州市",
+ "242": "汕尾市",
+ "243": "河源市",
+ "244": "阳江市",
+ "245": "清远市",
+ "246": "东莞市",
+ "247": "中山市",
+ "248": "东沙群岛",
+ "249": "潮州市",
+ "250": "揭阳市",
+ "251": "云浮市"
+ },
+ "20": {
+ "252": "南宁市",
+ "253": "柳州市",
+ "254": "桂林市",
+ "255": "梧州市",
+ "256": "北海市",
+ "257": "防城港市",
+ "258": "钦州市",
+ "259": "贵港市",
+ "260": "玉林市",
+ "261": "百色市",
+ "262": "贺州市",
+ "263": "河池市",
+ "264": "来宾市",
+ "265": "崇左市"
+ },
+ "21": {
+ "266": "海口市",
+ "267": "三亚市",
+ "268": "三沙市"
+ },
+ "22": {
+ "269": "重庆市"
+ },
+ "23": {
+ "270": "成都市",
+ "271": "自贡市",
+ "272": "攀枝花市",
+ "273": "泸州市",
+ "274": "德阳市",
+ "275": "绵阳市",
+ "276": "广元市",
+ "277": "遂宁市",
+ "278": "内江市",
+ "279": "乐山市",
+ "280": "南充市",
+ "281": "眉山市",
+ "282": "宜宾市",
+ "283": "广安市",
+ "284": "达州市",
+ "285": "雅安市",
+ "286": "巴中市",
+ "287": "资阳市",
+ "288": "阿坝藏族羌族自治州",
+ "289": "甘孜藏族自治州",
+ "290": "凉山彝族自治州"
+ },
+ "24": {
+ "291": "贵阳市",
+ "292": "六盘水市",
+ "293": "遵义市",
+ "294": "安顺市",
+ "295": "铜仁市",
+ "296": "黔西南布依族苗族自治州",
+ "297": "毕节市",
+ "298": "黔东南苗族侗族自治州",
+ "299": "黔南布依族苗族自治州"
+ },
+ "25": {
+ "300": "昆明市",
+ "301": "曲靖市",
+ "302": "玉溪市",
+ "303": "保山市",
+ "304": "昭通市",
+ "305": "丽江市",
+ "306": "普洱市",
+ "307": "临沧市",
+ "308": "楚雄彝族自治州",
+ "309": "红河哈尼族彝族自治州",
+ "310": "文山壮族苗族自治州",
+ "311": "西双版纳傣族自治州",
+ "312": "大理白族自治州",
+ "313": "德宏傣族景颇族自治州",
+ "314": "怒江傈僳族自治州",
+ "315": "迪庆藏族自治州"
+ },
+ "26": {
+ "316": "拉萨市",
+ "317": "昌都市",
+ "318": "山南地区",
+ "319": "日喀则市",
+ "320": "那曲地区",
+ "321": "阿里地区",
+ "322": "林芝市"
+ },
+ "27": {
+ "323": "西安市",
+ "324": "铜川市",
+ "325": "宝鸡市",
+ "326": "咸阳市",
+ "327": "渭南市",
+ "328": "延安市",
+ "329": "汉中市",
+ "330": "榆林市",
+ "331": "安康市",
+ "332": "商洛市"
+ },
+ "28": {
+ "333": "兰州市",
+ "334": "嘉峪关市",
+ "335": "金昌市",
+ "336": "白银市",
+ "337": "天水市",
+ "338": "武威市",
+ "339": "张掖市",
+ "340": "平凉市",
+ "341": "酒泉市",
+ "342": "庆阳市",
+ "343": "定西市",
+ "344": "陇南市",
+ "345": "临夏回族自治州",
+ "346": "甘南藏族自治州"
+ },
+ "29": {
+ "347": "西宁市",
+ "348": "海东市",
+ "349": "海北藏族自治州",
+ "350": "黄南藏族自治州",
+ "351": "海南藏族自治州",
+ "352": "果洛藏族自治州",
+ "353": "玉树藏族自治州",
+ "354": "海西蒙古族藏族自治州"
+ },
+ "30": {
+ "355": "银川市",
+ "356": "石嘴山市",
+ "357": "吴忠市",
+ "358": "固原市",
+ "359": "中卫市"
+ },
+ "31": {
+ "360": "乌鲁木齐市",
+ "361": "克拉玛依市",
+ "362": "吐鲁番市",
+ "363": "哈密地区",
+ "364": "昌吉回族自治州",
+ "365": "博尔塔拉蒙古自治州",
+ "366": "巴音郭楞蒙古自治州",
+ "367": "阿克苏地区",
+ "368": "克孜勒苏柯尔克孜自治州",
+ "369": "喀什地区",
+ "370": "和田地区",
+ "371": "伊犁哈萨克自治州",
+ "372": "塔城地区",
+ "373": "阿勒泰地区"
+ },
+ "32": {
+ "374": "台北市",
+ "375": "高雄市",
+ "376": "台南市",
+ "377": "台中市",
+ "378": "金门县",
+ "379": "南投县",
+ "380": "基隆市",
+ "381": "新竹市",
+ "382": "嘉义市",
+ "383": "新北市",
+ "384": "宜兰县",
+ "385": "新竹县",
+ "386": "桃园县",
+ "387": "苗栗县",
+ "388": "彰化县",
+ "389": "嘉义县",
+ "390": "云林县",
+ "391": "屏东县",
+ "392": "台东县",
+ "393": "花莲县",
+ "394": "澎湖县",
+ "395": "连江县"
+ },
+ "33": {
+ "396": "香港岛",
+ "397": "九龙",
+ "398": "新界"
+ },
+ "34": {
+ "399": "澳门半岛",
+ "400": "离岛"
+ },
+ "35": {
+ "401": "海外"
+ }
+}
\ No newline at end of file
diff --git a/public/zipcode_district_data.json b/public/zipcode_district_data.json
new file mode 100644
index 0000000..97b535d
--- /dev/null
+++ b/public/zipcode_district_data.json
@@ -0,0 +1,367 @@
+{
+ "北京市": 100000,
+ "上海市": 200000,
+ "天津市": 300000,
+ "重庆市": 404100,
+ "滁州": 239000,
+ "合肥": 230000,
+ "蚌埠": 233000,
+ "芜湖": 241000,
+ "淮南": 232000,
+ "马鞍山": 243000,
+ "安庆": 246000,
+ "宿州": 234000,
+ "亳州": 236000,
+ "阜阳": 236000,
+ "黄山": 242700,
+ "淮北": 235000,
+ "铜陵": 244000,
+ "宣城": 242000,
+ "六安": 237000,
+ "池州": 247100,
+ "福州": 350000,
+ "厦门": 361000,
+ "宁德": 352000,
+ "莆田": 351100,
+ "泉州": 362000,
+ "漳州": 363000,
+ "龙岩": 364000,
+ "三明": 365000,
+ "南平": 353000,
+ "临夏回族自治州": 731100,
+ "兰州": 730000,
+ "定西": 743000,
+ "平凉": 744000,
+ "庆阳": 745000,
+ "金昌": 737100,
+ "武威": 733000,
+ "张掖": 734000,
+ "嘉峪关": 735100,
+ "酒泉": 735000,
+ "天水": 741000,
+ "陇南": 742500,
+ "甘南藏族自治州": 747000,
+ "白银": 730900,
+ "广州": "0510000",
+ "汕尾": "0516600",
+ "阳江": "0529500",
+ "揭阳": "0522000",
+ "茂名": "0525000",
+ "江门": "0529000",
+ "韶关": "0512000",
+ "惠州": "0516000",
+ "梅州": "0514000",
+ "汕头": "0515000",
+ "深圳": "0518000",
+ "珠海": "0519000",
+ "佛山": "0528000",
+ "肇庆": "0526000",
+ "湛江": "0524000",
+ "中山": "0528400",
+ "河源": "0517000",
+ "清远": "0511500",
+ "云浮": "0527300",
+ "潮州": "0521000",
+ "东莞": "0523000",
+ "防城港": "0538000",
+ "崇左": "0532200",
+ "南宁": "0530000",
+ "来宾": "0546100",
+ "柳州": "0545000",
+ "桂林": "0541000",
+ "贺州": "0542800",
+ "梧州": "0543000",
+ "贵港": "0537000",
+ "玉林": "0537000",
+ "百色": "0533000",
+ "钦州": "0535000",
+ "河池": "0547000",
+ "北海": "0536000",
+ "贵阳": 550000,
+ "遵义": 563000,
+ "安顺": 561000,
+ "黔南布依族苗族": 558000,
+ "黔东南苗族侗族": 556000,
+ "铜仁市": 554300,
+ "毕节市": 551700,
+ "六盘水": 553000,
+ "黔西南布依族苗族": 562400,
+ "海口": 570100,
+ "三亚": 572000,
+ "三沙市": 573100,
+ "邯郸": "056000",
+ "石家庄": "050000",
+ "保定": "071000",
+ "张家口": "075000",
+ "承德": "067000",
+ "唐山": "063000",
+ "廊坊": "065000",
+ "沧州": "061000",
+ "衡水": "053000",
+ "邢台": "054000",
+ "秦皇岛": "066000",
+ "商丘": 476000,
+ "郑州": 450000,
+ "安阳": 455000,
+ "新乡": 453000,
+ "许昌": 461000,
+ "平顶山": 467000,
+ "信阳": 464000,
+ "南阳": 473000,
+ "开封": 475000,
+ "洛阳": 471000,
+ "焦作": 454150,
+ "鹤壁": 458000,
+ "濮阳": 457000,
+ "周口": 466000,
+ "漯河": 462000,
+ "驻马店": 463000,
+ "三门峡": 472000,
+ "哈尔滨": 150000,
+ "齐齐哈尔": 161000,
+ "牡丹江": 157000,
+ "佳木斯": 154000,
+ "绥化": 152000,
+ "黑河": 164300,
+ "大兴安岭地区": 165000,
+ "伊春": 153000,
+ "大庆": 163000,
+ "七台河": 154600,
+ "鸡西": 158100,
+ "鹤岗": 154100,
+ "双鸭山": 155100,
+ "武汉": 430000,
+ "鄂州": 436000,
+ "孝感": 432000,
+ "黄冈": 438000,
+ "黄石": 435000,
+ "咸宁": 437000,
+ "荆州": 434000,
+ "宜昌": 443000,
+ "恩施土家族苗族": 445000,
+ "十堰": 442000,
+ "随州": 441300,
+ "荆门": 448000,
+ "岳阳": 414000,
+ "长沙": 410000,
+ "湘潭": 411100,
+ "株洲": 412000,
+ "衡阳": 421000,
+ "郴州": 423000,
+ "常德": 415000,
+ "益阳": 413000,
+ "娄底": 417000,
+ "邵阳": 422000,
+ "湘西土家族苗族": 416000,
+ "张家界": 427000,
+ "怀化": 418000,
+ "永州": 425000,
+ "长春": 130000,
+ "吉林": 132000,
+ "延边朝鲜族自治州": 133000,
+ "四平": 136000,
+ "通化": 134000,
+ "白城": 137000,
+ "辽源": 136200,
+ "松原": 138000,
+ "白山": 134300,
+ "南京": 210000,
+ "无锡": 214000,
+ "镇江": 212000,
+ "苏州": 215000,
+ "南通": 226000,
+ "扬州": 225000,
+ "盐城": 224000,
+ "徐州": 221000,
+ "淮安": 223001,
+ "连云港": 222000,
+ "常州": 213000,
+ "泰州": 225300,
+ "宿迁": 223800,
+ "鹰潭": 335000,
+ "新余": 338000,
+ "南昌": 330000,
+ "九江": 332000,
+ "上饶": 334000,
+ "抚州": 344000,
+ "宜春": 336000,
+ "吉安": 343000,
+ "赣州": 341000,
+ "景德镇": 333000,
+ "萍乡": 337000,
+ "沈阳": 110000,
+ "铁岭": 112000,
+ "大连": 116000,
+ "鞍山": 114000,
+ "抚顺": 113000,
+ "本溪": 117000,
+ "丹东": 118000,
+ "锦州": 121000,
+ "营口": 115000,
+ "阜新": 123000,
+ "辽阳": 111000,
+ "朝阳": 122000,
+ "盘锦": 124000,
+ "葫芦岛": 125000,
+ "呼伦贝尔": "021000",
+ "呼和浩特": "010000",
+ "包头": "014000",
+ "乌海": "016000",
+ "乌兰察布": "012000",
+ "通辽": "028000",
+ "赤峰": "024000",
+ "鄂尔多斯": "017000",
+ "巴彦淖尔": "015000",
+ "锡林郭勒盟": "026000",
+ "兴安盟": 137400,
+ "阿拉善盟": 750300,
+ "银川": 750000,
+ "石嘴山": 753000,
+ "吴忠": 751100,
+ "固原": 756000,
+ "中卫": 755000,
+ "海北藏族自治州": 812200,
+ "西宁": 810000,
+ "海东": 810600,
+ "黄南藏族自治州": 811300,
+ "海南藏族自治州": 813000,
+ "果洛藏族自治州": 814000,
+ "玉树藏族自治州": 815000,
+ "海西蒙古族藏族": 817000,
+ "成都": 610000,
+ "攀枝花": 617000,
+ "自贡": 643000,
+ "绵阳": 621000,
+ "南充": 637000,
+ "达州": 635000,
+ "遂宁": 629000,
+ "广安": 638500,
+ "巴中": 636600,
+ "泸州": 646000,
+ "宜宾": 644000,
+ "内江": 641000,
+ "资阳": 641300,
+ "乐山": 614000,
+ "眉山": 620000,
+ "凉山彝族自治州": 615000,
+ "雅安": 625000,
+ "甘孜藏族自治州": 626000,
+ "阿坝藏族羌族": 624000,
+ "德阳": 618000,
+ "广元": 628000,
+ "菏泽": 274000,
+ "济南": 250000,
+ "青岛": 266000,
+ "淄博": 255000,
+ "德州": 253000,
+ "烟台": 264000,
+ "潍坊": 261000,
+ "济宁": 272000,
+ "泰安": 271000,
+ "临沂": 276000,
+ "滨州": 256600,
+ "东营": 257000,
+ "威海": 264200,
+ "枣庄": 277000,
+ "日照": 276800,
+ "莱芜": 271100,
+ "聊城": 252000,
+ "西安": 710000,
+ "咸阳": 712000,
+ "延安": 716000,
+ "榆林": 719000,
+ "渭南": 714000,
+ "商洛": 726000,
+ "安康": 725000,
+ "汉中": 723000,
+ "宝鸡": 721000,
+ "铜川": 727000,
+ "朔州": "036000",
+ "忻州": "034000",
+ "太原": "030000",
+ "大同": "037000",
+ "阳泉": "045000",
+ "晋中": "030600",
+ "长治": "046000",
+ "晋城": "048000",
+ "临汾": "041000",
+ "吕梁": "033000",
+ "运城": "044000",
+ "塔城地区": 834700,
+ "哈密地区": 839000,
+ "和田地区": 848000,
+ "阿勒泰地区": 836500,
+ "克孜勒苏柯尔克孜": 845350,
+ "博尔塔拉蒙古": 833400,
+ "克拉玛依": 834000,
+ "乌鲁木齐": 830000,
+ "昌吉回族自治州": 831100,
+ "吐鲁番": 838000,
+ "巴音郭楞蒙古": 841000,
+ "阿克苏地区": 843000,
+ "喀什地区": 844000,
+ "伊犁哈萨克自治州": 835000,
+ "拉萨": 850000,
+ "日喀则": 857000,
+ "山南地区": 856000,
+ "林芝": 860000,
+ "昌都": 854000,
+ "那曲地区": 852000,
+ "阿里地区": 859000,
+ "西双版纳傣族": 666100,
+ "德宏傣族景颇族": 678400,
+ "昭通": 657000,
+ "昆明": 650000,
+ "大理白族自治州": 671000,
+ "红河哈尼族彝族": 661400,
+ "曲靖": 655000,
+ "保山": 678000,
+ "文山壮族苗族": 663000,
+ "玉溪": 653100,
+ "楚雄彝族自治州": 675000,
+ "临沧": 677000,
+ "怒江傈僳族自治州": 673100,
+ "迪庆藏族自治州": 674400,
+ "丽江": 674100,
+ "衢州": 324000,
+ "杭州": 310000,
+ "湖州": 313000,
+ "嘉兴": 314000,
+ "宁波": 315000,
+ "绍兴": 312000,
+ "台州": 318000,
+ "温州": 325000,
+ "丽水": 323000,
+ "金华": 321000,
+ "舟山": 316000,
+ "基隆市": 200,
+ "台北市": 222,
+ "花莲县": 950,
+ "桃园县": 330,
+ "新竹县": 300,
+ "宜兰县": 260,
+ "苗栗县": 360,
+ "台中市": 400,
+ "彰化县": 500,
+ "南投县": 540,
+ "嘉义县": 600,
+ "云林县": 640,
+ "澎湖县": 880,
+ "台南市": 700,
+ "屏东县": 900,
+ "台东县": 210,
+ "高雄市": 800,
+ "金门县": 893,
+ "新竹市": 300,
+ "嘉义市": 600,
+ "新北市": 231,
+ "襄阳": 441000,
+ "东沙群岛": 817000,
+ "普洱市": 665100,
+ "连江县": 350500,
+ "香港岛": 999077,
+ "九龙": 999077,
+ "新界": 999077,
+ "澳门半岛": 999078,
+ "离岛": 999077
+}
\ No newline at end of file