new-map
ihzero 2022-11-17 16:39:45 +08:00
parent 50df3f3e1c
commit e55f36133d
18 changed files with 508 additions and 83 deletions

View File

@ -6,7 +6,7 @@ VITE_PUBLIC_PATH = /
# Cross-domain proxy, you can configure multiple # Cross-domain proxy, you can configure multiple
# Please note that no line breaks # Please note that no line breaks
VITE_PROXY = [["/api","http://lcny-api.peidikeji.cn"]] VITE_PROXY = [["/api","http://lcny-api.peidikeji.cn"],["/upload","http://lcny-api.peidikeji.cn/api/web/upload"]]
# Delete console # Delete console
VITE_DROP_CONSOLE = false VITE_DROP_CONSOLE = false
@ -15,7 +15,7 @@ VITE_DROP_CONSOLE = false
VITE_GLOB_API_URL=/api VITE_GLOB_API_URL=/api
# File upload address optional # File upload address optional
VITE_GLOB_UPLOAD_URL=/api VITE_GLOB_UPLOAD_URL=/upload
# Interface prefix # Interface prefix
VITE_GLOB_API_URL_PREFIX= VITE_GLOB_API_URL_PREFIX=

View File

@ -855,3 +855,59 @@ export function updateFriendinks(params, mode: ErrorMessageMode = 'modal') {
}, },
) )
} }
/**
* @description:
*/
export function createFriendinks(data, mode: ErrorMessageMode = 'modal') {
return defHttp.post(
{
url: `/api/friend-links`,
data,
},
{
errorMessageMode: mode,
},
)
}
/**
* @description:
*/
export function deleteFriendinks(id, mode: ErrorMessageMode = 'modal') {
return defHttp.delete(
{
url: `/api/friend-links/${id}`,
},
{
errorMessageMode: mode,
},
)
}
/**
* @description:
*/
export function getWarningLogs(params, mode: ErrorMessageMode = 'modal') {
return defHttp.get(
{
url: `/api/device-warning-logs`,
params,
},
{
errorMessageMode: mode,
isTransformResponse: false,
},
)
}
/**
* @description:
*/
export function markWarningLogs(id, mode: ErrorMessageMode = 'modal') {
return defHttp.put(
{
url: `/api/device-warning-mark/${id}`,
},
{
errorMessageMode: mode,
},
)
}

View File

@ -18,9 +18,16 @@ export function uploadApi(
) { ) {
return defHttp.uploadFile<UploadApiResult>( return defHttp.uploadFile<UploadApiResult>(
{ {
url: uploadUrl + '/api/web/upload', url: uploadUrl,
onUploadProgress, onUploadProgress,
}, },
params, params,
) )
} }
export function uploadPostApi(data) {
return defHttp.post({
url: '/api/web/upload',
data,
})
}

View File

