PC-202203141647\Administrator 3 vuotta sitten
commit
003d37b8c6
79 muutettua tiedostoa jossa 3534 lisäystä ja 0 poistoa
  1. 3 0
      .browserslistrc
  2. 5 0
      .editorconfig
  3. 17 0
      .eslintrc.js
  4. 24 0
      .gitignore
  5. 5 0
      .prettierrc.json
  6. 31 0
      README.md
  7. 5 0
      babel.config.js
  8. 40 0
      package.json
  9. BIN
      public/favicon.ico
  10. 38 0
      public/index.html
  11. 5 0
      src/Api/apiList.js
  12. 3 0
      src/Api/baseUrl.js
  13. 105 0
      src/App.vue
  14. BIN
      src/assets/Dinner_b_1.png
  15. BIN
      src/assets/Dinner_breakfas.png
  16. BIN
      src/assets/Dinner_lunch.png
  17. BIN
      src/assets/Dinner_supper.png
  18. BIN
      src/assets/ProfilePhoto.png
  19. BIN
      src/assets/Purple.png
  20. BIN
      src/assets/back.png
  21. 6 0
      src/assets/css/font.css
  22. 92 0
      src/assets/css/reset.css
  23. BIN
      src/assets/exit.png
  24. BIN
      src/assets/font/pf.ttf
  25. BIN
      src/assets/head-icon/logo.png
  26. BIN
      src/assets/hight.png
  27. BIN
      src/assets/home.png
  28. BIN
      src/assets/icon_action_help.png
  29. BIN
      src/assets/icon_action_help_outline.png
  30. BIN
      src/assets/leftOrRight/left.png
  31. BIN
      src/assets/leftOrRight/right.png
  32. BIN
      src/assets/left_arrow.png
  33. BIN
      src/assets/logo.png
  34. BIN
      src/assets/menu_1.png
  35. BIN
      src/assets/menu_2.png
  36. BIN
      src/assets/menu_3.png
  37. BIN
      src/assets/menu_4.png
  38. BIN
      src/assets/menu_5.png
  39. BIN
      src/assets/menu_6.png
  40. BIN
      src/assets/no_data.png
  41. BIN
      src/assets/people_dark.png
  42. BIN
      src/assets/star.png
  43. BIN
      src/assets/tab-icons/exit.png
  44. BIN
      src/assets/tab-icons/pepole.png
  45. BIN
      src/assets/tab-icons/tab-1-select.jpg
  46. BIN
      src/assets/tab-icons/tab-2.jpg
  47. BIN
      src/assets/tab-icons/tab-3.jpg
  48. BIN
      src/assets/tab-icons/to_home_icon.png
  49. BIN
      src/assets/tip.png
  50. BIN
      src/assets/top-head/headimg.jpg
  51. BIN
      src/assets/top-head/headimg1.jpg
  52. BIN
      src/assets/top-head/headimg2.jpg
  53. BIN
      src/assets/union.png
  54. BIN
      src/assets/weight.png
  55. 214 0
      src/components/BottomTab.vue
  56. 99 0
      src/components/Echarts/BrokenLine.vue
  57. 111 0
      src/components/Echarts/Score.vue
  58. 250 0
      src/components/HeaderApp.vue
  59. 22 0
      src/components/HealthEval/HealthEvalList.vue
  60. 15 0
      src/components/HealthEval/HealthEvalListItem.vue
  61. 96 0
      src/components/LevelDescription.vue
  62. 126 0
      src/components/ScoreProgress.vue
  63. 63 0
      src/components/SuitList.vue
  64. 102 0
      src/components/WeekDays.vue
  65. 699 0
      src/components/public/Calendar.vue
  66. 10 0
      src/main.js
  67. 65 0
      src/router/index.js
  68. 24 0
      src/store/index.js
  69. 219 0
      src/utils/dateUtils
  70. 3 0
      src/utils/index.js
  71. 5 0
      src/views/AboutView.vue
  72. 15 0
      src/views/HealthEduOnline.vue
  73. 19 0
      src/views/HealthEval.vue
  74. 27 0
      src/views/HomeView.vue
  75. 13 0
      src/views/MyContract.vue
  76. 158 0
      src/views/MyHealth.vue
  77. 221 0
      src/views/MyNutrition.vue
  78. 564 0
      src/views/home/home.vue
  79. 15 0
      vue.config.js

+ 3 - 0
.browserslistrc

@@ -0,0 +1,3 @@
+> 1%
+last 2 versions
+not dead

+ 5 - 0
.editorconfig

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

+ 17 - 0
.eslintrc.js

@@ -0,0 +1,17 @@
+module.exports = {
+  root: true,
+  env: {
+    node: true
+  },
+  extends: [
+    'plugin:vue/vue3-essential',
+    '@vue/standard'
+  ],
+  parserOptions: {
+    parser: 'babel-eslint'
+  },
+  rules: {
+    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
+    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
+  }
+}

+ 24 - 0
.gitignore

@@ -0,0 +1,24 @@
+.DS_Store
+node_modules
+/dist
+
+
+# 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?
+package-lock.json

+ 5 - 0
.prettierrc.json

@@ -0,0 +1,5 @@
+{
+  "semi": false,
+  "singleQuote": true,
+  "trailingComma": "none"
+}

+ 31 - 0
README.md

@@ -0,0 +1,31 @@
+### 1. 项目目录介绍
+
+```shell
+src
+	api	--接口请求封装目录
+	components	--公共组件目录
+	router	--路由部分
+	store	--公共状态库
+	utils	--封装工具类函数
+	views	--vue组件目录
+		home	--主页
+			home.vue
+		....
+.prettierrc.json	--代码格式化
+vue.config.js	--项目配置文件
+```
+### 2. 项目启动,打包
+
+```shell
+# 启动项目
+	npm run serve
+# 项目打包
+	npm run build
+```
+
+### 3. 页面添加规则
+
+> 添加页面时,路径要和views目录里面的目录一一匹配,例
+>
+> - 添加/profile路由时,views文件夹下新建profile文件夹,该文件下新建`profile.vue`文件
+

+ 5 - 0
babel.config.js

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

+ 40 - 0
package.json

@@ -0,0 +1,40 @@
+{
+  "name": "health-station",
+  "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.26.1",
+    "core-js": "^3.6.5",
+    "echarts": "^5.3.2",
+    "swiper": "^5.4.5",
+    "vant": "^3.4.7",
+    "vue": "^3.0.0",
+    "vue-router": "^4.0.0-0",
+    "vue-smooth-dnd": "^0.8.1",
+    "vue3-smooth-dnd": "^0.0.2",
+    "vuex": "^4.0.0-0"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "~4.5.15",
+    "@vue/cli-plugin-eslint": "~4.5.15",
+    "@vue/cli-plugin-router": "~4.5.15",
+    "@vue/cli-plugin-vuex": "~4.5.15",
+    "@vue/cli-service": "~4.5.15",
+    "@vue/compiler-sfc": "^3.0.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": "^7.0.0",
+    "less": "^3.0.4",
+    "less-loader": "^5.0.0"
+  }
+}

BIN
public/favicon.ico


+ 38 - 0
public/index.html

@@ -0,0 +1,38 @@
+<!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"> -->
+<!--    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">-->
+<!--    <meta name="viewport" content="width=device-width, initial-scale=1.0">-->
+<!--    <meta name="viewport" content="width=1080">-->
+    <meta content="width=1080, user-scalable=0;" name="viewport" />
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <title><%= htmlWebpackPlugin.options.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>
+  <script>
+    setFontSize()
+function setFontSize(){
+    let designWidth = 1080;//设计稿的宽度,根据实际项目调整
+    let designHeight = 1920;//设计稿的高度,根据实际项目调整
+    var fontSize =
+        document.documentElement.clientWidth/document.documentElement.clientHeight < designWidth/designHeight ?
+        (document.documentElement.clientWidth / designWidth) * 12:
+        (document.documentElement.clientHeight / designHeight) * 12;
+    document.querySelector('html').style.fontSize = fontSize + 'px';
+}
+
+
+window.onresize = function () {
+    setFontSize()
+};
+  </script>
+</html>

+ 5 - 0
src/Api/apiList.js

@@ -0,0 +1,5 @@
+import axios from './baseUrl'
+
+export class Api{
+    
+}

+ 3 - 0
src/Api/baseUrl.js

@@ -0,0 +1,3 @@
+import axios from "axios";
+
+export default axios

+ 105 - 0
src/App.vue

@@ -0,0 +1,105 @@
+<template>
+  <div class="main-page">
+    <div class="swiper-head">
+      <div class="swiper-wrapper">
+        <div class="swiper-slide" data-swiper-autoplay="5000">
+          <Header class="" />
+        </div>
+        <div class="swiper-slide" data-swiper-autoplay="10000">
+          <Header class="" />
+        </div>
+        <div class="swiper-slide">
+          <Header class="" />
+        </div>
+      </div>
+    </div>
+<!--    <Header class="" />-->
+    <div class="page-body">
+      <router-view/>
+    </div>
+    <TabBottom/>
+  </div>
+</template>
+<script>
+  import Swiper from 'swiper';
+  import "swiper/css/swiper.css"
+  import TabBottom from '@/components/BottomTab.vue'
+  import Header from '@/components/HeaderApp.vue'
+  export default {
+    components: {
+      TabBottom,
+      Header
+    },
+    mounted() {
+      new Swiper ('.swiper-head', {
+        loop: true, // 循环模式选项
+        effect:'slide',//渐变切换
+        autoplay: {
+          delay: 3000,
+          stopOnLastSlide: false,
+          disableOnInteraction: false,
+        },
+        paginationClickable: false,//分页器切换
+      })
+    },
+    data () {
+      return {
+
+      }
+    }
+  }
+</script>
+<style lang="less">
+
+  @import "./assets/css/font.css";
+  .swiper-head,.swiper-wrapper{
+    width: 100vw;
+    height: 430px;
+  }
+
+  html,body,#app {
+    width: 100vw;
+    overflow-x: hidden;
+    height: 100% !important;
+    font-family: PF !important;
+  }
+  body {
+
+    padding: 0 !important;
+    margin: 0 !important;
+  }
+#app {
+  font-family: Avenir, Helvetica, Arial, sans-serif;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  text-align: center;
+  color: #2c3e50;
+}
+
+nav {
+
+  a {
+    font-weight: bold;
+    color: #2c3e50;
+
+    &.router-link-exact-active {
+      color: #42b983;
+    }
+  }
+}
+.main-page {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+}
+  .page-body{
+    flex: 1;
+    background-color: #FAFAFC;
+    overflow: auto;
+  }
+// .header{
+//   // height: 443px;
+//   height: 300px;
+//   background-color: #42b983;
+// }
+</style>

