Przeglądaj źródła

任务进度更新

Hwf 6 miesięcy temu
rodzic
commit
be79653677

+ 79 - 11
src/components/FileUpload/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div>
+  <div style="width:100%;">
     <div class="flex-box">
       <van-uploader
           multiple
@@ -9,21 +9,37 @@
           @oversize="onOversize"
           :before-read="beforeRead"
           :after-read="afterRead">
-        <van-button icon="plus" type="primary" class="button">上传文件</van-button>
+        <div class="add-box">
+          <van-icon name="plus" color="#DCE0EE" />
+        </div>
+<!--        <van-button icon="plus" type="primary" class="button">上传文件</van-button>-->
       </van-uploader>
       <slot></slot>
-    </div>
-    <div v-if="isShowTip" class="upload-tip">
-      <div v-if="fileType">1、支持{{ fileType.join('、') }}文件</div>
-      <div v-if="limit">2、最多支持上传{{limit}}个文件</div>
+      <slot name="upload-tip"></slot>
+      <div v-if="isShowTip" class="upload-tip">
+        <div v-if="fileType">支持{{ fileType.join('、') }}文件</div>
+        <div v-if="limit">最多支持上传{{limit}}个文件</div>
+      </div>
     </div>
     <!-- 文件列表 -->
-    <transition-group class="upload-file-list" name="el-fade-in-linear" tag="ul">
-      <li v-for="(file, index) in fileList" :key="file.uid" class="upload-list-item">
+    <transition-group v-if="type === 'image'" class="upload-file-list" name="el-fade-in-linear" tag="ul">
+      <div v-for="(file, index) in fileList" :key="file.uid" class="upload-list-item">
+        <van-image
+            width="90"
+            height="70"
+            :src="baseUrl + downLoadApi + file.url"
+        />
+        <div class="delete-icon" @click="handleDelete(index)">
+          <van-icon name="cross" color="#FFFFFF" size="8" />
+        </div>
+      </div>
+    </transition-group>
+    <transition-group v-else class="upload-file-list" name="el-fade-in-linear" tag="ul">
+      <li v-for="(file, index) in fileList" :key="file.uid" class="upload-list-item2">
         <div class="text-primary" @click="handleDownload(file)">
           {{ getFileName(file.name) }}
         </div>
-        <van-icon name="delete-o" class="delete-icon" @click="handleDelete(index)"/>
+        <van-icon name="delete-o" class="delete-icon2" @click="handleDelete(index)"/>
       </li>
     </transition-group>
   </div>