@ -1,11 +1,13 @@
<template> <template>
<div :class="[prefixCls, { fullscreen }]"> <div :class="[prefixCls, { fullscreen }]">
<!-- :action="uploadUrl" -->
<Upload <Upload
name="file" name="file"
:customRequest="customRequest"
multiple multiple
@change="handleChange" @change="handleChange"
:action="uploadUrl"
:showUploadList="false" :showUploadList="false"
:headers="headers"
accept=".jpg,.jpeg,.gif,.png,.webp" accept=".jpg,.jpeg,.gif,.png,.webp"
> >
<a-button type="primary" v-bind="{ ...getButtonProps }"> <a-button type="primary" v-bind="{ ...getButtonProps }">
@ -15,12 +17,14 @@
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, computed } from 'vue'; import { defineComponent, computed } from 'vue'
import { Upload } from 'ant-design-vue'; import { Upload } from 'ant-design-vue'
import { useDesign } from '/@/hooks/web/useDesign'; import { useDesign } from '/@/hooks/web/useDesign'
import { useGlobSetting } from '/@/hooks/setting'; import { useGlobSetting } from '/@/hooks/setting'
import { useI18n } from '/@/hooks/web/useI18n'; import { useI18n } from '/@/hooks/web/useI18n'
import { getToken } from '/@/utils/auth'
import { uploadPostApi } from '/@/api/upload'
export default defineComponent({ export default defineComponent({
name: 'TinymceImageUpload', name: 'TinymceImageUpload',
@ -36,48 +40,67 @@
}, },
emits: ['uploading', 'done', 'error'], emits: ['uploading', 'done', 'error'],
setup(props, { emit }) { setup(props, { emit }) {
let uploading = false; let uploading = false
const headers = {
const { uploadUrl } = useGlobSetting(); Authorization: `Bearer ` + getToken(),
const { t } = useI18n(); }
const { prefixCls } = useDesign('tinymce-img-upload'); const { uploadUrl } = useGlobSetting()
const { t } = useI18n()
const { prefixCls } = useDesign('tinymce-img-upload')
const getButtonProps = computed(() => { const getButtonProps = computed(() => {
const { disabled } = props; const { disabled } = props
return { return {
disabled, disabled,
}; }
}); })
function customRequest(file) {
const form = new FormData()
form.append('file', file.file)
form.append('contractName', file.file.name)
form.append('description', file.file.name)
//
uploadPostApi(form)
.then((res) => {
file.onSuccess(res)
})
.catch((err) => {
file.onError(err)
})
}
function handleChange(info: Recordable) { function handleChange(info: Recordable) {
const file = info.file; const file = info.file
const status = file?.status; const status = file?.status
const url = file?.response?.url; const url = file?.response?.file
const name = file?.name; const name = file?.name
if (status === 'uploading') { if (status === 'uploading') {
if (!uploading) { if (!uploading) {
emit('uploading', name); emit('uploading', name)
uploading = true; uploading = true
} }
} else if (status === 'done') { } else if (status === 'done') {
emit('done', name, url); emit('done', name, url)
uploading = false; uploading = false
} else if (status === 'error') { } else if (status === 'error') {
emit('error'); emit('error')
uploading = false; uploading = false
} }
} }
return { return {
customRequest,
headers,
prefixCls, prefixCls,
handleChange, handleChange,
uploadUrl, uploadUrl,
t, t,
getButtonProps, getButtonProps,
}; }
}, },
}); })
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@prefix-cls: ~'@{namespace}-tinymce-img-upload'; @prefix-cls: ~'@{namespace}-tinymce-img-upload';

View File

@ -250,8 +250,6 @@
for (const item of fileListRef.value) { for (const item of fileListRef.value) {
const { status, responseData } = item const { status, responseData } = item
if (status === UploadResultStatus.SUCCESS && responseData) { if (status === UploadResultStatus.SUCCESS && responseData) {
console.log(responseData?.data?.file)
fileList.push(responseData?.data?.file) fileList.push(responseData?.data?.file)
} }
} }

View File

@ -27,6 +27,8 @@ export const LOCK_INFO_KEY = 'LOCK__INFO__KEY__'
export const YEAR_KEY = 'YEAR_KEY__' export const YEAR_KEY = 'YEAR_KEY__'
export const INIT_TIME = 'INIT_TIME_'
export enum CacheTypeEnum { export enum CacheTypeEnum {
SESSION, SESSION,
LOCAL, LOCAL,

View File

@ -19,6 +19,14 @@ const main: AppRouteModule = {
title: '设备管理', title: '设备管理',
}, },
}, },
{
path: 'warning',
name: 'DeviceWarning',
component: () => import('/@/views/device/warning/index.vue'),
meta: {
title: '警报明细',
},
},
], ],
} }

View File

@ -12,6 +12,7 @@ import {
APP_LOCAL_CACHE_KEY, APP_LOCAL_CACHE_KEY,
APP_SESSION_CACHE_KEY, APP_SESSION_CACHE_KEY,
MULTIPLE_TABS_KEY, MULTIPLE_TABS_KEY,
INIT_TIME,
} from '/@/enums/cacheEnum' } from '/@/enums/cacheEnum'
import { DEFAULT_CACHE_TIME } from '/@/settings/encryptionSetting' import { DEFAULT_CACHE_TIME } from '/@/settings/encryptionSetting'
import { toRaw } from 'vue' import { toRaw } from 'vue'
@ -23,6 +24,7 @@ interface BasicStore {
[ROLES_KEY]: string[] [ROLES_KEY]: string[]
[PROJ_CFG_KEY]: ProjectConfig [PROJ_CFG_KEY]: ProjectConfig
[MULTIPLE_TABS_KEY]: RouteLocationNormalized[] [MULTIPLE_TABS_KEY]: RouteLocationNormalized[]
[INIT_TIME]: string | number | null | undefined
} }
type LocalStore = BasicStore type LocalStore = BasicStore

