需求列表 产品列表

This commit is contained in:
cxc
2022-09-20 17:31:39 +08:00
parent 5aa377760a
commit 25ed1387a7
47 changed files with 5276 additions and 757 deletions

View File

@ -3,28 +3,37 @@
<el-card shadow="always" style="width: 55%; margin: 0 auto">
<p><b>基本资料</b></p>
<el-form
ref="userInfoFormRef"
:model="userInfoForm"
ref="PersonalInfoFormRef"
:model="PersonalInfoForm"
:rules="rules"
label-width="100px"
>
<el-form-item label="姓名:" prop="nickName">
<el-input v-model="userInfoForm.nickName" placeholder="请输入姓名" />
<el-input
v-model="PersonalInfoForm.nickName"
placeholder="请输入姓名"
/>
</el-form-item>
<el-form-item label="手机:" prop="mobile">
<el-input v-model="userInfoForm.mobile" placeholder="请输入手机号" />
<el-input
v-model="PersonalInfoForm.mobile"
placeholder="请输入手机号"
/>
</el-form-item>
<el-form-item label="邮箱:" prop="email">
<el-input v-model="userInfoForm.email" placeholder="请输入邮箱" />
<el-input v-model="PersonalInfoForm.email" placeholder="请输入邮箱" />
</el-form-item>
<el-form-item label="职务:" prop="post">
<el-input v-model="userInfoForm.post" placeholder="请输入职务" />
<el-input v-model="PersonalInfoForm.post" placeholder="请输入职务" />
</el-form-item>
<el-form-item label="固定电话:" prop="phone">
<el-input v-model="userInfoForm.phone" placeholder="请输入固定电话" />
<el-input
v-model="PersonalInfoForm.phone"
placeholder="请输入固定电话"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitUserInfoForm">提交</el-button>
<el-button type="primary" @click="submitPersonalInfo">提交</el-button>
</el-form-item>
</el-form>
<p><b>企业资料</b></p>
@ -32,7 +41,7 @@
v-model="enterpriseInfoForm"
:isAdd="false"
:labelWidth="labelWidth"
ref="enterpriseInfoFormRef"
ref="enterpriseFormRef"
/>
<div :style="{ marginLeft: labelWidth + 'px' }">
<el-button type="primary" @click="submitEnterpriseForm">提交</el-button>
@ -40,36 +49,40 @@
</el-card>
</div>
</template>
<script setup>
import { expert } from "@/api/identity/index";
<script setup name="BasicInfo">
import { getInfo } from "@/api/login";
import { insertClientUser, updateEnterprise } from "@/api/enterprise";
// import { expert } from "@/api/identity/index";
import EnterpriseForm from "@/views/components/EnterpriseForm";
import { ElMessage } from "element-plus";
import { useRouter } from "vue-router";
const router = useRouter();
const data = reactive({
enterpriseInfoForm: {},
userInfoForm: {},
formData: {},
queryParams: {
pageNum: 1,
pageSize: 10,
postCode: undefined,
PersonalInfoForm: {}, // 个人基本资料
enterpriseInfoForm: {
// laboratory_id: undefined, // 所属实验室
// gender: 1,
},
// queryParams: {
// pageNum: 1,
// pageSize: 10,
// postCode: undefined,
// },
rules: {
nickName: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
phone: [{ required: true, message: "电话号码不能为空", trigger: "blur" }],
mobile: [{ required: true, message: "手机号码不能为空", trigger: "blur" }],
email: [{ required: true, message: "电子邮箱不能为空", trigger: "blur" }],
post: [{ required: true, message: "职务不能为空", trigger: "blur" }],
name: [{ required: true, message: "公司名称不能为空", trigger: "blur" }],
dutyParagraph: [
{ required: true, message: "公司税号不能为空", trigger: "blur" },
],
bank: [{ required: true, message: "开户行不能为空", trigger: "blur" }],
bankAccount: [
{ required: true, message: "开户行账号不能为空", trigger: "blur" },
],
bankPhone: [
{ required: true, message: "开户行电话不能为空", trigger: "blur" },
],
email: [{ required: true, message: "电子邮箱不能为空", trigger: "blur" }],
phone: [{ required: true, message: "联系电话不能为空", trigger: "blur" }],
address: [{ required: true, message: "地址不能为空", trigger: "blur" }],
username: [{ required: true, message: "联系人不能为空", trigger: "blur" }],
userPhone: [
@ -81,61 +94,46 @@ const data = reactive({
},
});
const { queryParams, formData, rules, enterpriseInfoForm, userInfoForm } =
toRefs(data);
const { PersonalInfoForm, rules, enterpriseInfoForm } = toRefs(data);
const { proxy } = getCurrentInstance();
const labelWidth = 140;
const form = reactive({
laboratory_id: undefined, // 所属实验室
gender: 1,
});
// let enterpriseInfoForm = ref({});
// 获取基础信息用于回显
const getBasicInfo = async () => {
const { data } = await getInfo();
// formData.value = data.enterprise;
userInfoForm.value = data.user;
enterpriseInfoForm.value = data.enterprise;
PersonalInfoForm.value = data.user ?? {};
enterpriseInfoForm.value = data.enterprise ?? {};
};
// 更新个人信息
const userInfoFormRef = ref();
const submitUserInfoForm = async () => {
await userInfoFormRef.value.validate();
const enterpriseFormRef = ref(null);
const PersonalInfoFormRef = ref(null);
const submitPersonalInfo = async () => {
try {
await insertClientUser(userInfoForm.value);
getBasicInfo();
ElMessage.success("更新基本信息成功");
await PersonalInfoFormRef.value.validate();
await insertClientUser(PersonalInfoForm.value);
ElMessage.success("更新个人信息成功");
const { data } = await getInfo();
PersonalInfoForm.value = data.user ?? {};
} catch (error) {
ElMessage.error("更新基本信息失败");
console.log(error);
}
};
// 更新企业信息
const enterpriseInfoFormRef = ref();
const submitEnterpriseForm = async () => {
const valid = await enterpriseInfoFormRef.value.validateForm();
if (valid) {
try {
const submitEnterpriseForm = async (status) => {
const enterpriseFormValid = await enterpriseFormRef.value.validateForm();
PersonalInfoFormRef.value.validate(async (valid) => {
if (enterpriseFormValid && valid) {
await updateEnterprise(enterpriseInfoForm.value);
getBasicInfo();
ElMessage.success("更新企业信息成功");
} catch (error) {
ElMessage.error("更新企业信息失败");
const { data } = await getInfo();
enterpriseInfoForm.value = data.enterprise ?? {};
} else {
console.log("校验未通过");
}
} else {
console.log("校验未通过");
}
});
};
// function submitForm(status) {
// if (proxy.$refs.expertForm.submitForm()) {
// expert(form).then((res) => {
// proxy.$modal.msgSuccess("新增成功");
// proxy.$router.go(-1);
// });
// } else {
// console.log("校验未通过");
// }
// }
getBasicInfo();
</script>

View File

@ -0,0 +1 @@
<template></template>

View File

@ -0,0 +1 @@
<template></template>

View File

@ -0,0 +1,129 @@
<template>
<div class="app-container">
<el-form
:model="queryParams"
ref="queryRef"
v-show="showSearch"
:inline="true"
>
<el-form-item label="活动名称" prop="title">
<el-input
v-model="queryParams.title"
placeholder="请输入活动名称"
clearable
style="width: 240px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="活动状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择">
<el-option label="显示" value="1"></el-option>
<el-option label="隐藏" value="2"></el-option>
<!-- <el-option label="已结束" value="3"></el-option> -->
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"
>搜索</el-button
>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<!-- 表格数据 -->
<el-table v-loading="loading" :data="dataList">
<el-table-column label="数据编号" prop="id" />
<el-table-column
label="活动名称"
prop="title"
:show-overflow-tooltip="true"
/>
<el-table-column
label="活动报名截止时间"
align="center"
prop="createTime"
>
<template #default="{ row }">
<span>{{ parseTime(row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="活动开始时间" align="center" prop="createTime">
<template #default="{ row }">
<span>{{ parseTime(row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="活动结束时间" align="center" prop="createTime">
<template #default="{ row }">
<span>{{ parseTime(row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="活动报名时间" align="center" prop="createTime">
<template #default="{ row }">
<span>{{ parseTime(row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="status">
<template #default="{ row }">
<el-tag type="success" v-if="row.status == 1">显示</el-tag>
<el-tag type="danger" v-else-if="row.status == 2">隐藏</el-tag>
<el-tag type="info" v-else>未知</el-tag>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script setup>
import { activitysList } from "@/api/enterprise";
const dataList = ref([]);
const loading = ref(true);
const showSearch = ref(true);
const total = ref(0);
const queryRef = ref();
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
title: undefined,
status: undefined,
},
});
const { queryParams } = toRefs(data);
/** 查询数据列表 */
const getList = async () => {
loading.value = true;
const resp = await activitysList(queryParams.value);
dataList.value = resp.rows;
total.value = resp.total;
loading.value = false;
};
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
if (queryRef.value) {
queryRef.value.resetFields();
handleQuery();
}
}
getList();
</script>

View File

@ -0,0 +1,202 @@
<template>
<div class="app-container">
<el-card shadow="always" style="width: 55%; margin: 0 auto">
<el-form
ref="formRef"
:model="form"
:rules="rules"
:label-width="labelWidth + 'px'"
>
<p><b>基本信息</b></p>
<el-row>
<el-col :span="24">
<el-form-item label="需求名称:" prop="title">
<el-input v-model="form.title"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="需求类别:">
<el-checkbox-group v-model="form.kinds">
<el-checkbox
v-for="item in checkList"
:key="item.id"
:label="item.name"
>{{ item.name }}</el-checkbox
>
<!-- <el-checkbox label="0" @change="handleCheck">其他</el-checkbox> -->
</el-checkbox-group>
<el-row :gutter="20">
<el-col :span="20">
<el-input
v-model="checkInput"
placeholder="请输入需求类别"
></el-input>
</el-col>
<el-col :span="4">
<el-button type="primary" @click="addCheck">添加</el-button>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="需求描述:" prop="description">
<!-- <Editor v-model="form.description" :minHeight="150" /> -->
<wangEditor
v-model="form.description"
width="100%"
min-height="150px"
></wangEditor>
</el-form-item>
</el-col>
</el-row>
<CityOptions
v-model="form"
:labelWidth="labelWidth"
ref="cityFormRef"
/>
<el-row>
<el-col :span="12">
<el-form-item label="需求联系人:" prop="name">
<el-input
v-model="form.name"
placeholder="请输入需求联系人"
></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系人手机号:" prop="mobile">
<el-input
v-model="form.mobile"
placeholder="请输入联系人手机号"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="需求提交人:" prop="commitUserName">
<el-input
v-model="form.commitUserName"
placeholder="请输入需求提交人"
></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="需求提交人手机号:" prop="commitPhone">
<el-input
v-model="form.commitPhone"
placeholder="需求提交人手机号"
></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div :style="{ marginLeft: labelWidth + 'px' }">
<el-button @click="$router.go(-1)">取消</el-button>
<el-button type="primary" @click="submitForm">提交</el-button>
</div>
</el-card>
</div>
</template>
<script setup>
import { insertDemand } from "@/api/enterprise";
import CityOptions from "@/views/components/CityOptions";
import { ElMessage } from "element-plus";
import { onActivated } from "vue";
import { useRouter } from "vue-router";
const router = useRouter();
const data = reactive({
form: {
check: [],
},
queryParams: {
pageNum: 1,
pageSize: 10,
postCode: undefined,
},
rules: {
title: [{ required: true, message: "需求名称不能为空", trigger: "blur" }],
description: [
{ required: true, message: "需求描述不能为空", trigger: "blur" },
],
name: [{ required: true, message: "需求联系人不能为空", trigger: "blur" }],
mobile: [
{ required: true, message: "联系人手机号不能为空", trigger: "blur" },
],
username: [
{ required: true, message: "需求提交人不能为空", trigger: "blur" },
],
userPhone: [{ required: true, message: "手机号不能为空", trigger: "blur" }],
},
});
const { form, rules } = toRefs(data);
const labelWidth = 140;
const checkList = reactive([
{
id: 1,
name: "成果推广",
},
{
id: 2,
name: "关键成果解决",
},
{
id: 3,
name: "对接专家院士",
},
{
id: 4,
name: "上市辅导",
},
]);
const checkInput = ref("");
const cityFormRef = ref();
const formRef = ref();
const submitForm = () => {
formRef.value.validate(async (valid) => {
const cityFormValid = cityFormRef.value.validateForm(); // 城市
if (valid && cityFormValid) {
console.log(form.value);
if (form.value.id != undefined) {
// updatePost(form.value).then((response) => {
// proxy.$modal.msgSuccess("修改成功");
// proxy.$router.go(-1);
// });
} else {
await insertDemand(form.value);
ElMessage.success("新增服务需求成功");
router.go(-1);
}
}
});
};
// 添加需求类别时验证
function addCheck() {
if (!checkInput.value.trim().length) return ElMessage.error("请输入");
const flag = checkList.some((item) => {
return item.name.trim() == checkInput.value.trim();
});
if (!flag) {
checkList.push({
id: checkList.length + 1,
name: checkInput.value,
});
checkInput.value = "";
}
}
onActivated(() => {});
</script>

View File

@ -0,0 +1,296 @@
<template>
<div class="app-container">
<el-card shadow="always" style="width: 55%; margin: 0 auto">
<el-form
ref="formRef"
:model="form"
:rules="rules"
:label-width="labelWidth + 'px'"
>
<p><b>基本信息</b></p>
<el-row>
<el-col :span="24">
<el-form-item label="成果需求名称:" prop="title">
<el-input v-model="form.title"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="需求类别:">
<el-checkbox-group v-model="form.kinds">
<el-checkbox
v-for="item in checkList"
:key="item.id"
:label="item.name"
>{{ item.name }}</el-checkbox
>
<!-- <el-checkbox label="0" @change="handleCheck">其他</el-checkbox> -->
</el-checkbox-group>
<el-row :gutter="20">
<el-col :span="20">
<el-input
v-model="checkInput"
placeholder="请输入需求类别"
></el-input>
</el-col>
<el-col :span="4">
<el-button type="primary" @click="addCheck">添加</el-button>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="需求描述:" prop="introduce">
<!-- <Editor v-model="form.add" :minHeight="150" /> -->
<wangEditor
v-model="form.introduce"
width="100%"
min-height="150px"
></wangEditor>
</el-form-item>
</el-col>
</el-row>
<!-- <CityOptions
v-model="form"
:labelWidth="labelWidth"
ref="cityForm"
/> -->
<FieldOptions
v-model="form"
:labelWidth="labelWidth"
ref="fieldFormRef"
/>
<el-row>
<el-col :span="12">
<el-form-item
label="成果需求预算:"
:prop="form.budgetMode == 1 ? 'budget' : ''"
>
<el-input
v-model="form.budget"
oninput="value=value.replace(/[^\d.]/g, '').replace(/\.{2,}/g, '.').replace('.', '$#$').replace(/\./g, '').replace('$#$', '.').replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3').replace(/^\./g, '')"
placeholder="请输入技术需求预算"
>
<template #append>万元</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label-width="50px">
<el-checkbox
false-label="1"
true-label="2"
v-model="form.budgetMode"
>面议</el-checkbox
>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="截止时间:" prop="deadline">
<el-date-picker
style="width: 100%"
v-model="form.deadline"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择截止时间"
>
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="需求联系人:" prop="name">
<el-input
v-model="form.name"
placeholder="请输入需求联系人"
></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系人手机号:" prop="mobile">
<el-input
v-model="form.mobile"
placeholder="请输入联系人手机号"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="需求提交人:" prop="commitUserName">
<el-input
v-model="form.commitUserName"
placeholder="请输入需求提交人"
></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="需求提交人手机号:" prop="commitUserPhone">
<el-input
v-model="form.commitUserPhone"
placeholder="请输入需求提交人手机号"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<InputBoxAdd
:labelWidth="labelWidth"
v-model="form"
title="想合作的单位及模式"
placeholder=""
fieldKey="wants"
ref="directionsFormRef"
/>
</el-col>
</el-row>
</el-form>
<div :style="{ marginLeft: labelWidth + 'px' }">
<el-button @click="router.go(-1)">取消</el-button>
<el-button type="primary" @click="submitForm">提交</el-button>
</div>
</el-card>
</div>
</template>
<script setup>
// import { expert } from "@/api/identity/index";
import { insertTechnologyDemand } from "@/api/enterprise";
import CityOptions from "@/views/components/CityOptions";
import FieldOptions from "@/views/components/FieldOptions";
import InputBoxAdd from "@/views/components/InputBoxAdd";
import { ElMessage } from "element-plus";
import { useRouter } from "vue-router";
const router = useRouter();
const data = reactive({
form: {
check: [],
},
queryParams: {
pageNum: 1,
pageSize: 10,
postCode: undefined,
},
rules: {
title: [{ required: true, message: "需求名称不能为空", trigger: "blur" }],
introduce: [
{ required: true, message: "需求描述不能为空", trigger: "blur" },
],
name: [{ required: true, message: "需求联系人不能为空", trigger: "blur" }],
mobile: [
{ required: true, message: "联系人手机号不能为空", trigger: "blur" },
],
commitUserName: [
{ required: true, message: "需求提交人不能为空", trigger: "blur" },
],
budget: [{ required: true, message: "需求预算不能为空", trigger: "blur" }],
deadline: [
{
required: true,
message: "请选择截止时间",
trigger: ["change", "blur"],
},
],
commitUserPhone: [
{ required: true, message: "需求提交人手机号不能为空", trigger: "blur" },
],
},
});
const { queryParams, form, rules } = toRefs(data);
const { proxy } = getCurrentInstance();
const labelWidth = 160;
// const isContainOther = ref(false);
const checkList = reactive([
{
id: 1,
name: "成果推广",
},
{
id: 2,
name: "关键成果解决",
},
{
id: 3,
name: "对接专家院士",
},
{
id: 4,
name: "上市辅导",
},
]);
const formRef = ref(null);
const fieldFormRef = ref(null);
const directionsFormRef = ref(null);
const checkInput = ref("");
const submitForm = async () => {
// await formRef.value.validate();
let formValid;
try {
formValid = await formRef.value.validate();
} catch (error) {
formValid = false;
}
const fieldFormValid = await fieldFormRef.value.validateForm();
const directionsFormValid = await directionsFormRef.value.validateForm();
if (formValid && fieldFormValid && directionsFormValid) {
await insertTechnologyDemand(form.value);
ElMessage.success("新增企业需求成功");
router.go(-1);
} else {
console.log("校验未通过");
}
// formRef.value.validate(async (valid) => {
// // console.log(valid);
// if (valid) {
// form.value.amount = form.value.amount - 0;
// }
// form.value.amount = form.value.amount - 0;
// const cityForm = proxy.$refs.cityForm.submitForm(); // 城市
// if (valid && cityForm) {
// console.log(form.value);
// if (form.value.id != undefined) {
// // updatePost(form.value).then((response) => {
// // proxy.$modal.msgSuccess("修改成功");
// // proxy.$router.go(-1);
// // });
// } else {
// // addPost(form.value).then((response) => {
// // proxy.$modal.msgSuccess("新增成功");
// // proxy.$router.go(-1);
// // });
// }
// }
// });
};
function addCheck() {
if (!checkInput.value.trim().length) return proxy.$modal.msgError("请输入");
const flag = checkList.some((item) => {
return item.name.trim() == checkInput.value.trim();
});
if (!flag) {
checkList.push({
id: checkList.length + 1,
name: checkInput.value,
});
checkInput.value = "";
}
}
</script>

View File

@ -0,0 +1 @@
<template></template>

View File

@ -2,8 +2,8 @@
<div class="app-container">
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<router-link to="./release">
<el-button type="primary" size="mini">发布需求</el-button>
<router-link to="./releaseService">
<el-button type="primary" size="small">发布需求</el-button>
</router-link>
</el-col>
<right-toolbar
@ -13,8 +13,8 @@
</el-row>
<el-radio-group
v-model="queryParams.type"
size="mini"
v-model="queryParams.status"
size="small"
@change="handleQuery"
>
<el-radio-button :label="1">待受理</el-radio-button>
@ -22,20 +22,20 @@
<el-radio-button :label="3">已结束</el-radio-button>
</el-radio-group>
<el-table v-loading="loading" :data="postList" style="margin-top: 20px">
<el-table-column label="需求名称" align="center" prop="postCode" />
<el-table-column label="需求类别" align="center" prop="postSort" />
<el-table v-loading="loading" :data="dataList" style="margin-top: 20px">
<el-table-column label="需求名称" align="center" prop="title" />
<el-table-column label="需求类别" align="center" prop="kind" />
<el-table-column label="状态" align="center" prop="status" />
<el-table-column label="联系人" align="center" prop="status" />
<el-table-column label="手机号" align="center" prop="status" />
<el-table-column label="联系人" align="center" prop="name" />
<el-table-column label="手机号" align="center" prop="mobile" />
<el-table-column
label="发布时间"
align="center"
prop="createTime"
width="180"
>
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
<template #default="{ row }">
<span>{{ parseTime(row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
@ -46,7 +46,7 @@
<template #default="scope">
<el-button
v-if="queryParams.type == 3"
size="mini"
size="small"
type="text"
icon="Delete"
@click="handleDelete(scope.row.id)"
@ -54,7 +54,7 @@
>
<el-button
v-if="queryParams.type == 1"
size="mini"
size="small"
type="text"
icon="Close"
@click="handleDelete(scope.row.id)"
@ -62,7 +62,7 @@
>
<el-button
v-if="queryParams.type != 3"
size="mini"
size="small"
type="text"
icon="View"
@click="handleEdit(scope.row.id)"
@ -83,18 +83,14 @@
</template>
<script setup>
import {
demand,
demandAdd,
demandEdit,
demandDetail,
demandDelete,
} from "@/api/admin/expert/demand";
import { demandList } from "@/api/enterprise";
import { onActivated } from "vue";
import { useRouter } from "vue-router";
const { proxy } = getCurrentInstance();
const router = useRouter();
const postList = ref([]);
const dataList = ref([]);
const loading = ref(true);
const showSearch = ref(true);
const total = ref(0);
@ -103,9 +99,9 @@ const dateRange = ref([]);
const data = reactive({
form: {},
queryParams: {
page_num: 1,
page_size: 10,
type: 1,
pageNum: 1,
pageSize: 10,
status: 1,
},
rules: {
name: [{ required: true, message: "公司名称不能为空", trigger: "blur" }],
@ -135,18 +131,13 @@ const data = reactive({
const { queryParams, form, rules } = toRefs(data);
/** 查询列表 */
function getList() {
const getList = async () => {
loading.value = true;
postList.value = [1];
total.value = 15;
const resp = await demandList(queryParams.value);
dataList.value = resp.rows;
total.value = resp.total;
loading.value = false;
// demand(queryParams.value).then((response) => {
// console.log(response);
// // postList.value = response.data.data;
// // total.value = response.data.count;
// loading.value = false;
// });
}
};
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
@ -175,4 +166,7 @@ function handleEdit(id) {
router.push({ path: "./release", query: { id } });
}
getList();
onActivated(() => {
getList();
});
</script>

View File

@ -0,0 +1,195 @@
<template>
<div class="app-container">
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<router-link to="./releaseTechnology">
<el-button type="primary" size="small">发布需求</el-button>
</router-link>
</el-col>
</el-row>
<el-radio-group
v-model="queryParams.status"
size="small"
@change="handleQuery"
>
<el-radio-button :label="1">已发布</el-radio-button>
<el-radio-button :label="0">待审核</el-radio-button>
<el-radio-button :label="2">已驳回</el-radio-button>
<el-radio-button :label="3">草稿箱</el-radio-button>
</el-radio-group>
<el-table v-loading="loading" :data="dataList" style="margin-top: 20px">
<el-table-column label="数据编号" prop="id" align="center" />
<el-table-column label="需求名称" prop="title" align="center" />
<el-table-column label="所属领域" prop="industryStr" align="center" />
<el-table-column label="联系人" prop="name" align="center" />
<el-table-column label="手机号" prop="mobile" align="center" />
<!-- <el-table-column label="浏览量" prop="visit_count" align="center" /> -->
<el-table-column
label="发布时间"
prop="createTime"
align="center"
width="180"
>
<template #default="{ row }">
<span>{{ parseTime(row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="截止时间"
prop="deadline"
align="center"
width="180"
>
<template #default="{ row }">
<span>{{ parseTime(row.deadline) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
class-name="small-padding fixed-width"
align="center"
>
<template #default="{ row }">
<router-link
:to="{ path: './released', query: { id: row.id } }"
v-if="queryParams.status == 0"
>
<el-button size="small" type="text" icon="Edit">编辑</el-button>
</router-link>
<el-button
v-if="queryParams.status != 1"
size="small"
type="text"
icon="Delete"
@click="handleDelete(scope.row.id)"
>删除</el-button
>
<el-button
v-if="queryParams.status == 2"
size="small"
type="text"
icon="View"
@click="handleResults(scope.row.id)"
>查看匹配结果</el-button
>
<el-button
v-if="queryParams.status == 1"
size="small"
type="text"
icon="Close"
>取消发布</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script setup name="technologyDemand">
import { technologyDemandList } from "@/api/enterprise";
import { ElMessage, ElMessageBox } from "element-plus";
import { useRouter } from "vue-router";
const { proxy } = getCurrentInstance();
const router = useRouter();
const dataList = ref([]); // 企业技术需求列表
const loading = ref(true);
// const showSearch = ref(true);
const total = ref(0);
// const dateRange = ref([]);
const data = reactive({
// form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
status: 1,
},
// rules: {
// name: [{ required: true, message: "公司名称不能为空", trigger: "blur" }],
// dutyParagraph: [
// { required: true, message: "公司税号不能为空", trigger: "blur" },
// ],
// bank: [{ required: true, message: "开户行不能为空", trigger: "blur" }],
// bankAccount: [
// { required: true, message: "开户行账号不能为空", trigger: "blur" },
// ],
// bankPhone: [
// { required: true, message: "开户行电话不能为空", trigger: "blur" },
// ],
// email: [{ required: true, message: "电子邮箱不能为空", trigger: "blur" }],
// phone: [{ required: true, message: "联系电话不能为空", trigger: "blur" }],
// address: [{ required: true, message: "地址不能为空", trigger: "blur" }],
// username: [{ required: true, message: "联系人不能为空", trigger: "blur" }],
// userPhone: [
// { required: true, message: "联系人电话不能为空", trigger: "blur" },
// ],
// userAddress: [
// { required: true, message: "邮寄地址不能为空", trigger: "blur" },
// ],
// },
});
const { queryParams, form, rules } = toRefs(data);
/** 查询列表 */
const getList = async () => {
loading.value = true;
const resp = await technologyDemandList(queryParams.value);
dataList.value = resp.rows;
total.value = resp.total;
loading.value = false;
};
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
// function resetQuery() {
// dateRange.value = [];
// proxy.resetForm("queryRef");
// handleQuery();
// }
/** 删除按钮操作 */
function handleDelete(id) {
ElMessageBox.confirm('是否确认删除数据编号为"' + id + '"的需求项?')
.then(function () {
return achievementDelete({ id });
})
.then(() => {
getList();
ElMessage.success("删除成功");
})
.catch(() => {});
}
function handleShelf(row) {
let text = row.shelf_status == 2 ? "上架" : "下架";
ElMessageBox.confirm('确认要"' + text + '""' + row.id + '"的需求吗?')
.then(function () {
let status = row.shelf_status == 1 ? 2 : 1;
return achievementShelf({ id: row.id, status });
})
.then(() => {
getList();
ElMessage.success(text + "成功");
})
.catch(() => {});
}
function handleResults(id) {
router.push({ path: "./results" });
}
getList();
</script>

View File

@ -1,173 +1 @@
<template>
<div class="app-container">
<div v-loading="loading">
<div class="item" v-for="item in dataList" :key="item.id">
<div style="margin: 10px 0 10px 0">浏览时间2022-02-02 22:00:00</div>
<el-row type="flex" style="justify-content: space-between">
<div style="display: flex">
<div class="img">
<img :src="item.image" alt />
</div>
<div class="content">
<div class="tit" @click="handleDetail(item.id)">
<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>
<div class="keywords">
<wordcloud :data="createdData(item.keywords)"></wordcloud>
</div>
</el-row>
<el-divider border-style="dashed"></el-divider>
</div>
</div>
</div>
</template>
<script setup>
import wordcloud from "@/views/admin/components/wordcloud.vue";
const dataList = ref([]);
const loading = ref(true);
const total = ref(0);
const data = reactive({
queryParams: {
pageNum: 1,
pageSize: 10,
postCode: undefined,
type: "1",
},
});
const { queryParams } = toRefs(data);
const router = useRouter();
/** 查询列表 */
function getList() {
loading.value = true;
dataList.value = [
{
id: "E8MnaAkwDj1X",
kind: 103,
name: "熊",
image:
"http://192.168.0.149:8000/upload/20220221/5b3fe85e89eea53535783ccbd7905c80.jpg",
product: "核心成果核心产品",
url: "",
industrys: ["农、林、牧、渔业/农业/测试名称", "采矿业/煤炭开采和洗选业"],
keywords: ["关键词1", "关键词2"],
},
{
id: "6bPKVW8aZzXo",
kind: 103,
name: "单位名称",
image:
"http://192.168.0.149:8000/upload/20220222/4bad3f051b8f08d651ff8835fb785e46.jpg",
product: "核心成果核心产品",
url: "",
industrys: [
"农、林、牧、渔业/农业/测试名称",
"采矿业/石油和天然气开采业",
],
keywords: ["关键词1", "关键词2"],
},
];
total.value = 15;
loading.value = false;
// loading.value = true;
// listPost(queryParams.value).then(
// (response) => {
// postList.value = response.rows;
// total.value = response.total;
// loading.value = false;
// }
// );
}
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: null },
});
window.open(routeData.href, "_blank");
}
getList();
</script>
<style lang="scss" scoped>
.item {
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>
<template></template>

View File

@ -13,13 +13,13 @@
size="small"
@change="handleQuery"
>
<el-radio-button label="1">已发布</el-radio-button>
<el-radio-button label="0">待审核</el-radio-button>
<el-radio-button label="2">已驳回</el-radio-button>
<el-radio-button label="3">草稿箱</el-radio-button>
<el-radio-button :label="0">待审核</el-radio-button>
<el-radio-button :label="1">已发布</el-radio-button>
<el-radio-button :label="2">已驳回</el-radio-button>
<el-radio-button :label="3">草稿箱</el-radio-button>
</el-radio-group>
<el-table v-loading="loading" :data="productList" style="margin-top: 20px">
<el-table v-loading="loading" :data="dataList" style="margin-top: 20px">
<el-table-column label="数据编号" prop="id" />
<el-table-column label="产品名称" prop="title" />
<el-table-column label="产品领域" prop="industryStr" />
@ -33,13 +33,13 @@
<template #default="{ row }">
<router-link
:to="{ path: './release', query: { id: row.id } }"
v-if="queryParams.status == 0"
v-if="queryParams.status == 3"
>
<el-button size="small" type="text" icon="Edit">编辑</el-button>
</router-link>
<el-button
v-if="queryParams.status == 2"
v-if="queryParams.status == 1"
size="small"
type="text"
icon="Download"
@ -55,7 +55,7 @@
>删除</el-button
>
<el-button
v-if="queryParams.status == 2"
v-if="queryParams.status == 1"
size="small"
type="text"
icon="View"
@ -63,15 +63,15 @@
>查看匹配结果</el-button
>
<el-button
v-if="queryParams.status == 2"
v-if="queryParams.status == 1"
size="small"
type="text"
icon="View"
@click="handlePages(row.id)"
@click="checkEnterpriseInfo(row.id)"
>浏览企业信息</el-button
>
<el-button
v-if="queryParams.status == 1"
v-if="queryParams.status == 0"
size="small"
type="text"
icon="Close"
@ -92,110 +92,75 @@
</template>
<script setup name="Product">
// import {
// expertAchievement,
// achievementShelf,
// achievementDelete,
// } from "@/api/admin/expert/technology";
import { getEnterpriseProduct } from "@/api/enterprise";
import { ElMessage, ElMessageBox } from "element-plus";
import { useRouter } from "vue-router";
const { proxy } = getCurrentInstance();
const router = useRouter();
const productList = ref([]);
const dataList = ref([]);
const loading = ref(true);
const showSearch = ref(true);
const total = ref(0);
const dateRange = ref([]);
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
status: "0",
},
rules: {
name: [{ required: true, message: "公司名称不能为空", trigger: "blur" }],
dutyParagraph: [
{ required: true, message: "公司税号不能为空", trigger: "blur" },
],
bank: [{ required: true, message: "开户行不能为空", trigger: "blur" }],
bankAccount: [
{ required: true, message: "开户行账号不能为空", trigger: "blur" },
],
bankPhone: [
{ required: true, message: "开户行电话不能为空", trigger: "blur" },
],
email: [{ required: true, message: "电子邮箱不能为空", trigger: "blur" }],
phone: [{ required: true, message: "联系电话不能为空", trigger: "blur" }],
address: [{ required: true, message: "地址不能为空", trigger: "blur" }],
username: [{ required: true, message: "联系人不能为空", trigger: "blur" }],
userPhone: [
{ required: true, message: "联系人电话不能为空", trigger: "blur" },
],
userAddress: [
{ required: true, message: "邮寄地址不能为空", trigger: "blur" },
],
status: 0, // 状态(0-待审核1-通过2-驳回3-草稿)
},
});
const { queryParams, form, rules } = toRefs(data);
const { queryParams } = toRefs(data);
/** 查询列表 */
const getList = async () => {
loading.value = true;
const resp = await getEnterpriseProduct(queryParams.value);
productList.value = resp.rows;
dataList.value = resp.rows;
total.value = resp.total;
loading.value = false;
};
// 处理删除
const handleDelete = (id) => {
ElMessageBox.confirm('是否确认删除数据编号为"' + id + '"的产品项?')
.then(async () => {
// delete product
//await deleteProduct(id);
// ElMessage.success("删除成功");
})
.catch((error) => {
console.log("已取消");
});
};
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
dateRange.value = [];
proxy.resetForm("queryRef");
handleQuery();
}
/** 删除按钮操作 */
function handleDelete(id) {
proxy.$modal
.confirm('是否确认删除数据编号为"' + id + '"的产品项?')
.then(function () {
return achievementDelete({ id });
})
.then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
})
.catch(() => {});
}
function handleShelf(row) {
// 下架和上架
const handleShelf = (row) => {
let text = row.shelf_status == 2 ? "上架" : "下架";
proxy.$modal
.confirm('确认要"' + text + '""' + row.id + '"的产品吗?')
ElMessageBox.confirm('确认要"' + text + '""' + row.id + '"的产品吗?')
.then(function () {
let status = row.shelf_status == 1 ? 2 : 1;
return achievementShelf({ id: row.id, status });
// return achievementShelf({ id: row.id, status });
})
.then(() => {
getList();
proxy.$modal.msgSuccess(text + "成功");
ElMessage.success(text + "成功");
})
.catch(() => {});
}
function handleResults(id) {
};
const handleResults = (id) => {
router.push({ path: "./results" });
}
function handlePages(id) {
};
const checkEnterpriseInfo = (id) => {
router.push({ path: "./business" });
}
// console.log(route);
};
getList();
</script>

View File

@ -8,40 +8,47 @@
ref="releaseFormRef"
/>
<div :style="{ marginLeft: labelWidth + 'px' }">
<el-button type="primary" @click="submitForm('0')">保存草稿</el-button>
<el-button type="primary" @click="submitForm('1')">提交审核</el-button>
<el-button type="primary" @click="submitForm(3)">保存草稿</el-button>
<el-button type="primary" @click="submitForm(0)">提交审核</el-button>
</div>
</el-card>
</div>
</template>
<script setup>
import { insertEnterpriseProduct } from "@/api/enterprise";
<script setup name="ReleaseProduct">
import ReleaseForm from "@/views/components/ReleaseForm";
import { ElMessage } from "element-plus";
import { useRoute, useRouter } from "vue-router";
import ReleaseForm from "../components/ReleaseForm";
import { getProductById } from "@/api/enterprise";
import { getProductById, insertEnterpriseProduct } from "@/api/enterprise";
import { reactive, toRefs } from "vue";
const route = useRoute();
const labelWidth = 140;
const form = reactive({});
const router = useRouter();
const labelWidth = 140;
// const = reactive({});
const data = reactive({
form: {},
});
const { form } = toRefs(data);
const releaseFormRef = ref();
const submitForm = async (status) => {
form.status = status;
const valid = await releaseFormRef.value.validateForm();
if (valid) {
await insertEnterpriseProduct(form);
const submitForm = async (is_submit) => {
form.value["status"] = is_submit;
console.log(await releaseFormRef.value.validateForm());
const isValid = await releaseFormRef.value.validateForm();
if (isValid) {
await insertEnterpriseProduct(form.value);
ElMessage.success("新增产品成功");
router.go(-1);
} else {
console.log("验未通过");
console.log("验未通过");
}
};
// 如果url参数包含id 则为修改,请求数据回显
const getProductDetail = async (id) => {
const { data } = await getProductById({ id });
form.value = data;
};
if (route.query.id) {
getProductById({ id: route.query.id }).then((resp) => {
console.log(resp);
});
// console.log(route.query.id);
// queryParams.value.id = route.query.id;
getProductDetail(route.query.id);
}
</script>

View File

@ -1,222 +1 @@
<template>
<div class="app-container">
<el-radio-group
v-model="queryParams.type"
size="mini"
@change="handleQuery"
>
<el-radio-button label="1">成果</el-radio-button>
<el-radio-button label="2">专利</el-radio-button>
<el-radio-button label="3">专家</el-radio-button>
<el-radio-button label="4">实验室</el-radio-button>
<el-radio-button label="5">企业</el-radio-button>
</el-radio-group>
<!-- <el-row :gutter="20">
<el-col
:xs="12"
:sm="6"
:lg="4"
style="margin-top: 20px"
v-for="item in 10"
:key="item"
>
<div style="border: 1px solid #787878">
<div style="text-align: right">
<el-tag type="warning" effect="dark" style="border-radius: 0">
7.8万
</el-tag>
</div>
<div style="padding: 10px">
<div class="ellipsis">
高碳当量高强度灰铁材质研发高碳当量高强度灰铁材质研发
</div>
<div
style="
margin: 10px 0;
display: flex;
justify-content: space-between;
"
>
<el-tag type="info" effect="plain">所属领域</el-tag>
<el-tag type="info" effect="plain">普通企业需求</el-tag>
</div>
<div style="margin-bottom: 10px">研发类型:</div>
<div>截止时间:</div>
</div>
<div class="btn_info pointer">查看详情</div>
</div>
</el-col>
</el-row> -->
<div style="margin-top: 20px" v-loading="loading">
<section v-for="item in postList" :key="item.id">
<div style="border: 1px solid #dcdcdc; margin-bottom: 10px">
<gainItem :data="item"></gainItem>
</div>
</section>
</div>
<!-- <pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/> -->
</div>
</template>
<script setup name="Post">
import {
listPost,
addPost,
delPost,
getPost,
updatePost,
} from "@/api/system/post";
import gainItem from "@/views/admin/components/gainItem.vue";
const { proxy } = getCurrentInstance();
const router = useRouter();
const postList = ref([]);
const loading = ref(true);
const total = ref(0);
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
postCode: undefined,
type: "1",
},
rules: {
name: [{ required: true, message: "公司名称不能为空", trigger: "blur" }],
dutyParagraph: [
{ required: true, message: "公司税号不能为空", trigger: "blur" },
],
bank: [{ required: true, message: "开户行不能为空", trigger: "blur" }],
bankAccount: [
{ required: true, message: "开户行账号不能为空", trigger: "blur" },
],
bankPhone: [
{ required: true, message: "开户行电话不能为空", trigger: "blur" },
],
email: [{ required: true, message: "电子邮箱不能为空", trigger: "blur" }],
phone: [{ required: true, message: "联系电话不能为空", trigger: "blur" }],
address: [{ required: true, message: "地址不能为空", trigger: "blur" }],
username: [{ required: true, message: "联系人不能为空", trigger: "blur" }],
userPhone: [
{ required: true, message: "联系人电话不能为空", trigger: "blur" },
],
userAddress: [
{ required: true, message: "邮寄地址不能为空", trigger: "blur" },
],
},
});
const { queryParams, form, rules } = toRefs(data);
/** 查询列表 */
function getList() {
postList.value = [
{
is_collect: true,
id: "Q7K1Jx6VYodq",
mode: 1,
title: "测试6",
description: "",
image: "",
file: "",
maturity: 1,
lead_standard: 0,
cooperation_mode: 101,
config: "",
introduce: "",
shelf_status: 0,
status: 0,
created_at: "0001-01-01T00:00:00Z",
updated_at: "0001-01-01T00:00:00Z",
research_name: "",
visit_count: 0,
collect_count: 0,
mode_title: "免费模式",
maturity_title: "正在研发",
cooperation_mode_title: "技术转让",
customers: ["关键词1", "关键词2"],
industrys: ["农、林、牧、渔业/农业", "采矿业/煤炭开采和洗选业", "制造业"],
keywords: ["关键词1", "关键词2"],
},
{
is_collect: false,
id: "gympJE5JrLxe",
mode: 1,
title: "测试5",
description: "",
image: "",
file: "",
maturity: 1,
lead_standard: 0,
cooperation_mode: 101,
config: "",
introduce: "",
shelf_status: 0,
status: 0,
created_at: "0001-01-01T00:00:00Z",
updated_at: "0001-01-01T00:00:00Z",
research_name: "",
visit_count: 0,
collect_count: 0,
mode_title: "免费模式",
maturity_title: "正在研发",
cooperation_mode_title: "技术转让",
customers: ["关键词1", "关键词2"],
industrys: ["农、林、牧、渔业/农业", "采矿业/煤炭开采和洗选业", "制造业"],
keywords: ["关键词1", "关键词2"],
},
];
total.value = 15;
loading.value = false;
// loading.value = true;
// listPost(queryParams.value).then(
// (response) => {
// postList.value = response.rows;
// total.value = response.total;
// loading.value = false;
// }
// );
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 删除按钮操作 */
function handleDelete(id) {
proxy.$modal
.confirm('是否确认删除订单号为"' + id + '"的数据项?')
.then(function () {
return delPost(postIds);
})
.then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
})
.catch(() => {});
}
function handleResults(id) {
router.push({ path: "./results" });
}
getList();
</script>
<style lang="scss" scoped>
.btn_info {
height: 35px;
line-height: 35px;
text-align: center;
color: #fff;
background-color: #787878;
}
</style>
<template>results</template>

View File

@ -0,0 +1,306 @@
<template>
<el-form
ref="formRef"
:model="modelValue"
:rules="rules"
:label-width="labelWidth + 'px'"
>
<div class="form_title" v-if="showTitle">基本信息</div>
<el-row>
<el-col :span="24">
<el-form-item label="专家头像:">
<ImageUpload v-model="modelValue.image" :limit="1" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="姓名:" prop="name">
<el-input v-model="modelValue.name"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="手机号:" prop="mobile">
<el-input v-model="modelValue.mobile"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="所属单位:" prop="research_id">
<el-select
v-model="modelValue.research_id"
filterable
placeholder="请选择"
@change="setLaboratory"
>
<el-option
v-for="item in researchOptions"
:key="item.id"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属实验室:">
<el-select
v-model="modelValue.laboratory_id"
filterable
placeholder="请选择"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<CityOptions
v-model="modelValue"
:labelWidth="labelWidth"
ref="cityFormRef"
/>
<el-row>
<el-col :span="24">
<el-form-item label="详细地址:">
<el-input v-model="modelValue.address"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="毕业院校:" prop="school">
<el-input v-model="modelValue.school"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="最高学历:" prop="education">
<el-select v-model="modelValue.education" placeholder="请选择">
<el-option
v-for="item in educationOptions"
:key="item.text"
:label="item.text"
:value="item.text"
>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="主修专业:" prop="major">
<el-input v-model="modelValue.major"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="职务:" prop="job">
<el-input v-model="modelValue.job"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="职称:" prop="title">
<el-input v-model="modelValue.title"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="从业时间:" prop="work_at">
<el-date-picker
v-model="modelValue.work_at"
type="date"
value-format="YYYY-MM-DD"
placeholder="选择日期"
>
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="性别:" prop="gender">
<el-radio v-model="modelValue.gender" :label="1">男</el-radio>
<el-radio v-model="modelValue.gender" :label="2">女</el-radio>
</el-form-item>
</el-col>
</el-row>
<FieldOptions
v-model="modelValue"
:labelWidth="labelWidth"
ref="fieldFormRef"
/>
<InputBoxAdd
:labelWidth="labelWidth"
v-model="modelValue"
title="关键词"
placeholder="应用场景关键词+技术产品关键词"
fieldKey="keywords"
ref="keywordsFormRef"
/>
<InputBoxAdd
:labelWidth="labelWidth"
v-model="modelValue"
title="研究方向"
placeholder="请输入研究方向"
fieldKey="researchs"
ref="researchsFormRef"
/>
<el-row>
<el-col :span="24">
<el-form-item label="个人简介:" prop="introduce">
<el-input
v-model="modelValue.introduce"
type="textarea"
:autosize="{ minRows: 2, maxRows: 8 }"
maxlength="400"
show-word-limit
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script setup name="ExpertForm">
import CityOptions from "@/views/components/CityOptions";
import FieldOptions from "@/views/components/FieldOptions";
import InputBoxAdd from "@/views/components/InputBoxAdd";
import { educationOptions } from "@/utils/parameter";
const props = defineProps({
modelValue: Object,
isAdd: {
type: Boolean,
default: true,
},
showTitle: {
type: Boolean,
default: false,
},
labelWidth: {
type: Number,
default: 120,
},
});
const { modelValue, isAdd, showTitle, labelWidth } = toRefs(props);
const data = reactive({
rules: {
product: [{ required: true, message: "请输入", trigger: "blur" }],
name: [{ required: true, message: "请输入", trigger: "blur" }],
kind: [{ required: true, message: "请选择", trigger: "change" }],
code: [{ required: true, message: "请输入", trigger: "blur" }],
mobile: [
{ required: true, message: "请输入", trigger: "blur" },
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: "请输入正确的手机号码",
trigger: "blur",
},
],
research_id: [{ required: true, message: "请选择", trigger: "change" }],
tenant_id: [
{
required: true,
message: "请选择",
trigger: ["blur", "change"],
},
],
school: [{ required: true, message: "请输入", trigger: "blur" }],
education: [{ required: true, message: "请选择", trigger: "change" }],
major: [{ required: true, message: "请输入", trigger: "blur" }],
job: [{ required: true, message: "请输入", trigger: "blur" }],
title: [{ required: true, message: "请输入", trigger: "blur" }],
work_at: [
{
required: true,
message: "从业时间不能为空",
trigger: ["change", "blur"],
},
],
license: [
{
required: true,
message: "请上传",
trigger: ["blur", "change"],
},
],
introduce: [
{
required: true,
message: "请输入",
trigger: ["change", "blur"],
},
],
},
});
const { rules } = toRefs(data);
const researchOptions = ref([]);
const options = ref([]);
const formRef = ref();
const cityFormRef = ref();
const fieldFormRef = ref();
const keywordsFormRef = ref();
const researchsFormRef = ref();
const validateForm = async () => {
let formValid;
try {
formValid = await formRef.value.validate();
} catch (error) {
formValid = false;
}
const cityFormValid = await cityFormRef.value.validateForm(); // 城市选择表单验证
const fieldFormValid = await fieldFormRef.value.validateForm(); // 领域选择表单验证
const keywordsFormValid = await keywordsFormRef.value.validateForm(); // 关键词表单验证
const researchsFormValid = await researchsFormRef.value.validateForm();
return (
formValid &&
cityFormValid &&
fieldFormValid &&
keywordsFormValid &&
researchsFormValid
);
// if (isAdd.value) {
// // const directionsFormValid = await directionsFormRef.value.validateForm();
// return formValid && cityFormValid && fieldFormValid && researchsFormValid;
// } else {
// return formValid && cityFormValid && fieldFormValid && keywordsFormValid;
// }
};
defineExpose({
validateForm,
});
</script>
<style lang="scss" scoped>
.form_title {
font-weight: 700;
margin-bottom: 30px;
}
.el-select,
.el-date-editor {
display: block;
width: 100%;
}
</style>

View File

@ -73,18 +73,25 @@
</el-form-item>
</el-col>
</el-row>
<!-- <el-row>
<el-row>
<el-col :span="24">
<el-form-item label="合作模式:">
<el-select
v-model="modelValue.province"
v-model="modelValue.cooperationMode"
clearable
placeholder="请选择"
>
<el-option
v-for="item in cooperationOptions"
:key="item.key"
:label="item.value"
:value="item.key"
>
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row> -->
</el-row>
<InputBoxAdd
:labelWidth="labelWidth"
@ -92,13 +99,18 @@
title="关键词"
placeholder="请输入关键词"
fieldKey="keywords"
ref="keywordsFormRef"
ref="keywordsForm"
/>
<el-row>
<el-col :span="24">
<el-form-item label="产品简介:" prop="introduce">
<WangEditor v-model="modelValue.introduce" :min-height="300" />
<wangEditor
v-model="modelValue.introduce"
min-height="150px"
width="100%"
ref="introduceRef"
/>
</el-form-item>
</el-col>
</el-row>
@ -123,9 +135,9 @@
</p>
<el-row>
<el-col :span="24">
<el-form-item label="证明材料:" prop="file">
<el-form-item label="证明材料:" prop="material">
<FileUpload
v-model="modelValue.file"
v-model="modelValue.material"
:limit="1"
:fileType="['doc', 'xls', 'pdf', 'jpg', 'png', 'zip']"
/>
@ -135,12 +147,18 @@
</el-form>
</template>
<script setup>
// import CityOptions from "@/views/components/CityOptions";
import CityOptions from "@/views/components/CityOptions";
import FieldOptions from "@/views/components/FieldOptions";
import InputBoxAdd from "@/views/components/InputBoxAdd";
import WangEditor from "@/components/WangEditor";
import { maturityOptions, leadOptions } from "@/utils/parameter";
import {
maturityOptions,
leadOptions,
cooperationOptions,
} from "@/utils/parameter";
import { reactive, toRefs } from "vue";
import VideoUpload from "@/components/VideoUpload";
// import { researchSelect, laboratorySelect } from "@/api/identity/index";
const props = defineProps({
modelValue: Object,
isAdd: {
@ -160,31 +178,31 @@ const { modelValue, isAdd, showTitle, labelWidth } = toRefs(props);
const data = reactive({
rules: {
product: [{ required: true, message: "请输入", trigger: "blur" }],
// product: [{ required: true, message: "", trigger: "blur" }],
title: [{ required: true, message: "请输入", trigger: "blur" }],
kind: [{ required: true, message: "请选择", trigger: "change" }],
code: [{ required: true, message: "请输入", trigger: "blur" }],
mobile: [
{ required: true, message: "请输入", trigger: "blur" },
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: "请输入正确的手机号码",
trigger: "blur",
},
],
research_id: [{ required: true, message: "请选择", trigger: "change" }],
// code: [{ required: true, message: "", trigger: "blur" }],
// mobile: [
// { required: true, message: "", trigger: "blur" },
// {
// pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
// message: "",
// trigger: "blur",
// },
// ],
// research_id: [{ required: true, message: "", trigger: "change" }],
maturity: [{ required: true, message: "请选择", trigger: "change" }],
tenant_id: [
{
required: true,
message: "请选择",
trigger: ["blur", "change"],
},
],
school: [{ required: true, message: "请输入", trigger: "blur" }],
education: [{ required: true, message: "请选择", trigger: "change" }],
major: [{ required: true, message: "请输入", trigger: "blur" }],
job: [{ required: true, message: "请输入", trigger: "blur" }],
// tenant_id: [
// {
// required: true,
// message: "",
// trigger: ["blur", "change"],
// },
// ],
// school: [{ required: true, message: "", trigger: "blur" }],
// education: [{ required: true, message: "", trigger: "change" }],
// major: [{ required: true, message: "", trigger: "blur" }],
// job: [{ required: true, message: "", trigger: "blur" }],
title: [{ required: true, message: "请输入", trigger: "blur" }],
work_at: [
{
@ -207,46 +225,69 @@ const data = reactive({
trigger: ["change", "blur"],
},
],
// image: [
// {
// required: true,
// message: "",
// trigger: ["change", "blur"],
// },
// ],
// video: [
// {
// required: true,
// message: "",
// trigger: ["change", "blur"],
// },
// ],
image: [
{
required: true,
message: "请上传",
trigger: ["change", "blur"],
},
],
video: [
{
required: true,
message: "请上传",
trigger: ["change", "blur"],
},
],
},
});
const { rules } = toRefs(data);
const formRef = ref();
const keywordsFormRef = ref();
const fieldFormRef = ref();
const customerFormRef = ref();
const formRef = ref(null);
const fieldFormRef = ref(null);
const customerFormRef = ref(null);
const validateForm = async () => {
let formValid = ref();
// await formRef.value.validate();
let formValid;
try {
formValid = await formRef.value.validate();
} catch (error) {
formValid = false;
}
const customerFormValid = await customerFormRef.value.validateForm(); //
const fieldFormValid = await fieldFormRef.value.validateForm(); //
const keywordsFormValid = await keywordsFormRef.value.validateForm(); //
return formValid && fieldFormValid && keywordsFormValid && customerFormValid;
const fieldFormValid = await fieldFormRef.value.validateForm(); //
const customerValid = await customerFormRef.value.validateForm(); //
console.log(formValid, fieldFormValid, customerValid);
return formValid && fieldFormValid && customerValid;
// const keywordsFormValid = await keywordsFormRef.value.validateForm(); //
// console.log(cityFormValid);
// if (isAdd.value) {
// const directionsFormValid = await directionsFormRef.value.validateForm();
// return (
// formValid &&
// cityFormValid &&
// fieldFormValid &&
// keywordsFormValid &&
// directionsFormValid
// );
// } else {
// return formValid && cityFormValid && fieldFormValid && keywordsFormValid;
// }
};
defineExpose({
validateForm,
});
// const submitForm = () => {
// let flag = false;
// this.$refs["formRef"].validate((valid) => {
// const fieldForm = this.$refs.fieldForm.submitForm();
// const customerForm = this.$refs.customerForm.submitForm();
// const keywordsForm = this.$refs.keywordsForm.submitForm();
// if (valid && fieldForm && customerForm && keywordsForm) {
// flag = !flag;
// }
// });
// return flag;
// };
</script>
<style lang="scss" scoped>
.form_title {
font-weight: 700;

View File

@ -0,0 +1,37 @@
<template>
<div class="app-container">
<el-card shadow="always" style="width: 55%; margin: 0 auto">
<ExpertForm
v-model="form"
:isAdd="false"
:labelWidth="labelWidth"
ref="expertForm"
/>
<div :style="{ marginLeft: labelWidth + 'px' }">
<el-button @click="$router.go(-1)">取消</el-button>
<el-button type="primary" @click="submitForm">提交</el-button>
</div>
</el-card>
</div>
</template>
<script setup>
import { expert } from "@/api/identity/index";
import ExpertForm from "@/views/components/ExpertForm";
const { proxy } = getCurrentInstance();
const labelWidth = 140;
const form = reactive({
laboratory_id: undefined, // 所属实验室
gender: 1,
});
function submitForm(status) {
// if (proxy.$refs.expertForm.submitForm()) {
// expert(form).then((res) => {
// proxy.$modal.msgSuccess("新增成功");
// proxy.$router.go(-1);
// });
// } else {
// console.log("校验未通过");
// }
}
</script>

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

View File

@ -0,0 +1,222 @@
<template>
<div
class="box"
style="background-size: cover; background-color: #fff"
:style="{ backgroundImage: state.banner ? `url(${state.banner})` : '' }"
>
<div>
<el-row>
<el-col :push="4" :sm="10" :md="12">
<div class="tab">
<div
v-for="(v, index) in state.tabList"
:class="{ active: state.tabIndex == index }"
@click="state.tabIndex = index"
>
{{ v }}
</div>
</div>
</el-col>
</el-row>
<div style="height: 16px"></div>
<el-row>
<el-col :push="4" :sm="10" :md="12">
<el-input v-model.trim="state.keyword" placeholder="请输入检索词">
<template #append>
<el-button class="x_btns" icon="Search" @click="handleQuery"
>搜索</el-button
>
</template>
</el-input>
</el-col>
<el-col :push="4" :sm="10" :md="8">
<div class="btnsWrap">
<el-button class="x_btns" @click="handleQuery">发布需求</el-button>
<el-button class="x_btns" @click="handleQuery"
>专家机构录入</el-button
>
</div>
</el-col>
</el-row>
<div style="height: 15vh"></div>
<el-row>
<el-col :push="3" :pull="3" :span="18">
<div class="numBox">
<div>
<div class="val">{{ state.data.expert_count }}</div>
<div class="des">专家数量</div>
</div>
<div>
<div class="val">
{{ state.data.patent_count + state.data.achievement_count }}
</div>
<div class="des">专利成果数量</div>
</div>
<div>
<div class="val">{{ state.data.demand_count }}</div>
<div class="des">需求数量</div>
</div>
<div>
<div class="val">{{ state.data.docking_count }}</div>
<div class="des">对接数量</div>
</div>
<div>
<div class="val">{{ state.data.company_count }}</div>
<div class="des">实验室数量</div>
</div>
</div>
</el-col>
</el-row>
<!-- <div class="icp-beian">
<el-link type="primary" href="https://beian.miit.gov.cn/"
>皖ICP备18001784号</el-link
>
</div> -->
</div>
<!-- <webFooter></webFooter> -->
</div>
</template>
<script setup>
import { onMounted, reactive } from "vue";
import { banner } from "@/api/website/home/index";
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,
banner: "",
data: {
expert_count: 0,
company_count: 0,
patent_count: 0,
achievement_count: 0,
demand_count: 0,
docking_count: 0,
},
});
onMounted(() => {
banner("首页背景").then((res) => {
if (200 == res.code) {
state.banner = res.data.images;
}
});
indexData().then((res) => {
if (200 == res.code) {
state.data = res.data;
}
});
// console.log("onmunted");
});
</script>
<style lang="scss" scoped>
.x_btns {
font-size: 14px !important;
font-weight: 400;
}
.box {
height: 100%;
width: 100%;
display: flex;
display: -webkit-flex;
align-items: center;
justify-content: center;
& > div {
width: 100%;
}
}
.btnsWrap {
margin: 0 0 0 40px;
.el-button {
height: 36px;
padding: 10px 25px;
}
}
.numBox {
display: flex;
display: -webkit-flex;
& > div {
flex: 1;
height: 200px;
display: -webkit-flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.val {
font-size: 36px;
font-family: DIN;
font-weight: 400;
color: #333333;
margin-bottom: 10px;
}
.des {
font-size: 16px;
font-family: Source Han Sans CN;
font-weight: 400;
color: #333333;
}
}
.tab {
width: 480px;
height: 42px;
overflow: hidden;
& > div {
width: 80px;
height: 42px;
line-height: 42px;
text-align: center;
font-size: 14px;
font-family: Source Han Sans CN;
font-weight: 400;
color: #333333;
float: left;
cursor: pointer;
user-select: none;
}
& > div.active {
font-size: 14px;
font-weight: 500;
color: #ffffff;
line-height: 38px;
background-image: url(./img/index1-bg1.png);
background-size: cover;
}
}
.wrap {
padding-left: 460px;
}
.search {
width: 720px;
}
.icp-beian {
width: 100vw;
text-align: center;
position: absolute;
bottom: 10px;
}
</style>

View File

@ -0,0 +1,297 @@
<template>
<div class="box">
<div style="position: absolute; top: 0; left: 50%">
<webReleaseActive
v-model:dialogVisible="dialogVisible"
></webReleaseActive>
</div>
<div class="wrap">
<div class="tit">
<div class="left">科技活动</div>
<div class="right">
<!-- @click="dialogVisible = true" -->
<!-- <div class="publish">发布活动</div> -->
<div class="more" @click="handlePage">更多</div>
</div>
</div>
<div class="content">
<div
class="item"
:class="index == 0 ? 'one' : ''"
v-for="(item, index) in state.list.slice(0, 1)"
:key="item.id"
@click="handleDetail(item.id)"
>
<img :src="item.image" style="width: 100%" />
<div class="des">
<div class="left">
<div>{{ item.title }}</div>
<div class="time">
活动时间{{ parseTime(item.begin_at) }} -
{{ parseTime(item.finish_at) }}
</div>
<div>{{ item.join_count }}人已观看</div>
</div>
<div class="right">{{ item.amount }}元报名</div>
</div>
</div>
<div
class="item"
v-for="item in state.list.slice(1)"
:key="item.id"
@click="handleDetail(item.id)"
>
<div class="img">
<img :src="item.image" />
</div>
<div class="dess">
<div class="txt">
{{ item.title }}
</div>
<div class="dess1">
<div class="time">
活动时间{{ parseTime(item.begin_at) }}
<!-- - {{ parseTime(item.finish_at) }} -->
</div>
<div>{{ item.join_count }}人已观看</div>
</div>
<div class="enroll">{{ item.amount }}元报名</div>
</div>
</div>
<!-- <div class="item">
<div class="img">
<img
src="https://t7.baidu.com/it/u=1820929524,3700012367&fm=193&f=GIF"
/>
</div>
<div class="dess">
<div class="txt">
助力工厂公辅系统数字化及节能提效助力工厂公辅系统数字化及节能提效
</div>
<div class="dess1">
<div class="time">活动时间2021-11-01 08:00</div>
<div>1988人已观看</div>
</div>
<div class="enroll">19.9元报名</div>
</div>
</div>
<div class="item">
<div class="img">
<img
src="https://t7.baidu.com/it/u=1820929524,3700012367&fm=193&f=GIF"
/>
</div>
<div class="dess">
<div class="txt">
助力工厂公辅系统数字化及节能提效助力工厂公辅系统数字化及节能提效
</div>
<div class="dess1">
<div class="time">活动时间2021-11-01 08:00</div>
<div>1988人已观看</div>
</div>
<div class="enroll">19.9元报名</div>
</div>
</div>
<div class="item">
<div class="img">
<img
src="https://t7.baidu.com/it/u=1820929524,3700012367&fm=193&f=GIF"
/>
</div>
<div class="dess">
<div class="txt">
助力工厂公辅系统数字化及节能提效助力工厂公辅系统数字化及节能提效
</div>
<div class="dess1">
<div class="time">活动时间2021-11-01 08:00</div>
<div>1988人已观看</div>
</div>
<div class="enroll end">已结束</div>
</div>
</div> -->
</div>
</div>
</div>
</template>
<script setup lang="ts">
import request from "@/utils/request";
import { defineComponent, onMounted, reactive } from "vue";
import webReleaseActive from "@/components/webReleaseActive/index.vue";
function activity() {
return request({
url: "/v1/activity",
method: "post",
data: {
status: 2,
page_num: 1,
page_size: 5,
},
});
}
const router = useRouter();
const dialogVisible = ref(false);
const state = reactive({
list: [],
total: 0,
});
function getList() {
activity().then((res) => {
if (200 == res.code) {
state.total = res.data.count;
state.list = res.data.data;
}
});
}
function handleDetail(id) {
let routeData = router.resolve({ path: `/activity/detail/${id}` });
window.open(routeData.href, "_blank");
}
function handlePage() {
router.push("/activity");
}
getList();
</script>
<style lang="scss" scoped>
.box {
height: 100%;
width: 100%;
display: flex;
display: -webkit-flex;
align-items: center;
justify-content: center;
div.wrap {
width: 1400px;
}
}
.tit {
overflow: hidden;
padding: 20px 0;
.left {
float: left;
font-size: 36px;
font-family: Source Han Sans CN;
font-weight: 300;
color: #333333;
}
.right {
float: right;
font-size: 20px;
font-family: Source Han Sans CN;
.publish {
display: inline-block;
font-weight: 500;
color: #0054ff;
margin-right: 20px;
cursor: pointer;
user-select: none;
}
.more {
display: inline-block;
font-weight: 400;
color: #333333;
cursor: pointer;
user-select: none;
}
}
}
.content {
width: 101%;
overflow: hidden;
.time {
display: inline-block;
padding: 2px 8px;
margin: 2px 0;
background: #0054ff;
border-radius: 10px;
font-size: 14px;
font-family: Source Han Sans CN;
font-weight: 400;
color: #ffffff;
}
.item {
position: relative;
float: left;
width: 24%;
margin: 0 1% 1% 0;
.dess {
overflow: hidden;
.txt {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dess1 {
float: left;
}
.enroll {
margin-top: 10px;
float: right;
width: 90px;
height: 30px;
line-height: 30px;
background: #0054ff;
font-size: 16px;
font-family: Source Han Sans CN;
font-weight: 400;
color: #ffffff;
text-align: center;
&.end {
background: #b4b4b4;
}
}
}
img {
top: 0;
left: 0;
position: absolute;
width: 100%;
height: 100%;
}
.img {
position: relative;
width: 100%;
height: 0;
padding-bottom: 54%;
}
&.one {
width: 49%;
height: 0;
padding-bottom: 36.75%;
overflow: hidden;
.des {
position: absolute;
height: 94px;
width: 100%;
bottom: 0;
background: rgba(0, 0, 0, 0.2);
overflow: hidden;
.left {
float: left;
font-size: 16px;
font-family: Source Han Sans CN;
font-weight: 400;
color: #ffffff;
margin: 16px 0 0 18px;
}
.right {
margin: 27px 38px;
float: right;
width: 120px;
height: 40px;
line-height: 40px;
background: #0054ff;
font-size: 16px;
font-family: Source Han Sans CN;
font-weight: 400;
color: #ffffff;
text-align: center;
}
}
}
}
}
</style>

View File

@ -0,0 +1,548 @@
<template>
<div class="box3" v-loading="loading">
<div class="tit">专家分布地图</div>
<div v-if="state.isShowGoBack" class="close-back" @click="goBack">
<img src="./img/back_button.png" />
</div>
<!-- echartsDom 兼容缩放 -->
<div ref="map" class="map echartsDom" id="map"></div>
<div class="leftBox">
<div class="head">
<div class="a">地区</div>
<div class="b">专家数量</div>
</div>
<div v-if="Object.keys(snapTree).length > 0" v-for="v in snapTree">
<div class="a">{{ v.name }}</div>
<div class="b">{{ v.count }}</div>
</div>
<div v-else>
<div class="a">暂无</div>
<div class="b">暂无</div>
</div>
</div>
<div class="rightBox">
<div class="head">
<div class="a">领域</div>
<div class="b">专家数量</div>
</div>
<div
v-if="Object.keys(getIndustry(snapTree)).length > 0"
v-for="(v, k) in getIndustry(snapTree)"
>
<div class="a" :title="k">{{ k }}</div>
<div class="b">{{ v }}</div>
</div>
<div v-else>
<div class="a">暂无</div>
<div class="b">暂无</div>
</div>
</div>
</div>
</template>
<script setup>
import { defineComponent, getCurrentInstance, onMounted, reactive } from "vue";
import echarts from "echarts";
import { getExpert } from "@/api/website/home/index";
const { proxy } = getCurrentInstance();
const loading = shallowRef(true);
let treeData = {
340000: {
code: "340000",
name: "安徽省",
count: 107,
industry: { "1-1": 2, "1-2": 1, "2-1": 3 },
children: {
340100: {
code: "340100",
name: "合肥市",
count: 106,
industry: { "1-1": 1, "1-2": 1, "2-1": 2 },
children: {
340111: {
code: "340111",
name: "包河区",
count: 105,
industry: { "1-1": 1, "2-1": 1 },
children: null,
},
340121: {
code: "340121",
name: "长丰县",
count: 105,
industry: { "1-2": 1, "2-1": 1 },
children: null,
},
},
},
340200: {
code: "340200",
name: "芜湖市",
count: 105,
industry: { "1-1": 1, "2-1": 1 },
children: {},
},
},
},
500000: {
code: "500000",
name: "重庆",
count: 300,
industry: null,
children: {
500100: {
code: "500100",
name: "市辖区",
count: 300,
industry: null,
children: null,
},
},
},
630000: {
code: "630000",
name: "青海省",
count: 1200,
industry: null,
children: {
630200: {
code: "630200",
name: "海东市",
count: 1200,
industry: null,
children: null,
},
},
},
};
const snapTree = shallowRef({});
function searchRegionData(code) {
// console.log(code, treeData,'searchRegionData')
return deepFindTree(code, treeData);
}
function deepFindTree(code, tree) {
let snap = false;
for (const key in tree) {
if (Object.hasOwnProperty.call(tree, key)) {
if (code == key) {
snap = tree[code];
break;
} else if (tree[key]["children"] != null) {
snap = deepFindTree(code, tree[key]["children"]);
if (snap) {
break;
}
} else {
snap = false;
}
}
}
return snap;
}
function getIndustry(object) {
let snap = {};
for (const key in object) {
if (Object.hasOwnProperty.call(object, key)) {
const element = object[key];
if (element["industry"] != null) {
for (const ek in element["industry"]) {
if (Object.hasOwnProperty.call(element["industry"], ek)) {
const ele = element["industry"][ek];
if (!Object.hasOwnProperty.call(snap, ek)) {
snap[ek] = 0;
}
snap[ek] += ele;
}
}
// for (let index = 0; index < element['industry'].length; index++) {
// const ele = element['industry'][index];
// if(Object.hasOwnProperty.call(snap, ele)) {
// }
// }
}
}
}
return snap;
}
const state = reactive({
loading: false,
isShowGoBack: false,
nameType: "",
// cityName: "中国",
cityName: "china",
areaCode: 10000,
AreaCodeStack: ["中国"],
geoJsonData: "",
echartsMap: null,
map: null,
uimap: null,
district: null,
polygons: [],
cityCode: "100000",
citySelect: null,
districtSelect: null,
opts: {},
areaData: {},
mapData: [],
zip: {}, //打包zip
codeList: [],
isCodeListLoadComplete: false, //codeList是否全部获取完毕
downloadTips: "下载geoJson数据", //下载进度提示
isShowTips: false, //是否显示下载提示
});
onMounted(() => {
// 数据接口
getExpert().then((res) => {
if (200 == res.code) {
treeData = res.data;
snapTree.value = res.data;
loading.value = false;
}
});
// let echartsDomList = document.querySelectorAll('.echartsDom');
// // 兼容echarts
// echartsDomList.forEach(element => {
// element.style.zoom = window.devicePixelRatio;
// element.style.transform = "scale(" + (1 / window.devicePixelRatio) + ")";
// element.style.transformOrigin = "0%0%";
// element.style.width = window.devicePixelRatio * 100 + '%';
// element.style.height = window.devicePixelRatio * 100 + '%';
// console.log(element.style.zoom, 'element.style.zoom')
// });
let height = document.body.clientHeight;
let width = document.body.clientWidth;
let dom = proxy.$refs["map"];
dom.style.width = width + "px";
dom.style.height = height - 80 + "px";
state.echartsMap = echarts.init(dom);
state.echartsMap.on("click", echartsMapClick);
setTimeout(() => {
state.map = new AMap.Map("container", {
resizeEnable: true,
center: [116.30946, 39.937629],
zoom: 3,
});
state.opts = {
subdistrict: 1, //返回下一级行政区
showbiz: false, //最后一级返回街道信息
};
state.district = new AMap.DistrictSearch(state.opts); //注意:需要使用插件同步下发功能才能这样直接使用
state.district.search("中国", (status, result) => {
if (status == "complete") {
getData(result.districtList[0], "", 100000);
}
});
}, 1000);
});
function goBack() {
state.isShowGoBack = false;
loading.value = true;
state.district.search("中国", (status, result) => {
if (status == "complete") {
getData(result.districtList[0], "", 100000);
snapTree.value = treeData;
}
});
}
function echartsMapClick(params) {
//地图点击事件
if (params.data.cityCode == "710000") {
return;
}
if (params.data.level == "district") {
return;
}
if (params.data.level == "street") return; //此处的params.data为state.mapData里的数据
let snap = searchRegionData(params.data.cityCode);
snapTree.value = {};
if (snap) {
snapTree.value = snap["children"];
}
state.cityCode = params.data.cityCode;
state.cityName = params.data.name;
state.district.setLevel(params.data.level); //行政区级别
state.district.setExtensions("all");
state.isShowGoBack = true;
loading.value = true;
//行政区查询
//按照adcode进行查询可以保证数据返回的唯一性
state.district.search(state.cityCode, (status, result) => {
if (status === "complete") {
if (params.data.level == "district") {
return;
}
state.AreaCodeStack.push(result.districtList[0].adcode);
getData(result.districtList[0], params.data.level, state.cityCode); //这个getData函数在前面已经定义过了
}
});
}
function getData(data, level, adcode) {
//处理获取出来的边界数据
var subList = data.districtList;
if (subList) {
var curlevel = subList[0].level;
if (curlevel === "street") {
//为了配合echarts地图区县名称显示正常这边街道级别数据需要特殊处理
let mapJsonList = state.geoJsonData.features;
let mapJson = {};
for (let i in mapJsonList) {
if (mapJsonList[i].properties.name == state.cityName) {
mapJson["features"] = [].concat(mapJsonList[i]);
}
}
state.mapData = [];
let item = searchRegionData(cityCode);
if (item) {
console.log("1 searchRegionData(cityCode)", item);
}
//这个mapData里包含每个区域的code、名称、对应的等级实现第三步功能时能用上
state.mapData.push({
name: state.cityName,
value: item ? item.count : 0,
level: curlevel,
});
loadMap(state.cityName, mapJson);
state.geoJsonData = mapJson;
return;
}
//街道级以上的数据处理方式
state.mapData = [];
for (var i = 0, l = subList.length; i < l; i++) {
var name = subList[i].name;
var cityCode = subList[i].adcode;
//这个mapData里包含每个区域的code、名称、对应的等级实现第三步功能时能用上
let item = searchRegionData(cityCode);
if (item) {
console.log("2 searchRegionData(cityCode)", item);
}
state.mapData.push({
name: name,
value: item ? item.count : 0,
cityCode: cityCode,
level: curlevel,
});
}
loadMapData(adcode);
}
}
function loadMapData(areaCode) {
AMapUI.loadUI(["geo/DistrictExplorer"], (DistrictExplorer) => {
//创建一个实例
var districtExplorer = (window.districtExplorer = new DistrictExplorer({
eventSupport: true, //打开事件支持
map: state.map,
}));
districtExplorer.loadAreaNode(areaCode, (error, areaNode) => {
if (error) {
console.error(error);
return;
}
let mapJson = {};
//特别注意这里哦如果查看过正常的geojson文件都会发现文件都是以features 字段开头的,所以这里要记得加上
mapJson.features = areaNode.getSubFeatures();
console.log("------------------");
for (var i = 0; i < mapJson.features.length; i++) {
if (
mapJson.features[i].properties.adcode == 810000 ||
mapJson.features[i].properties.adcode == 820000
) {
mapJson.features.splice(i, 1); // 删除下标为i 的元素i开始只删除一个就它自己了
i--; // 删除一个元素后数组长度减一了
}
}
console.log("------------------");
loadMap(state.cityName, mapJson);
});
});
}
function loadMap(mapName, data) {
if (data) {
echarts.registerMap(mapName, data); //把geoJson数据注入echarts
//配置echarts的option
var option = {
visualMap: {
type: "piecewise",
left: "center", //组件离容器左侧的距离,'left', 'center', 'right','20%'
bottom: "30",
orient: "horizontal", //图例排列方向
padding: 5,
pieces: [
{ gte: 0, lte: 99, label: "99", color: "#CAE9FD" },
{ gte: 100, lte: 299, label: "100-299", color: "#7ED2F7" },
{ gte: 300, lte: 499, label: "299-499", color: "#039DDD" },
{ gte: 500, label: "500", color: "#0D4884" },
// {max: 30, label: '安全', color: '#2c9a42'},
// {min: 30, max: 60, label: '警告', color: '#d08a00'},
// {min: 60, label: '危险', color: '#c23c33'},
],
// color: '#fff',
textStyle: {
color: "#fff",
},
visibility: "off",
},
tooltip: {
//提示框信息
trigger: "item",
formatter: "{b}\n{c}人",
},
series: [
{
name: "数据名称",
type: "map",
roam: false,
top: "15%",
bottom: state.isShowGoBack ? "8%" : "-20%",
mapType: mapName,
selectedMode: "single",
showLegendSymbol: false,
visibility: "off",
backgroundColor: "transparent",
itemStyle: {
normal: {
color: "#333333",
areaColor: "#fff",
borderColor: "#666666",
borderWidth: 0.5,
label: {
show: true,
textStyle: {
color: "#333333",
},
},
},
emphasis: {
areaColor: "rgb(38, 219, 11)",
borderColor: "#666666",
areaStyle: {
color: "#333333",
},
label: {
show: true,
textStyle: {
color: "#333333",
},
// formatter: function (value) { //标签的格式化工具。
// return value.name + '' + value.value; // 范围标签显示内容。
// }
},
},
},
data: state.mapData, //这个data里包含每个区域的code、名称、对应的等级实现第三步功能时能用上
},
],
};
state.echartsMap.setOption(option);
loading.value = false;
}
}
</script>
<style lang="scss" scoped>
.box3 {
width: 100%;
height: 100%;
background: linear-gradient(0deg, #010101, #041744);
position: relative;
.tit {
position: absolute;
top: 75px;
width: 100%;
text-align: center;
font-size: 36px;
font-family: Source Han Sans CN;
font-weight: 300;
color: #ffffff;
}
}
.map {
width: 100%;
height: 100%;
background-image: url(./img/lightEffect.png);
background-size: 644px 272px;
background-repeat: no-repeat;
background-position: center top;
}
.close-back {
background: url(img/close_back.png) no-repeat;
transition: all 0.5s;
height: 70px;
width: 85px;
color: #fff;
left: 65px;
position: absolute;
top: 100px;
cursor: pointer;
z-index: 1000;
&:hover {
left: 55px;
}
img {
margin: 28px auto 0;
width: 30px;
display: block;
transition: all 0.5s;
}
}
.leftBox {
left: 6%;
}
.rightBox {
right: 6%;
max-height: 465px !important;
}
.leftBox,
.rightBox {
position: absolute;
top: 25%;
max-width: 250px;
min-width: 200px;
max-height: 256px;
overflow: hidden;
background: rgba(4, 22, 65, 0.5);
border: 1px solid #0054ff;
color: rgba(161, 192, 255, 1);
& > div {
display: flex;
}
.head {
border-bottom: 1px solid #0054ff;
color: #ffffff;
}
.a {
flex: 1;
border-right: 1px solid #0054ff;
text-align: center;
line-height: 42px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.b {
text-align: center;
line-height: 42px;
width: 90px;
}
}
</style>

View File

@ -0,0 +1,546 @@
<template>
<div class="box3" v-loading="loading">
<div class="tit">实验室分布地图</div>
<div v-if="state.isShowGoBack" class="close-back" @click="goBack">
<img src="./img/back_button.png" />
</div>
<!-- echartsDom 兼容缩放 -->
<div ref="map" class="map echartsDom" id="map"></div>
<div class="leftBox">
<div class="head">
<div class="a">地区</div>
<div class="b">实验室数量</div>
</div>
<div v-if="Object.keys(snapTree).length > 0" v-for="v in snapTree">
<div class="a">{{ v.name }}</div>
<div class="b">{{ v.count }}</div>
</div>
<div v-else>
<div class="a">暂无</div>
<div class="b">暂无</div>
</div>
</div>
<div class="rightBox">
<div class="head">
<div class="a">领域</div>
<div class="b">实验室数量</div>
</div>
<div
v-if="Object.keys(getIndustry(snapTree)).length > 0"
v-for="(v, k) in getIndustry(snapTree)"
>
<div class="a" :title="k">{{ k }}</div>
<div class="b">{{ v }}</div>
</div>
<div v-else>
<div class="a">暂无</div>
<div class="b">暂无</div>
</div>
</div>
</div>
</template>
<script setup>
import { defineComponent, getCurrentInstance, onMounted, reactive } from "vue";
import echarts from "echarts";
import { laboratory } from "@/api/website/home/index";
const { proxy } = getCurrentInstance();
const loading = shallowRef(true);
let treeData = {
340000: {
code: "340000",
name: "安徽省",
count: 107,
industry: { "1-1": 2, "1-2": 1, "2-1": 3 },
children: {
340100: {
code: "340100",
name: "合肥市",
count: 106,
industry: { "1-1": 1, "1-2": 1, "2-1": 2 },
children: {
340111: {
code: "340111",
name: "包河区",
count: 105,
industry: { "1-1": 1, "2-1": 1 },
children: null,
},
340121: {
code: "340121",
name: "长丰县",
count: 105,
industry: { "1-2": 1, "2-1": 1 },
children: null,
},
},
},
340200: {
code: "340200",
name: "芜湖市",
count: 105,
industry: { "1-1": 1, "2-1": 1 },
children: {},
},
},
},
500000: {
code: "500000",
name: "重庆",
count: 300,
industry: null,
children: {
500100: {
code: "500100",
name: "市辖区",
count: 300,
industry: null,
children: null,
},
},
},
630000: {
code: "630000",
name: "青海省",
count: 1200,
industry: null,
children: {
630200: {
code: "630200",
name: "海东市",
count: 1200,
industry: null,
children: null,
},
},
},
};
const snapTree = shallowRef({});
function searchRegionData(code) {
// console.log(code, treeData,'searchRegionData')
return deepFindTree(code, treeData);
}
function deepFindTree(code, tree) {
let snap = false;
for (const key in tree) {
if (Object.hasOwnProperty.call(tree, key)) {
if (code == key) {
snap = tree[code];
break;
} else if (tree[key]["children"] != null) {
snap = deepFindTree(code, tree[key]["children"]);
if (snap) {
break;
}
} else {
snap = false;
}
}
}
return snap;
}
function getIndustry(object) {
let snap = {};
for (const key in object) {
if (Object.hasOwnProperty.call(object, key)) {
const element = object[key];
if (element["industry"] != null) {
for (const ek in element["industry"]) {
if (Object.hasOwnProperty.call(element["industry"], ek)) {
const ele = element["industry"][ek];
if (!Object.hasOwnProperty.call(snap, ek)) {
snap[ek] = 0;
}
snap[ek] += ele;
}
}
// for (let index = 0; index < element['industry'].length; index++) {
// const ele = element['industry'][index];
// if(Object.hasOwnProperty.call(snap, ele)) {
// }
// }
}
}
}
return snap;
}
const state = reactive({
loading: false,
isShowGoBack: false,
nameType: "",
// cityName: "中国",
cityName: "china",
areaCode: 10000,
AreaCodeStack: ["中国"],
geoJsonData: "",
echartsMap: null,
map: null,
uimap: null,
district: null,
polygons: [],
cityCode: "100000",
citySelect: null,
districtSelect: null,
opts: {},
areaData: {},
mapData: [],
zip: {}, //打包zip
codeList: [],
isCodeListLoadComplete: false, //codeList是否全部获取完毕
downloadTips: "下载geoJson数据", //下载进度提示
isShowTips: false, //是否显示下载提示
});
onMounted(() => {
// 数据接口
laboratory().then((res) => {
if (200 == res.code) {
treeData = res.data;
snapTree.value = res.data;
loading.value = false;
}
});
// let echartsDomList = document.querySelectorAll('.echartsDom');
// // 兼容echarts
// echartsDomList.forEach(element => {
// element.style.zoom = window.devicePixelRatio;
// element.style.transform = "scale(" + (1 / window.devicePixelRatio) + ")";
// element.style.transformOrigin = "0%0%";
// element.style.width = window.devicePixelRatio * 100 + '%';
// element.style.height = window.devicePixelRatio * 100 + '%';
// console.log(element.style.zoom, 'element.style.zoom')
// });
let height = document.body.clientHeight;
let width = document.body.clientWidth;
let dom = proxy.$refs["map"];
dom.style.width = width + "px";
dom.style.height = height - 80 + "px";
state.echartsMap = echarts.init(dom);
state.echartsMap.on("click", echartsMapClick);
setTimeout(() => {
state.map = new AMap.Map("container", {
resizeEnable: true,
center: [116.30946, 39.937629],
zoom: 3,
});
state.opts = {
subdistrict: 1, //返回下一级行政区
showbiz: false, //最后一级返回街道信息
};
state.district = new AMap.DistrictSearch(state.opts); //注意:需要使用插件同步下发功能才能这样直接使用
state.district.search("中国", (status, result) => {
if (status == "complete") {
getData(result.districtList[0], "", 100000);
}
});
}, 2000);
});
function goBack() {
state.isShowGoBack = false;
loading.value = true;
state.district.search("中国", (status, result) => {
if (status == "complete") {
getData(result.districtList[0], "", 100000);
snapTree.value = treeData;
}
});
}
function echartsMapClick(params) {
//地图点击事件
if (params.data.cityCode == "710000") {
return;
}
if (params.data.level == "district") {
return;
}
if (params.data.level == "street") return; //此处的params.data为state.mapData里的数据
let snap = searchRegionData(params.data.cityCode);
snapTree.value = {};
if (snap) {
snapTree.value = snap["children"];
}
state.cityCode = params.data.cityCode;
state.cityName = params.data.name;
state.district.setLevel(params.data.level); //行政区级别
state.district.setExtensions("all");
state.isShowGoBack = true;
loading.value = true;
//行政区查询
//按照adcode进行查询可以保证数据返回的唯一性
state.district.search(state.cityCode, (status, result) => {
if (status === "complete") {
if (params.data.level == "district") {
return;
}
state.AreaCodeStack.push(result.districtList[0].adcode);
getData(result.districtList[0], params.data.level, state.cityCode); //这个getData函数在前面已经定义过了
}
});
}
function getData(data, level, adcode) {
//处理获取出来的边界数据
var subList = data.districtList;
if (subList) {
var curlevel = subList[0].level;
if (curlevel === "street") {
//为了配合echarts地图区县名称显示正常这边街道级别数据需要特殊处理
let mapJsonList = state.geoJsonData.features;
let mapJson = {};
for (let i in mapJsonList) {
if (mapJsonList[i].properties.name == state.cityName) {
mapJson["features"] = [].concat(mapJsonList[i]);
}
}
state.mapData = [];
let item = searchRegionData(cityCode);
if (item) {
console.log("1 searchRegionData(cityCode)", item);
}
//这个mapData里包含每个区域的code、名称、对应的等级实现第三步功能时能用上
state.mapData.push({
name: state.cityName,
value: item ? item.count : 0,
level: curlevel,
});
loadMap(state.cityName, mapJson);
state.geoJsonData = mapJson;
return;
}
//街道级以上的数据处理方式
state.mapData = [];
for (var i = 0, l = subList.length; i < l; i++) {
var name = subList[i].name;
var cityCode = subList[i].adcode;
//这个mapData里包含每个区域的code、名称、对应的等级实现第三步功能时能用上
let item = searchRegionData(cityCode);
if (item) {
console.log("2 searchRegionData(cityCode)", item);
}
state.mapData.push({
name: name,
value: item ? item.count : 0,
cityCode: cityCode,
level: curlevel,
});
}
loadMapData(adcode);
}
}
function loadMapData(areaCode) {
AMapUI.loadUI(["geo/DistrictExplorer"], (DistrictExplorer) => {
//创建一个实例
var districtExplorer = (window.districtExplorer = new DistrictExplorer({
eventSupport: true, //打开事件支持
map: state.map,
}));
districtExplorer.loadAreaNode(areaCode, (error, areaNode) => {
if (error) {
console.error(error);
return;
}
let mapJson = {};
//特别注意这里哦如果查看过正常的geojson文件都会发现文件都是以features 字段开头的,所以这里要记得加上
mapJson.features = areaNode.getSubFeatures();
console.log("------------------");
for (var i = 0; i < mapJson.features.length; i++) {
if (
mapJson.features[i].properties.adcode == 810000 ||
mapJson.features[i].properties.adcode == 820000
) {
mapJson.features.splice(i, 1); // 删除下标为i 的元素i开始只删除一个就它自己了
i--; // 删除一个元素后数组长度减一了
}
}
console.log("------------------");
loadMap(state.cityName, mapJson);
});
});
}
function loadMap(mapName, data) {
if (data) {
echarts.registerMap(mapName, data); //把geoJson数据注入echarts
//配置echarts的option
var option = {
visualMap: {
type: "piecewise",
left: "center", //组件离容器左侧的距离,'left', 'center', 'right','20%'
bottom: "30",
orient: "horizontal", //图例排列方向
padding: 5,
pieces: [
{ gte: 0, lte: 99, label: "99", color: "#CAE9FD" },
{ gte: 100, lte: 299, label: "100-299", color: "#7ED2F7" },
{ gte: 300, lte: 499, label: "299-499", color: "#039DDD" },
{ gte: 500, label: "500", color: "#0D4884" },
// {max: 30, label: '安全', color: '#2c9a42'},
// {min: 30, max: 60, label: '警告', color: '#d08a00'},
// {min: 60, label: '危险', color: '#c23c33'},
],
// color: '#fff',
textStyle: {
color: "#333333",
},
visibility: "off",
},
tooltip: {
//提示框信息
trigger: "item",
formatter: "{b}\n{c}个",
},
series: [
{
name: "数据名称",
type: "map",
roam: false,
top: "15%",
bottom: state.isShowGoBack ? "8%" : "-20%",
mapType: mapName,
selectedMode: "single",
showLegendSymbol: false,
visibility: "off",
backgroundColor: "transparent",
itemStyle: {
normal: {
color: "#333333",
areaColor: "#fff",
borderColor: "#666666",
borderWidth: 0.5,
label: {
show: true,
textStyle: {
color: "#333333",
},
},
},
emphasis: {
areaColor: "rgb(38, 219, 11)",
borderColor: "#666666",
areaStyle: {
color: "#333333",
},
label: {
show: true,
textStyle: {
color: "#333333",
},
// formatter: function (value) { //标签的格式化工具。
// return value.name + '' + value.value; // 范围标签显示内容。
// }
},
},
},
data: state.mapData, //这个data里包含每个区域的code、名称、对应的等级实现第三步功能时能用上
},
],
};
state.echartsMap.setOption(option);
loading.value = false;
}
}
</script>
<style lang="scss" scoped>
.box3 {
width: 100%;
height: 100%;
position: relative;
.tit {
position: absolute;
top: 75px;
width: 100%;
text-align: center;
font-size: 36px;
font-family: Source Han Sans CN;
font-weight: 300;
color: #333333;
}
}
.map {
width: 100%;
height: 100%;
// background-image: url(./img/lightEffect.png);
background-size: 644px 272px;
background-repeat: no-repeat;
background-position: center top;
}
.close-back {
background: url(img/close_back.png) no-repeat;
transition: all 0.5s;
height: 70px;
width: 85px;
color: #fff;
left: 65px;
position: absolute;
top: 100px;
cursor: pointer;
z-index: 1000;
&:hover {
left: 55px;
}
img {
margin: 28px auto 0;
width: 30px;
display: block;
transition: all 0.5s;
}
}
.leftBox {
left: 6%;
}
.rightBox {
right: 6%;
max-height: 465px !important;
}
.leftBox,
.rightBox {
position: absolute;
top: 25%;
max-width: 250px;
min-width: 200px;
max-height: 256px;
overflow: hidden;
border: 1px solid #dcdcdc;
color: #666666;
& > div {
display: flex;
}
.head {
border-bottom: 1px solid #dcdcdc;
color: #333333;
}
.a {
flex: 1;
border-right: 1px solid #dcdcdc;
text-align: center;
line-height: 42px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.b {
text-align: center;
line-height: 42px;
width: 90px;
}
}
</style>

View File

@ -0,0 +1,548 @@
<template>
<div class="box3" v-loading="loading">
<div class="tit">专利与成果分布地图</div>
<div v-if="state.isShowGoBack" class="close-back" @click="goBack">
<img src="./img/back_button.png" />
</div>
<!-- echartsDom 兼容缩放 -->
<div ref="map" class="map echartsDom" id="map"></div>
<div class="leftBox">
<div class="head">
<div class="a">地区</div>
<div class="b">成果数量</div>
</div>
<div v-if="Object.keys(snapTree).length > 0" v-for="v in snapTree">
<div class="a">{{ v.name }}</div>
<div class="b">{{ v.count }}</div>
</div>
<div v-else>
<div class="a">暂无</div>
<div class="b">暂无</div>
</div>
</div>
<div class="rightBox">
<div class="head">
<div class="a">领域</div>
<div class="b">成果数量</div>
</div>
<div
v-if="Object.keys(getIndustry(snapTree)).length > 0"
v-for="(v, k) in getIndustry(snapTree)"
>
<div class="a" :title="k">{{ k }}</div>
<div class="b">{{ v }}</div>
</div>
<div v-else>
<div class="a">暂无</div>
<div class="b">暂无</div>
</div>
</div>
</div>
</template>
<script setup>
import { defineComponent, getCurrentInstance, onMounted, reactive } from "vue";
import echarts from "echarts";
import { achievement } from "@/api/website/home/index";
const { proxy } = getCurrentInstance();
const loading = shallowRef(true);
let treeData = {
340000: {
code: "340000",
name: "安徽省",
count: 107,
industry: { "1-1": 2, "1-2": 1, "2-1": 3 },
children: {
340100: {
code: "340100",
name: "合肥市",
count: 106,
industry: { "1-1": 1, "1-2": 1, "2-1": 2 },
children: {
340111: {
code: "340111",
name: "包河区",
count: 105,
industry: { "1-1": 1, "2-1": 1 },
children: null,
},
340121: {
code: "340121",
name: "长丰县",
count: 105,
industry: { "1-2": 1, "2-1": 1 },
children: null,
},
},
},
340200: {
code: "340200",
name: "芜湖市",
count: 105,
industry: { "1-1": 1, "2-1": 1 },
children: {},
},
},
},
500000: {
code: "500000",
name: "重庆",
count: 300,
industry: null,
children: {
500100: {
code: "500100",
name: "市辖区",
count: 300,
industry: null,
children: null,
},
},
},
630000: {
code: "630000",
name: "青海省",
count: 1200,
industry: null,
children: {
630200: {
code: "630200",
name: "海东市",
count: 1200,
industry: null,
children: null,
},
},
},
};
const snapTree = shallowRef({});
function searchRegionData(code) {
// console.log(code, treeData,'searchRegionData')
return deepFindTree(code, treeData);
}
function deepFindTree(code, tree) {
let snap = false;
for (const key in tree) {
if (Object.hasOwnProperty.call(tree, key)) {
if (code == key) {
snap = tree[code];
break;
} else if (tree[key]["children"] != null) {
snap = deepFindTree(code, tree[key]["children"]);
if (snap) {
break;
}
} else {
snap = false;
}
}
}
return snap;
}
function getIndustry(object) {
let snap = {};
for (const key in object) {
if (Object.hasOwnProperty.call(object, key)) {
const element = object[key];
if (element["industry"] != null) {
for (const ek in element["industry"]) {
if (Object.hasOwnProperty.call(element["industry"], ek)) {
const ele = element["industry"][ek];
if (!Object.hasOwnProperty.call(snap, ek)) {
snap[ek] = 0;
}
snap[ek] += ele;
}
}
// for (let index = 0; index < element['industry'].length; index++) {
// const ele = element['industry'][index];
// if(Object.hasOwnProperty.call(snap, ele)) {
// }
// }
}
}
}
return snap;
}
const state = reactive({
loading: false,
isShowGoBack: false,
nameType: "",
// cityName: "中国",
cityName: "china",
areaCode: 10000,
AreaCodeStack: ["中国"],
geoJsonData: "",
echartsMap: null,
map: null,
uimap: null,
district: null,
polygons: [],
cityCode: "100000",
citySelect: null,
districtSelect: null,
opts: {},
areaData: {},
mapData: [],
zip: {}, //打包zip
codeList: [],
isCodeListLoadComplete: false, //codeList是否全部获取完毕
downloadTips: "下载geoJson数据", //下载进度提示
isShowTips: false, //是否显示下载提示
});
onMounted(() => {
// 数据接口
achievement().then((res) => {
if (200 == res.code) {
treeData = res.data;
snapTree.value = res.data;
loading.value = false;
}
});
// let echartsDomList = document.querySelectorAll('.echartsDom');
// // 兼容echarts
// echartsDomList.forEach(element => {
// element.style.zoom = window.devicePixelRatio;
// element.style.transform = "scale(" + (1 / window.devicePixelRatio) + ")";
// element.style.transformOrigin = "0%0%";
// element.style.width = window.devicePixelRatio * 100 + '%';
// element.style.height = window.devicePixelRatio * 100 + '%';
// console.log(element.style.zoom, 'element.style.zoom')
// });
let height = document.body.clientHeight;
let width = document.body.clientWidth;
let dom = proxy.$refs["map"];
dom.style.width = width + "px";
dom.style.height = height - 80 + "px";
state.echartsMap = echarts.init(dom);
state.echartsMap.on("click", echartsMapClick);
setTimeout(() => {
state.map = new AMap.Map("container", {
resizeEnable: true,
center: [116.30946, 39.937629],
zoom: 3,
});
state.opts = {
subdistrict: 1, //返回下一级行政区
showbiz: false, //最后一级返回街道信息
};
state.district = new AMap.DistrictSearch(state.opts); //注意:需要使用插件同步下发功能才能这样直接使用
state.district.search("中国", (status, result) => {
if (status == "complete") {
getData(result.districtList[0], "", 100000);
}
});
}, 3000);
});
function goBack() {
state.isShowGoBack = false;
loading.value = true;
state.district.search("中国", (status, result) => {
if (status == "complete") {
getData(result.districtList[0], "", 100000);
snapTree.value = treeData;
}
});
}
function echartsMapClick(params) {
//地图点击事件
if (params.data.cityCode == "710000") {
return;
}
if (params.data.level == "district") {
return;
}
if (params.data.level == "street") return; //此处的params.data为state.mapData里的数据
let snap = searchRegionData(params.data.cityCode);
snapTree.value = {};
if (snap) {
snapTree.value = snap["children"];
}
state.cityCode = params.data.cityCode;
state.cityName = params.data.name;
state.district.setLevel(params.data.level); //行政区级别
state.district.setExtensions("all");
state.isShowGoBack = true;
loading.value = true;
//行政区查询
//按照adcode进行查询可以保证数据返回的唯一性
state.district.search(state.cityCode, (status, result) => {
if (status === "complete") {
if (params.data.level == "district") {
return;
}
state.AreaCodeStack.push(result.districtList[0].adcode);
getData(result.districtList[0], params.data.level, state.cityCode); //这个getData函数在前面已经定义过了
}
});
}
function getData(data, level, adcode) {
//处理获取出来的边界数据
var subList = data.districtList;
if (subList) {
var curlevel = subList[0].level;
if (curlevel === "street") {
//为了配合echarts地图区县名称显示正常这边街道级别数据需要特殊处理
let mapJsonList = state.geoJsonData.features;
let mapJson = {};
for (let i in mapJsonList) {
if (mapJsonList[i].properties.name == state.cityName) {
mapJson["features"] = [].concat(mapJsonList[i]);
}
}
state.mapData = [];
let item = searchRegionData(cityCode);
if (item) {
console.log("1 searchRegionData(cityCode)", item);
}
//这个mapData里包含每个区域的code、名称、对应的等级实现第三步功能时能用上
state.mapData.push({
name: state.cityName,
value: item ? item.count : 0,
level: curlevel,
});
loadMap(state.cityName, mapJson);
state.geoJsonData = mapJson;
return;
}
//街道级以上的数据处理方式
state.mapData = [];
for (var i = 0, l = subList.length; i < l; i++) {
var name = subList[i].name;
var cityCode = subList[i].adcode;
//这个mapData里包含每个区域的code、名称、对应的等级实现第三步功能时能用上
let item = searchRegionData(cityCode);
if (item) {
console.log("2 searchRegionData(cityCode)", item);
}
state.mapData.push({
name: name,
value: item ? item.count : 0,
cityCode: cityCode,
level: curlevel,
});
}
loadMapData(adcode);
}
}
function loadMapData(areaCode) {
AMapUI.loadUI(["geo/DistrictExplorer"], (DistrictExplorer) => {
//创建一个实例
var districtExplorer = (window.districtExplorer = new DistrictExplorer({
eventSupport: true, //打开事件支持
map: state.map,
}));
districtExplorer.loadAreaNode(areaCode, (error, areaNode) => {
if (error) {
console.error(error);
return;
}
let mapJson = {};
//特别注意这里哦如果查看过正常的geojson文件都会发现文件都是以features 字段开头的,所以这里要记得加上
mapJson.features = areaNode.getSubFeatures();
console.log("------------------");
for (var i = 0; i < mapJson.features.length; i++) {
if (
mapJson.features[i].properties.adcode == 810000 ||
mapJson.features[i].properties.adcode == 820000
) {
mapJson.features.splice(i, 1); // 删除下标为i 的元素i开始只删除一个就它自己了
i--; // 删除一个元素后数组长度减一了
}
}
console.log("------------------");
loadMap(state.cityName, mapJson);
});
});
}
function loadMap(mapName, data) {
if (data) {
echarts.registerMap(mapName, data); //把geoJson数据注入echarts
//配置echarts的option
var option = {
visualMap: {
type: "piecewise",
left: "center", //组件离容器左侧的距离,'left', 'center', 'right','20%'
bottom: "30",
orient: "horizontal", //图例排列方向
padding: 5,
pieces: [
{ gte: 0, lte: 99, label: "99", color: "#CAE9FD" },
{ gte: 100, lte: 299, label: "100-299", color: "#7ED2F7" },
{ gte: 300, lte: 499, label: "299-499", color: "#039DDD" },
{ gte: 500, label: "500", color: "#0D4884" },
// {max: 30, label: '安全', color: '#2c9a42'},
// {min: 30, max: 60, label: '警告', color: '#d08a00'},
// {min: 60, label: '危险', color: '#c23c33'},
],
// color: '#fff',
textStyle: {
color: "#fff",
},
visibility: "off",
},
tooltip: {
//提示框信息
trigger: "item",
formatter: "{b}\n{c}个",
},
series: [
{
name: "数据名称",
type: "map",
roam: false,
top: "15%",
bottom: state.isShowGoBack ? "8%" : "-20%",
mapType: mapName,
selectedMode: "single",
showLegendSymbol: false,
visibility: "off",
backgroundColor: "transparent",
itemStyle: {
normal: {
color: "#333333",
areaColor: "#fff",
borderColor: "#666666",
borderWidth: 0.5,
label: {
show: true,
textStyle: {
color: "#333333",
},
},
},
emphasis: {
areaColor: "rgb(38, 219, 11)",
borderColor: "#666666",
areaStyle: {
color: "#333333",
},
label: {
show: true,
textStyle: {
color: "#333333",
},
// formatter: function (value) { //标签的格式化工具。
// return value.name + '' + value.value; // 范围标签显示内容。
// }
},
},
},
data: state.mapData, //这个data里包含每个区域的code、名称、对应的等级实现第三步功能时能用上
},
],
};
state.echartsMap.setOption(option);
loading.value = false;
}
}
</script>
<style lang="scss" scoped>
.box3 {
width: 100%;
height: 100%;
background: linear-gradient(0deg, #010101, #041744);
position: relative;
.tit {
position: absolute;
top: 75px;
width: 100%;
text-align: center;
font-size: 36px;
font-family: Source Han Sans CN;
font-weight: 300;
color: #ffffff;
}
}
.map {
width: 100%;
height: 100%;
background-image: url(./img/lightEffect.png);
background-size: 644px 272px;
background-repeat: no-repeat;
background-position: center top;
}
.close-back {
background: url(img/close_back.png) no-repeat;
transition: all 0.5s;
height: 70px;
width: 85px;
color: #fff;
left: 65px;
position: absolute;
top: 100px;
cursor: pointer;
z-index: 1000;
&:hover {
left: 55px;
}
img {
margin: 28px auto 0;
width: 30px;
display: block;
transition: all 0.5s;
}
}
.leftBox {
left: 6%;
}
.rightBox {
right: 6%;
max-height: 465px !important;
}
.leftBox,
.rightBox {
position: absolute;
top: 25%;
max-width: 250px;
min-width: 200px;
max-height: 256px;
overflow: hidden;
background: rgba(4, 22, 65, 0.5);
border: 1px solid #0054ff;
color: rgba(161, 192, 255, 1);
& > div {
display: flex;
}
.head {
border-bottom: 1px solid #0054ff;
color: #ffffff;
}
.a {
flex: 1;
border-right: 1px solid #0054ff;
text-align: center;
line-height: 42px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.b {
text-align: center;
line-height: 42px;
width: 90px;
}
}
</style>

View File

@ -0,0 +1,546 @@
<template>
<div class="box3" v-loading="loading">
<div class="tit">需求分布地图</div>
<div v-if="state.isShowGoBack" class="close-back" @click="goBack">
<img src="./img/back_button.png" />
</div>
<!-- echartsDom 兼容缩放 -->
<div ref="map" class="map echartsDom" id="map"></div>
<div class="leftBox">
<div class="head">
<div class="a">地区</div>
<div class="b">需求数量</div>
</div>
<div v-if="Object.keys(snapTree).length > 0" v-for="v in snapTree">
<div class="a">{{ v.name }}</div>
<div class="b">{{ v.count }}</div>
</div>
<div v-else>
<div class="a">暂无</div>
<div class="b">暂无</div>
</div>
</div>
<div class="rightBox">
<div class="head">
<div class="a">领域</div>
<div class="b">需求数量</div>
</div>
<div
v-if="Object.keys(getIndustry(snapTree)).length > 0"
v-for="(v, k) in getIndustry(snapTree)"
>
<div class="a" :title="k">{{ k }}</div>
<div class="b">{{ v }}</div>
</div>
<div v-else>
<div class="a">暂无</div>
<div class="b">暂无</div>
</div>
</div>
</div>
</template>
<script setup>
import { defineComponent, getCurrentInstance, onMounted, reactive } from "vue";
import echarts from "echarts";
import { demand } from "@/api/website/home/index";
const { proxy } = getCurrentInstance();
const loading = shallowRef(true);
let treeData = {
340000: {
code: "340000",
name: "安徽省",
count: 107,
industry: { "1-1": 2, "1-2": 1, "2-1": 3 },
children: {
340100: {
code: "340100",
name: "合肥市",
count: 106,
industry: { "1-1": 1, "1-2": 1, "2-1": 2 },
children: {
340111: {
code: "340111",
name: "包河区",
count: 105,
industry: { "1-1": 1, "2-1": 1 },
children: null,
},
340121: {
code: "340121",
name: "长丰县",
count: 105,
industry: { "1-2": 1, "2-1": 1 },
children: null,
},
},
},
340200: {
code: "340200",
name: "芜湖市",
count: 105,
industry: { "1-1": 1, "2-1": 1 },
children: {},
},
},
},
500000: {
code: "500000",
name: "重庆",
count: 300,
industry: null,
children: {
500100: {
code: "500100",
name: "市辖区",
count: 300,
industry: null,
children: null,
},
},
},
630000: {
code: "630000",
name: "青海省",
count: 1200,
industry: null,
children: {
630200: {
code: "630200",
name: "海东市",
count: 1200,
industry: null,
children: null,
},
},
},
};
const snapTree = shallowRef({});
function searchRegionData(code) {
// console.log(code, treeData,'searchRegionData')
return deepFindTree(code, treeData);
}
function deepFindTree(code, tree) {
let snap = false;
for (const key in tree) {
if (Object.hasOwnProperty.call(tree, key)) {
if (code == key) {
snap = tree[code];
break;
} else if (tree[key]["children"] != null) {
snap = deepFindTree(code, tree[key]["children"]);
if (snap) {
break;
}
} else {
snap = false;
}
}
}
return snap;
}
function getIndustry(object) {
let snap = {};
for (const key in object) {
if (Object.hasOwnProperty.call(object, key)) {
const element = object[key];
if (element["industry"] != null) {
for (const ek in element["industry"]) {
if (Object.hasOwnProperty.call(element["industry"], ek)) {
const ele = element["industry"][ek];
if (!Object.hasOwnProperty.call(snap, ek)) {
snap[ek] = 0;
}
snap[ek] += ele;
}
}
// for (let index = 0; index < element['industry'].length; index++) {
// const ele = element['industry'][index];
// if(Object.hasOwnProperty.call(snap, ele)) {
// }
// }
}
}
}
return snap;
}
const state = reactive({
loading: false,
isShowGoBack: false,
nameType: "",
// cityName: "中国",
cityName: "china",
areaCode: 10000,
AreaCodeStack: ["中国"],
geoJsonData: "",
echartsMap: null,
map: null,
uimap: null,
district: null,
polygons: [],
cityCode: "100000",
citySelect: null,
districtSelect: null,
opts: {},
areaData: {},
mapData: [],
zip: {}, //打包zip
codeList: [],
isCodeListLoadComplete: false, //codeList是否全部获取完毕
downloadTips: "下载geoJson数据", //下载进度提示
isShowTips: false, //是否显示下载提示
});
onMounted(() => {
// 数据接口
demand().then((res) => {
if (200 == res.code) {
treeData = res.data;
snapTree.value = res.data;
loading.value = false;
}
});
// let echartsDomList = document.querySelectorAll('.echartsDom');
// // 兼容echarts
// echartsDomList.forEach(element => {
// element.style.zoom = window.devicePixelRatio;
// element.style.transform = "scale(" + (1 / window.devicePixelRatio) + ")";
// element.style.transformOrigin = "0%0%";
// element.style.width = window.devicePixelRatio * 100 + '%';
// element.style.height = window.devicePixelRatio * 100 + '%';
// console.log(element.style.zoom, 'element.style.zoom')
// });
let height = document.body.clientHeight;
let width = document.body.clientWidth;
let dom = proxy.$refs["map"];
dom.style.width = width + "px";
dom.style.height = height - 80 + "px";
state.echartsMap = echarts.init(dom);
state.echartsMap.on("click", echartsMapClick);
setTimeout(() => {
state.map = new AMap.Map("container", {
resizeEnable: true,
center: [116.30946, 39.937629],
zoom: 3,
});
state.opts = {
subdistrict: 1, //返回下一级行政区
showbiz: false, //最后一级返回街道信息
};
state.district = new AMap.DistrictSearch(state.opts); //注意:需要使用插件同步下发功能才能这样直接使用
state.district.search("中国", (status, result) => {
if (status == "complete") {
getData(result.districtList[0], "", 100000);
}
});
}, 4000);
});
function goBack() {
state.isShowGoBack = false;
loading.value = true;
state.district.search("中国", (status, result) => {
if (status == "complete") {
getData(result.districtList[0], "", 100000);
snapTree.value = treeData;
}
});
}
function echartsMapClick(params) {
//地图点击事件
if (params.data.cityCode == "710000") {
return;
}
if (params.data.level == "district") {
return;
}
if (params.data.level == "street") return; //此处的params.data为state.mapData里的数据
let snap = searchRegionData(params.data.cityCode);
snapTree.value = {};
if (snap) {
snapTree.value = snap["children"];
}
state.cityCode = params.data.cityCode;
state.cityName = params.data.name;
state.district.setLevel(params.data.level); //行政区级别
state.district.setExtensions("all");
state.isShowGoBack = true;
loading.value = true;
//行政区查询
//按照adcode进行查询可以保证数据返回的唯一性
state.district.search(state.cityCode, (status, result) => {
if (status === "complete") {
if (params.data.level == "district") {
return;
}
state.AreaCodeStack.push(result.districtList[0].adcode);
getData(result.districtList[0], params.data.level, state.cityCode); //这个getData函数在前面已经定义过了
}
});
}
function getData(data, level, adcode) {
//处理获取出来的边界数据
var subList = data.districtList;
if (subList) {
var curlevel = subList[0].level;
if (curlevel === "street") {
//为了配合echarts地图区县名称显示正常这边街道级别数据需要特殊处理
let mapJsonList = state.geoJsonData.features;
let mapJson = {};
for (let i in mapJsonList) {
if (mapJsonList[i].properties.name == state.cityName) {
mapJson["features"] = [].concat(mapJsonList[i]);
}
}
state.mapData = [];
let item = searchRegionData(cityCode);
if (item) {
console.log("1 searchRegionData(cityCode)", item);
}
//这个mapData里包含每个区域的code、名称、对应的等级实现第三步功能时能用上
state.mapData.push({
name: state.cityName,
value: item ? item.count : 0,
level: curlevel,
});
loadMap(state.cityName, mapJson);
state.geoJsonData = mapJson;
return;
}
//街道级以上的数据处理方式
state.mapData = [];
for (var i = 0, l = subList.length; i < l; i++) {
var name = subList[i].name;
var cityCode = subList[i].adcode;
//这个mapData里包含每个区域的code、名称、对应的等级实现第三步功能时能用上
let item = searchRegionData(cityCode);
if (item) {
console.log("2 searchRegionData(cityCode)", item);
}
state.mapData.push({
name: name,
value: item ? item.count : 0,
cityCode: cityCode,
level: curlevel,
});
}
loadMapData(adcode);
}
}
function loadMapData(areaCode) {
AMapUI.loadUI(["geo/DistrictExplorer"], (DistrictExplorer) => {
//创建一个实例
var districtExplorer = (window.districtExplorer = new DistrictExplorer({
eventSupport: true, //打开事件支持
map: state.map,
}));
districtExplorer.loadAreaNode(areaCode, (error, areaNode) => {
if (error) {
console.error(error);
return;
}
let mapJson = {};
//特别注意这里哦如果查看过正常的geojson文件都会发现文件都是以features 字段开头的,所以这里要记得加上
mapJson.features = areaNode.getSubFeatures();
console.log("------------------");
for (var i = 0; i < mapJson.features.length; i++) {
if (
mapJson.features[i].properties.adcode == 810000 ||
mapJson.features[i].properties.adcode == 820000
) {
mapJson.features.splice(i, 1); // 删除下标为i 的元素i开始只删除一个就它自己了
i--; // 删除一个元素后数组长度减一了
}
}
console.log("------------------");
loadMap(state.cityName, mapJson);
});
});
}
function loadMap(mapName, data) {
if (data) {
echarts.registerMap(mapName, data); //把geoJson数据注入echarts
//配置echarts的option
var option = {
visualMap: {
type: "piecewise",
left: "center", //组件离容器左侧的距离,'left', 'center', 'right','20%'
bottom: "30",
orient: "horizontal", //图例排列方向
padding: 5,
pieces: [
{ gte: 0, lte: 99, label: "99", color: "#CAE9FD" },
{ gte: 100, lte: 299, label: "100-299", color: "#7ED2F7" },
{ gte: 300, lte: 499, label: "299-499", color: "#039DDD" },
{ gte: 500, label: "500", color: "#0D4884" },
// {max: 30, label: '安全', color: '#2c9a42'},
// {min: 30, max: 60, label: '警告', color: '#d08a00'},
// {min: 60, label: '危险', color: '#c23c33'},
],
// color: '#fff',
textStyle: {
color: "#333333",
},
visibility: "off",
},
tooltip: {
//提示框信息
trigger: "item",
formatter: "{b}\n{c}个",
},
series: [
{
name: "数据名称",
type: "map",
roam: false,
top: "15%",
bottom: state.isShowGoBack ? "8%" : "-20%",
mapType: mapName,
selectedMode: "single",
showLegendSymbol: false,
visibility: "off",
backgroundColor: "transparent",
itemStyle: {
normal: {
color: "#333333",
areaColor: "#fff",
borderColor: "#666666",
borderWidth: 0.5,
label: {
show: true,
textStyle: {
color: "#333333",
},
},
},
emphasis: {
areaColor: "rgb(38, 219, 11)",
borderColor: "#666666",
areaStyle: {
color: "#333333",
},
label: {
show: true,
textStyle: {
color: "#333333",
},
// formatter: function (value) { //标签的格式化工具。
// return value.name + '' + value.value; // 范围标签显示内容。
// }
},
},
},
data: state.mapData, //这个data里包含每个区域的code、名称、对应的等级实现第三步功能时能用上
},
],
};
state.echartsMap.setOption(option);
loading.value = false;
}
}
</script>
<style lang="scss" scoped>
.box3 {
width: 100%;
height: 100%;
position: relative;
.tit {
position: absolute;
top: 75px;
width: 100%;
text-align: center;
font-size: 36px;
font-family: Source Han Sans CN;
font-weight: 300;
color: #333333;
}
}
.map {
width: 100%;
height: 100%;
// background-image: url(./img/lightEffect.png);
background-size: 644px 272px;
background-repeat: no-repeat;
background-position: center top;
}
.close-back {
background: url(img/close_back.png) no-repeat;
transition: all 0.5s;
height: 70px;
width: 85px;
color: #fff;
left: 65px;
position: absolute;
top: 100px;
cursor: pointer;
z-index: 1000;
&:hover {
left: 55px;
}
img {
margin: 28px auto 0;
width: 30px;
display: block;
transition: all 0.5s;
}
}
.leftBox {
left: 6%;
}
.rightBox {
right: 6%;
max-height: 465px !important;
}
.leftBox,
.rightBox {
position: absolute;
top: 25%;
max-width: 250px;
min-width: 200px;
max-height: 256px;
overflow: hidden;
border: 1px solid #dcdcdc;
color: #666666;
& > div {
display: flex;
}
.head {
border-bottom: 1px solid #dcdcdc;
color: #333333;
}
.a {
flex: 1;
border-right: 1px solid #dcdcdc;
text-align: center;
line-height: 42px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.b {
text-align: center;
line-height: 42px;
width: 90px;
}
}
</style>

View File

@ -0,0 +1,548 @@
<template>
<div class="box3" v-loading="loading">
<div class="tit">企业地图</div>
<div v-if="state.isShowGoBack" class="close-back" @click="goBack">
<img src="./img/back_button.png" />
</div>
<!-- echartsDom 兼容缩放 -->
<div ref="map" class="map echartsDom" id="map"></div>
<div class="leftBox">
<div class="head">
<div class="a">地区</div>
<div class="b">企业数量</div>
</div>
<div v-if="Object.keys(snapTree).length > 0" v-for="v in snapTree">
<div class="a">{{ v.name }}</div>
<div class="b">{{ v.count }}</div>
</div>
<div v-else>
<div class="a">暂无</div>
<div class="b">暂无</div>
</div>
</div>
<div class="rightBox">
<div class="head">
<div class="a">领域</div>
<div class="b">企业数量</div>
</div>
<div
v-if="Object.keys(getIndustry(snapTree)).length > 0"
v-for="(v, k) in getIndustry(snapTree)"
>
<div class="a" :title="k">{{ k }}</div>
<div class="b">{{ v }}</div>
</div>
<div v-else>
<div class="a">暂无</div>
<div class="b">暂无</div>
</div>
</div>
</div>
</template>
<script setup>
import { defineComponent, getCurrentInstance, onMounted, reactive } from "vue";
import echarts from "echarts";
import { company } from "@/api/website/home/index";
const { proxy } = getCurrentInstance();
const loading = shallowRef(true);
let treeData = {
340000: {
code: "340000",
name: "安徽省",
count: 107,
industry: { "1-1": 2, "1-2": 1, "2-1": 3 },
children: {
340100: {
code: "340100",
name: "合肥市",
count: 106,
industry: { "1-1": 1, "1-2": 1, "2-1": 2 },
children: {
340111: {
code: "340111",
name: "包河区",
count: 105,
industry: { "1-1": 1, "2-1": 1 },
children: null,
},
340121: {
code: "340121",
name: "长丰县",
count: 105,
industry: { "1-2": 1, "2-1": 1 },
children: null,
},
},
},
340200: {
code: "340200",
name: "芜湖市",
count: 105,
industry: { "1-1": 1, "2-1": 1 },
children: {},
},
},
},
500000: {
code: "500000",
name: "重庆",
count: 300,
industry: null,
children: {
500100: {
code: "500100",
name: "市辖区",
count: 300,
industry: null,
children: null,
},
},
},
630000: {
code: "630000",
name: "青海省",
count: 1200,
industry: null,
children: {
630200: {
code: "630200",
name: "海东市",
count: 1200,
industry: null,
children: null,
},
},
},
};
const snapTree = shallowRef({});
function searchRegionData(code) {
// console.log(code, treeData,'searchRegionData')
return deepFindTree(code, treeData);
}
function deepFindTree(code, tree) {
let snap = false;
for (const key in tree) {
if (Object.hasOwnProperty.call(tree, key)) {
if (code == key) {
snap = tree[code];
break;
} else if (tree[key]["children"] != null) {
snap = deepFindTree(code, tree[key]["children"]);
if (snap) {
break;
}
} else {
snap = false;
}
}
}
return snap;
}
function getIndustry(object) {
let snap = {};
for (const key in object) {
if (Object.hasOwnProperty.call(object, key)) {
const element = object[key];
if (element["industry"] != null) {
for (const ek in element["industry"]) {
if (Object.hasOwnProperty.call(element["industry"], ek)) {
const ele = element["industry"][ek];
if (!Object.hasOwnProperty.call(snap, ek)) {
snap[ek] = 0;
}
snap[ek] += ele;
}
}
// for (let index = 0; index < element['industry'].length; index++) {
// const ele = element['industry'][index];
// if(Object.hasOwnProperty.call(snap, ele)) {
// }
// }
}
}
}
return snap;
}
const state = reactive({
loading: false,
isShowGoBack: false,
nameType: "",
// cityName: "中国",
cityName: "china",
areaCode: 10000,
AreaCodeStack: ["中国"],
geoJsonData: "",
echartsMap: null,
map: null,
uimap: null,
district: null,
polygons: [],
cityCode: "100000",
citySelect: null,
districtSelect: null,
opts: {},
areaData: {},
mapData: [],
zip: {}, //打包zip
codeList: [],
isCodeListLoadComplete: false, //codeList是否全部获取完毕
downloadTips: "下载geoJson数据", //下载进度提示
isShowTips: false, //是否显示下载提示
});
onMounted(() => {
// 数据接口
company().then((res) => {
if (200 == res.code) {
treeData = res.data;
snapTree.value = res.data;
loading.value = false;
}
});
// let echartsDomList = document.querySelectorAll('.echartsDom');
// // 兼容echarts
// echartsDomList.forEach(element => {
// element.style.zoom = window.devicePixelRatio;
// element.style.transform = "scale(" + (1 / window.devicePixelRatio) + ")";
// element.style.transformOrigin = "0%0%";
// element.style.width = window.devicePixelRatio * 100 + '%';
// element.style.height = window.devicePixelRatio * 100 + '%';
// console.log(element.style.zoom, 'element.style.zoom')
// });
let height = document.body.clientHeight;
let width = document.body.clientWidth;
let dom = proxy.$refs["map"];
dom.style.width = width + "px";
dom.style.height = height - 80 + "px";
state.echartsMap = echarts.init(dom);
state.echartsMap.on("click", echartsMapClick);
setTimeout(() => {
state.map = new AMap.Map("container", {
resizeEnable: true,
center: [116.30946, 39.937629],
zoom: 3,
});
state.opts = {
subdistrict: 1, //返回下一级行政区
showbiz: false, //最后一级返回街道信息
};
state.district = new AMap.DistrictSearch(state.opts); //注意:需要使用插件同步下发功能才能这样直接使用
state.district.search("中国", (status, result) => {
if (status == "complete") {
getData(result.districtList[0], "", 100000);
}
});
}, 5000);
});
function goBack() {
state.isShowGoBack = false;
loading.value = true;
state.district.search("中国", (status, result) => {
if (status == "complete") {
getData(result.districtList[0], "", 100000);
snapTree.value = treeData;
}
});
}
function echartsMapClick(params) {
//地图点击事件
if (params.data.cityCode == "710000") {
return;
}
if (params.data.level == "district") {
return;
}
if (params.data.level == "street") return; //此处的params.data为state.mapData里的数据
let snap = searchRegionData(params.data.cityCode);
snapTree.value = {};
if (snap) {
snapTree.value = snap["children"];
}
state.cityCode = params.data.cityCode;
state.cityName = params.data.name;
state.district.setLevel(params.data.level); //行政区级别
state.district.setExtensions("all");
state.isShowGoBack = true;
loading.value = true;
//行政区查询
//按照adcode进行查询可以保证数据返回的唯一性
state.district.search(state.cityCode, (status, result) => {
if (status === "complete") {
if (params.data.level == "district") {
return;
}
state.AreaCodeStack.push(result.districtList[0].adcode);
getData(result.districtList[0], params.data.level, state.cityCode); //这个getData函数在前面已经定义过了
}
});
}
function getData(data, level, adcode) {
//处理获取出来的边界数据
var subList = data.districtList;
if (subList) {
var curlevel = subList[0].level;
if (curlevel === "street") {
//为了配合echarts地图区县名称显示正常这边街道级别数据需要特殊处理
let mapJsonList = state.geoJsonData.features;
let mapJson = {};
for (let i in mapJsonList) {
if (mapJsonList[i].properties.name == state.cityName) {
mapJson["features"] = [].concat(mapJsonList[i]);
}
}
state.mapData = [];
let item = searchRegionData(cityCode);
if (item) {
console.log("1 searchRegionData(cityCode)", item);
}
//这个mapData里包含每个区域的code、名称、对应的等级实现第三步功能时能用上
state.mapData.push({
name: state.cityName,
value: item ? item.count : 0,
level: curlevel,
});
loadMap(state.cityName, mapJson);
state.geoJsonData = mapJson;
return;
}
//街道级以上的数据处理方式
state.mapData = [];
for (var i = 0, l = subList.length; i < l; i++) {
var name = subList[i].name;
var cityCode = subList[i].adcode;
//这个mapData里包含每个区域的code、名称、对应的等级实现第三步功能时能用上
let item = searchRegionData(cityCode);
if (item) {
console.log("2 searchRegionData(cityCode)", item);
}
state.mapData.push({
name: name,
value: item ? item.count : 0,
cityCode: cityCode,
level: curlevel,
});
}
loadMapData(adcode);
}
}
function loadMapData(areaCode) {
AMapUI.loadUI(["geo/DistrictExplorer"], (DistrictExplorer) => {
//创建一个实例
var districtExplorer = (window.districtExplorer = new DistrictExplorer({
eventSupport: true, //打开事件支持
map: state.map,
}));
districtExplorer.loadAreaNode(areaCode, (error, areaNode) => {
if (error) {
console.error(error);
return;
}
let mapJson = {};
//特别注意这里哦如果查看过正常的geojson文件都会发现文件都是以features 字段开头的,所以这里要记得加上
mapJson.features = areaNode.getSubFeatures();
console.log("------------------");
for (var i = 0; i < mapJson.features.length; i++) {
if (
mapJson.features[i].properties.adcode == 810000 ||
mapJson.features[i].properties.adcode == 820000
) {
mapJson.features.splice(i, 1); // 删除下标为i 的元素i开始只删除一个就它自己了
i--; // 删除一个元素后数组长度减一了
}
}
console.log("------------------");
loadMap(state.cityName, mapJson);
});
});
}
function loadMap(mapName, data) {
if (data) {
echarts.registerMap(mapName, data); //把geoJson数据注入echarts
//配置echarts的option
var option = {
visualMap: {
type: "piecewise",
left: "center", //组件离容器左侧的距离,'left', 'center', 'right','20%'
bottom: "30",
orient: "horizontal", //图例排列方向
padding: 5,
pieces: [
{ gte: 0, lte: 99, label: "99", color: "#CAE9FD" },
{ gte: 100, lte: 299, label: "100-299", color: "#7ED2F7" },
{ gte: 300, lte: 499, label: "299-499", color: "#039DDD" },
{ gte: 500, label: "500", color: "#0D4884" },
// {max: 30, label: '安全', color: '#2c9a42'},
// {min: 30, max: 60, label: '警告', color: '#d08a00'},
// {min: 60, label: '危险', color: '#c23c33'},
],
// color: '#fff',
textStyle: {
color: "#fff",
},
visibility: "off",
},
tooltip: {
//提示框信息
trigger: "item",
formatter: "{b}\n{c}个",
},
series: [
{
name: "数据名称",
type: "map",
roam: false,
top: "15%",
bottom: state.isShowGoBack ? "8%" : "-20%",
mapType: mapName,
selectedMode: "single",
showLegendSymbol: false,
visibility: "off",
backgroundColor: "transparent",
itemStyle: {
normal: {
color: "#333333",
areaColor: "#fff",
borderColor: "#666666",
borderWidth: 0.5,
label: {
show: true,
textStyle: {
color: "#333333",
},
},
},
emphasis: {
areaColor: "rgb(38, 219, 11)",
borderColor: "#666666",
areaStyle: {
color: "#333333",
},
label: {
show: true,
textStyle: {
color: "#333333",
},
// formatter: function (value) { //标签的格式化工具。
// return value.name + '' + value.value; // 范围标签显示内容。
// }
},
},
},
data: state.mapData, //这个data里包含每个区域的code、名称、对应的等级实现第三步功能时能用上
},
],
};
state.echartsMap.setOption(option);
loading.value = false;
}
}
</script>
<style lang="scss" scoped>
.box3 {
width: 100%;
height: 100%;
background: linear-gradient(0deg, #010101, #041744);
position: relative;
.tit {
position: absolute;
top: 75px;
width: 100%;
text-align: center;
font-size: 36px;
font-family: Source Han Sans CN;
font-weight: 300;
color: #ffffff;
}
}
.map {
width: 100%;
height: 100%;
background-image: url(./img/lightEffect.png);
background-size: 644px 272px;
background-repeat: no-repeat;
background-position: center top;
}
.close-back {
background: url(img/close_back.png) no-repeat;
transition: all 0.5s;
height: 70px;
width: 85px;
color: #fff;
left: 65px;
position: absolute;
top: 100px;
cursor: pointer;
z-index: 1000;
&:hover {
left: 55px;
}
img {
margin: 28px auto 0;
width: 30px;
display: block;
transition: all 0.5s;
}
}
.leftBox {
left: 6%;
}
.rightBox {
right: 6%;
max-height: 465px !important;
}
.leftBox,
.rightBox {
position: absolute;
top: 25%;
max-width: 250px;
min-width: 200px;
max-height: 256px;
overflow: hidden;
background: rgba(4, 22, 65, 0.5);
border: 1px solid #0054ff;
color: rgba(161, 192, 255, 1);
& > div {
display: flex;
}
.head {
border-bottom: 1px solid #0054ff;
color: #ffffff;
}
.a {
flex: 1;
border-right: 1px solid #0054ff;
text-align: center;
line-height: 42px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.b {
text-align: center;
line-height: 42px;
width: 90px;
}
}
</style>

View File

@ -0,0 +1,133 @@
<template>
<div class="box">
<div class="wrap">
<div>
<div class="tit">全国服务站点</div>
<div class="content">
<div>
<div
class="item"
v-for="(value, key, index) in state.platformInfo"
:key="index"
>
<div>{{ value.name }}</div>
<p v-for="item in value.children" :key="item.code">
<a :href="item.domain" target="_blank" v-if="item.domain">{{
item.name
}}</a>
</p>
</div>
</div>
</div>
<div class="more" v-if="state.platformInfo.length > 15">查看更多</div>
</div>
</div>
<webFooter style="width: 100%"></webFooter>
</div>
</template>
<script setup lang="ts">
import request from "@/utils/request";
import { onMounted, reactive } from "vue";
import webFooter from "@/components/webFooter/index.vue";
function platform() {
return request({
url: "/v1/sys/platform",
});
}
const state = reactive({
platformInfo: {},
});
function getInfo() {
platform().then((res) => {
console.log(res);
state.platformInfo = res.data;
});
}
getInfo();
</script>
<style lang="scss" scoped>
.box {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
.wrap {
width: 100%;
height: 100%;
background-image: url(./img/index8-bg1.png);
background-size: 100% 50%;
background-repeat: no-repeat;
background-position: center bottom;
& > div {
flex: 1;
height: 100%;
width: 1000px;
margin: 0 auto;
padding: 10px 0;
box-sizing: border-box;
display: flex;
display: -webkit-flex;
align-items: center;
justify-content: space-evenly;
flex-direction: column;
}
.tit {
text-align: center;
font-size: 30px;
font-family: Source Han Sans CN;
font-weight: 400;
color: #333333;
}
.content {
font-size: 16px;
font-family: Source Han Sans CN;
font-weight: 500;
color: #333333;
display: flex;
display: -webkit-flex;
justify-content: center;
align-items: center;
flex-direction: column;
& > div {
overflow: hidden;
flex: 1;
}
.item {
width: 66px;
float: left;
a {
color: #0054ff;
}
p {
font-size: 14px;
font-family: Source Han Sans CN;
font-weight: 500;
color: #666666;
}
}
}
.more {
width: 150px;
height: 46px;
line-height: 44px;
border: 1px solid #0054ff;
font-size: 16px;
font-family: Source Han Sans CN;
font-weight: 500;
color: #0054ff;
text-align: center;
user-select: none;
cursor: pointer;
&:hover {
opacity: 0.7;
}
}
}
}
</style>

View File

@ -1,10 +1,268 @@
<template>
<div>
{{ msg }}
</div>
</template>
<script setup>
import { ref } from "vue";
<div v-loading="loading" class="fullPage" ref="fullPage">
<div class="fullPageContainer" ref="fullPageContainer">
<!-- <div
v-for="(item, $index) in state.boxList"
class="section"
:key="$index"
:style="`z-index: ${item.zIndex};`"
>
<component :is="item.comp"></component>
</div> -->
const msg = ref("hekko");
<!-- <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"
>
<div
v-for="(item, $index) in state.boxList"
class="box"
:key="$index"
:style="`z-index: ${item.zIndex};`"
v-show="state.showBox === $index"
>
<component :is="item.comp"></component>
</div>
</transition-group>
</div>-->
</template>
<script setup lang="ts">
import { ref } from "vue";
const loading = ref<boolean>(true);
// let state = reactive({
// fullpage: {
// current: 1, // 当前的页面编号
// isScrolling: false, // 是否在滚动,是为了防止滚动多页,需要通过一个变量来控制是否滚动
// deltaY: 0, // 返回鼠标滚轮的垂直滚动量保存的鼠标滚动事件的deleteY,用来判断是往下还是往上滚
// },
// showBox: 0,
// boxList: [
// {
// comp: index1,
// zIndex: 1,
// title: "index1",
// },
// {
// comp: index2,
// zIndex: 1,
// title: "index2",
// },
// {
// comp: index3,
// zIndex: 1,
// title: "index3",
// },
// {
// comp: index4,
// zIndex: 1,
// title: "index4",
// },
// {
// comp: index5,
// zIndex: 1,
// title: "index5",
// },
// {
// comp: index6,
// zIndex: 1,
// title: "index6",
// },
// {
// comp: index7,
// zIndex: 1,
// title: "index7",
// },
// {
// comp: index8,
// zIndex: 1,
// title: "index8",
// },
// ],
// animate: {
// in: "animate__animated animate__fadeInDown",
// out: "animate__animated animate__fadeOutDown",
// },
// });
// const 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();
// }
// };
</script>
<!-- <script setup lang="ts">
import { reactive, onMounted, getCurrentInstance, ref } from "vue";
const { proxy } = getCurrentInstance();
import index1 from "./comp/index1.vue";
import index2 from "./comp/index2.vue";
import index3 from "./comp/index3.vue";
import index4 from "./comp/index4.vue";
import index5 from "./comp/index5.vue";
import index6 from "./comp/index6.vue";
import index7 from "./comp/index7.vue";
import index8 from "./comp/index8.vue";
const loading = ref(true);
setTimeout(() => {
loading.value = false;
}, 1000);
onMounted(() => {});
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: [
{
comp: index1,
zIndex: 1,
title: "index1",
},
{
comp: index2,
zIndex: 1,
title: "index2",
},
{
comp: index3,
zIndex: 1,
title: "index3",
},
{
comp: index4,
zIndex: 1,
title: "index4",
},
{
comp: index5,
zIndex: 1,
title: "index5",
},
{
comp: index6,
zIndex: 1,
title: "index6",
},
{
comp: index7,
zIndex: 1,
title: "index7",
},
{
comp: index8,
zIndex: 1,
title: "index8",
},
],
animate: {
in: "animate__animated animate__fadeInDown",
out: "animate__animated animate__fadeOutDown",
},
});
</script> -->
<style lang="scss" scoped>
.fullPage {
width: 100%;
height: 100%;
overflow: hidden;
}
.fullPageContainer {
width: 100%;
height: 100%;
transition: all linear 0.5s;
}
.section {
width: 100%;
height: 100%;
background-position: center center;
background-repeat: no-repeat;
}
</style>

View File

@ -92,7 +92,7 @@
:model="registerForm"
status-icon
:rules="isCheckRules"
ref="isCheck"
ref="isCheckRef"
>
<el-form-item prop="isCheck">
<div style="margin-top: 43px">
@ -127,19 +127,21 @@
<script setup>
import Cookies from "js-cookie";
import { encrypt, decrypt } from "@/utils/jsencrypt";
// import { encrypt, decrypt } from "@/utils/jsencrypt";
import md5 from "js-md5";
import Register from "../register";
import Retrieve from "../retrieve";
import WebGetCode from "@/components/webGetCode";
import useUserStore from "@/store/modules/user";
import { useRouter } from "vue-router";
// const store = useStore();
const router = useRouter();
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
const isLogin = ref(1);
console.log(md5);
const loginForm = ref({
username: "18212342345",
password: "12342345",
@ -151,7 +153,8 @@ const loginForm = ref({
const registerForm = ref({
isCheck: true,
});
const loginRef = ref();
const isCheckRef = ref();
const disabled = ref(true);
const buttonName = ref("获取验证码");
const isDisabled = ref(false);
@ -180,12 +183,11 @@ const loading = ref(false);
const register = ref(true);
const redirect = ref(undefined);
function handleLogin() {
proxy.$refs.loginRef.validate((valid) => {
proxy.$refs.isCheck.validate((valid2) => {
if (valid && valid2) {
const handleLogin = async () => {
loginRef.value.validate((loginValid) => {
isCheckRef.value.validate((isCheckValid) => {
if (loginValid && isCheckValid) {
loading.value = true;
if (loginForm.value.rememberMe) {
Cookies.set("username", loginForm.value.username, { expires: 30 });
Cookies.set("password", loginForm.value.password, {
@ -217,7 +219,7 @@ function handleLogin() {
}
});
});
}
};
function getCookie() {
const username = Cookies.get("username");
@ -301,10 +303,10 @@ getCookie();
width: 14px;
margin-left: 2px;
}
::v-deep .el-tabs__active-bar {
:deep(.el-tabs__active-bar) {
background-color: #0054ff;
}
::v-deep .el-tabs__item {
:deep(.el-tabs__item) {
color: #666666;
font-size: 16px;
&.is-active {