Ver código fonte

Merge branch 'master' into 'system-assemble'

# Conflicts:
#   src/views/auth/dept/columns.ts
朱 叠 2 anos atrás
pai
commit
b7190fc7c6

+ 1 - 1
.env.production

@@ -1,5 +1,5 @@
 # 是否开启mock
-VITE_USE_MOCK = true
+VITE_USE_MOCK = false
 
 # 网站根目录
 VITE_PUBLIC_PATH = /

Diferenças do arquivo suprimidas por serem muito extensas
+ 1048 - 166
pnpm-lock.yaml


+ 27 - 0
src/api/algo/algo.ts

@@ -0,0 +1,27 @@
+import { http } from '@/utils/http/axios';
+
+export function getAlgoInfo(page: number, pageSize: number) {
+  return http.request({
+    url: '/cameraAlgo/getList?pageNumber=' + page + '&pageSize=' + pageSize,
+    method: 'get',
+  });
+}
+
+export function searchAlgoInfo(page: number, keyWord: string) {
+  return http.request({
+    url: '/cameraAlgo/getAlgo?algoInfo=' + keyWord + '&pageNumber=' + page + '&pageSize=12',
+    method: 'get',
+  });
+}
+
+export function algoInfoModify(algoId: number, pushLinkPrompt: string, pushStatement: string) {
+  return http.request({
+    url: '/cameraAlgo/saveAlgoState',
+    method: 'post',
+    data: {
+      algoId,
+      pushLinkPrompt,
+      pushStatement,
+    },
+  });
+}

+ 341 - 0
src/views/cameras/algo-management/algoManagement.vue

