Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
64af029c
authored
Apr 11, 2024
by
puhui999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
CRM: 完善用户画像数据统计
parent
f6e4753b
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
34 additions
and
36 deletions
+34
-36
.env.local-dev
+0
-0
package.json
+3
-3
src/components/DictSelect/src/DictSelect.vue
+0
-1
src/views/crm/statistics/portrait/components/CrmStatisticsPortraitCustomerArea.vue
+11
-13
src/views/crm/statistics/portrait/components/CrmStatisticsPortraitCustomerIndustry.vue
+4
-3
src/views/crm/statistics/portrait/components/CrmStatisticsPortraitCustomerLevel.vue
+4
-4
src/views/crm/statistics/portrait/components/CrmStatisticsPortraitCustomerSource.vue
+4
-3
src/views/crm/statistics/portrait/index.vue
+8
-9
No files found.
.env.local
→
.env.local
-dev
View file @
64af029c
File moved
package.json
View file @
64af029c
...
...
@@ -6,11 +6,11 @@
"private"
:
false
,
"scripts"
:
{
"i"
:
"pnpm install"
,
"
dev
"
:
"vite --mode local-dev"
,
"
local-server
"
:
"vite --mode local-dev"
,
"dev-server"
:
"vite --mode dev"
,
"ts:check"
:
"vue-tsc --noEmit"
,
"build:local
-dev
"
:
"node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode local-dev"
,
"build:dev"
:
"node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode
local-
dev"
,
"build:local"
:
"node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode local-dev"
,
"build:dev"
:
"node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode dev"
,
"build:test"
:
"node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode test"
,
"build:stage"
:
"node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode stage"
,
"build:prod"
:
"node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode prod"
,
...
...
src/components/DictSelect/src/DictSelect.vue
View file @
64af029c
...
...
@@ -33,7 +33,6 @@ import { getBoolDictOptions, getIntDictOptions, getStrDictOptions } from '@/util
// 接受父组件参数
interface
Props
{
modelValue
?:
any
// 值
dictType
:
string
// 字典类型
valueType
:
string
// 字典值类型
}
...
...
src/views/crm/statistics/portrait/components/C
ustomerAddress
.vue
→
src/views/crm/statistics/portrait/components/C
rmStatisticsPortraitCustomerArea
.vue
View file @
64af029c
...
...
@@ -25,8 +25,7 @@ import {
StatisticsPortraitApi
}
from
'@/api/crm/statistics/portrait'
// TODO @puhui999:address 换成 area 会更合适哈,
defineOptions
({
name
:
'CustomerAddress'
})
defineOptions
({
name
:
'CustomerArea'
})
const
props
=
defineProps
<
{
queryParams
:
any
}
>
()
// 搜索参数
// 注册地图
...
...
@@ -107,22 +106,21 @@ const loadData = async () => {
areaStatisticsList
.
value
=
areaList
.
map
((
item
:
CrmStatisticCustomerAreaRespVO
)
=>
{
return
{
...
item
,
areaName
:
item
.
areaName
// TODO @puhui999:这里最好注释下原因哈
.
replace
(
'维吾尔自治区'
,
''
)
.
replace
(
'壮族自治区'
,
''
)
.
replace
(
'回族自治区'
,
''
)
.
replace
(
'自治区'
,
''
)
.
replace
(
'省'
,
''
)
areaName
:
item
.
areaName
// TODO @puhui999:这里最好注释下原因哈
, 🤣 我从 mall copy 过来的
//
.replace('维吾尔自治区', '')
//
.replace('壮族自治区', '')
//
.replace('回族自治区', '')
//
.replace('自治区', '')
//
.replace('省', '')
}
})
build
er
LeftMap
()
build
er
RightMap
()
buildLeftMap
()
buildRightMap
()
loading
.
value
=
false
}
defineExpose
({
loadData
})
// TODO @puhui999:builder 改成 build 更合理哈
const
builderLeftMap
=
()
=>
{
const
buildLeftMap
=
()
=>
{
let
min
=
0
let
max
=
0
echartsOption
.
series
!
[
0
].
data
=
areaStatisticsList
.
value
.
map
((
item
)
=>
{
...
...
@@ -134,7 +132,7 @@ const builderLeftMap = () => {
echartsOption
.
visualMap
!
[
'max'
]
=
max
}
const
build
er
RightMap
=
()
=>
{
const
buildRightMap
=
()
=>
{
let
min
=
0
let
max
=
0
echartsOption2
.
series
!
[
0
].
data
=
areaStatisticsList
.
value
.
map
((
item
)
=>
{
...
...
src/views/crm/statistics/portrait/components/CustomerIndustry.vue
→
src/views/crm/statistics/portrait/components/C
rmStatisticsPortraitC
ustomerIndustry.vue
View file @
64af029c
...
...
@@ -39,7 +39,7 @@ import {
}
from
'@/api/crm/statistics/portrait'
import
{
EChartsOption
}
from
'echarts'
import
{
DICT_TYPE
,
getDictLabel
}
from
'@/utils/dict'
import
{
getSumValue
}
from
'@/utils'
import
{
erpCalculatePercentage
,
getSumValue
}
from
'@/utils'
import
{
isEmpty
}
from
'@/utils/is'
defineOptions
({
name
:
'CustomerIndustry'
})
...
...
@@ -185,8 +185,9 @@ const calculateProportion = (sourceList: CrmStatisticCustomerIndustryRespVO[]) =
const
sumDealCount
=
getSumValue
(
list
.
map
((
item
)
=>
item
.
dealCount
))
list
.
forEach
((
item
)
=>
{
item
.
industryPortion
=
item
.
customerCount
===
0
?
0
:
((
item
.
customerCount
/
sumCustomerCount
)
*
100
).
toFixed
(
2
)
item
.
dealPortion
=
item
.
dealCount
===
0
?
0
:
((
item
.
dealCount
/
sumDealCount
)
*
100
).
toFixed
(
2
)
item
.
customerCount
===
0
?
0
:
erpCalculatePercentage
(
item
.
customerCount
,
sumCustomerCount
)
item
.
dealPortion
=
item
.
dealCount
===
0
?
0
:
erpCalculatePercentage
(
item
.
dealCount
,
sumDealCount
)
})
}
...
...
src/views/crm/statistics/portrait/components/CustomerLevel.vue
→
src/views/crm/statistics/portrait/components/C
rmStatisticsPortraitC
ustomerLevel.vue
View file @
64af029c
...
...
@@ -39,7 +39,7 @@ import {
}
from
'@/api/crm/statistics/portrait'
import
{
EChartsOption
}
from
'echarts'
import
{
DICT_TYPE
,
getDictLabel
}
from
'@/utils/dict'
import
{
getSumValue
}
from
'@/utils'
import
{
erpCalculatePercentage
,
getSumValue
}
from
'@/utils'
import
{
isEmpty
}
from
'@/utils/is'
defineOptions
({
name
:
'CustomerSource'
})
...
...
@@ -184,10 +184,10 @@ const calculateProportion = (levelList: CrmStatisticCustomerLevelRespVO[]) => {
const
sumCustomerCount
=
getSumValue
(
list
.
map
((
item
)
=>
item
.
customerCount
))
const
sumDealCount
=
getSumValue
(
list
.
map
((
item
)
=>
item
.
dealCount
))
list
.
forEach
((
item
)
=>
{
// TODO @puhui999:可以使用 erpCalculatePercentage 方法
item
.
levelPortion
=
item
.
customerCount
===
0
?
0
:
((
item
.
customerCount
/
sumCustomerCount
)
*
100
).
toFixed
(
2
)
item
.
dealPortion
=
item
.
dealCount
===
0
?
0
:
((
item
.
dealCount
/
sumDealCount
)
*
100
).
toFixed
(
2
)
item
.
customerCount
===
0
?
0
:
erpCalculatePercentage
(
item
.
customerCount
,
sumCustomerCount
)
item
.
dealPortion
=
item
.
dealCount
===
0
?
0
:
erpCalculatePercentage
(
item
.
dealCount
,
sumDealCount
)
})
}
...
...
src/views/crm/statistics/portrait/components/CustomerSource.vue
→
src/views/crm/statistics/portrait/components/C
rmStatisticsPortraitC
ustomerSource.vue
View file @
64af029c
...
...
@@ -40,7 +40,7 @@ import {
import
{
EChartsOption
}
from
'echarts'
import
{
DICT_TYPE
,
getDictLabel
}
from
'@/utils/dict'
import
{
isEmpty
}
from
'@/utils/is'
import
{
getSumValue
}
from
'@/utils'
import
{
erpCalculatePercentage
,
getSumValue
}
from
'@/utils'
defineOptions
({
name
:
'CustomerSource'
})
const
props
=
defineProps
<
{
queryParams
:
any
}
>
()
// 搜索参数
...
...
@@ -185,8 +185,9 @@ const calculateProportion = (sourceList: CrmStatisticCustomerSourceRespVO[]) =>
const
sumDealCount
=
getSumValue
(
list
.
map
((
item
)
=>
item
.
dealCount
))
list
.
forEach
((
item
)
=>
{
item
.
sourcePortion
=
item
.
customerCount
===
0
?
0
:
((
item
.
customerCount
/
sumCustomerCount
)
*
100
).
toFixed
(
2
)
item
.
dealPortion
=
item
.
dealCount
===
0
?
0
:
((
item
.
dealCount
/
sumDealCount
)
*
100
).
toFixed
(
2
)
item
.
customerCount
===
0
?
0
:
erpCalculatePercentage
(
item
.
customerCount
,
sumCustomerCount
)
item
.
dealPortion
=
item
.
dealCount
===
0
?
0
:
erpCalculatePercentage
(
item
.
dealCount
,
sumDealCount
)
})
}
...
...
src/views/crm/statistics/portrait/index.vue
View file @
64af029c
...
...
@@ -61,19 +61,19 @@
<el-tabs
v-model=
"activeTab"
>
<!-- 城市分布分析 -->
<el-tab-pane
label=
"城市分布分析"
lazy
name=
"addressRef"
>
<C
ustomerAddress
ref=
"addressRef"
:query-params=
"queryParams"
/>
<C
rmStatisticsPortraitCustomerArea
ref=
"addressRef"
:query-params=
"queryParams"
/>
</el-tab-pane>
<!-- 客户级别分析 -->
<el-tab-pane
label=
"客户级别分析"
lazy
name=
"levelRef"
>
<CustomerLevel
ref=
"levelRef"
:query-params=
"queryParams"
/>
<C
rmStatisticsPortraitC
ustomerLevel
ref=
"levelRef"
:query-params=
"queryParams"
/>
</el-tab-pane>
<!-- 客户来源分析 -->
<el-tab-pane
label=
"客户来源分析"
lazy
name=
"sourceRef"
>
<CustomerSource
ref=
"sourceRef"
:query-params=
"queryParams"
/>
<C
rmStatisticsPortraitC
ustomerSource
ref=
"sourceRef"
:query-params=
"queryParams"
/>
</el-tab-pane>
<!-- 客户行业分析 -->
<el-tab-pane
label=
"客户行业分析"
lazy
name=
"industryRef"
>
<CustomerIndustry
ref=
"industryRef"
:query-params=
"queryParams"
/>
<C
rmStatisticsPortraitC
ustomerIndustry
ref=
"industryRef"
:query-params=
"queryParams"
/>
</el-tab-pane>
</el-tabs>
</el-col>
...
...
@@ -85,11 +85,10 @@ import * as UserApi from '@/api/system/user'
import
{
useUserStore
}
from
'@/store/modules/user'
import
{
beginOfDay
,
defaultShortcuts
,
endOfDay
,
formatDate
}
from
'@/utils/formatTime'
import
{
defaultProps
,
handleTree
}
from
'@/utils/tree'
// TODO @puhui999:最好命名带上模块名,如:CrmStatisticsPortrait
import
CustomerAddress
from
'./components/CustomerAddress.vue'
import
CustomerIndustry
from
'./components/CustomerIndustry.vue'
import
CustomerSource
from
'./components/CustomerSource.vue'
import
CustomerLevel
from
'./components/CustomerLevel.vue'
import
CrmStatisticsPortraitCustomerArea
from
'./components/CrmStatisticsPortraitCustomerArea.vue'
import
CrmStatisticsPortraitCustomerIndustry
from
'./components/CrmStatisticsPortraitCustomerIndustry.vue'
import
CrmStatisticsPortraitCustomerSource
from
'./components/CrmStatisticsPortraitCustomerSource.vue'
import
CrmStatisticsPortraitCustomerLevel
from
'./components/CrmStatisticsPortraitCustomerLevel.vue'
defineOptions
({
name
:
'CrmStatisticsPortrait'
})
...
...
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