Browse Source

分页布局模拟

CzRger 7 months ago
parent
commit
1420417257

+ 94 - 0
src/components/cus/CusEllipsis.vue

@@ -0,0 +1,94 @@
+<template>
+  <div class="cus-ellipsis" ref="ref_main">
+    <template v-if="html">
+      <div class="cus-ellipsis-temp" ref="ref_temp" v-html="value"/>
+    </template>
+    <template v-else>
+      <div class="cus-ellipsis-temp" ref="ref_temp">{{value}}</div>
+    </template>
+    <template v-if="html">
+      <el-tooltip
+        :disabled="!isEllipsis"
+        :content="String(value)"
+        raw-content
+        placement="top"
+        popper-class="__cus-popover"
+      >
+        <div class="__text-ellipsis" v-html="value"/>
+      </el-tooltip>
+    </template>
+    <template v-else>
+      <el-tooltip
+        :disabled="!isEllipsis"
+        :content="String(value)"
+        placement="top"
+        popper-class="__cus-popover"
+      >
+        <div class="__text-ellipsis">{{value}}</div>
+      </el-tooltip>
+    </template>
+  </div>
+</template>
+
+<script lang="ts">
+import {
+  defineComponent,
+  computed,
+  onMounted,
+  ref,
+  reactive,
+  watch,
+  getCurrentInstance,
+  ComponentInternalInstance,
+  toRefs,
+  nextTick
+} from 'vue'
+import {useRouter, useRoute} from 'vue-router'
+
+export default defineComponent({
+  name: 'CusEllipsis',
+  components: {},
+  props: {
+    value: {
+      required: true,
+      default: '',
+    },
+    always: {default: false},
+    html: {default: false}
+  },
+  setup(props) {
+    const router = useRouter();
+    const route = useRoute();
+    const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties
+    const state = reactive({
+      isEllipsis: false
+    })
+    const ref_main = ref()
+    const ref_temp = ref()
+    watch(() => props.value, (n) => {
+      if (n) {
+        nextTick(() => {
+          state.isEllipsis = props.always || ref_temp.value?.clientWidth > ref_main.value?.clientWidth
+        })
+      }
+    }, {immediate: true})
+    return {
+      ...toRefs(state),
+      ref_main,
+      ref_temp
+    }
+  },
+})
+</script>
+
+<style scoped lang="scss">
+  .cus-ellipsis {
+    width: 100%;
+    .cus-ellipsis-temp {
+      word-break: break-all;
+      white-space: nowrap;
+      position: absolute;
+      visibility: hidden;
+    }
+  }
+</style>

+ 2 - 33
src/components/cus/CusTab.vue

