feat: 项目看板部分接口对接以及视频配置组件接口对接

This commit is contained in:
kun 2024-06-14 15:06:30 +08:00
parent 500cc54d92
commit 549eafbb43
12 changed files with 388 additions and 304 deletions

View File

@ -131,3 +131,18 @@ export const getCountTaskProgressApi = (params: {}, showLoading: boolean) => {
export const queryCountEnterpriseApi = (params: {}, showLoading: boolean) => {
return http.post(BASEURL + `/xmgl/xzTaskProgressTotal/countEnterprise`, params, { headers: { noLoading: showLoading } });
};
// 人员情况
export const performanceAnalysisApi = (params: {}, showLoading: boolean) => {
return http.post(BASEURL + `/xmgl/workerAttendance/safetyPerformanceAnalysis`, params, { headers: { noLoading: showLoading } });
};
// 三色评价
export const statsEnterpriseRiskApi = (params: {}, showLoading: boolean) => {
return http.post(BASEURL + `/xmgl/workerInfo/statsEnterpriseRisk`, params, { headers: { noLoading: showLoading } });
};
// 安全教育视频配置
export const configWeekVideoSaveApi = (params: {}, showLoading: boolean) => {
return http.post(BASEURL + `/xmgl/educationConfigWeekVideo/save`, params, { headers: { noLoading: showLoading } });
};
export const configWeekVideoListApi = (params: {}, showLoading: boolean) => {
return http.get(BASEURL + `/xmgl/educationConfigWeekVideo/list`, params, { headers: { noLoading: showLoading } });
};

View File

@ -14,15 +14,16 @@
</div>
</div>
<div class="contont-video" style="color: #fff; font-size: 24px">
<div class="video-list" v-for="item in dialogInfo.videoUploadList" :key="item.id">
<div class="video-list" v-for="(item, index) in dialogInfo.videoUploadList" :key="item.id">
<div>{{ item.title }}</div>
<el-upload
ref="upload"
class="upload-demo"
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
:limit="1"
:on-exceed="handleExceed"
:auto-upload="false"
:action="BASEURL + '/upload/image'"
:on-success="file => handleSuccess(file, index)"
:beforeUpload="handleBeforeUploadVideo"
name="files"
:show-file-list="false"
>
<template #trigger>
<el-button type="primary">
@ -43,9 +44,16 @@
<script lang="ts" setup>
import { onMounted, reactive, ref } from "vue";
import { UploadFilled } from "@element-plus/icons-vue";
import { genFileId } from "element-plus";
import type { UploadInstance, UploadProps, UploadRawFile } from "element-plus";
import { ElMessage } from "element-plus";
import type { UploadInstance } from "element-plus";
import { configWeekVideoSaveApi,configWeekVideoListApi } from "@/api/modules/agjtCommandApi";
import { GlobalStore } from "@/stores";
import moment from "moment";
import { COMPANY } from "@/config/config";
const store = GlobalStore();
const BASEURL = import.meta.env.VITE_API_URL;
const emits = defineEmits(["updateConfig"])
const videoConfigData = ref();
const dialogInfo = reactive({
showDialog: false,
postData: {} as any,
@ -80,6 +88,79 @@ const dialogInfo = reactive({
}
]
});
//
const configWeekVideoListFn = async (showLoading:boolean) => {
const res: any = await configWeekVideoListApi(
{
projectSn: store.sn
},
showLoading
);
if (res.result) {
videoConfigData.value = res.result
}
}
//
const configWeekVideoEditFn = async (showLoading:boolean,url:any,weekIndex:number) => {
console.log(url)
let requestData:any = {
projectSn: store.sn
}
//
const today = weekIndex == 6?0:weekIndex + 1
const weekParamsKey = ["sun","mon","tues","wed","thur","fri","sat"]
requestData[weekParamsKey[+today]] = url;
// type
if(COMPANY == "agjtProjectKanban"){
requestData.type = 1;
} else if(COMPANY == "agjtOverviewScreen"){
requestData.type = 2;
} else if(COMPANY == "agjtLive"){
requestData.type = 3;
}
// id
if(videoConfigData.value && videoConfigData.value.length){
requestData.id = videoConfigData.value[0].id
}
const res: any = await configWeekVideoSaveApi(
requestData,
showLoading
);
if (res.success) {
console.log("修改成功", res);
ElMessage({
showClose: true,
message: "上传成功",
type: "success"
});
configWeekVideoListFn(true);
emits("updateConfig")
}
}
//
function handleBeforeUploadVideo(file: any) {
console.log(file, "上传之前");
let fileType = file.type.split("/")[0];
if (fileType == "video") {
return true;
} else {
ElMessage({
showClose: true,
message: "请选择正确的视频文件",
type: "warning"
});
return false;
}
}
//
function handleSuccess(file: any, index: number) {
if (file.code == 200 || file.status == "SUCCESS") {
console.log(file, "上传成功");
let url = file.data[0].imageUrl;
// this.imgUrl = url;
configWeekVideoEditFn(true,url,index);
}
}
const closeDialog = () => {
dialogInfo.showDialog = false;
dialogInfo.postData = {};
@ -91,18 +172,13 @@ function openDialog(obj: any) {
const upload = ref<UploadInstance>();
const handleExceed: UploadProps["onExceed"] = files => {
upload.value!.clearFiles();
const file = files[0] as UploadRawFile;
file.uid = genFileId();
upload.value!.handleStart(file);
};
// ()
defineExpose({
openDialog
});
onMounted(async () => {});
onMounted(async () => {
configWeekVideoListFn(true);
});
</script>
<style lang="scss" scoped>

View File

@ -28,9 +28,9 @@ export const BASE_IMAGE_URL = import.meta.env.VITE_BASE_IMAGE_URL;
// export const COMPANY: string = "zsbf"; //中水北方
// export const COMPANY: string = "as"; //鞍山项目
// export const COMPANY: string = "agjt"; //鞍钢集团
export const COMPANY: string = "agjtLive"; //鞍钢集团现场大屏
// export const COMPANY: string = "agjtLive"; //鞍钢集团现场大屏
// export const COMPANY: string = "agjtCommand"; //鞍钢集团指挥部大屏
// export const COMPANY: string = "agjtProjectKanban"; //鞍钢集团项目看板大屏
export const COMPANY: string = "agjtProjectKanban"; //鞍钢集团项目看板大屏
// export const COMPANY: string = "agjtOverviewScreen"; //鞍钢集团项目总览
// export const COMPANY: string = "slx"; //苏立信项目
// export const COMPANY: string = "hfqc"; //合肥启程项目

View File

@ -26,11 +26,9 @@ export const staticRouter: RouteRecordRaw[] = [
name: "大屏",
// // component: () => import("@/views/sevenLargeScreen/indexL.vue"), //七参数标准版
// component: () => import("@/views/commandScreen/indexCommand.vue"), //指挥部大屏
component: () => import("@/views/agjtLiveScreen/indexLive.vue"), //鞍钢现场大屏
// component: () => import("@/views/overviewScreen/indexCommand.vue"), //总览大屏
// component: () => import("@/views/agjtLiveScreen/indexLive.vue"), //鞍钢现场大屏
// component: () => import("@/views/overviewScreen/indexCommand.vue"), //总览大屏
// component: () => import("@/views/agjtProjectKanban/indexL.vue"), //鞍钢集团项目看板大屏
component: () => import("@/views/agjtProjectKanban/indexL.vue"), //鞍钢集团项目看板大屏
// component: () => import("@/views/sevenLargeScreen/indexL_syhy.vue"), // 只有一级路由(盘锦、嘉兴、鄱湖美湾医疗项目需切换至该首页)
children: [
{
@ -286,9 +284,9 @@ export const staticRouter: RouteRecordRaw[] = [
component: () => import("@/views/agjtProjectKanban/comprehensiveManage/projectOverview/index.vue")
},
{
path: "/agjtLiveScreen",
name: "鞍钢现场大屏",
component: () => import("@/views/agjtLiveScreen/liveScreen/index.vue")
path: "/overviewScreen",
name: "大屏总览",
component: () => import("@/views/overviewScreen/commandCenter/index.vue")
}
],
meta: {

View File

@ -12,7 +12,6 @@
import Card from "@/components/card.vue";
import { ref, onMounted, watch } from "vue";
import * as echarts from 'echarts';
import { da } from "element-plus/es/locale";
let tempList = ref([
{name:'高处作业',value:12,doing:10,per:'12.5'},{name:'断路作业',value:12,doing:10,per:'12.5'},{name:'吊装安全',value:12,doing:10,per:'12.5'},{name:'受限空间',value:12,doing:10,per:'12.5'},

View File

@ -2,30 +2,30 @@
<div class="leftTop">
<Card :title="activeTab == 0 ? '人员情况' : '三色评价'">
<div class="top-content">
<span :class="activeTab == 0 ? 'active' : ''" @click="activeTab = 0">人员情况</span>
<span :class="activeTab == 1 ? 'active' : ''" @click="activeTab = 1">三色评价</span>
<span :class="activeTab == 0 ? 'active' : ''" @click="activeChange(0)">人员情况</span>
<span :class="activeTab == 1 ? 'active' : ''" @click="activeChange(1)">三色评价</span>
</div>
<div class="box-content" v-show="activeTab == 0">
<div class="member-top-data">
<div class="top-data-item">
<span>未履职人员</span>
<span>12/2500</span>
<span>{{performanceAnalysisObj.notPerformNum || 0}}/{{performanceAnalysisObj.inServiceNum || 0}}</span>
</div>
<div class="top-data-item">
<span>项目经理</span>
<span>12/25</span>
<span>{{performanceAnalysisObj.xmjlNotPerformNum || 0}}/{{performanceAnalysisObj.xmjlInServiceNum || 0}}</span>
</div>
<div class="top-data-item">
<span>安全员</span>
<span>12/25</span>
<span>{{performanceAnalysisObj.aqyNotPerformNum || 0}}/{{performanceAnalysisObj.aqyInServiceNum || 0}}</span>
</div>
<div class="top-data-item">
<span>质量员</span>
<span>12/25</span>
<span>{{performanceAnalysisObj.zlyNotPerformNum || 0}}/{{performanceAnalysisObj.zlyInServiceNum || 0}}</span>
</div>
<div class="top-data-item">
<span>监理</span>
<span>5/5</span>
<span>{{performanceAnalysisObj.jlNotPerformNum || 0}}/{{performanceAnalysisObj.jlInServiceNum || 0}}</span>
</div>
</div>
<div class="member-bottom-table">
@ -39,22 +39,18 @@
<div>监理</div>
</div>
<el-scrollbar class="list-box">
<div
v-for="(item, index) in list"
class="listStyle"
:key="item.id"
>
<div v-for="(item, index) in performanceAnalysisList" class="listStyle" :key="item.id">
<!-- <div style="width: 5%">{{ index + 1 }}</div> -->
<div>{{ item.waterMeterName || "" }}</div>
<div>{{ item.waterTonnage || 0 }}</div>
<div>{{ item.waterTonnage || 0 }}</div>
<div>{{ item.waterTonnage || 0 }}</div>
<div>{{ item.waterTonnage || 0 }}</div>
<div>{{ item.waterTonnage || 0 }}</div>
<div>{{ item.enterpriseName || "" }}</div>
<div>{{item.notPerformNum || 0}}/{{item.inServiceNum || 0}}</div>
<div>{{item.xmjlNotPerformNum || 0}}/{{item.xmjlInServiceNum || 0}}</div>
<div>{{item.aqyNotPerformNum || 0}}/{{item.aqyInServiceNum || 0}}</div>
<div>{{item.zlyNotPerformNum || 0}}/{{item.zlyInServiceNum || 0}}</div>
<div>{{item.jlNotPerformNum || 0}}/{{item.jlInServiceNum || 0}}</div>
</div>
</el-scrollbar>
</div>
<div class="not-data" v-if="list.length == 0">
<div class="not-data" v-if="performanceAnalysisList.length == 0">
<img src="@/assets/images/noData.png" alt="" />
<p>暂无数据</p>
</div>
@ -64,40 +60,36 @@
<div class="remark-top-data">
<div class="top-data-item">
<span>低风险</span>
<span>1200</span>
<span>{{statsEnterpriseRiskObj.lowRiskNum}}</span>
</div>
<div class="top-data-item">
<span>中风险</span>
<span>25</span>
<span>{{statsEnterpriseRiskObj.mediumRiskNum}}</span>
</div>
<div class="top-data-item">
<span>高风险</span>
<span>0</span>
<span>{{statsEnterpriseRiskObj.highRiskNum}}</span>
</div>
</div>
<div class="remark-bottom-table">
<div class="list-content">
<div class="tab-list">
<div>企业名称</div>
<div>高风险人数</div>
<div>中风险人数</div>
<div>低风险人数</div>
<div>中风险人数</div>
<div>高风险人数</div>
</div>
<el-scrollbar class="list-box">
<div
v-for="(item, index) in list"
class="listStyle"
:key="item.id"
>
<div v-for="(item, index) in statsEnterpriseRiskList" class="listStyle" :key="item.id">
<!-- <div style="width: 5%">{{ index + 1 }}</div> -->
<div>{{ item.waterMeterName || "" }}</div>
<div>{{ item.waterTonnage || 0 }}</div>
<div>{{ item.waterTonnage || 0 }}</div>
<div>{{ item.waterTonnage || 0 }}</div>
<div>{{ item.enterpriseName || "" }}</div>
<div>{{ item.lowRiskNum || 0 }}</div>
<div>{{ item.mediumRiskNum || 0 }}</div>
<div>{{ item.highRiskNum || 0 }}</div>
</div>
</el-scrollbar>
</div>
<div class="not-data" v-if="list.length == 0">
<div class="not-data" v-if="statsEnterpriseRiskList.length == 0">
<img src="@/assets/images/noData.png" alt="" />
<p>暂无数据</p>
</div>
@ -111,15 +103,80 @@
import Card from "@/components/card.vue";
import { ref, watch, onMounted } from "vue";
import { GlobalStore } from "@/stores";
import { performanceAnalysisApi, statsEnterpriseRiskApi } from "@/api/modules/agjtCommandApi";
const store = GlobalStore();
const activeTab = ref(0);
const list = ref([
{waterMeterName: 123,waterTonnage:456},
{waterMeterName: 123,waterTonnage:456},
{waterMeterName: 123,waterTonnage:456},
{waterMeterName: 123,waterTonnage:456}
]) as any;
onMounted(async () => {});
const performanceAnalysisObj = ref({
aqyInServiceNum:0,
aqyNotPerformNum:0,
enterpriseName:0,
inServiceNum:0,
jlInServiceNum:0,
jlNotPerformNum:0,
notPerformNum:0,
xmjlInServiceNum:0,
xmjlNotPerformNum:0,
zlyInServiceNum:0,
zlyNotPerformNum:0
})
const performanceAnalysisList = ref([] as any)
const statsEnterpriseRiskObj = ref({
lowRiskNum: 0,
mediumRiskNum: 0,
highRiskNum: 0
})
const statsEnterpriseRiskList = ref([] as any)
// tab
const activeChange = (index:any) => {
activeTab.value = index;
if(index == 0){
performanceAnalysisFn(true)
} else {
statsEnterpriseRiskFn(true)
}
}
//
const performanceAnalysisFn = async (showLoading: boolean) => {
const res: any = await performanceAnalysisApi(
{
projectSn: store.sn
},
showLoading
);
if (res.result) {
console.log(res.result, "人员情况");
performanceAnalysisObj.value = res.result;
performanceAnalysisList.value = res.result.list || [];
}
};
//
const statsEnterpriseRiskFn = async (showLoading: boolean) => {
const res: any = await statsEnterpriseRiskApi(
{
projectSn: store.sn
},
showLoading
);
if (res.result) {
console.log(res.result, "三色评价");
// performanceAnalysisObj.value = res.result;
statsEnterpriseRiskList.value = res.result || [];
let dealData = {
lowRiskNum: 0,
mediumRiskNum: 0,
highRiskNum: 0
}
statsEnterpriseRiskList.value.map((item:any) => {
dealData.lowRiskNum += item.lowRiskNum
dealData.mediumRiskNum += item.mediumRiskNum
dealData.highRiskNum += item.highRiskNum
})
statsEnterpriseRiskObj.value = dealData
}
};
onMounted(async () => {
performanceAnalysisFn(true);
});
</script>
<style lang="scss" scoped>
@ -154,7 +211,7 @@ onMounted(async () => {});
width: 100%;
height: 100%;
padding-top: 1%;
.remark-top-data{
.remark-top-data {
display: flex;
align-items: center;
justify-content: space-around;
@ -197,7 +254,7 @@ onMounted(async () => {});
align-items: center;
width: 100%;
height: 31px;
background: rgba(0,122,255,0.19);
background: rgba(0, 122, 255, 0.19);
// position: absolute;
left: 75.5%;
top: 75%;
@ -220,7 +277,7 @@ onMounted(async () => {});
line-height: 30px;
margin-top: 0.5%;
cursor: pointer;
background: rgba(0,122,255,0.06);
background: rgba(0, 122, 255, 0.06);
div {
width: 25%;
text-align: center;
@ -228,7 +285,7 @@ onMounted(async () => {});
}
}
.listStyle:hover {
background: rgba(0,122,255,0.43);
background: rgba(0, 122, 255, 0.43);
}
}
}
@ -276,7 +333,7 @@ onMounted(async () => {});
align-items: center;
width: 100%;
height: 31px;
background: rgba(0,122,255,0.19);
background: rgba(0, 122, 255, 0.19);
// position: absolute;
left: 75.5%;
top: 75%;
@ -299,7 +356,7 @@ onMounted(async () => {});
line-height: 30px;
margin-top: 0.5%;
cursor: pointer;
background: rgba(0,122,255,0.06);
background: rgba(0, 122, 255, 0.06);
div {
width: 17%;
text-align: center;
@ -307,7 +364,7 @@ onMounted(async () => {});
}
}
.listStyle:hover {
background: rgba(0,122,255,0.43);
background: rgba(0, 122, 255, 0.43);
}
}
}

View File

@ -21,7 +21,7 @@
<video :src="BASEURL + '/image/' + projectData.videoUrl" class="videos" autoplay controls loop></video>
</div>
</Card>
<setVideoDialog ref="partyBuildRef"></setVideoDialog>
<setVideoDialog ref="partyBuildRef" @updateConfig="updateConfig"></setVideoDialog>
</div>
</template>
@ -30,13 +30,12 @@ import Card from "@/components/card.vue";
import { ref, onMounted, watch } from "vue";
import { GlobalStore } from "@/stores";
import { ElMessage } from "element-plus";
import { editProjectInfo, eidtProjectShowConfig, queryBySnData } from "@/api/modules/projectOverview";
import { selectLiveVideoListApi } from "@/api/modules/video";
import ckplayerComp from "./ckplayerComp.vue";
import { COMPANY } from "@/config/config";
import setVideoDialog from "@/components/setVideoDialog.vue";
import { configWeekVideoListApi } from "@/api/modules/agjtCommandApi";
import moment from "moment";
const store = GlobalStore();
const videoList = ref([] as any);
// ts
@ -66,29 +65,31 @@ watch(
}
}
);
//
const picUrl = ref("" as any);
const BASEURL = import.meta.env.VITE_API_URL;
//
const showVideo = ref(1 as any);
//
const showChangeImg = ref(false as any);
//
const showChangeVideo = ref(false as any);
let topText2 = ref([
{ id: 1, title: "现场视频", isActive: true },
{ id: 2, title: "宣传视频", isActive: false },
{ id: 3, title: "效果图", isActive: false }
]);
let topText = ref([
// { id: 1, title: "", isActive: true },
{ id: 2, title: "宣传视频", isActive: true },
{ id: 3, title: "效果图", isActive: false }
]);
//
const updateConfig = () => {
configWeekVideoListFn(true)
}
//
const configWeekVideoListFn = async (showLoading:boolean) => {
const res: any = await configWeekVideoListApi(
{
projectSn: store.sn
},
showLoading
);
if (res.result) {
//
const today = moment().format('d');
const weekParamsKey = ["sun","mon","tues","wed","thur","fri","sat"]
projectData.value.videoUrl = res.result[0][weekParamsKey[+today]]
}
}
const getVideoList = async () => {
let res: any = await selectLiveVideoListApi({
projectSn: store.sn
@ -111,152 +112,10 @@ const getVideoList = async () => {
}, 2000);
}
};
function boxStyle(item: any) {
if (item.isActive) {
let choiseStyle = {
color: "#fff"
};
return choiseStyle;
}
return {};
}
let tabIndex = ref(1 as any);
function activeBtn(item: any) {
let currentState = item.isActive;
if (!currentState) {
topText.value.forEach(el => {
el.isActive = false;
});
item.isActive = !currentState;
tabIndex.value = item.id;
}
showVideo.value = item.id;
console.log(showVideo.value)
}
const uploadFail = () => {
ElMessage({
showClose: true,
message: "上传失败,请重试",
type: "warning"
});
};
const fileTypeFail = (text: any) => {
ElMessage({
showClose: true,
message: text,
type: "warning"
});
};
const uploadSuccess = () => {
ElMessage({
showClose: true,
message: "上传成功",
type: "success"
});
};
//
function handleBeforeUploadVideo(file: any) {
console.log(file, "上传之前");
let fileType = file.type.split("/")[0];
if (fileType == "video") {
return true;
} else {
fileTypeFail("请选择正确的视频文件"); //""
return false;
}
}
//
function handleBeforeUploadPic(file: any) {
console.log(file, "上传之前");
let fileType = file.type.split("/")[0];
if (fileType == "image") {
return true;
} else {
fileTypeFail("请选择正确的图片文件"); //""
return false;
}
}
//
function handleError(file: any) {
console.log(file, "上传失败");
uploadFail(); //""
}
//
function handleSuccess(file: any) {
console.log("效果图上传成功", file);
if (file.code == 200 || file.status == "SUCCESS") {
console.log(file);
let url = file.data[0].imageUrl;
saveEffectData(url);
}
}
//
function handleSuccessTwo(file: any) {
if (file.code == 200 || file.status == "SUCCESS") {
console.log(file, "上传成功");
let url = file.data[0].imageUrl;
// this.imgUrl = url;
saveOrDeleteVideo(url);
}
}
//
function saveEffectData(url: any) {
// let configValue = JSON.stringify(url);
let data = {
projectSn: store.sn,
showType: 3,
showTitle: "效果图", //''
configValue: url
};
eidtProjectShowConfig(data).then((res: any) => {
if (res.code == 200) {
getQueryBySnData();
}
});
}
//
function getQueryBySnData() {
queryBySnData({
projectSn: store.sn,
showType: 3
}).then((res: any) => {
console.log(res, "效果图");
if (res.result) {
picUrl.value = res.result.configValue;
}
});
}
// //
function saveOrDeleteVideo(url) {
editProjectInfo({
projectSn: store.sn,
videoUrl: url
}).then(res => {
console.log("保存成功", res);
uploadSuccess(); //""
projectData.value.videoUrl = url;
});
}
//
defineExpose({
getQueryBySnData
})
onMounted(async () => {
if(COMPANY !== 'agjt') showVideo.value = 2
await getVideoList();
getQueryBySnData();
if(COMPANY != 'agjt'){
showVideo.value = 2;
}
await configWeekVideoListFn(true);
});
</script>

View File

@ -5,32 +5,45 @@
<div class="top-content">
<div class="top-content-left">
项目总进度
<span v-if="!projectData?.totalProjectDay" class="dayImg">0</span>
<span v-else class="dayImg" v-for="item in projectData?.totalProjectDay" :key="item">{{ item }}</span>
<span v-if="!projectData?.totalProgress" class="dayImg">0</span>
<span v-else class="dayImg" v-for="item in projectData?.totalProgress" :key="item">{{ item }}</span>
<span style="margin-left: 4%">%</span>
</div>
<div class="top-content-right">
项目剩余天数
<span v-if="!projectData?.totalProjectDay" class="dayImg">0</span>
<span v-else class="dayImg" v-for="item in projectData?.totalProjectDay" :key="item">{{ item }}</span>
<span v-if="!projectData?.projectRestDayNum" class="dayImg">0</span>
<span v-else class="dayImg" v-for="item in projectData?.projectRestDayNum" :key="item">{{ item }}</span>
<span style="margin-left: 4%"></span>
</div>
</div>
<div class="bottom-content">
<div class="bottom-content-item" v-for="(item,index) in topRank" :key="index">
<div class="item-one-style" :class="'item-one-style' + (index + 1)">Top{{ index + 1 }}</div>
<div class="item-two-style">
<div class="two-part-one">
<span>{{item.name}}</span>
<span>{{item.percent || 0}}%</span>
</div>
<div class="two-part-two">
<div class="bg-progress"></div>
<div class="finished-progress" :class="'finished-progress' + (index + 1)" :style="{width: item.percent + '%'}"></div>
<div class="finished-point" :class="'finished-point' + (index + 1)" :style="{left: item.percent + '%'}"></div>
<el-scrollbar class="list-box">
<div class="bottom-content-item" v-for="(item, index) in topRank" :key="index">
<div v-if="index < 2" class="item-one-style" :class="'item-one-style' + (index + 1)">Top{{ index + 1 }}</div>
<div v-else class="item-one-style item-one-style3">Top{{ index + 1 }}</div>
<div class="item-two-style">
<div class="two-part-one">
<span>{{ item.enterpriseName }}</span>
<span>{{ item.changeAfter || 0 }}%</span>
</div>
<div class="two-part-two">
<div class="bg-progress"></div>
<div
v-if="index < 2"
class="finished-progress"
:class="'finished-progress' + (index + 1)"
:style="{ width: item.changeAfter + '%' }"
></div>
<div
v-else
class="finished-progress finished-progress3"
:style="{ width: item.changeAfter + '%' }"
></div>
<div class="finished-point" :class="'finished-point' + (index + 1)" :style="{ left: item.changeAfter + '%' }"></div>
</div>
</div>
</div>
</div>
</el-scrollbar>
</div>
</div>
</Card>
@ -40,37 +53,71 @@
<script setup lang="ts">
import Card from "@/components/card.vue";
import { ref, onMounted, watch } from "vue";
// ts
type Props = {
statisticsCount?: any; //
};
// withDefaults ()
const props = withDefaults(defineProps<Props>(), {
statisticsCount: {
devcount: {}
}
});
import { getCountTaskProgressApi, queryCountEnterpriseApi } from "@/api/modules/agjtCommandApi";
import { GlobalStore } from "@/stores";
const store = GlobalStore();
const projectData = ref({
totalProjectDay: "180"
totalProgress: "180",
projectRestDayNum: "180"
});
const topRank = ref([
{
name: "广东省某某科技有限公司(东北厂区)",
percent: 70
enterpriseName: "广东省某某科技有限公司(东北厂区)",
changeAfter: 70
},
{
name: "广州市某公司名称(东北厂区)",
percent: 65
enterpriseName: "广州市某公司名称(东北厂区)",
changeAfter: 65
},
{
name: "企业名称(东北厂区)",
percent: 60
enterpriseName: "企业名称(东北厂区)",
changeAfter: 60
},
{
name: "这里是第四名企业名称(东北厂区)",
percent: 55
enterpriseName: "这里是第四名企业名称(东北厂区)",
changeAfter: 55
},
{
enterpriseName: "这里是第四名企业名称(东北厂区)",
changeAfter: 55
},
{
enterpriseName: "这里是第四名企业名称(东北厂区)",
changeAfter: 55
}
])
]);
//
const getCountTaskProgress = async (showLoading: boolean) => {
const res: any = await getCountTaskProgressApi(
{
projectSn: store.sn
},
showLoading
);
if (res.result) {
console.log(res.result, "项目剩余天数");
projectData.value.totalProgress = res.result.projectTotalProgress + "";
projectData.value.projectRestDayNum = res.result.projectSurplusDayNum + "";
}
};
//
const queryCountEnterprise = async (showLoading: boolean) => {
const res: any = await queryCountEnterpriseApi(
{
projectSn: store.sn,
isCountMainEnterprise: 1
},
showLoading
);
if (res.result) {
console.log(res.result, "总包项目进度");
topRank.value = res.result;
}
};
onMounted(() => {
getCountTaskProgress(true);
queryCountEnterprise(true);
});
</script>
<style lang="scss" scoped>
@ -79,6 +126,7 @@ const topRank = ref([
height: 100%;
display: flex;
.box-content {
height: 100%;
.top-content {
display: flex;
align-items: center;
@ -107,7 +155,11 @@ const topRank = ref([
.bottom-content {
margin: 0 2%;
margin-top: 6%;
&-item:not(:last-child){
height: 66%;
.list-box{
height: 100%;
}
&-item:not(:last-child) {
margin-bottom: 3%;
}
&-item {
@ -128,13 +180,13 @@ const topRank = ref([
background: linear-gradient(90deg, #e24a3b 0%, rgba(226, 74, 59, 0) 100%);
}
.item-one-style2 {
background: linear-gradient( 90deg, #C9B217 0%, rgba(201,178,23,0) 100%);
background: linear-gradient(90deg, #c9b217 0%, rgba(201, 178, 23, 0) 100%);
}
.item-one-style3 {
background: linear-gradient( 90deg, #3877F2 0%, rgba(56,119,242,0) 100%);
background: linear-gradient(90deg, #3877f2 0%, rgba(56, 119, 242, 0) 100%);
}
.item-one-style4 {
background: linear-gradient( 90deg, #3877F2 0%, rgba(56,119,242,0) 100%);
background: linear-gradient(90deg, #3877f2 0%, rgba(56, 119, 242, 0) 100%);
}
.item-two-style {
flex: 1;
@ -181,20 +233,20 @@ const topRank = ref([
background: linear-gradient(270deg, #e24a3b 0%, rgba(226, 74, 59, 0) 100%);
}
.finished-progress2 {
background: linear-gradient( 270deg, #C9B217 0%, rgba(201,178,23,0) 100%);
background: linear-gradient(270deg, #c9b217 0%, rgba(201, 178, 23, 0) 100%);
}
.finished-progress3 {
background: linear-gradient( 270deg, #3877F2 0%, rgba(56,119,242,0) 100%);
background: linear-gradient(270deg, #3877f2 0%, rgba(56, 119, 242, 0) 100%);
}
.finished-progress4 {
background: linear-gradient( 270deg, #3877F2 0%, rgba(56,119,242,0) 100%);
background: linear-gradient(270deg, #3877f2 0%, rgba(56, 119, 242, 0) 100%);
}
.finished-point{
.finished-point {
position: absolute;
top: 1px;
width: 3px;
height: 7px;
background: #FFFFFF;
background: #ffffff;
}
}
}

View File

@ -29,7 +29,6 @@ import Card from "@/components/card.vue";
import { GlobalStore } from "@/stores";
import { ref, onMounted, watch } from "vue";
import { getStageOption } from "@/api/modules/projectOverview";
// ts
type Props = {
projectData?: any; //

View File

@ -1,6 +1,17 @@
<template>
<div class="leftTop">
<Card title="隐患智能统计分析">
<div class="hRight">
<el-date-picker
style="width: 90%"
v-model="dateRange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD"
/>
</div>
<div class="box-content">
<div class="contentTop contentMiddle">
<div class="ctHead">
@ -36,7 +47,7 @@ import { onMounted, ref } from "vue";
import { GlobalStore } from "@/stores";
import * as echarts from "echarts";
const store = GlobalStore();
let questionTotal = ref(0 as any);
const dateRange = ref([] as any);
const echartsTest = ref();
const majorDangerCount = ref(0 as any);
const majorDangerRate = ref(0 as any);
@ -461,6 +472,12 @@ onMounted(async () => {
.leftTop {
width: 100%;
height: 100%;
.hRight {
width: 40%;
position: absolute;
top: 1%;
right: 0;
}
.box-content {
height: 100%;
.contentTop {
@ -541,4 +558,20 @@ onMounted(async () => {
::v-deep .h-card {
position: relative;
}
:deep() {
.el-input__wrapper{
width: 80%;
height: 0%;
background: #0d2956;
box-shadow: 0 0 0 1px #007AFF inset;
}
.el-range-separator {
color: #ccc;
font-size: 12px;
}
.el-range-input {
color: #ccc;
font-size: 12px;
}
}
</style>

View File

@ -56,6 +56,9 @@ import { useRouter } from "vue-router";
import { GlobalStore } from "@/stores";
import { jumpLargeUserInfoApi } from "@/api/modules/login";
import { COMPANY } from "@/config/config";
import {
getCountTaskProgressApi
} from "@/api/modules/agjtCommandApi";
const BASEURL = import.meta.env.VITE_API_URL;
const store = GlobalStore();
const projectData = ref({
@ -83,17 +86,18 @@ const itemList = ref([]);
const activeTab = ref(0);
const activeTab2 = ref(0);
const router = useRouter();
//tab
const getAllModelMenu = () => {
let half = store.projectDateAuth.moduleList;
half.forEach((item: any) => {
if (item.moduleType == 4) {
menuList.value.push(item);
return;
}
});
console.log("筛选出的数据看板路由", menuList.value);
//
const getCountTaskProgress = async (showLoading: boolean) => {
const res: any = await getCountTaskProgressApi(
{
projectSn: store.sn
},
showLoading
);
if (res.result) {
console.log(res.result,'项目剩余天数')
projectData.value.totalProjectDay = res.result.projectSurplusDayNum + "";
}
};
onMounted(async () => {
if (COMPANY === "agjtCommand") {
@ -124,7 +128,6 @@ onMounted(async () => {
// });
// console.log("", moduleListData.value);
}
// await getAllModelMenu();
activeTab.value = menuList.value[0].modulePath;
itemList.value = menuList.value[0].menuList;
@ -134,13 +137,7 @@ onMounted(async () => {
// menuClick(menuList.value[0], activeIndex.value);
getNowTime();
document.addEventListener("click", bodyCloseMenus);
const subMenus = document.querySelectorAll(".menStyle");
if (subMenus.length >= 5 && COMPANY !== "hfqc") {
subMenus[4].style.marginLeft = "30%";
}
if (COMPANY === "hfqc") {
subMenus[3].style.marginLeft = "44%";
}
getCountTaskProgress(true);
});
let timer = ref(null as any);

View File

@ -112,7 +112,6 @@ const login = (formEl: FormInstance | undefined) => {
// }
router.push("/commandScreen");
} else if (COMPANY === "agjtProjectKanban") {
router.push("/agjtProjectKanban");
if (![5, 10].includes(result.accountType)) {
ElMessage({
message: "账号类型不匹配",