<script lang="ts" setup>
|
import type { PropType } from 'vue';
|
|
import { computed } from 'vue';
|
|
import { getFormDataOptionLabel } from '#/components/FormGenerator/src/helper/formDataOptions';
|
import { $t } from '#/locales';
|
|
defineOptions({ name: 'ChildTableColumn' });
|
|
const props = defineProps({
|
data: { type: Array as PropType<any[]>, default: () => [] },
|
head: { type: Array as PropType<any[]>, default: () => [] },
|
formData: { type: Object as PropType<Record<string, any>>, default: () => ({}) },
|
defaultNumber: { type: Number, default: 3 },
|
expand: { type: Boolean, default: false },
|
showOverflow: { type: Boolean, default: true },
|
});
|
const emit = defineEmits(['toggleExpand', 'toDetail']);
|
|
const fewData = computed(() => (props.data ? props.data.slice(0, props.defaultNumber) : []));
|
|
function toggleExpand() {
|
emit('toggleExpand');
|
}
|
function toDetail(modelId, id, propsValue) {
|
emit('toDetail', modelId, id, propsValue);
|
}
|
function getValueList(value, multiple) {
|
if (Array.isArray(value)) return value;
|
if (value === null || value === undefined || value === '') return [];
|
if (typeof value === 'string') {
|
try {
|
const list = JSON.parse(value);
|
if (Array.isArray(list)) return list;
|
} catch {}
|
if (multiple && value.includes(',')) return value.split(',');
|
}
|
return [value];
|
}
|
function getOptionText(headItem, value) {
|
const valueList = getValueList(value, headItem.multiple || headItem.jnpfKey === 'checkbox');
|
const fieldNames = headItem.props || {};
|
const valueKey = fieldNames.value || 'id';
|
const labelKey = fieldNames.label || 'fullName';
|
const options: any[] = [];
|
const loop = (list = []) => {
|
for (const item of list) {
|
options.push(item);
|
if (item.children?.length) loop(item.children);
|
}
|
};
|
loop(headItem.options || []);
|
return valueList
|
.map((valueItem) => {
|
const option = options.find((item) => String(item[valueKey]) === String(valueItem));
|
return option ? option[labelKey] : valueItem;
|
})
|
.filter((item) => item !== null && item !== undefined && item !== '')
|
.join(',');
|
}
|
function getCellText(headItem, value) {
|
if (headItem.__config__?.dataType === 'formData') {
|
const displayValue = getFormDataOptionLabel(headItem, props.formData, value);
|
return Array.isArray(displayValue) ? displayValue.join(',') : displayValue;
|
}
|
if (['checkbox', 'radio', 'select'].includes(headItem.jnpfKey)) return getOptionText(headItem, value);
|
return Array.isArray(value) ? value.join(',') : value;
|
}
|
</script>
|
|
<template>
|
<div class="child-table-column">
|
<template v-if="!expand">
|
<tr v-for="(item, index) in fewData" class="child-table__row" :key="index">
|
<td
|
v-for="(headItem, i) in head"
|
:key="i"
|
:style="{ width: `${headItem.width || headItem.minWidth}px`, 'text-align': headItem.align }"
|
:class="{ 'td-flex-1': !headItem.width }">
|
<div class="cell" v-if="headItem.jnpfKey === 'relationForm'">
|
<p class="link-text" :title="item[headItem.__vModel__]" @click="toDetail(headItem.modelId, item[`${headItem.__vModel__}_id`], headItem.propsValue)">
|
{{ item[headItem.__vModel__] }}
|
</p>
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'inputNumber'">
|
<jnpf-input-number v-model:value="item[headItem.__vModel__]" :precision="headItem.precision" :thousands="headItem.thousands" disabled detailed />
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'calculate'">
|
<jnpf-calculate
|
v-model:value="item[headItem.__vModel__]"
|
:is-storage="headItem.isStorage"
|
:precision="headItem.precision"
|
:thousands="headItem.thousands"
|
:round-type="headItem.roundType"
|
:type="headItem.type"
|
:date-cal-config="headItem.dateCalConfig"
|
detailed />
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'sign'">
|
<jnpf-sign v-model:value="item[headItem.__vModel__]" detailed />
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'signature'">
|
<jnpf-signature v-model:value="item[headItem.__vModel__]" detailed />
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'rate'">
|
<jnpf-rate v-model:value="item[headItem.__vModel__]" :count="headItem.count" :allow-half="headItem.allowHalf" disabled />
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'slider'">
|
<jnpf-slider v-model:value="item[headItem.__vModel__]" :min="headItem.min" :max="headItem.max" :step="headItem.step" disabled />
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'uploadImg'">
|
<jnpf-upload-img v-model:value="item[headItem.__vModel__]" disabled detailed simple v-if="item[headItem.__vModel__]?.length" />
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'uploadFile'">
|
<jnpf-upload-file v-model:value="item[headItem.__vModel__]" disabled detailed simple v-if="item[headItem.__vModel__]?.length" />
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'input'">
|
<jnpf-input
|
v-model:value="item[headItem.__vModel__]"
|
:use-mask="headItem.useMask"
|
:mask-config="headItem.maskConfig"
|
:show-overflow="showOverflow"
|
detailed />
|
</div>
|
<div class="cell" :class="{ ellipsis: showOverflow }" :title="getCellText(headItem, item[headItem.__vModel__])" v-else>
|
{{ getCellText(headItem, item[headItem.__vModel__]) }}
|
</div>
|
</td>
|
</tr>
|
</template>
|
<template v-if="expand">
|
<tr v-for="(item, index) in data" class="child-table__row" :key="index">
|
<td
|
v-for="(headItem, i) in head"
|
:key="i"
|
:style="{ width: `${headItem.width || headItem.minWidth}px`, 'text-align': headItem.align }"
|
:class="{ 'td-flex-1': !headItem.width }">
|
<div class="cell" v-if="headItem.jnpfKey === 'relationForm'">
|
<p class="link-text" :title="item[headItem.__vModel__]" @click="toDetail(headItem.modelId, item[`${headItem.__vModel__}_id`], headItem.propsValue)">
|
{{ item[headItem.__vModel__] }}
|
</p>
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'inputNumber'">
|
<jnpf-input-number v-model:value="item[headItem.__vModel__]" :precision="headItem.precision" :thousands="headItem.thousands" disabled detailed />
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'calculate'">
|
<jnpf-calculate
|
v-model:value="item[headItem.__vModel__]"
|
:is-storage="headItem.isStorage"
|
:precision="headItem.precision"
|
:thousands="headItem.thousands"
|
:round-type="headItem.roundType"
|
detailed />
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'sign'">
|
<jnpf-sign v-model:value="item[headItem.__vModel__]" detailed />
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'signature '">
|
<jnpf-signature v-model:value="item[headItem.__vModel__]" detailed />
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'rate'">
|
<jnpf-rate v-model:value="item[headItem.__vModel__]" :count="headItem.count" :allow-half="headItem.allowHalf" disabled />
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'slider'">
|
<jnpf-slider v-model:value="item[headItem.__vModel__]" :min="headItem.min" :max="headItem.max" :step="headItem.step" disabled />
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'uploadImg'">
|
<jnpf-upload-img v-model:value="item[headItem.__vModel__]" disabled detailed simple v-if="item[headItem.__vModel__]?.length" />
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'uploadFile'">
|
<jnpf-upload-file v-model:value="item[headItem.__vModel__]" disabled detailed simple v-if="item[headItem.__vModel__]?.length" />
|
</div>
|
<div class="cell" v-else-if="headItem.jnpfKey === 'input'">
|
<jnpf-input
|
v-model:value="item[headItem.__vModel__]"
|
:use-mask="headItem.useMask"
|
:mask-config="headItem.maskConfig"
|
:show-overflow="showOverflow"
|
detailed />
|
</div>
|
<div class="cell" :class="{ ellipsis: showOverflow }" :title="getCellText(headItem, item[headItem.__vModel__])" v-else>
|
{{ getCellText(headItem, item[headItem.__vModel__]) }}
|
</div>
|
</td>
|
</tr>
|
</template>
|
<div class="expand-more-btn" v-if="data && data.length > defaultNumber">
|
<a-button v-if="expand" type="link" @click="toggleExpand">{{ $t('views.dynamicModel.hideSome') }}</a-button>
|
<a-button v-if="!expand" type="link" @click="toggleExpand">{{ $t('views.dynamicModel.showMore') }}</a-button>
|
</div>
|
</div>
|
</template>
|