<template>
|
<view class="sales-account">
|
<!-- 使用通用页面头部组件 -->
|
<PageHeader title="来票台账"
|
@back="goBack" />
|
<!-- 搜索区域 -->
|
<view class="search-section">
|
<view class="search-bar">
|
<view class="search-input">
|
<up-input class="search-text"
|
placeholder="请输入供应商名称搜索"
|
v-model="searchForm.supplierName"
|
@change="handleQuery"
|
clearable />
|
</view>
|
<view class="filter-button"
|
@click="handleQuery">
|
<up-icon name="search"
|
size="24"
|
color="#999"></up-icon>
|
</view>
|
</view>
|
</view>
|
<!-- 列表区域 -->
|
<view class="ledger-list"
|
v-if="total > 0">
|
<view v-for="(item, index) in ledgerList"
|
:key="index">
|
<view class="ledger-item">
|
<view class="item-header">
|
<view class="item-left">
|
<view class="document-icon">
|
<up-icon name="file-text"
|
size="16"
|
color="#ffffff"></up-icon>
|
</view>
|
<text class="item-id">{{ item.purchaseContractNumber }}</text>
|
</view>
|
</view>
|
<up-divider></up-divider>
|
<view class="item-details">
|
<view class="detail-row">
|
<text class="detail-label">销售合同号</text>
|
<text class="detail-value">{{ item.salesContractNo }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">项目名称</text>
|
<text class="detail-value">{{ item.projectName }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">供应商名称</text>
|
<text class="detail-value">{{ item.supplierName }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">产品大类</text>
|
<text class="detail-value">{{ item.productCategory }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">规格型号</text>
|
<text class="detail-value">{{ item.specificationModel }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">发票号</text>
|
<text class="detail-value">{{ item.invoiceNumber || '-' }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">合同金额(元)</text>
|
<text class="detail-value">{{ item.taxInclusiveTotalPrice || '-' }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">来票日期</text>
|
<text class="detail-value">{{ item.createdAt || '-' }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">来票金额(元)</text>
|
<text class="detail-value highlight">{{ formatAmount(item.ticketsAmount) }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">不含税金额(元)</text>
|
<text class="detail-value highlight">{{ formatAmount(item.unTicketsPrice) }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">增值税</text>
|
<text class="detail-value">{{ item.invoiceAmount }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">录入人</text>
|
<text class="detail-value">{{ item.issUer }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">录入日期</text>
|
<text class="detail-value">{{ item.createdAt }}</text>
|
</view>
|
</view>
|
<view class="action-buttons">
|
<!-- <u-button
|
type="primary"
|
size="small"
|
class="action-btn"
|
:disabled="item.issUer !== userStore.nickName"
|
@click="openEdit(item)"
|
>
|
编辑
|
</u-button>
|
<u-button
|
type="error"
|
size="small"
|
plain
|
class="action-btn"
|
:disabled="item.issUer !== userStore.nickName"
|
@click="handleDelete(item)"
|
>
|
删除
|
</u-button> -->
|
<!-- <u-button-->
|
<!-- type="default"-->
|
<!-- size="small"-->
|
<!-- plain-->
|
<!-- class="action-btn"-->
|
<!-- v-if="item.invoiceFileName"-->
|
<!-- @click="openFileActions(item.commonFiles || [])"-->
|
<!-- >-->
|
<!-- 查看附件-->
|
<!-- </u-button>-->
|
<!-- <u-button-->
|
<!-- type="primary"-->
|
<!-- size="small"-->
|
<!-- class="action-btn"-->
|
<!-- v-else-->
|
<!-- :disabled="item.issUer !== userStore.nickName"-->
|
<!-- @click="openUpload(item)"-->
|
<!-- >-->
|
<!-- 上传-->
|
<!-- </u-button>-->
|
</view>
|
</view>
|
</view>
|
</view>
|
<view v-else
|
class="no-data">
|
<text>暂无来票台账数据</text>
|
</view>
|
<!-- 单行上传弹窗(无表单) -->
|
<u-popup v-model="showUpload"
|
mode="bottom"
|
border-radius="10">
|
<view class="upload-container">
|
<view class="popup-header">
|
<text class="popup-title">上传附件(仅支持 pdf,最大10MB,最多10个)</text>
|
</view>
|
<u-upload ref="uploadRef"
|
accept="file"
|
multiple
|
:max-count="10"
|
:show-progress="true"
|
:before-upload="beforeReadPdf"
|
:action="uploadUrl"
|
:header="{ Authorization: 'Bearer ' + getToken() }"
|
name="file"
|
@on-success="onUploadSuccess"
|
@on-error="onUploadError" />
|
<view class="uploaded-list"
|
v-if="fileList.length">
|
<view class="uploaded-item"
|
v-for="(f, idx) in fileList"
|
:key="idx">
|
<text class="file-name">{{ f.name || getFileNameFromUrl(f.url) }}</text>
|
<u-button size="mini"
|
type="error"
|
plain
|
@click="removeUploaded(idx)">移除</u-button>
|
</view>
|
</view>
|
<view class="filter-actions">
|
<u-button @click="showUpload = false"
|
type="default"
|
size="default"
|
style="width: 150px;">取消</u-button>
|
<u-button @click="confirmUpload"
|
type="primary"
|
size="default"
|
style="width: 150px;">确认</u-button>
|
</view>
|
</view>
|
</u-popup>
|
<!-- 附件列表选择 -->
|
<u-action-sheet v-model="showFileSheet"
|
:list="fileActions"
|
:cancel-btn="true"
|
@click="onSelectFile"
|
@close="showFileSheet = false" />
|
</view>
|
</template>
|
|
<script setup>
|
import { ref, reactive, onMounted } from "vue";
|
import dayjs from "dayjs";
|
const showToast = message => {
|
uni.showToast({
|
title: message,
|
icon: "none",
|
});
|
};
|
import useUserStore from "@/store/modules/user";
|
import { getToken } from "@/utils/auth";
|
import config from "@/config.js";
|
import {
|
registrationProductPage,
|
commitFile,
|
delInvoiceLedgerByRegProductId,
|
} from "@/api/salesManagement/invoiceLedger.js";
|
import { onShow } from "@dcloudio/uni-app";
|
import { productRecordPage } from "@/api/procurementManagement/procurementInvoiceLedger";
|
import { delRegistration } from "@/api/procurementManagement/invoiceEntry";
|
import PageHeader from "@/components/PageHeader.vue";
|
import FooterButtons from "@/components/FooterButtons.vue";
|
|
const userStore = useUserStore();
|
|
// 列表与查询
|
const ledgerList = ref([]);
|
const total = ref(0);
|
const page = reactive({ current: -1, size: -1 });
|
const searchForm = reactive({
|
supplierName: "",
|
});
|
|
const currentId = ref("");
|
const fileList = ref([]); // 行上传或通用上传列表
|
const uploadRef = ref();
|
const uploadUrl = config.baseUrl + "/invoiceLedger/uploadFile";
|
|
// 行上传弹窗
|
const showUpload = ref(false);
|
|
// 附件查看
|
const showFileSheet = ref(false);
|
const fileActions = ref([]);
|
let currentFilesToOpen = [];
|
|
const formatAmount = val => {
|
if (val === undefined || val === null || val === "") return "0.00";
|
const num = Number(val);
|
if (Number.isNaN(num)) return "0.00";
|
return num.toFixed(2);
|
};
|
const formatDateTime = val => {
|
if (!val) return "";
|
return dayjs(val).format("YYYY-MM-DD HH:mm:ss");
|
};
|
|
const goBack = () => {
|
uni.navigateBack();
|
};
|
|
const handleQuery = () => {
|
getList();
|
};
|
|
const getList = async () => {
|
try {
|
uni.showLoading({
|
title: "加载中...",
|
});
|
const res = await productRecordPage({ ...searchForm, ...page });
|
// 兼容不同返回结构
|
const records = res?.data?.records || res?.records || res?.data || [];
|
const totalVal = res?.data?.total || res?.total || records.length || 0;
|
ledgerList.value = records;
|
total.value = totalVal;
|
uni.hideLoading();
|
} catch (e) {
|
uni.hideLoading();
|
showToast("获取列表失败");
|
}
|
};
|
|
// 编辑逻辑改为跳转新页面
|
const openEdit = row => {
|
try {
|
uni.setStorageSync("invoiceLedgerEditRow", JSON.stringify(row));
|
uni.navigateTo({
|
url: "/pages/procurementManagement/procurementInvoiceLedger/detail",
|
});
|
} catch (e) {
|
showToast("跳转失败");
|
}
|
};
|
|
// 删除
|
const handleDelete = row => {
|
let ids = [];
|
ids.push(row.id);
|
console.log(ids);
|
uni.showModal({
|
title: "删除确认",
|
content: "该发票台账将被删除,是否确认删除?",
|
success: async res => {
|
if (res.confirm) {
|
try {
|
uni.showLoading({
|
title: "处理中...",
|
});
|
await delRegistration(ids);
|
uni.hideLoading();
|
showToast("删除成功");
|
await getList();
|
} catch (e) {
|
uni.hideLoading();
|
showToast("删除失败,请重试");
|
}
|
}
|
},
|
});
|
};
|
|
// 行上传
|
const openUpload = row => {
|
currentId.value = row.id;
|
fileList.value = [];
|
showUpload.value = true;
|
};
|
const confirmUpload = async () => {
|
try {
|
const payload = { fileList: fileList.value, id: currentId.value };
|
uni.showLoading({
|
title: "提交中...",
|
});
|
await commitFile(payload);
|
uni.hideLoading();
|
showToast("提交成功");
|
showUpload.value = false;
|
fileList.value = [];
|
currentId.value = "";
|
getList();
|
} catch (e) {
|
uni.hideLoading();
|
showToast("提交失败,请重试");
|
}
|
};
|
|
// 上传相关
|
const beforeReadPdf = file => {
|
// 兼容多文件
|
const files = Array.isArray(file) ? file : [file];
|
for (const f of files) {
|
const sizeOk = f.size <= 10 * 1024 * 1024;
|
const ext = (f.name || "").split(".").pop()?.toLowerCase();
|
if (ext !== "pdf") {
|
showToast("仅支持pdf文件");
|
return false;
|
}
|
if (!sizeOk) {
|
showToast("上传文件大小不能超过10MB");
|
return false;
|
}
|
}
|
return true;
|
};
|
|
// uview-plus 的上传成功回调
|
const onUploadSuccess = (res, file) => {
|
try {
|
const data = JSON.parse(res.data || "{}");
|
if (data.code === 200) {
|
fileList.value.push(data.data);
|
showToast("上传成功");
|
} else {
|
showToast("上传失败: " + (data.msg || "未知错误"));
|
}
|
} catch (err) {
|
showToast("上传失败");
|
}
|
};
|
|
// uview-plus 的上传失败回调
|
const onUploadError = err => {
|
showToast("上传失败");
|
};
|
|
const removeUploaded = index => {
|
fileList.value.splice(index, 1);
|
};
|
|
const getFileNameFromUrl = url => {
|
try {
|
if (!url) return "";
|
return decodeURIComponent(url.split("/").pop());
|
} catch (e) {
|
return url;
|
}
|
};
|
|
// 附件查看
|
const openFileActions = commonFiles => {
|
currentFilesToOpen = commonFiles || [];
|
fileActions.value = (commonFiles || []).map((f, idx) => ({
|
title: getFileNameFromUrl(f.url || ""),
|
index: idx,
|
}));
|
showFileSheet.value = true;
|
};
|
const onSelectFile = async action => {
|
try {
|
const item = currentFilesToOpen[action.index];
|
if (!item || !item.url) return;
|
uni.showLoading({
|
title: "下载中...",
|
});
|
uni.downloadFile({
|
url: item.url,
|
success: res => {
|
uni.hideLoading();
|
if (res.statusCode === 200) {
|
uni.openDocument({ filePath: res.tempFilePath });
|
} else {
|
showToast("下载失败");
|
}
|
},
|
fail: () => {
|
uni.hideLoading();
|
showToast("下载失败");
|
},
|
});
|
} catch (e) {
|
uni.hideLoading();
|
showToast("打开失败");
|
}
|
};
|
|
onShow(() => {
|
getList();
|
});
|
</script>
|
|
<style scoped lang="scss">
|
@import "@/styles/procurement-common.scss";
|
|
// 来票台账特有样式(所有样式都已包含在公共样式中)
|
</style>
|