惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cisco Talos Blog
Cisco Talos Blog
阮一峰的网络日志
阮一峰的网络日志
云风的 BLOG
云风的 BLOG
D
Docker
Vercel News
Vercel News
IT之家
IT之家
Recent Announcements
Recent Announcements
Last Week in AI
Last Week in AI
V
Visual Studio Blog
Engineering at Meta
Engineering at Meta
腾讯CDC
Google DeepMind News
Google DeepMind News
I
InfoQ
博客园 - 三生石上(FineUI控件)
Apple Machine Learning Research
Apple Machine Learning Research
The GitHub Blog
The GitHub Blog
博客园 - Franky
The Cloudflare Blog
A
About on SuperTechFans
有赞技术团队
有赞技术团队
Y
Y Combinator Blog
T
Tenable Blog
P
Proofpoint News Feed
Recorded Future
Recorded Future
Security Latest
Security Latest
H
Hackread – Cybersecurity News, Data Breaches, AI and More
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - 聂微东
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Google Online Security Blog
Google Online Security Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Simon Willison's Weblog
Simon Willison's Weblog
The Last Watchdog
The Last Watchdog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
News and Events Feed by Topic
TaoSecurity Blog
TaoSecurity Blog
U
Unit 42
The Hacker News
The Hacker News
Martin Fowler
Martin Fowler
T
Threat Research - Cisco Blogs
NISL@THU
NISL@THU
F
Full Disclosure
M
MIT News - Artificial intelligence
人人都是产品经理
人人都是产品经理
Hugging Face - Blog
Hugging Face - Blog
V
V2EX
Project Zero
Project Zero

博客园 - abcByme

边框渐变、字体渐变 列表进度处理 路由保存参数还在当前页 菜单右侧竖条 登录记住密码浏览器默认样式修改 头像图片上传和裁切 a-table 子级异步加载 动态效果 是否第一次打开 vue3 拖动弹窗 vue3 表格下拉刷新 平均分布从左到右 从上到下 js 数据平均分配 喊话器功能 获取完整的文件路径地址 vue3 词云 树形多选 多表单验证 复选框单选
vue3 下拉刷新
abcByme · 2024-12-27 · via 博客园 - abcByme

<script setup lang="ts">

import { Empty } from 'ant-design-vue';

const props = withDefaults(defineProps<{

  modelValue: any[] // 重要: 外部在使用这个的时候,不要修改,要通过endSuccess这些方法来修改

  defaultPageSize: number

  defaultPage: number

}>(), {

  modelValue: () => [],

  defaultPageSize: 10,

  defaultPage: 1,

});

const emit = defineEmits<{

  (e: 'update:modelValue', val: any[]): void

  (e: 'load', val: { page: number, pageSize: number }): void

}>();

const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;

const dataSource = ref<any[]>([]);

const page = ref(props.defaultPage);

const pageSize = ref(props.defaultPageSize);

const noMoreData = ref(false); // 是否有更多数据

const loading = ref(false); // 是否正在加载中

let lockFlag = false; // 锁,用于保证一次加载只能调用一次回调方法

watch(() => props.modelValue, () => {

  dataSource.value = props.modelValue || [];

}, { immediate: true });

onMounted(() => {

  // dataSource.value = [];

  // page.value = props.defaultPage;

  // pageSize.value = props.defaultPageSize;

  // noMoreData.value = false;

  // loading.value = false;

  nextTick(() => {

    lockFlag = false;

    emit('load', { page: page.value, pageSize: pageSize.value });

  });

});

/**

 * 加载更多

 */

function loadMore() {

  if (noMoreData.value) {

    return;

  }

  if (loading.value) {

    return;

  }

  loading.value = true;

  lockFlag = false;

  emit('load', { page: page.value, pageSize: pageSize.value });

}

function endSuccess(data: any[]) {

  if (lockFlag) {

    return;

  }

  lockFlag = true;

  if (page.value === 1) {

    dataSource.value = data;

  }

  else {

    dataSource.value = [...dataSource.value, ...data];

  }

  if (data.length < pageSize.value) {

    noMoreData.value = true;

  }

  else {

    noMoreData.value = false;

    page.value += 1;

  }

  emit('update:modelValue', [...dataSource.value]);

  loading.value = false;

}

function endError() {

  if (lockFlag) {

    return;

  }

  lockFlag = true;

  loading.value = false;

}

function reload() {

  if (loading.value && page.value === props.defaultPage) {

    return;

  }

  dataSource.value = [];

  page.value = props.defaultPage;

  pageSize.value = props.defaultPageSize;

  noMoreData.value = false;

  loading.value = false;

  emit('update:modelValue', []);

  lockFlag = false;

  emit('load', { page: page.value, pageSize: pageSize.value });

}