View File

@ -0,0 +1,78 @@
<template>
<div>
<BasicTable @register="registerTable">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<div class="flex items-center justify-center">
<TableAction
:actions="[
{
label: '标记',
popConfirm: {
title: '是否确认标记',
placement: 'topRight',
confirm: handleMark.bind(null, record),
},
ifShow: record.status == 0,
},
]"
/>
</div>
</template>
</template>
</BasicTable>
</div>
</template>
<script lang="ts">
import { BasicTable, useTable, TableAction } from '/@/components/Table'
import { getWarningLogs, markWarningLogs } from '/@/api/sys/user'
import { columns, searchFormSchema } from './warning.data'
import { message } from 'ant-design-vue'
export default {
components: {
BasicTable,
TableAction,
},
setup() {
const [registerTable, { reload }] = useTable({
title: '账号列表',
api: async (e) => {
const { data, meta } = await getWarningLogs({ ...e })
return {
items: data,
total: meta?.total,
}
},
rowKey: 'id',
columns,
formConfig: {
labelWidth: 80,
schemas: searchFormSchema,
},
useSearchForm: true,
showTableSetting: true,
bordered: true,
showIndexColumn: true,
})
const handleSuccess = () => {
message.success('操作成功')
reload()
}
const handleMark = async (record: Recordable) => {
await markWarningLogs(record.id)
message.success('删除成功')
reload()
}
return {
handleMark,
registerTable,
handleSuccess,
}
},
}
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,90 @@
import { BasicColumn, FormSchema } from '/@/components/Table'
import dayjs from 'dayjs'
import { h } from 'vue'
import { Tag } from 'ant-design-vue'
import { ColEx } from '/@/components/Form/src/types'
const colProps: Partial<ColEx> = {
xs: 24,
sm: 12,
md: 8,
lg: 6,
xl: 6,
xxl: 4,
}
const statusOptions = [
{
value: 0,
color: 'red',
label: '未处理',
},
{
value: 1,
color: 'green',
label: '已处理',
},
{
value: 2,
color: 'pink',
label: '已忽略',
},
]
export const columns: BasicColumn[] = [
{
title: 'ID',
dataIndex: 'id',
},
{
title: '内容',
dataIndex: 'content',
},
{
title: '等级',
dataIndex: 'lv',
width: 100,
},
{
title: '状态',
dataIndex: 'status',
width: 100,
customRender: ({ record }) => {
const status = record.status
const list = statusOptions
const item = list.find((e) => e.value === status)
const color = item?.color ?? 'red'
const text = item?.label ?? status
return h(Tag, { color: color }, () => text)
},
},
{
title: '开始时间',
dataIndex: 'created_at',
width: 180,
customRender: ({ text }) => {
if (!text) return ''
return dayjs.unix(text).format('YYYY-MM-DD HH:mm:ss')
},
},
{
width: 90,
title: '操作',
dataIndex: 'action',
align: 'center',
fixed: undefined,
},
]
export const searchFormSchema: FormSchema[] = [
{
field: 'status',
label: '状态',
component: 'Select',
componentProps: {
options: statusOptions,
},
colProps,
},
]

View File

