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
20a8a2b4
Commit
20a8a2b4
authored
May 29, 2025
by
法拉51246
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
产品、客户、拜访记录三个业务模块创建
关闭租户
parent
90358580
Changes
43
Hide whitespace changes
Inline
Side-by-side
Showing
43 changed files
with
2993 additions
and
38 deletions
+2993
-38
pom.xml
yudao-module-visit/pom.xml
+10
-6
DemoTestController.java
...dao/module/visit/controller/admin/DemoTestController.java
+0
-30
CustomerInfoController.java
...controller/admin/customerinfo/CustomerInfoController.java
+95
-0
CustomerInfoPageReqVO.java
...ntroller/admin/customerinfo/vo/CustomerInfoPageReqVO.java
+38
-0
CustomerInfoRespVO.java
.../controller/admin/customerinfo/vo/CustomerInfoRespVO.java
+47
-0
CustomerInfoSaveReqVO.java
...ntroller/admin/customerinfo/vo/CustomerInfoSaveReqVO.java
+70
-0
InfoController.java
...ao/module/visit/controller/admin/info/InfoController.java
+95
-0
InfoPageReqVO.java
.../module/visit/controller/admin/info/vo/InfoPageReqVO.java
+49
-0
InfoRespVO.java
...dao/module/visit/controller/admin/info/vo/InfoRespVO.java
+62
-0
InfoSaveReqVO.java
.../module/visit/controller/admin/info/vo/InfoSaveReqVO.java
+84
-0
ProductController.java
...ule/visit/controller/admin/product/ProductController.java
+99
-0
ProductPageReqVO.java
...e/visit/controller/admin/product/vo/ProductPageReqVO.java
+34
-0
ProductRespVO.java
...dule/visit/controller/admin/product/vo/ProductRespVO.java
+42
-0
ProductSaveReqVO.java
...e/visit/controller/admin/product/vo/ProductSaveReqVO.java
+30
-0
CustomerInfoDO.java
...ule/visit/dal/dataobject/customerinfo/CustomerInfoDO.java
+105
-0
InfoDO.java
...ocoder/yudao/module/visit/dal/dataobject/info/InfoDO.java
+123
-0
ProductDO.java
.../yudao/module/visit/dal/dataobject/product/ProductDO.java
+49
-0
CustomerInfoMapper.java
...dule/visit/dal/mysql/customerinfo/CustomerInfoMapper.java
+31
-0
InfoMapper.java
...iocoder/yudao/module/visit/dal/mysql/info/InfoMapper.java
+34
-0
ProductMapper.java
...r/yudao/module/visit/dal/mysql/product/ProductMapper.java
+30
-0
ErrorCodeConstants.java
.../iocoder/yudao/module/visit/enums/ErrorCodeConstants.java
+20
-0
CustomerInfoService.java
...odule/visit/service/customerinfo/CustomerInfoService.java
+55
-0
CustomerInfoServiceImpl.java
...e/visit/service/customerinfo/CustomerInfoServiceImpl.java
+74
-0
InfoService.java
.../iocoder/yudao/module/visit/service/info/InfoService.java
+55
-0
InfoServiceImpl.java
...oder/yudao/module/visit/service/info/InfoServiceImpl.java
+74
-0
ProductService.java
...er/yudao/module/visit/service/product/ProductService.java
+55
-0
ProductServiceImpl.java
...udao/module/visit/service/product/ProductServiceImpl.java
+74
-0
CustomerInfoMapper.xml
...main/resources/mapper/customerinfo/CustomerInfoMapper.xml
+12
-0
InfoMapper.xml
...odule-visit/src/main/resources/mapper/info/InfoMapper.xml
+12
-0
ProductMapper.xml
...visit/src/main/resources/mapper/product/ProductMapper.xml
+12
-0
application.yaml
yudao-server/src/main/resources/application.yaml
+1
-1
.env
yudao-ui/yudao-ui-admin-vue3/.env
+1
-1
logo.png
yudao-ui/yudao-ui-admin-vue3/public/logo.png
+0
-0
index.ts
...i/yudao-ui-admin-vue3/src/api/visit/customerinfo/index.ts
+53
-0
index.ts
yudao-ui/yudao-ui-admin-vue3/src/api/visit/info/index.ts
+57
-0
index.ts
yudao-ui/yudao-ui-admin-vue3/src/api/visit/product/index.ts
+43
-0
dict.ts
yudao-ui/yudao-ui-admin-vue3/src/utils/dict.ts
+6
-0
CustomerInfoForm.vue
...in-vue3/src/views/visit/customerinfo/CustomerInfoForm.vue
+183
-0
index.vue
...udao-ui-admin-vue3/src/views/visit/customerinfo/index.vue
+233
-0
InfoForm.vue
...-ui/yudao-ui-admin-vue3/src/views/visit/info/InfoForm.vue
+210
-0
index.vue
yudao-ui/yudao-ui-admin-vue3/src/views/visit/info/index.vue
+288
-0
ProductForm.vue
...dao-ui-admin-vue3/src/views/visit/product/ProductForm.vue
+117
-0
index.vue
...-ui/yudao-ui-admin-vue3/src/views/visit/product/index.vue
+231
-0
No files found.
yudao-module-visit/pom.xml
View file @
20a8a2b4
...
...
@@ -3,18 +3,18 @@
<parent>
<groupId>
cn.iocoder.boot
</groupId>
<artifactId>
yudao
</artifactId>
<version>
${revision}
</version>
<version>
${revision}
</version>
<!-- 1. 修改 version 为 ${revision} -->
</parent>
<modelVersion>
4.0.0
</modelVersion>
<artifactId>
yudao-module-visit
</artifactId>
<packaging>
jar
</packaging>
<packaging>
jar
</packaging>
<!-- 2. 新增 packaging 为 jar -->
<name>
${project.artifactId}
</name>
<description>
visit 模块,主要实现 拜访
系统主要业务逻辑
。
<name>
${project.artifactId}
</name>
<!-- 3. 新增 name 为 ${project.artifactId} -->
<description>
<!-- 4. 新增 description 为该模块的描述 -->
visit 模块,主要实现 拜访
等功能
。
</description>
<dependencies>
<dependencies>
<!-- 5. 新增依赖,这里引入的都是比较常用的业务组件、技术组件 -->
<!-- Web 相关 -->
<dependency>
<groupId>
cn.iocoder.boot
</groupId>
...
...
@@ -37,6 +37,10 @@
<groupId>
cn.iocoder.boot
</groupId>
<artifactId>
yudao-spring-boot-starter-test
</artifactId>
</dependency>
<dependency>
<groupId>
cn.iocoder.boot
</groupId>
<artifactId>
yudao-spring-boot-starter-excel
</artifactId>
</dependency>
</dependencies>
</project>
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/DemoTestController.java
deleted
100644 → 0
View file @
90358580
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
controller
.
admin
;
import
cn.iocoder.yudao.framework.common.pojo.CommonResult
;
import
io.swagger.v3.oas.annotations.tags.Tag
;
import
io.swagger.v3.oas.annotations.Operation
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
pojo
.
CommonResult
.
success
;
@Tag
(
name
=
"管理后台 - Test"
)
@RestController
@RequestMapping
(
"/demo/test"
)
@Validated
public
class
DemoTestController
{
// 这个构造方法,只是方便大家,验证 Controller 有生效
public
DemoTestController
()
{
System
.
out
.
println
(
getClass
()
+
"生效啦!!!"
);
}
@GetMapping
(
"/get"
)
@Operation
(
summary
=
"获取 test 信息"
)
public
CommonResult
<
String
>
get
()
{
return
success
(
"true"
);
}
}
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/CustomerInfoController.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
controller
.
admin
.
customerinfo
;
import
org.springframework.web.bind.annotation.*
;
import
javax.annotation.Resource
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
io.swagger.v3.oas.annotations.tags.Tag
;
import
io.swagger.v3.oas.annotations.Parameter
;
import
io.swagger.v3.oas.annotations.Operation
;
import
javax.validation.constraints.*
;
import
javax.validation.*
;
import
javax.servlet.http.*
;
import
java.util.*
;
import
java.io.IOException
;
import
cn.iocoder.yudao.framework.common.pojo.PageParam
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.common.pojo.CommonResult
;
import
cn.iocoder.yudao.framework.common.util.object.BeanUtils
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
pojo
.
CommonResult
.
success
;
import
cn.iocoder.yudao.framework.excel.core.util.ExcelUtils
;
import
cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
apilog
.
core
.
enums
.
OperateTypeEnum
.*;
import
cn.iocoder.yudao.module.visit.controller.admin.customerinfo.vo.*
;
import
cn.iocoder.yudao.module.visit.dal.dataobject.customerinfo.CustomerInfoDO
;
import
cn.iocoder.yudao.module.visit.service.customerinfo.CustomerInfoService
;
@Tag
(
name
=
"管理后台 - 客户信息"
)
@RestController
@RequestMapping
(
"/visit/customer-info"
)
@Validated
public
class
CustomerInfoController
{
@Resource
private
CustomerInfoService
customerInfoService
;
@PostMapping
(
"/create"
)
@Operation
(
summary
=
"创建客户信息"
)
@PreAuthorize
(
"@ss.hasPermission('visit:customer-info:create')"
)
public
CommonResult
<
Long
>
createCustomerInfo
(
@Valid
@RequestBody
CustomerInfoSaveReqVO
createReqVO
)
{
return
success
(
customerInfoService
.
createCustomerInfo
(
createReqVO
));
}
@PutMapping
(
"/update"
)
@Operation
(
summary
=
"更新客户信息"
)
@PreAuthorize
(
"@ss.hasPermission('visit:customer-info:update')"
)
public
CommonResult
<
Boolean
>
updateCustomerInfo
(
@Valid
@RequestBody
CustomerInfoSaveReqVO
updateReqVO
)
{
customerInfoService
.
updateCustomerInfo
(
updateReqVO
);
return
success
(
true
);
}
@DeleteMapping
(
"/delete"
)
@Operation
(
summary
=
"删除客户信息"
)
@Parameter
(
name
=
"id"
,
description
=
"编号"
,
required
=
true
)
@PreAuthorize
(
"@ss.hasPermission('visit:customer-info:delete')"
)
public
CommonResult
<
Boolean
>
deleteCustomerInfo
(
@RequestParam
(
"id"
)
Long
id
)
{
customerInfoService
.
deleteCustomerInfo
(
id
);
return
success
(
true
);
}
@GetMapping
(
"/get"
)
@Operation
(
summary
=
"获得客户信息"
)
@Parameter
(
name
=
"id"
,
description
=
"编号"
,
required
=
true
,
example
=
"1024"
)
@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
));
}
@GetMapping
(
"/page"
)
@Operation
(
summary
=
"获得客户信息分页"
)
@PreAuthorize
(
"@ss.hasPermission('visit:customer-info:query')"
)
public
CommonResult
<
PageResult
<
CustomerInfoRespVO
>>
getCustomerInfoPage
(
@Valid
CustomerInfoPageReqVO
pageReqVO
)
{
PageResult
<
CustomerInfoDO
>
pageResult
=
customerInfoService
.
getCustomerInfoPage
(
pageReqVO
);
return
success
(
BeanUtils
.
toBean
(
pageResult
,
CustomerInfoRespVO
.
class
));
}
@GetMapping
(
"/export-excel"
)
@Operation
(
summary
=
"导出客户信息 Excel"
)
@PreAuthorize
(
"@ss.hasPermission('visit:customer-info:export')"
)
@ApiAccessLog
(
operateType
=
EXPORT
)
public
void
exportCustomerInfoExcel
(
@Valid
CustomerInfoPageReqVO
pageReqVO
,
HttpServletResponse
response
)
throws
IOException
{
pageReqVO
.
setPageSize
(
PageParam
.
PAGE_SIZE_NONE
);
List
<
CustomerInfoDO
>
list
=
customerInfoService
.
getCustomerInfoPage
(
pageReqVO
).
getList
();
// 导出 Excel
ExcelUtils
.
write
(
response
,
"客户信息.xls"
,
"数据"
,
CustomerInfoRespVO
.
class
,
BeanUtils
.
toBean
(
list
,
CustomerInfoRespVO
.
class
));
}
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerInfoPageReqVO.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
controller
.
admin
.
customerinfo
.
vo
;
import
lombok.*
;
import
java.util.*
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
cn.iocoder.yudao.framework.common.pojo.PageParam
;
import
java.math.BigDecimal
;
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
@EqualsAndHashCode
(
callSuper
=
true
)
@ToString
(
callSuper
=
true
)
public
class
CustomerInfoPageReqVO
extends
PageParam
{
@Schema
(
description
=
"客户姓名"
)
private
String
customerName
;
@Schema
(
description
=
"联系方式"
)
private
String
contact
;
@Schema
(
description
=
"公司名称"
)
private
String
companyName
;
@Schema
(
description
=
"性质等级"
)
private
Integer
customerType
;
@Schema
(
description
=
"市级行政区编码"
)
private
String
cityCode
;
@Schema
(
description
=
"创建时间"
)
@DateTimeFormat
(
pattern
=
FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND
)
private
LocalDateTime
[]
createTime
;
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerInfoRespVO.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
controller
.
admin
.
customerinfo
.
vo
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.*
;
import
java.util.*
;
import
java.math.BigDecimal
;
import
org.springframework.format.annotation.DateTimeFormat
;
import
java.time.LocalDateTime
;
import
com.alibaba.excel.annotation.*
;
import
cn.iocoder.yudao.framework.excel.core.annotations.DictFormat
;
import
cn.iocoder.yudao.framework.excel.core.convert.DictConvert
;
@Schema
(
description
=
"管理后台 - 客户信息 Response VO"
)
@Data
@ExcelIgnoreUnannotated
public
class
CustomerInfoRespVO
{
@Schema
(
description
=
"编号"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
,
example
=
"1"
)
@ExcelProperty
(
"编号"
)
private
Long
id
;
@Schema
(
description
=
"客户姓名"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@ExcelProperty
(
"客户姓名"
)
private
String
customerName
;
@Schema
(
description
=
"联系方式"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@ExcelProperty
(
"联系方式"
)
private
String
contact
;
@Schema
(
description
=
"公司名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@ExcelProperty
(
"公司名称"
)
private
String
companyName
;
@Schema
(
description
=
"性质等级"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@ExcelProperty
(
value
=
"性质等级"
,
converter
=
DictConvert
.
class
)
@DictFormat
(
"customer_type"
)
// TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private
Integer
customerType
;
@Schema
(
description
=
"所在地区"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@ExcelProperty
(
"所在地区"
)
private
String
regionFullName
;
@Schema
(
description
=
"创建时间"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@ExcelProperty
(
"创建时间"
)
private
LocalDateTime
createTime
;
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerInfoSaveReqVO.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
controller
.
admin
.
customerinfo
.
vo
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.*
;
import
java.util.*
;
import
javax.validation.constraints.*
;
import
java.math.BigDecimal
;
@Schema
(
description
=
"管理后台 - 客户信息新增/修改 Request VO"
)
@Data
public
class
CustomerInfoSaveReqVO
{
@Schema
(
description
=
"编号"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
,
example
=
"1"
)
private
Long
id
;
@Schema
(
description
=
"客户姓名"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"客户姓名不能为空"
)
private
String
customerName
;
@Schema
(
description
=
"联系方式"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"联系方式不能为空"
)
private
String
contact
;
@Schema
(
description
=
"公司名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"公司名称不能为空"
)
private
String
companyName
;
@Schema
(
description
=
"性质等级"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotNull
(
message
=
"性质等级不能为空"
)
private
Integer
customerType
;
@Schema
(
description
=
"省名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"省名称不能为空"
)
private
String
provinceName
;
@Schema
(
description
=
"市名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"市名称不能为空"
)
private
String
cityName
;
@Schema
(
description
=
"区名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"区名称不能为空"
)
private
String
areaName
;
@Schema
(
description
=
"所在地区"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"所在地区不能为空"
)
private
String
regionFullName
;
@Schema
(
description
=
"详细地址"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"详细地址不能为空"
)
private
String
locationText
;
@Schema
(
description
=
"经度"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotNull
(
message
=
"经度不能为空"
)
private
BigDecimal
longitude
;
@Schema
(
description
=
"纬度"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotNull
(
message
=
"纬度不能为空"
)
private
BigDecimal
latitude
;
@Schema
(
description
=
"定位静态图 URL"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"定位静态图 URL不能为空"
)
private
String
locationImage
;
@Schema
(
description
=
"产品信息"
)
private
String
productIds
;
@Schema
(
description
=
"客户部门"
)
private
String
department
;
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/InfoController.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
controller
.
admin
.
info
;
import
org.springframework.web.bind.annotation.*
;
import
javax.annotation.Resource
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
io.swagger.v3.oas.annotations.tags.Tag
;
import
io.swagger.v3.oas.annotations.Parameter
;
import
io.swagger.v3.oas.annotations.Operation
;
import
javax.validation.constraints.*
;
import
javax.validation.*
;
import
javax.servlet.http.*
;
import
java.util.*
;
import
java.io.IOException
;
import
cn.iocoder.yudao.framework.common.pojo.PageParam
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.common.pojo.CommonResult
;
import
cn.iocoder.yudao.framework.common.util.object.BeanUtils
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
pojo
.
CommonResult
.
success
;
import
cn.iocoder.yudao.framework.excel.core.util.ExcelUtils
;
import
cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
apilog
.
core
.
enums
.
OperateTypeEnum
.*;
import
cn.iocoder.yudao.module.visit.controller.admin.info.vo.*
;
import
cn.iocoder.yudao.module.visit.dal.dataobject.info.InfoDO
;
import
cn.iocoder.yudao.module.visit.service.info.InfoService
;
@Tag
(
name
=
"管理后台 - 客户拜访记录"
)
@RestController
@RequestMapping
(
"/visit/info"
)
@Validated
public
class
InfoController
{
@Resource
private
InfoService
infoService
;
@PostMapping
(
"/create"
)
@Operation
(
summary
=
"创建客户拜访记录"
)
@PreAuthorize
(
"@ss.hasPermission('visit:info:create')"
)
public
CommonResult
<
Long
>
createInfo
(
@Valid
@RequestBody
InfoSaveReqVO
createReqVO
)
{
return
success
(
infoService
.
createInfo
(
createReqVO
));
}
@PutMapping
(
"/update"
)
@Operation
(
summary
=
"更新客户拜访记录"
)
@PreAuthorize
(
"@ss.hasPermission('visit:info:update')"
)
public
CommonResult
<
Boolean
>
updateInfo
(
@Valid
@RequestBody
InfoSaveReqVO
updateReqVO
)
{
infoService
.
updateInfo
(
updateReqVO
);
return
success
(
true
);
}
@DeleteMapping
(
"/delete"
)
@Operation
(
summary
=
"删除客户拜访记录"
)
@Parameter
(
name
=
"id"
,
description
=
"编号"
,
required
=
true
)
@PreAuthorize
(
"@ss.hasPermission('visit:info:delete')"
)
public
CommonResult
<
Boolean
>
deleteInfo
(
@RequestParam
(
"id"
)
Long
id
)
{
infoService
.
deleteInfo
(
id
);
return
success
(
true
);
}
@GetMapping
(
"/get"
)
@Operation
(
summary
=
"获得客户拜访记录"
)
@Parameter
(
name
=
"id"
,
description
=
"编号"
,
required
=
true
,
example
=
"1024"
)
@PreAuthorize
(
"@ss.hasPermission('visit:info:query')"
)
public
CommonResult
<
InfoRespVO
>
getInfo
(
@RequestParam
(
"id"
)
Long
id
)
{
InfoDO
info
=
infoService
.
getInfo
(
id
);
return
success
(
BeanUtils
.
toBean
(
info
,
InfoRespVO
.
class
));
}
@GetMapping
(
"/page"
)
@Operation
(
summary
=
"获得客户拜访记录分页"
)
@PreAuthorize
(
"@ss.hasPermission('visit:info:query')"
)
public
CommonResult
<
PageResult
<
InfoRespVO
>>
getInfoPage
(
@Valid
InfoPageReqVO
pageReqVO
)
{
PageResult
<
InfoDO
>
pageResult
=
infoService
.
getInfoPage
(
pageReqVO
);
return
success
(
BeanUtils
.
toBean
(
pageResult
,
InfoRespVO
.
class
));
}
@GetMapping
(
"/export-excel"
)
@Operation
(
summary
=
"导出客户拜访记录 Excel"
)
@PreAuthorize
(
"@ss.hasPermission('visit:info:export')"
)
@ApiAccessLog
(
operateType
=
EXPORT
)
public
void
exportInfoExcel
(
@Valid
InfoPageReqVO
pageReqVO
,
HttpServletResponse
response
)
throws
IOException
{
pageReqVO
.
setPageSize
(
PageParam
.
PAGE_SIZE_NONE
);
List
<
InfoDO
>
list
=
infoService
.
getInfoPage
(
pageReqVO
).
getList
();
// 导出 Excel
ExcelUtils
.
write
(
response
,
"客户拜访记录.xls"
,
"数据"
,
InfoRespVO
.
class
,
BeanUtils
.
toBean
(
list
,
InfoRespVO
.
class
));
}
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoPageReqVO.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
controller
.
admin
.
info
.
vo
;
import
lombok.*
;
import
java.time.LocalDate
;
import
io.swagger.v3.oas.annotations.media.Schema
;
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_HOUR_MINUTE_SECOND
;
@Schema
(
description
=
"管理后台 - 客户拜访记录分页 Request VO"
)
@Data
@EqualsAndHashCode
(
callSuper
=
true
)
@ToString
(
callSuper
=
true
)
public
class
InfoPageReqVO
extends
PageParam
{
@Schema
(
description
=
"客户姓名"
)
private
String
customerName
;
@Schema
(
description
=
"联系方式(客户手机号)"
)
private
String
contact
;
@Schema
(
description
=
"客户公司名称"
)
private
String
companyName
;
@Schema
(
description
=
"拜访日期"
)
@DateTimeFormat
(
pattern
=
FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND
)
private
LocalDate
[]
visitDate
;
@Schema
(
description
=
"性质等级"
,
example
=
"1"
)
private
Integer
customerStatus
;
@Schema
(
description
=
"拜访品种(多选,逗号分隔)"
)
private
String
visitProductIds
;
@Schema
(
description
=
"拜访方式(字典)"
)
private
Integer
visitMethod
;
@Schema
(
description
=
"拜访类型(字典)"
,
example
=
"2"
)
private
Integer
visitType
;
@Schema
(
description
=
"创建时间"
)
@DateTimeFormat
(
pattern
=
FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND
)
private
LocalDateTime
[]
createTime
;
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoRespVO.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
controller
.
admin
.
info
.
vo
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.*
;
import
java.time.LocalDate
;
import
java.util.*
;
import
java.math.BigDecimal
;
import
org.springframework.format.annotation.DateTimeFormat
;
import
java.time.LocalDateTime
;
import
com.alibaba.excel.annotation.*
;
import
cn.iocoder.yudao.framework.excel.core.annotations.DictFormat
;
import
cn.iocoder.yudao.framework.excel.core.convert.DictConvert
;
@Schema
(
description
=
"管理后台 - 客户拜访记录 Response VO"
)
@Data
@ExcelIgnoreUnannotated
public
class
InfoRespVO
{
@Schema
(
description
=
"主键ID"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
,
example
=
"1"
)
@ExcelProperty
(
"主键ID"
)
private
Long
id
;
@Schema
(
description
=
"客户姓名"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@ExcelProperty
(
"客户姓名"
)
private
String
customerName
;
@Schema
(
description
=
"联系方式(客户手机号)"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@ExcelProperty
(
"联系方式(客户手机号)"
)
private
String
contact
;
@Schema
(
description
=
"客户公司名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@ExcelProperty
(
"客户公司名称"
)
private
String
companyName
;
@Schema
(
description
=
"拜访日期"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@ExcelProperty
(
"拜访日期"
)
private
LocalDate
visitDate
;
@Schema
(
description
=
"性质等级"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
,
example
=
"1"
)
@ExcelProperty
(
"性质等级"
)
private
Integer
customerStatus
;
@Schema
(
description
=
"拜访品种(多选,逗号分隔)"
)
@ExcelProperty
(
"拜访品种(多选,逗号分隔)"
)
private
String
visitProductIds
;
@Schema
(
description
=
"拜访方式(字典)"
)
@ExcelProperty
(
value
=
"拜访方式(字典)"
,
converter
=
DictConvert
.
class
)
@DictFormat
(
"visit_method"
)
// TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private
Integer
visitMethod
;
@Schema
(
description
=
"拜访类型(字典)"
,
example
=
"2"
)
@ExcelProperty
(
value
=
"拜访类型(字典)"
,
converter
=
DictConvert
.
class
)
@DictFormat
(
"visit_type"
)
// TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private
Integer
visitType
;
@Schema
(
description
=
"创建时间"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@ExcelProperty
(
"创建时间"
)
private
LocalDateTime
createTime
;
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoSaveReqVO.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
controller
.
admin
.
info
.
vo
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.*
;
import
java.time.LocalDate
;
import
java.util.*
;
import
javax.validation.constraints.*
;
import
java.math.BigDecimal
;
@Schema
(
description
=
"管理后台 - 客户拜访记录新增/修改 Request VO"
)
@Data
public
class
InfoSaveReqVO
{
@Schema
(
description
=
"主键ID"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
,
example
=
"1"
)
private
Long
id
;
@Schema
(
description
=
"客户姓名"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"客户姓名不能为空"
)
private
String
customerName
;
@Schema
(
description
=
"联系方式(客户手机号)"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"联系方式(客户手机号)不能为空"
)
private
String
contact
;
@Schema
(
description
=
"客户公司名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"客户公司名称不能为空"
)
private
String
companyName
;
@Schema
(
description
=
"省名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"省名称不能为空"
)
private
String
provinceName
;
@Schema
(
description
=
"市名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"市名称不能为空"
)
private
String
cityName
;
@Schema
(
description
=
"区名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"区名称不能为空"
)
private
String
areaName
;
@Schema
(
description
=
"定位地址文字描述"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"定位地址文字描述不能为空"
)
private
String
locationText
;
@Schema
(
description
=
"经度"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotNull
(
message
=
"经度不能为空"
)
private
BigDecimal
longitude
;
@Schema
(
description
=
"纬度"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotNull
(
message
=
"纬度不能为空"
)
private
BigDecimal
latitude
;
@Schema
(
description
=
"定位静态图URL"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotEmpty
(
message
=
"定位静态图URL不能为空"
)
private
String
locationImage
;
@Schema
(
description
=
"拜访日期"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@NotNull
(
message
=
"拜访日期不能为空"
)
private
LocalDate
visitDate
;
@Schema
(
description
=
"性质等级"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
,
example
=
"1"
)
@NotNull
(
message
=
"性质等级不能为空"
)
private
Integer
customerStatus
;
@Schema
(
description
=
"拜访品种(多选,逗号分隔)"
)
private
String
visitProductIds
;
@Schema
(
description
=
"拜访方式(字典)"
)
private
Integer
visitMethod
;
@Schema
(
description
=
"拜访类型(字典)"
,
example
=
"2"
)
private
Integer
visitType
;
@Schema
(
description
=
"服务内容"
)
private
String
serviceContent
;
@Schema
(
description
=
"客户反馈"
)
private
String
customerFeedback
;
@Schema
(
description
=
"服务记录图片URL列表(JSON数组)"
)
private
String
serviceImages
;
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/product/ProductController.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
controller
.
admin
.
product
;
import
org.springframework.web.bind.annotation.*
;
import
javax.annotation.Resource
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
io.swagger.v3.oas.annotations.tags.Tag
;
import
io.swagger.v3.oas.annotations.Parameter
;
import
io.swagger.v3.oas.annotations.Operation
;
import
javax.validation.constraints.*
;
import
javax.validation.*
;
import
javax.servlet.http.*
;
import
java.util.*
;
import
java.io.IOException
;
import
cn.iocoder.yudao.framework.common.pojo.PageParam
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.common.pojo.CommonResult
;
import
cn.iocoder.yudao.framework.common.util.object.BeanUtils
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
pojo
.
CommonResult
.
success
;
import
cn.iocoder.yudao.framework.excel.core.util.ExcelUtils
;
import
cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
apilog
.
core
.
enums
.
OperateTypeEnum
.*;
import
cn.iocoder.yudao.module.visit.controller.admin.product.vo.*
;
import
cn.iocoder.yudao.module.visit.dal.dataobject.product.ProductDO
;
import
cn.iocoder.yudao.module.visit.service.product.ProductService
;
@Tag
(
name
=
"管理后台 - 产品"
)
@RestController
@RequestMapping
(
"/visit/product"
)
@Validated
public
class
ProductController
{
@Resource
private
ProductService
productService
;
public
ProductController
(){
System
.
out
.
println
(
"生效"
);
}
@PostMapping
(
"/create"
)
@Operation
(
summary
=
"创建产品"
)
@PreAuthorize
(
"@ss.hasPermission('visit:product:create')"
)
public
CommonResult
<
Long
>
createProduct
(
@Valid
@RequestBody
ProductSaveReqVO
createReqVO
)
{
return
success
(
productService
.
createProduct
(
createReqVO
));
}
@PutMapping
(
"/update"
)
@Operation
(
summary
=
"更新产品"
)
@PreAuthorize
(
"@ss.hasPermission('visit:product:update')"
)
public
CommonResult
<
Boolean
>
updateProduct
(
@Valid
@RequestBody
ProductSaveReqVO
updateReqVO
)
{
productService
.
updateProduct
(
updateReqVO
);
return
success
(
true
);
}
@DeleteMapping
(
"/delete"
)
@Operation
(
summary
=
"删除产品"
)
@Parameter
(
name
=
"id"
,
description
=
"编号"
,
required
=
true
)
@PreAuthorize
(
"@ss.hasPermission('visit:product:delete')"
)
public
CommonResult
<
Boolean
>
deleteProduct
(
@RequestParam
(
"id"
)
Long
id
)
{
productService
.
deleteProduct
(
id
);
return
success
(
true
);
}
@GetMapping
(
"/get"
)
@Operation
(
summary
=
"获得产品"
)
@Parameter
(
name
=
"id"
,
description
=
"编号"
,
required
=
true
,
example
=
"1024"
)
@PreAuthorize
(
"@ss.hasPermission('visit:product:query')"
)
public
CommonResult
<
ProductRespVO
>
getProduct
(
@RequestParam
(
"id"
)
Long
id
)
{
ProductDO
product
=
productService
.
getProduct
(
id
);
return
success
(
BeanUtils
.
toBean
(
product
,
ProductRespVO
.
class
));
}
@GetMapping
(
"/page"
)
@Operation
(
summary
=
"获得产品分页"
)
@PreAuthorize
(
"@ss.hasPermission('visit:product:query')"
)
public
CommonResult
<
PageResult
<
ProductRespVO
>>
getProductPage
(
@Valid
ProductPageReqVO
pageReqVO
)
{
PageResult
<
ProductDO
>
pageResult
=
productService
.
getProductPage
(
pageReqVO
);
return
success
(
BeanUtils
.
toBean
(
pageResult
,
ProductRespVO
.
class
));
}
@GetMapping
(
"/export-excel"
)
@Operation
(
summary
=
"导出产品 Excel"
)
@PreAuthorize
(
"@ss.hasPermission('visit:product:export')"
)
@ApiAccessLog
(
operateType
=
EXPORT
)
public
void
exportProductExcel
(
@Valid
ProductPageReqVO
pageReqVO
,
HttpServletResponse
response
)
throws
IOException
{
pageReqVO
.
setPageSize
(
PageParam
.
PAGE_SIZE_NONE
);
List
<
ProductDO
>
list
=
productService
.
getProductPage
(
pageReqVO
).
getList
();
// 导出 Excel
ExcelUtils
.
write
(
response
,
"产品.xls"
,
"数据"
,
ProductRespVO
.
class
,
BeanUtils
.
toBean
(
list
,
ProductRespVO
.
class
));
}
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/product/vo/ProductPageReqVO.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
controller
.
admin
.
product
.
vo
;
import
lombok.*
;
import
java.util.*
;
import
io.swagger.v3.oas.annotations.media.Schema
;
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_HOUR_MINUTE_SECOND
;
@Schema
(
description
=
"管理后台 - 产品分页 Request VO"
)
@Data
@EqualsAndHashCode
(
callSuper
=
true
)
@ToString
(
callSuper
=
true
)
public
class
ProductPageReqVO
extends
PageParam
{
@Schema
(
description
=
"品种名称"
,
example
=
"阿莫西林胶囊"
)
private
String
productName
;
@Schema
(
description
=
"包装信息"
,
example
=
"盒装"
)
private
String
packageName
;
@Schema
(
description
=
"规格"
,
example
=
"10x20mg"
)
private
String
specification
;
@Schema
(
description
=
"状态(1:正常,0:禁用)"
,
example
=
"1"
)
private
Integer
status
;
@Schema
(
description
=
"创建时间"
)
@DateTimeFormat
(
pattern
=
FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND
)
private
LocalDateTime
[]
createTime
;
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/product/vo/ProductRespVO.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
controller
.
admin
.
product
.
vo
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.*
;
import
java.util.*
;
import
org.springframework.format.annotation.DateTimeFormat
;
import
java.time.LocalDateTime
;
import
com.alibaba.excel.annotation.*
;
import
cn.iocoder.yudao.framework.excel.core.annotations.DictFormat
;
import
cn.iocoder.yudao.framework.excel.core.convert.DictConvert
;
@Schema
(
description
=
"管理后台 - 产品 Response VO"
)
@Data
@ExcelIgnoreUnannotated
public
class
ProductRespVO
{
@Schema
(
description
=
"编号"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
,
example
=
"1"
)
@ExcelProperty
(
"编号"
)
private
Long
id
;
@Schema
(
description
=
"品种名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
,
example
=
"阿莫西林胶囊"
)
@ExcelProperty
(
"品种名称"
)
private
String
productName
;
@Schema
(
description
=
"包装信息"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
,
example
=
"盒装"
)
@ExcelProperty
(
"包装信息"
)
private
String
packageName
;
@Schema
(
description
=
"规格"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
,
example
=
"10x20mg"
)
@ExcelProperty
(
"规格"
)
private
String
specification
;
@Schema
(
description
=
"状态(1:正常,0:禁用)"
,
example
=
"1"
)
@ExcelProperty
(
value
=
"状态(1:正常,0:禁用)"
,
converter
=
DictConvert
.
class
)
@DictFormat
(
"common_status"
)
// TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private
Integer
status
;
@Schema
(
description
=
"创建时间"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
)
@ExcelProperty
(
"创建时间"
)
private
LocalDateTime
createTime
;
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/product/vo/ProductSaveReqVO.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
controller
.
admin
.
product
.
vo
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.*
;
import
java.util.*
;
import
javax.validation.constraints.*
;
@Schema
(
description
=
"管理后台 - 产品新增/修改 Request VO"
)
@Data
public
class
ProductSaveReqVO
{
@Schema
(
description
=
"编号"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
,
example
=
"1"
)
private
Long
id
;
@Schema
(
description
=
"品种名称"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
,
example
=
"阿莫西林胶囊"
)
@NotEmpty
(
message
=
"品种名称不能为空"
)
private
String
productName
;
@Schema
(
description
=
"包装信息"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
,
example
=
"盒装"
)
@NotEmpty
(
message
=
"包装信息不能为空"
)
private
String
packageName
;
@Schema
(
description
=
"规格"
,
requiredMode
=
Schema
.
RequiredMode
.
REQUIRED
,
example
=
"10x20mg"
)
@NotEmpty
(
message
=
"规格不能为空"
)
private
String
specification
;
@Schema
(
description
=
"状态(1:正常,0:禁用)"
,
example
=
"1"
)
private
Integer
status
;
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/dal/dataobject/customerinfo/CustomerInfoDO.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
dal
.
dataobject
.
customerinfo
;
import
lombok.*
;
import
java.util.*
;
import
java.math.BigDecimal
;
import
java.math.BigDecimal
;
import
java.time.LocalDateTime
;
import
java.time.LocalDateTime
;
import
com.baomidou.mybatisplus.annotation.*
;
import
cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO
;
/**
* 客户信息 DO
*
* @author 超级管理员
*/
@TableName
(
"visit_customer_info"
)
@KeySequence
(
"visit_customer_info_seq"
)
// 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode
(
callSuper
=
true
)
@ToString
(
callSuper
=
true
)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public
class
CustomerInfoDO
extends
BaseDO
{
/**
* 编号
*/
@TableId
private
Long
id
;
/**
* 客户姓名
*/
private
String
customerName
;
/**
* 联系方式
*/
private
String
contact
;
/**
* 公司名称
*/
private
String
companyName
;
/**
* 性质等级
*
* 枚举 {@link TODO customer_type 对应的类}
*/
private
Integer
customerType
;
/**
* 省级行政区编码
*/
private
String
provinceCode
;
/**
* 省名称
*/
private
String
provinceName
;
/**
* 市级行政区编码
*/
private
String
cityCode
;
/**
* 市名称
*/
private
String
cityName
;
/**
* 区行政区编码
*/
private
String
areaCode
;
/**
* 区名称
*/
private
String
areaName
;
/**
* 所在地区
*/
private
String
regionFullName
;
/**
* 详细地址
*/
private
String
locationText
;
/**
* 经度
*/
private
BigDecimal
longitude
;
/**
* 纬度
*/
private
BigDecimal
latitude
;
/**
* 定位静态图 URL
*/
private
String
locationImage
;
/**
* 产品信息
*/
private
String
productIds
;
/**
* 客户部门
*
* 枚举 {@link TODO customer_dept 对应的类}
*/
private
String
department
;
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/dal/dataobject/info/InfoDO.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
dal
.
dataobject
.
info
;
import
lombok.*
;
import
java.time.LocalDate
;
import
java.util.*
;
import
java.math.BigDecimal
;
import
java.math.BigDecimal
;
import
java.time.LocalDateTime
;
import
java.time.LocalDateTime
;
import
com.baomidou.mybatisplus.annotation.*
;
import
cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO
;
/**
* 客户拜访记录 DO
*
* @author 超级管理员
*/
@TableName
(
"visit_info"
)
@KeySequence
(
"visit_info_seq"
)
// 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode
(
callSuper
=
true
)
@ToString
(
callSuper
=
true
)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public
class
InfoDO
extends
BaseDO
{
/**
* 主键ID
*/
@TableId
private
Long
id
;
/**
* 客户姓名
*/
private
String
customerName
;
/**
* 联系方式(客户手机号)
*/
private
String
contact
;
/**
* 客户公司名称
*/
private
String
companyName
;
/**
* 省编码
*/
private
String
provinceCode
;
/**
* 省名称
*/
private
String
provinceName
;
/**
* 市编码
*/
private
String
cityCode
;
/**
* 市名称
*/
private
String
cityName
;
/**
* 区编码
*/
private
String
areaCode
;
/**
* 区名称
*/
private
String
areaName
;
/**
* 定位地址文字描述
*/
private
String
locationText
;
/**
* 经度
*/
private
BigDecimal
longitude
;
/**
* 纬度
*/
private
BigDecimal
latitude
;
/**
* 定位静态图URL
*/
private
String
locationImage
;
/**
* 拜访日期
*/
private
LocalDate
visitDate
;
/**
* 性质等级
*/
private
Integer
customerStatus
;
/**
* 拜访品种(多选,逗号分隔)
*/
private
String
visitProductIds
;
/**
* 拜访方式(字典)
*
* 枚举 {@link TODO visit_method 对应的类}
*/
private
Integer
visitMethod
;
/**
* 拜访类型(字典)
*
* 枚举 {@link TODO visit_type 对应的类}
*/
private
Integer
visitType
;
/**
* 服务内容
*/
private
String
serviceContent
;
/**
* 客户反馈
*/
private
String
customerFeedback
;
/**
* 服务记录图片URL列表(JSON数组)
*/
private
String
serviceImages
;
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/dal/dataobject/product/ProductDO.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
dal
.
dataobject
.
product
;
import
lombok.*
;
import
java.util.*
;
import
java.time.LocalDateTime
;
import
java.time.LocalDateTime
;
import
com.baomidou.mybatisplus.annotation.*
;
import
cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO
;
/**
* 产品 DO
*
* @author 超级管理员
*/
@TableName
(
"visit_product"
)
@KeySequence
(
"visit_product_seq"
)
// 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode
(
callSuper
=
true
)
@ToString
(
callSuper
=
true
)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public
class
ProductDO
extends
BaseDO
{
/**
* 编号
*/
@TableId
private
Long
id
;
/**
* 品种名称
*/
private
String
productName
;
/**
* 包装信息
*/
private
String
packageName
;
/**
* 规格
*/
private
String
specification
;
/**
* 状态(1:正常,0:禁用)
*
* 枚举
*/
private
Integer
status
;
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/dal/mysql/customerinfo/CustomerInfoMapper.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
dal
.
mysql
.
customerinfo
;
import
java.util.*
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX
;
import
cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX
;
import
cn.iocoder.yudao.module.visit.dal.dataobject.customerinfo.CustomerInfoDO
;
import
org.apache.ibatis.annotations.Mapper
;
import
cn.iocoder.yudao.module.visit.controller.admin.customerinfo.vo.*
;
/**
* 客户信息 Mapper
*
* @author 超级管理员
*/
@Mapper
public
interface
CustomerInfoMapper
extends
BaseMapperX
<
CustomerInfoDO
>
{
default
PageResult
<
CustomerInfoDO
>
selectPage
(
CustomerInfoPageReqVO
reqVO
)
{
return
selectPage
(
reqVO
,
new
LambdaQueryWrapperX
<
CustomerInfoDO
>()
.
likeIfPresent
(
CustomerInfoDO:
:
getCustomerName
,
reqVO
.
getCustomerName
())
.
eqIfPresent
(
CustomerInfoDO:
:
getContact
,
reqVO
.
getContact
())
.
likeIfPresent
(
CustomerInfoDO:
:
getCompanyName
,
reqVO
.
getCompanyName
())
.
eqIfPresent
(
CustomerInfoDO:
:
getCustomerType
,
reqVO
.
getCustomerType
())
.
eqIfPresent
(
CustomerInfoDO:
:
getCityCode
,
reqVO
.
getCityCode
())
.
betweenIfPresent
(
CustomerInfoDO:
:
getCreateTime
,
reqVO
.
getCreateTime
())
.
orderByDesc
(
CustomerInfoDO:
:
getId
));
}
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/dal/mysql/info/InfoMapper.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
dal
.
mysql
.
info
;
import
java.util.*
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX
;
import
cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX
;
import
cn.iocoder.yudao.module.visit.dal.dataobject.info.InfoDO
;
import
org.apache.ibatis.annotations.Mapper
;
import
cn.iocoder.yudao.module.visit.controller.admin.info.vo.*
;
/**
* 客户拜访记录 Mapper
*
* @author 超级管理员
*/
@Mapper
public
interface
InfoMapper
extends
BaseMapperX
<
InfoDO
>
{
default
PageResult
<
InfoDO
>
selectPage
(
InfoPageReqVO
reqVO
)
{
return
selectPage
(
reqVO
,
new
LambdaQueryWrapperX
<
InfoDO
>()
.
likeIfPresent
(
InfoDO:
:
getCustomerName
,
reqVO
.
getCustomerName
())
.
eqIfPresent
(
InfoDO:
:
getContact
,
reqVO
.
getContact
())
.
likeIfPresent
(
InfoDO:
:
getCompanyName
,
reqVO
.
getCompanyName
())
.
betweenIfPresent
(
InfoDO:
:
getVisitDate
,
reqVO
.
getVisitDate
())
.
eqIfPresent
(
InfoDO:
:
getCustomerStatus
,
reqVO
.
getCustomerStatus
())
.
eqIfPresent
(
InfoDO:
:
getVisitProductIds
,
reqVO
.
getVisitProductIds
())
.
eqIfPresent
(
InfoDO:
:
getVisitMethod
,
reqVO
.
getVisitMethod
())
.
eqIfPresent
(
InfoDO:
:
getVisitType
,
reqVO
.
getVisitType
())
.
betweenIfPresent
(
InfoDO:
:
getCreateTime
,
reqVO
.
getCreateTime
())
.
orderByDesc
(
InfoDO:
:
getId
));
}
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/dal/mysql/product/ProductMapper.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
dal
.
mysql
.
product
;
import
java.util.*
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX
;
import
cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX
;
import
cn.iocoder.yudao.module.visit.dal.dataobject.product.ProductDO
;
import
org.apache.ibatis.annotations.Mapper
;
import
cn.iocoder.yudao.module.visit.controller.admin.product.vo.*
;
/**
* 产品 Mapper
*
* @author 超级管理员
*/
@Mapper
public
interface
ProductMapper
extends
BaseMapperX
<
ProductDO
>
{
default
PageResult
<
ProductDO
>
selectPage
(
ProductPageReqVO
reqVO
)
{
return
selectPage
(
reqVO
,
new
LambdaQueryWrapperX
<
ProductDO
>()
.
likeIfPresent
(
ProductDO:
:
getProductName
,
reqVO
.
getProductName
())
.
eqIfPresent
(
ProductDO:
:
getPackageName
,
reqVO
.
getPackageName
())
.
eqIfPresent
(
ProductDO:
:
getSpecification
,
reqVO
.
getSpecification
())
.
eqIfPresent
(
ProductDO:
:
getStatus
,
reqVO
.
getStatus
())
.
betweenIfPresent
(
ProductDO:
:
getCreateTime
,
reqVO
.
getCreateTime
())
.
orderByDesc
(
ProductDO:
:
getId
));
}
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/enums/ErrorCodeConstants.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
enums
;
import
cn.iocoder.yudao.framework.common.exception.ErrorCode
;
/*
* System 错误码枚举类
*
* system 系统,使用 1-002-000-000 段
*/
public
interface
ErrorCodeConstants
{
// ========== 产品 ==========
ErrorCode
PRODUCT_NOT_EXISTS
=
new
ErrorCode
(
1001000001
,
"产品不存在"
);
// ========== 客户信息 ==========
ErrorCode
CUSTOMER_INFO_NOT_EXISTS
=
new
ErrorCode
(
1002000001
,
"客户信息不存在"
);
// ========== 客户拜访记录 ==========
ErrorCode
INFO_NOT_EXISTS
=
new
ErrorCode
(
1003000001
,
"客户拜访记录不存在"
);
}
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/customerinfo/CustomerInfoService.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
service
.
customerinfo
;
import
java.util.*
;
import
javax.validation.*
;
import
cn.iocoder.yudao.module.visit.controller.admin.customerinfo.vo.*
;
import
cn.iocoder.yudao.module.visit.dal.dataobject.customerinfo.CustomerInfoDO
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.common.pojo.PageParam
;
/**
* 客户信息 Service 接口
*
* @author 超级管理员
*/
public
interface
CustomerInfoService
{
/**
* 创建客户信息
*
* @param createReqVO 创建信息
* @return 编号
*/
Long
createCustomerInfo
(
@Valid
CustomerInfoSaveReqVO
createReqVO
);
/**
* 更新客户信息
*
* @param updateReqVO 更新信息
*/
void
updateCustomerInfo
(
@Valid
CustomerInfoSaveReqVO
updateReqVO
);
/**
* 删除客户信息
*
* @param id 编号
*/
void
deleteCustomerInfo
(
Long
id
);
/**
* 获得客户信息
*
* @param id 编号
* @return 客户信息
*/
CustomerInfoDO
getCustomerInfo
(
Long
id
);
/**
* 获得客户信息分页
*
* @param pageReqVO 分页查询
* @return 客户信息分页
*/
PageResult
<
CustomerInfoDO
>
getCustomerInfoPage
(
CustomerInfoPageReqVO
pageReqVO
);
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/customerinfo/CustomerInfoServiceImpl.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
service
.
customerinfo
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.*
;
import
cn.iocoder.yudao.module.visit.controller.admin.customerinfo.vo.*
;
import
cn.iocoder.yudao.module.visit.dal.dataobject.customerinfo.CustomerInfoDO
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.common.pojo.PageParam
;
import
cn.iocoder.yudao.framework.common.util.object.BeanUtils
;
import
cn.iocoder.yudao.module.visit.dal.mysql.customerinfo.CustomerInfoMapper
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
exception
.
util
.
ServiceExceptionUtil
.
exception
;
import
static
cn
.
iocoder
.
yudao
.
module
.
visit
.
enums
.
ErrorCodeConstants
.*;
/**
* 客户信息 Service 实现类
*
* @author 超级管理员
*/
@Service
@Validated
public
class
CustomerInfoServiceImpl
implements
CustomerInfoService
{
@Resource
private
CustomerInfoMapper
customerInfoMapper
;
@Override
public
Long
createCustomerInfo
(
CustomerInfoSaveReqVO
createReqVO
)
{
// 插入
CustomerInfoDO
customerInfo
=
BeanUtils
.
toBean
(
createReqVO
,
CustomerInfoDO
.
class
);
customerInfoMapper
.
insert
(
customerInfo
);
// 返回
return
customerInfo
.
getId
();
}
@Override
public
void
updateCustomerInfo
(
CustomerInfoSaveReqVO
updateReqVO
)
{
// 校验存在
validateCustomerInfoExists
(
updateReqVO
.
getId
());
// 更新
CustomerInfoDO
updateObj
=
BeanUtils
.
toBean
(
updateReqVO
,
CustomerInfoDO
.
class
);
customerInfoMapper
.
updateById
(
updateObj
);
}
@Override
public
void
deleteCustomerInfo
(
Long
id
)
{
// 校验存在
validateCustomerInfoExists
(
id
);
// 删除
customerInfoMapper
.
deleteById
(
id
);
}
private
void
validateCustomerInfoExists
(
Long
id
)
{
if
(
customerInfoMapper
.
selectById
(
id
)
==
null
)
{
throw
exception
(
CUSTOMER_INFO_NOT_EXISTS
);
}
}
@Override
public
CustomerInfoDO
getCustomerInfo
(
Long
id
)
{
return
customerInfoMapper
.
selectById
(
id
);
}
@Override
public
PageResult
<
CustomerInfoDO
>
getCustomerInfoPage
(
CustomerInfoPageReqVO
pageReqVO
)
{
return
customerInfoMapper
.
selectPage
(
pageReqVO
);
}
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/info/InfoService.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
service
.
info
;
import
java.util.*
;
import
javax.validation.*
;
import
cn.iocoder.yudao.module.visit.controller.admin.info.vo.*
;
import
cn.iocoder.yudao.module.visit.dal.dataobject.info.InfoDO
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.common.pojo.PageParam
;
/**
* 客户拜访记录 Service 接口
*
* @author 超级管理员
*/
public
interface
InfoService
{
/**
* 创建客户拜访记录
*
* @param createReqVO 创建信息
* @return 编号
*/
Long
createInfo
(
@Valid
InfoSaveReqVO
createReqVO
);
/**
* 更新客户拜访记录
*
* @param updateReqVO 更新信息
*/
void
updateInfo
(
@Valid
InfoSaveReqVO
updateReqVO
);
/**
* 删除客户拜访记录
*
* @param id 编号
*/
void
deleteInfo
(
Long
id
);
/**
* 获得客户拜访记录
*
* @param id 编号
* @return 客户拜访记录
*/
InfoDO
getInfo
(
Long
id
);
/**
* 获得客户拜访记录分页
*
* @param pageReqVO 分页查询
* @return 客户拜访记录分页
*/
PageResult
<
InfoDO
>
getInfoPage
(
InfoPageReqVO
pageReqVO
);
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/info/InfoServiceImpl.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
service
.
info
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.*
;
import
cn.iocoder.yudao.module.visit.controller.admin.info.vo.*
;
import
cn.iocoder.yudao.module.visit.dal.dataobject.info.InfoDO
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.common.pojo.PageParam
;
import
cn.iocoder.yudao.framework.common.util.object.BeanUtils
;
import
cn.iocoder.yudao.module.visit.dal.mysql.info.InfoMapper
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
exception
.
util
.
ServiceExceptionUtil
.
exception
;
import
static
cn
.
iocoder
.
yudao
.
module
.
visit
.
enums
.
ErrorCodeConstants
.*;
/**
* 客户拜访记录 Service 实现类
*
* @author 超级管理员
*/
@Service
@Validated
public
class
InfoServiceImpl
implements
InfoService
{
@Resource
private
InfoMapper
infoMapper
;
@Override
public
Long
createInfo
(
InfoSaveReqVO
createReqVO
)
{
// 插入
InfoDO
info
=
BeanUtils
.
toBean
(
createReqVO
,
InfoDO
.
class
);
infoMapper
.
insert
(
info
);
// 返回
return
info
.
getId
();
}
@Override
public
void
updateInfo
(
InfoSaveReqVO
updateReqVO
)
{
// 校验存在
validateInfoExists
(
updateReqVO
.
getId
());
// 更新
InfoDO
updateObj
=
BeanUtils
.
toBean
(
updateReqVO
,
InfoDO
.
class
);
infoMapper
.
updateById
(
updateObj
);
}
@Override
public
void
deleteInfo
(
Long
id
)
{
// 校验存在
validateInfoExists
(
id
);
// 删除
infoMapper
.
deleteById
(
id
);
}
private
void
validateInfoExists
(
Long
id
)
{
if
(
infoMapper
.
selectById
(
id
)
==
null
)
{
throw
exception
(
INFO_NOT_EXISTS
);
}
}
@Override
public
InfoDO
getInfo
(
Long
id
)
{
return
infoMapper
.
selectById
(
id
);
}
@Override
public
PageResult
<
InfoDO
>
getInfoPage
(
InfoPageReqVO
pageReqVO
)
{
return
infoMapper
.
selectPage
(
pageReqVO
);
}
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/product/ProductService.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
service
.
product
;
import
java.util.*
;
import
javax.validation.*
;
import
cn.iocoder.yudao.module.visit.controller.admin.product.vo.*
;
import
cn.iocoder.yudao.module.visit.dal.dataobject.product.ProductDO
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.common.pojo.PageParam
;
/**
* 产品 Service 接口
*
* @author 超级管理员
*/
public
interface
ProductService
{
/**
* 创建产品
*
* @param createReqVO 创建信息
* @return 编号
*/
Long
createProduct
(
@Valid
ProductSaveReqVO
createReqVO
);
/**
* 更新产品
*
* @param updateReqVO 更新信息
*/
void
updateProduct
(
@Valid
ProductSaveReqVO
updateReqVO
);
/**
* 删除产品
*
* @param id 编号
*/
void
deleteProduct
(
Long
id
);
/**
* 获得产品
*
* @param id 编号
* @return 产品
*/
ProductDO
getProduct
(
Long
id
);
/**
* 获得产品分页
*
* @param pageReqVO 分页查询
* @return 产品分页
*/
PageResult
<
ProductDO
>
getProductPage
(
ProductPageReqVO
pageReqVO
);
}
\ No newline at end of file
yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/product/ProductServiceImpl.java
0 → 100644
View file @
20a8a2b4
package
cn
.
iocoder
.
yudao
.
module
.
visit
.
service
.
product
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.*
;
import
cn.iocoder.yudao.module.visit.controller.admin.product.vo.*
;
import
cn.iocoder.yudao.module.visit.dal.dataobject.product.ProductDO
;
import
cn.iocoder.yudao.framework.common.pojo.PageResult
;
import
cn.iocoder.yudao.framework.common.pojo.PageParam
;
import
cn.iocoder.yudao.framework.common.util.object.BeanUtils
;
import
cn.iocoder.yudao.module.visit.dal.mysql.product.ProductMapper
;
import
static
cn
.
iocoder
.
yudao
.
framework
.
common
.
exception
.
util
.
ServiceExceptionUtil
.
exception
;
import
static
cn
.
iocoder
.
yudao
.
module
.
visit
.
enums
.
ErrorCodeConstants
.*;
/**
* 产品 Service 实现类
*
* @author 超级管理员
*/
@Service
@Validated
public
class
ProductServiceImpl
implements
ProductService
{
@Resource
private
ProductMapper
productMapper
;
@Override
public
Long
createProduct
(
ProductSaveReqVO
createReqVO
)
{
// 插入
ProductDO
product
=
BeanUtils
.
toBean
(
createReqVO
,
ProductDO
.
class
);
productMapper
.
insert
(
product
);
// 返回
return
product
.
getId
();
}
@Override
public
void
updateProduct
(
ProductSaveReqVO
updateReqVO
)
{
// 校验存在
validateProductExists
(
updateReqVO
.
getId
());
// 更新
ProductDO
updateObj
=
BeanUtils
.
toBean
(
updateReqVO
,
ProductDO
.
class
);
productMapper
.
updateById
(
updateObj
);
}
@Override
public
void
deleteProduct
(
Long
id
)
{
// 校验存在
validateProductExists
(
id
);
// 删除
productMapper
.
deleteById
(
id
);
}
private
void
validateProductExists
(
Long
id
)
{
if
(
productMapper
.
selectById
(
id
)
==
null
)
{
throw
exception
(
PRODUCT_NOT_EXISTS
);
}
}
@Override
public
ProductDO
getProduct
(
Long
id
)
{
return
productMapper
.
selectById
(
id
);
}
@Override
public
PageResult
<
ProductDO
>
getProductPage
(
ProductPageReqVO
pageReqVO
)
{
return
productMapper
.
selectPage
(
pageReqVO
);
}
}
\ No newline at end of file
yudao-module-visit/src/main/resources/mapper/customerinfo/CustomerInfoMapper.xml
0 → 100644
View file @
20a8a2b4
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"cn.iocoder.yudao.module.visit.dal.mysql.customerinfo.CustomerInfoMapper"
>
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>
\ No newline at end of file
yudao-module-visit/src/main/resources/mapper/info/InfoMapper.xml
0 → 100644
View file @
20a8a2b4
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"cn.iocoder.yudao.module.visit.dal.mysql.info.InfoMapper"
>
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>
\ No newline at end of file
yudao-module-visit/src/main/resources/mapper/product/ProductMapper.xml
0 → 100644
View file @
20a8a2b4
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"cn.iocoder.yudao.module.visit.dal.mysql.product.ProductMapper"
>
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>
\ No newline at end of file
yudao-server/src/main/resources/application.yaml
View file @
20a8a2b4
...
...
@@ -271,7 +271,7 @@ yudao:
front-type
:
20
# 前端模版的类型,参见 CodegenFrontTypeEnum 枚举类
unit-test-enable
:
false
# 是否生成单元测试
tenant
:
# 多租户相关配置项
enable
:
tru
e
enable
:
fals
e
ignore-urls
:
-
/jmreport/*
# 积木报表,无法携带租户编号
ignore-visit-urls
:
...
...
yudao-ui/yudao-ui-admin-vue3/.env
View file @
20a8a2b4
...
...
@@ -8,7 +8,7 @@ VITE_PORT=80
VITE_OPEN=false
# 租户开关
VITE_APP_TENANT_ENABLE=
tru
e
VITE_APP_TENANT_ENABLE=
fals
e
# 验证码的开关
VITE_APP_CAPTCHA_ENABLE=true
...
...
yudao-ui/yudao-ui-admin-vue3/public/logo.png
0 → 100644
View file @
20a8a2b4
317 KB
yudao-ui/yudao-ui-admin-vue3/src/api/visit/customerinfo/index.ts
0 → 100644
View file @
20a8a2b4
import
request
from
'
@/config/axios
'
// 客户信息 VO
export
interface
CustomerInfoVO
{
id
:
number
// 编号
customerName
:
string
// 客户姓名
contact
:
string
// 联系方式
companyName
:
string
// 公司名称
customerType
:
number
// 性质等级
provinceName
:
string
// 省名称
cityName
:
string
// 市名称
areaName
:
string
// 区名称
regionFullName
:
string
// 所在地区
locationText
:
string
// 详细地址
longitude
:
number
// 经度
latitude
:
number
// 纬度
locationImage
:
string
// 定位静态图 URL
productIds
:
string
// 产品信息
department
:
string
// 客户部门
}
// 客户信息 API
export
const
CustomerInfoApi
=
{
// 查询客户信息分页
getCustomerInfoPage
:
async
(
params
:
any
)
=>
{
return
await
request
.
get
({
url
:
`/visit/customer-info/page`
,
params
})
},
// 查询客户信息详情
getCustomerInfo
:
async
(
id
:
number
)
=>
{
return
await
request
.
get
({
url
:
`/visit/customer-info/get?id=`
+
id
})
},
// 新增客户信息
createCustomerInfo
:
async
(
data
:
CustomerInfoVO
)
=>
{
return
await
request
.
post
({
url
:
`/visit/customer-info/create`
,
data
})
},
// 修改客户信息
updateCustomerInfo
:
async
(
data
:
CustomerInfoVO
)
=>
{
return
await
request
.
put
({
url
:
`/visit/customer-info/update`
,
data
})
},
// 删除客户信息
deleteCustomerInfo
:
async
(
id
:
number
)
=>
{
return
await
request
.
delete
({
url
:
`/visit/customer-info/delete?id=`
+
id
})
},
// 导出客户信息 Excel
exportCustomerInfo
:
async
(
params
)
=>
{
return
await
request
.
download
({
url
:
`/visit/customer-info/export-excel`
,
params
})
},
}
\ No newline at end of file
yudao-ui/yudao-ui-admin-vue3/src/api/visit/info/index.ts
0 → 100644
View file @
20a8a2b4
import
request
from
'
@/config/axios
'
// 客户拜访记录 VO
export
interface
InfoVO
{
id
:
number
// 主键ID
customerName
:
string
// 客户姓名
contact
:
string
// 联系方式(客户手机号)
companyName
:
string
// 客户公司名称
provinceName
:
string
// 省名称
cityName
:
string
// 市名称
areaName
:
string
// 区名称
locationText
:
string
// 定位地址文字描述
longitude
:
number
// 经度
latitude
:
number
// 纬度
locationImage
:
string
// 定位静态图URL
visitDate
:
Date
// 拜访日期
customerStatus
:
number
// 性质等级
visitProductIds
:
string
// 拜访品种(多选,逗号分隔)
visitMethod
:
number
// 拜访方式(字典)
visitType
:
number
// 拜访类型(字典)
serviceContent
:
string
// 服务内容
customerFeedback
:
string
// 客户反馈
serviceImages
:
string
// 服务记录图片URL列表(JSON数组)
}
// 客户拜访记录 API
export
const
InfoApi
=
{
// 查询客户拜访记录分页
getInfoPage
:
async
(
params
:
any
)
=>
{
return
await
request
.
get
({
url
:
`/visit/info/page`
,
params
})
},
// 查询客户拜访记录详情
getInfo
:
async
(
id
:
number
)
=>
{
return
await
request
.
get
({
url
:
`/visit/info/get?id=`
+
id
})
},
// 新增客户拜访记录
createInfo
:
async
(
data
:
InfoVO
)
=>
{
return
await
request
.
post
({
url
:
`/visit/info/create`
,
data
})
},
// 修改客户拜访记录
updateInfo
:
async
(
data
:
InfoVO
)
=>
{
return
await
request
.
put
({
url
:
`/visit/info/update`
,
data
})
},
// 删除客户拜访记录
deleteInfo
:
async
(
id
:
number
)
=>
{
return
await
request
.
delete
({
url
:
`/visit/info/delete?id=`
+
id
})
},
// 导出客户拜访记录 Excel
exportInfo
:
async
(
params
)
=>
{
return
await
request
.
download
({
url
:
`/visit/info/export-excel`
,
params
})
},
}
\ No newline at end of file
yudao-ui/yudao-ui-admin-vue3/src/api/visit/product/index.ts
0 → 100644
View file @
20a8a2b4
import
request
from
'
@/config/axios
'
// 产品 VO
export
interface
ProductVO
{
id
:
number
// 编号
productName
:
string
// 品种名称
packageName
:
string
// 包装信息
specification
:
string
// 规格
status
:
number
// 状态(1:正常,0:禁用)
}
// 产品 API
export
const
ProductApi
=
{
// 查询产品分页
getProductPage
:
async
(
params
:
any
)
=>
{
return
await
request
.
get
({
url
:
`/visit/product/page`
,
params
})
},
// 查询产品详情
getProduct
:
async
(
id
:
number
)
=>
{
return
await
request
.
get
({
url
:
`/visit/product/get?id=`
+
id
})
},
// 新增产品
createProduct
:
async
(
data
:
ProductVO
)
=>
{
return
await
request
.
post
({
url
:
`/visit/product/create`
,
data
})
},
// 修改产品
updateProduct
:
async
(
data
:
ProductVO
)
=>
{
return
await
request
.
put
({
url
:
`/visit/product/update`
,
data
})
},
// 删除产品
deleteProduct
:
async
(
id
:
number
)
=>
{
return
await
request
.
delete
({
url
:
`/visit/product/delete?id=`
+
id
})
},
// 导出产品 Excel
exportProduct
:
async
(
params
)
=>
{
return
await
request
.
download
({
url
:
`/visit/product/export-excel`
,
params
})
},
}
yudao-ui/yudao-ui-admin-vue3/src/utils/dict.ts
View file @
20a8a2b4
...
...
@@ -113,6 +113,12 @@ export enum DICT_TYPE {
TERMINAL
=
'
terminal
'
,
// 终端
DATE_INTERVAL
=
'
date_interval
'
,
// 数据间隔
// ========== VISIT 模块 ==========
CUSTOMER_TYPE
=
'
customer_type
'
,
CUSTOMER_DEPT
=
'
customer_dept
'
,
VISIT_METHOD
=
'
visit_method
'
,
VISIT_TYPE
=
'
visit_type
'
,
// ========== SYSTEM 模块 ==========
SYSTEM_USER_SEX
=
'
system_user_sex
'
,
SYSTEM_MENU_TYPE
=
'
system_menu_type
'
,
...
...
yudao-ui/yudao-ui-admin-vue3/src/views/visit/customerinfo/CustomerInfoForm.vue
0 → 100644
View file @
20a8a2b4
<
template
>
<Dialog
:title=
"dialogTitle"
v-model=
"dialogVisible"
>
<el-form
ref=
"formRef"
:model=
"formData"
:rules=
"formRules"
label-width=
"100px"
v-loading=
"formLoading"
>
<el-form-item
label=
"客户姓名"
prop=
"customerName"
>
<el-input
v-model=
"formData.customerName"
placeholder=
"请输入客户姓名"
/>
</el-form-item>
<el-form-item
label=
"联系方式"
prop=
"contact"
>
<el-input
v-model=
"formData.contact"
placeholder=
"请输入联系方式"
/>
</el-form-item>
<el-form-item
label=
"公司名称"
prop=
"companyName"
>
<el-input
v-model=
"formData.companyName"
placeholder=
"请输入公司名称"
/>
</el-form-item>
<el-form-item
label=
"性质等级"
prop=
"customerType"
>
<el-select
v-model=
"formData.customerType"
placeholder=
"请选择性质等级"
>
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.CUSTOMER_TYPE)"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"省名称"
prop=
"provinceName"
>
<el-input
v-model=
"formData.provinceName"
placeholder=
"请输入省名称"
/>
</el-form-item>
<el-form-item
label=
"市名称"
prop=
"cityName"
>
<el-input
v-model=
"formData.cityName"
placeholder=
"请输入市名称"
/>
</el-form-item>
<el-form-item
label=
"区名称"
prop=
"areaName"
>
<el-input
v-model=
"formData.areaName"
placeholder=
"请输入区名称"
/>
</el-form-item>
<el-form-item
label=
"所在地区"
prop=
"regionFullName"
>
<el-input
v-model=
"formData.regionFullName"
placeholder=
"请输入所在地区"
/>
</el-form-item>
<el-form-item
label=
"详细地址"
prop=
"locationText"
>
<el-input
v-model=
"formData.locationText"
placeholder=
"请输入详细地址"
/>
</el-form-item>
<el-form-item
label=
"经度"
prop=
"longitude"
>
<el-input
v-model=
"formData.longitude"
placeholder=
"请输入经度"
/>
</el-form-item>
<el-form-item
label=
"纬度"
prop=
"latitude"
>
<el-input
v-model=
"formData.latitude"
placeholder=
"请输入纬度"
/>
</el-form-item>
<el-form-item
label=
"定位静态图 URL"
prop=
"locationImage"
>
<UploadImg
v-model=
"formData.locationImage"
/>
</el-form-item>
<el-form-item
label=
"产品信息"
prop=
"productIds"
>
<el-input
v-model=
"formData.productIds"
placeholder=
"请输入产品信息"
/>
</el-form-item>
<el-form-item
label=
"客户部门"
prop=
"department"
>
<el-select
v-model=
"formData.department"
placeholder=
"请选择客户部门"
>
<el-option
v-for=
"dict in getStrDictOptions(DICT_TYPE.CUSTOMER_DEPT)"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
</el-form>
<template
#footer
>
<el-button
@
click=
"submitForm"
type=
"primary"
:disabled=
"formLoading"
>
确 定
</el-button>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
</
template
>
</Dialog>
</template>
<
script
setup
lang=
"ts"
>
import
{
getIntDictOptions
,
getStrDictOptions
,
DICT_TYPE
}
from
'
@/utils/dict
'
import
{
CustomerInfoApi
,
CustomerInfoVO
}
from
'
@/api/visit/customerinfo
'
/** 客户信息 表单 */
defineOptions
({
name
:
'
CustomerInfoForm
'
})
const
{
t
}
=
useI18n
()
// 国际化
const
message
=
useMessage
()
// 消息弹窗
const
dialogVisible
=
ref
(
false
)
// 弹窗的是否展示
const
dialogTitle
=
ref
(
''
)
// 弹窗的标题
const
formLoading
=
ref
(
false
)
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const
formType
=
ref
(
''
)
// 表单的类型:create - 新增;update - 修改
const
formData
=
ref
({
id
:
undefined
,
customerName
:
undefined
,
contact
:
undefined
,
companyName
:
undefined
,
customerType
:
undefined
,
provinceName
:
undefined
,
cityName
:
undefined
,
areaName
:
undefined
,
regionFullName
:
undefined
,
locationText
:
undefined
,
longitude
:
undefined
,
latitude
:
undefined
,
locationImage
:
undefined
,
productIds
:
undefined
,
department
:
undefined
,
})
const
formRules
=
reactive
({
customerName
:
[{
required
:
true
,
message
:
'
客户姓名不能为空
'
,
trigger
:
'
blur
'
}],
contact
:
[{
required
:
true
,
message
:
'
联系方式不能为空
'
,
trigger
:
'
blur
'
}],
companyName
:
[{
required
:
true
,
message
:
'
公司名称不能为空
'
,
trigger
:
'
blur
'
}],
customerType
:
[{
required
:
true
,
message
:
'
性质等级不能为空
'
,
trigger
:
'
change
'
}],
provinceName
:
[{
required
:
true
,
message
:
'
省名称不能为空
'
,
trigger
:
'
blur
'
}],
cityName
:
[{
required
:
true
,
message
:
'
市名称不能为空
'
,
trigger
:
'
blur
'
}],
areaName
:
[{
required
:
true
,
message
:
'
区名称不能为空
'
,
trigger
:
'
blur
'
}],
regionFullName
:
[{
required
:
true
,
message
:
'
所在地区不能为空
'
,
trigger
:
'
blur
'
}],
locationText
:
[{
required
:
true
,
message
:
'
详细地址不能为空
'
,
trigger
:
'
blur
'
}],
longitude
:
[{
required
:
true
,
message
:
'
经度不能为空
'
,
trigger
:
'
blur
'
}],
latitude
:
[{
required
:
true
,
message
:
'
纬度不能为空
'
,
trigger
:
'
blur
'
}],
locationImage
:
[{
required
:
true
,
message
:
'
定位静态图 URL不能为空
'
,
trigger
:
'
blur
'
}],
})
const
formRef
=
ref
()
// 表单 Ref
/** 打开弹窗 */
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
dialogVisible
.
value
=
true
dialogTitle
.
value
=
t
(
'
action.
'
+
type
)
formType
.
value
=
type
resetForm
()
// 修改时,设置数据
if
(
id
)
{
formLoading
.
value
=
true
try
{
formData
.
value
=
await
CustomerInfoApi
.
getCustomerInfo
(
id
)
}
finally
{
formLoading
.
value
=
false
}
}
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
/** 提交表单 */
const
emit
=
defineEmits
([
'
success
'
])
// 定义 success 事件,用于操作成功后的回调
const
submitForm
=
async
()
=>
{
// 校验表单
await
formRef
.
value
.
validate
()
// 提交请求
formLoading
.
value
=
true
try
{
const
data
=
formData
.
value
as
unknown
as
CustomerInfoVO
if
(
formType
.
value
===
'
create
'
)
{
await
CustomerInfoApi
.
createCustomerInfo
(
data
)
message
.
success
(
t
(
'
common.createSuccess
'
))
}
else
{
await
CustomerInfoApi
.
updateCustomerInfo
(
data
)
message
.
success
(
t
(
'
common.updateSuccess
'
))
}
dialogVisible
.
value
=
false
// 发送操作成功的事件
emit
(
'
success
'
)
}
finally
{
formLoading
.
value
=
false
}
}
/** 重置表单 */
const
resetForm
=
()
=>
{
formData
.
value
=
{
id
:
undefined
,
customerName
:
undefined
,
contact
:
undefined
,
companyName
:
undefined
,
customerType
:
undefined
,
provinceName
:
undefined
,
cityName
:
undefined
,
areaName
:
undefined
,
regionFullName
:
undefined
,
locationText
:
undefined
,
longitude
:
undefined
,
latitude
:
undefined
,
locationImage
:
undefined
,
productIds
:
undefined
,
department
:
undefined
,
}
formRef
.
value
?.
resetFields
()
}
</
script
>
\ No newline at end of file
yudao-ui/yudao-ui-admin-vue3/src/views/visit/customerinfo/index.vue
0 → 100644
View file @
20a8a2b4
<
template
>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class=
"-mb-15px"
:model=
"queryParams"
ref=
"queryFormRef"
:inline=
"true"
label-width=
"68px"
>
<el-form-item
label=
"客户姓名"
prop=
"customerName"
>
<el-input
v-model=
"queryParams.customerName"
placeholder=
"请输入客户姓名"
clearable
@
keyup.enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"联系方式"
prop=
"contact"
>
<el-input
v-model=
"queryParams.contact"
placeholder=
"请输入联系方式"
clearable
@
keyup.enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"公司名称"
prop=
"companyName"
>
<el-input
v-model=
"queryParams.companyName"
placeholder=
"请输入公司名称"
clearable
@
keyup.enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"性质等级"
prop=
"customerType"
>
<el-select
v-model=
"queryParams.customerType"
placeholder=
"请选择性质等级"
clearable
class=
"!w-240px"
>
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.CUSTOMER_TYPE)"
: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
type=
"primary"
plain
@
click=
"openForm('create')"
v-hasPermi=
"['visit:customer-info:create']"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
新增
</el-button>
<el-button
type=
"success"
plain
@
click=
"handleExport"
:loading=
"exportLoading"
v-hasPermi=
"['visit:customer-info:export']"
>
<Icon
icon=
"ep:download"
class=
"mr-5px"
/>
导出
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table
v-loading=
"loading"
:data=
"list"
:stripe=
"true"
:show-overflow-tooltip=
"true"
>
<el-table-column
label=
"编号"
align=
"center"
prop=
"id"
/>
<el-table-column
label=
"客户姓名"
align=
"center"
prop=
"customerName"
/>
<el-table-column
label=
"联系方式"
align=
"center"
prop=
"contact"
/>
<el-table-column
label=
"公司名称"
align=
"center"
prop=
"companyName"
/>
<el-table-column
label=
"性质等级"
align=
"center"
prop=
"customerType"
>
<template
#default
="
scope
"
>
<dict-tag
:type=
"DICT_TYPE.CUSTOMER_TYPE"
:value=
"scope.row.customerType"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"所在地区"
align=
"center"
prop=
"regionFullName"
/>
<el-table-column
label=
"创建时间"
align=
"center"
prop=
"createTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
<el-table-column
label=
"操作"
align=
"center"
min-width=
"120px"
>
<
template
#default
="
scope
"
>
<el-button
link
type=
"primary"
@
click=
"openForm('update', scope.row.id)"
v-hasPermi=
"['visit:customer-info:update']"
>
编辑
</el-button>
<el-button
link
type=
"danger"
@
click=
"handleDelete(scope.row.id)"
v-hasPermi=
"['visit:customer-info:delete']"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total=
"total"
v-model:page=
"queryParams.pageNo"
v-model:limit=
"queryParams.pageSize"
@
pagination=
"getList"
/>
</ContentWrap>
<!-- 表单弹窗:添加/修改 -->
<CustomerInfoForm
ref=
"formRef"
@
success=
"getList"
/>
</template>
<
script
setup
lang=
"ts"
>
import
{
getIntDictOptions
,
DICT_TYPE
}
from
'
@/utils/dict
'
import
{
dateFormatter
}
from
'
@/utils/formatTime
'
import
download
from
'
@/utils/download
'
import
{
CustomerInfoApi
,
CustomerInfoVO
}
from
'
@/api/visit/customerinfo
'
import
CustomerInfoForm
from
'
./CustomerInfoForm.vue
'
/** 客户信息 列表 */
defineOptions
({
name
:
'
CustomerInfo
'
})
const
message
=
useMessage
()
// 消息弹窗
const
{
t
}
=
useI18n
()
// 国际化
const
loading
=
ref
(
true
)
// 列表的加载中
const
list
=
ref
<
CustomerInfoVO
[]
>
([])
// 列表的数据
const
total
=
ref
(
0
)
// 列表的总页数
const
queryParams
=
reactive
({
pageNo
:
1
,
pageSize
:
10
,
customerName
:
undefined
,
contact
:
undefined
,
companyName
:
undefined
,
customerType
:
undefined
,
cityCode
:
undefined
,
createTime
:
[],
})
const
queryFormRef
=
ref
()
// 搜索的表单
const
exportLoading
=
ref
(
false
)
// 导出的加载中
/** 查询列表 */
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
const
data
=
await
CustomerInfoApi
.
getCustomerInfoPage
(
queryParams
)
list
.
value
=
data
.
list
total
.
value
=
data
.
total
}
finally
{
loading
.
value
=
false
}
}
/** 搜索按钮操作 */
const
handleQuery
=
()
=>
{
queryParams
.
pageNo
=
1
getList
()
}
/** 重置按钮操作 */
const
resetQuery
=
()
=>
{
queryFormRef
.
value
.
resetFields
()
handleQuery
()
}
/** 添加/修改操作 */
const
formRef
=
ref
()
const
openForm
=
(
type
:
string
,
id
?:
number
)
=>
{
formRef
.
value
.
open
(
type
,
id
)
}
/** 删除按钮操作 */
const
handleDelete
=
async
(
id
:
number
)
=>
{
try
{
// 删除的二次确认
await
message
.
delConfirm
()
// 发起删除
await
CustomerInfoApi
.
deleteCustomerInfo
(
id
)
message
.
success
(
t
(
'
common.delSuccess
'
))
// 刷新列表
await
getList
()
}
catch
{}
}
/** 导出按钮操作 */
const
handleExport
=
async
()
=>
{
try
{
// 导出的二次确认
await
message
.
exportConfirm
()
// 发起导出
exportLoading
.
value
=
true
const
data
=
await
CustomerInfoApi
.
exportCustomerInfo
(
queryParams
)
download
.
excel
(
data
,
'
客户信息.xls
'
)
}
catch
{
}
finally
{
exportLoading
.
value
=
false
}
}
/** 初始化 **/
onMounted
(()
=>
{
getList
()
})
</
script
>
yudao-ui/yudao-ui-admin-vue3/src/views/visit/info/InfoForm.vue
0 → 100644
View file @
20a8a2b4
<
template
>
<Dialog
:title=
"dialogTitle"
v-model=
"dialogVisible"
>
<el-form
ref=
"formRef"
:model=
"formData"
:rules=
"formRules"
label-width=
"100px"
v-loading=
"formLoading"
>
<el-form-item
label=
"拜访人姓名"
prop=
"customerName"
>
<el-input
v-model=
"formData.customerName"
placeholder=
"请输入拜访人姓名"
/>
</el-form-item>
<el-form-item
label=
"联系方式"
prop=
"contact"
>
<el-input
v-model=
"formData.contact"
placeholder=
"请输入联系方式"
/>
</el-form-item>
<el-form-item
label=
"客户公司名称"
prop=
"companyName"
>
<el-input
v-model=
"formData.companyName"
placeholder=
"请输入客户公司名称"
/>
</el-form-item>
<el-form-item
label=
"省名称"
prop=
"provinceName"
>
<el-input
v-model=
"formData.provinceName"
placeholder=
"请输入省名称"
/>
</el-form-item>
<el-form-item
label=
"市名称"
prop=
"cityName"
>
<el-input
v-model=
"formData.cityName"
placeholder=
"请输入市名称"
/>
</el-form-item>
<el-form-item
label=
"区名称"
prop=
"areaName"
>
<el-input
v-model=
"formData.areaName"
placeholder=
"请输入区名称"
/>
</el-form-item>
<el-form-item
label=
"定位地址文字描述"
prop=
"locationText"
>
<el-input
v-model=
"formData.locationText"
placeholder=
"请输入定位地址文字描述"
/>
</el-form-item>
<el-form-item
label=
"经度"
prop=
"longitude"
>
<el-input
v-model=
"formData.longitude"
placeholder=
"请输入经度"
/>
</el-form-item>
<el-form-item
label=
"纬度"
prop=
"latitude"
>
<el-input
v-model=
"formData.latitude"
placeholder=
"请输入纬度"
/>
</el-form-item>
<el-form-item
label=
"定位静态图URL"
prop=
"locationImage"
>
<UploadImg
v-model=
"formData.locationImage"
/>
</el-form-item>
<el-form-item
label=
"拜访日期"
prop=
"visitDate"
>
<el-date-picker
v-model=
"formData.visitDate"
type=
"date"
value-format=
"x"
placeholder=
"选择拜访日期"
/>
</el-form-item>
<el-form-item
label=
"性质等级"
prop=
"customerStatus"
>
<el-radio-group
v-model=
"formData.customerStatus"
>
<el-radio
value=
"1"
>
请选择字典生成
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label=
"拜访品种"
prop=
"visitProductIds"
>
<el-input
v-model=
"formData.visitProductIds"
placeholder=
"请输入拜访品种"
/>
</el-form-item>
<el-form-item
label=
"拜访方式"
prop=
"visitMethod"
>
<el-select
v-model=
"formData.visitMethod"
placeholder=
"请选择拜访方式"
>
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.VISIT_METHOD)"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"拜访类型"
prop=
"visitType"
>
<el-select
v-model=
"formData.visitType"
placeholder=
"请选择拜访类型"
>
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.VISIT_TYPE)"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"服务内容"
prop=
"serviceContent"
>
<Editor
v-model=
"formData.serviceContent"
height=
"150px"
/>
</el-form-item>
<el-form-item
label=
"客户反馈"
prop=
"customerFeedback"
>
<el-input
v-model=
"formData.customerFeedback"
placeholder=
"请输入客户反馈"
/>
</el-form-item>
<el-form-item
label=
"服务记录图片URL列表"
prop=
"serviceImages"
>
<UploadImg
v-model=
"formData.serviceImages"
/>
</el-form-item>
</el-form>
<template
#footer
>
<el-button
@
click=
"submitForm"
type=
"primary"
:disabled=
"formLoading"
>
确 定
</el-button>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
</
template
>
</Dialog>
</template>
<
script
setup
lang=
"ts"
>
import
{
getIntDictOptions
,
DICT_TYPE
}
from
'
@/utils/dict
'
import
{
InfoApi
,
InfoVO
}
from
'
@/api/visit/info
'
/** 客户拜访记录 表单 */
defineOptions
({
name
:
'
InfoForm
'
})
const
{
t
}
=
useI18n
()
// 国际化
const
message
=
useMessage
()
// 消息弹窗
const
dialogVisible
=
ref
(
false
)
// 弹窗的是否展示
const
dialogTitle
=
ref
(
''
)
// 弹窗的标题
const
formLoading
=
ref
(
false
)
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const
formType
=
ref
(
''
)
// 表单的类型:create - 新增;update - 修改
const
formData
=
ref
({
id
:
undefined
,
customerName
:
undefined
,
contact
:
undefined
,
companyName
:
undefined
,
provinceName
:
undefined
,
cityName
:
undefined
,
areaName
:
undefined
,
locationText
:
undefined
,
longitude
:
undefined
,
latitude
:
undefined
,
locationImage
:
undefined
,
visitDate
:
undefined
,
customerStatus
:
undefined
,
visitProductIds
:
undefined
,
visitMethod
:
undefined
,
visitType
:
undefined
,
serviceContent
:
undefined
,
customerFeedback
:
undefined
,
serviceImages
:
undefined
,
})
const
formRules
=
reactive
({
customerName
:
[{
required
:
true
,
message
:
'
拜访人姓名不能为空
'
,
trigger
:
'
blur
'
}],
contact
:
[{
required
:
true
,
message
:
'
联系方式不能为空
'
,
trigger
:
'
blur
'
}],
companyName
:
[{
required
:
true
,
message
:
'
客户公司名称不能为空
'
,
trigger
:
'
blur
'
}],
provinceName
:
[{
required
:
true
,
message
:
'
省名称不能为空
'
,
trigger
:
'
blur
'
}],
cityName
:
[{
required
:
true
,
message
:
'
市名称不能为空
'
,
trigger
:
'
blur
'
}],
areaName
:
[{
required
:
true
,
message
:
'
区名称不能为空
'
,
trigger
:
'
blur
'
}],
locationText
:
[{
required
:
true
,
message
:
'
定位地址文字描述不能为空
'
,
trigger
:
'
blur
'
}],
longitude
:
[{
required
:
true
,
message
:
'
经度不能为空
'
,
trigger
:
'
blur
'
}],
latitude
:
[{
required
:
true
,
message
:
'
纬度不能为空
'
,
trigger
:
'
blur
'
}],
locationImage
:
[{
required
:
true
,
message
:
'
定位静态图URL不能为空
'
,
trigger
:
'
blur
'
}],
visitDate
:
[{
required
:
true
,
message
:
'
拜访日期不能为空
'
,
trigger
:
'
blur
'
}],
customerStatus
:
[{
required
:
true
,
message
:
'
性质等级不能为空
'
,
trigger
:
'
blur
'
}],
})
const
formRef
=
ref
()
// 表单 Ref
/** 打开弹窗 */
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
dialogVisible
.
value
=
true
dialogTitle
.
value
=
t
(
'
action.
'
+
type
)
formType
.
value
=
type
resetForm
()
// 修改时,设置数据
if
(
id
)
{
formLoading
.
value
=
true
try
{
formData
.
value
=
await
InfoApi
.
getInfo
(
id
)
}
finally
{
formLoading
.
value
=
false
}
}
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
/** 提交表单 */
const
emit
=
defineEmits
([
'
success
'
])
// 定义 success 事件,用于操作成功后的回调
const
submitForm
=
async
()
=>
{
// 校验表单
await
formRef
.
value
.
validate
()
// 提交请求
formLoading
.
value
=
true
try
{
const
data
=
formData
.
value
as
unknown
as
InfoVO
if
(
formType
.
value
===
'
create
'
)
{
await
InfoApi
.
createInfo
(
data
)
message
.
success
(
t
(
'
common.createSuccess
'
))
}
else
{
await
InfoApi
.
updateInfo
(
data
)
message
.
success
(
t
(
'
common.updateSuccess
'
))
}
dialogVisible
.
value
=
false
// 发送操作成功的事件
emit
(
'
success
'
)
}
finally
{
formLoading
.
value
=
false
}
}
/** 重置表单 */
const
resetForm
=
()
=>
{
formData
.
value
=
{
id
:
undefined
,
customerName
:
undefined
,
contact
:
undefined
,
companyName
:
undefined
,
provinceName
:
undefined
,
cityName
:
undefined
,
areaName
:
undefined
,
locationText
:
undefined
,
longitude
:
undefined
,
latitude
:
undefined
,
locationImage
:
undefined
,
visitDate
:
undefined
,
customerStatus
:
undefined
,
visitProductIds
:
undefined
,
visitMethod
:
undefined
,
visitType
:
undefined
,
serviceContent
:
undefined
,
customerFeedback
:
undefined
,
serviceImages
:
undefined
,
}
formRef
.
value
?.
resetFields
()
}
</
script
>
yudao-ui/yudao-ui-admin-vue3/src/views/visit/info/index.vue
0 → 100644
View file @
20a8a2b4
<
template
>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class=
"-mb-15px"
:model=
"queryParams"
ref=
"queryFormRef"
:inline=
"true"
label-width=
"98px"
>
<el-form-item
label=
"拜访人姓名"
prop=
"customerName"
>
<el-input
v-model=
"queryParams.customerName"
placeholder=
"请输入拜访人姓名"
clearable
@
keyup.enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"联系方式"
prop=
"contact"
>
<el-input
v-model=
"queryParams.contact"
placeholder=
"请输入联系方式"
clearable
@
keyup.enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"客户公司名称"
prop=
"companyName"
>
<el-input
v-model=
"queryParams.companyName"
placeholder=
"请输入客户公司名称"
clearable
@
keyup.enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"拜访日期"
prop=
"visitDate"
>
<el-date-picker
v-model=
"queryParams.visitDate"
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
label=
"性质等级"
prop=
"customerStatus"
>
<el-select
v-model=
"queryParams.customerStatus"
placeholder=
"请选择性质等级"
clearable
class=
"!w-240px"
>
<el-option
label=
"请选择字典生成"
value=
""
/>
</el-select>
</el-form-item>
<el-form-item
label=
"拜访品种"
prop=
"visitProductIds"
>
<el-input
v-model=
"queryParams.visitProductIds"
placeholder=
"请输入拜访品种"
clearable
@
keyup.enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"拜访方式"
prop=
"visitMethod"
>
<el-select
v-model=
"queryParams.visitMethod"
placeholder=
"请选择拜访方式"
clearable
class=
"!w-240px"
>
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.VISIT_METHOD)"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"拜访类型"
prop=
"visitType"
>
<el-select
v-model=
"queryParams.visitType"
placeholder=
"请选择拜访类型"
clearable
class=
"!w-240px"
>
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.VISIT_TYPE)"
: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
type=
"primary"
plain
@
click=
"openForm('create')"
v-hasPermi=
"['visit:info:create']"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
新增
</el-button>
<el-button
type=
"success"
plain
@
click=
"handleExport"
:loading=
"exportLoading"
v-hasPermi=
"['visit:info:export']"
>
<Icon
icon=
"ep:download"
class=
"mr-5px"
/>
导出
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table
v-loading=
"loading"
:data=
"list"
:stripe=
"true"
:show-overflow-tooltip=
"true"
>
<el-table-column
label=
"主键ID"
align=
"center"
prop=
"id"
/>
<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=
"visitDate"
/>
<el-table-column
label=
"性质等级"
align=
"center"
prop=
"customerStatus"
/>
<el-table-column
label=
"拜访品种"
align=
"center"
prop=
"visitProductIds"
/>
<el-table-column
label=
"拜访方式"
align=
"center"
prop=
"visitMethod"
>
<template
#default
="
scope
"
>
<dict-tag
:type=
"DICT_TYPE.VISIT_METHOD"
:value=
"scope.row.visitMethod"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"拜访类型"
align=
"center"
prop=
"visitType"
>
<
template
#default
="
scope
"
>
<dict-tag
:type=
"DICT_TYPE.VISIT_TYPE"
:value=
"scope.row.visitType"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"创建时间"
align=
"center"
prop=
"createTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
<el-table-column
label=
"操作"
align=
"center"
min-width=
"120px"
>
<
template
#default
="
scope
"
>
<el-button
link
type=
"primary"
@
click=
"openForm('update', scope.row.id)"
v-hasPermi=
"['visit:info:update']"
>
编辑
</el-button>
<el-button
link
type=
"danger"
@
click=
"handleDelete(scope.row.id)"
v-hasPermi=
"['visit:info:delete']"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total=
"total"
v-model:page=
"queryParams.pageNo"
v-model:limit=
"queryParams.pageSize"
@
pagination=
"getList"
/>
</ContentWrap>
<!-- 表单弹窗:添加/修改 -->
<InfoForm
ref=
"formRef"
@
success=
"getList"
/>
</template>
<
script
setup
lang=
"ts"
>
import
{
getIntDictOptions
,
DICT_TYPE
}
from
'
@/utils/dict
'
import
{
dateFormatter
}
from
'
@/utils/formatTime
'
import
download
from
'
@/utils/download
'
import
{
InfoApi
,
InfoVO
}
from
'
@/api/visit/info
'
import
InfoForm
from
'
./InfoForm.vue
'
/** 客户拜访记录 列表 */
defineOptions
({
name
:
'
Info
'
})
const
message
=
useMessage
()
// 消息弹窗
const
{
t
}
=
useI18n
()
// 国际化
const
loading
=
ref
(
true
)
// 列表的加载中
const
list
=
ref
<
InfoVO
[]
>
([])
// 列表的数据
const
total
=
ref
(
0
)
// 列表的总页数
const
queryParams
=
reactive
({
pageNo
:
1
,
pageSize
:
10
,
customerName
:
undefined
,
contact
:
undefined
,
companyName
:
undefined
,
visitDate
:
[],
customerStatus
:
undefined
,
visitProductIds
:
undefined
,
visitMethod
:
undefined
,
visitType
:
undefined
,
createTime
:
[],
})
const
queryFormRef
=
ref
()
// 搜索的表单
const
exportLoading
=
ref
(
false
)
// 导出的加载中
/** 查询列表 */
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
const
data
=
await
InfoApi
.
getInfoPage
(
queryParams
)
list
.
value
=
data
.
list
total
.
value
=
data
.
total
}
finally
{
loading
.
value
=
false
}
}
/** 搜索按钮操作 */
const
handleQuery
=
()
=>
{
queryParams
.
pageNo
=
1
getList
()
}
/** 重置按钮操作 */
const
resetQuery
=
()
=>
{
queryFormRef
.
value
.
resetFields
()
handleQuery
()
}
/** 添加/修改操作 */
const
formRef
=
ref
()
const
openForm
=
(
type
:
string
,
id
?:
number
)
=>
{
formRef
.
value
.
open
(
type
,
id
)
}
/** 删除按钮操作 */
const
handleDelete
=
async
(
id
:
number
)
=>
{
try
{
// 删除的二次确认
await
message
.
delConfirm
()
// 发起删除
await
InfoApi
.
deleteInfo
(
id
)
message
.
success
(
t
(
'
common.delSuccess
'
))
// 刷新列表
await
getList
()
}
catch
{}
}
/** 导出按钮操作 */
const
handleExport
=
async
()
=>
{
try
{
// 导出的二次确认
await
message
.
exportConfirm
()
// 发起导出
exportLoading
.
value
=
true
const
data
=
await
InfoApi
.
exportInfo
(
queryParams
)
download
.
excel
(
data
,
'
客户拜访记录.xls
'
)
}
catch
{
}
finally
{
exportLoading
.
value
=
false
}
}
/** 初始化 **/
onMounted
(()
=>
{
getList
()
})
</
script
>
yudao-ui/yudao-ui-admin-vue3/src/views/visit/product/ProductForm.vue
0 → 100644
View file @
20a8a2b4
<
template
>
<Dialog
:title=
"dialogTitle"
v-model=
"dialogVisible"
>
<el-form
ref=
"formRef"
:model=
"formData"
:rules=
"formRules"
label-width=
"100px"
v-loading=
"formLoading"
>
<el-form-item
label=
"品种名称"
prop=
"productName"
>
<el-input
v-model=
"formData.productName"
placeholder=
"请输入品种名称"
/>
</el-form-item>
<el-form-item
label=
"包装信息"
prop=
"packageName"
>
<el-input
v-model=
"formData.packageName"
placeholder=
"请输入包装信息"
/>
</el-form-item>
<el-form-item
label=
"规格"
prop=
"specification"
>
<el-input
v-model=
"formData.specification"
placeholder=
"请输入规格"
/>
</el-form-item>
<el-form-item
label=
"状态"
prop=
"status"
>
<el-select
v-model=
"formData.status"
placeholder=
"请选择状态"
>
<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>
<template
#footer
>
<el-button
@
click=
"submitForm"
type=
"primary"
:disabled=
"formLoading"
>
确 定
</el-button>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
</
template
>
</Dialog>
</template>
<
script
setup
lang=
"ts"
>
import
{
getIntDictOptions
,
DICT_TYPE
}
from
'
@/utils/dict
'
import
{
ProductApi
,
ProductVO
}
from
'
@/api/visit/product
'
/** 产品 表单 */
defineOptions
({
name
:
'
ProductForm
'
})
const
{
t
}
=
useI18n
()
// 国际化
const
message
=
useMessage
()
// 消息弹窗
const
dialogVisible
=
ref
(
false
)
// 弹窗的是否展示
const
dialogTitle
=
ref
(
''
)
// 弹窗的标题
const
formLoading
=
ref
(
false
)
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const
formType
=
ref
(
''
)
// 表单的类型:create - 新增;update - 修改
const
formData
=
ref
({
id
:
undefined
,
productName
:
undefined
,
packageName
:
undefined
,
specification
:
undefined
,
status
:
undefined
,
})
const
formRules
=
reactive
({
productName
:
[{
required
:
true
,
message
:
'
品种名称不能为空
'
,
trigger
:
'
blur
'
}],
packageName
:
[{
required
:
true
,
message
:
'
包装信息不能为空
'
,
trigger
:
'
blur
'
}],
specification
:
[{
required
:
true
,
message
:
'
规格不能为空
'
,
trigger
:
'
blur
'
}],
})
const
formRef
=
ref
()
// 表单 Ref
/** 打开弹窗 */
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
dialogVisible
.
value
=
true
dialogTitle
.
value
=
t
(
'
action.
'
+
type
)
formType
.
value
=
type
resetForm
()
// 修改时,设置数据
if
(
id
)
{
formLoading
.
value
=
true
try
{
formData
.
value
=
await
ProductApi
.
getProduct
(
id
)
}
finally
{
formLoading
.
value
=
false
}
}
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
/** 提交表单 */
const
emit
=
defineEmits
([
'
success
'
])
// 定义 success 事件,用于操作成功后的回调
const
submitForm
=
async
()
=>
{
// 校验表单
await
formRef
.
value
.
validate
()
// 提交请求
formLoading
.
value
=
true
try
{
const
data
=
formData
.
value
as
unknown
as
ProductVO
if
(
formType
.
value
===
'
create
'
)
{
await
ProductApi
.
createProduct
(
data
)
message
.
success
(
t
(
'
common.createSuccess
'
))
}
else
{
await
ProductApi
.
updateProduct
(
data
)
message
.
success
(
t
(
'
common.updateSuccess
'
))
}
dialogVisible
.
value
=
false
// 发送操作成功的事件
emit
(
'
success
'
)
}
finally
{
formLoading
.
value
=
false
}
}
/** 重置表单 */
const
resetForm
=
()
=>
{
formData
.
value
=
{
id
:
undefined
,
productName
:
undefined
,
packageName
:
undefined
,
specification
:
undefined
,
status
:
undefined
,
}
formRef
.
value
?.
resetFields
()
}
</
script
>
yudao-ui/yudao-ui-admin-vue3/src/views/visit/product/index.vue
0 → 100644
View file @
20a8a2b4
<
template
>
<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
type=
"primary"
plain
@
click=
"openForm('create')"
v-hasPermi=
"['visit:product:create']"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
新增
</el-button>
<el-button
type=
"success"
plain
@
click=
"handleExport"
:loading=
"exportLoading"
v-hasPermi=
"['visit:product:export']"
>
<Icon
icon=
"ep:download"
class=
"mr-5px"
/>
导出
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table
v-loading=
"loading"
:data=
"list"
:stripe=
"true"
:show-overflow-tooltip=
"true"
>
<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-column
label=
"操作"
align=
"center"
min-width=
"120px"
>
<
template
#default
="
scope
"
>
<el-button
link
type=
"primary"
@
click=
"openForm('update', scope.row.id)"
v-hasPermi=
"['visit:product:update']"
>
编辑
</el-button>
<el-button
link
type=
"danger"
@
click=
"handleDelete(scope.row.id)"
v-hasPermi=
"['visit:product:delete']"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total=
"total"
v-model:page=
"queryParams.pageNo"
v-model:limit=
"queryParams.pageSize"
@
pagination=
"getList"
/>
</ContentWrap>
<!-- 表单弹窗:添加/修改 -->
<ProductForm
ref=
"formRef"
@
success=
"getList"
/>
</template>
<
script
setup
lang=
"ts"
>
import
{
getIntDictOptions
,
DICT_TYPE
}
from
'
@/utils/dict
'
import
{
dateFormatter
}
from
'
@/utils/formatTime
'
import
download
from
'
@/utils/download
'
import
{
ProductApi
,
ProductVO
}
from
'
@/api/visit/product
'
import
ProductForm
from
'
./ProductForm.vue
'
/** 产品 列表 */
defineOptions
({
name
:
'
Product
'
})
const
message
=
useMessage
()
// 消息弹窗
const
{
t
}
=
useI18n
()
// 国际化
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
exportLoading
=
ref
(
false
)
// 导出的加载中
/** 查询列表 */
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
handleQuery
=
()
=>
{
queryParams
.
pageNo
=
1
getList
()
}
/** 重置按钮操作 */
const
resetQuery
=
()
=>
{
queryFormRef
.
value
.
resetFields
()
handleQuery
()
}
/** 添加/修改操作 */
const
formRef
=
ref
()
const
openForm
=
(
type
:
string
,
id
?:
number
)
=>
{
formRef
.
value
.
open
(
type
,
id
)
}
/** 删除按钮操作 */
const
handleDelete
=
async
(
id
:
number
)
=>
{
try
{
// 删除的二次确认
await
message
.
delConfirm
()
// 发起删除
await
ProductApi
.
deleteProduct
(
id
)
message
.
success
(
t
(
'
common.delSuccess
'
))
// 刷新列表
await
getList
()
}
catch
{}
}
/** 导出按钮操作 */
const
handleExport
=
async
()
=>
{
try
{
// 导出的二次确认
await
message
.
exportConfirm
()
// 发起导出
exportLoading
.
value
=
true
const
data
=
await
ProductApi
.
exportProduct
(
queryParams
)
download
.
excel
(
data
,
'
产品.xls
'
)
}
catch
{
}
finally
{
exportLoading
.
value
=
false
}
}
/** 初始化 **/
onMounted
(()
=>
{
getList
()
})
</
script
>
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