YangJian0701 1 year ago
parent
commit
c1fe8ed121

+ 1 - 0
package.json

@@ -10,6 +10,7 @@
     "@element-plus/icons-vue": "^2.1.0",
     "@element-plus/icons-vue": "^2.1.0",
     "axios": "^1.6.1",
     "axios": "^1.6.1",
     "core-js": "^3.8.3",
     "core-js": "^3.8.3",
+    "echarts": "^5.4.3",
     "element-plus": "^2.4.2",
     "element-plus": "^2.4.2",
     "register-service-worker": "^1.7.2",
     "register-service-worker": "^1.7.2",
     "vue": "^3.2.13",
     "vue": "^3.2.13",

+ 8 - 0
src/App.vue

@@ -1,9 +1,15 @@
 <template>
 <template>
   <router-view/>
   <router-view/>
 </template>
 </template>
+<script lang="ts" setup>
+
+
+</script>
 <style lang="scss">
 <style lang="scss">
 @import url('@/assets/css/scrolls.css');
 @import url('@/assets/css/scrolls.css');
 @import url('@/assets/css/font.css');
 @import url('@/assets/css/font.css');
+@import url('@/assets/scss/config.scss');
+
 #app {
 #app {
   font-family: Avenir, Helvetica, Arial, sans-serif;
   font-family: Avenir, Helvetica, Arial, sans-serif;
   -webkit-font-smoothing: antialiased;
   -webkit-font-smoothing: antialiased;
