Browse Source

合并冲突

tags/v1.0.0^2
余菲 2 years ago
parent
commit
5793a46616
43 changed files with 1599 additions and 1077 deletions
  1. +59
    -0
      src/api/common/upload.js
  2. +1
    -1
      src/api/system/role/index.js
  3. +1
    -1
      src/components/DataTable/tools/useDataSource.js
  4. +1
    -2
      src/components/Modal/index.vue
  5. +28
    -1
      src/router/routes/modules/index.js
  6. +12
    -0
      src/utils/dictionary.js
  7. +17
    -0
      src/views/question-manage/question-distribution/index.vue
  8. +17
    -0
      src/views/question-manage/question-list/index.vue
  9. +17
    -0
      src/views/report-manage/all-report/index.vue
  10. +0
    -0
      src/views/system-manage/department-manage/components/DeptModal.vue
  11. +0
    -0
      src/views/system-manage/department-manage/index.vue
  12. +0
    -0
      src/views/system-manage/department-manage/info.js
  13. +0
    -0
      src/views/system-manage/department-manage/table.js
  14. +0
    -0
      src/views/system-manage/menu-manage/components/MenuModal.vue
  15. +0
    -0
      src/views/system-manage/menu-manage/index.vue
  16. +0
    -0
      src/views/system-manage/menu-manage/info.js
  17. +0
    -0
      src/views/system-manage/menu-manage/table.js
  18. +17
    -22
      src/views/system-manage/role-manage/components/ConfigModal.vue
  19. +135
    -0
      src/views/system-manage/role-manage/components/RoleModal.vue
  20. +104
    -0
      src/views/system-manage/role-manage/index.vue
  21. +24
    -0
      src/views/system-manage/role-manage/tools/form.js
  22. +4
    -2
      src/views/system-manage/role-manage/tools/search.js
  23. +165
    -0
      src/views/system-manage/role-manage/tools/table.js
  24. +168
    -0
      src/views/system-manage/user-manage/components/UserModal.vue
  25. +101
    -0
      src/views/system-manage/user-manage/index.vue
  26. +52
    -0
      src/views/system-manage/user-manage/tools/form.js
  27. +36
    -0
      src/views/system-manage/user-manage/tools/search.js
  28. +210
    -0
      src/views/system-manage/user-manage/tools/table.js
  29. +0
    -166
      src/views/system/role/components/RoleModal.vue
  30. +0
    -239
      src/views/system/role/index.vue
  31. +0
    -30
      src/views/system/role/table.js
  32. +0
    -251
      src/views/system/user/components/UserModal.vue
  33. +0
    -233
      src/views/system/user/index.vue
  34. +0
    -45
      src/views/system/user/info.js
  35. +0
    -69
      src/views/system/user/table.js
  36. +1
    -1
      src/views/task-manage/all-task/components/TaskModal.vue
  37. +6
    -6
      src/views/task-manage/all-task/components/VerifyDrawer.vue
  38. +8
    -8
      src/views/task-manage/all-task/index.vue
  39. +6
    -0
      src/views/task-manage/all-task/tools/table.js
  40. +175
    -0
      src/views/task-manage/question/components/ConfirmModal.vue
  41. +94
    -0
      src/views/task-manage/question/index.vue
  42. +21
    -0
      src/views/task-manage/question/tools/search.js
  43. +119
    -0
      src/views/task-manage/question/tools/table.js

+ 59
- 0
src/api/common/upload.js View File

@@ -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
})
}


+ 1
- 1
src/api/system/role/index.js View File

@@ -77,7 +77,7 @@ export function deleteRole(data) {
*/
export function getRolePermission(id) {
return request({
url: `/role/getPermissionList/${id}`,
url: `/role/getMenuList/${id}`,
method: 'GET'
})
}

+ 1
- 1
src/components/DataTable/tools/useDataSource.js View File

@@ -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)

+ 1
- 2
src/components/Modal/index.vue View File

@@ -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

+ 28
- 1
src/router/routes/modules/index.js View File

@@ -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'),

+ 12
- 0
src/utils/dictionary.js View File

@@ -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 }
]

