外链接编辑
parent
5b11df84cd
commit
2827fcc182
|
|
@ -811,3 +811,47 @@ export function editDeviceWarningRules(params, mode: ErrorMessageMode = 'modal')
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @description:操作日志
|
||||||
|
*/
|
||||||
|
export function getLogs(params, mode: ErrorMessageMode = 'modal') {
|
||||||
|
return defHttp.get(
|
||||||
|
{
|
||||||
|
url: `/api/operation-logs`,
|
||||||
|
params,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
errorMessageMode: mode,
|
||||||
|
isTransformResponse: false,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @description:友情链接列表
|
||||||
|
*/
|
||||||
|
export function getFriendinks(params, mode: ErrorMessageMode = 'modal') {
|
||||||
|
return defHttp.get(
|
||||||
|
{
|
||||||
|
url: `/api/friend-links`,
|
||||||
|
params,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
errorMessageMode: mode,
|
||||||
|
isTransformResponse: false,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @description:修改友情链接
|
||||||
|
*/
|
||||||
|
export function updateFriendinks(params, mode: ErrorMessageMode = 'modal') {
|
||||||
|
return defHttp.put(
|
||||||
|
{
|
||||||
|
url: `/api/friend-links/${params.id}`,
|
||||||
|
params,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
errorMessageMode: mode,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,22 @@ const main: AppRouteModule = {
|
||||||
title: '账号管理',
|
title: '账号管理',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'log',
|
||||||
|
name: 'SystemLog',
|
||||||
|
component: () => import('/@/views/system/log/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '系统日志',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'links',
|
||||||
|
name: 'SystemLinks',
|
||||||
|
component: () => import('/@/views/system/links/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '友情链接',
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,15 @@ export const columns: BasicColumn[] = [
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
export const searchFormSchema: FormSchema[] = []
|
export const searchFormSchema: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 'name',
|
||||||
|
label: '名称',
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {},
|
||||||
|
colProps: { span: 6 },
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
export const accountFormSchema: FormSchema[] = [
|
export const accountFormSchema: FormSchema[] = [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@
|
||||||
labelWidth: 120,
|
labelWidth: 120,
|
||||||
schemas: searchFormSchema,
|
schemas: searchFormSchema,
|
||||||
},
|
},
|
||||||
useSearchForm: false,
|
useSearchForm: true,
|
||||||
showTableSetting: true,
|
showTableSetting: true,
|
||||||
bordered: true,
|
bordered: true,
|
||||||
showIndexColumn: true,
|
showIndexColumn: true,
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@
|
||||||
labelWidth: 120,
|
labelWidth: 120,
|
||||||
schemas: searchFormSchema,
|
schemas: searchFormSchema,
|
||||||
},
|
},
|
||||||
useSearchForm: false,
|
useSearchForm: true,
|
||||||
showTableSetting: true,
|
showTableSetting: true,
|
||||||
bordered: true,
|
bordered: true,
|
||||||
showIndexColumn: true,
|
showIndexColumn: true,
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,15 @@ export const columns: BasicColumn[] = [
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
export const searchFormSchema: FormSchema[] = []
|
export const searchFormSchema: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 'name',
|
||||||
|
label: '名称',
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {},
|
||||||
|
colProps: { span: 6 },
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
export const accountFormSchema: FormSchema[] = [
|
export const accountFormSchema: FormSchema[] = [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
<Card :hoverable="true" class="card">
|
<Card :hoverable="true" class="card">
|
||||||
<template #cover>
|
<template #cover>
|
||||||
<div class="bg-gray-200 pt-220/386 relative">
|
<div class="bg-gray-200 pt-220/386 relative">
|
||||||
<div class="absolute left-0 w-full top-0 h-full"> </div>
|
<div class="absolute left-0 w-full top-0 h-full">
|
||||||
|
<video class="w-full h-full" autoplay controls ref="videoRef" muted></video>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="">{{ item.base_name }} </div>
|
<div class="">{{ item.base_name }} </div>
|
||||||
|
|
@ -10,8 +12,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import flvjs from 'flv.js'
|
||||||
import { Card } from 'ant-design-vue'
|
import { Card } from 'ant-design-vue'
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent, onMounted, ref, unref, onBeforeUnmount } from 'vue'
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
Card,
|
Card,
|
||||||
|
|
@ -23,7 +26,47 @@
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
|
let player: any | null = null
|
||||||
|
|
||||||
|
const videoRef = ref<HTMLDivElement | null>(null)
|
||||||
|
|
||||||
|
function videoPlayer() {
|
||||||
|
const { item } = props
|
||||||
|
// const { username, passage, ip, port, rtsp_url } = item.extends
|
||||||
|
// const url = `rtsp://${username}:${passage}@${ip}:${port}${rtsp_url}`
|
||||||
|
const url =
|
||||||
|
'rtsp://admin:admin12345@183.222.79.115:9007/cam/realmonitor?channel=1&subtype=0'
|
||||||
|
const playUrl = `ws://127.0.0.1:8100/rtsp?url=${window.btoa(url)}`
|
||||||
|
if (flvjs.isSupported()) {
|
||||||
|
let videoElement: any = unref(videoRef)
|
||||||
|
var flvPlayer = flvjs.createPlayer({
|
||||||
|
type: 'flv', // 媒体类型,默认是 flv,
|
||||||
|
isLive: true, // 是否是直播流
|
||||||
|
url: playUrl, //你的url地址
|
||||||
|
})
|
||||||
|
flvPlayer.attachMediaElement(videoElement)
|
||||||
|
flvPlayer.load()
|
||||||
|
flvPlayer.play()
|
||||||
|
player = flvPlayer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function destroyVideos() {
|
||||||
|
if (!player) return
|
||||||
|
player?.pause()
|
||||||
|
player?.unload()
|
||||||
|
player?.detachMediaElement()
|
||||||
|
player?.destroy()
|
||||||
|
player = null
|
||||||
|
}
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
destroyVideos()
|
||||||
|
})
|
||||||
|
onMounted(() => {
|
||||||
|
videoPlayer()
|
||||||
|
})
|
||||||
return {
|
return {
|
||||||
|
videoRef,
|
||||||
data: props.item,
|
data: props.item,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
<template>
|
||||||
|
<div> <BasicTable @register="registerTable" /> </div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { BasicTable, useTable } from '/@/components/Table'
|
||||||
|
import { reactive, toRefs } from 'vue'
|
||||||
|
import { getFriendinks } from '/@/api/sys/user'
|
||||||
|
import { columns, searchFormSchema } from './links.data'
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
BasicTable,
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
const state = reactive({})
|
||||||
|
|
||||||
|
const [registerTable, { reload }] = useTable({
|
||||||
|
title: '账号列表',
|
||||||
|
api: async (e) => {
|
||||||
|
const { data, meta } = await getFriendinks({ ...e })
|
||||||
|
return {
|
||||||
|
items: data,
|
||||||
|
total: meta?.total,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rowKey: 'id',
|
||||||
|
columns,
|
||||||
|
formConfig: {
|
||||||
|
labelWidth: 120,
|
||||||
|
schemas: searchFormSchema,
|
||||||
|
},
|
||||||
|
useSearchForm: true,
|
||||||
|
showTableSetting: true,
|
||||||
|
bordered: true,
|
||||||
|
showIndexColumn: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
registerTable,
|
||||||
|
...toRefs(state),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
import { BasicColumn } from '/@/components/Table'
|
||||||
|
import { FormSchema } from '/@/components/Table'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import { h } from 'vue'
|
||||||
|
import { Tag } from 'ant-design-vue'
|
||||||
|
import { Switch } from 'ant-design-vue'
|
||||||
|
import { useMessage } from '/@/hooks/web/useMessage'
|
||||||
|
import { updateFriendinks } from '/@/api/sys/user'
|
||||||
|
|
||||||
|
export const columns: BasicColumn[] = [
|
||||||
|
{
|
||||||
|
title: '名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '类型',
|
||||||
|
dataIndex: 'type',
|
||||||
|
width: 60,
|
||||||
|
customRender: ({ record }) => {
|
||||||
|
const status = record.type
|
||||||
|
|
||||||
|
const list = [
|
||||||
|
{
|
||||||
|
value: 1,
|
||||||
|
color: 'red',
|
||||||
|
label: '链接',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 2,
|
||||||
|
color: 'green',
|
||||||
|
label: '视频',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 3,
|
||||||
|
color: 'pink',
|
||||||
|
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)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '推荐',
|
||||||
|
dataIndex: 'is_recommend',
|
||||||
|
width: 180,
|
||||||
|
customRender: ({ record }) => {
|
||||||
|
if (!Reflect.has(record, 'pendingRecommendStatus')) {
|
||||||
|
record.pendingRecommendStatus = false
|
||||||
|
}
|
||||||
|
return h(Switch, {
|
||||||
|
checked: record.is_recommend === 1,
|
||||||
|
checkedChildren: '是',
|
||||||
|
unCheckedChildren: '否',
|
||||||
|
loading: record.pendingRecommendStatus,
|
||||||
|
onChange(checked: boolean) {
|
||||||
|
record.pendingRecommendStatus = true
|
||||||
|
const newStatus = checked ? 1 : 0
|
||||||
|
const { createMessage } = useMessage()
|
||||||
|
updateFriendinks({
|
||||||
|
id: record.id,
|
||||||
|
is_recommend: !checked,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
record.is_recommend = newStatus
|
||||||
|
createMessage.success(`已成功设置推荐`)
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
createMessage.error('修改推荐失败')
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
record.pendingRecommendStatusx = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '开启',
|
||||||
|
dataIndex: 'is_show',
|
||||||
|
width: 180,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'created_at',
|
||||||
|
width: 180,
|
||||||
|
customRender: ({ text }) => {
|
||||||
|
if (!text) return ''
|
||||||
|
return dayjs.unix(text).format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export const searchFormSchema: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 'type',
|
||||||
|
label: '动作',
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ label: 'create', value: 'create' },
|
||||||
|
{ label: 'update', value: 'update' },
|
||||||
|
{ label: 'delete', value: 'delete' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
colProps: { span: 6 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: '[start_time, end_time]',
|
||||||
|
label: '时间范围',
|
||||||
|
component: 'RangePicker',
|
||||||
|
componentProps: {
|
||||||
|
format: 'YYYY-MM-DD',
|
||||||
|
placeholder: ['开始时间', '结束时间'],
|
||||||
|
},
|
||||||
|
colProps: { span: 6 },
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
<template>
|
||||||
|
<div> <BasicTable @register="registerTable" /> </div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { BasicTable, useTable } from '/@/components/Table'
|
||||||
|
import { reactive, toRefs } from 'vue'
|
||||||
|
import { getLogs } from '/@/api/sys/user'
|
||||||
|
import { columns, searchFormSchema } from './log.data'
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
BasicTable,
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
const state = reactive({})
|
||||||
|
|
||||||
|
const [registerTable, { reload }] = useTable({
|
||||||
|
title: '账号列表',
|
||||||
|
api: async (e) => {
|
||||||
|
const { data, meta } = await getLogs({ ...e })
|
||||||
|
return {
|
||||||
|
items: data,
|
||||||
|
total: meta?.total,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rowKey: 'id',
|
||||||
|
columns,
|
||||||
|
formConfig: {
|
||||||
|
labelWidth: 120,
|
||||||
|
schemas: searchFormSchema,
|
||||||
|
},
|
||||||
|
useSearchForm: true,
|
||||||
|
showTableSetting: true,
|
||||||
|
bordered: true,
|
||||||
|
showIndexColumn: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
registerTable,
|
||||||
|
...toRefs(state),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
import { BasicColumn } from '/@/components/Table'
|
||||||
|
import { FormSchema } from '/@/components/Table'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
|
export const columns: BasicColumn[] = [
|
||||||
|
{
|
||||||
|
title: '操作人',
|
||||||
|
dataIndex: 'user_name',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '动作',
|
||||||
|
dataIndex: 'type',
|
||||||
|
width: 180,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '详情',
|
||||||
|
dataIndex: 'message',
|
||||||
|
width: 180,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '时间',
|
||||||
|
dataIndex: 'created_at',
|
||||||
|
width: 180,
|
||||||
|
customRender: ({ text }) => {
|
||||||
|
if (!text) return ''
|
||||||
|
return dayjs.unix(text).format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export const searchFormSchema: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 'type',
|
||||||
|
label: '动作',
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ label: 'create', value: 'create' },
|
||||||
|
{ label: 'update', value: 'update' },
|
||||||
|
{ label: 'delete', value: 'delete' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
colProps: { span: 6 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: '[start_time, end_time]',
|
||||||
|
label: '时间范围',
|
||||||
|
component: 'RangePicker',
|
||||||
|
componentProps: {
|
||||||
|
format: 'YYYY-MM-DD',
|
||||||
|
placeholder: ['开始时间', '结束时间'],
|
||||||
|
},
|
||||||
|
colProps: { span: 6 },
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'ph',
|
key: 'ph',
|
||||||
unit: null,
|
unit: 'PH',
|
||||||
name: 'PH值',
|
name: 'PH值',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -263,6 +263,7 @@
|
||||||
name: currentMenuObj.value?.unit ?? '',
|
name: currentMenuObj.value?.unit ?? '',
|
||||||
nameTextStyle: {
|
nameTextStyle: {
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
|
align: 'left',
|
||||||
},
|
},
|
||||||
axisTick: {
|
axisTick: {
|
||||||
show: false,
|
show: false,
|
||||||
|
|
|
||||||
|
|
@ -259,6 +259,7 @@
|
||||||
name: currentMenuObj.value?.unit ?? '',
|
name: currentMenuObj.value?.unit ?? '',
|
||||||
nameTextStyle: {
|
nameTextStyle: {
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
|
align: 'left',
|
||||||
},
|
},
|
||||||
axisTick: {
|
axisTick: {
|
||||||
show: false,
|
show: false,
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,6 @@
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
console.log(props)
|
|
||||||
|
|
||||||
const videoRef = ref<HTMLDivElement | null>(null)
|
const videoRef = ref<HTMLDivElement | null>(null)
|
||||||
let player: any | null = null
|
let player: any | null = null
|
||||||
const pUrl = ref(props.url)
|
const pUrl = ref(props.url)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue