init: Initialize the basic project.

This commit is contained in:
2026-01-06 09:58:29 +08:00
commit 1ab79d6f8f
1441 changed files with 129326 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
# 小诺卡片列表的组件
## 说明
### props定义
| 序号 | 编码 | 类型 | 说明 | 示例 |
|----|------------|---------|--------|------------------------|
| 1 | grid | Object | grid布局 | 见and-design定义Grid栅格 |
| 2 | dataSource | Array | 数据源 | 见dataSource字段定义 |
| 3 | page | Object | 分页 | 见page字段定义 |
| 4 | actions | Array | 操作数组 | 见action字段定义 |
| 5 | loading | Boolean | 加载中提示 | - |
> dataSource字段定义
| 序号 | 编码 | 类型 | 说明 | 示例 |
|----|----------|--------|-----------------|---------------|
| 1 | title | String | 标题 | 设备编码 |
| 2 | subTitle | String | 副标题 | 设备名称 |
| 3 | img | String | 图片 | |
| 4 | contents | Array | 内容 | 见content字段定义 |
| 5 | badge | Object | 徽标 | 见badge字段定义 |
| 6 | record | Object | 数据记录emit触发回调参数 | |
> content字段定义
| 序号 | 编码 | 类型 | 说明 | 示例 |
|----|-------|--------|----|------|
| 1 | label | String | 标签 | 所属产品 |
| 2 | value | Object | 值 | 透传 |
> badge字段定义
| 序号 | 编码 | 类型 | 说明 | 示例 |
|----|-------|--------|----|------------------------|
| 1 | text | String | 标签 | 所属产品 |
| 2 | color | String | 颜色 | 见ant-design定义预设、自定义 |
> action字段定义
| 序号 | 编码 | 类型 | 说明 | 示例 |
|----|-------|--------|----|---------|
| 1 | key | String | 键 | setting |
| 2 | label | String | 标签 | 所属产品 |
| 3 | icon | String | 图标 | setting |
| 4 | color | String | 颜色 | red |
> page字段定义
| 序号 | 编码 | 类型 | 说明 | 示例 |
|----|---------|--------|------|----|
| 1 | current | Number | 当前页 | 1 |
| 2 | size | Number | 每页大小 | 6 |
| 3 | total | Number | 总数 | 0 |
### emits定义
| 序号 | 方法名 | 参数类型 | 参数示例 |
|----|-------------|--------|-----------------------------|
| 1 | action | Object | {key: 'edit', record:{...}} |
| 2 | page-change | Number | 1 |

View File

@@ -0,0 +1,120 @@
<template>
<a-list :grid="grid" :data-source="props.dataSource" :pagination="pagination" :loading="loading">
<template #renderItem="{ item, index }">
<a-list-item :key="index" class="xn-card-list-item">
<a-badge-ribbon :text="item.badge.text" :color="item.badge.color ? item.badge.color : ''">
<a-card class="xn-card">
<template #title>
<a-tag color="orange">{{ item.title }}</a-tag>
</template>
<template #actions>
<template v-for="{ key, label, button, icon, color } in props.actions" :key="key">
<a-button v-if="button" type="link" size="small" @click.stop="doAction(key, item)">
<template #icon>
<component :is="icon" :style="{ color: color }" />
</template>
<span :style="{ color: color }">{{ label }}</span>
</a-button>
<a-tooltip v-else :title="label">
<component :is="icon" @click.stop="doAction(key, item)" :style="{ color: color }" />
</a-tooltip>
</template>
<slot name="custom-action-component" :record="item.record" />
</template>
<a-card-meta class="xn-card-meta">
<template #avatar>
<a-avatar shape="square" :size="60" :src="item.img" />
</template>
<template #title>
<span class="xn-card-meta-title">{{ item.subTitle }}</span>
</template>
<template #description>
<div v-if="item.contents">
<div v-for="content in item.contents" :key="content.value">
<span>{{ content.label }}{{ content.value }}</span>
</div>
</div>
</template>
</a-card-meta>
</a-card>
</a-badge-ribbon>
</a-list-item>
</template>
</a-list>
</template>
<script setup name="xnCardList">
import { message } from 'ant-design-vue'
const props = defineProps({
// grid布局
grid: {
type: Object,
default: () => {
return { gutter: 20, xs: 1, sm: 1, md: 2, lg: 2, xl: 3, xxl: 4, xxxl: 4 }
}
},
// 数据源
dataSource: {
type: Array,
required: true
},
// 分页
page: {
type: Object,
required: true
},
// 动作
actions: {
type: Array,
default: () => []
},
loading: {
type: Boolean,
default: false
}
})
const emit = defineEmits(['action', 'page-change'])
// 分页参数
const { current, size, total } = toRefs(props.page)
const pagination = reactive({
onChange: (current) => {
emit('page-change', current)
},
current: current,
pageSize: size,
total: total
})
// 触发 action
const doAction = (key, item) => {
if (!item.record) {
message.error('记录参数[record]错误')
return
}
emit('action', { key, record: item.record })
}
</script>
<style lang="less" scoped>
.xn-card {
background: linear-gradient(141.6deg, var(--primary-1) 0%, rgba(255, 255, 255, 0) 70%);
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
border-radius: 10px;
.xn-card-meta {
display: flex;
align-items: center;
.xn-card-meta-title {
font-size: 14px;
}
}
}
</style>
<style lang="less">
.xn-card-list-item {
padding: initial !important;
}
</style>