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 @@