Explorar o código

Merge branch 'shareBugFix' into 'master'

Share bug fix

See merge request tian-group/skyeye-admin-fe!64
孙宏耀 %!s(int64=2) %!d(string=hai) anos
pai
achega
c929a226ac

+ 76 - 0
src/api/push/push.ts

@@ -0,0 +1,76 @@
+import { http } from '@/utils/http/axios';
+
+interface WorkshopType {
+  name: string;
+  code: string;
+}
+
+export interface RobotType {
+  id?: number;
+  robotName?: string;
+  robotUrl?: string;
+  workshopCodes?: WorkshopType[];
+  workshopName?: string[];
+  isPush?: boolean;
+  tenantId?: number;
+  isDelete?: boolean;
+  createTime?: string;
+  remark?: string | null;
+}
+
+export interface QueryType {
+  pageNumber: number;
+  pageSize: number;
+}
+
+interface ReturnType {
+  records: RobotType[];
+  pageNumber: number;
+  pageSize: number;
+  totalPage: number;
+  totalRow: number;
+}
+
+/**
+ * @description: 查询
+ */
+export function getRobot(params: QueryType) {
+  return http.request<ReturnType>({
+    url: 'robotPush/getList',
+    method: 'get',
+    params,
+  });
+}
+
+/**
+ * @description: 添加
+ */
+export function addRobot(data: RobotType) {
+  return http.request({
+    url: '/robotPush/save',
+    method: 'post',
+    data,
+  });
+}
+
+/**
+ * @description: 编辑
+ */
+export function editRobot(data: RobotType) {
+  return http.request({
+    url: '/robotPush/update',
+    method: 'put',
+    data,
+  });
+}
+
+/**
+ * @description: 删除
+ *
+ */
+export function delRobot(id: number) {
+  return http.request({
+    url: `/robotPush/delete?id=${id}`,
+    method: 'delete',
+  });
+}

+ 199 - 0
src/views/alarm-push/PushAlarm.vue

