|
|
@@ -1,139 +1,164 @@
|
|
|
<template>
|
|
|
<div class="app-container home">
|
|
|
<!-- 太浦闸 -->
|
|
|
- <el-divider content-position="left">
|
|
|
+ <div class="section-header">
|
|
|
+ <svg-icon icon-class="monitor" class="section-icon" />
|
|
|
<span class="section-title">太浦闸</span>
|
|
|
- </el-divider>
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="24">
|
|
|
- <el-card class="home-card">
|
|
|
- <el-row :gutter="10">
|
|
|
- <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-for="(item, index) in tpzItems" :key="item.id">
|
|
|
- <div class="card-item" @click="goToPage('/more/tpz?folderId=' + item.id)">
|
|
|
- {{ index + 1 }}){{ item.name }}
|
|
|
- </div>
|
|
|
- </el-col>
|
|
|
- <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-if="loadingTpz && tpzItems.length === 0">
|
|
|
- <div class="empty-text">暂无数据</div>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
+ <span class="section-line"></span>
|
|
|
+ <el-button link type="primary" icon="Plus" @click="openAdd('tpz')">添加模块</el-button>
|
|
|
+ </div>
|
|
|
+ <el-card class="home-card" shadow="never">
|
|
|
+ <el-row :gutter="12">
|
|
|
+ <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-for="(item, index) in tpzItems" :key="item.id">
|
|
|
+ <div class="card-item" @click="goToPage('/more/tpz?folderId=' + item.id)">
|
|
|
+ <span class="card-index">{{ index + 1 }}</span>
|
|
|
+ <span class="card-text" :title="item.name">{{ item.name }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-if="!loadingTpz && tpzItems.length === 0">
|
|
|
+ <div class="empty-text">暂无数据</div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-card>
|
|
|
|
|
|
<!-- 望亭闸 -->
|
|
|
- <el-divider content-position="left">
|
|
|
+ <div class="section-header">
|
|
|
+ <svg-icon icon-class="example" class="section-icon" />
|
|
|
<span class="section-title">望亭闸</span>
|
|
|
- </el-divider>
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="24">
|
|
|
- <el-card class="home-card">
|
|
|
- <el-row :gutter="10">
|
|
|
- <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-for="(item, index) in wyhItems" :key="item.id">
|
|
|
- <div class="card-item" @click="goToPage('/more/wyh?folderId=' + item.id)">
|
|
|
- {{ index + 1 }}){{ item.name }}
|
|
|
- </div>
|
|
|
- </el-col>
|
|
|
- <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-if="loadingWyh && wyhItems.length === 0">
|
|
|
- <div class="empty-text">暂无数据</div>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
+ <span class="section-line"></span>
|
|
|
+ <el-button link type="primary" icon="Plus" @click="openAdd('wyh')">添加模块</el-button>
|
|
|
+ </div>
|
|
|
+ <el-card class="home-card" shadow="never">
|
|
|
+ <el-row :gutter="12">
|
|
|
+ <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-for="(item, index) in wyhItems" :key="item.id">
|
|
|
+ <div class="card-item" @click="goToPage('/more/wyh?folderId=' + item.id)">
|
|
|
+ <span class="card-index">{{ index + 1 }}</span>
|
|
|
+ <span class="card-text" :title="item.name">{{ item.name }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-if="!loadingWyh && wyhItems.length === 0">
|
|
|
+ <div class="empty-text">暂无数据</div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-card>
|
|
|
|
|
|
<!-- 直管工程 -->
|
|
|
- <el-divider content-position="left">
|
|
|
+ <div class="section-header">
|
|
|
+ <svg-icon icon-class="build" class="section-icon" />
|
|
|
<span class="section-title">直管工程</span>
|
|
|
- </el-divider>
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="24">
|
|
|
- <el-card class="home-card">
|
|
|
- <el-row :gutter="10">
|
|
|
- <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-for="(item, index) in zggcList" :key="item.id">
|
|
|
- <div class="project-item" @click="goToPage('/zggc/detail/' + item.id)">
|
|
|
- <div class="project-name">{{ item.name }}</div>
|
|
|
- </div>
|
|
|
- </el-col>
|
|
|
- <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-if="loadingZggc && zggcList.length === 0">
|
|
|
- <div class="empty-text">暂无数据</div>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
+ <span class="section-line"></span>
|
|
|
+ <el-button link type="primary" icon="Plus" @click="openAdd('zggc')">添加项目</el-button>
|
|
|
+ </div>
|
|
|
+ <el-card class="home-card" shadow="never">
|
|
|
+ <el-row :gutter="12">
|
|
|
+ <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-for="(item, index) in zggcList" :key="item.id">
|
|
|
+ <div class="project-item zggc-card" @click="goToPage('/zggc/detail/' + item.id)">
|
|
|
+ <div class="zggc-bar" :style="{ background: 'linear-gradient(to right, rgba(15,105,220,0.7) ' + (item.planValue || 0) + '%, rgb(212,212,212) ' + (item.planValue || 0) + '%)' }"></div>
|
|
|
+ <div class="zggc-text" :title="item.name">
|
|
|
+ <svg-icon icon-class="build" class="project-icon" />
|
|
|
+ <span class="zggc-name">{{ item.name }}</span>
|
|
|
+ <span class="zggc-pct">{{ item.planValue || 0 }}%</span>
|
|
|
+ </div>
|
|
|
+ <span class="status-tag" :class="getZggcStatusClass(item.planValue)">{{ getZggcStatus(item.planValue) }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-if="!loadingZggc && zggcList.length === 0">
|
|
|
+ <div class="empty-text">暂无数据</div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-card>
|
|
|
|
|
|
<!-- 重点工程 -->
|
|
|
- <el-divider content-position="left">
|
|
|
+ <div class="section-header">
|
|
|
+ <svg-icon icon-class="star" class="section-icon" />
|
|
|
<span class="section-title">重点工程</span>
|
|
|
- </el-divider>
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="24">
|
|
|
- <el-card class="home-card">
|
|
|
- <el-row :gutter="10">
|
|
|
- <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-for="(item, index) in zdgcList" :key="item.id">
|
|
|
- <div class="project-item" @click="goToPage('/zdgc/detail/' + item.id)">
|
|
|
- <div class="project-name">{{ item.name }}</div>
|
|
|
- </div>
|
|
|
- </el-col>
|
|
|
- <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-if="loadingZdgc && zdgcList.length === 0">
|
|
|
- <div class="empty-text">暂无数据</div>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
+ <span class="section-line"></span>
|
|
|
+ <el-button link type="primary" icon="Plus" @click="openAdd('zdgc')">添加分类</el-button>
|
|
|
+ </div>
|
|
|
+ <el-card class="home-card" shadow="never">
|
|
|
+ <el-row :gutter="12">
|
|
|
+ <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-for="(item, index) in zdgcList" :key="item.id">
|
|
|
+ <div class="project-item zdgc-card" @click="goToPage('/zdgc/index?folderId=' + item.id)">
|
|
|
+ <span class="zdgc-name" :title="item.name">{{ item.name }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-if="!loadingZdgc && zdgcList.length === 0">
|
|
|
+ <div class="empty-text">暂无数据</div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-card>
|
|
|
|
|
|
<!-- 督导检查 -->
|
|
|
- <el-divider content-position="left">
|
|
|
+ <div class="section-header">
|
|
|
+ <svg-icon icon-class="search" class="section-icon" />
|
|
|
<span class="section-title">督导检查</span>
|
|
|
- </el-divider>
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="24">
|
|
|
- <el-card class="home-card">
|
|
|
- <el-row :gutter="10">
|
|
|
- <el-col :span="2" v-for="(item, index) in ddjcList" :key="item.id">
|
|
|
- <div class="ddjc-item" @click="goToPage('/ddjc/index?folderId=' + item.id)">
|
|
|
- {{ item.name }}
|
|
|
- </div>
|
|
|
- </el-col>
|
|
|
- <el-col :span="2" v-if="loadingDdjc && ddjcList.length === 0">
|
|
|
- <div class="empty-text">暂无数据</div>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
+ <span class="section-line"></span>
|
|
|
+ <el-button link type="primary" icon="Plus" @click="openAdd('ddjc')">添加检查</el-button>
|
|
|
+ </div>
|
|
|
+ <el-card class="home-card" shadow="never">
|
|
|
+ <el-row :gutter="12">
|
|
|
+ <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-for="(item, index) in ddjcList" :key="item.id">
|
|
|
+ <div class="card-item" @click="goToPage('/ddjc/index?folderId=' + item.id)">
|
|
|
+ <span class="card-index">{{ index + 1 }}</span>
|
|
|
+ <span class="card-text" :title="item.name">{{ item.name }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-if="!loadingDdjc && ddjcList.length === 0">
|
|
|
+ <div class="empty-text">暂无数据</div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-card>
|
|
|
|
|
|
<!-- 规章制度 -->
|
|
|
- <el-divider content-position="left">
|
|
|
+ <div class="section-header">
|
|
|
+ <svg-icon icon-class="documentation" class="section-icon" />
|
|
|
<span class="section-title">规章制度</span>
|
|
|
- </el-divider>
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="24">
|
|
|
- <el-card class="home-card">
|
|
|
- <el-row :gutter="10">
|
|
|
- <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-for="(item, index) in gzzdList" :key="item.id">
|
|
|
- <div class="card-item" @click="goToPage('/gzzd/detail/' + item.id)">
|
|
|
- {{ item.name }}
|
|
|
- </div>
|
|
|
- </el-col>
|
|
|
- <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-if="loadingGzzd && gzzdList.length === 0">
|
|
|
- <div class="empty-text">暂无数据</div>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
+ <span class="section-line"></span>
|
|
|
+ <el-button link type="primary" icon="Plus" @click="openAdd('gzzd')">添加记录</el-button>
|
|
|
+ </div>
|
|
|
+ <el-card class="home-card" shadow="never">
|
|
|
+ <el-row :gutter="12">
|
|
|
+ <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-for="(item, index) in gzzdList" :key="item.id">
|
|
|
+ <div class="card-item" @click="goToPage('/gzzd/index?folderId=' + item.id)">
|
|
|
+ <svg-icon icon-class="documentation" class="card-item-icon" />
|
|
|
+ <span class="card-text" :title="item.name">{{ item.name }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="3" v-if="!loadingGzzd && gzzdList.length === 0">
|
|
|
+ <div class="empty-text">暂无数据</div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- 通用添加对话框 -->
|
|
|
+ <el-dialog :title="addTitle" v-model="addVisible" width="480px" append-to-body>
|
|
|
+ <el-form ref="addFormRef" :model="addForm" :rules="addRules" label-width="90px">
|
|
|
+ <el-form-item :label="nameLabel" prop="name">
|
|
|
+ <el-input v-model="addForm.name" placeholder="必填项,请输入名称" maxlength="100" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item v-if="showPlanInput" label="设置进度">
|
|
|
+ <el-input-number v-model="addForm.planValue" :min="0" :max="100" style="width: 150px" />
|
|
|
+ <span style="margin-left: 8px;">%</span>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button type="primary" :loading="addSubmitting" @click="submitAdd">立即提交</el-button>
|
|
|
+ <el-button @click="resetAddForm">重置</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
import { ref, onMounted } from 'vue'
|
|
|
import { useRouter } from 'vue-router'
|
|
|
-import { folderList } from '@/api/efinder/finder'
|
|
|
+import { folderList, mkdir } from '@/api/efinder/finder'
|
|
|
+import { addProject } from '@/api/pms/addProject'
|
|
|
|
|
|
const router = useRouter()
|
|
|
+const { proxy } = getCurrentInstance()
|
|
|
|
|
|
const tpzItems = ref([])
|
|
|
const wyhItems = ref([])
|
|
|
@@ -152,10 +177,114 @@ const goToPage = (path) => {
|
|
|
router.push(path)
|
|
|
}
|
|
|
|
|
|
-const loadByCate = (cate, listRef, loadingRef) => {
|
|
|
+// 添加对话框
|
|
|
+const addVisible = ref(false)
|
|
|
+const addCate = ref('')
|
|
|
+const addFormRef = ref(null)
|
|
|
+const addForm = reactive({ name: '', planValue: 0 })
|
|
|
+const addRules = { name: [{ required: true, message: '名称不能为空', trigger: 'blur' }] }
|
|
|
+const addTitleMap = { tpz: '添加模块', wyh: '添加模块', zggc: '添加项目', zdgc: '添加分类', ddjc: '添加检查', gzzd: '添加记录' }
|
|
|
+const addTitle = computed(() => addTitleMap[addCate.value] || '添加')
|
|
|
+// 标签文字对齐旧版:项目(直管)/ 分类(重点/督导/规章)/ 文件夹(太浦/望亭)
|
|
|
+const nameLabelMap = { tpz: '文件夹名称', wyh: '文件夹名称', zggc: '项目名称', zdgc: '分类名称', ddjc: '分类名称', gzzd: '分类名称' }
|
|
|
+const nameLabel = computed(() => nameLabelMap[addCate.value] || '项目名称')
|
|
|
+// 进度仅直管工程显示(旧版 zggcPrarms=1 才显示)
|
|
|
+const showPlanInput = computed(() => addCate.value === 'zggc')
|
|
|
+
|
|
|
+function openAdd(cate) {
|
|
|
+ addCate.value = cate
|
|
|
+ addSubmitting.value = false
|
|
|
+ resetAddForm()
|
|
|
+ addVisible.value = true
|
|
|
+ nextTick(() => proxy.resetForm('addFormRef'))
|
|
|
+}
|
|
|
+
|
|
|
+function resetAddForm() {
|
|
|
+ addForm.name = ''
|
|
|
+ addForm.planValue = 0
|
|
|
+}
|
|
|
+
|
|
|
+const addSubmitting = ref(false)
|
|
|
+
|
|
|
+function submitAdd() {
|
|
|
+ if (addSubmitting.value) return
|
|
|
+ addFormRef.value.validate(valid => {
|
|
|
+ if (!valid) return
|
|
|
+ addSubmitting.value = true
|
|
|
+ // 直管工程:走 addProject 接口,自动创建子目录(工程概况/程序管理/... 对齐旧版)
|
|
|
+ if (addCate.value === 'zggc') {
|
|
|
+ addProject({
|
|
|
+ folderId: 0,
|
|
|
+ name: addForm.name,
|
|
|
+ zggcPrarms: '1',
|
|
|
+ planValues: String(addForm.planValue)
|
|
|
+ }).then(res => {
|
|
|
+ addSubmitting.value = false
|
|
|
+ if (res.code === 200) {
|
|
|
+ proxy.$modal.msgSuccess('添加成功')
|
|
|
+ addVisible.value = false
|
|
|
+ refreshByCate('zggc')
|
|
|
+ } else {
|
|
|
+ proxy.$modal.msgError(res.msg || '添加失败')
|
|
|
+ }
|
|
|
+ }).catch(() => {
|
|
|
+ addSubmitting.value = false
|
|
|
+ proxy.$modal.msgError('添加失败')
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 其余模块(重点工程分类/督导检查/规章制度/太浦闸/望亭闸):直接创建顶层文件夹
|
|
|
+ const data = { name: addForm.name, fdCate: addCate.value, pid: 0 }
|
|
|
+ mkdir(data).then(res => {
|
|
|
+ addSubmitting.value = false
|
|
|
+ if (res.code === 200) {
|
|
|
+ proxy.$modal.msgSuccess('添加成功')
|
|
|
+ addVisible.value = false
|
|
|
+ refreshByCate(addCate.value)
|
|
|
+ } else {
|
|
|
+ proxy.$modal.msgError(res.msg || '添加失败')
|
|
|
+ }
|
|
|
+ }).catch(() => {
|
|
|
+ addSubmitting.value = false
|
|
|
+ proxy.$modal.msgError('添加失败')
|
|
|
+ })
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function refreshByCate(cate) {
|
|
|
+ const map = {
|
|
|
+ tpz: [tpzItems, loadingTpz],
|
|
|
+ wyh: [wyhItems, loadingWyh],
|
|
|
+ zggc: [zggcList, loadingZggc],
|
|
|
+ zdgc: [zdgcList, loadingZdgc],
|
|
|
+ ddjc: [ddjcList, loadingDdjc],
|
|
|
+ gzzd: [gzzdList, loadingGzzd]
|
|
|
+ }
|
|
|
+ const [listRef, loadingRef] = map[cate] || []
|
|
|
+ // 首页统一只展示顶层(pid=0),子级目录(如阶段目录)不作为一级模块展示
|
|
|
+ if (listRef) loadByCate(cate, listRef, loadingRef, isTopLevel)
|
|
|
+}
|
|
|
+
|
|
|
+// 直管工程:状态判断(对齐原版 tba-slgc)
|
|
|
+function getZggcStatus(val) {
|
|
|
+ if (!val || val === 0) return '未开工'
|
|
|
+ if (val >= 100) return '已完工'
|
|
|
+ return '在建'
|
|
|
+}
|
|
|
+function getZggcStatusClass(val) {
|
|
|
+ if (!val || val === 0) return 'status-gray'
|
|
|
+ if (val >= 100) return 'status-blue'
|
|
|
+ return 'status-green'
|
|
|
+}
|
|
|
+
|
|
|
+// 重点工程:首页展示顶层分类(一轮治太/二轮治太/太湖流域片重大水利工程)
|
|
|
+const isTopLevel = (item) => !item.pid || item.pid === 0
|
|
|
+
|
|
|
+const loadByCate = (cate, listRef, loadingRef, filterFn) => {
|
|
|
loadingRef.value = true
|
|
|
folderList({ fdCate: cate, pageSize: 999 }).then(res => {
|
|
|
- listRef.value = res.rows || res.data || []
|
|
|
+ const list = res.rows || res.data || []
|
|
|
+ listRef.value = filterFn ? list.filter(item => filterFn(item, list)) : list
|
|
|
loadingRef.value = false
|
|
|
}).catch(() => {
|
|
|
listRef.value = []
|
|
|
@@ -164,37 +293,71 @@ const loadByCate = (cate, listRef, loadingRef) => {
|
|
|
}
|
|
|
|
|
|
onMounted(() => {
|
|
|
- loadByCate('tpz', tpzItems, loadingTpz)
|
|
|
- loadByCate('wyh', wyhItems, loadingWyh)
|
|
|
- loadByCate('zggc', zggcList, loadingZggc)
|
|
|
- loadByCate('zdgc', zdgcList, loadingZdgc)
|
|
|
- loadByCate('ddjc', ddjcList, loadingDdjc)
|
|
|
- loadByCate('gzzd', gzzdList, loadingGzzd)
|
|
|
+ // 首页所有模块统一只展示顶层(pid=0),子级目录不作为一级模块展示
|
|
|
+ loadByCate('tpz', tpzItems, loadingTpz, isTopLevel)
|
|
|
+ loadByCate('wyh', wyhItems, loadingWyh, isTopLevel)
|
|
|
+ loadByCate('zggc', zggcList, loadingZggc, isTopLevel)
|
|
|
+ loadByCate('zdgc', zdgcList, loadingZdgc, isTopLevel)
|
|
|
+ loadByCate('ddjc', ddjcList, loadingDdjc, isTopLevel)
|
|
|
+ loadByCate('gzzd', gzzdList, loadingGzzd, isTopLevel)
|
|
|
})
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
.home {
|
|
|
- padding: 16px;
|
|
|
+ padding: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 分区标题:图标 + 标题 + 渐变分隔线 */
|
|
|
+.section-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+ margin-bottom: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.section-icon {
|
|
|
+ width: 20px;
|
|
|
+ height: 20px;
|
|
|
+ color: #409eff;
|
|
|
+ flex-shrink: 0;
|
|
|
}
|
|
|
|
|
|
.section-title {
|
|
|
font-size: 18px;
|
|
|
font-weight: 600;
|
|
|
color: #303133;
|
|
|
+ white-space: nowrap;
|
|
|
+}
|
|
|
+
|
|
|
+.section-line {
|
|
|
+ flex: 1;
|
|
|
+ height: 1px;
|
|
|
+ background: linear-gradient(to right, #e4e7ed, transparent);
|
|
|
}
|
|
|
|
|
|
.home-card {
|
|
|
- margin-bottom: 20px;
|
|
|
- border-radius: 8px;
|
|
|
+ margin-bottom: 24px;
|
|
|
+ border-radius: 10px;
|
|
|
+ border: 1px solid #ebeef5;
|
|
|
}
|
|
|
|
|
|
+.home-card :deep(.el-card__body) {
|
|
|
+ padding: 16px 16px 12px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 通用卡片:白底 + 左色条 + hover 上浮 */
|
|
|
.card-item {
|
|
|
- height: 40px;
|
|
|
- line-height: 40px;
|
|
|
- text-align: center;
|
|
|
+ height: 44px;
|
|
|
+ line-height: 44px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 6px;
|
|
|
+ background: #fff;
|
|
|
border: 1px solid #ebeef5;
|
|
|
- border-radius: 6px;
|
|
|
+ border-left: 3px solid #409eff;
|
|
|
+ border-radius: 8px;
|
|
|
cursor: pointer;
|
|
|
transition: all 0.25s;
|
|
|
font-size: 13px;
|
|
|
@@ -203,68 +366,153 @@ onMounted(() => {
|
|
|
overflow: hidden;
|
|
|
text-overflow: ellipsis;
|
|
|
margin: 4px 0;
|
|
|
+ padding: 0 8px;
|
|
|
}
|
|
|
|
|
|
.card-item:hover {
|
|
|
- background-color: #ecf5ff;
|
|
|
+ transform: translateY(-2px);
|
|
|
+ box-shadow: 0 4px 12px rgba(64, 158, 255, 0.15);
|
|
|
border-color: #409eff;
|
|
|
color: #409eff;
|
|
|
}
|
|
|
|
|
|
+.card-index {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #a8abb2;
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.card-text {
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+}
|
|
|
+
|
|
|
+.card-item-icon {
|
|
|
+ width: 14px;
|
|
|
+ height: 14px;
|
|
|
+ flex-shrink: 0;
|
|
|
+ color: #409eff;
|
|
|
+}
|
|
|
+
|
|
|
+/* 项目卡片容器(直管工程与重点工程高度统一为 60px) */
|
|
|
.project-item {
|
|
|
height: 60px;
|
|
|
- background: linear-gradient(135deg, #67c23a, #85ce61);
|
|
|
- border-radius: 6px;
|
|
|
+ background: #fff;
|
|
|
+ border: 1px solid #e4e7ed;
|
|
|
+ border-radius: 10px;
|
|
|
cursor: pointer;
|
|
|
transition: all 0.25s;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- padding: 5px;
|
|
|
+ position: relative;
|
|
|
margin: 4px 0;
|
|
|
+ overflow: hidden;
|
|
|
}
|
|
|
|
|
|
.project-item:hover {
|
|
|
- background: linear-gradient(135deg, #5daf34, #74bd52);
|
|
|
- transform: translateY(-2px);
|
|
|
- box-shadow: 0 4px 12px rgba(103, 194, 58, 0.3);
|
|
|
+ transform: translateY(-3px);
|
|
|
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
|
|
|
}
|
|
|
|
|
|
-.project-name {
|
|
|
- color: #fff;
|
|
|
- font-size: 12px;
|
|
|
- text-align: center;
|
|
|
+/* 直管工程进度条:蓝灰双色条铺满整个卡片 */
|
|
|
+.zggc-bar {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.zggc-text {
|
|
|
+ position: absolute;
|
|
|
+ left: 8%;
|
|
|
+ top: 50%;
|
|
|
+ transform: translateY(-50%);
|
|
|
+ color: #434342;
|
|
|
+ font-size: 13px;
|
|
|
+ font-weight: 600;
|
|
|
white-space: nowrap;
|
|
|
overflow: hidden;
|
|
|
text-overflow: ellipsis;
|
|
|
- width: 100%;
|
|
|
+ max-width: 68%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 3px;
|
|
|
+ z-index: 1;
|
|
|
+ background: rgba(255, 255, 255, 0.75);
|
|
|
+ border-radius: 12px;
|
|
|
+ padding: 3px 10px;
|
|
|
}
|
|
|
|
|
|
-.ddjc-item {
|
|
|
- height: 40px;
|
|
|
- line-height: 40px;
|
|
|
- text-align: center;
|
|
|
- border: 1px solid #ebeef5;
|
|
|
- border-radius: 6px;
|
|
|
- cursor: pointer;
|
|
|
- transition: all 0.25s;
|
|
|
- font-size: 12px;
|
|
|
- color: #606266;
|
|
|
- white-space: nowrap;
|
|
|
+.zggc-name {
|
|
|
overflow: hidden;
|
|
|
text-overflow: ellipsis;
|
|
|
- margin: 4px 0;
|
|
|
+ white-space: nowrap;
|
|
|
}
|
|
|
|
|
|
-.ddjc-item:hover {
|
|
|
- background-color: #ecf5ff;
|
|
|
- border-color: #409eff;
|
|
|
- color: #409eff;
|
|
|
+.zggc-pct {
|
|
|
+ flex-shrink: 0;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 12px;
|
|
|
+ background: rgba(0, 0, 0, 0.25);
|
|
|
+ border-radius: 8px;
|
|
|
+ padding: 1px 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.project-icon {
|
|
|
+ width: 14px;
|
|
|
+ height: 14px;
|
|
|
+ flex-shrink: 0;
|
|
|
+ color: #0f69dc;
|
|
|
+}
|
|
|
+
|
|
|
+/* 状态标签(右上角) */
|
|
|
+.status-tag {
|
|
|
+ position: absolute;
|
|
|
+ top: 8px;
|
|
|
+ right: 8px;
|
|
|
+ font-size: 11px;
|
|
|
+ padding: 1px 8px;
|
|
|
+ border-radius: 10px;
|
|
|
+ color: #fff;
|
|
|
+ z-index: 2;
|
|
|
+}
|
|
|
+
|
|
|
+.status-blue {
|
|
|
+ background: rgba(15, 105, 220, 0.8);
|
|
|
+}
|
|
|
+
|
|
|
+.status-green {
|
|
|
+ background: #6cdcf0;
|
|
|
+}
|
|
|
+
|
|
|
+.status-gray {
|
|
|
+ background: #c0c4cc;
|
|
|
+}
|
|
|
+
|
|
|
+/* 重点工程:分类卡片(旧版逻辑:分类无 type 走 else 分支 → 灰色) */
|
|
|
+.zdgc-card {
|
|
|
+ height: 60px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 0 10px;
|
|
|
+ border: none;
|
|
|
+ background: rgb(212, 212, 212);
|
|
|
+}
|
|
|
+
|
|
|
+.zdgc-name {
|
|
|
+ color: #434342;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 600;
|
|
|
+ margin-left: 8%;
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ width: 88%;
|
|
|
}
|
|
|
|
|
|
.empty-text {
|
|
|
- height: 40px;
|
|
|
- line-height: 40px;
|
|
|
+ height: 44px;
|
|
|
+ line-height: 44px;
|
|
|
text-align: center;
|
|
|
color: #909399;
|
|
|
font-size: 14px;
|