<script lang="ts" setup>
|
import type { BasicColumn } from '@jnpf/ui/vxeTable';
|
|
import { computed, onMounted, reactive, toRefs } from 'vue';
|
|
import { useMessage } from '@jnpf/hooks';
|
import { BasicForm, useForm } from '@jnpf/ui/form';
|
import { useModal } from '@jnpf/ui/modal';
|
import { BasicVxeTable, useVxeTable } from '@jnpf/ui/vxeTable';
|
|
import { DownOutlined, RedoOutlined } from '@ant-design/icons-vue';
|
|
import { getTableList, updateSign } from '#/api/extend/table';
|
import { $t } from '#/locales';
|
import { useBaseStore } from '#/store';
|
|
import Form from '../commonForm/index.vue';
|
|
defineOptions({ name: 'ExtendTableDemoSignTable' });
|
|
interface State {
|
industryTypeList: any[];
|
options: any[];
|
list: any[];
|
listQuery: any;
|
total: number;
|
}
|
|
const state = reactive<State>({
|
industryTypeList: [],
|
options: [
|
{ label: '红色', value: '1', color: '#ff625c' },
|
{ label: '橙色', value: '2', color: '#f9a646' },
|
{ label: '黄色', value: '3', color: '#f4ce4a' },
|
{ label: '绿色', value: '4', color: '#6dcc51' },
|
{ label: '蓝色', value: '5', color: '#4bb8f3' },
|
{ label: '紫色', value: '6', color: '#d088e1' },
|
{ label: '灰色', value: '7', color: '#a5a5a8' },
|
{ label: '清空', value: '0', color: '' },
|
],
|
list: [],
|
listQuery: {
|
currentPage: 1,
|
pageSize: 20,
|
sort: 'desc',
|
keyword: '',
|
},
|
total: 0,
|
});
|
const { options, list } = toRefs(state);
|
const baseStore = useBaseStore();
|
const { createMessage } = useMessage();
|
const columns: BasicColumn[] = [
|
{ title: '项目名称', dataIndex: 'projectName', width: 200 },
|
{ title: '项目编码', dataIndex: 'projectCode', width: 160 },
|
{
|
title: '项目类型',
|
dataIndex: 'projectType',
|
width: 120,
|
customRender: ({ record }) => {
|
const item = state.industryTypeList.find((o) => o.id == record.projectType);
|
return item && item.fullName ? item.fullName : '';
|
},
|
},
|
{ title: '项目阶段', dataIndex: 'projectPhase', width: 120 },
|
{
|
title: '项目标记',
|
dataIndex: 'signArray',
|
width: 170,
|
align: 'center',
|
slots: { default: 'signArray' },
|
filters: [
|
{ label: '红色', value: '1' },
|
{ label: '橙色', value: '2' },
|
{ label: '黄色', value: '3' },
|
{ label: '绿色', value: '4' },
|
{ label: '蓝色', value: '5' },
|
{ label: '紫色', value: '6' },
|
{ label: '灰色', value: '7' },
|
],
|
filterMethod: ({ value, row }) => row.signArray.includes(value),
|
},
|
{ title: '客户名称', dataIndex: 'customerName', width: 200 },
|
{ title: '负责人', dataIndex: 'principal', width: 80 },
|
{ title: '立项人', dataIndex: 'jackStands', width: 80 },
|
{ title: '交互时间', dataIndex: 'interactionDate', width: 100, format: 'date|YYYY-MM-DD' },
|
{ title: '费用金额', dataIndex: 'costAmount', width: 100 },
|
{ title: '已用金额', dataIndex: 'tunesAmount', width: 100 },
|
{ title: '预计收入', dataIndex: 'projectedIncome', width: 100 },
|
{ title: '登记人', dataIndex: 'registrant', width: 80 },
|
{ title: '登记时间', dataIndex: 'registerDate', width: 150, format: 'date|YYYY-MM-DD HH:mm' },
|
{ title: '备注', dataIndex: 'description', width: 100 },
|
];
|
const [registerTable, { setLoading }] = useVxeTable({
|
columns,
|
useSearchForm: false,
|
actionColumn: {
|
width: 100,
|
title: '操作',
|
dataIndex: 'action',
|
},
|
tableSetting: {
|
redo: false,
|
},
|
});
|
const [registerSearchForm] = useForm({
|
baseColProps: { span: 6 },
|
showActionButtonGroup: true,
|
showAdvancedButton: true,
|
compact: true,
|
labelAlign: 'left',
|
labelWidth: 60,
|
schemas: [
|
{
|
field: 'keyword',
|
label: $t('common.keyword'),
|
component: 'Input',
|
componentProps: {
|
placeholder: $t('common.enterKeyword'),
|
submitOnPressEnter: true,
|
},
|
},
|
],
|
});
|
const [registerForm, { openModal: openFormModal }] = useModal();
|
|
const getPagination = computed<any>(() => {
|
return {
|
current: state.listQuery.currentPage,
|
pageSize: state.listQuery.pageSize,
|
size: 'small',
|
defaultPageSize: state.listQuery.pageSize,
|
showTotal: (total) => $t('component.table.total', { total }),
|
showSizeChanger: true,
|
pageSizeOptions: ['20', '50', '80', '100'],
|
showQuickJumper: true,
|
total: state.total,
|
};
|
});
|
|
async function init() {
|
state.industryTypeList = (await baseStore.getDictionaryData('IndustryType')) as any[];
|
initData();
|
}
|
function initData() {
|
setLoading(true);
|
getTableList(state.listQuery)
|
.then((res) => {
|
setLoading(false);
|
const data = res.data.list;
|
for (const e of data) {
|
e.signArray = e.sign ? [...e.sign].filter((o) => o != '0') : [];
|
}
|
state.list = data;
|
state.total = res.data.pagination.total;
|
})
|
.then(() => {
|
setLoading(false);
|
});
|
}
|
function addOrUpdateHandle(id = '') {
|
openFormModal(true, { id, industryTypeList: state.industryTypeList });
|
}
|
function handleSign(row, value, i) {
|
let sign = '0000000';
|
if (value !== '0') {
|
const signArray = [...row.sign];
|
signArray[i] = signArray[i] == value ? '0' : value;
|
sign = signArray.join('');
|
}
|
updateSign(row.id, { sign }).then((res) => {
|
row.signArray = [...sign].filter((o) => o != '0');
|
row.sign = sign;
|
createMessage.success(res.msg);
|
});
|
}
|
function reload() {
|
initData();
|
}
|
function handleTableChange(pagination, _e, _v, type) {
|
if (type?.action !== 'paginate') return;
|
state.listQuery.currentPage = pagination.current;
|
state.listQuery.pageSize = pagination.pageSize;
|
initData();
|
}
|
function handleSubmit(values) {
|
state.listQuery.currentPage = 1;
|
state.listQuery.keyword = values?.keyword || '';
|
initData();
|
}
|
function handleReset() {
|
state.listQuery.currentPage = 1;
|
state.listQuery.keyword = '';
|
initData();
|
}
|
|
onMounted(() => init());
|
</script>
|
<template>
|
<div class="jnpf-content-wrapper">
|
<div class="jnpf-content-wrapper-center">
|
<div class="jnpf-content-wrapper-search-box">
|
<BasicForm @register="registerSearchForm" @reset="handleReset" @submit="handleSubmit" />
|
</div>
|
<div class="jnpf-content-wrapper-content">
|
<BasicVxeTable :data-source="list" :pagination="getPagination" @change="handleTableChange" @register="registerTable">
|
<template #tableTitle>
|
<a-button pre-icon="icon-ym icon-ym-btn-add" type="primary" @click="addOrUpdateHandle()">新建</a-button>
|
</template>
|
<template #signArray="{ record }">
|
<template v-if="record.signArray?.length">
|
<span v-for="(item, i) in record.signArray" :key="i">
|
<i v-if="item == '1'" class="ym-custom ym-custom-checkbox-blank-circle text-[16px]" style="color: #ff625c"></i>
|
<i v-if="item == '2'" class="ym-custom ym-custom-checkbox-blank-circle text-[16px]" style="color: #f9a646"></i>
|
<i v-if="item == '3'" class="ym-custom ym-custom-checkbox-blank-circle text-[16px]" style="color: #f4ce4a"></i>
|
<i v-if="item == '4'" class="ym-custom ym-custom-checkbox-blank-circle text-[16px]" style="color: #6dcc51"></i>
|
<i v-if="item == '5'" class="ym-custom ym-custom-checkbox-blank-circle text-[16px]" style="color: #4bb8f3"></i>
|
<i v-if="item == '6'" class="ym-custom ym-custom-checkbox-blank-circle text-[16px]" style="color: #d088e1"></i>
|
<i v-if="item == '7'" class="ym-custom ym-custom-checkbox-blank-circle text-[16px]" style="color: #a5a5a8"></i>
|
</span>
|
</template>
|
<i v-else class="ym-custom ym-custom-checkbox-blank-circle-outline text-[16px]" style="color: #cecece"></i>
|
</template>
|
<template #action="{ record }">
|
<a-dropdown>
|
<a class="ant-dropdown-link" @click.prevent>项目标记<DownOutlined class="ml-[6px]" /></a>
|
<template #overlay>
|
<a-menu>
|
<a-menu-item v-for="(item, i) in options" :key="item.value" @click="handleSign(record, item.value, i)">
|
<span :style="{ color: item.color }">{{ item.label }}</span>
|
</a-menu-item>
|
</a-menu>
|
</template>
|
</a-dropdown>
|
</template>
|
<template #toolbar>
|
<ATooltip placement="top">
|
<template #title>
|
<span>{{ $t('common.redo') }}</span>
|
</template>
|
<RedoOutlined @click="reload" />
|
</ATooltip>
|
</template>
|
</BasicVxeTable>
|
</div>
|
</div>
|
<Form @register="registerForm" @reload="reload" />
|
</div>
|
</template>
|