vue3+echarts柱状图点击加载数据及选中效果
一、父组件代码:
<template>
<div class="stockCommentInformation" v-loading="loading">
<!-- 柱形图与评论列表 -->
<div class="top-content">
<div class="filter-top">
<div class="left-box">
<el-date-picker
v-model="dateRange"
value-format="YYYY-MM-DD HH:mm:ss"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
:editable="false"
:disabled-date="disabledDate"
@change="changeDate"
class="date-select"
/>
</div>
<div
class="right-box"
v-if="barOptions.xAxis.data && barOptions.xAxis.data.length > 0"
>
<div class="line"></div>
<div class="title">{{ title }}</div>
</div>
</div>
<div class="content-box">
<div class="chart-box">
<div class="select-box">
<span class="select-text">评论舆情TOP10</span>
<el-select
v-model="selectValue"
style="width: 160px"
@change="changeCommentBarData"
>
<el-option
v-for="item in chartOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div class="no-data" v-show="showNoData">
<img src="@/assets/img/no_data.png" alt="" class="img" />
<div class="noData-text">暂无相关数据</div>
</div>
<barChart
id="barChart"
:chartWidth="chartWidth"
:chartHeight="chartHeight"
:options="barOptions"
:xName="xName"
:XInt="XInt"
@searchCommentList="searchCommentList"
v-show="!showNoData"
></barChart>
</div>
<div class="comment-list">
<template
v-if="barOptions.xAxis.data && barOptions.xAxis.data.length > 0"
>
<div class="list" v-for="(item, index) in commentList" :key="index">
<div class="date-box">
<div class="dot"></div>
<!-- 0:今日,1:近1周,2:近1月 -->
<div class="date-text">
{{
item.timePeriod === 0
? '近一天'
: item.timePeriod === 1
? '近一周'
: '近一月'
}}
</div>
</div>
<div class="comment-box">
<div class="negative-box">
<div class="label negative">负面评价</div>
<div class="num">{{ item.negNum }}条</div>
</div>
<div class="front-box">
<div class="label front">正面评价</div>
<div class="num">{{ item.posNum }}条</div>
</div>
</div>
<div class="keyword">
<div class="keyword-label label">关键词</div>
<el-popover
placement="top-start"
:width="300"
trigger="hover"
:content="item.keywords"
popper-class="switch-popper"
v-if="showTooltip"
>
<template #reference>
<div
class="keyword-list"
@mouseenter="isShowTooltip($event)"
>
{{ item.keywords }}
</div>
</template>
</el-popover>
<div
class="keyword-list"
@mouseenter="isShowTooltip($event)"
v-else
>
{{ item.keywords }}
</div>
</div>
<div class="review-box">
<div class="review-label label">综上所述</div>
<el-popover
placement="top-start"
:width="300"
trigger="hover"
:content="item.overview"
popper-class="switch-popper"
v-if="showTooltip"
>
<template #reference>
<div
class="keyword-list"
@mouseenter="isShowTooltip($event)"
>
{{ item.overview }}
</div>
</template>
</el-popover>
<div
class="keyword-list"
@mouseenter="isShowTooltip($event)"
v-else
>
{{ item.overview }}
</div>
</div>
</div>
</template>
<div class="nodata" v-else>今日无相关负面评价</div>
</div>
</div>
</div>
<!-- 分割框 -->
<div class="split-box"></div>
<!-- 表格 -->
<div class="bottom-content">
<div class="filter-table">
<div class="left-filter">
<el-input
v-model.trim="searchVal"
:maxlength="50"
placeholder="请输入关键字(公司名称、综述及关键词)"
clearable
@change="changeInputValue"
class="ipt"
/>
<div class="search-btn" @click="searchList">搜索</div>
</div>
<!-- tab栏 -->
<div class="tab-box">
<div class="tab-list">
<div
class="tab"
:class="tabIndex === index ? 'color' : ''"
@click="onClickItem(index)"
v-for="(item, index) in tagList"
:key="index"
>
{{ item.name }}
</div>
</div>
</div>
</div>
<stockCommentTable
:tableData="tableData"
:currentPage="currentPage"
:pageSize="pageSize"
:total="total"
@searchTableList="searchTableList"
@searchTableList1="searchTableList1"
@tableScrollTop="tableScrollTop"
ref="stockTable"
></stockCommentTable>
</div>
</div>
</template>
<script setup lang="ts">
import { ElMessage } from 'element-plus'
import barChart from './barChart.vue'
import type { EChartsOption } from 'echarts'
import stockCommentTable from './stockCommentTable.vue'
import {
queryStockComment,
queryCommentBarData,
queryCommentCompanyList
} from '@/service/stockIndex/index'
const showNoData = ref(false) // 是否展示无数据图片
const loading = ref(false) // 加载状态
const chartWidth = ref('890px') // 图表宽度
const chartHeight = ref('calc(100% - 32px - 35px - 10px)') // 图表高度
const searchVal = ref('') // 搜索框值
const total = ref(0) // 总条数
const currentPage = ref(1) // 当前页
const pageSize = ref(10) // 一页展示条数
const scrollTop = ref(0) // 表格滚动条距离顶部距离
const showTooltip = ref(false) // 是否展示浮框
const xName = ref('') // 柱状图名称
const title = ref('') // 右侧列表标题
const tagList = ref<any>([
{ value: 0, name: '今日' },
{ value: 1, name: '近1周' },
{ value: 2, name: '近1个月' }
]) // tab栏列表
const commentList = ref<any>([]) // 评论列表
const tabIndex = ref(0) // tab栏索引
const tableData = ref<any>([])
const stockTable = ref()
const XInt = ref(0) // 柱状图索引
const barOptions: any = ref<EChartsOption>({
xAxis: {
data: []
},
series: [
{
data: []
}
]
})
// 日期范围值
const dateRange = ref<any>([])
const startDate = ref() // 开始时间
const endDate = ref() //结束时间
const selectValue = ref(0)
const chartOptions = ref([
{ value: 0, label: '综合' },
{ value: 1, label: '负面舆情' }
])
// 控制当前时间之后不能选
const disabledDate = (time: any) => {
return time.getTime() > new Date().getTime()
}
// 改变时间
const changeDate = (value: any) => {
if (value) {
dateRange.value = toRaw(value)
startDate.value = dateRange.value[0]
endDate.value = dateRange.value[1]
} else {
dateRange.value = toRaw(value)
startDate.value = ''
endDate.value = ''
}
XInt.value = 0
xName.value = ''
getCommentBarData()
}
// 切换选项查询柱状图
const changeCommentBarData = (e: any) => {
selectValue.value = e
XInt.value = 0
xName.value = ''
getCommentBarData()
}
// 判断是否展示文本浮框
const isShowTooltip = (event: any) => {
const ev = event.target
const evWidth = ev.scrollWidth
const contentWidth = ev.clientWidth
if (evWidth > contentWidth) {
// 实际宽度 > 可视宽度 文字溢出
showTooltip.value = true
} else {
// 否则为不溢出
showTooltip.value = false
}
}
// tab栏切换
const onClickItem = (index: number) => {
currentPage.value = 1
tabIndex.value = index
// 设置表格内容展开状态为关闭初始化
if (stockTable.value) {
stockTable.value.closeInfo()
}
getStockComment()
}
// 改变搜索框输入值
const changeInputValue = (e: string) => {
searchVal.value = e
}
// 搜索
const searchList = () => {
// 设置表格内容展开状态为关闭初始化
if (stockTable.value) {
stockTable.value.closeInfo()
}
currentPage.value = 1
getStockComment()
}
// 表格滚动条置顶
const tableScrollTop = (top: number) => {
scrollTop.value = top
}
// 点击柱状图查询评论列表
const searchCommentList = (data: any) => {
getCommentCompanyList(data.data.securityId)
}
// 改变页数查询表格
const searchTableList = (current: number) => {
currentPage.value = current
// 设置表格内容展开状态为关闭初始化
if (stockTable.value) {
stockTable.value.closeInfo()
}
getStockComment()
// 滚动到顶部
tableScrollTop(0)
}
// 改变条数查询表格
const searchTableList1 = (pageSizes: number) => {
pageSize.value = pageSizes
// 设置表格内容展开状态为关闭初始化
if (stockTable.value) {
stockTable.value.closeInfo()
}
getStockComment()
// 滚动到顶部
tableScrollTop(0)
}
// 查询表格数据
const getStockComment = () => {
loading.value = true
tableData.value = []
queryStockComment(
searchVal.value,
pageSize.value,
currentPage.value,
tabIndex.value
).then((res: any) => {
if (res.code === 200) {
tableData.value = res.data.data
total.value = res.data.total
} else {
ElMessage({
message: res.message,
type: 'error'
})
}
loading.value = false
})
}
// 查询评论数量TOP10柱状图
const getCommentBarData = () => {
loading.value = true
queryCommentBarData(endDate.value, startDate.value, selectValue.value).then(
(res: any) => {
if (res.code === 200) {
barOptions.value.xAxis.data = []
barOptions.value.series[0].data = []
// 判断是否有数据
if (res.data && res.data.length > 0) {
showNoData.value = false
} else {
showNoData.value = true
}
res.data.forEach((i: any) => {
barOptions.value.xAxis.data.push(i.name)
barOptions.value.xAxis.data.forEach((item: any) => {
if (i.name === item) {
barOptions.value.series[0].data.push(i)
}
})
})
if (res.data.length > 0) {
getCommentCompanyList(res.data[0].securityId)
}
} else {
ElMessage({
message: res.message,
type: 'error'
})
}
loading.value = false
}
)
}
// 查询指定公司的评论动态(今日、近一周、近一月)
const getCommentCompanyList = (securityId: number | string) => {
loading.value = true
queryCommentCompanyList(securityId).then((res: any) => {
if (res.code === 200) {
title.value = `${res.data.companyName}【${res.data.symbol}】`
xName.value = res.data.companyName
commentList.value = res.data.dynamicsList
} else {
ElMessage({
message: res.message,
type: 'error'
})
}
loading.value = false
})
}
onMounted(() => {
nextTick(() => {
getCommentBarData()
getStockComment()
})
})
</script>
<style lang="less" scoped>
.stockCommentInformation {
margin: 0 auto !important;
.top-content {
padding: 20px;
background-color: #ffffff;
border-radius: 6px;
.filter-top {
height: 50px;
background: #f4f7fc;
border: 1px solid #ebeef8;
display: flex;
.left-box {
width: 890px;
border-right: 1px solid #ebeef8;
:deep(.el-date-editor) {
width: 350px;
height: 32px;
margin: 8px 0;
border-radius: 4px;
font-size: 12px !important;
margin-left: 17px;
}
}
.right-box {
display: flex;
align-items: center;
.line {
width: 4px;
height: 14px;
background: #3a5bb7;
border-radius: 0px 2px 2px 0px;
margin-right: 7px;
margin-left: 20px;
}
.title {
font-weight: 600;
font-size: 16px;
color: #333333;
}
}
}
.content-box {
display: flex;
height: 440px;
.chart-box {
border: 1px solid #ebeef8;
border-top: none;
.select-box {
margin: 23px 0 10px 27px;
display: flex;
align-items: center;
:deep(.el-select .el-input.is-focus .el-input__wrapper) {
box-shadow: 0 0 0 1px #3a5bb7 inset !important;
}
:deep(.el-select .el-input__inner) {
font-size: 12px;
}
.select-text {
font-weight: 400;
font-size: 14px;
color: #333333;
margin-right: 14px;
}
}
.no-data {
width: 890px;
height: 263px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.img {
width: 300px;
height: 163px;
margin-bottom: 10px;
}
.noData-text {
font-size: 12px;
color: #cacfd7;
}
}
}
.comment-list {
width: 520px;
padding: 21px;
border: 1px solid #ebeef8;
border-left: none;
border-top: none;
.list {
.date-box {
display: flex;
align-items: center;
.dot {
width: 4px;
height: 4px;
background: #333333;
}
.date-text {
font-weight: 700;
font-size: 14px;
color: #333333;
margin-left: 8px;
}
}
.comment-box {
display: flex;
align-items: center;
.negative-box {
margin-right: 130px;
}
.front-box,
.negative-box {
display: flex;
align-items: center;
margin-top: 15px;
margin-bottom: 12px;
.label {
width: 60px;
height: 21px;
border-radius: 2px;
font-size: 12px;
display: flex;
align-items: center;
justify-content: center;
}
.front {
background: #e9fae9;
color: #009900;
}
.negative {
background: #fee7e7;
color: #ff0000;
}
.num {
font-size: 14px;
color: #666666;
margin-left: 12px;
}
}
}
.keyword,
.review-box {
display: flex;
align-items: center;
margin-bottom: 12px;
.review-label {
color: #15a1f1;
background: #e7f4ff;
}
.keyword-label {
color: #f49029;
background: #fdf3e6;
}
.label {
width: 60px;
height: 21px;
border-radius: 2px;
font-size: 12px;
display: flex;
align-items: center;
justify-content: center;
}
.keyword-list {
width: 396px;
font-size: 14px;
color: #666666;
margin-left: 12px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
.nodata {
font-size: 14px;
color: #666666;
}
}
}
.split-box {
width: 100%;
height: 10px;
background: #f4f7fc;
}
.bottom-content {
padding: 20px;
background-color: #ffffff;
border-radius: 6px;
.filter-table {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
.left-filter {
display: flex;
align-items: center;
.ipt {
width: 280px;
height: 32px;
border-radius: 2px;
margin-right: 14px;
font-size: 12px;
color: #c9cdd6;
}
.search-btn {
width: 60px;
display: flex;
justify-content: center;
align-items: center;
height: 32px;
background-color: #3a5bb7;
border-radius: 4px;
color: #ffffff;
font-size: 12px;
cursor: pointer;
}
}
.tab-list {
display: flex;
background: #f4f7fc;
border-radius: 11px;
.tab {
display: flex;
align-items: center;
justify-content: center;
padding: 0 18px;
height: 22px;
border-radius: 12px;
font-weight: 500;
font-size: 12px;
color: #999999;
background: #f4f7fc;
border: 1px solid #f4f7fc;
cursor: pointer;
&:hover {
color: #3a5bb7;
}
}
.color {
border: 1px solid #3a5bb7;
background: #ffffff;
color: #3a5bb7;
}
}
}
}
}
</style>
二、barChart柱状图组件代码:
<template>
<div :id="id" :style="{ width: chartWidth, height: chartHeight }"></div>
</template>
<script setup lang="ts">
import * as echarts from 'echarts'
import _ from 'lodash'
const props = defineProps({
id: {
type: String,
default: 'barChart'
},
chartWidth: {
type: String,
default: ''
},
chartHeight: {
type: String,
default: ''
},
options: {
type: Object,
default: () => {}
},
XInt: {
type: Number,
default: 0
},
xName: {
type: String,
default: ''
}
})
const emit = defineEmits(['searchCommentList'])
// 定义图表
const barChart = ref<any>('')
const curInt = ref(props.XInt) // 柱状图索引
const curName = ref(props.xName) // 柱状图名称
watch(
() => [props.xName, props.XInt],
(newValue: any) => {
curName.value = newValue[0]
curInt.value = newValue[1]
},
{ deep: true }
)
// 图表渲染参数开始
let chartOptions = {
tooltip: {
// 触发类型,默认数据触发,可选为:'item' | 'axis'
trigger: 'axis',
formatter: function (params: any) {
// params 是一个数组,数组中包含每个系列的数据信息
let result = ''
params.forEach(function (item: any) {
// item 是每一个系列的数据
const seriesName = item.name // 系列名称
const value = item.value // 数据值
result += `<div style="margin-bottom: 5px; display: flex;align-items: center;font-size: 12px;"><span style="width: 7px; height: 7px; background-color: ${item.color}; border-radius: 50%;margin-right: 8px;"></span>${seriesName}:${value}</div>`
})
return result
}
},
grid: {
left: '57px',
right: '37px',
top: '20px',
bottom: '38px'
},
xAxis: {
type: 'category',
axisLine: {
lineStyle: {
color: '#D7D9DF' // 这里设置X轴刻度线的颜色
}
},
axisLabel: {
// 设置第一个名称(标签)的颜色
color: function (params: any, index: number) {
// 如果 index 为 0,即第一个名称,则设置为红色
if (curInt.value === index) {
return '#2a6cea'
} else {
if (curName.value === params) {
return '#2a6cea'
} else {
return '#999999' // 柱状图颜色
}
}
}
},
data: []
},
yAxis: {
type: 'value',
axisLine: {
lineStyle: {
color: '#D7D9DF' // 修改Y轴线的颜色
}
},
axisLabel: {
fontSize: 12, // 设置字体大小
color: '#999999' // 修改Y轴刻度文字的颜色
}
},
series: [
{
type: 'bar',
barWidth: 30,
itemStyle: {
// 设置圆角大小
borderRadius: [3, 3, 0, 0],
color: function (params: any) {
if (curInt.value === params.dataIndex) {
return '#2a6cea'
} else {
return '#6d9ffe' // 柱状图颜色
}
}
},
data: []
}
]
}
//监听options变化,给图表赋值
watch(
() => props.options,
(newValue) => {
if (barChart.value) {
//当数据有更新时候,可使用lineChart.value.clear()清除现有的图表状态,然后再应用新的配置。
barChart.value.clear()
//数据清空,因为使用_.merge合并时,会残留历史数据
chartOptions.xAxis.data = []
chartOptions.series.forEach((item: any) => {
item.data = []
})
//执行merge合并时,后面的props.options会覆盖chartOptions内相同字段内容,并返回chartOptions
_.merge(chartOptions, newValue)
barChart.value.setOption(chartOptions)
// 监听窗口大小变化,自动调整图表大小
setTimeout(() => {
barChart.value.resize()
})
}
},
{ deep: true }
)
onMounted(() => {
// 初始化 ECharts 实例
barChart.value = markRaw(
echarts.init(document.getElementById(props.id) as HTMLDivElement)
)
// 柱状图绑定点击事件
barChart.value.on('click', function (params: any) {
curInt.value = params.dataIndex
curName.value = params.name
barChart.value.setOption(chartOptions)
emit('searchCommentList', params)
})
// 监听窗口大小变化,自动调整图表大小
window.addEventListener('resize', () => {
barChart.value.resize()
})
})
onActivated(() => {
if (barChart.value) {
barChart.value.resize()
}
})
</script>
三、stockCommentTable表格组件代码:
<template>
<div class="table-list">
<el-table
:data="tableData"
:header-cell-style="headerCellStyle"
:header-row-class-name="'headerRowClass'"
max-height="560"
row-key="id"
@setScrollTop="setScrollTop"
class="my-table"
>
<el-table-column label="序号" type="index" width="60" align="center" />
<el-table-column label="公司名称" width="100" align="center">
<template #default="scope">
<div class="company-box" @click="toStockIndexPage(scope.row)">
<div>
{{ `${scope.row.companyName}` }}
</div>
<div>
{{ `【${scope.row.symbol}】` }}
</div>
</div>
</template>
</el-table-column>
<el-table-column width="500" align="left">
<template #header>
<div class="review-box">
<div class="review">综述</div>
<div class="all-open" @click="openReviewDetail">
<span class="all-text" v-if="!reviewDetailState">全部展开</span>
<span class="all-text" v-else>全部收起</span>
<div class="icon-box" v-if="!reviewDetailState">
<span class="icon iconfont icon-xiala"></span>
</div>
<div class="icon-box" v-else>
<span class="icon iconfont icon-shang"></span>
</div>
</div>
</div>
</template>
<template #default="scope">
<textUnpack
:textId="String(scope.row.securityId)"
id="stockCommentReview"
:newsDetailState="scope.row.collapseReview"
:textOver="scope.row.showOpenButton"
v-if="scope.row.overview"
>
<div v-html="scope.row.overview" class="info"></div>
</textUnpack>
</template>
</el-table-column>
<el-table-column
label="评论数量"
prop="totalNum"
align="center"
></el-table-column>
<el-table-column label="负面占比" prop="negRatio" align="center">
<template #default="scope">
{{ `${scope.row.negRatio}%` }}
</template>
</el-table-column>
<el-table-column label="中性占比" prop="neuterRatio" align="center">
<template #default="scope">
{{ `${scope.row.neuterRatio}%` }}
</template>
</el-table-column>
<el-table-column label="正面占比" prop="posRatio" align="center">
<template #default="scope">
{{ `${scope.row.posRatio}%` }}
</template>
</el-table-column>
<el-table-column
label="情绪指数"
prop="sentimentIndex"
align="center"
></el-table-column>
<el-table-column width="300" align="left">
<template #header>
<div class="review-box">
<div class="review">关键词</div>
<div class="all-open" @click="openKeyWordDetail">
<span class="all-text" v-if="!keyWordDetailState">全部展开</span>
<span class="all-text" v-else>全部收起</span>
<div class="icon-box" v-if="!keyWordDetailState">
<span class="icon iconfont icon-xiala"></span>
</div>
<div class="icon-box" v-else>
<span class="icon iconfont icon-shang"></span>
</div>
</div>
</div>
</template>
<template #default="scope">
<textUnpack
:textId="String(scope.row.securityId) + 'index'"
:newsDetailState="scope.row.collapseKeyWord"
:textOver="scope.row.showOpenButton"
v-if="scope.row.keywords"
>
<div v-html="scope.row.keywords" class="keyWord-info"></div>
</textUnpack>
</template>
</el-table-column>
</el-table>
<!-- 表格分页组件 -->
<paging
id="stockCommentInformation"
:currentPage="currentPage"
:pageSize="pageSize"
:page-sizes="[10, 20, 50]"
:total="total"
:background="true"
@handleCurrentChange="changeCurrentPage"
@handleSizeChange="changePageSizes"
></paging>
</div>
</template>
<script setup lang="ts">
import textUnpack from './textUnpack.vue' // 请查看Vue3+element-plus表格筛选与文本展开收起博客
import paging from './paging.vue' // 请查看Vue3+element-plus表格筛选与文本展开收起博客
import { useRouter } from 'vue-router'
const router = useRouter()
const props = defineProps({
currentPage: {
// 当前页
type: Number,
default: 1
},
pageSize: {
// 一页展示条数
type: Number,
default: 10
},
total: {
// 总条数
type: Number,
default: 0
},
tableData: {
// 表格数据
type: Array,
default: () => []
}
})
const emit = defineEmits([
'tableScrollTop',
'searchTableList',
'searchTableList1'
])
// 展开收起综述内容状态
const reviewDetailState = ref(false)
// 展开收起关键词内容状态
const keyWordDetailState = ref(false)
interface SpanMethodProps {
columnIndex: number
}
// 表格滚动条置顶
const setScrollTop = (top: number) => {
emit('tableScrollTop', top)
}
// 查看跳转
const toStockIndexPage = (row: any) => {
router.push({
path: '/main/stock-index',
query: {
securityId: row.securityId,
symbol: row.symbol,
market: row.market,
tabIndex: 7
}
})
}
// 设置表头样式
const headerCellStyle = ({ columnIndex }: SpanMethodProps) => {
if (columnIndex === 9) {
return {
background: '#f4f7fc',
color: '#333333',
fontSize: '13px',
borderRight: 'none',
padding: '1px 0'
}
} else {
return {
background: '#f4f7fc',
color: '#333333',
fontSize: '13px',
borderRight: '1px solid #ebeef8 !important',
padding: '1px 0'
}
}
}
// 点击改变当前页重新渲染表格数据
const changeCurrentPage = (current: number) => {
emit('searchTableList', current)
}
// 点击选择一页展示条数重新渲染表格
const changePageSizes = (pageSize: number) => {
emit('searchTableList1', pageSize)
}
// 设置表格内容展开状态为关闭初始化
const closeInfo = () => {
reviewDetailState.value = false
keyWordDetailState.value = false
}
// 暴露方法给父组件
defineExpose({
closeInfo
})
// 点击全部展开或收起综述内容
const openReviewDetail = () => {
reviewDetailState.value = !reviewDetailState.value
props.tableData.forEach((i: any) => {
i.collapseReview = reviewDetailState.value
})
}
// 点击全部展开或收起关键词内容
const openKeyWordDetail = () => {
keyWordDetailState.value = !keyWordDetailState.value
props.tableData.forEach((i: any) => {
i.collapseKeyWord = keyWordDetailState.value
})
}
</script>
<style>
.headerRowClass {
height: 34px;
}
</style>
<style lang="less" scoped>
.table-list {
.company-box {
cursor: pointer;
&:hover {
color: #3a5bb7;
}
}
.review-box {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 12px;
.review {
font-weight: 700;
font-size: 13px;
color: #333333;
}
.all-open {
display: flex;
align-items: center;
cursor: pointer;
.all-text {
font-weight: 400;
font-size: 12px;
color: #3a5bb7;
}
.icon-box {
display: flex;
justify-content: center;
align-items: center;
width: 16px;
height: 14px;
background: #e8ecf7;
border-radius: 2px;
margin: 0 5px;
.icon-xiala,
.icon-shang {
font-size: 12px;
color: #3a5bb7;
}
}
}
}
.info {
padding: 0 27px 0 12px;
}
.keyWord-info {
padding: 0 27px 0 12px;
}
.btn {
font-size: 13px;
color: #3a5bb7;
}
}
</style>