3 files modified
11 files added
| New file |
| | |
| | | import request from '@/axios' |
| | | |
| | | // 字典查询 行业 算法 工单类型 |
| | | export const getDictionary = params => { |
| | | return request({ |
| | | url: `/blade-system/dict-biz/listByCodes?code=${params}`, |
| | | method: 'get', |
| | | }) |
| | | } |
| | | |
| | | // 区域 |
| | | export const deptsByAreaCode = params => { |
| | | return request({ |
| | | url: `/blade-system/dept/deptsByAreaCode`, |
| | | method: 'get', |
| | | params, |
| | | }) |
| | | } |
| | | |
| | | // 获取机场信息 |
| | | export const getDockInfo = params => { |
| | | return request({ |
| | | url: `/drone-device-core/dp/home/getDockInfo`, |
| | | method: 'get', |
| | | params, |
| | | }) |
| | | } |
| New file |
| | |
| | | import request from '@/axios' |
| | | |
| | | // 任务总数统计 |
| | | export const totalJobNum = params => { |
| | | return request({ |
| | | url: '/drone-device-core/wayline/waylineJobInfo/totalJobNum', |
| | | method: 'get', |
| | | params: params, |
| | | }) |
| | | } |
| | | // 其他任务统计 |
| | | export const jobStatistics = data => { |
| | | return request({ |
| | | url: '/drone-device-core/wayline/waylineJobInfo/jobStatistics', |
| | | method: 'post', |
| | | data: data, |
| | | }) |
| | | } |
| | | // 行业任务统计 |
| | | export const industryJobNumPieChart = data => { |
| | | return request({ |
| | | url: '/drone-device-core/wayline/waylineJobInfo/industryJobNumPieChart', |
| | | method: 'post', |
| | | data: data, |
| | | }) |
| | | } |
| | | // 时间任务统计 |
| | | export const jobNumBar = data => { |
| | | return request({ |
| | | url: '/drone-device-core/wayline/waylineJobInfo/jobNumBar', |
| | | method: 'post', |
| | | data: data, |
| | | }) |
| | | } |
| | | // 事件任务统计 |
| | | export const jobEventBar = data => { |
| | | return request({ |
| | | url: '/drone-device-core/wayline/waylineJobInfo/jobEventBar', |
| | | method: 'post', |
| | | data: data, |
| | | }) |
| | | } |
| | | // 任务列表 |
| | | export const jobList = data => { |
| | | return request({ |
| | | url: '/drone-device-core/wayline/waylineJobInfo/jobList?current=' + data.current + '&size=' + data.size, |
| | | method: 'post', |
| | | data: {}, |
| | | }) |
| | | } |
| | | |
| | | |
| | |
| | | setToken(token) |
| | | state.token = token |
| | | setStore({ name: 'token', content: state.token }) |
| | | console.log('顶顶顶111', token) |
| | | window.localStorage.setItem(ELocalStorageKey.Token, token) |
| | | }, |
| | | SET_REFRESH_TOKEN: (state, refreshToken) => { |
| | |
| | | <!--时间 天气--> |
| | | <common-weather></common-weather> |
| | | <!-- 机巢数据 --> |
| | | <MachineData></MachineData> |
| | | <MachineData></MachineData> |
| | | <div class="do-return" @click="goBack"> |
| | | <img src="@/assets/images/signMachineNest/return.png" alt="" /> |
| | | </div> |
| | | <!--巡检任务详情--> |
| | | <InspectionRaskDetails></InspectionRaskDetails> |
| | | </div> |
| | |
| | | import CommonWeather from '@/components/CommonWeather.vue'; |
| | | import MachineData from './MachineData.vue'; |
| | | import InspectionRaskDetails from './InspectionRaskDetails.vue'; |
| | | import { useRouter } from 'vue-router'; |
| | | |
| | | const router = useRouter(); |
| | | |
| | | const goBack = () => { |
| | | router.push('/index'); |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | |
| | | position: absolute; |
| | | top: 88px; |
| | | color: #e7f5ff; |
| | | .do-return { |
| | | position: absolute; |
| | | top: 56px; |
| | | right: -50px; |
| | | cursor: pointer; |
| | | img { |
| | | width: 40px; |
| | | height: 40px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <script setup> |
| | | |
| | | import TaskLeft from "./components/TaskLeft/TaskLeft.vue"; |
| | | import TaskRight from "./components/TaskRight/TaskRight.vue"; |
| | | import TaskIntermediateContent from "./components/TaskIntermediateContent/TaskIntermediateContent.vue"; |
| | | </script> |
| | | |
| | | <template> |
| | | TaskManage |
| | | <TaskLeft/> |
| | | <TaskIntermediateContent /> |
| | | <TaskRight/> |
| | | </template> |
| | | |
| | | |
| | | <style scoped lang="scss"> |
| | | |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <div class="search-box"> |
| | | <el-form :model="searchForm" inline> |
| | | <el-form-item label="任务名称"> |
| | | <el-input v-model="searchForm.name" placeholder="请输入任务名称" clearable /> |
| | | </el-form-item> |
| | | <el-form-item label="所属部门"> |
| | | <el-select |
| | | v-model="searchForm.deptId" |
| | | placeholder="请选择部门" |
| | | clearable |
| | | > |
| | | <el-tree-select |
| | | v-model="searchForm.deptId" |
| | | :data="deptTreeData" |
| | | node-key="id" |
| | | :props="{ |
| | | label: 'name', |
| | | children: 'children' |
| | | }" |
| | | check-strictly |
| | | clearable |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="周期"> |
| | | <el-select v-model="searchForm.status" placeholder="请选择状态" clearable> |
| | | <el-option label="日" value="日" /> |
| | | <el-option label="周" value="周" /> |
| | | <el-option label="月" value="月" /> |
| | | <el-option label="年" value="年" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="任务状态"> |
| | | <el-select v-model="searchForm.status" placeholder="请选择状态" clearable> |
| | | <el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="任务时间"> |
| | | <el-date-picker |
| | | v-model="searchForm.dateRange" |
| | | type="daterange" |
| | | range-separator="至" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | value-format="YYYY-MM-DD" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="任务算法"> |
| | | <el-select v-model="searchForm.status" placeholder="请选择状态" clearable> |
| | | <el-option label="识别火情" value="日" /> |
| | | <el-option label="识别车辆" value="周" /> |
| | | <el-option label="识别船只" value="月" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="handleSearch">查询</el-button> |
| | | <el-button @click="handleReset">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </template> |
| | | <script setup> |
| | | import { getDictionary, deptsByAreaCode, getDockInfo } from '@/api/home/common'; |
| | | |
| | | |
| | | const searchForm = reactive({ |
| | | name: '', |
| | | job_info_num: '', |
| | | status: '', |
| | | dateRange: [] |
| | | }); |
| | | const statusOptions = [ |
| | | { label: '待执行', value: 1 }, |
| | | { label: '执行中', value: 2 }, |
| | | { label: '已完成', value: 3 }, |
| | | { label: '已取消', value: 4 }, |
| | | { label: '执行失败', value: 5 } |
| | | ]; |
| | | |
| | | // 部门以及机巢 |
| | | const deptTreeData = ref([]); |
| | | |
| | | const emit = defineEmits(['search']); |
| | | |
| | | const handleSearch = () => { |
| | | emit('search', { |
| | | ...searchForm, |
| | | begin_time: searchForm.dateRange[0], |
| | | end_time: searchForm.dateRange[1] |
| | | }); |
| | | }; |
| | | |
| | | const handleReset = () => { |
| | | searchForm.name = ''; |
| | | searchForm.job_info_num = ''; |
| | | searchForm.status = ''; |
| | | searchForm.dateRange = []; |
| | | handleSearch(); |
| | | }; |
| | | |
| | | // 请求字典字段 |
| | | const requestDictionary = () => { |
| | | getDictionary('SF,HYLB').then((res) => { |
| | | if (res.data.code !== 0) { |
| | | // 处理数据 |
| | | console.log('111111',res.data) |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // 处理部门数据为树形结构 |
| | | const handleDeptData = (data) => { |
| | | const buildTree = (items, parentId = 0) => { |
| | | const result = []; |
| | | for (const item of items) { |
| | | if (item.parent_id === parentId) { |
| | | const children = buildTree(items, item.id); |
| | | if (children.length) { |
| | | item.children = children; |
| | | } |
| | | result.push(item); |
| | | } |
| | | } |
| | | return result; |
| | | }; |
| | | return buildTree(data); |
| | | }; |
| | | // 部门信息 |
| | | const getDeptsByAreaCode = () => { |
| | | deptsByAreaCode().then((res) => { |
| | | if (res.data.code !== 0) { |
| | | deptTreeData.value = res.data; |
| | | // 处理数据 |
| | | console.log('22222',res.data) |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // 机巢信息 |
| | | const requestDockInfo = () => { |
| | | getDockInfo().then((res) => { |
| | | if (res.data.code !== 0) { |
| | | // 处理数据 |
| | | console.log('33333',res.data) |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | |
| | | onMounted(() => { |
| | | requestDictionary(); |
| | | deptsByAreaCode(); |
| | | requestDockInfo(); |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .search-box { |
| | | position: absolute; |
| | | top: 120px; |
| | | left: 450px; |
| | | width: calc(100% - 400px - 400px - 100px); |
| | | height:60px; |
| | | color: #fff; |
| | | background: rgba(31, 62, 122, 0.35); |
| | | padding: 10px 20px; |
| | | |
| | | :deep(.el-form) { |
| | | --el-text-color-regular: #fff; |
| | | |
| | | .el-form-item { |
| | | margin-bottom: 0; |
| | | margin-right: 20px; |
| | | |
| | | .el-form-item__label { |
| | | color: #fff; |
| | | } |
| | | |
| | | .el-input, |
| | | .el-select, |
| | | .el-date-editor { |
| | | width: 200px; |
| | | --el-input-bg-color: transparent; |
| | | --el-input-border-color: rgba(255, 255, 255, 0.3); |
| | | --el-input-text-color: #fff; |
| | | --el-input-placeholder-color: rgba(255, 255, 255, 0.5); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <!-- 任务统计表格 --> |
| | | <template> |
| | | <SearchBox></SearchBox> |
| | | <div class="task-intermediate-content"> |
| | | <el-table :data="jobListData" style="width: 100%" height="calc(100vh - 180px)"> |
| | | <el-table-column label="序号" width="60"> |
| | | <template #default="scope"> |
| | | {{ (jobListParams.page - 1) * jobListParams.limit + scope.$index + 1 }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="job_info_num" label="任务编号" /> |
| | | <el-table-column prop="name" label="任务名称" /> |
| | | <el-table-column prop="dept_name" label="所属部门" /> |
| | | <el-table-column prop="device_names" label="所属机巢" /> |
| | | <el-table-column prop="ai_type_str" label="关联算法" /> |
| | | <el-table-column prop="status" label="任务状态" > |
| | | <template #default="scope"> |
| | | <el-tag :type="getStatusType(scope.row.status)"> |
| | | {{ getStatusText(scope.row.status) }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="industry_type_str" label="任务类型" /> |
| | | <el-table-column prop="event_number" label="关联事件" /> |
| | | <el-table-column prop="begin_time" label="任务时间" /> |
| | | <el-table-column prop="creator_name" label="创建人" /> |
| | | <el-table-column label="操作" > |
| | | <template #default="scope"> |
| | | <el-button link type="primary" @click="handleDetail(scope.row)">查看</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <div class="pagination"> |
| | | <el-pagination |
| | | v-model:current-page="jobListParams.page" |
| | | v-model:page-size="jobListParams.limit" |
| | | :page-sizes="[10, 20, 30, 50]" |
| | | layout="total, sizes, prev, pager, next" |
| | | :total="total" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handleCurrentChange" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import SearchBox from '../SearchBox.vue'; |
| | | import { jobList } from '@/api/home/task'; |
| | | |
| | | const jobListParams = reactive({ |
| | | page: 1, |
| | | limit: 10, |
| | | }); |
| | | const jobListData = ref([]); |
| | | const total = ref(0); |
| | | |
| | | // 获取任务列表 |
| | | const getJobList = () => { |
| | | jobList({current:1,size:10}).then(res => { |
| | | if (res.data.code !== 0) return; |
| | | jobListData.value = res.data.data.records; |
| | | total.value = res.data.data.total; |
| | | }); |
| | | }; |
| | | // 状态文字 |
| | | const getStatusText = (status) => { |
| | | const statusMap = { |
| | | 1: '待执行', |
| | | 2: '执行中', |
| | | 3: '已完成', |
| | | 4: '已取消', |
| | | 5: '执行失败' |
| | | }; |
| | | return statusMap[status] || '未知'; |
| | | }; |
| | | |
| | | // 状态标签类型 |
| | | const getStatusType = (status) => { |
| | | const typeMap = { |
| | | 1: 'info', |
| | | 2: 'warning', |
| | | 3: 'success', |
| | | 4: '', |
| | | 5: 'danger' |
| | | }; |
| | | return typeMap[status] || ''; |
| | | }; |
| | | |
| | | // 查看详情 |
| | | const handleDetail = (row) => { |
| | | console.log('查看详情', row); |
| | | }; |
| | | |
| | | // 分页大小改变 |
| | | const handleSizeChange = (val) => { |
| | | jobListParams.limit = val; |
| | | getJobList(); |
| | | }; |
| | | |
| | | // 页码改变 |
| | | const handleCurrentChange = (val) => { |
| | | jobListParams.page = val; |
| | | getJobList(); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getJobList(); |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .task-intermediate-content { |
| | | position: absolute; |
| | | top: 190px; |
| | | width: calc(100% - 400px - 400px - 100px); |
| | | left: 450px; |
| | | height: 770px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: space-between; |
| | | |
| | | :deep(.el-table) { |
| | | background-color: transparent; |
| | | --el-table-tr-bg-color: transparent; |
| | | --el-table-border-color: rgba(255, 255, 255, 0.1); |
| | | --el-table-header-bg-color: rgba(31, 62, 122, 0.5); |
| | | --el-table-header-text-color: #fff; |
| | | --el-table-text-color: #fff; |
| | | .el-table__body tr:hover > td { |
| | | background-color: rgba(31, 62, 122, 0.3) !important; |
| | | } |
| | | } |
| | | |
| | | .pagination { |
| | | padding: 20px 0; |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | |
| | | :deep(.el-pagination) { |
| | | --el-pagination-bg-color: transparent; |
| | | --el-pagination-text-color: #fff; |
| | | --el-pagination-button-color: #fff; |
| | | --el-pagination-hover-color: #409eff; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <!-- 业务统计 --> |
| | | <template> |
| | | <common-title title="行业统计" :style="{ marginLeft: pxToRem(14) }"></common-title> |
| | | <div class="task-industry"> |
| | | <div class="chart" ref="chartRef"></div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import CommonTitle from '@/components/CommonTitle.vue'; |
| | | import * as echarts from 'echarts'; |
| | | import { industryJobNumPieChart } from '@/api/home/task'; |
| | | const chartRef = ref(null); |
| | | let chart = null; |
| | | |
| | | const option = { |
| | | tooltip: { |
| | | trigger: 'item', |
| | | formatter: '{b}: {c} ({d}%)' |
| | | }, |
| | | legend: { |
| | | orient: 'horizontal', |
| | | left: 'center', |
| | | bottom: '5%', |
| | | textStyle: { |
| | | color: '#fff', |
| | | fontSize: 12 |
| | | }, |
| | | itemWidth: 10, |
| | | itemHeight: 10, |
| | | itemGap: 10, |
| | | formatter: function(name) { |
| | | let data = option.series[0].data; |
| | | let total = 0; |
| | | let tarValue = 0; |
| | | for (let i = 0; i < data.length; i++) { |
| | | total += data[i].value; |
| | | if (data[i].name === name) { |
| | | tarValue = data[i].value; |
| | | } |
| | | } |
| | | let percentage = ((tarValue / total) * 100).toFixed(1); |
| | | return `${name} ${percentage}%`; |
| | | } |
| | | }, |
| | | series: [ |
| | | { |
| | | name: '行业统计', |
| | | type: 'pie', |
| | | radius: '60%', |
| | | center: ['35%', '50%'], |
| | | itemStyle: { |
| | | borderRadius: 4, |
| | | borderColor: 'rgba(255,255,255,0.2)', |
| | | borderWidth: 1 |
| | | }, |
| | | label: { |
| | | show: true, |
| | | position: 'inside', |
| | | formatter: '{c}', |
| | | fontSize: 12, |
| | | color: '#fff' |
| | | }, |
| | | labelLine: { |
| | | show: false |
| | | }, |
| | | emphasis: { |
| | | scale: true, |
| | | scaleSize: 10 |
| | | } |
| | | } |
| | | ] |
| | | }; |
| | | |
| | | // 获取行业统计数据 |
| | | const getIndustryJobNumPieChart = () => { |
| | | industryJobNumPieChart().then(res => { |
| | | if (res.data.code !== 0) return; |
| | | const data = res.data.data.map(item => ({ |
| | | name: item.name, |
| | | value: item.value, |
| | | itemStyle: { |
| | | color: getRandomColor() |
| | | } |
| | | })); |
| | | option.series[0].data = data; |
| | | chart.setOption(option); |
| | | }); |
| | | }; |
| | | |
| | | // 生成随机颜色 |
| | | const getRandomColor = () => { |
| | | const colors = ['#1890FF', '#36CBCB', '#4ECB73', '#FBD437', '#F2637B', '#975FE5']; |
| | | return colors[Math.floor(Math.random() * colors.length)]; |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | chart = echarts.init(chartRef.value); |
| | | getIndustryJobNumPieChart(); |
| | | |
| | | window.addEventListener('resize', () => { |
| | | chart?.resize(); |
| | | }); |
| | | }); |
| | | |
| | | onUnmounted(() => { |
| | | window.removeEventListener('resize', chart?.resize); |
| | | chart?.dispose(); |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .task-industry { |
| | | font-family: YouSheBiaoTiHei, YouSheBiaoTiHei; |
| | | margin-left: 29px; |
| | | padding: 16px 16px; |
| | | width: 340px; |
| | | height: 400px; |
| | | background: linear-gradient( |
| | | 270deg, |
| | | rgba(31, 62, 122, 0) 0%, |
| | | rgba(31, 62, 122, 0.35) 21%, |
| | | #1f3e7a 100% |
| | | ); |
| | | border-radius: 0px 0px 0px 0px; |
| | | opacity: 0.85; |
| | | .chart { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <div class="task-left"> |
| | | <TaskTotal /> |
| | | <TaskIndustry /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import TaskTotal from './TaskTotal.vue'; |
| | | import TaskIndustry from './TaskIndustry.vue'; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .task-left { |
| | | // width: 300px; |
| | | position: relative; |
| | | top: 20px; |
| | | } |
| | | </style> |
| New file |
| | |
| | | <!-- 任务统计 --> |
| | | <template> |
| | | <common-title title="任务统计" :style="{ marginLeft: pxToRem(14) }"></common-title> |
| | | <div class="task-total"> |
| | | <div class="card" v-for="item in list"> |
| | | <div> |
| | | <div class="value">{{ item.value }}</div> |
| | | <div class="name">{{item.name}}</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { pxToRem } from '@/utils/rem'; |
| | | import CommonTitle from '@/components/CommonTitle.vue'; |
| | | import { totalJobNum, jobStatistics } from "@/api/home/task"; |
| | | |
| | | const list = ref([ |
| | | { name: '总任务数', value: '1888'}, |
| | | { name: '计划执行', value: '18'}, |
| | | { name: '执行中', value: '999'}, |
| | | { name: '待执行', value: '8888'}, |
| | | { name: '已执行', value: '666'}, |
| | | { name: '执行失败', value: '2222'}, |
| | | ]); |
| | | |
| | | // 获取任务统计总数 |
| | | const getTotalJobNum = () => { |
| | | totalJobNum().then((res) => { |
| | | if (res.data.code !== 0) returen; |
| | | list.value[0].value = res.data.data; |
| | | }); |
| | | }; |
| | | // 获取其他任务统计 |
| | | const getJobStatistics = () => { |
| | | jobStatistics().then((res) => { |
| | | if (res.data.code !== 0) returen; |
| | | list.value[1].value = res.data.data.planned_executions; |
| | | list.value[2].value = res.data.data.running_num; |
| | | list.value[3].value = res.data.data.pending_executions; |
| | | list.value[4].value = res.data.data.executed; |
| | | list.value[5].value = res.data.data.failed_executions; |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getTotalJobNum(); |
| | | getJobStatistics(); |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .task-total { |
| | | font-family: YouSheBiaoTiHei, YouSheBiaoTiHei; |
| | | margin-left: 29px; |
| | | padding: 16px 16px; |
| | | width: 340px; |
| | | height: 400px; |
| | | background: linear-gradient( |
| | | 270deg, |
| | | rgba(31, 62, 122, 0) 0%, |
| | | rgba(31, 62, 122, 0.35) 21%, |
| | | #1f3e7a 100% |
| | | ); |
| | | border-radius: 0px 0px 0px 0px; |
| | | opacity: 0.85; |
| | | margin-bottom: 12px; |
| | | display: grid; |
| | | grid-template-columns: repeat(2, 1fr); |
| | | grid-template-rows: repeat(3, 1fr); |
| | | gap: 20px; |
| | | padding: 20px; |
| | | .card { |
| | | /* position: absolute; |
| | | top: 8px; |
| | | right: 10px; |
| | | width: 200px; */ |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 8px; |
| | | justify-content: flex-start; |
| | | line-height: 22px; |
| | | padding: 0 10px 10px 0; |
| | | color: #ffffff; |
| | | .name { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | |
| | | } |
| | | |
| | | .value { |
| | | font-family: YouSheBiaoTiHei, YouSheBiaoTiHei; |
| | | font-weight: 400; |
| | | font-size: 26px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <!-- 任务事件统计 --> |
| | | <template> |
| | | <common-title title="任务事件统计"></common-title> |
| | | <div class="task-event"> |
| | | <div class="chart" ref="chartRef"></div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import CommonTitle from '@/components/CommonTitle.vue'; |
| | | import * as echarts from 'echarts'; |
| | | import { jobEventBar } from '@/api/home/task'; |
| | | import dayjs from 'dayjs'; |
| | | |
| | | // 日期 |
| | | const currenDate = dayjs().format('YYYY-MM-DD'); |
| | | const newTime = ref([currenDate, currenDate]); |
| | | // 图表 |
| | | const chartRef = ref(null); |
| | | let chart = null; |
| | | |
| | | const option = { |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | axisPointer: { |
| | | type: 'shadow' |
| | | } |
| | | }, |
| | | legend: { |
| | | data: ['任务', '事件'], |
| | | textStyle: { |
| | | color: '#fff' |
| | | }, |
| | | bottom: '5%' |
| | | }, |
| | | grid: { |
| | | top: '15%', |
| | | left: '3%', |
| | | right: '4%', |
| | | bottom: '15%', |
| | | containLabel: true |
| | | }, |
| | | xAxis: { |
| | | type: 'category', |
| | | axisLine: { |
| | | lineStyle: { |
| | | color: '#fff' |
| | | } |
| | | }, |
| | | axisLabel: { |
| | | color: '#fff', |
| | | interval: 0, |
| | | rotate: 30 |
| | | } |
| | | }, |
| | | yAxis: { |
| | | type: 'value', |
| | | axisLine: { |
| | | lineStyle: { |
| | | color: '#fff' |
| | | } |
| | | }, |
| | | splitLine: { |
| | | lineStyle: { |
| | | color: 'rgba(255, 255, 255, 0.1)' |
| | | } |
| | | }, |
| | | axisLabel: { |
| | | color: '#fff' |
| | | } |
| | | }, |
| | | series: [ |
| | | { |
| | | name: '任务', |
| | | type: 'bar', |
| | | barWidth: '20%', |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: '#1EE7E7' }, |
| | | { offset: 1, color: 'rgba(30, 231, 231, 0.1)' } |
| | | ]) |
| | | } |
| | | }, |
| | | { |
| | | name: '事件', |
| | | type: 'bar', |
| | | barWidth: '20%', |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: '#0070FF' }, |
| | | { offset: 1, color: 'rgba(0, 112, 255, 0.1)' } |
| | | ]) |
| | | } |
| | | } |
| | | ] |
| | | }; |
| | | |
| | | // 获取行业统计数据 |
| | | const getJobEventBar = (value,date_enum) => { |
| | | jobEventBar({date_enum}).then(res => { |
| | | if (res.data.code !== 0) return; |
| | | option.xAxis.data = res.data.data.map(item => item.name); |
| | | option.series[0].data = res.data?.data.map(item => item.data[0].value); |
| | | option.series[1].data = res.data?.data.map(item => item.data[1].value); |
| | | chart.setOption(option); |
| | | }); |
| | | }; |
| | | |
| | | // 生成随机颜色 |
| | | const getRandomColor = () => { |
| | | const colors = ['#1890FF', '#36CBCB', '#4ECB73', '#FBD437', '#F2637B', '#975FE5']; |
| | | return colors[Math.floor(Math.random() * colors.length)]; |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | chart = echarts.init(chartRef.value); |
| | | getJobEventBar(newTime.value, 'CURRENT_YEAR'); |
| | | |
| | | window.addEventListener('resize', () => { |
| | | chart?.resize(); |
| | | }); |
| | | }); |
| | | |
| | | onUnmounted(() => { |
| | | window.removeEventListener('resize', chart?.resize); |
| | | chart?.dispose(); |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .task-event { |
| | | font-family: YouSheBiaoTiHei, YouSheBiaoTiHei; |
| | | margin-left: 29px; |
| | | padding: 16px 16px; |
| | | width: 340px; |
| | | height: 400px; |
| | | background: linear-gradient( |
| | | 270deg, |
| | | rgba(31, 62, 122, 0) 0%, |
| | | rgba(31, 62, 122, 0.35) 21%, |
| | | #1f3e7a 100% |
| | | ); |
| | | border-radius: 0px 0px 0px 0px; |
| | | opacity: 0.85; |
| | | .chart { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <div class="task-right"> |
| | | <TaskTime /> |
| | | <TaskEvent /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import TaskTime from './TaskTime.vue'; |
| | | import TaskEvent from './TaskEvent.vue'; |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .task-right { |
| | | position: absolute; |
| | | top: 122px; |
| | | right: 31px; |
| | | width: 404px; |
| | | |
| | | .titleBox { |
| | | width: 404px; |
| | | height: 43px; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <!-- 任务事件统计 --> |
| | | <template> |
| | | <common-title title="任务时间统计"></common-title> |
| | | <div class="task-time"> |
| | | <div class="chart" ref="chartRef"></div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import CommonTitle from '@/components/CommonTitle.vue'; |
| | | import * as echarts from 'echarts'; |
| | | import { jobNumBar } from '@/api/home/task'; |
| | | import dayjs from 'dayjs'; |
| | | |
| | | // 日期 |
| | | const currenDate = dayjs().format('YYYY-MM-DD'); |
| | | const newTime = ref([currenDate, currenDate]); |
| | | |
| | | const chartRef = ref(null); |
| | | let chart = null; |
| | | |
| | | const option = { |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | axisPointer: { |
| | | type: 'shadow' |
| | | } |
| | | }, |
| | | grid: { |
| | | top: '15%', |
| | | left: '3%', |
| | | right: '4%', |
| | | bottom: '3%', |
| | | containLabel: true |
| | | }, |
| | | xAxis: { |
| | | type: 'category', |
| | | axisLine: { |
| | | lineStyle: { |
| | | color: '#fff' |
| | | } |
| | | }, |
| | | axisLabel: { |
| | | color: '#fff', |
| | | interval: 0, |
| | | rotate: 30 |
| | | } |
| | | }, |
| | | yAxis: { |
| | | type: 'value', |
| | | axisLine: { |
| | | lineStyle: { |
| | | color: '#fff' |
| | | } |
| | | }, |
| | | splitLine: { |
| | | lineStyle: { |
| | | color: 'rgba(255, 255, 255, 0.1)' |
| | | } |
| | | }, |
| | | axisLabel: { |
| | | color: '#fff' |
| | | } |
| | | }, |
| | | series: [ |
| | | { |
| | | type: 'bar', |
| | | barWidth: '40%', |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: '#1EE7E7' }, |
| | | { offset: 1, color: 'rgba(30, 231, 231, 0.1)' } |
| | | ]) |
| | | } |
| | | } |
| | | ] |
| | | }; |
| | | |
| | | // 获取任务时间统计数据 |
| | | const getJobNumBar = (value,date_enum) => { |
| | | jobNumBar({date_enum}).then(res => { |
| | | if (res.data.code !== 0) return; |
| | | option.xAxis.data = res.data.data.map(item => item.name); |
| | | option.series[0].data = res.data.data.map(item => item.value); |
| | | chart.setOption(option); |
| | | }); |
| | | }; |
| | | |
| | | |
| | | onMounted(() => { |
| | | chart = echarts.init(chartRef.value); |
| | | getJobNumBar(newTime.value, 'CURRENT_YEAR'); |
| | | |
| | | window.addEventListener('resize', () => { |
| | | chart?.resize(); |
| | | }); |
| | | }); |
| | | |
| | | onUnmounted(() => { |
| | | window.removeEventListener('resize', chart?.resize); |
| | | chart?.dispose(); |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .task-time { |
| | | font-family: YouSheBiaoTiHei, YouSheBiaoTiHei; |
| | | margin-left: 29px; |
| | | padding: 16px 16px; |
| | | width: 340px; |
| | | height: 400px; |
| | | background: linear-gradient( |
| | | 270deg, |
| | | rgba(31, 62, 122, 0) 0%, |
| | | rgba(31, 62, 122, 0.35) 21%, |
| | | #1f3e7a 100% |
| | | ); |
| | | border-radius: 0px 0px 0px 0px; |
| | | opacity: 0.85; |
| | | .chart { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | } |
| | | </style> |