public/工地巡查单据模板.docx | 补丁 | 查看 | 原始文档 | blame | 历史 | |
public/餐饮巡查单据模板.doc | 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components.d.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/FYImageSelectDialog.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/utils/doc.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/fysp/check/ProCheckProxy.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/fysp/check/components/ArbitraryPhoto.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/fysp/check/components/CompSubTaskStatistic.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/fysp/scene/SceneInspectFile.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/fysp/task/TaskManage.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/fysp/task/components/CompMonitorObjEdit.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/fysp/task/components/CompSubTaskList.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
public/¹¤µØÑ²²éµ¥¾ÝÄ£°å.docxBinary files differ
public/²ÍÒûѲ²éµ¥¾ÝÄ£°å.docBinary files differ
src/components.d.ts
@@ -25,6 +25,7 @@ ElCard: typeof import('element-plus/es')['ElCard'] ElCascader: typeof import('element-plus/es')['ElCascader'] ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup'] ElCol: typeof import('element-plus/es')['ElCol'] ElCollapse: typeof import('element-plus/es')['ElCollapse'] ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem'] src/components/FYImageSelectDialog.vue
@@ -56,6 +56,7 @@ :preview-src-list=" readonly ? typeImgMap.get(activeId).map((v) => v.url) : [] " crossOrigin="Anonymous" :initial-index="i" @contextmenu="(e) => showContextMenu(e, i)" @click="onSelect(img, i)" src/utils/doc.js
@@ -81,10 +81,20 @@ let width = image.width; let height = image.height; if (width > height && horizontalHeight && height > horizontalHeight && scale) { if ( width > height && horizontalHeight && height > horizontalHeight && scale ) { height = horizontalHeight; width = horizontalHeight * scale; } else if (width <= height && verticalWidth && width > verticalWidth && scale) { } else if ( width <= height && verticalWidth && width > verticalWidth && scale ) { width = verticalWidth; height = verticalWidth * scale; } @@ -144,12 +154,15 @@ throw error; } const zip = new Pizzip(content); const imageOptions = getImageOptions(imageSize); let doc = new docxtemplater() .setOptions({ paragraphLoop: true }) .loadZip(zip) .attachModule(new ImageModule(imageOptions)) .compile(); .loadZip(zip); if (imageSize) { const imageOptions = getImageOptions(imageSize); doc.attachModule(new ImageModule(imageOptions)); } doc.compile(); doc.resolveData(data).then(() => { try { doc.render(); src/views/fysp/check/ProCheckProxy.js
@@ -29,7 +29,7 @@ //æªéè¿æ°é unpassNum: 0, //æ´æ¹ç changePer: '0%', changePer: '--', //éè¿ç passPer: '0%', //å®¡æ ¸ç @@ -49,10 +49,10 @@ status.uncheckNum++; else status.passNum++; if (p.extension3 == proStatus.pass) { if (p.extension3 != proStatus.unCheck) { status.proCheckedNum++; } if (p.extension3 == proStatus.change_pass) { if (p.extension3 == proStatus.change_pass || p.extension3 == proStatus.change_fail) { status.changeCheckedNum++; } @@ -234,18 +234,18 @@ else if (s.proCheckedNum < s.proNum) { type = 2; } // æªæ´æ¹ else if (s.changeNum < s.proNum) { type = 3; } // æ´æ¹æªå®¡æ ¸ else if (s.changeCheckedNum == 0) { else if (s.changeNum > 0 && s.changeCheckedNum == 0) { type = 4; } // æ´æ¹é¨åå®¡æ ¸ else if (s.changeCheckedNum < s.changeNum) { else if (s.changeNum > 0 && s.changeCheckedNum < s.changeNum) { type = 5; } // æªæ´æ¹ else if (s.changeNum < s.proNum) { type = 3; } // å®å ¨å®¡æ ¸ else { type = 6; src/views/fysp/check/components/ArbitraryPhoto.vue
@@ -74,6 +74,7 @@ // ], closeContextMenuListenr: undefined, // å³é®éä¸çå¾ç selectedFileElement: undefined, selectedFile: undefined, selectedIndex: undefined, selectedTypeId: undefined @@ -94,7 +95,7 @@ }; }); return [ // { label: 'å¤å¶å¾ç', action: 'copy' }, // { label: 'å¤å¶å°åªè´´æ¿', action: 'copy' }, { label: 'ç§»å¨å°', children: items } ]; } @@ -158,6 +159,7 @@ left: `${event.clientX}px`, top: `${event.clientY}px` }; this.selectedFileElement = event.target; this.selectedTypeId = typeId; this.selectedIndex = index; this.selectedFile = this.typesMap.get(typeId)[index]; @@ -168,6 +170,7 @@ handleMenuItem(item) { switch (item.action) { case 'copy': this.drawImageToCanvas(); break; case 'move': this.selectedFile.data.businesstypeid = item.value; @@ -217,6 +220,37 @@ // } // this.selectedFile.loading = false; // }, 2000); }, drawImageToCanvas() { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); const img = this.selectedFileElement; // è·åDOMå¼ç¨ // img.crossOrigin = 'Anonymous'; canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; ctx.drawImage(img, 0, 0, canvas.width, canvas.height); // this.copyCanvasToClipboard(canvas); const dataUrl = canvas.toDataURL('image/png'); // å¯ä»¥éæ©å ¶ä»æ ¼å¼å¦'image/jpeg' // å建ä¸ä¸ªä¸´æ¶çtextareaå ç´ æ¥å¤å¶ææ¬ const tempTextArea = document.createElement('textarea'); document.body.appendChild(tempTextArea); tempTextArea.value = dataUrl; tempTextArea.select(); document.execCommand('copy'); document.body.removeChild(tempTextArea); }, copyCanvasToClipboard(canvas) { canvas.toBlob((blob) => { const item = new ClipboardItem({ 'image/png': blob }); // ä½ å¯ä»¥æ ¹æ®éè¦æ¹åæ ¼å¼ï¼å¦ "image/jpeg" navigator.clipboard.write([item]).then( () => { console.log('Image copied to clipboard'); }, (err) => { console.error('Could not copy image: ', err); } ); }, 'image/png'); // åæ ·ï¼è¿éä¹å¯ä»¥æå®å ¶ä»æ ¼å¼ï¼å¦ 'image/jpeg' } } }; src/views/fysp/check/components/CompSubTaskStatistic.vue
@@ -269,17 +269,39 @@ completedTimes: 0, reviewTimes: 0 }; this.monitorObjList.forEach((m) => { if (this.sceneType == undefined || m.sceneTypeId == this.sceneType) { _res.total++; const times = parseInt(m.extension1); if (times) { _res.completedScenes++; _res.completedTimes += times; _res.reviewTimes += times - 1; } // Fixme 2025.5.30: ç®åæ¤å¤ççç®¡çæ¬ä¿¡æ¯éè®°å½çä»»å¡å®ææ¬¡æ°æåå·®ï¼æä»¥ææ¶å æ¹ä¸ºéè¿å·¡æ¥ä»»å¡æ¬èº«è¿è¡ç»è®¡ /**************************************************************************************/ // this.monitorObjList.forEach((m) => { // if (this.sceneType == undefined || m.sceneTypeId == this.sceneType) { // _res.total++; // const times = parseInt(m.extension1); // if (times) { // _res.completedScenes++; // _res.completedTimes += times; // _res.reviewTimes += times - 1; // } // } // }); /**************************************************************************************/ /**************************************************************************************/ _res.total = this.monitorObjList.filter( (m) => this.sceneType == undefined || m.sceneTypeId == this.sceneType ).length; _res.completedTimes = this.subtasks.length; const map = new Map(); const uniqueArr = []; for (let item of this.subtasks) { if (!map.has(item.data.sceneId)) { map.set(item.data.sceneId, true); uniqueArr.push(item); } }); } _res.completedScenes = uniqueArr.length; _res.reviewTimes = _res.completedTimes - _res.completedScenes; /**************************************************************************************/ return _res; } }, src/views/fysp/scene/SceneInspectFile.vue
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,252 @@ <template> <el-dialog :model-value="modelValue" @update:model-value="handleDialogChange" title="å·¡æ¥åæ®ä¸è½½" class="dialog-wrapper" v-loading="loading" > <el-scrollbar ref="scrollbarRef" height="50vh" v-loading="loading" :always="true" > <el-checkbox-group v-model="checkList"> <el-space direction="vertical" alignment="flex-start" fill> <el-checkbox v-for="(item, index) in sceneInfoList" :key="item.scense.guid" :value="index" :class="(item.invalid ? 'checkbox-invalid' : '') + ' checkbox'" > <div> <el-text size="large">{{ item.scense.name }}</el-text> </div> <div class="m-t-4"> <el-text size="small">{{ 'å°åï¼' + item.scense.location }}</el-text> </div> <el-space class="m-t-4"> <el-tag> {{ item.scense.cityname + item.scense.districtname + item.scense.townname }} <!-- {{ item.scense.districtname }} {{ item.scense.townname }} --> </el-tag> <el-tag>{{ item.scense.type }}</el-tag> <!-- {{ item.scense.contacts }} {{ item.scense.contactst }} --> </el-space> </el-checkbox> </el-space> </el-checkbox-group> </el-scrollbar> <template #footer> <div class="dialog-footer"> <el-button type="danger" @click="cancel">åæ¶</el-button> <el-button type="primary" :loading="docLoading" @click="handelDownload"> ä¸è½½ </el-button> <el-button type="default" :loading="docLoading" @click="handelPrint"> æå° </el-button> </div> </template> </el-dialog> </template> <script setup> /** * åºæ¯å·¡æ¥åæ®èªå¨ä¸è½½ */ import { ref, watch } from 'vue'; import { exportDocx } from '@/utils/doc'; import sceneApi from '@/api/fysp/sceneApi'; const props = defineProps({ // å¯¹è¯æ¡å¼å ³ modelValue: Boolean, // åºæ¯åºç¡ä¿¡æ¯æ°ç» value: Array }); const emits = defineEmits(['update:modelValue']); const loading = ref(false); const scrollbarRef = ref(); const sceneInfoList = ref([]); const checkList = ref([]); const docLoading = ref(false); watch( () => [props.modelValue, props.value], (nV, oV) => { if (nV[0] && nV[1] && nV[1] != oV[1]) { fetchSceneInfo(nV[1]); } } ); function fetchSceneInfo(sceneIdList) { loading.value = true; sceneInfoList.value = []; checkList.value = []; sceneIdList.forEach((sid) => { sceneApi .getSceneDetail(sid) .then((res) => { sceneInfoList.value.push(res.data); checkList.value.push(sceneInfoList.value.length - 1); //åºæ¯ // if (res.data.scense) sceneInfoList.value = res.data.scense; // if (res.data.subScene) { // formSubScene.value = res.data.subScene; // } else { // formSubScene.value = { // sGuid: formScene.value.guid // }; // } }) .finally(() => { loading.value = false; scrollbarRef.value.setScrollTop(0); }); }); } function handleDialogChange(value) { emits('update:modelValue', value); } // æ ¼å¼ååºæ¯ä¿¡æ¯ï¼çæåæ°ç»æ function parseParam() { const selected = sceneInfoList.value.filter((v, i) => { return checkList.value.indexOf(i) != -1; }); const param = selected.map((v) => { switch (v.scense.typeid) { // å·¥å° case 1: return { type: v.scense.typeid, params: { district: v.scense.districtname, name: v.scense.name, employerUnit: v.scense.csEmployerUnit, constructionUnit: v.subScene.csConstructionUnit, timeRange: v.subScene.csStartTime ? `${v.subScene.csStartTime}è³${v.subScene.csEndTime}` : undefined, stage: v.subScene.siExtension1, contacts: v.subScene.csConstructionContacts, contactsTel: v.subScene.csConstructionContactsTel, location: v.scense.location } }; // é¤é¥® case 5: return { type: v.scense.typeid, params: { district: v.scense.districtname, location: v.scense.location, name: v.scense.name, contacts: v.scense.contacts, contactsTel: v.scense.contactst } }; // default: // v.invalid = true; // return undefined; } }); param.forEach((p) => { for (const key in p.params) { let value = p.params[key]; if (value == undefined) { // è¥å±æ§ç¼ºå¤±ï¼åæ¹ä¸º20ä¸ªç©ºæ ¼ç¬¦ï¼å¯¹åºwordä¸10ä¸ªä¸æå符çé¿åº¦ p.params[key] = ' '; } } }); return param; } // æ ¹æ®åºæ¯ç±»åï¼çæå¯¹åºçwordææ¡£ function generateDoc(param) { param.forEach((p) => { let template, _param; switch (p.type) { // å·¥å° case 1: template = '/å·¥å°å·¡æ¥åæ®æ¨¡æ¿.docx'; _param = p.params; break; // é¤é¥® case 5: break; default: break; } exportDocx(template, _param, `${_param.name}å·¡æ¥åæ®.docx`).finally( () => (docLoading.value = false) ); }); } // ä¸è½½wordææ¡£ function download(file) {} // æå°wordææ¡£ function print(file) {} function filePrepare() { const param = parseParam(); if (param) { return generateDoc(param); } } // ç¹å»ä¸è½½æé®æä½ function handelDownload() { const file = filePrepare(); if (file) { download(file); } } // ç¹å»æå°æé®æä½ function handelPrint() { const file = filePrepare(); if (file) { print(file); } } // åæ¶æä½ function cancel() { // å ³éå¯¹è¯æ¡ handleDialogChange(false); } </script> <style scoped> .checkbox { border: var(--el-border); padding: 8px; } .checkbox-invalid { border-color: var(--el-color-error); } :deep(.el-checkbox) { height: auto; } </style> src/views/fysp/task/TaskManage.vue
@@ -202,10 +202,16 @@ computed: { // æ»ä»»å¡ç¶æç»è®¡ taskStatus() { let total = 0, inspected = 0; this.curMonitorObjList.forEach((obj) => { total += parseInt(obj.monitornum); inspected += obj.extension1 ? parseInt(obj.extension1) : 0; }); return [ { name: 'åºæ¯æ°', value: 100 }, { name: 'æªå·¡æ¥', value: 0 }, { name: '已巡æ¥', value: 0 } { name: 'åºæ¯æ°', value: total }, { name: 'æªå·¡æ¥', value: total - inspected }, { name: '已巡æ¥', value: inspected } ]; } }, src/views/fysp/task/components/CompMonitorObjEdit.vue
@@ -274,7 +274,7 @@ }); }, deleteMov(item) { if (item.extension1) { if (!(item.extension1 == null || item.extension1 == undefined || item.extension1 == '0')) { ElMessage({ message: 'å·²çç®¡åºæ¯æ æ³ç§»é¤', type: 'error' src/views/fysp/task/components/CompSubTaskList.vue
@@ -1,13 +1,22 @@ <template> <el-row justify="space-between"> <el-text>åæ¥è®¡å</el-text> <el-button v-show="create && data && data.length > 0" type="success" size="small" @click="add" >ä»»å¡è°æ´</el-button > <div> <el-button type="success" size="small" plain @click="handleInspectFileDownload" >åæ®ä¸è½½</el-button > <el-button v-show="create && data && data.length > 0" type="success" size="small" @click="add" >ä»»å¡è°æ´</el-button > </div> </el-row> <el-divider /> <div> @@ -70,11 +79,13 @@ @cancel="dialogVisible = false" ></CompSubTaskEdit> </el-dialog> <SceneInspectFile v-model="downloadDialog" :value="downloadSceneList"></SceneInspectFile> </template> <script setup> import { ref, computed, watch, onMounted, onUnmounted } from 'vue'; import { ElMessageBox, ElNotification, ElMessage } from 'element-plus'; import CompSubTaskEdit from './CompSubTaskEdit.vue'; import SceneInspectFile from "@/views/fysp/scene/SceneInspectFile.vue"; import subtaskApi from '@/api/fysp/subtaskApi'; const props = defineProps({ @@ -86,12 +97,14 @@ // æ¯å¦æ¾ç¤ºæ·»å ä»»å¡æé® create: Boolean, loading: Boolean, createLoading:Boolean, createLoading: Boolean }); const dialogVisible = ref(false); const activeItem = ref(null); const data = computed(() => props.modelValue); const downloadDialog = ref(false); const downloadSceneList = ref([]) const emit = defineEmits(['submit', 'add', 'remove', 'update:modelValue']); @@ -102,7 +115,7 @@ cancelButtonText: 'åæ¶', type: 'warning' }).then(() => { return subtaskApi.deleteSubtask(item.stguid).then(res=>{ return subtaskApi.deleteSubtask(item.stguid).then((res) => { if (res == 1) { const index = data.value.indexOf(item); data.value.splice(index, 1); @@ -110,9 +123,9 @@ emit('update:modelValue', data.value); emit('remove', item); } else { Promise.reject('å é¤å·¡æ¥ä»»å¡å¤±è´¥') Promise.reject('å é¤å·¡æ¥ä»»å¡å¤±è´¥'); } }) }); }); } } @@ -139,4 +152,9 @@ onUnmounted(() => { dialogVisible.value = false; }); function handleInspectFileDownload() { downloadSceneList.value = data.value.map(v=>v.scenseid) downloadDialog.value = true } </script>