editFire.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. <template>
  2. <el-form ref="form" label-width="106px" class="camera-from">
  3. <div class="def-select-map" ref="mapEl"></div>
  4. <div class="el-form-item">
  5. <el-col :span="12">
  6. <el-form-item label="项目编号" class="mandatory">
  7. <el-input
  8. v-model="bindFire.projectSn"
  9. maxlength="18"
  10. placeholder="请输入项目编号"
  11. />
  12. </el-form-item>
  13. </el-col>
  14. <el-col :span="12">
  15. <el-form-item label="起火对象" class="mandatory">
  16. <el-input
  17. v-model="bindFire.projectName"
  18. maxlength="50"
  19. placeholder="请输入起火对象"
  20. />
  21. </el-form-item>
  22. </el-col>
  23. </div>
  24. <el-form-item label="详细地址" class="mandatory asdasd">
  25. <!-- <el-input
  26. v-model="bindFire.projectAddress"
  27. maxlength="50"
  28. placeholder="请输入详细地址"
  29. /> -->
  30. <el-input v-model="keyword" placeholder="输入名称搜索" clearable @change="search">
  31. <template #append>
  32. <el-button :icon="Search" @click="search" />
  33. </template>
  34. </el-input>
  35. <div class="search-result" v-show="!info" ref="resultEl"></div>
  36. </el-form-item>
  37. <el-form-item label="勘验地址">
  38. <el-input v-model="bindFire.field1" maxlength="50" placeholder="请输入勘验地址" />
  39. </el-form-item>
  40. <el-form-item label="起火场所" class="mandatory">
  41. <el-cascader
  42. style="width: 100%"
  43. v-model="projectSite"
  44. placeholder="起火场所"
  45. :options="place"
  46. :props="{ expandTrigger: 'hover' }"
  47. />
  48. </el-form-item>
  49. <!-- <el-form-item label="全宗名称">
  50. <el-input v-model="bindFire.field2" maxlength="50" placeholder="请输入全宗名称" />
  51. </el-form-item> -->
  52. <div class="el-form-item">
  53. <el-col :span="12">
  54. <el-form-item label="勘验单位" class="mandatory">
  55. <companySelect v-model="bindFire.deptId" hideAll :notUpdate="true" disabled />
  56. </el-form-item>
  57. </el-col>
  58. <el-col :span="12">
  59. <el-form-item label="勘验人员" class="mandatory">
  60. <el-input
  61. v-model="bindFire.organizerUsers"
  62. maxlength="50"
  63. placeholder="请输入勘验人员"
  64. />
  65. </el-form-item>
  66. </el-col>
  67. </div>
  68. <div class="el-form-item">
  69. <!-- <el-col :span="12">
  70. <el-form-item label="勘验人姓名">
  71. <el-input
  72. v-model="bindFire.field3"
  73. maxlength="18"
  74. placeholder="请输入勘验人姓名"
  75. />
  76. </el-form-item>
  77. </el-col> -->
  78. <el-col :span="12">
  79. <el-form-item label="勘验人职务">
  80. <el-input
  81. v-model="bindFire.field4"
  82. maxlength="50"
  83. placeholder="请输入勘验人职务"
  84. />
  85. </el-form-item>
  86. </el-col>
  87. <el-col :span="12">
  88. <el-form-item label="火灾原因" class="mandatory">
  89. <el-cascader
  90. style="width: 100%"
  91. v-model="fireReason"
  92. placeholder="火灾原因:"
  93. :options="reason"
  94. :props="{ expandTrigger: 'hover' }"
  95. />
  96. </el-form-item>
  97. </el-col>
  98. </div>
  99. <div class="el-form-item">
  100. <el-col :span="12">
  101. <el-form-item label="事故日期" class="mandatory" placeholder="请选择事故日期">
  102. <el-date-picker
  103. type="date"
  104. v-model="accidentDate"
  105. style="width: 100%"
  106. :disabled-date="(date) => date.getTime() > new Date().getTime()"
  107. />
  108. </el-form-item>
  109. </el-col>
  110. <el-col :span="12">
  111. <el-form-item label="大屏显示" class="mandatory">
  112. <el-switch v-model="bindFire.mapShow" :disabled="!bindFire.latlng" />
  113. </el-form-item>
  114. </el-col>
  115. </div>
  116. <div class="el-form-item">
  117. <el-col :span="12">
  118. <el-form-item label="事件分类">
  119. <el-input
  120. v-model="bindFire.field5"
  121. maxlength="18"
  122. placeholder="请输入事件分类"
  123. />
  124. </el-form-item>
  125. </el-col>
  126. <el-col :span="12">
  127. <el-form-item label="分类登记">
  128. <el-input
  129. v-model="bindFire.field6"
  130. maxlength="50"
  131. placeholder="请输入分类登记"
  132. />
  133. </el-form-item>
  134. </el-col>
  135. </div>
  136. <div class="el-form-item">
  137. <el-col :span="12">
  138. <el-form-item label="天气情况">
  139. <el-input
  140. v-model="bindFire.field7"
  141. placeholder="请输入天气情况"
  142. show-word-limit
  143. maxlength="100"
  144. />
  145. </el-form-item>
  146. </el-col>
  147. <el-col :span="12">
  148. <el-form-item
  149. label="勘验起止时间"
  150. class="mandatory"
  151. placeholder="请选择勘验起止时间"
  152. >
  153. <el-date-picker
  154. v-model="f8"
  155. type="daterange"
  156. range-separator="-"
  157. start-placeholder="开始时间"
  158. end-placeholder="结束时间"
  159. :disabled-date="(date) => date.getTime() > new Date().getTime()"
  160. />
  161. <!-- <el-date-picker
  162. type="date"
  163. v-model="f8"
  164. style="width: 100%"
  165. :disabled-date="(date) => date.getTime() > new Date().getTime()"
  166. /> -->
  167. </el-form-item>
  168. </el-col>
  169. </div>
  170. </el-form>
  171. </template>
  172. <script setup lang="ts">
  173. import companySelect from "@/components/company-select/index.vue";
  174. import { ref, watchEffect } from "vue";
  175. import { Fire, setFire, addFire } from "@/app/fire/store/fire";
  176. import { reason, place } from "@/app/fire/constant/fire";
  177. import { ElMessage } from "element-plus";
  178. import { dateFormat, debounce } from "@/util";
  179. import { genCascaderValue, getCode } from "@/helper/cascader";
  180. import { QuiskExpose } from "@/helper/mount";
  181. import AMapLoader from "@amap/amap-jsapi-loader";
  182. import { user } from "@/store/user";
  183. import { Search } from "@element-plus/icons-vue";
  184. const props = defineProps<{ fire?: Fire }>();
  185. const bindFire = ref<Fire>(
  186. props.fire
  187. ? { ...props.fire }
  188. : ({
  189. deptId: user.value.info.deptId,
  190. } as Fire)
  191. );
  192. const fireReason = genCascaderValue(bindFire, "fireReason");
  193. const projectSite = genCascaderValue(bindFire, "projectSite");
  194. const accidentDate = ref(
  195. bindFire.value.accidentDate ? new Date(bindFire.value.accidentDate) : new Date()
  196. );
  197. const f8s = [new Date(), new Date()];
  198. if (bindFire.value.field8) {
  199. const s = bindFire.value.field8.split("至");
  200. console.log(s);
  201. if (s.length > 1) {
  202. f8s[0] = new Date(s[0]);
  203. f8s[1] = new Date(s[1]);
  204. } else {
  205. f8s[0] = new Date(s[0]);
  206. }
  207. }
  208. const f8 = ref(f8s);
  209. const keyword = ref(bindFire.value.projectAddress || "");
  210. const resultEl = ref<HTMLDivElement>();
  211. const searchAMap = ref<any>();
  212. type MapInfo = { lat: number; lng: number };
  213. const info = ref<MapInfo>();
  214. const mapEl = ref<HTMLDivElement>();
  215. watchEffect(async (onCleanup) => {
  216. if (!mapEl.value || !resultEl.value) {
  217. return;
  218. }
  219. const AMap = await AMapLoader.load({
  220. plugins: ["AMap.PlaceSearch"],
  221. key: "e661b00bdf2c44cccf71ef6070ef41b8",
  222. version: "2.0",
  223. });
  224. const map = new AMap.Map(mapEl.value, {
  225. WebGLParams: {
  226. preserveDrawingBuffer: true,
  227. },
  228. resizeEnable: true,
  229. });
  230. const placeSearch = new AMap.PlaceSearch({
  231. pageSize: 5,
  232. pageIndex: 1,
  233. map: map,
  234. panel: resultEl.value,
  235. autoFitView: true,
  236. });
  237. placeSearch.on("listElementClick", (e) => {
  238. bindFire.value.projectAddress =
  239. e.data.pname + e.data.cityname + e.data.adname + e.data.address;
  240. keyword.value = bindFire.value.projectAddress;
  241. console.log(e.data);
  242. bindFire.value.latAndLong = `${e.data.location.lat},${e.data.location.lng}`;
  243. bindFire.value.latlng = `${e.data.location.lat},${e.data.location.lng}`;
  244. info.value = {
  245. lat: e.data.lat,
  246. lng: e.data.lng,
  247. };
  248. });
  249. searchAMap.value = placeSearch;
  250. console.log(placeSearch.listElementClick);
  251. onCleanup(() => {
  252. searchAMap.value = null;
  253. map.destroy();
  254. });
  255. });
  256. const search = () => {
  257. info.value = undefined;
  258. searchAMap.value.search(keyword.value);
  259. };
  260. defineExpose<QuiskExpose>({
  261. async submit() {
  262. if (!bindFire.value.projectAddress || !bindFire.value.projectAddress.trim()) {
  263. ElMessage.error("详细地址不能为空!");
  264. throw "详细地址不能为空!";
  265. } else if (!bindFire.value.projectSn || !bindFire.value.projectSn.trim()) {
  266. ElMessage.error("项目编号不能为空!");
  267. throw "项目编号不能为空!";
  268. } else if (!bindFire.value.projectName || !bindFire.value.projectName.trim()) {
  269. ElMessage.error("起火对象不能为空!");
  270. throw "起火对象不能为空!";
  271. } else if (!bindFire.value.projectSite || !bindFire.value.projectSite.trim()) {
  272. ElMessage.error("起火场所不能为空!");
  273. throw "起火场所不能为空!";
  274. } else if (!bindFire.value.deptId || !bindFire.value.deptId.trim()) {
  275. ElMessage.error("勘验单位不能为空!");
  276. throw "勘验单位不能为空!";
  277. } else if (!bindFire.value.organizerUsers || !bindFire.value.organizerUsers.trim()) {
  278. ElMessage.error("勘验人员不能为空!");
  279. throw "勘验人员不能为空!";
  280. } else if (!accidentDate) {
  281. ElMessage.error("事故日期不能为空!");
  282. throw "事故日期不能为空!";
  283. } else if (!bindFire.value.fireReason || !bindFire.value.fireReason.trim()) {
  284. ElMessage.error("火灾原因不能为空!");
  285. throw "火灾原因不能为空!";
  286. }
  287. bindFire.value.accidentDate = dateFormat(accidentDate.value, "yyyy-MM-dd");
  288. bindFire.value.field8 =
  289. dateFormat(f8.value[0], "yyyy-MM-dd") +
  290. "至" +
  291. dateFormat(f8.value[1], "yyyy-MM-dd");
  292. bindFire.value.projectSiteCode = getCode(place, bindFire.value.projectSite);
  293. bindFire.value.id
  294. ? await setFire(bindFire.value)
  295. : await addFire(bindFire.value as any);
  296. },
  297. });
  298. </script>
  299. <style scoped>
  300. .search-result {
  301. position: absolute;
  302. left: 0;
  303. right: 0;
  304. z-index: 1;
  305. overflow: hidden;
  306. top: 100%;
  307. &.show {
  308. max-height: 450px;
  309. overflow-y: auto;
  310. }
  311. }
  312. .def-map-info {
  313. margin-top: 10px;
  314. p {
  315. font-size: 14px;
  316. color: rgba(0, 0, 0, 0.85);
  317. display: inline;
  318. &:not(:last-child)::after {
  319. content: ",";
  320. margin-right: 6px;
  321. }
  322. }
  323. span::after {
  324. content: ":";
  325. }
  326. }
  327. .def-select-map {
  328. position: absolute;
  329. opacity: 0;
  330. z-index: -1;
  331. width: 540px;
  332. height: 390px;
  333. z-index: 1;
  334. left: -100vw;
  335. top: -100vh;
  336. display: none;
  337. }
  338. .asdasd {
  339. position: relative;
  340. margin-bottom: 15px;
  341. z-index: 2;
  342. }
  343. </style>