This commit is contained in:
DESKTOP-VMMLSOQ\wangzg 2024-06-25 00:23:39 +08:00
parent 25d5677540
commit 49c083f6c4
6 changed files with 447 additions and 71 deletions

View File

@ -0,0 +1,225 @@
<template>
<div style="text-align: left">
<div class="table-search">
<a-form class="ant-advanced-search-form" :form="form" @submit="handleSearch" layout="inline" @change="handleSearchFormChange">
<a-form-item v-for="menuItem in searchItems" :key="menuItem.key" :label="menuItem.label">
<a-input
v-decorator="[menuItem.key]"
:placeholder="menuItem.placeholder || ''"
v-if="menuItem.type === 'input'"
/>
<a-select
v-decorator="[menuItem.key]"
:placeholder="menuItem.placeholder || ''"
v-else-if="menuItem.type === 'select'"
>
<a-select-option :value="cItem.value" v-for="cItem in menuItem.children || []" :key="cItem.value">{{ cItem.label }}</a-select-option>
</a-select>
<a-range-picker
:placeholder="menuItem.placeholder || ''" v-decorator="[menuItem.key]" v-else-if="menuItem.type === 'dateRange'" format="YYYY-MM-DD" />
</a-form-item>
<a-form-item>
<a-button type="primary" html-type="submit">查询</a-button>
<a-button :style="{ marginLeft: '8px' }" @click="reset">重置</a-button>
</a-form-item>
</a-form>
</div>
<a-divider />
<div class="table-operations">
<a-button @click="addRow" type="primary">
添加
</a-button>
</div>
<a-table :columns="realColumns" :data-source="tableDataSource" @change="handleChange" >
<span slot="action" slot-scope="text, record">
<a-button type="danger" size="small" @click="deleteRow(record)">删除</a-button>
<a-divider type="vertical" />
<a-button type="primary" size="small" @click="editRow(record)">编辑</a-button>
</span>
</a-table>
<a-modal
:title="dialog.title"
:visible="dialog.visible"
:confirm-loading="dialog.loading"
@ok="handleOk"
@cancel="handleCancel"
>
<a-form class="ant-advanced-search-form" :form="editForm" @submit="handleSearch" @change="handleSearchFormChange">
<a-form-item v-for="menuItem in formItems" :key="menuItem.key" :label="menuItem.label">
<a-input
v-decorator="[menuItem.key]"
:placeholder="menuItem.placeholder || ''"
v-if="menuItem.type === 'input'"
/>
<a-select
v-decorator="[menuItem.key]"
:placeholder="menuItem.placeholder || ''"
v-else-if="menuItem.type === 'select'"
>
<a-select-option
:placeholder="menuItem.placeholder || ''" :value="cItem.value" v-for="cItem in menuItem.children || []" :key="cItem.value">{{ cItem.label }}</a-select-option>
</a-select>
<a-range-picker v-decorator="[menuItem.key]" v-else-if="menuItem.type === 'dateRange'" format="YYYY-MM-DD" />
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
export default {
name: "user",
data () {
return {
tableDataSource: [],
form: this.$form.createForm(this, { name: `form_${new Date().valueOf()}` }),
editForm: this.$form.createForm(this, { name: `edit_form_${new Date().valueOf()}` }),
dialog: {
title: '',
visible: false,
isEdit: '',
loading: false
},
selectRow: null,
page: {
pageSize: 10,
pageNo: 1
},
searchFormModel: {}
}
},
props: {
//
formItems: {
type: Array,
default: ()=> []
},
//
columns: {
type: Array,
default: ()=> []
},
primaryKey: {
type: String,
default: 'id'
},
apiConf: {
type: Object,
default: () => ({})
}
},
computed: {
searchItems () {
return this.formItems.filter(item => !!item.isSearch)
},
realColumns () {
return [
...this.columns,
{
title: '操作',
dataIndex: 'action',
scopedSlots: { customRender: 'action' },
fixed: 'right',
width: 155
},
]
}
},
watch: {
},
mounted() {
this.handleSearch()
},
methods: {
handleSearchFormChange(changedFields) {
this.searchFormModel = { ...this.searchFormModel, ...changedFields }
},
addRow () {
this.handleCancel()
this.dialog.visible = true
},
editRow(row) {
this.selectRow = row
this.dialog.title = '添加'
this.dialog.visible = true
this.dialog.isEdit = true
this.dialog.loading = false
},
deleteRow(row) {
this.$confirm({
title: '确认要删除么?',
okText: '确认',
okType: 'danger',
cancelText: '再想想',
onOk() {
this.$post(this.apiConf.deleteApi, {
[this.primaryKey]: row[this.primaryKey],
})
}
});
},
handleChange ({ pageSize, pageNo }) {
this.page.pageSize = pageSize
this.page.pageNo = pageNo
this.handleSearch()
},
reset() {
this.form.resetFields();
},
async handleSearch(e) {
e && e.preventDefault();
const values = this.form.getFieldsValue()
const { data } = await this.$get(this.apiConf.listApi, {
...values,
pageSize: this.page.pageSize,
current: this.page.pageNo,
})
this.tableDataSource = data.items
},
async handleOk() {
const values = this.editForm.getFieldsValue()
if (this.dialog.isEdit) {
await this.$post(this.apiConf.editApi, {
[this.primaryKey]: this.selectRow[this.primaryKey],
...values
})
} else {
debugger
await this.$post(this.apiConf.addApi, values)
}
this.handleCancel()
this.handleSearch()
},
handleCancel() {
this.editRow = null
this.dialog.title = '添加'
this.dialog.visible = false
this.dialog.isEdit = false
this.dialog.loading = false
},
}
}
</script>
<style scoped lang="less">
.table-operations {
margin-bottom: 16px;
}
.ant-form-item {
margin-bottom: 0;
}
.ant-divider-horizontal {
margin: 16px 0;
}
.table-operations > button {
margin-right: 8px;
}
</style>