@@ -82,43 +82,12 @@ export default defineComponent({
       .cus-tab-item {
         padding: 0 4px;
         &.active {
-          color: #0062E9;
+          color: var(--cus-main-color);
           &:after {
             width: 100%;
             height: 2px;
             bottom: -1px;
-            background-color: #0062E9;
-          }
-        }
-      }
-    }
-    &.cus-tab-type3 {
-      height: 36px;
-      display: flex;
-      gap: 16px;
-      border-bottom: none;
-      .cus-tab-item {
-        display: flex;
-        flex-direction: column;
-        align-items: center;
-        justify-content: center;
-        font-family: PingFang SC, PingFang SC;
-        font-weight: 500;
-        font-size: 14px;
-        color: #FFFFFF;
-        margin-right: 0;
-        &:after {
-          margin-top: 6px;
-          content: '';
-          width: 100%;
-          height: 3px;
-          border-radius: 2px;
-          position: unset;
-        }
-        &.active {
-          color: #1CFEFF;
-          &:after {
-            background-color: #1CFEFF;
+            background-color: var(--cus-main-color);
           }
         }
       }

+ 6 - 1
src/router/index.ts

@@ -24,6 +24,9 @@ const router = createRouter({
 
 router.beforeEach((to, from , next) => {
     const AppStore = useAppStore()
+    if (themeConfig && !AppStore.theme.init) {
+        AppStore.setTheme(themeConfig)
+    }
     if (userInfo) {
         if (!AppStore.userInfo) {
             AppStore.$patch((state) => {
@@ -33,7 +36,7 @@ router.beforeEach((to, from , next) => {
         if (to.query.routeTitle) {
             to.meta.title = to.query.routeTitle
         }
-        document.title = to.meta?.title || import.meta.env.VITE_TITLE
+        document.title = to.meta?.title || AppStore.theme.title || import.meta.env.VITE_TITLE
         next()
     } else if (to.path === '/login') {
         next()
@@ -43,6 +46,7 @@ router.beforeEach((to, from , next) => {
     }
 })
 let userInfo = null
+let themeConfig = null
 export const initMainRouter = async () => {
     if (localStorage.getItem('ss_token')) {
         const loading = ElLoading.service({
@@ -60,6 +64,7 @@ export const initMainRouter = async () => {
                 router.addRoute(manageRouter)
             }
             loading.close()
+            themeConfig = config.data
             initRootVar(config.data)
         })
     } else if (location.pathname !== '/login') {

+ 12 - 0
src/stores/app.ts

@@ -6,9 +6,21 @@ export const useAppStore = defineStore('app', {
   state: () => ({
     token: localStorage.getItem('ss_token'),
     userInfo: null,
+    theme: {
+      init: false,
+      title: '智慧搜索平台',
+      subTitle: '',
+      logo: ''
+    }
   }),
   getters: {
   },
   actions: {
+    setTheme(config) {
+      this.theme.init = true
+      this.theme.title = config.title
+      this.theme.subTitle = config.subTitle
+      this.theme.logo = config.logo
+    }
   },
 })

+ 18 - 20
src/style/cus.scss

@@ -5,6 +5,7 @@
   --cus-text-color-2: #606266;
   --cus-text-color-3: #909399;
   --cus-text-color-4: #C0C4CC;
+  --el-color-primary: var(--cus-main-color) !important;
 }
 
 .__hover {
@@ -14,6 +15,23 @@
   }
 }
 
+.__text-ellipsis {
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  word-break: break-all;
+  &.el-link {
+    max-width: 100%;
+    .el-link__inner {
+      display: unset;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      word-break: break-all;
+    }
+  }
+}
+
 .__tooltip {
   position: relative;
   background-color: #f9f9f9;
@@ -187,23 +205,3 @@
     }
   }
 }
-
-.el-pagination {
-  .el-pager {
-    .is-active, >li:hover {
-      color: var(--cus-main-color);
-    }
-  }
-  .btn-prev, .btn-next {
-    &:hover {
-      color: var(--cus-main-color);
-    }
-  }
-}
-.el-input__wrapper.is-focus,
-.el-select__wrapper.is-focused {
-  box-shadow: 0 0 0 1px var(--cus-main-color) inset !important;
-}
-.el-select-dropdown__item.is-selected {
-  color: var(--cus-main-color) !important;
-}

+ 1 - 0
src/style/index.scss

@@ -15,6 +15,7 @@ html, body, #app {
   border: 0;
   width: 100%;
   height: 100%;
+  overflow: hidden;
 }
 
 .tox-silver-sink {

+ 204 - 129
src/views/web/list/index.vue

@@ -1,6 +1,15 @@
 <template>
   <div class="list">
     <div class="list-head">
+      <div class="list-head-logo">
+        <template v-if="AppStore.theme.logo">
+          <img class="logo" :src="AppStore.theme.logo"/>
+        </template>
+        <div class="title">
+          <div class="main-title">{{AppStore.theme.title}}</div>
+          <div class="sub-title" v-if="AppStore.theme.subTitle">{{AppStore.theme.subTitle}}</div>
+        </div>
+      </div>
       <div class="list-head-search">
         <div class="left-select __hover" @click.stop="ref_area.togglePopperVisible(true)">
           搜索范围<SvgIcon name="arrow_1" rotate="90" size="14" color="var(--cus-text-color-3)"/>
@@ -92,24 +101,30 @@
                 </div>
               </div>
               <div class="info">
-                <img src="@/assets/images/web/wen-list_table-head-icon-2.png"/>
-                <div>
-                  <div>数据共享来源</div>
-                  <div>{{ state.resultParams.indexConfig?.dataShareSource }}</div>
+                <div class="block">
+                  <img src="@/assets/images/web/wen-list_table-head-icon-2.png"/>
+                  <div class="text">
+                    <div class="text-title">数据共享来源</div>
+                    <div class="text-value"><CusEllipsis :value="state.resultParams.indexConfig?.dataShareSource"/></div>
+                  </div>
                 </div>
               </div>
               <div class="info">
-                <img src="@/assets/images/web/wen-list_table-head-icon-3.png"/>
-                <div>
-                  <div>数据提供来源</div>
-                  <div>{{ state.resultParams.indexConfig?.dataProvideSource }}</div>
+                <div class="block">
+                  <img src="@/assets/images/web/wen-list_table-head-icon-3.png"/>
+                  <div class="text">
+                    <div class="text-title">数据提供来源</div>
+                    <div class="text-value"><CusEllipsis :value="state.resultParams.indexConfig?.dataProvideSource"/></div>
+                  </div>
                 </div>
               </div>
               <div class="info">
-                <img src="@/assets/images/web/wen-list_table-head-icon-4.png"/>
-                <div>
-                  <div>数据量</div>
-                  <div>{{ state.resultParams.indexConfig?.dataTotal }}<span>条</span></div>
+                <div class="block">
+                  <img src="@/assets/images/web/wen-list_table-head-icon-4.png"/>
+                  <div class="text">
+                    <div class="text-title">数据量</div>
+                    <div class="text-value"><CusEllipsis :value="(state.resultParams.indexConfig?.dataTotal || 0) + '条'"/></div>
+                  </div>
                 </div>
               </div>
             </div>
@@ -136,7 +151,9 @@
                           gridColumn: `span ${c.col}`
                         }">
                           <div class="cols-item-label">{{c.key}}:</div>
-                          <div class="cols-item-value" v-html="item[c.value]"/>
+                          <div class="cols-item-value">
+                            <CusEllipsis :value="item[c.value]" :html="true"/>
+                          </div>
                         </div>
                       </template>
                     </div>
@@ -155,41 +172,47 @@
                 gridTemplateColumns: `repeat(${tableConfigCpt.cardLayout}, 1fr)`
               }">
                 <template v-for="(item, index) in state.tableParams.data">
-                  <div class="card-item __hover">
-                    <div class="main-row">
-                      <template v-if="tableConfigCpt?.cardImg.value">
-                        <div class="main-row-img">
-                          <el-image
-                            :src="item[tableConfigCpt?.cardImg.value]"
-                            :zoom-rate="1.2"
-                            :max-scale="7"
-                            :min-scale="0.2"
-                            :preview-src-list="[item[tableConfigCpt?.cardImg.value]]"
-                            :preview-teleported="true"
-                          />
-                        </div>
-                      </template>
-                      <div class="main-row-param" v-html="item[tableConfigCpt.cardMain.value]"/>
-                      <div class="main-row-operation">
-                        <div class="__hover">
-                          <SvgIcon name="detail_1" color="var(--cus-main-color)"/>详情
+                  <div class="card-block">
+                    <div class="card-item __hover">
+                      <div class="main-row">
+                        <template v-if="tableConfigCpt?.cardImg.value">
+                          <div class="main-row-img">
+                            <el-image
+                              :src="item[tableConfigCpt?.cardImg.value]"
+                              :zoom-rate="1.2"
+                              :max-scale="7"
+                              :min-scale="0.2"
+                              :preview-src-list="[item[tableConfigCpt?.cardImg.value]]"
+                              :preview-teleported="true"
+                            />
+                          </div>
+                        </template>
+                        <div class="main-row-param">
+                          <CusEllipsis :value="item[tableConfigCpt.cardMain.value]" :html="true"/>
                         </div>
-                        <div class="__hover">
-                          <SvgIcon name="archives_1" color="var(--cus-main-color)"/>档案
+                        <div class="main-row-operation">
+                          <div class="__hover">
+                            <SvgIcon name="detail_1" color="var(--cus-main-color)"/>详情
+                          </div>
+                          <div class="__hover">
+                            <SvgIcon name="archives_1" color="var(--cus-main-color)"/>档案
+                          </div>
                         </div>
                       </div>
-                    </div>
-                    <div class="cols" :style="{
+                      <div class="cols" :style="{
                       gridTemplateColumns: `repeat(${tableConfigCpt.cardCol}, 1fr)`
                     }">
-                      <template v-for="c in tableConfigCpt.cardConfig">
-                        <div class="cols-item" :style="{
+                        <template v-for="c in tableConfigCpt.cardConfig">
+                          <div class="cols-item" :style="{
                           gridColumn: `span ${c.col}`
                         }">
-                          <div class="cols-item-label">{{c.key}}:</div>
-                          <div class="cols-item-value" v-html="item[c.value]"/>
-                        </div>
-                      </template>
+                            <div class="cols-item-label">{{c.key}}:</div>
+                            <div class="cols-item-value">
+                              <CusEllipsis :value="item[c.value]" :html="true"/>
+                            </div>
+                          </div>
+                        </template>
+                      </div>
                     </div>
                   </div>
                 </template>
@@ -213,10 +236,11 @@
 <script setup lang="ts">
 import {computed, getCurrentInstance, onBeforeMount, onMounted, reactive, ref, watch} from "vue";
 import {useRoute, useRouter} from "vue-router";
-import {useWebStore} from "@/stores";
+import {useAppStore, useWebStore} from "@/stores";
 import {ElLoading} from "element-plus";
 
 const {proxy} = getCurrentInstance()
+const AppStore = useAppStore()
 const WebStore = useWebStore()
 const route = useRoute()
 const router = useRouter()
@@ -278,7 +302,7 @@ const tableConfigCpt = computed(() => {
   return {
     listCol: 5,
     listConfig: [
-      {key: '姓名', value: 'name', col: 3},
+      {key: '姓名', value: 'name', col: 1},
       {key: '性别', value: 'sex', col: 1},
       {key: '出生日期', value: 'a', col: 1},
       {key: '出生日期1', value: 'a', col: 1},
@@ -368,7 +392,7 @@ const getIndexConfig = () => {
       createTime: '2024-09-09 14:20:20',
       shareMethod: '数据库表',
       updateCycle: 'T+1',
-      dataShareSource: '海南省大数据管理局',
+      dataShareSource: '海南省大数据管理局1、海南省大数据管理局2、海南省大数据管理局3',
       dataProvideSource: '海南省大数据管理局',
       dataTotal: '9125815819',
     }
@@ -459,7 +483,7 @@ onMounted(() => {
         }
         if (init) {
           state.tableParams = {
-            model: 'list',
+            model: 'card',
             pageNum: 1,
             pageSize: 10,
             total: 0,
@@ -570,6 +594,31 @@ onMounted(() => {
     width: 100%;
     height: 72px;
     background-color: #FFFFFF;
+    .list-head-logo {
+      display: flex;
+      align-items: center;
+      margin-left: 24px;
+      .logo {
+        width: 40px;
+        height: 40px;
+      }
+      .title {
+        margin-left: 10px;
+        display: flex;
+        flex-direction: column;
+        gap: 2px;
+        .main-title {
+          font-weight: bold;
+          font-size: 24px;
+          color: var(--cus-text-color-1);
+        }
+        .sub-title {
+          font-weight: 400;
+          font-size: 10px;
+          color: var(--cus-text-color-3);
+        }
+      }
+    }
     .list-head-search {
       margin-left: auto;
       width: 800px;
@@ -608,7 +657,7 @@ onMounted(() => {
         font-size: 18px;
         color: var(--cus-text-color-2);
         .el-input__wrapper {
-          box-shadow: none;
+          box-shadow: none !important;
           background-color: transparent;
           .el-input__inner {
             &::placeholder {
@@ -775,6 +824,7 @@ onMounted(() => {
         display: flex;
         flex-direction: column;
         flex: 1;
+        overflow: hidden;
         .table-head {
           width: 100%;
           height: 162px;
@@ -805,10 +855,10 @@ onMounted(() => {
             gap: 10px;
             .main {
               height: 92px;
-              width: 455px;
+              min-width: 455px;
               display: flex;
               align-items: center;
-              background: linear-gradient( 90deg, rgba(var(--cus-main-color-rgb),0.3) 0%, rgba(var(--cus-main-color-rgb),0.2) 100%);
+              background: linear-gradient( 90deg, rgba(var(--cus-main-color-rgb),0.2) 0%, rgba(var(--cus-main-color-rgb),0.15) 100%);
               font-weight: 400;
               font-size: 12px;
               position: relative;
@@ -847,44 +897,56 @@ onMounted(() => {
               }
             }
             .info {
+              height: 100%;
               flex: 1;
-              height: 70px;
-              background: linear-gradient( 90deg, rgba(var(--cus-main-color-rgb),0.3) 0%, rgba(var(--cus-main-color-rgb),0.2) 100%);
-              position: relative;
-              &:before {
-                content: '';
-                background-image: url("@/assets/images/web/wen-list_table-head-bg-1.png");
-                background-repeat: no-repeat;
-                background-size: 100% 100%;
-                position: absolute;
+              overflow: hidden;
+              display: flex;
+              align-items: flex-end;
+              .block {
                 width: 100%;
-                height: 100%;
-                z-index: 1;
-              }
-              >* {
-                z-index: 2;
-              }
-              >img {
-                position: absolute;
-                bottom: 0;
-                left: 20px;
-              }
-              >div {
-                margin-left: 144px;
-                margin-top: 14px;
-                position: inherit;
-                >div:nth-child(1) {
-                  font-weight: 400;
-                  font-size: 14px;
-                  color: var(--cus-text-color-2);
+                height: 70px;
+                background: linear-gradient( 90deg, rgba(var(--cus-main-color-rgb),0.2) 0%, rgba(var(--cus-main-color-rgb),0.15) 100%);
+                position: relative;
+                display: grid;
+                &:before {
+                  content: '';
+                  background-image: url("@/assets/images/web/wen-list_table-head-bg-1.png");
+                  background-repeat: no-repeat;
+                  background-size: 100% 100%;
+                  position: absolute;
+                  width: 100%;
+                  height: 100%;
+                  z-index: 1;
+                }
+                >* {
+                  z-index: 2;
+                }
+                >img {
+                  position: absolute;
+                  bottom: 0;
+                  left: 20px;
                 }
-                >div:nth-child(2) {
-                  margin-top: 4px;
-                  font-weight: 500;
-                  font-size: 16px;
-                  color: var(--cus-main-color);
-                  >span {
-                    font-size: 12px;
+                .text {
+                  margin-left: 144px;
+                  margin-top: 14px;
+                  position: inherit;
+                  width: calc(100% - 144px);
+                  overflow: hidden;
+                  .text-title {
+                    width: 100%;
+                    font-weight: 400;
+                    font-size: 14px;
+                    color: var(--cus-text-color-2);
+                  }
+                  .text-value {
+                    width: 100%;
+                    margin-top: 4px;
+                    font-weight: 500;
+                    font-size: 16px;
+                    color: var(--cus-main-color);
+                    >span {
+                      font-size: 12px;
+                    }
                   }
                 }
               }
@@ -952,11 +1014,14 @@ onMounted(() => {
                   row-gap: 4px;
                   .cols-item {
                     display: flex;
+                    overflow: hidden;
                     .cols-item-label {
                       color: var(--cus-text-color-1);
                       font-weight: bold;
                     }
                     .cols-item-value {
+                      flex: 1;
+                      overflow: hidden;
                       color: var(--cus-text-color-2);
                     }
                   }
@@ -983,62 +1048,72 @@ onMounted(() => {
               display: grid;
               overflow-y: auto;
               gap: 16px;
-              .card-item {
-                padding: 16px;
-                background: linear-gradient( 180deg, rgba(var(--cus-main-color-rgb), 0.1) 0%, rgba(var(--cus-main-color-rgb),0) 100%), #FFFFFF;
+              padding-bottom: 4px;
+              padding-right: 4px;
+              .card-block {
+                overflow: hidden;
+                height: max-content;
                 box-shadow: 0px 2px 4px 0px rgba(var(--cus-main-color-rgb),0.2);
-                border-radius: 4px;
-                .main-row {
-                  display: flex;
-                  align-items: center;
-                  .main-row-img {
-                    width: 40px;
-                    height: 40px;
-                    border-radius: 4px;
-                    margin-right: 10px;
-                    .el-image {
-                      width: 100%;
-                      height: 100%;
-                      >img {
+                .card-item {
+                  padding: 16px;
+                  background: linear-gradient( 180deg, rgba(var(--cus-main-color-rgb), 0.1) 0%, rgba(var(--cus-main-color-rgb),0) 100%), #FFFFFF;
+                  border-radius: 4px;
+                  .main-row {
+                    display: flex;
+                    align-items: center;
+                    .main-row-img {
+                      width: 40px;
+                      height: 40px;
+                      border-radius: 4px;
+                      margin-right: 10px;
+                      .el-image {
                         width: 100%;
                         height: 100%;
+                        >img {
+                          width: 100%;
+                          height: 100%;
+                        }
                       }
                     }
-                  }
-                  .main-row-param {
-                    font-size: 20px;
-                    color: var(--cus-text-color-1);
-                    font-weight: bold;
-                  }
-                  .main-row-operation {
-                    display: flex;
-                    align-items: center;
-                    gap: 10px;
-                    font-size: 14px;
-                    color: var(--cus-text-color-2);
-                    margin-left: auto;
-                    >div {
+                    .main-row-param {
+                      flex: 1;
+                      font-size: 20px;
+                      color: var(--cus-text-color-1);
+                      font-weight: bold;
+                      overflow: hidden;
+                    }
+                    .main-row-operation {
                       display: flex;
                       align-items: center;
-                      .svg-icon {
-                        margin-right: 2px;
+                      gap: 10px;
+                      font-size: 14px;
+                      color: var(--cus-text-color-2);
+                      margin-left: auto;
+                      >div {
+                        display: flex;
+                        align-items: center;
+                        .svg-icon {
+                          margin-right: 2px;
+                        }
                       }
                     }
                   }
-                }
-                .cols {
-                  flex: 1;
-                  display: grid;
-                  row-gap: 4px;
-                  font-size: 14px;
-                  .cols-item {
-                    display: flex;
-                    .cols-item-label {
-                      color: var(--cus-text-color-1);
-                      font-weight: bold;
-                    }
-                    .cols-item-value {
-                      color: var(--cus-text-color-2);
+                  .cols {
+                    display: grid;
+                    row-gap: 4px;
+                    font-size: 14px;
+                    .cols-item {
+                      display: flex;
+                      overflow: hidden;
+                      .cols-item-label {
+                        color: var(--cus-text-color-1);
+                        font-weight: bold;
+                      }
+                      .cols-item-value {
+                        flex: 1;
+                        overflow: hidden;
+                        color: var(--cus-text-color-2);
+                      }
                     }
                   }
                 }