Преглед на файлове

Merge branch 'master' of http://face3d.4dage.com:7005/shaogen1995/YFYC-H5

任一存 преди 2 години
родител
ревизия
cb54bb860f
променени са 78 файла, в които са добавени 35650 реда и са изтрити 3322 реда
  1. 5 0
      houtai/.editorconfig
  2. 23 0
      houtai/.gitignore
  3. 24 0
      houtai/README.md
  4. 5 0
      houtai/babel.config.js
  5. 30013 0
      houtai/package-lock.json
  6. 71 0
      houtai/package.json
  7. BIN
      houtai/public/favicon.ico
  8. 17 0
      houtai/public/index.html
  9. 9 0
      houtai/src/App.vue
  10. 26 0
      houtai/src/apis/login.js
  11. 62 0
      houtai/src/apis/tab2.js
  12. 164 0
      houtai/src/assets/css/base.css
  13. BIN
      houtai/src/assets/img/IMGerror.png
  14. BIN
      houtai/src/assets/img/bg.png
  15. BIN
      houtai/src/assets/imgAdd/comment.png
  16. BIN
      houtai/src/assets/imgAdd/like.png
  17. BIN
      houtai/src/assets/imgAdd/likeAc.png
  18. BIN
      houtai/src/assets/imgAdd/mesBac.png
  19. BIN
      houtai/src/assets/imgAdd/touxiang.png
  20. 24 0
      houtai/src/main.js
  21. 68 0
      houtai/src/router/index.js
  22. 106 0
      houtai/src/utils/pass.js
  23. 37 0
      houtai/src/utils/request.js
  24. 345 0
      houtai/src/views/layout/index.vue
  25. 154 0
      houtai/src/views/login.vue
  26. 646 0
      houtai/src/views/tab2/add.vue
  27. 292 0
      houtai/src/views/tab2/index.vue
  28. 160 0
      houtai/src/views/tab3/index.vue
  29. 3 0
      houtai/vue.config.js
  30. 8 8
      yfyc/public/masonry.pkgd.min.js
  31. 7 0
      yfyc/src/api/interact.js
  32. BIN
      yfyc/src/assets/img/home/1.jpg
  33. BIN
      yfyc/src/assets/img/home/1.png
  34. BIN
      yfyc/src/assets/img/home/10.jpg
  35. BIN
      yfyc/src/assets/img/home/11.jpg
  36. BIN
      yfyc/src/assets/img/home/12.jpg
  37. BIN
      yfyc/src/assets/img/home/13.jpg
  38. BIN
      yfyc/src/assets/img/home/14.jpg
  39. BIN
      yfyc/src/assets/img/home/15.jpg
  40. BIN
      yfyc/src/assets/img/home/2.jpg
  41. BIN
      yfyc/src/assets/img/home/2.png
  42. BIN
      yfyc/src/assets/img/home/3.jpg
  43. BIN
      yfyc/src/assets/img/home/3.png
  44. BIN
      yfyc/src/assets/img/home/4.jpg
  45. BIN
      yfyc/src/assets/img/home/4.png
  46. BIN
      yfyc/src/assets/img/home/5.jpg
  47. BIN
      yfyc/src/assets/img/home/5.png
  48. BIN
      yfyc/src/assets/img/home/6.jpg
  49. BIN
      yfyc/src/assets/img/home/6.png
  50. BIN
      yfyc/src/assets/img/home/7.jpg
  51. BIN
      yfyc/src/assets/img/home/8.jpg
  52. BIN
      yfyc/src/assets/img/home/9.jpg
  53. 3 3
      yfyc/src/assets/libs/ua-parser.min.js
  54. 59 59
      yfyc/src/assets/my-reset.css
  55. 107 107
      yfyc/src/components/BackTop.vue
  56. 105 105
      yfyc/src/components/BookingSuccess.vue
  57. 63 63
      yfyc/src/components/SearchRedBtn.vue
  58. 69 69
      yfyc/src/components/SearchTransparent.vue
  59. 125 125
      yfyc/src/components/Select.vue
  60. 75 75
      yfyc/src/components/TabbarSmall.vue
  61. 27 27
      yfyc/src/directives/v-click-outside.js
  62. 15 14
      yfyc/src/router/index.js
  63. 84 84
      yfyc/src/utils/index.js
  64. 37 0
      yfyc/src/utils/request.js
  65. 17 6
      yfyc/src/views/Construct/components/HomeList.vue
  66. 26 5
      yfyc/src/views/Construct/index.vue
  67. 23 26
      yfyc/src/views/Interact/index.vue
  68. 129 129
      yfyc/src/views/My/Feedback.vue
  69. 207 207
      yfyc/src/views/My/MyBookings.vue
  70. 194 194
      yfyc/src/views/Serve/DontMiss.vue
  71. 312 312
      yfyc/src/views/Serve/FoodDetail.vue
  72. 217 217
      yfyc/src/views/Serve/FoodList.vue
  73. 165 165
      yfyc/src/views/Serve/HelpCenter.vue
  74. 400 400
      yfyc/src/views/Serve/HotelDetail.vue
  75. 276 276
      yfyc/src/views/Serve/HotelList.vue
  76. 173 173
      yfyc/src/views/Serve/RecommendedPath.vue
  77. 172 172
      yfyc/src/views/Serve/RecommendedPathDetail.vue
  78. 301 301
      yfyc/src/views/Serve/TravelPlague.vue

+ 5 - 0
houtai/.editorconfig

@@ -0,0 +1,5 @@
+[*.{js,jsx,ts,tsx,vue}]
+indent_style = space
+indent_size = 2
+trim_trailing_whitespace = true
+insert_final_newline = true

+ 23 - 0
houtai/.gitignore

@@ -0,0 +1,23 @@
+.DS_Store
+node_modules
+/dist
+edit-backstage
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 24 - 0
houtai/README.md

@@ -0,0 +1,24 @@
+# houtai
+
+## Project setup
+```
+npm install
+```
+
+### Compiles and hot-reloads for development
+```
+npm run serve
+```
+
+### Compiles and minifies for production
+```
+npm run build
+```
+
+### Lints and fixes files
+```
+npm run lint
+```
+
+### Customize configuration
+See [Configuration Reference](https://cli.vuejs.org/config/).

+ 5 - 0
houtai/babel.config.js

@@ -0,0 +1,5 @@
+module.exports = {
+  presets: [
+    '@vue/cli-plugin-babel/preset'
+  ]
+}

Файловите разлики са ограничени, защото са твърде много
+ 30013 - 0
houtai/package-lock.json


+ 71 - 0
houtai/package.json

@@ -0,0 +1,71 @@
+{
+  "name": "houtai",
+  "version": "0.1.0",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "lint": "vue-cli-service lint"
+  },
+  "dependencies": {
+    "axios": "^0.24.0",
+    "Base64": "^1.1.0",
+    "core-js": "^3.6.5",
+    "dayjs": "^1.11.5",
+    "echarts": "^5.4.0",
+    "element-ui": "^2.15.6",
+    "js-base64": "^3.7.2",
+    "moment": "^2.29.1",
+    "vant": "^2.12.45",
+    "vue": "^2.6.11",
+    "vue-json-excel": "^0.3.0",
+    "vue-router": "^3.2.0",
+    "wangeditor": "^4.7.11"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "~4.5.0",
+    "@vue/cli-plugin-eslint": "~4.5.0",
+    "@vue/cli-plugin-router": "~4.5.0",
+    "@vue/cli-service": "~4.5.0",
+    "@vue/eslint-config-standard": "^5.1.2",
+    "babel-eslint": "^10.1.0",
+    "eslint": "^6.7.2",
+    "eslint-plugin-import": "^2.20.2",
+    "eslint-plugin-node": "^11.1.0",
+    "eslint-plugin-promise": "^4.2.1",
+    "eslint-plugin-standard": "^4.0.0",
+    "eslint-plugin-vue": "^6.2.2",
+    "less": "^3.0.4",
+    "less-loader": "^5.0.0",
+    "lint-staged": "^9.5.0",
+    "vue-template-compiler": "^2.6.11"
+  },
+  "eslintConfig": {
+    "root": true,
+    "env": {
+      "node": true
+    },
+    "extends": [
+      "plugin:vue/essential",
+      "@vue/standard"
+    ],
+    "parserOptions": {
+      "parser": "babel-eslint"
+    },
+    "rules": {}
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not dead"
+  ],
+  "gitHooks": {
+    "pre-commit": "lint-staged"
+  },
+  "lint-staged": {
+    "*.{js,jsx,vue}": [
+      "vue-cli-service lint",
+      "git add"
+    ]
+  }
+}

BIN
houtai/public/favicon.ico


+ 17 - 0
houtai/public/index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <title>河南博物院-文物展示平台后台</title>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+    </noscript>
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>

+ 9 - 0
houtai/src/App.vue

@@ -0,0 +1,9 @@
+<template>
+  <div id="app">
+    <Router-view/>
+  </div>
+</template>
+
+<style lang="less">
+
+</style>

+ 26 - 0
houtai/src/apis/login.js

@@ -0,0 +1,26 @@
+import axios from '../utils/request'
+// 用户登录接口
+export const userLogin = (data) => {
+  return axios({
+    method: 'post',
+    url: '/api/admin/login',
+    data
+  })
+}
+// 修改密码
+export const updatePwd = (data) => {
+  return axios({
+    method: 'post',
+    url: '/api/sys/user/updatePwd',
+    data
+  })
+}
+
+// 获取场景管理列表
+export const sceneList = (data) => {
+  return axios({
+    method: 'post',
+    url: '/api/cms/scene/list',
+    data
+  })
+}

+ 62 - 0
houtai/src/apis/tab2.js

@@ -0,0 +1,62 @@
+import axios from '../utils/request'
+// 获取列表
+export const goodsList = (data) => {
+  return axios({
+    method: 'post',
+    url: '/api/cms/goods/list',
+    data
+  })
+}
+// 点击删除
+export const goodsRemove = (id) => {
+  return axios({
+    url: `/api/cms/goods/remove/${id}`
+  })
+}
+// 新增、编辑
+export const goodsSave = (data) => {
+  return axios({
+    method: 'post',
+    url: '/api/cms/goods/save',
+    data
+  })
+}
+// 是否显示
+export const goodsDisplay = (id, display) => {
+  return axios({
+    url: `/api/cms/goods/display/${id}/${display}`
+  })
+}
+
+// 通过id获取详情
+export const goodsDetail = (id) => {
+  return axios({
+    url: `/api/cms/goods/detail/${id}`
+  })
+}
+
+// ------------------------------操作日志列表
+export const logList = (data) => {
+  return axios({
+    method: 'post',
+    url: '/api/sys/log/list',
+    data
+  })
+}
+
+// ------------------------------操作日志列表
+export const dictGetTree = (data) => {
+  return axios({
+    method: 'post',
+    url: '/api/cms/dict/getTree',
+    data
+  })
+}
+
+// ------------------------------统计
+export const goodsReport = (data) => {
+  return axios({
+    url: '/api/cms/goods/report',
+    data
+  })
+}

+ 164 - 0
houtai/src/assets/css/base.css

@@ -0,0 +1,164 @@
+* {
+  margin: 0;
+  padding: 0;
+  box-sizing: border-box;
+}
+body {
+  background-color: transparent;
+}
+ul li {
+  list-style: none;
+}
+a {
+  text-decoration:none ;
+  color: #b9412e;
+}
+.insideTop {
+  position: relative;
+  padding-left: 30px;
+  font-weight: 700;
+  height: 40px;
+  margin-bottom: 12px;
+}
+.insideTop .add{
+  position: absolute;
+  top: -10px;
+  right: 30px;
+}
+.obstruct{
+  position: absolute;
+  left: 0px;
+  top: 60px;
+  width: 100%;
+  background-color: #f2ecde;
+  height: 12px;
+}
+.biaoshi{
+  position: relative;
+  font-style:normal
+}
+.biaoshi::before{
+  position: absolute;
+  top: 0px;
+  left: -92px;
+  content: '*';
+  color: #F56C6C;
+}
+
+
+.cell{
+  text-align: center !important;
+}
+.table .el-input__inner{
+  text-align: center;
+}
+.el-input__inner{
+  padding-right: 45px;
+}
+input::-webkit-outer-spin-button,
+input::-webkit-inner-spin-button {
+-webkit-appearance: none;
+}
+input[type="number"] {
+-moz-appearance: textfield;
+}
+.el-dialog{
+  min-width: 652px;
+}
+.el-upload__tip{
+  font-size: 14px;
+}
+
+.el-table--fit{
+  border-top: 1px solid #EBEEF5;
+}
+.table_img{
+  width: 100px;
+  height: 80px;
+  object-fit: cover;
+  border: 1px solid #ccc;
+}
+.table_name{
+  cursor: pointer;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;    
+}
+
+.upHint{
+  font-size: 12px;
+  color: #ccc;
+  height: 20px;
+  margin-top: -5px;
+}
+.el-radio__input.is-checked+.el-radio__label{
+  color: #964134;
+}
+.el-radio__input.is-checked .el-radio__inner{
+  border-color: #964134;
+  background: #964134;
+}
+.el-image__preview{
+  border: 5px solid #cccccc;
+  object-fit: cover;
+}
+.el-upload--picture-card:hover, .el-upload:focus{
+  color: #b9412e;
+}
+.w-e-menu {
+	z-index: 2 !important;
+}
+.w-e-text-container {
+	z-index: 1 !important;
+}
+.w-e-toolbar {
+	z-index: 10 !important;
+}
+.w-e-toolbar .w-e-menu:nth-of-type(18) {
+	display: none !important;
+}
+.w-e-toolbar .w-e-menu:nth-of-type(19) {
+	display: none !important;
+}
+.w-e-toolbar .w-e-menu:nth-of-type(13) {
+	display: none !important;
+}
+.w-e-toolbar .w-e-menu:nth-of-type(14) {
+	display: none !important;
+}
+.w-e-toolbar .w-e-menu:nth-of-type(16) {
+	display: none !important;
+}
+.w-e-toolbar .w-e-menu:nth-of-type(20) {
+	display: none !important;
+}
+.w-e-toolbar .w-e-menu:nth-of-type(21) {
+	display: none !important;
+}
+.w-e-toolbar .w-e-menu:nth-of-type(26) {
+	display: none !important;
+}
+.avatar-uploader .el-upload-list__item-name{
+  display: none;
+}
+.avatar-uploader .el-upload-list__item.is-success .el-upload-list__item-status-label{
+  display: none;
+}
+.el-upload-list__item .el-progress{
+  width: 500px;
+  position: static;
+  margin-bottom: 15px;
+}
+.el-upload-list__item{
+  width: 500px;
+}
+.el-month-table td.end-date .cell, .el-month-table td.start-date .cell{
+  background-color: #b9412e;
+}
+
+.el-month-table td.today .cell{
+  color: #b9412e;
+}
+.el-message-box__title{
+  color: #b9412e;
+}

BIN
houtai/src/assets/img/IMGerror.png


BIN
houtai/src/assets/img/bg.png


BIN
houtai/src/assets/imgAdd/comment.png


BIN
houtai/src/assets/imgAdd/like.png


BIN
houtai/src/assets/imgAdd/likeAc.png


BIN
houtai/src/assets/imgAdd/mesBac.png


BIN
houtai/src/assets/imgAdd/touxiang.png


+ 24 - 0
houtai/src/main.js

@@ -0,0 +1,24 @@
+import Vue from 'vue'
+import ElementUI from 'element-ui'
+import 'element-ui/lib/theme-chalk/index.css'
+import App from './App.vue'
+import router from './router'
+// 表格导出
+import JsonExcel from 'vue-json-excel'
+import './assets/css/base.css'
+Vue.component('downloadExcel', JsonExcel)
+
+Vue.config.productionTip = false
+const imgErr = {
+  data () {
+    return {
+      defaultImg: 'this.src="' + require('./assets/img/IMGerror.png') + '"'
+    }
+  }
+}
+Vue.mixin(imgErr)
+Vue.use(ElementUI)
+new Vue({
+  router,
+  render: h => h(App)
+}).$mount('#app')

+ 68 - 0
houtai/src/router/index.js

@@ -0,0 +1,68 @@
+import Vue from 'vue'
+import VueRouter from 'vue-router'
+import {
+  Message
+} from 'element-ui'
+Vue.use(VueRouter)
+
+const routes = [{
+  path: '/',
+  name: 'login',
+  component: () => import('../views/login.vue')
+},
+{
+  path: '/layout',
+  name: 'layout',
+  component: () => import('../views/layout/index.vue'),
+  children: [{
+    path: 'tab2',
+    name: 'tab2',
+    meta: {
+      myInd: 2
+    },
+    component: () => import('../views/tab2/index.vue')
+  },
+  {
+    path: 'tab2Add',
+    name: 'tab2Add',
+    meta: {
+      myInd: 2
+    },
+    component: () => import('../views/tab2/add.vue')
+  },
+  {
+    path: 'tab3',
+    name: 'tab3',
+    meta: {
+      myInd: 3
+    },
+    component: () => import('../views/tab3/index.vue')
+  }
+
+  ]
+}
+]
+
+const router = new VueRouter({
+  // mode: 'history',
+  base: process.env.BASE_URL,
+  routes
+})
+
+router.beforeEach((to, from, next) => {
+  // 如果是去登录页,不需要验证,直接下一步
+  if (to.name === 'login') next()
+  // 否则要有token值才能下一步,不然就返回登录页
+  else {
+    const token = localStorage.getItem('HNBWY_token')
+    if (token) next()
+    else {
+      Message.warning('登录失效,请重新登录')
+      next({
+        name: 'login'
+      })
+    }
+  }
+})
+
+export default router

+ 106 - 0
houtai/src/utils/pass.js

@@ -0,0 +1,106 @@
+/* eslint-disable */
+function NoToChinese (num) {
+  num = String(num)
+  var chnNumChar = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
+  if (num == 0) {
+    return chnNumChar[0]
+  }
+  let tmp = ''
+  for (let i = 0; i < num.length; i++) {
+    const ele = num.charAt(i)
+    tmp += chnNumChar[ele]
+  }
+
+  return tmp
+}
+
+function randomWord (randomFlag, min, max) {
+  let str = ''
+  let range = min
+  const arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
+  // 随机产生
+  if (randomFlag) {
+    range = Math.round(Math.random() * (max - min)) + min
+  }
+  for (var i = 0; i < range; i++) {
+    const pos = Math.round(Math.random() * (arr.length - 1))
+    str += arr[pos]
+  }
+  return str
+}
+
+module.exports = {
+  formatDate: function (time) {
+    var weekArr = ['日', '一', '二', '三', '四', '五', '六']
+    var date = new Date(time)
+    var year = date.getFullYear()
+    var month = date.getMonth() + 1
+    var day = date.getDate()
+    var week = '星期' + weekArr[date.getDay()]
+    if (window.innerWidth < 1700) {
+      return (
+        year +
+        '年' +
+        (String(month).length > 1 ? month : '0' + month) +
+        '月' +
+        (String(day).length > 1 ? day : '0' + day) +
+        '日' +
+        '<br/>' +
+        week
+      )
+    }
+    return (
+      year +
+      '年' +
+      (String(month).length > 1 ? month : '0' + month) +
+      '月' +
+      (String(day).length > 1 ? day : '0' + day) +
+      '日' +
+      ' ' +
+      week
+    )
+  },
+  smoothscrollpos: function (domName) {
+    if (domName == '/') {
+      return window.scrollTo(0, 0)
+    }
+    const smoothscroll = () => {
+      const dom = document.getElementById(domName)
+      // window.scrollTo({
+      //   top:dom.offsetTop - 100,
+      //   left:0,
+      //   behavior: "smooth"
+      // })
+      dom && window.scrollTo(0, dom.offsetTop - 120)
+    }
+    smoothscroll()
+  },
+
+  formatTime: function (time, fan = false) {
+    let t1 = time.split(' ')[0].split('-')
+    if (fan) {
+      t1 = t1.map((item) => {
+        const t = NoToChinese(item)
+        return t
+      })
+    }
+    return t1
+  },
+  encodeStr: function (str, strv = '') {
+    const NUM = 2
+    const front = randomWord(false, 8)
+    const middle = randomWord(false, 8)
+    const end = randomWord(false, 8)
+
+    const str1 = str.substring(0, NUM)
+    const str2 = str.substring(NUM)
+
+    if (strv) {
+      const strv1 = strv.substring(0, NUM)
+      const strv2 = strv.substring(NUM)
+      return [front + str2 + middle + str1 + end, front + strv2 + middle + strv1 + end]
+    }
+
+    return front + str2 + middle + str1 + end
+  }
+}

+ 37 - 0
houtai/src/utils/request.js

@@ -0,0 +1,37 @@
+import axios from 'axios'
+const service = axios.create({
+  // baseURL: 'http://192.168.20.55:8032', // 本地调试
+  baseURL: process.env.NODE_ENV === 'development' ? 'https://hnbwg.4dage.com' : '',
+  timeout: 5000
+})
+// 请求拦截器
+service.interceptors.request.use(function (config) {
+  // console.log('触发拦截器')
+  // 在发送请求之前做些什么:看看有没有token,如果有通过请求头的方式传递token
+  const token = localStorage.getItem('HNBWY_token')
+  if (token) { // 判断是否有token,有,则
+    // config.headers['Authorization'] = token
+    config.headers.token = token
+  }
+
+  return config
+}, function (error) {
+  // 对请求错误做些什么
+  return Promise.reject(error)
+})
+
+// 添加响应拦截器
+service.interceptors.response.use(function (response) {
+  // console.log('触发相应拦截器', response)
+  // 对响应数据做点什么--response就是发送每个请求的返回值
+  if (response.data.code === 5001 || response.data.code === 5002) {
+    // Toast.fail('未登录,请先登录')
+    localStorage.removeItem('HNBWY_token')
+  }
+  return response.data
+}, function (error) {
+  // 对响应错误做点什么
+  return Promise.reject(error)
+})
+
+export default service

+ 345 - 0
houtai/src/views/layout/index.vue

