fd2815e7 by lihua

逻辑空间管理前端开发

1 parent c046732c
...@@ -424,7 +424,52 @@ const routes: RouteRecordRaw[] = [ ...@@ -424,7 +424,52 @@ const routes: RouteRecordRaw[] = [
424 name: 'productApplicationDetail', 424 name: 'productApplicationDetail',
425 component: () => import('@/views/data_asset/productApplicationDetail.vue'), 425 component: () => import('@/views/data_asset/productApplicationDetail.vue'),
426 meta: { 426 meta: {
427 title: '数据申请-', 427 title: '申请详情-',
428 sidebar: false,
429 breadcrumb: false,
430 cache: true,
431 reuse: true
432 }
433 },
434 ]
435 },
436 {
437 path: '/data-product/space-manage',
438 component: Layout,
439 meta: {
440 title: '逻辑空间管理',
441 icon: 'sidebar-videos',
442 },
443 children: [
444 {
445 path: '',
446 name: 'productSpaceManage',
447 component: () => import('@/views/data_asset/productSpaceManage.vue'),
448 meta: {
449 title: '',
450 sidebar: false,
451 breadcrumb: false,
452 cache: true
453 },
454 },
455 {
456 path: 'product-space-edit',
457 name: 'productSpaceEdit',
458 component: () => import('@/views/data_asset/productSpaceEdit.vue'),
459 meta: {
460 title: '新增-',
461 sidebar: false,
462 breadcrumb: false,
463 cache: true,
464 reuse: true
465 }
466 },
467 {
468 path: 'product-space-detail',
469 name: 'productSpaceDetail',
470 component: () => import('@/views/data_asset/productSpaceDetail.vue'),
471 meta: {
472 title: '详情-',
428 sidebar: false, 473 sidebar: false,
429 breadcrumb: false, 474 breadcrumb: false,
430 cache: true, 475 cache: true,
......
1 <template>
2 <div class="container_wrap full" v-loading="fullscreenLoading">
3 <div class="content_main">
4 <ContentWrap id="id-baseInfo" title="逻辑空间信息" description="" :isExpand="baseInfoExpand" :expand-swicth="true"
5 class="mb16" @expand="(v) => baseInfoExpand = v">
6 <div class="list_panel">
7 <div class="list_item">
8 <span class="item_label">逻辑空间名称:</span>
9 <span class="item_value">
10 <ellipsis-tooltip :content="detailInfo.spaceName || '--'" class-name="w100f mr8-i"
11 :refName="'tooltipOver' + 'spaceName'"></ellipsis-tooltip>
12 </span>
13 </div>
14 <div class="list_item">
15 <span class="item_label">所属领域:</span>
16 <span class="item_value">{{ detailInfo.domainName || '--' }}</span>
17 </div>
18 <div class="list_item">
19 <span class="item_label">创建企业:</span>
20 <span class="item_value"> <ellipsis-tooltip :content="detailInfo.tenantName || '--'"
21 class-name="w100f mr8-i" :refName="'tooltipOver' + 'tenantName'"></ellipsis-tooltip></span>
22 </div>
23 <div class="list_item">
24 <span class="item_label">是否开启:</span>
25 <span class="item_value">{{ detailInfo.bizState ? '是' : '否' }}</span>
26 </div>
27 </div>
28 <el-tabs v-model="activeTabName" class="param-tabs" style="margin-top: 8px;">
29 <el-tab-pane label="成员权限" name="member">
30 <Table ref="memberTableRef" :tableInfo="memberTableInfo" class="fiveRow-table" />
31 </el-tab-pane>
32 <el-tab-pane label="策略配置" name="strategy">
33 <StrategyTable ref="strategyTableDetailRef" :show-title="false" :is-look="true"
34 :value="detailInfo.policyRSVOS || []">
35 </StrategyTable>
36 </el-tab-pane>
37 </el-tabs>
38 </ContentWrap>
39 <ContentWrap id="id-approveInfo" title="流程审批" expandSwicth style="margin-top: 15px" :isExpand="expandApprove"
40 @expand="(v) => expandApprove = v">
41 <ApprovalProcess ref="approvalProcessRef" v-if="deploymentId" :deploymentId="deploymentId"
42 :processInstanceId="processInstanceId">
43 </ApprovalProcess>
44 </ContentWrap>
45 </div>
46 <div class="tool_btns">
47 <div class="btns">
48 <el-button v-for="btn in toolBtns" :type="btn.type" :plain="btn.plain" @click="btnClick(btn)">{{ btn.label }}</el-button>
49 </div>
50 </div>
51 </div>
52 </template>
53
54 <script lang="ts" setup name="productSpaceDetail">
55 import useUserStore from "@/store/modules/user";
56 import StrategyTable from "../data_smart_contract/components/strategyTable.vue";
57 import { TableColumnWidth } from "@/utils/enum";
58
59
60 const { proxy } = getCurrentInstance() as any;
61 const userStore = useUserStore();
62 const route = useRoute();
63 const router = useRouter();
64 const fullPath = route.fullPath;
65
66 const fullscreenLoading = ref(false);
67 const baseInfoExpand = ref(true);
68 const expandApprove = ref(true);
69
70 const deploymentId = ref('');
71 const processInstanceId = ref('');
72
73 const detailInfo: any = ref({});
74
75 /** 页签当前活跃的有成员权限和策略配置 */
76 const activeTabName = ref('member');
77
78 const toolBtns: any = computed(() => {
79 let btnsArr: any = [{
80 label: "关闭", value: "cancel", plain: true
81 }];
82 // TODO,资产运营平台TODO
83 return btnsArr;
84 });
85
86 const btnClick = (btn: any) => {
87 switch (btn.value) {
88 case 'cancel':
89 cancel();
90 break;
91 default:
92 break;
93 }
94 }
95
96 const cancel = () => {
97 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
98 router.push({
99 name: 'productApplicationManage'
100 });
101 }
102
103 onBeforeMount(() => {
104
105 })
106
107 const memberTableInfo = ref({
108 id: "input-member-table",
109 height: '214px',
110 fields: [
111 { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
112 { label: "成员名称", field: "memberGuid", width: 200 },
113 { label: "角色类型", field: "roleType", width: 160 },
114 { label: "描述", field: "description", width: 300 },
115 ],
116 data: [],
117 showPage: false,
118 actionInfo: {
119 show: false,
120 }
121 });
122
123 </script>
124
125 <style lang="scss" scoped>
126 .content_main {
127 height: calc(100% - 44px);
128 padding: 16px;
129 overflow: hidden auto;
130 position: sticky;
131 }
132
133 .list_panel {
134 display: flex;
135 flex-wrap: wrap;
136 display: flex;
137 align-items: center;
138
139 .list_item {
140 width: 33.33%;
141 line-height: 32px;
142 font-size: 14px;
143 color: var(--el-text-color-regular);
144 display: flex;
145 justify-content: space-between;
146 min-width: 120px;
147
148 .item_label {
149 text-align: left;
150 }
151
152 .item_value {
153 color: var(--el-color-regular);
154 padding: 0 4px;
155 flex: 1;
156 text-align: justify;
157 min-width: 0;
158
159 &.link {
160 color: var(--el-color-primary);
161 cursor: pointer;
162 }
163 }
164
165 &.is_block {
166 width: 100%;
167
168 .item_value {
169 white-space: pre-wrap;
170 }
171 }
172 }
173 }
174
175 .tool_btns {
176 display: flex;
177 justify-content: center;
178 align-items: center;
179 height: 44px;
180 padding: 0 16px;
181 border-top: 1px solid #d9d9d9;
182 }
183
184 :deep(.el-tabs) {
185 margin-top: -8px;
186
187 .el-tabs__header {
188 margin-bottom: 8px;
189 }
190
191 .el-tabs__item {
192 height: 32px;
193
194 &:nth-child(2) {
195 padding-left: 16px;
196 }
197
198 }
199 }
200 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <template>
2 <div class="container_wrap">
3 <div class="table_tool_wrap">
4 <el-button type="primary" @click="newCreate">新增</el-button>
5 <el-input v-model.trim="pageInfo.keyWord" placeholder="名称搜索" :suffix-icon="Search" clearable
6 @blur="toSearch(true, true)" @keyup.enter.native="searchEnterFun" />
7 </div>
8 <div class="table_panel_wrap">
9 <div v-show="listData.length" class="data-content" v-loading="listDataLoading">
10 <div class="card-content" v-for="(item, index) in listData" :key="item.guid" @click="handleDataClick(item)">
11 <div class="v-top">
12 <span class="title">{{ item.name }}</span>
13 <el-tag :type="tagType(item, 'approveState')">{{ tagMethod(item, 'approveState') }}</el-tag>
14 </div>
15 <div class="v-middle">
16 <div class="per">
17 <div class="desc">产品数量</div>
18 <div class="cnt">{{ item.productNum == null ? '--' : changeNum(item.productNum, 0) }}</div>
19 </div>
20 <div class="per">
21 <div class="desc">成员数量</div>
22 <div class="cnt">{{ item.productNum == null ? '--' : changeNum(item.productNum, 0) }}</div>
23 </div>
24 </div>
25 <div class="v-bottom">
26 <div class="per" @click.stop="clickDetail(item)">详情</div>
27 <div class="divider" @click.stop></div>
28 <div class="per" @click.stop="clickDelete(item)">删除</div>
29 </div>
30 </div>
31 </div>
32 <div v-show="!listData.length" class="empty-content">
33 <img src="../../assets/images/empty-data.png" :style="{ width: '168px', height: '96px' }" />
34 <div class="empty-text">暂无数据</div>
35 </div>
36 </div>
37 <PageNav :class="[pageInfo.type]" :pageInfo="pageInfo" @pageChange="pageChange" />
38 </div>
39 </template>
40 <script setup lang="ts" name="productSpaceManage">
41 import { commonPageConfig } from '@/components/PageNav';
42 import { changeNum, tagMethod, tagType } from '@/utils/common';
43 import { Search } from "@element-plus/icons-vue";
44
45 const router = useRouter();
46 const { proxy } = getCurrentInstance() as any;
47
48 /** 卡片加载条 */
49 const listDataLoading = ref(false);
50 /** 列表数据 */
51 const listData: any = ref([{ guid: '1', name: '产品空间1' }, { guid: '2', name: '产品空间1' }, { guid: '3', name: '产品空间1' }, { guid: '4', name: '产品空间1' },
52 { guid: '5', name: '产品空间1' }
53 ]);
54
55 const oldKeyWord = ref(""); // 记录上次输入的关键字,避免重复搜索
56 const isEnter = ref(false); // 标识是否通过回车键触发搜索
57
58 const pageInfo = ref({
59 ...commonPageConfig,
60 rows: 0,
61 type: "normal",
62 keyWord: '',
63 });
64
65 const getTableData = (clear = false) => {
66 // listDataLoading.value = true;
67 // getDamCatalogTable({
68 // pageSize: pageInfo.value.limit,
69 // pageIndex: pageInfo.value.curr,
70 // keyWord: pageInfo.value.keyWord
71 // }).then((res: any) => {
72 // listDataLoading.value = false;
73 // if (res.code == proxy.$passCode) {
74 // const data = res.data || {}
75 // listData.value = data.records || [];
76 // pageInfo.value.limit = data.pageSize
77 // pageInfo.value.curr = data.pageIndex
78 // pageInfo.value.rows = data.totalRows
79 // } else {
80 // proxy.$ElMessage.error(res.msg);
81 // }
82 // });
83 }
84
85 const pageChange = (info) => {
86 pageInfo.value.curr = Number(info.curr);
87 pageInfo.value.limit = Number(info.limit);
88 getTableData();
89 };
90
91 /**
92 * 触发搜索查询
93 * @param clear - 是否清空页码,默认为true
94 * @param isBlur - 是否是失焦触发,默认为false
95 */
96 const toSearch = (clear: boolean = true, isBlur: boolean = false) => {
97 if (clear) {
98 pageInfo.value.curr = 1 // 重置为第一页
99 }
100 // 如果是失焦且不是回车触发,且关键词没有变化,则不执行搜索
101 if (isBlur && !isEnter.value && oldKeyWord.value === pageInfo.value.keyWord) {
102 return;
103 }
104 isEnter.value = false; // 重置回车状态
105 oldKeyWord.value = pageInfo.value.keyWord; // 更新关键词记录
106 getTableData(clear);
107 }
108
109 /**
110 * 回车搜索事件处理
111 * 在输入框按下回车键时触发
112 * @param event - 键盘事件对象
113 */
114 const searchEnterFun = (event) => {
115 isEnter.value = true; // 标记为回车触发
116 event.target?.blur(); // 输入框失去焦点
117 }
118
119 const newCreate = () => {
120 router.push({
121 name: 'productSpaceEdit'
122 })
123 }
124
125 const handleDataClick = (item) => {
126 router.push({
127 name: 'productSpaceEdit',
128 query: {
129 guid: item.guid,
130 name: item.name
131 }
132 })
133 }
134
135 const clickDetail = (item) => {
136 router.push({
137 name: 'productSpaceDetail',
138 query: {
139 guid: item.guid,
140 name: item.name
141 }
142 })
143 }
144
145 const clickDelete = (item) => {
146 proxy.$openMessageBox('此操作将永久删除该空间,是否继续?', () => {
147 // TODO
148 }, () => {
149 proxy.$ElMessage.info('已取消删除');
150 });
151 }
152
153 </script>
154
155 <style lang="scss" scoped>
156 .container_wrap {
157 padding: 0 16px;
158 }
159
160 .table_tool_wrap {
161 display: flex;
162 align-items: center;
163 justify-content: space-between;
164 padding-top: 12px;
165
166 .el-input {
167 width: 240px;
168 }
169 }
170
171 .table_panel_wrap {
172 height: calc(100% - 94px);
173 margin-top: 12px;
174 position: relative;
175
176 .data-content {
177 display: flex;
178 flex-wrap: wrap;
179 gap: 16px 16px;
180 align-content: flex-start;
181 overflow-y: auto;
182
183 .card-content {
184 width: calc(25% - 13px);
185 min-width: 220px;
186 height: 174px;
187 border: 1px solid rgba(229, 229, 229, 1);
188 border-radius: 4px;
189 cursor: pointer;
190 position: relative;
191
192 &:hover {
193 border-color: var(--el-color-primary);
194 }
195
196 .v-top {
197 height: 48px;
198 padding: 12px 16px;
199 display: flex;
200
201 .title {
202 font-size: 16px;
203 color: #212121;
204 line-height: 24px;
205 font-weight: 600;
206 width: calc(100% - 58px);
207 white-space: nowrap;
208 /* 防止文本换行 */
209 overflow: hidden;
210 /* 隐藏超出容器的文本 */
211 text-overflow: ellipsis;
212 /* 显示省略号 */
213 }
214
215 .el-tag {
216 width: 50px;
217 text-align: center;
218 line-height: 18px;
219 }
220 }
221
222 .v-middle {
223 height: 80px;
224 display: flex;
225
226 .per {
227 width: 50%;
228 height: 100%;
229 display: flex;
230 flex-direction: column;
231 align-items: center;
232 justify-content: center;
233
234 .desc {
235 font-size: 14px;
236 color: #999999;
237 line-height: 21px;
238 margin-bottom: 4px;
239 }
240
241 .cnt {
242 font-size: 24px;
243 color: #44ABB4;
244 line-height: 36px;
245 font-weight: 600;
246 }
247 }
248 }
249
250 .v-bottom {
251 background: #FAFAFA;
252 height: 44px;
253 display: flex;
254 border-top: 1px solid rgba(229, 229, 229, 1);
255
256 .divider {
257 border-right: 1px solid rgba(229, 229, 229, 1);
258 }
259
260 .per {
261 width: 50%;
262 display: flex;
263 align-items: center;
264 justify-content: center;
265 padding: 8px 0px;
266 }
267 }
268 }
269 }
270 }
271
272 .empty-content {
273 display: flex;
274 align-items: center;
275 justify-content: center;
276 height: 100%;
277 width: 100%;
278 flex-direction: column;
279
280 .empty-text {
281 font-size: 14px;
282 color: #b2b2b2;
283 margin-top: 12px;
284 }
285 }
286 </style>
...\ No newline at end of file ...\ No newline at end of file
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!