feat: 添加自动化部署方案(Docker + 远程服务器两套方案)

- 新增 deploy/docker/:Docker 本机模拟部署,含 Dockerfile、docker-compose、deploy.sh 一键脚本
- 新增 deploy/remote/:远程服务器部署,含 SSH 自动上传、重启、回滚脚本
- 新增 deploy/README.md:完整使用手册,含现状分析、落地调整工作清单、命令速查
- 新增 build.sh/start.sh:本地构建和启动脚本(含飞书通知)
- 新增前端 .env.docker 环境配置,API 指向测试服务器
- 前端 package.json 新增 build-docker 命令
- 更新 .gitignore:排除 IDE 配置、SQL 数据、Docker 敏感文件
- 前端 UI 样式优化(多个页面组件)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
xqzp2026
2026-04-15 18:41:15 +09:30
parent d27abbb529
commit 8373460096
71 changed files with 8003 additions and 350 deletions

View File

@@ -1,4 +1,4 @@
//测试环境
NODE_ENV='development'
VITE_APP_MODE='develop'
VITE_APP_API_ORIGIN = 'http://192.168.1.182:8095'
VITE_APP_API_ORIGIN = 'http://100.93.0.28:8095'

View File

@@ -0,0 +1,4 @@
//Docker模拟部署环境
NODE_ENV='production'
VITE_APP_MODE='develop'
VITE_APP_API_ORIGIN = 'http://100.93.0.28:18095'

File diff suppressed because it is too large Load Diff

View File

