管道气线
This commit is contained in:
@ -27,6 +27,7 @@ import SelectUserV2 from './components/SelectUserV2.vue';
|
||||
import SelectUserShowTree from './components/SelectUserShowTree.vue';
|
||||
import CommonInfo from './components/CommonInfo.vue';
|
||||
import SelectArea from './components/SelectArea.vue';
|
||||
import SelectAreaCascader from './components/SelectAreaCascader.vue';
|
||||
import AutoCodeRule from './components/AutoCodeRule.vue';
|
||||
import MoneyChineseInput from './components/MoneyChineseInput.vue';
|
||||
import Image from './components/Image.vue';
|
||||
@ -108,6 +109,7 @@ componentMap.set('User', SelectUserV2);
|
||||
componentMap.set('UserTree', SelectUserShowTree);
|
||||
componentMap.set('Info', CommonInfo);
|
||||
componentMap.set('Area', SelectArea);
|
||||
componentMap.set('AreaCascader', SelectAreaCascader);
|
||||
componentMap.set('SubForm', SubForm);
|
||||
componentMap.set('Button', Button);
|
||||
componentMap.set('SelectMap', SelectMap);
|
||||
|
||||
187
src/components/Form/src/components/SelectAreaCascader.vue
Normal file
187
src/components/Form/src/components/SelectAreaCascader.vue
Normal file
@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<Cascader v-model:value="emitData" :options="options" :load-data="loadData" change-on-select @change="handleChange" :displayRender="handleRenderDisplay">
|
||||
<template #suffixIcon v-if="loading">
|
||||
<LoadingOutlined spin />
|
||||
</template>
|
||||
<template #notFoundContent v-if="loading">
|
||||
<span>
|
||||
<LoadingOutlined spin class="mr-1" />
|
||||
{{ t('component.form.apiSelectNotFound') }}
|
||||
</span>
|
||||
</template>
|
||||
</Cascader>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, unref, watch } from 'vue';
|
||||
import { Cascader } from 'ant-design-vue';
|
||||
import { get, omit } from 'lodash-es';
|
||||
import { LoadingOutlined } from '@ant-design/icons-vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { getAreaList } from '/@/api/mdm/CountryRegion';
|
||||
|
||||
interface Option {
|
||||
value: string;
|
||||
label: string;
|
||||
loading?: boolean;
|
||||
isLeaf?: boolean;
|
||||
children?: Option[];
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
value: String,
|
||||
excludeType: String
|
||||
});
|
||||
|
||||
const emit = defineEmits(['change', 'defaultChange', 'update:value']);
|
||||
|
||||
const apiData = ref<any[]>([]);
|
||||
const options = ref<Option[]>([]);
|
||||
const loading = ref<boolean>(false);
|
||||
const emitData = ref<any[]>([]);
|
||||
const isChange = ref(false);
|
||||
const labelField = 'name';
|
||||
const valueField = 'id';
|
||||
const childrenField = 'children';
|
||||
const resultField = 'data';
|
||||
|
||||
const asyncFetchParamKey = 'pid';
|
||||
const { t } = useI18n();
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
async (val, oldVal) => {
|
||||
if (!val && !!oldVal && val !== oldVal) {
|
||||
//重置
|
||||
emitData.value = [];
|
||||
return;
|
||||
}
|
||||
//选择时不重复请求接口
|
||||
if (isChange.value) return;
|
||||
|
||||
if (val) {
|
||||
emitData.value = val.split(',');
|
||||
} else {
|
||||
emitData.value = [];
|
||||
}
|
||||
await initialFetch();
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
apiData,
|
||||
(data) => {
|
||||
options.value = generatorOptions(data);
|
||||
if (emitData.value.length > 1) {
|
||||
getParentNodes(emitData.value, options.value);
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
function generatorOptions(options: any[]): Option[] {
|
||||
return options.reduce((prev, next: Recordable) => {
|
||||
if (next) {
|
||||
const value = next[valueField];
|
||||
const item = {
|
||||
...omit(next, [labelField, valueField]),
|
||||
...next,
|
||||
label: next[labelField],
|
||||
value: `${value}`,
|
||||
isLeaf: !next.hasChild
|
||||
};
|
||||
const children = Reflect.get(next, childrenField);
|
||||
if (children) {
|
||||
Reflect.set(item, childrenField, generatorOptions(children));
|
||||
}
|
||||
prev.push(item);
|
||||
}
|
||||
return prev;
|
||||
}, [] as Option[]);
|
||||
}
|
||||
|
||||
async function initialFetch() {
|
||||
apiData.value = [];
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await getAreaList({ pid: '', excludeType:props.excludeType });
|
||||
if (Array.isArray(res)) {
|
||||
apiData.value = res;
|
||||
return;
|
||||
}
|
||||
if (resultField) {
|
||||
apiData.value = get(res, resultField) || [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadData(selectedOptions: Option[]) {
|
||||
const targetOption = selectedOptions[selectedOptions.length - 1];
|
||||
targetOption.loading = true;
|
||||
|
||||
try {
|
||||
const res = await getAreaList({
|
||||
[asyncFetchParamKey]: Reflect.get(targetOption, 'id'),
|
||||
excludeType:props.excludeType
|
||||
});
|
||||
|
||||
if (Array.isArray(res)) {
|
||||
const children = generatorOptions(res);
|
||||
targetOption.children = children;
|
||||
return;
|
||||
}
|
||||
if (resultField) {
|
||||
const children = generatorOptions(get(res, resultField) || []);
|
||||
targetOption.children = children;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
} finally {
|
||||
targetOption.loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
//数据回显
|
||||
function getParentNodes(ids: any[], tree: any[]) {
|
||||
ids.forEach((id) => {
|
||||
tree.forEach(async (item: any) => {
|
||||
if (item.code === id) {
|
||||
item.children = [];
|
||||
const res = await getAreaList({ pid: item.id,excludeType:props.excludeType });
|
||||
item.children = res.map((child) => {
|
||||
return {
|
||||
...child,
|
||||
label: child.name,
|
||||
value: child.id,
|
||||
isLeaf: !child.hasChild
|
||||
};
|
||||
});
|
||||
getParentNodes(ids, item.children);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function handleChange(keys) {
|
||||
isChange.value = true;
|
||||
if (!keys) {
|
||||
emit('change', keys);
|
||||
return;
|
||||
}
|
||||
emit('change', keys.join(','));
|
||||
emit('update:value', keys?.join(','));
|
||||
emitData.value = props.value === undefined ? keys : emitData.value;
|
||||
}
|
||||
|
||||
function handleRenderDisplay({ labels, selectedOptions }) {
|
||||
if (unref(emitData).length === selectedOptions.length) {
|
||||
return labels.join(` / `);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -130,6 +130,7 @@ export type ComponentType =
|
||||
| 'UserTree'
|
||||
| 'Info'
|
||||
| 'Area'
|
||||
| 'AreaCascader'
|
||||
| 'SubForm'
|
||||
| 'DicSelect'
|
||||
| 'DbSelect'
|
||||
|
||||
@ -32,6 +32,7 @@ import SelectUser from './components/SelectUser.vue';
|
||||
import CommonInfo from './components/CommonInfo.vue';
|
||||
import SelectArea from './components/SelectArea.vue';
|
||||
// import SelectArea from './components/SelectArea.vue';
|
||||
import SelectAreaCascader from './components/SelectAreaCascader.vue';
|
||||
|
||||
import { BasicUpload } from '/@/components/Upload';
|
||||
import { StrengthMeter } from '/@/components/StrengthMeter';
|
||||
@ -69,7 +70,7 @@ componentMap.set('Dept', SelectDepartment);
|
||||
componentMap.set('User', SelectUser);
|
||||
componentMap.set('Info', CommonInfo);
|
||||
componentMap.set('Area', SelectArea);
|
||||
|
||||
componentMap.set('AreaCascader', SelectAreaCascader);
|
||||
componentMap.set('DatePicker', DatePicker);
|
||||
componentMap.set('MonthPicker', DatePicker.MonthPicker);
|
||||
componentMap.set('RangePicker', DatePicker.RangePicker);
|
||||
|
||||
@ -248,4 +248,5 @@ export type ComponentType =
|
||||
| 'User'
|
||||
| 'Info'
|
||||
| 'Area'
|
||||
| 'Text';
|
||||
| 'AreaCascader'
|
||||
| 'Text'
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
title: '表名',
|
||||
dataIndex: 'tableName',
|
||||
key: 'tableName',
|
||||
width: 100,
|
||||
width: 130,
|
||||
ellipsis: true,
|
||||
sorter: true
|
||||
},
|
||||
@ -29,7 +29,7 @@
|
||||
title: '属性名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
width: 100,
|
||||
width: 130,
|
||||
ellipsis: true,
|
||||
sorter: true
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
title: '操作类型',
|
||||
dataIndex: 'operationType',
|
||||
key: 'operationType',
|
||||
width: 80,
|
||||
width: 100,
|
||||
sorter: true,
|
||||
customRender: ({ record }) => {
|
||||
let text = record.operationType
|
||||
@ -52,7 +52,7 @@
|
||||
title: '原数据',
|
||||
dataIndex: 'oldValue',
|
||||
key: 'oldValue',
|
||||
width: 150,
|
||||
// width: 150,
|
||||
ellipsis: true,
|
||||
sorter: true
|
||||
},
|
||||
@ -60,7 +60,7 @@
|
||||
title: '新数据',
|
||||
dataIndex: 'newValue',
|
||||
key: 'newValue',
|
||||
width: 150,
|
||||
// width: 150,
|
||||
ellipsis: true,
|
||||
sorter: true
|
||||
},
|
||||
@ -75,7 +75,7 @@
|
||||
title: '操作IP',
|
||||
dataIndex: 'operationIp',
|
||||
key: 'operationIp',
|
||||
width: 150,
|
||||
width: 120,
|
||||
sorter: true
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user