智处-防灭火资源表格
parent
0b2697fab4
commit
d76a4d0423
|
|
@ -98,6 +98,7 @@
|
|||
"axios": "^1.6.4",
|
||||
"codemirror": "^5.65.16",
|
||||
"color": "^4.2.3",
|
||||
"coordtransform": "^2.1.2",
|
||||
"cropperjs": "^1.6.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dayjs": "^1.11.10",
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 188 KiB |
|
|
@ -0,0 +1,67 @@
|
|||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { PublicConfigClass } from '@/packages/public'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { chartInitConfig } from '@/settings/designSetting'
|
||||
import { TableFilterConfig } from './index'
|
||||
import dataJson from './data.json'
|
||||
|
||||
const {header, source, filterset} = dataJson;
|
||||
|
||||
export const option = {
|
||||
header: header,
|
||||
dataset: source,
|
||||
filterset: filterset,
|
||||
dataStyle: {
|
||||
colLeft: 4,
|
||||
|
||||
filterMarginTop: 20,
|
||||
filterMarginLeft: 50,
|
||||
filterItemHeight: 45,
|
||||
|
||||
filterTitleAlign: 'left',
|
||||
filterTitleFontSize: 24,
|
||||
filterTitleFontColor: '#ADFFC0',
|
||||
|
||||
filterContentAlign: 'left',
|
||||
filterChooseFontSize: 18,
|
||||
filterChooseFontColor: '#FFFFFF',
|
||||
|
||||
tableMarginTop: 20,
|
||||
tableMarginLeft: 20,
|
||||
tableBordered: false,
|
||||
tableSigleColumn: true,
|
||||
tableSingleLine: true,
|
||||
tableStriped: false,
|
||||
tableSize: 'small',
|
||||
tableAlign: 'center',
|
||||
// 表头
|
||||
tableHeaderShow: false,
|
||||
// 序号
|
||||
orderBumberShow: false,
|
||||
// 操作
|
||||
buttonDivShow: true,
|
||||
buttonDivShow1: true,
|
||||
buttonDivShow2: true,
|
||||
buttonWidth: 22,
|
||||
buttonHeight: 22,
|
||||
// 宽度
|
||||
orderDivWidth: 50,
|
||||
buttonDivWidth: 100,
|
||||
// 字体
|
||||
tableHeaderBackgroud: '#FFFFFF',
|
||||
tableHeaderFontSize: 20,
|
||||
tableHeaderFontColor: '#000000',
|
||||
|
||||
tableDataBackgroudShow: false,
|
||||
tableDataBackgroud: '#FFFFFF',
|
||||
tableDataFontSize: 20,
|
||||
tableDataFontColor: '#FFFFFF',
|
||||
},
|
||||
}
|
||||
|
||||
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||
public key = TableFilterConfig.key
|
||||
public attr = { ...chartInitConfig, w: 1060, h: 570, zIndex: -1 }
|
||||
public chartConfig = cloneDeep(TableFilterConfig)
|
||||
public option = cloneDeep(option)
|
||||
}
|
||||
|
|
@ -0,0 +1,826 @@
|
|||
<template>
|
||||
<!-- 筛选项数据显示设置 -->
|
||||
<CollapseItem name="筛选项数据显示设置" :expanded="true">
|
||||
<span style="font-size: 12px; margin-left: 8px"> 筛选项字段与类型 </span>
|
||||
<div style="overflow-x: auto">
|
||||
<n-table
|
||||
class="go-request-header-table-box"
|
||||
style="margin-top: 12px"
|
||||
:single-line="false"
|
||||
size="small"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>标题名称</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in props.optionData.filterset" :key="index">
|
||||
<td>
|
||||
<n-input v-model:value="item.title" type="text" size="small" />
|
||||
</td>
|
||||
<td>
|
||||
<div style="width: 70px">
|
||||
<n-button
|
||||
class="go-ml-2"
|
||||
type="primary"
|
||||
size="small"
|
||||
ghost
|
||||
@click="
|
||||
props.optionData.filterset.splice(index + 1, 0, {
|
||||
title: null,
|
||||
field: null,
|
||||
compareType: null,
|
||||
showType: null,
|
||||
value: [],
|
||||
options: [{ label: null, value: null }],
|
||||
})
|
||||
"
|
||||
>
|
||||
+
|
||||
</n-button>
|
||||
<n-button
|
||||
class="go-ml-2"
|
||||
type="warning"
|
||||
size="small"
|
||||
ghost
|
||||
:disabled="props.optionData.filterset.length === 1"
|
||||
@click="
|
||||
if (props.optionData.filterset.length !== 1) {
|
||||
props.optionData.filterset.splice(index, 1);
|
||||
}
|
||||
"
|
||||
>
|
||||
-
|
||||
</n-button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</n-table>
|
||||
</div>
|
||||
</CollapseItem>
|
||||
<CollapseItem
|
||||
:expanded="false"
|
||||
v-for="(filtersetItem, filtersetIndex) in optionData.filterset"
|
||||
:key="filtersetIndex"
|
||||
:alone="false"
|
||||
:name="'筛选项【' + filtersetItem.title + '】设置'"
|
||||
>
|
||||
<SettingItem name="筛选类型">
|
||||
<n-select
|
||||
v-model:value="filtersetItem.showType"
|
||||
:options="[
|
||||
{ label: '多选框', value: 'checkbox' },
|
||||
{ label: '单选框', value: 'radio' },
|
||||
{ label: '下拉框', value: 'select' },
|
||||
{ label: '下拉框(多选)', value: 'selectGroup' },
|
||||
{ label: '按钮组', value: 'buttonGroup' },
|
||||
{ label: '按钮组(多选)', value: 'buttonGroupList' },
|
||||
{ label: '列搜索框', value: 'inputSearch' },
|
||||
{ label: '全数据搜索框', value: 'inputSearchAll' },
|
||||
{ label: '时间选择器', value: 'timePicker' },
|
||||
{ label: '时间范围', value: 'timeRange' },
|
||||
{ label: '日期范围', value: 'dateRange' },
|
||||
]"
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="筛选类型"
|
||||
@change="
|
||||
filtersetItem.compareType = null;
|
||||
filtersetItem.value = null;
|
||||
"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem v-if="!['inputSearchAll'].includes(filtersetItem.showType)" name="对应字段">
|
||||
<n-select
|
||||
v-model:value="filtersetItem.field"
|
||||
:options="columnsOptions"
|
||||
size="small"
|
||||
clearable
|
||||
placeholder="对应字段"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="筛选方式">
|
||||
<n-select
|
||||
v-model:value="filtersetItem.compareType"
|
||||
:options="getOptionsByShowType(filtersetItem)"
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="筛选方式"
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
<!-- 默认值,搜索框无默认值 -->
|
||||
<SettingItem
|
||||
v-if="!['inputSearch', 'inputSearchAll'].includes(filtersetItem.showType)"
|
||||
name="默认值"
|
||||
>
|
||||
<!-- 多选框、下拉框(多选)、按钮组 (多选)-->
|
||||
<n-select
|
||||
v-if="['checkbox', 'selectGroup', 'buttonGroupList'].includes(filtersetItem.showType)"
|
||||
v-model:value="filtersetItem.value"
|
||||
:options="filtersetItem.options"
|
||||
multiple
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="默认值"
|
||||
/>
|
||||
<!-- 时间选择器 -->
|
||||
<n-time-picker
|
||||
v-else-if="['timePicker'].includes(filtersetItem.showType)"
|
||||
v-model:formatted-value="filtersetItem.value"
|
||||
value-format="HH:mm:ss"
|
||||
format="HH:mm:ss"
|
||||
size="small"
|
||||
clearable
|
||||
placeholder="默认时间"
|
||||
/>
|
||||
<!-- 时间范围 -->
|
||||
<div v-else-if="['timeRange'].includes(filtersetItem.showType)">
|
||||
<n-time-picker
|
||||
v-model:formatted-value="filtersetItem.value"
|
||||
value-format="HH:mm:ss"
|
||||
format="HH:mm:ss"
|
||||
size="small"
|
||||
clearable
|
||||
placeholder="开始时间"
|
||||
/>
|
||||
<n-time-picker
|
||||
v-model:formatted-value="filtersetItem.value2"
|
||||
value-format="HH:mm:ss"
|
||||
format="HH:mm:ss"
|
||||
size="small"
|
||||
clearable
|
||||
placeholder="结束时间"
|
||||
/>
|
||||
</div>
|
||||
<!-- 日期范围 -->
|
||||
<n-date-picker
|
||||
v-else-if="['dateRange'].includes(filtersetItem.showType)"
|
||||
v-model:formatted-value="filtersetItem.value"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
type="datetimerange"
|
||||
size="small"
|
||||
clearable
|
||||
/>
|
||||
<!-- 其他 -->
|
||||
<n-select
|
||||
v-else
|
||||
v-model:value="filtersetItem.value"
|
||||
:options="filtersetItem.options"
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="默认值"
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
<!-- 搜索框、时间日期框无选项 -->
|
||||
<div style="overflow-x: auto">
|
||||
<n-table
|
||||
v-if="
|
||||
!['inputSearch', 'inputSearchAll', 'timePicker', 'timeRange', 'dateRange'].includes(
|
||||
filtersetItem.showType,
|
||||
)
|
||||
"
|
||||
class="go-request-header-table-box"
|
||||
style="margin-top: 12px"
|
||||
:single-line="false"
|
||||
size="small"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>名称</th>
|
||||
<th>值</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(optionsItem, optionsIndex) in filtersetItem.options" :key="optionsIndex">
|
||||
<td>
|
||||
<n-input
|
||||
v-model:value="optionsItem.label"
|
||||
type="text"
|
||||
size="small"
|
||||
placeholder="名称"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<n-input
|
||||
v-model:value="optionsItem.value"
|
||||
type="text"
|
||||
size="small"
|
||||
placeholder="值"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<div style="width: 70px">
|
||||
<n-button
|
||||
class="go-ml-2"
|
||||
type="primary"
|
||||
size="small"
|
||||
ghost
|
||||
@click="
|
||||
filtersetItem.options.splice(optionsIndex + 1, 0, {
|
||||
label: null,
|
||||
value: null,
|
||||
})
|
||||
"
|
||||
>
|
||||
+
|
||||
</n-button>
|
||||
<n-button
|
||||
class="go-ml-2"
|
||||
type="warning"
|
||||
size="small"
|
||||
ghost
|
||||
:disabled="optionsItem.length === 1"
|
||||
@click="
|
||||
if (filtersetItem.options.length !== 1) {
|
||||
filtersetItem.options.splice(optionsIndex, 1);
|
||||
}
|
||||
"
|
||||
>
|
||||
-
|
||||
</n-button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</n-table>
|
||||
</div>
|
||||
</CollapseItem>
|
||||
|
||||
<br />
|
||||
<!-- 筛选项样式设置 -->
|
||||
<CollapseItem name="筛选项样式设置" :expanded="true">
|
||||
<SettingItemBox :alone="false" name="整体设置">
|
||||
<SettingItem :alone="false" name="上方距离">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.filterMarginTop"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="上方距离"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem :alone="false" name="左右距离">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.filterMarginLeft"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="左右距离"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem :alone="false" name="单个筛选项高度">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.filterItemHeight"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="单个筛选项高度"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="标题对齐方式">
|
||||
<n-select
|
||||
v-model:value="optionData.dataStyle.filterTitleAlign"
|
||||
:options="[
|
||||
{ label: '靠左', value: 'left' },
|
||||
{ label: '居中', value: 'center' },
|
||||
{ label: '靠右', value: 'right' },
|
||||
]"
|
||||
size="small"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="内容对齐方式">
|
||||
<n-select
|
||||
v-model:value="optionData.dataStyle.filterContentAlign"
|
||||
:options="[
|
||||
{ label: '靠左', value: 'left' },
|
||||
{ label: '居中', value: 'center' },
|
||||
{ label: '靠右', value: 'right' },
|
||||
]"
|
||||
size="small"
|
||||
/>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
|
||||
<SettingItemBox :alone="false" name="标题样式">
|
||||
<SettingItem :alone="false" name="标题占比">
|
||||
<n-space vertical>
|
||||
<n-slider v-model:value="optionData.dataStyle.colLeft" :step="1" :min="0" :max="24" />
|
||||
<n-input-number v-model:value="optionData.dataStyle.colLeft" size="small">
|
||||
<template #suffix> / 24 </template>
|
||||
</n-input-number>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
<SettingItemBox :alone="false" name="字体设置">
|
||||
<SettingItem name="筛选标题字体颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.filterTitleFontColor"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="筛选标题字体大小">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.filterTitleFontSize"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="筛选标题字体大小"
|
||||
></n-input-number>
|
||||
</SettingItem>
|
||||
<SettingItem name="筛选内容字体颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.filterChooseFontColor"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="筛选内容字体大小">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.filterChooseFontSize"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="筛选内容字体大小"
|
||||
></n-input-number>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
|
||||
<CollapseItem name="表格数据显示设置" :expanded="true">
|
||||
<span style="font-size: 12px; margin-left: 8px">
|
||||
表格数据(请先确定数据部分,再确定表格数据)
|
||||
</span>
|
||||
<div style="overflow-x: auto">
|
||||
<n-table
|
||||
class="go-request-header-table-box"
|
||||
style="margin-top: 12px"
|
||||
:single-line="false"
|
||||
size="small"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>表头名称</th>
|
||||
<th>表格字段</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in props.optionData.header" :key="index">
|
||||
<td>
|
||||
{{ index + 1 }}
|
||||
</td>
|
||||
<td>
|
||||
<n-input v-model:value="item.title" type="text" size="small" />
|
||||
</td>
|
||||
<td>
|
||||
<n-select v-model:value="item.key" :options="columnsOptions" size="small" />
|
||||
</td>
|
||||
<td>
|
||||
<div style="width: 70px">
|
||||
<n-button class="go-ml-2" type="primary" size="small" ghost @click="add(index)">
|
||||
+
|
||||
</n-button>
|
||||
<n-button
|
||||
class="go-ml-2"
|
||||
type="warning"
|
||||
size="small"
|
||||
ghost
|
||||
:disabled="props.optionData.header.length === 1"
|
||||
@click="remove(index)"
|
||||
>
|
||||
-
|
||||
</n-button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</n-table>
|
||||
</div>
|
||||
|
||||
<SettingItemBox :alone="true" name="表格宽度">
|
||||
<SettingItem :alone="true" name="不包含序列和操作列">
|
||||
<n-input v-model:value="columnsWidths" type="text" size="small" />
|
||||
</SettingItem>
|
||||
<SettingItem :alone="false" name="序列宽度">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.orderDivWidth"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="序列宽度"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem :alone="false" name="操作列宽度">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.buttonDivWidth"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="操作列宽度"
|
||||
/>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
|
||||
<span style="font-size: 12px; margin-left: 8px"> 表格数据(前缀和后缀) </span>
|
||||
<div style="overflow-x: auto">
|
||||
<n-table
|
||||
class="go-request-header-table-box"
|
||||
style="margin-top: 12px"
|
||||
:single-line="false"
|
||||
size="small"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>表头名称</th>
|
||||
<th>前缀</th>
|
||||
<th>后缀</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in props.optionData.header" :key="index">
|
||||
<td>
|
||||
{{ item.title }}
|
||||
</td>
|
||||
<td>
|
||||
<n-input v-model:value="item.prefix" size="small" placeholder="前缀" />
|
||||
</td>
|
||||
<td>
|
||||
<n-input v-model:value="item.suffix" size="small" placeholder="后缀" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</n-table>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<span style="font-size: 12px; margin-left: 8px"> 表格数据(数据格式转换) </span>
|
||||
<div style="overflow-x: auto">
|
||||
<n-table
|
||||
class="go-request-header-table-box"
|
||||
style="margin-top: 12px"
|
||||
:single-line="false"
|
||||
size="small"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>表头名称</th>
|
||||
<th>数据格式转换</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in props.optionData.header" :key="index">
|
||||
<td style="width: 70px">
|
||||
{{ item.title }}
|
||||
</td>
|
||||
<td>
|
||||
<n-select
|
||||
v-model:value="item.convert"
|
||||
:options="[
|
||||
{ label: '小数点保留后两位', value: '0' },
|
||||
{ label: '转换时间格式(例:0小时0分钟0秒)', value: '1' },
|
||||
{ label: '转换日期格式(例:2025-01-01)', value: '2' },
|
||||
{ label: '转换日期格式(例:2025/01/01)', value: '3' },
|
||||
{ label: '转换日期格式(例:2025-01-01 00:00:00)', value: '4' },
|
||||
]"
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="数据格式转换"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</n-table>
|
||||
</div>
|
||||
|
||||
<SettingItemBox :alone="false" name="显示设置">
|
||||
<SettingItem name="是否显示边框">
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.dataStyle.tableBordered" size="small"></n-switch>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
<SettingItem name="是否使用斑马条纹">
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.dataStyle.tableStriped" size="small"></n-switch>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
<SettingItem name="是否不设定行的分割线">
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.dataStyle.tableSigleColumn" size="small"></n-switch>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
<SettingItem name="是否不设定列的分割线">
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.dataStyle.tableSingleLine" size="small"></n-switch>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
|
||||
<SettingItem name="是否显示表头">
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.dataStyle.tableHeaderShow" size="small"></n-switch>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
<SettingItem name="是否显示序号列">
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.dataStyle.orderBumberShow" size="small"></n-switch>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
<SettingItem name="是否显示操作列">
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.dataStyle.buttonDivShow" size="small"></n-switch>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
<SettingItem name="是否显示第一按钮">
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.dataStyle.buttonDivShow1" size="small"></n-switch>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
<SettingItem name="是否显示第二按钮">
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.dataStyle.buttonDivShow2" size="small"></n-switch>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
|
||||
<CollapseItem name="表格样式设置" :expanded="true">
|
||||
<SettingItemBox name="整体设置">
|
||||
<SettingItem name="上方距离">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.tableMarginTop"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="上方距离"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="左右距离">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.tableMarginLeft"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="左右距离"
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
<SettingItem name="对齐方式">
|
||||
<n-select
|
||||
v-model:value="optionData.dataStyle.tableAlign"
|
||||
:options="[
|
||||
{ label: '靠左', value: 'left' },
|
||||
{ label: '居中', value: 'center' },
|
||||
{ label: '靠右', value: 'right' },
|
||||
]"
|
||||
size="small"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="表格尺寸大小">
|
||||
<n-select
|
||||
v-model:value="optionData.dataStyle.tableSize"
|
||||
:options="[
|
||||
{ label: '小', value: 'small' },
|
||||
{ label: '中', value: 'medium' },
|
||||
{ label: '大', value: 'large' },
|
||||
]"
|
||||
size="small"
|
||||
/>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
<SettingItemBox :alone="false" name="表头设置">
|
||||
<SettingItem name="表头背景颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.tableHeaderBackgroud"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="表头字体颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.tableHeaderFontColor"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="表头字体大小">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.tableHeaderFontSize"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="表头字体大小"
|
||||
></n-input-number>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
<SettingItemBox :alone="false" name="表格设置">
|
||||
<SettingItem name="表格背景颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.tableDataBackgroud"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="是否使用表格背景颜色">
|
||||
<n-space>
|
||||
<n-switch
|
||||
v-model:value="optionData.dataStyle.tableDataBackgroudShow"
|
||||
size="small"
|
||||
></n-switch>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
<SettingItem name="表格字体颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.tableDataFontColor"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="表格字体大小">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.tableDataFontSize"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="表格字体大小"
|
||||
></n-input-number>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, watch, ref } from 'vue';
|
||||
import { option } from './config';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting';
|
||||
|
||||
const props = defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<typeof option>,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
// 表格字段
|
||||
const columnsOptions: any = ref([]);
|
||||
watch(
|
||||
() => props.optionData.dataset,
|
||||
() => {
|
||||
// 表格字段
|
||||
const field = Object.keys(props.optionData.dataset[0]);
|
||||
columnsOptions.value = [];
|
||||
field.forEach((item) => {
|
||||
columnsOptions.value.push({
|
||||
label: item,
|
||||
value: item,
|
||||
});
|
||||
});
|
||||
},
|
||||
{
|
||||
deep: false,
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
|
||||
// 新增
|
||||
const add = (index: number) => {
|
||||
props.optionData.header.splice(index + 1, 0, {
|
||||
key: '',
|
||||
title: '',
|
||||
align: props.optionData.dataStyle.tableAlign,
|
||||
width: '200',
|
||||
prefix: null,
|
||||
suffix: null,
|
||||
convert: null,
|
||||
});
|
||||
};
|
||||
|
||||
// 减少
|
||||
const remove = (index: number) => {
|
||||
if (props.optionData.header.length !== 1) {
|
||||
props.optionData.header.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
// 对齐方式
|
||||
watch(
|
||||
() => props.optionData.dataStyle.tableAlign,
|
||||
() => {
|
||||
props.optionData.header.forEach((item) => {
|
||||
item.align = props.optionData.dataStyle.tableAlign;
|
||||
});
|
||||
},
|
||||
);
|
||||
// 表格宽度
|
||||
const columnsWidths: any = ref('');
|
||||
watch(
|
||||
() => props.optionData.header,
|
||||
() => {
|
||||
columnsWidths.value = props.optionData.header.map((item) => item.width).join(',');
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
watch(
|
||||
() => columnsWidths.value,
|
||||
() => {
|
||||
const widths = columnsWidths.value.split(',');
|
||||
props.optionData.header.forEach((item, index) => {
|
||||
item.width = widths[index];
|
||||
});
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
|
||||
// 筛选方式
|
||||
function getOptionsByShowType(filtersetItem) {
|
||||
let result: any = [];
|
||||
if (filtersetItem.showType) {
|
||||
switch (filtersetItem.showType) {
|
||||
case 'checkbox':
|
||||
// 多选框
|
||||
result = [
|
||||
{ label: '等于', value: 'equal' },
|
||||
{ label: '含有', value: 'contain' },
|
||||
];
|
||||
break;
|
||||
case 'radio':
|
||||
// 单选框
|
||||
result = [
|
||||
{ label: '大于', value: 'greater' },
|
||||
{ label: '小于', value: 'less' },
|
||||
{ label: '大于等于', value: 'greaterAndEqual' },
|
||||
{ label: '小于等于', value: 'lessAndEqual' },
|
||||
{ label: '等于', value: 'equal' },
|
||||
{ label: '不等于', value: 'notequal' },
|
||||
{ label: '含有', value: 'contain' },
|
||||
{ label: '不含有', value: 'notcontain' },
|
||||
];
|
||||
break;
|
||||
case 'select':
|
||||
// 下拉框
|
||||
result = [
|
||||
{ label: '等于', value: 'equal' },
|
||||
{ label: '含有', value: 'contain' },
|
||||
];
|
||||
break;
|
||||
case 'selectGroup':
|
||||
// 下拉框(多选)
|
||||
result = [
|
||||
{ label: '等于', value: 'equal' },
|
||||
{ label: '含有', value: 'contain' },
|
||||
];
|
||||
break;
|
||||
case 'buttonGroup':
|
||||
// 按钮组
|
||||
result = [
|
||||
{ label: '等于', value: 'equal' },
|
||||
{ label: '不等于', value: 'notequal' },
|
||||
{ label: '含有', value: 'contain' },
|
||||
{ label: '不含有', value: 'notcontain' },
|
||||
];
|
||||
break;
|
||||
case 'buttonGroupList':
|
||||
// 按钮组(多选)
|
||||
result = [
|
||||
{ label: '等于', value: 'equal' },
|
||||
{ label: '不等于', value: 'notequal' },
|
||||
{ label: '含有', value: 'contain' },
|
||||
{ label: '不含有', value: 'notcontain' },
|
||||
];
|
||||
break;
|
||||
case 'inputSearch':
|
||||
// 列搜索框
|
||||
result = [{ label: '含有', value: 'contain' }];
|
||||
break;
|
||||
case 'inputSearchAll':
|
||||
// 全数据搜索框
|
||||
result = [{ label: '含有', value: 'contain' }];
|
||||
break;
|
||||
case 'timePicker':
|
||||
// 时间选择器
|
||||
result = [
|
||||
{ label: '大于', value: 'greater' },
|
||||
{ label: '小于', value: 'less' },
|
||||
{ label: '大于等于', value: 'greaterAndEqual' },
|
||||
{ label: '小于等于', value: 'lessAndEqual' },
|
||||
{ label: '等于', value: 'equal' },
|
||||
{ label: '不等于', value: 'notequal' },
|
||||
];
|
||||
break;
|
||||
case 'timeRange':
|
||||
// 时间范围
|
||||
result = [{ label: '在两者之间', value: 'between' }];
|
||||
break;
|
||||
case 'dateRange':
|
||||
// 日期范围
|
||||
result = [{ label: '在两者之间', value: 'between' }];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
{
|
||||
"header": [
|
||||
{
|
||||
"title": "名称",
|
||||
"key": "name",
|
||||
"align": "center",
|
||||
"width": "250",
|
||||
"prefix": null,
|
||||
"suffix": null,
|
||||
"convert": null
|
||||
},
|
||||
{
|
||||
"title": "面积",
|
||||
"key": "area",
|
||||
"align": "center",
|
||||
"width": "200",
|
||||
"prefix": null,
|
||||
"suffix": "m²",
|
||||
"convert": null
|
||||
},
|
||||
{
|
||||
"title": "时间",
|
||||
"key": "time",
|
||||
"align": "center",
|
||||
"width": "200",
|
||||
"prefix": null,
|
||||
"suffix": "小时",
|
||||
"convert": "0"
|
||||
},
|
||||
{
|
||||
"title": "路程",
|
||||
"key": "distance",
|
||||
"align": "center",
|
||||
"width": "200",
|
||||
"prefix": "路程",
|
||||
"suffix": "km",
|
||||
"convert": null
|
||||
},
|
||||
{
|
||||
"title": "预计时间",
|
||||
"key": "estimatedTime",
|
||||
"align": "center",
|
||||
"width": "300",
|
||||
"prefix": "预计",
|
||||
"suffix": null,
|
||||
"convert": "1"
|
||||
}
|
||||
],
|
||||
"filterset": [
|
||||
{
|
||||
"title": "地图显示",
|
||||
"field": "type",
|
||||
"compareType": "contain",
|
||||
"showType": "checkbox",
|
||||
"value": [ "水源", "物资", "营房", "防火通道", "三轮通道", "步行道" ],
|
||||
"options": [
|
||||
{ "label": "水源", "value": "水源" },
|
||||
{ "label": "物资", "value": "物资" },
|
||||
{ "label": "营房", "value": "营房" },
|
||||
{ "label": "防火通道", "value": "防火通道" },
|
||||
{ "label": "三轮通道", "value": "三轮通道" },
|
||||
{ "label": "步行道", "value": "步行道" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "资源列表",
|
||||
"field": "type",
|
||||
"compareType": "equal",
|
||||
"showType": "buttonGroup",
|
||||
"value": null,
|
||||
"options": [
|
||||
{ "label": "水源", "value": "水源" },
|
||||
{ "label": "物资", "value": "物资" },
|
||||
{ "label": "营房", "value": "营房" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "重点资源",
|
||||
"field": null,
|
||||
"compareType": null,
|
||||
"showType": null,
|
||||
"value": null,
|
||||
"options": [
|
||||
{ "label": null, "value": null }
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "距离",
|
||||
"field": "distance",
|
||||
"compareType": "lessAndEqual",
|
||||
"showType": "radio",
|
||||
"value": null,
|
||||
"options": [
|
||||
{ "label": "1km以内", "value": "1" },
|
||||
{ "label": "5km以内", "value": "5" },
|
||||
{ "label": "10km以内", "value": "10" },
|
||||
{ "label": "20km以内", "value": "20" },
|
||||
{ "label": "全部", "value": null }
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
{
|
||||
"name": "坑塘",
|
||||
"type": "水源",
|
||||
"area": null,
|
||||
"time": null,
|
||||
"distance": "21.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025-03-01 00:05:45"
|
||||
},
|
||||
{
|
||||
"name": "东蒙布袋口检查",
|
||||
"type": "物资",
|
||||
"area": "300",
|
||||
"time": "12.50",
|
||||
"distance": "14.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025-03-11 00:05:45"
|
||||
},
|
||||
{
|
||||
"name": "北刘家庄蓄水池",
|
||||
"type": "营房",
|
||||
"area": "300",
|
||||
"time": "12.50",
|
||||
"distance": "0.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025/03/01 00:05:45"
|
||||
|
||||
},
|
||||
{
|
||||
"name": "防火通道",
|
||||
"type": "防火通道",
|
||||
"area": null,
|
||||
"time": null,
|
||||
"distance": "2.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025-12-01 00:05:45"
|
||||
},
|
||||
{
|
||||
"name": "步行道",
|
||||
"type": "步行道",
|
||||
"area": "300",
|
||||
"time": "5.50",
|
||||
"distance": "1.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025-08-01 00:05:45"
|
||||
},
|
||||
{
|
||||
"name": "三轮通道",
|
||||
"type": "三轮通道",
|
||||
"area": "300",
|
||||
"time": "9.50",
|
||||
"distance": "5.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025-10-21 00:05:45"
|
||||
},
|
||||
{
|
||||
"name": "坑塘",
|
||||
"type": "水源",
|
||||
"area": null,
|
||||
"time": null,
|
||||
"distance": "10.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025-06-01 00:05:45"
|
||||
},
|
||||
{
|
||||
"name": "东蒙布袋口检查",
|
||||
"type": "物资",
|
||||
"area": "300",
|
||||
"time": "12.50",
|
||||
"distance": "10.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025-06-12 00:05:45"
|
||||
},
|
||||
{
|
||||
"name": "北刘家庄蓄水池",
|
||||
"type": "营房",
|
||||
"area": "300",
|
||||
"time": "12.50",
|
||||
"distance": "19.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025-05-01 00:05:45"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
|
||||
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
|
||||
|
||||
export const TableFilterConfig: ConfigType = {
|
||||
key: 'TableFilter',
|
||||
chartKey: 'VTableFilter',
|
||||
conKey: 'VCTableFilter',
|
||||
title: '自定义筛选表格',
|
||||
category: ChatCategoryEnum.TABLE,
|
||||
categoryName: ChatCategoryEnumName.TABLE,
|
||||
package: PackagesCategoryEnum.TABLES,
|
||||
chartFrame: ChartFrameEnum.COMMON,
|
||||
image: 'table_filter.png'
|
||||
}
|
||||
|
|
@ -0,0 +1,823 @@
|
|||
<template>
|
||||
<div class="TableFilter">
|
||||
<div class="filterDiv">
|
||||
<div class="filterItem" v-for="(item, index) in option.filterset" :key="index">
|
||||
<a-row>
|
||||
<!-- 筛选标题 -->
|
||||
<a-col :span="option.dataStyle.colLeft">
|
||||
<div class="filterTitle">{{ item.title }}</div>
|
||||
</a-col>
|
||||
<!-- 筛选内容 -->
|
||||
<!-- 多选框 -->
|
||||
<a-col :span="24 - option.dataStyle.colLeft" v-if="item.showType == 'checkbox'">
|
||||
<div class="filterContentDiv">
|
||||
<n-checkbox-group v-model:value="item.value">
|
||||
<n-checkbox
|
||||
:style="{
|
||||
marginRight: option.dataStyle.filterTitleFontSize + 'px',
|
||||
}"
|
||||
v-for="(checkboxItem, checkboxIndex) in item.options"
|
||||
:key="checkboxIndex"
|
||||
:value="checkboxItem.value"
|
||||
>
|
||||
<template #default>
|
||||
<span class="filterContentFont">{{ checkboxItem.label }}</span>
|
||||
</template>
|
||||
</n-checkbox>
|
||||
</n-checkbox-group>
|
||||
</div>
|
||||
</a-col>
|
||||
<!-- 单选框 -->
|
||||
<a-col :span="24 - option.dataStyle.colLeft" v-else-if="item.showType == 'radio'">
|
||||
<div class="filterContentDiv">
|
||||
<n-radio-group v-model:value="item.value" name="radiogroup">
|
||||
<n-space>
|
||||
<n-radio
|
||||
:style="{
|
||||
marginRight: option.dataStyle.filterTitleFontSize + 'px',
|
||||
}"
|
||||
v-for="(radioItem, radioIndex) in item.options"
|
||||
:key="radioIndex"
|
||||
:value="radioItem.value"
|
||||
>
|
||||
<span class="filterContentFont">{{ radioItem.label }}</span>
|
||||
</n-radio>
|
||||
</n-space>
|
||||
</n-radio-group>
|
||||
</div>
|
||||
</a-col>
|
||||
<!-- 下拉框 -->
|
||||
<a-col :span="24 - option.dataStyle.colLeft" v-else-if="item.showType == 'select'">
|
||||
<div class="filterContentDiv">
|
||||
<n-select
|
||||
v-model:value="item.value"
|
||||
:options="item.options"
|
||||
:style="{ width: '50%' }"
|
||||
placeholder="请选择选项"
|
||||
clearable
|
||||
/>
|
||||
</div>
|
||||
</a-col>
|
||||
<!-- 下拉框(多选) -->
|
||||
<a-col :span="24 - option.dataStyle.colLeft" v-else-if="item.showType == 'selectGroup'">
|
||||
<div class="filterContentDiv">
|
||||
<n-select
|
||||
v-model:value="item.value"
|
||||
:options="item.options"
|
||||
placeholder="请选择选项(可多选)"
|
||||
clearable
|
||||
multiple
|
||||
/>
|
||||
</div>
|
||||
</a-col>
|
||||
<!-- 按钮组 -->
|
||||
<a-col :span="24 - option.dataStyle.colLeft" v-else-if="item.showType == 'buttonGroup'">
|
||||
<div class="filterContentDiv" style="display: inline-flex">
|
||||
<div
|
||||
:style="{
|
||||
marginRight: option.dataStyle.filterTitleFontSize + 'px',
|
||||
}"
|
||||
v-for="(buttonItem, buttonIndex) in item.options"
|
||||
:key="buttonIndex"
|
||||
:class="
|
||||
item.value == buttonItem.value
|
||||
? 'filterContentFont_choose'
|
||||
: 'filterContentFont_nochoose'
|
||||
"
|
||||
@click="clickFilterButton(item, buttonItem)"
|
||||
>
|
||||
{{ buttonItem.label }}
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
<!-- 按钮组(多选) -->
|
||||
<a-col
|
||||
:span="24 - option.dataStyle.colLeft"
|
||||
v-else-if="item.showType == 'buttonGroupList'"
|
||||
>
|
||||
<div class="filterContentDiv" style="display: inline-flex">
|
||||
<div
|
||||
:style="{
|
||||
marginRight: option.dataStyle.filterTitleFontSize + 'px',
|
||||
}"
|
||||
v-for="(buttonItem, buttonIndex) in item.options"
|
||||
:key="buttonIndex"
|
||||
:class="
|
||||
item.value && item.value.includes(buttonItem.value)
|
||||
? 'filterContentFont_choose'
|
||||
: 'filterContentFont_nochoose'
|
||||
"
|
||||
@click="clickFilterButtonList(item, buttonItem)"
|
||||
>
|
||||
{{ buttonItem.label }}
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
<!-- 列搜索框 -->
|
||||
<a-col :span="24 - option.dataStyle.colLeft" v-else-if="item.showType == 'inputSearch'">
|
||||
<div class="filterContentDiv">
|
||||
<n-input-group>
|
||||
<n-input
|
||||
v-model:value="item.value"
|
||||
:style="{ width: '50%' }"
|
||||
:placeholder="'请输入' + item.title"
|
||||
clearable
|
||||
/>
|
||||
<n-button type="primary" ghost @click="search"> 搜索 </n-button>
|
||||
</n-input-group>
|
||||
</div>
|
||||
</a-col>
|
||||
<!-- 全数据搜索框 -->
|
||||
<a-col
|
||||
:span="24 - option.dataStyle.colLeft"
|
||||
v-else-if="item.showType == 'inputSearchAll'"
|
||||
>
|
||||
<div class="filterContentDiv">
|
||||
<n-input-group>
|
||||
<n-input
|
||||
v-model:value="item.value"
|
||||
:style="{ width: '50%' }"
|
||||
placeholder="请输入搜索数据"
|
||||
clearable
|
||||
/>
|
||||
<n-button type="primary" ghost @click="searchAll"> 搜索 </n-button>
|
||||
</n-input-group>
|
||||
</div>
|
||||
</a-col>
|
||||
<!-- 时间选择器 -->
|
||||
<a-col :span="24 - option.dataStyle.colLeft" v-else-if="item.showType == 'timePicker'">
|
||||
<div class="filterContentDiv">
|
||||
<n-time-picker
|
||||
v-model:formatted-value="item.value"
|
||||
value-format="HH:mm:ss"
|
||||
format="HH:mm:ss"
|
||||
:style="{ width: '50%' }"
|
||||
clearable
|
||||
placeholder="请选择时间"
|
||||
/>
|
||||
</div>
|
||||
</a-col>
|
||||
<!-- 时间范围 -->
|
||||
<a-col :span="24 - option.dataStyle.colLeft" v-else-if="item.showType == 'timeRange'">
|
||||
<div class="filterContentDiv" :style="{ display: 'inline-flex' }">
|
||||
<n-time-picker
|
||||
v-model:formatted-value="item.value"
|
||||
value-format="HH:mm:ss"
|
||||
format="HH:mm:ss"
|
||||
:style="{ width: '40%', marginRight: '30px' }"
|
||||
clearable
|
||||
placeholder="请选择开始时间"
|
||||
/>
|
||||
<n-time-picker
|
||||
v-model:formatted-value="item.value2"
|
||||
value-format="HH:mm:ss"
|
||||
format="HH:mm:ss"
|
||||
:style="{ width: '40%' }"
|
||||
clearable
|
||||
placeholder="请选择结束时间"
|
||||
/>
|
||||
</div>
|
||||
</a-col>
|
||||
<!-- 日期范围 -->
|
||||
<a-col :span="24 - option.dataStyle.colLeft" v-else-if="item.showType == 'dateRange'">
|
||||
<div class="filterContentDiv">
|
||||
<n-date-picker
|
||||
v-model:formatted-value="item.value"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
type="datetimerange"
|
||||
:style="{ width: '80%' }"
|
||||
size="small"
|
||||
clearable
|
||||
/>
|
||||
</div>
|
||||
</a-col>
|
||||
<!-- 其他 -->
|
||||
<a-col :span="24 - option.dataStyle.colLeft" v-else>
|
||||
<div class="filterContent"> </div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 表格部分 -->
|
||||
<!-- 表头 -->
|
||||
<div class="theadDiv">
|
||||
<n-table
|
||||
:bordered="option.dataStyle.tableBordered"
|
||||
:single-column="option.dataStyle.tableSigleColumn"
|
||||
:single-line="option.dataStyle.tableSingleLine"
|
||||
:size="option.dataStyle.tableSize"
|
||||
>
|
||||
<thead v-if="option.dataStyle.tableHeaderShow">
|
||||
<tr
|
||||
:style="{
|
||||
backgroud: option.dataStyle.tableHeaderBackgroud,
|
||||
}"
|
||||
>
|
||||
<th
|
||||
class="th"
|
||||
v-if="option.dataStyle.orderBumberShow"
|
||||
:style="{
|
||||
width: headWidths[0] + 'px',
|
||||
}"
|
||||
>
|
||||
</th>
|
||||
<th
|
||||
class="th"
|
||||
v-for="(item, index) in option.header"
|
||||
:key="index"
|
||||
:style="{
|
||||
width: headWidths[option.dataStyle.orderBumberShow ? index + 1 : index] + 'px',
|
||||
}"
|
||||
>
|
||||
{{ item.title }}
|
||||
</th>
|
||||
<th
|
||||
class="th"
|
||||
v-if="option.dataStyle.buttonDivShow"
|
||||
:style="{
|
||||
width: headWidths[headWidths.length - 1] + 'px',
|
||||
}"
|
||||
>
|
||||
操作
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</n-table>
|
||||
</div>
|
||||
<!-- 表格数据 -->
|
||||
<div class="tbodyDiv">
|
||||
<n-table
|
||||
:bordered="option.dataStyle.tableBordered"
|
||||
:single-column="option.dataStyle.tableSigleColumn"
|
||||
:single-line="option.dataStyle.tableSingleLine"
|
||||
:size="option.dataStyle.tableSize"
|
||||
>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(dataItem, dataIndex) in filterData"
|
||||
:key="dataIndex"
|
||||
:class="
|
||||
option.dataStyle.tableDataBackgroudShow
|
||||
? 'td_background'
|
||||
: dataIndex % 2 == 0
|
||||
? 'td_image1'
|
||||
: 'td_image2'
|
||||
"
|
||||
>
|
||||
<!-- 序号 -->
|
||||
<td
|
||||
id="dataTd_order"
|
||||
v-if="option.dataStyle.orderBumberShow"
|
||||
:style="{
|
||||
width: option.dataStyle.orderDivWidth + 'px',
|
||||
}"
|
||||
>
|
||||
{{ dataIndex + 1 }}
|
||||
</td>
|
||||
<!-- 数据 -->
|
||||
<td
|
||||
:id="'dataTd_' + headerIndex"
|
||||
v-for="(headerItem, headerIndex) in option.header"
|
||||
:key="headerIndex"
|
||||
:style="{
|
||||
width: headerItem.width + 'px',
|
||||
}"
|
||||
>
|
||||
<span>
|
||||
{{ dataItem[headerItem.key] ? convertData(headerItem, dataItem) : '--' }}
|
||||
</span>
|
||||
</td>
|
||||
<!-- 操作 -->
|
||||
<td
|
||||
id="dataTd_button"
|
||||
v-if="option.dataStyle.buttonDivShow"
|
||||
:style="{
|
||||
width: option.dataStyle.buttonDivWidth + 'px',
|
||||
}"
|
||||
>
|
||||
<div class="buttonDiv">
|
||||
<n-button
|
||||
v-if="option.dataStyle.buttonDivShow1"
|
||||
size="small"
|
||||
quaternary
|
||||
@click="pitchLocation(dataItem, dataIndex)"
|
||||
>
|
||||
<Button1 :dataStyle="option.dataStyle" />
|
||||
</n-button>
|
||||
<span
|
||||
v-if="option.dataStyle.buttonDivShow1 && option.dataStyle.buttonDivShow2"
|
||||
class="buttonDivspan"
|
||||
>
|
||||
|
|
||||
</span>
|
||||
<n-button
|
||||
v-if="option.dataStyle.buttonDivShow2"
|
||||
size="small"
|
||||
quaternary
|
||||
@click="moveLocation(dataItem, dataIndex)"
|
||||
>
|
||||
<Button2 :dataStyle="option.dataStyle" />
|
||||
</n-button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</n-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, PropType, toRefs, watch, reactive, ref } from 'vue';
|
||||
import { CreateComponentType } from '@/packages/index.d';
|
||||
import { icon } from '@/plugins';
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
|
||||
import { useChartDataFetch } from '@/hooks';
|
||||
import dayjs from 'dayjs';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import Button1 from './svg/button1.vue';
|
||||
import Button2 from './svg/button2.vue';
|
||||
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const { w, h } = toRefs(props.chartConfig.attr);
|
||||
|
||||
const option = reactive({
|
||||
header: props.chartConfig.option.header,
|
||||
dataset: props.chartConfig.option.dataset,
|
||||
filterset: props.chartConfig.option.filterset,
|
||||
dataStyle: props.chartConfig.option.dataStyle,
|
||||
});
|
||||
|
||||
// 表头高度
|
||||
const headHeight: any = computed(() => {
|
||||
if (option.dataStyle.tableHeaderShow) {
|
||||
return document.querySelector('.theadDiv')?.offsetHeight + 10;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
// 数据表实际宽度
|
||||
const headWidths = computed(() => {
|
||||
let widths: any = [];
|
||||
if (option.dataStyle.tableHeaderShow) {
|
||||
setTimeout(() => {
|
||||
if (option.dataStyle.orderBumberShow) {
|
||||
widths.push(document.getElementById('dataTd_order')?.offsetWidth);
|
||||
}
|
||||
option.header.forEach((item, index) => {
|
||||
let td = document.getElementById('dataTd_' + index);
|
||||
widths.push(td?.offsetWidth);
|
||||
});
|
||||
if (option.dataStyle.buttonDivShow) {
|
||||
widths.push(document.getElementById('dataTd_button')?.offsetWidth);
|
||||
}
|
||||
console.log(widths);
|
||||
}, 500);
|
||||
}
|
||||
return widths;
|
||||
});
|
||||
|
||||
// 搜索框
|
||||
const searchFlag = ref(false);
|
||||
const searchAllFlag = ref(false);
|
||||
|
||||
function search() {
|
||||
searchFlag.value = true;
|
||||
}
|
||||
function searchAll() {
|
||||
searchAllFlag.value = true;
|
||||
}
|
||||
|
||||
// 数据过滤
|
||||
const filterData = computed(() => {
|
||||
let data = cloneDeep(option.dataset);
|
||||
option.filterset.forEach((filtersetItem) => {
|
||||
// console.log(filtersetItem);
|
||||
if (
|
||||
(filtersetItem.field && filtersetItem.value) ||
|
||||
(!filtersetItem.field && filtersetItem.showType == 'inputSearchAll')
|
||||
) {
|
||||
switch (filtersetItem.compareType) {
|
||||
// 大于
|
||||
case 'greater':
|
||||
if (['timePicker'].includes(filtersetItem.showType)) {
|
||||
data = data.filter(
|
||||
(d) =>
|
||||
dayjs(d[filtersetItem.field], 'HH:mm:ss').diff(
|
||||
dayjs(filtersetItem.value, 'HH:mm:ss'),
|
||||
) > 0,
|
||||
);
|
||||
} else {
|
||||
data = data.filter(
|
||||
(d) => Number(d[filtersetItem.field]) > Number(filtersetItem.value),
|
||||
);
|
||||
}
|
||||
break;
|
||||
// 小于
|
||||
case 'less':
|
||||
if (['timePicker'].includes(filtersetItem.showType)) {
|
||||
data = data.filter(
|
||||
(d) =>
|
||||
dayjs(d[filtersetItem.field], 'HH:mm:ss').diff(
|
||||
dayjs(filtersetItem.value, 'HH:mm:ss'),
|
||||
) < 0,
|
||||
);
|
||||
} else {
|
||||
data = data.filter(
|
||||
(d) => Number(d[filtersetItem.field]) < Number(filtersetItem.value),
|
||||
);
|
||||
}
|
||||
break;
|
||||
// 大于等于
|
||||
case 'greaterAndEqual':
|
||||
if (['timePicker'].includes(filtersetItem.showType)) {
|
||||
data = data.filter(
|
||||
(d) =>
|
||||
dayjs(d[filtersetItem.field], 'HH:mm:ss').diff(
|
||||
dayjs(filtersetItem.value, 'HH:mm:ss'),
|
||||
) >= 0,
|
||||
);
|
||||
} else {
|
||||
data = data.filter(
|
||||
(d) => Number(d[filtersetItem.field]) >= Number(filtersetItem.value),
|
||||
);
|
||||
}
|
||||
break;
|
||||
// 小于等于
|
||||
case 'lessAndEqual':
|
||||
if (['timePicker'].includes(filtersetItem.showType)) {
|
||||
data = data.filter(
|
||||
(d) =>
|
||||
dayjs(d[filtersetItem.field], 'HH:mm:ss').diff(
|
||||
dayjs(filtersetItem.value, 'HH:mm:ss'),
|
||||
) <= 0,
|
||||
);
|
||||
} else {
|
||||
data = data.filter(
|
||||
(d) => Number(d[filtersetItem.field]) <= Number(filtersetItem.value),
|
||||
);
|
||||
}
|
||||
break;
|
||||
// 等于
|
||||
case 'equal':
|
||||
if (['checkbox'].includes(filtersetItem.showType)) {
|
||||
// 多选框不选中时,不展示
|
||||
data = data.filter((d) =>
|
||||
filtersetItem.value.some((li) => d[filtersetItem.field].includes(li)),
|
||||
);
|
||||
} else if (['selectGroup', 'buttonGroupList'].includes(filtersetItem.showType)) {
|
||||
// 下拉框(多选)、按钮组(多选)不选中时,全展示
|
||||
if (filtersetItem.value.length > 0) {
|
||||
data = data.filter((d) =>
|
||||
filtersetItem.value.some((li) => d[filtersetItem.field].includes(li)),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// 其他统一
|
||||
data = data.filter((d) => d[filtersetItem.field] == filtersetItem.value);
|
||||
}
|
||||
break;
|
||||
// 不等于
|
||||
case 'notequal':
|
||||
if (['checkbox'].includes(filtersetItem.showType)) {
|
||||
// 多选框不选中时,不展示
|
||||
data = data.filter((d) =>
|
||||
filtersetItem.value.some((li) => !d[filtersetItem.field].includes(li)),
|
||||
);
|
||||
} else if (['selectGroup', 'buttonGroupList'].includes(filtersetItem.showType)) {
|
||||
// 下拉框(多选)、按钮组(多选)不选中时,全展示
|
||||
if (filtersetItem.value.length > 0) {
|
||||
data = data.filter((d) =>
|
||||
filtersetItem.value.some((li) => !d[filtersetItem.field].includes(li)),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// 其他统一
|
||||
data = data.filter((d) => d[filtersetItem.field] !== filtersetItem.value);
|
||||
}
|
||||
break;
|
||||
// 含有
|
||||
case 'contain':
|
||||
if (['checkbox'].includes(filtersetItem.showType)) {
|
||||
// 多选框不选中时,不展示
|
||||
data = data.filter((d) =>
|
||||
filtersetItem.value.some((li) => d[filtersetItem.field].includes(li)),
|
||||
);
|
||||
} else if (['selectGroup', 'buttonGroupList'].includes(filtersetItem.showType)) {
|
||||
// 下拉框(多选)、按钮组(多选)不选中时,全展示
|
||||
if (filtersetItem.value.length > 0) {
|
||||
data = data.filter((d) =>
|
||||
filtersetItem.value.some((li) => d[filtersetItem.field].includes(li)),
|
||||
);
|
||||
}
|
||||
} else if (['inputSearch'].includes(filtersetItem.showType)) {
|
||||
// 搜索框单独处理
|
||||
if (searchFlag.value) {
|
||||
data = data.filter(
|
||||
(d) => d[filtersetItem.field].indexOf(filtersetItem.value) !== -1,
|
||||
);
|
||||
searchFlag.value = false;
|
||||
}
|
||||
} else if (['inputSearchAll'].includes(filtersetItem.showType)) {
|
||||
// 全数据搜索框单独处理
|
||||
if (searchAllFlag.value) {
|
||||
data = data.filter((d) => {
|
||||
let flag = false;
|
||||
option.header.some((headerLi) => {
|
||||
if (d[headerLi.key]) {
|
||||
flag = flag ? true : d[headerLi.key].includes(filtersetItem.value);
|
||||
}
|
||||
});
|
||||
return flag;
|
||||
});
|
||||
searchAllFlag.value = false;
|
||||
}
|
||||
} else {
|
||||
// 其他统一
|
||||
data = data.filter((d) => d[filtersetItem.field].indexOf(filtersetItem.value) !== -1);
|
||||
}
|
||||
break;
|
||||
// 不含有
|
||||
case 'notcontain':
|
||||
if (['checkbox'].includes(filtersetItem.showType)) {
|
||||
// 多选框不选中时,不展示
|
||||
data = data.filter((d) =>
|
||||
filtersetItem.value.some((li) => !d[filtersetItem.field].includes(li)),
|
||||
);
|
||||
} else if (['selectGroup', 'buttonGroupList'].includes(filtersetItem.showType)) {
|
||||
// 下拉框(多选)、按钮组(多选)不选中时,全展示
|
||||
if (filtersetItem.value.length > 0) {
|
||||
data = data.filter((d) =>
|
||||
filtersetItem.value.some((li) => !d[filtersetItem.field].includes(li)),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// 其他统一
|
||||
data = data.filter((d) => d[filtersetItem.field].indexOf(filtersetItem.value) == -1);
|
||||
}
|
||||
break;
|
||||
// 两者之间
|
||||
case 'between':
|
||||
if (['timeRange'].includes(filtersetItem.showType)) {
|
||||
data = data.filter((d) => {
|
||||
const time = dayjs(d[filtersetItem.field], 'HH:mm:ss');
|
||||
const startTime = dayjs(filtersetItem.value, 'HH:mm:ss');
|
||||
const endTime = dayjs(filtersetItem.value2, 'HH:mm:ss');
|
||||
return time.diff(startTime) >= 0 && time.diff(endTime) <= 0;
|
||||
});
|
||||
}
|
||||
if (['dateRange'].includes(filtersetItem.showType)) {
|
||||
data = data.filter((d) => {
|
||||
const time = dayjs(d[filtersetItem.field], 'YYYY-MM-DD HH:mm:ss');
|
||||
const startTime = dayjs(filtersetItem.value[0], 'YYYY-MM-DD HH:mm:ss');
|
||||
const endTime = dayjs(filtersetItem.value[1], 'YYYY-MM-DD HH:mm:ss');
|
||||
return time.diff(startTime) >= 0 && time.diff(endTime) <= 0;
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
return data;
|
||||
});
|
||||
|
||||
// 筛选-按钮点击事件
|
||||
function clickFilterButton(item, buttonItem) {
|
||||
if (item.value == buttonItem.value) {
|
||||
item.value = '';
|
||||
} else {
|
||||
item.value = buttonItem.value;
|
||||
}
|
||||
}
|
||||
// 筛选-按钮点击事件(多选)
|
||||
function clickFilterButtonList(item, buttonItem) {
|
||||
if (!item.value) {
|
||||
item.value = [];
|
||||
}
|
||||
if (item.value.includes(buttonItem.value)) {
|
||||
item.value.splice(item.value.indexOf(buttonItem.value), 1);
|
||||
} else {
|
||||
item.value.push(buttonItem.value);
|
||||
}
|
||||
}
|
||||
|
||||
// 数据转换
|
||||
function convertData(header, data) {
|
||||
let prefix = header.prefix ? header.prefix : '';
|
||||
let suffix = header.suffix ? header.suffix : '';
|
||||
let convertData = data[header.key];
|
||||
|
||||
// 小数点保留后两位
|
||||
if (convertData && header.convert == '0' && isValidNumber(convertData)) {
|
||||
convertData =
|
||||
typeof convertData === 'string'
|
||||
? String(parseFloat(convertData).toFixed(2))
|
||||
: String(convertData.toFixed(2));
|
||||
}
|
||||
// 转换时间格式(例:0小时0分钟0秒)
|
||||
if (convertData && header.convert == '1' && isValidTime(convertData)) {
|
||||
convertData =
|
||||
dayjs(convertData, 'HH:mm:ss').hour() +
|
||||
'小时' +
|
||||
dayjs(convertData, 'HH:mm:ss').minute() +
|
||||
'分钟' +
|
||||
dayjs(convertData, 'HH:mm:ss').second() +
|
||||
'秒';
|
||||
}
|
||||
// 转换日期格式(例:YYYY-MM-DD HH:mm:ss)
|
||||
let format = 'YYYY-MM-DD HH:mm:ss';
|
||||
if (header.convert == '2') {
|
||||
format = 'YYYY-MM-DD';
|
||||
}
|
||||
if (header.convert == '3') {
|
||||
format = 'YYYY/MM/DD';
|
||||
}
|
||||
if (
|
||||
convertData &&
|
||||
['2', '3', '4'].includes(header.convert) &&
|
||||
isValidDate(convertData, format)
|
||||
) {
|
||||
convertData = dayjs(convertData).format(format);
|
||||
}
|
||||
return prefix + convertData + suffix;
|
||||
}
|
||||
|
||||
// 检查字符串可否转成数字
|
||||
function isValidNumber(str) {
|
||||
const regex = /^-?\d+(\.\d+)?$/;
|
||||
return regex.test(String(str).trim());
|
||||
}
|
||||
// 检查字符串可否转成时间
|
||||
function isValidTime(str) {
|
||||
const parsedDate = dayjs(str, 'HH:mm:ss');
|
||||
if (parsedDate.isValid()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 检查字符串可否转成日期
|
||||
function isValidDate(str, format) {
|
||||
const parsedDate = dayjs(str, format);
|
||||
if (parsedDate.isValid()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 表格按钮方法
|
||||
function pitchLocation(dataItem, dataIndex) {}
|
||||
|
||||
function moveLocation(dataItem, dataIndex) {}
|
||||
|
||||
// setdata 数据监听与更改
|
||||
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
|
||||
props.chartConfig.option.dataset = newData;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.TableFilter {
|
||||
width: v-bind('`${w}px`');
|
||||
height: v-bind('`${h}px`');
|
||||
|
||||
// 页面不能被选中
|
||||
-webkit-user-select: none; /* Safari */
|
||||
-moz-user-select: none; /* Firefox */
|
||||
-ms-user-select: none; /* IE/Edge */
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.filterDiv {
|
||||
width: 100%;
|
||||
padding-top: v-bind('`${option.dataStyle.filterMarginTop}px`');
|
||||
padding-left: v-bind('`${option.dataStyle.filterMarginLeft}px`');
|
||||
padding-right: v-bind('`${option.dataStyle.filterMarginLeft}px`');
|
||||
}
|
||||
|
||||
// 筛选标题
|
||||
.filterTitle {
|
||||
text-align: v-bind('`${option.dataStyle.filterTitleAlign}`');
|
||||
font-size: v-bind('`${option.dataStyle.filterTitleFontSize}px`');
|
||||
color: v-bind('`${option.dataStyle.filterTitleFontColor}`');
|
||||
font-family:
|
||||
PingFangSC,
|
||||
PingFang SC;
|
||||
font-weight: 500;
|
||||
line-height: v-bind('`${option.dataStyle.filterTitleFontSize}px`');
|
||||
height: v-bind('`${option.dataStyle.filterItemHeight}px`');
|
||||
font-style: normal;
|
||||
}
|
||||
.filterContentDiv {
|
||||
width: 100%;
|
||||
height: v-bind('`${option.dataStyle.filterItemHeight}px`');
|
||||
justify-content: v-bind('`${option.dataStyle.filterContentAlign}`');
|
||||
text-align: v-bind('`${option.dataStyle.filterContentAlign}`');
|
||||
align-items: v-bind('`${option.dataStyle.filterContentAlign}`');
|
||||
}
|
||||
|
||||
// 内容通用字体
|
||||
.filterContentFont {
|
||||
font-size: v-bind('`${option.dataStyle.filterChooseFontSize}px`');
|
||||
color: v-bind('`${option.dataStyle.filterChooseFontColor}`');
|
||||
}
|
||||
::v-deep .n-checkbox-box {
|
||||
width: v-bind('`${option.dataStyle.filterChooseFontSize}px`') !important;
|
||||
height: v-bind('`${option.dataStyle.filterChooseFontSize}px`') !important;
|
||||
}
|
||||
::v-deep .n-radio__dot {
|
||||
width: v-bind('`${option.dataStyle.filterChooseFontSize}px`') !important;
|
||||
height: v-bind('`${option.dataStyle.filterChooseFontSize}px`') !important;
|
||||
}
|
||||
|
||||
.filterContentFont_nochoose {
|
||||
background: #1c211f;
|
||||
color: #18d09d;
|
||||
border: 1px solid #18d09d;
|
||||
font-size: v-bind('`${option.dataStyle.filterChooseFontSize}px`');
|
||||
width: v-bind('`${option.dataStyle.filterChooseFontSize + 62}px`');
|
||||
height: v-bind('`${option.dataStyle.filterChooseFontSize + 12}px`');
|
||||
border-radius: v-bind('`${option.dataStyle.filterChooseFontSize + 12}px`');
|
||||
text-align: center;
|
||||
line-height: v-bind('`${option.dataStyle.filterChooseFontSize + 12}px`');
|
||||
}
|
||||
.filterContentFont_choose {
|
||||
background: #26d1ad;
|
||||
color: #0d2822;
|
||||
font-size: v-bind('`${option.dataStyle.filterChooseFontSize}px`');
|
||||
width: v-bind('`${option.dataStyle.filterChooseFontSize + 62}px`');
|
||||
height: v-bind('`${option.dataStyle.filterChooseFontSize + 12}px`');
|
||||
border-radius: v-bind('`${option.dataStyle.filterChooseFontSize + 12}px`');
|
||||
text-align: center;
|
||||
line-height: v-bind('`${option.dataStyle.filterChooseFontSize + 12}px`');
|
||||
}
|
||||
|
||||
// 表头
|
||||
.theadDiv {
|
||||
margin-top: v-bind('`${option.dataStyle.tableMarginTop}px`');
|
||||
padding-left: v-bind('`${option.dataStyle.tableMarginLeft}px`');
|
||||
padding-right: v-bind('`${option.dataStyle.tableMarginLeft}px`');
|
||||
}
|
||||
// 表格部分
|
||||
.tbodyDiv {
|
||||
overflow-y: auto;
|
||||
height: v-bind(
|
||||
'`${h - headHeight - option.dataStyle.filterMarginTop - option.dataStyle.filterItemHeight * option.filterset.length - option.dataStyle.tableMarginTop}px`'
|
||||
);
|
||||
padding-left: v-bind('`${option.dataStyle.tableMarginLeft}px`');
|
||||
padding-right: v-bind('`${option.dataStyle.tableMarginLeft}px`');
|
||||
}
|
||||
.tbodyDiv::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.tbodyDiv {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
.th {
|
||||
background: v-bind('`${option.dataStyle.tableHeaderBackgroud}`');
|
||||
text-align: v-bind('`${option.dataStyle.tableAlign}`');
|
||||
color: v-bind('`${option.dataStyle.tableHeaderFontColor}`');
|
||||
font-size: v-bind('`${option.dataStyle.tableHeaderFontSize}px`');
|
||||
}
|
||||
td {
|
||||
text-align: v-bind('`${option.dataStyle.tableAlign}`');
|
||||
background: #ffffff00;
|
||||
color: v-bind('`${option.dataStyle.tableDataFontColor}`');
|
||||
font-size: v-bind('`${option.dataStyle.tableDataFontSize}px`');
|
||||
border-bottom: 0px;
|
||||
}
|
||||
.td_background {
|
||||
background: v-bind('`${option.dataStyle.tableDataBackgroud}`');
|
||||
}
|
||||
.td_image1 {
|
||||
background-image: url('@/assets/images/chart/zhichu/component/ModalTable_td1.png');
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
.td_image2 {
|
||||
background-image: url('@/assets/images/chart/zhichu/component/ModalTable_td2.png');
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.buttonDiv {
|
||||
display: flex;
|
||||
align-items: v-bind('`${option.dataStyle.tableAlign}`');
|
||||
justify-content: center;
|
||||
width: v-bind('`${option.dataStyle.buttonDivWidth}px`');
|
||||
}
|
||||
|
||||
.buttonDivspan {
|
||||
color: #00611a;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -8,7 +8,6 @@
|
|||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<title>编组 16</title>
|
||||
<defs>
|
||||
<linearGradient
|
||||
x1="50%"
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<template>
|
||||
<div>
|
||||
<svg
|
||||
:width="props.dataStyle.buttonWidth"
|
||||
:height="props.dataStyle.buttonHeight"
|
||||
viewBox="0 0 22 22"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-TableFilter-2-1">
|
||||
<stop stop-color="#099C48" offset="0%"></stop>
|
||||
<stop stop-color="#ADFFBF" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M21.2019328,9.14688177 L20.0206813,6.19375288 C19.8155181,5.68221122 19.3188567,5.34775913 18.7677109,5.35000178 L15.8500195,5.35000178 L15.8500195,4.67500089 C15.8500195,4.30220819 15.5478113,4 15.1750186,4 L2.35000178,4 C1.60441638,4 1,4.60441638 1,5.35000178 L1,14.8000142 C1,15.5455996 1.60441638,16.150016 2.35000178,16.150016 L3.78437866,16.150016 C4.09026867,17.3447101 5.1667745,18.1803128 6.4000071,18.1803128 C7.6332397,18.1803128 8.70974553,17.3447101 9.01563554,16.150016 L13.2343911,16.150016 C13.5402811,17.3447101 14.6167869,18.1803128 15.8500195,18.1803128 C17.0832521,18.1803128 18.159758,17.3447101 18.465648,16.150016 L19.9000249,16.150016 C20.6456102,16.150016 21.2500396,15.5455996 21.2500396,14.8000142 L21.2500396,9.4000071 C21.2505672,9.31331105 21.2342323,9.22733821 21.2019328,9.14688177 L21.2019328,9.14688177 Z M6.4000071,16.8250169 C5.65442171,16.8250169 5.05000533,16.2206005 5.05000533,15.4750151 C5.05000533,14.7294297 5.65442171,14.1250133 6.4000071,14.1250133 C7.14559249,14.1250133 7.75000888,14.7294297 7.75000888,15.4750151 C7.75000888,16.2206005 7.14559249,16.8250169 6.4000071,16.8250169 Z M15.8500195,16.8250169 C15.1044341,16.8250169 14.5000178,16.2206005 14.5000178,15.4750151 C14.5000178,14.7294297 15.1044341,14.1250133 15.8500195,14.1250133 C16.5956049,14.1250133 17.2000213,14.7294297 17.2000213,15.4750151 C17.2000213,16.2206005 16.5956049,16.8250169 15.8500195,16.8250169 Z M15.8500195,8.72500621 L15.8500195,6.70000355 L18.7677109,6.70000355 L19.5777119,8.72500621 L15.8500195,8.72500621 Z"
|
||||
id="path-TableFilter-2-2"
|
||||
></path>
|
||||
<filter
|
||||
x="-44.4%"
|
||||
y="-63.5%"
|
||||
width="188.9%"
|
||||
height="226.9%"
|
||||
filterUnits="objectBoundingBox"
|
||||
id="filter-TableFilter-2-3"
|
||||
>
|
||||
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur
|
||||
stdDeviation="3"
|
||||
in="shadowOffsetOuter1"
|
||||
result="shadowBlurOuter1"
|
||||
></feGaussianBlur>
|
||||
<feColorMatrix
|
||||
values="0 0 0 0 0 0 0 0 0 0.71372549 0 0 0 0 0 0 0 0 0.5 0"
|
||||
type="matrix"
|
||||
in="shadowBlurOuter1"
|
||||
></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="监测平台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="林业防火-智处-在线人员弹窗" transform="translate(-1412, -543)" fill-rule="nonzero">
|
||||
<g id="在线人员弹窗----" transform="translate(418.2674, 225.0542)">
|
||||
<g id="编组-14" transform="translate(54.7326, 64)">
|
||||
<g id="列表" transform="translate(0, 242.9458)">
|
||||
<g id="形状" transform="translate(939, 11)">
|
||||
<use
|
||||
fill="black"
|
||||
fill-opacity="1"
|
||||
filter="url(#filter-TableFilter-2-3)"
|
||||
xlink:href="#path-TableFilter-2-2"
|
||||
></use>
|
||||
<use
|
||||
fill="url(#linearGradient-TableFilter-2-1)"
|
||||
xlink:href="#path-TableFilter-2-2"
|
||||
></use>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps(['dataStyle']);
|
||||
</script>
|
||||
|
|
@ -5,57 +5,99 @@ import { chartInitConfig } from '@/settings/designSetting'
|
|||
import { ZhiChu_ModalTableConfig } from './index'
|
||||
import dataJson from './data.json'
|
||||
|
||||
const {header, source, filterset} = dataJson;
|
||||
const {header, source} = dataJson;
|
||||
|
||||
export const option = {
|
||||
header: header,
|
||||
dataset: source,
|
||||
filterset: filterset,
|
||||
dataStyle: {
|
||||
colLeft: 4,
|
||||
mapListValue: ['water', 'goods', 'barrack'],
|
||||
buttonValue: '0',
|
||||
distanceradio: '1',
|
||||
|
||||
// 筛选项
|
||||
filterMarginTop: 20,
|
||||
filterMarginLeft: 50,
|
||||
filterItemHeight: 45,
|
||||
|
||||
filterTitleAlign: 'left',
|
||||
filterTitleFontSize: 24,
|
||||
filterTitleFontColor: '#ADFFC0',
|
||||
|
||||
filterContentAlign: 'left',
|
||||
filterChooseFontSize: 18,
|
||||
filterChooseFontColor: '#FFFFFF',
|
||||
|
||||
// 水源-表格
|
||||
tableMarginTop: 20,
|
||||
tableMarginLeft: 20,
|
||||
tableBordered: false,
|
||||
tableSigleColumn: true,
|
||||
tableSingleLine: true,
|
||||
tableStriped: false,
|
||||
tableSize: 'small',
|
||||
tableAlign: 'center',
|
||||
// 表头
|
||||
tableHeaderShow: false,
|
||||
// 序号
|
||||
orderBumberShow: false,
|
||||
tableOrderBumberShow: false,
|
||||
// 操作
|
||||
buttonDivShow: true,
|
||||
buttonDivShow1: true,
|
||||
buttonDivShow2: true,
|
||||
buttonWidth: 22,
|
||||
buttonHeight: 22,
|
||||
tableButtonDivShow: true,
|
||||
tableButtonWidth: 22,
|
||||
tableButtonHeight: 22,
|
||||
// 宽度
|
||||
orderDivWidth: 50,
|
||||
buttonDivWidth: 100,
|
||||
tableOrderDivWidth: 50,
|
||||
tableButtonDivWidth: 100,
|
||||
// 字体
|
||||
tableHeaderBackgroud: '#FFFFFF',
|
||||
tableHeaderFontSize: 20,
|
||||
tableHeaderFontColor: '#000000',
|
||||
|
||||
tableDataBackgroudShow: false,
|
||||
tableDataBackgroud: '#FFFFFF',
|
||||
tableDataFontSize: 20,
|
||||
tableDataFontColor: '#FFFFFF',
|
||||
|
||||
// 物资-队列
|
||||
goodsMarginTop: 20,
|
||||
goodsMarginLeft: 20,
|
||||
goodsDivMarginTop: 20,
|
||||
goodsDivMarginLeft: 20,
|
||||
// 标题
|
||||
goodsTitleFontSize1: 18,
|
||||
goodsTitleFontColor1: '#FFFFFF',
|
||||
goodsTitleFontSize2: 14,
|
||||
goodsTitleFontColor2: '#FFFFFF',
|
||||
goodsTitleFontSize3: 16,
|
||||
goodsTitleFontColor3: '#FFFFFF',
|
||||
// 按钮
|
||||
goodsButtonBackgroud: '#409EFF',
|
||||
goodsButtonFontSize: 16,
|
||||
goodsButtonFontColor: '#FFFFFF',
|
||||
// 线
|
||||
goodsLineStartColor: '#4DFFB5',
|
||||
goodsLineEndColor: '#0B4D2C',
|
||||
// text
|
||||
goodsTextFontSize: 16,
|
||||
goodsTextFontColor: '#FFFFFF',
|
||||
|
||||
// 营房-队列
|
||||
barrackMarginTop: 20,
|
||||
barrackMarginLeft: 20,
|
||||
barrackDivMarginTop: 20,
|
||||
barrackDivMarginLeft: 20,
|
||||
// 标题
|
||||
barrackTitleFontSize1: 18,
|
||||
barrackTitleFontColor1: '#FFFFFF',
|
||||
barrackTitleFontSize2: 14,
|
||||
barrackTitleFontColor2: '#FFFFFF',
|
||||
barrackTitleFontSize3: 16,
|
||||
barrackTitleFontColor3: '#FFFFFF',
|
||||
// 按钮
|
||||
barrackButtonBackgroud: '#409EFF',
|
||||
barrackButtonFontSize: 16,
|
||||
barrackButtonFontColor: '#FFFFFF',
|
||||
// 线
|
||||
barrackLineStartColor: '#4DFFB5',
|
||||
barrackLineEndColor: '#0B4D2C',
|
||||
// text
|
||||
barrackTextFontSize: 16,
|
||||
barrackTextFontColor: '#FFFFFF',
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,261 +1,5 @@
|
|||
<template>
|
||||
<!-- 筛选项数据显示设置 -->
|
||||
<CollapseItem name="筛选项数据显示设置" :expanded="true">
|
||||
<span style="font-size: 12px; margin-left: 8px"> 筛选项字段与类型 </span>
|
||||
<div style="overflow-x: auto">
|
||||
<n-table
|
||||
class="go-request-header-table-box"
|
||||
style="margin-top: 12px"
|
||||
:single-line="false"
|
||||
size="small"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>标题名称</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in props.optionData.filterset" :key="index">
|
||||
<td>
|
||||
<n-input v-model:value="item.title" type="text" size="small" />
|
||||
</td>
|
||||
<td>
|
||||
<div style="width: 70px">
|
||||
<n-button
|
||||
class="go-ml-2"
|
||||
type="primary"
|
||||
size="small"
|
||||
ghost
|
||||
@click="
|
||||
props.optionData.filterset.splice(index + 1, 0, {
|
||||
title: null,
|
||||
field: null,
|
||||
compareType: null,
|
||||
showType: null,
|
||||
value: [],
|
||||
options: [{ label: null, value: null }],
|
||||
})
|
||||
"
|
||||
>
|
||||
+
|
||||
</n-button>
|
||||
<n-button
|
||||
class="go-ml-2"
|
||||
type="warning"
|
||||
size="small"
|
||||
ghost
|
||||
:disabled="props.optionData.filterset.length === 1"
|
||||
@click="
|
||||
if (props.optionData.filterset.length !== 1) {
|
||||
props.optionData.filterset.splice(index, 1);
|
||||
}
|
||||
"
|
||||
>
|
||||
-
|
||||
</n-button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</n-table>
|
||||
</div>
|
||||
</CollapseItem>
|
||||
<CollapseItem
|
||||
:expanded="false"
|
||||
v-for="(filtersetItem, filtersetIndex) in optionData.filterset"
|
||||
:key="filtersetIndex"
|
||||
:alone="false"
|
||||
:name="'筛选项【' + filtersetItem.title + '】设置'"
|
||||
>
|
||||
<SettingItem name="筛选类型">
|
||||
<n-select
|
||||
v-model:value="filtersetItem.showType"
|
||||
:options="[
|
||||
{ label: '多选框', value: 'checkbox' },
|
||||
{ label: '单选框', value: 'radio' },
|
||||
{ label: '下拉框', value: 'select' },
|
||||
{ label: '下拉框(多选)', value: 'selectGroup' },
|
||||
{ label: '按钮组', value: 'buttonGroup' },
|
||||
{ label: '按钮组(多选)', value: 'buttonGroupList' },
|
||||
{ label: '列搜索框', value: 'inputSearch' },
|
||||
{ label: '全数据搜索框', value: 'inputSearchAll' },
|
||||
{ label: '时间选择器', value: 'timePicker' },
|
||||
{ label: '时间范围', value: 'timeRange' },
|
||||
{ label: '日期范围', value: 'dateRange' },
|
||||
]"
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="筛选类型"
|
||||
@change="
|
||||
filtersetItem.compareType = null;
|
||||
filtersetItem.value = null;
|
||||
"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem v-if="!['inputSearchAll'].includes(filtersetItem.showType)" name="对应字段">
|
||||
<n-select
|
||||
v-model:value="filtersetItem.field"
|
||||
:options="columnsOptions"
|
||||
size="small"
|
||||
clearable
|
||||
placeholder="对应字段"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="筛选方式">
|
||||
<n-select
|
||||
v-model:value="filtersetItem.compareType"
|
||||
:options="getOptionsByShowType(filtersetItem)"
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="筛选方式"
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
<!-- 默认值,搜索框无默认值 -->
|
||||
<SettingItem
|
||||
v-if="!['inputSearch', 'inputSearchAll'].includes(filtersetItem.showType)"
|
||||
name="默认值"
|
||||
>
|
||||
<!-- 多选框、下拉框(多选)、按钮组 (多选)-->
|
||||
<n-select
|
||||
v-if="['checkbox', 'selectGroup', 'buttonGroupList'].includes(filtersetItem.showType)"
|
||||
v-model:value="filtersetItem.value"
|
||||
:options="filtersetItem.options"
|
||||
multiple
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="默认值"
|
||||
/>
|
||||
<!-- 时间选择器 -->
|
||||
<n-time-picker
|
||||
v-else-if="['timePicker'].includes(filtersetItem.showType)"
|
||||
v-model:formatted-value="filtersetItem.value"
|
||||
value-format="HH:mm:ss"
|
||||
format="HH:mm:ss"
|
||||
size="small"
|
||||
clearable
|
||||
placeholder="默认时间"
|
||||
/>
|
||||
<!-- 时间范围 -->
|
||||
<div v-else-if="['timeRange'].includes(filtersetItem.showType)">
|
||||
<n-time-picker
|
||||
v-model:formatted-value="filtersetItem.value"
|
||||
value-format="HH:mm:ss"
|
||||
format="HH:mm:ss"
|
||||
size="small"
|
||||
clearable
|
||||
placeholder="开始时间"
|
||||
/>
|
||||
<n-time-picker
|
||||
v-model:formatted-value="filtersetItem.value2"
|
||||
value-format="HH:mm:ss"
|
||||
format="HH:mm:ss"
|
||||
size="small"
|
||||
clearable
|
||||
placeholder="结束时间"
|
||||
/>
|
||||
</div>
|
||||
<!-- 日期范围 -->
|
||||
<n-date-picker
|
||||
v-else-if="['dateRange'].includes(filtersetItem.showType)"
|
||||
v-model:formatted-value="filtersetItem.value"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
type="datetimerange"
|
||||
size="small"
|
||||
clearable
|
||||
/>
|
||||
<!-- 其他 -->
|
||||
<n-select
|
||||
v-else
|
||||
v-model:value="filtersetItem.value"
|
||||
:options="filtersetItem.options"
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="默认值"
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
<!-- 搜索框、时间日期框无选项 -->
|
||||
<div style="overflow-x: auto">
|
||||
<n-table
|
||||
v-if="
|
||||
!['inputSearch', 'inputSearchAll', 'timePicker', 'timeRange', 'dateRange'].includes(
|
||||
filtersetItem.showType,
|
||||
)
|
||||
"
|
||||
class="go-request-header-table-box"
|
||||
style="margin-top: 12px"
|
||||
:single-line="false"
|
||||
size="small"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>名称</th>
|
||||
<th>值</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(optionsItem, optionsIndex) in filtersetItem.options" :key="optionsIndex">
|
||||
<td>
|
||||
<n-input
|
||||
v-model:value="optionsItem.label"
|
||||
type="text"
|
||||
size="small"
|
||||
placeholder="名称"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<n-input
|
||||
v-model:value="optionsItem.value"
|
||||
type="text"
|
||||
size="small"
|
||||
placeholder="值"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<div style="width: 70px">
|
||||
<n-button
|
||||
class="go-ml-2"
|
||||
type="primary"
|
||||
size="small"
|
||||
ghost
|
||||
@click="
|
||||
filtersetItem.options.splice(optionsIndex + 1, 0, {
|
||||
label: null,
|
||||
value: null,
|
||||
})
|
||||
"
|
||||
>
|
||||
+
|
||||
</n-button>
|
||||
<n-button
|
||||
class="go-ml-2"
|
||||
type="warning"
|
||||
size="small"
|
||||
ghost
|
||||
:disabled="optionsItem.length === 1"
|
||||
@click="
|
||||
if (filtersetItem.options.length !== 1) {
|
||||
filtersetItem.options.splice(optionsIndex, 1);
|
||||
}
|
||||
"
|
||||
>
|
||||
-
|
||||
</n-button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</n-table>
|
||||
</div>
|
||||
</CollapseItem>
|
||||
|
||||
<br />
|
||||
<!-- 筛选项样式设置 -->
|
||||
<CollapseItem name="筛选项样式设置" :expanded="true">
|
||||
<CollapseItem name="筛选显示设置" :expanded="true">
|
||||
<SettingItemBox :alone="false" name="整体设置">
|
||||
<SettingItem :alone="false" name="上方距离">
|
||||
<n-input-number
|
||||
|
|
@ -273,6 +17,14 @@
|
|||
placeholder="左右距离"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem :alone="false" name="标题占比">
|
||||
<n-space vertical>
|
||||
<n-slider v-model:value="optionData.dataStyle.colLeft" :step="1" :min="0" :max="12" />
|
||||
<n-input-number v-model:value="optionData.dataStyle.colLeft" size="small">
|
||||
<template #suffix> / 24 </template>
|
||||
</n-input-number>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
<SettingItem :alone="false" name="单个筛选项高度">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.filterItemHeight"
|
||||
|
|
@ -281,6 +33,9 @@
|
|||
placeholder="单个筛选项高度"
|
||||
/>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
|
||||
<SettingItemBox :alone="false" name="筛选标题设置">
|
||||
<SettingItem name="标题对齐方式">
|
||||
<n-select
|
||||
v-model:value="optionData.dataStyle.filterTitleAlign"
|
||||
|
|
@ -292,30 +47,6 @@
|
|||
size="small"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="内容对齐方式">
|
||||
<n-select
|
||||
v-model:value="optionData.dataStyle.filterContentAlign"
|
||||
:options="[
|
||||
{ label: '靠左', value: 'left' },
|
||||
{ label: '居中', value: 'center' },
|
||||
{ label: '靠右', value: 'right' },
|
||||
]"
|
||||
size="small"
|
||||
/>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
|
||||
<SettingItemBox :alone="false" name="标题样式">
|
||||
<SettingItem :alone="false" name="标题占比">
|
||||
<n-space vertical>
|
||||
<n-slider v-model:value="optionData.dataStyle.colLeft" :step="1" :min="0" :max="24" />
|
||||
<n-input-number v-model:value="optionData.dataStyle.colLeft" size="small">
|
||||
<template #suffix> / 24 </template>
|
||||
</n-input-number>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
<SettingItemBox :alone="false" name="字体设置">
|
||||
<SettingItem name="筛选标题字体颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
|
|
@ -331,6 +62,20 @@
|
|||
placeholder="筛选标题字体大小"
|
||||
></n-input-number>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
|
||||
<SettingItemBox :alone="false" name="筛选内容设置">
|
||||
<SettingItem name="筛选内容对齐方式">
|
||||
<n-select
|
||||
v-model:value="optionData.dataStyle.filterContentAlign"
|
||||
:options="[
|
||||
{ label: '靠左', value: 'left' },
|
||||
{ label: '居中', value: 'center' },
|
||||
{ label: '靠右', value: 'right' },
|
||||
]"
|
||||
size="small"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="筛选内容字体颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
|
|
@ -347,13 +92,48 @@
|
|||
></n-input-number>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
|
||||
<SettingItemBox :alone="true" name="默认值设置">
|
||||
<SettingItem :alone="false" name="地图显示">
|
||||
<n-select
|
||||
v-model:value="optionData.dataStyle.mapListValue"
|
||||
:options="[
|
||||
{ label: '水源', value: 'water' },
|
||||
{ label: '物资', value: 'goods' },
|
||||
{ label: '营房', value: 'barrack' },
|
||||
{ label: '防火通道', value: 'fanghuotongdao' },
|
||||
{ label: '三轮通道', value: 'sanluntongdao' },
|
||||
{ label: '步行道', value: 'buxingdao' },
|
||||
]"
|
||||
placeholder="请选择选项(可多选)"
|
||||
clearable
|
||||
multiple
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem :alone="false" name="资源列表">
|
||||
<n-radio-group v-model:value="optionData.dataStyle.buttonValue" name="radiogroup">
|
||||
<n-radio value="0"> 水源 </n-radio>
|
||||
<n-radio value="1"> 物资 </n-radio>
|
||||
<n-radio value="2"> 营房 </n-radio>
|
||||
</n-radio-group>
|
||||
</SettingItem>
|
||||
<SettingItem :alone="false" name="距离">
|
||||
<n-radio-group v-model:value="optionData.dataStyle.distanceradio" name="radiogroup">
|
||||
<n-radio value="1"> 1km以内 </n-radio>
|
||||
<n-radio value="2"> 5km以内 </n-radio>
|
||||
<n-radio value="3"> 10km以内 </n-radio>
|
||||
<n-radio value="4"> 20km以内 </n-radio>
|
||||
<n-radio value="5"> 全部 </n-radio>
|
||||
</n-radio-group>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
|
||||
<CollapseItem name="表格数据显示设置" :expanded="true">
|
||||
<span style="font-size: 12px; margin-left: 8px">
|
||||
表格数据(请先确定数据部分,再确定表格数据)
|
||||
</span>
|
||||
<CollapseItem name="水源-表格数据显示设置" :expanded="true">
|
||||
<div style="overflow-x: auto">
|
||||
<span style="font-size: 12px; margin-left: 8px">
|
||||
表格数据(请先确定数据部分,再确定表格数据)
|
||||
</span>
|
||||
<n-table
|
||||
class="go-request-header-table-box"
|
||||
style="margin-top: 12px"
|
||||
|
|
@ -407,7 +187,7 @@
|
|||
</SettingItem>
|
||||
<SettingItem :alone="false" name="序列宽度">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.orderDivWidth"
|
||||
v-model:value="optionData.dataStyle.tableOrderDivWidth"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="序列宽度"
|
||||
|
|
@ -415,7 +195,7 @@
|
|||
</SettingItem>
|
||||
<SettingItem :alone="false" name="操作列宽度">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.buttonDivWidth"
|
||||
v-model:value="optionData.dataStyle.tableButtonDivWidth"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="操作列宽度"
|
||||
|
|
@ -500,11 +280,6 @@
|
|||
<n-switch v-model:value="optionData.dataStyle.tableBordered" size="small"></n-switch>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
<SettingItem name="是否使用斑马条纹">
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.dataStyle.tableStriped" size="small"></n-switch>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
<SettingItem name="是否不设定行的分割线">
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.dataStyle.tableSigleColumn" size="small"></n-switch>
|
||||
|
|
@ -523,28 +298,21 @@
|
|||
</SettingItem>
|
||||
<SettingItem name="是否显示序号列">
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.dataStyle.orderBumberShow" size="small"></n-switch>
|
||||
<n-switch
|
||||
v-model:value="optionData.dataStyle.tableOrderBumberShow"
|
||||
size="small"
|
||||
></n-switch>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
<SettingItem name="是否显示操作列">
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.dataStyle.buttonDivShow" size="small"></n-switch>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
<SettingItem name="是否显示第一按钮">
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.dataStyle.buttonDivShow1" size="small"></n-switch>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
<SettingItem name="是否显示第二按钮">
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.dataStyle.buttonDivShow2" size="small"></n-switch>
|
||||
<n-switch v-model:value="optionData.dataStyle.tableButtonDivShow" size="small"></n-switch>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
|
||||
<CollapseItem name="表格样式设置" :expanded="true">
|
||||
<CollapseItem name="水源-表格样式设置" :expanded="true">
|
||||
<SettingItemBox name="整体设置">
|
||||
<SettingItem name="上方距离">
|
||||
<n-input-number
|
||||
|
|
@ -611,21 +379,6 @@
|
|||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
<SettingItemBox :alone="false" name="表格设置">
|
||||
<SettingItem name="表格背景颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.tableDataBackgroud"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="是否使用表格背景颜色">
|
||||
<n-space>
|
||||
<n-switch
|
||||
v-model:value="optionData.dataStyle.tableDataBackgroudShow"
|
||||
size="small"
|
||||
></n-switch>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
<SettingItem name="表格字体颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
|
|
@ -643,6 +396,314 @@
|
|||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
|
||||
<CollapseItem name="物资-数据显示设置" :expanded="true">
|
||||
<SettingItemBox name="整体设置">
|
||||
<SettingItem name="上方距离">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.goodsMarginTop"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="上方距离"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="左右距离">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.goodsMarginLeft"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="左右距离"
|
||||
/>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
<SettingItemBox name="单个内里样式设置">
|
||||
<SettingItem name="上方距离">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.goodsDivMarginTop"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="上方距离"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="左右距离">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.goodsDivMarginLeft"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="左右距离"
|
||||
/>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
|
||||
<SettingItemBox name="标题设置">
|
||||
<SettingItem name="名称字体颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.goodsTitleFontColor1"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="名称字体大小">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.goodsTitleFontSize1"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="名称字体大小"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="距离字体颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.goodsTitleFontColor2"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="距离字体大小">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.goodsTitleFontSize2"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="距离字体大小"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="预计时间字体颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.goodsTitleFontColor3"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="预计时间字体大小">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.goodsTitleFontSize3"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="预计时间字体大小"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="按钮背景颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.goodsButtonBackgroud"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="按钮字体颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.goodsButtonFontColor"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="按钮字体大小">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.goodsButtonFontSize"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="按钮字体大小"
|
||||
/>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
|
||||
<SettingItemBox name="间隔线设置">
|
||||
<SettingItem name="线起始颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.goodsLineStartColor"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem>
|
||||
<n-button size="small" @click="optionData.dataStyle.goodsLineStartColor = '#4DFFB5'">
|
||||
恢复默认
|
||||
</n-button>
|
||||
</SettingItem>
|
||||
<SettingItem name="线终结颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.goodsLineEndColor"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem>
|
||||
<n-button size="small" @click="optionData.dataStyle.goodsLineEndColor = '#0B4D2C'">
|
||||
恢复默认
|
||||
</n-button>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
|
||||
<SettingItemBox name="文本设置">
|
||||
<SettingItem name="文本字体颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.goodsTextFontColor"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="文本字体大小">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.goodsTextFontSize"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="文本字体大小"
|
||||
/>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
|
||||
<CollapseItem name="营房-数据显示设置" :expanded="true">
|
||||
<SettingItemBox name="整体设置">
|
||||
<SettingItem name="上方距离">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.barrackMarginTop"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="上方距离"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="左右距离">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.barrackMarginLeft"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="左右距离"
|
||||
/>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
<SettingItemBox name="单个内里样式设置">
|
||||
<SettingItem name="上方距离">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.barrackDivMarginTop"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="上方距离"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="左右距离">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.barrackDivMarginLeft"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="左右距离"
|
||||
/>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
|
||||
<SettingItemBox name="标题设置">
|
||||
<SettingItem name="名称字体颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.barrackTitleFontColor1"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="名称字体大小">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.barrackTitleFontSize1"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="名称字体大小"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="距离字体颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.barrackTitleFontColor2"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="距离字体大小">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.barrackTitleFontSize2"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="距离字体大小"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="预计时间字体颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.barrackTitleFontColor3"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="预计时间字体大小">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.barrackTitleFontSize3"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="预计时间字体大小"
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem name="按钮背景颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.barrackButtonBackgroud"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="按钮字体颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.barrackButtonFontColor"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="按钮字体大小">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.barrackButtonFontSize"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="按钮字体大小"
|
||||
/>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
|
||||
<SettingItemBox name="间隔线设置">
|
||||
<SettingItem name="线起始颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.barrackLineStartColor"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem>
|
||||
<n-button size="small" @click="optionData.dataStyle.barrackLineStartColor = '#4DFFB5'">
|
||||
恢复默认
|
||||
</n-button>
|
||||
</SettingItem>
|
||||
<SettingItem name="线终结颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.barrackLineEndColor"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem>
|
||||
<n-button size="small" @click="optionData.dataStyle.barrackLineEndColor = '#0B4D2C'">
|
||||
恢复默认
|
||||
</n-button>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
|
||||
<SettingItemBox name="文本设置">
|
||||
<SettingItem name="文本字体颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.dataStyle.barrackTextFontColor"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="文本字体大小">
|
||||
<n-input-number
|
||||
v-model:value="optionData.dataStyle.barrackTextFontSize"
|
||||
:min="0"
|
||||
size="small"
|
||||
placeholder="文本字体大小"
|
||||
/>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
|
@ -733,94 +794,4 @@
|
|||
immediate: true,
|
||||
},
|
||||
);
|
||||
|
||||
// 筛选方式
|
||||
function getOptionsByShowType(filtersetItem) {
|
||||
let result: any = [];
|
||||
if (filtersetItem.showType) {
|
||||
switch (filtersetItem.showType) {
|
||||
case 'checkbox':
|
||||
// 多选框
|
||||
result = [
|
||||
{ label: '等于', value: 'equal' },
|
||||
{ label: '含有', value: 'contain' },
|
||||
];
|
||||
break;
|
||||
case 'radio':
|
||||
// 单选框
|
||||
result = [
|
||||
{ label: '大于', value: 'greater' },
|
||||
{ label: '小于', value: 'less' },
|
||||
{ label: '大于等于', value: 'greaterAndEqual' },
|
||||
{ label: '小于等于', value: 'lessAndEqual' },
|
||||
{ label: '等于', value: 'equal' },
|
||||
{ label: '不等于', value: 'notequal' },
|
||||
{ label: '含有', value: 'contain' },
|
||||
{ label: '不含有', value: 'notcontain' },
|
||||
];
|
||||
break;
|
||||
case 'select':
|
||||
// 下拉框
|
||||
result = [
|
||||
{ label: '等于', value: 'equal' },
|
||||
{ label: '含有', value: 'contain' },
|
||||
];
|
||||
break;
|
||||
case 'selectGroup':
|
||||
// 下拉框(多选)
|
||||
result = [
|
||||
{ label: '等于', value: 'equal' },
|
||||
{ label: '含有', value: 'contain' },
|
||||
];
|
||||
break;
|
||||
case 'buttonGroup':
|
||||
// 按钮组
|
||||
result = [
|
||||
{ label: '等于', value: 'equal' },
|
||||
{ label: '不等于', value: 'notequal' },
|
||||
{ label: '含有', value: 'contain' },
|
||||
{ label: '不含有', value: 'notcontain' },
|
||||
];
|
||||
break;
|
||||
case 'buttonGroupList':
|
||||
// 按钮组(多选)
|
||||
result = [
|
||||
{ label: '等于', value: 'equal' },
|
||||
{ label: '不等于', value: 'notequal' },
|
||||
{ label: '含有', value: 'contain' },
|
||||
{ label: '不含有', value: 'notcontain' },
|
||||
];
|
||||
break;
|
||||
case 'inputSearch':
|
||||
// 列搜索框
|
||||
result = [{ label: '含有', value: 'contain' }];
|
||||
break;
|
||||
case 'inputSearchAll':
|
||||
// 全数据搜索框
|
||||
result = [{ label: '含有', value: 'contain' }];
|
||||
break;
|
||||
case 'timePicker':
|
||||
// 时间选择器
|
||||
result = [
|
||||
{ label: '大于', value: 'greater' },
|
||||
{ label: '小于', value: 'less' },
|
||||
{ label: '大于等于', value: 'greaterAndEqual' },
|
||||
{ label: '小于等于', value: 'lessAndEqual' },
|
||||
{ label: '等于', value: 'equal' },
|
||||
{ label: '不等于', value: 'notequal' },
|
||||
];
|
||||
break;
|
||||
case 'timeRange':
|
||||
// 时间范围
|
||||
result = [{ label: '在两者之间', value: 'between' }];
|
||||
break;
|
||||
case 'dateRange':
|
||||
// 日期范围
|
||||
result = [{ label: '在两者之间', value: 'between' }];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -46,141 +46,141 @@
|
|||
"convert": "1"
|
||||
}
|
||||
],
|
||||
"filterset": [
|
||||
{
|
||||
"title": "地图显示",
|
||||
"field": "type",
|
||||
"compareType": "contain",
|
||||
"showType": "checkbox",
|
||||
"value": [ "水源", "物资", "营房", "防火通道", "三轮通道", "步行道" ],
|
||||
"options": [
|
||||
{ "label": "水源", "value": "水源" },
|
||||
{ "label": "物资", "value": "物资" },
|
||||
{ "label": "营房", "value": "营房" },
|
||||
{ "label": "防火通道", "value": "防火通道" },
|
||||
{ "label": "三轮通道", "value": "三轮通道" },
|
||||
{ "label": "步行道", "value": "步行道" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "资源列表",
|
||||
"field": "type",
|
||||
"compareType": "equal",
|
||||
"showType": "buttonGroup",
|
||||
"value": null,
|
||||
"options": [
|
||||
{ "label": "水源", "value": "水源" },
|
||||
{ "label": "物资", "value": "物资" },
|
||||
{ "label": "营房", "value": "营房" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "重点资源",
|
||||
"field": null,
|
||||
"compareType": null,
|
||||
"showType": null,
|
||||
"value": null,
|
||||
"options": [
|
||||
{ "label": null, "value": null }
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "距离",
|
||||
"field": "distance",
|
||||
"compareType": "lessAndEqual",
|
||||
"showType": "radio",
|
||||
"value": null,
|
||||
"options": [
|
||||
{ "label": "1km以内", "value": "1" },
|
||||
{ "label": "5km以内", "value": "5" },
|
||||
{ "label": "10km以内", "value": "10" },
|
||||
{ "label": "20km以内", "value": "20" },
|
||||
{ "label": "全部", "value": null }
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
{
|
||||
"id": "1",
|
||||
"name": "坑塘",
|
||||
"type": "水源",
|
||||
"type": "0",
|
||||
"area": null,
|
||||
"time": null,
|
||||
"distance": "21.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025-03-01 00:05:45"
|
||||
},
|
||||
{
|
||||
"name": "东蒙布袋口检查",
|
||||
"type": "物资",
|
||||
"area": "300",
|
||||
"time": "12.50",
|
||||
"distance": "14.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025-03-11 00:05:45"
|
||||
},
|
||||
{
|
||||
"name": "北刘家庄蓄水池",
|
||||
"type": "营房",
|
||||
"area": "300",
|
||||
"time": "12.50",
|
||||
"distance": "0.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025/03/01 00:05:45"
|
||||
|
||||
"date": "2025-03-01 00:05:45",
|
||||
"goodsDetail": null,
|
||||
"situation": null,
|
||||
"teamLocation": null,
|
||||
"lng": "118.16247495",
|
||||
"lat": "35.36599084"
|
||||
},
|
||||
{
|
||||
"name": "防火通道",
|
||||
"type": "防火通道",
|
||||
"area": null,
|
||||
"time": null,
|
||||
"distance": "2.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025-12-01 00:05:45"
|
||||
},
|
||||
{
|
||||
"name": "步行道",
|
||||
"type": "步行道",
|
||||
"id": "2",
|
||||
"name": "东蒙布袋口检查",
|
||||
"type": "0",
|
||||
"area": "300",
|
||||
"time": "5.50",
|
||||
"time": "12.50",
|
||||
"distance": "1.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025-08-01 00:05:45"
|
||||
"date": "2025-03-11 00:05:45",
|
||||
"goodsDetail": null,
|
||||
"situation": null,
|
||||
"teamLocation": null,
|
||||
"lng": "118.153507",
|
||||
"lat": "35.369431"
|
||||
},
|
||||
{
|
||||
"name": "三轮通道",
|
||||
"type": "三轮通道",
|
||||
"id": "3",
|
||||
"name": "北刘家庄蓄水池",
|
||||
"type": "0",
|
||||
"area": "300",
|
||||
"time": "9.50",
|
||||
"time": "12.50",
|
||||
"distance": "5.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025-10-21 00:05:45"
|
||||
"date": "2025/03/01 00:05:45",
|
||||
"goodsDetail": null,
|
||||
"situation": null,
|
||||
"teamLocation": null,
|
||||
"lng": "118.16339875",
|
||||
"lat": "35.35693363"
|
||||
},
|
||||
{
|
||||
"name": "坑塘",
|
||||
"type": "水源",
|
||||
"id": "4",
|
||||
"name": "塔山林场物资储备库",
|
||||
"type": "1",
|
||||
"area": null,
|
||||
"time": null,
|
||||
"distance": "10.14",
|
||||
"distance": "3.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025-06-01 00:05:45"
|
||||
"date": "2025/03/01 00:05:45",
|
||||
"goodsDetail": "1、打草机 10个 2、干粉灭火弹 69箱 3、水剂灭火弹 45箱 4、高压细水雾 4台 5、斯蒂尔灭火机 13台 6、华盛泰山灭火机 2台 7、华盛泰山制草机 1台 8、打孔机 2台 9、肩抗灭火器 4个 10、森林灭火弹 6箱 11、扫把,20把 12、铁耙子 30把, 13、斯蒂尔制草机, 6个 14、高枝油锯 6个 15、水泵 2台 16、水枪 17个",
|
||||
"situation": null,
|
||||
"teamLocation": null,
|
||||
"lng": "118.11856589",
|
||||
"lat": "35.37110306"
|
||||
},
|
||||
{
|
||||
"id": "5",
|
||||
"name": "东蒙中队驻防地",
|
||||
"type": "2",
|
||||
"area": null,
|
||||
"time": null,
|
||||
"distance": "0.60",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025/03/01 00:05:45",
|
||||
"goodsDetail": null,
|
||||
"situation": "2辆皮卡、2辆运兵车、5台水泵、管带:2760米(92节)、22台风力灭火机、二号工具20个",
|
||||
"teamLocation": "东蒙中队驻地",
|
||||
"lng": "118.03173443854365",
|
||||
"lat": "35.43087222278798"
|
||||
},
|
||||
{
|
||||
"id": "6",
|
||||
"name": "东蒙布袋口检查",
|
||||
"type": "物资",
|
||||
"type": "0",
|
||||
"area": "300",
|
||||
"time": "12.50",
|
||||
"distance": "10.14",
|
||||
"distance": "1.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025-06-12 00:05:45"
|
||||
"date": "2025-03-11 00:05:45",
|
||||
"goodsDetail": null,
|
||||
"situation": null,
|
||||
"teamLocation": null,
|
||||
"lng": "118.19313469",
|
||||
"lat": "35.35926978"
|
||||
},
|
||||
{
|
||||
"id": "7",
|
||||
"name": "北刘家庄蓄水池",
|
||||
"type": "营房",
|
||||
"type": "0",
|
||||
"area": "300",
|
||||
"time": "12.50",
|
||||
"distance": "19.14",
|
||||
"distance": "5.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025-05-01 00:05:45"
|
||||
"date": "2025/03/01 00:05:45",
|
||||
"goodsDetail": null,
|
||||
"situation": null,
|
||||
"teamLocation": null,
|
||||
"lng": "118.16693284",
|
||||
"lat": "35.39109119"
|
||||
},
|
||||
{
|
||||
"id": "8",
|
||||
"name": "塔山林场物资储备库",
|
||||
"type": "1",
|
||||
"area": null,
|
||||
"time": null,
|
||||
"distance": "3.14",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025/03/01 00:05:45",
|
||||
"goodsDetail": "1、打草机 10个 2、干粉灭火弹 69箱 3、水剂灭火弹 45箱 4、高压细水雾 4台 5、斯蒂尔灭火机 13台 6、华盛泰山灭火机 2台 7、华盛泰山制草机 1台 8、打孔机 2台 9、肩抗灭火器 4个 10、森林灭火弹 6箱 11、扫把,20把 12、铁耙子 30把, 13、斯蒂尔制草机, 6个 14、高枝油锯 6个 15、水泵 2台 16、水枪 17个",
|
||||
"situation": null,
|
||||
"teamLocation": null,
|
||||
"lng": "118.16142131",
|
||||
"lat": "35.36308522"
|
||||
},
|
||||
{
|
||||
"id": "9",
|
||||
"name": "薛庄镇9号蓄水池",
|
||||
"type": "0",
|
||||
"area": null,
|
||||
"time": null,
|
||||
"distance": "0.60",
|
||||
"estimatedTime": "00:05:45",
|
||||
"date": "2025/03/01 00:05:45",
|
||||
"goodsDetail": null,
|
||||
"situation": "2辆皮卡、2辆运兵车、5台水泵、管带:2760米(92节)、22台风力灭火机、二号工具20个",
|
||||
"teamLocation": "东蒙中队驻地",
|
||||
"lng": "118.16303303",
|
||||
"lat": "35.36772074"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,158 @@
|
|||
<template>
|
||||
<div class="barrack">
|
||||
<div
|
||||
class="item"
|
||||
v-for="(dataItem, dataIndex) in filterData"
|
||||
:key="dataIndex"
|
||||
:class="dataIndex % 2 == 0 ? 'div_image1' : 'div_image2'"
|
||||
>
|
||||
<div class="text1">
|
||||
<div class="titleDiv">
|
||||
<span class="titleSpan1">{{ dataItem.name }}</span>
|
||||
<span class="titleSpan2">{{ dataItem.distance }}km </span>
|
||||
<span class="titleSpan3">预计到达时间:{{ dataItem.estimatedTime }}</span>
|
||||
</div>
|
||||
<div class="buttonDiv">
|
||||
<n-button class="button" size="small" @click="moveLocation(dataItem)">
|
||||
<Button1 :dataStyle="props.dataStyle" /> <span class="buttonSpan">定位</span>
|
||||
</n-button>
|
||||
<n-button class="button" size="small" @click="roamLocation(dataItem)">
|
||||
<Button2 :dataStyle="props.dataStyle" /> <span class="buttonSpan">漫游</span>
|
||||
</n-button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="rate"
|
||||
:style="{
|
||||
width: '100%',
|
||||
height: '3px',
|
||||
marginTop: '10px',
|
||||
marginBottom: '10px',
|
||||
background: `linear-gradient(90deg,
|
||||
${props.dataStyle.barrackLineStartColor} 0%,
|
||||
${props.dataStyle.barrackLineEndColor} 100%)`,
|
||||
}"
|
||||
/>
|
||||
<div class="text2"> 装备情况: {{ dataItem.situation }} </div>
|
||||
<div
|
||||
class="rate"
|
||||
:style="{
|
||||
width: '100%',
|
||||
height: '3px',
|
||||
marginTop: '10px',
|
||||
marginBottom: '10px',
|
||||
background: `linear-gradient(90deg,
|
||||
${props.dataStyle.barrackLineStartColor} 0%,
|
||||
${props.dataStyle.barrackLineEndColor} 100%)`,
|
||||
}"
|
||||
/>
|
||||
<div class="text2"> 队伍驻地: {{ dataItem.teamLocation }} </div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, PropType, toRefs, watch, reactive, ref } from 'vue';
|
||||
import dayjs from 'dayjs';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import Button1 from './button1.vue';
|
||||
import Button2 from './button2.vue';
|
||||
|
||||
const props = defineProps(['dataset', 'dataStyle', 'header', 'h', 'filterDivHeight']);
|
||||
const emit = defineEmits(['moveLocation', 'roamLocation']);
|
||||
|
||||
function moveLocation(dataItem) {
|
||||
emit('moveLocation', [dataItem.lng, dataItem.lat]);
|
||||
}
|
||||
function roamLocation(dataItem) {
|
||||
emit('roamLocation', [dataItem.lng, dataItem.lat]);
|
||||
}
|
||||
|
||||
// 筛选后的数据
|
||||
const filterData = computed(() => {
|
||||
return props.dataset.filter((item) => item.type == 2);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.barrack {
|
||||
overflow-y: auto;
|
||||
height: v-bind(
|
||||
'`${props.h -props.filterDivHeight - props.dataStyle.filterMarginTop - props.dataStyle.barrackMarginTop}px`'
|
||||
);
|
||||
margin-top: v-bind('`${props.dataStyle.barrackMarginTop}px`');
|
||||
padding-left: v-bind('`${props.dataStyle.barrackMarginLeft}px`');
|
||||
padding-right: v-bind('`${props.dataStyle.barrackMarginLeft}px`');
|
||||
}
|
||||
.barrack::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.barrack {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
.div_image1 {
|
||||
background: #165f58;
|
||||
}
|
||||
.div_image2 {
|
||||
background: #147c73;
|
||||
}
|
||||
|
||||
.item {
|
||||
padding-top: v-bind('`${props.dataStyle.barrackDivMarginTop}px`');
|
||||
padding-bottom: v-bind('`${props.dataStyle.barrackDivMarginTop}px`');
|
||||
padding-left: v-bind('`${props.dataStyle.barrackDivMarginLeft}px`');
|
||||
padding-right: v-bind('`${props.dataStyle.barrackDivMarginLeft}px`');
|
||||
}
|
||||
|
||||
.text1 {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
|
||||
.titleDiv {
|
||||
.titleSpan1 {
|
||||
font-size: v-bind('`${props.dataStyle.barrackTitleFontSize1}px`');
|
||||
font-weight: 800;
|
||||
color: v-bind('`${props.dataStyle.barrackTitleFontColor1}`');
|
||||
margin-right: 20px;
|
||||
}
|
||||
.titleSpan2 {
|
||||
font-size: v-bind('`${props.dataStyle.barrackTitleFontSize2}px`');
|
||||
font-weight: 400;
|
||||
color: v-bind('`${props.dataStyle.barrackTitleFontColor2}`');
|
||||
margin-right: 30px;
|
||||
}
|
||||
.titleSpan3 {
|
||||
font-size: v-bind('`${props.dataStyle.barrackTitleFontSize3}px`');
|
||||
font-weight: 400;
|
||||
color: v-bind('`${props.dataStyle.barrackTitleFontColor3}`');
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.buttonDiv {
|
||||
display: flex;
|
||||
justify-content: right;
|
||||
text-align: right;
|
||||
align-items: right;
|
||||
gap: 10px;
|
||||
}
|
||||
.button {
|
||||
display: inline-flex;
|
||||
background: v-bind('`${props.dataStyle.barrackButtonBackgroud}`');
|
||||
font-size: v-bind('`${props.dataStyle.barrackButtonFontSize}px`');
|
||||
color: v-bind('`${props.dataStyle.barrackButtonFontColor}`');
|
||||
|
||||
span {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text2 {
|
||||
font-size: v-bind('`${props.dataStyle.barrackTextFontSize}px`');
|
||||
color: v-bind('`${props.dataStyle.barrackTextFontColor}`');
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
<template>
|
||||
<div>
|
||||
<svg
|
||||
:width="props.dataStyle.tableButtonWidth"
|
||||
:height="props.dataStyle.tableButtonHeight"
|
||||
viewBox="0 0 22 22"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<title>编组 16</title>
|
||||
<defs>
|
||||
<linearGradient
|
||||
x1="50%"
|
||||
y1="0%"
|
||||
x2="50%"
|
||||
y2="100%"
|
||||
id="linearGradient-ZhiChu_ModalTable-1-1"
|
||||
>
|
||||
<stop stop-color="#009742" offset="0%"></stop>
|
||||
<stop stop-color="#A9FFBE" offset="56.1194042%"></stop>
|
||||
<stop stop-color="#AEFFC0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M6.5,0 C3.46386169,0.00319830091 1.00344429,2.28789449 1,5.10719402 C1,9.47732708 6,12.7778512 6.213125,12.9159776 C6.38534815,13.0280075 6.61465185,13.0280075 6.786875,12.9159776 C7,12.7778512 12,9.47732708 12,5.10719402 C11.9965557,2.28789449 9.53613831,0.00319830091 6.5,0 L6.5,0 Z M6.5,3.25003256 C7.6045695,3.25003256 8.5,4.08151206 8.5,5.10719402 C8.5,6.13287597 7.6045695,6.96435548 6.5,6.96435548 C5.3954305,6.96435548 4.5,6.13287597 4.5,5.10719402 C4.5,4.08151206 5.3954305,3.25003256 6.5,3.25003256 Z"
|
||||
id="path-ZhiChu_ModalTable-1-2"
|
||||
></path>
|
||||
<filter
|
||||
x="-54.5%"
|
||||
y="-46.2%"
|
||||
width="209.1%"
|
||||
height="190.4%"
|
||||
filterUnits="objectBoundingBox"
|
||||
id="filter-ZhiChu_ModalTable-1-3"
|
||||
>
|
||||
<feMorphology
|
||||
radius="0.5"
|
||||
operator="dilate"
|
||||
in="SourceAlpha"
|
||||
result="shadowSpreadOuter1"
|
||||
></feMorphology>
|
||||
<feOffset dx="0" dy="0" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur
|
||||
stdDeviation="1.5"
|
||||
in="shadowOffsetOuter1"
|
||||
result="shadowBlurOuter1"
|
||||
></feGaussianBlur>
|
||||
<feColorMatrix
|
||||
values="0 0 0 0 0 0 0 0 0 0.714933276 0 0 0 0 0 0 0 0 0.5 0"
|
||||
type="matrix"
|
||||
in="shadowBlurOuter1"
|
||||
></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="监测平台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="林业防火-智处-在线人员弹窗" transform="translate(-1373, -543)">
|
||||
<g id="在线人员弹窗----" transform="translate(418.2674, 225.0542)">
|
||||
<g id="编组-14" transform="translate(54.7326, 64)">
|
||||
<g id="列表" transform="translate(0, 242.9458)">
|
||||
<g id="map-pin-fill" transform="translate(900, 11)">
|
||||
<g id="编组-16" transform="translate(5, 4)">
|
||||
<g id="形状" fill-rule="nonzero">
|
||||
<use
|
||||
fill="black"
|
||||
fill-opacity="1"
|
||||
filter="url(#filter-ZhiChu_ModalTable-1-3)"
|
||||
xlink:href="#path-ZhiChu_ModalTable-1-2"
|
||||
></use>
|
||||
<use
|
||||
fill="url(#linearGradient-ZhiChu_ModalTable-1-1)"
|
||||
xlink:href="#path-ZhiChu_ModalTable-1-2"
|
||||
></use>
|
||||
</g>
|
||||
<ellipse
|
||||
id="椭圆形"
|
||||
fill="#AEFFC0"
|
||||
opacity="0.527510143"
|
||||
cx="6.5"
|
||||
cy="13"
|
||||
rx="6.5"
|
||||
ry="1"
|
||||
></ellipse>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps(['dataStyle']);
|
||||
</script>
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<div>
|
||||
<svg
|
||||
:width="props.dataStyle.buttonWidth"
|
||||
:height="props.dataStyle.buttonHeight"
|
||||
:width="props.dataStyle.tableButtonWidth"
|
||||
:height="props.dataStyle.tableButtonHeight"
|
||||
viewBox="0 0 22 22"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
<template>
|
||||
<div class="goods">
|
||||
<div
|
||||
class="item"
|
||||
v-for="(dataItem, dataIndex) in filterData"
|
||||
:key="dataIndex"
|
||||
:class="dataIndex % 2 == 0 ? 'div_image1' : 'div_image2'"
|
||||
>
|
||||
<div class="text1">
|
||||
<div class="titleDiv">
|
||||
<span class="titleSpan1">{{ dataItem.name }}</span>
|
||||
<span class="titleSpan2">{{ dataItem.distance }}km </span>
|
||||
<span class="titleSpan3">预计到达时间:{{ dataItem.estimatedTime }}</span>
|
||||
</div>
|
||||
<div class="buttonDiv">
|
||||
<n-button class="button" size="small" @click="moveLocation(dataItem)">
|
||||
<Button1 :dataStyle="props.dataStyle" /> <span class="buttonSpan">定位</span>
|
||||
</n-button>
|
||||
<n-button class="button" size="small" @click="roamLocation(dataItem)">
|
||||
<Button2 :dataStyle="props.dataStyle" /> <span class="buttonSpan">漫游</span>
|
||||
</n-button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="rate"
|
||||
:style="{
|
||||
width: '100%',
|
||||
height: '3px',
|
||||
marginTop: '10px',
|
||||
marginBottom: '10px',
|
||||
background: `linear-gradient(90deg,
|
||||
${props.dataStyle.goodsLineStartColor} 0%,
|
||||
${props.dataStyle.goodsLineEndColor} 100%)`,
|
||||
}"
|
||||
/>
|
||||
<div class="text2"> 物资明细: {{ dataItem.goodsDetail }} </div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, PropType, toRefs, watch, reactive, ref } from 'vue';
|
||||
import dayjs from 'dayjs';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import Button1 from './button1.vue';
|
||||
import Button2 from './button2.vue';
|
||||
|
||||
const props = defineProps([
|
||||
'dataset',
|
||||
'dataStyle',
|
||||
'header',
|
||||
'h',
|
||||
'filterDivHeight',
|
||||
'searchValue',
|
||||
]);
|
||||
const emit = defineEmits(['moveLocation', 'roamLocation']);
|
||||
|
||||
function moveLocation(dataItem) {
|
||||
emit('moveLocation', [dataItem.lng, dataItem.lat]);
|
||||
}
|
||||
function roamLocation(dataItem) {
|
||||
emit('roamLocation', [dataItem.lng, dataItem.lat]);
|
||||
}
|
||||
|
||||
// 筛选后的数据
|
||||
const filterData = computed(() => {
|
||||
let result = props.dataset.filter((item) => item.type == 1);
|
||||
if (props.searchValue) {
|
||||
result = props.dataset.filter((item) => item.name.includes(props.searchValue));
|
||||
}
|
||||
return result;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.goods {
|
||||
overflow-y: auto;
|
||||
height: v-bind(
|
||||
'`${props.h -props.filterDivHeight - props.dataStyle.filterMarginTop - props.dataStyle.goodsMarginTop}px`'
|
||||
);
|
||||
margin-top: v-bind('`${props.dataStyle.goodsMarginTop}px`');
|
||||
padding-left: v-bind('`${props.dataStyle.goodsMarginLeft}px`');
|
||||
padding-right: v-bind('`${props.dataStyle.goodsMarginLeft}px`');
|
||||
}
|
||||
.goods::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.goods {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
.div_image1 {
|
||||
background: #165f58;
|
||||
}
|
||||
.div_image2 {
|
||||
background: #147c73;
|
||||
}
|
||||
|
||||
.item {
|
||||
padding-top: v-bind('`${props.dataStyle.goodsDivMarginTop}px`');
|
||||
padding-bottom: v-bind('`${props.dataStyle.goodsDivMarginTop}px`');
|
||||
padding-left: v-bind('`${props.dataStyle.goodsDivMarginLeft}px`');
|
||||
padding-right: v-bind('`${props.dataStyle.goodsDivMarginLeft}px`');
|
||||
}
|
||||
|
||||
.text1 {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
|
||||
.titleDiv {
|
||||
.titleSpan1 {
|
||||
font-size: v-bind('`${props.dataStyle.goodsTitleFontSize1}px`');
|
||||
font-weight: 800;
|
||||
color: v-bind('`${props.dataStyle.goodsTitleFontColor1}`');
|
||||
margin-right: 20px;
|
||||
}
|
||||
.titleSpan2 {
|
||||
font-size: v-bind('`${props.dataStyle.goodsTitleFontSize2}px`');
|
||||
font-weight: 400;
|
||||
color: v-bind('`${props.dataStyle.goodsTitleFontColor2}`');
|
||||
margin-right: 30px;
|
||||
}
|
||||
.titleSpan3 {
|
||||
font-size: v-bind('`${props.dataStyle.goodsTitleFontSize3}px`');
|
||||
font-weight: 400;
|
||||
color: v-bind('`${props.dataStyle.goodsTitleFontColor3}`');
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.buttonDiv {
|
||||
display: flex;
|
||||
justify-content: right;
|
||||
text-align: right;
|
||||
align-items: right;
|
||||
gap: 10px;
|
||||
}
|
||||
.button {
|
||||
display: inline-flex;
|
||||
background: v-bind('`${props.dataStyle.goodsButtonBackgroud}`');
|
||||
font-size: v-bind('`${props.dataStyle.goodsButtonFontSize}px`');
|
||||
color: v-bind('`${props.dataStyle.goodsButtonFontColor}`');
|
||||
|
||||
span {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text2 {
|
||||
font-size: v-bind('`${props.dataStyle.goodsTextFontSize}px`');
|
||||
color: v-bind('`${props.dataStyle.goodsTextFontColor}`');
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,282 @@
|
|||
<template>
|
||||
<div class="water">
|
||||
<!-- 表格数据 -->
|
||||
<!-- 表头 -->
|
||||
<div class="theadDiv">
|
||||
<n-table
|
||||
:bordered="props.dataStyle.tableBordered"
|
||||
:single-column="props.dataStyle.tableSigleColumn"
|
||||
:single-line="props.dataStyle.tableSingleLine"
|
||||
:size="props.dataStyle.tableSize"
|
||||
>
|
||||
<thead v-if="props.dataStyle.tableHeaderShow">
|
||||
<tr
|
||||
:style="{
|
||||
backgroud: props.dataStyle.tableHeaderBackgroud,
|
||||
}"
|
||||
>
|
||||
<th
|
||||
class="th"
|
||||
v-if="props.dataStyle.tableOrderBumberShow"
|
||||
:style="{
|
||||
width: headWidths[0] + 'px',
|
||||
}"
|
||||
>
|
||||
</th>
|
||||
<th
|
||||
class="th"
|
||||
v-for="(item, index) in props.header"
|
||||
:key="index"
|
||||
:style="{
|
||||
width: headWidths[props.dataStyle.tableOrderBumberShow ? index + 1 : index] + 'px',
|
||||
}"
|
||||
>
|
||||
{{ item.title }}
|
||||
</th>
|
||||
<th
|
||||
class="th"
|
||||
v-if="props.dataStyle.tableButtonDivShow"
|
||||
:style="{
|
||||
width: headWidths[headWidths.length - 1] + 'px',
|
||||
}"
|
||||
>
|
||||
操作
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</n-table>
|
||||
</div>
|
||||
<!-- 表格数据 -->
|
||||
<div class="tbodyDiv">
|
||||
<n-table
|
||||
:bordered="props.dataStyle.tableBordered"
|
||||
:single-column="props.dataStyle.tableSigleColumn"
|
||||
:single-line="props.dataStyle.tableSingleLine"
|
||||
:size="props.dataStyle.tableSize"
|
||||
>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(dataItem, dataIndex) in filterData"
|
||||
:key="dataIndex"
|
||||
:class="dataIndex % 2 == 0 ? 'td_image1' : 'td_image2'"
|
||||
>
|
||||
<!-- 序号 -->
|
||||
<td
|
||||
id="dataTd_order"
|
||||
v-if="props.dataStyle.tableOrderBumberShow"
|
||||
:style="{
|
||||
width: props.dataStyle.tableOrderDivWidth + 'px',
|
||||
}"
|
||||
>
|
||||
{{ dataIndex + 1 }}
|
||||
</td>
|
||||
<!-- 数据 -->
|
||||
<td
|
||||
:id="'dataTd_' + headerIndex"
|
||||
v-for="(headerItem, headerIndex) in props.header"
|
||||
:key="headerIndex"
|
||||
:style="{
|
||||
width: headerItem.width + 'px',
|
||||
}"
|
||||
>
|
||||
<span>
|
||||
{{ dataItem[headerItem.key] ? convertData(headerItem, dataItem) : '--' }}
|
||||
</span>
|
||||
</td>
|
||||
<!-- 操作 -->
|
||||
<td
|
||||
id="dataTd_button"
|
||||
v-if="props.dataStyle.tableButtonDivShow"
|
||||
:style="{
|
||||
width: props.dataStyle.tableButtonDivWidth + 'px',
|
||||
}"
|
||||
>
|
||||
<div class="buttonDiv">
|
||||
<n-button size="small" quaternary @click="moveLocation(dataItem)">
|
||||
<Button1 :dataStyle="props.dataStyle" />
|
||||
</n-button>
|
||||
<span class="buttonDivspan"> | </span>
|
||||
<n-button size="small" quaternary @click="roamLocation(dataItem)">
|
||||
<Button2 :dataStyle="props.dataStyle" />
|
||||
</n-button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</n-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, PropType, toRefs, watch, reactive, ref } from 'vue';
|
||||
import dayjs from 'dayjs';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import Button1 from './button1.vue';
|
||||
import Button2 from './button2.vue';
|
||||
|
||||
const props = defineProps(['dataset', 'dataStyle', 'header', 'h', 'filterDivHeight']);
|
||||
const emit = defineEmits(['moveLocation', 'roamLocation']);
|
||||
|
||||
function moveLocation(dataItem) {
|
||||
emit('moveLocation', [dataItem.lng, dataItem.lat]);
|
||||
}
|
||||
function roamLocation(dataItem) {
|
||||
emit('roamLocation', [dataItem.lng, dataItem.lat]);
|
||||
}
|
||||
|
||||
// 表头高度
|
||||
const headHeight: any = computed(() => {
|
||||
if (props.dataStyle.tableHeaderShow) {
|
||||
return document.querySelector('.theadDiv')?.offsetHeight + 10;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
// 数据表实际宽度
|
||||
const headWidths = computed(() => {
|
||||
let widths: any = [];
|
||||
if (props.dataStyle.tableHeaderShow) {
|
||||
setTimeout(() => {
|
||||
if (props.dataStyle.tableOrderBumberShow) {
|
||||
widths.push(document.getElementById('dataTd_order')?.offsetWidth);
|
||||
}
|
||||
props.header.forEach((item, index) => {
|
||||
let td = document.getElementById('dataTd_' + index);
|
||||
widths.push(td?.offsetWidth);
|
||||
});
|
||||
if (props.dataStyle.tableButtonDivShow) {
|
||||
widths.push(document.getElementById('dataTd_button')?.offsetWidth);
|
||||
}
|
||||
console.log(widths);
|
||||
}, 500);
|
||||
}
|
||||
return widths;
|
||||
});
|
||||
// 筛选后的数据
|
||||
const filterData = computed(() => {
|
||||
return props.dataset.filter((item) => item.type == 0);
|
||||
});
|
||||
|
||||
// 数据转换
|
||||
function convertData(header, data) {
|
||||
let prefix = header.prefix ? header.prefix : '';
|
||||
let suffix = header.suffix ? header.suffix : '';
|
||||
let convertData = data[header.key];
|
||||
|
||||
// 小数点保留后两位
|
||||
if (convertData && header.convert == '0' && isValidNumber(convertData)) {
|
||||
convertData =
|
||||
typeof convertData === 'string'
|
||||
? String(parseFloat(convertData).toFixed(2))
|
||||
: String(convertData.toFixed(2));
|
||||
}
|
||||
// 转换时间格式(例:0小时0分钟0秒)
|
||||
if (convertData && header.convert == '1' && isValidTime(convertData)) {
|
||||
convertData =
|
||||
dayjs(convertData, 'HH:mm:ss').hour() +
|
||||
'小时' +
|
||||
dayjs(convertData, 'HH:mm:ss').minute() +
|
||||
'分钟' +
|
||||
dayjs(convertData, 'HH:mm:ss').second() +
|
||||
'秒';
|
||||
}
|
||||
// 转换日期格式(例:YYYY-MM-DD HH:mm:ss)
|
||||
let format = 'YYYY-MM-DD HH:mm:ss';
|
||||
if (header.convert == '2') {
|
||||
format = 'YYYY-MM-DD';
|
||||
}
|
||||
if (header.convert == '3') {
|
||||
format = 'YYYY/MM/DD';
|
||||
}
|
||||
if (
|
||||
convertData &&
|
||||
['2', '3', '4'].includes(header.convert) &&
|
||||
isValidDate(convertData, format)
|
||||
) {
|
||||
convertData = dayjs(convertData).format(format);
|
||||
}
|
||||
return prefix + convertData + suffix;
|
||||
}
|
||||
|
||||
// 检查字符串可否转成数字
|
||||
function isValidNumber(str) {
|
||||
const regex = /^-?\d+(\.\d+)?$/;
|
||||
return regex.test(String(str).trim());
|
||||
}
|
||||
// 检查字符串可否转成时间
|
||||
function isValidTime(str) {
|
||||
const parsedDate = dayjs(str, 'HH:mm:ss');
|
||||
if (parsedDate.isValid()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 检查字符串可否转成日期
|
||||
function isValidDate(str, format) {
|
||||
const parsedDate = dayjs(str, format);
|
||||
if (parsedDate.isValid()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 表头
|
||||
.theadDiv {
|
||||
margin-top: v-bind('`${props.dataStyle.tableMarginTop}px`');
|
||||
padding-left: v-bind('`${props.dataStyle.tableMarginLeft}px`');
|
||||
padding-right: v-bind('`${props.dataStyle.tableMarginLeft}px`');
|
||||
}
|
||||
// 表格部分
|
||||
.tbodyDiv {
|
||||
overflow-y: auto;
|
||||
height: v-bind(
|
||||
'`${props.h -props.filterDivHeight - props.dataStyle.filterMarginTop - props.dataStyle.tableMarginTop}px`'
|
||||
);
|
||||
padding-left: v-bind('`${props.dataStyle.tableMarginLeft}px`');
|
||||
padding-right: v-bind('`${props.dataStyle.tableMarginLeft}px`');
|
||||
}
|
||||
.tbodyDiv::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.tbodyDiv {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
.th {
|
||||
background: v-bind('`${props.dataStyle.tableHeaderBackgroud}`');
|
||||
text-align: v-bind('`${props.dataStyle.tableAlign}`');
|
||||
color: v-bind('`${props.dataStyle.tableHeaderFontColor}`');
|
||||
font-size: v-bind('`${props.dataStyle.tableHeaderFontSize}px`');
|
||||
}
|
||||
td {
|
||||
text-align: v-bind('`${props.dataStyle.tableAlign}`');
|
||||
background: #ffffff00;
|
||||
color: v-bind('`${props.dataStyle.tableDataFontColor}`');
|
||||
font-size: v-bind('`${props.dataStyle.tableDataFontSize}px`');
|
||||
border-bottom: 0px;
|
||||
}
|
||||
.td_image1 {
|
||||
background-image: url('@/assets/images/chart/zhichu/component/ModalTable_td1.png');
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
.td_image2 {
|
||||
background-image: url('@/assets/images/chart/zhichu/component/ModalTable_td2.png');
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.buttonDiv {
|
||||
display: flex;
|
||||
align-items: v-bind('`${props.dataStyle.tableAlign}`');
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.buttonDivspan {
|
||||
color: #00611a;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
var numberRegexp = /[-+]?([0-9]*\.[0-9]+|[0-9]+)([eE][-+]?[0-9]+)?/;
|
||||
// Matches sequences like '100 100' or '100 100 100'.
|
||||
var tuples = new RegExp('^' + numberRegexp.source + '(\\s' + numberRegexp.source + '){1,}');
|
||||
/*
|
||||
* Parse WKT and return GeoJSON.
|
||||
*
|
||||
* @param {string} _ A WKT geometry
|
||||
* @return {?Object} A GeoJSON geometry object
|
||||
*/
|
||||
function parse(input) {
|
||||
if (!input) {
|
||||
return {
|
||||
"coordinates": [],
|
||||
"type": "LineString"
|
||||
}
|
||||
}
|
||||
var parts = input.split(';');
|
||||
var _ = parts.pop();
|
||||
var srid = (parts.shift() || '').split('=').pop();
|
||||
|
||||
var i = 0;
|
||||
|
||||
function $(re) {
|
||||
var match = _.substring(i).match(re);
|
||||
if (!match) return null;
|
||||
else {
|
||||
i += match[0].length;
|
||||
return match[0];
|
||||
}
|
||||
}
|
||||
|
||||
function crs(obj) {
|
||||
if (obj && srid.match(/\d+/)) {
|
||||
obj.crs = {
|
||||
type: 'name',
|
||||
properties: {
|
||||
name: 'urn:ogc:def:crs:EPSG::' + srid
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
function white() { $(/^\s*/); }
|
||||
|
||||
function multicoords() {
|
||||
white();
|
||||
var depth = 0;
|
||||
var rings = [];
|
||||
var stack = [rings];
|
||||
var pointer = rings;
|
||||
var elem;
|
||||
|
||||
while (elem =
|
||||
$(/^(\()/) ||
|
||||
$(/^(\))/) ||
|
||||
$(/^(,)/) ||
|
||||
$(tuples)) {
|
||||
if (elem === '(') {
|
||||
stack.push(pointer);
|
||||
pointer = [];
|
||||
stack[stack.length - 1].push(pointer);
|
||||
depth++;
|
||||
} else if (elem === ')') {
|
||||
// For the case: Polygon(), ...
|
||||
if (pointer.length === 0) return null;
|
||||
|
||||
pointer = stack.pop();
|
||||
// the stack was empty, input was malformed
|
||||
if (!pointer) return null;
|
||||
depth--;
|
||||
if (depth === 0) break;
|
||||
} else if (elem === ',') {
|
||||
pointer = [];
|
||||
stack[stack.length - 1].push(pointer);
|
||||
} else if (!elem.split(/\s/g).some(isNaN)) {
|
||||
Array.prototype.push.apply(pointer, elem.split(/\s/g).map(parseFloat));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
white();
|
||||
}
|
||||
|
||||
if (depth !== 0) return null;
|
||||
|
||||
return rings;
|
||||
}
|
||||
|
||||
function coords() {
|
||||
var list = [];
|
||||
var item;
|
||||
var pt;
|
||||
while (pt =
|
||||
$(tuples) ||
|
||||
$(/^(,)/)) {
|
||||
if (pt === ',') {
|
||||
list.push(item);
|
||||
item = [];
|
||||
} else if (!pt.split(/\s/g).some(isNaN)) {
|
||||
if (!item) item = [];
|
||||
Array.prototype.push.apply(item, pt.split(/\s/g).map(parseFloat));
|
||||
}
|
||||
white();
|
||||
}
|
||||
|
||||
if (item) list.push(item);
|
||||
else return null;
|
||||
|
||||
return list.length ? list : null;
|
||||
}
|
||||
|
||||
function point() {
|
||||
if (!$(/^(point(\sz)?)/i)) return null;
|
||||
white();
|
||||
if (!$(/^(\()/)) return null;
|
||||
var c = coords();
|
||||
if (!c) return null;
|
||||
white();
|
||||
if (!$(/^(\))/)) return null;
|
||||
return {
|
||||
type: 'Point',
|
||||
coordinates: c[0]
|
||||
};
|
||||
}
|
||||
|
||||
function multipoint() {
|
||||
if (!$(/^(multipoint)/i)) return null;
|
||||
white();
|
||||
var newCoordsFormat = _
|
||||
.substring(_.indexOf('(') + 1, _.length - 1)
|
||||
.replace(/\(/g, '')
|
||||
.replace(/\)/g, '');
|
||||
_ = 'MULTIPOINT (' + newCoordsFormat + ')';
|
||||
var c = multicoords();
|
||||
if (!c) return null;
|
||||
white();
|
||||
return {
|
||||
type: 'MultiPoint',
|
||||
coordinates: c
|
||||
};
|
||||
}
|
||||
|
||||
function multilinestring() {
|
||||
if (!$(/^(multilinestring)/i)) return null;
|
||||
white();
|
||||
var c = multicoords();
|
||||
if (!c) return null;
|
||||
white();
|
||||
return {
|
||||
type: 'MultiLineString',
|
||||
coordinates: c
|
||||
};
|
||||
}
|
||||
|
||||
function linestring() {
|
||||
if (!$(/^(linestring(\sz)?)/i)) return null;
|
||||
white();
|
||||
if (!$(/^(\()/)) return null;
|
||||
var c = coords();
|
||||
if (!c) return null;
|
||||
if (!$(/^(\))/)) return null;
|
||||
return {
|
||||
type: 'LineString',
|
||||
coordinates: c
|
||||
};
|
||||
}
|
||||
|
||||
function polygon() {
|
||||
if (!$(/^(polygon(\sz)?)/i)) return null;
|
||||
white();
|
||||
var c = multicoords();
|
||||
if (!c) return null;
|
||||
return {
|
||||
type: 'Polygon',
|
||||
coordinates: c
|
||||
};
|
||||
}
|
||||
|
||||
function multipolygon() {
|
||||
if (!$(/^(multipolygon)/i)) return null;
|
||||
white();
|
||||
var c = multicoords();
|
||||
if (!c) return null;
|
||||
return {
|
||||
type: 'MultiPolygon',
|
||||
coordinates: c
|
||||
};
|
||||
}
|
||||
|
||||
function geometrycollection() {
|
||||
var geometries = [];
|
||||
var geometry;
|
||||
|
||||
if (!$(/^(geometrycollection)/i)) return null;
|
||||
white();
|
||||
|
||||
if (!$(/^(\()/)) return null;
|
||||
while (geometry = root()) {
|
||||
geometries.push(geometry);
|
||||
white();
|
||||
$(/^(,)/);
|
||||
white();
|
||||
}
|
||||
if (!$(/^(\))/)) return null;
|
||||
|
||||
return {
|
||||
type: 'GeometryCollection',
|
||||
geometries: geometries
|
||||
};
|
||||
}
|
||||
|
||||
function root() {
|
||||
return point() ||
|
||||
linestring() ||
|
||||
polygon() ||
|
||||
multipoint() ||
|
||||
multilinestring() ||
|
||||
multipolygon() ||
|
||||
geometrycollection();
|
||||
}
|
||||
|
||||
return crs(root());
|
||||
}
|
||||
|
||||
export { parse }
|
||||
|
|
@ -0,0 +1,742 @@
|
|||
import axios from "axios";
|
||||
import { gcj02towgs84, wgs84togcj02 } from 'coordtransform'
|
||||
import * as turf from '@turf/turf'
|
||||
import { Url } from "./urlFormat";
|
||||
import { getAppEnvConfig } from '@/utils/env';
|
||||
import * as mars3d from 'mars3d';
|
||||
import { parse } from "./handleGeojson";
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
const urls = new Url()
|
||||
const GD_URL = "https://restapi.amap.com/v5/direction/driving"
|
||||
const GD_KEY = "6af6a87038f44c8c793aa70331f2b7ca"
|
||||
const { VITE_GLOB_API_URL } = getAppEnvConfig();
|
||||
|
||||
|
||||
|
||||
//路线的图层
|
||||
let pathGraphicLayers: any = null
|
||||
let pathOneGraphicLayers: any = null
|
||||
let pathWaterGraphicLayers: any = null
|
||||
let pathRoadGraphicLayers: any = null
|
||||
let pathRoadGraphicLayers1: any = null
|
||||
let pathRoadGraphicLayers2: any = null
|
||||
|
||||
|
||||
|
||||
//导航寻路
|
||||
export const getRouterFunc = (params, method = 'all') => {
|
||||
/**
|
||||
* method:
|
||||
* 当为 postgis时,仅仅使用postgis导航
|
||||
* 默认:all :高德 + postgis
|
||||
* gaode:高德
|
||||
*/
|
||||
let { startlng, startlat, endlng, endlat } = params
|
||||
|
||||
if (method == 'postgis') {
|
||||
//使用gpostgis进行导航
|
||||
return new Promise((resolve, reject) => {
|
||||
let postgisParams = {
|
||||
startlng: startlng,
|
||||
startlat: startlat,
|
||||
endlng: endlng,
|
||||
endlat: endlat,
|
||||
areaname: 'feixian',
|
||||
}
|
||||
getRouterByPostGis(postgisParams).then(geojson => {
|
||||
//postGisCoordinates:postgis返回的geojson取出坐标数组
|
||||
let postGisCoordinates = getOneLineCoordinatesFromGeometry(geojson)
|
||||
let startRouterLngLat = postGisCoordinates[0]
|
||||
let endRouterLngLat = postGisCoordinates.at(-1)
|
||||
let resObject = {
|
||||
allCoordinates: postGisCoordinates, //全部线路的合集
|
||||
postGisRoute: postGisCoordinates, // postgis线路
|
||||
gdRoute: [],
|
||||
startLngLat: [startlng, startlat], // 起点
|
||||
endLngLat: [endlng, endlat], //终点
|
||||
startRouterLngLat: startRouterLngLat, // 路线查询结果的起点
|
||||
endRouterLngLat: endRouterLngLat, //路线查询结果的终点
|
||||
}
|
||||
let simpleRoute = getMinimumRoute(resObject)
|
||||
resolve(simpleRoute)
|
||||
})
|
||||
}).catch(err => {
|
||||
|
||||
})
|
||||
}
|
||||
if (method == 'all') {
|
||||
// 先用高德进行导航
|
||||
return new Promise((resolve, reject) => {
|
||||
getRouterByGD(params).then(solution => {
|
||||
// solution 为多条线路的数组,现在先用第一条线路 solution.path[0]
|
||||
let gdRoute = solution.path[0]
|
||||
let postgisParams = {
|
||||
startlng: gdRoute.endCoordinates[0],
|
||||
startlat: gdRoute.endCoordinates[1],
|
||||
endlng: endlng,
|
||||
endlat: endlat,
|
||||
areaname: 'feixian',
|
||||
}
|
||||
//使用gpostgis求出剩下的路线
|
||||
getRouterByPostGis(postgisParams).then(geojson => {
|
||||
//postGisCoordinates:postgis返回的geojson取出坐标数组
|
||||
let postGisCoordinates = getOneLineCoordinatesFromGeometry(geojson)
|
||||
// 高德返回的第一条线路的坐标数组
|
||||
let path_gd = gdRoute.path_polyline
|
||||
//合并高德和postgis的路线
|
||||
let allCoordinates = path_gd.concat(postGisCoordinates)
|
||||
//导航线路的起点和终点
|
||||
let startRouterLngLat = allCoordinates[0]
|
||||
let endRouterLngLat = allCoordinates.at(-1)
|
||||
let resObject = {
|
||||
allCoordinates: allCoordinates, //全部线路
|
||||
gdRoute: path_gd, //高德的线路
|
||||
postGisRoute: postGisCoordinates, // postgis的线路
|
||||
startLngLat: [startlng, startlat], // 起点
|
||||
endLngLat: [endlng, endlat], //终点
|
||||
startRouterLngLat: startRouterLngLat, // 路线查询结果的起点
|
||||
endRouterLngLat: endRouterLngLat, //路线查询结果的终点
|
||||
}
|
||||
let simpleRoute = getMinimumRoute(resObject)
|
||||
resolve(simpleRoute)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//高德路线导航
|
||||
export const getRouterByGD = (params) => {
|
||||
/**
|
||||
* type:Object
|
||||
*/
|
||||
let { startlng, startlat, endlng, endlat } = params
|
||||
//wgs84转火星坐标系
|
||||
var gcj02StartLngLat = wgs84togcj02(startlng, startlat);
|
||||
var gcj02EndLngLat = wgs84togcj02(endlng, endlat);
|
||||
let gd_params = {
|
||||
origin: `${gcj02StartLngLat[0]},${gcj02StartLngLat[1]}`,
|
||||
destination: `${gcj02EndLngLat[0]},${gcj02EndLngLat[1]}`,
|
||||
show_fields: 'polyline',
|
||||
key: GD_KEY,
|
||||
strategy:2
|
||||
}
|
||||
let new_url = urls.getUrl(GD_URL, gd_params)
|
||||
return new Promise((resolve, reject) => {
|
||||
axios({
|
||||
method: "get",
|
||||
url: new_url,
|
||||
}).then((res) => {
|
||||
if (res.status === 200) {
|
||||
let solution = []
|
||||
//处理数据
|
||||
res.data.route.paths.map(path => {
|
||||
let route_len = path.distance
|
||||
let path_polyline = path.steps.map(step => {
|
||||
return step.polyline
|
||||
})
|
||||
let router_path_str = [] //暂时存放 ['117.927498,35.263264']
|
||||
path_polyline.forEach(polyline => {
|
||||
let step = polyline.split(';')
|
||||
router_path_str = router_path_str.concat(step)
|
||||
});
|
||||
// 去掉重复点
|
||||
let unique_router_path_str = [...new Set(router_path_str)]
|
||||
// 坐标转数组
|
||||
let unique_router_path = unique_router_path_str.map(path_str => {
|
||||
let lng_lat_list = path_str.split(',')
|
||||
//高德坐标系转wgs84坐标系
|
||||
var wgs84Coordinate = gcj02towgs84(...lng_lat_list);
|
||||
return wgs84Coordinate
|
||||
})
|
||||
//高德导航的起点和终点
|
||||
let startCoordinates = unique_router_path[0]
|
||||
let endCoordinates = unique_router_path.at(-1)
|
||||
// 高德地图返回的结果:方案一。长度,线
|
||||
solution.push(
|
||||
{
|
||||
route_len: route_len,
|
||||
path_polyline: unique_router_path,
|
||||
startCoordinates: startCoordinates,
|
||||
endCoordinates: endCoordinates
|
||||
}
|
||||
)
|
||||
})
|
||||
let result = {
|
||||
routerCount: parseInt(res.data.count),
|
||||
path: solution
|
||||
}
|
||||
resolve(result)
|
||||
} else {
|
||||
reject(res)
|
||||
}
|
||||
}).catch(err => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
//使用postgres + postgis寻路
|
||||
export const getRouterByPostGis = (params) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios.get("http://221.2.83.254:9001/api/FirePrevention/LoadRoad"
|
||||
+ "?startlng=" + params.startlng
|
||||
+ "&startlat=" + params.startlat
|
||||
+ "&endlng=" + params.endlng
|
||||
+ "&endlat=" + params.endlat
|
||||
+ "&areaname=" + params.areaname
|
||||
).then((res) => {
|
||||
if (res.data.length > 0) {
|
||||
console.log('res.data::: ', res.data);
|
||||
let LineString = res.data[0].route;
|
||||
if (LineString == null || LineString == "null") {
|
||||
//没有找到路线,返回空
|
||||
console.log('PostGIS未找到合适了路线')
|
||||
resolve(parse(null))
|
||||
} else {
|
||||
resolve(parse(LineString))
|
||||
}
|
||||
} else {
|
||||
console.log('PostGIS未找到合适了路线')
|
||||
resolve(parse(null))
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log('PostGIS寻路算法服务端错误')
|
||||
resolve(parse(null))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 绘制线路
|
||||
export const drawRouterFunc = (pathObject) => {
|
||||
let { allCoordinates, startLngLat, endLngLat, startRouterLngLat, endRouterLngLat, gdRoute, postGisRoute } = pathObject
|
||||
// 添加graphic
|
||||
if (pathGraphicLayers == null) {
|
||||
pathGraphicLayers = new mars3d.layer.GraphicLayer();
|
||||
window.globalMap.addLayer(pathGraphicLayers);
|
||||
} else {
|
||||
// pathGraphicLayers.clear();
|
||||
}
|
||||
//当只有两组数据时,说明没有导航的路线,直接使用虚线连接
|
||||
|
||||
if (allCoordinates.length == 2) {
|
||||
//只绘制开头到结尾的路线的路段
|
||||
let endPathGraphic = drawPolylineDashEntity([startLngLat, endLngLat], 'YELLOW')
|
||||
pathGraphicLayers.addGraphic(endPathGraphic);
|
||||
} else {
|
||||
// 导航数据路段
|
||||
// let gdPathGraphic = drawLineFlowEntity(gdRoute, 'YELLOW',10)
|
||||
// let postgisPathGraphic = drawLineFlowEntity(postGisRoute, 'RED',10)
|
||||
let pathGraphic = drawLineFlowEntity(allCoordinates, '#E6472B')
|
||||
|
||||
//开始的路段
|
||||
let startPathGraphic = drawPolylineDashEntity([startLngLat, startRouterLngLat], 'YELLOW')
|
||||
|
||||
//结尾的路段
|
||||
let endPathGraphic = drawPolylineDashEntity([endRouterLngLat, endLngLat], 'YELLOW')
|
||||
|
||||
// pathGraphicLayers.addGraphic(gdPathGraphic);
|
||||
// pathGraphicLayers.addGraphic(postgisPathGraphic);
|
||||
pathGraphicLayers.addGraphic(pathGraphic);
|
||||
pathGraphicLayers.addGraphic(startPathGraphic);
|
||||
pathGraphicLayers.addGraphic(endPathGraphic);
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制线路
|
||||
export const drawRoutersFunc = (pathObject) => {
|
||||
let { allCoordinates, startLngLat, endLngLat, startRouterLngLat, endRouterLngLat, gdRoute, postGisRoute } = pathObject
|
||||
// 添加graphic
|
||||
if (pathGraphicLayers == null) {
|
||||
pathGraphicLayers = new mars3d.layer.GraphicLayer();
|
||||
window.globalMap.addLayer(pathGraphicLayers);
|
||||
} else {
|
||||
|
||||
}
|
||||
//当只有两组数据时,说明没有导航的路线,直接使用虚线连接
|
||||
|
||||
if (allCoordinates.length == 2) {
|
||||
//只绘制开头到结尾的路线的路段
|
||||
// let endPathGraphic = drawPolylineDashEntity([startLngLat, endLngLat], 'YELLOW')
|
||||
// pathGraphicLayers.addGraphic(endPathGraphic);
|
||||
} else {
|
||||
// 导航数据路段
|
||||
// let gdPathGraphic = drawLineFlowEntity(gdRoute, 'YELLOW',10)
|
||||
// let postgisPathGraphic = drawLineFlowEntity(postGisRoute, 'RED',10)
|
||||
let pathGraphic = drawLineFlowEntityColor(allCoordinates, '#E6472B')
|
||||
|
||||
//开始的路段
|
||||
// let startPathGraphic = drawPolylineDashEntity([startLngLat, startRouterLngLat], 'YELLOW')
|
||||
|
||||
//结尾的路段
|
||||
// let endPathGraphic = drawPolylineDashEntity([endRouterLngLat, endLngLat], 'YELLOW')
|
||||
let endPathGraphic = drawPolylineEntity([endRouterLngLat, endLngLat], 'YELLOW')
|
||||
|
||||
|
||||
// pathGraphicLayers.addGraphic(gdPathGraphic);
|
||||
// pathGraphicLayers.addGraphic(postgisPathGraphic);
|
||||
pathGraphicLayers.addGraphic(pathGraphic);
|
||||
// pathGraphicLayers.addGraphic(startPathGraphic);
|
||||
pathGraphicLayers.addGraphic(endPathGraphic);
|
||||
}
|
||||
}
|
||||
|
||||
export const drawRoutersFuncWaterGrid = (pathObject) => {
|
||||
let { pointArr } = pathObject
|
||||
// 添加graphic
|
||||
if (pathWaterGraphicLayers == null) {
|
||||
pathWaterGraphicLayers = new mars3d.layer.GraphicLayer();
|
||||
window.globalMap.addLayer(pathWaterGraphicLayers);
|
||||
} else {
|
||||
|
||||
}
|
||||
//当只有两组数据时,说明没有导航的路线,直接使用虚线连接
|
||||
|
||||
if (pointArr.length == 2) {
|
||||
|
||||
} else {
|
||||
// 导航数据路段
|
||||
let pathGraphic
|
||||
pathGraphic = drawLineFlowEntityColor2(pointArr, '#56C3F9')
|
||||
|
||||
pathWaterGraphicLayers.addGraphic(pathGraphic);
|
||||
|
||||
}
|
||||
}
|
||||
export const drawRoutersFuncGrid = (pathObject) => {
|
||||
let { pointArr, Type } = pathObject
|
||||
// 添加graphic
|
||||
if (pathRoadGraphicLayers == null) {
|
||||
pathRoadGraphicLayers = new mars3d.layer.GraphicLayer();
|
||||
window.globalMap.addLayer(pathRoadGraphicLayers);
|
||||
}
|
||||
//当只有两组数据时,说明没有导航的路线,直接使用虚线连接
|
||||
|
||||
if (pointArr.length == 2) {
|
||||
|
||||
} else {
|
||||
// 导航数据路段
|
||||
|
||||
let pathGraphic;
|
||||
pathGraphic = drawLineFlowEntityColor1(pointArr, '#E6472B')
|
||||
pathRoadGraphicLayers.addGraphic(pathGraphic);
|
||||
}
|
||||
}
|
||||
export const drawRoutersFuncGrid1 = (pathObject) => {
|
||||
let { pointArr, Type } = pathObject
|
||||
// 添加graphic
|
||||
if (pathRoadGraphicLayers1 == null) {
|
||||
pathRoadGraphicLayers1 = new mars3d.layer.GraphicLayer();
|
||||
window.globalMap.addLayer(pathRoadGraphicLayers1);
|
||||
}
|
||||
//当只有两组数据时,说明没有导航的路线,直接使用虚线连接
|
||||
|
||||
if (pointArr.length == 2) {
|
||||
|
||||
} else {
|
||||
// 导航数据路段
|
||||
let pathGraphic1;
|
||||
pathGraphic1 = drawLineFlowEntityColor2(pointArr, '#1F5FDE')
|
||||
pathRoadGraphicLayers1.addGraphic(pathGraphic1);
|
||||
|
||||
}
|
||||
}
|
||||
export const drawRoutersFuncGrid2 = (pathObject) => {
|
||||
let { pointArr, Type } = pathObject
|
||||
// 添加graphic
|
||||
if (pathRoadGraphicLayers2 == null) {
|
||||
pathRoadGraphicLayers2 = new mars3d.layer.GraphicLayer();
|
||||
window.globalMap.addLayer(pathRoadGraphicLayers2);
|
||||
}
|
||||
//当只有两组数据时,说明没有导航的路线,直接使用虚线连接
|
||||
|
||||
if (pointArr.length == 2) {
|
||||
|
||||
} else {
|
||||
// 导航数据路段
|
||||
let pathGraphic2;
|
||||
pathGraphic2 = drawLineFlowEntityColor2(pointArr, '#9C9C9C')
|
||||
pathRoadGraphicLayers2.addGraphic(pathGraphic2);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 高亮路线
|
||||
export const drawOneRouterFunc = (pathObject) => {
|
||||
let { allCoordinates, startLngLat, endLngLat, startRouterLngLat, endRouterLngLat, gdRoute, postGisRoute } = pathObject
|
||||
// 添加graphic
|
||||
if (pathOneGraphicLayers == null) {
|
||||
pathOneGraphicLayers = new mars3d.layer.GraphicLayer();
|
||||
window.globalMap.addLayer(pathOneGraphicLayers);
|
||||
} else {
|
||||
pathOneGraphicLayers.clear();
|
||||
}
|
||||
//当只有两组数据时,说明没有导航的路线,直接使用虚线连接
|
||||
|
||||
if (allCoordinates.length == 2) {
|
||||
//只绘制开头到结尾的路线的路段
|
||||
let endPathGraphic = drawPolylineDashEntity([startLngLat, endLngLat], 'YELLOW')
|
||||
pathOneGraphicLayers.addGraphic(endPathGraphic);
|
||||
} else {
|
||||
// 导航数据路段
|
||||
// let gdPathGraphic = drawLineFlowEntity(gdRoute, 'YELLOW',10)
|
||||
// let postgisPathGraphic = drawLineFlowEntity(postGisRoute, 'RED',10)
|
||||
let pathGraphic = drawLineFlowEntity(allCoordinates, 'CYAN')
|
||||
|
||||
//开始的路段
|
||||
// let startPathGraphic = drawPolylineDashEntity([startLngLat, startRouterLngLat], 'YELLOW')
|
||||
|
||||
//结尾的路段
|
||||
// let endPathGraphic = drawPolylineDashEntity([endRouterLngLat, endLngLat], 'YELLOW')
|
||||
|
||||
// pathGraphicLayers.addGraphic(gdPathGraphic);
|
||||
// pathGraphicLayers.addGraphic(postgisPathGraphic);
|
||||
pathOneGraphicLayers.addGraphic(pathGraphic);
|
||||
// pathGraphicLayers.addGraphic(startPathGraphic);
|
||||
// pathGraphicLayers.addGraphic(endPathGraphic);
|
||||
}
|
||||
}
|
||||
|
||||
// 生成虚线实体
|
||||
const drawPolylineDashEntity = (positions, cesiumColor,width=5) => {
|
||||
return new mars3d.graphic.PolylineEntity({
|
||||
positions: positions,
|
||||
style: {
|
||||
width: width,
|
||||
clampToGround: true,
|
||||
materialType: mars3d.MaterialType.PolylineDash,
|
||||
materialOptions: {
|
||||
color: '#FFFF00',
|
||||
dashLength: 8.0,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const drawPolylineEntity = (positions, cesiumColor,width=5) => {
|
||||
return new mars3d.graphic.PolylineEntity({
|
||||
positions: positions,
|
||||
style: {
|
||||
width: width,
|
||||
clampToGround: true,
|
||||
// materialType: mars3d.MaterialType.PolylineDash,
|
||||
materialOptions: {
|
||||
color: '#FF0000',
|
||||
// dashLength: 8.0,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 生成动态线实体
|
||||
const drawLineFlowEntity = (positions, cesiumColor,width=5) => {
|
||||
return new mars3d.graphic.PolylineEntity({
|
||||
positions: positions,
|
||||
style: {
|
||||
width: width,
|
||||
clampToGround: true,
|
||||
materialType: mars3d.MaterialType.LineFlowColor,
|
||||
materialOptions: {
|
||||
color: cesiumColor,
|
||||
speed: 1000,
|
||||
percent: 1,
|
||||
alpha: 1
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const drawLineFlowEntityColor = (positions, cesiumColor,width=5) => {
|
||||
return new mars3d.graphic.PolylineEntity({
|
||||
positions: positions,
|
||||
style: {
|
||||
width: width,
|
||||
clampToGround: true,
|
||||
materialType: mars3d.MaterialType.LineFlowColor,
|
||||
materialOptions: {
|
||||
color: cesiumColor,
|
||||
speed: 1000,
|
||||
percent: 1,
|
||||
alpha: 1
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
const drawLineFlowEntityColor1 = (positions, cesiumColor,width=5) => {
|
||||
return new mars3d.graphic.PolylineEntity({
|
||||
positions: positions,
|
||||
style: {
|
||||
width: width,
|
||||
clampToGround: true,
|
||||
materialType: mars3d.MaterialType.LineFlowColor,
|
||||
materialOptions: {
|
||||
color: cesiumColor,
|
||||
speed: 1000,
|
||||
percent: 1,
|
||||
alpha: 1
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const drawLineFlowEntityColor2 = (positions, cesiumColor,width=5) => {
|
||||
return new mars3d.graphic.PolylineEntity({
|
||||
positions: positions,
|
||||
style: {
|
||||
width: width,
|
||||
clampToGround: true,
|
||||
materialType: mars3d.MaterialType.LineFlowColor,
|
||||
materialOptions: {
|
||||
color: cesiumColor,
|
||||
speed: 1000,
|
||||
percent: 1,
|
||||
alpha: 1
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
//删除路线
|
||||
export const clearRouterFunc = () => {
|
||||
if (pathGraphicLayers == null) {
|
||||
return false
|
||||
} else {
|
||||
pathGraphicLayers.clear();
|
||||
}
|
||||
|
||||
|
||||
if (pathOneGraphicLayers == null) {
|
||||
return false
|
||||
} else {
|
||||
pathOneGraphicLayers.clear();
|
||||
|
||||
}
|
||||
}
|
||||
//删除水网路线
|
||||
export const clearWaterRouterFunc = () => {
|
||||
if (pathWaterGraphicLayers == null) {
|
||||
return false
|
||||
} else {
|
||||
pathWaterGraphicLayers.clear();
|
||||
}
|
||||
}
|
||||
//删除路网路线
|
||||
export const clearRoadRouterFunc = () => {
|
||||
if (pathRoadGraphicLayers == null) {
|
||||
return false
|
||||
} else {
|
||||
pathRoadGraphicLayers.clear();
|
||||
}
|
||||
}
|
||||
export const clearRoadRouterFunc1 = () => {
|
||||
if (pathRoadGraphicLayers1 == null) {
|
||||
return false
|
||||
} else {
|
||||
pathRoadGraphicLayers1.clear();
|
||||
}
|
||||
}
|
||||
export const clearRoadRouterFunc2 = () => {
|
||||
if (pathRoadGraphicLayers2 == null) {
|
||||
return false
|
||||
} else {
|
||||
pathRoadGraphicLayers2.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//计算最近路线
|
||||
const getMinimumRoute = (pathObject) => {
|
||||
//备份Object
|
||||
let pathObjectClone = cloneDeep(pathObject)
|
||||
let { allCoordinates, startLngLat, endLngLat, startRouterLngLat, endRouterLngLat, gdRoute, postGisRoute } = pathObjectClone
|
||||
// 当只有一个点时(终点),说明高德地图和postgis都未查询到线路,直接返回两点
|
||||
if (allCoordinates.length <= 1) {
|
||||
pathObjectClone.allCoordinates = [startLngLat, endLngLat]
|
||||
return pathObjectClone
|
||||
}
|
||||
//当postgis寻路时,计算两条线路的重叠之处
|
||||
if (postGisRoute.length && gdRoute.length) {
|
||||
//实例化turf标准格式
|
||||
let gdRouteLine = turf.lineString(gdRoute);
|
||||
let postGisRouteLine = turf.lineString(postGisRoute);
|
||||
//获取postgis和高德寻路的所有交点
|
||||
let intersectsGeojson = turf.lineIntersect(gdRouteLine, postGisRouteLine);
|
||||
let intersectsCoordinates = getMultPointCoordinatesFromGeoJson(intersectsGeojson)
|
||||
//如果相交点大于1,说明路线有重复部分
|
||||
if (intersectsCoordinates.length > 1) {
|
||||
let lastIntersectsCoordinates = intersectsCoordinates[0]
|
||||
let [slicedGdCoordinates, slicedPostGisCoordinates] = sliceByPoint(startRouterLngLat, gdRouteLine, endRouterLngLat, postGisRoute, lastIntersectsCoordinates)
|
||||
allCoordinates = slicedGdCoordinates.concat(slicedPostGisCoordinates)
|
||||
//处理后的结果赋值给pathObjectClone
|
||||
pathObjectClone.gdRoute = slicedGdCoordinates
|
||||
pathObjectClone.postGisRoute = slicedPostGisCoordinates
|
||||
gdRouteLine = turf.lineString(slicedGdCoordinates);
|
||||
postGisRouteLine = turf.lineString(slicedPostGisCoordinates);
|
||||
}
|
||||
// 阈值计算重复路线,去除重复线路
|
||||
let overlapping = turf.lineOverlap(gdRouteLine, postGisRouteLine, { tolerance: 0.1 });
|
||||
|
||||
if (overlapping.features.length) {
|
||||
let lastOverlapPoint = overlapping.features.at(-1).geometry.coordinates[0]
|
||||
let [overlapGdCoordinates, overlapPostGisCoordinates] = sliceByPoint(startRouterLngLat, gdRouteLine, endRouterLngLat, postGisRoute, lastOverlapPoint)
|
||||
allCoordinates = overlapGdCoordinates.concat(overlapPostGisCoordinates)
|
||||
// 连接路段平滑过渡
|
||||
}
|
||||
|
||||
}
|
||||
// 转成turf标准线格式
|
||||
let allRouteLine = turf.lineString(allCoordinates);
|
||||
// 转成turf标准点格式
|
||||
let startLngLatPoint = turf.point(startLngLat);
|
||||
let startRouterLngLatPoint = turf.point(startRouterLngLat);
|
||||
let endLngLatPoint = turf.point(endLngLat);
|
||||
let endRouterLngLatPoint = turf.point(endRouterLngLat);
|
||||
//获取终点到导航线最近的点
|
||||
let snappedGeojson = turf.nearestPointOnLine(allRouteLine, endLngLatPoint, { units: 'miles' });
|
||||
let snappedCoordinates = getOnePointCoordinatesFromGeoJson(snappedGeojson)
|
||||
// 根据最近的点截取路线,取前半部分
|
||||
let slicedGeojson = turf.lineSlice(startRouterLngLat, turf.point(snappedCoordinates), allRouteLine);
|
||||
let slicedCoordinates = getOnePointCoordinatesFromGeoJson(slicedGeojson)
|
||||
//把截取后的路线赋值给pathObjectClone
|
||||
pathObjectClone.allCoordinates = slicedCoordinates
|
||||
//计算出发地到目的地的图上距离(直线)
|
||||
let distanceStartToEnd = turf.distance(startLngLatPoint, endLngLatPoint)
|
||||
//计算出发点到出发导航路线出发点的步行距离
|
||||
let distanceStartToStartRoute = turf.distance(startLngLatPoint, startRouterLngLatPoint)
|
||||
//计算终点到出发导航路线终点的步行距离
|
||||
let distanceEndToEndRoute = turf.distance(endLngLatPoint, endRouterLngLatPoint)
|
||||
//如果出发点与目的地的实际距离小于步行的距离,直接使用出发点到目的地的距离,导航此时不适用
|
||||
if (distanceStartToEnd < (distanceStartToStartRoute + distanceEndToEndRoute)) {
|
||||
pathObjectClone.allCoordinates = [startLngLat, endLngLat]
|
||||
}
|
||||
//把终点到导航终点改为距离线路的最近的的点
|
||||
pathObjectClone.endRouterLngLat = snappedCoordinates
|
||||
return pathObjectClone
|
||||
}
|
||||
|
||||
const sliceByPoint = (line1Start, line1, line2End, line2, point) => {
|
||||
/**
|
||||
* 根据点point把line1的前半部分和line2的后半部分进行拼接
|
||||
* line1Start:line1的起始点 [lng.lat]
|
||||
* line2End:line2 的终止点 [lng,lat]
|
||||
*/
|
||||
//拷贝line2的坐标数组进行倒序排列
|
||||
let line2Copy = [...line2]
|
||||
line2Copy.reverse()
|
||||
let line2CopyReverseLineString = turf.lineString(line2Copy);
|
||||
// 根据point截取路线,line1取前半部分
|
||||
// 根据point截取路线,line2取后半部分
|
||||
//然后将两部分拼接,让line1路线从第一个交点处转向line2路段
|
||||
let slicedLine1Geojson = turf.lineSlice(line1Start, turf.point(point), line1);
|
||||
let slicedLine1Coordinates = getOnePointCoordinatesFromGeoJson(slicedLine1Geojson)
|
||||
let slicedLine2Geojson = turf.lineSlice(line2End, turf.point(point), line2CopyReverseLineString);
|
||||
let slicedLine2Coordinates = getOnePointCoordinatesFromGeoJson(slicedLine2Geojson)
|
||||
slicedLine2Coordinates.reverse()
|
||||
return [slicedLine1Coordinates, slicedLine2Coordinates]
|
||||
}
|
||||
|
||||
|
||||
// 坐标转geoJson
|
||||
const comLineStringGeoJson = (coordinates) => {
|
||||
return {
|
||||
"type": "Feature",
|
||||
"properties": {},
|
||||
"geometry": {
|
||||
"coordinates": coordinates,
|
||||
"type": "LineString"
|
||||
}
|
||||
}
|
||||
}
|
||||
// 从一条线的geometry中获取坐标
|
||||
const getOneLineCoordinatesFromGeometry = (geometry) => {
|
||||
let coordinates = geometry.coordinates
|
||||
// console.log('geometry::: ', geometry);
|
||||
let list = []
|
||||
if (geometry.type == "MultiLineString") {
|
||||
coordinates.map(coord => {
|
||||
list = list.concat(coord)
|
||||
})
|
||||
} else if (geometry.type == 'LineString') {
|
||||
list = list.concat(geometry.coordinates)
|
||||
} else {
|
||||
list = []
|
||||
}
|
||||
return list
|
||||
|
||||
}
|
||||
//从一个点的geojson中返回坐标点
|
||||
const getOnePointCoordinatesFromGeoJson = (geojson) => {
|
||||
return geojson.geometry.coordinates
|
||||
}
|
||||
//从多个点的geojson中返回坐标点
|
||||
const getMultPointCoordinatesFromGeoJson = (geojson) => {
|
||||
// console.log('geojson::: ', geojson);
|
||||
return geojson.features.map(feature => {
|
||||
return feature.geometry.coordinates
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 全局漫游
|
||||
let carGraphicEntity: any = null;
|
||||
let carGraphicLayer: any = null;
|
||||
|
||||
export const handlerStartRoaming = (coordinates,roaming=true)=>{
|
||||
if(carGraphicLayer == null){
|
||||
carGraphicLayer = new mars3d.layer.GraphicLayer();
|
||||
window.globalMap.addLayer(carGraphicLayer);
|
||||
}else{
|
||||
carGraphicLayer.clear();
|
||||
}
|
||||
|
||||
carGraphicEntity = new mars3d.graphic.FixedRoute({
|
||||
name: "步行路线",
|
||||
frameRate: 1,
|
||||
speed: 500,
|
||||
autoStop: false, // 到达终点自动停止
|
||||
clockLoop: true, // 循环播放
|
||||
positions: coordinates,
|
||||
pauseTime: 0,
|
||||
camera: {
|
||||
type: "gs",
|
||||
radius: 2500
|
||||
},
|
||||
model: {
|
||||
// url: "//data.mars3d.cn/gltf/mars/car/bus3.gltf",
|
||||
url:"http://221.2.83.254:9010/cartoon_fire_truck/xiaofangche.gltf",
|
||||
scale: 5,
|
||||
minimumPixelSize: 50,
|
||||
clampToGround: true
|
||||
},
|
||||
circle: {
|
||||
radius: 10,
|
||||
materialType: mars3d.MaterialType.CircleWave,
|
||||
materialOptions: {
|
||||
color: "#ffff00",
|
||||
opacity: 0.3,
|
||||
speed: 10,
|
||||
count: 3,
|
||||
gradient: 0.1
|
||||
},
|
||||
clampToGround: true
|
||||
}
|
||||
})
|
||||
carGraphicLayer.addGraphic(carGraphicEntity)
|
||||
// 开始漫游
|
||||
carGraphicEntity.enabled = roaming;
|
||||
carGraphicEntity.start()
|
||||
}
|
||||
|
||||
export const handlerStopRoaming = ()=>{
|
||||
if(carGraphicEntity){
|
||||
carGraphicLayer.removeGraphic(carGraphicEntity);
|
||||
carGraphicEntity = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
export class Url {
|
||||
/**
|
||||
* 传入对象返回url参数
|
||||
* @param {Object} data {a:1}
|
||||
* @returns {string}
|
||||
*/
|
||||
getParam(data) {
|
||||
let url = '';
|
||||
for (let k in data) {
|
||||
let value = data[k] !== undefined ? data[k] : '';
|
||||
if (value !== undefined && value !== "" && value !== null) {
|
||||
url += `&${k}=${encodeURIComponent(value)}`
|
||||
}
|
||||
}
|
||||
return url ? url.substring(1) : ''
|
||||
}
|
||||
|
||||
/**
|
||||
* 将url和参数拼接成完整地址
|
||||
* @param {string} url url地址
|
||||
* @param {Json} data json对象
|
||||
* @returns {string}
|
||||
*/
|
||||
getUrl(url, data) {
|
||||
//看原始url地址中开头是否带?,然后拼接处理好的参数
|
||||
return url += (url.indexOf('?') < 0 ? '?' : '') + this.getParam(data)
|
||||
}
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ export const option = {
|
|||
|
||||
lineBackgroud: '#000000',
|
||||
lineBorderWidth: 1,
|
||||
lineBorderColor: '#ffffff',
|
||||
lineBorderColor: '#4D6647',
|
||||
lineHeight: 15,
|
||||
lineStartColor: '#0B4D2C',
|
||||
lineEndColor: '#4DFFB5',
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@
|
|||
align-items: center;
|
||||
justify-content: v-bind('`${option.dataStyle.labelAlign}`');
|
||||
width: v-bind('`${option.dataStyle.labelWidth}px`');
|
||||
border-right: 1px solid #ffffff;
|
||||
border-right: 1px solid v-bind('`${option.dataStyle.lineBorderColor}`');
|
||||
|
||||
color: v-bind('`${option.dataStyle.labelFontColor}`');
|
||||
font-size: v-bind('`${option.dataStyle.labelFontSize}px`');
|
||||
|
|
|
|||
Loading…
Reference in New Issue