@@ -15,6 +21,8 @@
 body,html{
 body,html{
   height: 100%;
   height: 100%;
   background: linear-gradient( #d7e4f4,#afd1fe);
   background: linear-gradient( #d7e4f4,#afd1fe);
+  // background: rgb(241, 243, 244);
+
   // linear-gradient(to bottom #d7e4f4,#afd1fe)
   // linear-gradient(to bottom #d7e4f4,#afd1fe)
   // background: url('@/assets/img/bg-5.jpg') no-repeat bottom center;
   // background: url('@/assets/img/bg-5.jpg') no-repeat bottom center;
   // background-size:cover;
   // background-size:cover;

BIN
src/assets/img/userInfo.gif


+ 21 - 0
src/assets/scss/config.scss

@@ -0,0 +1,21 @@
+:root {
+    /*系统背景色*/
+    --y-background-color: #ccc;
+    /*大标题颜色*/
+    --y-fontSize-h1: 20px;
+    /*logo颜色*/
+    --y-color-logo: #409eff;
+    /*主体内容文字色*/
+    --y-TxtColor: #888;
+    /*边框*/
+    --y-border:1px solid #e4e7ed;
+    /*?卡片背景色*/
+    --y-card-background:#fff;
+    /*圆角*/
+    --y-radius:4px;
+
+    /*内边距*/
+    --y-padding:20px;
+    /*外边距*/
+    --y-margin:20px;
+}

+ 0 - 5
src/assets/style/self.scss

@@ -1,5 +0,0 @@
-$brandColor:#147DE2;     // 品牌主色
-$contentTxtColor:#888;   // 主体内容文字色
-$mainH1Fsize:32px;         // 大标题字号
-$contentFsize:14px;        // 主体内容字号
-

+ 4 - 0
src/components/backTop.vue

@@ -0,0 +1,4 @@
+<!-- 返回顶部 -->
+<template>
+    <el-backtop :right="100" :bottom="100" />
+</template>

+ 29 - 0
src/components/card.vue

@@ -0,0 +1,29 @@
+<!--  -->
+<template>
+    <div class="y-card">
+        <div class="y-card-headers">
+            <h4><slot name="card-tit"></slot>  </h4>
+        </div>
+        <div class="y-card-item">
+            <slot name="card-content"></slot>  
+        </div>
+    </div>
+</template>
+
+<script setup>
+</script>
+<style lang="scss">
+.y-card {
+    background: var(--y-card-background);
+    border-radius: var(--y-radius);
+    margin-bottom: var(--y-margin);
+    &-headers {
+        border-bottom: var(--y-border);
+        box-sizing: border-box;
+        padding: var(--y-padding);
+    }
+    &-item{
+        padding: var(--y-padding);
+    }
+}
+</style>

+ 109 - 0
src/components/echart/echart-bar.vue

@@ -0,0 +1,109 @@
+<!-- 柱图 -->
+<template>
+    <div style="height:300px;" :id="props.id" class="myChart"></div>
+</template>
+
+<script setup lang="ts">
+import { inject,onMounted,reactive } from "vue";
+const props = defineProps({
+    id: {
+        type: String,
+        default: () => '',
+    },
+    lineData:{
+        type:Object,
+        default: () => {},
+    },
+})
+
+let echartData:any = reactive({
+    titles:'',//标题
+    xAxisArr:[],//x轴
+    seriesDiscount:[], //合同总金额
+    seriesRecoveries:[] //合同已回款金额
+})
+
+let echart:any = null
+let myChart:any = null
+
+onMounted(() => {
+    echart = inject('echart')
+    myChart = echart.init(document.getElementById(props.id));
+    setEchartFun();
+})
+//函数
+const setEchartFun = async ()=>{
+    myChart.setOption(initEcharts());
+    window.onresize = function () {
+        myChart.resize();
+    };
+}
+
+const initEcharts = () => {
+    // 绘制图表
+    return {
+        tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+                type: 'cross',
+                label: {
+                    backgroundColor: '#6a7985'
+                }
+            }
+        },
+        title: {
+            // text: 'Rainfall vs Evaporation',
+            // subtext: echartData.titles
+        },
+        grid: {
+            left: '0%',
+            right: '1%',
+            bottom: '0%',
+            containLabel: true
+        },
+        xAxis: [
+            {
+                boundaryGap: false,
+                type: 'category',
+                // data: echartData.xAxisArr
+            }
+        ],
+        yAxis: {
+            type: 'value'
+        },
+        series: [
+            {
+                // name: echartData.tooltip,
+                type: 'line',
+                smooth: true,
+                stack: 'Total',
+                areaStyle: {},
+                emphasis: {
+                    focus: 'series'
+                },
+                itemStyle: { //面积图颜色设置
+                    color: {
+                        type: 'linear',
+                        x: 0,
+                        y: 0,
+                        x2: 0,
+                        y2: 1,
+                        colorStops: [
+                            {
+                                offset: 0, //offset 可取范围 0、0.1、0.2、到1
+                                color: 'rgba(250, 51, 171, 0.8)', // 0% 处的颜色
+                            },
+                            {
+                                offset: 1,
+                                color: 'rgba(206, 51, 181, 0.4)' // 100% 处的颜色
+                            }
+                        ],
+                        globalCoord: false // 缺省为 false
+                    }
+                },
+                data:[120, 200, 150, 80, 70, 110, 130],
+            }
+        ]
+    }
+}
+</script>

+ 1 - 0
src/components/logo.vue

@@ -17,6 +17,7 @@
         font-family: douyuzhuiguangti;
         font-family: douyuzhuiguangti;
         color: #409eff;
         color: #409eff;
         margin-top: 5px;
         margin-top: 5px;
+        background: var(--theme_bg_color);
     }
     }
 }
 }
 </style>
 </style>

+ 112 - 0
src/components/popover.vue

