789 lines
23 KiB
Vue
789 lines
23 KiB
Vue
<template>
|
|
<!-- 顶部统计 -->
|
|
<div class="top-box" v-if="data">
|
|
<el-row :gutter="20">
|
|
<el-col :span="12">
|
|
<div class="grid-content ep-bg-purple">
|
|
<el-card style="max-width: 100%" shadow="never">
|
|
<el-row :gutter="5" v-if="data.taskStatusVO">
|
|
<el-col :span="4">
|
|
<div class="top-item">
|
|
<div class="top-item-title"> 任务总数 </div>
|
|
<div class="top-item-num"> {{ data.taskStatusVO.tasksNumber || 0 }} </div>
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<div class="top-item">
|
|
<div class="top-item-title"> 执行中 </div>
|
|
<div class="top-item-num"> {{ data.taskStatusVO.underwayNum || 0 }} </div>
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<div class="top-item">
|
|
<div class="top-item-title"> 待执行 </div>
|
|
<div class="top-item-num"> {{ data.taskStatusVO.pendingExecutionNum || 0 }} </div>
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<div class="top-item">
|
|
<div class="top-item-title"> 已完成 </div>
|
|
<div class="top-item-num"> {{ data.taskStatusVO.completedNum || 0 }} </div>
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<div class="top-item">
|
|
<div class="top-item-title"> 已取消 </div>
|
|
<div class="top-item-num" style="color: #a6a6a6">
|
|
{{ data.cancelledNum || 0 }}
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<div class="top-item" style="border: none; color: #c60606">
|
|
<div class="top-item-title"> 异常 </div>
|
|
<div class="top-item-num" style="color: #c60606">
|
|
{{ data.taskStatusVO.abnormalNum || 0 }}
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
</el-row>
|
|
</el-card>
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="12">
|
|
<div class="grid-content ep-bg-purple">
|
|
<el-card style="max-width: 100%" shadow="never">
|
|
<el-row :gutter="5" v-if="data.statistics">
|
|
<el-col :span="4">
|
|
<div class="top-item">
|
|
<div class="top-item-title"> 车辆总数 </div>
|
|
<div class="top-item-num"> {{ data.statistics.total || 0 }} </div>
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<div class="top-item">
|
|
<div class="top-item-title"> 任务中 </div>
|
|
<div class="top-item-num"> {{ data.statistics.inTask || 0 }} </div>
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<div class="top-item">
|
|
<div class="top-item-title"> 锁定 </div>
|
|
<div class="top-item-num"> {{ data.statistics.doLock || 0 }} </div>
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<div class="top-item">
|
|
<div class="top-item-title"> 充电中 </div>
|
|
<div class="top-item-num"> {{ data.statistics.charge || 0 }} </div>
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<div class="top-item">
|
|
<div class="top-item-title"> 离线 </div>
|
|
<div class="top-item-num" style="color: #a6a6a6">
|
|
{{ data.statistics.offline || 0 }}
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<div class="top-item" style="border: none; color: #c60606">
|
|
<div class="top-item-title"> 故障 </div>
|
|
<div class="top-item-num" style="color: #c60606">
|
|
{{ data.statistics.fault || 0 }}
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
</el-row>
|
|
</el-card>
|
|
</div>
|
|
</el-col>
|
|
</el-row>
|
|
</div>
|
|
<!-- 下部分 -->
|
|
<div class="bottom-box">
|
|
<el-row :gutter="10">
|
|
<!-- 左边 -->
|
|
<el-col :span="6">
|
|
<div class="bottom-box-item" v-if="data">
|
|
<div class="bottom-box-item-table">
|
|
<div class="bottom-box-item-title">
|
|
<div class="bottom-box-item-title-left"> 执行中 </div>
|
|
<div class="bottom-box-item-title-right" @click="toManyTask('执行中')">
|
|
查看更多
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<el-table :data="data.underway" style="width: 100%">
|
|
<el-table-column prop="taskNo" label="任务编号" />
|
|
<el-table-column prop="skuNumber" label="车辆编号" />
|
|
<el-table-column prop="startTime" label="开始时间" :formatter="dateFormatter" />
|
|
<el-table-column prop="address" label="任务阶段" />
|
|
</el-table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="bottom-box-item" style="margin-top: 8px" v-if="data">
|
|
<div class="bottom-box-item-table">
|
|
<div class="bottom-box-item-title">
|
|
<div class="bottom-box-item-title-left"> 待执行 </div>
|
|
<div class="bottom-box-item-title-right" @click="toManyTask('未开始')">
|
|
查看更多
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<el-table :data="data.pendingExecution" style="width: 100%">
|
|
<el-table-column prop="taskNo" label="任务编号" />
|
|
<el-table-column prop="priorilty" label="优先级" />
|
|
<el-table-column prop="createTime" label="生成时间" :formatter="dateFormatter" />
|
|
</el-table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
<!-- 实时地图 -->
|
|
<el-col :span="12">
|
|
<div style="margin-bottom: 10px">
|
|
<el-cascader
|
|
v-model="mapValue"
|
|
:options="list"
|
|
@change="handleChangeMap"
|
|
style="width: 160px"
|
|
/>
|
|
</div>
|
|
<div style="width: 100%; padding-bottom: 120px" class="map-box-allBoard">
|
|
<indexPage ref="indexPageRef" :isAllBoard="true" :isFullScreen="true" />
|
|
</div>
|
|
<div
|
|
style="position: fixed; bottom: 20px"
|
|
:style="{ width: widthVal + 'px', left: leftVal + 'px' }"
|
|
v-if="data && data.deviceStatusInfoVOS"
|
|
>
|
|
<div
|
|
ref="scrollContainer"
|
|
class="scroll-container"
|
|
@mousedown="startDrag"
|
|
@mousemove="onDrag"
|
|
@mouseup="endDrag"
|
|
@mouseleave="endDrag"
|
|
>
|
|
<div class="content">
|
|
<div
|
|
v-for="(n, i) in data.deviceStatusInfoVOS"
|
|
:key="i"
|
|
class="item"
|
|
:class="{ noBoarder: i === data.deviceStatusInfoVOS.length - 1 }"
|
|
>
|
|
<div class="scroll-container-item-left">
|
|
<div class="scroll-container-item-left-title">{{
|
|
filterTypeFun(n.deviceType, typeList)
|
|
}}</div>
|
|
<div class="scroll-container-item-left-img">
|
|
<img
|
|
:src="n.defaultImage"
|
|
alt=""
|
|
object-fit="contain"
|
|
style="width: 100%; height: 100%"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="scroll-container-item-right">
|
|
<div class="scroll-container-item-right-item">
|
|
<div class="scroll-container-item-right-item-title"> 数量: </div>
|
|
<div class="scroll-container-item-right-item-num">
|
|
{{ n.totalNum || 0 }}
|
|
</div>
|
|
</div>
|
|
<div class="scroll-container-item-right-item" style="margin-top: 3px">
|
|
<div class="scroll-container-item-right-item-title"> 正常数量: </div>
|
|
<div class="scroll-container-item-right-item-num">
|
|
{{ n.normalNum || 0 }}
|
|
</div>
|
|
</div>
|
|
<div class="scroll-container-item-right-item" style="margin-top: 3px">
|
|
<div class="scroll-container-item-right-item-title"> 异常数量: </div>
|
|
<div class="scroll-container-item-right-item-num" style="color: #c60606">
|
|
{{ n.abnormalNum || 0 }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
<!-- 右边 -->
|
|
<el-col :span="6">
|
|
<div class="bottom-box-item" v-if="data">
|
|
<div class="bottom-box-item-table">
|
|
<div class="bottom-box-item-title">
|
|
<div class="bottom-box-item-title-left"> 异常信息 </div>
|
|
<div class="bottom-box-item-title-right" @click="toManyWarnMsg"> 查看更多 </div>
|
|
</div>
|
|
<div>
|
|
<el-table :data="data.robotWarnMsgDOS" style="width: 100%">
|
|
<el-table-column prop="robotNo" label="车辆编号" />
|
|
<el-table-column prop="warnMsg" label="异常信息">
|
|
<template #default="scope">
|
|
<div class="warn-msg">
|
|
<div
|
|
class="warn-msg-color"
|
|
:style="{ backgroundColor: computedBackgroundColor(scope.row.warnLevel) }"
|
|
>
|
|
</div>
|
|
<div class="warn-msg-text">
|
|
{{ scope.row.warnMsg || '' }}
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="createTime" label="发生时间" :formatter="dateFormatter" />
|
|
</el-table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="bottom-box-item" style="margin-top: 8px" v-if="data">
|
|
<div class="bottom-box-item-table">
|
|
<div class="bottom-box-item-title">
|
|
<div class="bottom-box-item-title-left"> 车辆信息 </div>
|
|
<div class="bottom-box-item-title-right" @click="goCarBord"> 查看更多 </div>
|
|
</div>
|
|
<div>
|
|
<el-table :data="data.robotElectricityLevelVOS" style="width: 100%">
|
|
<el-table-column prop="robotNo" label="车辆编号" />
|
|
<el-table-column prop="doLock" label="车辆状态">
|
|
<template #default="scope">
|
|
<span>{{ scope.row.doLock === 0 ? '正常' : '锁定' }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="batSoc" label="电量百分比">
|
|
<template #default="scope">
|
|
<div v-if="scope.row.batSoc === null">—</div>
|
|
<div class="battery-box-all">
|
|
<div class="battery-box" v-if="scope.row.batSoc !== null">
|
|
<img
|
|
src="@/assets/imgs/allBoard/dianlianggreen.png"
|
|
alt=""
|
|
class="battery-box-img"
|
|
v-if="scope.row.batSoc >= 40"
|
|
/>
|
|
<img
|
|
src="@/assets/imgs/allBoard/dianliangyellow.png"
|
|
alt=""
|
|
class="battery-box-img"
|
|
v-if="scope.row.batSoc < 40 && scope.row.batSoc >= 20"
|
|
/>
|
|
<img
|
|
src="@/assets/imgs/allBoard/dianliangred.png"
|
|
alt=""
|
|
class="battery-box-img"
|
|
v-if="scope.row.batSoc < 20"
|
|
/>
|
|
<div class="battery-box-inner">
|
|
<div
|
|
class="battery-box-inner-inner"
|
|
:class="
|
|
scope.row.batSoc >= 40
|
|
? 'green-bg'
|
|
: scope.row.batSoc < 40 && scope.row.batSoc >= 20
|
|
? 'yellow-bg'
|
|
: 'red-bg'
|
|
"
|
|
:style="{ width: scope.row.batSoc + '%' }"
|
|
>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<span class="battery-box-text" v-if="scope.row.batSoc !== null"
|
|
>{{ scope.row.batSoc || 0 }}%</span
|
|
>
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
</el-row>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue'
|
|
import { dateFormatter } from '@/utils/formatTime'
|
|
import * as ChartsApi from '@/api/boardCharts'
|
|
import { DICT_TYPE, getIntDictOptions, getDictOptions } from '@/utils/dict'
|
|
import indexPage from '../../mapPage/realTimeMap/components/indexPage.vue'
|
|
import * as MapApi from '@/api/map/map'
|
|
|
|
const router = useRouter() // 路由对象
|
|
const indexPageRef = ref(null)
|
|
const typeList = ref([])
|
|
defineOptions({ name: 'BoardAllBoard' })
|
|
const data = ref({
|
|
taskStatusVO: {
|
|
//顶部左边统计
|
|
pendingExecutionNum: 0,
|
|
underwayNum: 0,
|
|
completedNum: 0,
|
|
cancelledNum: 0,
|
|
abnormalNum: 0,
|
|
tasksNumber: 0
|
|
},
|
|
statistics: {
|
|
//顶部右边 统计
|
|
total: 0,
|
|
inTask: 0,
|
|
doLock: 0,
|
|
charge: 0,
|
|
offline: 0,
|
|
fault: 0
|
|
},
|
|
underway: [], //执行中
|
|
pendingExecution: [], //待执行
|
|
robotWarnMsgDOS: [], //异常信息
|
|
deviceStatusInfoVOS: [], //设备信息
|
|
robotElectricityLevelVOS: [] //车辆信息
|
|
})
|
|
//获取数据
|
|
const getAllData = async () => {
|
|
let datas = await ChartsApi.bulletinBoardGet()
|
|
console.log(datas)
|
|
data.value = datas
|
|
}
|
|
const widthVal = ref(0)
|
|
const leftVal = ref(0)
|
|
const getWidth = (val) => {
|
|
widthVal.value = val
|
|
console.log(widthVal.value)
|
|
}
|
|
const getLeftPx = (val) => {
|
|
leftVal.value = val
|
|
}
|
|
//返回异常颜色
|
|
const computedBackgroundColor = (warnLevel) => {
|
|
switch (warnLevel) {
|
|
case 1:
|
|
return '#1677FF'
|
|
case 2:
|
|
return '#F1CD0B'
|
|
case 3:
|
|
return '#E07300'
|
|
case 4:
|
|
return '#C60606'
|
|
default:
|
|
return ''
|
|
}
|
|
}
|
|
|
|
//前往更多任务
|
|
const toManyTask = (type) => {
|
|
// console.log(getIntDictOptions(DICT_TYPE.ROBOT_TASK_STATUS))
|
|
// return
|
|
router.push({
|
|
path: '/task-management/task-list',
|
|
query: {
|
|
type: type
|
|
}
|
|
})
|
|
}
|
|
|
|
//前往异常信息
|
|
const toManyWarnMsg = () => {
|
|
router.push({
|
|
path: '/carError'
|
|
})
|
|
}
|
|
// 前往车辆看板
|
|
const goCarBord = () => {
|
|
router.push({
|
|
path: '/board/carBoard'
|
|
})
|
|
}
|
|
const list = ref([]) // 地图区域列表
|
|
const mapValue = ref([]) //选中的区域绑定的数组值
|
|
const mapInfo = ref(null) //选中的区域
|
|
//获取地图区域
|
|
const getList = async () => {
|
|
let data = await MapApi.getPositionMapGetMap()
|
|
let mapList = []
|
|
for (let key in data) {
|
|
mapList.push({
|
|
floor: key,
|
|
label: key + '层',
|
|
value: key,
|
|
children: data[key]
|
|
})
|
|
}
|
|
if (mapList.length) {
|
|
mapList.forEach((item) => {
|
|
if (item.children.length) {
|
|
item.children.forEach((child) => {
|
|
child.label = child.area
|
|
child.value = child.id
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
list.value = mapList
|
|
console.log(list.value, data)
|
|
if (mapValue.value.length) {
|
|
handleChangeMap(mapValue.value)
|
|
} else {
|
|
mapValue.value = [list.value[0].value, list.value[0].children[0].value]
|
|
mapInfo.value = list.value[0].children[0]
|
|
? JSON.parse(JSON.stringify(list.value[0].children[0]))
|
|
: {
|
|
mapId: '',
|
|
floor: '',
|
|
area: ''
|
|
}
|
|
indexPageRef.value.getMapData(mapInfo.value)
|
|
}
|
|
}
|
|
//切换地图选择
|
|
const handleChangeMap = async (e) => {
|
|
mapInfo.value = findChildrenByValues(list.value, e)
|
|
? findChildrenByValues(list.value, e)
|
|
: {
|
|
mapId: '',
|
|
floor: '',
|
|
area: ''
|
|
}
|
|
console.log(mapInfo.value)
|
|
indexPageRef.value.getMapData(mapInfo.value)
|
|
}
|
|
// 筛选出对应的区域对象
|
|
const findChildrenByValues = (tree, values) => {
|
|
if (!tree || tree.length === 0) {
|
|
return null
|
|
}
|
|
function traverse(node) {
|
|
if (node.children) {
|
|
for (let child of node.children) {
|
|
if (values.includes(child.value)) {
|
|
return child
|
|
}
|
|
let result = traverse(child)
|
|
if (result) {
|
|
return result
|
|
}
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
for (let root of tree) {
|
|
if (values.includes(root.value)) {
|
|
if (root.children) {
|
|
for (let child of root.children) {
|
|
if (values.includes(child.value)) {
|
|
return child
|
|
}
|
|
let result = traverse(child)
|
|
if (result) {
|
|
return result
|
|
}
|
|
}
|
|
}
|
|
}
|
|
let result = traverse(root)
|
|
if (result) {
|
|
return result
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
const scrollContainer = ref(null)
|
|
let isDragging = false
|
|
let startX = 0
|
|
let scrollLeft = 0
|
|
|
|
const startDrag = (e) => {
|
|
isDragging = true
|
|
const rect = scrollContainer.value.getBoundingClientRect()
|
|
startX = e.clientX - rect.left
|
|
scrollLeft = scrollContainer.value.scrollLeft
|
|
scrollContainer.value.style.cursor = 'grabbing'
|
|
}
|
|
|
|
const onDrag = (e) => {
|
|
if (!isDragging) return
|
|
const rect = scrollContainer.value.getBoundingClientRect()
|
|
const mouseX = e.clientX - rect.left
|
|
const dragDistance = (mouseX - startX) * 2.5 // 速度系数
|
|
scrollContainer.value.scrollLeft = scrollLeft - dragDistance
|
|
}
|
|
|
|
const endDrag = () => {
|
|
isDragging = false
|
|
scrollContainer.value.style.cursor = 'grab'
|
|
}
|
|
const getElementWidthByClass = (className) => {
|
|
const element = document.querySelector(`.${className}`)
|
|
if (element) {
|
|
// return window.getComputedStyle(element).width
|
|
const widthWithUnit = window.getComputedStyle(element).width
|
|
return widthWithUnit.slice(0, -2)
|
|
}
|
|
return null
|
|
}
|
|
const getLeft = () => {
|
|
let indexpageContainer = document.getElementsByClassName('map-box-allBoard')[0]
|
|
// console.log('距离左边的距离', indexpageContainer.getBoundingClientRect().left)
|
|
leftVal.value = indexpageContainer.getBoundingClientRect().left
|
|
}
|
|
const getWidthPx = () => {
|
|
let width = getElementWidthByClass('map-box-allBoard')
|
|
// console.log("pppppppppppppp",width)
|
|
widthVal.value = width
|
|
}
|
|
const getLeftWidth = () => {
|
|
nextTick(() => {
|
|
getWidthPx()
|
|
getLeft()
|
|
})
|
|
}
|
|
//根据type和列表返回对应中文
|
|
const filterTypeFun = (type, list) => {
|
|
if (list.length) {
|
|
let obj = list.find((item) => {
|
|
return item.value == type
|
|
})
|
|
return obj == undefined ? type : obj.label
|
|
} else {
|
|
return type
|
|
}
|
|
}
|
|
onMounted(() => {
|
|
typeList.value = getDictOptions(DICT_TYPE.DEVICE_TYPE)
|
|
getAllData()
|
|
getList()
|
|
getLeftWidth()
|
|
window.addEventListener('resize', getLeftWidth)
|
|
})
|
|
onBeforeUnmount(() => {
|
|
window.removeEventListener('resize', getLeftWidth)
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.top-box {
|
|
width: 100%;
|
|
}
|
|
.top-item {
|
|
width: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
border-right: 1px solid #e7eaec;
|
|
}
|
|
.top-item-title {
|
|
font-family:
|
|
PingFangSC,
|
|
PingFang SC;
|
|
font-weight: 500;
|
|
font-size: 18px;
|
|
color: #0d162a;
|
|
margin-bottom: 8px;
|
|
}
|
|
.top-item-num {
|
|
font-family:
|
|
PingFangSC,
|
|
PingFang SC;
|
|
font-weight: 500;
|
|
font-size: 24px;
|
|
color: #00329f;
|
|
}
|
|
.bottom-box {
|
|
width: 100%;
|
|
margin-top: 12px;
|
|
}
|
|
.bottom-box-item {
|
|
width: 100%;
|
|
}
|
|
.bottom-box-item-title {
|
|
width: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: 8px;
|
|
}
|
|
.bottom-box-item-title-left {
|
|
font-family:
|
|
PingFangSC,
|
|
PingFang SC;
|
|
font-weight: 500;
|
|
font-size: 14px;
|
|
color: #0d162a;
|
|
}
|
|
.bottom-box-item-title-right {
|
|
font-family:
|
|
PingFangSC,
|
|
PingFang SC;
|
|
font-weight: 400;
|
|
font-size: 14px;
|
|
color: #1677ff;
|
|
cursor: pointer;
|
|
}
|
|
.bottom-box-item-table {
|
|
width: 100%;
|
|
}
|
|
.battery-box {
|
|
width: 22px;
|
|
height: 11px;
|
|
position: relative;
|
|
}
|
|
.battery-box-img {
|
|
width: 100%;
|
|
height: 100%;
|
|
vertical-align: top;
|
|
}
|
|
.battery-box-inner {
|
|
width: 17px;
|
|
height: 8px;
|
|
position: absolute;
|
|
left: 50%;
|
|
top: 50%;
|
|
transform: translateX(-50%) translateY(-50%);
|
|
}
|
|
.battery-box-inner-inner {
|
|
height: 100%;
|
|
}
|
|
.green-bg {
|
|
background: #52c41a;
|
|
}
|
|
.yellow-bg {
|
|
background: #f1cd0b;
|
|
}
|
|
.red-bg {
|
|
background: #c60606;
|
|
}
|
|
.battery-box-text {
|
|
font-family:
|
|
PingFangSC,
|
|
PingFang SC;
|
|
font-weight: 400;
|
|
font-size: 12px;
|
|
color: #0d162a;
|
|
margin-left: 3px;
|
|
}
|
|
.battery-box-all {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
}
|
|
.warn-msg {
|
|
display: flex;
|
|
}
|
|
.warn-msg-color {
|
|
width: 8px;
|
|
height: 8px;
|
|
flex-shrink: 0;
|
|
border-radius: 50%;
|
|
margin-right: 4px;
|
|
margin-top: 4px;
|
|
}
|
|
.warn-msg-text {
|
|
flex: 1;
|
|
font-family:
|
|
PingFangSC,
|
|
PingFang SC;
|
|
font-weight: 400;
|
|
font-size: 12px;
|
|
color: #0d162a;
|
|
margin-top: -3px;
|
|
}
|
|
/* 容器样式 */
|
|
.scroll-container {
|
|
width: 100%;
|
|
height: 104px;
|
|
overflow: hidden;
|
|
position: relative;
|
|
cursor: grab;
|
|
user-select: none;
|
|
background: #fff;
|
|
margin-top: 10px;
|
|
}
|
|
|
|
/* 隐藏滚动条 */
|
|
.scroll-container::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
/* 内容布局 */
|
|
.content {
|
|
display: inline-flex;
|
|
height: 100%;
|
|
padding: 20px 0;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
/* 单个项目样式 */
|
|
.item {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
|
|
padding: 17px 30px;
|
|
background: #fff;
|
|
transition: transform 0.2s;
|
|
border-right: 2px solid #e9e9e9;
|
|
}
|
|
|
|
/* .item:hover {
|
|
transform: translateY(-3px);
|
|
} */
|
|
|
|
/* 拖拽时状态 */
|
|
.scroll-container:active {
|
|
cursor: grabbing;
|
|
}
|
|
.scroll-container-item-left-title {
|
|
font-family:
|
|
PingFangSC,
|
|
PingFang SC;
|
|
font-weight: 500;
|
|
font-size: 14px;
|
|
color: #0d162a;
|
|
margin-bottom: 14px;
|
|
flex-shrink: 0;
|
|
}
|
|
.scroll-container-item-left-img {
|
|
width: 40px;
|
|
height: 40px;
|
|
vertical-align: top;
|
|
flex-shrink: 0;
|
|
}
|
|
.scroll-container-item-right {
|
|
flex-shrink: 0;
|
|
margin-left: 16px;
|
|
}
|
|
.noBoarder {
|
|
border-right: none;
|
|
}
|
|
.scroll-container-item-right-item {
|
|
display: flex;
|
|
flex-shrink: 0;
|
|
}
|
|
.scroll-container-item-right-item-title {
|
|
font-family:
|
|
PingFangSC,
|
|
PingFang SC;
|
|
font-weight: 400;
|
|
font-size: 12px;
|
|
color: #0d162a;
|
|
flex-shrink: 0;
|
|
}
|
|
.scroll-container-item-right-item-num {
|
|
font-family:
|
|
PingFangSC,
|
|
PingFang SC;
|
|
font-weight: 400;
|
|
font-size: 12px;
|
|
color: #0d162a;
|
|
flex-shrink: 0;
|
|
}
|
|
</style>
|