editFire.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. <template>
  2. <el-form ref="form" label-width="94px" 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="勘验地址" class="mandatory">
  38. <el-input v-model="bindFire.field1" maxlength="50" placeholder="请输入勘验地址" />
  39. </el-form-item>
  40. <el-form-item label="勘验信息" class="mandatory">
  41. <el-input
  42. v-model="bindFire.projectSite"
  43. placeholder="请输入天气情况等标准化勘验信息"
  44. />
  45. <!--
  46. <el-cascader
  47. style="width: 100%"
  48. v-model="projectSite"
  49. placeholder="天气情况等标准化勘验信息"
  50. :options="place"
  51. :props="{ expandTrigger: 'hover' }"
  52. /> -->
  53. </el-form-item>
  54. <el-form-item label="全宗名称" class="mandatory">
  55. <el-input v-model="bindFire.field2" maxlength="50" placeholder="请输入全宗名称" />
  56. </el-form-item>
  57. <div class="el-form-item">
  58. <el-col :span="12">
  59. <el-form-item label="承办单位" class="mandatory">
  60. <companySelect v-model="bindFire.deptId" hideAll :notUpdate="true" disabled />
  61. </el-form-item>
  62. </el-col>
  63. <el-col :span="12">
  64. <el-form-item label="勘验人员" class="mandatory" placeholder="请输入勘验人员">
  65. <el-input v-model="bindFire.organizerUsers" maxlength="50" />
  66. </el-form-item>
  67. </el-col>
  68. </div>
  69. <div class="el-form-item">
  70. <el-col :span="12">
  71. <el-form-item label="勘验人姓名" class="mandatory">
  72. <el-input
  73. v-model="bindFire.field3"
  74. maxlength="18"
  75. placeholder="请输入勘验人姓名"
  76. />
  77. </el-form-item>
  78. </el-col>
  79. <el-col :span="12">
  80. <el-form-item label="单位、职务" class="mandatory">
  81. <el-input
  82. v-model="bindFire.field4"
  83. maxlength="50"
  84. placeholder="请输入勘验人单位、职务"
  85. />
  86. </el-form-item>
  87. </el-col>
  88. </div>
  89. <div class="el-form-item">
  90. <el-col :span="12">
  91. <el-form-item label="勘验日期" class="mandatory" placeholder="请选择勘验日期">
  92. <el-date-picker
  93. type="date"
  94. v-model="accidentDate"
  95. style="width: 100%"
  96. :disabled-date="(date) => date.getTime() > new Date().getTime()"
  97. />
  98. </el-form-item>
  99. </el-col>
  100. <el-col :span="12">
  101. <el-form-item label="大屏显示" class="mandatory">
  102. <el-switch v-model="bindFire.mapShow" :disabled="!bindFire.latlng" />
  103. </el-form-item>
  104. </el-col>
  105. </div>
  106. </el-form>
  107. </template>
  108. <script setup lang="ts">
  109. import companySelect from "@/components/company-select/index.vue";
  110. import { ref, watchEffect } from "vue";
  111. import { Fire, setFire, addFire } from "@/app/fire/store/fire";
  112. import { reason, place } from "@/app/fire/constant/fire";
  113. import { ElMessage } from "element-plus";
  114. import { dateFormat, debounce } from "@/util";
  115. import { genCascaderValue, getCode } from "@/helper/cascader";
  116. import { QuiskExpose } from "@/helper/mount";
  117. import AMapLoader from "@amap/amap-jsapi-loader";
  118. import { user } from "@/store/user";
  119. import { Search } from "@element-plus/icons-vue";
  120. const props = defineProps<{ fire?: Fire }>();
  121. const bindFire = ref<Fire>(
  122. props.fire
  123. ? { ...props.fire }
  124. : ({
  125. deptId: user.value.info.deptId,
  126. } as Fire)
  127. );
  128. const fireReason = genCascaderValue(bindFire, "fireReason");
  129. const projectSite = genCascaderValue(bindFire, "projectSite");
  130. const accidentDate = ref(
  131. bindFire.value.accidentDate ? new Date(bindFire.value.accidentDate) : new Date()
  132. );
  133. const keyword = ref(bindFire.value.projectAddress || "");
  134. const resultEl = ref<HTMLDivElement>();
  135. const searchAMap = ref<any>();
  136. type MapInfo = { lat: number; lng: number };
  137. const info = ref<MapInfo>();
  138. const mapEl = ref<HTMLDivElement>();
  139. watchEffect(async (onCleanup) => {
  140. if (!mapEl.value || !resultEl.value) {
  141. return;
  142. }
  143. const AMap = await AMapLoader.load({
  144. plugins: ["AMap.PlaceSearch"],
  145. key: "e661b00bdf2c44cccf71ef6070ef41b8",
  146. version: "2.0",
  147. });
  148. const map = new AMap.Map(mapEl.value, {
  149. WebGLParams: {
  150. preserveDrawingBuffer: true,
  151. },
  152. resizeEnable: true,
  153. });
  154. const placeSearch = new AMap.PlaceSearch({
  155. pageSize: 5,
  156. pageIndex: 1,
  157. map: map,
  158. panel: resultEl.value,
  159. autoFitView: true,
  160. });
  161. placeSearch.on("listElementClick", (e) => {
  162. bindFire.value.projectAddress =
  163. e.data.pname + e.data.cityname + e.data.adname + e.data.address;
  164. keyword.value = bindFire.value.projectAddress;
  165. console.log(e.data);
  166. bindFire.value.latAndLong = `${e.data.location.lat},${e.data.location.lng}`;
  167. bindFire.value.latlng = `${e.data.location.lat},${e.data.location.lng}`;
  168. info.value = {
  169. lat: e.data.lat,
  170. lng: e.data.lng,
  171. };
  172. });
  173. searchAMap.value = placeSearch;
  174. console.log(placeSearch.listElementClick);
  175. onCleanup(() => {
  176. searchAMap.value = null;
  177. map.destroy();
  178. });
  179. });
  180. const search = () => {
  181. info.value = undefined;
  182. searchAMap.value.search(keyword.value);
  183. };
  184. defineExpose<QuiskExpose>({
  185. async submit() {
  186. if (!bindFire.value.projectAddress || !bindFire.value.projectAddress.trim()) {
  187. ElMessage.error("详细地址不能为空!");
  188. throw "详细地址不能为空!";
  189. } else if (!bindFire.value.projectSn || !bindFire.value.projectSn.trim()) {
  190. ElMessage.error("事件分类不能为空!");
  191. throw "事件分类不能为空!";
  192. } else if (!bindFire.value.projectName || !bindFire.value.projectName.trim()) {
  193. ElMessage.error("分类登记不能为空!");
  194. throw "分类登记不能为空!";
  195. } else if (!bindFire.value.projectSite || !bindFire.value.projectSite.trim()) {
  196. ElMessage.error("天气情况等标准化勘验信息不能为空!");
  197. throw "天气情况等标准化勘验信息不能为空!";
  198. } else if (!bindFire.value.deptId || !bindFire.value.deptId.trim()) {
  199. ElMessage.error("承办单位不能为空!");
  200. throw "承办单位不能为空!";
  201. } else if (!bindFire.value.organizerUsers || !bindFire.value.organizerUsers.trim()) {
  202. ElMessage.error("勘验人员不能为空!");
  203. throw "勘验人员不能为空!";
  204. } else if (!accidentDate) {
  205. ElMessage.error("勘验日期不能为空!");
  206. throw "勘验日期不能为空!";
  207. }
  208. // else if (!bindFire.value.fireReason || !bindFire.value.fireReason.trim()) {
  209. // ElMessage.error("火灾原因不能为空!");
  210. // throw "火灾原因不能为空!";
  211. // }
  212. bindFire.value.accidentDate = dateFormat(accidentDate.value, "yyyy-MM-dd");
  213. bindFire.value.projectSiteCode = getCode(place, bindFire.value.projectSite);
  214. bindFire.value.id
  215. ? await setFire(bindFire.value)
  216. : await addFire(bindFire.value as any);
  217. },
  218. });
  219. </script>
  220. <style scoped>
  221. .search-result {
  222. position: absolute;
  223. left: 0;
  224. right: 0;
  225. z-index: 1;
  226. overflow: hidden;
  227. top: 100%;
  228. &.show {
  229. max-height: 450px;
  230. overflow-y: auto;
  231. }
  232. }
  233. .def-map-info {
  234. margin-top: 10px;
  235. p {
  236. font-size: 14px;
  237. color: rgba(0, 0, 0, 0.85);
  238. display: inline;
  239. &:not(:last-child)::after {
  240. content: ",";
  241. margin-right: 6px;
  242. }
  243. }
  244. span::after {
  245. content: ":";
  246. }
  247. }
  248. .def-select-map {
  249. position: absolute;
  250. opacity: 0;
  251. z-index: -1;
  252. width: 540px;
  253. height: 390px;
  254. z-index: 1;
  255. left: -100vw;
  256. top: -100vh;
  257. display: none;
  258. }
  259. .asdasd {
  260. position: relative;
  261. margin-bottom: 15px;
  262. z-index: 2;
  263. }
  264. </style>