hi-ucs/front/src/views/home/algorithmCompare.vue

918 lines
21 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="bg">
<home-header></home-header>
<div class="box-container">
<a-spin
size="large"
v-if="loadingPage"
class="loading-box"
:spinning="loadingPage"
/>
<div class="nav-box">
<a-breadcrumb>
<a-breadcrumb-item>能力集市</a-breadcrumb-item>
<a-breadcrumb-item>算法对比</a-breadcrumb-item>
</a-breadcrumb>
</div>
<div class="content">
<a-anchor
:affix="false"
class="left"
:getContainer="getId"
@click="handleClickTab"
>
<a-anchor-link
class="left-item"
:href="`#${data}`"
:title="data"
v-for="(data, i) in leftNav"
:key="i"
:data-title="data"
/>
</a-anchor>
<div class="right">
<div class="top no-border-right">
<div class="td-name">
<!-- selectedRowKeys -->
{{ `共选取${selectedRowKeys.length}个算法` }}
</div>
<div class="td" v-for="(item, k) in detailArray" :key="k">
<span v-if="item">{{ item.name || '--' }}</span>
<span
v-if="item"
@click="deleteList(k)"
class="icon-delete"
></span>
<span
class="add-img"
@click="addList"
v-if="!item && k === detailArray.filter((v) => v).length"
></span>
</div>
</div>
<div class="bottom bottomRef" id="bottomRef" ref="bottomRef">
<div class="bottom-item" v-for="(data, i) in tableData" :key="i">
<div
class="title"
:id="data.title"
:title="data.title"
:ref="data.title"
v-if="
!(
data.title == '算法优势' ||
data.title == '应用场景' ||
data.title == '应用案例' ||
data.title == '常见问题' ||
data.title == '计费标准信息'
)
"
>
{{ data.title }}
</div>
<!-- 算法优势 -->
<!-- <div class="group-data" v-if="data.groupName"> -->
<!-- <compare-group-view :dataList="data.groupList"></compare-group-view> -->
<!-- <div v-if="data.groupList.length > 0">
<div
class="group-box"
v-for="(data, i) in data.groupList"
:key="i"
>
<div
class="flex-row-start row-tr"
v-for="(item, j) in Object.keys(data)"
:key="j"
:class="
j == Object.keys(data).length - 1 ? 'border-bottom' : ''
"
>
<div class="td-name" :style="{ height: getHeight(item) }">
<span class="td-text td-name-text">{{ item }}</span>
</div>
<div class="flex-row-start">
<div
class="td"
:style="{ height: getHeight(item) }"
v-for="(d, k) in data[item]"
:key="k"
>
<a-tooltip placement="top" :title="d">
<span class="td-text">{{ d }}</span>
</a-tooltip>
</div>
</div>
</div>
</div>
</div>
<div v-if="data.groupList.length == 0" class="no-data">
暂无数据
</div> -->
<!-- </div> -->
<div
class="flex-row-start row-tr"
v-for="(rowData, j) in data.list"
:key="j"
:class="j == data.list.length - 1 ? 'border-bottom' : ''"
>
<div
class="td-name"
:style="{ height: getHeight(rowData.name) }"
>
<span class="td-text td-name-text">
{{ rowData.name }}
</span>
</div>
<div class="flex-row-start">
<div
class="td"
v-for="(item, k) in rowData.infoList"
:key="k"
:style="{ height: getHeight(rowData.name) }"
>
<video
v-if="showVideo(rowData.name) && item"
width="240"
height="180"
controls
>
<source :src="item" type="video/mp4" />
您的浏览器不支持 HTML5 video 标签。
</video>
<a-tooltip v-else placement="top" :title="item">
<span class="td-text">{{ item }}</span>
</a-tooltip>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<a-modal
class="modal-box"
title="请选择"
:visible="showAddModal"
:onOk="handleOk"
:onCancel="handleCancel"
>
<a-table
:columns="columns"
:data-source="dataList"
style="height: 610px; overflow-y: scroll"
:row-selection="rowSelection"
rowKey="id"
></a-table>
</a-modal>
<!-- <HomeFooter></HomeFooter> -->
</div>
</template>
<script setup>
import HomeFooter from '@/views/newHome/components/Footer'
import HomeHeader from '@/views/home/components/header'
import CompareGroupView from '@/views/home/components/CompareGroupView'
import { pageWithAttrs } from '@/api/abilityStatistics'
import {
defineComponent,
ref,
onMounted,
getCurrentInstance,
computed,
unref,
reactive,
nextTick,
onCreated,
} from 'vue'
import { selectOne } from '@/api/home'
import { message, Tooltip, Table, Spin } from 'ant-design-vue'
import { useRouter } from 'vue-router'
const router = useRouter()
let queryId = router.currentRoute.value.query.id
const ctx = getCurrentInstance()
// 最大4列
const pagination = ref([])
// 表格列名
const columns = ref([
{
title: '算法名称',
dataIndex: 'name',
},
{
title: '算法类型',
dataIndex: 'type',
},
])
// 详情列表
const detailArray = ref(['', '', '', ''])
const titleInfoObj = {
基本信息: [
{
text: '算法名称',
key: 'name',
},
{
text: '算法类别',
},
{
text: '部署位置',
},
{
text: '应用领域',
key: '应用领域',
},
{
text: '共享条件',
key: 'shareCondition',
},
// {
// text: '共享类型',
// key: 'shareType',
// },
{
text: '算法描述',
key: 'description',
},
{
text: '算法介绍视频',
key: '算法介绍视频',
},
],
// 算法优势: [
// {
// text: '算法优势名称',
// key: 'name',
// },
// {
// text: '算法优势描述',
// key: 'desc',
// },
// ],
// 应用场景: [
// {
// text: '场景名称',
// key: '场景名称',
// },
// {
// text: '场景描述',
// key: '场景描述',
// },
// ],
// 应用案例: [
// {
// text: '关联应用',
// },
// {
// text: '算法需求背景',
// },
// {
// text: '算法应用期望达成效果',
// },
// ],
// 计费标准信息: [
// {
// text: '是否收费',
// },
// {
// text: '计费方式',
// },
// {
// text: '计费描述',
// },
// // {
// // text: '计费标准信息', key: ''
// // },
// ],
使用方式: [
{
text: '服务接口',
},
{
text: '接口请求方式',
key: 'apiMethodType',
},
{
text: '技术文档',
key: '',
},
{
text: '是否支持试用',
key: '',
},
{
text: '试用地址',
},
],
服务商: [
{
text: '服务商',
},
{
text: '服务商联系人',
},
{
text: '服务商联系电话',
},
],
// 常见问题: [
// {
// text: '常见问题',
// },
// {
// text: '回答',
// },
// ],
}
// 左侧导航
const leftNav = ref([])
Object.keys(titleInfoObj).map((v) => leftNav.value.push(v))
// 可能会有多组的数据
const arrayStr = ['算法优势', '应用场景', '计费标准信息', '常见问题']
let textObj = {
算法优势: {
name: '算法优势名称',
desc: '算法优势描述',
},
应用场景: {
name: '场景名称',
desc: '场景描述',
},
计费标准信息: {
type: '计费方式',
price: '价格',
desc: '计费描述信息',
是否收费: '是否收费',
},
常见问题: {
question: '常见问题',
answer: '回答',
},
}
const showAddModal = ref(false)
const dataList = ref([])
const selectedRowKeys = ref([])
let tableData = ref([])
const loadingPage = ref(false)
const getId = () => {
return window.document.getElementById('bottomRef')
}
const handleClickTab = (e, link) => {
// 阻止点击的默认事件修改路由
e.preventDefault()
if (link.href) {
let ele = document.getElementById(link.href)
ele && ele.scrollIntoView({ block: 'start', behavior: 'smooth' })
}
}
// 初始化
onMounted(() => {
selectedRowKeys.value.push(queryId)
nextTick(() => {
getList().then((res) => {
initData()
})
})
})
const initData = () => {
loadingPage.value = true
// queryId
// 获取详情
Promise.all(selectedRowKeys.value.map((id) => getDetail(id)))
.then((data) => {
detailArray.value = []
for (let index = 0; index < 4; index++) {
if (data[index] == undefined) {
detailArray.value.push('')
} else {
detailArray.value.push(formatterData(data[index]))
}
}
nextTick(() => {
// 处理数据
getNewData()
})
loadingPage.value = false
})
.catch((err) => {
loadingPage.value = false
message.error(err || '获取算法详情失败,请重试!')
})
}
// 处理数组
const getNewData = () => {
tableData.value = []
Object.keys(titleInfoObj).map((titleKey, i) => {
// 标题
let _newObj = {
title: titleKey,
}
if (arrayStr.includes(titleKey)) {
_newObj.groupName = titleKey
_newObj.groupList = []
} else {
_newObj.list = []
}
let list = []
titleInfoObj[titleKey].map((trName, index) => {
let obj = {
name: trName.text,
}
if (!arrayStr.includes(titleKey)) {
obj.infoList = getInfoList(trName)
list.push(obj)
} else {
console.log(titleKey, trName)
_newObj.groupList = getGroupList(titleKey, trName)
}
})
if (!arrayStr.includes(titleKey)) {
_newObj.list = list
}
tableData.value.push(_newObj)
})
tableData.value[1].list[4].infoList.map((item, index) => {
if (!item && tableData.value[0].list[0].infoList[index]) {
tableData.value[1].list[3].infoList[index] = '否'
} else if (item && tableData.value[0].list[0].infoList[index]) {
tableData.value[1].list[3].infoList[index] = '是'
}
})
console.log('11111111111111', tableData.value[1].list[4])
}
// 基本信息等
const getInfoList = (rowItem) => {
let arr = []
detailArray.value.map((item) => {
let val = undefined
val = item[rowItem.key || rowItem.text]
arr.push(val)
})
return arr
}
// 算法优势分组信息数组getGroupList
const getGroupList = (titleKey, trName) => {
let arr = []
detailArray.value.map((item) => {
if (item) {
if (arrayStr.includes(titleKey)) {
let groupItemObj = {}
let _list = item[titleKey] || []
let textInfo = textObj[titleKey]
_list.map((v) => {
// console.log(v)
Object.keys(v).map((d) => {
console.log(textInfo[d])
if (textInfo[d]) {
if (!groupItemObj[textInfo[d]]) {
groupItemObj[textInfo[d]] = ''
}
groupItemObj[textInfo[d]] += v[d] + ';'
}
})
})
arr.push(groupItemObj)
}
}
})
let _arr = translateArray(arr)
return _arr
}
// 数组转化
const translateArray = (list) => {
let arr = []
if (list.every((v) => JSON.stringify(v) == '{}')) {
arr = []
} else {
let itemObj = list.find((v) => JSON.stringify(v) !== '{}')
let obj = {}
Object.keys(itemObj).map((v) => {
let arr2 = []
list.map((item) => {
arr2.push(item[v] || '')
})
obj[v] = arr2
})
arr.push(obj)
}
return arr
}
// 获取算法列表
const getList = () => {
const data = {
deptIds: [],
districtId: '',
infoList: [{ attrType: '组件类型', attrValue: '智能算法' }],
name: '',
orderField: 'total',
orderType: 'DESC',
pageNum: 1,
pageSize: 15,
// type: '组件服务',
type: '',
}
return new Promise((resolve, reject) => {
pageWithAttrs(data)
.then((res) => {
dataList.value = res.data.data.records || []
nextTick(() => {
// 默认前两个
// selectedRowKeys.value.push(dataList.value[0].id)
// selectedRowKeys.value.push(dataList.value[1].id)
})
resolve(res)
})
.catch((err) => {
reject(err)
})
})
}
// 删除算法
const deleteList = (i) => {
selectedRowKeys.value.splice(i, 1)
detailArray.value.splice(i, 1)
nextTick(() => {
for (let index = 0; index < 4; index++) {
if (detailArray.value[index] == undefined) {
detailArray.value.splice(index, 1, '')
}
}
getNewData()
})
}
const addList = () => {
showAddModal.value = true
}
const handleOk = () => {
if (selectedRowKeys.value.length > 4) {
message.error('最多选择四个算法!')
return false
}
initData()
showAddModal.value = false
}
const handleCancel = () => {
showAddModal.value = false
}
const rowSelection = computed(() => {
return {
selectedRowKeys: unref(selectedRowKeys),
onChange: (changableRowKeys) => {
if (changableRowKeys.length > 4) {
message.error('最多选择四个算法!')
} else {
selectedRowKeys.value = changableRowKeys
}
if (selectedRowKeys.value.length > 4) {
selectedRowKeys.value = selectedRowKeys.value.splice(4)
}
},
hideDefaultSelections: true,
}
})
// 动态获取高度
const getHeight = (name) => {
if (name.indexOf('描述') != -1) {
return '120px'
}
if (name.indexOf('视频') != -1) {
return '230px'
}
}
// 是否视频播放
const showVideo = (name) => {
if (name.indexOf('视频') !== -1) {
return true
}
return false
}
// 获取详情
const getDetail = (id) => {
return new Promise((resolve, reject) => {
selectOne(id)
.then((res) => {
resolve(res.data && res.data.data)
})
.catch((err) => {
reject(err)
})
})
}
// 判断是否json字符串
const isJson = (str) => {
if (typeof str == 'string') {
try {
let obj = JSON.parse(str)
return true
} catch (e) {
return false
}
}
}
// infoList数组处理
const formatterData = (obj) => {
let _newObj = {}
obj.infoList.map((v) => {
_newObj[v.attrType] = isJson(v.attrValue)
? JSON.parse(v.attrValue)
: v.attrValue
})
let _obj = Object.assign({}, obj, _newObj)
return _obj
}
</script>
<style lang="less" scoped>
.bg {
background: #fff;
height: 100vh;
width: 100%;
}
// @font-face {
// font-family: 'num-typeface';
// src: url('~@/assets/newHome/font/num-typeface.otf');
// }
.border {
border: 1px solid #dddee1;
border-bottom: none;
border-right: none;
}
.border-bottom {
border-bottom: 1px solid #dddee1;
}
.no-border-right {
border: 1px solid #dddee1;
border-right: none;
}
.flex-row-start {
display: flex;
justify-content: flex-start;
align-items: center;
}
.box-container {
width: 1592px;
margin: 0 auto;
padding-top: 60px;
height: 100vh;
box-sizing: border-box;
.content {
display: flex;
justify-content: flex-start;
align-items: flex-start;
padding-top: 10px;
height: calc(100% - 60px);
width: 100%;
}
.nav-box {
height: 50px;
width: 100%;
font-size: 14px;
display: flex;
align-items: center;
background: rgba(244, 245, 248, 0.8);
padding-left: 10px;
}
.left {
width: 200px;
height: 600px;
background: rgba(244, 245, 248, 0.8);
.left-item {
margin: 0 14px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
color: #212121;
border-bottom: 1px solid #dddee1;
&:hover {
cursor: pointer;
}
}
.active {
background: #0058e1;
color: #fff !important;
margin: 0;
}
}
.right {
width: 1370px;
margin-left: 32px;
height: 100%;
.top {
width: 100%;
height: 100px;
margin-bottom: 20px;
display: flex;
align-items: center;
justify-content: flex-start;
.td-name {
height: 100px;
display: flex;
align-items: center;
justify-content: center;
}
.td {
height: 100px;
line-height: 100px;
position: relative;
display: flex;
justify-content: center;
align-items: center;
}
.icon-delete {
position: absolute;
right: 10px;
top: 10px;
height: 12px;
width: 12px;
background: url('~@/assets/newHome/delete-on.png');
background-size: 100% 100%;
cursor: pointer;
}
}
.bottom {
width: 100%;
overflow-y: auto;
height: calc(100% - 130px);
padding-bottom: 10px;
box-sizing: border-box;
}
}
}
.title {
font-size: 14px;
padding: 20px 0 10px 10px;
color: #212121;
font-weight: bold;
background: rgba(244, 245, 248, 0.8);
}
.td-name {
border-right: 1px solid #dddee1;
height: 60px;
line-height: 60px;
text-align: center;
width: 200px;
font-size: 14px;
display: flex;
align-items: center;
justify-content: center;
}
.td {
border-right: 1px solid #dddee1;
height: 60px;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
width: 290px;
font-size: 14px;
box-sizing: border-box;
table-layout: fixed;
}
.td-text {
width: 290px;
font-size: 14px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
word-break: break-all;
}
.td-name-text {
width: 200px;
}
.row-tr {
border: 1px solid #dddee1;
border-right: none;
border-bottom: none;
background: #fff;
}
.border-bottom {
border-bottom: 1px solid #dddee1;
}
.modal-box {
height: 650px;
width: 800px;
}
.add-img {
height: 60px;
width: 60px;
background: url('~@/assets/newHome/add-on.png');
background-size: 100% 100%;
cursor: pointer;
}
.no-data {
height: 100px;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #dddee1;
}
.loading-box {
width: 1592px;
height: 500px;
position: absolute;
display: flex;
align-items: center;
justify-content: center;
}
.video-box {
height: 140px;
width: 240px;
}
.ant-anchor-wrapper {
width: 200px;
height: 600px;
background: rgba(244, 245, 248, 0.8);
padding-left: 0;
position: static;
}
.ant-anchor-ink::before {
content: ' ';
width: 0 !important;
}
/deep/ .ant-anchor {
position: static;
padding-left: 0;
}
.ant-anchor-link {
padding: 0;
margin: 0 14px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
color: #212121;
border-bottom: 1px solid #dddee1;
}
:deep(.ant-checkbox-indeterminate) {
display: none;
}
</style>