up功能基本完成
This commit is contained in:
@@ -41,6 +41,7 @@ const container = ref(null)
|
||||
const photos = ref([])
|
||||
const parentChain = ref([])
|
||||
const containerDepth = ref(0)
|
||||
const canModifyContainer = ref(false)
|
||||
const loadingDetail = ref(true)
|
||||
const notFound = ref(false)
|
||||
|
||||
@@ -134,6 +135,7 @@ async function fetchContainer() {
|
||||
photos.value = data.photos ?? []
|
||||
parentChain.value = data.parent_chain ?? []
|
||||
containerDepth.value = data.depth ?? 0
|
||||
canModifyContainer.value = data.canModifyContainer === true
|
||||
} else {
|
||||
notFound.value = true
|
||||
}
|
||||
@@ -328,6 +330,7 @@ onMounted(async () => {
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<button
|
||||
v-if="canModifyContainer"
|
||||
class="inline-flex items-center gap-1.5 rounded-lg border border-gray-300 bg-white px-3 py-1.5 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 dark:border-dk-muted dark:bg-dk-base dark:text-white dark:hover:bg-dk-muted"
|
||||
@click="openEdit"
|
||||
>
|
||||
@@ -335,7 +338,7 @@ onMounted(async () => {
|
||||
{{ t('warehouse.edit') }}
|
||||
</button>
|
||||
<button
|
||||
v-if="container.ChildCount === 0 && container.ItemCount === 0"
|
||||
v-if="canModifyContainer && container.ChildCount === 0 && container.ItemCount === 0"
|
||||
class="inline-flex items-center gap-1.5 rounded-lg border border-red-300 bg-white px-3 py-1.5 text-sm font-medium text-red-600 transition-colors hover:bg-red-50 dark:border-red-900 dark:bg-dk-base dark:text-red-400 dark:hover:bg-red-900/20"
|
||||
@click="confirmDelete"
|
||||
>
|
||||
@@ -378,7 +381,14 @@ onMounted(async () => {
|
||||
|
||||
<!-- 元信息 -->
|
||||
<div class="flex flex-wrap gap-x-6 gap-y-1 text-xs text-gray-400 dark:text-gray-500">
|
||||
<span>{{ t('warehouse.created_by') }}: {{ usersStore.getUsernameFromUserID(container.CreatorID) }}</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<span>{{ t('warehouse.created_by') }}:</span>
|
||||
<img
|
||||
:src="usersStore.getAvatarUrlFromUserID(container.CreatorID)"
|
||||
class="w-4 h-4 rounded-full object-cover"
|
||||
/>
|
||||
{{ usersStore.getUsernameFromUserID(container.CreatorID) }}
|
||||
</span>
|
||||
<span>{{ t('warehouse.created_at') }}: {{ fmtTs(container.CreatedAt) }}</span>
|
||||
<span>{{ t('warehouse.child_containers') }}: {{ container.ChildCount }}</span>
|
||||
<span>{{ t('warehouse.items') }}: {{ container.ItemCount }}</span>
|
||||
@@ -418,12 +428,13 @@ onMounted(async () => {
|
||||
<th class="px-5 py-3 font-medium w-24 text-center">{{ t('warehouse.child_containers') }}</th>
|
||||
<th class="px-5 py-3 font-medium w-24 text-center">{{ t('warehouse.items') }}</th>
|
||||
<th class="px-5 py-3 font-medium whitespace-nowrap">{{ t('warehouse.created_at') }}</th>
|
||||
<th class="px-5 py-3 font-medium">{{ t('warehouse.created_by') }}</th>
|
||||
<th class="px-5 py-3 font-medium w-24 text-right">{{ t('warehouse.actions') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-if="loadingSub">
|
||||
<td colspan="5" class="px-5 py-8 text-center">
|
||||
<td colspan="6" class="px-5 py-8 text-center">
|
||||
<svg class="mx-auto h-5 w-5 animate-spin text-gray-400" viewBox="0 0 24 24" fill="none">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" />
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8H4z" />
|
||||
@@ -431,7 +442,7 @@ onMounted(async () => {
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-else-if="subContainers.length === 0">
|
||||
<td colspan="5" class="px-5 py-8 text-center text-gray-400 dark:text-gray-500">
|
||||
<td colspan="6" class="px-5 py-8 text-center text-gray-400 dark:text-gray-500">
|
||||
{{ t('warehouse.no_containers') }}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -459,6 +470,15 @@ onMounted(async () => {
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-5 py-3 text-xs text-gray-400 dark:text-gray-500 whitespace-nowrap">{{ fmtTs(c.CreatedAt) }}</td>
|
||||
<td class="px-5 py-3">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<img
|
||||
:src="usersStore.getAvatarUrlFromUserID(c.CreatorID)"
|
||||
class="w-5 h-5 rounded-full object-cover flex-shrink-0"
|
||||
/>
|
||||
<span class="truncate text-gray-600 dark:text-gray-400">{{ usersStore.getUsernameFromUserID(c.CreatorID) }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-5 py-3 text-right">
|
||||
<button
|
||||
class="text-xs text-blue-500 hover:underline"
|
||||
@@ -534,12 +554,13 @@ onMounted(async () => {
|
||||
<th class="px-5 py-3 font-medium">{{ t('warehouse.serial_number') }}</th>
|
||||
<th class="px-5 py-3 font-medium w-20 text-center">{{ t('warehouse.quantity') }}</th>
|
||||
<th class="px-5 py-3 font-medium whitespace-nowrap">{{ t('warehouse.created_at') }}</th>
|
||||
<th class="px-5 py-3 font-medium">{{ t('warehouse.created_by') }}</th>
|
||||
<th class="px-5 py-3 font-medium w-20 text-right">{{ t('warehouse.actions') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-if="loadingItems">
|
||||
<td colspan="5" class="px-5 py-8 text-center">
|
||||
<td colspan="6" class="px-5 py-8 text-center">
|
||||
<svg class="mx-auto h-5 w-5 animate-spin text-gray-400" viewBox="0 0 24 24" fill="none">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" />
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8H4z" />
|
||||
@@ -547,7 +568,7 @@ onMounted(async () => {
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-else-if="items.length === 0">
|
||||
<td colspan="5" class="px-5 py-8 text-center text-gray-400 dark:text-gray-500">
|
||||
<td colspan="6" class="px-5 py-8 text-center text-gray-400 dark:text-gray-500">
|
||||
{{ t('warehouse.no_items') }}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -567,6 +588,15 @@ onMounted(async () => {
|
||||
<td class="px-5 py-3 text-xs text-gray-500 dark:text-gray-400 max-w-[140px] truncate">{{ item.serial_number || '—' }}</td>
|
||||
<td class="px-5 py-3 text-center text-sm">{{ item.Quantity }}</td>
|
||||
<td class="px-5 py-3 text-xs text-gray-400 dark:text-gray-500 whitespace-nowrap">{{ fmtTs(item.CreatedAt) }}</td>
|
||||
<td class="px-5 py-3">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<img
|
||||
:src="usersStore.getAvatarUrlFromUserID(item.CreatorID)"
|
||||
class="w-5 h-5 rounded-full object-cover flex-shrink-0"
|
||||
/>
|
||||
<span class="truncate text-gray-600 dark:text-gray-400">{{ usersStore.getUsernameFromUserID(item.CreatorID) }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-5 py-3 text-right">
|
||||
<button
|
||||
class="text-xs text-blue-500 hover:underline"
|
||||
@@ -727,7 +757,6 @@ onMounted(async () => {
|
||||
:confirm-text="t('warehouse.delete')"
|
||||
:cancel-text="t('message.cancel')"
|
||||
danger
|
||||
:confirm-loading="deleting"
|
||||
@confirm="doDelete"
|
||||
/>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user