@@ -0,0 +1,112 @@
+<!--  -->
+<template>
+    <div class="">
+        <el-popover :width="300"
+            popper-style="box-shadow: rgb(14 18 22 / 35%) 0px 10px 38px -10px, rgb(14 18 22 / 20%) 0px 10px 20px -15px; padding: 20px;">
+            <template #reference>
+                <img src="@/assets/img/userInfo.gif" style="width: 40px;height: 40px;border-radius: 50%;cursor: pointer">
+            </template>
+            <template #default>
+                <div class="demo-rich-conent" style="display: flex; gap: 16px; flex-direction: column">
+                    <img src="@/assets/img/userInfo.gif" style="width: 40px;height: 40px;border-radius: 50%;">
+                    <div>
+                        <p class="demo-rich-content__name" style="margin: 0; font-weight: 500">
+                            你好,管理员
+                        </p>
+                        <p class="demo-rich-content__mention" style="color: var(--el-color-info)">
+                            @element-plus
+                        </p>
+                    </div>
+                    <div class="demo-ico__desc">
+                        <div class="demo-ico__desc_item" @click="exitFun(1)">
+                            <el-icon size="20" color="#fff">
+                                <FullScreen />
+                            </el-icon>
+                            <p class="demo-ico__desc_item_p">全屏</p>
+                        </div>
+                        <div class="demo-ico__desc_item" @click="exitFun(2)">
+                            <el-icon size="20" color="#fff">
+                                <Setting />
+                            </el-icon>
+                            <p class="demo-ico__desc_item_p">设置</p>
+                        </div>
+                        <div class="demo-ico__desc_item" @click="exitFun(3)">
+                            <el-icon size="20" color="#fff">
+                                <Bell />
+                            </el-icon>
+                            <p class="demo-ico__desc_item_p">系统消息</p>
+                        </div>
+                        <div class="demo-ico__desc_item" @click="exitFun(4)">
+                            <el-icon size="20" color="#fff">
+                                <SwitchButton />
+                            </el-icon>
+                            <p class="demo-ico__desc_item_p">退出账号</p>
+                        </div>
+                    </div>
+                </div>
+            </template>
+        </el-popover>
+    </div>
+</template>
+<script lang="ts" setup>
+import { exitFun } from "@/plugins/setFun";
+</script>
+<style lang="scss">
+.demo-ico__desc {
+    display: grid;
+    grid-template-columns: 1fr 1fr;
+    grid-gap: 10px;
+    user-select: none;
+
+    &_item {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        flex-direction: column;
+        padding: 10px 0;
+        border-radius: 2px;
+        cursor: pointer;
+
+        &_p {
+            color: #fff;
+            margin-top: 5px;
+            font-size: 12px;
+        }
+    }
+
+    &_item:nth-child(1) {
+        background: #ee954d;
+    }
+
+    &_item:nth-child(1):hover {
+        background: rgba(#ee954d, 0.6) !important;
+    }
+
+    &_item:nth-child(2) {
+        background: #32b67a;
+    }
+
+    &_item:nth-child(2):hover {
+        background: rgba(#32b67a, 0.6) !important;
+    }
+
+    &_item:nth-child(3) {
+        background: #349ac1;
+    }
+
+    &_item:nth-child(3):hover {
+        background: rgba(#349ac1, 0.6) !important;
+    }
+
+    &_item:nth-child(4) {
+        background: #ff8b8b;
+    }
+
+    &_item:nth-child(4):hover {
+        background: rgba(#ff8b8b, 0.6) !important;
+    }
+
+    &_item:nth-child(5) {
+        background: #e54b4b;
+    }
+}</style>

+ 37 - 9
src/components/routerMenu.vue

@@ -1,22 +1,50 @@
 <template>
 <template>
-  <el-menu :default-active="router.options.history.location" mode="horizontal" :ellipsis="false" router>
-    <el-menu-item :index="item.path" v-for="item,index in routerData" :key="index">
-      <span>{{item.meta.title}}</span>
-    </el-menu-item>
-  </el-menu>
+  <div>
+    <el-menu :default-active="router.options.history.location" mode="horizontal" :ellipsis="false" v-if="screenWidth>=1000" router>
+      <el-menu-item :index="item.path" v-for="item, index in routerData" :key="index">
+        <span>{{ item.meta.title }}</span>
+      </el-menu-item>
+    </el-menu>
+    <el-popover v-else>
+      <template #reference>
+        <el-icon size="30" style="cursor: pointer;">
+          <More />
+        </el-icon>
+      </template>
+      <template #default>
+        <div class="demo-rich-conent" style="display: flex; gap: 16px; flex-direction: column">
+          <el-menu :default-active="router.options.history.location" :ellipsis="false" router>
+            <el-menu-item :index="item.path" v-for="item, index in routerData" :key="index">
+              <span>{{ item.meta.title }}</span>
+            </el-menu-item>
+          </el-menu>
+        </div>
+      </template>
+    </el-popover>
+  </div>
 </template>
 </template>
 
 
 <script lang="ts" setup>
 <script lang="ts" setup>
 import { useRouter } from 'vue-router';
 import { useRouter } from 'vue-router';
 import { ref } from 'vue'
 import { ref } from 'vue'
 
 
-let router = useRouter()
 
 
-const routerData:any = ref([])
+let router = useRouter()
+const screenWidth = ref()
+const routerData: any = ref([])
 routerData.value = router.options.routes[0].children
 routerData.value = router.options.routes[0].children
-
+screenWidth.value = document.body.clientWidth
+window.onresize = () => (() => {
+  screenWidth.value = document.body.clientWidth
+})();
 </script>
 </script>
 
 
 <style scoped lang="scss">
 <style scoped lang="scss">
-
+/*去掉左侧菜单自带的右侧边框*/
+.el-menu--horizontal.el-menu {
+    border: none !important;
+}
+.el-menu {
+  border: none !important;
+}
 </style>
 </style>

+ 63 - 0
src/components/table.vue

@@ -0,0 +1,63 @@
+<!--  -->
+<template>
+    <div class="y-tabs">
+        <el-table :data="tableData">
+            <template>
+                <el-table-column v-for="(item, index) in columns" :key="index" v-bind="item" v-slot="scope">
+                    <slot :name="item.prop" :row="scope.row">{{ scope.row.prop }}</slot>
+                </el-table-column>
+            </template>
+        </el-table>
+
+        <Pagination layout="total, sizes, prev, pager, next, jumper" :pageable="pageable" :handleSizeChange="handleSizeChange"
+            :handleCurrentChange="handleCurrentChange" />
+    </div>
+</template>
+
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import { useTable } from '@/hooks/useTable'
+import { login } from '@/api/index'
+
+
+// 表格操作 Hooks
+const { tableData, getTableList,pageable } = useTable(login, { page: 1, page_z: 10 }, true)
+
+const columns: any = [
+    { prop: 'T_name', label: '姓名' },
+    { prop: 'T_id', label: 'id' },
+    { prop: 'operation', label: '操作', width: 200, fixed: 'right' }
+]
+getTableList()
+const data = reactive({
+    currentPage: 1,
+    pageSize: 10,
+})
+
+const handleSizeChange = (val: number) => {
+    console.log(`${val} items per page`)
+}
+const handleCurrentChange = (val: number) => {
+    console.log(`current page: ${val}`)
+}
+
+
+</script>
+<style lang="scss">
+.y-tabs {
+    background: var(--y-card-background);
+    border-radius: var(--y-radius);
+    margin-bottom: var(--y-margin);
+    padding: var(--y-padding);
+
+    &-headers {
+        border-bottom: var(--y-border);
+        box-sizing: border-box;
+        padding: var(--y-padding);
+    }
+
+    &-item {
+        padding: var(--y-padding);
+    }
+}
+</style>

+ 35 - 0
src/components/tabs.vue

@@ -0,0 +1,35 @@
+<!--  -->
+<template>
+    <div class="y-tabs">
+        <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+            <el-tab-pane :label="item.label" :name="item.name" v-for="(item,index) in props.tabData" :key="index">
+                <slot name="tabs-content"></slot>
+            </el-tab-pane>
+        </el-tabs>
+    </div>
+</template>
+
+<script setup lang="ts">
+import {ref,onMounted} from "vue";
+import type { TabsPaneContext } from 'element-plus'
+const activeName = ref('first')
+const props: any = defineProps({
+    tabData: {
+        type: Array,
+        default: () => '',
+    }
+})
+onMounted(()=>{
+    activeName.value = props.tabData[0].name
+})
+const handleClick = (tab: TabsPaneContext, event: Event) => {
+  console.log(tab, event)
+}
+</script>
+<style lang="scss">
+.y-tabs {
+    background: var(--y-card-background);
+    border-radius: var(--y-radius);
+    margin-bottom: var(--y-margin);
+}
+</style>

+ 100 - 0
src/hooks/useTable.ts

@@ -0,0 +1,100 @@
+import { reactive, toRefs } from 'vue'
+// 分页数据
+interface Pageable {
+  pageNum: number
+  pageSize: number
+  total: number
+  RemainingTime?: number
+  small: boolean
+  disabled: boolean
+}
+// 表格数据
+interface Table {
+  loading: boolean
+  tableData: any[]
+  pageable: Pageable
+  searchParam: any
+  searchInitParam: any
+  totalParam: any
+}
+
+/**
+ *
+ * @param requestApi 请求接口
+ * @param initParam 请求参数
+ * @param isPagination 是否需要分页
+ * @param dataCallback 对后台返回参数进行处理
+ * @returns
+ */
+
+
+export const useTable = (
+  requestApi: (params: any) => Promise<any>,
+  initParam: object = {},
+  isPagination: boolean = true,
+  dataCallback?: (data: any) => any
+) => {
+  const state = reactive<Table>({
+    // 表格数据
+    tableData: [],
+    loading: true,
+    // 分页数据
+    pageable: {
+      // 当前页数
+      pageNum: 1,
+      // 每页显示条数
+      pageSize: 10,
+      // 总条数
+      total: 0,
+      RemainingTime: 0,
+      small: true,
+      disabled: false
+    },
+    // 查询参数(只包括查询)
+    searchParam: {},
+    // 初始化默认的查询参数
+    searchInitParam: {},
+    // 总参数(包含分页和查询参数)
+    totalParam: {}
+  })
+
+  const getTableList = async () => {
+    const params: any = {
+      page: state.pageable.pageNum,
+      page_z: state.pageable.pageSize,
+      ...initParam
+    }
+    const res = await requestApi(params)
+    state.tableData = res.Data?.Data
+    dataCallback && (state.tableData = dataCallback(res))
+    state.pageable.total = res.Data?.Num
+    if (res.Data?.RemainingTime) {
+      state.pageable.RemainingTime = res.Data.RemainingTime
+    }
+    state.loading = false
+  }
+  if (isPagination) {
+  }
+  const handleSizeChange = (val: number) => {
+    state.pageable.pageSize = val
+    getTableList()
+  }
+
+  const handleCurrentChange = (val: number) => {
+    state.pageable.pageNum = val
+    getTableList()
+  }
+
+  const searchTable = () => {
+    state.pageable.pageNum = 1
+    getTableList()
+  }
+
+  return {
+    ...toRefs(state),
+    getTableList,
+    searchTable,
+    handleSizeChange,
+    handleCurrentChange
+  }
+}

+ 0 - 0
src/plugins/ResizeObserver.ts


+ 23 - 0
src/plugins/setFun.ts

@@ -0,0 +1,23 @@
+import router from '@/router';
+
+/**
+ * 
+ * @param key 操作顶部头像按钮
+ */
+export function exitFun (key:any) {
+    console.log('')
+    switch (key) {
+        case 1:
+            break;
+        case 2:
+            break; 
+        case 3:
+            break;
+        default:
+            router.replace('/')
+            break;
+    } 
+}
+// export function exitFun1 () {
+        
+// }

+ 36 - 8
src/views/home/index.vue

@@ -1,15 +1,43 @@
 <!--  -->
 <!--  -->
 <template>
 <template>
-    <div class="home">
-        首页
-    </div>
+  <div class="home">
+    <cards>
+      <template #card-tit>疫苗名称</template>
+      <template #card-content>
+        <echartbar id="bar1" :lineData="data.tableData" />
+      </template>
+    </cards>
+    <tabs :tabData="data.tabData">
+      <template #tabs-content>
+        <tables></tables>
+      </template>
+    </tabs>
+  </div>
 </template>
 </template>
 
 
-<script setup>
+<script setup lang="ts">
+import { reactive, provide,ref } from "vue";
+import echartbar from '@/components/echart/echart-bar.vue'
+import cards from '@/components/card.vue'
+import tabs from '@/components/tabs.vue'
+import tables from '@/components/table.vue'
+
+
+
+
+import * as echarts from 'echarts'
+provide('echart', echarts)
+const data = reactive({
+  tableData: [],
+  tabData:[
+    {label:"疫苗名称",name:"first"},
+    {label:"生产企业",name:"second"},
+    {label:"规格",name:"third"},
+    {label:"剂型",name:"fourth"},
+    {label:"单位",name:"fourth1"},
+  ]
+
+})
 </script>
 </script>
 <style lang="scss">
 <style lang="scss">
-/* @import url(); 引入css类 */
-.home{
-    // background: red;
-}
 </style>
 </style>

+ 13 - 5
src/views/layout/index.vue

@@ -1,18 +1,26 @@
 <!--  -->
 <!--  -->
 <template>
 <template>
     <div class="layout">
     <div class="layout">
-        <menus class="menus" style=""></menus>
-        <div style="flex: 1;margin-bottom: 150px;">
+        <el-affix :offset="0">
+            <menus class="menus"></menus>
+        </el-affix>
+        <div class="layout-route">
             <router-view></router-view>
             <router-view></router-view>
+            <backTop></backTop>
         </div>
         </div>
     </div>
     </div>
 </template>
 </template>
 <script setup lang="ts">
 <script setup lang="ts">
-    import menus from "./menu.vue";
+import menus from "./menu.vue";
+import backTop from "@/components/backTop.vue";
+
 </script>
 </script>
 <style lang="scss">
 <style lang="scss">
-/* @import url(); 引入css类 */
-.layout{
+.layout {
     height: 100vh;
     height: 100vh;
+    &-route{
+        flex: 1;
+        margin:var(--y-margin);
+    }
 }
 }
 </style>
 </style>

+ 4 - 1
src/views/layout/menu.vue

@@ -5,13 +5,15 @@
             <routerMenu></routerMenu>
             <routerMenu></routerMenu>
         </div>
         </div>
         <div>
         <div>
-            <el-icon><FullScreen /></el-icon>
+            <popover/>
         </div>
         </div>
     </div>
     </div>
 </template>
 </template>
   
   
 <script lang="ts" setup>
 <script lang="ts" setup>
+import popover from "@/components/popover.vue";
 import routerMenu from "@/components/routerMenu.vue";
 import routerMenu from "@/components/routerMenu.vue";
+
 import logo from "@/components/logo.vue";
 import logo from "@/components/logo.vue";
 
 
 </script>
 </script>
@@ -21,6 +23,7 @@ import logo from "@/components/logo.vue";
     display: flex;
     display: flex;
     justify-content: space-between;
     justify-content: space-between;
     align-items: center;
     align-items: center;
+    height: 60px;
     padding: 0 20px;
     padding: 0 20px;
     background: #fff;
     background: #fff;
     user-select: none;
     user-select: none;

+ 2 - 10
vue.config.js

@@ -1,22 +1,13 @@
 const { defineConfig } = require('@vue/cli-service')
 const { defineConfig } = require('@vue/cli-service')
 module.exports = defineConfig({
 module.exports = defineConfig({
 	transpileDependencies: true,
 	transpileDependencies: true,
-	// css:{	
-	// 	preprocessorOptions: {
-	// 		// 全局样式引入
-	// 		scss:{
-	// 			additionalData: '@import "./src/assets/styles/self.scss";',
-    //       		javascriptEnabled: true
-	// 		}
-	// 	},
-	// }
 })
 })
 module.exports = {
 module.exports = {
 	lintOnSave: false, //关闭eslint验证
 	lintOnSave: false, //关闭eslint验证
 	outputDir: '出入库管理系统',// 输出文件目录(默认dist)
 	outputDir: '出入库管理系统',// 输出文件目录(默认dist)
 	devServer: {
 	devServer: {
 		open: false,//打开浏览器
 		open: false,//打开浏览器
-      	host: '0.0.0.0',
+		host: '0.0.0.0',
 		proxy: {
 		proxy: {
 			[process.env.VUE_APP_BASE_API]: {
 			[process.env.VUE_APP_BASE_API]: {
 				target: process.env.VUE_APP_BASE_URL,
 				target: process.env.VUE_APP_BASE_URL,
@@ -28,4 +19,5 @@ module.exports = {
 		}
 		}
 	},
 	},
 	
 	
+
 }
 }