From 96c705e7c0eb114695c04a0500a4abc815739cf6 Mon Sep 17 00:00:00 2001
From: 康凯 <kangk26@foxmail.com>
Date: Sun, 12 Dec 2021 10:16:24 +0800
Subject: [PATCH] 开发完成 版本1.0
---
src/views/personage/list.vue | 190 +
src/views/layout/listIndex.vue | 155 +
vue.config.js | 14
src/assets/icon/iconfont.woff2 | 0
src/assets/home_background@1x.png | 0
src/assets/nav_memory@1x.png | 0
src/assets/icon/iconfont.woff | 0
src/assets/datalist/datalist@1x.png | 0
src/components/CustomSearch3.vue | 183 +
src/views/memory/detailImage.vue | 133 +
src/views/search/index.vue | 175 +
src/views/spirit/detailvideo.vue | 121
src/views/memory/detail.vue | 510 ++++
src/assets/icon/demo.css | 539 ++++
src/views/personage/detailvideo.vue | 121
src/api/jsonlint.js | 673 +++++
src/assets/icon/iconfont.json | 16
src/assets/icon/iconfont.js | 1
src/components/CustomSearch1.vue | 77
src/views/layout/searchIndex.vue | 75
.env.development | 5
src/views/spirit/detail.vue | 510 ++++
src/main.js | 142 +
.env.production | 6
src/views/home.vue | 191 +
src/components/CustomSearch2.vue | 201 +
package-lock.json | 121
src/assets/nav_scenery@1x.png | 0
src/assets/icon/iconfont.css | 19
src/views/scenery/detailvideo.vue | 121
src/assets/search/search@1x.png | 0
src/assets/nav_personage@1x.png | 0
src/api/apilist.js | 259 ++
src/views/spirit/list.vue | 153 +
src/views/memory/list.vue | 154 +
src/views/scenery/detailImage.vue | 133 +
src/views/search/results.vue | 268 ++
src/assets/icon/iconfont.ttf | 0
src/api/request.js | 74
src/views/personage/detailImage.vue | 133 +
src/views/personage/detail.vue | 510 ++++
src/views/scenery/detail.vue | 510 ++++
src/assets/nav_spirit@1x.png | 0
src/views/memory/detailvideo.vue | 121
src/assets/icon/demo_index.html | 211 +
/dev/null | 58
src/assets/datadetail/detail@1x.png | 0
package.json | 7
src/views/scenery/list.vue | 190 +
src/views/spirit/detailImage.vue | 133 +
src/App.vue | 52
51 files changed, 7,194 insertions(+), 71 deletions(-)
diff --git a/.env.development b/.env.development
new file mode 100644
index 0000000..8245922
--- /dev/null
+++ b/.env.development
@@ -0,0 +1,5 @@
+# just a flag
+ENV = 'development'
+
+# base api
+VUE_APP_BASE_API = '/'
diff --git a/.env.production b/.env.production
new file mode 100644
index 0000000..14da59c
--- /dev/null
+++ b/.env.production
@@ -0,0 +1,6 @@
+# just a flag
+ENV = 'production'
+
+# base api
+VUE_APP_BASE_API = '/'
+
diff --git a/package-lock.json b/package-lock.json
index 6395a37..3725035 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2201,6 +2201,11 @@
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
"dev": true
},
+ "array-find-index": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E="
+ },
"array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.nlark.com/array-flatten/download/array-flatten-1.1.1.tgz",
@@ -2323,6 +2328,14 @@
"integrity": "sha1-3TeelPDbgxCwgpH51kwyCXZmF/0=",
"dev": true
},
+ "async-validator": {
+ "version": "1.8.5",
+ "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-1.8.5.tgz",
+ "integrity": "sha512-tXBM+1m056MAX0E8TL2iCjg8WvSyXu0Zc8LNtYqrVeyoL3+esHRZ4SieE9fKQyyU09uONjnMEjrNBMqT0mbvmA==",
+ "requires": {
+ "babel-runtime": "6.x"
+ }
+ },
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.nlark.com/asynckit/download/asynckit-0.4.0.tgz",
@@ -2370,6 +2383,14 @@
"integrity": "sha1-1h9G2DslGSUOJ4Ta9bCUeai0HFk=",
"dev": true
},
+ "axios": {
+ "version": "0.24.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
+ "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
+ "requires": {
+ "follow-redirects": "^1.14.4"
+ }
+ },
"babel-eslint": {
"version": "10.1.0",
"resolved": "https://registry.npmmirror.com/babel-eslint/download/babel-eslint-10.1.0.tgz",
@@ -2383,6 +2404,11 @@
"eslint-visitor-keys": "^1.0.0",
"resolve": "^1.12.0"
}
+ },
+ "babel-helper-vue-jsx-merge-props": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz",
+ "integrity": "sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg=="
},
"babel-loader": {
"version": "8.2.3",
@@ -2433,6 +2459,27 @@
"dev": true,
"requires": {
"@babel/helper-define-polyfill-provider": "^0.3.0"
+ }
+ },
+ "babel-runtime": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+ "requires": {
+ "core-js": "^2.4.0",
+ "regenerator-runtime": "^0.11.0"
+ },
+ "dependencies": {
+ "core-js": {
+ "version": "2.6.12",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
+ "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ=="
+ },
+ "regenerator-runtime": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
+ }
}
},
"balanced-match": {
@@ -4064,8 +4111,7 @@
"deepmerge": {
"version": "1.5.2",
"resolved": "https://registry.npm.taobao.org/deepmerge/download/deepmerge-1.5.2.tgz?cache=0&sync_timestamp=1606805746825&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdeepmerge%2Fdownload%2Fdeepmerge-1.5.2.tgz",
- "integrity": "sha1-EEmdhohEza1P7ghC34x/bwyVp1M=",
- "dev": true
+ "integrity": "sha1-EEmdhohEza1P7ghC34x/bwyVp1M="
},
"default-gateway": {
"version": "5.0.5",
@@ -4513,6 +4559,19 @@
"resolved": "https://registry.npmmirror.com/electron-to-chromium/download/electron-to-chromium-1.4.12.tgz",
"integrity": "sha512-zjfhG9Us/hIy8AlQ5OzfbR/C4aBv1Dg/ak4GX35CELYlJ4tDAtoEcQivXvyBdqdNQ+R6PhlgQqV8UNPJmhkJog==",
"dev": true
+ },
+ "element-ui": {
+ "version": "2.15.6",
+ "resolved": "https://registry.npmjs.org/element-ui/-/element-ui-2.15.6.tgz",
+ "integrity": "sha512-rcYXEKd/j2G0AgficAOk1Zd1AsnHRkhmrK4yLHmNOiimU2JfsywgfKUjMoFuT6pQx0luhovj8lFjpE4Fnt58Iw==",
+ "requires": {
+ "async-validator": "~1.8.1",
+ "babel-helper-vue-jsx-merge-props": "^2.0.0",
+ "deepmerge": "^1.2.0",
+ "normalize-wheel": "^1.0.1",
+ "resize-observer-polyfill": "^1.5.0",
+ "throttle-debounce": "^1.0.1"
+ }
},
"elliptic": {
"version": "6.5.4",
@@ -5401,8 +5460,7 @@
"follow-redirects": {
"version": "1.14.5",
"resolved": "https://registry.npmmirror.com/follow-redirects/download/follow-redirects-1.14.5.tgz?cache=0&sync_timestamp=1635857764332&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.14.5.tgz",
- "integrity": "sha1-8JpYSJgdPHcrU5Iwl3hSP42Fw4E=",
- "dev": true
+ "integrity": "sha1-8JpYSJgdPHcrU5Iwl3hSP42Fw4E="
},
"for-in": {
"version": "1.0.2",
@@ -7358,6 +7416,16 @@
}
}
},
+ "mint-ui": {
+ "version": "2.2.13",
+ "resolved": "https://registry.npmjs.org/mint-ui/-/mint-ui-2.2.13.tgz",
+ "integrity": "sha512-Xz1SFagHSzKOprwQv3fcekXT5RJvhh939zwZHcWeazk1OJrCjsD4I2qm49AEUCfT1AoYzC+rsZIwGP/J6LwVVw==",
+ "requires": {
+ "array-find-index": "^1.0.2",
+ "raf.js": "0.0.4",
+ "vue-lazyload": "^1.0.1"
+ }
+ },
"mississippi": {
"version": "3.0.0",
"resolved": "https://registry.nlark.com/mississippi/download/mississippi-3.0.0.tgz",
@@ -7610,6 +7678,11 @@
"resolved": "https://registry.nlark.com/normalize-url/download/normalize-url-3.3.0.tgz",
"integrity": "sha1-suHE3E98bVd0PfczpPWXjRhlBVk=",
"dev": true
+ },
+ "normalize-wheel": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz",
+ "integrity": "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU="
},
"npm-run-path": {
"version": "2.0.2",
@@ -8952,6 +9025,11 @@
"integrity": "sha1-M0WUG0FTy50ILY7uTNogFqmu9/Y=",
"dev": true
},
+ "raf.js": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/raf.js/-/raf.js-0.0.4.tgz",
+ "integrity": "sha1-8Vr0RdJBsn+nExpXRQtn75xAL+w="
+ },
"randombytes": {
"version": "2.1.0",
"resolved": "https://registry.nlark.com/randombytes/download/randombytes-2.1.0.tgz",
@@ -9274,6 +9352,11 @@
"resolved": "https://registry.npm.taobao.org/requires-port/download/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
"dev": true
+ },
+ "resize-observer-polyfill": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+ "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
},
"resolve": {
"version": "1.20.0",
@@ -10484,6 +10567,11 @@
"neo-async": "^2.6.0"
}
},
+ "throttle-debounce": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-1.1.0.tgz",
+ "integrity": "sha512-XH8UiPCQcWNuk2LYePibW/4qL97+ZQ1AN3FNXwZRBNPPowo/NRU5fAlDCSNBJIYCKbioZfuYtMhG4quqoJhVzg=="
+ },
"through": {
"version": "2.3.8",
"resolved": "https://registry.npm.taobao.org/through/download/through-2.3.8.tgz",
@@ -11048,6 +11136,11 @@
"integrity": "sha1-UylVzB6yCKPZkLOp+acFdGV+CPI=",
"dev": true
},
+ "vue-lazyload": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/vue-lazyload/-/vue-lazyload-1.3.3.tgz",
+ "integrity": "sha512-uHnq0FTEeNmqnbBC2aRKlmtd9LofMZ6Q3mWvgfLa+i9vhxU8fDK+nGs9c1iVT85axSua/AUnMttIq3xPaU9G3A=="
+ },
"vue-loader": {
"version": "15.9.8",
"resolved": "https://registry.npmmirror.com/vue-loader/download/vue-loader-15.9.8.tgz?cache=0&sync_timestamp=1636034570924&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fvue-loader%2Fdownload%2Fvue-loader-15.9.8.tgz",
@@ -11150,6 +11243,26 @@
}
}
},
+ "vue-meta": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/vue-meta/-/vue-meta-2.4.0.tgz",
+ "integrity": "sha512-XEeZUmlVeODclAjCNpWDnjgw+t3WA6gdzs6ENoIAgwO1J1d5p1tezDhtteLUFwcaQaTtayRrsx7GL6oXp/m2Jw==",
+ "requires": {
+ "deepmerge": "^4.2.2"
+ },
+ "dependencies": {
+ "deepmerge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
+ }
+ }
+ },
+ "vue-router": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.3.tgz",
+ "integrity": "sha512-FUlILrW3DGitS2h+Xaw8aRNvGTwtuaxrRkNSHWTizOfLUie7wuYwezeZ50iflRn8YPV5kxmU2LQuu3nM/b3Zsg=="
+ },
"vue-style-loader": {
"version": "4.1.3",
"resolved": "https://registry.nlark.com/vue-style-loader/download/vue-style-loader-4.1.3.tgz",
diff --git a/package.json b/package.json
index 806eec0..d852662 100644
--- a/package.json
+++ b/package.json
@@ -8,8 +8,13 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
+ "axios": "^0.24.0",
"core-js": "^3.6.5",
- "vue": "^2.6.11"
+ "element-ui": "^2.15.6",
+ "mint-ui": "^2.2.13",
+ "vue": "^2.6.11",
+ "vue-meta": "^2.4.0",
+ "vue-router": "^3.5.3"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
diff --git a/src/App.vue b/src/App.vue
index 55df315..771fde0 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,28 +1,66 @@
<template>
<div id="app">
- <img alt="Vue logo" src="./assets/logo.png">
- <HelloWorld msg="Welcome to Your Vue.js App"/>
+ <router-view></router-view>
</div>
</template>
<script>
-import HelloWorld from './components/HelloWorld.vue'
-
export default {
name: 'App',
- components: {
- HelloWorld
+ components: {},
+ metaInfo: {
+ meta: [
+ {
+ name: "viewport",
+ content: "width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1, maximum-scale=1;"
+ }
+ ]
+ },
+ created() {
+ document.title = "吉林红色旅游";
}
}
</script>
<style>
+body{
+ margin: 1px;
+}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
- margin-top: 60px;
+}
+@media only screen and (min-width: 320px) {
+ html {
+ font-size: 6px !important;
+ }
+}
+
+
+@media only screen and (min-width: 375px) {
+ html {
+ font-size: 8px !important;
+ }
+}
+
+@media only screen and (min-width: 480px) {
+ html {
+ font-size: 12px !important;
+ }
+}
+
+@media only screen and (min-width: 640px) {
+ html {
+ font-size: 14px !important;
+ }
+}
+
+@media only screen and (min-width: 750px) {
+ html {
+ font-size: 16px !important;
+ }
}
</style>
diff --git a/src/api/apilist.js b/src/api/apilist.js
new file mode 100644
index 0000000..13fb47d
--- /dev/null
+++ b/src/api/apilist.js
@@ -0,0 +1,259 @@
+import request from "@/api/request";
+
+export function GetHomeQuickNav() {
+ return new Promise((resolve, reject) => {
+ request.get("/index.php/index/index")
+ .then(res => {
+ if (res.Code == "1") {
+ let hsjq = {
+ tab_pane_label: "红色景区",
+ tab_pane_content: res.Data.list.hsjq.map(a => {
+ return {id: a.id, type: a.type, title: a.title}
+ })
+ };
+ let hsjs = {
+ tab_pane_label: "红色精神",
+ tab_pane_content: res.Data.list.hsjs.map(a => {
+ return {id: a.id, type: a.type, title: a.title}
+ })
+ };
+ let hsjy = {
+ tab_pane_label: "红色记忆",
+ tab_pane_content: res.Data.list.hsjy.map(a => {
+ return {id: a.id, type: a.type, title: a.title}
+ })
+ };
+ let hsrw = {
+ tab_pane_label: "红色人物",
+ tab_pane_content: res.Data.list.hsrw.map(a => {
+ return {id: a.id, type: a.type, title: a.title}
+ })
+ };
+ resolve([hsjq, hsjs, hsjy, hsrw]);
+ } else {
+ reject(res.Message);
+ }
+ }).catch(err => {
+ throw err;
+ });
+ });
+}
+
+export function GetSearchInfo(searchType, searchName) {
+ return new Promise((resolve, reject) => {
+ request.get("/index.php/index/search?searchType=" + searchType + "&searchName=" + searchName)
+ .then(res => {
+ if (res.Code == "1") {
+ let hsjq = {
+ title: "红色景区",
+ data: res.Data.list.hsjq.map(a => {
+ return {id: a.id, type: a.type, name: a.title, keyWord: a.keywords, img: a.cover_path}
+ })
+ };
+ let hsjs = {
+ title: "红色精神",
+ data: res.Data.list.hsjs.map(a => {
+ return {id: a.id, type: a.type, name: a.title, keyWord: a.keywords, img: a.cover_path}
+ })
+ };
+ let hsjy = {
+ title: "红色记忆",
+ data: res.Data.list.hsjy.map(a => {
+ return {id: a.id, type: a.type, name: a.title, keyWord: a.keywords, img: a.cover_path}
+ })
+ };
+ let hsrw = {
+ title: "红色人物",
+ data: res.Data.list.hsrw.map(a => {
+ return {id: a.id, type: a.type, name: a.title, keyWord: a.keywords, img: a.cover_path}
+ })
+ };
+ resolve({hsjq, hsjs, hsjy, hsrw});
+ } else {
+ reject(res.Message);
+ }
+ }).catch(err => {
+ throw err;
+ });
+ });
+}
+
+export function GetSearchHomeInfo() {
+ return new Promise((resolve, reject) => {
+ request.get("/index.php/index/searchPage")
+ .then(res => {
+ if (res.Code == "1") {
+ let tjss = res.Data.tjss.map(a => {
+ return {id: a.id, title: a.title, type: a.type}
+ });
+ let rmtj = res.Data.rmtj.map(a => {
+ return {id: a.id, title: a.title, type: a.type, coverPath: a.cover_path}
+ });
+ resolve({tjss: tjss, rmtj: rmtj});
+ } else {
+ reject(res.Message);
+ }
+ }).catch(err => {
+ throw err;
+ });
+ });
+}
+
+//dataType(类型): 1=红色记忆,2=红色精神,3=红色景区,4,红色人物
+export function GetDataList(dataType, searchType, searchName, pageIndex, pageSize) {
+ return new Promise((resolve, reject) => {
+ request.get("/index.php/index/list?type=" + dataType + "&searchType=" + searchType + "&searchName=" + searchName + "&page=" + pageIndex + "&rows=" + pageSize)
+ .then(res => {
+ if (res.Code == "1") {
+ console.log(res, "请求响应")
+ let sceneryTabel = {
+ currentPage: Number(res.Data.list.current_page),
+ pageSize: Number(res.Data.list.per_page),
+ total: res.Data.list.total,
+ data: res.Data.list.data.map(t => {
+ return {
+ id: t.id,
+ name: t.title,
+ keyWord: t.keywords,
+ img: t.cover_path,
+ };
+ }),
+ }
+ resolve(sceneryTabel);
+ } else {
+ reject(res.Message);
+ }
+ }).catch(err => {
+ throw err;
+ });
+ });
+}
+
+export function GetDataDetail(id) {
+ return new Promise((resolve, reject) => {
+ request.get("/index.php/index/deails?id=" + id)
+ .then(res => {
+ if (res.Code == "1") {
+ let detail = {
+ id: res.Data.list.id,
+ keyWord: res.Data.list.keywords,
+ introduction: res.Data.list.description,
+ file: res.Data.list.file,
+ }
+ resolve(detail);
+ } else {
+ reject(res.Message);
+ }
+ }).catch(err => {
+ throw err;
+ });
+ });
+}
+
+export function GetDataDetailImages(id, searchType, searchName, page, pageSize) {
+ return new Promise((resolve, reject) => {
+ request.get("/index.php/index/picList?id=" + id + "&searchType=" + searchType + "&searchName=" + searchName + "&page=" + page + "&rows=" + pageSize)
+ .then(res => {
+ if (res.Code == "1") {
+ let images = {
+ pageSize: Number(res.Data.list.per_page),
+ currentPage: Number(res.Data.list.current_page),
+ total: res.Data.list.total,
+ data: res.Data.list.data.map(d => {
+ return {
+ id: d.id,
+ name: d.title,
+ path: d.cover_path,
+ }
+ }),
+ }
+ resolve(images);
+ } else {
+ reject(res.Message);
+ }
+ }).catch(err => {
+ throw err;
+ });
+ });
+}
+
+export function GetDataDetailVideos(id, searchType, searchName, page, pageSize) {
+ return new Promise((resolve, reject) => {
+ request.get("/index.php/index/videoList?id=" + id + "&searchType=" + searchType + "&searchName=" + searchName + "&page=" + page + "&rows=" + pageSize)
+ .then(res => {
+ if (res.Code == "1") {
+ let videos = {
+ pageSize: Number(res.Data.list.per_page),
+ currentPage: Number(res.Data.list.current_page),
+ total: res.Data.list.total,
+ data: res.Data.list.data.map(d => {
+ return {
+ id: d.id,
+ name: d.title,
+ path: d.cover_path,
+ description: d.description,
+ }
+ }),
+ }
+ resolve(videos);
+ } else {
+ reject(res.Message);
+ }
+ }).catch(err => {
+ throw err;
+ });
+ });
+}
+
+export function GetImageDetail(id, page, pid, rows) {
+ return new Promise((resolve, reject) => {
+ request.get("/index.php/index/picDeails?id=" + id + "&page=" + page + "&pid=" + pid + "&rows=" + rows)
+ .then(res => {
+ if (res.Code == "1") {
+ let detail = {
+ pageSize: res.Data.list.per_page,
+ currentPage: res.Data.list.current_page,
+ total: res.Data.list.total,
+ data: res.Data.list.data.map(d => {
+ return {
+ id: d.id,
+ name: d.title,
+ path: d.cover_path,
+ keyWord: d.keywords,
+ introduction: d.description,
+ }
+ }),
+ }
+ resolve(detail);
+ } else {
+ reject(res.Message);
+ }
+ }).catch(err => {
+ throw err;
+ });
+ });
+}
+
+export function GetVideoDetail(id) {
+ return new Promise((resolve, reject) => {
+ request.get("/index.php/index/videoDeails?id=" + id)
+ .then(res => {
+ if (res.Code == "1") {
+ let detail = {
+ id: res.Data.list.id,
+ title: res.Data.list.title,
+ patch: res.Data.list.cover_path,
+ keyWord: res.Data.list.keywords,
+ introduction: res.Data.list.description,
+ }
+ resolve(detail);
+ } else {
+ reject(res.Message);
+ }
+ }).catch(err => {
+ throw err;
+ });
+ });
+}
+
+
diff --git a/src/api/jsonlint.js b/src/api/jsonlint.js
new file mode 100644
index 0000000..19760cd
--- /dev/null
+++ b/src/api/jsonlint.js
@@ -0,0 +1,673 @@
+/* parser generated by jison 0.4.18 */
+/*
+ Returns a Parser object of the following structure:
+
+ Parser: {
+ yy: {}
+ }
+
+ Parser.prototype: {
+ yy: {},
+ trace: function(),
+ symbols_: {associative list: name ==> number},
+ terminals_: {associative list: number ==> name},
+ productions_: [...],
+ performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
+ table: [...],
+ defaultActions: {...},
+ parseError: function(str, hash),
+ parse: function(input),
+
+ lexer: {
+ EOF: 1,
+ parseError: function(str, hash),
+ setInput: function(input),
+ input: function(),
+ unput: function(str),
+ more: function(),
+ less: function(n),
+ pastInput: function(),
+ upcomingInput: function(),
+ showPosition: function(),
+ test_match: function(regex_match_array, rule_index),
+ next: function(),
+ lex: function(),
+ begin: function(condition),
+ popState: function(),
+ _currentRules: function(),
+ topState: function(),
+ pushState: function(condition),
+
+ options: {
+ ranges: boolean (optional: true ==> token location info will include a .range[] member)
+ flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
+ backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
+ },
+
+ performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
+ rules: [...],
+ conditions: {associative list: name ==> set},
+ }
+ }
+
+
+ token location info (@$, _$, etc.): {
+ first_line: n,
+ last_line: n,
+ first_column: n,
+ last_column: n,
+ range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based)
+ }
+
+
+ the parseError function receives a 'hash' object with these members for lexer and parser errors: {
+ text: (matched text)
+ token: (the produced terminal token, if any)
+ line: (yylineno)
+ }
+ while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
+ loc: (yylloc)
+ expected: (string describing the set of expected tokens)
+ recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
+ }
+*/
+var jsonlint = (function(){
+ var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,12],$V1=[1,13],$V2=[1,9],$V3=[1,10],$V4=[1,11],$V5=[1,14],$V6=[1,15],$V7=[14,18,22,24],$V8=[18,22],$V9=[22,24];
+ var parser = {trace: function trace () { },
+ yy: {},
+ symbols_: {"error":2,"JSONString":3,"STRING":4,"JSONNumber":5,"NUMBER":6,"JSONNullLiteral":7,"NULL":8,"JSONBooleanLiteral":9,"TRUE":10,"FALSE":11,"JSONText":12,"JSONValue":13,"EOF":14,"JSONObject":15,"JSONArray":16,"{":17,"}":18,"JSONMemberList":19,"JSONMember":20,":":21,",":22,"[":23,"]":24,"JSONElementList":25,"$accept":0,"$end":1},
+ terminals_: {2:"error",4:"STRING",6:"NUMBER",8:"NULL",10:"TRUE",11:"FALSE",14:"EOF",17:"{",18:"}",21:":",22:",",23:"[",24:"]"},
+ productions_: [0,[3,1],[5,1],[7,1],[9,1],[9,1],[12,2],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[15,2],[15,3],[20,3],[19,1],[19,3],[16,2],[16,3],[25,1],[25,3]],
+ performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
+ /* this == yyval */
+
+ var $0 = $$.length - 1;
+ switch (yystate) {
+ case 1:
+ // replace escaped characters with actual character
+ this.$ = yytext.replace(/\\(\\|")/g, "$"+"1")
+ .replace(/\\n/g,'\n')
+ .replace(/\\r/g,'\r')
+ .replace(/\\t/g,'\t')
+ .replace(/\\v/g,'\v')
+ .replace(/\\f/g,'\f')
+ .replace(/\\b/g,'\b');
+
+ break;
+ case 2:
+ this.$ = yytext == String(Number(yytext))? Number(yytext): yytext;
+ break;
+ case 3:
+ this.$ = null;
+ break;
+ case 4:
+ this.$ = true;
+ break;
+ case 5:
+ this.$ = false;
+ break;
+ case 6:
+ return this.$ = $$[$0-1];
+ break;
+ case 13:
+ this.$ = {};
+ break;
+ case 14: case 19:
+ this.$ = $$[$0-1];
+ break;
+ case 15:
+ this.$ = [$$[$0-2], $$[$0]];
+ break;
+ case 16:
+ this.$ = {}; this.$[$$[$0][0]] = $$[$0][1];
+ break;
+ case 17:
+ this.$ = $$[$0-2]; $$[$0-2][$$[$0][0]] = $$[$0][1];
+ break;
+ case 18:
+ this.$ = [];
+ break;
+ case 20:
+ this.$ = [$$[$0]];
+ break;
+ case 21:
+ this.$ = $$[$0-2]; $$[$0-2].push($$[$0]);
+ break;
+ }
+ },
+ table: [{3:5,4:$V0,5:6,6:$V1,7:3,8:$V2,9:4,10:$V3,11:$V4,12:1,13:2,15:7,16:8,17:$V5,23:$V6},{1:[3]},{14:[1,16]},o($V7,[2,7]),o($V7,[2,8]),o($V7,[2,9]),o($V7,[2,10]),o($V7,[2,11]),o($V7,[2,12]),o($V7,[2,3]),o($V7,[2,4]),o($V7,[2,5]),o([14,18,21,22,24],[2,1]),o($V7,[2,2]),{3:20,4:$V0,18:[1,17],19:18,20:19},{3:5,4:$V0,5:6,6:$V1,7:3,8:$V2,9:4,10:$V3,11:$V4,13:23,15:7,16:8,17:$V5,23:$V6,24:[1,21],25:22},{1:[2,6]},o($V7,[2,13]),{18:[1,24],22:[1,25]},o($V8,[2,16]),{21:[1,26]},o($V7,[2,18]),{22:[1,28],24:[1,27]},o($V9,[2,20]),o($V7,[2,14]),{3:20,4:$V0,20:29},{3:5,4:$V0,5:6,6:$V1,7:3,8:$V2,9:4,10:$V3,11:$V4,13:30,15:7,16:8,17:$V5,23:$V6},o($V7,[2,19]),{3:5,4:$V0,5:6,6:$V1,7:3,8:$V2,9:4,10:$V3,11:$V4,13:31,15:7,16:8,17:$V5,23:$V6},o($V8,[2,17]),o($V8,[2,15]),o($V9,[2,21])],
+ defaultActions: {16:[2,6]},
+ parseError: function parseError (str, hash) {
+ if (hash.recoverable) {
+ this.trace(str);
+ } else {
+ var error = new Error(str);
+ error.hash = hash;
+ throw error;
+ }
+ },
+ parse: function parse(input) {
+ var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
+ var args = lstack.slice.call(arguments, 1);
+ var lexer = Object.create(this.lexer);
+ var sharedState = { yy: {} };
+ for (var k in this.yy) {
+ if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
+ sharedState.yy[k] = this.yy[k];
+ }
+ }
+ lexer.setInput(input, sharedState.yy);
+ sharedState.yy.lexer = lexer;
+ sharedState.yy.parser = this;
+ if (typeof lexer.yylloc == 'undefined') {
+ lexer.yylloc = {};
+ }
+ var yyloc = lexer.yylloc;
+ lstack.push(yyloc);
+ var ranges = lexer.options && lexer.options.ranges;
+ if (typeof sharedState.yy.parseError === 'function') {
+ this.parseError = sharedState.yy.parseError;
+ } else {
+ this.parseError = Object.getPrototypeOf(this).parseError;
+ }
+ function popStack(n) {
+ stack.length = stack.length - 2 * n;
+ vstack.length = vstack.length - n;
+ lstack.length = lstack.length - n;
+ }
+ _token_stack:
+ var lex = function () {
+ var token;
+ token = lexer.lex() || EOF;
+ if (typeof token !== 'number') {
+ token = self.symbols_[token] || token;
+ }
+ return token;
+ };
+ var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
+ while (true) {
+ state = stack[stack.length - 1];
+ if (this.defaultActions[state]) {
+ action = this.defaultActions[state];
+ } else {
+ if (symbol === null || typeof symbol == 'undefined') {
+ symbol = lex();
+ }
+ action = table[state] && table[state][symbol];
+ }
+ if (typeof action === 'undefined' || !action.length || !action[0]) {
+ var errStr = '';
+ expected = [];
+ for (p in table[state]) {
+ if (this.terminals_[p] && p > TERROR) {
+ expected.push('\'' + this.terminals_[p] + '\'');
+ }
+ }
+ if (lexer.showPosition) {
+ errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\'';
+ } else {
+ errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\'');
+ }
+ this.parseError(errStr, {
+ text: lexer.match,
+ token: this.terminals_[symbol] || symbol,
+ line: lexer.yylineno,
+ loc: yyloc,
+ expected: expected
+ });
+ }
+ if (action[0] instanceof Array && action.length > 1) {
+ throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
+ }
+ switch (action[0]) {
+ case 1:
+ stack.push(symbol);
+ vstack.push(lexer.yytext);
+ lstack.push(lexer.yylloc);
+ stack.push(action[1]);
+ symbol = null;
+ if (!preErrorSymbol) {
+ yyleng = lexer.yyleng;
+ yytext = lexer.yytext;
+ yylineno = lexer.yylineno;
+ yyloc = lexer.yylloc;
+ if (recovering > 0) {
+ recovering--;
+ }
+ } else {
+ symbol = preErrorSymbol;
+ preErrorSymbol = null;
+ }
+ break;
+ case 2:
+ len = this.productions_[action[1]][1];
+ yyval.$ = vstack[vstack.length - len];
+ yyval._$ = {
+ first_line: lstack[lstack.length - (len || 1)].first_line,
+ last_line: lstack[lstack.length - 1].last_line,
+ first_column: lstack[lstack.length - (len || 1)].first_column,
+ last_column: lstack[lstack.length - 1].last_column
+ };
+ if (ranges) {
+ yyval._$.range = [
+ lstack[lstack.length - (len || 1)].range[0],
+ lstack[lstack.length - 1].range[1]
+ ];
+ }
+ r = this.performAction.apply(yyval, [
+ yytext,
+ yyleng,
+ yylineno,
+ sharedState.yy,
+ action[1],
+ vstack,
+ lstack
+ ].concat(args));
+ if (typeof r !== 'undefined') {
+ return r;
+ }
+ if (len) {
+ stack = stack.slice(0, -1 * len * 2);
+ vstack = vstack.slice(0, -1 * len);
+ lstack = lstack.slice(0, -1 * len);
+ }
+ stack.push(this.productions_[action[1]][0]);
+ vstack.push(yyval.$);
+ lstack.push(yyval._$);
+ newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
+ stack.push(newState);
+ break;
+ case 3:
+ return true;
+ }
+ }
+ return true;
+ }};
+ /* generated by jison-lex 0.3.4 */
+ var lexer = (function(){
+ var lexer = ({
+
+ EOF:1,
+
+ parseError:function parseError(str, hash) {
+ if (this.yy.parser) {
+ this.yy.parser.parseError(str, hash);
+ } else {
+ throw new Error(str);
+ }
+ },
+
+// resets the lexer, sets new input
+ setInput:function (input, yy) {
+ this.yy = yy || this.yy || {};
+ this._input = input;
+ this._more = this._backtrack = this.done = false;
+ this.yylineno = this.yyleng = 0;
+ this.yytext = this.matched = this.match = '';
+ this.conditionStack = ['INITIAL'];
+ this.yylloc = {
+ first_line: 1,
+ first_column: 0,
+ last_line: 1,
+ last_column: 0
+ };
+ if (this.options.ranges) {
+ this.yylloc.range = [0,0];
+ }
+ this.offset = 0;
+ return this;
+ },
+
+// consumes and returns one char from the input
+ input:function () {
+ var ch = this._input[0];
+ this.yytext += ch;
+ this.yyleng++;
+ this.offset++;
+ this.match += ch;
+ this.matched += ch;
+ var lines = ch.match(/(?:\r\n?|\n).*/g);
+ if (lines) {
+ this.yylineno++;
+ this.yylloc.last_line++;
+ } else {
+ this.yylloc.last_column++;
+ }
+ if (this.options.ranges) {
+ this.yylloc.range[1]++;
+ }
+
+ this._input = this._input.slice(1);
+ return ch;
+ },
+
+// unshifts one char (or a string) into the input
+ unput:function (ch) {
+ var len = ch.length;
+ var lines = ch.split(/(?:\r\n?|\n)/g);
+
+ this._input = ch + this._input;
+ this.yytext = this.yytext.substr(0, this.yytext.length - len);
+ //this.yyleng -= len;
+ this.offset -= len;
+ var oldLines = this.match.split(/(?:\r\n?|\n)/g);
+ this.match = this.match.substr(0, this.match.length - 1);
+ this.matched = this.matched.substr(0, this.matched.length - 1);
+
+ if (lines.length - 1) {
+ this.yylineno -= lines.length - 1;
+ }
+ var r = this.yylloc.range;
+
+ this.yylloc = {
+ first_line: this.yylloc.first_line,
+ last_line: this.yylineno + 1,
+ first_column: this.yylloc.first_column,
+ last_column: lines ?
+ (lines.length === oldLines.length ? this.yylloc.first_column : 0)
+ + oldLines[oldLines.length - lines.length].length - lines[0].length :
+ this.yylloc.first_column - len
+ };
+
+ if (this.options.ranges) {
+ this.yylloc.range = [r[0], r[0] + this.yyleng - len];
+ }
+ this.yyleng = this.yytext.length;
+ return this;
+ },
+
+// When called from action, caches matched text and appends it on next action
+ more:function () {
+ this._more = true;
+ return this;
+ },
+
+// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
+ reject:function () {
+ if (this.options.backtrack_lexer) {
+ this._backtrack = true;
+ } else {
+ return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
+ text: "",
+ token: null,
+ line: this.yylineno
+ });
+
+ }
+ return this;
+ },
+
+// retain first n characters of the match
+ less:function (n) {
+ this.unput(this.match.slice(n));
+ },
+
+// displays already matched input, i.e. for error messages
+ pastInput:function () {
+ var past = this.matched.substr(0, this.matched.length - this.match.length);
+ return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
+ },
+
+// displays upcoming input, i.e. for error messages
+ upcomingInput:function () {
+ var next = this.match;
+ if (next.length < 20) {
+ next += this._input.substr(0, 20-next.length);
+ }
+ return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
+ },
+
+// displays the character position where the lexing error occurred, i.e. for error messages
+ showPosition:function () {
+ var pre = this.pastInput();
+ var c = new Array(pre.length + 1).join("-");
+ return pre + this.upcomingInput() + "\n" + c + "^";
+ },
+
+// test the lexed token: return FALSE when not a match, otherwise return token
+ test_match:function(match, indexed_rule) {
+ var token,
+ lines,
+ backup;
+
+ if (this.options.backtrack_lexer) {
+ // save context
+ backup = {
+ yylineno: this.yylineno,
+ yylloc: {
+ first_line: this.yylloc.first_line,
+ last_line: this.last_line,
+ first_column: this.yylloc.first_column,
+ last_column: this.yylloc.last_column
+ },
+ yytext: this.yytext,
+ match: this.match,
+ matches: this.matches,
+ matched: this.matched,
+ yyleng: this.yyleng,
+ offset: this.offset,
+ _more: this._more,
+ _input: this._input,
+ yy: this.yy,
+ conditionStack: this.conditionStack.slice(0),
+ done: this.done
+ };
+ if (this.options.ranges) {
+ backup.yylloc.range = this.yylloc.range.slice(0);
+ }
+ }
+
+ lines = match[0].match(/(?:\r\n?|\n).*/g);
+ if (lines) {
+ this.yylineno += lines.length;
+ }
+ this.yylloc = {
+ first_line: this.yylloc.last_line,
+ last_line: this.yylineno + 1,
+ first_column: this.yylloc.last_column,
+ last_column: lines ?
+ lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
+ this.yylloc.last_column + match[0].length
+ };
+ this.yytext += match[0];
+ this.match += match[0];
+ this.matches = match;
+ this.yyleng = this.yytext.length;
+ if (this.options.ranges) {
+ this.yylloc.range = [this.offset, this.offset += this.yyleng];
+ }
+ this._more = false;
+ this._backtrack = false;
+ this._input = this._input.slice(match[0].length);
+ this.matched += match[0];
+ token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
+ if (this.done && this._input) {
+ this.done = false;
+ }
+ if (token) {
+ return token;
+ } else if (this._backtrack) {
+ // recover context
+ for (var k in backup) {
+ this[k] = backup[k];
+ }
+ return false; // rule action called reject() implying the next rule should be tested instead.
+ }
+ return false;
+ },
+
+// return next match in input
+ next:function () {
+ if (this.done) {
+ return this.EOF;
+ }
+ if (!this._input) {
+ this.done = true;
+ }
+
+ var token,
+ match,
+ tempMatch,
+ index;
+ if (!this._more) {
+ this.yytext = '';
+ this.match = '';
+ }
+ var rules = this._currentRules();
+ for (var i = 0; i < rules.length; i++) {
+ tempMatch = this._input.match(this.rules[rules[i]]);
+ if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
+ match = tempMatch;
+ index = i;
+ if (this.options.backtrack_lexer) {
+ token = this.test_match(tempMatch, rules[i]);
+ if (token !== false) {
+ return token;
+ } else if (this._backtrack) {
+ match = false;
+ continue; // rule action called reject() implying a rule MISmatch.
+ } else {
+ // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
+ return false;
+ }
+ } else if (!this.options.flex) {
+ break;
+ }
+ }
+ }
+ if (match) {
+ token = this.test_match(match, rules[index]);
+ if (token !== false) {
+ return token;
+ }
+ // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
+ return false;
+ }
+ if (this._input === "") {
+ return this.EOF;
+ } else {
+ return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
+ text: "",
+ token: null,
+ line: this.yylineno
+ });
+ }
+ },
+
+// return next match that has a token
+ lex:function lex () {
+ var r = this.next();
+ if (r) {
+ return r;
+ } else {
+ return this.lex();
+ }
+ },
+
+// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
+ begin:function begin (condition) {
+ this.conditionStack.push(condition);
+ },
+
+// pop the previously active lexer condition state off the condition stack
+ popState:function popState () {
+ var n = this.conditionStack.length - 1;
+ if (n > 0) {
+ return this.conditionStack.pop();
+ } else {
+ return this.conditionStack[0];
+ }
+ },
+
+// produce the lexer rule set which is active for the currently active lexer condition state
+ _currentRules:function _currentRules () {
+ if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
+ return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
+ } else {
+ return this.conditions["INITIAL"].rules;
+ }
+ },
+
+// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
+ topState:function topState (n) {
+ n = this.conditionStack.length - 1 - Math.abs(n || 0);
+ if (n >= 0) {
+ return this.conditionStack[n];
+ } else {
+ return "INITIAL";
+ }
+ },
+
+// alias for begin(condition)
+ pushState:function pushState (condition) {
+ this.begin(condition);
+ },
+
+// return the number of states currently on the stack
+ stateStackSize:function stateStackSize() {
+ return this.conditionStack.length;
+ },
+ options: {},
+ performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
+ var YYSTATE=YY_START;
+ switch($avoiding_name_collisions) {
+ case 0:/* skip whitespace */
+ break;
+ case 1:return 6
+ break;
+ case 2:yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2); return 4
+ break;
+ case 3:return 17
+ break;
+ case 4:return 18
+ break;
+ case 5:return 23
+ break;
+ case 6:return 24
+ break;
+ case 7:return 22
+ break;
+ case 8:return 21
+ break;
+ case 9:return 10
+ break;
+ case 10:return 11
+ break;
+ case 11:return 8
+ break;
+ case 12:return 14
+ break;
+ case 13:return 'INVALID'
+ break;
+ }
+ },
+ rules: [/^(?:\s+)/,/^(?:(-?([0-9]|[1-9][0-9]+))(\.[0-9]+)?([eE][-+]?[0-9]+)?\b)/,/^(?:"(?:\\[\\"bfnrt/]|\\u[a-fA-F0-9]{4}|[^\\\0-\x09\x0a-\x1f"])*")/,/^(?:\{)/,/^(?:\})/,/^(?:\[)/,/^(?:\])/,/^(?:,)/,/^(?::)/,/^(?:true\b)/,/^(?:false\b)/,/^(?:null\b)/,/^(?:$)/,/^(?:.)/],
+ conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13],"inclusive":true}}
+ });
+ return lexer;
+ })();
+ parser.lexer = lexer;
+ function Parser () {
+ this.yy = {};
+ }
+ Parser.prototype = parser;parser.Parser = Parser;
+ return new Parser;
+})();
+
+
+if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
+ exports.parser = jsonlint;
+ exports.Parser = jsonlint.Parser;
+ exports.parse = function () { return jsonlint.parse.apply(jsonlint, arguments); };
+ exports.main = function commonjsMain (args) {
+ if (!args[1]) {
+ console.log('Usage: '+args[0]+' FILE');
+ process.exit(1);
+ }
+ var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
+ return exports.parser.parse(source);
+ };
+ if (typeof module !== 'undefined' && require.main === module) {
+ exports.main(process.argv.slice(1));
+ }
+}
diff --git a/src/api/request.js b/src/api/request.js
new file mode 100644
index 0000000..6896ae9
--- /dev/null
+++ b/src/api/request.js
@@ -0,0 +1,74 @@
+import axios from 'axios'
+import {Message} from 'element-ui'
+import jsonlint from "@/api/jsonlint.js"
+
+const service = axios.create({
+ baseURL: process.env.VUE_APP_BASE_API,
+ timeout: 60000, // request timeout
+ headers: {},
+ transformResponse: [function (data) {
+ if (typeof data == "string") {
+ try {
+ data = jsonlint.parse((data));
+ } catch (e) {
+ console.log(e, 'axios:transformResponse异常');
+ }
+ }
+ return data;
+ }]
+})
+
+service.interceptors.request.use(
+ config => {
+ return config
+ },
+ error => {
+ return Promise.reject(error)
+ })
+
+service.interceptors.response.use(
+ response => {
+ if (response.status == 200) {
+ const resData = response.data;
+ return resData;
+ } else {
+ return Promise.reject(response)
+ }
+ },
+ error => {
+ Message({message: error.response.data.msg || '系统错误', type: 'error', duration: 2 * 1000})
+ return Promise.reject(error)
+ })
+
+export default {
+ //get请求
+ get(url, param) {
+ return new Promise(resolve => {
+ service({
+ method: 'get',
+ url,
+ params: param,
+ }).then(res => {
+ resolve(res);
+ }).catch(err => {
+ console.log(err, 'axios异常');
+ throw err;
+ });
+ });
+ },
+ //post请求
+ post(url, param) {
+ return new Promise(resolve => {
+ service({
+ method: 'post',
+ url,
+ data: param,
+ }).then(res => {
+ resolve(res);
+ }).catch(err => {
+ console.log(err, 'axios异常');
+ throw err;
+ });
+ });
+ },
+}
diff --git a/src/assets/datadetail/detail@1x.png b/src/assets/datadetail/detail@1x.png
new file mode 100644
index 0000000..508f6d2
--- /dev/null
+++ b/src/assets/datadetail/detail@1x.png
Binary files differ
diff --git a/src/assets/datalist/datalist@1x.png b/src/assets/datalist/datalist@1x.png
new file mode 100644
index 0000000..882abec
--- /dev/null
+++ b/src/assets/datalist/datalist@1x.png
Binary files differ
diff --git a/src/assets/home_background@1x.png b/src/assets/home_background@1x.png
new file mode 100644
index 0000000..6fcb834
--- /dev/null
+++ b/src/assets/home_background@1x.png
Binary files differ
diff --git a/src/assets/icon/demo.css b/src/assets/icon/demo.css
new file mode 100644
index 0000000..a67054a
--- /dev/null
+++ b/src/assets/icon/demo.css
@@ -0,0 +1,539 @@
+/* Logo 字体 */
+@font-face {
+ font-family: "iconfont logo";
+ src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
+ src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
+ url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
+ url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
+ url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
+}
+
+.logo {
+ font-family: "iconfont logo";
+ font-size: 160px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+/* tabs */
+.nav-tabs {
+ position: relative;
+}
+
+.nav-tabs .nav-more {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ height: 42px;
+ line-height: 42px;
+ color: #666;
+}
+
+#tabs {
+ border-bottom: 1px solid #eee;
+}
+
+#tabs li {
+ cursor: pointer;
+ width: 100px;
+ height: 40px;
+ line-height: 40px;
+ text-align: center;
+ font-size: 16px;
+ border-bottom: 2px solid transparent;
+ position: relative;
+ z-index: 1;
+ margin-bottom: -1px;
+ color: #666;
+}
+
+
+#tabs .active {
+ border-bottom-color: #f00;
+ color: #222;
+}
+
+.tab-container .content {
+ display: none;
+}
+
+/* 页面布局 */
+.main {
+ padding: 30px 100px;
+ width: 960px;
+ margin: 0 auto;
+}
+
+.main .logo {
+ color: #333;
+ text-align: left;
+ margin-bottom: 30px;
+ line-height: 1;
+ height: 110px;
+ margin-top: -50px;
+ overflow: hidden;
+ *zoom: 1;
+}
+
+.main .logo a {
+ font-size: 160px;
+ color: #333;
+}
+
+.helps {
+ margin-top: 40px;
+}
+
+.helps pre {
+ padding: 20px;
+ margin: 10px 0;
+ border: solid 1px #e7e1cd;
+ background-color: #fffdef;
+ overflow: auto;
+}
+
+.icon_lists {
+ width: 100% !important;
+ overflow: hidden;
+ *zoom: 1;
+}
+
+.icon_lists li {
+ width: 100px;
+ margin-bottom: 10px;
+ margin-right: 20px;
+ text-align: center;
+ list-style: none !important;
+ cursor: default;
+}
+
+.icon_lists li .code-name {
+ line-height: 1.2;
+}
+
+.icon_lists .icon {
+ display: block;
+ height: 100px;
+ line-height: 100px;
+ font-size: 42px;
+ margin: 10px auto;
+ color: #333;
+ -webkit-transition: font-size 0.25s linear, width 0.25s linear;
+ -moz-transition: font-size 0.25s linear, width 0.25s linear;
+ transition: font-size 0.25s linear, width 0.25s linear;
+}
+
+.icon_lists .icon:hover {
+ font-size: 100px;
+}
+
+.icon_lists .svg-icon {
+ /* 通过设置 font-size 来改变图标大小 */
+ width: 1em;
+ /* 图标和文字相邻时,垂直对齐 */
+ vertical-align: -0.15em;
+ /* 通过设置 color 来改变 SVG 的颜色/fill */
+ fill: currentColor;
+ /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
+ normalize.css 中也包含这行 */
+ overflow: hidden;
+}
+
+.icon_lists li .name,
+.icon_lists li .code-name {
+ color: #666;
+}
+
+/* markdown 样式 */
+.markdown {
+ color: #666;
+ font-size: 14px;
+ line-height: 1.8;
+}
+
+.highlight {
+ line-height: 1.5;
+}
+
+.markdown img {
+ vertical-align: middle;
+ max-width: 100%;
+}
+
+.markdown h1 {
+ color: #404040;
+ font-weight: 500;
+ line-height: 40px;
+ margin-bottom: 24px;
+}
+
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+ color: #404040;
+ margin: 1.6em 0 0.6em 0;
+ font-weight: 500;
+ clear: both;
+}
+
+.markdown h1 {
+ font-size: 28px;
+}
+
+.markdown h2 {
+ font-size: 22px;
+}
+
+.markdown h3 {
+ font-size: 16px;
+}
+
+.markdown h4 {
+ font-size: 14px;
+}
+
+.markdown h5 {
+ font-size: 12px;
+}
+
+.markdown h6 {
+ font-size: 12px;
+}
+
+.markdown hr {
+ height: 1px;
+ border: 0;
+ background: #e9e9e9;
+ margin: 16px 0;
+ clear: both;
+}
+
+.markdown p {
+ margin: 1em 0;
+}
+
+.markdown>p,
+.markdown>blockquote,
+.markdown>.highlight,
+.markdown>ol,
+.markdown>ul {
+ width: 80%;
+}
+
+.markdown ul>li {
+ list-style: circle;
+}
+
+.markdown>ul li,
+.markdown blockquote ul>li {
+ margin-left: 20px;
+ padding-left: 4px;
+}
+
+.markdown>ul li p,
+.markdown>ol li p {
+ margin: 0.6em 0;
+}
+
+.markdown ol>li {
+ list-style: decimal;
+}
+
+.markdown>ol li,
+.markdown blockquote ol>li {
+ margin-left: 20px;
+ padding-left: 4px;
+}
+
+.markdown code {
+ margin: 0 3px;
+ padding: 0 5px;
+ background: #eee;
+ border-radius: 3px;
+}
+
+.markdown strong,
+.markdown b {
+ font-weight: 600;
+}
+
+.markdown>table {
+ border-collapse: collapse;
+ border-spacing: 0px;
+ empty-cells: show;
+ border: 1px solid #e9e9e9;
+ width: 95%;
+ margin-bottom: 24px;
+}
+
+.markdown>table th {
+ white-space: nowrap;
+ color: #333;
+ font-weight: 600;
+}
+
+.markdown>table th,
+.markdown>table td {
+ border: 1px solid #e9e9e9;
+ padding: 8px 16px;
+ text-align: left;
+}
+
+.markdown>table th {
+ background: #F7F7F7;
+}
+
+.markdown blockquote {
+ font-size: 90%;
+ color: #999;
+ border-left: 4px solid #e9e9e9;
+ padding-left: 0.8em;
+ margin: 1em 0;
+}
+
+.markdown blockquote p {
+ margin: 0;
+}
+
+.markdown .anchor {
+ opacity: 0;
+ transition: opacity 0.3s ease;
+ margin-left: 8px;
+}
+
+.markdown .waiting {
+ color: #ccc;
+}
+
+.markdown h1:hover .anchor,
+.markdown h2:hover .anchor,
+.markdown h3:hover .anchor,
+.markdown h4:hover .anchor,
+.markdown h5:hover .anchor,
+.markdown h6:hover .anchor {
+ opacity: 1;
+ display: inline-block;
+}
+
+.markdown>br,
+.markdown>p>br {
+ clear: both;
+}
+
+
+.hljs {
+ display: block;
+ background: white;
+ padding: 0.5em;
+ color: #333333;
+ overflow-x: auto;
+}
+
+.hljs-comment,
+.hljs-meta {
+ color: #969896;
+}
+
+.hljs-string,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-strong,
+.hljs-emphasis,
+.hljs-quote {
+ color: #df5000;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-type {
+ color: #a71d5d;
+}
+
+.hljs-literal,
+.hljs-symbol,
+.hljs-bullet,
+.hljs-attribute {
+ color: #0086b3;
+}
+
+.hljs-section,
+.hljs-name {
+ color: #63a35c;
+}
+
+.hljs-tag {
+ color: #333333;
+}
+
+.hljs-title,
+.hljs-attr,
+.hljs-selector-id,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo {
+ color: #795da3;
+}
+
+.hljs-addition {
+ color: #55a532;
+ background-color: #eaffea;
+}
+
+.hljs-deletion {
+ color: #bd2c00;
+ background-color: #ffecec;
+}
+
+.hljs-link {
+ text-decoration: underline;
+}
+
+/* 代码高亮 */
+/* PrismJS 1.15.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+code[class*="language-"],
+pre[class*="language-"] {
+ color: black;
+ background: none;
+ text-shadow: 0 1px white;
+ font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+ text-align: left;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ word-wrap: normal;
+ line-height: 1.5;
+
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+
+ -webkit-hyphens: none;
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+ text-shadow: none;
+ background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+ text-shadow: none;
+ background: #b3d4fc;
+}
+
+@media print {
+
+ code[class*="language-"],
+ pre[class*="language-"] {
+ text-shadow: none;
+ }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+ padding: 1em;
+ margin: .5em 0;
+ overflow: auto;
+}
+
+:not(pre)>code[class*="language-"],
+pre[class*="language-"] {
+ background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre)>code[class*="language-"] {
+ padding: .1em;
+ border-radius: .3em;
+ white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+ color: slategray;
+}
+
+.token.punctuation {
+ color: #999;
+}
+
+.namespace {
+ opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+ color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+ color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+ color: #9a6e3a;
+ background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+ color: #07a;
+}
+
+.token.function,
+.token.class-name {
+ color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+ color: #e90;
+}
+
+.token.important,
+.token.bold {
+ font-weight: bold;
+}
+
+.token.italic {
+ font-style: italic;
+}
+
+.token.entity {
+ cursor: help;
+}
diff --git a/src/assets/icon/demo_index.html b/src/assets/icon/demo_index.html
new file mode 100644
index 0000000..0e9f7a8
--- /dev/null
+++ b/src/assets/icon/demo_index.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8"/>
+ <title>iconfont Demo</title>
+ <link rel="shortcut icon" href="//img.alicdn.com/imgextra/i2/O1CN01ZyAlrn1MwaMhqz36G_!!6000000001499-73-tps-64-64.ico" type="image/x-icon"/>
+ <link rel="icon" type="image/svg+xml" href="//img.alicdn.com/imgextra/i4/O1CN01EYTRnJ297D6vehehJ_!!6000000008020-55-tps-64-64.svg"/>
+ <link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
+ <link rel="stylesheet" href="demo.css">
+ <link rel="stylesheet" href="iconfont.css">
+ <script src="iconfont.js"></script>
+ <!-- jQuery -->
+ <script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
+ <!-- 代码高亮 -->
+ <script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
+ <style>
+ .main .logo {
+ margin-top: 0;
+ height: auto;
+ }
+
+ .main .logo a {
+ display: flex;
+ align-items: center;
+ }
+
+ .main .logo .sub-title {
+ margin-left: 0.5em;
+ font-size: 22px;
+ color: #fff;
+ background: linear-gradient(-45deg, #3967FF, #B500FE);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ }
+ </style>
+</head>
+<body>
+ <div class="main">
+ <h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank">
+ <img width="200" src="https://img.alicdn.com/imgextra/i3/O1CN01Mn65HV1FfSEzR6DKv_!!6000000000514-55-tps-228-59.svg">
+
+ </a></h1>
+ <div class="nav-tabs">
+ <ul id="tabs" class="dib-box">
+ <li class="dib active"><span>Unicode</span></li>
+ <li class="dib"><span>Font class</span></li>
+ <li class="dib"><span>Symbol</span></li>
+ </ul>
+
+ <a href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=2997242" target="_blank" class="nav-more">查看项目</a>
+
+ </div>
+ <div class="tab-container">
+ <div class="content unicode" style="display: block;">
+ <ul class="icon_lists dib-box">
+
+ <li class="dib">
+ <span class="icon iconfont"></span>
+ <div class="name">search</div>
+ <div class="code-name">&#xe82e;</div>
+ </li>
+
+ </ul>
+ <div class="article markdown">
+ <h2 id="unicode-">Unicode 引用</h2>
+ <hr>
+
+ <p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
+ <ul>
+ <li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
+ <li>默认情况下不支持多色,直接添加多色图标会自动去色。</li>
+ </ul>
+ <blockquote>
+ <p>注意:新版 iconfont 支持两种方式引用多色图标:SVG symbol 引用方式和彩色字体图标模式。(使用彩色字体图标需要在「编辑项目」中开启「彩色」选项后并重新生成。)</p>
+ </blockquote>
+ <p>Unicode 使用步骤如下:</p>
+ <h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
+<pre><code class="language-css"
+>@font-face {
+ font-family: 'iconfont';
+ src: url('iconfont.woff2?t=1638945390871') format('woff2'),
+ url('iconfont.woff?t=1638945390871') format('woff'),
+ url('iconfont.ttf?t=1638945390871') format('truetype');
+}
+</code></pre>
+ <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
+<pre><code class="language-css"
+>.iconfont {
+ font-family: "iconfont" !important;
+ font-size: 16px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+</code></pre>
+ <h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
+<pre>
+<code class="language-html"
+><span class="iconfont">&#x33;</span>
+</code></pre>
+ <blockquote>
+ <p>"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
+ </blockquote>
+ </div>
+ </div>
+ <div class="content font-class">
+ <ul class="icon_lists dib-box">
+
+ <li class="dib">
+ <span class="icon iconfont icon-search"></span>
+ <div class="name">
+ search
+ </div>
+ <div class="code-name">.icon-search
+ </div>
+ </li>
+
+ </ul>
+ <div class="article markdown">
+ <h2 id="font-class-">font-class 引用</h2>
+ <hr>
+
+ <p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
+ <p>与 Unicode 使用方式相比,具有如下特点:</p>
+ <ul>
+ <li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
+ <li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
+ </ul>
+ <p>使用步骤如下:</p>
+ <h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
+<pre><code class="language-html"><link rel="stylesheet" href="./iconfont.css">
+</code></pre>
+ <h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
+<pre><code class="language-html"><span class="iconfont icon-xxx"></span>
+</code></pre>
+ <blockquote>
+ <p>"
+ iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
+ </blockquote>
+ </div>
+ </div>
+ <div class="content symbol">
+ <ul class="icon_lists dib-box">
+
+ <li class="dib">
+ <svg class="icon svg-icon" aria-hidden="true">
+ <use xlink:href="#icon-search"></use>
+ </svg>
+ <div class="name">search</div>
+ <div class="code-name">#icon-search</div>
+ </li>
+
+ </ul>
+ <div class="article markdown">
+ <h2 id="symbol-">Symbol 引用</h2>
+ <hr>
+
+ <p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
+ 这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
+ <ul>
+ <li>支持多色图标了,不再受单色限制。</li>
+ <li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
+ <li>兼容性较差,支持 IE9+,及现代浏览器。</li>
+ <li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
+ </ul>
+ <p>使用步骤如下:</p>
+ <h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
+<pre><code class="language-html"><script src="./iconfont.js"></script>
+</code></pre>
+ <h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
+<pre><code class="language-html"><style>
+.icon {
+ width: 1em;
+ height: 1em;
+ vertical-align: -0.15em;
+ fill: currentColor;
+ overflow: hidden;
+}
+</style>
+</code></pre>
+ <h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
+<pre><code class="language-html"><svg class="icon" aria-hidden="true">
+ <use xlink:href="#icon-xxx"></use>
+</svg>
+</code></pre>
+ </div>
+ </div>
+
+ </div>
+ </div>
+ <script>
+ $(document).ready(function () {
+ $('.tab-container .content:first').show()
+
+ $('#tabs li').click(function (e) {
+ var tabContent = $('.tab-container .content')
+ var index = $(this).index()
+
+ if ($(this).hasClass('active')) {
+ return
+ } else {
+ $('#tabs li').removeClass('active')
+ $(this).addClass('active')
+
+ tabContent.hide().eq(index).fadeIn()
+ }
+ })
+ })
+ </script>
+</body>
+</html>
diff --git a/src/assets/icon/iconfont.css b/src/assets/icon/iconfont.css
new file mode 100644
index 0000000..0061006
--- /dev/null
+++ b/src/assets/icon/iconfont.css
@@ -0,0 +1,19 @@
+@font-face {
+ font-family: "iconfont"; /* Project id 2997242 */
+ src: url('iconfont.woff2?t=1638945390871') format('woff2'),
+ url('iconfont.woff?t=1638945390871') format('woff'),
+ url('iconfont.ttf?t=1638945390871') format('truetype');
+}
+
+.iconfont {
+ font-family: "iconfont" !important;
+ font-size: 16px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-search:before {
+ content: "\e82e";
+}
+
diff --git a/src/assets/icon/iconfont.js b/src/assets/icon/iconfont.js
new file mode 100644
index 0000000..b99950c
--- /dev/null
+++ b/src/assets/icon/iconfont.js
@@ -0,0 +1 @@
+!function(e){var t,n,o,i,c,d='<svg><symbol id="icon-search" viewBox="0 0 1024 1024"><path d="M1005.312 914.752l-198.528-198.464A448 448 0 1 0 0 448a448 448 0 0 0 716.288 358.784l198.4 198.4a64 64 0 1 0 90.624-90.432zM448 767.936A320 320 0 1 1 448 128a320 320 0 0 1 0 640z" fill="#262626" ></path></symbol></svg>',a=(a=document.getElementsByTagName("script"))[a.length-1].getAttribute("data-injectcss"),l=function(e,t){t.parentNode.insertBefore(e,t)};if(a&&!e.__iconfont__svg__cssinject__){e.__iconfont__svg__cssinject__=!0;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(e){console&&console.log(e)}}function s(){c||(c=!0,o())}function r(){try{i.documentElement.doScroll("left")}catch(e){return void setTimeout(r,50)}s()}t=function(){var e,t;(t=document.createElement("div")).innerHTML=d,d=null,(e=t.getElementsByTagName("svg")[0])&&(e.setAttribute("aria-hidden","true"),e.style.position="absolute",e.style.width=0,e.style.height=0,e.style.overflow="hidden",t=e,(e=document.body).firstChild?l(t,e.firstChild):e.appendChild(t))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(t,0):(n=function(){document.removeEventListener("DOMContentLoaded",n,!1),t()},document.addEventListener("DOMContentLoaded",n,!1)):document.attachEvent&&(o=t,i=e.document,c=!1,r(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,s())})}(window);
\ No newline at end of file
diff --git a/src/assets/icon/iconfont.json b/src/assets/icon/iconfont.json
new file mode 100644
index 0000000..7ae7f94
--- /dev/null
+++ b/src/assets/icon/iconfont.json
@@ -0,0 +1,16 @@
+{
+ "id": "2997242",
+ "name": "name",
+ "font_family": "iconfont",
+ "css_prefix_text": "icon-",
+ "description": "",
+ "glyphs": [
+ {
+ "icon_id": "6151301",
+ "name": "search",
+ "font_class": "search",
+ "unicode": "e82e",
+ "unicode_decimal": 59438
+ }
+ ]
+}
diff --git a/src/assets/icon/iconfont.ttf b/src/assets/icon/iconfont.ttf
new file mode 100644
index 0000000..fded390
--- /dev/null
+++ b/src/assets/icon/iconfont.ttf
Binary files differ
diff --git a/src/assets/icon/iconfont.woff b/src/assets/icon/iconfont.woff
new file mode 100644
index 0000000..c955146
--- /dev/null
+++ b/src/assets/icon/iconfont.woff
Binary files differ
diff --git a/src/assets/icon/iconfont.woff2 b/src/assets/icon/iconfont.woff2
new file mode 100644
index 0000000..02c10a9
--- /dev/null
+++ b/src/assets/icon/iconfont.woff2
Binary files differ
diff --git a/src/assets/nav_memory@1x.png b/src/assets/nav_memory@1x.png
new file mode 100644
index 0000000..aeedcd7
--- /dev/null
+++ b/src/assets/nav_memory@1x.png
Binary files differ
diff --git a/src/assets/nav_personage@1x.png b/src/assets/nav_personage@1x.png
new file mode 100644
index 0000000..dd3b123
--- /dev/null
+++ b/src/assets/nav_personage@1x.png
Binary files differ
diff --git a/src/assets/nav_scenery@1x.png b/src/assets/nav_scenery@1x.png
new file mode 100644
index 0000000..f9be825
--- /dev/null
+++ b/src/assets/nav_scenery@1x.png
Binary files differ
diff --git a/src/assets/nav_spirit@1x.png b/src/assets/nav_spirit@1x.png
new file mode 100644
index 0000000..0b83fc3
--- /dev/null
+++ b/src/assets/nav_spirit@1x.png
Binary files differ
diff --git a/src/assets/search/search@1x.png b/src/assets/search/search@1x.png
new file mode 100644
index 0000000..08c7c5a
--- /dev/null
+++ b/src/assets/search/search@1x.png
Binary files differ
diff --git a/src/components/CustomSearch1.vue b/src/components/CustomSearch1.vue
new file mode 100644
index 0000000..ef601dd
--- /dev/null
+++ b/src/components/CustomSearch1.vue
@@ -0,0 +1,77 @@
+<template>
+ <div class="custom-search1">
+ <input class="input-inner" type="text" autocapitalize="off" placeholder="请输入检索词" v-model="searchName"/>
+ <div class="input-append" v-on:click="$emit('search',searchName)">
+ <svg t="1638943404588" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
+ p-id="6664" width="200" height="200">
+ <path
+ d="M469.333 192c153.174 0 277.334 124.16 277.334 277.333 0 68.054-24.534 130.411-65.216 178.688L846.336 818.24l-48.341 49.877L630.4 695.125a276.053 276.053 0 0 1-161.067 51.542C316.16 746.667 192 622.507 192 469.333S316.16 192 469.333 192z m0 64C351.51 256 256 351.51 256 469.333s95.51 213.334 213.333 213.334 213.334-95.51 213.334-213.334S587.157 256 469.333 256z"
+ p-id="6665"></path>
+ </svg>
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ name: "CustomSearch1",
+ data() {
+ return {
+ searchName: ""
+ }
+ }
+}
+</script>
+
+<style scoped>
+.icon {
+ fill: currentColor;
+ color: #EFC587;
+}
+
+.custom-search1 {
+ width: 99%;
+ height: 8vh;
+ border: 4px solid #EFC587;
+ box-sizing: border-box;
+ border-radius: 200px;
+ background-color: rgba(0, 0, 0, 0.23);
+
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: center;
+ align-items: center;
+}
+
+.custom-search1 .input-inner {
+ width: 80%;
+ height: 95%;
+ border: 0;
+ border-radius: 200px;
+ background-color: rgba(0, 0, 0, 0);
+
+ font-size: 1.75rem;
+ font-family: Microsoft YaHei;
+ font-weight: 400;
+ line-height: 1.25rem;
+ color: #EFC587;
+ opacity: 1;
+}
+
+.custom-search1 .input-inner:focus {
+ outline: none;
+}
+
+.custom-search1 .input-append {
+ width: 9%;
+ height: 95%;
+ cursor: pointer;
+}
+
+.custom-search1 .input-append svg {
+ max-width: 2.68rem;
+ width: 100%;
+ height: 100%;
+}
+</style>
diff --git a/src/components/CustomSearch2.vue b/src/components/CustomSearch2.vue
new file mode 100644
index 0000000..724c7c0
--- /dev/null
+++ b/src/components/CustomSearch2.vue
@@ -0,0 +1,201 @@
+<template>
+ <div class="custom-search2">
+ <div class="custom-search-before" @click="ActionSheet">
+ <input class="input-inner" type="text" readonly="readonly" autocomplete="off" placeholder="请选择"
+ v-model="searchType.text">
+ <span class="input-append">
+ <svg t="1638954207837" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
+ p-id="6664" width="128" height="128"><path
+ d="M500.8 604.779L267.307 371.392l-45.227 45.27 278.741 278.613L779.307 416.66l-45.248-45.248z" p-id="6665"
+ fill="#EFC587"></path></svg>
+ </span>
+ </div>
+ <div class="custom-search-after">
+ <input class="input-inner" type="text" autocapitalize="off" placeholder="请输入检索词" v-model="searchName" v-on:focus="Focus"/>
+ <div class="input-append" v-on:click="Search">
+ <svg t="1638943404588" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
+ p-id="6664" width="200" height="200">
+ <path
+ d="M469.333 192c153.174 0 277.334 124.16 277.334 277.333 0 68.054-24.534 130.411-65.216 178.688L846.336 818.24l-48.341 49.877L630.4 695.125a276.053 276.053 0 0 1-161.067 51.542C316.16 746.667 192 622.507 192 469.333S316.16 192 469.333 192z m0 64C351.51 256 256 351.51 256 469.333s95.51 213.334 213.333 213.334 213.334-95.51 213.334-213.334S587.157 256 469.333 256z"
+ p-id="6665"></path>
+ </svg>
+ </div>
+ </div>
+ <actionsheet
+ :actions="searchTypeItems"
+ v-model="actionsheet">
+ </actionsheet>
+ </div>
+</template>
+
+<script>
+import {Actionsheet} from 'mint-ui';
+
+export default {
+ name: "CustomSearch2",
+ components: {Actionsheet},
+ data() {
+ return {
+ actionsheet: false,
+ searchType: {
+ text: "名称",
+ value: "title",
+ },
+ searchName: "",
+ searchTypeItems: [{
+ name: "名称",
+ value: "title",
+ method: this.SearchTypeItem
+ }, {
+ name: "关键字",
+ value: "keywords",
+ method: this.SearchTypeItem
+ }, {
+ name: "简介",
+ value: "descriprion",
+ method: this.SearchTypeItem
+ }],
+ }
+ },
+ methods: {
+ ActionSheet: function () {
+ this.actionsheet = true;
+ },
+ SearchTypeItem: function (obj) {
+ this.searchType = {
+ text: obj.name,
+ value: obj.value,
+ }
+ },
+ Search: function () {
+ if (this.searchName != "") {
+ if (localStorage.searchHistory) {
+ let hisArray = eval(localStorage.searchHistory);
+ hisArray.push({
+ searchType: this.searchType.value,
+ searchName: this.searchName,
+ });
+ localStorage.searchHistory = JSON.stringify(hisArray);
+ } else {
+ let hisArray = [{
+ searchType: this.searchType.value,
+ searchName: this.searchName,
+ }];
+ localStorage.searchHistory = JSON.stringify(hisArray);
+ }
+ }
+ this.$emit('search', this.searchType.value, this.searchName)
+ },
+ Focus: function () {
+ this.$emit('focus')
+ }
+ }
+}
+</script>
+
+<style scoped>
+.icon {
+ fill: currentColor;
+ color: #EFC587;
+}
+
+.custom-search2 {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: center;
+ align-items: center;
+}
+
+.custom-search-before {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: center;
+ align-items: center;
+
+ width: 30%;
+ height: 4vh;
+ background: rgba(0, 0, 0, 0.46);
+ border: 2px solid #EFC587;
+ border-radius: 6px;
+ margin-right: 1rem;
+}
+
+.custom-search-before .input-inner {
+ width: 70%;
+ height: 100%;
+ border: 0;
+ background-color: rgba(0, 0, 0, 0);
+
+ font-size: 1.6rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 2rem;
+ color: #EFC587;
+ cursor: pointer
+}
+
+.custom-search-before .input-inner:focus {
+ outline: none;
+}
+
+.custom-search-before .input-append {
+ width: 30%;
+ height: 100%;
+ cursor: pointer;
+}
+
+.custom-search-before .input-append svg {
+ max-width: 1.6rem;
+ width: 100%;
+ height: 100%;
+}
+
+
+.custom-search-after {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: center;
+ align-items: center;
+
+ width: 99%;
+ height: 4vh;
+ background: rgba(0, 0, 0, 0.59);
+ border: 2px solid #EFC587;
+ opacity: 1;
+ border-radius: 6px;
+}
+
+.custom-search-after .input-inner {
+ width: 90%;
+ height: 95%;
+ border: 0;
+ border-radius: 200px;
+ background-color: rgba(0, 0, 0, 0);
+
+ font-size: 1.31rem;
+ font-family: Microsoft YaHei;
+ font-weight: 400;
+ line-height: 3.33rem;
+ color: rgba(239, 197, 135, 0.6);
+ opacity: 1;
+}
+
+.custom-search-after .input-inner:focus {
+ outline: none;
+}
+
+.custom-search-after .input-append {
+ width: 9%;
+ height: 95%;
+ cursor: pointer;
+}
+
+.custom-search-after .input-append svg {
+ max-width: 1.6rem;
+ width: 100%;
+ height: 100%;
+}
+</style>
diff --git a/src/components/CustomSearch3.vue b/src/components/CustomSearch3.vue
new file mode 100644
index 0000000..8b65e18
--- /dev/null
+++ b/src/components/CustomSearch3.vue
@@ -0,0 +1,183 @@
+<template>
+ <div class="custom-search3">
+ <div class="custom-search-before" @click="ActionSheet">
+ <input class="input-inner" type="text" readonly="readonly" autocomplete="off" placeholder="请选择"
+ v-model="searchType.text">
+ <span class="input-append">
+ <svg t="1638954207837" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
+ p-id="6664" width="128" height="128"><path
+ d="M500.8 604.779L267.307 371.392l-45.227 45.27 278.741 278.613L779.307 416.66l-45.248-45.248z" p-id="6665"
+ fill="#606060"></path></svg>
+ </span>
+ </div>
+ <div class="custom-search-after">
+ <input class="input-inner" type="text" autocapitalize="off" placeholder="请输入检索词" v-model="searchName"/>
+ <div class="input-append" v-on:click="Search">
+ <svg t="1638943404588" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
+ p-id="6664" width="200" height="200">
+ <path
+ d="M469.333 192c153.174 0 277.334 124.16 277.334 277.333 0 68.054-24.534 130.411-65.216 178.688L846.336 818.24l-48.341 49.877L630.4 695.125a276.053 276.053 0 0 1-161.067 51.542C316.16 746.667 192 622.507 192 469.333S316.16 192 469.333 192z m0 64C351.51 256 256 351.51 256 469.333s95.51 213.334 213.333 213.334 213.334-95.51 213.334-213.334S587.157 256 469.333 256z"
+ p-id="6665" fill="#BC0000"></path>
+ </svg>
+ </div>
+ </div>
+ <actionsheet
+ :actions="searchTypeItems"
+ v-model="actionsheet">
+ </actionsheet>
+ </div>
+</template>
+
+<script>
+import {Actionsheet} from 'mint-ui';
+
+export default {
+ name: "CustomSearch3",
+ components: {Actionsheet},
+ data() {
+ return {
+ actionsheet: false,
+ searchType: {
+ text: "名称",
+ value: "title",
+ },
+ searchName: "",
+ searchTypeItems: [{
+ name: "名称",
+ value: "title",
+ method: this.SearchTypeItem
+ }, {
+ name: "关键字",
+ value: "keywords",
+ method: this.SearchTypeItem
+ }, {
+ name: "简介",
+ value: "descriprion",
+ method: this.SearchTypeItem
+ }],
+ }
+ },
+ methods: {
+ ActionSheet: function () {
+ this.actionsheet = true;
+ },
+ SearchTypeItem: function (obj) {
+ this.searchType = {
+ text: obj.name,
+ value: obj.value,
+ }
+ },
+ Search: function () {
+ this.$emit('search', this.searchType.value, this.searchName)
+ }
+ }
+}
+</script>
+
+<style scoped>
+.icon {
+ fill: currentColor;
+ color: #EFC587;
+}
+
+.custom-search3 {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: center;
+ align-items: center;
+
+ width: 100%;
+}
+
+.custom-search-before {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: center;
+ align-items: center;
+
+ width: 25%;
+ height: 4vh;
+ background: #FAFAFA;
+ border: 2px solid #EAEAEA;
+ border-radius: 6px;
+ margin-right: 1rem;
+}
+
+.custom-search-before .input-inner {
+ width: 70%;
+ height: 100%;
+ border: 0;
+ background-color: rgba(0, 0, 0, 0);
+
+ font-size: 1.5rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 1.5rem;
+ color: #606060;
+ cursor: pointer
+}
+
+.custom-search-before .input-inner:focus {
+ outline: none;
+}
+
+.custom-search-before .input-append {
+ width: 30%;
+ height: 100%;
+ cursor: pointer;
+}
+
+.custom-search-before .input-append svg {
+ max-width: 2rem;
+ width: 100%;
+ height: 100%;
+}
+
+
+.custom-search-after {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: center;
+ align-items: center;
+
+ width: 75%;
+ height: 4vh;
+ background: white;
+ border: 2px solid #BC0000;
+ opacity: 1;
+ border-radius: 6px;
+}
+
+.custom-search-after .input-inner {
+ width: 90%;
+ height: 3vh;
+ border: 0;
+ border-radius: 200px;
+
+ font-size: 1.4rem;
+ font-family: Microsoft YaHei;
+ font-weight: 400;
+ line-height: 1.4rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.custom-search-after .input-inner:focus {
+ outline: none;
+}
+
+.custom-search-after .input-append {
+ width: 9%;
+ height: 95%;
+ cursor: pointer;
+}
+
+.custom-search-after .input-append svg {
+ max-width: 2rem;
+ width: 100%;
+ height: 100%;
+}
+</style>
diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue
deleted file mode 100644
index 879051a..0000000
--- a/src/components/HelloWorld.vue
+++ /dev/null
@@ -1,58 +0,0 @@
-<template>
- <div class="hello">
- <h1>{{ msg }}</h1>
- <p>
- For a guide and recipes on how to configure / customize this project,<br>
- check out the
- <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
- </p>
- <h3>Installed CLI Plugins</h3>
- <ul>
- <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
- <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
- </ul>
- <h3>Essential Links</h3>
- <ul>
- <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
- <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
- <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
- <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
- <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
- </ul>
- <h3>Ecosystem</h3>
- <ul>
- <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
- <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
- <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
- <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
- <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
- </ul>
- </div>
-</template>
-
-<script>
-export default {
- name: 'HelloWorld',
- props: {
- msg: String
- }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-h3 {
- margin: 40px 0 0;
-}
-ul {
- list-style-type: none;
- padding: 0;
-}
-li {
- display: inline-block;
- margin: 0 10px;
-}
-a {
- color: #42b983;
-}
-</style>
diff --git a/src/main.js b/src/main.js
index 63eb05f..8cacbb0 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,8 +1,148 @@
import Vue from 'vue'
+import VueRouter from 'vue-router'
+import MintUI from 'mint-ui'
+import 'mint-ui/lib/style.css'
+import '../src/assets/icon/iconfont.css'
+
+import Meta from "vue-meta";
+
import App from './App.vue'
+import LayoutList from './views/layout/listIndex'
+import LayoutSearch from './views/layout/searchIndex'
+
+import HomePage from './views/home'
+import SearchIndex from './views/search/index'
+import SearchResults from './views/search/results'
+
+import SceneryList from './views/scenery/list'
+import SceneryDetail from './views/scenery/detail'
+import SceneryDetailImage from './views/scenery/detailImage'
+import SceneryDetailVideo from './views/scenery/detailvideo'
+
+import MemoryList from './views/memory/list'
+import MemoryDetail from './views/memory/detail'
+import MemoryDetailImage from './views/memory/detailImage'
+import MemoryDetailVideo from './views/memory/detailvideo'
+
+import SpiritList from './views/spirit/list'
+import SpiritDetail from './views/spirit/detail'
+import SpiritDetailImage from './views/spirit/detailImage'
+import SpiritDetailVideo from './views/spirit/detailvideo'
+
+import PersonageList from './views/personage/list'
+import PersonageDetail from './views/personage/detail'
+import PersonageDetailImage from './views/personage/detailImage'
+import PersonageDetailVideo from './views/personage/detailvideo'
Vue.config.productionTip = false
+const routes = [
+ {
+ name: 'default', path: '/', redirect: '/home', meta: {
+ title: '首页'
+ }
+ },
+ {name: 'home', path: '/home', component: HomePage},
+ {
+ name: 'search', path: '/search', component: LayoutSearch,
+ meta: {
+ title: '数据检索'
+ },
+ children: [
+ {name: 'search-index', path: 'index', component: SearchIndex},
+ {name: 'search-results', path: 'results', component: SearchResults},
+ ]
+ },
+ {
+ name: 'scenery', path: '/scenery', component: LayoutList,
+ meta: {
+ title: '红色景区库'
+ },
+ children: [
+ {name: 'scenery-list', path: 'list', component: SceneryList},
+ ],
+ },
+ {
+ name: 'scenery', path: '/scenery', component: App,
+ meta: {
+ title: '红色景区库'
+ },
+ children: [
+ {name: 'scenery-detail', path: 'detail', component: SceneryDetail},
+ {name: 'scenery-detail-image', path: 'detail/image', component: SceneryDetailImage},
+ {name: 'scenery-detail-video', path: 'detail/video', component: SceneryDetailVideo},
+ ],
+ },
+ {
+ name: 'memory', path: '/memory', component: LayoutList,
+ meta: {
+ title: '红色记忆库'
+ },
+ children: [
+ {name: 'memory-list', path: 'list', component: MemoryList},
+ ],
+ },
+ {
+ name: 'memory', path: '/memory', component: App,
+ meta: {
+ title: '红色记忆库'
+ },
+ children: [
+ {name: 'memory-detail', path: 'detail', component: MemoryDetail},
+ {name: 'memory-detail-image', path: 'detail/image', component: MemoryDetailImage},
+ {name: 'memory-detail-video', path: 'detail/video', component: MemoryDetailVideo},
+ ],
+ },
+ {
+ name: 'spirit', path: '/spirit', component: LayoutList,
+ meta: {
+ title: '红色精神库'
+ },
+ children: [
+ {name: 'spirit-list', path: 'list', component: SpiritList},
+ ],
+ },
+ {
+ name: 'spirit', path: '/spirit', component: App,
+ meta: {
+ title: '红色精神库'
+ },
+ children: [
+ {name: 'spirit-detail', path: 'detail', component: SpiritDetail},
+ {name: 'spirit-detail-image', path: 'detail/image', component: SpiritDetailImage},
+ {name: 'spirit-detail-video', path: 'detail/video', component: SpiritDetailVideo},
+ ],
+ },
+ {
+ name: 'personage', path: '/personage', component: LayoutList,
+ meta: {
+ title: '红色人物库'
+ },
+ children: [
+ {name: 'personage-list', path: 'list', component: PersonageList},
+ ],
+ },
+ {
+ name: 'personage', path: '/personage', component: App,
+ meta: {
+ title: '红色人物库'
+ },
+ children: [
+ {name: 'personage-detail', path: 'detail', component: PersonageDetail},
+ {name: 'personage-detail-image', path: 'detail/image', component: PersonageDetailImage},
+ {name: 'personage-detail-video', path: 'detail/video', component: PersonageDetailVideo},
+ ],
+ },
+];
+const router = new VueRouter({
+ routes
+});
+
+Vue.use(VueRouter);
+Vue.use(MintUI);
+Vue.use(Meta);
+
new Vue({
- render: h => h(App),
+ render: h => h(App),
+ router
}).$mount('#app')
diff --git a/src/views/home.vue b/src/views/home.vue
new file mode 100644
index 0000000..4288a96
--- /dev/null
+++ b/src/views/home.vue
@@ -0,0 +1,191 @@
+<template>
+ <div class="home">
+ <h1>吉林省红色旅游数据库</h1>
+ <div class="search-div">
+ <div class="search-type">
+ <ul>
+ <li :class="searchType=='title'?'selected':''" @click="SwitchSearchType('title')">名称</li>
+ <li :class="searchType=='keywords'?'selected':''" @click="SwitchSearchType('keywords')">关键词</li>
+ <li :class="searchType=='description'?'selected':''" @click="SwitchSearchType('description')">简介</li>
+ </ul>
+ </div>
+ <div class="search-name">
+ <CustomSearch1 v-on:search="Search"></CustomSearch1>
+ </div>
+ </div>
+ <div class="navigation-div">
+ <div class="nav-div nav-memory" @click="NavigationGo(1)">
+ 红色记忆
+ </div>
+ <div class="nav-div nav-personage" @click="NavigationGo(4)">
+ 红色人物
+ </div>
+ <div class="nav-div nav-scenery" @click="NavigationGo(3)">
+ 红色景区
+ </div>
+ <div class="nav-div nav-spirit" @click="NavigationGo(2)">
+ 红色精神
+ </div>
+ </div>
+ </div>
+</template>
+
+<script>
+import CustomSearch1 from '../components/CustomSearch1'
+
+export default {
+ name: "home",
+ components: {
+ CustomSearch1
+ },
+ data() {
+ return {
+ searchType: "title",
+ }
+ },
+ methods: {
+ Search: function (searchName) {
+ this.$router.push({name: "search-results", query: {searchType: this.searchType, searchName: searchName}});
+ },
+ SwitchSearchType: function (searchType) {
+ this.searchType = searchType;
+ },
+ NavigationGo(type) {
+ switch (type) {
+ case 1:
+ this.$router.push({name: "memory-list", query: {}});
+ break;
+ case 2:
+ this.$router.push({name: "spirit-list", query: {}});
+ break;
+ case 3:
+ this.$router.push({name: "scenery-list", query: {}});
+ break;
+ case 4:
+ this.$router.push({name: "personage-list", query: {}});
+ break;
+ }
+ }
+ }
+}
+</script>
+
+<style scoped>
+.home {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+
+ width: 100%;
+ height: 99vh;
+ background: url("../assets/home_background@1x.png") no-repeat 100% 100%;
+ background-size: cover;
+}
+
+h1 {
+ width: 70%;
+
+ font-size: 4.5rem;
+ font-family: FZZhengHeiS-DB-GB;
+ font-weight: 400;
+ line-height: 6.87rem;
+ color: #FFFFFF;
+}
+
+.search-div {
+ width: 90%;
+ padding-bottom: 3.8vh;
+}
+
+.search-div ul {
+ text-align: left;
+}
+
+.search-div ul li {
+ cursor: pointer;
+ display: inline-block;
+ list-style-type: none;
+ padding-right: 5vw;
+
+ font-size: 1.75rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ color: #FFFFFF;
+}
+
+.search-div ul li.selected {
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 500;
+ color: #EFC587;
+}
+
+.navigation-div {
+ width: 90%;
+}
+
+.navigation-div .nav-div {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+
+ width: 100%;
+ height: 10vh;
+ border-radius: 10px;
+ margin-bottom: 3vh;
+ cursor: pointer;
+}
+
+.navigation-div .nav-memory {
+ background: url("../assets/nav_memory@1x.png") no-repeat 100% 100%;
+ background-size: cover;
+
+ font-size: 3.37rem;
+ font-family: FZDaBiaoSong-B06S;
+ font-weight: 400;
+ line-height: 1.93rem;
+ color: #BC0000;
+ text-shadow: 0px 3px 6px rgba(255, 255, 255, 0.16);
+ opacity: 1;
+}
+
+.navigation-div .nav-personage {
+ background: url("../assets/nav_personage@1x.png") no-repeat 100% 100%;
+ background-size: cover;
+
+ font-size: 3.37rem;
+ font-family: FZDaBiaoSong-B06S;
+ font-weight: 400;
+ line-height: 1.93rem;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.navigation-div .nav-scenery {
+ background: url("../assets/nav_scenery@1x.png") no-repeat 100% 100%;
+ background-size: cover;
+
+ font-size: 3.37rem;
+ font-family: FZDaBiaoSong-B06S;
+ font-weight: 400;
+ line-height: 1.93rem;
+ color: #FFE36C;
+ text-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
+ opacity: 1;
+}
+
+.navigation-div .nav-spirit {
+ background: url("../assets/nav_spirit@1x.png") no-repeat 100% 100%;
+ background-size: cover;
+
+ font-size: 3.37rem;
+ font-family: FZDaBiaoSong-B06S;
+ font-weight: 400;
+ line-height: 1.93rem;
+ color: #FFE36C;
+ text-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
+ opacity: 1;
+}
+</style>
diff --git a/src/views/layout/listIndex.vue b/src/views/layout/listIndex.vue
new file mode 100644
index 0000000..f450b0c
--- /dev/null
+++ b/src/views/layout/listIndex.vue
@@ -0,0 +1,155 @@
+<template>
+ <div class="datalist">
+ <div class="data-title">
+ <div @click="ToHome">吉林省红色旅游数据库</div>
+ <div @click="ToHome">红色景点库</div>
+ </div>
+ <div class="data-content">
+ <transition name="fade-transform" mode="out-in">
+ <router-view :key="key"/>
+ </transition>
+ </div>
+ <mt-tabbar v-model="dataType" :fixed="true">
+ <mt-tab-item id="1">红色记忆</mt-tab-item>
+ <mt-tab-item id="2">红色精神</mt-tab-item>
+ <mt-tab-item id="3">红色景区</mt-tab-item>
+ <mt-tab-item id="4">红色人物</mt-tab-item>
+ </mt-tabbar>
+ </div>
+</template>
+
+<script>
+export default {
+ name: "listIndex",
+ data() {
+ return {
+ dataType: ""
+ }
+ },
+ methods: {
+ ToHome: function () {
+ this.$router.push({name: "home"});
+ }
+ },
+ watch: {
+ dataType: function () {
+ switch (this.dataType) {
+ case "1":
+ this.$router.push({name: "memory-list"});
+ break;
+ case "2":
+ this.$router.push({name: "spirit-list"});
+ break;
+ case "3":
+ this.$router.push({name: "scenery-list"});
+ break;
+ case "4":
+ this.$router.push({name: "personage-list"});
+ break;
+ }
+ },
+ },
+ computed: {
+ key() {
+ return this.$route.path
+ }
+ },
+ created() {
+ if (this.dataType == "") {
+ switch (this.$route.name) {
+ case "memory-list":
+ this.dataType = "1";
+ break;
+ case "spirit-list":
+ this.dataType = "2"
+ break;
+ case "scenery-list":
+ this.dataType = "3";
+ break;
+ case "personage-list":
+ this.dataType = "4";
+ break;
+ }
+ }
+ }
+}
+</script>
+
+<style scoped>
+.datalist {
+ width: 100%;
+ height: 100vh;
+}
+
+.data-title {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+
+ width: 100%;
+ height: 16vh;
+ background: url("../../assets/datalist/datalist@1x.png") no-repeat 100% 100%;
+ background-size: cover;
+}
+
+.data-title > div {
+ width: 100%;
+ text-align: left;
+ font-size: 2.87rem;
+ font-family: FZZhengHeiS-DB-GB;
+ font-weight: 400;
+ line-height: 4.37rem;
+ color: #FFFFFF;
+ opacity: 1;
+ padding-left: 2rem;
+}
+
+.data-content {
+ width: 100%;
+ height: 75vh;
+ background: #FFFFFF;
+ border-radius: 10px 10px 0px 0px;
+
+ position: relative;
+ z-index: 5;
+}
+
+.data-content .list-root{
+ height: 100%;
+ width: 100%;
+}
+
+.mint-tabbar {
+ height: 10vh;
+ background: white;
+ z-index: 9;
+}
+
+.mint-tabbar /deep/ .mint-tab-item {
+ padding: 20px 0;
+}
+
+.mint-tabbar /deep/ .mint-tab-item-label {
+ font-size: 1.75rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 1.93rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.mint-tabbar /deep/ .is-selected {
+ background-color: white;
+ border-top: 0.5vh solid #BC0000;
+}
+
+.mint-tabbar /deep/ .is-selected .mint-tab-item-label {
+ font-size: 1.75rem;
+ font-family: Source Han Sans CN;
+ font-weight: bold;
+ line-height: 1.93rem;
+ color: #BC0000;
+ opacity: 1;
+}
+</style>
diff --git a/src/views/layout/searchIndex.vue b/src/views/layout/searchIndex.vue
new file mode 100644
index 0000000..975aa60
--- /dev/null
+++ b/src/views/layout/searchIndex.vue
@@ -0,0 +1,75 @@
+<template>
+ <div class="search">
+ <div class="search-input">
+ <custom-search2 v-on:search="Search" v-on:focus="Focus"></custom-search2>
+ </div>
+ <div class="search-content">
+ <transition name="fade-transform" mode="out-in">
+ <router-view :key="key"/>
+ </transition>
+ </div>
+ </div>
+</template>
+
+<script>
+import CustomSearch2 from "@/components/CustomSearch2";
+
+export default {
+ name: "searchIndex",
+ components: {CustomSearch2},
+ methods: {
+ Search: function (searchType, searchName) {
+ this.$router.push({
+ name: 'search-results',
+ query: {
+ searchType: searchType,
+ searchName: searchName
+ }
+ });
+
+ },
+ Focus: function () {
+ this.$router.push({
+ name: 'search-index'
+ });
+ }
+ },
+ computed: {
+ key() {
+ return this.$route.path
+ }
+ }
+}
+</script>
+
+<style scoped>
+.search {
+ width: 100%;
+}
+
+.search .search-input {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+
+ width: 100%;
+ height: 10vh;
+ background: url("../../assets/search/search@1x.png") no-repeat 100% 100%;
+ background-size: cover;
+}
+
+.search .search-input .custom-search2 {
+ width: 90%;
+}
+
+.search .search-content {
+ width: 100%;
+ background: #FFFFFF;
+ border-radius: 10px 10px 0px 0px;
+
+ position: relative;
+ top: -10px;
+ z-index: 10;
+}
+</style>
diff --git a/src/views/memory/detail.vue b/src/views/memory/detail.vue
new file mode 100644
index 0000000..800f60b
--- /dev/null
+++ b/src/views/memory/detail.vue
@@ -0,0 +1,510 @@
+<template>
+ <div class="data-detail">
+ <div class="title">
+ <div class="title-left">
+ <div class="title-name" @click="ToListPage">{{ titleName }}</div>
+ <div class="title-introduce">{{ titleIntroduce }}</div>
+ </div>
+ <div class="title-right">
+ <div class="online-preview" @click="OnlinePreview(basisInfo.file)">在线浏览</div>
+ </div>
+ </div>
+ <div class="content">
+ <mt-navbar ref="navbar" v-model="navbarIndex">
+ <mt-tab-item id="1" data-type="1">基本信息</mt-tab-item>
+ <mt-tab-item id="2" data-type="2">相关图片</mt-tab-item>
+ <mt-tab-item id="3" data-type="3">相关视频</mt-tab-item>
+ </mt-navbar>
+ <mt-tab-container v-model="navbarIndex">
+ <mt-tab-container-item id="1">
+ <div class="content-keyword">
+ <div class="item-name">关键字</div>
+ {{ basisInfo.keyWord }}
+ </div>
+ <div class="content-introduction">
+ <div class="item-name">简介</div>
+ {{ basisInfo.introduction }}
+ </div>
+ </mt-tab-container-item>
+ <mt-tab-container-item id="2">
+ <CustomSearch3 v-on:search="SearchImages"></CustomSearch3>
+ <div class="content-images"
+ v-infinite-scroll="NextImages"
+ :infinite-scroll-disabled="images.scrollDisabled"
+ :infinite-scroll-distance="10">
+ <div class="content-item"
+ v-for="item in images.data"
+ :key="item.id"
+ @click="ToImageDetail(item.id)">
+ <div class="img-div">
+ <img :src="item.path"/>
+ </div>
+ <div class="item-name">{{ item.name }}</div>
+ </div>
+ </div>
+ </mt-tab-container-item>
+ <mt-tab-container-item id="3">
+ <CustomSearch3 v-on:search="SearchVideos"></CustomSearch3>
+ <div class="content-videos"
+ v-infinite-scroll="NextVideos"
+ :infinite-scroll-disabled="videos.scrollDisabled"
+ :infinite-scroll-distance="10">
+ <div class="content-item"
+ v-for="item in videos.data"
+ :key="item.id"
+ @click="ToVideoDetail(item.id)">
+ <div class="item-left">
+ <img :src="item.cover"/>
+ </div>
+ <div class="item-right">
+ <div class="item-name">{{ item.name }}</div>
+ <div class="item-introduce">{{ item.description }}</div>
+ </div>
+ </div>
+ </div>
+ </mt-tab-container-item>
+ </mt-tab-container>
+ </div>
+ </div>
+</template>
+
+<script>
+import CustomSearch3 from "@/components/CustomSearch3";
+import {
+ GetDataDetail as Api_GetDataDetail,
+ GetDataDetailImages as Api_GetDataDetailImages,
+ GetDataDetailVideos as Api_GetDataDetailVideos,
+} from "@/api/apilist";
+
+export default {
+ name: "detail",
+ components: {CustomSearch3},
+ data() {
+ return {
+ titleName: "",
+ titleIntroduce: "",
+ navbarIndex: "1",
+ basisInfo: {
+ id: "",
+ keyWord: "",
+ introduction: "",
+ file: "",
+ },
+ images: {
+ searchType: "title",
+ searchName: "",
+ pageSize: 10,
+ currentPage: 1,
+ total: 0,
+ data: [],
+ scrollDisabled: false,
+ },
+ videos: {
+ searchType: "title",
+ searchName: "",
+ pageSize: 10,
+ currentPage: 1,
+ total: 0,
+ data: [],
+ scrollDisabled: false,
+ },
+ }
+ },
+ methods: {
+ OnlinePreview: function (fileUrl) {
+ if (fileUrl) {
+ if (fileUrl.replace(/\\/g, '').toLowerCase().indexOf('.pdf') >= 0) {
+ window.open(fileUrl);
+ } else {
+ //https://view.officeapps.live.com/op/view.aspx?src=
+ window.open("http://www.xdocin.com/xdoc?_func=to&_format=html&_cache=1&_xdoc=" + fileUrl.replace(/\\/g, ''));
+ }
+ }
+ },
+ SearchBasisInfo: function (id) {
+ Api_GetDataDetail(id).then(res => {
+ this.basisInfo = res;
+ this.titleIntroduce = res.keyWord;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ SearchImages: function (searchType, searchName) {
+ this.images.searchType = searchType;
+ this.images.searchName = searchName;
+ Api_GetDataDetailImages(this.$route.query.id, searchType, searchName, 1, 10).then(res => {
+ this.images.currentPage = res.currentPage;
+ this.images.pageSize = res.pageSize;
+ this.images.total = res.total;
+ this.images.data = res.data;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ NextImages: function () {
+ let searchType = this.images.searchType;
+ let searchName = this.images.searchName;
+ let currentPage = this.images.currentPage + 1;
+ let pageSize = this.images.pageSize;
+ Api_GetDataDetailImages(this.$route.query.id, searchType, searchName, currentPage, pageSize).then(res => {
+ if (res.data.length > 0) {
+ this.images.total = res.total;
+ this.images.currentPage = res.currentPage;
+ this.images.data = this.images.data.concat(res.data);
+ }
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ SearchVideos: function (searchType, searchName) {
+ this.videos.searchType = searchType;
+ this.videos.searchName = searchName;
+ Api_GetDataDetailVideos(this.$route.query.id, searchType, searchName, 1, 10).then(res => {
+ this.videos.currentPage = res.currentPage;
+ this.videos.pageSize = res.pageSize;
+ this.videos.total = res.total;
+ this.videos.data = res.data;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ NextVideos: function () {
+ let searchType = this.videos.searchType;
+ let searchName = this.videos.searchName;
+ let currentPage = this.videos.currentPage + 1;
+ let pageSize = this.videos.pageSize;
+ Api_GetDataDetailVideos(this.$route.query.id, searchType, searchName, currentPage, pageSize).then(res => {
+ if (res.data.length > 0) {
+ this.videos.total = res.total;
+ this.videos.currentPage = res.currentPage;
+ this.videos.data = this.videos.data.concat(res.data);
+ }
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ ToImageDetail: function (id) {
+ let objId = this.$route.query.id;
+ this.$router.push({name: "memory-detail-image", query: {id: id, objId: objId}});
+ },
+ ToVideoDetail: function (id) {
+ let objId = this.$route.query.id;
+ this.$router.push({name: "memory-detail-video", query: {id: id, objId: objId}});
+ },
+ ToListPage: function () {
+ this.$router.push({name: "memory-list"})
+ },
+ },
+ watch: {
+ navbarIndex: function () {
+ switch (this.navbarIndex) {
+ case 1:
+ this.images.scrollDisabled = true;
+ this.videos.scrollDisabled = true;
+ break;
+ case 2:
+ this.images.scrollDisabled = false;
+ this.videos.scrollDisabled = true;
+ break;
+ case 3:
+ this.images.scrollDisabled = true;
+ this.videos.scrollDisabled = false;
+ break;
+ }
+ }
+ },
+ created() {
+ let id = this.$route.query.id;
+ this.titleName = this.$route.query.name;
+ this.SearchBasisInfo(id);
+ this.SearchImages("title", "");
+ this.SearchVideos("title", "");
+ }
+}
+</script>
+
+<style scoped>
+.data-detail {
+ width: 100%;
+}
+
+.data-detail .title {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: space-between;
+ align-items: center;
+
+ width: 100%;
+ height: 15.9vh;
+ background: url("../../assets/datadetail/detail@1x.png") no-repeat 100% 100%;
+ background-size: cover;
+ border-radius: 10px 10px 0 0;
+}
+
+.data-detail .title .title-left {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: flex-start;
+
+ width: 60%;
+ height: 100%;
+ padding-left: 2vh;
+}
+
+.data-detail .title .title-name {
+ width: 100%;
+ text-align: left;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+
+ font-size: 2.62rem;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 5.24rem;
+ color: #FFFFFF;
+ opacity: 1;
+}
+
+.data-detail .title .title-introduce {
+ width: 100%;
+
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 3.37rem;
+ color: #FFFFFF;
+ opacity: 1;
+}
+
+.data-detail .title .title-right {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: flex-start;
+
+ width: 30%;
+ height: 100%;
+}
+
+.data-detail .title .online-preview {
+ width: 80%;
+ background: #EFC587;
+ opacity: 1;
+ border-radius: 60px;
+
+ font-size: 1.75rem;
+ font-family: Source Han Sans CN;
+ font-weight: bold;
+ line-height: 3.87vh;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.data-detail .content {
+ width: 90%;
+ height: 84.1vh;
+ margin-left: 5%;
+ border-radius: 30px;
+}
+
+.mint-navbar /deep/ .mint-tab-item-label {
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 500;
+ line-height: 2rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.mint-navbar /deep/ .is-selected {
+ color: #BC0000;
+ border-bottom: 0.3vh solid #BC0000;
+}
+
+.mint-navbar /deep/ .is-selected .mint-tab-item-label {
+ color: #BC0000;
+}
+
+.mint-tab-container /deep/ .mint-tab-container-item:nth-child(1) {
+ padding-top: 5vh;
+}
+
+.content-keyword {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.content-keyword .item-name {
+ text-align: left;
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: bold;
+ line-height: 6rem;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.content-introduction {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.content-introduction .item-name {
+ text-align: left;
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: bold;
+ line-height: 6rem;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.mint-tab-container /deep/ .mint-tab-container-item:nth-child(2) {
+ padding-top: 2vh;
+}
+
+.custom-search3 {
+ margin-bottom: 2vh;
+}
+
+.content-images {
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: flex-start;
+}
+
+.content-images .content-item {
+ width: 50%;
+ height: 25vh;
+}
+
+.content-images .content-item .img-div {
+ width: 90%;
+ height: 80%;
+ border-radius: 10px;
+ box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
+}
+
+.content-images .content-item .img-div img {
+ width: 100%;
+ height: 100%;
+ border-radius: 10px;
+ object-fit: cover;
+}
+
+.content-images .content-item .item-name {
+ width: 90%;
+
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+
+ font-size: 2em;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 2em;
+ color: #333333;
+ opacity: 1;
+}
+
+.mint-tab-container /deep/ .mint-tab-container-item:nth-child(3) {
+ padding-top: 2vh;
+}
+
+.content-videos {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+}
+
+.content-videos .content-item {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+ align-items: center;
+
+ height: 10vh;
+ margin: 2vh auto;
+}
+
+.content-videos .item-left {
+ width: 30%;
+ height: 100%;
+}
+
+.content-videos .item-left img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.content-videos .item-right {
+ width: 70%;
+ height: 100%;
+ padding-left: 2vw;
+}
+
+.content-videos .item-name {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ text-align: left;
+ font-size: 2rem;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 4rem;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.content-videos .item-introduce {
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ text-align: left;
+ font-size: 1.62rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+</style>
diff --git a/src/views/memory/detailImage.vue b/src/views/memory/detailImage.vue
new file mode 100644
index 0000000..07a9a97
--- /dev/null
+++ b/src/views/memory/detailImage.vue
@@ -0,0 +1,133 @@
+<template>
+ <div class="data-detail-image">
+ <div class="images">
+ <mt-swipe :show-indicators="false" :auto="0" :continuous="false" @change="ChangeImage">
+ <mt-swipe-item v-for="item in images.data" :key="item.key">
+ <img :src="item.path"/>
+ </mt-swipe-item>
+ </mt-swipe>
+ </div>
+ <div class="content">
+ <mt-navbar v-model="navIndex">
+ <mt-tab-item id="1">关键词</mt-tab-item>
+ <mt-tab-item id="2">简介</mt-tab-item>
+ </mt-navbar>
+ <mt-tab-container v-model="navIndex">
+ <mt-tab-container-item id="1">
+ {{ image.keyWord }}
+ </mt-tab-container-item>
+ <mt-tab-container-item id="2">
+ {{ image.introduction }}
+ </mt-tab-container-item>
+ </mt-tab-container>
+ </div>
+ </div>
+</template>
+
+<script>
+import {GetImageDetail as Api_GetImageDetail} from "@/api/apilist";
+
+export default {
+ name: "detailImage",
+ data() {
+ return {
+ navIndex: "1",
+ images: {
+ pageSize: 10,
+ currentPage: 1,
+ total: 0,
+ data: []
+ },
+ image: {
+ id: "",
+ name: "",
+ path: "",
+ keyWord: "",
+ introduction: "",
+ }
+ }
+ },
+ methods: {
+ ChangeImage: function (index) {
+ this.image = this.images.data[index];
+ },
+ },
+ created() {
+ let imageId = this.$route.query.id;
+ let objId = this.$route.query.objId;
+ Api_GetImageDetail(imageId, 1, objId, 999).then(res => {
+ this.images = res;
+ this.image = res.data[0];
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ }
+}
+</script>
+
+<style scoped>
+.data-detail-image {
+ width: 100%;
+}
+
+.images {
+ width: 100%;
+ height: 31.5vh;
+}
+
+.images img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.content {
+ width: 100%;
+ height: 66vh;
+ box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
+ opacity: 1;
+ border-radius: 10px;
+
+ padding-top: 1vh;
+}
+
+.content > div{
+ width: 90%;
+ margin-left: 5%;
+}
+
+.mint-navbar{
+ margin-bottom: 4vh;
+}
+
+.mint-navbar .mint-tab-item /deep/ .mint-tab-item-label {
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 500;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.mint-navbar .is-selected {
+ border-bottom: 0.3rem solid #BC0000;
+}
+
+.mint-navbar .is-selected /deep/ .mint-tab-item-label {
+ color: #BC0000;
+ font-weight: bold;
+}
+
+.mint-tab-container {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #585858;
+ opacity: 1;
+}
+</style>
diff --git a/src/views/memory/detailvideo.vue b/src/views/memory/detailvideo.vue
new file mode 100644
index 0000000..f755c4c
--- /dev/null
+++ b/src/views/memory/detailvideo.vue
@@ -0,0 +1,121 @@
+<template>
+ <div class="data-detail-video">
+ <div class="videos">
+ <video poster="" :src="video.patch" controls="controls">
+ 您的浏览器不支持 video 标签。
+ </video>
+ </div>
+ <div class="content">
+ <mt-navbar v-model="navIndex">
+ <mt-tab-item id="1">关键词</mt-tab-item>
+ <mt-tab-item id="2">简介</mt-tab-item>
+ </mt-navbar>
+ <mt-tab-container v-model="navIndex">
+ <mt-tab-container-item id="1">
+ {{ video.keyWord }}
+ </mt-tab-container-item>
+ <mt-tab-container-item id="2">
+ {{ video.introduction }}
+ </mt-tab-container-item>
+ </mt-tab-container>
+ </div>
+ </div>
+</template>
+
+<script>
+import {GetVideoDetail as Api_GetVideoDetail} from "@/api/apilist";
+
+export default {
+ name: "detailVideo",
+ data() {
+ return {
+ navIndex: "1",
+ video: {
+ id: "",
+ name: "",
+ path: "",
+ keyWord: "",
+ introduction: "",
+ },
+ }
+ },
+ methods: {
+
+ },
+ created() {
+ let id = this.$route.query.id;
+ Api_GetVideoDetail(id).then(res => {
+ this.video = res;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ }
+}
+</script>
+
+<style scoped>
+.data-detail-video {
+ width: 100%;
+}
+
+.videos {
+ width: 100%;
+ height: 31.5vh;
+}
+
+.videos video {
+ width: 100%;
+ height: 100%;
+ background: black;
+}
+
+.content {
+ width: 100%;
+ height: 66vh;
+ box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
+ opacity: 1;
+ border-radius: 10px;
+
+ padding-top: 1vh;
+}
+
+.content > div{
+ width: 90%;
+ margin-left: 5%;
+}
+
+.mint-navbar{
+ margin-bottom: 4vh;
+}
+
+.mint-navbar .mint-tab-item /deep/ .mint-tab-item-label {
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 500;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.mint-navbar .is-selected {
+ border-bottom: 0.3rem solid #BC0000;
+}
+
+.mint-navbar .is-selected /deep/ .mint-tab-item-label {
+ color: #BC0000;
+ font-weight: bold;
+}
+
+.mint-tab-container {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #585858;
+ opacity: 1;
+}
+</style>
diff --git a/src/views/memory/list.vue b/src/views/memory/list.vue
new file mode 100644
index 0000000..ea48633
--- /dev/null
+++ b/src/views/memory/list.vue
@@ -0,0 +1,154 @@
+<template>
+ <div class="list-root">
+ <div class="search">
+ <CustomSearch3 v-on:search="Search"></CustomSearch3>
+ </div>
+ <div class="line"></div>
+ <div class="data-list"
+ v-infinite-scroll="loadBottom"
+ :infinite-scroll-disabled="allLoaded"
+ :infinite-scroll-distance="10">
+ <template v-for="item in data.data">
+ <div class="text-item" :key="item.key" @click="ToDetail(item.id, item.name)">
+ <div class="item-title">{{ item.name }}</div>
+ <div class="item-context">{{ item.keyWord }}</div>
+ </div>
+ <div class="line" :key="item.key"></div>
+ </template>
+ </div>
+ </div>
+</template>
+
+<script>
+import CustomSearch3 from "@/components/CustomSearch3";
+import {GetDataList as Api_GetDataList} from "@/api/apilist";
+
+export default {
+ name: "list",
+ components: {CustomSearch3},
+ data() {
+ return {
+ dataType: 1,
+ searchType: "title",
+ searchName: "",
+ data: {
+ currentPage: 1,
+ pageSize: 5,
+ total: 0,
+ data: []
+ },
+ allLoaded: false
+ };
+ },
+ methods: {
+ Search: function (searchType, searchName) {
+ this.searchType = searchType;
+ this.searchName = searchName;
+ Api_GetDataList(this.dataType, searchType, searchName, 1, this.data.pageSize).then(res => {
+ this.currentPage = res.currentPage;
+ this.pageSize = res.pageSize;
+ this.total = res.total;
+ this.data = res;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert("错误的请求!");
+ });
+ },
+ loadBottom: function () {
+ Api_GetDataList(this.dataType, this.searchType, this.searchName, this.data.currentPage + 1, this.data.pageSize).then(res => {
+ this.data.currentPage = res.currentPage;
+ this.data.pageSize = res.pageSize;
+ this.data.total = res.total;
+ if (res.data.length > 0) {
+ this.data.data = this.data.data.concat(res.data);
+ }
+ else{
+ this.allLoaded = true;
+ }
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert("错误的请求!");
+ });
+ },
+ ToDetail: function (id, name) {
+ this.$router.push({name: "memory-detail", query: {id: id, name: name}})
+ }
+ },
+ created() {
+ this.Search("title", "");
+ }
+}
+</script>
+
+<style scoped>
+li {
+ list-style-type: none;
+}
+
+.list-root {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+ width: 100%;
+}
+
+.search {
+ width: 100%;
+ margin-top: 3vh;
+}
+
+.search .custom-search3 {
+ width: 90%;
+ margin-left: 5%;
+}
+
+.line {
+ width: 100%;
+ border: 1px solid #EEEEEE;
+ margin-top: 3vh;
+ margin-bottom: 3vh;
+ opacity: 1;
+}
+
+.data-list {
+ width: 90%;
+ height: 65vh;
+ margin-left: 5%;
+ overflow: scroll;
+}
+
+.data-list .line {
+ width: 100%;
+ margin-bottom: 2vh;
+}
+
+
+.data-list /deep/ .text-item {
+ width: 90%;
+ margin-bottom: 2vh;
+}
+
+.data-list /deep/ .text-item .item-title {
+ text-align: left;
+ font-size: 2rem;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 4rem;
+ color: #BC0000;
+}
+
+.data-list /deep/ .text-item .item-context {
+ text-align: left;
+ font-size: 1.62rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 2rem;
+ color: #767676;
+ text-align: left;
+}
+</style>
diff --git a/src/views/personage/detail.vue b/src/views/personage/detail.vue
new file mode 100644
index 0000000..9205178
--- /dev/null
+++ b/src/views/personage/detail.vue
@@ -0,0 +1,510 @@
+<template>
+ <div class="data-detail">
+ <div class="title">
+ <div class="title-left">
+ <div class="title-name" @click="ToListPage">{{ titleName }}</div>
+ <div class="title-introduce">{{ titleIntroduce }}</div>
+ </div>
+ <div class="title-right">
+ <div class="online-preview" @click="OnlinePreview(basisInfo.file)">在线浏览</div>
+ </div>
+ </div>
+ <div class="content">
+ <mt-navbar ref="navbar" v-model="navbarIndex">
+ <mt-tab-item id="1" data-type="1">基本信息</mt-tab-item>
+ <mt-tab-item id="2" data-type="2">相关图片</mt-tab-item>
+ <mt-tab-item id="3" data-type="3">相关视频</mt-tab-item>
+ </mt-navbar>
+ <mt-tab-container v-model="navbarIndex">
+ <mt-tab-container-item id="1">
+ <div class="content-keyword">
+ <div class="item-name">关键字</div>
+ {{ basisInfo.keyWord }}
+ </div>
+ <div class="content-introduction">
+ <div class="item-name">简介</div>
+ {{ basisInfo.introduction }}
+ </div>
+ </mt-tab-container-item>
+ <mt-tab-container-item id="2">
+ <CustomSearch3 v-on:search="SearchImages"></CustomSearch3>
+ <div class="content-images"
+ v-infinite-scroll="NextImages"
+ :infinite-scroll-disabled="images.scrollDisabled"
+ :infinite-scroll-distance="10">
+ <div class="content-item"
+ v-for="item in images.data"
+ :key="item.id"
+ @click="ToImageDetail(item.id)">
+ <div class="img-div">
+ <img :src="item.path"/>
+ </div>
+ <div class="item-name">{{ item.name }}</div>
+ </div>
+ </div>
+ </mt-tab-container-item>
+ <mt-tab-container-item id="3">
+ <CustomSearch3 v-on:search="SearchVideos"></CustomSearch3>
+ <div class="content-videos"
+ v-infinite-scroll="NextVideos"
+ :infinite-scroll-disabled="videos.scrollDisabled"
+ :infinite-scroll-distance="10">
+ <div class="content-item"
+ v-for="item in videos.data"
+ :key="item.id"
+ @click="ToVideoDetail(item.id)">
+ <div class="item-left">
+ <img :src="item.cover"/>
+ </div>
+ <div class="item-right">
+ <div class="item-name">{{ item.name }}</div>
+ <div class="item-introduce">{{ item.description }}</div>
+ </div>
+ </div>
+ </div>
+ </mt-tab-container-item>
+ </mt-tab-container>
+ </div>
+ </div>
+</template>
+
+<script>
+import CustomSearch3 from "@/components/CustomSearch3";
+import {
+ GetDataDetail as Api_GetDataDetail,
+ GetDataDetailImages as Api_GetDataDetailImages,
+ GetDataDetailVideos as Api_GetDataDetailVideos,
+} from "@/api/apilist";
+
+export default {
+ name: "detail",
+ components: {CustomSearch3},
+ data() {
+ return {
+ titleName: "",
+ titleIntroduce: "",
+ navbarIndex: "1",
+ basisInfo: {
+ id: "",
+ keyWord: "",
+ introduction: "",
+ file: "",
+ },
+ images: {
+ searchType: "title",
+ searchName: "",
+ pageSize: 10,
+ currentPage: 1,
+ total: 0,
+ data: [],
+ scrollDisabled: false,
+ },
+ videos: {
+ searchType: "title",
+ searchName: "",
+ pageSize: 10,
+ currentPage: 1,
+ total: 0,
+ data: [],
+ scrollDisabled: false,
+ },
+ }
+ },
+ methods: {
+ OnlinePreview: function (fileUrl) {
+ if (fileUrl) {
+ if (fileUrl.replace(/\\/g, '').toLowerCase().indexOf('.pdf') >= 0) {
+ window.open(fileUrl);
+ } else {
+ //https://view.officeapps.live.com/op/view.aspx?src=
+ window.open("http://www.xdocin.com/xdoc?_func=to&_format=html&_cache=1&_xdoc=" + fileUrl.replace(/\\/g, ''));
+ }
+ }
+ },
+ SearchBasisInfo: function (id) {
+ Api_GetDataDetail(id).then(res => {
+ this.basisInfo = res;
+ this.titleIntroduce = res.keyWord;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ SearchImages: function (searchType, searchName) {
+ this.images.searchType = searchType;
+ this.images.searchName = searchName;
+ Api_GetDataDetailImages(this.$route.query.id, searchType, searchName, 1, 10).then(res => {
+ this.images.currentPage = res.currentPage;
+ this.images.pageSize = res.pageSize;
+ this.images.total = res.total;
+ this.images.data = res.data;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ NextImages: function () {
+ let searchType = this.images.searchType;
+ let searchName = this.images.searchName;
+ let currentPage = this.images.currentPage + 1;
+ let pageSize = this.images.pageSize;
+ Api_GetDataDetailImages(this.$route.query.id, searchType, searchName, currentPage, pageSize).then(res => {
+ if (res.data.length > 0) {
+ this.images.total = res.total;
+ this.images.currentPage = res.currentPage;
+ this.images.data = this.images.data.concat(res.data);
+ }
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ SearchVideos: function (searchType, searchName) {
+ this.videos.searchType = searchType;
+ this.videos.searchName = searchName;
+ Api_GetDataDetailVideos(this.$route.query.id, searchType, searchName, 1, 10).then(res => {
+ this.videos.currentPage = res.currentPage;
+ this.videos.pageSize = res.pageSize;
+ this.videos.total = res.total;
+ this.videos.data = res.data;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ NextVideos: function () {
+ let searchType = this.videos.searchType;
+ let searchName = this.videos.searchName;
+ let currentPage = this.videos.currentPage + 1;
+ let pageSize = this.videos.pageSize;
+ Api_GetDataDetailVideos(this.$route.query.id, searchType, searchName, currentPage, pageSize).then(res => {
+ if (res.data.length > 0) {
+ this.videos.total = res.total;
+ this.videos.currentPage = res.currentPage;
+ this.videos.data = this.videos.data.concat(res.data);
+ }
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ ToImageDetail: function (id) {
+ let objId = this.$route.query.id;
+ this.$router.push({name: "personage-detail-image", query: {id: id, objId: objId}});
+ },
+ ToVideoDetail: function (id) {
+ let objId = this.$route.query.id;
+ this.$router.push({name: "personage-detail-video", query: {id: id, objId: objId}});
+ },
+ ToListPage: function () {
+ this.$router.push({name: "personage-list"})
+ },
+ },
+ watch: {
+ navbarIndex: function () {
+ switch (this.navbarIndex) {
+ case 1:
+ this.images.scrollDisabled = true;
+ this.videos.scrollDisabled = true;
+ break;
+ case 2:
+ this.images.scrollDisabled = false;
+ this.videos.scrollDisabled = true;
+ break;
+ case 3:
+ this.images.scrollDisabled = true;
+ this.videos.scrollDisabled = false;
+ break;
+ }
+ }
+ },
+ created() {
+ let id = this.$route.query.id;
+ this.titleName = this.$route.query.name;
+ this.SearchBasisInfo(id);
+ this.SearchImages("title", "");
+ this.SearchVideos("title", "");
+ }
+}
+</script>
+
+<style scoped>
+.data-detail {
+ width: 100%;
+}
+
+.data-detail .title {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: space-between;
+ align-items: center;
+
+ width: 100%;
+ height: 15.9vh;
+ background: url("../../assets/datadetail/detail@1x.png") no-repeat 100% 100%;
+ background-size: cover;
+ border-radius: 10px 10px 0 0;
+}
+
+.data-detail .title .title-left {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: flex-start;
+
+ width: 60%;
+ height: 100%;
+ padding-left: 2vh;
+}
+
+.data-detail .title .title-name {
+ width: 100%;
+ text-align: left;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+
+ font-size: 2.62rem;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 5.24rem;
+ color: #FFFFFF;
+ opacity: 1;
+}
+
+.data-detail .title .title-introduce {
+ width: 100%;
+
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 3.37rem;
+ color: #FFFFFF;
+ opacity: 1;
+}
+
+.data-detail .title .title-right {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: flex-start;
+
+ width: 30%;
+ height: 100%;
+}
+
+.data-detail .title .online-preview {
+ width: 80%;
+ background: #EFC587;
+ opacity: 1;
+ border-radius: 60px;
+
+ font-size: 1.75rem;
+ font-family: Source Han Sans CN;
+ font-weight: bold;
+ line-height: 3.87vh;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.data-detail .content {
+ width: 90%;
+ height: 84.1vh;
+ margin-left: 5%;
+ border-radius: 30px;
+}
+
+.mint-navbar /deep/ .mint-tab-item-label {
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 500;
+ line-height: 2rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.mint-navbar /deep/ .is-selected {
+ color: #BC0000;
+ border-bottom: 0.3vh solid #BC0000;
+}
+
+.mint-navbar /deep/ .is-selected .mint-tab-item-label {
+ color: #BC0000;
+}
+
+.mint-tab-container /deep/ .mint-tab-container-item:nth-child(1) {
+ padding-top: 5vh;
+}
+
+.content-keyword {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.content-keyword .item-name {
+ text-align: left;
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: bold;
+ line-height: 6rem;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.content-introduction {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.content-introduction .item-name {
+ text-align: left;
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: bold;
+ line-height: 6rem;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.mint-tab-container /deep/ .mint-tab-container-item:nth-child(2) {
+ padding-top: 2vh;
+}
+
+.custom-search3 {
+ margin-bottom: 2vh;
+}
+
+.content-images {
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: flex-start;
+}
+
+.content-images .content-item {
+ width: 50%;
+ height: 25vh;
+}
+
+.content-images .content-item .img-div {
+ width: 90%;
+ height: 80%;
+ border-radius: 10px;
+ box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
+}
+
+.content-images .content-item .img-div img {
+ width: 100%;
+ height: 100%;
+ border-radius: 10px;
+ object-fit: cover;
+}
+
+.content-images .content-item .item-name {
+ width: 90%;
+
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+
+ font-size: 2em;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 2em;
+ color: #333333;
+ opacity: 1;
+}
+
+.mint-tab-container /deep/ .mint-tab-container-item:nth-child(3) {
+ padding-top: 2vh;
+}
+
+.content-videos {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+}
+
+.content-videos .content-item {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+ align-items: center;
+
+ height: 10vh;
+ margin: 2vh auto;
+}
+
+.content-videos .item-left {
+ width: 30%;
+ height: 100%;
+}
+
+.content-videos .item-left img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.content-videos .item-right {
+ width: 70%;
+ height: 100%;
+ padding-left: 2vw;
+}
+
+.content-videos .item-name {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ text-align: left;
+ font-size: 2rem;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 4rem;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.content-videos .item-introduce {
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ text-align: left;
+ font-size: 1.62rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+</style>
diff --git a/src/views/personage/detailImage.vue b/src/views/personage/detailImage.vue
new file mode 100644
index 0000000..07a9a97
--- /dev/null
+++ b/src/views/personage/detailImage.vue
@@ -0,0 +1,133 @@
+<template>
+ <div class="data-detail-image">
+ <div class="images">
+ <mt-swipe :show-indicators="false" :auto="0" :continuous="false" @change="ChangeImage">
+ <mt-swipe-item v-for="item in images.data" :key="item.key">
+ <img :src="item.path"/>
+ </mt-swipe-item>
+ </mt-swipe>
+ </div>
+ <div class="content">
+ <mt-navbar v-model="navIndex">
+ <mt-tab-item id="1">关键词</mt-tab-item>
+ <mt-tab-item id="2">简介</mt-tab-item>
+ </mt-navbar>
+ <mt-tab-container v-model="navIndex">
+ <mt-tab-container-item id="1">
+ {{ image.keyWord }}
+ </mt-tab-container-item>
+ <mt-tab-container-item id="2">
+ {{ image.introduction }}
+ </mt-tab-container-item>
+ </mt-tab-container>
+ </div>
+ </div>
+</template>
+
+<script>
+import {GetImageDetail as Api_GetImageDetail} from "@/api/apilist";
+
+export default {
+ name: "detailImage",
+ data() {
+ return {
+ navIndex: "1",
+ images: {
+ pageSize: 10,
+ currentPage: 1,
+ total: 0,
+ data: []
+ },
+ image: {
+ id: "",
+ name: "",
+ path: "",
+ keyWord: "",
+ introduction: "",
+ }
+ }
+ },
+ methods: {
+ ChangeImage: function (index) {
+ this.image = this.images.data[index];
+ },
+ },
+ created() {
+ let imageId = this.$route.query.id;
+ let objId = this.$route.query.objId;
+ Api_GetImageDetail(imageId, 1, objId, 999).then(res => {
+ this.images = res;
+ this.image = res.data[0];
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ }
+}
+</script>
+
+<style scoped>
+.data-detail-image {
+ width: 100%;
+}
+
+.images {
+ width: 100%;
+ height: 31.5vh;
+}
+
+.images img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.content {
+ width: 100%;
+ height: 66vh;
+ box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
+ opacity: 1;
+ border-radius: 10px;
+
+ padding-top: 1vh;
+}
+
+.content > div{
+ width: 90%;
+ margin-left: 5%;
+}
+
+.mint-navbar{
+ margin-bottom: 4vh;
+}
+
+.mint-navbar .mint-tab-item /deep/ .mint-tab-item-label {
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 500;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.mint-navbar .is-selected {
+ border-bottom: 0.3rem solid #BC0000;
+}
+
+.mint-navbar .is-selected /deep/ .mint-tab-item-label {
+ color: #BC0000;
+ font-weight: bold;
+}
+
+.mint-tab-container {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #585858;
+ opacity: 1;
+}
+</style>
diff --git a/src/views/personage/detailvideo.vue b/src/views/personage/detailvideo.vue
new file mode 100644
index 0000000..f755c4c
--- /dev/null
+++ b/src/views/personage/detailvideo.vue
@@ -0,0 +1,121 @@
+<template>
+ <div class="data-detail-video">
+ <div class="videos">
+ <video poster="" :src="video.patch" controls="controls">
+ 您的浏览器不支持 video 标签。
+ </video>
+ </div>
+ <div class="content">
+ <mt-navbar v-model="navIndex">
+ <mt-tab-item id="1">关键词</mt-tab-item>
+ <mt-tab-item id="2">简介</mt-tab-item>
+ </mt-navbar>
+ <mt-tab-container v-model="navIndex">
+ <mt-tab-container-item id="1">
+ {{ video.keyWord }}
+ </mt-tab-container-item>
+ <mt-tab-container-item id="2">
+ {{ video.introduction }}
+ </mt-tab-container-item>
+ </mt-tab-container>
+ </div>
+ </div>
+</template>
+
+<script>
+import {GetVideoDetail as Api_GetVideoDetail} from "@/api/apilist";
+
+export default {
+ name: "detailVideo",
+ data() {
+ return {
+ navIndex: "1",
+ video: {
+ id: "",
+ name: "",
+ path: "",
+ keyWord: "",
+ introduction: "",
+ },
+ }
+ },
+ methods: {
+
+ },
+ created() {
+ let id = this.$route.query.id;
+ Api_GetVideoDetail(id).then(res => {
+ this.video = res;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ }
+}
+</script>
+
+<style scoped>
+.data-detail-video {
+ width: 100%;
+}
+
+.videos {
+ width: 100%;
+ height: 31.5vh;
+}
+
+.videos video {
+ width: 100%;
+ height: 100%;
+ background: black;
+}
+
+.content {
+ width: 100%;
+ height: 66vh;
+ box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
+ opacity: 1;
+ border-radius: 10px;
+
+ padding-top: 1vh;
+}
+
+.content > div{
+ width: 90%;
+ margin-left: 5%;
+}
+
+.mint-navbar{
+ margin-bottom: 4vh;
+}
+
+.mint-navbar .mint-tab-item /deep/ .mint-tab-item-label {
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 500;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.mint-navbar .is-selected {
+ border-bottom: 0.3rem solid #BC0000;
+}
+
+.mint-navbar .is-selected /deep/ .mint-tab-item-label {
+ color: #BC0000;
+ font-weight: bold;
+}
+
+.mint-tab-container {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #585858;
+ opacity: 1;
+}
+</style>
diff --git a/src/views/personage/list.vue b/src/views/personage/list.vue
new file mode 100644
index 0000000..c9eaa76
--- /dev/null
+++ b/src/views/personage/list.vue
@@ -0,0 +1,190 @@
+<template>
+ <div class="list-root">
+ <div class="search">
+ <CustomSearch3 v-on:search="Search"></CustomSearch3>
+ </div>
+ <div class="line"></div>
+ <div class="data-list"
+ v-infinite-scroll="loadBottom"
+ :infinite-scroll-disabled="allLoaded"
+ :infinite-scroll-distance="10">
+ <template v-for="item in data.data">
+ <div class="image-item"
+ :key="item.key"
+ @click="ToDetail(item.id,item.name)">
+ <div class="item-left">
+ <img :src="item.img"/>
+ </div>
+ <div class="item-right">
+ <div class="item-title">{{ item.name }}</div>
+ <div class="item-context">{{ item.keyWord }}</div>
+ </div>
+ </div>
+ <div :key="item.key" class="line"></div>
+ </template>
+ </div>
+ </div>
+</template>
+
+<script>
+import CustomSearch3 from "@/components/CustomSearch3";
+import {GetDataList as Api_GetDataList} from "@/api/apilist";
+
+export default {
+ name: "list",
+ components: {CustomSearch3},
+ data() {
+ return {
+ dataType: 4,
+ searchType: "title",
+ searchName: "",
+ data: {
+ currentPage: 1,
+ pageSize: 5,
+ total: 0,
+ data: []
+ },
+ allLoaded: false
+ };
+ },
+ methods: {
+ Search: function (searchType, searchName) {
+ this.searchType = searchType;
+ this.searchName = searchName;
+ Api_GetDataList(this.dataType, searchType, searchName, 1, this.data.pageSize).then(res => {
+ this.currentPage = res.currentPage;
+ this.pageSize = res.pageSize;
+ this.total = res.total;
+ this.data = res;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert("错误的请求!");
+ });
+ },
+ loadBottom: function () {
+ Api_GetDataList(this.dataType, this.searchType, this.searchName, this.data.currentPage + 1, this.data.pageSize).then(res => {
+ this.data.currentPage = res.currentPage;
+ this.data.pageSize = res.pageSize;
+ this.data.total = res.total;
+ if (res.data.length > 0) {
+ this.data.data = this.data.data.concat(res.data);
+ } else {
+ this.allLoaded = true;
+ }
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert("错误的请求!");
+ });
+ },
+ ToDetail: function (id, name) {
+ this.$router.push({name: "personage-detail", query: {id: id, name: name}})
+ }
+ },
+ created() {
+ this.Search("title", "");
+ }
+}
+</script>
+
+<style scoped>
+li {
+ list-style-type: none;
+}
+
+.list-root {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+ width: 100%;
+}
+
+.search {
+ width: 100%;
+ margin-top: 3vh;
+}
+
+.search .custom-search3 {
+ width: 90%;
+ margin-left: 5%;
+}
+
+.line {
+ width: 100%;
+ border: 1px solid #EEEEEE;
+ margin-top: 3vh;
+ margin-bottom: 3vh;
+ opacity: 1;
+}
+
+.data-list {
+ width: 90%;
+ height: 65vh;
+ margin-left: 5%;
+ overflow: scroll;
+}
+
+.data-list .line {
+ width: 100%;
+ margin-bottom: 2vh;
+}
+
+.data-list /deep/ .image-item {
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: flex-start;
+
+ width: 100%;
+ margin-bottom: 2vh;
+}
+
+.data-list /deep/ .image-item .item-left {
+ width: 30%;
+}
+
+.data-list /deep/ .image-item .item-left img {
+ width: 100%;
+ height: 12vh;
+ border-radius: 10px;
+ object-fit: cover;
+}
+
+.data-list /deep/ .image-item .item-right {
+ width: 70%;
+}
+
+.data-list /deep/ .image-item .item-title {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ padding-left: 2rem;
+
+ text-align: left;
+ font-size: 2rem;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 4rem;
+ color: #BC0000;
+}
+
+.data-list /deep/ .image-item .item-context {
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ padding-left: 2rem;
+
+ font-size: 1.62rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 2rem;
+ color: #767676;
+ text-align: left;
+}
+</style>
diff --git a/src/views/scenery/detail.vue b/src/views/scenery/detail.vue
new file mode 100644
index 0000000..7ff3e7b
--- /dev/null
+++ b/src/views/scenery/detail.vue
@@ -0,0 +1,510 @@
+<template>
+ <div class="data-detail">
+ <div class="title">
+ <div class="title-left">
+ <div class="title-name" @click="ToListPage">{{ titleName }}</div>
+ <div class="title-introduce">{{ titleIntroduce }}</div>
+ </div>
+ <div class="title-right">
+ <div class="online-preview" @click="OnlinePreview(basisInfo.file)">在线浏览</div>
+ </div>
+ </div>
+ <div class="content">
+ <mt-navbar ref="navbar" v-model="navbarIndex">
+ <mt-tab-item id="1" data-type="1">基本信息</mt-tab-item>
+ <mt-tab-item id="2" data-type="2">相关图片</mt-tab-item>
+ <mt-tab-item id="3" data-type="3">相关视频</mt-tab-item>
+ </mt-navbar>
+ <mt-tab-container v-model="navbarIndex">
+ <mt-tab-container-item id="1">
+ <div class="content-keyword">
+ <div class="item-name">关键字</div>
+ {{ basisInfo.keyWord }}
+ </div>
+ <div class="content-introduction">
+ <div class="item-name">简介</div>
+ {{ basisInfo.introduction }}
+ </div>
+ </mt-tab-container-item>
+ <mt-tab-container-item id="2">
+ <CustomSearch3 v-on:search="SearchImages"></CustomSearch3>
+ <div class="content-images"
+ v-infinite-scroll="NextImages"
+ :infinite-scroll-disabled="images.scrollDisabled"
+ :infinite-scroll-distance="10">
+ <div class="content-item"
+ v-for="item in images.data"
+ :key="item.id"
+ @click="ToImageDetail(item.id)">
+ <div class="img-div">
+ <img :src="item.path"/>
+ </div>
+ <div class="item-name">{{ item.name }}</div>
+ </div>
+ </div>
+ </mt-tab-container-item>
+ <mt-tab-container-item id="3">
+ <CustomSearch3 v-on:search="SearchVideos"></CustomSearch3>
+ <div class="content-videos"
+ v-infinite-scroll="NextVideos"
+ :infinite-scroll-disabled="videos.scrollDisabled"
+ :infinite-scroll-distance="10">
+ <div class="content-item"
+ v-for="item in videos.data"
+ :key="item.id"
+ @click="ToVideoDetail(item.id)">
+ <div class="item-left">
+ <img :src="item.cover"/>
+ </div>
+ <div class="item-right">
+ <div class="item-name">{{ item.name }}</div>
+ <div class="item-introduce">{{ item.description }}</div>
+ </div>
+ </div>
+ </div>
+ </mt-tab-container-item>
+ </mt-tab-container>
+ </div>
+ </div>
+</template>
+
+<script>
+import CustomSearch3 from "@/components/CustomSearch3";
+import {
+ GetDataDetail as Api_GetDataDetail,
+ GetDataDetailImages as Api_GetDataDetailImages,
+ GetDataDetailVideos as Api_GetDataDetailVideos,
+} from "@/api/apilist";
+
+export default {
+ name: "detail",
+ components: {CustomSearch3},
+ data() {
+ return {
+ titleName: "",
+ titleIntroduce: "",
+ navbarIndex: "1",
+ basisInfo: {
+ id: "",
+ keyWord: "",
+ introduction: "",
+ file: "",
+ },
+ images: {
+ searchType: "title",
+ searchName: "",
+ pageSize: 10,
+ currentPage: 1,
+ total: 0,
+ data: [],
+ scrollDisabled: false,
+ },
+ videos: {
+ searchType: "title",
+ searchName: "",
+ pageSize: 10,
+ currentPage: 1,
+ total: 0,
+ data: [],
+ scrollDisabled: false,
+ },
+ }
+ },
+ methods: {
+ OnlinePreview: function (fileUrl) {
+ if (fileUrl) {
+ if (fileUrl.replace(/\\/g, '').toLowerCase().indexOf('.pdf') >= 0) {
+ window.open(fileUrl);
+ } else {
+ //https://view.officeapps.live.com/op/view.aspx?src=
+ window.open("http://www.xdocin.com/xdoc?_func=to&_format=html&_cache=1&_xdoc=" + fileUrl.replace(/\\/g, ''));
+ }
+ }
+ },
+ SearchBasisInfo: function (id) {
+ Api_GetDataDetail(id).then(res => {
+ this.basisInfo = res;
+ this.titleIntroduce = res.keyWord;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ SearchImages: function (searchType, searchName) {
+ this.images.searchType = searchType;
+ this.images.searchName = searchName;
+ Api_GetDataDetailImages(this.$route.query.id, searchType, searchName, 1, 10).then(res => {
+ this.images.currentPage = res.currentPage;
+ this.images.pageSize = res.pageSize;
+ this.images.total = res.total;
+ this.images.data = res.data;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ NextImages: function () {
+ let searchType = this.images.searchType;
+ let searchName = this.images.searchName;
+ let currentPage = this.images.currentPage + 1;
+ let pageSize = this.images.pageSize;
+ Api_GetDataDetailImages(this.$route.query.id, searchType, searchName, currentPage, pageSize).then(res => {
+ if (res.data.length > 0) {
+ this.images.total = res.total;
+ this.images.currentPage = res.currentPage;
+ this.images.data = this.images.data.concat(res.data);
+ }
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ SearchVideos: function (searchType, searchName) {
+ this.videos.searchType = searchType;
+ this.videos.searchName = searchName;
+ Api_GetDataDetailVideos(this.$route.query.id, searchType, searchName, 1, 10).then(res => {
+ this.videos.currentPage = res.currentPage;
+ this.videos.pageSize = res.pageSize;
+ this.videos.total = res.total;
+ this.videos.data = res.data;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ NextVideos: function () {
+ let searchType = this.videos.searchType;
+ let searchName = this.videos.searchName;
+ let currentPage = this.videos.currentPage + 1;
+ let pageSize = this.videos.pageSize;
+ Api_GetDataDetailVideos(this.$route.query.id, searchType, searchName, currentPage, pageSize).then(res => {
+ if (res.data.length > 0) {
+ this.videos.total = res.total;
+ this.videos.currentPage = res.currentPage;
+ this.videos.data = this.videos.data.concat(res.data);
+ }
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ ToImageDetail: function (id) {
+ let objId = this.$route.query.id;
+ this.$router.push({name: "scenery-detail-image", query: {id: id, objId: objId}});
+ },
+ ToVideoDetail: function (id) {
+ let objId = this.$route.query.id;
+ this.$router.push({name: "scenery-detail-video", query: {id: id, objId: objId}});
+ },
+ ToListPage: function () {
+ this.$router.push({name: "scenery-list"})
+ },
+ },
+ watch: {
+ navbarIndex: function () {
+ switch (this.navbarIndex) {
+ case 1:
+ this.images.scrollDisabled = true;
+ this.videos.scrollDisabled = true;
+ break;
+ case 2:
+ this.images.scrollDisabled = false;
+ this.videos.scrollDisabled = true;
+ break;
+ case 3:
+ this.images.scrollDisabled = true;
+ this.videos.scrollDisabled = false;
+ break;
+ }
+ }
+ },
+ created() {
+ let id = this.$route.query.id;
+ this.titleName = this.$route.query.name;
+ this.SearchBasisInfo(id);
+ this.SearchImages("title", "");
+ this.SearchVideos("title", "");
+ }
+}
+</script>
+
+<style scoped>
+.data-detail {
+ width: 100%;
+}
+
+.data-detail .title {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: space-between;
+ align-items: center;
+
+ width: 100%;
+ height: 15.9vh;
+ background: url("../../assets/datadetail/detail@1x.png") no-repeat 100% 100%;
+ background-size: cover;
+ border-radius: 10px 10px 0 0;
+}
+
+.data-detail .title .title-left {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: flex-start;
+
+ width: 60%;
+ height: 100%;
+ padding-left: 2vh;
+}
+
+.data-detail .title .title-name {
+ width: 100%;
+ text-align: left;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+
+ font-size: 2.62rem;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 5.24rem;
+ color: #FFFFFF;
+ opacity: 1;
+}
+
+.data-detail .title .title-introduce {
+ width: 100%;
+
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 3.37rem;
+ color: #FFFFFF;
+ opacity: 1;
+}
+
+.data-detail .title .title-right {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: flex-start;
+
+ width: 30%;
+ height: 100%;
+}
+
+.data-detail .title .online-preview {
+ width: 80%;
+ background: #EFC587;
+ opacity: 1;
+ border-radius: 60px;
+
+ font-size: 1.75rem;
+ font-family: Source Han Sans CN;
+ font-weight: bold;
+ line-height: 3.87vh;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.data-detail .content {
+ width: 90%;
+ height: 84.1vh;
+ margin-left: 5%;
+ border-radius: 30px;
+}
+
+.mint-navbar /deep/ .mint-tab-item-label {
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 500;
+ line-height: 2rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.mint-navbar /deep/ .is-selected {
+ color: #BC0000;
+ border-bottom: 0.3vh solid #BC0000;
+}
+
+.mint-navbar /deep/ .is-selected .mint-tab-item-label {
+ color: #BC0000;
+}
+
+.mint-tab-container /deep/ .mint-tab-container-item:nth-child(1) {
+ padding-top: 5vh;
+}
+
+.content-keyword {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.content-keyword .item-name {
+ text-align: left;
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: bold;
+ line-height: 6rem;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.content-introduction {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.content-introduction .item-name {
+ text-align: left;
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: bold;
+ line-height: 6rem;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.mint-tab-container /deep/ .mint-tab-container-item:nth-child(2) {
+ padding-top: 2vh;
+}
+
+.custom-search3 {
+ margin-bottom: 2vh;
+}
+
+.content-images {
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: flex-start;
+}
+
+.content-images .content-item {
+ width: 50%;
+ height: 25vh;
+}
+
+.content-images .content-item .img-div {
+ width: 90%;
+ height: 80%;
+ border-radius: 10px;
+ box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
+}
+
+.content-images .content-item .img-div img {
+ width: 100%;
+ height: 100%;
+ border-radius: 10px;
+ object-fit: cover;
+}
+
+.content-images .content-item .item-name {
+ width: 90%;
+
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+
+ font-size: 2em;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 2em;
+ color: #333333;
+ opacity: 1;
+}
+
+.mint-tab-container /deep/ .mint-tab-container-item:nth-child(3) {
+ padding-top: 2vh;
+}
+
+.content-videos {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+}
+
+.content-videos .content-item {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+ align-items: center;
+
+ height: 10vh;
+ margin: 2vh auto;
+}
+
+.content-videos .item-left {
+ width: 30%;
+ height: 100%;
+}
+
+.content-videos .item-left img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.content-videos .item-right {
+ width: 70%;
+ height: 100%;
+ padding-left: 2vw;
+}
+
+.content-videos .item-name {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ text-align: left;
+ font-size: 2rem;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 4rem;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.content-videos .item-introduce {
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ text-align: left;
+ font-size: 1.62rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+</style>
diff --git a/src/views/scenery/detailImage.vue b/src/views/scenery/detailImage.vue
new file mode 100644
index 0000000..07a9a97
--- /dev/null
+++ b/src/views/scenery/detailImage.vue
@@ -0,0 +1,133 @@
+<template>
+ <div class="data-detail-image">
+ <div class="images">
+ <mt-swipe :show-indicators="false" :auto="0" :continuous="false" @change="ChangeImage">
+ <mt-swipe-item v-for="item in images.data" :key="item.key">
+ <img :src="item.path"/>
+ </mt-swipe-item>
+ </mt-swipe>
+ </div>
+ <div class="content">
+ <mt-navbar v-model="navIndex">
+ <mt-tab-item id="1">关键词</mt-tab-item>
+ <mt-tab-item id="2">简介</mt-tab-item>
+ </mt-navbar>
+ <mt-tab-container v-model="navIndex">
+ <mt-tab-container-item id="1">
+ {{ image.keyWord }}
+ </mt-tab-container-item>
+ <mt-tab-container-item id="2">
+ {{ image.introduction }}
+ </mt-tab-container-item>
+ </mt-tab-container>
+ </div>
+ </div>
+</template>
+
+<script>
+import {GetImageDetail as Api_GetImageDetail} from "@/api/apilist";
+
+export default {
+ name: "detailImage",
+ data() {
+ return {
+ navIndex: "1",
+ images: {
+ pageSize: 10,
+ currentPage: 1,
+ total: 0,
+ data: []
+ },
+ image: {
+ id: "",
+ name: "",
+ path: "",
+ keyWord: "",
+ introduction: "",
+ }
+ }
+ },
+ methods: {
+ ChangeImage: function (index) {
+ this.image = this.images.data[index];
+ },
+ },
+ created() {
+ let imageId = this.$route.query.id;
+ let objId = this.$route.query.objId;
+ Api_GetImageDetail(imageId, 1, objId, 999).then(res => {
+ this.images = res;
+ this.image = res.data[0];
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ }
+}
+</script>
+
+<style scoped>
+.data-detail-image {
+ width: 100%;
+}
+
+.images {
+ width: 100%;
+ height: 31.5vh;
+}
+
+.images img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.content {
+ width: 100%;
+ height: 66vh;
+ box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
+ opacity: 1;
+ border-radius: 10px;
+
+ padding-top: 1vh;
+}
+
+.content > div{
+ width: 90%;
+ margin-left: 5%;
+}
+
+.mint-navbar{
+ margin-bottom: 4vh;
+}
+
+.mint-navbar .mint-tab-item /deep/ .mint-tab-item-label {
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 500;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.mint-navbar .is-selected {
+ border-bottom: 0.3rem solid #BC0000;
+}
+
+.mint-navbar .is-selected /deep/ .mint-tab-item-label {
+ color: #BC0000;
+ font-weight: bold;
+}
+
+.mint-tab-container {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #585858;
+ opacity: 1;
+}
+</style>
diff --git a/src/views/scenery/detailvideo.vue b/src/views/scenery/detailvideo.vue
new file mode 100644
index 0000000..f755c4c
--- /dev/null
+++ b/src/views/scenery/detailvideo.vue
@@ -0,0 +1,121 @@
+<template>
+ <div class="data-detail-video">
+ <div class="videos">
+ <video poster="" :src="video.patch" controls="controls">
+ 您的浏览器不支持 video 标签。
+ </video>
+ </div>
+ <div class="content">
+ <mt-navbar v-model="navIndex">
+ <mt-tab-item id="1">关键词</mt-tab-item>
+ <mt-tab-item id="2">简介</mt-tab-item>
+ </mt-navbar>
+ <mt-tab-container v-model="navIndex">
+ <mt-tab-container-item id="1">
+ {{ video.keyWord }}
+ </mt-tab-container-item>
+ <mt-tab-container-item id="2">
+ {{ video.introduction }}
+ </mt-tab-container-item>
+ </mt-tab-container>
+ </div>
+ </div>
+</template>
+
+<script>
+import {GetVideoDetail as Api_GetVideoDetail} from "@/api/apilist";
+
+export default {
+ name: "detailVideo",
+ data() {
+ return {
+ navIndex: "1",
+ video: {
+ id: "",
+ name: "",
+ path: "",
+ keyWord: "",
+ introduction: "",
+ },
+ }
+ },
+ methods: {
+
+ },
+ created() {
+ let id = this.$route.query.id;
+ Api_GetVideoDetail(id).then(res => {
+ this.video = res;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ }
+}
+</script>
+
+<style scoped>
+.data-detail-video {
+ width: 100%;
+}
+
+.videos {
+ width: 100%;
+ height: 31.5vh;
+}
+
+.videos video {
+ width: 100%;
+ height: 100%;
+ background: black;
+}
+
+.content {
+ width: 100%;
+ height: 66vh;
+ box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
+ opacity: 1;
+ border-radius: 10px;
+
+ padding-top: 1vh;
+}
+
+.content > div{
+ width: 90%;
+ margin-left: 5%;
+}
+
+.mint-navbar{
+ margin-bottom: 4vh;
+}
+
+.mint-navbar .mint-tab-item /deep/ .mint-tab-item-label {
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 500;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.mint-navbar .is-selected {
+ border-bottom: 0.3rem solid #BC0000;
+}
+
+.mint-navbar .is-selected /deep/ .mint-tab-item-label {
+ color: #BC0000;
+ font-weight: bold;
+}
+
+.mint-tab-container {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #585858;
+ opacity: 1;
+}
+</style>
diff --git a/src/views/scenery/list.vue b/src/views/scenery/list.vue
new file mode 100644
index 0000000..275e07b
--- /dev/null
+++ b/src/views/scenery/list.vue
@@ -0,0 +1,190 @@
+<template>
+ <div class="list-root">
+ <div class="search">
+ <CustomSearch3 v-on:search="Search"></CustomSearch3>
+ </div>
+ <div class="line"></div>
+ <div class="data-list"
+ v-infinite-scroll="loadBottom"
+ :infinite-scroll-disabled="allLoaded"
+ :infinite-scroll-distance="10">
+ <template v-for="item in data.data">
+ <div class="image-item"
+ :key="item.key"
+ @click="ToDetail(item.id,item.name)">
+ <div class="item-left">
+ <img :src="item.img"/>
+ </div>
+ <div class="item-right">
+ <div class="item-title">{{ item.name }}</div>
+ <div class="item-context">{{ item.keyWord }}</div>
+ </div>
+ </div>
+ <div :key="item.key" class="line"></div>
+ </template>
+ </div>
+ </div>
+</template>
+
+<script>
+import CustomSearch3 from "@/components/CustomSearch3";
+import {GetDataList as Api_GetDataList} from "@/api/apilist";
+
+export default {
+ name: "list",
+ components: {CustomSearch3},
+ data() {
+ return {
+ dataType: 3,
+ searchType: "title",
+ searchName: "",
+ data: {
+ currentPage: 1,
+ pageSize: 10,
+ total: 0,
+ data: []
+ },
+ allLoaded: false
+ };
+ },
+ methods: {
+ Search: function (searchType, searchName) {
+ this.searchType = searchType;
+ this.searchName = searchName;
+ Api_GetDataList(this.dataType, searchType, searchName, 1, this.data.pageSize).then(res => {
+ this.currentPage = res.currentPage;
+ this.pageSize = res.pageSize;
+ this.total = res.total;
+ this.data = res;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert("错误的请求!");
+ });
+ },
+ loadBottom: function () {
+ Api_GetDataList(this.dataType, this.searchType, this.searchName, this.data.currentPage + 1, this.data.pageSize).then(res => {
+ this.data.currentPage = res.currentPage;
+ this.data.pageSize = res.pageSize;
+ this.data.total = res.total;
+ if (res.data.length > 0) {
+ this.data.data = this.data.data.concat(res.data);
+ } else {
+ //加载完全部数据,上拉加载事件将不再执行
+ this.allLoaded = false;
+ }
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert("错误的请求!");
+ });
+ },
+ ToDetail: function (id, name) {
+ this.$router.push({name: "scenery-detail", query: {id: id, name: name}})
+ }
+ },
+ created() {
+ this.Search("title", "");
+ }
+}
+</script>
+
+<style scoped>
+li {
+ list-style-type: none;
+}
+
+.list-root {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+ width: 100%;
+}
+
+.search {
+ width: 100%;
+ margin-top: 3vh;
+}
+
+.search .custom-search3 {
+ width: 90%;
+ margin-left: 5%;
+}
+
+.line {
+ width: 100%;
+ border: 1px solid #EEEEEE;
+ margin-top: 3vh;
+ margin-bottom: 3vh;
+ opacity: 1;
+}
+
+.data-list {
+ width: 90%;
+ margin-left: 5%;
+ overflow: scroll;
+}
+
+.data-list .line {
+ width: 100%;
+ margin-bottom: 2vh;
+}
+
+.data-list /deep/ .image-item {
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: flex-start;
+
+ width: 100%;
+ margin-bottom: 2vh;
+}
+
+.data-list /deep/ .image-item .item-left {
+ width: 30%;
+}
+
+.data-list /deep/ .image-item .item-left img {
+ width: 100%;
+ height: 12vh;
+ border-radius: 10px;
+ object-fit: cover;
+}
+
+.data-list /deep/ .image-item .item-right {
+ width: 70%;
+}
+
+.data-list /deep/ .image-item .item-title {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ padding-left: 2rem;
+
+ text-align: left;
+ font-size: 2rem;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 4rem;
+ color: #BC0000;
+}
+
+.data-list /deep/ .image-item .item-context {
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ padding-left: 2rem;
+
+ font-size: 1.62rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 2rem;
+ color: #767676;
+ text-align: left;
+}
+</style>
diff --git a/src/views/search/index.vue b/src/views/search/index.vue
new file mode 100644
index 0000000..ca43210
--- /dev/null
+++ b/src/views/search/index.vue
@@ -0,0 +1,175 @@
+<template>
+ <div class="search-index">
+ <div class="index-title1">热门搜索</div>
+ <div class="index-hot">
+ <div v-for="item in hotList" :key="item.id" @click="SearchHot(item)">
+ {{ item.title }}
+ </div>
+ </div>
+ <div class="index-title2">
+ 历史搜索
+ <span class="remove-btn" @click="ClearHis">清除</span>
+ </div>
+ <div class="index-history">
+ <template v-for="item in historyList">
+ <div class="search-msg" :key="item.key" @click="SearchHis(item)">
+ <svg t="1639023179293" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
+ p-id="6665" width="200" height="200">
+ <path
+ d="M512 160c194.410667 0 352 157.589333 352 352S706.410667 864 512 864l-2.538667-0.106667c-91.477333-7.274667-165.738667-38.08-221.44-91.989333L288 842.666667h-64V640H405.333333v64h-92.842666c46.250667 56.917333 112.490667 88.725333 200.768 96l6.677333-0.106667C675.328 795.690667 800 668.394667 800 512c0-159.061333-128.938667-288-288-288S224 352.938667 224 512h-64c0-194.410667 157.589333-352 352-352zM469.333333 320h64v160h160v64H469.333333V320z"
+ p-id="6666" fill="#C7C7C7"></path>
+ </svg>
+ <span>{{ item.searchName }}</span>
+ </div>
+ <div class="line" :key="item.key"></div>
+ </template>
+ </div>
+ </div>
+</template>
+
+<script>
+import {
+ GetSearchHomeInfo as Api_GetSearchHomeInfo,
+} from '@/api/apilist'
+
+export default {
+ name: "index",
+ data() {
+ return {
+ hotList: [],
+ historyList: [],
+ }
+ },
+ methods: {
+ SearchHot(item) {
+ console.log(item);
+ this.$router.push({
+ name: "search-results",
+ query: {searchType: "title", searchName: item.title, type: item.type}
+ });
+ },
+ SearchHis(item) {
+ this.$router.push({
+ name: "search-results",
+ query: {searchType: item.searchType, searchName: item.searchName}
+ });
+ },
+ ClearHis() {
+ localStorage.clear();
+ this.historyList = [];
+ }
+ },
+ created() {
+ Api_GetSearchHomeInfo().then(res => {
+ this.hotList = res.rmtj;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert("请求错误!");
+ });
+
+ if (localStorage.searchHistory) {
+ this.historyList = eval(localStorage.searchHistory).reverse();
+ }
+ }
+}
+</script>
+
+<style scoped>
+.search-index {
+ width: 90%;
+ margin-left: 5%;
+}
+
+.index-title1 {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 5.87rem;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.index-hot {
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: flex-start;
+}
+
+.index-hot > div {
+ width: 30%;
+ border: 1px solid #999999;
+ border-radius: 140px;
+ margin-right: 3%;
+ margin-bottom: 2vh;
+ cursor: pointer;
+
+ font-size: 1.62rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 3.37rem;
+ color: #767676;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+}
+
+.index-hot > div:first-child {
+ border: 0;
+ color: #FFFFFF;
+ background: #BC0000;
+}
+
+.index-title2 {
+ text-align: left;
+ font-size: 1.75rem;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 5.87rem;
+ color: #333333;
+}
+
+.index-title2 .remove-btn {
+ float: right;
+ font-size: 1.5rem;
+ font-family: Source Han Serif CN;
+ font-weight: 400;
+ line-height: 5.87rem;
+ color: #767676;
+ cursor: pointer;
+}
+
+.index-history .search-msg {
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: center;
+
+ font-size: 1.62rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 3.37rem;
+ color: #999999;
+}
+
+.search-msg span {
+ cursor: pointer;
+}
+
+.search-msg svg {
+ width: 3vh;
+ height: 3vh;
+ margin-right: 1vh;
+ cursor: pointer;
+}
+
+.index-history .line {
+ border: 1px solid #E4E4E4;
+ margin-top: 1vh;
+ margin-bottom: 1vh;
+}
+</style>
diff --git a/src/views/search/results.vue b/src/views/search/results.vue
new file mode 100644
index 0000000..bcc0e4d
--- /dev/null
+++ b/src/views/search/results.vue
@@ -0,0 +1,268 @@
+<template>
+ <div class="search-results">
+ <div class="results-title">搜索结果</div>
+ <div class="results-list">
+ <navbar ref="navbar" v-model="type">
+ <tab-item id="1" data-type="1">红色记忆</tab-item>
+ <tab-item id="2" data-type="2">红色精神</tab-item>
+ <tab-item id="3" data-type="3">红色景区</tab-item>
+ <tab-item id="4" data-type="4">红色人物</tab-item>
+ </navbar>
+ <tab-container v-model="type">
+ <tab-container-item id="1">
+ <template v-for="item in searchItems.hsjy.data">
+ <div class="text-item" :key="item.key" @click="ToMemoryDetail(item.id,item.name)">
+ <div class="item-title">{{ item.name }}</div>
+ <div class="item-context">{{ item.keyWord }}</div>
+ </div>
+ <div class="line" :key="item.key"></div>
+ </template>
+ </tab-container-item>
+ <tab-container-item id="2">
+ <template v-for="item in searchItems.hsjs.data">
+ <div class="text-item" :key="item.key" @click="ToSpiritDetail(item.id,item.name)">
+ <div class="item-title">{{ item.name }}</div>
+ <div class="item-context">{{ item.keyWord }}</div>
+ </div>
+ <div class="line" :key="item.key"></div>
+ </template>
+ </tab-container-item>
+ <tab-container-item id="3">
+ <template v-for="item in searchItems.hsjq.data">
+ <div class="image-item" :key="item.key" @click="ToSceneryDetail(item.id,item.name)">
+ <div class="item-left">
+ <img :src="item.img"/>
+ </div>
+ <div class="item-right">
+ <div class="item-title">{{ item.name }}</div>
+ <div class="item-context">{{ item.keyWord }}</div>
+ </div>
+ </div>
+ <div class="line" :key="item.key"></div>
+ </template>
+ </tab-container-item>
+ <tab-container-item id="4">
+ <template v-for="item in searchItems.hsrw.data">
+ <div class="image-item" :key="item.key" @click="ToPersonageDetail(item.id,item.name)">
+ <div class="item-left">
+ <img :src="item.img"/>
+ </div>
+ <div class="item-right">
+ <div class="item-title">{{ item.name }}</div>
+ <div class="item-context">{{ item.keyWord }}</div>
+ </div>
+ </div>
+ <div class="line" :key="item.key"></div>
+ </template>
+ </tab-container-item>
+ </tab-container>
+ </div>
+ </div>
+</template>
+
+<script>
+import {Navbar, TabItem, TabContainer, TabContainerItem} from 'mint-ui';
+import {
+ GetSearchInfo as Api_GetSearchInfo,
+} from '@/api/apilist'
+
+export default {
+ name: "results",
+ components: {Navbar, TabItem, TabContainer, TabContainerItem},
+ data() {
+ return {
+ type: "1",
+ searchItems: [],
+ };
+ },
+ methods: {
+ ToMemoryDetail: function (id, name) {
+ this.$router.push({name: "memory-detail", query: {id: id, name: name}});
+ },
+ ToPersonageDetail: function (id, name) {
+ this.$router.push({name: "personage-detail", query: {id: id, name: name}});
+ },
+ ToSceneryDetail: function (id, name) {
+ this.$router.push({name: "scenery-detail", query: {id: id, name: name}});
+ },
+ ToSpiritDetail: function (id, name) {
+ this.$router.push({name: "spirit-detail", query: {id: id, name: name}});
+ },
+ },
+ watch: {},
+ created: function () {
+ let searchType = this.$route.query.searchType;
+ let searchName = this.$route.query.searchName;
+ let type = this.$route.query.type;
+ if (type) {
+ this.type = type.toString();
+ }
+
+ Api_GetSearchInfo(searchType, searchName).then(res => {
+ this.searchItems = res;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert("请求错误!");
+ });
+ },
+ beforeRouteUpdate(to, from, next) {
+ if (to.fullPath != from.fullPath) {
+ let searchType = to.query.searchType
+ let searchName = to.query.searchName;
+ let type = to.query.type;
+ if (type) {
+ this.type = type.toString();
+ }
+
+ Api_GetSearchInfo(searchType, searchName).then(res => {
+ this.searchItems = [];
+ this.searchItems = res;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert("请求错误!");
+ });
+ }
+ next();
+ },
+}
+</script>
+
+<style scoped>
+.search-results {
+ width: 90%;
+ margin-left: 5%;
+}
+
+.results-title {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 5.87rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.search-results .mint-navbar {
+ margin-bottom: 2vh;
+}
+
+.search-results .mint-navbar .mint-tab-item /deep/ .mint-tab-item-label {
+ font-size: 1.62rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 1.93rem;
+ color: #767676;
+ opacity: 1;
+ cursor: pointer
+}
+
+.search-results .mint-navbar .is-selected {
+ border-bottom: 2px solid #BC0000;
+}
+
+.search-results .mint-navbar .is-selected /deep/ .mint-tab-item-label {
+ color: #BC0000;
+}
+
+.search-results .mint-tab-container {
+}
+
+.search-results .mint-tab-container .mint-tab-container-item {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+}
+
+.search-results .mint-tab-container .mint-tab-container-item .line {
+ width: 100%;
+ border: 1px solid #EEEEEE;
+ margin-bottom: 2vh;
+}
+
+.search-results .mint-tab-container .mint-tab-container-item .text-item {
+ width: 90%;
+ margin-bottom: 2vh;
+}
+
+.search-results .mint-tab-container .mint-tab-container-item .text-item .item-title {
+ text-align: left;
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 500;
+ line-height: 4rem;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.search-results .mint-tab-container .mint-tab-container-item .text-item .item-context {
+ text-align: left;
+ font-size: 1.5rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 2.5rem;
+ color: #9B9B9B;
+ opacity: 1;
+}
+
+.search-results .mint-tab-container .mint-tab-container-item .image-item {
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: flex-start;
+
+ width: 90%;
+ margin-bottom: 2vh;
+}
+
+.search-results .mint-tab-container .mint-tab-container-item .image-item .item-left {
+ width: 30%;
+}
+
+.search-results .mint-tab-container .mint-tab-container-item .image-item .item-left img {
+ width: 100%;
+ height: 10vh;
+ border-radius: 10px;
+ object-fit: cover;
+}
+
+.search-results .mint-tab-container .mint-tab-container-item .image-item .item-right {
+ width: 70%;
+}
+
+.search-results .mint-tab-container .mint-tab-container-item .image-item .item-title {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+
+ padding-left: 4vw;
+ font-size: 2rem;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 4rem;
+ color: #BC0000;
+ text-align: left;
+
+}
+
+.search-results .mint-tab-container .mint-tab-container-item .image-item .item-context {
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ text-overflow: ellipsis;
+ overflow: hidden;
+
+ padding-left: 4vw;
+ font-size: 1.62rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 2rem;
+ color: #767676;
+ text-align: left;
+}
+</style>
diff --git a/src/views/spirit/detail.vue b/src/views/spirit/detail.vue
new file mode 100644
index 0000000..ca2c8d2
--- /dev/null
+++ b/src/views/spirit/detail.vue
@@ -0,0 +1,510 @@
+<template>
+ <div class="data-detail">
+ <div class="title">
+ <div class="title-left">
+ <div class="title-name" @click="ToListPage">{{ titleName }}</div>
+ <div class="title-introduce">{{ titleIntroduce }}</div>
+ </div>
+ <div class="title-right">
+ <div class="online-preview" @click="OnlinePreview(basisInfo.file)">在线浏览</div>
+ </div>
+ </div>
+ <div class="content">
+ <mt-navbar ref="navbar" v-model="navbarIndex">
+ <mt-tab-item id="1" data-type="1">基本信息</mt-tab-item>
+ <mt-tab-item id="2" data-type="2">相关图片</mt-tab-item>
+ <mt-tab-item id="3" data-type="3">相关视频</mt-tab-item>
+ </mt-navbar>
+ <mt-tab-container v-model="navbarIndex">
+ <mt-tab-container-item id="1">
+ <div class="content-keyword">
+ <div class="item-name">关键字</div>
+ {{ basisInfo.keyWord }}
+ </div>
+ <div class="content-introduction">
+ <div class="item-name">简介</div>
+ {{ basisInfo.introduction }}
+ </div>
+ </mt-tab-container-item>
+ <mt-tab-container-item id="2">
+ <CustomSearch3 v-on:search="SearchImages"></CustomSearch3>
+ <div class="content-images"
+ v-infinite-scroll="NextImages"
+ :infinite-scroll-disabled="images.scrollDisabled"
+ :infinite-scroll-distance="10">
+ <div class="content-item"
+ v-for="item in images.data"
+ :key="item.id"
+ @click="ToImageDetail(item.id)">
+ <div class="img-div">
+ <img :src="item.path"/>
+ </div>
+ <div class="item-name">{{ item.name }}</div>
+ </div>
+ </div>
+ </mt-tab-container-item>
+ <mt-tab-container-item id="3">
+ <CustomSearch3 v-on:search="SearchVideos"></CustomSearch3>
+ <div class="content-videos"
+ v-infinite-scroll="NextVideos"
+ :infinite-scroll-disabled="videos.scrollDisabled"
+ :infinite-scroll-distance="10">
+ <div class="content-item"
+ v-for="item in videos.data"
+ :key="item.id"
+ @click="ToVideoDetail(item.id)">
+ <div class="item-left">
+ <img :src="item.cover"/>
+ </div>
+ <div class="item-right">
+ <div class="item-name">{{ item.name }}</div>
+ <div class="item-introduce">{{ item.description }}</div>
+ </div>
+ </div>
+ </div>
+ </mt-tab-container-item>
+ </mt-tab-container>
+ </div>
+ </div>
+</template>
+
+<script>
+import CustomSearch3 from "@/components/CustomSearch3";
+import {
+ GetDataDetail as Api_GetDataDetail,
+ GetDataDetailImages as Api_GetDataDetailImages,
+ GetDataDetailVideos as Api_GetDataDetailVideos,
+} from "@/api/apilist";
+
+export default {
+ name: "detail",
+ components: {CustomSearch3},
+ data() {
+ return {
+ titleName: "",
+ titleIntroduce: "",
+ navbarIndex: "1",
+ basisInfo: {
+ id: "",
+ keyWord: "",
+ introduction: "",
+ file: "",
+ },
+ images: {
+ searchType: "title",
+ searchName: "",
+ pageSize: 10,
+ currentPage: 1,
+ total: 0,
+ data: [],
+ scrollDisabled: false,
+ },
+ videos: {
+ searchType: "title",
+ searchName: "",
+ pageSize: 10,
+ currentPage: 1,
+ total: 0,
+ data: [],
+ scrollDisabled: false,
+ },
+ }
+ },
+ methods: {
+ OnlinePreview: function (fileUrl) {
+ if (fileUrl) {
+ if (fileUrl.replace(/\\/g, '').toLowerCase().indexOf('.pdf') >= 0) {
+ window.open(fileUrl);
+ } else {
+ //https://view.officeapps.live.com/op/view.aspx?src=
+ window.open("http://www.xdocin.com/xdoc?_func=to&_format=html&_cache=1&_xdoc=" + fileUrl.replace(/\\/g, ''));
+ }
+ }
+ },
+ SearchBasisInfo: function (id) {
+ Api_GetDataDetail(id).then(res => {
+ this.basisInfo = res;
+ this.titleIntroduce = res.keyWord;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ SearchImages: function (searchType, searchName) {
+ this.images.searchType = searchType;
+ this.images.searchName = searchName;
+ Api_GetDataDetailImages(this.$route.query.id, searchType, searchName, 1, 10).then(res => {
+ this.images.currentPage = res.currentPage;
+ this.images.pageSize = res.pageSize;
+ this.images.total = res.total;
+ this.images.data = res.data;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ NextImages: function () {
+ let searchType = this.images.searchType;
+ let searchName = this.images.searchName;
+ let currentPage = this.images.currentPage + 1;
+ let pageSize = this.images.pageSize;
+ Api_GetDataDetailImages(this.$route.query.id, searchType, searchName, currentPage, pageSize).then(res => {
+ if (res.data.length > 0) {
+ this.images.total = res.total;
+ this.images.currentPage = res.currentPage;
+ this.images.data = this.images.data.concat(res.data);
+ }
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ SearchVideos: function (searchType, searchName) {
+ this.videos.searchType = searchType;
+ this.videos.searchName = searchName;
+ Api_GetDataDetailVideos(this.$route.query.id, searchType, searchName, 1, 10).then(res => {
+ this.videos.currentPage = res.currentPage;
+ this.videos.pageSize = res.pageSize;
+ this.videos.total = res.total;
+ this.videos.data = res.data;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ NextVideos: function () {
+ let searchType = this.videos.searchType;
+ let searchName = this.videos.searchName;
+ let currentPage = this.videos.currentPage + 1;
+ let pageSize = this.videos.pageSize;
+ Api_GetDataDetailVideos(this.$route.query.id, searchType, searchName, currentPage, pageSize).then(res => {
+ if (res.data.length > 0) {
+ this.videos.total = res.total;
+ this.videos.currentPage = res.currentPage;
+ this.videos.data = this.videos.data.concat(res.data);
+ }
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ },
+ ToImageDetail: function (id) {
+ let objId = this.$route.query.id;
+ this.$router.push({name: "spirit-detail-image", query: {id: id, objId: objId}});
+ },
+ ToVideoDetail: function (id) {
+ let objId = this.$route.query.id;
+ this.$router.push({name: "spirit-detail-video", query: {id: id, objId: objId}});
+ },
+ ToListPage: function () {
+ this.$router.push({name: "spirit-list"})
+ },
+ },
+ watch: {
+ navbarIndex: function () {
+ switch (this.navbarIndex) {
+ case 1:
+ this.images.scrollDisabled = true;
+ this.videos.scrollDisabled = true;
+ break;
+ case 2:
+ this.images.scrollDisabled = false;
+ this.videos.scrollDisabled = true;
+ break;
+ case 3:
+ this.images.scrollDisabled = true;
+ this.videos.scrollDisabled = false;
+ break;
+ }
+ }
+ },
+ created() {
+ let id = this.$route.query.id;
+ this.titleName = this.$route.query.name;
+ this.SearchBasisInfo(id);
+ this.SearchImages("title", "");
+ this.SearchVideos("title", "");
+ }
+}
+</script>
+
+<style scoped>
+.data-detail {
+ width: 100%;
+}
+
+.data-detail .title {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: space-between;
+ align-items: center;
+
+ width: 100%;
+ height: 15.9vh;
+ background: url("../../assets/datadetail/detail@1x.png") no-repeat 100% 100%;
+ background-size: cover;
+ border-radius: 10px 10px 0 0;
+}
+
+.data-detail .title .title-left {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: flex-start;
+
+ width: 60%;
+ height: 100%;
+ padding-left: 2vh;
+}
+
+.data-detail .title .title-name {
+ width: 100%;
+ text-align: left;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+
+ font-size: 2.62rem;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 5.24rem;
+ color: #FFFFFF;
+ opacity: 1;
+}
+
+.data-detail .title .title-introduce {
+ width: 100%;
+
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 3.37rem;
+ color: #FFFFFF;
+ opacity: 1;
+}
+
+.data-detail .title .title-right {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: flex-start;
+
+ width: 30%;
+ height: 100%;
+}
+
+.data-detail .title .online-preview {
+ width: 80%;
+ background: #EFC587;
+ opacity: 1;
+ border-radius: 60px;
+
+ font-size: 1.75rem;
+ font-family: Source Han Sans CN;
+ font-weight: bold;
+ line-height: 3.87vh;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.data-detail .content {
+ width: 90%;
+ height: 84.1vh;
+ margin-left: 5%;
+ border-radius: 30px;
+}
+
+.mint-navbar /deep/ .mint-tab-item-label {
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 500;
+ line-height: 2rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.mint-navbar /deep/ .is-selected {
+ color: #BC0000;
+ border-bottom: 0.3vh solid #BC0000;
+}
+
+.mint-navbar /deep/ .is-selected .mint-tab-item-label {
+ color: #BC0000;
+}
+
+.mint-tab-container /deep/ .mint-tab-container-item:nth-child(1) {
+ padding-top: 5vh;
+}
+
+.content-keyword {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.content-keyword .item-name {
+ text-align: left;
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: bold;
+ line-height: 6rem;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.content-introduction {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.content-introduction .item-name {
+ text-align: left;
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: bold;
+ line-height: 6rem;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.mint-tab-container /deep/ .mint-tab-container-item:nth-child(2) {
+ padding-top: 2vh;
+}
+
+.custom-search3 {
+ margin-bottom: 2vh;
+}
+
+.content-images {
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+ justify-content: flex-start;
+ align-items: flex-start;
+}
+
+.content-images .content-item {
+ width: 50%;
+ height: 25vh;
+}
+
+.content-images .content-item .img-div {
+ width: 90%;
+ height: 80%;
+ border-radius: 10px;
+ box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
+}
+
+.content-images .content-item .img-div img {
+ width: 100%;
+ height: 100%;
+ border-radius: 10px;
+ object-fit: cover;
+}
+
+.content-images .content-item .item-name {
+ width: 90%;
+
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+
+ font-size: 2em;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 2em;
+ color: #333333;
+ opacity: 1;
+}
+
+.mint-tab-container /deep/ .mint-tab-container-item:nth-child(3) {
+ padding-top: 2vh;
+}
+
+.content-videos {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+}
+
+.content-videos .content-item {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+ align-items: center;
+
+ height: 10vh;
+ margin: 2vh auto;
+}
+
+.content-videos .item-left {
+ width: 30%;
+ height: 100%;
+}
+
+.content-videos .item-left img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.content-videos .item-right {
+ width: 70%;
+ height: 100%;
+ padding-left: 2vw;
+}
+
+.content-videos .item-name {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ text-align: left;
+ font-size: 2rem;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 4rem;
+ color: #BC0000;
+ opacity: 1;
+}
+
+.content-videos .item-introduce {
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ text-align: left;
+ font-size: 1.62rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+</style>
diff --git a/src/views/spirit/detailImage.vue b/src/views/spirit/detailImage.vue
new file mode 100644
index 0000000..07a9a97
--- /dev/null
+++ b/src/views/spirit/detailImage.vue
@@ -0,0 +1,133 @@
+<template>
+ <div class="data-detail-image">
+ <div class="images">
+ <mt-swipe :show-indicators="false" :auto="0" :continuous="false" @change="ChangeImage">
+ <mt-swipe-item v-for="item in images.data" :key="item.key">
+ <img :src="item.path"/>
+ </mt-swipe-item>
+ </mt-swipe>
+ </div>
+ <div class="content">
+ <mt-navbar v-model="navIndex">
+ <mt-tab-item id="1">关键词</mt-tab-item>
+ <mt-tab-item id="2">简介</mt-tab-item>
+ </mt-navbar>
+ <mt-tab-container v-model="navIndex">
+ <mt-tab-container-item id="1">
+ {{ image.keyWord }}
+ </mt-tab-container-item>
+ <mt-tab-container-item id="2">
+ {{ image.introduction }}
+ </mt-tab-container-item>
+ </mt-tab-container>
+ </div>
+ </div>
+</template>
+
+<script>
+import {GetImageDetail as Api_GetImageDetail} from "@/api/apilist";
+
+export default {
+ name: "detailImage",
+ data() {
+ return {
+ navIndex: "1",
+ images: {
+ pageSize: 10,
+ currentPage: 1,
+ total: 0,
+ data: []
+ },
+ image: {
+ id: "",
+ name: "",
+ path: "",
+ keyWord: "",
+ introduction: "",
+ }
+ }
+ },
+ methods: {
+ ChangeImage: function (index) {
+ this.image = this.images.data[index];
+ },
+ },
+ created() {
+ let imageId = this.$route.query.id;
+ let objId = this.$route.query.objId;
+ Api_GetImageDetail(imageId, 1, objId, 999).then(res => {
+ this.images = res;
+ this.image = res.data[0];
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ }
+}
+</script>
+
+<style scoped>
+.data-detail-image {
+ width: 100%;
+}
+
+.images {
+ width: 100%;
+ height: 31.5vh;
+}
+
+.images img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.content {
+ width: 100%;
+ height: 66vh;
+ box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
+ opacity: 1;
+ border-radius: 10px;
+
+ padding-top: 1vh;
+}
+
+.content > div{
+ width: 90%;
+ margin-left: 5%;
+}
+
+.mint-navbar{
+ margin-bottom: 4vh;
+}
+
+.mint-navbar .mint-tab-item /deep/ .mint-tab-item-label {
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 500;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.mint-navbar .is-selected {
+ border-bottom: 0.3rem solid #BC0000;
+}
+
+.mint-navbar .is-selected /deep/ .mint-tab-item-label {
+ color: #BC0000;
+ font-weight: bold;
+}
+
+.mint-tab-container {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #585858;
+ opacity: 1;
+}
+</style>
diff --git a/src/views/spirit/detailvideo.vue b/src/views/spirit/detailvideo.vue
new file mode 100644
index 0000000..f755c4c
--- /dev/null
+++ b/src/views/spirit/detailvideo.vue
@@ -0,0 +1,121 @@
+<template>
+ <div class="data-detail-video">
+ <div class="videos">
+ <video poster="" :src="video.patch" controls="controls">
+ 您的浏览器不支持 video 标签。
+ </video>
+ </div>
+ <div class="content">
+ <mt-navbar v-model="navIndex">
+ <mt-tab-item id="1">关键词</mt-tab-item>
+ <mt-tab-item id="2">简介</mt-tab-item>
+ </mt-navbar>
+ <mt-tab-container v-model="navIndex">
+ <mt-tab-container-item id="1">
+ {{ video.keyWord }}
+ </mt-tab-container-item>
+ <mt-tab-container-item id="2">
+ {{ video.introduction }}
+ </mt-tab-container-item>
+ </mt-tab-container>
+ </div>
+ </div>
+</template>
+
+<script>
+import {GetVideoDetail as Api_GetVideoDetail} from "@/api/apilist";
+
+export default {
+ name: "detailVideo",
+ data() {
+ return {
+ navIndex: "1",
+ video: {
+ id: "",
+ name: "",
+ path: "",
+ keyWord: "",
+ introduction: "",
+ },
+ }
+ },
+ methods: {
+
+ },
+ created() {
+ let id = this.$route.query.id;
+ Api_GetVideoDetail(id).then(res => {
+ this.video = res;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert('错误的请求!');
+ });
+ }
+}
+</script>
+
+<style scoped>
+.data-detail-video {
+ width: 100%;
+}
+
+.videos {
+ width: 100%;
+ height: 31.5vh;
+}
+
+.videos video {
+ width: 100%;
+ height: 100%;
+ background: black;
+}
+
+.content {
+ width: 100%;
+ height: 66vh;
+ box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
+ opacity: 1;
+ border-radius: 10px;
+
+ padding-top: 1vh;
+}
+
+.content > div{
+ width: 90%;
+ margin-left: 5%;
+}
+
+.mint-navbar{
+ margin-bottom: 4vh;
+}
+
+.mint-navbar .mint-tab-item /deep/ .mint-tab-item-label {
+ font-size: 2rem;
+ font-family: Source Han Sans CN;
+ font-weight: 500;
+ line-height: 3rem;
+ color: #767676;
+ opacity: 1;
+}
+
+.mint-navbar .is-selected {
+ border-bottom: 0.3rem solid #BC0000;
+}
+
+.mint-navbar .is-selected /deep/ .mint-tab-item-label {
+ color: #BC0000;
+ font-weight: bold;
+}
+
+.mint-tab-container {
+ text-align: left;
+ font-size: 1.87rem;
+ font-family: Source Han Serif CN;
+ font-weight: 400;
+ line-height: 3rem;
+ color: #585858;
+ opacity: 1;
+}
+</style>
diff --git a/src/views/spirit/list.vue b/src/views/spirit/list.vue
new file mode 100644
index 0000000..06e36f1
--- /dev/null
+++ b/src/views/spirit/list.vue
@@ -0,0 +1,153 @@
+<template>
+ <div class="list-root">
+ <div class="search">
+ <CustomSearch3 v-on:search="Search"></CustomSearch3>
+ </div>
+ <div class="line"></div>
+ <div class="data-list"
+ v-infinite-scroll="loadBottom"
+ :infinite-scroll-disabled="allLoaded"
+ :infinite-scroll-distance="10">
+ <template v-for="item in data.data">
+ <div class="text-item" :key="item.key" @click="ToDetail(item.id, item.name)">
+ <div class="item-title">{{ item.name }}</div>
+ <div class="item-context">{{ item.keyWord }}</div>
+ </div>
+ <div class="line" :key="item.key"></div>
+ </template>
+ </div>
+ </div>
+</template>
+
+<script>
+import CustomSearch3 from "@/components/CustomSearch3";
+import {GetDataList as Api_GetDataList} from "@/api/apilist";
+
+export default {
+ name: "list",
+ components: {CustomSearch3},
+ data() {
+ return {
+ dataType: 2,
+ searchType: "title",
+ searchName: "",
+ data: {
+ currentPage: 1,
+ pageSize: 5,
+ total: 0,
+ data: []
+ },
+ allLoaded: false
+ };
+ },
+ methods: {
+ Search: function (searchType, searchName) {
+ this.searchType = searchType;
+ this.searchName = searchName;
+ Api_GetDataList(this.dataType, searchType, searchName, 1, this.data.pageSize).then(res => {
+ this.currentPage = res.currentPage;
+ this.pageSize = res.pageSize;
+ this.total = res.total;
+ this.data = res;
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert("错误的请求!");
+ });
+ },
+ loadBottom: function () {
+ Api_GetDataList(this.dataType, this.searchType, this.searchName, this.data.currentPage + 1, this.data.pageSize).then(res => {
+ this.data.currentPage = res.currentPage;
+ this.data.pageSize = res.pageSize;
+ this.data.total = res.total;
+ if (res.data.length > 0) {
+ this.data.data = this.data.data.concat(res.data);
+ }else{
+ this.allLoaded = true;
+ }
+ }, rej => {
+ alert(rej);
+ }).catch(err => {
+ console.log(err);
+ alert("错误的请求!");
+ });
+ },
+ ToDetail: function (id, name) {
+ this.$router.push({name: "spirit-detail", query: {id: id, name: name}})
+ }
+ },
+ created() {
+ this.Search("title", "");
+ }
+}
+</script>
+
+<style scoped>
+li {
+ list-style-type: none;
+}
+
+.list-root {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ align-items: center;
+ width: 100%;
+}
+
+.search {
+ width: 100%;
+ margin-top: 3vh;
+}
+
+.search .custom-search3 {
+ width: 90%;
+ margin-left: 5%;
+}
+
+.line {
+ width: 100%;
+ border: 1px solid #EEEEEE;
+ margin-top: 3vh;
+ margin-bottom: 3vh;
+ opacity: 1;
+}
+
+.data-list {
+ width: 90%;
+ height: 65vh;
+ margin-left: 5%;
+ overflow: scroll;
+}
+
+.data-list .line {
+ width: 100%;
+ margin-bottom: 2vh;
+}
+
+
+data-list /deep/ .text-item {
+ width: 90%;
+ margin-bottom: 2vh;
+}
+
+data-list /deep/ .text-item .item-title {
+ text-align: left;
+ font-size: 2rem;
+ font-family: Source Han Serif CN;
+ font-weight: bold;
+ line-height: 4rem;
+ color: #BC0000;
+}
+
+data-list /deep/ .text-item .item-context {
+ text-align: left;
+ font-size: 1.62rem;
+ font-family: Source Han Sans CN;
+ font-weight: 400;
+ line-height: 2rem;
+ color: #767676;
+ text-align: left;
+}
+</style>
diff --git a/vue.config.js b/vue.config.js
new file mode 100644
index 0000000..56d969d
--- /dev/null
+++ b/vue.config.js
@@ -0,0 +1,14 @@
+module.exports = {
+ publicPath:'./',
+ devServer: {
+ proxy: {
+ '/api': {
+ target: 'http://hsly.xingyao100.com/',
+ changeOrigin: true,
+ pathRewrite: {
+ '^/api': '/'
+ }
+ }
+ }
+ },
+}
--
Gitblit v1.9.3