【新增】前端代码第一次提交

This commit is contained in:
YOHO\20373
2025-04-17 16:42:02 +08:00
parent e0f13c705b
commit 865ebd0a4d
1635 changed files with 237638 additions and 23 deletions

View File

@@ -0,0 +1,240 @@
<template>
<Dialog v-model="dialogVisible" :title="dialogTitle">
<el-form
ref="formRef"
v-loading="formLoading"
:model="formData"
:rules="formRules"
label-width="110px"
>
<el-row>
<el-col :span="12">
<el-form-item label="还款期数" prop="period">
<el-input v-model="formData.period" disabled placeholder="保存时自动生成" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="负责人" prop="ownerUserId">
<el-select
v-model="formData.ownerUserId"
:disabled="formType !== 'create'"
class="w-1/1"
>
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="客户名称" prop="customerId">
<el-select
v-model="formData.customerId"
:disabled="formType !== 'create'"
class="w-1/1"
filterable
placeholder="请选择客户"
@change="handleCustomerChange"
>
<el-option
v-for="item in customerList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="合同名称" prop="contractId">
<el-select
v-model="formData.contractId"
:disabled="formType !== 'create' || !formData.customerId"
class="w-1/1"
filterable
placeholder="请选择合同"
>
<el-option
v-for="data in contractList"
:key="data.id"
:label="data.name"
:value="data.id!"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="计划回款金额" prop="price">
<el-input-number
v-model="formData.price"
:min="0.01"
:precision="2"
class="!w-100%"
controls-position="right"
placeholder="请输入计划回款金额"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计划回款日期" prop="returnTime">
<el-date-picker
v-model="formData.returnTime"
placeholder="选择计划回款日期"
type="date"
value-format="x"
class="!w-100%"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="提前几天提醒" prop="remindDays">
<el-input-number
v-model="formData.remindDays"
class="!w-100%"
controls-position="right"
placeholder="请输入提前几天提醒"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="回款方式" prop="returnType">
<el-select v-model="formData.returnType" class="w-1/1" placeholder="请选择回款方式">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_RECEIVABLE_RETURN_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入备注" type="textarea" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<el-button :disabled="formLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script lang="ts" setup>
import * as ReceivablePlanApi from '@/api/crm/receivable/plan'
import * as UserApi from '@/api/system/user'
import * as CustomerApi from '@/api/crm/customer'
import * as ContractApi from '@/api/crm/contract'
import { useUserStore } from '@/store/modules/user'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { cloneDeep } from 'lodash-es'
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中1修改时的数据加载2提交的按钮禁用
const formType = ref('') // 表单的类型create - 新增update - 修改
const formData = ref<ReceivablePlanApi.ReceivablePlanVO>({} as ReceivablePlanApi.ReceivablePlanVO)
const formRules = reactive({
price: [{ required: true, message: '计划回款金额不能为空', trigger: 'blur' }],
returnTime: [{ required: true, message: '计划回款日期不能为空', trigger: 'blur' }],
customerId: [{ required: true, message: '客户编号不能为空', trigger: 'blur' }],
contractId: [{ required: true, message: '合同编号不能为空', trigger: 'blur' }],
ownerUserId: [{ required: true, message: '负责人不能为空', trigger: 'blur' }]
})
const formRef = ref() // 表单 Ref
const customerList = ref<CustomerApi.CustomerVO[]>([]) // 客户列表
const contractList = ref<ContractApi.ContractVO[]>([]) // 合同列表
/** 打开弹窗 */
const open = async (type: string, id?: number, customerId?: number, contractId?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
// 修改时,设置数据
if (id) {
formLoading.value = true
try {
const data = await ReceivablePlanApi.getReceivablePlan(id)
formData.value = cloneDeep(data)
await handleCustomerChange(data.customerId!)
formData.value.contractId = data?.contractId
} finally {
formLoading.value = false
}
}
// 获得用户列表
userOptions.value = await UserApi.getSimpleUserList()
// 获得客户列表
customerList.value = await CustomerApi.getCustomerSimpleList()
// 默认新建时选中自己
if (formType.value === 'create') {
formData.value.ownerUserId = useUserStore().getUser.id
}
// 设置 customerId 和 contractId 默认值
if (customerId) {
formData.value.customerId = customerId
await handleCustomerChange(customerId)
}
if (contractId) {
formData.value.contractId = contractId
}
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
const submitForm = async () => {
// 校验表单
if (!formRef) return
const valid = await formRef.value.validate()
if (!valid) return
// 提交请求
formLoading.value = true
try {
const data = formData.value as unknown as ReceivablePlanApi.ReceivablePlanVO
if (formType.value === 'create') {
await ReceivablePlanApi.createReceivablePlan(data)
message.success(t('common.createSuccess'))
} else {
await ReceivablePlanApi.updateReceivablePlan(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
// 发送操作成功的事件
emit('success')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {} as ReceivablePlanApi.ReceivablePlanVO
formRef.value?.resetFields()
}
/** 处理切换客户 */
const handleCustomerChange = async (customerId: number) => {
// 重置合同编号
formData.value.contractId = undefined
// 获得合同列表
if (customerId) {
contractList.value = []
contractList.value = await ContractApi.getContractSimpleList(customerId)
}
}
</script>

View File

@@ -0,0 +1,173 @@
<template>
<!-- 操作栏 -->
<el-row justify="end">
<el-button @click="openForm('create', undefined)">
<Icon class="mr-5px" icon="icon-park:income" />
创建回款计划
</el-button>
</el-row>
<!-- 列表 -->
<ContentWrap class="mt-10px">
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
<el-table-column align="center" label="客户名称" prop="customerName" width="150px" />
<el-table-column align="center" label="合同编号" prop="contractNo" width="200px" />
<el-table-column align="center" label="期数" prop="period" />
<el-table-column
align="center"
label="计划回款(元)"
prop="price"
width="120"
:formatter="erpPriceTableColumnFormatter"
/>
<el-table-column
:formatter="dateFormatter2"
align="center"
label="计划回款日期"
prop="returnTime"
width="180px"
/>
<el-table-column align="center" label="提前几天提醒" prop="remindDays" width="150" />
<el-table-column
:formatter="dateFormatter2"
align="center"
label="提醒日期"
prop="remindTime"
width="180px"
/>
<el-table-column label="负责人" prop="ownerUserName" width="120" />
<el-table-column align="center" label="备注" prop="remark" />
<el-table-column align="center" fixed="right" label="操作" width="200px">
<template #default="scope">
<el-button
v-hasPermi="['crm:receivable:create']"
link
type="primary"
@click="createReceivable(scope.row)"
:disabled="scope.row.receivableId"
>
创建回款
</el-button>
<el-button
v-hasPermi="['crm:receivable-plan:update']"
link
type="primary"
@click="openForm('update', scope.row.id)"
>
编辑
</el-button>
<el-button
v-hasPermi="['crm:receivable-plan:delete']"
link
type="danger"
@click="handleDelete(scope.row.id)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
v-model:limit="queryParams.pageSize"
v-model:page="queryParams.pageNo"
:total="total"
@pagination="getList"
/>
</ContentWrap>
<!-- 表单弹窗添加 -->
<ReceivableForm ref="formRef" @success="getList" />
</template>
<script lang="ts" setup>
import * as ReceivablePlanApi from '@/api/crm/receivable/plan'
import ReceivableForm from './../ReceivablePlanForm.vue'
import { dateFormatter2 } from '@/utils/formatTime'
import { erpPriceTableColumnFormatter } from '@/utils'
defineOptions({ name: 'CrmReceivablePlanList' })
const props = defineProps<{
customerId?: number // 客户编号
contractId?: number // 合同编号
}>()
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const loading = ref(true) // 列表的加载中
const total = ref(0) // 列表的总页数
const list = ref([]) // 列表的数据
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
customerId: undefined as unknown, // 允许 undefined + number
contractId: undefined as unknown // 允许 undefined + number
})
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
if (props.customerId && !props.contractId) {
queryParams.customerId = props.customerId
} else if (props.customerId && props.contractId) {
// 如果是合同的话客户编号也需要带上因为权限基于客户
queryParams.customerId = props.customerId
queryParams.contractId = props.contractId
}
const data = await ReceivablePlanApi.getReceivablePlanPageByCustomer(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
// 置空参数
queryParams.customerId = undefined
queryParams.contractId = undefined
getList()
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id, props.customerId, props.contractId)
}
/** 创建回款 */
const emits = defineEmits<{
(e: 'createReceivable', v: ReceivablePlanApi.ReceivablePlanVO)
}>()
const createReceivable = (row: ReceivablePlanApi.ReceivablePlanVO) => {
emits('createReceivable', row)
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
// 删除的二次确认
await message.delConfirm()
// 发起删除
await ReceivablePlanApi.deleteReceivablePlan(id)
message.success(t('common.delSuccess'))
// 刷新列表
await getList()
} catch {}
}
/** 监听打开的 customerId + contractId从而加载最新的列表 */
watch(
() => [props.customerId, props.contractId],
(newVal) => {
// 保证至少客户编号有值
if (!newVal[0]) {
return
}
handleQuery()
},
{ immediate: true, deep: true }
)
</script>

