Skip to content

Commit 01ca5ec

Browse files
feat: Add Wecom Configuration Form
1 parent d56e477 commit 01ca5ec

File tree

15 files changed

+2452
-1
lines changed

15 files changed

+2452
-1
lines changed

frontend/src/i18n/en.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,13 @@
756756
"setting_successfully": "Setting Successfully",
757757
"customize_theme_color": "Customize theme color"
758758
},
759+
"platform": {
760+
"title": "Platform Integration",
761+
"status_open": "Enabled",
762+
"status_close": "Disabled",
763+
"access_in": "Access",
764+
"can_enable_it": "Can be enabled after successful test connection"
765+
},
759766
"authentication": {
760767
"invalid": "Invalid",
761768
"valid": "Valid",

frontend/src/i18n/ko-KR.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,13 @@
756756
"setting_successfully": "설정 성공",
757757
"customize_theme_color": "사용자 정의 테마 색상"
758758
},
759+
"platform": {
760+
"title": "플랫폼 연동",
761+
"status_open": "활성화됨",
762+
"status_close": "비활성화됨",
763+
"access_in": "접속",
764+
"can_enable_it": "연결 테스트 성공 후 활성화 가능"
765+
},
759766
"authentication": {
760767
"invalid": "유효하지 않음",
761768
"valid": "유효함",

frontend/src/i18n/zh-CN.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,6 @@
215215
"chart_selected": "已选{0}"
216216
},
217217
"qa": {
218-
"recommended_repetitive_tips": "Duplicate questions exist",
219218
"retrieve_error": "暂无内容",
220219
"retrieve_again": "重新获取",
221220
"recently": "最近",
@@ -757,6 +756,13 @@
757756
"setting_successfully": "设置成功",
758757
"customize_theme_color": "自定义主题色"
759758
},
759+
"platform": {
760+
"title": "平台对接",
761+
"status_open": "已开启",
762+
"status_close": "已关闭",
763+
"access_in": "接入",
764+
"can_enable_it": "测试连接有效后,可开启"
765+
},
760766
"authentication": {
761767
"invalid": "无效",
762768
"valid": "有效",

frontend/src/router/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import Audit from '@/views/system/audit/index.vue'
2121
import Appearance from '@/views/system/appearance/index.vue'
2222
import Parameter from '@/views/system/parameter/index.vue'
2323
import Authentication from '@/views/system/authentication/index.vue'
24+
import Platform from '@/views/system/platform/index.vue'
2425
import Permission from '@/views/system/permission/index.vue'
2526
import User from '@/views/system/user/User.vue'
2627
import Workspace from '@/views/system/workspace/index.vue'
@@ -212,6 +213,12 @@ export const routes = [
212213
component: Authentication,
213214
meta: { title: t('system.authentication_settings') },
214215
},
216+
{
217+
path: 'platform',
218+
name: 'platform',
219+
component: Platform,
220+
meta: { title: t('platform.title') },
221+
},
215222
],
216223
},
217224
{
Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
<template>
2+
<div class="info-template-container">
3+
<div v-if="!props.hideHead" class="info-template-header">
4+
<div class="info-template-title">
5+
<span>{{ curTitle }}</span>
6+
</div>
7+
<div>
8+
<el-button v-if="testConnectText" secondary @click="check">{{ testConnectText }}</el-button>
9+
<el-button v-if="showValidate" secondary @click="check">{{
10+
t('datasource.validate')
11+
}}</el-button>
12+
<el-button type="primary" @click="edit">{{ t('commons.edit') }}</el-button>
13+
</div>
14+
</div>
15+
<div class="info-template-content clearfix">
16+
<div v-for="item in settingList" :key="item.pkey" class="info-content-item">
17+
<div class="info-item-label">
18+
<!-- <span>{{ t(item.pkey) }}</span> -->
19+
<span>{{ item.pkey }}</span>
20+
<el-tooltip
21+
v-if="tooltipItem[item.pkey]"
22+
effect="dark"
23+
:content="tooltipItem[item.pkey]"
24+
placement="top"
25+
>
26+
<el-icon class="info-tips"
27+
><Icon name="dv-info"><dvInfo class="svg-icon" /></Icon
28+
></el-icon>
29+
</el-tooltip>
30+
</div>
31+
<div class="info-item-content">
32+
<div v-if="item.type === 'pwd'" class="info-item-pwd">
33+
<span class="info-item-pwd-span">{{
34+
pwdItem[item.pkey]['hidden'] ? '********' : item.pval
35+
}}</span>
36+
37+
<el-tooltip
38+
v-if="props.copyList.includes(item.pkey)"
39+
effect="dark"
40+
:content="t('datasource.copy')"
41+
placement="top"
42+
>
43+
<el-button text class="setting-tip-btn" @click="copyVal(item.pval)">
44+
<template #icon>
45+
<Icon name="de-copy"><icon_copy_outlined class="svg-icon" /></Icon>
46+
</template>
47+
</el-button>
48+
</el-tooltip>
49+
50+
<el-tooltip
51+
effect="dark"
52+
:content="
53+
pwdItem[item.pkey]['hidden']
54+
? t('embedded.click_to_show')
55+
: t('embedded.click_to_hide')
56+
"
57+
placement="top"
58+
>
59+
<el-button text class="setting-tip-btn" @click="switchPwd(item.pkey)">
60+
<template #icon>
61+
<Icon
62+
><component
63+
:is="
64+
pwdItem[item.pkey]['hidden']
65+
? icon_invisible_outlined
66+
: icon_visible_outlined
67+
"
68+
class="svg-icon"
69+
></component
70+
></Icon>
71+
</template>
72+
</el-button>
73+
</el-tooltip>
74+
</div>
75+
<!-- <span v-else-if="item.pkey.includes('basic.dsIntervalTime')">
76+
<span>{{ item.pval + ' ' + executeTime + t('common.every_exec') }}</span>
77+
</span> -->
78+
<template v-else>
79+
<div class="info-item-content-val">
80+
<span style="word-break: break-all">{{ item.pval }}</span>
81+
<el-tooltip
82+
v-if="props.copyList.includes(item.pkey)"
83+
effect="dark"
84+
:content="t('datasource.copy')"
85+
placement="top"
86+
>
87+
<el-icon class="info-tips hover-icon_with_bg" @click="copyVal(item.pval)">
88+
<icon_copy_outlined class="svg-icon" />
89+
</el-icon>
90+
</el-tooltip>
91+
</div>
92+
</template>
93+
</div>
94+
</div>
95+
</div>
96+
</div>
97+
</template>
98+
<script lang="ts" setup>
99+
import icon_copy_outlined from '@/assets/svg/icon_copy_outlined.svg'
100+
import icon_invisible_outlined from '@/assets/embedded/icon_invisible_outlined.svg'
101+
import icon_visible_outlined from '@/assets/embedded/icon_visible_outlined.svg'
102+
import dvInfo from '@/assets/svg/dashboard-info.svg'
103+
import { ref, computed, type PropType } from 'vue'
104+
import { useI18n } from 'vue-i18n'
105+
import { useClipboard } from '@vueuse/core'
106+
import { ElMessage } from 'element-plus-secondary'
107+
import type { SettingRecord, ToolTipRecord } from './SettingTemplate'
108+
const { copy } = useClipboard({ legacy: true })
109+
const { t } = useI18n()
110+
const props = defineProps({
111+
settingKey: {
112+
type: String,
113+
default: 'basic',
114+
},
115+
labelTooltips: {
116+
type: Array as PropType<ToolTipRecord[]>,
117+
default: () => [],
118+
},
119+
settingData: {
120+
type: Array as PropType<SettingRecord[]>,
121+
default: () => [],
122+
},
123+
settingTitle: {
124+
type: String,
125+
default: '',
126+
},
127+
hideHead: {
128+
type: Boolean,
129+
default: false,
130+
},
131+
showValidate: {
132+
type: Boolean,
133+
default: false,
134+
},
135+
testConnectText: {
136+
type: String,
137+
default: null,
138+
},
139+
copyList: {
140+
type: Array as PropType<string[]>,
141+
default: () => [],
142+
},
143+
})
144+
// const executeTime = ref(t('system.and_0_seconds'))
145+
const curTitle = computed(() => {
146+
return props.settingTitle || t('system.basic_settings')
147+
})
148+
const copyVal = async (val: any) => {
149+
try {
150+
await copy(val)
151+
ElMessage.success(t('embedded.copy_successful'))
152+
} catch (e) {
153+
console.error(e)
154+
ElMessage.warning(t('embedded.copy_failed'))
155+
}
156+
}
157+
const loadList = () => {
158+
settingList.value = []
159+
if (props.settingData?.length) {
160+
props.settingData.forEach((item) => {
161+
/* if (item.pkey.includes('basic.dsExecuteTime')) {
162+
executeTime.value = getExecuteTime(item.pval)
163+
} else {
164+
settingList.value.push(item)
165+
} */
166+
settingList.value.push(item)
167+
})
168+
}
169+
}
170+
171+
/* const getExecuteTime = (val: any) => {
172+
const options = [
173+
{ value: 'minute', label: t('system.time_0_seconds') },
174+
{ value: 'hour', label: t('system.and_0_seconds_de') },
175+
]
176+
return options.filter((item) => item.value === val)[0].label
177+
} */
178+
179+
const settingList = ref([] as SettingRecord[])
180+
181+
const init = () => {
182+
if (props.settingData?.length) {
183+
loadList()
184+
}
185+
}
186+
const pwdItem = ref({} as Record<string, { hidden: boolean }>)
187+
188+
const formatPwd = () => {
189+
settingList.value.forEach((setting) => {
190+
if (setting.type === 'pwd') {
191+
pwdItem.value[setting.pkey] = { hidden: true }
192+
}
193+
})
194+
}
195+
196+
const tooltipItem = ref({} as Record<string, any>)
197+
const formatLabel = () => {
198+
if (props.labelTooltips?.length) {
199+
props.labelTooltips.forEach((tooltip) => {
200+
tooltipItem.value[tooltip.key] = tooltip.val
201+
})
202+
}
203+
}
204+
205+
const switchPwd = (pkey: string) => {
206+
pwdItem.value[pkey]['hidden'] = !pwdItem.value[pkey]['hidden']
207+
}
208+
209+
const emits = defineEmits(['edit', 'check'])
210+
const edit = () => {
211+
emits('edit')
212+
}
213+
214+
const check = () => {
215+
emits('check')
216+
}
217+
defineExpose({
218+
init,
219+
})
220+
init()
221+
formatPwd()
222+
formatLabel()
223+
</script>
224+
225+
<style lang="less" scope>
226+
.setting-tip-btn {
227+
height: 24px !important;
228+
width: 24px !important;
229+
margin-left: 4px !important;
230+
.ed-icon {
231+
font-size: 16px;
232+
}
233+
}
234+
.info-template-container {
235+
padding: 24px 24px 8px 24px;
236+
background: var(--ContentBG, #ffffff);
237+
border-radius: 4px;
238+
.info-template-header {
239+
display: flex;
240+
margin-top: -4px;
241+
align-items: center;
242+
justify-content: space-between;
243+
.info-template-title {
244+
height: 24px;
245+
line-height: 23px;
246+
font-size: 16px;
247+
font-weight: 500;
248+
color: #1f2329;
249+
}
250+
}
251+
.info-template-content {
252+
width: 100%;
253+
margin-top: 12px;
254+
.info-content-item {
255+
width: 50%;
256+
float: left;
257+
margin-bottom: 16px;
258+
min-height: 46px;
259+
.info-item-label {
260+
height: 22px;
261+
line-height: 22px;
262+
display: flex;
263+
align-items: center;
264+
span {
265+
font-size: 14px;
266+
color: #646a73;
267+
font-weight: 400;
268+
}
269+
i {
270+
margin-left: 2px;
271+
}
272+
}
273+
.info-item-content {
274+
line-height: 22px;
275+
span {
276+
font-size: 14px;
277+
color: #1f2329;
278+
font-weight: 400;
279+
}
280+
281+
.info-item-pwd {
282+
height: 22px;
283+
line-height: 22px;
284+
width: 100%;
285+
display: flex;
286+
align-items: center;
287+
i {
288+
margin-left: 2px;
289+
}
290+
.info-item-pwd-span {
291+
max-width: calc(100% - 84px);
292+
overflow: hidden;
293+
white-space: nowrap;
294+
text-overflow: ellipsis;
295+
}
296+
}
297+
.info-item-content-val {
298+
display: flex;
299+
align-items: center;
300+
column-gap: 6px;
301+
.hover-icon_with_bg {
302+
color: var(--ed-color-primary);
303+
background-color: var(--ed-button-hover-bg-color);
304+
/* &::after {
305+
background: var(--ed-button-hover-bg-color);
306+
} */
307+
}
308+
}
309+
}
310+
}
311+
}
312+
.clearfix::after {
313+
content: '';
314+
display: table;
315+
clear: both;
316+
}
317+
}
318+
</style>

0 commit comments

Comments
 (0)