@@ -0,0 +1,199 @@
+<template>
+  <div class="push-page">
+    <el-card :bordered="false" class="proCard" style="position: relative">
+      <BasicTable
+        :columns="columns"
+        :data-source="robotPushList"
+        :row-key="(row) => row.id"
+        :action-column="actionColumn"
+        :loading="loading"
+        :pagination="{ total: total, pageSize: size, hideOnSinglePage: !robotPushList.length }"
+        :tableSetting="{
+          size: false,
+          redo: false,
+          fullscreen: false,
+          striped: false,
+          setting: false,
+        }"
+        :striped="true"
+        ref="tableRef"
+        @order-change="orderByItem"
+        @page-num-change="handlePageNumChange"
+        @page-size-change="handlePageSizeChange"
+      >
+        <template #tableTitle>
+          <el-button type="primary" :icon="Plus" @click="addDrawer">添加</el-button>
+        </template>
+      </BasicTable>
+    </el-card>
+    <AddRobot
+      v-if="showDrawer"
+      :robot-list="robotList"
+      @on-close="closeDrawer"
+      @sub-add="addSubRobot"
+      @sub-edit="editSubRobot"
+    />
+  </div>
+</template>
+
+<script setup lang="ts">
+  import { h, onMounted, reactive, ref } from 'vue';
+  import { BasicTable, TableActionIcons } from '@/components/Table';
+  import { BasicColumn } from '@/components/Table';
+  import { columns } from './constant';
+  import { Plus } from '@element-plus/icons-vue';
+  import editIcon from '@/assets/images/table/table-edit.png';
+  import deleteIcon from '@/assets/images/table/table-delete.png';
+  import AddRobot from './component/AddRobot.vue';
+  import { ElMessage, ElMessageBox } from 'element-plus';
+  import { RobotType } from '@/api/push/push';
+  import usePush from './usePush';
+
+  const usePushRobot = usePush();
+  const { robotPushList, total, page, size, loading, getRobotList, robotAdd, robotDel, robotEdit } =
+    usePushRobot;
+
+  onMounted(() => {
+    getRobotList();
+  });
+
+  // 添加弹窗相关
+  const showDrawer = ref(false);
+  const robotList = ref<RobotType | null>({});
+
+  //关闭drawer
+  const closeDrawer = () => {
+    showDrawer.value = false;
+  };
+
+  const addDrawer = () => {
+    robotList.value = null;
+    showDrawer.value = true;
+  };
+
+  const addSubRobot = (data) => {
+    robotAdd(data).then(() => {
+      ElMessage.success('添加成功');
+    });
+    showDrawer.value = false;
+  };
+
+  const editSubRobot = (data) => {
+    robotEdit(data).then(() => {
+      ElMessage.success('编辑成功');
+    });
+    showDrawer.value = false;
+  };
+
+  //操作列
+  const actionColumn: BasicColumn = reactive({
+    width: 200,
+    title: '操作',
+    prop: 'action',
+    key: 'action',
+    fixed: 'right',
+    render(record) {
+      return h(TableActionIcons as any, {
+        space: 20,
+        color: '#629bf9',
+        style: 'img',
+        size: 16,
+        actionIcons: [
+          {
+            label: '编辑',
+            icon: editIcon,
+            onClick: handleEdit.bind(null, record.row),
+          },
+          {
+            label: '删除',
+            icon: deleteIcon,
+            onClick: handleDelete.bind(null, record.row),
+          },
+        ],
+      });
+    },
+  });
+
+  // 列排序操作
+  const orderByItem = () => {};
+
+  const handlePageNumChange = (pageNum) => {
+    page.value = pageNum;
+    getRobotList();
+  };
+
+  const handlePageSizeChange = (pageSize) => {
+    size.value = pageSize;
+    getRobotList();
+  };
+
+  const handleDelete = (row) => {
+    ElMessageBox.confirm(`您想删除机器人${row.robotName}`, '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning',
+      draggable: true,
+    })
+      .then(() => {
+        robotDel(row.id).then(() => {
+          ElMessage.success('删除成功');
+        });
+      })
+      .catch(() => {});
+  };
+
+  //编辑
+  const handleEdit = (row) => {
+    robotList.value = row;
+    showDrawer.value = true;
+  };
+</script>
+
+<style scoped>
+  .push-page {
+    position: relative;
+    height: calc(100vh - 64px - 12px);
+    background-color: #ffffff;
+  }
+
+  .camera-list {
+    padding: 0 21px;
+  }
+
+  .empty-content {
+    margin: auto;
+    padding: 125px 0;
+  }
+
+  .empty-img {
+    width: 396px;
+  }
+
+  .empty-text {
+    font-size: 22px;
+    color: #8e8e8e;
+    line-height: 30px;
+    text-align: center;
+  }
+
+  .add-tip {
+    position: absolute;
+    left: 187px;
+    top: 64px;
+    font-size: 16px;
+    color: red;
+  }
+  .add-popover {
+    position: absolute;
+    width: calc(100% - 21px);
+    height: 622px;
+    top: 0;
+    bottom: 0;
+    margin: auto;
+    z-index: 99;
+  }
+
+  .item {
+    margin: 0px 40px 0px 15px;
+  }
+</style>

+ 144 - 0
src/views/alarm-push/component/AddRobot.vue