View File

@@ -0,0 +1,44 @@
<template>
<div>
<div class="flex items-start justify-between">
<div>
<el-col>
<el-row>
<span class="text-xl font-bold"> {{ receivablePlan.period }} </span>
</el-row>
</el-col>
</div>
<div>
<!-- 右上按钮 -->
<slot></slot>
</div>
</div>
</div>
<ContentWrap class="mt-10px">
<el-descriptions :column="5" direction="vertical">
<el-descriptions-item label="客户名称">
{{ receivablePlan.customerName }}
</el-descriptions-item>
<el-descriptions-item label="合同编号">{{ receivablePlan.contractNo }}</el-descriptions-item>
<el-descriptions-item label="计划回款金额">
{{ erpPriceInputFormatter(receivablePlan.price) }}
</el-descriptions-item>
<el-descriptions-item label="计划回款日期">
{{ formatDate(receivablePlan.returnTime) }}
</el-descriptions-item>
<el-descriptions-item label="实际回款金额">
<el-text v-if="receivablePlan.receivable">
{{ erpPriceInputFormatter(receivablePlan.receivable.price) }}
</el-text>
<el-text v-else>{{ erpPriceInputFormatter(0) }}</el-text>
</el-descriptions-item>
</el-descriptions>
</ContentWrap>
</template>
<script lang="ts" setup>
import * as ReceivablePlanApi from '@/api/crm/receivable/plan'
import { formatDate } from '@/utils/formatTime'
import { erpPriceInputFormatter } from '@/utils'
const { receivablePlan } = defineProps<{ receivablePlan: ReceivablePlanApi.ReceivablePlanVO }>()
</script>