@@ -2,8 +2,9 @@
"name": "witCleanSystem",
"version": "1.0.6",
"scripts": {
"dev": "vite --mode develop --open",
"dev": "vite --mode develop --open -- --host",
"build-test": "vite build --mode test",
"build-docker": "vite build --mode docker",
"build": "vite build --mode production"
},
"dependencies": {

View File

@@ -1,5 +1,5 @@
<template>
<el-skeleton :rows="30" :loading="pageBasicsData.loading" animated />
<el-skeleton :rows="30" :loading="pageBasicsData.loading" />
<!-- 对象数据管理 -->
<div class="regional-grid" v-if="!pageBasicsData.loading">
<!-- 顶部功能按钮 -->

View File

@@ -1,5 +1,5 @@
<template>
<el-skeleton :rows="30" :loading="pageBasicsData.loading" animated />
<el-skeleton :rows="30" :loading="pageBasicsData.loading" />
<!-- 场景对象管理 -->
<div class="regional-grid" v-if="!pageBasicsData.loading">
<!-- 顶部功能按钮 -->

View File

@@ -1,5 +1,5 @@
<template>
<el-skeleton :rows="30" :loading="pageBasicsData.loading" animated />
<el-skeleton :rows="30" :loading="pageBasicsData.loading" />
<!-- 服务事项管理 -->
<div class="regional-grid" v-if="!pageBasicsData.loading">
<!-- 顶部功能按钮 -->

View File

@@ -1,5 +1,5 @@
<template>
<el-skeleton :rows="30" :loading="pageBasicsData.loading" animated />
<el-skeleton :rows="30" :loading="pageBasicsData.loading" />
<!-- 区域网格管理 -->
<div class="regional-grid" v-if="!pageBasicsData.loading">
<!-- 顶部区域 -->

View File

@@ -1,5 +1,5 @@
<template>
<el-skeleton :rows="30" :loading="pageBasicsData.loading" animated />
<el-skeleton :rows="30" :loading="pageBasicsData.loading" />
<!-- 场景管理 -->
<div class="regional-grid" v-if="!pageBasicsData.loading">
<!-- 内容区域 -->

View File

@@ -1,5 +1,5 @@
<template>
<el-skeleton :rows="30" :loading="pageBasicsData.loading" animated />
<el-skeleton :rows="30" :loading="pageBasicsData.loading" />
<!-- 服务事项管理 -->
<div class="regional-grid" v-if="!pageBasicsData.loading">
<!-- 右侧区域 -->

View File

@@ -1,5 +1,5 @@
<template>
<el-skeleton :rows="30" :loading="data.loading" animated />
<el-skeleton :rows="30" :loading="data.loading" />
<!-- 服务事项管理 -->
<div class="regional-grid" v-if="!data.loading">
<!-- 顶部功能按钮 -->

View File

@@ -1,5 +1,5 @@
<template>
<el-skeleton :rows="30" :loading="pageBasicsData.loading" animated />
<el-skeleton :rows="30" :loading="pageBasicsData.loading" />
<!-- 作业数据管理 -->
<div class="regional-grid" v-if="!pageBasicsData.loading">
<!-- 顶部功能按钮 -->

View File

@@ -1,6 +1,6 @@
<template>
<div class='user-manage'>
<!-- <el-skeleton :rows='10' animated v-if='!isLoaded' :throttle='500' /> -->
<!-- <el-skeleton :rows='10' v-if='!isLoaded' :throttle='500' /> -->
<div class='main-container'>
<div class='top-screen' ref='topScreenRef'>
<qu-search-area :model="screenForm" @search="restSearch" @reset="clearScreen(screenFormRef)">

View File

@@ -1,6 +1,6 @@
<template>
<div class='user-manage'>
<!-- <el-skeleton :rows='10' animated v-if='!isLoaded' :throttle='500' /> -->
<!-- <el-skeleton :rows='10' v-if='!isLoaded' :throttle='500' /> -->
<div class='main-container'>
<div class='top-screen' ref='topScreenRef'>
<qu-search-area :model="screenForm" @search="restSearch" @reset="clearScreen(screenFormRef)">

View File

@@ -1,6 +1,6 @@
<template>
<!-- 骨架屏 -->
<el-skeleton :rows="30" :loading="pageBasicsData.loading" animated />
<el-skeleton :rows="30" :loading="pageBasicsData.loading" />
<!-- 人员人效统计 -->
<div class="task-box" v-if="!pageBasicsData.loading">
<div ref="topSearchRef">

View File

@@ -1,6 +1,6 @@
<template>
<!-- 骨架屏 -->
<el-skeleton :rows="30" :loading="pageBasicsData.loading" animated />
<el-skeleton :rows="30" :loading="pageBasicsData.loading" />
<!-- 人员人效统计 -->
<div class="task-box" v-if="!pageBasicsData.loading">
<div ref="topSearchRef">

View File

@@ -1,6 +1,6 @@
<template>
<!-- 骨架屏 -->
<el-skeleton :rows="30" :loading="pageBasicsData.loading" animated />
<el-skeleton :rows="30" :loading="pageBasicsData.loading" />
<!-- 人员人效统计 -->
<div class="task-box" v-if="!pageBasicsData.loading">
<div ref="topSearchRef">

View File

@@ -1,6 +1,6 @@
<template>
<!-- 骨架屏 -->
<el-skeleton :rows="30" :loading="pageBasicsData.loading" animated />
<el-skeleton :rows="30" :loading="pageBasicsData.loading" />
<!-- 任务人效统计 -->
<div class="task-box" v-if="!pageBasicsData.loading">
<div ref="topSearchRef">

View File

@@ -28,7 +28,7 @@
</qu-search-area>
</div>
<div class="auth-group">
<el-skeleton :rows="10" animated v-if="!isLoaded" :throttle="500" />
<el-skeleton :rows="10" v-if="!isLoaded" :throttle="500" />
<qu-table :tableData="tableData" v-model:tableHeader="tableHeader" :height="tableHeight" :pageProps="pageProps"
:rowButtons="rowButtons" @rowButtonClick="rowButtonCall" @pageChange="pageChange" @sortChange="sortChange"
@fetchTableAttr="fetchTableAttr" v-loading="mainLoading" v-else :tableButtons="tableButtons" @buttonClick="buttonClick"></qu-table>

View File

@@ -1,5 +1,5 @@
<template>
<el-skeleton :rows="10" animated v-if="!isLoaded" :throttle="500" />
<el-skeleton :rows="10" v-if="!isLoaded" :throttle="500" />
<div class="page-manage" v-else>
<div class="top-buttons">
<el-button

View File

@@ -1,6 +1,6 @@
<template>
<div class="user-manage">
<el-skeleton :rows="10" animated v-if="!isLoaded" :throttle="500" />
<el-skeleton :rows="10" v-if="!isLoaded" :throttle="500" />
<div class="main-container">
<div class="top-screen" ref="topScreenRef">
<qu-search-area :model="screenForm" @search="restSearch" @reset="clearScreen(screenFormRef)">

View File

@@ -48,7 +48,7 @@
</div>
</el-form-item>
</qu-search-area>
<el-skeleton :rows='10' animated v-if='!isLoaded' :throttle='500' />
<el-skeleton :rows='10' v-if='!isLoaded' :throttle='500' />
<div class='main-table' v-if='isLoaded'>
<qu-table :tableData='tableData' v-model:tableHeader='tableHeader' :height='tableHeight'
:pageProps='pageProps' :rowButtons='rowButtons' @rowButtonClick='rowButtonClick'

View File

@@ -1,6 +1,6 @@
<template>
<div class='user-manage'>
<!-- <el-skeleton :rows='10' animated v-if='!isLoaded' :throttle='500' /> -->
<!-- <el-skeleton :rows='10' v-if='!isLoaded' :throttle='500' /> -->
<div class='main-container'>
<qu-search-area ref='topScreenRef' :model='screenForm' @search='restSearch' @reset="clearScreen(screenFormRef, ['districtId', 'timeArr'])">
<el-form-item label="查询日期" prop="timeArr">

View File

@@ -57,7 +57,7 @@
</div>
</el-form-item>
</qu-search-area>
<el-skeleton :rows='10' animated v-if='!isLoaded' :throttle='500' />
<el-skeleton :rows='10' v-if='!isLoaded' :throttle='500' />
<div class='main-table' v-if='isLoaded'>
<qu-table :tableData='tableData' v-model:tableHeader='tableHeader' :height='tableHeight'
:pageProps='pageProps' :rowButtons='rowButtons' @rowButtonClick='rowButtonClick'

View File

@@ -1,6 +1,6 @@
<template>
<div class="user-manage">
<el-skeleton :rows="10" animated v-if="!isLoaded" :throttle="500" />
<el-skeleton :rows="10" v-if="!isLoaded" :throttle="500" />
<div class="main-container">
<qu-search-area ref="topScreenRef" :model="screenForm" @search="restSearch" @reset="clearScreen(screenFormRef)">
<el-form-item label="打卡日期" prop="name">

View File

@@ -1,6 +1,6 @@
<template>
<div class="user-manage">
<el-skeleton :rows="10" animated v-if="!isLoaded" :throttle="500" />
<el-skeleton :rows="10" v-if="!isLoaded" :throttle="500" />
<div class="main-container">
<qu-search-area ref="topScreenRef" :model="screenForm" @search="restSearch" @reset="clearScreen(screenFormRef, ['districtId'])">
<el-form-item label="打卡日期" prop="name">

View File

@@ -1,6 +1,6 @@
<template>
<div class="user-manage">
<el-skeleton :rows="10" animated v-if="!isLoaded" :throttle="500" />
<el-skeleton :rows="10" v-if="!isLoaded" :throttle="500" />
<div class="main-container">
<qu-search-area ref="topScreenRef" :model="screenForm" @search="restSearch" @reset="clearScreen(screenFormRef, ['districtId'])">
<el-form-item label="打卡日期" prop="name">

View File

@@ -1,5 +1,5 @@
<template>
<el-skeleton :rows="30" :loading="pageBasicsData.loading" animated />
<el-skeleton :rows="30" :loading="pageBasicsData.loading" />
<!-- 保洁任务 -->
<div class="task-box" v-if="!pageBasicsData.loading">
<qu-search-area ref="topSearchRef" :model="pageBasicsData.screenForm" @search="restSearch" @reset="clearScreen">

View File

@@ -1,5 +1,5 @@
<template>
<el-skeleton :rows="30" :loading="pageBasicsData.loading" animated />
<el-skeleton :rows="30" :loading="pageBasicsData.loading" />
<!-- 指派任务 -->
<div class="task-box" v-if="!pageBasicsData.loading">
<qu-search-area ref="topSearchRef" :model="pageBasicsData.screenForm" @search="queryScreen" @reset="resetScreen">

View File

@@ -1,6 +1,6 @@
<template>
<div class="user-manage">
<el-skeleton :rows="10" animated v-if="!isLoaded" :throttle="500" />
<el-skeleton :rows="10" v-if="!isLoaded" :throttle="500" />
<div class="main-container" v-show="isLoaded">
<qu-search-area ref="topScreenRef" :model="screenForm" @search="restSearch" @reset="clearScreen(screenFormRef, ['districtId'])">
<el-form-item label="所属站点" prop="districtId">

View File

@@ -104,7 +104,7 @@
</div>
</el-form-item>
</qu-search-area>
<el-skeleton :rows="10" animated v-if="!isLoaded" :throttle="500" />
<el-skeleton :rows="10" v-if="!isLoaded" :throttle="500" />
<div class="main-table" v-if="isLoaded">
<qu-table :tableData="tableData" v-model:tableHeader="tableHeader" :height="tableHeight"
:pageProps="pageProps" :rowButtons="rowButtons" @rowButtonClick="rowButtonClick" @pageChange="pageChange"

View File

@@ -1,5 +1,5 @@
<template>
<el-skeleton :rows="30" :loading="pageBasicsData.loading" animated />
<el-skeleton :rows="30" :loading="pageBasicsData.loading" />
<div class="task-box" v-if="!pageBasicsData.loading">
<qu-search-area ref="topSearchRef" :model="pageBasicsData.screenForm" @search="restSearch" @reset="clearScreen">
<el-form-item label="所属站点" prop="districtId">

View File

@@ -1,5 +1,5 @@
<template>
<el-skeleton :rows="30" :loading="pageBasicsData.loading" animated />
<el-skeleton :rows="30" :loading="pageBasicsData.loading" />
<!-- 用户上报任务 -->
<div class="task-box" v-if="!pageBasicsData.loading">
<qu-search-area ref="topSearchRef" :model="pageBasicsData.screenForm" @search="restSearch" @reset="clearScreen">

View File

@@ -17,7 +17,7 @@
</qu-search-area>
</div>
<div class="main-table">
<el-skeleton :rows="10" animated v-if="!isLoaded" :throttle="500" />
<el-skeleton :rows="10" v-if="!isLoaded" :throttle="500" />
<qu-table :tableData="tableData" v-model:tableHeader="tableHeader" :height="tableHeight" :pageProps="pageProps"
:rowButtons="rowButtons" @rowButtonClick="rowButtonClick" @pageChange="pageChange" @sortChange="sortChange"
v-loading="tableLoading" v-if="isLoaded" :tableButtons="tableButtons" @buttonClick="buttonClick">

View File

@@ -17,7 +17,7 @@
</qu-search-area>
</div>
<div class="main-table">
<el-skeleton :rows="10" animated v-if="!isLoaded" :throttle="500" />
<el-skeleton :rows="10" v-if="!isLoaded" :throttle="500" />
<qu-table :tableData="tableData" v-model:tableHeader="tableHeader" :height="tableHeight" :pageProps="pageProps"
:rowButtons="rowButtons" @rowButtonClick="rowButtonClick" @pageChange="pageChange" @sortChange="sortChange"
v-loading="tableLoading" v-if="isLoaded" :tableButtons="tableButtons" @buttonClick="buttonClick">

View File

@@ -17,7 +17,7 @@
</qu-search-area>
</div>
<div class="main-table">
<el-skeleton :rows="10" animated v-if="!isLoaded" :throttle="500" />
<el-skeleton :rows="10" v-if="!isLoaded" :throttle="500" />
<qu-table :tableData="tableData" v-model:tableHeader="tableHeader" :height="tableHeight" :pageProps="pageProps"
:rowButtons="rowButtons" @rowButtonClick="rowButtonClick" @pageChange="pageChange" @sortChange="sortChange"
v-loading="tableLoading" v-if="isLoaded" :tableButtons="tableButtons" @buttonClick="buttonClick"></qu-table>

View File

@@ -7,7 +7,7 @@
</userManageScreen>
</div>
<div class="main-table">
<el-skeleton :rows="10" animated v-if="!isLoaded" :throttle="500" />
<el-skeleton :rows="10" v-if="!isLoaded" :throttle="500" />
<qu-table :tableData="tableData" v-model:tableHeader="tableHeader" :height="tableHeight" :pageProps="pageProps"
:rowButtons="rowButtons" @rowButtonClick="rowButtonClick" @pageChange="pageChange" @sortChange="sortChange"
v-loading="tableLoading" v-if="isLoaded" :tableButtons="tableButtons" @buttonClick="buttonClick"></qu-table>

View File

@@ -26,7 +26,7 @@ export default defineConfig({
proxy: {
"/api": {
// target: "https://b.ququsearch.com",
target: "http://100.93.0.28:8095",
target: "http://localhost:8095",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},