diff --git a/README.md b/README.md
index 44c373e..d422e65 100644
--- a/README.md
+++ b/README.md
@@ -1 +1 @@
-# Vue 3 + Typescript + Vite + ElementUI-Plus + DayJs + Pinia
+# Vue 3 + Typescript + Vite + TDdesign + DayJs + Pinia
diff --git a/auto-imports.d.ts b/auto-imports.d.ts
index 9d24007..c2047c2 100644
--- a/auto-imports.d.ts
+++ b/auto-imports.d.ts
@@ -6,5 +6,5 @@
// biome-ignore lint: disable
export {}
declare global {
-
+ const ElMessageBox: typeof import('element-plus/es')['ElMessageBox']
}
diff --git a/dev-dist/sw.js b/dev-dist/sw.js
index b5057da..3eafb5b 100644
--- a/dev-dist/sw.js
+++ b/dev-dist/sw.js
@@ -82,7 +82,7 @@ define(['./workbox-86c9b217'], (function (workbox) { 'use strict';
"revision": "3ca0b8505b4bec776b69afdba2768812"
}, {
"url": "index.html",
- "revision": "0.t9v2fs5c6io"
+ "revision": "0.o5uo4dculfk"
}], {});
workbox.cleanupOutdatedCaches();
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
diff --git a/index.html b/index.html
index 1ba580c..b527dbb 100644
--- a/index.html
+++ b/index.html
@@ -2,12 +2,12 @@
-
+
- Vue项目模板
+ Vue模板
diff --git a/public/logo.png b/public/logo.png
new file mode 100644
index 0000000..caf8b1c
Binary files /dev/null and b/public/logo.png differ
diff --git a/public/version.json b/public/version.json
index 0fc2d28..035137c 100644
--- a/public/version.json
+++ b/public/version.json
@@ -1,5 +1,5 @@
{
- "version": "2025-10-15 09:50:32",
- "buildTime": "2025-10-15T01:50:32.937Z",
+ "version": "2025-12-27 10:25:12",
+ "buildTime": "2025-12-27T02:25:12.719Z",
"environment": "production"
-}
+}
\ No newline at end of file
diff --git a/src/App.vue b/src/App.vue
index b6bf554..84bdd1d 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -36,7 +36,7 @@ onMounted(async () => {
z-index: 1000;
display: flex;
justify-content: center;
- padding: 6px 8px;
+ padding: 16px 8px;
font-size: 12px;
color: #333;
background: rgba(255, 255, 255, 0.85);
diff --git a/src/assets/scss/index.scss b/src/assets/scss/index.scss
index 1bdcade..48122c9 100644
--- a/src/assets/scss/index.scss
+++ b/src/assets/scss/index.scss
@@ -3,6 +3,37 @@
padding: 0;
box-sizing: border-box !important;
}
+
+/* 禁用移动端弹性滚动 */
+html, body {
+ height: 100%;
+ overflow: hidden;
+ position: fixed;
+ width: 100%;
+ -webkit-overflow-scrolling: touch;
+}
+
+#app {
+ height: 100%;
+ overflow: auto;
+ -webkit-overflow-scrolling: auto;
+ position: relative;
+}
+
+/* 禁用iOS橡皮筋效果 */
+body {
+ position: fixed;
+ width: 100%;
+ height: 100%;
+ overscroll-behavior: none;
+ -webkit-overflow-scrolling: touch;
+}
+
+/* 防止下拉刷新和弹性滚动 */
+html {
+ overscroll-behavior: none;
+ -webkit-overflow-scrolling: touch;
+}
li {
list-style: none;
}
diff --git a/src/excelHandle.lnk b/src/excelHandle.lnk
deleted file mode 100644
index c2c4f99..0000000
Binary files a/src/excelHandle.lnk and /dev/null differ
diff --git a/src/main.ts b/src/main.ts
index d84ee08..bd22d76 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -15,8 +15,8 @@ import TDesign from 'tdesign-vue-next'
import 'tdesign-vue-next/es/style/index.css'
import 'normalize.css/normalize.css'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
-// 启动版本检测服务 (20秒检查一次)
-startVersionCheck(1000 * 20)
+// 启动版本检测服务 (两小时检查一次)
+startVersionCheck(1000 * 60 * 2)
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate) // 注入插件
// 挂载到app上
diff --git a/src/router/index.ts b/src/router/index.ts
index 5718919..438a82f 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -12,6 +12,11 @@ const routes = [
{
path: '/',
component: () => import('@/views/index.vue')
+ },
+ {
+ path: '/excel-upload',
+ name: 'ExcelUpload',
+ component: () => import('@/views/excel-upload/index.vue')
}
]
diff --git a/src/services/excel-upload.ts b/src/services/excel-upload.ts
new file mode 100644
index 0000000..4c0aad2
--- /dev/null
+++ b/src/services/excel-upload.ts
@@ -0,0 +1,71 @@
+import Axios from '../utils/request/base-service' // 导入配置好的axios文件
+import type { AxiosProgressEvent } from 'axios'
+
+// 封装axios请求函数,并用export导出
+export function uploadExcel(
+ file: FormData,
+ onUploadProgress?: (progressEvent: AxiosProgressEvent) => void
+) {
+ return Axios({
+ url: '/upload',
+ method: 'post',
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ },
+ data: file,
+ responseType: 'blob',
+ onUploadProgress
+ })
+}
+
+export function checkHealth() {
+ return Axios({
+ url: '/health',
+ method: 'get',
+ headers: {
+ 'Cache-Control': 'no-cache',
+ Pragma: 'no-cache'
+ },
+ params: {
+ _t: Date.now()
+ }
+ })
+}
+
+export function checkDataSourceStatus() {
+ return Axios({
+ url: '/data-source-status',
+ method: 'get',
+ headers: {
+ 'Cache-Control': 'no-cache',
+ Pragma: 'no-cache'
+ },
+ params: {
+ _t: Date.now()
+ }
+ })
+}
+
+export function testConnection() {
+ return Axios({
+ url: '/test',
+ method: 'get',
+ params: {
+ _t: Date.now()
+ }
+ })
+}
+
+export function getProcessingProgress() {
+ return Axios({
+ url: '/progress',
+ method: 'get',
+ headers: {
+ 'Cache-Control': 'no-cache',
+ Pragma: 'no-cache'
+ },
+ params: {
+ _t: Date.now()
+ }
+ })
+}
\ No newline at end of file
diff --git a/src/services/home.ts b/src/services/home.ts
index 24975b7..ce3b4bc 100644
--- a/src/services/home.ts
+++ b/src/services/home.ts
@@ -7,41 +7,41 @@
* @LastEditTime: 2022-01-25 18:04:29
*/
-import Axios from "../api/base-service"; // 导入配置好的axios文件
+import Axios from '../utils/request/base-service' // 导入配置好的axios文件
// 封装axios请求函数,并用export导出
export function getInfo(datas: unknown) {
return Axios({
- url: "/api.php?key=free&appid=0&msg=鹅鹅鹅",
- method: "GET",
+ url: '/api.php?key=free&appid=0&msg=鹅鹅鹅',
+ method: 'GET',
headers: {
- "content-type": "application/json",
+ 'content-type': 'application/json'
},
- data: datas,
- });
+ data: datas
+ })
}
export function getInfoA(datas: unknown) {
return Axios({
- url: "/api/getbooks",
- method: "get",
+ url: '/api/getbooks',
+ method: 'get',
headers: {
- "Content-Type": "application/x-www-form-urlencoded", //设置请求头请求格式form
+ 'Content-Type': 'application/x-www-form-urlencoded' //设置请求头请求格式form
},
- data: datas,
- });
+ data: datas
+ })
}
export function getItem(datas: unknown) {
return Axios({
- url: "/api/getItem",
- method: "post",
+ url: '/api/getItem',
+ method: 'post',
headers: {
- "Content-Type": "application/json", //设置请求头请求格式为json
+ 'Content-Type': 'application/json' //设置请求头请求格式为json
},
- data: datas,
- });
+ data: datas
+ })
}
export function getItemInfo(datas: unknown) {
return Axios({
- url: "/api/getItemInfo" + datas,
- method: "get",
- });
+ url: '/api/getItemInfo' + datas,
+ method: 'get'
+ })
}
diff --git a/src/api/base-service.ts b/src/utils/request/base-service.ts
similarity index 62%
rename from src/api/base-service.ts
rename to src/utils/request/base-service.ts
index e48a6c2..d66cac9 100644
--- a/src/api/base-service.ts
+++ b/src/utils/request/base-service.ts
@@ -1,5 +1,5 @@
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
-import { ElMessage, ElMessageBox } from 'element-plus'
+import { DialogPlugin } from 'tdesign-vue-next'
// 获取浏览器中的url地址和端口号并拼接
/* import { config } from 'public/config.js'
const getBaseUrl = () => {
@@ -13,8 +13,8 @@ const getBaseUrl = () => {
} */
// 创建一个新的axios实例
const instance: AxiosInstance = axios.create({
- baseURL: import.meta.env.VITE_BASE_API,
- timeout: 30000,
+ baseURL: '/api',
+ timeout: 3000000,
withCredentials: false,
headers: {
'Content-Type': 'application/json'
@@ -46,14 +46,31 @@ instance.interceptors.response.use(
const data = response.data
console.log('接口返回', data)
- // 判断接口返回的 Message 字段是否为 Success
- if (!data?.Message.includes('Success')) {
+
+ // 对于健康检查和数据源状态检查接口,直接返回数据
+ if (
+ response.config.url?.includes('/health') ||
+ response.config.url?.includes('/data-source-status')
+ ) {
+ return response
+ }
+
+ // 判断接口返回的 Message 字段是否为 Success(对于其他接口)
+ if (data && data.Message && !data.Message.includes('Success')) {
// 如果不是 Success,则将请求视为失败
- ElMessageBox.alert(JSON.stringify(data), '错误', {
- confirmButtonText: '确定',
- type: 'error',
- dangerouslyUseHTMLString: false
+ const errorDia = DialogPlugin({
+ header: '错误',
+ body: `接口${data.config.url}报错!【${JSON.stringify(data) || '未知错误'}】`,
+ confirmBtn: null,
+ cancelBtn: null,
+ destroyOnClose: true,
+ theme: 'danger',
+ zIndex: 10000,
+ onClose: () => {
+ errorDia.destroy()
+ }
})
+
return Promise.reject({
response: {
status: 200,
@@ -62,8 +79,8 @@ instance.interceptors.response.use(
}
})
}
- // 如果是 Success,则返回数据
- return data
+ // 如果是 Success,或者没有Message字段,则返回数据
+ return response
},
(error: any) => {
// 对响应错误做点什么
@@ -81,19 +98,19 @@ instance.interceptors.response.use(
}
console.error('报错', error)
-
- ElMessageBox.alert(
- `接口:【${error.config.url}】报错
- ${error.message}
- ${JSON.stringify(error?.response?.data)}
- `,
- '报错',
- {
- confirmButtonText: '确定',
- type: 'error',
- dangerouslyUseHTMLString: false
+ const errorDia = DialogPlugin({
+ header: '错误',
+ body: `接口${error.config.url}报错!【${JSON.stringify(error.message) || '未知错误'}】`,
+ confirmBtn: null,
+ cancelBtn: null,
+ destroyOnClose: true,
+ theme: 'danger',
+ zIndex: 10000,
+ onClose: () => {
+ errorDia.destroy()
}
- )
+ })
+
return Promise.reject(error)
}
)
diff --git a/src/views/excel-upload/index.vue b/src/views/excel-upload/index.vue
new file mode 100644
index 0000000..962a022
--- /dev/null
+++ b/src/views/excel-upload/index.vue
@@ -0,0 +1,437 @@
+
+
+
+
+
+
+
+ 服务器状态:
+ {{ serviceStatus === 'ok' ? '正常' : serviceStatus === 'error' ? '异常' : '检查中' }}
+
+
+ 数据源: {{ dataSourceStatus.both_exist ? '完整' : '缺失' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1、上传需要处理的Excel文件(包含身份证号列)
+ 2、系统将自动根据数据源补充乡镇街道和村社区信息
+ 3、处理完成后会自动下载结果文件
+
+
+
+
+
+
+
+
+
+
diff --git a/vite.config.ts b/vite.config.ts
index 63c28fa..c4abe31 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -26,8 +26,8 @@ export default defineConfig({
globPatterns: ['**/*.{js,css,html,svg,jpg,ico}']
},
manifest: {
- name: 'vue模板',
- short_name: 'vue模板',
+ name: 'Excel处理工具',
+ short_name: '处理工具',
theme_color: '#fff', // 浏览器状态栏主题
start_url: './',
display: 'standalone',
@@ -39,7 +39,6 @@ export default defineConfig({
type: 'image/png',
purpose: 'any'
},
-
{
src: 'logo.png',
sizes: '512x512',
@@ -67,17 +66,13 @@ export default defineConfig({
open: true,
proxy: {
'/api': {
- // 7566
- // target: 'http://192.168.39.120:7566',
- target: 'http://127.0.0.1:8066',
+ target: 'http://10.2.0.32:5000',
changeOrigin: true,
rewrite: p => p.replace(/^\/api/, ''),
bypass: (req, res, options) => {
- // @ts-ignore
const proxyURL = options.target + options.rewrite(req.url)
// console.log('proxyURL', proxyURL)
req.headers['x-req-proxyURL'] = proxyURL // 设置未生效
- // @ts-ignore
res.setHeader('x-req-proxyURL', proxyURL) // 设置响应头可以看到
}
}