develop
ihzero 2023-10-25 02:49:05 +08:00
parent d79915a0f1
commit fb61e5fd2b
44 changed files with 778 additions and 206 deletions

View File

@ -6,7 +6,7 @@ VITE_PUBLIC_PATH = /
# Cross-domain proxy, you can configure multiple
# Please note that no line breaks
VITE_PROXY = [["/basic-api","http://lcny.sk797.cn"],["/upload","http://lcny.sk797.cn/api/web/upload"]]
VITE_PROXY = [["/basic-api","http://lcny.sk797.cn"],["/upload","http://lcny.sk797.cn/api/web/upload"],['/live','https://open.ys7.com']]
# Delete console
VITE_DROP_CONSOLE = false

View File

@ -51,6 +51,7 @@
"crypto-js": "^4.1.1",
"dayjs": "^1.11.1",
"echarts": "^5.3.2",
"ezuikit-js": "^7.7.6",
"flv.js": "^1.6.2",
"intro.js": "^5.1.0",
"lodash-es": "^4.17.21",
@ -66,6 +67,7 @@
"sortablejs": "^1.15.0",
"tinymce": "^5.10.3",
"vditor": "^3.8.13",
"video.js": "^8.6.0",
"vue": "^3.2.33",
"vue-i18n": "^9.1.9",
"vue-json-pretty": "^2.0.6",

View File

@ -2,40 +2,40 @@
* @description: Login interface parameters
*/
export interface LoginParams {
username: string;
password: string;
username: string
password: string
}
export interface RoleInfo {
roleName: string;
value: string;
roleName: string
value: string
}
/**
* @description: Login interface return value
*/
export interface LoginResultModel {
info: GetUserInfoModel;
token: string;
permissions: RoleInfo;
info: GetUserInfoModel
token: string
permissions: RoleInfo
}
/**
* @description: Get user information return value
*/
export interface GetUserInfoModel {
info: UserInfo;
permissions: RoleInfo[];
info: UserInfo
permissions_slug: string[]
}
export interface UserInfo {
id: string | number;
username: string;
name: string;
avatar: string;
created_at: string;
updated_at: string;
department: string;
phone: string | number;
status: string | number;
is_enable: string | number;
id: string | number
username: string
name: string
avatar: string
created_at: string
updated_at: string
department: string
phone: string | number
status: string | number
is_enable: string | number
}

View File

