Browse Source

优化首页

lishuangjiang@potevio.com 1 year ago
parent
commit
6f73ce2f19

+ 194 - 0
sso-ui/sso-ui-admin-vue3/src/components/common/ScaleContainer/index.vue

@@ -0,0 +1,194 @@
+<template>
+  <transition :name="transitionName">
+    <div
+      v-show="visible"
+      ref="ScaleContainer"
+      class="scale-container scroll-style"
+      :class="{
+        'scroll__x-visible': scrollX,
+        'scroll__y-visible': scrollY,
+      }"
+    >
+      <div class="no-scale-box">
+        <slot name="noScale"></slot>
+      </div>
+      <div
+        ref="scaleBox"
+        :class="scrollX ? 'scale-box__scroll' : 'scale-box'"
+        :style="{
+          width: `${width}px`,
+          height: `${height}px`,
+        }"
+      >
+        <slot></slot>
+      </div>
+    </div>
+  </transition>
+</template>
+
+<script setup>
+import { ref, onMounted, onUnmounted, provide, nextTick, watch } from "vue";
+import { debounce, clearTimer } from "@/utils";
+
+defineOptions(
+  {
+    name: "ScaleContainer"
+  }
+);
+
+const props = defineProps({
+  // 设计稿宽度
+  width: {
+    type: Number,
+    default: 1920,
+  },
+  // 设计稿高度
+  height: {
+    type: Number,
+    default: 1080,
+  },
+  // 是否显示滚动条
+  scroll: {
+    type: Boolean,
+    default: false,
+  },
+  // 滚动条位置
+  scrollPosition: {
+    type: String,
+    default: "center",
+  },
+  // 显示1:1设计稿尺寸,若设计稿尺寸大于当前屏幕则显示xy轴滚动条
+  displayOrigin: {
+    type: Boolean,
+    default: false,
+  },
+  // 过渡动画名称
+  transitionName: {
+    type: String,
+    default: "fade",
+  },
+});
+
+const visible = ref(true);
+const scaleBox = ref(null);
+const ScaleContainer = ref(null);
+const scale = ref(1);
+
+const scrollX = ref(false);
+const scrollY = ref(false);
+
+const timer = ref(null);
+
+watch(
+  () => props.scroll,
+  (val) => {
+    scrollX.value = val;
+  }
+);
+
+const getScale = () => {
+  const { width, height, displayOrigin, scroll } = props;
+  scrollX.value = scroll;
+
+  if (displayOrigin) {
+    scrollY.value = scroll;
+    return 1;
+  }
+
+  let ww = window.innerWidth / width;
+  let wh = window.innerHeight / height;
+
+  if (scrollX.value) {
+    return wh;
+  }
+  return ww < wh ? ww : wh;
+};
+
+// 设置缩放大小
+const setScale = debounce(() => {
+  if(!scaleBox.value) return;
+
+  scale.value = getScale();
+
+  const { width, height, scrollPosition, scroll } = props;
+
+  scaleBox.value.style.setProperty("--scale", scale.value);
+  scaleBox.value.style.setProperty("--height", `${height}px`);
+  scaleBox.value.style.setProperty("--width", `${width}px`);
+
+  visible.value = false;
+  clearTimer([timer.value]);
+      timer.value = setTimeout(() => {
+    visible.value = true;
+    nextTick(() => {
+      if (scrollX.value) {
+        const position = {
+          left: 0,
+          center:
+            (scaleBox.value.offsetWidth * scale.value -
+              ScaleContainer.value.offsetWidth) /
+            2,
+          right: scaleBox.value.offsetWidth * scale.value,
+        };
+        ScaleContainer.value.scrollLeft = position[scrollPosition];
+      }
+    });
+  }, 100);
+}, 500);
+
+onMounted(() => {
+  setScale();
+  window.addEventListener("resize", setScale);
+});
+
+onUnmounted(() => {
+  window.removeEventListener("resize", setScale);
+});
+
+provide("getPageScale", scale);
+</script>
+
+<style lang="scss" scoped>
+.scale-container {
+  position: fixed;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  z-index: 1;
+  overflow: hidden;
+}
+
+.scroll__x-visible {
+  overflow-x: auto;
+}
+
+.scroll__y-visible {
+  overflow-y: auto;
+}
+
+.scale-box {
+  --scale: 1;
+  position: absolute;
+  left: 50%;
+  top: 50%;
+  transform: scale(var(--scale)) translateX(-50%) translateY(-50%);
+  transform-origin: 0 0;
+  transition: 0.3s;
+  overflow: hidden;
+
+  &__scroll {
+    --scale: 1;
+    position: absolute;
+    transform: scale(var(--scale));
+    transform-origin: 0 0;
+    transition: 0.3s;
+  }
+}
+
+.no-scale-box {
+  position: absolute;
+  width: calc(var(--width) * var(--scale));
+  height: calc(var(--height) * var(--scale));
+}
+</style>