BIN
src/assets/Dinner_b_1.png


BIN
src/assets/Dinner_breakfas.png


BIN
src/assets/Dinner_lunch.png


BIN
src/assets/Dinner_supper.png


BIN
src/assets/ProfilePhoto.png


BIN
src/assets/Purple.png


BIN
src/assets/back.png


+ 6 - 0
src/assets/css/font.css

@@ -0,0 +1,6 @@
+@font-face {
+    font-family: 'PF';
+    src: url("../font/pf.ttf");
+    font-weight: normal;
+    font-style: normal;
+}

+ 92 - 0
src/assets/css/reset.css

@@ -0,0 +1,92 @@
+body,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+hr,
+p,
+blockquote,
+dl,
+dt,
+dd,
+ul,
+ol,
+li,
+pre,
+form,
+fieldset,
+legend,
+button,
+input,
+textarea,
+th,
+td {
+  margin: 0;
+  padding: 0;
+}
+body,
+button,
+input,
+select,
+textarea {
+  font: 12px/1.5tahoma, arial, \5b8b\4f53;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+  font-size: 100%;
+}
+address,
+cite,
+dfn,
+em,
+var {
+  font-style: normal;
+}
+code,
+kbd,
+pre,
+samp {
+  font-family: couriernew, courier, monospace;
+}
+small {
+  font-size: 12px;
+}
+ul,
+ol {
+  list-style: none;
+}
+a {
+  text-decoration: none;
+}
+a:hover {
+  text-decoration: underline;
+}
+sup {
+  vertical-align: text-top;
+}
+sub {
+  vertical-align: text-bottom;
+}
+legend {
+  color: #000;
+}
+fieldset,
+img {
+  border: 0;
+}
+button,
+input,
+select,
+textarea {
+  font-size: 100%;
+}
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}

BIN
src/assets/exit.png


BIN
src/assets/font/pf.ttf


BIN
src/assets/head-icon/logo.png


BIN
src/assets/hight.png


BIN
src/assets/home.png


BIN
src/assets/icon_action_help.png


BIN
src/assets/icon_action_help_outline.png


BIN
src/assets/leftOrRight/left.png


BIN
src/assets/leftOrRight/right.png


BIN
src/assets/left_arrow.png


BIN
src/assets/logo.png


BIN
src/assets/menu_1.png


BIN
src/assets/menu_2.png


BIN
src/assets/menu_3.png


BIN
src/assets/menu_4.png


BIN
src/assets/menu_5.png


BIN
src/assets/menu_6.png


BIN
src/assets/no_data.png


BIN
src/assets/people_dark.png


BIN
src/assets/star.png


BIN
src/assets/tab-icons/exit.png


BIN
src/assets/tab-icons/pepole.png


BIN
src/assets/tab-icons/tab-1-select.jpg


BIN
src/assets/tab-icons/tab-2.jpg


BIN
src/assets/tab-icons/tab-3.jpg


BIN
src/assets/tab-icons/to_home_icon.png


BIN
src/assets/tip.png


BIN
src/assets/top-head/headimg.jpg


BIN
src/assets/top-head/headimg1.jpg


BIN
src/assets/top-head/headimg2.jpg


BIN
src/assets/union.png


BIN
src/assets/weight.png


+ 214 - 0
src/components/BottomTab.vue

@@ -0,0 +1,214 @@
+<template>
+    <div class="tab-container">
+        <div class="tab-home-btn">
+            <img src="@/assets/home.png" alt="返回首页">
+        </div>
+        <div class="tab-menu-list">
+            <nav ref="nav">
+
+                <router-link :to="item.path" @click="onItemClick" v-for="item in routes">
+                    <div class="tab-item">
+                      <div class="menu-img">
+                        <div class="bottom-bg"
+                             :style="{ backgroundColor: item.path == currentRoutePath? item.activeBg:''}"
+                             v-if="item.path != '/healthEduOnline'"></div>
+                        <img :src="item.imgUrl" />
+                      </div>
+                        <span>{{item.label}}</span>
+                    </div>
+                </router-link>
+            </nav>
+        </div>
+        <div class="tab-child">
+            <div class="child-box">
+                <img src="https://img.yzcdn.cn/vant/cat.jpeg" alt="">
+                <div class="BMI">
+                    <img src="@/assets/tab-icons/pepole.png" alt="">
+                    <div class="BMI-text">BMI未知</div>
+                </div>
+            </div>
+            <div  class="child-info">
+                <span>张晨晨</span>
+                <span>五年级(2)班</span>
+            </div>
+        </div>
+        <div class="tab-exit">
+            <img src="@/assets/tab-icons/exit.png" alt="">
+        </div>
+    </div>
+</template>
+
+<script>
+  import routers from '@/router/index.js'
+  import { mapState } from 'vuex'
+    export default {
+      name: "BottomTab",
+      data(){
+        return {
+          routes:routers.options.routes
+        }
+      },
+      computed:{
+        ...mapState({
+          currentRoutePath: state => state.currentPath
+        })
+      },
+      methods: {
+        onItemClick(){
+
+        }
+      }
+    }
+</script>
+
+<style scoped lang="less">
+  .menu-img{
+    width: 90px;
+    position: relative;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    height: 55%;
+  }
+  .menu-img img{
+    width: 60px !important;
+    height: 52px !important;
+    position: absolute;bottom: 0;
+  }
+  .active-tab{
+    background-color: #6754D9 !important;
+  }
+  .bottom-bg{
+    width: 90px;
+    height: 28px;
+    background: #E1E0F0;
+    border-radius: 100px;
+    position: absolute;bottom: 0;
+  }
+    .tab-exit{
+        width: 7vw;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+    }
+    .tab-exit img{
+        opacity: 0.54;
+        width: 2.5vw;
+        height: 3vw;
+    }
+    .child-info{
+        position: absolute;
+        bottom: 10px;
+    }
+    .child-name{
+        font-size: 2.3vw;
+        font-weight: 600;
+        margin-right: 5px;
+    }
+    .le{
+        font-size: 2vw;
+        font-weight: 300;
+    }
+.BMI{
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    border: 0.5px solid rgba(0,0,0,0.38);
+    width: 100% ;
+    border-radius: 50px;
+    position: relative;
+    top: -25px;
+    left: -2px;
+    background-color: white;
+    padding: 2px 2px;
+
+}
+.BMI img {
+    opacity: 0.5;
+    width: 16px !important;
+    height: 18px !important;
+}
+.BMI-text{
+    opacity: 0.5;
+    flex: 1;
+    font-size: 0.7em !important;
+}
+.tab-container{
+    min-height: 140px;
+    max-height: 20vh;
+    display: flex;
+    align-items: center;
+    border-top: 1px solid #88888822;
+}
+.tab-home-btn img{
+    width: 6vw;
+}
+.tab-home-btn{
+    width: 10vw;
+    height: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    border-right: 1px solid #88888822;
+}
+.tab-menu-list{
+    flex: 1;
+    height: 80%;
+    border-right: 1px solid #88888822;
+}
+.tab-menu-list nav {
+    display: flex;
+    padding-left: 10px;
+}
+nav{
+    height: 100%;
+  display: flex;
+  align-items: center;
+}
+nav a.router-link-exact-active {
+    text-decoration: none !important;
+    color: #000000DE;
+    font-weight: 600;
+}
+nav a{
+    text-decoration: none !important;
+    font-weight: 400;
+    font-size: 0.7em;
+    color: #0000008A;
+  display: inline-block;
+  height: 100%;
+
+}
+.tab-item  {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    height: 100%;
+    width: auto;
+  margin-right: 20px;
+}
+.tab-item span {
+    margin-top: 10px;
+  font-weight: 600;
+}
+.tab-item img{
+    width: 13vw;
+}
+    .tab-child{
+        width: 22vw;
+        height: 100%;
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
+        border-right: 1px solid #88888822;
+        position: relative;
+    }
+    .child-box img{
+        position: relative;
+        width: 50px;
+        height: 50px;
+        border-radius: 50%;
+    }
+</style>

+ 99 - 0
src/components/Echarts/BrokenLine.vue

