You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

336 lines
13 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="80px">
<el-form-item label="订单编号" prop="projectCode">
<el-input v-model="queryParams.projectCode" placeholder="请输入订单编号" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="订单名称" prop="projectName">
<el-input v-model="queryParams.projectName" placeholder="请输入订单名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="合同编号" prop="contractCode">
<el-input v-model="queryParams.contractCode" placeholder="请输入合同编号" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="合同名称" prop="contractName">
<el-input v-model="queryParams.contractName" placeholder="请输入合同名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="项目经理" prop="managerId">
<el-select v-model="queryParams.managerId" placeholder="请选择项目经理" clearable filterable>
<el-option v-for="user in userList" :key="user.userId" :label="user.nickName" :value="user.userId" />
</el-select>
</el-form-item>
<el-form-item label="待办人" prop="todoOwnerType">
<el-select v-model="queryParams.todoOwnerType" placeholder="请选择待办人" clearable>
<el-option v-for="item in todoOwnerTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</transition>
<div class="mb-[10px] flex gap-[10px] flex-wrap">
<el-button :type="todoType === 'purchase' ? 'primary' : 'default'" @click="handleTodo('purchase')">待采购({{ todoCounts.purchase }}</el-button>
<el-button :type="todoType === 'shipping' ? 'primary' : 'default'" @click="handleTodo('shipping')">待发货({{ todoCounts.shipping }}</el-button>
<el-button :type="todoType === 'invoice' ? 'primary' : 'default'" @click="handleTodo('invoice')">待开票({{ todoCounts.invoice }}</el-button>
<el-button :type="todoType === 'payment' ? 'primary' : 'default'" @click="handleTodo('payment')">待回款({{ todoCounts.payment }}</el-button>
</div>
<el-card shadow="never">
<el-table v-loading="loading" border :data="tableList" class="data-table">
<el-table-column label="序号" type="index" align="center" width="70" />
<!-- <el-table-column label="有无合同" align="center" prop="contractFlag" width="110">-->
<!-- <template #default="scope">-->
<!-- <dict-tag :options="contract_flag" :value="scope.row.contractFlag" />-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="订单编号" align="center" prop="projectCode" width="160" show-overflow-tooltip />
<el-table-column label="订单名称" align="center" prop="projectName" width="200">
<template #default="scope">
<el-link type="primary" underline @click="handleOrderLedger(scope.row)">
{{ scope.row.projectName }}
</el-link>
</template>
</el-table-column>
<el-table-column label="合同编号" align="center" prop="contractCode" width="160" />
<el-table-column label="合同名称" align="center" prop="contractName" width="220" show-overflow-tooltip />
<el-table-column label="业务方向" align="center" prop="businessDirection" width="120">
<template #default="scope">
<dict-tag :options="business_direction" :value="scope.row.businessDirection" />
</template>
</el-table-column>
<el-table-column label="采购状态" align="center" prop="orderPurchaseStatus" width="120">
<template #default="scope">
<dict-tag :options="order_purchase_status" :value="scope.row.orderPurchaseStatus" />
</template>
</el-table-column>
<el-table-column label="发货状态" align="center" prop="orderDeliveryStatus" width="120">
<template #default="scope">
<dict-tag :options="order_delivery_status" :value="scope.row.orderDeliveryStatus" />
</template>
</el-table-column>
<el-table-column label="开票状态" align="center" prop="orderInvoiceStatus" width="120">
<template #default="scope">
<dict-tag :options="order_invoice_status" :value="scope.row.orderInvoiceStatus" />
</template>
</el-table-column>
<el-table-column label="回款百分比" align="center" prop="orderPaymentRate" width="130">
<template #default="scope">
{{ scope.row.orderPaymentRate != null ? scope.row.orderPaymentRate : 0 }}%
</template>
</el-table-column>
<el-table-column label="备件标识" align="center" prop="spareFlag" width="120">
<template #default="scope">
<dict-tag :options="spare_flag" :value="scope.row.spareFlag" />
</template>
</el-table-column>
<el-table-column label="付款方式" align="center" prop="paymentMethod" width="120" />
<!-- <el-table-column label="部门" align="center" prop="deptName" width="120" />-->
<!-- <el-table-column label="部门负责人" align="center" prop="chargeName" width="120" />-->
<!-- <el-table-column label="分管副总" align="center" prop="deputyName" width="110" />-->
<el-table-column label="金额" align="center" prop="amount" width="120">
<template #default="scope">
{{ scope.row.amount != null ? formatNumber(scope.row.amount) : '-' }}
</template>
</el-table-column>
<el-table-column label="订单状态" align="center" prop="projectStatus" width="120">
<template #default="scope">
<dict-tag :options="project_status" :value="scope.row.projectStatus" />
</template>
</el-table-column>
<el-table-column label="流程状态" align="center" prop="flowStatus" width="120">
<template #default="scope">
<dict-tag :options="wf_business_status" :value="scope.row.flowStatus" />
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" min-width="160" show-overflow-tooltip />
<el-table-column label="激活标识" align="center" prop="activeFlag" width="120">
<template #default="scope">
<dict-tag :options="active_flag" :value="scope.row.activeFlag" />
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="120" fixed="right">
<template #default="scope">
<el-tooltip content="修改" placement="top" v-if="scope.row.flowStatus === 'draft' || scope.row.flowStatus === 'back'">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
</el-tooltip>
<el-tooltip content="查看详情" placement="top" v-if="scope.row.flowStatus !== 'draft'">
<el-button link type="info" icon="DocumentChecked" @click="handleView(scope.row)"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
</template>
<script setup lang="ts" name="ContractOrderTodoIndex">
import { reactive, ref, getCurrentInstance, onMounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { listContractOrderTodo } from '@/api/oa/erp/contractOrder';
import { ProjectInfoVO, ProjectInfoQuery } from '@/api/oa/erp/projectInfo/types';
import type { FormInstance } from 'element-plus';
import { getUserList } from '@/api/system/user';
import { UserQuery, UserVO } from '@/api/system/user/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const route = useRoute();
const router = useRouter();
const {
business_direction,
project_status,
active_flag,
contract_flag,
project_category,
spare_flag,
wf_business_status,
order_purchase_status,
order_delivery_status,
order_invoice_status
} = toRefs<any>(
proxy?.useDict('business_direction', 'project_status', 'active_flag', 'contract_flag', 'project_category', 'spare_flag', 'wf_business_status', 'order_purchase_status', 'order_delivery_status', 'order_invoice_status')
);
type TodoType = 'purchase' | 'shipping' | 'invoice' | 'payment';
const todoType = ref<TodoType>('purchase');
const loading = ref(true);
const tableList = ref<ProjectInfoVO[]>([]);
const allList = ref<ProjectInfoVO[]>([]);
const showSearch = ref(true);
const queryFormRef = ref<FormInstance>();
const userList = ref<UserVO[]>([]);
const todoOwnerTypeOptions = [
{ label: '本人创建', value: 'create' },
{ label: '本人项目经理', value: 'manager' },
{ label: '全部', value: 'all' }
];
const queryParams = reactive<any>({
// 检索框字段(仿照 contractOrderIndex
projectCode: undefined,
projectName: undefined,
contractCode: undefined,
contractName: undefined,
managerId: undefined,
todoOwnerType: 'all',
projectStatus: undefined
} as Partial<ProjectInfoQuery>);
const formatNumber = (num: number) => {
// 保持与其它页面一致:显示到小数点后两位
return Number(num).toFixed(2);
};
/** 字典:采购 4=已采购;发货 3=已发货;开票 3=已开票。待办 = 未完成态(不等于完成值,空值视为未完成) */
const norm = (v: unknown) => (v === null || v === undefined ? '' : String(v).trim());
const getTodoFilteredList = (type: TodoType, source: ProjectInfoVO[]) => {
if (type === 'purchase') {
return source.filter((item) => norm(item.orderPurchaseStatus) !== '4');
}
if (type === 'shipping') {
return source.filter((item) => norm(item.orderDeliveryStatus) !== '3');
}
if (type === 'invoice') {
return source.filter((item) => norm(item.orderInvoiceStatus) !== '3');
}
// 待回款:回款百分比未满 100%(与「未完成」一致)
return source.filter((item) => Number(item.orderPaymentRate ?? 0) < 100);
};
const todoListMap = ref<Record<TodoType, ProjectInfoVO[]>>({
purchase: [],
shipping: [],
invoice: [],
payment: []
});
const todoCounts = reactive({
purchase: 0,
shipping: 0,
invoice: 0,
payment: 0
});
const applyTodoData = () => {
todoListMap.value = {
purchase: getTodoFilteredList('purchase', allList.value),
shipping: getTodoFilteredList('shipping', allList.value),
invoice: getTodoFilteredList('invoice', allList.value),
payment: getTodoFilteredList('payment', allList.value)
};
todoCounts.purchase = todoListMap.value.purchase.length;
todoCounts.shipping = todoListMap.value.shipping.length;
todoCounts.invoice = todoListMap.value.invoice.length;
todoCounts.payment = todoListMap.value.payment.length;
tableList.value = todoListMap.value[todoType.value] || [];
};
const getEditPathByCategory = () => {
// 该页面在现有合同订单列表中已固定为同一路径
return '/contract/contractInfo/orderActivate';
};
const handleOrderLedger = (row: ProjectInfoVO) => {
const _projectId = row?.projectId;
if (!_projectId) return;
proxy?.$tab.closePage(route);
router.push(`/oa/erp/orderLedger/${_projectId}`);
};
const handleView = (row?: ProjectInfoVO) => {
const _projectId = row?.projectId;
if (!_projectId) return;
proxy?.$tab.closePage(route);
router.push({
path: getEditPathByCategory(),
query: {
id: _projectId,
type: 'view'
}
});
};
const handleUpdate = (row?: ProjectInfoVO) => {
const _projectId = row?.projectId;
if (!_projectId) return;
proxy?.$tab.closePage(route);
router.push({
path: getEditPathByCategory(),
query: {
id: _projectId,
type: 'update'
}
});
};
const refreshAllList = async () => {
const res: any = await listContractOrderTodo({
projectCode: queryParams.projectCode,
projectName: queryParams.projectName,
contractCode: queryParams.contractCode,
contractName: queryParams.contractName,
managerId: queryParams.managerId,
todoOwnerType: queryParams.todoOwnerType,
projectStatus: queryParams.projectStatus
});
allList.value = res.data || [];
};
const loadUserList = async () => {
const res = await getUserList({} as UserQuery);
userList.value = res.data || [];
};
const getList = async () => {
loading.value = true;
try {
await refreshAllList();
applyTodoData();
} finally {
loading.value = false;
}
};
const handleTodo = async (type: TodoType) => {
todoType.value = type;
tableList.value = todoListMap.value[todoType.value] || [];
};
const handleQuery = () => {
getList();
};
const resetQuery = () => {
queryFormRef.value?.resetFields();
handleQuery();
};
onMounted(() => {
loadUserList();
getList();
});
</script>
<style scoped lang="scss">
.data-table {
:deep(.el-table__header) {
th {
font-weight: 600;
}
}
}
</style>