+ 1 - 1
sso-ui/sso-ui-admin-vue3/src/router/modules/remaining.ts

@@ -196,7 +196,7 @@ const remainingRouter: AppRouteRecordRaw[] = [
   },
   {
     path: '/Navicate',
-    component: () => import('@/views/Home/Index2.vue'),
+    component: () => import('@/views/Home/index3.vue'),
     name: 'Navicate',
     meta: {
       hidden: true,

+ 35 - 3
sso-ui/sso-ui-admin-vue3/src/utils/index.ts

@@ -1,4 +1,4 @@
-import { toNumber } from 'lodash-es'
+import {toNumber} from 'lodash-es'
 
 /**
  *
@@ -215,8 +215,8 @@ export const getUrlNumberValue = (key: string, urlStr: string = location.href):
  * @param prop 字段名称
  * @param order 顺序
  */
-export const buildSortingField = ({ prop, order }) => {
-  return { field: prop, order: order === 'ascending' ? 'asc' : 'desc' }
+export const buildSortingField = ({prop, order}) => {
+  return {field: prop, order: order === 'ascending' ? 'asc' : 'desc'}
 }
 
 // ========== NumberUtils 数字方法 ==========
@@ -449,3 +449,35 @@ export function jsonParse(str: string) {
     return ''
   }
 }
+
+/**
+ * 防抖动
+ *
+ * @param {Function} fn
+ * @param {number} delay
+ * @return {*}
+ */
+export function debounce(fn: (...args: any[]) => void, delay: number = 500): (...args: any[]) => void {
+  let timer: ReturnType<typeof setTimeout> | null;
+  return function (this: any, ...args: any[]) {
+    if (timer) {
+      clearTimeout(timer);
+      timer = null;
+    }
+    timer = setTimeout(() => {
+      timer = null;
+      fn.apply(this, args);
+    }, delay);
+  };
+}
+
+
+export function clearTimer(timers: Array<ReturnType<typeof setTimeout> | null>): void {
+  timers.forEach((e, index) => {
+    if (e) {
+      clearInterval(e);
+      clearTimeout(e);
+    }
+    timers[index] = null;
+  });
+}

+ 202 - 0
sso-ui/sso-ui-admin-vue3/src/views/Home/index3.vue

@@ -0,0 +1,202 @@
+<template>
+  <ScaleContainer>
+    <div class="screen-container">
+      <div class="title"></div>
+      <div class="logout_bg">
+        <el-image style="width:40px;height:40px;margin-right: 40px" :src="manager" fit="cover"  @click="toProfile"  v-if="roles.includes('super_admin') || roles.includes('sys_admin')"/>
+        <el-image style="width:40px;height:40px;margin-right: 20px" :src="logouticon" fit="cover" @click="loginOut"/>
+      </div>
+      <div class="main">
+        <div class="col">
+          <div class="row2" style="background-color: #30CA79;">
+            <img class="image2" :src="img1"  />
+            <div class="text2"><el-link style="font-size: 30px;color: #fff; font-weight: 500" @click="handlerLink(44)">社区居家养老管理系统</el-link></div>
+          </div>
+          <div class="row2" style="background-color: #32B19E;">
+            <img class="image2" :src="img2"  />
+            <div class="text2"><el-link style="font-size: 30px;color: #fff; font-weight: 500" @click="handlerLink(43)">智慧养老IOT物联网平台</el-link></div>
+            <!--            <div class="text2"><a class="aaa" href="http://web.poteviohealth.com/boss/" target="_blank">智慧养老IOT物联网平台</a></div>-->
+          </div>
+        </div>
+        <div class="col col3" style="background-color: #00734D;">
+          <div class="text0"><el-link style="font-size: 30px;color: #fff; font-weight: 500" @click="handlerLink(45)">康养大数据平台</el-link></div>
+        </div>
+        <div class="col">
+          <div class="row2" style="background-color: #4C4B6B;">
+            <img class="image2" :src="img5"  />
+            <div class="text2"><el-link style="font-size: 30px;color: #fff; font-weight: 500" @click="handlerLink(50)">机构养老运营管理系统</el-link></div>
+          </div>
+          <div class="row2" style="background-color: #4A8EE2;">
+            <img class="image2" :src="img6"  />
+            <div class="text2"><el-link style="font-size: 30px;color: #fff; font-weight: 500" @click="handlerLink(49)">旅居养老运营管理系统</el-link></div>
+          </div>
+        </div>
+        <div class="col">
+          <div class="row2" style="background-color: #F3B144;">
+            <img class="image2" :src="img7" />
+            <div class="text2"><el-link style="font-size: 30px;color: #fff; font-weight: 500" @click="handlerLink(46)">运营数据分析平台</el-link></div>
+          </div>
+          <div class="row2" style="background-color: #AACC05;">
+            <img class="image2" :src="img8"  />
+            <div class="text2">建设中</div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </ScaleContainer>
+
+</template>
+
+<script setup lang="ts">
+import ScaleContainer from "@/components/common/ScaleContainer/index.vue";
+import manager from "@/assets/imgs/main/manager.png";
+import logouticon from "@/assets/imgs/main/logout.png";
+
+import { ElMessageBox } from 'element-plus'
+import { useUserStore } from '@/store/modules/user'
+import { useTagsViewStore } from '@/store/modules/tagsView'
+import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
+import * as UserApi from '@/api/system/user'
+import img1 from '@/assets/imgs/main/icon1.png';
+import img2 from '@/assets/imgs/main/icon2.png';
+import img3 from '@/assets/imgs/main/icon3.png';
+import img5 from '@/assets/imgs/main/icon5.png';
+import img6 from '@/assets/imgs/main/icon6.png';
+import img7 from '@/assets/imgs/main/icon7.png';
+import img8 from '@/assets/imgs/main/icon8.png';
+
+
+import * as authUtil from '@/utils/auth'
+
+const userStore = useUserStore()
+const tagsViewStore = useTagsViewStore()
+const { t } = useI18n()
+//
+const { push, replace } = useRouter()
+
+const { wsCache } = useCache()
+const loginOut = async () => {
+  try {
+    await ElMessageBox.confirm(t('common.loginOutMessage'), t('common.reminder'), {
+      confirmButtonText: t('common.ok'),
+      cancelButtonText: t('common.cancel'),
+      type: 'warning'
+    })
+    await userStore.loginOut()
+    tagsViewStore.delAllViews()
+    replace('/login?redirect=/Navicate')
+  } catch {}
+}
+const toProfile = async () => {
+  push('/system/user')
+}
+
+const handlerLink = async (id) =>{
+  try {
+    const linkUrl = await UserApi.getLinkInfo(id, authUtil.getAccessToken())
+    console.log(linkUrl)
+    if (linkUrl != "") {
+      window.open(linkUrl);
+    }
+  }catch (error) {
+    console.log(error);
+  }
+}
+const roles = wsCache.get(CACHE_KEY.USER).roles
+console.log("######################",roles)
+
+</script>
+
+<style scoped lang="scss">
+.screen-container {
+  // background: var(--app-screen-bg-color);
+  height: 100%;
+}
+
+.title{
+  width: 655px;
+  height: 62px;
+  // position: absolute;
+  // top:63px;
+  // left:113px;
+  margin-top: 63px;
+  margin-left: 113px;
+  background-image: url("/src/assets/imgs/main/logo.png");
+  background-repeat: no-repeat;
+}
+
+.logout_bg {
+  position: absolute;
+  top: 80px;
+  right: 60px;
+  width: 200px;
+  height: 50px;
+  cursor: pointer;
+}
+
+.main{
+  width: 1920px;
+  height: 600px;
+  margin-top: 115px;
+  margin-left: 130px;
+  // position: absolute;
+  // top:240px;
+  // left:130px;
+  display: flex;
+  color: #fff;
+  font-size: 32px;
+}
+
+.col{
+  width: 400px;
+  height: 600px;
+  margin-right: 10px;
+  text-decoration: none;
+}
+
+.col3{
+  background-image: url("/src/assets/imgs/main/icon0.png");
+}
+
+
+.row3{
+  width: 400px;
+  height: 190px;
+  margin-bottom: 15px;
+  display: flex;
+}
+.image3{
+  margin: 61px 24px 61px 40px;
+}
+.text3{
+  margin-top: 51px;
+}
+.row2{
+  width: 400px;
+  height: 290px;
+  margin-bottom: 20px;
+}
+.text0{
+  text-align: center;
+  margin-top: 110px;
+}
+.image2{
+  margin: 69px 160px 20px 160px;
+}
+.text2{
+  text-align: center;
+  width: 100%;
+}
+.aaa{
+  color: #fff;
+}
+
+.screen-content-container {
+  padding-top: size(var(--app-screen-header-height));
+  // padding-bottom: size(var(--app-screen-nav-height));
+  width: 100%;
+  height: 100%;
+  position: relative;
+  overflow: hidden;
+}
+</style>