@@ -0,0 +1,99 @@
+<template>
+<div ref="main" style="width:84.7rem; height:30.3rem"></div>
+</template>
+
+<script setup>
+import {
+    ref,
+    onMounted,
+    defineProps
+} from 'vue';
+import * as echarts from 'echarts';
+
+const props = defineProps({
+    company:{
+        type:String,
+        default:'cm/kg²'
+    },
+    xAxis:{
+        type:Array,
+        default:['3/25','3/26','3/27','3/28','3/29','3/30','3/31','4/1','4/2','4/3','4/4','4/5','4/6','4/7','4/8']
+    }
+})
+
+
+const main = ref()
+
+onMounted(() => {
+    setTimeout(() => {
+        init()
+    }, 20)
+})
+
+function init() {
+    var myChart = echarts.init(main.value)
+    var option;
+    option = {
+        tooltip: {
+            trigger: 'axis',
+            triggerOn: 'click'
+        },
+        legend: {
+            data: ['我的BMI', '班级平均'],
+            right: '100',
+            top:'20'
+        },
+        xAxis: [{
+            type: 'category',
+            data: props.xAxis,
+            axisPointer: {
+                type: 'shadow'
+            }
+        }],
+        yAxis: [{
+            type: 'value',
+            name: 'BMI',
+            min: 0,
+            max: 30,
+            interval: 5,
+            axisLabel: {
+                formatter: '{value} ml'
+            },
+            nameTextStyle: {
+                fontSize: 20
+            }
+        }],
+        series: [{
+                name: '班级平均',
+                type: 'bar',
+                barMaxWidth:'10%',
+                tooltip: {
+                    valueFormatter: function (value) {
+                        return value + ' ml';
+                    }
+                },
+                data: [
+                    2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3
+                ]
+            },
+            {
+                name: '我的BMI',
+                type: 'line',
+                areaStyle:{},
+                tooltip: {
+                    valueFormatter: function (value) {
+                        return value + ' °C';
+                    }
+                },
+                data: [2.0, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3, 23.4, 23.0, 16.5, 12.0, 6.2]
+            }
+        ]
+    };
+
+    option && myChart.setOption(option);
+}
+</script>
+
+<style>
+
+</style>

+ 111 - 0
src/components/Echarts/Score.vue

@@ -0,0 +1,111 @@
+<template>
+<div ref="main" style="width:13.3rem; height:13.3rem"></div>
+</template>
+
+<script setup>
+import {
+    ref,
+    onMounted,
+    defineProps
+} from 'vue';
+import * as echarts from 'echarts';
+
+const props = defineProps({
+    name:{
+        type: String,
+        default:"优秀"
+    },
+    color:{
+        default:'#31CA8A'
+    },
+    value:{
+        default:100
+    }
+})
+
+const main = ref()
+
+onMounted(() => {
+    setTimeout(()=>{
+    init()
+    },20)
+})
+
+function init() {
+    var myChart = echarts.init(main.value)
+    var option
+    const gaugeData = [{
+        value: props.value,
+        name: props.name,
+        title: {
+            offsetCenter: ['0%', '30%']
+        },
+        detail: {
+            valueAnimation: true,
+            offsetCenter: ['0%', '-20%']
+        }
+    }];
+    option = {
+        color: [props.color],
+        grid:{
+            width:100,
+            height:100
+        },
+        series: [{
+            type: 'gauge',
+            startAngle: 90,
+            endAngle: -270,
+            pointer: {
+                show: false
+            },
+            progress: {
+                show: true,
+                overlap: false,
+                roundCap: true,
+                clip: false,
+                itemStyle: {
+                    borderWidth: 1,
+                    borderColor: '#46464600'
+                }
+            },
+            axisLine: {
+                lineStyle: {
+                    width: 10
+                }
+            },
+            splitLine: {
+                show: false,
+                distance: 0,
+                length: 10
+            },
+            axisTick: {
+                show: false
+            },
+            axisLabel: {
+                show: false,
+                distance: 50
+            },
+            data: gaugeData,
+            title: {
+                fontSize: 14,
+                color:props.color
+            },
+            detail: {
+                width: 20,
+                height: 10,
+                fontSize: 14,
+                // color: 'auto',
+                borderColor: 'auto',
+                borderRadius: 20,
+                // borderWidth: 1,
+                formatter: '{value}%'
+            }
+        }]
+    };
+    option && myChart.setOption(option);
+}
+</script>
+
+<style>
+
+</style>

+ 250 - 0
src/components/HeaderApp.vue

