hookehuyr

feat(list): 新增资料列表操作组件并统一页面样式

- 新增 ListItemActions 组件,支持查看、收藏、删除操作
- 修复资料列表页布局问题(图标和文字水平排列)
- 统一首页和资料列表页的资料项样式和交互
- 更新收藏页、知识库页、计划页使用新组件
- 添加完整的组件文档和类型定义

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
...@@ -10,14 +10,10 @@ declare module 'vue' { ...@@ -10,14 +10,10 @@ declare module 'vue' {
10 DocumentPreview: typeof import('./src/components/DocumentPreview/index.vue')['default'] 10 DocumentPreview: typeof import('./src/components/DocumentPreview/index.vue')['default']
11 IconFont: typeof import('./src/components/IconFont.vue')['default'] 11 IconFont: typeof import('./src/components/IconFont.vue')['default']
12 IndexNav: typeof import('./src/components/indexNav.vue')['default'] 12 IndexNav: typeof import('./src/components/indexNav.vue')['default']
13 + ListItemActions: typeof import('./src/components/ListItemActions/index.vue')['default']
13 NavHeader: typeof import('./src/components/NavHeader.vue')['default'] 14 NavHeader: typeof import('./src/components/NavHeader.vue')['default']
14 NutAvatar: typeof import('@nutui/nutui-taro')['Avatar'] 15 NutAvatar: typeof import('@nutui/nutui-taro')['Avatar']
15 NutButton: typeof import('@nutui/nutui-taro')['Button'] 16 NutButton: typeof import('@nutui/nutui-taro')['Button']
16 - NutCheckbox: typeof import('@nutui/nutui-taro')['Checkbox']
17 - NutCheckboxGroup: typeof import('@nutui/nutui-taro')['CheckboxGroup']
18 - NutForm: typeof import('@nutui/nutui-taro')['Form']
19 - NutFormItem: typeof import('@nutui/nutui-taro')['FormItem']
20 - NutIcon: typeof import('@nutui/nutui-taro')['Icon']
21 NutInput: typeof import('@nutui/nutui-taro')['Input'] 17 NutInput: typeof import('@nutui/nutui-taro')['Input']
22 NutPicker: typeof import('@nutui/nutui-taro')['Picker'] 18 NutPicker: typeof import('@nutui/nutui-taro')['Picker']
23 NutPopup: typeof import('@nutui/nutui-taro')['Popup'] 19 NutPopup: typeof import('@nutui/nutui-taro')['Popup']
...@@ -26,7 +22,6 @@ declare module 'vue' { ...@@ -26,7 +22,6 @@ declare module 'vue' {
26 NutSearchbar: typeof import('@nutui/nutui-taro')['Searchbar'] 22 NutSearchbar: typeof import('@nutui/nutui-taro')['Searchbar']
27 NutTabPane: typeof import('@nutui/nutui-taro')['TabPane'] 23 NutTabPane: typeof import('@nutui/nutui-taro')['TabPane']
28 NutTabs: typeof import('@nutui/nutui-taro')['Tabs'] 24 NutTabs: typeof import('@nutui/nutui-taro')['Tabs']
29 - NutTextarea: typeof import('@nutui/nutui-taro')['Textarea']
30 NutUploader: typeof import('@nutui/nutui-taro')['Uploader'] 25 NutUploader: typeof import('@nutui/nutui-taro')['Uploader']
31 OfficeViewer: typeof import('./src/components/OfficeViewer.vue')['default'] 26 OfficeViewer: typeof import('./src/components/OfficeViewer.vue')['default']
32 PdfPreview: typeof import('./src/components/PdfPreview.vue')['default'] 27 PdfPreview: typeof import('./src/components/PdfPreview.vue')['default']
......
1 +<!--
2 + 列表项操作按钮组件
3 +
4 + @description 统一的列表项操作按钮组件,支持查看、收藏、删除三种操作
5 + @example
6 + <ListItemActions
7 + :viewable="true"
8 + :collectable="true"
9 + :deletable="true"
10 + :collected="item.collected"
11 + @view="onView(item)"
12 + @collect="onCollect(item)"
13 + @delete="onDelete(item)"
14 + />
15 +-->
16 +<template>
17 + <view class="flex justify-end gap-[24rpx]">
18 + <!-- 查看按钮 -->
19 + <view v-if="viewable" class="flex items-center text-blue-600" @tap="handleView">
20 + <IconFont name="eye" size="14" class="mr-[8rpx]" />
21 + <text class="text-[24rpx]">查看</text>
22 + </view>
23 +
24 + <!-- 收藏按钮 -->
25 + <view v-if="collectable" class="flex items-center" :class="isCollected ? 'text-red-500' : 'text-gray-400'" @tap="handleCollect">
26 + <IconFont :name="isCollected ? 'heart-fill' : 'heart'" size="14" class="mr-[8rpx]" />
27 + <text class="text-[24rpx]">{{ isCollected ? '已收藏' : '收藏' }}</text>
28 + </view>
29 +
30 + <!-- 删除按钮 -->
31 + <view v-if="deletable" class="flex items-center text-red-500" @tap="handleDelete">
32 + <IconFont name="del" size="14" class="mr-[8rpx]" />
33 + <text class="text-[24rpx]">删除</text>
34 + </view>
35 + </view>
36 +</template>
37 +
38 +<script setup>
39 +import { computed } from 'vue'
40 +import IconFont from '@/components/IconFont.vue'
41 +
42 +/**
43 + * 组件属性
44 + */
45 +const props = defineProps({
46 + /**
47 + * 是否显示查看按钮
48 + * @type {boolean}
49 + * @default true
50 + */
51 + viewable: {
52 + type: Boolean,
53 + default: true
54 + },
55 + /**
56 + * 是否显示收藏按钮
57 + * @type {boolean}
58 + * @default false
59 + */
60 + collectable: {
61 + type: Boolean,
62 + default: false
63 + },
64 + /**
65 + * 是否显示删除按钮
66 + * @type {boolean}
67 + * @default false
68 + */
69 + deletable: {
70 + type: Boolean,
71 + default: false
72 + },
73 + /**
74 + * 是否已收藏
75 + * @type {boolean}
76 + * @default false
77 + */
78 + collected: {
79 + type: Boolean,
80 + default: false
81 + }
82 +})
83 +
84 +/**
85 + * 组件事件
86 + */
87 +const emit = defineEmits({
88 + /**
89 + * 点击查看按钮时触发
90 + */
91 + view: null,
92 + /**
93 + * 点击收藏按钮时触发
94 + */
95 + collect: null,
96 + /**
97 + * 点击删除按钮时触发
98 + */
99 + delete: null
100 +})
101 +
102 +const isCollected = computed(() => props.collected)
103 +
104 +/**
105 + * 处理查看点击
106 + */
107 +const handleView = () => {
108 + emit('view')
109 +}
110 +
111 +/**
112 + * 处理收藏点击
113 + */
114 +const handleCollect = () => {
115 + emit('collect')
116 +}
117 +
118 +/**
119 + * 处理删除点击
120 + */
121 +const handleDelete = () => {
122 + emit('delete')
123 +}
124 +</script>
125 +
126 +<style lang="less" scoped>
127 +</style>
...@@ -43,16 +43,12 @@ ...@@ -43,16 +43,12 @@
43 <view class="h-[1rpx] bg-gray-100 mb-[20rpx]"></view> 43 <view class="h-[1rpx] bg-gray-100 mb-[20rpx]"></view>
44 44
45 <!-- Actions --> 45 <!-- Actions -->
46 - <view class="flex justify-end gap-[24rpx]"> 46 + <ListItemActions
47 - <view class="flex items-center text-blue-600" @tap="viewFile({...item, fileName: item.title})"> 47 + :viewable="true"
48 - <IconFont name="eye" size="14" class="mr-[8rpx]" /> 48 + :deletable="true"
49 - <text class="text-[24rpx]">查看</text> 49 + @view="viewFile({...item, fileName: item.title})"
50 - </view> 50 + @delete="onDelete(item)"
51 - <view class="flex items-center text-red-500" @tap="onDelete(item)"> 51 + />
52 - <IconFont name="del" size="14" class="mr-[8rpx]" />
53 - <text class="text-[24rpx]">删除</text>
54 - </view>
55 - </view>
56 </view> 52 </view>
57 53
58 <!-- Empty State --> 54 <!-- Empty State -->
...@@ -77,6 +73,7 @@ import { getDocumentIcon } from '@/utils/documentIcons' ...@@ -77,6 +73,7 @@ import { getDocumentIcon } from '@/utils/documentIcons'
77 import IconFont from '@/components/IconFont.vue' 73 import IconFont from '@/components/IconFont.vue'
78 import TabBar from '@/components/TabBar.vue' 74 import TabBar from '@/components/TabBar.vue'
79 import NavHeader from '@/components/NavHeader.vue' 75 import NavHeader from '@/components/NavHeader.vue'
76 +import ListItemActions from '@/components/ListItemActions/index.vue'
80 77
81 const go = useGo() 78 const go = useGo()
82 const { viewFile } = useFileOperation() 79 const { viewFile } = useFileOperation()
......
...@@ -126,61 +126,40 @@ ...@@ -126,61 +126,40 @@
126 </view> 126 </view>
127 127
128 <!-- Material List --> 128 <!-- Material List -->
129 - <view class="flex flex-col gap-[32rpx]"> 129 + <view class="flex flex-col gap-[24rpx]">
130 - <!-- Item 1 --> 130 + <!-- Material Items -->
131 - <view class="flex gap-[24rpx]" @tap="handleMaterialClick(hotMaterials[0])"> 131 + <view v-for="(item, index) in hotMaterials" :key="index"
132 - <view class="w-[80rpx] h-[88rpx] flex-shrink-0 flex items-center justify-center bg-blue-50 rounded-[12rpx]"> 132 + class="flex flex-row bg-white rounded-[24rpx] p-[24rpx] border border-gray-50">
133 - <image :src="getDocumentIcon(hotMaterials[0].fileName)" class="w-[48rpx] h-[48rpx]" mode="aspectFit" /> 133 +
134 - </view> 134 + <!-- 左侧图标 -->
135 - <view class="flex-1 flex flex-col justify-between py-[4rpx]"> 135 + <view class="w-[88rpx] h-[88rpx] mr-[24rpx] flex-shrink-0 flex items-center justify-center bg-gradient-to-br from-blue-50 to-blue-100 rounded-[20rpx] shadow-inner self-start">
136 - <text class="text-gray-800 text-[28rpx] leading-[40rpx] line-clamp-2 mb-1">{{ hotMaterials[0].title }}</text> 136 + <image :src="getDocumentIcon(item.fileName)" class="w-[48rpx] h-[48rpx]" mode="aspectFit" />
137 - <view class="flex items-center gap-2 mb-1">
138 - <view class="bg-blue-50 rounded px-2 py-0.5">
139 - <text class="text-blue-600 text-[22rpx]">{{ getDocumentLabel(hotMaterials[0].fileName) }}</text>
140 - </view>
141 - </view>
142 - <view class="flex justify-between items-end">
143 - <text class="text-gray-400 text-[24rpx]">{{ hotMaterials[0].learners }}</text>
144 - <text class="text-blue-600 text-[26rpx]">{{ hotMaterials[0].progress }}</text>
145 - </view>
146 - </view>
147 - </view>
148 - <view class="h-[2rpx] bg-gray-100"></view>
149 - <!-- Item 2 -->
150 - <view class="flex gap-[24rpx]" @tap="handleMaterialClick(hotMaterials[1])">
151 - <view class="w-[80rpx] h-[88rpx] flex-shrink-0 flex items-center justify-center bg-blue-50 rounded-[12rpx]">
152 - <image :src="getDocumentIcon(hotMaterials[1].fileName)" class="w-[48rpx] h-[48rpx]" mode="aspectFit" />
153 - </view>
154 - <view class="flex-1 flex flex-col justify-between py-[4rpx]">
155 - <text class="text-gray-800 text-[28rpx] leading-[40rpx] line-clamp-2 mb-1">{{ hotMaterials[1].title }}</text>
156 - <view class="flex items-center gap-2 mb-1">
157 - <view class="bg-blue-50 rounded px-2 py-0.5">
158 - <text class="text-blue-600 text-[22rpx]">{{ getDocumentLabel(hotMaterials[1].fileName) }}</text>
159 - </view>
160 - </view>
161 - <view class="flex justify-between items-end">
162 - <text class="text-gray-400 text-[24rpx]">{{ hotMaterials[1].learners }}</text>
163 - <text class="text-blue-600 text-[26rpx]">{{ hotMaterials[1].progress }}</text>
164 - </view>
165 - </view>
166 - </view>
167 - <view class="h-[2rpx] bg-gray-100"></view>
168 - <!-- Item 3 -->
169 - <view class="flex gap-[24rpx]" @tap="handleMaterialClick(hotMaterials[2])">
170 - <view class="w-[80rpx] h-[88rpx] flex-shrink-0 flex items-center justify-center bg-blue-50 rounded-[12rpx]">
171 - <image :src="getDocumentIcon(hotMaterials[2].fileName)" class="w-[48rpx] h-[48rpx]" mode="aspectFit" />
172 - </view>
173 - <view class="flex-1 flex flex-col justify-between py-[4rpx]">
174 - <text class="text-gray-800 text-[28rpx] leading-[40rpx] line-clamp-2 mb-1">{{ hotMaterials[2].title }}</text>
175 - <view class="flex items-center gap-2 mb-1">
176 - <view class="bg-blue-50 rounded px-2 py-0.5">
177 - <text class="text-blue-600 text-[22rpx]">{{ getDocumentLabel(hotMaterials[2].fileName) }}</text>
178 </view> 137 </view>
138 +
139 + <!-- 内容区域 -->
140 + <view class="flex-1 min-w-0">
141 + <text class="text-[#1F2937] text-[30rpx] font-bold leading-[1.4] line-clamp-2 mb-[8rpx]">
142 + {{ item.title }}
143 + </text>
144 + <view class="flex items-center gap-[12rpx] mb-[16rpx]">
145 + <view class="inline-flex items-center justify-center px-[12rpx] py-[4rpx] bg-gray-100 text-gray-500 text-[20rpx] font-medium rounded-[8rpx]">
146 + <text>{{ getDocumentLabel(item.fileName) }}</text>
179 </view> 147 </view>
180 - <view class="flex justify-between items-end"> 148 + <text class="text-[#9CA3AF] text-[22rpx]">{{ item.learners }}</text>
181 - <text class="text-gray-400 text-[24rpx]">{{ hotMaterials[2].learners }}</text>
182 - <text class="text-blue-600 text-[26rpx]">{{ hotMaterials[2].progress }}</text>
183 </view> 149 </view>
150 +
151 + <!-- 分割线 -->
152 + <view class="h-[1rpx] bg-gray-100 my-[20rpx]"></view>
153 +
154 + <!-- 操作按钮 -->
155 + <ListItemActions
156 + :viewable="true"
157 + :collectable="true"
158 + :deletable="false"
159 + :collected="item.collected"
160 + @view="onViewMaterial(item)"
161 + @collect="toggleMaterialCollect(item)"
162 + />
184 </view> 163 </view>
185 </view> 164 </view>
186 </view> 165 </view>
...@@ -217,6 +196,7 @@ import IconFont from '@/components/IconFont.vue'; ...@@ -217,6 +196,7 @@ import IconFont from '@/components/IconFont.vue';
217 import PlanPopup from '@/components/PlanPopup/index.vue'; 196 import PlanPopup from '@/components/PlanPopup/index.vue';
218 import SchemeA from '@/components/PlanSchemes/SchemeA.vue'; 197 import SchemeA from '@/components/PlanSchemes/SchemeA.vue';
219 import SchemeB from '@/components/PlanSchemes/SchemeB.vue'; 198 import SchemeB from '@/components/PlanSchemes/SchemeB.vue';
199 +import ListItemActions from '@/components/ListItemActions/index.vue';
220 200
221 // Plan Popup State 201 // Plan Popup State
222 const showPlanPopup = ref(false); 202 const showPlanPopup = ref(false);
...@@ -256,6 +236,7 @@ const hotMaterials = ref([ ...@@ -256,6 +236,7 @@ const hotMaterials = ref([
256 title: '2024年保险市场趋势分析报告', 236 title: '2024年保险市场趋势分析报告',
257 learners: '256人学习', 237 learners: '256人学习',
258 progress: '78%', 238 progress: '78%',
239 + collected: false,
259 // PDF 文件 240 // PDF 文件
260 fileName: '2024年保险市场趋势分析报告.pdf', 241 fileName: '2024年保险市场趋势分析报告.pdf',
261 downloadUrl: 'https://cdn.ipadbiz.cn/manulife/document/1_%E7%BE%8E%E4%B9%90%E7%88%B1%E8%A7%89%E6%95%99%E8%82%B22024%E9%A1%B9%E7%9B%AE%E5%9B%BE%E5%BD%B1%E4%BB%8B%E7%BB%8D_.pdf' 242 downloadUrl: 'https://cdn.ipadbiz.cn/manulife/document/1_%E7%BE%8E%E4%B9%90%E7%88%B1%E8%A7%89%E6%95%99%E8%82%B22024%E9%A1%B9%E7%9B%AE%E5%9B%BE%E5%BD%B1%E4%BB%8B%E7%BB%8D_.pdf'
...@@ -264,6 +245,7 @@ const hotMaterials = ref([ ...@@ -264,6 +245,7 @@ const hotMaterials = ref([
264 title: '高净值客户产品配置方案模板', 245 title: '高净值客户产品配置方案模板',
265 learners: '189人学习', 246 learners: '189人学习',
266 progress: '65%', 247 progress: '65%',
248 + collected: true,
267 // Word 文件 249 // Word 文件
268 fileName: '高净值客户产品配置方案模板.docx', 250 fileName: '高净值客户产品配置方案模板.docx',
269 downloadUrl: 'https://cdn.ipadbiz.cn/manulife/document/1_%E7%BE%8E%E4%B9%90%E7%88%B1%E8%A7%89%E6%95%99%E8%82%B22024%E9%A1%B9%E7%9B%AE%E5%9B%BE%E5%BD%B1%E4%BB%8B%E7%BB%8D_.pdf' 251 downloadUrl: 'https://cdn.ipadbiz.cn/manulife/document/1_%E7%BE%8E%E4%B9%90%E7%88%B1%E8%A7%89%E6%95%99%E8%82%B22024%E9%A1%B9%E7%9B%AE%E5%9B%BE%E5%BD%B1%E4%BB%8B%E7%BB%8D_.pdf'
...@@ -272,6 +254,7 @@ const hotMaterials = ref([ ...@@ -272,6 +254,7 @@ const hotMaterials = ref([
272 title: '产品收益率测算表(2024版)', 254 title: '产品收益率测算表(2024版)',
273 learners: '142人学习', 255 learners: '142人学习',
274 progress: '52%', 256 progress: '52%',
257 + collected: false,
275 // Excel 文件 258 // Excel 文件
276 fileName: '产品收益率测算表.xlsx', 259 fileName: '产品收益率测算表.xlsx',
277 downloadUrl: 'https://cdn.ipadbiz.cn/manulife/document/1_%E7%BE%8E%E4%B9%90%E7%88%B1%E8%A7%89%E6%95%99%E8%82%B22024%E9%A1%B9%E7%9B%AE%E5%9B%BE%E5%BD%B1%E4%BB%8B%E7%BB%8D_.pdf' 260 downloadUrl: 'https://cdn.ipadbiz.cn/manulife/document/1_%E7%BE%8E%E4%B9%90%E7%88%B1%E8%A7%89%E6%95%99%E8%82%B22024%E9%A1%B9%E7%9B%AE%E5%9B%BE%E5%BD%B1%E4%BB%8B%E7%BB%8D_.pdf'
...@@ -286,13 +269,28 @@ const go = useGo(); ...@@ -286,13 +269,28 @@ const go = useGo();
286 * 269 *
287 * @description 配置为文件类型列表,点击时打开文件预览 270 * @description 配置为文件类型列表,点击时打开文件预览
288 */ 271 */
289 -const { handleClick: handleMaterialClick } = useListItemClick({ 272 +const { handleClick: onViewMaterial } = useListItemClick({
290 listType: ListType.FILE, 273 listType: ListType.FILE,
291 onAfterClick: (item) => { 274 onAfterClick: (item) => {
292 console.log('用户打开了资料:', item.title); 275 console.log('用户打开了资料:', item.title);
293 } 276 }
294 }); 277 });
295 278
279 +/**
280 + * 切换资料收藏状态
281 + *
282 + * @description 切换热门资料的收藏状态
283 + * @param {Object} item - 资料项
284 + */
285 +const toggleMaterialCollect = (item) => {
286 + item.collected = !item.collected;
287 + Taro.showToast({
288 + title: item.collected ? '已收藏' : '已取消收藏',
289 + icon: 'success',
290 + duration: 1000
291 + });
292 +};
293 +
296 // Handle grid navigation click 294 // Handle grid navigation click
297 const handleGridNav = (item) => { 295 const handleGridNav = (item) => {
298 if (!item.route) { 296 if (!item.route) {
......
...@@ -45,7 +45,8 @@ ...@@ -45,7 +45,8 @@
45 </div> 45 </div>
46 46
47 <!-- Desc --> 47 <!-- Desc -->
48 - <div class="mt-auto self-start bg-[#F3F4F6] text-[#6B7280] text-[22rpx] px-[12rpx] py-[4rpx] rounded-full"> 48 + <div class="mt-auto self-start text-[22rpx] px-[12rpx] py-[4rpx] rounded-full"
49 + :class="[getDescColor(item.id).bg, getDescColor(item.id).text]">
49 {{ item.desc }} 50 {{ item.desc }}
50 </div> 51 </div>
51 </div> 52 </div>
...@@ -68,6 +69,34 @@ const activeTab = ref(0) ...@@ -68,6 +69,34 @@ const activeTab = ref(0)
68 const tabs = ['全部产品', '人寿保险', '医疗保险', '意外保险'] 69 const tabs = ['全部产品', '人寿保险', '医疗保险', '意外保险']
69 70
70 /** 71 /**
72 + * Desc 颜色调色板
73 + *
74 + * @description 为不同描述提供柔和的背景色和对应的文字颜色
75 + */
76 +const descColorPalette = [
77 + { bg: 'bg-blue-50', text: 'text-blue-600' }, // 蓝色
78 + { bg: 'bg-green-50', text: 'text-green-600' }, // 绿色
79 + { bg: 'bg-purple-50', text: 'text-purple-600' }, // 紫色
80 + { bg: 'bg-orange-50', text: 'text-orange-600' }, // 橙色
81 + { bg: 'bg-pink-50', text: 'text-pink-600' }, // 粉色
82 + { bg: 'bg-teal-50', text: 'text-teal-600' }, // 青色
83 + { bg: 'bg-indigo-50', text: 'text-indigo-600' }, // 靛蓝色
84 + { bg: 'bg-red-50', text: 'text-red-600' }, // 红色
85 +]
86 +
87 +/**
88 + * 获取 desc 的颜色样式
89 + *
90 + * @description 根据 ID 获取固定的背景色和文字颜色
91 + * @param {number} id - 产品 ID
92 + * @returns {Object} 包含 bg 和 text 属性的颜色对象
93 + */
94 +const getDescColor = (id) => {
95 + const index = id % descColorPalette.length
96 + return descColorPalette[index]
97 +}
98 +
99 +/**
71 * 生成产品数据 100 * 生成产品数据
72 * 101 *
73 * @description 生成模拟产品列表数据,每个产品包含唯一 id 102 * @description 生成模拟产品列表数据,每个产品包含唯一 id
......
This diff is collapsed. Click to expand it.
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
23 </view> 23 </view>
24 24
25 <!-- Arrow --> 25 <!-- Arrow -->
26 - <IconFont name="rectRight" size="20" color="#9CA3AF" /> 26 + <IconFont name="rect-right" size="20" color="#9CA3AF" />
27 </view> 27 </view>
28 28
29 <!-- Menu List --> 29 <!-- Menu List -->
......
...@@ -53,16 +53,12 @@ ...@@ -53,16 +53,12 @@
53 <view class="h-[1rpx] bg-gray-100 my-[20rpx]"></view> 53 <view class="h-[1rpx] bg-gray-100 my-[20rpx]"></view>
54 54
55 <!-- Actions --> 55 <!-- Actions -->
56 - <view class="flex justify-end gap-[24rpx]"> 56 + <ListItemActions
57 - <view class="flex items-center text-blue-600" @tap="onView(item)"> 57 + :viewable="true"
58 - <IconFont name="eye" size="14" class="mr-[8rpx]" /> 58 + :deletable="true"
59 - <text class="text-[24rpx]">查看</text> 59 + @view="onView(item)"
60 - </view> 60 + @delete="onDelete(item)"
61 - <view class="flex items-center text-red-500" @tap="onDelete(item)"> 61 + />
62 - <IconFont name="del" size="14" class="mr-[8rpx]" />
63 - <text class="text-[24rpx]">删除</text>
64 - </view>
65 - </view>
66 </view> 62 </view>
67 63
68 <!-- Empty State --> 64 <!-- Empty State -->
...@@ -85,6 +81,7 @@ import { useFileOperation } from '@/composables/useFileOperation' ...@@ -85,6 +81,7 @@ import { useFileOperation } from '@/composables/useFileOperation'
85 import IconFont from '@/components/IconFont.vue' 81 import IconFont from '@/components/IconFont.vue'
86 import TabBar from '@/components/TabBar.vue' 82 import TabBar from '@/components/TabBar.vue'
87 import NavHeader from '@/components/NavHeader.vue' 83 import NavHeader from '@/components/NavHeader.vue'
84 +import ListItemActions from '@/components/ListItemActions/index.vue'
88 import Taro from '@tarojs/taro' 85 import Taro from '@tarojs/taro'
89 86
90 const go = useGo() 87 const go = useGo()
......