ihzero 2022-11-03 09:57:11 +08:00
commit 1c5ad744c0
13 changed files with 775 additions and 440 deletions

View File

@ -120,3 +120,113 @@ export function deleteRoles(id: string, mode: ErrorMessageMode = 'modal') {
}, },
) )
} }
/**
* @description:
*/
export function getUsers(params, mode: ErrorMessageMode = 'modal') {
return defHttp.get(
{
url: '/api/admin-users',
params,
},
{
errorMessageMode: mode,
},
)
}
/**
* @description:
*/
export function getAgriculturalBasic(mode: ErrorMessageMode = 'modal') {
const params = { type: 1, per_page: 999999, page: 1 }
return defHttp.get(
{
url: '/api/agricultural-basic',
params,
},
{
errorMessageMode: mode,
},
)
}
/**
* @description:
*/
export function addUser(params, mode: ErrorMessageMode = 'modal') {
return defHttp.post(
{
url: '/api/admin-users',
params,
},
{
errorMessageMode: mode,
},
)
}
/**
* @description:/
*/
export function editEnable(id: string, mode: ErrorMessageMode = 'modal') {
return defHttp.put(
{
url: `/api/admin-users/${id}/enable `,
},
{
errorMessageMode: mode,
},
)
}
/**
* @description:
*/
export function getUsersInfo(id: string, mode: ErrorMessageMode = 'modal') {
return defHttp.get(
{
url: `/api/admin-users/${id} `,
},
{
errorMessageMode: mode,
},
)
}
/**
* @description:
*/
export function deleteUser(id: string, mode: ErrorMessageMode = 'modal') {
return defHttp.delete(
{
url: `/api/admin-users/${id}`,
},
{
errorMessageMode: mode,
},
)
}
/**
* @description:
*/
export function editUser(id: string, data, mode: ErrorMessageMode = 'modal') {
return defHttp.put(
{
url: `/api/admin-users/${id}`,
data,
},
{
errorMessageMode: mode,
},
)
}
/**
* @description:
*/
export function editPassword(id: string, data, mode: ErrorMessageMode = 'modal') {
return defHttp.put(
{
url: `/api/admin-users/${id}/edit-password`,
data,
},
{
errorMessageMode: mode,
},
)
}

View File

@ -1,5 +1,5 @@
import type { AppRouteModule } from '/@/router/types'; import type { AppRouteModule } from '/@/router/types'
import { LAYOUT } from '/@/router/constant'; import { LAYOUT } from '/@/router/constant'
const main: AppRouteModule = { const main: AppRouteModule = {
path: '/device', path: '/device',
name: 'Device', name: 'Device',
@ -20,6 +20,6 @@ const main: AppRouteModule = {
}, },
}, },
], ],
}; }
export default main; export default main

View File

