From fb188a83a1c937b267a83ce2dae1ea0fc3c13c11 Mon Sep 17 00:00:00 2001 From: xlh12306 <2860437006@qq.com> Date: Fri, 16 May 2025 23:12:28 +0800 Subject: [PATCH 01/85] =?UTF-8?q?=E6=8F=90=E4=BA=A4openapi=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95=E4=BB=A3=E7=A0=81=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=8E=A5=E5=8F=A3=E7=AE=A1=E7=90=86=E7=9A=84=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E4=BD=8D=E7=BD=AE=20=E6=8E=88=E6=9D=83=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=88=A0=E6=8E=89=E6=97=A0=E7=94=A8=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=20=E6=8E=88=E6=9D=83=E7=AE=A1=E7=90=86=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E9=87=8D=E7=BD=AE=E7=94=9F=E6=88=90ak=20sk?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=20=E6=8E=88=E6=9D=83=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=BA=94=E8=AF=A5=E6=94=B9=E6=88=90=E8=B7=9F=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E6=8E=88=E6=9D=83=E7=B1=BB=E5=9E=8B=E7=9A=84=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/jeecg/common/util/RestUtil.java | 25 ++++++++++ .../openapi/controller/OpenApiController.java | 2 +- .../OpenApiPermissionController.java | 21 ++------- .../jeecg/modules/openapi/entity/OpenApi.java | 5 ++ .../service/OpenApiPermissionService.java | 6 +++ .../impl/OpenApiPermissionServiceImpl.java | 47 ++++++++++++++++++- .../openapi/test/SampleOpenApiTest.java | 35 ++++++++++++++ .../src/views/openapi/OpenApiAuth.api.ts | 2 +- .../src/views/openapi/OpenApiAuth.data.ts | 6 +-- .../src/views/openapi/OpenApiAuthList.vue | 37 +++++++++++++-- .../src/views/openapi/components/AuthForm.vue | 23 ++++++--- .../views/openapi/components/AuthModal.vue | 37 ++++++++++++--- .../openapi/components/OpenApiAuthForm.vue | 10 ++-- .../openapi/components/OpenApiAuthModal.vue | 2 +- 14 files changed, 211 insertions(+), 47 deletions(-) create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-start/src/test/java/org/jeecg/modules/openapi/test/SampleOpenApiTest.java diff --git a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/RestUtil.java b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/RestUtil.java index f045c7daf..d03b679a2 100644 --- a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/RestUtil.java +++ b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/RestUtil.java @@ -8,6 +8,8 @@ import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.web.client.RestTemplate; +import java.net.MalformedURLException; +import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Iterator; import java.util.Map; @@ -30,6 +32,10 @@ public class RestUtil { // 微服务版集成企业微信单点登录 // 因为微服务版没有端口号,导致 SpringContextUtils.getDomain() 方法获取的域名的端口号变成了:-1所以出问题了,只需要把这个-1给去掉就可以了。 String port=":-1"; + //单元测试导致无端口号的问题 + if (!domain.endsWith(port)){ + checkAndAddPort(); + } if (domain.endsWith(port)) { domain = domain.substring(0, domain.length() - 3); } @@ -37,12 +43,31 @@ public class RestUtil { return domain; } + private static void checkAndAddPort() { + try { + URL url = new URL(domain); + int port = url.getPort(); + if (port == -1) { + domain = domain+":"+getPort(); + } + } catch (MalformedURLException e) { + log.warn("获取端口号异常"); + } + } + private static String getPath() { if (path == null) { path = SpringContextUtils.getApplicationContext().getEnvironment().getProperty("server.servlet.context-path"); } return oConvertUtils.getString(path); } + private static String getPort() { + String property = SpringContextUtils.getApplicationContext().getEnvironment().getProperty("server.port"); + if (StringUtils.isEmpty(property)||"0".equals(property)) { + property = "8080"; + } + return oConvertUtils.getString(property); + } public static String getBaseUrl() { String basepath = getDomain() + getPath(); diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiController.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiController.java index 84d9da2db..3bb171a2a 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiController.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiController.java @@ -162,7 +162,7 @@ public class OpenApiController extends JeecgController String method = openApi.getRequestMethod(); String appkey = request.getHeader("appkey"); OpenApiAuth openApiAuth = openApiAuthService.getByAppkey(appkey); - SysUser systemUser = sysUserService.getById(openApiAuth.getSystemUserId()); + SysUser systemUser = sysUserService.getUserByName(openApiAuth.getCreateBy()); String token = this.getToken(systemUser.getUsername(), systemUser.getPassword()); httpHeaders.put("X-Access-Token", Lists.newArrayList(token)); httpHeaders.put("Content-Type",Lists.newArrayList("application/json")); diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiPermissionController.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiPermissionController.java index 6d3324dfa..9f4d3a445 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiPermissionController.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiPermissionController.java @@ -1,35 +1,22 @@ package org.jeecg.modules.openapi.controller; -import cn.hutool.core.collection.CollectionUtil; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; import org.jeecg.common.api.vo.Result; import org.jeecg.common.system.base.controller.JeecgController; import org.jeecg.modules.openapi.entity.OpenApiPermission; import org.jeecg.modules.openapi.service.OpenApiPermissionService; import org.springframework.web.bind.annotation.*; -import java.util.Arrays; -import java.util.List; - @RestController @RequestMapping("/openapi/permission") public class OpenApiPermissionController extends JeecgController { @PostMapping("add") public Result add(@RequestBody OpenApiPermission openApiPermission) { - List list = Arrays.asList(openApiPermission.getApiId().split(",")); - if (CollectionUtil.isNotEmpty(list)) { - list.forEach(l->{ - OpenApiPermission saveApiPermission = new OpenApiPermission(); - saveApiPermission.setApiId(l); - saveApiPermission.setApiAuthId(openApiPermission.getApiAuthId()); - service.save(saveApiPermission); - }); - } + service.add(openApiPermission); return Result.ok("保存成功"); } - @GetMapping("/list") - public Result list( String apiAuthId) { - return Result.ok(service.list(Wrappers.lambdaQuery().eq(OpenApiPermission::getApiAuthId,apiAuthId))); + @GetMapping("/getOpenApi") + public Result getOpenApi( String apiAuthId) { + return service.getOpenApi(apiAuthId); } } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApi.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApi.java index 5913ccfad..202aa7276 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApi.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApi.java @@ -97,4 +97,9 @@ public class OpenApi implements Serializable { * 更新时间 */ private Date updateTime; + /** + * 历史已选接口 + */ + @TableField(exist = false) + private String ifCheckBox = "0"; } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/OpenApiPermissionService.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/OpenApiPermissionService.java index af541639e..3f45f2f25 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/OpenApiPermissionService.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/OpenApiPermissionService.java @@ -1,6 +1,8 @@ package org.jeecg.modules.openapi.service; import com.baomidou.mybatisplus.extension.service.IService; +import org.jeecg.common.api.vo.Result; +import org.jeecg.modules.openapi.entity.OpenApi; import org.jeecg.modules.openapi.entity.OpenApiPermission; import java.util.List; @@ -10,4 +12,8 @@ import java.util.List; */ public interface OpenApiPermissionService extends IService { List findByAuthId(String authId); + + Result getOpenApi(String apiAuthId); + + void add(OpenApiPermission openApiPermission); } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/impl/OpenApiPermissionServiceImpl.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/impl/OpenApiPermissionServiceImpl.java index f18cba34c..f7d108b3f 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/impl/OpenApiPermissionServiceImpl.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/impl/OpenApiPermissionServiceImpl.java @@ -1,22 +1,67 @@ package org.jeecg.modules.openapi.service.impl; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.jeecg.common.api.vo.Result; +import org.jeecg.modules.openapi.entity.OpenApi; import org.jeecg.modules.openapi.entity.OpenApiPermission; import org.jeecg.modules.openapi.mapper.OpenApiPermissionMapper; import org.jeecg.modules.openapi.service.OpenApiPermissionService; +import org.jeecg.modules.openapi.service.OpenApiService; import org.springframework.stereotype.Service; -import java.util.Collections; +import javax.annotation.Resource; +import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * @date 2024/12/19 17:44 */ @Service public class OpenApiPermissionServiceImpl extends ServiceImpl implements OpenApiPermissionService { + @Resource + private OpenApiService openApiService; @Override public List findByAuthId(String authId) { return baseMapper.selectList(Wrappers.lambdaQuery(OpenApiPermission.class).eq(OpenApiPermission::getApiAuthId, authId)); } + + @Override + public Result getOpenApi(String apiAuthId) { + List openApis = openApiService.list(); + if (CollectionUtil.isEmpty(openApis)) { + return Result.error("接口不存在"); + } + List openApiPermissions = baseMapper.selectList(Wrappers.lambdaQuery().eq(OpenApiPermission::getApiAuthId, apiAuthId)); + if (CollectionUtil.isNotEmpty(openApiPermissions)) { + Map openApiMap = openApis.stream().collect(Collectors.toMap(OpenApi::getId, o -> o)); + for (OpenApiPermission openApiPermission : openApiPermissions) { + OpenApi openApi = openApiMap.get(openApiPermission.getApiId()); + if (openApi!=null) { + openApi.setIfCheckBox("1"); + } + } + } + return Result.ok(openApis); + } + + @Override + public void add(OpenApiPermission openApiPermission) { + this.remove(Wrappers.lambdaQuery().eq(OpenApiPermission::getApiAuthId, openApiPermission.getApiAuthId())); + List list = Arrays.asList(openApiPermission.getApiId().split(",")); + if (CollectionUtil.isNotEmpty(list)) { + list.forEach(l->{ + if (StrUtil.isNotEmpty(l)){ + OpenApiPermission saveApiPermission = new OpenApiPermission(); + saveApiPermission.setApiId(l); + saveApiPermission.setApiAuthId(openApiPermission.getApiAuthId()); + this.save(saveApiPermission); + } + }); + } + } } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/test/java/org/jeecg/modules/openapi/test/SampleOpenApiTest.java b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/test/java/org/jeecg/modules/openapi/test/SampleOpenApiTest.java new file mode 100644 index 000000000..b48feb324 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/test/java/org/jeecg/modules/openapi/test/SampleOpenApiTest.java @@ -0,0 +1,35 @@ +package org.jeecg.modules.openapi.test; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import org.jeecg.JeecgSystemApplication; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,classes = JeecgSystemApplication.class) +@AutoConfigureMockMvc +public class SampleOpenApiTest { + @Autowired + private MockMvc mockMvc; + @Test + public void test() throws Exception { + String url = "/openapi/call/wYAu6xwg"; + MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get(url) + .param("id","a7d7e77e06c84325a40932163adcdaa6") + .header("appkey","ak-8CVxh8aYRkzZ0Z2u") + .header("signature","3ec15caeaf9b6281d0ab825795f61e2d") + .header("timestamp","1747403650402"); + String result = mockMvc.perform(requestBuilder).andReturn().getResponse().getContentAsString(); + JSONObject jsonObject = JSON.parseObject(result); + Assertions.assertEquals(true, jsonObject.getBoolean("success")); + System.out.println(jsonObject); + + } +} diff --git a/jeecgboot-vue3/src/views/openapi/OpenApiAuth.api.ts b/jeecgboot-vue3/src/views/openapi/OpenApiAuth.api.ts index 2ef98bcfb..67396b751 100644 --- a/jeecgboot-vue3/src/views/openapi/OpenApiAuth.api.ts +++ b/jeecgboot-vue3/src/views/openapi/OpenApiAuth.api.ts @@ -9,7 +9,7 @@ enum Api { edit='/openapi/auth/edit', apiList= '/openapi/list', genAKSK = '/openapi/auth/genAKSK', - permissionList='/openapi/permission/list', + permissionList='/openapi/permission/getOpenApi', permissionAdd='/openapi/permission/add', deleteOne = '/openapi/auth/delete', deleteBatch = '/openapi/auth/deleteBatch', diff --git a/jeecgboot-vue3/src/views/openapi/OpenApiAuth.data.ts b/jeecgboot-vue3/src/views/openapi/OpenApiAuth.data.ts index 558615bd0..142b42bed 100644 --- a/jeecgboot-vue3/src/views/openapi/OpenApiAuth.data.ts +++ b/jeecgboot-vue3/src/views/openapi/OpenApiAuth.data.ts @@ -33,7 +33,7 @@ export const columns: BasicColumn[] = [ { title: '关联系统用户名', align: "center", - dataIndex: 'systemUserId_dictText', + dataIndex: 'createBy', }, ]; @@ -43,7 +43,7 @@ export const superQuerySchema = { name: {title: '授权名称',order: 0,view: 'text', type: 'string',}, ak: {title: 'AK',order: 1,view: 'text', type: 'string',}, sk: {title: 'SK',order: 2,view: 'text', type: 'string',}, - createBy: {title: '创建人',order: 3,view: 'text', type: 'string',}, + createBy: {title: '关联系统用户名',order: 3,view: 'text', type: 'string',}, createTime: {title: '创建时间',order: 4,view: 'datetime', type: 'string',}, - systemUserId: {title: '关联系统用户名',order: 5,view: 'text', type: 'string',}, + // systemUserId: {title: '关联系统用户名',order: 5,view: 'text', type: 'string',}, }; diff --git a/jeecgboot-vue3/src/views/openapi/OpenApiAuthList.vue b/jeecgboot-vue3/src/views/openapi/OpenApiAuthList.vue index ab1e70855..cb220c0b7 100644 --- a/jeecgboot-vue3/src/views/openapi/OpenApiAuthList.vue +++ b/jeecgboot-vue3/src/views/openapi/OpenApiAuthList.vue @@ -11,9 +11,9 @@ - + - + @@ -62,6 +62,7 @@ + @@ -73,11 +74,19 @@ import { BasicTable, TableAction } from '/@/components/Table'; import { useListPage } from '/@/hooks/system/useListPage'; import { columns, superQuerySchema } from './OpenApiAuth.data'; - import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './OpenApiAuth.api'; + import { + list, + deleteOne, + batchDelete, + getImportUrl, + getExportUrl, + getGenAKSK + } from "./OpenApiAuth.api"; import OpenApiAuthModal from './components/OpenApiAuthModal.vue' import AuthModal from './components/AuthModal.vue' import { useUserStore } from '/@/store/modules/user'; import JSearchSelect from "../../components/Form/src/jeecg/components/JSearchSelect.vue"; + import { saveOrUpdate } from "@/views/openapi/OpenApi.api"; const formRef = ref(); const queryParam = reactive({}); @@ -157,8 +166,22 @@ */ function handleEdit(record: Recordable) { registerModal.value.disableSubmit = false; + registerModal.value.authDrawerOpen = true; registerModal.value.edit(record); } + + /** + * 重置事件 + * @param record + */ + async function handleReset(record: Recordable) { + const AKSKObj = await getGenAKSK({}); + record.ak = AKSKObj[0]; + record.sk = AKSKObj[1]; + saveOrUpdate(record,true); + // handleSuccess; + + } /** * 详情 @@ -200,8 +223,12 @@ auth: 'openapi:open_api_auth:edit' }, { - label: '编辑', - onClick: handleEdit.bind(null, record), + label: '重置', + popConfirm: { + title: '是否重置AK,SK', + confirm: handleReset.bind(null, record), + placement: 'topLeft', + }, auth: 'openapi:open_api_auth:edit' }, ]; diff --git a/jeecgboot-vue3/src/views/openapi/components/AuthForm.vue b/jeecgboot-vue3/src/views/openapi/components/AuthForm.vue index 0abd0d72a..7f5cbb482 100644 --- a/jeecgboot-vue3/src/views/openapi/components/AuthForm.vue +++ b/jeecgboot-vue3/src/views/openapi/components/AuthForm.vue @@ -33,7 +33,7 @@ }, }, }); - const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] = + const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource,setSelectedRowKeys }, { rowSelection, selectedRowKeys,selectedRows }] = tableContext; const props = defineProps({ @@ -85,13 +85,18 @@ formData.apiAuthId = record.id; // 获取当前已授权的项目 getPermissionList({ apiAuthId: record.id }).then((res) => { - if (res && res.length > 0) { - let list = res.result.records || res.result; + if (res.length > 0) { + let list = res; let ids = []; list.forEach((item) => { + if(item.ifCheckBox == "1"){ + selectedRowKeys.value.push(item.id) + selectedRows.value.push(item) + setSelectedRowKeys(selectedRowKeys.value); + } ids.push(item.apiId); }); - selectedRowKeys.value = ids; + // selectedRowKeys.value = ids; formData.apiIdList = ids; } }); @@ -102,8 +107,8 @@ * 提交数据 */ async function submitForm() { - if(selectedRowKeys.value.length === 0) - return emit('ok'); + // if(selectedRowKeys.value.length === 0) + // return emit('ok'); try { // 触发表单验证 await validate(); @@ -131,6 +136,7 @@ if (res.success) { createMessage.success(res.message); emit('ok'); + cleanData() } else { createMessage.warning(res.message); } @@ -139,11 +145,16 @@ confirmLoading.value = false; }); } + const cleanData = () => { + selectedRows.value = [] + selectedRowKeys.value = [] + } defineExpose({ add, edit, submitForm, + cleanData }); diff --git a/jeecgboot-vue3/src/views/openapi/components/AuthModal.vue b/jeecgboot-vue3/src/views/openapi/components/AuthModal.vue index 511aadc65..25677a008 100644 --- a/jeecgboot-vue3/src/views/openapi/components/AuthModal.vue +++ b/jeecgboot-vue3/src/views/openapi/components/AuthModal.vue @@ -1,14 +1,29 @@ diff --git a/jeecgboot-vue3/src/components/Form/src/jeecg/components/JLinkTableCard/components/LinkTableListModal.vue b/jeecgboot-vue3/src/components/Form/src/jeecg/components/JLinkTableCard/components/LinkTableListModal.vue new file mode 100644 index 000000000..1ac73241e --- /dev/null +++ b/jeecgboot-vue3/src/components/Form/src/jeecg/components/JLinkTableCard/components/LinkTableListModal.vue @@ -0,0 +1,320 @@ + + + + + diff --git a/jeecgboot-vue3/src/components/Form/src/jeecg/components/JLinkTableCard/hooks/useLinkTable.ts b/jeecgboot-vue3/src/components/Form/src/jeecg/components/JLinkTableCard/hooks/useLinkTable.ts new file mode 100644 index 000000000..91b3244fb --- /dev/null +++ b/jeecgboot-vue3/src/components/Form/src/jeecg/components/JLinkTableCard/hooks/useLinkTable.ts @@ -0,0 +1,358 @@ +import { defHttp } from '/@/utils/http/axios'; +import { ref, watchEffect, computed, reactive } from 'vue'; +import { pick } from 'lodash-es'; +import { filterMultiDictText } from '/@/utils/dict/JDictSelectUtil'; +import { getFileAccessHttpUrl } from '/@/utils/common/compUtils'; + +function queryTableData(tableName, params) { + const url = '/online/cgform/api/getData/' + tableName; + return defHttp.get({ url, params }); +} + +function queryTableColumns(tableName, params) { + const url = '/online/cgform/api/getColumns/' + tableName; + return defHttp.get({ url, params }); +} + +export function useLinkTable(props) { + //TODO 目前只支持查询第一页的数据,可以输入关键字搜索 + const pageNo = ref('1'); + // 查询列 + const baseParam = ref({}); + // 搜素条件 + const searchParam = ref({}); + // 第一个文本列 + const mainContentField = ref(''); + //权限数据 + const auths = reactive({ + add: true, + update: true, + }); + + //显示列 + const textFieldArray = computed(() => { + if (props.textField) { + return props.textField.split(','); + } + return []; + }); + const otherColumns = ref([]); + // 展示的列 配置的很多列,但是只展示三行 + const realShowColumns = computed(() => { + const columns = otherColumns.value; + if (props.multi == true) { + return columns.slice(0, 3); + } else { + return columns.slice(0, 6); + } + }); + + watchEffect(async () => { + const table = props.tableName; + if (table) { + const valueField = props.valueField || ''; + const textField = props.textField || ''; + const arr: any[] = []; + if (valueField) { + arr.push(valueField); + } + if (textField) { + const temp = textField.split(','); + mainContentField.value = temp[0]; + for (const field of temp) { + arr.push(field); + } + } + const imageField = props.imageField || ''; + if (imageField) { + arr.push(imageField); + } + baseParam.value = { + linkTableSelectFields: arr.join(','), + }; + await resetTableColumns(); + await reloadTableLinkOptions(); + } + }); + + const otherFields = computed(() => { + const textField = props.textField || ''; + const others: any[] = []; + let labelField = ''; + if (textField) { + const temp = textField.split(','); + labelField = temp[0]; + for (let i = 0; i < temp.length; i++) { + if (i > 0) { + others.push(temp[i]); + } + } + } + return { + others, + labelField, + }; + }); + + // 选项 + const selectOptions = ref([]); + const tableColumns = ref([]); + const dictOptions = ref({}); + + async function resetTableColumns() { + const params = baseParam.value; + const data = await queryTableColumns(props.tableName, params); + tableColumns.value = data.columns; + if (data.columns) { + const imageField = props.imageField; + const arr = data.columns.filter((c) => c.dataIndex != mainContentField.value && c.dataIndex != imageField); + otherColumns.value = arr; + } + dictOptions.value = data.dictOptions; + // 权限数据 + console.log('隐藏的按钮', data.hideColumns); + if (data.hideColumns) { + const hideCols = data.hideColumns; + if (hideCols.indexOf('add') >= 0) { + auths.add = false; + } else { + auths.add = true; + } + if (hideCols.indexOf('update') >= 0) { + auths.update = false; + } else { + auths.update = true; + } + } + } + + async function reloadTableLinkOptions() { + const params = getLoadDataParams(); + const data = await queryTableData(props.tableName, params); + const records = data.records; + //tableTitle.value = data.head.tableTxt; + const dataList: any[] = []; + const { others, labelField } = otherFields.value; + const imageField = props.imageField; + if (records && records.length > 0) { + for (const rd of records) { + const temp = { ...rd }; + transData(temp); + const result = Object.assign({}, pick(temp, others), { id: temp.id, label: temp[labelField], value: temp[props.valueField] }); + if (imageField) { + result[imageField] = temp[imageField]; + } + dataList.push(result); + } + } + //添加一个空对象 为add操作占位 + // update-begin--author:liaozhiyang---date:20240607---for:【TV360X-1095】高级查询关联记录去掉编辑按钮及去掉记录按钮 + props.editBtnShow && dataList.push({}); + // update-end--author:liaozhiyang---date:20240607---for:【TV360X-1095】高级查询关联记录去掉编辑按钮及去掉记录按钮 + selectOptions.value = dataList; + } + + /** + * 数据简单翻译-字典 + * @param data + */ + function transData(data) { + const columns = tableColumns.value; + const dictInfo = dictOptions.value; + for (const c of columns) { + const { dataIndex, customRender } = c; + if (data[dataIndex] || data[dataIndex] === 0) { + if (customRender && customRender == dataIndex) { + //这样的就是 字典数据了 可以直接翻译 + if (dictInfo[customRender]) { + data[dataIndex] = filterMultiDictText(dictInfo[customRender], data[dataIndex]); + continue; + } + } + } + // 兼容后台翻译字段 + const dictText = data[dataIndex + '_dictText']; + if (dictText) { + data[dataIndex] = dictText; + } + } + } + + //获取加载数据的查询条件 + function getLoadDataParams() { + const params = Object.assign({ pageSize: 100, pageNo: pageNo.value }, baseParam.value, searchParam.value); + return params; + } + + //设置查询条件 + function addQueryParams(text) { + if (!text) { + searchParam.value = {}; + } else { + const arr = textFieldArray.value; + const params: any[] = []; + const fields: any[] = []; + for (let i = 0; i < arr.length; i++) { + if (i <= 1) { + fields.push(arr[i]); + params.push({ field: arr[i], rule: 'like', val: text }); + } + } + // params[arr[i]] = `*${text}*` + // params['selectConditionFields'] = fields.join(',') + // searchParam.value = params; + params['superQueryMatchType'] = 'or'; + params['superQueryParams'] = encodeURI(JSON.stringify(params)); + searchParam.value = params; + } + } + + async function loadOne(value) { + if (!value) { + return []; + } + let valueFieldName = props.valueField; + let params = { + ...baseParam.value, + pageSize: 100, + pageNo: pageNo.value, + }; + params['superQueryMatchType'] = 'and'; + let valueCondition = [{ field: valueFieldName, rule: 'in', val: value }]; + params['superQueryParams'] = encodeURI(JSON.stringify(valueCondition)); + const data = await queryTableData(props.tableName, params); + let records = data.records; + //tableTitle.value = data.head.tableTxt; + let dataList: any[] = []; + if (records && records.length > 0) { + for (let item of records) { + let temp = { ...item }; + transData(temp); + dataList.push(temp); + } + } + return dataList; + } + + /** + * true:数据一致;false:数据不一致 + * @param arr + * @param value + */ + function compareData(arr, value) { + if (!arr || arr.length == 0) { + return false; + } + const valueArray = value.split(','); + if (valueArray.length != arr.length) { + return false; + } + let flag = true; + for (const item of arr) { + const temp = item[props.valueField]; + if (valueArray.indexOf(temp) < 0) { + flag = false; + } + } + return flag; + } + + function formatData(formData) { + Object.keys(formData).map((k) => { + if (formData[k] instanceof Array) { + formData[k] = formData[k].join(','); + } + }); + } + + function initFormData(formData, linkFieldArray, record) { + if (!record) { + record = {}; + } + if (linkFieldArray && linkFieldArray.length > 0) { + for (const str of linkFieldArray) { + const arr = str.split(','); + //["表单字段,表字典字段"] + const field = arr[0]; + const dictField = arr[1]; + if (!formData[field]) { + const value = record[dictField] || ''; + formData[field] = [value]; + } else { + formData[field].push(record[dictField]); + } + } + } + } + + // 获取图片地址 + function getImageSrc(item) { + if (props.imageField) { + let url = item[props.imageField]; + // update-begin--author:liaozhiyang---date:20250517---for:【TV360X-38】关联记录空间,被关联数据优多个图片时,封面图片不展示 + if (typeof url === 'string') { + // 有多张图时默认取第一张 + url = url.split(',')[0]; + } + // update-end--author:liaozhiyang---date:20250517---for:【TV360X-38】关联记录空间,被关联数据优多个图片时,封面图片不展示 + return getFileAccessHttpUrl(url); + } + return ''; + } + const showImage = computed(() => { + if (props.imageField) { + return true; + } else { + return false; + } + }); + + return { + pageNo, + otherColumns, + realShowColumns, + selectOptions, + reloadTableLinkOptions, + textFieldArray, + addQueryParams, + tableColumns, + transData, + mainContentField, + loadOne, + compareData, + formatData, + initFormData, + getImageSrc, + showImage, + auths, + }; +} + +/** + * 使用固定高度的modal + */ +export function useFixedHeightModal() { + const minWidth = 800; + const popModalFixedWidth = ref(800); + let tempWidth = window.innerWidth - 300; + if (tempWidth < minWidth) { + tempWidth = minWidth; + } + popModalFixedWidth.value = tempWidth; + + // 弹窗高度控制 + const popBodyStyle = ref({}); + function resetBodyStyle() { + const height = window.innerHeight - 210; + popBodyStyle.value = { + height: height + 'px', + overflowY: 'auto', + }; + } + + return { + popModalFixedWidth, + popBodyStyle, + resetBodyStyle, + }; +} diff --git a/jeecgboot-vue3/src/components/Form/src/jeecg/components/JSearchSelect.vue b/jeecgboot-vue3/src/components/Form/src/jeecg/components/JSearchSelect.vue index 4b3f502de..6c0776d43 100644 --- a/jeecgboot-vue3/src/components/Form/src/jeecg/components/JSearchSelect.vue +++ b/jeecgboot-vue3/src/components/Form/src/jeecg/components/JSearchSelect.vue @@ -15,6 +15,9 @@ @search="loadData" @change="handleAsyncChange" @popupScroll="handlePopupScroll" + :mode="multiple?'multiple':''" + @select="handleSelect" + @deselect="handleDeSelect" >