feat: 项目新建
@ -0,0 +1,12 @@
|
||||
###
|
||||
# @Author: donghao donghao@supervision.ltd
|
||||
# @Date: 2025-03-12 15:26:57
|
||||
# @LastEditors: donghao donghao@supervision.ltd
|
||||
# @LastEditTime: 2025-03-13 09:17:19
|
||||
# @FilePath: \5G-Loading-Bay-Web\.env.development
|
||||
# @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
###
|
||||
# .env.development
|
||||
NODE_ENV = development
|
||||
VITE_APP_ENV = development
|
||||
VITE_APP_BASE_API = http://192.168.10.14:8000
|
@ -0,0 +1,4 @@
|
||||
# .env.production
|
||||
NODE_ENV = production
|
||||
VITE_APP_ENV = production
|
||||
VITE_APP_BASE_API = http://127.0.0.1:8000
|
@ -0,0 +1,74 @@
|
||||
{
|
||||
"globals": {
|
||||
"Component": true,
|
||||
"ComponentPublicInstance": true,
|
||||
"ComputedRef": true,
|
||||
"DirectiveBinding": true,
|
||||
"EffectScope": true,
|
||||
"ExtractDefaultPropTypes": true,
|
||||
"ExtractPropTypes": true,
|
||||
"ExtractPublicPropTypes": true,
|
||||
"InjectionKey": true,
|
||||
"MaybeRef": true,
|
||||
"MaybeRefOrGetter": true,
|
||||
"PropType": true,
|
||||
"Ref": true,
|
||||
"VNode": true,
|
||||
"WritableComputedRef": true,
|
||||
"computed": true,
|
||||
"createApp": true,
|
||||
"customRef": true,
|
||||
"defineAsyncComponent": true,
|
||||
"defineComponent": true,
|
||||
"effectScope": true,
|
||||
"getCurrentInstance": true,
|
||||
"getCurrentScope": true,
|
||||
"h": true,
|
||||
"inject": true,
|
||||
"isProxy": true,
|
||||
"isReactive": true,
|
||||
"isReadonly": true,
|
||||
"isRef": true,
|
||||
"markRaw": true,
|
||||
"nextTick": true,
|
||||
"onActivated": true,
|
||||
"onBeforeMount": true,
|
||||
"onBeforeUnmount": true,
|
||||
"onBeforeUpdate": true,
|
||||
"onDeactivated": true,
|
||||
"onErrorCaptured": true,
|
||||
"onMounted": true,
|
||||
"onRenderTracked": true,
|
||||
"onRenderTriggered": true,
|
||||
"onScopeDispose": true,
|
||||
"onServerPrefetch": true,
|
||||
"onUnmounted": true,
|
||||
"onUpdated": true,
|
||||
"onWatcherCleanup": true,
|
||||
"provide": true,
|
||||
"reactive": true,
|
||||
"readonly": true,
|
||||
"ref": true,
|
||||
"resolveComponent": true,
|
||||
"shallowReactive": true,
|
||||
"shallowReadonly": true,
|
||||
"shallowRef": true,
|
||||
"toRaw": true,
|
||||
"toRef": true,
|
||||
"toRefs": true,
|
||||
"toValue": true,
|
||||
"triggerRef": true,
|
||||
"unref": true,
|
||||
"useAttrs": true,
|
||||
"useCssModule": true,
|
||||
"useCssVars": true,
|
||||
"useId": true,
|
||||
"useModel": true,
|
||||
"useSlots": true,
|
||||
"useTemplateRef": true,
|
||||
"watch": true,
|
||||
"watchEffect": true,
|
||||
"watchPostEffect": true,
|
||||
"watchSyncEffect": true
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["Vue.volar"]
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
// Generated by unplugin-auto-import
|
||||
// biome-ignore lint: disable
|
||||
export {}
|
||||
declare global {
|
||||
const EffectScope: typeof import('vue')['EffectScope']
|
||||
const computed: typeof import('vue')['computed']
|
||||
const createApp: typeof import('vue')['createApp']
|
||||
const customRef: typeof import('vue')['customRef']
|
||||
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
|
||||
const defineComponent: typeof import('vue')['defineComponent']
|
||||
const effectScope: typeof import('vue')['effectScope']
|
||||
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
||||
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
||||
const h: typeof import('vue')['h']
|
||||
const inject: typeof import('vue')['inject']
|
||||
const isProxy: typeof import('vue')['isProxy']
|
||||
const isReactive: typeof import('vue')['isReactive']
|
||||
const isReadonly: typeof import('vue')['isReadonly']
|
||||
const isRef: typeof import('vue')['isRef']
|
||||
const markRaw: typeof import('vue')['markRaw']
|
||||
const nextTick: typeof import('vue')['nextTick']
|
||||
const onActivated: typeof import('vue')['onActivated']
|
||||
const onBeforeMount: typeof import('vue')['onBeforeMount']
|
||||
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
|
||||
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
|
||||
const onDeactivated: typeof import('vue')['onDeactivated']
|
||||
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
|
||||
const onMounted: typeof import('vue')['onMounted']
|
||||
const onRenderTracked: typeof import('vue')['onRenderTracked']
|
||||
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
|
||||
const onScopeDispose: typeof import('vue')['onScopeDispose']
|
||||
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
|
||||
const onUnmounted: typeof import('vue')['onUnmounted']
|
||||
const onUpdated: typeof import('vue')['onUpdated']
|
||||
const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
|
||||
const provide: typeof import('vue')['provide']
|
||||
const reactive: typeof import('vue')['reactive']
|
||||
const readonly: typeof import('vue')['readonly']
|
||||
const ref: typeof import('vue')['ref']
|
||||
const resolveComponent: typeof import('vue')['resolveComponent']
|
||||
const shallowReactive: typeof import('vue')['shallowReactive']
|
||||
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||
const shallowRef: typeof import('vue')['shallowRef']
|
||||
const toRaw: typeof import('vue')['toRaw']
|
||||
const toRef: typeof import('vue')['toRef']
|
||||
const toRefs: typeof import('vue')['toRefs']
|
||||
const toValue: typeof import('vue')['toValue']
|
||||
const triggerRef: typeof import('vue')['triggerRef']
|
||||
const unref: typeof import('vue')['unref']
|
||||
const useAttrs: typeof import('vue')['useAttrs']
|
||||
const useCssModule: typeof import('vue')['useCssModule']
|
||||
const useCssVars: typeof import('vue')['useCssVars']
|
||||
const useId: typeof import('vue')['useId']
|
||||
const useModel: typeof import('vue')['useModel']
|
||||
const useSlots: typeof import('vue')['useSlots']
|
||||
const useTemplateRef: typeof import('vue')['useTemplateRef']
|
||||
const watch: typeof import('vue')['watch']
|
||||
const watchEffect: typeof import('vue')['watchEffect']
|
||||
const watchPostEffect: typeof import('vue')['watchPostEffect']
|
||||
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
|
||||
}
|
||||
// for type re-export
|
||||
declare global {
|
||||
// @ts-ignore
|
||||
export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
|
||||
import('vue')
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
VITE_PORT=5050
|
||||
VITE_API_BASE=/api
|
||||
VITE_MOCK_ENABLED=true
|
@ -0,0 +1,10 @@
|
||||
###
|
||||
# @Author: donghao donghao@supervision.ltd
|
||||
# @Date: 2025-03-06 11:36:56
|
||||
# @LastEditors: donghao donghao@supervision.ltd
|
||||
# @LastEditTime: 2025-03-06 11:37:31
|
||||
# @FilePath: \vite-ai\data-dashboard\env\.env.production
|
||||
# @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
###
|
||||
VITE_API_BASE=http://test-api.example.com
|
||||
VITE_MOCK_ENABLED=false
|
@ -0,0 +1,10 @@
|
||||
###
|
||||
# @Author: donghao donghao@supervision.ltd
|
||||
# @Date: 2025-03-06 11:36:48
|
||||
# @LastEditors: donghao donghao@supervision.ltd
|
||||
# @LastEditTime: 2025-03-06 11:37:50
|
||||
# @FilePath: \vite-ai\data-dashboard\env\.env.test
|
||||
# @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
###
|
||||
VITE_API_BASE=http://api.example.com
|
||||
VITE_MOCK_ENABLED=false
|
@ -0,0 +1,24 @@
|
||||
<!--
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2025-03-06 17:57:05
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2025-03-18 11:08:34
|
||||
* @FilePath: \5G-Loading-Bay-Web\index.html
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
-->
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>监控平台</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<script type="module" src="/adapter.min.js"></script>
|
||||
<script type="module" src="/webrtcstreamer.js"></script>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 551 KiB |
After Width: | Height: | Size: 478 KiB |
After Width: | Height: | Size: 591 KiB |
After Width: | Height: | Size: 1.0 MiB |
After Width: | Height: | Size: 1.7 MiB |
After Width: | Height: | Size: 699 KiB |
After Width: | Height: | Size: 2.7 MiB |
After Width: | Height: | Size: 1.3 MiB |
After Width: | Height: | Size: 1.0 MiB |
After Width: | Height: | Size: 1.5 MiB |
After Width: | Height: | Size: 991 KiB |
After Width: | Height: | Size: 398 KiB |
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2025-03-07 14:57:20
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2025-03-14 15:11:04
|
||||
* @FilePath: \5G-Loading-Bay-Web\mock\deviceStatus.ts
|
||||
* @Description: 设备状态
|
||||
*/
|
||||
import { MockMethod } from "vite-plugin-mock";
|
||||
import { deviceStatusListData, deviceHistoryListData } from "./pools/deviceStatusData";
|
||||
import { fetchCurrPageByList, fetchMockSuccessFullByOther } from "./utils/apiMock";
|
||||
|
||||
export default [
|
||||
{
|
||||
url: "/api/v1/device/device/",
|
||||
method: "post",
|
||||
response: req => {
|
||||
const { page, pageSize } = req.body;
|
||||
// console.log(req);
|
||||
return {
|
||||
...fetchCurrPageByList({
|
||||
...deviceStatusListData,
|
||||
data: {
|
||||
...deviceStatusListData.data,
|
||||
page,
|
||||
pageSize: pageSize || 10
|
||||
}
|
||||
})
|
||||
};
|
||||
}
|
||||
},
|
||||
{
|
||||
url: "/api/v1/device/device_history/",
|
||||
method: "post",
|
||||
response: req => {
|
||||
// console.log(req);
|
||||
return {...fetchMockSuccessFullByOther(deviceHistoryListData)}
|
||||
}
|
||||
}
|
||||
] as MockMethod[];
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2025-03-11 11:29:02
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2025-03-14 15:10:47
|
||||
* @FilePath: \5G-Loading-Bay-Web\mock\poleMonitor.ts
|
||||
* @Description: 撑杆监测
|
||||
*/
|
||||
import { MockMethod } from "vite-plugin-mock";
|
||||
import { poleMonitorListData, fileListData } from "./pools/poleMonitorData";
|
||||
import { fetchCurrPageByList, fetchMockSuccessFullByOther } from "./utils/apiMock";
|
||||
|
||||
export default [
|
||||
{
|
||||
url: "/api/getPoleMonitorList",
|
||||
method: "post",
|
||||
response: req => {
|
||||
const { page, pageSize } = req.body;
|
||||
// console.log(req);
|
||||
return {
|
||||
...fetchCurrPageByList({
|
||||
...poleMonitorListData,
|
||||
data: {
|
||||
...poleMonitorListData.data,
|
||||
page,
|
||||
pageSize: pageSize || 10
|
||||
}
|
||||
})
|
||||
};
|
||||
}
|
||||
},
|
||||
{
|
||||
url: "/api/v1/record/record_detail_list/",
|
||||
method: "post",
|
||||
response: req => {
|
||||
// console.log(req);
|
||||
return {...fetchMockSuccessFullByOther(fileListData)}
|
||||
}
|
||||
}
|
||||
] as MockMethod[];
|
@ -0,0 +1 @@
|
||||
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFtdLAogICJzb3VyY2VzQ29udGVudCI6IFtdLAogICJtYXBwaW5ncyI6ICIiLAogICJuYW1lcyI6IFtdCn0K
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2025-03-11 11:30:09
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2025-03-17 15:24:42
|
||||
* @FilePath: \5G-Loading-Bay-Web\mock\pools\poleMonitorData.ts
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
import Mock from "mockjs";
|
||||
import { isImage } from "../utils/is";
|
||||
const videoUrls = [
|
||||
"https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4",
|
||||
"http://192.168.10.14:8123/ftp/1.jpg",
|
||||
"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
|
||||
"https://www.sample-videos.com/video123/mp4/360/big_buck_bunny_360p_5mb.mp4",
|
||||
"https://media.w3.org/2010/05/video/movie_300.mp4",
|
||||
"https://www.w3schools.com/html/mov_bbb.mp4",
|
||||
"https://media.w3.org/2010/05/sintel/trailer.mp4",
|
||||
"https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/360/Big_Buck_Bunny_360_10s_1MB.mp4",
|
||||
"https://archive.org/download/Popeye_forPresident/Popeye_forPresident_512kb.mp4",
|
||||
"https://archive.org/download/Sita_Sings_the_Blues/Sita_Sings_the_Blues_small.mp4",
|
||||
];
|
||||
const mockListData = Mock.mock({
|
||||
// 生成 10 条数据,可以根据需要调整数量
|
||||
"data|140": [
|
||||
{
|
||||
// 车号,生成随机的 4 位字母和数字组合
|
||||
train_number: /[A-Z0-9]{10}/,
|
||||
// 车型,从预定义的数组中随机选择一个
|
||||
train_model: () => Mock.Random.pick(["轿车", "SUV", "客车", "货车"]),
|
||||
// 车厢号,生成 1 到 10 的随机整数
|
||||
"train_carriage_number|1-10": 1,
|
||||
// 告警类型,从预定义的数组中随机选择一个
|
||||
alarm_type: () =>
|
||||
Mock.Random.pick(["超速告警", "碰撞告警", "低电量告警"]),
|
||||
// 故障类型,从预定义的数组中随机选择一个
|
||||
faultType: () => Mock.Random.pick(["撑杆弯曲", "撑杆断折"]),
|
||||
// 等级,生成 1 到 3 的随机整数
|
||||
"level|1-3": 1,
|
||||
// 复核,随机生成 '是' 或 '否'
|
||||
is_reviewed: () => Mock.Random.pick([true, false]),
|
||||
// 时间,生成过去一个月内的随机日期和时间
|
||||
created_at: () =>
|
||||
Mock.Random.date("yyyy-MM-dd") + " " + Mock.Random.time("HH:mm:ss"),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const mockFilesData = Mock.mock({
|
||||
[`list|${videoUrls.length}`]: [
|
||||
{
|
||||
"id|+1": 10,
|
||||
key: "@id",
|
||||
name: "@animal",
|
||||
video_url: function () {
|
||||
// 依次取出视频链接
|
||||
const currFile = videoUrls[this.id - 10];
|
||||
if (!isImage(currFile)) {
|
||||
return videoUrls[this.id - 10];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
image_url: function () {
|
||||
// 依次取出视频链接
|
||||
const currFile = videoUrls[this.id - 10];
|
||||
if (isImage(currFile)) {
|
||||
return videoUrls[this.id - 10];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
created_at: '@datetime("yyyy-MM-dd HH:mm:ss")',
|
||||
updated_at: '@datetime("yyyy-MM-dd HH:mm:ss")',
|
||||
length: "@float(0.1, 10, 2, 2)",
|
||||
width: "@float(0.1, 10, 2, 2)",
|
||||
height: "@float(0.1, 10, 2, 2)",
|
||||
weight: "@float(0.1, 1000, 1, 2)",
|
||||
volume: function () {
|
||||
return (this.length * this.width * this.height).toFixed(2);
|
||||
},
|
||||
record: 1,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// console.log(mockListData, 'mockListData');
|
||||
const currentData = mockListData.data;
|
||||
const currentFilesData = mockFilesData.list;
|
||||
|
||||
export const poleMonitorListData = {
|
||||
data: {
|
||||
list: currentData,
|
||||
total: currentData.length,
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
};
|
||||
|
||||
export const fileListData = {
|
||||
data: {
|
||||
data: currentFilesData,
|
||||
},
|
||||
};
|
@ -0,0 +1,17 @@
|
||||
/**成功返回数据结构 */
|
||||
export interface successMockApiProps {
|
||||
code: number; // 0 成功
|
||||
success: boolean; // true 成功
|
||||
data: any; // mock业务层数据
|
||||
msg: string | undefined; // 成功提示
|
||||
isMock: boolean; // true 标识当前是模拟数据
|
||||
}
|
||||
|
||||
/**失败返回数据结构 */
|
||||
export interface failMockApiProps {
|
||||
code?: number; // 7 失败
|
||||
success: boolean; // false 失败
|
||||
data: any; // mock业务层数据
|
||||
msg: string | undefined; // 成功提示
|
||||
isMock: boolean; // true 标识当前是模拟数据
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2025-03-06 11:37:14
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2025-03-06 11:38:11
|
||||
* @FilePath: \vite-ai\data-dashboard\mock\user.ts
|
||||
* @Description: 模拟登录接口
|
||||
*/
|
||||
export default [
|
||||
{
|
||||
url: '/api/login',
|
||||
method: 'post',
|
||||
response: ({ body }) => {
|
||||
if (body.username === 'admin' && body.password === 'admin123') {
|
||||
return {
|
||||
code: 200,
|
||||
data: {
|
||||
token: 'MOCK_TOKEN_' + Date.now()
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
code: 401,
|
||||
message: '用户名或密码错误'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
@ -0,0 +1,49 @@
|
||||
// mock/utils/apiMock.ts
|
||||
function fetchMockSuccessFullByOther({
|
||||
data,
|
||||
msg
|
||||
}) {
|
||||
const result = {
|
||||
code: 200,
|
||||
// 200 成功
|
||||
success: true,
|
||||
// true 成功
|
||||
data: data || null,
|
||||
// mock业务层数据
|
||||
msg,
|
||||
// 成功提示
|
||||
isMock: true
|
||||
// true 标识当前是模拟数据
|
||||
};
|
||||
return result;
|
||||
}
|
||||
function fetchMockFailFullByOther({ data, msg }) {
|
||||
const result = {
|
||||
code: 599,
|
||||
// 200 成功
|
||||
success: false,
|
||||
// true 成功
|
||||
data: data || null,
|
||||
// mock业务层数据
|
||||
msg,
|
||||
// 成功提示
|
||||
isMock: true
|
||||
// true 标识当前是模拟数据
|
||||
};
|
||||
return result;
|
||||
}
|
||||
function fetchCurrPageByList({ data }) {
|
||||
const { current, pageSize } = data;
|
||||
const prevPage = current - 1;
|
||||
const currPageData = {
|
||||
...data,
|
||||
data: data.data.slice(prevPage * pageSize, current * pageSize)
|
||||
};
|
||||
return fetchMockSuccessFullByOther({ data: currPageData });
|
||||
}
|
||||
export {
|
||||
fetchCurrPageByList,
|
||||
fetchMockFailFullByOther,
|
||||
fetchMockSuccessFullByOther
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibW9jay91dGlscy9hcGlNb2NrLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJjb25zdCBfX2luamVjdGVkX2ZpbGVuYW1lX18gPSBcIkU6XFxcXHlheGluX3dlYlxcXFw1Ry1Mb2FkaW5nLUJheS1XZWJcXFxcbW9ja1xcXFx1dGlsc1xcXFxhcGlNb2NrLnRzXCI7Y29uc3QgX19pbmplY3RlZF9kaXJuYW1lX18gPSBcIkU6XFxcXHlheGluX3dlYlxcXFw1Ry1Mb2FkaW5nLUJheS1XZWJcXFxcbW9ja1xcXFx1dGlsc1wiO2NvbnN0IF9faW5qZWN0ZWRfaW1wb3J0X21ldGFfdXJsX18gPSBcImZpbGU6Ly8vRToveWF4aW5fd2ViLzVHLUxvYWRpbmctQmF5LVdlYi9tb2NrL3V0aWxzL2FwaU1vY2sudHNcIjsvKlxyXG4gKiBAQXV0aG9yOiBkb25naGFvIGRvbmdoYW9Ac3VwZXJ2aXNpb24ubHRkXHJcbiAqIEBEYXRlOiAyMDI1LTAzLTA3IDE0OjU4OjM5XHJcbiAqIEBMYXN0RWRpdG9yczogZG9uZ2hhbyBkb25naGFvQHN1cGVydmlzaW9uLmx0ZFxyXG4gKiBATGFzdEVkaXRUaW1lOiAyMDI1LTAzLTEzIDE0OjI5OjI2XHJcbiAqIEBGaWxlUGF0aDogXFw1Ry1Mb2FkaW5nLUJheS1XZWJcXG1vY2tcXHV0aWxzXFxhcGlNb2NrLnRzXHJcbiAqIEBEZXNjcmlwdGlvbjogXHU4RkQ5XHU2NjJGXHU5RUQ4XHU4QkE0XHU4QkJFXHU3RjZFLFx1OEJGN1x1OEJCRVx1N0Y2RWBjdXN0b21NYWRlYCwgXHU2MjUzXHU1RjAwa29yb0ZpbGVIZWFkZXJcdTY3RTVcdTc3MEJcdTkxNERcdTdGNkUgXHU4RkRCXHU4ODRDXHU4QkJFXHU3RjZFOiBodHRwczovL2dpdGh1Yi5jb20vT0JLb3JvMS9rb3JvMUZpbGVIZWFkZXIvd2lraS8lRTklODUlOEQlRTclQkQlQUVcclxuICovXHJcbmltcG9ydCB7IGZhaWxNb2NrQXBpUHJvcHMsIHN1Y2Nlc3NNb2NrQXBpUHJvcHMgfSBmcm9tIFwiLi4vdHlwaW5nXCI7XHJcbmV4cG9ydCBmdW5jdGlvbiBmZXRjaE1vY2tTdWNjZXNzRnVsbEJ5T3RoZXIoe1xyXG4gIGRhdGEsXHJcbiAgbXNnLFxyXG59KTogc3VjY2Vzc01vY2tBcGlQcm9wcyB7XHJcbiAgLy8gcmV0dXJuIHtcclxuICAvLyAgIGNvZGU6IDIwMCwgLy8gMjAwIFx1NjIxMFx1NTI5RlxyXG4gIC8vICAgc3VjY2VzczogdHJ1ZSwgLy8gdHJ1ZSBcdTYyMTBcdTUyOUZcclxuICAvLyAgIGRhdGE6IGRhdGEgfHwgbnVsbCwgLy8gbW9ja1x1NEUxQVx1NTJBMVx1NUM0Mlx1NjU3MFx1NjM2RVxyXG4gIC8vICAgbXNnOiBtc2cgfCBcIm9rXCIsIC8vIFx1NjIxMFx1NTI5Rlx1NjNEMFx1NzkzQVxyXG4gIC8vICAgaXNNb2NrOiB0cnVlIC8vIHRydWUgXHU2ODA3XHU4QkM2XHU1RjUzXHU1MjREXHU2NjJGXHU2QTIxXHU2MkRGXHU2NTcwXHU2MzZFXHJcbiAgLy8gfSBhcyBzdWNjZXNzTW9ja0FwaVByb3BzO1xyXG4gIGNvbnN0IHJlc3VsdDogc3VjY2Vzc01vY2tBcGlQcm9wcyA9IHtcclxuICAgIGNvZGU6IDIwMCwgLy8gMjAwIFx1NjIxMFx1NTI5RlxyXG4gICAgc3VjY2VzczogdHJ1ZSwgLy8gdHJ1ZSBcdTYyMTBcdTUyOUZcclxuICAgIGRhdGE6IGRhdGEgfHwgbnVsbCwgLy8gbW9ja1x1NEUxQVx1NTJBMVx1NUM0Mlx1NjU3MFx1NjM2RVxyXG4gICAgbXNnOiBtc2cgYXMgc3RyaW5nIHwgXCJva1wiLCAvLyBcdTYyMTBcdTUyOUZcdTYzRDBcdTc5M0FcclxuICAgIGlzTW9jazogdHJ1ZSwgLy8gdHJ1ZSBcdTY4MDdcdThCQzZcdTVGNTNcdTUyNERcdTY2MkZcdTZBMjFcdTYyREZcdTY1NzBcdTYzNkVcclxuICB9O1xyXG4gIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBmZXRjaE1vY2tGYWlsRnVsbEJ5T3RoZXIoeyBkYXRhLCBtc2cgfSk6IGZhaWxNb2NrQXBpUHJvcHMge1xyXG4gIC8vIHJldHVybiB7XHJcbiAgLy8gICBjb2RlOiA1OTksIC8vIDIwMCBcdTYyMTBcdTUyOUZcclxuICAvLyAgIHN1Y2Nlc3M6IHRydWUsIC8vIHRydWUgXHU2MjEwXHU1MjlGXHJcbiAgLy8gICBkYXRhOiBkYXRhIHx8IG51bGwsIC8vIG1vY2tcdTRFMUFcdTUyQTFcdTVDNDJcdTY1NzBcdTYzNkVcclxuICAvLyAgIG1zZzogbXNnIHwgXCJmYWlsXCIsIC8vIFx1NjIxMFx1NTI5Rlx1NjNEMFx1NzkzQVxyXG4gIC8vICAgaXNNb2NrOiB0cnVlIC8vIHRydWUgXHU2ODA3XHU4QkM2XHU1RjUzXHU1MjREXHU2NjJGXHU2QTIxXHU2MkRGXHU2NTcwXHU2MzZFXHJcbiAgLy8gfSBhcyBmYWlsTW9ja0FwaVByb3BzO1xyXG4gIGNvbnN0IHJlc3VsdDogZmFpbE1vY2tBcGlQcm9wcyA9IHtcclxuICAgIGNvZGU6IDU5OSwgLy8gMjAwIFx1NjIxMFx1NTI5RlxyXG4gICAgc3VjY2VzczogZmFsc2UsIC8vIHRydWUgXHU2MjEwXHU1MjlGXHJcbiAgICBkYXRhOiBkYXRhIHx8IG51bGwsIC8vIG1vY2tcdTRFMUFcdTUyQTFcdTVDNDJcdTY1NzBcdTYzNkVcclxuICAgIG1zZzogbXNnIGFzIHN0cmluZyB8IFwiZmFpbFwiLCAvLyBcdTYyMTBcdTUyOUZcdTYzRDBcdTc5M0FcclxuICAgIGlzTW9jazogdHJ1ZSwgLy8gdHJ1ZSBcdTY4MDdcdThCQzZcdTVGNTNcdTUyNERcdTY2MkZcdTZBMjFcdTYyREZcdTY1NzBcdTYzNkVcclxuICB9O1xyXG4gIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbi8vIFx1NTIwNlx1OTg3NVx1NUM1NVx1NzkzQVxyXG5leHBvcnQgZnVuY3Rpb24gZmV0Y2hDdXJyUGFnZUJ5TGlzdCh7IGRhdGEgfSk6IHN1Y2Nlc3NNb2NrQXBpUHJvcHMge1xyXG4gIC8vIGNvbnNvbGUubG9nKFwiZmV0Y2hDdXJyUGFnZUJ5TGlzdF9kYXRhXCIsIGRhdGEpO1xyXG4gIGNvbnN0IHsgY3VycmVudCwgcGFnZVNpemUgfSA9IGRhdGE7XHJcbiAgY29uc3QgcHJldlBhZ2UgPSBjdXJyZW50IC0gMTtcclxuICBjb25zdCBjdXJyUGFnZURhdGEgPSB7XHJcbiAgICAuLi5kYXRhLFxyXG4gICAgZGF0YTogZGF0YS5kYXRhLnNsaWNlKHByZXZQYWdlICogcGFnZVNpemUsIGN1cnJlbnQgKiBwYWdlU2l6ZSksXHJcbiAgfTtcclxuICByZXR1cm4gZmV0Y2hNb2NrU3VjY2Vzc0Z1bGxCeU90aGVyKHsgZGF0YTogY3VyclBhZ2VEYXRhIH0pO1xyXG59XHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFTTyxTQUFTLDRCQUE0QjtBQUFBLEVBQzFDO0FBQUEsRUFDQTtBQUNGLEdBQXdCO0FBUXRCLFFBQU0sU0FBOEI7QUFBQSxJQUNsQyxNQUFNO0FBQUE7QUFBQSxJQUNOLFNBQVM7QUFBQTtBQUFBLElBQ1QsTUFBTSxRQUFRO0FBQUE7QUFBQSxJQUNkO0FBQUE7QUFBQSxJQUNBLFFBQVE7QUFBQTtBQUFBLEVBQ1Y7QUFDQSxTQUFPO0FBQ1Q7QUFFTyxTQUFTLHlCQUF5QixFQUFFLE1BQU0sSUFBSSxHQUFxQjtBQVF4RSxRQUFNLFNBQTJCO0FBQUEsSUFDL0IsTUFBTTtBQUFBO0FBQUEsSUFDTixTQUFTO0FBQUE7QUFBQSxJQUNULE1BQU0sUUFBUTtBQUFBO0FBQUEsSUFDZDtBQUFBO0FBQUEsSUFDQSxRQUFRO0FBQUE7QUFBQSxFQUNWO0FBQ0EsU0FBTztBQUNUO0FBR08sU0FBUyxvQkFBb0IsRUFBRSxLQUFLLEdBQXdCO0FBRWpFLFFBQU0sRUFBRSxTQUFTLFNBQVMsSUFBSTtBQUM5QixRQUFNLFdBQVcsVUFBVTtBQUMzQixRQUFNLGVBQWU7QUFBQSxJQUNuQixHQUFHO0FBQUEsSUFDSCxNQUFNLEtBQUssS0FBSyxNQUFNLFdBQVcsVUFBVSxVQUFVLFFBQVE7QUFBQSxFQUMvRDtBQUNBLFNBQU8sNEJBQTRCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDM0Q7IiwKICAibmFtZXMiOiBbXQp9Cg==
|
@ -0,0 +1,27 @@
|
||||
// mock/utils/is.ts
|
||||
var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
|
||||
"jpg",
|
||||
"jpeg",
|
||||
"png",
|
||||
"gif",
|
||||
"bmp",
|
||||
"svg",
|
||||
"webp",
|
||||
"tiff",
|
||||
"psd",
|
||||
"ico",
|
||||
"jfif",
|
||||
"apng",
|
||||
"avif"
|
||||
]);
|
||||
function isImage(filename) {
|
||||
const baseName = filename.split("/").pop().split("\\").pop();
|
||||
if (!baseName) return false;
|
||||
const ext = baseName.split(".").pop()?.toLowerCase();
|
||||
if (!ext || ext.length < 2) return false;
|
||||
return IMAGE_EXTENSIONS.has(ext);
|
||||
}
|
||||
export {
|
||||
isImage
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibW9jay91dGlscy9pcy50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiY29uc3QgX19pbmplY3RlZF9maWxlbmFtZV9fID0gXCJFOlxcXFx5YXhpbl93ZWJcXFxcNUctTG9hZGluZy1CYXktV2ViXFxcXG1vY2tcXFxcdXRpbHNcXFxcaXMudHNcIjtjb25zdCBfX2luamVjdGVkX2Rpcm5hbWVfXyA9IFwiRTpcXFxceWF4aW5fd2ViXFxcXDVHLUxvYWRpbmctQmF5LVdlYlxcXFxtb2NrXFxcXHV0aWxzXCI7Y29uc3QgX19pbmplY3RlZF9pbXBvcnRfbWV0YV91cmxfXyA9IFwiZmlsZTovLy9FOi95YXhpbl93ZWIvNUctTG9hZGluZy1CYXktV2ViL21vY2svdXRpbHMvaXMudHNcIjsvKipcclxuICogXHU1MjI0XHU2NUFEXHU2NTg3XHU0RUY2XHU1NDBEXHU2NjJGXHU1NDI2XHU0RTNBXHU1NkZFXHU3MjQ3XHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSBcdTVCOENcdTY1NzRcdTY1ODdcdTRFRjZcdTU0MERcdUZGMDhcdTU0MkJcdThERUZcdTVGODRcdTU0OENcdTYyNjlcdTVDNTVcdTU0MERcdUZGMDlcclxuICogQHJldHVybnMge2Jvb2xlYW59IFx1NjYyRlx1NTQyNlx1NEUzQVx1NTZGRVx1NzI0N1xyXG4gKi9cclxuXHJcbmNvbnN0IElNQUdFX0VYVEVOU0lPTlMgPSBuZXcgU2V0KFtcclxuICBcImpwZ1wiLFxyXG4gIFwianBlZ1wiLFxyXG4gIFwicG5nXCIsXHJcbiAgXCJnaWZcIixcclxuICBcImJtcFwiLFxyXG4gIFwic3ZnXCIsXHJcbiAgXCJ3ZWJwXCIsXHJcbiAgXCJ0aWZmXCIsXHJcbiAgXCJwc2RcIixcclxuICBcImljb1wiLFxyXG4gIFwiamZpZlwiLFxyXG4gIFwiYXBuZ1wiLFxyXG4gIFwiYXZpZlwiLFxyXG5dKTtcclxuZXhwb3J0IGZ1bmN0aW9uIGlzSW1hZ2UoZmlsZW5hbWUpIHtcclxuICAvLyAxLiBcdTUzQkJcdTk2NjRcdThERUZcdTVGODRcdUZGMENcdTUzRUFcdTRGRERcdTc1NTlcdTY1ODdcdTRFRjZcdTU0MERcclxuICBjb25zdCBiYXNlTmFtZSA9IGZpbGVuYW1lLnNwbGl0KFwiL1wiKS5wb3AoKS5zcGxpdChcIlxcXFxcIikucG9wKCk7XHJcbiAgaWYgKCFiYXNlTmFtZSkgcmV0dXJuIGZhbHNlO1xyXG5cclxuICAvLyAyLiBcdTYzRDBcdTUzRDZcdTYyNjlcdTVDNTVcdTU0MERcdUZGMDhcdTU5MDRcdTc0MDZcdTU5MUFcdTYyNjlcdTVDNTVcdTU0MERcdUZGMENcdTUzRDZcdTY3MDBcdTU0MEVcdTRFMDBcdTRFMkFcdUZGMDlcclxuICBjb25zdCBleHQgPSBiYXNlTmFtZS5zcGxpdChcIi5cIikucG9wKCk/LnRvTG93ZXJDYXNlKCk7XHJcbiAgaWYgKCFleHQgfHwgZXh0Lmxlbmd0aCA8IDIpIHJldHVybiBmYWxzZTsgLy8gXHU2MjY5XHU1QzU1XHU1NDBEXHU5NTdGXHU1RUE2XHU4MUYzXHU1QzExMlx1NEY0RFx1RkYwOFx1NTk4Mi5qcGdcdUZGMDlcclxuXHJcbiAgLy8gMy4gXHU2OEMwXHU2N0U1XHU2NjJGXHU1NDI2XHU1NzI4XHU1NkZFXHU3MjQ3XHU2MjY5XHU1QzU1XHU1NDBEXHU3NjdEXHU1NDBEXHU1MzU1XHJcbiAgcmV0dXJuIElNQUdFX0VYVEVOU0lPTlMuaGFzKGV4dCk7XHJcbn1cclxuXHJcbi8vIFx1NzkzQVx1NEY4Qlx1NkQ0Qlx1OEJENVxyXG4vLyAgIGNvbnNvbGUubG9nKGlzSW1hZ2UoJ3Bob3RvLmpwZycpKTsgICAgIC8vIHRydWVcclxuLy8gICBjb25zb2xlLmxvZyhpc0ltYWdlKCdpbWFnZS5wbmcnKSk7ICAgIC8vIHRydWVcclxuLy8gICBjb25zb2xlLmxvZyhpc0ltYWdlKCdsb2dvLnN2ZycpKTsgICAgIC8vIHRydWVcclxuLy8gICBjb25zb2xlLmxvZyhpc0ltYWdlKCdjb3Zlci50YXIuZ3onKSk7IC8vIGZhbHNlXHVGRjA4XHU5NzVFXHU1NkZFXHU3MjQ3XHU2MjY5XHU1QzU1XHU1NDBEXHVGRjA5XHJcbi8vICAgY29uc29sZS5sb2coaXNJbWFnZSgnZmlsZScpKTsgICAgICAgICAvLyBmYWxzZVx1RkYwOFx1NjVFMFx1NjI2OVx1NUM1NVx1NTQwRFx1RkYwOVxyXG4vLyAgIGNvbnNvbGUubG9nKGlzSW1hZ2UoJy5oaWRkZW4ucG5nJykpOyAgLy8gdHJ1ZVx1RkYwOFx1OTY5MFx1ODVDRlx1NjU4N1x1NEVGNlx1RkYwOVxyXG4vLyAgIGNvbnNvbGUubG9nKGlzSW1hZ2UoJ2ljb24uSlBFRycpKTsgICAgLy8gdHJ1ZVx1RkYwOFx1NTkyN1x1NUMwRlx1NTE5OVx1NEUwRFx1NjU0Rlx1NjExRlx1RkYwOVxyXG4vLyAgIGNvbnNvbGUubG9nKGlzSW1hZ2UoJ3ZpZGVvLm1wNCcpKTsgICAgLy8gZmFsc2VcdUZGMDhcdTg5QzZcdTk4OTFcdUZGMDlcclxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQU1BLElBQU0sbUJBQW1CLG9CQUFJLElBQUk7QUFBQSxFQUMvQjtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUNGLENBQUM7QUFDTSxTQUFTLFFBQVEsVUFBVTtBQUVoQyxRQUFNLFdBQVcsU0FBUyxNQUFNLEdBQUcsRUFBRSxJQUFJLEVBQUUsTUFBTSxJQUFJLEVBQUUsSUFBSTtBQUMzRCxNQUFJLENBQUMsU0FBVSxRQUFPO0FBR3RCLFFBQU0sTUFBTSxTQUFTLE1BQU0sR0FBRyxFQUFFLElBQUksR0FBRyxZQUFZO0FBQ25ELE1BQUksQ0FBQyxPQUFPLElBQUksU0FBUyxFQUFHLFFBQU87QUFHbkMsU0FBTyxpQkFBaUIsSUFBSSxHQUFHO0FBQ2pDOyIsCiAgIm5hbWVzIjogW10KfQo=
|
@ -0,0 +1,20 @@
|
||||
// mock/utils/mockMoment.ts
|
||||
function generateRandomDateTimeByYear(year) {
|
||||
const month = Math.floor(Math.random() * 12) + 1;
|
||||
const day = Math.floor(Math.random() * 31) + 1;
|
||||
const hour = Math.floor(Math.random() * 24);
|
||||
const minute = Math.floor(Math.random() * 60);
|
||||
const second = Math.floor(Math.random() * 60);
|
||||
return `${year}-${month < 10 ? "0" : ""}${month}-${day < 10 ? "0" : ""}${day} ${hour < 10 ? "0" : ""}${hour}:${minute < 10 ? "0" : ""}${minute}:${second < 10 ? "0" : ""}${second}`;
|
||||
}
|
||||
function generateRandomMoment(date = /* @__PURE__ */ new Date(), type = "HH:mm:ss") {
|
||||
const hour = Math.floor(Math.random() * 24);
|
||||
const minute = Math.floor(Math.random() * 60);
|
||||
const second = Math.floor(Math.random() * 60);
|
||||
return `${hour < 10 ? "0" : ""}${hour}:${minute < 10 ? "0" : ""}${minute}:${second < 10 ? "0" : ""}${second}`;
|
||||
}
|
||||
export {
|
||||
generateRandomDateTimeByYear,
|
||||
generateRandomMoment
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibW9jay91dGlscy9tb2NrTW9tZW50LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJjb25zdCBfX2luamVjdGVkX2ZpbGVuYW1lX18gPSBcIkU6XFxcXHlheGluX3dlYlxcXFw1Ry1Mb2FkaW5nLUJheS1XZWJcXFxcbW9ja1xcXFx1dGlsc1xcXFxtb2NrTW9tZW50LnRzXCI7Y29uc3QgX19pbmplY3RlZF9kaXJuYW1lX18gPSBcIkU6XFxcXHlheGluX3dlYlxcXFw1Ry1Mb2FkaW5nLUJheS1XZWJcXFxcbW9ja1xcXFx1dGlsc1wiO2NvbnN0IF9faW5qZWN0ZWRfaW1wb3J0X21ldGFfdXJsX18gPSBcImZpbGU6Ly8vRToveWF4aW5fd2ViLzVHLUxvYWRpbmctQmF5LVdlYi9tb2NrL3V0aWxzL21vY2tNb21lbnQudHNcIjtleHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVSYW5kb21EYXRlVGltZUJ5WWVhcih5ZWFyKSB7XHJcbiAgLy8gXHU3NTFGXHU2MjEwXHU5NjhGXHU2NzNBXHU2NzA4XHU0RUZEXHVGRjA4MS0xMlx1RkYwOVxyXG4gIGNvbnN0IG1vbnRoID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMTIpICsgMTtcclxuXHJcbiAgLy8gXHU3NTFGXHU2MjEwXHU5NjhGXHU2NzNBXHU2NUU1XHU2NzFGXHVGRjA4MS0zMVx1RkYwOVxyXG4gIGNvbnN0IGRheSA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDMxKSArIDE7XHJcblxyXG4gIC8vIFx1NzUxRlx1NjIxMFx1OTY4Rlx1NjczQVx1NUMwRlx1NjVGNlx1RkYwODAtMjNcdUZGMDlcclxuICBjb25zdCBob3VyID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMjQpO1xyXG5cclxuICAvLyBcdTc1MUZcdTYyMTBcdTk2OEZcdTY3M0FcdTUyMDZcdTk0OUZcdUZGMDgwLTU5XHVGRjA5XHJcbiAgY29uc3QgbWludXRlID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogNjApO1xyXG5cclxuICAvLyBcdTc1MUZcdTYyMTBcdTk2OEZcdTY3M0FcdTc5RDJcdTk0OUZcdUZGMDgwLTU5XHVGRjA5XHJcbiAgY29uc3Qgc2Vjb25kID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogNjApO1xyXG5cclxuICAvLyBcdThGRDRcdTU2REVcdTk2OEZcdTY3M0FcdTY1RTVcdTY3MUZcdTU0OENcdTY1RjZcdTk1RjRcdTc2ODRcdTVCNTdcdTdCMjZcdTRFMzJcclxuICByZXR1cm4gYCR7eWVhcn0tJHttb250aCA8IDEwID8gXCIwXCIgOiBcIlwifSR7bW9udGh9LSR7XHJcbiAgICBkYXkgPCAxMCA/IFwiMFwiIDogXCJcIlxyXG4gIH0ke2RheX0gJHtob3VyIDwgMTAgPyBcIjBcIiA6IFwiXCJ9JHtob3VyfToke21pbnV0ZSA8IDEwID8gXCIwXCIgOiBcIlwifSR7bWludXRlfToke1xyXG4gICAgc2Vjb25kIDwgMTAgPyBcIjBcIiA6IFwiXCJcclxuICB9JHtzZWNvbmR9YDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlUmFuZG9tTW9tZW50KGRhdGUgPSBuZXcgRGF0ZSgpLCB0eXBlID0gXCJISDptbTpzc1wiKSB7XHJcbiAgLy8gXHU3NTFGXHU2MjEwXHU5NjhGXHU2NzNBXHU1QzBGXHU2NUY2XHVGRjA4MC0yM1x1RkYwOVxyXG4gIGNvbnN0IGhvdXIgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAyNCk7XHJcblxyXG4gIC8vIFx1NzUxRlx1NjIxMFx1OTY4Rlx1NjczQVx1NTIwNlx1OTQ5Rlx1RkYwODAtNTlcdUZGMDlcclxuICBjb25zdCBtaW51dGUgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiA2MCk7XHJcblxyXG4gIC8vIFx1NzUxRlx1NjIxMFx1OTY4Rlx1NjczQVx1NzlEMlx1OTQ5Rlx1RkYwODAtNTlcdUZGMDlcclxuICBjb25zdCBzZWNvbmQgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiA2MCk7XHJcbiAgLy8gXHU4RkQ0XHU1NkRFXHU5NjhGXHU2NzNBXHU2NUU1XHU2NzFGXHU1NDhDXHU2NUY2XHU5NUY0XHU3Njg0XHU1QjU3XHU3QjI2XHU0RTMyXHJcbiAgcmV0dXJuIGAke2hvdXIgPCAxMCA/IFwiMFwiIDogXCJcIn0ke2hvdXJ9OiR7bWludXRlIDwgMTAgPyBcIjBcIiA6IFwiXCJ9JHttaW51dGV9OiR7XHJcbiAgICBzZWNvbmQgPCAxMCA/IFwiMFwiIDogXCJcIlxyXG4gIH0ke3NlY29uZH1gO1xyXG59XHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBMlIsU0FBUyw2QkFBNkIsTUFBTTtBQUVyVSxRQUFNLFFBQVEsS0FBSyxNQUFNLEtBQUssT0FBTyxJQUFJLEVBQUUsSUFBSTtBQUcvQyxRQUFNLE1BQU0sS0FBSyxNQUFNLEtBQUssT0FBTyxJQUFJLEVBQUUsSUFBSTtBQUc3QyxRQUFNLE9BQU8sS0FBSyxNQUFNLEtBQUssT0FBTyxJQUFJLEVBQUU7QUFHMUMsUUFBTSxTQUFTLEtBQUssTUFBTSxLQUFLLE9BQU8sSUFBSSxFQUFFO0FBRzVDLFFBQU0sU0FBUyxLQUFLLE1BQU0sS0FBSyxPQUFPLElBQUksRUFBRTtBQUc1QyxTQUFPLEdBQUcsSUFBSSxJQUFJLFFBQVEsS0FBSyxNQUFNLEVBQUUsR0FBRyxLQUFLLElBQzdDLE1BQU0sS0FBSyxNQUFNLEVBQ25CLEdBQUcsR0FBRyxJQUFJLE9BQU8sS0FBSyxNQUFNLEVBQUUsR0FBRyxJQUFJLElBQUksU0FBUyxLQUFLLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFDdEUsU0FBUyxLQUFLLE1BQU0sRUFDdEIsR0FBRyxNQUFNO0FBQ1g7QUFFTyxTQUFTLHFCQUFxQixPQUFPLG9CQUFJLEtBQUssR0FBRyxPQUFPLFlBQVk7QUFFekUsUUFBTSxPQUFPLEtBQUssTUFBTSxLQUFLLE9BQU8sSUFBSSxFQUFFO0FBRzFDLFFBQU0sU0FBUyxLQUFLLE1BQU0sS0FBSyxPQUFPLElBQUksRUFBRTtBQUc1QyxRQUFNLFNBQVMsS0FBSyxNQUFNLEtBQUssT0FBTyxJQUFJLEVBQUU7QUFFNUMsU0FBTyxHQUFHLE9BQU8sS0FBSyxNQUFNLEVBQUUsR0FBRyxJQUFJLElBQUksU0FBUyxLQUFLLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFDdEUsU0FBUyxLQUFLLE1BQU0sRUFDdEIsR0FBRyxNQUFNO0FBQ1g7IiwKICAibmFtZXMiOiBbXQp9Cg==
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2025-03-07 14:58:39
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2025-03-13 14:29:26
|
||||
* @FilePath: \5G-Loading-Bay-Web\mock\utils\apiMock.ts
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
import { failMockApiProps, successMockApiProps } from "../typing";
|
||||
export function fetchMockSuccessFullByOther({
|
||||
data,
|
||||
msg,
|
||||
}): successMockApiProps {
|
||||
// return {
|
||||
// code: 200, // 200 成功
|
||||
// success: true, // true 成功
|
||||
// data: data || null, // mock业务层数据
|
||||
// msg: msg | "ok", // 成功提示
|
||||
// isMock: true // true 标识当前是模拟数据
|
||||
// } as successMockApiProps;
|
||||
const result: successMockApiProps = {
|
||||
code: 200, // 200 成功
|
||||
success: true, // true 成功
|
||||
data: data || null, // mock业务层数据
|
||||
msg: msg as string | "ok", // 成功提示
|
||||
isMock: true, // true 标识当前是模拟数据
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
export function fetchMockFailFullByOther({ data, msg }): failMockApiProps {
|
||||
// return {
|
||||
// code: 599, // 200 成功
|
||||
// success: true, // true 成功
|
||||
// data: data || null, // mock业务层数据
|
||||
// msg: msg | "fail", // 成功提示
|
||||
// isMock: true // true 标识当前是模拟数据
|
||||
// } as failMockApiProps;
|
||||
const result: failMockApiProps = {
|
||||
code: 599, // 200 成功
|
||||
success: false, // true 成功
|
||||
data: data || null, // mock业务层数据
|
||||
msg: msg as string | "fail", // 成功提示
|
||||
isMock: true, // true 标识当前是模拟数据
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
// 分页展示
|
||||
export function fetchCurrPageByList({ data }): successMockApiProps {
|
||||
// console.log("fetchCurrPageByList_data", data);
|
||||
const { current, pageSize } = data;
|
||||
const prevPage = current - 1;
|
||||
const currPageData = {
|
||||
...data,
|
||||
data: data.data.slice(prevPage * pageSize, current * pageSize),
|
||||
};
|
||||
return fetchMockSuccessFullByOther({ data: currPageData });
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "data-dashboard",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "cross-env NODE_ENV=development vite",
|
||||
"prod": "vite --mode production",
|
||||
"build": "cross-env NODE_ENV=production vite build",
|
||||
"build:dev": "vite build --mode development",
|
||||
"build:prod": "vite build --mode production",
|
||||
"preview": "vite preview --port 5050",
|
||||
"preview:prod": "vite preview --port 6060 --mode production"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/three": "^0.175.0",
|
||||
"axios": "^1.8.3",
|
||||
"echarts": "^5.6.0",
|
||||
"exceljs": "^4.4.0",
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.30.1",
|
||||
"postcss-scss": "^4.0.9",
|
||||
"sass": "^1.85.1",
|
||||
"swiper": "^11.2.5",
|
||||
"three": "^0.175.0",
|
||||
"unplugin-auto-import": "^19.1.1",
|
||||
"video.js": "^8.22.0",
|
||||
"vue": "^3.5.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/postcss": "^4.0.10",
|
||||
"@types/echarts": "^5.0.0",
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"@vitejs/plugin-vue-jsx": "^4.1.1",
|
||||
"@vue/tsconfig": "^0.7.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"cross-env": "^7.0.3",
|
||||
"element-plus": "^2.9.5",
|
||||
"mockjs": "^1.1.0",
|
||||
"pinia": "^3.0.1",
|
||||
"postcss": "^8.5.3",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "~5.7.2",
|
||||
"vite": "^6.2.0",
|
||||
"vite-plugin-mock": "^3.0.2",
|
||||
"vue-router": "^4.5.0",
|
||||
"vue-tsc": "^2.2.4"
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2025-03-06 16:22:19
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2025-03-06 17:07:24
|
||||
* @FilePath: \vite-ai\data-dashboard\postcss.config.js
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
import autoprefixer from 'autoprefixer';
|
||||
import tailwindcss from 'tailwindcss';
|
||||
export default {
|
||||
plugins: [
|
||||
tailwindcss(),
|
||||
autoprefixer()
|
||||
]
|
||||
};
|
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1,381 @@
|
||||
var WebRtcStreamer = (function () {
|
||||
|
||||
/**
|
||||
* Interface with WebRTC-streamer API
|
||||
* @constructor
|
||||
* @param {string} videoElement - id of the video element tag
|
||||
* @param {string} srvurl - url of webrtc-streamer (default is current location)
|
||||
*/
|
||||
var WebRtcStreamer = function WebRtcStreamer(videoElement, srvurl) {
|
||||
if (typeof videoElement === "string") {
|
||||
this.videoElement = document.getElementById(videoElement);
|
||||
} else {
|
||||
this.videoElement = videoElement;
|
||||
}
|
||||
this.srvurl = srvurl || location.protocol + "//" + window.location.hostname + ":" + window.location.port;
|
||||
this.pc = null;
|
||||
|
||||
this.mediaConstraints = {
|
||||
offerToReceiveAudio: true,
|
||||
offerToReceiveVideo: true
|
||||
};
|
||||
|
||||
this.iceServers = null;
|
||||
this.earlyCandidates = [];
|
||||
}
|
||||
|
||||
WebRtcStreamer.prototype._handleHttpErrors = function (response) {
|
||||
if (!response.ok) {
|
||||
throw Error(response.statusText);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect a WebRTC Stream to videoElement
|
||||
* @param {string} videourl - id of WebRTC video stream
|
||||
* @param {string} audiourl - id of WebRTC audio stream
|
||||
* @param {string} options - options of WebRTC call
|
||||
* @param {string} stream - local stream to send
|
||||
* @param {string} prefmime - prefered mime
|
||||
*/
|
||||
WebRtcStreamer.prototype.connect = function (videourl, audiourl, options, localstream, prefmime) {
|
||||
this.disconnect();
|
||||
|
||||
// getIceServers is not already received
|
||||
if (!this.iceServers) {
|
||||
console.log("Get IceServers");
|
||||
|
||||
fetch(this.srvurl + "/api/getIceServers")
|
||||
.then(this._handleHttpErrors)
|
||||
.then((response) => (response.json()))
|
||||
.then((response) => this.onReceiveGetIceServers(response, videourl, audiourl, options, localstream, prefmime))
|
||||
.catch((error) => this.onError("getIceServers " + error))
|
||||
|
||||
} else {
|
||||
this.onReceiveGetIceServers(this.iceServers, videourl, audiourl, options, localstream, prefmime);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect a WebRTC Stream and clear videoElement source
|
||||
*/
|
||||
WebRtcStreamer.prototype.disconnect = function () {
|
||||
if (this.videoElement?.srcObject) {
|
||||
this.videoElement.srcObject.getTracks().forEach(track => {
|
||||
track.stop()
|
||||
this.videoElement.srcObject.removeTrack(track);
|
||||
});
|
||||
}
|
||||
if (this.pc) {
|
||||
fetch(this.srvurl + "/api/hangup?peerid=" + this.pc.peerid)
|
||||
.then(this._handleHttpErrors)
|
||||
.catch((error) => this.onError("hangup " + error))
|
||||
|
||||
|
||||
try {
|
||||
this.pc.close();
|
||||
} catch (e) {
|
||||
console.log("Failure close peer connection:" + e);
|
||||
}
|
||||
this.pc = null;
|
||||
}
|
||||
}
|
||||
|
||||
WebRtcStreamer.prototype.filterPreferredCodec = function (sdp, prefmime) {
|
||||
const lines = sdp.split('\n');
|
||||
const [prefkind, prefcodec] = prefmime.toLowerCase().split('/');
|
||||
let currentMediaType = null;
|
||||
let sdpSections = [];
|
||||
let currentSection = [];
|
||||
|
||||
// Group lines into sections
|
||||
lines.forEach(line => {
|
||||
if (line.startsWith('m=')) {
|
||||
if (currentSection.length) {
|
||||
sdpSections.push(currentSection);
|
||||
}
|
||||
currentSection = [line];
|
||||
} else {
|
||||
currentSection.push(line);
|
||||
}
|
||||
});
|
||||
sdpSections.push(currentSection);
|
||||
|
||||
// Process each section
|
||||
const processedSections = sdpSections.map(section => {
|
||||
const firstLine = section[0];
|
||||
if (!firstLine.startsWith('m=' + prefkind)) {
|
||||
return section.join('\n');
|
||||
}
|
||||
|
||||
// Get payload types for preferred codec
|
||||
const rtpLines = section.filter(line => line.startsWith('a=rtpmap:'));
|
||||
const preferredPayloads = rtpLines
|
||||
.filter(line => line.toLowerCase().includes(prefcodec))
|
||||
.map(line => line.split(':')[1].split(' ')[0]);
|
||||
|
||||
if (preferredPayloads.length === 0) {
|
||||
return section.join('\n');
|
||||
}
|
||||
|
||||
// Modify m= line to only include preferred payloads
|
||||
const mLine = firstLine.split(' ');
|
||||
const newMLine = [...mLine.slice(0, 3), ...preferredPayloads].join(' ');
|
||||
|
||||
// Filter related attributes
|
||||
const filteredLines = section.filter(line => {
|
||||
if (line === firstLine) return false;
|
||||
if (line.startsWith('a=rtpmap:')) {
|
||||
return preferredPayloads.some(payload => line.startsWith(`a=rtpmap:${payload}`));
|
||||
}
|
||||
if (line.startsWith('a=fmtp:') || line.startsWith('a=rtcp-fb:')) {
|
||||
return preferredPayloads.some(payload => line.startsWith(`a=${line.split(':')[0].split('a=')[1]}:${payload}`));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
return [newMLine, ...filteredLines].join('\n');
|
||||
});
|
||||
|
||||
return processedSections.join('\n');
|
||||
}
|
||||
|
||||
/*
|
||||
* GetIceServers callback
|
||||
*/
|
||||
WebRtcStreamer.prototype.onReceiveGetIceServers = function (iceServers, videourl, audiourl, options, stream, prefmime) {
|
||||
this.iceServers = iceServers;
|
||||
this.pcConfig = iceServers || {
|
||||
"iceServers": []
|
||||
};
|
||||
try {
|
||||
this.createPeerConnection();
|
||||
|
||||
let callurl = this.srvurl + "/api/call?peerid=" + this.pc.peerid + "&url=" + encodeURIComponent(videourl);
|
||||
if (audiourl) {
|
||||
callurl += "&audiourl=" + encodeURIComponent(audiourl);
|
||||
}
|
||||
if (options) {
|
||||
callurl += "&options=" + encodeURIComponent(options);
|
||||
}
|
||||
|
||||
if (stream) {
|
||||
this.pc.addStream(stream);
|
||||
}
|
||||
|
||||
// clear early candidates
|
||||
this.earlyCandidates.length = 0;
|
||||
|
||||
// create Offer
|
||||
this.pc.createOffer(this.mediaConstraints).then((sessionDescription) => {
|
||||
console.log("Create offer:" + JSON.stringify(sessionDescription));
|
||||
|
||||
console.log(`video codecs:${Array.from(new Set(RTCRtpReceiver.getCapabilities("video")?.codecs?.map(codec => codec.mimeType)))}`)
|
||||
console.log(`audio codecs:${Array.from(new Set(RTCRtpReceiver.getCapabilities("audio")?.codecs?.map(codec => codec.mimeType)))}`)
|
||||
|
||||
if (prefmime != undefined) {
|
||||
//set prefered codec
|
||||
let [prefkind] = prefmime.split('/');
|
||||
if (prefkind != "video" && prefkind != "audio") {
|
||||
prefkind = "video";
|
||||
prefmime = prefkind + "/" + prefmime;
|
||||
}
|
||||
console.log("sdp:" + sessionDescription.sdp);
|
||||
sessionDescription.sdp = this.filterPreferredCodec(sessionDescription.sdp, prefmime);
|
||||
console.log("sdp:" + sessionDescription.sdp);
|
||||
}
|
||||
|
||||
|
||||
this.pc.setLocalDescription(sessionDescription)
|
||||
.then(() => {
|
||||
fetch(callurl, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(sessionDescription)
|
||||
})
|
||||
.then(this._handleHttpErrors)
|
||||
.then((response) => (response.json()))
|
||||
.catch((error) => this.onError("call " + error))
|
||||
.then((response) => this.onReceiveCall(response))
|
||||
.catch((error) => this.onError("call " + error))
|
||||
|
||||
}, (error) => {
|
||||
console.log("setLocalDescription error:" + JSON.stringify(error));
|
||||
});
|
||||
|
||||
}, (error) => {
|
||||
alert("Create offer error:" + JSON.stringify(error));
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
this.disconnect();
|
||||
alert("connect error: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WebRtcStreamer.prototype.getIceCandidate = function () {
|
||||
fetch(this.srvurl + "/api/getIceCandidate?peerid=" + this.pc.peerid)
|
||||
.then(this._handleHttpErrors)
|
||||
.then((response) => (response.json()))
|
||||
.then((response) => this.onReceiveCandidate(response))
|
||||
.catch((error) => this.onError("getIceCandidate " + error))
|
||||
}
|
||||
|
||||
/*
|
||||
* create RTCPeerConnection
|
||||
*/
|
||||
WebRtcStreamer.prototype.createPeerConnection = function () {
|
||||
console.log("createPeerConnection config: " + JSON.stringify(this.pcConfig));
|
||||
this.pc = new RTCPeerConnection(this.pcConfig);
|
||||
let pc = this.pc;
|
||||
pc.peerid = Math.random();
|
||||
|
||||
pc.onicecandidate = (evt) => this.onIceCandidate(evt);
|
||||
pc.onaddstream = (evt) => this.onAddStream(evt);
|
||||
pc.oniceconnectionstatechange = (evt) => {
|
||||
console.log("oniceconnectionstatechange state: " + pc.iceConnectionState);
|
||||
if (this.videoElement) {
|
||||
if (pc.iceConnectionState === "connected") {
|
||||
this.videoElement.style.opacity = "1.0";
|
||||
} else if (pc.iceConnectionState === "disconnected") {
|
||||
this.videoElement.style.opacity = "0.25";
|
||||
} else if ((pc.iceConnectionState === "failed") || (pc.iceConnectionState === "closed")) {
|
||||
this.videoElement.style.opacity = "0.5";
|
||||
} else if (pc.iceConnectionState === "new") {
|
||||
this.getIceCandidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
pc.ondatachannel = function (evt) {
|
||||
console.log("remote datachannel created:" + JSON.stringify(evt));
|
||||
|
||||
evt.channel.onopen = function () {
|
||||
console.log("remote datachannel open");
|
||||
this.send("remote channel openned");
|
||||
}
|
||||
evt.channel.onmessage = function (event) {
|
||||
console.log("remote datachannel recv:" + JSON.stringify(event.data));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
let dataChannel = pc.createDataChannel("ClientDataChannel");
|
||||
dataChannel.onopen = function () {
|
||||
console.log("local datachannel open");
|
||||
this.send("local channel openned");
|
||||
}
|
||||
dataChannel.onmessage = function (evt) {
|
||||
console.log("local datachannel recv:" + JSON.stringify(evt.data));
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Cannor create datachannel error: " + e);
|
||||
}
|
||||
|
||||
console.log("Created RTCPeerConnnection with config: " + JSON.stringify(this.pcConfig));
|
||||
return pc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RTCPeerConnection IceCandidate callback
|
||||
*/
|
||||
WebRtcStreamer.prototype.onIceCandidate = function (event) {
|
||||
if (event.candidate) {
|
||||
if (this.pc.currentRemoteDescription) {
|
||||
this.addIceCandidate(this.pc.peerid, event.candidate);
|
||||
} else {
|
||||
this.earlyCandidates.push(event.candidate);
|
||||
}
|
||||
} else {
|
||||
console.log("End of candidates.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WebRtcStreamer.prototype.addIceCandidate = function (peerid, candidate) {
|
||||
fetch(this.srvurl + "/api/addIceCandidate?peerid=" + peerid, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(candidate)
|
||||
})
|
||||
.then(this._handleHttpErrors)
|
||||
.then((response) => (response.json()))
|
||||
.then((response) => {
|
||||
console.log("addIceCandidate ok:" + response)
|
||||
})
|
||||
.catch((error) => this.onError("addIceCandidate " + error))
|
||||
}
|
||||
|
||||
/*
|
||||
* RTCPeerConnection AddTrack callback
|
||||
*/
|
||||
WebRtcStreamer.prototype.onAddStream = function (event) {
|
||||
console.log("Remote track added:" + JSON.stringify(event));
|
||||
|
||||
this.videoElement.srcObject = event.stream;
|
||||
let promise = this.videoElement.play();
|
||||
if (promise !== undefined) {
|
||||
promise.catch((error) => {
|
||||
console.warn("error:" + error);
|
||||
this.videoElement.setAttribute("controls", true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* AJAX /call callback
|
||||
*/
|
||||
WebRtcStreamer.prototype.onReceiveCall = function (dataJson) {
|
||||
|
||||
console.log("offer: " + JSON.stringify(dataJson));
|
||||
let descr = new RTCSessionDescription(dataJson);
|
||||
this.pc.setRemoteDescription(descr).then(() => {
|
||||
console.log("setRemoteDescription ok");
|
||||
while (this.earlyCandidates.length) {
|
||||
let candidate = this.earlyCandidates.shift();
|
||||
this.addIceCandidate(this.pc.peerid, candidate);
|
||||
}
|
||||
|
||||
this.getIceCandidate()
|
||||
}, (error) => {
|
||||
console.log("setRemoteDescription error:" + JSON.stringify(error));
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* AJAX /getIceCandidate callback
|
||||
*/
|
||||
WebRtcStreamer.prototype.onReceiveCandidate = function (dataJson) {
|
||||
console.log("candidate: " + JSON.stringify(dataJson));
|
||||
if (dataJson) {
|
||||
for (let i = 0; i < dataJson.length; i++) {
|
||||
let candidate = new RTCIceCandidate(dataJson[i]);
|
||||
|
||||
console.log("Adding ICE candidate :" + JSON.stringify(candidate));
|
||||
this.pc.addIceCandidate(candidate).then(() => {
|
||||
console.log("addIceCandidate OK");
|
||||
}, (error) => {
|
||||
console.log("addIceCandidate error:" + JSON.stringify(error));
|
||||
});
|
||||
}
|
||||
this.pc.addIceCandidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* AJAX callback for Error
|
||||
*/
|
||||
WebRtcStreamer.prototype.onError = function (status) {
|
||||
console.log("onError:" + status);
|
||||
}
|
||||
|
||||
return WebRtcStreamer;
|
||||
})();
|
||||
|
||||
if (typeof window !== 'undefined' && typeof window.document !== 'undefined') {
|
||||
window.WebRtcStreamer = WebRtcStreamer;
|
||||
}
|
||||
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||||
module.exports = WebRtcStreamer;
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2025-03-07 15:09:18
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2025-03-14 11:14:15
|
||||
* @FilePath: \5G-Loading-Bay-Web\src\api\dashboard.ts
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
// 接口层
|
||||
|
||||
import request from "@/utils/request/instance";
|
||||
import { config } from "@/config";
|
||||
|
||||
//TODO 定义响应类型
|
||||
|
||||
export const getDeviceStatusApi = (params: any) => {
|
||||
return request.get(`/api/v1/device/device/`, params);
|
||||
};
|
||||
|
||||
// 撑杆检测
|
||||
export const getAppearanceMonitorApi = (params: any) => {
|
||||
return request.get(`/api/v1/record/record/`, params);
|
||||
};
|
||||
|
||||
// 删除检测
|
||||
export const deleteAppearanceMonitorApi = (data: any) => {
|
||||
return request.delete(`/api/v1/record/record/${data.id}/`, data);
|
||||
};
|
||||
|
||||
// 撑杆检测详情
|
||||
export const getAppearanceMonitorDetailApi = (params: any) => {
|
||||
return request.get(`/api/v1/record/record_detail_list/`, params);
|
||||
};
|
||||
|
||||
// 检测总量
|
||||
export const getDataOverviewApi = (params: any) => {
|
||||
return request.get(`/api/v1/system/get_record_stats/`, params);
|
||||
};
|
||||
|
||||
// 设备信息数据
|
||||
export const getDeviceInfowApi = () => {
|
||||
return request.get(`/api/v1/system/get_device_stats/`);
|
||||
};
|
||||
|
||||
// 检测问题分布数据
|
||||
export const getRecordFaultApi = (params: any) => {
|
||||
return request.get(`/api/v1/system/get_record_fault_stats/`, params);
|
||||
};
|
||||
|
||||
// 获取实时监控
|
||||
export const getRealTimeApi = () => {
|
||||
return request.get(`/api/v1/record/get_latest_second_records/`);
|
||||
};
|
||||
|
||||
// 设备状态打开实时监控
|
||||
export const playRtspApi = (data: { url: string }) => {
|
||||
return request.post<LoginRes>(`/api/v1/common/play_rtsp/`, data, {
|
||||
showLoading: false, // 单独关闭loading
|
||||
});
|
||||
};
|
||||
|
||||
// {
|
||||
// "code": 200,
|
||||
// "success": true,
|
||||
// "data": {
|
||||
// "process_id": 23432,
|
||||
// "host": "192.168.10.14:7001"
|
||||
// },
|
||||
// "errorMessage": ""
|
||||
// }
|
||||
|
||||
// 设备状态关闭实时监控
|
||||
export const stopRtspApi = (data: { process_id: string | number }) => {
|
||||
return request.post<LoginRes>(`/api/v1/common/stop_rtsp/`, data, {
|
||||
showLoading: false, // 单独关闭loading
|
||||
});
|
||||
};
|
||||
|
||||
// 根据设备 ID 查询历史视频列表,支持日期时间过滤
|
||||
export const getDeviceHistoryDetailApi = (params: {
|
||||
device_id: string | number;
|
||||
start_time: string;
|
||||
end_time: string;
|
||||
}) => {
|
||||
return request.get(`/api/v1/device/device_history/`, params);
|
||||
};
|
||||
|
||||
// 车辆管理
|
||||
export const getVehiclManagementApi = (params: any) => {
|
||||
return request.get(`/api/v1/record/train_record/`, params);
|
||||
};
|
||||
|
||||
// 外观检测故障前详情
|
||||
export const getBeforeMonitorDetailApi = (params: any) => {
|
||||
return request.get(`/api/v1/record/before_arrive_record_list/`, params);
|
||||
};
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2025-03-12 15:13:38
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2025-03-13 09:29:20
|
||||
* @FilePath: \5G-Loading-Bay-Web\src\api\user.ts
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
import request from '@/utils/request/instance'
|
||||
import { config } from '@/config'
|
||||
|
||||
// 定义响应类型
|
||||
interface LoginRes {
|
||||
token: string
|
||||
userInfo: {
|
||||
id: number
|
||||
username: string
|
||||
}
|
||||
}
|
||||
|
||||
export const loginApi = (data: { username: string; password: string }) => {
|
||||
return request.post<LoginRes>(`/api/v1/user/login/`, data, {
|
||||
showLoading: false // 单独关闭loading
|
||||
})
|
||||
}
|
||||
|
||||
export const loginOutApi = () => {
|
||||
return request.post(`/api/v1/user/logout/`, {}, {
|
||||
showLoading: false // 单独关闭loading
|
||||
})
|
||||
}
|
||||
// export const getUserInfo = (userId: number) => {
|
||||
// return request.get(`/user/info/${userId}`)
|
||||
// }
|
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 342 KiB |
After Width: | Height: | Size: 800 KiB |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 225 KiB |
After Width: | Height: | Size: 194 KiB |
After Width: | Height: | Size: 400 KiB |
After Width: | Height: | Size: 352 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 142 KiB |
After Width: | Height: | Size: 317 KiB |
After Width: | Height: | Size: 713 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 248 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 855 B |
After Width: | Height: | Size: 488 B |
After Width: | Height: | Size: 112 KiB |
After Width: | Height: | Size: 106 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 915 B |
After Width: | Height: | Size: 711 B |
After Width: | Height: | Size: 876 B |
After Width: | Height: | Size: 922 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 955 B |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 420 B |
After Width: | Height: | Size: 468 B |
@ -0,0 +1,26 @@
|
||||
<svg width="42" height="34" viewBox="0 0 42 34" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_ii_9562_48037)">
|
||||
<path d="M38.582 32.8229H3.93728L1.25977 30.6782V24.4139L2.7611 23.2867L2.78615 10.4887L1.25977 9.26178V3.0673L3.93728 0.932617H38.582L41.2595 3.0673V30.6782L38.582 32.8229Z" fill="#009DFF" fill-opacity="0.1"/>
|
||||
</g>
|
||||
<path opacity="0.6" d="M38.3222 33H3.67751L1 30.848V24.562L2.50134 23.431L2.52638 10.589L1 9.35782V3.14202L3.67751 1H38.3222L40.9997 3.14202V30.848L38.3222 33Z" stroke="#009DFF" stroke-width="0.58" stroke-miterlimit="10"/>
|
||||
<path d="M21 15C22.933 15 24.5 13.433 24.5 11.5C24.5 9.56701 22.933 8 21 8C19.067 8 17.5 9.56701 17.5 11.5C17.5 13.433 19.067 15 21 15Z" fill="#009DFF" stroke="#009DFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M12 25.4V26H30V25.4C30 23.1598 30 22.0397 29.5641 21.184C29.1806 20.4314 28.5686 19.8195 27.816 19.436C26.9603 19 25.8402 19 23.6 19H18.4C16.1598 19 15.0397 19 14.1841 19.436C13.4314 19.8195 12.8195 20.4314 12.436 21.184C12 22.0397 12 23.1598 12 25.4Z" fill="#009DFF" stroke="#009DFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<defs>
|
||||
<filter id="filter0_ii_9562_48037" x="1.25977" y="-1.06738" width="39.9995" height="35.8904" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="2"/>
|
||||
<feGaussianBlur stdDeviation="2"/>
|
||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.0361115 0 0 0 0 0.4795 0 0 0 0 1 0 0 0 0.4 0"/>
|
||||
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_9562_48037"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="-2"/>
|
||||
<feGaussianBlur stdDeviation="2"/>
|
||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.0352941 0 0 0 0 0.478431 0 0 0 0 1 0 0 0 0.4 0"/>
|
||||
<feBlend mode="normal" in2="effect1_innerShadow_9562_48037" result="effect2_innerShadow_9562_48037"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 563 B |
After Width: | Height: | Size: 208 KiB |
After Width: | Height: | Size: 112 KiB |
After Width: | Height: | Size: 189 KiB |