@@ -0,0 +1,341 @@
+<template>
+  <PageWrapper>
+    <div class="background">
+      <div class="left">
+        <el-input
+          v-model="searchKey"
+          placeholder="请输入算法信息搜索"
+          style="margin-top: 24px; height: 32px; margin-bottom: 16px"
+          :suffix-icon="Search"
+          @blur="searchItem"
+        />
+        <div class="algo-table">
+          <el-table
+            ref="singleTableRef"
+            :data="algoList"
+            highlight-current-row
+            stripe
+            style="width: 100%"
+            height="100%"
+            :row-style="{ height: '54px' }"
+            :header-row-style="{ height: '54px' }"
+            @row-click="handleRowClick"
+          >
+            <el-table-column property="id" label="序号" width="80" align="center" />
+            <el-table-column property="code" label="算法编号" width="120" align="center" />
+            <el-table-column property="name" label="算法名称" />
+          </el-table>
+        </div>
+        <div style="display: flex; justify-content: flex-end">
+          <el-pagination
+            background
+            layout="prev, pager, next"
+            style="margin-top: 24px; height: 32px; margin-bottom: 34px"
+            :total="20"
+            v-model:current-page="curPage"
+            @current-change="changePage"
+            :page-size="pageSize"
+          />
+        </div>
+      </div>
+      <div class="right">
+        <div class="right_top">
+          <div class="top_left">
+            <el-scrollbar height="100%">
+              <div v-if="currentRow?.name == ''" class="details_title">请在左侧列表中选择算法</div>
+              <div v-else class="details_title">{{ currentRow?.name }}检测算法展示</div>
+              <div v-for="item in arrRemark" :key="item" class="textbox">
+                <div class="item_title">{{ item }}</div>
+                <!-- <div class="item_details">{{ currentRow?.remark }}</div> -->
+              </div>
+            </el-scrollbar>
+          </div>
+          <div class="top_right">
+            <video :src="currentRow?.url" controls autoplay muted style="width: 100%; height: 100%">
+            </video>
+          </div>
+        </div>
+        <div class="right_bottom">
+          <div class="details_title" style="margin-bottom: 16px">报警推送编辑</div>
+          <el-form :model="alarmConfig" size="default" :rules="rules" ref="ruleFormRef">
+            <el-form-item label="语句编辑:" prop="pushStatement">
+              <div class="pushStatement">
+                <div class="remark">时间:(示例:2023.10.23 10:55:28)</div>
+                <div class="remark">地点:(示例:C919总装车间150A工位)</div>
+                <el-input
+                  v-model="alarmConfig.pushStatement"
+                  style="width: 100%; height: 74px; margin-top: 4px"
+                  placeholder="示例:【异常类:未穿反光背心违规】您好,经安全管控平台分析,在该区域发现员工未穿反光背心或穿戴不规范的情况,请及时提醒。"
+                />
+              </div>
+            </el-form-item>
+
+            <el-form-item label="链接提示:" prop="pushLinkPrompt">
+              <el-input
+                v-model="alarmConfig.pushLinkPrompt"
+                style="width: 100%"
+                placeholder="示例:请点击商飞大脑-天眼APP查看。"
+              />
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" :loading="isSending" @click="onSubmit"
+                >保&nbsp;&nbsp;存</el-button
+              >
+            </el-form-item>
+          </el-form>
+        </div>
+      </div>
+      <!-- <video :src="address" controls autoplay muted style="width: 100%; height: 100%"> </video> -->
+    </div>
+  </PageWrapper>
+</template>
+<script lang="ts" setup>
+  import { onMounted, ref, onUnmounted, reactive, watchEffect } from 'vue';
+  import { PageWrapper } from '../../../components/Page';
+  import useAlgo from './useAlgoData';
+  import { Search } from '@element-plus/icons-vue';
+  import type { FormInstance, FormRules } from 'element-plus';
+
+  //调用后端数据
+  const algoDatas = useAlgo();
+  const {
+    algoList,
+    getAlgoDatas,
+    page,
+    pageSize,
+    keyWord,
+    searchAlgoDatas,
+    algoId,
+    pushLinkPrompt,
+    pushStatement,
+    modifyAlgoDatas,
+  } = algoDatas;
+  //将后端拉到的数据存到algoListUse数组中进行使用
+  //刷新时从后端拉一次算法数组
+  onMounted(() => {
+    getAlgoDatas();
+  });
+
+  const changePage = () => {
+    page.value = curPage.value;
+    getAlgoDatas();
+  };
+
+  const searchItem = () => {
+    keyWord.value = searchKey.value;
+    curPage.value = 1;
+    page.value = curPage.value;
+    searchAlgoDatas();
+  };
+
+  const curPage = ref(1);
+  const currentRow = ref({
+    algoCode: '',
+    name: '',
+    remark: '',
+    url: '',
+    id: 0,
+    pushLinkPrompt: '',
+    pushStatement: '',
+  });
+
+  interface User {
+    algoCode: string;
+    name: string;
+    remark: string;
+    url: string;
+    id: number;
+    pushLinkPrompt: string;
+    pushStatement: string;
+  }
+
+  const arrRemark = ref<string[]>([]);
+
+  const handleRowClick = (val: User | undefined) => {
+    // console.log('xxxxxxxxxx', currentRow.value);
+    currentRow.value = val;
+    arrRemark.value = currentRow.value.remark.split('\r\n');
+    // console.log('arrRemark', arrRemark.value);
+  };
+
+  const searchKey = ref('');
+
+  interface SettingConfig {
+    pushLinkPrompt: string;
+    pushStatement: string;
+  }
+
+  const alarmConfig = ref<SettingConfig>({
+    pushLinkPrompt: '',
+    pushStatement: '',
+  });
+  const rules = ref<FormRules>({
+    pushLinkPrompt: [{ required: true, message: '此处不可空缺' }],
+    pushStatement: [{ required: true, message: '此处不可空缺' }],
+  });
+
+  const ruleFormRef = ref<FormInstance>();
+
+  const isSending = ref(false);
+
+  const onSubmit = async () => {
+    if (!ruleFormRef.value) console.log('error submit!');
+    await ruleFormRef.value?.validate((valid, fields) => {
+      if (valid) {
+        isSending.value = true;
+        algoId.value = currentRow.value.id;
+        pushLinkPrompt.value = alarmConfig.value.pushLinkPrompt;
+        pushStatement.value = alarmConfig.value.pushStatement;
+        // console.log('algoId', algoId.value);
+        // console.log('pushStatement', pushStatement.value);
+        // console.log('pushLinkPrompt', pushLinkPrompt.value);
+        modifyAlgoDatas().finally(() => {
+          isSending.value = false;
+        });
+      } else {
+        console.log('error submit!', fields);
+      }
+    });
+  };
+</script>
+<style lang="scss" scoped>
+  .background {
+    position: relative;
+    height: calc(100vh - 64px - 12px);
+    background-color: #ffffff;
+    display: flex;
+    flex-direction: row;
+    .left {
+      position: relative;
+      height: 100%;
+      width: 31%;
+      padding-left: 1.66%;
+      padding-right: 1.33%;
+      // background-color: green;
+      border-right: #dddddd 1px solid;
+      display: flex;
+      flex-direction: column;
+      .algo-table {
+        position: relative;
+        height: calc(100% - 72px - 90px);
+        width: 100%;
+        // background-color: red;
+        // margin-top: 16px;
+      }
+    }
+    .right {
+      position: relative;
+      height: 100%;
+      width: 69%;
+      display: flex;
+      flex-direction: column;
+      // background-color: yellow;
+      .right_top {
+        position: relative;
+        height: 364px;
+        width: 100%;
+        display: flex;
+        flex-direction: row;
+        border-bottom: #dddddd 1px solid;
+        // background-color: rebeccapurple;
+        .top_left {
+          position: relative;
+          margin-top: 90px;
+          margin-left: 4%;
+          height: 234px;
+          width: 42%;
+          display: flex;
+          flex-direction: column;
+          // background-color: rebeccapurple;
+          .details_title {
+            position: relative;
+            height: 22px;
+            width: 100%;
+            font-size: 14px;
+            font-weight: 600;
+            color: rgba(0, 0, 0, 0.85);
+            line-height: 22px;
+          }
+          .textbox {
+            position: relative;
+            margin-top: 14px;
+            width: 100%;
+            display: flex;
+            flex-direction: row;
+            .item_title {
+              position: relative;
+              width: 100%;
+              font-size: 14px;
+              font-weight: 500;
+              color: rgba(0, 0, 0, 0.85);
+              line-height: 22px;
+            }
+            .item_details {
+              position: relative;
+              width: 79.8%;
+              font-size: 14px;
+              font-weight: 400;
+              color: rgba(0, 0, 0, 0.85);
+              line-height: 22px;
+            }
+          }
+        }
+        .top_right {
+          position: relative;
+          margin-top: 90px;
+          margin-left: 4%;
+          height: 234px;
+          width: 45%;
+          display: flex;
+          flex-direction: row;
+          // background-color: rebeccapurple;
+        }
+      }
+      .right_bottom {
+        position: relative;
+        margin-left: 4%;
+        margin-top: 24px;
+        width: 91%;
+        display: flex;
+        flex-direction: column;
+        .details_title {
+          position: relative;
+          height: 22px;
+          width: 100%;
+          font-size: 14px;
+          font-weight: 600;
+          color: rgba(0, 0, 0, 0.85);
+          line-height: 22px;
+        }
+      }
+    }
+  }
+  .pushStatement {
+    position: relative;
+    display: flex;
+    flex-direction: column;
+    height: 155px;
+    width: 100%;
+    // background-color: red;
+    .remark {
+      position: relative;
+      height: 22px;
+      width: 100%;
+      margin-top: 4px;
+      margin-left: 10px;
+      margin-bottom: 12px;
+      font-size: 16px;
+      font-weight: 400;
+      color: rgba(0, 0, 0, 0.42);
+      line-height: 22px;
+    }
+  }
+  :deep() {
+    .el-input__wrapper {
+      align-items: flex-start !important;
+    }
+    .el-form-item__content {
+      justify-content: flex-end;
+    }
+  }
+</style>