@ -11,14 +11,6 @@ const main: AppRouteModule = {
title: '系统管理', title: '系统管理',
}, },
children: [ children: [
{
path: 'management',
name: 'SystemManagement',
component: () => import('/@/views/system/management/index.vue'),
meta: {
title: '设备管理',
},
},
{ {
path: 'role', path: 'role',
name: 'SystemRole', name: 'SystemRole',

View File

@ -97,3 +97,9 @@ export function isUrl(path: string): boolean {
/^(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?(\/#\/)?(?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/ /^(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?(\/#\/)?(?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/
return reg.test(path) return reg.test(path)
} }
/**
*
*/
export function isMobile(value: string) {
return /^1[3-9]\d{9}$/.test(value)
}

View File

@ -7,107 +7,40 @@
width="500px" width="500px"
@ok="handleSubmit" @ok="handleSubmit"
> >
<BasicForm @register="registerForm" /> <BasicForm @register="registerForm"> </BasicForm>
</BasicDrawer> </BasicDrawer>
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import { defineComponent, ref, computed, unref } from 'vue' import { ref, computed, unref } from 'vue'
import { BasicForm, useForm } from '/@/components/Form/index' import { BasicForm, useForm } from '/@/components/Form/index'
import { FormSchema } from '/@/components/Table' import { accountFormSchema } from './management.data'
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer' import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'
import { getDeviceTypes, getAgriculturalBasic, createDevice } from '/@/api/sys/other'
import { defaultsDeep } from 'lodash-es' import { defaultsDeep } from 'lodash-es'
import { createDevice, getDeviceTypes, updateDevice } from '/@/api/sys/other'
const formSchema: FormSchema[] = [ const emits = defineEmits(['success', 'register'])
{ const isUpdate = ref(false)
field: 'type', const getTitle = computed(() => (!isUpdate.value ? '新增设备' : '编辑设备'))
component: 'Select', const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
label: '设备类型', labelWidth: 120,
required: true, baseColProps: { span: 24 },
componentProps: { schemas: accountFormSchema,
placeholder: '', showActionButtonGroup: false,
options: [], })
}, const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
}, resetFields()
{ setDrawerProps({ confirmLoading: false })
field: 'agricultural_base_id', isUpdate.value = data?.isUpdate
component: 'Select', if (unref(isUpdate)) {
label: '基地', const obj = Object.assign({}, { ...data, ...data?.extends })
required: true, const deviceTypes = await getDeviceTypes()
componentProps: { await setFieldsValue({
placeholder: '', ...obj,
options: [], agricultural_base_id: obj.base_id,
}, type: formatDataByObject(deviceTypes).find((e) => e.label == obj.type)?.value,
}, })
{ }
field: 'sn', })
label: '设备编号', const formatDataByObject = (obj) => {
required: true,
component: 'Input',
},
{
field: 'monitoring_point',
label: '监控点',
required: true,
component: 'Input',
},
{
field: 'extends.ip',
label: '设备IP',
required: true,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)
},
},
{
field: 'extends.port',
label: '设备端口',
required: true,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)
},
},
{
field: 'extends.rtsp_url',
label: 'RTSP地址',
required: true,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)
},
},
{
field: 'extends.username',
label: '设备登录名',
required: true,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)
},
},
{
field: 'extends.password',
label: '设备登录密码',
required: true,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)
},
},
{
field: 'extends.passage',
label: '设备播放通道',
required: true,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)
},
},
]
function formatDataByObject(obj): any[] {
const arr: any[] = [] const arr: any[] = []
Object.keys(obj).forEach((e) => { Object.keys(obj).forEach((e) => {
arr.push({ arr.push({
@ -117,103 +50,31 @@
}) })
return arr return arr
} }
const setValue = (keys: any, value: any) => {
function formatDataByArray(arr, label = 'name', value = 'id'): any[] {
return arr.reduce((p, c) => {
p.push({
label: c[label],
value: c[value],
})
return p
}, [])
}
function setValue(keys, value) {
const object = {} const object = {}
var last = keys.pop() var last = keys.pop()
keys.reduce((o, k) => (o[k] = o[k] || {}), object)[last] = value keys.reduce((o, k) => (o[k] = o[k] || {}), object)[last] = value
return object return object
} }
const handleSubmit = async () => {
export default defineComponent({
name: 'RoleDrawer',
components: { BasicDrawer, BasicForm },
emits: ['success', 'register'],
setup(_, { emit }) {
const isUpdate = ref(true)
const deviceTypesData = ref<[]>([])
const agriculturalBasicData = ref<[]>([])
const [registerForm, { resetFields, setFieldsValue, validate, updateSchema }] = useForm({
labelWidth: 110,
baseColProps: { span: 24 },
schemas: formSchema,
showActionButtonGroup: false,
})
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
resetFields()
setDrawerProps({ confirmLoading: false })
isUpdate.value = !!data?.isUpdate
if (unref(deviceTypesData).length === 0) {
deviceTypesData.value = await getDeviceTypes()
updateSchema({
field: 'type',
componentProps: {
options: formatDataByObject(deviceTypesData.value),
},
})
}
if (unref(agriculturalBasicData).length === 0) {
agriculturalBasicData.value = await getAgriculturalBasic()
updateSchema({
field: 'agricultural_base_id',
componentProps: {
options: formatDataByArray(agriculturalBasicData.value),
},
})
}
if (unref(isUpdate)) {
console.log(data.record)
// setFieldsValue({
// ...data.record,
// })
}
})
const getTitle = computed(() => (!unref(isUpdate) ? '新增设备' : '编辑设备'))
async function handleSubmit() {
try { try {
const values = await validate() const values = await validate()
let params = {} let params = {}
for (const key in values) { for (const key in values) {
params = defaultsDeep({}, params, setValue(key.split('.'), values[key])) params = defaultsDeep({}, params, setValue(key.split('.'), values[key]))
} }
setDrawerProps({ confirmLoading: true }) setDrawerProps({ confirmLoading: true })
if (!unref(isUpdate)) { if (values.id) {
await createDevice(params) //
await updateDevice(values.id, params)
} else { } else {
//
await createDevice(params) await createDevice(params)
} }
closeDrawer() closeDrawer()
emit('success') emits('success')
} finally { } finally {
setDrawerProps({ confirmLoading: false }) setDrawerProps({ confirmLoading: false })
} }
} }
return {
registerForm,
registerDrawer,
getTitle,
handleSubmit,
}
},
})
</script> </script>

View File

@ -1,17 +1,15 @@
<template> <template>
<div> <div>
<BasicTable @register="registerTable" :searchInfo="searchInfo"> <BasicTable @register="registerTable">
<template #toolbar> <template #toolbar>
<a-button type="primary" @click="handleCreate"></a-button> <a-button type="primary" @click="handleCreate"> </a-button>
</template> </template>
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'"> <template v-if="column.key === 'action'">
<div class="flex items-center justify-center">
<TableAction <TableAction
:actions="[ :actions="[
{ { label: '编辑', onClick: handleEdit.bind(null, record) },
label: '编辑',
onClick: handleEdit.bind(null, record),
},
{ {
label: '删除', label: '删除',
popConfirm: { popConfirm: {
@ -22,108 +20,23 @@
}, },
]" ]"
/> />
</div>
</template> </template>
</template> </template>
</BasicTable> </BasicTable>
<DeviceDrawer @register="registerDrawer" @success="handleSuccess" /> <DeviceDrawer @register="registerDrawer" @success="handleSuccess" />
</div> </div>
</template> </template>
<script lang="ts" setup>
<script lang="ts"> import { BasicTable, useTable, TableAction } from '/@/components/Table'
// import { PageWrapper } from '/@/components/Page'; import { getDevices, deleteDevice } from '/@/api/sys/other'
import { BasicTable, useTable } from '/@/components/Table' import { message } from 'ant-design-vue'
import { Card } from 'ant-design-vue'
import { defineComponent, reactive } from 'vue'
import { getDevices } from '/@/api/sys/other'
import { BasicColumn, FormSchema, TableAction } from '/@/components/Table'
import { h } from 'vue'
import { Tag } from 'ant-design-vue'
import { useDrawer } from '/@/components/Drawer' import { useDrawer } from '/@/components/Drawer'
import DeviceDrawer from './DeviceDrawer.vue' import DeviceDrawer from './DeviceDrawer.vue'
import { deleteDevice } from '/@/api/sys/other' import { columns, searchFormSchema } from './management.data'
export const columns: BasicColumn[] = [
{
title: '类型',
dataIndex: 'type',
},
{
title: '设备编号',
dataIndex: 'sn',
},
{
title: '基地',
dataIndex: 'base_name',
},
{
title: '监控点',
dataIndex: 'monitoring_point',
},
{
title: '状态',
dataIndex: 'status',
customRender: ({ record }) => {
const status = record.status
// : 0 , 1 线, 2 线, 3
const list = [
{
value: 0,
color: 'red',
label: '禁用',
},
{
value: 1,
color: 'green',
label: '在线',
},
{
value: 2,
color: 'pink',
label: '离线',
},
{
value: 3,
color: 'orange',
label: '故障',
},
]
const item = list.find((e) => e.value === status)
const color = item?.color ?? 'red'
const text = item?.label ?? status
return h(Tag, { color: color }, () => text)
},
},
]
export const searchFormSchema: FormSchema[] = [
{
field: 'account',
label: '',
component: 'Input',
colProps: { span: 4 },
},
{
field: 'nickname',
label: '',
component: 'Input',
colProps: { span: 4 },
componentProps: {
placeholder: '请输入1',
},
},
]
export default defineComponent({
components: {
[Card.name]: Card,
BasicTable,
TableAction,
DeviceDrawer,
},
setup() {
const [registerDrawer, { openDrawer }] = useDrawer() const [registerDrawer, { openDrawer }] = useDrawer()
const searchInfo = reactive<Recordable>({}) const [registerTable, { reload }] = useTable({
const [registerTable, { reload, updateTableDataRecord }] = useTable({ title: '设备列表',
api: getDevices, api: getDevices,
rowKey: 'id', rowKey: 'id',
columns, columns,
@ -132,56 +45,29 @@
schemas: searchFormSchema, schemas: searchFormSchema,
}, },
useSearchForm: true, useSearchForm: true,
showTableSetting: false, showTableSetting: true,
bordered: true, bordered: true,
handleSearchInfoFn(info) { showIndexColumn: true,
console.log('handleSearchInfoFn', info)
return info
},
actionColumn: {
width: 120,
title: '操作',
dataIndex: 'action',
fixed: undefined,
},
}) })
function handleCreate() { const handleSuccess = () => {
message.success('操作成功')
reload()
}
const handleCreate = () => {
openDrawer(true, { openDrawer(true, {
isUpdate: false, id: false,
}) })
} }
const handleEdit = (record: Recordable) => {
function handleEdit(record: Recordable) {
openDrawer(true, { openDrawer(true, {
record, ...record,
isUpdate: true, isUpdate: true,
}) })
} }
const handleDelete = async (record: Recordable) => {
async function handleDelete(record: Recordable) {
try {
await deleteDevice(record.id) await deleteDevice(record.id)
} finally { message.success('删除成功')
reload() reload()
} }
}
function handleSuccess() {
reload()
}
return {
searchInfo,
handleEdit,
handleDelete,
handleSuccess,
registerDrawer,
handleCreate,
registerTable,
}
},
})
</script> </script>
<style scoped></style>

View File

@ -0,0 +1,224 @@
import { BasicColumn } from '/@/components/Table'
import { FormSchema } from '/@/components/Table'
import { getAgriculturalBasic } from '/@/api/sys/user'
import { getDeviceTypes } from '/@/api/sys/other'
import { h } from 'vue'
import { Tag } from 'ant-design-vue'
function formatDataByObject(obj): any[] {
const arr: any[] = []
Object.keys(obj).forEach((e) => {
arr.push({
label: obj[e],
value: e,
})
})
return arr
}
export const columns: BasicColumn[] = [
{
title: '类型',
dataIndex: 'type',
},
{
title: '设备编号',
dataIndex: 'sn',
},
{
title: '基地',
dataIndex: 'base_name',
},
{
title: '监控点',
dataIndex: 'monitoring_point',
},
{
title: '状态',
dataIndex: 'status',
customRender: ({ record }) => {
const status = record.status
// 状态: 0 禁用, 1 在线, 2 离线, 3 故障
const list = [
{
value: 0,
color: 'red',
label: '禁用',
},
{
value: 1,
color: 'green',
label: '在线',
},
{
value: 2,
color: 'pink',
label: '离线',
},
{
value: 3,
color: 'orange',
label: '故障',
},
]
const item = list.find((e) => e.value === status)
const color = item?.color ?? 'red'
const text = item?.label ?? status
return h(Tag, { color: color }, () => text)
},
},
{
width: 180,
title: '操作',
dataIndex: 'action',
align: 'center',
fixed: undefined,
},
]
export const searchFormSchema: FormSchema[] = [
{
field: 'base',
label: '基地',
component: 'ApiSelect',
componentProps: {
api: getAgriculturalBasic,
labelField: 'name',
valueField: 'id',
},
colProps: { span: 6 },
},
{
field: 'type',
label: '类型',
component: 'ApiSelect',
componentProps: {
api: async () => {
const res = await getDeviceTypes()
return formatDataByObject(res)
},
},
colProps: { span: 6 },
},
{
field: 'status',
label: '状态',
component: 'Select',
componentProps: {
options: [
{ label: '禁用', value: '0' },
{ label: '在线', value: '1' },
{ label: '离线', value: '2' },
{ label: '故障', value: '3' },
],
},
colProps: { span: 6 },
},
{
field: 'point',
label: '监控点',
component: 'Input',
colProps: { span: 6 },
},
]
export const accountFormSchema: FormSchema[] = [
{
field: 'id',
label: '设备ID',
required: false,
dynamicDisabled: true,
component: 'Input',
ifShow: ({ values }) => {
return !!values.id
},
},
{
field: 'type',
label: '设备类型',
required: true,
component: 'ApiSelect',
componentProps: {
api: async () => {
const res = await getDeviceTypes()
return formatDataByObject(res)
},
},
},
{
field: 'agricultural_base_id',
label: '基地',
required: true,
component: 'ApiSelect',
componentProps: {
api: getAgriculturalBasic,
labelField: 'name',
valueField: 'id',
},
},
{
field: 'sn',
label: '设备编号',
required: true,
component: 'Input',
},
{
field: 'monitoring_point',
label: '监控点',
required: true,
component: 'Input',
},
{
field: 'extends.ip',
label: '设备IP',
required: true,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)
},
},
{
field: 'extends.port',
label: '设备端口',
required: true,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)
},
},
{
field: 'extends.rtsp_url',
label: 'RTSP地址',
required: true,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)
},
},
{
field: 'extends.username',
label: '设备登录名',
required: true,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)
},
},
{
field: 'extends.password',
label: '设备登录密码',
required: true,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)
},
},
{
field: 'extends.passage',
label: '设备播放通道',
required: true,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)
},
},
]

