浏览代码

feat: save

gemercheung 10 月之前
父节点
当前提交
4710a69868

+ 10 - 0
src/request/urls.ts

@@ -177,6 +177,16 @@ export const insertCaseFile = "/fusion/caseFiles/add";
 export const deleteCaseFile = "/fusion/caseFiles/delete";
 export const deleteCaseFile = "/fusion/caseFiles/delete";
 export const updateCaseFile = "/fusion/caseFiles/updateTitle";
 export const updateCaseFile = "/fusion/caseFiles/updateTitle";
 
 
+//勘验笔录信息(犯罪)
+export const caseInquestInfo = "/fusion/caseInquestCriminal/info";
+export const caseInquestOpt = "/fusion/caseInquestCriminal/saveOrUpdate";
+export const caseInquestExport = "/fusion/caseInquestCriminal/downDocx";
+
+//提取清单
+export const caseExtractDetail = "/fusion/caseExtractDetail/info";
+export const caseExtractDetailOpt = "/fusion/caseExtractDetail/saveOrUpdate";
+export const caseExtractDetailExport = "/fusion/caseExtractDetail/downDocx";
+
 // 火调链接地址设置密码
 // 火调链接地址设置密码
 export const setCasePsw = "/fusion/web/fireProject/updateRandomCode";
 export const setCasePsw = "/fusion/web/fireProject/updateRandomCode";
 export const getCasePsw = "/fusion/web/fireProject/getRandCode";
 export const getCasePsw = "/fusion/web/fireProject/getRandCode";

+ 30 - 0
src/store/case.ts

@@ -7,6 +7,12 @@ import {
   setCasePsw,
   setCasePsw,
   syncInfo,
   syncInfo,
   updateCaseFile,
   updateCaseFile,
+  caseInquestInfo,
+  caseInquestOpt,
+  caseInquestExport,
+  caseExtractDetail,
+  caseExtractDetailOpt,
+  caseExtractDetailExport,
 } from "@/request";
 } from "@/request";
 import { ModelScene, QuoteScene, Scene, SceneType } from "./scene";
 import { ModelScene, QuoteScene, Scene, SceneType } from "./scene";
 import { CaseFile } from "./caseFile";
 import { CaseFile } from "./caseFile";
@@ -72,3 +78,27 @@ export const getCaseScenes = (scenes: Scene[]) => {
 
 
 export const replaceCaseScenes = (caseId: number, caseScenes: CaseScenes) =>
 export const replaceCaseScenes = (caseId: number, caseScenes: CaseScenes) =>
   axios.post(repCaseScenes, { sceneNumParam: caseScenes, caseId });
   axios.post(repCaseScenes, { sceneNumParam: caseScenes, caseId });
+
+export const getCaseInquestInfo = (caseId: number) =>
+  axios.get(caseInquestInfo, { params: { caseId } });
+
+export const saveCaseInquestInfo = (caseId: number, data) =>
+  axios.post(caseInquestOpt, { caseId, ...data });
+
+export const exportCaseInquestInfo = (caseId: number) =>
+  axios.get(caseInquestExport, {
+    params: { caseId, ingoreRes: true },
+    responseType: "blob",
+  });
+
+export const getCaseDetailInfo = (caseId: number) =>
+  axios.get(caseExtractDetail, { params: { caseId } });
+
+export const saveCaseDetailInfo = (caseId: number, data) =>
+  axios.post(caseExtractDetailOpt, { caseId, ...data });
+
+export const exportCaseDetailInfo = (caseId: number) =>
+  axios.get(caseExtractDetailExport, {
+    params: { caseId, ingoreRes: true },
+    responseType: "blob",
+  });

+ 94 - 58
src/view/case/caseFile.vue

@@ -1,64 +1,90 @@
 <template>
 <template>
-  <com-head :options="options" v-model="currentTypeId" notContent v-if="options.length" />
-
+  <com-head
+    :options="options"
+    v-model="currentTypeId"
+    notContent
+    v-if="options.length"
+  />
+  <!-- {{ currentTypeId }} -->
   <div class="body-layer">
   <div class="body-layer">
-    <div class="body-head">
-      <h3 style="visibility: hidden">场景管理</h3>
-      <div>
-        <template v-if="isDraw">
-          <el-button type="primary" @click="gotoDraw(BoardType.map, -1)">
-            创建{{ BoardTypeDesc[BoardType.map] }}
-          </el-button>
-          <el-button type="primary" @click="gotoDraw(BoardType.scene, -1)">
-            创建{{ BoardTypeDesc[BoardType.scene] }}
+    <template v-if="currentTypeId === 3">
+      <Records :caseId="caseId" :title="caseInfoData.caseTitle" />
+    </template>
+    <template v-else-if="currentTypeId === 5">
+      <Manifest :caseId="caseId" :title="caseInfoData.caseTitle" />
+    </template>
+    <template v-else>
+      <div class="body-head">
+        <h3 style="visibility: hidden">场景管理</h3>
+        <div>
+          <template v-if="isDraw">
+            <el-button type="primary" @click="gotoDraw(BoardType.map, -1)">
+              创建{{ BoardTypeDesc[BoardType.map] }}
+            </el-button>
+            <el-button type="primary" @click="gotoDraw(BoardType.scene, -1)">
+              创建{{ BoardTypeDesc[BoardType.scene] }}
+            </el-button>
+          </template>
+          <el-button type="primary" @click="addCaseFileHandler">
+            上传
           </el-button>
           </el-button>
-        </template>
-        <el-button type="primary" @click="addCaseFileHandler"> 上传 </el-button>
+        </div>
       </div>
       </div>
-    </div>
 
 
-    <el-table :data="files" tooltip-effect="dark" style="width: 100%" size="large">
-      <el-table-column label="序号" width="70" v-slot:default="{ $index }">
-        <div style="text-align: center">
-          {{ $index + 1 }}
-        </div>
-      </el-table-column>
-      <el-table-column label="名称" v-slot:default="{ row }: { row: CaseFile }">
-        <span v-if="!inputCaseTitles.includes(row)">
-          {{ row.filesTitle }}
-          <el-icon class="edit-title" @click="inputCaseTitles.push(row)">
-            <EditPen />
-          </el-icon>
-        </span>
-        <template v-else>
-          <ElInput
-            v-model="row.filesTitle"
-            placeholder="请输入文件名"
-            focus
-            :maxlength="50"
-            style="width: 280px"
-          >
-            <template #append>
-              <el-button type="primary" plain @click="updateFileTitle(row)">
-                确定
-              </el-button>
-            </template>
-          </ElInput>
-        </template>
-      </el-table-column>
-      <el-table-column label="创建时间" prop="createTime"></el-table-column>
-      <el-table-column label="操作" v-slot:default="{ row }: { row: CaseFile }">
-        <span class="oper-span" @click="query(row)"> 查看 </span>
-        <span
-          class="oper-span"
-          @click="gotoDraw(row.imgType!, row.filesId)"
-          v-if="row.imgType !== null"
+      <el-table
+        :data="files"
+        tooltip-effect="dark"
+        style="width: 100%"
+        size="large"
+      >
+        <el-table-column label="序号" width="70" v-slot:default="{ $index }">
+          <div style="text-align: center">
+            {{ $index + 1 }}
+          </div>
+        </el-table-column>
+        <el-table-column
+          label="名称"
+          v-slot:default="{ row }: { row: CaseFile }"
+        >
+          <span v-if="!inputCaseTitles.includes(row)">
+            {{ row.filesTitle }}
+            <el-icon class="edit-title" @click="inputCaseTitles.push(row)">
+              <EditPen />
+            </el-icon>
+          </span>
+          <template v-else>
+            <ElInput
+              v-model="row.filesTitle"
+              placeholder="请输入文件名"
+              focus
+              :maxlength="50"
+              style="width: 280px"
+            >
+              <template #append>
+                <el-button type="primary" plain @click="updateFileTitle(row)">
+                  确定
+                </el-button>
+              </template>
+            </ElInput>
+          </template>
+        </el-table-column>
+        <el-table-column label="创建时间" prop="createTime"></el-table-column>
+        <el-table-column
+          label="操作"
+          v-slot:default="{ row }: { row: CaseFile }"
         >
         >
-          编辑
-        </span>
-        <span class="oper-span delBtn" @click="del(row)"> 删除 </span>
-      </el-table-column>
-    </el-table>
+          <span class="oper-span" @click="query(row)"> 查看 </span>
+          <span
+            class="oper-span"
+            @click="gotoDraw(row.imgType!, row.filesId)"
+            v-if="row.imgType !== null"
+          >
+            编辑
+          </span>
+          <span class="oper-span delBtn" @click="del(row)"> 删除 </span>
+        </el-table-column>
+      </el-table>
+    </template>
   </div>
   </div>
 </template>
 </template>
 
 
@@ -81,6 +107,8 @@ import {
 import { getCaseInfo, updateCaseInfo } from "@/store/case";
 import { getCaseInfo, updateCaseInfo } from "@/store/case";
 import { appConstant } from "@/app";
 import { appConstant } from "@/app";
 import { ElIcon, ElInput, ElMessage } from "element-plus";
 import { ElIcon, ElInput, ElMessage } from "element-plus";
+import Records from "./records/index.vue";
+import Manifest from "./records/manifest.vue";
 
 
 const caseId = computed(() => {
 const caseId = computed(() => {
   const caseId = router.currentRoute.value.params.caseId;
   const caseId = router.currentRoute.value.params.caseId;
@@ -88,6 +116,7 @@ const caseId = computed(() => {
     return Number(caseId);
     return Number(caseId);
   }
   }
 });
 });
+const caseInfoData = ref<any>();
 
 
 const inputCaseTitles = ref<CaseFile[]>([]);
 const inputCaseTitles = ref<CaseFile[]>([]);
 
 
@@ -96,13 +125,18 @@ const updateFileTitle = async (caseFile: CaseFile) => {
     return ElMessage.error("卷宗标题不能为空!");
     return ElMessage.error("卷宗标题不能为空!");
   }
   }
   await updateCaseInfo(caseFile);
   await updateCaseInfo(caseFile);
-  inputCaseTitles.value = inputCaseTitles.value.filter((item) => item !== caseFile);
+  inputCaseTitles.value = inputCaseTitles.value.filter(
+    (item) => item !== caseFile
+  );
 };
 };
 
 
 const currentTypeId = ref<number>();
 const currentTypeId = ref<number>();
 const types = ref<CaseFileType[]>([]);
 const types = ref<CaseFileType[]>([]);
 const options = computed(() =>
 const options = computed(() =>
-  types.value.map((item) => ({ name: item.filesTypeName, value: item.filesTypeId }))
+  types.value.map((item) => ({
+    name: item.filesTypeName,
+    value: item.filesTypeId,
+  }))
 );
 );
 const isDraw = computed(() => currentTypeId.value === FileDrawType);
 const isDraw = computed(() => currentTypeId.value === FileDrawType);
 
 
