@@ -0,0 +1,59 @@ | |||
import { defAxios as request } from '@/utils/http' | |||
/** | |||
* @description: 获取音视频上传地址和凭证 | |||
* @param {Object} params | |||
* @return {Object} | |||
*/ | |||
export function getAuth(params) { | |||
return request({ | |||
url: '/aliyuncsVod/createUploadVideo', | |||
method: 'get', | |||
params | |||
}) | |||
} | |||
/** | |||
* @description: 刷新音/视频上传凭证 | |||
* @param {String} videoId | |||
* @return {*} | |||
*/ | |||
export function refreshAuth(videoId) { | |||
return request({ | |||
url: '/aliyuncsVod/refreshUploadVideo', | |||
method: 'get', | |||
params: { | |||
videoId | |||
} | |||
}) | |||
} | |||
/** | |||
* @description: 获取图片上传鉴权 | |||
* @param {String} objectName | |||
* @return {*} | |||
*/ | |||
export function getOssAuth(objectName) { | |||
return request({ | |||
url: '/aliyunOss/getSecurityToken', | |||
method: 'get', | |||
responseAll: true, | |||
params: { | |||
objectName | |||
} | |||
}) | |||
} | |||
/** | |||
* @description: 上传离线视频地址 | |||
* @param {String} params | |||
* @return {*} | |||
*/ | |||
export function uploadVideoUrl(data) { | |||
return request({ | |||
url: '/inspection/uploadVideoUrl', | |||
method: 'post', | |||
data | |||
}) | |||
} | |||
@@ -77,7 +77,7 @@ export function deleteRole(data) { | |||
*/ | |||
export function getRolePermission(id) { | |||
return request({ | |||
url: `/role/getPermissionList/${id}`, | |||
url: `/role/getMenuList/${id}`, | |||
method: 'GET' | |||
}) | |||
} |
@@ -45,7 +45,7 @@ export function useDataSource(propsRef, { getPaginationInfo, setPagination, setL | |||
} | |||
// 处理数据结构 | |||
const resultInfo = res[listField] ? res[listField] : res | |||
dataSourceRef.value = dataType === 'tree' ? dealTree(resultInfo) : resultInfo | |||
dataSourceRef.value = dataType === 'tree' ? dealTree(resultInfo.data) : resultInfo | |||
setPagination({ | |||
[pageField]: currentPage, | |||
[totalField]: Math.ceil(resultTotal / pageSize) |
@@ -34,7 +34,7 @@ export default defineComponent({ | |||
return { | |||
...props.options, | |||
width: props.options.width || 600, | |||
preset: props.options.preset || 'card', | |||
preset: props.options.preset || 'dialog', | |||
showIcon: !!props.options.showIcon | |||
} | |||
}) | |||
@@ -66,7 +66,6 @@ export default defineComponent({ | |||
// styL = +sty.left.replace(/\px/g, '') | |||
// styT = +sty.top.replace(/\px/g, '') | |||
// } | |||
// document.onmousemove = function(e) { | |||
// // 计算移动的距离 | |||
// const l = e.clientX - disX |
@@ -24,13 +24,40 @@ export default [ | |||
{ | |||
path: '/system', | |||
component: Layout, | |||
redirect: '/system/menu', | |||
redirect: '/system/user', | |||
name: 'System', | |||
title: '系统管理', | |||
meta: { | |||
title: '系统管理' | |||
}, | |||
children: [ | |||
{ | |||
path: 'user', | |||
component: () => import('@/views/system/user/index.vue'), | |||
name: 'SystemUser', | |||
title: '用户管理', | |||
meta: { | |||
title: '用户管理' | |||
} | |||
}, | |||
{ | |||
path: 'role', | |||
component: () => import('@/views/system/role/index.vue'), | |||
name: 'SystemRole', | |||
title: '角色管理', | |||
meta: { | |||
title: '角色管理' | |||
} | |||
}, | |||
{ | |||
path: 'dept', | |||
component: () => import('@/views/system/dept/index.vue'), | |||
name: 'SystemDept', | |||
title: '部门管理', | |||
meta: { | |||
title: '部门管理' | |||
} | |||
}, | |||
{ | |||
path: 'menu', | |||
component: () => import('@/views/system/menu/index.vue'), |
@@ -13,3 +13,15 @@ export const TASK_TYPE = [ | |||
{ label: '日常巡检', value: 0 }, | |||
{ label: '应急巡检', value: 1 } | |||
] | |||
export const QUESTION_TYPE = [ | |||
{ label: '林场问题图斑', value: 1 }, | |||
{ label: '病虫树', value: 2 }, | |||
{ label: '人员活动', value: 3 }, | |||
{ label: '火灾隐患', value: 4 } | |||
] | |||
export const USER_STATUS = [ | |||
{ label: '正常', value: 1 }, | |||
{ label: '禁用', value: 2 } | |||
] |
@@ -0,0 +1,17 @@ | |||
<template> | |||
<div> | |||
问题分布 | |||
</div> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'QuestionDistribution', | |||
setup() { | |||
} | |||
} | |||
</script> | |||
<style scoped lang='scss'> | |||
</style> |
@@ -0,0 +1,17 @@ | |||
<template> | |||
<div> | |||
问题列表 | |||
</div> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'QuestionList', | |||
setup() { | |||
} | |||
} | |||
</script> | |||
<style scoped lang='scss'> | |||
</style> |
@@ -0,0 +1,17 @@ | |||
<template> | |||
<div> | |||
全部报告 | |||
</div> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'AllReport', | |||
setup() { | |||
} | |||
} | |||
</script> | |||
<style scoped lang='scss'> | |||
</style> |
@@ -33,14 +33,14 @@ export default defineComponent({ | |||
type: Boolean, | |||
default: false | |||
}, | |||
row: { | |||
data: { | |||
type: Object, | |||
default: () => {} | |||
} | |||
}, | |||
emits: { | |||
'update:visible': null, | |||
'done': null | |||
'reload': null | |||
}, | |||
setup(props, { emit }) { | |||
const data = reactive({ | |||
@@ -62,7 +62,7 @@ export default defineComponent({ | |||
// 获取当前角色的权限菜单列表 | |||
async function getMenuByRoleId() { | |||
const res = await getRolePermission(props.row.id) | |||
const res = await getRolePermission(props.data.id) | |||
data.allTreeData = toTreeData(res.data, 'id', 'pid', 'children') | |||
const checkedArr = res.data | |||
if (checkedArr.length) { | |||
@@ -80,6 +80,17 @@ export default defineComponent({ | |||
data.menuIds = keys | |||
} | |||
function handleConfirm() { | |||
savePermission({ roleId: this.row.id, menuIds: this.menuIds }).then(res => { | |||
if (res.code === 0) { | |||
this.handleClose() | |||
this.$emit('reload') | |||
} | |||
}).catch(e => { | |||
console.log(e) | |||
}) | |||
} | |||
/* 关闭弹窗 */ | |||
const handleClose = () => { | |||
emit('update:visible', false) | |||
@@ -88,25 +99,9 @@ export default defineComponent({ | |||
return { | |||
...toRefs(data), | |||
getModalOptions, | |||
handleClose, | |||
handleCheckTree | |||
} | |||
}, | |||
methods: { | |||
// 提交 | |||
handleConfirm() { | |||
console.log(this.menuIds, this.checkedTreeData) | |||
savePermission({ roleId: this.row.id, menuIds: this.menuIds }).then(res => { | |||
if (res.code === 0) { | |||
this.handleClose() | |||
this.$emit('done') | |||
$message.success(res.msg) | |||
} else { | |||
$message.error(res.msg) | |||
} | |||
}).catch(e => { | |||
console.log(e) | |||
}) | |||
handleCheckTree, | |||
handleConfirm, | |||
handleClose | |||
} | |||
} | |||
}) |
@@ -0,0 +1,135 @@ | |||
<template> | |||
<Modal | |||
:options="getModalOptions" | |||
:on-positive-click="handleConfirm" | |||
:on-negative-click="handleClose" | |||
:on-close="handleClose" | |||
> | |||
<template #Context> | |||
<n-form | |||
ref="formRef" | |||
:model="roleForm" | |||
:rules="roleRules" | |||
:label-width="80" | |||
label-placement="left" | |||
require-mark-placement="left" | |||
:disabled="disabled" | |||
> | |||
<template v-for="(item,index) in getFormOptions" :key="index"> | |||
<n-form-item :label="item.label" :path="item.key"> | |||
<n-input v-if="item.type === 'input'" v-model:value="roleForm[item.key]" v-bind="item.props" /> | |||
<n-radio-group v-if="item.type === 'radio'" v-model:value="roleForm[item.key]" :name="item.key"> | |||
<n-space> | |||
<n-radio v-for="(cItem,cIndex) in item.options" :key="`${item.key}_${cIndex}`" :value="cItem.value"> {{ cItem.label }}</n-radio> | |||
</n-space> | |||
</n-radio-group> | |||
</n-form-item> | |||
</template> | |||
</n-form> | |||
</template> | |||
</Modal> | |||
</template> | |||
<script> | |||
import form from '../tools/form.js' | |||
import { defineComponent, ref, reactive, computed, toRefs } from 'vue' | |||
import Modal from '@/components/Modal/index.vue' | |||
import { addRole, editRole } from '@/api/system/role/index' | |||
export default defineComponent({ | |||
name: 'RoleModal', | |||
components: { Modal }, | |||
props: { | |||
visible: { | |||
type: Boolean, | |||
default: false | |||
}, | |||
data: { | |||
type: Object, | |||
default: () => {} | |||
} | |||
}, | |||
emits: { | |||
'update:visible': null, | |||
'reload': null | |||
}, | |||
setup(props, { emit }) { | |||
const MODAL_TYPE = { | |||
'create': '新建角色', | |||
'preview': '角色详情', | |||
'update': '编辑角色' | |||
} | |||
const { roleForm, roleRules } = form | |||
const formRef = ref() | |||
const data = reactive({ | |||
roleForm: { | |||
...roleForm, | |||
...props.data | |||
}, | |||
roleRules: { | |||
...roleRules | |||
}, | |||
disabled: props.type === 'preview' | |||
}) | |||
const getModalOptions = computed(() => { | |||
return { | |||
title: MODAL_TYPE[props.type], | |||
show: props.visible, | |||
negativeText: '取消', | |||
positiveText: '确认' | |||
} | |||
}) | |||
const getFormOptions = computed(() => { | |||
return { | |||
...form.formItem | |||
} | |||
}) | |||
function handleConfirm() { | |||
formRef.value?.validate((errors) => { | |||
if (!errors) { | |||
const params = { ...data.roleForm } | |||
if (params.id) { | |||
/* 编辑 */ | |||
editRole(params) | |||
.then(res => { | |||
if (res.code === 0) { | |||
emit('reload') | |||
handleClose() | |||
} | |||
}) | |||
} else { | |||
/* 新增 */ | |||
addRole(params) | |||
.then(res => { | |||
if (res.code === 0) { | |||
emit('reload') | |||
handleClose() | |||
} | |||
}) | |||
} | |||
} else { | |||
$message.error('请完善必填信息') | |||
} | |||
}) | |||
} | |||
/* 关闭弹窗 */ | |||
const handleClose = () => { | |||
emit('update:visible', false) | |||
} | |||
return { | |||
...toRefs(data), | |||
formRef, | |||
getModalOptions, | |||
getFormOptions, | |||
handleConfirm, | |||
handleClose | |||
} | |||
} | |||
}) | |||
</script> | |||
<style scoped lang='scss'> | |||
</style> |
@@ -0,0 +1,104 @@ | |||
<template> | |||
<div> | |||
<n-card> | |||
<headSearch :info="search" @search="handleSearch" /> | |||
<data-table | |||
ref="tableRef" | |||
:columns="columns" | |||
:row-key="(row) => row.id" | |||
:request="loadDataTable" | |||
size="large" | |||
scroll-x="1200" | |||
@update:checked-row-keys="handleCheck" | |||
> | |||
<template #tableTitle> | |||
<n-button type="primary" @click="handleModal"> 新建 </n-button> | |||
<n-popconfirm | |||
negative-text="取消" | |||
positive-text="确认" | |||
@positive-click="deleteComplex" | |||
> | |||
<template #trigger> | |||
<n-button type="primary">删除</n-button> | |||
</template> | |||
确定删除选中的数据吗? | |||
</n-popconfirm> | |||
</template> | |||
</data-table> | |||
</n-card> | |||
</div> | |||
<!-- 新增、编辑弹窗 --> | |||
<RoleModal v-if="modalShow" v-model:visible="modalShow" :data="rowData" @reload="handleSearch" /> | |||
<!-- 分配权限 --> | |||
<ConfigModal v-if="configModalShow" v-model:visible="configModalShow" :data="rowData" @reload="handleSearch" /> | |||
</template> | |||
<script> | |||
import search from './tools/search.js' | |||
import table from './tools/table.js' | |||
import headSearch from '@/components/Search/index.vue' | |||
import dataTable from '@/components/DataTable/index.vue' | |||
import { getRoleList } from '@/api/system/role/index' | |||
import { ref, unref, toRefs, reactive } from 'vue' | |||
import RoleModal from './components/RoleModal.vue' | |||
import ConfigModal from './components/ConfigModal.vue' | |||
export default { | |||
name: 'MenuPage', | |||
components: { headSearch, dataTable, RoleModal, ConfigModal }, | |||
setup() { | |||
const data = reactive({ | |||
...toRefs(table), | |||
search | |||
}) | |||
const params = ref({}) | |||
const tableRef = ref() | |||
const loadDataTable = async(res) => { | |||
const _params = { | |||
...unref(params), | |||
...res | |||
} | |||
return await getRoleList(_params) | |||
} | |||
// 新增用户 | |||
function handleModal() { | |||
data.rowData = null | |||
data.modalType = 'create' | |||
data.modalShow = true | |||
} | |||
// 选择表格数据 | |||
const selectedIds = ref([]) | |||
function handleCheck(rowKeys) { | |||
selectedIds.value = rowKeys | |||
} | |||
// 批量删除 | |||
function deleteComplex() { | |||
if (selectedIds.value.length) { | |||
data.deleteData(selectedIds.value) | |||
} else { | |||
$message.warning('请至少选中一条数据') | |||
} | |||
} | |||
return { | |||
...toRefs(data), | |||
tableRef, | |||
loadDataTable, | |||
handleModal, | |||
handleCheck, | |||
selectedIds, | |||
deleteComplex | |||
} | |||
} | |||
} | |||
</script> | |||
<style scoped lang='scss'> | |||
.n-button + .n-button { | |||
margin-left: 10px; | |||
} | |||
</style> |
@@ -0,0 +1,24 @@ | |||
import { reactive } from 'vue' | |||
import { USER_STATUS } from '@/utils/dictionary.js' | |||
const data = reactive({ | |||
roleForm: { | |||
code: '', | |||
name: '', | |||
status: 1, | |||
note: '' | |||
}, | |||
roleRules: { | |||
code: [{ required: true, message: '请输入角色编号', trigger: 'blur' }], | |||
name: [{ required: true, message: '请输入角色名称', type: 'string', trigger: 'blur' }], | |||
status: [{ required: true, message: '请选择状态', type: 'number', trigger: 'blur' }] | |||
}, | |||
formItem: [ | |||
{ type: 'input', key: 'code', label: '角色编号', props: { maxlength: '20', placeholder: '请输入角色编号', clearable: true }}, | |||
{ type: 'input', key: 'name', label: '角色名称', props: { maxlength: '20', placeholder: '请输入角色名称', clearable: true }}, | |||
{ type: 'radio', key: 'status', label: '状态', options: USER_STATUS }, | |||
{ type: 'input', key: 'note', label: '备注', props: { type: 'textarea', autosize: { maxlength: '200', minRows: 3, maxRows: 3 }}} | |||
] | |||
}) | |||
export default data |
@@ -1,4 +1,6 @@ | |||
const data = [ | |||
import { reactive } from 'vue' | |||
const data = reactive([ | |||
{ | |||
label: '角色名称', | |||
key: 'name', | |||
@@ -6,6 +8,6 @@ const data = [ | |||
placeholder: '请输入角色名称' | |||
} | |||
} | |||
] | |||
]) | |||
export default data |
@@ -0,0 +1,165 @@ | |||
import { h, ref, reactive } from 'vue' | |||
import TableSwitch from '@/components/DataTable/tools/Switch.vue' | |||
import TableAction from '@/components/DataTable/tools/Action.vue' | |||
import { getRoleList, deleteRole, setRoleStatus } from '@/api/system/role/index' | |||
/* 注册table */ | |||
const tableRef = ref() | |||
const searchParams = ref() | |||
function handleSearch(params) { | |||
searchParams.value = { ...params } | |||
tableRef.value.reFetch({ searchParams }) | |||
} | |||
/** | |||
* @description: 获取数据及操作 | |||
* @param {*} row 单行数据 | |||
* @param {*} type 操作类型 create:创建,preview:预览,edit:编辑 | |||
* @return {*} | |||
*/ | |||
function getRowData(row, type) { | |||
data.rowData = row | |||
data.modalType = type | |||
data.modalShow = true | |||
} | |||
/** | |||
* @description: 打开分配权限窗口 | |||
* @param {*} row 单行数据 | |||
* @return {*} | |||
*/ | |||
function configure(row) { | |||
data.rowData = row | |||
data.configModalShow = true | |||
} | |||
/** | |||
* @description: 改变状态 | |||
* @param {*} row 选中数据 | |||
* @return {*} | |||
*/ | |||
function handleStatusChange(row) { | |||
setRoleStatus({ id: row.data.id, status: row.value }) | |||
.then((res) => { | |||
if (res.code === 0) { | |||
handleSearch() | |||
} | |||
}) | |||
.catch((e) => { | |||
console.log(e) | |||
}) | |||
} | |||
// 删除接口 | |||
function deleteData(data) { | |||
deleteRole(data) | |||
.then((res) => { | |||
if (res.code === 0) { | |||
handleSearch() | |||
} | |||
}) | |||
.catch((e) => { | |||
console.log(e) | |||
}) | |||
} | |||
const data = reactive({ | |||
tableRef, | |||
searchParams, | |||
rowData: {}, | |||
modalType: 'create', | |||
modalShow: false, | |||
configModalShow: false, | |||
handleSearch, | |||
deleteData, | |||
columns: [ | |||
{ type: 'selection' }, | |||
{ | |||
title: '角色编号', | |||
key: 'code', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '角色名称', | |||
key: 'name', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '创建时间', | |||
key: 'createTime', | |||
align: 'center', | |||
Minwidth: 160 | |||
}, | |||
{ | |||
title: '更新时间', | |||
key: 'updateTime', | |||
align: 'center', | |||
Minwidth: 160 | |||
}, | |||
{ | |||
title: '状态', | |||
key: 'status', | |||
align: 'center', | |||
width: 100, | |||
render(row) { | |||
return h(TableSwitch, { | |||
data: { id: row.id, status: row.status }, | |||
rowKey: 'status', | |||
checkedValue: 1, | |||
uncheckedValue: 2, | |||
onChange: handleStatusChange.bind(null, row) | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '操作', | |||
align: 'center', | |||
width: 150, | |||
fixed: 'right', | |||
render(row) { | |||
return h(TableAction, { | |||
actions: [ | |||
{ | |||
label: '修改', | |||
type: 'button', | |||
props: { | |||
type: 'primary', | |||
text: true, | |||
onClick: getRowData.bind(null, row, 'update') | |||
}, | |||
auth: 'basic_list' | |||
}, | |||
{ | |||
label: '分配权限', | |||
type: 'button', | |||
props: { | |||
type: 'primary', | |||
ghost: true, | |||
text: true, | |||
onClick: configure.bind(null, row) | |||
}, | |||
auth: 'basic_list' | |||
}, | |||
{ | |||
label: '删除', | |||
type: 'popconfirm', | |||
auth: 'basic_list', | |||
tip: '确定删除这条数据吗?', | |||
props: { | |||
onPositiveClick: deleteData.bind(null, [row.id]) | |||
}, | |||
ButtonProps: { | |||
text: true, | |||
type: 'primary' | |||
} | |||
} | |||
], | |||
align: 'center' | |||
}) | |||
} | |||
} | |||
] | |||
}) | |||
export default data |
@@ -0,0 +1,168 @@ | |||
<template> | |||
<Modal | |||
:options="getModalOptions" | |||
:on-positive-click="handleConfirm" | |||
:on-negative-click="handleClose" | |||
:on-close="handleClose" | |||
> | |||
<template #Context> | |||
<n-form | |||
ref="formRef" | |||
:model="userForm" | |||
:rules="userRules" | |||
:label-width="80" | |||
label-placement="left" | |||
require-mark-placement="left" | |||
:disabled="disabled" | |||
> | |||
<template v-for="(item,index) in getFormOptions" :key="index"> | |||
<n-form-item :label="item.label" :path="item.key"> | |||
<UploadOss v-if="item.type === 'oss'" :ref="el=>{ossRefs[item.refIndex] = el}" :default-list="userForm[item.file]" @upload-status="handleUploadStatus" /> | |||
<n-input v-if="item.type === 'input'" v-model:value="userForm[item.key]" v-bind="item.props" /> | |||
<n-select v-if="item.type === 'select'" v-model:value="userForm[item.key]" v-bind="item.props" /> | |||
<n-radio-group v-if="item.type === 'radio'" v-model:value="userForm[item.key]" :name="item.key"> | |||
<n-space> | |||
<n-radio v-for="(cItem,cIndex) in item.options" :key="`${item.key}_${cIndex}`" :value="cItem.value"> {{ cItem.label }}</n-radio> | |||
</n-space> | |||
</n-radio-group> | |||
</n-form-item> | |||
</template> | |||
</n-form> | |||
</template> | |||
</Modal> | |||
</template> | |||
<script> | |||
import { form, getDeptOptions, getRoleOptions } from '../tools/form.js' | |||
import { defineComponent, ref, reactive, computed, toRefs } from 'vue' | |||
import Modal from '@/components/Modal/index.vue' | |||
import UploadOss from '@/components/UploadOss/index.vue' | |||
import { addUser, editUser } from '@/api/system/user/index' | |||
export default defineComponent({ | |||
name: 'UserModal', | |||
components: { Modal, UploadOss }, | |||
props: { | |||
visible: { | |||
type: Boolean, | |||
default: false | |||
}, | |||
type: { | |||
type: String, | |||
default: 'create' | |||
}, | |||
data: { | |||
type: Object, | |||
default: () => null | |||
} | |||
}, | |||
emits: { | |||
'update:visible': null, | |||
'reload': null | |||
}, | |||
setup(props, { emit }) { | |||
const MODAL_TYPE = { | |||
'create': '新建用户', | |||
'preview': '用户详情', | |||
'update': '编辑用户' | |||
} | |||
getDeptOptions() | |||
getRoleOptions() | |||
const { userForm, userRules } = form | |||
const formRef = ref() | |||
const ossRefs = ref([]) | |||
const data = reactive({ | |||
userForm: { | |||
...userForm, | |||
...props.data, | |||
roleIds: props?.data?.roles.map((item) => { return item.id }) || [] | |||
}, | |||
userRules: { | |||
...userRules | |||
}, | |||
disabled: props.type === 'preview' | |||
}) | |||
const getModalOptions = computed(() => { | |||
return { | |||
show: props.visible, | |||
title: MODAL_TYPE[props.type], | |||
negativeText: '取消', | |||
positiveText: '确认' | |||
} | |||
}) | |||
const getFormOptions = computed(() => { | |||
return { | |||
...form.formItem | |||
} | |||
}) | |||
function handleUploadStatus(status) { | |||
data.userForm.imageStatus = status | |||
} | |||
function handleConfirm() { | |||
formRef.value?.validate((errors) => { | |||
if (!errors) { | |||
const uploads = ossRefs.value.map((item, index) => { | |||
return item.startUpload() | |||
}) | |||
Promise.all(uploads) | |||
.then(response => { | |||
const isError = response.map((item) => { | |||
return item.includes('error') | |||
}) | |||
if (!isError.includes(true)) { | |||
const imageStr = response.join() | |||
const params = { | |||
...data.userForm, | |||
// avatar: imageStr | |||
avatar: '/imagedir/2uim2hpl94u_1655380018696.png' | |||
} | |||
if (params.id) { | |||
/* 编辑 */ | |||
editUser(params) | |||
.then(res => { | |||
if (res.code === 0) { | |||
emit('reload') | |||
handleClose() | |||
} | |||
}) | |||
} else { | |||
/* 新增 */ | |||
addUser(params) | |||
.then(res => { | |||
if (res.code === 0) { | |||
emit('reload') | |||
handleClose() | |||
} | |||
}) | |||
} | |||
} else { | |||
$message.error('文件上传失败,请稍后重试') | |||
} | |||
}) | |||
} else { | |||
$message.error('请完善必填信息') | |||
} | |||
}) | |||
} | |||
/* 关闭弹窗 */ | |||
const handleClose = () => { | |||
emit('update:visible', false) | |||
} | |||
return { | |||
...toRefs(data), | |||
formRef, | |||
ossRefs, | |||
getModalOptions, | |||
getFormOptions, | |||
handleUploadStatus, | |||
handleConfirm, | |||
handleClose | |||
} | |||
} | |||
}) | |||
</script> | |||
<style scoped lang='scss'> | |||
</style> |
@@ -0,0 +1,101 @@ | |||
<template> | |||
<div> | |||
<n-card> | |||
<headSearch :info="search" @search="handleSearch" @reset="handleSearch" /> | |||
<data-table | |||
ref="tableRef" | |||
:columns="columns" | |||
:row-key="(row) => row.id" | |||
:request="loadDataTable" | |||
size="large" | |||
@update:checked-row-keys="handleCheck" | |||
> | |||
<template #tableTitle> | |||
<n-button type="primary" @click="handleModal"> 新建 </n-button> | |||
<n-popconfirm | |||
negative-text="取消" | |||
positive-text="确认" | |||
@positive-click="deleteComplex" | |||
> | |||
<template #trigger> | |||
<n-button type="primary"> 删除 </n-button> | |||
</template> | |||
确认要删除选中数据吗? | |||
</n-popconfirm> | |||
</template> | |||
</data-table> | |||
</n-card> | |||
</div> | |||
<!-- 新增、编辑弹窗 --> | |||
<UserModal v-if="modalShow" v-model:visible="modalShow" :type="modalType" :data="rowData" @reload="handleSearch" /> | |||
</template> | |||
<script> | |||
import { search, fetchRolesOption } from './tools/search.js' | |||
import table from './tools/table.js' | |||
import headSearch from '@/components/Search/index.vue' | |||
import dataTable from '@/components/DataTable/index.vue' | |||
import { getUserList } from '@/api/system/user/index.js' | |||
import { unref, ref, toRefs, reactive } from 'vue' | |||
import UserModal from './components/UserModal.vue' | |||
export default { | |||
name: 'MenuPage', | |||
components: { dataTable, UserModal, headSearch }, | |||
setup() { | |||
fetchRolesOption() | |||
const data = reactive({ | |||
...toRefs(table), | |||
...toRefs(search) | |||
}) | |||
const loadDataTable = async(res) => { | |||
const _params = { | |||
...unref(data.searchParams), | |||
...res | |||
} | |||
return await getUserList(_params) | |||
} | |||
// 新增 | |||
function handleModal() { | |||
data.rowData = null | |||
data.modalType = 'create' | |||
data.modalShow = true | |||
} | |||
// 选择表格数据 | |||
const selectedIds = ref([]) | |||
function handleCheck(rowKeys) { | |||
selectedIds.value = rowKeys | |||
} | |||
// 批量删除 | |||
function deleteComplex() { | |||
if (selectedIds.value.length) { | |||
data.deleteData(selectedIds.value) | |||
} else { | |||
$message.warning('请至少选中一条数据') | |||
} | |||
} | |||
return { | |||
...toRefs(data), | |||
loadDataTable, | |||
handleModal, | |||
selectedIds, | |||
deleteComplex, | |||
handleCheck | |||
} | |||
}, | |||
methods: { | |||
} | |||
} | |||
</script> | |||
<style scoped lang='scss'> | |||
.n-button + .n-button { | |||
margin-left: 10px; | |||
} | |||
</style> |
@@ -0,0 +1,52 @@ | |||
import { ref, reactive } from 'vue' | |||
import { USER_STATUS } from '@/utils/dictionary.js' | |||
import { getDeptAll } from '@/api/system/dept/index' | |||
import { getRoleAll } from '@/api/system/role/index' | |||
import { dataToSelect } from '@/utils/handleData.js' | |||
const departmentOptions = ref() | |||
const rolesOptions = ref() | |||
export const form = reactive({ | |||
userForm: { | |||
avatar: '', | |||
code: '', | |||
deptId: null, | |||
username: '', | |||
realname: '', | |||
password: '', | |||
roleIds: [], | |||
status: 1, | |||
note: '' | |||
}, | |||
userRules: { | |||
imageStatus: [{ required: true, message: '请选择头像', type: 'string', trigger: 'blur' }], | |||
code: [{ required: true, message: '请输入编号', trigger: 'blur' }], | |||
realname: [{ required: true, message: '请输入用户姓名', type: 'string', trigger: 'blur' }], | |||
deptId: [{ required: true, message: '请选择部门', type: 'number', trigger: 'blur' }], | |||
status: [{ required: true, message: '请选择状态', type: 'number', trigger: 'blur' }], | |||
roleIds: [{ required: true, message: '请选择角色', type: 'array', trigger: 'blur' }], | |||
username: [{ required: true, message: '请输入用户账号', type: 'string', trigger: 'blur' }] | |||
}, | |||
formItem: [ | |||
// { type: 'oss', key: 'imageStatus', label: '头像', file: 'avatar', refIndex: 0 }, | |||
{ type: 'oss', key: 'imageStatus', label: '头像', file: 'avatar' }, | |||
{ type: 'input', key: 'code', label: '用户编号', props: { maxlength: '20', placeholder: '请输入用户编号', clearable: true }}, | |||
{ type: 'input', key: 'username', label: '用户账号', props: { maxlength: '20', placeholder: '请输入用户账号', clearable: true }}, | |||
{ type: 'input', key: 'password', label: '登录密码', props: { type: 'password', maxlength: '20', placeholder: '请输入登录密码', clearable: true }}, | |||
{ type: 'input', key: 'realname', label: '用户姓名', props: { maxlength: '20', placeholder: '请输入用户姓名', clearable: true }}, | |||
{ type: 'select', key: 'deptId', label: '所属部门', props: { options: departmentOptions, placeholder: '请选择所属部门' }}, | |||
{ type: 'select', key: 'roleIds', label: '角色', props: { multiple: true, options: rolesOptions, placeholder: '请选择角色' }}, | |||
{ type: 'radio', key: 'status', label: '状态', options: USER_STATUS }, | |||
{ type: 'input', key: 'note', label: '备注', props: { type: 'textarea', autosize: { maxlength: '200', minRows: 3, maxRows: 3 }}} | |||
] | |||
}) | |||
export const getDeptOptions = async function() { | |||
const res = await getDeptAll() | |||
departmentOptions.value = dataToSelect(res.data, { label: 'name', value: 'id' }) | |||
} | |||
// 获取角色列表 | |||
export const getRoleOptions = async function() { | |||
const res = await getRoleAll() | |||
rolesOptions.value = dataToSelect(res.data, { label: 'name', value: 'id' }) | |||
} |
@@ -0,0 +1,36 @@ | |||
import { getRoleAll } from '@/api/system/role/index' | |||
import { ref, reactive } from 'vue' | |||
const rolesOptions = ref([]) | |||
export const search = reactive({ | |||
search: [ | |||
{ | |||
label: '用户账号', | |||
key: 'username', | |||
props: { | |||
placeholder: '请输入用户账号' | |||
} | |||
}, | |||
{ | |||
label: '用户姓名', | |||
key: 'realname', | |||
props: { | |||
placeholder: '请输入用户姓名' | |||
} | |||
}, | |||
{ | |||
label: '用户角色', | |||
type: 'select', | |||
key: 'roleId', | |||
props: { | |||
placeholder: '请选择用户角色', | |||
options: rolesOptions | |||
} | |||
} | |||
] | |||
}) | |||
export const fetchRolesOption = async function() { | |||
const res = await getRoleAll() | |||
rolesOptions.value = res.data.map((item) => { return { key: item.id, label: item.name } }) | |||
} |
@@ -0,0 +1,210 @@ | |||
import { h, ref, reactive } from 'vue' | |||
import TableImage from '@/components/DataTable/tools/Image.vue' | |||
import TableTags from '@/components/DataTable/tools/Tags.vue' | |||
import TableSwitch from '@/components/DataTable/tools/Switch.vue' | |||
import TableAction from '@/components/DataTable/tools/Action.vue' | |||
import { resetPassword, deleteUser, setUserStatus } from '@/api/system/user/index.js' | |||
/* 注册table */ | |||
const tableRef = ref() | |||
const searchParams = ref() | |||
function handleSearch(params) { | |||
searchParams.value = { ...params } | |||
tableRef.value.reFetch({ searchParams }) | |||
} | |||
/** | |||
* @description: 获取数据及操作 | |||
* @param {*} row 单行数据 | |||
* @param {*} type 操作类型 create:创建,preview:预览,edit:编辑 | |||
* @return {*} | |||
*/ | |||
function getRowData(row, type) { | |||
data.rowData = row | |||
data.modalType = type | |||
data.modalShow = true | |||
} | |||
// 设置状态 | |||
function setStatus(row) { | |||
setUserStatus({ id: row.data.id, status: row.value }).then(res => { | |||
if (res.code === 0) { | |||
handleSearch() | |||
$message.success(res.msg) | |||
} else { | |||
$message.error(res.msg) | |||
} | |||
}).catch(e => { | |||
console.log(e) | |||
}) | |||
} | |||
/** | |||
* @description: 重置密码 | |||
* @param {Number} id 选中数据id | |||
* @return {*} | |||
*/ | |||
function handlePasswordReset(id) { | |||
resetPassword({ id }) | |||
.then(res => { | |||
if (res.code === 0) { | |||
handleSearch() | |||
} | |||
}).catch(e => { | |||
console.log(e) | |||
}) | |||
} | |||
/** | |||
* @description: 删除用户接口 | |||
* @param {Array} ids 用户id集合 | |||
* @return {*} | |||
*/ | |||
function deleteData(ids) { | |||
deleteUser(ids).then((res) => { | |||
if (res.code === 0) { | |||
handleSearch() | |||
} | |||
}).catch(e => { | |||
console.log(e) | |||
}) | |||
} | |||
const data = reactive({ | |||
tableRef, | |||
searchParams, | |||
rowData: {}, | |||
modalType: 'create', | |||
modalShow: false, | |||
handleSearch, | |||
deleteData, | |||
columns: [ | |||
{ | |||
type: 'selection' | |||
}, | |||
{ | |||
title: '用户编号', | |||
key: 'code', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '头像', | |||
key: 'avatar', | |||
align: 'center', | |||
render(row) { | |||
return h(TableImage, { | |||
images: { | |||
width: 36, | |||
height: 36, | |||
src: row.avatar | |||
} | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '用户账号', | |||
key: 'username', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '用户姓名', | |||
key: 'realname', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '角色', | |||
key: 'roleList', | |||
align: 'center', | |||
render(row) { | |||
return h(TableTags, { | |||
data: row.roles, | |||
rowKey: 'name' | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '部门', | |||
key: 'deptName', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '创建时间', | |||
key: 'createTime', | |||
align: 'center', | |||
width: 160 | |||
}, | |||
{ | |||
title: '更新时间', | |||
key: 'updateTime', | |||
align: 'center', | |||
width: 160 | |||
}, | |||
{ | |||
title: '状态', | |||
key: 'status', | |||
align: 'center', | |||
width: 100, | |||
render(row) { | |||
return h(TableSwitch, { | |||
data: { id: row.id, status: row.status }, | |||
rowKey: 'status', | |||
checkedValue: 1, | |||
uncheckedValue: 2, | |||
onChange: setStatus.bind(row) | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '操作', | |||
align: 'center', | |||
width: 150, | |||
fixed: 'right', | |||
render(row) { | |||
return h(TableAction, { | |||
actions: [ | |||
{ | |||
label: '修改', | |||
type: 'button', | |||
props: { | |||
type: 'primary', | |||
text: true, | |||
onClick: getRowData.bind(null, row, 'update') | |||
}, | |||
auth: 'basic_list' | |||
}, | |||
{ | |||
label: '重置密码', | |||
type: 'popconfirm', | |||
tip: '确定要重置为123456吗?', | |||
props: { | |||
onPositiveClick: handlePasswordReset.bind(null, row.id) | |||
}, | |||
ButtonProps: { | |||
text: true, | |||
type: 'primary' | |||
}, | |||
auth: 'basic_list' | |||
}, | |||
{ | |||
label: '删除', | |||
type: 'popconfirm', | |||
auth: 'basic_list', | |||
tip: '确定删除这条数据吗?', | |||
props: { | |||
onPositiveClick: deleteData.bind(null, [row.id]) | |||
}, | |||
ButtonProps: { | |||
text: true, | |||
type: 'primary' | |||
} | |||
} | |||
], | |||
align: 'center' | |||
}) | |||
} | |||
} | |||
] | |||
}) | |||
export default data |
@@ -1,166 +0,0 @@ | |||
<template> | |||
<Modal | |||
:options="getModalOptions" | |||
:on-positive-click="handleConfirm" | |||
:on-negative-click="handleClose" | |||
:on-close="handleClose" | |||
> | |||
<template #Context> | |||
<n-form | |||
ref="formRef" | |||
:model="form" | |||
label-placement="left" | |||
:rules="rules" | |||
:on-positive-click="handleConfirm" | |||
:on-negative-click="handleClose" | |||
> | |||
<n-form-item label="角色编号:" path="code"> | |||
<n-input | |||
v-model:value="form.code" | |||
clearable | |||
:maxlength="20" | |||
placeholder="请输入角色编号" | |||
/> | |||
</n-form-item> | |||
<n-form-item label="角色名称:" path="name"> | |||
<n-input | |||
v-model:value="form.name" | |||
clearable | |||
:maxlength="20" | |||
placeholder="请输入角色名称" | |||
/> | |||
</n-form-item> | |||
<n-form-item label="状态" path="status"> | |||
<n-radio-group | |||
v-model:value="form.status" | |||
> | |||
<n-radio :value="1">正常</n-radio> | |||
<n-radio :value="2">禁用</n-radio> | |||
</n-radio-group> | |||
</n-form-item> | |||
<n-form-item | |||
label="备注:" | |||
> | |||
<n-input | |||
v-model:value="form.note" | |||
type="textarea" | |||
:rows="3" | |||
:maxlength="200" | |||
placeholder="请输入备注" | |||
/> | |||
</n-form-item> | |||
</n-form> | |||
</template> | |||
</Modal> | |||
</template> | |||
<script> | |||
import { defineComponent, computed, reactive, toRefs } from 'vue' | |||
import Modal from '@/components/Modal/index.vue' | |||
import { addRole, editRole } from '@/api/system/role/index' | |||
export default defineComponent({ | |||
name: 'RoleModal', | |||
components: { Modal }, | |||
props: { | |||
visible: { | |||
type: Boolean, | |||
default: false | |||
}, | |||
row: { | |||
type: Object, | |||
default: () => {} | |||
} | |||
}, | |||
emits: { | |||
'update:visible': null, | |||
'done': null | |||
}, | |||
setup(props, { emit }) { | |||
const data = reactive({ | |||
form: { | |||
code: '', | |||
name: '', | |||
status: 1, | |||
note: '' | |||
}, | |||
rules: { | |||
code: [ | |||
{ required: true, message: '请输入角色编号', trigger: 'blur' } | |||
], | |||
name: [ | |||
{ required: true, message: '请输入角色名称', type: 'string', trigger: 'blur' } | |||
], | |||
status: [ | |||
{ required: true, message: '请选择状态', type: 'number', trigger: 'blur' } | |||
] | |||
} | |||
}) | |||
const getModalOptions = computed(() => { | |||
return { | |||
title: Object.keys(props.row).length === 0 ? '添加角色' : '编辑角色', | |||
show: props.visible, | |||
form: Object.assign(data.form, props.row), | |||
negativeText: '取消', | |||
positiveText: '确认' | |||
} | |||
}) | |||
/* 关闭弹窗 */ | |||
const handleClose = () => { | |||
emit('update:visible', false) | |||
} | |||
return { | |||
getModalOptions, | |||
handleClose, | |||
...toRefs(data), | |||
rules: reactive({ | |||
code: [ | |||
{ required: true, message: '请输入角色编号', trigger: 'blur' } | |||
], | |||
name: [ | |||
{ required: true, message: '请输入角色名称', type: 'string', trigger: 'blur' } | |||
], | |||
status: [ | |||
{ required: true, message: '请选择状态', type: 'number', trigger: 'blur' } | |||
] | |||
}) | |||
} | |||
}, | |||
methods: { | |||
// 表单提交 | |||
handleConfirm() { | |||
const type = Object.keys(this.row).length === 0 ? 'add' : 'edit' | |||
this.$refs.formRef.validate((errors) => { | |||
if (!errors) { | |||
if (type === 'add') { | |||
addRole(this.form).then(res => { | |||
if (res.code === 0) { | |||
this.handleClose() | |||
this.$emit('done') | |||
$message.success(res.msg) | |||
} else { | |||
$message.error(res.msg) | |||
} | |||
}).catch(e => { | |||
console.log(e) | |||
}) | |||
} else if (type === 'edit') { | |||
editRole(this.form).then(res => { | |||
if (res.code === 0) { | |||
this.handleClose() | |||
this.$emit('done') | |||
$message.success(res.msg) | |||
} else { | |||
$message.error(res.msg) | |||
} | |||
}) | |||
} | |||
} | |||
}) | |||
} | |||
} | |||
}) | |||
</script> | |||
<style scoped lang='scss'> | |||
</style> |
@@ -1,239 +0,0 @@ | |||
<template> | |||
<div> | |||
<n-card> | |||
<headSearch :info="info" @search="handleSearch" /> | |||
<data-table | |||
ref="tableRef" | |||
:columns="columns" | |||
:row-key="(row) => row.id" | |||
:request="loadDataTable" | |||
size="large" | |||
scroll-x="1200" | |||
@update:checked-row-keys="handleCheck" | |||
> | |||
<template #tableTitle> | |||
<n-button type="primary" @click="handleModal"> 新建 </n-button> | |||
<n-popconfirm | |||
negative-text="取消" | |||
positive-text="确认" | |||
@positive-click="deleteComplex" | |||
> | |||
<template #trigger> | |||
<n-button type="primary">删除</n-button> | |||
</template> | |||
确定删除选中的数据吗? | |||
</n-popconfirm> | |||
</template> | |||
</data-table> | |||
</n-card> | |||
</div> | |||
<!-- 新增、编辑弹窗 --> | |||
<role-modal | |||
v-if="modalShow" | |||
v-model:visible="modalShow" | |||
:row="rowData" | |||
@done="handleSearch" | |||
/> | |||
<!-- 分配权限 --> | |||
<config-modal | |||
v-if="configModalShow" | |||
v-model:visible="configModalShow" | |||
:row="rowData" | |||
@done="handleSearch" | |||
/> | |||
</template> | |||
<script> | |||
import headSearch from '@/components/Search/index.vue' | |||
import dataTable from '@/components/DataTable/index.vue' | |||
import TableAction from '@/components/DataTable/tools/Action.vue' | |||
import TableSwitch from '@/components/DataTable/tools/Switch.vue' | |||
import { | |||
getRoleList, | |||
deleteRole, | |||
setRoleStatus | |||
} from '@/api/system/role/index' | |||
import { h, ref, unref, toRefs, reactive } from 'vue' | |||
import table from './table.js' | |||
import info from './info.js' | |||
import RoleModal from './components/RoleModal.vue' | |||
import ConfigModal from './components/ConfigModal.vue' | |||
export default { | |||
name: 'MenuPage', | |||
components: { headSearch, dataTable, RoleModal, ConfigModal }, | |||
setup() { | |||
const data = reactive({ | |||
columns: [ | |||
...table.columns, | |||
{ | |||
title: '状态', | |||
key: 'status', | |||
align: 'center', | |||
width: 100, | |||
render(row) { | |||
return h(TableSwitch, { | |||
data: { id: row.id, status: row.status }, | |||
rowKey: 'status', | |||
checkedValue: 1, | |||
uncheckedValue: 2, | |||
onChange: setStatus.bind(row) | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '操作', | |||
align: 'center', | |||
width: 150, | |||
fixed: 'right', | |||
render(row) { | |||
return h(TableAction, { | |||
actions: [ | |||
{ | |||
label: '修改', | |||
type: 'button', | |||
props: { | |||
type: 'primary', | |||
onClick: play.bind(null, row) | |||
}, | |||
auth: 'basic_list' | |||
}, | |||
{ | |||
label: '分配权限', | |||
type: 'button', | |||
props: { | |||
type: 'primary', | |||
ghost: true, | |||
onClick: configure.bind(null, row) | |||
}, | |||
auth: 'basic_list' | |||
}, | |||
{ | |||
label: '删除', | |||
type: 'popconfirm', | |||
auth: 'basic_list', | |||
tip: '确定删除这条数据吗?', | |||
props: { | |||
negativeText: '取消', | |||
positiveText: '确认', | |||
onPositiveClick: deleteSingle.bind(null, row.id) | |||
} | |||
} | |||
], | |||
align: 'center' | |||
}) | |||
} | |||
} | |||
], | |||
info: ref(info), | |||
modalShow: false, | |||
configModalShow: false, | |||
rowData: {} | |||
}) | |||
// 编辑 | |||
function play(row) { | |||
data.rowData = row | |||
data.modalShow = true | |||
} | |||
// 配置权限 | |||
function configure(row) { | |||
data.rowData = row | |||
data.configModalShow = true | |||
} | |||
const params = ref({}) | |||
const tableRef = ref() | |||
function handleSearch(data) { | |||
params.value = { | |||
...data | |||
} | |||
tableRef.value.reFetch({ ...unref(params) }) | |||
} | |||
const loadDataTable = async(res) => { | |||
const _params = { | |||
...unref(params), | |||
...res | |||
} | |||
return await getRoleList(_params) | |||
} | |||
// 新增用户 | |||
function handleModal() { | |||
data.rowData = {} | |||
data.modalShow = true | |||
} | |||
// 选择表格数据 | |||
const selectedIds = ref([]) | |||
function handleCheck(rowKeys) { | |||
selectedIds.value = rowKeys | |||
} | |||
// 批量删除 | |||
function deleteComplex() { | |||
if (selectedIds.value.length) { | |||
deleteData(selectedIds.value) | |||
} else { | |||
$message.warning('请至少选中一条数据') | |||
} | |||
} | |||
// 单个删除数据 | |||
function deleteSingle(id) { | |||
deleteData([id]) | |||
} | |||
// 删除接口 | |||
function deleteData(data) { | |||
deleteRole(data) | |||
.then((res) => { | |||
if (res.code === 0) { | |||
handleSearch() | |||
$message.success(res.msg) | |||
} else { | |||
$message.error(res.msg) | |||
} | |||
}) | |||
.catch((e) => { | |||
console.log(e) | |||
}) | |||
} | |||
// 设置状态 | |||
function setStatus(row) { | |||
console.log(row) | |||
setRoleStatus({ id: row.data.id, status: row.value }) | |||
.then((res) => { | |||
if (res.code === 0) { | |||
handleSearch() | |||
$message.success(res.msg) | |||
} else { | |||
$message.error(res.msg) | |||
} | |||
}) | |||
.catch((e) => { | |||
console.log(e) | |||
}) | |||
} | |||
return { | |||
...toRefs(data), | |||
tableRef, | |||
loadDataTable, | |||
handleSearch, | |||
handleModal, | |||
handleCheck, | |||
selectedIds, | |||
deleteSingle, | |||
deleteComplex, | |||
deleteData, | |||
setStatus | |||
} | |||
} | |||
} | |||
</script> | |||
<style scoped lang='scss'> | |||
.n-button + .n-button { | |||
margin-left: 10px; | |||
} | |||
</style> |
@@ -1,30 +0,0 @@ | |||
const data = { | |||
columns: [ | |||
{ type: 'selection' }, | |||
{ | |||
title: '角色编号', | |||
key: 'code', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '角色名称', | |||
key: 'name', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '创建时间', | |||
key: 'createTime', | |||
align: 'center', | |||
Minwidth: 160 | |||
}, | |||
{ | |||
title: '更新时间', | |||
key: 'updateTime', | |||
align: 'center', | |||
Minwidth: 160 | |||
} | |||
] | |||
} | |||
export default data |
@@ -1,251 +0,0 @@ | |||
<template> | |||
<Modal | |||
:options="getModalOptions" | |||
:on-positive-click="handleConfirm" | |||
:on-negative-click="handleClose" | |||
:on-close="handleClose" | |||
> | |||
<template #Context> | |||
<n-form | |||
ref="formRef" | |||
:model="form" | |||
label-placement="left" | |||
:rules="rules" | |||
:on-positive-click="handleConfirm" | |||
:on-negative-click="handleClose" | |||
> | |||
<n-form-item | |||
label="头像:" | |||
path="avatar" | |||
> | |||
<uploadImage | |||
:options="{ | |||
max:1, | |||
action: '/upload/uploadImage/demo', | |||
}" | |||
/> | |||
</n-form-item> | |||
<n-form-item label="用户编号:" path="code"> | |||
<n-input | |||
v-model:value="form.code" | |||
clearable | |||
:maxlength="20" | |||
placeholder="请输入用户编号" | |||
/> | |||
</n-form-item> | |||
<n-form-item label="用户账号:" path="username"> | |||
<n-input | |||
v-model:value="form.username" | |||
clearable | |||
:maxlength="20" | |||
placeholder="请输入用户账号" | |||
/> | |||
</n-form-item> | |||
<n-form-item | |||
label="登录密码:" | |||
path="password" | |||
> | |||
<n-input | |||
v-model:value="form.password" | |||
type="password" | |||
:maxlength="20" | |||
placeholder="请输入登录密码" | |||
/> | |||
</n-form-item> | |||
<n-form-item label="用户姓名:" path="realname"> | |||
<n-input | |||
v-model:value="form.realname" | |||
clearable | |||
:maxlength="20" | |||
placeholder="请输入用户姓名" | |||
/> | |||
</n-form-item> | |||
<n-form-item label="所属部门:" path="deptId"> | |||
<n-select | |||
v-model:value="form.deptId" | |||
:options="deptOptions" | |||
placeholder="请选择所属部门" | |||
/> | |||
</n-form-item> | |||
<n-form-item label="角色:" path="roleIds"> | |||
<n-select | |||
v-model:value="form.roleIds" | |||
clearable | |||
:multiple="true" | |||
:options="rolesOptions" | |||
placeholder="请选择角色" | |||
/> | |||
</n-form-item> | |||
<n-form-item label="状态" path="status"> | |||
<n-radio-group | |||
v-model:value="form.status" | |||
> | |||
<n-radio :value="1">正常</n-radio> | |||
<n-radio :value="2">禁用</n-radio> | |||
</n-radio-group> | |||
</n-form-item> | |||
<n-form-item | |||
label="备注:" | |||
> | |||
<n-input | |||
v-model:value="form.note" | |||
type="textarea" | |||
:rows="3" | |||
:maxlength="200" | |||
placeholder="请输入备注" | |||
/> | |||
</n-form-item> | |||
</n-form> | |||
</template> | |||
</Modal> | |||
</template> | |||
<script> | |||
import { defineComponent, computed, onMounted, reactive, toRefs } from 'vue' | |||
import Modal from '@/components/Modal/index.vue' | |||
import uploadImage from '@/components/ImgUpload/index.vue' | |||
import { getDeptAll } from '@/api/system/dept/index' | |||
import { getRoleAll } from '@/api/system/role/index' | |||
import { addUser, editUser } from '@/api/system/user/index' | |||
import { dataToSelect } from '@/utils/handleData.js' | |||
export default defineComponent({ | |||
name: 'UserModal', | |||
components: { Modal, uploadImage }, | |||
props: { | |||
visible: { | |||
type: Boolean, | |||
default: false | |||
}, | |||
row: { | |||
type: Object, | |||
default: () => {} | |||
} | |||
}, | |||
emits: { | |||
'update:visible': null, | |||
'done': null | |||
}, | |||
setup(props, { emit }) { | |||
const data = reactive({ | |||
form: { | |||
avatar: '/images/user/20211011/20211011151447698.jpg', | |||
code: '', | |||
deptId: null, | |||
username: '', | |||
realname: '', | |||
password: '', | |||
roleIds: [], | |||
status: 1, | |||
note: '' | |||
}, | |||
deptOptions: [], | |||
rolesOptions: [], | |||
rules: { | |||
avatar: [ | |||
{ required: true, message: '请选择头像', type: 'string', trigger: 'blur' } | |||
], | |||
code: [ | |||
{ required: true, message: '请输入编号', trigger: 'blur' } | |||
], | |||
realname: [ | |||
{ required: true, message: '请输入用户姓名', type: 'string', trigger: 'blur' } | |||
], | |||
deptId: [ | |||
{ required: true, message: '请选择部门', type: 'number', trigger: 'blur' } | |||
], | |||
status: [ | |||
{ required: true, message: '请选择状态', type: 'number', trigger: 'blur' } | |||
], | |||
roleIds: [ | |||
{ required: true, message: '请选择角色', type: 'array', trigger: 'blur' } | |||
], | |||
username: [ | |||
{ required: true, message: '请输入用户账号', type: 'string', trigger: 'blur' } | |||
] | |||
} | |||
}) | |||
const getModalOptions = computed(() => { | |||
return { | |||
title: Object.keys(props.row).length === 0 ? '添加用户' : '编辑用户', | |||
show: props.visible, | |||
form: Object.assign(data.form, props.row), | |||
negativeText: '取消', | |||
positiveText: '确认' | |||
} | |||
}) | |||
/* 关闭弹窗 */ | |||
const handleClose = () => { | |||
emit('update:visible', false) | |||
} | |||
// 获取部门列表 | |||
async function getDeptOptions() { | |||
const res = await getDeptAll() | |||
data.deptOptions = dataToSelect(res.data, { label: 'name', value: 'id' }) | |||
} | |||
// 获取角色列表 | |||
async function getRoleOptions() { | |||
const res = await getRoleAll() | |||
data.rolesOptions = dataToSelect(res.data, { label: 'name', value: 'id' }) | |||
} | |||
onMounted(() => { | |||
getDeptOptions() | |||
getRoleOptions() | |||
}) | |||
// 上传文件 | |||
const handleUpload = ({ file }) => { | |||
console.log(file) | |||
// data.form.avatar = file.url | |||
} | |||
return { | |||
...toRefs(data), | |||
getModalOptions, | |||
handleClose, | |||
handleUpload | |||
} | |||
}, | |||
methods: { | |||
// 表单提交 | |||
handleConfirm() { | |||
const type = Object.keys(this.row).length === 0 ? 'add' : 'edit' | |||
this.$refs.formRef.validate((errors) => { | |||
if (!errors) { | |||
if (type === 'add') { | |||
addUser(this.form).then(res => { | |||
if (res.code === 0) { | |||
this.handleClose() | |||
this.$emit('done') | |||
$message.success(res.msg) | |||
} else { | |||
$message.error(res.msg) | |||
} | |||
}).catch(e => { | |||
console.log(e) | |||
}) | |||
} else if (type === 'edit') { | |||
editUser(this.form).then(res => { | |||
if (res.code === 0) { | |||
this.handleClose() | |||
this.$emit('done') | |||
$message.success(res.msg) | |||
} else { | |||
$message.error(res.msg) | |||
} | |||
}) | |||
} | |||
} else { | |||
$message.error('请完善必填信息') | |||
} | |||
}) | |||
} | |||
} | |||
}) | |||
</script> | |||
<style scoped lang='scss'> | |||
</style> |
@@ -1,233 +0,0 @@ | |||
<template> | |||
<div> | |||
<n-card> | |||
<headSearch :info="info" @search="handleSearch" /> | |||
<data-table | |||
ref="tableRef" | |||
:columns="columns" | |||
:row-key="(row) => row.id" | |||
:request="loadDataTable" | |||
size="large" | |||
@update:checked-row-keys="handleCheck" | |||
> | |||
<template #tableTitle> | |||
<n-button type="primary" @click="handleModal"> 新建 </n-button> | |||
<n-popconfirm | |||
negative-text="取消" | |||
positive-text="确认" | |||
@positive-click="deleteComplex" | |||
> | |||
<template #trigger> | |||
<n-button type="primary"> 删除 </n-button> | |||
</template> | |||
确认要删除选中数据吗? | |||
</n-popconfirm> | |||
</template> | |||
</data-table> | |||
</n-card> | |||
</div> | |||
<!-- 新增、编辑弹窗 --> | |||
<user-modal | |||
v-if="modalShow" | |||
v-model:visible="modalShow" | |||
:row="rowData" | |||
@done="handleSearch" | |||
/> | |||
</template> | |||
<script> | |||
import headSearch from '@/components/Search/index.vue' | |||
import dataTable from '@/components/DataTable/index.vue' | |||
import TableSwitch from '@/components/DataTable/tools/Switch.vue' | |||
import TableAction from '@/components/DataTable/tools/Action.vue' | |||
import { getUserList, resetPassword, deleteUser, setUserStatus } from '@/api/system/user/index.js' | |||
import { h, unref, ref, toRefs, reactive } from 'vue' | |||
import UserModal from './components/UserModal.vue' | |||
import info from './info.js' | |||
import table from './table.js' | |||
export default { | |||
name: 'MenuPage', | |||
components: { dataTable, UserModal, headSearch }, | |||
setup() { | |||
const data = reactive({ | |||
columns: [ | |||
...table.columns, | |||
{ | |||
title: '状态', | |||
key: 'status', | |||
align: 'center', | |||
width: 100, | |||
render(row) { | |||
return h(TableSwitch, { | |||
data: { id: row.id, status: row.status }, | |||
rowKey: 'status', | |||
checkedValue: 1, | |||
uncheckedValue: 2, | |||
onChange: setStatus.bind(row) | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '操作', | |||
align: 'center', | |||
width: 150, | |||
fixed: 'right', | |||
render(row) { | |||
return h(TableAction, { | |||
actions: [ | |||
{ | |||
label: '修改', | |||
type: 'button', | |||
props: { | |||
type: 'primary', | |||
onClick: play.bind(null, row) | |||
}, | |||
auth: 'basic_list' | |||
}, | |||
{ | |||
label: '重置密码', | |||
type: 'popconfirm', | |||
auth: 'basic_list', | |||
tip: '确定要重置为123456吗?', | |||
props: { | |||
negativeText: '取消', | |||
positiveText: '确认', | |||
onPositiveClick: resetPsw.bind(null, row.id) | |||
} | |||
}, | |||
{ | |||
label: '删除', | |||
type: 'popconfirm', | |||
auth: 'basic_list', | |||
tip: '确定删除这条数据吗?', | |||
props: { | |||
negativeText: '取消', | |||
positiveText: '确认', | |||
onPositiveClick: deleteSingle.bind(null, row.id) | |||
} | |||
} | |||
], | |||
align: 'center' | |||
}) | |||
} | |||
} | |||
], | |||
info: ref(info), | |||
modalShow: false, | |||
rowData: {} | |||
}) | |||
// 打开编辑弹窗 | |||
function play(row) { | |||
data.rowData = row | |||
data.modalShow = true | |||
} | |||
const params = ref({}) | |||
const tableRef = ref() | |||
function handleSearch(data) { | |||
params.value = { | |||
...data | |||
} | |||
tableRef.value.reFetch({ ...unref(params) }) | |||
} | |||
const loadDataTable = async(res) => { | |||
const _params = { | |||
...unref(params), | |||
...res | |||
} | |||
return await getUserList(_params) | |||
} | |||
// 新增 | |||
function handleModal() { | |||
data.rowData = {} | |||
data.modalShow = true | |||
} | |||
// 选择表格数据 | |||
const selectedIds = ref([]) | |||
function handleCheck(rowKeys) { | |||
selectedIds.value = rowKeys | |||
} | |||
// 批量删除 | |||
function deleteComplex() { | |||
if (selectedIds.value.length) { | |||
deleteData(selectedIds.value) | |||
} else { | |||
$message.warning('请至少选中一条数据') | |||
} | |||
} | |||
// 单个删除数据 | |||
function deleteSingle(id) { | |||
deleteData([id]) | |||
} | |||
// 删除用户接口 | |||
function deleteData(data) { | |||
deleteUser(data).then((res) => { | |||
if (res.code === 0) { | |||
handleSearch() | |||
$message.success(res.msg) | |||
} else { | |||
$message.error(res.msg) | |||
} | |||
}).catch(e => { | |||
console.log(e) | |||
}) | |||
} | |||
// 重置密码 | |||
function resetPsw(id) { | |||
resetPassword({ id }).then(res => { | |||
if (res.code === 0) { | |||
handleSearch() | |||
$message.success(res.msg) | |||
} else { | |||
$message.error(res.msg) | |||
} | |||
}).catch(e => { | |||
console.log(e) | |||
}) | |||
} | |||
// 设置状态 | |||
function setStatus(row) { | |||
setUserStatus({ id: row.data.id, status: row.value }).then(res => { | |||
if (res.code === 0) { | |||
handleSearch() | |||
$message.success(res.msg) | |||
} else { | |||
$message.error(res.msg) | |||
} | |||
}).catch(e => { | |||
console.log(e) | |||
}) | |||
} | |||
return { | |||
loadDataTable, | |||
handleModal, | |||
...toRefs(data), | |||
tableRef, | |||
handleSearch, | |||
selectedIds, | |||
deleteComplex, | |||
handleCheck, | |||
deleteData, | |||
resetPsw, | |||
setStatus | |||
} | |||
}, | |||
methods: { | |||
} | |||
} | |||
</script> | |||
<style scoped lang='scss'> | |||
.n-button + .n-button { | |||
margin-left: 10px; | |||
} | |||
</style> |
@@ -1,45 +0,0 @@ | |||
import { getRoleAll } from '@/api/system/role/index' | |||
import { dataToSelect } from '@/utils/handleData.js' | |||
import { ref } from 'vue' | |||
const rolesOptions = ref([]) | |||
const getRolesOption = async function() { | |||
const res = await getRoleAll() | |||
rolesOptions.value = dataToSelect(res.data, { label: 'name', value: 'id' }) | |||
} | |||
// getRolesOption() | |||
const data = [ | |||
{ | |||
label: '用户账号', | |||
key: 'username', | |||
props: { | |||
placeholder: '请输入用户账号' | |||
} | |||
}, | |||
{ | |||
label: '用户姓名', | |||
key: 'realname', | |||
props: { | |||
placeholder: '请输入用户姓名' | |||
} | |||
}, | |||
{ | |||
label: '用户角色', | |||
type: 'select', | |||
key: 'roleId', | |||
props: { | |||
placeholder: '请选择用户角色', | |||
options: rolesOptions | |||
} | |||
} | |||
// { | |||
// label: '角色类型', | |||
// type: 'date', | |||
// key: 'date', | |||
// props: { | |||
// type: 'date' | |||
// } | |||
// } | |||
] | |||
export default data | |||
@@ -1,69 +0,0 @@ | |||
import { h } from 'vue' | |||
import TableImage from '@/components/DataTable/tools/Image.vue' | |||
import TableTags from '@/components/DataTable/tools/Tags.vue' | |||
const table = { | |||
columns: [ | |||
{ | |||
type: 'selection' | |||
}, | |||
{ | |||
title: '用户编号', | |||
key: 'code', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '头像', | |||
key: 'avatar', | |||
align: 'center', | |||
render(row) { | |||
return h(TableImage, { | |||
images: { | |||
width: 36, | |||
height: 36, | |||
src: row.avatar | |||
} | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '用户账号', | |||
key: 'username', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '用户姓名', | |||
key: 'realname', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '角色', | |||
key: 'roleList', | |||
align: 'center', | |||
render(row) { | |||
return h(TableTags, { | |||
data: row.roleList, | |||
rowKey: 'name' | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '部门', | |||
key: 'deptName', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '创建时间', | |||
key: 'createTime', | |||
align: 'center', | |||
width: 160 | |||
}, | |||
{ | |||
title: '更新时间', | |||
key: 'updateTime', | |||
align: 'center', | |||
width: 160 | |||
} | |||
] | |||
} | |||
export default table |
@@ -28,7 +28,7 @@ | |||
</template> | |||
<script> | |||
import { defineComponent, computed, ref, unref, reactive, toRefs } from 'vue' | |||
import { defineComponent, computed, ref, reactive, toRefs } from 'vue' | |||
import Modal from '@/components/Modal/index.vue' | |||
import form from '../tools/form.js' | |||
export default defineComponent({ |
@@ -1,18 +1,20 @@ | |||
<template> | |||
<n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse"> | |||
<n-drawer-content closable title="问题核实"> | |||
<n-drawer-content closable title="疑似问题核实"> | |||
<!-- <QuestionPage /> --> | |||
<position-msg /> | |||
</n-drawer-content> | |||
</n-drawer> | |||
</template> | |||
<script> | |||
import { h, defineComponent, computed, reactive, toRefs } from 'vue' | |||
import QuestionPage from '@/views/task-manage/question/index.vue' | |||
import { defineComponent, computed, reactive, toRefs } from 'vue' | |||
import PositionMsg from '@/components/PositionMsg/index.vue' | |||
export default defineComponent({ | |||
name: 'LiveDrawer', | |||
components: { PositionMsg }, | |||
components: { QuestionPage, PositionMsg }, | |||
props: { | |||
/* 可见 */ | |||
visible: { | |||
@@ -29,9 +31,7 @@ export default defineComponent({ | |||
'update:visible': null | |||
}, | |||
setup(props, { emit }) { | |||
const data = reactive({ | |||
}) | |||
const data = reactive({}) | |||
/* 获取抽屉的信息 */ | |||
const getDrawerOptions = computed(() => { |
@@ -1,8 +1,8 @@ | |||
<template> | |||
<div> | |||
<n-card> | |||
<headSearch :info="search" /> | |||
<data-table | |||
<HeadSearch :info="search" /> | |||
<DataTable | |||
ref="tableRef" | |||
:columns="columns" | |||
:data="data" | |||
@@ -23,7 +23,7 @@ | |||
确认要删除选中数据吗? | |||
</n-popconfirm> --> | |||
</template> | |||
</data-table> | |||
</DataTable> | |||
</n-card> | |||
</div> | |||
@@ -39,10 +39,10 @@ | |||
</template> | |||
<script> | |||
import headSearch from '@/components/Search/index.vue' | |||
import table from './tools/table.js' | |||
import search from './tools/search.js' | |||
import dataTable from '@/components/DataTable/index.vue' | |||
import HeadSearch from '@/components/Search/index.vue' | |||
import DataTable from '@/components/DataTable/index.vue' | |||
import TaskModal from './components/TaskModal.vue' | |||
import LiveDrawer from './components/LiveDrawer.vue' | |||
import DemandDrawer from './components/DemandDrawer.vue' | |||
@@ -51,12 +51,12 @@ import { h, unref, ref, toRefs, reactive } from 'vue' | |||
export default { | |||
name: 'TaskAll', | |||
components: { headSearch, dataTable, TaskModal, LiveDrawer, DemandDrawer, VerifyDrawer }, | |||
components: { HeadSearch, DataTable, TaskModal, LiveDrawer, DemandDrawer, VerifyDrawer }, | |||
setup() { | |||
const data = reactive({ | |||
search, | |||
...toRefs(table), | |||
data: [{}], | |||
search | |||
data: [{}] | |||
}) | |||
/** |
@@ -2,6 +2,12 @@ | |||
import TableAction from '@/components/DataTable/tools/Action.vue' | |||
import { h, reactive } from 'vue' | |||
/** | |||
* @description: 获取数据及操作 | |||
* @param {*} row 单行数据 | |||
* @param {*} type 操作类型 create:创建,preview:预览,edit:编辑 | |||
* @return {*} | |||
*/ | |||
function getRowData(row, type) { | |||
data.rowData = row | |||
data.modalType = type |
@@ -0,0 +1,175 @@ | |||
<template> | |||
<Modal | |||
:options="getModalOptions" | |||
:on-positive-click="handleConfirm" | |||
:on-negative-click="handleIgnore" | |||
:on-close="handleClose" | |||
> | |||
<template #Context> | |||
<div class="carousel__flex"> | |||
<n-icon size="26" color="#8A8A8A"> | |||
<LeftOutlined @click="handleCarousel('prev')" /> | |||
</n-icon> | |||
<div class="carousel__container"> | |||
<label>问题描述</label> | |||
<n-carousel ref="carouselRef" :show-dots="false"> | |||
<img | |||
v-for="item in getCarouselInfo" | |||
:key="item.id" | |||
class="carousel-img" | |||
:src="item.image" | |||
> | |||
</n-carousel> | |||
</div> | |||
<n-icon size="26" color="#8A8A8A"> | |||
<RightOutlined @click="handleCarousel('next')" /> | |||
</n-icon> | |||
</div> | |||
<div class="modal-form"> | |||
<label>问题类型</label> | |||
<n-select | |||
v-model:value="selectType" | |||
:options="QUESTION_TYPE" | |||
/> | |||
</div> | |||
</template> | |||
</Modal> | |||
</template> | |||
<script> | |||
import { QUESTION_TYPE } from '@/utils/dictionary.js' | |||
import { LeftOutlined, RightOutlined } from '@vicons/antd' | |||
import Modal from '@/components/Modal/index.vue' | |||
import { defineComponent, computed, ref, reactive, toRefs } from 'vue' | |||
export default defineComponent({ | |||
name: 'UserModal', | |||
components: { Modal, LeftOutlined, RightOutlined }, | |||
props: { | |||
visible: { | |||
type: Boolean, | |||
default: false | |||
}, | |||
data: { | |||
type: Array, | |||
default: () => null | |||
} | |||
}, | |||
emits: { | |||
'update:visible': null, | |||
'update-data': null, | |||
'done': null | |||
}, | |||
setup(props, { emit }) { | |||
const formRef = ref() | |||
const data = reactive({ | |||
selectRow: props.data[0], | |||
selectType: props.data[0].type, | |||
QUESTION_TYPE | |||
}) | |||
/* 获取弹窗的属性 */ | |||
const getModalOptions = computed(() => { | |||
return { | |||
show: props.visible, | |||
title: '问题确认', | |||
width: 700, | |||
negativeText: '忽略', | |||
positiveText: '确认' | |||
} | |||
}) | |||
const getCarouselInfo = computed(() => { | |||
return props.data | |||
}) | |||
const carouselRef = ref(null) | |||
function handleCarousel(type) { | |||
const currentIndex = carouselRef.value.getCurrentIndex() | |||
switch (type) { | |||
case 'prev': | |||
if (currentIndex !== 0) { | |||
carouselRef.value.prev() | |||
data.selectRow = props.data[currentIndex - 1] | |||
data.selectType = props.data[currentIndex - 1].type | |||
} | |||
break | |||
case 'next': | |||
if (currentIndex !== props.data.length - 1) { | |||
carouselRef.value.next() | |||
data.selectRow = props.data[currentIndex + 1] | |||
data.selectType = props.data[currentIndex + 1].type | |||
} | |||
break | |||
} | |||
} | |||
/** | |||
* @description: 保存 | |||
* @return {*} | |||
*/ | |||
const handleConfirm = () => { | |||
emit('update-data') | |||
} | |||
const handleIgnore = () => { | |||
} | |||
/* 关闭弹窗 */ | |||
const handleClose = () => { | |||
emit('update:visible', false) | |||
} | |||
return { | |||
...toRefs(data), | |||
formRef, | |||
getModalOptions, | |||
getCarouselInfo, | |||
carouselRef, | |||
handleCarousel, | |||
handleConfirm, | |||
handleIgnore, | |||
handleClose | |||
} | |||
} | |||
}) | |||
</script> | |||
<style scoped lang='scss'> | |||
.carousel__flex{ | |||
display: flex; | |||
align-items: center; | |||
justify-content: space-between; | |||
.carousel__container{ | |||
width: calc(100% - 100px); | |||
display: flex; | |||
margin-right: 40px; | |||
label{ | |||
width: 70px; | |||
flex-shrink: 0; | |||
} | |||
} | |||
.n-icon{ | |||
cursor: pointer; | |||
} | |||
.carousel-img{ | |||
width: 100%; | |||
height: 280px; | |||
object-fit: cover | |||
} | |||
} | |||
.modal-form{ | |||
width: calc(100% - 60px); | |||
display: flex; | |||
align-items: center; | |||
margin: 20px auto 0; | |||
label{ | |||
width: 70px; | |||
flex-shrink: 0; | |||
} | |||
.n-select{ | |||
width: 300px; | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,94 @@ | |||
<template> | |||
<HeadSearch :info="search" /> | |||
<DataTable | |||
ref="tableRef" | |||
:columns="columns" | |||
:row-key="(row) => row.id" | |||
:data="data" | |||
size="large" | |||
scroll-x="1200" | |||
@fetch-success="getTableData" | |||
@update:checked-row-keys="handleRowsCheck" | |||
> | |||
<template #tableTitle> | |||
<n-button @click="handleIgnoreBatch">忽略</n-button> | |||
<n-button type="primary" @click="handleConfirmBatch"> | |||
确认 | |||
</n-button> | |||
</template> | |||
</DataTable> | |||
<ConfirmModal v-if="confirmModal" v-model:visible="confirmModal" :data="pageData" @update-data="tableReload" /> | |||
</template> | |||
<script> | |||
import table from './tools/table.js' | |||
import search from './tools/search.js' | |||
import HeadSearch from '@/components/Search/index.vue' | |||
import DataTable from '@/components/DataTable/index.vue' | |||
import ConfirmModal from './components/ConfirmModal.vue' | |||
import { h, computed, ref, reactive, toRefs } from 'vue' | |||
export default { | |||
name: 'QuestionPage', | |||
components: { HeadSearch, DataTable, ConfirmModal }, | |||
setup() { | |||
const data = reactive({ | |||
search, | |||
...toRefs(table), | |||
data: [ | |||
{ id: 1, image: 'https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel1.jpeg', type: 1 }, | |||
{ id: 2, image: 'https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel2.jpeg', type: 2 } | |||
], | |||
pageData: [] | |||
}) | |||
/** | |||
* @description: | |||
* @return {*} | |||
*/ | |||
function getTableData(list) { | |||
data.pageData = list | |||
} | |||
/** | |||
* @description: 选中行的rowkey | |||
* @param {*} rowKeys | |||
* @return {*} | |||
*/ | |||
function handleRowsCheck(rowKeys) { | |||
console.log(rowKeys) | |||
} | |||
function handleIgnoreBatch() { | |||
} | |||
function handleConfirmBatch() { | |||
} | |||
const tableRef = ref() | |||
/* 刷新表格数据 */ | |||
function tableReload(res) { | |||
const _params = { | |||
...res | |||
} | |||
tableRef.value.reFetch(_params) | |||
} | |||
return { | |||
...toRefs(data), | |||
tableRef, | |||
getTableData, | |||
handleRowsCheck, | |||
handleIgnoreBatch, | |||
handleConfirmBatch, | |||
tableReload | |||
} | |||
} | |||
} | |||
</script> | |||
<style scoped lang='scss'> | |||
</style> |
@@ -0,0 +1,21 @@ | |||
import { reactive } from 'vue' | |||
import { QUESTION_TYPE } from '@/utils/dictionary.js' | |||
const data = reactive([ | |||
{ | |||
label: '任务状态', | |||
key: 'status', | |||
type: 'select', | |||
value: 'all', | |||
props: { | |||
placeholder: '请选择任务状态', | |||
options: [ | |||
{ label: '全部', value: 'all' }, | |||
...QUESTION_TYPE | |||
] | |||
} | |||
} | |||
]) | |||
export default data | |||
@@ -0,0 +1,119 @@ | |||
// import TableTags from '@/components/DataTable/tools/Tags.vue' | |||
import TableImage from '@/components/DataTable/tools/Image.vue' | |||
import TableAction from '@/components/DataTable/tools/Action.vue' | |||
import { h, reactive } from 'vue' | |||
/* 问题忽略 */ | |||
function handleRowIgnore(row) { | |||
data.rowData = row | |||
console.log('问题忽略') | |||
} | |||
/* 问题确认 */ | |||
function handleRowConfirm(row) { | |||
data.rowData = row | |||
console.log('问题确认') | |||
} | |||
function handleImgPreview() { | |||
data.confirmModal = true | |||
} | |||
const data = reactive({ | |||
rowData: {}, | |||
confirmModal: false, | |||
columns: [ | |||
{ | |||
type: 'selection' | |||
}, | |||
{ | |||
title: '序号', | |||
key: 'name', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '问题类型', | |||
key: 'name', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '问题图片', | |||
key: 'image', | |||
align: 'center', | |||
render(row) { | |||
return h(TableImage, { | |||
images: { | |||
width: 36, | |||
height: 36, | |||
src: row.image, | |||
previewDisabled: true, | |||
onClick: handleImgPreview.bind(null, row) | |||
} | |||
}) | |||
} | |||
}, | |||
{ | |||
title: '经纬度', | |||
key: 'name', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '位置', | |||
key: 'name', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '备注', | |||
key: 'name', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '状态', | |||
key: 'name', | |||
align: 'center' | |||
}, | |||
{ | |||
title: '操作', | |||
align: 'center', | |||
width: 150, | |||
fixed: 'right', | |||
render(row) { | |||
return h(TableAction, { | |||
actions: [ | |||
{ | |||
label: '忽略', | |||
type: 'popconfirm', | |||
tip: '是否忽略该数据?', | |||
props: { | |||
onClick: handleRowIgnore.bind(null, row) | |||
}, | |||
ButtonProps: { | |||
text: true, | |||
type: 'primary' | |||
}, | |||
auth: 'basic_list' | |||
}, | |||
{ | |||
label: '确认', | |||
type: 'popconfirm', | |||
tip: '是否确认该数据?', | |||
props: { | |||
onClick: handleRowConfirm.bind(null, row) | |||
}, | |||
ButtonProps: { | |||
text: true, | |||
type: 'primary' | |||
}, | |||
auth: 'basic_list' | |||
} | |||
], | |||
align: 'center' | |||
}) | |||
} | |||
} | |||
] | |||
}) | |||
export default data |