feat: 新增文件上传支持,优化移动端UI与巡检功能

1.  新增全局上传配置,设置默认20MB请求体上限与上传目录
2.  重构上传文件处理,按天自动创建子目录存储文件
3.  修复巡检上传表单移动端强制调用相机的问题
4.  为MES与库房客户端添加响应式侧边栏,支持桌面折叠与移动端抽屉模式
5.  补充PAD端巡检页面的独立访问说明文档
6.  删除冗余的前端静态首页文件
7.  更新库房客户端静态资源哈希值
This commit is contained in:
SunYF
2026-08-31 18:54:15 +08:00
parent ae4c292487
commit bb1bb2c3f5
10 changed files with 174 additions and 64 deletions
@@ -1,10 +1,10 @@
<script setup>
import { computed } from 'vue'
import { ref, computed, onMounted, onBeforeUnmount, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import {
HomeFilled, Download, Upload, Search, CircleCheck, List,
Box, Tickets, Monitor, EditPen
Box, Tickets, Monitor, EditPen, Fold, Expand
} from '@element-plus/icons-vue'
import { getUser, logout } from '../utils/auth'
@@ -15,6 +15,38 @@ const user = getUser()
const userName = computed(() => user?.realName || user?.username || '未登录')
const pageTitle = computed(() => route.meta?.title || '')
// ===== 响应式侧边栏:桌面可折叠,移动端抽屉 =====
const isCollapse = ref(false) // 桌面端折叠(仅图标)
const isMobile = ref(false) // 移动端(≤767px
const mobileOpen = ref(false) // 移动端抽屉展开
const asideWidth = computed(() => (isMobile.value ? '210px' : isCollapse.value ? '64px' : '210px'))
function toggleAside() {
if (isMobile.value) {
mobileOpen.value = !mobileOpen.value
} else {
isCollapse.value = !isCollapse.value
}
}
function onScreenChange() {
const mq = window.matchMedia('(max-width: 767px)')
isMobile.value = mq.matches
if (!isMobile.value) mobileOpen.value = false
}
// 路由切换后自动收起移动端抽屉
watch(() => route.path, () => {
if (isMobile.value) mobileOpen.value = false
})
onMounted(() => {
onScreenChange()
window.addEventListener('resize', onScreenChange)
})
onBeforeUnmount(() => window.removeEventListener('resize', onScreenChange))
const menus = [
{ path: '/', title: '工作台', icon: HomeFilled },
{ path: '/inbound', title: '入库管理', icon: Download },
@@ -50,13 +82,17 @@ function onLogout() {
<template>
<el-container class="layout">
<el-aside width="210px" class="aside">
<!-- 移动端遮罩 -->
<div v-if="isMobile && mobileOpen" class="drawer-mask" @click="mobileOpen = false"></div>
<el-aside :width="asideWidth" class="aside"
:class="{ 'drawer': isMobile, 'drawer-open': isMobile && mobileOpen }">
<div class="brand">
<el-icon :size="22"><Box /></el-icon>
<span>库房客户端</span>
<span v-show="!isCollapse">库房客户端</span>
</div>
<el-menu :default-active="route.path" class="menu" background-color="#001529"
text-color="#c2cad8" active-text-color="#ffffff" router>
text-color="#c2cad8" active-text-color="#ffffff" router
:collapse="isCollapse && !isMobile">
<el-menu-item v-for="m in menus" :key="m.path" :index="m.path">
<el-icon><component :is="m.icon" /></el-icon>
<span>{{ m.title }}</span>
@@ -66,7 +102,13 @@ function onLogout() {
<el-container>
<el-header height="56px" class="header">
<span class="title">{{ pageTitle }}</span>
<div class="header-left">
<el-icon class="collapse-btn" @click="toggleAside">
<Expand v-if="isMobile ? !mobileOpen : isCollapse" />
<Fold v-else />
</el-icon>
<span class="title">{{ pageTitle }}</span>
</div>
<div class="spacer"></div>
<el-button text type="primary" @click="router.push('/display')">
<el-icon style="margin-right:4px"><Monitor /></el-icon>免登录大屏
@@ -91,19 +133,26 @@ function onLogout() {
<style scoped>
.layout { height: 100vh; }
.aside { background: #001529; }
.aside { background: #001529; transition: width .2s ease; }
.drawer { position: fixed; left: 0; top: 0; bottom: 0; z-index: 1001; transform: translateX(-100%); transition: transform .3s ease; }
.drawer-open { transform: translateX(0); }
.drawer-mask { position: fixed; inset: 0; background: rgba(0, 0, 0, .45); z-index: 1000; }
.brand {
display: flex; align-items: center; gap: 8px;
height: 56px; padding: 0 16px;
color: #fff; font-weight: 600; font-size: 15px;
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
white-space: nowrap;
}
.menu { border-right: none; }
.header {
display: flex; align-items: center; gap: 10px;
background: #fff; border-bottom: 1px solid #ebeef5;
}
.title { font-size: 16px; font-weight: 600; }
.header-left { display: flex; align-items: center; gap: 8px; min-width: 0; }
.collapse-btn { font-size: 20px; cursor: pointer; color: #303133; display: flex; align-items: center; flex-shrink: 0; }
.collapse-btn:hover { color: #1668dc; }
.title { font-size: 16px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.spacer { flex: 1; }
.help-btn { font-size: 13px; color: #606266; }
.user-name {