Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
B
baifang-java
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
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
单欣鑫
baifang-java
Commits
db94161b
Commit
db94161b
authored
Jun 03, 2025
by
法拉51246
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
三个基本功能基本完成
parent
07703c77
Changes
24
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
696 additions
and
108 deletions
+696
-108
CustomerInfoController.java
...controller/admin/customerinfo/CustomerInfoController.java
+11
-1
CustomerInfoRespVO.java
.../controller/admin/customerinfo/vo/CustomerInfoRespVO.java
+16
-2
InfoController.java
...ao/module/visit/controller/admin/info/InfoController.java
+1
-1
InfoPageReqVO.java
.../module/visit/controller/admin/info/vo/InfoPageReqVO.java
+5
-1
InfoRespVO.java
...dao/module/visit/controller/admin/info/vo/InfoRespVO.java
+46
-1
InfoSaveReqVO.java
.../module/visit/controller/admin/info/vo/InfoSaveReqVO.java
+3
-0
ProductController.java
...ule/visit/controller/admin/product/ProductController.java
+9
-0
ProductSimpleReqVO.java
...visit/controller/admin/product/vo/ProductSimpleReqVO.java
+32
-0
InfoDO.java
...ocoder/yudao/module/visit/dal/dataobject/info/InfoDO.java
+4
-0
ProductService.java
...er/yudao/module/visit/service/product/ProductService.java
+2
-0
ProductServiceImpl.java
...udao/module/visit/service/product/ProductServiceImpl.java
+16
-0
package-lock.json
yudao-ui/yudao-ui-admin-vue3/package-lock.json
+2
-3
package.json
yudao-ui/yudao-ui-admin-vue3/package.json
+1
-1
index.ts
...i/yudao-ui-admin-vue3/src/api/visit/customerinfo/index.ts
+58
-53
index.ts
yudao-ui/yudao-ui-admin-vue3/src/api/visit/product/index.ts
+5
-0
UploadImgs.vue
...i-admin-vue3/src/components/UploadFile/src/UploadImgs.vue
+14
-9
CustomerInfoForm.vue
...in-vue3/src/views/visit/customerinfo/CustomerInfoForm.vue
+44
-5
index.vue
...udao-ui-admin-vue3/src/views/visit/customerinfo/index.vue
+6
-0
productTable.vue
...-admin-vue3/src/views/visit/customerinfo/productTable.vue
+214
-0
InfoForm.vue
...-ui/yudao-ui-admin-vue3/src/views/visit/info/InfoForm.vue
+148
-27
index.vue
yudao-ui/yudao-ui-admin-vue3/src/views/visit/info/index.vue
+6
-1
index.vue
...-ui/yudao-ui-admin-vue3/src/views/visit/product/index.vue
+9
-2
ProductList.vue
.../yudao-ui-admin-vue3/src/views/visit/util/ProductList.vue
+43
-0
tsconfig.json
yudao-ui/yudao-ui-admin-vue3/tsconfig.json
+1
-1
No files found.
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/CustomerInfoController.java
View file @
db94161b
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
controller
.
admin
.
customerinfo
;
import
cn.iocoder.yudao.module.visit.controller.admin.product.vo.ProductSimpleReqVO
;
import
cn.iocoder.yudao.module.visit.service.product.ProductService
;
import
com.fhs.common.utils.StringUtil
;
import
org.springframework.web.bind.annotation.*
;
import
javax.annotation.Resource
;
import
org.springframework.validation.annotation.Validated
;
...
...
@@ -37,6 +40,8 @@ public class CustomerInfoController {
@Resource
private
CustomerInfoService
customerInfoService
;
@Resource
private
ProductService
productService
;
@PostMapping
(
"/create"
)
@Operation
(
summary
=
"创建客户信息"
)
...
...
@@ -68,7 +73,12 @@ public class CustomerInfoController {
@PreAuthorize
(
"@ss.hasPermission('visit:customer-info:query')"
)
public
CommonResult
<
CustomerInfoRespVO
>
getCustomerInfo
(
@RequestParam
(
"id"
)
Long
id
)
{
CustomerInfoDO
customerInfo
=
customerInfoService
.
getCustomerInfo
(
id
);
return
success
(
BeanUtils
.
toBean
(
customerInfo
,
CustomerInfoRespVO
.
class
));
CustomerInfoRespVO
bean
=
BeanUtils
.
toBean
(
customerInfo
,
CustomerInfoRespVO
.
class
);
// if (!StringUtil.isEmpty(customerInfo.getProductIds())){
// List<ProductSimpleReqVO> productSimpleReqVO = productService.getProductByIds(customerInfo.getProductIds());
// bean.setProductList(productSimpleReqVO);
// }
return
success
(
bean
);
}
@GetMapping
(
"/page"
)
...
...
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerInfoRespVO.java
View file @
db94161b
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
controller
.
admin
.
customerinfo
.
vo
;
import
cn.iocoder.yudao.module.visit.controller.admin.product.vo.ProductSimpleReqVO
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.*
;
import
java.util.*
;
...
...
@@ -36,6 +37,16 @@ public class CustomerInfoRespVO {
@DictFormat
(
"customer_type"
)
// TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private
Integer
customerType
;
//省名称
@Schema
(
description
=
"省名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
private
String
provinceName
;
//市名称
@Schema
(
description
=
"市名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
private
String
cityName
;
//区名称
@Schema
(
description
=
"区名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
private
String
areaName
;
@Schema
(
description
=
"所在地区"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@ExcelProperty
(
"所在地区"
)
private
String
regionFullName
;
...
...
@@ -54,8 +65,8 @@ public class CustomerInfoRespVO {
@ExcelProperty
(
"产品ID"
)
private
String
productIds
;
@Schema
(
description
=
"部门"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@ExcelProperty
(
"部门"
)
@Schema
(
description
=
"
客户所属
部门"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@ExcelProperty
(
"
客户所属
部门"
)
@DictFormat
(
"customer_dept"
)
private
String
department
;
...
...
@@ -67,4 +78,7 @@ public class CustomerInfoRespVO {
@ExcelProperty
(
"创建时间"
)
private
LocalDateTime
createTime
;
@Schema
(
description
=
"产品信息List对象"
)
private
List
<
ProductSimpleReqVO
>
productList
;
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/InfoController.java
View file @
db94161b
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoPageReqVO.java
View file @
db94161b
...
...
@@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
import
org.springframework.format.annotation.DateTimeFormat
;
import
java.time.LocalDateTime
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
DateUtils
.
FORMAT_YEAR_MONTH_DAY
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
DateUtils
.
FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND
;
@Schema
(
description
=
"管理后台 - 客户拜访记录分页 Request VO"
)
...
...
@@ -26,8 +27,11 @@ public class InfoPageReqVO extends PageParam {
@Schema
(
description
=
"客户公司名称"
)
private
String
companyName
;
@Schema
(
description
=
"所在地区"
)
private
String
regionFullName
;
@Schema
(
description
=
"拜访日期"
)
@DateTimeFormat
(
pattern
=
FORMAT_YEAR_MONTH_DAY
_HOUR_MINUTE_SECOND
)
@DateTimeFormat
(
pattern
=
FORMAT_YEAR_MONTH_DAY
)
private
LocalDate
[]
visitDate
;
@Schema
(
description
=
"性质等级"
,
example
=
"1"
)
...
...
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoRespVO.java
View file @
db94161b
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
controller
.
admin
.
info
.
vo
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.*
;
...
...
@@ -12,6 +13,9 @@ import com.alibaba.excel.annotation.*;
import
cn.iocoder.yudao.framework.excel.core.annotations.DictFormat
;
import
cn.iocoder.yudao.framework.excel.core.convert.DictConvert
;
import
javax.validation.constraints.NotEmpty
;
import
javax.validation.constraints.NotNull
;
@Schema
(
description
=
"管理后台 - 客户拜访记录 Response VO"
)
@Data
@ExcelIgnoreUnannotated
...
...
@@ -33,12 +37,39 @@ public class InfoRespVO {
@ExcelProperty
(
"客户公司名称"
)
private
String
companyName
;
@Schema
(
description
=
"所在地区"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@ExcelProperty
(
"所在地区"
)
private
String
regionFullName
;
@Schema
(
description
=
"省名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
private
String
provinceName
;
@Schema
(
description
=
"市名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
private
String
cityName
;
@Schema
(
description
=
"区名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
private
String
areaName
;
@Schema
(
description
=
"定位地址文字描述"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
private
String
locationText
;
@Schema
(
description
=
"经度"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
private
BigDecimal
longitude
;
@Schema
(
description
=
"纬度"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
private
BigDecimal
latitude
;
@Schema
(
description
=
"定位静态图URL"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
private
String
locationImage
;
@Schema
(
description
=
"拜访日期"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@ExcelProperty
(
"拜访日期"
)
@JsonFormat
(
pattern
=
"yyyy-MM-dd"
)
private
LocalDate
visitDate
;
@Schema
(
description
=
"性质等级"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
,
example
=
"1"
)
@ExcelProperty
(
"性质等级"
)
@ExcelProperty
(
value
=
"性质等级"
,
converter
=
DictConvert
.
class
)
@DictFormat
(
"customer_type"
)
private
Integer
customerStatus
;
@Schema
(
description
=
"拜访品种(多选,逗号分隔)"
)
...
...
@@ -59,4 +90,18 @@ public class InfoRespVO {
@ExcelProperty
(
"创建时间"
)
private
LocalDateTime
createTime
;
@Schema
(
description
=
"服务内容"
)
@ExcelProperty
(
"服务内容"
)
private
String
serviceContent
;
@Schema
(
description
=
"客户反馈"
)
@ExcelProperty
(
"客户反馈"
)
private
String
customerFeedback
;
@Schema
(
description
=
"服务记录图片URL列表(JSON数组)"
)
@ExcelProperty
(
"服务记录图片URL列表(JSON数组)"
)
private
String
serviceImages
;
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoSaveReqVO.java
View file @
db94161b
...
...
@@ -39,6 +39,9 @@ public class InfoSaveReqVO {
@NotEmpty
(
message
=
"区名称不能为空"
)
private
String
areaName
;
@Schema
(
description
=
"所在地区"
)
private
String
regionFullName
;
@Schema
(
description
=
"定位地址文字描述"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"定位地址文字描述不能为空"
)
private
String
locationText
;
...
...
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/product/ProductController.java
View file @
db94161b
...
...
@@ -76,6 +76,15 @@ public class ProductController {
return
success
(
BeanUtils
.
toBean
(
product
,
ProductRespVO
.
class
));
}
@GetMapping
(
"/getListByIds"
)
@Operation
(
summary
=
"获得产品"
)
@Parameter
(
name
=
"ids"
,
description
=
"编号"
,
required
=
true
,
example
=
"1024,1023"
)
@PreAuthorize
(
"@ss.hasPermission('visit:product:query')"
)
public
CommonResult
<
List
<
ProductSimpleReqVO
>>
getProduct
(
@RequestParam
(
"ids"
)
String
ids
)
{
List
<
ProductSimpleReqVO
>
productByIds
=
productService
.
getProductByIds
(
ids
);
return
success
(
productByIds
);
}
@GetMapping
(
"/page"
)
@Operation
(
summary
=
"获得产品分页"
)
@PreAuthorize
(
"@ss.hasPermission('visit:product:query')"
)
...
...
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/product/vo/ProductSimpleReqVO.java
0 → 100644
View file @
db94161b
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
controller
.
admin
.
product
.
vo
;
import
cn.iocoder.yudao.framework.common.pojo.PageParam
;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.Data
;
import
lombok.EqualsAndHashCode
;
import
lombok.ToString
;
import
org.springframework.format.annotation.DateTimeFormat
;
import
java.time.LocalDateTime
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
util
.
date
.
DateUtils
.
FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND
;
@Schema
(
description
=
"管理后台 - 产品弹窗 Request VO"
)
@Data
@ToString
(
callSuper
=
true
)
public
class
ProductSimpleReqVO
{
@Schema
(
description
=
"编号"
,
example
=
"1"
)
private
Long
id
;
@Schema
(
description
=
"品种名称"
,
example
=
"阿莫西林胶囊"
)
private
String
productName
;
@Schema
(
description
=
"包装信息"
,
example
=
"盒装"
)
private
String
packageName
;
@Schema
(
description
=
"规格"
,
example
=
"10x20mg"
)
private
String
specification
;
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/dal/dataobject/info/InfoDO.java
View file @
db94161b
...
...
@@ -67,6 +67,10 @@ public class InfoDO extends BaseDO {
* 区名称
*/
private
String
areaName
;
/**
* 所在地区
*/
private
String
regionFullName
;
/**
* 定位地址文字描述
*/
...
...
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/product/ProductService.java
View file @
db94161b
...
...
@@ -59,4 +59,6 @@ public interface ProductService {
* @return 产品分页
*/
ProductImportRespVO
importProductList
(
List
<
ProductImportExcelVO
>
list
,
Boolean
updateSupport
);
List
<
ProductSimpleReqVO
>
getProductByIds
(
String
productIds
);
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/product/ProductServiceImpl.java
View file @
db94161b
...
...
@@ -111,6 +111,22 @@ public class ProductServiceImpl implements ProductService {
return
respVO
;
}
@Override
public
List
<
ProductSimpleReqVO
>
getProductByIds
(
String
productIds
)
{
//1.判断productIds是否为空
if
(
StrUtil
.
isEmpty
(
productIds
))
{
return
new
ArrayList
<>();
}
//2.按逗号切分成数组
String
[]
ids
=
productIds
.
split
(
","
);
//3.判断数组长度
if
(
ids
.
length
>
0
)
{
List
<
ProductDO
>
productDOS
=
productMapper
.
selectByIds
(
Arrays
.
asList
(
ids
));
return
BeanUtils
.
toBean
(
productDOS
,
ProductSimpleReqVO
.
class
);
}
return
new
ArrayList
<>();
}
private
void
validateProductUnique
(
String
productName
,
String
specification
,
String
packageName
)
{
ProductPageReqVO
productPageReqVO
=
new
ProductPageReqVO
();
...
...
yudao-ui/yudao-ui-admin-vue3/package-lock.json
View file @
db94161b
...
...
@@ -26,7 +26,7 @@
"camunda-bpmn-moddle"
:
"^7.0.1"
,
"cropperjs"
:
"^1.6.1"
,
"crypto-js"
:
"^4.2.0"
,
"dayjs"
:
"^1.11.1
0
"
,
"dayjs"
:
"^1.11.1
3
"
,
"diagram-js"
:
"^12.8.0"
,
"driver.js"
:
"^1.3.1"
,
"echarts"
:
"^5.5.0"
,
...
...
@@ -9042,8 +9042,7 @@
"node_modules/dayjs"
:
{
"version"
:
"1.11.13"
,
"resolved"
:
"https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz"
,
"integrity"
:
"sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
,
"license"
:
"MIT"
"integrity"
:
"sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
},
"node_modules/de-indent"
:
{
"version"
:
"1.0.2"
,
...
...
yudao-ui/yudao-ui-admin-vue3/package.json
View file @
db94161b
...
...
@@ -42,7 +42,7 @@
"camunda-bpmn-moddle"
:
"^7.0.1"
,
"cropperjs"
:
"^1.6.1"
,
"crypto-js"
:
"^4.2.0"
,
"dayjs"
:
"^1.11.1
0
"
,
"dayjs"
:
"^1.11.1
3
"
,
"diagram-js"
:
"^12.8.0"
,
"driver.js"
:
"^1.3.1"
,
"echarts"
:
"^5.5.0"
,
...
...
yudao-ui/yudao-ui-admin-vue3/src/api/visit/customerinfo/index.ts
View file @
db94161b
...
...
@@ -31,6 +31,11 @@ export const CustomerInfoApi = {
return
await
request
.
get
({
url
:
`/visit/customer-info/get?id=`
+
id
})
},
// 查询客户信息中拜访品种详情
getProductSimpleList
:
async
(
id
:
number
)
=>
{
return
await
request
.
get
({
url
:
`/visit/customer-info/getProductSimpleList?id=`
+
id
})
},
// 新增客户信息
createCustomerInfo
:
async
(
data
:
CustomerInfoVO
)
=>
{
return
await
request
.
post
({
url
:
`/visit/customer-info/create`
,
data
})
...
...
yudao-ui/yudao-ui-admin-vue3/src/api/visit/product/index.ts
View file @
db94161b
...
...
@@ -21,6 +21,11 @@ export const ProductApi = {
return
await
request
.
get
({
url
:
`/visit/product/get?id=`
+
id
})
},
// 查询产品详情ByIds
getProductByIds
:
async
(
ids
:
string
)
=>
{
return
await
request
.
get
({
url
:
`/visit/product/getListByIds?ids=`
+
ids
})
},
// 新增产品
createProduct
:
async
(
data
:
ProductVO
)
=>
{
return
await
request
.
post
({
url
:
`/visit/product/create`
,
data
})
...
...
yudao-ui/yudao-ui-admin-vue3/src/components/UploadFile/src/UploadImgs.vue
View file @
db94161b
...
...
@@ -136,19 +136,24 @@ const uploadSuccess: UploadProps['onSuccess'] = (res: any): void => {
// 监听模型绑定值变动
watch
(
()
=>
props
.
modelValue
,
(
val
:
string
|
string
[])
=>
{
if
(
!
val
)
{
fileList
.
value
=
[]
// fix:处理掉缓存,表单重置后上传组件的内容并没有重置
return
(
val
)
=>
{
// 防止 val 为字符串、null、undefined 报错
let
urls
:
string
[]
=
[]
if
(
Array
.
isArray
(
val
))
{
urls
=
val
}
else
if
(
typeof
val
===
'
string
'
)
{
urls
=
val
.
split
(
'
,
'
).
filter
((
url
)
=>
url
.
trim
()
!==
''
)
}
fileList
.
value
=
[]
// 保障数据为空
fileList
.
value
.
push
(
...(
val
as
string
[]).
map
((
url
)
=>
({
name
:
url
.
substring
(
url
.
lastIndexOf
(
'
/
'
)
+
1
),
url
}))
)
fileList
.
value
=
urls
.
map
((
url
)
=>
({
name
:
url
.
substring
(
url
.
lastIndexOf
(
'
/
'
)
+
1
),
url
})
)
},
{
immediate
:
true
,
deep
:
true
}
{
immediate
:
true
}
)
// 发送图片链接列表更新
const
emitUpdateModelValue
=
()
=>
{
let
result
:
string
[]
=
fileList
.
value
.
map
((
file
)
=>
file
.
url
!
)
...
...
yudao-ui/yudao-ui-admin-vue3/src/views/visit/customerinfo/CustomerInfoForm.vue
View file @
db94161b
...
...
@@ -70,7 +70,15 @@
<!-- <UploadImg v-model="formData.locationImage" />-->
<!-- </el-form-item>-->
<el-form-item
label=
"产品信息"
prop=
"productIds"
>
<el-input
v-model=
"formData.productIds"
placeholder=
"请输入产品信息"
/>
<el-input
v-model=
"formData.productIds"
placeholder=
"请点击右侧选择"
readonly
>
<
template
#append
>
<el-link
type=
"primary"
@
click=
"openProduct"
>
选择产品
</el-link>
</
template
>
</el-input>
</el-form-item>
<el-form-item
label=
"客户部门"
prop=
"department"
>
<el-select
v-model=
"formData.department"
placeholder=
"请选择客户部门"
>
...
...
@@ -88,11 +96,14 @@
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
</
template
>
</Dialog>
<productTable
ref=
"productListRef"
@
update-product=
"handleUpdateProduct"
:ids=
"formData.productIds"
/>
</template>
<
script
setup
lang=
"ts"
>
import
{
getIntDictOptions
,
getStrDictOptions
,
DICT_TYPE
}
from
'
@/utils/dict
'
import
{
CustomerInfoApi
,
CustomerInfoVO
}
from
'
@/api/visit/customerinfo
'
import
{
pcaTextArr
}
from
'
element-china-area-data
'
import
MapPicker
from
'
../util/MapPicker.vue
'
import
productTable
from
'
./productTable.vue
'
/** 客户信息 表单 */
defineOptions
({
name
:
'
CustomerInfoForm
'
})
...
...
@@ -103,7 +114,7 @@ const dialogVisible = ref(false) // 弹窗的是否展示
const
dialogTitle
=
ref
(
''
)
// 弹窗的标题
const
formLoading
=
ref
(
false
)
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const
formType
=
ref
(
''
)
// 表单的类型:create - 新增;update - 修改
const
selectedOptions
=
ref
([])
const
selectedOptions
=
ref
<
string
[]
>
([])
interface
CustomerFormData
{
id
?:
number
;
customerName
?:
string
;
...
...
@@ -118,7 +129,7 @@ interface CustomerFormData {
longitude
?:
number
;
latitude
?:
number
;
locationImage
?:
string
;
productIds
?:
number
[]
;
productIds
?:
string
;
department
?:
string
;
}
const
formData
=
ref
<
CustomerFormData
>
({
...
...
@@ -154,7 +165,20 @@ const formRules = reactive({
})
const
formRef
=
ref
()
// 表单 Ref
//地图相关操作
//===========================================选择产品相关操作=================================
const
productListRef
=
ref
<
InstanceType
<
typeof
productTable
>
|
null
>
(
null
);
// 产品列表 Ref
// 打开二级产品列表弹窗
const
openProduct
=
()
=>
{
productListRef
.
value
?.
open
();
// 调用子组件暴露的方法
}
const
handleUpdateProduct
=
(
ids
:
string
)
=>
{
console
.
log
(
'
来自子组件的产品ID:
'
,
ids
);
//存入表单
formData
.
value
.
productIds
=
ids
;
};
//===========================================地图相关操作=================================
const
mapPickerRef
=
ref
()
const
openMapPicker
=
()
=>
{
...
...
@@ -184,12 +208,25 @@ const open = async (type: string, id?: number) => {
if
(
id
)
{
formLoading
.
value
=
true
try
{
formData
.
value
=
await
CustomerInfoApi
.
getCustomerInfo
(
id
)
formData
.
value
=
await
CustomerInfoApi
.
getCustomerInfo
(
id
)
//进入页面根据id获取数据
restoreSelectedOptionsFromForm
();
}
finally
{
formLoading
.
value
=
false
}
}
}
function
restoreSelectedOptionsFromForm
()
{
const
province
=
formData
.
value
.
provinceName
??
''
let
city
=
formData
.
value
.
cityName
??
''
const
area
=
formData
.
value
.
areaName
??
''
//如果是直辖市,cityName要重新赋值为市辖区,否则无法回显
if
(
province
.
match
(
/
(
北京|上海|天津|重庆
)
/
)){
city
=
'
市辖区
'
}
selectedOptions
.
value
=
[
province
,
city
,
area
]
}
const
handleChange
=
(
value
:
string
[])
=>
{
//给省市区和所在地区赋值
const
[
province
,
city
,
area
]
=
value
...
...
@@ -251,5 +288,7 @@ const resetForm = () => {
department
:
undefined
,
}
formRef
.
value
?.
resetFields
()
selectedOptions
.
value
=
[];
}
</
script
>
yudao-ui/yudao-ui-admin-vue3/src/views/visit/customerinfo/index.vue
View file @
db94161b
...
...
@@ -105,6 +105,11 @@
:formatter=
"dateFormatter"
width=
"180px"
/>
<el-table-column
label=
"产品信息"
prop=
"productIds"
>
<
template
#default
="
scope
"
>
<ProductList
:ids=
scope.row.productIds
/>
</
template
>
</el-table-column>
<el-table-column
label=
"操作"
align=
"center"
min-width=
"120px"
>
<
template
#default
="
scope
"
>
<el-button
...
...
@@ -145,6 +150,7 @@ import { dateFormatter } from '@/utils/formatTime'
import
download
from
'
@/utils/download
'
import
{
CustomerInfoApi
,
CustomerInfoVO
}
from
'
@/api/visit/customerinfo
'
import
CustomerInfoForm
from
'
./CustomerInfoForm.vue
'
import
ProductList
from
"
@/views/visit/util/ProductList.vue
"
;
/** 客户信息 列表 */
defineOptions
({
name
:
'
CustomerInfo
'
})
...
...
yudao-ui/yudao-ui-admin-vue3/src/views/visit/customerinfo/productTable.vue
0 → 100644
View file @
db94161b
<
template
>
<el-dialog
v-model=
"dialogTableVisible"
title=
"选择产品"
width=
"800"
>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class=
"-mb-15px"
:model=
"queryParams"
ref=
"queryFormRef"
:inline=
"true"
label-width=
"68px"
>
<el-form-item
label=
"品种名称"
prop=
"productName"
>
<el-input
v-model=
"queryParams.productName"
placeholder=
"请输入品种名称"
clearable
@
keyup.enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"包装信息"
prop=
"packageName"
>
<el-input
v-model=
"queryParams.packageName"
placeholder=
"请输入包装信息"
clearable
@
keyup.enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"规格"
prop=
"specification"
>
<el-input
v-model=
"queryParams.specification"
placeholder=
"请输入规格"
clearable
@
keyup.enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"状态"
prop=
"status"
>
<el-select
v-model=
"queryParams.status"
placeholder=
"请选择状态"
clearable
class=
"!w-240px"
>
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"创建时间"
prop=
"createTime"
>
<el-date-picker
v-model=
"queryParams.createTime"
value-format=
"YYYY-MM-DD HH:mm:ss"
type=
"daterange"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
:default-time=
"[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class=
"!w-220px"
/>
</el-form-item>
<el-form-item>
<el-button
@
click=
"handleQuery"
><Icon
icon=
"ep:search"
class=
"mr-5px"
/>
搜索
</el-button>
<el-button
@
click=
"resetQuery"
><Icon
icon=
"ep:refresh"
class=
"mr-5px"
/>
重置
</el-button>
<el-button
@
click=
"sendToParent"
type=
"success"
plain
>
确认
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table
:reserve-selection=
"true"
ref=
"tableRef"
v-loading=
"loading"
row-key=
"id"
:data=
"list"
:stripe=
"true"
:show-overflow-tooltip=
"true"
@
selection-change=
"handleSelectionChange"
>
<el-table-column
type=
"selection"
width=
"55"
/>
<el-table-column
label=
"编号"
align=
"center"
prop=
"id"
/>
<el-table-column
label=
"品种名称"
align=
"center"
prop=
"productName"
/>
<el-table-column
label=
"包装信息"
align=
"center"
prop=
"packageName"
/>
<el-table-column
label=
"规格"
align=
"center"
prop=
"specification"
/>
<el-table-column
label=
"状态"
align=
"center"
prop=
"status"
>
<template
#default
="
scope
"
>
<dict-tag
:type=
"DICT_TYPE.COMMON_STATUS"
:value=
"scope.row.status"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"创建时间"
align=
"center"
prop=
"createTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
</el-table>
<!-- 分页 -->
<Pagination
:total=
"total"
v-model:page=
"queryParams.pageNo"
v-model:limit=
"queryParams.pageSize"
@
pagination=
"getList"
/>
</ContentWrap>
</el-dialog>
</template>
<
script
setup
lang=
"ts"
>
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'
@/utils/dict
'
import
{
dateFormatter
}
from
'
@/utils/formatTime
'
import
{
ProductApi
,
ProductVO
}
from
'
@/api/visit/product
'
import
{
defineEmits
}
from
'
vue
'
;
const
dialogTableVisible
=
ref
(
false
)
/** 产品 列表 */
defineOptions
({
name
:
'
Product
'
})
//接受参数ids
const
props
=
defineProps
({
ids
:
{
type
:
String
,
required
:
false
,
default
:
()
=>
''
}
})
const
tableRef
=
ref
();
//表单
// 定义事件名和参数类型(可选)
const
emit
=
defineEmits
<
{
(
e
:
'
updateProduct
'
,
data
:
string
):
void
;
}
>
();
const
sendToParent
=
()
=>
{
const
joinedIds
=
multipleSelection
.
value
.
join
(
'
,
'
);
// ✅ 转为 "101,203,305"
emit
(
'
updateProduct
'
,
joinedIds
);
// ✅ 传 string 给父组件
dialogTableVisible
.
value
=
false
;
// ✅ 关闭弹窗
};
const
loading
=
ref
(
true
)
// 列表的加载中
const
list
=
ref
<
ProductVO
[]
>
([])
// 列表的数据
const
total
=
ref
(
0
)
// 列表的总页数
const
queryParams
=
reactive
({
pageNo
:
1
,
pageSize
:
10
,
productName
:
undefined
,
packageName
:
undefined
,
specification
:
undefined
,
status
:
undefined
,
createTime
:
[],
})
const
queryFormRef
=
ref
()
// 搜索的表单
const
multipleSelection
=
ref
<
any
[]
>
([])
//存储多选内容
// 打开弹窗
const
open
=
()
=>
{
dialogTableVisible
.
value
=
true
//先清除勾选,再重新匹配勾选的反显
tableRef
.
value
?.
clearSelection
();
if
(
props
.
ids
&&
props
.
ids
.
trim
()
!==
''
)
{
multipleSelection
.
value
=
props
.
ids
.
split
(
'
,
'
).
map
(
item
=>
Number
(
item
))
//将父组件传递过来的ids转为数组
}
getList
().
then
(()
=>
{
toggleDefaultSelection
();
});
}
/** 多选操作**/
const
handleSelectionChange
=
(
val
)
=>
{
multipleSelection
.
value
=
val
.
map
(
item
=>
item
.
id
)
console
.
log
(
val
,
multipleSelection
)
}
/** 查询列表 */
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
const
data
=
await
ProductApi
.
getProductPage
(
queryParams
)
list
.
value
=
data
.
list
total
.
value
=
data
.
total
}
finally
{
loading
.
value
=
false
}
}
/** 回显已选择 */
const
toggleDefaultSelection
=
()
=>
{
nextTick
(()
=>
{
multipleSelection
.
value
.
forEach
(
id
=>
{
const
row
=
list
.
value
.
find
(
item
=>
item
.
id
===
id
);
if
(
row
)
{
tableRef
.
value
?.
toggleRowSelection
(
row
,
true
);
}
});
});
};
/** 搜索按钮操作 */
const
handleQuery
=
()
=>
{
queryParams
.
pageNo
=
1
getList
()
}
/** 重置按钮操作 */
const
resetQuery
=
()
=>
{
queryFormRef
.
value
.
resetFields
()
handleQuery
()
}
/** 初始化 **/
onMounted
(()
=>
{
})
// 暴露函数
defineExpose
({
open
});
</
script
>
<
style
scoped
lang=
"scss"
>
</
style
>
yudao-ui/yudao-ui-admin-vue3/src/views/visit/info/InfoForm.vue
View file @
db94161b
This diff is collapsed.
Click to expand it.
yudao-ui/yudao-ui-admin-vue3/src/views/visit/info/index.vue
View file @
db94161b
...
...
@@ -137,8 +137,13 @@
<el-table-column
label=
"拜访人姓名"
align=
"center"
prop=
"customerName"
width=
"100px"
/>
<el-table-column
label=
"联系方式"
align=
"center"
prop=
"contact"
/>
<el-table-column
label=
"客户公司名称"
align=
"center"
prop=
"companyName"
width=
"120px"
/>
<el-table-column
label=
"所在省市区"
align=
"center"
prop=
"regionFullName"
width=
"100px"
/>
<el-table-column
label=
"拜访日期"
align=
"center"
prop=
"visitDate"
/>
<el-table-column
label=
"性质等级"
align=
"center"
prop=
"customerStatus"
/>
<el-table-column
label=
"性质等级"
align=
"center"
prop=
"customerStatus"
>
<template
#default
="
scope
"
>
<dict-tag
:type=
"DICT_TYPE.CUSTOMER_TYPE"
:value=
"scope.row.customerStatus"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"拜访品种"
align=
"center"
prop=
"visitProductIds"
/>
<el-table-column
label=
"拜访方式"
align=
"center"
prop=
"visitMethod"
>
<
template
#default
="
scope
"
>
...
...
yudao-ui/yudao-ui-admin-vue3/src/views/visit/product/index.vue
View file @
db94161b
...
...
@@ -95,7 +95,8 @@
<!-- 列表 -->
<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"
@
selection-change=
"handleSelectionChange"
>
<el-table-column
type=
"selection"
width=
"55"
/>
<el-table-column
label=
"编号"
align=
"center"
prop=
"id"
/>
<el-table-column
label=
"品种名称"
align=
"center"
prop=
"productName"
/>
<el-table-column
label=
"包装信息"
align=
"center"
prop=
"packageName"
/>
...
...
@@ -161,7 +162,7 @@ defineOptions({ name: 'Product' })
const
message
=
useMessage
()
// 消息弹窗
const
{
t
}
=
useI18n
()
// 国际化
// const selectable = (row) => ![1, 2].includes(row.id)
const
loading
=
ref
(
true
)
// 列表的加载中
const
list
=
ref
<
ProductVO
[]
>
([])
// 列表的数据
const
total
=
ref
(
0
)
// 列表的总页数
...
...
@@ -176,7 +177,13 @@ const queryParams = reactive({
})
const
queryFormRef
=
ref
()
// 搜索的表单
const
exportLoading
=
ref
(
false
)
// 导出的加载中
const
multipleSelection
=
ref
([])
//存储多选内容
/** 多选操作**/
const
handleSelectionChange
=
(
val
)
=>
{
multipleSelection
.
value
=
val
.
map
(
item
=>
item
.
id
)
console
.
log
(
val
,
multipleSelection
)
}
/** 查询列表 */
const
getList
=
async
()
=>
{
loading
.
value
=
true
...
...
yudao-ui/yudao-ui-admin-vue3/src/views/visit/util/ProductList.vue
0 → 100644
View file @
db94161b
<
template
>
<el-popover
placement=
"right"
width=
"500"
trigger=
"click"
>
<template
#reference
>
<el-button
link
type=
"primary"
@
click=
"getHandler"
>
点击查看
</el-button>
</
template
>
<el-table
:data=
"gridData"
>
<el-table-column
width=
"150"
property=
"productName"
label=
"品种名称"
/>
<el-table-column
width=
"150"
property=
"packageName"
label=
"包装信息"
/>
<el-table-column
width=
"200"
property=
"specification"
label=
"规格"
/>
</el-table>
</el-popover>
</template>
<
script
lang=
"ts"
setup
>
import
{
defineProps
}
from
'
vue
'
import
{
ProductApi
}
from
"
@/api/visit/product
"
;
const
props
=
defineProps
({
ids
:
{
type
:
String
,
required
:
true
}
})
interface
Product
{
productName
:
string
packageName
:
string
specification
:
string
}
const
gridData
=
ref
<
Product
[]
>
([])
// 修正5:添加函数返回值类型
const
getHandler
=
async
():
Promise
<
void
>
=>
{
try
{
gridData
.
value
=
await
ProductApi
.
getProductByIds
(
props
.
ids
)
// 显式使用props
console
.
log
(
gridData
);
}
catch
(
error
)
{
console
.
error
(
'
获取产品失败:
'
,
error
)
gridData
.
value
=
[]
}
}
</
script
>
yudao-ui/yudao-ui-admin-vue3/tsconfig.json
View file @
db94161b
...
...
@@ -4,7 +4,7 @@
"useDefineForClassFields"
:
true
,
"module"
:
"esnext"
,
"moduleResolution"
:
"node"
,
"strict"
:
tru
e
,
"strict"
:
fals
e
,
"jsx"
:
"preserve"
,
"sourceMap"
:
true
,
"resolveJsonModule"
:
true
,
...
...
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