9eadeb70 by lihua

数据服务前端代码

1 parent 24ba6db6
1 # 页面标题 1 # 页面标题
2 VITE_APP_TITLE = 数据资产管理系统 2 VITE_APP_TITLE = 可信数据空间
3 # 接口域名 3 # 接口域名
4 # VITE_API_BASEURL = https://www.zgsjzc.com/api 4 # VITE_API_BASEURL = https://www.zgsjzc.com/api
5 # VITE_API_BASEURL = https://swzl-test.csbr.cn/api 5 # VITE_API_BASEURL = https://swzl-test.csbr.cn/api
6 VITE_API_BASEURL = http://192.168.6.20:28052/ 6 # VITE_API_BASEURL = http://localhost:9000
7 VITE_API_BASEURL = http://192.168.9.1:58052/
7 # VITE_API_BASEURL = http://192.168.6.20:8052/ 8 # VITE_API_BASEURL = http://192.168.6.20:8052/
8 9
9 VITE_IDASS_BASEURL = https://daop-test.zgsjzc.com/portalLogin 10 VITE_IDASS_BASEURL = https://daop-test.zgsjzc.com/portalLogin
...@@ -97,6 +98,9 @@ VITE_APP_CIRCULATION = https://daop-lt-test.zgsjzc.com/ ...@@ -97,6 +98,9 @@ VITE_APP_CIRCULATION = https://daop-lt-test.zgsjzc.com/
97 #数据加工交付 98 #数据加工交付
98 VITE_APP_DATA_DELIVERY = https://daop-jgjf-test.zgsjzc.com/ 99 VITE_APP_DATA_DELIVERY = https://daop-jgjf-test.zgsjzc.com/
99 100
101 #数据服务接口地址
102 VITE_APP_SERVICE_BASEURL = ms-daop-jgjf-data-open-service
103
100 # 本地访问地址 104 # 本地访问地址
101 # VITE_API_CIRCULATION_URL = http://localhost:9000/circulation 105 # VITE_API_CIRCULATION_URL = http://localhost:9000/circulation
102 106
......
1 # 页面标题 1 # 页面标题
2 VITE_APP_TITLE = 数据资产管理系统 2 VITE_APP_TITLE = 可信数据空间
3 # 接口域名 3 # 接口域名
4 VITE_API_BASEURL = https://daop-zcgl-test.zgsjzc.com/ 4 VITE_API_BASEURL = https://daop-zcgl-test.zgsjzc.com/
5 # VITE_API_BASEURL = http://49.4.26.201:31709/ 5 # VITE_API_BASEURL = http://49.4.26.201:31709/
...@@ -122,6 +122,9 @@ VITE_API_MESSAGE = ms-daop-message-service ...@@ -122,6 +122,9 @@ VITE_API_MESSAGE = ms-daop-message-service
122 #企业信息接口 122 #企业信息接口
123 VITE_APP_PERSONAL_URL = ms-daop-personel-service 123 VITE_APP_PERSONAL_URL = ms-daop-personel-service
124 124
125 #数据服务接口地址
126 VITE_APP_SERVICE_BASEURL = ms-daop-jgjf-data-open-service
127
125 #流通平台接口地址 128 #流通平台接口地址
126 VITE_APP_CIRCULATION = https://daop-lt-test.zgsjzc.com/ 129 VITE_APP_CIRCULATION = https://daop-lt-test.zgsjzc.com/
127 #数据加工交付 130 #数据加工交付
......
1 /** 数据服务模块接口 */
2 import request from "@/utils/request";
3
4 /** api类型,有表单类型,自定义sql. */
5 export const apiTypes: any = [{
6 value: 1,
7 label: '单表API'
8 }, {
9 value: 2,
10 label: '自定义sql'
11 }, {
12 value: 3,
13 label: '注册API'
14 }];
15
16 /** 查询域名和文根 */
17 export const getDomainName = () => request({
18 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-base-info/domain-and-service-name`,
19 method: 'get'
20 })
21
22 // 获取参数类型的接口
23 export const getDataTypeList = () => request({
24 url:`${import.meta.env.VITE_APP_API_BASEURL}/data-dict/get-data-list`,
25 method: 'post',
26 data: { paramCode: "DATA_TYPE" }
27 })
28
29 /** 获取参数位置 */
30 // export const getPositionList = () => request({
31 // url:`${import.meta.env.VITE_APP_CONFIG_URL}/data-dict/get-data-list`,
32 // method: 'post',
33 // data: { paramCode: "PARAM_POSITION" }
34 // })
35
36 /** 获取参数操作符 */
37 export const getOperationList = () => request({
38 url:`${import.meta.env.VITE_APP_API_BASEURL}/data-dict/get-data-list`,
39 method: 'post',
40 data: { paramCode: "PARAM_OPERATOR" }
41 })
42
43 /** 获取主题域分层的主题表树结构 */
44 export const getSubjectTableTree = (params) => request({
45 url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-directory/directory-tree-list`,
46 method: 'post',
47 data: params
48 })
49
50 /** 获取主题域分层的主题表树结构 */
51 export const getSubjectTableByDomain = (params) => request({
52 url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/list-by-domain-guid?domainGuid=${params}`,
53 method: 'get',
54 data: params
55 })
56
57 /** 获取主题表详情,用于绑定字段下拉列表。 */
58 export const getSubjectTableDetail = (params) => request({
59 url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/detailToSync/${params}`,
60 method: 'get'
61 })
62
63 /** -------------------------- 管理API ------------------------------------ */
64 /** 获取标签列表 */
65 export const getTagsList = (params) => request({
66 url:`${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-tag-sort/page-list`,
67 method: 'post',
68 data: params
69 })
70
71 /** 添加标签接口 */
72 export const addTagLabel = (params) => request({
73 url:`${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-tag-sort/save`,
74 method: 'post',
75 data: params
76 })
77
78 /** 编辑标签 */
79 export const editTagLabel = (params) => request({
80 url:`${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-tag-sort/update`,
81 method: 'post',
82 data: params
83 })
84
85 /** 删除标签 */
86 export const deleteTag = (params) => request({
87 url:`${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-tag-sort/delete`,
88 method: 'delete',
89 data: params
90 })
91
92 /** api信息列表 */
93 export const getAPIList = (params) => request({
94 url:`${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-base-info/page-list`,
95 method: 'post',
96 data: params
97 })
98
99 /** 启用停用API */
100 export const updateAPIState = (params) => request({
101 url:`${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-base-info/start-or-stop?guid=${params.guid}&apiState=${params.apiState}`,
102 method: 'get'
103 })
104
105 /** 移动API信息 */
106 export const moveAPI = (params) => request({
107 url:`${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-base-info/move?sceneGuid=${params.sceneGuid }`,
108 method: 'post',
109 data: params.guids
110 })
111
112 /** 新建api时验证api名称是否存在 */
113 export const checkExistAPIName = (params) => request({
114 url:`${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-base-info/exist-api-name?apiName=${params}`,
115 method: 'get'
116 })
117
118 /** 新建api时验证api请求路径是否存在 */
119 export const checkExistRequestPath = (params) => request({
120 url:`${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-base-info/exist-request-path?requestName=${params}`,
121 method: 'get'
122 })
123
124 /** 新增API信息 */
125 export const addApi = (params) => request({
126 url:`${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-base-info/save`,
127 method: 'post',
128 data: params
129 })
130
131 /** 修改API信息 */
132 export const updateApi = (params) => request({
133 url:`${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-base-info/update`,
134 method: 'post',
135 data: params
136 })
137
138 /** 提交发起API审批流程 */
139 export const addApiApprove = (guid) => request({
140 url:`${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-base-info/add-approve/${guid}`,
141 method: 'get'
142 })
143
144 /** 删除API信息 */
145 export const deleteApi = (guid) => request({
146 url:`${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-base-info/delete?guid=${guid}`,
147 method: 'delete'
148 })
149
150 /** 复制API */
151 export const copyApi = (params) => request({
152 url:`${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-base-info/copy?apiName=${params.apiName}&guid=${params.guid}&requestPath=${params.requestPath}`,
153 method: 'get'
154 })
155
156 /** 获取api详情信息 */
157 export const getApiDetail = (guid) => request({
158 url:`${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-base-info/detail/${guid}`,
159 method: 'get'
160 })
161
162 /** 获取api流程详情 */
163 export const getApiApprovalDetail = (guid) => request({
164 url:`${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-base-info/approve-detail/${guid}`,
165 method: 'get'
166 })
167
168 /** 验证API */
169 export const validateApiSql = (params) => request({
170 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/invoke/check-sql`,
171 method: 'post',
172 data: params
173 })
174
175 /** 第三步测试调用APi */
176 export const testEditApi = (params) => request({
177 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/invoke/test`,
178 method: 'post',
179 data: params
180 })
181
182 /** --------------------------- API授权设置应用产品 -------------------------------- */
183 /** 获取api产品列表 */
184 export const getAppProductList = () => request({
185 url:`${import.meta.env.VITE_APP_SERVICE_BASEURL}/app-product/list`,
186 method: 'get'
187 })
188
189 /** 获取api绑定产品列表数据 */
190 export const getApibindProducts = (params) => request({
191 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-product-binding/page-list`,
192 method: 'post',
193 data: params
194 })
195
196 /** 保存APi产品绑定关系 */
197 export const saveApiBindProduct = (params) => request({
198 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-product-binding/save`,
199 method: 'post',
200 data: params
201 })
202
203 /** --------------------------- 调用,授权API-------------------------------- */
204 /** 获取product列表数据 */
205 export const getAppProductData = (params) => request({
206 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/app-product/page-list`,
207 method: 'post',
208 data: params
209 })
210
211 /** 判断是否是idaas */
212 export const isUseIdaas = () => request({
213 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/app-product/isUseIdaas`,
214 method: 'get'
215 })
216
217 /** 判断应用产品名称是否重复 */
218 export const isExistProduct = (params) => request({
219 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/app-product/exist?productName=${params}`,
220 method: 'post'
221 })
222
223 /** 判断appKey是否重复 */
224 export const isExistAppKey = (params) => request({
225 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/app-product/exist-appKey?appKey=${params}`,
226 method: 'post'
227 })
228
229 /** 获取应用产品详情 */
230 export const getProductDetail = (guid) => request({
231 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/app-product/detail?guid=${guid}`,
232 method: 'get'
233 })
234
235 /** 保存应用产品设置 */
236 export const saveProduct = (params) => request({
237 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/app-product/save`,
238 method: 'post',
239 data: params
240 })
241
242 /** 修改应用产品设置 */
243 export const updateProduct = (params) => request({
244 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/app-product/update`,
245 method: 'post',
246 data: params
247 })
248
249 /** 删除应用产品 */
250 export const deleteAppProduct = (params) => request({
251 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/app-product/delete`,
252 method: 'delete',
253 data: params
254 });
255
256 /** ---------------------------- 测试API ---------------------------------------- */
257
258 /** 获取有效的标签列表 */
259 export const getValidApiLabel = (isApiValid = false) => request({
260 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-tag-sort/list-valid${isApiValid ? '?isApiValid=true' : ''}`,
261 method: 'get'
262 })
263 export const getSceneValidApiLabel = (isApiValid = false) => request({
264 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-base-info/list-valid-scene${isApiValid ? '?isApiValid=true' : '?isApiValid=false'}`,
265 method: 'get'
266 })
267
268 /** 根据标签获取有效的api列表 */
269 export const getValidApi = (sceneGuid) => request({
270 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-base-info/list-valid?sceneGuid=${sceneGuid}`,
271 method: 'get'
272 })
273
274 /** 根据标签获取所有的api列表 */
275 export const getAllApi = (sceneGuid) => request({
276 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/api-base-info/list-by-scene-guid/${sceneGuid}`,
277 method: 'get'
278 })
279
280 /** 测试API调用借口 */
281 export const testApiData = (params) => request({
282 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/invoke/test-by-guid`,
283 method: 'post',
284 data: params
285 })
286
287 /** ---------------------------- 首页数据服务看板 ---------------------------------------- */
288
289 /** 获取首页指标统计 */
290 export const getDataStat = (params) => request({
291 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/home-page/data-stat?startTime=${params?.[0]}&endTime=${params?.[1]}`,
292 method: 'get'
293 })
294
295 /** 调用影响的应用产品统计 */
296 export const getProductStat = (params) => request({
297 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/home-page/product-stat?endTime=${params?.[1]}`,
298 method: 'get'
299 })
300
301 /** 调用异常次数的APi统计 */
302 export const getAPIErrorStat = (params) => request({
303 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/home-page/api-error-stat?appKey=${params.appKey}&startTime=${params.date?.[0]}&endTime=${params.date?.[1]}`,
304 method: 'get'
305 })
306
307 /** 调用次数的趋势图 */
308 export const getCallApiCountStat = (params) => request({
309 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/home-page/call-api-number-stat?endTime=${params?.[1]}`,
310 method: 'get'
311 })
312
313 /** 调用API数的趋势图 */
314 export const getCallApiNumberStat = (params) => request({
315 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/home-page/call-api-count-stat?endTime=${params?.[1]}`,
316 method: 'get'
317 })
318
319 /** ---------------------------- ip白名单管理 ---------------------------------------- */
320 /** 获取ip列表数据 */
321 export const getIPList = (params) => request({
322 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/white-ip/page-list`,
323 method: 'post',
324 data: params
325 })
326
327 /** 添加ip */
328 export const saveIP = (params) => request({
329 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/white-ip/save`,
330 method: 'post',
331 data: params
332 })
333
334 /** 修改Ip */
335 export const updateIP = (params) => request({
336 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/white-ip/update`,
337 method: 'post',
338 data: params
339 })
340
341 /** 删除IP */
342 export const deleteIP = (params) => request({
343 url: `${import.meta.env.VITE_APP_SERVICE_BASEURL}/white-ip/delete`,
344 method: 'delete',
345 data: params
346 })
...\ No newline at end of file ...\ No newline at end of file
...@@ -32,10 +32,10 @@ export const getSystemMenu = (params, isAdmin = false) => { ...@@ -32,10 +32,10 @@ export const getSystemMenu = (params, isAdmin = false) => {
32 isAdmin 32 isAdmin
33 ? `${ 33 ? `${
34 import.meta.env.VITE_APP_AUTH_URL 34 import.meta.env.VITE_APP_AUTH_URL
35 }/product-menu-permission/tenant/get-product-menu?tenantGuid=${params.tenantGuid}&platformSystemGuid=32774fcfdf5e43e8b866660374d8bced` 35 }/product-menu-permission/tenant/get-product-menu?tenantGuid=${params.tenantGuid}&platformSystemGuid=4149c763d70948b195eb3d4b997c1722`
36 : `${ 36 : `${
37 import.meta.env.VITE_APP_AUTH_URL 37 import.meta.env.VITE_APP_AUTH_URL
38 }/product-menu-permission/staff/get-product-menu-template?platformSystemGuid=32774fcfdf5e43e8b866660374d8bced`, 38 }/product-menu-permission/staff/get-product-menu-template?platformSystemGuid=4149c763d70948b195eb3d4b997c1722`,
39 method: "get", 39 method: "get",
40 }); 40 });
41 }; 41 };
...@@ -247,6 +247,21 @@ export const getDataSource = (params) => request({ ...@@ -247,6 +247,21 @@ export const getDataSource = (params) => request({
247 method: "post", 247 method: "post",
248 data: params, 248 data: params,
249 }); 249 });
250
251 /** 获取数据源列表 */
252 export const getSchemaTableList = (params) => request({
253 url:`${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/schema-table-page-list`,
254 method: 'post',
255 data: params
256 })
257
258 // 获取表结构
259 export const tableColumnList = (params)=> request({
260 url:`${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/table-column-list`,
261 method: 'post',
262 data: params
263 })
264
250 // 新增 265 // 新增
251 export const addDataSource = (params) => request({ 266 export const addDataSource = (params) => request({
252 url: `${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/save`, 267 url: `${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/save`,
...@@ -289,6 +304,12 @@ export const getAllFlowData = (params) => request({ ...@@ -289,6 +304,12 @@ export const getAllFlowData = (params) => request({
289 method: 'get', 304 method: 'get',
290 params 305 params
291 }) 306 })
307
308 export const getParamsDictList = (dictType) => request({
309 url: `${import.meta.env.VITE_APP_CONFIG_URL}/dict/data/get-by-dictType?dictType=${dictType}`,
310 method: 'get',
311 })
312
292 // 获取资产/价值评估机构数据 313 // 获取资产/价值评估机构数据
293 export const getSingleList = (params) => request({ 314 export const getSingleList = (params) => request({
294 url: `${import.meta.env.VITE_APP_PERSONAL_URL}/tenant/singlePage`, 315 url: `${import.meta.env.VITE_APP_PERSONAL_URL}/tenant/singlePage`,
...@@ -316,4 +337,11 @@ export const getParamsList = (params) => request({ ...@@ -316,4 +337,11 @@ export const getParamsList = (params) => request({
316 url: `${import.meta.env.VITE_APP_CONFIG_URL}/dict/data/get-by-dictType`, 337 url: `${import.meta.env.VITE_APP_CONFIG_URL}/dict/data/get-by-dictType`,
317 method: 'get', 338 method: 'get',
318 params 339 params
319 })
...\ No newline at end of file ...\ No newline at end of file
340 })
341
342 // sql验证
343 export const checkSql = (params) => request({
344 url:`${import.meta.env.VITE_APP_DATA_SOURCE_URL }/sql-operate/check-sql`,
345 method: 'post',
346 data:params
347 })
......
...@@ -3,25 +3,6 @@ function Layout() { ...@@ -3,25 +3,6 @@ function Layout() {
3 return import('@/layouts/index.vue') 3 return import('@/layouts/index.vue')
4 } 4 }
5 const routes: RouteRecordRaw[] = [ 5 const routes: RouteRecordRaw[] = [
6 // {
7 // path: '/data-asset/register-guide',
8 // component: Layout,
9 // meta: {
10 // title: '登记服务指南',
11 // icon: 'sidebar-videos',
12 // },
13 // children: [{
14 // path: '',
15 // name: 'registerGuide',
16 // component: () => import('@/views/data_asset/registerGuide.vue'),
17 // meta: {
18 // title: '登记服务指南',
19 // sidebar: false,
20 // breadcrumb: false,
21 // cache: true
22 // },
23 // }]
24 // },
25 { 6 {
26 path: '/data-asset/register-catalog', 7 path: '/data-asset/register-catalog',
27 component: Layout, 8 component: Layout,
......
...@@ -253,47 +253,5 @@ const routes: RouteRecordRaw[] = [ ...@@ -253,47 +253,5 @@ const routes: RouteRecordRaw[] = [
253 }, 253 },
254 ], 254 ],
255 }, 255 },
256 {
257 path: '/data-asset-register/register-progress',
258 component: Layout,
259 meta: {
260 title: '登记进度一览',
261 icon: 'ep:grid',
262 },
263 children: [
264 {
265 path: '',
266 name: 'registerProgress',
267 component: () => import('@/views/data_asset/registerProgress.vue'),
268 meta: {
269 title: '登记进度一览',
270 sidebar: false,
271 cache: true,
272 breadcrumb: false,
273 },
274 },
275 ]
276 },
277 {
278 path: '/data-asset-register/contract-progress',
279 component: Layout,
280 meta: {
281 title: '合同进度一览',
282 icon: 'ep:grid',
283 },
284 children: [
285 {
286 path: '',
287 name: 'contractProgress',
288 component: () => import('@/views/data_asset/contractProgress.vue'),
289 meta: {
290 title: '合同进度一览',
291 sidebar: false,
292 cache: true,
293 breadcrumb: false,
294 },
295 },
296 ]
297 }
298 ] 256 ]
299 export default routes 257 export default routes
......
1 import type { RouteRecordRaw } from 'vue-router'
2
3 function Layout() {
4 return import('@/layouts/index.vue')
5 }
6
7 const routes: RouteRecordRaw[] = [
8 {
9 path: '/data-service/api-management',
10 component: Layout,
11 meta: {
12 title: '管理API',
13 icon: 'sidebar-videos',
14 },
15 children: [
16 {
17 path: '',
18 name: 'apiManagement',
19 component: () => import('@/views/data_service/apiManagement.vue'),
20 meta: {
21 title: '管理API',
22 sidebar: false,
23 breadcrumb: false,
24 cache: true
25 }
26 },
27 {
28 path: 'api-create',
29 name: 'apiCreate',
30 component: () => import('@/views/data_service/apiCreate.vue'),
31 meta: {
32 title: '新建API',
33 sidebar: false,
34 breadcrumb: false,
35 cache: true,
36 reuse: true,
37 editPage: true
38 },
39 beforeEnter: (to, from) => {
40 if (to.query.type) {
41 to.meta.title = `新建(${to.query.type == '1' ? '单表API' : (to.query.type == '2' ? '自定义sql' : '注册API')})`;
42 to.meta.editPage = true;
43 } else if (to.query.detail) {
44 to.meta.title = `详情-${to.query.apiName}`;
45 to.meta.editPage = false;
46 } else if (to.query.guid) {
47 to.meta.title = `编辑-${to.query.apiName}`;
48 to.meta.editPage = true;
49 }
50 }
51 },
52 {
53 // path: 'processDetail',
54 // name: 'APIProcessDetail',
55 path: 'api-detail',
56 name: 'apiDetail',
57 component: () => import('@/views/data_service/detail_serviceApi.vue'),
58 meta: {
59 title: '流程详情',
60 sidebar: false,
61 breadcrumb: false,
62 cache: true,
63 reuse: true
64 }
65 },
66 {
67 path: 'processDetail',
68 name: 'APIProcessDetail',
69 component: () => import('@/views/detail.vue'),
70 meta: {
71 title: '流程详情',
72 sidebar: false,
73 breadcrumb: false,
74 cache: true,
75 reuse: true
76 }
77 },
78 ],
79 },
80 {
81 path: '/data-service/api-test',
82 component: Layout,
83 meta: {
84 title: '测试API',
85 icon: 'sidebar-videos',
86 },
87 children: [
88 {
89 path: '',
90 name: 'apiTest',
91 component: () => import('@/views/data_service/apiTest.vue'),
92 meta: {
93 title: '测试API',
94 sidebar: false,
95 breadcrumb: false,
96 cache: true
97 },
98 },
99 ],
100 },
101 ]
102
103 export default routes
...@@ -3,6 +3,7 @@ import generatedRoutes from 'virtual:generated-pages' ...@@ -3,6 +3,7 @@ import generatedRoutes from 'virtual:generated-pages'
3 import type { RouteRecordRaw } from 'vue-router' 3 import type { RouteRecordRaw } from 'vue-router'
4 import DataAssess from './modules/dataAsset'; 4 import DataAssess from './modules/dataAsset';
5 import DataAssetRegistry from './modules/dataAssetRegistry'; 5 import DataAssetRegistry from './modules/dataAssetRegistry';
6 import DataService from './modules/dataService';
6 7
7 import useSettingsStore from '@/store/modules/settings' 8 import useSettingsStore from '@/store/modules/settings'
8 9
...@@ -90,7 +91,8 @@ const systemRoutes: RouteRecordRaw[] = [ ...@@ -90,7 +91,8 @@ const systemRoutes: RouteRecordRaw[] = [
90 // 动态路由(异步路由、导航栏路由) 91 // 动态路由(异步路由、导航栏路由)
91 const asyncRoutes: RouteRecordRaw[] = [ 92 const asyncRoutes: RouteRecordRaw[] = [
92 ...DataAssess, 93 ...DataAssess,
93 ...DataAssetRegistry, 94 ...DataService,
95 // ...DataAssetRegistry,
94 ] 96 ]
95 97
96 const constantRoutesByFilesystem = generatedRoutes.filter((item) => { 98 const constantRoutesByFilesystem = generatedRoutes.filter((item) => {
......
...@@ -40,7 +40,7 @@ const globalSettings: Settings.all = { ...@@ -40,7 +40,7 @@ const globalSettings: Settings.all = {
40 }, 40 },
41 "home": { 41 "home": {
42 "enable": false, 42 "enable": false,
43 "title": "数据资产管理系统" 43 "title": "可信数据空间"
44 }, 44 },
45 "breadcrumb": { 45 "breadcrumb": {
46 "enable": true 46 "enable": true
......
1 const useDataAnonymizationStore = defineStore(
2 // 资产目录guid
3 'isRefresh',
4 () => {
5 const isRefresh = ref<boolean>(false);
6 function setIsRefresh(v: boolean) {
7 isRefresh.value = v;
8 }
9
10 const isAnonPageRefresh = ref<boolean>(false);
11 function setIsAnonPageRefresh(v: boolean) {
12 isAnonPageRefresh.value = v;
13 }
14
15 return {
16 isRefresh,
17 isAnonPageRefresh,
18 setIsRefresh,
19 setIsAnonPageRefresh,
20 };
21 }
22 );
23
24 export default useDataAnonymizationStore;
1 const useDataCatalogStore = defineStore(
2 // 主题域guid
3 'domainGuid',
4 () => {
5 const domainGuid = ref<string>("")
6
7 function set(guid: any) {
8 domainGuid.value = guid;
9 }
10
11 return {
12 domainGuid,
13 set
14 }
15 },
16 )
17
18 export default useDataCatalogStore
19
...\ No newline at end of file ...\ No newline at end of file
1 const useEntryStore = defineStore(
2 // api标签分类guid
3 'isRefresh',
4
5 () => {
6
7 const isRefresh = ref(false);
8 function setIsRefresh(update: boolean) {
9 isRefresh.value = update;
10 }
11
12 return {
13 isRefresh,
14 setIsRefresh,
15 }
16 },
17 )
18
19 export default useEntryStore
...\ No newline at end of file ...\ No newline at end of file
1 const useDataMetaStore = defineStore("dataMeta", () => {
2 const guid: Ref<string> = ref("")
3 const databaseName = ref("")
4 const tableName = ref("")
5 const databaseChName = ref("");
6 const databaseGuid = ref('');
7 const fieldGuid = ref("");
8 const fieldEnName = ref('');
9 const isFieldLineage = ref(false);
10 const set = (prop?: {
11 tableGuid: string;
12 table: string;
13 databas: string;
14 databaseCh: string;
15 dsGuid: string;
16 fGuid?: string;
17 fEnName?: string;
18 isFieldLine?: boolean;
19 }) => {
20 guid.value = prop?.tableGuid || "";
21 databaseName.value = prop?.databas || "";
22 tableName.value = prop?.table || "";
23 databaseChName.value = prop?.databaseCh || "";
24 databaseGuid.value = prop?.dsGuid || "";
25 fieldGuid.value = prop?.fGuid || "";
26 fieldEnName.value = prop?.fEnName || "";
27 isFieldLineage.value = prop?.isFieldLine ?? false;
28 }
29 return {
30 guid,
31 databaseName,
32 tableName,
33 databaseChName,
34 databaseGuid,
35 fieldGuid,
36 fieldEnName,
37 isFieldLineage,
38 set
39 }
40 })
41
42 export default useDataMetaStore
...\ No newline at end of file ...\ No newline at end of file
1 const useDataQualityStore = defineStore(
2 // 质检表分组guid
3 'modelGroupGuid',
4
5 () => {
6 const modelGroupGuid = ref<string>("")
7
8 function set(guid: any) {
9 modelGroupGuid.value = guid;
10 }
11
12 const modelGuid = ref<string>("")
13
14 function setModelGuid(guid: any) {
15 modelGuid.value = guid;
16 }
17
18 const planType = ref<number>(0);
19
20 function setPlanType(type: any) {
21 planType.value = type;
22 }
23
24 const defaultPlanType = ref<number>(1);
25
26 function setDefaultPlanType(type: any) {
27 defaultPlanType.value = type;
28 }
29
30 const isUpdate = ref(false);
31 function setIsUpdate(update: boolean) {
32 isUpdate.value = update;
33 }
34
35
36 return {
37 modelGroupGuid,
38 set,
39 setModelGuid,
40 modelGuid,
41 planType,
42 isUpdate,
43 setIsUpdate,
44 setPlanType,
45 setDefaultPlanType,
46 defaultPlanType
47 }
48 },
49 )
50
51 export default useDataQualityStore
...\ No newline at end of file ...\ No newline at end of file
1 const useDataAsyncStore = defineStore("asyncGuid",()=>{
2 const taskGuid = ref("")
3 const set = (guid:string)=>{
4 taskGuid.value = guid
5 }
6 return {
7 taskGuid,
8 set
9 }
10 })
11
12 export default useDataAsyncStore
...\ No newline at end of file ...\ No newline at end of file
1 const useDataStandardsStore = defineStore(
2 // 主题域guid
3 'domainGuid',
4 () => {
5 const isAdd = ref(false)
6 const standardSetGuid = ref("")
7 const guid = ref("")
8 function set(guid: any) {
9 isAdd.value = guid;
10 }
11 function setGuid(sGuid,stanGuid){
12 guid.value = sGuid
13 standardSetGuid.value = stanGuid
14 }
15 return {
16 isAdd,
17 set,
18 guid,
19 setGuid,
20 standardSetGuid,
21 }
22 },
23 )
24
25 export default useDataStandardsStore
...\ No newline at end of file ...\ No newline at end of file
...@@ -46,4 +46,4 @@ export const commonPageConfig = { ...@@ -46,4 +46,4 @@ export const commonPageConfig = {
46 } 46 }
47 47
48 /** 通用的系统guid */ 48 /** 通用的系统guid */
49 export const SystemGuid = '32774fcfdf5e43e8b866660374d8bced';
...\ No newline at end of file ...\ No newline at end of file
49 export const SystemGuid = '4149c763d70948b195eb3d4b997c1722';
...\ No newline at end of file ...\ No newline at end of file
......
1 <route lang="yaml"> 1 <route lang="yaml">
2 name: notFound 2 name: notFound
3 meta: 3 meta:
4 title: 数据资产管理 4 title: 可信数据空间
5 constant: true 5 constant: true
6 layout: false 6 layout: false
7 </route> 7 </route>
......
1 <route lang="yaml">
2 name: contractProgress
3 </route>
4
5 <script lang="ts" setup name="contractProgress">
6 import { ref } from 'vue';
7 import { TableColumnWidth, commonPageConfig } from '@/utils/enum';
8 import {
9 saveDamContract,
10 updateDamContract,
11 delDamContract,
12 getContractList,
13 getParamsList,
14 getTenantList
15 } from "@/api/modules/dataAsset";
16 import { Plus } from "@element-plus/icons-vue";
17 import TableTools from "@/components/Tools/table_tools.vue";
18 import { useValidator } from '@/hooks/useValidator';
19 import useUserStore from "@/store/modules/user";
20 import { cloneDeep } from 'lodash-es';
21 import { onUploadFileDownload } from '@/api/modules/common';
22
23 const { proxy } = getCurrentInstance() as any;
24 const userStore = useUserStore();
25 const userData = JSON.parse(userStore.userData)
26 const { required } = useValidator();
27 const contractTypes: any = ref([]);
28
29 /** 交易合同节点 */
30 const tradeContractNodesList: any = ref([]);
31
32 /** 资产合同节点 */
33 const registerContractNodesList: any = ref([]);
34
35 /** 甲方乙方的下拉会员列表 */
36 const partyAList: any = ref([]);
37
38 const searchItemList = ref([
39 {
40 type: "input",
41 label: "",
42 field: "contractName",
43 default: "",
44 maxlength: 50,
45 placeholder: "合同名称",
46 clearable: true,
47 },
48 {
49 label: "",
50 type: "select",
51 placeholder: "合同类型",
52 field: "contractTypeCode",
53 options: contractTypes.value,
54 default: '',
55 filterable: true,
56 clearable: true,
57 },
58 {
59 type: 'select',
60 label: '',
61 field: 'contractNodeCode',
62 default: '',
63 placeholder: '进展阶段',
64 options: [],
65 clearable: true
66 },
67 {
68 type: "date-range",
69 field: "dateRange",
70 default: null,
71 startPlaceholder: '签约开始日期',
72 endPlaceholder: '签约结束日期',
73 clearable: true,
74 required: true
75 }
76 ]);
77
78 const page = ref({
79 ...commonPageConfig,
80 contractName: '',
81 contractTypeCode: '',
82 contractNodeCode: '',
83 dateRange: []
84 });
85
86 const toSearch = (val: any, clear: boolean = false) => {
87 page.value.curr = 1;
88 if (clear) {
89 searchItemList.value.map((item) => (item.default = ""));
90 page.value.contractName = '';
91 page.value.contractTypeCode = "";
92 page.value.contractNodeCode = "";
93 page.value.dateRange = [];
94 searchItemList.value[2].options = [];
95 } else {
96 page.value.contractName = val.contractName;
97 page.value.contractTypeCode = val.contractTypeCode;
98 page.value.contractNodeCode = val.contractNodeCode;
99 page.value.dateRange = val.dateRange;
100 }
101 getTableData();
102 };
103
104 const tableTools = ref();
105
106 const handleSearchChange = (val, row, info) => {
107 if (row.field == 'contractTypeCode') {
108 tableTools.value.toolSearch.formInline.contractNodeCode = '';
109 searchItemList.value[2].options = val == '1' ? registerContractNodesList.value : (!val ? [] : tradeContractNodesList.value);
110 }
111 }
112
113 const getTableData = () => {
114 tableInfo.value.loading = true;
115 getContractList({
116 pageSize: page.value.limit,
117 pageIndex: page.value.curr,
118 contractName: page.value.contractName,
119 contractTypeCode: page.value.contractTypeCode,
120 contractNodeCode: page.value.contractNodeCode,
121 startDate: page.value.dateRange?.[0] || '',
122 endDate: page.value.dateRange?.[1] || '',
123 }).then((res: any) => {
124 tableInfo.value.loading = false
125 if (res.code == proxy.$passCode) {
126 const data = res.data || {}
127 tableInfo.value.data = data.records || [];
128 tableInfo.value.page.curr = data.pageIndex;
129 tableInfo.value.page.rows = data.totalRows || 0;
130 } else {
131 proxy.$ElMessage.error(res.msg);
132 }
133 })
134 }
135
136 const currTableData: any = ref({});
137
138 const tableInfo = ref({
139 id: 'contract-data-table',
140 rowKey: 'guid',
141 loading: false,
142 fields: [
143 { label: "合同名称", field: "contractName", width: 160, align: "left" },
144 { label: "合同类型", field: "contractTypeName", width: 110 },
145 { label: "甲方名称", field: "partyAName", width: 180 },
146 { label: "乙方名称", field: "partyBName", width: 180 },
147 { label: "签约日期", field: "signContractDate", width: 110 },
148 ],
149 childFields: [
150 { label: "进展节点", field: "contractNodeName", width: 140, align: "left" },
151 { label: "开始日期", field: "startDate", width: TableColumnWidth.DATE },
152 { label: "结束日期", field: "endDate", width: TableColumnWidth.DATE },
153 { label: "工作内容描述", field: "contentDescribe", width: 280 },
154 ],
155 data: [],
156 page: {
157 type: "normal",
158 rows: 0,
159 ...page.value,
160 }
161 });
162
163 const getNodeSteps = (scope) => {
164 let contractNodeCodes = scope.row.contractNodeCodes || [];
165 return {
166 list: contractNodeCodes.map((n, index) => {
167 return {
168 // tooltip: {
169 // placement: 'top',
170 // content: n.name,
171 // className: 'step_title_tooltip',
172 // effect: 'light',
173 // },
174 title: n.name,
175 value: index + 1
176 }
177 }),
178 step: !scope.row.contractNodes?.length ? null : (scope.row.contractNodes.length - 1)
179 }
180 }
181
182 const contractEditFormItems = ref([
183 {
184 label: "合同类型",
185 type: "select",
186 placeholder: "请选择",
187 field: "contractTypeCode",
188 options: contractTypes.value,
189 default: '',
190 filterable: true,
191 clearable: true,
192 required: true,
193 },
194 {
195 type: "input",
196 label: "合同名称",
197 field: "contractName",
198 default: "",
199 maxlength: 50,
200 placeholder: "请输入",
201 clearable: true,
202 required: true,
203 },
204 {
205 label: "甲方名称",
206 type: "select",
207 placeholder: "请选择",
208 field: "partyAGuid",
209 options: partyAList.value,
210 props: {
211 value: 'guid',
212 label: 'tenantName'
213 },
214 default: '',
215 filterable: true,
216 clearable: true,
217 required: true,
218 },
219 {
220 label: "乙方名称",
221 type: "select",
222 placeholder: "请选择",
223 field: "partyBGuid",
224 options: partyAList.value,
225 props: {
226 value: 'guid',
227 label: 'tenantName'
228 },
229 default: '',
230 filterable: true,
231 clearable: true,
232 required: true,
233 },
234 {
235 label: "跟进节点",
236 type: "select",
237 placeholder: "请选择",
238 field: "contractNodeCodes",
239 options: [],
240 multiple: true,
241 default: [],
242 filterable: true,
243 collapse: true,
244 tagsTooltip: true,
245 clearable: true,
246 required: true,
247 },
248 {
249 label: '签约日期',
250 type: 'date',
251 placeholder: '请输入',
252 field: 'signContractDate',
253 default: "",
254 unlink: true,
255 disabled: false,
256 clearable: true,
257 required: true
258 },
259 ]);
260
261 const contractEditFormRules = ref({
262 contractTypeCode: [required('请选择合同类型')],
263 contractName: [required('请填写合同名称')],
264 partyAGuid: [required('请选择甲方名称')],
265 partyBGuid: [required('请选择乙方名称')],
266 contractNodeCodes: [required('请选择跟进节点')],
267 signContractDate: [required('请选择签约日期')],
268 });
269
270
271 /** 新增分类的form */
272 const contractEditFormInfo = ref({
273 type: "form",
274 title: "",
275 col: "span",
276 formInfo: {
277 id: "add-class-form",
278 readonly: false,
279 items: contractEditFormItems.value,
280 rules: contractEditFormRules.value,
281 },
282 });
283
284 const drawerRef = ref();
285
286 /** 新增编辑分类。 */
287 const drawerInfo = ref({
288 visible: false,
289 direction: 'rtl',
290 size: 550,
291 header: {
292 title: '新增合同',
293 },
294 type: '',
295 container: {
296 contents: [contractEditFormInfo.value],
297 },
298 footer: {
299 visible: true,
300 btns: [
301 { type: 'default', label: '取消', value: 'cancel' },
302 { type: 'primary', label: '确定', value: 'save', loading: false },
303 ]
304 }
305 })
306
307 const validate = async () => {
308 if (!nodesInfo.value?.length) {
309 return true;
310 }
311 let taskIndex = 0;
312 for (const task of nodesInfo.value) {
313 let res = await depFormRef.value['ref-' + task.contractNodeCode]?.ruleFormRef?.validate((valid, errorItem) => {
314 if (!valid) {
315 var obj = Object.keys(errorItem);
316 depFormRef.value['ref-' + task.contractNodeCode]?.ruleFormRef?.scrollToField(obj[0]);
317 return false;
318 }
319 })
320 if (!res) {
321 return res;
322 }
323 taskIndex++;
324 }
325 return true;
326 }
327
328 const drawerBtnClick = async (btn, info) => {
329 if (btn.value == 'cancel') {
330 drawerInfo.value.visible = false;
331 } else {
332 if (info.partyAGuid == info.partyBGuid) {
333 proxy.$ElMessage.error(`甲方名称跟乙方名称不能选择同一个`);
334 drawerRef.value?.getDrawerConRef('drawerFormRef')?.ruleFormRef?.scrollToField('partyAGuid');
335 return;
336 }
337 let res = await validate();
338 if (!res) {
339 return
340 }
341 info.contractNodes = [];
342 let index = 0;
343 for (const n of nodesInfo.value) {
344 let formInline = depFormRef.value['ref-' + n.contractNodeCode].formInline;
345 if (index != 0) {
346 if (formInline.dateRange[0] < info.contractNodes[index - 1].endDate) {
347 proxy.$ElMessage.error(`【${n.contractNodeName}】的开始日期应大于等于上一个节点的结束日期`);
348 depFormRef.value['ref-' + n.contractNodeCode]?.ruleFormRef?.scrollToField('dateRange');
349 return;
350 }
351 }
352 info.contractNodes.push(Object.assign({}, formInline, {
353 contractNodeCode: n.contractNodeCode,
354 contractGuid: currTableData.value.guid,
355 contractTypeCode: info.contractTypeCode,
356 startDate: formInline.dateRange[0],
357 endDate: formInline.dateRange[1],
358 nodeAchievement: formInline.nodeAchievement?.map(n => {
359 return {
360 name: n.name,
361 url: n.url
362 }
363 }) || []
364 }))
365 index++;
366 }
367 drawerInfo.value.footer.btns[1].loading = true;
368 if (drawerInfo.value.type == 'add') {
369 saveDamContract(info).then((res: any) => {
370 drawerInfo.value.footer.btns[1].loading = false;
371 if (res.code == proxy.$passCode) {
372 page.value.curr = 1;
373 getTableData();
374 proxy.$ElMessage.success('新增合同成功');
375 drawerInfo.value.visible = false;
376 } else {
377 proxy.$ElMessage.error(res.msg);
378 }
379 })
380 } else {
381 const params = { ...info };
382 params.guid = currTableData.value.guid;
383 updateDamContract(params).then((res: any) => {
384 drawerInfo.value.footer.btns[1].loading = false;
385 if (res.code == proxy.$passCode) {
386 getTableData();
387 proxy.$ElMessage.success('修改合同成功');
388 drawerInfo.value.visible = false;
389 } else {
390 proxy.$ElMessage.error(res.msg);
391 }
392 })
393 }
394 }
395 }
396
397 const drawerSelectChange = (val, row, info) => {
398 if (row.field == 'contractTypeCode') {
399 contractEditFormItems.value.forEach(item => {
400 item.default = info[item.field];
401 if (item.field == 'contractNodeCodes') {
402 item.default = '';
403 nodesInfo.value = [];
404 item.options = val == '1' ? registerContractNodesList.value : (!val ? [] : tradeContractNodesList.value);
405 }
406 });
407 } else if (row.field == 'contractNodeCodes') {
408 info.contractNodeCodes = val?.sort((a, b) => parseInt(a) - parseInt(b));
409 let oldNodesInfo = nodesInfo.value;
410 let nodeInfo: any[] = [];
411 info.contractNodeCodes?.forEach(code => {
412 let node = oldNodesInfo.find(on => on.contractNodeCode == code);
413 if (node) {
414 let formInline = depFormRef.value['ref-' + node.contractNodeCode]?.formInline || {};
415 node.nodeFormItems.forEach(item => {
416 item.default = formInline[item.field];
417 })
418 nodeInfo.push(node);
419 } else {
420 if (oldNodesInfo.length > 0 && parseInt(code) < parseInt(oldNodesInfo[oldNodesInfo.length - 1].contractNodeCode)) {
421 nodeInfo.push({
422 contractNodeCode: code,
423 contractNodeName: registerContractNodesList.value.find(r => r.value == code)?.label || tradeContractNodesList.value.find(r => r.value == code)?.label,
424 nodeFormItems: cloneDeep(nodeFormItems.value),
425 nodeFormRules: nodeFormRules.value
426 });
427 }
428 }
429 }) || [];
430 nodesInfo.value = nodeInfo;
431 }
432 }
433
434 const contractNodeCodes = computed(() => {
435 return drawerRef.value?.getDrawerConRef('drawerFormRef')?.formInline?.contractNodeCodes;
436 })
437
438 const handleNodeFileView = (scope) => {
439 let file = scope.row?.nodeAchievement?.[0];
440 onUploadFileDownload(file);
441 }
442
443 const handleTableEdit = (scope) => {
444 drawerInfo.value.visible = true;
445 drawerInfo.value.type = 'edit';
446 drawerInfo.value.header.title = '编辑合同';
447 drawerInfo.value.footer.visible = true;
448 currTableData.value = scope.row;
449 contractEditFormItems.value.forEach(item => {
450 item.default = scope.row[item.field];
451 item.disabled = false;
452 if (item.field == 'contractNodeCodes') {
453 item.default = scope.row.contractNodeCodes?.map(c => c.code) || [];
454 item.options = scope.row.contractTypeCode == '1' ? registerContractNodesList.value : (!scope.row.contractTypeCode ? [] : tradeContractNodesList.value);
455 }
456 })
457 nodesInfo.value = scope.row.contractNodes?.map(node => {
458 let items = cloneDeep(nodeFormItems.value);
459 items.forEach(item => {
460 item.disabled = false;
461 item.default = node[item.field];
462 if (item.field == 'dateRange') {
463 item.default = [node.startDate, node.endDate];
464 }
465 })
466 return Object.assign({}, node, {
467 nodeFormItems: items,
468 nodeFormRules: nodeFormRules.value
469 })
470 }) || [];
471 }
472
473 const handleTableDel = (scope) => {
474 proxy.$openMessageBox("确定要删除该登记合同吗?", () => {
475 delDamContract([scope.row.guid]).then((res: any) => {
476 if (res.code == proxy.$passCode) {
477 page.value.curr = 1;
478 getTableData();
479 proxy.$ElMessage.success('删除登记合同成功');
480 } else {
481 proxy.$ElMessage.error(res.msg);
482 }
483 });
484 }, () => {
485 proxy.$ElMessage.info("已取消删除");
486 })
487 }
488
489 const handleTableView = (scope) => {
490 drawerInfo.value.visible = true;
491 drawerInfo.value.type = 'view';
492 drawerInfo.value.header.title = '查看合同';
493 currTableData.value = scope.row;
494 contractEditFormItems.value.forEach(item => {
495 item.default = scope.row[item.field];
496 item.disabled = true;
497 if (item.field == 'contractNodeCodes') {
498 item.default = scope.row.contractNodeCodes?.map(c => c.code) || [];
499 item.options = scope.row.contractTypeCode == '1' ? registerContractNodesList.value : (!scope.row.contractTypeCode ? [] : tradeContractNodesList.value);
500 }
501 })
502 nodesInfo.value = scope.row.contractNodes?.map(node => {
503 let items = cloneDeep(nodeFormItems.value);
504 items.forEach(item => {
505 item.default = node[item.field];
506 item.disabled = true;
507 if (item.field == 'dateRange') {
508 item.default = [node.startDate, node.endDate];
509 }
510 })
511 return Object.assign({}, node, {
512 nodeFormItems: items,
513 nodeFormRules: nodeFormRules.value
514 })
515 }) || [];
516 drawerInfo.value.footer.visible = false;
517 }
518
519 const handleCreate = () => {
520 drawerInfo.value.visible = true;
521 drawerInfo.value.type = 'add';
522 drawerInfo.value.header.title = '新增合同';
523 drawerInfo.value.footer.visible = true;
524 contractEditFormItems.value.forEach(item => {
525 item.default = '';
526 item.disabled = false;
527 if (item.field == 'partyBGuid') {
528 item.default = userData.tenantGuid;
529 }
530 })
531 }
532
533 const nodesInfo: any = ref([]);
534
535 const depFormRef = ref({});
536 const setDepItemRef = (el: any, index: string) => {
537 if (el) {
538 depFormRef.value['ref-' + index] = el;
539 }
540 }
541
542 const nodeFormItems = ref([{
543 label: "开始日期~结束日期",
544 type: "date-picker",
545 field: "dateRange",
546 default: [],
547 placeholder: "开始日期~结束日期",
548 clearable: true,
549 format: 'YYYY-MM-DD',
550 valueFormat: 'YYYY-MM-DD',
551 block: true,
552 required: true,
553 },
554 // {
555 // label: '开始日期',
556 // type: 'date',
557 // placeholder: '请选择',
558 // field: 'startDate',
559 // default: "",
560 // unlink: true,
561 // disabled: false,
562 // clearable: true,
563 // required: true
564 // }, {
565 // label: '结束日期',
566 // type: 'date',
567 // placeholder: '请选择',
568 // field: 'endDate',
569 // default: "",
570 // unlink: true,
571 // disabled: false,
572 // clearable: true,
573 // required: true
574 // },
575 {
576 label: '节点成果上传',
577 tip: '支持格式:xls .xlsx .doc .docx .rar .zip',
578 type: 'upload-file',
579 accept: '.xls, .xlsx, .doc, .docx, .rar, .zip',
580 required: true,
581 block: true,
582 visible: true,
583 default: [],
584 field: 'nodeAchievement',
585 limit: 1,
586 }, {
587 label: '工作内容描述',
588 type: 'textarea',
589 placeholder: '请输入',
590 field: 'contentDescribe',
591 default: '',
592 maxlength: 200,
593 block: true,
594 clearable: true,
595 },]);
596
597 const nodeFormRules = ref({
598 dateRange: [{
599 type: 'array', required: true, message: '请填写开始日期~结束日期', trigger: 'change',
600 }],
601 // startDate: [required('请填写开始日期')],
602 // endDate: [required('请填写结束日期')],
603 nodeAchievement: [{
604 validator: (rule: any, value: any, callback: any) => {
605 if (!value?.length) {
606 callback(new Error('请上传节点成果附件'))
607 } else {
608 callback();
609 }
610 }, trigger: 'change'
611 }],
612 });
613
614 const addNode = () => {
615 let len = nodesInfo.value.length;
616 let code = contractNodeCodes.value[len];
617 let nodeList = drawerRef.value?.getDrawerConRef('drawerFormRef')?.formInline?.contractTypeCode == '2' ? tradeContractNodesList.value : registerContractNodesList.value;
618 nodesInfo.value.push({
619 contractNodeCode: code,
620 contractNodeName: nodeList.find(r => r.value == code)?.label,
621 nodeFormItems: cloneDeep(nodeFormItems.value),
622 nodeFormRules: nodeFormRules.value
623 })
624 }
625
626 const handleDelNode = (index) => {
627 proxy.$openMessageBox("确定要删除该进展阶段节点信息录入吗?", () => {
628 nodesInfo.value.splice(index, 1);
629 }, () => {
630 proxy.$ElMessage.info("已取消删除");
631 })
632 }
633
634 onBeforeMount(() => {
635 getParamsList({
636 dictType: "资产合同类型"
637 }).then((res: any) => {
638 contractTypes.value = [];
639 if (res.code == proxy.$passCode) {
640 contractTypes.value = res.data || [];
641 searchItemList.value[1].options = contractTypes.value;
642 contractEditFormItems.value[0].options = contractTypes.value;
643 } else {
644 proxy.$ElMessage.error(res.msg);
645 }
646 })
647 getParamsList({
648 dictType: "交易合同节点"
649 }).then((res: any) => {
650 tradeContractNodesList.value = [];
651 if (res.code == proxy.$passCode) {
652 tradeContractNodesList.value = res.data || [];
653 } else {
654 proxy.$ElMessage.error(res.msg);
655 }
656 })
657 getParamsList({
658 dictType: "登记合同节点"
659 }).then((res: any) => {
660 registerContractNodesList.value = [];
661 if (res.code == proxy.$passCode) {
662 registerContractNodesList.value = res.data || [];
663 } else {
664 proxy.$ElMessage.error(res.msg);
665 }
666 })
667 getTenantList({
668 bizState: 'Y',
669 pageSize: -1
670 }).then((res: any) => {
671 partyAList.value = [];
672 if (res.code == proxy.$passCode) {
673 partyAList.value = res.data?.records || [];
674 contractEditFormItems.value[2].options = partyAList.value;
675 contractEditFormItems.value[3].options = partyAList.value;
676 } else {
677 proxy.$ElMessage.error(res.msg);
678 }
679 })
680 })
681
682 </script>
683
684 <template>
685 <div class="container_wrap">
686 <div class="table_tool_wrap">
687 <TableTools ref="tableTools" :searchItems="searchItemList" :searchId="'contract-data-search'" @search="toSearch"
688 :init="true" @select-change="handleSearchChange" />
689 </div>
690 <div class="tools_btns">
691 <el-button type="primary" @click="handleCreate">新增</el-button>
692 </div>
693 <div class="table_panel_wrap">
694 <el-table v-loading="tableInfo.loading" ref="tableRef" :data="tableInfo.data" :highlight-current-row="true" stripe
695 border height="100%" tooltip-effect="light" row-key="guid" class="expand-table"
696 :style="{ width: '100%', height: 'calc(100% - 8px)', margin: '8px 0px', display: 'inline-block', }">
697 <el-table-column type="expand">
698 <template #default="scope">
699 <el-table ref="fieldsTableRef" :data="scope.row.contractNodes" :highlight-current-row="true" stripe border
700 height="100%" tooltip-effect="light" :style="{
701 width: '100%',
702 'max-height': '100%',
703 display: 'inline-block',
704 }">
705 <el-table-column label="序号" type="index" width="56px" align="center" show-overflow-tooltip>
706 </el-table-column>
707 <el-table-column v-for="field in tableInfo.childFields" :prop="field.field" :label="field.label"
708 :width="field.width" :align="field.align" show-overflow-tooltip>
709 <template #default="scope">
710 <span>{{ scope.row[field.field || ''] || '--' }}</span>
711 </template>
712 </el-table-column>
713 <el-table-column label="附件信息" width="120px" align="left" fixed="right" show-overflow-tooltip>
714 <template #default="scope">
715 <span class="text_btn" @click="handleNodeFileView(scope)">查看</span>
716 </template>
717 </el-table-column>
718 </el-table>
719 </template>
720 </el-table-column>
721 <el-table-column label="序号" type="index" width="56px" align="center" show-overflow-tooltip>
722 </el-table-column>
723 <el-table-column v-for="field in tableInfo.fields" :prop="field.field" :label="field.label" :width="field.width"
724 :align="field.align" show-overflow-tooltip>
725 <template #default="scope">
726 <span>{{ scope.row[field.field || ''] || '--' }}</span>
727 </template>
728 </el-table-column>
729 <el-table-column label="进展阶段" width="450px" align="center">
730 <template #default="scope">
731 <div class="custom-steps" v-if="scope.row.contractNodeCodes?.length">
732 <StepBar :steps-info="getNodeSteps(scope)" />
733 </div>
734 <span v-else>--</span>
735 </template>
736 </el-table-column>
737 <el-table-column label="操作" width="100px" align="left" fixed="right" show-overflow-tooltip>
738 <template #default="scope">
739 <span v-if="!scope.row.createUserId || scope.row.createUserId == userData.userGuid" class="text_btn" @click="handleTableEdit(scope)">编辑</span>
740 <span v-if="!scope.row.createUserId || scope.row.createUserId == userData.userGuid" class="text_btn ml4" @click="handleTableDel(scope)">删除</span>
741 <span v-if="scope.row.createUserId && scope.row.createUserId != userData.userGuid" class="text_btn ml4" @click="handleTableView(scope)">查看</span>
742 </template>
743 </el-table-column>
744 </el-table>
745 </div>
746 <Drawer :drawerInfo="drawerInfo" @drawerBtnClick="drawerBtnClick" ref="drawerRef"
747 @drawerSelectChange='drawerSelectChange'>
748 <!-- 传递到 Form 组件中的默认插槽 -->
749 <template v-slot:default>
750 <template v-if="contractNodeCodes?.length > 0">
751 <div v-show="!(!nodesInfo?.length && drawerInfo.type == 'view')" class="title-label">进展阶段录入</div>
752 <!-- 渲染行 -->
753 <div v-for="(row, index) in nodesInfo" :key="index" class="match-content-wrapper">
754 <div class="title-row"><span class="title">{{ row.contractNodeName }}</span><span class="btns"
755 v-show="index == nodesInfo.length - 1" @click="handleDelNode(index)">删除</span></div>
756 <Form :ref="(el: any) => { setDepItemRef(el, row.contractNodeCode) }" :itemList="row.nodeFormItems"
757 :formId="'node-form' + index" :rules="row.nodeFormRules" col="col2" />
758 </div>
759 <!-- 新增按钮 -->
760 <div class="bottm_tools" v-show="nodesInfo.length < contractNodeCodes?.length && drawerInfo.type != 'view'" @click="addNode">
761 <el-icon>
762 <Plus />
763 </el-icon>
764 <span>新增进展</span>
765 </div>
766 </template>
767 </template>
768 </Drawer>
769 </div>
770 </template>
771
772 <style lang="scss" scoped>
773 .container_wrap {
774 padding: 0 16px;
775 }
776
777 .table_panel_wrap {
778 height: calc(100% - 94px);
779 }
780
781 .ml4 {
782 margin-left: 4px;
783 }
784
785 :deep(.custom-steps) {
786 width: 100%;
787 height: 64px;
788 display: flex;
789
790 .el-steps {
791 width: 100%;
792 }
793 }
794
795 .title-label {
796 margin-bottom: 4px;
797 font-size: 18px;
798 color: #212121;
799 }
800
801 .title-row {
802 height: 48px;
803 display: flex;
804 justify-content: space-between;
805 align-items: center;
806
807 .title {
808 color: #212121;
809 font-size: 16px;
810 font-weight: 600;
811 }
812
813 .btns {
814 cursor: pointer;
815 color: var(--el-color-primary);
816 font-size: 14px;
817 }
818 }
819
820 .bottm_tools {
821 width: 100%;
822 height: 40px;
823 display: flex;
824 justify-content: center;
825 align-items: center;
826 background: #fafafa;
827 color: #999;
828 font-size: 14px;
829 border: 1px dashed var(--el-border-color-regular);
830 margin-bottom: 12px;
831
832 >span {
833 margin-left: 8px;
834 }
835
836 &:hover {
837 background: #EBF6F7;
838 border: 1px dashed var(--el-color-primary);
839 }
840 }
841
842 :deep(.el-table.expand-table) {
843 .el-table__expanded-cell.el-table__cell {
844 background: #fff !important;
845 padding-left: 48px;
846 padding-right: 8px;
847 }
848 }
849
850 :deep(.el-steps) {
851 .el-step__head.is-finish .el-step__icon.is-icon {
852 background-color: transparent;
853 }
854 }
855 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <route lang="yaml">
2 name: apiCalls
3 </route>
4
5 <script lang="ts" setup name="apiCalls">
6 import { ref } from 'vue';
7 import { TableColumnWidth } from '@/utils/enum';
8 import { commonPageConfig } from '@/components/PageNav/index';
9 import TableTools from '@/components/Tools/table_tools.vue';
10 import { useRouter, useRoute } from "vue-router";
11 import {
12 getAppProductData,
13 deleteAppProduct
14 } from "@/api/modules/dataService";
15 import useDataServiceStore from "@/store/modules/dataService";
16
17 const { proxy } = getCurrentInstance() as any;
18 const router = useRouter();
19 const dataServiceStore = useDataServiceStore();
20
21 /** 分页及搜索传参信息配置。 */
22 const page = ref({
23 ...commonPageConfig,
24 productName: ''
25 });
26
27 const searchItemList = ref([
28 {
29 type: "input",
30 label: "",
31 field: "productName",
32 default: "",
33 placeholder: "应用名称",
34 clearable: true,
35 }
36 ]);
37
38 const tableInfo = ref({
39 id: 'data-app-table',
40 fields: [
41 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
42 { label: "应用名称", field: "productName", width: 140 },
43 { label: "appKey", field: "appKey", width: 140 },
44 { label: "appSecret", field: "appSecret", width: 120 },
45 {
46 label: "绑定API数", field: "apiBingingNum", width: 100, align: 'right', type: 'chnum'
47 },
48 {
49 label: "调用次数", field: "invokeNum", width: 100, align: 'right', type: 'chnum'
50 },
51 {
52 label: "调用异常数", field: "invokeErrorNum", width: 105, align: 'right', type: 'chnum'
53 },
54 { label: "应用负责人", field: "directorName", width: TableColumnWidth.USERNAME },
55 { label: "修改人", field: "updateUserName", width: TableColumnWidth.USERNAME },
56 { label: "修改时间", field: "updateTime", width: TableColumnWidth.DATETIME },
57 ],
58 data: [],
59 page: {
60 type: "normal",
61 rows: 0,
62 ...page.value,
63 },
64 actionInfo: {
65 label: "操作",
66 type: "btn",
67 width: 120,
68 fixed: 'right',
69 btns: (scope) => {
70 const row = scope.row
71 let btnsArr: any = [];
72 btnsArr.push({
73 label: "编辑", value: "edit", click: (scope) => {
74 router.push({
75 name: 'apiBind',
76 query: {
77 guid: scope.row.guid,
78 productName: scope.row.productName
79 }
80 });
81 }
82 });
83 btnsArr.push({
84 label: "删除", value: "delete", click: (scope) => {
85 if (scope.row.apiBingingNum > 0) {
86 proxy.$ElMessage.warning('该应用有绑定的API,无法删除');
87 return;
88 }
89 proxy.$openMessageBox('确定要删除该应用吗?', () => {
90 deleteAppProduct([scope.row.guid]).then((res: any) => {
91 if (res.code == proxy.$passCode) {
92 page.value.curr = 1;
93 getTableData();
94 proxy.$ElMessage.success("删除成功");
95 } else {
96 proxy.$ElMessage.error(res.msg);
97 }
98 });
99 }, () => {
100 proxy.$ElMessage.info("已取消");
101 })
102 }
103 });
104 return btnsArr
105 },
106 },
107 loading: false
108 })
109
110 const toSearch = (val: any, clear: boolean = false) => {
111 page.value.curr = 1;
112 if (clear) {
113 searchItemList.value.map((item) => (item.default = ""));
114 page.value.productName = '';
115 } else {
116 page.value.productName = val.productName;
117 }
118 getTableData();
119 };
120
121 const tablePageChange = (info) => {
122 page.value.curr = Number(info.curr);
123 page.value.limit = Number(info.limit);
124 getTableData();
125 };
126
127 const getTableDataPromise: any = ref(null);
128 const getTableData = () => {
129 tableInfo.value.loading = true
130 getTableDataPromise.value = getAppProductData({
131 pageIndex: page.value.curr,
132 pageSize: page.value.limit,
133 productName: page.value.productName
134 }).then((res: any) => {
135 getTableDataPromise.value = null;
136 if (res.code == proxy.$passCode) {
137 const data = res.data || {}
138 tableInfo.value.data = data.records || []
139 tableInfo.value.page.limit = data.pageSize
140 tableInfo.value.page.curr = data.pageIndex
141 tableInfo.value.page.rows = data.totalRows
142 } else {
143 proxy.$ElMessage({
144 type: 'error',
145 message: res.msg,
146 })
147 }
148 tableInfo.value.loading = false
149 })
150 };
151
152 const addAppProduct = () => {
153 router.push({
154 name: 'apiBind',
155 });
156 }
157
158 onBeforeMount(() => {
159 toSearch({})
160 })
161
162 onActivated(() => {
163 if (dataServiceStore.isUpdate) {
164 if (getTableDataPromise.value) {
165 getTableDataPromise.value.then(() => {
166 getTableData();
167 dataServiceStore.setIsUpdate(false);
168 });
169 } else {
170 getTableData();
171 dataServiceStore.setIsUpdate(false);
172 }
173 }
174 });
175
176 </script>
177
178 <template>
179 <div class="container_wrap">
180 <div class="table_tool_wrap">
181 <TableTools :searchItems="searchItemList" :searchId="'data-source-search'" @search="toSearch" :init="false" />
182 <div class="tools_btns">
183 <el-button type="primary" @click="addAppProduct" v-preReClick>添加</el-button>
184 </div>
185 </div>
186 <div class="table_panel_wrap">
187 <Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" />
188 </div>
189 </div>
190 </template>
191
192 <style lang="scss" scoped>
193 .table_tool_wrap {
194 width: 100%;
195 height: 84px !important;
196 padding: 0 8px;
197
198 .tools_btns {
199 padding: 0px 0 0;
200 }
201 }
202
203 .table_panel_wrap {
204 width: 100%;
205 height: calc(100% - 84px);
206 padding: 0px 8px 0;
207 }
208 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <route lang="yaml">
2 name: apiCreate
3 </route>
4
5 <script lang="ts" setup name="apiCreate">
6 import { ref } from 'vue';
7 import { useValidator } from '@/hooks/useValidator';
8 import { CirclePlus } from '@element-plus/icons-vue';
9 import { TableColumnWidth } from '@/utils/enum';
10 import { handleContentWrapView, scrollLastRowToView } from '@/utils/common';
11 import { enableRowDrop, destroySort } from '@/utils/sortable';
12 import {
13 apiTypes,
14 // getDataTypeList,
15 // getPositionList,
16 // getOperationList,
17 getSubjectTableTree,
18 getSubjectTableByDomain,
19 getSubjectTableDetail,
20 checkExistAPIName,
21 checkExistRequestPath,
22 addApi,
23 updateApi,
24 getApiDetail,
25 testEditApi,
26 validateApiSql,
27 getDomainName
28 } from "@/api/modules/dataService";
29 import {
30 getDataSource,
31 getSchemaTableList,
32 tableColumnList,
33 checkSql,
34 getParamsDictList,
35 } from "@/api/modules/queryService";
36 import { getCamundaDeploymentId, isNeedApprove } from "@/api/modules/workFlowService"
37 import useUserStore from "@/store/modules/user";
38 import useDataServiceStore from "@/store/modules/dataService";
39 import { useDefault } from "@/hooks/useDefault"
40
41 const route = useRoute();
42 const router = useRouter();
43 const { proxy } = getCurrentInstance() as any;
44 const { required, description, chOrEnPreffix, regexpValidate, checkExistName } = useValidator();
45 const { checkValidValue } = useDefault()
46 const userStore = useUserStore();
47 const userData = JSON.parse(userStore.userData)
48 const dataServiceStore = useDataServiceStore();
49 const scrollContainer = ref(null);
50 const flowExpand = ref(true);
51 const bizApproveVO = ref()
52 const deploymentId = ref('');
53 const fullPath = route.fullPath;
54 const apiType: any = ref(route.query.type);
55 // const sceneName = ref(route.query.tagName);
56 const apiGuid = ref(route.query.guid);
57 /** 是否是详情页面。 */
58 const isDetail = ref(route.query.isDetail);
59 /** 域名 */
60 const domainName = ref('');
61 /** 整个页面的加载状态,获取详情或提交时显示。 */
62 const fullscreenLoading = ref(false);
63 /** 编辑时的详情信息。 */
64 const detailInfo: any = ref({});
65 /** 默认显示步骤 */
66 const step = ref(0);
67 /** 步骤条配置信息 */
68 const stepsInfo = ref({
69 step: step.value,
70 list: [
71 { title: '填写API基本信息', value: 1 },
72 { title: '配置取数逻辑', value: 2 },
73 { title: '测试API', value: 3 },
74 ]
75 })
76
77 /** 验证表格入参是否符合条件 */
78 const validInputParams = (data, paramTypeName: string = "参数", isConst = false) => {
79 let paramNames: string[] = [];
80 let dataIndex = 1;
81 for (const d of data) {
82 if (!d.paramName) {
83 proxy.$ElMessage.error(`第 ${dataIndex}${paramTypeName}名称不能为空`);
84 return false;
85 }
86 // 确保第一个字符是字母
87 if (!/^[A-Za-z]/.test(d.paramName)) {
88 proxy.$ElMessage.error(`第 ${dataIndex}${paramTypeName}名称输入必须以字母开头`);
89 return false;
90 }
91 if (paramNames.some(p => p == d.paramName)) {
92 proxy.$ElMessage.error(`${paramTypeName}名称不能重复`);
93 return false;
94 }
95 if (!d.paramPosition) {
96 proxy.$ElMessage.error(`第 ${dataIndex}${paramTypeName}位置不能为空`);
97 return false;
98 }
99 if (!d.dataType) {
100 proxy.$ElMessage.error(`第 ${dataIndex}${paramTypeName}类型不能为空`);
101 return false;
102 }
103 if (checkValidValue[d.dataType]) {
104 let v = checkValidValue[d.dataType](d.defaultValue, d.isManyValue == 'Y');
105 if (v !== true) {
106 proxy.$ElMessage.error(`第 ${dataIndex}${paramTypeName}类型为${v},请输入合法的值`);
107 return false;
108 }
109 }
110 if (isConst && !d.defaultValue) {
111 proxy.$ElMessage.error(`第 ${dataIndex}${paramTypeName}的常量值不能为空`);
112 return;
113 }
114 // if (d.isRequired == 'Y' && !d.defaultValue) {
115 // proxy.$ElMessage.error(`第 ${dataIndex} 个参数为必填则默认值不能为空`);
116 // return;
117 // }
118 paramNames.push(d.paramName);
119 dataIndex++;
120 }
121 return true;
122 }
123
124 /** 步骤条的上一步,下一步。 */
125 const nextStep = (val) => {
126 if (val == 1) {
127 baseInfoFormRef.value?.ruleFormRef?.validate((valid, errorItem) => {
128 if (valid) {
129 // if (row.field == 'processOrderGuids') {//场景名称
130
131 // }
132 //验证入参定义表格输入, 入参参数名不能有重复的。
133 // if (!inputParamsData.value.length) { //请求参数都来自入参定义。
134 // proxy.$ElMessage.error('入参定义不能为空');
135 // return;
136 // }
137 if (!validInputParams(inputParamsData.value)) {
138 handleContentWrapView('inputParams');
139 return;
140 }
141 step.value = val;
142 stepsInfo.value.step = val;
143 /** 处理数据源表单下拉列表数据获取 */
144 if (apiType.value == '1') {
145 if (apiGuid.value && !targetDsFields.value.length) {
146 getTargetDatabaseList().then(() => {
147 if (detailInfo.value.dataSourceType == 1) {
148 getSchemaTableData(detailInfo.value.dataSourceGuid).then(() => {
149 getBingFieldList(1, detailInfo.value.dataSourceGuid, detailInfo.value.tableName, false);
150 });
151 } else {
152 currDsInfo.value.subjectDomainGuid = detailInfo.value.subjectDomainGuid;
153 currDsInfo.value.subjectDomainName = detailInfo.value.subjectDomainName;
154 currDsInfo.value.directoryGuid = detailInfo.value.directoryGuid;
155 getSubjectDomainData(detailInfo.value.subjectDomainGuid).then(() => {
156 getBingFieldList(2, detailInfo.value.dataSourceGuid, detailInfo.value.tableGuid, false);
157 });
158 }
159 });
160 } else {
161 getTargetDatabaseList();
162 }
163 getMatchTableList();
164 } else if (apiType.value == '2') {
165 getTargetDatabaseList();
166 }
167 } else {
168 var obj = Object.keys(errorItem);
169 baseInfoFormRef.value.ruleFormRef.scrollToField(obj[0])
170 }
171 if (scrollContainer.value) {
172 scrollContainer.value.scrollTo({
173 top: 0,
174 behavior: 'smooth' // 平滑滚动
175 });
176 }
177 });
178
179 } else if (val == 2) {
180 if (apiType.value != '3') {
181 //先验证再下一步。
182 tableInfoFormRef.value?.ruleFormRef?.validate((valid, errorItem) => {
183 if (valid) {
184 if (apiType.value == '1') {
185 /** 请求参数可以不填写,TODO,滚动到可见范围内 */
186 let requestParamsData: any = requestParamsTableInfo.value.data;
187 let dataIndex = 1;
188 for (const d of requestParamsData) {
189 if (!d.paramName) {
190 handleContentWrapView('requestParams');
191 proxy.$ElMessage.error(`第 ${dataIndex} 个请求参数的参数名称不能为空`);
192 return;
193 }
194 if (!d.boundField) {
195 handleContentWrapView('requestParams');
196 proxy.$ElMessage.error(`第 ${dataIndex} 个请求参数的绑定字段不能为空`);
197 return;
198 }
199 if (!d.operator) {
200 handleContentWrapView('requestParams');
201 proxy.$ElMessage.error(`第 ${dataIndex} 个请求参数的操作符不能为空`);
202 return;
203 }
204 if (d.operator == '2' || d.operator == '11') {
205 let inputParam = inputParamsData.value.find(param => param.paramName == d.paramName);
206 if (inputParam && inputParam.isRequired != 'Y') {
207 handleContentWrapView('requestParams');
208 proxy.$ElMessage.error(`参数名称:${d.paramName}需必填,请返回上一步修改`);
209 return;
210 }
211 }
212 dataIndex++;
213 }
214 let responseParamsData: any[] = responseParamsTableInfo.value.data;
215 if (!responseParamsData.length) {
216 handleContentWrapView('responseParams');
217 proxy.$ElMessage.error(`返回参数不能为空`);
218 return;
219 }
220 dataIndex = 1;
221 let resParamNames: string[] = [];
222 for (const d of responseParamsData) {
223 if (!d.paramName) {
224 handleContentWrapView('responseParams');
225 proxy.$ElMessage.error(`第 ${dataIndex} 个返回参数的参数名不能为空`);
226 return;
227 }
228 if (resParamNames.some(p => p == d.paramName)) {
229 handleContentWrapView('responseParams');
230 proxy.$ElMessage.error(`返回参数的参数名称不能重复`);
231 return;
232 }
233 if (!d.boundField) {
234 handleContentWrapView('responseParams');
235 proxy.$ElMessage.error(`第 ${dataIndex} 个返回参数的绑定字段不能为空`);
236 return;
237 }
238 if (!d.dataType) {
239 handleContentWrapView('responseParams');
240 proxy.$ElMessage.error(`第 ${dataIndex} 个返回参数的参数类型不能为空`);
241 return;
242 }
243 resParamNames.push(d.paramName);
244 dataIndex++;
245 }
246 let sortParamsData: any[] = sortParamsTableInfo.value.data;
247 dataIndex = 1;
248 let sortParamNames: string[] = [];
249 let boundFields: string[] = [];
250 for (const d of sortParamsData) {
251 if (!d.paramName) {
252 handleContentWrapView('sortParams');
253 proxy.$ElMessage.error(`第 ${dataIndex} 个排序参数的参数名不能为空`);
254 return;
255 }
256 if (sortParamNames.some(p => p == d.paramName)) {
257 handleContentWrapView('sortParams');
258 proxy.$ElMessage.error(`排序参数的参数名称不能重复`);
259 return;
260 }
261 if (!d.boundField) {
262 handleContentWrapView('sortParams');
263 proxy.$ElMessage.error(`第 ${dataIndex} 个排序参数的绑定字段不能为空`);
264 return;
265 }
266 if (boundFields.some(b => b == d.boundField)) {
267 handleContentWrapView('sortParams');
268 proxy.$ElMessage.error(`排序参数的绑定字段不能重复`);
269 return;
270 }
271 if (!d.sortMode) {
272 handleContentWrapView('sortParams');
273 proxy.$ElMessage.error(`第 ${dataIndex} 个排序参数的排序方式不能为空`);
274 return;
275 }
276 sortParamNames.push(d.paramName);
277 boundFields.push(d.boundField);
278 dataIndex++;
279 }
280 /** query参数数据来自于请求参数以及入参定义的结合 */
281 let queryParamData: any[] = queryParamsTableInfo.value.data;
282 queryParamsTableInfo.value.data = requestParamsData.map(r => {
283 let inputParam = inputParamsData.value.find(i => r.paramName == i.paramName);
284 let introductionValue = queryParamData.find((q: any) => q.paramName == r.paramName)?.introductionValue;
285 return { ...r, ...inputParam, introductionValue: introductionValue != null ? introductionValue : inputParam.defaultValue };
286 });
287 } else if (apiType.value == '2') {
288 if (!sqlIsChecked.value) {
289 proxy.$ElMessage.error(`请先验证通过Sql`);
290 return;
291 }
292 /** query参数数据来自于请求参数 */
293 let queryParamData: any[] = queryParamsTableInfo.value.data;
294 queryParamsTableInfo.value.data = inputParamsData.value.map(r => {
295 let introductionValue = queryParamData.find((q: any) => q.paramName == r.paramName)?.introductionValue;
296 return { ...r, introductionValue: introductionValue != null ? introductionValue : r.defaultValue };
297 });
298 }
299 apiFormItems.value.forEach(item => {
300 item.default = baseInfoFormRef.value.formInline[item.field];
301 if (item.field == 'requestMode') {
302 item.default = item.default == 'G' ? 'get' : 'post';
303 } else if (item.field == 'requestPath') {
304 item.default = `https${domainName.value}${item.default}`
305 }
306 })
307 if (baseInfoFormRef.value.formInline.authenticationType == 'N') {
308 defaultParamsTableInfo.value.data = defaultParamsData.value.concat([{
309 paramName: 'appKey',
310 dataType: '字符型',
311 isRequired: '是',
312 value: ''
313 }]);
314 } else {
315 defaultParamsTableInfo.value.data = defaultParamsData.value;
316 }
317 step.value = val;
318 stepsInfo.value.step = val;
319 /** 每次到这一步都清除请求结果。 */
320 // resultFormItems.value[0].default = '';
321 // resultFormItems.value[1].default = '';
322 } else {
323 //将表单滚动到可见范围内。
324 var obj = Object.keys(errorItem);
325 tableInfoFormRef.value.ruleFormRef.scrollToField(obj[0])
326 }
327 });
328 } else {
329 backApiInfoFormRef.value?.ruleFormRef?.validate((valid, errorItem) => {
330 if (valid) {
331 if (!validInputParams(registRequestParamsTableInfo.value.data, '请求参数')) {
332 handleContentWrapView('registRequestParams');
333 return;
334 }
335 if (!validInputParams(constParamsTableInfo.value.data, '常量参数', true)) {
336 handleContentWrapView('constParams');
337 return;
338 }
339 /** query参数数据来自于请求参数 */
340 let queryParamData: any[] = queryParamsTableInfo.value.data;
341 queryParamsTableInfo.value.data = registRequestParamsTableInfo.value.data.map((r: any) => {
342 let introductionValue = queryParamData.find((q: any) => q.paramName == r.paramName)?.introductionValue;
343 return { ...r, introductionValue: introductionValue != null ? introductionValue : r.defaultValue };
344 });
345 constParamsTableInfo.value.data.map((r: any) => {
346 let introductionValue = queryParamData.find((q: any) => q.paramName == r.paramName)?.introductionValue;
347 queryParamsTableInfo.value.data.push({ ...r, introductionValue: introductionValue != null ? introductionValue : r.defaultValue, isConst: true });
348 });
349 apiFormItems.value.forEach(item => {
350 item.default = baseInfoFormRef.value.formInline[item.field];
351 if (item.field == 'requestMode') {
352 item.default = item.default == 'G' ? 'get' : 'post';
353 } else if (item.field == 'requestPath') {
354 item.default = `https${domainName.value}${item.default}`
355 }
356 })
357 if (baseInfoFormRef.value.formInline.authenticationType == 'N') {
358 defaultParamsTableInfo.value.data = defaultParamsData.value.concat([{
359 paramName: 'appKey',
360 dataType: '字符型',
361 isRequired: '是',
362 value: ''
363 }]);
364 } else {
365 defaultParamsTableInfo.value.data = defaultParamsData.value;
366 }
367 step.value = val;
368 stepsInfo.value.step = val;
369 /** 每次到这一步都清除请求结果。 */
370 // resultFormItems.value[0].default = '';
371 // resultFormItems.value[1].default = '';
372 } else {
373 var obj = Object.keys(errorItem);
374 backApiInfoFormRef.value.ruleFormRef.scrollToField(obj[0])
375 }
376 })
377 }
378 if (scrollContainer.value) {
379 scrollContainer.value.scrollTo({
380 top: 0,
381 behavior: 'smooth' // 平滑滚动
382 });
383 }
384 }
385 };
386
387 const previousStep = (val) => {
388 step.value = val - 1;
389 stepsInfo.value.step = val - 1;
390 if (scrollContainer.value) {
391 scrollContainer.value.scrollTo({
392 top: 0,
393 behavior: 'smooth' // 平滑滚动
394 });
395 }
396 }
397
398 /** ---------------------------- 获取参数字典 -------------------------- */
399 const dataTypeList: any = ref([]);
400
401 /** 获取参数类型下拉选项 */
402 const getParamDataTypeList = () => {
403 getParamsDictList('字段类型').then((res: any) => {
404 dataTypeList.value = [];
405 if (res.code == proxy.$passCode) {
406 dataTypeList.value = res.data || [];
407 inputParamsTableInfo.value.editInfo.dataType.options = dataTypeList.value;
408 responseParamsTableInfo.value.editInfo.dataType.options = dataTypeList.value;
409 registRequestParamsTableInfo.value.editInfo.dataType.options = dataTypeList.value;
410 constParamsTableInfo.value.editInfo.dataType.options = dataTypeList.value;
411 } else {
412 proxy.$ElMessage.error(res.msg);
413 }
414 })
415 }
416
417 const paramPositionList: any = ref([]);
418
419 /** 获取参数类型下拉选项 */
420 const getParamPositionList = () => {
421 getParamsDictList('API参数位置').then((res: any) => {
422 paramPositionList.value = [];
423 if (res.code == proxy.$passCode) {
424 paramPositionList.value = res.data || [];
425 inputParamsTableInfo.value.editInfo.paramPosition.options = paramPositionList.value;
426 registRequestParamsTableInfo.value.editInfo.paramPosition.options = paramPositionList.value;
427 constParamsTableInfo.value.editInfo.paramPosition.options = paramPositionList.value;
428 } else {
429 proxy.$ElMessage.error(res.msg);
430 }
431 })
432 }
433
434 const paramOperatorList: any = ref([])
435
436 /** 获取参数操作符下拉选项 */
437 const getParamOperatorList = () => {
438 getParamsDictList('参数操作符').then((res: any) => {
439 paramOperatorList.value = [];
440 if (res.code == proxy.$passCode) {
441 paramOperatorList.value = res.data || [];
442 requestParamsTableInfo.value.editInfo.operator.options = paramOperatorList.value;
443 } else {
444 proxy.$ElMessage.error(res.msg);
445 }
446 })
447 }
448
449 const sceneList: any = ref([]);//场景列表
450 /** 获取参数类型下拉选项 */
451 // const getParamSceneList = () => {
452 // let query={
453 // pageIndex: 1,
454 // pageSize: -1,
455 // tenantGuid: userData.tenantGuid
456 // }
457 // getSceneList(query).then((res: any) => {
458 // sceneList.value = [];
459 // if (res.code == proxy.$passCode) {
460 // sceneList.value = res.data.records || [];
461 // baseFormItems.value[3].options = sceneList.value
462 // } else {
463 // proxy.$ElMessage.error(res.msg);
464 // }
465 // })
466 // }
467 // const processSheetList: any = ref([]);//场景列表
468 // /** 获取参数类型下拉选项 */
469 // const getParamProcessSheetList = () => {
470
471 // getProcessSheetListByUser(userData.staffGuid).then((res: any) => {
472 // processSheetList.value = [];
473 // if (res.code == proxy.$passCode) {
474 // processSheetList.value = res.data || [];
475 // baseFormItems.value[5].options = processSheetList.value
476 // } else {
477 // proxy.$ElMessage.error(res.msg);
478 // }
479 // })
480 // }
481
482 /** ----------------------------第一步填写基本信息 -------------------------- */
483 /** 基本信息表单组件引用 */
484 const baseInfoFormRef = ref();
485
486 /** 基本信息表单配置。 */
487 const baseFormItems = ref([{
488 label: 'API名称',
489 type: 'input',
490 placeholder: '只能以中文或英文开头',
491 field: 'apiName',
492 maxlength: 50,
493 regexp: /[^a-zA-Z0-9_\u4e00-\u9fa5-]/g,
494 default: '',
495 required: true
496 }, {
497 label: '返回类型',
498 type: 'select',
499 options: [{
500 label: 'json',
501 value: 'json'
502 }, {
503 label: 'xml',
504 value: 'xml'
505 }],
506 placeholder: '请选择',
507 field: 'responseType',
508 default: 'json',
509 clearable: true,
510 filterable: true,
511 required: true
512 }, {
513 label: 'API类型',
514 type: 'select',
515 options: apiTypes,
516 placeholder: '请选择',
517 field: 'apiType',
518 default: parseInt(apiType.value),
519 disabled: true,
520 required: true
521 },
522 // {
523 // label: '场景名称',
524 // type: 'select',
525 // options: sceneList.value,
526 // placeholder: '请选择',
527 // field: 'sceneGuid',
528 // default: '',
529 // props: {
530 // value: 'guid',
531 // label: 'sceneName'
532 // },
533 // required: true,
534 // visible: false
535 // },
536 {
537 type: "select-group",
538 field: "httpInfo",
539 col: ' select-input-long',
540 children: [
541 {
542 label: "请求路径",
543 type: "input",
544 placeholder: "请选择",
545 default: "https",
546 field: "httpType",
547 required: true,
548 disabled: true,
549 visible: true,
550 },
551 {
552 label: " ",
553 type: "input",
554 placeholder: "请输入",
555 default: '/',
556 field: "requestPath",
557 maxlength: 50,
558 required: true,
559 visible: true,
560 },
561 ],
562 visible: true
563 },
564 // {
565 // label: '场景名称',
566 // type: 'input',
567 // placeholder: '请选择',
568 // field: 'sceneName',
569 // default: '',
570 // disabled: true,
571 // },
572 // {
573 // label: '加工单号',
574 // type: 'select',
575 // options: processSheetList.value,
576 // placeholder: '请选择',
577 // field: 'processOrderGuids',
578 // default: '',
579 // props: {
580 // value: 'guid',
581 // label: 'requirementOrderName'
582 // },
583 // required: true,
584 // filterable: true,
585 // clearable: true,
586 // // multiple: true,
587 // // tagsTooltip: true,
588 // // collapse: true,
589 // // maxTags: 1,
590 // },
591 // {
592 // label: '加工单号',
593 // type: 'input',
594 // placeholder: '请选择',
595 // field: 'processOrderNo',
596 // default: null,
597 // visible: false
598 // },
599 {
600 label: '请求方式',
601 type: 'select',
602 options: [{
603 value: 'P',
604 label: 'post'
605 }, {
606 value: 'G',
607 label: 'get'
608 }],
609 placeholder: '请选择',
610 field: 'requestMode',
611 default: 'P',
612 clearable: true,
613 filterable: true,
614 // disabled: true,
615 required: true
616 }, {
617 label: '安全认证',
618 type: 'select',
619 options: [{
620 value: 'T',
621 label: 'TOKEN认证'
622 },
623 // {
624 // value: 'N',
625 // label: '无认证'
626 // }
627 ],
628 placeholder: '请选择',
629 field: 'authenticationType',
630 default: 'T',
631 clearable: true,
632 filterable: true,
633 disabled: true,
634 required: true
635 },
636 // {
637 // label: "IP白名单",
638 // type: "select",
639 // placeholder: "请选择",
640 // default: [],
641 // field: "whiteIPs", //只有无安全认证时显示。
642 // options: whiteIPsList.value,
643 // props: {
644 // value: 'guid',
645 // label: 'ip'
646 // },
647 // filterable: true,
648 // clearable: true,
649 // multiple: true,
650 // tagsTooltip: true,
651 // collapse: true,
652 // maxTags: 1,
653 // required: true,
654 // visible: false,
655 // },
656 {
657 label: 'API描述',
658 type: 'textarea',
659 placeholder: '请输入',
660 field: 'apiDescription',
661 default: '',
662 maxlength: 200,
663 block: true,
664 clearable: true,
665 required: true,
666 },
667 // {
668 // label: "加工单对象",
669 // type: "select",
670 // placeholder: "请选择",
671 // default: [],
672 // field: "processDTOS",
673 // options: whiteIPsList.value,
674 // props: {
675 // value: 'guid',
676 // label: 'ip'
677 // },
678 // filterable: true,
679 // clearable: true,
680 // multiple: true,
681 // tagsTooltip: true,
682 // collapse: true,
683 // maxTags: 1,
684 // required: true,
685 // visible: false,
686 // },
687 ])
688
689 /** 记录已检验过的APIName */
690 const checkedInfo = ref({});
691
692 /** 记录已检验过的API路径 */
693 const checkedPathInfo = ref({});
694
695 /** 基本信息表单配置规则。 */
696 const baseFormRules = ref({
697 apiName: [required("请填写API名称"), chOrEnPreffix(), checkExistName(checkedInfo.value, checkExistAPIName, detailInfo.value, 'apiName')],
698 responseType: [required("请选择返回类型")],
699 // sceneGuid: [required("请选择场景名称")],
700 // processOrderGuids: [required("请选择加工单号")],
701 /** 此处请求路径后端说只能输入一级。 */
702 requestPath: [required("请填写请求路径"), regexpValidate(/^\/[^\/][\w\u4e00-\u9fa5_-]*$/, '请填写合法的请求路径'), checkExistName(checkedPathInfo.value, checkExistRequestPath, detailInfo.value, 'requestPath', '该请求路径已存在,请填写其他路径')],
703 requestMode: [required("请选择请求方式")],
704 authenticationType: [required("请选择安全认证")],
705 apiDescription: [required('请填写API描述'), description(200)],
706 // whiteIPs: [required('请选择IP白名单')],
707 });
708
709 const inputParamsTableRef = ref();
710 const inputParamsData: any = ref([]);
711
712 /** 基本信息的入参定义表格配置 */
713 const inputParamsTableInfo = ref({
714 id: "input-params-table",
715 height: '214px',
716 fields: [
717 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
718 { label: "参数名", field: "paramName", width: 140, required: true, columClass: 'edit-colum', type: 'edit' },
719 { label: "参数位置", field: "paramPosition", width: 120, required: true, columClass: 'edit-colum', type: 'edit' },
720 { label: "参数类型", field: "dataType", width: 120, required: true, columClass: 'edit-colum', type: 'edit', impactValue: "defaultValue" },
721 { label: "是否必填", field: "isRequired", width: 100, required: true, columClass: 'edit-colum', type: 'edit' },
722 { label: "是否多值", field: "isManyValue", width: 100, required: true, columClass: 'edit-colum', type: 'edit' },
723 { label: "默认值", field: "defaultValue", width: 160, columClass: 'edit-colum', type: 'edit', dataTypeName: 'dataType' },
724 { label: "描述", field: "description", width: 160, columClass: 'edit-colum', type: 'edit' },
725 ],
726 editInfo: {
727 paramName: {
728 needCacheOldValue: true,
729 label: '',
730 type: 'input',
731 field: 'paramName',
732 default: '',
733 maxlength: 50,
734 regexp: /[^A-Za-z0-9_]/g,
735 placeholder: '请输入',
736 clearable: true,
737 },
738 paramPosition: {
739 label: '',
740 type: 'select',
741 field: 'paramPosition',
742 default: '',
743 options: paramPositionList.value,
744 props: {
745 label: 'label',
746 value: 'value'
747 },
748 placeholder: '请选择',
749 clearable: true,
750 filterable: true
751 },
752 dataType: {
753 label: '',
754 type: 'select',
755 field: 'dataType',
756 default: '',
757 options: dataTypeList.value,
758 props: {
759 label: 'label',
760 value: 'value'
761 },
762 placeholder: '请选择',
763 clearable: true,
764 filterable: true
765 },
766 isRequired: {
767 label: '',
768 type: 'select',
769 field: 'isRequired',
770 default: 'N',
771 options: [
772 {
773 label: "是",
774 value: "Y",
775 },
776 {
777 label: "否",
778 value: "N",
779 },
780 ],
781 placeholder: '请选择',
782 },
783 isManyValue: {
784 label: '',
785 type: 'select',
786 field: 'isManyValue',
787 default: 'N',
788 options: [
789 {
790 label: "是",
791 value: "Y",
792 },
793 {
794 label: "否",
795 value: "N",
796 },
797 ],
798 placeholder: '请选择',
799 },
800 defaultValue: {
801 label: '',
802 type: 'input',
803 field: 'defaultValue',
804 default: '',
805 maxlength: 100,
806 placeholder: '请输入',
807 clearable: true,
808 },
809 description: {
810 label: '',
811 type: 'input',
812 field: 'description',
813 default: '',
814 maxlength: 100,
815 placeholder: '请输入',
816 clearable: true,
817 }
818 },
819 STATUS: 'edit',
820 data: inputParamsData.value,
821 showPage: false,
822 actionInfo: {
823 show: true,
824 label: "操作",
825 type: "btn",
826 width: 60,
827 fixed: 'right',
828 btns: [
829 {
830 label: "删除", value: "remove", click: (scope) => {
831 //点击上一步,删除入参定义时,需要判断下一步的参数有没有引用,若引用了,需要同步删除的。
832 let requestParamsData = requestParamsTableInfo.value.data || [];
833 let rIndex = requestParamsData.findIndex((r: any) => r.paramName == scope.row.paramName);
834 let index = scope.$index;
835 if (rIndex > -1) {
836 proxy.$openMessageBox("该参数被请求参数引用,确定同步删除吗?", () => {
837 inputParamsData.value.splice(index, 1);
838 inputParamsTableInfo.value.data = inputParamsData.value;
839 requestParamsTableInfo.value.data.splice(rIndex, 1);
840 proxy.$ElMessage.success('参数删除成功');
841 }, () => {
842 proxy.$ElMessage.info("已取消");
843 });
844 } else {
845 inputParamsData.value.splice(index, 1);
846 inputParamsTableInfo.value.data = inputParamsData.value;
847 }
848 }
849 },
850 ]
851 },
852 loading: false
853 });
854
855 /** 给表格添加一行入参定义。 */
856 const addInputParams = () => {
857 inputParamsData.value.push({ paramName: '', isRequired: 'N', isManyValue: 'N', paramPosition: 'B', dataType: 'varchar', defaultValue: '', description: '' });
858 inputParamsTableInfo.value.data = inputParamsData.value;
859 nextTick(() => {
860 scrollLastRowToView(inputParamsTableRef.value?.tableRef, inputParamsData.value.length);
861 })
862 }
863
864 const inputParamsTableInputChange = (val, scope, item) => {
865 if (item.field == 'paramName') {
866 let oldV = scope.row[`old-${item.field}`];
867 if (oldV != val) {
868 let param: any = requestParamsTableInfo.value.data.find((r: any) => r.paramName == oldV);
869 param && (param.paramName = val);
870 }
871 }
872 }
873
874 /** 记录当前输入的白名单值,用于切换隐藏后再显示时显示之前的输入值 */
875 const whiteIPsValue = ref([]);
876 const processDTOSValue = ref([]);
877
878 const handleBaseInfoSelectChange = (val, row, info) => {
879 // if (row.field == 'authenticationType') {
880 // baseFormItems.value.forEach(item => {
881 // item.default = info[item.field];
882 // if (item.field == 'httpInfo') {
883 // item.children && (item.children[1].default = info['requestPath']);
884 // }
885 // // if (item.field == 'whiteIPs') {
886 // // item.visible = info.authenticationType == 'N';
887 // // if (item.visible) {
888 // // item.default = whiteIPsValue.value || [];
889 // // }
890 // // }
891 // });
892 // whiteIPsValue.value = info.whiteIPs;
893 // }
894 // if (row.field == 'processOrderGuids'){
895 // // if(val&&val.length>0){
896 // // let obj=processSheetList.value.filter(item => val.includes(item.guid))||[]
897 // // let processDTOS=obj.map(item=>({
898 // // processOrderNo:item.processOrderNo,
899 // // guid:item.guid,
900 // // requirementOrderName:item.requirementOrderName,
901 // // }))
902 // // if(processDTOS?.length>0){
903 // // processDTOS.forEach(obj=>{
904 // // obj.noName=obj.processOrderNo + '' + obj.requirementOrderName
905 // // })
906 // // }
907 // // processDTOSValue.value = processDTOS || [];
908
909 // // }
910 // if(val){
911 // let obj=processSheetList.value.filter(item => val==item.guid)||[]
912 // let processDTOS=obj.map(item=>({
913 // processOrderNo:item.processOrderNo,
914 // guid:item.guid,
915 // requirementOrderName:item.requirementOrderName,
916 // }))
917 // if(processDTOS?.length>0){
918 // processDTOS.forEach(obj=>{
919 // obj.noName=obj.processOrderNo + '' + obj.requirementOrderName
920 // })
921 // }
922 // processDTOSValue.value = processDTOS || [];
923
924 // }
925 // }
926 // console.log('ooo',baseInfoFormRef?.value.formInline);
927
928 // if (row.field == 'sceneGuid') {//场景名称
929 // let obj=sceneList.value.filter(item => item.guid == val)||[]
930 // console.log('obj',sceneList.value,obj,val);
931
932 // baseFormItems.value.forEach(item => {
933 // item.default = info[item.field];
934 // if (item.field == 'sceneName') {
935 // item.default = obj[0].sceneName||''
936 // }
937 // });
938 // }
939
940 }
941
942 /** ----------------------------第二步配置取数逻辑(单表API类型) -------------------------- */
943
944 /** 数据源列表 */
945 const databaseList: any = ref([]);
946 /** 选择的数据源对应的表列表 */
947 const dsTableList: any = ref([]);
948 /** 获取数据源列表 */
949 const getTargetDatabaseList = () => {
950 return getDataSource({ connectStatus: 1, }).then((res: any) => {
951 if (res.code == proxy.$passCode) {
952 databaseList.value = res.data || [];
953 tableFormItems.value[1].options = databaseList.value;
954 } else {
955 proxy.$ElMessage.error(res.msg);
956 }
957 })
958 }
959
960 /** 获取 数据目录主题域列表 */
961 const matchtableList: any = ref([]);
962 const getMatchTableList = () => {
963 getSubjectTableTree({}).then((res: any) => {
964 if (res.code === proxy.$passCode) {
965 matchtableList.value = res.data || []
966 tableFormItems.value[2].options = matchtableList.value;
967 } else {
968 proxy.$ElMessage.error(res.msg);
969 }
970 })
971 }
972
973 /** 数据源选择表单组件 */
974 const tableInfoFormRef = ref();
975
976 /** 数据源选择表单配置。 */
977 const tableFormItems = ref([{
978 label: "数据类型",
979 type: "select",
980 placeholder: "请选择",
981 field: "dataSourceType",
982 options: [
983 { label: "数据源", value: 1 },
984 { label: "数据目录", value: 2 }
985 ],
986 default: 1,
987 required: true,
988 }, {
989 label: "数据源",
990 type: "select",
991 placeholder: "请选择",
992 field: "dataSourceGuid",
993 options: databaseList.value,
994 props: {
995 value: 'guid',
996 label: 'databaseNameZh'
997 },
998 default: '',
999 filterable: true,
1000 clearable: true,
1001 visible: true,
1002 required: true,
1003 },
1004 {
1005 label: "数据源",
1006 type: "tree-select",
1007 placeholder: "请选择",
1008 field: "subjectDomainGuid",
1009 options: matchtableList.value,
1010 lazy: false,
1011 expandKeys: [],
1012 props: {
1013 label: 'name',
1014 value: 'guid',
1015 children: 'children',
1016 isLeaf: 'isLeaf'
1017 },
1018 filterable: true,
1019 clearable: true,
1020 default: '',
1021 visible: false,
1022 required: true,
1023 },
1024 {
1025 label: "数据表",
1026 type: "select",
1027 placeholder: "请选择",
1028 field: "tableName",
1029 options: dsTableList.value,
1030 props: {
1031 label: 'label',
1032 value: 'value'
1033 },
1034 default: '',
1035 filterable: true,
1036 clearable: true,
1037 required: true,
1038 }, {
1039 label: "数据表",
1040 type: "select",
1041 placeholder: "请选择",
1042 field: "tableGuid",
1043 options: dsTableList.value,
1044 props: {
1045 label: 'label',
1046 value: 'value'
1047 },
1048 default: '',
1049 filterable: true,
1050 clearable: true,
1051 visible: false,
1052 required: true,
1053 }]);
1054
1055 /** 数据源选择表单配置规则。 */
1056 const tableFormRules = ref({
1057 dataSourceGuid: [required("请选择数据源")],
1058 subjectDomainGuid: [required("请选择数据源")],
1059 tableName: [required("请选择数据表")],
1060 tableGuid: [required("请选择数据表")],
1061 });
1062
1063 /** 单表API当前选择的数据源信息 */
1064 const currDsInfo: any = ref({});
1065
1066 /** 根据选择的数据源和表显示绑定字段列表。 */
1067 const targetDsFields: any = ref([]);
1068
1069 const handleTableFormSelectChange = (val, row, formInfo) => {
1070 if (row.field == 'dataSourceType') {
1071 tableFormItems.value[0].default = val;
1072 tableFormItems.value[1].visible = val == 1;
1073 tableFormItems.value[2].visible = val == 2;
1074 tableFormItems.value[3].visible = val == 1;
1075 tableFormItems.value[4].visible = val == 2;
1076 currDsInfo.value = {};
1077 if (val == 1) {
1078 tableFormItems.value[1].default = '';
1079 } else {
1080 tableFormItems.value[2].default = '';
1081 /** 只有单表API有切换数据源请求表的需求。 */
1082 apiType.value == '1' && handleTableFormSelectChange('', { field: 'dataSourceGuid' }, formInfo);
1083 }
1084 } else if (row.field == 'dataSourceGuid') {
1085 tableFormItems.value[3].default = '';//清空数据表。重新显示下拉框表数据。
1086 tableFormItems.value[1].default = val;
1087 if (!val) {
1088 currDsInfo.value = {};
1089 dsTableList.value = [];
1090 tableFormItems.value[3].options = dsTableList.value;
1091 } else {
1092 getSchemaTableData(val);
1093 }
1094 handleTableFormSelectChange('', { field: 'tableName' }, formInfo);
1095 sqlIsChecked.value = false;
1096 } else if (row.field == 'subjectDomainGuid') {
1097 tableFormItems.value[4].default = '';//清空数据表。重新显示下拉框表数据。
1098 tableFormItems.value[2].default = val;
1099 getSubjectDomainData(val);
1100 } else if (row.field == 'tableName' || row.field == 'tableGuid') {
1101 if (!val) {
1102 targetDsFields.value = [];
1103 requestParamsTableInfo.value.editInfo.boundField.options = targetDsFields.value;
1104 responseParamsTableInfo.value.editInfo.boundField.options = targetDsFields.value;
1105 sortParamsTableInfo.value.editInfo.boundField.options = targetDsFields.value;
1106 requestParamsTableInfo.value.data.forEach((d: any) => {
1107 if (d.boundField) {
1108 d.boundField = "";
1109 }
1110 })
1111 responseParamsTableInfo.value.data.forEach((d: any) => {
1112 if (d.boundField) {
1113 d.boundField = "";
1114 }
1115 })
1116 sortParamsTableInfo.value.data.forEach((d: any) => {
1117 if (d.boundField) {
1118 d.boundField = "";
1119 }
1120 })
1121 } else {
1122 getBingFieldList(formInfo.dataSourceType, formInfo.dataSourceGuid, formInfo[row.field]);
1123 }
1124 }
1125 }
1126
1127 const handleTableTreeNodeChange = (node) => {
1128 if (!node.children) {
1129 currDsInfo.value = node;
1130 currDsInfo.value.subjectDomainGuid = node.guid;
1131 currDsInfo.value.subjectDomainName = node.name;
1132 currDsInfo.value.directoryGuid = node.parentGuid;
1133 }
1134 }
1135
1136 /** 根据数据源获取对应的表列表。 */
1137 const getSchemaTableData = (dsGuid) => {
1138 const option = databaseList.value.find((item) => item.guid === dsGuid)
1139 currDsInfo.value = option;
1140 const obj = { curr: -1, limit: -1, ...option }
1141 return getSchemaTableList({
1142 pageSize: obj.limit,
1143 pageIndex: obj.curr,
1144 dataSourceGuid: obj.guid,
1145 database: obj.databaseNameEn,
1146 databaseType: obj.databaseType,
1147 tableName: obj.value,
1148 hadFlag: false,
1149 subjectDomainGuid: obj.subjectDomainGuid
1150 }).then((res: any) => {
1151 if (res.code == proxy.$passCode) {
1152 dsTableList.value = res.data.records?.map(r => {
1153 r.label = r.tableComment ? (r.tableComment + `(${r.tableName})`) : r.tableName;
1154 r.value = r.tableName;
1155 return r;
1156 }) || [];
1157 tableFormItems.value[3].options = dsTableList.value;
1158 } else {
1159 proxy.$ElMessage.error(res.msg);
1160 }
1161 })
1162 }
1163
1164 /** 获取数据目录列表 */
1165 const getSubjectDomainData = (val) => {
1166 return getSubjectTableByDomain(val).then((res: any) => {
1167 if (res.code == proxy.$passCode) {
1168 dsTableList.value = res.data?.map(r => {
1169 r.label = r.chName ? (r.chName + `(${r.enName})`) : r.enName;
1170 r.value = r.guid;
1171 return r;
1172 }) || [];
1173 tableFormItems.value[4].options = dsTableList.value
1174 } else {
1175 proxy.$ElMessage.error(res.msg);
1176 }
1177 })
1178 }
1179
1180 /** 获取绑定字段列表 */
1181 const getBingFieldList = (dataSourceType, dataSourceGuid, tableName, isSelectChange = true) => {
1182 /** 表选择变化,对应的绑定字段列表会变化,那么请求参数,返回参数,排序参数,需要判断,不在当前字段列表中就清除。 */
1183 if (dataSourceType == 1) {//数据源的表
1184 // 此处跟数据同步那里不同,因为用户可以不使用数据目录模块。
1185 tableColumnList({
1186 dataSourceGuid: dataSourceGuid,
1187 database: currDsInfo.value.databaseNameEn,
1188 databaseType: currDsInfo.value.databaseType,
1189 pageIndex: 1,
1190 pageSize: -1,
1191 tableName: tableName,
1192 }).then((res: any) => {
1193 if (res.code == proxy.$passCode) {
1194 targetDsFields.value = res.data?.map(r => {
1195 r.value = r.columnName,
1196 r.label = r.columnName + (r.columnComment ? `(${r.columnComment})` : '');
1197 return r
1198 }) || [];
1199 console.log('targetDsFields.value', targetDsFields.value)
1200 requestParamsTableInfo.value.editInfo.boundField.options = targetDsFields.value;
1201 isSelectChange && requestParamsTableInfo.value.data.forEach((d: any) => {
1202 if (d.boundField && !targetDsFields.value.some(f => f.value == d.boundField)) {
1203 d.boundField = "";
1204 }
1205 })
1206 responseParamsTableInfo.value.editInfo.boundField.options = targetDsFields.value;
1207 isSelectChange && responseParamsTableInfo.value.data.forEach((d: any) => {
1208 if (d.boundField && !targetDsFields.value.some(f => f.value == d.boundField)) {
1209 d.boundField = "";
1210 }
1211 })
1212 sortParamsTableInfo.value.editInfo.boundField.options = targetDsFields.value;
1213 isSelectChange && sortParamsTableInfo.value.data.forEach((d: any) => {
1214 if (d.boundField && !targetDsFields.value.some(f => f.value == d.boundField)) {
1215 d.boundField = "";
1216 }
1217 })
1218 } else {
1219 proxy.$ElMessage.error(res.msg);
1220 }
1221 })
1222 } else { //数据目录的表
1223 getSubjectTableDetail(tableName).then((res: any) => {
1224 if (res.code == proxy.$passCode) {
1225 targetDsFields.value = res.data.subjectFieldVOS?.map(r => {
1226 r.value = r.enName,
1227 r.label = r.enName + (r.chName ? `(${r.chName})` : '');
1228 return r
1229 }) || [];
1230 requestParamsTableInfo.value.editInfo.boundField.options = targetDsFields.value;
1231 responseParamsTableInfo.value.editInfo.boundField.options = targetDsFields.value;
1232 sortParamsTableInfo.value.editInfo.boundField.options = targetDsFields.value;
1233 } else {
1234 proxy.$ElMessage.error(res.msg);
1235 }
1236 })
1237 }
1238 }
1239
1240 const requestParamsTableInfoRef = ref();
1241
1242 /**
1243 * 请求参数表格配置
1244 * 注意:绑定字段需要自动匹配,第一步点进来时默认将入参定义,全部变为请求参数的默认值设置。
1245 */
1246 const requestParamsTableInfo = ref({
1247 id: "request-params-table",
1248 height: '214px',
1249 fields: [
1250 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
1251 { label: "绑定参数", field: "paramName", width: 140, required: true, columClass: 'edit-colum', type: 'edit' },
1252 { label: "绑定字段", field: "boundField", width: 140, required: true, columClass: 'edit-colum', type: 'edit' },
1253 { label: "操作符", field: "operator", width: 100, required: true, columClass: 'edit-colum', type: 'edit' },
1254 ],
1255 editInfo: {
1256 paramName: {
1257 label: '',
1258 type: 'select',
1259 field: 'paramName',
1260 default: '',
1261 getOptions: (scope) => {
1262 return inputParamsData.value;
1263 },
1264 props: {
1265 label: 'paramName',
1266 value: 'paramName'
1267 },
1268 placeholder: '请选择',
1269 clearable: true,
1270 },
1271 boundField: {
1272 label: '',
1273 type: 'select',
1274 field: 'boundField',
1275 default: '',
1276 options: targetDsFields.value,
1277 placeholder: '请选择',
1278 clearable: true,
1279 },
1280 operator: {
1281 label: '',
1282 type: 'select',
1283 field: 'operator',
1284 default: '1',
1285 options: paramOperatorList.value,
1286 props: {
1287 label: 'label',
1288 value: 'value'
1289 },
1290 filterable: true,
1291 placeholder: '请选择',
1292 clearable: true,
1293 }
1294 },
1295 STATUS: 'edit',
1296 data: <Array<Object>>[],
1297 showPage: false,
1298 actionInfo: {
1299 show: true,
1300 label: "操作",
1301 type: "btn",
1302 width: apiType.value != '3' ? 180 : 80,
1303 fixed: 'right',
1304 btns: (scope) => {
1305 let row = scope.row;
1306 return [
1307 {
1308 label: "复制", visible: apiType.value != '3', value: "copy", disabled: requestParamsTableInfo.value.data.length == inputParamsData.value.length, click: (scope) => {
1309 let index = scope.$index;
1310 let data = requestParamsTableInfo.value.data;
1311 data.push({ ...scope.row });
1312 }
1313 },
1314 {
1315 label: "添加至排序", visible: apiType.value != '3', disabled: !row.paramName || !row.boundField || sortParamsTableInfo.value.data.some(d => d.paramName == row.paramName), value: "addSort", click: (scope) => { //必填参数完成后再启用添加至排序按钮
1316 sortParamsTableInfo.value.data.push({ paramName: row.paramName, boundField: row.boundField, sortMode: 'ASC', index: sortParamsTableInfo.value.data.length + 1 });
1317 }
1318 },
1319 {
1320 label: "删除", value: "remove", click: (scope) => {
1321 let index = scope.$index;
1322 requestParamsTableInfo.value.data.splice(index, 1);
1323 }
1324 },
1325 ]
1326 }
1327 },
1328 loading: false
1329 });
1330
1331 /** 给表格添加一行请求参数。 */
1332 const addRequestParams = () => {
1333 requestParamsTableInfo.value.data.push({ operator: '1' });
1334 nextTick(() => {
1335 scrollLastRowToView(requestParamsTableInfoRef.value?.tableRef, requestParamsTableInfo.value.data.length);
1336 })
1337 }
1338
1339 const getRequestParamOptions = () => {
1340 let requestData: any = requestParamsTableInfo.value.data;
1341 requestParamsTableInfo.value.editInfo.paramName.getOptions = (scope) => {
1342 let val = inputParamsData.value.filter(p => !requestData.some(r => r.paramName == p.paramName));
1343 return scope.row.paramName ? val.concat({
1344 paramName: scope.row.paramName
1345 }) : val;
1346 };
1347 }
1348 const seeDetail = (row) => {
1349 console.log('row', row);
1350 router.push({
1351 name: 'processSheetDetail',
1352 query: {
1353 guid: row.guid,
1354 }
1355 });
1356 }
1357
1358 watch(() => inputParamsData.value, (v, oldV) => {
1359 if (isEditNoChange.value) {
1360 isEditNoChange.value = false;
1361 return;
1362 }
1363 if (checkedSqlScript.value.params.some(item1 => v.find(vv => vv.paramName == item1)) && checkedSqlScript.value.sql) {
1364 return;
1365 }
1366 /** 修改了请求参数,需要重新检验sql. */
1367 sqlIsChecked.value = false;
1368 getRequestParamOptions();
1369 }, {
1370 deep: true
1371 });
1372
1373 watch(() => requestParamsTableInfo.value.data, (v) => {
1374 getRequestParamOptions();
1375 }, {
1376 deep: true
1377 });
1378
1379 const handleRequestSelectChange = (val, scope, item) => {
1380 if (item.field == 'paramName') {
1381 let inputParam = inputParamsData.value.find(p => p.paramName == val);
1382 if (!inputParam) {
1383 return;
1384 }
1385 if (inputParam.isManyValue == 'Y' && scope.row.isManyValue != 'Y') {
1386 scope.row.operator = '10';//多值时默认是in。非多值时不设置,避免出现,已经设置了like操作符,但是切换了参数值之后就被改变了。
1387 } else if (inputParam.isManyValue == 'N' && scope.row.isManyValue != 'N') {
1388 scope.row.operator = '1';
1389 }
1390 scope.row.isManyValue = inputParam.isManyValue;
1391 if (inputParam.isRequired != 'Y' && (scope.row.operator == '2' || scope.row.operator == '11')) {
1392 proxy.$ElMessage.error(`参数名称:${scope.row.paramName}需必填,请返回上一步修改`);
1393 }
1394 } else if (item.field == 'operator') {
1395 let inputParam = inputParamsData.value.find(p => p.paramName == scope.row.paramName);
1396 if (!inputParam) {
1397 return;
1398 }
1399 if (inputParam.isRequired != 'Y' && (scope.row.operator == '2' || scope.row.operator == '11')) {
1400 proxy.$ElMessage.error(`参数名称:${scope.row.paramName}需必填,请返回上一步修改`);
1401 }
1402 }
1403 }
1404
1405 const responseParamsTableRef = ref();
1406
1407 /**
1408 * 返回参数表格配置
1409 * 注意:绑定字段需要自动匹配,第一步点进来时默认将入参定义,全部变为返回参数的默认值设置。
1410 */
1411 const responseParamsTableInfo = ref({
1412 id: "reponse-params-table",
1413 height: '214px',
1414 fields: [
1415 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
1416 { label: "参数名", field: "paramName", width: 140, required: true, columClass: 'edit-colum', type: 'edit' },
1417 { label: "绑定字段", field: "boundField", width: 140, required: true, columClass: 'edit-colum', type: 'edit' },
1418 { label: "参数类型", field: "dataType", width: 120, required: true, columClass: 'edit-colum', type: 'edit' },
1419 { label: "示例值", field: "exampleValue", width: 160, columClass: 'edit-colum', type: 'edit' },
1420 { label: "描述", field: "description", width: 160, columClass: 'edit-colum', type: 'edit' },
1421 ],
1422 editInfo: {
1423 paramName: {
1424 label: '',
1425 type: 'input',
1426 field: 'paramName',
1427 maxlength: 50,
1428 regexp: /[^A-Za-z0-9_]/g,
1429 default: '',
1430 placeholder: '请选择',
1431 clearable: true,
1432 },
1433 boundField: {
1434 label: '',
1435 type: 'select',
1436 field: 'boundField',
1437 default: '',
1438 options: targetDsFields.value,
1439 placeholder: '请选择',
1440 clearable: true,
1441 },
1442 dataType: {
1443 label: '',
1444 type: 'select',
1445 field: 'dataType',
1446 default: '',
1447 options: dataTypeList.value,
1448 props: {
1449 label: 'label',
1450 value: 'value'
1451 },
1452 placeholder: '请选择',
1453 clearable: true,
1454 filterable: true
1455 },
1456 exampleValue: {
1457 label: '',
1458 type: 'input',
1459 field: 'exampleValue',
1460 default: '',
1461 maxlength: 100,
1462 placeholder: '请输入',
1463 clearable: true,
1464 },
1465 description: {
1466 label: '',
1467 type: 'input',
1468 field: 'description',
1469 default: '',
1470 maxlength: 100,
1471 placeholder: '请输入',
1472 clearable: true,
1473 }
1474 },
1475 STATUS: 'edit',
1476 data: <Array<Object>>[],
1477 showPage: false,
1478 actionInfo: {
1479 show: true,
1480 label: "操作",
1481 type: "btn",
1482 width: 150,
1483 fixed: 'right',
1484 btns: (scope) => {
1485 let row = scope.row;
1486 return [
1487 {
1488 label: "添加至排序", value: "addSort", disabled: !row.paramName || !row.boundField || sortParamsTableInfo.value.data.some(d => d.paramName == row.paramName), click: (scope) => {
1489 sortParamsTableInfo.value.data.push({ paramName: row.paramName, boundField: row.boundField, sortMode: 'ASC', index: sortParamsTableInfo.value.data.length + 1 });
1490 }
1491 },
1492 {
1493 label: "删除", value: "remove", click: (scope) => {
1494 let index = scope.$index;
1495 responseParamsTableInfo.value.data.splice(index, 1);
1496 }
1497 },
1498 ]
1499 }
1500 },
1501 loading: false
1502 });
1503
1504 /** 给表格添加一行返回参数。 */
1505 const addresponseParams = () => {
1506 responseParamsTableInfo.value.data.push({});
1507 nextTick(() => {
1508 scrollLastRowToView(responseParamsTableRef.value?.tableRef, responseParamsTableInfo.value.data.length);
1509 });
1510 }
1511
1512 /** 处理返回参数编辑表格中的下拉框事件 */
1513 const handleresponseParamselectChange = (val, scope, item) => {
1514 if (item.field == 'boundField') {
1515 scope.row.paramName = val;
1516 if (tableInfoFormRef.value.formInline.dataSourceType == 1) {
1517 scope.row.dataType = targetDsFields.value.find(t => t.columnName == val)?.dataType;
1518 } else {
1519 scope.row.dataType = targetDsFields.value.find(t => t.enName == val)?.dataType;
1520 }
1521 }
1522 }
1523
1524 const sortParamsTableRef = ref();
1525
1526 /**
1527 * 排序参数表格配置
1528 * 注意:绑定字段需要自动匹配,第一步点进来时默认将入参定义,全部变为返回参数的默认值设置。
1529 */
1530 const sortParamsTableInfo = ref({
1531 id: "sort-params-table",
1532 sortable: true,
1533 rowKey: 'index',
1534 height: '214px',
1535 fields: [
1536 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
1537 { label: "参数名", field: "paramName", width: 140, required: true, columClass: 'edit-colum', type: 'edit' },
1538 { label: "绑定字段", field: "boundField", width: 140, required: true, columClass: 'edit-colum', type: 'edit' },
1539 { label: "排序方式", field: "sortMode", width: 120, required: true, columClass: 'edit-colum', type: 'edit' },
1540 { label: "描述", field: "description", width: 160, columClass: 'edit-colum', type: 'edit' },
1541 ],
1542 editInfo: {
1543 paramName: {
1544 label: '',
1545 type: 'input',
1546 field: 'paramName',
1547 default: '',
1548 maxlength: 50,
1549 regexp: /[^A-Za-z0-9_]/g,
1550 placeholder: '请输入',
1551 clearable: true,
1552 },
1553 boundField: {
1554 label: '',
1555 type: 'select',
1556 field: 'boundField',
1557 default: '',
1558 options: targetDsFields.value,
1559 placeholder: '请选择',
1560 clearable: true,
1561 },
1562 sortMode: {
1563 label: '',
1564 type: 'select',
1565 field: 'sortMode',
1566 default: 'ASC',
1567 options: [{
1568 value: 'ASC',
1569 label: '升序'
1570 }, {
1571 value: 'DESC',
1572 label: '降序'
1573 }],
1574 placeholder: '请选择',
1575 clearable: false,
1576 },
1577 description: {
1578 label: '',
1579 type: 'input',
1580 field: 'description',
1581 default: '',
1582 maxlength: 100,
1583 placeholder: '请输入',
1584 clearable: true,
1585 }
1586 },
1587 STATUS: 'edit',
1588 data: <Array<{
1589 paramName: string,
1590 boundField: string,
1591 description?: string,
1592 sortMode?: string,
1593 index?: number
1594 }>>[],
1595 showPage: false,
1596 actionInfo: {
1597 show: true,
1598 label: "操作",
1599 type: "btn",
1600 width: 120,
1601 fixed: 'right',
1602 btns: [
1603 { value: 'sort' },
1604 {
1605 label: "删除", value: "remove", click: (scope) => {
1606 let index = scope.$index;
1607 sortParamsTableInfo.value.data.splice(index, 1);
1608 }
1609 },
1610 ]
1611 },
1612 loading: false
1613 });
1614
1615 /** 给表格添加一行排序参数。 */
1616 const addSortParams = () => {
1617 sortParamsTableInfo.value.data.push({ paramName: '', boundField: '', description: '', sortMode: 'ASC', index: sortParamsTableInfo.value.data.length + 1 });
1618 nextTick(() => {
1619 scrollLastRowToView(sortParamsTableRef.value?.tableRef, sortParamsTableInfo.value.data.length);
1620 });
1621 }
1622
1623 /** 处理排序参数编辑表格中的下拉框事件 */
1624 const handleSortParamSelectChange = (val, scope, item) => {
1625 if (item.field == 'boundField') {
1626 scope.row.paramName = val;
1627 }
1628 }
1629
1630 /** ----------------------------第二步配置取数逻辑(自定义sql类型) -------------------------- */
1631 /** 数据源选择表单组件 */
1632 const sqlInfoFormRef = ref();
1633
1634 /** sql是否验证通过,只有通过才可以继续进行下一步 */
1635 const sqlIsChecked = ref(false);
1636
1637 const isEditNoChange = ref(false);
1638
1639 watch(() => sqlIsChecked.value, (val) => {
1640 if (val === false) {
1641 checkedSqlScript.value = {
1642 sql: '',
1643 params: []
1644 };
1645 }
1646 })
1647
1648 const checkedSqlScript = ref({
1649 sql: '',
1650 params: []
1651 });
1652
1653 /** 数据源选择表单配置。 */
1654 const sqlFormItems = ref([{
1655 label: "",
1656 type: "textarea-panel",
1657 title: '编写查询sql',
1658 placeholder: "select * from mf_staff where tenant_name=@{id1} and organisaiton=@{id2} and age between @{id3} and @{id4} order by (mf_staff.tenant_name, mf_staff.staff_name)",
1659 trim: false,
1660 rows: 12,
1661 field: "sqlScript",
1662 default: '',
1663 btns: [
1664 {
1665 label: '验证', value: 'sqlyz', click: () => {
1666 let dataSourceGuid = tableInfoFormRef.value.formInline.dataSourceGuid;
1667 if (!dataSourceGuid) {
1668 proxy.$ElMessage.error('请选择数据源');
1669 return;
1670 }
1671 let sqlScript = sqlInfoFormRef.value.formInline.sqlScript?.trim();
1672 if (!sqlScript) {
1673 proxy.$ElMessage.error('请先编写查询sql');
1674 return;
1675 }
1676 checkSql({
1677 dataSourceGuid: dataSourceGuid,
1678 sqlScript: sqlScript,
1679 }).then((res: any) => {
1680 if (res.code == proxy.$passCode) {
1681 sqlIsChecked.value = true;
1682 checkedSqlScript.value = {
1683 sql: sqlScript,
1684 params: inputParamsData.value?.map(p => p.paramName)
1685 };
1686 proxy.$ElMessage.success('Sql验证通过');
1687 } else {
1688 sqlIsChecked.value = false;
1689 proxy.$ElMessage.error(res.msg);
1690 }
1691 });
1692 }
1693 }
1694 ],
1695 clearable: true,
1696 required: true,
1697 block: true,
1698 },]);
1699
1700 /** 数据源选择表单配置规则。 */
1701 const sqlFormRules = ref({
1702 sqlScript: [required('请编写查询sql')]
1703 });
1704
1705 const sqlFormInputChange = (val, row) => {
1706 if (row.field == 'sqlScript') {
1707 if (checkedSqlScript.value.sql != val.trim()) {
1708 sqlIsChecked.value = false
1709 }
1710 }
1711 }
1712
1713 /** ----------------------------第二步配置取数逻辑(注册API类型) -------------------------- */
1714
1715 /** 基本信息表单组件引用 */
1716 const backApiInfoFormRef = ref();
1717
1718 /** 基本信息表单配置。 */
1719 const backApiFormItems = ref([{
1720 type: "select-group",
1721 field: "backHttpInfo",
1722 col: ' select-input-long',
1723 children: [
1724 {
1725 label: "后台服务HOST",
1726 type: "select",
1727 placeholder: "请选择",
1728 options: [
1729 {
1730 value: "https",
1731 label: "https",
1732 },
1733 {
1734 value: "http",
1735 label: "http",
1736 }
1737 ],
1738 default: "https",
1739 field: "backstageAgreement",
1740 required: true,
1741 visible: true,
1742 },
1743 {
1744 label: " ",
1745 type: "input",
1746 placeholder: "请输入",
1747 default: '',
1748 field: "backstageHost",
1749 required: true,
1750 maxlength: 50,
1751 visible: true,
1752 },
1753 ],
1754 visible: true
1755 }, {
1756 label: "后台服务PATH",
1757 type: "input",
1758 placeholder: "请输入",
1759 default: '/',
1760 field: "backstagePath",
1761 required: true,
1762 maxlength: 200,
1763 visible: true,
1764 }, {
1765 label: '请求方式',
1766 type: 'select',
1767 options: [{
1768 value: 'P',
1769 label: 'post'
1770 }, {
1771 value: 'G',
1772 label: 'get'
1773 }],
1774 placeholder: '请选择',
1775 field: 'backstageRequestMode',
1776 default: 'P',
1777 clearable: true,
1778 filterable: true,
1779 required: true
1780 }, {
1781 label: "后端超时(ms)",
1782 type: "input",
1783 placeholder: "请输入",
1784 default: '',
1785 field: "backstageOvertime",
1786 required: false,
1787 maxlength: 50,
1788 regexp: /\D/g,
1789 visible: true,
1790 }])
1791
1792 /** 基本信息表单配置规则。 */
1793 const backApiFormRules = ref({
1794 backstageAgreement: [required("请选择后台服务协议")],
1795 backstageHost: [required("请填写后台服务HOST")],
1796 backstageRequestMode: [required("请选择请求方式")],
1797 backstagePath: [required("请填写后台服务PATH"), regexpValidate(/^\/(?!\/)[\u4e00-\u9fa5a-zA-Z_-]+(\/[\u4e00-\u9fa5a-zA-Z_-]+)*$/, '请输入合法的请求路径')],
1798 });
1799
1800 const registRequestParamsTableRef = ref();
1801
1802 /**
1803 * 注册APi的请求参数表格配置
1804 * 注意:绑定字段需要自动匹配,第一步点进来时默认将入参定义,全部变为注册API请求参数的默认值设置。
1805 */
1806 const registRequestParamsTableInfo = ref({
1807 id: "regist-request-params-table",
1808 height: '214px',
1809 fields: [
1810 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
1811 { label: "参数名", field: "paramName", width: 140, required: true, columClass: 'edit-colum', type: 'edit' },
1812 { label: "参数位置", field: "paramPosition", width: 120, required: true, columClass: 'edit-colum', type: 'edit' },
1813 { label: "参数类型", field: "dataType", width: 120, required: true, columClass: 'edit-colum', type: 'edit', impactValue: "defaultValue" },
1814 { label: "是否必填", field: "isRequired", width: 100, required: true, columClass: 'edit-colum', type: 'edit' },
1815 { label: "是否多值", field: "isManyValue", width: 100, required: true, columClass: 'edit-colum', type: 'edit' },
1816 { label: "默认值", field: "defaultValue", width: 160, columClass: 'edit-colum', type: 'edit', dataTypeName: 'dataType' },
1817 { label: "描述", field: "description", width: 160, columClass: 'edit-colum', type: 'edit' },
1818 ],
1819 editInfo: {
1820 paramName: {
1821 label: '',
1822 type: 'input',
1823 field: 'paramName',
1824 maxlength: 50,
1825 regexp: /[^A-Za-z0-9_]/g,
1826 default: '',
1827 placeholder: '请输入',
1828 clearable: true,
1829 },
1830 paramPosition: {
1831 label: '',
1832 type: 'select',
1833 field: 'paramPosition',
1834 default: '',
1835 options: paramPositionList.value,
1836 props: {
1837 label: 'label',
1838 value: 'value'
1839 },
1840 placeholder: '请选择',
1841 clearable: true,
1842 filterable: true
1843 },
1844 dataType: {
1845 label: '',
1846 type: 'select',
1847 field: 'dataType',
1848 default: '',
1849 options: dataTypeList.value,
1850 props: {
1851 label: 'label',
1852 value: 'value'
1853 },
1854 placeholder: '请选择',
1855 clearable: true,
1856 filterable: true
1857 },
1858 isRequired: {
1859 label: '',
1860 type: 'select',
1861 field: 'isRequired',
1862 default: 'N',
1863 options: [
1864 {
1865 label: "是",
1866 value: "Y",
1867 },
1868 {
1869 label: "否",
1870 value: "N",
1871 },
1872 ],
1873 placeholder: '请选择',
1874 },
1875 isManyValue: {
1876 label: '',
1877 type: 'select',
1878 field: 'isManyValue',
1879 default: 'N',
1880 options: [
1881 {
1882 label: "是",
1883 value: "Y",
1884 },
1885 {
1886 label: "否",
1887 value: "N",
1888 },
1889 ],
1890 placeholder: '请选择',
1891 },
1892 defaultValue: {
1893 label: '',
1894 type: 'input',
1895 field: 'defaultValue',
1896 default: '',
1897 maxlength: 100,
1898 placeholder: '请输入',
1899 clearable: true,
1900 },
1901 description: {
1902 label: '',
1903 type: 'input',
1904 field: 'description',
1905 default: '',
1906 maxlength: 100,
1907 placeholder: '请输入',
1908 clearable: true,
1909 }
1910 },
1911 STATUS: 'edit',
1912 data: <Array<Object>>[],
1913 showPage: false,
1914 actionInfo: {
1915 show: true,
1916 label: "操作",
1917 type: "btn",
1918 width: 80,
1919 fixed: 'right',
1920 btns: (scope) => {
1921 let row = scope.row;
1922 return [
1923 {
1924 label: "删除", value: "remove", click: (scope) => {
1925 let index = scope.$index;
1926 registRequestParamsTableInfo.value.data.splice(index, 1);
1927 }
1928 }
1929 ]
1930 }
1931 },
1932 loading: false
1933 });
1934
1935 /** 给表格添加一行请求参数。 */
1936 const addRegistRequestParams = () => {
1937 registRequestParamsTableInfo.value.data.push({ paramName: '', isRequired: 'N', isManyValue: 'N', paramPosition: 'B', dataType: 'varchar', defaultValue: '' });
1938 nextTick(() => {
1939 scrollLastRowToView(registRequestParamsTableRef.value?.tableRef, registRequestParamsTableInfo.value.data.length);
1940 });
1941 }
1942
1943 const constParamsTableRef = ref();
1944
1945 /**
1946 * 常量参数表格配置
1947 * 注意:绑定字段需要自动匹配,第一步点进来时默认将入参定义,全部变为常量参数的默认值设置。
1948 */
1949 const constParamsTableInfo = ref({
1950 id: "const-params-table",
1951 height: '214px',
1952 minHeight: '100px',
1953 minPanelHeight: '100px',
1954 fields: [
1955 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
1956 { label: "参数名", field: "paramName", width: 140, required: true, columClass: 'edit-colum', type: 'edit' },
1957 { label: "参数位置", field: "paramPosition", width: 120, required: true, columClass: 'edit-colum', type: 'edit' },
1958 { label: "参数类型", field: "dataType", width: 120, required: true, columClass: 'edit-colum', type: 'edit', impactValue: "defaultValue" },
1959 { label: "是否必填", field: "isRequired", width: 100, required: true },
1960 { label: "常量值", field: "defaultValue", width: 160, required: true, columClass: 'edit-colum', type: 'edit', dataTypeName: 'dataType' },
1961 { label: "描述", field: "description", width: 160, columClass: 'edit-colum', type: 'edit' },
1962 ],
1963 editInfo: {
1964 paramName: {
1965 label: '',
1966 type: 'input',
1967 field: 'paramName',
1968 maxlength: 50,
1969 default: '',
1970 regexp: /[^A-Za-z0-9_]/g,
1971 placeholder: '请输入',
1972 clearable: true,
1973 },
1974 paramPosition: {
1975 label: '',
1976 type: 'select',
1977 field: 'paramPosition',
1978 default: '',
1979 options: paramPositionList.value,
1980 props: {
1981 label: 'label',
1982 value: 'value'
1983 },
1984 placeholder: '请选择',
1985 clearable: true,
1986 filterable: true
1987 },
1988 dataType: {
1989 label: '',
1990 type: 'select',
1991 field: 'dataType',
1992 default: '',
1993 options: dataTypeList.value,
1994 props: {
1995 label: 'label',
1996 value: 'value'
1997 },
1998 placeholder: '请选择',
1999 clearable: true,
2000 filterable: true
2001 },
2002 isRequired: {
2003 label: '',
2004 type: 'select',
2005 field: 'isRequired',
2006 default: 'Y',
2007 options: [
2008 {
2009 label: "是",
2010 value: "Y",
2011 },
2012 {
2013 label: "否",
2014 value: "N",
2015 },
2016 ],
2017 placeholder: '请选择',
2018 },
2019 isManyValue: {
2020 label: '',
2021 type: 'select',
2022 field: 'isManyValue',
2023 default: 'N',
2024 options: [
2025 {
2026 label: "是",
2027 value: "Y",
2028 },
2029 {
2030 label: "否",
2031 value: "N",
2032 },
2033 ],
2034 placeholder: '请选择',
2035 },
2036 defaultValue: {
2037 label: '',
2038 type: 'input',
2039 field: 'defaultValue',
2040 default: '',
2041 maxlength: 100,
2042 placeholder: '请输入',
2043 clearable: true,
2044 },
2045 description: {
2046 label: '',
2047 type: 'input',
2048 field: 'description',
2049 default: '',
2050 maxlength: 100,
2051 placeholder: '请输入',
2052 clearable: true,
2053 }
2054 },
2055 STATUS: 'edit',
2056 data: <Array<Object>>[],
2057 showPage: false,
2058 actionInfo: {
2059 show: true,
2060 label: "操作",
2061 type: "btn",
2062 width: 80,
2063 fixed: 'right',
2064 btns: (scope) => {
2065 let row = scope.row;
2066 return [
2067 {
2068 label: "删除", value: "remove", click: (scope) => {
2069 let index = scope.$index;
2070 constParamsTableInfo.value.data.splice(index, 1);
2071 }
2072 }
2073 ]
2074 }
2075 },
2076 loading: false
2077 });
2078
2079 /** 给表格添加一行常量参数。 */
2080 const addConstParams = () => {
2081 constParamsTableInfo.value.data.push({ paramName: '', isRequired: 'Y', isManyValue: 'N', paramPosition: 'B', dataType: 'varchar', defaultValue: '' });
2082 nextTick(() => {
2083 scrollLastRowToView(constParamsTableRef.value?.tableRef, constParamsTableInfo.value.data.length);
2084 });
2085 }
2086
2087 /** ---------------------------- 测试API -------------------------- */
2088 /** api基本信息表单配置 */
2089 const apiFormItems = ref([{
2090 label: 'API名称',
2091 type: 'input',
2092 disabled: true,
2093 field: 'apiName',
2094 maxlength: 50,
2095 default: '',
2096 required: true
2097 }, {
2098 label: '请求方式',
2099 type: 'input',
2100 disabled: true,
2101 field: 'requestMode',
2102 maxlength: 50,
2103 default: 'post',
2104 required: true
2105 }, {
2106 label: '请求路径',
2107 type: 'input',
2108 disabled: true,
2109 field: 'requestPath',
2110 maxlength: 50,
2111 default: '',
2112 block: true,
2113 required: true,
2114 },]);
2115
2116 /**
2117 * query参数表格配置。
2118 */
2119 const queryParamsTableInfo = ref({
2120 id: "query-params-table",
2121 height: '214px',
2122 fields: [
2123 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
2124 { label: "参数名", field: "paramName", width: 140 },
2125 {
2126 label: "参数类型", field: "dataType", width: 100, getName: (scope) => {
2127 return dataTypeList.value.find(d => d.value == scope.row.dataType)?.label;
2128 }
2129 },
2130 {
2131 label: "是否必填", field: "isRequired", width: 100, getName: (scope) => {
2132 return scope.row.isRequired == 'Y' ? '是' : '否'
2133 }
2134 },
2135 {
2136 label: "是否多值", field: "isManyValue", width: 100, getName: (scope) => {
2137 return scope.row.isManyValue == 'Y' ? '是' : '否'
2138 }
2139 },
2140 {
2141 label: "值", field: "introductionValue", width: 240, columClass: 'edit-colum', type: 'edit', dataTypeName: 'dataType', getVisible: (scope) => {
2142 return !scope.row.isConst;
2143 }
2144 },
2145 { label: "描述", field: "description", width: 140 },
2146 ],
2147 editInfo: {
2148 introductionValue: {
2149 label: '',
2150 type: 'input',
2151 field: 'introductionValue',
2152 default: '',
2153 placeholder: '请输入',
2154 clearable: true,
2155 }
2156 },
2157 STATUS: 'edit',
2158 data: <Array<Object>>[],
2159 showPage: false,
2160 actionInfo: {
2161 show: false
2162 },
2163 loading: false
2164 });
2165
2166 const defaultParamsData: any = ref([{
2167 paramName: 'pageSize',
2168 dataType: '整型',
2169 isRequired: '是',
2170 value: 50
2171 }, {
2172 paramName: 'pageIndex',
2173 dataType: '整型',
2174 isRequired: '是',
2175 value: 1
2176 }]);
2177
2178 /** default参数表格配置 */
2179 const defaultParamsTableInfo = ref({
2180 id: "default-params-table",
2181 height: 'auto',
2182 minHeight: '50px',
2183 minPanelHeight: '50px',
2184 fields: [
2185 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
2186 { label: "参数名", field: "paramName", width: 140 },
2187 { label: "参数类型", field: "dataType", width: 100 },
2188 { label: "是否必填", field: "isRequired", width: 100 },
2189 { label: "值", field: "value", width: 240, columClass: 'edit-colum', type: 'edit' },
2190 ],
2191 editInfo: {
2192 value: { //只能输入大于0的整数。
2193 label: '',
2194 type: 'input',
2195 field: 'value',
2196 default: '',
2197 maxlength: 50,
2198 min: 1,
2199 regexp: /\D/g,
2200 placeholder: '请输入',
2201 clearable: false,
2202 }
2203 },
2204 STATUS: 'edit',
2205 data: defaultParamsData.value,
2206 showPage: false,
2207 actionInfo: {
2208 show: false
2209 },
2210 loading: false
2211 });
2212
2213 /** api测试结果详情表单 */
2214 const resultFormItems = ref([{
2215 label: '请求详情',
2216 type: 'textarea',
2217 placeholder: '输出请求详情',
2218 field: 'requestUrlDetail',
2219 default: '',
2220 rows: 10,
2221 readonly: true,
2222 maxlength: "",
2223 clearable: true,
2224 required: false,
2225 }, {
2226 label: '返回内容',
2227 type: 'textarea',
2228 placeholder: '输出返回内容',
2229 field: 'resultInfo',
2230 default: '',
2231 rows: 10,
2232 readonly: true,
2233 maxlength: "",
2234 clearable: true,
2235 required: false,
2236 }]);
2237
2238 onActivated(() => {
2239 // getIPList({
2240 // pageSize: -1
2241 // }).then((res: any) => {
2242 // if (res.code == proxy.$passCode) {
2243 // whiteIPsList.value = res.data.records || [];
2244 // let formItem: any = baseFormItems.value.find(i => i.field == 'whiteIPs');
2245 // formItem && (formItem.options = whiteIPsList.value);
2246 // } else {
2247 // proxy.$ElMessage.error(res.msg);
2248 // }
2249 // });
2250 })
2251
2252 const getDetailPromise = ref();
2253
2254 const needApprove = ref(false);
2255
2256 onBeforeMount(() => {
2257 getDomainName().then((res: any) => {
2258 if (res.code == proxy.$passCode) {
2259 domainName.value = res.data;
2260 } else {
2261 proxy.$ElMessage.error(res.msg);
2262 }
2263 });
2264 getParamDataTypeList();
2265 getParamPositionList();
2266 //TODO,需要取消注释
2267 // isNeedApprove({ funcCode: 'ZCZLPJ' }).then((res1: any) => {
2268 // if (res1.code == proxy.$passCode) {
2269 // needApprove.value = !!res1.data;
2270 // } else {
2271 // proxy.$ElMessage.error(res1.msg);
2272 // }
2273 // });
2274 // getParamSceneList();
2275 //getParamProcessSheetList()
2276 if (apiGuid.value) {//编辑页面。
2277 fullscreenLoading.value = true;
2278 getDetailPromise.value = getApiDetail(apiGuid.value).then((res: any) => {
2279 getDetailPromise.value = null;
2280 fullscreenLoading.value = false;
2281 if (res.code == proxy.$passCode) {
2282 let data = detailInfo.value = res.data;
2283 apiType.value = data.apiType;
2284 baseFormItems.value.forEach(item => {
2285 item.default = data[item.field];
2286 if (item.field == 'httpInfo') {
2287 item.children && (item.children[1].default = data['requestPath']);
2288 }
2289 // if (item.field == 'processOrderGuids'){
2290 // if(data.processDTOS&&data.processDTOS.length>0){
2291 // // item.default=data.processDTOS.map(item=>item.guid)
2292 // item.default=data.processDTOS[0].guid
2293 // let processDTOS=data.processDTOS || [];
2294 // if(processDTOS?.length>0){
2295 // processDTOS.forEach(obj=>{
2296 // obj.noName=obj.processOrderNo + '' + obj.requirementOrderName
2297 // })
2298 // }
2299 // processDTOSValue.value = processDTOS || [];
2300
2301 // }
2302 // }
2303 // if (item.field == 'processOrderNo') {
2304 // if (data.processOrderNo?.length) {
2305 // item.default = data.processOrderNo || [];
2306 // }
2307 // }
2308 // if (item.field == 'whiteIPs') {
2309 // item.visible = data.authenticationType == 'N';
2310 // if (data.whiteIPs?.length) {
2311 // item.default = data.whiteIPs || [];
2312 // }
2313 // // }
2314 // if (item.field == 'authenticationType') {
2315 // // item.disabled = apiType.value == '3';
2316 // }
2317 });
2318 /** 需要重新设置,否则detailInfo.value无法为最新。 */
2319 nextTick().then(() => {
2320 baseFormRules.value.apiName = [required("请填写API名称"), chOrEnPreffix(), checkExistName(checkedInfo.value, checkExistAPIName, detailInfo.value, 'apiName')];
2321 baseFormRules.value.requestPath = [required("请填写请求路径"), regexpValidate(/^\/[^\/][\w\u4e00-\u9fa5_-]*$/, '请输入合法的请求路径'), checkExistName(checkedPathInfo.value, checkExistRequestPath, detailInfo.value, 'requestPath', '该请求路径已存在,请填写其他路径')];
2322 });
2323 let apiConfigAccessRSVOS = data.apiConfigAccessRSVOS || [];
2324 inputParamsData.value = [];
2325 let requestData: any[] = [];
2326 let responseData: any[] = [];
2327 let registRequestData: any[] = [];
2328 let constData: any[] = [];
2329 let sortData: any[] = [];
2330 apiConfigAccessRSVOS.forEach(vo => {
2331 if (vo.paramType == 'DEFIN') {
2332 inputParamsData.value.push(vo);
2333 } else if (vo.paramType == 'REQ') {
2334 if (apiType.value == '3') {
2335 registRequestData.push(vo);
2336 } else if (apiType.value == '2') {
2337 inputParamsData.value.push(vo);
2338 } else {
2339 requestData.push(vo);
2340 }
2341 } else if (vo.paramType == 'RESP') {
2342 responseData.push(vo);
2343 } else if (vo.paramType == 'ORDER') {
2344 sortData.push({ ...vo, index: sortData.length + 1 });
2345 } else if (vo.paramType == 'SQL') {
2346 sqlFormItems.value.forEach(item => {
2347 item.default = vo.selectSqlStatement;
2348 });
2349 } else if (vo.paramType == 'CONSTANT') {
2350 constData.push(vo);
2351 }
2352 });
2353 inputParamsTableInfo.value.data = inputParamsData.value;
2354 requestParamsTableInfo.value.data = requestData;
2355 responseParamsTableInfo.value.data = responseData;
2356 sortParamsTableInfo.value.data = sortData;
2357 registRequestParamsTableInfo.value.data = registRequestData;
2358 constParamsTableInfo.value.data = constData;
2359 tableFormItems.value.forEach(item => {
2360 item.default = data[item.field];
2361 });
2362 if (apiType.value == '1') {
2363 getParamOperatorList();
2364 tableFormItems.value[1].visible = data.dataSourceType == 1;
2365 tableFormItems.value[3].visible = data.dataSourceType == 1;
2366 tableFormItems.value[2].visible = data.dataSourceType == 2;
2367 tableFormItems.value[4].visible = data.dataSourceType == 2;
2368 } else if (apiType.value == '3') {
2369 backApiFormItems.value.forEach(item => {
2370 item.default = data[item.field];
2371 if (item.children) {
2372 item.children.forEach(c => {
2373 c.default = data[c.field];
2374 });
2375 }
2376 });
2377 }
2378 sqlIsChecked.value = true;
2379 isEditNoChange.value = true;
2380 checkedSqlScript.value = {
2381 sql: sqlFormItems.value[0].default,
2382 params: inputParamsData.value.map(i => i.paramName)
2383 };
2384 let { approveVO } = data;
2385 bizApproveVO.value = data.approveVO;
2386 if (approveVO && (approveVO.approveState == 'N' || approveVO.approveState == 'C' || approveVO.approveState == 'R')) {
2387 getCamundaDeploymentId('10023').then((res: any) => {
2388 if (res.code == proxy.$passCode) {
2389 deploymentId.value = res.data;
2390 } else {
2391 proxy.$ElMessage.error(res.msg);
2392 }
2393 })
2394 }
2395 } else {
2396 apiType.value = '1';
2397 proxy.$ElMessage.error(res.msg);
2398 }
2399 });
2400 } else {
2401 // baseFormItems.value[4].default = sceneName.value
2402 getCamundaDeploymentId('10023').then((res: any) => {
2403 if (res.code == proxy.$passCode) {
2404 deploymentId.value = res.data;
2405 } else {
2406 proxy.$ElMessage.error(res.msg);
2407 }
2408 })
2409 if (apiType.value == '1') {
2410 getParamOperatorList();
2411 }
2412 let item = baseFormItems.value.find(b => b.field == 'authenticationType');
2413 // item && (item.disabled = apiType.value == '3');
2414 }
2415 })
2416
2417 onMounted(() => {
2418 if (getDetailPromise.value) {
2419 getDetailPromise.value.then(() => {
2420 enableRowDrop((evt) => {
2421 let tableData = sortParamsTableInfo.value.data;
2422 const movedItem = tableData.splice(evt.oldIndex, 1)[0];
2423 tableData.splice(evt.newIndex, 0, movedItem);
2424 nextTick(() => {
2425 sortParamsTableInfo.value.data = JSON.parse(JSON.stringify(tableData)).map((t: any, index) => {
2426 t.index = index + 1;
2427 return t;
2428 })
2429 })
2430 });
2431 });
2432 } else {
2433 enableRowDrop((evt) => {
2434 let tableData = sortParamsTableInfo.value.data;
2435 const movedItem = tableData.splice(evt.oldIndex, 1)[0];
2436 tableData.splice(evt.newIndex, 0, movedItem);
2437 nextTick(() => {
2438 sortParamsTableInfo.value.data = JSON.parse(JSON.stringify(tableData)).map((t: any, index) => {
2439 t.index = index + 1;
2440 return t;
2441 })
2442 })
2443 });
2444 }
2445 });
2446
2447 onUnmounted(() => {
2448 destroySort();
2449 })
2450
2451 const startTestApiBtnLoading = ref(false);
2452
2453 /** 调用测试API接口,并返回详情。 */
2454 const startTestApi = () => {
2455 let queryParamData: any[] = queryParamsTableInfo.value.data;
2456 let dataIndex = 1;
2457 for (const d of queryParamData) {
2458 if (d.isRequired == 'Y' && d.introductionValue !== 0 && !d.introductionValue) {
2459 proxy.$ElMessage.error(`第 ${dataIndex} 个参数为必填则值不能为空`);
2460 handleContentWrapView('queryParams');
2461 return;
2462 }
2463 if (checkValidValue[d.dataType]) {
2464 let v = checkValidValue[d.dataType](d.introductionValue, d.isManyValue == 'Y');
2465 if (v !== true) {
2466 proxy.$ElMessage.error(`第 ${dataIndex} 个参数类型为${v},请输入合法的值`);
2467 handleContentWrapView('queryParams');
2468 return;
2469 }
2470 }
2471 dataIndex++;
2472 }
2473 let params = { ...baseInfoFormRef.value?.formInline, ...tableInfoFormRef.value?.formInline, dataSourceName: currDsInfo.value.databaseNameZh, requestAgreement: 'https' };
2474 if (params.apiType == '1') {
2475 if (params.dataSourceType == 2) {
2476 params.directoryGuid = currDsInfo.value.directoryGuid;
2477 params.subjectDomainName = currDsInfo.value.subjectDomainName;
2478 let dsTable = dsTableList.value.find(d => d.value == params.tableGuid);
2479 params.dataSourceGuid = dsTable.dataSourceGuid;
2480 params.tableName = dsTable.enName;
2481 }
2482 }
2483 let defaultParamsDataInfo = defaultParamsTableInfo.value.data;
2484 if (defaultParamsDataInfo.length == 3 && !defaultParamsDataInfo[2].value) {
2485 proxy.$ElMessage.error(`请填写参数appKey`);
2486 handleContentWrapView('defaultParams');
2487 return;
2488 }
2489 let apiConfigAccessDTOS: any[] = [];
2490 if (apiType.value != '2') { //单表API,注册API
2491 inputParamsData.value.forEach(i => {
2492 apiConfigAccessDTOS.push({ ...i, paramType: 'DEFIN' });
2493 });
2494 requestParamsTableInfo.value.data.forEach((r: any, index) => {
2495 let obj = { ...r, paramType: 'REQ' };
2496 if (apiType.value == 1) {
2497 let p = inputParamsData.value.find(i => i.paramName == r.paramName);
2498 let queryData = queryParamData[index];
2499 obj = Object.assign({}, p, obj, { paramPosition: p.paramPosition, dataType: p.dataType, isRequired: queryData.isRequired, isManyValue: queryData.isManyValue, introductionValue: queryData.introductionValue });
2500 }
2501 apiConfigAccessDTOS.push(obj);
2502 });
2503 let responseParamsData = responseParamsTableInfo.value.data;
2504 responseParamsData.forEach(r => {
2505 apiConfigAccessDTOS.push({ ...r, paramType: 'RESP' });
2506 });
2507 sortParamsTableInfo.value.data.forEach(s => {
2508 apiConfigAccessDTOS.push({ ...s, paramType: 'ORDER' });
2509 });
2510 if (apiType.value == '3') {
2511 registRequestParamsTableInfo.value.data.forEach((r, index) => {
2512 let queryData = queryParamData[index];
2513 apiConfigAccessDTOS.push({ ...r, paramType: 'REQ', isRequired: queryData.isRequired, isManyValue: queryData.isManyValue, introductionValue: queryData.introductionValue });
2514 });
2515 constParamsTableInfo.value.data.forEach(c => {
2516 apiConfigAccessDTOS.push({ ...c, paramType: 'CONSTANT' });
2517 });
2518 params = { ...params, ...backApiInfoFormRef.value.formInline };
2519 }
2520 } else {//自定义sql
2521 inputParamsData.value.forEach((i, index) => {
2522 apiConfigAccessDTOS.push({ ...i, paramType: 'REQ', introductionValue: queryParamData[index].introductionValue });
2523 });
2524 apiConfigAccessDTOS.push({
2525 paramType: 'SQL',
2526 selectSqlStatement: sqlInfoFormRef.value.formInline.sqlScript?.trim()
2527 });
2528 }
2529 params.apiConfigAccessDTOS = apiConfigAccessDTOS;
2530 params.pageSize = defaultParamsDataInfo[0].value;
2531 params.pageIndex = defaultParamsDataInfo[1].value;
2532 defaultParamsDataInfo.length == 3 && (params.appKey = defaultParamsDataInfo[2].value);
2533 startTestApiBtnLoading.value = true;
2534 resultFormItems.value[0].default = '';
2535 resultFormItems.value[1].default = '';
2536 testEditApi(params).then((res: any) => {
2537 startTestApiBtnLoading.value = false;
2538 if (res.code == proxy.$passCode) {
2539 proxy.$ElMessage.success('测试API调用成功');
2540 let info = res.data;
2541 resultFormItems.value[0].default = JSON.stringify(info.apiInvokeReqVO, null, 4);
2542 resultFormItems.value[1].default = JSON.stringify(info.apiInvokeRespVO, null, 4);
2543 } else {
2544 proxy.$ElMessage.error(res.msg);
2545 }
2546 }).catch(() => {
2547 startTestApiBtnLoading.value = false;
2548 });
2549 }
2550
2551 /** 提交新增API. */
2552 const save = (isSubmit: boolean = false) => {
2553 let params = { isSubmit: isSubmit ? 'Y' : 'N', ...baseInfoFormRef.value?.formInline, ...tableInfoFormRef.value?.formInline, dataSourceName: currDsInfo.value.databaseNameZh, requestAgreement: 'https' };
2554 params.immediateApprove = isSubmit
2555 if (params.apiType == '1') {
2556 if (params.dataSourceType == 2) {
2557 params.directoryGuid = currDsInfo.value.directoryGuid;
2558 params.subjectDomainName = currDsInfo.value.subjectDomainName;
2559 let dsTable = dsTableList.value.find(d => d.value == params.tableGuid);
2560 params.dataSourceGuid = dsTable.dataSourceGuid;
2561 params.tableName = dsTable.enName;
2562 }
2563 }
2564 /** 验证输入的query值, query参数的值应该不用存储 */
2565 // let queryParamData: any[] = queryParamsTableInfo.value.data;
2566 // let dataIndex = 1;
2567 // for (const d of queryParamData) {
2568 // if (d.introductionValue && checkValidValue[d.dataType]) {
2569 // let v = checkValidValue[d.dataType](d.introductionValue, d.isManyValue == 'Y');
2570 // if (v !== true) {
2571 // proxy.$ElMessage.error(`第 ${dataIndex} 个参数类型为${v},请输入合法的值`);
2572 // return;
2573 // }
2574 // }
2575 // dataIndex++;
2576 // }
2577
2578 let apiConfigAccessDTOS: any[] = [];
2579 if (apiType.value != '2') { //单表API
2580 inputParamsData.value.forEach(i => {
2581 apiConfigAccessDTOS.push({ ...i, paramType: 'DEFIN' });
2582 });
2583 requestParamsTableInfo.value.data.forEach((r: any, index) => {
2584 let obj = { ...r, paramType: 'REQ', /*introductionValue: queryParamData[index].introductionValue*/ };
2585 if (apiType.value == 1) {
2586 let p = inputParamsData.value.find(i => i.paramName == r.paramName);
2587 obj = Object.assign({}, p, obj, { paramPosition: p.paramPosition, dataType: p.dataType, description: p.description, isRequired: p.isRequired, isManyValue: p.isManyValue, defaultValue: p.defaultValue });
2588 }
2589 apiConfigAccessDTOS.push(obj);
2590 });
2591 let responseParamsData = responseParamsTableInfo.value.data;
2592 responseParamsData.forEach(r => {
2593 apiConfigAccessDTOS.push({ ...r, paramType: 'RESP' });
2594 });
2595 sortParamsTableInfo.value.data.forEach(s => {
2596 apiConfigAccessDTOS.push({ ...s, paramType: 'ORDER' });
2597 });
2598 if (apiType.value == '3') {
2599 registRequestParamsTableInfo.value.data.forEach((r, index) => {
2600 apiConfigAccessDTOS.push({ ...r, paramType: 'REQ', /*introductionValue: queryParamData[index].introductionValue*/ });
2601 });
2602 constParamsTableInfo.value.data.forEach(c => {
2603 apiConfigAccessDTOS.push({ ...c, paramType: 'CONSTANT' });
2604 });
2605 params = { ...params, ...backApiInfoFormRef.value.formInline };
2606 }
2607 } else {//自定义sql
2608 inputParamsData.value.forEach(i => {
2609 apiConfigAccessDTOS.push({ ...i, paramType: 'REQ' });
2610 });
2611 apiConfigAccessDTOS.push({
2612 paramType: 'SQL',
2613 selectSqlStatement: sqlInfoFormRef.value.formInline.sqlScript?.trim()
2614 });
2615 }
2616 fullscreenLoading.value = true;
2617 params.apiConfigAccessDTOS = apiConfigAccessDTOS;
2618 let defaultParamsDataInfo = defaultParamsTableInfo.value.data;
2619 params.pageSize = defaultParamsDataInfo[0].value;
2620 params.pageIndex = defaultParamsDataInfo[1].value;
2621 if (!apiGuid.value) {
2622 addApi(params).then((res: any) => {
2623 fullscreenLoading.value = false;
2624 if (res.code == proxy.$passCode) {
2625 proxy.$ElMessage.success(!isSubmit ? '新建API保存成功' : '新建API保存并提交成功');
2626 router.push({
2627 name: 'apiManagement'
2628 });
2629 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
2630 dataServiceStore.setIsUpdate(true);//改成存场景guid
2631 } else {
2632 proxy.$ElMessage.error(res.msg);
2633 }
2634 });
2635 } else {
2636 params.guid = apiGuid.value;
2637 updateApi(params).then((res: any) => {
2638 fullscreenLoading.value = false;
2639 if (res.code == proxy.$passCode) {
2640 proxy.$ElMessage.success(!isSubmit ? 'API编辑保存成功' : 'API编辑保存并提交成功');
2641 router.push({
2642 name: 'apiManagement'
2643 });
2644 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
2645 dataServiceStore.setIsUpdate(true);
2646 } else {
2647 proxy.$ElMessage.error(res.msg);
2648 }
2649 });
2650 }
2651 }
2652
2653 /** 取消关闭当前新建或编辑页面。 */
2654 const cancel = () => {
2655 if (isDetail.value) {
2656 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
2657 router.push({
2658 path: '/data-service/api-management'
2659 });
2660 return;
2661 }
2662 proxy.$openMessageBox("当前页面尚未保存,确定放弃修改吗?", () => {
2663 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
2664 router.push({
2665 path: '/data-service/api-management'
2666 });
2667 }, () => {
2668 proxy.$ElMessage.info("已取消");
2669 });
2670 }
2671
2672 </script>
2673
2674 <template>
2675 <div class="container_wrap full" v-loading="fullscreenLoading">
2676 <div class="content_main" ref="scrollContainer">
2677 <div class="top_tool_wrap">
2678 <StepBar :steps-info="stepsInfo" />
2679 </div>
2680 <div class="operator_panel_wrap" v-show="step == 0">
2681 <ContentWrap id="id-baseInfo" title="基本信息" description="">
2682 <Form ref="baseInfoFormRef" :itemList="baseFormItems" formId="register-base-form" :rules="baseFormRules"
2683 @select-change="handleBaseInfoSelectChange" col="col3" />
2684 </ContentWrap>
2685 <ContentWrap id="id-inputParams" v-if="apiType != '3'" :title="apiType == '2' ? '请求参数' : '入参定义'" description=""
2686 class="mt16">
2687 <Table ref="inputParamsTableRef" :tableInfo="inputParamsTableInfo" class="fiveRow-table"
2688 @tableInputChange="inputParamsTableInputChange" />
2689 <div class="row-add-btn">
2690 <el-button link @click="addInputParams" :icon="CirclePlus" v-preReClick>添加</el-button>
2691 </div>
2692 </ContentWrap>
2693 </div>
2694 <div class="operator_panel_wrap" v-show="step == 1">
2695 <template v-if="apiType == '1'">
2696 <ContentWrap id="id-tableInfo" title="数据源" description="">
2697 <Form ref="tableInfoFormRef" :itemList="tableFormItems" formId="table-base-form" :rules="tableFormRules"
2698 col="col3" @select-change="handleTableFormSelectChange"
2699 @treeSelectNodeChange="handleTableTreeNodeChange" />
2700 </ContentWrap>
2701 <ContentWrap id="id-requestParams" title="请求参数" description="" class="mt16">
2702 <Table ref="requestParamsTableRef" :tableInfo="requestParamsTableInfo" class="fiveRow-table"
2703 @tableSelectChange="handleRequestSelectChange" />
2704 <div class="row-add-btn">
2705 <el-button link @click="addRequestParams" :icon="CirclePlus"
2706 :disabled="requestParamsTableInfo.data.length == inputParamsData.length" v-preReClick>添加</el-button>
2707 </div>
2708 </ContentWrap>
2709 <ContentWrap id="id-responseParams" title="返回参数" description="" class="mt16">
2710 <Table ref="responseParamsTableRef" :tableInfo="responseParamsTableInfo"
2711 @tableSelectChange="handleresponseParamselectChange" class="fiveRow-table" />
2712 <div class="row-add-btn">
2713 <el-button link @click="addresponseParams" :icon="CirclePlus" v-preReClick>添加</el-button>
2714 </div>
2715 </ContentWrap>
2716 <ContentWrap id="id-sortParams" title="排序参数" description="" class="mt16">
2717 <Table ref="sortParamsTableRef" :tableInfo="sortParamsTableInfo"
2718 @tableSelectChange="handleSortParamSelectChange" class="fiveRow-table" />
2719 <div class="row-add-btn">
2720 <el-button link @click="addSortParams" :icon="CirclePlus" v-preReClick>添加</el-button>
2721 </div>
2722 </ContentWrap>
2723 </template>
2724 <template v-else-if="apiType == '2'">
2725 <ContentWrap id="id-dsInfo" title="数据源" description="">
2726 <Form ref="tableInfoFormRef" :itemList="[tableFormItems[1]]" formId="table-base-form"
2727 :rules="tableFormRules" col="col3" @select-change="handleTableFormSelectChange" />
2728 </ContentWrap>
2729 <ContentWrap id="id-sqlInfo" title="sql" description="" class="mt16">
2730 <Form ref="sqlInfoFormRef" :itemList="sqlFormItems" formId="table-base-form" :rules="sqlFormRules"
2731 @inputChange="sqlFormInputChange" />
2732 </ContentWrap>
2733 </template>
2734 <template v-else-if="apiType == '3'">
2735 <ContentWrap id="id-backApiInfo" title="注册API信息" description="">
2736 <Form ref="backApiInfoFormRef" :itemList="backApiFormItems" formId="table-base-form"
2737 :rules="backApiFormRules" col="col3" />
2738 </ContentWrap>
2739 <ContentWrap id="id-registRequestParams" title="请求参数" description="" class="mt16">
2740 <Table ref="registRequestParamsTableRef" :tableInfo="registRequestParamsTableInfo" class="fiveRow-table" />
2741 <div class="row-add-btn">
2742 <el-button link @click="addRegistRequestParams" :icon="CirclePlus" v-preReClick>添加</el-button>
2743 </div>
2744 </ContentWrap>
2745 <ContentWrap id="id-constParams" title="常量参数" description="" class="mt16">
2746 <Table ref="constParamsTableRef" :tableInfo="constParamsTableInfo" class="fiveRow-table" />
2747 <div class="row-add-btn">
2748 <el-button link @click="addConstParams" :icon="CirclePlus" v-preReClick>添加</el-button>
2749 </div>
2750 </ContentWrap>
2751 </template>
2752 </div>
2753 <div class="operator_panel_wrap" v-show="step == 2">
2754 <ContentWrap id="id-api" title="API" description="">
2755 <Form ref="apiInfoFormRef" style="width: 70%" :itemList="apiFormItems" formId="api-base-form" col="col2" />
2756 </ContentWrap>
2757 <ContentWrap id="id-queryParams" title="QUERY" description="" class="mt16">
2758 <Table :tableInfo="queryParamsTableInfo" class="mb10" />
2759 </ContentWrap>
2760 <ContentWrap id="id-defaultParams" title="DEFAULT" description="" class="mt16">
2761 <Table :tableInfo="defaultParamsTableInfo" class="mb10" />
2762 </ContentWrap>
2763 <ContentWrap id="id-test" title="测试API" description="" class="mt16">
2764 <el-button :loading="startTestApiBtnLoading" @click="startTestApi" class="mb10">开始测试</el-button>
2765 <Form ref="resultInfoFormRef" :itemList="resultFormItems" formId="result-base-form" col="col2" />
2766 </ContentWrap>
2767 </div>
2768 <ContentWrap title="流程审批" v-show="needApprove" description="" :isExpand="flowExpand" :expand-swicth="true" class="mt16"
2769 @expand="(v) => flowExpand = v">
2770 <ApprovalProcess v-if="deploymentId" :deploymentId="deploymentId" :definitionId="''">
2771 </ApprovalProcess>
2772 </ContentWrap>
2773 </div>
2774 <!-- <FlowBtnGroup v-show="step == 2" pageType="add" :approveVO="bizApproveVO" @save="save"></FlowBtnGroup> -->
2775 <div class="bottom_tool_wrap">
2776 <template v-if="step == 0">
2777 <el-button @click="cancel">取消</el-button>
2778 <el-button type="primary" @click="nextStep(1)">下一步</el-button>
2779 </template>
2780 <template v-else-if="step == 1">
2781 <el-button @click="cancel">取消</el-button>
2782 <el-button type="primary" @click="previousStep(1)">上一步</el-button>
2783 <el-button type="primary" @click="nextStep(2)">下一步</el-button>
2784 </template>
2785 <template v-else>
2786 <el-button @click="cancel">取消</el-button>
2787 <el-button type="primary" @click="previousStep(2)">上一步</el-button>
2788 <el-button v-if="!isDetail" type="primary" @click="save()">保存</el-button>
2789 <el-button v-if="!isDetail" type="primary" @click="save(true)">保存并提交</el-button>
2790 </template>
2791 <!-- <template v-if="pageType == 'add'">
2792 <template v-if="approveVO && approveVO.approveState == 'N'">
2793 <el-button type="" @click="save(false)">保存草稿</el-button>
2794 </template>
2795 <template v-if="!approveVO">
2796 <el-button type="" @click="save(false)">保存草稿</el-button>
2797 </template>
2798 <el-button type="primary" @click="save(true)">提交流程</el-button>
2799 </template> -->
2800 </div>
2801 </div>
2802 </template>
2803
2804 <style lang="scss" scoped>
2805 .top_tool_wrap {
2806 width: 100%;
2807 height: 72px;
2808 margin: 8px 0 0px;
2809 display: flex;
2810 justify-content: center;
2811 align-items: center;
2812
2813 :deep(.el-steps) {
2814 width: 50%;
2815 justify-content: center;
2816 }
2817 }
2818
2819 .content_main {
2820 height: calc(100% - 40px);
2821 padding: 0 16px 16px;
2822 overflow: hidden auto;
2823
2824 .operator_panel_wrap {
2825 height: auto;
2826
2827 .row-add-btn {
2828 .el-button--default {
2829 padding: 4px 0px;
2830 margin: 8px 0px;
2831 }
2832
2833 :deep(.el-icon) {
2834 width: 16px;
2835 height: 16px;
2836
2837 svg {
2838 width: 16px;
2839 height: 16px;
2840 }
2841 }
2842 }
2843 }
2844
2845 }
2846
2847 :deep(.el-form) {
2848 .select-input-long {
2849 .el-form-item:first-child {
2850 width: 100px;
2851 margin-right: 0px;
2852 }
2853
2854 .el-form-item:last-child {
2855 width: calc(100% - 100px);
2856 margin-right: 0px;
2857
2858 .item-label {
2859 white-space: pre;
2860
2861 .required_mark::after {
2862 content: '';
2863 }
2864 }
2865 }
2866 }
2867 }
2868
2869 .bottom_tool_wrap {
2870 height: 40px;
2871 padding: 0 16px;
2872 border-top: 1px solid #d9d9d9;
2873 display: flex;
2874 justify-content: flex-end;
2875 align-items: center;
2876 }
2877
2878 .mb10 {
2879 margin-bottom: 10px;
2880 }
2881
2882 .mt16 {
2883 margin-top: 16px;
2884 }
2885
2886 .fiveRow-table {
2887 :deep(.el-table) {
2888 .el-table__empty-block {
2889 height: 182px !important;
2890 }
2891 }
2892 }
2893
2894 #id-test {
2895 :deep(.el-form) {
2896 .el-textarea .el-textarea__inner {
2897 overflow-wrap: break-word;
2898 white-space: pre-wrap;
2899 word-break: break-all;
2900 }
2901 }
2902 }
2903 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <route lang="yaml">
2 name: processDetail
3 </route>
4
5 <script lang="ts" setup name="processDetail">
6 import { ref } from "vue";
7 import { ElMessage, ElMessageBox } from "element-plus";
8 import { CircleCloseFilled } from '@element-plus/icons-vue'
9 import useUserStore from "@/store/modules/user";
10 import { useRoute } from "vue-router";
11 import detail_serviceApi from './detail_serviceApi.vue';
12 import Dialog from "@/components/Dialog/index.vue";
13
14 import { getCamundaDeploymentId,getDetailDataPromise,getProcessFlowDetail, passFlowData, rejectFlowData, revokeFlowData } from "@/api/modules/workFlowService";
15
16 const route = useRoute();
17
18 const fullPath = route.fullPath;
19 const deploymentId = ref('');
20
21 const guid = route.query.guid as string;
22
23 const detailType = <string>route.query.type || '';
24
25 const reason = ref('')
26 const toolBtns: any = ref([])
27
28 const emits = defineEmits([
29 "tableSelectChange",
30 "tableBtnClick",
31 ]);
32
33 const { proxy } = getCurrentInstance() as any
34
35 const userStore = useUserStore()
36 const userData = JSON.parse(userStore.userData)
37
38 const srcs = ref('')
39
40 const flowDetail: any = ref({});
41 const flowDetailLoading = ref(false);
42
43 const bizGuid = ref('');
44
45 const contents = ref({
46 pass: [
47 {
48 type: 'form',
49 title: '',
50 formInfo: {
51 id: 'batch-pass-form',
52 items: [
53 {
54 label: '',
55 type: "textarea",
56 placeholder: "请填写通过备注(选填)",
57 field: "approveSuggest",
58 clearable: true,
59 block: true,
60 col: 'margin_b_0',
61 }
62 ]
63 }
64 }
65 ],
66 reject: [
67 {
68 type: 'form',
69 title: '',
70 formInfo: {
71 id: 'batch-reject-form',
72 items: [
73 {
74 label: '',
75 type: "textarea",
76 placeholder: "请填写驳回理由(必填)",
77 field: "approveSuggest",
78 clearable: true,
79 block: true,
80 col: 'margin_b_0',
81 }
82 ]
83 }
84 }
85 ],
86 });
87 const dialogInfo = ref({
88 visible: false,
89 size: 460,
90 direction: "column",
91 header: {
92 title: "",
93 },
94 type: '',
95 contents: [],
96 footer: {
97 btns: [
98 { type: "default", label: "取消", value: "cancel" },
99 { type: "primary", label: "确定", value: "submit" },
100 ],
101 },
102 });
103
104 const getProcessDetail = () => {
105 if (!flowDetailLoading.value) {
106 flowDetailLoading.value = true
107 }
108 getCamundaDeploymentId('10023').then((res: any) => {
109 flowDetailLoading.value = false
110 if (res.code == proxy.$passCode) {
111 if (res.code == proxy.$passCode) {
112 deploymentId.value = res.data;
113 } else {
114 proxy.$ElMessage.error(res.msg);
115 }
116 } else {
117 proxy.$ElMessage.error(res.msg);
118 }
119 })
120 // getProcessFlowDetail(guid).then((res: any) => {
121 // flowDetailLoading.value = false;
122 // if (res.code == proxy.$passCode) {
123 // let detail = res.data || {};
124 // if(Object.keys(detail).length == 0){
125 // ElMessage({
126 // type: 'error',
127 // message: '流程不存在'
128 // })
129 // return
130 // }
131 // flowDetail.value = detail;
132 // srcs.value = `${import.meta.env.VITE_BPMN_URL}/daopIframeBpmn?token=${userStore.token}&processInstanceId=${detail.camundaInstanceId}&camundaDeploymentId=${detail.camundaDeploymentId}`
133 // bizGuid.value = detail.bizGuid || '';
134 // let tab: any = userStore.tabbar.find((tab: any) => tab.fullPath === fullPath);
135 // if (tab) {
136 // tab.meta.title = `流程详情-${detail.functionName}`;
137 // }
138 // if (detailType !== 'detail') {
139 // const btnsArr: any = []
140 // if (detail.approveState == 'A') {
141 // if (detail.approveStaffGuids && detail.approveStaffGuids.indexOf(userData.staffGuid) > -1) {
142 // btnsArr.splice(0, 1, { label: "驳回", value: "reject", type: 'danger', plain: true }, { label: "通过", value: "pass", type: 'primary' })
143 // }
144 // if (detail.staffGuid && detail.staffGuid == userData.staffGuid) {
145 // btnsArr.push({ label: "撤销", value: "revoke" })
146 // }
147 // }
148 // toolBtns.value = btnsArr
149 // }
150 // } else {
151 // ElMessage.error(res.msg);
152 // }
153 // }).catch(() => {
154 // flowDetailLoading.value = false;
155 // })
156 }
157
158 const btnClick = (btn) => {
159 const type = btn.value
160 if (type == 'pass' || type == 'reject') {
161 dialogInfo.value.type = type
162 dialogInfo.value.header.title = type == 'pass' ? '通过备注' : '驳回理由'
163 dialogInfo.value.contents = contents.value[type]
164 dialogInfo.value.visible = true
165 } else if (type == 'revoke') {
166 ElMessageBox.confirm('确定撤销吗?', "提示", {
167 confirmButtonText: "确定",
168 cancelButtonText: "取消",
169 type: type,
170 }).then(() => {
171 flowDetailLoading.value = true;
172 let params = {
173 guid: flowDetail.value.guid,
174 flowType: flowDetail.value.flowType,
175 approveSuggest: '',
176 approveStaffGuid: userData.staffGuid
177 }
178 revokeFlowData(params).then((res: any) => {
179 if (res.code == proxy.$passCode) {
180 getProcessDetail()
181 ElMessage({
182 type: 'success',
183 message: '撤销成功'
184 })
185 } else {
186 ElMessage({
187 type: 'error',
188 message: res.msg
189 })
190 flowDetailLoading.value = false;
191 }
192 }).catch(() => {
193 flowDetailLoading.value = false;
194 })
195 })
196 }
197 }
198
199 const dialogBtnClick = (btn, info) => {
200 if (btn.value == 'submit') {
201 let params = { ...info }
202 params.guid = flowDetail.value.guid
203 params.flowType = flowDetail.value.flowType
204 params.approveStaffGuid = userData.staffGuid
205 if (dialogInfo.value.type == 'pass') {
206 dialogInfo.value.visible = false;
207 flowDetailLoading.value = true;
208 passFlowData(params).then((res: any) => {
209 if (res.code == proxy.$passCode) {
210 getProcessDetail();
211 ElMessage({
212 type: 'success',
213 message: '审批成功'
214 })
215 } else {
216 ElMessage({
217 type: 'error',
218 message: res.msg,
219 })
220 flowDetailLoading.value = false;
221 }
222 }).catch(() => {
223 flowDetailLoading.value = false;
224 })
225 } else if (dialogInfo.value.type == 'reject') {
226 if (info.approveSuggest == '') {
227 ElMessage.error('请填写驳回理由')
228 return
229 }
230 dialogInfo.value.visible = false;
231 flowDetailLoading.value = true;
232 rejectFlowData(params).then((res: any) => {
233 if (res.code == proxy.$passCode) {
234 getProcessDetail();
235 ElMessage({
236 type: 'success',
237 message: '驳回成功'
238 })
239 dialogInfo.value.visible = false;
240 } else {
241 ElMessage({
242 type: 'error',
243 message: res.msg,
244 })
245 flowDetailLoading.value = false;
246 }
247 }).catch(() => {
248 flowDetailLoading.value = false;
249 })
250 }
251 } else if (btn.value == 'cancel') {
252 dialogInfo.value.visible = false;
253 }
254 };
255
256 onBeforeMount(() => {
257 getProcessDetail();
258 })
259
260 </script>
261
262 <template>
263 <div class="container_wrap" v-loading="flowDetailLoading">
264 <div class="content_main" :class="{ full: toolBtns.length == 0 }">
265 <div class="panel_wrap">
266 <div class="panel_header">
267 <div class="header_title">
268 <span class="title_text">申请内容</span>
269 </div>
270 </div>
271 <div class="panel_body">
272 <div class="list_panel">
273 <detail_serviceApi :apiGuid="guid"></detail_serviceApi>
274 </div>
275 </div>
276 </div>
277 <div class="panel_wrap">
278 <div class="panel_header">
279 <div class="header_title">
280 <span class="title_text">审批操作</span>
281 </div>
282 </div>
283 <div class="panel_body">
284 <div class="process_panel" v-if="!flowDetailLoading">
285 <ApprovalProcess v-if="deploymentId" :deploymentId="deploymentId" :definitionId="''">
286 </ApprovalProcess>
287 </div>
288 </div>
289 </div>
290 </div>
291 <div class="tool_btns" v-if="toolBtns.length">
292 <div class="btns">
293 <el-button v-for="btn in toolBtns" :type="btn.type" :plain="btn.plain" @click="btnClick(btn)">{{ btn.label
294 }}</el-button>
295 </div>
296 </div>
297
298 <Dialog :dialogInfo="dialogInfo" @btnClick="dialogBtnClick" />
299 </div>
300 </template>
301
302 <style lang="scss" scoped>
303 .container_wrap {
304 padding: 0;
305 height: 100%;
306 overflow: hidden;
307
308 &>.content_main {
309 padding: 16px;
310 height: calc(100% - 44px);
311 overflow: hidden auto;
312
313 &.full {
314 height: 100%;
315 }
316 }
317 }
318
319 .panel_wrap {
320 .panel_header {
321 .header_title {
322 height: 40px;
323 padding: 0 16px;
324 background-color: #fafafa;
325 box-shadow: 0 0 0 1px rgba(229, 229, 229, 1);
326 display: flex;
327 align-items: center;
328 }
329
330 .title_text {
331 line-height: 22px;
332 font-size: 14px;
333 color: var(--el-color-regular);
334 font-weight: 600;
335 }
336 }
337
338 .panel_body {
339 padding: 8px 16px;
340 box-shadow: 0 0 0 1px rgba(229, 229, 229, 1);
341 border-top: none;
342 margin-top: 1px;
343
344 .list_panel {
345 display: flex;
346 flex-wrap: wrap;
347
348 .list_item {
349 width: 33.33%;
350 line-height: 32px;
351 font-size: 14px;
352 color: #666666;
353 display: flex;
354 justify-content: space-between;
355
356 .item_label {
357 width: 100px;
358 text-align: right;
359 }
360
361 .item_value {
362 color: var(--el-color-regular);
363 padding: 0 16px;
364 flex: 1;
365 text-align: justify;
366 }
367
368 &.is_block {
369 width: 100%;
370 }
371 }
372
373 :deep(.panel_body) {
374 box-shadow: none;
375 }
376 }
377
378 .table_panel_wrap {
379 .table_panel {
380 padding: 0;
381 min-height: unset;
382 }
383 }
384
385 .process_panel {
386 height: 500px;
387
388 .iframe-sty {
389 width: 100%;
390 height: 100%;
391 border: none;
392 }
393
394 :deep(.property-panel) {
395 height: calc(100% - 50px) !important;
396 }
397 }
398
399 }
400
401 +.panel_wrap {
402 margin-top: 16px;
403 }
404
405 &.results_panel {
406 box-shadow: 0 0 0 1px #d9d9d9;
407
408 .panel_header {
409 .header_title {
410 background-color: transparent;
411 box-shadow: none;
412
413 .el-icon {
414 margin-right: 8px;
415 width: 20px;
416 height: 20px;
417
418 svg {
419 width: 100%;
420 height: 100%;
421 }
422 }
423 }
424 }
425
426 .panel_body {
427 padding-top: 0;
428 margin-top: 0;
429 box-shadow: none;
430
431 .results_list {
432 display: flex;
433
434 .list_item {
435 display: flex;
436 margin-bottom: 8px;
437 margin-right: 60px;
438 color: #666;
439
440 .item_value {
441 padding: 0 8px;
442 color: var(--el-color-regular);
443 }
444 }
445 }
446 }
447
448 &.success {
449 background-color: #F4FEF6;
450 box-shadow: 0 0 0 1px #4FA55D;
451
452 .panel_header {
453 .header_title {
454 .el-icon {
455 color: #4FA55D;
456 }
457 }
458 }
459 }
460
461 &.reject {
462 background-color: #FDF2F4;
463 box-shadow: 0 0 0 1px #E63E33;
464
465 .panel_header {
466 .header_title {
467 .el-icon {
468 color: #E63E33;
469 }
470 }
471 }
472 }
473
474 &.audit {
475 background-color: #FEFBF3;
476 box-shadow: 0 0 0 1px #F19E40;
477
478 .panel_header {
479 .header_title {
480 .el-icon {
481 color: #F19E40;
482 }
483 }
484 }
485 }
486
487 &.revoke {
488 background-color: #F5F5F5;
489 box-shadow: 0 0 0 1px #CCCCCC;
490
491 .panel_header {
492 .header_title {
493 .el-icon {
494 color: #666666;
495 }
496 }
497 }
498 }
499 }
500 }
501
502 .tool_btns {
503 display: flex;
504 justify-content: center;
505 align-items: center;
506 height: 44px;
507 padding: 0 16px;
508 box-shadow: 0 -1px 0 0 #d9d9d9;
509 }
510 </style>
511
...\ No newline at end of file ...\ No newline at end of file
1 <route lang="yaml">
2 name: apiManagement
3 </route>
4
5 <script lang="ts" setup name="apiManagement">
6 import { ref } from 'vue';
7 import { TableColumnWidth } from '@/utils/enum';
8 import { commonPageConfig } from '@/components/PageNav/index';
9 import TableTools from '@/components/Tools/table_tools.vue'
10 import { useValidator } from '@/hooks/useValidator';
11 import { useRouter, useRoute } from "vue-router";
12 import { isNeedApprove, passFlowData, rejectFlowData, revokeFlowData } from "@/api/modules/workFlowService";
13 import {
14 apiTypes,
15 getAPIList,
16 updateAPIState,
17 addApiApprove,
18 deleteApi,
19 copyApi,
20 checkExistAPIName,
21 } from "@/api/modules/dataService";
22 import useDataServiceStore from "@/store/modules/dataService";
23 import useUserStore from "@/store/modules/user";
24
25 const router = useRouter();
26 const dataServiceStore = useDataServiceStore();
27 const { required, chOrEnPreffix, regexpValidate, checkExistName } = useValidator();
28 const userStore = useUserStore()
29 const userData = JSON.parse(userStore.userData)
30 const { proxy } = getCurrentInstance() as any;
31
32 onBeforeMount(() => {
33 //TODO,需要调用isNeedApprove接口判断是否需要审批,判断是否显示审批列
34 getTableData();
35 });
36
37 onActivated(() => {
38 /** 若是新建则默认选中对应的标签展示列表。 */
39 if (dataServiceStore.isUpdate) {
40 getTableData();
41 dataServiceStore.setIsUpdate(false);
42 }
43 })
44
45 const APIDataPage: any = ref({
46 ...commonPageConfig, apiType: '',
47 apiName: '',//API标签名称搜索。
48 approveState: ''
49 });
50
51 /** api管理列表表格数据上方搜索区域 */
52 const tableSearchItemList: any = ref([
53 {
54 type: 'input',
55 label: '',
56 field: 'apiName',
57 default: '',
58 placeholder: 'API名称',
59 maxlength: 50,
60 clearable: true
61 }, {
62 type: 'select',
63 label: '',
64 field: 'apiType',
65 default: '',
66 placeholder: 'API类型',
67 options: apiTypes,
68 clearable: true
69 }, {
70 type: 'select',
71 label: '',
72 field: 'approveState',
73 default: '',
74 placeholder: '全部状态',
75 options: [
76 { label: '草稿中', value: 'N' },
77 { label: '审批中', value: 'A' },
78 { label: '已通过', value: 'Y' },
79 { label: '已驳回', value: 'R' },
80 { label: '已撤销', value: 'C' },
81 ],
82 clearable: true
83 }
84 ]);
85
86 const getTableData = () => {
87 tableInfo.value.loading = true;
88 getAPIList({
89 // tagGuid: lastClickNode.value.guid,
90 pageSize: APIDataPage.value.limit,
91 pageIndex: APIDataPage.value.curr,
92 apiName: APIDataPage.value.apiName,
93 apiType: APIDataPage.value.apiType,
94 approveState: APIDataPage.value.approveState
95 }).then((res: any) => {
96 tableInfo.value.loading = false;
97 if (res.code == proxy.$passCode) {
98 const data = res.data || {};
99 tableInfo.value.data = data.records || []
100 tableInfo.value.page.limit = data.pageSize
101 tableInfo.value.page.curr = data.pageIndex
102 tableInfo.value.page.rows = data.totalRows
103 } else {
104 proxy.$ElMessage.error(res.msg);
105 }
106 })
107 }
108
109 const toTableSearch = (val, clear) => {
110 APIDataPage.value.curr = 1;
111 if (clear) {
112 APIDataPage.value.apiType = '';
113 APIDataPage.value.apiName = '';
114 APIDataPage.value.dataState = null;
115 APIDataPage.value.approveState = '';
116 getTableData();
117 return;
118 }
119 APIDataPage.value.apiType = val.apiType;
120 APIDataPage.value.apiName = val.apiName;
121 if (!val.approveState) {
122 APIDataPage.value.approveState = '';
123 } else {
124 APIDataPage.value.approveState = val.approveState;
125 }
126 getTableData();
127 }
128
129 const handleAPICreateCommand = (command: string) => {
130 router.push({
131 name: 'apiCreate',
132 query: {
133 type: command,
134 }
135 });
136 }
137
138 /** 记录正在提交审批流程的api,防止重复提交 */
139 const addApprovePromise = ref({});
140 const selectRowData: any = ref([])
141 const currTableData: any = ref({});
142 const tableInfo = ref({
143 id: 'api-data-table',
144 rowKey: 'guid',
145 loading: false,
146 multiple: false,
147 fields: [
148 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
149 { label: "API名称", field: "apiName", width: 140, align: "left" },
150 {
151 label: "API类型", field: "apiType", width: 100, align: "left", getName: (scope) => {
152 return apiTypes.find(a => a.value == scope.row.apiType)?.label;
153 }
154 },
155 {
156 label: "调用次数", field: "invokeCount", width: 100, align: 'right', type: 'chnum'
157 },
158 {
159 label: "调用异常数", field: "invokeErrorCount", width: 105, align: 'right', type: 'chnum'
160 },
161 {
162 label: "平均响应时间(s)", field: "averageRespTime", width: 130, align: 'right', type: 'chnum'
163 },
164 { label: "API请求路径", field: "requestUrl", width: TableColumnWidth.DESCRIPTION },
165 {
166 label: '状态', field: 'apiState', type: 'switch', activeText: '启用', inactiveText: '停用', activeValue: 1, inactiveValue: 0, switchWidth: 56, width: 96, align: 'center', isDisabled: (scope) => {
167 if (scope.row.apiState == 1 && scope.row.bindingCount > 0) {//被授权的不能禁用。
168 return true;
169 }
170 return scope.row.approveState != 'Y';//正在审批中的不能停用。草稿中的不能启用。
171 }
172 },
173 { label: "审批状态", field: "approveState", type: "tag", width: TableColumnWidth.STATE, align: 'center' },
174 { label: "API描述", field: "apiDescription", width: TableColumnWidth.DESCRIPTION },
175 { label: "修改人", field: "updateUserName", width: TableColumnWidth.USERNAME },
176 { label: "修改时间", field: "updateTime", width: 170 },
177 ],
178 data: [],
179 page: {
180 type: "normal",
181 rows: 0,
182 ...APIDataPage.value,
183 },
184 actionInfo: {
185 label: "操作",
186 type: "btn",
187 isMore: false,
188 width: 200,
189 btns: (scope) => {
190 const { row } = scope;
191 let list: any = [];
192 const approveVO = row.approveVO || {};
193 if (!approveVO && row.isApprove == 'N') {
194 list.push({ label: "编辑", value: "edit", click: apiManageTableBtnMap.EDIT });
195 list.push({ label: "删除", value: "del", click: apiManageTableBtnMap.DELETE });
196 list.push({ label: "详情", value: "detail", click: apiManageTableBtnMap.DETAIL });
197 list.push({ label: "复制", value: "copy", click: apiManageTableBtnMap.COPY })
198 return list;
199 }
200 const currentStaffGuid = userData.staffGuid
201 const bizApproveState = row.bizApproveState;
202 const approveState = approveVO.approveState || null;
203 const approveStaffGuids = approveVO.approveStaffGuids || [];
204 const staffGuid = approveVO.staffGuid || '';
205 let isShowCancel = false;
206 let flowState;
207 if (approveState == 'N') {
208 flowState = 1;
209 }
210 if (approveState == 'A' && approveStaffGuids.indexOf(currentStaffGuid) > -1) {
211 flowState = 2;
212 }
213 if ((approveState == 'C' || approveState == 'R') && staffGuid == currentStaffGuid) {
214 flowState = 3;
215 }
216 if (approveVO && approveVO.approveState == 'A' && staffGuid == currentStaffGuid) {
217 isShowCancel = true;
218 }
219 if (flowState === 1) {
220 list = [{ label: "编辑", value: "edit", click: apiManageTableBtnMap.EDIT }]
221 }
222 if (flowState === 2) {
223 list = [{ label: "通过", value: "pass", click: apiManageTableBtnMap.PASS }, { label: "驳回", value: "reject", click: apiManageTableBtnMap.REJECT }]
224 }
225 if (approveState == 'Y' && row.apiState != 1 && staffGuid == currentStaffGuid) {
226 list = [{ label: "编辑", value: "edit", click: apiManageTableBtnMap.EDIT }]
227 }
228 if (flowState === 3 || (row.apiState != 1 && approveState !== 'A')) {
229 list.push({ label: "删除", value: "del", click: apiManageTableBtnMap.DELETE })
230 }
231 if (flowState === 3 && bizApproveState != 'D') {
232 list.push({ label: "重新提交", value: "redit", click: apiManageTableBtnMap.EDIT })
233 }
234 if (isShowCancel) {
235 list.push({ label: "撤销", value: "revoke", click: apiManageTableBtnMap.REVOKE })
236 }
237 if (flowState !== 1) {
238 list.push({ label: "详情", value: "detail", click: apiManageTableBtnMap.DETAIL })
239 }
240 list.push({ label: "复制", value: "copy", click: apiManageTableBtnMap.COPY })
241 return list
242 },
243 }
244 });
245
246 /** api管理表格的操作按钮事件。 */
247 const apiManageTableBtnMap = {
248 /** 编辑 */
249 EDIT: (scope) => {
250 router.push({
251 name: 'apiCreate',
252 query: {
253 guid: scope.row.guid,
254 apiName: scope.row.apiName,
255 // tagGuid: lastClickNode.value.guid
256 }
257 });
258 },
259 /** 详情 */
260 DETAIL: (scope) => {
261 let row = scope.row;
262 if (!row.approveGuid) {
263 proxy.$ElMessage.error(`【${row.apiName}】关联流程已删除!`);
264 return;
265 }
266 router.push({
267 name: 'APIProcessDetail',
268 query: { guid: row.approveGuid, type: 'detail' }
269 });
270 },
271 /** 撤回 */
272 REVOKE: (scope) => {
273 proxy.$openMessageBox('确定撤销该API审批吗?', () => {
274 let params = {
275 guid: scope.row.approveGuid,
276 approveStaffGuid: userData.staffGuid
277 }
278 revokeFlowData(params).then((res: any) => {
279 if (res.code == proxy.$passCode) {
280 getTableData();
281 proxy.$ElMessage.success('撤销成功');
282 } else {
283 proxy.$ElMessage.error(res.msg);
284 }
285 })
286 }, () => {
287 proxy.$ElMessage({
288 type: 'info',
289 message: '已取消撤销'
290 });
291 });
292 },
293 SUBMIT: (scope) => {
294 if (addApprovePromise.value[scope.row.guid]) {
295 return;
296 }
297 addApprovePromise.value[scope.row.guid] = addApiApprove(scope.row.guid).then((res: any) => {
298 delete addApprovePromise.value[scope.row.guid];
299 if (res.code == proxy.$passCode) {
300 getTableData();
301 proxy.$ElMessage({
302 type: 'success',
303 message: '该API提交成功'
304 })
305 } else {
306 proxy.$ElMessage.error(res.msg);
307 }
308 })
309 },
310 PASS: (scope) => {
311 approveSuggest.value = '';
312 approveType.value = 'pass';
313 dialogTitle.value = '通过理由'
314 dialogVisible.value = true;
315 },
316 REJECT: (scope) => {
317 approveSuggest.value = '';
318 approveType.value = 'reject';
319 dialogTitle.value = '驳回理由'
320 dialogVisible.value = true;
321 },
322 DELETE: (scope) => {
323 proxy.$openMessageBox("确定要删除该API吗?", () => {
324 deleteApi(scope.row.guid).then((res: any) => {
325 if (res.code == proxy.$passCode) {
326 APIDataPage.value.curr = 1;
327 getTableData();
328 proxy.$ElMessage.success('删除该API提交成功');
329 } else {
330 proxy.$ElMessage.error(res.msg);
331 }
332 });
333 })
334 },
335 COPY: (scope) => {
336 currTableData.value = scope.row;
337 copyApiFormItems.value[0].default = scope.row.apiName + '_copy';
338 copyApiFormItems.value[1].children && (copyApiFormItems.value[1].children[1].default = scope.row.requestPath + '-copy');
339 copyApiDialogInfo.value.formInfo.items = copyApiFormItems.value;
340 copyApiDialogInfo.value.visible = true;
341 }
342 }
343
344 const approveSuggest = ref();
345 const dialogTitle = ref('通过理由');
346 const dialogVisible = ref(false);
347 //弹窗类型
348 const approveType = ref();
349
350 const passSubmit = () => {
351 let row = currTableData.value
352 dialogVisible.value = false;
353 tableInfo.value.loading = true;
354 passFlowData({
355 guid: row.approveVO.approveGuid,
356 flowType: row.approveVO.flowType,
357 approveSuggest: approveSuggest.value,
358 approveStaffGuid: userData.staffGuid,
359 }).then((res: any) => {
360 tableInfo.value.loading = false;
361 if (res.code == '00000') {
362 proxy.$ElMessage.success('审批通过!')
363 getTableData();
364 } else {
365 proxy.$ElMessage.error(res.msg)
366 }
367 })
368
369 }
370 const rejectSubmit = () => {
371 if (!approveSuggest.value) return proxy.$ElMessage.error('请填写驳回理由!')
372 let row = currTableData.value
373 dialogVisible.value = false;
374 tableInfo.value.loading = true;
375 rejectFlowData({
376 guid: row.approveVO.approveGuid,
377 flowType: row.approveVO.flowType,
378 approveSuggest: approveSuggest.value,
379 approveStaffGuid: userData.staffGuid,
380 }).then((res: any) => {
381 if (res.code == '00000') {
382 tableInfo.value.loading = false;
383 proxy.$ElMessage.success('驳回成功!')
384 getTableData();
385 } else {
386 proxy.$ElMessage.error(res.msg)
387 }
388 })
389 }
390
391 const apiTablePageChange = (info) => {
392 APIDataPage.value.curr = Number(info.curr);
393 APIDataPage.value.limit = Number(info.limit);
394 tableInfo.value.page.limit = APIDataPage.value.limit;
395 tableInfo.value.page.curr = APIDataPage.value.curr;
396 getTableData();
397 };
398
399 const tableSwitchBeforeChange = (scope, field, callback) => {
400 const msg = `确定【${scope.row[field] == 1 ? '停用' : '启用'}】该API吗?`;
401 proxy.$openMessageBox(msg, () => {
402 const state = scope.row[field] == 1 ? 0 : 1
403 const result = tableSwitchChange(state, scope, field)
404 callback(result)
405 }, () => {
406 callback(false)
407 });
408 }
409
410 const tableSwitchChange = (val, scope, field) => {
411 return new Promise((resolve, reject) => {
412 let params = {
413 guid: scope.row.guid,
414 apiState: val
415 }
416 updateAPIState(params).then((res: any) => {
417 if (res.code == proxy.$passCode && res.data) {
418 getTableData();
419 proxy.$ElMessage({
420 type: "success",
421 message: `该API${val == 1 ? '启用' : '停用'}成功`,
422 });
423 resolve(true)
424 } else {
425 proxy.$ElMessage({
426 type: "error",
427 message: res.msg,
428 });
429 getTableData();
430 reject(false)
431 }
432 }).catch(() => {
433 getTableData();
434 reject(false)
435 })
436 })
437 }
438
439 const tableSelectionChange = (val) => {
440 selectRowData.value = val;
441 };
442
443 /** -------------- 复制功能 ------------------- */
444 const copyApiFormItems = ref([{
445 type: 'input',
446 label: 'API名称',
447 field: 'apiName',
448 default: '',
449 regexp: /[^a-zA-Z0-9_\u4e00-\u9fa5-]/g,
450 block: true,
451 placeholder: '请输入',
452 maxlength: 50,
453 clearable: true,
454 required: true
455 }, {
456 type: "select-group",
457 field: "httpInfo",
458 col: ' select-input-long-reverse',
459 block: true,
460 children: [
461 {
462 label: "API请求路径",
463 type: "input",
464 placeholder: "请选择",
465 default: "https",
466 field: "httpType",
467 required: true,
468 disabled: true,
469 visible: true,
470 },
471 {
472 label: " ",
473 type: "input",
474 placeholder: "请输入",
475 default: '/',
476 field: "requestPath",
477 maxlength: 50,
478 required: true,
479 visible: true,
480 },
481 ],
482 visible: true
483 }]);
484
485 /** 记录已检验过的APIName */
486 const checkedInfo = ref({});
487
488 const copyApiFormRules = ref({
489 apiName: [required("请填写API名称"), chOrEnPreffix(), checkExistName(checkedInfo.value, checkExistAPIName, '')],
490 requestPath: [required("请填写请求路径"), regexpValidate(/^\/[^\/][\w\u4e00-\u9fa5_-]*$/, '请输入合法的请求路径')],
491 });
492
493 const copyApiDialogInfo = ref({
494 visible: false,
495 size: 480,
496 title: "复制API",
497 type: 'add',
498 formInfo: {
499 id: 'add-authorize-form',
500 items: copyApiFormItems.value,
501 rules: copyApiFormRules.value
502 },
503 btns: {
504 submit: (btn, info) => {
505 info.guid = currTableData.value.guid;
506 copyApiDialogInfo.value.submitBtnLoading = true;
507 copyApi(info).then((res: any) => {
508 copyApiDialogInfo.value.submitBtnLoading = false;
509 if (res.code == proxy.$passCode) {
510 APIDataPage.value.curr = 1;
511 getTableData();
512 proxy.$ElMessage({
513 type: 'success',
514 message: `【${info.apiName}】API复制成功`
515 })
516 copyApiDialogInfo.value.visible = false;
517 } else {
518 proxy.$ElMessage.error(res.msg);
519 }
520 })
521 },
522 cancel: () => {
523 copyApiDialogInfo.value.visible = false;
524 }
525 },
526 submitBtnLoading: false
527 });
528
529 </script>
530
531 <template>
532 <div class="container_wrap full flex">
533 <div class="main_wrap">
534 <div class="table_tool_wrap">
535 <TableTools ref="tableTools" :searchItems="tableSearchItemList" :init="false" :searchId="'api-table-search'"
536 @search="toTableSearch" />
537 <div class="tools_btns">
538 <el-dropdown popper-class="table-create-menu" @command="handleAPICreateCommand" placement="bottom-start"
539 trigger="click">
540 <span class="el-dropdown-link">
541 <el-button type="primary">新建API</el-button>
542 </span>
543 <template #dropdown>
544 <el-dropdown-menu>
545 <el-dropdown-item command="1">
546 <el-icon style="width: 24px;height: 24px;">
547 <svg-icon style="width: 24px;height: 24px;" name="api-single-table" />
548 </el-icon>
549 <div class="item-content">
550 <span class="item-content-title">单表API</span>
551 <span class="item-content-desc">选单表中的字段进行对外输出</span>
552 </div>
553 </el-dropdown-item>
554 <el-dropdown-item command="2">
555 <el-icon style="width: 24px;height: 24px;">
556 <svg-icon style="width: 24px;height: 24px;" name="api-sql" />
557 </el-icon>
558 <div class="item-content">
559 <span class="item-content-title">自定义sql</span>
560 <span class="item-content-desc">对复杂接口的配置</span>
561 </div>
562 </el-dropdown-item>
563 <el-dropdown-item command="3">
564 <el-icon style="width: 24px;height: 24px;">
565 <svg-icon style="width: 24px;height: 24px;" name="api-regist" />
566 </el-icon>
567 <div class="item-content">
568 <span class="item-content-title">注册API</span>
569 <span class="item-content-desc">已有的API接口,通过注册进行线上监控和维护</span>
570 </div>
571 </el-dropdown-item>
572 </el-dropdown-menu>
573 </template>
574 </el-dropdown>
575 </div>
576 </div>
577 <div class="table_panel_wrap">
578 <Table :tableInfo="tableInfo" @tablePageChange="apiTablePageChange"
579 @tableSwitchBeforeChange="tableSwitchBeforeChange" @tableSelectionChange="tableSelectionChange" />
580 </div>
581 </div>
582 <!-- 复制对话框 -->
583 <Dialog_form :dialogConfigInfo="copyApiDialogInfo" />
584 <el-dialog v-model="dialogVisible" width="40%">
585 <template #title>
586 <div v-if="dialogTitle == '驳回理由'">{{ dialogTitle }}<span style="color:red;">*</span></div>
587 <div v-else>{{ dialogTitle }}</div>
588 </template>
589 <el-input type="textarea" :rows="4" maxlength="100" v-model="approveSuggest" show-word-limit resize="none">
590 </el-input>
591 <template #footer>
592 <div class="dialog-footer">
593 <el-button @click="dialogVisible = false">取消</el-button>
594 <el-button v-if="approveType == 'pass'" type="primary" @click="passSubmit">通过</el-button>
595 <el-button v-if="approveType == 'reject'" type="primary" @click="rejectSubmit">驳回</el-button>
596 </div>
597 </template>
598 </el-dialog>
599 </div>
600 </template>
601
602 <style lang="scss" scoped>
603 .container_wrap {
604 padding: 0;
605 display: flex;
606 justify-content: space-between;
607
608 .aside_wrap {
609 width: 199px;
610 border-right: 1px solid #d9d9d9;
611 box-shadow: none;
612
613 .aside_title {
614 width: calc(100% - 32px);
615 display: inline-block;
616 }
617
618 .icon-add.el-icon {
619 width: 24px;
620 height: 24px;
621 vertical-align: middle;
622 cursor: pointer;
623
624 svg {
625 width: 24px;
626 height: 24px;
627 }
628 }
629
630 :deep(.tree_panel) {
631 height: 100%;
632 padding-top: 0;
633
634 .el-tree {
635 margin: 0;
636 height: calc(100% - 68px);
637 overflow: hidden auto;
638 }
639 }
640
641 }
642
643 .main_wrap {
644 padding: 0 16px;
645 height: auto;
646 flex: 1;
647
648 .table_panel_wrap {
649 height: calc(100% - 92px);
650 }
651 }
652 }
653
654 :deep(.el-form) {
655 .select-input-long {
656 .el-form-item:first-child {
657 width: 67%;
658 margin-right: 0px;
659 }
660
661 .el-form-item:last-child {
662 width: 33%;
663 margin-right: 0px;
664
665 .item-label {
666 white-space: pre;
667
668 .required_mark::after {
669 content: '';
670 }
671 }
672 }
673 }
674
675 .select-input-long-reverse {
676 .el-form-item:first-child {
677 width: 100px;
678 margin-right: 0px;
679 }
680
681 .el-form-item:last-child {
682 width: calc(100% - 100px);
683 margin-right: 0px;
684
685 .item-label {
686 white-space: pre;
687
688 .required_mark::after {
689 content: '';
690 }
691 }
692 }
693 }
694 }
695 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <route lang="yaml">
2 name: apiTest
3 </route>
4
5 <script lang="ts" setup name="apiTest">
6 import { ref } from 'vue';
7 import {
8 getValidApiLabel,
9 getSceneValidApiLabel,
10 getAllApi,
11 testApiData,
12 getApiDetail
13 } from "@/api/modules/dataService";
14 import { TableColumnWidth } from '@/utils/enum';
15 import { useValidator } from '@/hooks/useValidator';
16 import { progressProps } from 'element-plus';
17 import { useRouter } from "vue-router";
18
19 const { required } = useValidator();
20 const router = useRouter();
21 const { proxy } = getCurrentInstance() as any;
22 /** API下拉列表。已发布的启用的API名称,选择后自动带出路径和请求参数。 */
23 const apiLabelList = ref([]);
24 const processDTOSValue = ref([]);
25
26 const apiFormRef = ref();
27 /** 选择要测试的API. */
28 const apiFormItems = ref([
29 {
30 type: 'tree-select',
31 label: 'API名称',
32 field: 'apiGuid',
33 default: '',
34 placeholder: '请选择',
35 options: [],
36 col: 'path-w30',
37 props: {
38 label: "sceneName",
39 children: "children",
40 value: 'guid',
41 isLeaf: 'isLeaf'
42 },
43 filterable: true,
44 clearable: true,
45 required: true
46 },
47 // {
48 // type: 'input',
49 // label: 'API路径',
50 // field: 'path',
51 // default: '',
52 // maxlength: 50,
53 // col: 'path-w30',
54 // disabled: true,
55 // required: false
56 // },
57 // {
58 // type: 'input',
59 // label: '场景名称',
60 // field: 'sceneName',
61 // default: '',
62 // maxlength: 50,
63 // col: 'path-w20',
64 // disabled: true,
65 // required: false,
66 // },{
67 // type: 'input',
68 // label: '场景名称',
69 // field: 'sceneGuid',
70 // default: '',
71 // maxlength: 50,
72 // col: 'path-w20',
73 // disabled: true,
74 // required: false,
75 // visible: false,
76 // },{
77 // type: 'input',
78 // label: '加工单号',
79 // field: 'processOrderNo',
80 // default: '',
81 // maxlength: 50,
82 // col: 'path-w20',
83 // disabled: true,
84 // required: false,
85 // },
86 ]);
87
88 const apiFormRules = ref({
89 apiGuid: [required('请选择数据产品')]
90 });
91
92 const requestParamsTableInfo = ref({
93 id: "query-params-table",
94 height: '214px',
95 fields: [
96 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
97 { label: "参数名", field: "paramName", width: 140 },
98 { label: "参数位置", field: "paramPositionName", width: 100 },
99 { label: "参数类型", field: "dataTypeName", width: 120 },
100 {
101 label: "是否必填", field: "isRequired", width: 100, getName: (scope) => {
102 return scope.row.isRequired == 'Y' ? '是' : '否'
103 }
104 },
105 {
106 label: "是否多值", field: "isManyValue", width: 100, getName: (scope) => {
107 return scope.row.isManyValue == 'Y' ? '是' : '否'
108 }
109 },
110 {
111 label: "值", field: "introductionValue", width: 240, columClass: 'edit-colum', type: 'edit', dataTypeName: 'paramType', getVisible: (scope) => {
112 return !scope.row.isConst;
113 }
114 },
115 { label: "描述", field: "description", width: 120 },
116 ],
117 editInfo: {
118 introductionValue: {
119 label: '',
120 type: 'input',
121 field: 'introductionValue',
122 default: '',
123 placeholder: '请输入',
124 clearable: true,
125 }
126 },
127 STATUS: 'edit',
128 data: <Array<Object>>[],
129 showPage: false,
130 actionInfo: {
131 show: false
132 },
133 loading: false
134 });
135
136 const defaultParamsData: any = ref([{
137 paramName: 'pageSize',
138 dataType: '整型',
139 isRequired: '是',
140 value: 50
141 }, {
142 paramName: 'pageIndex',
143 dataType: '整型',
144 isRequired: '是',
145 value: 1
146 }]);
147
148 /** default参数表格配置 */
149 const defaultParamsTableInfo = ref({
150 id: "default-params-table",
151 height: 'auto',
152 minHeight: '50px',
153 minPanelHeight: '50px',
154 fields: [
155 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
156 { label: "参数名", field: "paramName", width: 140 },
157 { label: "参数类型", field: "dataType", width: 100 },
158 { label: "是否必填", field: "isRequired", width: 100 },
159 { label: "值", field: "value", width: 240, columClass: 'edit-colum', type: 'edit' },
160 ],
161 editInfo: {
162 value: { //只能输入大于0的整数。
163 label: '',
164 type: 'input',
165 field: 'value',
166 default: '',
167 maxlength: 50,
168 min: 1,
169 regexp: /\D/g,
170 placeholder: '请输入',
171 clearable: false,
172 }
173 },
174 STATUS: 'edit',
175 data: defaultParamsData.value,
176 showPage: false,
177 actionInfo: {
178 show: false
179 },
180 loading: false
181 });
182
183 /** api测试结果详情表单 */
184 const resultFormItems = ref([{
185 label: '请求详情',
186 type: 'textarea',
187 placeholder: '输出请求详情',
188 field: 'requestUrlDetail',
189 default: '',
190 rows: 10,
191 readonly: true,
192 maxlength: "",
193 clearable: true,
194 required: false,
195 }, {
196 label: '返回内容',
197 type: 'textarea',
198 placeholder: '输出返回内容',
199 field: 'resultInfo',
200 default: '',
201 rows: 10,
202 readonly: true,
203 maxlength: "",
204 clearable: true,
205 required: false,
206 }]);
207
208 const getValidLabelPromise: any = ref(null);
209
210 onBeforeMount(() => {
211 getValidLabelPromise.value = getSceneValidApiLabel().then((res: any) => {
212 getValidLabelPromise.value = null;
213 if (res.code == proxy.$passCode) {
214 apiLabelList.value = res.data || [];
215 } else {
216 proxy.$ElMessage.error(res.msg);
217 }
218 })
219 // selectApiDetailInfo.value = {
220 // requestUrl: 'baidu.com',
221 // sceneName: '场景A',
222 // sceneGuid: 'A',
223 // processOrderNo: [
224 // {
225 // processOrderNo:1111,
226 // guid:'02e799002ad64cd3b1bc5aa31b592eca',
227 // requirementOrderName:'需求名称1',
228 // },
229 // {
230 // processOrderNo:2222,
231 // guid:'02e799002ad64cd3b1bc5aa31b592eca',
232 // requirementOrderName:'需求名称2',
233 // }
234 // ]
235 // };
236 if(selectApiDetailInfo.value?.processOrderNo?.length>0){
237 selectApiDetailInfo.value.processOrderNo.forEach(item=>{
238 item.noName=item.processOrderNo + '' + item.requirementOrderName
239 })
240 }
241 console.log('selectApiDetailInfo',selectApiDetailInfo.value);
242
243 })
244
245 const apiNodeLoad = (node, resolve, item) => {
246 if (node.level === 0) {
247 if (getValidLabelPromise.value) {
248 getValidLabelPromise.value.then(() => {
249 resolve(apiLabelList.value);
250 });
251 return;
252 }
253 resolve(apiLabelList.value)
254 } else if (node.level === 1) {
255 getAllApi(node.data.guid).then((res: any) => {
256 if (res.code == proxy.$passCode) {
257 const apiData = res.data?.map(d => {
258 d.sceneName = d.apiName;
259 d.isLeaf = true;
260 return d;
261 }) ?? [];
262 resolve(apiData);
263 } else {
264 proxy.$ElMessage.error(res.msg);
265 }
266 });
267 }
268 }
269
270 const getApiDetailPromise: any = ref(null);
271 const selectApiDetailInfo: any = ref({});////选择数据产品后带出来的信息
272
273 const apiSelectNodeChange = (node, item) => {
274 if (!node.isLeaf) {
275 return true;
276 }
277 requestParamsTableInfo.value.loading = true;
278 getApiDetailPromise.value = getApiDetail(node.guid).then((res: any) => {
279 getApiDetailPromise.value = null;
280 requestParamsTableInfo.value.loading = false;
281 requestParamsTableInfo.value.data = [];
282 if (res.code == proxy.$passCode) {
283 let data = res.data;
284 selectApiDetailInfo.value = res.data || {};
285 if(data.processDTOS&&data.processDTOS.length>0){
286 let processDTOS=data.processDTOS || [];
287 if(processDTOS?.length>0){
288 processDTOS.forEach(obj=>{
289 obj.noName=obj.processOrderNo + '' + obj.requirementOrderName
290 })
291 }
292 processDTOSValue.value = processDTOS || [];
293
294 }
295
296 }
297 else {
298 proxy.$ElMessage.error(res.msg);
299 }
300 })
301 }
302
303 const apiSelectChange = (val) => {
304 if (!val) {//清空值
305 apiFormItems.value[0].default = val;
306 // apiFormItems.value[1].default = '';
307 requestParamsTableInfo.value.data = [];
308 resultFormItems.value[0].default = '';
309 resultFormItems.value[1].default = '';
310 } else {
311 resultFormItems.value[0].default = '';
312 resultFormItems.value[1].default = '';
313 if (getApiDetailPromise.value) {
314 getApiDetailPromise.value.then(() => {
315 apiFormItems.value[0].default = val;
316 // apiFormItems.value[1].default = selectApiDetailInfo.value.requestUrl;
317 // apiFormItems.value[2].default = selectApiDetailInfo.value.sceneName;
318 // apiFormItems.value[3].default = selectApiDetailInfo.value.sceneGuid;
319 // apiFormItems.value[4].default = selectApiDetailInfo.value.processOrderNo;
320 let apiConfigAccessRSVOS = selectApiDetailInfo.value.apiConfigAccessRSVOS || [];
321 apiConfigAccessRSVOS.forEach(vo => {
322 if (vo.paramType == 'REQ') {
323 requestParamsTableInfo.value.data.push({ ...vo, introductionValue: vo.defaultValue });
324 } else if (vo.paramType == 'CONSTANT') {
325 requestParamsTableInfo.value.data.push({ ...vo, isConst: true, introductionValue: vo.defaultValue });
326 }
327 })
328 if (selectApiDetailInfo.value.authenticationType == 'N') {
329 defaultParamsTableInfo.value.data = defaultParamsData.value.concat([{
330 paramName: 'appKey',
331 dataType: '字符型',
332 isRequired: '是',
333 value: ''
334 }]);
335 } else {
336 defaultParamsTableInfo.value.data = defaultParamsData.value;
337 }
338 });
339 } else {
340 apiFormItems.value[0].default = val;
341 // apiFormItems.value[1].default = selectApiDetailInfo.value.requestUrl;
342 let apiConfigAccessRSVOS = selectApiDetailInfo.value.apiConfigAccessRSVOS || [];
343 apiConfigAccessRSVOS.forEach(vo => {
344 if (vo.paramType == 'REQ') {
345 requestParamsTableInfo.value.data.push({ ...vo, introductionValue: vo.defaultValue });
346 } else if (vo.paramType == 'CONSTANT') {
347 requestParamsTableInfo.value.data.push({ ...vo, isConst: true, introductionValue: vo.defaultValue });
348 }
349 })
350 }
351 }
352 }
353
354 const startTestApiBtnLoading = ref(false);
355
356 const startTestApi = () => {
357 apiFormRef.value?.ruleFormRef?.validate((valid, errorItem) => {
358 if (valid) {
359 let requestParamsData: any[] = requestParamsTableInfo.value.data;
360 if (requestParamsData.length) {
361 let dataIndex = 1;
362 for (const d of requestParamsData) {
363 if (d.isRequired == 'Y' && d.introductionValue !== 0 && !d.introductionValue) {
364 proxy.$ElMessage.error(`第 ${dataIndex} 个请求参数为必填则值不能为空`);
365 return;
366 }
367 dataIndex++;
368 }
369 }
370 let defaultParamsDataInfo = defaultParamsTableInfo.value.data;
371 if (defaultParamsDataInfo.length == 3 && !defaultParamsDataInfo[2].value) {
372 proxy.$ElMessage.error(`请填写参数appKey`);
373 return;
374 }
375 resultFormItems.value[0].default = '';
376 resultFormItems.value[1].default = '';
377 startTestApiBtnLoading.value = true;
378 testApiData({
379 pageSize: defaultParamsDataInfo[0].value,
380 pageIndex: defaultParamsDataInfo[1].value,
381 appKey: defaultParamsDataInfo.length == 3 ? defaultParamsDataInfo[2].value : '',
382 guid: apiFormRef.value.formInline.apiGuid,
383 apiConfigAccessDTOS: requestParamsData
384 }).then((res: any) => {
385 startTestApiBtnLoading.value = false;
386 if (res.code == proxy.$passCode) {
387 proxy.$ElMessage.success('测试API调用成功');
388 let info = res.data;
389 resultFormItems.value[0].default = JSON.stringify(info.apiInvokeReqVO, null, 4);
390 resultFormItems.value[1].default = JSON.stringify(info.apiInvokeRespVO, null, 4);
391 } else {
392 proxy.$ElMessage.error(res.msg);
393 }
394 }).catch(() => {
395 startTestApiBtnLoading.value = false;
396 });
397 } else {
398 var obj = Object.keys(errorItem);
399 apiFormRef.value.ruleFormRef.scrollToField(obj[0])
400 }
401 });
402 }
403 const seeDetail = (row) => {
404 console.log('row',row);
405 router.push({
406 name: 'processSheetDetail',
407 query: {
408 guid: row.guid,
409 }
410 });
411 }
412
413 </script>
414
415 <template>
416 <div class="container_wrap full">
417 <ContentWrap id="id-requestParams" title="请求参数" description="">
418 <div>
419 <Form ref="apiFormRef" :itemList="apiFormItems" formId="table-base-form" :rules="apiFormRules" col="col3"
420 @treeSelectLoad="apiNodeLoad" @treeSelectNodeChange="apiSelectNodeChange" @select-change="apiSelectChange" />
421 <el-row :gutter="24" class="mb10" v-if="selectApiDetailInfo?.sceneName">
422 <el-col :span="24">
423 <span class="label">API路径:</span>
424 <!-- -->
425 <span class="value">{{ selectApiDetailInfo?.requestUrl||'-' }}</span>
426 </el-col>
427 <!-- <el-col :span="12">
428 <span class="label">场景名称:</span>
429 <span class="value">{{ selectApiDetailInfo?.sceneName }}</span>
430 </el-col>
431 -->
432 </el-row>
433 <!-- <el-row :gutter="24" class="mb10" v-if="selectApiDetailInfo?.sceneName">
434 <el-col :span="24">
435 <span class="label">加工单号:</span>
436 <span v-for="(obj,idx) in processDTOSValue" @click="seeDetail(obj)" class="value cursor" style="color:#4fa1a4;padding-right:8px">{{ obj.noName }}{{ idx<processDTOSValue.length-1?'、':'' }}</span>
437 </el-col>
438 </el-row> -->
439 </div>
440
441 <Table :tableInfo="requestParamsTableInfo" class="mb10 mt8" />
442 </ContentWrap>
443 <ContentWrap id="id-defaultParams" title="DEFAULT" description="" class="mt16">
444 <Table :tableInfo="defaultParamsTableInfo" class="mb10" />
445 </ContentWrap>
446 <ContentWrap id="id-test" title="测试API" description="" class="mt16">
447 <el-button :disabled="requestParamsTableInfo.loading" :loading="startTestApiBtnLoading" @click="startTestApi"
448 class="mb10">开始测试</el-button>
449 <Form ref="resultInfoFormRef" :itemList="resultFormItems" formId="result-base-form" col="col2" />
450 </ContentWrap>
451 </div>
452 </template>
453
454 <style lang="scss" scoped>
455 .container_wrap.full {
456 overflow-y: auto;
457 padding: 16px;
458 }
459
460 :deep(.el-form) {
461 .el-form-item.path-w50 {
462 width: calc(60% - 6px) !important;
463 max-width: 720px;
464 }
465 .el-form-item.path-w30 {
466 width: calc(30% - 6px) !important;
467 max-width: 540px;
468 }
469 .el-form-item.path-w20 {
470 width: calc(18% - 6px) !important;
471 max-width: 540px;
472 margin-right: 8px !important;
473 }
474
475 .el-textarea .el-textarea__inner {
476 overflow-wrap: break-word;
477 white-space: pre-wrap;
478 word-break: break-all;
479 }
480 }
481
482 .mt8 {
483 margin-top: 8px;
484 }
485
486 .mt16 {
487 margin-top: 16px;
488 }
489
490 .mb10 {
491 margin-bottom: 10px;
492 }
493 .value {
494 color: #212121;
495 }
496 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <script lang="ts" setup name="detail_serviceApi">
2 import { ref } from "vue";
3 import { TableColumnWidth } from '@/utils/enum';
4 import { getCamundaDeploymentId } from "@/api/modules/workFlowService"
5 import {
6 getApiApprovalDetail,
7 getApiDetail,
8 apiTypes,
9 } from "@/api/modules/dataService";
10 const route = useRoute();
11 const { proxy } = getCurrentInstance() as any;
12 const router = useRouter();
13 const props = defineProps({
14 apiGuid: {
15 type: String,
16 default: ''
17 }
18 });
19 const detailLoading = ref(false);
20 const baseInfoExpand = ref(true);
21 const deploymentId = ref('');
22 const processInstanceId = ref('');
23 const pageDetail = ref({});
24 const bizApproveVO = ref();
25 const process = ref();
26 const flowExpand = ref(true);
27 const detailInfo: any = ref({});
28 const apiType = ref('1');// 单表API.
29 const sql = ref('');
30 const processDTOSValue = ref([]);
31
32 onBeforeMount(() => {
33 if (route.query.guid) {
34 getDetail();
35 } else {
36 getCamundaDeploymentId('10023').then((res: any) => {
37 if (res.code == proxy.$passCode) {
38 deploymentId.value = res.data;
39 } else {
40 proxy.$ElMessage.error(res.msg);
41 }
42 })
43 }
44 });
45
46 onActivated(() => {
47 // if (route.query.guid) {
48 // getDetail();
49 // } else {
50 // getCamundaDeploymentId('10023').then((res: any) => {
51 // if (res.code == proxy.$passCode) {
52 // deploymentId.value = res.data;
53 // } else {
54 // proxy.$ElMessage.error(res.msg);
55 // }
56 // })
57 // }
58 })
59
60 const getDetail = () => {
61 detailLoading.value = true;
62
63 // getApiDetail
64 return getApiDetail(route.query.guid).then((res: any) => {
65 detailLoading.value = false;
66 if (res?.code == proxy.$passCode) {
67 let data = res.data;
68 let { approveVO } = data
69 pageDetail.value = res.data;
70 bizApproveVO.value = data.approveVO;
71 deploymentId.value = approveVO.camundaDeploymentId
72 processInstanceId.value = approveVO.camundaInstanceId
73 process.value?.renderProcessNodes();
74 detailInfo.value = data;
75 apiType.value = data.apiType;
76 let apiConfigAccessRSVOS = data.apiConfigAccessRSVOS || [];
77 let inputParamData: any[] = [];
78 let requestData: any[] = [];
79 let responseData: any[] = [];
80 let registRequestData: any[] = [];
81 let constData: any[] = [];
82 let sortData: any[] = [];
83 apiConfigAccessRSVOS.forEach(vo => {
84 if (vo.paramType == 'DEFIN') {
85 inputParamData.push(vo);
86 } else if (vo.paramType == 'REQ') {
87 if (apiType.value == '3') {
88 registRequestData.push(vo);
89 } else if (apiType.value == '2') {
90 inputParamData.push(vo);
91 } else {
92 requestData.push(vo);
93 }
94 } else if (vo.paramType == 'RESP') {
95 responseData.push(vo);
96 } else if (vo.paramType == 'ORDER') {
97 sortData.push({ ...vo, index: sortData.length + 1 });
98 } else if (vo.paramType == 'SQL') {
99 sql.value = vo.selectSqlStatement;
100 // sqlFormItems.value.forEach(item => {
101 // item.default = vo.selectSqlStatement;
102 // });
103 } else if (vo.paramType == 'CONSTANT') {
104 constData.push(vo);
105 }
106 });
107 if(data.processDTOS&&data.processDTOS.length>0){
108 let processDTOS=data.processDTOS || [];
109 if(processDTOS?.length>0){
110 processDTOS.forEach(obj=>{
111 obj.noName=obj.processOrderNo + '' + obj.requirementOrderName
112 })
113 }
114 processDTOSValue.value = processDTOS || [];
115
116 }
117 inputParamsTableInfo.value.data = inputParamData;
118 inputParamsTableInfo.value.height = inputParamData.length > 10 ? '390px' : 'auto';
119 requestParamsTableInfo.value.data = requestData;
120 requestParamsTableInfo.value.height = requestData.length > 10 ? '390px' : 'auto';
121 responseParamsTableInfo.value.data = responseData;
122 responseParamsTableInfo.value.height = responseData.length > 10 ? '390px' : 'auto';
123 sortParamsTableInfo.value.data = sortData;
124 sortParamsTableInfo.value.height = sortData.length > 10 ? '390px' : 'auto';
125 registRequestParamsTableInfo.value.data = registRequestData;
126 registRequestParamsTableInfo.value.height = registRequestData.length > 10 ? '390px' : 'auto';
127 constParamsTableInfo.value.data = constData;
128 constParamsTableInfo.value.height = constData.length > 10 ? '390px' : 'auto';
129 } else {
130 proxy.$ElMessage.error(res?.msg);
131 }
132 });
133 }
134 const seeDetail = (row) => {
135 router.push({
136 name: 'processSheetDetail',
137 query: {
138 guid: row.guid,
139 }
140 });
141 }
142
143 /** 基本信息的入参定义表格配置 */
144 const inputParamsTableInfo = ref({
145 id: "input-params-table",
146 height: 'auto',
147 minHeight: '50px',
148 minPanelHeight: '50px',
149 fields: [
150 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
151 { label: "参数名", field: "paramName", width: 160 },
152 { label: "参数位置", field: "paramPositionName", width: 100 },
153 { label: "参数类型", field: "dataTypeName", width: 120 },
154 {
155 label: "是否必填", field: "isRequired", width: 100, getName: (scope) => {
156 return scope.row.isRequired == 'Y' ? '是' : '否'
157 }
158 },
159 {
160 label: "是否多值", field: "isManyValue", width: 100, getName: (scope) => {
161 return scope.row.isManyValue == 'Y' ? '是' : '否'
162 }
163 },
164 { label: "默认值", field: "defaultValue", width: 200 },
165 { label: "描述", field: "description", width: 160 }
166 ],
167 data: <Array<Object>>[],
168 showPage: false,
169 actionInfo: {
170 show: false,
171 },
172 loading: false
173 });
174
175 const requestParamsTableInfo = ref({
176 id: "request-params-table",
177 height: 'auto',
178 minHeight: '50px',
179 minPanelHeight: '50px',
180 fields: [
181 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
182 { label: "绑定参数", field: "paramName", width: 160 },
183 { label: "绑定字段", field: "boundField", width: 160 },
184 { label: "操作符", field: "operatorName", width: 100 },
185 ],
186 data: <Array<Object>>[],
187 showPage: false,
188 actionInfo: {
189 show: false,
190 },
191 loading: false
192 });
193
194 /** 注册API的请求参数 */
195 const registRequestParamsTableInfo = ref({
196 id: "request-params-table",
197 height: 'auto',
198 minHeight: '50px',
199 minPanelHeight: '50px',
200 fields: [
201 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
202 { label: "参数名", field: "paramName", width: 160 },
203 { label: "参数位置", field: "paramPositionName", width: 100 },
204 { label: "参数类型", field: "dataTypeName", width: 120 },
205 {
206 label: "是否必填", field: "isRequired", width: 100, getName: (scope) => {
207 return scope.row.isRequired == 'Y' ? '是' : '否'
208 }
209 },
210 {
211 label: "是否多值", field: "isManyValue", width: 100, getName: (scope) => {
212 return scope.row.isManyValue == 'Y' ? '是' : '否'
213 }
214 },
215 { label: "默认值", field: "defaultValue", width: 200 },
216 { label: "描述", field: "description", width: 160 }
217 ],
218 data: <Array<Object>>[],
219 showPage: false,
220 actionInfo: {
221 show: false,
222 },
223 loading: false
224 });
225
226 /** 注册API的常量参数 */
227 const constParamsTableInfo = ref({
228 id: "const-params-table",
229 height: 'auto',
230 minHeight: '50px',
231 minPanelHeight: '50px',
232 fields: [
233 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
234 { label: "参数名", field: "paramName", width: 160 },
235 { label: "参数位置", field: "paramPositionName", width: 100 },
236 { label: "参数类型", field: "dataTypeName", width: 120 },
237 {
238 label: "是否必填", field: "isRequired", width: 100, getName: (scope) => {
239 return scope.row.isRequired == 'Y' ? '是' : '否'
240 }
241 },
242 { label: "常量值", field: "defaultValue", width: 200 },
243 { label: "描述", field: "description", width: 160 }
244 ],
245 data: <Array<Object>>[],
246 showPage: false,
247 actionInfo: {
248 show: false,
249 },
250 loading: false
251 });
252
253 const responseParamsTableInfo = ref({
254 id: "response-params-table",
255 height: 'auto',
256 minHeight: '50px',
257 minPanelHeight: '50px',
258 fields: [
259 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
260 { label: "参数名", field: "paramName", width: 160 },
261 { label: "绑定字段", field: "boundField", width: 140 },
262 { label: "参数类型", field: "dataTypeName", width: 120 },
263 { label: "示例值", field: "exampleValue", width: 160 },
264 { label: "描述", field: "description", width: 160 },
265 ],
266 data: <Array<Object>>[],
267 showPage: false,
268 actionInfo: {
269 show: false,
270 },
271 loading: false
272 });
273
274 /** 排序参数配置 */
275 const sortParamsTableInfo = ref({
276 id: "sort-params-table",
277 height: 'auto',
278 minHeight: '100px',
279 minPanelHeight: '100px',
280 fields: [
281 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
282 { label: "参数名", field: "paramName", width: 160 },
283 { label: "绑定字段", field: "boundField", width: 140 },
284 {
285 label: "排序方式", field: "sortMode", width: 100, getName: (scope) => {
286 return scope.row.sortMode == 'ASC' ? '升序' : '降序';
287 }
288 },
289 { label: "描述", field: "description", width: 160 },
290 ],
291 data: <Array<Object>>[],
292 showPage: false,
293 actionInfo: {
294 show: false,
295 },
296 loading: false
297 });
298
299 </script>
300
301 <template>
302 <div class="content_main" v-loading="detailLoading">
303 <ContentWrap title="基础信息" description="" :isExpand="baseInfoExpand" :expand-swicth="true"
304 class="mb16" @expand="(v) => baseInfoExpand = v">
305 <div class="list_panel">
306 <div class="list_item">
307 <span class="item_label">API类型:</span>
308 <span class="item_value">{{ apiTypes.find(a => a.value == apiType)?.label || '-' }}</span>
309 </div>
310 <div class="list_item">
311 <span class="item_label">API名称:</span>
312 <span class="item_value">{{ detailInfo.apiName || '-' }}</span>
313 </div>
314 <!-- <div class="list_item">
315 <span class="item_label">场景名称:</span>
316 <span class="item_value">{{ detailInfo.sceneName || '-' }}</span>
317 </div> -->
318 <div class="list_item">
319 <span class="item_label">返回类型:</span>
320 <span class="item_value">{{ detailInfo.responseType || '-' }}</span>
321 </div>
322 <div class="list_item">
323 <span class="item_label">请求方式:</span>
324 <span class="item_value">{{ detailInfo.requestMode == 'G' ? 'get' : 'post' }}</span>
325 </div>
326 <div class="list_item">
327 <span class="item_label">安全认证:</span>
328 <span class="item_value">{{ detailInfo.authenticationType == 'T' ? 'token认证' : '无认证' }}</span>
329 </div>
330 <div class="list_item" v-if="detailInfo.authenticationType == 'N'">
331 <span class="item_label">IP白名单:</span>
332 <span class="item_value">
333 <ellipsis-tooltip :content="detailInfo.whiteIPAddrs?.length ? detailInfo.whiteIPAddrs.join(',') : '-'" class-name="w100f mr8-i"
334 :refName="'tooltipOver' + 'WhiteIPs'"></ellipsis-tooltip>
335 </span>
336 </div>
337 <!-- 空白占位符 -->
338 <!-- <div class="list_item" v-if="apiType == '1'">
339 <span class="item_label"></span>
340 <span class="item_value"></span>
341 </div> -->
342 <div class="list_item" v-if="apiType == '1'">
343 <span class="item_label">数据类型:</span>
344 <span class="item_value">{{ detailInfo.dataSourceType == 1 ? '数据源' : '数据目录' }}</span>
345 </div>
346 <div class="list_item" v-if="apiType != '3'">
347 <span class="item_label">数据源:</span>
348 <span class="item_value">{{ detailInfo.dataSourceName || '-' }}</span>
349 </div>
350 <div class="list_item" v-if="apiType == '1'">
351 <span class="item_label">数据表:</span>
352 <span class="item_value">{{ detailInfo.tableName || '-' }}</span>
353 </div>
354 <div class="list_item" v-if="apiType == '1'">
355 <span class="item_label">数据表中文名:</span>
356 <span class="item_value">{{ detailInfo.tableNameCh || '-' }}</span>
357 </div>
358 <div class="list_item is_block">
359 <span class="item_label">请求路径:</span>
360 <span class="item_value">
361 <ellipsis-tooltip :content="detailInfo.requestUrl || '-'" class-name="w100f mr8-i"
362 :refName="'tooltipOver' + 'requestUrl'"></ellipsis-tooltip></span>
363 </div>
364 <div class="list_item is_block">
365 <span class="item_label">API描述:</span>
366 <span class="item_value">
367 <ellipsis-tooltip :content="detailInfo.apiDescription || '-'" class-name="w100f mr8-i"
368 :refName="'tooltipOver' + route.query.guid"></ellipsis-tooltip></span>
369 </div>
370 <template v-if="apiType == '3'">
371 <div class="list_item">
372 <span class="item_label">后台服务HOST:</span>
373 <span class="item_value">{{ `${detailInfo.backstageAgreement}://${detailInfo.backstageHost}` }}</span>
374 </div>
375 <div class="list_item">
376 <span class="item_label">请求方式:</span>
377 <span class="item_value">{{ detailInfo.backstageRequestMode == 'G' ? 'get' : 'post' }}</span>
378 </div>
379 <div class="list_item">
380 <span class="item_label">后端超时:</span>
381 <span class="item_value">{{ detailInfo.backstageOvertime == null ? '-' : (detailInfo.backstageOvertime + 'ms') }}</span>
382 </div>
383 <div class="list_item is_block">
384 <span class="item_label">后台服务PATH:</span>
385 <span class="item_value">
386 <ellipsis-tooltip :content="detailInfo.backstagePath || '-'" class-name="w100f mr8-i"
387 :refName="'tooltipOver' + 'path'"></ellipsis-tooltip></span>
388 </div>
389 </template>
390 </div>
391 </ContentWrap>
392
393 <template v-if="inputParamsTableInfo.data.length">
394 <div class="list_item" style="font-weight: 500;color: var(--el-color-regular);margin: 8px 0px;">{{ apiType == '3' ? '请求参数' : '入参定义' }}</div>
395 <Table :tableInfo="inputParamsTableInfo" />
396 </template>
397 <template v-if="requestParamsTableInfo.data.length">
398 <div class="list_item" style="font-weight: 500;color: var(--el-color-regular);margin: 8px 0px;">请求参数</div>
399 <Table :tableInfo="requestParamsTableInfo" />
400 </template>
401 <template v-if="responseParamsTableInfo.data.length">
402 <div class="list_item" style="font-weight: 500;color: var(--el-color-regular);margin: 8px 0px;">返回参数</div>
403 <Table :tableInfo="responseParamsTableInfo" />
404 </template>
405 <template v-if="sortParamsTableInfo.data.length">
406 <div class="list_item" style="font-weight: 500;color: var(--el-color-regular);margin: 8px 0px;">排序参数</div>
407 <Table :tableInfo="sortParamsTableInfo" />
408 </template>
409 <template v-if="apiType == '3'">
410 <template v-if="registRequestParamsTableInfo.data.length">
411 <div class="list_item" style="font-weight: 500;color: var(--el-color-regular);margin: 8px 0px;">请求参数</div>
412 <Table :tableInfo="registRequestParamsTableInfo" />
413 </template>
414 <template v-if="constParamsTableInfo.data.length">
415 <div class="list_item" style="font-weight: 500;color: var(--el-color-regular);margin: 8px 0px;">常量参数</div>
416 <Table :tableInfo="constParamsTableInfo" />
417 </template>
418 </template>
419 <template v-if="apiType == '2'">
420 <div class="list_item" style="font-weight: 500;color: var(--el-color-regular);margin: 8px 0px;">查询sql</div>
421 <el-input v-model.trim="sql" :rows="10" type="textarea" :readonly="true" />
422 </template>
423 <ContentWrap title="流程审批" v-if="detailInfo.approveVO && detailInfo.isApprove != 'N'" description="" :isExpand="flowExpand" :expand-swicth="true"
424 class="mb16" @expand="(v) => flowExpand = v">
425 <ApprovalProcess ref="process" v-if="deploymentId" :deploymentId="deploymentId" :processInstanceId="processInstanceId">
426 </ApprovalProcess>
427 </ContentWrap>
428 <FlowBtnGroup pageType="detail" :approveVO="bizApproveVO" @refreshPage="getDetail"></FlowBtnGroup>
429
430 </div>
431 </template>
432
433 <style scoped lang="scss">
434 .content_main {
435 height: calc(100% - 40px);
436 padding: 16px;
437 overflow: hidden auto;
438 position: sticky;
439
440 .list_panel {
441 display: flex;
442 flex-wrap: wrap;
443
444 .list_item {
445 width: 33.33%;
446 line-height: 21px;
447 margin-bottom: 12px;
448 font-size: 14px;
449 color: var(--el-text-color-regular);
450 display: flex;
451 justify-content: space-between;
452 min-width: 120px;
453
454 .item_label {
455 width: 100px;
456 text-align: right;
457 }
458
459 .item_value {
460 color: var(--el-color-regular);
461 padding: 0 8px;
462 flex: 1;
463 text-align: justify;
464 max-width: calc(100% - 100px);
465 }
466
467 &.is_block {
468 width: 100%;
469 }
470
471 .file-operate {
472 display: flex;
473 align-items: center;
474 position: relative;
475
476 .file-img {
477 width: 24px;
478 height: 24px;
479 }
480
481 &:hover {
482 background-color: #f5f5f5;
483 }
484
485 .file-name {
486 color: var(--el-color-regular);
487 margin-left: 4px;
488 }
489
490 .file-preview {
491 position: absolute;
492 cursor: pointer;
493 color: var(--el-color-primary);
494 margin-right: 8px;
495 }
496 }
497 }
498 }
499
500 .table_panel {
501 height: 200px;
502 min-height: 200px;
503 }
504 }
505 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <route lang="yaml">
2 name: ipWhitelist
3 </route>
4
5 <script lang="ts" setup name="ipWhitelist">
6 import { ref } from 'vue';
7 import { TableColumnWidth } from '@/utils/enum';
8 import TableTools from '@/components/Tools/table_tools.vue';
9 import { commonPageConfig } from '@/components/PageNav/index';
10 import { useRouter, useRoute } from "vue-router";
11 import {
12 getIPList,
13 deleteIP,
14 saveIP,
15 updateIP
16 } from "@/api/modules/dataService";
17 import { useValidator } from '@/hooks/useValidator';
18
19 const { proxy } = getCurrentInstance() as any;
20 const router = useRouter();
21 const { required, regexpValidate } = useValidator();
22
23 /** 分页及搜索传参信息配置。 */
24 const page = ref({
25 ...commonPageConfig,
26 ip: ''
27 });
28
29 const searchItemList = ref([{
30 type: "input",
31 label: "",
32 field: "ip",
33 default: "",
34 placeholder: "IP",
35 clearable: true,
36 }]);
37
38 const currTableData: any = ref({});
39 const tableInfo = ref({
40 id: 'data-app-table',
41 fields: [
42 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
43 { label: "IP", field: "ip", width: 140 },
44 { label: "描述", field: "description", width: TableColumnWidth.DESCRIPTION },
45 { label: "修改人", field: "updateUserName", width: TableColumnWidth.USERNAME },
46 { label: "修改时间", field: "updateTime", width: TableColumnWidth.DATETIME },
47 ],
48 data: [],
49 page: {
50 type: "normal",
51 rows: 0,
52 ...page.value,
53 },
54 actionInfo: {
55 label: "操作",
56 type: "btn",
57 width: 120,
58 fixed: 'right',
59 btns: (scope) => {
60 let btnsArr: any = [];
61 btnsArr.push({
62 label: "编辑", value: "edit", click: (scope) => {
63 currTableData.value = scope.row;
64 IPDialogInfo.value.header.title = '编辑IP';
65 IPDialogInfo.value.type = 'edit';
66 IPFormItems.value[0].default = scope.row.ip;
67 IPFormItems.value[1].default = scope.row.description;
68 IPDialogInfo.value.visible = true;
69 }
70 });
71 btnsArr.push({
72 label: "删除", value: "delete", click: (scope) => {
73 proxy.$openMessageBox('确定要删除该IP吗?', () => {
74 deleteIP([scope.row.guid]).then((res: any) => {
75 if (res.code == proxy.$passCode) {
76 page.value.curr = 1;
77 getTableData();
78 proxy.$ElMessage.success("删除成功");
79 } else {
80 proxy.$ElMessage.error(res.msg);
81 }
82 });
83 }, () => {
84 proxy.$ElMessage.info("已取消");
85 })
86 }
87 });
88 return btnsArr
89 },
90 },
91 loading: false
92 })
93
94 const IPFormItems = ref([{
95 type: 'input',
96 label: 'IP',
97 field: 'ip',
98 default: '',
99 block: true,
100 placeholder: '请输入',
101 maxlength: 50,
102 clearable: true,
103 required: true
104 }, {
105 label: '描述',
106 type: 'textarea',
107 placeholder: '请输入',
108 field: 'description',
109 default: '',
110 maxlength: 200,
111 block: true,
112 clearable: true,
113 required: false
114 }]);
115
116 const IPFormRules = ref({
117 ip: [required("请填写IP"), regexpValidate(/^(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])$/, '请输入合法的IP地址')],
118 });
119
120 const IPDialogInfo = ref({
121 visible: false,
122 size: 480,
123 direction: "column",
124 header: {
125 title: "添加IP",
126 },
127 type: 'add',
128 contents: [
129 {
130 type: 'form',
131 title: '',
132 formInfo: {
133 id: 'add-authorize-form',
134 items: IPFormItems.value,
135 rules: IPFormRules.value
136 }
137 }
138 ],
139 footer: {
140 btns: [
141 { type: "default", label: "取消", value: "cancel" },
142 { type: "primary", label: "确定", value: "submit", loading: false },
143 ],
144 },
145 });
146
147 const IPDialogBtnClick = (btn, info) => {
148 if (btn.value == 'submit') {
149 IPDialogInfo.value.footer.btns[1].loading = true;
150 if (IPDialogInfo.value.type == 'add') {
151 saveIP(info).then((res: any) => {
152 IPDialogInfo.value.footer.btns[1].loading = false;
153 if (res.code == proxy.$passCode) {
154 page.value.curr = 1;
155 getTableData();
156 proxy.$ElMessage({
157 type: 'success',
158 message: `添加IP成功`
159 })
160 IPDialogInfo.value.visible = false;
161 } else {
162 proxy.$ElMessage.error(res.msg);
163 }
164 })
165 } else {
166 info.guid = currTableData.value.guid;
167 updateIP(info).then((res: any) => {
168 IPDialogInfo.value.footer.btns[1].loading = false;
169 if (res.code == proxy.$passCode) {
170 page.value.curr = 1;
171 getTableData();
172 proxy.$ElMessage({
173 type: 'success',
174 message: `编辑IP成功`
175 })
176 IPDialogInfo.value.visible = false;
177 } else {
178 proxy.$ElMessage.error(res.msg);
179 }
180 })
181 }
182 } else if (btn.value == 'cancel') {
183 IPDialogInfo.value.visible = false;
184 }
185 };
186
187 const toSearch = (val: any, clear: boolean = false) => {
188 page.value.curr = 1;
189 if (clear) {
190 searchItemList.value.map((item) => (item.default = ""));
191 page.value.ip = '';
192 } else {
193 page.value.ip = val.ip;
194 }
195 getTableData();
196 };
197
198 const tablePageChange = (info) => {
199 page.value.curr = Number(info.curr);
200 page.value.limit = Number(info.limit);
201 getTableData();
202 };
203
204 const getTableData = () => {
205 tableInfo.value.loading = true
206 getIPList({
207 pageIndex: page.value.curr,
208 pageSize: page.value.limit,
209 ip: page.value.ip
210 }).then((res: any) => {
211 if (res.code == proxy.$passCode) {
212 const data = res.data || {}
213 tableInfo.value.data = data.records || []
214 tableInfo.value.page.limit = data.pageSize
215 tableInfo.value.page.curr = data.pageIndex
216 tableInfo.value.page.rows = data.totalRows
217 } else {
218 proxy.$ElMessage({
219 type: 'error',
220 message: res.msg,
221 })
222 }
223 tableInfo.value.loading = false
224 })
225 };
226
227 const addIPWhite = () => {
228 IPDialogInfo.value.visible = true;
229 IPDialogInfo.value.header.title = '添加IP';
230 IPDialogInfo.value.type = 'add';
231 IPFormItems.value[0].default = '';
232 IPFormItems.value[1].default = ''
233 }
234
235 onBeforeMount(() => {
236 toSearch({})
237 })
238
239 </script>
240
241 <template>
242 <div class="container_wrap">
243 <div class="table_tool_wrap">
244 <TableTools :searchItems="searchItemList" :searchId="'data-source-search'" @search="toSearch" :init="false" />
245 <div class="tools_btns">
246 <el-button type="primary" @click="addIPWhite" v-preReClick>添加</el-button>
247 </div>
248 </div>
249 <div class="table_panel_wrap">
250 <Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" />
251 </div>
252 <!-- 添加编辑IP对话框 -->
253 <Dialog :dialogInfo="IPDialogInfo" @btnClick="IPDialogBtnClick" />
254 </div>
255 </template>
256
257 <style lang="scss" scoped>
258 .table_tool_wrap {
259 width: 100%;
260 height: 84px !important;
261 padding: 0 8px;
262
263 .tools_btns {
264 padding: 0px 0 0;
265 }
266 }
267
268 .table_panel_wrap {
269 width: 100%;
270 height: calc(100% - 84px);
271 padding: 0px 8px 0;
272 }
273 </style>
...\ No newline at end of file ...\ No newline at end of file
...@@ -154,7 +154,7 @@ function testAccount(logonUser: string) { ...@@ -154,7 +154,7 @@ function testAccount(logonUser: string) {
154 <div> 154 <div>
155 <img :src="banner" class="banner"> 155 <img :src="banner" class="banner">
156 <div class="banner_desc"> 156 <div class="banner_desc">
157 <h4>数据资产管理系统</h4> 157 <h4>可信数据空间</h4>
158 <span>激活数据流通体系,释放数据要素新质生产力</span> 158 <span>激活数据流通体系,释放数据要素新质生产力</span>
159 </div> 159 </div>
160 </div> 160 </div>
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!