View File

@@ -0,0 +1,83 @@
<template>
<ContentWrap>
<el-collapse v-model="activeNames">
<el-collapse-item name="basicInfo">
<template #title>
<span class="text-base font-bold">基本信息</span>
</template>
<el-descriptions :column="4">
<el-descriptions-item label="期数">{{ receivablePlan.period }}</el-descriptions-item>
<el-descriptions-item label="客户名称">
{{ receivablePlan.customerName }}
</el-descriptions-item>
<el-descriptions-item label="合同编号">
{{ receivablePlan.contractNo }}
</el-descriptions-item>
<el-descriptions-item label="计划回款金额">
{{ erpPriceInputFormatter(receivablePlan.price) }}
</el-descriptions-item>
<el-descriptions-item label="计划回款日期">
{{ formatDate(receivablePlan.returnTime, 'YYYY-MM-DD') }}
</el-descriptions-item>
<el-descriptions-item label="计划回款方式">
<dict-tag
:type="DICT_TYPE.CRM_RECEIVABLE_RETURN_TYPE"
:value="receivablePlan.returnType"
/>
</el-descriptions-item>
<el-descriptions-item label="提前几天提醒">
{{ receivablePlan.remindDays }}
</el-descriptions-item>
<el-descriptions-item label="备注">{{ receivablePlan.remark }}</el-descriptions-item>
<el-descriptions-item label="实际回款金额">
<el-text v-if="receivablePlan.receivable">
{{ erpPriceInputFormatter(receivablePlan.receivable.price) }}
</el-text>
<el-text v-else>{{ erpPriceInputFormatter(0) }}</el-text>
</el-descriptions-item>
<el-descriptions-item label="未回款金额">
<el-text v-if="receivablePlan.receivable">
{{ erpPriceInputFormatter(receivablePlan.price - receivablePlan.receivable.price) }}
</el-text>
<el-text v-else>{{ erpPriceInputFormatter(receivablePlan.price) }}</el-text>
</el-descriptions-item>
<el-descriptions-item label="实际回款日期">
{{ formatDate(receivablePlan.receivable?.returnTime, 'YYYY-MM-DD') }}
</el-descriptions-item>
</el-descriptions>
</el-collapse-item>
<el-collapse-item name="systemInfo">
<template #title>
<span class="text-base font-bold">系统信息</span>
</template>
<el-descriptions :column="4">
<el-descriptions-item label="负责人">
{{ receivablePlan.ownerUserName }}
</el-descriptions-item>
<el-descriptions-item label="创建人">
{{ receivablePlan.creatorName }}
</el-descriptions-item>
<el-descriptions-item label="创建时间">
{{ formatDate(receivablePlan.createTime) }}
</el-descriptions-item>
<el-descriptions-item label="更新时间">
{{ formatDate(receivablePlan.updateTime) }}
</el-descriptions-item>
</el-descriptions>
</el-collapse-item>
</el-collapse>
</ContentWrap>
</template>
<script setup lang="ts">
import * as ReceivablePlanApi from '@/api/crm/receivable/plan'
import { DICT_TYPE } from '@/utils/dict'
import { formatDate } from '@/utils/formatTime'
import { erpPriceInputFormatter } from '@/utils'
const { receivablePlan } = defineProps<{
receivablePlan: ReceivablePlanApi.ReceivablePlanVO
}>()
// 展示的折叠面板
const activeNames = ref(['basicInfo', 'systemInfo'])
</script>