@@ -0,0 +1,144 @@
+<template>
+  <div>
+    <el-drawer
+      ref="companyDrawerRef"
+      class="test"
+      :model-value="true"
+      @close="() => emits('onClose')"
+      with-header="true"
+      size="30%"
+    >
+      <template #header="{ titleId }">
+        <p :id="titleId">{{ title }}</p>
+      </template>
+      <el-form
+        ref="ruleFormRef"
+        :model="ruleForm"
+        :rules="rules"
+        label-width="120px"
+        class="demo-ruleForm"
+        size="default"
+        status-icon
+      >
+        <el-form-item label="机器人名称" prop="robotName">
+          <el-input v-model="ruleForm.robotName" style="width: 200px" />
+        </el-form-item>
+        <el-form-item label="机器人地址" prop="robotUrl">
+          <el-input v-model="ruleForm.robotUrl" style="width: 200px" />
+        </el-form-item>
+        <el-form-item label="场景" prop="workshopName">
+          <el-tree-select
+            v-model="ruleForm.workshopName"
+            :data="scenesTree"
+            :render-after-expand="false"
+            :default-expand-all="true"
+            check-strictly
+            multiple
+            placeholder="请选择场景"
+            style="width: 200px"
+            @change="handleTreeSelect"
+          />
+        </el-form-item>
+        <el-form-item label="状态">
+          <el-switch
+            v-model="ruleForm.isPush"
+            :active-value="true"
+            :inactive-value="false"
+            class="switchUse"
+          />
+        </el-form-item>
+      </el-form>
+      <div style="position: absolute; left: 108px; bottom: 67px">
+        <el-button @click="resetDrawer">重置</el-button>
+        <el-button type="primary" @click="subDrawer"> 提交 </el-button>
+      </div>
+    </el-drawer></div
+  >
+</template>
+
+<script setup lang="ts">
+  import { computed, reactive, ref, defineProps, defineEmits, onBeforeMount } from 'vue';
+  import type { FormInstance, FormRules } from 'element-plus';
+  import { RobotType } from '@/api/push/push';
+  import useSceneInfos from '@/hooks/useSceneInfos';
+  import { cloneDeep } from 'lodash-es';
+
+  const sceneInfos = useSceneInfos();
+  const { scenesTree, flattenedWorkshops, getScenesTree } = sceneInfos;
+
+  const props = defineProps<{
+    robotList: RobotType | null;
+  }>();
+
+  const title = computed(() => {
+    if (props.robotList) {
+      return '编辑机器人';
+    }
+    return '添加机器人';
+  });
+
+  const emits = defineEmits(['onClose', 'subAdd', 'subEdit']);
+
+  //表格中的规则
+  const ruleFormRef = ref<FormInstance>();
+
+  const ruleForm = ref<RobotType>({
+    robotName: '',
+    robotUrl: '',
+    workshopCodes: [],
+    workshopName: [],
+    isPush: true,
+  });
+
+  const rules = reactive<FormRules>({
+    robotName: [{ required: true, message: '请输入机器人名称', trigger: 'blur' }],
+    robotUrl: [{ required: true, message: '请输入机器人地址', trigger: 'blur' }],
+    workshopName: [{ required: true, message: '请选择场景', trigger: 'blur' }],
+  });
+
+  //重置编辑框
+  const resetDrawer = () => {
+    ruleForm.value.robotName = '';
+    ruleForm.value.robotUrl = '';
+    ruleForm.value.workshopCodes = [];
+    ruleForm.value.workshopName = [];
+    ruleForm.value.isPush = true;
+  };
+  //提交
+  const subDrawer = () => {
+    if (props.robotList) {
+      const data = {
+        id: props.robotList.id,
+        robotName: ruleForm.value.robotName,
+        robotUrl: ruleForm.value.robotUrl,
+        workshopCodes: ruleForm.value.workshopCodes,
+        isPush: ruleForm.value.isPush,
+      };
+      emits('subEdit', data);
+    } else {
+      const data = {
+        robotName: ruleForm.value.robotName,
+        robotUrl: ruleForm.value.robotUrl,
+        workshopCodes: ruleForm.value.workshopCodes,
+        isPush: ruleForm.value.isPush,
+      };
+      emits('subAdd', data);
+    }
+  };
+
+  const handleTreeSelect = (code: string) => {
+    ruleForm.value.workshopCodes = flattenedWorkshops.value
+      .filter((item) => code.includes(item.code))
+      .map(({ code, name }) => ({ code, name }));
+  };
+
+  onBeforeMount(() => {
+    getScenesTree({ level: 2, valueKey: 'code', labelKey: 'name', disabled: true });
+    if (props.robotList) {
+      ruleForm.value = cloneDeep(props.robotList);
+      ruleForm.value.workshopName = ruleForm.value.workshopCodes!.map((item) => item.code);
+    }
+  });
+</script>
+
+<style scoped></style>

+ 42 - 0
src/views/alarm-push/constant.ts

@@ -0,0 +1,42 @@
+import { BasicColumn } from '@/components/Table';
+import { h } from 'vue';
+
+export const columns: BasicColumn[] = [
+  {
+    label: '序号',
+    minWidth: 60,
+    type: 'index',
+    fixed: 'left',
+  },
+  {
+    label: '机器人名称',
+    prop: 'robotName',
+    minWidth: 100,
+  },
+  {
+    label: '机器人地址',
+    prop: 'robotUrl',
+    minWidth: 140,
+  },
+  {
+    label: '场景',
+    prop: 'workshopCodes',
+    minWidth: 120,
+    render(record) {
+      return h(
+        'span',
+        {},
+        {
+          default: () => {
+            return record.row.workshopCodes.map((item) => item.name).join(' , ');
+          },
+        },
+      );
+    },
+  },
+];
+
+export enum ENABLED {
+  FALSE = '0',
+  TRUE = '1',
+}

+ 62 - 0
src/views/alarm-push/usePush.ts

