收款计划
parent
0fb01cd478
commit
05f5087306
|
|
@ -5,14 +5,18 @@ export interface ContractVO {
|
||||||
id: number
|
id: number
|
||||||
name: string
|
name: string
|
||||||
no: string
|
no: string
|
||||||
customerId: number[]
|
customerId: number
|
||||||
customer?:{
|
customerName?: string
|
||||||
|
otherCustomerId: number[]
|
||||||
|
otherCustomer?:{
|
||||||
id: number
|
id: number
|
||||||
name: string
|
name: string
|
||||||
}
|
}
|
||||||
|
|
||||||
businessId: number
|
businessId: number
|
||||||
businessName: string
|
businessName: string
|
||||||
|
deptId: number
|
||||||
|
deptName?: string
|
||||||
contactLastTime: Date
|
contactLastTime: Date
|
||||||
ownerUserId: number
|
ownerUserId: number
|
||||||
ownerUserName?: string
|
ownerUserName?: string
|
||||||
|
|
@ -38,6 +42,8 @@ export interface ContractVO {
|
||||||
creator: string
|
creator: string
|
||||||
creatorName: string
|
creatorName: string
|
||||||
updateTime?: Date
|
updateTime?: Date
|
||||||
|
picUrls?: string[]
|
||||||
|
fileUrls?: string[]
|
||||||
products?: [
|
products?: [
|
||||||
{
|
{
|
||||||
id: number
|
id: number
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ export interface ReceivableVO {
|
||||||
id: number
|
id: number
|
||||||
no: string
|
no: string
|
||||||
planId?: number
|
planId?: number
|
||||||
|
period?: number // 期数
|
||||||
customerId?: number
|
customerId?: number
|
||||||
customerName?: string
|
customerName?: string
|
||||||
contractId?: number
|
contractId?: number
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ export interface ReceivablePlanVO {
|
||||||
remindTime: Date
|
remindTime: Date
|
||||||
customerId: number
|
customerId: number
|
||||||
customerName?: string
|
customerName?: string
|
||||||
|
deptId: number
|
||||||
|
deptName?: string
|
||||||
contractId?: number
|
contractId?: number
|
||||||
contractNo?: string
|
contractNo?: string
|
||||||
ownerUserId: number
|
ownerUserId: number
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ export interface DeptVO {
|
||||||
phone: string
|
phone: string
|
||||||
email: string
|
email: string
|
||||||
createTime: Date
|
createTime: Date
|
||||||
|
type: number
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询部门(精简)列表
|
// 查询部门(精简)列表
|
||||||
|
|
@ -17,6 +18,11 @@ export const getSimpleDeptList = async (): Promise<DeptVO[]> => {
|
||||||
return await request.get({ url: '/system/dept/simple-list' })
|
return await request.get({ url: '/system/dept/simple-list' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查询部门(精简)列表
|
||||||
|
export const querySimpleDeptList = async () => {
|
||||||
|
return await request.get({ url: '/system/dept/query-list?type=2'})
|
||||||
|
}
|
||||||
|
|
||||||
// 查询部门列表
|
// 查询部门列表
|
||||||
export const getDeptPage = async (params: PageParam) => {
|
export const getDeptPage = async (params: PageParam) => {
|
||||||
return await request.get({ url: '/system/dept/list', params })
|
return await request.get({ url: '/system/dept/list', params })
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,147 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div v-if="loading" class="loading-container">
|
||||||
|
<el-skeleton :rows="5" animated />
|
||||||
|
</div>
|
||||||
|
<div v-else class="attachment-container">
|
||||||
|
<!-- 图片展示部分 -->
|
||||||
|
<div class="section" v-if="picUrls?.length">
|
||||||
|
<h3 class="section-title">图片</h3>
|
||||||
|
<div class="image-list">
|
||||||
|
<div
|
||||||
|
v-for="(url, index) in picUrls"
|
||||||
|
:key="index"
|
||||||
|
class="image-item"
|
||||||
|
>
|
||||||
|
<el-image
|
||||||
|
:src="url"
|
||||||
|
:preview-src-list="picUrls"
|
||||||
|
:initial-index="index"
|
||||||
|
fit="cover"
|
||||||
|
class="thumbnail"
|
||||||
|
>
|
||||||
|
<template #error>
|
||||||
|
<div class="image-error">
|
||||||
|
<span>加载失败</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-image>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 文件展示部分 -->
|
||||||
|
<div class="section" v-if="fileUrls?.length">
|
||||||
|
<h3 class="section-title">文件</h3>
|
||||||
|
<div class="file-list">
|
||||||
|
<div
|
||||||
|
v-for="(url, index) in fileUrls"
|
||||||
|
:key="index"
|
||||||
|
class="file-item"
|
||||||
|
>
|
||||||
|
<el-icon class="file-icon"><Document /></el-icon>
|
||||||
|
<div class="file-info">
|
||||||
|
<a
|
||||||
|
:href="url"
|
||||||
|
target="_blank"
|
||||||
|
class="file-name"
|
||||||
|
@click.prevent="downloadFile(url)"
|
||||||
|
>
|
||||||
|
{{ extractFileName(url) }}
|
||||||
|
</a>
|
||||||
|
<!-- <div class="file-actions">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
link
|
||||||
|
@click="downloadFile(url)"
|
||||||
|
>
|
||||||
|
下载
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="info"
|
||||||
|
link
|
||||||
|
@click="previewFile(url)"
|
||||||
|
>
|
||||||
|
预览
|
||||||
|
</el-button>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 空状态显示 -->
|
||||||
|
<el-empty
|
||||||
|
v-if="!picUrls?.length && !fileUrls?.length"
|
||||||
|
description="暂无附件数据"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ElMessage, ElLoading } from 'element-plus'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { Document } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
loading: boolean
|
||||||
|
picUrls: string[]
|
||||||
|
fileUrls: string[]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
// 从URL中提取文件名
|
||||||
|
const extractFileName = (url: string) => {
|
||||||
|
try {
|
||||||
|
const path = new URL(url).pathname
|
||||||
|
return decodeURIComponent(path.substring(path.lastIndexOf('/') + 1))
|
||||||
|
} catch {
|
||||||
|
return decodeURIComponent(url.substring(url.lastIndexOf('/') + 1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下载文件
|
||||||
|
const downloadFile = (url: string) => {
|
||||||
|
const loadingInstance = ElLoading.service({
|
||||||
|
lock: true,
|
||||||
|
text: '文件下载中...',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
const link = document.createElement('a')
|
||||||
|
link.href = url
|
||||||
|
link.download = extractFileName(url)
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
document.body.removeChild(link)
|
||||||
|
ElMessage.success('文件下载开始')
|
||||||
|
} catch (error: any) {
|
||||||
|
ElMessage.error('下载失败: ' + error.message)
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => {
|
||||||
|
loadingInstance.close()
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 预览文件(简单实现)
|
||||||
|
const previewFile = (url: string) => {
|
||||||
|
if (url.match(/\.(png|jpg|jpeg|gif|webp)$/i)) {
|
||||||
|
window.open(url, '_blank')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.attachment-container { padding: 16px; }
|
||||||
|
.section { margin-bottom: 24px; }
|
||||||
|
.section-title { font-weight: bold; margin-bottom: 8px; }
|
||||||
|
.image-list { display: flex; flex-wrap: wrap; gap: 12px; }
|
||||||
|
.image-item { width: 120px; height: 120px; }
|
||||||
|
.thumbnail { width: 100%; height: 100%; object-fit: cover; }
|
||||||
|
.file-list { display: flex; flex-direction: column; gap: 12px; }
|
||||||
|
.file-item { display: flex; align-items: center; }
|
||||||
|
.file-icon { margin-right: 8px; }
|
||||||
|
.file-info { flex: 1; }
|
||||||
|
.file-name { color: #409EFF; text-decoration: underline; cursor: pointer; }
|
||||||
|
.file-actions { margin-left: 16px; }
|
||||||
|
.image-error { color: #f56c6c; text-align: center; }
|
||||||
|
</style>
|
||||||
|
|
@ -129,6 +129,7 @@ export enum DICT_TYPE {
|
||||||
SYSTEM_MAIL_SEND_STATUS = 'system_mail_send_status',
|
SYSTEM_MAIL_SEND_STATUS = 'system_mail_send_status',
|
||||||
SYSTEM_NOTIFY_TEMPLATE_TYPE = 'system_notify_template_type',
|
SYSTEM_NOTIFY_TEMPLATE_TYPE = 'system_notify_template_type',
|
||||||
SYSTEM_SOCIAL_TYPE = 'system_social_type',
|
SYSTEM_SOCIAL_TYPE = 'system_social_type',
|
||||||
|
SYSTEM_DEPT_TYPE = 'system_dept_type',
|
||||||
|
|
||||||
// ========== INFRA 模块 ==========
|
// ========== INFRA 模块 ==========
|
||||||
INFRA_BOOLEAN_STRING = 'infra_boolean_string',
|
INFRA_BOOLEAN_STRING = 'infra_boolean_string',
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,12 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col> -->
|
</el-col> -->
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="客户签约方 " prop="customerId">
|
<el-form-item label="合同名称" prop="name">
|
||||||
|
<el-input v-model="formData.name" placeholder="请输入合同名称" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="主客户签约方 " prop="customerId">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="formData.customerId"
|
v-model="formData.customerId"
|
||||||
placeholder="请选择客户签约方 "
|
placeholder="请选择客户签约方 "
|
||||||
|
|
@ -23,6 +28,26 @@
|
||||||
:multiple-limit="3"
|
:multiple-limit="3"
|
||||||
filterable
|
filterable
|
||||||
clearable
|
clearable
|
||||||
|
>
|
||||||
|
<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="8">
|
||||||
|
<el-form-item label="其他客户签约方 " prop="otherCustomerId">
|
||||||
|
<el-select
|
||||||
|
v-model="formData.otherCustomerId"
|
||||||
|
placeholder="请选择客户签约方 "
|
||||||
|
class="w-1/1"
|
||||||
|
@change="handleCustomerChange"
|
||||||
|
:multiple-limit="2"
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
multiple
|
multiple
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
|
|
@ -35,7 +60,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="公司签约方主体" prop="deptId">
|
<el-form-item label="公司签约方" prop="deptId">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="formData.deptId"
|
v-model="formData.deptId"
|
||||||
class="w-1/1"
|
class="w-1/1"
|
||||||
|
|
@ -49,27 +74,6 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="合同名称" prop="name">
|
|
||||||
<el-input v-model="formData.name" placeholder="请输入合同名称" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<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-row>
|
<el-row>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
|
|
@ -147,7 +151,7 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
|
|
||||||
<el-col :span="8">
|
<el-col>
|
||||||
<el-form-item label="备注" prop="remark">
|
<el-form-item label="备注" prop="remark">
|
||||||
<el-input v-model="formData.remark" placeholder="请输入备注" type="textarea" />
|
<el-input v-model="formData.remark" placeholder="请输入备注" type="textarea" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
@ -167,7 +171,7 @@
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="产品总金额" prop="totalProductPrice">
|
<el-form-item label="合同总金额" prop="totalProductPrice">
|
||||||
<el-input
|
<el-input
|
||||||
disabled
|
disabled
|
||||||
v-model="formData.totalProductPrice"
|
v-model="formData.totalProductPrice"
|
||||||
|
|
@ -175,7 +179,7 @@
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<!-- <el-col :span="8">
|
||||||
<el-form-item label="整单折扣(%)" prop="discountPercent">
|
<el-form-item label="整单折扣(%)" prop="discountPercent">
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-model="formData.discountPercent"
|
v-model="formData.discountPercent"
|
||||||
|
|
@ -196,8 +200,14 @@
|
||||||
:formatter="erpPriceInputFormatter"
|
:formatter="erpPriceInputFormatter"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col> -->
|
||||||
</el-row>
|
</el-row>
|
||||||
|
<el-form-item label="附加图片" prop="picUrls">
|
||||||
|
<UploadImgs v-model="formData.picUrls" :fileType="['image/jpeg', 'image/png']" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="附件" prop="fileUrls">
|
||||||
|
<UploadFile v-model="formData.fileUrls" :fileType="['pdf']"/>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button :disabled="formLoading" type="primary" @click="submitForm">保存</el-button>
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">保存</el-button>
|
||||||
|
|
@ -228,7 +238,8 @@ const formData = ref({
|
||||||
id: undefined,
|
id: undefined,
|
||||||
no: undefined,
|
no: undefined,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
customerId: [],
|
customerId: undefined,
|
||||||
|
otherCustomerId: [],
|
||||||
contractStatus: undefined,
|
contractStatus: undefined,
|
||||||
contractType: undefined,
|
contractType: undefined,
|
||||||
contractAttribute: undefined,
|
contractAttribute: undefined,
|
||||||
|
|
@ -243,16 +254,34 @@ const formData = ref({
|
||||||
discountPercent: 0,
|
discountPercent: 0,
|
||||||
totalProductPrice: undefined,
|
totalProductPrice: undefined,
|
||||||
remark: undefined,
|
remark: undefined,
|
||||||
products: []
|
products: [],
|
||||||
|
picUrls: [],
|
||||||
|
fileUrls: [],
|
||||||
})
|
})
|
||||||
|
const validateEndTime = (rule: any, value: any, callback: any) => {
|
||||||
|
if (!value || !formData.value.startTime) {
|
||||||
|
callback()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (value < formData.value.startTime) {
|
||||||
|
callback(new Error('结束时间不能早于开始时间'))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
name: [{ required: true, message: '合同名称不能为空', trigger: 'blur' }],
|
name: [{ required: true, message: '合同名称不能为空', trigger: 'blur' }],
|
||||||
customerId: [{ required: true, message: '客户不能为空', trigger: 'blur' }],
|
customerId: [{ required: true, message: '主签约方不能为空', trigger: 'blur' }],
|
||||||
orderDate: [{ required: true, message: '下单日期不能为空', trigger: 'blur' }],
|
orderDate: [{ required: true, message: '下单日期不能为空', trigger: 'blur' }],
|
||||||
ownerUserId: [{ required: true, message: '负责人不能为空', trigger: 'blur' }],
|
|
||||||
contractStatus: [{ required: true, message: '合同状态不能为空', trigger: 'blur' }],
|
contractStatus: [{ required: true, message: '合同状态不能为空', trigger: 'blur' }],
|
||||||
contractType: [{ required: true, message: '合同类型不能为空', trigger: 'blur' }],
|
contractType: [{ required: true, message: '合同类型不能为空', trigger: 'blur' }],
|
||||||
contractAttribute: [{ required: true, message: '合同属性不能为空', trigger: 'blur' }]
|
contractAttribute: [{ required: true, message: '合同属性不能为空', trigger: 'blur' }],
|
||||||
|
deptId: [{ required: true, message: '公司签约方不能为空', trigger: 'blur' }],
|
||||||
|
startTime: [{ required: true, message: '开始时间不能为空', trigger: 'blur' }],
|
||||||
|
endTime: [
|
||||||
|
{ required: true, message: '结束时间不能为空', trigger: 'blur' },
|
||||||
|
{ validator: validateEndTime, trigger: 'blur' }
|
||||||
|
],
|
||||||
})
|
})
|
||||||
const formRef = ref() // 表单 Ref
|
const formRef = ref() // 表单 Ref
|
||||||
const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表
|
const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表
|
||||||
|
|
@ -305,13 +334,13 @@ const open = async (type: string, id?: number) => {
|
||||||
// 获得用户列表
|
// 获得用户列表
|
||||||
userOptions.value = await UserApi.getSimpleUserList()
|
userOptions.value = await UserApi.getSimpleUserList()
|
||||||
// 默认新建时选中自己
|
// 默认新建时选中自己
|
||||||
if (formType.value === 'create') {
|
// if (formType.value === 'create') {
|
||||||
formData.value.ownerUserId = useUserStore().getUser.id
|
// formData.value.ownerUserId = useUserStore().getUser.id
|
||||||
}
|
// }
|
||||||
// 获取联系人
|
// 获取联系人
|
||||||
contactList.value = await ContactApi.getSimpleContactList()
|
contactList.value = await ContactApi.getSimpleContactList()
|
||||||
// 加载部门列表
|
// 加载部门列表
|
||||||
deptList.value = await DeptApi.getSimpleDeptList()
|
deptList.value = await DeptApi.querySimpleDeptList()
|
||||||
}
|
}
|
||||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
|
@ -322,6 +351,19 @@ const submitForm = async () => {
|
||||||
if (!formRef) return
|
if (!formRef) return
|
||||||
const valid = await formRef.value.validate()
|
const valid = await formRef.value.validate()
|
||||||
if (!valid) return
|
if (!valid) return
|
||||||
|
// 校验产品清单不能为空
|
||||||
|
if (!formData.value.products || formData.value.products.length === 0) {
|
||||||
|
message.error('产品清单不能为空')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验图片或附件至少有一个不为空
|
||||||
|
const hasPic = formData.value.picUrls && formData.value.picUrls.length > 0
|
||||||
|
const hasFile = formData.value.fileUrls && formData.value.fileUrls.length > 0
|
||||||
|
if (!hasPic && !hasFile) {
|
||||||
|
message.error('附加图片和附件不能同时为空')
|
||||||
|
return
|
||||||
|
}
|
||||||
// 提交请求
|
// 提交请求
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
productFormRef.value.validate()
|
productFormRef.value.validate()
|
||||||
|
|
@ -348,7 +390,8 @@ const resetForm = () => {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
no: undefined,
|
no: undefined,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
customerId: [],
|
customerId: undefined,
|
||||||
|
otherCustomerId: [],
|
||||||
contractStatus: undefined,
|
contractStatus: undefined,
|
||||||
contractType: undefined,
|
contractType: undefined,
|
||||||
contractAttribute: undefined,
|
contractAttribute: undefined,
|
||||||
|
|
@ -363,7 +406,9 @@ const resetForm = () => {
|
||||||
discountPercent: 0,
|
discountPercent: 0,
|
||||||
totalProductPrice: undefined,
|
totalProductPrice: undefined,
|
||||||
remark: undefined,
|
remark: undefined,
|
||||||
products: []
|
products: [],
|
||||||
|
picUrls: [],
|
||||||
|
fileUrls: [],
|
||||||
}
|
}
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,48 +12,33 @@
|
||||||
<el-table-column label="序号" type="index" align="center" width="60" />
|
<el-table-column label="序号" type="index" align="center" width="60" />
|
||||||
<el-table-column label="产品名称" min-width="180">
|
<el-table-column label="产品名称" min-width="180">
|
||||||
<template #default="{ row, $index }">
|
<template #default="{ row, $index }">
|
||||||
<el-form-item :prop="`${$index}.productId`" :rules="formRules.productId" class="mb-0px!">
|
<el-form-item :prop="`${$index}.productName`" :rules="formRules.productName" class="mb-0px!">
|
||||||
<el-select
|
<el-input
|
||||||
v-model="row.productId"
|
v-model="row.productName"
|
||||||
clearable
|
placeholder="请输入产品名称"
|
||||||
filterable
|
/>
|
||||||
@change="onChangeProduct($event, row)"
|
</el-form-item>
|
||||||
placeholder="请选择产品"
|
</template>
|
||||||
>
|
</el-table-column>
|
||||||
|
<el-table-column label="单位" min-width="80">
|
||||||
|
<template #default="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.productUnit`" :rules="formRules.productUnit" class="mb-0px!">
|
||||||
|
<el-select v-model="row.productUnit" placeholder="请选择单位">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in productList"
|
v-for="dict in getIntDictOptions(DICT_TYPE.CRM_PRODUCT_UNIT)"
|
||||||
:key="item.id"
|
:key="dict.value"
|
||||||
:label="item.name"
|
:label="dict.label"
|
||||||
:value="item.id"
|
:value="dict.value"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="条码" min-width="150">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<el-form-item class="mb-0px!">
|
|
||||||
<el-input disabled v-model="row.productNo" />
|
|
||||||
</el-form-item>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="单位" min-width="80">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<dict-tag :type="DICT_TYPE.CRM_PRODUCT_UNIT" :value="row.productUnit" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="价格(元)" min-width="120">
|
<el-table-column label="价格(元)" min-width="120">
|
||||||
<template #default="{ row }">
|
|
||||||
<el-form-item class="mb-0px!">
|
|
||||||
<el-input disabled v-model="row.productPrice" :formatter="erpPriceInputFormatter" />
|
|
||||||
</el-form-item>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="售价(元)" fixed="right" min-width="140">
|
|
||||||
<template #default="{ row, $index }">
|
<template #default="{ row, $index }">
|
||||||
<el-form-item :prop="`${$index}.contractPrice`" class="mb-0px!">
|
<el-form-item :prop="`${$index}.productPrice`" :rules="formRules.productPrice" class="mb-0px!">
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-model="row.contractPrice"
|
v-model="row.productPrice"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
:min="0.001"
|
:min="0.001"
|
||||||
:precision="2"
|
:precision="2"
|
||||||
|
|
@ -96,27 +81,39 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import * as ProductApi from '@/api/crm/product'
|
import * as ProductApi from '@/api/crm/product'
|
||||||
import { erpPriceInputFormatter, erpPriceMultiply } from '@/utils'
|
import { erpPriceInputFormatter, erpPriceMultiply } from '@/utils'
|
||||||
import { DICT_TYPE } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
products: undefined
|
products: any[]
|
||||||
disabled: false
|
disabled: boolean
|
||||||
}>()
|
}>()
|
||||||
const formLoading = ref(false) // 表单的加载中
|
const formLoading = ref(false) // 表单的加载中
|
||||||
const formData = ref([])
|
|
||||||
|
// 定义产品行类型
|
||||||
|
interface ProductRow {
|
||||||
|
id?: string | number
|
||||||
|
productName?: string
|
||||||
|
productUnit?: string
|
||||||
|
productPrice?: number
|
||||||
|
count?: number
|
||||||
|
totalPrice?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const formData = ref<ProductRow[]>([])
|
||||||
|
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }],
|
productName: [{ required: true, message: '产品名称不能为空', trigger: 'blur' }],
|
||||||
contractPrice: [{ required: true, message: '合同价格不能为空', trigger: 'blur' }],
|
productUnit: [{ required: true, message: '单位不能为空', trigger: 'blur' }],
|
||||||
|
productPrice: [{ required: true, message: '价格不能为空', trigger: 'blur' }],
|
||||||
count: [{ required: true, message: '产品数量不能为空', trigger: 'blur' }]
|
count: [{ required: true, message: '产品数量不能为空', trigger: 'blur' }]
|
||||||
})
|
})
|
||||||
const formRef = ref([]) // 表单 Ref
|
const formRef = ref([]) // 表单 Ref
|
||||||
const productList = ref<ProductApi.ProductVO[]>([]) // 产品列表
|
|
||||||
|
|
||||||
/** 初始化设置产品项 */
|
/** 初始化设置产品项 */
|
||||||
watch(
|
watch(
|
||||||
() => props.products,
|
() => props.products,
|
||||||
async (val) => {
|
(val) => {
|
||||||
formData.value = val
|
formData.value = val || []
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
|
|
@ -130,8 +127,8 @@ watch(
|
||||||
}
|
}
|
||||||
// 循环处理
|
// 循环处理
|
||||||
val.forEach((item) => {
|
val.forEach((item) => {
|
||||||
if (item.contractPrice != null && item.count != null) {
|
if (item.productPrice != null && item.count != null) {
|
||||||
item.totalPrice = erpPriceMultiply(item.contractPrice, item.count)
|
item.totalPrice = erpPriceMultiply(item.productPrice, item.count)
|
||||||
} else {
|
} else {
|
||||||
item.totalPrice = undefined
|
item.totalPrice = undefined
|
||||||
}
|
}
|
||||||
|
|
@ -142,14 +139,13 @@ watch(
|
||||||
|
|
||||||
/** 新增按钮操作 */
|
/** 新增按钮操作 */
|
||||||
const handleAdd = () => {
|
const handleAdd = () => {
|
||||||
const row = {
|
const row: ProductRow = {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
productId: undefined,
|
productName: undefined,
|
||||||
productUnit: undefined, // 产品单位
|
productUnit: undefined, // 产品单位
|
||||||
productNo: undefined, // 产品条码
|
|
||||||
productPrice: undefined, // 产品价格
|
productPrice: undefined, // 产品价格
|
||||||
contractPrice: undefined,
|
count: 1,
|
||||||
count: 1
|
totalPrice: undefined
|
||||||
}
|
}
|
||||||
formData.value.push(row)
|
formData.value.push(row)
|
||||||
}
|
}
|
||||||
|
|
@ -159,17 +155,6 @@ const handleDelete = (index: number) => {
|
||||||
formData.value.splice(index, 1)
|
formData.value.splice(index, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 处理产品变更 */
|
|
||||||
const onChangeProduct = (productId, row) => {
|
|
||||||
const product = productList.value.find((item) => item.id === productId)
|
|
||||||
if (product) {
|
|
||||||
row.productUnit = product.unit
|
|
||||||
row.productNo = product.no
|
|
||||||
row.productPrice = product.price
|
|
||||||
row.contractPrice = product.price
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 表单校验 */
|
/** 表单校验 */
|
||||||
const validate = () => {
|
const validate = () => {
|
||||||
return formRef.value.validate()
|
return formRef.value.validate()
|
||||||
|
|
@ -178,6 +163,7 @@ defineExpose({ validate })
|
||||||
|
|
||||||
/** 初始化 */
|
/** 初始化 */
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
productList.value = await ProductApi.getProductSimpleList()
|
// 移除未用的 productList 相关内容
|
||||||
|
// productList.value = await ProductApi.getProductSimpleList()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -20,23 +20,22 @@
|
||||||
<!-- <el-descriptions-item label="合同编号">{{ contract.no }}</el-descriptions-item> -->
|
<!-- <el-descriptions-item label="合同编号">{{ contract.no }}</el-descriptions-item> -->
|
||||||
<el-descriptions-item label="合同名称">{{ contract.name }}</el-descriptions-item>
|
<el-descriptions-item label="合同名称">{{ contract.name }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="客户签约方">
|
<el-descriptions-item label="客户签约方">
|
||||||
<div>
|
{{ contract.customerName || '' }}
|
||||||
<template v-if="Array.isArray(contract.customer)">
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="其他签约方">
|
||||||
<span v-for="(c, idx) in contract.customer" :key="c.id">
|
<div>
|
||||||
{{ c.name }}<span v-if="idx < contract.customer.length - 1"><br /> </span>
|
<template v-if="Array.isArray(contract.otherCustomer)">
|
||||||
|
<span v-for="(c, idx) in contract.otherCustomer" :key="c.id">
|
||||||
|
{{ c.name }}<span v-if="idx < contract.otherCustomer.length - 1"><br /> </span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
{{ contract.customer?.name || '' }}
|
{{ contract.otherCustomer?.name || '' }}
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="责任人">
|
<el-descriptions-item label="公司签约方">
|
||||||
{{ contract.ownerUserName }}
|
{{ contract.deptName }}
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="合同金额(元)">
|
|
||||||
{{ erpPriceInputFormatter(contract.totalPrice) }}
|
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="签订时间">
|
<el-descriptions-item label="签订时间">
|
||||||
{{ formatDate(contract.orderDate, 'YYYY-MM-DD') }}
|
{{ formatDate(contract.orderDate, 'YYYY-MM-DD') }}
|
||||||
|
|
@ -48,7 +47,13 @@
|
||||||
{{ formatDate(contract.endTime, 'YYYY-MM-DD') }}
|
{{ formatDate(contract.endTime, 'YYYY-MM-DD') }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="合同状态">
|
<el-descriptions-item label="合同状态">
|
||||||
<dict-tag :type="DICT_TYPE.CRM_AUDIT_STATUS" :value="contract.auditStatus" />
|
<dict-tag :type="DICT_TYPE.CRM_CONTRACT_STATUS" :value="contract.contractStatus" />
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="合同类型">
|
||||||
|
<dict-tag :type="DICT_TYPE.CRM_CONTRACT_TYPE" :value="contract.contractType" />
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="合同属性">
|
||||||
|
<dict-tag :type="DICT_TYPE.CRM_CONTRACT_ATTRIBUTE" :value="contract.contractAttribute" />
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="合同金额(元)">
|
<el-descriptions-item label="合同金额(元)">
|
||||||
{{ erpPriceInputFormatter(contract.totalPrice) }}
|
{{ erpPriceInputFormatter(contract.totalPrice) }}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<el-table :data="contract.products" :stripe="true" :show-overflow-tooltip="true">
|
<el-table :data="contract.products" :stripe="true" :show-overflow-tooltip="true">
|
||||||
<el-table-column
|
<el-table-column
|
||||||
align="center"
|
align="center"
|
||||||
label="产品名称"
|
label="产品或服务"
|
||||||
fixed="left"
|
fixed="left"
|
||||||
prop="productName"
|
prop="productName"
|
||||||
min-width="160"
|
min-width="160"
|
||||||
|
|
@ -12,7 +12,6 @@
|
||||||
{{ scope.row.productName }}
|
{{ scope.row.productName }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="产品条码" align="center" prop="productNo" min-width="120" />
|
|
||||||
<el-table-column align="center" label="产品单位" prop="productUnit" min-width="160">
|
<el-table-column align="center" label="产品单位" prop="productUnit" min-width="160">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<dict-tag :type="DICT_TYPE.CRM_PRODUCT_UNIT" :value="row.productUnit" />
|
<dict-tag :type="DICT_TYPE.CRM_PRODUCT_UNIT" :value="row.productUnit" />
|
||||||
|
|
@ -25,13 +24,13 @@
|
||||||
min-width="140"
|
min-width="140"
|
||||||
:formatter="erpPriceTableColumnFormatter"
|
:formatter="erpPriceTableColumnFormatter"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<!-- <el-table-column
|
||||||
label="合同价格(元)"
|
label="合同价格(元)"
|
||||||
align="center"
|
align="center"
|
||||||
prop="contractPrice"
|
prop="contractPrice"
|
||||||
min-width="140"
|
min-width="140"
|
||||||
:formatter="erpPriceTableColumnFormatter"
|
:formatter="erpPriceTableColumnFormatter"
|
||||||
/>
|
/> -->
|
||||||
<el-table-column
|
<el-table-column
|
||||||
align="center"
|
align="center"
|
||||||
label="数量"
|
label="数量"
|
||||||
|
|
@ -48,10 +47,10 @@
|
||||||
/>
|
/>
|
||||||
</el-table>
|
</el-table>
|
||||||
<el-row class="mt-10px" justify="end">
|
<el-row class="mt-10px" justify="end">
|
||||||
<el-col :span="3"> 整单折扣:{{ erpPriceInputFormatter(contract.discountPercent) }}% </el-col>
|
<!-- <el-col :span="3"> 整单折扣:{{ erpPriceInputFormatter(contract.discountPercent) }}% </el-col> -->
|
||||||
<el-col :span="4">
|
<!-- <el-col :span="4">
|
||||||
产品总金额:{{ erpPriceInputFormatter(contract.totalProductPrice) }} 元
|
产品总金额:{{ erpPriceInputFormatter(contract.) }} 元
|
||||||
</el-col>
|
</el-col> -->
|
||||||
</el-row>
|
</el-row>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,35 @@
|
||||||
<!-- 合同详情页面组件-->
|
<!-- 合同详情页面组件-->
|
||||||
<template>
|
<template>
|
||||||
<ContractDetailsHeader v-loading="loading" :contract="contract">
|
<ContractDetailsHeader v-loading="loading" :contract="contract">
|
||||||
<el-button v-if="permissionListRef?.validateWrite" @click="openForm('update', contract.id)">
|
<el-button v-hasPermi="['crm:contract:update']" @click="openForm('update', contract.id)">
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button v-if="permissionListRef?.validateOwnerUser" type="primary" @click="transferContract">
|
<!-- <el-button v-hasPermi="['crm:contract:update']" type="primary" @click="transferContract">
|
||||||
转移
|
转移
|
||||||
</el-button>
|
</el-button> -->
|
||||||
</ContractDetailsHeader>
|
</ContractDetailsHeader>
|
||||||
<el-col>
|
<el-col>
|
||||||
<el-tabs>
|
<el-tabs>
|
||||||
<el-tab-pane label="产品">
|
<el-tab-pane label="合同清单">
|
||||||
<ContractProductList :contract="contract" />
|
<ContractProductList :contract="contract" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="付款">
|
<el-tab-pane label="付款计划">
|
||||||
<ReceivablePlanList
|
<ReceivablePlanList
|
||||||
:contract-id="contract.id!"
|
:contract-id="contract.id!"
|
||||||
:customer-id="Array.isArray(contract.customerId) ? contract.customerId[0] : contract.customerId"
|
:customer-id="contract.customerId"
|
||||||
@create-receivable="createReceivable"
|
@create-receivable="createReceivable"
|
||||||
/>
|
/>
|
||||||
<ReceivableList
|
<ReceivableList
|
||||||
ref="receivableListRef"
|
ref="receivableListRef"
|
||||||
:contract-id="contract.id!"
|
:contract-id="contract.id!"
|
||||||
:customer-id="Array.isArray(contract.customerId) ? contract.customerId[0] : contract.customerId"
|
:customer-id="contract.customerId"
|
||||||
/>
|
/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="团队成员">
|
<el-tab-pane label="合同明细">
|
||||||
<PermissionList
|
<AttachmentTab
|
||||||
ref="permissionListRef"
|
:loading="loading"
|
||||||
:biz-id="contract.id!"
|
:pic-urls="contract.picUrls"
|
||||||
:biz-type="BizTypeEnum.CRM_CONTRACT"
|
:file-urls="contract.fileUrls"
|
||||||
:show-action="true"
|
|
||||||
@quit-team="close"
|
|
||||||
/>
|
/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="操作日志">
|
<el-tab-pane label="操作日志">
|
||||||
|
|
@ -57,6 +55,7 @@ import CrmTransferForm from '@/views/crm/permission/components/TransferForm.vue'
|
||||||
import PermissionList from '@/views/crm/permission/components/PermissionList.vue'
|
import PermissionList from '@/views/crm/permission/components/PermissionList.vue'
|
||||||
import ReceivableList from '@/views/crm/receivable/components/ReceivableList.vue'
|
import ReceivableList from '@/views/crm/receivable/components/ReceivableList.vue'
|
||||||
import ReceivablePlanList from '@/views/crm/receivable/plan/components/ReceivablePlanList.vue'
|
import ReceivablePlanList from '@/views/crm/receivable/plan/components/ReceivablePlanList.vue'
|
||||||
|
import AttachmentTab from '@/components/AttachmentFile/index.vue'
|
||||||
|
|
||||||
defineOptions({ name: 'CrmContractDetail' })
|
defineOptions({ name: 'CrmContractDetail' })
|
||||||
const props = defineProps<{ id?: number }>()
|
const props = defineProps<{ id?: number }>()
|
||||||
|
|
|
||||||
|
|
@ -28,13 +28,13 @@
|
||||||
placeholder="请输入合同名称"
|
placeholder="请输入合同名称"
|
||||||
@keyup.enter="handleQuery"
|
@keyup.enter="handleQuery"
|
||||||
/>
|
/>
|
||||||
<el-form-item label="客户" prop="customerId">
|
<el-form-item label="客户签约方" prop="customerId">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="queryParams.customerId"
|
v-model="queryParams.customerId"
|
||||||
class="!w-240px"
|
class="!w-240px"
|
||||||
clearable
|
clearable
|
||||||
lable-key="name"
|
lable-key="name"
|
||||||
placeholder="请选择客户"
|
placeholder="请选择客户签约方"
|
||||||
value-key="id"
|
value-key="id"
|
||||||
@keyup.enter="handleQuery"
|
@keyup.enter="handleQuery"
|
||||||
>
|
>
|
||||||
|
|
@ -76,28 +76,27 @@
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
|
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true" :row-class-name="tableRowClassName">
|
||||||
<!-- <el-table-column align="center" fixed="left" label="合同编号" prop="no" width="180" /> -->
|
<!-- <el-table-column align="center" fixed="left" label="合同编号" prop="no" width="180" /> -->
|
||||||
<el-table-column align="center" fixed="left" label="合同名称" prop="name" width="160">
|
<el-table-column align="center" fixed="left" label="合同名称" prop="name" width="300">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-link :underline="false" type="primary" @click="openDetail(scope.row.id)">
|
<el-link :underline="false" type="primary" @click="openDetail(scope.row.id)">
|
||||||
{{ scope.row.name }}
|
{{ scope.row.name }}
|
||||||
</el-link>
|
</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" label="客户签约方" prop="customer.id" width="350">
|
<el-table-column align="center" label="客户签约方" prop="deptId" width="300">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
|
|
||||||
<el-link
|
<el-link
|
||||||
:underline="false"
|
:underline="false"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="openCustomerDetail(scope.row.customer[0].id)"
|
@click="openCustomerDetail(scope.row.customerId)"
|
||||||
>
|
>
|
||||||
{{ scope.row.customer[0].name }}
|
{{ scope.row.customerName }}
|
||||||
</el-link>
|
</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" label="所属部门" prop="ownerUserDeptName" width="160" />
|
|
||||||
<!-- <el-table-column
|
<!-- <el-table-column
|
||||||
align="center"
|
align="center"
|
||||||
label="合同金额(元)"
|
label="合同金额(元)"
|
||||||
|
|
@ -119,13 +118,13 @@
|
||||||
width="160"
|
width="160"
|
||||||
:formatter="dateFormatter2"
|
:formatter="dateFormatter2"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<!-- <el-table-column
|
||||||
align="center"
|
align="center"
|
||||||
label="已付款金额(万元)"
|
label="已付款金额(万元)"
|
||||||
prop="totalReceivablePrice"
|
prop="totalReceivablePrice"
|
||||||
width="160"
|
width="160"
|
||||||
:formatter="erpPriceTableColumnFormatter"
|
:formatter="erpPriceTableColumnFormatter"
|
||||||
/>
|
/> -->
|
||||||
<!-- <el-table-column
|
<!-- <el-table-column
|
||||||
align="center"
|
align="center"
|
||||||
label="未付款金额(元)"
|
label="未付款金额(元)"
|
||||||
|
|
@ -137,14 +136,14 @@
|
||||||
{{ erpPriceInputFormatter(scope.row.totalPrice - scope.row.totalReceivablePrice) }}
|
{{ erpPriceInputFormatter(scope.row.totalPrice - scope.row.totalReceivablePrice) }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column> -->
|
</el-table-column> -->
|
||||||
<el-table-column align="center" label="责任人" prop="ownerUserName" width="160" />
|
<!-- <el-table-column align="center" label="责任人" prop="ownerUserName" width="160" /> -->
|
||||||
|
|
||||||
<el-table-column align="center" fixed="right" label="合同状态" prop="contractStatus" width="160">
|
<el-table-column align="center" label="合同状态" prop="contractStatus" width="160">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.CRM_CONTRACT_STATUS" :value="scope.row.contractStatus" />
|
<dict-tag :type="DICT_TYPE.CRM_CONTRACT_STATUS" :value="scope.row.contractStatus" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" fixed="right" label="合同类型" prop="contractType" width="160">
|
<el-table-column align="center" label="合同类型" prop="contractType" width="160">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.CRM_CONTRACT_TYPE" :value="scope.row.contractType" />
|
<dict-tag :type="DICT_TYPE.CRM_CONTRACT_TYPE" :value="scope.row.contractType" />
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -160,7 +159,7 @@
|
||||||
>
|
>
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<!-- <el-button
|
||||||
v-if="scope.row.auditStatus === 0"
|
v-if="scope.row.auditStatus === 0"
|
||||||
v-hasPermi="['crm:contract:update']"
|
v-hasPermi="['crm:contract:update']"
|
||||||
link
|
link
|
||||||
|
|
@ -168,8 +167,8 @@
|
||||||
@click="handleSubmit(scope.row)"
|
@click="handleSubmit(scope.row)"
|
||||||
>
|
>
|
||||||
提交审核
|
提交审核
|
||||||
</el-button>
|
</el-button> -->
|
||||||
<el-button
|
<!-- <el-button
|
||||||
v-else
|
v-else
|
||||||
link
|
link
|
||||||
v-hasPermi="['crm:contract:update']"
|
v-hasPermi="['crm:contract:update']"
|
||||||
|
|
@ -177,7 +176,7 @@
|
||||||
@click="handleProcessDetail(scope.row)"
|
@click="handleProcessDetail(scope.row)"
|
||||||
>
|
>
|
||||||
查看审批
|
查看审批
|
||||||
</el-button>
|
</el-button> -->
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['crm:contract:delete']"
|
v-hasPermi="['crm:contract:delete']"
|
||||||
link
|
link
|
||||||
|
|
@ -329,4 +328,45 @@ onMounted(async () => {
|
||||||
await getList()
|
await getList()
|
||||||
customerList.value = await CustomerApi.getCustomerSimpleList()
|
customerList.value = await CustomerApi.getCustomerSimpleList()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 计算行样式的方法
|
||||||
|
const tableRowClassName = ({ row }: { row: any }) => {
|
||||||
|
if (!row.endTime) return '';
|
||||||
|
|
||||||
|
const endTime = new Date(row.endTime);
|
||||||
|
const today = new Date();
|
||||||
|
|
||||||
|
if(row.contractAttribute === 2 ) {
|
||||||
|
// 如果是一次性合同,直接返回空样式
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
// 计算剩余天数
|
||||||
|
const diffTime = today.getTime() - endTime.getTime();
|
||||||
|
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
|
||||||
|
console.log('diffDays', diffDays, endTime);
|
||||||
|
if (diffDays <= 90) { // 少于3个月
|
||||||
|
return 'expiring-soon-row';
|
||||||
|
} else if (diffDays <= 180) { // 少于6个月
|
||||||
|
return 'expiring-row';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* 添加行样式 */
|
||||||
|
.el-table .expiring-row td {
|
||||||
|
background-color: #fffcde !important; /* 黄色背景 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table .expiring-soon-row td {
|
||||||
|
background-color: #ffe8e8 !important; /* 红色背景 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 如果需要,可以添加悬停效果 */
|
||||||
|
.el-table .expiring-row:hover>td,
|
||||||
|
.el-table .expiring-soon-row:hover>td {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@
|
||||||
<el-option
|
<el-option
|
||||||
v-for="data in contractList"
|
v-for="data in contractList"
|
||||||
:key="data.id"
|
:key="data.id"
|
||||||
:disabled="data.auditStatus !== 20"
|
|
||||||
:label="data.name"
|
:label="data.name"
|
||||||
:value="data.id!"
|
:value="data.id!"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,45 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- 操作栏 -->
|
<!-- 操作栏 -->
|
||||||
<el-row justify="end">
|
<el-row>
|
||||||
<el-button @click="openForm('create')">
|
<text class="text-xs font-bold">
|
||||||
|
实付明细
|
||||||
|
</text>
|
||||||
|
<!-- <el-button @click="openForm('create')">
|
||||||
<Icon class="mr-5px" icon="icon-park:income-one" />
|
<Icon class="mr-5px" icon="icon-park:income-one" />
|
||||||
创建付款
|
创建付款
|
||||||
</el-button>
|
</el-button> -->
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap class="mt-10px">
|
<ContentWrap class="mt-10px">
|
||||||
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
|
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
|
||||||
<el-table-column align="center" label="付款编号" prop="no" />
|
|
||||||
<el-table-column align="center" label="客户" prop="customerName" />
|
|
||||||
<el-table-column align="center" label="合同" prop="contract.no" />
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
:formatter="dateFormatter2"
|
:formatter="dateFormatter2"
|
||||||
align="center"
|
align="center"
|
||||||
label="付款日期"
|
label="实际付款日期"
|
||||||
prop="returnTime"
|
prop="returnTime"
|
||||||
width="150px"
|
min-width="150px"
|
||||||
/>
|
/>
|
||||||
<el-table-column align="center" label="付款方式" prop="returnType" width="130px">
|
<!-- <el-table-column align="center" label="付款编号" prop="no" /> -->
|
||||||
|
<el-table-column align="center" label="收款单位" prop="customerName" min-width="300px" />
|
||||||
|
<el-table-column align="center" label="付款单位" prop="deptName" min-width="300px"/>
|
||||||
|
<el-table-column align="center" label="对应计划期数" prop="period" min-width="150px" />
|
||||||
|
<!-- <el-table-column align="center" label="合同" prop="contract.no" /> -->
|
||||||
|
<el-table-column
|
||||||
|
align="center"
|
||||||
|
label="实付金额(元)"
|
||||||
|
prop="price"
|
||||||
|
:formatter="erpPriceTableColumnFormatter"
|
||||||
|
min-width="150px"
|
||||||
|
/>
|
||||||
|
<el-table-column align="center" label="付款方式" prop="returnType">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.CRM_RECEIVABLE_RETURN_TYPE" :value="scope.row.returnType" />
|
<dict-tag :type="DICT_TYPE.CRM_RECEIVABLE_RETURN_TYPE" :value="scope.row.returnType" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<!-- <el-table-column align="center" label="负责人" prop="ownerUserName" /> -->
|
||||||
align="center"
|
<!-- <el-table-column align="center" label="备注" prop="remark" /> -->
|
||||||
label="付款金额(元)"
|
<!-- <el-table-column align="center" fixed="right" label="操作" width="130px">
|
||||||
prop="price"
|
|
||||||
:formatter="erpPriceTableColumnFormatter"
|
|
||||||
/>
|
|
||||||
<el-table-column align="center" label="负责人" prop="ownerUserName" />
|
|
||||||
<el-table-column align="center" label="备注" prop="remark" />
|
|
||||||
<el-table-column align="center" fixed="right" label="操作" width="130px">
|
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['crm:receivable:update']"
|
v-hasPermi="['crm:receivable:update']"
|
||||||
|
|
@ -52,7 +58,7 @@
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column> -->
|
||||||
</el-table>
|
</el-table>
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<Pagination
|
<Pagination
|
||||||
|
|
|
||||||
|
|
@ -9,22 +9,24 @@
|
||||||
>
|
>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="还款期数" prop="period">
|
<el-form-item label="付款期数" prop="period">
|
||||||
<el-input v-model="formData.period" disabled placeholder="保存时自动生成" />
|
<el-input v-model="formData.period" disabled placeholder="保存时自动生成" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="负责人" prop="ownerUserId">
|
<el-form-item label="付款单位">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="formData.ownerUserId"
|
v-model="formData.contractId"
|
||||||
:disabled="formType !== 'create'"
|
disabled
|
||||||
class="w-1/1"
|
class="w-1/1"
|
||||||
|
filterable
|
||||||
|
placeholder="请选择付款单位"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in userOptions"
|
v-for="data in contractList"
|
||||||
:key="item.id"
|
:key="data.id"
|
||||||
:label="item.nickname"
|
:label="data.deptName"
|
||||||
:value="item.id"
|
:value="data.id!"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
@ -32,14 +34,13 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="客户名称" prop="customerId">
|
<el-form-item label="收款单位" prop="customerId">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="formData.customerId"
|
v-model="formData.customerId"
|
||||||
:disabled="formType !== 'create'"
|
disabled
|
||||||
class="w-1/1"
|
class="w-1/1"
|
||||||
filterable
|
filterable
|
||||||
placeholder="请选择客户"
|
placeholder="请选择收款单位"
|
||||||
@change="handleCustomerChange"
|
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in customerList"
|
v-for="item in customerList"
|
||||||
|
|
@ -54,7 +55,7 @@
|
||||||
<el-form-item label="合同名称" prop="contractId">
|
<el-form-item label="合同名称" prop="contractId">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="formData.contractId"
|
v-model="formData.contractId"
|
||||||
:disabled="formType !== 'create' || !formData.customerId"
|
disabled
|
||||||
class="w-1/1"
|
class="w-1/1"
|
||||||
filterable
|
filterable
|
||||||
placeholder="请选择合同"
|
placeholder="请选择合同"
|
||||||
|
|
@ -71,14 +72,14 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="计划付款金额" prop="price">
|
<el-form-item label="计划金额(元)" prop="price">
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-model="formData.price"
|
v-model="formData.price"
|
||||||
:min="0.01"
|
:min="0.01"
|
||||||
:precision="2"
|
:precision="2"
|
||||||
class="!w-100%"
|
class="!w-100%"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
placeholder="请输入计划付款金额"
|
placeholder="请输入计划金额"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
@ -95,7 +96,7 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<!-- <el-col :span="12">
|
||||||
<el-form-item label="提前几天提醒" prop="remindDays">
|
<el-form-item label="提前几天提醒" prop="remindDays">
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-model="formData.remindDays"
|
v-model="formData.remindDays"
|
||||||
|
|
@ -116,10 +117,10 @@
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col> -->
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="备注" prop="remark">
|
<el-form-item label="用途" prop="remark">
|
||||||
<el-input v-model="formData.remark" placeholder="请输入备注" type="textarea" />
|
<el-input v-model="formData.remark" placeholder="请输入用途" type="textarea" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
@ -150,9 +151,7 @@ const formData = ref<ReceivablePlanApi.ReceivablePlanVO>({} as ReceivablePlanApi
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
price: [{ required: true, message: '计划付款金额不能为空', trigger: 'blur' }],
|
price: [{ required: true, message: '计划付款金额不能为空', trigger: 'blur' }],
|
||||||
returnTime: [{ required: true, message: '计划付款日期不能为空', trigger: 'blur' }],
|
returnTime: [{ required: true, message: '计划付款日期不能为空', trigger: 'blur' }],
|
||||||
customerId: [{ required: true, message: '客户编号不能为空', trigger: 'blur' }],
|
remark: [{ required: true, message: '用途不能为空', trigger: 'blur' }]
|
||||||
contractId: [{ required: true, message: '合同编号不能为空', trigger: 'blur' }],
|
|
||||||
ownerUserId: [{ required: true, message: '负责人不能为空', trigger: 'blur' }]
|
|
||||||
})
|
})
|
||||||
const formRef = ref() // 表单 Ref
|
const formRef = ref() // 表单 Ref
|
||||||
const customerList = ref<CustomerApi.CustomerVO[]>([]) // 客户列表
|
const customerList = ref<CustomerApi.CustomerVO[]>([]) // 客户列表
|
||||||
|
|
@ -181,9 +180,9 @@ const open = async (type: string, id?: number, customerId?: number, contractId?:
|
||||||
// 获得客户列表
|
// 获得客户列表
|
||||||
customerList.value = await CustomerApi.getCustomerSimpleList()
|
customerList.value = await CustomerApi.getCustomerSimpleList()
|
||||||
// 默认新建时选中自己
|
// 默认新建时选中自己
|
||||||
if (formType.value === 'create') {
|
// if (formType.value === 'create') {
|
||||||
formData.value.ownerUserId = useUserStore().getUser.id
|
// formData.value.ownerUserId = useUserStore().getUser.id
|
||||||
}
|
// }
|
||||||
// 设置 customerId 和 contractId 默认值
|
// 设置 customerId 和 contractId 默认值
|
||||||
if (customerId) {
|
if (customerId) {
|
||||||
formData.value.customerId = customerId
|
formData.value.customerId = customerId
|
||||||
|
|
@ -231,10 +230,13 @@ const resetForm = () => {
|
||||||
const handleCustomerChange = async (customerId: number) => {
|
const handleCustomerChange = async (customerId: number) => {
|
||||||
// 重置合同编号
|
// 重置合同编号
|
||||||
formData.value.contractId = undefined
|
formData.value.contractId = undefined
|
||||||
|
formData.value.deptName = undefined
|
||||||
|
|
||||||
// 获得合同列表
|
// 获得合同列表
|
||||||
if (customerId) {
|
if (customerId) {
|
||||||
contractList.value = []
|
contractList.value = []
|
||||||
contractList.value = await ContractApi.getContractSimpleList(customerId)
|
contractList.value = await ContractApi.getContractSimpleList(customerId)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,51 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- 操作栏 -->
|
<!-- 操作栏 -->
|
||||||
<el-row justify="end">
|
<el-row align="middle" class="mb-2">
|
||||||
<el-button @click="openForm('create', undefined)">
|
<el-col :span="12">
|
||||||
<Icon class="mr-5px" icon="icon-park:income" />
|
<span class="text-xs font-bold">付款计划</span>
|
||||||
创建付款计划
|
</el-col>
|
||||||
</el-button>
|
<el-col :span="12" class="text-right">
|
||||||
|
<el-button @click="openForm('create', undefined)">
|
||||||
|
<Icon class="mr-5px" icon="icon-park:income" />
|
||||||
|
创建付款计划
|
||||||
|
</el-button>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap class="mt-10px">
|
<ContentWrap class="mt-10px">
|
||||||
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
|
<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
|
<el-table-column
|
||||||
:formatter="dateFormatter2"
|
:formatter="dateFormatter2"
|
||||||
align="center"
|
align="center"
|
||||||
label="计划付款日期"
|
label="计划付款日期"
|
||||||
prop="returnTime"
|
prop="returnTime"
|
||||||
width="180px"
|
min-width="150px"
|
||||||
/>
|
/>
|
||||||
<el-table-column align="center" label="提前几天提醒" prop="remindDays" width="150" />
|
<el-table-column align="center" label="收款单位" prop="customerName" min-width="300px" />
|
||||||
|
<el-table-column align="center" label="付款单位" prop="deptName" min-width="300px"/>
|
||||||
|
<el-table-column align="center" label="期数" prop="period" min-width="150px"/>
|
||||||
|
<el-table-column
|
||||||
|
align="center"
|
||||||
|
label="计划付款金额(元)"
|
||||||
|
prop="price"
|
||||||
|
min-width="180"
|
||||||
|
:formatter="erpPriceTableColumnFormatter"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- <el-table-column align="center" label="提前几天提醒" prop="remindDays" width="150" />
|
||||||
<el-table-column
|
<el-table-column
|
||||||
:formatter="dateFormatter2"
|
:formatter="dateFormatter2"
|
||||||
align="center"
|
align="center"
|
||||||
label="提醒日期"
|
label="提醒日期"
|
||||||
prop="remindTime"
|
prop="remindTime"
|
||||||
width="180px"
|
width="180px"
|
||||||
/>
|
/> -->
|
||||||
<el-table-column label="负责人" prop="ownerUserName" width="120" />
|
<!-- <el-table-column label="负责人" prop="ownerUserName" width="120" /> -->
|
||||||
<el-table-column align="center" label="备注" prop="remark" />
|
<el-table-column align="center" label="用途" prop="remark" min-width="300px"/>
|
||||||
<el-table-column align="center" fixed="right" label="操作" width="200px">
|
<el-table-column align="center" fixed="right" label="操作" width="200px">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<!-- <el-button
|
||||||
v-hasPermi="['crm:receivable:create']"
|
v-hasPermi="['crm:receivable:create']"
|
||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
|
|
@ -47,7 +53,7 @@
|
||||||
:disabled="scope.row.receivableId"
|
:disabled="scope.row.receivableId"
|
||||||
>
|
>
|
||||||
创建付款
|
创建付款
|
||||||
</el-button>
|
</el-button> -->
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['crm:receivable-plan:update']"
|
v-hasPermi="['crm:receivable-plan:update']"
|
||||||
link
|
link
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@
|
||||||
<Icon class="mr-5px" icon="ep:refresh" />
|
<Icon class="mr-5px" icon="ep:refresh" />
|
||||||
重置
|
重置
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<!-- <el-button
|
||||||
v-hasPermi="['crm:receivable-plan:create']"
|
v-hasPermi="['crm:receivable-plan:create']"
|
||||||
plain
|
plain
|
||||||
type="primary"
|
type="primary"
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
>
|
>
|
||||||
<Icon class="mr-5px" icon="ep:plus" />
|
<Icon class="mr-5px" icon="ep:plus" />
|
||||||
新增
|
新增
|
||||||
</el-button>
|
</el-button> -->
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['crm:receivable-plan:export']"
|
v-hasPermi="['crm:receivable-plan:export']"
|
||||||
:loading="exportLoading"
|
:loading="exportLoading"
|
||||||
|
|
@ -69,12 +69,15 @@
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<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 v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
|
||||||
<el-table-column align="center" fixed="left" label="客户名称" prop="customerName" width="150">
|
<el-table-column
|
||||||
|
:formatter="dateFormatter2"
|
||||||
|
align="center"
|
||||||
|
label="计划付款日期"
|
||||||
|
prop="returnTime"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column align="center" label="收款单位名称" prop="customerName" width="150">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-link
|
<el-link
|
||||||
:underline="false"
|
:underline="false"
|
||||||
|
|
@ -85,7 +88,17 @@
|
||||||
</el-link>
|
</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" label="合同编号" prop="contractNo" width="200px" />
|
<el-table-column align="center" label="合同名称" prop="contractName" width="200px" >
|
||||||
|
<template #default="scope">
|
||||||
|
<el-link
|
||||||
|
:underline="false"
|
||||||
|
type="primary"
|
||||||
|
@click="openContractDetail(scope.row.contractId)"
|
||||||
|
>
|
||||||
|
{{ scope.row.contractName }}
|
||||||
|
</el-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column align="center" label="期数" prop="period">
|
<el-table-column align="center" label="期数" prop="period">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-link :underline="false" type="primary" @click="openDetail(scope.row.id)">
|
<el-link :underline="false" type="primary" @click="openDetail(scope.row.id)">
|
||||||
|
|
@ -101,30 +114,8 @@
|
||||||
:formatter="erpPriceTableColumnFormatter"
|
:formatter="erpPriceTableColumnFormatter"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
:formatter="dateFormatter2"
|
|
||||||
align="center"
|
align="center"
|
||||||
label="计划付款日期"
|
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"
|
prop="receivable.price"
|
||||||
width="160"
|
width="160"
|
||||||
>
|
>
|
||||||
|
|
@ -135,16 +126,16 @@
|
||||||
<el-text v-else>{{ erpPriceInputFormatter(0) }}</el-text>
|
<el-text v-else>{{ erpPriceInputFormatter(0) }}</el-text>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<!-- <el-table-column
|
||||||
align="center"
|
align="center"
|
||||||
label="实际付款日期"
|
label="实际付款日期"
|
||||||
prop="receivable.returnTime"
|
prop="receivable.returnTime"
|
||||||
width="180px"
|
width="180px"
|
||||||
:formatter="dateFormatter2"
|
:formatter="dateFormatter2"
|
||||||
/>
|
/> -->
|
||||||
<el-table-column
|
<el-table-column
|
||||||
align="center"
|
align="center"
|
||||||
label="实际付款金额(元)"
|
label="应付款金额(元)"
|
||||||
prop="receivable.price"
|
prop="receivable.price"
|
||||||
width="160"
|
width="160"
|
||||||
>
|
>
|
||||||
|
|
@ -155,21 +146,6 @@
|
||||||
<el-text v-else>{{ erpPriceInputFormatter(scope.row.price) }}</el-text>
|
<el-text v-else>{{ erpPriceInputFormatter(scope.row.price) }}</el-text>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</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">
|
<el-table-column align="center" fixed="right" label="操作" width="180px">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
|
|
@ -245,11 +221,6 @@ const exportLoading = ref(false) // 导出的加载中
|
||||||
const activeName = ref('1') // 列表 tab
|
const activeName = ref('1') // 列表 tab
|
||||||
const customerList = ref<CustomerApi.CustomerVO[]>([]) // 客户列表
|
const customerList = ref<CustomerApi.CustomerVO[]>([]) // 客户列表
|
||||||
|
|
||||||
/** tab 切换 */
|
|
||||||
const handleTabClick = (tab: TabsPaneContext) => {
|
|
||||||
queryParams.sceneType = tab.paneName
|
|
||||||
handleQuery()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 查询列表 */
|
/** 查询列表 */
|
||||||
const getList = async () => {
|
const getList = async () => {
|
||||||
|
|
@ -325,6 +296,10 @@ const openDetail = (id: number) => {
|
||||||
const openCustomerDetail = (id: number) => {
|
const openCustomerDetail = (id: number) => {
|
||||||
push({ name: 'CrmCustomerDetail', params: { id } })
|
push({ name: 'CrmCustomerDetail', params: { id } })
|
||||||
}
|
}
|
||||||
|
/** 打开合同详情 */
|
||||||
|
const openContractDetail = (id: number) => {
|
||||||
|
push({ name: 'CrmContractDetail', params: { id } })
|
||||||
|
}
|
||||||
|
|
||||||
/** 初始化 **/
|
/** 初始化 **/
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,162 @@
|
||||||
|
<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="付款单位">
|
||||||
|
<el-select
|
||||||
|
v-model="formData.contractId"
|
||||||
|
class="w-1/1"
|
||||||
|
filterable
|
||||||
|
placeholder="请选择付款单位"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="data in deptList"
|
||||||
|
:key="data.id"
|
||||||
|
:label="data.name"
|
||||||
|
:value="data.id!"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="收款单位" prop="customerName">
|
||||||
|
<el-input
|
||||||
|
v-model="formData.customerName"
|
||||||
|
placeholder="请输入收款单位"/>
|
||||||
|
</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="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'
|
||||||
|
import * as DeptApi from '@/api/system/dept'
|
||||||
|
import { de } from 'element-plus/es/locale'
|
||||||
|
|
||||||
|
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' }],
|
||||||
|
remark: [{ required: true, message: '用途不能为空', trigger: 'blur' }]
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
const deptList = ref<DeptApi.DeptVO[]>([])
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
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)
|
||||||
|
formData.value.contractId = data?.contractId
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获得用户列表
|
||||||
|
userOptions.value = await UserApi.getSimpleUserList()
|
||||||
|
// 加载部门列表
|
||||||
|
deptList.value = await DeptApi.querySimpleDeptList()
|
||||||
|
// 默认新建时选中自己
|
||||||
|
// if (formType.value === 'create') {
|
||||||
|
// formData.value.ownerUserId = useUserStore().getUser.id
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,276 @@
|
||||||
|
<template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<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-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
|
||||||
|
<el-table-column
|
||||||
|
:formatter="dateFormatter2"
|
||||||
|
align="center"
|
||||||
|
label="计划付款日期"
|
||||||
|
prop="returnTime"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column align="center" label="付款单位" prop="deptName" min-width="300">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.deptName }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="收款单位" prop="customerName" min-width="300">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.customerName }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
align="center"
|
||||||
|
label="计划付款金额(元)"
|
||||||
|
prop="price"
|
||||||
|
width="160"
|
||||||
|
:formatter="erpPriceTableColumnFormatter"
|
||||||
|
/>
|
||||||
|
<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 align="center" label="创建人" prop="creatorName" width="150">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.creatorName }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column align="center" fixed="right" label="操作" width="180px">
|
||||||
|
<template #default="scope">
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
|
<RequestForm ref="formRef" @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 * as CustomerApi from '@/api/crm/customer'
|
||||||
|
import { erpPriceInputFormatter, erpPriceTableColumnFormatter } from '@/utils'
|
||||||
|
import { TabsPaneContext } from 'element-plus'
|
||||||
|
import RequestForm from '@/views/crm/receivable/request/RequestForm.vue'
|
||||||
|
|
||||||
|
defineOptions({ name: 'ExpenseRequest' })
|
||||||
|
|
||||||
|
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[]>([]) // 客户列表
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
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 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>
|
||||||
|
|
@ -22,83 +22,11 @@
|
||||||
|
|
||||||
<!-- 附件标签页 -->
|
<!-- 附件标签页 -->
|
||||||
<el-tab-pane label="附件">
|
<el-tab-pane label="附件">
|
||||||
<div v-if="loading" class="loading-container">
|
<AttachmentTab
|
||||||
<el-skeleton :rows="5" animated />
|
:loading="loading"
|
||||||
</div>
|
:pic-urls="stationSite.picUrls"
|
||||||
|
:file-urls="stationSite.fileUrls"
|
||||||
<div v-else class="attachment-container">
|
/>
|
||||||
<!-- 图片展示部分 -->
|
|
||||||
<div class="section" v-if="stationSite.picUrls?.length">
|
|
||||||
<h3 class="section-title">图片</h3>
|
|
||||||
<div class="image-list">
|
|
||||||
<div
|
|
||||||
v-for="(url, index) in stationSite.picUrls"
|
|
||||||
:key="index"
|
|
||||||
class="image-item"
|
|
||||||
>
|
|
||||||
<el-image
|
|
||||||
:src="url"
|
|
||||||
:preview-src-list="stationSite.picUrls"
|
|
||||||
:initial-index="index"
|
|
||||||
fit="cover"
|
|
||||||
class="thumbnail"
|
|
||||||
>
|
|
||||||
<template #error>
|
|
||||||
<div class="image-error">
|
|
||||||
<span>加载失败</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-image>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 文件展示部分 -->
|
|
||||||
<div class="section" v-if="stationSite.fileUrls?.length">
|
|
||||||
<h3 class="section-title">文件</h3>
|
|
||||||
<div class="file-list">
|
|
||||||
<div
|
|
||||||
v-for="(url, index) in stationSite.fileUrls"
|
|
||||||
:key="index"
|
|
||||||
class="file-item"
|
|
||||||
>
|
|
||||||
<el-icon class="file-icon"><Document /></el-icon>
|
|
||||||
<div class="file-info">
|
|
||||||
<a
|
|
||||||
:href="url"
|
|
||||||
target="_blank"
|
|
||||||
class="file-name"
|
|
||||||
@click.prevent="downloadFile(url)"
|
|
||||||
>
|
|
||||||
{{ extractFileName(url) }}
|
|
||||||
</a>
|
|
||||||
<div class="file-actions">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
link
|
|
||||||
@click="downloadFile(url)"
|
|
||||||
>
|
|
||||||
下载
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="info"
|
|
||||||
link
|
|
||||||
@click="previewFile(url)"
|
|
||||||
>
|
|
||||||
预览
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 空状态显示 -->
|
|
||||||
<el-empty
|
|
||||||
v-if="!stationSite.picUrls?.length && !stationSite.fileUrls?.length"
|
|
||||||
description="暂无附件数据"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<!-- <el-tabs>
|
<!-- <el-tabs>
|
||||||
<el-tab-pane label="操作日志">
|
<el-tab-pane label="操作日志">
|
||||||
|
|
@ -128,6 +56,7 @@ import FollowUpList from '@/views/crm/followup/components/FollowUpList.vue'
|
||||||
import StationSiteForm from '../StationSiteForm.vue'
|
import StationSiteForm from '../StationSiteForm.vue'
|
||||||
import CrmTransferForm from '@/views/crm/permission/components/TransferForm.vue'
|
import CrmTransferForm from '@/views/crm/permission/components/TransferForm.vue'
|
||||||
import { ElMessage, ElLoading } from 'element-plus'
|
import { ElMessage, ElLoading } from 'element-plus'
|
||||||
|
import AttachmentTab from '@/components/AttachmentFile/index.vue'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const stationSiteId = ref<number>()
|
const stationSiteId = ref<number>()
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,17 @@
|
||||||
<el-form-item label="显示排序" prop="sort">
|
<el-form-item label="显示排序" prop="sort">
|
||||||
<el-input-number v-model="formData.sort" :min="0" controls-position="right" />
|
<el-input-number v-model="formData.sort" :min="0" controls-position="right" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="负责人" prop="leaderUserId">
|
<el-form-item label="部门类型" prop="type">
|
||||||
|
<el-select v-model="formData.type" clearable placeholder="请选择类型">
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_DEPT_TYPE)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- <el-form-item label="负责人" prop="leaderUserId">
|
||||||
<el-select v-model="formData.leaderUserId" clearable placeholder="请输入负责人">
|
<el-select v-model="formData.leaderUserId" clearable placeholder="请输入负责人">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in userList"
|
v-for="item in userList"
|
||||||
|
|
@ -33,14 +43,14 @@
|
||||||
:value="item.id"
|
:value="item.id"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item> -->
|
||||||
<el-form-item label="联系电话" prop="phone">
|
<el-form-item label="联系电话" prop="phone">
|
||||||
<el-input v-model="formData.phone" maxlength="11" placeholder="请输入联系电话" />
|
<el-input v-model="formData.phone" maxlength="11" placeholder="请输入联系电话" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="邮箱" prop="email">
|
<el-form-item label="邮箱" prop="email">
|
||||||
<el-input v-model="formData.email" maxlength="50" placeholder="请输入邮箱" />
|
<el-input v-model="formData.email" maxlength="50" placeholder="请输入邮箱" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="状态" prop="status">
|
<el-form-item label="状态" prop="status" width="300px">
|
||||||
<el-select v-model="formData.status" clearable placeholder="请选择状态">
|
<el-select v-model="formData.status" clearable placeholder="请选择状态">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
||||||
|
|
@ -83,13 +93,15 @@ const formData = ref({
|
||||||
leaderUserId: undefined,
|
leaderUserId: undefined,
|
||||||
phone: undefined,
|
phone: undefined,
|
||||||
email: undefined,
|
email: undefined,
|
||||||
status: CommonStatusEnum.ENABLE
|
status: CommonStatusEnum.ENABLE,
|
||||||
|
type: undefined
|
||||||
})
|
})
|
||||||
const formRules = reactive<FormRules>({
|
const formRules = reactive<FormRules>({
|
||||||
parentId: [{ required: true, message: '上级部门不能为空', trigger: 'blur' }],
|
parentId: [{ required: true, message: '上级部门不能为空', trigger: 'blur' }],
|
||||||
name: [{ required: true, message: '部门名称不能为空', trigger: 'blur' }],
|
name: [{ required: true, message: '部门名称不能为空', trigger: 'blur' }],
|
||||||
sort: [{ required: true, message: '显示排序不能为空', trigger: 'blur' }],
|
sort: [{ required: true, message: '显示排序不能为空', trigger: 'blur' }],
|
||||||
email: [{ type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }],
|
email: [{ type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }],
|
||||||
|
type: [{ required: true, message: '部门类型不能为空', trigger: ['blur', 'change'] }],
|
||||||
phone: [
|
phone: [
|
||||||
{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的手机号码', trigger: 'blur' }
|
{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的手机号码', trigger: 'blur' }
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -59,25 +59,31 @@
|
||||||
:default-expand-all="isExpandAll"
|
:default-expand-all="isExpandAll"
|
||||||
v-if="refreshTable"
|
v-if="refreshTable"
|
||||||
>
|
>
|
||||||
<el-table-column prop="name" label="部门名称" />
|
<el-table-column prop="name" label="部门名称" width="500px" />
|
||||||
|
<!--
|
||||||
<el-table-column prop="leader" label="负责人">
|
<el-table-column prop="leader" label="负责人">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
{{ userList.find((user) => user.id === scope.row.leaderUserId)?.nickname }}
|
{{ userList.find((user) => user.id === scope.row.leaderUserId)?.nickname }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column> -->
|
||||||
<el-table-column prop="sort" label="排序" />
|
<el-table-column prop="sort" label="排序" />
|
||||||
<el-table-column prop="status" label="状态">
|
<el-table-column prop="status" label="状态">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column label="部门类型" align="center" prop="type" width="150px">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.SYSTEM_DEPT_TYPE" :value="scope.row.type" width="300px"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- <el-table-column
|
||||||
label="创建时间"
|
label="创建时间"
|
||||||
align="center"
|
align="center"
|
||||||
prop="createTime"
|
prop="createTime"
|
||||||
width="180"
|
width="180"
|
||||||
:formatter="dateFormatter"
|
:formatter="dateFormatter"
|
||||||
/>
|
/> -->
|
||||||
<el-table-column label="操作" align="center">
|
<el-table-column label="操作" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue