This commit is contained in:
MeSHard
2025-11-20 18:08:12 +08:00
parent 26ecddea1e
commit 186a92e834
2 changed files with 444 additions and 473 deletions

View File

@@ -48,47 +48,43 @@
ruleInline: {}, ruleInline: {},
columns: [{ columns: [{
title: '充电站名称', title: '充电站名称',
key: 'id', key: 'charge_station_name',
}, },
{ {
title: '桩类型', title: '桩类型',
key: 'out_trade_no', key: 'type',
}, },
{ {
title: '桩数量', title: '桩数量',
key: 'openid', key: 'pile_num_2',
}, },
{ {
title: '枪数量', title: '枪数量',
key: 'total', key: 'pile_num',
}, },
{ {
title: '充电次数', title: '充电次数(次)',
key: 'total_used', key: 'order_num',
}, },
{ {
title: '充电电量(度)', title: '充电电量(度)',
key: 'trade_state', key: 'power',
}, },
{ {
title: '充电金额(元)', title: '充电金额(元)',
key: 'success_time', key: 'money',
}, },
{ {
title: '电费', title: '电费(元)',
key: 'success_time', key: 'elec',
}, },
{ {
title: '服务费', title: '服务费(元)',
key: 'success_time', key: 'sevice',
}, },
{ {
title: '总时长', title: '总时长(小时)',
key: 'success_time', key: 'length',
},
{
title: '尖峰平谷电量',
key: 'success_time',
}, },
{ {
title: '操作', title: '操作',
@@ -121,9 +117,8 @@
page: this.page, page: this.page,
pageSize: this.pageSize, pageSize: this.pageSize,
}).then((res) => { }).then((res) => {
this.total = res.total this.total = res.data.total
this.data = res.data this.data = res.data.data
this.page = res.current_page
}) })
}, },
handleSubmit(name) { handleSubmit(name) {

View File

@@ -3,12 +3,7 @@
<div class="search-area"> <div class="search-area">
<Form ref="searchForm" inline :label-width="100" :model="formInline"> <Form ref="searchForm" inline :label-width="100" :model="formInline">
<FormItem prop="username" label="用户名:"> <FormItem prop="username" label="用户名:">
<Input <Input v-model="formInline.username" clearable placeholder="请输入用户名" @on-enter="handleSubmit" />
v-model="formInline.username"
clearable
placeholder="请输入用户名"
@on-enter="handleSubmit"
/>
</FormItem> </FormItem>
<FormItem> <FormItem>
<Button type="primary" @click="handleSubmit">搜索</Button> <Button type="primary" @click="handleSubmit">搜索</Button>
@@ -20,41 +15,22 @@
<Button type="primary" @click="handleAdd">添加用户</Button> <Button type="primary" @click="handleAdd">添加用户</Button>
</div> </div>
<div class="table-container"> <div class="table-container">
<Table <Table border stripe :loading="tableLoading" :columns="columns" :height="tableHeight" :data="data">
border
stripe
:loading="tableLoading"
:columns="columns"
:height="tableHeight"
:data="data"
>
<template #roles="{ row }"> <template #roles="{ row }">
<span>{{ formatRoleLabel(row.roles) }}</span> <span>{{ formatRoleLabel(row.roles) }}</span>
</template> </template>
<template #action="{ row }"> <template #action="{ row }">
<Button type="primary" size="small" style="margin-right: 5px" @click="handleEdit(row.id)">编辑</Button> <Button type="primary" size="small" style="margin-right: 5px"
@click="handleEdit(row.id)">编辑</Button>
<Button type="error" size="small" @click="handleRemove(row.id)">删除</Button> <Button type="error" size="small" @click="handleRemove(row.id)">删除</Button>
</template> </template>
</Table> </Table>
<Page
:current="page" <Page :total="total" show-total show-sizer class="page" @on-change="onChangePage"
:page-size="pageSize" @on-page-size-change="onChangePageSize" />
:total="total"
show-total
show-sizer
show-elevator
class="page"
@on-change="onChangePage"
@on-page-size-change="onChangePageSize"
/>
</div> </div>
<Modal <Modal v-model="showModal" :title="modalTitle" :mask-closable="false" @on-cancel="cancel">
v-model="showModal"
:title="modalTitle"
:mask-closable="false"
@on-cancel="cancel"
>
<Form ref="formValidate" :model="formValidate" :rules="formRules" :label-width="100"> <Form ref="formValidate" :model="formValidate" :rules="formRules" :label-width="100">
<FormItem label="用户名" prop="username" :required="true"> <FormItem label="用户名" prop="username" :required="true">
<Input v-model="formValidate.username" placeholder="请输入用户名" /> <Input v-model="formValidate.username" placeholder="请输入用户名" />
@@ -63,12 +39,8 @@
<Input v-model="formValidate.nickname" placeholder="请输入姓名" /> <Input v-model="formValidate.nickname" placeholder="请输入姓名" />
</FormItem> </FormItem>
<FormItem label="登录密码" prop="password" :required="!isEdit"> <FormItem label="登录密码" prop="password" :required="!isEdit">
<Input <Input type="password" password v-model="formValidate.password"
type="password" :placeholder="isEdit ? '不修改可留空' : '请输入登录密码'" />
password
v-model="formValidate.password"
:placeholder="isEdit ? '不修改可留空' : '请输入登录密码'"
/>
</FormItem> </FormItem>
<FormItem label="手机号" prop="phone" :required="true"> <FormItem label="手机号" prop="phone" :required="true">
<Input v-model="formValidate.phone" placeholder="请输入11位手机号" /> <Input v-model="formValidate.phone" placeholder="请输入11位手机号" />
@@ -91,16 +63,16 @@
</template> </template>
<script> <script>
import { import {
getAdminList, getAdminList,
addAdmin, addAdmin,
getAdmin, getAdmin,
getAdminUpdate, getAdminUpdate,
getAdminDelete, getAdminDelete,
getRoleList, getRoleList,
} from '@/api' } from '@/api'
const createDefaultForm = () => ({ const createDefaultForm = () => ({
id: '', id: '',
username: '', username: '',
nickname: '', nickname: '',
@@ -108,9 +80,9 @@ const createDefaultForm = () => ({
email: '', email: '',
phone: '', phone: '',
roles: '', roles: '',
}) })
export default { export default {
name: 'system_admin', name: 'system_admin',
data() { data() {
return { return {
@@ -125,8 +97,7 @@ export default {
username: '', username: '',
}, },
// 表格列的结构描述,保持字段展示的一致性 // 表格列的结构描述,保持字段展示的一致性
columns: [ columns: [{
{
title: 'ID', title: 'ID',
key: 'id', key: 'id',
minWidth: 80, minWidth: 80,
@@ -177,24 +148,32 @@ export default {
}, },
formRules() { formRules() {
return { return {
username: [ username: [{
{ required: true, message: '请输入用户名', trigger: 'blur' }, required: true,
], message: '请输入用户名',
nickname: [ trigger: 'blur',
{ required: true, message: '请输入姓名', trigger: 'blur' }, }],
], nickname: [{
password: [ required: true,
{ validator: this.validatePassword, trigger: 'blur' }, message: '请输入姓名',
], trigger: 'blur',
phone: [ }],
{ validator: this.validatePhone, trigger: 'blur' }, password: [{
], validator: this.validatePassword,
email: [ trigger: 'blur',
{ validator: this.validateEmail, trigger: 'blur' }, }],
], phone: [{
roles: [ validator: this.validatePhone,
{ validator: this.validateRoles, trigger: 'change' }, trigger: 'blur',
], }],
email: [{
validator: this.validateEmail,
trigger: 'blur',
}],
roles: [{
validator: this.validateRoles,
trigger: 'change',
}],
} }
}, },
}, },
@@ -213,15 +192,11 @@ export default {
return createDefaultForm() return createDefaultForm()
}, },
calculateTableHeight() { calculateTableHeight() {
// 根据浏览器高度动态计算表格剩余空间,保证页面结构自适应 const searchHeight = document.querySelector('.search-area').offsetHeight
const searchArea = document.querySelector('.search-area') const pageHeight = 32 // 分页组件大约高度
const actionArea = document.querySelector('.action-btn') const margins = 40 // 上下边距总和
const searchHeight = searchArea ? searchArea.offsetHeight : 0 this.tableHeight = window.innerHeight - searchHeight - pageHeight - margins - 230
const actionHeight = actionArea ? actionArea.offsetHeight : 0 console.log(this.tableHeight)
const pageHeight = 70
const basePadding = 80
const height = window.innerHeight - searchHeight - actionHeight - pageHeight - basePadding
this.tableHeight = height > 320 ? height : 320
}, },
async fetchRoles() { async fetchRoles() {
// 角色列表仅需偶尔变动,进入页面时加载一次即可 // 角色列表仅需偶尔变动,进入页面时加载一次即可
@@ -234,7 +209,6 @@ export default {
} }
}, },
async getList() { async getList() {
// 列表查询会根据分页与搜索条件拼接参数,接口结果兼容 data/list 两种结构
this.tableLoading = true this.tableLoading = true
try { try {
const res = await getAdminList({ const res = await getAdminList({
@@ -242,10 +216,8 @@ export default {
pageSize: this.pageSize, pageSize: this.pageSize,
...this.formInline, ...this.formInline,
}) })
const responseData = res.data || {} this.data = res.data.data
const list = responseData.data || responseData.list || [] this.total = res.data.total
this.data = Array.isArray(list) ? list : []
this.total = typeof responseData.total === 'number' ? responseData.total : (res.total || 0)
} finally { } finally {
this.tableLoading = false this.tableLoading = false
} }
@@ -265,7 +237,9 @@ export default {
async handleEdit(id) { async handleEdit(id) {
// 编辑前需要获取详情,避免列表中数据字段不完整 // 编辑前需要获取详情,避免列表中数据字段不完整
try { try {
const res = await getAdmin({ id }) const res = await getAdmin({
id,
})
const detail = res.data || {} const detail = res.data || {}
this.formValidate = { this.formValidate = {
id: detail.id, id: detail.id,
@@ -295,7 +269,9 @@ export default {
return return
} }
try { try {
await getAdminDelete({ id }) await getAdminDelete({
id,
})
this.$Message.success('删除成功') this.$Message.success('删除成功')
if (this.data.length === 1 && this.page > 1) { if (this.data.length === 1 && this.page > 1) {
this.page -= 1 this.page -= 1
@@ -421,18 +397,18 @@ export default {
} }
}, },
}, },
} }
</script> </script>
<style scoped> <style scoped>
.container { .container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100vh; height: 100vh;
padding: 20px; padding: 20px;
box-sizing: border-box; box-sizing: border-box;
} }
.action-btn { .action-btn {
margin: 20px 0; margin: 20px 0;
background-color: white; background-color: white;
padding: 20px; padding: 20px;
@@ -440,27 +416,27 @@ export default {
border-radius: 15px; border-radius: 15px;
display: flex; display: flex;
align-items: center; align-items: center;
} }
.action-btn button { .action-btn button {
margin-right: 20px; margin-right: 20px;
} }
.table-container { .table-container {
flex: 1; flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.page { .page {
margin-top: 10px; margin-top: 10px;
text-align: right; text-align: right;
} }
.search-area { .search-area {
background-color: white; background-color: white;
padding: 20px; padding: 20px;
border: 1px solid #F3F7FD; border: 1px solid #F3F7FD;
border-radius: 15px; border-radius: 15px;
} }
</style> </style>