明树Git Lab

Commit 1d2b693a authored by chenron's avatar chenron

角色管理

parent 89517cb8
...@@ -6,17 +6,25 @@ ...@@ -6,17 +6,25 @@
<div class="card-value-top"> <div class="card-value-top">
<div> <div>
<p class="pro-title">{{ item.protitle }}</p> <p class="pro-title">{{ item.protitle }}</p>
<p class="pro-value">{{ item.proValue }}<span>亿元</span></p> <p class="pro-value">
{{ item.proValue }}<span v-if="item.proValue !== '*'">亿元</span>
</p>
</div> </div>
<div> <div>
<p class="pro-title">{{ item.thirdTtile }}</p> <p class="pro-title">{{ item.thirdTtile }}</p>
<p class="pro-value">{{ item.thirdValue }}<span>亿元</span></p> <p class="pro-value">
{{ item.thirdValue }}
<span v-if="item.thirdValue !== '*'">亿元</span>
</p>
</div> </div>
</div> </div>
<div class="card-value-bottom"> <div class="card-value-bottom">
<div> <div>
<p class="pro-title">2025年累计完成</p> <p class="pro-title">2025年累计完成</p>
<p class="pro-value">112.1<span>亿元</span></p> <p class="pro-value">
{{ item.cumulativeValue
}}<span v-if="item.cumulativeValue !== '*'">亿元</span>
</p>
</div> </div>
<div class="value-bottom-right"> <div class="value-bottom-right">
<p class="comparison">累计同期环比</p> <p class="comparison">累计同期环比</p>
...@@ -29,8 +37,14 @@ ...@@ -29,8 +37,14 @@
class="trend-icon" class="trend-icon"
:class="{ 'down-trend': item.title === '运营成本' }" :class="{ 'down-trend': item.title === '运营成本' }"
> >
<Bottom v-if="item.title === '运营成本'" /> <span v-if="item.compareValue !== '*'">
<Bottom
v-if="
item.title === '运营成本' || item.title === '利润总额'
"
/>
<Top v-else /> <Top v-else />
</span>
</el-icon> </el-icon>
</p> </p>
</div> </div>
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
</template> </template>
<script setup> <script setup>
import AMapLoader from "@amap/amap-jsapi-loader"; import AMapLoader from "@amap/amap-jsapi-loader";
import { nextTick, onMounted, ref } from "vue"; import { nextTick, onMounted, reactive, ref } from "vue";
import gansuLine from "./newLine.json"; import gansuLine from "./newLine.json";
let map = null; let map = null;
window._AMapSecurityConfig = { window._AMapSecurityConfig = {
...@@ -13,6 +13,7 @@ window._AMapSecurityConfig = { ...@@ -13,6 +13,7 @@ window._AMapSecurityConfig = {
}; };
// 初始化地图 // 初始化地图
const handleInitMap = () => { const handleInitMap = () => {
let selectName = sessionStorage.getItem("selectedContentBtn");
AMapLoader.load({ AMapLoader.load({
key: "c691971f068b92c897fb908c4ddef6d4", // 申请好的Web端开发者Key key: "c691971f068b92c897fb908c4ddef6d4", // 申请好的Web端开发者Key
version: "2.0", version: "2.0",
...@@ -38,7 +39,7 @@ const handleInitMap = () => { ...@@ -38,7 +39,7 @@ const handleInitMap = () => {
// }); // });
handleDistrict(); handleDistrict();
addPolylines(); addPolylines();
handleAddMarket(); handleAddMarket(selectName);
}) })
.catch((e) => { .catch((e) => {
// console.log(e); // console.log(e);
...@@ -163,80 +164,85 @@ const addPolylines = () => { ...@@ -163,80 +164,85 @@ const addPolylines = () => {
map.add(geojsonObj); map.add(geojsonObj);
}; };
// 添加标记 // 添加标记
const handleAddMarket = () => { let currentMarkers = []; // 存储当前显示的标记
const markers = []; const handleAddMarket = (selectName) => {
const positionsList = [ // 清除之前的所有标记
{ if (currentMarkers.length > 0) {
number: 1, map.remove(currentMarkers);
position: [116.405467, 39.907761], currentMarkers = [];
}, }
{
number: 5, // 根据不同状态定义标记数据
position: [114.298569, 30.584354], const markerData = {
}, 建设: [
{ // 安徽
number: 6, { number: 1, position: [117.27, 31.86] },
position: [117.190186, 39.125595], // 广东
}, { number: 1, position: [113.2806, 23.1252] },
{ // 陕西
number: 4, { number: 2, position: [112.5492, 37.857] },
position: [112.549248, 37.857014], // 广西
}, { number: 2, position: [108.3664, 22.8177] },
{ // 山东
number: 8, { number: 2, position: [121.6167, 38.9167] },
position: [123.429092, 41.796768], // 河北
}, { number: 1, position: [114.52, 38.05] },
{ ],
number: 2, 试运营: [
position: [121.472641, 31.231707], // 四川
}, { number: 2, position: [117.27, 31.86] },
{ // 山东
number: 7, { number: 3, position: [121.6167, 38.9167] },
position: [119.306236, 26.075302], // 云南
}, { number: 1, position: [102.7333, 25.05] },
{ // 陕西
number: 9, { number: 3, position: [112.5492, 37.857] },
position: [106.504959, 29.533155], // 广西
}, { number: 1, position: [108.3664, 22.8177] },
{ // 湖北
number: 6, { number: 1, position: [114.3052, 30.5929] },
position: [91.1145, 29.64415], ],
}, 运营: [
{ // 四川
number: 3, { number: 1, position: [117.27, 31.86] },
position: [101.77782, 36.61729], // 山东
}, { number: 1, position: [121.6167, 38.9167] },
{ // 湖北
number: 8, { number: 1, position: [114.3052, 30.5929] },
position: [87.61688, 43.82663], ],
}, 退出: [
{ // 河南
number: 10, { number: 3, position: [113.65, 34.7667] },
position: [111.75199, 40.84149], ],
}, 立项: [], // 立项没有标记
{ };
number: 9,
position: [126.642464, 45.756966],
},
];
for (var i = 0, marker; i < positionsList.length; i++) { const positionsList = markerData[selectName] || [];
marker = new AMap.Marker({
// 创建新的标记
for (var i = 0; i < positionsList.length; i++) {
const marker = new AMap.Marker({
map: map, map: map,
position: positionsList[i].position, position: positionsList[i].position,
// icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
offset: new AMap.Pixel(-13, -30), offset: new AMap.Pixel(-13, -30),
content: content:
"" +
'<div class="custom-content-marker">' + '<div class="custom-content-marker">' +
'<img src="//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png">' + '<img src="//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png">' +
`<div class="anchorPoint"">${positionsList[i].number}</div>` + `<div class="anchorPoint">${positionsList[i].number}</div>` +
"</div>", "</div>",
}); });
markers.push(marker); currentMarkers.push(marker);
} }
map.add([markers]);
}; };
// 暴露更新标记的方法给父组件
const updateMarkers = (selectName) => {
handleAddMarket(selectName);
};
// 暴露方法给父组件
defineExpose({
updateMarkers,
});
onMounted(() => { onMounted(() => {
handleInitMap(); handleInitMap();
}); });
......
...@@ -6,11 +6,16 @@ ...@@ -6,11 +6,16 @@
<div class="amount"> <div class="amount">
<div> <div>
<p class="amount-title">实际完成金额</p> <p class="amount-title">实际完成金额</p>
<p class="amount-value">2.87<span>亿元</span></p> <p class="amount-value">
{{ item.actualValue
}}<span v-if="item.actualValue !== '*'">亿元</span>
</p>
</div> </div>
<div> <div>
<p class="amount-title">计划完成金额</p> <p class="amount-title">计划完成金额</p>
<p class="amount-value">4.21<span>亿元</span></p> <p class="amount-value">
{{ item.planValue }}<span v-if="item.planValue !== '*'">亿元</span>
</p>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -137,12 +137,16 @@ onMounted(() => {}); ...@@ -137,12 +137,16 @@ onMounted(() => {});
display: flex; display: flex;
.stat-card { .stat-card {
.vw(width, 180); .vw(width, 180);
.vh(height, 90);
.vw(border-radius, 5); .vw(border-radius, 5);
.vw(padding, 10); .vw(padding, 10);
.vw(margin-right,10); .vw(margin-right,10);
background-image: url("@/assets/images/total2.png"); background-image: url("@/assets/images/total2.png");
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: contain; background-size: 100% 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
.stat-card-title { .stat-card-title {
.font(12); .font(12);
} }
......
...@@ -394,7 +394,10 @@ ...@@ -394,7 +394,10 @@
</el-row> </el-row>
<!-- 表单操作按钮 --> <!-- 表单操作按钮 -->
<el-form-item v-if="config.showButtons !== false"> <el-form-item v-if="config.showButtons !== false" class="form-buttons">
<el-button v-if="config.showReset !== false" @click="handleReset">
{{ config.resetText || "重置" }}
</el-button>
<el-button <el-button
v-if="config.showSubmit !== false" v-if="config.showSubmit !== false"
type="primary" type="primary"
...@@ -403,9 +406,6 @@ ...@@ -403,9 +406,6 @@
> >
{{ config.submitText || "提交" }} {{ config.submitText || "提交" }}
</el-button> </el-button>
<el-button v-if="config.showReset !== false" @click="handleReset">
{{ config.resetText || "重置" }}
</el-button>
<el-button <el-button
v-for="btn in config.customButtons" v-for="btn in config.customButtons"
:key="btn.key" :key="btn.key"
...@@ -697,6 +697,14 @@ onMounted(() => { ...@@ -697,6 +697,14 @@ onMounted(() => {
margin-bottom: 18px; margin-bottom: 18px;
} }
.form-buttons {
:deep(.el-form-item__content) {
display: flex;
justify-content: flex-end;
gap: 10px;
}
}
:deep(.el-input-number) { :deep(.el-input-number) {
width: 100%; width: 100%;
} }
...@@ -715,7 +723,7 @@ onMounted(() => { ...@@ -715,7 +723,7 @@ onMounted(() => {
:deep(.el-form-item) { :deep(.el-form-item) {
&:last-child { &:last-child {
.el-form-item__content { .el-form-item__content {
justify-content: flex-end; // justify-content: flex-end;
} }
} }
} }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<el-table <el-table
style="width: 100%" style="width: 100%"
:data="tableData" :data="tableData"
:height="tableHeight" :height="computedTableHeight"
:max-height="maxHeight" :max-height="maxHeight"
:stripe="stripe" :stripe="stripe"
border border
...@@ -170,6 +170,21 @@ const props = defineProps({ ...@@ -170,6 +170,21 @@ const props = defineProps({
type: [String, Number], type: [String, Number],
default: "auto", default: "auto",
}, },
// 是否自动计算表格高度
autoHeight: {
type: Boolean,
default: false,
},
// 自动计算时的最大显示行数
maxRows: {
type: Number,
default: 10,
},
// 行高(像素)
rowHeight: {
type: Number,
default: 45,
},
// 表格最大高度 // 表格最大高度
maxHeight: [String, Number], maxHeight: [String, Number],
// 是否为斑马纹表格 // 是否为斑马纹表格
...@@ -375,6 +390,23 @@ const tableData = computed(() => { ...@@ -375,6 +390,23 @@ const tableData = computed(() => {
return props.data; return props.data;
}); });
// 自动计算表格高度
const computedTableHeight = computed(() => {
if (!props.autoHeight) {
return props.tableHeight;
}
const headerHeight = 50;
const paginationHeight = props.pagination ? 50 : 0;
const baseHeight = headerHeight + paginationHeight;
// 如果数据超过最大行数,固定显示最大行数的高度;如果数据不超过最大行数,按实际行数计算高度
const actualRows = Math.min(tableData.value.length, props.maxRows);
const contentHeight = actualRows * props.rowHeight;
return `${baseHeight + contentHeight}px`;
});
// 监听器 // 监听器
watch( watch(
() => props.currentPage, () => props.currentPage,
......
...@@ -65,6 +65,13 @@ const routes = [ ...@@ -65,6 +65,13 @@ const routes = [
title: 'roleManage', title: 'roleManage',
component: () => import('@/views/systemManage/roleManage.vue'), component: () => import('@/views/systemManage/roleManage.vue'),
meta: { menuName: '角色管理',} meta: { menuName: '角色管理',}
},
{
path: '/systemManage/menuManage',
name: '菜单管理',
title: 'menuManage',
component: () => import('@/views/systemManage/menuManage.vue'),
meta: { menuName: '菜单管理',}
} }
] ]
}, },
......
...@@ -44,29 +44,36 @@ ...@@ -44,29 +44,36 @@
<script setup> <script setup>
import Map from "@/components/CommonMap.vue"; import Map from "@/components/CommonMap.vue";
import CommonTotal from "@/components/CommonTotal.vue"; import CommonTotal from "@/components/CommonTotal.vue";
import { reactive, ref, onMounted, onUnmounted, shallowReactive, defineOptions } from "vue"; import {
reactive,
ref,
onMounted,
onUnmounted,
shallowReactive,
defineOptions,
} from "vue";
import CircleProgress from "./CircleProgress.vue"; import CircleProgress from "./CircleProgress.vue";
// 定义组件名称,用于keep-alive缓存 // 定义组件名称,用于keep-alive缓存
defineOptions({ defineOptions({
name: 'Construct' name: "Construct",
}); });
// 使用shallowReactive减少深层响应式开销 // 使用shallowReactive减少深层响应式开销
const projectList = shallowReactive([ const projectList = shallowReactive([
{ title: "总个数(个)", value: "59" }, { title: "总个数(个)", value: "10" },
{ title: "总投资(亿元)", value: "2733.35" }, { title: "总投资(亿元)", value: "1334.05" },
{ title: "总规模(公里)", value: "5116.72" }, { title: "总规模(公里)", value: "1051.56" },
]); ]);
const investmentList = shallowReactive([ const investmentList = shallowReactive([
{ title: "10月完成投资(亿元)", value: "0" }, { title: "10月完成投资(亿元)", value: "*" },
{ title: "2025年完成投资(亿元)", value: "19.725" }, { title: "2025年完成投资(亿元)", value: "*" },
{ title: "累计完成投资(亿元)", value: "807.56" }, { title: "累计完成投资(亿元)", value: "*" },
]); ]);
// recycleList // recycleList
const recycleList = shallowReactive([ const recycleList = shallowReactive([
{ title: "10月完成投资(亿元)", value: "0" }, { title: "10月完成投资(亿元)", value: "*" },
{ title: "2025年完成投资(亿元)", value: "2.98" }, { title: "2025年完成投资(亿元)", value: "*" },
{ title: "完成率", value: "50.2%" }, { title: "完成率", value: "*" },
]); ]);
</script> </script>
...@@ -120,7 +127,7 @@ const recycleList = shallowReactive([ ...@@ -120,7 +127,7 @@ const recycleList = shallowReactive([
font-family: "DIN"; font-family: "DIN";
} }
.progress-image { .progress-image {
.vw(width,520); .vw(width,430);
.vh(height,85); .vh(height,85);
background-image: url("@/assets/images/箭头.png"); background-image: url("@/assets/images/箭头.png");
background-repeat: no-repeat; background-repeat: no-repeat;
......
...@@ -38,57 +38,66 @@ import Map from "@/components/CommonMap.vue"; ...@@ -38,57 +38,66 @@ import Map from "@/components/CommonMap.vue";
import CommonTotal from "@/components/CommonTotal.vue"; import CommonTotal from "@/components/CommonTotal.vue";
import CommonComplete from "@/components/CommonComplete.vue"; import CommonComplete from "@/components/CommonComplete.vue";
import CommonPlant from "@/components/CommonPlant.vue"; import CommonPlant from "@/components/CommonPlant.vue";
import { shallowReactive, ref, onMounted, onUnmounted, defineOptions } from "vue"; import {
shallowReactive,
ref,
onMounted,
onUnmounted,
defineOptions,
} from "vue";
// 定义组件名称,用于keep-alive缓存 // 定义组件名称,用于keep-alive缓存
defineOptions({ defineOptions({
name: 'Operation' name: "Operation",
}); });
// 使用shallowReactive减少深层响应式开销 // 使用shallowReactive减少深层响应式开销
const projectList = shallowReactive([ const projectList = shallowReactive([
{ title: "总个数(个)", value: "59" }, { title: "总个数(个)", value: "2" },
{ title: "总投资(亿元)", value: "2733.35" }, { title: "总投资(亿元)", value: "114.23" },
{ title: "总规模(公里)", value: "5116.72" }, { title: "总规模(公里)", value: "233.22" },
]); ]);
const investmentList = shallowReactive([ const investmentList = shallowReactive([
{ title: "10月完成投资(亿元)", value: "0" }, { title: "10月完成投资(亿元)", value: "*" },
{ title: "2025年完成投资(亿元)", value: "19.725" }, { title: "2025年完成投资(亿元)", value: "*" },
{ title: "累计完成投资(亿元)", value: "807.56" }, { title: "累计完成投资(亿元)", value: "*" },
]); ]);
const recycleList = shallowReactive([ const recycleList = shallowReactive([
{ title: "10月完成投资(亿元)", value: "0" }, { title: "10月完成投资(亿元)", value: "*" },
{ title: "2025年完成投资(亿元)", value: "2.98" }, { title: "2025年完成投资(亿元)", value: "*" },
{ title: "完成率", value: "50.2%" }, { title: "完成率", value: "*" },
]); ]);
const operationList = shallowReactive([ const operationList = shallowReactive([
{ title: "营业收入完成进度", value: "68.1%" }, { title: "营业收入完成进度", value: "*", actualValue: "*", planValue: "*" },
{ title: "运营成本完成进度", value: "68.1%" }, { title: "运营成本完成进度", value: "*", actualValue: "*", planValue: "*" },
{ title: "利润总额完成进度", value: "68.1%" }, { title: "利润总额完成进度", value: "*", actualValue: "*", planValue: "*" },
]); ]);
const completeList = shallowReactive([ const completeList = shallowReactive([
{ {
title: "营业收入", title: "营业收入",
protitle: "11月完成", protitle: "11月完成",
proValue: "1.1", proValue: "*",
thirdTtile: "第三季度完成", thirdTtile: "第三季度完成",
thirdValue: "4.21", thirdValue: "*",
compareValue: "+1.2%", compareValue: "*",
cumulativeValue: "*",
}, },
{ {
title: "运营成本", title: "运营成本",
protitle: "11月完成", protitle: "11月完成",
proValue: "47.98", proValue: "*",
thirdTtile: "第三季度完成", thirdTtile: "第三季度完成",
thirdValue: "5.75", thirdValue: "*",
compareValue: "-0.5%", compareValue: "*",
cumulativeValue: "*",
}, },
{ {
title: "利润总额", title: "利润总额",
protitle: "11月完成", protitle: "11月完成",
proValue: "9.90", proValue: "*",
thirdTtile: "第三季度完成", thirdTtile: "第三季度完成",
thirdValue: "23.52", thirdValue: "*",
compareValue: "+1.2%", compareValue: "*",
cumulativeValue: "*",
}, },
]); ]);
</script> </script>
......
...@@ -2,17 +2,25 @@ ...@@ -2,17 +2,25 @@
<div class="project-container"> <div class="project-container">
<CommonTotal :numberList="initiationList" /> <CommonTotal :numberList="initiationList" />
</div> </div>
<Map /> <Map ref="mapRef" />
</template> </template>
<script setup> <script setup>
import CommonTotal from "@/components/CommonTotal.vue"; import CommonTotal from "@/components/CommonTotal.vue";
import Map from "@/components/CommonMap.vue"; import Map from "@/components/CommonMap.vue";
import { onMounted, reactive, watch, ref, computed, shallowRef, defineOptions } from "vue"; import {
onMounted,
reactive,
watch,
ref,
computed,
shallowRef,
defineOptions,
} from "vue";
// 定义组件名称,用于keep-alive缓存 // 定义组件名称,用于keep-alive缓存
defineOptions({ defineOptions({
name: 'ProjectApproval' name: "ProjectApproval",
}); });
const props = defineProps({ const props = defineProps({
...@@ -21,12 +29,14 @@ const props = defineProps({ ...@@ -21,12 +29,14 @@ const props = defineProps({
default: "立项", default: "立项",
}, },
}); });
const mapRef = ref(null);
// 使用静态数据避免重复创建 // 使用静态数据避免重复创建
const STATIC_DATA = { const STATIC_DATA = {
立项: [ 立项: [
{ title: "总个数(个)", value: "59" }, { title: "总个数(个)", value: "0" },
{ title: "总投资(亿元)", value: "2733.35" }, { title: "总投资(亿元)", value: "0" },
{ title: "总规模(公里)", value: "5116.72" }, { title: "总规模(公里)", value: "0" },
], ],
转让: [ 转让: [
{ title: "总个数(个)", value: "59" }, { title: "总个数(个)", value: "59" },
...@@ -35,10 +45,10 @@ const STATIC_DATA = { ...@@ -35,10 +45,10 @@ const STATIC_DATA = {
{ title: "累计完成投资(亿元)", value: "3116.44" }, { title: "累计完成投资(亿元)", value: "3116.44" },
], ],
退出: [ 退出: [
{ title: "总个数(个)", value: "59" }, { title: "总个数(个)", value: "3" },
{ title: "总投资(亿元)", value: "2733.35" }, { title: "总投资(亿元)", value: "141.29" },
{ title: "总规模(公里)", value: "5116.72" }, { title: "总规模(公里)", value: "108.35" },
{ title: "累计完成投资(亿元)", value: "3116.44" }, { title: "累计完成投资(亿元)", value: "0" },
], ],
}; };
...@@ -46,6 +56,18 @@ const STATIC_DATA = { ...@@ -46,6 +56,18 @@ const STATIC_DATA = {
const initiationList = computed(() => { const initiationList = computed(() => {
return STATIC_DATA[props.currentName] || STATIC_DATA.立项; return STATIC_DATA[props.currentName] || STATIC_DATA.立项;
}); });
// 监听props.currentName的变化
watch(
() => props.currentName,
(newValue, oldValue) => {
// 调用地图组件的updateMarkers方法来更新标记
if (mapRef.value && mapRef.value.updateMarkers) {
mapRef.value.updateMarkers(newValue);
}
},
{ immediate: true }
);
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
......
<template>
<div class="construct-container">
<div class="construct-left">
<div class="tag-image">
<img src="@/assets/images/建设.png" />
</div>
<div class="construct-left-map">
<Map />
</div>
</div>
<div class="construct-right">
<div>
<div class="info-title">项目概况</div>
<CommonTotal :numberList="projectList" />
</div>
<div>
<div class="info-title">投资完成情况</div>
<CommonTotal :numberList="investmentList" />
</div>
<div>
<div class="info-title">经营计划完成情况</div>
<CommonComplete :numberList="completeList" />
</div>
<div>
<div class="info-title">投资回收完成情况</div>
<CommonTotal :numberList="recycleList" />
</div>
<div>
<div class="info-title">2025年经营计划完成进度</div>
<CommonPlant :numberList="operationList" />
</div>
</div>
</div>
</template>
<script setup>
import Map from "@/components/CommonMap.vue";
import CommonTotal from "@/components/CommonTotal.vue";
import CommonComplete from "@/components/CommonComplete.vue";
import CommonPlant from "@/components/CommonPlant.vue";
import {
shallowReactive,
ref,
onMounted,
onUnmounted,
defineOptions,
} from "vue";
// 定义组件名称,用于keep-alive缓存
defineOptions({
name: "Operation",
});
// 使用shallowReactive减少深层响应式开销
const projectList = shallowReactive([
{ title: "总个数(个)", value: "9" },
{ title: "总投资(亿元)", value: "2733.35" },
{ title: "总规模(公里)", value: "5116.72" },
]);
const investmentList = shallowReactive([
{ title: "10月完成投资(亿元)", value: "*" },
{ title: "2025年完成投资(亿元)", value: "*" },
{ title: "累计完成投资(亿元)", value: "*" },
]);
const recycleList = shallowReactive([
{ title: "10月完成投资(亿元)", value: "*" },
{ title: "2025年完成投资(亿元)", value: "*" },
{ title: "完成率", value: "*" },
]);
const operationList = shallowReactive([
{
title: "营业收入完成进度",
value: "85.81%",
actualValue: "38.86",
planValue: "45.27",
},
{
title: "运营成本完成进度",
value: "79.60%",
actualValue: "20.91",
planValue: "26.27",
},
{
title: "利润总额完成进度",
value: "77.59%",
actualValue: "-7.94",
planValue: "-10.23",
},
]);
const completeList = shallowReactive([
{
title: "营业收入",
protitle: "11月完成",
proValue: "*",
thirdTtile: "第三季度完成",
thirdValue: "31.71",
compareValue: "+3.78%",
cumulativeValue: "38.86",
},
{
title: "运营成本",
protitle: "11月完成",
proValue: "*",
thirdTtile: "第三季度完成",
thirdValue: "16.99",
compareValue: "-14.73%",
cumulativeValue: "20.91",
},
{
title: "利润总额",
protitle: "11月完成",
proValue: "*",
thirdTtile: "第三季度完成",
thirdValue: "-5.91",
compareValue: "−28.83%",
cumulativeValue: "-7.94",
},
]);
</script>
<style scoped lang="less">
.construct-container {
display: flex;
.construct-left {
width: 100%;
height: 100%;
.tag-image {
img {
.vw(width, 85);
}
}
.construct-left-map {
.vh(height, 700);
.vh(padding-top, 4);
}
}
.construct-right {
display: flex;
flex-direction: column;
justify-content: space-between;
.info-title {
.vw(width, 180);
.vh(height, 30);
.vh(line-height, 30);
.font(16);
.vw(padding-left,20);
.vh(margin-bottom,15);
.vh(margin-top,15);
text-align: left;
color: #fff;
white-space: nowrap;
font-family: YouSheBiaoTiYuan;
background-image: url("@/assets/images/tag.png");
background-repeat: no-repeat;
background-size: cover;
background-position: center;
background-size: 100% 100%;
}
}
}
</style>
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
:class="{ active: selectedLeftBtn === 'risk' }" :class="{ active: selectedLeftBtn === 'risk' }"
@click="selectLeftBtn('risk')" @click="selectLeftBtn('risk')"
> >
固定风险投资 固定资产投资
</div> </div>
</div> </div>
<div class="header-middile"> <div class="header-middile">
...@@ -55,17 +55,14 @@ ...@@ -55,17 +55,14 @@
>{{ item.name }} >{{ item.name }}
</span> </span>
</div> </div>
<keep-alive include="ProjectApproval,Construct,Operation"> <keep-alive include="ProjectApproval,Construct,Operation,TrialOperations">
<ProjectApproval <ProjectApproval
:currentName="selectedContentName" :currentName="selectedContentName"
v-if=" v-if="selectedContentBtn === 1 || selectedContentBtn === 6"
selectedContentBtn === 1 ||
selectedContentBtn === 4 ||
selectedContentBtn === 5
"
/> />
<Construct v-else-if="selectedContentBtn === 2" /> <Construct v-else-if="selectedContentBtn === 2" />
<Operation v-else /> <Operation v-else-if="selectedContentBtn === 4" />
<TrialOperations v-else-if="selectedContentBtn === 3" />
</keep-alive> </keep-alive>
</div> </div>
<div class="bottom"></div> <div class="bottom"></div>
...@@ -76,7 +73,8 @@ ...@@ -76,7 +73,8 @@
import Construct from "./components/Construct.vue"; import Construct from "./components/Construct.vue";
import ProjectApproval from "./components/ProjectApproval.vue"; import ProjectApproval from "./components/ProjectApproval.vue";
import Operation from "./components/Operation.vue"; import Operation from "./components/Operation.vue";
import { reactive, ref, nextTick } from "vue"; import TrialOperations from "./components/trialOperations.vue";
import { reactive, ref, nextTick, watch, onMounted } from "vue";
const selectedLeftBtn = ref("equity"); const selectedLeftBtn = ref("equity");
const selectedRightBtn = ref(""); const selectedRightBtn = ref("");
...@@ -98,14 +96,18 @@ const navList = reactive([ ...@@ -98,14 +96,18 @@ const navList = reactive([
}, },
{ {
index: 3, index: 3,
name: "运营", name: "运营",
}, },
{ {
index: 4, index: 4,
name: "转让", name: "运营",
}, },
// {
// index: 5,
// name: "转让",
// },
{ {
index: 5, index: 6,
name: "退出", name: "退出",
}, },
]); ]);
...@@ -123,21 +125,14 @@ const selectRightBtn = (btn) => { ...@@ -123,21 +125,14 @@ const selectRightBtn = (btn) => {
// 添加防抖功能,避免频繁切换造成的性能问题 // 添加防抖功能,避免频繁切换造成的性能问题
let debounceTimer = null; let debounceTimer = null;
const selectContentBtn = (item) => { const selectContentBtn = (item) => {
// 清除之前的定时器
if (debounceTimer) { if (debounceTimer) {
clearTimeout(debounceTimer); clearTimeout(debounceTimer);
} }
// 使用防抖延迟切换
debounceTimer = setTimeout(() => { debounceTimer = setTimeout(() => {
selectedContentBtn.value = item.index; selectedContentBtn.value = item.index;
selectedContentName.value = item.name; selectedContentName.value = item.name;
sessionStorage.setItem("selectedContentBtn", selectedContentName.value);
// 使用nextTick确保DOM更新完成 }, 100);
nextTick(() => {
// 可以在这里添加其他需要延迟执行的逻辑
});
}, 100); // 100ms防抖延迟
}; };
// 暂时注释未使用的函数,避免lint警告 // 暂时注释未使用的函数,避免lint警告
...@@ -188,6 +183,11 @@ const toggleFullscreen = () => { ...@@ -188,6 +183,11 @@ const toggleFullscreen = () => {
isFullscreen.value = !isFullscreen.value; isFullscreen.value = !isFullscreen.value;
}; };
// 页面初始化时设置sessionStorage
onMounted(() => {
sessionStorage.setItem("selectedContentBtn", selectedContentName.value);
});
// 监听全屏变化事件 // 监听全屏变化事件
window.addEventListener("fullscreenchange", () => { window.addEventListener("fullscreenchange", () => {
if (!document.fullscreenElement) { if (!document.fullscreenElement) {
...@@ -348,7 +348,7 @@ window.addEventListener("fullscreenchange", () => { ...@@ -348,7 +348,7 @@ window.addEventListener("fullscreenchange", () => {
} }
// 退出按钮 // 退出按钮
:nth-child(5) { :nth-child(6) {
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 80% 80%; background-size: 80% 80%;
background-position: center; background-position: center;
...@@ -367,7 +367,8 @@ window.addEventListener("fullscreenchange", () => { ...@@ -367,7 +367,8 @@ window.addEventListener("fullscreenchange", () => {
// 中间按钮(建设、运营、转止) // 中间按钮(建设、运营、转止)
:nth-child(2), :nth-child(2),
:nth-child(3), :nth-child(3),
:nth-child(4) { :nth-child(4),
:nth-child(5) {
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 80% 80%; background-size: 80% 80%;
background-position: center; background-position: center;
...@@ -381,7 +382,7 @@ window.addEventListener("fullscreenchange", () => { ...@@ -381,7 +382,7 @@ window.addEventListener("fullscreenchange", () => {
background-image: url("@/assets/images/nav-hight-btn.png"); background-image: url("@/assets/images/nav-hight-btn.png");
} }
} }
:nth-child(5) { :nth-child(6) {
margin-left: -31px; margin-left: -31px;
} }
} }
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
<div class="depart-manage" v-loading="loading"> <div class="depart-manage" v-loading="loading">
<div class="search-origin"> <div class="search-origin">
<div class="origin-title"> <div class="origin-title">
<h3>组织列表</h3> <h3>部门列表</h3>
<span @click="handleAdd">+&nbsp; 新增组织</span> <!-- <span @click="handleAdd('parent')">+&nbsp; 新增组织</span> -->
</div> </div>
<el-input placeholder="请输入部门名称" clearable> <el-input placeholder="请输入部门名称" clearable>
<template #prefix> <template #prefix>
...@@ -18,6 +18,10 @@ ...@@ -18,6 +18,10 @@
</span> </span>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item @click="handleAdd"
><i class="iconfont icon-tianjia"></i
>添加组织</el-dropdown-item
>
<el-dropdown-item @click="handleOriginEdit" <el-dropdown-item @click="handleOriginEdit"
><i class="iconfont icon-bianji"></i ><i class="iconfont icon-bianji"></i
>编辑组织</el-dropdown-item >编辑组织</el-dropdown-item
...@@ -47,12 +51,14 @@ ...@@ -47,12 +51,14 @@
<el-input placeholder="请输入人员信息" v-model="userName" /> <el-input placeholder="请输入人员信息" v-model="userName" />
</div> </div>
<div> <div>
<el-button type="primary" @click="handleUserData">查询</el-button>
<el-button type="" @click="handleReset">重置</el-button> <el-button type="" @click="handleReset">重置</el-button>
<el-button type="primary" @click="handleUserData">查询</el-button>
</div> </div>
</div> </div>
<common-table <common-table
:tableHeight="tableHeight" :autoHeight="true"
:maxRows="10"
:rowHeight="40"
:data="tableData" :data="tableData"
:columns="tableColumns" :columns="tableColumns"
:total="total" :total="total"
...@@ -103,17 +109,6 @@ const originTreeData = ref([]); ...@@ -103,17 +109,6 @@ const originTreeData = ref([]);
const selectedNode = ref(null); const selectedNode = ref(null);
const userName = ref(""); const userName = ref("");
// 计算表格高度
const tableHeight = computed(() => {
const headerHeight = 50;
const paginationHeight = 50;
const rowHeight = 40;
const baseHeight = headerHeight + paginationHeight;
const maxRows = Math.min(tableData.value.length, 10);
const contentHeight = maxRows * rowHeight;
return `${baseHeight + contentHeight}px`;
});
// 数据转换函数 // 数据转换函数
const convertToTreeData = (apiData, type) => { const convertToTreeData = (apiData, type) => {
if (type === "id") { if (type === "id") {
...@@ -250,11 +245,12 @@ const handleCurrentPageChange = (page) => { ...@@ -250,11 +245,12 @@ const handleCurrentPageChange = (page) => {
const handleAdd = () => { const handleAdd = () => {
isEdit.value = false; isEdit.value = false;
dialogTitle.value = "新增组织"; dialogTitle.value = "新增组织";
dialogVisible.value = true;
console.log(selectedNode.value);
originForm.value = { originForm.value = {
parentId: "", parentId: "",
name: "", name: "",
}; };
dialogVisible.value = true;
}; };
let currentID = ref(""); let currentID = ref("");
// 处理树节点点击事件 // 处理树节点点击事件
...@@ -289,11 +285,12 @@ const handleOriginEdit = () => { ...@@ -289,11 +285,12 @@ const handleOriginEdit = () => {
}; };
// 组织删除 // 组织删除
const handleDeleteOrigin = () => { const handleDeleteOrigin = () => {
console.log(selectedNode.value);
if (selectedNode.value === null) { if (selectedNode.value === null) {
ElMessage.warning("请选择要删除的组织"); ElMessage.warning("请选择要删除的组织");
} else { } else {
const deleteItem = { const deleteItem = {
id: selectedNode.value.value, id: selectedNode.value.id,
name: selectedNode.value.label, name: selectedNode.value.label,
parentId: selectedNode.value.parentId parentId: selectedNode.value.parentId
? selectedNode.value.parentId ? selectedNode.value.parentId
...@@ -356,10 +353,12 @@ const handleFormSubmit = (formData) => { ...@@ -356,10 +353,12 @@ const handleFormSubmit = (formData) => {
const handleFormReset = () => { const handleFormReset = () => {
dialogVisible.value = false; dialogVisible.value = false;
selectedNode.value = "";
}; };
const handleDialogClose = () => { const handleDialogClose = () => {
dialogVisible.value = false; dialogVisible.value = false;
selectedNode.value = null;
}; };
const handleReset = () => { const handleReset = () => {
userName.value = ""; userName.value = "";
...@@ -466,6 +465,32 @@ onMounted(() => { ...@@ -466,6 +465,32 @@ onMounted(() => {
.tree-content { .tree-content {
margin-top: 20px; margin-top: 20px;
position: relative; position: relative;
.el-tree {
max-height: 700px;
overflow-y: auto;
// 只有当内容超过700px时才显示滚动条
&:not(:hover) {
scrollbar-width: none;
-ms-overflow-style: none;
&::-webkit-scrollbar {
display: none;
}
}
&:hover {
scrollbar-width: thin;
&::-webkit-scrollbar {
display: block;
width: 6px;
}
&::-webkit-scrollbar-thumb {
background-color: rgba(144, 147, 153, 0.3);
border-radius: 3px;
}
&::-webkit-scrollbar-track {
background-color: transparent;
}
}
}
} }
.table-container { .table-container {
......
This diff is collapsed.
...@@ -11,7 +11,9 @@ ...@@ -11,7 +11,9 @@
</div> </div>
<div class="table-container"> <div class="table-container">
<common-table <common-table
:tableHeight="tableHeight" :autoHeight="true"
:maxRows="10"
:rowHeight="40"
:data="tableData" :data="tableData"
:columns="tableColumns" :columns="tableColumns"
:total="total" :total="total"
...@@ -32,10 +34,7 @@ ...@@ -32,10 +34,7 @@
<el-button type="text" size="small" @click="handleDelete(row, index)"> <el-button type="text" size="small" @click="handleDelete(row, index)">
删除 删除
</el-button> </el-button>
<el-button type="text" size="small" @click="handleMenu(row, index)" <!-- <el-button type="text" size="small">数据权限 </el-button> -->
>菜单配置</el-button
>
<el-button type="text" size="small">数据权限 </el-button>
</template> </template>
</common-table> </common-table>
</div> </div>
...@@ -47,7 +46,7 @@ ...@@ -47,7 +46,7 @@
@close="handleDialogClose" @close="handleDialogClose"
> >
<commonForm <commonForm
v-model="userForm" v-model="roleForm"
:config="formConfig" :config="formConfig"
:items="formItems" :items="formItems"
:rules="formRules" :rules="formRules"
...@@ -55,7 +54,7 @@ ...@@ -55,7 +54,7 @@
@reset="handleFormReset" @reset="handleFormReset"
/> />
</el-dialog> </el-dialog>
<el-dialog v-model="menuVisible" title="菜单配置"> <!-- <el-dialog v-model="menuVisible" title="菜单配置">
<el-tree <el-tree
:data="treeData" :data="treeData"
show-checkbox show-checkbox
...@@ -63,13 +62,14 @@ ...@@ -63,13 +62,14 @@
node-key="id" node-key="id"
ref="tree" ref="tree"
highlight-current highlight-current
@node-click="handleNodeClick"
> >
</el-tree> </el-tree>
<template #footer> <template #footer>
<el-button type="primary" @click="hanldeSubmit">保存</el-button> <el-button type="primary" @click="hanldeSubmit">保存</el-button>
<el-button>取消</el-button> <el-button>取消</el-button>
</template> </template>
</el-dialog> </el-dialog> -->
</div> </div>
</template> </template>
...@@ -84,22 +84,12 @@ import { da } from "element-plus/es/locales.mjs"; ...@@ -84,22 +84,12 @@ import { da } from "element-plus/es/locales.mjs";
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const loading = ref(false); const loading = ref(false);
const treeData = ref([]); const treeData = ref([]);
const tree = ref(null);
// 计算表格高度
const tableHeight = computed(() => {
const headerHeight = 50;
const paginationHeight = 50;
const rowHeight = 40;
const baseHeight = headerHeight + paginationHeight;
const maxRows = Math.min(tableData.value.length, 10);
const contentHeight = maxRows * rowHeight;
return `${baseHeight + contentHeight}px`;
});
// 数据转换函数 // 数据转换函数
const convertToTreeData = (apiData) => { const convertToTreeData = (apiData) => {
return apiData.map((item) => ({ return apiData.map((item) => ({
id: item.id, value: item.id.toString(),
label: item.name, label: item.name,
children: item.children ? convertToTreeData(item.children) : [], children: item.children ? convertToTreeData(item.children) : [],
})); }));
...@@ -167,16 +157,14 @@ const tableColumns = [ ...@@ -167,16 +157,14 @@ const tableColumns = [
// 对话框相关 // 对话框相关
const dialogVisible = ref(false); const dialogVisible = ref(false);
const menuVisible = ref(false);
const dialogTitle = ref("新增角色"); const dialogTitle = ref("新增角色");
const isEdit = ref(false); const isEdit = ref(false);
const editIndex = ref(-1); const editIndex = ref(-1);
// 用户表单数据 // 用户表单数据
const userForm = ref({ const roleForm = ref({
name: "", name: "",
createdAt: "", menus: [],
updatedAt: "",
}); });
// 用户表单配置 // 用户表单配置
...@@ -199,17 +187,19 @@ const formItems = computed(() => [ ...@@ -199,17 +187,19 @@ const formItems = computed(() => [
rules: [{ required: true, message: "请输入角色名称", trigger: "blur" }], rules: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
}, },
{ {
type: "date", type: "tree",
prop: "createdAt", prop: "menus",
label: "创建时间", label: "菜单配置",
placeholder: "请输入创建时间", placeholder: "请选择菜单配置",
span: 24, data: treeData.value,
}, clearable: true,
{ filterable: true,
type: "date", checkStrictly: true,
prop: "updatedAt", renderAfterExpand: false,
label: "更新时间", showCheckbox: false,
placeholder: "请输入更新时间", multiple: true,
collapseTags: true,
maxCollapseTags: 2,
span: 24, span: 24,
}, },
]); ]);
...@@ -243,28 +233,35 @@ const handleCurrentPageChange = (page) => { ...@@ -243,28 +233,35 @@ const handleCurrentPageChange = (page) => {
loadTableData(); loadTableData();
}; };
// 树节点点击
const handleNodeClick = (data, node, element) => {
// console.log(data, "data");
// console.log(node, "node");
// console.log(element, "element");
};
// 新增用户 // 新增用户
const handleAdd = () => { const handleAdd = () => {
isEdit.value = false; isEdit.value = false;
dialogTitle.value = "新增用户"; dialogTitle.value = "新增用户";
userForm.value = { roleForm.value = {
name: "", name: "",
createdAt: "", menus: [],
updatedAt: "",
}; };
dialogVisible.value = true; dialogVisible.value = true;
}; };
let currentID = ref(); let currentID = ref();
let currentRow = ref();
// 编辑 // 编辑
const handleEdit = (row, index) => { const handleEdit = (row, index) => {
isEdit.value = true; isEdit.value = true;
dialogTitle.value = "编辑用户"; dialogTitle.value = "编辑用户";
editIndex.value = index; editIndex.value = index;
currentRow.value = row;
proxy.$post({ proxy.$post({
url: "/api/user/manage/getUserInfo", url: "/api/user/role/getRole",
data: { id: row.id }, data: { id: row.id },
callback: (data) => { callback: (data) => {
userForm.value = { ...data }; roleForm.value = { ...data };
currentID.value = data.id; currentID.value = data.id;
}, },
error: (err) => { error: (err) => {
...@@ -297,10 +294,6 @@ const handleDelete = async (row, index) => { ...@@ -297,10 +294,6 @@ const handleDelete = async (row, index) => {
loadTableData(); loadTableData();
} catch {} } catch {}
}; };
// 菜单配置
const handleMenu = () => {
menuVisible.value = true;
};
const handleFormSubmit = (formData) => { const handleFormSubmit = (formData) => {
if (isEdit.value) { if (isEdit.value) {
...@@ -308,6 +301,7 @@ const handleFormSubmit = (formData) => { ...@@ -308,6 +301,7 @@ const handleFormSubmit = (formData) => {
const updateUser = { const updateUser = {
...formData, ...formData,
id: currentID.value, id: currentID.value,
menus: Array.isArray(formData.menus) ? formData.menus : [],
}; };
proxy.$post({ proxy.$post({
url: "/api/user/role/updateRole", url: "/api/user/role/updateRole",
...@@ -315,10 +309,10 @@ const handleFormSubmit = (formData) => { ...@@ -315,10 +309,10 @@ const handleFormSubmit = (formData) => {
callback: (data) => { callback: (data) => {
dialogVisible.value = false; dialogVisible.value = false;
loadTableData(); loadTableData();
ElMessage.success("用户信息更新成功"); ElMessage.success("更新成功");
}, },
error: (err) => { error: (err) => {
ElMessage.error("用户信息更新失败:", err); ElMessage.error("更新失败:", err);
}, },
}); });
} else { } else {
...@@ -350,7 +344,18 @@ const handleDialogClose = () => { ...@@ -350,7 +344,18 @@ const handleDialogClose = () => {
}; };
const hanldeSubmit = () => { const hanldeSubmit = () => {
menuVisible.value = false; // 获取当前复选框选中的节点信息
const checkedNodes = tree.value?.getCheckedNodes();
const halfCheckedNodes = tree.value?.getHalfCheckedNodes();
// 获取选中节点的ID
const checkedIds = checkedNodes ? checkedNodes.map((node) => node.id) : [];
const halfCheckedIds = halfCheckedNodes
? halfCheckedNodes.map((node) => node.id)
: [];
// 合并所有选中的节点ID(完全选中和半选中的)
const allSelectedIds = [...checkedIds, ...halfCheckedIds];
}; };
// 表格数据 // 表格数据
const loadTableData = () => { const loadTableData = () => {
...@@ -382,7 +387,6 @@ const handleTreeData = () => { ...@@ -382,7 +387,6 @@ const handleTreeData = () => {
pageSize: pageSize.value, pageSize: pageSize.value,
}, },
callback: (data) => { callback: (data) => {
console.log(data, "234234");
treeData.value = convertToTreeData(data); treeData.value = convertToTreeData(data);
}, },
error: (err) => { error: (err) => {
...@@ -422,4 +426,29 @@ onMounted(() => { ...@@ -422,4 +426,29 @@ onMounted(() => {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
} }
} }
.el-tree {
max-height: 500px;
overflow-y: auto;
&:not(:hover) {
scrollbar-width: none;
-ms-overflow-style: none;
&::-webkit-scrollbar {
display: none;
}
}
&:hover {
scrollbar-width: thin;
&::-webkit-scrollbar {
display: block;
width: 6px;
}
&::-webkit-scrollbar-thumb {
background-color: rgba(144, 147, 153, 0.3);
border-radius: 3px;
}
&::-webkit-scrollbar-track {
background-color: transparent;
}
}
}
</style> </style>
...@@ -11,7 +11,9 @@ ...@@ -11,7 +11,9 @@
</div> </div>
<div class="table-container"> <div class="table-container">
<common-table <common-table
:tableHeight="tableHeight" :autoHeight="true"
:maxRows="10"
:rowHeight="40"
:data="tableData" :data="tableData"
:columns="tableColumns" :columns="tableColumns"
:total="total" :total="total"
...@@ -78,18 +80,7 @@ import { da } from "element-plus/es/locales.mjs"; ...@@ -78,18 +80,7 @@ import { da } from "element-plus/es/locales.mjs";
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const loading = ref(false); const loading = ref(false);
// 计算表格高度
const tableHeight = computed(() => {
const headerHeight = 50;
const paginationHeight = 50;
const rowHeight = 40;
const baseHeight = headerHeight + paginationHeight;
// 1.如果数据超过10条,固定显示10行的高度 + 滚动条;2.如果数据不超过10条,按实际行数计算高度
const maxRows = Math.min(tableData.value.length, 10);
const contentHeight = maxRows * rowHeight;
return `${baseHeight + contentHeight}px`;
});
// 数据转换函数 // 数据转换函数
const convertToTreeData = (apiData) => { const convertToTreeData = (apiData) => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment