2025-10-15
添加金融模块
This commit is contained in:
15
src/api/financial.js
Normal file
15
src/api/financial.js
Normal 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
|
||||||
|
}
|
||||||
1
src/assets/svg/financial.svg
Normal file
1
src/assets/svg/financial.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 5.1 KiB |
@@ -115,7 +115,7 @@ const editorConfig = {
|
|||||||
fontFamily: {
|
fontFamily: {
|
||||||
fontFamilyList: [
|
fontFamilyList: [
|
||||||
'黑体', '仿宋', '楷体', '标楷体', '华文仿宋', '华文楷体', '宋体', '微软雅黑',
|
'黑体', '仿宋', '楷体', '标楷体', '华文仿宋', '华文楷体', '宋体', '微软雅黑',
|
||||||
'Arial', 'Tahoma', 'Verdana', 'Times New Roman', 'Courier New'
|
// 'Arial', 'Tahoma', 'Verdana', 'Times New Roman', 'Courier New'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
// 配置颜色
|
// 配置颜色
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
<div class="logo">
|
<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>
|
<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>
|
</div>
|
||||||
|
|
||||||
<el-menu
|
<el-menu
|
||||||
@@ -16,53 +18,80 @@
|
|||||||
class="sidebar-menu"
|
class="sidebar-menu"
|
||||||
>
|
>
|
||||||
<el-menu-item index="/dashboard">
|
<el-menu-item index="/dashboard">
|
||||||
<el-icon><Odometer /></el-icon>
|
<el-icon>
|
||||||
|
<Odometer/>
|
||||||
|
</el-icon>
|
||||||
<template #title>仪表盘</template>
|
<template #title>仪表盘</template>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
|
|
||||||
<el-menu-item v-if="userStore.isAdmin" index="/users">
|
<el-menu-item v-if="userStore.isAdmin" index="/users">
|
||||||
<el-icon><User /></el-icon>
|
<el-icon>
|
||||||
|
<User/>
|
||||||
|
</el-icon>
|
||||||
<template #title>用户管理</template>
|
<template #title>用户管理</template>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
|
|
||||||
<el-menu-item v-if="userStore.isAdmin" index="/user-audit">
|
<el-menu-item v-if="userStore.isAdmin" index="/user-audit">
|
||||||
<el-icon><DocumentChecked /></el-icon>
|
<el-icon>
|
||||||
|
<DocumentChecked/>
|
||||||
|
</el-icon>
|
||||||
<template #title>用户审核</template>
|
<template #title>用户审核</template>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
|
|
||||||
<el-menu-item v-if="userStore.isAdmin" index="/points">
|
<el-menu-item v-if="userStore.isAdmin" index="/points">
|
||||||
<el-icon><Coin /></el-icon>
|
<el-icon>
|
||||||
|
<Coin/>
|
||||||
|
</el-icon>
|
||||||
<template #title>积分管理</template>
|
<template #title>积分管理</template>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
|
|
||||||
<el-menu-item index="/program">
|
<el-menu-item index="/program">
|
||||||
<el-icon><ProgramSvg /></el-icon>
|
<el-icon>
|
||||||
|
<ProgramSvg/>
|
||||||
|
</el-icon>
|
||||||
<template #title>项目管理</template>
|
<template #title>项目管理</template>
|
||||||
</el-menu-item>
|
</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-menu-item index="/chat">
|
||||||
<el-icon><ChatSvg /></el-icon>
|
<el-icon>
|
||||||
|
<ChatSvg/>
|
||||||
|
</el-icon>
|
||||||
<template #title>聊天室</template>
|
<template #title>聊天室</template>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
|
|
||||||
<el-menu-item v-if="userStore.isAdmin" index="/transfers">
|
<el-menu-item v-if="userStore.isAdmin" index="/transfers">
|
||||||
<el-icon><Money /></el-icon>
|
<el-icon>
|
||||||
|
<Money/>
|
||||||
|
</el-icon>
|
||||||
<template #title>转账管理</template>
|
<template #title>转账管理</template>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
|
|
||||||
|
|
||||||
<el-menu-item v-if="userStore.isAdmin" index="/beans">
|
<el-menu-item v-if="userStore.isAdmin" index="/beans">
|
||||||
<el-icon><Promotion /></el-icon>
|
<el-icon>
|
||||||
|
<Promotion/>
|
||||||
|
</el-icon>
|
||||||
<template #title>融豆管理</template>
|
<template #title>融豆管理</template>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
|
|
||||||
<el-menu-item v-if="userStore.isAdmin" index="/projects">
|
<el-menu-item v-if="userStore.isAdmin" index="/projects">
|
||||||
<el-icon><Setting /></el-icon>
|
<el-icon>
|
||||||
|
<Setting/>
|
||||||
|
</el-icon>
|
||||||
<template #title>项目管理</template>
|
<template #title>项目管理</template>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
|
|
||||||
<el-menu-item index="/profile">
|
<el-menu-item index="/profile">
|
||||||
<el-icon><UserFilled /></el-icon>
|
<el-icon>
|
||||||
|
<UserFilled/>
|
||||||
|
</el-icon>
|
||||||
<template #title>个人资料</template>
|
<template #title>个人资料</template>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
@@ -78,7 +107,10 @@
|
|||||||
@click="toggleCollapse"
|
@click="toggleCollapse"
|
||||||
class="collapse-btn"
|
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-button>
|
||||||
|
|
||||||
<el-breadcrumb separator="/" class="breadcrumb">
|
<el-breadcrumb separator="/" class="breadcrumb">
|
||||||
@@ -96,14 +128,18 @@
|
|||||||
<!-- 全屏按钮 -->
|
<!-- 全屏按钮 -->
|
||||||
<el-tooltip content="全屏" placement="bottom">
|
<el-tooltip content="全屏" placement="bottom">
|
||||||
<el-button type="text" @click="toggleFullscreen" class="header-btn">
|
<el-button type="text" @click="toggleFullscreen" class="header-btn">
|
||||||
<el-icon><FullScreen /></el-icon>
|
<el-icon>
|
||||||
|
<FullScreen/>
|
||||||
|
</el-icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<!-- 刷新按钮 -->
|
<!-- 刷新按钮 -->
|
||||||
<el-tooltip content="刷新" placement="bottom">
|
<el-tooltip content="刷新" placement="bottom">
|
||||||
<el-button type="text" @click="refresh" class="header-btn">
|
<el-button type="text" @click="refresh" class="header-btn">
|
||||||
<el-icon><Refresh /></el-icon>
|
<el-icon>
|
||||||
|
<Refresh/>
|
||||||
|
</el-icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
@@ -111,23 +147,33 @@
|
|||||||
<el-dropdown @command="handleCommand" class="user-dropdown">
|
<el-dropdown @command="handleCommand" class="user-dropdown">
|
||||||
<div class="user-info">
|
<div class="user-info">
|
||||||
<el-avatar :size="32" :src="userStore.user?.avatar">
|
<el-avatar :size="32" :src="userStore.user?.avatar">
|
||||||
<el-icon><UserFilled /></el-icon>
|
<el-icon>
|
||||||
|
<UserFilled/>
|
||||||
|
</el-icon>
|
||||||
</el-avatar>
|
</el-avatar>
|
||||||
<span class="username">{{ userStore.user?.username }}</span>
|
<span class="username">{{ userStore.user?.username }}</span>
|
||||||
<el-icon class="dropdown-icon"><ArrowDown /></el-icon>
|
<el-icon class="dropdown-icon">
|
||||||
|
<ArrowDown/>
|
||||||
|
</el-icon>
|
||||||
</div>
|
</div>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item command="profile">
|
<el-dropdown-item command="profile">
|
||||||
<el-icon><UserFilled /></el-icon>
|
<el-icon>
|
||||||
|
<UserFilled/>
|
||||||
|
</el-icon>
|
||||||
个人资料
|
个人资料
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item command="changePassword">
|
<el-dropdown-item command="changePassword">
|
||||||
<el-icon><Lock /></el-icon>
|
<el-icon>
|
||||||
|
<Lock/>
|
||||||
|
</el-icon>
|
||||||
修改密码
|
修改密码
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item divided command="logout">
|
<el-dropdown-item divided command="logout">
|
||||||
<el-icon><SwitchButton /></el-icon>
|
<el-icon>
|
||||||
|
<SwitchButton/>
|
||||||
|
</el-icon>
|
||||||
退出登录
|
退出登录
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
@@ -199,6 +245,7 @@ import { useUserStore } from '@/stores/user'
|
|||||||
import {ElMessage, ElMessageBox} from 'element-plus'
|
import {ElMessage, ElMessageBox} from 'element-plus'
|
||||||
import ProgramSvg from '@/assets/svg/program.svg'
|
import ProgramSvg from '@/assets/svg/program.svg'
|
||||||
import ChatSvg from '@/assets/svg/chat.svg'
|
import ChatSvg from '@/assets/svg/chat.svg'
|
||||||
|
import FinancialSvg from '@/assets/svg/financial.svg'
|
||||||
import {
|
import {
|
||||||
Odometer,
|
Odometer,
|
||||||
User,
|
User,
|
||||||
@@ -225,6 +272,7 @@ import {
|
|||||||
CreditCard,
|
CreditCard,
|
||||||
Bell,
|
Bell,
|
||||||
} from '@element-plus/icons-vue'
|
} from '@element-plus/icons-vue'
|
||||||
|
import Financial from "@/views/Financial.vue";
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|||||||
@@ -116,6 +116,15 @@ const routes = [
|
|||||||
title: '聊天 - 炬融圈',
|
title: '聊天 - 炬融圈',
|
||||||
icon: 'ChatDotRound'
|
icon: 'ChatDotRound'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'financial',
|
||||||
|
name: 'Financial',
|
||||||
|
component: () => import('@/views/Financial.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '金融 - 炬融圈',
|
||||||
|
icon: 'financial'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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 programRequest = createRequest(import.meta.env.VITE_UPLOAD_BASE_URL || '/program')
|
||||||
export const groupRequest = createRequest(import.meta.env.VITE_UPLOAD_BASE_URL || '/group')
|
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 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 loadingInstance = null
|
||||||
let requestCount = 0
|
let requestCount = 0
|
||||||
@@ -175,7 +176,7 @@ const api = {
|
|||||||
login: (data) => midRequest.post('/auth/login', data),
|
login: (data) => midRequest.post('/auth/login', data),
|
||||||
getCap: () => midRequest.get('/captcha/generate'),
|
getCap: () => midRequest.get('/captcha/generate'),
|
||||||
register: (data) => midRequest.post('/auth/register', data),
|
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)
|
changePassword: (data) => midRequest.put('/auth/change-password', data)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
579
src/views/Financial.vue
Normal file
579
src/views/Financial.vue
Normal 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>
|
||||||
@@ -170,7 +170,7 @@
|
|||||||
</el-card>
|
</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 ref="formRef" :model="form" :rules="rules" label-width="80px">
|
||||||
<el-form-item label="项目名称" prop="name">
|
<el-form-item label="项目名称" prop="name">
|
||||||
<el-input v-model="form.name" placeholder="请输入项目名称"/>
|
<el-input v-model="form.name" placeholder="请输入项目名称"/>
|
||||||
@@ -388,7 +388,7 @@ const reset = () => {
|
|||||||
introduction: undefined,
|
introduction: undefined,
|
||||||
paymentMethod: undefined
|
paymentMethod: undefined
|
||||||
}
|
}
|
||||||
formRef.value.resetForm()
|
proxy.$refs["formRef"].resetFields()
|
||||||
}
|
}
|
||||||
|
|
||||||
const cancel = () => {
|
const cancel = () => {
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ export default defineConfig({
|
|||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path) => path.replace(/^\/message/, '')
|
rewrite: (path) => path.replace(/^\/message/, '')
|
||||||
},
|
},
|
||||||
|
'/financial':{
|
||||||
|
target: 'http://192.168.0.15:3008',
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: (path) => path.replace(/^\/financial/, '')
|
||||||
|
},
|
||||||
'/uploads': {
|
'/uploads': {
|
||||||
target: 'https://test.zrbjr.com',
|
target: 'https://test.zrbjr.com',
|
||||||
changeOrigin: true
|
changeOrigin: true
|
||||||
|
|||||||
Reference in New Issue
Block a user