Merge branch 'main' of http://121.37.111.42:3000/zhengsl/WholeProcessPlatform into main_hzz
This commit is contained in:
commit
2f87f8fb40
@ -12,13 +12,13 @@ export function getAisbdbyxList(data: any) {
|
|||||||
// AI识别大坝环境-获取饼图+表格数据 /api/wmp-env-server/env/ai/com/GetKendoListCust
|
// AI识别大坝环境-获取饼图+表格数据 /api/wmp-env-server/env/ai/com/GetKendoListCust
|
||||||
export function getAiChartTable(data: any) {
|
export function getAiChartTable(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/wmp-env-server/env/ai/com/GetKendoListCust',
|
url: '/warn/ai/com/GetKendoListCust',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// AI识别大坝环境-获取电站列表
|
// AI识别大坝环境-获取电站列表
|
||||||
export function getAiRstcd(data: any) {
|
export function getAiRstcd(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/warn/ai/com/qgc/aiRstcd/GetKendoListCust',
|
url: '/warn/ai/com/qgc/aiRstcd/GetKendoListCust',
|
||||||
@ -84,7 +84,7 @@ export function getAiRecord(data: any) {
|
|||||||
// AI识别大坝环境-获取日历详情视频数据 /warn/ai/com/qgc/aiFile/GetKendoListCust
|
// AI识别大坝环境-获取日历详情视频数据 /warn/ai/com/qgc/aiFile/GetKendoListCust
|
||||||
export function getAiFile(data: any) {
|
export function getAiFile(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/wmp-env-server/env/ai/com/qgc/aiFile/GetKendoListCust',
|
url: '/warn/ai/com/qgc/aiFile/GetKendoListCust',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
|
|||||||
@ -177,7 +177,84 @@
|
|||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item-rest>
|
</a-form-item-rest>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 基地电站下拉框 -->
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="flex gap-[10px]"
|
||||||
|
v-else-if="item.type === 'jidiData'"
|
||||||
|
>
|
||||||
|
<a-form-item-rest>
|
||||||
|
<!-- 基地下拉框 -->
|
||||||
|
<a-select
|
||||||
|
:value="formData[item.name]"
|
||||||
|
placeholder="请选择"
|
||||||
|
@change="val => dataDimensionDataChange(val, item.name)"
|
||||||
|
show-search
|
||||||
|
allow-clear
|
||||||
|
:loading="shuJuTianBaoStore.baseLoading"
|
||||||
|
:filter-option="filterOption"
|
||||||
|
style="width: 135px"
|
||||||
|
>
|
||||||
|
<a-select-option
|
||||||
|
v-for="opt in shuJuTianBaoStore.baseOption"
|
||||||
|
:key="opt.baseid"
|
||||||
|
:value="opt.baseid"
|
||||||
|
:label="opt.basename"
|
||||||
|
>
|
||||||
|
{{ opt.basename }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
<!-- 电站下拉框 -->
|
||||||
|
<a-select
|
||||||
|
v-if="props.zhujianfujian == 'fu'"
|
||||||
|
:value="formData.rstcd"
|
||||||
|
placeholder="请选择电站"
|
||||||
|
@change="stcdIdChange"
|
||||||
|
show-search
|
||||||
|
allow-clear
|
||||||
|
:loading="shuJuTianBaoStore.engLoading"
|
||||||
|
:filter-option="filterOption"
|
||||||
|
style="width: 135px"
|
||||||
|
:dropdown-style="{
|
||||||
|
maxHeight: '400px',
|
||||||
|
overflow: 'auto',
|
||||||
|
minWidth: '300px'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<a-select-option
|
||||||
|
v-for="opt in shuJuTianBaoStore.engOption"
|
||||||
|
:key="opt.stcd"
|
||||||
|
:value="opt.stcd"
|
||||||
|
:label="opt.ennm"
|
||||||
|
:title="opt.ennm + ',' + opt.reachcdName"
|
||||||
|
:reachcdName="opt.reachcdName"
|
||||||
|
>
|
||||||
|
{{ opt.ennm }},{{ opt.reachcdName }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
<!-- 电站下拉框 -->
|
||||||
|
<a-select
|
||||||
|
v-if="props.zhujianfujian == 'zhu'"
|
||||||
|
:value="formData.stcd"
|
||||||
|
placeholder="请选择电站"
|
||||||
|
@change="stcdIdChange"
|
||||||
|
show-search
|
||||||
|
allow-clear
|
||||||
|
:loading="shuJuTianBaoStore.engLoading"
|
||||||
|
:filter-option="filterOption"
|
||||||
|
style="width: 135px"
|
||||||
|
>
|
||||||
|
<a-select-option
|
||||||
|
v-for="opt in shuJuTianBaoStore.engOption"
|
||||||
|
:key="opt.stcd"
|
||||||
|
:value="opt.stcd"
|
||||||
|
:label="opt.ennm"
|
||||||
|
>
|
||||||
|
{{ opt.ennm }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item-rest>
|
||||||
|
</div>
|
||||||
<!-- 下拉选择 -->
|
<!-- 下拉选择 -->
|
||||||
<!-- <div v-else-if="item.type === 'Select'">
|
<!-- <div v-else-if="item.type === 'Select'">
|
||||||
<div v-for="i in item.options"> {{ i[item.values?.name] }} {{ i[item.values?.value] }}</div>
|
<div v-for="i in item.options"> {{ i[item.values?.name] }} {{ i[item.values?.value] }}</div>
|
||||||
@ -362,9 +439,13 @@ const initForm = () => {
|
|||||||
validSearchList.value.forEach(item => {
|
validSearchList.value.forEach(item => {
|
||||||
if (item.type == 'waterStation') {
|
if (item.type == 'waterStation') {
|
||||||
// 下拉菜单
|
// 下拉菜单
|
||||||
// shuJuTianBaoStore.getBaseOption();
|
shuJuTianBaoStore.getBaseOption();
|
||||||
shuJuTianBaoStore.getSelectForOption();
|
shuJuTianBaoStore.getSelectForOption();
|
||||||
shuJuTianBaoStore.getEngOption(formData.rvcd);
|
shuJuTianBaoStore.getEngOption(formData.rvcd,'rvcd');
|
||||||
|
}
|
||||||
|
if (item.type == 'jidiData') {
|
||||||
|
shuJuTianBaoStore.getBaseOption();
|
||||||
|
shuJuTianBaoStore.getEngOption(formData[item.name] || 'all','baseId');
|
||||||
}
|
}
|
||||||
if (item.fieldProps?.required) {
|
if (item.fieldProps?.required) {
|
||||||
rules[item.name] = [
|
rules[item.name] = [
|
||||||
@ -387,19 +468,19 @@ const triggerManualValuesChange = (changedKey: string, newValue: any) => {
|
|||||||
emit('valuesChange', changedValues, { ...formData });
|
emit('valuesChange', changedValues, { ...formData });
|
||||||
};
|
};
|
||||||
|
|
||||||
// const dataDimensionDataChange = (value: any) => {
|
const dataDimensionDataChange = (value: any, fieldName: string = 'baseId') => {
|
||||||
// formData.baseId = value;
|
formData[fieldName] = value;
|
||||||
// formData.rstcd = "";
|
formData.rstcd = "";
|
||||||
// shuJuTianBaoStore.getEngOption(formData.baseId);
|
shuJuTianBaoStore.getEngOption(value,'baseId');
|
||||||
|
triggerManualValuesChange('baseId', formData.baseId);
|
||||||
// // 【关键修改】手动触发 valuesChange,因为 a-form-item-rest 阻断了自动监听
|
// 一次性触发所有变更通知,避免多次调用
|
||||||
// triggerManualValuesChange("baseId", formData.baseId);
|
// emit('valuesChange', { [fieldName]: value, rstcd: "" }, { ...formData });
|
||||||
// };
|
};
|
||||||
|
|
||||||
const lyChange = (value: any) => {
|
const lyChange = (value: any) => {
|
||||||
formData.rvcd = value;
|
formData.rvcd = value;
|
||||||
formData.rstcd = '';
|
formData.rstcd = '';
|
||||||
shuJuTianBaoStore.getEngOption(formData.rvcd);
|
shuJuTianBaoStore.getEngOption(formData.rvcd,'rvcd');
|
||||||
|
|
||||||
// 【关键修改】手动触发 valuesChange,因为 a-form-item-rest 阻断了自动监听
|
// 【关键修改】手动触发 valuesChange,因为 a-form-item-rest 阻断了自动监听
|
||||||
triggerManualValuesChange('rvcd', formData.rvcd);
|
triggerManualValuesChange('rvcd', formData.rvcd);
|
||||||
@ -408,12 +489,12 @@ const lyChange = (value: any) => {
|
|||||||
const stcdIdChange = (value: any) => {
|
const stcdIdChange = (value: any) => {
|
||||||
if (props.zhujianfujian == 'fu') {
|
if (props.zhujianfujian == 'fu') {
|
||||||
formData.rstcd = value;
|
formData.rstcd = value;
|
||||||
shuJuTianBaoStore.getFpssOption(formData.rvcd, value);
|
shuJuTianBaoStore.getFpssOption(formData.baseId, value);
|
||||||
// 【关键修改】手动触发 valuesChange
|
// 【关键修改】手动触发 valuesChange
|
||||||
triggerManualValuesChange('rstcd', formData.rstcd);
|
triggerManualValuesChange('rstcd', formData.rstcd);
|
||||||
} else {
|
} else {
|
||||||
formData.stcd = value;
|
formData.stcd = value;
|
||||||
shuJuTianBaoStore.getFpssOption(formData.rvcd, value);
|
shuJuTianBaoStore.getFpssOption(formData.baseId, value);
|
||||||
// 【关键修改】手动触发 valuesChange
|
// 【关键修改】手动触发 valuesChange
|
||||||
triggerManualValuesChange('stcd', formData.stcd);
|
triggerManualValuesChange('stcd', formData.stcd);
|
||||||
}
|
}
|
||||||
|
|||||||
282
frontend/src/components/FishResource/FishResourceSearch.vue
Normal file
282
frontend/src/components/FishResource/FishResourceSearch.vue
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
<template>
|
||||||
|
<div class="approval-search">
|
||||||
|
<BasicSearch
|
||||||
|
ref="basicSearchRef"
|
||||||
|
:searchList="searchList"
|
||||||
|
:initial-values="initSearchData"
|
||||||
|
:zhujianfujian="'fu'"
|
||||||
|
@reset="handleResetWrapper"
|
||||||
|
@finish="onSearchFinish"
|
||||||
|
@values-change="onValuesChange"
|
||||||
|
><template #jcdt>
|
||||||
|
<a-date-picker
|
||||||
|
class="w-[120px]"
|
||||||
|
v-model:value="jcdt.min"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
placeholder="起始时间"
|
||||||
|
:showToday="false"
|
||||||
|
>
|
||||||
|
<template #renderExtraFooter>
|
||||||
|
<div class="flex items-center flex-wrap px-2">
|
||||||
|
<span
|
||||||
|
v-for="item in DateSetting.RangeButton.days1"
|
||||||
|
:key="item"
|
||||||
|
@click="handleRangeClick(item)"
|
||||||
|
>
|
||||||
|
<a class="text-[#1890ff] mr-1"> {{ item.label }}</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-date-picker>
|
||||||
|
至
|
||||||
|
<a-form-item-rest>
|
||||||
|
<a-date-picker
|
||||||
|
class="w-[120px]"
|
||||||
|
v-model:value="jcdt.max"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
:disabledDate="disabledEndDate"
|
||||||
|
placeholder="结束时间"
|
||||||
|
:showToday="false"
|
||||||
|
>
|
||||||
|
<template #renderExtraFooter>
|
||||||
|
<div class="flex items-center flex-wrap px-2">
|
||||||
|
<span
|
||||||
|
v-for="item in DateSetting.RangeButton.days1"
|
||||||
|
:key="item"
|
||||||
|
@click="handleRangeClick(item)"
|
||||||
|
>
|
||||||
|
<a class="text-[#1890ff] mr-1"> {{ item.label }}</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-date-picker>
|
||||||
|
</a-form-item-rest>
|
||||||
|
</template>
|
||||||
|
<template #actions>
|
||||||
|
<a-button :loading="exportLoading" @click="exportBtn">导出</a-button>
|
||||||
|
</template>
|
||||||
|
</BasicSearch>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, computed, onMounted } from 'vue';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import BasicSearch from '@/components/BasicSearch/index.vue';
|
||||||
|
import { DateSetting } from '@/utils/enumeration';
|
||||||
|
import { useTimeScale } from '@/store/composables/useTimeScale';
|
||||||
|
import { getFishReleaseMonitorSectionList } from '@/api/DataQueryMenuModule';
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'export-btn'): void;
|
||||||
|
(e: 'reset', values: any): void;
|
||||||
|
(e: 'search-finish', values: any): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const basicSearchRef = ref<any>();
|
||||||
|
const btnLoading = ref<boolean>(false);
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
exportLoading?: boolean;
|
||||||
|
modalData: any;
|
||||||
|
}>();
|
||||||
|
const initSearchData = {
|
||||||
|
baseId: props.modalData.baseid ?? 'all',
|
||||||
|
rstcd: null,
|
||||||
|
stcd: '',
|
||||||
|
mway: '1'
|
||||||
|
};
|
||||||
|
|
||||||
|
const searchData = ref<any>({ ...initSearchData });
|
||||||
|
|
||||||
|
const {
|
||||||
|
jcdt,
|
||||||
|
currentTimeScale,
|
||||||
|
handleRangeClick,
|
||||||
|
disabledEndDate,
|
||||||
|
handleSearchFinish,
|
||||||
|
handleValuesChange,
|
||||||
|
init,
|
||||||
|
setDefaultTimeRange
|
||||||
|
} = useTimeScale({
|
||||||
|
defaultTimeScale: initSearchData.timeScale,
|
||||||
|
onSearchFinish: values => emit('search-finish', values),
|
||||||
|
onReset: () => emit('reset', initSearchData)
|
||||||
|
});
|
||||||
|
const crossSectionListLoading = ref<any>(false);
|
||||||
|
const crossSectionList = ref<any>([]);
|
||||||
|
|
||||||
|
const searchList: any = computed(() => [
|
||||||
|
// {
|
||||||
|
// type: 'waterStation',
|
||||||
|
// name: 'rvcd',
|
||||||
|
// label: '流域',
|
||||||
|
// placeholder: '请输入流域名称',
|
||||||
|
// fieldProps: {
|
||||||
|
// allowClear: true
|
||||||
|
// },
|
||||||
|
// options: []
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
type: 'jidiData',
|
||||||
|
name: 'baseId',
|
||||||
|
label: '水电基地',
|
||||||
|
placeholder: '请输入水电基地名称',
|
||||||
|
fieldProps: {
|
||||||
|
allowClear: true
|
||||||
|
},
|
||||||
|
options: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'Select',
|
||||||
|
name: 'stcd',
|
||||||
|
label: '过鱼设施名称',
|
||||||
|
width: 200,
|
||||||
|
placeholder: '请选择过鱼设施名称',
|
||||||
|
fieldProps: {
|
||||||
|
allowClear: true
|
||||||
|
},
|
||||||
|
loading: crossSectionListLoading.value,
|
||||||
|
options: crossSectionList.value.map(item => ({
|
||||||
|
label: item.stnm,
|
||||||
|
value: item.stcd
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'Radio',
|
||||||
|
name: 'mway',
|
||||||
|
label: '数据类型',
|
||||||
|
width: 140,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '人工',
|
||||||
|
value: '1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '自动',
|
||||||
|
value: '2'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'custom',
|
||||||
|
name: 'jcdt',
|
||||||
|
label: '时间',
|
||||||
|
fieldProps: {
|
||||||
|
allowClear: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
const onSearchFinish = (values: any) => {
|
||||||
|
handleSearchFinish(values);
|
||||||
|
};
|
||||||
|
|
||||||
|
const exportBtn = () => {
|
||||||
|
emit('export-btn');
|
||||||
|
};
|
||||||
|
const initCrossSectionList = params => {
|
||||||
|
const filters = [];
|
||||||
|
if (params) {
|
||||||
|
if (params.baseId != '' && params.baseId != 'all') {
|
||||||
|
filters.push({
|
||||||
|
field: 'baseId',
|
||||||
|
operator: 'contains',
|
||||||
|
dataType: 'string',
|
||||||
|
value: params.baseId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (params.rstcd != '' && params.rstcd != null) {
|
||||||
|
filters.push({
|
||||||
|
field: 'rstcd',
|
||||||
|
operator: 'contains',
|
||||||
|
dataType: 'string',
|
||||||
|
value: params.rstcd
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crossSectionListLoading.value = true;
|
||||||
|
getFishReleaseMonitorSectionList({
|
||||||
|
filter: {
|
||||||
|
logic: 'and',
|
||||||
|
filters: filters
|
||||||
|
},
|
||||||
|
select: ['stcd', 'stnm', 'wtDeviceType', 'dtinType', 'mway']
|
||||||
|
}).then(res => {
|
||||||
|
if (res.data?.data) {
|
||||||
|
crossSectionList.value = res.data?.data;
|
||||||
|
}
|
||||||
|
crossSectionListLoading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onValuesChange = (changedValues: any, allValues: any) => {
|
||||||
|
// 当基地或断面变化时,清空过鱼设施选中并重新请求列表
|
||||||
|
if ('baseId' in changedValues || 'rstcd' in changedValues) {
|
||||||
|
allValues.stcd = null;
|
||||||
|
if (basicSearchRef.value?.formData) {
|
||||||
|
basicSearchRef.value.formData.stcd = null;
|
||||||
|
}
|
||||||
|
initCrossSectionList(allValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleValuesChange(changedValues, allValues);
|
||||||
|
searchData.value = { ...searchData.value, ...allValues };
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleResetWrapper = () => {
|
||||||
|
// 手动重置内部状态,避免触发两次请求
|
||||||
|
currentTimeScale.value = initSearchData.timeScale;
|
||||||
|
const now = dayjs();
|
||||||
|
if (props.modalData.year) {
|
||||||
|
jcdt.value = {
|
||||||
|
min: `${props.modalData.year}-01-01 00:00:00`,
|
||||||
|
max: `${props.modalData.year}-12-31 23:59:59`
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
jcdt.value = {
|
||||||
|
min: `${now
|
||||||
|
.subtract(5, 'year')
|
||||||
|
.startOf('year')
|
||||||
|
.format('YYYY-MM-DD')} 00:00:00`,
|
||||||
|
max: `${now.endOf('year').format('YYYY-MM-DD')} 23:59:59`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
setDefaultTimeRange(initSearchData.timeScale);
|
||||||
|
// 触发搜索,使用当前状态而非 initSearchData
|
||||||
|
handleSearchFinish({
|
||||||
|
...initSearchData
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
btnLoading,
|
||||||
|
searchData
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
init();
|
||||||
|
// 设置默认年份:前一年到当前年
|
||||||
|
const now = dayjs();
|
||||||
|
if (props.modalData.year) {
|
||||||
|
jcdt.value = {
|
||||||
|
min: `${props.modalData.year}-01-01 00:00:00`,
|
||||||
|
max: `${props.modalData.year}-12-31 23:59:59`
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
jcdt.value = {
|
||||||
|
min: `${now.subtract(5, 'year').format('YYYY-MM-DD')} 00:00:00`,
|
||||||
|
max: `${now.format('YYYY-MM-DD')} 23:59:59`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
initCrossSectionList();
|
||||||
|
// 使用 handleSearchFinish 确保包含 jcdt 等完整参数
|
||||||
|
handleSearchFinish({ ...initSearchData });
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss"></style>
|
||||||
554
frontend/src/components/FishResource/index.vue
Normal file
554
frontend/src/components/FishResource/index.vue
Normal file
@ -0,0 +1,554 @@
|
|||||||
|
<template>
|
||||||
|
<div class="w-full h-full flex flex-col" style="height:calc(60vh)">
|
||||||
|
<!-- 搜索组件 -->
|
||||||
|
<FishDataSearch
|
||||||
|
@export-btn="exportBtn"
|
||||||
|
@search-finish="onSearchFinish"
|
||||||
|
@reset="onReset"
|
||||||
|
:exportLoading="exportLoading"
|
||||||
|
:modalData = "props.modalData"
|
||||||
|
ref="searchRef"
|
||||||
|
/>
|
||||||
|
<!-- 表格组件 -->
|
||||||
|
<BasicTable
|
||||||
|
ref="tableRef"
|
||||||
|
:scrollX="tableScrollX"
|
||||||
|
:scrollY="tableScrollY"
|
||||||
|
:columns="tableColumns"
|
||||||
|
:list-url="getFishReleaseMonitorList"
|
||||||
|
:searchParams="{
|
||||||
|
sort: sort
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
</BasicTable>
|
||||||
|
|
||||||
|
<!-- 图片预览弹框 -->
|
||||||
|
<a-modal
|
||||||
|
v-model:open="imagePreviewVisible"
|
||||||
|
title="图片预览"
|
||||||
|
:footer="null"
|
||||||
|
width="800px"
|
||||||
|
>
|
||||||
|
<div style="text-align: center">
|
||||||
|
<img :src="previewImageUrl" style="width: 100%; height: 600px" />
|
||||||
|
</div>
|
||||||
|
</a-modal>
|
||||||
|
|
||||||
|
<!-- 视频预览弹框 -->
|
||||||
|
<a-modal
|
||||||
|
v-model:open="videoPreviewVisible"
|
||||||
|
title="视频预览"
|
||||||
|
:footer="null"
|
||||||
|
width="800px"
|
||||||
|
>
|
||||||
|
<div style="text-align: center">
|
||||||
|
<video
|
||||||
|
:src="previewVideoUrl"
|
||||||
|
controls
|
||||||
|
style="width: 100%; height: 600px"
|
||||||
|
></video>
|
||||||
|
</div>
|
||||||
|
</a-modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed, onMounted, nextTick, h } from 'vue';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { Button } from 'ant-design-vue';
|
||||||
|
import FishDataSearch from './FishResourceSearch.vue';
|
||||||
|
import BasicTable from '@/components/BasicTable/index.vue';
|
||||||
|
import { getFishReleaseMonitorList } from '@/api/DataQueryMenuModule';
|
||||||
|
import { calcTableScrollY } from '@/utils/index';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
const props = defineProps<{
|
||||||
|
modalData?: any;
|
||||||
|
}>();
|
||||||
|
const sort = ref<any>([
|
||||||
|
{
|
||||||
|
field: 'baseStepSort',
|
||||||
|
dir: 'asc'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'rvcdStepSort',
|
||||||
|
dir: 'asc'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'rstcdStepSort',
|
||||||
|
dir: 'asc'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'ttpwr',
|
||||||
|
dir: 'asc'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'tm',
|
||||||
|
dir: 'desc'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
const tableRef = ref();
|
||||||
|
const searchRef = ref();
|
||||||
|
const tableScrollY = ref<string | number>(0);
|
||||||
|
const currentSearchParams = ref<any>({});
|
||||||
|
const exportLoading = ref(false);
|
||||||
|
|
||||||
|
// 图片预览
|
||||||
|
const imagePreviewVisible = ref(false);
|
||||||
|
const previewImageUrl = ref('');
|
||||||
|
// 视频预览
|
||||||
|
const videoPreviewVisible = ref(false);
|
||||||
|
const previewVideoUrl = ref('');
|
||||||
|
useDraggable(imagePreviewVisible, { boundary: true, resetOnOpen: true });
|
||||||
|
useDraggable(videoPreviewVisible, { boundary: true, resetOnOpen: true });
|
||||||
|
const openImagePreview = (url: string) => {
|
||||||
|
previewImageUrl.value = import.meta.env.VITE_APP_ATTACHMENT_URL + '/?' + url;
|
||||||
|
imagePreviewVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const openVideoPreview = (url: string) => {
|
||||||
|
previewVideoUrl.value = import.meta.env.VITE_APP_ATTACHMENT_URL + '/?' + url;
|
||||||
|
videoPreviewVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const tableScrollX = computed(() =>
|
||||||
|
Math.max(
|
||||||
|
tableColumns.value.reduce(
|
||||||
|
(sum: number, col: any) => sum + (col.width || 180),
|
||||||
|
0
|
||||||
|
),
|
||||||
|
600
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 人工列
|
||||||
|
const columnsManual: any[] = [
|
||||||
|
{
|
||||||
|
key: 'stnm',
|
||||||
|
title: '电站名称',
|
||||||
|
dataIndex: 'stnm',
|
||||||
|
visible: true,
|
||||||
|
width: 200,
|
||||||
|
sort: true,
|
||||||
|
merge: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'baseName',
|
||||||
|
title: '所属基地',
|
||||||
|
dataIndex: 'baseName',
|
||||||
|
sort: true,
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'stnm',
|
||||||
|
title: '过鱼设施名称',
|
||||||
|
dataIndex: 'stnm',
|
||||||
|
sort: true,
|
||||||
|
width: 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'strdt',
|
||||||
|
title: '开始时间',
|
||||||
|
dataIndex: 'strdt',
|
||||||
|
sort: true,
|
||||||
|
width: 100,
|
||||||
|
customRender: ({ text }) => dayjs(text).format('YYYY-MM-DD') || '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'enddt',
|
||||||
|
title: '结束时间',
|
||||||
|
dataIndex: 'enddt',
|
||||||
|
sort: true,
|
||||||
|
width: 100,
|
||||||
|
customRender: ({ text }) => dayjs(text).format('YYYY-MM-DD') || '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'tm',
|
||||||
|
title: '填报时间',
|
||||||
|
dataIndex: 'tm',
|
||||||
|
sort: true,
|
||||||
|
width: 160
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'ftp',
|
||||||
|
title: '鱼种类',
|
||||||
|
dataIndex: 'ftp',
|
||||||
|
sort: true,
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'fcnt',
|
||||||
|
title: '过鱼数量(尾)',
|
||||||
|
dataIndex: 'fcnt',
|
||||||
|
sort: true,
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'directionName',
|
||||||
|
title: '鱼游向',
|
||||||
|
dataIndex: 'directionName',
|
||||||
|
sort: true,
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'fsz',
|
||||||
|
title: '鱼类规格',
|
||||||
|
dataIndex: 'fsz',
|
||||||
|
sort: true,
|
||||||
|
width: 160
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'firstimgurl',
|
||||||
|
title: '图片',
|
||||||
|
dataIndex: 'firstimgurl',
|
||||||
|
align: 'center',
|
||||||
|
width: 110,
|
||||||
|
customRender: ({ text }: any) => {
|
||||||
|
const hasValidUrl =
|
||||||
|
text &&
|
||||||
|
text !== '-' &&
|
||||||
|
text.trim() !== '' &&
|
||||||
|
text !== 'null' &&
|
||||||
|
text !== 'undefined';
|
||||||
|
return h(
|
||||||
|
Button,
|
||||||
|
{
|
||||||
|
type: 'link',
|
||||||
|
disabled: !hasValidUrl,
|
||||||
|
style: {
|
||||||
|
color: !hasValidUrl ? '#ccc' : '#1890ff',
|
||||||
|
cursor: !hasValidUrl ? 'not-allowed' : 'pointer'
|
||||||
|
},
|
||||||
|
onClick: () => {
|
||||||
|
if (hasValidUrl) {
|
||||||
|
openImagePreview(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => '查看图片'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'videourl',
|
||||||
|
title: '视频',
|
||||||
|
dataIndex: 'videourl',
|
||||||
|
align: 'center',
|
||||||
|
width: 110,
|
||||||
|
customRender: ({ text }: any) => {
|
||||||
|
const hasValidUrl =
|
||||||
|
text &&
|
||||||
|
text !== '-' &&
|
||||||
|
text.trim() !== '' &&
|
||||||
|
text !== 'null' &&
|
||||||
|
text !== 'undefined';
|
||||||
|
return h(
|
||||||
|
Button,
|
||||||
|
{
|
||||||
|
type: 'link',
|
||||||
|
disabled: !hasValidUrl,
|
||||||
|
style: {
|
||||||
|
color: !hasValidUrl ? '#ccc' : '#1890ff',
|
||||||
|
cursor: !hasValidUrl ? 'not-allowed' : 'pointer'
|
||||||
|
},
|
||||||
|
onClick: () => {
|
||||||
|
if (hasValidUrl) {
|
||||||
|
openVideoPreview(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => '查看视频'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// 自动列
|
||||||
|
const columnsAuto: any[] = [
|
||||||
|
{
|
||||||
|
key: 'stnm',
|
||||||
|
title: '电站名称',
|
||||||
|
dataIndex: 'stnm',
|
||||||
|
visible: true,
|
||||||
|
width: 200,
|
||||||
|
sort: true,
|
||||||
|
merge: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'baseName',
|
||||||
|
title: '所属基地',
|
||||||
|
dataIndex: 'baseName',
|
||||||
|
sort: true,
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'stnm',
|
||||||
|
title: '过鱼设施名称',
|
||||||
|
dataIndex: 'stnm',
|
||||||
|
sort: true,
|
||||||
|
width: 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'tm',
|
||||||
|
title: '时间',
|
||||||
|
dataIndex: 'tm',
|
||||||
|
sort: true,
|
||||||
|
width: 160
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'ftp',
|
||||||
|
title: '鱼种类',
|
||||||
|
dataIndex: 'ftp',
|
||||||
|
sort: true,
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'length',
|
||||||
|
title: '鱼长度(cm)',
|
||||||
|
dataIndex: 'length',
|
||||||
|
sort: true,
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'width',
|
||||||
|
title: '鱼宽度(cm)',
|
||||||
|
dataIndex: 'width',
|
||||||
|
sort: true,
|
||||||
|
width: 120,
|
||||||
|
customRender: ({ text }: any) => {
|
||||||
|
const num = parseFloat(text);
|
||||||
|
return isNaN(num) ? '-' : num.toFixed(2);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'fishspeed',
|
||||||
|
title: '鱼速度(m/s)',
|
||||||
|
dataIndex: 'fishspeed',
|
||||||
|
sort: true,
|
||||||
|
width: 80,
|
||||||
|
customRender: ({ text }: any) => {
|
||||||
|
const num = parseFloat(text);
|
||||||
|
return isNaN(num) ? '-' : num.toFixed(2);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'directionName',
|
||||||
|
title: '鱼游向',
|
||||||
|
dataIndex: 'directionName',
|
||||||
|
sort: true,
|
||||||
|
width: 160
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'temperature',
|
||||||
|
title: '水温(℃)',
|
||||||
|
dataIndex: 'temperature',
|
||||||
|
sort: true,
|
||||||
|
width: 160,
|
||||||
|
customRender: ({ text }: any) => {
|
||||||
|
const num = parseFloat(text);
|
||||||
|
return isNaN(num) ? '-' : num.toFixed(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'speed',
|
||||||
|
title: '流速(m/s)',
|
||||||
|
dataIndex: 'speed',
|
||||||
|
sort: true,
|
||||||
|
width: 160,
|
||||||
|
customRender: ({ text }: any) => {
|
||||||
|
const num = parseFloat(text);
|
||||||
|
return isNaN(num) ? '-' : num.toFixed(2);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'fcnt',
|
||||||
|
title: '过鱼数量(尾)',
|
||||||
|
dataIndex: 'fcnt',
|
||||||
|
sort: true,
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'channelno',
|
||||||
|
title: '过鱼通道',
|
||||||
|
dataIndex: 'channelno',
|
||||||
|
sort: true,
|
||||||
|
width: 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'firstimgurl',
|
||||||
|
title: '轮廓图',
|
||||||
|
dataIndex: 'firstimgurl',
|
||||||
|
align: 'center',
|
||||||
|
width: 110,
|
||||||
|
customRender: ({ text }: any) => {
|
||||||
|
const hasValidUrl =
|
||||||
|
text &&
|
||||||
|
text !== '-' &&
|
||||||
|
text.trim() !== '' &&
|
||||||
|
text !== 'null' &&
|
||||||
|
text !== 'undefined';
|
||||||
|
return h(
|
||||||
|
Button,
|
||||||
|
{
|
||||||
|
type: 'link',
|
||||||
|
disabled: !hasValidUrl,
|
||||||
|
style: {
|
||||||
|
color: !hasValidUrl ? '#ccc' : '#1890ff',
|
||||||
|
cursor: !hasValidUrl ? 'not-allowed' : 'pointer'
|
||||||
|
},
|
||||||
|
onClick: () => {
|
||||||
|
if (hasValidUrl) {
|
||||||
|
openImagePreview(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => '查看图片'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'videourl',
|
||||||
|
title: '短视频',
|
||||||
|
dataIndex: 'videourl',
|
||||||
|
align: 'center',
|
||||||
|
width: 110,
|
||||||
|
customRender: ({ text }: any) => {
|
||||||
|
const hasValidUrl =
|
||||||
|
text &&
|
||||||
|
text !== '-' &&
|
||||||
|
text.trim() !== '' &&
|
||||||
|
text !== 'null' &&
|
||||||
|
text !== 'undefined';
|
||||||
|
return h(
|
||||||
|
Button,
|
||||||
|
{
|
||||||
|
type: 'link',
|
||||||
|
disabled: !hasValidUrl,
|
||||||
|
style: {
|
||||||
|
color: !hasValidUrl ? '#ccc' : '#1890ff',
|
||||||
|
cursor: !hasValidUrl ? 'not-allowed' : 'pointer'
|
||||||
|
},
|
||||||
|
onClick: () => {
|
||||||
|
if (hasValidUrl) {
|
||||||
|
openVideoPreview(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => '查看视频'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// 根据数据类型动态切换列
|
||||||
|
const tableColumns = computed(() => {
|
||||||
|
const mway = currentSearchParams.value.mway;
|
||||||
|
return mway === '2' ? columnsAuto : columnsManual;
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSearchFinish = async (values: any) => {
|
||||||
|
currentSearchParams.value = values;
|
||||||
|
// 等待 prop 更新后再调用 getList
|
||||||
|
await nextTick();
|
||||||
|
initTable(values);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onReset = async (values: any) => {
|
||||||
|
currentSearchParams.value = values;
|
||||||
|
await nextTick();
|
||||||
|
initTable(values);
|
||||||
|
};
|
||||||
|
|
||||||
|
const exportBtn = () => {
|
||||||
|
if (exportLoading.value) return;
|
||||||
|
|
||||||
|
exportLoading.value = true;
|
||||||
|
searchRef.value.btnLoading = true;
|
||||||
|
|
||||||
|
tableRef.value
|
||||||
|
.exportTable({
|
||||||
|
fileName: `过鱼监测数据_${dayjs().format('YYYY-MM-DD HH-mm-ss')}`
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
exportLoading.value = false;
|
||||||
|
searchRef.value.btnLoading = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const initTable = (values: any) => {
|
||||||
|
console.log(values);
|
||||||
|
const filters = [
|
||||||
|
values.baseId && values.baseId !== 'all'
|
||||||
|
? {
|
||||||
|
field: 'baseId',
|
||||||
|
operator: 'contains',
|
||||||
|
dataType: 'string',
|
||||||
|
value: values.baseId
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
values.rstcd
|
||||||
|
? {
|
||||||
|
field: 'rstcd',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: values.rstcd
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
values.mway
|
||||||
|
? {
|
||||||
|
field: 'mway',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: values.mway
|
||||||
|
}
|
||||||
|
: null
|
||||||
|
].filter(Boolean); // 移除空项
|
||||||
|
if (values.stcd) {
|
||||||
|
filters.push({
|
||||||
|
logic: 'or',
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
field: 'stcd',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: values.stcd
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'stcode',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: values.stcd
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (values.jcdt) {
|
||||||
|
filters.push(
|
||||||
|
{
|
||||||
|
field: 'tm',
|
||||||
|
operator: 'gte',
|
||||||
|
dataType: 'date',
|
||||||
|
value: dayjs(values.jcdt.min).format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'tm',
|
||||||
|
operator: 'lte',
|
||||||
|
dataType: 'date',
|
||||||
|
value: dayjs(values.jcdt.max).format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
logic: 'and',
|
||||||
|
filters
|
||||||
|
};
|
||||||
|
tableRef.value.getList(params);
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
nextTick(() => {
|
||||||
|
tableScrollY.value = calcTableScrollY();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
||||||
@ -245,6 +245,7 @@ import { useModelStore } from '@/store/modules/model';
|
|||||||
import videoCover from '@/assets/images/videFm.jpg';
|
import videoCover from '@/assets/images/videFm.jpg';
|
||||||
import MediaViewer from './MediaViewer.vue';
|
import MediaViewer from './MediaViewer.vue';
|
||||||
import AttachmentPreview from './AttachmentPreview.vue';
|
import AttachmentPreview from './AttachmentPreview.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
const modelStore = useModelStore();
|
const modelStore = useModelStore();
|
||||||
|
|
||||||
@ -875,7 +876,8 @@ const notRunningMediaViewerRef = ref();
|
|||||||
// 附件预览弹窗
|
// 附件预览弹窗
|
||||||
const attachmentModalVisible = ref(false);
|
const attachmentModalVisible = ref(false);
|
||||||
const currentAttachmentFid = ref('');
|
const currentAttachmentFid = ref('');
|
||||||
|
useDraggable(detailModalVisible, { boundary: true, resetOnOpen: true });
|
||||||
|
useDraggable(attachmentModalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 查看附件
|
// 查看附件
|
||||||
const handleViewAttachment = (record: any) => {
|
const handleViewAttachment = (record: any) => {
|
||||||
if (!record.fid) {
|
if (!record.fid) {
|
||||||
|
|||||||
@ -152,7 +152,7 @@ import { getStcdDetail } from '@/api/mapModal';
|
|||||||
const baseUrl = import.meta.env.VITE_APP_ATTACHMENT_URL;
|
const baseUrl = import.meta.env.VITE_APP_ATTACHMENT_URL;
|
||||||
const modelStore = useModelStore();
|
const modelStore = useModelStore();
|
||||||
const hasLoaded = ref(false); // 标记是否已经请求过
|
const hasLoaded = ref(false); // 标记是否已经请求过
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
url: {
|
url: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -168,6 +168,7 @@ const isLogo = ref(false);
|
|||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const data2: any = ref({});
|
const data2: any = ref({});
|
||||||
const tabledata = ref([]);
|
const tabledata = ref([]);
|
||||||
|
useDraggable(visible, { boundary: true, resetOnOpen: true });
|
||||||
const columnsConfig = ref([
|
const columnsConfig = ref([
|
||||||
{
|
{
|
||||||
type: 'ENG',
|
type: 'ENG',
|
||||||
|
|||||||
@ -56,6 +56,7 @@ import { getMonitorDataFpq, getMonitorDataOnline } from '@/api/mapModal';
|
|||||||
import { useModelStore } from '@/store/modules/model';
|
import { useModelStore } from '@/store/modules/model';
|
||||||
import { DateSetting } from '@/utils/enumeration';
|
import { DateSetting } from '@/utils/enumeration';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const modelStore = useModelStore();
|
const modelStore = useModelStore();
|
||||||
@ -72,7 +73,8 @@ const previewImageUrl = ref('');
|
|||||||
// 视频预览
|
// 视频预览
|
||||||
const videoPreviewVisible = ref(false);
|
const videoPreviewVisible = ref(false);
|
||||||
const previewVideoUrl = ref('');
|
const previewVideoUrl = ref('');
|
||||||
|
useDraggable(imagePreviewVisible, { boundary: true, resetOnOpen: true });
|
||||||
|
useDraggable(videoPreviewVisible, { boundary: true, resetOnOpen: true });
|
||||||
const openImagePreview = (url: string) => {
|
const openImagePreview = (url: string) => {
|
||||||
previewImageUrl.value = import.meta.env.VITE_APP_ATTACHMENT_URL + '/?' + url;
|
previewImageUrl.value = import.meta.env.VITE_APP_ATTACHMENT_URL + '/?' + url;
|
||||||
imagePreviewVisible.value = true;
|
imagePreviewVisible.value = true;
|
||||||
|
|||||||
@ -102,6 +102,7 @@ import { getDictItemsByCode } from '@/api/dict';
|
|||||||
import { getFishDictoryDropdown } from '@/api/select';
|
import { getFishDictoryDropdown } from '@/api/select';
|
||||||
import { useModelStore } from '@/store/modules/model';
|
import { useModelStore } from '@/store/modules/model';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const modelStore = useModelStore();
|
const modelStore = useModelStore();
|
||||||
@ -125,7 +126,8 @@ const previewImageUrl = ref('');
|
|||||||
// 视频预览
|
// 视频预览
|
||||||
const videoPreviewVisible = ref(false);
|
const videoPreviewVisible = ref(false);
|
||||||
const currentVideoUrl = ref('');
|
const currentVideoUrl = ref('');
|
||||||
|
useDraggable(imagePreviewVisible, { boundary: true, resetOnOpen: true });
|
||||||
|
useDraggable(videoPreviewVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 鱼类搜索过滤
|
// 鱼类搜索过滤
|
||||||
const filterFtpOption = (input: string, option: any) => {
|
const filterFtpOption = (input: string, option: any) => {
|
||||||
console.log('filterOption', input, option);
|
console.log('filterOption', input, option);
|
||||||
|
|||||||
@ -79,6 +79,7 @@ import { queryPostUrlList } from '@/api/mapModal';
|
|||||||
import { useModelStore } from '@/store/modules/model';
|
import { useModelStore } from '@/store/modules/model';
|
||||||
import BasicTable from '@/components/BasicTable/index.vue';
|
import BasicTable from '@/components/BasicTable/index.vue';
|
||||||
import { DateSetting } from '@/utils/enumeration';
|
import { DateSetting } from '@/utils/enumeration';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
const modelStore = useModelStore();
|
const modelStore = useModelStore();
|
||||||
|
|
||||||
@ -102,7 +103,7 @@ let chartInstance: echarts.ECharts | null = null;
|
|||||||
const videoModalVisible = ref(false);
|
const videoModalVisible = ref(false);
|
||||||
const videoModalTitle = ref('');
|
const videoModalTitle = ref('');
|
||||||
const currentVideoUrl = ref('');
|
const currentVideoUrl = ref('');
|
||||||
|
useDraggable(videoModalVisible, { boundary: true, resetOnOpen: true });
|
||||||
const tabsList = [{ name: '流量监测', key: 'flowMeasure' }];
|
const tabsList = [{ name: '流量监测', key: 'flowMeasure' }];
|
||||||
const activeTabKey = ref('flowMeasure');
|
const activeTabKey = ref('flowMeasure');
|
||||||
|
|
||||||
|
|||||||
@ -110,6 +110,7 @@ import {
|
|||||||
type OperationFilterField,
|
type OperationFilterField,
|
||||||
type OperationTableItem
|
type OperationTableItem
|
||||||
} from './operationConfig';
|
} from './operationConfig';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
isActive: { type: Boolean, default: false }
|
isActive: { type: Boolean, default: false }
|
||||||
@ -141,6 +142,7 @@ const loadYear = ref(false);
|
|||||||
const loadFtp = ref(false);
|
const loadFtp = ref(false);
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
const attachmentModalVisible = ref(false);
|
const attachmentModalVisible = ref(false);
|
||||||
|
useDraggable(attachmentModalVisible, { boundary: true, resetOnOpen: true });
|
||||||
const currentAttachmentFid = ref('');
|
const currentAttachmentFid = ref('');
|
||||||
const fieldOptionsMap = reactive<Record<string, OperationFilterOption[]>>({});
|
const fieldOptionsMap = reactive<Record<string, OperationFilterOption[]>>({});
|
||||||
const selectLoadingMap = reactive<Record<string, boolean>>({});
|
const selectLoadingMap = reactive<Record<string, boolean>>({});
|
||||||
|
|||||||
@ -28,7 +28,7 @@ import * as echarts from 'echarts';
|
|||||||
import { getVmsstbprptKendoList } from '@/api/home';
|
import { getVmsstbprptKendoList } from '@/api/home';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import ShuiDianKaiFQKTwoLayer from '@/modules/shuidianhuangjingjieruMod/TwoLayer/ShuiDianKaiFQKTwoLayer.vue';
|
import ShuiDianKaiFQKTwoLayer from '@/modules/shuidianhuangjingjieruMod/TwoLayer/ShuiDianKaiFQKTwoLayer.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'developStatusChart'
|
name: 'developStatusChart'
|
||||||
});
|
});
|
||||||
@ -41,7 +41,7 @@ const dataLoading = ref(false);
|
|||||||
|
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const modalProps = ref<any>({});
|
const modalProps = ref<any>({});
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
function openModal(props: any) {
|
function openModal(props: any) {
|
||||||
modalProps.value = props;
|
modalProps.value = props;
|
||||||
modalVisible.value = true;
|
modalVisible.value = true;
|
||||||
|
|||||||
@ -60,7 +60,7 @@ import { ref, watch } from 'vue';
|
|||||||
import { getVmsstbprptKendoList } from '@/api/home';
|
import { getVmsstbprptKendoList } from '@/api/home';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import HuanJingSJJRQK from '@/modules/shuidianhuangjingjieruMod/TwoLayer/HuanJingSJJRQK.vue';
|
import HuanJingSJJRQK from '@/modules/shuidianhuangjingjieruMod/TwoLayer/HuanJingSJJRQK.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'EngEnvironmentData'
|
name: 'EngEnvironmentData'
|
||||||
});
|
});
|
||||||
@ -72,7 +72,7 @@ const data = ref<Record<string, number>>({ one: 0, two: 0, three: 0 });
|
|||||||
|
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const modalProps = ref<any>({});
|
const modalProps = ref<any>({});
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
function openModal(props: any) {
|
function openModal(props: any) {
|
||||||
modalProps.value = props;
|
modalProps.value = props;
|
||||||
modalVisible.value = true;
|
modalVisible.value = true;
|
||||||
|
|||||||
@ -63,6 +63,7 @@ import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
|||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import { vpcGetKendoListCust } from '@/api/zxdzw';
|
import { vpcGetKendoListCust } from '@/api/zxdzw';
|
||||||
import ArtsDetail from '@/components/carouselIntroduce/ArtsDetail.vue';
|
import ArtsDetail from '@/components/carouselIntroduce/ArtsDetail.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -83,7 +84,7 @@ const baseid = ref('');
|
|||||||
// 弹框控制
|
// 弹框控制
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const currentItem = ref<any>(null);
|
const currentItem = ref<any>(null);
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 加载状态
|
// 加载状态
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
|
|||||||
@ -109,6 +109,7 @@ import isSameOrAfter from 'dayjs/plugin/isSameOrAfter'
|
|||||||
import BasicTable from '@/components/BasicTable/index.vue'
|
import BasicTable from '@/components/BasicTable/index.vue'
|
||||||
import { wqGetKendoList } from '@/api/sz'
|
import { wqGetKendoList } from '@/api/sz'
|
||||||
import HJMZDTwoLays from "./HJMZDTwoLays.vue"
|
import HJMZDTwoLays from "./HJMZDTwoLays.vue"
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 注册 dayjs 插件
|
// 注册 dayjs 插件
|
||||||
dayjs.extend(isSameOrAfter)
|
dayjs.extend(isSameOrAfter)
|
||||||
@ -155,7 +156,7 @@ const detailModalVisible = ref(false)
|
|||||||
const detailData = ref<any>({})
|
const detailData = ref<any>({})
|
||||||
const mapModalVisible = ref(false)
|
const mapModalVisible = ref(false)
|
||||||
const mapModalData = ref<any>({})
|
const mapModalData = ref<any>({})
|
||||||
|
useDraggable(detailModalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 排序配置
|
// 排序配置
|
||||||
const sortConfig = computed(() => [
|
const sortConfig = computed(() => [
|
||||||
{ field: 'rstcdStepSort', dir: 'asc' },
|
{ field: 'rstcdStepSort', dir: 'asc' },
|
||||||
|
|||||||
@ -36,6 +36,8 @@ import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
|||||||
import { wqGetKendoListCust } from '@/api/sz'
|
import { wqGetKendoListCust } from '@/api/sz'
|
||||||
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
||||||
import EnvironmentalQualityTwoLayers from "./TwoLayers/EnvironmentalQualityTwoLayers.vue"
|
import EnvironmentalQualityTwoLayers from "./TwoLayers/EnvironmentalQualityTwoLayers.vue"
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'EnvironmentalQuality'
|
name: 'EnvironmentalQuality'
|
||||||
@ -774,7 +776,7 @@ onUnmounted(() => {
|
|||||||
// 弹框相关状态
|
// 弹框相关状态
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const clickedBarData = ref<{ name: string; current: number | null; lastYear: number | null; selectedId?: string } | null>(null);
|
const clickedBarData = ref<{ name: string; current: number | null; lastYear: number | null; selectedId?: string } | null>(null);
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -32,6 +32,7 @@ import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
|||||||
import { vpcGetKendoListCust } from '@/api/zxdzw';
|
import { vpcGetKendoListCust } from '@/api/zxdzw';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import ZhiWuYuanDetailTable from './ZhiWuYuanDetailTable.vue';
|
import ZhiWuYuanDetailTable from './ZhiWuYuanDetailTable.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -50,7 +51,7 @@ const loading = ref(false);
|
|||||||
// 弹窗状态
|
// 弹窗状态
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const modalJidi = ref('all');
|
const modalJidi = ref('all');
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 基地选项(用于弹窗中的下拉)
|
// 基地选项(用于弹窗中的下拉)
|
||||||
const jidiOptions = ref<any[]>([]);
|
const jidiOptions = ref<any[]>([]);
|
||||||
|
|
||||||
|
|||||||
@ -54,6 +54,7 @@ import Yanchengyulei from './TwoLayers/Yanchengyulei.vue';
|
|||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import { wbsbGetKendoList, getDftYear, fishChanges2 } from '@/api/stdc';
|
import { wbsbGetKendoList, getDftYear, fishChanges2 } from '@/api/stdc';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'alongFishMod'
|
name: 'alongFishMod'
|
||||||
@ -108,7 +109,7 @@ const modalHbrvcd = ref('');
|
|||||||
const modalStateName = ref('');
|
const modalStateName = ref('');
|
||||||
const modalSectionName = ref('');
|
const modalSectionName = ref('');
|
||||||
const modalStcd = ref('');
|
const modalStcd = ref('');
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// ==================== 图表相关 ====================
|
// ==================== 图表相关 ====================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -53,6 +53,8 @@ import { getVmsstbprpt, inOutOneGetKendoListCust } from '@/api/sw';
|
|||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import churukushuiwen from './churukushuiwen.vue';
|
import churukushuiwen from './churukushuiwen.vue';
|
||||||
import { MapClass } from '@/components/gis/map.class';
|
import { MapClass } from '@/components/gis/map.class';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// ==================== 组件基础配置 ====================
|
// ==================== 组件基础配置 ====================
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -96,7 +98,7 @@ const modalVisible = ref(false); // 弹框显示状态
|
|||||||
const clickDataInfo = ref<any>(null); // 点击的数据点信息
|
const clickDataInfo = ref<any>(null); // 点击的数据点信息
|
||||||
const stationName = ref(''); // 站点名称
|
const stationName = ref(''); // 站点名称
|
||||||
// ==================== 数据处理函数 ====================
|
// ==================== 数据处理函数 ====================
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
/**
|
/**
|
||||||
* 转换图表数据格式
|
* 转换图表数据格式
|
||||||
* 将后端返回的扁平数据结构转换为ECharts所需的双线数据格式
|
* 将后端返回的扁平数据结构转换为ECharts所需的双线数据格式
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<SidePanelItem
|
<SidePanelItem
|
||||||
title="典型设施介绍"
|
title="典型设施介绍"
|
||||||
:select="selectConfig"
|
:select="selectConfig"
|
||||||
@update-values="handlePanelChange"
|
@update-values="handlePanelChange"
|
||||||
>
|
>
|
||||||
<a-spin :spinning="loading">
|
<a-spin :spinning="loading">
|
||||||
@ -51,9 +51,9 @@
|
|||||||
<a-empty v-else description="暂无数据" />
|
<a-empty v-else description="暂无数据" />
|
||||||
</a-spin>
|
</a-spin>
|
||||||
</SidePanelItem>
|
</SidePanelItem>
|
||||||
|
|
||||||
<!-- 设施详情弹框 -->
|
<!-- 设施详情弹框 -->
|
||||||
<a-modal v-model:open="modalVisible" :title="'设施详情'" width="1536px" :footer="null">
|
<a-modal v-model:open="modalVisibleone" :title="'设施详情'" width="1536px" :footer="null">
|
||||||
<div v-if="currentItem" class="detail-container">
|
<div v-if="currentItem" class="detail-container">
|
||||||
<ArtsDetail :dataSource="currentItem" :index="getCurrentRealIndex()" />
|
<ArtsDetail :dataSource="currentItem" :index="getCurrentRealIndex()" />
|
||||||
</div>
|
</div>
|
||||||
@ -66,6 +66,7 @@ import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
|||||||
import ArtsDetail from '@/components/carouselIntroduce/ArtsDetail.vue';
|
import ArtsDetail from '@/components/carouselIntroduce/ArtsDetail.vue';
|
||||||
import { getMsstbprptKendoList } from '@/api/home';
|
import { getMsstbprptKendoList } from '@/api/home';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -84,9 +85,9 @@ interface MediaItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 弹框控制
|
// 弹框控制
|
||||||
const modalVisible = ref(false);
|
const modalVisibleone = ref(false);
|
||||||
const currentItem = ref<any>(null);
|
const currentItem = ref<any>(null);
|
||||||
|
useDraggable(modalVisibleone, { boundary: true, resetOnOpen: true });
|
||||||
// 加载状态
|
// 加载状态
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
@ -217,7 +218,7 @@ const handleItemClick = () => {
|
|||||||
description: item.description || '',
|
description: item.description || '',
|
||||||
title: item.title || ''
|
title: item.title || ''
|
||||||
}));
|
}));
|
||||||
modalVisible.value = true;
|
modalVisibleone.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理下拉选择变化
|
// 处理下拉选择变化
|
||||||
|
|||||||
@ -36,6 +36,8 @@ import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
|||||||
import { dwInfoGetKendoListCust } from "@/api/sw";
|
import { dwInfoGetKendoListCust } from "@/api/sw";
|
||||||
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
||||||
import DiwenshuijianhuansheshileixingzuchengjijieruqingkuangTwoLayers from "./TwoLayers/diwenshuijianhuansheshileixingzuchengjijieruqingkuangTwoLayers.vue"
|
import DiwenshuijianhuansheshileixingzuchengjijieruqingkuangTwoLayers from "./TwoLayers/diwenshuijianhuansheshileixingzuchengjijieruqingkuangTwoLayers.vue"
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -73,7 +75,7 @@ const baseid = ref('')
|
|||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const selectedItem: any = ref<DataString | null>(null);
|
const selectedItem: any = ref<DataString | null>(null);
|
||||||
const twoLayersRef = ref();
|
const twoLayersRef = ref();
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
|
|
||||||
const getListData = async () => {
|
const getListData = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
|||||||
@ -68,6 +68,8 @@ import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
|||||||
import { fishDicGetKendoList, wbsbGetKendoList } from '@/api/yldc';
|
import { fishDicGetKendoList, wbsbGetKendoList } from '@/api/yldc';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import ArtsDetail from '@/components/carouselIntroduce/ArtsDetail.vue';
|
import ArtsDetail from '@/components/carouselIntroduce/ArtsDetail.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'zengZhiZhanJieShaoMod'
|
name: 'zengZhiZhanJieShaoMod'
|
||||||
@ -87,7 +89,7 @@ let rvcd = ref('');
|
|||||||
// 弹框控制
|
// 弹框控制
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const currentItem = ref<any>(null);
|
const currentItem = ref<any>(null);
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 加载状态
|
// 加载状态
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
|
|||||||
@ -62,6 +62,8 @@ import { ref, onMounted, onUnmounted, computed } from 'vue';
|
|||||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||||
import { msstbprptGetKendoList } from '@/api/yldc';
|
import { msstbprptGetKendoList } from '@/api/yldc';
|
||||||
import ArtsDetail from '@/components/carouselIntroduce/ArtsDetail.vue';
|
import ArtsDetail from '@/components/carouselIntroduce/ArtsDetail.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'zengZhiZhanJieShaoMod'
|
name: 'zengZhiZhanJieShaoMod'
|
||||||
@ -79,7 +81,7 @@ const baseUrl = import.meta.env.VITE_APP_ATTACHMENT_URL;
|
|||||||
// 弹框控制
|
// 弹框控制
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const currentItem = ref<any>(null);
|
const currentItem = ref<any>(null);
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 加载状态
|
// 加载状态
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
|
|||||||
@ -36,6 +36,8 @@ import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
|||||||
import { vmsstbprptGetKendoList } from '@/api/gyss'
|
import { vmsstbprptGetKendoList } from '@/api/gyss'
|
||||||
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
||||||
import FPVDDetailMD from './components/FPVDDetailMD.vue'
|
import FPVDDetailMD from './components/FPVDDetailMD.vue'
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'guoyusheshijiansheqingkuang'
|
name: 'guoyusheshijiansheqingkuang'
|
||||||
@ -81,6 +83,7 @@ const loading = ref(false);
|
|||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const selectedFacility = ref<any>(null);
|
const selectedFacility = ref<any>(null);
|
||||||
const title = ref('');
|
const title = ref('');
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 处理卡片点击事件
|
// 处理卡片点击事件
|
||||||
const handleCardClick = (facility: any) => {
|
const handleCardClick = (facility: any) => {
|
||||||
selectedFacility.value = facility;
|
selectedFacility.value = facility;
|
||||||
|
|||||||
@ -1,201 +1,230 @@
|
|||||||
<!-- SidePanelItem.vue -->
|
<!-- SidePanelItem.vue -->
|
||||||
<template>
|
<template>
|
||||||
<SidePanelItem title="过鱼设施">
|
<SidePanelItem title="过鱼设施">
|
||||||
<a-spin :spinning="loading" tip="加载中...">
|
<a-spin :spinning="loading" tip="加载中...">
|
||||||
<div class="facility-grid">
|
<div class="facility-grid">
|
||||||
<div v-for="facility in facilities" :key="facility.name" class="facility-card"
|
<div
|
||||||
@click="handleFacilityClick(facility)">
|
v-for="facility in facilities"
|
||||||
<div style="width: 60px;height: 62px;display: flex;align-items: center;justify-content: center;">
|
:key="facility.name"
|
||||||
<div class="facility-icon">
|
class="facility-card"
|
||||||
<i style="color: #fff;" :class="facility.icon" type="icon-shengtailiuliang2"></i>
|
@click="handleFacilityClick(facility)"
|
||||||
</div>
|
>
|
||||||
</div>
|
<div
|
||||||
|
style="
|
||||||
<div class="facility-info">
|
width: 60px;
|
||||||
<div class="facility-name">{{ facility.name }}</div>
|
height: 62px;
|
||||||
<div style="font-size: 16px;"> <span class="facility-count">{{ facility.count
|
display: flex;
|
||||||
}}</span><span>座</span></div>
|
align-items: center;
|
||||||
</div>
|
justify-content: center;
|
||||||
</div>
|
"
|
||||||
|
>
|
||||||
|
<div class="facility-icon">
|
||||||
|
<i
|
||||||
|
style="color: #fff"
|
||||||
|
:class="facility.icon"
|
||||||
|
type="icon-shengtailiuliang2"
|
||||||
|
></i>
|
||||||
</div>
|
</div>
|
||||||
</a-spin>
|
</div>
|
||||||
</SidePanelItem>
|
|
||||||
<!-- 弹框 -->
|
<div class="facility-info">
|
||||||
<a-modal v-model:open="modalVisible" :title="'过鱼设施'" :footer="null" width="1536px" @cancel="handleCloseModal">
|
<div class="facility-name">{{ facility.name }}</div>
|
||||||
<ModalPage v-if="currentFacility" :data="currentFacility" :jdId="'all'" />
|
<div style="font-size: 16px">
|
||||||
</a-modal>
|
<span class="facility-count">{{ facility.count }}</span
|
||||||
|
><span>座</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-spin>
|
||||||
|
</SidePanelItem>
|
||||||
|
<!-- 弹框 -->
|
||||||
|
<a-modal
|
||||||
|
v-model:open="modalVisible"
|
||||||
|
:title="'过鱼设施'"
|
||||||
|
:footer="null"
|
||||||
|
width="1536px"
|
||||||
|
@cancel="handleCloseModal"
|
||||||
|
>
|
||||||
|
<ModalPage v-if="currentFacility" :data="currentFacility" :jdId="'all'" />
|
||||||
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
|
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
|
||||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||||
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import { buildGetKendoListCust } from '@/api/gyss';
|
import { buildGetKendoListCust } from '@/api/gyss';
|
||||||
import ModalPage from './ModalPage/index.vue'
|
import ModalPage from './ModalPage/index.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'qixidibaohugongzuokaizhanQK'
|
name: 'qixidibaohugongzuokaizhanQK'
|
||||||
});
|
});
|
||||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
// loading状态
|
// loading状态
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
// 设施数据
|
// 设施数据
|
||||||
const facilities = ref([
|
const facilities = ref([
|
||||||
{
|
{
|
||||||
name: '鱼道',
|
name: '鱼道',
|
||||||
count: 0,
|
count: 0,
|
||||||
icon: 'icon iconfont icon-map-gyssYudao',
|
icon: 'icon iconfont icon-map-gyssYudao',
|
||||||
key: 'FP_1'
|
key: 'FP_1'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '集运鱼系统',
|
name: '集运鱼系统',
|
||||||
count: 0,
|
count: 0,
|
||||||
icon: 'icon iconfont icon-map-gyssJiyunyuxitong',
|
icon: 'icon iconfont icon-map-gyssJiyunyuxitong',
|
||||||
key: 'FP_3'
|
key: 'FP_3'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '升鱼机',
|
name: '升鱼机',
|
||||||
count: 0,
|
count: 0,
|
||||||
icon: 'icon iconfont icon-map-gyssShengyuji',
|
icon: 'icon iconfont icon-map-gyssShengyuji',
|
||||||
key: 'FP_4'
|
key: 'FP_4'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '其他',
|
name: '其他',
|
||||||
count: 0,
|
count: 0,
|
||||||
icon: 'icon iconfont icon-map-gyssQita',
|
icon: 'icon iconfont icon-map-gyssQita',
|
||||||
key: 'FP_5'
|
key: 'FP_5'
|
||||||
},
|
}
|
||||||
|
|
||||||
]);
|
]);
|
||||||
const baseid = ref('')
|
const baseid = ref('');
|
||||||
// 弹框相关状态
|
// 弹框相关状态
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const currentFacility = ref<any>(null);
|
const currentFacility = ref<any>(null);
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
//获取页面数据
|
//获取页面数据
|
||||||
const getData = async () => {
|
const getData = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
let params = {
|
let params = {
|
||||||
"filter": {
|
filter: {
|
||||||
"logic": "and",
|
logic: 'and',
|
||||||
"filters": []
|
filters: []
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
const res = await buildGetKendoListCust(params); //适配监控-VD
|
||||||
|
let data = res?.data?.data || res?.data || [];
|
||||||
|
|
||||||
|
// 重置所有设施的count为0
|
||||||
|
facilities.value.forEach(facility => {
|
||||||
|
facility.count = 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 遍历接口返回的所有数据
|
||||||
|
data.forEach(item => {
|
||||||
|
const matchedFacility = facilities.value.find(
|
||||||
|
facility => facility.key === item.sttpCode
|
||||||
|
);
|
||||||
|
if (matchedFacility) {
|
||||||
|
// 如果在facilities中找到对应的key,累加到该设施
|
||||||
|
matchedFacility.count +=
|
||||||
|
Number(item.built) + Number(item.building) || 0;
|
||||||
|
} else {
|
||||||
|
// 如果没有找到对应的key,累加到FP_5(其他)
|
||||||
|
const otherFacility = facilities.value.find(
|
||||||
|
facility => facility.key === 'FP_5'
|
||||||
|
);
|
||||||
|
if (otherFacility) {
|
||||||
|
otherFacility.count +=
|
||||||
|
Number(item.built) + Number(item.building) || 0;
|
||||||
}
|
}
|
||||||
const res = await buildGetKendoListCust(params); //适配监控-VD
|
}
|
||||||
let data = res?.data?.data || res?.data || [];
|
});
|
||||||
|
} catch (error) {
|
||||||
// 重置所有设施的count为0
|
console.error('获取数据失败:', error);
|
||||||
facilities.value.forEach(facility => {
|
} finally {
|
||||||
facility.count = 0;
|
loading.value = false;
|
||||||
});
|
}
|
||||||
|
};
|
||||||
// 遍历接口返回的所有数据
|
|
||||||
data.forEach(item => {
|
|
||||||
const matchedFacility = facilities.value.find(facility => facility.key === item.sttpCode);
|
|
||||||
if (matchedFacility) {
|
|
||||||
// 如果在facilities中找到对应的key,累加到该设施
|
|
||||||
matchedFacility.count += Number(item.built) + Number(item.building) || 0;
|
|
||||||
} else {
|
|
||||||
// 如果没有找到对应的key,累加到FP_5(其他)
|
|
||||||
const otherFacility = facilities.value.find(facility => facility.key === 'FP_5');
|
|
||||||
if (otherFacility) {
|
|
||||||
otherFacility.count += Number(item.built) + Number(item.building) || 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error('获取数据失败:', error);
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 点击处理函数
|
// 点击处理函数
|
||||||
const handleFacilityClick = (facility: any) => {
|
const handleFacilityClick = (facility: any) => {
|
||||||
currentFacility.value = facility;
|
currentFacility.value = facility;
|
||||||
modalVisible.value = true;
|
modalVisible.value = true;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
// 关闭弹框
|
// 关闭弹框
|
||||||
const handleCloseModal = () => {
|
const handleCloseModal = () => {
|
||||||
modalVisible.value = false;
|
modalVisible.value = false;
|
||||||
currentFacility.value = null;
|
currentFacility.value = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => JidiSelectEventStore.selectedItem,
|
() => JidiSelectEventStore.selectedItem,
|
||||||
(newVal) => {
|
newVal => {
|
||||||
baseid.value = newVal.wbsCode;
|
baseid.value = newVal.wbsCode;
|
||||||
getData()
|
getData();
|
||||||
},
|
},
|
||||||
{ deep: true, immediate: true }
|
{ deep: true, immediate: true }
|
||||||
);
|
);
|
||||||
// 页面加载时执行
|
// 页面加载时执行
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 延迟初始化,确保容器已渲染
|
// 延迟初始化,确保容器已渲染
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 组件卸载时清理
|
// 组件卸载时清理
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {});
|
||||||
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.facility-grid {
|
.facility-grid {
|
||||||
width: 406px;
|
width: 406px;
|
||||||
flex-flow: wrap;
|
flex-flow: wrap;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
|
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
|
||||||
|
Helvetica Neue, Arial, Noto Sans, sans-serif, Apple Color Emoji,
|
||||||
|
Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
|
||||||
}
|
}
|
||||||
|
|
||||||
.facility-card {
|
.facility-card {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
height: 70px;
|
height: 70px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin: 4px 0px;
|
margin: 4px 0px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border: 1px solid #e8e8e8;
|
border: 1px solid #e8e8e8;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.facility-icon {
|
.facility-icon {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
// margin-right: 8px;
|
// margin-right: 8px;
|
||||||
background: #5389b5;
|
background: #5389b5;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
|
||||||
.anticon {
|
.anticon {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.facility-info {
|
.facility-info {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.facility-name {
|
.facility-name {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: #333;
|
color: #333;
|
||||||
// margin-bottom: 4px;
|
// margin-bottom: 4px;
|
||||||
// font-weight: 500;
|
// font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.facility-count {
|
.facility-count {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
color: #2f6b98;
|
color: #2f6b98;
|
||||||
// font-weight: 600;
|
// font-weight: 600;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,76 +1,102 @@
|
|||||||
<!-- SidePanelItem.vue -->
|
<!-- SidePanelItem.vue -->
|
||||||
<template>
|
<template>
|
||||||
<SidePanelItem title="过鱼设施介绍">
|
<SidePanelItem title="过鱼设施介绍">
|
||||||
<!-- Loading 和空状态容器 -->
|
<!-- Loading 和空状态容器 -->
|
||||||
<a-spin :spinning="loading" class="carousel-container-wrapper">
|
<a-spin :spinning="loading" class="carousel-container-wrapper">
|
||||||
<div v-if="hasData" class="container" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
|
<div
|
||||||
<!-- 跑马灯轨道容器 -->
|
v-if="hasData"
|
||||||
<div class="carousel-track" :class="{ 'no-transition': isTransitioning }"
|
class="container"
|
||||||
:style="{ transform: `translateX(-${currentIndex * 100}%)` }">
|
@mouseenter="handleMouseEnter"
|
||||||
<!-- 遍历所有媒体项(包含克隆项) -->
|
@mouseleave="handleMouseLeave"
|
||||||
<div v-for="(item, index) in renderMediaData" :key="index" class="carousel-item"
|
>
|
||||||
@click="handleItemClick(originalMediaData)">
|
<!-- 跑马灯轨道容器 -->
|
||||||
<!-- 图片 -->
|
<div
|
||||||
<img :src="item.url" :alt="item.stnm" loading="lazy" />
|
class="carousel-track"
|
||||||
<!-- 说明文字(随媒体项移动) -->
|
:class="{ 'no-transition': isTransitioning }"
|
||||||
<div class="text">{{ item.stnm }}</div>
|
:style="{ transform: `translateX(-${currentIndex * 100}%)` }"
|
||||||
</div>
|
>
|
||||||
</div>
|
<!-- 遍历所有媒体项(包含克隆项) -->
|
||||||
|
<div
|
||||||
<!-- 面板指示器(固定在底部右侧) -->
|
v-for="(item, index) in renderMediaData"
|
||||||
<div class="pagination-dots-fixed">
|
:key="index"
|
||||||
<span v-for="(dot, index) in originalMediaData" :key="index" class="dot"
|
class="carousel-item"
|
||||||
:class="{ active: currentRealIndex === index }" @click="goToSlide(index)"></span>
|
@click="handleItemClick(originalMediaData)"
|
||||||
</div>
|
>
|
||||||
</div>
|
<!-- 图片 -->
|
||||||
<!-- 暂无数据状态 -->
|
<img :src="item.url" :alt="item.stnm" loading="lazy" />
|
||||||
|
<!-- 说明文字(随媒体项移动) -->
|
||||||
<!-- 独立的文字说明区域(随跑马灯切换而变化) -->
|
<div class="text">{{ item.stnm }}</div>
|
||||||
<div v-if="hasData" class="description-text" @click="handleItemClick(originalMediaData)">
|
</div>
|
||||||
{{ currentDescription }}
|
|
||||||
</div>
|
|
||||||
<a-empty v-else description="暂无数据" :image="simpleImage" />
|
|
||||||
</a-spin>
|
|
||||||
</SidePanelItem>
|
|
||||||
<!-- 设施详情弹框 -->
|
|
||||||
<a-modal v-model:open="modalVisible" :title="'设施类型介绍'" width="1536px" :footer="null">
|
|
||||||
<!-- 你在这里编写弹框内容 -->
|
|
||||||
<div v-if="currentItem">
|
|
||||||
<ArtsDetail :dataSource='currentItem' :index="getCurrentRealIndex()" />
|
|
||||||
</div>
|
</div>
|
||||||
</a-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
<!-- 面板指示器(固定在底部右侧) -->
|
||||||
|
<div class="pagination-dots-fixed">
|
||||||
|
<span
|
||||||
|
v-for="(dot, index) in originalMediaData"
|
||||||
|
:key="index"
|
||||||
|
class="dot"
|
||||||
|
:class="{ active: currentRealIndex === index }"
|
||||||
|
@click="goToSlide(index)"
|
||||||
|
></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 暂无数据状态 -->
|
||||||
|
|
||||||
|
<!-- 独立的文字说明区域(随跑马灯切换而变化) -->
|
||||||
|
<div
|
||||||
|
v-if="hasData"
|
||||||
|
class="description-text"
|
||||||
|
@click="handleItemClick(originalMediaData)"
|
||||||
|
>
|
||||||
|
{{ currentDescription }}
|
||||||
|
</div>
|
||||||
|
<a-empty v-else description="暂无数据" :image="simpleImage" />
|
||||||
|
</a-spin>
|
||||||
|
</SidePanelItem>
|
||||||
|
<!-- 设施详情弹框 -->
|
||||||
|
<a-modal
|
||||||
|
v-model:open="modalVisible"
|
||||||
|
:title="'设施类型介绍'"
|
||||||
|
width="1536px"
|
||||||
|
:footer="null"
|
||||||
|
>
|
||||||
|
<!-- 你在这里编写弹框内容 -->
|
||||||
|
<div v-if="currentItem">
|
||||||
|
<ArtsDetail :dataSource="currentItem" :index="getCurrentRealIndex()" />
|
||||||
|
</div>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, onMounted, onUnmounted, computed, watch } from 'vue';
|
import { ref, onMounted, onUnmounted, computed, watch } from 'vue';
|
||||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||||
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import { fpVmsstbprptGetKendoList } from '@/api/gyss';
|
import { fpVmsstbprptGetKendoList } from '@/api/gyss';
|
||||||
import ArtsDetail from '@/components/carouselIntroduce/ArtsDetail.vue';
|
import ArtsDetail from '@/components/carouselIntroduce/ArtsDetail.vue';
|
||||||
import { Empty } from 'ant-design-vue';
|
import { Empty } from 'ant-design-vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// ==================== 类型定义 ====================
|
// ==================== 类型定义 ====================
|
||||||
interface MediaItem {
|
interface MediaItem {
|
||||||
url: string;
|
url: string;
|
||||||
stnm: string;
|
stnm: string;
|
||||||
introduce: string;
|
introduce: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CarouselConfig {
|
interface CarouselConfig {
|
||||||
autoPlayInterval: number;
|
autoPlayInterval: number;
|
||||||
transitionDuration: number;
|
transitionDuration: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== 常量配置 ====================
|
// ==================== 常量配置 ====================
|
||||||
const CAROUSEL_CONFIG: CarouselConfig = {
|
const CAROUSEL_CONFIG: CarouselConfig = {
|
||||||
autoPlayInterval: 4000, // 自动轮播间隔 4秒
|
autoPlayInterval: 4000, // 自动轮播间隔 4秒
|
||||||
transitionDuration: 500 // 过渡动画时长 500ms
|
transitionDuration: 500 // 过渡动画时长 500ms
|
||||||
};
|
};
|
||||||
|
|
||||||
// ==================== Store 和基础配置 ====================
|
// ==================== Store 和基础配置 ====================
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'ZhiWuYuanJianSheJiJieRuQingKuangBar'
|
name: 'ZhiWuYuanJianSheJiJieRuQingKuangBar'
|
||||||
});
|
});
|
||||||
|
|
||||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
@ -79,6 +105,7 @@ const baseUrl = import.meta.env.VITE_APP_ATTACHMENT_URL;
|
|||||||
// 弹框控制
|
// 弹框控制
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const currentItem = ref<any>(null);
|
const currentItem = ref<any>(null);
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// ==================== 数据状态 ====================
|
// ==================== 数据状态 ====================
|
||||||
// 加载状态
|
// 加载状态
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
@ -108,37 +135,37 @@ let autoPlayTimer: ReturnType<typeof setInterval> | null = null;
|
|||||||
* 结构:[最后一项克隆, 原始数据..., 第一项克隆]
|
* 结构:[最后一项克隆, 原始数据..., 第一项克隆]
|
||||||
*/
|
*/
|
||||||
const renderMediaData = computed<MediaItem[]>(() => {
|
const renderMediaData = computed<MediaItem[]>(() => {
|
||||||
const length = originalMediaData.value.length;
|
const length = originalMediaData.value.length;
|
||||||
if (length === 0) return [];
|
if (length === 0) return [];
|
||||||
|
|
||||||
return [
|
return [
|
||||||
originalMediaData.value[length - 1], // 克隆最后一项
|
originalMediaData.value[length - 1], // 克隆最后一项
|
||||||
...originalMediaData.value, // 原始数据
|
...originalMediaData.value, // 原始数据
|
||||||
originalMediaData.value[0] // 克隆第一项
|
originalMediaData.value[0] // 克隆第一项
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前真实的索引(排除克隆项的影响)
|
* 获取当前真实的索引(排除克隆项的影响)
|
||||||
*/
|
*/
|
||||||
const currentRealIndex = computed(() => {
|
const currentRealIndex = computed(() => {
|
||||||
const realLength = originalMediaData.value.length;
|
const realLength = originalMediaData.value.length;
|
||||||
if (realLength === 0) return 0;
|
if (realLength === 0) return 0;
|
||||||
|
|
||||||
let realIndex = currentIndex.value - 1; // 减去克隆的首项偏移
|
let realIndex = currentIndex.value - 1; // 减去克隆的首项偏移
|
||||||
|
|
||||||
// 处理边界情况(无缝循环时的克隆项)
|
// 处理边界情况(无缝循环时的克隆项)
|
||||||
if (realIndex < 0) realIndex = realLength - 1;
|
if (realIndex < 0) realIndex = realLength - 1;
|
||||||
if (realIndex >= realLength) realIndex = 0;
|
if (realIndex >= realLength) realIndex = 0;
|
||||||
|
|
||||||
return realIndex;
|
return realIndex;
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算当前显示的描述文字
|
* 计算当前显示的描述文字
|
||||||
*/
|
*/
|
||||||
const currentDescription = computed(() => {
|
const currentDescription = computed(() => {
|
||||||
return originalMediaData.value[currentRealIndex.value]?.introduce || '';
|
return originalMediaData.value[currentRealIndex.value]?.introduce || '';
|
||||||
});
|
});
|
||||||
|
|
||||||
// ==================== 核心方法 ====================
|
// ==================== 核心方法 ====================
|
||||||
@ -146,280 +173,282 @@ const currentDescription = computed(() => {
|
|||||||
* 启动自动轮播
|
* 启动自动轮播
|
||||||
*/
|
*/
|
||||||
const startAutoPlay = () => {
|
const startAutoPlay = () => {
|
||||||
stopAutoPlay(); // 先清除旧的定时器
|
stopAutoPlay(); // 先清除旧的定时器
|
||||||
autoPlayTimer = setInterval(() => {
|
autoPlayTimer = setInterval(() => {
|
||||||
if (!isHovering.value && !isTransitioning.value) {
|
if (!isHovering.value && !isTransitioning.value) {
|
||||||
nextSlide();
|
nextSlide();
|
||||||
}
|
}
|
||||||
}, CAROUSEL_CONFIG.autoPlayInterval);
|
}, CAROUSEL_CONFIG.autoPlayInterval);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 停止自动轮播
|
* 停止自动轮播
|
||||||
*/
|
*/
|
||||||
const stopAutoPlay = () => {
|
const stopAutoPlay = () => {
|
||||||
if (autoPlayTimer) {
|
if (autoPlayTimer) {
|
||||||
clearInterval(autoPlayTimer);
|
clearInterval(autoPlayTimer);
|
||||||
autoPlayTimer = null;
|
autoPlayTimer = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 切换到下一张
|
* 切换到下一张
|
||||||
*/
|
*/
|
||||||
const nextSlide = () => {
|
const nextSlide = () => {
|
||||||
currentIndex.value++;
|
currentIndex.value++;
|
||||||
|
|
||||||
// 延迟检查是否需要无缝跳转(与transition时间一致)
|
// 延迟检查是否需要无缝跳转(与transition时间一致)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
handleSeamlessLoop();
|
handleSeamlessLoop();
|
||||||
}, CAROUSEL_CONFIG.transitionDuration);
|
}, CAROUSEL_CONFIG.transitionDuration);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理无缝循环(克隆项处理)
|
* 处理无缝循环(克隆项处理)
|
||||||
*/
|
*/
|
||||||
const handleSeamlessLoop = () => {
|
const handleSeamlessLoop = () => {
|
||||||
const realLength = originalMediaData.value.length;
|
const realLength = originalMediaData.value.length;
|
||||||
if (realLength === 0) return;
|
if (realLength === 0) return;
|
||||||
|
|
||||||
// 如果到达克隆的最后一项(索引 = realLength + 1)
|
// 如果到达克隆的最后一项(索引 = realLength + 1)
|
||||||
if (currentIndex.value >= realLength + 1) {
|
if (currentIndex.value >= realLength + 1) {
|
||||||
// 1. 禁用过渡动画,实现瞬间跳转
|
// 1. 禁用过渡动画,实现瞬间跳转
|
||||||
isTransitioning.value = true;
|
isTransitioning.value = true;
|
||||||
|
|
||||||
// 2. 瞬间跳转到真实的第二项(索引1),用户看不到跳变
|
// 2. 瞬间跳转到真实的第二项(索引1),用户看不到跳变
|
||||||
currentIndex.value = 1;
|
currentIndex.value = 1;
|
||||||
|
|
||||||
// 3. 等待两帧后恢复过渡动画(确保DOM已更新)
|
// 3. 等待两帧后恢复过渡动画(确保DOM已更新)
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
isTransitioning.value = false;
|
isTransitioning.value = false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理鼠标进入
|
* 处理鼠标进入
|
||||||
*/
|
*/
|
||||||
const handleMouseEnter = () => {
|
const handleMouseEnter = () => {
|
||||||
isHovering.value = true;
|
isHovering.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理鼠标离开
|
* 处理鼠标离开
|
||||||
*/
|
*/
|
||||||
const handleMouseLeave = () => {
|
const handleMouseLeave = () => {
|
||||||
isHovering.value = false;
|
isHovering.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 跳转到指定幻灯片
|
* 跳转到指定幻灯片
|
||||||
*/
|
*/
|
||||||
const goToSlide = (targetIndex: number) => {
|
const goToSlide = (targetIndex: number) => {
|
||||||
if (isTransitioning.value) return;
|
if (isTransitioning.value) return;
|
||||||
|
|
||||||
// 计算目标索引(考虑克隆项偏移)
|
// 计算目标索引(考虑克隆项偏移)
|
||||||
currentIndex.value = targetIndex + 1;
|
currentIndex.value = targetIndex + 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取轮播图数据
|
* 获取轮播图数据
|
||||||
*/
|
*/
|
||||||
const getCarouselData = async () => {
|
const getCarouselData = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
hasData.value = false;
|
hasData.value = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const params = {
|
const params = {
|
||||||
filter: {
|
filter: {
|
||||||
logic: 'and',
|
logic: 'and',
|
||||||
filters: [
|
filters: [
|
||||||
{
|
{
|
||||||
field: 'sttpFullPath',
|
field: 'sttpFullPath',
|
||||||
operator: 'contains',
|
operator: 'contains',
|
||||||
dataType: 'string',
|
dataType: 'string',
|
||||||
value: 'ENV,ENVP,FP,FP'
|
value: 'ENV,ENVP,FP,FP'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'logo',
|
field: 'logo',
|
||||||
operator: 'isnotnull',
|
operator: 'isnotnull',
|
||||||
dataType: 'string'
|
dataType: 'string'
|
||||||
},
|
},
|
||||||
baseid.value !== 'all' ? {
|
baseid.value !== 'all'
|
||||||
field: 'baseId',
|
? {
|
||||||
operator: 'eq',
|
field: 'baseId',
|
||||||
dataType: 'string',
|
operator: 'eq',
|
||||||
value: baseid.value
|
dataType: 'string',
|
||||||
} : null
|
value: baseid.value
|
||||||
].filter(Boolean)
|
}
|
||||||
},
|
: null
|
||||||
select: ['introduce', 'logo', 'stnm', 'precis'],
|
].filter(Boolean)
|
||||||
sort: [{ field: 'rstcdStepSort', dir: 'asc' }]
|
},
|
||||||
};
|
select: ['introduce', 'logo', 'stnm', 'precis'],
|
||||||
|
sort: [{ field: 'rstcdStepSort', dir: 'asc' }]
|
||||||
|
};
|
||||||
|
|
||||||
const res = await fpVmsstbprptGetKendoList(params);
|
const res = await fpVmsstbprptGetKendoList(params);
|
||||||
const data = res?.data?.data || [];
|
const data = res?.data?.data || [];
|
||||||
|
|
||||||
if (data.length > 0) {
|
if (data.length > 0) {
|
||||||
originalMediaData.value = data.map((item: any) => ({
|
originalMediaData.value = data.map((item: any) => ({
|
||||||
url: item.logo ? `${baseUrl}/?${item.logo}&view=jpg` : '',
|
url: item.logo ? `${baseUrl}/?${item.logo}&view=jpg` : '',
|
||||||
introduce: item.introduce || '',
|
introduce: item.introduce || '',
|
||||||
stnm: item.stnm || ''
|
stnm: item.stnm || ''
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// 重置索引到第一项(跳过克隆的首项)
|
// 重置索引到第一项(跳过克隆的首项)
|
||||||
currentIndex.value = 1;
|
currentIndex.value = 1;
|
||||||
hasData.value = true;
|
hasData.value = true;
|
||||||
} else {
|
} else {
|
||||||
// 无数据时清空
|
// 无数据时清空
|
||||||
originalMediaData.value = [];
|
originalMediaData.value = [];
|
||||||
hasData.value = false;
|
hasData.value = false;
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('获取轮播图数据失败:', error);
|
|
||||||
originalMediaData.value = [];
|
|
||||||
hasData.value = false;
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取轮播图数据失败:', error);
|
||||||
|
originalMediaData.value = [];
|
||||||
|
hasData.value = false;
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ==================== 生命周期 ====================
|
// ==================== 生命周期 ====================
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
startAutoPlay();
|
startAutoPlay();
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
stopAutoPlay();
|
stopAutoPlay();
|
||||||
});
|
});
|
||||||
|
|
||||||
// ==================== 监听器 ====================
|
// ==================== 监听器 ====================
|
||||||
watch(
|
watch(
|
||||||
() => JidiSelectEventStore.selectedItem,
|
() => JidiSelectEventStore.selectedItem,
|
||||||
(newVal) => {
|
newVal => {
|
||||||
if (newVal?.wbsCode) {
|
if (newVal?.wbsCode) {
|
||||||
baseid.value = newVal.wbsCode;
|
baseid.value = newVal.wbsCode;
|
||||||
} else {
|
} else {
|
||||||
baseid.value = 'all';
|
baseid.value = 'all';
|
||||||
}
|
}
|
||||||
getCarouselData();
|
getCarouselData();
|
||||||
},
|
},
|
||||||
{ deep: true, immediate: true }
|
{ deep: true, immediate: true }
|
||||||
);
|
);
|
||||||
// 获取当前真实的索引(排除克隆项的影响)
|
// 获取当前真实的索引(排除克隆项的影响)
|
||||||
const getCurrentRealIndex = () => {
|
const getCurrentRealIndex = () => {
|
||||||
const realLength = originalMediaData.value.length;
|
const realLength = originalMediaData.value.length;
|
||||||
let realIndex = currentIndex.value - 1; // 减去克隆的首项偏移
|
let realIndex = currentIndex.value - 1; // 减去克隆的首项偏移
|
||||||
|
|
||||||
// 处理边界情况(无缝循环时的克隆项)
|
// 处理边界情况(无缝循环时的克隆项)
|
||||||
if (realIndex < 0) realIndex = realLength - 1;
|
if (realIndex < 0) realIndex = realLength - 1;
|
||||||
if (realIndex >= realLength) realIndex = 0;
|
if (realIndex >= realLength) realIndex = 0;
|
||||||
|
|
||||||
return realIndex;
|
return realIndex;
|
||||||
};
|
};
|
||||||
// 处理项目点击事件
|
// 处理项目点击事件
|
||||||
const handleItemClick = (item: any) => {
|
const handleItemClick = (item: any) => {
|
||||||
console.log('轮播图项目被点击:', item, getCurrentRealIndex());
|
console.log('轮播图项目被点击:', item, getCurrentRealIndex());
|
||||||
currentItem.value = item.map((item: any) => ({
|
currentItem.value = item.map((item: any) => ({
|
||||||
url: item.url || '',
|
url: item.url || '',
|
||||||
description: item.introduce || '',
|
description: item.introduce || '',
|
||||||
title: item.stnm || ''
|
title: item.stnm || ''
|
||||||
}));
|
}));
|
||||||
modalVisible.value = true;
|
modalVisible.value = true;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.container {
|
.container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 228px;
|
height: 228px;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden; // 隐藏超出容器的内容
|
overflow: hidden; // 隐藏超出容器的内容
|
||||||
|
|
||||||
// 跑马灯轨道
|
// 跑马灯轨道
|
||||||
.carousel-track {
|
.carousel-track {
|
||||||
display: flex; // 横向排列所有媒体项
|
display: flex; // 横向排列所有媒体项
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
transition: transform 0.5s ease-in-out; // 0.5秒平滑过渡
|
||||||
|
|
||||||
|
// 禁用过渡动画(用于无缝跳转)
|
||||||
|
&.no-transition {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单个媒体项
|
||||||
|
.carousel-item {
|
||||||
|
min-width: 100%; // 每个项目占满容器宽度
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
flex-shrink: 0; // 防止被压缩
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
transition: transform 0.5s ease-in-out; // 0.5秒平滑过渡
|
object-fit: cover; // 保持比例填充
|
||||||
|
}
|
||||||
|
|
||||||
// 禁用过渡动画(用于无缝跳转)
|
.text {
|
||||||
&.no-transition {
|
|
||||||
transition: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 单个媒体项
|
|
||||||
.carousel-item {
|
|
||||||
min-width: 100%; // 每个项目占满容器宽度
|
|
||||||
height: 100%;
|
|
||||||
position: relative;
|
|
||||||
flex-shrink: 0; // 防止被压缩
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover; // 保持比例填充
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 22px;
|
|
||||||
line-height: 22px;
|
|
||||||
background: rgba(0, 0, 0, 0.1);
|
|
||||||
color: #fff;
|
|
||||||
padding-left: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 固定的面板指示器
|
|
||||||
.pagination-dots-fixed {
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 10px;
|
bottom: 0;
|
||||||
right: 10px;
|
left: 0;
|
||||||
display: flex;
|
width: 100%;
|
||||||
gap: 6px;
|
height: 22px;
|
||||||
z-index: 10; // 确保在文字上方
|
line-height: 22px;
|
||||||
|
background: rgba(0, 0, 0, 0.1);
|
||||||
.dot {
|
color: #fff;
|
||||||
width: 5px;
|
padding-left: 10px;
|
||||||
height: 5px;
|
}
|
||||||
border-radius: 50%;
|
|
||||||
background-color: #D8D8D8;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.3s ease;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
background-color: #005293;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 固定的面板指示器
|
||||||
|
.pagination-dots-fixed {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
right: 10px;
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
z-index: 10; // 确保在文字上方
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
width: 5px;
|
||||||
|
height: 5px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #d8d8d8;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: #005293;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 独立的文字说明区域
|
// 独立的文字说明区域
|
||||||
.description-text {
|
.description-text {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
// margin-bottom: 20px;
|
// margin-bottom: 20px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
// 多行文本溢出省略
|
// 多行文本溢出省略
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
-webkit-line-clamp: 2;
|
-webkit-line-clamp: 2;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<!-- SidePanelItem.vue -->
|
<!-- SidePanelItem.vue -->
|
||||||
<template>
|
<template>
|
||||||
<SidePanelItem title="环保设施情况">
|
<SidePanelItem title="环保设施情况">
|
||||||
<a-spin :spinning="loading">
|
<a-spin :spinning="loading">
|
||||||
<div class="facility-grid" v-if="facilities.length > 0">
|
<div class="facility-grid" v-if="facilities.length > 0">
|
||||||
@ -49,6 +49,7 @@ import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
|||||||
import { environmentalProtectionConstruction } from '@/api/home';
|
import { environmentalProtectionConstruction } from '@/api/home';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import HuanbaoModTwoLayers from './TwoLayers/HuanbaoModTwoLayers.vue';
|
import HuanbaoModTwoLayers from './TwoLayers/HuanbaoModTwoLayers.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -82,7 +83,7 @@ const modalRes = ref({
|
|||||||
bldstt: '',
|
bldstt: '',
|
||||||
hydrodtin: '1'
|
hydrodtin: '1'
|
||||||
});
|
});
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 获取数据
|
// 获取数据
|
||||||
const getData = async () => {
|
const getData = async () => {
|
||||||
if (!baseid.value) return;
|
if (!baseid.value) return;
|
||||||
|
|||||||
@ -68,6 +68,7 @@ import svg_liuliangjiancezhan from '@/assets/svg/liuliangjiancezhan.svg';
|
|||||||
import svg_shuizhijiancezhan from '@/assets/svg/shuizhijiancezhan.svg';
|
import svg_shuizhijiancezhan from '@/assets/svg/shuizhijiancezhan.svg';
|
||||||
import svg_zengzhizhanshuizhizhan from '@/assets/svg/zengzhizhanshuizhizhan.svg';
|
import svg_zengzhizhanshuizhizhan from '@/assets/svg/zengzhizhanshuizhizhan.svg';
|
||||||
import svg_qixidi from '@/assets/svg/qixidi.svg';
|
import svg_qixidi from '@/assets/svg/qixidi.svg';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'huanbaoMod'
|
name: 'huanbaoMod'
|
||||||
@ -103,7 +104,7 @@ const baseid = ref('');
|
|||||||
// 弹框相关状态
|
// 弹框相关状态
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const currentFacility = ref<IFacility | null>(null);
|
const currentFacility = ref<IFacility | null>(null);
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
const fetchData = () => {
|
const fetchData = () => {
|
||||||
let params = {
|
let params = {
|
||||||
filter: {
|
filter: {
|
||||||
|
|||||||
@ -316,7 +316,8 @@ import { postIdUrl } from '@/api/mapModal';
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import videoCover from '@/assets/images/videFm.jpg';
|
import videoCover from '@/assets/images/videFm.jpg';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
;
|
||||||
const baseUrl = import.meta.env.VITE_APP_ATTACHMENT_URL;
|
const baseUrl = import.meta.env.VITE_APP_ATTACHMENT_URL;
|
||||||
|
|
||||||
// ==================== Props ====================
|
// ==================== Props ====================
|
||||||
@ -393,11 +394,11 @@ let videoChartInstance: ECharts | null = null;
|
|||||||
// ==================== 日历视图状态 ====================
|
// ==================== 日历视图状态 ====================
|
||||||
const calendarLoading = ref(false);
|
const calendarLoading = ref(false);
|
||||||
const calendarData = ref<any[]>([]);
|
const calendarData = ref<any[]>([]);
|
||||||
const calendarValue = ref(dayjs());
|
const calendarValue = ref(searchData.value.month);
|
||||||
const detailModalVisible = ref(false);
|
const detailModalVisible = ref(false);
|
||||||
const detailActiveKey = ref('2');
|
const detailActiveKey = ref('2');
|
||||||
const detailDate = ref('');
|
const detailDate = ref('');
|
||||||
|
useDraggable(detailModalVisible, { boundary: true, resetOnOpen: true })
|
||||||
// 日历状态映射(运行/未运行)
|
// 日历状态映射(运行/未运行)
|
||||||
const calendarStatusMap: Record<
|
const calendarStatusMap: Record<
|
||||||
string,
|
string,
|
||||||
@ -1293,7 +1294,7 @@ const colStcdData = async () => {
|
|||||||
|
|
||||||
const params = { filter: { logic: 'and', filters } };
|
const params = { filter: { logic: 'and', filters } };
|
||||||
const res: any = await getAiRstcd(params);
|
const res: any = await getAiRstcd(params);
|
||||||
const _data = res?.data?.data?.data ?? [];
|
const _data = res?.data?.data ?? [];
|
||||||
const list = _data.map((item: any) => ({
|
const list = _data.map((item: any) => ({
|
||||||
label: item.stnm,
|
label: item.stnm,
|
||||||
value: item.stcd
|
value: item.stcd
|
||||||
@ -1501,6 +1502,14 @@ watch(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ==================== 监听月份变化,同步日历显示 ====================
|
||||||
|
watch(
|
||||||
|
() => searchData.value.month,
|
||||||
|
(newMonth) => {
|
||||||
|
calendarValue.value = newMonth;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// ==================== 监听 Tab 切换 ====================
|
// ==================== 监听 Tab 切换 ====================
|
||||||
watch(tabIndex, () => {
|
watch(tabIndex, () => {
|
||||||
pieCode.value = [];
|
pieCode.value = [];
|
||||||
|
|||||||
@ -51,6 +51,7 @@ import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
|||||||
import AISPTK from './AISPTK.vue';
|
import AISPTK from './AISPTK.vue';
|
||||||
import { getAiGyssList } from '@/api/zngj';
|
import { getAiGyssList } from '@/api/zngj';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -65,7 +66,7 @@ const panelDetail = ref<any>({});
|
|||||||
// ==================== 弹框状态 ====================
|
// ==================== 弹框状态 ====================
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const currentAction = ref('AI_5006');
|
const currentAction = ref('AI_5006');
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
const lyName = computed(() => baseid.value === '02' ? '升鱼斗运行' : '升鱼机运行');
|
const lyName = computed(() => baseid.value === '02' ? '升鱼斗运行' : '升鱼机运行');
|
||||||
|
|
||||||
// ==================== 日期选择器配置 ====================
|
// ==================== 日期选择器配置 ====================
|
||||||
|
|||||||
@ -40,6 +40,7 @@ import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
|||||||
import SidePanelItem from "@/components/SidePanelItem/index.vue";
|
import SidePanelItem from "@/components/SidePanelItem/index.vue";
|
||||||
import { getStllGaojingList } from '@/api/zngj';
|
import { getStllGaojingList } from '@/api/zngj';
|
||||||
import ModeGaoJing from './ModeGaoJing.vue';
|
import ModeGaoJing from './ModeGaoJing.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -51,7 +52,7 @@ const baseid = ref('');
|
|||||||
const dataLoading = ref(false);
|
const dataLoading = ref(false);
|
||||||
const isModalOpen = ref(false);
|
const isModalOpen = ref(false);
|
||||||
const currentWarnState = ref('');
|
const currentWarnState = ref('');
|
||||||
|
useDraggable(isModalOpen, { boundary: true, resetOnOpen: true });
|
||||||
const data = ref([
|
const data = ref([
|
||||||
{
|
{
|
||||||
name:'正常',
|
name:'正常',
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
|||||||
import SidePanelItem from "@/components/SidePanelItem/index.vue";
|
import SidePanelItem from "@/components/SidePanelItem/index.vue";
|
||||||
import { getShuizhiGaojingList } from '@/api/zngj';
|
import { getShuizhiGaojingList } from '@/api/zngj';
|
||||||
import ModeGaoJing from './ModeGaoJing.vue';
|
import ModeGaoJing from './ModeGaoJing.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "shuizhijianceshuju",
|
name: "shuizhijianceshuju",
|
||||||
@ -51,7 +52,7 @@ const defaultValue = ref<string>('0');
|
|||||||
// 弹框状态
|
// 弹框状态
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const currentWarnState = ref('');
|
const currentWarnState = ref('');
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
const handleCardClick = (warnState: string) => {
|
const handleCardClick = (warnState: string) => {
|
||||||
currentWarnState.value = warnState;
|
currentWarnState.value = warnState;
|
||||||
modalVisible.value = true;
|
modalVisible.value = true;
|
||||||
|
|||||||
@ -68,6 +68,7 @@ import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
|||||||
import LsstjkTk from './LsstjkTk.vue';
|
import LsstjkTk from './LsstjkTk.vue';
|
||||||
import { wbsbGetKendoList, getEvnmAutoMonitor } from '@/api/stdc';
|
import { wbsbGetKendoList, getEvnmAutoMonitor } from '@/api/stdc';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名
|
// 定义组件名
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -81,7 +82,7 @@ const dataLoading = ref(false);
|
|||||||
// ==================== 弹框状态 ====================
|
// ==================== 弹框状态 ====================
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const currentOrderIndex = ref('16');
|
const currentOrderIndex = ref('16');
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// ==================== 响应式变量定义 ====================
|
// ==================== 响应式变量定义 ====================
|
||||||
// 选择器配置
|
// 选择器配置
|
||||||
const select = ref({
|
const select = ref({
|
||||||
|
|||||||
@ -70,6 +70,7 @@ import dayjs from 'dayjs';
|
|||||||
import { ZoomInOutlined } from '@ant-design/icons-vue';
|
import { ZoomInOutlined } from '@ant-design/icons-vue';
|
||||||
import type { Dayjs } from 'dayjs';
|
import type { Dayjs } from 'dayjs';
|
||||||
import MonthlyAverage from '../monthlyAverage.vue';
|
import MonthlyAverage from '../monthlyAverage.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'MonthlyAverageMaxModal'
|
name: 'MonthlyAverageMaxModal'
|
||||||
@ -101,7 +102,7 @@ const detailModalData = ref<any>(null);
|
|||||||
// 选择器相关 - 内部状态管理
|
// 选择器相关 - 内部状态管理
|
||||||
const selectValue = ref('');
|
const selectValue = ref('');
|
||||||
const selectOptions = ref<any[]>([]);
|
const selectOptions = ref<any[]>([]);
|
||||||
|
useDraggable(detailModalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 树形选择器展开状态管理
|
// 树形选择器展开状态管理
|
||||||
const treeExpandedKeys = ref<string[]>([])
|
const treeExpandedKeys = ref<string[]>([])
|
||||||
const nodeMap = new Map<string, { node: any; parentKey: string | null }>()
|
const nodeMap = new Map<string, { node: any; parentKey: string | null }>()
|
||||||
|
|||||||
@ -41,6 +41,7 @@ import dayjs from 'dayjs'
|
|||||||
import {
|
import {
|
||||||
ZoomInOutlined
|
ZoomInOutlined
|
||||||
} from '@ant-design/icons-vue';
|
} from '@ant-design/icons-vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'monthlyAvgWaterTemCompareHistory'
|
name: 'monthlyAvgWaterTemCompareHistory'
|
||||||
@ -68,7 +69,8 @@ const stationName = ref('');
|
|||||||
|
|
||||||
// 图表放大展示弹框状态
|
// 图表放大展示弹框状态
|
||||||
const zoomModalVisible = ref(false);
|
const zoomModalVisible = ref(false);
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
|
useDraggable(zoomModalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 选择器配置
|
// 选择器配置
|
||||||
const select = ref({
|
const select = ref({
|
||||||
show: true,
|
show: true,
|
||||||
|
|||||||
@ -1,206 +1,237 @@
|
|||||||
<!-- SidePanelItem.vue -->
|
<!-- SidePanelItem.vue -->
|
||||||
<template>
|
<template>
|
||||||
<SidePanelItem title="栖息地保护工作开展情况">
|
<SidePanelItem title="栖息地保护工作开展情况">
|
||||||
<a-spin :spinning="loading" tip="加载中...">
|
<a-spin :spinning="loading" tip="加载中...">
|
||||||
<div class="facility-grid">
|
<div class="facility-grid">
|
||||||
<div v-for="facility in facilities" :key="facility.name" class="facility-card"
|
<div
|
||||||
@click="handleFacilityClick(facility)">
|
v-for="facility in facilities"
|
||||||
<div style="width: 60px;height: 62px;display: flex;align-items: center;justify-content: center;">
|
:key="facility.name"
|
||||||
<div class="facility-icon">
|
class="facility-card"
|
||||||
<i style="color: #fff;" :class="facility.icon" type="icon-shengtailiuliang2"></i>
|
@click="handleFacilityClick(facility)"
|
||||||
</div>
|
>
|
||||||
</div>
|
<div
|
||||||
|
style="
|
||||||
<div class="facility-info">
|
width: 60px;
|
||||||
<div class="facility-name">{{ facility.name }}</div>
|
height: 62px;
|
||||||
<div style="font-size: 16px;"> <span class="facility-count">{{ facility.count
|
display: flex;
|
||||||
}}</span><span>个</span></div>
|
align-items: center;
|
||||||
</div>
|
justify-content: center;
|
||||||
</div>
|
"
|
||||||
|
>
|
||||||
|
<div class="facility-icon">
|
||||||
|
<i
|
||||||
|
style="color: #fff"
|
||||||
|
:class="facility.icon"
|
||||||
|
type="icon-shengtailiuliang2"
|
||||||
|
></i>
|
||||||
</div>
|
</div>
|
||||||
</a-spin>
|
</div>
|
||||||
</SidePanelItem>
|
|
||||||
<!-- 弹框 -->
|
<div class="facility-info">
|
||||||
<a-modal v-model:open="modalVisible" :title="'栖息地保护工作开展情况'" :footer="null" width="1536px" @cancel="handleCloseModal">
|
<div class="facility-name">{{ facility.name }}</div>
|
||||||
<QixidiheduanjianceqingkuangEJ v-if="currentFacility" :activeKey="currentFacility.sttpCode" :tabs="facilities"
|
<div style="font-size: 16px">
|
||||||
:baseId="baseid" />
|
<span class="facility-count">{{ facility.count }}</span
|
||||||
</a-modal>
|
><span>个</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-spin>
|
||||||
|
</SidePanelItem>
|
||||||
|
<!-- 弹框 -->
|
||||||
|
<a-modal
|
||||||
|
v-model:open="modalVisible"
|
||||||
|
:title="'栖息地保护工作开展情况'"
|
||||||
|
:footer="null"
|
||||||
|
width="1536px"
|
||||||
|
@cancel="handleCloseModal"
|
||||||
|
>
|
||||||
|
<QixidiheduanjianceqingkuangEJ
|
||||||
|
v-if="currentFacility"
|
||||||
|
:activeKey="currentFacility.sttpCode"
|
||||||
|
:tabs="facilities"
|
||||||
|
:baseId="baseid"
|
||||||
|
/>
|
||||||
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
|
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
|
||||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||||
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import { fhGetKendoListCust } from '@/api/qxd'
|
import { fhGetKendoListCust } from '@/api/qxd';
|
||||||
import QixidiheduanjianceqingkuangEJ from "./qixidiheduanjianceqingkuangEJ/index.vue"
|
import QixidiheduanjianceqingkuangEJ from './qixidiheduanjianceqingkuangEJ/index.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'qixidibaohugongzuokaizhanQK'
|
name: 'qixidibaohugongzuokaizhanQK'
|
||||||
});
|
});
|
||||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
// loading状态
|
// loading状态
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
// 设施数据
|
// 设施数据
|
||||||
const facilities = ref([
|
const facilities = ref([
|
||||||
{
|
{
|
||||||
name: '栖息地',
|
name: '栖息地',
|
||||||
count: 0,
|
count: 0,
|
||||||
icon: 'icon iconfont icon-qixidi',
|
icon: 'icon iconfont icon-qixidi',
|
||||||
sttpCode: 'FH'
|
sttpCode: 'FH'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '水温监测',
|
name: '水温监测',
|
||||||
count: 0,
|
count: 0,
|
||||||
icon: 'icon iconfont icon-diwenshuijianhuan',
|
icon: 'icon iconfont icon-diwenshuijianhuan',
|
||||||
sttpCode: 'WTRV'
|
sttpCode: 'WTRV'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '水文监测',
|
name: '水文监测',
|
||||||
count: 0,
|
count: 0,
|
||||||
icon: 'icon iconfont icon-shuiwen-line',
|
icon: 'icon iconfont icon-shuiwen-line',
|
||||||
sttpCode: 'ZQ'
|
sttpCode: 'ZQ'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '视频监控',
|
name: '视频监控',
|
||||||
count: 0,
|
count: 0,
|
||||||
icon: 'icon iconfont icon-shipinjiankongshebei',
|
icon: 'icon iconfont icon-shipinjiankongshebei',
|
||||||
sttpCode: 'VD'
|
sttpCode: 'VD'
|
||||||
},
|
}
|
||||||
|
|
||||||
]);
|
]);
|
||||||
const baseid = ref('')
|
const baseid = ref('');
|
||||||
// 弹框相关状态
|
// 弹框相关状态
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const currentFacility = ref<any>(null);
|
const currentFacility = ref<any>(null);
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
//获取页面数据
|
//获取页面数据
|
||||||
const getData = async () => {
|
const getData = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
let params = {
|
let params = {
|
||||||
"filter": {
|
filter: {
|
||||||
"logic": "and",
|
logic: 'and',
|
||||||
"filters": [
|
filters: [
|
||||||
baseid.value != 'all' ? {
|
baseid.value != 'all'
|
||||||
"field": "baseId",
|
? {
|
||||||
"operator": "eq",
|
field: 'baseId',
|
||||||
"dataType": "string",
|
operator: 'eq',
|
||||||
"value": baseid.value
|
dataType: 'string',
|
||||||
} : null
|
value: baseid.value
|
||||||
].filter(Boolean)
|
}
|
||||||
},
|
: null
|
||||||
"group": [
|
].filter(Boolean)
|
||||||
{
|
},
|
||||||
"dir": "asc",
|
group: [
|
||||||
"field": "sttpCode"
|
{
|
||||||
}
|
dir: 'asc',
|
||||||
],
|
field: 'sttpCode'
|
||||||
"groupResultFlat": true
|
|
||||||
}
|
}
|
||||||
const res = await fhGetKendoListCust(params); //适配监控-VD
|
],
|
||||||
let data = res?.data?.data || res?.data || [];
|
groupResultFlat: true
|
||||||
|
};
|
||||||
|
const res = await fhGetKendoListCust(params); //适配监控-VD
|
||||||
|
let data = res?.data?.data || res?.data || [];
|
||||||
|
|
||||||
// 根据接口返回的数据更新 facilities 的 count
|
// 根据接口返回的数据更新 facilities 的 count
|
||||||
facilities.value.forEach(facility => {
|
facilities.value.forEach(facility => {
|
||||||
const matchedItem = data.find(item => item.sttpCode === facility.sttpCode);
|
const matchedItem = data.find(
|
||||||
if (matchedItem) {
|
item => item.sttpCode === facility.sttpCode
|
||||||
facility.count = matchedItem.count_sttpCode || 0;
|
);
|
||||||
} else {
|
if (matchedItem) {
|
||||||
facility.count = 0;
|
facility.count = matchedItem.count_sttpCode || 0;
|
||||||
}
|
} else {
|
||||||
});
|
facility.count = 0;
|
||||||
} catch (error) {
|
}
|
||||||
console.error('获取数据失败:', error);
|
});
|
||||||
} finally {
|
} catch (error) {
|
||||||
loading.value = false;
|
console.error('获取数据失败:', error);
|
||||||
}
|
} finally {
|
||||||
}
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
// 点击处理函数
|
// 点击处理函数
|
||||||
const handleFacilityClick = (facility: any) => {
|
const handleFacilityClick = (facility: any) => {
|
||||||
currentFacility.value = facility;
|
currentFacility.value = facility;
|
||||||
modalVisible.value = true;
|
modalVisible.value = true;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
// 关闭弹框
|
// 关闭弹框
|
||||||
const handleCloseModal = () => {
|
const handleCloseModal = () => {
|
||||||
modalVisible.value = false;
|
modalVisible.value = false;
|
||||||
currentFacility.value = null;
|
currentFacility.value = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => JidiSelectEventStore.selectedItem,
|
() => JidiSelectEventStore.selectedItem,
|
||||||
(newVal) => {
|
newVal => {
|
||||||
baseid.value = newVal.wbsCode;
|
baseid.value = newVal.wbsCode;
|
||||||
getData()
|
getData();
|
||||||
},
|
},
|
||||||
{ deep: true, immediate: true }
|
{ deep: true, immediate: true }
|
||||||
);
|
);
|
||||||
// 页面加载时执行
|
// 页面加载时执行
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 延迟初始化,确保容器已渲染
|
// 延迟初始化,确保容器已渲染
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 组件卸载时清理
|
// 组件卸载时清理
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {});
|
||||||
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.facility-grid {
|
.facility-grid {
|
||||||
width: 406px;
|
width: 406px;
|
||||||
flex-flow: wrap;
|
flex-flow: wrap;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
|
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
|
||||||
|
Helvetica Neue, Arial, Noto Sans, sans-serif, Apple Color Emoji,
|
||||||
|
Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
|
||||||
}
|
}
|
||||||
|
|
||||||
.facility-card {
|
.facility-card {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
height: 70px;
|
height: 70px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin: 4px 0px;
|
margin: 4px 0px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border: 1px solid #e8e8e8;
|
border: 1px solid #e8e8e8;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.facility-icon {
|
.facility-icon {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
// margin-right: 8px;
|
// margin-right: 8px;
|
||||||
background: #5389b5;
|
background: #5389b5;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
|
||||||
.anticon {
|
.anticon {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.facility-info {
|
.facility-info {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.facility-name {
|
.facility-name {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: #333;
|
color: #333;
|
||||||
// margin-bottom: 4px;
|
// margin-bottom: 4px;
|
||||||
// font-weight: 500;
|
// font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.facility-count {
|
.facility-count {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
color: #2f6b98;
|
color: #2f6b98;
|
||||||
// font-weight: 600;
|
// font-weight: 600;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -57,6 +57,8 @@ import type { ECharts } from 'echarts';
|
|||||||
import { msstbprptGetKendoList } from '@/api/stll';
|
import { msstbprptGetKendoList } from '@/api/stll';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import STLLXFFS from './TwoLayer/STLLXFFS.vue';
|
import STLLXFFS from './TwoLayer/STLLXFFS.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'xieFangFangShi'
|
name: 'xieFangFangShi'
|
||||||
@ -78,7 +80,7 @@ const apiRawData = ref<any[]>([]); // 保存原始 API 数据
|
|||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const modalTitle = ref('');
|
const modalTitle = ref('');
|
||||||
const selectedData = ref<any>(null);
|
const selectedData = ref<any>(null);
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 颜色配置(根据图片配色)
|
// 颜色配置(根据图片配色)
|
||||||
const colors = [
|
const colors = [
|
||||||
'#9556a4', // 基荷发电 - 紫色
|
'#9556a4', // 基荷发电 - 紫色
|
||||||
|
|||||||
@ -38,6 +38,8 @@ import type { ECharts } from 'echarts';
|
|||||||
import { vmsstbprptGetKendoList } from '@/api/stll';
|
import { vmsstbprptGetKendoList } from '@/api/stll';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import FBQKTwolayer from './TwoLayer/FenBuQingKuangTwoLayer.vue';
|
import FBQKTwolayer from './TwoLayer/FenBuQingKuangTwoLayer.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名
|
// 定义组件名
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'XieFangFenBu'
|
name: 'XieFangFenBu'
|
||||||
@ -59,7 +61,7 @@ const wbsCode = ref('');
|
|||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const selectData = ref(''); // 选中的设施类型名称
|
const selectData = ref(''); // 选中的设施类型名称
|
||||||
const jidiName = ref(''); // 选中的基地名称
|
const jidiName = ref(''); // 选中的基地名称
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 设施类型配置
|
// 设施类型配置
|
||||||
const typeName = [
|
const typeName = [
|
||||||
{ label: '生态放流孔', eqtp: 'EQ_1' },
|
{ label: '生态放流孔', eqtp: 'EQ_1' },
|
||||||
|
|||||||
@ -105,6 +105,8 @@ import { useMapViewStore } from '@/modules/map/stores/map-view.store';
|
|||||||
import STLLXFFS from './TwoLayer/ShengTaiLiuLiangDaBQKTwoLayer.vue';
|
import STLLXFFS from './TwoLayer/ShengTaiLiuLiangDaBQKTwoLayer.vue';
|
||||||
import ModalYkzhbzdjcgz from './TwoLayer/ModalYkzhbzdjcgz.vue';
|
import ModalYkzhbzdjcgz from './TwoLayer/ModalYkzhbzdjcgz.vue';
|
||||||
import HuanbaoZDJCGZKZ from '@/modules/huanbaozdjcgzkzQK/index.vue';
|
import HuanbaoZDJCGZKZ from '@/modules/huanbaozdjcgzkzQK/index.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'shengtaidabiaoMod'
|
name: 'shengtaidabiaoMod'
|
||||||
@ -149,7 +151,8 @@ const modalVisible = ref(false);
|
|||||||
const modalTitle = ref('');
|
const modalTitle = ref('');
|
||||||
const selectedItem = ref<any>(null);
|
const selectedItem = ref<any>(null);
|
||||||
const huanbaoModalVisible = ref(false);
|
const huanbaoModalVisible = ref(false);
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
|
useDraggable(huanbaoModalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 处理电站数量点击事件
|
// 处理电站数量点击事件
|
||||||
const handleStationClick = () => {
|
const handleStationClick = () => {
|
||||||
huanbaoModalVisible.value = true;
|
huanbaoModalVisible.value = true;
|
||||||
|
|||||||
@ -67,6 +67,8 @@ import { eqqecRateCount, evnmAutoMonitorGetKendoListCust } from '@/api/stll';
|
|||||||
import ModalYkzhbzdjcgz from '../shengtaidabiaoMod/TwoLayer/ModalYkzhbzdjcgz.vue';
|
import ModalYkzhbzdjcgz from '../shengtaidabiaoMod/TwoLayer/ModalYkzhbzdjcgz.vue';
|
||||||
import STLLXFFS from './TwoLayer/STLLXFFS.vue'
|
import STLLXFFS from './TwoLayer/STLLXFFS.vue'
|
||||||
import { useMapViewStore } from '@/modules/map/stores/map-view.store';
|
import { useMapViewStore } from '@/modules/map/stores/map-view.store';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'shengtaidabiaoMod'
|
name: 'shengtaidabiaoMod'
|
||||||
@ -604,6 +606,8 @@ watch(
|
|||||||
const detailModalVisible = ref(false);
|
const detailModalVisible = ref(false);
|
||||||
const detailModalTitle = ref('');
|
const detailModalTitle = ref('');
|
||||||
const detailData = ref<any[]>([]);
|
const detailData = ref<any[]>([]);
|
||||||
|
useDraggable(huanbaoModalVisible, { boundary: true, resetOnOpen: true });
|
||||||
|
useDraggable(detailModalVisible, { boundary: true, resetOnOpen: true });
|
||||||
const detailColumns = ref([
|
const detailColumns = ref([
|
||||||
{
|
{
|
||||||
title: mode.value === 'top' ? '基地名称' : '调节性能',
|
title: mode.value === 'top' ? '基地名称' : '调节性能',
|
||||||
|
|||||||
@ -68,6 +68,8 @@ import { eqqecRateCount, evnmAutoMonitorGetKendoListCust } from '@/api/stll';
|
|||||||
import ModalYkzhbzdjcgz from '../shengtaidabiaoMod/TwoLayer/ModalYkzhbzdjcgz.vue';
|
import ModalYkzhbzdjcgz from '../shengtaidabiaoMod/TwoLayer/ModalYkzhbzdjcgz.vue';
|
||||||
import STLLXFFS from './TwoLayer/STLLXFFS.vue'
|
import STLLXFFS from './TwoLayer/STLLXFFS.vue'
|
||||||
import { useMapViewStore } from '@/modules/map/stores/map-view.store';
|
import { useMapViewStore } from '@/modules/map/stores/map-view.store';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'shengtaidabiaoMod'
|
name: 'shengtaidabiaoMod'
|
||||||
@ -97,6 +99,7 @@ const huanbaoModalVisible = ref(false);
|
|||||||
const handleStationClick = () => {
|
const handleStationClick = () => {
|
||||||
huanbaoModalVisible.value = true;
|
huanbaoModalVisible.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 加载数据
|
// 加载数据
|
||||||
const loadData = async () => {
|
const loadData = async () => {
|
||||||
spinning.value = true;
|
spinning.value = true;
|
||||||
@ -633,6 +636,8 @@ const detailColumns = ref([
|
|||||||
watch(mode, () => {
|
watch(mode, () => {
|
||||||
loadData();
|
loadData();
|
||||||
});
|
});
|
||||||
|
useDraggable(huanbaoModalVisible, { boundary: true, resetOnOpen: true });
|
||||||
|
useDraggable(detailModalVisible, { boundary: true, resetOnOpen: true });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -62,6 +62,8 @@ import { ref, onMounted, onUnmounted, computed } from 'vue';
|
|||||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||||
import ArtsDetail from '@/components/carouselIntroduce/ArtsDetail.vue';
|
import ArtsDetail from '@/components/carouselIntroduce/ArtsDetail.vue';
|
||||||
import { sttpbGetKendoList } from '@/api/sw';
|
import { sttpbGetKendoList } from '@/api/sw';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'diwenshuijianhuansheshileixingzuchengjijieruqingkuang'
|
name: 'diwenshuijianhuansheshileixingzuchengjijieruqingkuang'
|
||||||
@ -96,6 +98,7 @@ const isTransitioning = ref(false);
|
|||||||
// 弹框控制
|
// 弹框控制
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const currentItem = ref<any>(null);
|
const currentItem = ref<any>(null);
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 初始化渲染数组(克隆首尾项)
|
// 初始化渲染数组(克隆首尾项)
|
||||||
const initRenderData = () => {
|
const initRenderData = () => {
|
||||||
const length = originalMediaData.value.length;
|
const length = originalMediaData.value.length;
|
||||||
|
|||||||
@ -43,6 +43,7 @@ import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
|||||||
import YaerAverage from './TwoLayers/yaerAverage.vue';
|
import YaerAverage from './TwoLayers/yaerAverage.vue';
|
||||||
|
|
||||||
import { MapClass } from '@/components/gis/map.class';
|
import { MapClass } from '@/components/gis/map.class';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
// 水温年内分布数据(响应式)
|
// 水温年内分布数据(响应式)
|
||||||
@ -52,7 +53,7 @@ const showemit = ref(true);
|
|||||||
// 弹框相关状态
|
// 弹框相关状态
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const currentData = ref<any>({});
|
const currentData = ref<any>({});
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
const chartRef = ref<HTMLElement | null>(null);
|
const chartRef = ref<HTMLElement | null>(null);
|
||||||
let chartInstance: echarts.ECharts | null = null;
|
let chartInstance: echarts.ECharts | null = null;
|
||||||
// 选择器配置
|
// 选择器配置
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import { ref, watch } from 'vue';
|
|||||||
import { getVmsstbprptKendoList } from '@/api/home';
|
import { getVmsstbprptKendoList } from '@/api/home';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import ShuiDianKaiFQKTwoLayer from './TwoLayer/ShuiDianKaiFQKTwoLayer.vue';
|
import ShuiDianKaiFQKTwoLayer from './TwoLayer/ShuiDianKaiFQKTwoLayer.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'DataTable'
|
name: 'DataTable'
|
||||||
@ -43,7 +44,7 @@ const tableData = ref<any[]>([]);
|
|||||||
|
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const modalProps = ref<any>({});
|
const modalProps = ref<any>({});
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
const openDialog = (record: any) => {
|
const openDialog = (record: any) => {
|
||||||
const currentJidiInfo = JidiSelectEventStore.selectedItem;
|
const currentJidiInfo = JidiSelectEventStore.selectedItem;
|
||||||
const isAll = currentJidiInfo?.wbsCode === 'all';
|
const isAll = currentJidiInfo?.wbsCode === 'all';
|
||||||
|
|||||||
@ -68,6 +68,7 @@ import SsstdcgkTk from './SsstdcgkTk.vue';
|
|||||||
import { wbsbGetKendoList, getDftYear, getWeFisht } from '@/api/stdc';
|
import { wbsbGetKendoList, getDftYear, getWeFisht } from '@/api/stdc';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { Label } from 'cesium';
|
import { Label } from 'cesium';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名
|
// 定义组件名
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -80,7 +81,7 @@ const dataLoading = ref(false);
|
|||||||
|
|
||||||
// ==================== 弹框状态 ====================
|
// ==================== 弹框状态 ====================
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// ==================== 响应式变量定义 ====================
|
// ==================== 响应式变量定义 ====================
|
||||||
// 选择器配置
|
// 选择器配置
|
||||||
const select = ref({
|
const select = ref({
|
||||||
|
|||||||
@ -40,6 +40,8 @@ import SidePanelItem from "@/components/SidePanelItem/index.vue";
|
|||||||
import { getKendoListCust, baseEvnmAutoMonitorGetKendoListCust } from "@/api/sw";
|
import { getKendoListCust, baseEvnmAutoMonitorGetKendoListCust } from "@/api/sw";
|
||||||
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
||||||
import ShuiwenjiancegongzuoEJ from "./shuiwenjiancegongzuoEJ.vue"
|
import ShuiwenjiancegongzuoEJ from "./shuiwenjiancegongzuoEJ.vue"
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -68,7 +70,7 @@ const loading = ref(false);
|
|||||||
// 弹框相关状态
|
// 弹框相关状态
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
const currentFacility = ref<any>(null);
|
const currentFacility = ref<any>(null);
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 点击处理函数
|
// 点击处理函数
|
||||||
const handleFacilityClick = (facility: any) => {
|
const handleFacilityClick = (facility: any) => {
|
||||||
// console.log(facility);
|
// console.log(facility);
|
||||||
|
|||||||
@ -33,6 +33,8 @@ import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
|||||||
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
||||||
import { msstbprptGetKendoList } from '@/api/sz'
|
import { msstbprptGetKendoList } from '@/api/sz'
|
||||||
import ShuiwenjiancegongzuoEJ from "./shuiwenjiancegongzuoEJ.vue"
|
import ShuiwenjiancegongzuoEJ from "./shuiwenjiancegongzuoEJ.vue"
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'shuizhijiancegongzuoQK'
|
name: 'shuizhijiancegongzuoQK'
|
||||||
@ -74,7 +76,7 @@ const modalVisible = ref(false);
|
|||||||
const currentFacility = ref<any>(null);
|
const currentFacility = ref<any>(null);
|
||||||
const baseid = ref("")
|
const baseid = ref("")
|
||||||
|
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
//获取水质监测工作开展情况数据
|
//获取水质监测工作开展情况数据
|
||||||
const getDataList = async () => {
|
const getDataList = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
|||||||
@ -460,9 +460,7 @@ const getSelectConfig = async () => {
|
|||||||
return indexA - indexB;
|
return indexA - indexB;
|
||||||
});
|
});
|
||||||
select.value.options = filterSelectOptions(dataMapNameArr);
|
select.value.options = filterSelectOptions(dataMapNameArr);
|
||||||
if (baseid.value === 'all') {
|
if (filterSelectOptions(dataMapNameArr)[0]?.children) {
|
||||||
select.value.value = 'SJLY1U';
|
|
||||||
} else if (filterSelectOptions(dataMapNameArr)[0]?.children) {
|
|
||||||
select.value.value =
|
select.value.value =
|
||||||
filterSelectOptions(dataMapNameArr)[0]?.children[0]?.value;
|
filterSelectOptions(dataMapNameArr)[0]?.children[0]?.value;
|
||||||
} else if (filterSelectOptions(dataMapNameArr)[0]?.value) {
|
} else if (filterSelectOptions(dataMapNameArr)[0]?.value) {
|
||||||
|
|||||||
@ -396,6 +396,7 @@ import { postIdUrl } from '@/api/mapModal';
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import videoCover from '@/assets/images/videFm.jpg';
|
import videoCover from '@/assets/images/videFm.jpg';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
const baseUrl = import.meta.env.VITE_APP_ATTACHMENT_URL;
|
const baseUrl = import.meta.env.VITE_APP_ATTACHMENT_URL;
|
||||||
|
|
||||||
@ -469,7 +470,7 @@ let videoChartInstance: ECharts | null = null;
|
|||||||
// ==================== 日历视图状态 ====================
|
// ==================== 日历视图状态 ====================
|
||||||
const calendarLoading = ref(false);
|
const calendarLoading = ref(false);
|
||||||
const calendarData = ref<any[]>([]);
|
const calendarData = ref<any[]>([]);
|
||||||
const calendarValue = ref(dayjs());
|
const calendarValue = ref(searchData.value.month);
|
||||||
const detailModalVisible = ref(false);
|
const detailModalVisible = ref(false);
|
||||||
const detailActiveKey = ref('');
|
const detailActiveKey = ref('');
|
||||||
const detailVideoLoading = ref(false);
|
const detailVideoLoading = ref(false);
|
||||||
@ -486,10 +487,10 @@ const detailActiveMedia = ref<{ type: string; src: string }>({
|
|||||||
const detailTabItems = ref<any[]>([]);
|
const detailTabItems = ref<any[]>([]);
|
||||||
const detailDate = ref('');
|
const detailDate = ref('');
|
||||||
const detailType = ref('');
|
const detailType = ref('');
|
||||||
const detailDataType = ref('');
|
const detailDataType = computed(() => detailActiveKey.value);
|
||||||
const qingpiaoModalVisible = ref(false);
|
const qingpiaoModalVisible = ref(false);
|
||||||
const qingpiaoFids = ref<string[]>([]);
|
const qingpiaoFids = ref<string[]>([]);
|
||||||
|
useDraggable(detailModalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 日历状态映射(与React端一致)
|
// 日历状态映射(与React端一致)
|
||||||
const calendarStatusMap: Record<
|
const calendarStatusMap: Record<
|
||||||
string,
|
string,
|
||||||
@ -1378,7 +1379,7 @@ const colStcdData = async () => {
|
|||||||
|
|
||||||
const params = { filter: { logic: 'and', filters } };
|
const params = { filter: { logic: 'and', filters } };
|
||||||
const res: any = await getAiRstcd(params);
|
const res: any = await getAiRstcd(params);
|
||||||
const _data = res?.data?.data?.data ?? [];
|
const _data = res?.data?.data ?? [];
|
||||||
const list = _data.map((item: any) => ({
|
const list = _data.map((item: any) => ({
|
||||||
label: item.stnm,
|
label: item.stnm,
|
||||||
value: item.stcd
|
value: item.stcd
|
||||||
@ -1521,7 +1522,6 @@ const handleCalendarDayClick = async (current: any, dayData: any) => {
|
|||||||
const date = dayjs(current).format('YYYY-MM-DD');
|
const date = dayjs(current).format('YYYY-MM-DD');
|
||||||
const status = dayData.status;
|
const status = dayData.status;
|
||||||
const statusInfo = calendarStatusMap[status];
|
const statusInfo = calendarStatusMap[status];
|
||||||
|
|
||||||
if (!statusInfo) return;
|
if (!statusInfo) return;
|
||||||
|
|
||||||
// 清漂识别直接打开附件预览
|
// 清漂识别直接打开附件预览
|
||||||
@ -1541,7 +1541,6 @@ const handleCalendarDayClick = async (current: any, dayData: any) => {
|
|||||||
// 漂浮物/叠梁门打开视频详情弹窗
|
// 漂浮物/叠梁门打开视频详情弹窗
|
||||||
detailDate.value = date;
|
detailDate.value = date;
|
||||||
detailType.value = statusInfo.type;
|
detailType.value = statusInfo.type;
|
||||||
detailDataType.value = statusInfo.dataType;
|
|
||||||
|
|
||||||
// 设置 Tab 项(与React端一致)
|
// 设置 Tab 项(与React端一致)
|
||||||
if (tabIndex.value === '2') {
|
if (tabIndex.value === '2') {
|
||||||
@ -1593,6 +1592,8 @@ const fetchDetailVideoList = async () => {
|
|||||||
: null,
|
: null,
|
||||||
// type过滤
|
// type过滤
|
||||||
{ field: 'type', operator: 'eq', value: detailType.value },
|
{ field: 'type', operator: 'eq', value: detailType.value },
|
||||||
|
// dataType过滤
|
||||||
|
{ field: 'dataType', operator: 'eq', value: detailDataType.value },
|
||||||
// 时间范围
|
// 时间范围
|
||||||
{
|
{
|
||||||
field: 'tm',
|
field: 'tm',
|
||||||
@ -1826,6 +1827,15 @@ watch(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ==================== 监听月份变化,同步日历显示 ====================
|
||||||
|
watch(
|
||||||
|
() => searchData.value.month,
|
||||||
|
(newMonth) => {
|
||||||
|
calendarValue.value = newMonth;
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// ==================== 监听 Tab 切换 ====================
|
// ==================== 监听 Tab 切换 ====================
|
||||||
watch(tabIndex, () => {
|
watch(tabIndex, () => {
|
||||||
pieCode.value = [];
|
pieCode.value = [];
|
||||||
|
|||||||
@ -50,6 +50,7 @@ import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
|||||||
import AISBTK from './AISBTK.vue';
|
import AISBTK from './AISBTK.vue';
|
||||||
import { getAisbdbyxList } from '@/api/zngj';
|
import { getAisbdbyxList } from '@/api/zngj';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -104,7 +105,7 @@ const handleCardClick = (tabIdx: string) => {
|
|||||||
const handleModalClose = () => {
|
const handleModalClose = () => {
|
||||||
modalVisible.value = false;
|
modalVisible.value = false;
|
||||||
};
|
};
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// ==================== 获取卡片统计数据 ====================
|
// ==================== 获取卡片统计数据 ====================
|
||||||
const getCardData = async () => {
|
const getCardData = async () => {
|
||||||
if (!datetimePicker.value.value || !baseid.value) return;
|
if (!datetimePicker.value.value || !baseid.value) return;
|
||||||
|
|||||||
@ -50,6 +50,8 @@ import {
|
|||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import { MapClass } from '@/components/gis/map.class';
|
import { MapClass } from '@/components/gis/map.class';
|
||||||
import ZengZhiZhanQingKuangTwoLayers from './TwoLayers/ZengZhiZhanQingKuangTwoLayers.vue';
|
import ZengZhiZhanQingKuangTwoLayers from './TwoLayers/ZengZhiZhanQingKuangTwoLayers.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
|
|
||||||
const baseid = ref('');
|
const baseid = ref('');
|
||||||
@ -65,7 +67,7 @@ let chartInstance: ECharts | null = null;
|
|||||||
// 弹窗控制
|
// 弹窗控制
|
||||||
const dialogVisible = ref(false);
|
const dialogVisible = ref(false);
|
||||||
const dialogData = ref<any>(null);
|
const dialogData = ref<any>(null);
|
||||||
|
useDraggable(dialogVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 当前选中的站点选项
|
// 当前选中的站点选项
|
||||||
const selectedOption = computed(() => {
|
const selectedOption = computed(() => {
|
||||||
return select.value.options.find(
|
return select.value.options.find(
|
||||||
|
|||||||
@ -63,6 +63,8 @@ import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
|||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import { msstbprptGetKendoList } from '@/api/zzfl';
|
import { msstbprptGetKendoList } from '@/api/zzfl';
|
||||||
import ArtsDetail from '@/components/carouselIntroduce/ArtsDetail.vue';
|
import ArtsDetail from '@/components/carouselIntroduce/ArtsDetail.vue';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'zengZhiZhanJieShaoMod'
|
name: 'zengZhiZhanJieShaoMod'
|
||||||
@ -103,7 +105,7 @@ const isHovering = ref(false);
|
|||||||
|
|
||||||
// 是否正在切换动画中(用于禁用transition)
|
// 是否正在切换动画中(用于禁用transition)
|
||||||
const isTransitioning = ref(false);
|
const isTransitioning = ref(false);
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 初始化渲染数组(克隆首尾项)
|
// 初始化渲染数组(克隆首尾项)
|
||||||
const initRenderData = () => {
|
const initRenderData = () => {
|
||||||
const length = originalMediaData.value.length;
|
const length = originalMediaData.value.length;
|
||||||
|
|||||||
@ -60,6 +60,8 @@ import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
|||||||
import { overviewGetKendoListCust } from '@/api/zzfl';
|
import { overviewGetKendoListCust } from '@/api/zzfl';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import WholeValuedStationOverviewDetail from "./WholeValuedStationOverviewDetail/index.vue"
|
import WholeValuedStationOverviewDetail from "./WholeValuedStationOverviewDetail/index.vue"
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
// 定义组件名(便于调试和递归)
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'zengzhizhanjiansheyunxing'
|
name: 'zengzhizhanjiansheyunxing'
|
||||||
@ -68,6 +70,7 @@ const JidiSelectEventStore = useJidiSelectEventStore();
|
|||||||
const baseid = ref('');
|
const baseid = ref('');
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const dialogVisible = ref(false);
|
const dialogVisible = ref(false);
|
||||||
|
useDraggable(dialogVisible, { boundary: true, resetOnOpen: true });
|
||||||
const dialogTitle = ref('增殖站概况');
|
const dialogTitle = ref('增殖站概况');
|
||||||
const datetimePicker = ref({
|
const datetimePicker = ref({
|
||||||
show: true,
|
show: true,
|
||||||
|
|||||||
@ -27,6 +27,7 @@ export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => {
|
|||||||
try {
|
try {
|
||||||
baseLoading.value = true;
|
baseLoading.value = true;
|
||||||
const res = await getBaseDropdown({});
|
const res = await getBaseDropdown({});
|
||||||
|
// debugger
|
||||||
if (res.data && Array.isArray(res.data)) {
|
if (res.data && Array.isArray(res.data)) {
|
||||||
const list = [...res.data];
|
const list = [...res.data];
|
||||||
// 直接赋值给 ref,触发响应式更新
|
// 直接赋值给 ref,触发响应式更新
|
||||||
@ -58,10 +59,15 @@ export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 获取电站列表
|
// 获取电站列表
|
||||||
const getEngOption = async (rvcd: string) => {
|
const getEngOption = async (rvcd: string, type: string) => {
|
||||||
try {
|
try {
|
||||||
engLoading.value = true;
|
engLoading.value = true;
|
||||||
const param = rvcd === 'all' ? {} : { reachcd: rvcd };
|
let param:any
|
||||||
|
if (type == 'baseId') {
|
||||||
|
param = rvcd === 'all' ? {} : { baseId: rvcd };
|
||||||
|
} else {
|
||||||
|
param = rvcd === 'all' ? {} : { reachcd: rvcd };
|
||||||
|
}
|
||||||
const res = await getEngInfoDropdown(param);
|
const res = await getEngInfoDropdown(param);
|
||||||
if (res.data && Array.isArray(res.data)) {
|
if (res.data && Array.isArray(res.data)) {
|
||||||
// 直接赋值给 ref
|
// 直接赋值给 ref
|
||||||
|
|||||||
@ -26,21 +26,23 @@ export function useDraggable(
|
|||||||
let cleanup: (() => void) | null = null;
|
let cleanup: (() => void) | null = null;
|
||||||
|
|
||||||
const initDrag = (): (() => void) | null => {
|
const initDrag = (): (() => void) | null => {
|
||||||
const modalContent = document.querySelector(
|
|
||||||
modalSelector
|
|
||||||
) as HTMLElement | null;
|
|
||||||
const dragHandle = document.querySelector(handle) as HTMLElement | null;
|
|
||||||
if (!modalContent || !dragHandle) return null;
|
|
||||||
|
|
||||||
// 重置位置到居中
|
|
||||||
if (resetOnOpen) {
|
if (resetOnOpen) {
|
||||||
modalContent.style.position = '';
|
const modalContents = document.querySelectorAll(
|
||||||
modalContent.style.left = '';
|
modalSelector
|
||||||
modalContent.style.top = '';
|
) as NodeListOf<HTMLElement>;
|
||||||
modalContent.style.margin = '';
|
modalContents.forEach(content => {
|
||||||
modalContent.style.transform = '';
|
if (content.offsetParent !== null) {
|
||||||
|
content.style.position = '';
|
||||||
|
content.style.left = '';
|
||||||
|
content.style.top = '';
|
||||||
|
content.style.margin = '';
|
||||||
|
content.style.transform = '';
|
||||||
|
content.style.width = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let currentModalContent: HTMLElement | null = null;
|
||||||
let isDragging = false;
|
let isDragging = false;
|
||||||
let startX = 0;
|
let startX = 0;
|
||||||
let startY = 0;
|
let startY = 0;
|
||||||
@ -56,19 +58,30 @@ export function useDraggable(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onPointerDown = (e: MouseEvent | TouchEvent) => {
|
const onPointerDown = (e: MouseEvent | TouchEvent) => {
|
||||||
|
const target = e.target instanceof HTMLElement ? e.target : null;
|
||||||
|
const dragHandle = target?.closest(handle) as HTMLElement | null;
|
||||||
|
|
||||||
|
if (!dragHandle) return;
|
||||||
|
|
||||||
|
const modalContent = dragHandle.closest(
|
||||||
|
modalSelector
|
||||||
|
) as HTMLElement | null;
|
||||||
|
if (!modalContent) return;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
e.target instanceof HTMLElement &&
|
target.closest('.ant-modal-close') ||
|
||||||
(e.target.closest('.ant-modal-close') ||
|
target.closest('button') ||
|
||||||
e.target.closest('button') ||
|
target.closest('input') ||
|
||||||
e.target.closest('input') ||
|
target.closest('select') ||
|
||||||
e.target.closest('select') ||
|
target.closest('textarea') ||
|
||||||
e.target.closest('textarea') ||
|
target.closest('a')
|
||||||
e.target.closest('a'))
|
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
isDragging = true;
|
isDragging = true;
|
||||||
|
currentModalContent = modalContent;
|
||||||
|
|
||||||
const rect = modalContent.getBoundingClientRect();
|
const rect = modalContent.getBoundingClientRect();
|
||||||
startLeft = rect.left;
|
startLeft = rect.left;
|
||||||
startTop = rect.top;
|
startTop = rect.top;
|
||||||
@ -76,7 +89,6 @@ export function useDraggable(
|
|||||||
startX = pos.clientX - startLeft;
|
startX = pos.clientX - startLeft;
|
||||||
startY = pos.clientY - startTop;
|
startY = pos.clientY - startTop;
|
||||||
|
|
||||||
// --- 新增:固定宽度 ---
|
|
||||||
const currentWidth = modalContent.offsetWidth;
|
const currentWidth = modalContent.offsetWidth;
|
||||||
modalContent.style.width = currentWidth + 'px';
|
modalContent.style.width = currentWidth + 'px';
|
||||||
|
|
||||||
@ -91,46 +103,63 @@ export function useDraggable(
|
|||||||
document.addEventListener('touchmove', onPointerMove, { passive: false });
|
document.addEventListener('touchmove', onPointerMove, { passive: false });
|
||||||
document.addEventListener('touchend', onPointerUp);
|
document.addEventListener('touchend', onPointerUp);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onPointerMove = (e: MouseEvent | TouchEvent) => {
|
const onPointerMove = (e: MouseEvent | TouchEvent) => {
|
||||||
if (!isDragging) return;
|
if (!isDragging || !currentModalContent) return;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const pos = getPointerPos(e);
|
const pos = getPointerPos(e);
|
||||||
let newLeft = pos.clientX - startX;
|
let newLeft = pos.clientX - startX;
|
||||||
let newTop = pos.clientY - startY;
|
let newTop = pos.clientY - startY;
|
||||||
|
|
||||||
if (boundary) {
|
if (boundary) {
|
||||||
const maxX = window.innerWidth - modalContent.offsetWidth;
|
const maxX = window.innerWidth - currentModalContent.offsetWidth;
|
||||||
const maxY = window.innerHeight - modalContent.offsetHeight;
|
const maxY = window.innerHeight - currentModalContent.offsetHeight;
|
||||||
newLeft = Math.max(0, Math.min(newLeft, maxX));
|
newLeft = Math.max(0, Math.min(newLeft, maxX));
|
||||||
newTop = Math.max(0, Math.min(newTop, maxY));
|
newTop = Math.max(0, Math.min(newTop, maxY));
|
||||||
}
|
}
|
||||||
|
|
||||||
modalContent.style.left = `${newLeft}px`;
|
currentModalContent.style.left = `${newLeft}px`;
|
||||||
modalContent.style.top = `${newTop}px`;
|
currentModalContent.style.top = `${newTop}px`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onPointerUp = () => {
|
const onPointerUp = () => {
|
||||||
|
if (!currentModalContent) return;
|
||||||
isDragging = false;
|
isDragging = false;
|
||||||
modalContent.style.userSelect = '';
|
currentModalContent.style.userSelect = '';
|
||||||
modalContent.style.webkitUserSelect = '';
|
currentModalContent.style.webkitUserSelect = '';
|
||||||
document.removeEventListener('mousemove', onPointerMove);
|
document.removeEventListener('mousemove', onPointerMove);
|
||||||
document.removeEventListener('mouseup', onPointerUp);
|
document.removeEventListener('mouseup', onPointerUp);
|
||||||
document.removeEventListener('touchmove', onPointerMove);
|
document.removeEventListener('touchmove', onPointerMove);
|
||||||
document.removeEventListener('touchend', onPointerUp);
|
document.removeEventListener('touchend', onPointerUp);
|
||||||
|
currentModalContent = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
dragHandle.addEventListener('mousedown', onPointerDown);
|
document.addEventListener('mousedown', onPointerDown);
|
||||||
dragHandle.addEventListener('touchstart', onPointerDown, {
|
document.addEventListener('touchstart', onPointerDown, {
|
||||||
passive: false
|
passive: false
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
dragHandle.removeEventListener('mousedown', onPointerDown);
|
document.removeEventListener('mousedown', onPointerDown);
|
||||||
dragHandle.removeEventListener('touchstart', onPointerDown);
|
document.removeEventListener('touchstart', onPointerDown);
|
||||||
document.removeEventListener('mousemove', onPointerMove);
|
document.removeEventListener('mousemove', onPointerMove);
|
||||||
document.removeEventListener('mouseup', onPointerUp);
|
document.removeEventListener('mouseup', onPointerUp);
|
||||||
document.removeEventListener('touchmove', onPointerMove);
|
document.removeEventListener('touchmove', onPointerMove);
|
||||||
document.removeEventListener('touchend', onPointerUp);
|
document.removeEventListener('touchend', onPointerUp);
|
||||||
|
|
||||||
|
const modalContents = document.querySelectorAll(
|
||||||
|
modalSelector
|
||||||
|
) as NodeListOf<HTMLElement>;
|
||||||
|
modalContents.forEach(content => {
|
||||||
|
content.style.position = '';
|
||||||
|
content.style.left = '';
|
||||||
|
content.style.top = '';
|
||||||
|
content.style.margin = '';
|
||||||
|
content.style.transform = '';
|
||||||
|
content.style.width = '';
|
||||||
|
content.style.userSelect = '';
|
||||||
|
content.style.webkitUserSelect = '';
|
||||||
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,7 @@
|
|||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import { deletePowerInfo } from '@/api/DataQueryMenuModule';
|
import { deletePowerInfo } from '@/api/DataQueryMenuModule';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
@ -72,7 +73,8 @@ const open = (record: any, callback: Function) => {
|
|||||||
dataSourceVisible.value = true;
|
dataSourceVisible.value = true;
|
||||||
onSuccess.value = callback;
|
onSuccess.value = callback;
|
||||||
};
|
};
|
||||||
|
useDraggable(dataSourceVisible, { boundary: true, resetOnOpen: true });
|
||||||
|
useDraggable(confirmVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 修改依据确认
|
// 修改依据确认
|
||||||
const handleDataSourceConfirm = () => {
|
const handleDataSourceConfirm = () => {
|
||||||
dataSourceVisible.value = false;
|
dataSourceVisible.value = false;
|
||||||
|
|||||||
@ -58,6 +58,7 @@ import FishDataSearch from './FishDataSearch.vue';
|
|||||||
import BasicTable from '@/components/BasicTable/index.vue';
|
import BasicTable from '@/components/BasicTable/index.vue';
|
||||||
import { getFishReleaseMonitorList } from '@/api/DataQueryMenuModule';
|
import { getFishReleaseMonitorList } from '@/api/DataQueryMenuModule';
|
||||||
import { calcTableScrollY } from '@/utils/index';
|
import { calcTableScrollY } from '@/utils/index';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
const sort = ref<any>([
|
const sort = ref<any>([
|
||||||
{
|
{
|
||||||
@ -93,7 +94,8 @@ const previewImageUrl = ref('');
|
|||||||
// 视频预览
|
// 视频预览
|
||||||
const videoPreviewVisible = ref(false);
|
const videoPreviewVisible = ref(false);
|
||||||
const previewVideoUrl = ref('');
|
const previewVideoUrl = ref('');
|
||||||
|
useDraggable(imagePreviewVisible, { boundary: true, resetOnOpen: true });
|
||||||
|
useDraggable(videoPreviewVisible, { boundary: true, resetOnOpen: true });
|
||||||
const openImagePreview = (url: string) => {
|
const openImagePreview = (url: string) => {
|
||||||
previewImageUrl.value = import.meta.env.VITE_APP_ATTACHMENT_URL + '/?' + url;
|
previewImageUrl.value = import.meta.env.VITE_APP_ATTACHMENT_URL + '/?' + url;
|
||||||
imagePreviewVisible.value = true;
|
imagePreviewVisible.value = true;
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import RightDrawer from "@/components/RightDrawer/index.vue";
|
|||||||
import HuanbaoMod from "@/modules/huanbaoMod/index.vue" // 环保设施建设情况
|
import HuanbaoMod from "@/modules/huanbaoMod/index.vue" // 环保设施建设情况
|
||||||
import Dianxingcuoshijieshao from "@/modules/dianxingcuoshijieshao/index.vue" // 环保设施建设情况
|
import Dianxingcuoshijieshao from "@/modules/dianxingcuoshijieshao/index.vue" // 环保设施建设情况
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="moduleContent">
|
<div class="moduleContent">
|
||||||
<div class="leftContent">
|
<div class="leftContent">
|
||||||
|
|||||||
@ -279,6 +279,7 @@ import {
|
|||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
import { encrypt } from '@/utils/rsaEncrypt';
|
import { encrypt } from '@/utils/rsaEncrypt';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
// 注册表单数据
|
// 注册表单数据
|
||||||
const registerData = reactive({
|
const registerData = reactive({
|
||||||
@ -510,7 +511,7 @@ const registerRules = {
|
|||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const activeTab = ref('register');
|
const activeTab = ref('register');
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
// 初始化加载集团列表
|
// 初始化加载集团列表
|
||||||
const loadGroupList = async () => {
|
const loadGroupList = async () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -7,12 +7,13 @@ import SSSTDCQK from '@/modules/shuiShengShengTaiDiaoCha/index.vue'; // 水生
|
|||||||
import AlongFishMod from '@/modules/alongFishMod/index.vue'; //沿程鱼类变化情况
|
import AlongFishMod from '@/modules/alongFishMod/index.vue'; //沿程鱼类变化情况
|
||||||
import SSSTDCDB from './shuiShengShengTaiDiaoCha/SSSTDCDB.vue';
|
import SSSTDCDB from './shuiShengShengTaiDiaoCha/SSSTDCDB.vue';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
const modalVisible = ref(false);
|
const modalVisible = ref(false);
|
||||||
|
|
||||||
const currentItem = computed(() => JidiSelectEventStore.selectedItem);
|
const currentItem = computed(() => JidiSelectEventStore.selectedItem);
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
const handleOpenModal = () => {
|
const handleOpenModal = () => {
|
||||||
modalVisible.value = true;
|
modalVisible.value = true;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -226,6 +226,7 @@ import {
|
|||||||
import { Tag } from 'ant-design-vue'; // 确保导入 Tag
|
import { Tag } from 'ant-design-vue'; // 确保导入 Tag
|
||||||
import { getDictItemsByCode } from '@/api/dict';
|
import { getDictItemsByCode } from '@/api/dict';
|
||||||
import { calcTableScrollY } from '@/utils/index';
|
import { calcTableScrollY } from '@/utils/index';
|
||||||
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
const baseUrl = import.meta.env.VITE_APP_ATTACHMENT_URL;
|
const baseUrl = import.meta.env.VITE_APP_ATTACHMENT_URL;
|
||||||
const baseUrlApi = import.meta.env.VITE_APP_BASE_API_URL;
|
const baseUrlApi = import.meta.env.VITE_APP_BASE_API_URL;
|
||||||
@ -324,7 +325,7 @@ const baseColumnsConfig: ColumnConfig[] = [
|
|||||||
// --- 状态定义 ---
|
// --- 状态定义 ---
|
||||||
const visible = ref(false); // 导入预览 Modal
|
const visible = ref(false); // 导入预览 Modal
|
||||||
const editModalRef = ref<any>(null);
|
const editModalRef = ref<any>(null);
|
||||||
|
useDraggable(visible, { boundary: true, resetOnOpen: true });
|
||||||
// 编辑相关状态
|
// 编辑相关状态
|
||||||
const editModalVisible = ref(false);
|
const editModalVisible = ref(false);
|
||||||
const isView = ref(false);
|
const isView = ref(false);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user