@ -214,7 +214,10 @@ export function getAgriculturalDeviceBasic(params, mode: ErrorMessageMode = 'non
return defHttp.get(
{
url: '/api/agricultural-device-basic',
params,
params: {
all: 1,
...params,
},
},
{
errorMessageMode: mode,
@ -417,12 +420,12 @@ export function updateRecommend(params, mode: ErrorMessageMode = 'none') {
)
}
/**
* @description:
* @description:
*/
export function devicePoints(type, mode: ErrorMessageMode = 'none') {
return defHttp.get(
{
url: `/api/agricultural-device-points?type=${type}`,
url: `/api/agricultural-device-points?type=${type}&all=1`,
},
{
errorMessageMode: mode,

View File

@ -0,0 +1,56 @@
<template>
<video ref="videoRefF" class="w-full h-full" autoplay controls muted></video>
</template>
<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount, unref } from 'vue'
import flvjs from 'flv.js'
const props = defineProps({
url: {
type: String,
default: '',
},
})
const videoRefF = ref<HTMLVideoElement | null>(null)
let player: any | null = null
onMounted(() => {
initVideo()
})
function initVideo() {
if (!props.url) return
if (flvjs.isSupported()) {
let videoElement: any = unref(videoRefF)
var flvPlayer = flvjs.createPlayer({
type: 'flv', // flv,
isLive: true, //
url: props.url, //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()
})
</script>
<style lang="less">
.vjs-loading-spinner {
.vjs-control-text {
display: none !important;
}
}
</style>

View File

@ -0,0 +1,30 @@
<template>
<div class="w-full h-full" v-if="!!url">
<M3u8 v-bind="getProps" :url="url" v-if="isM3u8" />
<Flv v-bind="getProps" :url="url" v-else />
</div>
</template>
<script setup lang="ts">
import { computed, unref } from 'vue'
import M3u8 from './m3up.vue'
import Flv from './flv.vue'
import { useAttrs } from '/@/hooks/core/useAttrs'
const props = defineProps({
url: {
type: String,
default: '',
},
})
const attrs = useAttrs()
const getProps = computed(() => {
return {
...unref(attrs),
...unref(props),
}
})
const isM3u8 = computed(() => {
return props.url.includes('.m3u8')
})
</script>

View File

@ -0,0 +1,59 @@
<template>
<video ref="videoRef" class="w-full h-full myvideo" autoplay controls></video>
</template>
<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import videojs, { VideoJsPlayer } from 'video.js'
import 'video.js/dist/video-js.css'
const props = defineProps({
url: {
type: String,
default: '',
},
})
const videoRef = ref<HTMLVideoElement | null>(null)
const videoPlayer: Ref<VideoJsPlayer | null> = ref(null)
onMounted(() => {
initVideo()
})
function initVideo() {
const url = props.url
if (url) {
videoPlayer.value = videojs(videoRef.value, {
controls: false,
autoplay: true,
muted: true,
width: '100%',
height: '100%',
sources: [{ src: url, type: 'application/x-mpegURL' }],
})
if (videoPlayer.value) {
videoPlayer.value.on('play', () => {})
}
}
}
onBeforeUnmount(() => {
if (videoPlayer.value) {
videoPlayer.value?.dispose()
}
})
</script>
<style lang="less">
.vjs-loading-spinner {
.vjs-control-text {
display: none !important;
}
}
.myvideo {
@apply w-full h-full;
video {
@apply w-full h-full;
}
}
</style>

View File

@ -67,11 +67,13 @@ export function usePermission() {
if ([PermissionModeEnum.ROUTE_MAPPING, PermissionModeEnum.ROLE].includes(permMode)) {
if (!isArray(value)) {
return userStore.getRoleList?.includes(value as RoleEnum)
return userStore.getPermissions?.includes(value as RoleEnum)
}
return (intersection(value, userStore.getRoleList) as RoleEnum[]).length > 0
return (intersection(value, userStore.getPermissions) as RoleEnum[]).length > 0
}
if (userStore.getRoleList.includes(RoleEnum.SUPER)) return true
if (PermissionModeEnum.BACK === permMode) {
const allCodeList = permissionStore.getPermCodeList as string[]
if (!isArray(value)) {

View File

@ -39,7 +39,7 @@
<Notify v-if="getShowNotice" :class="`${prefixCls}-action__item notify-item`" />
<div class="px-8px cursor-pointer">
<div class="px-8px cursor-pointer" v-auth="'endpoint.data_dashboard'">
<router-link to="/v">数据看板</router-link>
</div>

View File

@ -8,6 +8,7 @@ import { useUserStoreWithOut } from '/@/store/modules/user'
import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic'
import { RootRoute } from '/@/router/routes'
import { usePermission } from '/@/hooks/web/usePermission'
const LOGIN_PATH = PageEnum.BASE_LOGIN
@ -43,6 +44,7 @@ export function createPermissionGuard(router: Router) {
}
} catch {}
}
next()
return
}
@ -91,6 +93,13 @@ export function createPermissionGuard(router: Router) {
}
if (permissionStore.getIsDynamicAddedRoute) {
if (to.path === '/v') {
const { hasPermission } = usePermission()
if (!hasPermission('endpoint.data_dashboard')) {
return next({ path: '/', replace: true })
}
}
next()
return
}

View File

@ -27,8 +27,6 @@ export const router = createRouter({
// reset router
export function resetRouter() {
console.log('====')
router.getRoutes().forEach((route) => {
const { name } = route
if (name && !WHITE_NAME_LIST.includes(name as string)) {

View File

@ -15,6 +15,7 @@ const main: AppRouteModule = {
path: 'basics',
name: 'Basics',
meta: {
permission: ['admin'],
title: '全市基础数据',
// icon: 'ion:key-outline',
},
@ -25,6 +26,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/base/city-data/index.vue'),
meta: {
title: '城镇数据',
permission: 'endpoint.town_street.index',
},
},
{
@ -33,6 +35,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/base/base-data/index.vue'),
meta: {
title: '基地数据',
permission: 'endpoint.agricultural_basic.index',
},
},
],
@ -51,6 +54,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/base/crops/town-crops/index.vue'),
meta: {
title: '城镇农作物',
permission: 'endpoint.town_crops.index',
},
},
{
@ -59,6 +63,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/base/crops/base-crops/index.vue'),
meta: {
title: '基地农作物',
permission: 'endpoint.crops.index',
},
},
],
@ -77,6 +82,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/base/crop-yields/town-yields/index.vue'),
meta: {
title: '城镇产量',
permission: 'endpoint.town_crops_output.index',
},
},
{
@ -85,6 +91,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/base/crop-yields/base-yields/index.vue'),
meta: {
title: '基地产量',
permission: 'endpoint.crops_output.index',
},
},
],
@ -103,6 +110,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/base/estate/shrim-price/index.vue'),
meta: {
title: '稻虾价格',
permission: 'endpoint.rice_shrimp_prices.index',
},
},
{
@ -111,6 +119,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/base/estate/shrim-price/week.vue'),
meta: {
title: '稻虾每周价格',
permission: 'endpoint.rice_shrimp_weekly_prices.index',
},
},
{
@ -119,6 +128,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/base/estate/shrimp-industries/index.vue'),
meta: {
title: '稻虾产业',
permission: 'endpoint.rice_shrimp_industries.index',
},
},
{
@ -127,6 +137,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/base/estate/shrimp-flows/index.vue'),
meta: {
title: '稻虾流向',
permission: 'endpoint.rice_shrimp_flows.index',
},
},
{
@ -135,6 +146,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/base/estate/materiels/index.vue'),
meta: {
title: '大宗物资',
permission: 'endpoint.materiels.index',
},
},
],

View File

@ -17,6 +17,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/device/management/index.vue'),
meta: {
title: '设备管理',
permission: 'endpoint.device.index',
},
},
{
@ -25,6 +26,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/device/warning/index.vue'),
meta: {
title: '警报明细',
permission: 'endpoint.warnings.index',
},
},
],

View File

@ -17,6 +17,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/main/meteorological/index.vue'),
meta: {
title: '气象监测',
permission: 'endpoint.weather.index',
},
},
{
@ -25,6 +26,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/main/monitor/index.vue'),
meta: {
title: '智能监控',
permission: 'endpoint.camera.index',
},
},
{
@ -33,6 +35,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/main/soil-monitoring/index.vue'),
meta: {
title: '土壤监控',
permission: 'endpoint.soil.index',
},
},
{
@ -41,6 +44,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/main/water-quality/index.vue'),
meta: {
title: '水质监控',
permission: 'endpoint.water.index',
},
},
{
@ -49,6 +53,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/main/insect-monitors/index.vue'),
meta: {
title: '昆虫性诱监测',
permission: 'endpoint.insect.index',
},
},
{
@ -57,6 +62,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/main/pests/index.vue'),
meta: {
title: '虫情监测',
permission: 'endpoint.worm_statics.index',
},
},
{
@ -65,6 +71,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/main/insecticidal-lamp/index.vue'),
meta: {
title: '杀虫灯监测',
permission: 'endpoint.insecticidal_lamp.index',
},
},
],

View File

@ -17,6 +17,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/system/role/index.vue'),
meta: {
title: '角色管理',
permission: 'endpoint.admin_roles.index',
},
},
{
@ -25,6 +26,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/system/account/index.vue'),
meta: {
title: '账号管理',
permission: 'endpoint.admin_roles.index',
},
},
{
@ -33,6 +35,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/system/log/index.vue'),
meta: {
title: '系统日志',
permission: 'endpoint.operation_log.index',
},
},
{
@ -41,6 +44,7 @@ const main: AppRouteModule = {
component: () => import('/@/views/system/links/index.vue'),
meta: {
title: '友情链接',
permission: 'endpoint.friend_links.index',
},
},
],

View File

