功能基本完成

This commit is contained in:
2026-04-14 17:28:37 +08:00
parent 6eb6e76bfd
commit 0310fd9aa3
8 changed files with 110 additions and 11 deletions
+5
View File
@@ -6,6 +6,11 @@ export const purchaseApi = {
return api.post('/purchase/getorders', params)
},
/** 获取订单数量统计 */
getOrderCount() {
return api.post('/purchase/getordercount', {})
},
/** 新增采购订单 */
addOrder(data) {
return api.post('/purchase/addorder', data)
+3 -1
View File
@@ -94,6 +94,7 @@
"link": "Link",
"no_photos": "No photos",
"open_link": "Open Link",
"copy_link": "Copy Link",
"no_costs": "No cost records",
"cost_total": "Total",
"change_status": "Change Status",
@@ -191,7 +192,8 @@
"today_schedule_count": "Today: {count} schedule(s)",
"today_no_schedule": "No schedules today",
"loading": "Loading...",
"today": "Today: {date}"
"today": "Today: {date}",
"pending_orders": "Pending orders"
},
"message": {
"functionality_not_yet_developed": "Functionality not yet developed",
+3 -1
View File
@@ -94,6 +94,7 @@
"link": "链接",
"no_photos": "暂无图片",
"open_link": "打开链接",
"copy_link": "复制链接",
"no_costs": "暂无费用记录",
"cost_total": "合计",
"change_status": "变更状态",
@@ -191,7 +192,8 @@
"today_schedule_count": "今日共 {count} 个日程",
"today_no_schedule": "今日暂无日程",
"loading": "加载中...",
"today": "今日:{date}"
"today": "今日:{date}",
"pending_orders": "待处理订单"
},
"message": {
"functionality_not_yet_developed": "功能未开发",
+33 -3
View File
@@ -4,6 +4,7 @@ import { useUserStore } from '@/stores/user'
import { useUsersStore } from '@/stores/users'
import { usePageTitle } from '@/composables/usePageTitle'
import { scheduleApi } from '@/api/schedule'
import { purchaseApi } from '@/api/purchase'
import { ref, computed, onMounted } from 'vue'
usePageTitle('appname.home')
@@ -15,6 +16,10 @@ const usersStore = useUsersStore()
const todaySchedules = ref([])
const loadingSchedules = ref(false)
// 采购订单数据
const pendingOrderCount = ref(0)
const loadingOrders = ref(false)
// 获取今日日期字符串
const todayStr = computed(() => {
const today = new Date()
@@ -57,6 +62,21 @@ async function fetchTodaySchedules() {
}
}
// 获取待处理订单数量
async function fetchPendingOrders() {
loadingOrders.value = true
try {
const { errCode, data } = await purchaseApi.getOrderCount()
if (errCode === 0 && data) {
pendingOrderCount.value = data.pending || 0
}
} catch (e) {
console.error('获取订单数量失败', e)
} finally {
loadingOrders.value = false
}
}
// 获取用户名
function getUsername(userId) {
if (!userId) return ''
@@ -100,6 +120,9 @@ function getWeekday(dateStr) {
onMounted(() => {
fetchTodaySchedules()
if (userStore.isLoggedIn) {
fetchPendingOrders()
}
})
</script>
@@ -161,12 +184,19 @@ onMounted(() => {
<!-- 功能入口卡片 -->
<div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
<div
<RouterLink
to="/purchase"
class="rounded-xl border border-gray-200 bg-white px-5 py-4 transition-shadow hover:shadow-md dark:border-dk-muted dark:bg-dk-card"
>
<p class="mb-1 text-sm text-gray-500">{{ t('appname.purchase') }}</p>
<p class="text-lg font-bold text-gray-900 dark:text-white"></p>
</div>
<p class="text-lg font-bold text-gray-900 dark:text-white">
<span v-if="loadingOrders">...</span>
<span v-else :class="{ 'text-yellow-600 dark:text-yellow-400': pendingOrderCount > 0 }">
{{ pendingOrderCount || '—' }}
</span>
</p>
<p class="text-xs text-gray-400">{{ t('home.pending_orders') }}</p>
</RouterLink>
</div>
</div>
</template>
@@ -160,7 +160,7 @@ onMounted(fetchOrders)
@click="jumpToOrder(order.ID)"
>
<td class="px-6 py-3 text-gray-400">{{ order.ID }}</td>
<td class="px-6 py-3 font-medium text-gray-900 dark:text-white">{{ order.Title }}</td>
<td class="px-6 py-3 max-w-[200px] truncate font-medium text-gray-900 dark:text-white">{{ order.Title }}</td>
<td class="px-6 py-3 max-w-[200px] truncate text-gray-600 dark:text-gray-300">{{ order.Remark || '-' }}</td>
<td class="px-6 py-3 whitespace-nowrap text-gray-500 dark:text-gray-400">{{ formatDate(order.CreatedAt) }}</td>
<td class="px-6 py-3">
@@ -137,6 +137,14 @@ function openLink() {
window.open(url, "_blank");
}
function copyLink() {
if (!order.value?.Link) return;
navigator.clipboard.writeText(order.value.Link.trim()).then(() => {
const toast = useToastStore()
toast.success('链接已复制')
})
}
function getStatusLabel(status) {
if (!status) return "";
const opt = statusOptions.find((o) => o.value === status);
@@ -450,12 +458,26 @@ onMounted(fetchOrder);
<label class="mb-1 block text-xs font-medium text-gray-400">{{
t("purchase.link")
}}</label>
<div v-if="order?.Link" class="flex items-center gap-2">
<p class="max-w-xs truncate text-blue-600 dark:text-blue-400">
<div v-if="order?.Link" class="flex flex-wrap items-center gap-2">
<a
:href="order.Link.trim().startsWith('http') ? order.Link.trim() : 'https://' + order.Link.trim()"
target="_blank"
class="max-w-[400px] truncate rounded bg-gray-100 px-3 py-1.5 text-xs text-blue-600 hover:bg-gray-200 dark:bg-dk-base dark:text-blue-400 dark:hover:bg-gray-800"
:title="order.Link"
>
{{ order.Link }}
</p>
</a>
<button
class="inline-flex items-center gap-1 rounded px-2 py-0.5 text-xs text-blue-600 hover:bg-blue-50 dark:text-blue-400 dark:hover:bg-blue-900/20"
class="inline-flex items-center gap-1 rounded bg-blue-100 px-3 py-1.5 text-xs font-medium text-blue-700 hover:bg-blue-200 dark:bg-blue-900/40 dark:text-blue-300 dark:hover:bg-blue-900/60"
@click="copyLink"
>
<svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
</svg>
{{ t('purchase.copy_link') }}
</button>
<button
class="inline-flex items-center gap-1 rounded px-2 py-1 text-xs text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-800"
@click="openLink"
>
<IconExternalLink :size="14" />