diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSaveReqVO.java index ed6bee1105df8bdb86cc2bccd3eb3b999c6c0784..49c35d3a17e0e3581c346122290bf137850cfc94 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSaveReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSaveReqVO.java @@ -38,7 +38,7 @@ public class UserSaveReqVO { private String remark; @Schema(description = "部门编号", example = "我是一个用户") - @NotBlank(message = "部门编号不能为空") + @NotNull(message = "部门编号不能为空") @DiffLogField(name = "部门", function = DeptParseFunction.NAME) private Long deptId; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java index c0c9be8e4224d5228e4171276904f4d721b1dafa..d653f282277ee8d1e03facc516441b5333afb235 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java @@ -9,6 +9,7 @@ import org.apache.ibatis.annotations.Mapper; import java.util.Collection; import java.util.List; +import java.util.Set; @Mapper public interface AdminUserMapper extends BaseMapperX { @@ -48,4 +49,7 @@ public interface AdminUserMapper extends BaseMapperX { return selectList(AdminUserDO::getDeptId, deptIds); } + default List selectListInDeptIds(Set deptCondition){ + return selectList(new LambdaQueryWrapperX().inIfPresent(AdminUserDO::getDeptId, deptCondition)); + } } diff --git a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerImportExcelVO.java b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerImportExcelVO.java index 55a128ed7d2fa23a4c09fc309fb4568a61eba584..dccdbce4e0dde15a1d5d1ba91669f06a3b22f54a 100644 --- a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerImportExcelVO.java +++ b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerImportExcelVO.java @@ -30,7 +30,6 @@ public class CustomerImportExcelVO { private String customerName; @ExcelProperty("联系方式") - @Pattern(regexp = "^$|^\\d{11}$", message = "联系方式必须是11位数字") private String contact; @ExcelProperty("公司名称") diff --git a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerInfoRespVO.java b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerInfoRespVO.java index b4daae9c1ab1c83ddef01fc4d10737ba5b91970c..12420fa5b5694adc14478a9d4ccb4417cedd3467 100644 --- a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerInfoRespVO.java +++ b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerInfoRespVO.java @@ -24,8 +24,8 @@ public class CustomerInfoRespVO { @ExcelProperty("客户姓名") private String customerName; - @Schema(description = "联系方式(客户手机号)", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("联系方式(客户手机号)") + @Schema(description = "联系方式", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("联系方式") private String contact; @Schema(description = "公司名称", requiredMode = Schema.RequiredMode.REQUIRED) diff --git a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerInfoSaveReqVO.java b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerInfoSaveReqVO.java index cb79d9e6cded961887fafc9fbcb376e5a70fdd6a..d456b16d8b352982e585aee81a3096a67ce59fae 100644 --- a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerInfoSaveReqVO.java +++ b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerInfoSaveReqVO.java @@ -14,11 +14,9 @@ public class CustomerInfoSaveReqVO { private Long id; @Schema(description = "客户姓名", requiredMode = Schema.RequiredMode.REQUIRED) - @NotEmpty(message = "客户姓名不能为空") private String customerName; @Schema(description = "联系方式") - @Pattern(regexp = "^$|^\\d{11}$", message = "联系方式必须是11位数字") private String contact; @Schema(description = "公司名称", requiredMode = Schema.RequiredMode.REQUIRED) diff --git a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/home/HomeController.java b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/home/HomeController.java index 5161e2b32f15121fbf6f09d156ff938a1efdfcc6..bf3b4febebcb7109ab4d97700e3376f9d0da7b29 100644 --- a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/home/HomeController.java +++ b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/home/HomeController.java @@ -1,10 +1,12 @@ package cn.iocoder.yudao.module.visit.controller.admin.home; +import cn.hutool.http.HttpUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.module.visit.controller.admin.home.vo.*; import cn.iocoder.yudao.module.visit.service.customerinfo.CustomerInfoService; import cn.iocoder.yudao.module.visit.service.home.HomeService; import cn.iocoder.yudao.module.visit.service.product.ProductService; +import com.alibaba.fastjson.JSON; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.validation.annotation.Validated; @@ -17,6 +19,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.Year; import java.time.YearMonth; +import java.util.Map; import java.util.Objects; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -154,5 +157,13 @@ public class HomeController { return new LocalDateTime[]{startTime, endTime}; } + @GetMapping("/api/map/geocoder") + public CommonResult> getGeocoder(@RequestParam String lat, @RequestParam String lng) { + String key = "2OZBZ-WUCE7-SLKXP-HJVOW-3P6RF-WVB7H"; + String url = "https://apis.map.qq.com/ws/geocoder/v1/?location=" + lat + "," + lng + "&key=" + key; + String json = HttpUtil.get(url); + return success(JSON.parseObject(json)); + } + } \ No newline at end of file diff --git a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoPageReqVO.java b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoPageReqVO.java index 3a0ded2fc5f5691b42a30b58470920818f1de8af..92bd6b2022a31d7460a119d069245f0bd777270a 100644 --- a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoPageReqVO.java +++ b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoPageReqVO.java @@ -21,7 +21,7 @@ public class InfoPageReqVO extends PageParam { @Schema(description = "客户姓名") private String customerName; - @Schema(description = "联系方式(客户手机号)") + @Schema(description = "联系方式") private String contact; @Schema(description = "客户公司名称") diff --git a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoRespVO.java b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoRespVO.java index db922465e4ab16bd48f4fa42d3e327010b4a51d6..9181761e41bfd616f6578b6d591b7fbb89284c16 100644 --- a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoRespVO.java +++ b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoRespVO.java @@ -29,8 +29,8 @@ public class InfoRespVO { @ExcelProperty("客户姓名") private String customerName; - @Schema(description = "联系方式(客户手机号)", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("联系方式(客户手机号)") + @Schema(description = "联系方式", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("联系方式") private String contact; @Schema(description = "客户公司名称", requiredMode = Schema.RequiredMode.REQUIRED) diff --git a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoSaveReqVO.java b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoSaveReqVO.java index 9c2ad3e8bf25aeebf1e9f0d43f81af03dbf47bee..3c36b8e2bd41a7ec20ac41d4c7da013b0d68d96b 100644 --- a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoSaveReqVO.java +++ b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/info/vo/InfoSaveReqVO.java @@ -20,8 +20,7 @@ public class InfoSaveReqVO { @NotEmpty(message = "客户姓名不能为空") private String customerName; - @Schema(description = "联系方式(客户手机号)") - @Pattern(regexp = "^$|^\\d{11}$", message = "联系方式必须是11位数字") + @Schema(description = "联系方式") private String contact; @Schema(description = "客户公司名称", requiredMode = Schema.RequiredMode.REQUIRED) diff --git a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/home/HomeServiceImpl.java b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/home/HomeServiceImpl.java index 83a0ea56290ff614e2f45496dd8f46800c96bca9..2d8c3819bda705d079e148c78bd9b444a8b0bcb1 100644 --- a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/home/HomeServiceImpl.java +++ b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/home/HomeServiceImpl.java @@ -2,10 +2,13 @@ package cn.iocoder.yudao.module.visit.service.home; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.module.system.api.dict.DictDataApi; import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO; +import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper; +import cn.iocoder.yudao.module.system.service.dept.DeptService; import cn.iocoder.yudao.module.visit.controller.admin.customerinfo.vo.CustomerInfoPageReqVO; import cn.iocoder.yudao.module.visit.controller.admin.home.vo.*; import cn.iocoder.yudao.module.visit.controller.admin.info.vo.InfoPageReqVO; @@ -29,6 +32,8 @@ import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; + /** * 主页 Service 实现类 * @@ -48,13 +53,20 @@ public class HomeServiceImpl implements HomeService { private AdminUserMapper userMapper; @Resource private DictDataApi dictDataApi; + @Resource + private DeptService deptService; //首页第一排数据 @Override public HomeFirstRespVO getHomeInfoFirst(HomeReqVO reqVO) { HomeFirstRespVO homeFirstRespVO = new HomeFirstRespVO(); //业务员数量(不按时间) - List userDOS = userMapper.selectList(); + Long loginUserDeptId = SecurityFrameworkUtils.getLoginUserDeptId();//查出登录用户的deptId + Set deptCondition = Collections.emptySet();//默认不限制 + if (loginUserDeptId == null || !loginUserDeptId.equals(100L)) {//说明是总公司,不限制 + deptCondition = getDeptCondition(loginUserDeptId);//不是总公司了,就递归查询该部门以及子部门的所有id + } + List userDOS = userMapper.selectListInDeptIds(deptCondition); homeFirstRespVO.setYwysl(String.valueOf(userDOS.size())); //按创建时间查这段时间的客户数量 CustomerInfoPageReqVO customerInfoPageReqVO = new CustomerInfoPageReqVO(); @@ -92,14 +104,27 @@ public class HomeServiceImpl implements HomeService { .count())); return homeFirstRespVO; } - + /** + * 获得部门条件:查询指定部门的子部门编号们,包括自身 + * + * @param deptId 部门编号 + * @return 部门编号集合 + */ + private Set getDeptCondition(Long deptId) { + if (deptId == null) { + return Collections.emptySet(); + } + Set deptIds = convertSet(deptService.getChildDeptList(deptId), DeptDO::getId); + deptIds.add(deptId); // 包括自身 + return deptIds; + } //拜访周统计 @Override public HomeBfztjRespVO getHomeInfoBfztj(HomeReqVO reqVO) { //如果查询时间是空,则start = LocalDateTime.now().minusWeeks(10); LocalDateTime start = null; LocalDateTime end = null; - if (reqVO.getSearchTime() == null) { + if (reqVO.getSearchTime() == null) { start = LocalDateTime.now().minusWeeks(9); end = LocalDateTime.now(); }else { @@ -114,7 +139,7 @@ public class HomeServiceImpl implements HomeService { List counts = new ArrayList<>(); for (int i = 0; i < 10; i++) { - LocalDateTime weekStart = start.plusWeeks(i); + LocalDateTime weekStart = start.plusWeeks(i).with(LocalTime.MIN);; LocalDateTime weekEnd = weekStart.plusDays(6).with(LocalTime.MAX); LocalDateTime[] week = new LocalDateTime[]{weekStart, weekEnd}; if (weekStart.isAfter(end)) break; diff --git a/yudao-ui/yudao-ui-admin-vue3/src/api/visit/home/index.ts b/yudao-ui/yudao-ui-admin-vue3/src/api/visit/home/index.ts index 5e99c45d75682e70673103316684221436a1da42..bbd66e860058dab72bcb9d710d56b8f47333bb86 100644 --- a/yudao-ui/yudao-ui-admin-vue3/src/api/visit/home/index.ts +++ b/yudao-ui/yudao-ui-admin-vue3/src/api/visit/home/index.ts @@ -38,4 +38,8 @@ export const homesApi = { getHomeInfoBfcplxzbqk: async (params: any) => { return await request.get({ url: `/visit/home/getHomeInfoBfcplxzbqk`, params }) }, + // 地图逆解析 + getMapGeocoder: async (params: any) => { + return await request.get({ url: `/visit/home/api/map/geocoder`, params }) + }, } diff --git a/yudao-ui/yudao-ui-admin-vue3/src/views/system/user/UserForm.vue b/yudao-ui/yudao-ui-admin-vue3/src/views/system/user/UserForm.vue index 3e7e1676a847bdb12547ff07a79d12b2871a053c..47f15a73322d312ccc7f66b66c179cf03459ef39 100644 --- a/yudao-ui/yudao-ui-admin-vue3/src/views/system/user/UserForm.vue +++ b/yudao-ui/yudao-ui-admin-vue3/src/views/system/user/UserForm.vue @@ -104,6 +104,7 @@ import {FormRules} from 'element-plus' import {getRefreshToken, getTenantId, setToken} from "@/utils/auth"; import axios from "axios"; import {config} from "@/config/axios/config"; +import {useUserStoreWithOut} from "@/store/modules/user"; defineOptions({ name: 'SystemUserForm' }) @@ -194,6 +195,8 @@ const submitForm = async () => { const refreshTokenRes = await refreshToken() // 2.1 刷新成功,则回放队列的请求 + 当前请求 setToken((await refreshTokenRes).data.data) + const userStore = useUserStoreWithOut() + await userStore.setUserInfoAction() message.success(t('common.updateSuccess')) } dialogVisible.value = false diff --git a/yudao-ui/yudao-ui-admin-vue3/src/views/system/user/index.vue b/yudao-ui/yudao-ui-admin-vue3/src/views/system/user/index.vue index 8f7a9dcee94724cc85871d6d803206155262caea..0a9f006b9d9da127ae1cf8816ce7fc2aed9ed970 100644 --- a/yudao-ui/yudao-ui-admin-vue3/src/views/system/user/index.vue +++ b/yudao-ui/yudao-ui-admin-vue3/src/views/system/user/index.vue @@ -230,7 +230,7 @@ const queryFormRef = ref() // 搜索的表单 /** 查询列表 */ const getList = async () => { loading.value = true - if (userStore.user.deptId!==100){//如果不是总公司用户,再过滤,总公司用户可以看到所有 + if (userStore.user.deptId!==100&&(queryParams.deptId===null||queryParams.deptId===undefined)){//如果不是总公司用户,再过滤,总公司用户可以看到所有 queryParams.deptId = userStore.user.deptId } try { diff --git a/yudao-ui/yudao-ui-admin-vue3/src/views/visit/customerinfo/CustomerInfoForm.vue b/yudao-ui/yudao-ui-admin-vue3/src/views/visit/customerinfo/CustomerInfoForm.vue index 9e1d71ca1772441e2ef5bfc525fabefe522f053d..00d451491b7ee6df1a7ef035ad150ed552b03eb4 100644 --- a/yudao-ui/yudao-ui-admin-vue3/src/views/visit/customerinfo/CustomerInfoForm.vue +++ b/yudao-ui/yudao-ui-admin-vue3/src/views/visit/customerinfo/CustomerInfoForm.vue @@ -104,6 +104,7 @@ import { CustomerInfoApi, CustomerInfoVO } from '@/api/visit/customerinfo' import { pcaTextArr } from 'element-china-area-data' import MapPicker from '../util/MapPicker.vue' import productTable from './productTable.vue' +import {homesApi} from "@/api/visit/home"; /** 客户信息 表单 */ defineOptions({ name: 'CustomerInfoForm' }) @@ -152,7 +153,6 @@ const formData = ref({ department: undefined, }) const formRules = reactive({ - customerName: [{ required: true, message: '客户姓名不能为空', trigger: 'blur' }], companyName: [{ required: true, message: '公司名称不能为空', trigger: 'blur' }], customerType: [{ required: true, message: '性质等级不能为空', trigger: 'change' }], department: [{ required: true, message: '客户部门不能为空', trigger: 'change' }], @@ -199,6 +199,36 @@ const handleLocation = ({ lat, lng, address }) => { formData.value.locationImage = mapUrl + //逆地址解析 + const params: any = { + lat: lat, + lng: lng + } + homesApi.getMapGeocoder(params).then(res => { + console.log('逆地址解析结果:', res) + if (res.status === 0) { + const comp = res.result.address_component + // 赋值到 formData + formData.value.provinceName = comp.province || '' + formData.value.cityName = comp.city || '' + formData.value.areaName = comp.district || '' + formData.value.regionFullName = comp.province + comp.city + comp.district + const province = formData.value.provinceName ?? '' + let city = formData.value.cityName ?? '' + const area = formData.value.areaName ?? '' + //将省市区修改格式赋值给selectedOptions + if(province.match(/(北京|上海|天津|重庆)/)){ + city = '市辖区' + } + selectedOptions.value = [province, city, area]//专门回显用的 + + } else { + console.warn('逆地址解析失败:', res.data.message) + } + }).catch(err => { + console.log(err) + }) + } /** 打开弹窗 */ const open = async (type: string, id?: number) => { diff --git a/yudao-ui/yudao-ui-admin-vue3/src/views/visit/info/InfoForm.vue b/yudao-ui/yudao-ui-admin-vue3/src/views/visit/info/InfoForm.vue index d79309084b323e1d9472db4cbbb6eb37250d097e..a1dae1058eb1f94f5fe7097972100b44415c7d4c 100644 --- a/yudao-ui/yudao-ui-admin-vue3/src/views/visit/info/InfoForm.vue +++ b/yudao-ui/yudao-ui-admin-vue3/src/views/visit/info/InfoForm.vue @@ -142,6 +142,8 @@ import productTable from "@/views/visit/customerinfo/productTable.vue"; import { pcaTextArr } from 'element-china-area-data' import MapPicker from '../util/MapPicker.vue' import { onMounted } from 'vue' +import request from "@/config/axios"; +import {homesApi} from "@/api/visit/home"; /** 客户拜访记录 表单 */ defineOptions({ name: 'InfoForm' }) @@ -299,6 +301,35 @@ const handleLocation = ({ lat, lng, address }) => { const mapUrl = `https://apis.map.qq.com/ws/staticmap/v2/?center=${lat},${lng}&zoom=13&size=600*300&maptype=roadmap&markers=size:large|color:0xFFCCFF|label:k|${lat},${lng}&key=${mapKey}` formData.value.locationImage = mapUrl + //逆地址解析 + const params: any = { + lat: lat, + lng: lng + } + homesApi.getMapGeocoder(params).then(res => { + console.log('逆地址解析结果:', res) + if (res.status === 0) { + const comp = res.result.address_component + // 赋值到 formData + formData.value.provinceName = comp.province || '' + formData.value.cityName = comp.city || '' + formData.value.areaName = comp.district || '' + formData.value.regionFullName = comp.province + comp.city + comp.district + const province = formData.value.provinceName ?? '' + let city = formData.value.cityName ?? '' + const area = formData.value.areaName ?? '' + //将省市区修改格式赋值给selectedOptions + if(province.match(/(北京|上海|天津|重庆)/)){ + city = '市辖区' + } + selectedOptions.value = [province, city, area]//专门回显用的 + + } else { + console.warn('逆地址解析失败:', res.data.message) + } + }).catch(err => { + console.log(err) + }) }