@ -23,6 +23,7 @@ import { getPermCode } from '/@/api/sys/user'
import { useMessage } from '/@/hooks/web/useMessage'
import { PageEnum } from '/@/enums/pageEnum'
import { RoleEnum } from '/@/enums/roleEnum'
interface PermissionState {
// Permission code list
@ -115,17 +116,21 @@ export const usePermissionStore = defineStore({
const appStore = useAppStoreWithOut()
let routes: AppRouteRecordRaw[] = []
const permissionList = toRaw(userStore.getPermissions) || []
const roleList = toRaw(userStore.getRoleList) || []
const { permissionMode = projectSetting.permissionMode } = appStore.getProjectConfig
// 路由过滤器 在 函数filter 作为回调传入遍历使用
const routeFilter = (route: AppRouteRecordRaw) => {
const { meta } = route
if (roleList.includes(RoleEnum.SUPER)) return true
// 抽出角色
const { roles } = meta || {}
if (!roles) return true
const { permission } = meta || {}
if (!permission) return false
// 进行角色权限判断
return roleList.some((role) => roles.includes(role))
return permissionList.some((e) => permission === e)
}
const routeRemoveIgnoreFilter = (route: AppRouteRecordRaw) => {
@ -184,8 +189,9 @@ export const usePermissionStore = defineStore({
case PermissionModeEnum.ROUTE_MAPPING:
// 对非一级路由进行过滤
routes = filter(asyncRoutes, routeFilter)
// 对一级路由再次根据角色权限过滤
routes = routes.filter(routeFilter)
// routes = routes.filter(routeFilter)
// 将路由转换成菜单
const menuList = transformRouteToMenu(routes, true)
// 移除掉 ignoreRoute: true 的路由 非一级路由

View File

@ -23,6 +23,7 @@ interface UserState {
roleList: RoleEnum[]
sessionTimeout?: boolean
lastUpdateTime: number
permissions: string[]
}
export const useUserStore = defineStore({
@ -38,6 +39,7 @@ export const useUserStore = defineStore({
sessionTimeout: false,
// Last fetch time
lastUpdateTime: 0,
permissions: [],
}),
getters: {
getUserInfo(): UserInfo {
@ -55,6 +57,9 @@ export const useUserStore = defineStore({
getLastUpdateTime(): number {
return this.lastUpdateTime
},
getPermissions(): string[] {
return this.permissions
},
},
actions: {
setToken(info: string | undefined) {
@ -65,6 +70,9 @@ export const useUserStore = defineStore({
this.roleList = roleList
setAuthCache(ROLES_KEY, roleList)
},
setPermissions(permissions: string[]) {
this.permissions = permissions
},
setUserInfo(info: UserInfo | null) {
this.userInfo = info
this.lastUpdateTime = new Date().getTime()
@ -125,15 +133,21 @@ export const useUserStore = defineStore({
},
async getUserInfoAction(): Promise<UserInfo | null> {
if (!this.getToken) return null
const { info, permissions }: GetUserInfoModel = await getUserInfo()
const userInfo: UserInfo = Object.assign({}, info, { roles: permissions })
const { roles = [] } = userInfo
if (isArray(roles)) {
const roleList = roles.map((item) => item.value) as RoleEnum[]
this.setRoleList(roleList)
const { info, permissions_slug }: GetUserInfoModel = await getUserInfo()
const userInfo: UserInfo = Object.assign({}, info, {
permissions: permissions_slug,
roles: [],
})
if (isArray(permissions_slug)) {
this.setPermissions(permissions_slug)
} else {
userInfo.roles = []
this.setRoleList([])
userInfo.permissions = []
this.setPermissions([])
}
if (userInfo.username === 'admin') {
this.setRoleList([RoleEnum.SUPER])
}
this.setUserInfo(userInfo)
return userInfo

View File

@ -2,16 +2,27 @@
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate"> </a-button>
<a-button
v-auth="'endpoint.agricultural_basic.create'"
type="primary"
@click="handleCreate"
>
新增基地
</a-button>
</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: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'endpoint.agricultural_basic.edit',
},
{
label: '删除',
auth: 'endpoint.agricultural_basic.destroy',
popConfirm: {
title: '是否确认删除',
placement: 'topRight',

View File

@ -2,9 +2,15 @@
<PageWrapper :contentStyle="{ margin: '16px 0' }">
<a-card title="全市数据统计" class="px-16px">
<template #extra>
<a-button size="small" @click="handleCensus"></a-button>
<a-button
v-auth="'endpoint.town_street.base_statistics_edit'"
size="small"
@click="handleCensus"
>编辑</a-button
>
</template>
<a-card-grid
v-auth="'endpoint.town_street.base_statistics'"
v-show="filterCityData.findIndex((e) => e === item.slug) < 0"
class="!md:w-1/3 !xl:w-1/7 !w-full !py-24px !px-10px"
v-for="(item, index) in CityDate"
@ -24,7 +30,11 @@
<div class="flex items-center justify-center">
<TableAction
:actions="[
{ label: '编辑', onClick: handleEdit.bind(null, record) },
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'endpoint.town_street.edit',
},
// {
// label: '',
// popConfirm: {

View File

@ -2,16 +2,23 @@
<div>
<BasicTable title="基地总产量" @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate"> </a-button>
<a-button type="primary" @click="handleCreate" v-auth="'endpoint.crops_output.create'">
新增
</a-button>
</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: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'endpoint.crops_output.edit',
},
{
label: '删除',
auth: 'endpoint.crops_output.destroy',
popConfirm: {
title: '是否确认删除',
placement: 'topRight',

View File

@ -2,16 +2,23 @@
<div>
<BasicTable title="城镇总产量" @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate"> </a-button>
<a-button type="primary" @click="handleCreate" v-auth="'endpoint.town_crops_output.create'">
新增
</a-button>
</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: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'endpoint.town_crops_output.edit',
},
{
label: '删除',
auth: 'endpoint.town_crops_output.destroy',
popConfirm: {
title: '是否确认删除',
placement: 'topRight',

View File

@ -2,16 +2,23 @@
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate"> </a-button>
<a-button type="primary" @click="handleCreate" v-auth="'endpoint.crops.create'">
新增农作物
</a-button>
</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: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'endpoint.crops.edit',
},
{
label: '删除',
auth: 'endpoint.crops.destroy',
popConfirm: {
title: '是否确认删除',
placement: 'topRight',

View File

@ -2,16 +2,23 @@
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate"> </a-button>
<a-button type="primary" @click="handleCreate" v-auth="'endpoint.town_crops.create'">
新增农作物
</a-button>
</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: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'endpoint.town_crops.edit',
},
{
label: '删除',
auth: 'endpoint.town_crops.destroy',
popConfirm: {
title: '是否确认删除',
placement: 'topRight',

View File

@ -2,16 +2,23 @@
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate"> </a-button>
<a-button type="primary" @click="handleCreate" v-auth="'endpoint.materiels.create'">
新增
</a-button>
</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: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'endpoint.materiels.edit',
},
{
label: '删除',
auth: 'endpoint.materiels.destroy',
popConfirm: {
title: '是否确认删除',
placement: 'topRight',

View File

@ -2,16 +2,27 @@
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate"> </a-button>
<a-button
type="primary"
@click="handleCreate"
v-auth="'endpoint.rice_shrimp_prices.create'"
>
新增
</a-button>
</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: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'endpoint.rice_shrimp_prices.edit',
},
{
label: '删除',
auth: 'endpoint.rice_shrimp_prices.destroy',
popConfirm: {
title: '是否确认删除',
placement: 'topRight',

View File

@ -2,16 +2,27 @@
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate"> </a-button>
<a-button
type="primary"
@click="handleCreate"
v-auth="'endpoint.rice_shrimp_weekly_prices.create'"
>
新增
</a-button>
</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: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'endpoint.rice_shrimp_weekly_prices.edit',
},
{
label: '删除',
auth: 'endpoint.rice_shrimp_weekly_prices.destroy',
popConfirm: {
title: '是否确认删除',
placement: 'topRight',

View File

@ -2,16 +2,23 @@
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate"> </a-button>
<a-button type="primary" @click="handleCreate" v-auth="'endpoint.rice_shrimp_flows.create'">
新增
</a-button>
</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: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'endpoint.rice_shrimp_flows.edit',
},
{
label: '删除',
auth: 'endpoint.rice_shrimp_flows.destroy',
popConfirm: {
title: '是否确认删除',
placement: 'topRight',

View File

@ -2,16 +2,27 @@
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate"> </a-button>
<a-button
type="primary"
@click="handleCreate"
v-auth="'endpoint.rice_shrimp_industries.create'"
>
新增
</a-button>
</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: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'endpoint.rice_shrimp_industries.edit',
},
{
label: '删除',
auth: 'endpoint.rice_shrimp_industries.destroy',
popConfirm: {
title: '是否确认删除',
placement: 'topRight',

View File

@ -2,16 +2,23 @@
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate"> </a-button>
<a-button type="primary" @click="handleCreate" v-auth="'endpoint.device.create'">
新增设备
</a-button>
</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: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'endpoint.device.edit',
},
{
label: '删除',
auth: 'endpoint.device.destroy',
popConfirm: {
title: '是否确认删除',
placement: 'topRight',

View File

@ -267,7 +267,7 @@ export const accountFormSchema: FormSchema[] = [
{
field: 'extends.ip',
label: '设备IP',
required: true,
required: false,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)
@ -276,7 +276,7 @@ export const accountFormSchema: FormSchema[] = [
{
field: 'extends.port',
label: '设备端口',
required: true,
required: false,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)
@ -285,7 +285,7 @@ export const accountFormSchema: FormSchema[] = [
{
field: 'extends.rtsp_url',
label: 'RTSP地址',
required: true,
required: false,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)
@ -295,7 +295,7 @@ export const accountFormSchema: FormSchema[] = [
{
field: 'extends.username',
label: '设备登录名',
required: true,
required: false,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)
@ -304,7 +304,7 @@ export const accountFormSchema: FormSchema[] = [
{
field: 'extends.password',
label: '设备登录密码',
required: true,
required: false,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)
@ -313,7 +313,7 @@ export const accountFormSchema: FormSchema[] = [
{
field: 'extends.passage',
label: '设备播放通道',
required: true,
required: false,
component: 'Input',
ifShow: ({ values }) => {
return !!(values.type == 1)

View File

@ -167,6 +167,7 @@
})
paginationParams.pageTotal = meta.total
list.value = data
// console.log(data)
}
onMounted(() => {

View File

@ -8,7 +8,8 @@
>推荐</div
>
<div class="absolute left-0 w-full top-0 h-full">
<video class="w-full h-full" autoplay controls ref="videoRef" muted></video>
<!-- <video class="w-full h-full" autoplay controls ref="videoRef" muted></video> -->
<LiveVideo v-if="liveUrl" class="w-full h-full" :url="liveUrl" />
</div>
</div>
</template>
@ -33,15 +34,17 @@
</template>
<script lang="ts">
import flvjs from 'flv.js'
import { Card, Switch, Tooltip } from 'ant-design-vue'
import { updateRecommend } from '/@/api/sys/other'
import { defineComponent, onMounted, ref, unref, onBeforeUnmount } from 'vue'
import { defineComponent, onMounted, ref, onBeforeUnmount, toRaw } from 'vue'
import LiveVideo from '/@/components/LiveVideo/index.vue'
import axios from 'axios'
export default defineComponent({
components: {
Card,
[Switch.name]: Switch,
Tooltip,
LiveVideo,
},
props: {
item: {
@ -57,35 +60,43 @@
},
},
setup(props) {
let player: any | null = null
const videoRef = ref<HTMLDivElement | null>(null)
const checked = ref<boolean>(props.item.is_recommend == 1)
function videoPlayer() {
const { item } = props
const url = item.extends.rtsp_url
const playUrl = `ws://${props.url}/rtsp?url=${window.btoa(url)}`
console.log(playUrl)
const liveUrl = ref<string>('')
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
async function getVideoUrl() {
const option = toRaw(props.item)
const { supplier, extends: extend, sn } = option
const url = extend.rtsp_url
let playUrl: any = `ws://${props.url}/rtsp?url=${window.btoa(url)}`
if (supplier?.id == 'device-supplier-biang') {
try {
playUrl = await getSeedingLive({
username: extend.username,
password: extend.password,
equipmentCode: sn,
channelNo: extend.passage,
})
} catch (error) {}
}
liveUrl.value = playUrl
}
function destroyVideos() {
if (!player) return
player?.pause()
player?.unload()
player?.detachMediaElement()
player?.destroy()
player = null
function getSeedingLive(params) {
return new Promise(async (resolve, reject) => {
try {
const { data } = await axios.get(
'https://yun.bigdata5s.com/api/open-api/open/getSeedingLive',
{
params,
},
)
if (data.code == 200) resolve(data.data)
else reject(data)
} catch (error) {
reject(error)
}
})
}
async function onChange(e) {
const is_recommend = e ? 1 : 0
@ -93,17 +104,14 @@
// eslint-disable-next-line vue/no-mutating-props
props.item.is_recommend = is_recommend
}
onBeforeUnmount(() => {
destroyVideos()
})
onMounted(() => {
videoPlayer()
getVideoUrl()
})
return {
videoRef,
checked,
onChange,
liveUrl,
data: props.item,
}
},

View File

@ -85,7 +85,7 @@
<template v-else>
<div class="flex justify-between">
<span class="text-xl">预警数据统计</span>
<Button @click="handleSetting"></Button>
<Button @click="handleSetting" v-auth="'endpoint.soil.setting'"></Button>
</div>
<div class="mt-20px md:flex enter-y flex-wrap -mr-4">
<EarlyWarningItem

View File

@ -85,7 +85,7 @@
<template v-else>
<div class="flex justify-between">
<span class="text-xl">预警数据统计</span>
<Button @click="handleSetting"></Button>
<Button v-auth="'endpoint.water.setting'" @click="handleSetting"></Button>
</div>
<div class="mt-20px md:flex enter-y flex-wrap -mr-4">
<EarlyWarningItem

View File

@ -37,6 +37,7 @@ export const columns: BasicColumn[] = [
title: '是否启用',
dataIndex: 'is_enable',
width: 180,
auth: 'endpoint.admin_users.enable',
customRender: ({ record }) => {
if (!Reflect.has(record, 'pendingStatus')) {
record.pendingStatus = false

View File

@ -2,17 +2,28 @@
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate"> </a-button>
<a-button type="primary" @click="handleCreate" v-auth="'endpoint.admin_users.create'">
新增账号
</a-button>
</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: '修改密码', onClick: handleEditpassword.bind(null, record) },
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'endpoint.admin_users.edit',
},
{
label: '修改密码',
onClick: handleEditpassword.bind(null, record),
auth: 'endpoint.admin_users.edit_password',
},
{
label: '删除',
auth: 'endpoint.admin_users.destroy',
popConfirm: {
title: '是否确认删除',
placement: 'topRight',

View File

@ -2,16 +2,23 @@
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate"> </a-button>
<a-button type="primary" @click="handleCreate" v-auth="'endpoint.friend_links.index'">
新增链接
</a-button>
</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: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'endpoint.friend_links.edit',
},
{
label: '删除',
auth: 'endpoint.friend_links.destroy',
popConfirm: {
title: '是否确认删除',
placement: 'topRight',

View File

@ -17,7 +17,9 @@
checkable
toolbar
title="菜单分配"
/>
>
<!-- <template #title="{ label, slug }"> {{ label }}{{ slug }} </template> -->
</BasicTree>
</template>
</BasicForm>
</BasicDrawer>
@ -46,6 +48,7 @@
if (unref(treeData).length === 0) {
// treeData.value = (await getPermissions()) as any as TreeItem[]
const res = await getPermissions()
treeData.value = res
}
isUpdate.value = data?.isUpdate

View File

@ -2,16 +2,23 @@
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate"> </a-button>
<a-button type="primary" @click="handleCreate" v-auth="'endpoint.admin_roles.create'">
新增角色
</a-button>
</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: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'endpoint.admin_roles.edit',
},
{
label: '删除',
auth: 'endpoint.admin_roles.destroy',
popConfirm: {
title: '是否确认删除',
placement: 'topRight',

View File

@ -37,7 +37,7 @@
class="h-130px"
:class="{ 'h-140px': isBase }"
v-for="(item, index) in listBig"
:key="index"
:key="item.url + index"
>
<VideoFlv
@onScreen="onScreenClick"
@ -69,7 +69,12 @@
>
<template #content>
<div class="w-full">
<VideoFlv :url="currentModelVideo.url" :screen="false" :name="currentModelVideo.name" />
<VideoFlv
v-if="currentModelVideo.url"
:url="currentModelVideo.url"
:screen="false"
:name="currentModelVideo.name"
/>
</div>
</template>
</LinkModal>
@ -84,6 +89,7 @@
onBeforeMount,
computed,
toRefs,
toRaw,
onBeforeUnmount,
} from 'vue'
import { DownOutlined } from '@ant-design/icons-vue'
@ -95,6 +101,7 @@
import v02 from '../../../assets/images/v02.png'
import v03 from '../../../assets/images/v03.png'
import LinkModal from '../LinkModal.vue'
import axios from 'axios'
export default defineComponent({
components: {
Box,
@ -155,25 +162,71 @@
status: 1,
is_recommend: 1,
})
Data.list = []
currentVido.value = null
Data.list = resData.splice(0, 4).map((e, index) => {
const { rtsp_url } = e.extends
const arr = resData.splice(0, 4)
const list: any = []
for (let index = 0; index < arr.length; index++) {
const e = arr[index]
const option = toRaw(e)
const { supplier, extends: extend, sn } = option
const { rtsp_url } = extend
const url = rtsp_url
// const url = 'rtsp://admin:admin12345@183.222.79.115:9007/cam/realmonitor?channel=1&subtype=0'
return {
...e,
img: index == 0 ? v01 : index == 1 ? v02 : index == 2 ? v03 : v01,
url: `ws://${ip}:${port}/rtsp?url=${window.btoa(url)}`,
let playUrl: any = `ws://${ip}:${port}/rtsp?url=${window.btoa(url)}`
if (supplier?.id == 'device-supplier-biang') {
try {
playUrl = await getSeedingLive({
username: extend.username,
password: extend.password,
equipmentCode: sn,
channelNo: extend.passage,
})
} catch (error) {}
}
})
list.push(
Object.assign(
{},
{
...e,
img: index == 0 ? v01 : index == 1 ? v02 : index == 2 ? v03 : v01,
url: playUrl,
},
),
)
}
Data.list = list
console.log(Data.list[0])
if (Data.list.length > 0) currentVido.value = Data.list[0]
if (!isBase.value) {
autoChage(change_time)
}
}
function getSeedingLive(params) {
return new Promise(async (resolve, reject) => {
try {
const { data } = await axios.get(
'https://yun.bigdata5s.com/api/open-api/open/getSeedingLive',
{
params,
},
)
if (data.code == 200) resolve(data.data)
else reject(data)
} catch (error) {
reject(error)
}
})
}
let timer: any = null
function autoChage(time) {

View File

@ -1,21 +1,18 @@
<template>
<div class="w-full h-full relative">
<video
class="w-full h-full bg-gray-700 bg-opacity-30"
autoplay
controls
ref="videoRef"
muted
></video>
<LiveVideo v-if="url" class="bg-gray-700 bg-opacity-30" :url="url" />
<div class="absolute left-0 w-full top-0 h-full" @click.prevent.stop="onScreen"></div>
</div>
</template>
<script lang="ts">
import flvjs from 'flv.js'
import { defineComponent, ref, unref, onMounted, watch, onBeforeUnmount, computed } from 'vue'
import { defineComponent, ref, computed } from 'vue'
import LiveVideo from '/@/components/LiveVideo/index.vue'
export default defineComponent({
name: 'VideoFlv',
components: {
LiveVideo,
},
props: {
url: {
type: String,
@ -31,34 +28,12 @@
},
},
setup(props, { emit }) {
const videoRef = ref<HTMLDivElement | null>(null)
let player: any | null = null
const pUrl = ref(props.url)
const pName = computed(() => props.name)
const isScreen = computed(() => props.screen)
function videoPlayer() {
if (!props.url) return
if (flvjs.isSupported()) {
let videoElement: any = unref(videoRef)
var flvPlayer = flvjs.createPlayer({
type: 'flv', // flv,
isLive: true, //
url: props.url, //url
})
flvPlayer.attachMediaElement(videoElement)
flvPlayer.load()
flvPlayer.play()
player = flvPlayer
}
}
onMounted(() => {
videoPlayer()
})
function onScreen() {
if (isScreen.value) {
emit('onScreen', { url: props.url, name: props.name })
@ -67,35 +42,11 @@
}
}
function destroyVideos() {
if (!player) return
player?.pause()
player?.unload()
player?.detachMediaElement()
player?.destroy()
player = null
}
onBeforeUnmount(() => {
destroyVideos()
})
watch(
() => props.url,
(e) => {
if (e) {
destroyVideos()
videoPlayer()
}
},
)
return {
pName,
onScreen,
isScreen,
pUrl,
videoRef,
}
},
})

57
types/store.d.ts vendored
View File

@ -1,52 +1,53 @@
import { ErrorTypeEnum } from '/@/enums/exceptionEnum';
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
import { RoleInfo } from '/@/api/sys/model/userModel';
import { ErrorTypeEnum } from '/@/enums/exceptionEnum'
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum'
import { RoleInfo } from '/@/api/sys/model/userModel'
// Lock screen information
export interface LockInfo {
// Password required
pwd?: string | undefined;
pwd?: string | undefined
// Is it locked?
isLock?: boolean;
isLock?: boolean
}
// Error-log information
export interface ErrorLogInfo {
// Type of error
type: ErrorTypeEnum;
type: ErrorTypeEnum
// Error file
file: string;
file: string
// Error name
name?: string;
name?: string
// Error message
message: string;
message: string
// Error stack
stack?: string;
stack?: string
// Error detail
detail: string;
detail: string
// Error url
url: string;
url: string
// Error time
time?: string;
time?: string
}
export interface UserInfo {
id: string | number;
username: string;
name: string;
avatar: string;
created_at: string;
updated_at: string;
department: string;
phone: string | number;
status: string | number;
is_enable: string | number;
roles: RoleInfo[];
id: string | number
username: string
name: string
avatar: string
created_at: string
updated_at: string
department: string
phone: string | number
status: string | number
is_enable: string | number
roles: RoleInfo[]
permissions: string[]
}
export interface BeforeMiniState {
menuCollapsed?: boolean;
menuSplit?: boolean;
menuMode?: MenuModeEnum;
menuType?: MenuTypeEnum;
menuCollapsed?: boolean
menuSplit?: boolean
menuMode?: MenuModeEnum
menuType?: MenuTypeEnum
}

View File

@ -53,7 +53,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
],
},
server: {
https: true,
https: false,
// Listening on all local IPs
host: true,
port: VITE_PORT,

222
yarn.lock
View File

@ -935,6 +935,13 @@
dependencies:
regenerator-runtime "^0.13.10"
"@babel/runtime@^7.12.5", "@babel/runtime@^7.5.5":
version "7.23.2"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885"
integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==
dependencies:
regenerator-runtime "^0.14.0"
"@babel/standalone@^7.17.11":
version "7.20.0"
resolved "https://registry.npmmirror.com/@babel/standalone/-/standalone-7.20.0.tgz"
@ -1912,6 +1919,47 @@
"@typescript-eslint/types" "5.42.0"
eslint-visitor-keys "^3.3.0"
"@videojs/http-streaming@3.6.0":
version "3.6.0"
resolved "https://registry.yarnpkg.com/@videojs/http-streaming/-/http-streaming-3.6.0.tgz#60a22cd021d42df2ce92438f401335486520c5db"
integrity sha512-dK98DFM7D3j8BIGVk6Htaw5A32ciPLDiKyMlcQaxVbxDzH7DtLpkldIRlf92No8lbh0u6VS0EF9q2vv0nDwkOg==
dependencies:
"@babel/runtime" "^7.12.5"
"@videojs/vhs-utils" "4.0.0"
aes-decrypter "4.0.1"
global "^4.4.0"
m3u8-parser "^7.1.0"
mpd-parser "^1.2.2"
mux.js "7.0.0"
video.js "^7 || ^8"
"@videojs/vhs-utils@4.0.0", "@videojs/vhs-utils@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@videojs/vhs-utils/-/vhs-utils-4.0.0.tgz#4d4dbf5d61a9fbd2da114b84ec747c3a483bc60d"
integrity sha512-xJp7Yd4jMLwje2vHCUmi8MOUU76nxiwII3z4Eg3Ucb+6rrkFVGosrXlMgGnaLjq724j3wzNElRZ71D/CKrTtxg==
dependencies:
"@babel/runtime" "^7.12.5"
global "^4.4.0"
url-toolkit "^2.2.1"
"@videojs/vhs-utils@^3.0.5":
version "3.0.5"
resolved "https://registry.yarnpkg.com/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz#665ba70d78258ba1ab977364e2fe9f4d4799c46c"
integrity sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==
dependencies:
"@babel/runtime" "^7.12.5"
global "^4.4.0"
url-toolkit "^2.2.1"
"@videojs/xhr@2.6.0":
version "2.6.0"
resolved "https://registry.yarnpkg.com/@videojs/xhr/-/xhr-2.6.0.tgz#cd897e0ad54faf497961bcce3fa16dc15a26bb80"
integrity sha512-7J361GiN1tXpm+gd0xz2QWr3xNWBE+rytvo8J3KuggFaLg+U37gZQ2BuPLcnkfGffy2e+ozY70RHC8jt7zjA6Q==
dependencies:
"@babel/runtime" "^7.5.5"
global "~4.4.0"
is-function "^1.0.1"
"@vitejs/plugin-legacy@^1.8.1":
version "1.8.2"
resolved "https://registry.npmmirror.com/@vitejs/plugin-legacy/-/plugin-legacy-1.8.2.tgz"
@ -2170,6 +2218,11 @@
micromatch "^4.0.5"
windicss "^3.5.6"
"@xmldom/xmldom@^0.8.3":
version "0.8.10"
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99"
integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==
"@zxcvbn-ts/core@^2.0.1":
version "2.1.0"
resolved "https://registry.npmmirror.com/@zxcvbn-ts/core/-/core-2.1.0.tgz"
@ -2213,6 +2266,16 @@ adler-32@~1.3.0:
resolved "https://registry.npmmirror.com/adler-32/-/adler-32-1.3.1.tgz"
integrity sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==
aes-decrypter@4.0.1, aes-decrypter@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/aes-decrypter/-/aes-decrypter-4.0.1.tgz#c1a81d0bde0e96fed0674488d2a31a6d7ab9b7a7"
integrity sha512-H1nh/P9VZXUf17AA5NQfJML88CFjVBDuGkp5zDHa7oEhYN9TTpNLJknRY1ie0iSKWlDf6JRnJKaZVDSQdPy6Cg==
dependencies:
"@babel/runtime" "^7.12.5"
"@videojs/vhs-utils" "^3.0.5"
global "^4.4.0"
pkcs7 "^1.0.4"
aggregate-error@^3.0.0:
version "3.1.0"
resolved "https://registry.npmmirror.com/aggregate-error/-/aggregate-error-3.1.0.tgz"
@ -3716,6 +3779,11 @@ dom-serializer@^2.0.0:
domhandler "^5.0.2"
entities "^4.2.0"
dom-walk@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==
domelementtype@1, domelementtype@^1.3.1:
version "1.3.1"
resolved "https://registry.npmmirror.com/domelementtype/-/domelementtype-1.3.1.tgz"
@ -4586,6 +4654,11 @@ extglob@^2.0.2:
snapdragon "^0.8.1"
to-regex "^3.0.1"
ezuikit-js@^7.7.6:
version "7.7.6"
resolved "https://registry.yarnpkg.com/ezuikit-js/-/ezuikit-js-7.7.6.tgz#28e7637d7e1517d23b3cf7c3235a1188d38edac2"
integrity sha512-eizB8ToIBumN7v69SII4poly1ppZGIGQPj9c8yYTmP7KGZpXnqrQAXcjYrN4PRjcI2U7jrJoRr1i4BNIofzYVg==
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
@ -5083,6 +5156,14 @@ global-prefix@^3.0.0:
kind-of "^6.0.2"
which "^1.3.1"
global@4.4.0, global@^4.3.1, global@^4.4.0, global@~4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406"
integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==
dependencies:
min-document "^2.19.0"
process "^0.11.10"
globals@^11.1.0:
version "11.12.0"
resolved "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz"
@ -5535,6 +5616,11 @@ indent-string@^4.0.0:
resolved "https://registry.npmmirror.com/indent-string/-/indent-string-4.0.0.tgz"
integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==
individual@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/individual/-/individual-2.0.0.tgz#833b097dad23294e76117a98fb38e0d9ad61bb97"
integrity sha512-pWt8hBCqJsUWI/HtcfWod7+N9SgAqyPEaF7JQjwzjn5vGrpg6aQ5qeAFQ7dx//UH4J1O+7xqew+gCeeFt6xN/g==
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz"
@ -5752,6 +5838,11 @@ is-fullwidth-code-point@^4.0.0:
resolved "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz"
integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==
is-function@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08"
integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==
is-gif@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/is-gif/-/is-gif-3.0.0.tgz"
@ -6138,6 +6229,11 @@ junk@^3.1.0:
resolved "https://registry.npmmirror.com/junk/-/junk-3.1.0.tgz"
integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==
keycode@2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.0.tgz#3d0af56dc7b8b8e5cba8d0a97f107204eec22b04"
integrity sha512-ps3I9jAdNtRpJrbBvQjpzyFbss/skHqzS+eu4RxKLaEAtFqkjZaB6TZMSivPbLxf4K7VI4SjR0P5mRCX5+Q25A==
keyv@3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/keyv/-/keyv-3.0.0.tgz"
@ -6428,6 +6524,24 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
m3u8-parser@^6.0.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/m3u8-parser/-/m3u8-parser-6.2.0.tgz#5b2f2fe103b76bd3ffc77c6b1eafc3772b1251dd"
integrity sha512-qlC00JTxYOxawcqg+RB8jbyNwL3foY/nCY61kyWP+RCuJE9APLeqB/nSlTjb4Mg0yRmyERgjswpdQxMvkeoDrg==
dependencies:
"@babel/runtime" "^7.12.5"
"@videojs/vhs-utils" "^3.0.5"
global "^4.4.0"
m3u8-parser@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/m3u8-parser/-/m3u8-parser-7.1.0.tgz#fa92ee22fc798150397c297152c879fe09f066c6"
integrity sha512-7N+pk79EH4oLKPEYdgRXgAsKDyA/VCo0qCHlUwacttQA0WqsjZQYmNfywMvjlY9MpEBVZEt0jKFd73Kv15EBYQ==
dependencies:
"@babel/runtime" "^7.12.5"
"@videojs/vhs-utils" "^3.0.5"
global "^4.4.0"
magic-string@^0.25.0, magic-string@^0.25.7:
version "0.25.9"
resolved "https://registry.npmmirror.com/magic-string/-/magic-string-0.25.9.tgz"
@ -6621,6 +6735,13 @@ mimic-response@^1.0.0:
resolved "https://registry.npmmirror.com/mimic-response/-/mimic-response-1.0.1.tgz"
integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
min-document@^2.19.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==
dependencies:
dom-walk "^0.1.0"
min-indent@^1.0.0:
version "1.0.1"
resolved "https://registry.npmmirror.com/min-indent/-/min-indent-1.0.1.tgz"
@ -6687,6 +6808,16 @@ mozjpeg@^7.0.0:
bin-build "^3.0.0"
bin-wrapper "^4.0.0"
mpd-parser@^1.0.1, mpd-parser@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/mpd-parser/-/mpd-parser-1.2.2.tgz#bf479cbb0bec605130075c0e904a853b29265973"
integrity sha512-QCfB1koOoZw6E5La1cx+W/Yd0EZlRhHMqMr4TAJez0eRTuPDzPM5FWoiOqjyo37W+ISPLzmfJACSbJFEBjbL4Q==
dependencies:
"@babel/runtime" "^7.12.5"
"@videojs/vhs-utils" "^3.0.5"
"@xmldom/xmldom" "^0.8.3"
global "^4.4.0"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz"
@ -6707,6 +6838,22 @@ mute-stream@0.0.8:
resolved "https://registry.npmmirror.com/mute-stream/-/mute-stream-0.0.8.tgz"
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
mux.js@7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/mux.js/-/mux.js-7.0.0.tgz#f5f80cd63bc5eaf13ba2e8b3396d4dd03a8aa1f2"
integrity sha512-DeZmr+3NDrO02k4SREtl4VB5GyGPCz2fzMjDxBIlamkxffSTLge97rtNMoonnmFHTp96QggDucUtKv3fmyObrA==
dependencies:
"@babel/runtime" "^7.11.2"
global "^4.4.0"
mux.js@^6.2.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/mux.js/-/mux.js-6.3.0.tgz#b0a46bc468402f7ce2be4e0f87ce903f8683bfeb"
integrity sha512-/QTkbSAP2+w1nxV+qTcumSDN5PA98P0tjrADijIzQHe85oBK3Akhy9AHlH0ne/GombLMz1rLyvVsmrgRxoPDrQ==
dependencies:
"@babel/runtime" "^7.11.2"
global "^4.4.0"
nanoid@^3.3.4:
version "3.3.4"
resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.4.tgz"
@ -7339,6 +7486,13 @@ pinkie@^2.0.0:
resolved "https://registry.npmmirror.com/pinkie/-/pinkie-2.0.4.tgz"
integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==
pkcs7@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/pkcs7/-/pkcs7-1.0.4.tgz#6090b9e71160dabf69209d719cbafa538b00a1cb"
integrity sha512-afRERtHn54AlwaF2/+LFszyAANTCggGilmcmILUzEjvs3XgFZT+xE6+QWQcAGmu4xajy+Xtj7acLOPdx5/eXWQ==
dependencies:
"@babel/runtime" "^7.5.5"
pngjs@^5.0.0:
version "5.0.0"
resolved "https://registry.npmmirror.com/pngjs/-/pngjs-5.0.0.tgz"
@ -7515,6 +7669,11 @@ process-nextick-args@~2.0.0:
resolved "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz"
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
process@^0.11.10:
version "0.11.10"
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
proto-list@~1.2.1:
version "1.2.4"
resolved "https://registry.npmmirror.com/proto-list/-/proto-list-1.2.4.tgz"
@ -7736,6 +7895,11 @@ regenerator-runtime@^0.13.10, regenerator-runtime@^0.13.9:
resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz"
integrity sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==
regenerator-runtime@^0.14.0:
version "0.14.0"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==
regenerator-transform@^0.15.0:
version "0.15.0"
resolved "https://registry.npmmirror.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz"
@ -7957,6 +8121,13 @@ run-parallel@^1.1.9:
dependencies:
queue-microtask "^1.2.2"
rust-result@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/rust-result/-/rust-result-1.0.0.tgz#34c75b2e6dc39fe5875e5bdec85b5e0f91536f72"
integrity sha512-6cJzSBU+J/RJCF063onnQf0cDUOHs9uZI1oroSGnHOph+CQTIJ5Pp2hK5kEQq1+7yE/EEWfulSNXAQ2jikPthA==
dependencies:
individual "^2.0.0"
rxjs@^7.5.5:
version "7.5.7"
resolved "https://registry.npmmirror.com/rxjs/-/rxjs-7.5.7.tgz"
@ -7974,6 +8145,13 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1:
resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safe-json-parse@4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/safe-json-parse/-/safe-json-parse-4.0.0.tgz#7c0f578cfccd12d33a71c0e05413e2eca171eaac"
integrity sha512-RjZPPHugjK0TOzFrLZ8inw44s9bKox99/0AZW9o/BEQVrJfhI+fIHMErnPyRa89/yRXUUr93q+tiN6zhoVV4wQ==
dependencies:
rust-result "^1.0.0"
safe-regex-test@^1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz"
@ -9172,6 +9350,11 @@ url-to-options@^1.0.1:
resolved "https://registry.npmmirror.com/url-to-options/-/url-to-options-1.0.1.tgz"
integrity sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==
url-toolkit@^2.2.1:
version "2.2.5"
resolved "https://registry.yarnpkg.com/url-toolkit/-/url-toolkit-2.2.5.tgz#58406b18e12c58803e14624df5e374f638b0f607"
integrity sha512-mtN6xk+Nac+oyJ/PrI7tzfmomRVNFIWKUbG8jdYFt52hxbiReFAXIjYskvu64/dvuW71IcB7lV8l0HvZMac6Jg==
use@^3.1.0:
version "3.1.1"
resolved "https://registry.npmmirror.com/use/-/use-3.1.1.tgz"
@ -9222,6 +9405,45 @@ vditor@^3.8.13:
dependencies:
diff-match-patch "^1.0.5"
"video.js@^7 || ^8", video.js@^8.6.0:
version "8.6.0"
resolved "https://registry.yarnpkg.com/video.js/-/video.js-8.6.0.tgz#3ed095edee8db2dceaa11e915c6c20de241d9261"
integrity sha512-uoX0Me0UyJuW3cB8IT0VLpEim5HwUutrXTxuQqYxPeahVr5EfFOP2IjUAlnvACpb6eA/pbmO6d4TpZXuXD+blQ==
dependencies:
"@babel/runtime" "^7.12.5"
"@videojs/http-streaming" "3.6.0"
"@videojs/vhs-utils" "^4.0.0"
"@videojs/xhr" "2.6.0"
aes-decrypter "^4.0.1"
global "4.4.0"
keycode "2.2.0"
m3u8-parser "^6.0.0"
mpd-parser "^1.0.1"
mux.js "^6.2.0"
safe-json-parse "4.0.0"
videojs-contrib-quality-levels "4.0.0"
videojs-font "4.1.0"
videojs-vtt.js "0.15.5"
videojs-contrib-quality-levels@4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/videojs-contrib-quality-levels/-/videojs-contrib-quality-levels-4.0.0.tgz#faa8096594cdbfc3ccbefe8572fc20531ba23f3d"
integrity sha512-u5rmd8BjLwANp7XwuQ0Q/me34bMe6zg9PQdHfTS7aXgiVRbNTb4djcmfG7aeSrkpZjg+XCLezFNenlJaCjBHKw==
dependencies:
global "^4.4.0"
videojs-font@4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/videojs-font/-/videojs-font-4.1.0.tgz#3ae1dbaac60b4f0f1c4e6f7ff9662a89df176015"
integrity sha512-X1LuPfLZPisPLrANIAKCknZbZu5obVM/ylfd1CN+SsCmPZQ3UMDPcvLTpPBJxcBuTpHQq2MO1QCFt7p8spnZ/w==
videojs-vtt.js@0.15.5:
version "0.15.5"
resolved "https://registry.yarnpkg.com/videojs-vtt.js/-/videojs-vtt.js-0.15.5.tgz#567776eaf2a7a928d88b148a8b401ade2406f2ca"
integrity sha512-yZbBxvA7QMYn15Lr/ZfhhLPrNpI/RmCSCqgIff57GC2gIrV5YfyzLfLyZMj0NnZSAz8syB4N0nHXpZg9MyrMOQ==
dependencies:
global "^4.3.1"
vite-plugin-compression@^0.5.1:
version "0.5.1"
resolved "https://registry.npmmirror.com/vite-plugin-compression/-/vite-plugin-compression-0.5.1.tgz"