Преглед изворни кода

Merge remote-tracking branch 'origin/dev' into feat/production-safety

sunqijun пре 1 месец
родитељ
комит
bdef11b923

+ 10 - 5
src/api/emergency-plan/index.ts

@@ -26,11 +26,16 @@ export const getEmergencyPlanList = (data: QueryPageRequest<PlanEmergencyListQue
  * 创建应急预案
  */
 export const createEmergencyPlan = (data: AddEmergencyPlanParam) => {
-  return http.request({
-    url: '/emergencyPlan/saveEmergencyPlan',
-    method: 'post',
-    data,
-  });
+  return http.request(
+    {
+      url: '/emergencyPlan/saveEmergencyPlan',
+      method: 'post',
+      data,
+    },
+    {
+      isShowErrorMessage: true,
+    },
+  );
 };
 
 /**

+ 5 - 0
src/components/PersonGroup/SelectGroup.vue

@@ -45,8 +45,13 @@
     });
   };
 
+  const clearValidate = () => {
+    ruleFormRef.value?.resetFields();
+  };
+
   defineExpose({
     validateForm,
+    clearValidate,
   });
 
   onMounted(() => {

+ 5 - 1
src/components/UploadImages/UploadImages.vue

@@ -169,6 +169,11 @@
       });
     });
 
+    if (fileInput.value!.files!.length > 0) {
+      // 清空文件输入域
+      fileInput.value!.value = '';
+    }
+
     // 触发更新事件
     if (filesToAdd.length > 0) {
       emitChange();
@@ -177,7 +182,6 @@
 
   const removeImage = (index: number) => {
     // 释放对象URL以避免内存泄漏
-    alert(index);
     URL.revokeObjectURL(uploadedImages[index].url);
     uploadedImages.splice(index, 1);
     ElMessage.success('删除成功');

+ 2 - 2
src/types/emergency-plan/index.ts

@@ -4,7 +4,7 @@ export interface PlanEmergencyListQuery {
   planName?: string;
   planType?: string;
   eventType?: string;
-  professionalTestSite?: string;
+  taskSite?: number;
   status?: number;
 }
 
@@ -22,7 +22,7 @@ interface BasicListResponse {
 }
 
 export interface PlanEmergencyListResponse extends BasicListResponse {
-  professionalTestSite: string | null;
+  taskSite: number | null;
   isDisabled: number;
   status: number;
   approvalTemplateId: number;

+ 1 - 0
src/types/emergency-supplier/index.ts

@@ -213,4 +213,5 @@ export interface NotifyDepartmentForm {
   noticeScope: number; // 通知范围: 1-通知此物资所有需求部门 2-仅通知此物资当前需求部门
   requestTime: string; // 通知领用时间
   requestLocation: string; // 通知领用地点
+  userGroupIds: number[];
 }

+ 7 - 4
src/views/emergency/emergency-plan/PageManagement.vue

@@ -53,6 +53,9 @@
           <template #eventType="scope">
             <span>{{ getEmergencyEvent(scope.row.eventType) }}</span>
           </template>
+          <template #taskSite="scope">
+            <span>{{ TASK_SITE_MAP[scope.row.taskSite] }}</span>
+          </template>
           <template #status="scope">
             <span
               :class="
@@ -157,7 +160,7 @@
     APPROVAL_TYPE_MAP,
     APPROVAL_STATUS_MAP,
     APPROVAL_STATUS,
-    APPROVAL_TYPE,
+    TASK_SITE_MAP,
   } from './src/constant';
 
   const router = useRouter();
@@ -266,7 +269,7 @@
     planName: null,
     planType: null,
     eventType: null,
-    professionalTestSite: null,
+    taskSite: null,
     status: null,
   });
   const handleSearch = () => {
@@ -280,8 +283,8 @@
     if (searchData.eventType) {
       planManagementListQuery.queryParam.eventType = searchData.eventType;
     }
-    if (searchData.professionalTestSite) {
-      planManagementListQuery.queryParam.professionalTestSite = searchData.professionalTestSite;
+    if (searchData.taskSite) {
+      planManagementListQuery.queryParam.taskSite = searchData.taskSite;
     }
     if (searchData.status !== null) {
       planManagementListQuery.queryParam.status = searchData.status;

+ 2 - 2
src/views/emergency/emergency-plan/PageManagementDetail.vue

@@ -123,7 +123,7 @@
       eventType: formData.eventType,
       deptId: formData.deptId,
       deptName: formData.deptName,
-      professionalTestSite: formData.professionalTestSite,
+      taskSite: formData.taskSite,
       approvalTemplateId: formData.approvalTemplateId,
       appendix: JSON.stringify(attachmentListRes),
     };
@@ -138,7 +138,7 @@
       eventType: formData.eventType,
       deptId: formData.deptId,
       deptName: formData.deptName,
-      professionalTestSite: formData.professionalTestSite,
+      taskSite: formData.taskSite,
       approvalTemplateId: formData.approvalTemplateId,
       appendix: JSON.stringify(attachmentListRes),
     };

+ 4 - 9
src/views/emergency/emergency-plan/src/components/AddManagementDetail.vue

@@ -29,14 +29,9 @@
           @change="handleChangeDept"
         />
       </template>
-      <template #professionalTestSite>
-        <el-select v-model="ruleFormData.professionalTestSite" placeholder="请选择作业场所">
-          <el-option
-            v-for="item in PROFESSIONAL_TEST_SITE_DICE"
-            :key="item.value"
-            :label="item.label"
-            :value="item.value"
-          />
+      <template #taskSite>
+        <el-select v-model="ruleFormData.taskSite" placeholder="请选择作业场所">
+          <el-option v-for="item in TASK_SITE_DICE" :key="item.value" :label="item.label" :value="item.value" />
         </el-select>
       </template>
       <template #approvalTemplateId>
@@ -66,7 +61,7 @@
   import type { AddEmergencyPlanForm } from '@/types/emergency-plan';
   import type { FileItem } from '@/components/UploadFiles/types.ts';
   import { PLAN_MANAGEMENT_FORM_CONFIG, PLAN_MANAGEMENT_FORM_DATA, PLAN_MANAGEMENT_FORM_RULES } from '../config';
-  import { PROFESSIONAL_TEST_SITE_DICE } from '../constant';
+  import { TASK_SITE_DICE } from '../constant';
 
   const formRef = ref();
   const cascaderRef = ref();

+ 6 - 0
src/views/emergency/emergency-plan/src/components/EditManagementDetail.vue

@@ -1,6 +1,11 @@
 <template>
   <div class="emergency-plan-container">
     <BasicForm ref="formRef" :formData="ruleFormData" :formConfig="ruleFormConfig" :formRules="formRules">
+      <template #taskSite>
+        <el-select v-model="ruleFormData.taskSite" placeholder="请选择作业场所" :disabled="true">
+          <el-option v-for="item in TASK_SITE_DICE" :key="item.value" :label="item.label" :value="item.value" />
+        </el-select>
+      </template>
       <template #uploadFile>
         <UploadFiles
           label="上传附件"
@@ -28,6 +33,7 @@
     PLAN_MANAGEMENT_FORM_DATA_EDIT,
     PLAN_MANAGEMENT_FORM_RULES_EDIT,
   } from '../config';
+  import { TASK_SITE_DICE } from '../constant';
 
   const formRef = ref();
   const props = defineProps<{

+ 6 - 0
src/views/emergency/emergency-plan/src/components/ViewManagementDetail.vue

@@ -1,6 +1,11 @@
 <template>
   <div class="emergency-plan-container">
     <BasicForm ref="formRef" :formData="ruleFormData" :formConfig="ruleFormConfig">
+      <template #taskSite>
+        <el-select v-model="ruleFormData.taskSite" placeholder="请选择作业场所" :disabled="true">
+          <el-option v-for="item in TASK_SITE_DICE" :key="item.value" :label="item.label" :value="item.value" />
+        </el-select>
+      </template>
       <template #uploadFile>
         <div class="appendix-container" v-if="ruleFormData.uploadFile.length">
           <div class="appendix-item" v-for="item in ruleFormData.uploadFile" :key="item.fileId">
@@ -27,6 +32,7 @@
   import { queryEmergencyPlan } from '@/api/emergency-plan';
   import { PLAN_MANAGEMENT_FORM_CONFIG_EDIT, PLAN_MANAGEMENT_FORM_DATA_EDIT } from '../config';
   import { FILE_TYPE_ICON } from '@/components/UploadFiles/constants';
+  import { TASK_SITE_DICE } from '../constant';
 
   const formRef = ref();
   const previewOnlineRef = ref<InstanceType<typeof PreviewOnline>>();

+ 5 - 8
src/views/emergency/emergency-plan/src/config/form.ts

@@ -36,8 +36,8 @@ export const PLAN_MANAGEMENT_FORM_CONFIG: FormConfig[] = [
   },
   {
     label: '作业场所:',
-    prop: 'professionalTestSite',
-    slot: 'professionalTestSite',
+    prop: 'taskSite',
+    slot: 'taskSite',
   },
   {
     label: '审批流程:',
@@ -86,11 +86,8 @@ export const PLAN_MANAGEMENT_FORM_CONFIG_EDIT: FormConfig[] = [
   },
   {
     label: '作业场所:',
-    prop: 'professionalTestSite',
-    component: 'ElInput',
-    componentProps: {
-      disabled: true,
-    },
+    prop: 'taskSite',
+    slot: 'taskSite',
   },
   {
     label: '审批流程:',
@@ -111,7 +108,7 @@ const BASE_FORM_DATA = {
   eventType: '',
   deptId: null,
   deptName: '',
-  professionalTestSite: null,
+  taskSite: null,
   approvalTemplateId: null,
   appendix: '',
   uploadFile: [],

+ 6 - 4
src/views/emergency/emergency-plan/src/config/search.ts

@@ -1,5 +1,5 @@
 import type { SearchConfig } from '@/types/basic-search';
-import { EMERGENCY_PLAN_STATUS_OPTIONS, APPROVAL_STATUS_OPTIONS } from '../constant';
+import { EMERGENCY_PLAN_STATUS_OPTIONS, APPROVAL_STATUS_OPTIONS, TASK_SITE_DICE } from '../constant';
 
 export const EMERGENCY_PLAN_MANAGEMENT_SEARCH_CONFIG: SearchConfig[] = [
   {
@@ -22,10 +22,12 @@ export const EMERGENCY_PLAN_MANAGEMENT_SEARCH_CONFIG: SearchConfig[] = [
   },
   {
     label: '作业场所:',
-    prop: 'professionalTestSite',
-    component: 'ElInput',
+    prop: 'taskSite',
+    component: 'ElSelect',
+    selectOptions: TASK_SITE_DICE,
     componentProps: {
-      placeholder: '请输入作业场所',
+      placeholder: '请选择作业场所',
+      filterable: true,
     },
   },
   {

+ 2 - 2
src/views/emergency/emergency-plan/src/config/table.ts

@@ -66,7 +66,7 @@ export const EMERGENCY_PLAN_MANAGEMENT_TABLE_COLUMNS: TableColumnProps[] = [
   BASIC_TABLE_COLUMNS.DEPT_NAME,
   {
     label: '作业场所',
-    prop: 'professionalTestSite',
+    slot: 'taskSite',
     minWidth: '160px',
   },
   {
@@ -77,7 +77,7 @@ export const EMERGENCY_PLAN_MANAGEMENT_TABLE_COLUMNS: TableColumnProps[] = [
   {
     label: '启停',
     slot: 'isDisabled',
-    minWidth: '60px',
+    minWidth: '100px',
     align: 'center',
   },
   BASIC_TABLE_COLUMNS.ACTION,

+ 31 - 9
src/views/emergency/emergency-plan/src/constant.ts

@@ -84,37 +84,59 @@ export const APPROVAL_STATUS_OPTIONS = [
   },
 ];
 
-export const PROFESSIONAL_TEST_SITE_DICE = [
+export enum TASK_SITE {
+  WAREHOUSE = 1,
+  ACCOMMODATION,
+  OFFICE,
+  SERVICE,
+  EXPERIMENT,
+  SPORTS,
+  CONSTRUCTION,
+  OHTER,
+}
+
+export const TASK_SITE_MAP = {
+  [TASK_SITE.WAREHOUSE]: '仓储',
+  [TASK_SITE.ACCOMMODATION]: '住宿',
+  [TASK_SITE.OFFICE]: '办公',
+  [TASK_SITE.SERVICE]: '服务',
+  [TASK_SITE.EXPERIMENT]: '试验',
+  [TASK_SITE.SPORTS]: '文体活动',
+  [TASK_SITE.CONSTRUCTION]: '施工',
+  [TASK_SITE.OHTER]: '其他',
+};
+
+export const TASK_SITE_DICE = [
   {
     label: '仓储',
-    value: '仓储',
+    value: TASK_SITE.WAREHOUSE,
   },
   {
     label: '住宿',
-    value: '住宿',
+    value: TASK_SITE.ACCOMMODATION,
   },
   {
     label: '办公',
-    value: '办公',
+    value: TASK_SITE.OFFICE,
   },
   {
     label: '服务',
-    value: '服务',
+    value: TASK_SITE.SERVICE,
   },
   {
     label: '试验',
-    value: '试验',
+    value: TASK_SITE.EXPERIMENT,
   },
   {
     label: '文体活动',
-    value: '文体活动',
+    value: TASK_SITE.SPORTS,
   },
   {
     label: '施工',
-    value: '施工',
+    value: TASK_SITE.CONSTRUCTION,
   },
   {
     label: '其他',
-    value: '其他',
+    value: TASK_SITE.OHTER,
   },
 ];

+ 9 - 3
src/views/emergency/emergency-supplies/src/components/ChangeRecord.vue

@@ -9,14 +9,18 @@
         <span>{{ scope.row.changeQuantity }}</span>
       </template>
       <template #action="scope">
-        <ActionButton text="报废详情" @click="handleViewDetail(scope.row)" />
+        <ActionButton
+          v-if="scope.row.changeType === CHANGE_TYPE.DISCARD"
+          text="报废详情"
+          @click="handleViewDetail(scope.row)"
+        />
       </template>
     </BasicTable>
     <el-drawer title="报废详情" v-model="drawerVisible" size="40%" :close-on-click-modal="true" :show-close="true">
       <div class="drawer-body">
         <div class="drawer-item">
           <span class="drawer-item-label">报废理由:</span>
-          <span>{{ record?.scrapReason }}</span>
+          <span>{{ record?.scrapReason || '无' }}</span>
         </div>
         <div v-if="uploadedImages.length > 0" class="drawer-item">
           <span class="drawer-item-label">报废照片:</span>
@@ -48,6 +52,7 @@
   import { CHANGE_TYPE_MAP } from '../constant';
   import ActionButton from '@/components/ActionButton.vue';
   import { unformatImage } from '@/components/UploadImages/utils';
+  import { CHANGE_TYPE } from '../constant';
 
   const { tableConfig } = useTableConfig(CHANGE_RECORD_TABLE_COLUMNS, CHANGE_RECORD_TABLE_OPTIONS, false);
   const props = defineProps<{
@@ -87,8 +92,9 @@
   .image-container {
     display: flex;
     flex-wrap: wrap;
-    gap: 5px;
+    gap: 10px;
     width: 100%;
+    padding: 10px 0;
   }
   .image-preview {
     width: 100px;

+ 2 - 2
src/views/emergency/emergency-supplies/src/components/DiscardSupplies.vue

@@ -86,8 +86,8 @@
   };
 
   const scrapImage = ref<ImageItem[]>([]);
-  const handleUploadSuccess = (files: ImageItem[]) => {
-    scrapImage.value = files;
+  const handleUploadSuccess = () => {
+    scrapImage.value = uploadImagesRef.value!.getUploadedImages();
   };
 
   const handleSumbit = async () => {

+ 37 - 4
src/views/emergency/emergency-supplies/src/components/NotifyDepartmentDialog.vue

@@ -10,6 +10,11 @@
           </el-radio-group>
         </template>
       </BasicForm>
+      <SelectGroup
+        ref="selectGroupRef"
+        :user-group-list="ruleFormData.userGroupIds || []"
+        @user-group-list-change="handleUserGroupListChange"
+      />
     </template>
     <template #footer>
       <el-button @click="basicDialogRef?.closeDialog">取消</el-button>
@@ -23,6 +28,7 @@
   import { ElMessage, ElRadioGroup, ElRadio } from 'element-plus';
   import BasicDialog from '@/components/BasicDialog.vue';
   import BasicForm from '@/components/BasicForm.vue';
+  import SelectGroup from '@/components/PersonGroup/SelectGroup.vue';
   import { useFormConfigHook } from '@/hooks/useFormConfigHook';
   import { NOTIFY_DEPARTMENT_FORM_CONFIG, NOTIFY_DEPARTMENT_FORM_DATA, NOTIFY_DEPARTMENT_FORM_RULES } from '../config';
   import { NOTIFY_RANGE, NOTIFY_RANGE_OPTIONS } from '../constant';
@@ -34,7 +40,7 @@
 
   const basicDialogRef = ref<InstanceType<typeof BasicDialog>>();
   const basicFormRef = ref<InstanceType<typeof BasicForm>>();
-  const tmpDetailId = ref<number | undefined>(undefined);
+  const selectGroupRef = ref<InstanceType<typeof SelectGroup>>();
 
   const { ruleFormConfig, ruleFormData, formRules } = useFormConfigHook(
     NOTIFY_DEPARTMENT_FORM_CONFIG,
@@ -42,6 +48,7 @@
     NOTIFY_DEPARTMENT_FORM_RULES,
   );
 
+  const tmpDetailId = ref<number | undefined>(undefined);
   const notifyRangeOptions = ref<{ label: string; value: number }[]>(NOTIFY_RANGE_OPTIONS);
 
   // 打开对话框
@@ -50,10 +57,20 @@
     basicDialogRef.value?.openDialog();
   };
 
+  // 处理分组列表变化
+  const handleUserGroupListChange = (userGroupIds: number[]) => {
+    ruleFormData.userGroupIds = userGroupIds;
+  };
+
   // 提交表单
   const handleSubmit = async () => {
-    const validate = await basicFormRef.value?.validateForm();
-    if (!validate) return;
+    if (!basicFormRef.value) return;
+    const parentValidateResult = await basicFormRef.value.validateForm();
+    let childValidateResult = true;
+    if (selectGroupRef.value) {
+      childValidateResult = (await selectGroupRef.value.validateForm()) as boolean;
+    }
+    if (!parentValidateResult || !childValidateResult) return;
 
     if (!tmpDetailId.value) {
       ElMessage.error('缺少必要参数');
@@ -66,6 +83,7 @@
         noticeScope: ruleFormData.noticeScope,
         requestTime: ruleFormData.requestTime,
         requestLocation: ruleFormData.requestLocation,
+        userGroupIds: ruleFormData.userGroupIds,
       });
       ElMessage.success('通知成功');
       basicDialogRef.value?.closeDialog();
@@ -74,6 +92,7 @@
       ruleFormData.noticeScope = NOTIFY_RANGE.ALL;
       ruleFormData.requestTime = '';
       ruleFormData.requestLocation = '';
+      ruleFormData.userGroupIds = [];
       // 触发父组件刷新列表
       emits('success');
     } catch (error) {
@@ -85,6 +104,9 @@
   // 刷新表单数据(在对话框打开时调用,用于清除验证状态)
   const refreshFormData = () => {
     basicFormRef.value?.clearValidate();
+    if (selectGroupRef.value) {
+      selectGroupRef.value.clearValidate();
+    }
   };
 
   defineExpose({
@@ -92,4 +114,15 @@
   });
 </script>
 
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+  .select-group-container {
+    width: 600px;
+    margin: 32px 0;
+
+    :deep(.el-form) {
+      .el-form-item__label {
+        padding: 0;
+      }
+    }
+  }
+</style>

+ 1 - 0
src/views/emergency/emergency-supplies/src/config/form.ts

@@ -434,6 +434,7 @@ export const NOTIFY_DEPARTMENT_FORM_DATA = {
   noticeScope: NOTIFY_RANGE.ALL,
   requestTime: '',
   requestLocation: '',
+  userGroupIds: [] as number[],
 };
 
 // 物资领用通知表单规则

+ 1 - 1
src/views/emergency/emergency-supplies/src/constant/index.ts

@@ -28,7 +28,7 @@ export const EMERGENCY_SUPPLY_TABS = [
   },
 ];
 
-enum CHANGE_TYPE {
+export enum CHANGE_TYPE {
   CHECK = 1,
   CHANGE,
   DISCARD,

+ 13 - 9
src/views/security-confidentiality/overview/components/SecurityPosition.vue

@@ -67,7 +67,7 @@
   };
 
   const getCameraUrl = (val: CameraInfo) => {
-    if (val.pushStreamDTO && val.pushStreamDTO.videoUrls) {
+    if (val.pushStreamDTO && val.pushStreamDTO.videoUrls.pushstreamIp) {
       const videoUrl = val.pushStreamDTO.videoUrls.pushstreamIp;
       const protocol = isHttps() ? 'wss' : 'ws';
       // 如果是绝对地址
@@ -97,15 +97,19 @@
     getSecurityPositionList({
       groupName: '',
       cameraName: '',
-    }).then((res) => {
-      securityPositionCameraInfo.value = res.flatMap((item) => {
-        return item.children.map((child) => ({
-          ...child,
-          positionName: item.groupName,
-        }));
+    })
+      .then((res) => {
+        securityPositionCameraInfo.value = res.flatMap((item) => {
+          return item.children.map((child) => ({
+            ...child,
+            positionName: item.groupName,
+          }));
+        });
+        positionCameraCount.value = securityPositionCameraInfo.value.length;
+      })
+      .catch((err) => {
+        console.log(err);
       });
-      positionCameraCount.value = securityPositionCameraInfo.value.length;
-    });
   });
 
   window.onresize = () => {