明树Git Lab

Commit eef91c57 authored by chenron's avatar chenron

部门管理添加

parent 502ba659
@font-face {
font-family: "iconfont"; /* Project id 5072634 */
src: url('iconfont.woff2?t=1764314450961') format('woff2'),
url('iconfont.woff?t=1764314450961') format('woff'),
url('iconfont.ttf?t=1764314450961') format('truetype');
src: url('//at.alicdn.com/t/c/font_5072634_8c3g9zvwtne.woff2?t=1764660705764') format('woff2'),
url('//at.alicdn.com/t/c/font_5072634_8c3g9zvwtne.woff?t=1764660705764') format('woff'),
url('//at.alicdn.com/t/c/font_5072634_8c3g9zvwtne.ttf?t=1764660705764') format('truetype');
}
.iconfont {
......@@ -13,6 +13,26 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-gengduo:before {
content: "\e73a";
}
.icon-shanchu:before {
content: "\e8c1";
}
.icon-bianji:before {
content: "\e607";
}
.icon-tianjia:before {
content: "\e6ea";
}
.icon-gedian:before {
content: "\e603";
}
.icon-gongzuotai:before {
content: "\e605";
}
......@@ -20,4 +40,3 @@
.icon-quanping:before {
content: "\e62f";
}
window._iconfont_svg_string_5072634='<svg><symbol id="icon-gongzuotai" viewBox="0 0 1024 1024"><path d="M837.12 112.64H161.28c-43.52 0-76.8 35.84-76.8 76.8v468.48c0 43.52 35.84 76.8 76.8 76.8h276.48v156.16H215.04c-15.36 0-25.6 12.8-25.6 25.6 0 15.36 12.8 25.6 25.6 25.6h570.88c15.36 0 25.6-12.8 25.6-25.6 0-15.36-12.8-25.6-25.6-25.6h-243.2v-156.16h294.4c43.52 0 76.8-35.84 76.8-76.8V189.44c2.56-43.52-33.28-76.8-76.8-76.8z m25.6 545.28c0 15.36-12.8 25.6-25.6 25.6H161.28c-15.36 0-25.6-12.8-25.6-25.6V189.44c0-15.36 12.8-25.6 25.6-25.6h675.84c15.36 0 25.6 12.8 25.6 25.6v468.48z m0 0" ></path></symbol><symbol id="icon-quanping" viewBox="0 0 1024 1024"><path d="M181 357.5V181.2h176.4c14.3 0 25.9-11.6 25.9-25.9v-31.1c0-14.3-11.6-25.9-25.9-25.9H118c-11 0-20 9-20 20v239.4c0 14.3 11.6 25.9 25.9 25.9H155c14.4-0.1 26-11.7 26-26.1zM668.6 181.2H845v176.4c0 14.3 11.6 25.9 25.9 25.9H902c14.3 0 25.9-11.6 25.9-25.9V118.2c0-11-9-20-20-20H668.6c-14.3 0-25.9 11.6-25.9 25.9v31.1c0 14.3 11.6 26 25.9 26zM357.4 845.2H181V668.8c0-14.3-11.6-25.9-25.9-25.9H124c-14.3 0-25.9 11.6-25.9 25.9v239.4c0 11 9 20 20 20h239.4c14.3 0 25.9-11.6 25.9-25.9v-31.1c-0.1-14.4-11.7-26-26-26zM845 668.8v176.4H668.6c-14.3 0-25.9 11.6-25.9 25.9v31.1c0 14.3 11.6 25.9 25.9 25.9H908c11 0 20-9 20-20V668.8c0-14.3-11.6-25.9-25.9-25.9H871c-14.4 0-26 11.6-26 25.9z" ></path></symbol></svg>',(n=>{var t=(e=(e=document.getElementsByTagName("script"))[e.length-1]).getAttribute("data-injectcss"),e=e.getAttribute("data-disable-injectsvg");if(!e){var c,o,i,d,s,a=function(t,e){e.parentNode.insertBefore(t,e)};if(t&&!n.__iconfont__svg__cssinject__){n.__iconfont__svg__cssinject__=!0;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(t){console&&console.log(t)}}c=function(){var t,e=document.createElement("div");e.innerHTML=n._iconfont_svg_string_5072634,(e=e.getElementsByTagName("svg")[0])&&(e.setAttribute("aria-hidden","true"),e.style.position="absolute",e.style.width=0,e.style.height=0,e.style.overflow="hidden",e=e,(t=document.body).firstChild?a(e,t.firstChild):t.appendChild(e))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(c,0):(o=function(){document.removeEventListener("DOMContentLoaded",o,!1),c()},document.addEventListener("DOMContentLoaded",o,!1)):document.attachEvent&&(i=c,d=n.document,s=!1,r(),d.onreadystatechange=function(){"complete"==d.readyState&&(d.onreadystatechange=null,l())})}function l(){s||(s=!0,i())}function r(){try{d.documentElement.doScroll("left")}catch(t){return void setTimeout(r,50)}l()}})(window);
\ No newline at end of file
window._iconfont_svg_string_5072634='<svg><symbol id="icon-gengduo" viewBox="0 0 1024 1024"><path d="M223.962372 607.897867c-52.980346 0-95.983874-43.003528-95.983874-95.983874s43.003528-95.983874 95.983874-95.983874 95.983874 43.003528 95.983874 95.983874S276.942718 607.897867 223.962372 607.897867z" fill="#575B66" ></path><path d="M511.913993 607.897867c-52.980346 0-95.983874-43.003528-95.983874-95.983874s43.003528-95.983874 95.983874-95.983874 95.983874 43.003528 95.983874 95.983874S564.894339 607.897867 511.913993 607.897867z" fill="#575B66" ></path><path d="M800.037628 607.897867c-52.980346 0-95.983874-43.003528-95.983874-95.983874s43.003528-95.983874 95.983874-95.983874 95.983874 43.003528 95.983874 95.983874S852.84596 607.897867 800.037628 607.897867z" fill="#575B66" ></path></symbol><symbol id="icon-shanchu" viewBox="0 0 1024 1024"><path d="M106.666667 213.333333h810.666666v42.666667H106.666667z" fill="#3D3D3D" ></path><path d="M640 128v42.666667h42.666667V128c0-23.573333-19.093333-42.666667-42.538667-42.666667H383.872A42.496 42.496 0 0 0 341.333333 128v42.666667h42.666667V128h256z" fill="#3D3D3D" ></path><path d="M213.333333 896V256H170.666667v639.957333C170.666667 919.552 189.653333 938.666667 213.376 938.666667h597.248C834.218667 938.666667 853.333333 919.68 853.333333 895.957333V256h-42.666666v640H213.333333z" fill="#3D3D3D" ></path><path d="M320 341.333333h42.666667v384h-42.666667zM490.666667 341.333333h42.666666v384h-42.666666zM661.333333 341.333333h42.666667v384h-42.666667z" fill="#3D3D3D" ></path></symbol><symbol id="icon-bianji" viewBox="0 0 1024 1024"><path d="M153.6 902.656a32.256 32.256 0 0 1 0-64h716.8a32.256 32.256 0 0 1 0 64zM743.936 151.04l72.192 72.192a51.2 51.2 0 0 1 0 72.192L358.4 751.616a51.2 51.2 0 0 1-36.352 14.848H226.816a25.6 25.6 0 0 1-25.6-25.6v-97.792a51.2 51.2 0 0 1 14.848-36.352l455.68-455.68a51.2 51.2 0 0 1 72.192 0z m-478.72 497.152v54.272h54.272l442.88-442.88L708.096 204.8z" fill="#5A5A68" ></path></symbol><symbol id="icon-tianjia" viewBox="0 0 1024 1024"><path d="M924.9 337.6c-22.6-53.4-54.9-101.3-96-142.4-41.1-41.1-89.1-73.5-142.4-96-55.3-23.5-114-35.3-174.5-35.3S392.8 75.8 337.6 99.1c-53.4 22.6-101.3 54.9-142.4 96-41.1 41.1-73.5 89.1-96 142.4C75.8 392.8 64 451.5 64 512s11.9 119.2 35.2 174.4c22.6 53.4 54.9 101.3 96 142.4 41.1 41.1 89.1 73.5 142.4 96 55.3 23.4 114 35.2 174.5 35.2s119.2-11.9 174.4-35.2c53.4-22.6 101.3-54.9 142.4-96 41.1-41.1 73.5-89.1 96-142.4 23.4-55.3 35.2-114 35.2-174.4 0-60.5-11.8-119.2-35.2-174.4zM512 902.5c-215.3 0-390.5-175.2-390.5-390.5S296.7 121.5 512 121.5 902.5 296.7 902.5 512 727.3 902.5 512 902.5z" ></path><path d="M681.7 483.2H540.8v-141c0-15.9-12.9-28.8-28.8-28.8s-28.8 12.9-28.8 28.8v140.9h-141c-15.9 0-28.8 12.9-28.8 28.8s12.9 28.8 28.8 28.8h140.9v140.9c0 15.9 12.9 28.8 28.8 28.8s28.8-12.9 28.8-28.8V540.8h140.9c15.9 0 28.8-12.9 28.8-28.8 0.2-15.9-12.8-28.8-28.7-28.8z" ></path></symbol><symbol id="icon-gedian" viewBox="0 0 1024 1024"><path d="M371.29728 181.76A87.46752 87.46752 0 1 1 284.16 269.22752 87.296 87.296 0 0 1 371.29728 181.76z m278.84544 0a87.46752 87.46752 0 1 1-87.13984 87.46752A87.296 87.296 0 0 1 650.14272 181.76zM371.29728 461.65248A87.46752 87.46752 0 1 1 284.16 549.12a87.296 87.296 0 0 1 87.13728-87.46752z m278.84544 0a87.46752 87.46752 0 1 1-87.13984 87.46752 87.296 87.296 0 0 1 87.13984-87.46752zM371.29728 741.54752A87.46752 87.46752 0 1 1 284.16 829.01248a87.296 87.296 0 0 1 87.13728-87.46496z m278.84544 0a87.46752 87.46752 0 1 1-87.13984 87.46496 87.296 87.296 0 0 1 87.13984-87.46496z" ></path></symbol><symbol id="icon-gongzuotai" viewBox="0 0 1024 1024"><path d="M837.12 112.64H161.28c-43.52 0-76.8 35.84-76.8 76.8v468.48c0 43.52 35.84 76.8 76.8 76.8h276.48v156.16H215.04c-15.36 0-25.6 12.8-25.6 25.6 0 15.36 12.8 25.6 25.6 25.6h570.88c15.36 0 25.6-12.8 25.6-25.6 0-15.36-12.8-25.6-25.6-25.6h-243.2v-156.16h294.4c43.52 0 76.8-35.84 76.8-76.8V189.44c2.56-43.52-33.28-76.8-76.8-76.8z m25.6 545.28c0 15.36-12.8 25.6-25.6 25.6H161.28c-15.36 0-25.6-12.8-25.6-25.6V189.44c0-15.36 12.8-25.6 25.6-25.6h675.84c15.36 0 25.6 12.8 25.6 25.6v468.48z m0 0" ></path></symbol><symbol id="icon-quanping" viewBox="0 0 1024 1024"><path d="M181 357.5V181.2h176.4c14.3 0 25.9-11.6 25.9-25.9v-31.1c0-14.3-11.6-25.9-25.9-25.9H118c-11 0-20 9-20 20v239.4c0 14.3 11.6 25.9 25.9 25.9H155c14.4-0.1 26-11.7 26-26.1zM668.6 181.2H845v176.4c0 14.3 11.6 25.9 25.9 25.9H902c14.3 0 25.9-11.6 25.9-25.9V118.2c0-11-9-20-20-20H668.6c-14.3 0-25.9 11.6-25.9 25.9v31.1c0 14.3 11.6 26 25.9 26zM357.4 845.2H181V668.8c0-14.3-11.6-25.9-25.9-25.9H124c-14.3 0-25.9 11.6-25.9 25.9v239.4c0 11 9 20 20 20h239.4c14.3 0 25.9-11.6 25.9-25.9v-31.1c-0.1-14.4-11.7-26-26-26zM845 668.8v176.4H668.6c-14.3 0-25.9 11.6-25.9 25.9v31.1c0 14.3 11.6 25.9 25.9 25.9H908c11 0 20-9 20-20V668.8c0-14.3-11.6-25.9-25.9-25.9H871c-14.4 0-26 11.6-26 25.9z" ></path></symbol></svg>',(c=>{var t=(e=(e=document.getElementsByTagName("script"))[e.length-1]).getAttribute("data-injectcss"),e=e.getAttribute("data-disable-injectsvg");if(!e){var i,n,o,a,d,h=function(t,e){e.parentNode.insertBefore(t,e)};if(t&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(t){console&&console.log(t)}}i=function(){var t,e=document.createElement("div");e.innerHTML=c._iconfont_svg_string_5072634,(e=e.getElementsByTagName("svg")[0])&&(e.setAttribute("aria-hidden","true"),e.style.position="absolute",e.style.width=0,e.style.height=0,e.style.overflow="hidden",e=e,(t=document.body).firstChild?h(e,t.firstChild):t.appendChild(e))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(i,0):(n=function(){document.removeEventListener("DOMContentLoaded",n,!1),i()},document.addEventListener("DOMContentLoaded",n,!1)):document.attachEvent&&(o=i,a=c.document,d=!1,s(),a.onreadystatechange=function(){"complete"==a.readyState&&(a.onreadystatechange=null,l())})}function l(){d||(d=!0,o())}function s(){try{a.documentElement.doScroll("left")}catch(t){return void setTimeout(s,50)}l()}})(window);
\ No newline at end of file
......@@ -57,39 +57,39 @@ const props = defineProps({
justify-content: center;
align-items: center;
.stat-card {
.vw(width, 170);
.vw(width, 180);
.vw(border-radius, 5);
.vw(margin-right,10);
.vw(padding, 10);
.vw(margin,10);
background-image: url("@/assets/images/complete.png");
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: center;
.stat-card-title {
.font(12);
text-align: center;
}
.stat-card-value {
.font(12);
display: flex;
flex-direction: column;
justify-content: space-between;
.vh(margin-top,20);
.card-value-top {
.vh(margin-bottom,10);
}
.card-value-top,
.card-value-bottom {
display: flex;
justify-content: space-between;
p {
.vh(height,10);
}
.pro-title {
.font(10);
margin-bottom: -12px;
}
.pro-value {
.font(18);
.font(16);
font-family: "DIN";
color: @Color;
font-weight: 100;
span {
.font(10);
font-weight: 400;
// font-weight: 400;
}
}
}
......@@ -110,7 +110,7 @@ const props = defineProps({
}
.trend-icon {
font-size: 12px;
.font(12);
color: #32d25a;
&.down-trend {
......
......@@ -30,20 +30,18 @@ const props = defineProps({
.stat-cards-container {
display: flex;
.stat-card {
.vw(width, 170);
.vw(width, 180);
.vw(border-radius, 5);
.vw(padding, 10);
.vw(margin,10);
.vw(margin-right,10);
background-image: url("@/assets/images/total2.png");
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: center;
.stat-card-title {
.font(12);
font-weight: 700;
}
.stat-card-value {
.font(20);
.font(18);
color: @Color;
font-family: "DIN";
}
......@@ -52,7 +50,6 @@ const props = defineProps({
justify-content: space-between;
.amount-title {
.font(10);
.vh(height, 5);
}
.amount-value {
.font(16);
......
......@@ -133,33 +133,28 @@ onMounted(() => {});
<style scoped lang="less">
.common-container {
display: flex;
justify-content: center;
.stat-cards-container {
display: flex;
.stat-card {
.vw(width, 170);
.vw(width, 180);
.vw(border-radius, 5);
.vw(padding, 20);
// .vw(margin,10);
.vw(padding, 10);
.vw(margin-right,10);
background-image: url("@/assets/images/total2.png");
background-repeat: no-repeat;
background-size: 90% 80%;
background-position: center;
background-size: contain;
.stat-card-title {
.font(12);
}
.stat-card-value {
.font(24);
.font(18);
cursor: pointer;
font-family: "DIN";
}
}
:last-child {
margin-right: 0;
}
}
}
:deep(.el-dialog__title) {
font-weight: 900;
}
:deep(.el-dialog) {
}
</style>
.tab-content{
th{
text-align: center;
// text-align: center;
}
}
\ No newline at end of file
......@@ -11,15 +11,11 @@
<div class="construct-right">
<div>
<div class="info-title">项目概况</div>
<div>
<CommonTotal :numberList="projectList" />
</div>
<CommonTotal :numberList="projectList" />
</div>
<div>
<div class="info-title">投资完成情况</div>
<div>
<CommonTotal :numberList="investmentList" />
</div>
<CommonTotal :numberList="investmentList" />
</div>
<div>
<div class="info-title">投资完成情况</div>
......@@ -39,9 +35,7 @@
</div>
<div>
<div class="info-title">投资回收完成情况</div>
<div>
<CommonTotal :numberList="recycleList" />
</div>
<CommonTotal :numberList="recycleList" />
</div>
</div>
</div>
......@@ -50,20 +44,26 @@
<script setup>
import Map from "@/components/CommonMap.vue";
import CommonTotal from "@/components/CommonTotal.vue";
import { reactive, ref, onMounted, onUnmounted } from "vue";
import { reactive, ref, onMounted, onUnmounted, shallowReactive, defineOptions } from "vue";
import CircleProgress from "./CircleProgress.vue";
const projectList = reactive([
// 定义组件名称,用于keep-alive缓存
defineOptions({
name: 'Construct'
});
// 使用shallowReactive减少深层响应式开销
const projectList = shallowReactive([
{ title: "总个数(个)", value: "59" },
{ title: "总投资(亿元)", value: "2733.35" },
{ title: "总规模(公里)", value: "5116.72" },
]);
const investmentList = reactive([
const investmentList = shallowReactive([
{ title: "10月完成投资(亿元)", value: "0" },
{ title: "2025年完成投资(亿元)", value: "19.725" },
{ title: "累计完成投资(亿元)", value: "807.56" },
]);
// recycleList
const recycleList = reactive([
const recycleList = shallowReactive([
{ title: "10月完成投资(亿元)", value: "0" },
{ title: "2025年完成投资(亿元)", value: "2.98" },
{ title: "完成率", value: "50.2%" },
......@@ -74,7 +74,7 @@ const recycleList = reactive([
.construct-container {
display: flex;
.construct-left {
flex: 1;
width: 100%;
height: 100%;
.tag-image {
img {
......@@ -94,11 +94,12 @@ const recycleList = reactive([
.vw(width, 180);
.vh(height, 30);
.vh(line-height, 30);
.vw(margin-left,20);
.font(20);
.vw(padding-left,23);
.font(16);
.vw(padding-left,20);
.vh(margin-bottom,15);
text-align: left;
color: #fff;
white-space: nowrap;
font-family: YouSheBiaoTiYuan;
background-image: url("@/assets/images/tag.png");
background-repeat: no-repeat;
......@@ -132,24 +133,21 @@ const recycleList = reactive([
.vw(left,65);
width: 85%;
height: 30%;
background-image: url(/src/assets/images/baseRate.png);
background-image: url("@/assets/images/baseRate.png");
background-size: 100% 100%;
background-repeat: no-repeat;
}
.progress-show-value-rel {
height: 100%;
background-image: url("@/assets/images/baseRateRel.png");
background-size: auto 100%;
-webkit-transform: skew(-30deg);
transform: skew(-30deg);
position: absolute;
.vh(top,26);
.vw(left,65);
height: 30%;
max-width: 83%;
height: 30%;
background-image: url(/src/assets/images/progress.png);
background-size: 100% 100%;
background-repeat: no-repeat;
-webkit-transform: skew(-30deg);
transform: skew(-30deg);
}
}
}
......
......@@ -11,33 +11,23 @@
<div class="construct-right">
<div>
<div class="info-title">项目概况</div>
<div>
<CommonTotal :numberList="projectList" />
</div>
<CommonTotal :numberList="projectList" />
</div>
<div>
<div class="info-title">投资完成情况</div>
<div>
<CommonTotal :numberList="investmentList" />
</div>
<CommonTotal :numberList="investmentList" />
</div>
<div>
<div class="info-title">经营计划完成情况</div>
<div>
<CommonComplete :numberList="completeList" />
</div>
<CommonComplete :numberList="completeList" />
</div>
<div>
<div class="info-title">投资回收完成情况</div>
<div>
<CommonTotal :numberList="recycleList" />
</div>
<CommonTotal :numberList="recycleList" />
</div>
<div>
<div class="info-title">2025年经营计划完成进度</div>
<div>
<CommonPlant :numberList="operationList" />
</div>
<CommonPlant :numberList="operationList" />
</div>
</div>
</div>
......@@ -48,28 +38,34 @@ 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 { reactive, ref, onMounted, onUnmounted } from "vue";
const projectList = reactive([
import { shallowReactive, ref, onMounted, onUnmounted, defineOptions } from "vue";
// 定义组件名称,用于keep-alive缓存
defineOptions({
name: 'Operation'
});
// 使用shallowReactive减少深层响应式开销
const projectList = shallowReactive([
{ title: "总个数(个)", value: "59" },
{ title: "总投资(亿元)", value: "2733.35" },
{ title: "总规模(公里)", value: "5116.72" },
]);
const investmentList = reactive([
const investmentList = shallowReactive([
{ title: "10月完成投资(亿元)", value: "0" },
{ title: "2025年完成投资(亿元)", value: "19.725" },
{ title: "累计完成投资(亿元)", value: "807.56" },
]);
const recycleList = reactive([
const recycleList = shallowReactive([
{ title: "10月完成投资(亿元)", value: "0" },
{ title: "2025年完成投资(亿元)", value: "2.98" },
{ title: "完成率", value: "50.2%" },
]);
const operationList = reactive([
const operationList = shallowReactive([
{ title: "营业收入完成进度", value: "68.1%" },
{ title: "运营成本完成进度", value: "68.1%" },
{ title: "利润总额完成进度", value: "68.1%" },
]);
const completeList = reactive([
const completeList = shallowReactive([
{
title: "营业收入",
protitle: "11月完成",
......@@ -101,7 +97,7 @@ const completeList = reactive([
.construct-container {
display: flex;
.construct-left {
flex: 1;
width: 100%;
height: 100%;
.tag-image {
img {
......@@ -118,14 +114,16 @@ const completeList = reactive([
flex-direction: column;
justify-content: space-between;
.info-title {
.vw(width, 230);
.vw(width, 180);
.vh(height, 30);
.vh(line-height, 30);
.vw(margin-left,10);
.font(20);
.vw(padding-left,28);
.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;
......
<template>
<CommonTotal :numberList="initiationList" />
<div class="project-container">
<CommonTotal :numberList="initiationList" />
</div>
<Map />
</template>
<script setup>
import CommonTotal from "@/components/CommonTotal.vue";
import Map from "@/components/CommonMap.vue";
import { onMounted, reactive, watch, ref } from "vue";
import { onMounted, reactive, watch, ref, computed, shallowRef, defineOptions } from "vue";
// 定义组件名称,用于keep-alive缓存
defineOptions({
name: 'ProjectApproval'
});
const props = defineProps({
currentName: {
......@@ -14,64 +21,36 @@ const props = defineProps({
default: "立项",
},
});
const initiationList = ref([]);
// 根据currentName设置不同的数据
const setNumberList = (name) => {
if (name === "立项") {
initiationList.value = [
{ title: "总个数(个)", value: "59" },
{ title: "总投资(亿元)", value: "2733.35" },
{ title: "总规模(公里)", value: "5116.72" },
];
} else {
initiationList.value = [
{ title: "总个数(个)", value: "59" },
{ title: "总投资(亿元)", value: "2733.35" },
{ title: "总规模(公里)", value: "5116.72" },
{ title: "累计完成投资(亿元)", value: "3116.44" },
];
}
// 使用静态数据避免重复创建
const STATIC_DATA = {
立项: [
{ title: "总个数(个)", value: "59" },
{ title: "总投资(亿元)", value: "2733.35" },
{ title: "总规模(公里)", value: "5116.72" },
],
转让: [
{ title: "总个数(个)", value: "59" },
{ title: "总投资(亿元)", value: "2733.35" },
{ title: "总规模(公里)", value: "5116.72" },
{ title: "累计完成投资(亿元)", value: "3116.44" },
],
退出: [
{ title: "总个数(个)", value: "59" },
{ title: "总投资(亿元)", value: "2733.35" },
{ title: "总规模(公里)", value: "5116.72" },
{ title: "累计完成投资(亿元)", value: "3116.44" },
],
};
watch(
() => props.currentName,
(newVal) => {
setNumberList(newVal);
},
{
immediate: true,
deep: true,
}
);
onMounted(() => {
setNumberList(props.currentName);
// 使用computed进行响应式计算,避免不必要的重新渲染
const initiationList = computed(() => {
return STATIC_DATA[props.currentName] || STATIC_DATA.立项;
});
</script>
<style scoped lang="less">
.stat-cards-container {
.project-container {
display: flex;
justify-content: center;
align-items: center;
.stat-card {
.vw(width, 180);
.vh(height, 80);
.vw(border-radius, 5);
.vw(padding, 10);
.vw(padding, 10);
.vw(margin,10);
background-image: url("@/assets/images/total.png");
background-repeat: no-repeat;
background-size: cover;
background-position: center;
.stat-card-title {
.font(14);
}
.stat-card-value {
.vh(margin-top, 20);
.font(20);
}
}
}
</style>
<template>
<div class="home-container">
<div class="header">
<div class="header-left">
<div
class="nav-btn"
:class="{ active: selectedLeftBtn === 'equity' }"
@click="selectLeftBtn('equity')"
>
股权投资
</div>
<div
class="nav-btn"
:class="{ active: selectedLeftBtn === 'risk' }"
@click="selectLeftBtn('risk')"
>
固定风险投资
</div>
<div class="construct-container">
<div class="construct-left">
<div class="tag-image">
<img src="@/assets/images/建设.png" />
</div>
<div class="header-middile">
葛洲坝集团交通投资有限公司投资决策分析系统
</div>
<div class="header-right">
<div
class="nav-btn"
:class="{ active: selectedRightBtn === 'realestate' }"
@click="selectRightBtn('realestate')"
>
房地产投资
</div>
<div
class="nav-btn"
:class="{ active: selectedRightBtn === 'finance' }"
@click="selectRightBtn('finance')"
>
融资建设投资
</div>
<div class="construct-left-map">
<Map />
</div>
</div>
<div class="content">
<div class="fullscreen-btn">
<span @click="toggleFullscreen" class="fullscreen-text">
<el-icon :size="18">
<full-screen />
</el-icon>
{{ isFullscreen ? "退出全屏" : "全屏" }}
</span>
<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 class="content-btn">
<span
v-for="item in navList"
:key="item.index"
:class="{ active: selectedContentBtn === item.index }"
@click="selectContentBtn(item)"
>{{ item.name }}
</span>
<div>
<div class="info-title">2025年经营计划完成进度</div>
<CommonPlant :numberList="operationList" />
</div>
<ProjectApproval
:currentName="selectedContentName"
v-if="
selectedContentBtn === 1 ||
selectedContentBtn === 4 ||
selectedContentBtn === 5
"
/>
<Construct v-else-if="selectedContentBtn === 2" />
<Operation v-else />
</div>
<div class="bottom"></div>
</div>
</template>
<script setup>
import Construct from "../components/Construct.vue";
import ProjectApproval from "../components/ProjectApproval.vue";
import Operation from "../components/Operation.vue";
import { reactive, ref } from "vue";
const selectedLeftBtn = ref("equity");
const selectedRightBtn = ref("");
const selectedContentBtn = ref(1);
const selectedContentName = ref("立项");
const isFullscreen = ref(false);
const showPopup = ref(false);
const currentProject = ref({});
const popupStyle = ref({});
const navList = reactive([
{
index: 1,
name: "立项",
},
{
index: 2,
name: "建设",
},
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 { reactive, ref, onMounted, onUnmounted } from "vue";
const projectList = reactive([
{ title: "总个数(个)", value: "59" },
{ title: "总投资(亿元)", value: "2733.35" },
{ title: "总规模(公里)", value: "5116.72" },
]);
const investmentList = reactive([
{ title: "10月完成投资(亿元)", value: "0" },
{ title: "2025年完成投资(亿元)", value: "19.725" },
{ title: "累计完成投资(亿元)", value: "807.56" },
]);
const recycleList = reactive([
{ title: "10月完成投资(亿元)", value: "0" },
{ title: "2025年完成投资(亿元)", value: "2.98" },
{ title: "完成率", value: "50.2%" },
]);
const operationList = reactive([
{ title: "营业收入完成进度", value: "68.1%" },
{ title: "运营成本完成进度", value: "68.1%" },
{ title: "利润总额完成进度", value: "68.1%" },
]);
const completeList = reactive([
{
index: 3,
name: "运营",
title: "营业收入",
protitle: "11月完成",
proValue: "1.1",
thirdTtile: "第三季度完成",
thirdValue: "4.21",
compareValue: "+1.2%",
},
{
index: 4,
name: "转让",
title: "运营成本",
protitle: "11月完成",
proValue: "47.98",
thirdTtile: "第三季度完成",
thirdValue: "5.75",
compareValue: "-0.5%",
},
{
index: 5,
name: "退出",
title: "利润总额",
protitle: "11月完成",
proValue: "9.90",
thirdTtile: "第三季度完成",
thirdValue: "23.52",
compareValue: "+1.2%",
},
]);
const selectLeftBtn = (btn) => {
selectedLeftBtn.value = btn;
selectedRightBtn.value = "";
};
const selectRightBtn = (btn) => {
selectedRightBtn.value = btn;
selectedLeftBtn.value = "";
};
const selectContentBtn = (item) => {
selectedContentBtn.value = item.index;
selectedContentName.value = item.name;
};
const showProjectPopup = (event) => {
currentProject.value = {
name: "项目001",
data: [
{ label: "数据01", value: "3654.89", unit: "单位" },
{ label: "数据02", value: "3654.89", unit: "单位" },
{ label: "数据03", value: "3654.89", unit: "单位" },
],
};
popupStyle.value = {
left: `${event.clientX}px`,
top: `${event.clientY - 100}px`,
};
showPopup.value = true;
};
// 全屏切换功能
const toggleFullscreen = () => {
const homeContainer = document.querySelector(".home-container");
if (isFullscreen.value) {
// 退出全屏
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
homeContainer.style.height = "100%";
} else {
// 进入全屏
if (homeContainer.requestFullscreen) {
homeContainer.requestFullscreen();
} else if (homeContainer.webkitRequestFullscreen) {
homeContainer.webkitRequestFullscreen();
} else if (homeContainer.msRequestFullscreen) {
homeContainer.msRequestFullscreen();
}
homeContainer.style.height = "100vh";
}
isFullscreen.value = !isFullscreen.value;
};
// 监听全屏变化事件
window.addEventListener("fullscreenchange", () => {
if (!document.fullscreenElement) {
isFullscreen.value = false;
const homeContainer = document.querySelector(".home-container");
if (homeContainer) homeContainer.style.height = "100%";
} else {
isFullscreen.value = true;
const homeContainer = document.querySelector(".home-container");
if (homeContainer) homeContainer.style.height = "100vh";
}
});
</script>
<style scoped lang="less">
.home-container {
// background-image: url("@/assets/images/bg.png");
// background-repeat: no-repeat;
// background-size: cover;
// background-position: center;
width: 100%;
height: 100%;
background-color: #04427e;
overflow: hidden;
color: #fff;
.construct-container {
display: flex;
flex-direction: column;
justify-content: space-between;
.header {
.construct-left {
width: 100%;
.vh(height, 80);
display: flex;
justify-content: center;
align-items: flex-end;
.header-middile {
background-image: url("@/assets/images/header.png");
background-repeat: no-repeat;
background-position: center;
background-size: auto;
.font(28);
letter-spacing: 1px;
font-weight: 400;
font-family: "YouSheBiaoTiHei";
.vw(width,950);
height: 74px;
display: flex;
justify-content: center;
align-items: center;
}
.header-left {
display: flex;
align-items: center;
justify-content: center;
.nav-btn {
.font(16);
cursor: pointer;
color: #fff;
font-family: YouSheBiaoTiYuan;
font-weight: 100;
display: flex;
align-items: center;
justify-content: center;
&:not(.active) {
background-image: url("@/assets/images/left-btn.png");
background-repeat: no-repeat;
background-position: center;
background-size: contain;
width: 155px;
height: 35px;
background-size: 100% 100%;
}
&.active {
background-image: url("@/assets/images/left-hlightBtn.png");
background-repeat: no-repeat;
background-position: center;
background-size: contain;
width: 155px;
height: 35px;
background-size: 100% 100%;
}
}
}
.header-right {
display: flex;
justify-content: center;
align-items: center;
.nav-btn {
.font(16);
cursor: pointer;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-family: YouSheBiaoTiYuan;
&:not(.active) {
background-image: url("@/assets/images/right-btn.png");
background-repeat: no-repeat;
background-position: center;
width: 155px;
height: 35px;
background-size: 100% 100%;
}
&.active {
background-image: url("@/assets/images/right-hight-btn.png");
background-repeat: no-repeat;
background-position: center;
background-size: contain;
width: 155px;
height: 35px;
background-size: 100% 100%;
}
height: 100%;
.tag-image {
img {
.vw(width, 85);
}
}
}
.content {
flex: 1;
.vw(padding-left, 20);
.vw(padding-right, 20);
.content-btn {
.vh(margin-top,-10);
.vh(margin-bottom,20);
display: flex;
justify-content: center;
align-items: center;
span {
.font(14);
width: 110px;
height: 35px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
flex-shrink: 0;
color: #fff; // 补充文字颜色(匹配蓝色按钮的白色文字)
}
// 立项按钮
:nth-child(1) {
background-repeat: no-repeat;
background-size: 80% 80%;
background-position: center;
width: 115px;
height: 35px;
line-height: 35px;
text-align: center;
&.active {
background-image: url("@/assets/images/立项.png");
}
&:not(.active) {
background-image: url("@/assets/images/initiation-default.png");
}
}
// 退出按钮
:nth-child(5) {
background-repeat: no-repeat;
background-size: 80% 80%;
background-position: center;
width: 111px;
height: 35px;
line-height: 35px;
text-align: center;
&.active {
background-image: url("@/assets/images/退出-active.png");
}
&:not(.active) {
background-image: url("@/assets/images/退出.png");
}
}
// 中间按钮(建设、运营、转止)
:nth-child(2),
:nth-child(3),
:nth-child(4) {
background-repeat: no-repeat;
background-size: 80% 80%;
background-position: center;
width: 115px;
height: 35px;
line-height: 35px;
text-align: center;
margin-left: -32px;
background-image: url("@/assets/images/default-btn.png");
&.active {
background-image: url("@/assets/images/nav-hight-btn.png");
}
}
:nth-child(5) {
margin-left: -31px;
}
.construct-left-map {
.vh(height, 700);
.vh(padding-top, 4);
}
}
.bottom {
background-image: url("@/assets/images/bottom.png");
background-repeat: no-repeat;
background-size: cover;
background-position: center;
width: 100%;
.vh(height, 80);
}
.fullscreen-btn {
.construct-right {
display: flex;
cursor: pointer;
span {
margin-left: auto;
color: white;
font-weight: 700;
flex-direction: column;
justify-content: space-between;
.info-title {
.vw(width, 180);
.vh(height, 30);
.vh(line-height, 30);
.font(16);
display: flex;
align-items: center;
gap: 6px;
.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%;
}
}
}
......
......@@ -55,16 +55,18 @@
>{{ item.name }}
</span>
</div>
<ProjectApproval
:currentName="selectedContentName"
v-if="
selectedContentBtn === 1 ||
selectedContentBtn === 4 ||
selectedContentBtn === 5
"
/>
<Construct v-else-if="selectedContentBtn === 2" />
<Operation v-else />
<keep-alive include="ProjectApproval,Construct,Operation">
<ProjectApproval
:currentName="selectedContentName"
v-if="
selectedContentBtn === 1 ||
selectedContentBtn === 4 ||
selectedContentBtn === 5
"
/>
<Construct v-else-if="selectedContentBtn === 2" />
<Operation v-else />
</keep-alive>
</div>
<div class="bottom"></div>
</div>
......@@ -74,7 +76,7 @@
import Construct from "./components/Construct.vue";
import ProjectApproval from "./components/ProjectApproval.vue";
import Operation from "./components/Operation.vue";
import { reactive, ref } from "vue";
import { reactive, ref, nextTick } from "vue";
const selectedLeftBtn = ref("equity");
const selectedRightBtn = ref("");
......@@ -118,26 +120,42 @@ const selectRightBtn = (btn) => {
selectedLeftBtn.value = "";
};
// 添加防抖功能,避免频繁切换造成的性能问题
let debounceTimer = null;
const selectContentBtn = (item) => {
selectedContentBtn.value = item.index;
selectedContentName.value = item.name;
// 清除之前的定时器
if (debounceTimer) {
clearTimeout(debounceTimer);
}
// 使用防抖延迟切换
debounceTimer = setTimeout(() => {
selectedContentBtn.value = item.index;
selectedContentName.value = item.name;
// 使用nextTick确保DOM更新完成
nextTick(() => {
// 可以在这里添加其他需要延迟执行的逻辑
});
}, 100); // 100ms防抖延迟
};
const showProjectPopup = (event) => {
currentProject.value = {
name: "项目001",
data: [
{ label: "数据01", value: "3654.89", unit: "单位" },
{ label: "数据02", value: "3654.89", unit: "单位" },
{ label: "数据03", value: "3654.89", unit: "单位" },
],
};
popupStyle.value = {
left: `${event.clientX}px`,
top: `${event.clientY - 100}px`,
};
showPopup.value = true;
};
// 暂时注释未使用的函数,避免lint警告
// const showProjectPopup = (event) => {
// currentProject.value = {
// name: "项目001",
// data: [
// { label: "数据01", value: "3654.89", unit: "单位" },
// { label: "数据02", value: "3654.89", unit: "单位" },
// { label: "数据03", value: "3654.89", unit: "单位" },
// ],
// };
// popupStyle.value = {
// left: `${event.clientX}px`,
// top: `${event.clientY - 100}px`,
// };
// showPopup.value = true;
// };
// 全屏切换功能
const toggleFullscreen = () => {
......
......@@ -10,19 +10,47 @@
<el-icon><search /></el-icon>
</template>
</el-input>
<div class="tree-content">
<span class="filterRow">
<el-dropdown>
<span class="el-dropdown-link">
<i class="iconfont icon-gengduo"></i>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="handleOriginEdit"
><i class="iconfont icon-bianji"></i
>编辑组织</el-dropdown-item
>
<el-dropdown-item @click="handleDeleteOrigin"
><i class="iconfont icon-shanchu"></i
>删除组织</el-dropdown-item
>
</el-dropdown-menu>
</template>
</el-dropdown>
</span>
<el-tree
:data="treeData"
node-key="id"
default-expand-all
draggable
@node-click="handleNodeClick"
>
</el-tree>
</div>
</div>
<div class="table-container">
<div class="origin-title">
<h3>部门管理</h3>
<el-button type="primary" @click="handleAdd"> 新增 </el-button>
<div class="table-container" v-loading="userLoading">
<div class="search-contain">
<div>
人员信息:
<el-input placeholder="请输入人员信息" v-model="userName" />
</div>
<div>
<el-button type="primary" @click="handleUserData">查询</el-button>
<el-button type="" @click="handleReset">重置</el-button>
</div>
</div>
<commonForm
v-model="searchForm"
:config="searchConfig"
:items="searchItems"
@submit="handleSearch"
@reset="handleReset"
/>
<common-table
:tableHeight="tableHeight"
:data="tableData"
......@@ -35,29 +63,10 @@
@size-change="handleSizeChange"
@current-page-change="handleCurrentPageChange"
>
<!-- <template #header-actions>
<el-button type="primary" @click="handleAdd">
<el-icon><Plus /></el-icon>
新增
</el-button>
</template> -->
<template #enable="{ row }">
<el-switch
:model-value="row.enable === 0 ? true : false"
@change="handleStatusChange($event, row)"
active-color="#13ce66"
inactive-color="#ff4949"
></el-switch>
</template>
<template #operations="{ row, index }">
<el-button type="text" size="small" @click="handleEdit(row, index)">
编辑
</el-button>
<el-button type="text" size="small" @click="handleDelete(row, index)">
删除
</el-button>
<el-tag :type="row.enable === 0 ? 'success' : 'danger'">
{{ row.enable === "0" ? "启用" : "停用" }}
</el-tag>
</template>
</common-table>
</div>
......@@ -65,11 +74,11 @@
<el-dialog
v-model="dialogVisible"
:title="dialogTitle"
width="600px"
width="400px"
@close="handleDialogClose"
>
<commonForm
v-model="userForm"
v-model="originForm"
:config="formConfig"
:items="formItems"
:rules="formRules"
......@@ -88,6 +97,11 @@ import CommonTable from "@/components/common/commonTable.vue";
const { proxy } = getCurrentInstance();
const loading = ref(false);
const userLoading = ref(false);
const treeData = ref([]);
const originTreeData = ref([]);
const selectedNode = ref(null);
const userName = ref("");
// 计算表格高度
const tableHeight = computed(() => {
......@@ -95,20 +109,28 @@ const tableHeight = computed(() => {
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) => {
return apiData.map((item) => ({
value: item.id.toString(),
label: item.name,
children: item.children ? convertToTreeData(item.children) : [],
}));
const convertToTreeData = (apiData, type) => {
if (type === "id") {
return apiData.map((item) => ({
id: item.id,
label: item.name,
parentId: item.parentId,
children: item.children ? convertToTreeData(item.children) : [],
}));
} else {
return apiData.map((item) => ({
parentId: item.parentId,
value: item.id,
label: item.name,
children: item.children ? convertToTreeData(item.children) : [],
}));
}
};
// 表格数据
......@@ -160,50 +182,17 @@ const tableColumns = [
slot: "enable",
align: "center",
},
{
prop: "operations",
label: "操作",
width: 160,
slot: "operations",
fixed: "right",
align: "center",
},
];
// 对话框相关
const dialogVisible = ref(false);
const dialogTitle = ref("新增用户");
const isEdit = ref(false);
const editIndex = ref(-1);
const searchForm = ref({
name: "",
});
const searchConfig = {
inline: false,
labelWidth: "80px",
showButtons: true,
submitText: "查询",
resetText: "重置",
};
const searchItems = [
{
type: "input",
prop: "name",
label: "部门名称",
placeholder: "请输入部门名称",
clearable: true,
span: 8,
},
];
// 用户表单数据
const userForm = ref({
const originForm = ref({
name: "",
departs: [],
positions: [],
roles: [],
enable: "0",
parentId: "",
});
// 用户表单配置
......@@ -213,121 +202,33 @@ const formConfig = {
submitText: "保存",
resetText: "取消",
};
const departmentData = ref([]);
const positionsData = ref([]);
const rolesData = ref([]);
const loadDepartmentData = () => {
proxy.$post({
url: "/api/user/depart/treeDepart",
data: {},
callback: (data) => {
departmentData.value = convertToTreeData(data);
},
error: (err) => {},
});
};
// 岗位下拉数据
const loadPositionsData = () => {
proxy.$post({
url: "/api/user/position/listPosition",
data: {},
callback: (data) => {
positionsData.value = convertToTreeData(data.rows);
},
error: (err) => {},
});
};
// 角色下拉数据
const loadRolesData = () => {
proxy.$post({
url: "/api/user/role/listRole",
data: {
page: 1,
pageSize: 10,
},
callback: (data) => {
rolesData.value = convertToTreeData(data.rows);
},
error: (err) => {},
});
};
// 用户表单项配置
const formItems = computed(() => [
{
type: "input",
prop: "name",
label: "用户姓名",
placeholder: "请输入用户姓名",
span: 12,
},
{
type: "tree",
prop: "departs",
label: "所属部门",
placeholder: "请选择部门",
data: departmentData.value,
clearable: true,
filterable: true,
checkStrictly: true,
renderAfterExpand: false,
showCheckbox: true,
multiple: true,
collapseTags: true,
maxCollapseTags: 2,
span: 12,
},
{
type: "tree",
prop: "positions",
label: "岗位",
placeholder: "请选择岗位",
data: positionsData.value,
clearable: true,
filterable: true,
checkStrictly: true,
renderAfterExpand: false,
showCheckbox: true,
multiple: true,
collapseTags: true,
maxCollapseTags: 2,
span: 12,
},
{
type: "tree",
prop: "roles",
label: "角色",
placeholder: "请选择角色",
data: rolesData.value,
prop: "parentId",
label: "上级组织",
placeholder: "请选择上级组织",
data: originTreeData.value,
clearable: true,
filterable: true,
checkStrictly: true,
renderAfterExpand: false,
showCheckbox: true,
multiple: true,
collapseTags: true,
maxCollapseTags: 2,
span: 12,
showCheckbox: false,
multiple: false,
span: 24,
// required: true,
// rules: [{ required: true, message: "请选择上级组织", trigger: "blur" }],
},
{
type: "input",
prop: "mobile",
label: "手机号码",
placeholder: "请输入手机号码",
span: 12,
},
{
type: "radio",
prop: "enable",
label: "状态",
span: 12,
options: [
{ label: "启用", value: "0" },
{ label: "停用", value: "1" },
],
prop: "name",
label: "组织名称:",
placeholder: "请输入组织名称",
required: true,
rules: [{ required: true, message: "请输入组织名称", trigger: "blur" }],
span: 24,
},
]);
......@@ -348,103 +249,106 @@ const handleCurrentPageChange = (page) => {
// 新增用户
const handleAdd = () => {
isEdit.value = false;
dialogTitle.value = "新增用户";
userForm.value = {
dialogTitle.value = "新增组织";
originForm.value = {
parentId: "",
name: "",
departs: [],
positions: [],
roles: [],
enable: "0",
};
loadDepartmentData();
loadPositionsData();
loadRolesData();
dialogVisible.value = true;
};
let currentID = ref();
// 编辑
const handleEdit = (row, index) => {
isEdit.value = true;
dialogTitle.value = "编辑用户";
editIndex.value = index;
proxy.$post({
url: "/api/user/manage/getUserInfo",
data: { id: row.id },
callback: (data) => {
userForm.value = { ...data };
currentID.value = data.id;
},
error: (err) => {
ElMessage.error("编辑失败:", err);
},
});
dialogVisible.value = true;
let currentID = ref("");
// 处理树节点点击事件
const handleNodeClick = (data, node, element) => {
selectedNode.value = data;
currentID.value = selectedNode.value.id;
handleUserData();
};
// 删除
const handleDelete = async (row, index) => {
try {
await ElMessageBox.confirm(`确定要删除用户"${row.name}"吗?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
// 组织详情
const handleOriginEdit = () => {
if (selectedNode.value === null) {
ElMessage.warning("请选择要编辑的数据");
} else {
isEdit.value = true;
dialogVisible.value = true;
dialogTitle.value = "编辑组织";
const selectID = {
id: selectedNode.value.id,
};
proxy.$post({
url: "/api/user/depart/getDepart",
data: selectID,
callback: (data) => {
originForm.value = { ...data };
currentID.value = data.id;
},
error: (err) => {
ElMessage.error("编辑失败:", err);
},
});
}
};
// 组织删除
const handleDeleteOrigin = () => {
if (selectedNode.value === null) {
ElMessage.warning("请选择要删除的组织");
} else {
const deleteItem = {
id: selectedNode.value.value,
name: selectedNode.value.label,
parentId: selectedNode.value.parentId
? selectedNode.value.parentId
: null,
};
proxy.$post({
url: "/api/user/manage/deleteUser",
data: { id: row.id },
url: "/api/user/depart/deleteDepart",
data: deleteItem,
callback: (data) => {
dialogVisible.value = false;
loadTableData();
handleTreeData();
ElMessage.success("删除成功");
},
error: (err) => {
ElMessage.error("删除失败:", err);
ElMessage.error("删除失败", err);
},
});
loadTableData();
} catch {}
}
};
const handleFormSubmit = (formData) => {
if (isEdit.value) {
// 编辑用户
const updateUser = {
// 编辑组织
const updateOriForm = {
...formData,
departs: Array.isArray(formData.departs) ? formData.departs : [],
positions: Array.isArray(formData.positions) ? formData.positions : [],
roles: Array.isArray(formData.roles) ? formData.roles : [],
parentId: formData.parentId ? formData.parentId : null,
id: currentID.value,
};
proxy.$post({
url: "/api/user/manage/updateUser",
data: updateUser,
url: "/api/user/depart/updateDepart",
data: updateOriForm,
callback: (data) => {
dialogVisible.value = false;
loadTableData();
ElMessage.success("用户信息更新成功");
handleTreeData();
ElMessage.success("组织更新成功");
},
error: (err) => {
ElMessage.error("用户信息更新失败:", err);
ElMessage.error("组织更新失败", err);
},
});
} else {
// 新增用户
const newUser = {
// 新增组织
const addOroginForm = {
...formData,
departs: Array.isArray(formData.departs) ? formData.departs : [],
positions: Array.isArray(formData.positions) ? formData.positions : [],
roles: Array.isArray(formData.roles) ? formData.roles : [],
parentId: formData.parentId ? formData.parentId : null,
};
proxy.$post({
url: "/api/user/manage/createUser",
data: newUser,
url: "/api/user/depart/createDepart",
data: addOroginForm,
callback: (data) => {
dialogVisible.value = false;
loadTableData();
ElMessage.success("用户添加成功");
handleTreeData();
ElMessage.success("组织添加成功");
},
error: (err) => {
ElMessage.error("用户添加失败:", err);
ElMessage.error("组织添加失败:", err);
},
});
}
......@@ -457,38 +361,43 @@ const handleFormReset = () => {
const handleDialogClose = () => {
dialogVisible.value = false;
};
const handleReset = () => {
userName.value = "";
currentPage.value = 1;
handleUserData();
};
// 处理状态切换
const handleStatusChange = (newValue, row) => {
const newEnableValue = newValue ? "0" : "1";
// 树形数据
const handleTreeData = () => {
loading.value = true;
proxy.$post({
url: "/api/user/manage/updateUser",
url: "/api/user/depart/treeDepart",
data: {
id: row.id,
enable: newEnableValue,
page: currentPage.value,
pageSize: pageSize.value,
},
callback: (data) => {
row.enable = newEnableValue;
loadTableData();
ElMessage.success(
`用户状态已${newEnableValue === "0" ? "启用" : "停用"}`
);
treeData.value = convertToTreeData(data, "id");
originTreeData.value = convertToTreeData(data, "value");
selectedNode.value = data[0].id;
loading.value = false;
},
error: (err) => {
ElMessage.error("状态更新失败");
loading.value = false;
ElMessage.error("加载数据失败");
},
});
};
// 表格数据
const loadTableData = () => {
loading.value = true;
// 人员信息
const handleUserData = () => {
userLoading.value = true;
proxy.$post({
url: "/api/user/manage/listUser",
url: "/api/user/depart/getDepartUsers",
data: {
page: currentPage.value,
pageSize: pageSize.value,
departId: currentID.value,
name: userName.value,
},
callback: (data) => {
tableData.value = data.rows.map((item) => {
......@@ -498,20 +407,17 @@ const loadTableData = () => {
return item;
});
total.value = data.count;
loading.value = false;
userLoading.value = false;
},
error: (err) => {
loading.value = false;
userLoading.value = false;
ElMessage.error("加载数据失败");
},
});
};
onMounted(() => {
// loadTableData();
// loadDepartmentData();
// loadPositionsData();
// loadRolesData();
handleTreeData();
});
</script>
......@@ -540,6 +446,27 @@ onMounted(() => {
cursor: pointer;
}
}
.search-contain {
display: flex;
justify-content: space-between;
.el-input {
width: 255px;
}
}
.filterRow {
display: inline-block;
cursor: pointer;
display: flex;
justify-content: end;
.icon-gedian {
color: rgba(37, 97, 239, 1);
font-size: 20px;
}
}
.tree-content {
margin-top: 20px;
position: relative;
}
.table-container {
flex: 1;
......@@ -552,4 +479,29 @@ onMounted(() => {
.el-input__wrapper {
height: 35px;
}
// 树节点选中样式
:deep(.el-tree-node__content) {
&:hover {
background-color: #f5f7fa;
}
}
:deep(.el-tree-node.is-current > .el-tree-node__content) {
background-color: rgba(37, 97, 239, 1);
color: #fff;
height: 40px;
border-radius: 3px;
.el-tree-node__label {
color: white !important;
}
.el-icon {
color: white !important;
}
}
// :deep(.el-tree-node > .el-tree-node__children) {
// background-color: rgba(37, 97, 239, 1) !important;
// }
</style>
......@@ -279,7 +279,7 @@ const formItems = computed(() => [
filterable: true,
checkStrictly: true,
renderAfterExpand: false,
showCheckbox: true,
showCheckbox: false,
multiple: true,
collapseTags: true,
maxCollapseTags: 2,
......@@ -295,7 +295,7 @@ const formItems = computed(() => [
filterable: true,
checkStrictly: true,
renderAfterExpand: false,
showCheckbox: true,
showCheckbox: false,
multiple: true,
collapseTags: true,
maxCollapseTags: 2,
......@@ -311,7 +311,7 @@ const formItems = computed(() => [
filterable: true,
checkStrictly: true,
renderAfterExpand: false,
showCheckbox: true,
showCheckbox: false,
multiple: true,
collapseTags: true,
maxCollapseTags: 2,
......
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