Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
B
biz.qingxiao.com
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wangxuelai
biz.qingxiao.com
Commits
d6d9fddf
Commit
d6d9fddf
authored
Jan 14, 2020
by
baixian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
优化
parent
654825d3
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
2325 additions
and
412 deletions
+2325
-412
api.js
src/common/api.js
+2
-0
constants.js
src/common/constants.js
+1174
-0
menuconfig.js
src/common/menuconfig.js
+1
-1
addcrm.js
src/models/addcrm.js
+41
-0
crm.js
src/models/crm.js
+168
-2
crmdetail.js
src/models/crmdetail.js
+235
-0
index.js
src/models/index.js
+2
-0
webapp.js
src/models/webapp.js
+44
-7
AddCrm.js
src/pages/crm/AddCrm.js
+18
-25
ChangeStatusModal.js
src/pages/crm/ChangeStatusModal.js
+89
-0
index.js
src/pages/crm/index.js
+126
-9
AddLogModal.js
src/pages/crmdetail/AddLogModal.js
+95
-0
index.js
src/pages/crmdetail/index.js
+222
-221
index.less
src/pages/crmdetail/index.less
+76
-146
RenewEdit.js
src/pages/student/RenewEdit.js
+3
-1
router.js
src/router.js
+1
-0
crm.js
src/services/crm.js
+28
-0
No files found.
src/common/api.js
View file @
d6d9fddf
...
...
@@ -223,5 +223,7 @@ export default {
},
crm
:
{
crmList
:
`
${
dakaapi
}
member/crm/clues`
,
clue_records
:
`
${
dakaapi
}
member/crm/clue_records`
,
clue_logs
:
`
${
dakaapi
}
member/crm/clue_logs`
,
},
};
src/common/constants.js
View file @
d6d9fddf
This diff is collapsed.
Click to expand it.
src/common/menuconfig.js
View file @
d6d9fddf
...
...
@@ -152,7 +152,7 @@ export default {
activeurl
:
`
${
__IMGCDN__
}
menu/crmactive.png`
,
notactiveurl
:
`
${
__IMGCDN__
}
menu/crm.png`
,
path
:
'/sjd/crm'
,
relativePath
:
[
'/sjd/crm'
,
'/sjd/addcrm'
,
'/sjd/crmdetail/:id'
],
relativePath
:
[
'/sjd/crm'
,
'/sjd/addcrm'
,
'/sjd/crmdetail/:id'
,
'/sjd/editcrm/:id'
],
},
{
id
:
'30'
,
...
...
src/models/addcrm.js
View file @
d6d9fddf
...
...
@@ -31,6 +31,7 @@ export default {
remark
:
''
,
birthday
:
''
,
gender
:
1
,
customers
:
[],
},
},
subscriptions
:
{
...
...
@@ -80,6 +81,45 @@ export default {
});
}
},
*
queryCrmDetail
({
payload
},
{
call
,
put
,
select
})
{
const
{
id
}
=
payload
;
const
loading
=
message
.
loading
(
'数据加载中...'
,
0.5
);
const
data
=
yield
call
(
crmAjax
.
crmDetail
,
{
id
,
});
setTimeout
(
loading
);
if
(
data
.
code
==
200
)
{
if
(
data
.
data
.
reserve_mobile
.
length
>
0
)
{
if
(
data
.
data
.
reserve_mobile
&&
(
typeof
data
.
data
.
reserve_mobile
==
'string'
))
{
data
.
data
.
reserve_mobile
=
JSON
.
parse
(
data
.
data
.
reserve_mobile
);
}
}
yield
put
({
type
:
'updateState'
,
payload
:
{
editCrmInfo
:
{
id
:
data
.
data
.
id
,
reserve_mobile
:
[...
data
.
data
.
reserve_mobile
],
name
:
data
.
data
.
name
,
mobile
:
data
.
data
.
mobile
,
source_type
:
data
.
data
.
source_type
,
intent_course_id
:
data
.
data
.
intent_course
?
data
.
data
.
intent_course
.
id
:
''
,
remark
:
data
.
data
.
remark
,
birthday
:
data
.
data
.
birthday
,
gender
:
data
.
data
.
gender
,
customers
:
data
.
data
.
customers
?
data
.
data
.
customers
:
[],
},
},
});
}
else
{
yield
put
({
type
:
'webapp/errorrequestresolve'
,
payload
:
{
data
,
},
});
}
},
*
saveCrm
({
payload
},
{
call
,
put
,
select
})
{
const
{
sid
}
=
yield
select
(
state
=>
state
.
webapp
);
const
{
...
...
@@ -189,6 +229,7 @@ export default {
remark
:
''
,
birthday
:
''
,
gender
:
1
,
customers
:
[],
},
courseList
:
[],
operator
:
{
...
...
src/models/crm.js
View file @
d6d9fddf
...
...
@@ -11,11 +11,12 @@ import {
}
from
'../utils/index'
;
import
*
as
crmAjax
from
'../services/crm'
;
import
errorcode
from
'../common/errorcode'
;
import
*
as
classMgtAjax
from
'../services/classmgt'
;
import
*
as
courseAjax
from
'../services/course'
;
import
*
as
studentsAjax
from
'../services/students'
;
export
default
{
namespace
:
'crm'
,
state
:
{
courseList
:
[],
crmParams
:
{
page
:
1
,
perPage
:
10
,
...
...
@@ -29,6 +30,18 @@ export default {
},
crmTotal
:
0
,
crmList
:
[],
checkedStatus
:
1
,
statusVisible
:
false
,
statusLoading
:
false
,
cluesId
:
0
,
operator
:
{
id
:
''
,
nickname
:
''
,
},
courseRelateClassList
:
[],
courseList
:
[],
goRenewCourseShow
:
false
,
studentInfo
:
{},
},
subscriptions
:
{
setup
({
dispatch
,
history
})
{
// eslint-disable-line
...
...
@@ -44,6 +57,11 @@ export default {
},
},
});
yield
put
({
type
:
'queryCoureList'
,
payload
:
{
},
});
},
*
queryCrmList
({
payload
},
{
call
,
put
,
select
})
{
const
{
params
}
=
payload
;
...
...
@@ -80,7 +98,6 @@ export default {
}
},
*
reset
({
payload
},
{
call
,
put
,
select
})
{
const
{
copyClassListQueryParams
}
=
yield
select
(
state
=>
state
.
classmgt
);
yield
put
({
type
:
'queryCrmList'
,
payload
:
{
...
...
@@ -109,6 +126,143 @@ export default {
pathname
:
`/sjd/crmdetail/
${
id
}
`
,
}));
},
*
saveStatus
({
payload
},
{
call
,
put
,
select
})
{
const
{
statusLoading
,
cluesId
}
=
yield
select
(
state
=>
state
.
crm
);
if
(
statusLoading
)
{
return
;
}
yield
put
({
type
:
'updateState'
,
payload
:
{
statusLoading
:
true
,
},
});
const
{
status
,
callBack
,
}
=
payload
;
const
loadmessage
=
message
.
loading
(
'保存中...'
,
0
);
const
data
=
yield
call
(
crmAjax
.
crmEdit
,
{
status
,
id
:
cluesId
,
});
yield
put
({
type
:
'updateState'
,
payload
:
{
statusLoading
:
false
,
},
});
setTimeout
(
loadmessage
);
if
(
data
.
code
==
200
)
{
message
.
success
(
'修改成功'
,
1
);
yield
put
({
type
:
'updateState'
,
payload
:
{
statusVisible
:
false
,
},
});
if
(
callBack
&&
(
typeof
callBack
==
'function'
))
{
callBack
();
}
yield
put
({
type
:
'queryCrmList'
,
payload
:
{
params
:
{
page
:
1
,
},
},
});
}
else
{
yield
put
({
type
:
'webapp/errorrequestresolve'
,
payload
:
{
data
,
},
});
}
},
*
searchCourseRelateClass
({
payload
},
{
call
,
put
,
select
})
{
const
{
sid
}
=
yield
select
(
state
=>
state
.
webapp
);
const
{
courseId
,
callBack
}
=
payload
;
const
classListData
=
yield
call
(
classMgtAjax
.
getClassList
,
{
page
:
1
,
perPage
:
1000
,
school_id
:
sid
,
course_id
:
courseId
,
graduation_status
:
1
,
});
yield
put
({
type
:
'updateState'
,
payload
:
{
courseRelateClassList
:
(
classListData
.
data
&&
classListData
.
data
.
list
)
||
[],
},
});
if
(
callBack
&&
(
typeof
callBack
)
==
'function'
)
{
callBack
();
}
},
*
queryCoureList
({
payload
},
{
call
,
put
,
select
})
{
const
{
sid
}
=
yield
select
(
state
=>
state
.
webapp
);
const
courselistinfo
=
yield
call
(
courseAjax
.
courseList
,
{
school_id
:
sid
,
page
:
1
,
perPage
:
100
,
});
if
(
courselistinfo
.
code
==
200
&&
courselistinfo
.
data
)
{
yield
put
({
type
:
'updateState'
,
payload
:
{
courseList
:
(
courselistinfo
.
data
&&
courselistinfo
.
data
.
list
)
||
[],
},
});
}
},
// eslint-disable-next-line require-yield
*
studentModelCoursesBuyOrRenew
({
payload
},
{
call
,
put
,
select
})
{
const
{
studentInfo
}
=
yield
select
(
state
=>
state
.
crm
);
const
{
sid
}
=
yield
select
(
state
=>
state
.
webapp
);
const
{
values
,
callBack
}
=
payload
;
const
loadmessage
=
message
.
loading
(
'购买中...'
,
0
);
const
data
=
yield
call
(
studentsAjax
.
studentsAdd
,
{
school_id
:
sid
,
name
:
studentInfo
.
name
,
birthday
:
studentInfo
.
birthday
,
mobile
:
studentInfo
.
mobile
,
avatar
:
''
,
remark
:
studentInfo
.
remark
,
gender
:
studentInfo
.
gender
,
force
:
1
,
operator_id
:
studentInfo
.
final_follow_id
,
});
// eslint-disable-next-line no-empty
if
(
data
.
code
===
200
)
{
}
// const buyOrRenewData = yield call(courseAjax.coursesBuyOrRenew, Object.assign(values, {
// class_ids: (values.class_ids && values.class_ids.join(',')) || '',
// student_id: selectdeStudent.id,
// }));
// setTimeout(loadmessage);
// if (buyOrRenewData.code == 200) {
// yield put({
// type: 'updateState',
// payload: {
// goRenewCourseShow: false,
// },
// });
// message.success('保存成功', 1);
// if (callBack && (typeof callBack) == 'function') {
// callBack();
// }
// } else {
// yield put({
// type: 'webapp/errorrequestresolve',
// payload: {
// data: buyOrRenewData,
// },
// });
// }
},
*
pageInit
({
payload
},
{
call
,
put
,
select
})
{
yield
put
({
type
:
'updateState'
,
...
...
@@ -126,6 +280,18 @@ export default {
},
crmTotal
:
0
,
crmList
:
[],
checkedStatus
:
1
,
statusVisible
:
false
,
statusLoading
:
false
,
cluesId
:
0
,
operator
:
{
id
:
''
,
nickname
:
''
,
},
courseRelateClassList
:
[],
courseList
:
[],
goRenewCourseShow
:
false
,
studentInfo
:
{},
},
});
},
...
...
src/models/crmdetail.js
0 → 100644
View file @
d6d9fddf
import
{
routerRedux
}
from
'dva/router'
;
import
{
message
}
from
'antd'
;
import
{
delay
}
from
'redux-saga'
;
import
moment
from
'moment'
;
import
{
LocalStorage
,
SessionStorage
,
isExpired
,
getRandomFilename
,
}
from
'../utils/index'
;
import
*
as
crmAjax
from
'../services/crm'
;
import
errorcode
from
'../common/errorcode'
;
import
*
as
courseAjax
from
'../services/course'
;
export
default
{
namespace
:
'crmdetail'
,
state
:
{
crmDetail
:
{},
addLogVisible
:
false
,
addLogLoading
:
false
,
clueParams
:
{
page
:
1
,
perPage
:
10
,
},
clueTotal
:
0
,
clueList
:
[],
activeIndex
:
1
,
logParams
:
{
page
:
1
,
perPage
:
999
,
},
logList
:
[],
},
subscriptions
:
{
setup
({
dispatch
,
history
})
{
// eslint-disable-line
},
},
effects
:
{
*
queryinfo
({
payload
},
{
call
,
put
,
select
})
{
const
{
id
}
=
payload
;
yield
put
({
type
:
'queryCrmDetail'
,
payload
:
{
id
,
},
});
yield
put
({
type
:
'queryClueList'
,
payload
:
{
params
:
{
clue_id
:
id
,
},
},
});
yield
put
({
type
:
'queryLogsList'
,
payload
:
{
params
:
{
clue_id
:
id
,
},
},
});
},
*
queryClueList
({
payload
},
{
call
,
put
,
select
})
{
const
{
params
}
=
payload
;
const
{
clueParams
,
clueTotal
}
=
yield
select
(
state
=>
state
.
crmdetail
);
const
loading
=
message
.
loading
(
'数据加载中...'
,
0.5
);
const
newParams
=
Object
.
assign
(
clueParams
,
params
);
let
newTotal
=
clueTotal
;
const
data
=
yield
call
(
crmAjax
.
clueList
,
{
...
newParams
,
});
setTimeout
(
loading
);
if
(
data
.
code
==
200
)
{
if
(
data
.
data
.
total
!=
undefined
)
{
newTotal
=
data
.
data
.
total
;
}
yield
put
({
type
:
'updateState'
,
payload
:
{
clueList
:
data
.
data
&&
data
.
data
.
list
,
clueTotal
:
newTotal
,
clueParams
:
{
...
newParams
},
},
});
}
else
{
yield
put
({
type
:
'webapp/errorrequestresolve'
,
payload
:
{
data
,
},
});
}
},
*
queryLogsList
({
payload
},
{
call
,
put
,
select
})
{
const
{
params
}
=
payload
;
const
{
logParams
}
=
yield
select
(
state
=>
state
.
crmdetail
);
const
newParams
=
Object
.
assign
(
logParams
,
params
);
const
data
=
yield
call
(
crmAjax
.
logsList
,
{
...
newParams
,
});
if
(
data
.
code
==
200
)
{
yield
put
({
type
:
'updateState'
,
payload
:
{
logList
:
data
.
data
&&
data
.
data
.
list
,
logParams
:
{
...
newParams
},
},
});
}
else
{
yield
put
({
type
:
'webapp/errorrequestresolve'
,
payload
:
{
data
,
},
});
}
},
*
queryCrmDetail
({
payload
},
{
call
,
put
,
select
})
{
const
{
id
}
=
payload
;
const
data
=
yield
call
(
crmAjax
.
crmDetail
,
{
id
,
});
if
(
data
.
code
==
200
)
{
if
(
data
.
data
.
reserve_mobile
.
length
>
0
)
{
if
(
data
.
data
.
reserve_mobile
&&
(
typeof
data
.
data
.
reserve_mobile
==
'string'
))
{
data
.
data
.
reserve_mobile
=
JSON
.
parse
(
data
.
data
.
reserve_mobile
);
}
}
yield
put
({
type
:
'updateState'
,
payload
:
{
crmDetail
:
{
...
data
.
data
},
},
});
}
else
{
yield
put
({
type
:
'webapp/errorrequestresolve'
,
payload
:
{
data
,
},
});
}
},
*
saveLog
({
payload
},
{
call
,
put
,
select
})
{
const
{
addLogLoading
,
crmDetail
}
=
yield
select
(
state
=>
state
.
crmdetail
);
if
(
addLogLoading
)
{
return
;
}
yield
put
({
type
:
'updateState'
,
payload
:
{
addLogLoading
:
true
,
},
});
const
{
content
,
type
,
callBack
,
}
=
payload
;
const
loadmessage
=
message
.
loading
(
'保存中...'
,
0
);
const
data
=
yield
call
(
crmAjax
.
addClueRecords
,
{
content
,
type
,
clue_id
:
crmDetail
.
id
,
});
yield
put
({
type
:
'updateState'
,
payload
:
{
addLogLoading
:
false
,
},
});
setTimeout
(
loadmessage
);
if
(
data
.
code
==
200
)
{
message
.
success
(
'添加成功'
,
1
);
yield
put
({
type
:
'updateState'
,
payload
:
{
addLogVisible
:
false
,
},
});
if
(
callBack
&&
(
typeof
callBack
==
'function'
))
{
callBack
();
}
yield
put
({
type
:
'queryClueList'
,
payload
:
{
params
:
{
clue_id
:
crmDetail
.
id
,
page
:
1
,
},
},
});
}
else
{
yield
put
({
type
:
'webapp/errorrequestresolve'
,
payload
:
{
data
,
},
});
}
},
*
goEditCrm
({
payload
},
{
put
,
select
})
{
const
{
id
}
=
payload
;
yield
put
(
routerRedux
.
push
({
pathname
:
`/sjd/editcrm/
${
id
}
`
,
}));
},
*
pageInit
({
payload
},
{
call
,
put
,
select
})
{
yield
put
({
type
:
'updateState'
,
payload
:
{
crmDetail
:
{},
addLogVisible
:
false
,
addLogLoading
:
false
,
activeIndex
:
1
,
logParams
:
{
page
:
1
,
perPage
:
10
,
},
logList
:
[],
},
});
},
},
reducers
:
{
save
(
state
,
action
)
{
return
{
...
state
,
...
action
.
payload
};
},
updateState
(
state
,
action
)
{
return
{
...
state
,
...
action
.
payload
};
},
},
};
src/models/index.js
View file @
d6d9fddf
...
...
@@ -53,6 +53,7 @@ import personmanage from './personmanage';
import
rolemanage
from
'./rolemanage'
;
import
crm
from
'./crm'
;
import
addcrm
from
'./addcrm'
;
import
crmdetail
from
'./crmdetail'
;
export
default
{
loginModel
,
indexstaicModel
,
...
...
@@ -100,4 +101,5 @@ export default {
rolemanage
,
crm
,
addcrm
,
crmdetail
,
};
src/models/webapp.js
View file @
d6d9fddf
...
...
@@ -881,12 +881,12 @@ export default {
}
const
potentialactive
=
pathToRegexp
(
'/sjd/crmdetail/:id'
).
exec
(
pathname
);
if
(
potentialactive
)
{
//
dispatch({
// type: 'onlineclasses/findCourse
',
//
payload: {
//
id: potentialactive[1],
//
},
//
});
dispatch
({
type
:
'crmdetail/queryinfo
'
,
payload
:
{
id
:
potentialactive
[
1
],
},
});
dispatch
({
type
:
'updateState'
,
payload
:
{
...
...
@@ -925,6 +925,35 @@ export default {
},
});
}
const
editcrmactive
=
pathToRegexp
(
'/sjd/editcrm/:id'
).
exec
(
pathname
);
if
(
editcrmactive
)
{
dispatch
({
type
:
'addcrm/queryinfo'
,
payload
:
{
},
});
dispatch
({
type
:
'addcrm/queryCrmDetail'
,
payload
:
{
id
:
editcrmactive
[
1
],
},
});
dispatch
({
type
:
'updateState'
,
payload
:
{
breadcrumbList
:
[
{
path
:
'sjd/crm'
,
name
:
'潜客管理'
,
},
{
path
:
pathname
,
name
:
'编辑潜在学员'
,
},
],
},
});
}
if
(
pathname
===
'/sjd/singleclass'
)
{
dispatch
({
type
:
'onlineclasses/pageInit'
,
...
...
@@ -1265,10 +1294,18 @@ export default {
yield
put
({
type
:
'permissionsetting/pageInit'
,
});
}
else
if
(
pathToRegexp
(
'/sjd/
addpotential
'
).
exec
(
locationPathname
))
{
}
else
if
(
pathToRegexp
(
'/sjd/
crm
'
).
exec
(
locationPathname
))
{
yield
put
({
type
:
'crm/pageInit'
,
});
}
else
if
(
pathToRegexp
(
'/sjd/addcrm'
).
exec
(
locationPathname
))
{
yield
put
({
type
:
'addcrm/pageInit'
,
});
}
else
if
(
pathToRegexp
(
'/sjd/editcrm/:id'
).
exec
(
locationPathname
))
{
yield
put
({
type
:
'addcrm/pageInit'
,
});
}
// yield put({
// type: 'joinschooladd/pageInit',
...
...
src/pages/crm/AddCrm.js
View file @
d6d9fddf
...
...
@@ -31,7 +31,6 @@ class AddCrmForm extends React.Component {
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
age
:
0
,
};
}
componentDidMount
()
{
// 挂载
...
...
@@ -50,14 +49,12 @@ class AddCrmForm extends React.Component {
e
.
preventDefault
();
this
.
props
.
form
.
validateFields
((
err
,
values
)
=>
{
if
(
!
err
)
{
console
.
log
(
values
,
'values'
);
const
{
name
,
mobile
,
source_type
,
intent_course_id
,
remark
,
reserve_mobile
,
birthday
,
gender
,
}
=
values
;
...
...
@@ -67,7 +64,7 @@ class AddCrmForm extends React.Component {
name
,
mobile
,
source_type
,
intent_course_id
,
intent_course_id
:
intent_course_id
===
undefined
?
0
:
intent_course_id
,
remark
,
birthday
:
birthday
?
birthday
.
format
(
'YYYY-MM-DD'
)
:
''
,
gender
,
...
...
@@ -113,14 +110,6 @@ class AddCrmForm extends React.Component {
},
});
}
handleChangeAge
=
(
dateString
)
=>
{
if
(
!
dateString
)
{
this
.
state
.
age
=
0
;
return
;
}
const
toyear
=
new
Date
().
getFullYear
()
+
1
;
this
.
state
.
age
=
toyear
-
dateString
.
format
(
'YYYY'
)
||
0
;
}
render
()
{
const
{
form
:
{
getFieldDecorator
,
getFieldValue
},
...
...
@@ -128,7 +117,6 @@ class AddCrmForm extends React.Component {
courseList
,
operator
,
}
=
this
.
props
;
const
{
age
}
=
this
.
state
;
const
formItemLayout
=
{
labelCol
:
{
xs
:
{
span
:
24
},
...
...
@@ -147,7 +135,7 @@ class AddCrmForm extends React.Component {
xxl
:
{
span
:
21
},
},
};
const
formItems
=
editCrmInfo
.
reserve_mobile
.
map
((
k
,
index
)
=>
{
const
formItems
=
editCrmInfo
&&
editCrmInfo
.
reserve_mobile
.
map
((
k
,
index
)
=>
{
const
newIndex
=
index
;
return
(
<
Form
.
Item
...
...
@@ -158,16 +146,17 @@ class AddCrmForm extends React.Component {
colon
=
{
index
===
0
}
>
{
getFieldDecorator
(
`names[
${
index
}
]`
,
{
initialValue
:
k
,
rules
:
[
{
required
:
false
,
message
:
'请输入您的手机号!'
},
{
pattern
:
/^1
[
3456789
]{1}[
0-9
]{9}
$/
,
message
:
'请输入正确的手机号码!'
},
{
max
:
11
,
message
:
'手机号长度为11位!'
},
],
})(
<
Input
value
=
{
k
}
style
=
{{
width
:
260
}}
placeholder
=
"请输入手机号码"
onChange
=
{
e
=>
this
.
mobileChange
(
e
,
newIndex
)}
maxLength
=
{
11
}
/>
,
)}
})(
<
Input
style
=
{{
width
:
260
}}
placeholder
=
"请输入手机号码"
onChange
=
{
e
=>
this
.
mobileChange
(
e
,
newIndex
)}
maxLength
=
{
11
}
/>
,
)}
{
/* <Input value={k} style={{ width: 260 }} placeholder="请输入手机号码" onChange={e => this.mobileChange(e, newIndex)} maxLength={11} /> */
}
{
editCrmInfo
.
reserve_mobile
.
length
>
1
?
(
{
editCrmInfo
.
reserve_mobile
.
length
>
1
&&
index
!=
0
?
(
<
Button
size
=
"small"
className
=
{
pageStyle
.
delmobile
}
type
=
"danger"
onClick
=
{()
=>
this
.
delMobile
(
newIndex
)}
>
删除
<
/Button
>
)
:
null
}
{
index
===
0
?
(
...
...
@@ -184,7 +173,10 @@ class AddCrmForm extends React.Component {
<
FormItem
{...
formItemLayout
}
label
=
"学员姓名"
>
{
getFieldDecorator
(
'name'
,
{
initialValue
:
editCrmInfo
.
name
,
rules
:
[{
required
:
true
,
message
:
'学员姓名不能为空'
}],
rules
:
[
{
required
:
true
,
message
:
'学员姓名不能为空'
},
{
max
:
20
,
message
:
'学员姓名不能超过20位!'
},
],
})(
<
Input
style
=
{{
width
:
260
}}
placeholder
=
"请填写学员姓名"
/>
,
)}
...
...
@@ -198,7 +190,7 @@ class AddCrmForm extends React.Component {
{
max
:
11
,
message
:
'手机号长度为11位!'
},
],
})(
<
Input
style
=
{{
width
:
260
}}
placeholder
=
"请填写联系方式"
/>
,
<
Input
disabled
=
{
editCrmInfo
.
id
}
style
=
{{
width
:
260
}}
placeholder
=
"请填写联系方式"
/>
,
)}
<
p
className
=
{
pageStyle
.
mobileTip
}
>
此号码用于接收上课与预约通知相关短信
<
/p
>
<
/FormItem
>
...
...
@@ -214,18 +206,20 @@ class AddCrmForm extends React.Component {
<
/FormItem
>
<
FormItem
{...
formItemLayout
}
label
=
"生日日期"
>
{
getFieldDecorator
(
'birthday'
,
{
initialValue
:
editCrmInfo
.
birthday
,
initialValue
:
editCrmInfo
.
birthday
?
moment
(
editCrmInfo
.
birthday
)
:
''
,
})(
<
DatePicker
disabledDate
=
{
this
.
disabledDate
}
allowClear
onChange
=
{
this
.
handleChangeAge
}
style
=
{{
width
:
134
}}
/>
,
)}
<
span
style
=
{{
marginLeft
:
12
}}
>
年龄:
{
age
}
<
/span
>
<
/FormItem
>
{
formItems
}
<
FormItem
{...
formItemLayout
}
label
=
"备注"
>
{
getFieldDecorator
(
'remark'
,
{
initialValue
:
editCrmInfo
.
remark
,
rules
:
[
{
max
:
200
,
message
:
'备注不能超过200字!'
},
],
})(
<
TextArea
rows
=
{
4
}
style
=
{{
width
:
260
}}
placeholder
=
"请输入备注"
/>
,
<
TextArea
rows
=
{
4
}
maxLength
=
{
210
}
style
=
{{
width
:
260
}}
placeholder
=
"请输入备注"
/>
,
)}
<
/FormItem
>
<
div
className
=
{
pageStyle
.
commonTitle
}
>
售卖信息
<
/div
>
...
...
@@ -234,7 +228,7 @@ class AddCrmForm extends React.Component {
initialValue
:
editCrmInfo
.
source_type
?
editCrmInfo
.
source_type
:
undefined
,
rules
:
[{
required
:
true
,
message
:
'来源渠道不能为空'
}],
})(
<
Select
style
=
{{
width
:
260
}}
placeholder
=
"请选择"
>
<
Select
disabled
=
{
editCrmInfo
.
id
}
style
=
{{
width
:
260
}}
placeholder
=
"请选择"
>
<
Option
value
=
{
1
}
>
在线购买
<
/Option
>
<
Option
value
=
{
2
}
>
在线招生
<
/Option
>
<
Option
value
=
{
3
}
>
来电咨询
<
/Option
>
...
...
@@ -249,7 +243,6 @@ class AddCrmForm extends React.Component {
<
FormItem
{...
formItemLayout
}
label
=
"意向课程"
>
{
getFieldDecorator
(
'intent_course_id'
,
{
initialValue
:
editCrmInfo
.
intent_course_id
?
editCrmInfo
.
intent_course_id
:
undefined
,
rules
:
[{
required
:
true
,
message
:
'意向课程不能为空'
}],
})(
<
Select
style
=
{{
width
:
260
}}
placeholder
=
"请选择"
>
{
courseList
.
map
(
ele
=>
<
Option
value
=
{
ele
.
id
}
>
{
ele
.
title
}
<
/Option>
)
}
...
...
src/pages/crm/ChangeStatusModal.js
0 → 100644
View file @
d6d9fddf
import
{
connect
}
from
'dva'
;
import
React
from
'react'
;
import
PropTypes
from
'prop-types'
;
import
{
message
,
Row
,
Col
,
Input
,
Select
,
Modal
,
Form
,
InputNumber
,
Checkbox
,
Radio
,
Tabs
}
from
'antd'
;
import
{
imagify
,
pageIn
}
from
'../../utils/index'
;
const
FormItem
=
Form
.
Item
;
const
{
TabPane
}
=
Tabs
;
const
{
TextArea
}
=
Input
;
const
{
Option
}
=
Select
;
class
ChangeStatusModal
extends
React
.
Component
{
componentDidMount
()
{
// 挂载
}
componentWillUnmount
()
{
// 卸载
}
save
=
()
=>
{
const
{
form
,
save
}
=
this
.
props
;
form
.
validateFields
((
err
,
values
)
=>
{
if
(
!
err
)
{
const
{
status
,
}
=
values
;
save
({
status
,
callBack
:
()
=>
{
form
.
resetFields
();
},
});
}
});
}
close
=
()
=>
{
const
{
form
,
close
}
=
this
.
props
;
form
.
resetFields
();
close
();
}
render
()
{
const
{
visible
,
loading
,
status
,
form
:
{
getFieldDecorator
,
getFieldValue
},
}
=
this
.
props
;
const
formItemModalLineLayout
=
{
labelCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
5
},
},
wrapperCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
19
},
},
};
return
(
<
Modal
visible
=
{
visible
}
title
=
"跟进状态"
okText
=
"保存"
confirmLoading
=
{
loading
}
onCancel
=
{
this
.
close
}
onOk
=
{
this
.
save
}
maskClosable
=
{
false
}
zIndex
=
{
110
}
width
=
{
500
}
bodyStyle
=
{{
padding
:
20
}}
>
<
Form
hideRequiredMark
labelAlign
=
"left"
>
<
FormItem
label
=
"当前跟进状态"
{...
formItemModalLineLayout
}
>
{
getFieldDecorator
(
'status'
,
{
initialValue
:
Number
(
status
),
rules
:
[{
required
:
true
,
message
:
'当前跟进状态不能为空'
}],
})(
<
Select
style
=
{{
width
:
260
}}
placeholder
=
"请选择"
>
<
Option
value
=
{
1
}
>
待跟进
<
/Option
>
<
Option
value
=
{
2
}
>
跟进中
<
/Option
>
<
Option
value
=
{
3
}
>
已完成
<
/Option
>
<
Option
value
=
{
4
}
>
无效
<
/Option
>
<
/Select>
,
)}
<
/FormItem
>
<
/Form
>
<
/Modal
>
);
}
}
const
ChangeStatus
=
Form
.
create
()(
ChangeStatusModal
);
export
default
ChangeStatus
;
src/pages/crm/index.js
View file @
d6d9fddf
...
...
@@ -22,6 +22,8 @@ import moment from 'moment';
import
{
routerRedux
}
from
'dva/router'
;
import
pageStyle
from
'./index.less'
;
import
{
pageIn
,
hasBtnPower
,
btnPermission
}
from
'../../utils/index'
;
import
ChangeStatusModal
from
'./ChangeStatusModal'
;
import
RenewEdit
from
'../student/RenewEdit'
;
import
BtnPermission
from
'../../components/BtnPermission'
;
const
{
Option
}
=
Select
;
const
{
TextArea
}
=
Input
;
...
...
@@ -68,7 +70,6 @@ class Crm extends React.Component {
}
searchParamsChange
=
(
e
,
type
,
key
)
=>
{
const
{
dispatch
}
=
this
.
props
;
console
.
log
(
e
,
'11'
);
let
getvalue
=
''
;
if
(
type
==
'Input'
)
{
getvalue
=
e
;
...
...
@@ -130,12 +131,99 @@ class Crm extends React.Component {
},
});
}
handleChangeStatus
=
(
record
)
=>
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'crm/updateState'
,
payload
:
{
statusVisible
:
true
,
checkedStatus
:
record
.
status
,
cluesId
:
record
.
id
,
},
});
}
closeStatusModal
=
()
=>
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'crm/updateState'
,
payload
:
{
statusVisible
:
false
,
checkedStatus
:
1
,
cluesId
:
0
,
},
});
}
saveStatus
=
(
values
)
=>
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'crm/saveStatus'
,
payload
:
values
,
});
}
goBuyCourse
=
(
record
)
=>
{
const
{
dispatch
,
schoolUserInfo
}
=
this
.
props
;
console
.
log
(
record
,
'record'
);
dispatch
({
type
:
'crm/updateState'
,
payload
:
{
goRenewCourseShow
:
true
,
operator
:
{
...
schoolUserInfo
},
studentInfo
:
{
...
record
},
},
});
}
searchCourseRelateClass
=
(
courseId
,
callBack
)
=>
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'crm/searchCourseRelateClass'
,
payload
:
{
courseId
,
callBack
:
callBack
||
''
,
},
});
}
closeEditClassModal
=
()
=>
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'crm/updateState'
,
payload
:
{
goRenewCourseShow
:
false
,
studentInfo
:
{},
operator
:
{
id
:
''
,
nickname
:
''
,
},
},
});
}
sureRenewCourse
=
(
values
,
callBack
)
=>
{
const
{
dispatch
}
=
this
.
props
;
dispatch
({
type
:
'crm/studentModelCoursesBuyOrRenew'
,
payload
:
{
values
:
{
...
values
,
buy
:
values
.
buy
||
0
,
give
:
values
.
give
||
0
,
},
callBack
,
},
});
}
render
()
{
const
{
userPermission
,
crmList
,
crmTotal
,
crmParams
,
statusVisible
,
checkedStatus
,
statusLoading
,
goRenewCourseShow
,
courseRelateClassList
,
courseList
,
operator
,
schoolUserInfo
,
}
=
this
.
props
;
const
{
isExpendMore
}
=
this
.
state
;
const
columns
=
[
...
...
@@ -222,8 +310,6 @@ class Crm extends React.Component {
return
'已完成'
;
case
4
:
return
'无效'
;
case
5
:
return
'已成功'
;
default
:
return
'-'
;
}
...
...
@@ -246,9 +332,9 @@ class Crm extends React.Component {
render
:
(
text
,
record
)
=>
{
return
(
<
div
className
=
{
pageStyle
.
tableoperatebox
}
>
<
span
className
=
"hreflink"
>
购课
<
/span
>
<
span
className
=
"hreflink"
onClick
=
{()
=>
this
.
goBuyCourse
(
record
)}
>
购课
<
/span
>
<
Divider
type
=
"vertical"
/>
<
span
className
=
"hreflink"
>
跟进
<
/span
>
<
span
className
=
"hreflink"
onClick
=
{()
=>
this
.
handleChangeStatus
(
record
)}
>
跟进
<
/span
>
<
/div
>
);
},
...
...
@@ -290,10 +376,8 @@ class Crm extends React.Component {
<
Option
value
=
""
>
全部
<
/Option
>
<
Option
value
=
{
1
}
>
待跟进
<
/Option
>
<
Option
value
=
{
2
}
>
跟进中
<
/Option
>
<
Option
value
=
{
3
}
>
已邀约
<
/Option
>
<
Option
value
=
{
4
}
>
已试听
<
/Option
>
<
Option
value
=
{
5
}
>
已完成
<
/Option
>
<
Option
value
=
{
6
}
>
无效
<
/Option
>
<
Option
value
=
{
3
}
>
已完成
<
/Option
>
<
Option
value
=
{
4
}
>
无效
<
/Option
>
<
/Select
>
<
/Col
>
{
...
...
@@ -361,6 +445,23 @@ class Crm extends React.Component {
/
>
<
/div
>
<
/div
>
<
ChangeStatusModal
visible
=
{
statusVisible
}
close
=
{
this
.
closeStatusModal
}
status
=
{
checkedStatus
}
save
=
{
this
.
saveStatus
}
loading
=
{
statusLoading
}
/
>
<
RenewEdit
visible
=
{
goRenewCourseShow
}
searchCourseRelateClass
=
{
this
.
searchCourseRelateClass
}
classList
=
{
courseRelateClassList
}
renewCourses
=
{
courseList
}
operator
=
{
operator
}
close
=
{
this
.
closeEditClassModal
}
save
=
{
this
.
sureRenewCourse
}
isOperator
/>
<
/div
>
);
}
...
...
@@ -375,6 +476,13 @@ function mapStateToProps(state) {
crmList
,
crmTotal
,
crmParams
,
statusVisible
,
checkedStatus
,
statusLoading
,
goRenewCourseShow
,
courseRelateClassList
,
courseList
,
operator
,
}
=
state
.
crm
;
const
{
guideStep
,
...
...
@@ -382,6 +490,7 @@ function mapStateToProps(state) {
}
=
state
.
userguide
;
const
{
userPermission
,
schoolUserInfo
,
}
=
state
.
webapp
;
return
{
userPermission
,
...
...
@@ -390,6 +499,14 @@ function mapStateToProps(state) {
crmList
,
crmTotal
,
crmParams
,
statusVisible
,
checkedStatus
,
statusLoading
,
goRenewCourseShow
,
courseRelateClassList
,
courseList
,
operator
,
schoolUserInfo
,
};
}
export
default
connect
(
mapStateToProps
)(
CrmForm
);
...
...
src/pages/crmdetail/AddLogModal.js
0 → 100644
View file @
d6d9fddf
import
{
connect
}
from
'dva'
;
import
React
from
'react'
;
import
PropTypes
from
'prop-types'
;
import
{
message
,
Row
,
Col
,
Input
,
Select
,
Modal
,
Form
,
InputNumber
,
Checkbox
,
Radio
,
Tabs
}
from
'antd'
;
import
{
imagify
,
pageIn
}
from
'../../utils/index'
;
const
FormItem
=
Form
.
Item
;
const
{
TabPane
}
=
Tabs
;
const
{
TextArea
}
=
Input
;
class
AddLogModal
extends
React
.
Component
{
componentDidMount
()
{
// 挂载
}
componentWillUnmount
()
{
// 卸载
}
save
=
()
=>
{
const
{
form
,
save
}
=
this
.
props
;
form
.
validateFields
((
err
,
values
)
=>
{
if
(
!
err
)
{
const
{
content
,
type
,
}
=
values
;
save
({
content
,
type
,
callBack
:
()
=>
{
form
.
resetFields
();
},
});
}
});
}
close
=
()
=>
{
const
{
form
,
close
}
=
this
.
props
;
form
.
resetFields
();
close
();
}
render
()
{
const
{
visible
,
loading
,
form
:
{
getFieldDecorator
,
getFieldValue
},
}
=
this
.
props
;
const
formItemModalLineLayout
=
{
labelCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
4
},
},
wrapperCol
:
{
xs
:
{
span
:
24
},
sm
:
{
span
:
20
},
},
};
return
(
<
Modal
visible
=
{
visible
}
title
=
"添加跟进记录"
okText
=
"发布"
confirmLoading
=
{
loading
}
onCancel
=
{
this
.
close
}
onOk
=
{
this
.
save
}
maskClosable
=
{
false
}
zIndex
=
{
110
}
width
=
{
500
}
bodyStyle
=
{{
padding
:
20
}}
>
<
Form
hideRequiredMark
labelAlign
=
"left"
>
<
FormItem
label
=
"结果情况"
{...
formItemModalLineLayout
}
>
{
getFieldDecorator
(
'content'
,
{
initialValue
:
''
,
rules
:
[{
required
:
true
,
message
:
'结果情况不能为空'
}],
})(
<
TextArea
rows
=
{
4
}
placeholder
=
"请输入跟进的结果情况"
/>
,
)}
<
/FormItem
>
<
FormItem
label
=
"沟通方式"
{...
formItemModalLineLayout
}
>
{
getFieldDecorator
(
'type'
,
{
initialValue
:
'1'
,
rules
:
[{
required
:
true
,
message
:
'沟通方式不能为空'
}],
})(
<
Radio
.
Group
>
<
Radio
value
=
"1"
>
微信沟通
<
/Radio
>
<
Radio
value
=
"2"
>
电话沟通
<
/Radio
>
<
/Radio.Group>
,
)}
<
/FormItem
>
<
/Form
>
<
/Modal
>
);
}
}
const
AddLog
=
Form
.
create
()(
AddLogModal
);
export
default
AddLog
;
src/pages/crmdetail/index.js
View file @
d6d9fddf
This diff is collapsed.
Click to expand it.
src/pages/crmdetail/index.less
View file @
d6d9fddf
@import '../../less/variables.less';
.container {
background-color: #fff;
border-radius: 2px;
padding: 20px;
}
.headerbox{
background-color: #fff;
.headerbtn {
margin: 0 16px 0 0;
.headBox {
display: flex;
align-items: flex-start;
.leftBox {
width: 56px;
height: 56px;
margin-right: 30px;
&>img {
width: 56px;
height: 56px;
}
}
padding-bottom: 18px;
}
.searchrow {
.formitem {
display: flex;
align-items: center;
margin-bottom: 16px;
.formitemlabel {
color: #000000;
font-size: 14px;
line-height: 1;
min-width: 70px;
white-space: nowrap;
.rightBox {
width: calc(100% - 90px);
:global {
.ant-descriptions-row > th, .ant-descriptions-row > td {
padding-bottom: 10px;
}
}
.rightTop {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
.rightName {
font-size: 15px;
&>span {
font-weight:500;
color:rgba(55,55,55,1);
font-family:PingFangSC-Medium,PingFang SC;
display: inline-block;
margin-right: 10px;
}
}
.btn {
padding: 0 15px;
&:first-child {
margin-right: 10px;
}
}
}
}
}
.selectitem {
display: block;
}
.searchbtnbox {
height: 54px;
display: flex;
align-items: flex-end;
}
.resetbtn {
margin-right: 16px;
}
.tablebox {
background: #fff;
.tableWrap {
margin-top: 2px;
:global {
.ant-table-fixed {
border-bottom: 1px solid #E8E8E8 !important;
}
.ant-table tbody tr:nth-child(2n) {
background-color: #FBFBFB;
}
.ant-table-thead > tr > th, .ant-table-tbody > tr > td {
padding: 11px 1
0
px;
padding: 11px 1
6
px;
}
.ant-table-bordered .ant-table-tbody tr td {
border-bottom: none;
...
...
@@ -56,6 +62,9 @@
border-bottom: none;
border-right: none!important;
}
.ant-table-bordered table {
border-bottom: 1px solid #e8e8e8!important;;
}
.ant-table-bordered .ant-table-thead tr th:last-child {
border-right: 1px solid #e8e8e8!important;
}
...
...
@@ -65,122 +74,43 @@
.ant-table-bordered .ant-table-tbody tr:last-child {
border-bottom: 1px solid #e8e8e8!important;
}
.tablefooterbox {
padding: 12px 0 12px 0;
margin-top: 10px;
.tablefooterstatic {
font-size: 16px;
color: #555555;
}
display: flex;
align-items: center;
justify-content: space-between;
}
}
}
.divideline {
color: #E9E9E9;
padding: 0 8px;
}
.alink {
color: #1890FF;
}
.classNamebox {
max-width: 250px;
word-break: break-all;
color: #1890FF;
cursor: pointer;
// background-color: #fff;
}
.tableoperatebox {
min-width: 160px;
line-height: 30px;
}
.endsearchcol {
margin-bottom: 18px;
}
.endclassfooter {
.dynamicHead {
display: flex;
align-items: center;
justify-content: space-between;
}
.classroomitem {
margin-bottom: 5px;
.classroom {
color:rgba(0,0,0,0.85);
}
.aLink {
color: #1890FF;
padding-left: 21px;
margin-bottom: 16px;
.dynamicSelect {
margin-left: 50px;
&>span {
font-size:13px;
font-family:PingFangSC-Regular,PingFang SC;
font-weight:400;
color:rgba(102,102,102,1);
display: inline-block;
margin-right: 5px;
}
}
}
.activeamount{
background-color: #cccccc;
color: #666666;
text-align: center;
line-height: 50px;
font-size: 20px;
.logitem{
margin: 20px 0;
word-break: break-all;
}
.rightList {
display: flex;
align-items: center;
height: 32px;
.resetIcon {
width: 14px;
height: 14px;
cursor: pointer;
margin-right: 15px;
}
.expend {
font-size:13px;
font-family:PingFangSC-Regular,PingFang SC;
font-weight:400;
color:rgba(102,102,102,1);
display: inline-block;
cursor: pointer;
}
.logTeacherName {
font-weight: 700;
}
.tablefooterbox {
color: rgba(0,0,0,0.6);
font-size: 16px;
line-height: 50px;
display: flex;
background-color: #fff;
align-items: center;
justify-content: space-between;
padding-left: 14px;
padding-right: 14px;
margin-top: 10px;
.tablefooterstatic {
color:rgba(0,0,0,0.65);
font-size: 14px;
}
}
.tabList {
display: flex;
border-bottom: 1px solid #E8E8E8;
margin-bottom: 18px;
.tabItem {
font-size:13px;
font-weight:400;
color:rgba(102,102,102,1);
line-height:18px;
padding: 0 30px 10px;
cursor: pointer;
position: relative;
&:hover {
font-weight:600;
color:#1890FF;
}
}
.tabItemActive {
font-size:13px;
font-weight:600;
color:#1890FF;
line-height:18px;
padding: 0 30px 10px;
cursor: pointer;
position: relative;
font-family:PingFangSC-Semibold,PingFang SC;
&:after {
content: '';
display: block;
width: 30%;
height: 2px;
background-color: #1890FF;
position: absolute;
bottom: 0;
left: 35%;
}
}
.logAction {
color: #108EE9;
font-weight: 700;
}
src/pages/student/RenewEdit.js
View file @
d6d9fddf
...
...
@@ -129,6 +129,7 @@ class RenewEdit extends React.Component {
renewCourses
,
operator
,
toChangeOperator
,
isOperator
,
}
=
this
.
props
;
const
{
selectedCourse
,
modeType
,
mybuyCourse
}
=
this
.
state
;
const
{
getFieldDecorator
}
=
this
.
props
.
form
;
...
...
@@ -141,6 +142,7 @@ class RenewEdit extends React.Component {
onOk
=
{
this
.
renewCourse
}
className
=
"modifyclassModal"
zIndex
=
{
110
}
maskClosable
=
{
false
}
>
<
Form
className
=
"modalform"
hideRequiredMark
>
<
div
className
=
{
pageStyle
.
courseinfo
}
>
...
...
@@ -381,7 +383,7 @@ class RenewEdit extends React.Component {
})(
<
span
>
{
operator
.
nickname
}
<
/span>
,
)}
<
span
className
=
{
`hreflink
${
pageStyle
.
changeOperate
}
`
}
onClick
=
{()
=>
toChangeOperator
(
true
)}
>
修改
<
/span
>
{
!
isOperator
&&
<
span
className
=
{
`hreflink
${
pageStyle
.
changeOperate
}
`
}
onClick
=
{()
=>
toChangeOperator
(
true
)}
>
修改
<
/span>
}
<
/Form.Item
>
<
/Col
>
<
/Row
>
...
...
src/router.js
View file @
d6d9fddf
...
...
@@ -296,6 +296,7 @@ function RouterConfig({ history }) {
<
Route
path
=
"/sjd/crm"
exact
component
=
{
Crm
}
/
>
<
Route
path
=
"/sjd/addcrm"
exact
component
=
{
AddCrm
}
/
>
<
Route
path
=
"/sjd/crmdetail/:id"
exact
component
=
{
CrmDetail
}
/
>
<
Route
path
=
"/sjd/editcrm/:id"
exact
component
=
{
AddCrm
}
/
>
<
Route
component
=
{
Errorpage
}
/
>
<
/Switch
>
<
/SjdIndex
>
...
...
src/services/crm.js
View file @
d6d9fddf
...
...
@@ -24,3 +24,31 @@ export function crmEdit(params) {
data
,
});
}
export
function
crmDetail
(
params
)
{
return
request
({
url
:
`
${
api
.
crm
.
crmList
}
/
${
params
.
id
}
`
,
method
:
'GET'
,
});
}
export
function
addClueRecords
(
params
)
{
const
data
=
qs
.
stringify
(
params
);
return
request
({
url
:
`
${
api
.
crm
.
clue_records
}
`
,
method
:
'POST'
,
data
,
});
}
export
function
clueList
(
params
)
{
const
data
=
qs
.
stringify
(
params
);
return
request
({
url
:
`
${
api
.
crm
.
clue_records
}
?
${
data
}
`
,
method
:
'GET'
,
});
}
export
function
logsList
(
params
)
{
const
data
=
qs
.
stringify
(
params
);
return
request
({
url
:
`
${
api
.
crm
.
clue_logs
}
?
${
data
}
`
,
method
:
'GET'
,
});
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
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 comment