diff --git a/fund-mobile/components.d.ts b/fund-mobile/components.d.ts
index 191b730..3239f8d 100644
--- a/fund-mobile/components.d.ts
+++ b/fund-mobile/components.d.ts
@@ -11,7 +11,11 @@ declare module 'vue' {
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
Tabbar: typeof import('./src/components/Tabbar.vue')['default']
+ VanButton: typeof import('vant/es')['Button']
+ VanCellGroup: typeof import('vant/es')['CellGroup']
VanDatePicker: typeof import('vant/es')['DatePicker']
+ VanField: typeof import('vant/es')['Field']
+ VanForm: typeof import('vant/es')['Form']
VanIcon: typeof import('vant/es')['Icon']
VanList: typeof import('vant/es')['List']
VanNavBar: typeof import('vant/es')['NavBar']
diff --git a/fund-mobile/src/api/index.ts b/fund-mobile/src/api/index.ts
index 7a094cc..8e591bf 100644
--- a/fund-mobile/src/api/index.ts
+++ b/fund-mobile/src/api/index.ts
@@ -16,7 +16,7 @@ export function logout() {
// ===================== 项目管理 =====================
-export function getProjectList(params?: { pageNum: number; pageSize: number; projectName?: string }) {
+export function getProjectList(params?: { pageNum: number; pageSize: number; keyword?: string }) {
return request.get('/project/page', { params })
}
@@ -24,19 +24,45 @@ export function getProjectById(id: number) {
return request.get(`/project/${id}`)
}
+export function createProject(data: any) {
+ return request.post('/project', data)
+}
+
+// ===================== 需求工单管理 =====================
+
+export function getRequirementList(params?: { pageNum: number; pageSize: number; keyword?: string }) {
+ return request.get('/requirement/page', { params })
+}
+
+export function getRequirementById(id: number) {
+ return request.get(`/requirement/${id}`)
+}
+
+export function createRequirement(data: any) {
+ return request.post('/requirement', data)
+}
+
// ===================== 客户管理 =====================
-export function getCustomerList(params?: { pageNum: number; pageSize: number; customerName?: string }) {
+export function getCustomerList(params?: { pageNum: number; pageSize: number; keyword?: string }) {
return request.get('/customer/page', { params })
}
+export function getCustomerById(id: number) {
+ return request.get(`/customer/${id}`)
+}
+
+export function createCustomer(data: any) {
+ return request.post('/customer', data)
+}
+
// ===================== 支出管理 =====================
export function createExpense(data: any) {
return request.post('/exp/expense', data)
}
-export function getExpenseList(params: { pageNum: number; pageSize: number }) {
+export function getExpenseList(params?: { pageNum: number; pageSize: number; title?: string }) {
return request.get('/exp/expense/page', { params })
}
@@ -50,10 +76,18 @@ export function getTodayExpense() {
// ===================== 应收款管理 =====================
-export function getReceivableList(params: { pageNum: number; pageSize: number; status?: string }) {
+export function getReceivableList(params?: { pageNum: number; pageSize: number; status?: string; keyword?: string }) {
return request.get('/receipt/receivable/page', { params })
}
+export function getReceivableById(id: number) {
+ return request.get(`/receipt/receivable/${id}`)
+}
+
+export function createReceivable(data: any) {
+ return request.post('/receipt/receivable', data)
+}
+
export function getUpcomingDueList(daysWithin: number = 7) {
return request.get(`/receipt/receivable/upcoming-due?daysWithin=${daysWithin}`)
}
diff --git a/fund-mobile/src/router/index.ts b/fund-mobile/src/router/index.ts
index a3a3958..fa72a96 100644
--- a/fund-mobile/src/router/index.ts
+++ b/fund-mobile/src/router/index.ts
@@ -10,36 +10,79 @@ const router = createRouter({
component: () => import('@/views/Home.vue'),
meta: { title: '首页', requiresAuth: true }
},
+ // 需求工单
+ {
+ path: '/requirement',
+ name: 'RequirementList',
+ component: () => import('@/views/requirement/List.vue'),
+ meta: { title: '需求工单', requiresAuth: true }
+ },
+ {
+ path: '/requirement/add',
+ name: 'RequirementAdd',
+ component: () => import('@/views/requirement/Add.vue'),
+ meta: { title: '新增需求工单', requiresAuth: true }
+ },
+ // 支出管理
+ {
+ path: '/expense',
+ name: 'ExpenseList',
+ component: () => import('@/views/expense/List.vue'),
+ meta: { title: '支出管理', requiresAuth: true }
+ },
{
path: '/expense/add',
name: 'ExpenseAdd',
component: () => import('@/views/expense/Add.vue'),
meta: { title: '新增支出', requiresAuth: true }
},
+ // 应收款管理
{
path: '/receivable',
name: 'ReceivableList',
component: () => import('@/views/receivable/List.vue'),
- meta: { title: '应收款列表', requiresAuth: true }
+ meta: { title: '应收款管理', requiresAuth: true }
},
+ {
+ path: '/receivable/add',
+ name: 'ReceivableAdd',
+ component: () => import('@/views/receivable/Add.vue'),
+ meta: { title: '新增应收款', requiresAuth: true }
+ },
+ // 项目管理
{
path: '/project',
name: 'ProjectList',
component: () => import('@/views/project/List.vue'),
- meta: { title: '项目列表', requiresAuth: true }
+ meta: { title: '项目管理', requiresAuth: true }
},
+ {
+ path: '/project/add',
+ name: 'ProjectAdd',
+ component: () => import('@/views/project/Add.vue'),
+ meta: { title: '新增项目', requiresAuth: true }
+ },
+ // 客户管理
{
path: '/customer',
name: 'CustomerList',
component: () => import('@/views/customer/List.vue'),
- meta: { title: '客户列表', requiresAuth: true }
+ meta: { title: '客户管理', requiresAuth: true }
},
+ {
+ path: '/customer/add',
+ name: 'CustomerAdd',
+ component: () => import('@/views/customer/Add.vue'),
+ meta: { title: '新增客户', requiresAuth: true }
+ },
+ // 我的
{
path: '/my',
name: 'My',
component: () => import('@/views/my/Index.vue'),
meta: { title: '我的', requiresAuth: true }
},
+ // 登录
{
path: '/login',
name: 'Login',
diff --git a/fund-mobile/src/views/Home.vue b/fund-mobile/src/views/Home.vue
index 188a3dc..84564e6 100644
--- a/fund-mobile/src/views/Home.vue
+++ b/fund-mobile/src/views/Home.vue
@@ -43,41 +43,100 @@
-
+
+
+
-
-
-
-
+
-
-
+
-
+
+
+
@@ -240,23 +299,25 @@ onMounted(() => {
color: var(--mac-text-secondary);
}
+/* 快捷操作样式 */
.quick-card {
+ margin-bottom: 16px;
padding: 20px;
}
.quick-grid {
display: grid;
- grid-template-columns: repeat(3, 1fr);
- gap: 16px;
+ grid-template-columns: repeat(5, 1fr);
+ gap: 8px;
}
.quick-item {
display: flex;
flex-direction: column;
align-items: center;
- padding: 16px 8px;
+ padding: 12px 4px;
background: rgba(0, 0, 0, 0.02);
- border-radius: 16px;
+ border-radius: 12px;
cursor: pointer;
transition: all 0.2s ease;
}
@@ -267,22 +328,121 @@ onMounted(() => {
}
.quick-icon {
- width: 48px;
- height: 48px;
- border-radius: 14px;
- background: linear-gradient(135deg, var(--mac-primary), #5AC8FA);
+ width: 40px;
+ height: 40px;
+ border-radius: 12px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 20px;
+ color: #fff;
+ margin-bottom: 8px;
+}
+
+.quick-icon.requirement {
+ background: linear-gradient(135deg, #5856D6, #AF52DE);
+}
+
+.quick-icon.receivable {
+ background: linear-gradient(135deg, #34C759, #30D158);
+}
+
+.quick-icon.expense {
+ background: linear-gradient(135deg, #FF3B30, #FF453A);
+}
+
+.quick-icon.project {
+ background: linear-gradient(135deg, #007AFF, #5AC8FA);
+}
+
+.quick-icon.customer {
+ background: linear-gradient(135deg, #FF9500, #FF9F0A);
+}
+
+.quick-text {
+ font-size: 11px;
+ font-weight: 500;
+ color: var(--mac-text);
+ text-align: center;
+}
+
+/* 业务服务样式 */
+.service-card {
+ padding: 20px;
+ margin-bottom: 16px;
+}
+
+.service-list {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+}
+
+.service-item {
+ display: flex;
+ align-items: center;
+ padding: 14px;
+ background: rgba(0, 0, 0, 0.02);
+ border-radius: 12px;
+ cursor: pointer;
+ transition: all 0.2s ease;
+}
+
+.service-item:active {
+ background: rgba(0, 122, 255, 0.08);
+}
+
+.service-icon {
+ width: 44px;
+ height: 44px;
+ border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
font-size: 22px;
color: #fff;
- margin-bottom: 10px;
- box-shadow: 0 4px 12px rgba(0, 122, 255, 0.25);
+ margin-right: 14px;
+ flex-shrink: 0;
}
-.quick-text {
- font-size: 13px;
- font-weight: 500;
+.service-icon.requirement {
+ background: linear-gradient(135deg, #5856D6, #AF52DE);
+}
+
+.service-icon.receivable {
+ background: linear-gradient(135deg, #34C759, #30D158);
+}
+
+.service-icon.expense {
+ background: linear-gradient(135deg, #FF3B30, #FF453A);
+}
+
+.service-icon.project {
+ background: linear-gradient(135deg, #007AFF, #5AC8FA);
+}
+
+.service-icon.customer {
+ background: linear-gradient(135deg, #FF9500, #FF9F0A);
+}
+
+.service-content {
+ flex: 1;
+}
+
+.service-name {
+ font-size: 15px;
+ font-weight: 600;
color: var(--mac-text);
+ margin-bottom: 4px;
+}
+
+.service-desc {
+ font-size: 12px;
+ color: var(--mac-text-secondary);
+}
+
+.service-arrow {
+ color: var(--mac-text-secondary);
+ font-size: 14px;
}
diff --git a/fund-mobile/src/views/customer/Add.vue b/fund-mobile/src/views/customer/Add.vue
new file mode 100644
index 0000000..a72903b
--- /dev/null
+++ b/fund-mobile/src/views/customer/Add.vue
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 提交
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fund-mobile/src/views/customer/List.vue b/fund-mobile/src/views/customer/List.vue
index 247ca28..32d59ff 100644
--- a/fund-mobile/src/views/customer/List.vue
+++ b/fund-mobile/src/views/customer/List.vue
@@ -77,7 +77,7 @@ const loadData = async () => {
const res: any = await getCustomerList({
pageNum: pageNum.value,
pageSize,
- customerName: searchText.value || undefined
+ keyword: searchText.value || undefined
})
const records = res.data?.records || []
if (pageNum.value === 1) {
diff --git a/fund-mobile/src/views/expense/List.vue b/fund-mobile/src/views/expense/List.vue
new file mode 100644
index 0000000..40a5f99
--- /dev/null
+++ b/fund-mobile/src/views/expense/List.vue
@@ -0,0 +1,224 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.typeName || '-' }}
+
+
+
+ {{ item.expenseDate }}
+
+
+
+
+ 支出金额
+ ¥{{ item.amount?.toLocaleString() }}
+
+
+ 已支付
+ ¥{{ item.paidAmount?.toLocaleString() }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fund-mobile/src/views/project/Add.vue b/fund-mobile/src/views/project/Add.vue
new file mode 100644
index 0000000..906e00c
--- /dev/null
+++ b/fund-mobile/src/views/project/Add.vue
@@ -0,0 +1,233 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 元
+
+
+
+
+
+ 元
+
+
+
+
+
+
+
+
+
+
+
+
+ 提交
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fund-mobile/src/views/project/List.vue b/fund-mobile/src/views/project/List.vue
index b0c7c4c..8efae3c 100644
--- a/fund-mobile/src/views/project/List.vue
+++ b/fund-mobile/src/views/project/List.vue
@@ -92,7 +92,7 @@ const loadData = async () => {
const res: any = await getProjectList({
pageNum: pageNum.value,
pageSize,
- projectName: searchText.value || undefined
+ keyword: searchText.value || undefined
})
const records = res.data?.records || []
if (pageNum.value === 1) {
diff --git a/fund-mobile/src/views/receivable/Add.vue b/fund-mobile/src/views/receivable/Add.vue
new file mode 100644
index 0000000..be0db92
--- /dev/null
+++ b/fund-mobile/src/views/receivable/Add.vue
@@ -0,0 +1,221 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 元
+
+
+
+
+
+
+
+
+
+
+ 提交
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fund-mobile/src/views/receivable/List.vue b/fund-mobile/src/views/receivable/List.vue
index 7945d92..2d0a23b 100644
--- a/fund-mobile/src/views/receivable/List.vue
+++ b/fund-mobile/src/views/receivable/List.vue
@@ -4,10 +4,15 @@
-
+
+
+
+
+
+
@@ -37,6 +42,11 @@
+
+
+
+
+
@@ -45,6 +55,7 @@ import { ref, onMounted } from 'vue'
import { showToast } from 'vant'
import { getReceivableList } from '@/api'
+const searchText = ref('')
const loading = ref(false)
const refreshing = ref(false)
const finished = ref(false)
@@ -72,20 +83,34 @@ const getStatusName = (status: string) => {
return map[status] || status
}
-const onLoad = async () => {
+const loadData = async () => {
try {
- const res: any = await getReceivableList({ pageNum: pageNum.value, pageSize })
+ const res: any = await getReceivableList({
+ pageNum: pageNum.value,
+ pageSize,
+ keyword: searchText.value || undefined
+ })
const records = res.data?.records || []
- list.value.push(...records)
- loading.value = false
- if (records.length < pageSize) {
- finished.value = true
+ if (pageNum.value === 1) {
+ list.value = records
} else {
- pageNum.value++
+ list.value.push(...records)
}
+ finished.value = records.length < pageSize
+ loading.value = false
} catch (e: any) {
showToast(e.message || '加载失败')
loading.value = false
+ finished.value = true
+ }
+}
+
+const onLoad = () => {
+ if (pageNum.value === 1 && list.value.length === 0) {
+ loadData()
+ } else {
+ pageNum.value++
+ loadData()
}
}
@@ -94,17 +119,25 @@ const onRefresh = () => {
pageNum.value = 1
finished.value = false
refreshing.value = false
- onLoad()
+ loadData()
+}
+
+const handleSearch = () => {
+ pageNum.value = 1
+ finished.value = false
+ list.value = []
+ loadData()
}
onMounted(() => {
- onLoad()
+ loadData()
})
diff --git a/fund-mobile/src/views/requirement/Add.vue b/fund-mobile/src/views/requirement/Add.vue
new file mode 100644
index 0000000..78adda4
--- /dev/null
+++ b/fund-mobile/src/views/requirement/Add.vue
@@ -0,0 +1,209 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 提交
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fund-mobile/src/views/requirement/List.vue b/fund-mobile/src/views/requirement/List.vue
new file mode 100644
index 0000000..73836e1
--- /dev/null
+++ b/fund-mobile/src/views/requirement/List.vue
@@ -0,0 +1,240 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.customerName || '-' }}
+
+
+
+ {{ item.projectName || '-' }}
+
+
+
+
+ 优先级
+ {{ getPriorityText(item.priority) }}
+
+
+ 创建时间
+ {{ item.createTime }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+