@@ -0,0 +1,62 @@
+import { ref } from 'vue';
+import { RobotType, getRobot, addRobot, editRobot, delRobot } from '@/api/push/push';
+import { useRequest } from 'vue-hooks-plus';
+
+export const usePush = () => {
+  const robotPushList = ref<RobotType[]>([]);
+  const total = ref(0);
+  const page = ref(1);
+  const size = ref(10);
+
+  // 查询
+  const robotSearch = () => {
+    const params = {
+      pageNumber: page.value,
+      pageSize: size.value,
+    };
+    return getRobot(params).then((res) => {
+      return res;
+    });
+  };
+
+  const { loading, run: getRobotList } = useRequest(robotSearch, {
+    manual: true,
+    onSuccess: (res) => {
+      robotPushList.value = [...res.records];
+      total.value = res.totalRow;
+    },
+  });
+
+  const robotAdd = (data: RobotType) => {
+    return addRobot(data).then(() => {
+      getRobotList();
+    });
+  };
+
+  const robotDel = (id: number) => {
+    return delRobot(id).then(() => {
+      getRobotList();
+    });
+  };
+
+  const robotEdit = (data: RobotType) => {
+    return editRobot(data).then(() => {
+      getRobotList();
+    });
+  };
+
+  return {
+    robotPushList,
+    total,
+    page,
+    size,
+    loading,
+    robotSearch,
+    getRobotList,
+    robotAdd,
+    robotDel,
+    robotEdit,
+  };
+};
+
+export default usePush;

+ 7 - 2
src/views/cameras/overview/components/ShareCameraDetail.vue

@@ -99,6 +99,7 @@
   import useCameraShare from '../stores/useCameraShare';
   import { getVerify } from '@/api/camera/camera-share';
   import dayjs from 'dayjs';
+  import { ElMessage } from 'element-plus';
 
   const useShare = useCameraShare();
   const { cameraShareList, queryCameraId, conditionSearch, handleDel, handleAdd, handleEdit } =
@@ -165,8 +166,12 @@
   const verifyAccount = () => {
     // shareData.value.name = 'C' + shareData.value.account;
     getVerify(shareData.value.tenantCode!).then((res) => {
-      shareData.value.tenantName = res.tenantName;
-      shareData.value.toTenantId = res.tenantId;
+      if (res) {
+        shareData.value.tenantName = res.tenantName;
+        shareData.value.toTenantId = res.tenantId;
+      } else {
+        ElMessage.error('企业账号验证失败');
+      }
     });
   };
 

+ 6 - 1
src/views/system-config/scene-manage/SceneManage.vue

@@ -106,11 +106,13 @@
   import useScene from './use-scene';
   import useSceneTemplete from './use-sence-templete';
   import { useRouter } from 'vue-router';
+  import { storeToRefs } from 'pinia';
 
   const router = useRouter();
 
   const useSceneList = useScene();
-  const { tableData, getSceneDetail } = useSceneList;
+  const { tableData } = storeToRefs(useSceneList);
+  const { getSceneDetail } = useSceneList;
   const useSceneTempleteDetail = useSceneTemplete();
   const { sceneList, templateList, workshopTemplateList } = useSceneTempleteDetail;
   const expendRowKeys = ref(['']);
