From ac2085eb4cdee35564daa936be6231faed662ec0 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Thu, 6 Nov 2025 13:29:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E8=A7=86=E9=A2=91=E9=A2=84=E8=A7=88?= =?UTF-8?q?=E5=88=86=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/device/deviceChannel.ts | 14 + .../components/lib/custom/video-custom.js | 126 +++++++++ .../device/components/preview-video/index.vue | 254 ++++++++++++------ .../preview-video/preview-video-dialog.vue | 162 +---------- .../device/components/replay-video/index.vue | 186 ++++++++----- .../replay-video/replay-video-dialog.vue | 126 ++------- src/views/device/deviceCamera/index.vue | 18 +- src/views/device/deviceCameraReplay/index.vue | 3 +- src/views/device/deviceManage/index.vue | 3 +- src/views/door/doorAlarm/index.vue | 4 +- src/views/login/index.vue | 1 - 11 files changed, 474 insertions(+), 423 deletions(-) create mode 100644 src/views/device/components/lib/custom/video-custom.js diff --git a/src/api/device/deviceChannel.ts b/src/api/device/deviceChannel.ts index 0ee1abd..ebeb5c9 100644 --- a/src/api/device/deviceChannel.ts +++ b/src/api/device/deviceChannel.ts @@ -1,5 +1,6 @@ import request from "/@/utils/request" +// 通过deviceCode查询通道列表 export function list(query: any) { return request({ url: '/admin/deviceChannel/list', @@ -8,6 +9,19 @@ export function list(query: any) { }) } +// 通过deviceCode查询通道列表 +export const getChannelPage = (query:any) => { + return request({ + url: '/admin/deviceChannel/panel/getPage', + method: 'post', + data:query, + params: { + current: query.current, + size: query.size, + } + }) +} + export function getReplayList(data: any) { return request({ url: '/admin/deviceChannel/getReplayList', diff --git a/src/views/device/components/lib/custom/video-custom.js b/src/views/device/components/lib/custom/video-custom.js new file mode 100644 index 0000000..de50e24 --- /dev/null +++ b/src/views/device/components/lib/custom/video-custom.js @@ -0,0 +1,126 @@ +const pageDivId = "ws-video-page" + +const rendererPage = (page = 1, pageSize = 10, total = 0, onChange = () => { }) => { + const tpl = document.createElement('template') + tpl.innerHTML = ` +
+
+ `.trim() + const root = tpl.content.firstElementChild + // 初始化分页栏 + mountPagination(root, { total, pageSize, current: page, onChange }) + return root +} + +const createPagination = ({ total = 0, pageSize = 10, current = 1, onChange = (page, pageSize) => { } }) => { + const totalPages = Math.max(1, Math.ceil(total / pageSize)) + const bar = document.createElement('div') + bar.className = 'ws-pagination-bar' + bar.id = 'ws-pagination-bar' + bar.style.cssText = 'display:flex;gap:4px;align-items:center;flex-wrap:wrap;color:#e5e7eb;font-size:11px;' + // 将当前分页状态写入 dataset,事件从 dataset 读取最新值,避免闭包旧值 + bar.dataset.current = String(current) + bar.dataset.pageSize = String(pageSize) + bar.dataset.total = String(total) + bar.dataset.totalPages = String(totalPages) + + const makeBtn = (text, disabled, handler) => { + const btn = document.createElement('button') + btn.textContent = text + btn.disabled = !!disabled + btn.style.cssText = 'padding:2px 6px;border:1px solid #B4BAC2;background:transparent;color:#B4BAC2;border-radius:3px;cursor:pointer;font-size:14px;' + btn.addEventListener('click', handler) + return btn + } + + const prev = makeBtn('上一页', current <= 1, () => { + const cur = Number(bar.dataset.current || 1) + const size = Number(bar.dataset.pageSize || 10) + onChange(Math.max(1, cur - 1), size) + }) + prev.className = 'ws-pagination-prev' + const next = makeBtn('下一页', current >= totalPages, () => { + const cur = Number(bar.dataset.current || 1) + const size = Number(bar.dataset.pageSize || 10) + const tp = Number(bar.dataset.totalPages || 1) + onChange(Math.min(tp, cur + 1), size) + }) + next.className = 'ws-pagination-next' + + const info = document.createElement('span') + info.className = 'ws-pagination-info' + info.textContent = `第${current}/${totalPages}页,共${total}项` + info.style = "font-size:14px;color:#B4BAC2;" + + bar.append(prev, info, next) + return bar +} + +const mountPagination = ($container, { total, pageSize, current, onChange }) => { + // 就地更新,避免闪烁与重复 append + const updateUI = (bar, total, size, cur) => { + const tp = Math.max(1, Math.ceil(total / size)) + // 写入最新状态 + bar.dataset.current = String(cur) + bar.dataset.pageSize = String(size) + bar.dataset.total = String(total) + bar.dataset.totalPages = String(tp) + // 更新文案与禁用状态 + const prevBtn = bar.querySelector('.ws-pagination-prev') + const nextBtn = bar.querySelector('.ws-pagination-next') + const info = bar.querySelector('.ws-pagination-info') + if (prevBtn) prevBtn.disabled = cur <= 1 + if (nextBtn) nextBtn.disabled = cur >= tp + if (info) info.textContent = `第${cur}/${tp}页,共${total}项` + } + + let bar = $container.querySelector('#ws-pagination-bar') + + const handleChange = (page, size = pageSize) => { + updateUI(bar, total, size, page) + // 向外派发事件,便于宿主接收分页变更 + $container.dispatchEvent(new CustomEvent('pagechange', { detail: { page, pageSize: size, total } })) + // 执行外部回调(透传 page 与 pageSize) + if (typeof onChange === 'function') { + onChange(page, size) + } + } + + if (!bar) { + bar = createPagination({ total, pageSize, current, onChange: handleChange }) + $container.appendChild(bar) + } + updateUI(bar, total, pageSize, current) +} + +const clearClss = ($wsControl) => { + const $wsControlEnd = $wsControl.querySelector(".ws-flex.ws-flex-end") + if ($wsControlEnd) { + $wsControlEnd.style = "width: initial;" + } + // 删除$wsControl下面style为flex:1的元素 + const $flex1 = $wsControl.querySelector("[style*='flex: 1']") + if ($flex1) $flex1.remove() +} + +export const rendererVideoPage = (opts = {}) => { + const $wsControl = document.querySelector(".ws-control") + if (!$wsControl) return + clearClss($wsControl) + // 先查找有没有 video-page 元素 + let $page = $wsControl.querySelector(`#${pageDivId}`) + const defaults = { total: 0, pageSize: 10, current: 1, onChange: () => { } } + const params = { ...defaults, ...opts } + if (!$page) { + const node = rendererPage(params.current, params.pageSize, params.total, params.onChange) + if (typeof $wsControl.prepend === 'function') { + $wsControl.prepend(node) + } else { + $wsControl.insertBefore(node, $wsControl.firstChild) + } + $page = node + } else { + // 如果容器已存在,确保分页挂载 + mountPagination($page, params) + } +} \ No newline at end of file diff --git a/src/views/device/components/preview-video/index.vue b/src/views/device/components/preview-video/index.vue index b899808..eef3991 100644 --- a/src/views/device/components/preview-video/index.vue +++ b/src/views/device/components/preview-video/index.vue @@ -5,31 +5,37 @@