feat: 完善前端页面 - 客户管理、项目管理、合同管理、用户管理完整功能
This commit is contained in:
parent
69a3d62c3e
commit
ed19ab4739
77
fund-admin/src/api/project.js
Normal file
77
fund-admin/src/api/project.js
Normal file
@ -0,0 +1,77 @@
|
||||
import request from '../utils/request'
|
||||
|
||||
export const getProjectList = (params) => {
|
||||
return request({
|
||||
url: '/proj/api/v1/project/list',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export const getProjectById = (id) => {
|
||||
return request({
|
||||
url: `/proj/api/v1/project/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export const createProject = (data) => {
|
||||
return request({
|
||||
url: '/proj/api/v1/project',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const updateProject = (id, data) => {
|
||||
return request({
|
||||
url: `/proj/api/v1/project/${id}`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteProject = (id) => {
|
||||
return request({
|
||||
url: `/proj/api/v1/project/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export const updateProjectStatus = (id, status) => {
|
||||
return request({
|
||||
url: `/proj/api/v1/project/${id}/status/${status}`,
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
export const getContractList = (params) => {
|
||||
return request({
|
||||
url: '/proj/api/v1/contract/list',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export const createContract = (data) => {
|
||||
return request({
|
||||
url: '/proj/api/v1/contract',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const updateContract = (id, data) => {
|
||||
return request({
|
||||
url: `/proj/api/v1/contract/${id}`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteContract = (id) => {
|
||||
return request({
|
||||
url: `/proj/api/v1/contract/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
55
fund-admin/src/api/user.js
Normal file
55
fund-admin/src/api/user.js
Normal file
@ -0,0 +1,55 @@
|
||||
import request from '../utils/request'
|
||||
|
||||
export const getUserList = (params) => {
|
||||
return request({
|
||||
url: '/sys/api/v1/user/list',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export const getUserById = (id) => {
|
||||
return request({
|
||||
url: `/sys/api/v1/user/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export const createUser = (data) => {
|
||||
return request({
|
||||
url: '/sys/api/v1/user',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const updateUser = (id, data) => {
|
||||
return request({
|
||||
url: `/sys/api/v1/user/${id}`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteUser = (id) => {
|
||||
return request({
|
||||
url: `/sys/api/v1/user/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export const resetPassword = (id, newPassword) => {
|
||||
return request({
|
||||
url: `/sys/api/v1/user/${id}/reset-password`,
|
||||
method: 'put',
|
||||
params: { newPassword }
|
||||
})
|
||||
}
|
||||
|
||||
export const updateUserStatus = (id, status) => {
|
||||
return request({
|
||||
url: `/sys/api/v1/user/${id}/status`,
|
||||
method: 'put',
|
||||
params: { status }
|
||||
})
|
||||
}
|
||||
@ -60,13 +60,77 @@
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</el-card>
|
||||
|
||||
<!-- 新增/编辑对话框 -->
|
||||
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="客户编码" prop="customerCode">
|
||||
<el-input v-model="form.customerCode" placeholder="请输入客户编码" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="客户名称" prop="customerName">
|
||||
<el-input v-model="form.customerName" placeholder="请输入客户名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="客户类型" prop="customerType">
|
||||
<el-select v-model="form.customerType" placeholder="请选择" style="width: 100%">
|
||||
<el-option label="企业客户" value="ENTERPRISE" />
|
||||
<el-option label="个人客户" value="PERSONAL" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属行业">
|
||||
<el-input v-model="form.industry" placeholder="请输入所属行业" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系人">
|
||||
<el-input v-model="form.legalPerson" placeholder="请输入联系人" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系电话">
|
||||
<el-input v-model="form.phone" placeholder="请输入联系电话" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="邮箱">
|
||||
<el-input v-model="form.email" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="地址">
|
||||
<el-input v-model="form.address" placeholder="请输入地址" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="form.remark" type="textarea" rows="3" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { getCustomerList, deleteCustomer } from '../../api/customer'
|
||||
import { getCustomerList, createCustomer, updateCustomer, deleteCustomer } from '../../api/customer'
|
||||
|
||||
const loading = ref(false)
|
||||
const tableData = ref([])
|
||||
@ -111,12 +175,74 @@ const handleReset = () => {
|
||||
handleSearch()
|
||||
}
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('')
|
||||
const formRef = ref(null)
|
||||
const form = reactive({
|
||||
customerId: null,
|
||||
customerCode: '',
|
||||
customerName: '',
|
||||
customerType: 'ENTERPRISE',
|
||||
industry: '',
|
||||
legalPerson: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
address: '',
|
||||
remark: ''
|
||||
})
|
||||
|
||||
const rules = {
|
||||
customerCode: [{ required: true, message: '请输入客户编码', trigger: 'blur' }],
|
||||
customerName: [{ required: true, message: '请输入客户名称', trigger: 'blur' }],
|
||||
customerType: [{ required: true, message: '请选择客户类型', trigger: 'change' }]
|
||||
}
|
||||
|
||||
const handleAdd = () => {
|
||||
console.log('新增客户')
|
||||
dialogTitle.value = '新增客户'
|
||||
resetForm()
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const handleEdit = (row) => {
|
||||
console.log('编辑客户:', row)
|
||||
dialogTitle.value = '编辑客户'
|
||||
resetForm()
|
||||
Object.assign(form, row)
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const resetForm = () => {
|
||||
form.customerId = null
|
||||
form.customerCode = ''
|
||||
form.customerName = ''
|
||||
form.customerType = 'ENTERPRISE'
|
||||
form.industry = ''
|
||||
form.legalPerson = ''
|
||||
form.phone = ''
|
||||
form.email = ''
|
||||
form.address = ''
|
||||
form.remark = ''
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
try {
|
||||
if (form.customerId) {
|
||||
await updateCustomer(form.customerId, form)
|
||||
ElMessage.success('更新成功')
|
||||
} else {
|
||||
await createCustomer(form)
|
||||
ElMessage.success('创建成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
fetchData()
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleDelete = (row) => {
|
||||
|
||||
@ -4,14 +4,314 @@
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>合同管理</span>
|
||||
<el-button type="primary">新增合同</el-button>
|
||||
<el-button type="primary" @click="handleAdd">新增合同</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<p>合同管理页面 - 开发中</p>
|
||||
|
||||
<el-form :inline="true" class="search-form">
|
||||
<el-form-item label="合同名称">
|
||||
<el-input v-model="searchForm.contractName" placeholder="请输入合同名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="合同状态">
|
||||
<el-select v-model="searchForm.contractStatus" placeholder="请选择" clearable>
|
||||
<el-option label="草稿" value="DRAFT" />
|
||||
<el-option label="已签署" value="SIGNED" />
|
||||
<el-option label="执行中" value="EXECUTING" />
|
||||
<el-option label="已完成" value="COMPLETED" />
|
||||
<el-option label="已终止" value="TERMINATED" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">查询</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table :data="tableData" border v-loading="loading">
|
||||
<el-table-column prop="contractCode" label="合同编码" width="120" />
|
||||
<el-table-column prop="contractName" label="合同名称" />
|
||||
<el-table-column prop="contractStatus" label="合同状态" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getStatusType(scope.row.contractStatus)">
|
||||
{{ getStatusText(scope.row.contractStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="contractAmount" label="合同金额" width="120">
|
||||
<template #default="scope">
|
||||
{{ formatAmount(scope.row.contractAmount) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="signDate" label="签署日期" width="120" />
|
||||
<el-table-column prop="effectiveDate" label="生效日期" width="120" />
|
||||
<el-table-column label="操作" width="200" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button type="danger" link @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-pagination
|
||||
class="pagination"
|
||||
v-model:current-page="page.current"
|
||||
v-model:page-size="page.size"
|
||||
:total="page.total"
|
||||
layout="total, sizes, prev, pager, next"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</el-card>
|
||||
|
||||
<!-- 新增/编辑对话框 -->
|
||||
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="700px">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="合同编码" prop="contractCode">
|
||||
<el-input v-model="form.contractCode" placeholder="请输入合同编码" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="合同名称" prop="contractName">
|
||||
<el-input v-model="form.contractName" placeholder="请输入合同名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="合同金额" prop="contractAmount">
|
||||
<el-input-number v-model="form.contractAmount" :precision="2" :min="0" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="合同类型">
|
||||
<el-select v-model="form.contractType" placeholder="请选择" style="width: 100%">
|
||||
<el-option label="销售合同" value="SALES" />
|
||||
<el-option label="采购合同" value="PURCHASE" />
|
||||
<el-option label="服务合同" value="SERVICE" />
|
||||
<el-option label="其他" value="OTHER" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="签署日期">
|
||||
<el-date-picker v-model="form.signDate" type="date" placeholder="选择日期" style="width: 100%" value-format="YYYY-MM-DD" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="生效日期">
|
||||
<el-date-picker v-model="form.effectiveDate" type="date" placeholder="选择日期" style="width: 100%" value-format="YYYY-MM-DD" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="到期日期">
|
||||
<el-date-picker v-model="form.expiryDate" type="date" placeholder="选择日期" style="width: 100%" value-format="YYYY-MM-DD" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="签署地点">
|
||||
<el-input v-model="form.signLocation" placeholder="请输入签署地点" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="付款条款">
|
||||
<el-input v-model="form.paymentTerms" type="textarea" rows="2" placeholder="请输入付款条款" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="form.remark" type="textarea" rows="2" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { getContractList, createContract, updateContract, deleteContract } from '../../api/project'
|
||||
|
||||
const loading = ref(false)
|
||||
const tableData = ref([])
|
||||
|
||||
const searchForm = reactive({
|
||||
contractName: '',
|
||||
contractStatus: ''
|
||||
})
|
||||
|
||||
const page = reactive({
|
||||
current: 1,
|
||||
size: 10,
|
||||
total: 0
|
||||
})
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('')
|
||||
const formRef = ref(null)
|
||||
const form = reactive({
|
||||
contractId: null,
|
||||
contractCode: '',
|
||||
contractName: '',
|
||||
contractType: 'SALES',
|
||||
contractAmount: 0,
|
||||
signDate: '',
|
||||
effectiveDate: '',
|
||||
expiryDate: '',
|
||||
signLocation: '',
|
||||
paymentTerms: '',
|
||||
remark: ''
|
||||
})
|
||||
|
||||
const rules = {
|
||||
contractCode: [{ required: true, message: '请输入合同编码', trigger: 'blur' }],
|
||||
contractName: [{ required: true, message: '请输入合同名称', trigger: 'blur' }],
|
||||
contractAmount: [{ required: true, message: '请输入合同金额', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
const fetchData = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getContractList({
|
||||
current: page.current,
|
||||
size: page.size,
|
||||
contractName: searchForm.contractName,
|
||||
contractStatus: searchForm.contractStatus
|
||||
})
|
||||
tableData.value = res.records
|
||||
page.total = res.total
|
||||
} catch (error) {
|
||||
console.error('获取合同列表失败:', error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleSearch = () => {
|
||||
page.current = 1
|
||||
fetchData()
|
||||
}
|
||||
|
||||
const handleReset = () => {
|
||||
searchForm.contractName = ''
|
||||
searchForm.contractStatus = ''
|
||||
handleSearch()
|
||||
}
|
||||
|
||||
const handleAdd = () => {
|
||||
dialogTitle.value = '新增合同'
|
||||
resetForm()
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const handleEdit = (row) => {
|
||||
dialogTitle.value = '编辑合同'
|
||||
resetForm()
|
||||
Object.assign(form, row)
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const resetForm = () => {
|
||||
form.contractId = null
|
||||
form.contractCode = ''
|
||||
form.contractName = ''
|
||||
form.contractType = 'SALES'
|
||||
form.contractAmount = 0
|
||||
form.signDate = ''
|
||||
form.effectiveDate = ''
|
||||
form.expiryDate = ''
|
||||
form.signLocation = ''
|
||||
form.paymentTerms = ''
|
||||
form.remark = ''
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
try {
|
||||
if (form.contractId) {
|
||||
await updateContract(form.contractId, form)
|
||||
ElMessage.success('更新成功')
|
||||
} else {
|
||||
await createContract(form)
|
||||
ElMessage.success('创建成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
fetchData()
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleDelete = (row) => {
|
||||
ElMessageBox.confirm('确定要删除该合同吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
try {
|
||||
await deleteContract(row.contractId)
|
||||
ElMessage.success('删除成功')
|
||||
fetchData()
|
||||
} catch (error) {
|
||||
console.error('删除失败:', error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleSizeChange = (val) => {
|
||||
page.size = val
|
||||
fetchData()
|
||||
}
|
||||
|
||||
const handleCurrentChange = (val) => {
|
||||
page.current = val
|
||||
fetchData()
|
||||
}
|
||||
|
||||
const getStatusType = (status) => {
|
||||
const map = {
|
||||
'DRAFT': 'info',
|
||||
'SIGNED': 'warning',
|
||||
'EXECUTING': 'primary',
|
||||
'COMPLETED': 'success',
|
||||
'TERMINATED': 'danger'
|
||||
}
|
||||
return map[status] || 'info'
|
||||
}
|
||||
|
||||
const getStatusText = (status) => {
|
||||
const map = {
|
||||
'DRAFT': '草稿',
|
||||
'SIGNED': '已签署',
|
||||
'EXECUTING': '执行中',
|
||||
'COMPLETED': '已完成',
|
||||
'TERMINATED': '已终止'
|
||||
}
|
||||
return map[status] || status
|
||||
}
|
||||
|
||||
const formatAmount = (amount) => {
|
||||
if (!amount) return '¥0.00'
|
||||
return '¥' + parseFloat(amount).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page-container {
|
||||
padding: 20px;
|
||||
@ -22,4 +322,13 @@
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 20px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -4,14 +4,328 @@
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>项目管理</span>
|
||||
<el-button type="primary">新增项目</el-button>
|
||||
<el-button type="primary" @click="handleAdd">新增项目</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<p>项目管理页面 - 开发中</p>
|
||||
|
||||
<el-form :inline="true" class="search-form">
|
||||
<el-form-item label="项目名称">
|
||||
<el-input v-model="searchForm.projectName" placeholder="请输入项目名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="项目状态">
|
||||
<el-select v-model="searchForm.projectStatus" placeholder="请选择" clearable>
|
||||
<el-option label="草稿" value="DRAFT" />
|
||||
<el-option label="进行中" value="IN_PROGRESS" />
|
||||
<el-option label="已完成" value="COMPLETED" />
|
||||
<el-option label="已取消" value="CANCELLED" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">查询</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table :data="tableData" border v-loading="loading">
|
||||
<el-table-column prop="projectCode" label="项目编码" width="120" />
|
||||
<el-table-column prop="projectName" label="项目名称" />
|
||||
<el-table-column prop="projectStatus" label="项目状态" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getStatusType(scope.row.projectStatus)">
|
||||
{{ getStatusText(scope.row.projectStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="projectAmount" label="项目金额" width="120">
|
||||
<template #default="scope">
|
||||
{{ formatAmount(scope.row.projectAmount) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="startDate" label="开始日期" width="120" />
|
||||
<el-table-column prop="endDate" label="结束日期" width="120" />
|
||||
<el-table-column prop="projectManager" label="项目经理" width="120" />
|
||||
<el-table-column label="操作" width="250" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button type="success" link @click="handleUpdateStatus(scope.row)">状态</el-button>
|
||||
<el-button type="danger" link @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-pagination
|
||||
class="pagination"
|
||||
v-model:current-page="page.current"
|
||||
v-model:page-size="page.size"
|
||||
:total="page.total"
|
||||
layout="total, sizes, prev, pager, next"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</el-card>
|
||||
|
||||
<!-- 新增/编辑对话框 -->
|
||||
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="700px">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="项目编码" prop="projectCode">
|
||||
<el-input v-model="form.projectCode" placeholder="请输入项目编码" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="项目名称" prop="projectName">
|
||||
<el-input v-model="form.projectName" placeholder="请输入项目名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="项目金额" prop="projectAmount">
|
||||
<el-input-number v-model="form.projectAmount" :precision="2" :min="0" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="项目经理" prop="projectManager">
|
||||
<el-input v-model="form.projectManager" placeholder="请输入项目经理" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="开始日期" prop="startDate">
|
||||
<el-date-picker v-model="form.startDate" type="date" placeholder="选择日期" style="width: 100%" value-format="YYYY-MM-DD" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="结束日期" prop="endDate">
|
||||
<el-date-picker v-model="form.endDate" type="date" placeholder="选择日期" style="width: 100%" value-format="YYYY-MM-DD" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="项目描述" prop="projectDesc">
|
||||
<el-input v-model="form.projectDesc" type="textarea" rows="3" placeholder="请输入项目描述" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 状态更新对话框 -->
|
||||
<el-dialog v-model="statusDialogVisible" title="更新项目状态" width="400px">
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="项目状态">
|
||||
<el-select v-model="statusForm.projectStatus" placeholder="请选择状态" style="width: 100%">
|
||||
<el-option label="草稿" value="DRAFT" />
|
||||
<el-option label="进行中" value="IN_PROGRESS" />
|
||||
<el-option label="已完成" value="COMPLETED" />
|
||||
<el-option label="已取消" value="CANCELLED" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="statusDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleStatusSubmit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { getProjectList, createProject, updateProject, deleteProject, updateProjectStatus } from '../../api/project'
|
||||
|
||||
const loading = ref(false)
|
||||
const tableData = ref([])
|
||||
|
||||
const searchForm = reactive({
|
||||
projectName: '',
|
||||
projectStatus: ''
|
||||
})
|
||||
|
||||
const page = reactive({
|
||||
current: 1,
|
||||
size: 10,
|
||||
total: 0
|
||||
})
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('')
|
||||
const formRef = ref(null)
|
||||
const form = reactive({
|
||||
projectId: null,
|
||||
projectCode: '',
|
||||
projectName: '',
|
||||
projectAmount: 0,
|
||||
projectManager: '',
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
projectDesc: ''
|
||||
})
|
||||
|
||||
const rules = {
|
||||
projectCode: [{ required: true, message: '请输入项目编码', trigger: 'blur' }],
|
||||
projectName: [{ required: true, message: '请输入项目名称', trigger: 'blur' }],
|
||||
projectAmount: [{ required: true, message: '请输入项目金额', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
const statusDialogVisible = ref(false)
|
||||
const statusForm = reactive({
|
||||
projectId: null,
|
||||
projectStatus: ''
|
||||
})
|
||||
|
||||
const fetchData = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getProjectList({
|
||||
current: page.current,
|
||||
size: page.size,
|
||||
projectName: searchForm.projectName,
|
||||
projectStatus: searchForm.projectStatus
|
||||
})
|
||||
tableData.value = res.records
|
||||
page.total = res.total
|
||||
} catch (error) {
|
||||
console.error('获取项目列表失败:', error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleSearch = () => {
|
||||
page.current = 1
|
||||
fetchData()
|
||||
}
|
||||
|
||||
const handleReset = () => {
|
||||
searchForm.projectName = ''
|
||||
searchForm.projectStatus = ''
|
||||
handleSearch()
|
||||
}
|
||||
|
||||
const handleAdd = () => {
|
||||
dialogTitle.value = '新增项目'
|
||||
resetForm()
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const handleEdit = (row) => {
|
||||
dialogTitle.value = '编辑项目'
|
||||
resetForm()
|
||||
Object.assign(form, row)
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const resetForm = () => {
|
||||
form.projectId = null
|
||||
form.projectCode = ''
|
||||
form.projectName = ''
|
||||
form.projectAmount = 0
|
||||
form.projectManager = ''
|
||||
form.startDate = ''
|
||||
form.endDate = ''
|
||||
form.projectDesc = ''
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
try {
|
||||
if (form.projectId) {
|
||||
await updateProject(form.projectId, form)
|
||||
ElMessage.success('更新成功')
|
||||
} else {
|
||||
await createProject(form)
|
||||
ElMessage.success('创建成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
fetchData()
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleUpdateStatus = (row) => {
|
||||
statusForm.projectId = row.projectId
|
||||
statusForm.projectStatus = row.projectStatus
|
||||
statusDialogVisible.value = true
|
||||
}
|
||||
|
||||
const handleStatusSubmit = async () => {
|
||||
try {
|
||||
await updateProjectStatus(statusForm.projectId, statusForm.projectStatus)
|
||||
ElMessage.success('状态更新成功')
|
||||
statusDialogVisible.value = false
|
||||
fetchData()
|
||||
} catch (error) {
|
||||
console.error('状态更新失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleDelete = (row) => {
|
||||
ElMessageBox.confirm('确定要删除该项目吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
try {
|
||||
await deleteProject(row.projectId)
|
||||
ElMessage.success('删除成功')
|
||||
fetchData()
|
||||
} catch (error) {
|
||||
console.error('删除失败:', error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleSizeChange = (val) => {
|
||||
page.size = val
|
||||
fetchData()
|
||||
}
|
||||
|
||||
const handleCurrentChange = (val) => {
|
||||
page.current = val
|
||||
fetchData()
|
||||
}
|
||||
|
||||
const getStatusType = (status) => {
|
||||
const map = {
|
||||
'DRAFT': 'info',
|
||||
'IN_PROGRESS': 'primary',
|
||||
'COMPLETED': 'success',
|
||||
'CANCELLED': 'danger'
|
||||
}
|
||||
return map[status] || 'info'
|
||||
}
|
||||
|
||||
const getStatusText = (status) => {
|
||||
const map = {
|
||||
'DRAFT': '草稿',
|
||||
'IN_PROGRESS': '进行中',
|
||||
'COMPLETED': '已完成',
|
||||
'CANCELLED': '已取消'
|
||||
}
|
||||
return map[status] || status
|
||||
}
|
||||
|
||||
const formatAmount = (amount) => {
|
||||
if (!amount) return '¥0.00'
|
||||
return '¥' + parseFloat(amount).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page-container {
|
||||
padding: 20px;
|
||||
@ -22,4 +336,13 @@
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 20px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -8,40 +8,323 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-table :data="tableData" border>
|
||||
<el-table-column prop="username" label="用户名" />
|
||||
<el-table-column prop="realName" label="姓名" />
|
||||
<el-table-column prop="phone" label="手机号" />
|
||||
<el-form :inline="true" class="search-form">
|
||||
<el-form-item label="用户名">
|
||||
<el-input v-model="searchForm.username" placeholder="请输入用户名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名">
|
||||
<el-input v-model="searchForm.realName" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="searchForm.status" placeholder="请选择" clearable>
|
||||
<el-option label="启用" :value="1" />
|
||||
<el-option label="禁用" :value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">查询</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table :data="tableData" border v-loading="loading">
|
||||
<el-table-column prop="username" label="用户名" width="120" />
|
||||
<el-table-column prop="realName" label="姓名" width="120" />
|
||||
<el-table-column prop="phone" label="手机号" width="140" />
|
||||
<el-table-column prop="email" label="邮箱" />
|
||||
<el-table-column prop="status" label="状态">
|
||||
<el-table-column prop="position" label="职位" width="120" />
|
||||
<el-table-column prop="status" label="状态" width="80">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
|
||||
{{ scope.row.status === 1 ? '启用' : '禁用' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200">
|
||||
<template #default>
|
||||
<el-button type="primary" link>编辑</el-button>
|
||||
<el-button type="danger" link>删除</el-button>
|
||||
<el-table-column label="操作" width="300" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button type="warning" link @click="handleResetPassword(scope.row)">重置密码</el-button>
|
||||
<el-button
|
||||
:type="scope.row.status === 1 ? 'danger' : 'success'"
|
||||
link
|
||||
@click="handleToggleStatus(scope.row)"
|
||||
>
|
||||
{{ scope.row.status === 1 ? '禁用' : '启用' }}
|
||||
</el-button>
|
||||
<el-button type="danger" link @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-pagination
|
||||
class="pagination"
|
||||
v-model:current-page="page.current"
|
||||
v-model:page-size="page.size"
|
||||
:total="page.total"
|
||||
layout="total, sizes, prev, pager, next"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</el-card>
|
||||
|
||||
<!-- 新增/编辑对话框 -->
|
||||
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="用户名" prop="username">
|
||||
<el-input v-model="form.username" placeholder="请输入用户名" :disabled="!!form.userId" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input v-model="form.realName" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="手机号" prop="phone">
|
||||
<el-input v-model="form.phone" placeholder="请输入手机号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="form.email" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="性别">
|
||||
<el-select v-model="form.gender" placeholder="请选择" style="width: 100%">
|
||||
<el-option label="男" :value="1" />
|
||||
<el-option label="女" :value="2" />
|
||||
<el-option label="保密" :value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="职位">
|
||||
<el-input v-model="form.position" placeholder="请输入职位" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item v-if="!form.userId" label="密码" prop="password">
|
||||
<el-input v-model="form.password" type="password" placeholder="请输入密码" show-password />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 重置密码对话框 -->
|
||||
<el-dialog v-model="passwordDialogVisible" title="重置密码" width="400px">
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="新密码" prop="newPassword">
|
||||
<el-input v-model="passwordForm.newPassword" type="password" placeholder="请输入新密码" show-password />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="passwordDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handlePasswordSubmit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { getUserList, createUser, updateUser, deleteUser, resetPassword, updateUserStatus } from '../../api/user'
|
||||
|
||||
const tableData = ref([
|
||||
{ username: 'admin', realName: '管理员', phone: '13800138000', email: 'admin@example.com', status: 1 },
|
||||
{ username: 'zhangsan', realName: '张三', phone: '13800138001', email: 'zhangsan@example.com', status: 1 }
|
||||
])
|
||||
const loading = ref(false)
|
||||
const tableData = ref([])
|
||||
|
||||
const searchForm = reactive({
|
||||
username: '',
|
||||
realName: '',
|
||||
status: null
|
||||
})
|
||||
|
||||
const page = reactive({
|
||||
current: 1,
|
||||
size: 10,
|
||||
total: 0
|
||||
})
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('')
|
||||
const formRef = ref(null)
|
||||
const form = reactive({
|
||||
userId: null,
|
||||
username: '',
|
||||
password: '',
|
||||
realName: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
gender: 1,
|
||||
position: ''
|
||||
})
|
||||
|
||||
const rules = {
|
||||
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
|
||||
realName: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
||||
password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
const passwordDialogVisible = ref(false)
|
||||
const passwordForm = reactive({
|
||||
userId: null,
|
||||
newPassword: ''
|
||||
})
|
||||
|
||||
const fetchData = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getUserList({
|
||||
current: page.current,
|
||||
size: page.size,
|
||||
username: searchForm.username,
|
||||
realName: searchForm.realName,
|
||||
status: searchForm.status
|
||||
})
|
||||
tableData.value = res.records
|
||||
page.total = res.total
|
||||
} catch (error) {
|
||||
console.error('获取用户列表失败:', error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleSearch = () => {
|
||||
page.current = 1
|
||||
fetchData()
|
||||
}
|
||||
|
||||
const handleReset = () => {
|
||||
searchForm.username = ''
|
||||
searchForm.realName = ''
|
||||
searchForm.status = null
|
||||
handleSearch()
|
||||
}
|
||||
|
||||
const handleAdd = () => {
|
||||
console.log('新增用户')
|
||||
dialogTitle.value = '新增用户'
|
||||
resetForm()
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const handleEdit = (row) => {
|
||||
dialogTitle.value = '编辑用户'
|
||||
resetForm()
|
||||
Object.assign(form, row)
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const resetForm = () => {
|
||||
form.userId = null
|
||||
form.username = ''
|
||||
form.password = ''
|
||||
form.realName = ''
|
||||
form.phone = ''
|
||||
form.email = ''
|
||||
form.gender = 1
|
||||
form.position = ''
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
try {
|
||||
if (form.userId) {
|
||||
await updateUser(form.userId, form)
|
||||
ElMessage.success('更新成功')
|
||||
} else {
|
||||
await createUser(form)
|
||||
ElMessage.success('创建成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
fetchData()
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleResetPassword = (row) => {
|
||||
passwordForm.userId = row.userId
|
||||
passwordForm.newPassword = ''
|
||||
passwordDialogVisible.value = true
|
||||
}
|
||||
|
||||
const handlePasswordSubmit = async () => {
|
||||
if (!passwordForm.newPassword) {
|
||||
ElMessage.warning('请输入新密码')
|
||||
return
|
||||
}
|
||||
try {
|
||||
await resetPassword(passwordForm.userId, passwordForm.newPassword)
|
||||
ElMessage.success('密码重置成功')
|
||||
passwordDialogVisible.value = false
|
||||
} catch (error) {
|
||||
console.error('密码重置失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleToggleStatus = (row) => {
|
||||
const newStatus = row.status === 1 ? 0 : 1
|
||||
const actionText = newStatus === 1 ? '启用' : '禁用'
|
||||
ElMessageBox.confirm(`确定要${actionText}该用户吗?`, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
try {
|
||||
await updateUserStatus(row.userId, newStatus)
|
||||
ElMessage.success(`${actionText}成功`)
|
||||
fetchData()
|
||||
} catch (error) {
|
||||
console.error('状态更新失败:', error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleDelete = (row) => {
|
||||
ElMessageBox.confirm('确定要删除该用户吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
try {
|
||||
await deleteUser(row.userId)
|
||||
ElMessage.success('删除成功')
|
||||
fetchData()
|
||||
} catch (error) {
|
||||
console.error('删除失败:', error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleSizeChange = (val) => {
|
||||
page.size = val
|
||||
fetchData()
|
||||
}
|
||||
|
||||
const handleCurrentChange = (val) => {
|
||||
page.current = val
|
||||
fetchData()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@ -54,4 +337,13 @@ const handleAdd = () => {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 20px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user