| | |
| | | * @returns |
| | | */ |
| | | getClue({ sTime, eTime, pageNum = 1, pageSize = 30 }) { |
| | | let url = 'clue/fetch?'; |
| | | if (sTime) { |
| | | url += `sTime=${sTime}&`; |
| | | } |
| | | if (eTime) { |
| | | url += `eTime=${eTime}&`; |
| | | } |
| | | return $clue.get(`${url}pageNum=${pageNum}&pageSize=${pageSize}`); |
| | | return $clue.get(`clue/fetch`, { |
| | | params: { |
| | | sTime, |
| | | eTime, |
| | | pageNum, |
| | | pageSize |
| | | } |
| | | }); |
| | | // .then((res) => res.data); |
| | | }, |
| | | |
| | |
| | | * è·å线索ç»è®º |
| | | * @param {string} clueId 线索id |
| | | */ |
| | | getConclusion(clueId) { |
| | | return $clue.get(`clue/conclusion/fetch?clueId=${clueId}`).then((res) => res.data); |
| | | getConclusion(clueId, internal) { |
| | | return $clue |
| | | .get(`clue/conclusion/fetch`, { |
| | | params: { clueId, internal } |
| | | }) |
| | | .then((res) => res.data); |
| | | }, |
| | | |
| | | /** |
| | | * æäº¤çº¿ç´¢ç»è®º |
| | | * @param {object} conclusion 线索 |
| | | * @returns |
| | | * @returns |
| | | */ |
| | | uploadConclusion(conclusion) { |
| | | return $clue.post(`clue/conclusion/upload`, conclusion).then((res) => res.data); |
| | | return $clue |
| | | .post(`clue/conclusion/upload`, conclusion) |
| | | .then((res) => res.data); |
| | | }, |
| | | |
| | | /** |
| | | * æ¨é线索ç»è®ºè³ç¬¬ä¸æ¹ |
| | | * @param {Array} conclusionIdList 线索idéå |
| | | * @returns |
| | | * @returns |
| | | */ |
| | | pushConclusion(conclusionIdList) { |
| | | return $clue.post(`clue/conclusion/push`, conclusionIdList).then((res) => res.data); |
| | | return $clue |
| | | .post(`clue/conclusion/push`, conclusionIdList) |
| | | .then((res) => res.data); |
| | | } |
| | | }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { $clue } from '../index'; |
| | | |
| | | export default { |
| | | /** |
| | | * æ¥è¯¢çº¿ç´¢æ¸
å |
| | | * @param {object} param0 |
| | | * @returns |
| | | */ |
| | | getInternalClue({ sTime, eTime, pageNum = 1, pageSize = 30 }) { |
| | | return $clue.get(`clue/internal/fetch`, { |
| | | params: { |
| | | sTime, |
| | | eTime, |
| | | pageNum, |
| | | pageSize |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | createInternalClue(clueInternal) { |
| | | return $clue.put('clue/internal/create', clueInternal); |
| | | }, |
| | | |
| | | updateInternalClue(clueInternal) { |
| | | return $clue.post('clue/internal/update', clueInternal); |
| | | }, |
| | | |
| | | deleteInternalClue(clueInternal) { |
| | | return $clue.delete('clue/internal/delete', { |
| | | data: clueInternal |
| | | }); |
| | | } |
| | | }; |
| | |
| | | * è·åå·²æäº¤ç线索é®é¢ |
| | | * @param {string} clueId 线索id |
| | | */ |
| | | getQuestion(clueId) { |
| | | getQuestion(clueId, internal) { |
| | | return $clue |
| | | .get(`clue/question/fetch?clueId=${clueId}`) |
| | | .get(`clue/question/fetch`, { |
| | | params: { clueId, internal } |
| | | }) |
| | | .then((res) => { |
| | | return getClueQuestionList(res.data); |
| | | }); |
| | |
| | | files.forEach((e) => { |
| | | formData.append('images', e); |
| | | }); |
| | | return $clue.post(`clue/question/upload`, formData).then((res) => res.data); |
| | | return $clue |
| | | .post(`clue/question/upload`, formData) |
| | | .then((res) => res.data); |
| | | }, |
| | | |
| | | /** |
| | | * ä¿®æ¹çº¿ç´¢é®é¢ |
| | | * @param {object} question é®é¢æè¿° |
| | | * @param {*} files é®é¢å¾ç |
| | | * @param {Array} deleteImgUrl å é¤çå¾çç¸å¯¹è·¯å¾ï¼ç¨;åå² |
| | | * @returns |
| | | */ |
| | | updateQuestion(question, files, deleteImgUrl) { |
| | | const formData = new FormData(); |
| | | formData.append('question', JSON.stringify(question)); |
| | | formData.append('deleteImg', deleteImgUrl); |
| | | files.forEach((e) => { |
| | | formData.append('images', e); |
| | | }); |
| | | return $clue |
| | | .post(`clue/question/update`, formData) |
| | | .then((res) => res.data); |
| | | }, |
| | | |
| | | deleteQuestion(questionId) { |
| | | return $clue.delete(`clue/question`, { params: { questionId } }).then((res) => res.data); |
| | | return $clue |
| | | .delete(`clue/question`, { params: { questionId } }) |
| | | .then((res) => res.data); |
| | | }, |
| | | |
| | | uploadQuestionUrl() { |
| | |
| | | * @returns |
| | | */ |
| | | pushQuestion(questionIdList) { |
| | | return $clue.post(`clue/question/push`, questionIdList).then((res) => res.data); |
| | | return $clue |
| | | .post(`clue/question/push`, questionIdList) |
| | | .then((res) => res.data); |
| | | } |
| | | }; |
| | |
| | | |
| | | export default { |
| | | /** |
| | | * å建å
é¨çº¿ç´¢ä»»å¡ |
| | | * @param {*} clueTask |
| | | * @returns |
| | | */ |
| | | createClueTaskInternal(clueTaskInternal) { |
| | | return $clue.put(`clue/task/create/internal`, clueTaskInternal); |
| | | }, |
| | | |
| | | /** |
| | | * åå»ºçº¿ç´¢ä»»å¡ |
| | | * @param {*} clueTask |
| | | * @returns |
| | | */ |
| | | createClueTask(clueTask) { |
| | | return $clue |
| | | .put(`clue/task/create`, clueTask) |
| | | return $clue.put(`clue/task/create`, clueTask); |
| | | }, |
| | | |
| | | /** |
| | |
| | | * @returns |
| | | */ |
| | | updateClueTask(clueTask) { |
| | | return $clue |
| | | .post(`clue/task/update`, clueTask) |
| | | return $clue.post(`clue/task/update`, clueTask); |
| | | }, |
| | | |
| | | /** |
| | |
| | | * @returns |
| | | */ |
| | | fetchClueTask(clueTask) { |
| | | return $clue |
| | | .post(`clue/task/fetch`, clueTask) |
| | | return $clue.post(`clue/task/fetch`, clueTask); |
| | | }, |
| | | |
| | | /** |
| | | * å é¤çº¿ç´¢ä»»å¡ |
| | | * @param {*} clueTask |
| | | * @returns |
| | | */ |
| | | deleteClueTask(clueTask) { |
| | | return $clue.post(`clue/task/delete`, clueTask); |
| | | } |
| | | }; |
| | |
| | | // å¨åé请æ±ä¹å, æ·»å 请æ±å¤´ |
| | | // config.headers = addHeaders(config.headers); |
| | | |
| | | console.log('==>请æ±å¼å§'); |
| | | console.log(`${config.baseURL}${config.url}`); |
| | | if (config.data) { |
| | | console.log('==>è¯·æ±æ°æ®', config.data); |
| | | } |
| | | return config; |
| | | }, |
| | | function (error) { |
| | |
| | | function (response) { |
| | | // 2xx èå´å
çç¶æç é½ä¼è§¦åè¯¥å½æ°ã |
| | | // 对ååºæ°æ®åç¹ä»ä¹ |
| | | const config = response.config; |
| | | console.log('==>请æ±å¼å§', `${config.baseURL}${config.url}`); |
| | | if (config.data) { |
| | | console.log('==>è¯·æ±æ°æ®', config.data); |
| | | } |
| | | console.log(response); |
| | | console.log('==>请æ±ç»æ'); |
| | | if (response.status == 200) { |
| | |
| | | import axios from 'axios'; |
| | | import { setInterceptors } from "./config"; |
| | | |
| | | const debug = true; |
| | | const debug = false; |
| | | |
| | | // let url1 = 'http://47.100.191.150:9031/'; |
| | | // let url1_file = 'http://47.100.191.150:9031'; |
| | |
| | | return { |
| | | radioOptions: [ |
| | | { name: '线索管ç', label: 0 }, |
| | | { name: 'ç½æ ¼ç®¡ç', label: 1 } |
| | | // { name: 'ç½æ ¼ç®¡ç', label: 1 }, |
| | | { name: 'å
é¨çº¿ç´¢', label: 2 }, |
| | | ], |
| | | radio1: 0 |
| | | }; |
| | |
| | | <template> |
| | | <el-dialog v-model="dialogShow" width="70%" destroy-on-close> |
| | | <el-dialog |
| | | class="dialog" |
| | | v-model="dialogShow" |
| | | width="70%" |
| | | destroy-on-close |
| | | > |
| | | <template #header> |
| | | <div> åæ æ¾å</div> |
| | | <div>åæ æ¾å</div> |
| | | </template> |
| | | <div class="fy-tip-red">å·¦é®ç¹å»å°å¾éååæ ç¹ï¼æè
æ ¹æ®å
³é®åæç´¢å°ç¹</div> |
| | | <div class="fy-tip-red"> |
| | | å·¦é®ç¹å»å°å¾éååæ ç¹ï¼æè
æ ¹æ®å
³é®åæç´¢å°ç¹ |
| | | </div> |
| | | <el-row> |
| | | <el-col :span="10"> |
| | | <el-form |
| | |
| | | <span>{{ searchResult.address }}</span> |
| | | <div> |
| | | <span>{{ |
| | | 'é«å¾·' + searchResult.lon + ', ' + searchResult.lat |
| | | 'é«å¾·ï¼' + searchResult.lon + ', ' + searchResult.lat |
| | | }}</span> |
| | | <el-divider direction="vertical" /> |
| | | <span>{{ |
| | | 'GPS' + searchResult.gpsLon + ', ' + searchResult.gpsLat |
| | | 'GPSï¼' + |
| | | searchResult.gpsLon + |
| | | ', ' + |
| | | searchResult.gpsLat |
| | | }}</span> |
| | | </div> |
| | | </div> |
| | |
| | | }; |
| | | }, |
| | | props: { |
| | | show: Boolean |
| | | // å¯¹è¯æ¡æ¾ç¤ºéè |
| | | show: Boolean, |
| | | // é»è®¤æç´¢ç¹ç»çº¬åº¦ï¼[lng, lat] |
| | | defaultCoor: Array |
| | | }, |
| | | data() { |
| | | return { |
| | |
| | | geocoder = new AMap.Geocoder({ |
| | | city: '䏿µ·' // city æå®è¿è¡ç¼ç æ¥è¯¢çåå¸ï¼æ¯æä¼ å
¥åå¸åãadcode å citycode |
| | | }); |
| | | if (this.defaultCoor) { |
| | | const [lng, lat] = baseMapUtil.wgs84togcj02( |
| | | this.defaultCoor[0], |
| | | this.defaultCoor[1] |
| | | ); |
| | | const lnglat = new AMap.LngLat(lng, lat); |
| | | this.setMarker(lnglat); |
| | | this.getAddress(lnglat); |
| | | this.map.setFitView(); |
| | | } |
| | | this.map.on('click', (ev) => { |
| | | // this.formObj.lon = ev.lnglat.getLng(); |
| | | // this.formObj.lat = ev.lnglat.getLat(); |
| | | this.map.clearMap(); |
| | | const marker = new AMap.Marker({ |
| | | position: ev.lnglat |
| | | }); |
| | | this.map.add(marker); |
| | | |
| | | geocoder.getAddress(ev.lnglat, (status, result) => { |
| | | if (status === 'complete' && result.info === 'OK') { |
| | | this.searchResult.address = |
| | | result.regeocode.formattedAddress; |
| | | this.searchResult.lon = ev.lnglat.getLng(); |
| | | this.searchResult.lat = ev.lnglat.getLat(); |
| | | const [gpsLon, gpsLat] = baseMapUtil.gcj02towgs84( |
| | | this.searchResult.lon, |
| | | this.searchResult.lat |
| | | ); |
| | | this.searchResult.gpsLon = gpsLon; |
| | | this.searchResult.gpsLat = gpsLat; |
| | | } |
| | | }); |
| | | this.setMarker(ev.lnglat); |
| | | this.getAddress(ev.lnglat); |
| | | }); |
| | | }); |
| | | // inited = true; |
| | |
| | | } |
| | | }); |
| | | }, |
| | | getAddress(lnglat) { |
| | | geocoder.getAddress(lnglat, (status, result) => { |
| | | if (status === 'complete' && result.info === 'OK') { |
| | | this.searchResult.address = |
| | | result.regeocode.formattedAddress; |
| | | this.searchResult.lon = lnglat.getLng(); |
| | | this.searchResult.lat = lnglat.getLat(); |
| | | const [gpsLon, gpsLat] = baseMapUtil.gcj02towgs84( |
| | | this.searchResult.lon, |
| | | this.searchResult.lat |
| | | ); |
| | | this.searchResult.gpsLon = gpsLon; |
| | | this.searchResult.gpsLat = gpsLat; |
| | | } |
| | | }); |
| | | }, |
| | | setMarker(lnglat) { |
| | | this.map.clearMap(); |
| | | const marker = new AMap.Marker({ |
| | | position: lnglat |
| | | }); |
| | | this.map.add(marker); |
| | | }, |
| | | submit() { |
| | | this.$emit('onSubmit', this.searchResult); |
| | | this.dialogShow = false; |
| | |
| | | border-radius: var(--el-border-radius-round); |
| | | box-shadow: var(--el-box-shadow); |
| | | } |
| | | |
| | | .dialog { |
| | | pointer-events: auto; |
| | | } |
| | | </style> |
| | |
| | | /** |
| | | * é«å¾·å°å¾åæ 转GPSåæ ç®æ³ |
| | | */ |
| | | gcj02towgs84(lng, lat) { |
| | | gcj02towgs84(_lng, _lat) { |
| | | // lat = +latlng = +lng |
| | | const lng = parseFloat(_lng) |
| | | const lat = parseFloat(_lat) |
| | | if (out_of_china(lng, lat)) { |
| | | return [lng, lat]; |
| | | } else { |
| | |
| | | * @param lat |
| | | * @returns {*[]} |
| | | */ |
| | | wgs84togcj02(lng, lat) { |
| | | wgs84togcj02(_lng, _lat) { |
| | | // lat = +latlng = +lng |
| | | const lng = parseFloat(_lng) |
| | | const lat = parseFloat(_lat) |
| | | if (out_of_china(lng, lat)) { |
| | | return [lng, lat]; |
| | | } else { |
| | |
| | | import { $clue } from '@/api/index'; |
| | | |
| | | function getClueQuestion(data) { |
| | | data.cqFilePath = data.cqFilePath.split(';').map((val) => { |
| | | data.files = data.cqFilePath.split(';').map((val) => { |
| | | return $clue.imgUrl + val; |
| | | }); |
| | | return data; |
| | |
| | | <!-- <router-view> --> |
| | | <ClueLayout v-show="menuIndex == 0"></ClueLayout> |
| | | <GridLayout v-show="menuIndex == 1"></GridLayout> |
| | | <InternalClueLayout v-show="menuIndex == 2"></InternalClueLayout> |
| | | <!-- </router-view> --> |
| | | </div> |
| | | </template> |
| | |
| | | |
| | | import GridLayout from '@/views/overlay-grid/GridLayout.vue'; |
| | | import ClueLayout from '@/views/overlay-clue/ClueLayout.vue'; |
| | | import InternalClueLayout from '@/views/internal-clue/InternalClueLayout.vue'; |
| | | |
| | | // é¤åç´¢å¼ |
| | | const menuIndex = ref(0); |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog |
| | | style="pointer-events: auto" |
| | | :model-value="modelValue" |
| | | @update:modelValue="handleDialogChange" |
| | | width="50%" |
| | | :close-on-click-modal="false" |
| | | :close-on-press-escape="false" |
| | | destroy-on-close |
| | | > |
| | | <template #header> |
| | | <span> {{ create ? 'åå¸å
é¨çº¿ç´¢' : 'æ´æ°å
é¨çº¿ç´¢' }}</span> |
| | | </template> |
| | | <el-form |
| | | label-width="120px" |
| | | label-position="right" |
| | | :rules="rules" |
| | | :model="formObj" |
| | | ref="formRef" |
| | | > |
| | | <el-form-item label="线索åç§°" prop="cclueName"> |
| | | <el-input |
| | | v-model="formObj.cclueName" |
| | | placeholder="请è¾å
¥çº¿ç´¢åç§°" |
| | | class="w-200" |
| | | ></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="线索æè¿°" prop="cconclusion"> |
| | | <el-input |
| | | v-model="formObj.cconclusion" |
| | | type="textarea" |
| | | placeholder="请è¾å
¥çº¿ç´¢æè¿°" |
| | | ></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="详ç»å°å" prop="caddress"> |
| | | <el-input |
| | | v-model="formObj.caddress" |
| | | placeholder="请è¾å
¥å°åæè
éè¿âåæ æ¾åâèªå¨è·å¾" |
| | | ></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="åæ " prop="coordinate"> |
| | | <el-input |
| | | style="width: 300px; margin-right: 8px" |
| | | v-model="formObj.coordinate" |
| | | placeholder="ç»çº¬åº¦åæ ï¼æ ¼å¼ä¸º121.123452,31.231235" |
| | | ></el-input> |
| | | <el-button plain type="primary" @click="openMapDialog" |
| | | >åæ æ¾å</el-button |
| | | > |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="onCancel">åæ¶</el-button> |
| | | <el-button |
| | | :disabled="!edit" |
| | | type="primary" |
| | | :loading="loading" |
| | | @click="onSubmit" |
| | | >ç¡®å®</el-button |
| | | > |
| | | </template> |
| | | </el-dialog> |
| | | <MapSearch |
| | | v-model:show="mapDialogShow" |
| | | @on-submit="selectAddress" |
| | | ></MapSearch> |
| | | </template> |
| | | <script setup> |
| | | import { ref, reactive, watch, onMounted } from 'vue'; |
| | | import { useFormConfirm } from '@/composables/formConfirm'; |
| | | import clueInternalApi from '@/api/clue/clueInternalApi'; |
| | | |
| | | import MapSearch from '@/components/map/MapSearch.vue'; |
| | | |
| | | const props = defineProps({ |
| | | modelValue: Boolean, |
| | | clueData: Object, |
| | | create: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // èªå®ä¹åå»ºæ¹æ³ |
| | | onCreate: Function, |
| | | // èªå®ä¹æ´æ°æ¹æ³ |
| | | onUpdate: Function |
| | | }); |
| | | |
| | | const emits = defineEmits(['update:modelValue', 'onSubmit']); |
| | | |
| | | function handleDialogChange(value) { |
| | | emits('update:modelValue', value); |
| | | } |
| | | |
| | | const { formObj, formRef, edit, onSubmit, onCancel, clear } = |
| | | useFormConfirm({ |
| | | submit: { |
| | | do: submit |
| | | }, |
| | | cancel: { |
| | | do: cancel |
| | | } |
| | | }); |
| | | const loading = ref(false); |
| | | // è¡¨åæ£æ¥è§å |
| | | const rules = reactive({ |
| | | cclueName: [ |
| | | { |
| | | required: true, |
| | | message: '线索åç§°ä¸è½ä¸ºç©º', |
| | | trigger: 'blur' |
| | | } |
| | | ], |
| | | caddress: [ |
| | | { |
| | | required: true, |
| | | message: '线索å°åä¸è½ä¸ºç©º', |
| | | trigger: 'blur' |
| | | } |
| | | ], |
| | | coordinate: [ |
| | | { |
| | | required: true, |
| | | message: '线索å®ä½ä¸è½ä¸ºç©º', |
| | | trigger: 'blur' |
| | | } |
| | | ], |
| | | }); |
| | | |
| | | // å¯¹è¯æ¡ç¡®è®¤æä½ |
| | | function submit() { |
| | | const param = getParams(); |
| | | return props.create |
| | | ? props.onCreate |
| | | ? props.onCreate(param) |
| | | : createClue(param) |
| | | : props.onUpdate |
| | | ? props.onUpdate(param) |
| | | : updateClue(param); |
| | | } |
| | | |
| | | // å¯¹è¯æ¡åæ¶æä½ |
| | | function cancel() { |
| | | emits('update:modelValue', false); |
| | | } |
| | | |
| | | // æ°å»ºå
é¨çº¿ç´¢ |
| | | function createClue(params) { |
| | | clueInternalApi |
| | | .createInternalClue(params) |
| | | .then(() => { |
| | | emits('update:modelValue', false); |
| | | emits('onSubmit'); |
| | | }) |
| | | .finally(() => { |
| | | loading.value = false; |
| | | }); |
| | | } |
| | | |
| | | // æ´æ°å
é¨çº¿ç´¢ |
| | | function updateClue(params) { |
| | | clueInternalApi |
| | | .updateInternalClue(params) |
| | | .then(() => { |
| | | emits('update:modelValue', false); |
| | | emits('onSubmit'); |
| | | }) |
| | | .finally(() => { |
| | | loading.value = false; |
| | | }); |
| | | } |
| | | |
| | | // è·åçº¿ç´¢å¯¹è±¡åæ° |
| | | function getParams() { |
| | | const coor = formObj.value.coordinate.split(','); |
| | | return { |
| | | cid: formObj.value.cid, |
| | | cclueName: formObj.value.cclueName, |
| | | cconclusion: formObj.value.cconclusion, |
| | | caddress: formObj.value.caddress, |
| | | clongitude: parseFloat(coor[0]), |
| | | clatitude: parseFloat(coor[1]) |
| | | }; |
| | | } |
| | | |
| | | // åå§å线索表å对象 |
| | | watch( |
| | | () => [props.modelValue, props.clueData], |
| | | (nV, oV) => { |
| | | const [m, d] = nV; |
| | | if (m) { |
| | | formObj.value = {}; |
| | | if (d) { |
| | | formObj.value = d; |
| | | formObj.value.coordinate = d.cLongitude + ',' + d.cLatitude; |
| | | } |
| | | } |
| | | } |
| | | ); |
| | | /*********************************************************** */ |
| | | const mapDialogShow = ref(false); |
| | | function openMapDialog() { |
| | | mapDialogShow.value = true; |
| | | } |
| | | function selectAddress(result) { |
| | | formObj.value.caddress = result.address; |
| | | formObj.value.coordinate = result.gpsLon + ',' + result.gpsLat; |
| | | } |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-row class="fy-overlay-container" justify="space-between"> |
| | | <el-col :span="6"> |
| | | <InternalClueManage |
| | | @itemSelected="selectClue" |
| | | ></InternalClueManage> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <ClueReport |
| | | v-model:show="show" |
| | | :clueData="selectedClue" |
| | | @pushed="(e) => (selectedClue.cuploaded = e)" |
| | | @onClueTaskChange="handleClueTaskChange" |
| | | ></ClueReport> |
| | | </el-col> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import InternalClueManage from '@/views/internal-clue/InternalClueManage.vue'; |
| | | import ClueReport from '@/views/overlay-clue/report/ClueReport.vue'; |
| | | import { ref, provide } from 'vue'; |
| | | |
| | | // 注å
¥åæ° |
| | | |
| | | // 表æå½åæä½çæ¯å
é¨çº¿ç´¢ |
| | | provide('isInternal', true); |
| | | |
| | | const selectedClue = ref(); |
| | | const show = ref(false); |
| | | |
| | | /** |
| | | * éæ©çº¿ç´¢äºä»¶ |
| | | */ |
| | | const selectClue = function (clue) { |
| | | show.value = true; |
| | | selectedClue.value = clue; |
| | | }; |
| | | |
| | | function handleClueTaskChange() { |
| | | selectedClue.value.taskCount = 1; |
| | | } |
| | | </script> |
| | | |
| | | <style scoped></style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="fy-card"> |
| | | <div class="fy-h1">å
é¨çº¿ç´¢æ¸
å</div> |
| | | <div class="fy-flex-row"> |
| | | <span>æ¶é´</span> |
| | | <el-date-picker |
| | | v-model="updateTime" |
| | | type="datetime" |
| | | placeholder="éæ©æ¥æåæ¶é´" |
| | | /> |
| | | <el-button type="primary" @click="getClues">æ¥è¯¢</el-button> |
| | | <el-button type="success" @click="clueDialog = true" |
| | | >æ°å»º</el-button |
| | | > |
| | | </div> |
| | | <el-scrollbar height="70vh" class="p-h-1"> |
| | | <ClueList :dataList="clueList" @itemSelected="selectClue"> |
| | | </ClueList> |
| | | </el-scrollbar> |
| | | <el-row justify="space-between" class="p-8"> |
| | | <el-pagination |
| | | size="small" |
| | | v-model:current-page="currentPage" |
| | | v-model:page-size="pageSize" |
| | | :page-sizes="[10, 20, 50, 100]" |
| | | :background="true" |
| | | layout="total, sizes, pager" |
| | | :total="total" |
| | | /> |
| | | </el-row> |
| | | </div> |
| | | <InternalClueEdit |
| | | v-model="clueDialog" |
| | | :create="true" |
| | | :onCreate="createInternalClue" |
| | | ></InternalClueEdit> |
| | | <ClueTaskEdit |
| | | v-model="clueTaskDialog" |
| | | :create="true" |
| | | :onCreate="createInternalTask" |
| | | ></ClueTaskEdit> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted, reactive } from 'vue'; |
| | | import moment from 'moment'; |
| | | |
| | | import clueInternalApi from '@/api/clue/clueInternalApi'; |
| | | import clueTaskApi from '@/api/clue/clueTaskApi'; |
| | | import { onMapMounted } from '@/components/map/baseMap'; |
| | | |
| | | import ClueList from '@/views/overlay-clue/list/components/ClueList.vue'; |
| | | import ClueTaskEdit from '@/views/overlay-clue/task/ClueTaskEdit.vue'; |
| | | import InternalClueEdit from '@/views/internal-clue/InternalClueEdit.vue'; |
| | | |
| | | const emits = defineEmits('itemSelected'); |
| | | |
| | | // ä¸åæ¶é´ï¼æ¯æ¬¡æ¥è¯¢å¤§äºæ¤æ¶é´çæ°æ®ï¼ |
| | | const updateTime = ref(); |
| | | // 线索æ¸
å |
| | | const clueList = ref([]); |
| | | const currentPage = ref(1); |
| | | const pageSize = ref(100); |
| | | const total = ref(0); |
| | | |
| | | /** |
| | | * æ¥è¯¢å·²ä¸åç线索æ¸
å |
| | | */ |
| | | const getClues = function () { |
| | | let sTime; |
| | | let eTime; |
| | | if (updateTime.value) { |
| | | const now = moment(updateTime.value); |
| | | sTime = now.format('YYYY-MM-DD HH:mm:ss'); |
| | | eTime = now.add(1, 'month').format('YYYY-MM-DD HH:mm:ss'); |
| | | } |
| | | onMapMounted(() => { |
| | | clueInternalApi |
| | | .getInternalClue({ |
| | | sTime, |
| | | eTime, |
| | | pageNum: currentPage.value, |
| | | pageSize: pageSize.value |
| | | }) |
| | | .then((res) => { |
| | | total.value = res.head.totalCount; |
| | | clueList.value = res.data; |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * éæ©çº¿ç´¢äºä»¶ |
| | | */ |
| | | const selectClue = function (clue) { |
| | | emits('itemSelected', clue); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getClues(); |
| | | }); |
| | | |
| | | /************************************************************** */ |
| | | const clueData = ref(); |
| | | const clueDialog = ref(false); |
| | | const clueTaskDialog = ref(false); |
| | | |
| | | function createInternalClue(clue) { |
| | | clueData.value = clue; |
| | | clueDialog.value = false; |
| | | clueTaskDialog.value = true; |
| | | } |
| | | function createInternalTask(clueTask) { |
| | | clueTaskApi |
| | | .createClueTaskInternal({ |
| | | clueTask: clueTask, |
| | | clueInternal: clueData.value |
| | | }) |
| | | .then((res) => { |
| | | if (res.success) { |
| | | clueTaskDialog.value = false; |
| | | getClues(); |
| | | } |
| | | }); |
| | | } |
| | | </script> |
| | | <style scoped></style> |
| | |
| | | <!-- æ¸
å详æ
--> |
| | | <CloseButton v-show="show" @close="closeEdit"> |
| | | <el-button |
| | | v-if="!isInternal" |
| | | class="push-btn" |
| | | :type="clueData.cuploaded ? 'success' : 'danger'" |
| | | @click="pushCheck" |
| | |
| | | import clueTaskApi from '@/api/clue/clueTaskApi'; |
| | | |
| | | export default { |
| | | inject: { |
| | | // æ¯å¦æ¯å
é¨çº¿ç´¢ç¸å
³æä½ |
| | | isInternal: { |
| | | default: false |
| | | } |
| | | }, |
| | | components: { |
| | | ClueReportClue, |
| | | ClueReportConclusion, |
| | |
| | | |
| | | getClueTask() { |
| | | clueTaskApi |
| | | .fetchClueTask({ clueId: this.clueData.cid }) |
| | | .fetchClueTask({ |
| | | clueId: this.clueData.cid, |
| | | internalTask: this.isInternal |
| | | }) |
| | | .then((res) => { |
| | | this.isCreateMode = res.data.length == 0; |
| | | if (res.data.length > 0) { |
| | |
| | | <!-- æ¸
å详æ
--> |
| | | <DescriptionsList title="线索æ¸
å详æ
"> |
| | | <template #extra> |
| | | <el-button type="primary" text size="small" @click="openPDF" |
| | | <el-button |
| | | v-if="!isInternal" |
| | | type="primary" |
| | | text |
| | | size="small" |
| | | @click="openPDF" |
| | | >æ¥çPDF</el-button |
| | | > |
| | | </template> |
| | |
| | | label="线索åç§°" |
| | | :content="clue.cclueName" |
| | | /> |
| | | <DescriptionsListItem label="å建æ¶é´" :content="$tf(clue.ccreateTime)" /> |
| | | <DescriptionsListItem label="ä¸åæ¶é´" :content="$tf(clue.creleaseTime)" /> |
| | | <DescriptionsListItem |
| | | label="å建æ¶é´" |
| | | :content="$tf(clue.ccreateTime)" |
| | | /> |
| | | <DescriptionsListItem |
| | | label="ä¸åæ¶é´" |
| | | :content="$tf(clue.creleaseTime)" |
| | | /> |
| | | <DescriptionsListItem |
| | | label="æ¥è¦ç«ç¹" |
| | | :content="clue.csiteName" |
| | |
| | | import clueApi from '@/api/clue/clueApi'; |
| | | |
| | | export default { |
| | | inject: { |
| | | // æ¯å¦æ¯å
é¨çº¿ç´¢ç¸å
³æä½ |
| | | isInternal: { |
| | | default: false |
| | | } |
| | | }, |
| | | props: { |
| | | clue: Object |
| | | }, |
| | |
| | | '_blank' |
| | | ); |
| | | } |
| | | }, |
| | | } |
| | | }; |
| | | </script> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { reactive, ref, watch, computed } from 'vue'; |
| | | import { reactive, ref, watch, computed, inject } from 'vue'; |
| | | import { useCloned } from '@vueuse/core'; |
| | | import { useFormConfirm } from '@/composables/formConfirm'; |
| | | import clueConclusionApi from '@/api/clue/clueConclusionApi'; |
| | | |
| | | // å³å®å½åæ¯å¦æ¯å
é¨çº¿ç´¢ç¸å
³æä½ |
| | | const isInternal = inject('isInternal', false); |
| | | |
| | | const props = defineProps({ |
| | | clueId: Number |
| | |
| | | |
| | | function submit() { |
| | | formObj.value.cid = props.clueId; |
| | | formObj.value.ccInternal = isInternal; |
| | | return uploadConclusion(); |
| | | } |
| | | function cancel() { |
| | |
| | | * è·å线索ç»è®º |
| | | */ |
| | | function getConclusion() { |
| | | clueConclusionApi.getConclusion(props.clueId).then((res) => { |
| | | conclusion.value = res; |
| | | formObj.value = res == null ? {} : res; |
| | | // formObj.value = useCloned(res, { manual: true }); |
| | | }); |
| | | clueConclusionApi |
| | | .getConclusion(props.clueId, isInternal) |
| | | .then((res) => { |
| | | conclusion.value = res; |
| | | formObj.value = res == null ? {} : res; |
| | | // formObj.value = useCloned(res, { manual: true }); |
| | | }); |
| | | } |
| | | </script> |
| | | <style scoped></style> |
| | |
| | | <template #extra> |
| | | <div> |
| | | <el-button |
| | | v-if="!clueData.cuploaded" |
| | | type="danger" |
| | | size="small" |
| | | icon="Delete" |
| | | :disabled="clueData.cuploaded" |
| | | @click="deleteQuestion(item)" |
| | | ></el-button> |
| | | <el-button |
| | |
| | | </div> |
| | | <QuestionDetail |
| | | :clueData="clueData" |
| | | :uploaded="clueData.cuploaded" |
| | | v-model:show="dialogShow" |
| | | :question="selectedQuestion" |
| | | @on-submit="getQuestion" |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, watch, computed } from 'vue'; |
| | | import { ref, watch, computed, inject } from 'vue'; |
| | | import clueQuestionApi from '@/api/clue/clueQuestionApi'; |
| | | import QuestionDetail from './QuestionDetail.vue'; |
| | | import { |
| | | useMessageBoxTip, |
| | | useMessageBox |
| | | } from '@/composables/messageBox'; |
| | | |
| | | // å³å®å½åæ¯å¦æ¯å
é¨çº¿ç´¢ç¸å
³æä½ |
| | | const isInternal = inject('isInternal', false); |
| | | |
| | | const props = defineProps({ |
| | | // clueId: Number, |
| | |
| | | * è·å线索ç»è®º |
| | | */ |
| | | function getQuestion() { |
| | | clueQuestionApi.getQuestion(props.clueData.cid).then((res) => { |
| | | questionList.value = res; |
| | | }); |
| | | clueQuestionApi |
| | | .getQuestion(props.clueData.cid, isInternal) |
| | | .then((res) => { |
| | | questionList.value = res; |
| | | }); |
| | | } |
| | | |
| | | function pushQuestion(item) { |
| | |
| | | destroy-on-close |
| | | > |
| | | <template #header> |
| | | <span> æ·»å é®é¢</span> |
| | | <span> |
| | | {{ |
| | | uploaded ? 'é®é¢è¯¦æ
' : createMode ? 'æ·»å é®é¢' : 'ä¿®æ¹é®é¢' |
| | | }}</span |
| | | > |
| | | </template> |
| | | <el-form |
| | | label-width="90px" |
| | |
| | | > |
| | | <el-form-item label="é®é¢åç§°" prop="cqName"> |
| | | <el-input |
| | | :disabled="uploaded" |
| | | v-model="formObj.cqName" |
| | | placeholder="请è¾å
¥é®é¢åç§°" |
| | | ></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="é®é¢æè¿°" prop="cqDescription"> |
| | | <el-input |
| | | :disabled="uploaded" |
| | | v-model="formObj.cqDescription" |
| | | type="textarea" |
| | | placeholder="请è¾å
¥é®é¢æè¿°" |
| | | ></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="æå¨è¡é" prop="cqStreet"> |
| | | <el-select v-model="formObj.cqStreet" placeholder="æå¨è¡é"> |
| | | <el-select |
| | | v-model="formObj.cqStreet" |
| | | placeholder="æå¨è¡é" |
| | | :disabled="uploaded" |
| | | > |
| | | <el-option |
| | | v-for="s in streets" |
| | | :key="s.value" |
| | |
| | | </el-form-item> |
| | | <el-form-item label="详ç»å°å" prop="cqAddress"> |
| | | <el-input |
| | | :disabled="uploaded" |
| | | v-model="formObj.cqAddress" |
| | | placeholder="请è¾å
¥å°åæè
éè¿âåæ æ¾åâèªå¨è·å¾" |
| | | ></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="åæ " prop="coordinate"> |
| | | <el-input |
| | | :disabled="uploaded" |
| | | style="width: 300px; margin-right: 8px" |
| | | v-model="formObj.coordinate" |
| | | placeholder="ç»çº¬åº¦åæ ï¼æ ¼å¼ä¸º121.123452,31.231235" |
| | | ></el-input> |
| | | <el-button plain type="primary" @click="openMapDialog" |
| | | <el-button |
| | | :disabled="uploaded" |
| | | plain |
| | | type="primary" |
| | | @click="openMapDialog" |
| | | >åæ æ¾å</el-button |
| | | > |
| | | </el-form-item> |
| | | <el-form-item label="é®é¢å¾ç" prop="files"> |
| | | <el-upload |
| | | :class="uploadableClz" |
| | | ref="uploadRef" |
| | | :file-list="fileList" |
| | | action="" |
| | |
| | | list-type="picture-card" |
| | | name="images" |
| | | accept="image/png, image/jpeg" |
| | | :limit="3" |
| | | :limit="maxImageCount" |
| | | multiple |
| | | :on-preview="handleFilePreview" |
| | | :on-remove="handleFileRemove" |
| | | :on-change="handleFileChange" |
| | | > |
| | | <el-icon><Plus /></el-icon> |
| | | <template #file="{ file }"> |
| | | <div> |
| | | <img |
| | | class="el-upload-list__item-thumbnail" |
| | | :src="file.url" |
| | | alt="" |
| | | /> |
| | | <span class="el-upload-list__item-actions"> |
| | | <span |
| | | class="el-upload-list__item-preview" |
| | | @click="handleFilePreview(file)" |
| | | > |
| | | <el-icon><zoom-in /></el-icon> |
| | | </span> |
| | | <!-- <span |
| | | v-if="!disabled" |
| | | class="el-upload-list__item-delete" |
| | | @click="handleDownload(file)" |
| | | > |
| | | <el-icon><Download /></el-icon> |
| | | </span> --> |
| | | <span |
| | | v-if="!uploaded" |
| | | class="el-upload-list__item-delete" |
| | | @click="handleFileRemove(file)" |
| | | > |
| | | <el-icon><Delete /></el-icon> |
| | | </span> |
| | | </span> |
| | | </div> |
| | | </template> |
| | | <template #tip> |
| | | <div class="el-upload__tip"> |
| | | è¯·éæ©å°äº500kbçjpg/pngå¾çï¼æå¤3å¼ |
| | | {{ |
| | | `è¯·éæ©å°äº500kbçjpg/pngå¾çï¼æå¤${maxImageCount}å¼ ` |
| | | }} |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | |
| | | ></el-image-viewer> |
| | | <MapSearch |
| | | v-model:show="mapDialogShow" |
| | | :defaultCoor=" |
| | | formObj.coordinate |
| | | ? formObj.coordinate.split(',') |
| | | : undefined |
| | | " |
| | | @on-submit="selectAddress" |
| | | ></MapSearch> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { reactive, ref, watch, computed } from 'vue'; |
| | | import { reactive, ref, watch, computed, inject } from 'vue'; |
| | | import { ElMessage } from 'element-plus'; |
| | | import { useFormConfirm } from '@/composables/formConfirm'; |
| | | import { streets } from '@/constant/street'; |
| | | import clueQuestionApi from '@/api/clue/clueQuestionApi'; |
| | | import { $clue } from '@/api/index'; |
| | | import MapSearch from '@/components/map/MapSearch.vue'; |
| | | |
| | | // å³å®å½åæ¯å¦æ¯å
é¨çº¿ç´¢ç¸å
³æä½ |
| | | const isInternal = inject('isInternal', false); |
| | | |
| | | const props = defineProps({ |
| | | clueId: Number, |
| | | // åºæ¥çº¿ç´¢å¯¹è±¡ |
| | | clueData: { |
| | | type: Object, |
| | | default: () => { |
| | | return {}; |
| | | } |
| | | }, |
| | | // å¯¹è¯æ¡æ¾ç¤ºæ§å¶ |
| | | show: Boolean, |
| | | // 线索é®é¢å¯¹è±¡ |
| | | question: Object, |
| | | create: { |
| | | // é®é¢æ¯å¦å·²ä¸ä¼ |
| | | uploaded: { |
| | | type: Boolean, |
| | | default: true |
| | | default: false |
| | | }, |
| | | maxImageCount: { |
| | | type: Number, |
| | | default: 3 |
| | | } |
| | | }); |
| | | |
| | | const emit = defineEmits(['update:show', 'onSubmit', 'onClose']); |
| | | |
| | | // åå»ºææ¯ä¿®æ¹æ¨¡å¼ |
| | | const createMode = ref(true); |
| | | |
| | | // 䏿¥å¼¹åºæ¡ |
| | | const dialogShow = ref(false); |
| | | const mapDialogShow = ref(false); |
| | | const uploadRef = ref(); |
| | | const fileList = ref([]); |
| | | // æ´æ°æ¨¡å¼ä¸ï¼è®°å½è¢«å é¤çåæå¾ç |
| | | let deletedFileList = []; |
| | | // å³å®æ¯å¦è½ä¸ä¼ å¾ç |
| | | const uploadableClz = computed(() => { |
| | | return props.uploaded || |
| | | (fileList.value && fileList.value.length >= props.maxImageCount) |
| | | ? 'question-not-upload' |
| | | : ''; |
| | | }); |
| | | |
| | | const previewShow = ref(false); |
| | | const initialIndex = ref(0); |
| | | const urlList = computed(() => |
| | | fileList.value.map((value) => { |
| | | return value.url; |
| | | }) |
| | | fileList.value |
| | | ? fileList.value.map((value) => { |
| | | return value.url; |
| | | }) |
| | | : [] |
| | | ); |
| | | |
| | | function handleFilePreview(file) { |
| | |
| | | previewShow.value = false; |
| | | } |
| | | |
| | | function handleFileRemove(file, fileList) { |
| | | formObj.value.files = fileList; |
| | | function handleFileRemove(file, files) { |
| | | if (!createMode.value) { |
| | | if (file.url.indexOf($clue.imgUrl) != -1) { |
| | | const originUrl = file.url.replace($clue.imgUrl, ''); |
| | | deletedFileList.push(originUrl); |
| | | } |
| | | } |
| | | const index = fileList.value.indexOf(file); |
| | | fileList.value.splice(index, 1); |
| | | // fileList.value = fileList; |
| | | edit.value = true; |
| | | } |
| | | |
| | | function handleFileChange(file, fileList) { |
| | | formObj.value.files = fileList; |
| | | function handleFileChange(file, files) { |
| | | fileList.value = files; |
| | | edit.value = true; |
| | | } |
| | | |
| | | const { formObj, formRef, edit, onSubmit, onCancel, clear } = |
| | |
| | | }); |
| | | |
| | | function submit() { |
| | | if (!fileList.value || fileList.value.length == 0) { |
| | | ElMessage({ |
| | | message: 'è³å°ä¸ä¼ ä¸å¼ å¾ç', |
| | | type: 'error' |
| | | }); |
| | | return; |
| | | } |
| | | const coor = formObj.value.coordinate.split(','); |
| | | const q = { |
| | | cid: parseInt(props.clueData.cid), |
| | | cqName: formObj.value.cqName, |
| | | cqDescription: formObj.value.cqDescription, |
| | | cqStreet: formObj.value.cqStreet, |
| | | cqAddress: formObj.value.cqAddress, |
| | | ...formObj.value, |
| | | // cqId: formObj.value.cqId, |
| | | cId: parseInt(props.clueData.cid), |
| | | // cqName: formObj.value.cqName, |
| | | // cqDescription: formObj.value.cqDescription, |
| | | // cqStreet: formObj.value.cqStreet, |
| | | // cqAddress: formObj.value.cqAddress, |
| | | cqLongitude: parseFloat(coor[0]), |
| | | cqLatitude: parseFloat(coor[1]) |
| | | cqLatitude: parseFloat(coor[1]), |
| | | cqInternal: isInternal |
| | | // cqFilePath: formObj.value.cqFilePath |
| | | }; |
| | | const files = []; |
| | | if (formObj.value.files) { |
| | | formObj.value.files.forEach((f) => { |
| | | files.push(f.raw); |
| | | if (fileList.value) { |
| | | fileList.value.forEach((f) => { |
| | | if (f.url.indexOf($clue.imgUrl) == -1) { |
| | | files.push(f.raw); |
| | | } |
| | | }); |
| | | } |
| | | return props.create ? uploadQuestion(q, files) : updateQuestion(q, ); |
| | | return createMode.value |
| | | ? uploadQuestion(q, files) |
| | | : updateQuestion(q, files); |
| | | } |
| | | |
| | | function cancel() { |
| | |
| | | */ |
| | | function uploadQuestion(question, files) { |
| | | loading.value = true; |
| | | |
| | | return clueQuestionApi |
| | | .uploadQuestion(question, files) |
| | | .then(() => { |
| | | dialogShow.value = false; |
| | | clear(); |
| | | // clear(); |
| | | uploadRef.value.clearFiles(); |
| | | emit('onSubmit'); |
| | | }) |
| | |
| | | }); |
| | | } |
| | | |
| | | function updateQuestion(question, newFiles, deleteFiles) { |
| | | |
| | | function updateQuestion(question, newFiles) { |
| | | loading.value = true; |
| | | const deleteImgUrl = deletedFileList.join(';'); |
| | | return clueQuestionApi |
| | | .updateQuestion(question, newFiles, deleteImgUrl) |
| | | .then(() => { |
| | | dialogShow.value = false; |
| | | // clear(); |
| | | uploadRef.value.clearFiles(); |
| | | emit('onSubmit'); |
| | | }) |
| | | .finally(() => { |
| | | loading.value = false; |
| | | }); |
| | | } |
| | | |
| | | function parseFormObj(question) { |
| | | question.coordinate = |
| | | question.cqLongitude + ',' + question.cqLatitude; |
| | | fileList.value = []; |
| | | question.cqFilePath.forEach((f, index) => { |
| | | fileList.value.push({ |
| | | fileList.value = question.files.map((f, index) => { |
| | | return { |
| | | name: `${index}`, |
| | | url: f |
| | | }); |
| | | }; |
| | | }); |
| | | return { ...question }; |
| | | } |
| | |
| | | dialogShow.value = val[0]; |
| | | if (val[0]) { |
| | | fileList.value = []; |
| | | deletedFileList = []; |
| | | if (val[1]) { |
| | | createMode.value = false; |
| | | formObj.value = parseFormObj(val[1]); |
| | | } else { |
| | | createMode.value = true; |
| | | formObj.value = {}; |
| | | } |
| | | // edit.value = false |
| | | } |
| | | } |
| | | ); |
| | | |
| | | watch(dialogShow, (val) => { |
| | | if (!val) { |
| | | clear(); |
| | | } |
| | | emit('update:show', val); |
| | | }); |
| | | </script> |
| | | <style scoped> |
| | | :deep(.question-not-upload .el-upload-list > .el-upload) { |
| | | display: none; |
| | | } |
| | | </style> |
| | |
| | | |
| | | const props = defineProps({ |
| | | modelValue: Boolean, |
| | | clueData: { |
| | | type: Object, |
| | | default: () => { |
| | | return {}; |
| | | } |
| | | }, |
| | | clueData: Object, |
| | | clueTask: Object, |
| | | create: { |
| | | type: Boolean, |
| | | default: true |
| | | } |
| | | }, |
| | | // èªå®ä¹åå»ºæ¹æ³ |
| | | onCreate: Function, |
| | | // èªå®ä¹æ´æ°æ¹æ³ |
| | | onUpdate: Function |
| | | }); |
| | | |
| | | const emits = defineEmits(['update:modelValue', 'onSubmit']); |
| | |
| | | const loading = ref(false); |
| | | // è¡¨åæ£æ¥è§å |
| | | const rules = reactive({ |
| | | clueId: [ |
| | | { |
| | | required: true, |
| | | message: '线索ç¼å·ä¸è½ä¸ºç©º', |
| | | trigger: 'blur' |
| | | } |
| | | ], |
| | | // clueId: [ |
| | | // { |
| | | // required: true, |
| | | // message: '线索ç¼å·ä¸è½ä¸ºç©º', |
| | | // trigger: 'blur' |
| | | // } |
| | | // ], |
| | | taskTime: [ |
| | | { |
| | | required: true, |
| | |
| | | |
| | | function submit() { |
| | | const param = getParams(); |
| | | return props.create ? createClueTask(param) : updateClueTask(param); |
| | | return props.create |
| | | ? props.onCreate |
| | | ? props.onCreate(param) |
| | | : createClueTask(param) |
| | | : props.onUpdate |
| | | ? props.onUpdate(param) |
| | | : updateClueTask(param); |
| | | } |
| | | |
| | | function cancel() { |