diff --git a/frontend/src/api/embedded.ts b/frontend/src/api/embedded.ts
new file mode 100644
index 00000000..fccad9d7
--- /dev/null
+++ b/frontend/src/api/embedded.ts
@@ -0,0 +1,7 @@
+import { request } from '@/utils/request'
+
+export const getList = () => request.get('/system/assistant')
+export const updateAssistant = (data: any) => request.put('/system/assistant', data)
+export const saveAssistant = (data: any) => request.post('/system/assistant', data)
+export const getOne = (id: any) => request.get(`/system/assistant/${id}`)
+export const delOne = (id: any) => request.delete(`/system/assistant/${id}`)
diff --git a/frontend/src/assets/embedded/icon_copy_outlined.svg b/frontend/src/assets/embedded/icon_copy_outlined.svg
new file mode 100644
index 00000000..ec989b6c
--- /dev/null
+++ b/frontend/src/assets/embedded/icon_copy_outlined.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/src/assets/embedded/window.png b/frontend/src/assets/embedded/window.png
new file mode 100644
index 00000000..5441b79a
Binary files /dev/null and b/frontend/src/assets/embedded/window.png differ
diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json
index 36f089e8..5c803f1c 100644
--- a/frontend/src/i18n/en.json
+++ b/frontend/src/i18n/en.json
@@ -228,8 +228,8 @@
"got_it": "Got it",
"field_original_notes": "Field original notes",
"field_notes_1": "Field notes",
- "no_table":"No Table",
- "go_add":"Add"
+ "no_table": "No Table",
+ "go_add": "Add"
},
"model": {
"default_model": "Default model",
@@ -430,7 +430,12 @@
"target_credential_name": "Target credential name",
"target_credential": "Target credential",
"edit_advanced_applications": "Edit advanced applications",
- "edit_basic_applications": "Edit basic applications"
+ "edit_basic_applications": "Edit basic applications",
+ "delete": "delete {msg}?",
+ "code_to_embed": "Copy the following code to embed",
+ "floating_window_mode": "Floating window mode",
+ "copy_successful": "Copy successful",
+ "copy_failed": "Copy failed"
},
"chat": {
"type": "Chart Type",
@@ -476,4 +481,4 @@
"back_community": "Restore to Community Edition",
"confirm_tips": "Are you sure to restore to Community Edition?"
}
-}
+}
\ No newline at end of file
diff --git a/frontend/src/i18n/zh-CN.json b/frontend/src/i18n/zh-CN.json
index 3a2a5ed6..c0665465 100644
--- a/frontend/src/i18n/zh-CN.json
+++ b/frontend/src/i18n/zh-CN.json
@@ -231,8 +231,8 @@
"got_it": "知道了",
"field_original_notes": "字段原始备注",
"field_notes_1": "字段备注",
- "no_table":"暂无数据表",
- "go_add":"去添加"
+ "no_table": "暂无数据表",
+ "go_add": "去添加"
},
"model": {
"default_model": "默认模型",
@@ -442,7 +442,12 @@
"target_credential_name": "目标凭证名称",
"target_credential": "目标凭证",
"edit_advanced_applications": "编辑高级应用",
- "edit_basic_applications": "编辑基础应用"
+ "edit_basic_applications": "编辑基础应用",
+ "delete": "是否删除: {msg}?",
+ "code_to_embed": "复制以下代码进行嵌入",
+ "floating_window_mode": "浮窗模式",
+ "copy_successful": "复制成功",
+ "copy_failed": "复制失败"
},
"chat": {
"type": "图表类型",
@@ -488,4 +493,4 @@
"back_community": "还原至社区版",
"confirm_tips": "确定还原至社区版?"
}
-}
+}
\ No newline at end of file
diff --git a/frontend/src/views/system/embedded/DsCard.vue b/frontend/src/views/system/embedded/DsCard.vue
index 072ede49..a3eff0ae 100644
--- a/frontend/src/views/system/embedded/DsCard.vue
+++ b/frontend/src/views/system/embedded/DsCard.vue
@@ -49,7 +49,7 @@ const handlePublic = () => {
{{ name }}
{{ typeName }}
- {{
+ {{
isPrivate ? $t('embedded.private') : $t('embedded.public')
}}
@@ -127,7 +127,7 @@ const handlePublic = () => {
right: 0;
top: 12px;
- .is-private {
+ &.is-private {
background: #f54a4533;
color: #d03f3b;
}
diff --git a/frontend/src/views/system/embedded/index.vue b/frontend/src/views/system/embedded/index.vue
index f8d83d8e..7f7a6bf0 100644
--- a/frontend/src/views/system/embedded/index.vue
+++ b/frontend/src/views/system/embedded/index.vue
@@ -6,9 +6,14 @@ import icon_close_outlined from '@/assets/svg/operate/ope-close.svg'
import EmptyBackground from '@/views/dashboard/common/EmptyBackground.vue'
import icon_database_colorful from '@/assets/embedded/icon_database_colorful.png'
import icon_web_site_colorful from '@/assets/embedded/icon_web-site_colorful.png'
+import floating_window from '@/assets/embedded/window.png'
+import icon_copy_outlined from '@/assets/embedded/icon_copy_outlined.svg'
+
import Card from './Card.vue'
+import { workspaceList } from '@/api/workspace'
import DsCard from './DsCard.vue'
import { datasourceApi } from '@/api/datasource'
+import { getList, updateAssistant, saveAssistant, delOne } from '@/api/embedded'
import { useI18n } from 'vue-i18n'
import { cloneDeep } from 'lodash-es'
@@ -23,14 +28,14 @@ const dsFormRef = ref()
const urlFormRef = ref()
const dialogTitle = ref('')
const embeddedList = ref([])
-const systemCredentials = ref([])
-const credentials = ref([])
+const systemCredentials = ['localStorage', 'cookie', 'sessionStorage']
+const credentials = ['header', 'cookie', 'param']
const workspaces = ref([])
const defaultEmbedded = {
id: '',
name: '',
- isBase: false,
+ type: 0,
description: '',
domain: '',
}
@@ -38,19 +43,18 @@ const currentEmbedded = reactive(cloneDeep(defaultEmbedded))
const isCreate = ref(false)
const defaultForm = {
- workspace: '',
- id: '',
+ oid: '',
+ private_list: [] as any,
}
const dsForm = reactive(cloneDeep(defaultForm))
const defaultUrlForm = {
- url: '',
- system_credential_type: '',
- target_credential_location: '',
- credential_name: '',
- target_credential_name: '',
- target_credential: '',
- id: '',
+ endpoint: '',
+ type: '',
+ source: '',
+ target: '',
+ target_key: '',
+ target_val: '',
}
const urlForm = reactive(cloneDeep(defaultUrlForm))
@@ -68,20 +72,24 @@ const userTypeList = [
name: t('embedded.basic_application'),
img: icon_database_colorful,
tip: t('embedded.support_is_required'),
- value: 1,
+ value: 0,
},
{
name: t('embedded.advanced_application'),
img: icon_web_site_colorful,
tip: t('embedded.data_permissions_etc'),
- value: 0,
+ value: 1,
},
]
-const ruleType = ref(0)
+const initWorkspace = () => {
+ workspaceList().then((res) => {
+ workspaces.value = res
+ })
+}
const handleAddEmbedded = (val: any) => {
- ruleType.value = val
Object.assign(currentEmbedded, cloneDeep(defaultEmbedded))
- if (val === 1) {
+ currentEmbedded.type = val
+ if (val === 0) {
handleBaseEmbedded(null)
} else {
handleAdvancedEmbedded(null)
@@ -95,19 +103,10 @@ const getDsList = () => {
}
const handleBaseEmbedded = (row: any) => {
advancedApplication.value = false
+ initWorkspace()
getDsList()
if (row) {
- Object.assign(dsForm, cloneDeep(defaultForm))
- // const { name, ds_id, table_id, tree, id, ds_name, table_name } = row
- // Object.assign(dsForm, {
- // id,
- // name,
- // ds_id,
- // table_id,
- // ds_name,
- // table_name,
- // expression_tree: typeof tree === 'object' ? tree : JSON.parse(tree),
- // })
+ Object.assign(dsForm, JSON.parse(row.configuration))
}
ruleConfigvVisible.value = true
dialogTitle.value = row?.id
@@ -117,18 +116,9 @@ const handleBaseEmbedded = (row: any) => {
const handleAdvancedEmbedded = (row: any) => {
advancedApplication.value = true
if (row) {
- Object.assign(urlForm, cloneDeep(defaultUrlForm))
-
- // const { name, ds_id, table_id, id, permission_list, ds_name, table_name } = row
- // Object.assign(dsForm, {
- // id,
- // name,
- // ds_id,
- // ds_name,
- // table_id,
- // table_name,
- // permissions: permission_list,
- // })
+ const obj = JSON.parse(row.configuration)
+ Object.assign(urlForm, cloneDeep(obj.certificate))
+ urlForm.endpoint = obj.endpoint
}
ruleConfigvVisible.value = true
dialogTitle.value = row?.id
@@ -147,53 +137,34 @@ const handleActive = (row: any) => {
}
const handlePrivate = (row: any) => {
- console.log('row', row)
+ dsForm.private_list.push(row.id)
}
+
const handlePublic = (row: any) => {
- console.log('row', row)
+ dsForm.private_list = dsForm.private_list.filter((ele: any) => ele !== row.id)
}
const searchLoading = ref(false)
const handleSearch = () => {
- embeddedList.value = [
- {
- id: '1',
- name: 'jkajsdkjs',
- isBase: false,
- description: 'klasdkljlkasjdklljkajsdksa',
- },
- {
- id: '2',
- name: 'jkajsdkjsklk',
- isBase: true,
- description: 'kajldj',
- },
- ]
- // searchLoading.value = true
- // getList()
- // .then((res: any) => {
- // embeddedList.value = res || []
- // })
- // .finally(() => {
- // searchLoading.value = false
- // })
+ searchLoading.value = true
+ getList()
+ .then((res: any) => {
+ embeddedList.value = res || []
+ })
+ .finally(() => {
+ searchLoading.value = false
+ })
}
handleSearch()
-// const editForm = (row: any) => {
-// if (row.type === 'row') {
-// ruleType.value = 1
-// handleBaseEmbedded(row)
-// } else {
-// ruleType.value = 0
-// handleAdvancedEmbedded(row)
-// }
-// }
const handleEditRule = (row: any) => {
- editRule.value = 1
- isCreate.value = false
Object.assign(currentEmbedded, cloneDeep(row))
- ruleConfigvVisible.value = true
+ delete currentEmbedded.configuration
+ if (row.type === 0) {
+ handleBaseEmbedded(row)
+ } else {
+ handleAdvancedEmbedded(row)
+ }
}
// const deleteRuleHandler = (row: any) => {
@@ -211,20 +182,20 @@ const handleEditRule = (row: any) => {
// }
const deleteHandler = (row: any) => {
- ElMessageBox.confirm(t('permission.rule_group_1', { msg: row.name }), {
+ ElMessageBox.confirm(t('embedded.delete', { msg: row.name }), {
confirmButtonType: 'danger',
confirmButtonText: t('dashboard.delete'),
cancelButtonText: t('common.cancel'),
customClass: 'confirm-no_icon',
autofocus: false,
}).then(() => {
- // delPermissions(row.id).then(() => {
- // ElMessage({
- // type: 'success',
- // message: t('dashboard.delete_success'),
- // })
- // handleSearch()
- // })
+ delOne(row.id).then(() => {
+ ElMessage({
+ type: 'success',
+ message: t('dashboard.delete_success'),
+ })
+ handleSearch()
+ })
})
}
@@ -255,7 +226,14 @@ const rules = {
}
const dsRules = {
- workspace: [
+ oid: [
+ {
+ required: true,
+ message: t('datasource.please_enter') + t('common.empty') + t('user.workspace'),
+ trigger: 'change',
+ },
+ ],
+ private_list: [
{
required: true,
message: t('datasource.please_enter') + t('common.empty') + t('user.workspace'),
@@ -265,24 +243,22 @@ const dsRules = {
}
const urlRules = {
- url: [
+ endpoint: [
{
required: true,
message: t('datasource.please_enter') + t('common.empty') + t('embedded.interface_url'),
trigger: 'blur',
},
],
- system_credential_type: [
+ type: [
{
required: true,
message:
- t('datasource.Please_select') +
- t('common.empty') +
- t('embedded.target_credential_location'),
+ t('datasource.Please_select') + t('common.empty') + t('embedded.system_credential_type'),
trigger: 'change',
},
],
- credential_name: [
+ source: [
{
required: true,
message: t('datasource.please_enter') + t('common.empty') + t('embedded.credential_name'),
@@ -290,7 +266,7 @@ const urlRules = {
},
],
- target_credential_location: [
+ target: [
{
required: true,
message:
@@ -300,7 +276,7 @@ const urlRules = {
trigger: 'change',
},
],
- target_credential_name: [
+ target_key: [
{
required: true,
message:
@@ -309,7 +285,7 @@ const urlRules = {
},
],
- target_credential: [
+ target_val: [
{
required: true,
message: t('datasource.please_enter') + t('common.empty') + t('embedded.target_credential'),
@@ -318,16 +294,6 @@ const urlRules = {
],
}
-// const closeForm = () => {
-// dialogFormVisible.value = false
-// }
-// const saveHandler = () => {
-// dsFormRef.value.validate((res: any) => {
-// if (res) {
-// dialogFormVisible.value = false
-// }
-// })
-// }
const preview = () => {
activeStep.value = 0
}
@@ -339,17 +305,59 @@ const next = () => {
})
}
const saveEmbedded = () => {
- // const { id, name, permissions } = currentEmbedded
- // saveEmbeddeds(permissions).then(() => {
- // ElMessage({
- // type: 'success',
- // message: t('common.save_success'),
- // })
- // beforeClose()
- // handleSearch()
- // })
+ const req = currentEmbedded.id ? updateAssistant : saveAssistant
+ const formRef = currentEmbedded.type === 1 ? urlFormRef : dsFormRef
+ formRef.value.validate((res: any) => {
+ if (res) {
+ const obj = { ...currentEmbedded }
+ if (currentEmbedded.type === 0) {
+ obj.configuration = JSON.stringify(dsForm)
+ } else {
+ obj.configuration = JSON.stringify({
+ endpoint: urlForm.endpoint,
+ certificate: { ...urlForm },
+ })
+ }
+
+ if (!currentEmbedded.id) {
+ delete obj.id
+ }
+ req(obj).then(() => {
+ ElMessage({
+ type: 'success',
+ message: t('common.save_success'),
+ })
+ beforeClose()
+ handleSearch()
+ })
+ }
+ })
}
const btnSelect = ref('d')
+
+const dialogVisible = ref(false)
+const scriptElement = ref('')
+const handleEmbedded = (row: any) => {
+ dialogVisible.value = true
+ const { origin, pathname } = window.location
+ scriptElement.value = `g-#script
+ async
+ defer
+ id="${row.id}"
+ src="${origin + pathname}assistant.js?id=${row.id}"k-*g-#/scriptk-*`
+ .replaceAll('g-#', '<')
+ .replaceAll('k-*', '>')
+}
+const copyCode = () => {
+ navigator.clipboard
+ .writeText(scriptElement.value)
+ .then(function () {
+ ElMessage.success(t('embedded.copy_successful'))
+ })
+ .catch(function () {
+ ElMessage.error(t('embedded.copy_successful'))
+ })
+}
@@ -419,8 +427,9 @@ const btnSelect = ref('d')
:id="ele.id"
:key="ele.id"
:name="ele.name"
- :is-base="ele.isBase"
+ :is-base="ele.type === 0"
:description="ele.description"
+ @embedded="handleEmbedded(ele)"
@edit="handleEditRule(ele)"
@del="deleteHandler(ele)"
>
@@ -546,65 +555,57 @@ const btnSelect = ref('d')
class="form-content_error"
@submit.prevent
>
-
+
-
+
-
+
-
+
-
+
-
+
+
-
+
+
+
+
+
{{ $t('embedded.floating_window_mode') }}
+
![]()
+
+
+
+ {{ $t('embedded.code_to_embed') }}
+
+
+
+
+
+
+ {{ scriptElement }}
+
+
+
+
diff --git a/frontend/src/views/system/member/index.vue b/frontend/src/views/system/member/index.vue
index 1f680d21..e5a19580 100644
--- a/frontend/src/views/system/member/index.vue
+++ b/frontend/src/views/system/member/index.vue
@@ -160,6 +160,7 @@ const userInfo = ref({
})
const afterFind = ref(false)
const findUser = () => {
+ if (!workspaceForm.name) return
uwsOption({ keyword: workspaceForm.name })
.then((res: any) => {
userInfo.value = res || {}