bug fix and performance improvements
This commit is contained in:
16
index.html
16
index.html
@ -7,15 +7,21 @@
|
||||
<meta content="webkit" name="renderer">
|
||||
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
|
||||
<link href="/favicon.ico" rel="icon">
|
||||
<!-- <script type="text/javascript">-->
|
||||
<!-- window._AMapSecurityConfig = {-->
|
||||
<!-- securityJsCode: '7d1b758db4876389af608259c4c99832',-->
|
||||
<!-- }-->
|
||||
<!-- </script>-->
|
||||
<script type="text/javascript">
|
||||
window._AMapSecurityConfig = {
|
||||
securityJsCode: '7d1b758db4876389af608259c4c99832',
|
||||
securityJsCode: '2b65e7751cb17e4605f4c4cdccf885f6',
|
||||
// securityJsCode: '7d1b758db4876389af608259c4c99832',
|
||||
}
|
||||
</script>
|
||||
<script src='//webapi.amap.com/maps?v=1.4.15&key=bfc7224388e835679ffe74cfbd28c8d6' type="text/javascript"></script>
|
||||
<script src="https://webapi.amap.com/maps?v=1.4.11&key=bfc7224388e835679ffe74cfbd28c8d6&plugin=AMap.DistrictSearch"
|
||||
type="text/javascript"></script>
|
||||
<script src="//webapi.amap.com/ui/1.0/main.js?v=1.0.11"></script>
|
||||
<!-- <script src='//webapi.amap.com/maps?v=1.4.15&key=bfc7224388e835679ffe74cfbd28c8d6' type="text/javascript"></script>-->
|
||||
<!-- <script src="https://webapi.amap.com/maps?v=1.4.11&key=bfc7224388e835679ffe74cfbd28c8d6&plugin=AMap.DistrictSearch"-->
|
||||
<!-- type="text/javascript"></script>-->
|
||||
<!-- <script src="//webapi.amap.com/ui/1.0/main.js?v=1.0.11"></script>-->
|
||||
<title>中科云</title>
|
||||
<!--[if lt IE 11]>
|
||||
<script>window.location.href = '/html/ie.html';</script><![endif]-->
|
||||
|
@ -17,6 +17,7 @@
|
||||
"url": "https://gitee.com/y_project/RuoYi-Vue.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"@amap/amap-jsapi-loader": "^1.0.1",
|
||||
"@element-plus/icons-vue": "1.1.4",
|
||||
"@vueuse/core": "8.5.0",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
@ -29,6 +30,7 @@
|
||||
"element-plus": "2.1.8",
|
||||
"file-saver": "2.0.5",
|
||||
"fuse.js": "6.5.3",
|
||||
"html2canvas": "^1.4.1",
|
||||
"js-cookie": "3.0.1",
|
||||
"js-md5": "^0.7.3",
|
||||
"jsencrypt": "3.2.1",
|
||||
|
3715
src/assets/custom.geo.json
Normal file
3715
src/assets/custom.geo.json
Normal file
File diff suppressed because it is too large
Load Diff
1
src/assets/former-soviet-union-ussr_1371.json
Normal file
1
src/assets/former-soviet-union-ussr_1371.json
Normal file
File diff suppressed because one or more lines are too long
3
src/assets/geo_ru.json
Normal file
3
src/assets/geo_ru.json
Normal file
File diff suppressed because one or more lines are too long
BIN
src/assets/images/map_back.png
Normal file
BIN
src/assets/images/map_back.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 508 B |
1
src/assets/russia_geo.json
Normal file
1
src/assets/russia_geo.json
Normal file
File diff suppressed because one or more lines are too long
@ -138,7 +138,7 @@
|
||||
{{ t("headerMenu.personalCenter") }}
|
||||
</div>
|
||||
<div
|
||||
v-if="userStore.avatar"
|
||||
v-if="userStore.token"
|
||||
class="menu-item-tit"
|
||||
:class="pagePath == '/login' ? 'active' : ''"
|
||||
@click="logout"
|
||||
@ -181,7 +181,6 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ElMessageBox } from "element-plus";
|
||||
import { reactive, watch } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
|
||||
@ -190,6 +189,7 @@ import { getCategory } from "@/api/website/solution";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import useSettingsStore from "@/store/modules/settings";
|
||||
import defaultAvatar from "@/assets/logo/avatar.png";
|
||||
import modal from "@/plugins/modal";
|
||||
|
||||
const userStore = useUserStore();
|
||||
let state = reactive({});
|
||||
@ -245,11 +245,8 @@ function handlePath(path) {
|
||||
}
|
||||
|
||||
function logout() {
|
||||
ElMessageBox.confirm("确定注销并退出系统吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
modal
|
||||
.confirm(t("common.areYouSureYouWantToLogOutAndExitTheSystem"))
|
||||
.then(() => {
|
||||
useUserStore()
|
||||
.logOut()
|
||||
|
@ -131,7 +131,7 @@ function submitForm() {
|
||||
if (valid) {
|
||||
pubMessage(form.value).then((res) => {
|
||||
// proxy.$modal.msgSuccess(res.message);
|
||||
ElMessage.success("发送成功");
|
||||
ElMessage.success(t("tips.sendSuccess"));
|
||||
reset();
|
||||
});
|
||||
}
|
||||
|
@ -115,5 +115,7 @@ const form = {
|
||||
achievementPicture: "Изображение достижений",
|
||||
// 产品领域
|
||||
productField: "Область продукта",
|
||||
// 成熟度证明材料
|
||||
maturityProofMaterial: "Материалы подтверждения зрелости",
|
||||
};
|
||||
export default form;
|
||||
|
@ -113,6 +113,8 @@ const form = {
|
||||
achievementPicture: "成果图片",
|
||||
// 产品领域
|
||||
productField: "产品领域",
|
||||
// 成熟度证明材料
|
||||
maturityProofMaterial: "成熟度证明材料",
|
||||
};
|
||||
|
||||
export default form;
|
||||
|
@ -9,20 +9,28 @@ const tips = {
|
||||
reasonDescription: "Описание причины незавершенного проекта",
|
||||
browseEnterpriseInformation: "Просмотр информации о предприятии",
|
||||
moveToDraftBox: "Переместить в черновик",
|
||||
// 取消关联成功 取消发布成功 认领专利成功
|
||||
cancelAssociationSuccess: "Отмена связи прошла успешно",
|
||||
cancelReleaseSuccess: "Отмена публикации прошла успешно",
|
||||
claimPatentSuccess: "Патент успешно принят",
|
||||
// 解绑实验室成功
|
||||
unbindLabSuccess: "Успешно отвязана лаборатория",
|
||||
// 导入结果
|
||||
importResult: "Результат импорта",
|
||||
// 面议
|
||||
faceToFace: "По договоренности",
|
||||
|
||||
// 更新企业信息成功
|
||||
updateEnterpriseInformationSuccess:
|
||||
"Информация о предприятии успешно обновлена",
|
||||
pleaseEnterApplicant: "Пожалуйста, введите заявителя (разделите запятыми)",
|
||||
sendSuccess: "Отправлено успешно",
|
||||
applyForSettledSuccessfully: "Заявка на въезд успешно подана",
|
||||
reLogin: "Перезагрузить",
|
||||
loginStatusExpired:
|
||||
"Срок действия сеанса истек, вы можете остаться на этой странице или перезагрузить страницу",
|
||||
invalidSessionOrSessionExpired:
|
||||
"Недействительный сеанс или сеанс истек, пожалуйста, войдите снова.",
|
||||
downloadingData: "Загрузка данных, пожалуйста, подождите",
|
||||
backendInterfaceConnectionException:
|
||||
"Ошибка подключения к интерфейсу бэкэнда",
|
||||
// 下载文件出现错误,请联系管理员!
|
||||
downloadFileError:
|
||||
"Ошибка загрузки файла, пожалуйста, свяжитесь с администратором!",
|
||||
};
|
||||
|
||||
export default tips;
|
||||
|
@ -9,19 +9,23 @@ const tips = {
|
||||
reasonDescription: "未结题原因描述",
|
||||
browseEnterpriseInformation: "浏览企业信息",
|
||||
moveToDraftBox: "移到草稿箱",
|
||||
// 取消关联成功 取消发布成功 认领专利成功
|
||||
cancelAssociationSuccess: "取消关联成功",
|
||||
cancelReleaseSuccess: "取消发布成功",
|
||||
claimPatentSuccess: "认领专利成功",
|
||||
// 解绑实验室成功
|
||||
unbindLabSuccess: "解绑实验室成功",
|
||||
// 导入结果
|
||||
importResult: "导入结果",
|
||||
// 面议
|
||||
faceToFace: "面议",
|
||||
|
||||
// 更新企业信息成功
|
||||
updateEnterpriseInformationSuccess: "更新企业信息成功",
|
||||
pleaseEnterApplicant: "请输入申请(专利权)人(多个请以 , 分割)",
|
||||
sendSuccess: "发送成功",
|
||||
applyForSettledSuccessfully: "申请入驻成功",
|
||||
reLogin: "重新登录",
|
||||
loginStatusExpired: "登录状态已过期,您可以继续留在该页面,或者重新登录",
|
||||
invalidSessionOrSessionExpired: "无效的会话,或者会话已过期,请重新登录。",
|
||||
downloadingData: "正在下载数据,请稍候",
|
||||
backendInterfaceConnectionException: "后端接口连接异常",
|
||||
// 下载文件出现错误,请联系管理员!
|
||||
downloadFileError: "下载文件出现错误,请联系管理员!",
|
||||
};
|
||||
|
||||
export default tips;
|
||||
|
@ -93,7 +93,6 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ElMessageBox } from "element-plus";
|
||||
import Breadcrumb from "@/components/Breadcrumb";
|
||||
import TopNav from "@/components/TopNav";
|
||||
import Hamburger from "@/components/Hamburger";
|
||||
@ -101,20 +100,21 @@ import Screenfull from "@/components/Screenfull";
|
||||
import SizeSelect from "@/components/SizeSelect";
|
||||
import HeaderSearch from "@/components/HeaderSearch";
|
||||
import UserAvatar from "@/views/system/user/profile/userAvatar.vue";
|
||||
import RuoYiGit from "@/components/RuoYi/Git";
|
||||
import RuoYiDoc from "@/components/RuoYi/Doc";
|
||||
import useAppStore from "@/store/modules/app";
|
||||
import useUserStore from "@/store/modules/user";
|
||||
import useSettingsStore from "@/store/modules/settings";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { ref } from "vue";
|
||||
import defaultAvatar from "@/assets/logo/avatar.png";
|
||||
import modal from "@/plugins/modal";
|
||||
|
||||
const appStore = useAppStore();
|
||||
const userStore = useUserStore();
|
||||
const settingsStore = useSettingsStore();
|
||||
const { t, locale } = useI18n();
|
||||
const avatarRef = ref();
|
||||
const baseUrl = ref(import.meta.env.VITE_APP_BASE_API);
|
||||
|
||||
function toggleSideBar() {
|
||||
appStore.toggleSideBar();
|
||||
}
|
||||
@ -139,11 +139,8 @@ function handleCommand(command) {
|
||||
}
|
||||
|
||||
function logout() {
|
||||
ElMessageBox.confirm("确定注销并退出系统吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
modal
|
||||
.confirm(t("common.areYouSureYouWantToLogOutAndExitTheSystem"))
|
||||
.then(() => {
|
||||
userStore.logOut().then(() => {
|
||||
location.href = "/index";
|
||||
|
@ -35,26 +35,118 @@ export const enterpriseOptions = [
|
||||
{ key: "104", value: "高新技术企业" },
|
||||
{ key: "105", value: "科技企业" },
|
||||
];
|
||||
|
||||
// 基金对接-Фонд стыкуется
|
||||
// 委托研发-Поручить разработку
|
||||
// 海外留学生培养-Обучение иностранных студентов
|
||||
// 贷款-Кредиты
|
||||
// 对接专家院士-Академик - специалист по стыковке
|
||||
// 人才培养-Подготовка кадров
|
||||
// 一带一路国际合作-Международное сотрудничество
|
||||
// 上市辅导-Консультирование по листингу
|
||||
// 成果产业化-Индустриализация результатов
|
||||
// 国家级科研平台合作-Сотрудничество национальных научно - исследовательских платформ
|
||||
// 研发项目立项评估-Оценка проектов НИОКР
|
||||
// 科技查新-Новые технологии.
|
||||
// 产业链上下游对接-Промышленная цепочка вверх и вниз по течению
|
||||
// 知识产权布局-Распределение интеллектуальной собственности
|
||||
// 高价值专利培育-Высокая стоимость патентов
|
||||
// 技术咨询-Технические консультации
|
||||
// 对接政府项目落地-Посадка на правительственный проект
|
||||
// 设立院士工作站-Создание академической рабочей станции
|
||||
|
||||
// 需求类型
|
||||
export const demandCategoryList = [
|
||||
{ id: 1, name: "基金对接" },
|
||||
{ id: 2, name: "贷款" },
|
||||
{ id: 3, name: "对接专家院士" },
|
||||
{ id: 4, name: "人才培养" },
|
||||
{ id: 5, name: "一带一路国际合作" },
|
||||
{ id: 6, name: "上市辅导" },
|
||||
{ id: 7, name: "成果产业化" },
|
||||
{ id: 8, name: "国家级科研平台合作" },
|
||||
{ id: 9, name: "研发项目立项评估" },
|
||||
{ id: 10, name: "科技查新" },
|
||||
{ id: 11, name: "产业链上下游对接" },
|
||||
{ id: 12, name: "委托研发" },
|
||||
{ id: 13, name: "对接政府项目落地" },
|
||||
{ id: 14, name: "技术咨询" },
|
||||
{ id: 15, name: "高价值专利培育" },
|
||||
{ id: 16, name: "知识产权布局" },
|
||||
{ id: 17, name: "设立院士工作站" },
|
||||
{ id: 18, name: "海外留学生培养" },
|
||||
{
|
||||
id: 1,
|
||||
name: "基金对接",
|
||||
nameRu: "Фонд стыкуется",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "贷款",
|
||||
nameRu: "Поручить разработку",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "对接专家院士",
|
||||
nameRu: "Обучение иностранных студентов",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "人才培养",
|
||||
nameRu: "Кредиты",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "一带一路国际合作",
|
||||
nameRu: "Академик - специалист по стыковке",
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: "上市辅导",
|
||||
nameRu: "Подготовка кадров",
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: "成果产业化",
|
||||
nameRu: "Международное сотрудничество",
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: "国家级科研平台合作",
|
||||
nameRu: "Консультирование по листингу",
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
name: "研发项目立项评估",
|
||||
nameRu: "Индустриализация результатов",
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
name: "科技查新",
|
||||
nameRu: "Сотрудничество национальных научно - исследовательских платформ",
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
name: "产业链上下游对接",
|
||||
nameRu: "Оценка проектов НИОКР",
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
name: "委托研发",
|
||||
nameRu: "Новые технологии.",
|
||||
},
|
||||
{
|
||||
id: 13,
|
||||
name: "对接政府项目落地",
|
||||
nameRu: "Промышленная цепочка вверх и вниз по течению",
|
||||
},
|
||||
{
|
||||
id: 14,
|
||||
name: "技术咨询",
|
||||
nameRu: "Распределение интеллектуальной собственности",
|
||||
},
|
||||
{
|
||||
id: 15,
|
||||
name: "高价值专利培育",
|
||||
nameRu: "Высокая стоимость патентов",
|
||||
},
|
||||
{
|
||||
id: 16,
|
||||
name: "知识产权布局",
|
||||
nameRu: "Технические консультации",
|
||||
},
|
||||
{
|
||||
id: 17,
|
||||
name: "设立院士工作站",
|
||||
nameRu: "Посадка на правительственный проект",
|
||||
},
|
||||
{
|
||||
id: 18,
|
||||
name: "海外留学生培养",
|
||||
nameRu: "Создание академической рабочей станции",
|
||||
},
|
||||
];
|
||||
// export const enterpriseOptions = [
|
||||
// { key: "101", value: '上市企业' },
|
||||
|
@ -109,10 +109,10 @@ service.interceptors.response.use(
|
||||
if (!isRelogin.show) {
|
||||
isRelogin.show = true;
|
||||
ElMessageBox.confirm(
|
||||
"登录状态已过期,您可以继续留在该页面,或者重新登录",
|
||||
t("tips.loginStatusExpired"),
|
||||
t("common.systemPrompt"),
|
||||
{
|
||||
confirmButtonText: "重新登录",
|
||||
confirmButtonText: t("tips.reLogin"),
|
||||
cancelButtonText: t("common.cancel"),
|
||||
type: "warning",
|
||||
}
|
||||
@ -129,7 +129,7 @@ service.interceptors.response.use(
|
||||
isRelogin.show = false;
|
||||
});
|
||||
}
|
||||
return Promise.reject("无效的会话,或者会话已过期,请重新登录。");
|
||||
return Promise.reject(t("tips.invalidSessionOrSessionExpired"));
|
||||
} else if (code === 500) {
|
||||
ElMessage({
|
||||
message: msg,
|
||||
@ -149,7 +149,7 @@ service.interceptors.response.use(
|
||||
console.log("err" + error);
|
||||
let { message } = error;
|
||||
if (message == "Network Error") {
|
||||
message = "后端接口连接异常";
|
||||
message = t("tips.backendInterfaceConnectionException");
|
||||
} else if (message.includes("timeout")) {
|
||||
message = t("common.requestTimeout");
|
||||
} else if (message.includes("Request failed with status code")) {
|
||||
@ -167,7 +167,7 @@ service.interceptors.response.use(
|
||||
// 通用下载方法
|
||||
export function download(url, params, filename) {
|
||||
downloadLoadingInstance = ElLoading.service({
|
||||
text: "正在下载数据,请稍候",
|
||||
text: t("tips.downloadingData"),
|
||||
background: "rgba(0, 0, 0, 0.7)",
|
||||
});
|
||||
return service
|
||||
@ -196,7 +196,7 @@ export function download(url, params, filename) {
|
||||
})
|
||||
.catch((r) => {
|
||||
console.error(r);
|
||||
ElMessage.error("下载文件出现错误,请联系管理员!");
|
||||
ElMessage.error(t("tips.downloadFileError"));
|
||||
downloadLoadingInstance.close();
|
||||
});
|
||||
}
|
||||
|
5
src/utils/string.js
Normal file
5
src/utils/string.js
Normal file
@ -0,0 +1,5 @@
|
||||
export function toTitleCase(str) {
|
||||
return str.replace(/\w\S*/g, function (txt) {
|
||||
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
|
||||
});
|
||||
}
|
@ -37,22 +37,22 @@ export default {
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => [
|
||||
{
|
||||
name: "测试一类",
|
||||
value: 30,
|
||||
},
|
||||
{
|
||||
name: "测试二类",
|
||||
value: 30,
|
||||
},
|
||||
{
|
||||
name: "测试三类",
|
||||
value: 30,
|
||||
},
|
||||
{
|
||||
name: "测试四类",
|
||||
value: 30,
|
||||
},
|
||||
// {
|
||||
// name: "测试一类",
|
||||
// value: 30,
|
||||
// },
|
||||
// {
|
||||
// name: "测试二类",
|
||||
// value: 30,
|
||||
// },
|
||||
// {
|
||||
// name: "测试三类",
|
||||
// value: 30,
|
||||
// },
|
||||
// {
|
||||
// name: "测试四类",
|
||||
// value: 30,
|
||||
// },
|
||||
],
|
||||
},
|
||||
},
|
||||
@ -196,7 +196,8 @@ button {
|
||||
color: green;
|
||||
text-decoration: none;
|
||||
font-size: 16px;
|
||||
font-family: "微软雅黑";
|
||||
//font-family: "微软雅黑";
|
||||
font-family: "Microsoft YaHei UI";
|
||||
font-weight: bold;
|
||||
}
|
||||
.wordCloud__tag :hover {
|
||||
|
@ -26,8 +26,20 @@
|
||||
<el-checkbox
|
||||
v-for="item in checkList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
>{{ item.name }}
|
||||
:label="
|
||||
locale === 'zh'
|
||||
? item.name
|
||||
: locale === 'ru'
|
||||
? item.nameRu
|
||||
: null
|
||||
"
|
||||
>{{
|
||||
locale === "zh"
|
||||
? item.name
|
||||
: locale === "ru"
|
||||
? item.nameRu
|
||||
: null
|
||||
}}
|
||||
</el-checkbox>
|
||||
<!-- <el-checkbox label="0" @change="handleCheck">其他</el-checkbox> -->
|
||||
</el-checkbox-group>
|
||||
@ -107,34 +119,34 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
:label="t('admin.table.demandSubmitter')"
|
||||
prop="commitUserName"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.commitUserName"
|
||||
:placeholder="
|
||||
t('admin.form.placeholder', {
|
||||
type: t('admin.table.demandSubmitter'),
|
||||
})
|
||||
"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
:label="t('admin.form.demandSubmitterPhone')"
|
||||
prop="commitPhone"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.commitPhone"
|
||||
:placeholder="t('admin.form.demandSubmitterPhone')"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- <el-row>-->
|
||||
<!-- <el-col :span="12">-->
|
||||
<!-- <el-form-item-->
|
||||
<!-- :label="t('admin.table.demandSubmitter')"-->
|
||||
<!-- prop="commitUserName"-->
|
||||
<!-- >-->
|
||||
<!-- <el-input-->
|
||||
<!-- v-model="form.commitUserName"-->
|
||||
<!-- :placeholder="-->
|
||||
<!-- t('admin.form.placeholder', {-->
|
||||
<!-- type: t('admin.table.demandSubmitter'),-->
|
||||
<!-- })-->
|
||||
<!-- "-->
|
||||
<!-- ></el-input>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-col>-->
|
||||
<!-- <el-col :span="12">-->
|
||||
<!-- <el-form-item-->
|
||||
<!-- :label="t('admin.form.demandSubmitterPhone')"-->
|
||||
<!-- prop="commitPhone"-->
|
||||
<!-- >-->
|
||||
<!-- <el-input-->
|
||||
<!-- v-model="form.commitPhone"-->
|
||||
<!-- :placeholder="t('admin.form.demandSubmitterPhone')"-->
|
||||
<!-- ></el-input>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-col>-->
|
||||
<!-- </el-row>-->
|
||||
</el-form>
|
||||
<div :style="{ marginLeft: labelWidth + 'px' }">
|
||||
<el-button @click="backToList"
|
||||
@ -154,14 +166,15 @@ import {
|
||||
insertDemand,
|
||||
updateDemand,
|
||||
} from "@/api/admin/enterprise/demand";
|
||||
import { toTitleCase } from "@/utils/string";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { computed, onMounted, reactive, toRefs } from "vue";
|
||||
import { computed, onMounted, reactive, ref, toRefs } from "vue";
|
||||
import { demandCategoryList } from "@/utils/parameter";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { updateCount } from "@/api/admin/count";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
const { t, locale } = useI18n();
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const data = reactive({
|
||||
@ -284,9 +297,11 @@ function addCheck() {
|
||||
return item.name.trim() == checkInput.value.trim();
|
||||
});
|
||||
if (!flag) {
|
||||
const nameField =
|
||||
locale.value === "zh" ? "name" : `name${toTitleCase(locale.value)}`;
|
||||
checkList.push({
|
||||
id: checkList.length + 1,
|
||||
name: checkInput.value,
|
||||
[nameField]: checkInput.value,
|
||||
});
|
||||
checkInput.value = "";
|
||||
}
|
||||
@ -298,12 +313,16 @@ onMounted(() => {
|
||||
const obj = Object.assign({}, route, { title: "修改服务需求" });
|
||||
tab.updatePage(obj);
|
||||
getDemand({ id: route.query.id }).then((resp) => {
|
||||
// const nameField = locale === "zh" ? "name" : "nameRu";
|
||||
console.log(locale.value);
|
||||
const nameField =
|
||||
locale.value === "zh" ? "name" : `name${toTitleCase(locale.value)}`;
|
||||
if (resp.data.kinds) {
|
||||
resp.data.kinds.forEach((el, index) => {
|
||||
if (!checkList.find((item) => item.name == el)) {
|
||||
if (!checkList.find((item) => item[nameField] === el)) {
|
||||
checkList.push({
|
||||
id: index,
|
||||
name: el,
|
||||
[nameField]: el,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -371,18 +371,22 @@ const checkList = reactive([
|
||||
{
|
||||
id: 1,
|
||||
name: "成果推广",
|
||||
nameRu: "Продвижение достижений",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "关键成果解决",
|
||||
nameRu: "Решение ключевых результатов",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "对接专家院士",
|
||||
nameRu: "Связь с экспертами и академиками",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "上市辅导",
|
||||
nameRu: "Помощь в выходе на рынок",
|
||||
},
|
||||
]);
|
||||
|
||||
@ -460,7 +464,11 @@ onMounted(() => {
|
||||
formRef.value.resetFields();
|
||||
|
||||
if (route.query.id) {
|
||||
const obj = Object.assign({}, route, { title: "修改技术需求" });
|
||||
const obj = Object.assign({}, route, {
|
||||
title: t("admin.form.edit", {
|
||||
type: t("webSearch.technologyDemand"),
|
||||
}),
|
||||
});
|
||||
tab.updatePage(obj);
|
||||
getTechnologyDemand({ id: route.query.id }).then((resp) => {
|
||||
form.value = resp.data;
|
||||
|
@ -210,14 +210,21 @@ function handleShelf(row) {
|
||||
let text =
|
||||
row.shelf_status == 2 ? t("admin.table.putOn") : t("admin.table.putOff");
|
||||
modal
|
||||
.confirm('确认要"' + text + '""' + row.id + '"的需求吗?')
|
||||
// .confirm('确认要"' + text + '""' + row.id + '"的需求吗?')
|
||||
.confirm(
|
||||
t("admin.common.confirmAction", {
|
||||
action: text,
|
||||
number: row.id,
|
||||
type: t("admin.common.demand"),
|
||||
})
|
||||
)
|
||||
.then(function () {
|
||||
let status = row.shelf_status == 1 ? 2 : 1;
|
||||
return achievementShelf({ id: row.id, status });
|
||||
})
|
||||
.then(() => {
|
||||
getList();
|
||||
ElMessage.success(text + "成功");
|
||||
ElMessage.success(t("admin.common.success", { action: text }));
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
@ -191,7 +191,14 @@ function handleQuery() {
|
||||
// 取消发布
|
||||
const releaseCancel = (id) => {
|
||||
modal
|
||||
.confirm('确认要取消发布id为"' + id + '"的产品吗?')
|
||||
// .confirm('确认要取消发布id为"' + id + '"的产品吗?')
|
||||
.confirm(
|
||||
t("admin.common.confirmAction", {
|
||||
action: t("admin.table.cancelPublish"),
|
||||
number: id,
|
||||
type: t("admin.form.product"),
|
||||
})
|
||||
)
|
||||
.then(async () => {
|
||||
await updateEnterpriseProduct({ id, status: 3 });
|
||||
ElMessage.success(t("tips.cancelReleaseSuccess"));
|
||||
@ -206,14 +213,21 @@ const handleShelf = (row) => {
|
||||
let text =
|
||||
row.shelfStatus == 2 ? t("admin.table.putOn") : t("admin.table.putOff");
|
||||
modal
|
||||
.confirm('确认要"' + text + '""' + row.id + '"的产品吗?')
|
||||
// .confirm('确认要"' + text + '""' + row.id + '"的产品吗?')
|
||||
.confirm(
|
||||
t("admin.common.confirmAction", {
|
||||
action: text,
|
||||
number: row.id,
|
||||
type: t("admin.form.product"),
|
||||
})
|
||||
)
|
||||
.then(function () {
|
||||
let status = row.shelfStatus == 1 ? 2 : 1;
|
||||
return updateEnterpriseProduct({ id: row.id, shelfStatus: status });
|
||||
})
|
||||
.then(() => {
|
||||
getList();
|
||||
ElMessage.success(text + "成功");
|
||||
ElMessage.success(t("admin.common.success", { action: text }));
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
@ -50,7 +50,7 @@ const submitForm = async (is_submit) => {
|
||||
form.value.cooperationMode = form.value.cooperationModeArr.join(",");
|
||||
if (route.query.id) {
|
||||
await updateEnterpriseProduct(form.value);
|
||||
ElMessage.success("修改产品成功");
|
||||
ElMessage.success(t("admin.common.editSuccess"));
|
||||
} else {
|
||||
await insertEnterpriseProduct(form.value);
|
||||
ElMessage.success(t("admin.common.AddSuccess"));
|
||||
|
@ -268,7 +268,7 @@
|
||||
</p>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="成熟度证明材料:">
|
||||
<el-form-item :label="t('admin.form.maturityProofMaterial')">
|
||||
<FileUpload
|
||||
v-model="modelValue.file"
|
||||
:fileType="['doc', 'xls', 'ppt', 'txt', 'pdf', 'jpg']"
|
||||
|
@ -195,7 +195,11 @@ function handleShelf(row) {
|
||||
const shelfStatus = row.shelfStatus == 1 ? 2 : 1;
|
||||
await updateExpertAchievement({ id: row.id, shelfStatus });
|
||||
getList();
|
||||
ElMessage.success(text + "成功");
|
||||
ElMessage.success(
|
||||
t("admin.common.success", {
|
||||
action: text,
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -69,13 +69,13 @@
|
||||
</el-button>
|
||||
</el-col>
|
||||
<!-- 无接口 暂时注释 -->
|
||||
<el-col :span="1.5">
|
||||
<router-link to="./claimPatent">
|
||||
<el-button type="primary" plain icon="Plus" size="small"
|
||||
>{{ t("admin.table.claim") }}
|
||||
</el-button>
|
||||
</router-link>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">-->
|
||||
<!-- <router-link to="./claimPatent">-->
|
||||
<!-- <el-button type="primary" plain icon="Plus" size="small"-->
|
||||
<!-- >{{ t("admin.table.claim") }}-->
|
||||
<!-- </el-button>-->
|
||||
<!-- </router-link>-->
|
||||
<!-- </el-col>-->
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
@queryTable="getList"
|
||||
@ -145,7 +145,7 @@
|
||||
<el-form-item :label="t('webSearch.applicant')" prop="applyName">
|
||||
<el-input
|
||||
v-model="form.applyName"
|
||||
placeholder="请输入申请(专利权)人(多个请以 , 分割)"
|
||||
:placeholder="t('tips.pleaseEnterApplicant')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
|
@ -313,13 +313,13 @@
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
technologyProjectList,
|
||||
insertTechnologyProject,
|
||||
deleteTechnologyProjectByIds,
|
||||
insertTechnologyProject,
|
||||
technologyProjectList,
|
||||
updateTechnologyProject,
|
||||
} from "@/api/admin/expert/research";
|
||||
import dayjs from "dayjs";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { ElMessage } from "element-plus";
|
||||
import modal from "@/plugins/modal";
|
||||
import { cloneDeep } from "lodash-es";
|
||||
import { useRouter } from "vue-router";
|
||||
@ -468,14 +468,25 @@ function handleShelf(row) {
|
||||
const text =
|
||||
row.shelfStatus == 2 ? t("admin.table.putOn") : t("admin.table.putOff");
|
||||
modal
|
||||
.confirm(`确认要${text}"${row.id}"的数据吗?`)
|
||||
// .confirm(`确认要${text}"${row.id}"的数据吗?`)
|
||||
.confirm(
|
||||
t("admin.common.confirmAction", {
|
||||
type: t("admin.common.researchProject"),
|
||||
action: text,
|
||||
number: row.id,
|
||||
})
|
||||
)
|
||||
.then(() => {
|
||||
const shelfStatus = row.shelfStatus == 1 ? 2 : 1;
|
||||
return updateTechnologyProject({ id: row.id, shelfStatus });
|
||||
})
|
||||
.then(() => {
|
||||
getList();
|
||||
ElMessage.success(text + "成功");
|
||||
ElMessage.success(
|
||||
t("admin.common.success", {
|
||||
action: text,
|
||||
})
|
||||
);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
|
@ -40,7 +40,7 @@ const submitForm = async () => {
|
||||
const valid = await researchFormRef.value.validateForm();
|
||||
if (valid) {
|
||||
insertResearch(form.value).then((resp) => {
|
||||
ElMessage.success("申请入驻成功");
|
||||
ElMessage.success(t("tips.applyForSettledSuccessfully"));
|
||||
router.push("/identity/index");
|
||||
});
|
||||
} else {
|
||||
|
@ -1,22 +1,22 @@
|
||||
<template>
|
||||
<div class="paging">
|
||||
<el-icon
|
||||
class="prev"
|
||||
:style="{
|
||||
cursor: page === 1 ? 'not-allowed' : 'pointer',
|
||||
color: page === 1 ? '#999' : '#4f93ed',
|
||||
}"
|
||||
class="prev"
|
||||
@click="prev"
|
||||
>
|
||||
<ArrowLeftBold />
|
||||
</el-icon>
|
||||
<div class="page-num">{{ page }}</div>
|
||||
<el-icon
|
||||
class="next"
|
||||
:style="{
|
||||
cursor: Math.ceil(total / 5) <= page ? 'not-allowed' : 'pointer',
|
||||
color: Math.ceil(total / 5) <= page ? '#999' : '#4f93ed',
|
||||
}"
|
||||
class="next"
|
||||
@click="next"
|
||||
>
|
||||
<ArrowRightBold />
|
||||
@ -26,6 +26,8 @@
|
||||
|
||||
<script setup>
|
||||
import { toRefs } from "vue";
|
||||
import { ArrowLeftBold, ArrowRightBold } from "@element-plus/icons-vue";
|
||||
|
||||
const emit = defineEmits(["update:page"]);
|
||||
const props = defineProps({
|
||||
total: {
|
||||
@ -40,7 +42,7 @@ const props = defineProps({
|
||||
const { total, page } = toRefs(props);
|
||||
|
||||
const prev = () => {
|
||||
if (page.value == 1) return;
|
||||
if (page.value === 1) return;
|
||||
emit("update:page", page.value - 1);
|
||||
};
|
||||
const next = () => {
|
||||
@ -50,6 +52,7 @@ const next = () => {
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.paging {
|
||||
display: flex;
|
||||
width: 100px;
|
||||
z-index: 9999;
|
||||
position: absolute;
|
||||
@ -58,6 +61,7 @@ const next = () => {
|
||||
transform: translateX(-50%);
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.prev,
|
||||
.next {
|
||||
user-select: none;
|
||||
@ -66,5 +70,9 @@ const next = () => {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.page-num {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
527
src/views/website/home/comp/index0.vue
Normal file
527
src/views/website/home/comp/index0.vue
Normal file
@ -0,0 +1,527 @@
|
||||
<script setup>
|
||||
import AMapLoader from "@amap/amap-jsapi-loader";
|
||||
import { computed, onMounted, ref, shallowRef, toRefs, watch } from "vue";
|
||||
import { init, registerMap } from "echarts";
|
||||
import {
|
||||
countAchievementByArea,
|
||||
countAchievementByCity,
|
||||
countAchievementByProvince,
|
||||
countDemandByArea,
|
||||
countDemandByCity,
|
||||
countDemandByProvince,
|
||||
countEnterpriseByArea,
|
||||
countEnterpriseByCity,
|
||||
countEnterpriseByProvince,
|
||||
countExpertByArea,
|
||||
countExpertByCity,
|
||||
countExpertByProvince,
|
||||
} from "@/api/website/home";
|
||||
import backBtnPng from "@/assets/images/map_back.png";
|
||||
import RegionPagine from "@/views/website/home/comp/RegionPagine.vue";
|
||||
import html2canvas from "html2canvas";
|
||||
import anime from "animejs";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import geoJSONRU from "@/assets/custom.geo.json";
|
||||
|
||||
const { t, locale } = useI18n();
|
||||
const leftBoxPageNum = ref(1);
|
||||
const rightBoxPageNum = ref(1);
|
||||
const mapRef = ref(null);
|
||||
const districtSearch = shallowRef(null);
|
||||
const myEcharts = shallowRef(null);
|
||||
const map = shallowRef(null);
|
||||
const mapData = ref([]);
|
||||
const props = defineProps({
|
||||
mapIndex: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
});
|
||||
const { mapIndex } = toRefs(props);
|
||||
const emit = defineEmits(["changeMapIndex"]);
|
||||
const methods = [
|
||||
{
|
||||
name: "expert",
|
||||
title: computed(() => t("map.expertMap")),
|
||||
byProvince: countExpertByProvince,
|
||||
byCity: countExpertByCity,
|
||||
byArea: countExpertByArea,
|
||||
},
|
||||
{
|
||||
name: "technology",
|
||||
// title: "技术分布地图",
|
||||
title: computed(() => t("map.technologyMap")),
|
||||
byProvince: countAchievementByProvince,
|
||||
byCity: countAchievementByCity,
|
||||
byArea: countAchievementByArea,
|
||||
},
|
||||
{
|
||||
name: "demand",
|
||||
// title: "需求分布地图",
|
||||
title: computed(() => t("map.demandMap")),
|
||||
byProvince: countDemandByProvince,
|
||||
byCity: countDemandByCity,
|
||||
byArea: countDemandByArea,
|
||||
},
|
||||
{
|
||||
name: "enterprise",
|
||||
// title: "企业分布地图",
|
||||
title: computed(() => t("map.enterpriseMap")),
|
||||
byProvince: countEnterpriseByProvince,
|
||||
byCity: countEnterpriseByCity,
|
||||
byArea: countEnterpriseByArea,
|
||||
},
|
||||
];
|
||||
|
||||
const areaCount = ref([]); // 按行政区划统计
|
||||
const industryCount = ref([]); // 按领域统计
|
||||
const areaCountPaged = computed(() =>
|
||||
areaCount.value.slice(
|
||||
(leftBoxPageNum.value - 1) * 5,
|
||||
leftBoxPageNum.value * 5
|
||||
)
|
||||
);
|
||||
const industryCountPaged = computed(() =>
|
||||
industryCount.value.slice(
|
||||
(rightBoxPageNum.value - 1) * 5,
|
||||
rightBoxPageNum.value * 5
|
||||
)
|
||||
);
|
||||
const options = {
|
||||
// nameProperty: 'adcode',
|
||||
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" },
|
||||
],
|
||||
textStyle: {
|
||||
color: "#fff",
|
||||
},
|
||||
visibility: "off",
|
||||
},
|
||||
tooltip: {
|
||||
//提示框信息
|
||||
trigger: "item",
|
||||
formatter: "{b}\n{c}人",
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: "map",
|
||||
name: "中国",
|
||||
map: "map",
|
||||
data: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
const loadAMap = async () => {
|
||||
const AMap = await AMapLoader.load({
|
||||
key: "377d7c36dd385e2a722f29d4c6e1ffbf", // 申请好的Web端开发者Key,首次调用 load 时必填
|
||||
version: "2.0", // 指定要加载的 JS API 的版本,缺省时默认为 1.4.15
|
||||
plugins: [
|
||||
/*"AMap.DistrictSearch", "AMap.DistrictExplorer"*/
|
||||
], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
|
||||
AMapUI: {
|
||||
// 是否加载 AMapUI,缺省不加载
|
||||
version: "1.1", // AMapUI 缺省 1.1
|
||||
plugins: [], // 需要加载的 AMapUI ui插件
|
||||
},
|
||||
});
|
||||
map.value = new AMap.Map("container", {
|
||||
zoom: 4, //级别
|
||||
center: [108.946609, 34.262324], //中心点坐标
|
||||
// viewMode: '3D' //使用3D视图
|
||||
});
|
||||
map.value.on("click", mapClick);
|
||||
// districtSearch.value = new AMap.DistrictSearch({
|
||||
// level: 'province',
|
||||
// extensions: 'all',
|
||||
// subdistrict: 1,
|
||||
// showbiz: false,
|
||||
// })
|
||||
};
|
||||
const loading = ref(false);
|
||||
const loadChinaDistrict = (adcode) => {
|
||||
loading.value = true;
|
||||
AMapUI.loadUI(["geo/DistrictExplorer"], (DistrictExplorer) => {
|
||||
const districtExplorer = new DistrictExplorer({
|
||||
map: map, //关联的地图实例
|
||||
});
|
||||
|
||||
districtExplorer.loadAreaNode(adcode, async (error, areaNode) => {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
const parentAdcode = areaNode.getAdcode();
|
||||
// 绘制载入的区划节点
|
||||
const geoJSON = {
|
||||
type: "FeatureCollection",
|
||||
features: areaNode.getSubFeatures(),
|
||||
};
|
||||
const level = getLevel(adcode);
|
||||
let result;
|
||||
try {
|
||||
if (level === 0) {
|
||||
result = await methods[mapIndex.value]["byProvince"]();
|
||||
} else if (level === 1) {
|
||||
result = await methods[mapIndex.value]["byCity"](adcode);
|
||||
} else if (level === 2) {
|
||||
result = await methods[mapIndex.value]["byArea"](adcode);
|
||||
}
|
||||
} catch (e) {
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
if (result.industry)
|
||||
industryCount.value = Object.keys(result.industry).map((key) => ({
|
||||
name: key,
|
||||
count: result.industry[key],
|
||||
}));
|
||||
areaCount.value = result.count ?? [];
|
||||
mapData.value = geoJSON.features.map((el) => {
|
||||
const areaProp = el.properties;
|
||||
return {
|
||||
adcode: areaProp.adcode,
|
||||
name: areaProp.name,
|
||||
value:
|
||||
result.count.find((el) => el.code == areaProp.adcode)?.count ?? 0,
|
||||
};
|
||||
});
|
||||
|
||||
registerMap("map", { geoJSON, specialAreas: {} });
|
||||
options.series[0].data = mapData.value;
|
||||
myEcharts.value.setOption(options);
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const loadRussiaDistrict = () => {
|
||||
registerMap("map", { geoJSON: geoJSONRU, specialAreas: {} });
|
||||
myEcharts.value.setOption(options);
|
||||
// TODO:get count
|
||||
};
|
||||
// 返回地图上一级
|
||||
const backMap = () => {
|
||||
// loadChinaDistrict(parentAdcode)
|
||||
loadChinaDistrict("100000");
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
await loadAMap();
|
||||
myEcharts.value = init(mapRef.value);
|
||||
myEcharts.value.on("click", mapClick);
|
||||
if (locale.value === "zh") {
|
||||
loadChinaDistrict("100000");
|
||||
} else {
|
||||
loadRussiaDistrict();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 根据adcode判断省市区级别
|
||||
* @param adcode
|
||||
* @return {number} 国家: 0 省: 1 市: 2 区: 3
|
||||
*/
|
||||
const getLevel = (adcode) => {
|
||||
adcode = adcode.toString();
|
||||
if (adcode === "100000") {
|
||||
return 0;
|
||||
}
|
||||
const splitPattern = /(\d{2})(\d{2})(\d{2})/;
|
||||
const resultArray = adcode.match(splitPattern).slice(1);
|
||||
// 国家: 0 省: 1 市: 2 区: 3
|
||||
let result = resultArray.indexOf("00");
|
||||
if (result === -1) {
|
||||
result = 3;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
const mapClick = (ev) => {
|
||||
const level = getLevel(ev.data.adcode);
|
||||
if (level === 3) {
|
||||
return;
|
||||
}
|
||||
loadChinaDistrict(ev.data.adcode);
|
||||
};
|
||||
|
||||
const playScrollAnimation = (direction, start) => {
|
||||
const pageWrap = document.querySelector(".page-wrap");
|
||||
const rootWrap = document.querySelector(".root-container");
|
||||
html2canvas(pageWrap).then((canvas) => {
|
||||
canvas.addEventListener("wheel", (ev) => {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
});
|
||||
if (direction === "down") {
|
||||
rootWrap.insertBefore(canvas, pageWrap);
|
||||
} else if (direction === "up") {
|
||||
rootWrap.appendChild(canvas);
|
||||
rootWrap.style.transform = "translateY(-100%)";
|
||||
}
|
||||
anime({
|
||||
targets: rootWrap,
|
||||
translateY: direction === "down" ? "-100%" : "0",
|
||||
duration: 300,
|
||||
easing: "linear",
|
||||
begin: start,
|
||||
complete: () => {
|
||||
rootWrap.removeChild(canvas);
|
||||
rootWrap.style.transform = "translateY(0%)";
|
||||
isScrolling.value = false;
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const isScrolling = ref(false);
|
||||
const handleScroll = async (ev) => {
|
||||
let direction = ev.deltaY > 0 ? "down" : "up";
|
||||
// 判断滚轮滚动方向
|
||||
if (
|
||||
(direction === "down" && mapIndex.value >= methods.length - 1) ||
|
||||
(direction === "up" && mapIndex.value <= 0)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
if (isScrolling.value) {
|
||||
return;
|
||||
}
|
||||
isScrolling.value = true;
|
||||
playScrollAnimation(direction, () => {});
|
||||
if (direction === "down" && mapIndex.value < methods.length - 1) {
|
||||
emit("changeMapIndex", mapIndex.value + 1);
|
||||
} else if (direction === "up" && mapIndex.value > 0) {
|
||||
emit("changeMapIndex", mapIndex.value - 1);
|
||||
}
|
||||
};
|
||||
|
||||
watch(mapIndex, (newVal, oldVal) => {
|
||||
console.log(`mapIndex change from ${oldVal} to ${newVal}`);
|
||||
if (newVal === oldVal) {
|
||||
return;
|
||||
}
|
||||
isScrolling.value = true;
|
||||
const direction = newVal > oldVal ? "down" : "up";
|
||||
playScrollAnimation(direction, () => {});
|
||||
if (locale.value === "zh") {
|
||||
loadChinaDistrict("100000");
|
||||
} else {
|
||||
loadRussiaDistrict();
|
||||
}
|
||||
});
|
||||
|
||||
watch(locale, (newVal) => {
|
||||
console.log(newVal);
|
||||
if (newVal === "zh") {
|
||||
loadChinaDistrict("100000");
|
||||
} else if (newVal === "ru") {
|
||||
loadRussiaDistrict();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="root-wrap">
|
||||
<div class="root-container">
|
||||
<div class="page-wrap" @wheel="handleScroll">
|
||||
<div class="title">{{ methods[mapIndex].title.value }}</div>
|
||||
<div v-if="loading" class="loading-modal"></div>
|
||||
<!-- 返回上一级按钮 -->
|
||||
<div class="back-btn" @click="backMap">
|
||||
<img :src="backBtnPng" alt="back" />
|
||||
</div>
|
||||
<!-- 人数表格 -->
|
||||
<div class="count-table area">
|
||||
<div class="table">
|
||||
<div class="head">
|
||||
<div class="th">
|
||||
<div class="title">地区</div>
|
||||
<div class="count">人数</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body">
|
||||
<div v-for="item in areaCountPaged" :key="item.adcode" class="tr">
|
||||
<div class="title">{{ item.name }}</div>
|
||||
<div class="count">{{ item.count }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<RegionPagine
|
||||
v-model:page="leftBoxPageNum"
|
||||
:total="areaCount.length"
|
||||
/>
|
||||
</div>
|
||||
<!-- 领域 -->
|
||||
<div class="count-table industry">
|
||||
<div class="table">
|
||||
<div class="head">
|
||||
<div class="th">
|
||||
<div class="title">领域</div>
|
||||
<div class="count">人数</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body">
|
||||
<div
|
||||
v-for="item in industryCountPaged"
|
||||
:key="item.adcode"
|
||||
class="tr"
|
||||
>
|
||||
<div class="title">{{ item.name }}</div>
|
||||
<div class="count">{{ item.count }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<RegionPagine
|
||||
v-model:page="rightBoxPageNum"
|
||||
:total="industryCount.length"
|
||||
/>
|
||||
</div>
|
||||
<div id="map-container" ref="mapRef"></div>
|
||||
<div
|
||||
id="container"
|
||||
style="
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgb(0, 0, 0);
|
||||
display: none;
|
||||
"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.scroll-to-top {
|
||||
animation: 1s linear infinite page-scroll;
|
||||
}
|
||||
|
||||
.root-wrap {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
.root-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
> canvas {
|
||||
transition: all 0.3s linear;
|
||||
}
|
||||
|
||||
.page-wrap {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
//top: 0;
|
||||
//left: 0;
|
||||
position: relative;
|
||||
//transition: all 0.3s linear;
|
||||
//animation: 1s linear forwards page-scroll;
|
||||
.loading-modal {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background: #f0f2f5;
|
||||
}
|
||||
|
||||
#map-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(0deg, #010101, #041744);
|
||||
}
|
||||
|
||||
> .title {
|
||||
position: absolute;
|
||||
top: 75px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 36px;
|
||||
font-family: Source Han Sans CN, sans-serif;
|
||||
font-weight: 300;
|
||||
color: #ffffff;
|
||||
z-index: 101;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
position: absolute;
|
||||
left: 120px;
|
||||
top: 120px;
|
||||
z-index: 99;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.count-table {
|
||||
position: absolute;
|
||||
|
||||
z-index: 101;
|
||||
|
||||
&.area {
|
||||
top: 200px;
|
||||
left: 120px;
|
||||
}
|
||||
|
||||
&.industry {
|
||||
top: 200px;
|
||||
right: 120px;
|
||||
}
|
||||
|
||||
.table {
|
||||
border: 1px solid #0054ff;
|
||||
|
||||
.head,
|
||||
.body {
|
||||
.tr,
|
||||
.th {
|
||||
display: flex;
|
||||
color: white;
|
||||
|
||||
.title,
|
||||
.count {
|
||||
width: 100px;
|
||||
padding: 8px 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
border-right: 1px solid #0054ff;
|
||||
}
|
||||
}
|
||||
|
||||
.th {
|
||||
border-bottom: 1px solid #0054ff;
|
||||
}
|
||||
|
||||
.tr {
|
||||
color: rgb(161, 192, 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pagination {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//@keyframes page-scroll {
|
||||
// 0% {
|
||||
// transform: translateY(0);
|
||||
// }
|
||||
// 100% {
|
||||
// transform: translateY(-100%);
|
||||
// }
|
||||
//}
|
||||
</style>
|
@ -1,32 +1,34 @@
|
||||
<template>
|
||||
<div v-loading="loading" class="fullPage" ref="fullPageRef">
|
||||
<div ref="fullPageRef" v-loading="loading" class="fullPage">
|
||||
<div class="indicator">
|
||||
<div
|
||||
:class="`${state.fullpage.current == idx ? 'active' : ''}`"
|
||||
v-for="idx in len"
|
||||
:key="idx"
|
||||
v-for="idx in 6"
|
||||
:id="idx.toString()"
|
||||
:key="idx"
|
||||
:class="`${indicatorActiveIndex == idx ? 'active' : ''}`"
|
||||
class="point"
|
||||
@click="handleIndicatorClick(idx)"
|
||||
></div>
|
||||
</div>
|
||||
<div
|
||||
class="fullPageContainer"
|
||||
:data-index="state.fullpage.current"
|
||||
ref="fullPageContainerRef"
|
||||
:data-index="state.fullpage.current"
|
||||
class="fullPageContainer"
|
||||
@mousewheel="mouseWheelHandle"
|
||||
>
|
||||
<!-- @DOMMouseScroll="mouseWheelHandle" -->
|
||||
<div
|
||||
v-for="(item, $index) in state.boxList"
|
||||
class="section"
|
||||
:key="$index"
|
||||
:style="`z-index: ${item.zIndex};`"
|
||||
class="section"
|
||||
>
|
||||
<!-- v-if="`index${state.fullpage.current}` == item.title" -->
|
||||
<component
|
||||
v-if="Math.abs(state.fullpage.current - ($index + 1)) <= 1"
|
||||
:is="item.comp"
|
||||
v-if="Math.abs(state.fullpage.current - ($index + 1)) <= 1"
|
||||
:map-index="mapIndex"
|
||||
@changeMapIndex="mapIndex = $event"
|
||||
></component>
|
||||
</div>
|
||||
</div>
|
||||
@ -50,21 +52,9 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
reactive,
|
||||
onMounted,
|
||||
ref,
|
||||
shallowRef,
|
||||
onUnmounted,
|
||||
computed,
|
||||
} from "vue";
|
||||
import { computed, onMounted, reactive, ref, shallowRef } from "vue";
|
||||
import index0 from "./comp/index0.vue";
|
||||
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);
|
||||
@ -73,6 +63,8 @@ setTimeout(() => {
|
||||
}, 500);
|
||||
const fullPageRef = ref();
|
||||
const fullPageContainerRef = ref();
|
||||
const mapIndex = ref(0); // 0-3
|
||||
const mapRef = ref();
|
||||
onMounted(() => {
|
||||
fullPageContainerRef.value.addEventListener(
|
||||
"DOMMouseScroll",
|
||||
@ -88,6 +80,7 @@ onMounted(() => {
|
||||
// });
|
||||
const len = computed(() => state.boxList.length);
|
||||
// const len = ref(6);
|
||||
|
||||
const next = () => {
|
||||
// 往下切换
|
||||
// TODO:
|
||||
@ -106,6 +99,7 @@ const pre = () => {
|
||||
move(state.fullpage.current); // 执行切换
|
||||
}
|
||||
};
|
||||
|
||||
function move(index) {
|
||||
state.fullpage.isScrolling = true; // 为了防止滚动多页,需要通过一个变量来控制是否滚动
|
||||
directToMove(index); //执行滚动
|
||||
@ -114,6 +108,7 @@ function move(index) {
|
||||
state.fullpage.isScrolling = false;
|
||||
}, 1010);
|
||||
}
|
||||
|
||||
function directToMove(index) {
|
||||
let height = fullPageRef.value["clientHeight"]; //获取屏幕的宽度
|
||||
// let scrollPage = proxy.$refs["fullPageContainer"]; // 获取执行tarnsform的元素
|
||||
@ -122,6 +117,7 @@ function directToMove(index) {
|
||||
fullPageContainerRef.value.style.transform = `translateY(${scrollHeight})`;
|
||||
state.fullpage.current = index;
|
||||
}
|
||||
|
||||
function mouseWheelHandle(event) {
|
||||
// 监听鼠标监听
|
||||
// 添加冒泡阻止
|
||||
@ -157,35 +153,10 @@ let state = reactive({
|
||||
zIndex: 1,
|
||||
title: "index1",
|
||||
},
|
||||
// {
|
||||
// comp: shallowRef(index2),
|
||||
// zIndex: 1,
|
||||
// title: "index2",
|
||||
// },
|
||||
{
|
||||
comp: shallowRef(index3),
|
||||
comp: shallowRef(index0),
|
||||
zIndex: 1,
|
||||
title: "index3",
|
||||
},
|
||||
// {
|
||||
// comp: shallowRef(index4),
|
||||
// zIndex: 1,
|
||||
// title: "index4",
|
||||
// },
|
||||
{
|
||||
comp: shallowRef(index5),
|
||||
zIndex: 1,
|
||||
title: "index5",
|
||||
},
|
||||
{
|
||||
comp: shallowRef(index6),
|
||||
zIndex: 1,
|
||||
title: "index6",
|
||||
},
|
||||
{
|
||||
comp: shallowRef(index7),
|
||||
zIndex: 1,
|
||||
title: "index7",
|
||||
title: "index1",
|
||||
},
|
||||
{
|
||||
comp: shallowRef(index8),
|
||||
@ -199,19 +170,46 @@ let state = reactive({
|
||||
},
|
||||
});
|
||||
|
||||
const indicatorActiveIndex = computed(() => {
|
||||
if (state.fullpage.current === 1) {
|
||||
return 1;
|
||||
} else if (state.fullpage.current === 2) {
|
||||
return mapIndex.value + 2;
|
||||
} else {
|
||||
return state.fullpage.current + 3;
|
||||
}
|
||||
});
|
||||
|
||||
// 点击 indicator 时
|
||||
const handleIndicatorClick = (idx) => {
|
||||
if (idx == state.fullpage.current) {
|
||||
return;
|
||||
} else if (idx > state.fullpage.current) {
|
||||
for (let i = state.fullpage.current; i < idx; i++) {
|
||||
console.log(idx);
|
||||
let boxIndex;
|
||||
let _mapIndex;
|
||||
if (idx === 1) {
|
||||
boxIndex = 1;
|
||||
_mapIndex = null;
|
||||
} else if (idx <= 5) {
|
||||
boxIndex = 2;
|
||||
_mapIndex = idx - 2;
|
||||
} else {
|
||||
boxIndex = 3;
|
||||
_mapIndex = null;
|
||||
}
|
||||
|
||||
if (boxIndex > state.fullpage.current) {
|
||||
for (let i = state.fullpage.current; i < boxIndex; i++) {
|
||||
next();
|
||||
}
|
||||
} else {
|
||||
for (let i = state.fullpage.current; i > idx; i--) {
|
||||
} else if (boxIndex < state.fullpage.current) {
|
||||
for (let i = state.fullpage.current; i > boxIndex; i--) {
|
||||
pre();
|
||||
}
|
||||
}
|
||||
if (_mapIndex !== null && _mapIndex !== mapIndex.value) {
|
||||
// mapRef.value?.loadMapByIndex(_mapIndex)
|
||||
// console.log(mapRef.value.loadMapByIndex)
|
||||
mapIndex.value = _mapIndex;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -221,32 +219,38 @@ const handleIndicatorClick = (idx) => {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
.indicator {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 20px;
|
||||
z-index: 999;
|
||||
transform: translateY(-50%);
|
||||
|
||||
.point {
|
||||
transition: all 1s;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background-color: #999;
|
||||
border-radius: 50%;
|
||||
|
||||
&.active {
|
||||
background-color: #0054ff;
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fullPageContainer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transition: all linear 0.5s;
|
||||
}
|
||||
|
||||
.section {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -143,17 +143,14 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Cookies from "js-cookie";
|
||||
// import { encrypt, decrypt } from "@/utils/jsencrypt";
|
||||
import Cookies from "js-cookie"; // 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";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { computed, reactive } from "vue";
|
||||
import { reactify } from "@vueuse/core";
|
||||
import { computed, reactive, ref } from "vue"; // const store = useStore();
|
||||
// const store = useStore();
|
||||
const router = useRouter();
|
||||
|
||||
@ -176,9 +173,9 @@ const registerForm = ref({
|
||||
const loginRef = ref();
|
||||
const isCheckRef = ref();
|
||||
const disabled = ref(true);
|
||||
const buttonName = ref("获取验证码");
|
||||
const isDisabled = ref(false);
|
||||
const time = ref(10);
|
||||
// const buttonName = ref("获取验证码");
|
||||
// const isDisabled = ref(false);
|
||||
// const time = ref(10);
|
||||
|
||||
const loginRules = reactive({
|
||||
username: [
|
||||
@ -199,7 +196,7 @@ const loginRules = reactive({
|
||||
|
||||
const isCheck = (rule, value, callback) => {
|
||||
if (!value) {
|
||||
callback(new Error("请阅读并勾选"));
|
||||
callback(new Error(t("register.readAndCheck")));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
|
@ -4,13 +4,26 @@
|
||||
<div v-if="data.image" class="img">
|
||||
<el-image :src="data.image" alt="" style="height: 150px" />
|
||||
</div>
|
||||
<div v-else-if="data.type == 1" class="type">产品</div>
|
||||
<div v-else-if="data.type == 2" class="type">成果</div>
|
||||
<div v-else-if="data.type == 1" class="type">
|
||||
<!--产品-->
|
||||
{{ t("admin.form.product") }}
|
||||
</div>
|
||||
<div v-else-if="data.type == 2" class="type">
|
||||
{{ t("admin.common.achievement") }}
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="tit" @click="handleDetail(data.dataId)">
|
||||
<!-- {{-->
|
||||
<!-- data.type == 2 ? `成果名称 :`: data.type == 1 ? "产品名称:" : ""-->
|
||||
<!-- }}-->
|
||||
{{
|
||||
data.type == 2 ? "成果名称:" : data.type == 1 ? "产品名称:" : ""
|
||||
}}
|
||||
t("admin.form.name", {
|
||||
type:
|
||||
data.type == 2
|
||||
? t("admin.common.achievement")
|
||||
: t("admin.form.product"),
|
||||
})
|
||||
}}:
|
||||
{{ data.title }}
|
||||
</div>
|
||||
<slot name="des" />
|
||||
@ -31,11 +44,12 @@
|
||||
}}</span>
|
||||
</div> -->
|
||||
<div class="line">
|
||||
联系人
|
||||
<!-- 联系人-->
|
||||
{{ t("webSearch.contact") }}
|
||||
<span>中科云平台</span>
|
||||
</div>
|
||||
<div class="line">
|
||||
联系方式(微信同号):
|
||||
{{ t("webSearch.contactInformation") }}({{ t("webSearch.wechat") }}):
|
||||
<span>18156053255</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -66,6 +80,7 @@ import { useRoute, useRouter } from "vue-router";
|
||||
import { toRefs } from "vue";
|
||||
import { addViewHistory } from "@/utils/view_history";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
<span>{{ data.industryStr }}</span>
|
||||
</div>
|
||||
<div class="line">
|
||||
{{ t("webSearch.webSite") }}:
|
||||
{{ t("admin.form.labWebsite") }}:
|
||||
<span>{{ data.url }}</span>
|
||||
</div>
|
||||
<div class="line">
|
||||
|
@ -40,7 +40,7 @@
|
||||
:disabled="!state.currentKeyword"
|
||||
icon="Search"
|
||||
@click="handleQuery"
|
||||
>搜索
|
||||
>{{ t("common.search") }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
|
@ -64,7 +64,9 @@
|
||||
</div>
|
||||
</section>
|
||||
<div style="padding: 20px 0">
|
||||
<div class="pointTit">毕业院校</div>
|
||||
<div class="pointTit">
|
||||
{{ t("admin.table.graduateSchool") }}
|
||||
</div>
|
||||
</div>
|
||||
<section>
|
||||
<div>
|
||||
|
@ -50,7 +50,7 @@
|
||||
</div>
|
||||
<div class="line">
|
||||
<!-- 网址-->
|
||||
{{ t("webSearch.website") }}
|
||||
{{ t("admin.form.labWebsite") }}
|
||||
:
|
||||
<a :href="state.LabDetail.url" target="_blank">{{
|
||||
state.LabDetail.url
|
||||
|
Reference in New Issue
Block a user