View File

@ -0,0 +1,60 @@
<template>
<BasicDrawer
v-bind="$attrs"
@register="registerDrawer"
showFooter
:title="getTitle"
width="500px"
@ok="handleSubmit"
>
<BasicForm @register="registerForm"> </BasicForm>
</BasicDrawer>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue'
import { BasicForm, useForm } from '/@/components/Form/index'
import { accountFormSchema } from './account.data'
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'
import { addUser, getUsersInfo, editUser } from '/@/api/sys/user'
const emits = defineEmits(['success', 'register'])
const isUpdate = ref(false)
const getTitle = computed(() => (!isUpdate.value ? '新增账号' : '编辑账号'))
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
labelWidth: 90,
baseColProps: { span: 24 },
schemas: accountFormSchema,
showActionButtonGroup: false,
})
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
resetFields()
setDrawerProps({ confirmLoading: false })
isUpdate.value = data?.isUpdate
if (unref(isUpdate)) {
const res = await getUsersInfo(data.id)
await setFieldsValue({
...res,
role_id: res?.roles.map((e) => e.id),
base_ids: res?.bases.map((e) => e.id),
})
}
})
const handleSubmit = async () => {
try {
const values = await validate()
setDrawerProps({ confirmLoading: true })
if (values.id) {
values.role_id = values?.role_id.join()
//
await editUser(values.id, values)
} else {
//
await addUser(values)
}
closeDrawer()
emits('success')
} finally {
setDrawerProps({ confirmLoading: false })
}
}
</script>

