Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation
This project
Loading...
Sign in
李宁
/
Activity
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit c352d425
authored
Nov 13, 2025
by
李宁
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
1
1 parent
f9320e1d
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
427 additions
and
176 deletions
zhiJianBusi/zjbPc/src/assets/js/api/interface/account/index.js
zhiJianBusi/zjbPc/src/assets/js/api/interface/person/index.js
zhiJianBusi/zjbPc/src/components/system/AccountManagement.vue
zhiJianBusi/zjbPc/src/components/system/PersonnelManagement.vue
zhiJianBusi/zjbPc/src/views/LoginPage.vue
zhiJianBusi/zjbPc/src/views/OpportunityDetail.vue
zhiJianBusi/zjbPc/src/views/OpportunityManagement.vue
zhiJianBusi/zjbPc/vue.config.js
zhiJianBusi/zjbPhone/busiDetail.html
zhiJianBusi/zjbPhone/css/busiDetail.css
zhiJianBusi/zjbPhone/js/busiDetail.js
zhiJianBusi/zjbPhone/js/login.js
zhiJianBusi/zjbPhone/myBusi.html
zhiJianBusi/zjbPc/src/assets/js/api/interface/account/index.js
View file @
c352d42
...
...
@@ -35,7 +35,7 @@ export function deleteRole(data) {
*/
export
function
addAndUpdateRole
(
data
)
{
return
request
({
url
:
'/compass/api/system/account
/create'
+
(
data
.
id
?
'/update'
:
'
'
),
url
:
'/compass/api/system/account
'
+
(
data
.
id
?
'/update'
:
'/create
'
),
data
,
})
}
\ No newline at end of file
zhiJianBusi/zjbPc/src/assets/js/api/interface/person/index.js
View file @
c352d42
...
...
@@ -13,8 +13,13 @@ export function queryAllPerson(data) {
* 添加人员
*/
export
function
addNewPerson
(
data
)
{
let
url
=
'/compass/api/personnel/create'
if
(
data
.
id
){
url
=
'/compass/api/personnel/update'
}
return
request
({
url
:
'/compass/api/personnel/create'
,
url
:
url
,
data
,
})
}
...
...
zhiJianBusi/zjbPc/src/components/system/AccountManagement.vue
View file @
c352d42
...
...
@@ -30,7 +30,6 @@
type=
"text"
size=
"small"
@
click=
"editAccount(scope.row)"
disabled
>
编辑
</el-button>
...
...
@@ -80,7 +79,7 @@
<el-form-item
label=
"密码"
prop=
"password"
>
<el-input
v-model=
"accountForm.password"
placeholder=
"请输入密码
"
:placeholder=
"editingAccount?'******':'请输入密码'
"
></el-input>
</el-form-item>
</el-col>
...
...
@@ -213,7 +212,6 @@ export default {
accountName
:
''
,
roleCode
:
''
,
status
:
''
,
grid
:
''
,
contactPhone
:
''
,
email
:
''
,
...
...
@@ -235,7 +233,7 @@ export default {
{
required
:
true
,
message
:
'请输入用户名'
,
trigger
:
'blur'
}
],
password
:
[
{
required
:
true
,
message
:
'请输入密码'
,
trigger
:
'blur'
}
{
validator
:
this
.
validatePassword
,
message
:
'请输入密码'
,
trigger
:
'blur'
}
],
accountName
:
[
{
required
:
true
,
message
:
'请输入姓名'
,
trigger
:
'blur'
}
...
...
@@ -266,6 +264,13 @@ export default {
this
.
queryRole
()
},
methods
:
{
validatePassword
(
rule
,
value
,
callback
)
{
if
(
!
this
.
editingAccount
&&
!
value
)
{
callback
(
new
Error
(
'请输入密码'
))
}
else
{
callback
()
}
},
ifRoleCho
(
key
){
let
gd
=
this
.
getData
...
...
@@ -390,17 +395,14 @@ export default {
},
addAccount
(){
let
ad
=
this
.
accountForm
this
.
editingAccount
=
null
ad
=
{
account
:
''
,
password
:
''
,
accountName
:
''
,
roleCode
:
''
,
status
:
''
,
contactPhone
:
''
,
email
:
''
}
ad
.
account
=
''
ad
.
accountName
=
''
ad
.
roleCode
=
''
ad
.
status
=
''
ad
.
contactPhone
=
''
ad
.
email
=
''
ad
.
password
=
''
if
(
!
this
.
getData
.
city
){
ad
.
city
=
''
ad
.
county
=
''
...
...
@@ -416,12 +418,36 @@ export default {
}
this
.
isAddDialogOpen
=
true
this
.
$refs
.
accountForm
.
clearValidate
()
},
editAccount
(
account
)
{
debugger
this
.
editingAccount
=
account
this
.
accountForm
=
{
...
account
}
editAccount
(
row
)
{
this
.
editingAccount
=
row
let
ad
=
this
.
accountForm
ad
.
account
=
row
.
account
ad
.
accountName
=
row
.
accountName
ad
.
roleCode
=
row
.
roleCode
ad
.
status
=
row
.
status
+
''
ad
.
contactPhone
=
row
.
contactPhone
ad
.
email
=
row
.
email
ad
.
password
=
row
.
password
if
(
row
.
cityCode
){
ad
.
city
=
row
.
cityCode
this
.
cityChange
(
ad
.
city
)
if
(
row
.
countyCode
){
ad
.
county
=
row
.
countyCode
this
.
countyChange
(
ad
.
county
)
if
(
row
.
gridCode
){
ad
.
grid
=
row
.
gridCode
}
}
}
this
.
isAddDialogOpen
=
true
this
.
$refs
.
accountForm
.
clearValidate
()
},
deleteAccount
(
id
)
{
this
.
$confirm
(
'确定要删除该账号吗?此操作不可撤销。'
,
'确认删除'
,
{
...
...
@@ -476,7 +502,7 @@ export default {
}).
then
(
res
=>
{
if
(
res
.
code
==
'200'
){
let
__this
=
this
this
.
$alert
(
'添加成功'
,
'温馨提示'
,
{
this
.
$alert
(
this
.
editingAccount
?
'编辑成功'
:
'添加成功'
,
'温馨提示'
,
{
confirmButtonText
:
'确定'
,
callback
:
()
=>
{
__this
.
handleFilter
()
...
...
zhiJianBusi/zjbPc/src/components/system/PersonnelManagement.vue
View file @
c352d42
...
...
@@ -96,7 +96,7 @@
<el-table-column
prop=
"phone"
label=
"手机号"
width=
"150"
></el-table-column>
<el-table-column
prop=
"personnelTypeName"
label=
"人员类型"
width=
"120"
></el-table-column>
<el-table-column
prop=
"areaName"
label=
"所属区域"
width=
"150"
></el-table-column>
<el-table-column
prop=
"grid
Name
"
label=
"网格"
width=
"220"
></el-table-column>
<el-table-column
prop=
"grid
List"
:formatter=
"gridRender
"
label=
"网格"
width=
"220"
></el-table-column>
<el-table-column
prop=
"relatedMarketingCode"
label=
"关联支撑人员"
width=
"120"
></el-table-column>
<el-table-column
label=
"状态"
width=
"80"
>
<
template
slot-scope=
"scope"
>
...
...
@@ -111,7 +111,6 @@
<el-button
type=
"text"
size=
"small"
disabled
@
click=
"updatePerson(scope.row)"
>
编辑
...
...
@@ -174,7 +173,7 @@
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"人员类型"
prop=
"personnelType"
>
<el-select
v-model=
"updatePersonStore.personnelType"
@
change=
"personnelTypeChange"
style=
"width: 100%;"
>
<el-select
v-model=
"updatePersonStore.personnelType"
:disabled=
"!!updatePersonStore.row.id"
@
change=
"personnelTypeChange"
style=
"width: 100%;"
>
<el-option
label=
"装维师傅"
value=
"1"
></el-option>
<el-option
label=
"支撑人员"
value=
"2"
></el-option>
</el-select>
...
...
@@ -183,31 +182,6 @@
</el-row>
<el-row
:gutter=
"20"
>
<!-- 当选择装维师傅时显示关联支撑人员字段 -->
<el-col
:span=
"12"
>
<el-form-item
label=
"状态"
prop=
"status"
>
<el-select
v-model=
"updatePersonStore.status"
style=
"width: 100%;"
>
<el-option
label=
"启用"
value=
"1"
></el-option>
<el-option
label=
"关闭"
value=
"0"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col
:span=
"12"
v-if=
"updatePersonStore.personnelType == '1'"
>
<el-form-item
label=
"关联支撑人"
prop=
"relatedMarketingCode"
>
<el-select
v-model=
"updatePersonStore.relatedMarketingCode"
placeholder=
"请选择支撑人员"
style=
"width: 100%;"
>
<el-option
v-for=
"item in yxPersonList"
:key=
"item.personnelCode"
:label=
"item.personnelName"
:value=
"item.personnelCode"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row
:gutter=
"20"
>
<el-col
:span=
"30"
>
<el-form-item
label=
"所属区域"
prop=
"grid"
>
<
template
v-if=
"updatePersonStore.cityArr.length>0"
>
...
...
@@ -247,6 +221,8 @@
v-model=
"updatePersonStore.grid"
placeholder=
"选择网格"
:disabled=
"getData.grid!=''"
:multiple=
"gridIsMultiple"
@
change=
"gridChange"
clearable
>
<el-option
v-for=
"item in updatePersonStore.gridArr"
...
...
@@ -259,6 +235,31 @@
</el-form-item>
</el-col>
</el-row>
<el-row
:gutter=
"20"
>
<!-- 当选择装维师傅时显示关联支撑人员字段 -->
<el-col
:span=
"12"
>
<el-form-item
label=
"状态"
prop=
"status"
>
<el-select
v-model=
"updatePersonStore.status"
style=
"width: 100%;"
>
<el-option
label=
"启用"
value=
"1"
></el-option>
<el-option
label=
"关闭"
value=
"0"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col
:span=
"12"
v-if=
"updatePersonStore.personnelType=='1' && updatePersonStore.grid"
>
<el-form-item
label=
"关联支撑人"
prop=
"relatedMarketingCode"
>
<el-select
v-model=
"updatePersonStore.relatedMarketingCode"
placeholder=
"请选择支撑人员"
style=
"width: 100%;"
>
<el-option
v-for=
"item in yxPersonList"
:key=
"item.personnelCode"
:label=
"item.personnelName"
:value=
"item.personnelCode"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
...
...
@@ -347,12 +348,13 @@ export default {
cityArr
:
[],
county
:
''
,
countyArr
:
[],
grid
:
''
,
grid
:
[]
,
gridArr
:
[],
},
yxPersonList
:[],
formData
:{
personnelCode
:
''
,
phone
:
''
,
personnelTypes
:
[]
},
tableData
:
[],
...
...
@@ -400,6 +402,7 @@ export default {
isImportDialogOpen
:
false
,
selectedFile
:
null
,
gridIsMultiple
:
false
}
},
created
(){
...
...
@@ -410,9 +413,38 @@ export default {
this
.
queryArea
()
this
.
handleFilter
()
this
.
queryYxPerson
()
},
methods
:
{
personnelTypeChange
(
value
){
// 重置关联支撑人员
this
.
updatePersonStore
.
relatedMarketingCode
=
''
// 重置网格选择
if
(
value
===
'1'
)
{
// 装维师傅 - 单选
this
.
updatePersonStore
.
grid
=
''
}
else
{
// 支撑人员 - 多选
this
.
updatePersonStore
.
grid
=
[]
}
setTimeout
(()
=>
{
// 设置网格选择模式
this
.
gridIsMultiple
=
value
===
'2'
},
100
)
// 如果当前有选中的网格且是装维师傅,查询支撑人员
if
(
value
===
'1'
&&
this
.
updatePersonStore
.
grid
)
{
this
.
queryYxPerson
()
}
},
gridRender
(
row
,
column
){
let
arr
=
row
.
gridList
if
(
arr
&&
arr
.
length
>
0
){
return
arr
.
map
(
item
=>
{
return
item
.
gridName
}).
join
(
','
)
}
return
""
},
queryArea
(){
this
.
apiReq
.
queryLevelAllArea
({
areaLevel
:
2
,
...
...
@@ -426,13 +458,11 @@ export default {
}
})
},
personnelTypeChange
(){
this
.
updatePersonStore
.
relatedMarketingCode
=
''
},
queryYxPerson
(){
this
.
apiReq
.
queryAllPerson
({
pageSize
:
20
,
pageNum
:
1
,
gridCode
:
this
.
updatePersonStore
.
grid
,
personnelTypes
:
[
2
]
}).
then
(
res
=>
{
if
(
res
.
code
==
200
){
...
...
@@ -447,13 +477,40 @@ export default {
ud
.
row
=
row
ud
.
personnelName
=
row
.
personnelName
ud
.
personnelCode
=
row
.
personnelCode
ud
.
personnelType
=
row
.
personnelType
+
''
// 设置网格选择模式
this
.
gridIsMultiple
=
ud
.
personnelType
===
'2'
if
(
row
.
personnelType
==
'1'
){
ud
.
relatedMarketingCode
=
row
.
relatedMarketingCode
+
''
}
if
(
row
.
cityCode
){
ud
.
city
=
row
.
cityCode
this
.
cityChange
(
ud
.
city
,
'person'
)
if
(
row
.
countyCode
){
ud
.
county
=
row
.
countyCode
this
.
countyChange
(
ud
.
county
,
'person'
)
if
(
row
.
gridList
){
let
arr
=
row
.
gridList
.
map
(
item
=>
{
return
item
.
gridCode
})
ud
.
grid
=
row
.
personnelType
==
'1'
?
arr
.
join
(
''
):
arr
if
(
row
.
personnelType
==
'1'
){
this
.
queryYxPerson
()
}
}
}
}
ud
.
phone
=
row
.
phone
ud
.
status
=
row
.
status
ud
.
relatedMarketingCode
=
row
.
relatedMarketingCode
ud
.
status
=
row
.
status
+
''
}
else
{
ud
.
row
=
{}
ud
.
personnelName
=
''
ud
.
personnelCode
=
''
ud
.
personnelType
=
''
ud
.
phone
=
''
ud
.
status
=
''
ud
.
relatedMarketingCode
=
''
...
...
@@ -546,6 +603,7 @@ export default {
let
ad
=
type
==
'person'
?
this
.
updatePersonStore
:
this
.
addressStore
ad
.
county
=
value
ad
.
grid
=
''
ad
.
gridArr
=
[]
this
.
apiReq
.
queryGridList
({
areaCode
:
value
...
...
@@ -559,6 +617,11 @@ export default {
}
})
},
gridChange
(
value
){
if
(
this
.
updatePersonStore
.
personnelType
==
1
&&
value
){
this
.
queryYxPerson
()
}
},
deletePersonnel
(
id
)
{
this
.
$confirm
(
'确定要删除该人员吗?此操作不可撤销。'
,
'确认删除'
,
{
confirmButtonText
:
'确定'
,
...
...
@@ -582,6 +645,7 @@ export default {
if
(
valid
)
{
let
ud
=
this
.
updatePersonStore
this
.
apiReq
.
addNewPerson
({
id
:
ud
.
row
?
ud
.
row
.
id
:
''
,
personnelName
:
ud
.
personnelName
,
personnelCode
:
ud
.
personnelCode
,
phone
:
ud
.
phone
,
...
...
@@ -589,11 +653,11 @@ export default {
status
:
ud
.
status
,
relatedMarketingCode
:
ud
.
relatedMarketingCode
,
areaCode
:
ud
.
county
,
gridCode
:
ud
.
grid
gridCode
List
:
ud
.
personnelType
==
1
?[
ud
.
grid
]:
ud
.
grid
}).
then
(
res
=>
{
if
(
res
.
code
==
'200'
){
let
__this
=
this
this
.
$alert
(
'添加成功'
,
'温馨提示'
,
{
this
.
$alert
(
ud
.
row
?
'编辑成功'
:
'添加成功'
,
'温馨提示'
,
{
confirmButtonText
:
'确定'
,
callback
:
()
=>
{
__this
.
handleFilter
()
...
...
zhiJianBusi/zjbPc/src/views/LoginPage.vue
View file @
c352d42
...
...
@@ -68,7 +68,7 @@
alt=
"中国移动 Logo"
class=
"login-logo"
>
<h1
class=
"login-app-title"
>
上门随销
商机管理平台
</h1>
<h1
class=
"login-app-title"
>
南通铁通
商机管理平台
</h1>
</div>
<!-- 登录方式切换 -->
...
...
zhiJianBusi/zjbPc/src/views/OpportunityDetail.vue
View file @
c352d42
...
...
@@ -77,7 +77,7 @@
</div>
</el-card>
<el-card
class=
"detail-card"
>
<el-card
class=
"detail-card"
v-if=
"opportunity.opportunityType == 1"
>
<div
class=
"card-header"
>
<h3>
支撑人员信息
</h3>
</div>
...
...
@@ -192,6 +192,7 @@
icon=
"el-icon-edit"
class=
"action-btn"
@
click=
"assignBusi"
v-if=
"opportunity.opportunityType==1"
:disabled=
"opportunity.status!=1 && opportunity.status!=2"
>
分配商机
...
...
@@ -201,7 +202,7 @@
icon=
"el-icon-s-promotion"
class=
"action-btn"
@
click=
"dealBusi"
:disabled=
"
opportunity.status!=1 && opportunity.status!=2
"
:disabled=
"
(opportunity.status!=1 && opportunity.status!=2) || ifCanOperate
"
>
标记成单
</el-button>
...
...
@@ -210,7 +211,7 @@
icon=
"el-icon-s-check"
class=
"action-btn"
@
click=
"audioBusi"
:disabled=
"
opportunity.status!=3
"
:disabled=
"
(opportunity.status!=3) || ifCanOperate
"
>
商机审核
</el-button>
...
...
@@ -219,7 +220,7 @@
icon=
"el-icon-circle-close"
class=
"action-btn"
@
click=
"shutBusi"
:disabled=
"
opportunity.status==5 || opportunity.status==4
"
:disabled=
"
(opportunity.status==5 || opportunity.status==4) || ifCanOperate
"
>
关闭商机
</el-button>
...
...
@@ -262,7 +263,7 @@
type=
"text"
icon=
"el-icon-edit-outline"
class=
"action-btn"
:disabled=
"
opportunity.status==5 || opportunity.status==4
"
:disabled=
"
(opportunity.status==5 || opportunity.status==4) || ifCanOperate
"
@
click=
"memoStore.isEdit = true"
>
编辑
...
...
@@ -299,12 +300,14 @@
width=
"500px"
>
<el-form
:model=
"closeBusiStore"
label-width=
"100px"
>
<el-form-item
label=
"关闭原因"
>
<el-input
v-model=
"closeBusiStore.reason"
type=
"textarea"
:rows=
"4"
placeholder=
"请输入关闭商机原因"
></el-input>
<el-select
v-model=
"closeBusiStore.reason"
placeholder=
"请选择关闭理由"
>
<el-option
v-for=
"item in closeBusiStore.reasonsList"
:key=
"item.closeReason"
:label=
"item.closeReason"
:value=
"item.closeReason"
></el-option>
</el-select>
</el-form-item>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
...
...
@@ -354,7 +357,7 @@
</el-radio-group>
</el-form-item>
<el-form-item
v-if=
"audioBusiStore.result == '0'"
label=
"不通过
理由"
required
>
<el-form-item
label=
"
理由"
required
>
<el-input
v-model=
"audioBusiStore.reason"
type=
"textarea"
...
...
@@ -429,7 +432,8 @@ export default {
closeBusiStore
:{
isShow
:
false
,
reason
:
''
reason
:
''
,
reasonsList
:
[],
},
yxPersonList
:
[],
audioBusiStore
:{
...
...
@@ -461,9 +465,24 @@ export default {
created
()
{
this
.
queryDetail
()
this
.
queryFollow
()
this
.
query
YxPerson
()
this
.
query
CloseList
()
},
methods
:
{
ifCanOperate
(){
let
ui
=
JSON
.
parse
(
localStorage
.
getItem
(
'accountInfo'
))
return
this
.
opportunity
.
opportunityType
==
2
&&
ui
.
gridCode
},
queryCloseList
(){
this
.
apiReq
.
queryBusiCloseReansonList
({
pageNum
:
1
,
pageSize
:
1000
}).
then
(
res
=>
{
if
(
res
.
code
==
200
){
this
.
closeBusiStore
.
reasonsList
=
res
.
data
.
records
}
})
},
getAddressShow
(
value
){
if
(
!
value
){
return
'--'
...
...
@@ -471,11 +490,19 @@ export default {
return
value
.
split
(
":"
)[
1
]
},
queryYxPerson
(){
this
.
apiReq
.
queryAllPerson
(
{
let
param
=
{
pageSize
:
20
,
pageNum
:
1
,
personnelTypes
:
[
2
]
}).
then
(
res
=>
{
}
if
(
this
.
opportunity
.
opportunityType
==
1
){
param
.
gridCode
=
this
.
opportunity
.
gridCode
}
else
{
param
.
areaCode
=
this
.
opportunity
.
areaCode
}
this
.
apiReq
.
queryAllPerson
(
param
).
then
(
res
=>
{
if
(
res
.
code
==
200
){
this
.
yxPersonList
=
res
.
data
.
records
}
...
...
@@ -564,6 +591,7 @@ export default {
this
.
memoStore
.
value
=
res
.
data
.
adminRemark
this
.
handleAudio
()
this
.
queryYxPerson
()
}
else
{
this
.
$alert
(
res
.
$message
,
'温馨提示'
,
{
confirmButtonText
:
'确定'
,
...
...
@@ -609,7 +637,7 @@ export default {
audioBusiSubmit
(){
let
ad
=
this
.
audioBusiStore
if
(
ad
.
result
==
0
&&
!
ad
.
reason
){
if
(
!
ad
.
reason
){
this
.
$message
.
error
(
'请输入不通过理由'
)
return
}
...
...
zhiJianBusi/zjbPc/src/views/OpportunityManagement.vue
View file @
c352d42
...
...
@@ -221,7 +221,7 @@
<el-table
:data=
"tableData"
border
v-loading=
"loading"
>
<el-table-column
prop=
"
id"
label=
"商机ID"
width=
"15
0"
></el-table-column>
<el-table-column
prop=
"
opportunityCode"
label=
"商机ID"
width=
"20
0"
></el-table-column>
<el-table-column
prop=
"createTime"
label=
"创建时间"
:formatter=
"timeRender"
width=
"180"
></el-table-column>
<el-table-column
prop=
"customerAddress"
label=
"客户地址"
width=
"230"
:formatter=
"addressRender"
show-overflow-tooltip
></el-table-column>
<el-table-column
prop=
"customerPhone"
label=
"用户账号"
width=
"120"
></el-table-column>
...
...
@@ -245,7 +245,7 @@
<el-table-column
label=
"操作"
min-width=
"200"
>
<
template
slot-scope=
"scope"
>
<el-button
type=
"text"
size=
"small"
@
click=
"checkDetail(scope.row)"
>
查看详情
</el-button>
<el-button
type=
"text"
size=
"small"
@
click=
"checkAudio(scope.row)"
:disabled=
"
scope.row.status!=3
"
>
审核
</el-button>
<el-button
type=
"text"
size=
"small"
@
click=
"checkAudio(scope.row)"
:disabled=
"
ifCanAudio(scope.row)
"
>
审核
</el-button>
</
template
>
</el-table-column>
</el-table>
...
...
@@ -271,12 +271,70 @@
title=
"新增商机"
:visible
.
sync=
"newOpportunity.isShow"
width=
"800px"
>
<el-form
label-width=
"120px"
>
<el-form
:model=
"newOpportunity"
:rules=
"newOpportunity.rules"
ref=
"opportuntityForm"
label-width=
"120px"
>
<el-form-item
label=
"用户账号"
prop=
"customerPhone"
>
<el-input
v-model=
"newOpportunity.customerPhone"
placeholder=
"请输入用户账号"
></el-input>
</el-form-item>
<el-form-item
label=
"客户地址"
prop=
"city"
>
<
template
v-if=
"newOpportunity.cityArr.length>0"
>
<el-form-item
label=
"装维人员工号"
prop=
"maintenanceStaffNo"
>
<el-input
v-model=
"newOpportunity.maintenanceStaffNo"
placeholder=
"请输入装维人员工号"
@
blur=
"getGwName"
></el-input>
</el-form-item>
<el-form-item
label=
"装维人员姓名"
v-if=
"newOpportunity.maintenanceStaffName"
>
<el-input
v-model=
"newOpportunity.maintenanceStaffName"
disabled
></el-input>
</el-form-item>
<el-form-item
label=
"业务类型"
prop=
"tagIds"
>
<el-select
v-model=
"newOpportunity.tagIds"
placeholder=
"请选择业务类型"
style=
"width: 100%;"
multiple
>
<el-option
v-for=
"item in busiLabelStore"
:label=
"item.tagName"
:value=
"item.id"
:disabled=
"isTagCanCho(item)"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"客户地址"
:required=
"newOpportunity.tagIds.includes(1)||newOpportunity.tagIds.includes(2)"
>
<el-form-item
prop=
"city"
v-if=
"newOpportunity.cityArr.length>0"
style=
"display: inline-block"
>
<el-select
v-model=
"newOpportunity.city"
placeholder=
"选择地市"
@
change=
"addCityChange"
style=
"margin-right: 10px"
clearable
>
<el-option
v-for=
"item in newOpportunity.cityArr"
:key=
"item.code"
:label=
"item.name"
:value=
"item.code"
></el-option>
</el-select>
</el-form-item>
<el-form-item
prop=
"county"
v-if=
"newOpportunity.countyArr.length>0"
style=
"display: inline-block"
>
<el-select
v-model=
"newOpportunity.county"
placeholder=
"选择区县"
@
change=
"addCountyChange"
style=
"margin-right: 10px"
clearable
>
<el-option
v-for=
"item in newOpportunity.countyArr"
:key=
"item.code"
:label=
"item.name"
:value=
"item.code"
></el-option>
</el-select>
</el-form-item>
<el-form-item
prop=
"streets"
v-if=
"newOpportunity.streetsArr.length>0"
style=
"display: inline-block"
>
<el-select
v-model=
"newOpportunity.streets"
placeholder=
"选择街道"
@
change=
"addStreetsChange"
clearable
>
<el-option
v-for=
"item in newOpportunity.streetsArr"
:key=
"item.code"
:label=
"item.name"
:value=
"item.code"
></el-option>
</el-select>
</el-form-item>
<el-form-item
prop=
"detail"
v-if=
"newOpportunity.streets"
>
<el-input
v-model=
"newOpportunity.detail"
placeholder=
"请输入详细地址"
style=
"margin-top: 10px;"
></el-input>
</el-form-item>
<!-- <template v-if="newOpportunity.cityArr.length>0">
<el-select
v-model="newOpportunity.city"
placeholder="选择地市"
...
...
@@ -320,15 +378,7 @@
></el-option>
</el-select>
</template>
<el-input
v-if=
"newOpportunity.streets"
v-model=
"newOpportunity.detail"
placeholder=
"请输入详细地址"
style=
"margin-top: 10px;"
></el-input>
</el-form-item>
<el-form-item
label=
"装维人员工号"
prop=
"maintenanceStaffNo"
>
<el-input
v-model=
"newOpportunity.maintenanceStaffNo"
placeholder=
"请输入装维人员工号"
></el-input>
</el-form-item>
<el-form-item
label=
"业务类型"
prop=
"tagIds"
>
<el-select
v-model=
"newOpportunity.tagIds"
placeholder=
"请选择业务类型"
style=
"width: 100%;"
multiple
>
<el-option
v-for=
"item in busiLabelStore"
:label=
"item.tagName"
:value=
"item.id"
:disabled=
"isTagCanCho(item)"
></el-option>
</el-select>
<el-input v-if="newOpportunity.streets" v-model="newOpportunity.detail" placeholder="请输入详细地址" style="margin-top: 10px;"></el-input> -->
</el-form-item>
<el-form-item
label=
"文字描述"
prop=
"textDescription"
>
<el-input
...
...
@@ -376,33 +426,10 @@
</template>
<
script
>
import
{
mapGetters
}
from
'vuex'
// 商机状态映射
const
statusMap
=
{
'assigned'
:
{
label
:
'待跟进'
,
color
:
'blue'
},
'following'
:
{
label
:
'跟进中'
,
color
:
'orange'
},
'pending_review'
:
{
label
:
'成单待审核'
,
color
:
'purple'
},
'completed'
:
{
label
:
'已成单'
,
color
:
'green'
},
'closed'
:
{
label
:
'已关闭'
,
color
:
'gray'
}
}
// 商机标签
const
opportunityTags
=
[
'网络升级'
,
'家庭安防'
,
'智能家居'
,
'宽带套餐'
,
'移动套餐'
,
'融合套餐'
,
'企业业务'
]
// 支撑人员列表
const
mockSalesPersons
=
[
{
id
:
'SALE001'
,
name
:
'张营销'
,
gridName
:
'A网格'
,
phone
:
'13812345001'
},
{
id
:
'SALE002'
,
name
:
'陈营销'
,
gridName
:
'B网格'
,
phone
:
'13812345002'
},
{
id
:
'SALE003'
,
name
:
'刘营销'
,
gridName
:
'C网格'
,
phone
:
'13812345003'
},
{
id
:
'SALE004'
,
name
:
'赵营销'
,
gridName
:
'A网格'
,
phone
:
'13812345004'
},
{
id
:
'SALE005'
,
name
:
'王营销'
,
gridName
:
'B网格'
,
phone
:
'13812345005'
}
]
export
default
{
name
:
'OpportunityManagement'
,
data
()
{
let
fthis
=
this
return
{
formData
:{
customerPhone
:
''
,
...
...
@@ -449,16 +476,38 @@ export default {
detail
:
''
,
maintenanceStaffNo
:
''
,
maintenanceStaffName
:
''
,
tagIds
:
[],
opportunityType
:
''
,
textDescription
:
''
textDescription
:
''
,
rules
:{
customerPhone
:
[
{
required
:
true
,
message
:
'请输入用户账号'
,
trigger
:
'blur'
}
],
maintenanceStaffNo
:
[
{
required
:
true
,
message
:
'请输入装维人员工号'
,
trigger
:
'blur'
}
],
tagIds
:
[
{
required
:
true
,
message
:
'请选择业务类型'
,
trigger
:
'blur'
}
],
city
:
[
{
validator
:
this
.
validateCity
,
message
:
'请选择地市'
,
trigger
:
'blur'
}
],
county
:
[
{
validator
:
this
.
validateCounty
,
message
:
'请选择区县'
,
trigger
:
'blur'
}
],
streets
:
[
{
validator
:
this
.
validateStreets
,
message
:
'请选择街道'
,
trigger
:
'blur'
}
],
detail
:
[
{
validator
:
this
.
validateDetail
,
message
:
'请输入详细地址'
,
trigger
:
'blur'
}
],
}
},
busiLabelStore
:
[],
loading
:
false
,
statusMap
,
opportunityTags
,
mockSalesPersons
,
activeTab
:
'all'
,
searchTerm
:
''
,
selectedRegion
:
''
,
...
...
@@ -489,6 +538,55 @@ export default {
this
.
queryAllBusiLabel
()
},
methods
:
{
ifCanAudio
(
row
){
return
row
.
status
!=
3
||
(
row
.
opportunityType
==
2
&&
this
.
getData
.
grid
)
},
getGwName
(){
this
.
apiReq
.
queryAllPerson
({
pageSize
:
this
.
pageStore
.
pageSize
,
pageNum
:
this
.
pageStore
.
currentPage
,
personnelCode
:
this
.
newOpportunity
.
maintenanceStaffNo
}).
then
(
res
=>
{
this
.
newOpportunity
.
maintenanceStaffName
=
''
if
(
res
.
code
==
200
){
let
arr
=
res
.
data
.
records
if
(
arr
.
length
>
0
){
this
.
newOpportunity
.
maintenanceStaffName
=
arr
[
0
].
personnelName
}
}
})
},
validateCity
(
rule
,
value
,
callback
)
{
if
(
this
.
shouldValidateAddress
()
&&
!
value
)
{
callback
(
new
Error
(
'请选择地市'
))
}
else
{
callback
()
}
},
validateCounty
(
rule
,
value
,
callback
)
{
if
(
this
.
shouldValidateAddress
()
&&
!
value
)
{
callback
(
new
Error
(
'请选择区县'
))
}
else
{
callback
()
}
},
validateStreets
(
rule
,
value
,
callback
)
{
if
(
this
.
shouldValidateAddress
()
&&
!
value
)
{
callback
(
new
Error
(
'请选择街道'
))
}
else
{
callback
()
}
},
validateDetail
(
rule
,
value
,
callback
)
{
if
(
this
.
shouldValidateAddress
()
&&
!
value
)
{
callback
(
new
Error
(
'请输入详细地址'
))
}
else
{
callback
()
}
},
shouldValidateAddress
()
{
return
this
.
newOpportunity
.
tagIds
.
includes
(
1
)
||
this
.
newOpportunity
.
tagIds
.
includes
(
2
)
},
addressRender
(
row
,
column
){
let
value
=
row
[
column
.
property
]
...
...
@@ -535,18 +633,10 @@ export default {
addNewBusi
(){
let
nd
=
this
.
newOpportunity
nd
.
customerPhone
=
''
nd
.
city
=
''
nd
.
cityName
=
''
nd
.
county
=
''
nd
.
countyName
=
''
nd
.
streets
=
''
nd
.
streetsName
=
''
nd
.
maintenanceStaffNo
=
''
nd
.
tagIds
=
''
nd
.
textDescription
=
''
nd
.
isShow
=
true
setTimeout
(()
=>
{
this
.
$refs
.
opportuntityForm
.
resetFields
()
},
0
);
},
queryAllBusiLabel
(){
this
.
apiReq
.
queryBusiLabelList
({
...
...
@@ -614,8 +704,18 @@ export default {
addCityChange
(
value
){
let
ad
=
this
.
newOpportunity
ad
.
city
=
value
ad
.
cityName
=
ad
.
cityArr
.
find
(
item
=>
item
.
code
==
value
).
name
if
(
!
value
){
ad
.
county
=
''
ad
.
countyName
=
''
ad
.
countyArr
=
[]
ad
.
streets
=
''
ad
.
streetsName
=
''
ad
.
streetsArr
=
[]
return
}
ad
.
cityName
=
ad
.
cityArr
.
find
(
item
=>
item
.
code
==
value
).
name
ad
.
cityArr
.
forEach
(
item
=>
{
if
(
item
.
code
==
ad
.
city
){
ad
.
countyArr
=
item
.
districts
...
...
@@ -625,8 +725,15 @@ export default {
addCountyChange
(
value
){
let
ad
=
this
.
newOpportunity
ad
.
county
=
value
ad
.
countyName
=
ad
.
countyArr
.
find
(
item
=>
item
.
code
==
value
).
name
if
(
!
value
){
ad
.
streets
=
''
ad
.
streetsName
=
''
ad
.
streetsArr
=
[]
return
}
ad
.
countyName
=
ad
.
countyArr
.
find
(
item
=>
item
.
code
==
value
).
name
ad
.
countyArr
.
forEach
(
item
=>
{
if
(
item
.
code
==
ad
.
county
){
ad
.
streetsArr
=
item
.
streets
...
...
@@ -689,30 +796,12 @@ export default {
}
})
},
addBusiSubmit
(){
a
sync
a
ddBusiSubmit
(){
let
nd
=
this
.
newOpportunity
if
(
!
nd
.
customerPhone
){
this
.
$message
.
error
(
'请输入用户账号'
)
return
}
if
(
!
nd
.
city
||
!
nd
.
county
||
!
nd
.
streets
||
!
nd
.
detail
){
this
.
$message
.
error
(
'请补全客户地址信息'
)
return
}
await
this
.
$refs
.
opportuntityForm
.
validate
()
let
address
=
nd
.
city
+
'|'
+
nd
.
county
+
'|'
+
nd
.
streets
+
":"
+
nd
.
cityName
+
nd
.
countyName
+
nd
.
streetsName
+
nd
.
detail
if
(
!
nd
.
maintenanceStaffNo
){
this
.
$message
.
error
(
'请输入装维人员工号'
)
return
}
if
(
!
nd
.
tagIds
){
this
.
$message
.
error
(
'请选择业务类型'
)
return
}
this
.
apiReq
.
createBusi
({
customerAddress
:
address
,
...
nd
...
...
@@ -734,9 +823,6 @@ export default {
},
getStatusType
(
status
)
{
const
typeMap
=
{
'assigned'
:
'info'
,
...
...
zhiJianBusi/zjbPc/vue.config.js
View file @
c352d42
...
...
@@ -11,7 +11,7 @@ module.exports = {
proxy
:
{
'/compass'
:
{
target
:
'https://testznzl.lgyzpt.com/'
,
//target: 'http
s://hall.51xinpai.cn
',
//target: 'http
://39.107.104.220:8877
',
changeOrigin
:
true
,
pathRewrite
:
{
'^/compass'
:
'compass'
...
...
zhiJianBusi/zjbPhone/busiDetail.html
View file @
c352d42
...
...
@@ -199,7 +199,7 @@
<div
class=
"imgList"
>
<div
class=
"addImg"
v-if=
"gjStore.imgArr.length<3"
>
<img
class=
"add"
src=
"images/add.png"
alt=
""
>
<input
type=
"file"
@
change=
"fileChange"
accept=
"image/*"
:disabled=
"gjStore.isLoading"
>
<input
type=
"file"
@
change=
"fileChange"
accept=
"image/*"
multiple
:disabled=
"gjStore.isLoading"
>
</div>
<div
class=
"imgShow"
v-for=
"(item,index) in gjStore.imgArr"
>
<img
class=
"show"
:src=
"item.url"
alt=
""
>
...
...
@@ -249,12 +249,25 @@
<div
class=
"botTs"
>
关闭后将无法再进行任何编辑操作
</div>
</div>
</div>
<!-- <div class="outAlertBg">
<div class="imgAlertCon">
<div class="imgDiv">
<img src="https://pic1.arkoo.com/56D0B40F99F841DF8A2425762AE2565D/picture/o_1i4qop009177v1tgf14db15he1iaj1is.jpg" alt="">
</div>
<div class="choButt">
<div class="prev">prev</div>
<div class="next">next</div>
</div>
</div>
</div> -->
</div>
<!-- 引入Vue.js -->
<script
src=
"js/vue.min.js"
></script>
<script
src=
"js/axios.min.js"
></script>
<script
src=
"js/util.js"
></script>
<script
src=
"js/busiDetail.js?
123
"
></script>
<script
src=
"js/busiDetail.js?
000
"
></script>
</body>
</html>
\ No newline at end of file
zhiJianBusi/zjbPhone/css/busiDetail.css
View file @
c352d42
...
...
@@ -182,6 +182,32 @@ 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
,
...
...
zhiJianBusi/zjbPhone/js/busiDetail.js
View file @
c352d42
...
...
@@ -337,17 +337,20 @@ new Vue({
return
}
let
file
=
e
.
target
.
files
[
0
]
console
.
log
(
file
)
if
(
file
.
type
.
includes
(
'image/'
)
<=
0
){
util
.
toast
(
'请上传图片'
)
return
let
files
=
e
.
currentTarget
.
files
if
(
files
.
length
>
3
)
{
utils
.
toast
(
`最多只能选择3张图片`
);
e
.
value
=
''
;
return
false
;
}
for
(
let
key
in
files
){
this
.
gjStore
.
imgArr
.
push
({
file
:
file
,
url
:
URL
.
createObjectURL
(
file
)
file
:
files
[
key
]
,
url
:
URL
.
createObjectURL
(
files
[
key
]
)
})
}
},
/**
...
...
zhiJianBusi/zjbPhone/js/login.js
View file @
c352d42
...
...
@@ -8,7 +8,7 @@ new Vue({
loginForm
:
{
employeeId
:
''
,
phoneNumber
:
''
,
verifyCode
:
''
verifyCode
:
'
123456
'
},
countdown
:
0
,
countdownTimer
:
null
,
...
...
@@ -19,16 +19,16 @@ new Vue({
this
.
platform
=
type
localStorage
.
setItem
(
'platform'
,
type
)
//
if(type == 'gw'){
//
this.loginForm.employeeId = '54321'
//
this.loginForm.phoneNumber = '15611154004'
//
}else if(type == 'yx'){
//
this.loginForm.employeeId = '12345'
//
this.loginForm.phoneNumber = '13718590607'
//
}else{
//
this.loginForm.employeeId = '54321'
//
this.loginForm.phoneNumber = '13212789513'
//
}
if
(
type
==
'gw'
){
this
.
loginForm
.
employeeId
=
'54321'
this
.
loginForm
.
phoneNumber
=
'15611154004'
}
else
if
(
type
==
'yx'
){
this
.
loginForm
.
employeeId
=
'12345'
this
.
loginForm
.
phoneNumber
=
'13718590607'
}
else
{
this
.
loginForm
.
employeeId
=
'54321'
this
.
loginForm
.
phoneNumber
=
'13212789513'
}
},
getVerifyCode
()
{
let
pa
=
this
.
loginForm
...
...
zhiJianBusi/zjbPhone/myBusi.html
View file @
c352d42
...
...
@@ -48,7 +48,7 @@
<input
class=
"search-input"
type=
"text"
placeholder=
"输入用户
账号
"
placeholder=
"输入用户
联系方式
"
v-model=
"searchKeyword"
data-node-id=
"355:510"
>
...
...
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment