feat(customer): 添加公海客户归属查看权限控制
- 在CustomerMapper中增加isAdmin参数用于权限判断
- 修改数据库查询逻辑实现权限控制的差异化显示
- 重构CustomerServiceImpl中的客户列表查询方法
- 新增私海客户新增时同步到公海的功能
- 更新AI销售助手工具类的客户查询权限验证
- 添加customer:viewAll权限标识及相关文档说明
- 增加数据库迁移脚本配置权限菜单项
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # å
¬æµ·å®¢æ·å½å±æ¥çæé |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - å®¢æ·æ¡£æ¡ - å
¬æµ·å®¢æ·å表 (`/customer/publicSea`) |
| | | - å®¢æ·æ¡£æ¡ - ç§æµ·å®¢æ·å表 (`/customer/privateSea`) |
| | | - AI éå®å©æ - 客æ·å表æ¥è¯¢ |
| | | |
| | | ## API |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | GET | /basic/customer/list | æ¥è¯¢å®¢æ·å表ï¼type=1 å
¬æµ·ï¼type=0 ç§æµ·ï¼ | |
| | | |
| | | **请æ±åæ°ï¼** ä¸åï¼åèç°ææ¥å£ææ¡£ã |
| | | |
| | | **ååºåæ´ï¼** `usageUserName` åæ®µçå¼åæéæ§å¶ï¼ |
| | | |
| | | - **æ `customer:viewAll` æé**ï¼`usageUserName` è¿å该客æ·å¯¹åºçéå®äººåç§°ï¼ä¸ä¹åè¡ä¸ºä¸è´ï¼ |
| | | - **æ `customer:viewAll` æé**ï¼ä»
å½å®¢æ·ç±å½åç¨æ·é¢ç¨ï¼`usage_user`ï¼æå建ï¼`create_user`ï¼æ¶è¿åéå®äººåç§°ï¼å
¶ä»æ
åµè¿å空å符串 `""` |
| | | |
| | | ååºç»æä¸åï¼ä»ä¸ºï¼ |
| | | |
| | | ```json |
| | | { |
| | | "code": 200, |
| | | "data": { |
| | | "records": [ |
| | | { |
| | | "id": 1, |
| | | "customerName": "xxxå
¬å¸", |
| | | "usageUserName": "å¼ ä¸", |
| | | "type": 1, |
| | | "isAssigned": 1 |
| | | } |
| | | ] |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ## å端修æ¹ç¹ |
| | | |
| | | ### 1. å
¬æµ·å®¢æ·åè¡¨è¡¨æ ¼ â å¤ç空ç usageUserName |
| | | |
| | | å
¬æµ·å表ç"å½å±éå®"åéå¤ç `usageUserName` 为空çæ
åµï¼ |
| | | |
| | | ```html |
| | | <el-table-column prop="usageUserName" label="å½å±éå®" width="120"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ scope.row.usageUserName || '-' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | ``` |
| | | |
| | | ### 2. æéæ§å¶ â 页颿é®/åè½å¯è§æ§ |
| | | |
| | | éè¿ `v-hasPermi` æä»¤æ `@ss.hasPermi('customer:viewAll')` æ§å¶ç®¡çç±»åè½çå¯è§æ§ï¼ä¾å¦å¯¼åºå«éå®äººä¿¡æ¯çæ¥è¡¨çï¼ï¼ |
| | | |
| | | ```html |
| | | <el-button v-hasPermi="['customer:viewAll']" @click="exportWithSalesperson"> |
| | | 导åºï¼å«å½å±éå®ï¼ |
| | | </el-button> |
| | | ``` |
| | | |
| | | ### 3. æéæ è¯ |
| | | |
| | | 卿é管çï¼è§è²ç®¡ç > èåæéï¼ä¸æ°å¢æé®çº§æéï¼ |
| | | |
| | | | æéæ è¯ | æéåç§° | 说æ | |
| | | |----------|----------|------| |
| | | | `customer:viewAll` | å
¬æµ·å®¢æ·å½å±æ¥ç | å
许æ¥çå
¬æµ·ä¸ææå®¢æ·çå½å±éå®äººä¿¡æ¯ | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - 该æéä¸å½±åå®¢æ·æ°æ®çå¯è§èå´ï¼å
¬æµ·å®¢æ·ä»å¯¹ææç»å½ç¨æ·å¯è§ï¼ï¼åªæ§å¶"å½å±éå®äºº"ä¿¡æ¯çå±ç¤ºã |
| | | - ç§æµ·å表ä¸ï¼ç¨æ·åæ¬å°±åªè½çå°èªå·±ç客æ·ï¼`usageUserName` å§ç»æ¯èªå·±çåç§°ï¼ä¸åæ¤æéå½±åã |
| | | - åç«¯ä¸æéæ©å®¢æ·å表 (`/basic/customer/customerList`) ä¹åæ¤æéå½±åï¼æ æéæ¶ `usageUserName` å¯è½ä¸ºç©ºã |
| | | - AI éå®å©æçå®¢æ·æ¥è¯¢åæ ·éµå¾ªæ¤æéè§åã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ---------------------------- |
| | | -- å®¢æ·æ¡£æ¡ - å
¬æµ·å®¢æ·å½å±æ¥çæé |
| | | -- 说æï¼å¨"å®¢æ·æ¡£æ¡"èå䏿°å¢æé®æéï¼æè¯¥æéçç¨æ·å¯å¨å
¬æµ·æ¥çææå®¢æ·çå½å±éå®äººä¿¡æ¯ |
| | | -- æ§è¡æ¹å¼ï¼ç´æ¥æ§è¡æ¬ SQL æéè¿ç³»ç»èå管çç颿卿·»å |
| | | -- ---------------------------- |
| | | |
| | | -- æ¥æ¾"å®¢æ·æ¡£æ¡"èåç ID ä½ä¸ºç¶èå |
| | | SET @parent_menu_name = 'å®¢æ·æ¡£æ¡(å
¬æµ·)'; |
| | | |
| | | SELECT @parent_id := menu_id |
| | | FROM sys_menu |
| | | WHERE menu_name = @parent_menu_name |
| | | AND menu_type IN ('C', 'M') |
| | | LIMIT 1; |
| | | |
| | | -- ä»
彿¾å°ç¶èåä¸è¯¥æéæ è¯ä¸å卿¶ææå
¥ |
| | | INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark, app_component) |
| | | SELECT 'å
¬æµ·å®¢æ·å½å±æ¥ç', |
| | | @parent_id, |
| | | 9, |
| | | '', |
| | | NULL, |
| | | NULL, |
| | | '', |
| | | 1, |
| | | 0, |
| | | 'F', |
| | | '0', |
| | | '0', |
| | | 'customer:viewAll', |
| | | '#', |
| | | 'admin', |
| | | NOW(), |
| | | '', |
| | | NULL, |
| | | 'æ§å¶å
¬æµ·å®¢æ·å表ä¸å½å±éå®äººåç§°çå¯è§æ§', |
| | | NULL |
| | | FROM DUAL |
| | | WHERE @parent_id IS NOT NULL |
| | | AND NOT EXISTS ( |
| | | SELECT 1 FROM sys_menu WHERE perms = 'customer:viewAll' |
| | | ); |
| | |
| | | customerDto.setType(normalizeSeaType(seaType)); |
| | | customerDto.setUsageStatus(1L); |
| | | |
| | | List<CustomerVo> rows = defaultList(customerMapper.list(customerDto, loginUser.getUserId())); |
| | | boolean isAdmin = SecurityUtils.hasPermi("customer:viewAll"); |
| | | List<CustomerVo> rows = defaultList(customerMapper.list(customerDto, loginUser.getUserId(), isAdmin)); |
| | | List<CustomerVo> filtered = rows.stream() |
| | | .filter(item -> matchCustomerKeyword(item, keyword)) |
| | | .sorted(Comparator.comparing(CustomerVo::getId, Comparator.nullsLast(Comparator.reverseOrder()))) |
| | |
| | | */ |
| | | int deleteCustomerByIds(Long[] ids); |
| | | |
| | | IPage<CustomerVo> listPage(Page<CustomerDto> page, @Param("c") CustomerDto customer, @Param("loginUserId") Long loginUserId); |
| | | IPage<CustomerVo> listPage(Page<CustomerDto> page, @Param("c") CustomerDto customer, @Param("loginUserId") Long loginUserId, @Param("isAdmin") Boolean isAdmin); |
| | | |
| | | List<CustomerVo> list(@Param("c") CustomerDto customer, @Param("loginUserId") Long loginUserId); |
| | | List<CustomerVo> list(@Param("c") CustomerDto customer, @Param("loginUserId") Long loginUserId, @Param("isAdmin") Boolean isAdmin); |
| | | |
| | | IPage<CustomerTransactionsVo> customewTransactions(Page page, @Param("customerName") String customerName); |
| | | |
| | |
| | | public IPage<CustomerVo> selectCustomerList(Page<CustomerDto> page, CustomerDto customer) { |
| | | LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | Long loginUserId = loginUser.getUserId(); |
| | | IPage<CustomerVo> customerPage = customerMapper.listPage(page, customer, loginUserId); |
| | | boolean isAdmin = SecurityUtils.hasPermi("customer:viewAll"); |
| | | IPage<CustomerVo> customerPage = customerMapper.listPage(page, customer, loginUserId, isAdmin); |
| | | |
| | | List<CustomerVo> records = customerPage.getRecords(); |
| | | if (CollectionUtils.isEmpty(records)) { |
| | |
| | | LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | Long tenantId = loginUser.getTenantId(); |
| | | customer.setTenantId(tenantId); |
| | | return customerMapper.insert(customer); |
| | | int result = customerMapper.insert(customer); |
| | | |
| | | // ç§æµ·æ°å¢æ¶åæ¥ä¸æ¡å°å
¬æµ· |
| | | if (customer.getType() != null && customer.getType() == 0) { |
| | | Customer publicSeaCustomer = new Customer(); |
| | | BeanUtils.copyProperties(customer, publicSeaCustomer); |
| | | publicSeaCustomer.setId(null); |
| | | publicSeaCustomer.setType(1); |
| | | publicSeaCustomer.setIsAssigned(0); |
| | | publicSeaCustomer.setUsageUser(loginUser.getUserId()); |
| | | publicSeaCustomer.setUsageStatus(1L); |
| | | customerMapper.insert(publicSeaCustomer); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | |
| | | public List<CustomerVo> selectCustomerLists(CustomerDto customer) { |
| | | LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | Long loginUserId = loginUser.getUserId(); |
| | | return customerMapper.list(customer, loginUserId); |
| | | boolean isAdmin = SecurityUtils.hasPermi("customer:viewAll"); |
| | | return customerMapper.list(customer, loginUserId, isAdmin); |
| | | } |
| | | |
| | | @Override |
| | |
| | | public List<Map<String, Object>> customerList(Customer customer) { |
| | | LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | Long loginUserId = loginUser.getUserId(); |
| | | boolean isAdmin = SecurityUtils.hasPermi("customer:viewAll"); |
| | | CustomerDto query = new CustomerDto(); |
| | | if (customer != null) { |
| | | BeanUtils.copyProperties(customer, query); |
| | | } |
| | | |
| | | // å¤ç¨å®¢æ·å表çå¯è§æ§è§åï¼é¿å
æå«äººçç§æµ·å®¢æ·æ´é²ç»å½åè´¦å· |
| | | List<CustomerVo> visibleCustomers = customerMapper.list(query, loginUserId); |
| | | List<CustomerVo> visibleCustomers = customerMapper.list(query, loginUserId, isAdmin); |
| | | if (CollectionUtils.isEmpty(visibleCustomers)) { |
| | | return Collections.emptyList(); |
| | | } |
| | |
| | | <select id="listPage" resultType="com.ruoyi.basic.vo.CustomerVo"> |
| | | select |
| | | c.*, |
| | | u.user_name usage_user_name, |
| | | <choose> |
| | | <when test="isAdmin"> |
| | | u.nick_name usage_user_name, |
| | | </when> |
| | | <otherwise> |
| | | CASE WHEN c.usage_user = #{loginUserId} OR c.create_user = #{loginUserId} THEN u.nick_name ELSE '' END as usage_user_name, |
| | | </otherwise> |
| | | </choose> |
| | | ( |
| | | select group_concat(u2.user_name separator ', ') |
| | | select group_concat(u2.nick_name separator ', ') |
| | | from customer_user cu |
| | | left join sys_user u2 on cu.user_id = u2.user_id |
| | | where cu.customer_id = c.id |
| | |
| | | <select id="list" resultType="com.ruoyi.basic.vo.CustomerVo"> |
| | | select |
| | | c.*, |
| | | u.user_name usage_user_name, |
| | | <choose> |
| | | <when test="isAdmin"> |
| | | u.nick_name usage_user_name, |
| | | </when> |
| | | <otherwise> |
| | | CASE WHEN c.usage_user = #{loginUserId} OR c.create_user = #{loginUserId} THEN u.nick_name ELSE '' END as usage_user_name, |
| | | </otherwise> |
| | | </choose> |
| | | ( |
| | | select group_concat(u2.user_name separator ', ') |
| | | select group_concat(u2.nick_name separator ', ') |
| | | from customer_user cu |
| | | left join sys_user u2 on cu.user_id = u2.user_id |
| | | where cu.customer_id = c.id |