|
|
@@ -41,14 +41,11 @@
|
|
|
:key="'in'+index"
|
|
|
:title="item.allotNo || '入账记录'"
|
|
|
statusType="primary"
|
|
|
+ @click="handleItemClick(item, 0)"
|
|
|
>
|
|
|
- <CommonInfoRow label="认领金额(元)" :value="amountUnitFormatter(item.amount)" isAmount />
|
|
|
- <CommonInfoRow label="外拨金额(元)" :value="amountUnitFormatter(item.externalAmount)" />
|
|
|
- <CommonInfoRow label="留校金额(元)" :value="amountUnitFormatter(item.internalAmount)" />
|
|
|
+ <CommonInfoRow label="认领金额" :value="amountUnitFormatter(item.amount)" isAmount />
|
|
|
<CommonInfoRow label="认领时间" :value="item.applyTime ? formatDate(item.applyTime) : '--'" />
|
|
|
- <CommonInfoRow label="摘要" :value="item.remark" />
|
|
|
- <CommonInfoRow label="创建人" :value="item.createBy || item.createName" />
|
|
|
- <CommonInfoRow label="创建时间" :value="item.createTime ? formatDate(item.createTime) : '--'" noBorder />
|
|
|
+ <CommonInfoRow label="负责人" :value="item.projectIncharge" noBorder />
|
|
|
</CommonListCard>
|
|
|
</template>
|
|
|
</view>
|
|
|
@@ -62,15 +59,11 @@
|
|
|
:key="'out'+index"
|
|
|
:title="item.externalAllotNo || '外拨记录'"
|
|
|
statusType="warning"
|
|
|
+ @click="handleItemClick(item, 1)"
|
|
|
>
|
|
|
- <CommonInfoRow label="项目编号" :value="item.projectNo" />
|
|
|
- <CommonInfoRow label="外拨总额(元)" :value="amountUnitFormatter(item.amount)" isAmount />
|
|
|
- <CommonInfoRow label="已拨金额(元)" :value="amountUnitFormatter(item.allottedAmount)" />
|
|
|
- <CommonInfoRow label="未拨金额(元)" :value="amountUnitFormatter(item.notAllottedAmount)" />
|
|
|
+ <CommonInfoRow label="外拨总额" :value="amountUnitFormatter(item.amount)" isAmount />
|
|
|
<CommonInfoRow label="申请日期" :value="item.applyTime ? formatDate(item.applyTime) : '--'" />
|
|
|
- <CommonInfoRow label="摘要" :value="item.remark" />
|
|
|
- <CommonInfoRow label="创建人" :value="item.createBy || item.createName" />
|
|
|
- <CommonInfoRow label="创建时间" :value="item.createTime ? formatDate(item.createTime) : '--'" noBorder />
|
|
|
+ <CommonInfoRow label="负责人" :value="item.projectIncharge" noBorder />
|
|
|
</CommonListCard>
|
|
|
</template>
|
|
|
</view>
|
|
|
@@ -85,28 +78,49 @@
|
|
|
:title="item.expenseNo || '支出记录'"
|
|
|
:statusLabel="getExpenseStatusLabel(item.status)"
|
|
|
:statusType="getExpenseStatusType(item.status)"
|
|
|
+ @click="handleItemClick(item, 2)"
|
|
|
>
|
|
|
- <CommonInfoRow label="支出金额(元)" :value="amountUnitFormatter(item.amount)" isAmount />
|
|
|
+ <CommonInfoRow label="支出金额" :value="amountUnitFormatter(item.amount)" isAmount />
|
|
|
<CommonInfoRow label="支出科目" :value="item.subject" />
|
|
|
- <CommonInfoRow label="收款人" :value="item.receiver" />
|
|
|
- <CommonInfoRow label="支出日期" :value="item.expendTime ? formatDate(item.expendTime) : '--'" />
|
|
|
- <CommonInfoRow label="摘要" :value="item.remark" />
|
|
|
- <CommonInfoRow label="创建人" :value="item.createBy || item.createName" />
|
|
|
- <CommonInfoRow label="创建时间" :value="item.createTime ? formatDate(item.createTime) : '--'" :noBorder="!(item.fileName && item.fileUrl)" />
|
|
|
-
|
|
|
- <view v-if="item.fileName && item.fileUrl" style="margin-top: 20rpx;">
|
|
|
- <CommonFileList :files="[{ fileName: item.fileName, fileUrl: item.fileUrl }]" />
|
|
|
- </view>
|
|
|
+ <CommonInfoRow label="支出日期" :value="item.expendTime ? formatDate(item.expendTime) : '--'" noBorder />
|
|
|
</CommonListCard>
|
|
|
</template>
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
+
|
|
|
+ <!-- 详情弹窗 -->
|
|
|
+ <uv-popup ref="detailPopup" mode="bottom" round="20" bgColor="#f8f9fc">
|
|
|
+ <view class="detail-popup-content">
|
|
|
+ <view class="popup-header">
|
|
|
+ <text class="title">详情记录</text>
|
|
|
+ <uv-icon name="close" @click="closePopup" color="#999" size="20"></uv-icon>
|
|
|
+ </view>
|
|
|
+ <scroll-view scroll-y class="detail-scroll">
|
|
|
+ <view class="detail-list">
|
|
|
+ <view class="detail-item" v-for="(field, idx) in currentFields" :key="idx">
|
|
|
+ <text class="label">{{ field.label }}</text>
|
|
|
+ <view class="value-wrap">
|
|
|
+ <text class="value" :class="{ 'amount': field.isAmount }">
|
|
|
+ {{ formatFieldValue(field) }}
|
|
|
+ </text>
|
|
|
+ <text class="unit" v-if="field.isAmount">元</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view v-if="activeItem?.fileName" class="attachment-section">
|
|
|
+ <text class="label">附件信息</text>
|
|
|
+ <CommonFileList :files="[{ fileName: activeItem.fileName, fileUrl: activeItem.fileUrl }]" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+ </view>
|
|
|
+ </uv-popup>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, watch } from 'vue';
|
|
|
+import { ref, watch, computed } from 'vue';
|
|
|
import { useProjectStore } from '@/store/modules/project';
|
|
|
import { formatDate } from '@/utils/date';
|
|
|
import { formatWithComma } from '@/utils/format';
|
|
|
@@ -129,6 +143,83 @@ const projectStore = useProjectStore();
|
|
|
|
|
|
// 当前激活的子 Tab 索引
|
|
|
const currentTab = ref(0);
|
|
|
+const detailPopup = ref();
|
|
|
+const activeItem = ref<any>(null);
|
|
|
+const activeTabType = ref(0);
|
|
|
+
|
|
|
+// 详情字段配置
|
|
|
+const fieldConfigs = {
|
|
|
+ inbound: [
|
|
|
+ { label: '认领编号', key: 'allotNo' },
|
|
|
+ { label: '项目负责人', key: 'projectIncharge' },
|
|
|
+ { label: '项目类型', key: 'projectType', isType: true },
|
|
|
+ { label: '认领金额', key: 'amount', isAmount: true },
|
|
|
+ { label: '外拨金额', key: 'externalAmount', isAmount: true },
|
|
|
+ { label: '留校金额', key: 'internalAmount', isAmount: true },
|
|
|
+ { label: '认领时间', key: 'applyTime', isDate: true },
|
|
|
+ { label: '摘要', key: 'remark' },
|
|
|
+ { label: '创建人', key: 'createdName' },
|
|
|
+ { label: '创建时间', key: 'createdTime', isDate: true },
|
|
|
+ ],
|
|
|
+ outbound: [
|
|
|
+ { label: '外拨编号', key: 'externalAllotNo' },
|
|
|
+ { label: '项目编号', key: 'projectNo' },
|
|
|
+ { label: '项目负责人', key: 'projectIncharge' },
|
|
|
+ { label: '外拨总额', key: 'amount', isAmount: true },
|
|
|
+ { label: '已拨金额', key: 'allottedAmount', isAmount: true },
|
|
|
+ { label: '未拨金额', key: 'notAllottedAmount', isAmount: true },
|
|
|
+ { label: '申请日期', key: 'applyTime', isDate: true },
|
|
|
+ { label: '摘要', key: 'remark' },
|
|
|
+ { label: '创建人', key: 'createdName' },
|
|
|
+ { label: '创建时间', key: 'createdTime', isDate: true },
|
|
|
+ ],
|
|
|
+ expense: [
|
|
|
+ { label: '支出编号', key: 'expenseNo' },
|
|
|
+ { label: '项目类型', key: 'projectType', isType: true },
|
|
|
+ { label: '项目名称', key: 'projectName' },
|
|
|
+ { label: '支出金额', key: 'amount', isAmount: true },
|
|
|
+ { label: '支出科目', key: 'subject' },
|
|
|
+ { label: '支出状态', key: 'status', isStatus: true },
|
|
|
+ { label: '合同金额', key: 'contractAmount', isAmount: true },
|
|
|
+ { label: '间接/配套经费支出', key: 'otherAmount', isAmount: true },
|
|
|
+ { label: '财政拨款支出', key: 'projectAmount', isAmount: true },
|
|
|
+ { label: '自筹经费支出', key: 'raiseAmount', isAmount: true },
|
|
|
+ { label: '收款人', key: 'receiver' },
|
|
|
+ { label: '支出日期', key: 'expendTime', isDate: true },
|
|
|
+ { label: '摘要', key: 'remark' },
|
|
|
+ { label: '创建人', key: 'createdName' },
|
|
|
+ { label: '创建时间', key: 'createdTime', isDate: true },
|
|
|
+ ]
|
|
|
+};
|
|
|
+
|
|
|
+const currentFields = computed(() => {
|
|
|
+ if (activeTabType.value === 0) return fieldConfigs.inbound;
|
|
|
+ if (activeTabType.value === 1) return fieldConfigs.outbound;
|
|
|
+ return fieldConfigs.expense;
|
|
|
+});
|
|
|
+
|
|
|
+const formatFieldValue = (field: any) => {
|
|
|
+ if (!activeItem.value) return '--';
|
|
|
+ const val = activeItem.value[field.key];
|
|
|
+ if (field.isAmount) return amountUnitFormatter(val);
|
|
|
+ if (field.isDate) return val ? formatDate(val) : '--';
|
|
|
+ if (field.isType) return getProjectType(val);
|
|
|
+ if (field.isStatus) return getExpenseStatusLabel(val);
|
|
|
+ return val || '--';
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * 详情点击显示
|
|
|
+ */
|
|
|
+const handleItemClick = (item: any, type: number) => {
|
|
|
+ activeItem.value = item;
|
|
|
+ activeTabType.value = type;
|
|
|
+ detailPopup.value.open();
|
|
|
+};
|
|
|
+
|
|
|
+const closePopup = () => {
|
|
|
+ detailPopup.value.close();
|
|
|
+};
|
|
|
|
|
|
// 经费模块内部的子 Tab 配置
|
|
|
const fundingTabs = ref([
|
|
|
@@ -221,13 +312,13 @@ const handleDownload = (file: any) => {
|
|
|
}
|
|
|
|
|
|
.summary-card {
|
|
|
- background: #fff;
|
|
|
- border-radius: 16rpx;
|
|
|
+ background: linear-gradient(135deg, #ffffff 0%, #f6faff 100%);
|
|
|
+ border-radius: 20rpx;
|
|
|
padding: 30rpx;
|
|
|
- box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.03);
|
|
|
+ box-shadow: 0 8rpx 24rpx rgba(28, 155, 253, 0.08);
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
- gap: 20rpx;
|
|
|
+ gap: 30rpx;
|
|
|
|
|
|
.sum-row {
|
|
|
display: flex;
|
|
|
@@ -240,20 +331,22 @@ const handleDownload = (file: any) => {
|
|
|
align-items: center;
|
|
|
|
|
|
.sum-label {
|
|
|
- font-size: 26rpx;
|
|
|
- color: #888;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #909399;
|
|
|
margin-bottom: 12rpx;
|
|
|
}
|
|
|
|
|
|
.sum-value {
|
|
|
- font-size: 36rpx;
|
|
|
- font-weight: bold;
|
|
|
+ font-size: 38rpx;
|
|
|
+ font-weight: 700;
|
|
|
font-family: din;
|
|
|
+ letter-spacing: 0.5px;
|
|
|
|
|
|
.unit {
|
|
|
- font-size: 24rpx;
|
|
|
- margin-left: 4rpx;
|
|
|
- font-weight: normal;
|
|
|
+ font-size: 22rpx;
|
|
|
+ margin-left: 6rpx;
|
|
|
+ font-weight: 400;
|
|
|
+ color: #999;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -265,6 +358,90 @@ const handleDownload = (file: any) => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+.detail-popup-content {
|
|
|
+ padding: 40rpx 30rpx;
|
|
|
+ max-height: 85vh;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .popup-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 40rpx;
|
|
|
+ padding: 0 10rpx;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ font-size: 34rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .detail-scroll {
|
|
|
+ flex: 1;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+
|
|
|
+ .detail-list {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 30rpx;
|
|
|
+
|
|
|
+ .detail-item {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: flex-start;
|
|
|
+ padding-bottom: 24rpx;
|
|
|
+ border-bottom: 1rpx solid #efefef;
|
|
|
+
|
|
|
+ .label {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #909399;
|
|
|
+ flex-shrink: 0;
|
|
|
+ margin-right: 30rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .value-wrap {
|
|
|
+ display: flex;
|
|
|
+ align-items: baseline;
|
|
|
+ justify-content: flex-end;
|
|
|
+ flex: 1;
|
|
|
+
|
|
|
+ .value {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333;
|
|
|
+ text-align: right;
|
|
|
+ word-break: break-all;
|
|
|
+
|
|
|
+ &.amount {
|
|
|
+ color: #1c9bfd;
|
|
|
+ font-weight: bold;
|
|
|
+ font-family: din;
|
|
|
+ font-size: 32rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .unit {
|
|
|
+ font-size: 20rpx;
|
|
|
+ color: #999;
|
|
|
+ margin-left: 4rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .attachment-section {
|
|
|
+ margin-top: 20rpx;
|
|
|
+ .label {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #909399;
|
|
|
+ display: block;
|
|
|
+ margin-bottom: 16rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
.section {
|
|
|
width: 100%;
|
|
|
}
|