From 982c97ab82f3beb1b4febcf014562eda34b9fc05 Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期二, 29 九月 2026 17:59:41 +0800
Subject: [PATCH] feat(ui): 江苏商贸品牌视觉与首页/登录页改版

---
 src/views/dashboard/analytics/modules/todo-panel.vue |  208 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 208 insertions(+), 0 deletions(-)

diff --git a/src/views/dashboard/analytics/modules/todo-panel.vue b/src/views/dashboard/analytics/modules/todo-panel.vue
new file mode 100644
index 0000000..916b434
--- /dev/null
+++ b/src/views/dashboard/analytics/modules/todo-panel.vue
@@ -0,0 +1,208 @@
+<script lang="ts" setup>
+import { onMounted, ref } from 'vue';
+
+import { IconifyIcon } from '@vben/icons';
+
+import { getTaskTodoPage } from '#/api/bpm/task';
+
+defineOptions({ name: 'DashboardTodoPanel' });
+
+const emit = defineEmits<{
+  navigate: [name: string];
+}>();
+
+interface TodoItem {
+  id: string;
+  name: string;
+  createTime?: number;
+}
+
+const loading = ref(true);
+const items = ref<TodoItem[]>([]);
+
+/** createTime 涓烘绉掓椂闂存埑锛屾牸寮忓寲鎴愭槗璇绘枃鏈� */
+function formatTime(ts?: number) {
+  if (!ts) return '-';
+  const d = new Date(ts);
+  const p = (n: number) => String(n).padStart(2, '0');
+  return `${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`;
+}
+
+async function load() {
+  loading.value = true;
+  try {
+    const result = await getTaskTodoPage({ pageNo: 1, pageSize: 6 });
+    items.value = (result.list ?? []).map((t: any) => ({
+      id: String(t.id),
+      name: t.name ?? '鏈懡鍚嶄换鍔�',
+      createTime: t.createTime,
+    }));
+  } catch {
+    items.value = [];
+  } finally {
+    loading.value = false;
+  }
+}
+
+onMounted(load);
+</script>
+
+<template>
+  <div class="elite-section h-full">
+    <div class="elite-head">
+      <h3 class="elite-title">
+        <span class="elite-bar"></span>
+        鎴戠殑寰呭姙
+      </h3>
+      <span class="elite-more" @click="emit('navigate', 'BpmTaskTodo')">
+        鍏ㄩ儴
+        <IconifyIcon class="size-3.5" icon="lucide:chevron-right" />
+      </span>
+    </div>
+
+    <!-- 楠ㄦ灦 -->
+    <div v-if="loading" class="elite-empty">鍔犺浇涓��</div>
+
+    <!-- 绌虹姸鎬� -->
+    <div v-else-if="items.length === 0" class="elite-empty">
+      <IconifyIcon class="mb-2 size-8 opacity-40" icon="lucide:inbox" />
+      <div>鏆傛棤寰呭姙浠诲姟</div>
+    </div>
+
+    <!-- 鍒楄〃 -->
+    <ul v-else class="elite-list">
+      <li
+        v-for="item in items"
+        :key="item.id"
+        class="elite-row"
+        @click="emit('navigate', 'BpmTaskTodo')"
+      >
+        <span class="elite-dot"></span>
+        <span class="elite-row-name">{{ item.name }}</span>
+        <span class="elite-row-time">{{ formatTime(item.createTime) }}</span>
+      </li>
+    </ul>
+  </div>
+</template>
+
+<style scoped>
+.elite-section {
+  border-radius: 14px;
+  padding: 20px;
+  background: #fdfcfa;
+  border: 1px solid rgba(212, 175, 55, 0.22);
+  box-shadow: 0 2px 14px rgba(15, 36, 64, 0.05);
+}
+
+.dark .elite-section {
+  background: #101a2b;
+  border-color: rgba(212, 175, 55, 0.2);
+  box-shadow: 0 2px 14px rgba(0, 0, 0, 0.3);
+}
+
+.elite-head {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  margin-bottom: 14px;
+}
+
+.elite-title {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  margin: 0;
+  font-size: 15px;
+  font-weight: 600;
+  letter-spacing: 1px;
+  color: #0f2440;
+}
+
+.dark .elite-title {
+  color: #f0ead8;
+}
+
+.elite-bar {
+  display: inline-block;
+  width: 3px;
+  height: 15px;
+  border-radius: 2px;
+  background: linear-gradient(180deg, #e3c567, #b8901f);
+}
+
+.elite-more {
+  display: inline-flex;
+  cursor: pointer;
+  align-items: center;
+  gap: 2px;
+  font-size: 12px;
+  color: #b8901f;
+  transition: color 0.2s ease;
+}
+
+.elite-more:hover {
+  color: #8a6a12;
+}
+
+.elite-empty {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 34px 0;
+  font-size: 13px;
+  color: #8a94a6;
+}
+
+.elite-list {
+  margin: 0;
+  padding: 0;
+  list-style: none;
+}
+
+.elite-row {
+  display: flex;
+  cursor: pointer;
+  align-items: center;
+  gap: 10px;
+  padding: 11px 10px;
+  border-radius: 8px;
+  border-bottom: 1px solid rgba(15, 36, 64, 0.05);
+  transition: background-color 0.2s ease;
+}
+
+.elite-row:last-child {
+  border-bottom: none;
+}
+
+.elite-row:hover {
+  background: rgba(212, 175, 55, 0.07);
+}
+
+.elite-dot {
+  width: 6px;
+  height: 6px;
+  flex-shrink: 0;
+  border-radius: 999px;
+  background: #d4af37;
+}
+
+.elite-row-name {
+  overflow: hidden;
+  flex: 1;
+  font-size: 13.5px;
+  color: #0f2440;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.dark .elite-row-name {
+  color: #e6e9ef;
+}
+
+.elite-row-time {
+  flex-shrink: 0;
+  font-size: 12px;
+  color: #8a94a6;
+}
+</style>

--
Gitblit v1.9.3