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

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>