Commit 528665ef by 李宁

1

1 parent 5abfbfa7
...@@ -141,6 +141,16 @@ export function queryBusiCloseReansonList(data) { ...@@ -141,6 +141,16 @@ export function queryBusiCloseReansonList(data) {
} }
/** /**
* 商机关闭原因:根据区域列表查询
*/
export function queryAreaCloseReansonList(data) {
return request({
url: '/compass/api/common/close-reason/page',
data,
})
}
/**
* 商机关闭原因添加和更新 * 商机关闭原因添加和更新
*/ */
export function busiCloseReasonUpdate(data) { export function busiCloseReasonUpdate(data) {
......
...@@ -29,7 +29,7 @@ const routes = [ ...@@ -29,7 +29,7 @@ const routes = [
component: OpportunityManagement component: OpportunityManagement
}, },
{ {
path: '/opportunities/:id', path: '/opportunitiesDetail',
name: 'OpportunityDetail', name: 'OpportunityDetail',
component: OpportunityDetail component: OpportunityDetail
}, },
......
...@@ -186,6 +186,7 @@ const menuItems = [ ...@@ -186,6 +186,7 @@ const menuItems = [
// 面包屑配置 // 面包屑配置
const breadcrumbMap = { const breadcrumbMap = {
"/opportunities": "商机管理", "/opportunities": "商机管理",
"/opportunitiesDetail": "商机详情",
"/grid-query": "网格查询", "/grid-query": "网格查询",
"/system": "系统管理", "/system": "系统管理",
"/system/personnel": "人员管理", "/system/personnel": "人员管理",
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
<el-col :span="8"> <el-col :span="8">
<div class="info-item"> <div class="info-item">
<span class="info-label">商机ID:</span> <span class="info-label">商机ID:</span>
<span class="info-value">{{ opportunity.id }}</span> <span class="info-value">{{ opportunity.opportunityCode }}</span>
</div> </div>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
...@@ -220,7 +220,7 @@ ...@@ -220,7 +220,7 @@
icon="el-icon-circle-close" icon="el-icon-circle-close"
class="action-btn" class="action-btn"
@click="shutBusi" @click="shutBusi"
:disabled="(opportunity.status==5 || opportunity.status==4) || ifCanOperate" :disabled="opportunity.status==5 || opportunity.status==4 || ifCanOperate"
> >
关闭商机 关闭商机
</el-button> </el-button>
...@@ -422,10 +422,7 @@ export default { ...@@ -422,10 +422,7 @@ export default {
name: 'OpportunityDetail', name: 'OpportunityDetail',
data() { data() {
return { return {
picArr: [ detailId: '',
'https://testznzl.lgyzpt.com/activity/zjbPc/static/img/ad61df2f28f6b51d5f386829473ab1b592fd14e0.47afcfd0.png',
'https://testznzl.lgyzpt.com/activity/zjbPc/static/img/1b66793397a66bf54212d266505eb98e3377a354.fb5fc9cc.png'
],
opportunity: {}, opportunity: {},
followList: [], followList: [],
...@@ -463,20 +460,31 @@ export default { ...@@ -463,20 +460,31 @@ export default {
} }
}, },
created() { created() {
this.detailId = localStorage.getItem('detailId')
this.queryDetail() this.queryDetail()
this.queryFollow() this.queryFollow()
this.queryCloseList() this.queryCloseList()
}, },
methods: { computed:{
ifCanOperate(){ ifCanOperate(){
let ui = JSON.parse(localStorage.getItem('accountInfo')) let ui = JSON.parse(localStorage.getItem('accountInfo'))
return this.opportunity.opportunityType==2&&ui.gridCode if(this.opportunity.opportunityType==2&&ui.gridCode){
return true
}
return false
}
}, },
methods: {
queryCloseList(){ queryCloseList(){
this.apiReq.queryBusiCloseReansonList({ let ui = JSON.parse(localStorage.getItem('accountInfo'))
this.apiReq.queryAreaCloseReansonList({
pageNum: 1, pageNum: 1,
pageSize: 1000 pageSize: 1000,
areaCode: ui.areaCode
}).then(res=>{ }).then(res=>{
if(res.code == 200){ if(res.code == 200){
this.closeBusiStore.reasonsList = res.data.records this.closeBusiStore.reasonsList = res.data.records
...@@ -535,7 +543,7 @@ export default { ...@@ -535,7 +543,7 @@ export default {
}, },
queryFollow(){ queryFollow(){
this.apiReq.queryBusiFollowList({ this.apiReq.queryBusiFollowList({
opportunityId: this.$route.params.id, opportunityId: this.detailId,
pageNum: 1, pageNum: 1,
pageSize: 1000 pageSize: 1000
}).then(res=>{ }).then(res=>{
...@@ -580,7 +588,7 @@ export default { ...@@ -580,7 +588,7 @@ export default {
}, },
queryDetail(){ queryDetail(){
this.apiReq.queryBusiDetail({ this.apiReq.queryBusiDetail({
opportunityId: this.$route.params.id opportunityId: this.detailId
}).then(res=>{ }).then(res=>{
if(res.code == 200){ if(res.code == 200){
if(res.data.voiceDescriptionUrl){ if(res.data.voiceDescriptionUrl){
......
...@@ -848,7 +848,9 @@ export default { ...@@ -848,7 +848,9 @@ export default {
this.currentPage = 1 this.currentPage = 1
}, },
checkDetail(row){ checkDetail(row){
this.$router.push(`/opportunities/${row.id}`) localStorage.setItem('detailId',row.id)
this.$router.push(`/opportunitiesDetail`)
}, },
checkAudio(row){ checkAudio(row){
this.handleOpenAudit(row.id) this.handleOpenAudit(row.id)
......
...@@ -19,7 +19,11 @@ ...@@ -19,7 +19,11 @@
"mcp__figma__get_metadata", "mcp__figma__get_metadata",
"Bash(python3 -m http.server 8080)", "Bash(python3 -m http.server 8080)",
"Bash(open \"http://localhost:8080/zjbPhone/busiDetail.html\")", "Bash(open \"http://localhost:8080/zjbPhone/busiDetail.html\")",
"Bash(open \"http://localhost:8080/myBusi.html\")" "Bash(open \"http://localhost:8080/myBusi.html\")",
"Bash(lsof -ti:8080)",
"Bash(python3 -m http.server 8081)",
"Bash(open \"http://localhost:8081/zjbPhone/busiDetail.html\")",
"Bash(open \"http://localhost:8081/zjbPhone/addBusi.html\")"
], ],
"deny": [], "deny": [],
"ask": [] "ask": []
......
...@@ -162,7 +162,9 @@ ...@@ -162,7 +162,9 @@
<p class="progress-time">{{ switchTime(item.createTime) }}</p> <p class="progress-time">{{ switchTime(item.createTime) }}</p>
<p class="progress-desc">{{ item.followPersonName }}:{{ item.followContent }}</p> <p class="progress-desc">{{ item.followPersonName }}:{{ item.followContent }}</p>
<div class="progress-img" v-if="followImgArr(item.followImages).length > 0"> <div class="progress-img" v-if="followImgArr(item.followImages).length > 0">
<img v-for="iitem in followImgArr(item.followImages)" :src="iitem"> <img v-for="(iitem, imgIndex) in followImgArr(item.followImages)"
:src="iitem"
@click="showImagePreview(followImgArr(item.followImages), imgIndex)">
</div> </div>
</div> </div>
</div> </div>
...@@ -250,18 +252,36 @@ ...@@ -250,18 +252,36 @@
</div> </div>
</div> </div>
<!-- <div class="outAlertBg"> <!-- 图片预览弹窗 -->
<div class="imgAlertCon"> <div class="outAlertBg" v-if="imagePreview.show" @click="closeImagePreview">
<div class="imgAlertCon" @click.stop>
<div class="imgDiv"> <div class="imgDiv">
<img src="https://pic1.arkoo.com/56D0B40F99F841DF8A2425762AE2565D/picture/o_1i4qop009177v1tgf14db15he1iaj1is.jpg" alt=""> <img :src="imagePreview.images[imagePreview.currentIndex]" alt=""
@load="onImageLoad"
@error="onImageError">
</div> </div>
<div class="choButt"> <!-- 图片索引指示器 -->
<div class="prev">prev</div> <div class="imgIndicator" v-if="imagePreview.images.length > 1">
<div class="next">next</div> {{ imagePreview.currentIndex + 1 }} / {{ imagePreview.images.length }}
</div>
<!-- 切换按钮 -->
<div class="choButt" v-if="imagePreview.images.length > 1">
<div class="prev"
:class="{ disabled: imagePreview.currentIndex === 0 }"
@click="prevImage">上一张</div>
<div class="next"
:class="{ disabled: imagePreview.currentIndex === imagePreview.images.length - 1 }"
@click="nextImage">下一张</div>
</div>
<!-- 关闭按钮 -->
<div class="closePreview" @click="closeImagePreview">
<img src="images/close.png" alt="">
</div>
</div> </div>
</div> </div>
</div> -->
</div> </div>
<!-- 引入Vue.js --> <!-- 引入Vue.js -->
......
...@@ -182,32 +182,6 @@ body { ...@@ -182,32 +182,6 @@ body {
} }
/* .imgAlertCon .imgDiv{
width: 6.5rem;
height: 9rem;
margin-bottom: .3rem;
display: flex;
align-items: center;
justify-content: center;
}
.imgAlertCon .imgDiv img{
max-width: 100%;
max-height: 100%;
}
.imgAlertCon .choButt{
width: 100%;
display: flex;
color: #fff;
font-size: .4rem;
justify-content: space-around;
}
.imgAlertCon .choButt div{
background: #0068EE;
padding: .1rem .3rem;
border-radius: .08rem;
} */
/* 通用卡片样式 */ /* 通用卡片样式 */
.business-info-section, .business-info-section,
.business-detail-section, .business-detail-section,
...@@ -545,3 +519,156 @@ body { ...@@ -545,3 +519,156 @@ body {
outline: 0.04rem solid rgba(0, 122, 255, 0.3); outline: 0.04rem solid rgba(0, 122, 255, 0.3);
outline-offset: 0.04rem; outline-offset: 0.04rem;
} }
/* 图片预览弹窗样式 */
.outAlertBg[style*="display: block"],
.outAlertBg:not([style*="none"]) {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.9);
z-index: 99999;
display: flex;
align-items: center;
justify-content: center;
}
.imgAlertCon {
position: relative;
width: 90%;
height: 80%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.imgDiv {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
width: 100%;
}
.imgDiv img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
border-radius: 0.1rem;
}
/* 图片索引指示器 */
.imgIndicator {
position: absolute;
top: 1rem;
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 0.2rem 0.4rem;
border-radius: 0.2rem;
font-size: 0.3rem;
z-index: 10;
}
/* 切换按钮组 */
.choButt {
display: flex;
justify-content: space-between;
width: 80%;
margin-top: 1rem;
gap: 1rem;
}
.choButt .prev,
.choButt .next {
flex: 1;
padding: 0.3rem 0.6rem;
background: rgba(255, 255, 255, 0.2);
color: white;
border-radius: 0.3rem;
text-align: center;
cursor: pointer;
font-size: 0.3rem;
transition: all 0.3s ease;
border: 0.02rem solid rgba(255, 255, 255, 0.3);
}
.choButt .prev:hover,
.choButt .next:hover {
background: rgba(255, 255, 255, 0.3);
}
.choButt .prev.disabled,
.choButt .next.disabled {
opacity: 0.3;
cursor: not-allowed;
}
.choButt .prev.disabled:hover,
.choButt .next.disabled:hover {
background: rgba(255, 255, 255, 0.2);
}
/* 关闭按钮 */
.closePreview {
position: absolute;
top: 1rem;
right: 1rem;
width: 0.8rem;
height: 0.8rem;
background: rgba(0, 0, 0, 0.5);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 10;
}
.closePreview img {
width: 0.4rem;
height: 0.4rem;
object-fit: contain;
}
/* 跟进图片样式 */
.progress-img {
display: flex;
flex-wrap: wrap;
gap: 0.2rem;
margin-top: 0.2rem;
}
.progress-img img {
width: 1.5rem;
height: 1.5rem;
object-fit: cover;
border-radius: 0.1rem;
cursor: pointer;
transition: transform 0.2s ease;
}
.progress-img img:hover {
transform: scale(1.05);
}
.progress-img img:active {
transform: scale(0.95);
}
/* 动画效果 */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.imgAlertCon {
animation: fadeIn 0.3s ease-out;
}
\ No newline at end of file \ No newline at end of file
...@@ -56,6 +56,10 @@ new Vue({ ...@@ -56,6 +56,10 @@ new Vue({
mounted() { mounted() {
this.isAlone = utils.getUrlParam('source')!='zhijian' this.isAlone = utils.getUrlParam('source')!='zhijian'
// 获取用户信息并反写地址
this.getUserInfoAndInitAddress();
if(!this.isAlone){ if(!this.isAlone){
this.initData() this.initData()
this.queryHaZjLabel() this.queryHaZjLabel()
...@@ -73,6 +77,61 @@ new Vue({ ...@@ -73,6 +77,61 @@ new Vue({
}, },
methods: { methods: {
/**
* 获取用户信息并初始化地址
*/
getUserInfoAndInitAddress() {
// 从localStorage获取用户信息
const userInfoStr = localStorage.getItem('userInfo');
if (userInfoStr) {
this.userInfo = JSON.parse(userInfoStr);
// 如果有区域代码,则进行地址反写
if (this.userInfo.areaCode) {
this.initAddressByAreaCode(this.userInfo.areaCode);
}
}
},
/**
* 根据区域代码初始化地址选择
*/
initAddressByAreaCode(areaCode) {
const province = this.addressData.provinces[0]; // 江苏省
// 搜索所有城市和区县
for (let i = 0; i < province.cities.length; i++) {
const city = province.cities[i];
// 搜索该城市的所有区县
for (let j = 0; j < city.districts.length; j++) {
const district = city.districts[j];
// 如果找到匹配的区县代码
if (district.code === areaCode) {
// 设置选中的省市区
this.addressSelector.selectedProvince = province;
this.addressSelector.selectedCity = city;
this.addressSelector.selectedDistrict = district;
this.addressSelector.selectedStreet = null;
// 更新显示的地址文本
this.selectedAddressText = `${province.name} ${city.name} ${district.name}`;
this.selectedAddressCode = areaCode;
// 设置地址选择器当前步骤为街道选择(步骤3)
this.addressSelector.currentStep = 3;
console.log(`地址反写成功: ${this.selectedAddressText}`);
return;
}
}
}
// 如果没有找到对应的区县代码
console.log(`未找到区域代码 ${areaCode} 对应的地址信息`);
},
goZj(){ goZj(){
location.href = 'result.html' location.href = 'result.html'
}, },
...@@ -771,7 +830,14 @@ new Vue({ ...@@ -771,7 +830,14 @@ new Vue({
*/ */
openAddressSelector() { openAddressSelector() {
this.addressSelector.show = true; this.addressSelector.show = true;
// 如果已经反写了地址(已选择省市区),直接跳到街道选择
if (this.addressSelector.selectedDistrict) {
this.addressSelector.currentStep = 3;
} else {
// 否则从省开始选择
this.addressSelector.currentStep = 0; this.addressSelector.currentStep = 0;
}
}, },
/** /**
......
...@@ -56,7 +56,14 @@ new Vue({ ...@@ -56,7 +56,14 @@ new Vue({
}, },
timeWriteStr: '', timeWriteStr: '',
nIndex: '--' nIndex: '--',
// 图片预览相关数据
imagePreview: {
show: false,
images: [],
currentIndex: 0
}
}, },
created() { created() {
...@@ -605,6 +612,62 @@ new Vue({ ...@@ -605,6 +612,62 @@ new Vue({
}, },
/** /**
* 显示图片预览
*/
showImagePreview(images, index = 0) {
this.imagePreview.images = images;
this.imagePreview.currentIndex = index;
this.imagePreview.show = true;
// 禁止背景滚动
document.body.style.overflow = 'hidden';
},
/**
* 关闭图片预览
*/
closeImagePreview() {
this.imagePreview.show = false;
this.imagePreview.images = [];
this.imagePreview.currentIndex = 0;
// 恢复背景滚动
document.body.style.overflow = 'auto';
},
/**
* 上一张图片
*/
prevImage() {
if (this.imagePreview.currentIndex > 0) {
this.imagePreview.currentIndex--;
}
},
/**
* 下一张图片
*/
nextImage() {
if (this.imagePreview.currentIndex < this.imagePreview.images.length - 1) {
this.imagePreview.currentIndex++;
}
},
/**
* 图片加载完成
*/
onImageLoad() {
console.log('图片加载完成');
},
/**
* 图片加载错误
*/
onImageError() {
utils.toast('图片加载失败');
},
/**
* 清理资源 * 清理资源
*/ */
cleanup() { cleanup() {
...@@ -618,6 +681,9 @@ new Vue({ ...@@ -618,6 +681,9 @@ new Vue({
clearTimeout(this.cleanupTimer); clearTimeout(this.cleanupTimer);
this.cleanupTimer = null; this.cleanupTimer = null;
} }
// 关闭图片预览
this.closeImagePreview();
} }
}, },
...@@ -663,6 +729,21 @@ new Vue({ ...@@ -663,6 +729,21 @@ new Vue({
// 监听器 // 监听器
watch: { watch: {
// 监听ESC键关闭图片预览
'imagePreview.show'(newVal) {
if (newVal) {
const handleKeyDown = (e) => {
if (e.key === 'Escape') {
this.closeImagePreview();
document.removeEventListener('keydown', handleKeyDown);
} else if (e.key === 'ArrowLeft') {
this.prevImage();
} else if (e.key === 'ArrowRight') {
this.nextImage();
}
};
document.addEventListener('keydown', handleKeyDown);
}
}
} }
}); });
\ No newline at end of file \ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!