View File

@@ -0,0 +1,103 @@
<template>
<ReceivablePlanDetailsHeader v-loading="loading" :receivable-plan="receivablePlan">
<el-button
v-if="permissionListRef?.validateWrite"
@click="openForm('update', receivablePlan.id)"
>
编辑
</el-button>
</ReceivablePlanDetailsHeader>
<el-col>
<el-tabs>
<el-tab-pane label="详细资料">
<ReceivablePlanDetailsInfo :receivable-plan="receivablePlan" />
</el-tab-pane>
<el-tab-pane label="操作日志">
<OperateLogV2 :log-list="logList" />
</el-tab-pane>
<el-tab-pane label="团队成员">
<PermissionList
ref="permissionListRef"
:biz-id="receivablePlan.id!"
:biz-type="BizTypeEnum.CRM_RECEIVABLE_PLAN"
:show-action="true"
@quit-team="close"
/>
</el-tab-pane>
</el-tabs>
</el-col>
<!-- 表单弹窗添加/修改 -->
<ReceivablePlanForm ref="formRef" @success="getReceivablePlan(receivablePlan.id)" />
</template>
<script lang="ts" setup>
import { useTagsViewStore } from '@/store/modules/tagsView'
import * as ReceivablePlanApi from '@/api/crm/receivable/plan'
import ReceivablePlanDetailsHeader from './ReceivablePlanDetailsHeader.vue'
import ReceivablePlanDetailsInfo from './ReceivablePlanDetailsInfo.vue'
import PermissionList from '@/views/crm/permission/components/PermissionList.vue' // 团队成员列表(权限)
import { BizTypeEnum } from '@/api/crm/permission'
import { OperateLogVO } from '@/api/system/operatelog'
import { getOperateLogPage } from '@/api/crm/operateLog'
import ReceivablePlanForm from '@/views/crm/receivable/plan/ReceivablePlanForm.vue'
defineOptions({ name: 'CrmReceivablePlanDetail' })
const message = useMessage()
const receivablePlanId = ref(0) // 回款计划编号
const loading = ref(true) // 加载中
const receivablePlan = ref<ReceivablePlanApi.ReceivablePlanVO>(
{} as ReceivablePlanApi.ReceivablePlanVO
) // 回款计划详情
const permissionListRef = ref<InstanceType<typeof PermissionList>>() // 团队成员列表 Ref
/** 获取详情 */
const getReceivablePlan = async (id: number) => {
loading.value = true
try {
receivablePlan.value = await ReceivablePlanApi.getReceivablePlan(id)
await getOperateLog(id)
} finally {
loading.value = false
}
}
/** 编辑 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
/** 获取操作日志 */
const logList = ref<OperateLogVO[]>([]) // 操作日志列表
const getOperateLog = async (receivablePlanId: number) => {
if (!receivablePlanId) {
return
}
const data = await getOperateLogPage({
bizType: BizTypeEnum.CRM_RECEIVABLE_PLAN,
bizId: receivablePlanId
})
logList.value = data.list
}
/** 关闭窗口 */
const { delView } = useTagsViewStore() // 视图操作
const { currentRoute } = useRouter() // 路由
const close = () => {
delView(unref(currentRoute))
}
/** 初始化 */
const { params } = useRoute()
onMounted(async () => {
if (!params.id) {
message.warning('参数错误,回款计划不能为空!')
close()
return
}
receivablePlanId.value = params.id as unknown as number
await getReceivablePlan(receivablePlanId.value)
})
</script>

