This commit is contained in:
Vinjor 2025-11-24 11:31:11 +08:00
parent 447e1e93b7
commit 6fe48fa281
11 changed files with 188 additions and 29 deletions

View File

@ -59,8 +59,7 @@ public class CusManagerController extends BaseController
@PreAuthorize("@ss.hasPermi('cus:manager:export')")
@Log(title = "客户管理信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, CusManager cusManager)
{
public void export(HttpServletResponse response, CusManager cusManager) {
List<CusManager> list = cusManagerService.list();
ExcelUtil<CusManager> util = new ExcelUtil<CusManager>(CusManager.class);
util.exportExcel(response, list, "客户管理信息数据");
@ -88,14 +87,13 @@ public class CusManagerController extends BaseController
}
/**
* 修改客户管理信息
* 更新客户管理人员信息
*/
@PreAuthorize("@ss.hasPermi('cus:manager:edit')")
@Log(title = "客户管理信息", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody CusManager cusManager)
{
return toAjax(cusManagerService.updateById(cusManager));
@PutMapping("/updateUser")
public AjaxResult updateUser(@RequestBody CusManager cusManager) {
cusManagerService.updateByCusId(cusManager);
return success();
}
/**
@ -104,8 +102,7 @@ public class CusManagerController extends BaseController
@PreAuthorize("@ss.hasPermi('cus:manager:remove')")
@Log(title = "客户管理信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids)
{
public AjaxResult remove(@PathVariable String[] ids) {
List<String> list = new ArrayList<>(Arrays.asList(ids));
return toAjax(cusManagerService.removeByIds(list));
}

View File

@ -30,6 +30,7 @@ public class CusContacts extends DlBaseEntity
/** 主键(使用雪花算法生成唯一主键) */
@TableId
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Long id;
/** 客户ID */

View File

@ -18,4 +18,12 @@ import org.apache.ibatis.annotations.Mapper;
public interface CusManagerMapper extends BaseMapper<CusManager>
{
IPage<CusManager> queryListPage(@Param("entity") CusManager entity, Page<CusManager> page);
/**
* 更新客户管理信息
* @author vinjor-M
* @date 10:14 2025/11/24
* @return int
**/
int updateByCusId(@Param("entity") CusManager entity);
}

View File

@ -25,4 +25,11 @@ public interface ICusManagerService extends IService<CusManager> {
* @date 15:15 2025/11/20
**/
void saveOrUpdateByCusName(List<CusManager> cusManagerList);
/**
* 根据客户id修改客户管理信息
* @author vinjor-M
* @date 10:13 2025/11/24
**/
void updateByCusId(CusManager cusManager);
}

View File

@ -96,6 +96,16 @@ public class CusManagerServiceImpl extends ServiceImpl<CusManagerMapper, CusMana
}
}
/**
* 根据客户id修改客户管理信息
*
* @param cusManager
* @author vinjor-M
* @date 10:13 2025/11/24
*/
@Override
public void updateByCusId(CusManager cusManager) {
cusManagerMapper.updateByCusId(cusManager);
}
}

View File

@ -23,7 +23,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<sql id="selectCusManagerVo">
select id, cus_id, user_id,user_name, follow_step, seas_reason, seas_group, old_dept, del_flag, creator, create_time, updater, update_time from cus_manager
</sql>
<select id="queryListPage" parameterType="CusManager" resultMap="CusManagerResult">
<include refid="selectCusManagerVo"/>
<where>
@ -37,4 +36,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="entity.updateTime != null "> and update_time = #{entity.updateTime}</if>
</where>
</select>
<update id="updateByCusId">
update cus_manager set user_id = #{entity.userId},
user_name = #{entity.userName}
where del_flag='0' and cus_id = #{entity.cusId}
</update>
</mapper>

View File

