new-map
parent
98f7ffd9b0
commit
1f265d6b85
|
|
@ -1,12 +0,0 @@
|
|||
import { defHttp } from '/@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
// The address does not exist
|
||||
Error = '/error',
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Trigger ajax error
|
||||
*/
|
||||
|
||||
export const fireErrorApi = () => defHttp.get({ url: Api.Error });
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
export interface BasicPageParams {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
}
|
||||
|
||||
export interface BasicFetchResult<T> {
|
||||
items: T[];
|
||||
total: number;
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
export interface UploadApiResult {
|
||||
message: string;
|
||||
code: number;
|
||||
url: string;
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
import { defHttp } from '/@/utils/http/axios';
|
||||
|
||||
import { ErrorMessageMode } from '/#/axios';
|
||||
|
||||
/**
|
||||
* @description:设备列表
|
||||
*/
|
||||
export function getDevices(params, mode: ErrorMessageMode = 'modal') {
|
||||
return defHttp.get(
|
||||
{
|
||||
url: '/api/devices',
|
||||
params,
|
||||
},
|
||||
{
|
||||
errorMessageMode: mode,
|
||||
},
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @description:设备类型
|
||||
*/
|
||||
export function getDeviceTypes(mode: ErrorMessageMode = 'modal') {
|
||||
return defHttp.get(
|
||||
{
|
||||
url: '/api/device-types',
|
||||
},
|
||||
{
|
||||
errorMessageMode: mode,
|
||||
},
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @description:添加设备
|
||||
*/
|
||||
export function createDevice(data, mode: ErrorMessageMode = 'modal') {
|
||||
return defHttp.post(
|
||||
{
|
||||
url: '/api/devices',
|
||||
data,
|
||||
},
|
||||
{
|
||||
errorMessageMode: mode,
|
||||
},
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @description:更新设备
|
||||
*/
|
||||
export function updateDevice(device, data, mode: ErrorMessageMode = 'modal') {
|
||||
return defHttp.put(
|
||||
{
|
||||
url: `/api/devices/${device}`,
|
||||
data,
|
||||
},
|
||||
{
|
||||
errorMessageMode: mode,
|
||||
},
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @description:删除设备
|
||||
*/
|
||||
export function deleteDevice(device, mode: ErrorMessageMode = 'modal') {
|
||||
return defHttp.delete(
|
||||
{
|
||||
url: `/api/devices/${device}`,
|
||||
},
|
||||
{
|
||||
errorMessageMode: mode,
|
||||
},
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @description:基地数据列表
|
||||
*/
|
||||
export function getAgriculturalBasic(
|
||||
params = { per_page: 999999, page: 1 },
|
||||
mode: ErrorMessageMode = 'modal',
|
||||
) {
|
||||
return defHttp.get(
|
||||
{
|
||||
url: '/api/agricultural-basic',
|
||||
params,
|
||||
},
|
||||
{
|
||||
errorMessageMode: mode,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
import { UploadApiResult } from './model/uploadModel';
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { UploadFileParams } from '/#/axios';
|
||||
import { useGlobSetting } from '/@/hooks/setting';
|
||||
|
||||
const { uploadUrl = '' } = useGlobSetting();
|
||||
|
||||
/**
|
||||
* @description: Upload interface
|
||||
*/
|
||||
export function uploadApi(
|
||||
params: UploadFileParams,
|
||||
onUploadProgress: (progressEvent: ProgressEvent) => void,
|
||||
) {
|
||||
return defHttp.uploadFile<UploadApiResult>(
|
||||
{
|
||||
url: uploadUrl,
|
||||
onUploadProgress,
|
||||
},
|
||||
params,
|
||||
);
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ import { ErrorMessageMode } from '/#/axios';
|
|||
|
||||
enum Api {
|
||||
Login = '/api/auth/login',
|
||||
Logout = '/logout',
|
||||
Logout = '/api/users/logout',
|
||||
GetUserInfo = '/api/users/info',
|
||||
GetPermCode = '/getPermCode',
|
||||
}
|
||||
|
|
@ -37,5 +37,5 @@ export function getPermCode() {
|
|||
}
|
||||
|
||||
export function doLogout() {
|
||||
return defHttp.get({ url: Api.Logout });
|
||||
return defHttp.delete({ url: Api.Logout });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,6 +201,10 @@
|
|||
.@{prefix-cls} {
|
||||
.ant-drawer-wrapper-body {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.ant-drawer-close {
|
||||
|
|
@ -209,10 +213,19 @@
|
|||
}
|
||||
}
|
||||
|
||||
.ant-drawer-content {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ant-drawer-body {
|
||||
height: calc(100% - @header-height);
|
||||
padding: 0;
|
||||
background-color: @component-background;
|
||||
flex-grow: 1;
|
||||
overflow: auto;
|
||||
font-size: 14px;
|
||||
line-height: 1.5715;
|
||||
word-wrap: break-word;
|
||||
|
||||
.scrollbar__wrap {
|
||||
padding: 16px !important;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ const main: AppRouteModule = {
|
|||
component: LAYOUT,
|
||||
redirect: '/permission/front/page',
|
||||
meta: {
|
||||
orderNo: 16,
|
||||
orderNo: 2,
|
||||
icon: 'ion:key-outline',
|
||||
title: '基础数据管理',
|
||||
},
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ const dashboard: AppRouteModule = {
|
|||
component: LAYOUT,
|
||||
redirect: '/dashboard/analysis',
|
||||
meta: {
|
||||
orderNo: 10,
|
||||
orderNo: 0,
|
||||
icon: 'ion:grid-outline',
|
||||
title: t('routes.dashboard.dashboard'),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
import type { AppRouteModule } from '/@/router/types';
|
||||
import { LAYOUT } from '/@/router/constant';
|
||||
const main: AppRouteModule = {
|
||||
path: '/device',
|
||||
name: 'Device',
|
||||
component: LAYOUT,
|
||||
redirect: '/device/index',
|
||||
meta: {
|
||||
orderNo: 3,
|
||||
icon: 'ion:key-outline',
|
||||
title: '设备管理',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
name: 'DeviceManagement',
|
||||
component: () => import('/@/views/device/management/index.vue'),
|
||||
meta: {
|
||||
title: '设备管理',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default main;
|
||||
|
|
@ -7,7 +7,7 @@ const main: AppRouteModule = {
|
|||
component: LAYOUT,
|
||||
redirect: '/permission/front/page',
|
||||
meta: {
|
||||
orderNo: 15,
|
||||
orderNo: 1,
|
||||
icon: 'ion:key-outline',
|
||||
title: t('routes.demo.main.meteorological'),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
import type { AppRouteModule } from '/@/router/types';
|
||||
import { LAYOUT } from '/@/router/constant';
|
||||
const main: AppRouteModule = {
|
||||
path: '/system',
|
||||
name: 'System',
|
||||
component: LAYOUT,
|
||||
redirect: '/permission/front/page',
|
||||
meta: {
|
||||
orderNo: 4,
|
||||
icon: 'ion:key-outline',
|
||||
title: '系统管理',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'management',
|
||||
name: 'SystemManagement',
|
||||
component: () => import('/@/views/system/management/index.vue'),
|
||||
meta: {
|
||||
title: '设备管理',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default main;
|
||||
|
|
@ -124,7 +124,7 @@ export const useUserStore = defineStore({
|
|||
},
|
||||
async getUserInfoAction(): Promise<UserInfo | null> {
|
||||
if (!this.getToken) return null;
|
||||
const { info, permissions } = await getUserInfo();
|
||||
const { info, permissions }: GetUserInfoModel = await getUserInfo();
|
||||
const userInfo: UserInfo = Object.assign({}, info, { roles: permissions });
|
||||
const { roles = [] } = userInfo;
|
||||
if (isArray(roles)) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,217 @@
|
|||
<template>
|
||||
<BasicDrawer
|
||||
v-bind="$attrs"
|
||||
@register="registerDrawer"
|
||||
showFooter
|
||||
:title="getTitle"
|
||||
width="500px"
|
||||
@ok="handleSubmit"
|
||||
>
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, computed, unref } from 'vue';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { FormSchema } from '/@/components/Table';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { getDeviceTypes, getAgriculturalBasic, createDevice } from '/@/api/sys/other';
|
||||
import { defaultsDeep } from 'lodash-es';
|
||||
|
||||
const formSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'type',
|
||||
component: 'Select',
|
||||
label: '设备类型',
|
||||
required: true,
|
||||
componentProps: {
|
||||
placeholder: '',
|
||||
options: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'agricultural_base_id',
|
||||
component: 'Select',
|
||||
label: '基地',
|
||||
required: true,
|
||||
componentProps: {
|
||||
placeholder: '',
|
||||
options: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
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);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
function formatDataByObject(obj): any[] {
|
||||
const arr: any[] = [];
|
||||
Object.keys(obj).forEach((e) => {
|
||||
arr.push({
|
||||
label: obj[e],
|
||||
value: e,
|
||||
});
|
||||
});
|
||||
return arr;
|
||||
}
|
||||
|
||||
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 = {};
|
||||
var last = keys.pop();
|
||||
keys.reduce((o, k) => (o[k] = o[k] || {}), object)[last] = value;
|
||||
return object;
|
||||
}
|
||||
|
||||
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,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
|
||||
if (unref(deviceTypesData).length === 0) {
|
||||
deviceTypesData.value = await getDeviceTypes();
|
||||
}
|
||||
if (unref(agriculturalBasicData).length === 0) {
|
||||
agriculturalBasicData.value = await getAgriculturalBasic();
|
||||
}
|
||||
|
||||
updateSchema({
|
||||
field: 'type',
|
||||
componentProps: {
|
||||
options: formatDataByObject(deviceTypesData.value),
|
||||
},
|
||||
});
|
||||
|
||||
updateSchema({
|
||||
field: 'agricultural_base_id',
|
||||
componentProps: {
|
||||
options: formatDataByArray(agriculturalBasicData.value),
|
||||
},
|
||||
});
|
||||
|
||||
if (unref(isUpdate)) {
|
||||
setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const getTitle = computed(() => (!unref(isUpdate) ? '新增设备' : '编辑设备'));
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const values = await validate();
|
||||
|
||||
let params = {};
|
||||
for (const key in values) {
|
||||
params = defaultsDeep({}, params, setValue(key.split('.'), values[key]));
|
||||
}
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
if (!unref(isUpdate)) {
|
||||
await createDevice(params);
|
||||
} else {
|
||||
await createDevice(params);
|
||||
}
|
||||
closeDrawer();
|
||||
emit('success');
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
registerForm,
|
||||
registerDrawer,
|
||||
getTitle,
|
||||
handleSubmit,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
<template>
|
||||
<div dense>
|
||||
<BasicTable @register="registerTable" :searchInfo="searchInfo">
|
||||
<template #toolbar>
|
||||
<a-button type="primary" @click="handleCreate">新增</a-button>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
placement: 'topRight',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
},
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<DeviceDrawer @register="registerDrawer" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
// import { PageWrapper } from '/@/components/Page';
|
||||
import { BasicTable, useTable } from '/@/components/Table';
|
||||
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 DeviceDrawer from './DeviceDrawer.vue';
|
||||
import { deleteDevice } from '/@/api/sys/other';
|
||||
|
||||
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 searchInfo = reactive<Recordable>({});
|
||||
const [registerTable, { reload, updateTableDataRecord }] = useTable({
|
||||
api: getDevices,
|
||||
rowKey: 'id',
|
||||
columns,
|
||||
formConfig: {
|
||||
labelWidth: 0,
|
||||
schemas: searchFormSchema,
|
||||
autoSubmitOnEnter: true,
|
||||
rowProps: { gutter: [16, 0] },
|
||||
},
|
||||
useSearchForm: true,
|
||||
showTableSetting: false,
|
||||
bordered: true,
|
||||
handleSearchInfoFn(info) {
|
||||
console.log('handleSearchInfoFn', info);
|
||||
return info;
|
||||
},
|
||||
actionColumn: {
|
||||
width: 80,
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
slots: { customRender: 'action' },
|
||||
fixed: undefined,
|
||||
},
|
||||
});
|
||||
|
||||
function handleCreate() {
|
||||
openDrawer(true, {
|
||||
isUpdate: false,
|
||||
});
|
||||
}
|
||||
|
||||
function handleEdit(record: Recordable) {
|
||||
openDrawer(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
});
|
||||
}
|
||||
|
||||
async function handleDelete(record: Recordable) {
|
||||
try {
|
||||
await deleteDevice(record.id);
|
||||
} finally {
|
||||
reload();
|
||||
}
|
||||
}
|
||||
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
|
||||
return {
|
||||
searchInfo,
|
||||
handleEdit,
|
||||
handleDelete,
|
||||
handleSuccess,
|
||||
registerDrawer,
|
||||
handleCreate,
|
||||
registerTable,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<template>
|
||||
<div> 设备管理</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
return {};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
Loading…
Reference in New Issue