dbd-meeting-html/src/views/admin/CustomerEdit.vue
2024-03-28 16:35:05 +08:00

708 lines
27 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<a-card :body-style="{padding: '24px 32px'}" :bordered='false'>
<a-form @submit='handleSubmit' :form='form' :label-col='{ span: 4 }' :wrapper-col='{ span: 6 }'>
<a-tabs :defaultActiveKey='defaultActiveKey' @change='callback'>
<a-tab-pane tab='企业详情' key='1'>
<a-form-item style='display:none'>
<a-input v-decorator="['id']" />
</a-form-item>
<a-row>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='企业名称'>
<a-input placeholder='企业名称'
v-decorator="['name', {rules: [{required: true, message: '请输入企业名称'}]}]" />
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='简称'>
<a-input placeholder='简称' v-decorator="['shortName']" />
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='企业类型'>
<a-select
v-decorator="['type', {initialValue:'COMPANY',rules: [{required: true, message: '请选择企业类型'}]}]">
<a-select-option value='COMPANY'>公司</a-select-option>
<a-select-option value='PERSON'>个人</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='企业状态'>
<a-select
v-decorator="['customerStatus', {initialValue:'DEAL',rules: [{required: true, message: '请选择企业状态'}]}]">
<a-select-option value='POTENTIAL'>潜在企业</a-select-option>
<a-select-option value='PURPOSE'>意向企业</a-select-option>
<a-select-option value='DEAL'>成交企业</a-select-option>
<a-select-option value='LOSE'>流失企业</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='楼层'>
<a-select v-decorator="['buildId',{rules: [{ required: true, message: '请选择所属楼层' }]}]"
placeholder='所属楼层' @change='getRoomList'>
<a-select-option v-for='item in floorList' :key='item.id' :value='item.id'>
{{ item.floorName }}
</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='房间'>
<a-select v-decorator="['roomId',{rules: [{ required: true, message: '选择所属房间' }]}]"
placeholder='所属房间'>
<a-select-option v-for='item in roomList' :key='item.id' :value='item.id'>
{{ item.name }}
</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='入住时间'>
<a-date-picker
format='YYYY-MM-DD HH:mm'
valueFormat='YYYY-MM-DD HH:mm:ss'
:show-time="{ format: 'HH:mm' }"
v-decorator="['startDate',{rules: [{ required: true, message: '选择入住时间' }]}]"
type='date'
placeholder='入住时间'
style='width: 100%'
/>
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='租期结束时间'>
<a-date-picker
format='YYYY-MM-DD HH:mm'
valueFormat='YYYY-MM-DD HH:mm:ss'
:show-time="{ format: 'HH:mm' }"
v-decorator="['endDate',{rules: [{ required: true, message: '选择租期结束时间' }]}]"
type='date'
placeholder='租期结束时间'
style='width: 100%'
/>
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='所属行业'>
<a-input placeholder='所属行业' v-decorator="['sector']" />
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='所属国家'>
<a-input placeholder='所属国家' v-decorator="['country']" />
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='过程管理'>
<a-select v-decorator="['process']">
<a-select-option value='FIRST_VISIT'>初次拜访</a-select-option>
<a-select-option value='NEED_GUID'>需求引导分析</a-select-option>
<a-select-option value='COMPETE'>竞争阶段</a-select-option>
<a-select-option value='PREDETERMINE'>预定阶段</a-select-option>
<a-select-option value='CONTRACT'>合同阶段</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='联系人'>
<a-input placeholder='联系人' v-decorator="['contacts',{rules: [{ required: true, message: '请输入联系人' }]}]" />
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='联系电话'>
<a-input placeholder='联系电话' v-decorator="['phone',{rules: [{ required: true, message: '请输入联系电话' }]}]" />
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='邮箱'>
<a-input placeholder='邮箱' v-decorator="['email']" />
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='统一信用代码'>
<a-input placeholder='统一信用代码' v-decorator="['creditNo']" />
<a-button type='primary' @click='getQiXinBasicInfo'>同步工商数据</a-button>
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='邮编'>
<a-input placeholder='邮编' v-decorator="['postalCode']" />
</a-form-item>
</a-col>
<a-col :span='24'>
<a-form-item :labelCol='labelCol' :wrapperCol='wrapperCol' label='通讯地址'>
<a-input placeholder='通讯地址' v-decorator="['mailAddress']" />
</a-form-item>
</a-col>
<a-col :span='24'>
<a-form-item :labelCol='labelCol' :wrapperCol='wrapperCol' label='上传公司头像'
extra='尺寸建议宽160px高160px'>
<a-upload
v-decorator="['headImg']"
list-type='picture-card'
class='avatar-uploader'
:show-upload-list='false'
:action='uploadUrl'
:headers='headers'
:before-upload='beforeUpload'
@change='handleChange'
>
<img v-if='imageUrl' :src='imageUrl' style='width: 102px; height: 102px' />
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class='ant-upload-text'> 上传</div>
</div>
</a-upload>
</a-form-item>
</a-col>
<a-col :span='24'>
<a-form-item :labelCol='labelCol' :wrapperCol='wrapperCol' label='上传照片墙'>
<a-upload
v-decorator="['bannerImages', {rules: [{ required: false, message: '上传照片墙' }]}]"
list-type='picture-card'
class='avatar-uploader'
:file-list='fileList'
:action='uploadUrl'
:headers='headers'
@preview='handlePreview'
@change='handleChangeFileList'
>
<div v-if='fileList.length < 4'>
<a-icon type='plus' />
<div class='ant-upload-text'> 上传</div>
</div>
</a-upload>
<a-modal :visible='previewVisible' :footer='null' @cancel='handleCancel'>
<img style='width: 100%' :src='previewImage' />
</a-modal>
</a-form-item>
</a-col>
<a-col :span='8'>
<a-form-item :labelCol='labelColOneThird' :wrapperCol='wrapperColOneThird' label='渠道类型'>
<a-select v-decorator="['channelType']">
<a-select-option value='AGENT'>中介公司</a-select-option>
<a-select-option value='AD'>广告</a-select-option>
<a-select-option value='COOPERATE'>合作推荐</a-select-option>
<a-select-option value='MY_CHANNEL'>自开发渠道</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span='8'>
<a-form-item :labelCol='labelColOneThird' :wrapperCol='wrapperColOneThird' label='渠道名称'>
<a-input placeholder='渠道名称' v-decorator="['channelName']" />
</a-form-item>
</a-col>
<a-col :span='8'>
<a-form-item :labelCol='labelColOneThird' :wrapperCol='wrapperColOneThird' label='是否黑名单'>
<a-switch :checked='customerForm.isBlacklist' @change='onChangeBlacklist'
v-decorator="['isBlacklist']" />
</a-form-item>
</a-col>
<a-col :span='24'>
<a-form-item :labelCol='labelCol' :wrapperCol='wrapperColOneThird' label='企业备注'>
<a-input placeholder='企业备注' v-decorator="['remark']" />
</a-form-item>
</a-col>
<a-col :span='24'>
<a-form-item :labelCol='labelCol' :wrapperCol='wrapperCol' label='工商注册号'>
<a-input placeholder='工商注册号' v-decorator="['regNo']" />
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='组织机构代码'>
<a-input placeholder='组织机构代码' v-decorator="['orgNo']" />
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='法人名'>
<a-input placeholder='法人名' v-decorator="['operName']" />
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='经营状态'>
<a-input placeholder='经营状态' v-decorator="['status']" />
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='公司类型(企业性质)'>
<a-input placeholder='公司类型(企业性质)' v-decorator="['econKind']" />
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='注册资金'>
<a-input placeholder='注册资金' v-decorator="['registCapi']" />
</a-form-item>
</a-col>
<a-col :span='12'>
<a-form-item :labelCol='labelColHalf' :wrapperCol='wrapperColHalf' label='登记机关'>
<a-input placeholder='登记机关'
v-decorator="['belongOrg']" />
</a-form-item>
</a-col>
<a-col :span='24'>
<a-form-item :labelCol='labelCol' :wrapperCol='wrapperCol' label='注册地址'>
<a-input placeholder='注册地址'
v-decorator="['address']" />
</a-form-item>
</a-col>
<a-col :span='24'>
<a-form-item :labelCol='labelCol' :wrapperCol='wrapperCol' label='经营范围'>
<!-- <a-input placeholder="经营范围" v-decorator="['scope']" /> -->
<a-textarea placeholder='经营范围' v-decorator="['scope']"
:autoSize='{ minRows: 3, maxRows: 5 }'></a-textarea>
</a-form-item>
</a-col>
</a-row>
<a-form-item :wrapperCol='{ span: 24 }' style='text-align: center'>
<a-button htmlType='submit' type='primary'>提交</a-button>
<a-button icon='rollback' style='margin-left: 8px' @click='rollback'>关闭</a-button>
</a-form-item>
</a-tab-pane>
<a-tab-pane tab='关联合同' key='2' forceRender v-if='$route.query.customerId'>
<div style='margin: 10px'>
<a-button type='primary' @click='navContract'>新增合同</a-button>
</div>
<a-table
:pagination='false'
:columns='contractColumns'
:dataSource='contractData'
rowKey='id'
>
<div slot='sn' slot-scope='text, record' style='cursor:pointer;color:#1890ff'
@click='handleDetail(record.id)'>
<span>{{ text }}</span>
</div>
<span slot='serial' slot-scope='text, record, index'>
{{ index + 1 }}
</span>
<span slot='status' slot-scope='text'>
{{ text | statusFilter }}
</span>
</a-table>
</a-tab-pane>
<a-tab-pane tab='联系人' key='3' v-if='$route.query.customerId'>
<div style='margin: 10px'>
<a-button type='primary' @click='$refs.contactModal.add({ customerId: $route.query.customerId })'>
新建联系人
</a-button>
</div>
<a-table :pagination='false' :columns='contactsItemColumns' :dataSource='contactsItemData' rowKey='id'>
<template slot='operation' slot-scope='text, record'>
<!-- <a-button type="link" @click="$refs.contactModal.add(record)">编辑</a-button>-->
<!-- <a-divider type="vertical" />-->
<a-popconfirm @confirm='handleDeleteContact(record)'>
<template slot='title'>
<span>确定删除 {{ record.name }} </span>
</template>
<a-icon slot='icon' type='question-circle-o' style='color: red' />
<a-button type='link'>删除</a-button>
</a-popconfirm>
</template>
</a-table>
</a-tab-pane>
<a-tab-pane tab='相关文件' key='4' v-if='$route.query.customerId'>
<customer-attachment-list :customer-id='$route.query.customerId'></customer-attachment-list>
</a-tab-pane>
</a-tabs>
</a-form>
<customer-contacts-modal ref='contactModal' @ok='handleContactSaved' />
</a-card>
</template>
<script>
import moment from 'moment'
import storage from 'store'
import { ACCESS_TOKEN } from '@/store/mutation-types'
import {
saveCustomer,
getCustomer,
getQiXinBasicInfo,
getStaffList,
updateStaffByCustomer
} from '@/api/admin/customer'
import {
getFloorList,
getRoomListByFloorId
} from '@/api/admin/meeting/roomContent'
import { getCustomerContractList } from '@/api/admin/customerContract'
import CustomerContactsModal from './modules/CustomerContactsModal.vue'
import CustomerAttachmentList from './modules/CustomerAttachmentList.vue'
import pick from 'lodash.pick'
export default {
name: 'BaseForm',
components: {
CustomerContactsModal,
CustomerAttachmentList
},
data() {
return {
id: '',
defaultActiveKey: '1',
// 合同行
contractColumns: [
{
title: '合同编号',
dataIndex: 'sn',
scopedSlots: { customRender: 'sn' }
},
{
title: '物管合同号',
dataIndex: 'pmSn'
},
{
title: '合同名称',
dataIndex: 'name'
},
{
title: '签订时间',
dataIndex: 'signDate'
},
{
title: '记租时间',
dataIndex: 'startDate'
},
{
title: '到期时间',
dataIndex: 'endDate'
},
{
title: '状态',
dataIndex: 'status',
scopedSlots: { customRender: 'status' }
},
{
title: '签订人',
dataIndex: 'operName'
}
],
// 联系人列表表头
contactsItemColumns: [
{
title: '昵称',
dataIndex: 'username'
},
{
title: '手机号',
dataIndex: 'mobile'
},
{
title: '操作',
key: 'operation',
scopedSlots: { customRender: 'operation' }
}
],
labelColHalf: {
span: 6
},
wrapperColHalf: {
span: 18
},
labelColOneThird: {
span: 9
},
wrapperColOneThird: {
span: 15
},
labelCol: {
xs: { span: 24 },
sm: { span: 3 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 21 }
},
contractData: [],
orderPaymentData: [],
orderRefundsData: [],
orderShippingData: [],
orderReturnsData: [],
contactsItemData: [],
customerForm: {},
uploadUrl: process.env.VUE_APP_API_BASE_URL + '/api/dfs/upload',
headers: {
Authorization: 'Bearer ' + storage.get(ACCESS_TOKEN)
},
fileList: [],
previewVisible: false,
previewImage: '',
loading: false,
imageUrl: '',
// form
form: this.$form.createForm(this),
floorList: [],
roomList: [],
}
},
filters: {
statusFilter(type) {
const statusMap = {
'DRAFT': '草稿',
'APPROVING': '待审批',
'APPROVED': '已审批',
'REFUSE': '已拒绝',
'EXECUTING': '执行中',
'VOIDED': '已作废',
'OVERDUE': '已到期',
'END': '已结束'
}
return statusMap[type]
}
},
created() {
this.id = this.$route.query.customerId
if (this.$route.query.types) {
this.defaultActiveKey = '2'
}
this.handleInit()
// 获取楼层
this.getFloorDataList();
},
methods: {
// 获取楼层
getFloorDataList() {
getFloorList().then((res) => {
this.floorList = res.data
})
},
// 获取房间
getRoomList(value) {
let param = {
'buildingDetailId': value,
'type': 0
}
getRoomListByFloorId(param).then((res) => {
this.roomList = res.data
})
},
handleDetail(id) {
this.$router.push({
name: 'customerContractDetailModal',
query: { id: id, customerId: this.$route.query.customerId, url: 'customerEdit' }
})
},
navContract(e) {
this.$router.push({ name: 'customerContractEdit', query: { customerId: this.id, url: 'customerEdit' } })
},
onChangeBlacklist(checked) {
this.customerForm.isBlacklist = checked
},
getQiXinBasicInfo() {
var keyword = this.form.getFieldValue('creditNo')
getQiXinBasicInfo({ 'keyword': keyword }).then(res => {
if (res.code === 0) {
var qiXinResult = JSON.parse(res.data)
if (!(isNaN(qiXinResult) && !isNaN(Date.parse(qiXinResult.endDate)))) {
qiXinResult.endDate = null
}
this.form.setFieldsValue(pick(qiXinResult, 'creditNo', 'regNo', 'status', 'orgNo', 'operName', 'econKind', 'startDate', 'registCapi', 'endDate', 'address', 'scope', 'delFlag', 'belongOrg', 'remark'))
} else {
this.$message.error('同步工商信息失败:' + res.msg)
}
})
},
handleInit() {
const { customerId } = this.$route.query
if (customerId) {
getCustomer(customerId).then(res => {
this.customerForm = res
// 房间
if (this.customerForm.roomId) {
this.roomList.push({
id: this.customerForm.roomId,
name: this.customerForm.roomName
})
}
// 头像
if (this.customerForm.headImg) {
this.imageUrl = process.env.VUE_APP_API_BASE_URL + this.customerForm.headImg
}
// 照片墙
this.customerForm.bannerImages.forEach((item, i) => {
item.url = process.env.VUE_APP_API_BASE_URL + item.url
})
this.fileList = this.customerForm.bannerImages
this.form.setFieldsValue(pick(this.customerForm, 'id', 'name', 'shortName', 'type', 'customerStatus', 'sector', 'country', 'process', 'contacts', 'phone', 'email', 'creditNo', 'mailAddress',
'postalCode', 'channelType', 'channelName', 'isBlacklist', 'regNo', 'status', 'orgNo', 'operName', 'econKind', 'startDate', 'registCapi', 'endDate'
, 'address', 'scope', 'delFlag', 'belongOrg', 'remark', 'headImg', 'bannerImages' , 'roomId' , 'buildId'))
})
}
this.getContastsList()
this.getContractList()
},
onChange(date, dateString) {
console.log(date, dateString)
},
// handler
handleSubmit(e) {
e.preventDefault()
this.form.validateFields((err, values) => {
if (!err) {
// eslint-disable-next-line no-console
const bannerImages = []
this.fileList.forEach((file, index) => {
// 添加原来的
if (file.hasOwnProperty('name') && file.hasOwnProperty('url') && file.hasOwnProperty('uid')) {
bannerImages.push({ 'name': file.name, 'url': file.name, 'uid': index })
}
if (file.status === 'done' && file.response.code === 0) {
const data = file.response
bannerImages.push({ 'name': data.fileName, 'url': data.fileName, 'uid': index })
}
})
// 照片墙
values.bannerImages = bannerImages
console.log('Received values of form: ', values)
// values.startDate = moment(values.startDate).format('YYYY-MM-DD')
// console.log(values.startDate)
this.confirmLoading = true
saveCustomer(values).then(res => {
if (res.code === 0) {
this.$message.success('保存成功')
this.$emit('ok')
this.visible = false
this.rollback()
} else {
this.$message.error(res.msg)
}
}).catch(() => {
this.$message.error('系统错误,请稍后再试')
}).finally(() => {
this.confirmLoading = false
})
}
})
},
rollback() {
this.$router.push('/admin/service/customer')
},
// 联系人列表
getContastsList() {
let param = {
customerId: this.$route.query.customerId
}
getStaffList(param).then(res => {
this.contactsItemData = res.rows
})
},
// 合同列表
getContractList() {
getCustomerContractList({ customerId: this.$route.query.customerId }).then(res => {
// console.log(res)
if (res.code === 0) {
this.contractData = res.rows
}
})
},
// 新增联系人回调
handleContactSaved() {
this.getContastsList()
},
// 删除联系人
handleDeleteContact(contactInfo) {
console.log(contactInfo)
// contactInfo.
updateStaffByCustomer(contactInfo).then(res => {
if (res.code === 0) {
this.$message.success('删除成功')
this.deleteVisible = false
this.getContastsList()
} else {
this.$message.error(res.msg)
}
}).catch(() => {
this.$message.error('系统错误,请稍后再试')
}).finally(() => {
})
},
beforeUpload(file) {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'
if (!isJpgOrPng) {
this.$message.error('You can only upload JPG file!')
}
const isLt2M = file.size / 1024 / 1024 < 2
if (!isLt2M) {
this.$message.error('图片必须小于 2MB!')
}
return isJpgOrPng && isLt2M
},
handleChange(info) {
if (info.file.status === 'uploading') {
this.loading = true
return
}
if (info.file.status === 'done') {
const { form: { setFieldsValue } } = this
const result = info.file.response
// 设置值
this.$nextTick(() => {
setFieldsValue({
headImg: result.fileName
})
})
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => {
this.imageUrl = imageUrl
this.loading = false
})
}
},
async handlePreview(file) {
if (!file.url && !file.preview) {
file.preview = await getBase64FileList(file.originFileObj)
}
this.previewImage = file.url || file.preview
this.previewVisible = true
},
handleCancel() {
this.previewVisible = false
},
// 上传照片墙
handleChangeFileList({ fileList }) {
this.fileList = fileList
}
}
}
// 上传头像
function getBase64(img, callback) {
const reader = new FileReader()
reader.addEventListener('load', () => callback(reader.result))
reader.readAsDataURL(img)
}
// 上传照片墙
function getBase64FileList(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => resolve(reader.result)
reader.onerror = error => reject(error)
})
}
</script>
<style>
.avatar-uploader > .ant-upload {
width: 102px;
height: 102px;
}
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
</style>