new-map
parent
50df3f3e1c
commit
e55f36133d
|
|
@ -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=
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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';
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,14 @@ const main: AppRouteModule = {
|
||||||
title: '设备管理',
|
title: '设备管理',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'warning',
|
||||||
|
name: 'DeviceWarning',
|
||||||
|
component: () => import('/@/views/device/warning/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '警报明细',
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
|
|
|
||||||
|
|
@ -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 },
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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>`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue