src/api/index.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components.d.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/router/index.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/utils/css-util.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/fysp/data-product/base-data-product/ProdManage.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/fysp/data-product/base-data-product/ProdSceneInfo.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/fysp/data-product/base-data-product/components/BaseProdProcess.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/fysp/data-product/base-data-product/components/ProdDownload.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/fysp/data-product/base-data-product/components/ProdQueryOpt.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/api/index.js
@@ -13,8 +13,8 @@ let ip2_file = 'https://fyami.com.cn/'; if (debug) { // ip1 = 'http://192.168.0.103:9001/'; ip1 = 'http://localhost:9001/'; ip1 = 'http://192.168.0.103:9001/'; // ip1 = 'http://localhost:9001/'; // ip1_file = 'http://192.168.0.138:8080/'; // ip2 = 'http://192.168.0.138:8080/'; // ip2_file = 'https://fyami.com.cn/'; src/components.d.ts
@@ -20,11 +20,8 @@ ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb'] ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem'] ElButton: typeof import('element-plus/es')['ElButton'] ElCalendar: typeof import('element-plus/es')['ElCalendar'] 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'] @@ -45,7 +42,6 @@ ElImageViewer: typeof import('element-plus/es')['ElImageViewer'] ElInput: typeof import('element-plus/es')['ElInput'] ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] ElLink: typeof import('element-plus/es')['ElLink'] ElMain: typeof import('element-plus/es')['ElMain'] ElMenu: typeof import('element-plus/es')['ElMenu'] ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] src/router/index.js
@@ -93,7 +93,7 @@ // åºç¡äº§å-åºæ¯æ¸ å path: 'scene', name: 'ProdSceneInfo', meta: { keepAlive: true, key: 'ProdManage' }, meta: { keepAlive: false, key: 'ProdManage' }, component: () => import( '@/views/fysp/data-product/base-data-product/ProdSceneInfo.vue' @@ -103,7 +103,7 @@ // åºç¡äº§å-è§èæ§è¯ä¼° path: 'evaluate', name: 'ProdEvaluationInfo', meta: { keepAlive: true, key: 'ProdManage' }, meta: { keepAlive: false, key: 'ProdManage' }, component: () => import( '@/views/fysp/data-product/base-data-product/ProdEvaluationInfo.vue' @@ -113,7 +113,7 @@ // åºç¡äº§å-å·¡æ¥ä¿¡æ¯ path: 'inspection', name: 'ProdInspectionInfo', meta: { keepAlive: true, key: 'ProdManage' }, meta: { keepAlive: false, key: 'ProdManage' }, component: () => import( '@/views/fysp/data-product/base-data-product/ProdInspectionInfo.vue' @@ -123,7 +123,7 @@ // åºç¡äº§å-çæµæ°æ® path: 'monitordata', name: 'ProdMonitorDataInfo', meta: { keepAlive: true, key: 'ProdManage' }, meta: { keepAlive: false, key: 'ProdManage' }, component: () => import( '@/views/fysp/data-product/base-data-product/ProdMonitorDataInfo.vue' src/utils/css-util.js
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,21 @@ /** * æåcssä¸å¸¦æcalc彿°ç表达å¼çåæ°é¨å * @param {String} str cssä¸å¸¦æcalc彿°çè¡¨è¾¾å¼ */ function unCalc(str) { if (str.startsWith('calc(')) { let _str = str.replace('calc(', '') _str = _str.replace(/\)/g, (match, offset, string) => { if (offset === string.lastIndexOf(match)) { return '' } else { return match } }) return _str } else { return str } } export { unCalc } src/views/fysp/data-product/base-data-product/ProdManage.vue
@@ -1,9 +1,11 @@ <template> <el-affix> <el-menu ref="menuRef" default-active="scene" ellipsis mode="horizontal" style="max-width: 600px" style="max-width: 600px; background-color: aliceblue" > <el-menu-item v-for="item in menu" @@ -13,7 +15,8 @@ >{{ item.name }}</el-menu-item > </el-menu> <router-view v-slot="{ Component, route }"> </el-affix> <router-view v-slot="{ Component, route }" :style="'height: ' + height"> <keep-alive> <component v-if="route.meta.keepAlive" @@ -25,11 +28,14 @@ </router-view> </template> <script setup> import { ref, onMounted } from 'vue'; import { ref, onMounted, provide } from 'vue'; import { useRouter, useRoute } from 'vue-router'; const router = useRouter(); const route = useRoute(); const menuRef = ref(null); const height = ref('calc(100vh - 64px)'); const menu = ref([ { @@ -58,5 +64,17 @@ }); } }; function calcTableHeight() { const h = menuRef.value.$el.offsetHeight; return `calc(100vh - ${h}px - 60px - var(--el-main-padding) * 2)`; } onMounted(() => { height.value = calcTableHeight(); }); // æä¾ç»å é¨ç»ä»¶è§å¾æå¤§é«åº¦ provide('viewHeight', height); </script> <style scoped></style> src/views/fysp/data-product/base-data-product/ProdSceneInfo.vue
@@ -1,31 +1,90 @@ <template> <BaseProdProcess :active="active"> <template #step1> <BaseProdProcess v-model:active="active" @onStep1="onStep1" :loading="loading" > <!-- <template #step1> <ProdQueryOpt :loading="loading" @submit="onSearch"> </ProdQueryOpt> </template> --> <template #step2="{ contentHeight }"> <el-table :data="tableData" v-loading="loading" :height="viewHeight" table-layout="fixed" :show-overflow-tooltip="true" size="small" border > <el-table-column fixed="left" prop="index" label="ç¼å·" width="40"> </el-table-column> <el-table-column fixed="left" prop="name" label="åç§°" :show-overflow-tooltip="true" min-width="200" > </el-table-column> <el-table-column prop="type" label="ç±»å" width="50" /> <el-table-column prop="status" label="ç¶æ" width="60" /> <el-table-column prop="stage" label="é¶æ®µ" width="90" /> <!-- <el-table-column prop="provincename" label="ç" width="90" /> <el-table-column prop="cityname" label="å¸" width="90" /> <el-table-column prop="districtname" label="åºå¿" width="90" /> --> <el-table-column prop="townname" label="è¡é" width="110" /> <el-table-column prop="location" label="å°å" width="200" /> <!-- <el-table-column prop="longitude" label="ç»åº¦" width="110" /> <el-table-column prop="latitude" label="纬度" width="110" /> --> <!-- <el-table-column prop="updatedate" label="æ´æ°æ¶é´" width="140" :formatter="timeFormat" /> --> </el-table> </template> <template #step2></template> <template #step3></template> <!-- <template #step3></template> --> </BaseProdProcess> </template> <script setup> import { ref } from 'vue'; import { ref, inject } from 'vue'; import dayjs from 'dayjs'; import BaseProdProcess from '@/views/fysp/data-product/base-data-product/components/BaseProdProcess.vue'; import ProdQueryOpt from '@/views/fysp/data-product/base-data-product/components/ProdQueryOpt.vue'; import dataprodbaseApi from '@/api/fysp/dataprodbaseApi.js'; const active = ref(1); const loading = ref(false) const loading = ref(false); const tableData = ref([]); const viewHeight = inject('viewHeight'); function changeActive() { active.value++; active.value = active.value > 3 ? 1 : active.value; } function onSearch(opt) { console.log(opt); function onStep1(opt) { loading.value = true; setTimeout(() => { changeActive() dataprodbaseApi .fetchProdSceneInfo(opt) .then((res) => { if (res.success) { tableData.value = res.data.map((item) => ({ status: item.status, stage: item.stage, ...item.scene })); } changeActive(); }) .finally(() => { loading.value = false; }, 1000); }); } function timeFormat(row, column, cellValue, index) { return dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss'); } </script> src/views/fysp/data-product/base-data-product/components/BaseProdProcess.vue
@@ -1,62 +1,310 @@ <template> <!-- <el-button type="primary" @click="changeActive">change</el-button> --> <!-- <el-row> <el-col :span="active == 1 ? 16 : 4" :class="active == 1 ? 'prod-active' : 'prod-inactive'" >step1</el-col> <el-col :span="active == 2 ? 16 : 4" :class="active == 2 ? 'prod-active' : 'prod-inactive'" >step2</el-col> <el-col :span="active == 3 ? 16 : 4" :class="active == 3 ? 'prod-active' : 'prod-inactive'" >step3</el-col> </el-row> --> <el-row> <div :class="active == 1 ? 'prod-active' : 'prod-inactive'"> <!-- æ¥éª¤1 æ°æ®äº§åçæé项 --> <div :class="active == 1 ? 'prod-active' : 'prod-inactive'" ref="step1Ref"> <transition name="el-fade-in" @after-leave="handleTransitionContentEnd(1)" > <div v-show="showStep1Content"> <template v-if="$slots.step1"> <slot name="step1"></slot> </template> <template v-else> <ProdQueryOpt :loading="loading" @submit="onSearch"> </ProdQueryOpt> </template> </div> <div :class="active == 2 ? 'prod-active' : 'prod-inactive'"> <slot name="step2"></slot> </transition> <transition name="el-fade-in" @after-leave="handleTransitionThumbnailEnd(1)" > <div v-show="showStep1Thumbnail" class="prod-thumbnail-wrapper" :style="{ height: viewHeight }" @click="changeActive(1)" > <div class="prod-thumbnail">â ä¿®æ¹é项</div> </div> <div :class="active == 3 ? 'prod-active' : 'prod-inactive'"> </transition> </div> <!-- æ¥éª¤2 æ°æ®äº§åç»æé¢è§ --> <div :class="active == 2 ? 'prod-active' : 'prod-inactive'" ref="step2Ref"> <transition name="el-fade-in" @after-leave="handleTransitionContentEnd(2)" > <div v-show="showStep2Content"> <div ref="titleRef" class="prod-title"> <el-text tag="b" size="large">æ°æ®äº§åé¢è§</el-text> </div> <slot name="step2" :contentHeight="contentHeight"></slot> </div> </transition> <transition name="el-fade-in" @after-leave="handleTransitionThumbnailEnd(2)" > <div v-show="showStep2Thumbnail" class="prod-thumbnail-wrapper" :style="{ height: viewHeight }" @click="changeActive(2)" > <div :class=" 'prod-thumbnail prod-thumbnail_middle ' + (active < 2 ? 'prod-thumbnail-disabled' : '') " > â¡æ°æ®äº§åé¢è§ </div> </div> </transition> </div> <!-- æ¥éª¤3 æ°æ®äº§å表åä¸è½½ --> <div :class="active == 3 ? 'prod-active' : 'prod-inactive'" ref="step3Ref"> <transition name="el-fade-in" @after-leave="handleTransitionContentEnd(3)" > <div v-show="showStep3Content"> <template v-if="$slots.step3"> <slot name="step3"></slot> </template> <template v-else> <ProdDownload></ProdDownload> </template> </div> </transition> <transition name="el-fade-in" @after-leave="handleTransitionThumbnailEnd(3)" > <div v-show="showStep3Thumbnail" class="prod-thumbnail-wrapper" :style="{ height: viewHeight }" @click="changeActive(3)" > <div :class=" 'prod-thumbnail prod-thumbnail_end ' + (active < 3 ? 'prod-thumbnail-disabled' : '') " > â¢æ°æ®äº§åä¸è½½ </div> </div> </transition> </div> </el-row> </template> <script setup> import { ref } from 'vue'; import { computed, inject, ref, watch, onMounted } from 'vue'; import { unCalc } from '@/utils/css-util'; import ProdQueryOpt from '@/views/fysp/data-product/base-data-product/components/ProdQueryOpt.vue'; import ProdDownload from '@/views/fysp/data-product/base-data-product/components/ProdDownload.vue'; const props = defineProps({ active: { type: Number, default: 1 }, loading: { type: Boolean, default: false } }); // function changeActive() { // active.value++; // active.value = active.value > 3 ? 1 : active.value; // } const emit = defineEmits(['update:active', 'onStep1']); const viewHeight = inject('viewHeight'); const btnDisabled = ref(false); const titleRef = ref(null); const contentHeight = ref('50vh'); function calContentHeight() { console.log(titleRef.value.offsetHeight); contentHeight.value = `calc(${unCalc(viewHeight.value)} - ${ titleRef.value?.offsetHeight || 0 }px)`; console.log(contentHeight.value); } // æ¥éª¤å¼ç¨ const step1Ref = ref(null); const step2Ref = ref(null); const step3Ref = ref(null); // æ§å¶æ¾ç¤º/éèçç¶æ const showStep1Content = ref(props.active === 1); const showStep1Thumbnail = ref(props.active != 1); const showStep2Content = ref(props.active === 2); const showStep2Thumbnail = ref(props.active != 2); const showStep3Content = ref(props.active === 3); const showStep3Thumbnail = ref(props.active != 3); // è®°å½å¨ç»æ¯å¦æ£å¨è¿è¡ä¸ const isAnimating = ref({}); // çå¬activeåå watch( () => props.active, (newActive, oldActive) => { // æ è®°å¨ç»å¼å§ isAnimating.value[oldActive] = true; isAnimating.value[newActive] = true; // å éèææå 容ï¼çå¾ å¨ç»ç»æååæ¾ç¤ºæ£ç¡®çå 容 if (oldActive === 1) { showStep1Content.value = false; } else if (oldActive === 2) { showStep2Content.value = false; } else if (oldActive === 3) { showStep3Content.value = false; } if (newActive === 1) { showStep1Thumbnail.value = false; } else if (newActive === 2) { showStep2Thumbnail.value = false; } else if (newActive === 3) { showStep3Thumbnail.value = false; } } ); // å¤çå¨ç»ç»æäºä»¶ function handleTransitionThumbnailEnd(stepIndex) { // æ£æ¥å¨ç»æ¯å¦ç¡®å®ç»æï¼é¿å éå¤è§¦åï¼ if (isAnimating.value[stepIndex]) { isAnimating.value[stepIndex] = false; // setTimeout(() => { // å¨ç»ç»æåï¼æ´æ°æ¾ç¤ºç¶æ if (stepIndex === 1) { showStep1Content.value = props.active === 1; } else if (stepIndex === 2) { showStep2Content.value = props.active === 2; } else if (stepIndex === 3) { showStep3Content.value = props.active === 3; } // }, 50); } } function handleTransitionContentEnd(stepIndex) { // æ£æ¥å¨ç»æ¯å¦ç¡®å®ç»æï¼é¿å éå¤è§¦åï¼ if (isAnimating.value[stepIndex]) { isAnimating.value[stepIndex] = false; // setTimeout(() => { // å¨ç»ç»æåï¼æ´æ°æ¾ç¤ºç¶æ if (stepIndex === 1) { showStep1Thumbnail.value = props.active != 1; } else if (stepIndex === 2) { showStep2Thumbnail.value = props.active != 2; } else if (stepIndex === 3) { showStep3Thumbnail.value = props.active != 3; } // }, 50); } } function onSearch(opt) { emit('onStep1', opt); } function changeActive(index) { let isAnimate = false; Object.values(isAnimating.value).forEach((item) => { isAnimate = isAnimate || item; }); if (!isAnimate && !btnDisabled.value && props.active >= index) { emit('update:active', index); btnDisabled.value = true; setTimeout(() => { btnDisabled.value = false; }, 500); } // emit('update:active', index); } onMounted(() => { calContentHeight(); }); </script> <style scoped> .prod-active { width: 66.667%; /* width: 66.667%; */ width: 90%; transition: width 0.5s ease, box-shadow 0.3s ease; /* background-color: #409eff; */ margin: 5px 0; border-radius: 4px; box-shadow: -3px 0 6px rgba(0, 0, 0, 0.1), 3px 0 6px rgba(0, 0, 0, 0.1); } .prod-inactive { /* width: 16.667%; */ width: 5%; transition: width 0.5s ease; background-color: #409eff; color: white; /* background-color: #e4e7ed; */ margin: 5px 0; border-radius: 4px; } .prod-inactive { width: 16.667%; transition: width 0.5s ease; .prod-title { padding: 10px; } .prod-thumbnail-wrapper { display: flex; justify-content: center; align-items: center; padding: 0 2px; } .prod-thumbnail { height: 90%; width: 100%; background-color: #409eff; color: white; display: flex; justify-content: center; align-items: center; writing-mode: vertical-rl; text-orientation: upright; letter-spacing: 8px; font-size: 18px; font-weight: 500; border-top-left-radius: 4px; border-bottom-left-radius: 4px; cursor: pointer; } .prod-thumbnail_middle { border-radius: 0px; } .prod-thumbnail_end { border-top-left-radius: 0px; border-bottom-left-radius: 0px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; } .prod-thumbnail-disabled { background-color: #e4e7ed; color: #606266; margin: 5px 0; border-radius: 4px; color: #c0c4cc; cursor: not-allowed; } </style> src/views/fysp/data-product/base-data-product/components/ProdDownload.vue
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,2 @@ <template>ProdDownload</template> <script setup></script> src/views/fysp/data-product/base-data-product/components/ProdQueryOpt.vue
@@ -4,6 +4,7 @@ <div><el-text tag="b" size="large">产åçæé项</el-text></div> </template> <SearchBar v-show="active" ref="refSearchBar" :btn-show="false" :init="false" @@ -11,7 +12,7 @@ > </SearchBar> <template #footer> <el-row justify="space-around"> <el-row v-show="active" justify="space-around"> <el-button type="primary" size="default" @@ -31,6 +32,10 @@ loading: { type: Boolean, default: false }, active:{ type: Boolean, default: true } }); const emit = defineEmits(['submit']);