@ -26,10 +26,10 @@ export function addManager(data) {
})
}
// 修改客户管理信息
export function updateManager(data) {
// 更新客户管理人员信息
export function updateUser(data) {
return request({
url: '/cus/manager',
url: '/cus/manager/updateUser',
method: 'put',
data: data
})

View File

@ -37,6 +37,8 @@ import DictTag from '@/components/DictTag'
import VueMeta from 'vue-meta'
// 字典数据组件
import DictData from '@/components/DictData'
// 引入我们刚刚创建的剪贴板工具
import '@/utils/clipboard'
// 全局方法挂载
Vue.prototype.getDicts = getDicts

View File

@ -0,0 +1,25 @@
// src/utils/clipboard.js
import Vue from 'vue'
import { Message } from 'element-ui'
function copyTextToClipboard(text) {
if (!navigator.clipboard) {
Message.error('浏览器不支持剪贴板API请手动复制');
return Promise.reject();
}
if (typeof text !== 'string' || !text.trim()) {
Message.warning('请提供有效文本');
return Promise.reject();
}
return navigator.clipboard.writeText(text.trim())
.then(() => Message.success('复制成功'))
.catch(err => {
Message.error(`复制失败:${err.message}`);
return Promise.reject(err);
});
}
// 关键挂载到Vue原型必须有这行
Vue.prototype.$copyText = copyTextToClipboard;
export default copyTextToClipboard;

View File

@ -96,7 +96,7 @@
<el-table-column label="星标" align="center" prop="ifStar">
<template slot-scope="scope">
<i v-if="scope.row.ifStar" title="取消星标" class="el-icon-star-on"
style="color: #E6A23C;font-size: 18px;cursor: pointer"
style="color: #ffba00;font-size: 18px;cursor: pointer"
@click="setIfStar(scope.row,false)"></i>
<i v-else class="el-icon-star-off" title="星标" style="cursor: pointer" @click="setIfStar(scope.row,true)"></i>
</template>
@ -279,19 +279,23 @@
<follow-form ref="followForm"/>
<!-- 给客户设置标签-->
<label-form ref="labelForm" @ok="getList"/>
<!-- 转移客户-->
<select-all-user :multiple="false" ref="selectAllUser" @ok="chooseUserFun"/>
</div>
</template>
<script>
import { listMain, getMain, delMain, addMain, updateMain ,setIfStar} from '@/api/cus/main'
import { updateUser} from '@/api/cus/manager'
import DrawForm from './drawForm'
import { getToken } from '@/utils/auth'
import FollowForm from '../follow/followForm'
import LabelForm from './labelForm'
import SelectAllUser from '../../system/user/selectAllUser'
export default {
name: 'Main',
components: { LabelForm, DrawForm, FollowForm },
components: { SelectAllUser, LabelForm, DrawForm, FollowForm },
dicts: ['cus_main_product', 'cus_label', 'cus_type', 'sys_user_sex', 'cus_from', 'cus_level', 'cus_busi_type', 'cus_follow_step'],
data() {
return {
@ -434,6 +438,8 @@ export default {
break
case 'changeUser':
//
this.cusMain = dataObj.row
this.$refs.selectAllUser.show();
break
case 'goSea':
//
@ -500,6 +506,26 @@ export default {
this.$message.error(resp.msg)
}
})
},
/**
* 选择移交客户
* @param userList
*/
chooseUserFun(userList){
let dataObj = {
cusId: this.cusMain.id,
userId: userList[0].userId,
userName: userList[0].nickName
}
updateUser(dataObj).then((resp) => {
if(resp.code==200){
this.$message.success("操作成功");
this.handleQuery()
}else{
this.$message.error(resp.msg)
}
})
}
}
}

View File

@ -17,7 +17,7 @@
<!--第一行-->
<div class="customer-header-row">
<span class="customer-fullname" :title="mainInfo.cusMain.fullName">{{mainInfo.cusMain.fullName}}</span>
<i class="el-icon-copy-document dl-canclick" title="复制"></i>
<i class="el-icon-copy-document dl-canclick" title="复制" @click="$copyText(mainInfo.cusMain.fullName)"></i>
<el-divider direction="vertical"></el-divider>
<div class="country-container">
<img v-if="mainInfo.countryImg != null" :src="getImg(mainInfo.countryImg)" style="width: 30px; height: 20px;"/>
@ -33,7 +33,7 @@
<div><span class="gray-text">No.</span>
<span title="客户编号" class="dark-text">{{mainInfo.cusMain.cusCode}}</span>
</div>
<i class="el-icon-copy-document dl-canclick" title="复制"></i>
<i class="el-icon-copy-document dl-canclick" title="复制" @click="$copyText(mainInfo.cusMain.cusCode)"></i>
</div>
</div>
<!-- 第二行-标签 -->
@ -98,6 +98,7 @@
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="goSea">转入公海</el-dropdown-item>
<el-dropdown-item command="move">移交客户</el-dropdown-item>
<el-dropdown-item command="del">删除</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
@ -164,7 +165,7 @@
</div>
<div class="contact-right">
<div class="contact-name item-title">{{item.name}}</div>
<i class="el-icon-copy-document icon-color"/>
<i class="el-icon-copy-document icon-color" @click="$copyText(item.name)"/>
</div>
<!-- 操作按钮-->
<div class="contact-opt">
@ -179,7 +180,7 @@
</div>
<div class="contact-right">
<div class="contact-name">{{item.email || "-"}}</div>
<i v-if="item.email" class="el-icon-copy-document icon-color"/>
<i v-if="item.email" class="el-icon-copy-document icon-color" @click="$copyText(item.email)"/>
</div>
</div>
<div class="contact-row">
@ -188,7 +189,7 @@
</div>
<div class="contact-right">
<div class="contact-name">{{item.telephone || "-"}}</div>
<i v-if="item.telephone" class="el-icon-copy-document icon-color"/>
<i v-if="item.telephone" class="el-icon-copy-document icon-color" @click="$copyText(item.telephone)"/>
</div>
</div>
<div class="contact-row">
@ -197,7 +198,7 @@
</div>
<div class="contact-right">
<div class="contact-name">{{item.whatsApp || "-"}}</div>
<i v-if="item.whatsApp" class="el-icon-copy-document icon-color"/>
<i v-if="item.whatsApp" class="el-icon-copy-document icon-color" @click="$copyText(item.whatsApp)"/>
</div>
</div>
</div>
@ -212,10 +213,13 @@
<edit-form @ok="getMainInfo" ref="contactForm" />
<!-- 给客户打标签-->
<label-form ref="labelForm" @ok="getMainInfo"/>
<!-- 选择用户组件-->
<select-all-user :multiple="false" ref="selectAllUser" @ok="chooseUserFun" />
</div>
</template>
<script>
import { updateUser} from '@/api/cus/manager'
import { delMain} from "@/api/cus/main";
import { delContacts } from "@/api/cus/contacts";
import TimeLine from '../axis/timeLine'
@ -228,11 +232,12 @@ import {viewData} from "@/api/cus/main"
import FollowForm from '../follow/followForm'
import EditForm from '../contacts/editForm'
import LabelForm from './labelForm'
import SelectAllUser from '../../system/user/selectAllUser'
export default {
name: 'HighFidelityCustomerDetail',
components: { LabelForm, EditForm, FollowForm, WhatsApp, FollowList, EmailList, BankList, CompanyInfo, TimeLine },
components: { SelectAllUser, LabelForm, EditForm, FollowForm, WhatsApp, FollowList, EmailList, BankList, CompanyInfo, TimeLine },
data() {
return {
id:"",
@ -249,6 +254,11 @@ export default {
filterList:[],
}
},
watch: {
activeTab(newVal) {
this.reloadTabContent(newVal);
}
},
created() {
if(this.$route.query.id){
this.id = this.$route.query.id;
@ -256,6 +266,45 @@ export default {
}
},
methods: {
/**
* 根据 tab 名称重新加载对应内容
*/
reloadTabContent(tabName) {
this.$nextTick(() => {
switch (tabName) {
case 'timeline':
if (this.$refs.timeLine && typeof this.$refs.timeLine.handleQuery == 'function') {
this.$refs.timeLine.handleQuery();
}
break;
case 'info':
if (this.$refs.companyInfo && typeof this.$refs.companyInfo.handleQuery == 'function') {
this.$refs.companyInfo.handleQuery();
}
break;
case 'bank':
if (this.$refs.bankList && typeof this.$refs.bankList.getList == 'function') {
this.$refs.bankList.getList();
}
break;
case 'email':
if (this.$refs.emailList && typeof this.$refs.emailList.getList == 'function') {
this.$refs.emailList.getList();
}
break;
case 'follow':
if (this.$refs.followList && typeof this.$refs.followList.getList == 'function') {
this.$refs.followList.getList();
}
break;
case 'whatsapp':
if (this.$refs.whatsApp && typeof this.$refs.whatsApp.getList == 'function') {
this.$refs.whatsApp.getList();
}
break;
}
});
},
/**
* 设置客户标签
*/
@ -332,6 +381,9 @@ export default {
case 'del':
this.handleDelete()
break
case 'move':
this.$refs.selectAllUser.show();
break
}
},
/** 删除按钮操作 */
@ -342,14 +394,20 @@ export default {
}).then(() => {
this.$modal.msgSuccess("删除成功");
setTimeout(()=>{
//
this.$router.back();
//
const obj = { path: "/cus/viewForm" ,name:"ViewForm"};
this.$tab.closePage(obj);
this.closeAndBack()
},500)
}).catch(() => {});
},
/**
* 关闭本页面并返回上一页
*/
closeAndBack(){
//
this.$router.back();
//
const obj = { path: "/cus/viewForm" ,name:"ViewForm"};
this.$tab.closePage(obj);
},
/**
* 删除联系人
*/
@ -373,6 +431,26 @@ export default {
*/
newContanct(){
this.$refs.contactForm.handleAdd(this.id)
},
/**
* 选择移交客户
* @param userList
*/
chooseUserFun(userList){
let dataObj = {
cusId: this.id,
userId: userList[0].userId,
userName: userList[0].nickName
}
updateUser(dataObj).then((resp) => {
if(resp.code==200){
this.$message.success("操作成功");
this.$refs.companyInfo.handleQuery();
}else{
this.$message.error(resp.msg)
}
})
}
},
}