+ 54 - 0
src/views/cameras/algo-management/useAlgoData.ts

@@ -0,0 +1,54 @@
+import { getAlgoInfo, searchAlgoInfo, algoInfoModify } from '@/api/algo/algo';
+import { ref } from 'vue';
+import { ElMessage } from 'element-plus';
+
+export function useAlgo() {
+  const algoList = ref([]);
+  const page = ref(1);
+  const pageSize = ref(12);
+  const keyWord = ref('');
+
+  const algoId = ref(0);
+  const pushLinkPrompt = ref('');
+  const pushStatement = ref('');
+
+  const getAlgoDatas = () => {
+    return getAlgoInfo(page.value, pageSize.value).then((res) => {
+      algoList.value = res.records;
+    });
+  };
+
+  const searchAlgoDatas = () => {
+    return searchAlgoInfo(page.value, keyWord.value).then((res) => {
+      algoList.value = res.records;
+    });
+  };
+
+  const modifyAlgoDatas = () => {
+    return algoInfoModify(algoId.value, pushLinkPrompt.value, pushStatement.value)
+      .then(function () {
+        ElMessage({
+          message: '算法数据保存成功',
+          type: 'success',
+        });
+      })
+      .catch(function () {
+        ElMessage.error('算法数据保存失败');
+      });
+  };
+
+  return {
+    algoList,
+    page,
+    pageSize,
+    keyWord,
+    getAlgoDatas,
+    searchAlgoDatas,
+    algoId,
+    pushLinkPrompt,
+    pushStatement,
+    modifyAlgoDatas,
+  };
+}
+
+export default useAlgo;