@@ -41,6 +57,9 @@ const props = defineProps({
     type: [String, Object, Array],
     default: () => []
   },
+  type: {
+    type: String
+  },
   buttonText: {
     type: String,
     default: '选取文件'
@@ -67,7 +86,7 @@ const props = defineProps({
   }
 });
 
-const emit = defineEmits(['update:modelValue']);
+const emit = defineEmits(['update:modelValue', 'change']);
 const number = ref(0);
 const uploadList = ref<any[]>([]);
 
@@ -213,12 +232,14 @@ const uploadedSuccessfully = () => {
     uploadList.value = [];
     number.value = 0;
     emit('update:modelValue', fileList.value);
+    emit('change', fileList.value);
   }
 };
 // 删除文件
 const handleDelete = (index: number) => {
   fileList.value.splice(index, 1);
   emit('update:modelValue', fileList.value);
+  emit('change', fileList.value);
 };
 // 获取文件名称
 const getFileName = (name: string) => {
@@ -248,14 +269,50 @@ const handleDownload = (file: any) => {
   font-size: 14px;
 }
 .upload-file-list {
+  width: 100%;
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
   .upload-list-item {
+    position: relative;
+    width: 90px;
+    height: 70px;
+    margin-top: 17px;
+    margin-right: 17px;
+    &:nth-child(n + 3) {
+      margin-right: 0;
+    }
+    .text-primary {
+      color: #2c81ff;
+      font-size: 14px;
+    }
+    .delete-icon {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      width: 12px;
+      height: 12px;
+      background: #2C81FF;
+      border-radius: 50%;
+      position: absolute;
+      top: -6px;
+      right: -6px;
+    }
+    .delete-icon2 {
+      color: #969799;
+      font-size: 20px;
+      margin-left: 5px;
+    }
+  }
+  .upload-list-item2 {
     display: flex;
     align-items: center;
+    position: relative;
     .text-primary {
       color: #2c81ff;
       font-size: 14px;
     }
-    .delete-icon {
+    .delete-icon2 {
       color: #969799;
       font-size: 20px;
       margin-left: 5px;
@@ -266,4 +323,15 @@ const handleDownload = (file: any) => {
   display: flex;
   align-items: center;
 }
+.add-box {
+  width: 48px;
+  height: 48px;
+  background: #FFFFFF;
+  border: 1px solid #DCE0EE;
+  border-radius: 2px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 10px;
+}
 </style>

+ 9 - 0
src/router/routes.ts

@@ -341,6 +341,15 @@ export const constantRoutes: Array<RouteRecordRaw> = [
       title: "响应人员报送",
       noCache: true
     }
+  },
+  {
+    path: "/taskProgressUpdate",
+    name: "TaskProgressUpdate",
+    component: () => import("@/views/mobileControl/TaskProgressUpdate.vue"),
+    meta: {
+      title: "任务进度更新",
+      noCache: true
+    }
   }
 ];
 

+ 17 - 7
src/styles/index.less

@@ -191,16 +191,26 @@ a:hover {
       margin-right: 9px;
       color: #414F64;
     }
-    .van-field__body {
-      border: 1px solid #DCE0EE;
-      border-radius: 2px;
-      .van-field__control {
-        height: 30px;
-        padding: 0 5px;
-        color: #414F64;
+    .common-field {
+      .van-field__body {
+        border: 1px solid #DCE0EE;
+        border-radius: 2px;
+        .van-field__control {
+          min-height: 30px;
+          padding: 0 5px;
+          color: #414F64;
+        }
       }
     }
   }
+  .common-textarea {
+    .van-field__error-message {
+      position: absolute;
+      bottom: -3px;
+      left: 0;
+      margin-top: 0;
+    }
+  }
   .common-form-footer {
     position: fixed;
     left: 0;

+ 5 - 0
src/utils/validate.ts

@@ -11,3 +11,8 @@ export function validatePhone(phoneNumber: string) {
   // 使用正则表达式进行校验
   return pattern.test(phoneNumber);
 }
+
+export function validateFile(fieList: []) {
+  debugger
+  return fieList && fieList.length > 0;
+}

+ 7 - 4
src/views/InformationReception/infoDetails.vue

@@ -56,7 +56,7 @@
       <div class="confirm-btn" @click="handleSubmitted">响应人员报送</div>
     </div>
     <div v-if="infoDetail.info_type === '1'" class="box2">
-      <div class="confirm-btn">进度更新</div>
+      <div class="confirm-btn" @click="handleTaskUpdate">进度更新</div>
       <div class="confirm-btn">工作请示</div>
     </div>
     <div v-if="infoDetail.response_type === 1" class="box1">
@@ -87,6 +87,7 @@ import { showFailToast } from "vant";
 const route = useRoute();
 const router = useRouter();
 const infoDetail = ref({
+  id: '',
   // 0预案通知 1事件接报
   info_type: '',
   // 0阅读 1点击确认 2签字确认
@@ -104,10 +105,12 @@ let infoId = ref();
 let showSignature = ref(false);
 const baseUrl = import.meta.env.VITE_BASE_API;
 
-const handleSubmitted = () => {
-  router.push({ name: 'PersonSubmitted'})
+const handleSubmitted = (id) => {
+  router.push({ name: 'PersonSubmitted', query: { id: infoDetail.value.id}});
 };
-
+const handleTaskUpdate = (id) => {
+  router.push({ name: 'TaskProgressUpdate', query: { id: infoDetail.value.id }});
+}
 const handleReceive = () => {
   confirmReceived({id: infoId.value}).then((res)=>{
     infoDetail.value.response_status = res.data.response_status;

+ 16 - 9
src/views/InformationReception/personSubmitted.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="common-form-container">
-    <van-form label-width="60" @submit="onSubmit">
+    <van-form label-width="60" colon  @submit="onSubmit">
       <div v-for="(item, index) in form.data1" :key="index" class="form-item">
         <div v-if="index === 0" class="form-header">
           <div class="form-header-left">
@@ -24,14 +24,16 @@
 
             <van-field
                 v-model="item.name"
-                label="姓名:"
+                class="common-field"
+                label="姓名"
                 placeholder="请输入姓名"
                 :rules="rules.name"
             />
             <van-field
                 v-model="item.phone"
+                class="common-field"
                 type="tel"
-                label="联系方式:"
+                label="联系方式"
                 placeholder="请输入联系方式"
                 :rules="rules.phone"
             />
@@ -63,21 +65,20 @@
             </div>
             <van-field
                 v-model="item.name"
-                label="姓名:"
+                class="common-field"
+                label="姓名"
                 placeholder="请输入姓名"
                 :rules="rules.name"
             />
             <van-field
                 v-model="item.phone"
+                class="common-field"
                 type="tel"
-                label="联系方式:"
+                label="联系方式"
                 placeholder="请输入联系方式"
                 :rules="rules.phone"
             />
           </div>
-          <van-cell-group inset>
-
-          </van-cell-group>
         </div>
       </div>
       <div class="common-form-footer">
@@ -92,9 +93,11 @@
 import { reactive, ref } from "vue";
 import { validatePhone } from "@/utils/validate";
 import { showConfirmDialog, showSuccessToast } from "vant";
-import { useRouter } from "vue-router";
+import { useRoute, useRouter } from "vue-router";
 
+const route = useRoute();
 const router = useRouter();
+let id = ref('');
 // 表单数据
 const form = ref<PersonSubmittedForm>({
   // 赶赴现场人员
@@ -152,6 +155,10 @@ const onSubmit = () => {
     onCancel();
   }, 1500);
 }
+
+onMounted(() => {
+  id.value = route.query.id;
+})
 </script>
 
 <style lang="scss" scoped>

+ 146 - 0
src/views/mobileControl/TaskProgressUpdate.vue

@@ -0,0 +1,146 @@
+<template>
+  <div class="common-form-container">
+    <van-form label-width="90" label-align="top" colon @submit="onSubmit">
+      <div class="form-item">
+        <div class="form-header">
+          <div class="form-header-left">
+            <i class="line-icon" />
+            <div class="form-title">任务进度更新</div>
+          </div>
+        </div>
+        <div class="common-form-content">
+          <div class="common-form-item">
+            <van-field
+                v-model="form.processing_status_text"
+                class="common-field"
+                :right-icon="selectIcon"
+                readonly
+                label="任务完成情况"
+                placeholder="请输入任务完成情况"
+                :rules="rules.processing_status"
+                @click="showPicker = true"
+            />
+            <van-field
+                v-model="form.feedback_content"
+                class="common-field common-textarea"
+                rows="8"
+                type="textarea"
+                label="反馈内容"
+                maxlength="300"
+                placeholder="请描述现场情况"
+                show-word-limit
+                :rules="rules.feedback_content"
+            />
+            <van-field label="文件上传" :error-message="uploaderErrors">
+              <template #input>
+                <FileUpload v-model="form.fileList" type="image" :file-size="5" :limit="12" :isShowTip="false" :fileType="['png', 'jpg', 'jpeg']" @change="handleFileListChange">
+                  <template #upload-tip>
+                    <div class="upload-tip">
+                      <div>支持上传png、jpg、jpeg</div>
+                      <div>文件不大于5M</div>
+                    </div>
+                  </template>
+                </FileUpload>
+              </template>
+            </van-field>
+          </div>
+        </div>
+      </div>
+      <div class="common-form-footer">
+        <van-button class="btn" @click="onCancel">取消</van-button>
+        <van-button class="btn primary-btn" :loading="submitting" type="primary" native-type="submit">提交</van-button>
+      </div>
+    </van-form>
+    <van-popup v-model:show="showPicker" destroy-on-close round position="bottom">
+      <van-picker
+          :model-value="pickerValue"
+          :columns="options"
+          @cancel="showPicker = false"
+          @confirm="onConfirm"
+      />
+    </van-popup>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import {useRoute, useRouter} from "vue-router";
+import {reactive, ref} from "vue";
+import {showSuccessToast} from "vant";
+import selectIcon from  "@/assets/images/selectIcon.png";
+import {Numeric} from "vant/es/utils";
+import FileUpload from "@/components/FileUpload/index.vue";
+import {validateFile} from "@/utils/validate";
+
+const route = useRoute();
+const router = useRouter();
+let id = ref('');
+// 表单数据
+const form = ref({
+  processing_status: '',
+  processing_status_text: '',
+  feedback_content: '',
+  fileList: []
+});
+const pickerValue = ref<Numeric[]>([]);
+let uploaderErrors = ref('');
+// 表单校验规则
+const rules = reactive({
+  processing_status: [{ required: true, message: '请选择任务完成情况' }],
+  feedback_content: [{ required: true, message: '反馈内容不能为空' }],
+  fileList: [{ validator: validateFile, message: '请上传文件' }]
+});
+let showPicker = ref(false);
+
+const options = [
+  { text: '处理中', value: '处理中' },
+  { text: '已完成', value: '已完成' },
+];
+// 选择任务完成情况
+const onConfirm = ({ selectedValues, selectedOptions }) => {
+  showPicker.value = false;
+  pickerValue.value = selectedValues;
+  form.value.processing_status = selectedOptions[0].value;
+  form.value.processing_status_text = selectedOptions[0].text;
+};
+// 是否在提交
+let submitting = ref(false);
+// 文件上传回调
+const handleFileListChange = () => {
+  let flag = true;
+  if (form.value.fileList && form.value.fileList.length === 0) {
+    uploaderErrors.value = '请上传文件';
+    flag = false;
+  }
+  uploaderErrors.value = '';
+  return flag;
+};
+// 返回
+const onCancel = () => {
+  router.go(-1);
+};
+
+// 提交表单
+const onSubmit = () => {
+  if (submitting.value) return;
+  let flag = handleFileListChange();
+  if (!flag) return;
+  uploaderErrors.value = '';
+  submitting.value = true;
+  setTimeout(() => {
+    submitting.value = false;
+    showSuccessToast('提交成功');
+    onCancel();
+  }, 1500);
+}
+
+onMounted(() => {
+  id.value = route.query.id;
+})
+</script>
+
+<style lang="scss" scoped>
+.upload-tip {
+  font-size: 12px;
+  color: rgba(0, 0, 0, 0.45);
+}
+</style>