Files
simple-todo/frontend/app/src/pages/collaboration/detail/index.vue
T
2026-05-26 11:54:24 +08:00

182 lines
5.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view>
<AppNavbar title="记录详情" show-back fallback-url="/pages/collaboration/records/index" />
<view class="page">
<view v-if="record" class="panel">
<view class="section-title">{{ record.brand }} / {{ record.goods }}</view>
<view class="detail-grid">
<text>合作平台{{ record.cooperationPlatform || '-' }}</text>
<text>返图数量{{ record.imageReturnNum ?? '-' }}</text>
<text>留存方式{{ record.retainedMethod || '-' }}</text>
<text>合作方式{{ record.cooperatedMethod || '-' }}</text>
<text>购入方式{{ record.purchaseMethod || '-' }}</text>
<text>购入金额{{ amountText(record.purchasePrice) }}</text>
<text>购入日期{{ record.purchaseDate || '-' }}</text>
<text>购入平台{{ record.purchasePlatform || '-' }}</text>
<text>稿费{{ amountText(record.remuneration) }}</text>
<text>预完成日期{{ record.deadline || '-' }}</text>
<text>完成日期{{ record.completeDate || '-' }}</text>
<text>拍摄要求{{ record.requirements || '-' }}</text>
<text>备注{{ record.remark || '-' }}</text>
</view>
<view class="status-row">
<AtTag :class="['tag', settlementTagClass(record.purchaseSettlementStatus)]">
拍单{{ record.purchaseSettlementStatus?.label || '-' }}
</AtTag>
<AtTag :class="['tag', settlementTagClass(record.deliverySettlementStatus)]">
快递{{ record.deliverySettlementStatus?.label || '-' }}
</AtTag>
<AtTag :class="['tag', settlementTagClass(record.remunerationSettlementStatus)]">
稿费{{ record.remunerationSettlementStatus?.label || '-' }}
</AtTag>
</view>
</view>
<view class="panel">
<view class="section-title">任务</view>
<AtListItem
v-for="(task, index) in record?.tasks || []"
:key="`task-${index}`"
class="detail-row"
:title="`第 ${index + 1} 次返图`"
:note="task.releaseDate || '未完成'"
/>
<AtLoadMore v-if="!record?.tasks?.length" class="empty small-empty" status="noMore" no-more-text="暂无任务" />
</view>
<view class="panel">
<view class="section-title">支出</view>
<AtListItem
v-for="item in record?.expenditures || []"
:key="item.expenditureId"
class="detail-row"
:title="`${item.purpose || '支出'} / ${item.spendDate || '-'}`"
:note="amountText(item.amount)"
/>
<AtLoadMore v-if="!record?.expenditures?.length" class="empty small-empty" status="noMore" no-more-text="暂无支出" />
</view>
<view class="panel">
<view class="section-title">结款</view>
<AtListItem
v-for="item in record?.settlements || []"
:key="item.settlementId"
class="detail-row"
:title="`${item.purpose || '结款'} / ${item.method || '-'} / ${item.settleDate || '-'}`"
:note="amountText(item.income)"
/>
<AtLoadMore v-if="!record?.settlements?.length" class="empty small-empty" status="noMore" no-more-text="暂无结款" />
</view>
<view class="panel">
<view class="section-title">文件</view>
<AtListItem
v-for="item in record?.files || []"
:key="item.fileId"
class="file-row"
:title="item.originalFilename || item.url"
:note="item.fileType"
arrow="right"
@click="previewFile(item.url)"
/>
<AtLoadMore v-if="!record?.files?.length" class="empty small-empty" status="noMore" no-more-text="暂无文件" />
</view>
</view>
</view>
</template>
<script setup lang="ts">
import Taro, { useDidShow } from '@tarojs/taro'
import { ref } from 'vue'
import { getCollaborationRecordInfoApi, type CollaborationRecordDetailDTO, type SettlementStatusDTO } from '@/api/collaboration'
import { isLoggedIn, redirectToLogin } from '@/utils/auth'
import AppNavbar from '@/components/AppNavbar.vue'
const record = ref<CollaborationRecordDetailDTO>()
useDidShow(() => {
if (!isLoggedIn()) {
redirectToLogin()
return
}
loadRecord()
})
async function loadRecord() {
const recordId = getRecordId()
if (!recordId) return
const { data } = await getCollaborationRecordInfoApi(recordId)
record.value = data
}
function getRecordId() {
const params = Taro.getCurrentInstance().router?.params || {}
return Number(params.recordId || 0)
}
function amountText(amount?: number) {
return amount === undefined || amount === null ? '-' : `¥${amount}`
}
function settlementTagClass(status?: SettlementStatusDTO) {
const classMap = {
UNSETTLED: 'settlement-tag-danger',
PARTIAL: 'settlement-tag-warning',
SETTLED: 'settlement-tag-success'
}
return status ? classMap[status.status] || '' : ''
}
function previewFile(url?: string) {
if (!url) return
Taro.setClipboardData({ data: url })
}
</script>
<style lang="scss">
.detail-grid {
display: grid;
gap: 14px;
font-size: $font-lg;
color: $text-regular;
}
.status-row {
display: flex;
flex-wrap: wrap;
gap: 18px;
margin-top: 18px;
}
.settlement-tag-danger {
color: $color-danger;
background: $color-danger-light;
}
.settlement-tag-warning {
color: $color-warning;
background: $color-warning-light;
}
.settlement-tag-success {
color: $color-success;
background: $color-success-light;
}
.detail-row,
.file-row {
display: flex;
gap: 16px;
align-items: center;
justify-content: space-between;
padding: $space-md 0;
font-size: $font-lg;
border-top: 1px solid $border-color-light;
}
.small-empty {
padding: 24px 0;
}
</style>