@ -16,26 +16,42 @@
import { accountFormSchema } from './links.data' import { accountFormSchema } from './links.data'
import { BasicModal, useModalInner } from '/@/components/Modal' import { BasicModal, useModalInner } from '/@/components/Modal'
import { defaultsDeep } from 'lodash-es' import { defaultsDeep } from 'lodash-es'
import { createDevice, getDeviceTypes, updateDevice } from '/@/api/sys/other' import { createFriendinks, updateFriendinks } from '/@/api/sys/user'
const emits = defineEmits(['success', 'register'])
const isUpdate = ref(false) const isUpdate = ref(false)
const getTitle = computed(() => (!isUpdate.value ? '新增链接' : '编辑链接')) const getTitle = computed(() => (!isUpdate.value ? '新增链接' : '编辑链接'))
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({ const [registerForm, { resetFields, setFieldsValue, updateSchema, validate }] = useForm({
labelWidth: 60, labelWidth: 80,
baseColProps: { span: 24 }, baseColProps: { span: 24 },
schemas: accountFormSchema, schemas: accountFormSchema,
showActionButtonGroup: false, showActionButtonGroup: false,
}) })
const isTrueFalse = (e) => !!e
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => { const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields() resetFields()
setModalProps({ confirmLoading: false }) setModalProps({ confirmLoading: false })
isUpdate.value = data?.isUpdate isUpdate.value = data?.isUpdate
if (unref(isUpdate)) { if (unref(isUpdate)) {
const obj = Object.assign({}, { ...data, ...data?.extends }) const obj = Object.assign({}, { ...data, ...data?.extends })
const deviceTypes = await getDeviceTypes() updateSchema({
field: 'type',
dynamicDisabled: true,
})
console.log({
...obj,
agricultural_base_id: obj.base_id,
is_show: isTrueFalse(obj.is_show),
is_recommend: isTrueFalse(obj.is_recommend),
[`content${obj.type}`]: obj.type == 2 ? [obj.content] : obj.content,
})
await setFieldsValue({ await setFieldsValue({
...obj, ...obj,
agricultural_base_id: obj.base_id, agricultural_base_id: obj.base_id,
type: formatDataByObject(deviceTypes).find((e) => e.label == obj.type)?.value, is_show: isTrueFalse(obj.is_show),
is_recommend: isTrueFalse(obj.is_recommend),
[`content${obj.type}`]: obj.type == 2 ? [obj.content] : obj.content,
}) })
} }
}) })
@ -56,27 +72,30 @@
return object return object
} }
const handleSubmit = async () => { const handleSubmit = async () => {
const values = await validate() try {
console.log(values) const values = await validate()
let params: any = {}
for (const key in values) {
params = defaultsDeep({}, params, setValue(key.split('.'), values[key]))
}
if (params.type == 2) {
params.content = params.content2[0]
} else {
params.content = params[`content${params.type}`]
}
// try { setModalProps({ confirmLoading: true })
// const values = await validate() if (values.id) {
// let params = {} //
// for (const key in values) { await updateFriendinks(params)
// params = defaultsDeep({}, params, setValue(key.split('.'), values[key])) } else {
// } //
// setModalProps({ confirmLoading: true }) await createFriendinks(params)
// if (values.id) { }
// // closeModal()
// await updateDevice(values.id, params) emits('success')
// } else { } finally {
// // setModalProps({ confirmLoading: false })
// await createDevice(params) }
// }
// closeModal()
// emits('success')
// } finally {
// setModalProps({ confirmLoading: false })
// }
} }
</script> </script>

View File

@ -4,6 +4,25 @@
<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 v-if="column.key === 'action'">
<div class="flex items-center justify-center">
<TableAction
:actions="[
{ label: '编辑', onClick: handleEdit.bind(null, record) },
{
label: '删除',
popConfirm: {
title: '是否确认删除',
placement: 'topRight',
confirm: handleDelete.bind(null, record),
},
},
]"
/>
</div>
</template>
</template>
</BasicTable> </BasicTable>
<LinksDrawer @register="registerModal" @success="handleSuccess" /> <LinksDrawer @register="registerModal" @success="handleSuccess" />
@ -11,9 +30,9 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { BasicTable, useTable } from '/@/components/Table' import { BasicTable, useTable, TableAction } from '/@/components/Table'
import { reactive, toRefs } from 'vue' import { reactive, toRefs } from 'vue'
import { getFriendinks } from '/@/api/sys/user' import { getFriendinks, deleteFriendinks } from '/@/api/sys/user'
import { columns, searchFormSchema } from './links.data' import { columns, searchFormSchema } from './links.data'
import { useModal } from '/@/components/Modal' import { useModal } from '/@/components/Modal'
import LinksDrawer from './LinksDrawer.vue' import LinksDrawer from './LinksDrawer.vue'
@ -22,6 +41,7 @@
components: { components: {
BasicTable, BasicTable,
LinksDrawer, LinksDrawer,
TableAction,
}, },
setup() { setup() {
const state = reactive({}) const state = reactive({})
@ -58,7 +78,21 @@
}) })
} }
const handleEdit = (record: Recordable) => {
openModal(true, {
...record,
isUpdate: true,
})
}
const handleDelete = async (record: Recordable) => {
await deleteFriendinks(record.id)
message.success('删除成功')
reload()
}
return { return {
handleEdit,
handleDelete,
registerTable, registerTable,
registerModal, registerModal,
handleSuccess, handleSuccess,

View File

@ -1,5 +1,4 @@
import { BasicColumn } from '/@/components/Table' import { BasicColumn, FormSchema } from '/@/components/Table'
import { FormSchema } from '/@/components/Table'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { h } from 'vue' import { h } from 'vue'
import { Tag } from 'ant-design-vue' import { Tag } from 'ant-design-vue'
@ -40,12 +39,16 @@ export const columns: BasicColumn[] = [
{ {
title: '名称', title: '名称',
dataIndex: 'name', dataIndex: 'name',
},
{
title: '排序',
dataIndex: 'sort',
width: 100, width: 100,
}, },
{ {
title: '类型', title: '类型',
dataIndex: 'type', dataIndex: 'type',
width: 60, width: 100,
customRender: ({ record }) => { customRender: ({ record }) => {
const status = record.type const status = record.type
@ -59,7 +62,7 @@ export const columns: BasicColumn[] = [
{ {
title: '推荐', title: '推荐',
dataIndex: 'is_recommend', dataIndex: 'is_recommend',
width: 180, width: 100,
customRender: ({ record }) => { customRender: ({ record }) => {
if (!Reflect.has(record, 'pendingRecommendStatus')) { if (!Reflect.has(record, 'pendingRecommendStatus')) {
record.pendingRecommendStatus = false record.pendingRecommendStatus = false
@ -94,7 +97,7 @@ export const columns: BasicColumn[] = [
{ {
title: '状态', title: '状态',
dataIndex: 'is_show', dataIndex: 'is_show',
width: 180, width: 100,
customRender: ({ record }) => { customRender: ({ record }) => {
if (!Reflect.has(record, 'pendingShowStatus')) { if (!Reflect.has(record, 'pendingShowStatus')) {
record.pendingShowStatus = false record.pendingShowStatus = false
@ -135,6 +138,13 @@ export const columns: BasicColumn[] = [
return dayjs.unix(text).format('YYYY-MM-DD HH:mm:ss') return dayjs.unix(text).format('YYYY-MM-DD HH:mm:ss')
}, },
}, },
{
width: 180,
title: '操作',
dataIndex: 'action',
align: 'center',
fixed: undefined,
},
] ]
export const searchFormSchema: FormSchema[] = [ export const searchFormSchema: FormSchema[] = [
@ -171,6 +181,42 @@ export const accountFormSchema: FormSchema[] = [
return !!values.id return !!values.id
}, },
}, },
{
field: 'name',
label: '名称',
required: true,
component: 'Input',
},
{
field: 'sort',
label: '排序',
required: true,
defaultValue: 1,
component: 'InputNumber',
},
{
field: 'is_recommend',
label: '推荐',
required: true,
defaultValue: false,
component: 'Switch',
componentProps: {
checkedChildren: '是',
unCheckedChildren: '否',
},
},
{
field: 'is_show',
label: '状态',
required: true,
defaultValue: true,
componentProps: {
checkedChildren: '开启',
unCheckedChildren: '关闭',
},
component: 'Switch',
},
{ {
field: 'type', field: 'type',
label: '类型', label: '类型',
@ -182,7 +228,7 @@ export const accountFormSchema: FormSchema[] = [
}, },
}, },
{ {
field: 'content', field: 'content3',
label: '内容', label: '内容',
required: true, required: true,
component: 'Input', component: 'Input',
@ -199,14 +245,17 @@ export const accountFormSchema: FormSchema[] = [
}, },
}, },
{ {
field: 'content', field: 'content2',
label: '地址', label: '地址',
required: true, required: true,
component: 'Upload', component: 'Upload',
componentProps: { componentProps: {
maxSize: 10, maxSize: 30,
maxNumber: 1, maxNumber: 1,
showPreviewNumber: false, showPreviewNumber: false,
multiple: false,
emptyHidePreview: true,
accept: ['.mp4'],
api: uploadApi, api: uploadApi,
}, },
ifShow: ({ values }) => { ifShow: ({ values }) => {
@ -214,7 +263,7 @@ export const accountFormSchema: FormSchema[] = [
}, },
}, },
{ {
field: 'content', field: 'content1',
label: '地址', label: '地址',
required: true, required: true,
component: 'Input', component: 'Input',

View File

@ -1,7 +1,11 @@
import { BasicColumn } from '/@/components/Table' import { BasicColumn } from '/@/components/Table'
import { FormSchema } from '/@/components/Table' import { FormSchema } from '/@/components/Table'
import dayjs from 'dayjs' import dayjs from 'dayjs'
const options = [
{ label: '创建', value: 'create' },
{ label: '修改', value: 'update' },
{ label: '删除', value: 'delete' },
]
export const columns: BasicColumn[] = [ export const columns: BasicColumn[] = [
{ {
title: '操作人', title: '操作人',
@ -12,6 +16,9 @@ export const columns: BasicColumn[] = [
title: '动作', title: '动作',
dataIndex: 'type', dataIndex: 'type',
width: 180, width: 180,
customRender: ({ text }) => {
return options.find((e) => e.value == text)?.label
},
}, },
{ {
title: '详情', title: '详情',
@ -35,11 +42,7 @@ export const searchFormSchema: FormSchema[] = [
label: '动作', label: '动作',
component: 'Select', component: 'Select',
componentProps: { componentProps: {
options: [ options,
{ label: 'create', value: 'create' },
{ label: 'update', value: 'update' },
{ label: 'delete', value: 'delete' },
],
}, },
colProps: { span: 8 }, colProps: { span: 8 },
}, },

View File

@ -62,6 +62,7 @@
type: 'line', type: 'line',
smooth: false, smooth: false,
// symbol: 'none', // symbol: 'none',
stack: 'Total',
itemStyle: { itemStyle: {
color: color.itemColor, color: color.itemColor,
}, },

View File

@ -26,6 +26,7 @@
import { useVisualizationStore } from '/@/store/modules/visualization' import { useVisualizationStore } from '/@/store/modules/visualization'
import { chartBarColors } from './colors' import { chartBarColors } from './colors'
import { useVContext } from '../useVContext' import { useVContext } from '../useVContext'
import { add } from 'lodash-es'
export default defineComponent({ export default defineComponent({
components: { components: {
Box, Box,
@ -83,7 +84,6 @@
legendData: [] as any, legendData: [] as any,
series: [] as any, series: [] as any,
} }
Data.series.forEach(({ name, data, diffs }, index) => { Data.series.forEach(({ name, data, diffs }, index) => {
const color = chartBarColors[index % chartBarColors.length] const color = chartBarColors[index % chartBarColors.length]
obj.legendData.push(name) obj.legendData.push(name)
@ -146,7 +146,7 @@
if (item) { if (item) {
const min = item.data[e.dataIndex] ?? 0 const min = item.data[e.dataIndex] ?? 0
const diff = item.diffs[e.dataIndex] ?? 0 const diff = item.diffs[e.dataIndex] ?? 0
const sum = min + diff const sum = add(Number(min), Number(diff))
str += `${e.marker}<span style="width:50px;display: inline-block;">${e.seriesName}</span> ${min}-${sum}<br>` str += `${e.marker}<span style="width:50px;display: inline-block;">${e.seriesName}</span> ${min}-${sum}<br>`
} }
} }

View File

@ -66,7 +66,8 @@
import { getFriendLinks } from '/@/api/sys/other' import { getFriendLinks } from '/@/api/sys/other'
import { onBeforeMount, ref } from 'vue' import { onBeforeMount, ref } from 'vue'
import LinkModal from '../LinkModal.vue' import LinkModal from '../LinkModal.vue'
import { useVContext } from '../useVContext'
const { rootEmitter } = useVContext()
const getPopupContainer = (trigger) => { const getPopupContainer = (trigger) => {
return trigger.parentElement return trigger.parentElement
} }
@ -106,7 +107,7 @@
const find = _type.find((e) => e.type == item.type) const find = _type.find((e) => e.type == item.type)
return { return {
...acc, ...acc,
[find?.value ?? '其他']: [...(acc[item.type] ?? []), item], [find?.value ?? '其他']: [...(acc[find.value] ?? []), item],
} }
}, {}) }, {})
} }
@ -118,12 +119,15 @@
} else { } else {
visibleModal.value = true visibleModal.value = true
} }
console.log(e)
} }
onBeforeMount(() => { onBeforeMount(() => {
getDataF() getDataF()
getData() getData()
rootEmitter.on('interval:auto', () => {
getDataF()
getData()
})
}) })
</script> </script>

View File

@ -2,7 +2,7 @@
<ScaleScreen :boxStyle="{ background: '#020603' }" :width="3120" :height="760" :autoScale="true"> <ScaleScreen :boxStyle="{ background: '#020603' }" :width="3120" :height="760" :autoScale="true">
<!-- <div class="overflow-y-scroll"> --> <!-- <div class="overflow-y-scroll"> -->
<!-- w-3120px h-760px --> <!-- w-3120px h-760px -->
<div class="flex flex-col h-full bg-img relative"> <div class="flex flex-col h-full bg-img relative visualization—xx">
<canvas <canvas
class="absolute left-0 top-0 w-full h-full overflow-hidden" class="absolute left-0 top-0 w-full h-full overflow-hidden"
ref="cavsRef" ref="cavsRef"
@ -87,8 +87,12 @@
import { createVContext } from './useVContext' import { createVContext } from './useVContext'
import mitt from '/@/utils/mitt' import mitt from '/@/utils/mitt'
import Build from './components/cavas' import Build from './components/cavas'
import dayjs from 'dayjs'
import { getWarningLogs } from '/@/api/sys/user'
import { notification } from 'ant-design-vue'
// import Am from './components/Star' // import Am from './components/Star'
const initTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
localStorage.removeItem('warning_id')
export default defineComponent({ export default defineComponent({
components: { components: {
[Modal.name]: Modal, [Modal.name]: Modal,
@ -120,6 +124,40 @@
baseData: reactive({}), baseData: reactive({}),
}) })
async function getWarning() {
const ids = localStorage.getItem('warning_id')?.split(',') ?? []
const { data } = await getWarningLogs({ per_page: 10, page: 1, start_time: initTime })
const fliterData = data.filter((e) => ids.findIndex((id) => e.id == id) < 0)
const arr = ids.concat(
fliterData.reduce((p, c) => {
p.push(c.id)
return p
}, []),
)
localStorage.setItem('warning_id', arr.join(','))
fliterData.forEach((e, index) => {
openNotificationWithIcon(e.content, 4.5 + index * 0.5)
})
}
const openNotificationWithIcon = (message: string, duration = 4.5) => {
notification.warning({
message: '报警',
duration: duration,
class: 'warning-class',
style: {
backgroundColor: 'rgba(28, 44, 52, 0.8)',
color: '#fff',
},
getContainer: (): any => {
return document.body.querySelector(`.visualization—xx`)
},
description: message,
})
}
createVContext({ createVContext({
rootEmitter: vEmitter, rootEmitter: vEmitter,
}) })
@ -130,13 +168,18 @@
const visibleMapModal = ref<boolean>(false) const visibleMapModal = ref<boolean>(false)
onMounted(() => { onMounted(() => {
timer1 = setInterval(() => vEmitter.emit('interval:auto'), 1000 * 60) timer1 = setInterval(() => {
getWarning()
vEmitter.emit('interval:auto')
}, 1000 * 60)
timer2 = setInterval(() => vEmitter.emit('interval:tab'), 1000 * 30) timer2 = setInterval(() => vEmitter.emit('interval:tab'), 1000 * 30)
timer3 = setInterval(() => vEmitter.emit('interval:tab1'), 1000 * 10) timer3 = setInterval(() => vEmitter.emit('interval:tab1'), 1000 * 10)
new Build(cavsRef).run() new Build(cavsRef).run()
// Am(unref(cavsRef)) // Am(unref(cavsRef))
}) })
onBeforeMount(() => { onBeforeMount(() => {
getWarning()
vEmitter.on('map:click', () => { vEmitter.on('map:click', () => {
// visibleMapModal.value = true // visibleMapModal.value = true
}) })
@ -161,7 +204,15 @@
}, },
}) })
</script> </script>
<style lang="less">
.warning-class {
border: 1px solid #396684;
.ant-notification-notice-message {
color: #fff;
}
}
</style>
<style scoped lang="less"> <style scoped lang="less">
.bg-img { .bg-img {
// background-image: url('../../assets/images/map-bg.png') no-repeat; // background-image: url('../../assets/images/map-bg.png') no-repeat;