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