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
a2443e48
authored
Feb 21, 2024
by
YunaiV
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
✨
CRM:完善商机的列表
parent
08bb022c
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
260 additions
and
18 deletions
+260
-18
src/api/crm/product/index.ts
+5
-0
src/views/crm/business/BusinessForm.vue
+0
-0
src/views/crm/business/components/BusinessProductForm.vue
+183
-0
src/views/crm/business/index.vue
+69
-9
src/views/crm/contact/ContactForm.vue
+0
-2
src/views/crm/product/ProductForm.vue
+1
-6
src/views/crm/product/index.vue
+2
-1
No files found.
src/api/crm/product/index.ts
View file @
a2443e48
...
@@ -23,6 +23,11 @@ export const getProductPage = async (params) => {
...
@@ -23,6 +23,11 @@ export const getProductPage = async (params) => {
return
await
request
.
get
({
url
:
`/crm/product/page`
,
params
})
return
await
request
.
get
({
url
:
`/crm/product/page`
,
params
})
}
}
// 获得产品精简列表
export
const
getProductSimpleList
=
async
()
=>
{
return
await
request
.
get
({
url
:
`/crm/product/simple-list`
})
}
// 查询产品详情
// 查询产品详情
export
const
getProduct
=
async
(
id
:
number
)
=>
{
export
const
getProduct
=
async
(
id
:
number
)
=>
{
return
await
request
.
get
({
url
:
`/crm/product/get?id=`
+
id
})
return
await
request
.
get
({
url
:
`/crm/product/get?id=`
+
id
})
...
...
src/views/crm/business/BusinessForm.vue
View file @
a2443e48
This diff is collapsed.
Click to expand it.
src/views/crm/business/components/BusinessProductForm.vue
0 → 100644
View file @
a2443e48
<
template
>
<el-form
ref=
"formRef"
:model=
"formData"
:rules=
"formRules"
v-loading=
"formLoading"
label-width=
"0px"
:inline-message=
"true"
:disabled=
"disabled"
>
<el-table
:data=
"formData"
class=
"-mt-10px"
>
<el-table-column
label=
"序号"
type=
"index"
align=
"center"
width=
"60"
/>
<el-table-column
label=
"产品名称"
min-width=
"180"
>
<template
#
default=
"
{ row, $index }">
<el-form-item
:prop=
"`$
{$index}.productId`" :rules="formRules.productId" class="mb-0px!">
<el-select
v-model=
"row.productId"
clearable
filterable
@
change=
"onChangeProduct($event, row)"
placeholder=
"请选择产品"
>
<el-option
v-for=
"item in productList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
</el-select>
</el-form-item>
</
template
>
</el-table-column>
<el-table-column
label=
"条码"
min-width=
"150"
>
<
template
#
default=
"{ row }"
>
<el-form-item
class=
"mb-0px!"
>
<el-input
disabled
v-model=
"row.productNo"
/>
</el-form-item>
</
template
>
</el-table-column>
<el-table-column
label=
"单位"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
<dict-tag
:type=
"DICT_TYPE.CRM_PRODUCT_UNIT"
:value=
"row.productUnit"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"价格(元)"
min-width=
"120"
>
<
template
#
default=
"{ row }"
>
<el-form-item
class=
"mb-0px!"
>
<el-input
disabled
v-model=
"row.productPrice"
:formatter=
"erpPriceInputFormatter"
/>
</el-form-item>
</
template
>
</el-table-column>
<el-table-column
label=
"售价(元)"
fixed=
"right"
min-width=
"140"
>
<
template
#
default=
"{ row, $index }"
>
<el-form-item
:prop=
"`$
{$index}.businessPrice`" class="mb-0px!">
<el-input-number
v-model=
"row.businessPrice"
controls-position=
"right"
:min=
"0.001"
:precision=
"2"
class=
"!w-100%"
/>
</el-form-item>
</
template
>
</el-table-column>
<el-table-column
label=
"数量"
prop=
"count"
fixed=
"right"
min-width=
"120"
>
<
template
#
default=
"{ row, $index }"
>
<el-form-item
:prop=
"`$
{$index}.count`" :rules="formRules.count" class="mb-0px!">
<el-input-number
v-model=
"row.count"
controls-position=
"right"
:min=
"0.001"
:precision=
"3"
class=
"!w-100%"
/>
</el-form-item>
</
template
>
</el-table-column>
<el-table-column
label=
"合计"
prop=
"totalPrice"
fixed=
"right"
min-width=
"140"
>
<
template
#
default=
"{ row, $index }"
>
<el-form-item
:prop=
"`$
{$index}.totalPrice`" class="mb-0px!">
<el-input
disabled
v-model=
"row.totalPrice"
:formatter=
"erpPriceInputFormatter"
/>
</el-form-item>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
fixed=
"right"
label=
"操作"
width=
"60"
>
<
template
#
default=
"{ $index }"
>
<el-button
@
click=
"handleDelete($index)"
link
>
—
</el-button>
</
template
>
</el-table-column>
</el-table>
</el-form>
<el-row
justify=
"center"
class=
"mt-3"
v-if=
"!disabled"
>
<el-button
@
click=
"handleAdd"
round
>
+ 添加产品
</el-button>
</el-row>
</template>
<
script
setup
lang=
"ts"
>
import
*
as
ProductApi
from
'@/api/crm/product'
import
{
erpCountInputFormatter
,
erpPriceInputFormatter
,
erpPriceMultiply
}
from
'@/utils'
import
{
DICT_TYPE
}
from
'@/utils/dict'
const
props
=
defineProps
<
{
products
:
undefined
disabled
:
false
}
>
()
const
formLoading
=
ref
(
false
)
// 表单的加载中
const
formData
=
ref
([])
const
formRules
=
reactive
({
productId
:
[{
required
:
true
,
message
:
'产品不能为空'
,
trigger
:
'blur'
}],
businessPrice
:
[{
required
:
true
,
message
:
'合同价格不能为空'
,
trigger
:
'blur'
}],
count
:
[{
required
:
true
,
message
:
'产品数量不能为空'
,
trigger
:
'blur'
}]
})
const
formRef
=
ref
([])
// 表单 Ref
const
productList
=
ref
<
ProductApi
.
ProductVO
[]
>
([])
// 产品列表
/** 初始化设置产品项 */
watch
(
()
=>
props
.
products
,
async
(
val
)
=>
{
formData
.
value
=
val
},
{
immediate
:
true
}
)
/** 监听合同产品变化,计算合同产品总价 */
watch
(
()
=>
formData
.
value
,
(
val
)
=>
{
if
(
!
val
||
val
.
length
===
0
)
{
return
}
// 循环处理
val
.
forEach
((
item
)
=>
{
if
(
item
.
businessPrice
!=
null
&&
item
.
count
!=
null
)
{
item
.
totalPrice
=
erpPriceMultiply
(
item
.
businessPrice
,
item
.
count
)
}
else
{
item
.
totalPrice
=
undefined
}
})
},
{
deep
:
true
}
)
/** 新增按钮操作 */
const
handleAdd
=
()
=>
{
const
row
=
{
id
:
undefined
,
productId
:
undefined
,
productUnit
:
undefined
,
// 产品单位
productNo
:
undefined
,
// 产品条码
productPrice
:
undefined
,
// 产品价格
businessPrice
:
undefined
,
count
:
1
}
formData
.
value
.
push
(
row
)
}
/** 删除按钮操作 */
const
handleDelete
=
(
index
:
number
)
=>
{
formData
.
value
.
splice
(
index
,
1
)
}
/** 处理产品变更 */
const
onChangeProduct
=
(
productId
,
row
)
=>
{
const
product
=
productList
.
value
.
find
((
item
)
=>
item
.
id
===
productId
)
if
(
product
)
{
row
.
productUnit
=
product
.
unit
row
.
productNo
=
product
.
no
row
.
productPrice
=
product
.
price
row
.
businessPrice
=
product
.
price
}
}
/** 表单校验 */
const
validate
=
()
=>
{
return
formRef
.
value
.
validate
()
}
defineExpose
({
validate
})
/** 初始化 */
onMounted
(
async
()
=>
{
productList
.
value
=
await
ProductApi
.
getProductSimpleList
()
})
</
script
>
src/views/crm/business/index.vue
View file @
a2443e48
...
@@ -39,9 +39,31 @@
...
@@ -39,9 +39,31 @@
<!-- 列表 -->
<!-- 列表 -->
<ContentWrap>
<ContentWrap>
<el-table
v-loading=
"loading"
:data=
"list"
:stripe=
"true"
:show-overflow-tooltip=
"true"
>
<el-table
v-loading=
"loading"
:data=
"list"
:stripe=
"true"
:show-overflow-tooltip=
"true"
>
<el-table-column
label=
"商机名称"
align=
"center"
prop=
"name"
/>
<el-table-column
align=
"center"
label=
"商机名称"
fixed=
"left"
prop=
"name"
width=
"160"
>
<el-table-column
label=
"客户名称"
align=
"center"
prop=
"customerName"
/>
<template
#
default=
"scope"
>
<el-table-column
label=
"商机金额"
align=
"center"
prop=
"price"
/>
<el-link
:underline=
"false"
type=
"primary"
@
click=
"openDetail(scope.row.id)"
>
{{
scope
.
row
.
name
}}
</el-link>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
fixed=
"left"
label=
"客户名称"
prop=
"customerName"
width=
"120"
>
<
template
#
default=
"scope"
>
<el-link
:underline=
"false"
type=
"primary"
@
click=
"openCustomerDetail(scope.row.customerId)"
>
{{
scope
.
row
.
customerName
}}
</el-link>
</
template
>
</el-table-column>
<el-table-column
label=
"商机金额(元)"
align=
"center"
prop=
"totalPrice"
width=
"140"
:formatter=
"erpPriceTableColumnFormatter"
/>
<el-table-column
<el-table-column
label=
"预计成交日期"
label=
"预计成交日期"
align=
"center"
align=
"center"
...
@@ -49,9 +71,23 @@
...
@@ -49,9 +71,23 @@
:formatter=
"dateFormatter"
:formatter=
"dateFormatter"
width=
"180px"
width=
"180px"
/>
/>
<el-table-column
label=
"备注"
align=
"center"
prop=
"remark"
/>
<el-table-column
align=
"center"
label=
"备注"
prop=
"remark"
width=
"200"
/>
<el-table-column
label=
"商机状态类型"
align=
"center"
prop=
"statusTypeName"
/>
<el-table-column
<el-table-column
label=
"商机状态"
align=
"center"
prop=
"statusName"
/>
:formatter=
"dateFormatter"
align=
"center"
label=
"下次联系时间"
prop=
"contactNextTime"
width=
"180px"
/>
<el-table-column
align=
"center"
label=
"负责人"
prop=
"ownerUserName"
width=
"100px"
/>
<el-table-column
align=
"center"
label=
"所属部门"
prop=
"ownerUserDeptName"
width=
"100px"
/>
<el-table-column
:formatter=
"dateFormatter"
align=
"center"
label=
"最后跟进时间"
prop=
"contactLastTime"
width=
"180px"
/>
<el-table-column
<el-table-column
label=
"更新时间"
label=
"更新时间"
align=
"center"
align=
"center"
...
@@ -66,9 +102,21 @@
...
@@ -66,9 +102,21 @@
:formatter=
"dateFormatter"
:formatter=
"dateFormatter"
width=
"180px"
width=
"180px"
/>
/>
<el-table-column
label=
"负责人"
align=
"center"
prop=
"ownerUserId"
/>
<el-table-column
align=
"center"
label=
"创建人"
prop=
"creatorName"
width=
"100px"
/>
<el-table-column
label=
"创建人"
align=
"center"
prop=
"creator"
/>
<el-table-column
<el-table-column
label=
"跟进状态"
align=
"center"
prop=
"followUpStatus"
/>
label=
"商机状态组"
align=
"center"
prop=
"statusTypeName"
fixed=
"right"
width=
"140"
/>
<el-table-column
label=
"商机阶段"
align=
"center"
prop=
"statusName"
fixed=
"right"
width=
"120"
/>
<el-table-column
label=
"操作"
align=
"center"
fixed=
"right"
width=
"130px"
>
<el-table-column
label=
"操作"
align=
"center"
fixed=
"right"
width=
"130px"
>
<
template
#
default=
"scope"
>
<
template
#
default=
"scope"
>
<el-button
<el-button
...
@@ -108,6 +156,7 @@ import { dateFormatter } from '@/utils/formatTime'
...
@@ -108,6 +156,7 @@ import { dateFormatter } from '@/utils/formatTime'
import
download
from
'@/utils/download'
import
download
from
'@/utils/download'
import
*
as
BusinessApi
from
'@/api/crm/business'
import
*
as
BusinessApi
from
'@/api/crm/business'
import
BusinessForm
from
'./BusinessForm.vue'
import
BusinessForm
from
'./BusinessForm.vue'
import
{
erpPriceTableColumnFormatter
}
from
'@/utils'
defineOptions
({
name
:
'CrmBusiness'
})
defineOptions
({
name
:
'CrmBusiness'
})
...
@@ -166,6 +215,17 @@ const resetQuery = () => {
...
@@ -166,6 +215,17 @@ const resetQuery = () => {
handleQuery
()
handleQuery
()
}
}
/** 打开客户详情 */
const
{
currentRoute
,
push
}
=
useRouter
()
const
openDetail
=
(
id
:
number
)
=>
{
push
({
name
:
'CrmBusinessDetail'
,
params
:
{
id
}
})
}
/** 打开客户详情 */
const
openCustomerDetail
=
(
id
:
number
)
=>
{
push
({
name
:
'CrmCustomerDetail'
,
params
:
{
id
}
})
}
/** 添加/修改操作 */
/** 添加/修改操作 */
const
formRef
=
ref
()
const
formRef
=
ref
()
const
openForm
=
(
type
:
string
,
id
?:
number
)
=>
{
const
openForm
=
(
type
:
string
,
id
?:
number
)
=>
{
...
...
src/views/crm/contact/ContactForm.vue
View file @
a2443e48
...
@@ -206,7 +206,6 @@ const formRules = reactive({
...
@@ -206,7 +206,6 @@ const formRules = reactive({
ownerUserId
:
[{
required
:
true
,
message
:
'负责人不能为空'
,
trigger
:
'blur'
}]
ownerUserId
:
[{
required
:
true
,
message
:
'负责人不能为空'
,
trigger
:
'blur'
}]
})
})
const
formRef
=
ref
()
// 表单 Ref
const
formRef
=
ref
()
// 表单 Ref
const
ownerUserList
=
ref
<
any
[]
>
([])
const
userOptions
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 用户列表
const
userOptions
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 用户列表
// TODO 芋艿:统一的客户选择面板
// TODO 芋艿:统一的客户选择面板
const
customerList
=
ref
<
CustomerApi
.
CustomerVO
[]
>
([])
// 客户列表
const
customerList
=
ref
<
CustomerApi
.
CustomerVO
[]
>
([])
// 客户列表
...
@@ -288,6 +287,5 @@ const resetForm = () => {
...
@@ -288,6 +287,5 @@ const resetForm = () => {
remark
:
undefined
remark
:
undefined
}
}
formRef
.
value
?.
resetFields
()
formRef
.
value
?.
resetFields
()
ownerUserList
.
value
=
[]
}
}
</
script
>
</
script
>
src/views/crm/product/ProductForm.vue
View file @
a2443e48
...
@@ -104,7 +104,6 @@ import * as ProductCategoryApi from '@/api/crm/product/productCategory'
...
@@ -104,7 +104,6 @@ import * as ProductCategoryApi from '@/api/crm/product/productCategory'
import
{
defaultProps
,
handleTree
}
from
'@/utils/tree'
import
{
defaultProps
,
handleTree
}
from
'@/utils/tree'
import
{
getSimpleUserList
,
UserVO
}
from
'@/api/system/user'
import
{
getSimpleUserList
,
UserVO
}
from
'@/api/system/user'
import
{
useUserStore
}
from
'@/store/modules/user'
import
{
useUserStore
}
from
'@/store/modules/user'
import
{
fenToYuan
,
yuanToFen
}
from
'@/utils'
defineOptions
({
name
:
'CrmProductForm'
})
defineOptions
({
name
:
'CrmProductForm'
})
...
@@ -149,7 +148,6 @@ const open = async (type: string, id?: number) => {
...
@@ -149,7 +148,6 @@ const open = async (type: string, id?: number) => {
formLoading
.
value
=
true
formLoading
.
value
=
true
try
{
try
{
formData
.
value
=
await
ProductApi
.
getProduct
(
id
)
formData
.
value
=
await
ProductApi
.
getProduct
(
id
)
formData
.
value
.
price
=
Number
(
fenToYuan
(
formData
.
value
.
price
))
}
finally
{
}
finally
{
formLoading
.
value
=
false
formLoading
.
value
=
false
}
}
...
@@ -169,10 +167,7 @@ const submitForm = async () => {
...
@@ -169,10 +167,7 @@ const submitForm = async () => {
// 提交请求
// 提交请求
formLoading
.
value
=
true
formLoading
.
value
=
true
try
{
try
{
const
data
=
{
const
data
=
formData
.
value
as
unknown
as
ProductApi
.
ProductVO
...
formData
.
value
,
price
:
yuanToFen
(
formData
.
value
.
price
)
}
as
unknown
as
ProductApi
.
ProductVO
if
(
formType
.
value
===
'create'
)
{
if
(
formType
.
value
===
'create'
)
{
await
ProductApi
.
createProduct
(
data
)
await
ProductApi
.
createProduct
(
data
)
message
.
success
(
t
(
'common.createSuccess'
))
message
.
success
(
t
(
'common.createSuccess'
))
...
...
src/views/crm/product/index.vue
View file @
a2443e48
...
@@ -68,7 +68,7 @@
...
@@ -68,7 +68,7 @@
label=
"价格(元)"
label=
"价格(元)"
align=
"center"
align=
"center"
prop=
"price"
prop=
"price"
:formatter=
"
fenToYuanFormat
"
:formatter=
"
erpPriceTableColumnFormatter
"
width=
"100"
width=
"100"
/>
/>
<el-table-column
label=
"产品描述"
align=
"center"
prop=
"description"
width=
"150"
/>
<el-table-column
label=
"产品描述"
align=
"center"
prop=
"description"
width=
"150"
/>
...
@@ -134,6 +134,7 @@ import download from '@/utils/download'
...
@@ -134,6 +134,7 @@ import download from '@/utils/download'
import
*
as
ProductApi
from
'@/api/crm/product'
import
*
as
ProductApi
from
'@/api/crm/product'
import
ProductForm
from
'./ProductForm.vue'
import
ProductForm
from
'./ProductForm.vue'
import
{
fenToYuanFormat
}
from
'@/utils/formatter'
import
{
fenToYuanFormat
}
from
'@/utils/formatter'
import
{
erpPriceTableColumnFormatter
}
from
'@/utils'
defineOptions
({
name
:
'CrmProduct'
})
defineOptions
({
name
:
'CrmProduct'
})
...
...
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