View File

@ -1,18 +1,99 @@
import { BasicColumn } from '/@/components/Table' import { BasicColumn } from '/@/components/Table'
import { FormSchema } from '/@/components/Table' import { FormSchema } from '/@/components/Table'
import { getRoles, getAgriculturalBasic, editEnable } from '/@/api/sys/user'
import { isMobile } from '/@/utils/is'
import { h } from 'vue'
import { Tag, Switch, message } from 'ant-design-vue'
export const columns: BasicColumn[] = [ export const columns: BasicColumn[] = [
{ {
title: '角色名称', title: '用户名',
dataIndex: 'name', dataIndex: 'username',
width: 200,
},
{
title: '角色编码',
dataIndex: 'slug',
width: 180, width: 180,
}, },
{ {
width: 80, title: '昵称',
dataIndex: 'name',
width: 180,
},
{
title: '电话',
dataIndex: 'phone',
width: 180,
customRender: ({ text }) => {
if (!text) return '-'
return text
},
},
{
title: '部门',
dataIndex: 'department',
width: 180,
customRender: ({ text }) => {
if (!text) return '-'
return text
},
},
{
title: '是否启用',
dataIndex: 'is_enable',
width: 180,
customRender: ({ record }) => {
if (!Reflect.has(record, 'pendingStatus')) {
record.pendingStatus = false
}
return h(Switch, {
checked: record.is_enable == 1,
checkedChildren: '正常',
unCheckedChildren: '禁用',
loading: record.pendingStatus,
onChange: (e) => {
record.pendingStatus = true
editEnable(record.id)
.then(() => {
record.is_enable = e ? 1 : 0
message.success('状态修改成功')
})
.catch(({ msg }) => {
message.error(msg)
})
.finally(() => {
record.pendingStatus = false
})
},
})
},
},
{
title: '状态',
dataIndex: 'status',
width: 180,
customRender: ({ record }) => {
const status = record.status
const list = [
{
value: 1,
color: 'green',
label: '在职',
},
{
value: 2,
color: 'pink',
label: '离职',
},
{
value: 3,
color: 'orange',
label: '休假',
},
]
const item = list.find((e) => e.value === status)
const color = item?.color ?? 'red'
const text = item?.label ?? status
return h(Tag, { color: color }, () => text)
},
},
{
width: 180,
title: '操作', title: '操作',
dataIndex: 'action', dataIndex: 'action',
align: 'center', align: 'center',
@ -20,31 +101,12 @@ export const columns: BasicColumn[] = [
}, },
] ]
export const searchFormSchema: FormSchema[] = [ export const searchFormSchema: FormSchema[] = []
// {
// field: 'roleNme',
// label: '角色名称',
// component: 'Input',
// colProps: { span: 8 },
// },
// {
// field: 'status',
// label: '状态',
// component: 'Select',
// componentProps: {
// options: [
// { label: '启用', value: '0' },
// { label: '停用', value: '1' },
// ],
// },
// colProps: { span: 8 },
// },
]
export const formSchema: FormSchema[] = [ export const accountFormSchema: FormSchema[] = [
{ {
field: 'id', field: 'id',
label: '角色ID', label: '用户ID',
required: false, required: false,
dynamicDisabled: true, dynamicDisabled: true,
component: 'Input', component: 'Input',
@ -53,24 +115,115 @@ export const formSchema: FormSchema[] = [
}, },
}, },
{ {
field: 'name', field: 'username',
label: '角色名', label: '用户名',
required: true, required: true,
component: 'Input', component: 'Input',
}, },
{ {
field: 'slug', field: 'password',
label: '角色编码', label: '码',
required: true, required: true,
component: 'Input', component: 'InputPassword',
},
{
label: ' ',
field: 'permission_ids',
slot: 'menu',
component: 'Input',
ifShow: ({ values }) => { ifShow: ({ values }) => {
return !!values.id return !values.id
},
},
{
field: 'name',
label: '姓名',
required: true,
component: 'Input',
},
{
field: 'role_id',
label: '角色选择',
required: true,
component: 'ApiSelect',
componentProps: {
api: getRoles,
labelField: 'name',
valueField: 'id',
},
},
{
field: 'status',
label: '状态',
required: true,
component: 'RadioGroup',
componentProps: {
options: [
{
label: '在职',
value: 1,
},
{
label: '离职',
value: 2,
},
{
label: '休假',
value: 3,
},
],
},
},
{
field: 'department',
label: '部门',
required: false,
component: 'Input',
},
{
field: 'phone',
label: '手机号',
component: 'Input',
componentProps: {
type: 'number',
},
rules: [
{
required: false,
message: '请输入',
},
{
validator(_, value) {
return new Promise((resolve, reject) => {
if (!value) return resolve()
if (isMobile(value)) {
return resolve()
} else reject('手机号格式不正确')
})
},
},
],
},
{
field: 'base_ids',
label: '基地数据',
required: false,
component: 'ApiSelect',
componentProps: {
api: getAgriculturalBasic,
labelField: 'name',
valueField: 'id',
mode: 'multiple',
}, },
}, },
] ]
export const passwordFormSchema: FormSchema[] = [
{
field: 'password',
label: '密码',
required: true,
component: 'InputPassword',
},
{
field: 'password_confirmation',
label: '确认密码',
required: true,
component: 'InputPassword',
},
]