defineExpose({

  endSuccess,

  endError,

  reload,

});

</script>

<template>

  <div class="loadmore-list">

    <ScrollLoad class="loadmore-list-body" @load-more="loadMore">

      <div v-if="!dataSource.length">

        <a-empty :image="simpleImage" />

      </div>

      <template v-else>

        <slot />

      </template>

    </ScrollLoad>

  </div>

</template>

<style lang="less" scoped>

.loadmore-list {

  width: 100%;

  height: 100%;

  overflow: hidden;

  .loadmore-list-body {

    width: 100%;

    height: 100%;

    // overflow: auto;

    overflow-x:hidden;

    overflow-y:auto;

  }

}

</style>

<script setup lang="ts">
import loadMoreList from '@/views/components/loadMoreList.vue';
import eventsave from "./eventsave.vue";
import { TYPE, LEVEL, STATUS, levleText, imgUrl } from './enums.ts'
const props = defineProps({
  isupdata: {
    type: Boolean,
    default: false
  }
});
watch(() => props.isupdata, () => {
  if (props.isupdata) {
    _getEventPageQuery()
  }
}, {
  deep: true
});
const list: any = ref([
])
const formpramas = ref({
  pageQueryDTO: {
    currentPage: 1,
    pageSize: 3,
    districtCode: '',
    typ: '',
    level: ''
  }
})
const loadMoreListRef = ref()
const emit = defineEmits(['detail', 'listfirst', 'leftupdata']);
function _getEventPageQuery() {
  getEventPageQuery(formpramas.value).then(res => {
    if (res.success) {
      let d = res.data?.records || [];
      if (d && d.length > 0) {
        (window as any).cMap.glowWayline.addRiskBillboard(d);
      }

      if (d && d.length) {
        d.forEach((item) => {
          item.title = levleText(item.level)
          item.imgUrl = imgUrl(item.type)
        })
        // list.value = d;
        loadMoreListRef.value.endSuccess(d);
        emit('listfirst', list.value[0])
      }
    } else {
      loadMoreListRef.value.endError();
    }
  })
}


//详情
function detail(item: any) {
  emit('detail', item)
}
//加载更多
function getList(pageConfig: { page: number, pageSize: number }) {
  formpramas.value.pageQueryDTO.currentPage = pageConfig.page;
  formpramas.value.pageQueryDTO.pageSize = pageConfig.pageSize;
  _getEventPageQuery()
}
const eventsaveRef = ref();

//应急救援告警接收
function add() {
  eventsaveRef.value.show();
}
function getsaveupdata() {
  //保存成功了
  emit('leftupdata')
}
</script>
<template>
  <div class="w-full h-full">
    <div class="tt-text" @click="add">
      <span>应急救援告警接收</span>
    </div>
    <div class="list-box h-full">
      <loadMoreList ref="loadMoreListRef" v-model="list" @load="getList" :default-page-size="3" :default-page="1">
        <div class="sub" v-for="item in list" @click="detail(item)">
          <div class="tit">
            <span class="s-text">
              <img :src="item.imgUrl" alt="">
              {{ TYPE[item.type] }}
            </span>
            <span class="s-status" :class="`color${item.level}`">
              {{ LEVEL[item.level] }}
              <a-tooltip placement="right" :title="item.title" v-if="item.level">
                <PubSvgIcon name="wenhao" size="12" class="cursor-pointer ml-0.5" />
              </a-tooltip>
            </span>
          </div>
          <div class="cont">
            <div class="cont-sub mt-[6px] justify-between">
              <div>
                关联飞行计划:
              </div>
              <div>
                <a-tooltip placement="right" :title="item.planName">
                  <span>{{ item.planName }}</span>
                </a-tooltip>
              </div>
              <div>
                <span :class="`color${item.status}`">
                  {{ STATUS[item.status] }}
                </span>
              </div>
            </div>
            <div class="cont-sub">
              <div>
                事故发生时间:
              </div>
              <div>
                {{ item.accidentTime }}
              </div>
            </div>
            <div class="cont-sub">
              <div>
                事故地点:
              </div>
              <div class="hidd-cla">
                <a-tooltip placement="right" :title="item.place">
                  <span>{{ item.place }}</span>
                </a-tooltip>
              </div>
            </div>
            <div class="cont-sub">
              <div>
                管理单位:
              </div>
              <div>
                {{ item.orgName }}
              </div>
            </div>
          </div>
        </div>
      </loadMoreList>
    </div>
    <!-- 保存应急救援告警接收 -->
    <eventsave ref="eventsaveRef" @saveupdata="getsaveupdata"></eventsave>
  </div>