@@ -0,0 +1,250 @@
+<template>
+    <div class="header">
+      <div class="mask"></div>
+        <div class="head_top">
+            <!-- {{data.month}}|{{data.date}}|{{'星期' + data.day}} -->
+            <div class="head_top_left">
+                <div class="head_top_date">{{data.date}}</div>
+                <div class="head_top_month">{{data.month + '月'}}&nbsp;&nbsp; | &nbsp;&nbsp;{{'周' + data.day}}</div>
+            </div>
+            <div class="head_top_right">
+                <img style="{width:6.7rem; height:6.7rem;}" src="../assets/head-icon/logo.png" alt="">
+                <div>华园紫杭</div>
+            </div>
+        </div>
+        <div class="head_bottom">
+            <div class="head_bottom_left">
+                <div class="head_bottom_left_top">
+                    <div>谷雨</div>
+                    <div>推荐菜品</div>
+                </div>
+                <div class="foods-list">
+                  <div v-for="item in props.recommendFoods" class="inline-item">
+                    <div class="food-item">
+                      <van-image width="109" height="107" :src="require('@/assets/ProfilePhoto.png')"></van-image>
+                      <span class="food-name">{{item.name}}</span>
+                    </div>
+                  </div>
+                </div>
+            </div>
+            <div class="head_bottom_right">
+                <div class="head_bottom_right_box">
+                    <div>
+                        <span>谷雨</span>
+                        <p class="p1">
+                            谷雨西厢宜养蚕。
+                        降雨增多,空气中的湿度逐渐加大。
+                          谷雨西厢宜养蚕。
+                          降雨增多,空气中的湿度逐渐加大。
+                          谷雨西厢宜养蚕。
+                          降雨增多,空气中的湿度逐渐加大。
+                        </p>
+
+                    </div>
+                    <div>
+                        <span>饮食规律</span>
+                        <p class="p1">
+                            养肝多吃绿色食品;温补食物,可以吃些刺激的。
+                        </p>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { reactive,defineProps } from 'vue';
+
+const props = defineProps({
+  recommendFoods:{
+    type: Array,
+    default: () => {
+       return [
+         {url:'香菇肉丝.png',name:'香菇肉丝'},
+         {url:'香菇肉丝.png',name:'香菇肉丝炒辣椒'},
+         {url:'香菇肉丝.png',name:'香菇肉丝'},
+         {url:'香菇肉丝.png',name:'香菇肉丝'},
+         {url:'香菇肉丝.png',name:'香菇肉丝'}
+       ]
+    }
+  }
+})
+const data = reactive({
+    month:null,
+    date:null,
+    day:null,
+})
+
+const getTime = ()=>{
+    let date = new Date()
+    data.month = date.getMonth()+1
+    data.date = date.getDate()
+    if (date.getDay()==0) {
+        data.day='日'
+    }else{
+        data.day = date.getDay()
+    }
+    console.log(date.toLocaleString('ja-JP-u-ca-chinese'));
+}
+getTime()
+
+
+</script>
+
+<style>
+  .foods-list{
+    margin: 25px 2.5rem;
+    overflow-x: scroll;
+    display: flex;
+  }
+  .foods-list::-webkit-scrollbar {
+    display: none;
+  }
+  .inline-item{
+    display: inline-block;
+    margin-right: 20px;
+  }
+  .food-item{
+    display: flex;
+    flex-direction: column;
+    width: 109px;
+
+  }
+  .food-name{
+    margin-top: 8px;
+    font-size: 16px;
+    font-weight: 600;
+    color: #175C19;
+    width: 109px;
+    word-break: break-all;
+    text-overflow: ellipsis;
+    display: -webkit-box;
+    -webkit-box-orient: vertical;
+    -webkit-line-clamp: 1; /* 这里是超出几行省略 */
+    overflow: hidden;
+  }
+  .p1{
+    height: 67px;
+    width: 215px;
+    word-break: break-all;
+    text-overflow: ellipsis;
+    display: -webkit-box;
+    -webkit-box-orient: vertical;
+    -webkit-line-clamp: 3; /* 这里是超出几行省略 */
+    overflow: hidden;
+  }
+  .mask{
+    height: 136px;
+    background: linear-gradient(to bottom, #00000077 0%, #00000022 20%);
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100vw;
+    z-index: 9;
+  }
+.header{
+    height: 430px;
+    /* background-color: aqua; */
+    background: url(../assets/top-head/headimg2.jpg) no-repeat;
+    background-size: cover;
+}
+.head_top_right{
+    display: flex;
+    align-items: center;
+    font-size: 2.4rem;
+}
+.head_top_right div{
+    margin-left: 1rem;
+}
+.head_top{
+  position: relative;
+  z-index: 10;
+    display: flex;
+    color: #fff;
+    width: 94%;
+    height: 120px;
+  margin: 8px auto;
+    justify-content: space-between;
+    align-items: center;
+}
+.head_top_date{
+    font-size: 6rem;
+}
+.head_top_left{
+    /* width: 10rem; */
+    display: flex;
+}
+.head_top_month{
+  font-size: 2.4rem;
+  align-self: flex-end;
+  margin-left: 3.3rem;
+  line-height: 5.6rem;
+}
+
+
+.head_bottom{
+  display: flex;
+  width: 94%;
+  margin: auto;
+  justify-content: space-between;
+}
+.head_bottom_left{
+  width: 710px;
+  height: 260px;
+  background-color: rgba(255, 255, 255, .6);
+  /* opacity: .6; */
+  border-radius: 1rem;
+}
+.head_bottom_right{
+  width: 270px;
+  height: 260px;
+  background-color: rgba(255, 255, 255, .6);
+  /* opacity: .6; */
+  border-radius: 1rem;
+}
+.head_bottom_left_top{
+    display: flex;
+    align-items: center;
+    margin-left: 3rem;
+    margin-top: 2rem;
+}
+.head_bottom_left_top div:nth-child(1){
+    background-color: #175C19;
+    border-radius: 50%;
+    width: 50px;
+     height: 50px;
+    color: #fff;
+    line-height: 50px;
+    font-size: 18px;
+}
+.head_bottom_left_top div:nth-child(2){
+    font-size: 28px;
+    margin-left: 1rem;
+  font-weight: 600;
+    color: #185D1A;
+}
+.head_bottom_right_box{
+    width: 86%;
+    height: 70%;
+    margin: 1rem auto;
+    text-align: left;
+    color: #0A3A28;
+}
+.head_bottom_right_box div:nth-child(1){
+  padding-top: 20px;
+  font-size: 16px;
+}
+.head_bottom_right_box div:nth-child(1) span{
+    font-size: 20px;
+  font-weight: 600;
+}
+.head_bottom_right_box div:nth-child(2){
+  font-size: 16px;
+  margin-top: 30px;
+}
+.head_bottom_right_box div:nth-child(2) span{
+    font-size: 20px;
+  font-weight: 600;
+}
+</style>

+ 22 - 0
src/components/HealthEval/HealthEvalList.vue

@@ -0,0 +1,22 @@
+<template>
+    <div class="cpn-root">
+      <Item></Item>
+    </div>
+</template>
+
+<script>
+  import Item from './HealthEvalListItem.vue'
+  export default {
+    name: 'HealthEavlList',
+    components:{
+      Item
+    }
+  }
+</script>
+
+<style scoped>
+.cpn-root{
+  height: 100%;
+  background-color: #929292;
+}
+</style>

+ 15 - 0
src/components/HealthEval/HealthEvalListItem.vue

@@ -0,0 +1,15 @@
+<template>
+  <div>
+
+  </div>
+</template>
+
+<script>
+  export default {
+    name: 'HealthEvalListItem'
+  }
+</script>
+
+<style scoped>
+
+</style>

+ 96 - 0
src/components/LevelDescription.vue

@@ -0,0 +1,96 @@
+<template>
+    <div class="cpn-root" @click.stop="()=>{}">
+      <div class="qa-header">
+        <img src="@/assets/star.png" alt="">
+        <span class="level-desc-title">营养评级说明</span>
+      </div>
+      <div class="level-value-list">
+        <div class="level-value-item" v-for="item in evalList">
+          <div class="level-value">{{item.title}}</div>
+          <div class="level-description">{{item.value}}</div>
+        </div>
+      </div>
+      <div class="btn-i-know">
+        <van-button size="large" color="#846FFE" round>我知道了</van-button>
+      </div>
+    </div>
+</template>
+
+<script>
+  export default {
+    name: 'LevelDescription',
+    data(){
+      return {
+        evalList:[
+          {
+            title:"S",
+            value:"≥90(分)"
+          },{
+            title:"A",
+            value:"80~90(分)"
+          },{
+            title:"B",
+            value:"70~80(分)"
+          },{
+            title:"C",
+            value:"60~70(分)"
+          },{
+            title:"D",
+            value:"≤60(分)"
+          }
+        ]
+      }
+    }
+  }
+</script>
+
+<style scoped>
+.cpn-root{
+  background-color: white;
+  border-radius: 15px;
+  width: 592px;
+  height: 823px;
+  position: fixed;
+  top: 520px;
+  right: 45px;
+}
+  .qa-header{
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    padding: 64px 0 80px 0;
+
+  }
+  .qa-header img{
+    width: 46px;
+    height: 46px;
+    margin-right: 16px;
+  }
+  .level-desc-title{
+    font-size: 34px;
+    font-weight: bold;
+  }
+.level-value-item:first-child{
+  margin-top: 0 !important;
+}
+  .level-value-item{
+    display: flex;
+    width: 80%;
+    margin: 60px auto;
+  }
+  .level-value {
+    color: #846FFE;
+    font-size: 34px;
+    font-weight: 600;
+  }
+  .level-description{
+    font-size: 24px;
+    font-weight: 600;
+    text-align: right;
+    flex: 1;
+  }
+  /deep/
+.van-button--large{
+  width: 30% !important;
+}
+</style>

+ 126 - 0
src/components/ScoreProgress.vue

@@ -0,0 +1,126 @@
+<template>
+    <div class="progress-bar-root">
+      <div class="title-text">
+        {{lj}}
+      </div>
+      <div class="progress-temp">
+        <van-progress :style="{'--color':slidColor}" :pivot-text="percent+'%'" :color="slidColor" :percentage="percent" />
+        <div class="split-dot">
+          <span class="dot"></span>
+          <span class="dot"></span>
+          <span class="dot no-right"></span>
+        </div>
+        <div class="split-dot split-text">
+          <span class="dot no-right" :class="[level == 3?'blod-text':'']">合格</span>
+          <span class="dot no-right" :class="[level == 2?'blod-text':'']">良好</span>
+          <span class="dot no-right" :class="[level == 1?'blod-text':'']">优秀</span>
+        </div>
+      </div>
+    </div>
+</template>
+
+<script>
+  export default {
+    name: 'ScoreProgress',
+    computed:{
+      slidColor(){
+        if(this.percent && this.percent > 66.6){
+          return '#31CA8A'
+        }
+        if(this.percent && this.percent > 33.3){
+          return '#FFA900'
+        }
+         return '#FD6C3B'
+      },
+      level(){
+        if(this.percent && this.percent > 66.6){
+          return 1
+        }
+        if(this.percent && this.percent > 33.3){
+          return 2
+        }
+        return 3
+      }
+    },
+    props: {
+      percent:{
+        type: Number,
+        default: ()=>{
+          return 0
+        }
+      },
+      lj:{
+        type: String,
+        default: ()=>{
+          return '未知元素'
+        }
+      }
+    }
+  }
+</script>
+
+<style scoped>
+.progress-bar-root{
+  height: 90px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  width: 90%;
+  margin: 0 auto;
+}
+.title-text{
+  width: 8vw;
+  text-align: left !important;
+  font-weight: bold;
+  font-size: 14px;
+}
+.progress-temp{
+  flex: 1;
+  margin: 0 auto;
+  position: relative;
+}
+.split-dot{
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  height: 4px;
+  background-color: #31CA8A00;
+  display: flex;
+}
+.split-text{
+  top: 10px;
+}
+.dot{
+  flex: 1;
+  border-right: 1px solid #929292;
+}
+.no-right{
+  border: none !important;
+  text-align: center;
+}
+/deep/
+.van-progress__portion{
+  background-color: #ffffff00 !important;
+}
+/deep/
+.van-progress__pivot{
+  top: -400% !important;
+  z-index: 5 !important;
+}
+/deep/
+.van-progress__pivot::after{
+  content: '';
+  z-index: 4 !important;
+  width: 5px;
+  position: absolute;
+  bottom: -15%;
+  left: 43%;
+  transform: rotate(45deg);
+  height: 5px;
+  background: var(--color);
+}
+  .blod-text{
+    font-weight: 600 !important;
+  }
+</style>

+ 63 - 0
src/components/SuitList.vue

@@ -0,0 +1,63 @@
+<template>
+  <div class="suit-root">
+    <div class="suit-item" :class="[index == active ? 'active':'']" v-for="(item,index) in list" @click="itemClick(index,item)">
+      {{ item.name }}
+    </div>
+  </div>
+</template>
+
+<script>
+  export default {
+    name: 'SuitList',
+    data(){
+      return {
+        active: -1
+      }
+    },
+    props:{
+      list:{
+        type: Array,
+        default: ()=>{
+          return []
+        }
+      }
+    },
+    methods:{
+      itemClick(index,item) {
+        this.active = index
+        this.$emit('item-click',item)
+      }
+    }
+  }
+</script>
+
+<style scoped>
+  .suit-root{
+    margin-top: 1vh;
+    justify-content: center;
+    align-items: center;
+    overflow-x: scroll;
+    height: 3vh;
+    white-space: nowrap;
+    width: auto;
+  }
+  .suit-root::-webkit-scrollbar{
+    display: none;
+  }
+  .suit-item{
+    display: inline-block;
+    width: 60px;
+    padding: 5px 8px;
+    background: #f6f4ff;
+    font-weight: 500;
+    font-size: 14px;
+    border-radius: 16.5px;
+    margin:0 10px;
+    white-space: nowrap;
+  }
+  .active{
+    border: 0.5px solid #846ffe;
+    background: #f6f4ff;
+    color: #846ffe;
+  }
+</style>

+ 102 - 0
src/components/WeekDays.vue

@@ -0,0 +1,102 @@
+<template>
+    <div class="week-days-content">
+      <span class="day-item" v-for="(item, index) in weekdays" @click="itemClick(item,index)">
+        <span :class="['weekday-name',active == index ?'today-active':'']">{{item.weekdayName}}</span>
+        <span :class="['day-date',active == index ?'date-active':'']">{{item.day}}</span>
+        <span class="day-has-suit"></span>
+      </span>
+    </div>
+</template>
+
+<script>
+  import * as dateUtils from '../utils/dateUtils'
+  export default {
+    name: 'WeekDays',
+    data() {
+      return {
+        active: -1
+
+      }
+    },
+    computed:{
+      weekdays:function() {
+        let arr = dateUtils.getWeekDays(this.start,this.end)
+        let findIndex = arr.findIndex(t=>t.isActive)
+        if(findIndex > -1){
+          arr[findIndex].isActive = false
+        }
+        this.active = findIndex
+        return arr
+      }
+    },
+    mounted () {
+
+    },
+    props:{
+      'start': {
+        type: Date,
+        default: new Date()
+      },
+      'end': {
+        type: Date,
+        default: new Date()
+      }
+    },
+    methods:{
+      itemClick(item,index) {
+        this.weekdays.forEach(t=>t.isActive = false)
+        this.active = index
+        this.$emit('on-item-click',item)
+      }
+    }
+  }
+</script>
+
+<style scoped>
+.week-days-content {
+  width: 100%;
+  display: flex;
+}
+  .day-item{
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    flex: 1;
+  }
+.day-item span {
+  width: 100%;
+  text-align: center;
+}
+  .weekday-name {
+    flex: 1;
+    font-size: 0.5em;
+    color: rgba(0,0,0,0.54);
+    margin-bottom: 10px;
+  }
+.day-has-suit{
+  display: block;
+  width: 6px !important;
+  height: 6px !important;
+  background-color: #31CA8A;
+  border-radius: 100px;
+  margin-top: 10px;
+}
+.today-active{
+  color: black;
+  font-weight: 600;
+}
+  .date-active{
+    border-radius: 100px;
+    background-color: #7D72F2;
+    color: white;
+  }
+  .day-date{
+    font-size: 1em;
+    display: block;
+    width: 5vw !important;
+    height: 5vw;
+    line-height: 5vw;
+    border-radius: 100px;
+  }
+</style>

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 699 - 0
src/components/public/Calendar.vue


+ 10 - 0
src/main.js

@@ -0,0 +1,10 @@
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+import store from './store'
+import vant from 'vant'
+// 样式初始化
+import './assets/css/reset.css'
+import 'vant/lib/index.css'
+
+createApp(App).use(store).use(router).use(vant).mount('#app')

+ 65 - 0
src/router/index.js

@@ -0,0 +1,65 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import store  from '../store'
+const routes = [
+  {
+    path: '/',
+    name: 'Home',
+    label:'健康评估',
+    activeBg:'#43a8d1',
+    imgUrl: require("@/assets/menu_3.png"),
+    component: () => import('../views/HealthEval.vue')
+  },
+  {
+    path: '/healthEduOnline',
+    name: 'HealthEduOnline',
+    label:'健康教育在线',
+    activeBg:'',
+    imgUrl: require("@/assets/logo.png"),
+    component: () => import('../views/HealthEduOnline.vue')
+  },
+  {
+    path: '/foods',
+    name: 'foods',
+    label:'本周食谱',
+    activeBg:'#6754D9',
+    imgUrl: require("@/assets/menu_1.png"),
+    component: () => import('../views/home/home.vue')
+  },
+  {
+    path:'/nutrition',
+    name:'nutrition',
+    label:'我是营养师',
+    activeBg:'#1DA46B',
+    imgUrl: require("@/assets/menu_4.png"),
+    component: () => import('../views/MyNutrition.vue')
+  },
+  {
+    path: '/myContract',
+    name: 'myContract',
+    label:'我的联系人',
+    activeBg:'#536DAD',
+    imgUrl: require("@/assets/menu_5.png"),
+    component: () => import('../views/MyContract.vue')
+  },
+  {
+    path: '/health',
+    name: 'health',
+    label:'我的健康',
+    activeBg:'#37AEA0',
+    imgUrl: require("@/assets/menu_2.png"),
+    component: () => import('../views/MyHealth.vue')
+  }
+
+]
+
+const router = createRouter({
+  history: createWebHistory(process.env.BASE_URL),
+  routes
+})
+
+router.beforeResolve((to,form,next)=>{
+  store.commit('setCurrentPath',to.path)
+  next()
+})
+
+export default router

+ 24 - 0
src/store/index.js

@@ -0,0 +1,24 @@
+import { createStore } from 'vuex'
+
+export default createStore({
+  state: {
+    currentPath: '/'
+  },
+  mutations: {
+    setCurrentPath:(state,path) => {
+      state.currentPath = path
+    }
+  },
+  getters: {
+    getCurrentPath:(state) => {
+      return state.currentPath
+    }
+  },
+  actions: {
+    setCurrentPath:(state,path) => {
+      state.commit('setCurrentPath',path)
+    }
+  },
+  modules: {
+  }
+})

+ 219 - 0
src/utils/dateUtils

@@ -0,0 +1,219 @@
+/*
+ *计算每个月有几周
+ */
+const weekMethods = (date) => {
+  let fristDay = date;
+  let endDay = getCurrentMonthLastDay(fristDay).getDate();
+  let dayArr = [];
+  let week = fristDay.getDay();
+  if (week == 0) {
+    dayArr = test(endDay, 6, dayArr);
+  } else if (week == 1) {
+    dayArr = test(endDay, 5, dayArr);
+  } else if (week == 2) {
+    dayArr = test(endDay, 4, dayArr);
+  } else if (week == 3) {
+    dayArr = test(endDay, 3, dayArr);
+  } else if (week == 4) {
+    dayArr = test(endDay, 2, dayArr);
+  } else if (week == 5) {
+    dayArr = test(endDay, 1, dayArr);
+  } else if (week == 6) {
+    dayArr = test(endDay, 0, dayArr);
+  }
+  return dayArr;
+};
+
+const test = (endDay, num, arr) => {
+  if (num != 6) {
+    arr.push({
+      startDay: "01",
+      endDay: "0" + (1 + num)
+    })
+  } else {
+    arr.push({
+      startDay: "01",
+      endDay: "07"
+    })
+  }
+
+  for (let i = 1 + num + 1; i < endDay + 1; i = i + 7) {
+    let obj = {};
+    if (i == endDay) {
+      obj = {
+        startDay: i,
+        endDay: i
+      };
+    } else if (i + 6 > endDay) {
+      obj = {
+        startDay: i,
+        endDay: endDay
+      };
+
+    } else {
+      obj = {
+        startDay: i > 10 ? i : "0" + i,
+        endDay: i + 6 > 10 ? i + 6 : "0" + (i + 6)
+      };
+    }
+    arr.push(obj);
+  }
+  arr.forEach((item, index) => {
+    item.text = "第" + (index + 1) + "周(" + item.startDay + "-" + item.endDay + ")"
+    item.value = index + 1
+  })
+
+  return arr;
+};
+
+/**
+ * 获取当前月的最后一天
+ * */
+const getCurrentMonthLastDay = (date) => {
+  // let date = new Date();
+  let currentMonth = date.getMonth();
+  let nextMonth = ++currentMonth;
+  let nextMonthFirstDay = new Date(date.getFullYear(), nextMonth, 1);
+  let oneDay = 1000 * 60 * 60 * 24;
+  let lastTime = new Date(nextMonthFirstDay - oneDay);
+  return lastTime;
+};
+
+/**
+ * 年循环
+ */
+// export const yearLoop = (minDate, maxDate) => {
+//   let yearArr = [];
+//   if (!minDate) {
+//     minDate = new Date().getFullYear() - 5;
+//   }
+//   if (!maxDate) {
+//     maxDate = minDate + 10;
+//   }
+//   for (let i = minDate; i < maxDate; i++) {
+//     yearArr.push({
+//       text: i + "年",
+//       value: i,
+//       children: monthLoop(i),
+//     });
+//   }
+//   return yearArr
+// };
+/***
+ * 根据月循环
+ */
+
+const monthLoop = (year) => {
+  let month = [];
+  for (let i = 1; i < 13; i++) {
+    month.push({
+      text: i + "月",
+      value: i >9 ? i : '0' + i
+    });
+  }
+  month.forEach((item, index) => {
+    let date = new Date(year, index, 1);
+    item.children = weekMethods(date);
+  });
+  return month
+};
+/** * 格式化时间为:yyyy-MM-dd HH:mm:ss * @param date * @returns {string} */
+function jsDateFormatter (date,type) {
+  var seperator1 = "-";
+  var seperator2 = ":";
+  var month = date.getMonth() + 1;
+  var strDate = date.getDate();
+  if (month >= 1 && month <= 9) {
+    month = "0" + month;
+  }
+  if (strDate >= 0 && strDate <= 9) {
+    strDate = "0" + strDate;
+  }
+  if(type == 'date'){
+    var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate;
+    return currentdate;
+  }
+  var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate + " " + date.getHours() + seperator2 + date.getMinutes()+ seperator2 + date.getSeconds();
+  return currentdate;
+}
+function getDiffDay(date_1, date_2) {
+  // 计算两个日期之间的差值
+  let totalDays,diffDate
+  let myDate_1 = Date.parse(date_1)
+  let myDate_2 = Date.parse(date_2)
+  // 将两个日期都转换为毫秒格式,然后做差
+  diffDate = Math.abs(myDate_1 - myDate_2) // 取相差毫秒数的绝对值
+
+  totalDays = Math.floor(diffDate / (1000 * 3600 * 24)) // 向下取整
+  // console.log(totalDays)
+
+  return totalDays    // 相差的天数
+}
+
+export const getWeekDays = (start,end) => {
+  let arr = []
+  let days = getDiffDay(start,end)
+  let startDate = new Date(start)
+  for (let i = 0; i <= days;i++) {
+    let itemDate = new Date(startDate)
+    itemDate.setDate(startDate.getDate()+(i));
+    itemDate = new Date(itemDate)
+    let weekDayName = getWeekdayName(itemDate.getDay(),itemDate)
+    arr.push({
+      day: itemDate.getDate(),
+      weekday: itemDate.getDay(),
+      weekdayName: weekDayName,
+      date: itemDate,
+      str: `${itemDate.getFullYear()}${itemDate.getMonth()}${itemDate.getDate()}`,
+      isActive: weekDayName == '今日'
+    })
+  }
+  return arr
+}
+
+export const getWeekdayName = (weekday,date) => {
+  let current = new Date()
+  let diff = getDiffDay(jsDateFormatter(date,'date'),jsDateFormatter(current,'date'))
+  if(diff == 0)
+    return '今日'
+  switch (weekday) {
+    case 1: return '一'
+    case 2: return '二'
+    case 3: return '三'
+    case 4: return '四'
+    case 5: return '五'
+    case 6: return '六'
+    case 0: return '日'
+    default: return  '未知'
+  }
+}
+export const getCurrentWeekByDate = (date) => {
+  if(!date) date = (new Date()).toDateString()
+  let dateObj = new Date(date)
+  let weekIndex = dateObj.getDay()
+  let leftDayCount = weekIndex - 0;
+  let rightDayCount = 6 - weekIndex;
+  let leftDateList = []
+  let rightDateList = []
+  for (let i = leftDayCount;i>0;i--){
+    let newDate = new Date(dateObj.toDateString())
+    newDate = newDate.setDate(newDate.getDate() - i)
+    newDate = new Date(newDate)
+    leftDateList.push(newDate)
+  }
+  for (let i = 1;i<= rightDayCount;i++){
+    let newDate = new Date(dateObj.toDateString())
+    newDate = newDate.setDate(newDate.getDate() + i)
+    newDate = new Date(newDate)
+    rightDateList.push(newDate)
+  }
+  return [...leftDateList,dateObj,...rightDateList]
+}
+
+export const getDateFormatOfCN = (date) => {
+  date = new Date(date)
+  let year = date.getFullYear()
+  let month = date.getMonth() + 1
+  let day = date.getDate()
+  return `${year}年${month}月${day}日`
+}

+ 3 - 0
src/utils/index.js

@@ -0,0 +1,3 @@
+export default {
+}
+

+ 5 - 0
src/views/AboutView.vue

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

+ 15 - 0
src/views/HealthEduOnline.vue

@@ -0,0 +1,15 @@
+<template>
+    <div>
+      健康教育在线
+    </div>
+</template>
+
+<script>
+  export default {
+    name: 'HealthEduOnline'
+  }
+</script>
+
+<style scoped>
+
+</style>

+ 19 - 0
src/views/HealthEval.vue

@@ -0,0 +1,19 @@
+<template>
+    <div style="height: 100%" class="page-root">
+      <List></List>
+    </div>
+</template>
+
+<script>
+  import List from '@/components/HealthEval/HealthEvalList.vue'
+  export default {
+    name: 'HealthEval',
+    components:{
+      List
+    }
+  }
+</script>
+
+<style scoped>
+
+</style>

+ 27 - 0
src/views/HomeView.vue

@@ -0,0 +1,27 @@
+<template>
+  <div class="home">
+    <div class="top-content">
+
+    </div>
+  </div>
+</template>
+
+<script>
+// @ is an alias to /src
+// import HelloWorld from '@/components/HelloWorld.vue'
+import * as util from '@/utils/index'
+export default {
+  name: 'HomeView',
+  components: {
+  }
+}
+</script>
+<style>
+  .top-content {
+    width: 100vw;
+    height: 24vh;
+    /* background-image: url(../assets/top-head/headimg2.jpg); */
+    background-size: cover;
+    background-position:center ;
+  }
+</style>

+ 13 - 0
src/views/MyContract.vue

@@ -0,0 +1,13 @@
+<template>
+    <div>我的联系人</div>
+</template>
+
+<script>
+  export default {
+    name: 'MyContract'
+  }
+</script>
+
+<style scoped>
+
+</style>

+ 158 - 0
src/views/MyHealth.vue

@@ -0,0 +1,158 @@
+<template>
+    <div class="health_top">
+        <div class="my_data_box">
+            <div class="my_data">
+                <img src="../assets/hight.png" alt="">
+                <div>张晨晨</div>
+            </div>
+            <div class="body_data">
+                <div class="height_data">
+                    <img src="../assets/hight.png" alt="">
+                    <div class="specific_data_box">
+                        <div>身高(cm)</div>
+                        <div class="specific_data">152.0</div>
+                    </div>
+                </div>
+                <div class="weight_data">
+                    <img src="../assets/weight.png" alt="">
+                    <div class="specific_data_box">
+                        <div>体重(kg)</div>
+                        <div class="specific_data">45.0</div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="bmi_box">
+            <div class="bmi_word">
+                <div>BMI</div>
+                <img src="../assets/icon_action_help_outline.png" alt="">
+            </div>
+            <div>
+              
+            </div>
+        </div>
+    </div>
+    <div class="health_mid">
+        <div class="echarts">
+            <BrokenLine />
+        </div>
+        <div></div>
+        <div></div>
+    </div>
+</template>
+
+<script>
+import BrokenLine from '../components/Echarts/BrokenLine.vue'
+    export default {
+        name: "MyHealth",
+        components:{
+            BrokenLine,
+        }
+    }
+</script>
+
+<style scoped lang="less">
+.health_top{
+    width: 90%;
+    height: 22.9rem;
+    // background-color: bisque;
+    margin: 4rem auto 2.8rem auto;
+    display: flex;
+    justify-content: space-between;
+}
+.my_data{
+    display: flex;
+    align-items: center;
+    font-size: 2.4rem;
+    font-weight: bold;
+    margin-top: 2.3rem;
+    margin-left: 3.6rem;
+    img{
+        width: 6.2rem;
+        height: 6.2rem;
+    }
+    div{
+        margin-left: 2.3rem;
+    }
+}
+.my_data_box{
+    width: 60%;
+    height: 100%;
+    background-color: #fff;
+    border-radius: 2rem;
+}
+.bmi_box{
+    width: 30%;
+    height: 100%;
+    // background-color: #fff;
+    background: linear-gradient(to bottom right, #F3F1FF, #fff);
+    border-radius: 1.8rem;
+}
+.body_data{
+    margin-left: 3.6rem;
+    margin-top: 2.8rem;
+    display: flex;
+    justify-content: space-between;
+}
+.height_data{
+    display: flex;
+    align-items: center;
+    font-size: 1.1rem;
+    text-align: left;
+    width: 50%;
+    border-right: #00000011 solid;
+
+    img{
+        width: 6.4rem;
+        height: 6.4rem;
+    }
+}
+.weight_data{
+    display: flex;
+    align-items: center;
+    font-size: 1.1rem;
+    text-align: left;
+    width: 50%;
+    margin-left: 4.7rem;
+    img{
+        width: 6.4rem;
+        height: 6.4rem;
+    }
+}
+.specific_data{
+    font-size: 3.2rem;
+    font-weight: bold;
+}
+.specific_data_box{
+    margin-left: 2.3rem;
+    div:nth-child(1){
+        color: #999999;
+    }
+}
+
+.bmi_word{
+    display: flex;
+    align-items: center;
+    margin-top: 2rem;
+    margin-left: 2.6rem;
+    font-size: 3.2rem;
+    font-weight: bold;
+    img{
+        width: 2rem;
+        height: 2rem;
+        margin-left: 1.4rem;
+    }
+}
+.health_mid{
+    width: 90%;
+    height: 65rem;
+    background-color: #999999;
+    margin: auto;
+}
+.echarts{
+    width: 100%;
+    height: 30rem;
+    border-radius: 20px;
+    background-color: #fff;
+}
+</style>

+ 221 - 0
src/views/MyNutrition.vue

@@ -0,0 +1,221 @@
+<template>
+  <div class="page-content">
+    <div class="left-content">
+      <div class="dish_items">
+        <div class="dish_item">
+          <div class="item-container" ref="box">
+            <div class="draggable-item-horizontal selected-item"  v-for="item in items2">
+              <div class="selected-item-content">
+                <img class="selected-item-img" :src="item.img" :alt="item.data">
+                <span>{{item.data}}</span>
+              </div>
+            </div>
+            <div class="container-selected-item"  :style="{border:isEnter?'1px dashed red':'1px dashed blue'}">
+              <Container
+                behaviour="contain"
+                group-name="1"
+                :get-child-payload="getChildPayload2"
+                @drop="onDrop('items2', $event,'type1')"
+                @drag-enter="onEnter"
+                @drag-leave="onLeave"
+                @drag-end="onEnd"
+                drag-class="card-ghost">
+                <div style="color: #00000000">{{ "1 " }}</div>
+              </Container>
+            </div>
+          </div>
+
+
+        </div>
+        <div class="dish_item">
+          <Container
+            orientation="horizontal"
+            :drag-begin-delay="0"
+            behaviour="contain"
+            group-name="1"
+            :get-child-payload="getChildPayload1"
+            @drop="onDrop('items3', $event)"
+            drag-class="card-ghost">
+            <Draggable v-for="item in items3">
+              <div class="draggable-item-horizontal">
+                <div class="selected-item-content">
+                  <img class="selected-item-img" :src="item.img" :alt="item.data">
+                  <span>{{item.data}}</span>
+                </div>
+              </div>
+            </Draggable>
+          </Container>
+        </div>
+      </div>
+    </div>
+    <div class="right-content">
+      <div class="dish_select_list">
+        <Container
+          :drag-begin-delay="20"
+          behaviour="copy"
+          group-name="1"
+
+          :get-child-payload="getChildPayload1"
+          drag-class="card-ghost">
+          <Draggable v-for="item in items1">
+            <div class="draggable-item">
+              <div class="selected-item-content">
+                <img class="selected-item-img" :src="item.img" :alt="item.data">
+                <span>{{item.data}}</span>
+              </div>
+            </div>
+          </Draggable>
+        </Container>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+  import { Container, Draggable } from 'vue3-smooth-dnd'
+  const applyDrag = (arr, dragResult) => {
+    const { removedIndex, addedIndex, payload } = dragResult
+    if (removedIndex === null && addedIndex === null) return arr
+
+    const result = [...arr]
+    let itemToAdd = payload
+
+    if (removedIndex !== null) {
+      itemToAdd = result.splice(removedIndex, 1)[0]
+    }
+
+    if (addedIndex !== null) {
+      result.splice(addedIndex, 0, itemToAdd)
+    }
+
+    return result
+  }
+
+  export default {
+    name: 'Copy',
+    components: {Container, Draggable},
+    data () {
+      return {
+        isEnter: false,
+        items3: [],
+        items2: [],
+        items1: [{
+          id:1,
+          data:'xx_drag_1',
+          img:'https://do-while.oss-cn-beijing.aliyuncs.com/exhibition/1635177107%281%29.jpg'
+        },{
+          id:2,
+          data:'xx_drag_2',
+          img:'https://do-while.oss-cn-beijing.aliyuncs.com/exhibition/1635175644%281%29.jpg'
+        }]
+      }
+    },
+    methods: {
+      onDrop (collection, dropResult,type) {
+        const { removedIndex, addedIndex, payload } = dropResult
+        if(type == 'type1') {
+          let itemToAdd = payload
+          this[collection].splice(this[collection].length, 0, itemToAdd)
+        }
+        // this[collection] = applyDrag(this[collection], dropResult)
+
+      },
+      getChildPayload1 (index) {
+        return this.items1[index]
+      },
+      getChildPayload2 (index) {
+        return this.items2[index]
+      },
+      getChildPayload3 (index) {
+        return this.items3[index]
+      },
+      onEnter(e){
+        console.log(e)
+        this.isEnter = true
+      },
+      onLeave(e){
+        this.isEnter = false
+      },
+      onEnd(){
+        this.isEnter = false
+        this.$nextTick(()=>{
+          this.$refs.box.scrollLeft = this.$refs.box.scrollWidth
+        })
+      }
+    }
+  }
+</script>
+
+<style>
+.page-content{
+  display: flex;
+
+  height: 100%;
+}
+  .left-content{
+     flex: 1;
+    padding-top: 15px;
+     margin-right: 26px;
+    background-color: #31CA8A22;
+   }
+.right-content{
+  width: 342px;
+  padding-top: 15px;
+  background-color: #55112222;
+}
+  .horizontal{
+    width: 100% !important;
+    display: flex;
+    text-align: left;
+  }
+.smooth-dnd-container.horizontal > .smooth-dnd-draggable-wrapper{
+  display: inline-block;
+  margin-left: 20px;
+}
+
+  .draggable-item{
+    display: inline;
+  }
+  .dish_select_list .smooth-dnd-container{
+    display: flex;
+    flex-direction: column;
+  }
+  .dish_select_list .smooth-dnd-container .smooth-dnd-draggable-wrapper{
+    display: inline-block;
+    width: 57px;
+  }
+  .item-container{
+    max-width: 712px;
+    overflow-x: scroll;
+    white-space: nowrap; /* 内容超出不换行 */
+
+  }
+  .container-selected-item{
+    width: 80px;
+    height: 80px;
+    border-radius: 10px;
+    display: inline-block;
+  }
+  .selected-item {
+    height: 160px;
+    width: 90px;
+    display: inline-block;
+  }
+.smooth-dnd-disable-touch-action *{
+  touch-action: auto;
+}
+  .dish_item{
+
+    display: flex;
+  }
+  .selected-item-content{
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+  }
+  .selected-item-img{
+    width: 40px;
+    height: 40px;
+  }
+</style>

+ 564 - 0
src/views/home/home.vue

@@ -0,0 +1,564 @@
+<template>
+<div class="home">
+  <van-overlay :show="show.showMaskQA"
+               z-index="20"
+               lock-scroll
+               class-name="mask-back"
+               @click="show.showMaskQA = false" >
+    <LevelDescription></LevelDescription>
+  </van-overlay>
+  <!--  左侧  -->
+  <div class="home_left">
+    <!-- 今日膳食 -->
+    <div class="today_meal">
+      <h2 class="today_title">今日膳食</h2>
+      <!-- 日历 -->
+      <div class="calendar">
+        <WeekDays @on-item-click="onDayClick" v-if="currentDateArray.length > 0" :start="currentDateArray[0]" :end="currentDateArray[6]"></WeekDays>
+      </div>
+    </div>
+    <div class="three_meals">
+      <!-- 早餐 -->
+      <div class="breakfast">
+        <div class="breakfast_top">
+          <img src="../../assets/Dinner_breakfas.png" alt="">
+          <div>早餐</div>
+        </div>
+        <div class="food">
+          <template v-if="foodsList.foodsBreakfast && foodsList.foodsBreakfast.length > 0">
+            <div class="food_box" v-for="item in foodsList.foodsBreakfast">
+              <img :src="item.img" alt="">
+              <div>{{item.name}}</div>
+            </div>
+          </template>
+          <template v-else>
+            <div class="no-data">
+              <img src="../../assets/no_data.png" alt="">
+              <div class="no-data-tip">没有早餐</div>
+            </div>
+          </template>
+        </div>
+      </div>
+      <!-- 午餐 -->
+      <div class="breakfast">
+          <div class="breakfast_top">
+              <img src="../../assets/Dinner_lunch.png" alt="">
+              <div>午餐</div>
+          </div>
+          <div class="food">
+            <template v-if="foodsList.foodsLunch && foodsList.foodsLunch.length > 0">
+              <div>
+                <div class="food_box" v-for="item in foodsList.foodsLunch">
+                  <img :src="item.img" alt="">
+                  <div>{{item.name}}</div>
+                </div>
+              </div>
+            </template>
+            <template v-else>
+              <div class="no-data">
+                <img src="../../assets/no_data.png" alt="">
+                <div class="no-data-tip">没有午餐</div>
+              </div>
+            </template>
+          </div>
+      </div>
+      <!-- 晚餐 -->
+      <div class="breakfast">
+          <div class="breakfast_top">
+              <img src="../../assets/Dinner_supper.png" alt="">
+              <div>晚餐</div>
+          </div>
+          <div class="food">
+            <template v-if="foodsList.foodsDinner && foodsList.foodsDinner.length > 0">
+              <div>
+                <div class="food_box" v-for="item in foodsList.foodsDinner">
+                  <img :src="item.img" alt="">
+                  <div>{{item.name}}</div>
+                </div>
+              </div>
+            </template>
+            <template v-else>
+              <div class="no-data">
+                <img src="../../assets/no_data.png" alt="">
+                <div class="no-data-tip">没有晚餐</div>
+              </div>
+            </template>
+          </div>
+      </div>
+
+      <div class="breakfast">
+        <div class="breakfast_top">
+          <img src="../../assets/Dinner_supper.png" alt="">
+          <div>早点</div>
+        </div>
+        <div class="food">
+          <template v-if="foodsList.foodsDinner && foodsList.foodsDinner.length > 0">
+            <div>
+              <div class="food_box" v-for="item in foodsList.foodsDinner">
+                <img :src="item.img" alt="">
+                <div>{{item.name}}</div>
+              </div>
+            </div>
+          </template>
+          <template v-else>
+            <div class="no-data">
+              <img src="../../assets/no_data.png" alt="">
+              <div class="no-data-tip">没有晚餐</div>
+            </div>
+          </template>
+        </div>
+      </div>
+      <div class="breakfast">
+        <div class="breakfast_top">
+          <img src="../../assets/Dinner_supper.png" alt="">
+          <div>晚餐</div>
+        </div>
+        <div class="food">
+          <template v-if="foodsList.foodsDinner && foodsList.foodsDinner.length > 0">
+            <div>
+              <div class="food_box" v-for="item in foodsList.foodsDinner">
+                <img :src="item.img" alt="">
+                <div>{{item.name}}</div>
+              </div>
+            </div>
+          </template>
+          <template v-else>
+            <div class="no-data">
+              <img src="../../assets/no_data.png" alt="">
+              <div class="no-data-tip">没有晚餐</div>
+            </div>
+          </template>
+        </div>
+      </div>
+    </div>
+    <!-- 评价食谱 -->
+    <div class="comment-container">
+      <button class="recipes">评价食谱</button>
+    </div>
+    <!-- 选择时间 -->
+    <div class="select_time">
+      <div @click="toPrevWeek">
+        <img src="../../assets/leftOrRight/left.png" alt="">
+      </div>
+      <div class="select_time_mid" v-if="dateRange">
+        {{dateRange[0]}}~{{dateRange[1]}}
+      </div>
+      <div @click="toNextWeek">
+        <img src="../../assets/leftOrRight/right.png" alt="">
+      </div>
+    </div>
+    <div class="suit">
+      <SuitList @item-click="onSuitClick" :list="mockSuitList"></SuitList>
+    </div>
+  </div>
+  <!-- 右侧 -->
+  <div class="home_right">
+    <div class="evaluate_top">
+      <div class="evaluate_top_left">
+        <img src="../../assets/star.png" alt="">
+        <h2 class="comment-title">营养评级</h2>
+      </div>
+      <div class="evaluate_top_right">
+        <img class="dafen" src="../../assets/Purple.png" alt="">
+        <img @click="show.showMaskQA = true" class="inquiry" src="../../assets/icon_action_help.png" alt="">
+      </div>
+    </div>
+    <div class="evaluate_bottom">
+      <!-- 能量分布 -->
+      <div class="nengLiangFenBu">
+        <div class="word">
+          能量分布
+        </div>
+        <div class="echarts_box">
+          <div class="echarts">
+            <Score />
+            <div>蛋白质</div>
+          </div>
+          <div class="echarts">
+            <Score :name="'良好'" :color="'#FFA900'" :value="76.8" />
+            <div>脂肪</div>
+          </div>
+          <div class="echarts">
+            <Score :name="'及格'" :color="'#FD6C3B'" :value="10" />
+            <div>碳水化合物</div>
+          </div>
+        </div>
+      </div>
+      <!-- 其他营养素 -->
+      <div class="other">
+        <ScoreProgress lj="膳食纤维" :percent="80"></ScoreProgress>
+        <ScoreProgress lj="铁" :percent="55"></ScoreProgress>
+        <ScoreProgress lj="锌" :percent="89"></ScoreProgress>
+      </div>
+    </div>
+    </div>
+</div>
+</template>
+
+<script>
+import { ref, reactive } from 'vue'
+import WeekDays from '@/components/WeekDays.vue'
+import ScoreProgress from '@/components/ScoreProgress.vue'
+import SuitList from '@/components/SuitList.vue'
+import Score from '@/components/Echarts/Score.vue'
+import LevelDescription from '@/components/LevelDescription.vue'
+import { Overlay } from 'vant';
+import { getCurrentWeekByDate,getDateFormatOfCN } from '@/utils/dateUtils'
+export default {
+  components:{
+    WeekDays,
+    Score,
+    LevelDescription,
+    SuitList,
+    ScoreProgress,
+    'van-overlay':Overlay
+  },
+  data() {
+    return {
+      mockSuitList:[{name:'A套餐'},{name:'B套餐'},{name:'C套餐'},{name:'C套餐'},{name:'C套餐'},{name:'C套餐'},{name:'C套餐'},{name:'C套餐'},{name:'C套餐'},{name:'C套餐'},{name:'C套餐'}],
+      foodsList:{
+        foodsBreakfast:[{
+          name:'奶蒸馒头',
+          img: require('../../assets/ProfilePhoto.png')
+        },{
+          name:'烤全羊',
+          img: require('../../assets/ProfilePhoto.png')
+        },{
+          name:'佛跳墙',
+          img: require('../../assets/ProfilePhoto.png')
+        },{
+          name:'农家一碗香不香',
+          img: require('../../assets/ProfilePhoto.png')
+        },{
+          name:'农家一碗香不香',
+          img: require('../../assets/ProfilePhoto.png')
+        }],
+
+        foodsLunch:[],
+        foodsDinner:[]
+      },
+      currentDateArray:[],
+      show:{
+        showMaskQA:false
+      },
+      currenFirstDay:{
+        dateFormat: "",
+        year: "",
+        month: "",
+        date: "",
+        day: "",
+        timestamp: ""
+      }
+    }
+  },
+
+  mounted () {
+    this.currentDateArray = getCurrentWeekByDate()
+  },
+  computed:{
+    dateRange() {
+      if(this.currentDateArray.length == 0) return null
+      let startName = getDateFormatOfCN(this.currentDateArray[0])
+      let endName = getDateFormatOfCN(this.currentDateArray[6])
+      return [startName,endName]
+    }
+  },
+  methods:{
+    onSuitClick (item) {
+      // console.log(item)
+    },
+    firstDayChage( day ){
+      currenFirstDay = day
+    },
+    toPrevWeek(){
+      let preDay = new Date(this.currentDateArray[0])
+      preDay.setDate(preDay.getDate()-1)
+      this.currentDateArray = getCurrentWeekByDate(preDay)
+    },
+    toNextWeek(){
+      let preDay = new Date(this.currentDateArray[6])
+      preDay.setDate(preDay.getDate()+1)
+      this.currentDateArray = getCurrentWeekByDate(preDay)
+    },
+    onDayClick(item) {
+      console.log(item)
+    }
+  }
+}
+
+
+
+</script>
+
+<style lang="less">
+  :root{
+    --van-overlay-background-color: #00000011;
+  }
+  /deep/
+  .mask-back{
+    background-color: #00000000 !important;
+  }
+.home {
+    display: flex;
+    width: 95%;
+    height: 96%;
+    margin-top: 2% !important;
+    justify-content: space-between;
+    margin: 10px auto 10px auto;
+    background-color: #FAFAFC;
+}
+
+.home_left {
+    background-color: #fff;
+    width: 49%;
+    display: flex;
+  flex-direction: column;
+    // height: 122.1rem;
+}
+
+.home_right {
+    background-color: #F4F2FF;
+    width: 49%;
+  display: flex;
+  flex-direction: column;
+    // height: 122.1rem;
+    height: 100% !important;
+    border-radius: 1.6rem;
+    height: 86.8rem;
+  padding-bottom: 10px;
+}
+
+.evaluate_top {
+    height: 14rem;
+    width: 90%;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    // background-color: red;
+    margin: auto;
+}
+
+.evaluate_top_left {
+    width: 50%;
+    display: flex;
+    align-items: center;
+    font-size: 2.2rem;
+
+}
+
+.evaluate_top_left img {
+    width: 4.6rem;
+    height: 4.6rem;
+}
+
+
+.comment-title{
+  margin-left: 1rem;
+  font-size: 32px;
+}
+
+.evaluate_top_right {
+    width: 40%;
+    height: 70%;
+    display: flex;
+    justify-content: flex-end;
+    align-items: center;
+    position: relative;
+}
+
+.dafen {
+  width: 115px;
+  height: 115px;
+  margin-right: 20px;
+}
+
+.inquiry {
+    width: 2rem;
+    height: 2rem;
+    position: absolute;
+    right: -1.3rem;
+    top: .1rem;
+}
+
+.evaluate_bottom {
+    width: 98%;
+    height: 70rem;
+    background-color: #FFF;
+    margin: auto;
+    border-radius: 1.6rem;
+    padding-top: 2rem;
+  flex: 1;
+}
+
+.nengLiangFenBu {
+    height: 25%;
+    // background-color: #00000068;
+    width: 90%;
+    text-align: left;
+    margin: auto;
+    font-size: 2rem;
+}
+
+.echarts_box {
+    display: flex;
+    align-items: center;
+    justify-content: space-around;
+    // justify-content: center;
+}
+
+.echarts {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+}
+
+.today_meal {
+    margin-top: 2rem;
+    text-align: left;
+    font-size: 3rem;
+    border-bottom: 1px #00000011 solid;
+    padding-bottom: 2rem;
+}
+.today_title {
+  margin: 3rem;
+  font-size: 32px;
+  font-weight: 600;
+}
+.calendar {
+    width: 95%;
+    display: flex;
+    justify-content: space-between;
+
+}
+.calendar_data{
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    // margin-right: 2rem;
+
+    div:nth-child(1){
+        margin: 0 !important;
+        color: #929292;
+        font-size: 1.17rem;
+    }
+    div:nth-child(2){
+        font-size: 2.3rem;
+        margin-top: 1rem;
+    }
+}
+
+.breakfast {
+    margin-top: 30px;
+    margin-left: 2.75rem;
+}
+
+.breakfast_top {
+    display: flex;
+    align-items: center;
+
+    img {
+        width: 3.3rem;
+        height: 3.3rem;
+    }
+
+    div {
+      margin-left: 1.1rem;
+      font-size: 1.8em;
+      font-weight: bold;
+    }
+}
+
+.food {
+    display: flex;
+    margin-top: 2rem;
+    //
+    overflow-x: scroll;
+
+
+    img {
+        width: 5.3rem;
+        height: 5.3rem;
+    }
+}
+.food::-webkit-scrollbar{
+    display: none;
+}
+
+.food_box {
+  display: flex;
+  align-items: center;
+  flex-direction: column;
+  font-size: 1.8em;
+  margin-right: 1.6rem;
+
+    div {
+        margin-top: 0.7rem;
+      max-width: 140px;
+      min-width: 90px;
+      word-break: break-all;
+      text-overflow: ellipsis;
+      -webkit-box-orient: vertical;
+      display: -webkit-box;
+      -webkit-line-clamp: 1;
+      overflow: hidden;
+    }
+}
+
+.recipes {
+  width: 16.6vw;
+  height: 2.5vh;
+  background-color: #9380FF;
+  border: none;
+  border-radius: 16.7rem;
+  color: white;
+  font-size: 1.4em;
+}
+
+.three_meals {
+    flex: 1;
+    overflow: auto;
+}
+
+.select_time {
+    width: 100%;
+    height: 7rem;
+    display: flex;
+    justify-content: space-around;
+    margin-top: 4.8rem;
+    align-items: center;
+    // background-color: red;
+    border-top: #00000011 solid;
+
+}
+.select_time_mid{
+    width: 23rem;
+    height: 3.5rem;
+    border-radius: 2rem;
+    background-color: #F6F7FB;
+    width: 80%;
+    margin: 0 auto;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  font-size: 1.8em;
+  color: #000;
+  font-weight: 600;
+
+}
+  .comment-container{
+      margin-left:  2.75rem;
+  }
+.no-data{
+  width: 100%;
+  padding: 2.5vh 0;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+.no-data-tip{
+  margin-top: 8px;
+  font-size: 1.1em;
+}
+</style>

+ 15 - 0
vue.config.js

@@ -0,0 +1,15 @@
+/*
+ * @Description: 项目配置文件
+ * @Author: ligy
+ * @Date: 2022-04-06 15:41:12
+ * @LastEditTime: 2022-04-06 15:41:13
+ */
+module.exports = {
+    lintOnSave: false,
+    devServer: {
+        overlay: {
+        warning: false,
+        errors: false
+        }
+    },
+}