| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680 |
- <template>
- <div v-if="showModal" class="modal-overlay" @click.self="handleClose">
- <div class="modal modal-lg">
- <div class="modal-header">
- <div class="modal-title"><i class="fas fa-user-plus"></i> 添加客户</div>
- <button class="modal-close" @click="handleClose"><i class="fas fa-times"></i></button>
- </div>
- <div class="modal-body">
- <!-- 基础信息 -->
- <div class="section-title">基础信息</div>
- <div class="form-row ">
- <div class="lef">
- <div class="form-group">
- <label class="form-label">客户代码</label>
- <input type="text" class="form-input" v-model="formData.customerCode" placeholder="客户代码">
- </div>
- <div class="form-group">
- <label class="form-label">归属人员 <span class="required">*</span></label>
- <select class="form-select" v-model="formData.ownerUser">
- <option value="">请选择用户</option>
- <option value="user1">用户1</option>
- <option value="user2">用户2</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">客户状态 <span class="required">*</span></label>
- <select class="form-select" v-model="formData.customerStatus">
- <option value="no_need">暂无需</option>
- <option value="intent">意向客户</option>
- <option value="deal">成交客户</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">联系人姓名 <span class="required">*</span></label>
- <input type="text" class="form-input" v-model="formData.contactName" placeholder="请输入联系人姓名">
- </div>
- <div class="form-group">
- <label class="form-label">意向产品</label>
- <select class="form-select" v-model="formData.intentProduct">
- <option value="">意向产品</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">客户来源</label>
- <select class="form-select" v-model="formData.source">
- <option value="">客户来源</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">客户等级</label>
- <div class="radio-group">
- <label class="radio-item">
- <input type="radio" v-model="formData.level" value="A"> A级
- </label>
- <label class="radio-item">
- <input type="radio" v-model="formData.level" value="B"> B级
- </label>
- <label class="radio-item">
- <input type="radio" v-model="formData.level" value="C"> C级
- </label>
- <label class="radio-item">
- <input type="radio" v-model="formData.level" value="D"> D级
- </label>
- </div>
- </div>
- <div class="form-group">
- <label class="form-label">助记名称</label>
- <input type="text" class="form-input" v-model="formData.alias" placeholder="请输入助记名称">
- </div>
- </div>
- <div class="right">
- <div class="form-group">
- <label class="form-label">区域名称 <span class="required">*</span></label>
- <select class="form-select" v-model="formData.regionName">
- <option value="">请选择</option>
- <option value="A">区域A</option>
- <option value="B">区域B</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">客户名称 <span class="required">*</span></label>
- <input type="text" class="form-input" v-model="formData.customerName" placeholder="请输入客户名称">
- </div>
- <!-- 企业网址 紧凑多行布局 -->
- <div class="form-group multi-input-group">
- <label class="form-label">企业网址 <span class="required">*</span></label>
- <div class="input-item" v-for="(item, idx) in formData.websiteList" :key="idx">
- <div class="input-with-icon">
- <input
- type="text"
- class="form-input"
- v-model="formData.websiteList[idx]"
- placeholder="请输入企业网址"
- >
- <span class="icon-btn" @click="addWebsite" v-if="idx === 0">+</span>
- <span class="icon-btn minus" @click="delWebsite(idx)" v-if="idx > 0">-</span>
- </div>
- </div>
- </div>
- <!-- 联系人邮箱 紧凑多行布局 -->
- <div class="form-group multi-input-group">
- <label class="form-label">联系人邮箱 <span class="required">*</span></label>
- <div class="input-item" v-for="(item, idx) in formData.emailList" :key="idx">
- <div class="input-with-icon">
- <input
- type="text"
- class="form-input"
- v-model="formData.emailList[idx]"
- placeholder="请输入联系人邮箱"
- >
- <span class="icon-btn" @click="addEmail" v-if="idx === 0">+</span>
- <span class="icon-btn minus" @click="delEmail(idx)" v-if="idx > 0">-</span>
- </div>
- </div>
- </div>
- <div class="form-group">
- <label class="form-label">客户类型</label>
- <select class="form-select" v-model="formData.customerType">
- <option value="">客户类型</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">经济性质</label>
- <select class="form-select" v-model="formData.economicNature">
- <option value="">客户经济性质</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">信用等级</label>
- <div class="radio-group">
- <label class="radio-item">
- <input type="radio" v-model="formData.creditLevel" value="good"> 良好
- </label>
- <label class="radio-item">
- <input type="radio" v-model="formData.creditLevel" value="normal"> 一般
- </label>
- <label class="radio-item">
- <input type="radio" v-model="formData.creditLevel" value="poor"> 较差
- </label>
- <label class="radio-item">
- <input type="radio" v-model="formData.creditLevel" value="worse"> 比较差
- </label>
- </div>
- </div>
- <div class="form-group">
- <label class="form-label">备注信息</label>
- <textarea class="form-textarea" v-model="formData.remark" placeholder="请输入内容"></textarea>
- </div>
- </div>
- </div>
- <!-- 企业信息 -->
- <div class="section-title">企业信息</div>
- <div class="form-row">
- <div class="form-group">
- <label class="form-label">企业规模</label>
- <select class="form-select" v-model="formData.scale">
- <option value="">意向产品</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">所属行业</label>
- <input type="text" class="form-input" v-model="formData.industry" placeholder="请输入所属行业">
- </div>
- </div>
- <div class="form-row">
- <div class="form-group">
- <label class="form-label">通信地址</label>
- <input type="text" class="form-input" v-model="formData.address" placeholder="请输入通信地址">
- </div>
- <div class="form-group">
- <label class="form-label">邮政编码</label>
- <input type="text" class="form-input" v-model="formData.postcode" placeholder="请输入邮政编码">
- </div>
- </div>
- <div class="form-row">
- <div class="form-group">
- <label class="form-label">传真号码</label>
- <input type="text" class="form-input" v-model="formData.fax" placeholder="请输入传真号码">
- </div>
- <div class="form-group">
- <label class="form-label">企业邮箱</label>
- <div class="input-with-icon">
- <input type="text" class="form-input" v-model="formData.companyEmail" placeholder="请输入企业邮箱">
- <span class="icon-btn">+</span>
- </div>
- </div>
- </div>
- <div class="form-row">
- <div class="form-group">
- <label class="form-label">企业备用邮箱</label>
- <div class="input-with-icon">
- <input type="text" class="form-input" v-model="formData.backupEmail" placeholder="请输入企业备用邮箱">
- <span class="icon-btn minus">-</span>
- </div>
- </div>
- <div class="form-group">
- <label class="form-label">联系号码</label>
- <input type="text" class="form-input" v-model="formData.contactPhone" placeholder="请输入联系号码">
- </div>
- </div>
- <!-- 首要联系人 -->
- <div class="section-title">首要联系人</div>
- <div class="form-row">
- <div class="form-group">
- <label class="form-label">称呼</label>
- <div class="radio-group">
- <label class="radio-item">
- <input type="radio" v-model="formData.gender" value="unknown"> 未知
- </label>
- <label class="radio-item">
- <input type="radio" v-model="formData.gender" value="mr"> 先生
- </label>
- <label class="radio-item">
- <input type="radio" v-model="formData.gender" value="mrs"> 女士
- </label>
- </div>
- </div>
- <div class="form-group">
- <label class="form-label">角色</label>
- <select class="form-select" v-model="formData.role">
- <option value="">请选择角色</option>
- </select>
- </div>
- </div>
- <div class="form-row">
- <div class="form-group">
- <label class="form-label">生日</label>
- <select class="form-select" v-model="formData.birthday">
- <option value="">请选择生日</option>
- </select>
- </div>
- <div class="form-group">
- <label class="form-label">部门职务</label>
- <input type="text" class="form-input" v-model="formData.position" placeholder="请输入部门职务">
- </div>
- </div>
- <div class="form-row">
- <div class="form-group">
- <label class="form-label">手机号码</label>
- <input type="text" class="form-input" v-model="formData.mobile" placeholder="请输入手机号码">
- </div>
- <div class="form-group">
- <label class="form-label">联系人备用邮箱</label>
- <div class="input-with-icon">
- <input type="text" class="form-input" v-model="formData.contactBackupEmail" placeholder="请输入联系人备用邮箱">
- <span class="icon-btn minus">-</span>
- </div>
- </div>
- </div>
- <div class="form-row">
- <div class="form-group">
- <label class="form-label">固定电话</label>
- <input type="text" class="form-input" v-model="formData.tel" placeholder="请输入固定电话">
- </div>
- <div class="form-group">
- <label class="form-label">传真号码</label>
- <input type="text" class="form-input" v-model="formData.contactFax" placeholder="请输入传真号码">
- </div>
- </div>
- <div class="form-row">
- <div class="form-group">
- <label class="form-label">宅电</label>
- <input type="text" class="form-input" v-model="formData.homeTel" placeholder="请输入内容">
- </div>
- <div class="form-group">
- <label class="form-label">QQ</label>
- <input type="text" class="form-input" v-model="formData.qq" placeholder="请输入QQ">
- </div>
- </div>
- <div class="form-row">
- <div class="form-group">
- <label class="form-label">SKYPE</label>
- <input type="text" class="form-input" v-model="formData.skype" placeholder="请输入SKYPE">
- </div>
- <div class="form-group">
- <label class="form-label">旺旺</label>
- <input type="text" class="form-input" v-model="formData.ww" placeholder="请输入旺旺">
- </div>
- </div>
- <div class="form-row">
- <div class="form-group">
- <label class="form-label">微信</label>
- <input type="text" class="form-input" v-model="formData.wechat" placeholder="请输入微信">
- </div>
- <div class="form-group">
- <label class="form-label">Twitter</label>
- <input type="text" class="form-input" v-model="formData.twitter" placeholder="请输入Twitter">
- </div>
- </div>
- <div class="form-row">
- <div class="form-group">
- <label class="form-label">LinkedIn</label>
- <input type="text" class="form-input" v-model="formData.linkedin" placeholder="请输入LinkedIn">
- </div>
- <div class="form-group">
- <label class="form-label">Facebook</label>
- <input type="text" class="form-input" v-model="formData.facebook" placeholder="请输入Facebook">
- </div>
- </div>
- <div class="form-row">
- <div class="form-group">
- <label class="form-label">Whatsapp</label>
- <input type="text" class="form-input" v-model="formData.whatsapp" placeholder="请输入Whatsapp">
- </div>
- <div class="form-group">
- <label class="form-label">所在地区</label>
- <input type="text" class="form-input" v-model="formData.contactRegion" placeholder="请输入所在地区">
- </div>
- </div>
- </div>
- <div class="modal-footer">
- <button class="btn btn-secondary" @click="handleClose">取消</button>
- <button class="btn btn-primary" @click="handleAdd"><i class="fas fa-plus"></i> 添加</button>
- </div>
- </div>
- </div>
- </template>
- <script setup>
- import { ref, defineProps, defineEmits } from 'vue'
- const props = defineProps({
- showModal: {
- type: Boolean,
- default: false
- }
- })
- const emit = defineEmits(['close', 'add'])
- // 表单数据
- const formData = ref({
- customerCode: '',
- regionName: '',
- ownerUser: '',
- customerName: '',
- customerStatus: 'no_need',
- websiteList: [''], // 最多4条(主+3备用)
- emailList: [''], // 最多4条(主+3备用)
- intentProduct: '',
- customerType: '',
- source: '',
- economicNature: '',
- level: 'A',
- creditLevel: 'good',
- alias: '',
- remark: '',
- scale: '',
- industry: '',
- address: '',
- postcode: '',
- fax: '',
- companyEmail: '',
- backupEmail: '',
- contactPhone: '',
- gender: 'unknown',
- role: '',
- birthday: '',
- position: '',
- mobile: '',
- contactBackupEmail: '',
- tel: '',
- contactFax: '',
- homeTel: '',
- qq: '',
- skype: '',
- ww: '',
- wechat: '',
- twitter: '',
- linkedin: '',
- facebook: '',
- whatsapp: '',
- contactRegion: ''
- })
- // 企业网址 新增
- const addWebsite = () => {
- if (formData.value.websiteList.length >= 4) return
- formData.value.websiteList.push('')
- }
- // 企业网址 删除
- const delWebsite = (index) => {
- formData.value.websiteList.splice(index, 1)
- }
- // 联系人邮箱 新增
- const addEmail = () => {
- if (formData.value.emailList.length >= 4) return
- formData.value.emailList.push('')
- }
- // 联系人邮箱 删除
- const delEmail = (index) => {
- formData.value.emailList.splice(index, 1)
- }
- // 关闭弹窗 & 重置表单
- const handleClose = () => {
- formData.value = {
- customerCode: '',
- regionName: '',
- ownerUser: '',
- customerName: '',
- customerStatus: 'no_need',
- websiteList: [''],
- emailList: [''],
- intentProduct: '',
- customerType: '',
- source: '',
- economicNature: '',
- level: 'A',
- creditLevel: 'good',
- alias: '',
- remark: '',
- scale: '',
- industry: '',
- address: '',
- postcode: '',
- fax: '',
- companyEmail: '',
- backupEmail: '',
- contactPhone: '',
- gender: 'unknown',
- role: '',
- birthday: '',
- position: '',
- mobile: '',
- contactBackupEmail: '',
- tel: '',
- contactFax: '',
- homeTel: '',
- qq: '',
- skype: '',
- ww: '',
- wechat: '',
- twitter: '',
- linkedin: '',
- facebook: '',
- whatsapp: '',
- contactRegion: ''
- }
- emit('close')
- }
- // 提交表单
- const handleAdd = () => {
- const { websiteList, emailList, regionName, ownerUser, customerName, customerStatus } = formData.value
- if (!regionName || !ownerUser || !customerName || !customerStatus) {
- alert('请填写所有必填项!')
- return
- }
- // 过滤空值
- const params = {
- ...formData.value,
- websiteList: websiteList.filter(item => item.trim()),
- emailList: emailList.filter(item => item.trim())
- }
- emit('add', params)
- handleClose()
- }
- </script>
- <style scoped>
- .modal-overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0, 0, 0, 0.7);
- display: flex;
- align-items: center;
- justify-content: center;
- z-index: 1000;
- padding: 20px;
- }
- .modal {
- background: var(--bg-card);
- border-radius: 16px;
- width: 100%;
- max-width: 800px;
- max-height: 90vh;
- overflow: hidden;
- display: flex;
- flex-direction: column;
- }
- .modal-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 20px;
- border-bottom: 1px solid var(--border);
- }
- .modal-title {
- display: flex;
- align-items: center;
- gap: 12px;
- font-size: 16px;
- font-weight: 600;
- }
- .modal-close {
- width: 32px;
- height: 32px;
- background: var(--bg-hover);
- border: none;
- border-radius: 8px;
- color: var(--text-secondary);
- cursor: pointer;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .modal-close:hover {
- background: var(--border);
- color: var(--text-primary);
- }
- .modal-body {
- flex: 1;
- overflow-y: auto;
- padding: 20px;
- }
- .modal-footer {
- display: flex;
- justify-content: flex-end;
- gap: 12px;
- padding: 20px;
- border-top: 1px solid var(--border);
- }
- .section-title {
- font-size: 14px;
- font-weight: 600;
- color: var(--text-secondary);
- background: var(--bg-hover);
- padding: 8px 12px;
- border-radius: 4px;
- margin-bottom: 16px;
- }
- /* 行布局:保留两列,统一间距 */
- .form-row {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 16px;
- margin-bottom: 16px;
- align-items: flex-start; /* 关键:多行输入时顶部对齐,避免留白 */
- }
- .form-row .left,.form-row .right{
- display: flex;
- flex-direction: column;
- }
- .form-group {
-
- }
- /* 多行输入专属样式 */
- .multi-input-group {
- gap: 4px; /* 标签与输入组间距缩小 */
- }
- .form-group.full-width {
- grid-column: 1 / -1;
- }
- .form-label {
- font-size: 12px;
- color: var(--text-secondary);
- margin-bottom: 6px;
- }
- .form-input,
- .form-select,
- .form-textarea {
- width: 100%;
- padding: 10px 14px;
- background: var(--bg-dark);
- border: 1px solid var(--border);
- border-radius: 8px;
- color: var(--text-primary);
- font-size: 13px;
- box-sizing: border-box;
- }
- .form-input:focus,
- .form-select:focus,
- .form-textarea:focus {
- outline: none;
- border-color: var(--primary);
- }
- .form-textarea {
- min-height: 80px;
- resize: vertical;
- }
- .required {
- color: var(--danger, #f56c6c);
- }
- /* 单条输入容器,紧凑间距 */
- .input-item {
- margin-bottom: 6px;
- }
- .input-item:last-child {
- margin-bottom: 0;
- }
- .input-with-icon {
- position: relative;
- width: 100%;
- }
- .icon-btn {
- position: absolute;
- right: 12px;
- top: 50%;
- transform: translateY(-50%);
- color: var(--primary);
- cursor: pointer;
- font-size: 16px;
- user-select: none;
- }
- .icon-btn.minus {
- color: var(--danger, #f56c6c);
- }
- .radio-group {
- display: flex;
- gap: 16px;
- align-items: center;
- }
- .radio-item {
- display: flex;
- align-items: center;
- gap: 4px;
- font-size: 13px;
- color: var(--text-secondary);
- cursor: pointer;
- }
- .btn {
- padding: 10px 20px;
- border-radius: 8px;
- border: none;
- cursor: pointer;
- font-size: 13px;
- display: flex;
- align-items: center;
- gap: 6px;
- }
- .btn-secondary {
- background: var(--bg-hover);
- color: var(--text-secondary);
- }
- .btn-primary {
- background: var(--primary);
- color: #fff;
- }
- </style>
|