</template>
<style lang="less" scoped>
.tt-text {
  position: absolute;
  right: 0;
  top: -4px;
  background: url(@/assets/images/rescue/left2-titbg.png)no-repeat center center;
  background-size: 100% 100%;
  width: 130px;
  // height: 24px;
  line-height: 24px;
  text-align: center;
  cursor: pointer;

  span {

    font-family: youshe;
    font-size: 14px;
    color: #FFFFFF;
    text-align: center;
    text-shadow: 0 0 8px #46B5FF;
  }
}

.list-box {
  overflow-y: auto;
  overflow-x: hidden;
  // overflow: hidden;

  .sub {
    padding: 10px 10px 12px 16px;
    background: url(@/assets/images/rescue/left2-listsub-bg.png)no-repeat center center;
    background-size: 100% 100%;
    width: 344px;
    height: 158px;
    margin-bottom: 9px;
    cursor: pointer;

    .tit {
      display: flex;
      justify-content: space-between;
      height: 21px;

      .s-text {
        display: flex;
        align-items: center;

        img {
          width: 15px;
          height: 15px;
          margin-right: 5px;
        }

        font-family: youshe;
        font-size: 16px;
        color: #FFFFFF;
        text-shadow: 0 2px 4px #21538480;
      }

      .s-status {
        font-family: PingFangSC-Regular;
        font-weight: 400;
        font-size: 12px;
        color: #FFFFFF;
        text-align: center;
        display: flex;
        width: 50px;
        height: 20px;
        border-radius: 4px;
        align-items: center;
        justify-content: center;

        &.color1 {
          background-image: radial-gradient(circle at 13% 20%, #93ffec99 0%, #39f1ff00 38%), linear-gradient(248deg, #4decff1a 0%, #00efffcc 100%);
          box-shadow: inset 6px -6px 8px 0 #40fff652;
        }

        &.color2 {
          background-image: radial-gradient(circle at 13% 20%, #FFD293 0%, #ffa83900 38%), linear-gradient(248deg, #ff9b4d1a 0%, #FF9600 100%);
          box-shadow: inset 6px -6px 8px 0 #ff404052;
        }

        &.color3 {

          background-image: radial-gradient(circle at 13% 20%, #FF9393 0%, #ff393900 38%), linear-gradient(248deg, #ff4d4d1a 0%, #D70000 100%);
          box-shadow: inset 6px -6px 8px 0 #ff404052;
        }
      }
    }

    .cont {
      height: 112px;

      .cont-sub {
        display: flex;
        font-family: PingFangSC-Regular;
        font-weight: 400;
        font-size: 14px;
        margin-bottom: 4px;
        // height: 20px;
        line-height: 20px;
        // justify-content: space-between;

        div:nth-of-type(1) {
          // width: 98px;
          color: #F7F7F7;
        }

        div:nth-of-type(2) {
          width: 160px;
          color: #ffffffb3;
          display: -webkit-box;
          -webkit-box-orient: vertical;
          -webkit-line-clamp: 2;
          overflow: hidden;
          text-overflow: ellipsis;
        }

        div:nth-of-type(3) {
          span {
            font-family: PingFangSC-Regular;
            font-weight: 400;
            font-size: 12px;
            color: #FFFFFF;
            text-align: center;
            display: flex;
            width: 50px;
            height: 20px;
            border-radius: 4px;
            align-items: center;
            justify-content: center;

            &.color1 {

              background-image: radial-gradient(circle at 13% 20%, #FF9393 0%, #ff393900 38%), linear-gradient(248deg, #ff4d4d1a 0%, #D70000 100%);
              box-shadow: inset 6px -6px 8px 0 #ff404052;
            }

            &.color2 {
              background-image: radial-gradient(circle at 13% 20%, #FFD293 0%, #ffa83900 38%), linear-gradient(248deg, #ff9b4d1a 0%, #FF9600 100%);
              box-shadow: inset 6px -6px 8px 0 #ff404052;
            }

            &.color3 {

              background-image: radial-gradient(circle at 13% 20%, #93ffec99 0%, #39f1ff00 38%), linear-gradient(248deg, #4decff1a 0%, #00efffcc 100%);
              box-shadow: inset 6px -6px 8px 0 #40fff652;
            }
          }
        }

        .hidd-cla {
          width: 180px !important;
          -webkit-line-clamp: 1 !important;
        }
      }
    }
  }
}
</style>