Hua 1 tydzień temu
rodzic
commit
2f1b8e5831

+ 460 - 0
src/views/InspectDC/Object/Problem/addProblem.vue

@@ -0,0 +1,460 @@
+<template>
+  <div class="pblm-detail-wrapper">
+    <van-form @submit="onSubmit">
+      <div class="pblm-detail-label">
+        <span>添加问题</span>
+        <!-- <van-button size="mini" type="primary" @click="showTacObjPblmstbPopup()">选择违规事项</van-button> -->
+      </div>
+      <van-cell-group inset>
+        
+        <van-field
+            v-model="tacObjPblmstb.inspPblmsName"
+            is-link
+            readonly
+            label="问题类别"
+            placeholder="选择对象"
+            @click="showPicker = true"
+        />
+        <van-popup v-model:show="showPicker" destroy-on-close round position="bottom">
+            <van-picker
+            :columns="columns"
+            @change="changeC1"
+            @cancel="showPicker = false"
+            @confirm="onConfirm"
+            />
+        </van-popup>
+        <van-field
+            v-model="tacObjPblmstb.checkPoint"
+            is-link
+            readonly
+            label="问题项目"
+            placeholder="选择对象"
+            @click="showPicker1 = true"
+        />
+        <van-popup v-model:show="showPicker1" destroy-on-close round position="bottom">
+            <van-picker
+            :columns="columns1"
+            @change="changeC2"
+            @cancel="showPicker1 = false"
+            @confirm="onConfirm1"
+            />
+        </van-popup>
+        <van-field
+            v-model="tacObjPblmstb.pblmDesc"
+            is-link
+            readonly
+            label="问题描述"
+            placeholder="选择对象"
+            @click="showPicker2 = true"
+        />
+        <van-popup v-model:show="showPicker2" destroy-on-close round position="bottom">
+            <van-picker
+            :columns="columns2"
+            @cancel="showPicker2 = false"
+            @confirm="onConfirm2"
+            />
+        </van-popup>
+        <van-field v-model="tacObjPblmstb.inspPblmDesc" placeholder="请输入对象名称" label="详细描述" rows="1" type="textarea"/>
+        <van-field v-model="tacObjPblmstb.inspPblmOrgName" placeholder="请输入" label="问题责任单位" />
+        <van-field v-model="tacObjPblmstb.note" placeholder="请输入对象名称" label="备注" rows="1" type="textarea"/>
+        <div style="display: flex;align-items: center;margin-top: -6%;">
+            <div style="width: 20%;text-align: center;font-weight: 700;font-size: 14px;">上传照片</div>
+            <van-uploader v-model="fileList" :after-read="afterRead" style=""/>
+        </div>
+      </van-cell-group>
+      <div style="margin: 16px;">
+        <van-button @click="addPro" block native-type="submit" round type="primary">
+          提交
+        </van-button>
+      </div>
+    </van-form>
+
+    <van-popup v-model:show="tacObjPblmstbShow" :style="{ width: '80%', height: '100%' }" position="left">
+    </van-popup>
+  </div>
+</template>
+<script setup>
+// /pdcApi/file/insert?bizId=
+import { showSuccessToast, showFailToast } from 'vant';
+import { getToken } from "@/utils/auth";
+import {computed, onMounted, ref, watch} from "vue";
+import {useRoute} from "vue-router";
+import { useAppStore } from '@/stores/app';
+import {useUserStore} from "@/stores/user";
+import request from "@/utils/request";
+import axios from 'axios';
+const route = useRoute();
+const userStore = useUserStore();
+const pblm = ref({});
+const tacObjPblmstb =  ref({
+});
+const columns = ref([]);
+const columns1 = ref([]);
+const columns2 = ref([]);
+const columns3 = ref([
+    { text: '是', value: '1' },
+    { text: '否', value: '0' }
+]);
+const fileList = ref([]);
+const showPicker = ref(false);
+const showPicker1 = ref(false);
+const showPicker2 = ref(false);
+const showPicker3 = ref(false);
+const pickerValue3 = ref([])
+const pickerValue = ref([])
+const pickerValue1 = ref([])
+const pickerValue2 = ref([])
+const router = useRoute();
+const parSectino = ref([]);
+const subjectList = ref([]);
+const picContent = ref('');
+const tacObjPblmstbShow = ref(false);
+function afterRead(file) {
+//   picContent.value = file.content
+  console.log(file,fileList.value);
+}
+function onConfirm3(selectedValues, selectedOptions) {
+  tacObjPblmstb.value.ifCasePblm = selectedValues.selectedOptions[0].text
+  showPicker3.value = false;
+}
+function onConfirm(selectedValues, selectedOptions) {
+  tacObjPblmstb.value.inspPblmsName = selectedValues.selectedOptions[0].text
+  showPicker.value = false;
+}
+function onConfirm1(selectedValues, selectedOptions) {
+  tacObjPblmstb.value.checkPoint = selectedValues.selectedOptions[0].text
+  showPicker1.value = false;
+}
+function onConfirm2(selectedValues, selectedOptions) {
+  tacObjPblmstb.value.pblmDesc = selectedValues.selectedOptions[0].text
+  showPicker2.value = false;
+}
+function changeC1(selectedValues, selectedOptions) {
+  columns1.value = []
+  columns2.value = []
+  parSectino.value.forEach(item => {
+    if(item.inspPblmsName === selectedValues.selectedValues[0]){
+        var par = {
+            text: item.checkPoint,
+            value: item.checkPoint
+        }
+        columns1.value.push(par);
+    }
+    columns1.value = [...new Set(columns1.value.map(item => JSON.stringify(item)))].map(str => JSON.parse(str))
+  })
+}
+function changeC2(selectedValues, selectedOptions) {
+  columns2.value = []
+  parSectino.value.forEach(item => {
+    if(item.checkPoint === selectedValues.selectedValues[0]){
+        var par = {
+            text: item.pblmDesc,
+            value: item.pblmDesc
+        }
+        columns2.value.push(par);
+    }
+    columns2.value = [...new Set(columns2.value.map(item => JSON.stringify(item)))].map(str => JSON.parse(str))
+  })
+  console.log(columns1.value)
+}
+function formatTime(timestamp) {
+  const date = new Date(timestamp);
+  const year = date.getFullYear();
+  const month = ('0' + (date.getMonth() + 1)).slice(-2);
+  const day = ('0' + date.getDate()).slice(-2);
+  const hours = ('0' + date.getHours()).slice(-2);
+  const minutes = ('0' + date.getMinutes()).slice(-2);
+  const seconds = ('0' + date.getSeconds()).slice(-2);
+  
+  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+}
+async function getSelection(){
+    await request.get(`/dc/insp/pblms/listByObjId/${pblm.value.objId}`).then(res=>{
+        parSectino.value = res.data
+        const uniqueInspPblmsName = [...new Set(res.data.map(item => item.inspPblmsName))];
+        const uniquePblmDesc = [...new Set(res.data.map(item => item.pblmDesc))];
+        const uniqueCheckPoint = [...new Set(res.data.map(item => item.checkPoint))];
+        // columns1.value = uniqueCheckPoint.map(item => ({ text: item, value: item }));
+        // columns2.value = uniquePblmDesc.map(item => ({ text: item, value: item }));
+        columns.value = uniqueInspPblmsName.map(item => ({ text: item, value: item }));
+    })
+}
+const parData = ref({});
+async function addPro(){
+    var a = {
+        "villType": "0",
+        "objId": "f4006678339a41ee80e673b99b94c73b",
+        "regid": "8a7c895e51da4fedb6bd4153eb9a2c1d",
+        "objType": 128,
+        "inspPblmCate": null,
+        "inspPblmDesc": "bbb",
+        "ifCasePblm": "0",
+        "pblmStat": "0",
+        "dataStat": "",
+        "nm": "新东鲁水库222",
+        "recPers": "80df1213ad9f493e85a771d6f4b18a17",
+        "note": "ccc",
+        "inspPblmOrgName": "aaa",
+        "inspPblmName": "安全管理责任",
+        "inspPlbmType": "水库大坝安全责任制",
+        "inspPblmCode": "未落实",
+        "pblmsTypeId": "4caca9ed8ea24ec3a2e557dcf842f6fd"
+    }
+    // tacObjPblmstb.value.objId = pblm.value.objId;
+    // tacObjPblmstb.value.regid = pblm.value.rgstrId;
+    // tacObjPblmstb.value.recPers = userStore.userId;
+    // tacObjPblmstb.value.nm = pblm.value.nm;
+    // tacObjPblmstb.value.ifCasePblm = '0'
+    // tacObjPblmstb.value.objType = 128
+    // tacObjPblmstb.value.inspPlbmType = tacObjPblmstb.value.checkPoint
+    // tacObjPblmstb.value.inspPblmCode = tacObjPblmstb.value.pblmDesc
+    parSectino.value.forEach(item => {
+        if(item.inspPblmsName === tacObjPblmstb.value.inspPblmsName && item.checkPoint === tacObjPblmstb.value.checkPoint && item.pblmDesc === tacObjPblmstb.value.pblmDesc){
+            console.log(item)
+            tacObjPblmstb.value.pblmsTypeId = item.guid
+        }
+    })
+    a.pblmsTypeId = tacObjPblmstb.value.pblmsTypeId
+    a.objId = pblm.value.objId;
+    a.regid = pblm.value.rgstrId;
+    a.recPers = userStore.userId;
+    a.nm = pblm.value.nm;
+    a.objType = 128
+    a.inspPblmName = tacObjPblmstb.value.inspPblmsName
+    a.inspPlbmType = tacObjPblmstb.value.checkPoint
+    a.inspPblmCode = tacObjPblmstb.value.pblmDesc
+    a.note = tacObjPblmstb.value.note
+    a.inspPblmOrgName = tacObjPblmstb.value.inspPblmOrgName
+    a.inspPblmDesc = tacObjPblmstb.value.inspPblmDesc
+    uploadFileToServer(fileList.value[0], '36c12e323dfd4623a18bf4ddaefebaaa')
+    // await request.post('/dc/insp/pblm', a).then((res) => {
+    //     if (res.success) {
+    //     showSuccessToast('保存成功!');
+    //     const formData = new FormData();
+    //     const file = fileList.value[0];
+    //     console.log('文件内容类型:', typeof file.content);
+    //     console.log('文件对象:', file);
+
+    //     // 情况1: 如果 file.content 是 Blob/File 对象
+    //     if (file.content instanceof Blob || file.content instanceof File) {
+    //         formData.append('file', file.content, file.name || 'file');
+    //     } 
+    //     // 情况2: 如果 file.content 是 base64 字符串
+    //     else if (typeof file.content === 'string' && file.content.startsWith('data:')) {
+    //     file.content = new File([file.content], file.name || 'file', {
+    //         type: file.type || 'application/octet-stream',
+    //         lastModified: Date.now()
+    //     });
+    //     }
+    //     // 情况3: 如果 file.content 是其他格式
+    //     else {
+    //     // 尝试转换为 Blob
+    //         const blob = new Blob([file.content], { type: file.type || 'application/octet-stream' });
+    //         formData.append('file', blob, file.name || 'file');
+    //     }
+    //     request.post('pdcApi/file/insert?bizId=' + res.data.pblmId, formData, {
+    //     headers: {
+    //         // 不要手动设置Content-Type
+    //         'Accept': 'application/json'
+    //     },
+    //     // 禁用请求体转换(关键:避免request库将FormData转为JSON)
+    //     transformRequest: [data => data],
+    //     // 确保请求体是FormData原生格式
+    //     processData: false,
+    //     contentType: false
+    //     }).then((res) => {
+                    
+    //             });
+    //     }
+    // });
+}
+const dataURLtoBlob = (dataURL) => {
+  try {
+    const arr = dataURL.split(',');
+    const mime = arr[0].match(/:(.*?);/)[1];
+    const bstr = atob(arr[1]);
+    let n = bstr.length;
+    const u8arr = new Uint8Array(n);
+    while (n--) {
+      u8arr[n] = bstr.charCodeAt(n);
+    }
+    return new Blob([u8arr], { type: mime });
+  } catch (e) {
+    console.error('base64转Blob失败:', e);
+    return new Blob([], { type: 'application/octet-stream' });
+  }
+};
+
+// 2. 手动构建multipart/form-data(保留之前验证正确的逻辑)
+const buildMultipartFormData = async (file) => {
+  if (!file) throw new Error('文件为空');
+
+  // 生成标准boundary
+  const boundary = `----WebKitFormBoundary${Math.random().toString(36).substr(2, 16)}`;
+
+  // 处理文件为Blob
+  let fileBlob;
+  if (file.content instanceof Blob || file.content instanceof File) {
+    fileBlob = file.content;
+  } else if (typeof file.content === 'string' && file.content.startsWith('data:')) {
+    fileBlob = dataURLtoBlob(file.content);
+  } else {
+    throw new Error(`不支持的文件格式: ${typeof file.content}`);
+  }
+
+  // 读取文件为ArrayBuffer
+  const fileBuffer = await new Promise((resolve, reject) => {
+    const reader = new FileReader();
+    reader.onload = () => resolve(reader.result);
+    reader.onerror = reject;
+    reader.readAsArrayBuffer(fileBlob);
+  });
+
+  // 手动拼接multipart格式(字符串转Uint8Array,兼容App端)
+  const stringToUint8Array = (str) => {
+    const arr = [];
+    for (let i = 0; i < str.length; i++) {
+      arr.push(str.charCodeAt(i));
+    }
+    return new Uint8Array(arr);
+  };
+
+  const parts = [];
+  // 拼接分隔符+元信息
+  parts.push(stringToUint8Array(`--${boundary}\r\n`));
+  parts.push(stringToUint8Array(`Content-Disposition: form-data; name="file"; filename="${encodeURIComponent(file.name || 'upload.png')}"\r\n`));
+  parts.push(stringToUint8Array(`Content-Type: ${fileBlob.type || 'application/octet-stream'}\r\n\r\n`));
+  // 拼接文件二进制数据
+  parts.push(new Uint8Array(fileBuffer));
+  // 拼接结束分隔符
+  parts.push(stringToUint8Array(`\r\n--${boundary}--\r\n`));
+
+  // 合并所有片段
+  const totalLength = parts.reduce((sum, part) => sum + part.length, 0);
+  const resultBuffer = new Uint8Array(totalLength);
+  let offset = 0;
+  parts.forEach(part => {
+    resultBuffer.set(part, offset);
+    offset += part.length;
+  });
+
+  return {
+    body: resultBuffer,
+    contentType: `multipart/form-data; boundary=${boundary}`
+  };
+};
+
+// 3. 核心:改用Fetch API上传文件(替换Axios)
+const uploadFileToServer = async (file, bizId) => {
+  if (!file || !bizId) {
+    showFailToast('文件或业务ID为空');
+    return null;
+  }
+
+  try {
+    // 构建标准multipart请求体
+    const { body, contentType } = await buildMultipartFormData(file);
+    
+    // 获取token和自定义头(和Axios拦截器一致)
+    const appStore = useAppStore();
+    const userStore = useUserStore();
+    const token = getToken();
+
+    // 拼接完整接口地址(补充baseURL,和你的request封装一致)
+    const baseURL = process.env.VUE_APP_BASE_API;
+    const fullUrl = `${baseURL}/pdcApi/file/insert?bizId=${bizId}`;
+
+    // 使用Fetch API发送请求(原生支持二进制,无兼容性问题)
+    const response = await fetch(fullUrl, {
+      method: 'POST',
+      headers: {
+        'Content-Type': contentType, // 带boundary的标准格式
+        'Accept': 'application/json',
+        'Orgid': appStore.currentOrgId || '034',
+        'Persid': userStore.userId,
+        'Accesstoken': token,
+        'Cache-Control': 'no-cache'
+      },
+      body: new Blob([body], { type: contentType }), // 二进制请求体
+      timeout: 30000,
+      credentials: 'include' // 保持cookie/token会话(和Axios一致)
+    });
+
+    // 解析响应
+    if (!response.ok) {
+      throw new Error(`请求失败: ${response.status}`);
+    }
+    const resData = await response.json();
+    console.log('文件上传成功:', resData);
+    return resData;
+
+  } catch (error) {
+    console.error('文件上传失败:', error);
+    showFailToast('文件上传失败');
+    throw error;
+  }
+};
+watch(() => tacObjPblmstb.value.inspPblmsName, (newVal, oldVal) => {
+    if (newVal !== oldVal) {
+        columns1.value = []
+        columns2.value = []
+        parSectino.value.forEach(item => {
+            if(item.inspPblmsName === newVal){
+                var par = {
+                    text: item.checkPoint,
+                    value: item.checkPoint
+                }
+                columns1.value.push(par);
+            }
+            columns1.value = [...new Set(columns1.value.map(item => JSON.stringify(item)))].map(str => JSON.parse(str))
+        })
+    }
+});
+watch(() => tacObjPblmstb.value.checkPoint, (newVal, oldVal) => {
+    if (newVal !== oldVal) {
+        columns2.value = []
+        parSectino.value.forEach(item => {
+            if(item.checkPoint === newVal){
+                var par = {
+                    text: item.pblmDesc,
+                    value: item.pblmDesc
+                }
+                columns2.value.push(par);
+            }
+            columns2.value = [...new Set(columns2.value.map(item => JSON.stringify(item)))].map(str => JSON.parse(str))
+        })
+    }
+});
+onMounted(() => {
+  var par = JSON.parse(router.query.object);
+  pblm.value = par
+  pblm.value.objId = par.objId
+  pblm.value.pblmId = par.pblmId;
+  pblm.value.rgstrId = par.rgstrId;
+  console.log(pblm.value)
+  getSelection().then(() => {
+  })
+})
+
+</script>
+<style lang="scss" scoped>
+.pblm-detail-wrapper {
+  height: 100%;
+  padding: 10px 0;
+  overflow: auto;
+
+  .pblm-detail-label {
+    padding: 10px 16px;
+    color: #606266;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+  }
+
+}
+</style>
+<style lang="scss">
+.van-cell-group--inset {
+  margin: 0 10px;
+}
+</style>

+ 5 - 2
src/views/InspectDC/Object/Problem/index.vue

@@ -140,12 +140,14 @@ const columns = ref([
 function jumpPageToadd() {
   var par = JSON.parse(router.query.object);
   formObj.value.objId = par.objId
+  console.log(formObj.value);
   jumpPage(`/addProblem/${formObj.value.objId}`, { object: JSON.stringify(formObj.value) });
 }
 async function onConfirmDelete() {
   if(reason.value === ''){
     showFailToast('请输入删除原因!');
     showWhy.value = true;
+    reason.value = '';
   }
   else{
     // 刷新问题列表
@@ -189,13 +191,14 @@ function deletePblm(pblmId) {
 }
 function getData() {
   var par = JSON.parse(router.query.object);
-  formObj.value = JSON.parse(router.query.object);
+  formObj.value = JSON.parse(router.query.object)
   request.get(`/bis/insp/baseNew/getByRgstr/${formObj.value.rgstrId}`).then(res=>{
     if(res.success){
       formObj.value = res.data;
+      var par = JSON.parse(router.query.object);
+      formObj.value.rgstrId = par.rgstrId
     }
   })
-  
   var problemForm = {
     objType:128,
     objId: par.objId,

+ 13 - 8
src/views/InspectDC/current.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="content-wrapper">
     <div class="filter-wrapper">
-      <gw-select :columns="inspectTypes" v-model:value="inspectType" />
+      <!-- <gw-select :columns="inspectTypes" v-model:value="inspectType" /> -->
     </div>
     <van-pull-refresh
       class="inspect-group-wrapper"
@@ -11,20 +11,21 @@
       <card01
         v-for="item in list"
         :key="item"
+        :description="`时间:${item.sttm} 至 ${item.entm}`"
         :title="item.prsnTitle + ''"
         icon="notes"
-        :description="`时间:${item.sttm} 至 ${item.entm}`"
-        @click="jumpPage(`/inspect/${item.plnaId}/objects`, { inspectType })"
+        @click="jumpPage(`/inspectDC/${item.plnaId}/objects`, { inspectType })"
       />
     </van-pull-refresh>
   </div>
 </template>
 <script setup>
-import { defineEmits, ref, watch } from "vue";
+import { defineEmits, onMounted, ref, watch } from "vue";
 import GwSelect from "@/components/GwSelect.vue";
 import card01 from "@/components/card01.vue";
 import { getCurrGroup } from "@/api/inspect.js";
 import { jumpPage } from "@/utils/page";
+import request from "@/utils/request";
 
 const emits = defineEmits(["onClick"]);
 
@@ -42,13 +43,17 @@ const loading = ref(false);
 const finished = ref(false);
 
 function onLoad() {
-  getCurrGroup(inspectType.value).then((res) => {
+  request.get(`/dc/insp/base/getCurrGroup`,{
+    pid:'128',
+    userid:localStorage.getItem("userid"),
+  }).then(res=>{
     list.value = res.data;
-    loading.value = false;
-    finished.value = true;
-  });
+  })
 }
 
+onMounted(() => {
+  onLoad();
+})
 watch(
   () => inspectType,
   (inspectType) => {

+ 0 - 2
src/views/Problem/detail/index.vue

@@ -262,8 +262,6 @@ function onSubmit() {
   }
   data.subjectNames = unitNames.join(',')
   data.subjectIds = subIds.join(',')
-
-
   addTacQuestion(data).then(res => {
     pblm.value.id = res.data.id
     showNotify({type: 'success', message: '保存成功'});