@@ -199,6 +201,8 @@
     fixed: 'right',
     render(record) {
       return h(ActionColomn, {
+        // rowUpDisable:
+        // rowDownDisable:
         subItem: record.row,
         handleConig: handleConfig,
         handleAdd: handleAdd,
@@ -359,6 +363,7 @@
   const rowUp = (row) => {
     if (row.parent) {
       const parentIndex = row.parent.children!.indexOf(row);
+      row.parentIndex = parentIndex;
       if (parentIndex > 0) {
         const previousRow = row.parent.children![parentIndex - 1];
         // 进行交换位置

+ 51 - 14
src/views/system-config/scene-manage/actionColomns.vue

@@ -2,35 +2,45 @@
   <div style="display: flex">
     <div style="display: flex; margin-right: 7px">
       <div
-        v-if="props.subItem.parentId !== undefined"
+        v-if="(props.subItem as ComAddDatas).parentId !== undefined"
         @click="changeConig"
         class="wordStyle"
         style="margin-right: 10px"
         >页面设置</div
       >
       <div v-else style="margin-right: 10px; width: 56px"></div>
-      <div @click="changeAdd" class="wordStyle" style="margin-right: 7px">添加下一级</div></div
-    >
+      <div v-if="!isWorkshop" @click="changeAdd" class="wordStyle">添加下一级</div>
+      <div v-else style="margin-right: 10px; width: 67px"></div
+    ></div>
     <div style="width: 1px; height: 14px; color: #e9e9e9; margin-right: 14px">|</div>
     <img src="../../../assets/icons/edit.png" @click="changeEdit" class="action-img" alt="" />
     <img src="../../../assets/icons/delete.png" @click="changeDelete" class="action-img" alt="" />
-    <img src="../../../assets/icons/up.png" @click="changeUp" class="action-img" alt="" />
-    <img src="../../../assets/icons/down.png" @click="changeDown" class="action-img" alt="" />
+    <img
+      src="../../../assets/icons/up.png"
+      @click="changeUp"
+      :class="{ 'action-disable': isFirst, 'action-img': !isFirst }"
+      alt=""
+    />
+    <img
+      src="../../../assets/icons/down.png"
+      @click="changeDown"
+      :class="{ 'action-disable': isLast, 'action-img': !isLast }"
+      alt=""
+    />
   </div>
 </template>
 
 <script setup lang="ts">
-  interface User {
-    name?: string;
-    tag?: string;
-    code?: string;
-    hasChildren?: boolean;
-    children?: User[];
-    parentId?: number;
-  }
+  import { computed } from 'vue';
+  import { ComAddDatas, WorkshopAddDatas, WorkspaceAddDatas } from '@/api/scene/sceneOperate.ts';
+  import useScene from './use-scene';
+  import { storeToRefs } from 'pinia';
+
+  const useSceneList = useScene();
+  const { tableData } = storeToRefs(useSceneList);
 
   const props = defineProps<{
-    subItem: User;
+    subItem: ComAddDatas | WorkshopAddDatas | WorkspaceAddDatas;
     handleConig: (row) => unknown;
     handleAdd: (row) => unknown;
     handleEdit: (row) => unknown;
@@ -39,6 +49,24 @@
     handleDown: (row) => unknown;
   }>();
 
+  const isWorkshop = computed(() => {
+    return (props.subItem as any).workshopId ? true : false;
+  });
+
+  const isFirst = computed(() => {
+    return (props.subItem as any).serial === 0 ? true : false;
+  });
+
+  const isLast = computed(() => {
+    if ((props.subItem as any).parentId === 0) {
+      return (props.subItem as any).serial === tableData.value.length - 1 ? true : false;
+    } else {
+      return (props.subItem as any).serial === (props.subItem as any).parent?.children.length - 1
+        ? true
+        : false;
+    }
+  });
+
   const changeConig = () => {
     props.handleConig(props.subItem);
   };
@@ -71,7 +99,9 @@
     color: #1890ff;
     line-height: 22px;
     cursor: pointer;
+    margin-right: 7px;
   }
+
   .otp-btn {
     width: 52px;
     height: 26px;
@@ -94,4 +124,11 @@
     height: 16px;
     margin-top: 5px;
   }
+  .action-disable {
+    margin-right: 10px;
+    height: 16px;
+    margin-top: 5px;
+    filter: grayscale(100%);
+    cursor: not-allowed;
+  }
 </style>

+ 2 - 2
src/views/system-config/scene-manage/use-method.tsx

@@ -15,8 +15,8 @@ export const colomns = [
     label: '预览',
     prop: 'preview',
     render: ({ row, column }) => {
-      console.log('record row', row);
-      console.log('record', column);
+      // console.log('record row', row);
+      // console.log('record', column);
       if (!row.parent && row.labelList?.[0]?.id) {
         return (
           <a

+ 18 - 2
src/views/system-config/scene-manage/use-scene.ts

@@ -6,9 +6,25 @@ import {
   LabelModuleListType,
 } from '@/api/scene/sceneOperate';
 import { WorkShopTempleteType } from '@/api/scene/secene-templet';
+import { defineStore } from 'pinia';
 import { ref } from 'vue';
 
-export function useScene() {
+// export function useScene() {
+//   //场景数据
+//   const tableData = ref<
+//     SceneListType<GetListWorkshop<WorkspaceAddDatas, WorkShopTempleteType>, LabelModuleListType>[]
+//   >([]);
+
+//   const getSceneDetail = () => {
+//     getSceneList().then((res) => {
+//       tableData.value = res;
+//     });
+//   };
+
+//   return { tableData, getSceneDetail };
+// }
+
+export const useScene = defineStore('scene-data', () => {
   //场景数据
   const tableData = ref<
     SceneListType<GetListWorkshop<WorkspaceAddDatas, WorkShopTempleteType>, LabelModuleListType>[]
@@ -21,6 +37,6 @@ export function useScene() {
   };
 
   return { tableData, getSceneDetail };
-}
+});
 
 export default useScene;