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
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
403 additions
and
171 deletions
+403
-171
src/api/crm/product/index.ts
+5
-0
src/views/crm/business/BusinessForm.vue
+143
-153
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
<
template
>
<
template
>
<Dialog
:title=
"dialogTitle"
v-model=
"dialogVisible"
>
<Dialog
:title=
"dialogTitle"
v-model=
"dialogVisible"
width=
"1280"
>
<el-form
<el-form
ref=
"formRef"
ref=
"formRef"
:model=
"formData"
:model=
"formData"
:rules=
"formRules"
:rules=
"formRules"
label-width=
"1
0
0px"
label-width=
"1
2
0px"
v-loading=
"formLoading"
v-loading=
"formLoading"
>
>
<el-row>
<el-col
:span=
"8"
>
<el-form-item
label=
"商机名称"
prop=
"name"
>
<el-form-item
label=
"商机名称"
prop=
"name"
>
<el-input
v-model=
"formData.name"
placeholder=
"请输入商机名称"
/>
<el-input
v-model=
"formData.name"
placeholder=
"请输入商机名称"
/>
</el-form-item>
</el-form-item>
<!-- TODO 芋艿:客户列表的组件 -->
<el-form-item
label=
"客户名称"
prop=
"customerName"
>
<el-popover
placement=
"bottom"
:width=
"600"
trigger=
"click"
:teleported=
"false"
:visible=
"showCustomer"
:offset=
"10"
>
<template
#
reference
>
<el-input
placeholder=
"请选择客户"
@
click=
"openCustomerSelect"
v-model=
"formData.customerName"
/>
</
template
>
<el-table
:data=
"customerList"
ref=
"multipleTableRef"
@
select=
"handleSelectionChange"
>
<el-table-column
width=
"55"
label=
"选择"
type=
"selection"
/>
<el-table-column
width=
"100"
label=
"编号"
property=
"id"
/>
<el-table-column
width=
"150"
label=
"客户名称"
property=
"name"
/>
<el-table-column
width=
"100"
label=
"客户来源"
prop=
"source"
align=
"center"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.CRM_CUSTOMER_SOURCE"
:value=
"scope.row.source"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"客户级别"
align=
"center"
prop=
"level"
width=
"120"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.CRM_CUSTOMER_LEVEL"
:value=
"scope.row.level"
/>
</
template
>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-row
:gutter=
"20"
>
<el-col>
<Pagination
:total=
"total"
v-model:page=
"queryParams.pageNo"
v-model:limit=
"queryParams.pageSize"
@
pagination=
"getCustomerList"
layout=
"sizes, prev, pager, next"
/>
</el-col>
</el-row>
<el-row
:gutter=
"20"
>
<el-col
:span=
"10"
:offset=
"13"
>
<el-button
@
click=
"selectCustomer"
>
确认
</el-button>
<el-button
@
click=
"showCustomer = false"
>
取消
</el-button>
</el-col>
</el-col>
</el-row>
<el-col
:span=
"8"
>
</el-popover>
<el-form-item
label=
"负责人"
prop=
"ownerUserId"
>
</el-form-item>
<!-- TODO @ljlleo:idea 红色的报错,可以解决下 -->
<el-form-item
label=
"商机状态类型"
prop=
"statusTypeId"
>
<el-select
<el-select
v-model=
"formData.statusTypeId"
v-model=
"formData.ownerUserId"
placeholder=
"请选择商机状态类型"
:disabled=
"formType !== 'create'"
clearable
class=
"w-1/1"
@
change=
"changeBusinessStatusType"
>
>
<el-option
<el-option
v-for=
"item in businessStatusTypeList"
v-for=
"item in userOptions"
:key=
"item.id"
:label=
"item.nickname"
:value=
"item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col
:span=
"8"
>
<el-form-item
label=
"客户名称"
prop=
"customerId"
>
<el-select
v-model=
"formData.customerId"
placeholder=
"请选择客户"
class=
"w-1/1"
>
<el-option
v-for=
"item in customerList"
:key=
"item.id"
:key=
"item.id"
:label=
"item.name"
:label=
"item.name"
:value=
"item.id"
:value=
"item.id"
/>
/>
</el-select>
</el-select>
</el-form-item>
</el-form-item>
<el-form-item
label=
"商机状态"
prop=
"statusId"
>
</el-col>
<el-select
v-model=
"formData.statusId"
placeholder=
"请选择商机状态"
clearable
>
</el-row>
<el-row>
<el-col
:span=
"8"
>
<el-form-item
label=
"商机状态组"
prop=
"statusTypeId"
>
<el-select
v-model=
"formData.statusTypeId"
placeholder=
"请选择商机状态组"
clearable
class=
"w-1/1"
>
<el-option
<el-option
v-for=
"item in businessStatus
List"
v-for=
"item in statusType
List"
:key=
"item.id"
:key=
"item.id"
:label=
"item.name"
:label=
"item.name"
:value=
"item.id"
:value=
"item.id"
/>
/>
</el-select>
</el-select>
</el-form-item>
</el-form-item>
</el-col>
<el-col
:span=
"8"
>
<el-form-item
label=
"预计成交日期"
prop=
"dealTime"
>
<el-form-item
label=
"预计成交日期"
prop=
"dealTime"
>
<el-date-picker
<el-date-picker
v-model=
"formData.dealTime"
v-model=
"formData.dealTime"
type=
"date"
type=
"date"
value-format=
"x"
value-format=
"x"
placeholder=
"选择预计成交日期"
placeholder=
"选择预计成交日期"
class=
"!w-1/1"
/>
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"商机金额"
prop=
"price"
>
</el-col>
<el-input
v-model=
"formData.price"
placeholder=
"请输入商机金额"
/>
<el-col
:span=
"8"
>
<el-form-item
label=
"备注"
prop=
"remark"
>
<el-input
type=
"textarea"
v-model=
"formData.remark"
placeholder=
"请输入备注"
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"整单折扣"
prop=
"discountPercent"
>
</el-col>
<el-input
v-model=
"formData.discountPercent"
placeholder=
"请输入整单折扣"
/>
</el-row>
<!-- 子表的表单 -->
<ContentWrap>
<el-tabs
v-model=
"subTabsName"
class=
"-mt-15px -mb-10px"
>
<el-tab-pane
label=
"产品清单"
name=
"product"
>
<BusinessProductForm
ref=
"productFormRef"
:products=
"formData.products"
:disabled=
"disabled"
/>
</el-tab-pane>
</el-tabs>
</ContentWrap>
<el-row>
<el-col
:span=
"8"
>
<el-form-item
label=
"产品总金额"
prop=
"totalProductPrice"
>
<el-input
disabled
v-model=
"formData.totalProductPrice"
:formatter=
"erpPriceInputFormatter"
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"产品总金额"
prop=
"productPrice"
>
</el-col>
<el-input
v-model=
"formData.productPrice"
placeholder=
"请输入产品总金额"
/>
<el-col
:span=
"8"
>
<el-form-item
label=
"整单折扣(%)"
prop=
"discountPercent"
>
<el-input-number
v-model=
"formData.discountPercent"
placeholder=
"请输入整单折扣"
controls-position=
"right"
:min=
"0"
:precision=
"2"
class=
"!w-1/1"
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"备注"
prop=
"remark"
>
</el-col>
<el-input
v-model=
"formData.remark"
placeholder=
"请输入备注"
/>
<el-col
:span=
"8"
>
<el-form-item
label=
"折扣后金额"
prop=
"price"
>
<el-input
disabled
v-model=
"formData.totalPrice"
placeholder=
"请输入商机金额"
:formatter=
"erpPriceInputFormatter"
/>
</el-form-item>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-form>
<template
#
footer
>
<template
#
footer
>
<el-button
@
click=
"submitForm"
type=
"primary"
:disabled=
"formLoading"
>
确 定
</el-button>
<el-button
@
click=
"submitForm"
type=
"primary"
:disabled=
"formLoading"
>
确 定
</el-button>
...
@@ -119,8 +133,10 @@
...
@@ -119,8 +133,10 @@
import
*
as
BusinessApi
from
'@/api/crm/business'
import
*
as
BusinessApi
from
'@/api/crm/business'
import
*
as
BusinessStatusTypeApi
from
'@/api/crm/businessStatusType'
import
*
as
BusinessStatusTypeApi
from
'@/api/crm/businessStatusType'
import
*
as
CustomerApi
from
'@/api/crm/customer'
import
*
as
CustomerApi
from
'@/api/crm/customer'
import
{
DICT_TYPE
}
from
'@/utils/dict'
import
*
as
UserApi
from
'@/api/system/user'
import
{
ElTable
}
from
'element-plus'
import
{
useUserStore
}
from
'@/store/modules/user'
import
BusinessProductForm
from
'./components/BusinessProductForm.vue'
import
{
erpPriceInputFormatter
,
erpPriceMultiply
}
from
'@/utils'
const
{
t
}
=
useI18n
()
// 国际化
const
{
t
}
=
useI18n
()
// 国际化
const
message
=
useMessage
()
// 消息弹窗
const
message
=
useMessage
()
// 消息弹窗
...
@@ -132,33 +148,53 @@ const formType = ref('') // 表单的类型:create - 新增;update - 修改
...
@@ -132,33 +148,53 @@ const formType = ref('') // 表单的类型:create - 新增;update - 修改
const
formData
=
ref
({
const
formData
=
ref
({
id
:
undefined
,
id
:
undefined
,
name
:
undefined
,
name
:
undefined
,
statusTypeId
:
undefined
,
statusId
:
undefined
,
contactNextTime
:
undefined
,
customerId
:
undefined
,
customerId
:
undefined
,
contactNextTime
:
undefined
,
ownerUserId
:
undefined
,
statusTypeId
:
undefined
,
dealTime
:
undefined
,
dealTime
:
undefined
,
price
:
undefined
,
discountPercent
:
0
,
discountPercent
:
undefined
,
totalProductPrice
:
undefined
,
product
Price
:
undefined
,
total
Price
:
undefined
,
remark
:
undefined
,
remark
:
undefined
,
ownerUserId
:
undefined
,
products
:
[]
roUserIds
:
undefined
,
rwUserIds
:
undefined
,
endStatus
:
undefined
,
endRemark
:
undefined
,
contactLastTime
:
undefined
,
followUpStatus
:
undefined
})
})
const
formRules
=
reactive
({
const
formRules
=
reactive
({
name
:
[{
required
:
true
,
message
:
'商机名称不能为空'
,
trigger
:
'blur'
}]
name
:
[{
required
:
true
,
message
:
'商机名称不能为空'
,
trigger
:
'blur'
}],
customerId
:
[{
required
:
true
,
message
:
'客户不能为空'
,
trigger
:
'blur'
}],
ownerUserId
:
[{
required
:
true
,
message
:
'负责人不能为空'
,
trigger
:
'blur'
}],
statusTypeId
:
[{
required
:
true
,
message
:
'商机状态组不能为空'
,
trigger
:
'blur'
}]
})
})
const
formRef
=
ref
()
// 表单 Ref
const
formRef
=
ref
()
// 表单 Ref
const
businessStatusList
=
ref
([])
// 商机状态列表
const
userOptions
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 用户列表
const
businessStatusTypeList
=
ref
([])
//商机状态类型列表
const
statusTypeList
=
ref
([])
// 商机状态类型列表
const
loading
=
ref
(
true
)
// 列表的加载中
// TODO 芋艿:统一的客户选择面板
const
total
=
ref
(
0
)
// 列表的总页数
const
customerList
=
ref
([])
// 客户列表的数据
const
customerList
=
ref
([])
// 客户列表的数据
/** 子表的表单 */
const
subTabsName
=
ref
(
'product'
)
const
productFormRef
=
ref
()
/** 计算 discountPrice、totalPrice 价格 */
watch
(
()
=>
formData
.
value
,
(
val
)
=>
{
if
(
!
val
)
{
return
}
const
totalProductPrice
=
val
.
products
.
reduce
((
prev
,
curr
)
=>
prev
+
curr
.
totalPrice
,
0
)
const
discountPrice
=
val
.
discountPercent
!=
null
?
erpPriceMultiply
(
totalProductPrice
,
val
.
discountPercent
/
100.0
)
:
0
const
totalPrice
=
totalProductPrice
-
discountPrice
// 赋值
formData
.
value
.
totalProductPrice
=
totalProductPrice
formData
.
value
.
totalPrice
=
totalPrice
},
{
deep
:
true
}
)
/** 打开弹窗 */
/** 打开弹窗 */
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
dialogVisible
.
value
=
true
dialogVisible
.
value
=
true
...
@@ -174,8 +210,15 @@ const open = async (type: string, id?: number) => {
...
@@ -174,8 +210,15 @@ const open = async (type: string, id?: number) => {
formLoading
.
value
=
false
formLoading
.
value
=
false
}
}
}
}
customerList
.
value
=
await
CustomerApi
.
getCustomerSimpleList
()
// 加载商机状态类型列表
// 加载商机状态类型列表
businessStatusTypeList
.
value
=
await
BusinessStatusTypeApi
.
getBusinessStatusTypeList
()
statusTypeList
.
value
=
await
BusinessStatusTypeApi
.
getBusinessStatusTypeList
()
// 获得用户列表
userOptions
.
value
=
await
UserApi
.
getSimpleUserList
()
// 默认新建时选中自己
if
(
formType
.
value
===
'create'
)
{
formData
.
value
.
ownerUserId
=
useUserStore
().
getUser
.
id
}
}
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
...
@@ -186,6 +229,7 @@ const submitForm = async () => {
...
@@ -186,6 +229,7 @@ const submitForm = async () => {
if
(
!
formRef
)
return
if
(
!
formRef
)
return
const
valid
=
await
formRef
.
value
.
validate
()
const
valid
=
await
formRef
.
value
.
validate
()
if
(
!
valid
)
return
if
(
!
valid
)
return
await
productFormRef
.
value
.
validate
()
// 提交请求
// 提交请求
formLoading
.
value
=
true
formLoading
.
value
=
true
try
{
try
{
...
@@ -210,71 +254,17 @@ const resetForm = () => {
...
@@ -210,71 +254,17 @@ const resetForm = () => {
formData
.
value
=
{
formData
.
value
=
{
id
:
undefined
,
id
:
undefined
,
name
:
undefined
,
name
:
undefined
,
statusTypeId
:
undefined
,
statusId
:
undefined
,
contactNextTime
:
undefined
,
customerId
:
undefined
,
customerId
:
undefined
,
contactNextTime
:
undefined
,
ownerUserId
:
undefined
,
statusTypeId
:
undefined
,
dealTime
:
undefined
,
dealTime
:
undefined
,
price
:
undefined
,
discountPercent
:
0
,
discountPercent
:
undefined
,
totalProductPrice
:
undefined
,
product
Price
:
undefined
,
total
Price
:
undefined
,
remark
:
undefined
,
remark
:
undefined
,
ownerUserId
:
undefined
,
products
:
[]
roUserIds
:
undefined
,
rwUserIds
:
undefined
,
endStatus
:
undefined
,
endRemark
:
undefined
,
contactLastTime
:
undefined
,
followUpStatus
:
undefined
}
}
formRef
.
value
?.
resetFields
()
formRef
.
value
?.
resetFields
()
}
}
/** 加载商机状态列表 */
const
changeBusinessStatusType
=
async
(
typeId
:
number
)
=>
{
businessStatusList
.
value
=
await
BusinessStatusTypeApi
.
getBusinessStatusListByTypeId
(
typeId
)
}
const
queryParams
=
reactive
({
pageNo
:
1
,
pageSize
:
10
,
name
:
null
,
mobile
:
null
,
industryId
:
null
,
level
:
null
,
source
:
null
,
pool
:
false
})
// 选择客户
const
showCustomer
=
ref
(
false
)
const
openCustomerSelect
=
()
=>
{
showCustomer
.
value
=
!
showCustomer
.
value
queryParams
.
pageNo
=
1
getCustomerList
()
}
/** 查询客户列表 */
const
getCustomerList
=
async
()
=>
{
loading
.
value
=
true
try
{
const
data
=
await
CustomerApi
.
getCustomerPage
(
queryParams
)
customerList
.
value
=
data
.
list
total
.
value
=
data
.
total
}
finally
{
loading
.
value
=
false
}
}
const
multipleTableRef
=
ref
<
InstanceType
<
typeof
ElTable
>>
()
const
multipleSelection
=
ref
()
const
handleSelectionChange
=
({},
row
)
=>
{
multipleSelection
.
value
=
row
multipleTableRef
.
value
!
.
clearSelection
()
multipleTableRef
.
value
!
.
toggleRowSelection
(
row
,
undefined
)
}
const
selectCustomer
=
()
=>
{
formData
.
value
.
customerId
=
multipleSelection
.
value
.
id
formData
.
value
.
customerName
=
multipleSelection
.
value
.
name
showCustomer
.
value
=
!
showCustomer
.
value
}
</
script
>
</
script
>
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