index.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. import {
  2. ref,
  3. defineComponent,
  4. computed,
  5. onMounted,
  6. onUnmounted,
  7. reactive,
  8. } from 'vue';
  9. import { useRoute, useRouter } from 'vue-router';
  10. import { upload, UploadData } from '@/api/common';
  11. import cloneDeep from 'lodash/cloneDeep';
  12. import div from '@/components/div';
  13. import { useCommonStore, useIncidentStore } from '@/store';
  14. import QueryMap from '@/components/QueryMap';
  15. import { BaseMediaUrl} from '@/utils/index';
  16. // import MediaUpload from '@/components/MediaUpload';
  17. import './index.scss';
  18. import {
  19. DropdownItemOption,
  20. NavBar,
  21. DropdownMenu,
  22. DropdownItem,
  23. Icon,
  24. PullRefresh,
  25. Sticky,
  26. Collapse,
  27. CollapseItem,
  28. Loading,
  29. Form,
  30. Field,
  31. CellGroup,
  32. Popup,
  33. Picker,
  34. ActionBar,
  35. Button,
  36. Notify,
  37. Uploader,
  38. UploaderFileListItem,
  39. } from 'vant';
  40. import { isArray } from 'lodash';
  41. export default defineComponent({
  42. name: 'IncidentManagementReport',
  43. setup() {
  44. const store = useIncidentStore();
  45. const commonStore = useCommonStore();
  46. const detail = computed(() => store.incidentDetail?.baseInfo);
  47. const addr = ref('');
  48. const form = ref({ ...detail.value });
  49. const formRef = ref();
  50. const showCreateByPicker = ref(false);
  51. const showCreateTypeByPicker = ref(false);
  52. const route = useRoute();
  53. const router = useRouter();
  54. const isshowprew = ref(false);
  55. const videosrclist = reactive([]);
  56. const imagessrclist = reactive([]);
  57. const videop = ref();
  58. const videopsrc = ref("");
  59. const handleUpload = (file) => {
  60. upload(file).then((res) => {
  61. let type = /\w+([.jpg|.png|.gif|.swf|.bmp|.jpeg]){1}$/.test(
  62. res.data.fileName?.substr( res.data.fileName?.lastIndexOf('.') + 1 ) ?? '',
  63. );
  64. if (!type) {
  65. videosrclist.push(res.data);
  66. } else {
  67. imagessrclist.push(res.data);;
  68. }
  69. }).catch((error)=>{
  70. });
  71. };
  72. const handleSaveReport = () => {
  73. const { id } = route.query;
  74. const saveFn = id ? store.putIncidentItem : store.postIncidentItem;
  75. // console.log(formRef);
  76. const result = saveFn({
  77. ...form.value,
  78. level: Number(form.value.level) ?? null,
  79. type: Number(form.value.type) ?? null,
  80. pic: imagessrclist.map((i: UploadData) => i.url).join(','),
  81. video: videosrclist.map((i: UploadData) => i.url).join(','),
  82. // status: route.params.status as unknown as number,
  83. });
  84. };
  85. onMounted(async () => {
  86. commonStore.getGlobalDict('zhdd_incident_level');
  87. commonStore.getGlobalDict('zhdd_incident_type');
  88. commonStore.getGlobalDict('zhdd_org_upload');
  89. route.query.id && (await store.getIncidentItem(route.query.id as string));
  90. addr.value = detail?.value?.addr ?? '';
  91. if (detail.value) {
  92. form.value = cloneDeep(detail.value);
  93. }
  94. });
  95. onUnmounted(() => {
  96. commonStore.uploadFiles = [];
  97. store.incidentDetail = {};
  98. store.incidentDetail = {
  99. baseInfo: {},
  100. process: [],
  101. task: [],
  102. };
  103. });
  104. return () => (
  105. <div class="incident-report-container ">
  106. <NavBar
  107. title="应急处置"
  108. left-arrow
  109. fixed
  110. onClick-left={() => router.push('/home')}
  111. />
  112. <Popup
  113. style="width:100%;background:rgba(0,0,0,0)"
  114. v-model:show={isshowprew.value}
  115. onClose={() => {
  116. videop.value.pause();
  117. }}>
  118. <video
  119. ref={videop}
  120. src={videopsrc.value}
  121. controls
  122. autoplay="true"
  123. style="width:100%"></video>
  124. </Popup>
  125. <Form>
  126. <CellGroup>
  127. <Field
  128. v-model={form.value.name}
  129. name="事件标题"
  130. label="事件标题"
  131. placeholder="请输入"
  132. required
  133. rules={[{ required: true, message: '事件标题必填' }]}
  134. />
  135. <Field
  136. v-model={form.value.createBy}
  137. name="上报人"
  138. label="上报人"
  139. placeholder="请输入"
  140. required
  141. rules={[{ required: true, message: '上报人必填' }]}
  142. />
  143. <Field
  144. v-model={form.value.createDept}
  145. name="上报单位"
  146. label="上报单位"
  147. placeholder="请输入"
  148. required
  149. rules={[{ required: true, message: '上报单位必填' }]}
  150. />
  151. <Field
  152. v-model={form.value.typeText}
  153. is-link
  154. readonly
  155. name="事件类型"
  156. label="事件类型"
  157. placeholder="请选择"
  158. required
  159. rules={[{ required: true, message: '事件类型必填' }]}
  160. onClick={() => (showCreateTypeByPicker.value = true)}
  161. />
  162. <Popup
  163. v-model:show={showCreateTypeByPicker.value}
  164. position="bottom">
  165. <Picker
  166. columns={commonStore.globalDict['zhdd_incident_type']?.map(
  167. (i) => ({ text: i.dictLabel, value: i.dictValue }),
  168. )}
  169. onConfirm={(value) => {
  170. form.value.typeText = value.text;
  171. form.value.type = value.value;
  172. console.log(value, '---');
  173. showCreateTypeByPicker.value = false;
  174. }}
  175. onCancel={() => {
  176. showCreateTypeByPicker.value = false;
  177. }}
  178. />
  179. </Popup>
  180. <Field
  181. v-model={form.value.levelText}
  182. is-link
  183. readonly
  184. name="事件等级"
  185. label="事件等级"
  186. placeholder="请选择"
  187. required
  188. rules={[{ required: true, message: '事件等级必填' }]}
  189. onClick={() => (showCreateByPicker.value = true)}
  190. />
  191. <Popup v-model:show={showCreateByPicker.value} position="bottom">
  192. <Picker
  193. columns={commonStore.globalDict['zhdd_incident_level']?.map(
  194. (i) => ({ text: i.dictLabel, value: i.dictValue }),
  195. )}
  196. onConfirm={(value) => {
  197. form.value.levelText = value.text;
  198. form.value.level = value.value;
  199. console.log(value, '---');
  200. showCreateByPicker.value = false;
  201. }}
  202. onCancel={() => {
  203. showCreateByPicker.value = false;
  204. }}
  205. />
  206. </Popup>
  207. <Field
  208. v-model={form.value.des}
  209. rows={2}
  210. autosize
  211. name="事件描述"
  212. label="事件描述"
  213. type="textarea"
  214. placeholder="请输入"
  215. />
  216. <Field
  217. v-model={form.value.addr}
  218. name="事件地点"
  219. label="事件地点"
  220. placeholder="请输入"
  221. required
  222. onChange={(add: string) => {
  223. addr.value = add.target.value;
  224. }}
  225. rules={[{ required: true, message: '事件地点必填' }]}
  226. />
  227. <QueryMap
  228. address={addr.value}
  229. v-model:locations={form.value.locations}
  230. v-model:longitude={(form.value.locations ?? '').split(',')[0]}
  231. v-model:latitude={(form.value.locations ?? '').split(',')[1]}
  232. onChoose={(name) => {
  233. form.value.addr = name;
  234. }}
  235. onRestPositon={() => {
  236. addr.value = store.incidentDetail.baseInfo?.addr ?? '';
  237. form.value.addr = store.incidentDetail.baseInfo?.addr;
  238. form.value.locations = store.incidentDetail.baseInfo?.locations;
  239. }}
  240. />
  241. <Field
  242. name="上传视频"
  243. label="上传视频"
  244. placeholder="请输入"
  245. v-slots={{
  246. input: () => (
  247. <Uploader
  248. accept="video/*"
  249. v-model={form.value.video}
  250. afterRead={(
  251. file: UploaderFileListItem | UploaderFileListItem[],
  252. ) => {
  253. handleUpload((isArray(file) ? file[0] : file).file);
  254. return false;
  255. }}
  256. onDelete={(filep, detail) => {
  257. videosrclist.splice(detail.index, 1);
  258. console.log(videosrclist);
  259. }}
  260. onClick-preview={(index) => {
  261. isshowprew.value = true;
  262. try {
  263. videopsrc.value = URL.createObjectURL(index.file);
  264. videop.value.play();
  265. videop.value.currentTime = 0;
  266. } catch (error) {}
  267. }}
  268. // v-slots={{
  269. // 'preview-cover': () => (
  270. // <video
  271. // style="width:100%;height:100%"
  272. // controls
  273. // src="https://vod-progressive.akamaized.net/exp=1643032410~acl=%2Fvimeo-prod-skyfire-std-us%2F01%2F2673%2F7%2F188365455%2F623960082.mp4~hmac=e4a0fb352e805ff4fe74317441bf6f6deb059508cc7bb2f7aa92884023b13818/vimeo-prod-skyfire-std-us/01/2673/7/188365455/623960082.mp4?filename=Emoji+Saver+-+Drama.mp4"></video>
  274. // ),
  275. // }}
  276. />
  277. ),
  278. }}
  279. />
  280. <Field
  281. name="上传图片"
  282. label="上传图片"
  283. placeholder="请输入"
  284. v-slots={{
  285. input: () => (
  286. <Uploader
  287. accept="image/*"
  288. v-model={form.value.pic}
  289. onDelete={(filep, detail) => {
  290. imagessrclist.splice(detail.index, 1);
  291. console.log(imagessrclist);
  292. }}
  293. afterRead={(
  294. file: UploaderFileListItem | UploaderFileListItem[],
  295. ) => {
  296. handleUpload((isArray(file) ? file[0] : file).file);
  297. return false;
  298. }}
  299. />
  300. ),
  301. }}
  302. />
  303. </CellGroup>
  304. <div style={{ height: '80px' }}></div>
  305. <ActionBar>
  306. <div style={{ padding: '10px 20px' }}>
  307. <Button block type="primary" onClick={handleSaveReport}>
  308. 提交
  309. </Button>
  310. </div>
  311. </ActionBar>
  312. </Form>
  313. </div>
  314. );
  315. },
  316. });