View File

@ -2,44 +2,16 @@
<a-layout id="components-layout-demo-fixed-sider"> <a-layout id="components-layout-demo-fixed-sider">
<a-layout-sider :trigger="null" v-model="collapsed" collapsible> <a-layout-sider :trigger="null" v-model="collapsed" collapsible>
<div class="logo"> <div class="logo">
管理系统 欢迎
</div> </div>
<a-menu theme="dark" mode="inline" :default-selected-keys="['4']"> <a-menu theme="dark" mode="inline" v-model="selectedKeys">
<a-menu-item key="1"> <a-menu-item key="1" v-for="item in menus" :key="item.key">
<a-icon type="user" /> <a-icon :type="item.icon"/>
<span class="nav-text">nav 1</span> <span class="nav-text">{{ item.title }}</span>
</a-menu-item>
<a-menu-item key="2">
<a-icon type="video-camera" />
<span class="nav-text">nav 2</span>
</a-menu-item>
<a-menu-item key="3">
<a-icon type="upload" />
<span class="nav-text">nav 3</span>
</a-menu-item>
<a-menu-item key="4">
<a-icon type="bar-chart" />
<span class="nav-text">nav 4</span>
</a-menu-item>
<a-menu-item key="5">
<a-icon type="cloud-o" />
<span class="nav-text">nav 5</span>
</a-menu-item>
<a-menu-item key="6">
<a-icon type="appstore-o" />
<span class="nav-text">nav 6</span>
</a-menu-item>
<a-menu-item key="7">
<a-icon type="team" />
<span class="nav-text">nav 7</span>
</a-menu-item>
<a-menu-item key="8">
<a-icon type="shop" />
<span class="nav-text">nav 8</span>
</a-menu-item> </a-menu-item>
</a-menu> </a-menu>
</a-layout-sider> </a-layout-sider>
<a-layout > <a-layout>
<a-layout-header <a-layout-header
style="background: #fff; padding: 0" style="background: #fff; padding: 0"
ref="header" ref="header"
@ -53,17 +25,17 @@
:type="collapsed ? 'menu-unfold' : 'menu-fold'" :type="collapsed ? 'menu-unfold' : 'menu-fold'"
@click="() => (collapsed = !collapsed)" @click="() => (collapsed = !collapsed)"
/> />
<a-icon type="arrow-left" style="font-size: 18px; padding-right: 24px;" /> <a-menu class="cus-menu">
<a-breadcrumb :routes="routes"> <a-sub-menu>
<template slot="itemRender" slot-scope="{ route, params, routes, paths }"> <span slot="title" class="submenu-title-wrapper">
<span v-if="routes.indexOf(route) === routes.length - 1"> <a-icon type="setting"/>
{{ route.breadcrumbName }} 操作
</span> </span>
<router-link v-else :to="`/${paths.join('/')}`"> <a-menu-item key="setting:2">修改密码</a-menu-item>
{{ route.breadcrumbName }} <a-menu-item key="setting:1">退出</a-menu-item>
</router-link> </a-sub-menu>
</template> </a-menu>
</a-breadcrumb>
</div> </div>
@ -73,9 +45,9 @@
<nuxt/> <nuxt/>
</div> </div>
</a-layout-content> </a-layout-content>
<!-- <a-layout-footer :style="{ textAlign: 'center' }" ref="footer"> <!-- <a-layout-footer :style="{ textAlign: 'center' }" ref="footer">
Ant Design ©2018 Created by Ant UED Ant Design ©2018 Created by Ant UED
</a-layout-footer>--> </a-layout-footer>-->
</a-layout> </a-layout>
</a-layout> </a-layout>
</template> </template>
@ -83,7 +55,7 @@
<script> <script>
export default { export default {
name: "manager", name: "manager",
data () { data() {
return { return {
collapsed: false, collapsed: false,
headerHeight: 0, headerHeight: 0,
@ -94,18 +66,41 @@ export default {
breadcrumbName: 'First-level Menu', breadcrumbName: 'First-level Menu',
}, },
], ],
pageTitle: '123' pageTitle: '123',
menus: [
{
link: '/manager/user',
title: '用户管理',
icon: 'user',
key: 'manager-user'
},
{
link: '/manager/role',
title: '角色管理',
icon: 'user',
key: 'manager-role'
}
],
selectedKeys: []
}
},
watch: {
'$route': {
immediate: true,
handler (to) {
this.selectedKeys = [to.name]
}
} }
}, },
computed: { computed: {
contentStyle () { contentStyle() {
return { return {
margin: '24px 16px 24px', margin: '24px 16px 24px',
overflow: 'inherit', overflow: 'inherit',
height: `calc(100vh - ${this.headerHeight + this.footerHeight + 48}px)`, height: `calc(100vh - ${this.headerHeight + this.footerHeight + 48}px)`,
} }
}, },
containerStyle () { containerStyle() {
return { return {
padding: '24px', padding: '24px',
background: '#fff', background: '#fff',
@ -115,8 +110,8 @@ export default {
} }
} }
}, },
mounted () { mounted() {
this.$nextTick( () => { this.$nextTick(() => {
if (this.$refs.header) { if (this.$refs.header) {
this.headerHeight = this.$refs.header.$el.offsetHeight this.headerHeight = this.$refs.header.$el.offsetHeight
// this.footerHeight = this.$refs.footer.$el.offsetHeight // this.footerHeight = this.$refs.footer.$el.offsetHeight
@ -127,15 +122,23 @@ export default {
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
.cus-menu {
/deep/ .ant-menu-submenu-arrow {
display: none;
}
}
#components-layout-demo-fixed-sider { #components-layout-demo-fixed-sider {
.header-con { .header-con {
width: 100%;
display: flex; display: flex;
justify-content: flex-start; justify-content: space-between;
align-items: center; align-items: center;
} }
.trigger:hover { .trigger:hover {
color: #1890ff; color: #1890ff;
} }
.trigger { .trigger {
font-size: 18px; font-size: 18px;
line-height: 64px; line-height: 64px;
@ -143,6 +146,7 @@ export default {
cursor: pointer; cursor: pointer;
transition: color 0.3s; transition: color 0.3s;
} }
.logo { .logo {
width: 80%; width: 80%;
padding: 0 10px; padding: 0 10px;

63
pages/manager/role.vue Normal file
View File

@ -0,0 +1,63 @@
<template>
<div>
<Curd
:columns="columns"
:api-conf="apiConf"
:form-items="formItems"
/>
</div>
</template>
<script>
import base from "~/templates/base";
import Curd from "../../components/smallCommon/Curd.vue";
export default {
name: "role",
extends: base,
components: {
Curd
},
data () {
return {
columns: [
{
dataIndex: 'roleName',
key: 'roleName',
title: '角色名'
},
{
dataIndex: 'roleDescription',
key: 'roleDescription',
title: '角色描述'
}
],
formItems: [
{
type: 'input',
key: 'roleName',
label: '角色名',
isSearch: true,
placeholder: '请输入角色名',
},
{
dataIndex: 'roleDescription',
key: 'roleDescription',
title: '角色描述'
}
],
apiConf: {
listApi: '/api/Role/all',
deleteApi: '/api/Role/remove',
editApi: '/api/Role/update',
addApi: '/api/Role/update',
}
}
}
}
</script>
<style scoped lang="less">
</style>

View File

@ -1,15 +0,0 @@
<template>
<div>test</div>
</template>
<script>
import base from "~/templates/base";
export default {
name: "test",
extends: base,
}
</script>
<style scoped>
</style>

85
pages/manager/user.vue Normal file
View File

@ -0,0 +1,85 @@
<template>
<div>
<Curd
:columns="columns"
:api-conf="apiConf"
:form-items="formItems"
/>
</div>
</template>
<script>
import base from "~/templates/base";
import Curd from "../../components/smallCommon/Curd.vue";
export default {
name: "user",
extends: base,
components: {
Curd
},
data () {
return {
columns: [
{
dataIndex: 'username',
key: 'username',
title: '用户名'
},
{
dataIndex: 'email',
key: 'email',
title: '邮箱'
},
{
dataIndex: 'phone',
key: 'phone',
title: '电话'
},
{
dataIndex: 'roleId',
key: 'roleId',
title: '角色'
}
],
formItems: [
{
type: 'input',
key: 'username',
label: '用户名',
isSearch: true,
placeholder: '请输入用户名',
},
{
type: 'input',
key: 'password',
label: '密码',
placeholder: '请输入密码'
},
{
type: 'input',
key: 'email',
label: '邮箱',
placeholder: '请输入邮箱',
},
{
type: 'input',
key: 'phone',
label: '电话',
placeholder: '请输入电话',
}
],
apiConf: {
listApi: '/api/User/List',
deleteApi: '/api/User/DeleteUser',
editApi: '/api/User/UpdateUser',
addApi: '/api/User/Add',
}
}
}
}
</script>
<style scoped lang="less">
</style>

View File

@ -4,7 +4,7 @@ import Vue from 'vue'
axios.defaults.withcredentials =true axios.defaults.withcredentials =true
// create an axios instance // create an axios instance
const service = axios.create({ const service = axios.create({
baseURL: '', // 所有异步请求都加上/api,nginx转发到后端Springboot baseURL: process.env.NODE_ENV === 'development' ? '' : 'http://101.43.201.20', // 所有异步请求都加上/api,nginx转发到后端Springboot
timeout: 5000 // request timeout timeout: 5000 // request timeout
}) })
@ -38,3 +38,17 @@ service.interceptors.response.use(
) )
Vue.prototype.$http = service Vue.prototype.$http = service
Vue.prototype.$post = (url, data) => {
return service({
url,
method: "post",
data
})
}
Vue.prototype.$get = (url, data) => {
return service({
url,
method: "get",
params: data
})
}