+ 17
- 0
src/views/question-manage/question-distribution/index.vue View File

@@ -0,0 +1,17 @@
<template>
<div>
问题分布
</div>
</template>

<script>
export default {
name: 'QuestionDistribution',
setup() {

}
}

</script>
<style scoped lang='scss'>
</style>

+ 17
- 0
src/views/question-manage/question-list/index.vue View File

@@ -0,0 +1,17 @@
<template>
<div>
问题列表
</div>
</template>

<script>
export default {
name: 'QuestionList',
setup() {

}
}

</script>
<style scoped lang='scss'>
</style>

+ 17
- 0
src/views/report-manage/all-report/index.vue View File

@@ -0,0 +1,17 @@
<template>
<div>
全部报告
</div>
</template>

<script>
export default {
name: 'AllReport',
setup() {

}
}

</script>
<style scoped lang='scss'>
</style>

src/views/system/dept/components/DeptModal.vue → src/views/system-manage/department-manage/components/DeptModal.vue View File


src/views/system/dept/index.vue → src/views/system-manage/department-manage/index.vue View File


src/views/system/dept/info.js → src/views/system-manage/department-manage/info.js View File


src/views/system/dept/table.js → src/views/system-manage/department-manage/table.js View File


src/views/system/menu/components/MenuModal.vue → src/views/system-manage/menu-manage/components/MenuModal.vue View File


src/views/system/menu/index.vue → src/views/system-manage/menu-manage/index.vue View File


src/views/system/menu/info.js → src/views/system-manage/menu-manage/info.js View File


src/views/system/menu/table.js → src/views/system-manage/menu-manage/table.js View File


src/views/system/role/components/ConfigModal.vue → src/views/system-manage/role-manage/components/ConfigModal.vue View File

@@ -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
}
}
})

+ 135
- 0
src/views/system-manage/role-manage/components/RoleModal.vue View File

@@ -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>

+ 104
- 0
src/views/system-manage/role-manage/index.vue View File

@@ -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>

+ 24
- 0
src/views/system-manage/role-manage/tools/form.js View File

@@ -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

src/views/system/role/info.js → src/views/system-manage/role-manage/tools/search.js View File

@@ -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

+ 165
- 0
src/views/system-manage/role-manage/tools/table.js View File

@@ -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

+ 168
- 0
src/views/system-manage/user-manage/components/UserModal.vue View File

@@ -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>

+ 101
- 0
src/views/system-manage/user-manage/index.vue View File

@@ -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>

+ 52
- 0
src/views/system-manage/user-manage/tools/form.js View File

@@ -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' })
}

+ 36
- 0
src/views/system-manage/user-manage/tools/search.js View File

@@ -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 } })
}

+ 210
- 0
src/views/system-manage/user-manage/tools/table.js View File

@@ -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

+ 0
- 166
src/views/system/role/components/RoleModal.vue View File

@@ -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>

+ 0
- 239
src/views/system/role/index.vue View File

@@ -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>

+ 0
- 30
src/views/system/role/table.js View File

@@ -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

+ 0
- 251
src/views/system/user/components/UserModal.vue View File

@@ -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>

+ 0
- 233
src/views/system/user/index.vue View File

@@ -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>

+ 0
- 45
src/views/system/user/info.js View File

@@ -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


+ 0
- 69
src/views/system/user/table.js View File

@@ -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

+ 1
- 1
src/views/task-manage/all-task/components/TaskModal.vue View File

@@ -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({

+ 6
- 6
src/views/task-manage/all-task/components/VerifyDrawer.vue View File

@@ -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(() => {

+ 8
- 8
src/views/task-manage/all-task/index.vue View File

@@ -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: [{}]
})

/**

+ 6
- 0
src/views/task-manage/all-task/tools/table.js View File

@@ -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

+ 175
- 0
src/views/task-manage/question/components/ConfirmModal.vue View File

@@ -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>

+ 94
- 0
src/views/task-manage/question/index.vue View File

@@ -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>

+ 21
- 0
src/views/task-manage/question/tools/search.js View File

@@ -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


+ 119
- 0
src/views/task-manage/question/tools/table.js View File

@@ -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

Loading…
Cancel
Save