import { defineComponent, computed, unref } from 'vue' | import { defineComponent, computed, unref } from 'vue' | ||||
export default defineComponent({ | export default defineComponent({ | ||||
name: 'CardModal', | |||||
name: 'Modal', | |||||
props: { | props: { | ||||
options: { | options: { | ||||
type: Object, | type: Object, |
props: { | props: { | ||||
...tableProps | ...tableProps | ||||
}, | }, | ||||
emits: [ | |||||
'fetch-success', | |||||
'fetch-error', | |||||
'update:checked-row-keys', | |||||
'edit-end', | |||||
'edit-cancel', | |||||
'edit-row-end', | |||||
'edit-change' | |||||
], | |||||
setup(props, { emit }) { | setup(props, { emit }) { | ||||
const getProps = computed(() => { | const getProps = computed(() => { | ||||
return { ...props } | return { ...props } | ||||
} | } | ||||
}) | }) | ||||
emit('fetch-success', isRequest ? unref(getDataSourceRef) : unref(getProps).data) | |||||
const key = Symbol('s-table') | const key = Symbol('s-table') | ||||
provide(key, { getBindProps }) | provide(key, { getBindProps }) | ||||
/* tableData-end */ | /* tableData-end */ |
<script> | <script> | ||||
import { defineComponent, computed, unref } from 'vue' | import { defineComponent, computed, unref } from 'vue' | ||||
import { isArray } from '@/utils/is.js' | |||||
export default defineComponent({ | export default defineComponent({ | ||||
name: 'TableTags', | name: 'TableTags', | ||||
props: { | props: { | ||||
/* 展示的数据 */ | /* 展示的数据 */ | ||||
data: { | data: { | ||||
type: Object, | |||||
defalut: [], | |||||
type: [Array, String, Number], | |||||
required: true | required: true | ||||
}, | }, | ||||
/* 展示数据取的字段 */ | /* 展示数据取的字段 */ | ||||
const getData = computed(() => { | const getData = computed(() => { | ||||
return { | return { | ||||
rowKey: unref(props.rowKey), | rowKey: unref(props.rowKey), | ||||
data: { ...unref(props.data) }, | |||||
data: isArray(props.data) ? { ...unref(props.data) } : [{ [props.rowKey]: props.data }], | |||||
filters: { ...unref(props.filters) } | filters: { ...unref(props.filters) } | ||||
} | } | ||||
}) | }) |
<template> | |||||
<div> | |||||
<n-upload | |||||
action="#" | |||||
:default-file-list="fileList" | |||||
list-type="image-card" | |||||
> | |||||
点击上传 | |||||
</n-upload> | |||||
<n-modal | |||||
v-model:show="showModal" | |||||
preset="card" | |||||
style="width: 600px" | |||||
title="一张很酷的图片" | |||||
> | |||||
<img :src="previewImageUrl" style="width: 100%"> | |||||
</n-modal> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
name: 'ImgUpload', | |||||
props: { | |||||
options: { | |||||
type: Object, | |||||
default: null | |||||
} | |||||
}, | |||||
setup() { | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
</style> |
<template> | |||||
<n-modal | |||||
v-bind="getModalOptions" | |||||
:style="`width:${getModalOptions.width}px`" | |||||
:title="options.title" | |||||
> | |||||
<n-card :bordered="false"> | |||||
<slot name="Context" /> | |||||
</n-card> | |||||
</n-modal> | |||||
</template> | |||||
<script> | |||||
import { defineComponent, computed } from 'vue' | |||||
export default defineComponent({ | |||||
props: { | |||||
options: { | |||||
type: Object, | |||||
default: () => {} | |||||
} | |||||
}, | |||||
emits: { | |||||
onConfirm: null, | |||||
onClose: (value) => { | |||||
return value | |||||
} | |||||
}, | |||||
setup(props, { emit }) { | |||||
const getModalOptions = computed(() => { | |||||
return { | |||||
...props.options, | |||||
width: props.options.width || 600, | |||||
preset: props.options.preset || 'dialog', | |||||
showIcon: !!props.options.showIcon | |||||
} | |||||
}) | |||||
const handleConfirm = function() { | |||||
emit('onConfirm') | |||||
return false | |||||
} | |||||
const handleClose = function() { | |||||
emit('onClose', true) | |||||
} | |||||
return { | |||||
getModalOptions, | |||||
handleConfirm, | |||||
handleClose | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
</style> |
<template> | <template> | ||||
<Modal :options="getModalOptions" @on-close="handleClose"> | |||||
<Modal | |||||
:options="getModalOptions" | |||||
:on-close="handleClose" | |||||
:on-positive-click="handleConfirm" | |||||
:on-negative-click="handleClose" | |||||
> | |||||
<template #Context> | <template #Context> | ||||
111 | |||||
<n-form ref="formRef" :model="menuForm" :rules="menuRules" require-mark-placement="left" :label-width="80" label-placement="left"> | |||||
<n-grid x-gap="12" :cols="2"> | |||||
<n-gi> | |||||
<n-form-item label="上级菜单" path="pid"> | |||||
<n-select | |||||
v-model:value="menuForm.pid" | |||||
placeholder="请选择上级菜单" | |||||
:options="getMenuList" | |||||
/> | |||||
</n-form-item> | |||||
</n-gi> | |||||
<n-gi> | |||||
<n-form-item label="菜单类型" path="type"> | |||||
<n-radio-group v-model:value="menuForm.type" name="type"> | |||||
<n-radio v-for="item in typeOptions" :key="`type_${item.key}`" :value="item.key"> | |||||
{{ item.label }} | |||||
</n-radio> | |||||
</n-radio-group> | |||||
</n-form-item> | |||||
</n-gi> | |||||
<n-gi> | |||||
<n-form-item label="菜单名称" path="title"> | |||||
<n-input v-model:value="menuForm.title" placeholder="请输入菜单名称" /> | |||||
</n-form-item> | |||||
</n-gi> | |||||
<n-gi> | |||||
<n-form-item label="打开方式" path="target"> | |||||
<n-radio-group v-model:value="menuForm.target" name="target"> | |||||
<n-radio v-for="item in openOptions" :key="`target_${item.key}`" :value="item.key"> | |||||
{{ item.label }} | |||||
</n-radio> | |||||
</n-radio-group> | |||||
</n-form-item> | |||||
</n-gi> | |||||
<n-gi> | |||||
<n-form-item label="菜单图标" path="icon"> | |||||
<n-input v-model:value="menuForm.icon" placeholder="请选择菜单图标" /> | |||||
</n-form-item> | |||||
</n-gi> | |||||
<n-gi> | |||||
<n-form-item label="权限标识" path="permission"> | |||||
<n-input v-model:value="menuForm.permission" placeholder="请输入权限标识" /> | |||||
</n-form-item> | |||||
</n-gi> | |||||
<n-gi> | |||||
<n-form-item label="路由地址" path="path"> | |||||
<n-input v-model:value="menuForm.path" placeholder="请输入路由地址" /> | |||||
</n-form-item> | |||||
</n-gi> | |||||
<n-gi> | |||||
<n-form-item label="排序号" path="sort"> | |||||
<n-input v-model:value="menuForm.sort" placeholder="请输入排序号" /> | |||||
</n-form-item> | |||||
</n-gi> | |||||
<n-gi> | |||||
<n-form-item label="组件路径" path="component"> | |||||
<n-input v-model:value="menuForm.component" placeholder="请输入组件路径" /> | |||||
</n-form-item> | |||||
</n-gi> | |||||
<n-gi> | |||||
<n-form-item label="是否可见" path="hide"> | |||||
<n-radio-group v-model:value="menuForm.hide" name="hide"> | |||||
<n-radio v-for="item in visibleOptions" :key="`hide_${item.key}`" :value="item.key"> | |||||
{{ item.label }} | |||||
</n-radio> | |||||
</n-radio-group> | |||||
</n-form-item> | |||||
</n-gi> | |||||
<n-gi> | |||||
<n-form-item label="菜单状态" path="status"> | |||||
<n-radio-group v-model:value="menuForm.status" name="status"> | |||||
<n-radio v-for="item in statusOptions" :key="`status_${item.key}`" :value="item.key"> | |||||
{{ item.label }} | |||||
</n-radio> | |||||
</n-radio-group> | |||||
</n-form-item> | |||||
</n-gi> | |||||
</n-grid> | |||||
</n-form> | |||||
</template> | </template> | ||||
</Modal> | </Modal> | ||||
</template> | </template> | ||||
<script> | <script> | ||||
import { defineComponent, computed } from 'vue' | |||||
import Modal from '@/components/CardModal/index.vue' | |||||
import { defineComponent, computed, reactive, toRefs, ref } from 'vue' | |||||
import Modal from '@/components/Modal/index.vue' | |||||
import { addMenu } from '@/api/system/menu/index.js' | |||||
export default defineComponent({ | export default defineComponent({ | ||||
name: 'MenuModal', | name: 'MenuModal', | ||||
components: { Modal }, | components: { Modal }, | ||||
props: { | props: { | ||||
/* 可见 */ | |||||
visible: { | visible: { | ||||
type: Boolean, | type: Boolean, | ||||
default: false | default: false | ||||
}, | }, | ||||
row: { | |||||
/* 选中的数据 */ | |||||
data: { | |||||
type: Object, | type: Object, | ||||
default: () => {} | default: () => {} | ||||
}, | |||||
menuList: { | |||||
type: Array, | |||||
default: () => [] | |||||
} | } | ||||
}, | }, | ||||
emits: { | emits: { | ||||
'update:visible': null, | |||||
onClose: null, | |||||
done: null | |||||
'update:visible': null | |||||
}, | }, | ||||
setup(props, { emit }) { | setup(props, { emit }) { | ||||
const data = reactive({ | |||||
menuForm: { | |||||
pid: null, | |||||
type: '0', | |||||
title: '', | |||||
target: '0', | |||||
icon: '', | |||||
permission: '', | |||||
path: '', | |||||
sort: '', | |||||
component: '', | |||||
hide: '0', | |||||
status: '1' | |||||
}, | |||||
menuRules: { | |||||
title: { | |||||
required: true, | |||||
message: '请输入菜单名称', | |||||
trigger: ['blur'] | |||||
}, | |||||
sort: { | |||||
required: true, | |||||
message: '请输入排序号', | |||||
trigger: ['blur'] | |||||
} | |||||
}, | |||||
typeOptions: [ | |||||
{ key: '0', label: '菜单' }, | |||||
{ key: '1', label: '按钮' } | |||||
], | |||||
openOptions: [ | |||||
{ key: '0', label: '组件' }, | |||||
{ key: '1', label: '内链' }, | |||||
{ key: '2', label: '外链' } | |||||
], | |||||
visibleOptions: [ | |||||
{ key: '0', label: '可见' }, | |||||
{ key: '1', label: '不可见' } | |||||
], | |||||
statusOptions: [ | |||||
{ key: '1', label: '在用' }, | |||||
{ key: '2', label: '停用' } | |||||
] | |||||
}) | |||||
const getMenuList = computed(() => { | |||||
const list = props.menuList.map((item) => { | |||||
const menu = { | |||||
label: item.title, | |||||
value: item.pid | |||||
} | |||||
return menu | |||||
}) | |||||
return list | |||||
}) | |||||
const getModalOptions = computed(() => { | const getModalOptions = computed(() => { | ||||
return { | return { | ||||
show: props.visible | |||||
show: props.visible, | |||||
title: props.data ? '修改菜单' : '新建菜单', | |||||
width: 700, | |||||
negativeText: '取消', | |||||
positiveText: '确认' | |||||
} | } | ||||
}) | }) | ||||
const handleClose = () => { | const handleClose = () => { | ||||
emit('update:visible', false) | emit('update:visible', false) | ||||
} | } | ||||
const formRef = ref() | |||||
const handleConfirm = () => { | |||||
formRef.value?.validate((errors) => { | |||||
if (!errors) { | |||||
const params = { | |||||
...data.menuForm | |||||
} | |||||
addMenu(params) | |||||
.then(res => { | |||||
console.log(res) | |||||
handleClose() | |||||
}) | |||||
} else { | |||||
// console.log('error') | |||||
} | |||||
}) | |||||
return false | |||||
} | |||||
return { | return { | ||||
...toRefs(data), | |||||
formRef, | |||||
getMenuList, | |||||
getModalOptions, | getModalOptions, | ||||
handleClose | |||||
handleClose, | |||||
handleConfirm | |||||
} | } | ||||
} | } | ||||
}) | }) |
<template> | <template> | ||||
<div> | <div> | ||||
<n-card> | <n-card> | ||||
<data-table :columns="data.columns" :pagination="false" :data="data.data" size="large"> | |||||
<data-table :columns="data.columns" :pagination="false" :data="data.data" size="large" @fetch-success="getFechData"> | |||||
<template #tableTitle> | <template #tableTitle> | ||||
<n-button type="primary" @click="handlleRoleAdd"> | <n-button type="primary" @click="handlleRoleAdd"> | ||||
添加菜单 | 添加菜单 | ||||
</n-card> | </n-card> | ||||
</div> | </div> | ||||
<RoleModal v-model:visible="data.modalShow" /> | |||||
<RoleModal v-model:visible="data.modalShow" :data="data.selectRow" :menu-list="data.data" /> | |||||
</template> | </template> | ||||
<script> | <script> | ||||
} | } | ||||
} | } | ||||
], | ], | ||||
data: [ | |||||
], | |||||
modalShow: false | |||||
data: [], | |||||
modalShow: false, | |||||
selectRow: null | |||||
}) | }) | ||||
function play(row) { | function play(row) { | ||||
data.modalShow = true | data.modalShow = true | ||||
} | } | ||||
/** | |||||
* @description: 获取表单数据 | |||||
* @param {*} data | |||||
* @return {*} | |||||
*/ | |||||
function getFechData(data) { | |||||
} | |||||
onMounted(() => { | onMounted(() => { | ||||
fetchList() | fetchList() | ||||
}) | }) | ||||
return { data, handlleRoleAdd } | |||||
return { | |||||
data, | |||||
handlleRoleAdd, | |||||
getFechData | |||||
} | |||||
} | } | ||||
} | } | ||||
<template> | <template> | ||||
<Modal :options="getModalOptions" @on-close="handleClose" @save="submitForm"> | |||||
<Modal | |||||
:options="getModalOptions" | |||||
:on-positive-click="handleConfirm" | |||||
:on-negative-click="handleClose" | |||||
:on-close="handleClose" | |||||
> | |||||
<template #Context> | <template #Context> | ||||
<n-form | <n-form | ||||
ref="formRef" | ref="formRef" | ||||
:model="form" | :model="form" | ||||
label-placement="left" | label-placement="left" | ||||
:rules="rules" | :rules="rules" | ||||
:on-positive-click="handleConfirm" | |||||
:on-negative-click="handleClose" | |||||
> | > | ||||
<n-form-item | <n-form-item | ||||
label="头像:" | label="头像:" | ||||
<script> | <script> | ||||
import { defineComponent, computed, onMounted, reactive, toRefs } from 'vue' | import { defineComponent, computed, onMounted, reactive, toRefs } from 'vue' | ||||
import Modal from '@/components/CardModal/index.vue' | |||||
import Modal from '@/components/Modal/index.vue' | |||||
import { getDeptAll } from '@/api/system/dept/index' | import { getDeptAll } from '@/api/system/dept/index' | ||||
import { getRoleAll } from '@/api/system/role/index' | import { getRoleAll } from '@/api/system/role/index' | ||||
import { addUser, editUser } from '@/api/system/user/index' | import { addUser, editUser } from '@/api/system/user/index' | ||||
}, | }, | ||||
emits: { | emits: { | ||||
'update:visible': null, | 'update:visible': null, | ||||
onClose: null, | |||||
'done': null | 'done': null | ||||
}, | }, | ||||
setup(props, { emit }) { | setup(props, { emit }) { | ||||
return { | return { | ||||
title: Object.keys(props.row).length === 0 ? '添加用户' : '编辑用户', | title: Object.keys(props.row).length === 0 ? '添加用户' : '编辑用户', | ||||
show: props.visible, | show: props.visible, | ||||
form: Object.assign(data.form, props.row) | |||||
form: Object.assign(data.form, props.row), | |||||
negativeText: '取消', | |||||
positiveText: '确认' | |||||
} | } | ||||
}) | }) | ||||
}, | }, | ||||
methods: { | methods: { | ||||
// 表单提交 | // 表单提交 | ||||
submitForm() { | |||||
handleConfirm() { | |||||
const type = Object.keys(this.row).length === 0 ? 'add' : 'edit' | const type = Object.keys(this.row).length === 0 ? 'add' : 'edit' | ||||
// this.$refs.formRef.validate((errors) => { | |||||
// console.log(errors, '++++++++') | |||||
// }) | |||||
console.log(this.form) | |||||
if (type === 'add') { | |||||
addUser(this.form).then(res => { | |||||
if (res.data.code === 0) { | |||||
// this.$message.success(res.data.msg) | |||||
this.updateVisible(false) | |||||
this.$emit('done') | |||||
} else { | |||||
console.log(res.data.msg) | |||||
// this.$message.error(res.data.msg) | |||||
} | |||||
}).catch(e => { | |||||
console.log(e) | |||||
}) | |||||
} else if (type === 'edit') { | |||||
editUser(this.form).then(res => { | |||||
if (res.data.code === 0) { | |||||
// this.$message.success(res.data.msg) | |||||
this.updateVisible(false) | |||||
this.$emit('done') | |||||
} else { | |||||
// this.$message.error(res.data.msg) | |||||
this.$refs.formRef.validate((errors) => { | |||||
if (!errors) { | |||||
if (type === 'add') { | |||||
addUser(this.form).then(res => { | |||||
if (res.code === 0) { | |||||
this.handleClose() | |||||
this.$emit('done') | |||||
} else { | |||||
console.log(res.data.msg) | |||||
} | |||||
}).catch(e => { | |||||
console.log(e) | |||||
}) | |||||
} else if (type === 'edit') { | |||||
editUser(this.form).then(res => { | |||||
if (res.code === 0) { | |||||
this.handleClose() | |||||
this.$emit('done') | |||||
} else { | |||||
console.log(res.data.msg) | |||||
} | |||||
}) | |||||
} | } | ||||
}) | |||||
} | |||||
}, | |||||
/* 更新visible */ | |||||
updateVisible(value) { | |||||
this.$emit('update:visible', value) | |||||
} | |||||
}) | |||||
} | } | ||||
} | } | ||||
}) | }) |
> | > | ||||
<template #tableTitle> | <template #tableTitle> | ||||
<n-button type="primary" @click="handleUser"> 新建 </n-button> | <n-button type="primary" @click="handleUser"> 新建 </n-button> | ||||
<!-- <n-button type="primary" @click="deleteUsers"> 删除 </n-button> --> | |||||
<n-popconfirm | |||||
@positive-click="handlePositiveClick" | |||||
@negative-click="handleNegativeClick" | |||||
> | |||||
<n-button type="primary" @click="deleteUsers"> 删除 </n-button> | |||||
</n-popconfirm> | |||||
</template> | </template> | ||||
</data-table> | </data-table> | ||||
</n-card> | </n-card> | ||||
</div> | </div> | ||||
<!-- 新增、编辑弹窗 --> | <!-- 新增、编辑弹窗 --> | ||||
<user-modal v-if="data.modalShow" v-model:visible="data.modalShow" :row="rowData" @done="loadDataTable"/> | |||||
<user-modal v-if="data.modalShow" v-model:visible="data.modalShow" :row="rowData" @done="loadDataTable" /> | |||||
</template> | </template> | ||||
<script> | <script> | ||||
key: 'realname', | key: 'realname', | ||||
align: 'center' | align: 'center' | ||||
}, | }, | ||||
{ | |||||
title: '用户类型', | |||||
key: 'type', | |||||
align: 'center', | |||||
width: 100 | |||||
}, | |||||
{ | { | ||||
title: '角色', | title: '角色', | ||||
key: 'roles', | key: 'roles', | ||||
render(row) { | render(row) { | ||||
return h(TableTags, { | return h(TableTags, { | ||||
data: row.roles, | data: row.roles, | ||||
rowKey: 'name', | |||||
filters: [ | |||||
{ | |||||
key: '超级管理员', | |||||
label: '123', | |||||
color: { | |||||
textColor: 'red' | |||||
} | |||||
} | |||||
] | |||||
rowKey: 'name' | |||||
// filters: [ | |||||
// { | |||||
// key: '管理员', | |||||
// label: '123', | |||||
// color: { | |||||
// textColor: 'red' | |||||
// } | |||||
// } | |||||
// ] | |||||
}) | }) | ||||
} | } | ||||
}, | }, |