You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
265 lines
7.5 KiB
265 lines
7.5 KiB
7 months ago
|
<!-- @format -->
|
||
|
|
||
|
<template>
|
||
|
<div class="edittable-contain">
|
||
|
<div class="operation">
|
||
|
<a-button type="primary" @click="operation('get')" v-if="api">获取数据</a-button>
|
||
|
<a-button type="primary" @click="operation('clear')">清除数据</a-button>
|
||
|
</div>
|
||
|
|
||
|
<NsBasicTable
|
||
|
:columns="columns"
|
||
|
:data-source="dataSource"
|
||
|
align="center"
|
||
|
rowKey="familyUuid"
|
||
|
@change="change"
|
||
|
:scroll="{ x: '800px' }"
|
||
|
>
|
||
|
<template #headerCell="{ title, column }">
|
||
|
<template v-if="column.required">
|
||
|
<div class="mainColum">{{ title }}</div>
|
||
|
</template>
|
||
|
</template>
|
||
|
<template #bodyCell="{ column, text, record, index }">
|
||
|
<template v-if="column.dataIndex !== 'action'">
|
||
|
<div>
|
||
|
<component
|
||
|
style="min-width: 120px"
|
||
|
v-model:value="record[column.dataIndex]"
|
||
|
:is="column.component"
|
||
|
:record="record"
|
||
|
v-bind="column.formProps || column.componentProps"
|
||
|
/>
|
||
|
<p v-if="column.validator" style="color: red">
|
||
|
{{ column.validator(record) === 'error' ? column.errorTitle : '' }}
|
||
|
</p>
|
||
|
</div>
|
||
|
</template>
|
||
|
<template v-if="column.dataIndex === 'action'">
|
||
|
<div style="min-width: 120px" class="column-operation">
|
||
|
<span style="cursor: pointer; color: rgb(27, 182, 182)" @click="remove(index)"
|
||
|
>移除</span
|
||
|
>
|
||
|
<span
|
||
|
style="cursor: pointer; color: rgb(27, 182, 182)"
|
||
|
@click="setOptions('down', index)"
|
||
|
>向下插入</span
|
||
|
>
|
||
|
<span style="cursor: pointer; color: rgb(27, 182, 182)" @click="setOptions('up', index)"
|
||
|
>向上插入</span
|
||
|
>
|
||
|
</div>
|
||
|
</template>
|
||
|
</template>
|
||
|
|
||
|
<template #footer v-if="!readonly">
|
||
|
<span style="cursor: pointer; color: rgb(27, 182, 182)" @click="add"> 添加</span>
|
||
|
</template>
|
||
|
</NsBasicTable>
|
||
|
</div>
|
||
|
</template>
|
||
|
<script lang="ts">
|
||
|
import { defineComponent, ref, PropType, nextTick, watch, unref, computed } from 'vue';
|
||
|
import { cloneDeep, get, isArray, isEqual, isFunction, isString, isUndefined } from 'lodash-es';
|
||
|
import { HttpRequestConfig, useApi } from '/nerv-lib/use/use-api';
|
||
|
import { useParams } from '/nerv-lib/use/use-params';
|
||
|
export default defineComponent({
|
||
|
name: 'NsCustomEditTable',
|
||
|
props: {
|
||
|
api: {
|
||
|
type: [String, Object, Function] as PropType<string | Function | HttpRequestConfig>,
|
||
|
required: true,
|
||
|
},
|
||
|
params: {
|
||
|
type: Object,
|
||
|
default: () => ({}),
|
||
|
},
|
||
|
resultField: {
|
||
|
type: String,
|
||
|
default: 'data.data',
|
||
|
},
|
||
|
columns: {
|
||
|
type: Array,
|
||
|
default: () => [],
|
||
|
},
|
||
|
initData: {
|
||
|
type: Array,
|
||
|
default: () => [],
|
||
|
},
|
||
|
readonly: {
|
||
|
type: Boolean,
|
||
|
default: () => false,
|
||
|
},
|
||
|
value: {
|
||
|
type: Array,
|
||
|
default: () => [],
|
||
|
},
|
||
|
formModel: {
|
||
|
type: Object as PropType<Recordable>,
|
||
|
default: () => ({}),
|
||
|
},
|
||
|
scroll: {
|
||
|
type: Object,
|
||
|
default: () => ({ x: '800px' }),
|
||
|
},
|
||
|
},
|
||
|
emits: ['change', 'validateChange'],
|
||
|
setup(props, { emit }) {
|
||
|
// const components = inject("components");
|
||
|
const columns = ref([]);
|
||
|
const dataSource = ref([]);
|
||
|
const { getParams } = useParams();
|
||
|
columns.value = props.columns;
|
||
|
dataSource.value = props.initData;
|
||
|
const add = () => {
|
||
|
// let info = JSON.parse(JSON.stringify(props.initItem));
|
||
|
// if (
|
||
|
// dataSource.value.length === 0
|
||
|
// ) {
|
||
|
dataSource.value.push({});
|
||
|
// }
|
||
|
console.log(dataSource.value);
|
||
|
};
|
||
|
const pagination = ref({
|
||
|
current: 1,
|
||
|
pageSize: 10,
|
||
|
});
|
||
|
const remove = (i: number) => {
|
||
|
let pagebase = (pagination.value.current - 1) * 10;
|
||
|
dataSource.value.splice(i + pagebase, 1);
|
||
|
};
|
||
|
|
||
|
const change = (pag, filters, sorter, { currentDataSource }) => {
|
||
|
pagination.value = pag;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* 获取数据
|
||
|
*/
|
||
|
const fetch = () => {
|
||
|
const requestConfig: HttpRequestConfig = { method: 'get' };
|
||
|
const { api, params: _params, resultField, filterData, dynamicParams } = props;
|
||
|
let params: Recordable = cloneDeep(_params);
|
||
|
// if (props.filterFiled && filterFiledRef.value) {
|
||
|
// params[props.filterFiled] = filterFiledRef.value;
|
||
|
// }
|
||
|
// let data;
|
||
|
if (dynamicParams) {
|
||
|
params = getParams(props.formModel, dynamicParams, { ...params });
|
||
|
// console.log('getParams', data);
|
||
|
}
|
||
|
const { httpRequest } = useApi();
|
||
|
httpRequest({ api, params, requestConfig })
|
||
|
.then((res: Recordable) => {
|
||
|
emit('validateChange', { help: undefined });
|
||
|
if (resultField) {
|
||
|
// debugger;
|
||
|
let data = get(res, resultField) || [];
|
||
|
// data = data.splice(Math.floor(Math.random() * 3), Math.floor(Math.random() * 5 + 5));
|
||
|
if (isFunction(filterData)) {
|
||
|
dataSource.value = data.filter(filterData);
|
||
|
} else {
|
||
|
dataSource.value = data;
|
||
|
}
|
||
|
emit('change', dataSource.value);
|
||
|
}
|
||
|
})
|
||
|
.catch((error: any) => {
|
||
|
if (error?.response?.status === 403) {
|
||
|
emit('validateChange', { help: '暂无权限', validateStatus: 'error' });
|
||
|
}
|
||
|
dataSource.value = [];
|
||
|
});
|
||
|
};
|
||
|
|
||
|
const operation = (name) => {
|
||
|
if (name === 'get') {
|
||
|
fetch();
|
||
|
}
|
||
|
if (name === 'clear') {
|
||
|
dataSource.value.splice(0);
|
||
|
emit('change', dataSource.value);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
const setOptions = (name, i) => {
|
||
|
let pagebase = (pagination.value.current - 1) * 10;
|
||
|
let index = i + pagebase;
|
||
|
if (name === 'up') {
|
||
|
if (index === 0) {
|
||
|
dataSource.value.unshift({});
|
||
|
} else {
|
||
|
dataSource.value.splice(index, 0, {});
|
||
|
}
|
||
|
}
|
||
|
if (name === 'down') {
|
||
|
dataSource.value.splice(index + 1, 0, {});
|
||
|
}
|
||
|
emit('change', dataSource.value);
|
||
|
};
|
||
|
|
||
|
watch(
|
||
|
() => props.value,
|
||
|
(val) => {
|
||
|
dataSource.value = props.value;
|
||
|
emit('change', val);
|
||
|
},
|
||
|
{ deep: true, immediate: true }
|
||
|
);
|
||
|
return {
|
||
|
remove,
|
||
|
add,
|
||
|
dataSource,
|
||
|
columns,
|
||
|
operation,
|
||
|
setOptions,
|
||
|
change,
|
||
|
};
|
||
|
},
|
||
|
// watch: {
|
||
|
// dataSource: {
|
||
|
// handler(val) {
|
||
|
// console.log(val);
|
||
|
// this.$emit('change', val);
|
||
|
// },
|
||
|
// deep: true,
|
||
|
// },
|
||
|
// },
|
||
|
});
|
||
|
</script>
|
||
|
<style lang="less" scoped>
|
||
|
:deep(.ant-table-thead)
|
||
|
> tr
|
||
|
> th:not(:last-child):not(.ant-table-selection-column):not(.ant-table-row-expand-icon-cell):not([colspan])::before {
|
||
|
display: none;
|
||
|
}
|
||
|
.mainColum {
|
||
|
&::before {
|
||
|
display: inline-block;
|
||
|
margin-right: 4 px;
|
||
|
color: #ff4d4f;
|
||
|
font-size: 12px;
|
||
|
font-family: SimSun, sans-serif;
|
||
|
line-height: 1;
|
||
|
content: '*';
|
||
|
}
|
||
|
}
|
||
|
:deep(.ant-form-item-explain.ant-form-item-explain-error) {
|
||
|
display: flex;
|
||
|
min-width: 130px !important;
|
||
|
width: 140px !important;
|
||
|
}
|
||
|
.operation {
|
||
|
padding-bottom: 8px;
|
||
|
.ant-btn {
|
||
|
margin-right: 16px;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.column-operation {
|
||
|
span {
|
||
|
margin-right: 8px;
|
||
|
}
|
||
|
}
|
||
|
</style>
|