2025-10-15

添加金融模块
This commit is contained in:
2025-10-15 17:18:06 +08:00
parent 014479b8d1
commit a0ba35ba5c
9 changed files with 743 additions and 85 deletions

15
src/api/financial.js Normal file
View File

@@ -0,0 +1,15 @@
import {financialRequest} from '@/utils/api'
// 金融相关API
export const financialAPI = {
// 登录
list: (params) => financialRequest.get('/financial/list', {params}),
add: (data) => financialRequest.post('/financial', data),
update: (data) => financialRequest.patch("/financial", data),
delete: (id) => financialRequest.delete(`/financial/${id}`),
getOne: (id) => financialRequest.get(`/financial/${id}`),
}
export default {
financialAPI
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@@ -115,7 +115,7 @@ const editorConfig = {
fontFamily: {
fontFamilyList: [
'黑体', '仿宋', '楷体', '标楷体', '华文仿宋', '华文楷体', '宋体', '微软雅黑',
'Arial', 'Tahoma', 'Verdana', 'Times New Roman', 'Courier New'
// 'Arial', 'Tahoma', 'Verdana', 'Times New Roman', 'Courier New'
]
},
// 配置颜色

View File

@@ -3,131 +3,177 @@
<!-- 侧边栏 -->
<el-aside :width="isCollapse ? '64px' : '200px'" class="sidebar">
<div class="logo">
<img v-if="!isCollapse" src="/logo.svg" alt="Logo" class="logo-img" />
<img v-if="!isCollapse" src="/logo.svg" alt="Logo" class="logo-img"/>
<span v-if="!isCollapse" class="logo-text">项目后台管理</span>
<el-icon v-else class="logo-icon"><Setting /></el-icon>
<el-icon v-else class="logo-icon">
<Setting/>
</el-icon>
</div>
<el-menu
:default-active="$route.path"
:collapse="isCollapse"
:unique-opened="true"
router
class="sidebar-menu"
:default-active="$route.path"
:collapse="isCollapse"
:unique-opened="true"
router
class="sidebar-menu"
>
<el-menu-item index="/dashboard">
<el-icon><Odometer /></el-icon>
<el-icon>
<Odometer/>
</el-icon>
<template #title>仪表盘</template>
</el-menu-item>
<el-menu-item v-if="userStore.isAdmin" index="/users">
<el-icon><User /></el-icon>
<el-icon>
<User/>
</el-icon>
<template #title>用户管理</template>
</el-menu-item>
<el-menu-item v-if="userStore.isAdmin" index="/user-audit">
<el-icon><DocumentChecked /></el-icon>
<el-icon>
<DocumentChecked/>
</el-icon>
<template #title>用户审核</template>
</el-menu-item>
<el-menu-item v-if="userStore.isAdmin" index="/points">
<el-icon><Coin /></el-icon>
<el-icon>
<Coin/>
</el-icon>
<template #title>积分管理</template>
</el-menu-item>
<el-menu-item index="/program">
<el-icon><ProgramSvg /></el-icon>
<el-icon>
<ProgramSvg/>
</el-icon>
<template #title>项目管理</template>
</el-menu-item>
<el-menu-item index="/financial">
<el-icon>
<FinancialSvg/>
</el-icon>
<template #title>金融</template>
</el-menu-item>
<el-menu-item index="/chat">
<el-icon><ChatSvg /></el-icon>
<el-icon>
<ChatSvg/>
</el-icon>
<template #title>聊天室</template>
</el-menu-item>
<el-menu-item v-if="userStore.isAdmin" index="/transfers">
<el-icon><Money /></el-icon>
<el-icon>
<Money/>
</el-icon>
<template #title>转账管理</template>
</el-menu-item>
<el-menu-item v-if="userStore.isAdmin" index="/beans">
<el-icon><Promotion /></el-icon>
<el-icon>
<Promotion/>
</el-icon>
<template #title>融豆管理</template>
</el-menu-item>
<el-menu-item v-if="userStore.isAdmin" index="/projects">
<el-icon><Setting /></el-icon>
<el-icon>
<Setting/>
</el-icon>
<template #title>项目管理</template>
</el-menu-item>
<el-menu-item index="/profile">
<el-icon><UserFilled /></el-icon>
<el-icon>
<UserFilled/>
</el-icon>
<template #title>个人资料</template>
</el-menu-item>
</el-menu>
</el-aside>
<!-- 主内容区 -->
<el-container>
<!-- 顶部导航 -->
<el-header class="header">
<div class="header-left">
<el-button
type="text"
@click="toggleCollapse"
class="collapse-btn"
type="text"
@click="toggleCollapse"
class="collapse-btn"
>
<el-icon><Expand v-if="isCollapse" /><Fold v-else /></el-icon>
<el-icon>
<Expand v-if="isCollapse"/>
<Fold v-else/>
</el-icon>
</el-button>
<el-breadcrumb separator="/" class="breadcrumb">
<el-breadcrumb-item
v-for="item in breadcrumbs"
:key="item.path"
:to="item.path"
v-for="item in breadcrumbs"
:key="item.path"
:to="item.path"
>
{{ item.title }}
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="header-right">
<!-- 全屏按钮 -->
<el-tooltip content="全屏" placement="bottom">
<el-button type="text" @click="toggleFullscreen" class="header-btn">
<el-icon><FullScreen /></el-icon>
<el-icon>
<FullScreen/>
</el-icon>
</el-button>
</el-tooltip>
<!-- 刷新按钮 -->
<el-tooltip content="刷新" placement="bottom">
<el-button type="text" @click="refresh" class="header-btn">
<el-icon><Refresh /></el-icon>
<el-icon>
<Refresh/>
</el-icon>
</el-button>
</el-tooltip>
<!-- 用户菜单 -->
<el-dropdown @command="handleCommand" class="user-dropdown">
<div class="user-info">
<el-avatar :size="32" :src="userStore.user?.avatar">
<el-icon><UserFilled /></el-icon>
<el-icon>
<UserFilled/>
</el-icon>
</el-avatar>
<span class="username">{{ userStore.user?.username }}</span>
<el-icon class="dropdown-icon"><ArrowDown /></el-icon>
<el-icon class="dropdown-icon">
<ArrowDown/>
</el-icon>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="profile">
<el-icon><UserFilled /></el-icon>
<el-icon>
<UserFilled/>
</el-icon>
个人资料
</el-dropdown-item>
<el-dropdown-item command="changePassword">
<el-icon><Lock /></el-icon>
<el-icon>
<Lock/>
</el-icon>
修改密码
</el-dropdown-item>
<el-dropdown-item divided command="logout">
<el-icon><SwitchButton /></el-icon>
<el-icon>
<SwitchButton/>
</el-icon>
退出登录
</el-dropdown-item>
</el-dropdown-menu>
@@ -135,51 +181,51 @@
</el-dropdown>
</div>
</el-header>
<!-- 主内容 -->
<el-main class="main-content">
<transition name="fade" mode="out-in">
<router-view />
<router-view/>
</transition>
</el-main>
</el-container>
</el-container>
<!-- 修改密码对话框 -->
<el-dialog
v-model="passwordDialogVisible"
title="修改密码"
width="400px"
:before-close="handlePasswordDialogClose"
v-model="passwordDialogVisible"
title="修改密码"
width="400px"
:before-close="handlePasswordDialogClose"
>
<el-form
ref="passwordFormRef"
:model="passwordForm"
:rules="passwordRules"
label-width="80px"
ref="passwordFormRef"
:model="passwordForm"
:rules="passwordRules"
label-width="80px"
>
<el-form-item label="当前密码" prop="currentPassword">
<el-input
v-model="passwordForm.currentPassword"
type="password"
placeholder="请输入当前密码"
show-password
v-model="passwordForm.currentPassword"
type="password"
placeholder="请输入当前密码"
show-password
/>
</el-form-item>
<el-form-item label="新密码" prop="newPassword">
<el-input
v-model="passwordForm.newPassword"
type="password"
placeholder="请输入新密码"
show-password
v-model="passwordForm.newPassword"
type="password"
placeholder="请输入新密码"
show-password
/>
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword">
<el-input
v-model="passwordForm.confirmPassword"
type="password"
placeholder="请确认新密码"
show-password
v-model="passwordForm.confirmPassword"
type="password"
placeholder="请确认新密码"
show-password
/>
</el-form-item>
</el-form>
@@ -193,12 +239,13 @@
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useUserStore } from '@/stores/user'
import { ElMessage, ElMessageBox } from 'element-plus'
import {ref, computed, onMounted} from 'vue'
import {useRoute, useRouter} from 'vue-router'
import {useUserStore} from '@/stores/user'
import {ElMessage, ElMessageBox} from 'element-plus'
import ProgramSvg from '@/assets/svg/program.svg'
import ChatSvg from '@/assets/svg/chat.svg'
import FinancialSvg from '@/assets/svg/financial.svg'
import {
Odometer,
User,
@@ -225,6 +272,7 @@ import {
CreditCard,
Bell,
} from '@element-plus/icons-vue'
import Financial from "@/views/Financial.vue";
const route = useRoute()
const router = useRouter()
@@ -252,11 +300,11 @@ const passwordForm = ref({
// 密码验证规则
const passwordRules = {
currentPassword: [
{ required: true, message: '请输入当前密码', trigger: 'blur' }
{required: true, message: '请输入当前密码', trigger: 'blur'}
],
newPassword: [
{ required: true, message: '请输入新密码', trigger: 'blur' },
{ min: 6, message: '密码长度不能少于6位', trigger: 'blur' },
{required: true, message: '请输入新密码', trigger: 'blur'},
{min: 6, message: '密码长度不能少于6位', trigger: 'blur'},
{
pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d@$!%*?&]{6,}$/,
message: '密码必须包含大小写字母和数字',
@@ -264,7 +312,7 @@ const passwordRules = {
}
],
confirmPassword: [
{ required: true, message: '请确认新密码', trigger: 'blur' },
{required: true, message: '请确认新密码', trigger: 'blur'},
{
validator: (rule, value, callback) => {
if (value !== passwordForm.value.newPassword) {
@@ -282,7 +330,7 @@ const passwordRules = {
const breadcrumbs = computed(() => {
const matched = route.matched.filter(item => item.meta && item.meta.title)
const breadcrumbList = []
matched.forEach(item => {
if (item.path !== '/') {
breadcrumbList.push({
@@ -291,7 +339,7 @@ const breadcrumbs = computed(() => {
})
}
})
return breadcrumbList
})
@@ -337,7 +385,7 @@ const handleLogout = async () => {
cancelButtonText: '取消',
type: 'warning'
})
await userStore.logout()
router.push('/login')
} catch (error) {
@@ -349,16 +397,16 @@ const handleLogout = async () => {
const handleChangePassword = async () => {
try {
await passwordFormRef.value.validate()
const result = await userStore.changePassword({
currentPassword: passwordForm.value.currentPassword,
newPassword: passwordForm.value.newPassword
})
if (result.success) {
passwordDialogVisible.value = false
resetPasswordForm()
// 延迟跳转到登录页
setTimeout(() => {
router.push('/login')
@@ -557,11 +605,11 @@ const resetPasswordForm = () => {
z-index: 1000;
height: 100vh;
}
.breadcrumb {
display: none;
}
.username {
display: none;
}

View File

@@ -116,6 +116,15 @@ const routes = [
title: '聊天 - 炬融圈',
icon: 'ChatDotRound'
}
},
{
path: 'financial',
name: 'Financial',
component: () => import('@/views/Financial.vue'),
meta: {
title: '金融 - 炬融圈',
icon: 'financial'
}
}
]
},

View File

@@ -139,6 +139,7 @@ export const midRequest = createRequest(import.meta.env.VITE_UPLOAD_BASE_URL ||
export const programRequest = createRequest(import.meta.env.VITE_UPLOAD_BASE_URL || '/program')
export const groupRequest = createRequest(import.meta.env.VITE_UPLOAD_BASE_URL || '/group')
export const messageRequest = createRequest(import.meta.env.VITE_UPLOAD_BASE_URL || '/message')
export const financialRequest = createRequest(import.meta.env.VITE_UPLOAD_BASE_URL || '/financial')
let loadingInstance = null
let requestCount = 0
@@ -175,7 +176,7 @@ const api = {
login: (data) => midRequest.post('/auth/login', data),
getCap: () => midRequest.get('/captcha/generate'),
register: (data) => midRequest.post('/auth/register', data),
getCurrentUser: () => apiRequest.get('/auth/me'),
getCurrentUser: () => midRequest.get('/auth/me'),
changePassword: (data) => midRequest.put('/auth/change-password', data)
},

579
src/views/Financial.vue Normal file
View File

@@ -0,0 +1,579 @@
<template>
<div class="page-container">
<el-card class="page-header">
<h2>金融管理</h2>
<p>管理金融的信息</p>
</el-card>
<!-- 统计卡片 -->
<!-- <el-card class="stats-card">-->
<!-- <el-row :gutter="24" class="stats-row">-->
<!-- <el-col :span="8">-->
<!-- <el-card class="stat-card">-->
<!-- <div class="stat-content">-->
<!-- <div class="stat-number">{{ stats.totalTransfers }}</div>-->
<!-- <div class="stat-label">总转账数</div>-->
<!-- </div>-->
<!-- <el-icon class="stat-icon">-->
<!-- <Money/>-->
<!-- </el-icon>-->
<!-- </el-card>-->
<!-- </el-col>-->
<!-- <el-col :span="8">-->
<!-- <el-card class="stat-card">-->
<!-- <div class="stat-content">-->
<!-- <div class="stat-number">{{ stats.confirmedTransfers }}</div>-->
<!-- <div class="stat-label">已确认</div>-->
<!-- </div>-->
<!-- <el-icon class="stat-icon">-->
<!-- <Check/>-->
<!-- </el-icon>-->
<!-- </el-card>-->
<!-- </el-col>-->
<!-- <el-col :span="8">-->
<!-- <el-card class="stat-card">-->
<!-- <div class="stat-content">-->
<!-- <div class="stat-number">¥{{ stats.totalAmount }}</div>-->
<!-- <div class="stat-label">总欠额</div>-->
<!-- </div>-->
<!-- <el-icon class="stat-icon">-->
<!-- <Wallet/>-->
<!-- </el-icon>-->
<!-- </el-card>-->
<!-- </el-col>-->
<!-- </el-row>-->
<!-- </el-card>-->
<!-- 筛选和操作 -->
<el-card class="filter-card">
<el-row :gutter="20">
<!-- <el-col :span="4">-->
<!-- <el-select v-model="queryParams.status" placeholder="选择状态" clearable>-->
<!-- <el-option label="全部" value=""/>-->
<!-- <el-option label="待确认" value="pending"/>-->
<!-- <el-option label="已确认" value="confirmed"/>-->
<!-- <el-option label="已拒绝" value="rejected"/>-->
<!-- <el-option label="已取消" value="cancelled"/>-->
<!-- </el-select>-->
<!-- </el-col>-->
<el-col :span="4">
<el-input v-model="queryParams.keyword" placeholder="搜索产品代码、名称或公司" clearable/>
</el-col>
<!-- <el-col :span="4">-->
<!-- <el-date-picker-->
<!-- v-model="dateRange"-->
<!-- type="daterange"-->
<!-- range-separator="至"-->
<!-- start-placeholder="开始日期"-->
<!-- end-placeholder="结束日期"-->
<!-- format="YYYY-MM-DD"-->
<!-- value-format="YYYY-MM-DD"-->
<!-- />-->
<!-- </el-col>-->
<el-row style="margin-left: 50px;" :gutter="10">
<el-col :span="12">
<el-button type="primary" @click="getList">搜索</el-button>
</el-col>
<el-col :span="12">
<el-button @click="resetFilters">重置</el-button>
</el-col>
</el-row>
</el-row>
</el-card>
<!-- 数据列表 -->
<el-card class="table-card">
<el-row :gutter="10" class="mb8 mb-2">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="Edit"
:disabled="single"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
:disabled="single"
@click="handleDelete"
>删除
</el-button>
</el-col>
</el-row>
<el-table
:data="dataList"
v-loading="loading"
@selection-change="handleSelectionChange"
stripe
style="width: 100%"
>
<el-table-column type="selection" width="55" align="center"/>
<!-- <el-table-column prop="id" label="ID"/>-->
<el-table-column prop="productCode" label="产品代码"/>
<el-table-column prop="productName" label="产品名称"/>
<el-table-column prop="productType" label="产品类型"/>
<el-table-column prop="company" label="公司"/>
<el-table-column label="产品负责人">
<template #default="scope">
<el-tag>{{ scope.row.user.username }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="riskLevel" label="风险等级">
<template #default="scope">
<el-tag type="danger">{{ scope.row.riskLevel }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="expectedReturnRate" label="预期收益率">
<template #default="scope">
<el-tag type="success">{{ scope.row.expectedReturnRate }}%</el-tag>
</template>
</el-table-column>
<el-table-column prop="createDate" label="创建时间"/>
<el-table-column prop="introduction" label="产品描述">
<template #default="scope">
<el-button text type="primary" @click="handleDetail(scope.row)">详情</el-button>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="300">
<template #default="scope">
<!-- <el-button link type="primary" icon="Document" @click="handleDetail(scope.row)">详情</el-button>-->
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination
v-model:current-page="pagination.page"
v-model:page-size="pagination.size"
:page-sizes="[10,50,100]"
:total="pagination.total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="getList"
@current-change="getList"
/>
</div>
</el-card>
<!-- 表单 -->
<el-dialog :title="title" v-model="open" width="60%" append-to-body top="1vh" @close="reset">
<el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="产品代码" prop="productCode">
<el-input v-model="form.productCode" placeholder="请输入产品代码"/>
</el-form-item>
<el-form-item label="产品名称" prop="productName">
<el-input v-model="form.productName" placeholder="请输入产品名称"/>
</el-form-item>
<el-form-item label="产品类型" prop="productType">
<el-select v-model="form.productType" placeholder="请选择产品类型">
<el-option label="存款" value="存款"/>
<el-option label="基金" value="基金"/>
<el-option label="保险" value="保险"/>
<el-option label="理财" value="理财"/>
</el-select>
</el-form-item>
<el-form-item label="公司名称" prop="company">
<el-input v-model="form.company" placeholder="请输入公司名称"/>
</el-form-item>
<el-form-item label="风险等级" prop="riskLevel">
<el-select v-model="form.riskLevel" placeholder="请选择风险等级">
<el-option label="R1" value="R1"/>
<el-option label="R2" value="R2"/>
<el-option label="R3" value="R3"/>
<el-option label="R4" value="R4"/>
<el-option label="R5" value="R5"/>
</el-select>
</el-form-item>
<el-form-item label="预期收益" prop="expectedReturnRate">
<el-input v-model="form.expectedReturnRate" placeholder="请输入预期收益"/>
</el-form-item>
<!-- <el-form-item label="开始时间" prop="startDate">-->
<!-- <el-input v-model="form.startDate" placeholder="请选择开始时间"/>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="结束时间" prop="endDate">-->
<!-- <el-input v-model="form.endDate" placeholder="请选择结束时间"/>-->
<!-- </el-form-item>-->
<el-form-item label="产品描述" prop="introduction" class="editor">
<RichTextEditor v-model="form.introduction" class="w-100"/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
<!-- 详情 -->
<el-dialog :title="detailTitle" v-model="openDetail" width="50%" class="h-75 overflow-hidden overflow-scroll">
<div class="p-5 border editor-content-view">
<div v-html="detailContent"></div>
</div>
</el-dialog>
</div>
</template>
<script setup>
import {getCurrentInstance, reactive, ref, shallowRef, toRefs} from "vue";
import {Check, Money, Wallet} from "@element-plus/icons-vue";
import {ElMessage, ElMessageBox} from "element-plus";
import {financialAPI} from "@/api/financial";
import {useUserStore} from "@/stores/user";
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import '@/assets/wangeditor.css'
import RichTextEditor from "@/components/RichTextEditor.vue";
const {proxy} = getCurrentInstance();
const userStore = useUserStore()
// 统计
const stats = ref({
totalTransfers: 10,
confirmedTransfers: 10,
totalAmount: 10
})
const dateRange = ref([])
// 列表
const dataList = ref([])
const loading = ref(false)
const single = ref(true);
// 分页
const pagination = ref({
page: 1,
size: 10,
total: 0
});
// 表单
const open = ref(false)
const title = ref("");
const data = reactive({
form: {},
queryParams: {
page: 1,
size: 10,
name: undefined,
status: undefined,
keyword: undefined
},
rules: {
productCode: [{required: true, message: "产品代码不能为空", trigger: "blur"}],
productName: [{required: true, message: "产品名称不能为空", trigger: "blur"}],
productType: [{required: true, message: "产品类型不能为空", trigger: "blur"}],
company: [{required: true, message: "产品企业不能为空", trigger: "blur"}],
riskLevel: [{required: true, message: "风险等级不能为空", trigger: "blur"}],
expectedReturnRate: [{required: true, message: "预期收益率不能为空", trigger: "blur"}],
introduction: [{required: true, message: "产品描述不能为空", trigger: "blur"}],
},
});
const {queryParams, form, rules} = toRefs(data);
// TODO
const getStats = () => {
// financialAPI.getStats().then(res => {
// stats.value = res.data.data.stats
// })
}
// 加载数据
const getList = async () => {
loading.value = true;
// api请求
queryParams.value.page = pagination.value.page;
queryParams.value.size = pagination.value.size;
financialAPI.list(queryParams.value).then(res => {
// console.log(res)
dataList.value = res.data.data.list
pagination.value.total = res.data.data.total
loading.value = false;
})
}
// 重置
const resetFilters = () => {
queryParams.value = {
page: 1,
keyword: undefined
}
dateRange.value = []
getList()
}
const handleSelectionChange = (selection) => {
single.value = selection.length != 1;
}
const handleAdd = () => {
title.value = "新增产品"
open.value = true;
form.value = {}
}
const handleUpdate = (row) => {
financialAPI.getOne(row.id).then(res => {
form.value = res.data.data
title.value = "修改产品"
open.value = true;
})
}
const handleDelete = (row) => {
ElMessageBox.confirm('确定要删除吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
financialAPI.delete(row.id).then(res => {
ElMessage.success('删除成功')
getList()
})
}).catch(() => {
ElMessage.info('已取消删除')
})
}
const openDetail = ref(false)
const detailTitle = ref("")
const detailContent = ref("")
// 查看详情
const handleDetail = (row) => {
detailTitle.value = row.name
detailContent.value = row.introduction
openDetail.value = true
}
const submitForm = () => {
proxy.$refs["formRef"].validate(valid => {
if (valid) {
form.value.managerId = userStore.user.id
if (form.value.id != undefined) {
delete form.value.user;
financialAPI.update(form.value).then(res => {
ElMessage.success('修改成功')
open.value = false
getList()
})
} else {
financialAPI.add(form.value).then(res => {
ElMessage.success('添加成功')
open.value = false
getList()
})
}
}
})
}
const formRef = ref(null)
const reset = () => {
form.value = {
managerId: undefined,
startDate: undefined,
endDate: undefined,
name: undefined,
company: undefined,
address: undefined,
introduction: undefined,
paymentMethod: undefined
}
proxy.$refs["formRef"].resetFields()
}
const cancel = () => {
open.value = false
reset()
}
// 获取统计
getStats()
// 获取列表
getList();
</script>
<style scoped lang="scss">
.page-container {
padding: 20px;
}
.page-header {
margin-bottom: 20px;
}
.page-header h2 {
margin: 0 0 8px 0;
color: #303133;
}
.page-header p {
margin: 0;
color: #909399;
}
.stats-card {
margin-bottom: 20px;
}
.stats-row {
margin-bottom: 20px;
}
.stat-card {
position: relative;
overflow: hidden;
}
.stat-content {
padding: 20px;
}
.stat-number {
font-size: 28px;
font-weight: bold;
color: #409eff;
margin-bottom: 8px;
}
.stat-label {
color: #909399;
font-size: 14px;
}
.stat-icon {
position: absolute;
right: 20px;
top: 50%;
transform: translateY(-50%);
font-size: 40px;
color: #e4e7ed;
}
.stat-card.overdue {
border-left: 4px solid #e6a23c;
}
.stat-card.overdue .stat-icon {
color: #e6a23c;
}
.stat-card.overdue .stat-number {
color: #e6a23c;
}
.filter-card {
margin-bottom: 20px;
}
.table-card {
margin-bottom: 20px;
}
.amount {
font-weight: bold;
color: #67c23a;
}
.amount-red {
font-weight: bold;
color: #ff4949;
}
.pagination-container {
margin-top: 20px;
text-align: right;
}
.proof-container {
text-align: center;
}
.proof-image {
width: 60%;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.proof-section {
margin-top: 20px;
}
.proof-section h4 {
margin-bottom: 10px;
color: #303133;
}
.detail-container {
display: grid;
place-items: center;
}
.detail-buttom {
color: #409eff;
cursor: pointer;
font-size: 10px;
}
.detail-buttom:hover {
text-decoration: underline;
}
.avatar {
width: 100px;
height: 100px;
display: block;
object-fit: cover;
}
.pay-detail-text {
white-space: pre-line;
word-break: break-word;
padding: 10px;
background-color: #f5f7fa;
border-radius: 4px;
border-left: 3px solid #409eff;
font-size: large;
}
.user-balance-info {
margin-top: 5px;
padding: 5px 10px;
background-color: #f5f7fa;
border-radius: 4px;
border-left: 3px solid #409eff;
}
.real-name {
font-size: 12px;
color: #909399;
margin-top: 2px;
}
//::v-deep .editor{
// .el-form-item__content{
// border: 1px solid #000;
// }
//}
</style>

View File

@@ -170,7 +170,7 @@
</el-card>
<!-- 表单 -->
<el-dialog :title="title" v-model="open" width="60%" append-to-body top="1vh">
<el-dialog :title="title" v-model="open" width="60%" append-to-body top="1vh" @close="reset">
<el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="项目名称" prop="name">
<el-input v-model="form.name" placeholder="请输入项目名称"/>
@@ -388,7 +388,7 @@ const reset = () => {
introduction: undefined,
paymentMethod: undefined
}
formRef.value.resetForm()
proxy.$refs["formRef"].resetFields()
}
const cancel = () => {

View File

@@ -47,6 +47,11 @@ export default defineConfig({
changeOrigin: true,
rewrite: (path) => path.replace(/^\/message/, '')
},
'/financial':{
target: 'http://192.168.0.15:3008',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/financial/, '')
},
'/uploads': {
target: 'https://test.zrbjr.com',
changeOrigin: true