diff --git a/doc/sql/fund_proj_init.sql b/doc/sql/fund_proj_init.sql
index eed0d30..eaef1e0 100644
--- a/doc/sql/fund_proj_init.sql
+++ b/doc/sql/fund_proj_init.sql
@@ -19,6 +19,7 @@ CREATE TABLE IF NOT EXISTS project (
project_code VARCHAR(64) NOT NULL COMMENT '项目编码',
project_name VARCHAR(128) NOT NULL COMMENT '项目名称',
customer_id VARCHAR(32) NOT NULL COMMENT '客户ID',
+ customer_name VARCHAR(128) COMMENT '客户名称',
project_type VARCHAR(32) NOT NULL COMMENT '项目类型',
budget_amount DECIMAL(18,2) COMMENT '预算金额',
start_date DATE COMMENT '开始日期',
diff --git a/fund-admin/src/api/expense.ts b/fund-admin/src/api/expense.ts
index 72061b7..61cf246 100644
--- a/fund-admin/src/api/expense.ts
+++ b/fund-admin/src/api/expense.ts
@@ -13,20 +13,20 @@ export function createExpenseType(data: any) {
return request.post('/exp/expense-type', data)
}
-export function updateExpenseType(id: number, data: any) {
+export function updateExpenseType(id: string, data: any) {
return request.put(`/exp/expense-type/${id}`, data)
}
-export function deleteExpenseType(id: number) {
+export function deleteExpenseType(id: string) {
return request.delete(`/exp/expense-type/${id}`)
}
// 支出管理
-export function getExpenseList(params: { pageNum: number; pageSize: number; title?: string; expenseType?: number; approvalStatus?: number; payStatus?: number }) {
+export function getExpenseList(params: { pageNum: number; pageSize: number; title?: string; expenseType?: string; approvalStatus?: number; payStatus?: number }) {
return request.get('/exp/expense/page', { params })
}
-export function getExpenseById(id: number) {
+export function getExpenseById(id: string) {
return request.get(`/exp/expense/${id}`)
}
@@ -34,49 +34,49 @@ export function createExpense(data: any) {
return request.post('/exp/expense', data)
}
-export function updateExpense(id: number, data: any) {
+export function updateExpense(id: string, data: any) {
return request.put(`/exp/expense/${id}`, data)
}
-export function deleteExpense(id: number) {
+export function deleteExpense(id: string) {
return request.delete(`/exp/expense/${id}`)
}
// 审批流程
-export function submitExpense(id: number) {
+export function submitExpense(id: string) {
return request.post(`/exp/expense/${id}/submit`)
}
-export function withdrawExpense(id: number) {
+export function withdrawExpense(id: string) {
return request.post(`/exp/expense/${id}/withdraw`)
}
-export function approveExpense(id: number, comment: string) {
+export function approveExpense(id: string, comment: string) {
return request.put(`/exp/expense/${id}/approve?comment=${encodeURIComponent(comment)}`)
}
-export function rejectExpense(id: number, comment: string) {
+export function rejectExpense(id: string, comment: string) {
return request.put(`/exp/expense/${id}/reject?comment=${encodeURIComponent(comment)}`)
}
-export function confirmPayExpense(id: number, payChannel: string, payVoucher?: string) {
+export function confirmPayExpense(id: string, payChannel: string, payVoucher?: string) {
return request.put(`/exp/expense/${id}/confirm-pay?payChannel=${payChannel}&payVoucher=${payVoucher || ''}`)
}
// 导出支出明细
-export function exportExpense(params?: { title?: string; expenseType?: number; approvalStatus?: number; payStatus?: number }) {
+export function exportExpense(params?: { title?: string; expenseType?: string; approvalStatus?: number; payStatus?: number }) {
const baseUrl = import.meta.env.VITE_API_URL || ''
const token = localStorage.getItem('token')
const tenantId = localStorage.getItem('tenantId') || '1'
const queryParams = new URLSearchParams()
if (params?.title) queryParams.append('title', params.title)
- if (params?.expenseType) queryParams.append('expenseType', String(params.expenseType))
+ if (params?.expenseType) queryParams.append('expenseType', params.expenseType)
if (params?.approvalStatus !== undefined) queryParams.append('approvalStatus', String(params.approvalStatus))
if (params?.payStatus !== undefined) queryParams.append('payStatus', String(params.payStatus))
const queryString = queryParams.toString()
- const url = `${baseUrl}/exp/expense/export${queryString ? '?' + queryString : ''}`
+ const url = `${baseUrl}/fund/exp/expense/export${queryString ? '?' + queryString : ''}`
return fetch(url, {
headers: {
diff --git a/fund-admin/src/api/file.ts b/fund-admin/src/api/file.ts
index 4692408..839fd96 100644
--- a/fund-admin/src/api/file.ts
+++ b/fund-admin/src/api/file.ts
@@ -1,11 +1,11 @@
import { request } from './request'
// 文件上传
-export function uploadFile(file: File, businessType?: string, businessId?: number, description?: string) {
+export function uploadFile(file: File, businessType?: string, businessId?: string, description?: string) {
const formData = new FormData()
formData.append('file', file)
if (businessType) formData.append('businessType', businessType)
- if (businessId) formData.append('businessId', String(businessId))
+ if (businessId) formData.append('businessId', businessId)
if (description) formData.append('description', description)
return request.post('/file/upload', formData, {
@@ -16,26 +16,26 @@ export function uploadFile(file: File, businessType?: string, businessId?: numbe
}
// 获取文件列表
-export function getFileList(params: { pageNum: number; pageSize: number; businessType?: string; businessId?: number; fileType?: string }) {
+export function getFileList(params: { pageNum: number; pageSize: number; businessType?: string; businessId?: string; fileType?: string }) {
return request.get('/file/page', { params })
}
// 根据业务查询文件
-export function getFilesByBusiness(businessType: string, businessId: number) {
+export function getFilesByBusiness(businessType: string, businessId: string) {
return request.get('/file/list', { params: { businessType, businessId } })
}
// 获取文件详情
-export function getFileById(id: number) {
+export function getFileById(id: string) {
return request.get(`/file/${id}`)
}
// 删除文件
-export function deleteFile(id: number) {
+export function deleteFile(id: string) {
return request.delete(`/file/${id}`)
}
// 获取文件下载URL
export function getFileDownloadUrl(filePath: string) {
- return `/file/download/${filePath}`
+ return `/fund/file/download/${filePath}`
}
diff --git a/fund-admin/src/api/project.ts b/fund-admin/src/api/project.ts
index f1f2d2f..365b350 100644
--- a/fund-admin/src/api/project.ts
+++ b/fund-admin/src/api/project.ts
@@ -4,7 +4,7 @@ export function getProjectList(params: { pageNum: number; pageSize: number; proj
return request.get('/project/page', { params })
}
-export function getProjectById(id: number) {
+export function getProjectById(id: string) {
return request.get(`/project/${id}`)
}
@@ -12,11 +12,11 @@ export function createProject(data: any) {
return request.post('/project', data)
}
-export function updateProject(id: number, data: any) {
+export function updateProject(id: string, data: any) {
return request.put(`/project/${id}`, data)
}
-export function deleteProject(id: number) {
+export function deleteProject(id: string) {
return request.delete(`/project/${id}`)
}
@@ -25,7 +25,7 @@ export function getRequirementList(params: { pageNum: number; pageSize: number;
return request.get('/requirement/page', { params })
}
-export function getRequirementById(id: number) {
+export function getRequirementById(id: string) {
return request.get(`/requirement/${id}`)
}
@@ -33,10 +33,10 @@ export function createRequirement(data: any) {
return request.post('/requirement', data)
}
-export function updateRequirement(id: number, data: any) {
+export function updateRequirement(id: string, data: any) {
return request.put(`/requirement/${id}`, data)
}
-export function deleteRequirement(id: number) {
+export function deleteRequirement(id: string) {
return request.delete(`/requirement/${id}`)
}
diff --git a/fund-admin/src/views/customer/contact.vue b/fund-admin/src/views/customer/contact.vue
index 1e6d90f..701964c 100644
--- a/fund-admin/src/views/customer/contact.vue
+++ b/fund-admin/src/views/customer/contact.vue
@@ -70,22 +70,18 @@
-
-
+
+
-
-
-
-
-
+
-
-
+
+
@@ -126,15 +122,15 @@ const dialogTitle = ref('新增联系人')
const formRef = ref()
const form = reactive({
- contactId: null as number | null,
+ id: null as string | null,
customerId: customerId.value,
contactName: '',
position: '',
phone: '',
email: '',
- wechat: '',
- isPrimary: false,
- remarks: ''
+ isPrimary: 0,
+ status: 1,
+ remark: ''
})
const rules = reactive({
@@ -210,8 +206,8 @@ const handleSubmit = async () => {
submitLoading.value = true
try {
- if (form.contactId) {
- await updateContact(form.contactId, form)
+ if (form.id) {
+ await updateContact(form.id, form)
ElMessage.success('更新成功')
} else {
await createContact(form)
@@ -228,15 +224,15 @@ const handleSubmit = async () => {
}
const resetForm = () => {
- form.contactId = null
+ form.id = null
form.customerId = customerId.value
form.contactName = ''
form.position = ''
form.phone = ''
form.email = ''
- form.wechat = ''
- form.isPrimary = false
- form.remarks = ''
+ form.isPrimary = 0
+ form.status = 1
+ form.remark = ''
formRef.value?.clearValidate()
}
diff --git a/fund-admin/src/views/expense/index.vue b/fund-admin/src/views/expense/index.vue
index c00237d..fd74a39 100644
--- a/fund-admin/src/views/expense/index.vue
+++ b/fund-admin/src/views/expense/index.vue
@@ -6,12 +6,12 @@
-
+
@@ -44,7 +44,7 @@
-
+
@@ -57,20 +57,20 @@
- 草稿
- 待审批
- 已通过
- 已拒绝
+ 待审批
+ 审批中
+ 已通过
+ 已拒绝
已撤回
- 未支付
+ 未支付
已支付
-
+
@@ -80,10 +80,10 @@
详情
- 编辑
- 提交
- 审批
- 删除
+ 编辑
+ 提交
+ 审批
+ 删除
@@ -115,13 +115,13 @@
-
-
+
+
@@ -134,9 +134,9 @@
@@ -156,22 +156,29 @@
-
+
-
-
+
+
+
+
-
-
+
+
-
-
+
+
@@ -286,7 +293,7 @@ import { getExpenseTypeTree } from '@/api/expense'
import { getProjectList } from '@/api/project'
// 文件上传相关
-const uploadUrl = '/file/api/v1/file/upload'
+const uploadUrl = '/fund/file/upload'
const uploadHeaders = {
Authorization: `Bearer ${localStorage.getItem('token') || ''}`,
'X-Tenant-Id': localStorage.getItem('tenantId') || '1'
@@ -305,7 +312,7 @@ const queryParams = reactive({
pageNum: 1,
pageSize: 10,
title: '',
- expenseTypeId: null as number | null,
+ expenseType: null as string | null,
approvalStatus: '',
payStatus: ''
})
@@ -315,32 +322,30 @@ const dialogTitle = ref('新增支出')
const formRef = ref()
const form = reactive({
- expenseId: null as number | null,
+ id: null as string | null,
title: '',
- expenseTypeId: null as number | null,
- projectId: null as number | null,
+ expenseType: null as string | null,
+ projectId: null as string | null,
amount: 0,
payeeName: '',
expenseDate: '',
- applicant: '',
- description: '',
- remarks: '',
+ purpose: '',
+ remark: '',
attachments: ''
})
const rules = reactive({
title: [{ required: true, message: '请输入支出标题', trigger: 'blur' }],
- expenseTypeId: [{ required: true, message: '请选择支出类型', trigger: 'change' }],
+ expenseType: [{ required: true, message: '请选择支出类型', trigger: 'change' }],
amount: [{ required: true, message: '请输入支出金额', trigger: 'blur' }],
payeeName: [{ required: true, message: '请输入收款单位', trigger: 'blur' }],
- expenseDate: [{ required: true, message: '请选择支出日期', trigger: 'change' }],
- applicant: [{ required: true, message: '请输入申请人', trigger: 'blur' }]
+ expenseDate: [{ required: true, message: '请选择支出日期', trigger: 'change' }]
})
const approvalVisible = ref(false)
const approvalData = ref({})
const approvalForm = reactive({
- expenseId: null as number | null,
+ expenseId: null as string | null,
comment: ''
})
@@ -351,8 +356,8 @@ const detailData = ref({})
const handleUploadSuccess = (response: any, _file: any, fileListVal: any[]) => {
if (response.code === 200 || response.code === 0) {
const urls = fileListVal
- .filter(f => f.response?.data?.filePath || f.url)
- .map(f => f.response?.data?.filePath || f.url)
+ .filter(f => f.response?.data?.fileUrl || f.url)
+ .map(f => f.response?.data?.fileUrl || f.url)
form.attachments = urls.join(',')
ElMessage.success('上传成功')
} else {
@@ -368,8 +373,8 @@ const handleUploadError = () => {
// 移除文件
const handleUploadRemove = (_file: any, fileListVal: any[]) => {
const urls = fileListVal
- .filter(f => f.response?.data?.filePath || f.url)
- .map(f => f.response?.data?.filePath || f.url)
+ .filter(f => f.response?.data?.fileUrl || f.url)
+ .map(f => f.response?.data?.fileUrl || f.url)
form.attachments = urls.join(',')
}
@@ -377,7 +382,7 @@ const handleUploadRemove = (_file: any, fileListVal: any[]) => {
const getFileUrl = (path: string) => {
if (!path) return '#'
if (path.startsWith('http')) return path
- return `/file/api/v1/file/download/${path}`
+ return `/fund/file/download/${path}`
}
// 递归展平树形数据
@@ -434,7 +439,7 @@ const handleSearch = () => {
const handleReset = () => {
queryParams.title = ''
- queryParams.expenseTypeId = null
+ queryParams.expenseType = null
queryParams.approvalStatus = ''
queryParams.payStatus = ''
queryParams.pageNum = 1
@@ -474,7 +479,7 @@ const handleSubmit = (row: any) => {
type: 'warning'
}).then(async () => {
try {
- await submitExpense(row.expenseId)
+ await submitExpense(row.id)
ElMessage.success('提交成功')
fetchData()
} catch (e) {
@@ -485,7 +490,7 @@ const handleSubmit = (row: any) => {
const handleApprove = (row: any) => {
approvalData.value = row
- approvalForm.expenseId = row.expenseId
+ approvalForm.expenseId = row.id
approvalForm.comment = ''
approvalVisible.value = true
}
@@ -523,7 +528,7 @@ const handleDelete = (row: any) => {
type: 'warning'
}).then(async () => {
try {
- await deleteExpense(row.expenseId)
+ await deleteExpense(row.id)
ElMessage.success('删除成功')
fetchData()
} catch (e) {
@@ -539,8 +544,8 @@ const handleSaveExpense = async () => {
submitLoading.value = true
try {
- if (form.expenseId) {
- await updateExpense(form.expenseId, form)
+ if (form.id) {
+ await updateExpense(form.id, form)
ElMessage.success('更新成功')
} else {
await createExpense(form)
@@ -557,16 +562,15 @@ const handleSaveExpense = async () => {
}
const resetForm = () => {
- form.expenseId = null
+ form.id = null
form.title = ''
- form.expenseTypeId = null
+ form.expenseType = null
form.projectId = null
form.amount = 0
form.payeeName = ''
form.expenseDate = ''
- form.applicant = ''
- form.description = ''
- form.remarks = ''
+ form.purpose = ''
+ form.remark = ''
form.attachments = ''
fileList.value = []
formRef.value?.clearValidate()
@@ -578,7 +582,7 @@ const handleExport = async () => {
try {
const params: any = {}
if (queryParams.title) params.title = queryParams.title
- if (queryParams.expenseTypeId) params.expenseType = queryParams.expenseTypeId
+ if (queryParams.expenseType) params.expenseType = queryParams.expenseType
if (queryParams.approvalStatus) params.approvalStatus = parseInt(queryParams.approvalStatus)
if (queryParams.payStatus) params.payStatus = parseInt(queryParams.payStatus)
diff --git a/fund-admin/src/views/project/index.vue b/fund-admin/src/views/project/index.vue
index 954ae5d..a7e58b2 100644
--- a/fund-admin/src/views/project/index.vue
+++ b/fund-admin/src/views/project/index.vue
@@ -105,8 +105,13 @@
-
-
+
+
+
+
+
+
+
@@ -131,23 +136,14 @@
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
+
+
@@ -210,26 +206,23 @@ const dialogTitle = ref('新增项目')
const formRef = ref()
const form = reactive({
- projectId: null as number | null,
+ id: null as string | null,
projectCode: '',
projectName: '',
- customerId: null as number | null,
- contractAmount: 0,
+ customerId: null as string | null,
+ projectType: '',
+ budgetAmount: 0,
startDate: '',
endDate: '',
projectManager: '',
- projectStatus: 'PENDING',
- description: '',
- remarks: ''
+ remark: ''
})
const rules = reactive({
projectCode: [{ required: true, message: '请输入项目编号', trigger: 'blur' }],
projectName: [{ required: true, message: '请输入项目名称', trigger: 'blur' }],
customerId: [{ required: true, message: '请选择客户', trigger: 'change' }],
- contractAmount: [{ required: true, message: '请输入合同金额', trigger: 'blur' }],
- startDate: [{ required: true, message: '请选择开始日期', trigger: 'change' }],
- projectStatus: [{ required: true, message: '请选择项目状态', trigger: 'change' }]
+ projectType: [{ required: true, message: '请选择项目类型', trigger: 'change' }]
})
const detailVisible = ref(false)
@@ -310,8 +303,8 @@ const handleSubmit = async () => {
submitLoading.value = true
try {
- if (form.projectId) {
- await updateProject(form.projectId, form)
+ if (form.id) {
+ await updateProject(form.id, form)
ElMessage.success('更新成功')
} else {
await createProject(form)
@@ -328,17 +321,16 @@ const handleSubmit = async () => {
}
const resetForm = () => {
- form.projectId = null
+ form.id = null
form.projectCode = ''
form.projectName = ''
form.customerId = null
- form.contractAmount = 0
+ form.projectType = ''
+ form.budgetAmount = 0
form.startDate = ''
form.endDate = ''
form.projectManager = ''
- form.projectStatus = 'PENDING'
- form.description = ''
- form.remarks = ''
+ form.remark = ''
formRef.value?.clearValidate()
}
diff --git a/fund-admin/src/views/project/requirement.vue b/fund-admin/src/views/project/requirement.vue
index 5fa4a90..9be3859 100644
--- a/fund-admin/src/views/project/requirement.vue
+++ b/fund-admin/src/views/project/requirement.vue
@@ -312,7 +312,7 @@ import { getProjectList } from '@/api/project'
import { getCustomerList } from '@/api/customer'
// 文件上传相关
-const uploadUrl = '/file/api/v1/file/upload'
+const uploadUrl = '/fund/file/upload'
const uploadHeaders = {
Authorization: `Bearer ${localStorage.getItem('token') || ''}`,
'X-Tenant-Id': localStorage.getItem('tenantId') || '1'
@@ -380,8 +380,8 @@ const handleUploadSuccess = (response: any, _file: any, fileListVal: any[]) => {
if (response.code === 200 || response.code === 0) {
// 保存附件URL(多文件用逗号分隔)
const urls = fileListVal
- .filter(f => f.response?.data?.filePath || f.url)
- .map(f => f.response?.data?.filePath || f.url)
+ .filter(f => f.response?.data?.fileUrl || f.url)
+ .map(f => f.response?.data?.fileUrl || f.url)
form.attachmentUrl = urls.join(',')
ElMessage.success('上传成功')
} else {
@@ -397,8 +397,8 @@ const handleUploadError = () => {
// 移除文件
const handleUploadRemove = (_file: any, fileListVal: any[]) => {
const urls = fileListVal
- .filter(f => f.response?.data?.filePath || f.url)
- .map(f => f.response?.data?.filePath || f.url)
+ .filter(f => f.response?.data?.fileUrl || f.url)
+ .map(f => f.response?.data?.fileUrl || f.url)
form.attachmentUrl = urls.join(',')
}
@@ -406,7 +406,7 @@ const handleUploadRemove = (_file: any, fileListVal: any[]) => {
const getFileUrl = (path: string) => {
if (!path) return '#'
if (path.startsWith('http')) return path
- return `/file/api/v1/file/download/${path}`
+ return `/fund/file/download/${path}`
}
const fetchCustomers = async () => {
diff --git a/fund-admin/src/views/receivable/index.vue b/fund-admin/src/views/receivable/index.vue
index 4fc07c2..6b0b01b 100644
--- a/fund-admin/src/views/receivable/index.vue
+++ b/fund-admin/src/views/receivable/index.vue
@@ -92,8 +92,8 @@
-
-
+
+
@@ -124,35 +124,19 @@
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -298,23 +282,22 @@ const dialogTitle = ref('新增应收款')
const formRef = ref()
const form = reactive({
- receivableId: null as number | null,
- receivableCode: '',
- projectId: null as number | null,
- customerId: null as number | null,
- totalAmount: 0,
- dueDate: '',
- receiptStatus: 'UNPAID',
- description: '',
- remarks: ''
+ id: null as string | null,
+ projectId: null as string | null,
+ customerId: null as string | null,
+ receivableAmount: 0,
+ receivableDate: '',
+ paymentDueDate: '',
+ paymentMethod: '',
+ bankAccount: '',
+ remark: ''
})
const rules = reactive({
- receivableCode: [{ required: true, message: '请输入应收款编号', trigger: 'blur' }],
projectId: [{ required: true, message: '请选择关联项目', trigger: 'change' }],
customerId: [{ required: true, message: '请选择客户', trigger: 'change' }],
- totalAmount: [{ required: true, message: '请输入应收金额', trigger: 'blur' }],
- dueDate: [{ required: true, message: '请选择应收日期', trigger: 'change' }]
+ receivableAmount: [{ required: true, message: '请输入应收金额', trigger: 'blur' }],
+ receivableDate: [{ required: true, message: '请选择应收日期', trigger: 'change' }]
})
const receiptVisible = ref(false)
@@ -473,8 +456,8 @@ const handleSubmit = async () => {
submitLoading.value = true
try {
- if (form.receivableId) {
- await updateReceivable(form.receivableId, form)
+ if (form.id) {
+ await updateReceivable(form.id, form)
ElMessage.success('更新成功')
} else {
await createReceivable(form)
@@ -491,15 +474,15 @@ const handleSubmit = async () => {
}
const resetForm = () => {
- form.receivableId = null
- form.receivableCode = ''
+ form.id = null
form.projectId = null
form.customerId = null
- form.totalAmount = 0
- form.dueDate = ''
- form.receiptStatus = 'UNPAID'
- form.description = ''
- form.remarks = ''
+ form.receivableAmount = 0
+ form.receivableDate = ''
+ form.paymentDueDate = ''
+ form.paymentMethod = ''
+ form.bankAccount = ''
+ form.remark = ''
formRef.value?.clearValidate()
}
diff --git a/fund-admin/vite.config.ts b/fund-admin/vite.config.ts
index fe75bc9..84c88fe 100644
--- a/fund-admin/vite.config.ts
+++ b/fund-admin/vite.config.ts
@@ -20,41 +20,11 @@ export default defineConfig(({ mode }) => {
server: {
port: 3000,
proxy: {
- '/auth/': {
- target: 'http://localhost:8100',
- changeOrigin: true
- },
- '/sys/': {
+ // 所有 /fund/ 请求代理到网关,去掉 /fund 前缀
+ '/fund/': {
target: 'http://localhost:8000',
- changeOrigin: true
- },
- '/cust/': {
- target: 'http://localhost:8000',
- changeOrigin: true
- },
- '/proj/': {
- target: 'http://localhost:8000',
- changeOrigin: true
- },
- '/req/': {
- target: 'http://localhost:8000',
- changeOrigin: true
- },
- '/exp/': {
- target: 'http://localhost:8000',
- changeOrigin: true
- },
- '/receipt/': {
- target: 'http://localhost:8000',
- changeOrigin: true
- },
- '/file/': {
- target: 'http://localhost:8000',
- changeOrigin: true
- },
- '/report/': {
- target: 'http://localhost:8000',
- changeOrigin: true
+ changeOrigin: true,
+ rewrite: (path) => path.replace(/^\/fund/, '')
}
}
}
diff --git a/fund-file/src/main/java/com/fundplatform/file/controller/FileController.java b/fund-file/src/main/java/com/fundplatform/file/controller/FileController.java
index 5b3d48c..7ccfe67 100644
--- a/fund-file/src/main/java/com/fundplatform/file/controller/FileController.java
+++ b/fund-file/src/main/java/com/fundplatform/file/controller/FileController.java
@@ -6,6 +6,7 @@ import com.fundplatform.file.data.entity.FileRecord;
import com.fundplatform.file.data.service.FileRecordService;
import com.fundplatform.file.service.CosStorageService;
import com.fundplatform.file.vo.FileRecordVO;
+import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -151,25 +152,43 @@ public class FileController {
/**
* 下载文件
+ * 支持本地文件和COS文件下载
*/
@GetMapping("/download/**")
public void download(HttpServletResponse response,
+ HttpServletRequest httpRequest,
@RequestHeader(value = "X-Tenant-Id", required = false) String tenantId) throws IOException {
- String requestUri = request.getRequestURI();
+ String requestUri = httpRequest.getRequestURI();
String filePath = requestUri.substring(requestUri.indexOf("/download/") + 10);
+
+ log.info("文件下载请求: filePath={}", filePath);
+
+ // 检查是否是COS路径
+ if (filePath.startsWith("cos:")) {
+ // COS文件,重定向到COS URL
+ String cosUrl = filePath.substring(4);
+ response.sendRedirect(cosUrl);
+ return;
+ }
+
+ // 检查是否已经是完整URL
+ if (filePath.startsWith("http://") || filePath.startsWith("https://")) {
+ response.sendRedirect(filePath);
+ return;
+ }
+
+ // 本地文件
String fullPath = uploadPath + "/" + filePath;
-
File file = new File(fullPath);
if (!file.exists()) {
+ log.warn("文件不存在: {}", fullPath);
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ response.setContentType("application/json;charset=UTF-8");
+ response.getWriter().write("{\"code\":404,\"message\":\"文件不存在\"}");
return;
}
- // 查找文件记录
- // 简化处理,直接下载
-
String fileName = file.getName();
- // 尝试还原原始文件名(如果有扩展名的话)
response.setContentType("application/octet-stream");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + URLEncoder.encode(fileName, StandardCharsets.UTF_8) + "\"");
@@ -186,10 +205,6 @@ public class FileController {
}
}
- // 注入HttpServletRequest
- @jakarta.annotation.Resource
- private jakarta.servlet.http.HttpServletRequest request;
-
/**
* 根据ID获取文件信息
*/
diff --git a/fund-mobile/src/views/expense/Add.vue b/fund-mobile/src/views/expense/Add.vue
index 867964e..2ab54d0 100644
--- a/fund-mobile/src/views/expense/Add.vue
+++ b/fund-mobile/src/views/expense/Add.vue
@@ -132,7 +132,7 @@ const onAfterRead = async (file: any) => {
const res: any = await uploadFile(file.file, 'expense', undefined, '支出附件')
// 从响应中获取文件路径
- const filePath = res.data?.filePath || res.data?.url
+ const filePath = res.data?.fileUrl || res.data?.url
if (filePath) {
uploadedAttachments.value.push(filePath)
console.log('文件上传成功:', filePath)
diff --git a/fund-mobile/src/views/expense/List.vue b/fund-mobile/src/views/expense/List.vue
index 176714e..eeb80dd 100644
--- a/fund-mobile/src/views/expense/List.vue
+++ b/fund-mobile/src/views/expense/List.vue
@@ -104,9 +104,18 @@ const getAttachmentCount = (attachments: string) => {
const previewAttachments = (item: any) => {
if (!item.attachments) return
- // 将 base64 字符串转为图片 URL
- const attachmentList = item.attachments.split(',')
- const imageUrls = attachmentList.map((b64: string) => `data:image/jpeg;base64,${b64}`)
+ // 将逗号分隔的URL字符串转为数组
+ const attachmentList = item.attachments.split(',').filter((s: string) => s.trim())
+
+ // 构建图片URL列表
+ const imageUrls = attachmentList.map((url: string) => {
+ // 如果已经是完整URL,直接使用
+ if (url.startsWith('http')) return url
+ // 如果是COS路径
+ if (url.startsWith('cos:')) return url.substring(4)
+ // 否则使用文件下载接口
+ return `/fund/file/download/${url}`
+ })
ImagePreview.show({
images: imageUrls,
diff --git a/fund-mobile/src/views/receivable/Add.vue b/fund-mobile/src/views/receivable/Add.vue
index 58f11a6..a7aa654 100644
--- a/fund-mobile/src/views/receivable/Add.vue
+++ b/fund-mobile/src/views/receivable/Add.vue
@@ -189,7 +189,7 @@ const onSubmit = async () => {
projectId: form.value.projectId,
receivableAmount: parseFloat(form.value.receivableAmount),
receivableDate: form.value.receivableDate,
- description: form.value.description
+ remark: form.value.description
})
showSuccessToast('提交成功')
router.back()
diff --git a/fund-receipt/src/main/java/com/fundplatform/receipt/controller/FundReceiptController.java b/fund-receipt/src/main/java/com/fundplatform/receipt/controller/FundReceiptController.java
index b98bfd8..faec0cf 100644
--- a/fund-receipt/src/main/java/com/fundplatform/receipt/controller/FundReceiptController.java
+++ b/fund-receipt/src/main/java/com/fundplatform/receipt/controller/FundReceiptController.java
@@ -19,7 +19,7 @@ public class FundReceiptController {
}
@PostMapping
- public Result create(@Valid @RequestBody FundReceiptDTO dto) {
+ public Result create(@Valid @RequestBody FundReceiptDTO dto) {
return Result.success(receiptService.createReceipt(dto));
}
@@ -29,7 +29,7 @@ public class FundReceiptController {
}
@GetMapping("/{id}")
- public Result getById(@PathVariable Long id) {
+ public Result getById(@PathVariable String id) {
return Result.success(receiptService.getReceiptById(id));
}
@@ -44,17 +44,17 @@ public class FundReceiptController {
}
@DeleteMapping("/{id}")
- public Result delete(@PathVariable Long id) {
+ public Result delete(@PathVariable String id) {
return Result.success(receiptService.deleteReceipt(id));
}
@PutMapping("/{id}/confirm")
- public Result confirm(@PathVariable Long id) {
+ public Result confirm(@PathVariable String id) {
return Result.success(receiptService.confirm(id));
}
@PutMapping("/{id}/write-off")
- public Result writeOff(@PathVariable Long id) {
+ public Result writeOff(@PathVariable String id) {
return Result.success(receiptService.writeOff(id));
}
}
diff --git a/fund-receipt/src/main/java/com/fundplatform/receipt/controller/ReceivableController.java b/fund-receipt/src/main/java/com/fundplatform/receipt/controller/ReceivableController.java
index e666efe..21301a7 100644
--- a/fund-receipt/src/main/java/com/fundplatform/receipt/controller/ReceivableController.java
+++ b/fund-receipt/src/main/java/com/fundplatform/receipt/controller/ReceivableController.java
@@ -39,7 +39,7 @@ public class ReceivableController {
* 创建应收款
*/
@PostMapping
- public Result create(@Valid @RequestBody ReceivableDTO dto) {
+ public Result create(@Valid @RequestBody ReceivableDTO dto) {
return Result.success(receivableService.createReceivable(dto));
}
@@ -47,7 +47,7 @@ public class ReceivableController {
* 更新应收款(仅待确认状态可修改)
*/
@PutMapping("/{id}")
- public Result update(@PathVariable Long id, @Valid @RequestBody ReceivableDTO dto) {
+ public Result update(@PathVariable String id, @Valid @RequestBody ReceivableDTO dto) {
dto.setId(id);
return Result.success(receivableService.updateReceivable(dto));
}
@@ -56,7 +56,7 @@ public class ReceivableController {
* 根据ID查询应收款
*/
@GetMapping("/{id}")
- public Result getById(@PathVariable Long id) {
+ public Result getById(@PathVariable String id) {
return Result.success(receivableService.getReceivableById(id));
}
@@ -67,8 +67,8 @@ public class ReceivableController {
public Result> page(
@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "10") int pageSize,
- @RequestParam(required = false) Long projectId,
- @RequestParam(required = false) Long customerId,
+ @RequestParam(required = false) String projectId,
+ @RequestParam(required = false) String customerId,
@RequestParam(required = false) String status,
@RequestParam(required = false) Integer confirmStatus) {
return Result.success(receivableService.pageReceivables(pageNum, pageSize, projectId, customerId, status, confirmStatus));
@@ -79,8 +79,8 @@ public class ReceivableController {
*/
@PutMapping("/{id}/confirm")
public Result confirm(
- @PathVariable Long id,
- @RequestHeader(value = "X-User-Id", required = false) Long confirmBy) {
+ @PathVariable String id,
+ @RequestHeader(value = "X-User-Id", required = false) String confirmBy) {
return Result.success(receivableService.confirmReceivable(id, confirmBy));
}
@@ -88,7 +88,7 @@ public class ReceivableController {
* 取消确认
*/
@PutMapping("/{id}/cancel-confirm")
- public Result cancelConfirm(@PathVariable Long id) {
+ public Result cancelConfirm(@PathVariable String id) {
return Result.success(receivableService.cancelConfirm(id));
}
@@ -96,7 +96,7 @@ public class ReceivableController {
* 记录收款
*/
@PostMapping("/{id}/receipt")
- public Result recordReceipt(@PathVariable Long id, @RequestParam BigDecimal amount) {
+ public Result recordReceipt(@PathVariable String id, @RequestParam BigDecimal amount) {
return Result.success(receivableService.recordReceipt(id, amount));
}
@@ -104,7 +104,7 @@ public class ReceivableController {
* 获取应收款的收款记录列表
*/
@GetMapping("/{id}/receipts")
- public Result> getReceipts(@PathVariable Long id) {
+ public Result> getReceipts(@PathVariable String id) {
return Result.success(receivableService.getReceiptsByReceivableId(id));
}
@@ -121,7 +121,7 @@ public class ReceivableController {
* 删除应收款(仅待确认状态可删除)
*/
@DeleteMapping("/{id}")
- public Result delete(@PathVariable Long id) {
+ public Result delete(@PathVariable String id) {
return Result.success(receivableService.deleteReceivable(id));
}
@@ -166,8 +166,8 @@ public class ReceivableController {
*/
@GetMapping("/export")
public void exportExcel(
- @RequestParam(required = false) Long projectId,
- @RequestParam(required = false) Long customerId,
+ @RequestParam(required = false) String projectId,
+ @RequestParam(required = false) String customerId,
@RequestParam(required = false) String status,
@RequestParam(required = false) Integer confirmStatus,
HttpServletResponse response) {