This commit is contained in:
南浔
2025-07-19 14:09:58 +08:00
parent 9ce7a162c6
commit 909c6516ad
9 changed files with 666 additions and 88 deletions
+196
View File
@@ -0,0 +1,196 @@
<template>
<div>
<div class="card">
<div class="card-body">
<h5 class="card-title">{{ title }}</h5>
<p>DataTables has most features enabled by default, so all you need to do to use it with your own tables is to
call the construction function: <code>$().DataTable();</code>.</p>
<div id="zero-conf_wrapper" class="dataTables_wrapper dt-bootstrap4">
<div class="row">
<div class="col-sm-12 col-md-6">
<div class="dataTables_length" id="zero-conf_length"><label>Show <select name="zero-conf_length"
aria-controls="zero-conf" class="custom-select custom-select-sm form-control form-control-sm"
v-model="pageSize">
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select> entries</label></div>
</div>
<div class="col-sm-12 col-md-6">
<div id="zero-conf_filter" class="dataTables_filter"><label>Search:<input type="search"
class="form-control form-control-sm" placeholder="" aria-controls="zero-conf"></label></div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<table id="zero-conf" class="display dataTable" style="width:100%" role="grid"
aria-describedby="zero-conf_info">
<thead>
<tr role="row">
<th class="sorting_asc" tabindex="0" aria-controls="zero-conf" rowspan="1" colspan="1"
aria-sort="ascending" aria-label="Name: activate to sort column descending"
style="width: 85.5469px;" v-for="(item, index) in headers" :key="index">{{ item.text }}</th>
</tr>
</thead>
<tbody>
<tr role="row" v-for="(item, rowIndex) in rows" :key="rowIndex"
:class="rowIndex % 2 ? 'even' : 'odd'">
<td v-for="(header, colIndex) in headers" :key="colIndex">
{{ item[header.value] }}
</td>
</tr>
</tbody>
<tfoot>
<tr>
<th rowspan="1" colspan="1" v-for="(header, index) in headers" :key="index">{{ header.value }}</th>
</tr>
</tfoot>
</table>
</div>
</div>
<div class="row">
<div class="col-sm-12 col-md-5">
<div class="dataTables_info" id="zero-conf_info" role="status" aria-live="polite">Showing 1 to 10 of 57
entries</div>
</div>
<div class="col-sm-12 col-md-7">
<div class="dataTables_paginate paging_simple_numbers" id="zero-conf_paginate">
<ul class="pagination">
<li :class="['paginate_button', 'page-item', 'previous', (currentPageIndex == 1 ? 'disabled' : '')]"
id="zero-conf_previous"><a href="#" aria-controls="zero-conf" data-dt-idx="0" tabindex="0"
class="page-link" @click.prevent="previousPage">上一页</a></li>
<li :class="['paginate_button','page-item',item.index == currentPageIndex ? 'active' : '']"
v-for="(item,index) in pageBtn" :key="index"
><a href="#" aria-controls="zero-conf" :data-dt-idx="item.index"
tabindex="0" class="page-link" @click.prevent="currentPageIndex = item.index">{{item.text}}</a></li>
<li
:class="['paginate_button', 'page-item', 'next', (currentPageIndex == pageCount ? 'disabled' : '')]"
id="zero-conf_next"><a href="#" aria-controls="zero-conf" data-dt-idx="7" tabindex="0"
class="page-link" @click.prevent="nextPage">下一页</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "DataTable",
props: {
title: {
type: String,
default: "标题",
},
headers: {
// 表头数组 [{ text: '名字', value: 'name'}, ...]
type: Array,
required: true,
},
rows: {
// 数据数组 [{ name: '佐藤爱理', position: '会计', office: '东京', age: 33, startDate: '2008/11/28', salary: '162,700 元' }, ...]
type: Array,
required: true,
},
dataCount: {
type: Number,
required: true
}
},
data() {
return {
//当前页索引
currentPageIndex: 1,
//单页大小
pageSize: 10,
//总页数
pageCount: 0,
//分页按钮数据,[{text:'1',index:1},.....]
pageBtn: []
}
},
mounted() {
},
methods: {
//下一页
nextPage() {
if (this.currentPageIndex < this.pageCount) this.currentPageIndex++;
},
//上一页
previousPage() {
if (this.currentPageIndex > 1) {
this.currentPageIndex--
}
},
changePage(pageIndex) {
this.currentPageIndex == pageIndex
},
//更新总页数
updatePageCount(newPageSize) {
this.pageCount = Math.floor(this.dataCount / newPageSize);
this.pageCount += this.dataCount % newPageSize == 0 ? 0 : 1;
},
//更新单页数据
updateRows(newPageIndex) {
},
//更新分页按钮数据
updatePageBtn(newPageIndex){
this.pageBtn = []
//初始化首页
this.pageBtn.push({text: '1', index: 1})
//总页数小于8时显示全部页码
if(this.pageCount <= 8){
for(let i = 2; i < this.pageCount; i++){
this.pageBtn.push({text: `${i}`, index: i})
}
}else{
//当前页左侧显示2格页码,当显示最小页码距离首页中间间隔大于1时隐藏间隔页面
if(newPageIndex - 2 > 3){
this.pageBtn.push({text: '...', index: newPageIndex})
}
//渲染当前页码左右各两格页码
for(let i = newPageIndex - 2; i <= newPageIndex + 2; i++){
this.pageBtn.push({text: `${i}`, index: i})
}
//当前页右侧显示2格页码,当显示最大页码距离尾页中间间隔大于1时隐藏间隔页面
if(newPageIndex + 2 < this.pageCount - 2){
this.pageBtn.push({text: '...', index: newPageIndex})
}
}
//渲染尾页
this.pageBtn.push({text: `${this.pageCount}`, index: this.pageCount})
}
},
watch: {
//监听分页大小变化
'pageSize': {
handler(newVal) {
this.updatePageCount(newVal)
//单页显示数据量改变时重置当前索引,防止数据以及控件异常
this.currentPageIndex = 1
this.updateRows(this.currentPageIndex)
this.updatePageBtn(this.currentPageIndex)
},
immediate: true
},
//监听页索引,用于切换数据
'currentPageIndex': {
handler(newVal) {
this.updateRows(newVal)
this.updatePageBtn(newVal)
},
immediate: true
}
}
}
</script>
<style scoped>
/* 可自定义样式 */
</style>
+1
View File
@@ -12,6 +12,7 @@ import './assets/plugins/font-awesome/css/all.min.css'
import 'perfect-scrollbar'
import "perfect-scrollbar/css/perfect-scrollbar.css"
Vue.config.productionTip = false
//挂载后端请求函数到全局
+5 -1
View File
@@ -14,10 +14,14 @@ const register = async (param)=> await request.post('/api/Auth/Register',param)
//获取用户个人信息
const getUserInfo = async () => await request.get('/api/User/UserInfo')
//获取用户列表(分页)
const getUserList = async (pageIndex,pageSize,desc) => await request.get(`/api/Admin/UserList?pageIndex=${pageIndex}&pageSize=${pageSize}&desc=${desc}`)
export default {
login,
register,
SendValidateCode,
getAllConfig,
getUserInfo
getUserInfo,
getUserList
}
+1
View File
@@ -33,6 +33,7 @@ const routes = [
{
path: '/layout',
component: () => import('@/views/layout/Home.vue'),
redirect:'/layout/index',
children: [
{
path: 'index',
+2 -2
View File
@@ -138,13 +138,13 @@
<li class="sidebar-title">
主页
</li>
<li class="active-page" v-for="item in routeMenu.filter(x => x.meta.isHome)" :key="item.path">
<li :class="{ 'active-page' : $route.path.endsWith(item.path) }" v-for="item in routeMenu.filter(x => x.meta.isHome)" :key="item.path">
<router-link :to="item.path"><i :data-feather="item.meta.icon"></i>{{item.meta.title}}</router-link>
</li>
<li class="sidebar-title">
菜单
</li>
<li v-for="item in routeMenu.filter(x => !x.meta.isHome)" :key="item.path">
<li :class="{ 'active-page' : $route.path.endsWith(item.path) }" v-for="item in routeMenu.filter(x => !x.meta.isHome)" :key="item.path">
<router-link :to="item.path"><i :data-feather="item.meta.icon"></i>{{item.meta.title}}</router-link>
</li>
</ul>
+128
View File
@@ -0,0 +1,128 @@
<template>
<div class="main-wrapper">
<div class="row">
<div class="col">
<DataTable :title="'员工信息表'" :headers="tableHeaders" :rows="tableData" :data-count="dataCount"/>
</div>
</div>
</div>
</template>
<script>
import DataTable from '@/components/DataTable.vue';
export default {
components: { DataTable },
data() {
return {
dataCount:11,
tableHeaders: [
{ text: "名字", value: "name", width: "155px" },
{ text: "位置", value: "position", width: "214px" },
{ text: "办公室", value: "office", width: "48px" },
{ text: "年龄", value: "age", width: "29px" },
{ text: "开始日期", value: "startDate", width: "82px" },
{ text: "工资", value: "salary", width: "103px" },
],
tableData: [
{
name: "佐藤爱理",
position: "会计",
office: "东京",
age: 33,
startDate: "2008/11/28",
salary: "162,700 元",
},
{
name: "安吉莉卡·拉莫斯",
position: "首席执行官 CEO",
office: "伦敦",
age: 47,
startDate: "2009/10/09",
salary: "1,200,000 美元",
},
{
name: "安吉莉卡·拉莫斯",
position: "首席执行官 CEO",
office: "伦敦",
age: 47,
startDate: "2009/10/09",
salary: "1,200,000 美元",
},
{
name: "安吉莉卡·拉莫斯",
position: "首席执行官 CEO",
office: "伦敦",
age: 47,
startDate: "2009/10/09",
salary: "1,200,000 美元",
},
{
name: "安吉莉卡·拉莫斯",
position: "首席执行官 CEO",
office: "伦敦",
age: 47,
startDate: "2009/10/09",
salary: "1,200,000 美元",
},
{
name: "安吉莉卡·拉莫斯",
position: "首席执行官 CEO",
office: "伦敦",
age: 47,
startDate: "2009/10/09",
salary: "1,200,000 美元",
},
{
name: "安吉莉卡·拉莫斯",
position: "首席执行官 CEO",
office: "伦敦",
age: 47,
startDate: "2009/10/09",
salary: "1,200,000 美元",
},
{
name: "安吉莉卡·拉莫斯",
position: "首席执行官 CEO",
office: "伦敦",
age: 47,
startDate: "2009/10/09",
salary: "1,200,000 美元",
},
{
name: "安吉莉卡·拉莫斯",
position: "首席执行官 CEO",
office: "伦敦",
age: 47,
startDate: "2009/10/09",
salary: "1,200,000 美元",
},
{
name: "安吉莉卡·拉莫斯",
position: "首席执行官 CEO",
office: "伦敦",
age: 47,
startDate: "2009/10/09",
salary: "1,200,000 美元",
},
// 其他数据...
],
};
},
methods: {
async loadUserList(pageIndex = 1, pageSize = 10, desc = false){
try{
const res = await this.$api.getUserList(pageIndex,pageSize,desc)
console.log(res)
}catch(e){
this.$alert('用户列表数据加载失败!','danger')
console.error(e)
}
}
},
mounted(){
this.loadUserList()
}
};
</script>
-79
View File
@@ -1,79 +0,0 @@
<template>
<div :class="active">
<div class='loader'>
<div class='spinner-grow text-primary' role='status'>
<span class='sr-only'>Loading...</span>
</div>
</div>
<div class="container">
<div class="row justify-content-md-center">
<div class="col-md-12 col-lg-4">
<div class="card login-box-container">
<div class="card-body">
<div class="authent-logo">
<img src="../../assets/images/logo@2x.png" alt="">
</div>
<div class="authent-text">
<p>Welcome to IO!</p>
<p>Please Sign-in to your account.</p>
</div>
<form>
<div class="mb-3">
<div class="form-floating">
<input type="text" class="form-control" id="floatingInput" placeholder="账号" v-model="username">
<label for="floatingInput">账号</label>
</div>
</div>
<div class="mb-3">
<div class="form-floating">
<input type="password" class="form-control" id="floatingPassword" placeholder="密码" v-model="password">
<label for="floatingPassword">密码</label>
</div>
</div>
<!-- <div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="exampleCheck1">
<label class="form-check-label" for="exampleCheck1">Check me out</label>
</div> -->
<div class="d-grid">
<button type="submit" class="btn btn-info m-b-xs" @click="submit()">登录</button>
</div>
</form>
<div class="authent-reg">
<p>没有账号<RouterLink to="/registered">注册</RouterLink></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { login_api } from '@/request/api'
export default {
name: 'Login',
data() {
return {
active: 'login-page',
username: '',
password :''
}
},
mounted() {
this.active = 'login-page no-loader'
},
methods: {
async submit(){
let res=await login_api({username:this.username,password:this.password})
if (res.code == 2000) {
console.log('登录成功')
this.$router.push('/home')
}else{
console.log(res.msg);
}
}
},
}
</script>