View File

@@ -0,0 +1,335 @@
<template>
<doc-alert title="【回款】回款管理、回款计划" url="https://doc.iocoder.cn/crm/receivable/" />
<doc-alert title="【通用】数据权限" url="https://doc.iocoder.cn/crm/permission/" />
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
ref="queryFormRef"
:inline="true"
:model="queryParams"
class="-mb-15px"
label-width="68px"
>
<el-form-item label="客户名称" prop="customerId">
<el-select
v-model="queryParams.customerId"
class="!w-240px"
placeholder="请选择客户"
@keyup.enter="handleQuery"
>
<el-option
v-for="item in customerList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="合同编号" prop="contractNo">
<el-input
v-model="queryParams.contractNo"
class="!w-240px"
clearable
placeholder="请输入合同编号"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery">
<Icon class="mr-5px" icon="ep:search" />
搜索
</el-button>
<el-button @click="resetQuery">
<Icon class="mr-5px" icon="ep:refresh" />
重置
</el-button>
<el-button
v-hasPermi="['crm:receivable-plan:create']"
plain
type="primary"
@click="openForm('create')"
>
<Icon class="mr-5px" icon="ep:plus" />
新增
</el-button>
<el-button
v-hasPermi="['crm:receivable-plan:export']"
:loading="exportLoading"
plain
type="success"
@click="handleExport"
>
<Icon class="mr-5px" icon="ep:download" />
导出
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-tabs v-model="activeName" @tab-click="handleTabClick">
<el-tab-pane label="我负责的" name="1" />
<el-tab-pane label="下属负责的" name="3" />
</el-tabs>
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
<el-table-column align="center" fixed="left" label="客户名称" prop="customerName" width="150">
<template #default="scope">
<el-link
:underline="false"
type="primary"
@click="openCustomerDetail(scope.row.customerId)"
>
{{ scope.row.customerName }}
</el-link>
</template>
</el-table-column>
<el-table-column align="center" label="合同编号" prop="contractNo" width="200px" />
<el-table-column align="center" label="期数" prop="period">
<template #default="scope">
<el-link :underline="false" type="primary" @click="openDetail(scope.row.id)">
{{ scope.row.period }}
</el-link>
</template>
</el-table-column>
<el-table-column
align="center"
label="计划回款金额(元)"
prop="price"
width="160"
:formatter="erpPriceTableColumnFormatter"
/>
<el-table-column
:formatter="dateFormatter2"
align="center"
label="计划回款日期"
prop="returnTime"
width="180px"
/>
<el-table-column align="center" label="提前几天提醒" prop="remindDays" width="150" />
<el-table-column
align="center"
label="提醒日期"
prop="remindTime"
width="180px"
:formatter="dateFormatter2"
/>
<el-table-column align="center" label="回款方式" prop="returnType" width="130px">
<template #default="scope">
<dict-tag :type="DICT_TYPE.CRM_RECEIVABLE_RETURN_TYPE" :value="scope.row.returnType" />
</template>
</el-table-column>
<el-table-column align="center" label="备注" prop="remark" />
<el-table-column label="负责人" prop="ownerUserName" width="120" />
<el-table-column
align="center"
label="实际回款金额(元)"
prop="receivable.price"
width="160"
>
<template #default="scope">
<el-text v-if="scope.row.receivable">
{{ erpPriceInputFormatter(scope.row.receivable.price) }}
</el-text>
<el-text v-else>{{ erpPriceInputFormatter(0) }}</el-text>
</template>
</el-table-column>
<el-table-column
align="center"
label="实际回款日期"
prop="receivable.returnTime"
width="180px"
:formatter="dateFormatter2"
/>
<el-table-column
align="center"
label="实际回款金额(元)"
prop="receivable.price"
width="160"
>
<template #default="scope">
<el-text v-if="scope.row.receivable">
{{ erpPriceInputFormatter(scope.row.price - scope.row.receivable.price) }}
</el-text>
<el-text v-else>{{ erpPriceInputFormatter(scope.row.price) }}</el-text>
</template>
</el-table-column>
<el-table-column
:formatter="dateFormatter"
align="center"
label="更新时间"
prop="updateTime"
width="180px"
/>
<el-table-column
:formatter="dateFormatter"
align="center"
label="创建时间"
prop="createTime"
width="180px"
/>
<el-table-column align="center" label="创建人" prop="creatorName" width="100px" />
<el-table-column align="center" fixed="right" label="操作" width="180px">
<template #default="scope">
<el-button
v-hasPermi="['crm:receivable:create']"
link
type="success"
@click="openReceivableForm(scope.row)"
:disabled="scope.row.receivableId"
>
创建回款
</el-button>
<el-button
v-hasPermi="['crm:receivable-plan:update']"
link
type="primary"
@click="openForm('update', scope.row.id)"
>
编辑
</el-button>
<el-button
v-hasPermi="['crm:receivable-plan:delete']"
link
type="danger"
@click="handleDelete(scope.row.id)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
v-model:limit="queryParams.pageSize"
v-model:page="queryParams.pageNo"
:total="total"
@pagination="getList"
/>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<ReceivablePlanForm ref="formRef" @success="getList" />
<ReceivableForm ref="receivableFormRef" @success="getList" />
</template>
<script lang="ts" setup>
import { DICT_TYPE } from '@/utils/dict'
import { dateFormatter, dateFormatter2 } from '@/utils/formatTime'
import download from '@/utils/download'
import * as ReceivablePlanApi from '@/api/crm/receivable/plan'
import ReceivablePlanForm from './ReceivablePlanForm.vue'
import * as CustomerApi from '@/api/crm/customer'
import { erpPriceInputFormatter, erpPriceTableColumnFormatter } from '@/utils'
import { TabsPaneContext } from 'element-plus'
import ReceivableForm from '@/views/crm/receivable/ReceivableForm.vue'
defineOptions({ name: 'ReceivablePlan' })
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const loading = ref(true) // 列表的加载中
const total = ref(0) // 列表的总页数
const list = ref([]) // 列表的数据
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
sceneType: '1', // 默认和 activeName 相等
customerId: undefined,
contractNo: undefined
})
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中
const activeName = ref('1') // 列表 tab
const customerList = ref<CustomerApi.CustomerVO[]>([]) // 客户列表
/** tab 切换 */
const handleTabClick = (tab: TabsPaneContext) => {
queryParams.sceneType = tab.paneName
handleQuery()
}
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await ReceivablePlanApi.getReceivablePlanPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
/** 创建回款操作 */
const receivableFormRef = ref()
const openReceivableForm = (row: ReceivablePlanApi.ReceivablePlanVO) => {
receivableFormRef.value.open('create', undefined, row)
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
// 删除的二次确认
await message.delConfirm()
// 发起删除
await ReceivablePlanApi.deleteReceivablePlan(id)
message.success(t('common.delSuccess'))
// 刷新列表
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
// 导出的二次确认
await message.exportConfirm()
// 发起导出
exportLoading.value = true
const data = await ReceivablePlanApi.exportReceivablePlan(queryParams)
download.excel(data, '回款计划.xls')
} catch {
} finally {
exportLoading.value = false
}
}
/** 打开详情 */
const { push } = useRouter()
const openDetail = (id: number) => {
push({ name: 'CrmReceivablePlanDetail', params: { id } })
}
/** 打开客户详情 */
const openCustomerDetail = (id: number) => {
push({ name: 'CrmCustomerDetail', params: { id } })
}
/** 初始化 **/
onMounted(async () => {
await getList()
// 获得客户列表
customerList.value = await CustomerApi.getCustomerSimpleList()
})
</script>