Просмотр исходного кода

feat: 添加交通管理与通知的表单页

wyf 8 месяцев назад
Родитель
Сommit
31c698ce6a

+ 1 - 1
src/constant/nav.ts

@@ -24,7 +24,7 @@ export const NAV_LIST = [
     },
   },
   {
-    name: '交通安全',
+    name: 'Traffic',
     path: '/traffic',
     meta: {
       title: '交通安全',

+ 1 - 8
src/views/traffic/regulation/RegulationItem.vue

@@ -4,21 +4,14 @@
       <BreadcrumbBack />
       <span class="breadcrumb-title">{{ headerTitle }}</span>
     </header>
-    <main class="safety-platform-container__main">
-      <component :is="dynamicComponent" ref="dynamicComponentRef" @record-submitted="handleRecordSubmitted" />
-    </main>
-    <!-- <footer class="safety-platform-container__footer">
-    </footer> -->
-    <UploadLoading :form-loading="formLoading" v-if="formLoading" />
+    <component :is="dynamicComponent" ref="dynamicComponentRef" @record-submitted="handleRecordSubmitted" />
   </div>
 </template>
 
 <script setup lang="ts">
   import { ref, computed, defineAsyncComponent } from 'vue';
   import { useRoute } from 'vue-router';
-  import UploadLoading from '@/components/UploadLoading.vue';
 
-  const formLoading = ref(false);
   const route = useRoute();
   const operate = route.query.operate;
   const headerTitle = computed(() => {

+ 91 - 3
src/views/traffic/regulation/components/NoticeCreate.vue

@@ -1,7 +1,95 @@
 <template>
-  <div>创建管理通知</div>
+  <main class="safety-platform-container__main">
+    <BasicForm ref="basicFormRef" :formData="ruleFormData" :formRules="formRules" :formConfig="ruleFormConfig">
+      <template #noticeFiles>
+        <UploadFiles label="上传附件" ref="uploadFilesRef" @uploadSuccess="handleUploadSuccess" />
+      </template>
+      <template #isPush>
+        <el-radio-group v-model="ruleFormData.isPush">
+          <el-radio :value="IS_PUSH.PUSH">是</el-radio>
+          <el-radio :value="IS_PUSH.NOT_PUSH">否</el-radio>
+        </el-radio-group>
+        <SelectGroup
+          v-if="ruleFormData.isPush === IS_PUSH.PUSH"
+          ref="selectGroupRef"
+          :userGroupList="ruleFormData.userGroupList || []"
+          @userGroupListChange="handleUserGroupListChange"
+        />
+      </template>
+    </BasicForm>
+  </main>
+  <footer class="safety-platform-container__footer">
+    <el-button @click="router.back()">取消</el-button>
+    <el-button type="primary" @click="handleSubmit">提交</el-button>
+  </footer>
+  <UploadLoading :form-loading="formLoading" v-if="formLoading" />
 </template>
 
-<script setup lang="ts"></script>
+<script setup lang="ts">
+  import BasicForm from '@/components/BasicForm.vue';
+  import UploadFiles from '@/views/disaster/components/UploadFiles.vue';
+  import SelectGroup from '@/components/PersonGroup/SelectGroup.vue';
+  import { useFormConfigHook } from '@/hooks/useFormConfigHook';
+  import { useUserInfoHook } from '@/views/disaster/hooks';
+  import { IS_PUSH } from '../constants';
+  import { NOTICE_FORM_CONFIG, NOTICE_FORM_DATA, NOTICE_FORM_RULES } from '../configs/form';
+  import { FileItem, NoticeRuleForm } from '../types';
+  import { onMounted, ref } from 'vue';
+  import UploadLoading from '@/components/UploadLoading.vue';
+  import { useRouter } from 'vue-router';
 
-<style scoped></style>
+  const { realname } = useUserInfoHook();
+
+  const { ruleFormData, formRules, ruleFormConfig, cloneRuleFormData, beforeRouteLeave } =
+    useFormConfigHook<NoticeRuleForm>(NOTICE_FORM_CONFIG, NOTICE_FORM_DATA, NOTICE_FORM_RULES);
+
+  const basicFormRef = ref<InstanceType<typeof BasicForm>>();
+  const selectGroupRef = ref<InstanceType<typeof SelectGroup>>();
+
+  const handleUserGroupListChange = (userGroupList: number[]) => {
+    ruleFormData.userGroupList = userGroupList;
+  };
+
+  const handleUploadSuccess = (fileList: FileItem[]) => {
+    ruleFormData.noticeFiles = fileList;
+  };
+
+  const handleValidate = async () => {
+    if (!basicFormRef.value) return;
+    const parentValidateResult = await basicFormRef.value.validateForm();
+    let childValidateResult = true;
+    if (selectGroupRef.value) {
+      childValidateResult = (await selectGroupRef.value.validateForm()) as boolean;
+    }
+    return parentValidateResult && childValidateResult;
+  };
+
+  const getFormData = () => {
+    if (!ruleFormData.isPush) {
+      ruleFormData.userGroupList = [];
+    }
+    cloneRuleFormData();
+    return ruleFormData;
+  };
+
+  const formLoading = ref(false);
+  const router = useRouter();
+  const handleSubmit = () => {
+    handleValidate();
+  };
+
+  // defineExpose({
+  //   handleValidate,
+  //   getFormData,
+  // });
+
+  onMounted(() => {
+    ruleFormData.realname = realname;
+    cloneRuleFormData();
+    beforeRouteLeave();
+  });
+</script>
+
+<style scoped lang="scss">
+  @use '@/styles/page-details-layout.scss' as *;
+</style>

+ 95 - 3
src/views/traffic/regulation/components/NoticeEdit.vue

@@ -1,7 +1,99 @@
 <template>
-  <div></div>
+  <main class="safety-platform-container__main">
+    <BasicForm ref="basicFormRef" :formData="ruleFormData" :formRules="formRules" :formConfig="ruleFormConfig">
+      <template #noticeFiles>
+        <UploadFiles label="上传附件" ref="uploadFilesRef" @uploadSuccess="handleUploadSuccess" />
+      </template>
+      <template #isPush>
+        <el-radio-group v-model="ruleFormData.isPush">
+          <el-radio :value="IS_PUSH.PUSH">是</el-radio>
+          <el-radio :value="IS_PUSH.NOT_PUSH">否</el-radio>
+        </el-radio-group>
+        <SelectGroup
+          v-if="ruleFormData.isPush === IS_PUSH.PUSH"
+          ref="selectGroupRef"
+          :userGroupList="ruleFormData.userGroupList || []"
+          @userGroupListChange="handleUserGroupListChange"
+        />
+      </template>
+    </BasicForm>
+  </main>
+  <footer class="safety-platform-container__footer">
+    <el-button @click="router.back()">取消</el-button>
+    <el-button type="primary" @click="handleSubmit">提交</el-button>
+  </footer>
+  <UploadLoading :form-loading="formLoading" v-if="formLoading" />
 </template>
 
-<script setup lang="ts"></script>
+<script setup lang="ts">
+  import BasicForm from '@/components/BasicForm.vue';
+  import UploadFiles from '@/views/disaster/components/UploadFiles.vue';
+  import SelectGroup from '@/components/PersonGroup/SelectGroup.vue';
+  import { useFormConfigHook } from '@/hooks/useFormConfigHook';
+  import { IS_PUSH } from '../constants';
+  import { NOTICE_FORM_CONFIG, NOTICE_FORM_DATA, NOTICE_FORM_RULES } from '../configs/form';
+  import { FileItem, NoticeRuleForm } from '../types';
+  import { onMounted, ref } from 'vue';
+  import UploadLoading from '@/components/UploadLoading.vue';
+  import { useRouter } from 'vue-router';
 
-<style scoped lang="scss"></style>
+  const props = defineProps<{
+    id: number;
+  }>();
+  const getNoticeDetail = async () => {
+    // TODO 获取详情并写入表单
+  };
+
+  const { ruleFormData, formRules, ruleFormConfig, cloneRuleFormData, beforeRouteLeave } =
+    useFormConfigHook<NoticeRuleForm>(NOTICE_FORM_CONFIG, NOTICE_FORM_DATA, NOTICE_FORM_RULES);
+
+  const basicFormRef = ref<InstanceType<typeof BasicForm>>();
+  const selectGroupRef = ref<InstanceType<typeof SelectGroup>>();
+
+  const handleUserGroupListChange = (userGroupList: number[]) => {
+    ruleFormData.userGroupList = userGroupList;
+  };
+
+  const handleUploadSuccess = (fileList: FileItem[]) => {
+    ruleFormData.noticeFiles = fileList;
+  };
+
+  const handleValidate = async () => {
+    if (!basicFormRef.value) return;
+    const parentValidateResult = await basicFormRef.value.validateForm();
+    let childValidateResult = true;
+    if (selectGroupRef.value) {
+      childValidateResult = (await selectGroupRef.value.validateForm()) as boolean;
+    }
+    return parentValidateResult && childValidateResult;
+  };
+
+  const getFormData = () => {
+    if (!ruleFormData.isPush) {
+      ruleFormData.userGroupList = [];
+    }
+    cloneRuleFormData();
+    return ruleFormData;
+  };
+
+  const formLoading = ref(false);
+  const router = useRouter();
+  const handleSubmit = () => {
+    handleValidate();
+  };
+
+  // defineExpose({
+  //   handleValidate,
+  //   getFormData,
+  // });
+
+  onMounted(async () => {
+    await getNoticeDetail();
+    cloneRuleFormData();
+    beforeRouteLeave();
+  });
+</script>
+
+<style scoped lang="scss">
+  @use '@/styles/page-details-layout.scss' as *;
+</style>

+ 1 - 1
src/views/traffic/regulation/components/NoticeTable.vue

@@ -10,7 +10,7 @@
         <el-input
           class="regulation-search-input"
           v-model="searchData"
-          placeholder="输入通知标题或文件名称"
+          placeholder="输入通知标题或文件名称"
           :prefix-icon="Search"
           clearable
         >

+ 91 - 3
src/views/traffic/regulation/components/RegulationCreate.vue

@@ -1,7 +1,95 @@
 <template>
-  <div> </div>
+  <main class="safety-platform-container__main">
+    <BasicForm ref="basicFormRef" :formData="ruleFormData" :formRules="formRules" :formConfig="ruleFormConfig">
+      <template #regulationFiles>
+        <UploadFiles label="上传附件" ref="uploadFilesRef" @uploadSuccess="handleUploadSuccess" />
+      </template>
+      <template #isPush>
+        <el-radio-group v-model="ruleFormData.isPush">
+          <el-radio :value="IS_PUSH.PUSH">是</el-radio>
+          <el-radio :value="IS_PUSH.NOT_PUSH">否</el-radio>
+        </el-radio-group>
+        <SelectGroup
+          v-if="ruleFormData.isPush === IS_PUSH.PUSH"
+          ref="selectGroupRef"
+          :userGroupList="ruleFormData.userGroupList || []"
+          @userGroupListChange="handleUserGroupListChange"
+        />
+      </template>
+    </BasicForm>
+  </main>
+  <footer class="safety-platform-container__footer">
+    <el-button @click="router.back()">取消</el-button>
+    <el-button type="primary" @click="handleSubmit">提交</el-button>
+  </footer>
+  <UploadLoading :form-loading="formLoading" v-if="formLoading" />
 </template>
 
-<script setup lang="ts"></script>
+<script setup lang="ts">
+  import BasicForm from '@/components/BasicForm.vue';
+  import UploadFiles from '@/views/disaster/components/UploadFiles.vue';
+  import SelectGroup from '@/components/PersonGroup/SelectGroup.vue';
+  import { useFormConfigHook } from '@/hooks/useFormConfigHook';
+  import { useUserInfoHook } from '@/views/disaster/hooks';
+  import { IS_PUSH } from '../constants';
+  import { REGULATION_FORM_CONFIG, REGULATION_FORM_DATA, REGULATION_FORM_RULES } from '../configs/form';
+  import { FileItem, RegulationRuleForm } from '../types';
+  import { onMounted, ref } from 'vue';
+  import UploadLoading from '@/components/UploadLoading.vue';
+  import { useRouter } from 'vue-router';
 
-<style scoped></style>
+  const { realname } = useUserInfoHook();
+
+  const { ruleFormData, formRules, ruleFormConfig, cloneRuleFormData, beforeRouteLeave } =
+    useFormConfigHook<RegulationRuleForm>(REGULATION_FORM_CONFIG, REGULATION_FORM_DATA, REGULATION_FORM_RULES);
+
+  const basicFormRef = ref<InstanceType<typeof BasicForm>>();
+  const selectGroupRef = ref<InstanceType<typeof SelectGroup>>();
+
+  const handleUserGroupListChange = (userGroupList: number[]) => {
+    ruleFormData.userGroupList = userGroupList;
+  };
+
+  const handleUploadSuccess = (fileList: FileItem[]) => {
+    ruleFormData.regulationFiles = fileList;
+  };
+
+  const handleValidate = async () => {
+    if (!basicFormRef.value) return;
+    const parentValidateResult = await basicFormRef.value.validateForm();
+    let childValidateResult = true;
+    if (selectGroupRef.value) {
+      childValidateResult = (await selectGroupRef.value.validateForm()) as boolean;
+    }
+    return parentValidateResult && childValidateResult;
+  };
+
+  const getFormData = () => {
+    if (!ruleFormData.isPush) {
+      ruleFormData.userGroupList = [];
+    }
+    cloneRuleFormData();
+    return ruleFormData;
+  };
+
+  const formLoading = ref(false);
+  const router = useRouter();
+  const handleSubmit = () => {
+    handleValidate();
+  };
+
+  // defineExpose({
+  //   handleValidate,
+  //   getFormData,
+  // });
+
+  onMounted(() => {
+    ruleFormData.realname = realname;
+    cloneRuleFormData();
+    beforeRouteLeave();
+  });
+</script>
+
+<style scoped lang="scss">
+  @use '@/styles/page-details-layout.scss' as *;
+</style>

+ 95 - 3
src/views/traffic/regulation/components/RegulationEdit.vue

@@ -1,7 +1,99 @@
 <template>
-  <div>创建管理规定</div>
+  <main class="safety-platform-container__main">
+    <BasicForm ref="basicFormRef" :formData="ruleFormData" :formRules="formRules" :formConfig="ruleFormConfig">
+      <template #regulationFiles>
+        <UploadFiles label="上传附件" ref="uploadFilesRef" @uploadSuccess="handleUploadSuccess" />
+      </template>
+      <template #isPush>
+        <el-radio-group v-model="ruleFormData.isPush">
+          <el-radio :value="IS_PUSH.PUSH">是</el-radio>
+          <el-radio :value="IS_PUSH.NOT_PUSH">否</el-radio>
+        </el-radio-group>
+        <SelectGroup
+          v-if="ruleFormData.isPush === IS_PUSH.PUSH"
+          ref="selectGroupRef"
+          :userGroupList="ruleFormData.userGroupList || []"
+          @userGroupListChange="handleUserGroupListChange"
+        />
+      </template>
+    </BasicForm>
+  </main>
+  <footer class="safety-platform-container__footer">
+    <el-button @click="router.back()">取消</el-button>
+    <el-button type="primary" @click="handleSubmit">提交</el-button>
+  </footer>
+  <UploadLoading :form-loading="formLoading" v-if="formLoading" />
 </template>
 
-<script setup lang="ts"></script>
+<script setup lang="ts">
+  import BasicForm from '@/components/BasicForm.vue';
+  import UploadFiles from '@/views/disaster/components/UploadFiles.vue';
+  import SelectGroup from '@/components/PersonGroup/SelectGroup.vue';
+  import { useFormConfigHook } from '@/hooks/useFormConfigHook';
+  import { IS_PUSH } from '../constants';
+  import { REGULATION_FORM_CONFIG, REGULATION_FORM_DATA, REGULATION_FORM_RULES } from '../configs/form';
+  import { FileItem, RegulationRuleForm } from '../types';
+  import { onMounted, ref } from 'vue';
+  import UploadLoading from '@/components/UploadLoading.vue';
+  import { useRouter } from 'vue-router';
 
-<style scoped></style>
+  const props = defineProps<{
+    id: number;
+  }>();
+
+  const { ruleFormData, formRules, ruleFormConfig, cloneRuleFormData, beforeRouteLeave } =
+    useFormConfigHook<RegulationRuleForm>(REGULATION_FORM_CONFIG, REGULATION_FORM_DATA, REGULATION_FORM_RULES);
+
+  const basicFormRef = ref<InstanceType<typeof BasicForm>>();
+  const selectGroupRef = ref<InstanceType<typeof SelectGroup>>();
+
+  const getRegulationDetail = async () => {
+    // TODO 获取详情并写入表单
+  };
+  const handleUserGroupListChange = (userGroupList: number[]) => {
+    ruleFormData.userGroupList = userGroupList;
+  };
+
+  const handleUploadSuccess = (fileList: FileItem[]) => {
+    ruleFormData.regulationFiles = fileList;
+  };
+
+  const handleValidate = async () => {
+    if (!basicFormRef.value) return;
+    const parentValidateResult = await basicFormRef.value.validateForm();
+    let childValidateResult = true;
+    if (selectGroupRef.value) {
+      childValidateResult = (await selectGroupRef.value.validateForm()) as boolean;
+    }
+    return parentValidateResult && childValidateResult;
+  };
+
+  const getFormData = () => {
+    if (!ruleFormData.isPush) {
+      ruleFormData.userGroupList = [];
+    }
+    cloneRuleFormData();
+    return ruleFormData;
+  };
+
+  const formLoading = ref(false);
+  const router = useRouter();
+  const handleSubmit = () => {
+    handleValidate();
+  };
+
+  // defineExpose({
+  //   handleValidate,
+  //   getFormData,
+  // });
+
+  onMounted(async () => {
+    await getRegulationDetail();
+    cloneRuleFormData();
+    beforeRouteLeave();
+  });
+</script>
+
+<style scoped lang="scss">
+  @use '@/styles/page-details-layout.scss' as *;
+</style>

+ 1 - 1
src/views/traffic/regulation/components/RegulationTable.vue

@@ -10,7 +10,7 @@
         <el-input
           class="regulation-search-input"
           v-model="searchData"
-          placeholder="输入规定标题或文件名称"
+          placeholder="输入规定标题或文件名称"
           :prefix-icon="Search"
           clearable
         >

+ 125 - 0
src/views/traffic/regulation/configs/form.ts

@@ -0,0 +1,125 @@
+import { FormConfig } from '@/types/basic-form';
+
+export const REGULATION_FORM_CONFIG: FormConfig[] = [
+  {
+    prop: 'name',
+    label: '名称:',
+    component: 'ElInput',
+    componentProps: {
+      placeholder: '请输入管理规定的标题',
+      maxlength: 200,
+      showWordLimit: true,
+    },
+  },
+  {
+    prop: 'regulationFiles',
+    label: '规定文件:',
+    slot: 'regulationFiles',
+  },
+  {
+    prop: 'isPush',
+    label: '是否推送:',
+    slot: 'isPush',
+  },
+  {
+    label: '备注:',
+    prop: 'memo',
+    component: 'ElInput',
+    componentProps: {
+      type: 'textarea',
+      rows: 5,
+      maxlength: 1000,
+      showWordLimit: true,
+    },
+  },
+  {
+    label: '创建人:',
+    prop: 'realname',
+    component: 'ElInput',
+    componentProps: {
+      disabled: true,
+    },
+  },
+];
+
+export const REGULATION_FORM_DATA = {
+  name: '',
+  regulationFiles: [],
+  isPush: null,
+  memo: '',
+  realname: '',
+};
+
+export const REGULATION_FORM_RULES = {
+  name: [{ required: true, message: '请输入管理规定的标题', trigger: 'blur' }],
+  regulationFiles: [{ required: true, message: '请上传规定文件', trigger: 'change' }],
+  isPush: [{ required: true, message: '请选择是否推送', trigger: 'change' }],
+};
+
+export const NOTICE_FORM_CONFIG: FormConfig[] = [
+  {
+    prop: 'name',
+    label: '通知标题:',
+    component: 'ElInput',
+    componentProps: {
+      placeholder: '请输入通知标题',
+      maxlength: 200,
+      showWordLimit: true,
+    },
+  },
+  {
+    label: '通知内容:',
+    prop: 'content',
+    component: 'ElInput',
+    componentProps: {
+      type: 'textarea',
+      rows: 5,
+      maxlength: 1000,
+      showWordLimit: true,
+    },
+  },
+  {
+    prop: 'noticeFiles',
+    label: '通知文件:',
+    slot: 'noticeFiles',
+  },
+  {
+    prop: 'isPush',
+    label: '是否推送:',
+    slot: 'isPush',
+  },
+  {
+    label: '备注:',
+    prop: 'memo',
+    component: 'ElInput',
+    componentProps: {
+      type: 'textarea',
+      rows: 5,
+      maxlength: 1000,
+      showWordLimit: true,
+    },
+  },
+  {
+    label: '创建人:',
+    prop: 'realname',
+    component: 'ElInput',
+    componentProps: {
+      disabled: true,
+    },
+  },
+];
+
+export const NOTICE_FORM_DATA = {
+  name: '',
+  content: '',
+  noticeFiles: [],
+  isPush: null,
+  memo: '',
+  realname: '',
+};
+
+export const NOTICE_FORM_RULES = {
+  name: [{ required: true, message: '请输入通知标题', trigger: 'blur' }],
+  content: [{ required: true, message: '请输入通知内容', trigger: 'blur' }],
+  isPush: [{ required: true, message: '请选择是否推送', trigger: 'change' }],
+};

+ 5 - 0
src/views/traffic/regulation/constants.ts

@@ -8,3 +8,8 @@ export const TRAFFIC_REGULATION_SUBPAGES = [
     value: 'notice',
   },
 ];
+
+export enum IS_PUSH {
+  NOT_PUSH = 0,
+  PUSH,
+}

+ 27 - 0
src/views/traffic/regulation/types.ts

@@ -0,0 +1,27 @@
+export interface RegulationRuleForm {
+  name: string;
+  regulationFiles: FileItem[];
+  isPush: number | null;
+  userGroupList?: number[];
+  memo?: string;
+  realname: string;
+}
+
+export interface NoticeRuleForm {
+  name: string;
+  content: string;
+  noticeFiles: FileItem[];
+  isPush: number | null;
+  userGroupList?: number[];
+  memo?: string;
+  realname: string;
+}
+
+export interface FileItem {
+  fileId: number;
+  fileName: string;
+  fileType: string;
+  fileSize: string;
+  fileUrl?: string;
+  file?: File;
+}