找企业
This commit is contained in:
@ -39,6 +39,14 @@ export const constantRoutes = [
|
||||
path: '',
|
||||
component: () => import('../views/website/index/index.vue'),
|
||||
},
|
||||
{
|
||||
path: 'searchList/0',
|
||||
component: () => import('../views/website/searchList/index0.vue'),
|
||||
},
|
||||
{
|
||||
path: 'searchList/0/detail/:id',
|
||||
component: () => import('../views/website/searchList/index0Detail.vue'),
|
||||
},
|
||||
{
|
||||
path: 'solution/:name',
|
||||
name: 'solution',
|
||||
|
@ -5,9 +5,9 @@
|
||||
<el-col :push="4" :sm="10" :md="12">
|
||||
<div class="tab">
|
||||
<div
|
||||
v-for="(v,index) in queryParams.tabList"
|
||||
:class="{ active: queryParams.tabIndex == index }"
|
||||
@click="queryParams.tabIndex = index"
|
||||
v-for="(v,index) in state.tabList"
|
||||
:class="{ active: state.tabIndex == index }"
|
||||
@click="state.tabIndex = index"
|
||||
>{{ v }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
@ -15,7 +15,7 @@
|
||||
<div style="height: 16px;"></div>
|
||||
<el-row>
|
||||
<el-col :push="4" :sm="10" :md="12">
|
||||
<el-input v-model.trim="queryParams.input3" placeholder="请输入检索词">
|
||||
<el-input v-model.trim="state.keyword" placeholder="请输入检索词">
|
||||
<template #append>
|
||||
<el-button class="x_btns" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
</template>
|
||||
@ -33,23 +33,23 @@
|
||||
<el-col :push="3" :pull="3" :span="18">
|
||||
<div class="numBox">
|
||||
<div>
|
||||
<div class="val">9800+</div>
|
||||
<div class="val">{{ state.data.expert_count }}</div>
|
||||
<div class="des">专家数量</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="val">98000+</div>
|
||||
<div class="val">{{ state.data.patent_count + state.data.achievement_count }}</div>
|
||||
<div class="des">专利成果数量</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="val">10000+</div>
|
||||
<div class="val">{{ state.data.demand_count }}</div>
|
||||
<div class="des">需求数量</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="val">120000+</div>
|
||||
<div class="val">{{ state.data.docking_count }}</div>
|
||||
<div class="des">对接数量</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="val">11000+</div>
|
||||
<div class="val">{{ state.data.company_count }}</div>
|
||||
<div class="des">实验室数量</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -59,25 +59,49 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
<script setup>
|
||||
import { onMounted, reactive } from "vue";
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
input3: "",
|
||||
const router = useRouter();
|
||||
import request from '@/utils/request'
|
||||
function indexData () {
|
||||
return request({
|
||||
url: '/v1/index',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
function handleDetail (mode, keyword) {
|
||||
let routeData = router.resolve({ path: `/searchList/${mode}`, query: { keyword } });
|
||||
window.open(routeData.href, '_blank');
|
||||
}
|
||||
|
||||
function handleQuery () {
|
||||
console.log(state.keyword, state.tabIndex)
|
||||
handleDetail(state.tabIndex, state.keyword)
|
||||
}
|
||||
|
||||
const state = reactive({
|
||||
keyword: "",
|
||||
tabList: [
|
||||
'找企业', '找成果', '找实验室', '找专利', '找专家', '接需求'
|
||||
],
|
||||
tabIndex: 0,
|
||||
data: {
|
||||
expert_count: 0,
|
||||
company_count: 0,
|
||||
patent_count: 0,
|
||||
achievement_count: 0,
|
||||
demand_count: 0,
|
||||
docking_count: 0,
|
||||
}
|
||||
});
|
||||
function handleQuery() {
|
||||
queryParams.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
function getList() { }
|
||||
|
||||
onMounted(() => {
|
||||
console.log("onmunted");
|
||||
indexData().then(res => {
|
||||
if (200 == res.code) {
|
||||
state.data = res.data
|
||||
}
|
||||
})
|
||||
// console.log("onmunted");
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -1,5 +1,32 @@
|
||||
<template>
|
||||
<div class="home">
|
||||
<div class="fullPage" ref="fullPage">
|
||||
<div
|
||||
class="fullPageContainer"
|
||||
ref="fullPageContainer"
|
||||
@mousewheel="mouseWheelHandle"
|
||||
@DOMMouseScroll="mouseWheelHandle"
|
||||
>
|
||||
<div
|
||||
v-for="(item, $index) in state.boxList"
|
||||
class="section"
|
||||
:key="$index"
|
||||
:style="`z-index: ${item.zIndex};`"
|
||||
>
|
||||
<component :is="item.comp"></component>
|
||||
</div>
|
||||
|
||||
<!-- <div class="section"><index1></index1></div>
|
||||
<div class="section"><index2 /></div>
|
||||
<div class="section"><index3 /></div>
|
||||
<div class="section"><index4 /></div>
|
||||
<div class="section"><index5 /></div>
|
||||
<div class="section"><index6 /></div>
|
||||
<div class="section"><index7 /></div>
|
||||
<div class="section"><index8 /></div>-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="home">
|
||||
<transition-group
|
||||
:enter-active-class="state.animate.in"
|
||||
:leave-active-class="state.animate.out"
|
||||
@ -14,12 +41,12 @@
|
||||
<component :is="item.comp"></component>
|
||||
</div>
|
||||
</transition-group>
|
||||
</div>
|
||||
</div>-->
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, onMounted } from "vue";
|
||||
|
||||
import { reactive, onMounted, getCurrentInstance } from "vue";
|
||||
const { proxy } = getCurrentInstance();
|
||||
import index1 from './comp/index1.vue';
|
||||
import index2 from './comp/index2.vue';
|
||||
import index3 from './comp/index3.vue';
|
||||
@ -29,7 +56,62 @@ import index6 from './comp/index6.vue';
|
||||
import index7 from './comp/index7.vue';
|
||||
import index8 from './comp/index8.vue';
|
||||
|
||||
|
||||
function next() { // 往下切换
|
||||
let len = 8; // 页面的个数
|
||||
if (state.fullpage.current + 1 <= len) { // 如果当前页面编号+1 小于总个数,则可以执行向下滑动
|
||||
state.fullpage.current += 1; // 页面+1
|
||||
move(state.fullpage.current); // 执行切换
|
||||
}
|
||||
}
|
||||
function pre() {// 往上切换
|
||||
if (state.fullpage.current - 1 > 0) { // 如果当前页面编号-1 大于0,则可以执行向下滑动
|
||||
state.fullpage.current -= 1;// 页面+1
|
||||
move(state.fullpage.current);// 执行切换
|
||||
}
|
||||
}
|
||||
function move(index) {
|
||||
state.fullpage.isScrolling = true; // 为了防止滚动多页,需要通过一个变量来控制是否滚动
|
||||
directToMove(index); //执行滚动
|
||||
setTimeout(() => { //这里的动画是1s执行完,使用setTimeout延迟1s后解锁
|
||||
state.fullpage.isScrolling = false;
|
||||
}, 1010);
|
||||
}
|
||||
function directToMove(index) {
|
||||
let height = proxy.$refs["fullPage"]['clientHeight']; //获取屏幕的宽度
|
||||
let scrollPage = proxy.$refs["fullPageContainer"]; // 获取执行tarnsform的元素
|
||||
let scrollHeight; // 计算滚动的告诉,是往上滚还往下滚
|
||||
scrollHeight = -(index - 1) * height + "px";
|
||||
scrollPage.style.transform = `translateY(${scrollHeight})`;
|
||||
state.fullpage.current = index;
|
||||
}
|
||||
function mouseWheelHandle(event) { // 监听鼠标监听
|
||||
// 添加冒泡阻止
|
||||
let evt = event || window.event;
|
||||
if (evt.stopPropagation) {
|
||||
evt.stopPropagation();
|
||||
} else {
|
||||
evt.returnValue = false;
|
||||
}
|
||||
if (state.fullpage.isScrolling) { // 判断是否可以滚动
|
||||
return false;
|
||||
}
|
||||
let e = event.originalEvent || event;
|
||||
state.fullpage.deltaY = e.deltaY || e.detail; // Firefox使用detail
|
||||
if (state.fullpage.deltaY > 0) {
|
||||
next();
|
||||
} else if (state.fullpage.deltaY < 0) {
|
||||
pre();
|
||||
}
|
||||
}
|
||||
|
||||
let state = reactive({
|
||||
|
||||
fullpage: {
|
||||
current: 1, // 当前的页面编号
|
||||
isScrolling: false, // 是否在滚动,是为了防止滚动多页,需要通过一个变量来控制是否滚动
|
||||
deltaY: 0 // 返回鼠标滚轮的垂直滚动量,保存的鼠标滚动事件的deleteY,用来判断是往下还是往上滚
|
||||
},
|
||||
showBox: 0,
|
||||
boxList: [
|
||||
{
|
||||
@ -78,101 +160,27 @@ let state = reactive({
|
||||
out: "animate__animated animate__fadeOutDown",
|
||||
},
|
||||
});
|
||||
function choice(i: number) {
|
||||
if (i > state.showBox && i == (state.boxList.length + 1)) return false;
|
||||
if(i < state.showBox && i == 0) return false;
|
||||
if (i === state.showBox) return false;
|
||||
|
||||
// style 的 z-index 属性提升到最上面
|
||||
state.boxList.forEach((item, idx) => {
|
||||
if (idx === i) {
|
||||
item.zIndex = 100;
|
||||
} else {
|
||||
item.zIndex = 1;
|
||||
}
|
||||
});
|
||||
|
||||
// 根据判断当前显示的 box 下标和点击的下标进行对比,修改动画方向
|
||||
const animateType = "fade";
|
||||
if (i > state.showBox) {
|
||||
state.animate.in = `animate__animated animate__${animateType}InUp`;
|
||||
state.animate.out = `animate__animated animate__${animateType}OutUp`;
|
||||
} else {
|
||||
state.animate.in = `animate__animated animate__${animateType}InDown`;
|
||||
state.animate.out = `animate__animated animate__${animateType}OutDown`;
|
||||
}
|
||||
|
||||
state.showBox = i;
|
||||
}
|
||||
|
||||
const mouseWheelHandler = (event: any) => {
|
||||
let i = state.showBox;
|
||||
if (mouseWheelFlag(event) === "up") {
|
||||
i = i - 1 < 0 ? state.boxList.length - 1 : i - 1;
|
||||
} else {
|
||||
i = i + 1 > state.boxList.length - 1 ? 0 : i + 1;
|
||||
}
|
||||
choice(i);
|
||||
};
|
||||
|
||||
/**
|
||||
* mouseWheelFlag
|
||||
* @param event window.event
|
||||
* @returns up | down
|
||||
*/
|
||||
const mouseWheelFlag: (event: any) => string = (event: any) => {
|
||||
let delta = 0;
|
||||
if (!event) event = window.event;
|
||||
if (event.wheelDelta) {
|
||||
//IE、chrome浏览器使用的是wheelDelta,并且值为“正负120”
|
||||
delta = event.wheelDelta / 120;
|
||||
if ((window as any).opera) delta = -delta; //因为IE、chrome等向下滚动是负值,FF是正值,为了处理一致性,在此取反处理
|
||||
} else if (event.detail) {
|
||||
//FF浏览器使用的是detail,其值为“正负3”
|
||||
delta = -event.detail / 3;
|
||||
}
|
||||
return delta > 0 ? "up" : "down";
|
||||
};
|
||||
|
||||
/**
|
||||
* throttle 节流
|
||||
* @param func 须要包装的函数
|
||||
* @param delay 延迟时间,单位ms
|
||||
*/
|
||||
const throttle: (func: any, delay: number, immediate?: boolean) => any = (
|
||||
func,
|
||||
delay = 100
|
||||
) => {
|
||||
let flag = false;
|
||||
return (...args: any) => {
|
||||
if (!flag) {
|
||||
flag = true;
|
||||
setTimeout(() => {
|
||||
flag = false;
|
||||
func.call(this, ...args);
|
||||
}, delay);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener("mousewheel", throttle(mouseWheelHandler, 500), true);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
height: 100%;
|
||||
.fullPage {
|
||||
width: 100%;
|
||||
backdrop-filter: blur(4rpx);
|
||||
}
|
||||
.home {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
.box {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
.fullPageContainer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transition: all linear 0.5s;
|
||||
}
|
||||
.section {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
112
src/views/website/searchList/components/collectAndVisit.vue
Normal file
112
src/views/website/searchList/components/collectAndVisit.vue
Normal file
@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<div class="collectAndVisit">
|
||||
<div>{{ visit_count }}游览</div>
|
||||
<div class="heart_w">
|
||||
<div class="heart" @click="change()" :class="{ in: state.isCollect }"></div>
|
||||
<span>{{ state.collect }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import request from '@/utils/request'
|
||||
import { reactive } from 'vue';
|
||||
function launch (id) {
|
||||
return request({
|
||||
url: '/v1/user/collect/launch',
|
||||
method: 'post',
|
||||
data: { kind: props.kind, object_id: props.object_id, }
|
||||
})
|
||||
}
|
||||
let flag = true;
|
||||
const props = defineProps({
|
||||
is_collect: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
collect_count: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
visit_count: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
kind: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
object_id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const state = reactive({
|
||||
collect: props.collect_count,
|
||||
isCollect: props.is_collect,
|
||||
})
|
||||
|
||||
async function postData () {
|
||||
if (flag) {
|
||||
flag = false;
|
||||
await launch().then(res => {
|
||||
if (200 == res.code) {
|
||||
state.isCollect = res.data;
|
||||
if (res.data) {
|
||||
state.collect++;
|
||||
} else {
|
||||
state.collect--;
|
||||
}
|
||||
}
|
||||
flag = true;
|
||||
}).catch(() => {
|
||||
flag = false;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function change () {
|
||||
|
||||
postData();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.collectAndVisit {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
.heart_w {
|
||||
vertical-align: text-bottom;
|
||||
span {
|
||||
vertical-align: text-bottom;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
}
|
||||
.heart {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
vertical-align: text-bottom;
|
||||
display: inline-block;
|
||||
width: 18.3px;
|
||||
height: 16.4px;
|
||||
margin-right: 5px;
|
||||
background-size: cover;
|
||||
background-image: url(./img/heart0.png);
|
||||
}
|
||||
.in {
|
||||
background-image: url(./img/heart1.png);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
BIN
src/views/website/searchList/components/img/heart0.png
Normal file
BIN
src/views/website/searchList/components/img/heart0.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 723 B |
BIN
src/views/website/searchList/components/img/heart1.png
Normal file
BIN
src/views/website/searchList/components/img/heart1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 503 B |
116
src/views/website/searchList/components/industrySelect.vue
Normal file
116
src/views/website/searchList/components/industrySelect.vue
Normal file
@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row type="flex">
|
||||
<div style="display: inline-block;line-height: 32px;">所属领域:</div>
|
||||
<div style="flex:1">
|
||||
<el-row :gutter="10" style="margin-bottom: 10px;">
|
||||
<el-col :span="8">
|
||||
<el-select
|
||||
style="width: 100%;"
|
||||
placeholder="请选择"
|
||||
v-model="state.id1"
|
||||
@change="state.id2 = '';change()"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="option in state.industryList"
|
||||
:key="option.id"
|
||||
:value="option.id"
|
||||
:label="option.name"
|
||||
/>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-select
|
||||
style="width: 100%;"
|
||||
placeholder="请选择"
|
||||
v-model="state.id2"
|
||||
@change="state.id3 = '';change()"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="option in searchIndustryData(state.id1)['children']"
|
||||
:key="option.id"
|
||||
:value="option.id"
|
||||
:label="option.name"
|
||||
/>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-select
|
||||
style="width: 100%;"
|
||||
placeholder="请选择"
|
||||
v-model="state.id3"
|
||||
@change="change()"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="option in searchIndustryData(state.id2)['children']"
|
||||
:key="option.id"
|
||||
:value="option.id"
|
||||
:label="option.name"
|
||||
/>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted } from 'vue';
|
||||
import { industry } from "@/api/website/home/index";
|
||||
const state = reactive({
|
||||
industryList: [],
|
||||
id1: '',
|
||||
id2: '',
|
||||
id3: '',
|
||||
});
|
||||
let treeData = [];
|
||||
const emit = defineEmits();
|
||||
function change() {
|
||||
emit("industryChange", {
|
||||
id1: state.id1,
|
||||
id2: state.id2,
|
||||
id3: state.id3,
|
||||
});
|
||||
}
|
||||
|
||||
function searchIndustryData (code) {
|
||||
return deepFindTree(code, treeData);
|
||||
}
|
||||
|
||||
function deepFindTree (code, arr) {
|
||||
let snap = false;
|
||||
for (let index = 0; index < arr.length; index++) {
|
||||
const ele = arr[index];
|
||||
if (code == ele.id) {
|
||||
snap = ele;
|
||||
break;
|
||||
} else if (ele['children'] != null) {
|
||||
snap = deepFindTree(code, ele['children']);
|
||||
if (snap) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
snap = false;
|
||||
}
|
||||
}
|
||||
return snap;
|
||||
}
|
||||
|
||||
function init () {
|
||||
industry().then(res => {
|
||||
if (200 == res.code) {
|
||||
state.industryList = res.data;
|
||||
treeData = res.data;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
|
||||
</script>
|
126
src/views/website/searchList/components/productItem.vue
Normal file
126
src/views/website/searchList/components/productItem.vue
Normal file
@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="wrap">
|
||||
<div class="img">
|
||||
<!-- <img :src="data.image" alt /> -->
|
||||
<img src="https://t7.baidu.com/it/u=1951548898,3927145&fm=193&f=GIF" />
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="tit">{{ data.title }}</div>
|
||||
<div class="line">
|
||||
技术成熟度:
|
||||
<span>{{ data.maturity_title }}</span>
|
||||
</div>
|
||||
<div class="line">
|
||||
合作模式:
|
||||
<span>{{ data.cooperation_mode_title }}</span>
|
||||
</div>
|
||||
<div class="labelList">
|
||||
<div v-for="item in data.industrys">{{ item }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="keywords">
|
||||
<wordcloud v-if="data.keywords" :data="createdData(data.keywords)"></wordcloud>
|
||||
</div>
|
||||
<collectAndVisit :is_collect="data.is_collect" :collect_count="data.collect_count" :visit_count="data.visit_count" :object_id="data.id" :kind="1005"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import wordcloud from './wordcloud.vue'
|
||||
import collectAndVisit from './collectAndVisit.vue'
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
function createdData (arr) {
|
||||
let l = [];
|
||||
let snap = JSON.parse(JSON.stringify(arr))
|
||||
snap.map(e => {
|
||||
l.push({ name: e, value: 30 })
|
||||
return { name: e, value: 30 }
|
||||
})
|
||||
return l;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
height: 190px;
|
||||
background: #ffffff;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
.wrap {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.img {
|
||||
width: 200px;
|
||||
height: 150px;
|
||||
margin-right: 10px;
|
||||
img {
|
||||
display: block;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.keywords {
|
||||
width: 129px;
|
||||
height: 129px;
|
||||
}
|
||||
.content {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
|
||||
.labelList {
|
||||
overflow: hidden;
|
||||
div {
|
||||
padding: 2px 4px;
|
||||
float: left;
|
||||
background: #0054ff;
|
||||
border-radius: 4px;
|
||||
margin-right: 5px;
|
||||
margin-bottom: 5px;
|
||||
font-size: 14px;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
font-size: 16px;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
color: #666666;
|
||||
margin: 10px 0;
|
||||
span {
|
||||
font-size: 16px;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
.tit {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
font-size: 20px;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
112
src/views/website/searchList/components/searchContainer.vue
Normal file
112
src/views/website/searchList/components/searchContainer.vue
Normal file
@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<div class="searchContainer" v-loading="loading">
|
||||
<div class="wrap">
|
||||
<div
|
||||
class="banner"
|
||||
style="height: 394px;background-size: cover;background-color: #ccc"
|
||||
:style="{ backgroundImage: state.banner ? `url(${state.banner})` : '' }"
|
||||
>
|
||||
<div class="conter1000">
|
||||
<div class="tit">{{ title }}</div>
|
||||
<el-input v-model.trim="state.currentKeyword" placeholder="请输入检索词">
|
||||
<template #append>
|
||||
<el-button icon="Search" @click="handleQuery">搜索</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="conter1000">
|
||||
<slot ></slot>
|
||||
</div>
|
||||
</div>
|
||||
<webFooter></webFooter>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import webFooter from "@/components/webFooter/index.vue";
|
||||
import request from '@/utils/request'
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
import { banner } from "@/api/website/home/index";
|
||||
const loading = ref(true);
|
||||
|
||||
const state = reactive({
|
||||
currentKeyword: ''
|
||||
});
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
bannerKey: {
|
||||
required: true,
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
const emit = defineEmits();
|
||||
|
||||
function handleQuery () {
|
||||
emit("handleQuery", state.currentKeyword);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
state.currentKeyword = route.query.keyword;
|
||||
handleQuery();
|
||||
banner(props.bannerKey).then(res => {
|
||||
if (200 == res.code) {
|
||||
state.banner = res.data.images
|
||||
loading.value = false;
|
||||
}
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
})
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.searchContainer {
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.wrap {
|
||||
flex: 1;
|
||||
background: #F2F6FF;
|
||||
}
|
||||
.banner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.tit {
|
||||
text-align: center;
|
||||
font-size: 34px;
|
||||
line-height: 80px;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
text-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.el-input {
|
||||
::v-deep(.el-input__inner) {
|
||||
border-right: 0;
|
||||
}
|
||||
::v-deep(.el-input-group__append) {
|
||||
overflow: hidden;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
border-top-color: #0054ff;
|
||||
border-right-color: #0054ff;
|
||||
border-bottom-color: #0054ff;
|
||||
background-color: #0054ff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
::v-deep(.el-input__inner),
|
||||
::v-deep(.el-input-group__append) {
|
||||
height: 50px !important;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
209
src/views/website/searchList/components/wordcloud.vue
Normal file
209
src/views/website/searchList/components/wordcloud.vue
Normal file
@ -0,0 +1,209 @@
|
||||
<template>
|
||||
<div class="wordcloud">
|
||||
<div
|
||||
class="wordCloud__tagBall"
|
||||
:style="{width:`${this.width}px`,height:`${this.height}px`}"
|
||||
@mouseenter="stop"
|
||||
@mouseleave="start"
|
||||
>
|
||||
<span
|
||||
class="wordCloud__tag"
|
||||
v-for="(item, index) of data"
|
||||
:key="index"
|
||||
:style="{color:color[index % color.length],...contentEle[index].style}"
|
||||
:title="item.name+item.value"
|
||||
>{{item.name}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'cloudWork',
|
||||
props: {
|
||||
width: {
|
||||
type: Number,
|
||||
default: 129
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 129
|
||||
},
|
||||
// 测试数据
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => [
|
||||
{
|
||||
name: '测试一类',
|
||||
value: 30
|
||||
},
|
||||
{
|
||||
name: '测试二类',
|
||||
value: 30
|
||||
},
|
||||
{
|
||||
name: '测试三类',
|
||||
value: 30
|
||||
},
|
||||
{
|
||||
name: '测试四类',
|
||||
value: 30
|
||||
},
|
||||
|
||||
]
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
color: ['#0054FF', '#B9B9B9', '#D1AF07', '#E27914', '#CB4A4D', '#B02690'],
|
||||
contentEle: [],
|
||||
direction: '-1',
|
||||
speed: 400,
|
||||
animateID: null
|
||||
}),
|
||||
created() {
|
||||
this.contentEle = this.data.map(() => ({
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0,
|
||||
style: {}
|
||||
}));
|
||||
},
|
||||
mounted() {
|
||||
this.innit();
|
||||
},
|
||||
methods: {
|
||||
innit() {
|
||||
const RADIUSX = (this.width - 50) / 2;
|
||||
const RADIUSY = (this.height - 50) / 2;
|
||||
this.contentEle = [];
|
||||
for (let i = 0; i < this.data.length; i += 1) {
|
||||
const k = -1 + (2 * (i + 1) - 1) / this.data.length;
|
||||
const a = Math.acos(k);
|
||||
const b = a * Math.sqrt(this.data.length * Math.PI);
|
||||
const x = RADIUSX * Math.sin(a) * Math.cos(b);
|
||||
const y = RADIUSY * Math.sin(a) * Math.sin(b);
|
||||
const z = RADIUSX * Math.cos(a);
|
||||
const singleEle = {
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
style: {}
|
||||
};
|
||||
this.contentEle.push(singleEle);
|
||||
}
|
||||
this.animate();
|
||||
},
|
||||
animate() {
|
||||
this.rotateX();
|
||||
this.rotateY();
|
||||
this.move();
|
||||
this.animateID = window.requestAnimationFrame(this.animate);
|
||||
},
|
||||
rotateX() {
|
||||
const angleX = ['-1', '1'].includes(this.direction)
|
||||
? Math.PI / Infinity
|
||||
: Math.PI / ((Number(this.direction) / 2) * Number(this.speed));
|
||||
const cos = Math.cos(angleX);
|
||||
const sin = Math.sin(angleX);
|
||||
|
||||
this.contentEle = this.contentEle.map((t) => {
|
||||
const y1 = t.y * cos - t.z * sin;
|
||||
const z1 = t.z * cos + t.y * sin;
|
||||
return {
|
||||
...t,
|
||||
y: y1,
|
||||
z: z1
|
||||
};
|
||||
});
|
||||
},
|
||||
rotateY() {
|
||||
const angleY = ['-2', '2'].includes(this.direction)
|
||||
? Math.PI / Infinity
|
||||
: Math.PI / (Number(this.direction) * Number(this.speed));
|
||||
const cos = Math.cos(angleY);
|
||||
const sin = Math.sin(angleY);
|
||||
this.contentEle = this.contentEle.map((t) => {
|
||||
const x1 = t.x * cos - t.z * sin;
|
||||
const z1 = t.z * cos + t.x * sin;
|
||||
return {
|
||||
...t,
|
||||
x: x1,
|
||||
z: z1
|
||||
};
|
||||
});
|
||||
},
|
||||
move() {
|
||||
const CX = this.width / 2;
|
||||
const CY = this.height / 2;
|
||||
this.contentEle = this.contentEle.map((singleEle) => {
|
||||
const { x, y, z } = singleEle;
|
||||
const fallLength = 500;
|
||||
const RADIUS = (this.width - 50) / 2;
|
||||
const scale = fallLength / (fallLength - z);
|
||||
const alpha = (z + RADIUS) / (2 * RADIUS);
|
||||
const left = `${x + CX - 15}px`;
|
||||
const top = `${y + CY - 15}px`;
|
||||
const transform = `translate(${left}, ${top}) scale(${scale})`;
|
||||
const style = {
|
||||
...singleEle.style,
|
||||
opacity: alpha + 0.5,
|
||||
zIndex: parseInt(scale * 100, 10),
|
||||
transform
|
||||
};
|
||||
return {
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
style
|
||||
};
|
||||
});
|
||||
},
|
||||
// 鼠标移入暂停
|
||||
stop() {
|
||||
window.cancelAnimationFrame(this.animateID);
|
||||
},
|
||||
// 鼠标离开恢复
|
||||
start() {
|
||||
this.animate();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
button {
|
||||
margin: 20px;
|
||||
}
|
||||
.wordcloud {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.wordCloud__tagBall {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.wordCloud__tag {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
color: green;
|
||||
text-decoration: none;
|
||||
font-size: 12px;
|
||||
font-family: '微软雅黑';
|
||||
font-weight: bold;
|
||||
}
|
||||
.wordCloud__tag :hover {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.wordCloud__home {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
240
src/views/website/searchList/index0.vue
Normal file
240
src/views/website/searchList/index0.vue
Normal file
@ -0,0 +1,240 @@
|
||||
<template>
|
||||
<div class="index">
|
||||
<searchContainer bannerKey="首页>企业库" title="企业库" @handleQuery="handleQuery">
|
||||
<template v-slot>
|
||||
<el-row type="flex" style="padding: 20px 0;">
|
||||
<div style="flex: 1">
|
||||
<div style="position: relative;">
|
||||
<industrySelect @industryChange="industryChange"></industrySelect>
|
||||
<div class="total">
|
||||
共找到
|
||||
<span>{{ state.total }}</span> 家企业
|
||||
</div>
|
||||
<div v-loading="loading">
|
||||
<div class="item" v-for="item in state.list" :key="item.id">
|
||||
<el-row type="flex" style="padding: 40px 20px;">
|
||||
<div class="img">
|
||||
<!-- <img :src="item.image" alt /> -->
|
||||
<img src="https://t7.baidu.com/it/u=1951548898,3927145&fm=193&f=GIF" alt />
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="tit" @click="handleDetail(item.id)">
|
||||
<div style="float: right;">
|
||||
<span>匹配度</span>
|
||||
<el-rate style="display: inline-block" v-model="state.val" disabled></el-rate>
|
||||
</div>
|
||||
<div class="text" style="flex: 1">{{ item.name }}</div>
|
||||
|
||||
</div>
|
||||
<div class="line">
|
||||
企业规模: <span>{{item.kind_title}}</span>
|
||||
</div>
|
||||
<div class="line">
|
||||
核心产品及应用场景: <span>{{item.product}}</span>
|
||||
</div>
|
||||
<div class="line">
|
||||
企业网站: <a :href="item.url"><span>{{item.url}}</span></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="keywords" style="flex: 1">
|
||||
<wordcloud :data="createdData(item.keywords)"></wordcloud>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<pagination
|
||||
class="pagination"
|
||||
:total="state.total"
|
||||
:pageSizes="state.pageSizes"
|
||||
v-model:page="state.pageNum"
|
||||
v-model:limit="state.pageSize"
|
||||
:autoScroll="false"
|
||||
@pagination="getDataList"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="r">1</div>
|
||||
</el-row>
|
||||
</template>
|
||||
</searchContainer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import request from '@/utils/request'
|
||||
const router = useRouter();
|
||||
import { onMounted } from 'vue';
|
||||
import searchContainer from './components/searchContainer.vue'
|
||||
import industrySelect from './components/industrySelect.vue'
|
||||
import wordcloud from './components/wordcloud.vue'
|
||||
|
||||
function handleDetail (id) {
|
||||
let routeData = router.resolve({ path: `/searchList/0/detail/${id}`, query: {keyword: state.keyword}});
|
||||
window.open(routeData.href, '_blank');
|
||||
}
|
||||
|
||||
const loading = ref(true);
|
||||
const state = reactive({
|
||||
pageNum: 1,
|
||||
total: 1,
|
||||
pageSize: 10,
|
||||
pageSizes: [10, 10 << 1, 10 << 2, 10 << 3],
|
||||
keyword: '',
|
||||
industryList: [],
|
||||
id1: '',
|
||||
id2: '',
|
||||
id3: '',
|
||||
val: 3,
|
||||
arr: [{
|
||||
"name": "Cat",
|
||||
"value": 26
|
||||
},
|
||||
{
|
||||
"name": "fish",
|
||||
"value": 19
|
||||
}]
|
||||
});
|
||||
|
||||
function createdData(arr) {
|
||||
let l = [];
|
||||
let snap = JSON.parse(JSON.stringify(arr))
|
||||
snap.map(e=>{
|
||||
l.push({name: e,value: 30})
|
||||
return {name: e,value: 30}
|
||||
})
|
||||
return l;
|
||||
}
|
||||
function search () {
|
||||
let industry = '';
|
||||
if (state.id1) {
|
||||
industry += state.id1;
|
||||
}
|
||||
if (state.id2) {
|
||||
industry += `-${state.id2}`;
|
||||
}
|
||||
if (state.id3) {
|
||||
industry += `-${state.id3}`;
|
||||
}
|
||||
return request({
|
||||
url: '/v1/search',
|
||||
method: 'post',
|
||||
data: { industry, mode: 1, page_num: state.pageNum, page_size: state.pageSize, keyword: state.keyword }
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
function handleQuery (keyword) {
|
||||
state.keyword = keyword;
|
||||
getDataList()
|
||||
}
|
||||
function industryChange (industry) {
|
||||
if (industry.id1) {
|
||||
state.id1 = industry.id1;
|
||||
}
|
||||
if (industry.id2) {
|
||||
state.id2 = industry.id2;
|
||||
}
|
||||
if (industry.id3) {
|
||||
state.id3 = industry.id3;
|
||||
}
|
||||
getDataList()
|
||||
}
|
||||
|
||||
function getDataList () {
|
||||
loading.value = true;
|
||||
search().then(res => {
|
||||
if (200 == res.code) {
|
||||
// 总条数
|
||||
state.total = res.data.count;
|
||||
state.list = res.data.data;
|
||||
loading.value = false;
|
||||
}
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.total {
|
||||
font-size: 16px;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
margin-bottom: 20px;
|
||||
span {
|
||||
font-size: 30px;
|
||||
color: #0054ff;
|
||||
}
|
||||
}
|
||||
|
||||
.r {
|
||||
display: inline-block;
|
||||
width: 325px;
|
||||
margin-left: 14px;
|
||||
min-height: 200px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.item {
|
||||
height: 200px;
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.img {
|
||||
width: 90px;
|
||||
margin-right: 12px;
|
||||
display: flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
img {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
.content {
|
||||
display: inline-block;
|
||||
width: 390px;
|
||||
.line {
|
||||
font-size: 16px;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
color: #666666;
|
||||
margin: 10px 0;
|
||||
span {
|
||||
font-size: 16px;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.keywords {
|
||||
flex: 1;
|
||||
width: 129px;
|
||||
height: 129px;
|
||||
}
|
||||
.tit {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
.text {
|
||||
margin-right: 200px;
|
||||
overflow: hidden;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 20px;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
403
src/views/website/searchList/index0Detail.vue
Normal file
403
src/views/website/searchList/index0Detail.vue
Normal file
@ -0,0 +1,403 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<searchContainer bannerKey="首页>企业库" title="企业库" @handleQuery="handleQuery">
|
||||
<template v-slot>
|
||||
<div class="head">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item>
|
||||
<span class="one">找企业</span>
|
||||
</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>
|
||||
<span>企业详情</span>
|
||||
</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<el-row type="flex">
|
||||
<div style="flex: 1">
|
||||
<div class="item">
|
||||
<el-row type="flex" style="padding: 40px 20px;">
|
||||
<div class="img">
|
||||
<!-- <img :src="state.companyDetail.image" alt /> -->
|
||||
<img
|
||||
src="https://t7.baidu.com/it/u=1951548898,3927145&fm=193&f=GIF"
|
||||
alt
|
||||
/>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="tit">
|
||||
<div style="float: right;">
|
||||
<span>匹配度</span>
|
||||
<el-rate
|
||||
style="display: inline-block"
|
||||
v-model="state.val"
|
||||
disabled
|
||||
></el-rate>
|
||||
</div>
|
||||
<div
|
||||
class="text"
|
||||
style="flex: 1"
|
||||
>{{ state.companyDetail.name }}</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
企业规模:
|
||||
<span>{{ state.companyDetail.introduce }}</span>
|
||||
</div>
|
||||
<div class="line">
|
||||
核心产品及应用场景:
|
||||
<span>{{ state.companyDetail.product }}</span>
|
||||
</div>
|
||||
<div class="line">
|
||||
企业网站:
|
||||
<a :href="state.companyDetail.url">
|
||||
<span>{{ state.companyDetail.url }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="keywords" style="flex: 1">
|
||||
<wordcloud
|
||||
v-if="state.companyDetail.keywords"
|
||||
:data="createdData(state.companyDetail.keywords)"
|
||||
></wordcloud>
|
||||
</div>
|
||||
<div class="btns">
|
||||
<div class="order">预约对接</div>
|
||||
<div class="share">一键分享</div>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<div class="product">
|
||||
<div style="padding: 20px 0;">
|
||||
<div class="pointTit">企业简介</div>
|
||||
</div>
|
||||
<div class="html" v-html="state.companyDetail.introduce"></div>
|
||||
<div style="padding: 20px 0;">
|
||||
<div class="pointTit">生产方向</div>
|
||||
</div>
|
||||
<section v-if="state.companyDetail.directions">
|
||||
<div v-for="item in state.companyDetail.directions" class="describe">{{state.companyDetail.introduce}}</div>
|
||||
|
||||
</section>
|
||||
<div style="padding: 20px 0;">
|
||||
<div class="pointTit">产品列表</div>
|
||||
</div>
|
||||
<section v-for="item in state.companyProduct" :key="item.id">
|
||||
<div style="border: 1px solid #DCDCDC;margin-bottom: 10px;">
|
||||
<productItem :data="item"></productItem>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div style="padding: 20px 0;">
|
||||
<div class="pointTit">企业推荐</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="item" v-for="item in state.list" :key="item.id">
|
||||
<el-row type="flex" style="padding: 40px 20px;">
|
||||
<div class="img">
|
||||
<!-- <img :src="item.image" alt /> -->
|
||||
<img
|
||||
src="https://t7.baidu.com/it/u=1951548898,3927145&fm=193&f=GIF"
|
||||
alt
|
||||
/>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="tit" @click="handleDetail(item.id)">
|
||||
<div style="float: right;">
|
||||
<span>匹配度</span>
|
||||
<el-rate
|
||||
style="display: inline-block"
|
||||
v-model="state.val"
|
||||
disabled
|
||||
></el-rate>
|
||||
</div>
|
||||
<div
|
||||
class="text"
|
||||
style="flex: 1"
|
||||
>{{ item.name.repeat(10) }}</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
企业规模:
|
||||
<span>{{ item.kind_title }}</span>
|
||||
</div>
|
||||
<div class="line">
|
||||
核心产品及应用场景:
|
||||
<span>{{ item.product }}</span>
|
||||
</div>
|
||||
<div class="line">
|
||||
企业网站:
|
||||
<a :href="item.url">
|
||||
<span>{{ item.url }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="keywords" style="flex: 1">
|
||||
<wordcloud :data="createdData(item.keywords)"></wordcloud>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="r">1</div>
|
||||
</el-row>
|
||||
</template>
|
||||
</searchContainer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import request from '@/utils/request'
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
import { onMounted } from 'vue';
|
||||
import searchContainer from './components/searchContainer.vue'
|
||||
import wordcloud from './components/wordcloud.vue'
|
||||
import productItem from './components/productItem.vue'
|
||||
const loading = ref(true);
|
||||
const state = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 4,
|
||||
keyword: '',
|
||||
val: 3,
|
||||
companyDetail: {},
|
||||
companyProduct: [],
|
||||
arr: [{
|
||||
"name": "Cat",
|
||||
"value": 26
|
||||
},
|
||||
{
|
||||
"name": "fish",
|
||||
"value": 19
|
||||
}]
|
||||
});
|
||||
|
||||
// 建议 列表前4条
|
||||
function recommend () {
|
||||
return request({
|
||||
url: '/v1/search',
|
||||
method: 'post',
|
||||
data: { mode: 1, page_num: state.pageNum, page_size: state.pageSize, keyword: state.keyword }
|
||||
})
|
||||
}
|
||||
|
||||
// 公司详情
|
||||
function company (id) {
|
||||
return request({
|
||||
url: '/v1/manage/company',
|
||||
method: 'post',
|
||||
data: { company_id: id }
|
||||
})
|
||||
}
|
||||
function companyProduct (id) {
|
||||
return request({
|
||||
url: '/v1/manage/company/product',
|
||||
method: 'post',
|
||||
data: { company_id: id, page_num: 1, page_size: 10, }
|
||||
})
|
||||
}
|
||||
|
||||
function createdData (arr) {
|
||||
let l = [];
|
||||
let snap = JSON.parse(JSON.stringify(arr))
|
||||
snap.map(e => {
|
||||
l.push({ name: e, value: 30 })
|
||||
return { name: e, value: 30 }
|
||||
})
|
||||
return l;
|
||||
}
|
||||
|
||||
function handleDetail (id) {
|
||||
let routeData = router.resolve({ path: `/searchList/0/detail/${id}`, query: { keyword: state.keyword } });
|
||||
window.open(routeData.href, '_blank');
|
||||
}
|
||||
|
||||
function handleList (mode, keyword) {
|
||||
router.push({ path: `/searchList/${mode}`, query: { keyword } });
|
||||
}
|
||||
|
||||
// 首次加载数据,其后跳转页面
|
||||
let flag = true;
|
||||
|
||||
function handleQuery (keyword) {
|
||||
state.keyword = keyword;
|
||||
if (flag) {
|
||||
getDataList();
|
||||
flag = false;
|
||||
} else {
|
||||
handleList(0, keyword);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getDataList () {
|
||||
loading.value = true;
|
||||
recommend().then(res => {
|
||||
if (200 == res.code) {
|
||||
// 总条数
|
||||
state.total = res.data.count;
|
||||
state.list = res.data.data;
|
||||
}
|
||||
})
|
||||
let id = route.params.id;
|
||||
if (!id) return
|
||||
company(id).then(res => {
|
||||
if (200 == res.code) {
|
||||
state.companyDetail = res.data;
|
||||
loading.value = false;
|
||||
}
|
||||
}).catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
companyProduct(id).then(res => {
|
||||
if (200 == res.code) {
|
||||
state.companyProduct = res.data.data;
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.head {
|
||||
padding: 15px 0px;
|
||||
span {
|
||||
font-size: 16px;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
color: #666666;
|
||||
}
|
||||
.one {
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
.r {
|
||||
display: inline-block;
|
||||
width: 325px;
|
||||
margin-left: 14px;
|
||||
min-height: 200px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.product {
|
||||
width: 661px;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
.describe {
|
||||
font-size: 14px;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
color: #666666;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.pointTit {
|
||||
position: relative;
|
||||
padding-left: 10px;
|
||||
font-size: 16px;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
&:before {
|
||||
content: "";
|
||||
top: 8px;
|
||||
left: 0px;
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background: #0054ff;
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.btns {
|
||||
overflow: hidden;
|
||||
padding-top: 20px;
|
||||
width: 100%;
|
||||
|
||||
div {
|
||||
text-align: center;
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
width: 101px;
|
||||
height: 36px;
|
||||
font-size: 14px;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
line-height: 36px;
|
||||
box-sizing: border-box;
|
||||
&:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
.share {
|
||||
color: #333333;
|
||||
background: #f2f6ff;
|
||||
border: 1px solid #dcdcdc;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.order {
|
||||
background: #0054ff;
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 90px;
|
||||
margin-right: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
img {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
.content {
|
||||
display: inline-block;
|
||||
width: 390px;
|
||||
.line {
|
||||
font-size: 16px;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
color: #666666;
|
||||
margin: 10px 0;
|
||||
span {
|
||||
font-size: 16px;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
.keywords {
|
||||
flex: 1;
|
||||
width: 129px;
|
||||
height: 129px;
|
||||
}
|
||||
.tit {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
.text {
|
||||
margin-right: 200px;
|
||||
overflow: hidden;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 20px;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user