diff --git a/public/serverConfig.json b/public/serverConfig.json
index aec550f..8bb2c29 100644
--- a/public/serverConfig.json
+++ b/public/serverConfig.json
@@ -19,5 +19,5 @@
   "CachingAsyncRoutes": false,
   "TooltipEffect": "light",
   "ResponsiveStorageNameSpace": "responsive-",
-  "AdminHostUrl": "http://192.168.10.81:8848/"
+  "AdminHostUrl": "http://192.168.10.13:8000"
 }
diff --git a/src/api/utils.ts b/src/api/utils.ts
index 2f0d1a1..98ade66 100644
--- a/src/api/utils.ts
+++ b/src/api/utils.ts
@@ -1,2 +1,4 @@
 const { VITE_APP_BASE_URL } = import.meta.env;
-export const baseUrlApi = (url: string) => `${VITE_APP_BASE_URL}/api/${url}`;
+import { getConfig } from "@/config";
+export const baseUrlApi = (url: string) =>
+  `${getConfig().AdminHostUrl || VITE_APP_BASE_URL}/api/${url}`;
diff --git a/src/api/videoParse.ts b/src/api/videoParse.ts
new file mode 100644
index 0000000..07ad0f2
--- /dev/null
+++ b/src/api/videoParse.ts
@@ -0,0 +1,24 @@
+import { http } from "@/utils/http";
+import { baseUrlApi } from "./utils";
+
+type Result = {
+  msg: any;
+  success: boolean;
+  data?: {
+    person?: Array<any>;
+    car?: Array<any>;
+  };
+};
+type Data = {
+  success: boolean;
+  msg: any;
+  count: number;
+  results?: Array<any>;
+};
+
+export const getPicList = (params?: object) => {
+  return http.request<Result>("get", baseUrlApi("tps/pics"), { params });
+};
+export const getTPList = (params?: object) => {
+  return http.request<Data>("get", baseUrlApi("tps"), { params });
+};
diff --git a/src/router/modules/videoParse.ts b/src/router/modules/videoParse.ts
new file mode 100644
index 0000000..c17e2e3
--- /dev/null
+++ b/src/router/modules/videoParse.ts
@@ -0,0 +1,20 @@
+export default {
+  path: "/videoParse",
+  // redirect: "/error/403",
+  meta: {
+    icon: "lollipop",
+    title: "视频分析",
+    showLink: true,
+    rank: 10
+  },
+  children: [
+    {
+      path: "/videoParse/index",
+      name: "VideoParsePage",
+      component: () => import("@/views/videoParse/index.vue"),
+      meta: {
+        title: "视频分析"
+      }
+    }
+  ]
+} as RouteConfigsTable;
diff --git a/src/views/videoParse/hook.tsx b/src/views/videoParse/hook.tsx
new file mode 100644
index 0000000..e53dddd
--- /dev/null
+++ b/src/views/videoParse/hook.tsx
@@ -0,0 +1,77 @@
+import { addDialog } from "@/components/ReDialog";
+// import { ref, h } from "vue";
+import OurPlayer from "@/components/VideoPlayer/OurPlayer.vue";
+// import { http } from "@/utils/http";
+
+export function videoUtil() {
+  // const currentPlayingIndex = ref(-1);
+  const columns: TableColumnList = [
+    {
+      label: "视频内时间",
+      prop: "relative_time",
+      minWidth: 100,
+      sortable: true
+    },
+    {
+      label: "异常类型",
+      prop: "exception_type",
+      minWidth: 100
+    },
+    {
+      label: "异常ID",
+      prop: "abnormal_id",
+      minWidth: 100
+    },
+    {
+      label: "异常行为",
+      prop: "abnormal_behavior",
+      minWidth: 100,
+      slot: "violation"
+    },
+    {
+      label: "异常关键帧",
+      slot: "image"
+    },
+    {
+      label: "异常视频定位",
+      slot: "video"
+    }
+    // {
+    //   label: "视频",
+    //   slot: "video"
+    // },
+  ];
+  function openDialog(title = "视频", row) {
+    const highlights = [
+      // 进度条时间点高亮
+      {
+        text: row.event_type,
+        time: row.relative_time
+      }
+    ];
+    sessionStorage.setItem("video_url", row.abnormal_video);
+    sessionStorage.setItem("highlights", JSON.stringify(highlights));
+    addDialog({
+      title: `${title}用户`,
+      width: "40%",
+      draggable: true,
+      fullscreenIcon: true,
+      closeOnClickModal: false,
+      contentRenderer: () => <OurPlayer></OurPlayer>
+      // return h(
+      //   "video",
+      //   {
+      //     controls: true,
+      //     id: "video-" + index,
+      //     onPlay: () => playVideo(row, index)
+      //   },
+      //   [h("source", { src: row.video_dir, type: "video/mp4" })]
+      // );
+    });
+  }
+
+  return {
+    columns,
+    openDialog
+  };
+}
diff --git a/src/views/videoParse/index.vue b/src/views/videoParse/index.vue
new file mode 100644
index 0000000..ba98cea
--- /dev/null
+++ b/src/views/videoParse/index.vue
@@ -0,0 +1,454 @@
+<script setup lang="ts">
+import { useWindowSize } from "@vueuse/core";
+import { Help } from "@element-plus/icons-vue";
+import { ref, reactive, onMounted } from "vue";
+import { PureTableBar } from "@/components/RePureTableBar";
+import { PureTable } from "@pureadmin/table";
+import { type PaginationProps } from "@pureadmin/table";
+import { getPicList, getTPList } from "@/api/videoParse";
+import { getToken } from "@/utils/auth";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { videoUtil } from "./hook";
+
+import type { UploadProps, UploadUserFile } from "element-plus";
+
+defineOptions({
+  name: "videoParse"
+});
+const { columns, openDialog } = videoUtil();
+const fileList = ref<UploadUserFile[]>([
+  {
+    name: "element-plus-logo.svg",
+    url: "https://element-plus.org/images/element-plus-logo.svg"
+  }
+]);
+
+const handleRemove: UploadProps["onRemove"] = (file, uploadFiles) => {
+  console.log(file, uploadFiles);
+};
+
+const handlePreview: UploadProps["onPreview"] = uploadFile => {
+  console.log(uploadFile);
+};
+
+const handleExceed: UploadProps["onExceed"] = (files, uploadFiles) => {
+  ElMessage.warning(
+    `The limit is 3, you selected ${files.length} files this time, add up to ${
+      files.length + uploadFiles.length
+    } totally`
+  );
+};
+
+const beforeRemove: UploadProps["beforeRemove"] = uploadFile => {
+  return ElMessageBox.confirm(
+    `Cancel the transfer of ${uploadFile.name} ?`
+  ).then(
+    () => true,
+    () => false
+  );
+};
+const { height } = useWindowSize();
+
+const videoData = ref([]);
+const loading = ref(true);
+const currentPage = ref(1);
+const totalNumber = ref(0);
+const pageSize = ref(10);
+// const isDisplay = true;
+const pagination = reactive<PaginationProps>({
+  total: totalNumber.value,
+  pageSize: pageSize.value,
+  currentPage: currentPage.value,
+  background: true
+});
+const personOddList = ref([]);
+const personEvenList = ref([]);
+const carOddList = ref([]);
+const carEvenList = ref([]);
+
+function handleUpdate(row) {
+  openDialog("我的", row);
+  console.log(row);
+}
+function handleSizeChange(val) {
+  pageSize.value = val;
+  onSearch();
+}
+
+function handleCurrentChange(val) {
+  currentPage.value = val;
+  onSearch();
+}
+function onSearch() {
+  const params = {
+    video_name: "test1",
+    page: currentPage.value || undefined,
+    page_size: pageSize.value || undefined
+  };
+  getTPList(params).then(response => {
+    if (response.success) {
+      const dataList = response;
+      totalNumber.value = dataList.count;
+      pagination.total = dataList.count;
+      videoData.value = dataList.results;
+      setTimeout(() => {
+        loading.value = false;
+      }, 500);
+    }
+  });
+  getPicList(params).then(response => {
+    if (response.success) {
+      const dataList = response;
+      personOddList.value = dataList.data.person.filter(
+        item => item.id % 2 == 1
+      );
+      personEvenList.value = dataList.data.person.filter(
+        item => item.id % 2 == 0
+      );
+      carOddList.value = dataList.data.car.filter(item => item.id % 2 == 1);
+      carEvenList.value = dataList.data.car.filter(item => item.id % 2 == 0);
+      setTimeout(() => {
+        loading.value = false;
+      }, 500);
+    }
+  });
+}
+
+function spanStyle(type) {
+  switch (type) {
+    case 1:
+      return "span-first";
+    case 2:
+      return "span-second";
+    case 3:
+      return "span-third";
+    default:
+      "";
+      break;
+  }
+}
+onMounted(() => {
+  onSearch();
+});
+</script>
+
+<template>
+  <div class="main">
+    <el-row :gutter="24">
+      <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+        <el-card
+          class="box-card"
+          :style="{ height: `calc(${height}px - 150px)` }"
+        >
+          <template #header>
+            <div class="card-header">
+              <span>视频分析</span>
+            </div>
+          </template>
+          <div class="file-upload flex justify-around">
+            <div class="upload-box">
+              <el-upload
+                v-model:file-list="fileList"
+                class="upload"
+                :headers="{ token: 'Bearer ' + getToken().accessToken }"
+                action="http://192.168.10.13:8000/api/tps/upload_video"
+                multiple
+                :on-preview="handlePreview"
+                :on-remove="handleRemove"
+                :before-remove="beforeRemove"
+                :limit="1"
+                :on-exceed="handleExceed"
+              >
+                <span>{{ "选择分析文件" }}</span
+                ><el-button type="primary">选择文件</el-button>
+                <!-- <template #tip>
+                <div class="el-upload__tip">
+                  jpg/png files with a size less than 500KB.
+                </div>
+              </template> -->
+              </el-upload>
+            </div>
+            <el-button type="success" size="large">
+              分析 <el-icon class="el-icon--right"><Help /></el-icon
+            ></el-button>
+          </div>
+          <el-divider border-style="dashed" />
+          <!-- <el-empty description="暂无数据" v-show="videoData.length == 0" /> -->
+          <div class="analysis-content flex justify-between">
+            <div
+              class="analysis-box"
+              :style="{ height: `calc(${height}px - 60vh - 150px)` }"
+            >
+              <span class="analysis-box-label">被执法人员推定</span>
+              <div
+                class="analysis-table"
+                :style="{ height: `calc(${height}px - 60vh - 240px)` }"
+              >
+                <div class="analysis-table-left">
+                  <div class="analysis-box-lable w-full flex justify-end">
+                    <span>目标清晰度</span>
+                  </div>
+                  <el-scrollbar :height="`calc(${height}px - 60vh - 220px)`">
+                    <div
+                      v-for="(item, index) in personOddList"
+                      :key="index"
+                      class="scrollbar-item"
+                    >
+                      <span :class="spanStyle(item.id)">{{ item.id }}</span>
+                      <el-image
+                        style="height: 100px"
+                        :src="item.pic_path"
+                        :zoom-rate="1.2"
+                        :preview-src-list="[item.pic_path]"
+                        fit="cover"
+                      />
+                      <span>{{ item.pic_quality }}</span>
+                    </div>
+                  </el-scrollbar>
+                </div>
+                <el-divider
+                  direction="vertical"
+                  :style="{ height: `calc(${height}px - 60vh - 220px)` }"
+                />
+                <div class="analysis-table-left">
+                  <div class="analysis-box-lable w-full flex justify-end">
+                    <span>目标清晰度</span>
+                  </div>
+                  <el-scrollbar :height="`calc(${height}px - 60vh - 220px)`">
+                    <div
+                      v-for="(item, index) in personEvenList"
+                      :key="index"
+                      class="scrollbar-item"
+                    >
+                      <span :class="spanStyle(item.id)">{{ item.id }}</span>
+                      <el-image
+                        style="height: 100px"
+                        :src="item.pic_path"
+                        :zoom-rate="1.2"
+                        :preview-src-list="[item.pic_path]"
+                        fit="cover"
+                      />
+                      <span>{{ item.pic_quality }}</span>
+                    </div>
+                  </el-scrollbar>
+                </div>
+              </div>
+            </div>
+            <div
+              class="analysis-box"
+              :style="{ height: `calc(${height}px - 60vh - 150px)` }"
+            >
+              <span class="analysis-box-label">被执法车辆推定</span>
+              <div
+                class="analysis-table"
+                :style="{ height: `calc(${height}px - 60vh - 240px)` }"
+              >
+                <div class="analysis-table-left">
+                  <div class="analysis-box-lable w-full flex justify-end">
+                    <span>目标清晰度</span>
+                  </div>
+                  <el-scrollbar :height="`calc(${height}px - 60vh - 220px)`">
+                    <div
+                      v-for="item in carOddList"
+                      :key="item.id"
+                      class="scrollbar-item"
+                    >
+                      <span :class="spanStyle(item.id)">{{ item.id }}</span>
+                      <div class="defect-image">
+                        <el-image
+                          style="height: 100px"
+                          :src="item.pic_path"
+                          :zoom-rate="1.2"
+                          :preview-src-list="[item.pic_path]"
+                          fit="cover"
+                        />
+                        <span>{{ item.car_number }}</span>
+                      </div>
+                      <span>{{ item.pic_quality }}</span>
+                    </div>
+                  </el-scrollbar>
+                </div>
+                <el-divider
+                  direction="vertical"
+                  :style="{ height: `calc(${height}px - 60vh - 240px)` }"
+                />
+                <div class="analysis-table-left">
+                  <div class="analysis-box-lable w-full flex justify-end">
+                    <span>目标清晰度</span>
+                  </div>
+                  <el-scrollbar :height="`calc(${height}px - 60vh - 220px)`">
+                    <div
+                      v-for="item in carEvenList"
+                      :key="item.id"
+                      class="scrollbar-item"
+                    >
+                      <span :class="spanStyle(item.id)">{{ item.id }}</span>
+                      <div class="defect-image">
+                        <el-image
+                          style="height: 100px"
+                          :src="item.pic_path"
+                          :zoom-rate="1.2"
+                          :preview-src-list="[item.pic_path]"
+                          fit="cover"
+                        />
+                        <span>{{ item.car_number }}</span>
+                      </div>
+                      <span>{{ item.pic_quality }}</span>
+                    </div>
+                  </el-scrollbar>
+                </div>
+              </div>
+            </div>
+          </div>
+          <PureTableBar
+            title="视频分析列表"
+            :columns="columns"
+            @refresh="onSearch"
+          >
+            <template v-slot="{ size, dynamicColumns }">
+              <pure-table
+                border
+                adaptive
+                align-whole="center"
+                table-layout="auto"
+                :loading="loading"
+                :size="size"
+                :data="videoData"
+                :columns="dynamicColumns"
+                :pagination="pagination"
+                :paginationSmall="size === 'small' ? true : false"
+                :header-cell-style="{
+                  background: 'var(--el-table-row-hover-bg-color)',
+                  color: 'var(--el-text-color-primary)'
+                }"
+                @page-size-change="handleSizeChange"
+                @page-current-change="handleCurrentChange"
+              >
+                <template #violation="{ row }">
+                  {{ row.is_violation ? "是" : "否" }}
+                </template>
+                <template #image="{ row, index }">
+                  <el-image
+                    preview-teleported
+                    loading="lazy"
+                    :src="row.abnormal_pic"
+                    :preview-src-list="[row.abnormal_pic]"
+                    :initial-index="index"
+                    fit="cover"
+                    class="w-[100px] h-[100px]"
+                  />
+                </template>
+                <template #video="{ row }">
+                  <el-button
+                    class="reset-margin"
+                    link
+                    type="primary"
+                    :size="size"
+                    @click="handleUpdate(row)"
+                  >
+                    播放视频
+                  </el-button>
+                </template>
+              </pure-table>
+            </template>
+          </PureTableBar>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+<style scoped lang="scss">
+.card-header {
+  span {
+    font-weight: bold;
+  }
+}
+
+.file-upload {
+  height: 60px;
+
+  .upload-box {
+    width: 300px;
+
+    .upload {
+      span {
+        margin-right: 10px;
+      }
+    }
+  }
+}
+
+.analysis-content {
+  .analysis-box {
+    width: 48%;
+    padding: 20px;
+    box-shadow: 5px 5px 5px rgb(0 0 0 / 2.5%), 5px -5px 5px rgb(0 0 0 / 2.5%),
+      -5px 5px 5px rgb(0 0 0 / 2.5%), -5px -5px 5px rgb(0 0 0 / 2.5%);
+    // background: skyblue;
+    // height: 400px;
+    .analysis-box-label {
+      font-size: 20px;
+      font-weight: bold;
+    }
+
+    .analysis-table {
+      display: flex;
+      justify-content: space-between;
+      width: 100%;
+
+      .analysis-table-left {
+        width: 45%;
+
+        .analysis-box-lable {
+          padding-right: 10px;
+        }
+
+        .scrollbar-item {
+          display: flex;
+          align-items: center;
+          justify-content: space-around;
+          margin-bottom: 20px;
+
+          .defect-image {
+            position: relative;
+
+            span {
+              position: absolute;
+              bottom: 7px;
+              left: 0;
+              width: 100%;
+              height: 30px;
+              line-height: 30px;
+              color: #fff;
+              text-align: center;
+              background-color: rgb(0 0 0 / 50%);
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+:deep(.analysis-box-line) {
+  height: 320px;
+}
+
+.span-first {
+  font-size: 28px;
+  font-weight: bold;
+  color: #e02828;
+}
+
+.span-second {
+  font-size: 28px;
+  font-weight: bold;
+  color: #e58b03;
+}
+
+.span-third {
+  font-size: 28px;
+  font-weight: bold;
+  color: #516ee0;
+}
+</style>
diff --git a/src/views/welcome/hook.tsx b/src/views/welcome/hook.tsx
index df8554c..d01654c 100644
--- a/src/views/welcome/hook.tsx
+++ b/src/views/welcome/hook.tsx
@@ -1,10 +1,20 @@
 import { addDialog } from "@/components/ReDialog";
-import { ref, h } from "vue";
+// import { ref, h } from "vue";
+import OurPlayer from "@/components/VideoPlayer/OurPlayer.vue";
 // import { http } from "@/utils/http";
 
 export function welcomeUtil() {
-  const currentPlayingIndex = ref(-1);
-  function openDialog(title = "视频", row, index: number) {
+  // const currentPlayingIndex = ref(-1);
+  function openDialog(title = "视频", row) {
+    const highlights = [
+      // 进度条时间点高亮
+      {
+        text: row.event_type,
+        time: row.relative_time
+      }
+    ];
+    sessionStorage.setItem("video_url", row.video_dir);
+    sessionStorage.setItem("highlights", JSON.stringify(highlights));
     console.log(row.video_dir, "row.video_dir");
     addDialog({
       title: `${title}用户`,
@@ -12,28 +22,27 @@ export function welcomeUtil() {
       draggable: true,
       fullscreenIcon: true,
       closeOnClickModal: false,
-      contentRenderer: () => {
-        return h(
-          "video",
-          {
-            controls: true,
-            id: "video-" + index,
-            onPlay: () => playVideo(row, index)
-          },
-          [h("source", { src: row.video_dir, type: "video/mp4" })]
-        );
-      }
+      contentRenderer: () => <OurPlayer></OurPlayer>
+      // return h(
+      //   "video",
+      //   {
+      //     controls: true,
+      //     id: "video-" + index,
+      //     onPlay: () => playVideo(row, index)
+      //   },
+      //   [h("source", { src: row.video_dir, type: "video/mp4" })]
+      // );
     });
   }
-  function playVideo(row, index) {
-    if (currentPlayingIndex.value !== -1) {
-      const videoElement = document.getElementById(
-        "video-" + currentPlayingIndex.value
-      );
-      videoElement.pause(); // 暂停当前正在播放的视频
-    }
-    currentPlayingIndex.value = index;
-  }
+  // function playVideo(row, index) {
+  //   if (currentPlayingIndex.value !== -1) {
+  //     const videoElement = document.getElementById(
+  //       "video-" + currentPlayingIndex.value
+  //     );
+  //     videoElement.pause(); // 暂停当前正在播放的视频
+  //   }
+  //   currentPlayingIndex.value = index;
+  // }
 
   return {
     openDialog
diff --git a/src/views/welcome/index.vue b/src/views/welcome/index.vue
index 507bb54..8886506 100644
--- a/src/views/welcome/index.vue
+++ b/src/views/welcome/index.vue
@@ -44,26 +44,26 @@ const violationMap = ref({
 });
 // const currentPlayingIndex = ref(-1); // 当前正在播放的视频索引,默认为没有视频正在播放
 
-// function playVideo(index) {
-//   // data = JSON.parse(JSON.stringify(data));
-//   // // console.log(AdminHostUrl)
-//   // dialogVisible.value = true;
-//   // const highlights = [
-//   //   // 进度条时间点高亮
-//   //   {
-//   //     text: data.event_type,
-//   //     time: data.relative_time
-//   //   }
-//   // ];
-//   // sessionStorage.setItem("video_url", data.video_dir);
-//   // sessionStorage.setItem("highlights", JSON.stringify(highlights));
-//   if (currentPlayingIndex.value !== -1) {
-//     const videoElement = document.getElementById(
-//       "video-" + currentPlayingIndex.value
-//     );
-//     videoElement.pause(); // 暂停当前正在播放的视频
+// function playVideo(data) {
+// data = JSON.parse(JSON.stringify(data));
+// // console.log(AdminHostUrl)
+// dialogVisible.value = true;
+// const highlights = [
+//   // 进度条时间点高亮
+//   {
+//     text: data.event_type,
+//     time: data.relative_time
 //   }
-//   currentPlayingIndex.value = index;
+// ];
+// sessionStorage.setItem("video_url", data.video_dir);
+// sessionStorage.setItem("highlights", JSON.stringify(highlights));
+// if (currentPlayingIndex.value !== -1) {
+//   const videoElement = document.getElementById(
+//     "video-" + currentPlayingIndex.value
+//   );
+//   videoElement.pause(); // 暂停当前正在播放的视频
+// }
+// currentPlayingIndex.value = index;
 // }
 
 function onSearch() {
@@ -254,8 +254,8 @@ const pagination = reactive<PaginationProps>({
   currentPage: currentPage.value,
   background: true
 });
-function handleUpdate(row, index) {
-  openDialog("我的", row, index);
+function handleUpdate(row) {
+  openDialog("我的", row);
   console.log(row);
 }
 // function handleDelete(row) {
@@ -398,13 +398,13 @@ onMounted(() => {
               <source :src="row.video_dir" type="video/mp4" />
             </video>
           </template> -->
-          <template #operation="{ row, index }">
+          <template #operation="{ row }">
             <el-button
               class="reset-margin"
               link
               type="primary"
               :size="size"
-              @click="handleUpdate(row, index)"
+              @click="handleUpdate(row)"
             >
               播放视频
             </el-button>