|
@@ -16,601 +16,24 @@
|
|
|
<div class="page-main">
|
|
|
<div class="scroll-content">
|
|
|
<div class="col1">
|
|
|
- <div class="card">
|
|
|
- <div class="title">
|
|
|
- <span class="label">服务单元概览</span>
|
|
|
- </div>
|
|
|
- <div style="height: calc(100% - 140px)"
|
|
|
- ><my-chart :options="options1"></my-chart
|
|
|
- ></div>
|
|
|
- <div class="grid1-others">
|
|
|
- <div class="item">
|
|
|
- <div class="label">设备出库总量(台)</div>
|
|
|
- <p class="num">{{ result1?.equipmentOutboundTotal }}</p>
|
|
|
- </div>
|
|
|
- <div class="item">
|
|
|
- <div class="label">设备占用率(%)</div>
|
|
|
- <p class="num">{{ result1?.equipmentOccupancyRate }}</p>
|
|
|
- </div>
|
|
|
- <div class="item">
|
|
|
- <div class="label">在服务人员总数(人)</div>
|
|
|
- <p class="num">{{ result1?.servicePersonnelTotal }}</p>
|
|
|
- </div>
|
|
|
- <div class="item">
|
|
|
- <div class="label">现场人员占用率(%)</div>
|
|
|
- <p class="num">{{ result1?.sitePersonnelOccupancyRate }}</p>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="card">
|
|
|
- <div class="title">
|
|
|
- <span class="label">人力供应商项目数量分布及占比</span>
|
|
|
- </div>
|
|
|
- <div style="height: calc(100% - 36px)">
|
|
|
- <my-chart
|
|
|
- :options="options2"
|
|
|
- @chartClick="chart2Click"
|
|
|
- ></my-chart>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="col2">
|
|
|
- <div class="card" style="height: calc((100% - 206px) * 3 / 7)">
|
|
|
- <div class="title">
|
|
|
- <span class="label">人力供应商项目角色人员分布</span>
|
|
|
- <t-select
|
|
|
- v-model="supplierId"
|
|
|
- :options="supplierOptions"
|
|
|
- size="small"
|
|
|
- style="width: 150px"
|
|
|
- placeholder="请选择人力供应商"
|
|
|
- >
|
|
|
- </t-select>
|
|
|
- </div>
|
|
|
- <div class="box3 flex">
|
|
|
- <div style="width: 40%; height: 100%">
|
|
|
- <my-chart :options="options3"></my-chart>
|
|
|
- </div>
|
|
|
- <div class="grid3-others" style="width: 60%; height: 100%">
|
|
|
- <div class="num-show flex items-center justify-around">
|
|
|
- <div class="desc">
|
|
|
- <div class="label">实施工程师(人)</div>
|
|
|
- <div class="value">{{ ssgcsNum }}</div>
|
|
|
- </div>
|
|
|
- <div class="desc">
|
|
|
- <div class="label">区域协调人(人)</div>
|
|
|
- <div class="value">{{ qyxtrNum }}</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="desc-text"
|
|
|
- >覆盖{{ regionOptions?.length }}个大区:{{
|
|
|
- regionOptions.map((item) => item.label).join('、')
|
|
|
- }}</div
|
|
|
- >
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div
|
|
|
- class="card m-t-15px"
|
|
|
- style="height: calc((100% - 206px) * 4 / 7)"
|
|
|
- >
|
|
|
- <div class="title">
|
|
|
- <span class="label">项目角色待调配额盘点</span>
|
|
|
- <t-select
|
|
|
- v-model="regionId"
|
|
|
- :options="regionOptions"
|
|
|
- size="small"
|
|
|
- style="width: 150px"
|
|
|
- placeholder="请选择大区"
|
|
|
- >
|
|
|
- </t-select>
|
|
|
- </div>
|
|
|
- <div class="box4">
|
|
|
- <div class="charts-box">
|
|
|
- <div class="chart-item">
|
|
|
- <div class="chart-wrap">
|
|
|
- <my-chart :options="options41"></my-chart>
|
|
|
- </div>
|
|
|
- <div class="title-wrap">实施工程师</div>
|
|
|
- </div>
|
|
|
- <div class="chart-item">
|
|
|
- <div class="chart-wrap">
|
|
|
- <my-chart :options="options42"></my-chart>
|
|
|
- </div>
|
|
|
- <div class="title-wrap">区域协调人</div>
|
|
|
- </div>
|
|
|
- <div class="chart-item">
|
|
|
- <div class="chart-wrap">
|
|
|
- <my-chart :options="options43"></my-chart>
|
|
|
- </div>
|
|
|
- <div class="title-wrap">助理工程师</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="desc-text">
|
|
|
- <p
|
|
|
- >大区内同业务类型待划拨派单数量:{{
|
|
|
- result4?.projectWait
|
|
|
- }}个</p
|
|
|
- >
|
|
|
- <p>当前大区覆盖城市:{{ result4?.regionCities }}个</p>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="card m-t-15px" style="height: 80px">
|
|
|
- <div class="title">
|
|
|
- <span class="label">项目配额完成进度</span>
|
|
|
- </div>
|
|
|
- <div class="bar-box flex items-center">
|
|
|
- <div class="process-box">
|
|
|
- <div
|
|
|
- class="process"
|
|
|
- :style="{ width: (result5 || 0) * 100 + '%' }"
|
|
|
- ></div>
|
|
|
- </div>
|
|
|
- <span class="process-text m-l-10px">{{
|
|
|
- (result5 || 0) * 100 + '%'
|
|
|
- }}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="card m-t-15px" style="height: 80px">
|
|
|
- <div class="title">
|
|
|
- <span class="label">人员配额完成进度</span>
|
|
|
- </div>
|
|
|
- <div class="bar-box flex items-center">
|
|
|
- <div class="process-box">
|
|
|
- <div
|
|
|
- class="process"
|
|
|
- :style="{ width: (result6 || 0) * 100 + '%' }"
|
|
|
- ></div>
|
|
|
- </div>
|
|
|
- <span class="process-text m-l-10px">{{
|
|
|
- (result6 || 0) * 100 + '%'
|
|
|
- }}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="col3">
|
|
|
- <div class="card">
|
|
|
- <div class="title">
|
|
|
- <span class="label">设备供应商设备使用占比</span>
|
|
|
- </div>
|
|
|
- <div style="height: calc(100% - 36px)">
|
|
|
- <my-chart :options="options7"></my-chart>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="card">
|
|
|
- <div class="title">
|
|
|
- <span class="label">大区在服务人数分布及对比</span>
|
|
|
- <FullscreenIcon
|
|
|
- class="cursor-pointer"
|
|
|
- @click="chart8?.maximize"
|
|
|
- color="#595959"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div style="height: calc(100% - 36px)">
|
|
|
- <my-chart :options="options8" ref="chart8"></my-chart>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ <div class="row1"></div>
|
|
|
+ <div class="row2"></div>
|
|
|
</div>
|
|
|
+ <div class="col2"></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <SupplierDetailDrillDialog
|
|
|
- v-model:visible="showSupplierDetailDrill"
|
|
|
- :data="supplierDetailDrillData"
|
|
|
- :footer="false"
|
|
|
- ></SupplierDetailDrillDialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup name="ServiceAnalysis">
|
|
|
import { ref, computed, watch } from 'vue';
|
|
|
-import {
|
|
|
- createWaterBallOption,
|
|
|
- createRingPieOption,
|
|
|
- createCakePieOption,
|
|
|
- createStackingBarOption,
|
|
|
-} from '@/utils/chart';
|
|
|
+
|
|
|
import { useRequest } from 'vue-request';
|
|
|
-import {
|
|
|
- serviceOverviewAnalysis,
|
|
|
- supplierOverviewAnalysis,
|
|
|
- supplierRoleAnalysis,
|
|
|
- projectAllocateProcessAnalysis,
|
|
|
- personAllocateProcessAnalysis,
|
|
|
- projectRoleAnalysis,
|
|
|
- getRegionList,
|
|
|
- deviceUseAnalysis,
|
|
|
- personNumAnalysis,
|
|
|
- serviceServiceList,
|
|
|
-} from '@/api/report';
|
|
|
-import SupplierDetailDrillDialog from './supplier-detail-drill-dialog.vue';
|
|
|
+import {} from '@/api/report';
|
|
|
import { FullscreenIcon } from 'tdesign-icons-vue-next';
|
|
|
import { cloneDeep } from 'lodash-es';
|
|
|
-const chart8 = ref();
|
|
|
-
|
|
|
-const showSupplierDetailDrill = ref(false);
|
|
|
-const supplierDetailDrillData = ref({
|
|
|
- serviceUnitId: '',
|
|
|
- serviceName: '',
|
|
|
- supplierId: '',
|
|
|
- supplierName: '',
|
|
|
-});
|
|
|
-
|
|
|
-const chart2Click = (params) => {
|
|
|
- supplierDetailDrillData.value.supplierId = params.data.id;
|
|
|
- supplierDetailDrillData.value.supplierName = params.data.name;
|
|
|
- supplierDetailDrillData.value.serviceUnitId = serviceId.value;
|
|
|
- supplierDetailDrillData.value.serviceName = serviceOptions.value.find(
|
|
|
- (item) => item.id == serviceId.value
|
|
|
- )?.name;
|
|
|
- setTimeout(() => {
|
|
|
- showSupplierDetailDrill.value = true;
|
|
|
- }, 10);
|
|
|
-};
|
|
|
-const ssgcsNum = ref('');
|
|
|
-const qyxtrNum = ref('');
|
|
|
-const curTimeRange = ref([]);
|
|
|
-const serviceOptions = ref([]);
|
|
|
-const timeParams = computed(() => {
|
|
|
- return {
|
|
|
- startTime: new Date(curTimeRange.value[0] + ' 00:00:00').getTime(),
|
|
|
- endTime: new Date(curTimeRange.value[1] + ' 23:59:59').getTime(),
|
|
|
- };
|
|
|
-});
|
|
|
-const serviceId = ref('');
|
|
|
-const {
|
|
|
- data: result1,
|
|
|
- loading: loading1,
|
|
|
- run: run1,
|
|
|
-} = useRequest(serviceOverviewAnalysis); //服务单元概览
|
|
|
-
|
|
|
-const {
|
|
|
- data: result2,
|
|
|
- loading: loading2,
|
|
|
- runAsync: run2,
|
|
|
-} = useRequest(supplierOverviewAnalysis); //人力供应商项目数量分布及占比
|
|
|
-
|
|
|
-const {
|
|
|
- data: result3,
|
|
|
- loading: loading3,
|
|
|
- runAsync: run3,
|
|
|
-} = useRequest(supplierRoleAnalysis); //人力供应商项目角色人员分布
|
|
|
-
|
|
|
-const { data: regionList, runAsync: runGetRegionList } =
|
|
|
- useRequest(getRegionList); //获取大区列表
|
|
|
-
|
|
|
-const {
|
|
|
- data: result4,
|
|
|
- loading: loading4,
|
|
|
- run: run4,
|
|
|
-} = useRequest(projectRoleAnalysis); //项目角色待调配配额盘点
|
|
|
-
|
|
|
-const {
|
|
|
- data: result5,
|
|
|
- loading: loading5,
|
|
|
- run: run5,
|
|
|
-} = useRequest(projectAllocateProcessAnalysis); //项目调配完成进度
|
|
|
|
|
|
-const {
|
|
|
- data: result6,
|
|
|
- loading: loading6,
|
|
|
- run: run6,
|
|
|
-} = useRequest(personAllocateProcessAnalysis); //人员配额完成进度
|
|
|
-
|
|
|
-const {
|
|
|
- data: result7,
|
|
|
- loading: loading7,
|
|
|
- run: run7,
|
|
|
-} = useRequest(deviceUseAnalysis); //设备供应商设备使用占比
|
|
|
-
|
|
|
-const {
|
|
|
- data: result8,
|
|
|
- loading: loading8,
|
|
|
- run: run8,
|
|
|
-} = useRequest(personNumAnalysis); //大区在服务人数分布及对比
|
|
|
-
|
|
|
-const timeChange = (time) => {
|
|
|
- serviceServiceList(timeParams.value).then((res) => {
|
|
|
- serviceOptions.value = res || [];
|
|
|
- res?.length && (serviceId.value = res[0].id);
|
|
|
- });
|
|
|
-};
|
|
|
-
|
|
|
-watch(serviceId, (serviceUnitId) => {
|
|
|
- run1({ serviceUnitId });
|
|
|
- supplierId.value = '';
|
|
|
- regionId.value = '';
|
|
|
- result4.value = '';
|
|
|
- ssgcsNum.value = '';
|
|
|
- qyxtrNum.value = '';
|
|
|
- regionList.value = [];
|
|
|
- run2({ serviceUnitId }).then((res) => {
|
|
|
- if (!supplierId.value) {
|
|
|
- if (res.supplierDistribution?.length) {
|
|
|
- supplierId.value = res.supplierDistribution[0].id;
|
|
|
- }
|
|
|
- //赋值,默认选择第一个供应商
|
|
|
- //todo ...
|
|
|
- }
|
|
|
- });
|
|
|
- run5({ serviceUnitId });
|
|
|
- run6({ serviceUnitId });
|
|
|
- run7({ serviceUnitId });
|
|
|
- run8({ serviceUnitId });
|
|
|
-
|
|
|
- // runGetRegionList({ serviceUnitId: serviceId.value }).then((res) => {
|
|
|
- // if (res && res.length) {
|
|
|
- // regionId.value = res[0].region_id;
|
|
|
- // }
|
|
|
- // });
|
|
|
-});
|
|
|
-
|
|
|
-const supplierId = ref('');
|
|
|
-const supplierOptions = computed(() => {
|
|
|
- return (result2.value?.supplierDistribution || []).map((item) => {
|
|
|
- return { ...item, label: item.name, value: item.id };
|
|
|
- });
|
|
|
-});
|
|
|
-const regionId = ref('');
|
|
|
-const regionOptions = computed(() => {
|
|
|
- return (regionList.value || []).map((item) => {
|
|
|
- item.label = item.region_name;
|
|
|
- item.value = item.region_id;
|
|
|
- return item;
|
|
|
- });
|
|
|
-});
|
|
|
-watch(supplierId, (supplierId) => {
|
|
|
- if (supplierId) {
|
|
|
- run3({ serviceUnitId: serviceId.value, supplierId }).then((res) => {
|
|
|
- let obj1 = res.find(
|
|
|
- (item) => item.NAME === '实施工程师' || item.name === '实施工程师'
|
|
|
- );
|
|
|
- let obj2 = res.find(
|
|
|
- (item) => item.NAME === '区域协调人' || item.name === '区域协调人'
|
|
|
- );
|
|
|
- ssgcsNum.value = obj1?.count || 0;
|
|
|
- qyxtrNum.value = obj2?.count || 0;
|
|
|
- });
|
|
|
- runGetRegionList({ serviceUnitId: serviceId.value, supplierId }).then(
|
|
|
- (res) => {
|
|
|
- if (res && res.length) {
|
|
|
- regionId.value = res[0].region_id;
|
|
|
- }
|
|
|
- }
|
|
|
- );
|
|
|
- }
|
|
|
-});
|
|
|
-watch(regionId, (regionId) => {
|
|
|
- if (regionId) {
|
|
|
- run4({
|
|
|
- serviceUnitId: serviceId.value,
|
|
|
- supplierId: supplierId.value,
|
|
|
- regionId,
|
|
|
- });
|
|
|
- }
|
|
|
-});
|
|
|
-
|
|
|
-const options1 = computed(() => {
|
|
|
- return createWaterBallOption({
|
|
|
- data: (result1.value?.projectProgress || 0) / 100,
|
|
|
- title: '项目执行进度',
|
|
|
- radius: '80%',
|
|
|
- });
|
|
|
-});
|
|
|
-
|
|
|
-const options2 = computed(() => {
|
|
|
- const supplierDistribution = result2.value?.supplierDistribution || [];
|
|
|
-
|
|
|
- return createRingPieOption(
|
|
|
- {
|
|
|
- data: supplierDistribution.map((item) => {
|
|
|
- return { ...item, name: item.name || 'null', value: item.count };
|
|
|
- }),
|
|
|
- title: '派单数',
|
|
|
- center: ['50%', '30%'],
|
|
|
- seriesName: '数量',
|
|
|
- radius: [40, 60],
|
|
|
- },
|
|
|
- {
|
|
|
- legend: {
|
|
|
- // type: 'scroll',
|
|
|
- orient: 'horizontal',
|
|
|
- top: null,
|
|
|
- right: null,
|
|
|
- bottom: '0%',
|
|
|
- left: 'center',
|
|
|
- },
|
|
|
- }
|
|
|
- );
|
|
|
-});
|
|
|
-
|
|
|
-const options3 = computed(() => {
|
|
|
- let data = (result3.value || []).map((item) => {
|
|
|
- item.value = item.count;
|
|
|
- item.name = item.NAME || item.name;
|
|
|
- return item;
|
|
|
- });
|
|
|
- return createCakePieOption(
|
|
|
- {
|
|
|
- data: data,
|
|
|
- radius: [0, 50],
|
|
|
- center: ['50%', '50%'],
|
|
|
- seriesName: '角色分布',
|
|
|
- },
|
|
|
- {
|
|
|
- legend: {
|
|
|
- show: false,
|
|
|
- },
|
|
|
- }
|
|
|
- );
|
|
|
-});
|
|
|
-
|
|
|
-const options41 = computed(() => {
|
|
|
- let projectRoleQuota = result4.value?.projectRoleQuota;
|
|
|
- return createWaterBallOption({
|
|
|
- data: projectRoleQuota?.effectQuota
|
|
|
- ? projectRoleQuota.effectDistributed / projectRoleQuota.effectQuota
|
|
|
- : 0,
|
|
|
- title: projectRoleQuota
|
|
|
- ? `剩${
|
|
|
- projectRoleQuota.effectQuota - projectRoleQuota.effectDistributed
|
|
|
- }配额`
|
|
|
- : loading4.value
|
|
|
- ? 'Loading...'
|
|
|
- : '无数据',
|
|
|
- radius: '80%',
|
|
|
- });
|
|
|
-});
|
|
|
-const options42 = computed(() => {
|
|
|
- let projectRoleQuota = result4.value?.projectRoleQuota;
|
|
|
- return createWaterBallOption({
|
|
|
- data: projectRoleQuota?.coordinatorQuota
|
|
|
- ? projectRoleQuota.coordinatorDistributed /
|
|
|
- projectRoleQuota.coordinatorQuota
|
|
|
- : 0,
|
|
|
- title: projectRoleQuota
|
|
|
- ? `剩${
|
|
|
- projectRoleQuota.coordinatorQuota -
|
|
|
- projectRoleQuota.coordinatorDistributed
|
|
|
- }配额`
|
|
|
- : loading4.value
|
|
|
- ? 'Loading...'
|
|
|
- : '无数据',
|
|
|
- radius: '80%',
|
|
|
- color: '35, 195, 67',
|
|
|
- });
|
|
|
-});
|
|
|
-const options43 = computed(() => {
|
|
|
- let projectRoleQuota = result4.value?.projectRoleQuota;
|
|
|
- return createWaterBallOption({
|
|
|
- data: projectRoleQuota?.assistantQuota
|
|
|
- ? projectRoleQuota.assistantDistributed / projectRoleQuota.assistantQuota
|
|
|
- : 0,
|
|
|
- title: projectRoleQuota
|
|
|
- ? `剩${
|
|
|
- projectRoleQuota.assistantQuota -
|
|
|
- projectRoleQuota.assistantDistributed
|
|
|
- }配额`
|
|
|
- : loading4.value
|
|
|
- ? 'Loading...'
|
|
|
- : '无数据',
|
|
|
- radius: '80%',
|
|
|
- color: '255, 154, 46',
|
|
|
- });
|
|
|
-});
|
|
|
-const options7 = computed(() => {
|
|
|
- return createCakePieOption(
|
|
|
- {
|
|
|
- data: (result7.value || []).map((item) => ({
|
|
|
- name: item.name,
|
|
|
- value: item.outs,
|
|
|
- })),
|
|
|
- radius: [0, 60],
|
|
|
- center: ['50%', '30%'],
|
|
|
- seriesName: '设备使用占比',
|
|
|
- },
|
|
|
- {
|
|
|
- legend: {
|
|
|
- // type: 'scroll',
|
|
|
- orient: 'horizontal',
|
|
|
- top: null,
|
|
|
- right: null,
|
|
|
- bottom: '0%',
|
|
|
- left: 'center',
|
|
|
- },
|
|
|
- }
|
|
|
- );
|
|
|
-});
|
|
|
-
|
|
|
-const options8 = computed(() => {
|
|
|
- let res = result8.value || {};
|
|
|
- let xData = (res.regionPersonnelInfo || []).map((item) => item.regionName);
|
|
|
- let regionPersonnelInfo = res.regionPersonnelInfo || [];
|
|
|
- let allSupplier = regionPersonnelInfo
|
|
|
- .map((item) => item.supplierPersonnelInfo)
|
|
|
- .flat();
|
|
|
- let supplierIdSet = res.supplierIdSet || [];
|
|
|
- for (let i = 0; i < regionPersonnelInfo.length; i++) {
|
|
|
- let item = regionPersonnelInfo[i];
|
|
|
- let arr = [];
|
|
|
- for (let j = 0; j < supplierIdSet.length; j++) {
|
|
|
- let find = item.supplierPersonnelInfo.find(
|
|
|
- (v) => v.supplierId == supplierIdSet[j]
|
|
|
- );
|
|
|
- let find2 = allSupplier.find((v) => v.supplierId == supplierIdSet[j]);
|
|
|
- arr.push(
|
|
|
- find ? cloneDeep(find) : { supplierName: find2.supplierName, count: 0 }
|
|
|
- );
|
|
|
- }
|
|
|
- item.supplierPersonnelInfo = arr;
|
|
|
- }
|
|
|
- let matrixArr = regionPersonnelInfo.map((item) => item.supplierPersonnelInfo);
|
|
|
- let sData = [];
|
|
|
- let names = [];
|
|
|
- if (supplierIdSet.length) {
|
|
|
- let first = regionPersonnelInfo[0];
|
|
|
- names = first.supplierPersonnelInfo.map((item) => item.supplierName);
|
|
|
- }
|
|
|
- for (let i = 0; i < names.length; i++) {
|
|
|
- let data = matrixArr.map((arr) => arr[i].count);
|
|
|
- sData.push({ name: names[i], data });
|
|
|
- }
|
|
|
- // res = res.map((item) => {
|
|
|
- // if (!item.name) {
|
|
|
- // item.name = 'null';
|
|
|
- // }
|
|
|
- // return item;
|
|
|
- // });
|
|
|
- // let xData = Array.from(new Set(res.map((item) => item.region_name)));
|
|
|
- // let names = Array.from(new Set(res.map((item) => item.name)));
|
|
|
- // let sData = [];
|
|
|
- // for (let i = 0; i < names.length; i++) {
|
|
|
- // let data = [];
|
|
|
- // for (let j = 0; j < xData.length; j++) {
|
|
|
- // let find = res.find(
|
|
|
- // (v) => v.name == names[i] && v.region_name == xData[j]
|
|
|
- // );
|
|
|
- // data.push(find?.count || 0);
|
|
|
- // }
|
|
|
- // sData.push({
|
|
|
- // name: names[i],
|
|
|
- // data: data,
|
|
|
- // });
|
|
|
- // }
|
|
|
- return createStackingBarOption(
|
|
|
- {
|
|
|
- xData: xData,
|
|
|
- // seriesData: [
|
|
|
- // { name: '阳光雨露', data: [322.1, 421.4, 100.9, 662, 200.03] },
|
|
|
- // { name: '软通智服', data: [990.84, 400, 343.5, 200.3, 552] },
|
|
|
- // ],
|
|
|
- seriesData: sData,
|
|
|
- },
|
|
|
- {
|
|
|
- tooltip: {
|
|
|
- formatter: function (obj) {
|
|
|
- let name = obj[0].name;
|
|
|
- let str = name + '<br />';
|
|
|
-
|
|
|
- for (let i = 0; i < obj.length; i++) {
|
|
|
- str =
|
|
|
- obj[i].value !== 0
|
|
|
- ? str +
|
|
|
- '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:' +
|
|
|
- obj[i]['color'] +
|
|
|
- ';"></span>' +
|
|
|
- obj[i]['seriesName'] +
|
|
|
- ' : ' +
|
|
|
- obj[i]['value'] +
|
|
|
- '<br />'
|
|
|
- : str + '';
|
|
|
- }
|
|
|
- return str;
|
|
|
- },
|
|
|
- },
|
|
|
- }
|
|
|
- );
|
|
|
-});
|
|
|
+watch(serviceId, (serviceUnitId) => {});
|
|
|
</script>
|
|
|
|
|
|
<style lang="less" scoped>
|
|
@@ -624,142 +47,6 @@ const options8 = computed(() => {
|
|
|
min-height: 600px;
|
|
|
min-width: 1000px;
|
|
|
display: flex;
|
|
|
-
|
|
|
- .col1,
|
|
|
- .col3 {
|
|
|
- width: 268px;
|
|
|
- height: 100%;
|
|
|
- .card {
|
|
|
- height: calc((100% - 15px) / 2);
|
|
|
- &:last-child {
|
|
|
- margin-top: 15px;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- .col2 {
|
|
|
- width: calc(100% - 566px);
|
|
|
- margin-left: 15px;
|
|
|
- margin-right: 15px;
|
|
|
- .process-text {
|
|
|
- font-size: 12px;
|
|
|
- color: #262626;
|
|
|
- width: 40px;
|
|
|
- }
|
|
|
- .process-box {
|
|
|
- flex: 1;
|
|
|
- background-color: #d9d9d9;
|
|
|
- height: 6px;
|
|
|
- border-radius: 3px;
|
|
|
- overflow: hidden;
|
|
|
- .process {
|
|
|
- background-color: #4080ff;
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
- }
|
|
|
- .box4 {
|
|
|
- height: calc(100% - 36px);
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- .charts-box {
|
|
|
- height: calc(100% - 68px);
|
|
|
- display: flex;
|
|
|
- justify-content: space-around;
|
|
|
- .chart-item {
|
|
|
- width: 33.3%;
|
|
|
- max-width: 246px;
|
|
|
- height: 100%;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- .chart-wrap {
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
- .title-wrap {
|
|
|
- text-align: center;
|
|
|
- color: #595959;
|
|
|
- font-size: 12px;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- .desc-text {
|
|
|
- margin-top: 10px;
|
|
|
- background-color: #f7f7f7;
|
|
|
- border-radius: 2px;
|
|
|
- padding: 8px 15px;
|
|
|
- font-size: 12px;
|
|
|
- color: #262626;
|
|
|
- height: 58px;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- justify-content: space-around;
|
|
|
- }
|
|
|
- }
|
|
|
- .box3 {
|
|
|
- height: calc(100% - 36px);
|
|
|
- .grid3-others {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- justify-content: space-around;
|
|
|
- .desc-text {
|
|
|
- background-color: #f7f7f7;
|
|
|
- border-radius: 2px;
|
|
|
- padding: 8px 15px;
|
|
|
- line-height: 1.4;
|
|
|
- font-size: 12px;
|
|
|
- color: #262626;
|
|
|
- }
|
|
|
- .num-show {
|
|
|
- .desc {
|
|
|
- .label {
|
|
|
- color: #8c8c8c;
|
|
|
- font-size: 12px;
|
|
|
- }
|
|
|
- .value {
|
|
|
- color: #165dff;
|
|
|
- font-size: 16px;
|
|
|
- font-weight: bold;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- .grid1-others {
|
|
|
- height: 104px;
|
|
|
- display: flex;
|
|
|
- flex-wrap: wrap;
|
|
|
- align-content: space-around;
|
|
|
- .item {
|
|
|
- width: 50%;
|
|
|
- text-align: center;
|
|
|
- .num {
|
|
|
- color: #165dff;
|
|
|
- font-size: 16px;
|
|
|
- font-weight: bold;
|
|
|
- }
|
|
|
- .label {
|
|
|
- font-size: 12px;
|
|
|
- color: #8c8c8c;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .card {
|
|
|
- padding: 4px 10px 10px 10px;
|
|
|
- background-color: #fff;
|
|
|
- border: 1px solid #e5e5e5;
|
|
|
- border-radius: 4px;
|
|
|
- .title {
|
|
|
- height: 36px;
|
|
|
- display: flex;
|
|
|
- justify-content: space-between;
|
|
|
- align-items: center;
|
|
|
- .label {
|
|
|
- color: #262626;
|
|
|
- font-size: 14px;
|
|
|
- // font-weight: bold;
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
}
|