123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518 |
- import {
- ref,
- defineComponent,
- computed,
- onMounted,
- onUnmounted,
- reactive,
- } from 'vue';
- import { useRoute, useRouter } from 'vue-router';
- import { upload, UploadData } from '@/api/common';
- import cloneDeep from 'lodash/cloneDeep';
- import div from '@/components/div';
- import { useCommonStore, useIncidentStore } from '@/store';
- import QueryMap from '@/components/QueryMap';
- import { BaseMediaUrl } from '@/utils/index';
- import { api_getusergps } from '@/service/login';
- // import MediaUpload from '@/components/MediaUpload';
- /** @ts-ignore */
- import icon_map_location from '@/assets/icons/home/icon_map_location@2x.png';
- /** @ts-ignore */
- import icon_location from '@/assets/icons/incident/location.png';
- import './index.scss';
- import {
- DropdownItemOption,
- NavBar,
- DropdownMenu,
- DropdownItem,
- Icon,
- PullRefresh,
- Sticky,
- Collapse,
- CollapseItem,
- Loading,
- Form,
- Field,
- CellGroup,
- Popup,
- Picker,
- ActionBar,
- Button,
- Notify,
- Uploader,
- UploaderFileListItem,
- Toast,
- } from 'vant';
- import { isArray } from 'lodash';
- export default defineComponent({
- name: 'IncidentManagementReport',
- setup() {
- const store = useIncidentStore();
- const commonStore = useCommonStore();
- const detail = computed(() => store.incidentDetail?.baseInfo);
- const addr = ref('');
- const form = ref({ ...detail.value });
- const formRef = ref();
- const showCreateByPicker = ref(false);
- const showCreateByDeptPicker = ref(false);
- const showCreateTypeByPicker = ref(false);
- const route = useRoute();
- const router = useRouter();
- const isshowprew = ref(false);
- const videosrclist = reactive([]);
- const imagessrclist = reactive([]);
- const videop = ref();
- const videopsrc = ref("");
-
- const handleUpload = (file) => {
- upload(file).then((res) => {
- let type = /\w+([.jpg|.png|.gif|.swf|.bmp|.jpeg]){1}$/.test(
- res.data.fileName?.substr( res.data.fileName?.lastIndexOf('.') + 1 ) ?? '',
- );
- if (!type) {
- videosrclist.push(res.data);
- } else {
- imagessrclist.push(res.data);;
- }
- }).catch((error)=>{
- });
- };
- const handleSaveReport = async () => {
- const { id } = route.query;
- const saveFn = id ? store.putIncidentItem : store.postIncidentItem;
- // console.log(formRef);
- const result = await saveFn({
- ...form.value,
- // level: Number(form.value.level) ?? null,
- // type: Number(form.value.type) ?? null,
- pic: imagessrclist.map((i: UploadData) => i.url).join(','),
- video: videosrclist.map((i: UploadData) => i.url).join(','),
- source: '1',
- // status: route.params.status as unknown as number,
- });
- if (result) {
- router.push("/")
- }
- };
- const getLocation = () => {
- api_getusergps().then((res) => {
- var lat = null;
- var lon = null;
- var iserror = false;
- try {
- lat = res.result[0].lat;
- lon = res.result[0].lon;
- if (lat == null || lat == undefined) iserror = true;
- } catch (e) {
- iserror = true;
- }
- if (!iserror) {
- var location = `${lon},${lat}`;
- fetch(
- `https://minedata.cn/service/lbs/reverse/v1/regeo?location=${location}&key=${window.key}`,
- {
- method: 'GET',
- headers: new Headers({
- 'Content-Type': 'application/json',
- }),
- },
- )
- .then((res) => res.json())
- .then((data) => {
- // console.log(data)
- // console.log(data.regeocodes[0].formatted_address);
- var ll = data.regeocodes[0].formatted_address;
- if (!window.map) {
- Notify({
- type: 'danger',
- message: '地图插件初始化异常, 请刷新页面 (Ctrl + R)',
- });
- return;
- }
- window.map.flyTo({
- center: [
- Number(location.split(',')[0]),
- Number(location.split(',')[1]),
- ],
- zoom: 14,
- bearing: 0,
- pitch: 0,
- duration: 2000,
- });
- if (window.map && window._marker) {
- window._marker.remove();
- window._marker = null;
- }
- if (window.map) {
- var el = document.createElement('div');
- el.id = 'marker';
- el.style.backgroundImage = `url(${icon_map_location})`;
- el.style.backgroundSize = 'cover';
- el.style.width = '24px';
- el.style.height = '24px';
- el.style.borderRadius = '50%';
- const popup = new window.minemap.Popup({
- closeOnClick: false,
- closeButton: false,
- offset: [0, -15],
- }).setText(ll);
- window._marker = new window.minemap.Marker(el, {
- offset: [-12, -12],
- })
- .setLngLat([
- Number(location.split(',')[0]),
- Number(location.split(',')[1]),
- ])
- .setPopup(popup)
- .addTo(window.map);
- }
- window._marker.togglePopup();
- // var ll =
- // data.regeocodes[0].formatted_address.replaceAll(
- // '江苏省宿迁市',
- // "");
- form.value.locations = location;
- form.value.addr = ll;
- });
- // minemap.service
- // .adminByPointData({
- // location: `${position.coords.longitude},${position.coords.latitude}`,
- // })
- // .then(function (response) {
- // console.log(response.data);
- // })
- // .catch(function (error) {
- // console.error(error);
- // });
-
- // (ee) => {
- // console.log(ee);
- // },
-
- } else {
- Notify({
- type: 'danger',
- message: 'App不支持地理定位。',
- });
- }
- })
-
- };
- onMounted(async () => {
- commonStore.getGlobalDict('zhdd_incident_level');
- commonStore.getGlobalDict('zhdd_incident_type');
- commonStore.getGlobalDict('zhdd_org_upload');
- try {
- getLocation();
- } catch (E) { }
-
- route.query.id && (await store.getIncidentItem(route.query.id as string));
- addr.value = detail?.value?.addr ?? '';
- if (detail.value) {
- form.value = cloneDeep(detail.value);
- }
- });
- onUnmounted(() => {
- commonStore.uploadFiles = [];
- store.incidentDetail = {};
- store.incidentDetail = {
- baseInfo: {},
- process: [],
- task: [],
- };
- });
- return () => (
- <div class="incident-report-container ">
- <NavBar
- title="应急事件上报"
- left-arrow
- fixed
- onClick-left={() => {
- // router.push('/home')
- uni.postMessage({
- data: 'test',
- });
- uni.navigateBack();
- }}
- />
- <Popup
- style="width:100%;background:rgba(0,0,0,0)"
- v-model:show={isshowprew.value}
- onClose={() => {
- videop.value.pause();
- }}>
- <video
- ref={videop}
- src={videopsrc.value}
- controls
- autoplay="true"
- style="width:100%"></video>
- </Popup>
- <Form>
- <CellGroup>
- <Field
- v-model={form.value.name}
- name="事件标题"
- label="事件标题"
- placeholder="请输入"
- required
- rules={[{ required: true, message: '事件标题必填' }]}
- />
- {/* <Field
- v-model={form.value.createBy}
- name="上报人"
- label="上报人"
- placeholder="请输入"
- required
- rules={[{ required: true, message: '上报人必填' }]}
- />
- <Field
- v-model={form.value.createDeptText}
- name="上报单位"
- is-link
- readonly
- label="上报单位"
- placeholder="请选择"
- required
- rules={[{ required: true, message: '上报单位必填' }]}
- onClick={() => (showCreateByDeptPicker.value = true)}
- />
- <Field
- v-model={form.value.typeText}
- is-link
- readonly
- name="事件类型"
- label="事件类型"
- placeholder="请选择"
- required
- rules={[{ required: true, message: '事件类型必填' }]}
- onClick={() => (showCreateTypeByPicker.value = true)}
- />
- <Popup
- v-model:show={showCreateTypeByPicker.value}
- position="bottom">
- <Picker
- columns={commonStore.globalDict['zhdd_incident_type']?.map(
- (i) => ({ text: i.dictLabel, value: i.dictValue }),
- )}
- onConfirm={(value) => {
- form.value.typeText = value.text;
- form.value.type = value.value;
- console.log(value, '---');
- showCreateTypeByPicker.value = false;
- }}
- onCancel={() => {
- showCreateTypeByPicker.value = false;
- }}
- />
- </Popup>
- <Field
- v-model={form.value.levelText}
- is-link
- readonly
- name="事件等级"
- label="事件等级"
- placeholder="请选择"
- required
- rules={[{ required: true, message: '事件等级必填' }]}
- onClick={() => (showCreateByPicker.value = true)}
- />
- <Popup v-model:show={showCreateByPicker.value} position="bottom">
- <Picker
- columns={commonStore.globalDict['zhdd_incident_level']?.map(
- (i) => ({ text: i.dictLabel, value: i.dictValue }),
- )}
- onConfirm={(value) => {
- form.value.levelText = value.text;
- form.value.level = value.value;
- console.log(value, '---');
- showCreateByPicker.value = false;
- }}
- onCancel={() => {
- showCreateByPicker.value = false;
- }}
- />
- </Popup>
- <Popup
- v-model:show={showCreateByDeptPicker.value}
- position="bottom">
- <Picker
- columns={commonStore.globalDict['zhdd_org_upload']?.map(
- (i) => ({ text: i.dictLabel, value: i.dictValue }),
- )}
- onConfirm={(value) => {
- form.value.createDeptText = value.text;
- form.value.createDept = value.value;
- console.log(value, '---');
- showCreateByDeptPicker.value = false;
- }}
- onCancel={() => {
- showCreateByDeptPicker.value = false;
- }}
- />
- </Popup> */}
- <Field
- v-model={form.value.des}
- rows={2}
- autosize
- name="事件描述"
- label="事件描述"
- type="textarea"
- placeholder="请输入"
- />
- <div style={"position:relative"}>
- <Field
- v-model={form.value.addr}
- name="事件地点"
- label="事件地点"
- placeholder="请输入"
- required
- style={'width:85%'}
- onChange={(add: string) => {
- addr.value = add.target.value;
- }}
- rules={[{ required: true, message: '事件地点必填' }]}
- />
- <Button style={'border:none;position:absolute;right:10px;top:0'} onClick={() => { getLocation();}}>
- <img style={'width:20px;height:20px'} src={icon_location} />
- </Button>
- </div>
- <QueryMap
- address={addr.value}
- v-model:locations={form.value.locations}
- v-model:longitude={(form.value.locations ?? '').split(',')[0]}
- v-model:latitude={(form.value.locations ?? '').split(',')[1]}
- onChoose={(name) => {
- form.value.addr = name;
- }}
- onRestPositon={() => {
- addr.value = store.incidentDetail.baseInfo?.addr ?? '';
- form.value.addr = store.incidentDetail.baseInfo?.addr;
- form.value.locations = store.incidentDetail.baseInfo?.locations;
- }}
- />
- <Field
- name="上传图片"
- label="上传图片"
- placeholder="请输入"
- v-slots={{
- input: () => (
- <Uploader
- accept="image/*"
- v-model={form.value.pic}
- max-size={20 * 1024 * 1024}
- onOversize={() => {
- Toast('最大支持20M的图片');
- }}
- onDelete={(filep, detail) => {
- imagessrclist.splice(detail.index, 1);
- console.log(imagessrclist);
- }}
- afterRead={(
- file: UploaderFileListItem | UploaderFileListItem[],
- ) => {
- handleUpload((isArray(file) ? file[0] : file).file);
- return false;
- }}
- />
- ),
- }}
- />
- <Field
- name="上传视频"
- label="上传视频"
- placeholder="请输入"
- v-slots={{
- input: () => (
- <Uploader
- accept="video/*"
- v-model={form.value.video}
- max-size={100 * 1024 * 1024}
- onOversize={() => {
- Toast('最大支持100M的视屏');
- }}
- afterRead={(
- file: UploaderFileListItem | UploaderFileListItem[],
- ) => {
- handleUpload((isArray(file) ? file[0] : file).file);
- return false;
- }}
- onDelete={(filep, detail) => {
- videosrclist.splice(detail.index, 1);
- console.log(videosrclist);
- }}
- onClick-preview={(index) => {
- isshowprew.value = true;
- try {
- videopsrc.value = URL.createObjectURL(index.file);
- videop.value.play();
- videop.value.currentTime = 0;
- } catch (error) {}
- }}
- // v-slots={{
- // 'preview-cover': () => (
- // <video
- // style="width:100%;height:100%"
- // controls
- // 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>
- // ),
- // }}
- />
- ),
- }}
- />
- </CellGroup>
- <div style={{ height: '80px' }}></div>
- <ActionBar>
- <div style={{ padding: '10px 20px' }}>
- <Button block type="primary" onClick={handleSaveReport}>
- 提交
- </Button>
- </div>
- </ActionBar>
- </Form>
- </div>
- );
- },
- });
|