feat: app功能基本实现

This commit is contained in:
gin
2026-05-26 11:54:24 +08:00
parent 2757a4fb49
commit 2a702fa6a9
218 changed files with 6766 additions and 5961 deletions
@@ -0,0 +1,181 @@
<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>