@@ -115,7 +149,8 @@ const refresh = async () => {
 };
 };
 watchEffect(() => caseId.value && currentTypeId.value && refresh());
 watchEffect(() => caseId.value && currentTypeId.value && refresh());
 
 
-const query = (file: CaseFile) => window.open(file.filesUrl + "?time=" + Date.now());
+const query = (file: CaseFile) =>
+  window.open(file.filesUrl + "?time=" + Date.now());
 const del = async (file: CaseFile) => {
 const del = async (file: CaseFile) => {
   if (await confirm("确定要删除此数据?")) {
   if (await confirm("确定要删除此数据?")) {
     await delCaseFile({ caseId: caseId.value!, filesId: file.filesId });
     await delCaseFile({ caseId: caseId.value!, filesId: file.filesId });
@@ -140,6 +175,7 @@ onMounted(async () => {
   currentTypeId.value = types.value[0].filesTypeId;
   currentTypeId.value = types.value[0].filesTypeId;
   const caseInfo = await getCaseInfo(caseId.value!);
   const caseInfo = await getCaseInfo(caseId.value!);
   if (caseInfo) {
   if (caseInfo) {
+    caseInfoData.value = caseInfo;
     title.value = (await getCaseInfo(caseId.value!)).caseTitle + " | 卷宗管理";
     title.value = (await getCaseInfo(caseId.value!)).caseTitle + " | 卷宗管理";
     desc.value = "";
     desc.value = "";
   } else {
   } else {

+ 169 - 0
src/view/case/records/feild.md

@@ -0,0 +1,169 @@
+    /**
+     * 案件id
+     */
+    private Integer caseId;
+
+    /**
+     * 现场勘验号
+     */
+    private String inquestNum;
+
+    /**
+     * 单位名称
+     */
+    private String deptName;
+
+    /**
+     * 标题
+     */
+    private String title;
+
+    /**
+     * 发送单位
+     */
+    private String sendDept;
+
+    /**
+     * 笔录人
+     */
+    private String recorder;
+
+    /**
+     * 绘图人
+     */
+    private String painter;
+
+    /**
+     * 照相人
+     */
+    private String photographer;
+
+    /**
+     * 份数
+     */
+    private Integer issuanceCount;
+
+    /**
+     * 制作时间
+     */
+    private Date makeTime;
+
+    /**
+     * 签发意见
+     */
+    private String issuanceOpinion;
+
+    /**
+     * 签名
+     */
+    private String signature;
+
+    /**
+     * 签名时间
+     */
+    private Date signatureTime;
+
+    /**
+     * 报告单位
+     */
+    private String reportDept;
+
+    /**
+     * 时间
+     */
+    private Date inquestTime;
+
+    /**
+     * 勘验开始时间
+     */
+    private Date startTime;
+
+    /**
+     * 勘验结束时间
+     */
+    private Date endTime;
+
+    /**
+     * 勘验地址
+     */
+    private String address;
+
+    /**
+     * 现场保护情况
+     */
+    private String protectionSituation;
+
+    /**
+     * 现场保护人
+     */
+    private String protector;
+
+    /**
+     * 现场保护措施
+     */
+    private String protectionMeasures;
+
+    /**
+     * 现场情况
+     */
+    private String situation;
+
+    /**
+     * 变动原因
+     */
+    private String changeReason;
+
+    /**
+     * 天气情况
+     */
+    private JSONObject weatherInfo;
+
+    /**
+     * 光线
+     */
+    private String light;
+
+    /**
+     * 勘验指挥人
+     */
+    private String inquestCommander;
+
+    /**
+     * 勘验情况
+     */
+    private String inquestSituation;
+
+    /**
+     * 现场勘验制图数量
+     */
+    private Integer imageNum;
+
+    /**
+     * 照相数量
+     */
+    private Integer photographNum;
+
+    /**
+     * 摄影数量
+     */
+    private Integer photographyNum;
+
+    /**
+     * 现场勘验纪录人员数组
+     */
+    private JSONArray recorderInfo;
+
+    /**
+     * 现场勘验人员签名数组
+     */
+    private JSONArray signatureInfo;
+
+    /**
+     * 现场勘验见证人数组
+     */
+    private JSONArray witnessInfo;
+
+    /**
+     * 备注
+     */
+    private String remark;

+ 523 - 0
src/view/case/records/index copy.vue

@@ -0,0 +1,523 @@
+<template>
+  <!-- 勘验笔录{{ props.caseId }} -->
+  <div class="records">
+    <div class="header">
+      <el-button type="primary" @click="handleSave">保存</el-button>
+      <el-button :disabled="isDisableExport" @click="handleExport"
+        >导出</el-button
+      >
+    </div>
+    <h3 class="title">基本信息</h3>
+    <div class="content">
+      <div class="line">
+        <span>现场勘验号:</span>
+        <!-- <span>第</span> -->
+        <el-input
+          class="input"
+          v-model="data.count"
+          placeholder=""
+          style="width: 280px"
+        />
+      </div>
+
+      <div class="line">
+        <span>现场勘验单位:</span>
+        <!-- <span>第</span> -->
+        <el-input
+          class="input"
+          v-model="data.deptName"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="line">
+        <span>指派/报告单位:</span>
+        <!-- <span>第</span> -->
+        <el-input
+          class="input"
+          v-model="data.count"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="line">
+        <span>勘验时间: &nbsp; </span>
+        <div>
+          <el-date-picker
+            v-model="data.inquestTime"
+            type="datetime"
+            placeholder="勘验时间"
+            style="width: 180px"
+          />
+        </div>
+      </div>
+      <div class="line">
+        <span>现场勘验时间: &nbsp; </span>
+        <div>
+          <el-date-picker
+            v-model="data.times"
+            type="datetimerange"
+            range-separator="至"
+            start-placeholder="现场勘验开始时间"
+            end-placeholder="现场勘验结束时间"
+          />
+        </div>
+      </div>
+
+      <div class="line">
+        <span>现场地点:</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="line">
+        <span>现场地点:</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+      
+      <div class="line">
+        <span>勘验人员姓名、勘验人职务(含技术职务):</span>
+        <el-input
+          class="input"
+          type="tel"
+          v-model="data.userInfo"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="line">
+        <span>勘验气象条件(天气、风力、温度):</span>
+        <el-input
+          class="input"
+          type="tel"
+          v-model="data.weather"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="textarea">
+        <span>勘验情况:</span>
+        <el-input
+          type="textarea"
+          :rows="4"
+          v-model="data.situation"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+      <div class="textarea">
+        <span>一、环境勘验</span>
+        <el-input
+          type="textarea"
+          :rows="4"
+          v-model="data.environment"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="textarea">
+        <span>二、初步勘验</span>
+        <el-input
+          type="textarea"
+          :rows="4"
+          v-model="data.firstInquest"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="textarea">
+        <span>三、细项勘验</span>
+        <el-input
+          type="textarea"
+          :rows="4"
+          v-model="data.carefulInquest"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="textarea">
+        <span>四、专项勘验</span>
+        <el-input
+          type="textarea"
+          :rows="6"
+          v-model="data.specialInquest"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="textarea">
+        <span>提取物品描述:</span>
+        <el-input
+          type="textarea"
+          :rows="6"
+          v-model="data.itemDescription"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="textarea">
+        <span>现场拍照制图描述:</span>
+        <el-input
+          type="textarea"
+          :rows="6"
+          v-model="data.imgDescription"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="info">
+        <span class="sub-tit">勘验信息:</span>
+        <div class="inner">
+          <div class="sec">
+            <span>勘验负责人</span>
+            <el-input class="input" v-model="data.leader" placeholder="" />
+          </div>
+
+          <div class="sec">
+            <span> 记录人</span>
+            <el-input class="input" v-model="data.recorder" placeholder="" />
+          </div>
+
+          <div class="sec">
+            <span>勘验人</span>
+            <el-input class="input" v-model="data.inspector" placeholder="" />
+          </div>
+        </div>
+      </div>
+
+      <div class="gap"></div>
+      <!-- 证人 -->
+      <template v-for="item of data.witnessInfo">
+        <div class="witnessInfo">
+          <span class="sub-tit">证人信息:</span>
+          <div class="line">
+            <span>证人或当事人:</span>
+            <el-input
+              class="input"
+              v-model="item.name"
+              placeholder=""
+              style="width: 180px"
+            />
+            <div>
+              <el-input
+                class="input"
+                v-model="item.year"
+                placeholder=""
+                style="width: 80px"
+              />
+              <span>年</span>
+              <el-input
+                class="input"
+                v-model="item.month"
+                placeholder=""
+                style="width: 80px"
+              />
+              <span>月</span>
+              <el-input
+                class="input"
+                v-model="item.day"
+                placeholder=""
+                style="width: 80px"
+              />
+              <span>日</span>
+            </div>
+
+            <span style="margin-left: 50px">身份证件号码:</span>
+            <el-input
+              class="input"
+              v-model="item.id"
+              placeholder=""
+              style="width: 280px"
+            />
+          </div>
+          <div class="line">
+            <span>单位或住址:</span>
+            <el-input
+              class="input"
+              v-model="item.address"
+              placeholder=""
+              style="width: 100%"
+            />
+          </div>
+        </div>
+      </template>
+
+      <div class="btn-container">
+        <el-button class="btn" @click="addwitnessInfo">+新增</el-button>
+      </div>
+
+      <div></div>
+    </div>
+  </div>
+</template>
+<script setup>
+import { onMounted, ref, watch } from "vue";
+import { reactive } from "vue";
+import {
+  getCaseInquestInfo,
+  saveCaseInquestInfo,
+  exportCaseInquestInfo,
+} from "@/store/case";
+import { ElMessage } from "element-plus";
+import saveAs from "@/util/file-serve";
+const props = defineProps({ caseId: Number, title: String });
+
+console.log(props);
+const isDisableExport = ref(false);
+const data = reactive({
+  count: "",
+  startTime: {
+    year: "",
+    month: "",
+    day: "",
+    hour: "",
+    min: "",
+  },
+  endTime: {
+    year: "",
+    month: "",
+    day: "",
+    hour: "",
+    min: "",
+  },
+  address: "",
+  userInfo: "",
+  weather: "",
+  situation: "",
+  environment: "", //环境勘验
+  firstInquest: "", //初步勘验
+  carefulInquest: "", //细项勘验
+  specialInquest: "", //专项勘验
+  itemDescription: "",
+  imgDescription: "",
+  leader: "",
+  recorder: "",
+  inspector: "",
+  witnessInfo: [
+    {
+      name: "",
+      year: "",
+      month: "",
+      day: "",
+      id: "",
+      address: "",
+    },
+    {
+      name: "",
+      year: "",
+      month: "",
+      day: "",
+      id: "",
+      address: "",
+    },
+  ],
+});
+
+watch(
+  data,
+  (newValue) => {
+    // data.userName = newValue.userName.replace(/[^0-9]/g, '');
+    const sMonth = newValue.startTime.month.replace(/[^0-9]/g, "");
+    const sDay = newValue.startTime.day.replace(/[^0-9]/g, "");
+    const sHour = newValue.startTime.hour.replace(/[^0-9]/g, "");
+    const sMin = newValue.startTime.min.replace(/[^0-9]/g, "");
+
+    const eMonth = newValue.endTime.month.replace(/[^0-9]/g, "");
+    const eDay = newValue.endTime.day.replace(/[^0-9]/g, "");
+    const eHour = newValue.endTime.hour.replace(/[^0-9]/g, "");
+    const eMin = newValue.endTime.min.replace(/[^0-9]/g, "");
+
+    data.startTime.year = newValue.startTime.year.replace(/[^0-9]/g, "");
+    data.startTime.month = Number(sMonth) > 12 ? "12" : sMonth;
+    data.startTime.day = Number(sDay) > 31 ? "31" : sDay;
+    data.startTime.hour = Number(sDay) > 24 ? "24" : sHour;
+    data.startTime.min = Number(sMin) > 60 ? "0" : sMin;
+
+    data.endTime.year = newValue.endTime.year.replace(/[^0-9]/g, "");
+    data.endTime.month = Number(eMonth) > 12 ? "12" : eMonth;
+    data.endTime.day = Number(eDay) > 31 ? "31" : eDay;
+    data.endTime.hour = Number(eHour) > 24 ? "24" : eHour;
+    data.endTime.min = Number(eMin) > 60 ? "0" : eMin;
+
+    newValue.witnessInfo.forEach((item, key) => {
+      const year = newValue.witnessInfo[key].year.replace(/[^0-9]/g, "");
+      const month = newValue.witnessInfo[key].month.replace(/[^0-9]/g, "");
+      const day = newValue.witnessInfo[key].day.replace(/[^0-9]/g, "");
+      data.witnessInfo[key].year = year;
+      data.witnessInfo[key].month = Number(month) > 12 ? "12" : month;
+      data.witnessInfo[key].day = Number(day) > 31 ? "31" : day;
+    });
+  },
+  {
+    immediate: true,
+    deep: true,
+  }
+);
+
+const initInfo = async () => {
+  const res = await getCaseInquestInfo(props.caseId);
+
+  if (!res.data) {
+    isDisableExport.value = true;
+  } else {
+    isDisableExport.value = false;
+  }
+  for (var k in data) {
+    if (res.data && res.data.hasOwnProperty(k)) {
+      console.log("Key is " + k);
+      data[k] = res.data[k];
+    }
+  }
+};
+
+onMounted(() => {
+  initInfo();
+});
+
+const addwitnessInfo = () => {
+  // witnessInfoes.value += 1
+  data.witnessInfo.push({
+    name: "",
+    year: "",
+    month: "",
+    day: "",
+    id: "",
+  });
+};
+
+const handleSave = async () => {
+  console.log("data", data);
+  const res = await saveCaseInquestInfo(props.caseId, data);
+  if (res.code === 0) {
+    ElMessage.success("保存成功!");
+    initInfo();
+  }
+};
+const handleExport = async () => {
+  await saveCaseInquestInfo(props.caseId, data);
+  const res = await exportCaseInquestInfo(props.caseId);
+  console.log("res", res);
+  saveAs(res, `${props.title}_勘验笔录.docx`);
+};
+</script>
+
+<style lang="scss">
+.records {
+  max-width: 1280px;
+  margin: 0 auto;
+  padding: 20px 0;
+
+  .header {
+    display: flex;
+    justify-content: flex-endTime;
+  }
+
+  .input {
+    height: 32px;
+    line-height: 32px;
+    margin: 0 8px;
+  }
+
+  .textarea {
+    margin-right: 8px;
+    margin-bottom: 20px;
+
+    span {
+      padding: 10px 0;
+      display: inline-block;
+    }
+
+    // margin: 0 8px;
+  }
+
+  .line {
+    display: inline-flex;
+    width: 100%;
+    flex-direction: row;
+    align-items: center;
+    margin-bottom: 25px;
+    line-height: 38px;
+
+    span {
+      white-space: nowrap;
+    }
+  }
+}
+
+.title {
+  text-align: center;
+  margin-bottom: 30px;
+}
+
+.sub-tit {
+  display: inline-block;
+  padding-bottom: 20px;
+}
+
+.info {
+  display: block;
+
+  .inner {
+    display: flex;
+    flex-direction: row;
+    width: 100%;
+
+    .input {
+      flex: 1;
+    }
+
+    .sec {
+      flex: 1;
+      display: inline-flex;
+      align-items: center;
+      justify-content: center;
+    }
+  }
+}
+
+.witnessInfo {
+  background: #f5f5f5;
+  padding: 15px;
+  margin-top: 20px;
+  margin-right: 8px;
+}
+
+.gap {
+  margin: 15px 0;
+}
+
+.btn-container {
+  padding: 20px 0;
+
+  .btn {
+    color: #26559b;
+    width: 100%;
+
+    &:hover {
+      background: #f5f5f5;
+      border-color: #dcdfe6;
+    }
+  }
+}
+</style>

+ 871 - 0
src/view/case/records/index.vue

@@ -0,0 +1,871 @@
+<template>
+  <!-- 勘验笔录{{ props.caseId }} -->
+  <div class="records">
+    <div class="header">
+      <el-button type="primary" @click="handleSave">保存</el-button>
+      <el-button :disabled="isDisableExport" @click="handleExport"
+        >导出</el-button
+      >
+    </div>
+    <h3 class="title">现场勘验记录签发呈批表</h3>
+    <div class="content">
+      <div class="line">
+        <span>标题: </span>
+        <el-input
+          class="input"
+          v-model="data.title"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+      <div class="line">
+        <span>现场勘验号:</span>
+        <!-- <span>第</span> -->
+        <el-input
+          class="input"
+          v-model="data.inquestNum"
+          placeholder=""
+          style="width: 280px"
+        />
+      </div>
+      <div class="line">
+        <span>发送单位:</span>
+        <!-- <span>第</span> -->
+        <el-input
+          class="input"
+          v-model="data.sendDept"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="line">
+        <span>笔 录 人 :</span>
+        <el-input
+          class="input"
+          v-model="data.recorder"
+          placeholder=""
+          style="width: 120px"
+        />
+        <span>绘 图 人 :</span>
+        <el-input
+          class="input"
+          v-model="data.sendDept"
+          placeholder=""
+          style="width: 120px"
+        />
+        <span>照 相 人 :</span>
+        <el-input
+          class="input"
+          v-model="data.sendDept"
+          placeholder=""
+          style="width: 120px"
+        />
+      </div>
+
+      <div class="line">
+        <span>份数: </span>
+        <el-input
+          class="input"
+          type="number"
+          v-model="data.issuanceCount"
+          placeholder=""
+          style="width: 120px"
+        />
+      </div>
+      <div class="line">
+        <span>制作时间: &nbsp; </span>
+        <div>
+          <el-date-picker
+            class="input"
+            v-model="data.makeTime"
+            type="datetime"
+            placeholder="制作时间"
+            style="width: 180px"
+          />
+        </div>
+      </div>
+      <div class="textarea">
+        <span>签发意见 :</span>
+        <el-input
+          type="textarea"
+          :rows="6"
+          v-model="data.issuanceOpinion"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+    </div>
+
+    <h3 class="title">现 场 勘 验 笔 录</h3>
+
+    <div class="content">
+      <div class="line">
+        <span>现场勘验号:</span>
+        <!-- <span>第</span> -->
+        <el-input
+          class="input"
+          v-model="data.inquestNum"
+          placeholder=""
+          style="width: 280px"
+        />
+      </div>
+
+      <div class="line">
+        <span>现场勘验单位:</span>
+        <!-- <span>第</span> -->
+        <el-input
+          class="input"
+          v-model="data.deptName"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="line">
+        <span>指派/报告单位:</span>
+        <!-- <span>第</span> -->
+        <el-input
+          class="input"
+          v-model="data.reportDept"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="line">
+        <span>勘验时间: &nbsp; </span>
+        <div>
+          <el-date-picker
+            class="input"
+            v-model="data.inquestTime"
+            type="datetime"
+            placeholder="勘验时间"
+            style="width: 180px"
+          />
+        </div>
+      </div>
+      <div class="line">
+        <span>现场勘验时间: &nbsp; </span>
+        <div>
+          <el-date-picker
+            class="input"
+            v-model="data.times"
+            type="datetimerange"
+            range-separator="至"
+            start-placeholder="现场勘验开始时间"
+            end-placeholder="现场勘验结束时间"
+          />
+        </div>
+      </div>
+
+      <div class="line">
+        <span>现场地点:</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="line">
+        <span>现场保护情况:</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.protectionSituation"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="line">
+        <span>现场保护人: &nbsp;&nbsp; &nbsp;</span>
+        <span>姓名</span>
+        <!-- 单位 XX派出所 职务 一级警长 -->
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.protector.name"
+          placeholder=""
+          style="width: 180px"
+        />
+        <span>单位</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.protector.unit"
+          placeholder=""
+          style="width: 200px"
+        />
+        <span>职务</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.protector.job"
+          placeholder=""
+          style="width: 200px"
+        />
+      </div>
+      <!-- protectionMeasures -->
+      <div class="line">
+        <span>保护措施:&nbsp; </span>
+        <el-checkbox-group v-model="data.protectionMeasures">
+          <el-checkbox :value="0" label="专人看护现场,防止他人进入" />
+          <el-checkbox :value="1" checked label="设立警戒带,划定禁行区域" />
+          <el-checkbox :value="2" label="其他措施" />
+        </el-checkbox-group>
+      </div>
+      <div class="line">
+        <span>现场情况: &nbsp; </span>
+        <el-checkbox-group v-model="data.situation">
+          <el-checkbox :value="0" label="原始现场" />
+          <el-checkbox :value="1" checked label="变动现场" />
+        </el-checkbox-group>
+      </div>
+      <!-- changeReason -->
+      <div class="line">
+        <span>变动原因: &nbsp; </span>
+        <el-checkbox-group v-model="data.changeReason">
+          <el-checkbox :value="0" label="事主进入" />
+          <el-checkbox :value="1" label="报案人进入" />
+          <el-checkbox :value="2" label="其他" />
+        </el-checkbox-group>
+        <el-input
+          class="input"
+          v-model="data.changeReasonOtherValue"
+          :disabled="!data.changeReason.includes(2)"
+          style="margin-left: 20px; width: 200px"
+        />
+      </div>
+
+      <div class="line">
+        <span>天气: &nbsp; </span>
+        <el-checkbox-group v-model="data.weatherInfo.type">
+          <el-checkbox :value="0" label="阴" />
+          <el-checkbox :value="1" label="晴" />
+          <el-checkbox :value="2" label="雨" />
+          <el-checkbox :value="3" label="雾" />
+        </el-checkbox-group>
+        <span style="margin-left: 20px; font-size: 12px">温度: &nbsp;</span>
+        <el-input
+          class="input"
+          v-model="data.weatherInfo.temperature"
+          style="width: 80px"
+        />
+        <span style="margin-left: 20px; font-size: 12px">湿度: &nbsp;</span>
+        <el-input
+          class="input"
+          v-model="data.weatherInfo.humidity"
+          style="width: 80px"
+        />
+        <span style="margin-left: 20px; font-size: 12px">风向: &nbsp;</span>
+        <el-input
+          class="input"
+          v-model="data.weatherInfo.windDirection"
+          style="width: 80px"
+        />
+      </div>
+
+      <div class="line">
+        <span>现场勘验利用的光线: &nbsp; </span>
+        <el-checkbox-group v-model="data.light">
+          <el-checkbox :value="0" checked label="自然光" />
+          <el-checkbox :value="1" checked label="灯光" />
+          <el-checkbox :value="2" label="特种光" />
+        </el-checkbox-group>
+      </div>
+
+      <div class="line">
+        <span>现场勘验指挥人: &nbsp;&nbsp; </span>
+        <span>姓名</span>
+        <!-- 单位 XX派出所 职务 一级警长 -->
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.inquestCommander.name"
+          placeholder=""
+          style="width: 180px"
+        />
+        <span>单位</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.inquestCommander.unit"
+          placeholder=""
+          style="width: 200px"
+        />
+        <span>职务</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.inquestCommander.job"
+          placeholder=""
+          style="width: 200px"
+        />
+      </div>
+
+      <div class="textarea">
+        <span>现场勘验情况 :</span>
+        <el-input
+          type="textarea"
+          :rows="6"
+          v-model="data.inquestSituation"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="line">
+        <span>现场勘验制图,&nbsp; </span>
+        <el-input-number class="input" v-model="data.imageNum" style="width: 130px" />
+        <span>张; &nbsp;&nbsp;</span>
+        <span>照相</span>
+        <el-input-number class="input" v-model="data.photographNum" style="width: 130px" />
+        <span>张;&nbsp;&nbsp;</span>
+        <span>摄像</span>
+        <el-input class="input" v-model="data.d" style="width: 80px" />
+        <span>分</span>
+        <el-input class="input" v-model="data.d" style="width: 80px" />
+        <span>秒</span>
+      </div>
+      <div class="line">现场勘验记录人员:</div>
+      <div class="line">
+        <span>笔录人: &nbsp;&nbsp; </span>
+        <span>姓名</span>
+        <!-- 单位 XX派出所 职务 一级警长 -->
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 180px"
+        />
+        <span>单位</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+        <span>职务</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+      </div>
+      <div class="line">
+        <span>制图人: &nbsp;&nbsp; </span>
+        <span>姓名</span>
+        <!-- 单位 XX派出所 职务 一级警长 -->
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 180px"
+        />
+        <span>单位</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+        <span>职务</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+      </div>
+      <div class="line">
+        <span>照相人: &nbsp;&nbsp; </span>
+        <span>姓名</span>
+        <!-- 单位 XX派出所 职务 一级警长 -->
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 180px"
+        />
+        <span>单位</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+        <span>职务</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+      </div>
+      <div class="line">
+        <span>摄像人: &nbsp;&nbsp; </span>
+        <span>姓名</span>
+        <!-- 单位 XX派出所 职务 一级警长 -->
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 180px"
+        />
+        <span>单位</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+        <span>职务</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+      </div>
+      <div class="line">
+        <span>法 医: &nbsp;&nbsp; </span>
+        <span>姓名</span>
+        <!-- 单位 XX派出所 职务 一级警长 -->
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 180px"
+        />
+        <span>单位</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+        <span>职务</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+      </div>
+      <div class="line">
+        <span>法 医: &nbsp;&nbsp; </span>
+        <span>姓名</span>
+        <!-- 单位 XX派出所 职务 一级警长 -->
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 180px"
+        />
+        <span>单位</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+        <span>职务</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+      </div>
+      <div class="line">现场勘验人员:</div>
+
+      <div class="line">
+        <span>本人签名: &nbsp;&nbsp; </span>
+        <span>_______________ &nbsp;&nbsp;</span>
+
+        <span>单位</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+        <span>职务</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+      </div>
+      <div class="line">
+        <span>本人签名: &nbsp;&nbsp; </span>
+        <span>_______________ &nbsp;&nbsp;</span>
+
+        <span>单位</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+        <span>职务</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+      </div>
+      <div class="line">
+        <span>本人签名: &nbsp;&nbsp; </span>
+        <span>_______________ &nbsp;&nbsp;</span>
+
+        <span>单位</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+        <span>职务</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+      </div>
+      <div class="line">
+        <span>本人签名: &nbsp;&nbsp; </span>
+        <span>_______________ &nbsp;&nbsp;</span>
+
+        <span>单位</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+        <span>职务</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+      </div>
+
+      <div class="line">现场勘验见证人:</div>
+
+      <div class="line">
+        <span>本人签名: &nbsp;&nbsp; </span>
+        <span>_______________ &nbsp;&nbsp;</span>
+        <span>性别</span>
+        <el-select
+          class="input"
+          v-model="data.x"
+          placeholder="性别"
+          style="width: 140px"
+        >
+          <el-option :value="0" label="男" />
+          <el-option :value="1" label="女" />
+        </el-select>
+        <span>出生日期</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 200px"
+        />
+        <span>住址</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address"
+          placeholder=""
+          style="width: 260px"
+        />
+      </div>
+      <div class="line">
+        <span>本人签名: &nbsp;&nbsp; </span>
+        <span>_______________ &nbsp;&nbsp;</span>
+        <span>性别</span>
+        <el-select
+          class="input"
+          v-model="data.x"
+          placeholder="性别"
+          style="width: 140px"
+        >
+          <el-option :value="0" label="男" />
+          <el-option :value="1" label="女" />
+        </el-select>
+        <span>出生日期</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address1"
+          placeholder=""
+          style="width: 200px"
+        />
+        <span>住址</span>
+        <el-input
+          class="input"
+          type="text"
+          v-model="data.address12"
+          placeholder=""
+          style="width: 260px"
+        />
+      </div>
+
+      <div class="textarea">
+        <span>备注:</span>
+        <el-input
+          type="textarea"
+          :rows="6"
+          v-model="data.specialInquest"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div></div>
+    </div>
+  </div>
+</template>
+<script setup>
+import { onMounted, ref, watch } from "vue";
+import { reactive } from "vue";
+import {
+  getCaseInquestInfo,
+  saveCaseInquestInfo,
+  exportCaseInquestInfo,
+} from "@/store/case";
+import { ElMessage } from "element-plus";
+import saveAs from "@/util/file-serve";
+const props = defineProps({ caseId: Number, title: String });
+
+console.log(props);
+const isDisableExport = ref(false);
+const data = reactive({
+  inquestNum: "", //现场勘验号
+  deptName: "", //单位名称
+  sendDept: "", //发送单位
+  issuanceCount: "", // 份数
+  makeTime: "", //制作时间
+  recorder: "", // 笔录人
+  issuanceOpinion: "", //签发意见
+  reportDept: "", //报告单位
+  times: [], // startTime ,endTime
+  address: "", // 勘验地址
+
+  protector: {
+    name: "",
+    unit: "",
+    job: "",
+  }, // 现场保护人
+  protectionSituation: "", // 现场保护情况
+  situation: [], //现场情况
+  changeReason: [],
+  changeReasonOtherValue: "",
+  protectionMeasures: [], //保护措施
+  weatherInfo: {
+    type: [],
+    temperature: "",
+    humidity: "",
+    windDirection: "",
+  }, //天气情况
+  light: [], //光线
+  inquestCommander: {
+    name: "",
+    unit: "",
+    job: "",
+  }, //现场勘验指挥人
+  inquestSituation: "", //现场勘验情况
+  imageNum: 0, //现场勘验制图数量
+  photographNum: 0, //照相数量
+  photographyNum: 0, //摄影数量
+  recorderInfo: [],
+  signatureInfo: [],
+  witnessInfo: [],
+  remark: [],
+});
+
+const initInfo = async () => {
+  const res = await getCaseInquestInfo(props.caseId);
+
+  if (!res.data) {
+    isDisableExport.value = true;
+  } else {
+    isDisableExport.value = false;
+  }
+  for (var k in data) {
+    if (res.data && res.data.hasOwnProperty(k)) {
+      console.log("Key is " + k);
+      data[k] = res.data[k];
+    }
+  }
+};
+
+onMounted(() => {
+  initInfo();
+});
+
+const addwitnessInfo = () => {
+  // witnessInfoes.value += 1
+  data.witnessInfo.push({
+    name: "",
+    year: "",
+    month: "",
+    day: "",
+    id: "",
+  });
+};
+
+const handleSave = async () => {
+  console.log("data", data);
+  const res = await saveCaseInquestInfo(props.caseId, data);
+  if (res.code === 0) {
+    ElMessage.success("保存成功!");
+    initInfo();
+  }
+};
+const handleExport = async () => {
+  await saveCaseInquestInfo(props.caseId, data);
+  const res = await exportCaseInquestInfo(props.caseId);
+  console.log("res", res);
+  saveAs(res, `${props.title}_勘验笔录.docx`);
+};
+</script>
+
+<style lang="scss">
+.records {
+  max-width: 1280px;
+  margin: 0 auto;
+  padding: 20px 0;
+
+  .header {
+    display: flex;
+    justify-content: flex-endTime;
+  }
+
+  .input {
+    height: 32px;
+    line-height: 32px;
+    margin: 0 8px;
+  }
+
+  .textarea {
+    margin-right: 8px;
+    margin-bottom: 20px;
+
+    span {
+      padding: 10px 0;
+      display: inline-block;
+    }
+
+    // margin: 0 8px;
+  }
+
+  .line {
+    display: inline-flex;
+    width: 100%;
+    flex-direction: row;
+    align-items: center;
+    margin-bottom: 25px;
+    line-height: 38px;
+
+    span {
+      white-space: nowrap;
+    }
+  }
+}
+
+.title {
+  text-align: center;
+  margin-bottom: 30px;
+}
+
+.sub-tit {
+  display: inline-block;
+  padding-bottom: 20px;
+}
+
+.info {
+  display: block;
+
+  .inner {
+    display: flex;
+    flex-direction: row;
+    width: 100%;
+
+    .input {
+      flex: 1;
+    }
+
+    .sec {
+      flex: 1;
+      display: inline-flex;
+      align-items: center;
+      justify-content: center;
+    }
+  }
+}
+
+.witnessInfo {
+  background: #f5f5f5;
+  padding: 15px;
+  margin-top: 20px;
+  margin-right: 8px;
+}
+
+.gap {
+  margin: 15px 0;
+}
+
+.btn-container {
+  padding: 20px 0;
+
+  .btn {
+    color: #26559b;
+    width: 100%;
+
+    &:hover {
+      background: #f5f5f5;
+      border-color: #dcdfe6;
+    }
+  }
+}
+</style>

+ 444 - 0
src/view/case/records/manifest.vue

@@ -0,0 +1,444 @@
+<template>
+  <div class="records">
+    <div class="header">
+      <el-button type="primary" @click="handleSave">保存</el-button>
+      <el-button :disabled="isDisableExport" @click="handleExport"
+        >导出</el-button
+      >
+    </div>
+
+    <div class="content">
+      <div class="line">
+        <span>单位/地址:</span>
+        <el-input
+          class="input"
+          v-model="data.address"
+          placeholder=""
+          style="width: 100%"
+        />
+      </div>
+
+      <div class="line">
+        <span>提取日期:</span>
+        <div>
+          <el-input
+            class="input"
+            :maxlength="4"
+            type="text"
+            v-model="data.time.year"
+            placeholder=""
+            style="width: 80px"
+          />
+          <span>年</span>
+          <el-input
+            class="input"
+            :maxlength="2"
+            type="text"
+            v-model="data.time.month"
+            placeholder=""
+            style="width: 80px"
+          />
+          <span>月</span>
+          <el-input
+            class="input"
+            :maxlength="2"
+            type="text"
+            v-model="data.time.day"
+            placeholder=""
+            style="width: 80px"
+          />
+          <span>日</span>
+        </div>
+      </div>
+
+      <div class="detail">
+        <span class="sub-tit">提取清单:</span>
+        <template v-for="(item, index) in data.detail">
+          <div class="con">
+            <span class="sub-tit">编号 {{ index + 1 }}: </span>
+            <div class="info">
+              <div class="inner">
+                <div class="sec">
+                  <span>名称: </span>
+                  <el-input class="input" v-model="item.name" placeholder="" />
+                </div>
+
+                <div class="sec">
+                  <span>规格: </span>
+                  <el-input class="input" v-model="item.spec" placeholder="" />
+                </div>
+
+                <div class="sec">
+                  <span>数量: </span>
+                  <el-input class="input" v-model="item.num" placeholder="" />
+                </div>
+              </div>
+              <div class="inner">
+                <div class="sec">
+                  <span>提取部位: </span>
+                  <el-input class="input" v-model="item.part" placeholder="" />
+                </div>
+              </div>
+              <div class="inner">
+                <div class="sec">
+                  <span>特征: </span>
+                  <el-input class="input" v-model="item.desc" placeholder="" />
+                </div>
+              </div>
+            </div>
+          </div>
+        </template>
+      </div>
+      <div class="btn-container">
+        <el-button class="btn" @click="addItem">+新增</el-button>
+      </div>
+      <div class="gap"></div>
+
+      <div class="extractUser">
+        <span class="sub-tit">提取人:</span>
+        <template v-for="extractUser in data.extractUser">
+          <div class="line">
+            <span>姓名:</span>
+            <el-input
+              class="input"
+              v-model="extractUser.name"
+              placeholder=""
+              style="width: 20%"
+            />
+            <span>工作单位:</span>
+            <el-input
+              class="input"
+              v-model="extractUser.address"
+              placeholder=""
+              style="width: 70%"
+            />
+          </div>
+        </template>
+      </div>
+      <div class="btn-container">
+        <el-button class="btn" @click="addextractUser">+新增</el-button>
+      </div>
+      <!-- 证人 -->
+      <div>
+        <span>证人或当事人:</span>
+        <template v-for="wit in data.witnessInfo">
+          <div class="witnessInfo">
+            <!-- <span class="sub-tit">证人信息:</span> -->
+            <div class="line">
+              <span>姓名:</span>
+              <el-input
+                class="input"
+                v-model="wit.name"
+                placeholder=""
+                style="width: 180px"
+              />
+              <span style="margin-left: 50px">身份证件号码:</span>
+              <el-input
+                class="input"
+                v-model="wit.id"
+                placeholder=""
+                style="width: 280px"
+              />
+              <span style="margin-left: 50px">联系电话:</span>
+              <el-input
+                class="input"
+                v-model="wit.phone"
+                placeholder=""
+                style="width: 280px"
+              />
+            </div>
+            <div class="line">
+              <span>单位或住址:</span>
+              <el-input
+                class="input"
+                v-model="wit.address"
+                placeholder=""
+                style="width: 100%"
+              />
+            </div>
+          </div>
+        </template>
+      </div>
+      <div class="btn-container">
+        <el-button class="btn" @click="addwitnessInfo">+新增</el-button>
+      </div>
+      <div></div>
+    </div>
+  </div>
+</template>
+<script setup>
+import { onMounted, ref, watch } from "vue";
+import { reactive } from "vue";
+import {
+  getCaseDetailInfo,
+  saveCaseDetailInfo,
+  exportCaseDetailInfo,
+} from "@/store/case";
+import saveAs from "@/util/file-serve";
+import { ElMessage } from "element-plus";
+
+const props = defineProps({ caseId: Number, title: String });
+
+const isDisableExport = ref(false);
+
+console.log(props);
+
+const data = reactive({
+  address: "",
+  time: {
+    year: "",
+    month: "",
+    day: "",
+  },
+
+  location: "",
+  detail: [
+    {
+      // id: "1",
+      name: "",
+      spec: "",
+      num: "",
+      part: "",
+      desc: "",
+    },
+    {
+      // id: "2",
+      name: "",
+      spec: "",
+      num: "",
+      part: "",
+      desc: "",
+    },
+  ],
+  extractUser: [
+    {
+      name: "",
+      workplace: "",
+      id: "",
+    },
+
+    {
+      name: "",
+      address: "",
+      id: "",
+    },
+  ],
+
+  witnessInfo: [
+    {
+      name: "",
+      address: "",
+      phone: "",
+      id: "",
+    },
+    {
+      name: "",
+      address: "",
+      phone: "",
+      id: "",
+    },
+  ],
+});
+
+watch(
+  data,
+  (newValue) => {
+    // data.userName = newValue.userName.replace(/[^0-9]/g, '');
+    const sMonth = newValue.time.month.replace(/[^0-9]/g, "");
+    const sDay = newValue.time.day.replace(/[^0-9]/g, "");
+
+    data.time.year = newValue.time.year.replace(/[^0-9]/g, "");
+    data.time.month = Number(sMonth) > 12 ? "12" : sMonth;
+    data.time.day = Number(sDay) > 31 ? "31" : sDay;
+  },
+  {
+    immediate: true,
+    deep: true,
+  }
+);
+
+onMounted(() => {});
+
+const addwitnessInfo = () => {
+  data.witnessInfo.push({
+    name: "",
+    address: "",
+    phone: "",
+    id: "",
+  });
+};
+const addItem = () => {
+  data.detail.push({
+    // id: "1",
+    name: "",
+    spec: "",
+    num: "",
+    part: "",
+    desc: "",
+  });
+};
+const addextractUser = () => {
+  data.extractUser.push({
+    name: "",
+    address: "",
+    id: "",
+  });
+};
+const handleSave = async () => {
+  console.log("data", data);
+  const res = await saveCaseDetailInfo(props.caseId, data);
+  if (res.code === 0) {
+    ElMessage.success("保存成功!");
+    initInfo();
+  }
+};
+const handleExport = async () => {
+  await saveCaseDetailInfo(props.caseId, data);
+  const res = await exportCaseDetailInfo(props.caseId);
+  console.log("res", res);
+  saveAs(res, `${props.title}_提取清单.docx`);
+};
+const initInfo = async () => {
+  const res = await getCaseDetailInfo(props.caseId);
+
+  console.log("res", res);
+  for (var k in data) {
+    if (!res.data) {
+      isDisableExport.value = true;
+    } else {
+      isDisableExport.value = false;
+    }
+    if (res.data && res.data.hasOwnProperty(k)) {
+      // console.log("Key is " + k)
+      data[k] = res.data[k];
+    }
+  }
+};
+onMounted(() => {
+  initInfo();
+});
+</script>
+
+<style lang="scss">
+.records {
+  max-width: 1280px;
+  margin: 0 auto;
+  padding: 20px 0;
+
+  .header {
+    display: flex;
+    justify-content: flex-end;
+    margin-bottom: 50px;
+  }
+
+  .input {
+    height: 32px;
+    line-height: 32px;
+    margin: 0 8px;
+  }
+
+  .textarea {
+    margin-right: 8px;
+    margin-bottom: 20px;
+
+    span {
+      padding: 10px 0;
+      display: inline-block;
+    }
+
+    // margin: 0 8px;
+  }
+
+  .line {
+    display: inline-flex;
+    width: 100%;
+    flex-direction: row;
+    align-items: center;
+    margin-bottom: 25px;
+    line-height: 38px;
+
+    span {
+      white-space: nowrap;
+    }
+  }
+}
+
+.title {
+  text-align: center;
+}
+
+.sub-tit {
+  display: inline-block;
+  padding-bottom: 20px;
+}
+
+.info {
+  display: block;
+
+  .inner {
+    display: flex;
+    flex-direction: row;
+    width: 100%;
+
+    .input {
+      flex: 1;
+    }
+
+    .sec {
+      flex: 1;
+      display: inline-flex;
+      align-items: center;
+      justify-content: center;
+    }
+  }
+}
+.witnessInfo {
+  background: #f5f5f5;
+  padding: 15px;
+  margin-top: 20px;
+  // margin-right: 8px;
+}
+
+.gap {
+  margin: 15px 0;
+}
+
+.btn-container {
+  padding: 20px 0;
+
+  .btn {
+    color: #26559b;
+    width: 100%;
+
+    &:hover {
+      background: #f5f5f5;
+      border-color: #dcdfe6;
+    }
+  }
+}
+
+.detail {
+  .con {
+    padding: 20px;
+    background-color: #f5f5f5;
+  }
+
+  .info {
+    .inner {
+      margin-bottom: 20px;
+    }
+  }
+}
+
+.extractUser {
+  margin-right: 0px;
+
+  .line {
+    background-color: #f5f5f5;
+    padding: 15px;
+    width: calc(100% - 30px);
+    display: inline-flex;
+    margin-bottom: 15px;
+  }
+}
+</style>