@@ -0,0 +1,345 @@
+<template>
+  <div class="layout">
+    <div class="top">
+      <p>芜湖一房一册管理后台</p>
+      <div class="top_right" @mouseenter="cut = true" @mouseleave="cut = false">
+        <div class="user">
+          <span>{{ userName }}</span>
+          <!-- 下箭头 -->
+          <div class="pull_down" v-if="cut"></div>
+          <div class="pull_up" v-else></div>
+        </div>
+        <!-- 点击箭头出来的ul -->
+        <ul class="user_handle" v-show="cut">
+          <li @click="isShow = true">修改密码</li>
+          <li @click="outLogin">退出登录</li>
+        </ul>
+      </div>
+    </div>
+    <div class="con">
+      <div class="left">
+        <div
+          class="biaoji el-icon-message"
+          :class="{ biaojiAc: $route.meta.myInd === 2 }"
+        >
+          内容管理
+        </div>
+        <ul>
+          <li
+            v-for="item in tab1"
+            :key="item.id"
+            :class="{ active: $route.meta.myInd === item.id }"
+            @click="push(item.url)"
+          >
+            {{ item.name }}
+          </li>
+        </ul>
+
+        <div
+          class="biaoji el-icon-setting"
+          :class="{ biaojiAc: $route.meta.myInd === 3 }"
+        >
+          系统管理
+        </div>
+        <ul>
+          <li
+            v-for="item in tab2"
+            :key="item.id"
+            :class="{ active: $route.meta.myInd === item.id }"
+            @click="push(item.url)"
+          >
+            {{ item.name }}
+          </li>
+        </ul>
+      </div>
+      <!-- 右侧内容 -->
+      <div class="right" @click="cut = false">
+        <Router-view />
+      </div>
+    </div>
+    <!-- 点击修改密码出现弹窗 -->
+    <el-dialog title="修改密码" :visible.sync="isShow" @close="btnX()">
+      <el-form :model="form" label-width="100px" :rules="rules" ref="ruleForm">
+        <el-form-item label="旧密码:" prop="oldPassword">
+          <el-input
+            v-model="form.oldPassword"
+            placeholder="请输入"
+            show-password
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="新密码:" prop="newPassword">
+          <el-input
+            v-model="form.newPassword"
+            placeholder="请输入"
+            show-password
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="确定新密码:" prop="checkPass">
+          <el-input
+            v-model="form.checkPass"
+            placeholder="请输入"
+            show-password
+          ></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="btnX">取 消</el-button>
+        <el-button type="primary" @click="btnOk">确 定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { encodeStr } from '../../utils/pass'
+import { Base64 } from 'js-base64'
+import { updatePwd } from '@/apis/login'
+export default {
+  name: 'layout',
+  components: {},
+  data () {
+    // 这里存放数据
+    const validatePass2 = (rule, value, callback) => {
+      if (value !== this.form.newPassword) {
+        callback(new Error('两次输入密码不一致!'))
+      } else {
+        callback()
+      }
+    }
+    return {
+      // 修改密码
+      form: {
+        oldPassword: '',
+        newPassword: '',
+        checkPass: ''
+      },
+      rules: {
+        checkPass: [{ validator: validatePass2, trigger: 'blur' }],
+        oldPassword: [{ required: true, message: '不能为空', trigger: 'blur' }],
+        newPassword: [
+          { required: true, message: '不能为空', trigger: 'blur' },
+          { max: 15, message: '不能超过15个字', trigger: 'blur' }
+        ]
+      },
+      userName: '',
+      cut: false,
+      isShow: false,
+      tab1: [{ name: '建筑可对话-发布', id: 2, url: '/layout/tab2' }],
+      tab2: [{ name: '操作日志', id: 3, url: '/layout/tab3' }]
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    // 修改密码点击取消
+    btnX () {
+      this.$refs.ruleForm.resetFields()
+      this.cut = false
+      this.isShow = false
+      this.form = {
+        oldPassword: '',
+        newPassword: '',
+        checkPass: ''
+      }
+    },
+    // 修改密码点击确定
+    async btnOk () {
+      await this.$refs.ruleForm.validate()
+      try {
+        const data = {
+          oldPassword: encodeStr(Base64.encode(this.form.oldPassword)),
+          newPassword: encodeStr(Base64.encode(this.form.newPassword))
+        }
+        const res = await updatePwd(data)
+        if (res.code === 0) {
+          this.$message.success('修改成功')
+          localStorage.clear('HNBWY_token')
+          localStorage.clear('HNBWY_userInfo')
+          this.$router.push('/')
+        } else this.$message.error(res.msg)
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    push (url) {
+      this.$router.push(url).catch(() => {})
+    },
+    // 点击退出登录
+    outLogin () {
+      this.cut = false
+      this.$confirm('确定退出吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(() => {
+          localStorage.clear('HNBWY_token')
+          localStorage.clear('HNBWY_userName')
+          this.$router.push('/')
+          this.$message.success('退出成功!')
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    // 获取用户名
+    const res = localStorage.getItem('HNBWY_userName')
+    this.userName = res
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.layout {
+  .top {
+    padding-left: 50px;
+    position: relative;
+    width: 100%;
+    min-width: 1860px;
+    box-shadow: 1px 3px 3px 3px rgb(196, 177, 177);
+    height: 70px;
+    background-color: #3a80d2;
+    display: flex;
+    align-items: center;
+    & > P {
+      color: #fff;
+      font-size: 24px;
+      font-weight: 700;
+    }
+    .top_right {
+      width: 150px;
+      position: absolute;
+      right: 30px;
+      top: 0;
+      height: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      .user {
+        color: #fff;
+        cursor: pointer;
+        position: relative;
+        display: flex;
+        align-items: center;
+        font-weight: 700;
+        img {
+          margin-right: 15px;
+          width: 34px;
+          height: 34px;
+          border-radius: 50%;
+          overflow: hidden;
+        }
+        .pull_down {
+          position: absolute;
+          right: -25px;
+          bottom: 4px;
+          display: inline-block;
+          width: 0;
+          height: 0;
+          border-left: 8px solid transparent;
+          border-right: 8px solid transparent;
+          border-bottom: 8px solid #fff;
+        }
+        .pull_up {
+          cursor: pointer;
+          position: absolute;
+          right: -25px;
+          bottom: 4px;
+          display: inline-block;
+          width: 0;
+          height: 0;
+          border-left: 8px solid transparent;
+          border-right: 8px solid transparent;
+          border-top: 8px solid #fff;
+        }
+      }
+      .user_handle {
+        z-index: 999;
+        padding: 10px 40px;
+        position: absolute;
+        right: 0;
+        bottom: -90px;
+        background-color: #3a80d2;
+        li {
+          color: #fff;
+          cursor: pointer;
+          margin: 10px 0;
+        }
+        li:hover {
+          color: orange;
+        }
+      }
+    }
+  }
+  .con {
+    min-width: 1860px;
+    min-height: 807px;
+    background-color: #f2ecde;
+    display: flex;
+    width: 100%;
+    padding: 30px;
+    height: calc(100vh - 70px);
+  }
+  .left {
+    min-width: 180px;
+    width: 180px;
+    height: 100%;
+    min-height: 770px;
+    background-color: #fff;
+    padding-top: 30px;
+    .biaoji {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      height: 40px;
+      width: 90%;
+      border-radius: 0 40px 40px 0;
+      font-weight: 700;
+      font-size: 20px;
+      padding-left: 20px;
+      padding-right: 30px;
+    }
+    .biaojiAc {
+      background-color: #3a80d2;
+      color: #fff;
+    }
+    ul {
+      li {
+        cursor: pointer;
+        padding-left: 24px;
+        margin: 30px 0;
+        &:hover {
+          color: #3a80d2;
+        }
+      }
+      .active {
+        color: #3a80d2;
+      }
+    }
+  }
+  .right {
+    position: relative;
+    padding: 20px 0 0 0;
+    min-width: 1500px;
+    flex: 1;
+    margin-left: 30px;
+    background-color: #fff;
+    height: 100%;
+    min-height: 770px;
+  }
+}
+</style>

+ 154 - 0
houtai/src/views/login.vue

@@ -0,0 +1,154 @@
+<!--  -->
+<template>
+  <div class="login">
+    <div class="con">
+      <div class="left">
+        <p>芜湖一房一册</p>
+        <p>管理后台</p>
+      </div>
+      <div class="right" @keyup.enter="login">
+        <p>欢迎登录</p>
+        <div class="input">
+          <el-form
+            :model="ruleForm"
+            :rules="rules"
+            ref="ruleForm"
+            class="demo-ruleForm"
+          >
+            <el-form-item prop="userName">
+              <el-input
+                v-model="ruleForm.userName"
+                placeholder="账号"
+              ></el-input>
+            </el-form-item>
+            <el-form-item prop="passWord">
+              <el-input
+                show-password
+                v-model="ruleForm.passWord"
+                placeholder="密码"
+              ></el-input>
+            </el-form-item>
+          </el-form>
+        </div>
+        <div class="btn" @click="login">登 录</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { encodeStr } from '../utils/pass'
+import { Base64 } from 'js-base64'
+import { userLogin } from '@/apis/login'
+export default {
+  name: 'login',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      ruleForm: {
+        userName: '',
+        passWord: ''
+      },
+      rules: {
+        userName: [{ required: true, message: '不能为空', trigger: 'blur' }],
+        passWord: [{ required: true, message: '不能为空', trigger: 'blur' }]
+      }
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    async login () {
+      try {
+        await this.$refs.ruleForm.validate()
+        const data = {
+          userName: this.ruleForm.userName,
+          passWord: encodeStr(Base64.encode(this.ruleForm.passWord))
+        }
+        const res = await userLogin(data)
+        if (res.code === 0) {
+          localStorage.setItem('HNBWY_token', res.data.token)
+          localStorage.setItem('HNBWY_userName', res.data.user.userName)
+          this.$router.push('/layout/tab2')
+          this.$message.success('登录成功')
+        } else this.$message.warning(res.msg)
+      } catch (error) {
+        console.log(error)
+      }
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {},
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.login {
+  width: 100vw;
+  height: 100vh;
+  background: url("../assets/img/bg.png");
+  background-size: 100% 100%;
+  .con {
+    display: flex;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    width: 700px;
+    height: 400px;
+    .left {
+      display: flex;
+      flex-direction: column;
+      justify-content: center;
+      width: 350px;
+      height: 100%;
+      background-color: rgba(58, 128, 210, 0.8);
+      & > p {
+        width: 80%;
+        margin: 0 auto;
+        margin-bottom: 30px;
+        color: #fff;
+        font-weight: 700;
+        text-align: center;
+        font-size: 30px;
+      }
+    }
+    .right {
+      width: 350px;
+      background-color: rgba(255, 255, 255, 0.8);
+      & > p {
+        font-size: 24px;
+        text-align: center;
+        margin-top: 50px;
+      }
+      .input {
+        width: 90%;
+        margin: 50px auto;
+      }
+      .btn {
+        cursor: pointer;
+        width: 90%;
+        height: 40px;
+        line-height: 40px;
+        text-align: center;
+        margin: 50px auto 0;
+        background-color: #3a80d2;
+        border-radius: 8px;
+        color: #fff;
+      }
+    }
+  }
+}
+</style>

+ 646 - 0
houtai/src/views/tab2/add.vue

@@ -0,0 +1,646 @@
+<!--  -->
+<template>
+  <div class="tab2Add">
+    <div class="top">
+      典藏信息 > {{ ruleForm.type === "img" ? "精品图片" : "三维模型" }} >
+      {{ ruleForm.id ? "编辑" : "新增" }}
+    </div>
+    <div class="conten">
+      <el-form
+        :model="ruleForm"
+        ref="ruleForm"
+        label-width="120px"
+        class="demo-ruleForm"
+      >
+        <!-- 名称 -->
+        <div class="checkBox2">
+          <el-form-item label="名称:">
+            <i class="biaoshi biaoshi2"></i>
+            <el-input
+              v-model="ruleForm.name"
+              maxlength="10"
+              show-word-limit
+            ></el-input>
+          </el-form-item>
+          <!-- 总登记号 -->
+          <el-form-item label="总登记号:">
+            <el-input
+              v-model="ruleForm.registerNum"
+              maxlength="25"
+              show-word-limit
+            ></el-input>
+          </el-form-item>
+        </div>
+        <div class="checkBox">
+          <!-- 日期 -->
+          <el-form-item label="日期:">
+            <i class="biaoshi biaoshi2"></i>
+            <el-date-picker
+              format="yyyy-MM-dd"
+              value-format="yyyy-MM-dd"
+              v-model="day"
+              type="date"
+              placeholder="选择日期"
+            >
+            </el-date-picker>
+          </el-form-item>
+
+          <!-- 类型 -->
+          <el-form-item label="类别:">
+            <el-select
+              v-model="ruleForm.dictTextureId"
+              clearable
+              placeholder="请选择类别"
+            >
+              <el-option
+                v-for="i in dictTextureArr"
+                :key="i.value"
+                :label="i.label"
+                :value="i.value"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <!-- 年代 -->
+          <el-form-item label="年代:">
+            <el-cascader
+              ref="elCascader"
+              clearable
+              v-model="dictAgeId"
+              :options="options"
+            >
+            </el-cascader>
+          </el-form-item>
+          <!-- 级别 -->
+          <el-form-item label="级别:">
+            <el-select
+              v-model="ruleForm.dictLevelId"
+              clearable
+              placeholder="请选择级别"
+            >
+              <el-option
+                v-for="i in dictLevelArr"
+                :key="i.value"
+                :label="i.label"
+                :value="i.value"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </div>
+        <!-- 尺寸 -->
+        <el-form-item label="尺寸:" class="sizeInput">
+          <el-input v-model="chang" maxlength="100" show-word-limit></el-input>
+        </el-form-item>
+
+        <!-- 图片 -->
+        <el-form-item label="图片:">
+          <i class="biaoshi biaoshi1"></i>
+          <el-upload
+            accept=".png,.jpg,.jpeg,.gif"
+            :data="{ type: 'img' }"
+            class="avatar-uploader"
+            :action="baseURL + '/api/cms/goods/upload'"
+            :headers="{ token }"
+            :show-file-list="true"
+            :before-upload="beforethumbUpload"
+            :on-success="upload_thumb_success"
+          >
+            <div v-if="ruleForm.thumb" class="imgdiv">
+              <img
+                style="
+                  width: 150px;
+                  height: 150px;
+                  display: block;
+                  object-fit: cover;
+                "
+                :src="baseURL + ruleForm.thumb"
+              />
+              <i
+                class="el-icon-circle-close"
+                @click.stop="ruleForm.thumb = ''"
+              ></i>
+            </div>
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </el-upload>
+          <p class="upHint">
+            格式要求:支持png、jpg、gif和jpeg的图片格式;最大支持20MB。
+          </p>
+        </el-form-item>
+        <!-- 说明 -->
+        <el-form-item label="说明:">
+          <div class="txtBtn">
+            <el-button
+              :disabled="ruleForm.description.length >= 128"
+              size="small"
+              round
+              @click="ruleForm.description += '&emsp;&emsp;'"
+              >首行缩进</el-button
+            >
+            <el-button
+              :disabled="ruleForm.description.length >= 135"
+              size="small"
+              round
+              @click="ruleForm.description += '<br/>'"
+              >换行</el-button
+            >
+          </div>
+          <el-input
+            type="textarea"
+            v-model="ruleForm.description"
+            maxlength="140"
+            show-word-limit
+          ></el-input>
+        </el-form-item>
+        <!-- 附件 -->
+        <div class="rowFrom">
+          <el-form-item label="模型文件:" v-if="ruleForm.type === 'model'">
+            <i class="biaoshi"></i>
+            <el-upload
+              accept=".4dage"
+              multiple
+              drag
+              class="upload-demo"
+              :data="{ type: 'model' }"
+              :file-list="fileList"
+              :action="baseURL + '/api/cms/goods/upload'"
+              :headers="{ token }"
+              :before-upload="beforeFujian"
+              :on-success="successFujian"
+              :before-remove="beforeRemove"
+              :on-remove="handleRemove"
+              :limit="1"
+              :on-exceed="handleExceed"
+              :show-file-list="true"
+            >
+              <i class="el-icon-upload"></i>
+              <div class="el-upload__text">
+                将文件拖到此处,或<em>点击上传</em>
+              </div>
+              <div class="el-upload__text smEl">
+                仅支持.4dage格式的模型文件,大小不得超过500MB
+              </div>
+            </el-upload>
+          </el-form-item>
+          &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;
+          <el-form-item label="音频文件:" v-if="ruleForm.type === 'model'">
+            <el-upload
+              accept=".mp3"
+              multiple
+              drag
+              class="upload-demo"
+              :data="{ type: 'audio' }"
+              :file-list="fileList2"
+              :action="baseURL + '/api/cms/goods/upload'"
+              :headers="{ token }"
+              :before-upload="beforeFujian2"
+              :on-success="successFujian2"
+              :before-remove="beforeRemove2"
+              :on-remove="handleRemove2"
+              :limit="1"
+              :on-exceed="handleExceed2"
+              :show-file-list="true"
+            >
+              <i class="el-icon-upload"></i>
+              <div class="el-upload__text">
+                将文件拖到此处,或<em>点击上传</em>
+              </div>
+              <div class="el-upload__text smEl">
+                仅支持MP3格式的音频文件,大小不得超过10MB
+              </div>
+            </el-upload>
+          </el-form-item>
+        </div>
+      </el-form>
+    </div>
+    <!-- 底部按钮 -->
+    <div class="con_btn">
+      <el-button @click="goBack">取 消</el-button>&emsp;
+      <el-button type="primary" @click="saveGood">保 存</el-button>
+    </div>
+  </div>
+</template>
+
+<script>
+import { goodsSave, goodsDetail, dictGetTree } from '../../apis/tab2'
+import axios from '@/utils/request'
+export default {
+  name: 'tab2Add',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      // 日期
+      day: '',
+
+      // 服务器前缀地址
+      baseURL: '',
+      // 尺寸
+      chang: '',
+      // 年代
+      dictAgeId: [],
+      options: [],
+      // 类型数组
+      dictTextureArr: [],
+      // 级别数组
+      dictLevelArr: [],
+      ruleForm: {
+        // 总登记号
+        registerNum: '',
+        // 类别
+        dictTextureId: '',
+        // 级别
+        dictLevelId: '',
+        name: '',
+        type: null,
+        description: '',
+        thumb: '',
+        // 上传模型
+        filePath: '',
+        fileName: ''
+      },
+      fileList: [],
+      // ---------音频
+      fileList2: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    // 点击取消
+    goBack () {
+      let k = this.$route.query.k
+      if (!k) k = '1'
+      this.$router.push({
+        path: '/layout/tab2',
+        query: { typeU: this.ruleForm.type, k }
+      })
+    },
+    // 点击保存
+    async saveGood () {
+      if (this.ruleForm.name.trim() === '') {
+        return this.$message.warning('名称不能为空')
+      }
+      if (this.ruleForm.thumb === '') {
+        return this.$message.warning('图片不能为空')
+      }
+      if (this.ruleForm.filePath === '' && this.ruleForm.type === 'model') {
+        return this.$message.warning('文件不能为空')
+      }
+      if (!this.day) return this.$message.warning('日期不能为空')
+      const obj = { ...this.ruleForm }
+      obj.day = this.day
+      // 年代数据判断
+      if (this.dictAgeId && this.dictAgeId[1]) {
+        obj.dictAgeId = this.dictAgeId[1]
+        // eslint-disable-next-line no-constant-condition
+        const tempArr = this.$refs.elCascader.getCheckedNodes()[0].pathLabels
+        obj.dictAgeFront = tempArr.join('/')
+      }
+      // 长宽高判断
+      if (this.chang) obj.sizeLength = this.chang
+      const res = await goodsSave(obj)
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.goBack()
+      } else this.$message.warning(res.msg)
+    },
+    // 上传图片
+    beforethumbUpload (file) {
+      // console.log(998, file)
+      // 限制图片大小和格式
+      const sizeOk = file.size / 1024 / 1024 < 20
+      const typeOk =
+        file.type === 'image/png' ||
+        (file.type === 'image/jpeg' && !file.name.includes('.jfif')) ||
+        file.type === 'image/gif'
+
+      return new Promise((resolve, reject) => {
+        if (!typeOk) {
+          this.$message.error('图片格式有误!')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('图片大小超过20M!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    upload_thumb_success (data) {
+      this.$message.success('上传成功')
+      this.ruleForm.thumb = data.data.filePath
+    },
+    // 上传附件
+    beforeFujian (file) {
+      console.log('附件上传前', file)
+      const sizeOk = file.size / 1024 / 1024 < 500
+      const typeOk = file.type === '' && file.name.includes('.4dage')
+      return new Promise((resolve, reject) => {
+        if (!sizeOk) {
+          this.$message.error('模型大小超过500M!')
+          reject(file)
+        } else if (!typeOk) {
+          this.$message.error('模型格式有误!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    successFujian (file) {
+      console.log('上传附件成功', file)
+      if (file.code === 0) {
+        this.ruleForm.filePath = file.data.filePath
+        this.ruleForm.fileName = file.data.fileName
+        this.$message.success('上传成功')
+      } else if (file.code === -1) {
+        this.$message.warning('上传失败,不支持的文件格式')
+      }
+    },
+    beforeRemove (file, fileList) {
+      if (file && file.status === 'success') {
+        return this.$confirm(`确定移除 ${file.name}?`)
+      }
+    },
+    handleRemove (file, fileList) {
+      this.ruleForm.filePath = ''
+      this.ruleForm.fileName = ''
+    },
+    handleExceed (files, fileList) {
+      this.$message.warning('只能上传一个文件,请删除原文件后操作')
+    },
+
+    // 上传音频-------------
+    beforeFujian2 (file) {
+      console.log('附件上传前222', file)
+      const sizeOk = file.size / 1024 / 1024 < 10
+      const typeOk = file.type === 'audio/mpeg'
+      return new Promise((resolve, reject) => {
+        if (!sizeOk) {
+          this.$message.error('音频大小超过10M!')
+          reject(file)
+        } else if (!typeOk) {
+          this.$message.error('音频格式有误!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    successFujian2 (file) {
+      console.log('上传附件成功222', file)
+      if (file.code === 0) {
+        this.ruleForm.audioPath = file.data.filePath
+        this.ruleForm.audioName = file.data.fileName
+        this.$message.success('上传成功')
+      } else if (file.code === -1) {
+        this.$message.warning('上传失败,不支持的文件格式')
+      }
+    },
+    beforeRemove2 (file, fileList) {
+      if (file && file.status === 'success') {
+        return this.$confirm(`确定移除 ${file.name}?`)
+      }
+    },
+    handleRemove2 (file, fileList) {
+      this.ruleForm.audioPath = ''
+      this.ruleForm.audioName = ''
+    },
+    handleExceed2 (files, fileList) {
+      this.$message.warning('只能上传一个文件,请删除原文件后操作')
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  async created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 获取用户token
+    this.token = localStorage.getItem('HNBWY_token')
+    // 拿到路由跳转传过来的数据
+    this.ruleForm.type = this.$route.query.typeU
+
+    // 几个下拉框的数据
+    // --------年代
+    const res = await dictGetTree({ type: 'age' })
+    const temp = []
+    res.data.forEach((v, i) => {
+      temp.push({ value: v.id, label: v.name, children: [] })
+      v.children.forEach((p) => {
+        temp[i].children.push({ value: p.id, label: p.name })
+      })
+    })
+    this.options = [...temp]
+
+    // -------类别
+    const res2 = await dictGetTree({ type: 'texture' })
+    this.dictTextureArr = res2.data.map((v) => {
+      return { value: v.id, label: v.name }
+    })
+    // -------级别
+    const res3 = await dictGetTree({ type: 'level' })
+    this.dictLevelArr = res3.data.map((v) => {
+      return { value: v.id, label: v.name }
+    })
+
+    // 如果是编辑
+    let id = this.$route.query.id
+    if (id) {
+      id = Number(id)
+      const resSon = await goodsDetail(id)
+      this.ruleForm = resSon.data
+      // 附件回显
+      this.fileList = [{ name: resSon.data.fileName }]
+      // 音频回显
+      if (resSon.data.audioName) {
+        this.fileList2 = [{ name: resSon.data.audioName }]
+      }
+
+      // 年代回显
+      if (resSon.data.dictAgeId) {
+        res.data.forEach((v) => {
+          v.children.forEach((p) => {
+            if (p.id === resSon.data.dictAgeId) this.dictAgeId = [v.id, p.id]
+          })
+        })
+      }
+      // 尺寸回显
+      this.chang = resSon.data.sizeLength
+      // 日期回显
+      this.day = resSon.data.day
+    }
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab2Add {
+  width: 100%;
+  height: 100%;
+
+  .rowFrom {
+    display: flex;
+
+    /deep/.el-upload-list {
+      width: 360px;
+    }
+
+    /deep/.el-upload-list li {
+      width: 360px !important;
+    }
+  }
+
+  .top {
+    margin-top: -20px;
+    height: 50px;
+    line-height: 50px;
+    padding-left: 50px;
+    background-color: #f8f8f8;
+    font-weight: 700;
+  }
+
+  .conten {
+    padding-right: 300px;
+    padding-top: 20px;
+
+    .upHint {
+      position: absolute;
+      bottom: 40px;
+      left: 160px;
+    }
+
+    .avatar-uploader .el-upload {
+      border-radius: 6px;
+      cursor: pointer;
+      position: relative;
+      overflow: hidden;
+    }
+
+    .avatar-uploader .el-upload:hover {
+      border-color: #3e5eb3;
+    }
+
+    .avatar-uploader-icon {
+      border: 1px dashed #ccc;
+      font-size: 28px;
+      color: #8c939d;
+      width: 150px;
+      height: 150px;
+      line-height: 150px;
+      text-align: center;
+    }
+
+    .biaoshi1::before {
+      left: -64px;
+    }
+
+    .biaoshi2::before {
+      top: -11px;
+      left: -64px;
+    }
+
+    /deep/.el-form-item {
+      margin-bottom: 12px;
+    }
+
+    /deep/.el-textarea textarea {
+      margin-top: 10px;
+      height: 55px;
+      resize: none;
+    }
+
+    /deep/.el-textarea .el-input__count {
+      position: absolute;
+      bottom: -24px;
+      right: 4px;
+      background-color: transparent;
+      height: 30px;
+      line-height: 30px;
+    }
+
+    .smEl {
+      color: #ccc;
+      font-size: 12px;
+      margin-top: -15px;
+    }
+  }
+
+  .con_btn {
+    position: absolute;
+    bottom: 20px;
+    left: 50%;
+    transform: translateX(-50%);
+  }
+
+  .txtBtn {
+    position: absolute;
+    top: -32px;
+    right: 4px;
+  }
+
+  /deep/.imgdiv .el-icon-circle-close {
+    font-size: 20px;
+  }
+
+  .checkBox {
+    display: flex;
+  }
+
+  .checkBox2 {
+    width: 100%;
+    display: flex;
+
+    & > div {
+      width: 50%;
+    }
+  }
+
+  .fromSize {
+    /deep/.el-form-item__content {
+      display: flex;
+    }
+
+    /deep/.el-input {
+      width: 100px;
+    }
+
+    /deep/.el-input--suffix {
+      width: 90px;
+    }
+
+    /deep/.el-input__inner {
+      padding: 0 5px !important;
+    }
+
+    .sizeRow {
+      margin-right: 90px;
+    }
+
+    .sizeRow2 {
+      /deep/.el-input {
+        width: 110px;
+      }
+    }
+  }
+  .sizeInput{
+    /deep/input{
+      padding-right: 70px !important;
+    }
+  }
+
+  /deep/.el-upload-list {
+    margin-top: -12px;
+  }
+}
+</style>

+ 292 - 0
houtai/src/views/tab2/index.vue

@@ -0,0 +1,292 @@
+<template>
+  <div class="tab2">
+    <div class="insideTop">建筑可对话-发布</div>
+    <div class="obstruct"></div>
+    <div class="conten">
+      <!-- 右侧主要内容 -->
+      <div class="con_right" v-loading="loading">
+        <div class="search">
+          <span class="search_k">审核状态:</span>
+          <el-select v-model="formData.dictTextureId" placeholder="请选择">
+            <el-option label="通过" :value="1"> </el-option>
+            <el-option label="不通过" :value="2"> </el-option>
+          </el-select>
+        </div>
+
+        <!-- 表格 -->
+        <div class="table">
+          <el-table :data="tableData" style="width: 100%">
+            <el-table-column label="编号" width="80">
+              <template slot-scope="scope">
+                {{
+                  scope.$index + (formData.pageNum - 1) * formData.pageSize + 1
+                }}
+              </template>
+            </el-table-column>
+            <el-table-column label="名称" prop="name"> </el-table-column>
+            <el-table-column label="总登记号">
+              <template #default="{ row }">
+                <span
+                  style="cursor: pointer"
+                  :title="row.registerNum"
+                  v-if="row.registerNum"
+                  >{{
+                    row.registerNum.length > 10
+                      ? row.registerNum.substring(0, 10) + "..."
+                      : row.registerNum
+                  }}</span
+                >
+                <span v-else>(空)</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="类别">
+              <template #default="{ row }">
+                <span v-if="row.dictTextureName">{{
+                  row.dictTextureName
+                }}</span>
+                <span v-else>(空)</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="年代">
+              <template #default="{ row }">
+                <span v-if="row.dictAgeFront">{{ row.dictAgeFront }}</span>
+                <span v-else>(空)</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="级别">
+              <template #default="{ row }">
+                <span v-if="row.dictLevelName">{{ row.dictLevelName }}</span>
+                <span v-else>(空)</span>
+              </template>
+            </el-table-column>
+
+            <el-table-column label="图片" width="120">
+              <template #default="{ row }">
+                <img
+                  class="table_img"
+                  :src="baseURL + row.thumb"
+                  alt=""
+                  :onerror="defaultImg"
+                />
+              </template>
+            </el-table-column>
+            <el-table-column prop="day" label="日期"> </el-table-column>
+            <el-table-column label="操作">
+              <template #default="{ row }">
+                <el-button type="text">查看</el-button>
+                <el-button
+                  type="text"
+                  style="color: #d9001b"
+                  :disabled="!!row.display"
+                  @click="delGoods(row.id)"
+                  :class="{ disNo: row.display }"
+                  >删除</el-button
+                >
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </div>
+    </div>
+    <!-- 分页 -->
+    <div class="paging">
+      <span>共 {{ total }} 条</span>
+      <el-pagination
+        layout="sizes,prev, pager, next,jumper"
+        :total="total"
+        :current-page="formData.pageNum"
+        @current-change="currentChange"
+        @size-change="sizeChange"
+      >
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from '@/utils/request'
+import { goodsList, goodsRemove } from '@/apis/tab2'
+import dayjs from 'dayjs'
+import relativeTime from 'dayjs/plugin/relativeTime'
+import 'dayjs/locale/zh-cn'
+dayjs.extend(relativeTime)
+
+export default {
+  name: 'tab2',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      loading: false,
+
+      baseURL: '',
+      total: 0,
+
+      formData: {
+        startTime: '',
+        endTime: '',
+        pageNum: 1,
+        pageSize: 10,
+        dictTextureId: ''
+      },
+      tableData: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    // 分页器方法
+    currentChange (val) {
+      // console.log('当前页改变了', val)
+      this.formData.pageNum = val
+      this.goodsList(this.formData)
+    },
+    sizeChange (val) {
+      // console.log('条数改变了', val)
+      this.formData.pageNum = 1
+      this.formData.pageSize = val
+      this.goodsList(this.formData)
+    },
+    // 点击删除
+    delGoods (id) {
+      this.$confirm('删除后,信息无法恢复,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          const res = await goodsRemove(id)
+          if (res.code === 0) {
+            this.$message.success('删除成功')
+            if (this.tableData.length === 1 && this.formData.pageNum > 1) {
+              this.formData.pageNum -= 1
+            }
+            this.goodsList(this.formData)
+          } else this.$message.warning(res.msg)
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    },
+
+    // 封装获取列表的函数
+    async goodsList (data) {
+      const res = await goodsList(data)
+      this.total = res.data.total
+      this.tableData = res.data.records
+      // console.log(998, res)
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  async created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 判断是第一次进来还是修改或者新增或者查看后返回
+    // 拿到路由跳转传过来的数据
+    if (this.$route.query.typeU) {
+      this.formData.type = this.$route.query.typeU
+    }
+    const k = this.$route.query.k
+    if (k) this.formData.pageNum = Number(k)
+    this.goodsList(this.formData)
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab2 {
+  height: 100%;
+  .conten {
+    display: flex;
+    height: calc(100% - 52px);
+    .con_left {
+      padding: 20px 0 0 15px;
+      width: 150px;
+      height: 100%;
+      border-right: 1px solid black;
+      .cutJT {
+        margin-bottom: 10px;
+      }
+      ul {
+        li {
+          cursor: pointer;
+          width: 100px;
+          text-align: center;
+          line-height: 40px;
+          height: 40px;
+          &:hover {
+            color: #3a80d2;
+          }
+        }
+        .active {
+          color: #3a80d2;
+        }
+      }
+    }
+    .con_right {
+      padding: 15px 30px 0;
+      width: 100%;
+      .classify {
+        text-align: center;
+        width: 40px;
+        padding-bottom: 10px;
+        color: #b9412e;
+        border-bottom: 2px solid #b9412e;
+      }
+      .search {
+        display: flex;
+        align-items: center;
+        margin-bottom: 20px;
+        position: relative;
+        margin-top: 12px;
+        height: 40px;
+        /deep/.el-input__inner {
+          padding-right: 50px;
+        }
+        /deep/.el-select {
+          width: 250px;
+        }
+
+        .search_btn {
+          margin-left: 50px;
+          display: flex;
+          justify-content: space-between;
+          width: 300px;
+        }
+      }
+    }
+  }
+  // .table {
+  //   max-width: 1370px;
+  // }
+  /deep/.el-table__body-wrapper {
+    max-height: 500px;
+    overflow-y: auto;
+  }
+  .paging {
+    display: flex;
+    align-items: center;
+    position: absolute;
+    bottom: 15px;
+    right: 50px;
+    & > span {
+      margin-right: 15px;
+      font-size: 13px;
+    }
+  }
+  .disNo {
+    color: #ccc !important;
+  }
+}
+</style>

+ 160 - 0
houtai/src/views/tab3/index.vue

@@ -0,0 +1,160 @@
+<template>
+  <div class="tab6">
+    <div class="insideTop">
+      操作日志
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <!-- <div class="search"  @keyup.enter="searchBtn">
+        <el-input
+          v-model="formData.searchKey"
+          placeholder="请输入关键字"
+          style="width: 240px"
+        ></el-input>
+        <div class="search_btn">
+          <el-button type="primary" @click="searchBtn">查 询</el-button>
+        </div>
+      </div> -->
+      <!-- 表格 -->
+      <div class="table">
+        <el-table :data="tableData" style="width: 100%">
+          <el-table-column label="序号" width="80">
+            <template slot-scope="scope">
+              {{
+                scope.$index + (formData.pageNum - 1) * formData.pageSize + 1
+              }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="userName" label="账号"> </el-table-column>
+          <el-table-column prop="type" label="操作模块"> </el-table-column>
+          <el-table-column prop="description" label="操作事件"></el-table-column>
+          <el-table-column prop="createTime" label="操作时间"></el-table-column>
+        </el-table>
+      </div>
+    </div>
+    <!-- 分页 -->
+    <div class="paging">
+      <el-pagination
+        layout="sizes,prev, pager, next,jumper"
+        :total="total"
+        :current-page="formData.pageNum"
+        @current-change="currentChange"
+        @size-change="sizeChange"
+      >
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import { logList } from '@/apis/tab2'
+export default {
+  name: 'tab6',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      total: 0,
+      formData: {
+        pageNum: 1,
+        pageSize: 10,
+        searchKey: ''
+      },
+      tableData: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {
+  },
+  // 方法集合
+  methods: {
+    // 点击查询
+    searchBtn () {
+      this.formData.pageNum = 1
+      this.logList(this.formData)
+    },
+    // 封装获取列表的函数
+    async logList (data) {
+      const res = await logList(data)
+      this.total = res.data.total
+      this.tableData = res.data.records
+      // console.log(998, res)
+    },
+    // 分页器方法
+    currentChange (val) {
+      // console.log('当前页改变了', val)
+      this.formData.pageNum = val
+      this.logList(this.formData)
+    },
+    sizeChange (val) {
+      // console.log('条数改变了', val)
+      this.formData.pageNum = 1
+      this.formData.pageSize = val
+      this.logList(this.formData)
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    this.logList(this.formData)
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab6 {
+  height: 100%;
+  .insideTop .add{
+    right: 55px;
+  }
+  .conten {
+    padding: 15px 30px 0;
+    height: calc(100% - 32px);
+    .classify {
+      text-align: center;
+      width: 40px;
+      padding-bottom: 10px;
+      color: #b9412e;
+      border-bottom: 2px solid #b9412e;
+    }
+    .search {
+      display: flex;
+      margin-bottom: 20px;
+      position: relative;
+      margin-top: 12px;
+      height: 40px;
+      .search_k {
+        margin-left: 30px;
+      }
+      .search_btn {
+        margin-left: 30px;
+        display: flex;
+        justify-content: space-between;
+        width: 100px;
+      }
+    }
+    .table {
+      max-width: 1533px;
+    }
+    /deep/.el-table__body-wrapper {
+      max-height: 528px;
+      overflow-y: auto;
+    }
+  }
+  .paging {
+    position: absolute;
+    bottom: 15px;
+    right: 50px;
+  }
+}
+</style>

+ 3 - 0
houtai/vue.config.js

@@ -0,0 +1,3 @@
+module.exports = {
+  publicPath: './'
+}

Файловите разлики са ограничени, защото са твърде много
+ 8 - 8
yfyc/public/masonry.pkgd.min.js


+ 7 - 0
yfyc/src/api/interact.js

@@ -0,0 +1,7 @@
+import axios from '../utils/request'
+// 登录----
+export const getCodeAPI = (code) => {
+  return axios({
+    url: `wxMini/wxLogin/${code}`,
+  })
+}

BIN
yfyc/src/assets/img/home/1.jpg


BIN
yfyc/src/assets/img/home/1.png


BIN
yfyc/src/assets/img/home/10.jpg


BIN
yfyc/src/assets/img/home/11.jpg


BIN
yfyc/src/assets/img/home/12.jpg


BIN
yfyc/src/assets/img/home/13.jpg


BIN
yfyc/src/assets/img/home/14.jpg


BIN
yfyc/src/assets/img/home/15.jpg


BIN
yfyc/src/assets/img/home/2.jpg


BIN
yfyc/src/assets/img/home/2.png


BIN
yfyc/src/assets/img/home/3.jpg


BIN
yfyc/src/assets/img/home/3.png


BIN
yfyc/src/assets/img/home/4.jpg


BIN
yfyc/src/assets/img/home/4.png


BIN
yfyc/src/assets/img/home/5.jpg


BIN
yfyc/src/assets/img/home/5.png


BIN
yfyc/src/assets/img/home/6.jpg


BIN
yfyc/src/assets/img/home/6.png


BIN
yfyc/src/assets/img/home/7.jpg


BIN
yfyc/src/assets/img/home/8.jpg


BIN
yfyc/src/assets/img/home/9.jpg


Файловите разлики са ограничени, защото са твърде много
+ 3 - 3
yfyc/src/assets/libs/ua-parser.min.js


+ 59 - 59
yfyc/src/assets/my-reset.css

@@ -1,60 +1,60 @@
-*,
-*::before,
-*::after {
-  /* 阻止safari在用户交互设置一些元素的背景色 */
-  -webkit-tap-highlight-color: transparent;
-  box-sizing: border-box;
-}
-
-html {
-  overflow: hidden;
-  /* touch-action: none; */
-  scroll-behavior: smooth; /* MDN: When this property is specified on the root element, it applies to the viewport instead. This property specified on the body element will not propagate to the viewport.(???) */
-  height: 100%;
-}
-
-body {
-  text-align: justify;
-  height: 100%;
-  overflow: hidden;
-}
-
-a {
-  color: initial;
-  text-decoration: initial;
-  outline: none;
-}
-
-button {
-  padding: 0;
-  cursor: pointer;
-  background-color: initial;
-  border: initial;
-  outline: none;
-  white-space: pre;
-}
-
-img {
-  user-select: none;
-}
-
-menu {
-  list-style-type: initial;
-}
-
-li {
-  display: initial;
-}
-
-input {
-  outline: initial;
-  background: initial;
-  border: initial;
-  border-radius: initial;
-  width: initial;
-  height: initial;
-}
-
-td {
-  vertical-align: inherit;
+*,
+*::before,
+*::after {
+  /* 阻止safari在用户交互设置一些元素的背景色 */
+  -webkit-tap-highlight-color: transparent;
+  box-sizing: border-box;
+}
+
+html {
+  overflow: hidden;
+  /* touch-action: none; */
+  scroll-behavior: smooth; /* MDN: When this property is specified on the root element, it applies to the viewport instead. This property specified on the body element will not propagate to the viewport.(???) */
+  height: 100%;
+}
+
+body {
+  text-align: justify;
+  height: 100%;
+  overflow: hidden;
+}
+
+a {
+  color: initial;
+  text-decoration: initial;
+  outline: none;
+}
+
+button {
+  padding: 0;
+  cursor: pointer;
+  background-color: initial;
+  border: initial;
+  outline: none;
+  white-space: pre;
+}
+
+img {
+  user-select: none;
+}
+
+menu {
+  list-style-type: initial;
+}
+
+li {
+  display: initial;
+}
+
+input {
+  outline: initial;
+  background: initial;
+  border: initial;
+  border-radius: initial;
+  width: initial;
+  height: initial;
+}
+
+td {
+  vertical-align: inherit;
 }

+ 107 - 107
yfyc/src/components/BackTop.vue

@@ -1,108 +1,108 @@
-<template>
-  <div class="back-top" @click="onClickBackTop" v-show="isShowBackTopBtn">
-    <slot>
-      <div class="back-top__default">回到顶部</div>
-    </slot>
-  </div>
-</template>
-
-<script>
-// const TWEEN = require('@tweenjs/tween.js')
-
-export default({
-  props: {
-    targetId: {
-      type: String,
-      required: true,
-    },
-    triggerDistance: {
-      type: Number,
-      default: 200,
-    }
-  },
-  data() {
-    return {
-      target: null,
-      isShowBackTopBtn: false,
-      isBackingTop: false,
-    }
-  },
-  methods: {
-    onClickBackTop() {
-      if (this.isBackingTop) {
-        return
-      }
-      this.isBackingTop = true
-
-      // const tweenTarget = {
-      //   scrollTop: this.target.scrollTop
-      // }
-      // new TWEEN.Tween(tweenTarget)
-      //   .to({scrollTop: 0}, 800)
-      //   .easing(TWEEN.Easing.Quartic.Out)
-      //   .onUpdate(() => {
-      //     this.target.scrollTop = tweenTarget.scrollTop
-      //   })
-      //   .onComplete(() => {
-      //     this.isBackingTop = false
-      //   })
-      //   .start()
-      
-      // const animate = (time) => {
-      //   if (this.isBackingTop) {
-      //     requestAnimationFrame(animate)
-      //     TWEEN.update(time)
-      //   }
-      // }
-      // requestAnimationFrame(animate)
-
-      // 不想引入tween.js的话,可以用这段简单的匀速滚动代码
-      const startTime = Date.now()
-      const totalScroll = this.target.scrollTop
-      const fn = () => {
-        if (this.target.scrollTop === 0) {
-          this.isBackingTop = false
-          return
-        } 
-
-        const nowTime = Date.now()
-        const assumeScrollTop = totalScroll - (nowTime - startTime) * totalScroll / 500
-        this.target.scrollTop = assumeScrollTop > 0 ? assumeScrollTop : 0
-        requestAnimationFrame(fn)
-      }
-      requestAnimationFrame(fn)
-    },
-    onTargetScroll: globalUtils.debounce(function(e) {
-      if (this.isBackingTop) {
-        return
-      }
-      if (e.target.scrollTop >= this.triggerDistance) {
-        this.isShowBackTopBtn = true
-      } else {
-        this.isShowBackTopBtn = false
-      }
-    }),
-  },
-  mounted() {
-    this.target = document.getElementById(this.targetId)
-    if (this.target) {
-      this.target.addEventListener('scroll', this.onTargetScroll, {
-        passive: true,
-      })
-    }
-  },
-  unmounted() {
-    if (this.target) {
-      this.target.removeEventListener('scroll', this.onTargetScroll, {
-        passive: true,
-      })
-    }
-  }
-})
-</script>
-
-<style scoped lang="less">
-.back-top__default {
-  cursor: pointer;
-}
+<template>
+  <div class="back-top" @click="onClickBackTop" v-show="isShowBackTopBtn">
+    <slot>
+      <div class="back-top__default">回到顶部</div>
+    </slot>
+  </div>
+</template>
+
+<script>
+// const TWEEN = require('@tweenjs/tween.js')
+
+export default({
+  props: {
+    targetId: {
+      type: String,
+      required: true,
+    },
+    triggerDistance: {
+      type: Number,
+      default: 200,
+    }
+  },
+  data() {
+    return {
+      target: null,
+      isShowBackTopBtn: false,
+      isBackingTop: false,
+    }
+  },
+  methods: {
+    onClickBackTop() {
+      if (this.isBackingTop) {
+        return
+      }
+      this.isBackingTop = true
+
+      // const tweenTarget = {
+      //   scrollTop: this.target.scrollTop
+      // }
+      // new TWEEN.Tween(tweenTarget)
+      //   .to({scrollTop: 0}, 800)
+      //   .easing(TWEEN.Easing.Quartic.Out)
+      //   .onUpdate(() => {
+      //     this.target.scrollTop = tweenTarget.scrollTop
+      //   })
+      //   .onComplete(() => {
+      //     this.isBackingTop = false
+      //   })
+      //   .start()
+      
+      // const animate = (time) => {
+      //   if (this.isBackingTop) {
+      //     requestAnimationFrame(animate)
+      //     TWEEN.update(time)
+      //   }
+      // }
+      // requestAnimationFrame(animate)
+
+      // 不想引入tween.js的话,可以用这段简单的匀速滚动代码
+      const startTime = Date.now()
+      const totalScroll = this.target.scrollTop
+      const fn = () => {
+        if (this.target.scrollTop === 0) {
+          this.isBackingTop = false
+          return
+        } 
+
+        const nowTime = Date.now()
+        const assumeScrollTop = totalScroll - (nowTime - startTime) * totalScroll / 500
+        this.target.scrollTop = assumeScrollTop > 0 ? assumeScrollTop : 0
+        requestAnimationFrame(fn)
+      }
+      requestAnimationFrame(fn)
+    },
+    onTargetScroll: globalUtils.debounce(function(e) {
+      if (this.isBackingTop) {
+        return
+      }
+      if (e.target.scrollTop >= this.triggerDistance) {
+        this.isShowBackTopBtn = true
+      } else {
+        this.isShowBackTopBtn = false
+      }
+    }),
+  },
+  mounted() {
+    this.target = document.getElementById(this.targetId)
+    if (this.target) {
+      this.target.addEventListener('scroll', this.onTargetScroll, {
+        passive: true,
+      })
+    }
+  },
+  unmounted() {
+    if (this.target) {
+      this.target.removeEventListener('scroll', this.onTargetScroll, {
+        passive: true,
+      })
+    }
+  }
+})
+</script>
+
+<style scoped lang="less">
+.back-top__default {
+  cursor: pointer;
+}
 </style>

+ 105 - 105
yfyc/src/components/BookingSuccess.vue

@@ -1,106 +1,106 @@
-<template>
-  <div class="booking-success">
-    <article>
-      <h1>芜湖方特</h1>
-      <div class="tip-1">预约成功</div>
-      <div class="time-summary">
-        <span class="key">预约时间:</span>
-        <span class="value">2022-05-04 17:22:35</span>
-      </div>
-      <div class="line">
-        <img class="icon" src="@/assets/img/service/date.png" alt="" draggable="false">
-        <div class="text">
-          <span class="key">预约日期:</span>
-          <span class="value">2022-05-04 周六</span>
-          </div>
-      </div>
-      <div class="line">
-        <img class="icon" src="@/assets/img/service/time.png" alt="" draggable="false">
-        <div class="text">
-          <span class="key">预约时段:</span>
-          <span class="value">10:00-11:00</span>
-        </div>
-      </div>
-      <div class="line">
-        <img class="icon" src="@/assets/img/service/people.png" alt="" draggable="false">
-        <div class="text">
-          <span class="key">参观人数:</span>
-          <span class="value">1人</span>
-        </div>
-      </div>
-      <div class="tip-2">
-        请您在规定日期时间段内进行参观
-      </div>
-    </article>
-  </div>
-</template>
-
-<style lang="less" scoped>
-.booking-success {
-  position: fixed;
-  left: 0;
-  top: 0;
-  width: 100%;
-  height: 100%;
-  background: rgba(0, 0, 0, 0.8);
-  .line {
-    display: flex;
-    align-items: flex-end;
-    margin-bottom: 6vw;
-    .icon {
-      width: 4.3vw;
-      height: 4.3vw;
-      margin-right: 2.4vw;
-    }
-    .key {
-      font-size: 3.2vw;
-      font-weight: bold;
-      color: #222222;
-    }
-    .value {
-      font-size: 3.2vw;
-      color: #222222;
-    }
-  }
-  > article {
-    position: absolute;
-    left: 50%;
-    top: 50%;
-    transform: translate(-50%, -50%);
-    width: 81.9vw;
-    height: 125.4vw;
-    background-image: url(~@/assets/img/service/booking-result-bg.png);
-    background-size: cover;
-    background-repeat: no-repeat;
-    background-position: center center;
-    padding-left: 5vw;
-    padding-right: 5vw;
-    > h1 {
-      font-size: 8vw;
-      font-weight: bold;
-      color: #FFFFFF;
-      margin-top: 15vw;
-      text-align: center;
-    }
-    > .tip-1 {
-      margin-top: 20vw;
-      font-size: 6.4vw;
-      font-weight: bold;
-      color: #733634;
-    }
-    > .time-summary {
-      margin-top: 3.3vw;
-      margin-bottom: 9vw;
-    }
-    > .tip-2 {
-      position: absolute;
-      bottom: 12vw;
-      left: 50%;
-      transform: translateX(-50%);
-      white-space: pre;
-      font-size: 3.2vw;
-      color: #222222;
-    }
-  }
-}
+<template>
+  <div class="booking-success">
+    <article>
+      <h1>芜湖方特</h1>
+      <div class="tip-1">预约成功</div>
+      <div class="time-summary">
+        <span class="key">预约时间:</span>
+        <span class="value">2022-05-04 17:22:35</span>
+      </div>
+      <div class="line">
+        <img class="icon" src="@/assets/img/service/date.png" alt="" draggable="false">
+        <div class="text">
+          <span class="key">预约日期:</span>
+          <span class="value">2022-05-04 周六</span>
+          </div>
+      </div>
+      <div class="line">
+        <img class="icon" src="@/assets/img/service/time.png" alt="" draggable="false">
+        <div class="text">
+          <span class="key">预约时段:</span>
+          <span class="value">10:00-11:00</span>
+        </div>
+      </div>
+      <div class="line">
+        <img class="icon" src="@/assets/img/service/people.png" alt="" draggable="false">
+        <div class="text">
+          <span class="key">参观人数:</span>
+          <span class="value">1人</span>
+        </div>
+      </div>
+      <div class="tip-2">
+        请您在规定日期时间段内进行参观
+      </div>
+    </article>
+  </div>
+</template>
+
+<style lang="less" scoped>
+.booking-success {
+  position: fixed;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  background: rgba(0, 0, 0, 0.8);
+  .line {
+    display: flex;
+    align-items: flex-end;
+    margin-bottom: 6vw;
+    .icon {
+      width: 4.3vw;
+      height: 4.3vw;
+      margin-right: 2.4vw;
+    }
+    .key {
+      font-size: 3.2vw;
+      font-weight: bold;
+      color: #222222;
+    }
+    .value {
+      font-size: 3.2vw;
+      color: #222222;
+    }
+  }
+  > article {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    transform: translate(-50%, -50%);
+    width: 81.9vw;
+    height: 125.4vw;
+    background-image: url(~@/assets/img/service/booking-result-bg.png);
+    background-size: cover;
+    background-repeat: no-repeat;
+    background-position: center center;
+    padding-left: 5vw;
+    padding-right: 5vw;
+    > h1 {
+      font-size: 8vw;
+      font-weight: bold;
+      color: #FFFFFF;
+      margin-top: 15vw;
+      text-align: center;
+    }
+    > .tip-1 {
+      margin-top: 20vw;
+      font-size: 6.4vw;
+      font-weight: bold;
+      color: #733634;
+    }
+    > .time-summary {
+      margin-top: 3.3vw;
+      margin-bottom: 9vw;
+    }
+    > .tip-2 {
+      position: absolute;
+      bottom: 12vw;
+      left: 50%;
+      transform: translateX(-50%);
+      white-space: pre;
+      font-size: 3.2vw;
+      color: #222222;
+    }
+  }
+}
 </style>

+ 63 - 63
yfyc/src/components/SearchRedBtn.vue

@@ -1,64 +1,64 @@
-<template>
-  <div class="search-wrap">
-    <img class="icon" src="@/assets/img/service/search.png" alt="" draggable="false">
-    <input
-      v-model.trim="keyword"
-      maxlength="30"
-      type="text"
-      placeholder="输入您感兴趣的内容"
-      @keydown.enter="onClickSearch"
-    >
-    <button
-      class="search"
-      @click="onClickSearch"
-    >
-      搜索
-    </button>
-  </div>
-</template>
-
-<script>
-export default {
-  data() {
-    return {
-      keyword: '',
-    }
-  },
-  methods: {
-    onClickSearch() {
-      this.$emit('search', this.keyword)
-    },
-  }
-}
-</script>
-
-<style lang="less" scoped>
-.search-wrap {
-  background: #F4F4F4;
-  height: 6.9vw;
-  min-height: 30px;
-  border-radius: 1.1vw;
-  display: flex;
-  align-items: center;
-  font-size: 2.7vw;
-  > img.icon {
-    flex: 0 0 auto;
-    width: 2.8vw;
-    height: 2.8vw;
-    margin-left: 2.1vw;
-  }
-  > input {
-    flex: 1 0 1px;
-    height: 100%;
-    margin-left: 2.1vw;
-  }
-  > button.search {
-    height: 100%;
-    background: linear-gradient(0deg, #FE6E69 0%, #FF7C6E 100%);
-    border-radius: 1.1vw;
-    padding-left: 1.9vw;
-    padding-right: 1.9vw;
-    color: #fff;
-  }
-}
+<template>
+  <div class="search-wrap">
+    <img class="icon" src="@/assets/img/service/search.png" alt="" draggable="false">
+    <input
+      v-model.trim="keyword"
+      maxlength="30"
+      type="text"
+      placeholder="输入您感兴趣的内容"
+      @keydown.enter="onClickSearch"
+    >
+    <button
+      class="search"
+      @click="onClickSearch"
+    >
+      搜索
+    </button>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      keyword: '',
+    }
+  },
+  methods: {
+    onClickSearch() {
+      this.$emit('search', this.keyword)
+    },
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.search-wrap {
+  background: #F4F4F4;
+  height: 6.9vw;
+  min-height: 30px;
+  border-radius: 1.1vw;
+  display: flex;
+  align-items: center;
+  font-size: 2.7vw;
+  > img.icon {
+    flex: 0 0 auto;
+    width: 2.8vw;
+    height: 2.8vw;
+    margin-left: 2.1vw;
+  }
+  > input {
+    flex: 1 0 1px;
+    height: 100%;
+    margin-left: 2.1vw;
+  }
+  > button.search {
+    height: 100%;
+    background: linear-gradient(0deg, #FE6E69 0%, #FF7C6E 100%);
+    border-radius: 1.1vw;
+    padding-left: 1.9vw;
+    padding-right: 1.9vw;
+    color: #fff;
+  }
+}
 </style>

+ 69 - 69
yfyc/src/components/SearchTransparent.vue

@@ -1,70 +1,70 @@
-<template>
-  <div class="search-wrap">
-    <button
-      @click="onClickSearch"
-      class="search"
-    >
-      <img class="icon" src="@/assets/img/service/search-white.png" alt="" draggable="false">
-    </button>
-    <input
-      v-model.trim="keyword"
-      maxlength="30"
-      type="text"
-      :placeholder="placeholder"
-      @keydown.enter="onClickSearch"
-    >
-  </div>
-</template>
-
-<script>
-export default {
-  props: {
-    placeholder: {
-      type: String,
-      default: '请输入酒店名称',
-    }
-  },
-  data() {
-    return {
-      keyword: '',
-    }
-  },
-  methods: {
-    onClickSearch() {
-      this.$emit('search', this.keyword)
-    },
-  }
-}
-</script>
-
-<style lang="less" scoped>
-.search-wrap {
-  height: 10.7vw;
-  background: rgba(0, 0, 0, 0.65);
-  border: 1px solid #FFFFFF;
-  border-radius: 2.7vw;
-  display: flex;
-  align-items: center;
-  font-size: 4.3vw;
-  padding: 0 3.5vw;
-  > button.search {
-    flex: 0 0 auto;
-    width: 4vw;
-    height: 4vw;
-    position: relative;
-    margin-right: 2.1vw;
-    > img.icon {
-      position: absolute;
-      left: 0;
-      top: 0;
-      width: 100%;
-      height: 100%;
-    }
-  }
-  > input {
-    flex: 1 0 1px;
-    height: 100%;
-    color: #fff;
-  }
-}
+<template>
+  <div class="search-wrap">
+    <button
+      @click="onClickSearch"
+      class="search"
+    >
+      <img class="icon" src="@/assets/img/service/search-white.png" alt="" draggable="false">
+    </button>
+    <input
+      v-model.trim="keyword"
+      maxlength="30"
+      type="text"
+      :placeholder="placeholder"
+      @keydown.enter="onClickSearch"
+    >
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    placeholder: {
+      type: String,
+      default: '请输入酒店名称',
+    }
+  },
+  data() {
+    return {
+      keyword: '',
+    }
+  },
+  methods: {
+    onClickSearch() {
+      this.$emit('search', this.keyword)
+    },
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.search-wrap {
+  height: 10.7vw;
+  background: rgba(0, 0, 0, 0.65);
+  border: 1px solid #FFFFFF;
+  border-radius: 2.7vw;
+  display: flex;
+  align-items: center;
+  font-size: 4.3vw;
+  padding: 0 3.5vw;
+  > button.search {
+    flex: 0 0 auto;
+    width: 4vw;
+    height: 4vw;
+    position: relative;
+    margin-right: 2.1vw;
+    > img.icon {
+      position: absolute;
+      left: 0;
+      top: 0;
+      width: 100%;
+      height: 100%;
+    }
+  }
+  > input {
+    flex: 1 0 1px;
+    height: 100%;
+    color: #fff;
+  }
+}
 </style>

+ 125 - 125
yfyc/src/components/Select.vue

@@ -1,126 +1,126 @@
-<template>
-  <div class="select" v-click-outside.click="onClickOutside">
-    <button
-      class="menu-cover"
-      :class="{
-        active: isExpand,
-      }"
-      @click="isExpand = !isExpand"
-    >
-      {{value ? valueList[value] : placeholder}}
-      <img
-        class="pulldown-icon"
-        :src="isExpand ? require('@/assets/img/service/arrow-down-active.png') : require('@/assets/img/service/arrow-down.png')"
-        alt=""
-        draggable="false"
-      >
-    </button>
-    <div class="menu" v-show="isExpand">
-      <button v-for="(item, index) of valueList" :key="index"
-        :class="{
-          active: index === value,
-        }"
-        @click="onSelect(index)"
-      >
-        {{item}}
-      </button>
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-  props: {
-    valueList: {
-      type: Array,
-      default: function() {
-        return [
-        'all',
-        ]
-      },
-    },
-    placeholder: {
-      type: String,
-      default: '',
-    },
-    value: {
-      type: Number,
-      default: 0
-    }
-  },
-  data() {
-    return {
-      isExpand: false,
-    }
-  },
-  methods: {
-    onClickOutside() {
-      if (this.isExpand) {
-        this.isExpand = false
-      }
-    },
-    onSelect(index) {
-      this.isExpand = false
-      this.$emit('input', index)
-    }
-  }
-}
-</script>
-
-<style lang="less" scoped>
-.select {
-  height: 7vw;
-  position: relative;
-  > button.menu-cover {
-    height: 100%;
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    font-size: 3.5vw;
-    font-weight: bold;
-    color: #666666;
-    > .pulldown-icon {
-      margin-left: 1.5vw;
-      width: 3.1vw;
-      height: 1.9vw;
-    }
-  }
-  > button.menu-cover.active {
-    color: #FE6E69;
-    > .pulldown-icon {
-      transform: rotate(180deg);
-    }
-  }
-  > .menu {
-    position: absolute;
-    left: -4.3vw;
-    top: 100%;
-    width: 25.5vw;
-    background: #FDFDFD;
-    box-shadow: 0.1vw 0.1vw 1.1vw 0vw rgba(109,128,166,0.29);
-    > button {
-      width: calc(100% - 2.7vw * 2);
-      height: 13.2vw;
-      margin-left: 2.7vw;
-      margin-right: 2.7vw;
-      border-bottom: 1px solid #D9D9D9;
-      font-size: 3.2vw;
-      font-weight: 500;
-      color: #666666;
-      &:last-of-type {
-        border-bottom: initial;
-      }
-      &.active {
-        width: 100%;
-        margin-left: initial;
-        margin-right: initial;
-        border-bottom: initial;
-        font-size: 3.2vw;
-        font-weight: bold;
-        color: #FDFDFD;
-        background: linear-gradient(137deg, #FF615C 0%, #FF9877 100%);
-      }
-    }
-  }
-}
+<template>
+  <div class="select" v-click-outside.click="onClickOutside">
+    <button
+      class="menu-cover"
+      :class="{
+        active: isExpand,
+      }"
+      @click="isExpand = !isExpand"
+    >
+      {{value ? valueList[value] : placeholder}}
+      <img
+        class="pulldown-icon"
+        :src="isExpand ? require('@/assets/img/service/arrow-down-active.png') : require('@/assets/img/service/arrow-down.png')"
+        alt=""
+        draggable="false"
+      >
+    </button>
+    <div class="menu" v-show="isExpand">
+      <button v-for="(item, index) of valueList" :key="index"
+        :class="{
+          active: index === value,
+        }"
+        @click="onSelect(index)"
+      >
+        {{item}}
+      </button>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    valueList: {
+      type: Array,
+      default: function() {
+        return [
+        'all',
+        ]
+      },
+    },
+    placeholder: {
+      type: String,
+      default: '',
+    },
+    value: {
+      type: Number,
+      default: 0
+    }
+  },
+  data() {
+    return {
+      isExpand: false,
+    }
+  },
+  methods: {
+    onClickOutside() {
+      if (this.isExpand) {
+        this.isExpand = false
+      }
+    },
+    onSelect(index) {
+      this.isExpand = false
+      this.$emit('input', index)
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.select {
+  height: 7vw;
+  position: relative;
+  > button.menu-cover {
+    height: 100%;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    font-size: 3.5vw;
+    font-weight: bold;
+    color: #666666;
+    > .pulldown-icon {
+      margin-left: 1.5vw;
+      width: 3.1vw;
+      height: 1.9vw;
+    }
+  }
+  > button.menu-cover.active {
+    color: #FE6E69;
+    > .pulldown-icon {
+      transform: rotate(180deg);
+    }
+  }
+  > .menu {
+    position: absolute;
+    left: -4.3vw;
+    top: 100%;
+    width: 25.5vw;
+    background: #FDFDFD;
+    box-shadow: 0.1vw 0.1vw 1.1vw 0vw rgba(109,128,166,0.29);
+    > button {
+      width: calc(100% - 2.7vw * 2);
+      height: 13.2vw;
+      margin-left: 2.7vw;
+      margin-right: 2.7vw;
+      border-bottom: 1px solid #D9D9D9;
+      font-size: 3.2vw;
+      font-weight: 500;
+      color: #666666;
+      &:last-of-type {
+        border-bottom: initial;
+      }
+      &.active {
+        width: 100%;
+        margin-left: initial;
+        margin-right: initial;
+        border-bottom: initial;
+        font-size: 3.2vw;
+        font-weight: bold;
+        color: #FDFDFD;
+        background: linear-gradient(137deg, #FF615C 0%, #FF9877 100%);
+      }
+    }
+  }
+}
 </style>

+ 75 - 75
yfyc/src/components/TabbarSmall.vue

@@ -1,76 +1,76 @@
-<template>
-  <div class="tabbar-small">
-    <ul>
-      <li
-        v-for="(item, index) in tabList"
-        :key="item"
-        :class="{
-          active: index === activeTabIdx,
-        }"
-        @click="activeTabIdx = index"
-      >
-        {{item}}
-      </li>
-    </ul>
-  </div>
-</template>
-
-<script>
-export default {
-  props: {
-    tabList: {
-      type: Array,
-      require: true,
-    },
-  },
-  data() {
-    return {
-      activeTabIdx: 0,
-    }
-  },
-  watch: {
-    activeTabIdx: {
-      handler(vNew) {
-        this.$emit('change', vNew)
-      },
-      immediate: true,
-    }
-  },
-}
-</script>
-
-<style lang="less" scoped>
-.tabbar-small {
-  margin-top: 3.1vw;
-  margin-bottom: 3.6vw;
-  > ul {
-    display: flex;
-    align-items: center;
-    > li {
-      margin-right: 12vw;
-      position: relative;
-      font-size: 3.2vw;
-      font-weight: 600;
-      color: #333333;
-      &:last-of-type {
-        margin-right: initial;
-      }
-      &.active {
-        color: #FE6E69;
-        &::after {
-          content: '';
-          display: absolute;
-          top: calc(100% + 0.9vw);
-          position: absolute;
-          left: 50%;
-          transform: translateX(-50%);
-          width: 10.1vw;
-          height: 1.3vw;
-          background: linear-gradient(0deg, #FF615C 0%, #FF9877 100%);
-          border-radius: 0.7vw;
-        }
-      }
-    }
-  }
-}
+<template>
+  <div class="tabbar-small">
+    <ul>
+      <li
+        v-for="(item, index) in tabList"
+        :key="item"
+        :class="{
+          active: index === activeTabIdx,
+        }"
+        @click="activeTabIdx = index"
+      >
+        {{item}}
+      </li>
+    </ul>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    tabList: {
+      type: Array,
+      require: true,
+    },
+  },
+  data() {
+    return {
+      activeTabIdx: 0,
+    }
+  },
+  watch: {
+    activeTabIdx: {
+      handler(vNew) {
+        this.$emit('change', vNew)
+      },
+      immediate: true,
+    }
+  },
+}
+</script>
+
+<style lang="less" scoped>
+.tabbar-small {
+  margin-top: 3.1vw;
+  margin-bottom: 3.6vw;
+  > ul {
+    display: flex;
+    align-items: center;
+    > li {
+      margin-right: 12vw;
+      position: relative;
+      font-size: 3.2vw;
+      font-weight: 600;
+      color: #333333;
+      &:last-of-type {
+        margin-right: initial;
+      }
+      &.active {
+        color: #FE6E69;
+        &::after {
+          content: '';
+          display: absolute;
+          top: calc(100% + 0.9vw);
+          position: absolute;
+          left: 50%;
+          transform: translateX(-50%);
+          width: 10.1vw;
+          height: 1.3vw;
+          background: linear-gradient(0deg, #FF615C 0%, #FF9877 100%);
+          border-radius: 0.7vw;
+        }
+      }
+    }
+  }
+}
 </style>

+ 27 - 27
yfyc/src/directives/v-click-outside.js

@@ -1,28 +1,28 @@
-export default {
-  install(Vue) {
-    Vue.directive('click-outside', {
-      bind(el, binding) {
-        function documentHandler(e) {
-          if (el.contains(e.target)) {
-            return false
-          }
-          if (binding.expression) {
-            binding.value(e)
-          }
-        }
-        el.__vueClickOutside__ = documentHandler
-        if (binding.modifiers.click) {
-          document.addEventListener('click', documentHandler)
-        }
-        if (binding.modifiers.mousedown) {
-          document.addEventListener('mousedown', documentHandler)
-        }
-      },
-      unbind(el) {
-        document.removeEventListener('click', el.__vueClickOutside__)
-        document.removeEventListener('mousedown', el.__vueClickOutside__)
-        delete el.__vueClickOutside__
-      }
-    })
-  }
+export default {
+  install(Vue) {
+    Vue.directive('click-outside', {
+      bind(el, binding) {
+        function documentHandler(e) {
+          if (el.contains(e.target)) {
+            return false
+          }
+          if (binding.expression) {
+            binding.value(e)
+          }
+        }
+        el.__vueClickOutside__ = documentHandler
+        if (binding.modifiers.click) {
+          document.addEventListener('click', documentHandler)
+        }
+        if (binding.modifiers.mousedown) {
+          document.addEventListener('mousedown', documentHandler)
+        }
+      },
+      unbind(el) {
+        document.removeEventListener('click', el.__vueClickOutside__)
+        document.removeEventListener('mousedown', el.__vueClickOutside__)
+        delete el.__vueClickOutside__
+      }
+    })
+  }
 }

+ 15 - 14
yfyc/src/router/index.js

@@ -11,6 +11,7 @@ const routes = [{
       myTitle: '建筑可阅读'
     },
   },
+
   // 语音讲解
   {
     path: '/goods/audio',
@@ -41,12 +42,12 @@ const routes = [{
     name: 'goodsPlay',
     component: () => import('../views/Goods/components/GoodsPlay.vue')
   },
-    // 分享
-    {
-      path: '/goods/share',
-      name: 'goodsShare',
-      component: () => import('../views/Goods/components/GoodsShare.vue')
-    },
+  // 分享
+  {
+    path: '/goods/share',
+    name: 'goodsShare',
+    component: () => import('../views/Goods/components/GoodsShare.vue')
+  },
   // 悦·互动发布
   {
     path: '/layout/interact/issue',
@@ -56,15 +57,15 @@ const routes = [{
     },
     component: () => import('../views/Interact/components/InteractIssue.vue')
   },
-    // 悦·互动详情
-    {
-      path: '/layout/interact/info',
-      name: 'InteractInfo',
-      meta: {
-        myTitle: '建筑可对话详情'
-      },
-      component: () => import('../views/Interact/components/InteractInfo.vue')
+  // 悦·互动详情
+  {
+    path: '/layout/interact/info',
+    name: 'InteractInfo',
+    meta: {
+      myTitle: '建筑可对话详情'
     },
+    component: () => import('../views/Interact/components/InteractInfo.vue')
+  },
   // 定位,位置
   {
     path: '/layout/interact/location',

+ 84 - 84
yfyc/src/utils/index.js

@@ -1,85 +1,85 @@
-/**
- * 返回一个自带消抖效果的函数,下文用fnDebounced表示。
- *
- * fn: 需要被消抖的函数
- * delay: 消抖时长
- * isImmediateCall: 是否在一组操作中的第一次调用时立即执行fn
- * isRememberLastCall:是否在一组中最后一次调用后等delay时长再执行fn
- * 
- * 如果isRememberLastCall为false,意味着fn不会被延迟执行,所以fnDebounced执行时,要么在内部调用fn,同步返回fn返回值;要么内部决定本次不调用fn,同步返回null。
- * 如果isRememberLastCall为true,意味着fn可能被延迟执行,所以fnDebounced会返回一个Promise,在fn被调用时用其返回值resolve该Promise,或者在fn的延时调用计划被取消时用'canceled'resolve该Promise。(不宜reject,否则又没有人去catch,会导致浏览器报错。)
- */
-export function debounce(fn, delay = 250, isImmediateCall = false, isRememberLastCall = true) {
-  console.assert(isImmediateCall || isRememberLastCall, 'isImmediateCall 和 isRememberLastCall 至少应有一个是true,否则没有意义!')
-  let timer = null
-  let retPromiseLastTimeResolver = null
-  // 上次调用的时刻
-  let lastCallTime = 0
-
-  if (isImmediateCall && !isRememberLastCall) {
-    return function (...args) {
-      let ret = null
-      const currentTime = Date.now()
-      if (currentTime - lastCallTime >= delay) {
-        ret = fn.apply(this, args)
-      }
-      lastCallTime = currentTime
-      return ret
-    }
-  } else if (!isImmediateCall && isRememberLastCall) {
-    return function (...args) {
-      if (timer) {
-        clearTimeout(timer)
-        timer = null
-      }
-      if (retPromiseLastTimeResolver) {
-        retPromiseLastTimeResolver('canceled')
-        retPromiseLastTimeResolver = null
-      }
-      const ret = new Promise((resolve, reject) => {
-        retPromiseLastTimeResolver = resolve
-        timer = setTimeout(() => {
-          timer = null
-          retPromiseLastTimeResolver = null
-          resolve(fn.apply(this, args))
-        }, delay)
-      })
-      return ret
-    }
-  } else if (isImmediateCall && isRememberLastCall) {
-    return function (...args) {
-      const currentTime = Date.now()
-      if (currentTime - lastCallTime >= delay) { // 一组操作中的第一次
-        const res = fn.apply(this, args) 
-        lastCallTime = currentTime
-        return Promise.resolve(res)
-      } else { // 一组中的后续调用
-        if (timer) { // 在此之前存在中间调用
-          lastCallTime = currentTime
-          clearTimeout(timer)
-          timer = null
-        }
-        if (retPromiseLastTimeResolver) {
-          retPromiseLastTimeResolver('canceled')
-          retPromiseLastTimeResolver = null
-        }
-        const ret = new Promise((resolve, reject) => {
-          retPromiseLastTimeResolver = resolve
-          timer = setTimeout(() => {
-            lastCallTime = 0
-            timer = null
-            retPromiseLastTimeResolver = null
-            resolve(fn.apply(this, args))
-          }, delay)
-        })
-        return ret
-      }
-    }
-  } else {
-    console.error('不应该执行到这里!')
-  }
-}
-
-export default {
-  debounce,
+/**
+ * 返回一个自带消抖效果的函数,下文用fnDebounced表示。
+ *
+ * fn: 需要被消抖的函数
+ * delay: 消抖时长
+ * isImmediateCall: 是否在一组操作中的第一次调用时立即执行fn
+ * isRememberLastCall:是否在一组中最后一次调用后等delay时长再执行fn
+ * 
+ * 如果isRememberLastCall为false,意味着fn不会被延迟执行,所以fnDebounced执行时,要么在内部调用fn,同步返回fn返回值;要么内部决定本次不调用fn,同步返回null。
+ * 如果isRememberLastCall为true,意味着fn可能被延迟执行,所以fnDebounced会返回一个Promise,在fn被调用时用其返回值resolve该Promise,或者在fn的延时调用计划被取消时用'canceled'resolve该Promise。(不宜reject,否则又没有人去catch,会导致浏览器报错。)
+ */
+export function debounce(fn, delay = 250, isImmediateCall = false, isRememberLastCall = true) {
+  console.assert(isImmediateCall || isRememberLastCall, 'isImmediateCall 和 isRememberLastCall 至少应有一个是true,否则没有意义!')
+  let timer = null
+  let retPromiseLastTimeResolver = null
+  // 上次调用的时刻
+  let lastCallTime = 0
+
+  if (isImmediateCall && !isRememberLastCall) {
+    return function (...args) {
+      let ret = null
+      const currentTime = Date.now()
+      if (currentTime - lastCallTime >= delay) {
+        ret = fn.apply(this, args)
+      }
+      lastCallTime = currentTime
+      return ret
+    }
+  } else if (!isImmediateCall && isRememberLastCall) {
+    return function (...args) {
+      if (timer) {
+        clearTimeout(timer)
+        timer = null
+      }
+      if (retPromiseLastTimeResolver) {
+        retPromiseLastTimeResolver('canceled')
+        retPromiseLastTimeResolver = null
+      }
+      const ret = new Promise((resolve, reject) => {
+        retPromiseLastTimeResolver = resolve
+        timer = setTimeout(() => {
+          timer = null
+          retPromiseLastTimeResolver = null
+          resolve(fn.apply(this, args))
+        }, delay)
+      })
+      return ret
+    }
+  } else if (isImmediateCall && isRememberLastCall) {
+    return function (...args) {
+      const currentTime = Date.now()
+      if (currentTime - lastCallTime >= delay) { // 一组操作中的第一次
+        const res = fn.apply(this, args) 
+        lastCallTime = currentTime
+        return Promise.resolve(res)
+      } else { // 一组中的后续调用
+        if (timer) { // 在此之前存在中间调用
+          lastCallTime = currentTime
+          clearTimeout(timer)
+          timer = null
+        }
+        if (retPromiseLastTimeResolver) {
+          retPromiseLastTimeResolver('canceled')
+          retPromiseLastTimeResolver = null
+        }
+        const ret = new Promise((resolve, reject) => {
+          retPromiseLastTimeResolver = resolve
+          timer = setTimeout(() => {
+            lastCallTime = 0
+            timer = null
+            retPromiseLastTimeResolver = null
+            resolve(fn.apply(this, args))
+          }, delay)
+        })
+        return ret
+      }
+    }
+  } else {
+    console.error('不应该执行到这里!')
+  }
+}
+
+export default {
+  debounce,
 }

+ 37 - 0
yfyc/src/utils/request.js

@@ -0,0 +1,37 @@
+import axios from 'axios'
+const service = axios.create({
+  baseURL: process.env.NODE_ENV === 'development' ? 'http://192.168.20.55:8037/api' : '',
+  // baseURL: process.env.NODE_ENV === 'development' ? 'https://hnbwg.4dage.com/api' : '',
+  timeout: 5000
+})
+// 请求拦截器
+service.interceptors.request.use(function (config) {
+  // console.log('触发拦截器')
+  // 在发送请求之前做些什么:看看有没有token,如果有通过请求头的方式传递token
+  const token = localStorage.getItem('YFYC_token')
+  if (token) { // 判断是否有token,有,则
+    // config.headers['Authorization'] = token
+    config.headers.token = token
+  }
+
+  return config
+}, function (error) {
+  // 对请求错误做些什么
+  return Promise.reject(error)
+})
+
+// 添加响应拦截器
+service.interceptors.response.use(function (response) {
+  // console.log('触发相应拦截器', response)
+  // 对响应数据做点什么--response就是发送每个请求的返回值
+  if (response.data.code === 5001 || response.data.code === 5002) {
+    // Toast.fail('未登录,请先登录')
+    localStorage.removeItem('YFYC_token')
+  }
+  return response.data
+}, function (error) {
+  // 对响应错误做点什么
+  return Promise.reject(error)
+})
+
+export default service

+ 17 - 6
yfyc/src/views/Construct/components/HomeList.vue

@@ -21,7 +21,7 @@
         v-for="item in dataShow"
         :key="item.id"
       >
-        <img :src="require(`@/assets/img/home/${item.id}.png`)" alt="" />
+        <img :src="require(`@/assets/img/home/${item.id}.jpg`)" alt="" />
         <div class="name">{{ item.name }}</div>
         <div class="loc">
           <img src="../../../assets/img/home/loc.png" alt="" />
@@ -53,10 +53,21 @@ export default {
     return {
       txt: "",
       data: [
-        { id: 1, name: "鸠兹古镇", loction: "芜湖城东政务新区" },
-        { id: 2, name: "芜湖老海关", loction: "芜湖市新芜区滨江北路" },
-        { id: 3, name: "方特梦幻王国万圣夜", loction: "镜湖区银湖北路" },
-        { id: 4, name: "中江塔", loction: "芜湖市镜湖区滨江路桥口" },
+        { id: 1, name: "老芜湖海关旧址", loction: "滨江公园内" },
+        { id: 2, name: "英驻芜领事署旧址", loction: "范罗山" },
+        { id: 3, name: "总税务司公所旧址", loction: "范罗山" },
+        { id: 4, name: "洋员帮办楼旧址", loction: "范罗山" },
+        { id: 5, name: "英驻芜领事官邸旧址", loction: "吉和南路 26 号雨耕山顶" },
+        { id: 6, name: "大教堂", loction: "吉和街28 号" },
+        { id: 7, name: "神父楼", loction: "吉和街28 号" },
+        { id: 8, name: "天主教主教公署旧址", loction: "狮子山马路39号" },
+        { id: 9, name: "圣母院旧址", loction: "狮子山马路39号" },
+        { id: 10, name: "天主教修士楼", loction: "大官山顶" },
+        { id: 11, name: "内思高级工业职业学校旧址", loction: "吉和街26号" },
+        { id: 12, name: "博仁堂", loction: "安师大附属外国语学校中学内" },
+        { id: 13, name: "义德堂", loction: "安师大附属外国语学校中学内" },
+        { id: 14, name: "经方堂", loction: "安师大附属外国语学校中学内" },
+        { id: 15, name: "广济寺塔", loction: "广济寺内" },
       ],
       dataShow: [],
       videoShow: false,
@@ -85,7 +96,7 @@ export default {
   },
   methods: {
     handlClick(id) {
-      if (id === 2) this.videoShow = true;
+      if (id === 1) this.videoShow = true;
       else return Toast("敬请期待!");
     },
     // 获取列表的方法

+ 26 - 5
yfyc/src/views/Construct/index.vue

@@ -32,11 +32,11 @@
             <div
               class="swiper-slide"
               @click="handlClick"
-              v-for="i in 5"
-              :key="i"
+              v-for="item in data"
+              :key="item.id"
             >
-              <img src="../../assets/img/construct/sw1.png" alt="" />
-              <p>芜湖老海关{{ i }}</p>
+              <img :src="require(`@/assets/img/home/${item.id}.jpg`)" alt="" />
+              <p>{{ item.name }}</p>
             </div>
           </div>
         </div>
@@ -65,6 +65,27 @@ export default {
     return {
       vrShow: false,
       searchShow: false,
+      data: [
+        { id: 1, name: "老芜湖海关旧址", loction: "滨江公园内" },
+        { id: 2, name: "英驻芜领事署旧址", loction: "范罗山" },
+        { id: 3, name: "总税务司公所旧址", loction: "范罗山" },
+        { id: 4, name: "洋员帮办楼旧址", loction: "范罗山" },
+        {
+          id: 5,
+          name: "英驻芜领事官邸旧址",
+          loction: "吉和南路 26 号雨耕山顶",
+        },
+        { id: 6, name: "大教堂", loction: "吉和街28 号" },
+        { id: 7, name: "神父楼", loction: "吉和街28 号" },
+        { id: 8, name: "天主教主教公署旧址", loction: "狮子山马路39号" },
+        { id: 9, name: "圣母院旧址", loction: "狮子山马路39号" },
+        { id: 10, name: "天主教修士楼", loction: "大官山顶" },
+        { id: 11, name: "内思高级工业职业学校旧址", loction: "吉和街26号" },
+        { id: 12, name: "博仁堂", loction: "安师大附属外国语学校中学内" },
+        { id: 13, name: "义德堂", loction: "安师大附属外国语学校中学内" },
+        { id: 14, name: "经方堂", loction: "安师大附属外国语学校中学内" },
+        { id: 15, name: "广济寺塔", loction: "广济寺内" },
+      ],
     };
   },
   computed: {},
@@ -80,7 +101,7 @@ export default {
       slidesPerView: 1.4,
       spaceBetween: 30,
       centeredSlides: true,
-      initialSlide: 1,
+      initialSlide: 0,
     });
   },
   beforeCreate() {}, //生命周期 - 创建之前

+ 23 - 26
yfyc/src/views/Interact/index.vue

@@ -49,6 +49,7 @@
 </template>
 
 <script>
+import {getCodeAPI} from '@/api/interact.js'
 export default {
   components: {},
   data() {
@@ -79,21 +80,25 @@ export default {
   watch: {},
   methods: {
     // 点击+号
-    addInteract() {
-      this.$router.push("/layout/interact/issue");
-      // let code = this.getQueryString("code");
-      // if (code) this.$router.push("/layout/interact/issue");
-      // else {
-      //   //此处的ID是在文档的开发-基本配置里面
-      //   let appid = "wx779dbafb46bab697";
-      //   let url = "http://192.168.20.48:8080/#/layout/interact";
-      //   window.location.href =
-      //     "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" +
-      //     appid +
-      //     "&redirect_uri=" +
-      //     url +
-      //     "&response_type=code&scope=snsapi_userinfo&state=bc17befd6d5060f16de95e38f6eaf69c&connect_redirect=1#wechat_redirect";
-      // }
+   async addInteract() {
+      let code = this.getQueryCode();
+      if (code) {
+        let res =await getCodeAPI(code)
+        console.log('-----',res);
+        // this.$router.push("/layout/interact/issue");
+        }
+      else {
+        //此处的ID是在文档的开发-基本配置里面
+        let appid = "wx3255043d1b21a4f7";
+        // let url = "http://192.168.20.48:8080/#/layout/interact";
+        let url = "https://tp.wuhu.12301china.com/vote";
+        window.location.href =
+          "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" +
+          appid +
+          "&redirect_uri=" +
+          encodeURIComponent(url) +
+          "&response_type=code&scope=snsapi_userinfo&state=bc17befd6d5060f16de95e38f6eaf69c&connect_redirect=1#wechat_redirect";
+      }
     },
     searchFu() {
       this.getList();
@@ -105,23 +110,15 @@ export default {
         this.dataShow = this.spotData.filter((v) => v.name.includes(this.txt));
     },
     // 获取地址栏参数的方法
-    getQueryString(name) {
-      var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
-      var r = window.location.search.substr(1).match(reg); //获取url中"?"符后的字符串并正则匹配
-      var context = "";
-      if (r != null) context = r[2];
-      reg = null;
-      r = null;
-      return context == null || context == "" || context == "undefined"
-        ? ""
-        : context;
+    getQueryCode() {
+      return this.$route.query.code?this.$route.query.code:''
     },
   },
   created() {
     document.querySelector("#app").style.maxWidth = "500px";
 
     this.getList();
-    let code = this.getQueryString("code");
+    let code = this.getQueryCode();
     console.log("---------", code);
   },
   mounted() {},

+ 129 - 129
yfyc/src/views/My/Feedback.vue

@@ -1,130 +1,130 @@
-<template>
-  <div class="feedback">
-    <div class="text-card card">
-      <div class="title-bar bar">
-        <div class="key">主题:</div>
-        <input type="text">
-      </div>
-      <textarea name="" id="" rows="8" minlength="10" maxlength="150"
-        placeholder="请填写10个字以上的描述,以便我们提供更好的帮助。"
-      ></textarea>
-    </div>
-
-    <div class="photo-card card">
-      <div class="key">
-        截图 0 / 4
-      </div>
-      <button class="input-photo">
-        <img class="" src="@/assets/img/my/camera.png" alt="" draggable="false">
-      </button>
-      <div class="phone-bar bar">
-        <div class="key">联系方式</div>
-        <input type="text" placeholder="手机号 / 邮箱">
-      </div>
-    </div>
-
-    <button class="submit">
-      <img class="" src="@/assets/img/my/submit.png" alt="" draggable="false">
-    </button>
-  </div>
-</template>
-
-<script>
-export default {
-  data() {
-    return {
-      
-    }
-  },
-}
-</script>
-
-<style lang="less" scoped>
-.feedback {
-  background: #F5F5F5;
-  height: calc(100% - 80px);
-  overflow: auto;
-  position: relative;
-  > .card {
-    background-color: #fff;
-    margin-top: 3.2vw;
-    padding: 5vw 4.5vw 5.5vw 4.5vw;
-  }
-  .key {
-    font-size: 3.5vw;
-    font-weight: bold;
-    color: #000000;
-    line-height: 4vw;
-    margin-right: 5.3vw;
-  }
-  .bar {
-    display: flex;
-    align-items: center;
-    padding-bottom: 2.5vw;
-    border-bottom: 0.3vw solid #DCDCDC;
-  }
-  input {
-    font-size: 3.2vw;
-    color: #000000;
-    line-height: 4vw;
-  }
-
-  .text-card {
-    .title-bar {
-      .key {
-        flex: 0 0 auto;
-      }
-      input.text {
-        flex: 1 0 1px;
-      }
-    }
-    > textarea {
-      margin-top: 2.8vw;
-      width: 100%;
-      border: none;
-      resize: none;
-    }
-  }
-
-  .photo-card {
-    .key {
-    }
-    > button.input-photo {
-      margin-top: 2.8vw;
-      width: 15.5vw;
-      height: 15.5vw;
-      background: #f0f2f5;
-      border-radius: 1.3vw;
-      display: flex;
-      justify-content: center;
-      align-items: center;
-      > img {
-        width: 6.0vw;
-        height: 4.7vw;
-      }
-    }
-    .phone-bar {
-      margin-top: 13.6vw;
-      .key {
-        flex: 0 0 auto;
-      }
-      > input.text {
-        flex: 1 0 1px;
-      }
-    }
-  }
-
-  > button.submit {
-    position: absolute;
-    left: 50%;
-    bottom: 9.5vw;
-    transform: translateX(-50%);
-    width: 42.7vw;
-    height: 8vw;
-    > img {
-      width: 100%;
-      height: 100%;
-    }
-  }
-}
+<template>
+  <div class="feedback">
+    <div class="text-card card">
+      <div class="title-bar bar">
+        <div class="key">主题:</div>
+        <input type="text">
+      </div>
+      <textarea name="" id="" rows="8" minlength="10" maxlength="150"
+        placeholder="请填写10个字以上的描述,以便我们提供更好的帮助。"
+      ></textarea>
+    </div>
+
+    <div class="photo-card card">
+      <div class="key">
+        截图 0 / 4
+      </div>
+      <button class="input-photo">
+        <img class="" src="@/assets/img/my/camera.png" alt="" draggable="false">
+      </button>
+      <div class="phone-bar bar">
+        <div class="key">联系方式</div>
+        <input type="text" placeholder="手机号 / 邮箱">
+      </div>
+    </div>
+
+    <button class="submit">
+      <img class="" src="@/assets/img/my/submit.png" alt="" draggable="false">
+    </button>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      
+    }
+  },
+}
+</script>
+
+<style lang="less" scoped>
+.feedback {
+  background: #F5F5F5;
+  height: calc(100% - 80px);
+  overflow: auto;
+  position: relative;
+  > .card {
+    background-color: #fff;
+    margin-top: 3.2vw;
+    padding: 5vw 4.5vw 5.5vw 4.5vw;
+  }
+  .key {
+    font-size: 3.5vw;
+    font-weight: bold;
+    color: #000000;
+    line-height: 4vw;
+    margin-right: 5.3vw;
+  }
+  .bar {
+    display: flex;
+    align-items: center;
+    padding-bottom: 2.5vw;
+    border-bottom: 0.3vw solid #DCDCDC;
+  }
+  input {
+    font-size: 3.2vw;
+    color: #000000;
+    line-height: 4vw;
+  }
+
+  .text-card {
+    .title-bar {
+      .key {
+        flex: 0 0 auto;
+      }
+      input.text {
+        flex: 1 0 1px;
+      }
+    }
+    > textarea {
+      margin-top: 2.8vw;
+      width: 100%;
+      border: none;
+      resize: none;
+    }
+  }
+
+  .photo-card {
+    .key {
+    }
+    > button.input-photo {
+      margin-top: 2.8vw;
+      width: 15.5vw;
+      height: 15.5vw;
+      background: #f0f2f5;
+      border-radius: 1.3vw;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      > img {
+        width: 6.0vw;
+        height: 4.7vw;
+      }
+    }
+    .phone-bar {
+      margin-top: 13.6vw;
+      .key {
+        flex: 0 0 auto;
+      }
+      > input.text {
+        flex: 1 0 1px;
+      }
+    }
+  }
+
+  > button.submit {
+    position: absolute;
+    left: 50%;
+    bottom: 9.5vw;
+    transform: translateX(-50%);
+    width: 42.7vw;
+    height: 8vw;
+    > img {
+      width: 100%;
+      height: 100%;
+    }
+  }
+}
 </style>

+ 207 - 207
yfyc/src/views/My/MyBookings.vue

@@ -1,208 +1,208 @@
-<template>
-  <div class="my-bookings">
-    <TabbarSmall :tabList="['全部', '活动中', '未开始', '已结束']" @change="onTabbarChange"></TabbarSmall>
-    <div class="booking-list">
-      <article
-        v-for="(item, index) in bookingList"
-        :key="index"
-        :class="{
-          disabled: !item.isActive,
-        }"
-      >
-        <div class="top-bar">
-          <div class="first-line">
-            <h2>{{item.name}}</h2>
-            <button><span>查看</span><span>→</span></button>
-          </div>
-          <div class="time-line">
-            申请时间:{{item.date}} {{item.time}}
-          </div>
-        </div>
-        <div class="rest">
-          <div class="line">
-            <img class="icon" src="@/assets/img/service/date.png" alt="" draggable="false">
-            <div class="text">
-              <span class="key">参观日期:</span>
-              <span class="value">{{item.date}}</span>
-            </div>
-          </div>
-          <div class="line">
-            <img class="icon" src="@/assets/img/service/time.png" alt="" draggable="false">
-            <div class="text">
-              <span class="key">参观时段:</span>
-              <span class="value">{{item.time}}</span>
-            </div>
-          </div>
-          <div class="line">
-            <img class="icon" src="@/assets/img/service/people.png" alt="" draggable="false">
-            <div class="text">
-              <span class="key">参观人数:</span>
-              <span class="value">{{item.peopleNum}}人</span>
-            </div>
-          </div>
-          <button class="submit">
-            {{item.isActive ? '取消预约' : '已结束'}}
-          </button>
-        </div>
-      </article>
-    </div>
-  </div>
-</template>
-
-<script>
-import TabbarSmall from "@/components/TabbarSmall.vue";
-
-export default {
-  components: {
-    TabbarSmall,
-  },
-  data() {
-    return {
-      activeTabbarIdx: 0,
-      bookingList: [
-        {
-          name: '赭山风景区',
-          date: '2022-05-04 周六',
-          time: '10:00-11:00',
-          peopleNum: 1,
-          isActive: true,
-        },
-        {
-          name: '赭山风景区',
-          date: '2022-05-04 周六',
-          time: '10:00-11:00',
-          peopleNum: 1,
-          isActive: false,
-        },
-        {
-          name: '赭山风景区',
-          date: '2022-05-04 周六',
-          time: '10:00-11:00',
-          peopleNum: 1,
-          isActive: true,
-        },
-      ],
-    }
-  },
-  methods: {
-    onTabbarChange(idx) {
-      this.activeTabbarIdx = idx
-    }
-  }
-}
-</script>
-
-<style lang="less" scoped>
-.my-bookings {
-  background: #F5F5F5;
-  height: calc(100% - 80px);
-  overflow: auto;
-  position: relative;
-  padding: 0 4.5vw;
-  /deep/.tabbar-small {
-    > ul {
-      justify-content: space-between;
-    }
-  }
-
-  .booking-list {
-    > article.disabled {
-      > .top-bar {
-        background: #8E8E8E;
-      }
-      > .rest {
-        > button.submit {
-          background: #8E8E8E;
-        }
-      }
-    }
-    > article {
-      margin-top: 5vw;
-      margin-bottom: 5vw;
-      height: 56.8vw;
-      background: #FFFFFF;
-      box-shadow: 0px 16px 36px 0px rgba(0,0,0,0.1);
-      border-radius: 1.3vw;
-      overflow: hidden;
-      position: relative;
-      .line {
-        display: flex;
-        align-items: flex-end;
-        margin-top: 4.5vw;
-        .icon {
-          width: 4.3vw;
-          height: 4.3vw;
-          margin-right: 2.4vw;
-        }
-        .key {
-          font-size: 3.2vw;
-          font-weight: bold;
-          color: #222222;
-        }
-        .value {
-          font-size: 3.2vw;
-          color: #222222;
-        }
-      }
-
-      > .top-bar {
-        background: linear-gradient(130deg, #FF615C 0%, #FF9877 100%);
-        padding: 5.1vw 3.7vw 5.1vw;
-        > .first-line {
-          display: flex;
-          align-items: center;
-          justify-content: space-between;
-          > h2 {
-            font-size: 4.8vw;
-            font-weight: 600;
-            color: #FFFFFF;
-          }
-          > button {
-            padding-top: 1vw;
-            padding-bottom: 1vw;
-            font-size: 4vw;
-            color: #FFFFFF;
-            > span:nth-of-type(2) {
-              vertical-align: 0.2vw;
-            }
-          }
-        }
-        > .time-line {
-          margin-top: 2.7vw;
-          font-size: 3.2vw;
-          font-weight: 400;
-          color: #FFFFFF;
-        }
-      }
-      > .rest {
-        padding-left: 3.7vw;
-        padding-right: 3.7vw;
-        display: flex;
-        flex-direction: column;
-        justify-content: space-evenly;
-        > .line {
-          > img.icon {
-          }
-          > .text {
-            > .key {
-            }
-            > .value {
-            }
-          }
-        }
-        > button.submit {
-          position: absolute;
-          width: 21.6vw;
-          height: 6.4vw;
-          background: linear-gradient(130deg, #FF615C 0%, #FF9877 100%);
-          border-radius: 0.5vw;
-          bottom: 5.6vw;
-          right: 4vw;
-          font-size: 3.2vw;
-          color: #FFFFFF;
-        }
-      }
-    }
-  }
-}
+<template>
+  <div class="my-bookings">
+    <TabbarSmall :tabList="['全部', '活动中', '未开始', '已结束']" @change="onTabbarChange"></TabbarSmall>
+    <div class="booking-list">
+      <article
+        v-for="(item, index) in bookingList"
+        :key="index"
+        :class="{
+          disabled: !item.isActive,
+        }"
+      >
+        <div class="top-bar">
+          <div class="first-line">
+            <h2>{{item.name}}</h2>
+            <button><span>查看</span><span>→</span></button>
+          </div>
+          <div class="time-line">
+            申请时间:{{item.date}} {{item.time}}
+          </div>
+        </div>
+        <div class="rest">
+          <div class="line">
+            <img class="icon" src="@/assets/img/service/date.png" alt="" draggable="false">
+            <div class="text">
+              <span class="key">参观日期:</span>
+              <span class="value">{{item.date}}</span>
+            </div>
+          </div>
+          <div class="line">
+            <img class="icon" src="@/assets/img/service/time.png" alt="" draggable="false">
+            <div class="text">
+              <span class="key">参观时段:</span>
+              <span class="value">{{item.time}}</span>
+            </div>
+          </div>
+          <div class="line">
+            <img class="icon" src="@/assets/img/service/people.png" alt="" draggable="false">
+            <div class="text">
+              <span class="key">参观人数:</span>
+              <span class="value">{{item.peopleNum}}人</span>
+            </div>
+          </div>
+          <button class="submit">
+            {{item.isActive ? '取消预约' : '已结束'}}
+          </button>
+        </div>
+      </article>
+    </div>
+  </div>
+</template>
+
+<script>
+import TabbarSmall from "@/components/TabbarSmall.vue";
+
+export default {
+  components: {
+    TabbarSmall,
+  },
+  data() {
+    return {
+      activeTabbarIdx: 0,
+      bookingList: [
+        {
+          name: '赭山风景区',
+          date: '2022-05-04 周六',
+          time: '10:00-11:00',
+          peopleNum: 1,
+          isActive: true,
+        },
+        {
+          name: '赭山风景区',
+          date: '2022-05-04 周六',
+          time: '10:00-11:00',
+          peopleNum: 1,
+          isActive: false,
+        },
+        {
+          name: '赭山风景区',
+          date: '2022-05-04 周六',
+          time: '10:00-11:00',
+          peopleNum: 1,
+          isActive: true,
+        },
+      ],
+    }
+  },
+  methods: {
+    onTabbarChange(idx) {
+      this.activeTabbarIdx = idx
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.my-bookings {
+  background: #F5F5F5;
+  height: calc(100% - 80px);
+  overflow: auto;
+  position: relative;
+  padding: 0 4.5vw;
+  /deep/.tabbar-small {
+    > ul {
+      justify-content: space-between;
+    }
+  }
+
+  .booking-list {
+    > article.disabled {
+      > .top-bar {
+        background: #8E8E8E;
+      }
+      > .rest {
+        > button.submit {
+          background: #8E8E8E;
+        }
+      }
+    }
+    > article {
+      margin-top: 5vw;
+      margin-bottom: 5vw;
+      height: 56.8vw;
+      background: #FFFFFF;
+      box-shadow: 0px 16px 36px 0px rgba(0,0,0,0.1);
+      border-radius: 1.3vw;
+      overflow: hidden;
+      position: relative;
+      .line {
+        display: flex;
+        align-items: flex-end;
+        margin-top: 4.5vw;
+        .icon {
+          width: 4.3vw;
+          height: 4.3vw;
+          margin-right: 2.4vw;
+        }
+        .key {
+          font-size: 3.2vw;
+          font-weight: bold;
+          color: #222222;
+        }
+        .value {
+          font-size: 3.2vw;
+          color: #222222;
+        }
+      }
+
+      > .top-bar {
+        background: linear-gradient(130deg, #FF615C 0%, #FF9877 100%);
+        padding: 5.1vw 3.7vw 5.1vw;
+        > .first-line {
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+          > h2 {
+            font-size: 4.8vw;
+            font-weight: 600;
+            color: #FFFFFF;
+          }
+          > button {
+            padding-top: 1vw;
+            padding-bottom: 1vw;
+            font-size: 4vw;
+            color: #FFFFFF;
+            > span:nth-of-type(2) {
+              vertical-align: 0.2vw;
+            }
+          }
+        }
+        > .time-line {
+          margin-top: 2.7vw;
+          font-size: 3.2vw;
+          font-weight: 400;
+          color: #FFFFFF;
+        }
+      }
+      > .rest {
+        padding-left: 3.7vw;
+        padding-right: 3.7vw;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-evenly;
+        > .line {
+          > img.icon {
+          }
+          > .text {
+            > .key {
+            }
+            > .value {
+            }
+          }
+        }
+        > button.submit {
+          position: absolute;
+          width: 21.6vw;
+          height: 6.4vw;
+          background: linear-gradient(130deg, #FF615C 0%, #FF9877 100%);
+          border-radius: 0.5vw;
+          bottom: 5.6vw;
+          right: 4vw;
+          font-size: 3.2vw;
+          color: #FFFFFF;
+        }
+      }
+    }
+  }
+}
 </style>

+ 194 - 194
yfyc/src/views/Serve/DontMiss.vue

@@ -1,195 +1,195 @@
-<template>
-  <div class="dont-miss">
-    <SearchBar class="search-bar" @search="onSearch"></SearchBar>
-    <div class="select-wrap">
-      <Select
-        class="select"
-        :valueList="typeList"
-        v-model="typeIdx"
-        :placeholder="'分类'"
-      ></Select>
-      <Select
-        class="select"
-        v-model="areaIdx"
-        :valueList="areaList"
-        :placeholder="'区域'"
-      ></Select>
-    </div>
-    <div class="card-wrap">
-      <article
-        v-for="(item, index) in attractionList"
-        :key="index"
-      >
-        <img :src="item.img" alt="" draggable="false">
-        <h2>{{item.title}}</h2>
-        <div class="location">
-          <img class="icon" src="@/assets/img/service/address.png" alt="" draggable="false">
-          <span>{{item.location}}</span>
-        </div>
-      </article>
-    </div>
-  </div>
-</template>
-
-<script>
-import SearchBar from "@/components/SearchRedBtn.vue";
-import Select from "@/components/Select.vue";
-
-export default {
-  components: {
-    SearchBar,
-    Select,
-  },
-  data() {
-    return {
-      typeIdx: 0,
-      areaIdx: 0,
-      attractionList: [
-        {
-          img: require(`@/assets/img/service/【西洋建筑】.png`),
-          title: '芜湖老海关',
-          location: '芜湖市新芜区滨江北路',
-        },
-        {
-          img: require(`@/assets/img/service/【西洋建筑】.png`),
-          title: '芜湖老海关',
-          location: '芜湖市新芜区滨江北路',
-        },
-        {
-          img: require(`@/assets/img/service/【西洋建筑】.png`),
-          title: '芜湖老海关',
-          location: '芜湖市新芜区滨江北路',
-        },
-        {
-          img: require(`@/assets/img/service/【西洋建筑】.png`),
-          title: '芜湖老海关',
-          location: '芜湖市新芜区滨江北路',
-        },
-        {
-          img: require(`@/assets/img/service/【西洋建筑】.png`),
-          title: '芜湖老海关',
-          location: '芜湖市新芜区滨江北路',
-        },
-        {
-          img: require(`@/assets/img/service/【西洋建筑】.png`),
-          title: '芜湖老海关',
-          location: '芜湖市新芜区滨江北路',
-        },
-        {
-          img: require(`@/assets/img/service/【西洋建筑】.png`),
-          title: '芜湖老海关',
-          location: '芜湖市新芜区滨江北路',
-        },
-        {
-          img: require(`@/assets/img/service/【西洋建筑】.png`),
-          title: '芜湖老海关',
-          location: '芜湖市新芜区滨江北路',
-        },
-      ],
-    }
-  },
-  computed: {
-    typeList() {
-      return [
-        '全部',
-        '分类一',
-        '分类二',
-        '分类三',
-      ]
-    },
-    areaList() {
-      return [
-        '全部',
-        '镜湖区',
-        '弋江区',
-        '鸠江区',
-        '繁昌区',
-      ]
-    },
-  },
-  methods: {
-    onSearch() {
-
-    },
-  }
-}
-</script>
-
-<style lang="less" scoped>
-.dont-miss {
-  background-color: #fff;
-  height: calc(100% - 80px);
-  overflow: auto;
-  padding: 3.3vw 4.5vw 4.5vw 4.5vw;
-  display: flex;
-  flex-direction: column;
-  > .search-bar {
-    flex: 0 0 auto;
-  }
-  > .select-wrap {
-    flex: 0;
-    margin: 3.5vw 0 4vw 0;
-    > .select {
-      width: 15vw;
-      display: inline-block;
-      margin-right: 12.5vw;
-    }
-  }
-  > .card-wrap {
-    flex: 1 0 1px;
-    overflow: auto;
-    margin-right: -4vw;
-    > article {
-      width: 43.6vw;
-      height: 62.7vw;
-      display: inline-block;
-      background: #F7F8FA;
-      border-radius: 1.1vw;
-      overflow: hidden;
-      margin-right: 3.5vw;
-      margin-bottom: 4vw;
-      > img {
-        width: 100%;
-        height: 44.5vw;
-        object-fit: cover;
-        margin-right: 1.7vw;
-      }
-      > h2 {
-        font-size: 3.2vwx;
-        font-family: Source Han Serif CN;
-        font-weight: bold;
-        color: #333333;
-        line-height: 40px;
-        margin-left: 2.3vw;
-        margin-right: 2.3vw;
-        margin-bottom: 4.4vw;
-        font-size: 3.2vw;
-        font-weight: bold;
-        color: #333333;
-        line-height: 4vw;
-        overflow: hidden;
-        white-space: pre;
-        text-overflow: ellipsis;
-      }
-      > .location {
-        margin-left: 2.3vw;
-        margin-right: 2.3vw;
-        display: flex;
-        align-items: center;
-        > img {
-          width: 3.2vw;
-          height: 3.2vw;
-          margin-right: 1.1vw;
-        }
-        > span {
-          font-size: 2.7vw;
-          color: #333333;
-          overflow: hidden;
-          white-space: pre;
-          text-overflow: ellipsis;
-        }
-      }
-    }
-  }
-}
+<template>
+  <div class="dont-miss">
+    <SearchBar class="search-bar" @search="onSearch"></SearchBar>
+    <div class="select-wrap">
+      <Select
+        class="select"
+        :valueList="typeList"
+        v-model="typeIdx"
+        :placeholder="'分类'"
+      ></Select>
+      <Select
+        class="select"
+        v-model="areaIdx"
+        :valueList="areaList"
+        :placeholder="'区域'"
+      ></Select>
+    </div>
+    <div class="card-wrap">
+      <article
+        v-for="(item, index) in attractionList"
+        :key="index"
+      >
+        <img :src="item.img" alt="" draggable="false">
+        <h2>{{item.title}}</h2>
+        <div class="location">
+          <img class="icon" src="@/assets/img/service/address.png" alt="" draggable="false">
+          <span>{{item.location}}</span>
+        </div>
+      </article>
+    </div>
+  </div>
+</template>
+
+<script>
+import SearchBar from "@/components/SearchRedBtn.vue";
+import Select from "@/components/Select.vue";
+
+export default {
+  components: {
+    SearchBar,
+    Select,
+  },
+  data() {
+    return {
+      typeIdx: 0,
+      areaIdx: 0,
+      attractionList: [
+        {
+          img: require(`@/assets/img/service/【西洋建筑】.png`),
+          title: '芜湖老海关',
+          location: '芜湖市新芜区滨江北路',
+        },
+        {
+          img: require(`@/assets/img/service/【西洋建筑】.png`),
+          title: '芜湖老海关',
+          location: '芜湖市新芜区滨江北路',
+        },
+        {
+          img: require(`@/assets/img/service/【西洋建筑】.png`),
+          title: '芜湖老海关',
+          location: '芜湖市新芜区滨江北路',
+        },
+        {
+          img: require(`@/assets/img/service/【西洋建筑】.png`),
+          title: '芜湖老海关',
+          location: '芜湖市新芜区滨江北路',
+        },
+        {
+          img: require(`@/assets/img/service/【西洋建筑】.png`),
+          title: '芜湖老海关',
+          location: '芜湖市新芜区滨江北路',
+        },
+        {
+          img: require(`@/assets/img/service/【西洋建筑】.png`),
+          title: '芜湖老海关',
+          location: '芜湖市新芜区滨江北路',
+        },
+        {
+          img: require(`@/assets/img/service/【西洋建筑】.png`),
+          title: '芜湖老海关',
+          location: '芜湖市新芜区滨江北路',
+        },
+        {
+          img: require(`@/assets/img/service/【西洋建筑】.png`),
+          title: '芜湖老海关',
+          location: '芜湖市新芜区滨江北路',
+        },
+      ],
+    }
+  },
+  computed: {
+    typeList() {
+      return [
+        '全部',
+        '分类一',
+        '分类二',
+        '分类三',
+      ]
+    },
+    areaList() {
+      return [
+        '全部',
+        '镜湖区',
+        '弋江区',
+        '鸠江区',
+        '繁昌区',
+      ]
+    },
+  },
+  methods: {
+    onSearch() {
+
+    },
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.dont-miss {
+  background-color: #fff;
+  height: calc(100% - 80px);
+  overflow: auto;
+  padding: 3.3vw 4.5vw 4.5vw 4.5vw;
+  display: flex;
+  flex-direction: column;
+  > .search-bar {
+    flex: 0 0 auto;
+  }
+  > .select-wrap {
+    flex: 0;
+    margin: 3.5vw 0 4vw 0;
+    > .select {
+      width: 15vw;
+      display: inline-block;
+      margin-right: 12.5vw;
+    }
+  }
+  > .card-wrap {
+    flex: 1 0 1px;
+    overflow: auto;
+    margin-right: -4vw;
+    > article {
+      width: 43.6vw;
+      height: 62.7vw;
+      display: inline-block;
+      background: #F7F8FA;
+      border-radius: 1.1vw;
+      overflow: hidden;
+      margin-right: 3.5vw;
+      margin-bottom: 4vw;
+      > img {
+        width: 100%;
+        height: 44.5vw;
+        object-fit: cover;
+        margin-right: 1.7vw;
+      }
+      > h2 {
+        font-size: 3.2vwx;
+        font-family: Source Han Serif CN;
+        font-weight: bold;
+        color: #333333;
+        line-height: 40px;
+        margin-left: 2.3vw;
+        margin-right: 2.3vw;
+        margin-bottom: 4.4vw;
+        font-size: 3.2vw;
+        font-weight: bold;
+        color: #333333;
+        line-height: 4vw;
+        overflow: hidden;
+        white-space: pre;
+        text-overflow: ellipsis;
+      }
+      > .location {
+        margin-left: 2.3vw;
+        margin-right: 2.3vw;
+        display: flex;
+        align-items: center;
+        > img {
+          width: 3.2vw;
+          height: 3.2vw;
+          margin-right: 1.1vw;
+        }
+        > span {
+          font-size: 2.7vw;
+          color: #333333;
+          overflow: hidden;
+          white-space: pre;
+          text-overflow: ellipsis;
+        }
+      }
+    }
+  }
+}
 </style>

+ 312 - 312
yfyc/src/views/Serve/FoodDetail.vue

@@ -1,313 +1,313 @@
-<template>
-  <div class="food-detail">
-    <img src="@/assets/img/my/food-detail-banner-bg.png" alt="" class="banner-bg">
-    <div class="banner-card">
-      <h2>美食店铺名称(仁和新街点)</h2>
-      <div class="star">
-        <img
-          v-for="n in 5"
-          :key="n"
-          src="@/assets/img/service/star.png" alt="" class="star"
-        >
-        5
-      </div>
-      <div class="tag-list">
-        <div class="tag">
-          菜系标签
-        </div>
-        <div class="tag">
-          评价标签
-        </div>
-        <div class="tag">
-          其他标签
-        </div>
-      </div>
-      <img src="@/assets/img/service/food-detail-banner.png" alt="" class="shop-banner">
-      <div class="bottom-bar">
-        <div class="left">
-          <img src="@/assets/img/service/address-gray.png" alt="" class="icon">
-          <div class="address">鸠江区仁和路和兴街S12栋S110号</div>
-        </div>
-        <div class="right">
-          <button class="nav">
-            <img class="" src="@/assets/img/service/navigation-gray.png" alt="" draggable="false">
-            导航
-          </button>
-          <button class="phone">
-            <img class="" src="@/assets/img/service/phone-gray-2.png" alt="" draggable="false">
-            电话
-          </button>
-        </div>
-      </div>
-    </div>
-
-    <div class="content-card">
-      <div class="top-line">
-        <div class="title">推荐菜</div>
-        <button>
-          更多  》
-        </button>
-      </div>
-      <div class="swiper-container-food">
-        <div class="swiper-wrapper">
-          <div class="swiper-slide">
-            <img src="@/assets/img/service/【古建筑】.png" alt="">
-            <div class="title-wrap">
-              <h4>美食名称</h4>
-            </div>
-          </div>
-          <div class="swiper-slide">
-            <img src="@/assets/img/service/【快速浏览】.png" alt="">
-            <div class="title-wrap">
-              <h4>美食名称</h4>
-            </div>
-          </div>
-          <div class="swiper-slide">
-            <img src="@/assets/img/service/【西洋建筑】.png" alt="">
-            <div class="title-wrap">
-              <h4>美食名称</h4>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-
-    <div class="content-card">
-      <div class="top-line">
-        <div class="title">周边景点</div>
-        <button>
-          更多  》
-        </button>
-      </div>
-      <div class="swiper-container-attractions">
-        <div class="swiper-wrapper">
-          <div class="swiper-slide">
-            <img src="@/assets/img/service/【古建筑】.png" alt="">
-            <div class="title-wrap">
-              <h4>景点名称</h4>
-            </div>
-          </div>
-          <div class="swiper-slide">
-            <img src="@/assets/img/service/【快速浏览】.png" alt="">
-            <div class="title-wrap">
-              <h4>景点名称</h4>
-            </div>
-          </div>
-          <div class="swiper-slide">
-            <img src="@/assets/img/service/【西洋建筑】.png" alt="">
-            <div class="title-wrap">
-              <h4>景点名称</h4>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import Swiper from "../../assets/libs/swiper.js";
-
-export default {
-  mounted() {
-    this.$nextTick(() => {
-      new Swiper(".swiper-container-food", {
-        slidesPerView: 1.4,
-        spaceBetween: 15,
-        centeredSlides: true,
-      })
-    })
-
-    this.$nextTick(() => {
-      new Swiper(".swiper-container-attractions", {
-        slidesPerView: 2.3,
-        spaceBetween: 15,
-        centeredSlides: true,
-      })
-    })
-  }
-}
-</script>
-
-<style lang="less" scoped>
-@import "../../assets/libs/swiper.css";
-
-.food-detail {
-  position: relative;
-  height: calc(100% - 80px);
-  overflow: auto;
-  background: #F0F0F0;
-  z-index: 0;
-  
-  > img.banner-bg {
-    position: absolute;
-    top: 0;
-    width: 100%;
-    z-index: -1;
-  }
-  
-  > .banner-card {
-    background: #FFFFFF;
-    box-shadow: 0vw 0vw 0.9vw 0vw rgba(192,192,192,0.51);
-    border-radius: 1.3vw;
-    margin-top: 13.3vw;
-    margin-left: 2.8vw;
-    margin-right: 2.8vw;
-    padding: 3.5vw 3.2vw 3vw 3.2vw;
-    > h2 {
-      font-size: 4.8vw;
-      font-weight: bold;
-      color: #000000;
-      margin-bottom: 2.3vw;
-    }
-    > .star {
-      display: flex;
-      font-size: 3.2vw;
-      font-weight: bold;
-      color: #e6271d;
-      margin-bottom: 3vw;
-      > img.star {
-        width: 3vw;
-        height: 3vw;
-        margin-right: 1vw;
-      }
-    }
-    > .tag-list {
-      margin-bottom: 2.1vw;
-      > .tag {
-        padding-left: 2.3vw;
-        padding-right: 2.3vw;
-        padding-top: 1vw;
-        padding-bottom: 1vw;
-        display: inline-block;
-        background: #DDC49C;
-        border-radius: 0.5vw;
-        margin-right: 2.1vw;
-        font-size: 3.2vw;
-        font-weight: bold;
-        color: #483515;
-      }
-    }
-    > img.shop-banner {
-      width: 100%;
-      border-radius: 2.1vw;
-    }
-    > .bottom-bar {
-      margin-top: 3.3vw;
-      display: flex;
-      justify-content: space-between;
-      align-items: flex-end;
-      > .left {
-        > img.icon {
-          width: 3.1vw;
-          height: 3.9vw;
-          margin-right: 0.8vw;
-          vertical-align: middle;
-        }
-        > .address {
-          display: inline-block;
-          vertical-align: middle;
-          font-size: 3.5vw;
-          font-weight: bold;
-          color: #787878;
-        }
-      }
-      > .right {
-        > button {
-          font-size: 2.9vw;
-          font-weight: bold;
-          color: #787878;
-          display: inline-flex;
-          flex-direction: column;
-          align-items: center;
-          &:nth-of-type(1) {
-            margin-right: 5.5vw;
-          }
-          > img {
-            display: block;
-            width: 5.3vw;
-            height: 5.3vw;
-            margin-bottom: 0.8vw;
-          }
-        }
-      }
-    }
-  }
-
-  > .content-card {
-    background-color: #fff;
-    margin-top: 5vw;
-    padding-top: 6vw;
-    padding-bottom: 7.5vw;
-    > .top-line {
-      padding-left: 4.7vw;
-      padding-right: 4.7vw;
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      > .title {
-        font-size: 3.5vw;
-        font-weight: bold;
-        color: #000000;
-      }
-      > button {
-        font-size: 2.7vw;
-        font-weight: 600;
-        color: #333333;
-        padding-top: 1vw;
-        padding-bottom: 1vw;
-      }
-    }
-    > .swiper-container-food {
-      margin-top: 5vw;
-      overflow: hidden;
-      > .swiper-wrapper {
-        > .swiper-slide {
-          width: 82.8vw;
-          height: 53.2vw;
-          background: #F7F8FA;
-          > img {
-            width: 100%;
-            height: 40.7vw;
-            object-fit: cover;
-          }
-          > .title-wrap {
-            > h4 {
-              text-align: center;
-              margin-top: 4vw;
-              font-size: 3.2vw;
-              font-weight: bold;
-              color: #333333;
-            }
-          }
-        }
-      }
-    }
-    > .swiper-container-attractions {
-      margin-top: 5vw;
-      overflow: hidden;
-      > .swiper-wrapper {
-        > .swiper-slide {
-          width: 43.6vw;
-          height: 55vw;
-          background: #F7F8FA;
-          > img {
-            width: 100%;
-            height: 44.5vw;
-            object-fit: cover;
-          }
-          > .title-wrap {
-            > h4 {
-              text-align: center;
-              margin-top: 3vw;
-              font-size: 3.2vw;
-              font-weight: bold;
-              color: #333333;
-            }
-          }
-        }
-      }
-    }
-  }
-}
+<template>
+  <div class="food-detail">
+    <img src="@/assets/img/my/food-detail-banner-bg.png" alt="" class="banner-bg">
+    <div class="banner-card">
+      <h2>美食店铺名称(仁和新街点)</h2>
+      <div class="star">
+        <img
+          v-for="n in 5"
+          :key="n"
+          src="@/assets/img/service/star.png" alt="" class="star"
+        >
+        5
+      </div>
+      <div class="tag-list">
+        <div class="tag">
+          菜系标签
+        </div>
+        <div class="tag">
+          评价标签
+        </div>
+        <div class="tag">
+          其他标签
+        </div>
+      </div>
+      <img src="@/assets/img/service/food-detail-banner.png" alt="" class="shop-banner">
+      <div class="bottom-bar">
+        <div class="left">
+          <img src="@/assets/img/service/address-gray.png" alt="" class="icon">
+          <div class="address">鸠江区仁和路和兴街S12栋S110号</div>
+        </div>
+        <div class="right">
+          <button class="nav">
+            <img class="" src="@/assets/img/service/navigation-gray.png" alt="" draggable="false">
+            导航
+          </button>
+          <button class="phone">
+            <img class="" src="@/assets/img/service/phone-gray-2.png" alt="" draggable="false">
+            电话
+          </button>
+        </div>
+      </div>
+    </div>
+
+    <div class="content-card">
+      <div class="top-line">
+        <div class="title">推荐菜</div>
+        <button>
+          更多  》
+        </button>
+      </div>
+      <div class="swiper-container-food">
+        <div class="swiper-wrapper">
+          <div class="swiper-slide">
+            <img src="@/assets/img/service/【古建筑】.png" alt="">
+            <div class="title-wrap">
+              <h4>美食名称</h4>
+            </div>
+          </div>
+          <div class="swiper-slide">
+            <img src="@/assets/img/service/【快速浏览】.png" alt="">
+            <div class="title-wrap">
+              <h4>美食名称</h4>
+            </div>
+          </div>
+          <div class="swiper-slide">
+            <img src="@/assets/img/service/【西洋建筑】.png" alt="">
+            <div class="title-wrap">
+              <h4>美食名称</h4>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div class="content-card">
+      <div class="top-line">
+        <div class="title">周边景点</div>
+        <button>
+          更多  》
+        </button>
+      </div>
+      <div class="swiper-container-attractions">
+        <div class="swiper-wrapper">
+          <div class="swiper-slide">
+            <img src="@/assets/img/service/【古建筑】.png" alt="">
+            <div class="title-wrap">
+              <h4>景点名称</h4>
+            </div>
+          </div>
+          <div class="swiper-slide">
+            <img src="@/assets/img/service/【快速浏览】.png" alt="">
+            <div class="title-wrap">
+              <h4>景点名称</h4>
+            </div>
+          </div>
+          <div class="swiper-slide">
+            <img src="@/assets/img/service/【西洋建筑】.png" alt="">
+            <div class="title-wrap">
+              <h4>景点名称</h4>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import Swiper from "../../assets/libs/swiper.js";
+
+export default {
+  mounted() {
+    this.$nextTick(() => {
+      new Swiper(".swiper-container-food", {
+        slidesPerView: 1.4,
+        spaceBetween: 15,
+        centeredSlides: true,
+      })
+    })
+
+    this.$nextTick(() => {
+      new Swiper(".swiper-container-attractions", {
+        slidesPerView: 2.3,
+        spaceBetween: 15,
+        centeredSlides: true,
+      })
+    })
+  }
+}
+</script>
+
+<style lang="less" scoped>
+@import "../../assets/libs/swiper.css";
+
+.food-detail {
+  position: relative;
+  height: calc(100% - 80px);
+  overflow: auto;
+  background: #F0F0F0;
+  z-index: 0;
+  
+  > img.banner-bg {
+    position: absolute;
+    top: 0;
+    width: 100%;
+    z-index: -1;
+  }
+  
+  > .banner-card {
+    background: #FFFFFF;
+    box-shadow: 0vw 0vw 0.9vw 0vw rgba(192,192,192,0.51);
+    border-radius: 1.3vw;
+    margin-top: 13.3vw;
+    margin-left: 2.8vw;
+    margin-right: 2.8vw;
+    padding: 3.5vw 3.2vw 3vw 3.2vw;
+    > h2 {
+      font-size: 4.8vw;
+      font-weight: bold;
+      color: #000000;
+      margin-bottom: 2.3vw;
+    }
+    > .star {
+      display: flex;
+      font-size: 3.2vw;
+      font-weight: bold;
+      color: #e6271d;
+      margin-bottom: 3vw;
+      > img.star {
+        width: 3vw;
+        height: 3vw;
+        margin-right: 1vw;
+      }
+    }
+    > .tag-list {
+      margin-bottom: 2.1vw;
+      > .tag {
+        padding-left: 2.3vw;
+        padding-right: 2.3vw;
+        padding-top: 1vw;
+        padding-bottom: 1vw;
+        display: inline-block;
+        background: #DDC49C;
+        border-radius: 0.5vw;
+        margin-right: 2.1vw;
+        font-size: 3.2vw;
+        font-weight: bold;
+        color: #483515;
+      }
+    }
+    > img.shop-banner {
+      width: 100%;
+      border-radius: 2.1vw;
+    }
+    > .bottom-bar {
+      margin-top: 3.3vw;
+      display: flex;
+      justify-content: space-between;
+      align-items: flex-end;
+      > .left {
+        > img.icon {
+          width: 3.1vw;
+          height: 3.9vw;
+          margin-right: 0.8vw;
+          vertical-align: middle;
+        }
+        > .address {
+          display: inline-block;
+          vertical-align: middle;
+          font-size: 3.5vw;
+          font-weight: bold;
+          color: #787878;
+        }
+      }
+      > .right {
+        > button {
+          font-size: 2.9vw;
+          font-weight: bold;
+          color: #787878;
+          display: inline-flex;
+          flex-direction: column;
+          align-items: center;
+          &:nth-of-type(1) {
+            margin-right: 5.5vw;
+          }
+          > img {
+            display: block;
+            width: 5.3vw;
+            height: 5.3vw;
+            margin-bottom: 0.8vw;
+          }
+        }
+      }
+    }
+  }
+
+  > .content-card {
+    background-color: #fff;
+    margin-top: 5vw;
+    padding-top: 6vw;
+    padding-bottom: 7.5vw;
+    > .top-line {
+      padding-left: 4.7vw;
+      padding-right: 4.7vw;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      > .title {
+        font-size: 3.5vw;
+        font-weight: bold;
+        color: #000000;
+      }
+      > button {
+        font-size: 2.7vw;
+        font-weight: 600;
+        color: #333333;
+        padding-top: 1vw;
+        padding-bottom: 1vw;
+      }
+    }
+    > .swiper-container-food {
+      margin-top: 5vw;
+      overflow: hidden;
+      > .swiper-wrapper {
+        > .swiper-slide {
+          width: 82.8vw;
+          height: 53.2vw;
+          background: #F7F8FA;
+          > img {
+            width: 100%;
+            height: 40.7vw;
+            object-fit: cover;
+          }
+          > .title-wrap {
+            > h4 {
+              text-align: center;
+              margin-top: 4vw;
+              font-size: 3.2vw;
+              font-weight: bold;
+              color: #333333;
+            }
+          }
+        }
+      }
+    }
+    > .swiper-container-attractions {
+      margin-top: 5vw;
+      overflow: hidden;
+      > .swiper-wrapper {
+        > .swiper-slide {
+          width: 43.6vw;
+          height: 55vw;
+          background: #F7F8FA;
+          > img {
+            width: 100%;
+            height: 44.5vw;
+            object-fit: cover;
+          }
+          > .title-wrap {
+            > h4 {
+              text-align: center;
+              margin-top: 3vw;
+              font-size: 3.2vw;
+              font-weight: bold;
+              color: #333333;
+            }
+          }
+        }
+      }
+    }
+  }
+}
 </style>

+ 217 - 217
yfyc/src/views/Serve/FoodList.vue

@@ -1,218 +1,218 @@
-<template>
-  <div class="food-list-page">
-    <div class="banner-wrap">
-      <SearchBar class="search-bar" @search="onSearch"></SearchBar>
-    </div>
-    <div class="select-wrap">
-      <Select
-        class="select"
-        :valueList="orderList"
-        v-model="orderIdx"
-        :placeholder="'排序'"
-      ></Select>
-      <Select
-        class="select"
-        v-model="typeIdx"
-        :valueList="typeList"
-        :placeholder="'分类'"
-      ></Select>
-      <Select
-        class="select"
-        v-model="attractionIdx"
-        :valueList="attractionList"
-        :placeholder="'景点周边'"
-      ></Select>
-    </div>
-    
-    <div class="card-list">
-      <!-- <div class="grid-sizer"></div> -->
-      <article
-        @click="onClickFoodList(index)"
-      >
-        <div class="img-wrap">
-          <img class="photo" :src="foodList[0].img" alt="" draggable="false">
-          <div class="address">
-            <img class="icon" src="@/assets/img/service/address-white.png" alt="" draggable="false">
-            fdaslkfdj
-          </div>
-        </div>
-        <h2>sadfslf</h2>
-        <h2>sadfslf</h2>
-        <h2>sadfslf</h2>
-        <h2>sadfslf</h2>
-      </article>
-      <article
-        v-for="(item, index) in foodList"
-        :key="index"
-        @click="onClickFoodList(index)"
-      >
-        <div class="img-wrap">
-          <img class="photo" :src="item.img" alt="" draggable="false">
-          <div class="address">
-            <img class="icon" src="@/assets/img/service/address-white.png" alt="" draggable="false">
-            {{item.address}}
-          </div>
-        </div>
-        <h2>{{item.title}}</h2>
-      </article>
-    </div>
-
-  </div>
-</template>
-
-<script>
-import SearchBar from "@/components/SearchTransparent.vue";
-import Select from "@/components/Select.vue";
-
-export default {
-  components: {
-    SearchBar,
-    Select,
-  },
-  data() {
-    return {
-      orderIdx: 0,
-      typeIdx: 0,
-      attractionIdx: 0,
-      foodList: [
-        {
-          img: require('@/assets/img/service/food1.png'),
-          address: '芜湖市凤凰美食街中心广场',
-          title: '虾籽面',
-        },
-        {
-          img: require('@/assets/img/service/food1.png'),
-          address: '芜湖市凤凰美食街中心广场',
-          title: '虾籽面',
-        },
-        {
-          img: require('@/assets/img/service/food1.png'),
-          address: '芜湖市凤凰美食街中心广场',
-          title: '虾籽面',
-        },
-      ]
-    }
-  },
-  computed: {
-    orderList() {
-      return [
-        '全部',
-        '价格',
-        '距离',
-        '评价',
-      ]
-    },
-    typeList() {
-      return [
-        '全部',
-        '中餐',
-        '西餐',
-      ]
-    },
-    attractionList() {
-      return [
-        '全部',
-        '景点1',
-        '景点2',
-        '景点3',
-      ]
-    }
-  },
-  methods: {
-    onSearch() {
-
-    },
-    onClickFoodList(index) {
-      this.$router.push({name: 'FoodDetail'})
-    },
-  },
-  mounted() {
-    $('.card-list').masonry({
-      itemSelector: '.card-list > article',
-      percentPosition: true,
-    });
-  }
-}
-</script>
-
-<style lang="less" scoped>
-.food-list-page {
-  height: calc(100% - 80px);
-  background-color: #fff;
-  display: flex;
-  flex-direction: column;
-  > .banner-wrap {
-    flex: 0 0 auto;
-    height: 40vw;
-    background-image: url(~@/assets/img/service/food-banner.png);
-    background-size: cover;
-    background-repeat: no-repeat;
-    background-position: center center;
-    overflow: hidden;
-    margin-bottom: 4.1vw;
-    position: relative;
-    > .search-bar {
-      position: absolute;
-      bottom: 4.8vw;
-      left: 50%;
-      width: 80.1vw;
-      transform: translateX(-50%);
-    }
-  }
-  > .select-wrap {
-    flex: 0 0 auto;
-    margin: 0 4vw 4vw 4vw;
-    position: relative;
-    z-index: 1;
-    > .select {
-      display: inline-block;
-      margin-right: 5vw;
-    }
-  }
-  > .card-list {
-    flex: 1 0 1px;
-    margin-left: 4vw;
-    overflow: auto;
-    > article {
-      width: 43vw;
-      padding-bottom: 2.7vw;
-      margin-bottom: 4vw;
-      margin-right: 4vw;;
-      display: inline-block;
-      > .img-wrap {
-        height: 53.3vw;
-        border-radius: 1.1vw;
-        position: relative;
-        overflow: hidden;
-        > img.photo {
-          position: absolute;
-          left: 0;
-          top: 0;
-          width: 100%;
-          height: 100%;
-          object-fit: cover;
-        }
-        > .address {
-          position: absolute;
-          left: 2vw;
-          bottom: 2vw;
-          font-size: 2.7vw;
-          color: #FFFFFF;
-          > img.icon {
-            width: 2.7vw;
-            height: 3.6vw;
-            margin-right: 1vw;
-            vertical-align: -0.3em;
-          }
-        }
-      }
-      > h2 {
-        margin: 2.7vw 2vw 3vw 2vw;
-        font-size: 3.5vw;
-        font-weight: 500;
-        color: #454545;
-      }
-    }
-  }
-}
+<template>
+  <div class="food-list-page">
+    <div class="banner-wrap">
+      <SearchBar class="search-bar" @search="onSearch"></SearchBar>
+    </div>
+    <div class="select-wrap">
+      <Select
+        class="select"
+        :valueList="orderList"
+        v-model="orderIdx"
+        :placeholder="'排序'"
+      ></Select>
+      <Select
+        class="select"
+        v-model="typeIdx"
+        :valueList="typeList"
+        :placeholder="'分类'"
+      ></Select>
+      <Select
+        class="select"
+        v-model="attractionIdx"
+        :valueList="attractionList"
+        :placeholder="'景点周边'"
+      ></Select>
+    </div>
+    
+    <div class="card-list">
+      <!-- <div class="grid-sizer"></div> -->
+      <article
+        @click="onClickFoodList(index)"
+      >
+        <div class="img-wrap">
+          <img class="photo" :src="foodList[0].img" alt="" draggable="false">
+          <div class="address">
+            <img class="icon" src="@/assets/img/service/address-white.png" alt="" draggable="false">
+            fdaslkfdj
+          </div>
+        </div>
+        <h2>sadfslf</h2>
+        <h2>sadfslf</h2>
+        <h2>sadfslf</h2>
+        <h2>sadfslf</h2>
+      </article>
+      <article
+        v-for="(item, index) in foodList"
+        :key="index"
+        @click="onClickFoodList(index)"
+      >
+        <div class="img-wrap">
+          <img class="photo" :src="item.img" alt="" draggable="false">
+          <div class="address">
+            <img class="icon" src="@/assets/img/service/address-white.png" alt="" draggable="false">
+            {{item.address}}
+          </div>
+        </div>
+        <h2>{{item.title}}</h2>
+      </article>
+    </div>
+
+  </div>
+</template>
+
+<script>
+import SearchBar from "@/components/SearchTransparent.vue";
+import Select from "@/components/Select.vue";
+
+export default {
+  components: {
+    SearchBar,
+    Select,
+  },
+  data() {
+    return {
+      orderIdx: 0,
+      typeIdx: 0,
+      attractionIdx: 0,
+      foodList: [
+        {
+          img: require('@/assets/img/service/food1.png'),
+          address: '芜湖市凤凰美食街中心广场',
+          title: '虾籽面',
+        },
+        {
+          img: require('@/assets/img/service/food1.png'),
+          address: '芜湖市凤凰美食街中心广场',
+          title: '虾籽面',
+        },
+        {
+          img: require('@/assets/img/service/food1.png'),
+          address: '芜湖市凤凰美食街中心广场',
+          title: '虾籽面',
+        },
+      ]
+    }
+  },
+  computed: {
+    orderList() {
+      return [
+        '全部',
+        '价格',
+        '距离',
+        '评价',
+      ]
+    },
+    typeList() {
+      return [
+        '全部',
+        '中餐',
+        '西餐',
+      ]
+    },
+    attractionList() {
+      return [
+        '全部',
+        '景点1',
+        '景点2',
+        '景点3',
+      ]
+    }
+  },
+  methods: {
+    onSearch() {
+
+    },
+    onClickFoodList(index) {
+      this.$router.push({name: 'FoodDetail'})
+    },
+  },
+  mounted() {
+    $('.card-list').masonry({
+      itemSelector: '.card-list > article',
+      percentPosition: true,
+    });
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.food-list-page {
+  height: calc(100% - 80px);
+  background-color: #fff;
+  display: flex;
+  flex-direction: column;
+  > .banner-wrap {
+    flex: 0 0 auto;
+    height: 40vw;
+    background-image: url(~@/assets/img/service/food-banner.png);
+    background-size: cover;
+    background-repeat: no-repeat;
+    background-position: center center;
+    overflow: hidden;
+    margin-bottom: 4.1vw;
+    position: relative;
+    > .search-bar {
+      position: absolute;
+      bottom: 4.8vw;
+      left: 50%;
+      width: 80.1vw;
+      transform: translateX(-50%);
+    }
+  }
+  > .select-wrap {
+    flex: 0 0 auto;
+    margin: 0 4vw 4vw 4vw;
+    position: relative;
+    z-index: 1;
+    > .select {
+      display: inline-block;
+      margin-right: 5vw;
+    }
+  }
+  > .card-list {
+    flex: 1 0 1px;
+    margin-left: 4vw;
+    overflow: auto;
+    > article {
+      width: 43vw;
+      padding-bottom: 2.7vw;
+      margin-bottom: 4vw;
+      margin-right: 4vw;;
+      display: inline-block;
+      > .img-wrap {
+        height: 53.3vw;
+        border-radius: 1.1vw;
+        position: relative;
+        overflow: hidden;
+        > img.photo {
+          position: absolute;
+          left: 0;
+          top: 0;
+          width: 100%;
+          height: 100%;
+          object-fit: cover;
+        }
+        > .address {
+          position: absolute;
+          left: 2vw;
+          bottom: 2vw;
+          font-size: 2.7vw;
+          color: #FFFFFF;
+          > img.icon {
+            width: 2.7vw;
+            height: 3.6vw;
+            margin-right: 1vw;
+            vertical-align: -0.3em;
+          }
+        }
+      }
+      > h2 {
+        margin: 2.7vw 2vw 3vw 2vw;
+        font-size: 3.5vw;
+        font-weight: 500;
+        color: #454545;
+      }
+    }
+  }
+}
 </style>

+ 165 - 165
yfyc/src/views/Serve/HelpCenter.vue

@@ -1,166 +1,166 @@
-<template>
-  <div class="help-center">
-    <SearchBar class="search-bar" @search="onSearch"></SearchBar>
-    <TabbarSmall class="tabbar" :tabList="['常见问题', '服务电话']" @change="onTabbarChange"></TabbarSmall>
-    <div class="question-list" v-if="activeTabbarIdx === 0">
-      <div class="question-item" 
-        v-for="(item, index) in questionList"
-        :key="index"
-      >
-        <h2>{{item.title}}</h2>
-        <span class="time">{{item.time}}</span>
-      </div>
-    </div>
-    <div class="phone-list" v-if="activeTabbarIdx === 1">
-      <div class="phone-item" 
-        v-for="(item, index) in phoneList"
-        :key="index"
-      >
-        <h2>{{item.title}}</h2>
-        <a :href="`tel: ${item.phone}`" class="phone">{{item.phone}}</a>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import SearchBar from "@/components/SearchRedBtn.vue";
-import TabbarSmall from "@/components/TabbarSmall.vue";
-
-export default {
-  components: {
-    SearchBar,
-    TabbarSmall,
-  },
-  data() {
-    return {
-      activeTabbarIdx: 0,
-      questionList: [
-        {
-          title: '求推荐体育中心附近的停车场',
-          time: '2022-10-10',
-        },
-        {
-          title: '求推荐体育中心附近的停车场',
-          time: '2022-10-10',
-        },
-        {
-          title: '求推荐体育中心附近的停车场',
-          time: '2022-10-10',
-        },
-        {
-          title: '求推荐体育中心附近的停车场',
-          time: '2022-10-10',
-        },
-        {
-          title: '求推荐体育中心附近的停车场求推荐体育中心附近的停车场求推荐体育中心附近的停车场求推荐体育中心附近的停车场求推荐体育中心附近的停车场',
-          time: '2022-10-10',
-        },
-      ],
-      phoneList: [
-        {
-          title: '体育中心',
-          phone: '0431-85171079',
-        },
-        {
-          title: '体育中心',
-          phone: '0431-85171079',
-        },
-        {
-          title: '体育中心',
-          phone: '0431-85171079',
-        },
-        {
-          title: '体育中心',
-          phone: '0431-85171079',
-        },
-        {
-          title: '体育中心',
-          phone: '0431-85171079',
-        },
-      ]
-    }
-  },
-  methods: {
-    onSearch() {
-
-    },
-    onTabbarChange(idx) {
-      this.activeTabbarIdx = idx
-    }
-  },
-}
-</script>
-
-<style lang="less" scoped>
-.help-center {
-  background-color: #fff;
-  height: calc(100% - 80px);
-  overflow: auto;
-  padding: 3.3vw 4.5vw;
-  display: flex;
-  flex-direction: column;
-  > .search-bar {
-    flex: 0 0 auto;
-    margin-bottom: 4.1vw;
-  }
-  > .tabbar {
-    flex: 0 0 auto;
-    margin-bottom: 8.5vw;
-  }
-  > .question-list {
-    flex: 1 0 1px;
-    overflow: auto;
-    > .question-item {
-      border-bottom: 1px solid #E5E5E5;
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      height: 13.5vw;
-      > h2 {
-        flex: 0 0 auto;
-        max-width: 75%;
-        overflow: hidden;
-        text-overflow: ellipsis;
-        white-space: nowrap;
-        font-size: 3.2vw;
-        font-weight: bold;
-        color: #333333;
-      }
-      > .time {
-        flex: 0 0 auto;
-        max-width: 20%;
-        font-size: 2.7vw;
-        color: #333333;
-      }
-    }
-  }
-  > .phone-list {
-    flex: 1 0 1px;
-    overflow: auto;
-    > .phone-item {
-      border-bottom: 1px solid #E5E5E5;
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      height: 13.5vw;
-      > h2 {
-        flex: 0 0 auto;
-        max-width: 50%;
-        overflow: hidden;
-        text-overflow: ellipsis;
-        white-space: nowrap;
-        font-size: 3.2vw;
-        font-weight: bold;
-        color: #333333;
-      }
-      > .phone {
-        flex: 0 0 auto;
-        max-width: 50%;
-        font-size: 2.7vw;
-        color: #333333;
-      }
-    }
-  }
-}
+<template>
+  <div class="help-center">
+    <SearchBar class="search-bar" @search="onSearch"></SearchBar>
+    <TabbarSmall class="tabbar" :tabList="['常见问题', '服务电话']" @change="onTabbarChange"></TabbarSmall>
+    <div class="question-list" v-if="activeTabbarIdx === 0">
+      <div class="question-item" 
+        v-for="(item, index) in questionList"
+        :key="index"
+      >
+        <h2>{{item.title}}</h2>
+        <span class="time">{{item.time}}</span>
+      </div>
+    </div>
+    <div class="phone-list" v-if="activeTabbarIdx === 1">
+      <div class="phone-item" 
+        v-for="(item, index) in phoneList"
+        :key="index"
+      >
+        <h2>{{item.title}}</h2>
+        <a :href="`tel: ${item.phone}`" class="phone">{{item.phone}}</a>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import SearchBar from "@/components/SearchRedBtn.vue";
+import TabbarSmall from "@/components/TabbarSmall.vue";
+
+export default {
+  components: {
+    SearchBar,
+    TabbarSmall,
+  },
+  data() {
+    return {
+      activeTabbarIdx: 0,
+      questionList: [
+        {
+          title: '求推荐体育中心附近的停车场',
+          time: '2022-10-10',
+        },
+        {
+          title: '求推荐体育中心附近的停车场',
+          time: '2022-10-10',
+        },
+        {
+          title: '求推荐体育中心附近的停车场',
+          time: '2022-10-10',
+        },
+        {
+          title: '求推荐体育中心附近的停车场',
+          time: '2022-10-10',
+        },
+        {
+          title: '求推荐体育中心附近的停车场求推荐体育中心附近的停车场求推荐体育中心附近的停车场求推荐体育中心附近的停车场求推荐体育中心附近的停车场',
+          time: '2022-10-10',
+        },
+      ],
+      phoneList: [
+        {
+          title: '体育中心',
+          phone: '0431-85171079',
+        },
+        {
+          title: '体育中心',
+          phone: '0431-85171079',
+        },
+        {
+          title: '体育中心',
+          phone: '0431-85171079',
+        },
+        {
+          title: '体育中心',
+          phone: '0431-85171079',
+        },
+        {
+          title: '体育中心',
+          phone: '0431-85171079',
+        },
+      ]
+    }
+  },
+  methods: {
+    onSearch() {
+
+    },
+    onTabbarChange(idx) {
+      this.activeTabbarIdx = idx
+    }
+  },
+}
+</script>
+
+<style lang="less" scoped>
+.help-center {
+  background-color: #fff;
+  height: calc(100% - 80px);
+  overflow: auto;
+  padding: 3.3vw 4.5vw;
+  display: flex;
+  flex-direction: column;
+  > .search-bar {
+    flex: 0 0 auto;
+    margin-bottom: 4.1vw;
+  }
+  > .tabbar {
+    flex: 0 0 auto;
+    margin-bottom: 8.5vw;
+  }
+  > .question-list {
+    flex: 1 0 1px;
+    overflow: auto;
+    > .question-item {
+      border-bottom: 1px solid #E5E5E5;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      height: 13.5vw;
+      > h2 {
+        flex: 0 0 auto;
+        max-width: 75%;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        font-size: 3.2vw;
+        font-weight: bold;
+        color: #333333;
+      }
+      > .time {
+        flex: 0 0 auto;
+        max-width: 20%;
+        font-size: 2.7vw;
+        color: #333333;
+      }
+    }
+  }
+  > .phone-list {
+    flex: 1 0 1px;
+    overflow: auto;
+    > .phone-item {
+      border-bottom: 1px solid #E5E5E5;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      height: 13.5vw;
+      > h2 {
+        flex: 0 0 auto;
+        max-width: 50%;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        font-size: 3.2vw;
+        font-weight: bold;
+        color: #333333;
+      }
+      > .phone {
+        flex: 0 0 auto;
+        max-width: 50%;
+        font-size: 2.7vw;
+        color: #333333;
+      }
+    }
+  }
+}
 </style>

+ 400 - 400
yfyc/src/views/Serve/HotelDetail.vue

@@ -1,401 +1,401 @@
-<template>
-  <div class="hotel-detail">
-    <div class="banner">
-    </div>
-    <div class="title-area">
-      <div class="title-bar">
-        <div class="left">
-          <h2>芜湖金鹰尚美酒店</h2>
-          <div class="star">5星级</div>
-        </div>
-        <div class="right">
-          427余套客房· 684张床位
-        </div>
-      </div>
-      <div class="address-bar">
-        <div class="left-wrap">
-          <img class="icon" src="@/assets/img/service/address-gray.png" alt="" draggable="false">
-          <div class="info">
-            <div class="address">芜湖市镜湖区中山北路77号</div>
-            <div class="distance">距您2.8km</div>
-          </div>
-        </div>
-        <button>
-          <img class="icon" src="@/assets/img/service/navigation.png" alt="" draggable="false">
-          <span>开启导航</span>
-        </button>
-      </div>
-      <div class="phone-bar">
-        <div class="left-wrap">
-          <img class="icon" src="@/assets/img/service/phone-gray.png" alt="" draggable="false">
-          <div class="info">
-            <div class="title">
-              咨询电话
-            </div>
-            <div class="phone">
-              0533-3888999
-            </div>
-          </div>
-        </div>
-        <button>
-          <img class="icon" src="@/assets/img/service/phone-blue.png" alt="" draggable="false">
-          <span>快速拨通</span>
-        </button>
-      </div>
-    </div>
-    <div class="splitter">
-    </div>
-    <div
-      class="desc"
-    >
-      <h2>酒店概况</h2>
-      <div
-        class="content"
-        :class="{
-          expand: isExpanded
-        }"
-      >
-        酒店位于芜湖市中心位置—中山北路,毗邻八佰伴、凤凰美食街、华强吾悦广场、苏宁广场,以及一步之遥的中山路步行街。酒店“闹中取静”,背靠繁华交通主干道,拥有独立的地下及地面停车场。<br>
-        酒店有三百余间客房,客房位于酒店21F以上,透过房间落地窗,可以饱览赭山或长江美景。房内提供无线宽带、频道选择、私人保险箱、咖啡和茶、配有浴缸和独立淋浴间的宽敞浴室。同时,酒店还为儿童们准备了独具特色的儿童主题房,希望能成为您和家人心中“行业的佼佼者”。
-        <button
-          class="expand-content"
-          v-show="!isExpanded"
-          @click="isExpanded = true"
-        >
-          收起
-        </button>
-      </div>
-    </div>
-    <div class="splitter" />
-    <div class="food">
-      <h2>周边美食</h2>
-      <button class="more">
-        更多
-        <img class="" src="@/assets/img/service/arrow-gray-blunt.png" alt="" draggable="false">
-      </button>
-      <div class="food-photo-wrap"
-        v-for="n in 2"
-        :key="n"
-      >
-        <img class="food-photo" src="@/assets/img/service/arrow-gray-blunt.png" alt="" draggable="false">
-        <div class="food-name">无为板鸭</div>
-      </div>
-    </div>
-    <div class="attractions">
-      <h2>周边景点</h2>
-      <button class="more">
-        更多
-        <img class="" src="@/assets/img/service/arrow-gray-blunt.png" alt="" draggable="false">
-      </button>
-      <div class="attraction-photo-wrap"
-        v-for="n in 2"
-        :key="n"
-      >
-        <img class="attraction-photo" src="@/assets/img/service/arrow-gray-blunt.png" alt="" draggable="false">
-        <div class="attraction-name">鸠兹古镇</div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-  data() {
-    return {
-      isExpanded: false,
-    }
-  },
-}
-</script>
-
-<style lang="less" scoped>
-.hotel-detail {
-  background-color: #fff;
-  height: calc(100% - 80px);
-  overflow: auto;
-  .banner {
-    height: 62.9vw;
-    background-image: url(~@/assets/img/service/hotel-detail-banner.png);
-    background-size: cover;
-    background-repeat: no-repeat;
-    background-position: center center;
-    overflow: hidden;
-  }
-  .title-area {
-    padding: 4vw;
-    .title-bar {
-      display: flex;
-      justify-content: space-between;
-      align-items: flex-end;
-      margin-bottom: 3.9vw;
-      .left {
-        display: flex;
-        align-items: flex-end;
-        > h2 {
-          font-size: 4.8vw;
-          font-weight: bold;
-          color: #515151;
-          white-space: nowrap;
-        }
-        .star {
-          white-space: nowrap;
-          padding: 1.1vw 1.9vw;
-          font-size: 2.7vw;
-          font-weight: 500;
-          color: #f5c706;
-          background: rgba(217, 28, 28, 1);
-          border-radius: 2.3vw;
-        }
-      }
-      .right {
-        font-size: 2.9vw;
-        color: #B2B2B2;
-      }
-    }
-    .address-bar {
-      height: 13.3vw;
-      background: #F8F8F8;
-      border-radius: 1.3vw;
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      margin-bottom: 2.7vw;
-      padding-left: 3vw;
-      padding-right: 3vw;
-      > .left-wrap {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        .icon {
-          margin-right: 2.5vw;
-          width: 4.7vw;
-          height: 6.4vw;
-        }
-        .info {
-          .address {
-            font-size: 3.7vw;
-            font-weight: 500;
-            color: #656565;
-          }
-          .distance {
-            font-size: 3.2vw;
-            color: #777777;
-          }
-        }
-      }
-      > button {
-        display: flex;
-        align-items: center;
-        .icon {
-          width: 4.8vw;
-          height: 4.8vw;
-          margin-right: 1.5vw;
-        }
-        > span {
-          font-size: 4.0vw;
-          font-weight: 500;
-          color: #00a2ff;
-        }
-      }
-    }
-    .phone-bar {
-      height: 13.3vw;
-      background: #F8F8F8;
-      border-radius: 1.3vw;
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      margin-bottom: 2.7vw;
-      padding-left: 3vw;
-      padding-right: 3vw;
-      .left-wrap {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        .icon {
-          margin-right: 2.5vw;
-          width: 4.7vw;
-          height: 6.4vw;
-        }
-        .info {
-          > .title {
-            font-size: 3.7vw;
-            font-weight: 500;
-            color: #656565;
-          }
-          > .phone {
-            font-size: 3.2vw;
-            color: #777777;
-          }
-        }
-      }
-      > button {
-        display: flex;
-        align-items: center;
-        .icon {
-          width: 4.8vw;
-          height: 4.8vw;
-          margin-right: 1.5vw;
-        }
-        > span {
-          font-size: 4.0vw;
-          font-weight: 500;
-          color: #00a2ff;
-        }
-      }
-    }
-  }
-  > .desc {
-    padding: 4vw 4vw 6vw 4vw;
-    > h2 {
-      font-size: 4.8vw;
-      font-weight: 500;
-      color: #7A7A7A;
-      position: relative;
-      margin-bottom: 3.7vw;
-      &::before {
-        position: absolute;
-        content: '';
-        top: 0;
-        right: calc(100% + 1.5vw);
-        height: 95%;
-        width: 0.7vw;
-        background: #00A2FF;
-      }
-    }
-    > .content {
-      font-size: 4.0vw;
-      color: #7A7A7A;
-      line-height: 6.9vw;
-      max-height: calc(6.9vw * 5);
-      overflow: hidden;
-      position: relative;
-      &.expand {
-        max-height: initial;
-      }
-      > button {
-        position: absolute;
-        left: 0;
-        width: 100%;
-        bottom: 0;
-        height: 1.5em;
-        font-size: 4vw;
-        font-weight: 500;
-        color: #BBBBBB;
-        background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 80%);
-        text-align: right;
-      }
-    }
-  }
-  > .splitter {
-    height: 0.7vw;
-    background: #F7F7F7;
-  }
-  > .food {
-    padding: 4vw 0 6vw 4vw;
-    position: relative;
-    > h2 {
-      font-size: 4.8vw;
-      font-weight: 500;
-      color: #7A7A7A;
-      position: relative;
-      margin-bottom: 3.7vw;
-      &::before {
-        position: absolute;
-        content: '';
-        top: 0;
-        right: calc(100% + 1.5vw);
-        height: 95%;
-        width: 0.7vw;
-        background: #00A2FF;
-      }
-    }
-    > button.more {
-      position: absolute;
-      right: 4vw;
-      top: 4vw;
-      font-size: 4vw;
-      color: #CECECE;
-      height: 6vw;
-      display: flex;
-      align-items: center;
-      > img {
-        width: 1.9vw;
-        height: 3.6vw;
-        margin-left: 1.3vw;
-      }
-    }
-    > .food-photo-wrap {
-      margin-right: 4vw;
-      margin-bottom: 4vw;
-      display: inline-block;
-      > img.food-photo {
-        width: 44vw;
-        height: 44vw;
-        border-radius: 1.5vw;
-        margin-bottom: 1.6vw;
-      }
-      > .food-name {
-        font-size: 3.7vw;
-        font-weight: 500;
-        color: #9C9C9C;
-        width: 44vw;
-        text-align: center;
-      }
-    }
-  }
-  > .attractions {
-    padding: 4vw 0 6vw 4vw;
-    position: relative;
-    > h2 {
-      font-size: 4.8vw;
-      font-weight: 500;
-      color: #7A7A7A;
-      position: relative;
-      margin-bottom: 3.7vw;
-      &::before {
-        position: absolute;
-        content: '';
-        top: 0;
-        right: calc(100% + 1.5vw);
-        height: 95%;
-        width: 0.7vw;
-        background: #00A2FF;
-      }
-    }
-    > button.more {
-      position: absolute;
-      right: 4vw;
-      top: 4vw;
-      font-size: 4vw;
-      color: #CECECE;
-      height: 6vw;
-      display: flex;
-      align-items: center;
-      > img {
-        width: 1.9vw;
-        height: 3.6vw;
-        margin-left: 1.3vw;
-      }
-    }
-    > .attraction-photo-wrap {
-      margin-right: 4vw;
-      margin-bottom: 4vw;
-      display: inline-block;
-      > img.attraction-photo {
-        width: 44vw;
-        height: 44vw;
-        border-radius: 1.5vw;
-        margin-bottom: 1.6vw;
-      }
-      > .attraction-name {
-        font-size: 3.7vw;
-        font-weight: 500;
-        color: #9C9C9C;
-        width: 44vw;
-        text-align: center;
-      }
-    }
-  }
-}
+<template>
+  <div class="hotel-detail">
+    <div class="banner">
+    </div>
+    <div class="title-area">
+      <div class="title-bar">
+        <div class="left">
+          <h2>芜湖金鹰尚美酒店</h2>
+          <div class="star">5星级</div>
+        </div>
+        <div class="right">
+          427余套客房· 684张床位
+        </div>
+      </div>
+      <div class="address-bar">
+        <div class="left-wrap">
+          <img class="icon" src="@/assets/img/service/address-gray.png" alt="" draggable="false">
+          <div class="info">
+            <div class="address">芜湖市镜湖区中山北路77号</div>
+            <div class="distance">距您2.8km</div>
+          </div>
+        </div>
+        <button>
+          <img class="icon" src="@/assets/img/service/navigation.png" alt="" draggable="false">
+          <span>开启导航</span>
+        </button>
+      </div>
+      <div class="phone-bar">
+        <div class="left-wrap">
+          <img class="icon" src="@/assets/img/service/phone-gray.png" alt="" draggable="false">
+          <div class="info">
+            <div class="title">
+              咨询电话
+            </div>
+            <div class="phone">
+              0533-3888999
+            </div>
+          </div>
+        </div>
+        <button>
+          <img class="icon" src="@/assets/img/service/phone-blue.png" alt="" draggable="false">
+          <span>快速拨通</span>
+        </button>
+      </div>
+    </div>
+    <div class="splitter">
+    </div>
+    <div
+      class="desc"
+    >
+      <h2>酒店概况</h2>
+      <div
+        class="content"
+        :class="{
+          expand: isExpanded
+        }"
+      >
+        酒店位于芜湖市中心位置—中山北路,毗邻八佰伴、凤凰美食街、华强吾悦广场、苏宁广场,以及一步之遥的中山路步行街。酒店“闹中取静”,背靠繁华交通主干道,拥有独立的地下及地面停车场。<br>
+        酒店有三百余间客房,客房位于酒店21F以上,透过房间落地窗,可以饱览赭山或长江美景。房内提供无线宽带、频道选择、私人保险箱、咖啡和茶、配有浴缸和独立淋浴间的宽敞浴室。同时,酒店还为儿童们准备了独具特色的儿童主题房,希望能成为您和家人心中“行业的佼佼者”。
+        <button
+          class="expand-content"
+          v-show="!isExpanded"
+          @click="isExpanded = true"
+        >
+          收起
+        </button>
+      </div>
+    </div>
+    <div class="splitter" />
+    <div class="food">
+      <h2>周边美食</h2>
+      <button class="more">
+        更多
+        <img class="" src="@/assets/img/service/arrow-gray-blunt.png" alt="" draggable="false">
+      </button>
+      <div class="food-photo-wrap"
+        v-for="n in 2"
+        :key="n"
+      >
+        <img class="food-photo" src="@/assets/img/service/arrow-gray-blunt.png" alt="" draggable="false">
+        <div class="food-name">无为板鸭</div>
+      </div>
+    </div>
+    <div class="attractions">
+      <h2>周边景点</h2>
+      <button class="more">
+        更多
+        <img class="" src="@/assets/img/service/arrow-gray-blunt.png" alt="" draggable="false">
+      </button>
+      <div class="attraction-photo-wrap"
+        v-for="n in 2"
+        :key="n"
+      >
+        <img class="attraction-photo" src="@/assets/img/service/arrow-gray-blunt.png" alt="" draggable="false">
+        <div class="attraction-name">鸠兹古镇</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      isExpanded: false,
+    }
+  },
+}
+</script>
+
+<style lang="less" scoped>
+.hotel-detail {
+  background-color: #fff;
+  height: calc(100% - 80px);
+  overflow: auto;
+  .banner {
+    height: 62.9vw;
+    background-image: url(~@/assets/img/service/hotel-detail-banner.png);
+    background-size: cover;
+    background-repeat: no-repeat;
+    background-position: center center;
+    overflow: hidden;
+  }
+  .title-area {
+    padding: 4vw;
+    .title-bar {
+      display: flex;
+      justify-content: space-between;
+      align-items: flex-end;
+      margin-bottom: 3.9vw;
+      .left {
+        display: flex;
+        align-items: flex-end;
+        > h2 {
+          font-size: 4.8vw;
+          font-weight: bold;
+          color: #515151;
+          white-space: nowrap;
+        }
+        .star {
+          white-space: nowrap;
+          padding: 1.1vw 1.9vw;
+          font-size: 2.7vw;
+          font-weight: 500;
+          color: #f5c706;
+          background: rgba(217, 28, 28, 1);
+          border-radius: 2.3vw;
+        }
+      }
+      .right {
+        font-size: 2.9vw;
+        color: #B2B2B2;
+      }
+    }
+    .address-bar {
+      height: 13.3vw;
+      background: #F8F8F8;
+      border-radius: 1.3vw;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 2.7vw;
+      padding-left: 3vw;
+      padding-right: 3vw;
+      > .left-wrap {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        .icon {
+          margin-right: 2.5vw;
+          width: 4.7vw;
+          height: 6.4vw;
+        }
+        .info {
+          .address {
+            font-size: 3.7vw;
+            font-weight: 500;
+            color: #656565;
+          }
+          .distance {
+            font-size: 3.2vw;
+            color: #777777;
+          }
+        }
+      }
+      > button {
+        display: flex;
+        align-items: center;
+        .icon {
+          width: 4.8vw;
+          height: 4.8vw;
+          margin-right: 1.5vw;
+        }
+        > span {
+          font-size: 4.0vw;
+          font-weight: 500;
+          color: #00a2ff;
+        }
+      }
+    }
+    .phone-bar {
+      height: 13.3vw;
+      background: #F8F8F8;
+      border-radius: 1.3vw;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 2.7vw;
+      padding-left: 3vw;
+      padding-right: 3vw;
+      .left-wrap {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        .icon {
+          margin-right: 2.5vw;
+          width: 4.7vw;
+          height: 6.4vw;
+        }
+        .info {
+          > .title {
+            font-size: 3.7vw;
+            font-weight: 500;
+            color: #656565;
+          }
+          > .phone {
+            font-size: 3.2vw;
+            color: #777777;
+          }
+        }
+      }
+      > button {
+        display: flex;
+        align-items: center;
+        .icon {
+          width: 4.8vw;
+          height: 4.8vw;
+          margin-right: 1.5vw;
+        }
+        > span {
+          font-size: 4.0vw;
+          font-weight: 500;
+          color: #00a2ff;
+        }
+      }
+    }
+  }
+  > .desc {
+    padding: 4vw 4vw 6vw 4vw;
+    > h2 {
+      font-size: 4.8vw;
+      font-weight: 500;
+      color: #7A7A7A;
+      position: relative;
+      margin-bottom: 3.7vw;
+      &::before {
+        position: absolute;
+        content: '';
+        top: 0;
+        right: calc(100% + 1.5vw);
+        height: 95%;
+        width: 0.7vw;
+        background: #00A2FF;
+      }
+    }
+    > .content {
+      font-size: 4.0vw;
+      color: #7A7A7A;
+      line-height: 6.9vw;
+      max-height: calc(6.9vw * 5);
+      overflow: hidden;
+      position: relative;
+      &.expand {
+        max-height: initial;
+      }
+      > button {
+        position: absolute;
+        left: 0;
+        width: 100%;
+        bottom: 0;
+        height: 1.5em;
+        font-size: 4vw;
+        font-weight: 500;
+        color: #BBBBBB;
+        background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 80%);
+        text-align: right;
+      }
+    }
+  }
+  > .splitter {
+    height: 0.7vw;
+    background: #F7F7F7;
+  }
+  > .food {
+    padding: 4vw 0 6vw 4vw;
+    position: relative;
+    > h2 {
+      font-size: 4.8vw;
+      font-weight: 500;
+      color: #7A7A7A;
+      position: relative;
+      margin-bottom: 3.7vw;
+      &::before {
+        position: absolute;
+        content: '';
+        top: 0;
+        right: calc(100% + 1.5vw);
+        height: 95%;
+        width: 0.7vw;
+        background: #00A2FF;
+      }
+    }
+    > button.more {
+      position: absolute;
+      right: 4vw;
+      top: 4vw;
+      font-size: 4vw;
+      color: #CECECE;
+      height: 6vw;
+      display: flex;
+      align-items: center;
+      > img {
+        width: 1.9vw;
+        height: 3.6vw;
+        margin-left: 1.3vw;
+      }
+    }
+    > .food-photo-wrap {
+      margin-right: 4vw;
+      margin-bottom: 4vw;
+      display: inline-block;
+      > img.food-photo {
+        width: 44vw;
+        height: 44vw;
+        border-radius: 1.5vw;
+        margin-bottom: 1.6vw;
+      }
+      > .food-name {
+        font-size: 3.7vw;
+        font-weight: 500;
+        color: #9C9C9C;
+        width: 44vw;
+        text-align: center;
+      }
+    }
+  }
+  > .attractions {
+    padding: 4vw 0 6vw 4vw;
+    position: relative;
+    > h2 {
+      font-size: 4.8vw;
+      font-weight: 500;
+      color: #7A7A7A;
+      position: relative;
+      margin-bottom: 3.7vw;
+      &::before {
+        position: absolute;
+        content: '';
+        top: 0;
+        right: calc(100% + 1.5vw);
+        height: 95%;
+        width: 0.7vw;
+        background: #00A2FF;
+      }
+    }
+    > button.more {
+      position: absolute;
+      right: 4vw;
+      top: 4vw;
+      font-size: 4vw;
+      color: #CECECE;
+      height: 6vw;
+      display: flex;
+      align-items: center;
+      > img {
+        width: 1.9vw;
+        height: 3.6vw;
+        margin-left: 1.3vw;
+      }
+    }
+    > .attraction-photo-wrap {
+      margin-right: 4vw;
+      margin-bottom: 4vw;
+      display: inline-block;
+      > img.attraction-photo {
+        width: 44vw;
+        height: 44vw;
+        border-radius: 1.5vw;
+        margin-bottom: 1.6vw;
+      }
+      > .attraction-name {
+        font-size: 3.7vw;
+        font-weight: 500;
+        color: #9C9C9C;
+        width: 44vw;
+        text-align: center;
+      }
+    }
+  }
+}
 </style>

+ 276 - 276
yfyc/src/views/Serve/HotelList.vue

@@ -1,277 +1,277 @@
-<template>
-  <div class="hotel-list-page">
-    <div class="banner-wrap">
-      <SearchBar class="search-bar" @search="onSearch"></SearchBar>
-    </div>
-    <div class="select-wrap">
-      <Select
-        class="select"
-        :valueList="starList"
-        v-model="starIdx"
-        :placeholder="'星级'"
-      ></Select>
-      <Select
-        class="select"
-        v-model="areaIdx"
-        :valueList="areaList"
-        :placeholder="'景点周边'"
-      ></Select>
-      <Select
-        class="select"
-        v-model="recoLevelIdx"
-        :valueList="recoLevelList"
-        :placeholder="'推荐指数'"
-      ></Select>
-    </div>
-    
-    <div class="card-list">
-      <article
-        v-for="(item, index) in hotelList"
-        :key="index"
-        @click="onClickHotelList(index)"
-      >
-        <div class="img-wrap">
-          <img class="photo" :src="item.img" alt="" draggable="false">
-          <div class="star">{{item.star}}星级</div>
-          <div class="address">
-            <img class="icon" src="@/assets/img/service/address-white.png" alt="" draggable="false">
-            {{item.address}}
-          </div>
-          <div class="view-count">
-            <img class="icon" src="@/assets/img/service/eye-white.png" alt="" draggable="false">
-            {{item.viewCount}}
-          </div>
-        </div>
-        <h2>{{item.title}}</h2>
-        <div class="bottom-wrap">
-          <div class="reco">
-            推荐指数:
-            <img v-for="index in item.reco" :key="index" class="" src="@/assets/img/service/star.png" alt="" draggable="false">
-          </div>
-          <div class="phone">
-            电话:{{item.phone}}
-          </div>
-        </div>
-      </article>
-    </div>
-    
-  </div>
-</template>
-
-<script>
-import SearchBar from "@/components/SearchTransparent.vue";
-import Select from "@/components/Select.vue";
-export default {
-  components: {
-    SearchBar,
-    Select,
-  },
-  data() {
-    return {
-      starIdx: 0,
-      areaIdx: 0,
-      recoLevelIdx: 0,
-      hotelList: [
-        {
-          img: require('@/assets/img/service/hotel.png'),
-          star: 5,
-          address: '镜湖区中山北路77号',
-          viewCount: 157,
-          title: '芜湖金鹰尚美酒店',
-          reco: 5,
-          phone: '0533-3888999',
-        },
-        {
-          img: require('@/assets/img/service/hotel.png'),
-          star: 5,
-          address: '镜湖区中山北路77号',
-          viewCount: 157,
-          title: '芜湖金鹰尚美酒店',
-          reco: 5,
-          phone: '0533-3888999',
-        },
-        {
-          img: require('@/assets/img/service/hotel.png'),
-          star: 5,
-          address: '镜湖区中山北路77号',
-          viewCount: 157,
-          title: '芜湖金鹰尚美酒店',
-          reco: 5,
-          phone: '0533-3888999',
-        },
-        {
-          img: require('@/assets/img/service/hotel.png'),
-          star: 5,
-          address: '镜湖区中山北路77号',
-          viewCount: 157,
-          title: '芜湖金鹰尚美酒店',
-          reco: 5,
-          phone: '0533-3888999',
-        },
-      ]
-    }
-  },
-  computed: {
-    starList() {
-      return [
-        '全部',
-        '五星',
-        '四星',
-        '三星',
-      ]
-    },
-    areaList() {
-      return [
-        '全部',
-        '景点一',
-        '景点二',
-        '景点三',
-      ]
-    },
-    recoLevelList() {
-      return [
-        '全部',
-        '五星',
-        '四星',
-        '三星',
-        '二星',
-        '一星',
-      ]
-    }
-  },
-  methods: {
-    onSearch() {
-
-    },
-    onClickHotelList(index) {
-      this.$router.push({name: 'HotelDetail'})
-    },
-  },
-}
-</script>
-
-<style lang="less" scoped>
-.hotel-list-page {
-  height: calc(100% - 80px);
-  background-color: #fff;
-  display: flex;
-  flex-direction: column;
-  > .banner-wrap {
-    flex: 0 0 auto;
-    height: 40vw;
-    background-image: url(~@/assets/img/service/hotel-banner.png);
-    background-size: cover;
-    background-repeat: no-repeat;
-    background-position: center center;
-    overflow: hidden;
-    margin-bottom: 4.1vw;
-    position: relative;
-    > .search-bar {
-      position: absolute;
-      bottom: 4.8vw;
-      left: 50%;
-      width: 80.1vw;
-      transform: translateX(-50%);
-    }
-  }
-  > .select-wrap {
-    flex: 0 0 auto;
-    margin: 0 4vw 4vw 4vw;
-    position: relative;
-    z-index: 1;
-    > .select {
-      display: inline-block;
-      margin-right: 5vw;
-    }
-  }
-  > .card-list {
-    flex: 1 0 1px;
-    margin-left: 4vw;
-    margin-right: 4vw;
-    overflow: auto;
-    > article {
-      padding-bottom: 2.7vw;
-      margin-bottom: 4vw;
-      > .img-wrap {
-        height: 53.3vw;
-        border-radius: 1.1vw;
-        position: relative;
-        overflow: hidden;
-        > img.photo {
-          position: absolute;
-          left: 0;
-          top: 0;
-          width: 100%;
-          height: 100%;
-          object-fit: cover;
-        }
-        > .star {
-          position: absolute;
-          top: 0;
-          right: 0;
-          background: rgba(200, 17, 17, 0.75);
-          padding: 2vw 2.5vw;
-          font-size: 4vwpx;
-          font-weight: 500;
-          color: #ffe400;
-        }
-        > .address {
-          position: absolute;
-          left: 2vw;
-          bottom: 2vw;
-          font-size: 3.2vw;
-          font-weight: 500;
-          color: #FFFFFF;
-          display: flex;
-          align-items: center;
-          > img.icon {
-            width: 2.7vw;
-            height: 3.6vw;
-            margin-right: 1.2vw;
-          }
-        }
-        > .view-count {
-          position: absolute;
-          right: 2.3vw;
-          bottom: 2vw;
-          font-size: 3.2vw;
-          font-weight: 500;
-          color: #FFFFFF;
-          display: flex;
-          align-items: center;
-          > img.icon {
-            width: 4.3vw;
-            height: 3.1vw;
-            margin-right: 1.3vw;
-          }
-        }
-      }
-      > h2 {
-        margin: 2.7vw 2vw 3vw 2vw;
-        font-size: 4.8vw;
-        font-weight: 500;
-        color: #515151;
-      }
-      > .bottom-wrap {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        margin: 0 2vw;
-        > .reco {
-          font-size: 3.5vw;
-          color: #515151;
-          > img {
-            width: 3.3vw;
-            height: 3.3vw;
-            margin-right: 0.2vw;
-          }
-        }
-        > .phone {
-          font-size: 3.5vw;
-          color: #515151;
-        }
-      }
-    }
-  }
-}
+<template>
+  <div class="hotel-list-page">
+    <div class="banner-wrap">
+      <SearchBar class="search-bar" @search="onSearch"></SearchBar>
+    </div>
+    <div class="select-wrap">
+      <Select
+        class="select"
+        :valueList="starList"
+        v-model="starIdx"
+        :placeholder="'星级'"
+      ></Select>
+      <Select
+        class="select"
+        v-model="areaIdx"
+        :valueList="areaList"
+        :placeholder="'景点周边'"
+      ></Select>
+      <Select
+        class="select"
+        v-model="recoLevelIdx"
+        :valueList="recoLevelList"
+        :placeholder="'推荐指数'"
+      ></Select>
+    </div>
+    
+    <div class="card-list">
+      <article
+        v-for="(item, index) in hotelList"
+        :key="index"
+        @click="onClickHotelList(index)"
+      >
+        <div class="img-wrap">
+          <img class="photo" :src="item.img" alt="" draggable="false">
+          <div class="star">{{item.star}}星级</div>
+          <div class="address">
+            <img class="icon" src="@/assets/img/service/address-white.png" alt="" draggable="false">
+            {{item.address}}
+          </div>
+          <div class="view-count">
+            <img class="icon" src="@/assets/img/service/eye-white.png" alt="" draggable="false">
+            {{item.viewCount}}
+          </div>
+        </div>
+        <h2>{{item.title}}</h2>
+        <div class="bottom-wrap">
+          <div class="reco">
+            推荐指数:
+            <img v-for="index in item.reco" :key="index" class="" src="@/assets/img/service/star.png" alt="" draggable="false">
+          </div>
+          <div class="phone">
+            电话:{{item.phone}}
+          </div>
+        </div>
+      </article>
+    </div>
+    
+  </div>
+</template>
+
+<script>
+import SearchBar from "@/components/SearchTransparent.vue";
+import Select from "@/components/Select.vue";
+export default {
+  components: {
+    SearchBar,
+    Select,
+  },
+  data() {
+    return {
+      starIdx: 0,
+      areaIdx: 0,
+      recoLevelIdx: 0,
+      hotelList: [
+        {
+          img: require('@/assets/img/service/hotel.png'),
+          star: 5,
+          address: '镜湖区中山北路77号',
+          viewCount: 157,
+          title: '芜湖金鹰尚美酒店',
+          reco: 5,
+          phone: '0533-3888999',
+        },
+        {
+          img: require('@/assets/img/service/hotel.png'),
+          star: 5,
+          address: '镜湖区中山北路77号',
+          viewCount: 157,
+          title: '芜湖金鹰尚美酒店',
+          reco: 5,
+          phone: '0533-3888999',
+        },
+        {
+          img: require('@/assets/img/service/hotel.png'),
+          star: 5,
+          address: '镜湖区中山北路77号',
+          viewCount: 157,
+          title: '芜湖金鹰尚美酒店',
+          reco: 5,
+          phone: '0533-3888999',
+        },
+        {
+          img: require('@/assets/img/service/hotel.png'),
+          star: 5,
+          address: '镜湖区中山北路77号',
+          viewCount: 157,
+          title: '芜湖金鹰尚美酒店',
+          reco: 5,
+          phone: '0533-3888999',
+        },
+      ]
+    }
+  },
+  computed: {
+    starList() {
+      return [
+        '全部',
+        '五星',
+        '四星',
+        '三星',
+      ]
+    },
+    areaList() {
+      return [
+        '全部',
+        '景点一',
+        '景点二',
+        '景点三',
+      ]
+    },
+    recoLevelList() {
+      return [
+        '全部',
+        '五星',
+        '四星',
+        '三星',
+        '二星',
+        '一星',
+      ]
+    }
+  },
+  methods: {
+    onSearch() {
+
+    },
+    onClickHotelList(index) {
+      this.$router.push({name: 'HotelDetail'})
+    },
+  },
+}
+</script>
+
+<style lang="less" scoped>
+.hotel-list-page {
+  height: calc(100% - 80px);
+  background-color: #fff;
+  display: flex;
+  flex-direction: column;
+  > .banner-wrap {
+    flex: 0 0 auto;
+    height: 40vw;
+    background-image: url(~@/assets/img/service/hotel-banner.png);
+    background-size: cover;
+    background-repeat: no-repeat;
+    background-position: center center;
+    overflow: hidden;
+    margin-bottom: 4.1vw;
+    position: relative;
+    > .search-bar {
+      position: absolute;
+      bottom: 4.8vw;
+      left: 50%;
+      width: 80.1vw;
+      transform: translateX(-50%);
+    }
+  }
+  > .select-wrap {
+    flex: 0 0 auto;
+    margin: 0 4vw 4vw 4vw;
+    position: relative;
+    z-index: 1;
+    > .select {
+      display: inline-block;
+      margin-right: 5vw;
+    }
+  }
+  > .card-list {
+    flex: 1 0 1px;
+    margin-left: 4vw;
+    margin-right: 4vw;
+    overflow: auto;
+    > article {
+      padding-bottom: 2.7vw;
+      margin-bottom: 4vw;
+      > .img-wrap {
+        height: 53.3vw;
+        border-radius: 1.1vw;
+        position: relative;
+        overflow: hidden;
+        > img.photo {
+          position: absolute;
+          left: 0;
+          top: 0;
+          width: 100%;
+          height: 100%;
+          object-fit: cover;
+        }
+        > .star {
+          position: absolute;
+          top: 0;
+          right: 0;
+          background: rgba(200, 17, 17, 0.75);
+          padding: 2vw 2.5vw;
+          font-size: 4vwpx;
+          font-weight: 500;
+          color: #ffe400;
+        }
+        > .address {
+          position: absolute;
+          left: 2vw;
+          bottom: 2vw;
+          font-size: 3.2vw;
+          font-weight: 500;
+          color: #FFFFFF;
+          display: flex;
+          align-items: center;
+          > img.icon {
+            width: 2.7vw;
+            height: 3.6vw;
+            margin-right: 1.2vw;
+          }
+        }
+        > .view-count {
+          position: absolute;
+          right: 2.3vw;
+          bottom: 2vw;
+          font-size: 3.2vw;
+          font-weight: 500;
+          color: #FFFFFF;
+          display: flex;
+          align-items: center;
+          > img.icon {
+            width: 4.3vw;
+            height: 3.1vw;
+            margin-right: 1.3vw;
+          }
+        }
+      }
+      > h2 {
+        margin: 2.7vw 2vw 3vw 2vw;
+        font-size: 4.8vw;
+        font-weight: 500;
+        color: #515151;
+      }
+      > .bottom-wrap {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin: 0 2vw;
+        > .reco {
+          font-size: 3.5vw;
+          color: #515151;
+          > img {
+            width: 3.3vw;
+            height: 3.3vw;
+            margin-right: 0.2vw;
+          }
+        }
+        > .phone {
+          font-size: 3.5vw;
+          color: #515151;
+        }
+      }
+    }
+  }
+}
 </style>

+ 173 - 173
yfyc/src/views/Serve/RecommendedPath.vue

@@ -1,174 +1,174 @@
-<template>
-  <div class="recommended-path">
-    <SearchBar class="search-bar" @search="onSearch"></SearchBar>
-    <div class="keywords">
-      <h2>推荐</h2>
-      <button
-        class="keyword"
-        v-for="(item, index) in recoKeywordList"
-        :key="index"
-        @click="onClickTag(item)"
-      >
-        {{item}}
-      </button>
-    </div>
-    <div class="card-list">
-      <article
-        v-for="n in 10"
-        :key="n"
-        @click="$router.push({name: 'RecommendedPathDetail'})"
-      >
-        <div class="left">
-          <img src="@/assets/img/service/一日游.png" alt="" draggable="false">
-        </div>
-        <div class="right">
-          <h3>【一日游】方特  欢乐世界+梦幻王国+中江塔+老海关客流数据格式的克里夫拉萨大家反抗拉萨酱豆腐考虑离开</h3>
-          <ul class="tags">
-            <li class="tag">一日游</li>
-            <li class="tag">自驾</li>
-          </ul>
-          <div class="bottom">
-            <div class="time">2022-10-10</div>
-            <div class="view-count">
-              <img class="icon" src="@/assets/img/service/eye.png" alt="" draggable="false">
-              666
-            </div>
-          </div>
-        </div>
-      </article>
-    </div>
-  </div>
-</template>
-
-<script>
-import SearchBar from "@/components/SearchRedBtn.vue";
-
-export default {
-  components: {
-    SearchBar,
-  },
-  data() {
-    return {
-      recoKeywordList: [
-        '一日游',
-        '古建筑',
-        '美食',
-        '快速浏览',
-        '美食',
-      ]
-    }
-  },
-  methods: {
-    onSearch(v) {
-      console.log('on search: ', v);
-    },
-    onClickTag(v) {
-      console.log('on click tag: ', v);
-    }
-  }
-}
-</script>
-
-<style lang="less" scoped>
-.recommended-path {
-  background-color: #fff;
-  height: calc(100% - 80px);
-  overflow: auto;
-  padding: 6.1vw 4.5vw 4.5vw 4.5vw;
-  display: flex;
-  flex-direction: column;
-  .search-bar {
-    flex: 0 0 auto;
-  }
-  .keywords {
-    margin-top: 4.1vw;
-    margin-right: -4.5vw;
-    flex: 0 0 auto;
-    > h2 {
-      font-size: 3.5vw;
-      font-weight: bold;
-      color: #000000;
-      margin-bottom: 3.2vw;
-    }
-    > button {
-      background: #F4F4F4;
-      border-radius: 0.5vw;
-      padding: 2.5vw 4vw;
-      font-size: 2.7vw;
-      color: #333333;
-      margin-right: 4.5vw;
-      margin-bottom: 3.2vw;
-    }
-  }
-  .card-list {
-    flex: 1 0 1px;
-    overflow: auto;
-    > article {
-      height: 29.6vw;
-      background: #F7F8FA;
-      box-shadow: 0vw 0.5vw 1.1vw 0vw rgba(109,128,166,0.29);
-      border-radius: 1.1vw;
-      overflow: hidden;
-      margin-right: 1.1vw;
-      margin-bottom: 5.6vw;
-      display: flex;
-      > .left {
-        height: 100%;
-        width: 21.3vw;
-        flex: 0 1 auto;
-        > img {
-          width: 100%;
-          height: 100%;
-          object-fit: cover;
-          border-radius: 1.1vw;
-        }
-      }
-      > .right {
-        flex: 0 1 auto;
-        width: 69.7vw;
-        padding: 2.2vw 2vw 2.7vw 2vw;
-        > h3 {
-          font-size: 3.2vw;
-          color: #333333;
-          line-height: 6.4vw;
-          display: -webkit-box;
-          -webkit-box-orient: vertical;
-          -webkit-line-clamp: 2;
-          overflow: hidden;
-          margin-bottom: 3vw;
-        }
-        > ul.tags {
-          margin-bottom: 2vw;
-          > li.tag {
-            border: 0.3vw solid #FE6E69;
-            border-radius: 0.5vw;
-            margin-right: 2.9vw;
-            padding: 0.8vw 2vw;
-            font-size: 2.7vw;
-            color: #FE6E69;
-            letter-spacing: 0.2em;
-          }
-        }
-        > .bottom {
-          display: flex;
-          justify-content: space-between;
-          align-items: center;
-          font-size: 2.7vw;
-          color: #333333;
-          > .time {
-          }
-          > .view-count {
-            display: flex;
-            align-items: center;
-            > img {
-              width: 3.3vw;
-              height: 2.5vw;
-              margin-right: 0.9vw;
-            }
-          }
-        }
-      }
-    }
-  }
-}
+<template>
+  <div class="recommended-path">
+    <SearchBar class="search-bar" @search="onSearch"></SearchBar>
+    <div class="keywords">
+      <h2>推荐</h2>
+      <button
+        class="keyword"
+        v-for="(item, index) in recoKeywordList"
+        :key="index"
+        @click="onClickTag(item)"
+      >
+        {{item}}
+      </button>
+    </div>
+    <div class="card-list">
+      <article
+        v-for="n in 10"
+        :key="n"
+        @click="$router.push({name: 'RecommendedPathDetail'})"
+      >
+        <div class="left">
+          <img src="@/assets/img/service/一日游.png" alt="" draggable="false">
+        </div>
+        <div class="right">
+          <h3>【一日游】方特  欢乐世界+梦幻王国+中江塔+老海关客流数据格式的克里夫拉萨大家反抗拉萨酱豆腐考虑离开</h3>
+          <ul class="tags">
+            <li class="tag">一日游</li>
+            <li class="tag">自驾</li>
+          </ul>
+          <div class="bottom">
+            <div class="time">2022-10-10</div>
+            <div class="view-count">
+              <img class="icon" src="@/assets/img/service/eye.png" alt="" draggable="false">
+              666
+            </div>
+          </div>
+        </div>
+      </article>
+    </div>
+  </div>
+</template>
+
+<script>
+import SearchBar from "@/components/SearchRedBtn.vue";
+
+export default {
+  components: {
+    SearchBar,
+  },
+  data() {
+    return {
+      recoKeywordList: [
+        '一日游',
+        '古建筑',
+        '美食',
+        '快速浏览',
+        '美食',
+      ]
+    }
+  },
+  methods: {
+    onSearch(v) {
+      console.log('on search: ', v);
+    },
+    onClickTag(v) {
+      console.log('on click tag: ', v);
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.recommended-path {
+  background-color: #fff;
+  height: calc(100% - 80px);
+  overflow: auto;
+  padding: 6.1vw 4.5vw 4.5vw 4.5vw;
+  display: flex;
+  flex-direction: column;
+  .search-bar {
+    flex: 0 0 auto;
+  }
+  .keywords {
+    margin-top: 4.1vw;
+    margin-right: -4.5vw;
+    flex: 0 0 auto;
+    > h2 {
+      font-size: 3.5vw;
+      font-weight: bold;
+      color: #000000;
+      margin-bottom: 3.2vw;
+    }
+    > button {
+      background: #F4F4F4;
+      border-radius: 0.5vw;
+      padding: 2.5vw 4vw;
+      font-size: 2.7vw;
+      color: #333333;
+      margin-right: 4.5vw;
+      margin-bottom: 3.2vw;
+    }
+  }
+  .card-list {
+    flex: 1 0 1px;
+    overflow: auto;
+    > article {
+      height: 29.6vw;
+      background: #F7F8FA;
+      box-shadow: 0vw 0.5vw 1.1vw 0vw rgba(109,128,166,0.29);
+      border-radius: 1.1vw;
+      overflow: hidden;
+      margin-right: 1.1vw;
+      margin-bottom: 5.6vw;
+      display: flex;
+      > .left {
+        height: 100%;
+        width: 21.3vw;
+        flex: 0 1 auto;
+        > img {
+          width: 100%;
+          height: 100%;
+          object-fit: cover;
+          border-radius: 1.1vw;
+        }
+      }
+      > .right {
+        flex: 0 1 auto;
+        width: 69.7vw;
+        padding: 2.2vw 2vw 2.7vw 2vw;
+        > h3 {
+          font-size: 3.2vw;
+          color: #333333;
+          line-height: 6.4vw;
+          display: -webkit-box;
+          -webkit-box-orient: vertical;
+          -webkit-line-clamp: 2;
+          overflow: hidden;
+          margin-bottom: 3vw;
+        }
+        > ul.tags {
+          margin-bottom: 2vw;
+          > li.tag {
+            border: 0.3vw solid #FE6E69;
+            border-radius: 0.5vw;
+            margin-right: 2.9vw;
+            padding: 0.8vw 2vw;
+            font-size: 2.7vw;
+            color: #FE6E69;
+            letter-spacing: 0.2em;
+          }
+        }
+        > .bottom {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          font-size: 2.7vw;
+          color: #333333;
+          > .time {
+          }
+          > .view-count {
+            display: flex;
+            align-items: center;
+            > img {
+              width: 3.3vw;
+              height: 2.5vw;
+              margin-right: 0.9vw;
+            }
+          }
+        }
+      }
+    }
+  }
+}
 </style>

+ 172 - 172
yfyc/src/views/Serve/RecommendedPathDetail.vue

@@ -1,173 +1,173 @@
-<template>
-  <div class="one-day-tour" id="back-top-target">
-    <h1>【一日游】方特欢乐世界 + 梦幻王国 + 中江塔 + 老海关</h1>
-    <ul class="tag-list">
-      <li
-        class="tag"
-        v-for="(item, index) in tagList"
-        :key="index"
-      >
-        {{item}}
-      </li>
-    </ul>
-    <article
-      v-for="(item, index) in landscapeList"
-      :key="index"
-    >
-      <img :src="item.img" alt="" draggable="false">
-      <h2>{{item.title}}</h2>
-      <p>{{item.content}}</p>
-      <div class="bottom-wrap">
-        <div class="address-wrap">
-          <img src="@/assets/img/service/address.png" alt="" draggable="false">
-          <span>{{item.address}}</span>
-        </div>
-        <div class="phone-wrap">
-          <img src="@/assets/img/service/phone.png" alt="" draggable="false">
-          <span>{{item.phone}}</span>
-        </div>
-      </div>
-    </article>
-
-    <BackTop class="back-top" :targetId="'back-top-target'">
-      <img src="@/assets/img/service/back-top.png" alt="" draggable="false">
-    </BackTop>
-  </div>
-</template>
-
-<script>
-import BackTop from "@/components/BackTop.vue";
-
-export default {
-  components: {
-    BackTop,
-  },
-  data() {
-    return {
-      tagList: [
-        '梦幻游乐王国',
-        '古建筑',
-        '美食',
-      ],
-      landscapeList: [
-        {
-          img: require('@/assets/img/service/【西洋建筑】.png'),
-          title: '方特欢乐世界',
-          content: '方特欢乐世界拥有多个超大型项目,如国际一流的高空飞翔体验VR Soaring项目《飞越极限》,妙趣奇幻的大型MR Theater项目《海螺湾》,大型恐龙复活灾难体验MR Ride项目《恐龙危机》,惊险刺激的悬挂式过山车《火流星》,大型火山探险项目《维苏威火山》,专为小朋友量身设计的主题项目区《儿童王国》、主题卡通表演项目《熊出没舞台》等。',
-          address: '安徽省芜湖市镜湖区银湖北路80号',
-          phone: '400-166-0006',
-        },
-        {
-          img: require('@/assets/img/service/【西洋建筑】.png'),
-          title: '方特欢乐世界',
-          content: '方特欢乐世界拥有多个超大型项目,如国际一流的高空飞翔体验VR Soaring项目《飞越极限》,妙趣奇幻的大型MR Theater项目《海螺湾》,大型恐龙复活灾难体验MR Ride项目《恐龙危机》,惊险刺激的悬挂式过山车《火流星》,大型火山探险项目《维苏威火山》,专为小朋友量身设计的主题项目区《儿童王国》、主题卡通表演项目《熊出没舞台》等。',
-          address: '安徽省芜湖市镜湖区银湖北路80号',
-          phone: '400-166-0006',
-        },
-        {
-          img: require('@/assets/img/service/【西洋建筑】.png'),
-          title: '方特欢乐世界',
-          content: '方特欢乐世界拥有多个超大型项目,如国际一流的高空飞翔体验VR Soaring项目《飞越极限》,妙趣奇幻的大型MR Theater项目《海螺湾》,大型恐龙复活灾难体验MR Ride项目《恐龙危机》,惊险刺激的悬挂式过山车《火流星》,大型火山探险项目《维苏威火山》,专为小朋友量身设计的主题项目区《儿童王国》、主题卡通表演项目《熊出没舞台》等。',
-          address: '安徽省芜湖市镜湖区银湖北路80号',
-          phone: '400-166-0006',
-        },
-        {
-          img: require('@/assets/img/service/【西洋建筑】.png'),
-          title: '方特欢乐世界',
-          content: '方特欢乐世界拥有多个超大型项目,如国际一流的高空飞翔体验VR Soaring项目《飞越极限》,妙趣奇幻的大型MR Theater项目《海螺湾》,大型恐龙复活灾难体验MR Ride项目《恐龙危机》,惊险刺激的悬挂式过山车《火流星》,大型火山探险项目《维苏威火山》,专为小朋友量身设计的主题项目区《儿童王国》、主题卡通表演项目《熊出没舞台》等。',
-          address: '安徽省芜湖市镜湖区银湖北路80号',
-          phone: '400-166-0006',
-        },
-      ]
-    }
-  },
-}
-</script>
-
-<style lang="less" scoped>
-.one-day-tour {
-  background-color: #fff;
-  height: calc(100% - 80px);
-  overflow: auto;
-  > h1 {
-    margin-top: 3.2vw;
-    margin-bottom: 3.2vw;
-    margin-left: 4.5vw;
-    margin-right: 4.5vw;
-    font-size: 3.5vw;
-    font-weight: bold;
-    color: #000000;
-  }
-  > .tag-list {
-    margin-bottom: 5.1vw;
-    margin-left: 4.5vw;
-    display: block;
-    > .tag {
-      background: #F4F4F4;
-      border-radius: 0.5vw;
-      padding: 2.5vw 4vw;
-      font-size: 2.7vw;
-      color: #333333;
-      margin-right: 4.5vw;
-      margin-bottom: 3.2vw;
-      display: inline-block;
-      overflow: hidden;
-    }
-  }
-  > article {
-    margin: 0 4.5vw 8.1vw 4.5vw;
-    background: #F7F8FA;
-    box-shadow: 0px 0.5vw 1.1vw 0px rgba(109,128,166,0.29);
-    border-radius: 1.1vw;
-    overflow: hidden;
-    > img {
-      width: 100%;
-      margin-bottom: 3.1vw;
-    }
-    > h2 {
-      margin: 0 2.1vw 2.8vw 2.1vw;
-      font-size: 3.2vw;
-      font-weight: bold;
-      color: #333333;
-    }
-    > p {
-      margin: 0 2.1vw 7.6vw 2.1vw;
-      font-size: 2.9vw;
-      line-height: 6.7vw;
-      color: #535353;
-      text-indent: 2em;
-    }
-    > .bottom-wrap {
-      margin: 0 2.1vw 4.7vw 2.1vw;
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      > .address-wrap, .phone-wrap {
-        display: flex;
-        align-items: center;
-        margin-right: 3vw;
-        > img {
-          width: 3.2vw;
-          height: 3.2vw;
-          margin-right: 0.9vw;
-        }
-        > span {
-          font-size: 2.7vw;
-          color: #FE6E69;
-        }
-      }
-    }
-  }
-  > .back-top {
-    position: fixed;
-    bottom: calc(1.7vw + 80px);
-    right: 1.7vw;
-    width: 9.3vw;
-    height: 9.3vw;
-    > img {
-      width: 100%;
-      height: 100%;
-    }
-  }
-}
+<template>
+  <div class="one-day-tour" id="back-top-target">
+    <h1>【一日游】方特欢乐世界 + 梦幻王国 + 中江塔 + 老海关</h1>
+    <ul class="tag-list">
+      <li
+        class="tag"
+        v-for="(item, index) in tagList"
+        :key="index"
+      >
+        {{item}}
+      </li>
+    </ul>
+    <article
+      v-for="(item, index) in landscapeList"
+      :key="index"
+    >
+      <img :src="item.img" alt="" draggable="false">
+      <h2>{{item.title}}</h2>
+      <p>{{item.content}}</p>
+      <div class="bottom-wrap">
+        <div class="address-wrap">
+          <img src="@/assets/img/service/address.png" alt="" draggable="false">
+          <span>{{item.address}}</span>
+        </div>
+        <div class="phone-wrap">
+          <img src="@/assets/img/service/phone.png" alt="" draggable="false">
+          <span>{{item.phone}}</span>
+        </div>
+      </div>
+    </article>
+
+    <BackTop class="back-top" :targetId="'back-top-target'">
+      <img src="@/assets/img/service/back-top.png" alt="" draggable="false">
+    </BackTop>
+  </div>
+</template>
+
+<script>
+import BackTop from "@/components/BackTop.vue";
+
+export default {
+  components: {
+    BackTop,
+  },
+  data() {
+    return {
+      tagList: [
+        '梦幻游乐王国',
+        '古建筑',
+        '美食',
+      ],
+      landscapeList: [
+        {
+          img: require('@/assets/img/service/【西洋建筑】.png'),
+          title: '方特欢乐世界',
+          content: '方特欢乐世界拥有多个超大型项目,如国际一流的高空飞翔体验VR Soaring项目《飞越极限》,妙趣奇幻的大型MR Theater项目《海螺湾》,大型恐龙复活灾难体验MR Ride项目《恐龙危机》,惊险刺激的悬挂式过山车《火流星》,大型火山探险项目《维苏威火山》,专为小朋友量身设计的主题项目区《儿童王国》、主题卡通表演项目《熊出没舞台》等。',
+          address: '安徽省芜湖市镜湖区银湖北路80号',
+          phone: '400-166-0006',
+        },
+        {
+          img: require('@/assets/img/service/【西洋建筑】.png'),
+          title: '方特欢乐世界',
+          content: '方特欢乐世界拥有多个超大型项目,如国际一流的高空飞翔体验VR Soaring项目《飞越极限》,妙趣奇幻的大型MR Theater项目《海螺湾》,大型恐龙复活灾难体验MR Ride项目《恐龙危机》,惊险刺激的悬挂式过山车《火流星》,大型火山探险项目《维苏威火山》,专为小朋友量身设计的主题项目区《儿童王国》、主题卡通表演项目《熊出没舞台》等。',
+          address: '安徽省芜湖市镜湖区银湖北路80号',
+          phone: '400-166-0006',
+        },
+        {
+          img: require('@/assets/img/service/【西洋建筑】.png'),
+          title: '方特欢乐世界',
+          content: '方特欢乐世界拥有多个超大型项目,如国际一流的高空飞翔体验VR Soaring项目《飞越极限》,妙趣奇幻的大型MR Theater项目《海螺湾》,大型恐龙复活灾难体验MR Ride项目《恐龙危机》,惊险刺激的悬挂式过山车《火流星》,大型火山探险项目《维苏威火山》,专为小朋友量身设计的主题项目区《儿童王国》、主题卡通表演项目《熊出没舞台》等。',
+          address: '安徽省芜湖市镜湖区银湖北路80号',
+          phone: '400-166-0006',
+        },
+        {
+          img: require('@/assets/img/service/【西洋建筑】.png'),
+          title: '方特欢乐世界',
+          content: '方特欢乐世界拥有多个超大型项目,如国际一流的高空飞翔体验VR Soaring项目《飞越极限》,妙趣奇幻的大型MR Theater项目《海螺湾》,大型恐龙复活灾难体验MR Ride项目《恐龙危机》,惊险刺激的悬挂式过山车《火流星》,大型火山探险项目《维苏威火山》,专为小朋友量身设计的主题项目区《儿童王国》、主题卡通表演项目《熊出没舞台》等。',
+          address: '安徽省芜湖市镜湖区银湖北路80号',
+          phone: '400-166-0006',
+        },
+      ]
+    }
+  },
+}
+</script>
+
+<style lang="less" scoped>
+.one-day-tour {
+  background-color: #fff;
+  height: calc(100% - 80px);
+  overflow: auto;
+  > h1 {
+    margin-top: 3.2vw;
+    margin-bottom: 3.2vw;
+    margin-left: 4.5vw;
+    margin-right: 4.5vw;
+    font-size: 3.5vw;
+    font-weight: bold;
+    color: #000000;
+  }
+  > .tag-list {
+    margin-bottom: 5.1vw;
+    margin-left: 4.5vw;
+    display: block;
+    > .tag {
+      background: #F4F4F4;
+      border-radius: 0.5vw;
+      padding: 2.5vw 4vw;
+      font-size: 2.7vw;
+      color: #333333;
+      margin-right: 4.5vw;
+      margin-bottom: 3.2vw;
+      display: inline-block;
+      overflow: hidden;
+    }
+  }
+  > article {
+    margin: 0 4.5vw 8.1vw 4.5vw;
+    background: #F7F8FA;
+    box-shadow: 0px 0.5vw 1.1vw 0px rgba(109,128,166,0.29);
+    border-radius: 1.1vw;
+    overflow: hidden;
+    > img {
+      width: 100%;
+      margin-bottom: 3.1vw;
+    }
+    > h2 {
+      margin: 0 2.1vw 2.8vw 2.1vw;
+      font-size: 3.2vw;
+      font-weight: bold;
+      color: #333333;
+    }
+    > p {
+      margin: 0 2.1vw 7.6vw 2.1vw;
+      font-size: 2.9vw;
+      line-height: 6.7vw;
+      color: #535353;
+      text-indent: 2em;
+    }
+    > .bottom-wrap {
+      margin: 0 2.1vw 4.7vw 2.1vw;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      > .address-wrap, .phone-wrap {
+        display: flex;
+        align-items: center;
+        margin-right: 3vw;
+        > img {
+          width: 3.2vw;
+          height: 3.2vw;
+          margin-right: 0.9vw;
+        }
+        > span {
+          font-size: 2.7vw;
+          color: #FE6E69;
+        }
+      }
+    }
+  }
+  > .back-top {
+    position: fixed;
+    bottom: calc(1.7vw + 80px);
+    right: 1.7vw;
+    width: 9.3vw;
+    height: 9.3vw;
+    > img {
+      width: 100%;
+      height: 100%;
+    }
+  }
+}
 </style>

+ 301 - 301
yfyc/src/views/Serve/TravelPlague.vue

@@ -1,302 +1,302 @@
-<template>
-  <div class="dont-miss">
-    <SearchBar class="search-bar" @search="onSearch"></SearchBar>
-    <TabbarSmall :tabList="['景点开放', '出行政策']" @change="onTabbarChange"></TabbarSmall>
-
-    <div class="card-wrap" v-show="activeTabbarIdx === 0">
-      <article
-        v-for="(item, index) in attractionList"
-        :key="index"
-      >
-        <img :src="item.img" alt="" draggable="false">
-        <h2>{{item.title}}</h2>
-        <div class="location">
-          <img class="icon" src="@/assets/img/service/address.png" alt="" draggable="false">
-          <span>{{item.location}}</span>
-        </div>
-      </article>
-    </div>
-    
-    <div class="policy" v-show="activeTabbarIdx === 1">
-      <div class="banner-wrap">
-        <img class="banner" src="@/assets/img/service/plague-banner.jpg" alt="" draggable="false">
-      </div>
-      <ul class="tag-list">
-        <li
-          class="tag"
-          v-for="(item, index) in policyTagList"
-          :key="index"
-        >
-          {{item}}
-        </li>
-      </ul>
-      <div class="article-wrap">
-        <article
-          v-for="(item, index) in policyList"
-          :key="index"
-        >
-          <div class="left-wrap">
-            <h2>{{item.title}}</h2>
-            <span class="time">{{item.time}}</span>
-          </div>
-          <div class="right-wrap">
-            <img :src="item.img" alt="" draggable="false">
-          </div>
-        </article>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import SearchBar from "@/components/SearchRedBtn.vue";
-import TabbarSmall from "@/components/TabbarSmall.vue";
-// import Select from "@/components/Select.vue";
-
-export default {
-  components: {
-    SearchBar,
-    TabbarSmall,
-    // Select,
-  },
-  data() {
-    return {
-      activeTabbarIdx: 0,
-      attractionList: [
-        {
-          img: require(`@/assets/img/service/【西洋建筑】.png`),
-          title: '芜湖老海关',
-          location: '芜湖市新芜区滨江北路',
-        },
-        {
-          img: require(`@/assets/img/service/【西洋建筑】.png`),
-          title: '芜湖老海关',
-          location: '芜湖市新芜区滨江北路',
-        },
-        {
-          img: require(`@/assets/img/service/【西洋建筑】.png`),
-          title: '芜湖老海关',
-          location: '芜湖市新芜区滨江北路',
-        },
-        {
-          img: require(`@/assets/img/service/【西洋建筑】.png`),
-          title: '芜湖老海关',
-          location: '芜湖市新芜区滨江北路',
-        },
-        {
-          img: require(`@/assets/img/service/【西洋建筑】.png`),
-          title: '芜湖老海关',
-          location: '芜湖市新芜区滨江北路',
-        },
-        {
-          img: require(`@/assets/img/service/【西洋建筑】.png`),
-          title: '芜湖老海关',
-          location: '芜湖市新芜区滨江北路',
-        },
-        {
-          img: require(`@/assets/img/service/【西洋建筑】.png`),
-          title: '芜湖老海关',
-          location: '芜湖市新芜区滨江北路',
-        },
-        {
-          img: require(`@/assets/img/service/【西洋建筑】.png`),
-          title: '芜湖老海关',
-          location: '芜湖市新芜区滨江北路',
-        },
-      ],
-      policyTagList: [
-        '来(返)芜湖政策',
-        '离芜出行政策',
-        '核酸检测',
-      ],
-      policyList: [
-        {
-          title: '来(返)芜湖人员健康管理风险提醒',
-          time: '20222-10-10       17:00:52',
-          img: require('@/assets/img/service/plague-banner.jpg')
-        },
-        {
-          title: '来(返)芜湖人员健康管理风险提醒',
-          time: '20222-10-10       17:00:52',
-          img: require('@/assets/img/service/plague-banner.jpg')
-        },
-        {
-          title: '来(返)芜湖人员健康管理风险提醒',
-          time: '20222-10-10       17:00:52',
-          img: require('@/assets/img/service/plague-banner.jpg')
-        },
-        {
-          title: '来(返)芜湖人员健康管理风险提醒',
-          time: '20222-10-10       17:00:52',
-          img: require('@/assets/img/service/plague-banner.jpg')
-        },
-        {
-          title: '来(返)芜湖人员健康管理风险提醒',
-          time: '20222-10-10       17:00:52',
-          img: require('@/assets/img/service/plague-banner.jpg')
-        },
-        {
-          title: '来(返)芜湖人员健康管理风险提醒',
-          time: '20222-10-10       17:00:52',
-          img: require('@/assets/img/service/plague-banner.jpg')
-        },
-      ]
-    }
-  },
-  computed: {
-  },
-  methods: {
-    onSearch() {
-
-    },
-    onTabbarChange(idx) {
-      this.activeTabbarIdx = idx
-    }
-  }
-}
-</script>
-
-<style lang="less" scoped>
-.dont-miss {
-  background-color: #fff;
-  height: calc(100% - 80px);
-  overflow: auto;
-  padding: 3.3vw 4.5vw 4.5vw 4.5vw;
-  display: flex;
-  flex-direction: column;
-  > .search-bar {
-    flex: 0 0 auto;
-  }
-  > .select-wrap {
-    flex: 0;
-    margin: 3.5vw 0 4vw 0;
-    > .select {
-      width: 15vw;
-      display: inline-block;
-      margin-right: 12.5vw;
-    }
-  }
-  > .card-wrap {
-    flex: 1 0 1px;
-    overflow: auto;
-    margin-right: -4vw;
-    > article {
-      width: 43.6vw;
-      height: 62.7vw;
-      display: inline-block;
-      background: #F7F8FA;
-      border-radius: 1.1vw;
-      overflow: hidden;
-      margin-right: 3.5vw;
-      margin-bottom: 4vw;
-      > img {
-        width: 100%;
-        height: 44.5vw;
-        object-fit: cover;
-        margin-right: 1.7vw;
-      }
-      > h2 {
-        font-size: 3.2vwx;
-        font-family: Source Han Serif CN;
-        font-weight: bold;
-        color: #333333;
-        line-height: 40px;
-        margin-left: 2.3vw;
-        margin-right: 2.3vw;
-        margin-bottom: 4.4vw;
-        font-size: 3.2vw;
-        font-weight: bold;
-        color: #333333;
-        line-height: 4vw;
-        overflow: hidden;
-        white-space: pre;
-        text-overflow: ellipsis;
-      }
-      > .location {
-        margin-left: 2.3vw;
-        margin-right: 2.3vw;
-        display: flex;
-        align-items: center;
-        > img {
-          width: 3.2vw;
-          height: 3.2vw;
-          margin-right: 1.1vw;
-        }
-        > span {
-          font-size: 2.7vw;
-          color: #333333;
-          overflow: hidden;
-          white-space: pre;
-          text-overflow: ellipsis;
-        }
-      }
-    }
-  }
-  > .policy {
-    > .banner-wrap {
-      border-radius: 1.1vw;
-      overflow: hidden;
-      margin-bottom: 5.6vw;
-      > .banner {
-        width: 100%;
-      }
-    }
-    > .tag-list {
-      display: block;
-      margin-top: calc(9.2vw - 3.2vw);
-      > .tag {
-        background: #F4F4F4;
-        border-radius: 0.5vw;
-        padding: 2.5vw 4vw;
-        font-size: 2.7vw;
-        color: #333333;
-        margin-right: 4.5vw;
-        margin-bottom: 3.2vw;
-        display: inline-block;
-        overflow: hidden;
-      }
-    }
-    > .article-wrap {
-      height: 28vw;
-      > article {
-        background: #F7F8FA;
-        border-radius: 1.1vw;
-        display: flex;
-        overflow: hidden;
-        margin-bottom: 6vw;
-        > .left-wrap {
-          flex: 0 1 auto;
-          width: 47.7vw;
-          padding: 5.2vw 3.5vw;
-          display: flex;
-          flex-direction: column;
-          justify-content: space-between;
-          > h2 {
-            font-size: 3.2vw;
-            font-weight: bold;
-            color: #333333;
-            line-height: 4vw;
-            display: -webkit-box;
-            -webkit-box-orient: vertical;
-            -webkit-line-clamp: 2;
-            overflow: hidden;
-          }
-          > .time {
-            font-size: 2.7vw;
-            color: #333333;
-          }
-        }
-        > .right-wrap {
-          flex: 0 1 auto;
-          width: 43.6vw;
-          > img {
-            width: 100%;
-            height: 100%;
-            object-fit: cover;
-          }
-        }
-      }
-    }
-  }
-}
+<template>
+  <div class="dont-miss">
+    <SearchBar class="search-bar" @search="onSearch"></SearchBar>
+    <TabbarSmall :tabList="['景点开放', '出行政策']" @change="onTabbarChange"></TabbarSmall>
+
+    <div class="card-wrap" v-show="activeTabbarIdx === 0">
+      <article
+        v-for="(item, index) in attractionList"
+        :key="index"
+      >
+        <img :src="item.img" alt="" draggable="false">
+        <h2>{{item.title}}</h2>
+        <div class="location">
+          <img class="icon" src="@/assets/img/service/address.png" alt="" draggable="false">
+          <span>{{item.location}}</span>
+        </div>
+      </article>
+    </div>
+    
+    <div class="policy" v-show="activeTabbarIdx === 1">
+      <div class="banner-wrap">
+        <img class="banner" src="@/assets/img/service/plague-banner.jpg" alt="" draggable="false">
+      </div>
+      <ul class="tag-list">
+        <li
+          class="tag"
+          v-for="(item, index) in policyTagList"
+          :key="index"
+        >
+          {{item}}
+        </li>
+      </ul>
+      <div class="article-wrap">
+        <article
+          v-for="(item, index) in policyList"
+          :key="index"
+        >
+          <div class="left-wrap">
+            <h2>{{item.title}}</h2>
+            <span class="time">{{item.time}}</span>
+          </div>
+          <div class="right-wrap">
+            <img :src="item.img" alt="" draggable="false">
+          </div>
+        </article>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import SearchBar from "@/components/SearchRedBtn.vue";
+import TabbarSmall from "@/components/TabbarSmall.vue";
+// import Select from "@/components/Select.vue";
+
+export default {
+  components: {
+    SearchBar,
+    TabbarSmall,
+    // Select,
+  },
+  data() {
+    return {
+      activeTabbarIdx: 0,
+      attractionList: [
+        {
+          img: require(`@/assets/img/service/【西洋建筑】.png`),
+          title: '芜湖老海关',
+          location: '芜湖市新芜区滨江北路',
+        },
+        {
+          img: require(`@/assets/img/service/【西洋建筑】.png`),
+          title: '芜湖老海关',
+          location: '芜湖市新芜区滨江北路',
+        },
+        {
+          img: require(`@/assets/img/service/【西洋建筑】.png`),
+          title: '芜湖老海关',
+          location: '芜湖市新芜区滨江北路',
+        },
+        {
+          img: require(`@/assets/img/service/【西洋建筑】.png`),
+          title: '芜湖老海关',
+          location: '芜湖市新芜区滨江北路',
+        },
+        {
+          img: require(`@/assets/img/service/【西洋建筑】.png`),
+          title: '芜湖老海关',
+          location: '芜湖市新芜区滨江北路',
+        },
+        {
+          img: require(`@/assets/img/service/【西洋建筑】.png`),
+          title: '芜湖老海关',
+          location: '芜湖市新芜区滨江北路',
+        },
+        {
+          img: require(`@/assets/img/service/【西洋建筑】.png`),
+          title: '芜湖老海关',
+          location: '芜湖市新芜区滨江北路',
+        },
+        {
+          img: require(`@/assets/img/service/【西洋建筑】.png`),
+          title: '芜湖老海关',
+          location: '芜湖市新芜区滨江北路',
+        },
+      ],
+      policyTagList: [
+        '来(返)芜湖政策',
+        '离芜出行政策',
+        '核酸检测',
+      ],
+      policyList: [
+        {
+          title: '来(返)芜湖人员健康管理风险提醒',
+          time: '20222-10-10       17:00:52',
+          img: require('@/assets/img/service/plague-banner.jpg')
+        },
+        {
+          title: '来(返)芜湖人员健康管理风险提醒',
+          time: '20222-10-10       17:00:52',
+          img: require('@/assets/img/service/plague-banner.jpg')
+        },
+        {
+          title: '来(返)芜湖人员健康管理风险提醒',
+          time: '20222-10-10       17:00:52',
+          img: require('@/assets/img/service/plague-banner.jpg')
+        },
+        {
+          title: '来(返)芜湖人员健康管理风险提醒',
+          time: '20222-10-10       17:00:52',
+          img: require('@/assets/img/service/plague-banner.jpg')
+        },
+        {
+          title: '来(返)芜湖人员健康管理风险提醒',
+          time: '20222-10-10       17:00:52',
+          img: require('@/assets/img/service/plague-banner.jpg')
+        },
+        {
+          title: '来(返)芜湖人员健康管理风险提醒',
+          time: '20222-10-10       17:00:52',
+          img: require('@/assets/img/service/plague-banner.jpg')
+        },
+      ]
+    }
+  },
+  computed: {
+  },
+  methods: {
+    onSearch() {
+
+    },
+    onTabbarChange(idx) {
+      this.activeTabbarIdx = idx
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.dont-miss {
+  background-color: #fff;
+  height: calc(100% - 80px);
+  overflow: auto;
+  padding: 3.3vw 4.5vw 4.5vw 4.5vw;
+  display: flex;
+  flex-direction: column;
+  > .search-bar {
+    flex: 0 0 auto;
+  }
+  > .select-wrap {
+    flex: 0;
+    margin: 3.5vw 0 4vw 0;
+    > .select {
+      width: 15vw;
+      display: inline-block;
+      margin-right: 12.5vw;
+    }
+  }
+  > .card-wrap {
+    flex: 1 0 1px;
+    overflow: auto;
+    margin-right: -4vw;
+    > article {
+      width: 43.6vw;
+      height: 62.7vw;
+      display: inline-block;
+      background: #F7F8FA;
+      border-radius: 1.1vw;
+      overflow: hidden;
+      margin-right: 3.5vw;
+      margin-bottom: 4vw;
+      > img {
+        width: 100%;
+        height: 44.5vw;
+        object-fit: cover;
+        margin-right: 1.7vw;
+      }
+      > h2 {
+        font-size: 3.2vwx;
+        font-family: Source Han Serif CN;
+        font-weight: bold;
+        color: #333333;
+        line-height: 40px;
+        margin-left: 2.3vw;
+        margin-right: 2.3vw;
+        margin-bottom: 4.4vw;
+        font-size: 3.2vw;
+        font-weight: bold;
+        color: #333333;
+        line-height: 4vw;
+        overflow: hidden;
+        white-space: pre;
+        text-overflow: ellipsis;
+      }
+      > .location {
+        margin-left: 2.3vw;
+        margin-right: 2.3vw;
+        display: flex;
+        align-items: center;
+        > img {
+          width: 3.2vw;
+          height: 3.2vw;
+          margin-right: 1.1vw;
+        }
+        > span {
+          font-size: 2.7vw;
+          color: #333333;
+          overflow: hidden;
+          white-space: pre;
+          text-overflow: ellipsis;
+        }
+      }
+    }
+  }
+  > .policy {
+    > .banner-wrap {
+      border-radius: 1.1vw;
+      overflow: hidden;
+      margin-bottom: 5.6vw;
+      > .banner {
+        width: 100%;
+      }
+    }
+    > .tag-list {
+      display: block;
+      margin-top: calc(9.2vw - 3.2vw);
+      > .tag {
+        background: #F4F4F4;
+        border-radius: 0.5vw;
+        padding: 2.5vw 4vw;
+        font-size: 2.7vw;
+        color: #333333;
+        margin-right: 4.5vw;
+        margin-bottom: 3.2vw;
+        display: inline-block;
+        overflow: hidden;
+      }
+    }
+    > .article-wrap {
+      height: 28vw;
+      > article {
+        background: #F7F8FA;
+        border-radius: 1.1vw;
+        display: flex;
+        overflow: hidden;
+        margin-bottom: 6vw;
+        > .left-wrap {
+          flex: 0 1 auto;
+          width: 47.7vw;
+          padding: 5.2vw 3.5vw;
+          display: flex;
+          flex-direction: column;
+          justify-content: space-between;
+          > h2 {
+            font-size: 3.2vw;
+            font-weight: bold;
+            color: #333333;
+            line-height: 4vw;
+            display: -webkit-box;
+            -webkit-box-orient: vertical;
+            -webkit-line-clamp: 2;
+            overflow: hidden;
+          }
+          > .time {
+            font-size: 2.7vw;
+            color: #333333;
+          }
+        }
+        > .right-wrap {
+          flex: 0 1 auto;
+          width: 43.6vw;
+          > img {
+            width: 100%;
+            height: 100%;
+            object-fit: cover;
+          }
+        }
+      }
+    }
+  }
+}
 </style>