Commit 528665ef by 李宁

1

1 parent 5abfbfa7
......@@ -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) {
......
......@@ -29,7 +29,7 @@ const routes = [
component: OpportunityManagement
},
{
path: '/opportunities/:id',
path: '/opportunitiesDetail',
name: 'OpportunityDetail',
component: OpportunityDetail
},
......
......@@ -186,6 +186,7 @@ const menuItems = [
// 面包屑配置
const breadcrumbMap = {
"/opportunities": "商机管理",
"/opportunitiesDetail": "商机详情",
"/grid-query": "网格查询",
"/system": "系统管理",
"/system/personnel": "人员管理",
......
......@@ -17,7 +17,7 @@
<el-col :span="8">
<div class="info-item">
<span class="info-label">商机ID:</span>
<span class="info-value">{{ opportunity.id }}</span>
<span class="info-value">{{ opportunity.opportunityCode }}</span>
</div>
</el-col>
<el-col :span="8">
......@@ -220,7 +220,7 @@
icon="el-icon-circle-close"
class="action-btn"
@click="shutBusi"
:disabled="(opportunity.status==5 || opportunity.status==4) || ifCanOperate"
:disabled="opportunity.status==5 || opportunity.status==4 || ifCanOperate"
>
关闭商机
</el-button>
......@@ -422,10 +422,7 @@ export default {
name: 'OpportunityDetail',
data() {
return {
picArr: [
'https://testznzl.lgyzpt.com/activity/zjbPc/static/img/ad61df2f28f6b51d5f386829473ab1b592fd14e0.47afcfd0.png',
'https://testznzl.lgyzpt.com/activity/zjbPc/static/img/1b66793397a66bf54212d266505eb98e3377a354.fb5fc9cc.png'
],
detailId: '',
opportunity: {},
followList: [],
......@@ -463,20 +460,31 @@ export default {
}
},
created() {
this.detailId = localStorage.getItem('detailId')
this.queryDetail()
this.queryFollow()
this.queryCloseList()
},
methods: {
computed:{
ifCanOperate(){
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(){
this.apiReq.queryBusiCloseReansonList({
let ui = JSON.parse(localStorage.getItem('accountInfo'))
this.apiReq.queryAreaCloseReansonList({
pageNum: 1,
pageSize: 1000
pageSize: 1000,
areaCode: ui.areaCode
}).then(res=>{
if(res.code == 200){
this.closeBusiStore.reasonsList = res.data.records
......@@ -535,7 +543,7 @@ export default {
},
queryFollow(){
this.apiReq.queryBusiFollowList({
opportunityId: this.$route.params.id,
opportunityId: this.detailId,
pageNum: 1,
pageSize: 1000
}).then(res=>{
......@@ -580,7 +588,7 @@ export default {
},
queryDetail(){
this.apiReq.queryBusiDetail({
opportunityId: this.$route.params.id
opportunityId: this.detailId
}).then(res=>{
if(res.code == 200){
if(res.data.voiceDescriptionUrl){
......
......@@ -848,7 +848,9 @@ export default {
this.currentPage = 1
},
checkDetail(row){
this.$router.push(`/opportunities/${row.id}`)
localStorage.setItem('detailId',row.id)
this.$router.push(`/opportunitiesDetail`)
},
checkAudio(row){
this.handleOpenAudit(row.id)
......
......@@ -19,7 +19,11 @@
"mcp__figma__get_metadata",
"Bash(python3 -m http.server 8080)",
"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": [],
"ask": []
......
......@@ -162,7 +162,9 @@
<p class="progress-time">{{ switchTime(item.createTime) }}</p>
<p class="progress-desc">{{ item.followPersonName }}:{{ item.followContent }}</p>
<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>
......@@ -250,18 +252,36 @@
</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">
<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 class="choButt">
<div class="prev">prev</div>
<div class="next">next</div>
<!-- 图片索引指示器 -->
<div class="imgIndicator" v-if="imagePreview.images.length > 1">
{{ 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>
<!-- 引入Vue.js -->
......
......@@ -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-detail-section,
......@@ -544,4 +518,157 @@ body {
.back-icon:focus {
outline: 0.04rem solid rgba(0, 122, 255, 0.3);
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
......@@ -56,6 +56,10 @@ new Vue({
mounted() {
this.isAlone = utils.getUrlParam('source')!='zhijian'
// 获取用户信息并反写地址
this.getUserInfoAndInitAddress();
if(!this.isAlone){
this.initData()
this.queryHaZjLabel()
......@@ -73,6 +77,61 @@ new Vue({
},
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(){
location.href = 'result.html'
},
......@@ -771,7 +830,14 @@ new Vue({
*/
openAddressSelector() {
this.addressSelector.show = true;
this.addressSelector.currentStep = 0;
// 如果已经反写了地址(已选择省市区),直接跳到街道选择
if (this.addressSelector.selectedDistrict) {
this.addressSelector.currentStep = 3;
} else {
// 否则从省开始选择
this.addressSelector.currentStep = 0;
}
},
/**
......
......@@ -56,7 +56,14 @@ new Vue({
},
timeWriteStr: '',
nIndex: '--'
nIndex: '--',
// 图片预览相关数据
imagePreview: {
show: false,
images: [],
currentIndex: 0
}
},
created() {
......@@ -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() {
......@@ -618,6 +681,9 @@ new Vue({
clearTimeout(this.cleanupTimer);
this.cleanupTimer = null;
}
// 关闭图片预览
this.closeImagePreview();
}
},
......@@ -663,6 +729,21 @@ new Vue({
// 监听器
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
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!