View File

@ -2,7 +2,7 @@
<div> <div>
<BasicTable @register="registerTable"> <BasicTable @register="registerTable">
<template #toolbar> <template #toolbar>
<a-button type="primary" @click="handleCreate"> </a-button> <a-button type="primary" @click="handleCreate"> </a-button>
</template> </template>
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'"> <template v-if="column.key === 'action'">
@ -10,6 +10,7 @@
<TableAction <TableAction
:actions="[ :actions="[
{ label: '编辑', onClick: handleEdit.bind(null, record) }, { label: '编辑', onClick: handleEdit.bind(null, record) },
{ label: '修改密码', onClick: handleEditpassword.bind(null, record) },
{ {
label: '删除', label: '删除',
popConfirm: { popConfirm: {
@ -24,20 +25,26 @@
</template> </template>
</template> </template>
</BasicTable> </BasicTable>
<RoleDrawer @register="registerDrawer" @success="handleSuccess" /> <AccountDrawer @register="registerDrawer" @success="handleSuccess" />
<!-- 修改密码弹窗 -->
<PasswordModel @register="registerModal" @success="handleSuccessModel" />
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { BasicTable, useTable, TableAction } from '/@/components/Table' import { BasicTable, useTable, TableAction } from '/@/components/Table'
import { getRoles, deleteRoles } from '/@/api/sys/user' import { getUsers, deleteUser } from '/@/api/sys/user'
import { useDrawer } from '/@/components/Drawer'
import RoleDrawer from './RoleDrawer.vue'
import { message } from 'ant-design-vue' import { message } from 'ant-design-vue'
import { columns, searchFormSchema } from './role.data' import { useDrawer } from '/@/components/Drawer'
import { useModal } from '/@/components/Modal'
import AccountDrawer from './AccountDrawer.vue'
import PasswordModel from './passwordModel.vue'
import { columns, searchFormSchema } from './account.data'
const [registerModal, { openModal }] = useModal()
const [registerDrawer, { openDrawer }] = useDrawer() const [registerDrawer, { openDrawer }] = useDrawer()
const [registerTable, { reload }] = useTable({ const [registerTable, { reload }] = useTable({
title: '账号管理', title: '账号列表',
api: getRoles, api: getUsers,
rowKey: 'id',
columns, columns,
formConfig: { formConfig: {
labelWidth: 120, labelWidth: 120,
@ -48,13 +55,14 @@
bordered: true, bordered: true,
showIndexColumn: true, showIndexColumn: true,
}) })
const handleSuccess = () => { const handleSuccess = () => {
message.success('操作成功') message.success('操作成功')
reload() reload()
} }
const handleCreate = () => { const handleCreate = () => {
openDrawer(true, { openDrawer(true, {
isUpdate: false, id: false,
}) })
} }
const handleEdit = (record: Recordable) => { const handleEdit = (record: Recordable) => {
@ -64,9 +72,17 @@
}) })
} }
const handleDelete = async (record: Recordable) => { const handleDelete = async (record: Recordable) => {
await deleteRoles(record.id) await deleteUser(record.id)
message.success('删除成功') message.success('删除成功')
reload() reload()
} }
//
const handleEditpassword = (record: Recordable) => {
openModal(true, {
id: record.id,
})
}
const handleSuccessModel = () => {
message.success('操作成功')
}
</script> </script>
<style></style>

View File

@ -0,0 +1,45 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" title="修改密码" @ok="handleSubmit">
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { BasicModal, useModalInner } from '/@/components/Modal'
import { BasicForm, useForm } from '/@/components/Form/index'
import { passwordFormSchema } from './account.data'
import { message } from 'ant-design-vue'
import { editPassword } from '/@/api/sys/user'
const ID = ref('')
const emits = defineEmits(['success', 'register'])
const [registerForm, { resetFields, validate }] = useForm({
labelWidth: 80,
baseColProps: { span: 24 },
schemas: passwordFormSchema,
showActionButtonGroup: false,
actionColOptions: {
span: 23,
},
})
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
ID.value = data.id
resetFields()
setModalProps({ confirmLoading: false })
})
async function handleSubmit() {
try {
const values = await validate()
if (values.password_confirmation !== values.password) return message.error('两次密码不一致')
setModalProps({ confirmLoading: true })
await editPassword(ID.value, values)
closeModal()
emits('success')
} finally {
setModalProps({ confirmLoading: false })
}
}
</script>

View File

@ -1,15 +0,0 @@
<template>
<div> 设备管理</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
setup() {
return {};
},
});
</script>
<style scoped></style>

View File

@ -69,8 +69,5 @@ export const formSchema: FormSchema[] = [
field: 'permission_ids', field: 'permission_ids',
slot: 'menu', slot: 'menu',
component: 'Input', component: 'Input',
ifShow: ({ values }) => {
return !!values.id
},
}, },
] ]