1
0

index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. <template>
  2. <div class="abstract">
  3. <el-tabs v-model="activeName" class="demo-tabs h-full" @tab-click="handleClick">
  4. <el-tab-pane label="现场图" name="1">
  5. <div class="xct">
  6. <el-button
  7. class="w-full mt-4"
  8. type="primary"
  9. @click="gotoDraw(BoardType.scene, -1)"
  10. >
  11. 绘制平面图
  12. </el-button>
  13. <!-- <el-button
  14. style="width: calc(50% - 6px)"
  15. type="primary"
  16. @click="handleAiItem"
  17. >
  18. AI 平面图
  19. </el-button> -->
  20. <el-button
  21. class="w-full mt-4"
  22. style="margin-left: 0"
  23. type="primary"
  24. @click="gotoDraw(BoardType.map, -1)"
  25. >
  26. 绘制方位图
  27. </el-button>
  28. <!-- <div class="phote my-4 w-full">
  29. <p class="pb-2 title1">平面图</p>
  30. <div class="pmt-phote w-full flex justify-between ">
  31. <viewImg :list="list.pmt" delete @handleItem="handleoverviewItem" height="66px" />
  32. </div>
  33. </div>
  34. <div class="phote my-4 w-full">
  35. <p class="pb-2 title1">方位图</p>
  36. <div class="pmt-phote w-full flex justify-between ">
  37. <viewImg :list="list.fwt || []" delete @handleItem="handletabulationItem" height="66px" />
  38. </div>
  39. </div> -->
  40. <div class="phote my-4 w-full" v-for="item,index in list.xct" :key="index" v-show="item.caseFilesList?.length">
  41. <p class="pb-2 title1">{{item.filesTypeName}}</p>
  42. <div class="pmt-phote w-full flex justify-between ">
  43. <viewImg :list="item.caseFilesList || []" @handleItem="handleoverviewItem" height="66px" />
  44. </div>
  45. </div>
  46. </div>
  47. </el-tab-pane>
  48. <el-tab-pane class="h-full" label="现场照片" name="2">
  49. <div class="scene h-full">
  50. <el-button class="w-full" @click="handleAdd(['三录材料', '现场照片'])">上传</el-button>
  51. <!-- <el-button class="w-full my-4" style="margin-left: 0; margin-right: 0">添加场景</el-button> -->
  52. <div class="scene-list">
  53. <div class="list">
  54. <div class="listItem py-2" v-for="item,index in list.xczp" :key="index">
  55. <div class="title1 pb-2">{{item.filesTypeName}}</div>
  56. <viewImg :list="item.caseFilesList || []" @handleItem="handleItems" />
  57. <div class="list2" v-for="item2,index2 in item.childrenList" :key="index2" v-show="item2.caseFilesList?.length">
  58. <div class="title2">{{item2.filesTypeName}}</div>
  59. <viewImg :list="item2.caseFilesList || []" @handleItem="handleItems" />
  60. </div>
  61. </div>
  62. </div>
  63. </div>
  64. <el-button class="w-full" @click="handledrawCasePhotos">照片制卷</el-button>
  65. </div>
  66. </el-tab-pane>
  67. <el-tab-pane label="勘验笔录" name="3">
  68. <div class="blfrom">
  69. <el-upload
  70. class="upload-demo"
  71. :multiple="false"
  72. :show-file-list="false"
  73. drag
  74. :limit="1"
  75. :before-upload="upload"
  76. :file-list="fileLists"
  77. :http-request="uploadNewFile"
  78. :on-success="handleSuccess"
  79. :on-preview="previewFile"
  80. :accept="accept"
  81. :before-remove="removeFile"
  82. >
  83. <div type="primary" :disabled="!!file">
  84. <div>点击或拖拽文件上传</div>
  85. <div class="">支持 pdf、word 上传</div>
  86. </div>
  87. </el-upload>
  88. <el-button class="w-full mt-4" @click="handleRecords(-1)">在线填写</el-button>
  89. </div>
  90. <div class="blList">
  91. <div class="bllistItem flex justify-between items-center mt-4" v-for="item,index in list.klbj" :key="index">
  92. <div class="truncate" :title="item.filesTitle">{{item.filesTitle}}</div>
  93. <el-dropdown style="width: 20px" @command="(command)=>{handleCommand(command, item)}">
  94. <el-icon>
  95. <MoreFilled />
  96. </el-icon>
  97. <template #dropdown>
  98. <el-dropdown-menu>
  99. <el-dropdown-item v-if="item.createType == 'online'" command="edit">编辑</el-dropdown-item>
  100. <el-dropdown-item command="delete">删除</el-dropdown-item>
  101. <el-dropdown-item command="down">下载</el-dropdown-item>
  102. </el-dropdown-menu>
  103. </template>
  104. </el-dropdown>
  105. </div>
  106. </div>
  107. </el-tab-pane>
  108. </el-tabs>
  109. <el-dialog
  110. v-model="dialogVisible"
  111. title="请选择场景"
  112. width="500"
  113. :before-close="handleClose"
  114. >
  115. <div>
  116. <el-radio-group v-model="radio">
  117. <el-radio style=" width: 100%;" v-for="item,index in radioList" :key="index" :value="item.num">{{item.title}}</el-radio>
  118. </el-radio-group>
  119. </div>
  120. <template #footer>
  121. <div class="dialog-footer">
  122. <el-button @click="dialogVisible = false">取消</el-button>
  123. <el-button type="primary" @click="handleRadioItem"> 确认</el-button>
  124. </div>
  125. </template>
  126. </el-dialog>
  127. </div>
  128. </template>
  129. <script setup lang="ts">
  130. import { uploadNewFile, addByMediaLiBrary, getSceneListHasAi } from "@/store/case";
  131. import { computed, ref, reactive } from "vue";
  132. import { addCaseFile } from "../originalPhoto/quisk";
  133. import { ElMessage, ElMessageBox } from "element-plus";
  134. import { useUpload } from "@/hook/upload";
  135. import { selectMapImage } from "@/view/case/quisk";
  136. import { RouteName, router } from "@/router";
  137. import { BoardType } from "@/store/caseFile";
  138. import { updateByTreeFileLists, caseOverview, overviewAdd, getcaseByCaseId } from "@/store/case";
  139. import { Delete, Edit } from "@element-plus/icons-vue";
  140. import { setTypeFile } from "../originalPhoto/quisk";
  141. import viewImg from "@/components/viewImg/index.vue"
  142. import { delCaseFile } from "@/store/caseFile";
  143. import { uploadOldFile } from "@/store/system";
  144. const caseId = computed(() => (router.currentRoute.value?.params?.caseId));
  145. const active = ref(true);
  146. const radio = ref(null);
  147. const radioList = ref([]);
  148. const dialogVisible = ref(false);
  149. const list = ref({
  150. xct:[],
  151. xczp:[],
  152. klbj:[],
  153. pmt:[],
  154. fwt:[],
  155. });
  156. getList()
  157. const srcList = [
  158. "https://07akioni.oss-cn-beijing.aliyuncs.com/07akioni.jpeg",
  159. "https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg",
  160. ];
  161. const settype = ref(false);
  162. const ruleFormRef = ref(null);
  163. const klblId = ref(0);
  164. const fmtId = ref(0);
  165. const pmtId = ref(0);
  166. const activeName = ref('1');
  167. const fileLists = ref([]);
  168. const showModal = ref(false);
  169. const { size, fileList, upload, removeFile, previewFile, file, accept } =
  170. useUpload({
  171. maxSize: 10 * 1024 * 1024,
  172. formats: [".doc", ".docx", ".pdf"],
  173. });
  174. const handleClick = (tab) => {
  175. console.log(tab);
  176. };
  177. const getcaseByCaseIdList = async () =>{
  178. // let pmt = await caseOverview(caseId.value)
  179. // let fwt = await getcaseByCaseId(caseId.value)
  180. // list.value.pmt = pmt.map(ele =>{
  181. // let mapUrl = ele.mapUrl || ele.listCover
  182. // return {
  183. // ...ele,
  184. // mapUrl: mapUrl,
  185. // }
  186. // })
  187. // list.value.fwt = fwt.map(ele =>{
  188. // let mapUrl = ele.mapUrl || ele.listCover
  189. // return {
  190. // ...ele,
  191. // mapUrl: mapUrl,
  192. // }
  193. // })
  194. // console.log('getcaseByCaseId', res)
  195. // })
  196. }
  197. const gotoDraw = async (type: BoardType, id: number) => {
  198. if(BoardType.scene == type) {
  199. window.open(`/draw/#/overview?caseId=${caseId.value}`);
  200. }else{
  201. const {blob, width, height} = await selectMapImage({});
  202. console.log('blob', blob)
  203. if(!blob){
  204. return
  205. }
  206. const file = new File([blob], `方位图_.jpg`)
  207. const mapUrl = await uploadOldFile(file)
  208. const res = await overviewAdd({
  209. caseId: caseId.value,
  210. title: '方位图',
  211. listCover: mapUrl,
  212. high: height,
  213. width,
  214. mapUrl
  215. })
  216. getcaseByCaseIdList()
  217. getList()
  218. window.open(`/draw/#/tabulation?caseId=${caseId.value}&tabulationId=${res.id}`);
  219. }
  220. // router.push({
  221. // name: RouteName.drawCaseFile,
  222. // params: { caseId: caseId.value!, type, id },
  223. // });
  224. };
  225. function getList() {
  226. updateByTreeFileLists(caseId.value).then(res => {
  227. let newlist = res.find(ele => ele.filesTypeName == '三录材料')?.childrenList || [];
  228. list.value.xct = newlist.find(ele => ele.filesTypeName == '现场图')?.childrenList || [];
  229. list.value.xczp = newlist.find(ele => ele.filesTypeName == '现场照片')?.childrenList || [];
  230. list.value.klbj = newlist.find(ele => ele.filesTypeName == '勘验笔录')?.caseFilesList || [];
  231. klblId.value = newlist.find(ele => ele.filesTypeName == '勘验笔录').filesTypeId
  232. fmtId.value = list.value.xct.find(ele => ele.filesTypeName == '平面图').filesTypeId
  233. pmtId.value = list.value.xct.find(ele => ele.filesTypeName == '方位图').filesTypeId
  234. console.log('list.value', list.value)
  235. getcaseByCaseIdList()
  236. })
  237. }
  238. const submitForm = async (formEl) => {
  239. if (!formEl) return;
  240. await formEl.validate((valid, fields) => {
  241. if (valid) {
  242. console.log("submit!");
  243. } else {
  244. console.log("error submit!", fields);
  245. }
  246. });
  247. };
  248. const resetForm = (formEl) => {
  249. if (!formEl) return;
  250. formEl.resetFields();
  251. };
  252. function handleActive(params) {
  253. console.log("handleActive", params);
  254. }
  255. function handleoverviewItem(type, item) {
  256. console.log("handleoverviewItem", type, item);
  257. if('edit' == type) {
  258. let url = item.filesTitle == '平面图'? `/draw/#/overview?caseId=${caseId.value}&overviewId=${item.overviewId}`:`/draw/#/tabulation?caseId=${caseId.value}&tabulationId=${item.tabulationId}`;
  259. window.open(url);
  260. // gotoDraw(item.filesTypeId != pmtId.value? BoardType.scene : BoardType.map, item.filesId)
  261. }else{
  262. getList()
  263. }
  264. }
  265. // function handleoverviewItem(type, item) {
  266. // console.log("handleoverviewItem", type, item);
  267. // if('edit' == type) {
  268. // window.open(`/draw/#/overview?caseId=${caseId.value}&overviewId=${item.id}`);
  269. // // gotoDraw(item.filesTypeId != pmtId.value? BoardType.scene : BoardType.map, item.filesId)
  270. // }else{
  271. // getList()
  272. // }
  273. // }
  274. function handleItem(type, item) {
  275. console.log("handleItem", type, item);
  276. if('edit' == type) {
  277. gotoDraw(item.filesTypeId != pmtId.value? BoardType.scene : BoardType.map, item.filesId)
  278. }
  279. getList()
  280. }
  281. async function handleItems(type, item) {
  282. console.log("handleItem", type, item);
  283. if('edit' == type) {
  284. await setTypeFile({
  285. ...item,caseId:caseId.value,
  286. fileOptions: list.value.xczp,
  287. })
  288. }
  289. getList()
  290. }
  291. function handleSuccess(item) {
  292. let uploadId = item?.data.id;
  293. addByMediaLiBrary({ caseId: caseId.value, filesTypeId: klblId.value, uploadId }).then((res) => {
  294. fileLists.value = []
  295. getList();
  296. });
  297. }
  298. function handleRecords(fileId = -1) {
  299. router.push({
  300. name: RouteName.records,
  301. params: { caseId:caseId.value, fileId },
  302. });
  303. }
  304. async function handledrawCasePhotos() {
  305. router.push({
  306. name: RouteName.drawCasePhotos,
  307. params: { caseId: caseId.value! },
  308. });
  309. console.log("handleAdd");
  310. }
  311. async function handleAdd(filesTypeName) {
  312. await addCaseFile({ caseId: caseId.value, filesTypeName });
  313. getList()
  314. console.log("handleAdd");
  315. }
  316. const handleCommand = (command: string | number | object, item) => {
  317. switch (command) {
  318. case "edit":
  319. handleRecords(item.filesId)
  320. break;
  321. case "delete":
  322. handleDel(item)
  323. break;
  324. default:
  325. // window.open(item.filesUrl)
  326. console.log("other", item);
  327. downloadFile(item.filesUrl, item.filesTitle)
  328. }
  329. // ElMessage(`click on item ${command}`)
  330. }
  331. function getExtension (name) {
  332. return name.substring(name.lastIndexOf("."))
  333. }
  334. // 下载文件
  335. function downloadFile(sourceUrl, fileName,) {
  336. const link = document.createElement('a');
  337. link.style.display = 'none';
  338. // 设置下载地址
  339. link.setAttribute('href', sourceUrl);
  340. // 设置文件名
  341. link.setAttribute('download', fileName + getExtension(sourceUrl));
  342. document.body.appendChild(link);
  343. link.click();
  344. document.body.removeChild(link);
  345. }
  346. function handleClose(e) {
  347. console.log("handleClose", e);
  348. dialogVisible.value = false
  349. }
  350. function handleRadioItem() {
  351. console.log('handleRadioItem', radio.value)
  352. if(radio.value == null){
  353. ElMessage.error('请选择对应的场景!');
  354. return;
  355. }
  356. dialogVisible.value = false
  357. window.open(`/floorplan/index.html?m=${radio.value}`)
  358. }
  359. function handleAiItem() {
  360. getSceneListHasAi(caseId.value).then((res) => {
  361. console.log('getSceneListHasAi', res)
  362. let newradioList = []
  363. res.data.map(ele => {
  364. newradioList.push(ele)
  365. })
  366. radioList.value = newradioList
  367. if(newradioList.length){
  368. dialogVisible.value = true
  369. }else{
  370. ElMessage.error('暂无支持AI 平面图的场景');
  371. }
  372. });
  373. }
  374. function handleDel(item) {
  375. ElMessageBox.confirm("确定删除?", "提示", {
  376. confirmButtonText: "确定",
  377. cancelButtonText: "取消",
  378. type: "warning",
  379. }).then(async () => {
  380. await delCaseFile({ caseId: caseId.value, filesId: item.filesId });
  381. ElMessage({
  382. type: "success",
  383. message: "删除成功",
  384. });
  385. getList()
  386. });
  387. }
  388. </script>
  389. <style lang="scss" scoped>
  390. .abstract {
  391. height: 100%;
  392. .el-tab-pane{
  393. height: 100%;
  394. overflow-y: scroll;
  395. position: relative;
  396. }
  397. .el-form-item--label-top {
  398. margin-bottom: 14px;
  399. }
  400. .form-content {
  401. height: calc(100vh - 225px);
  402. overflow-y: scroll;
  403. }
  404. .demo-tabs {
  405. .el-tabs__item {
  406. height: 32px;
  407. line-height: 32px;
  408. }
  409. }
  410. }
  411. </style>