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')) + }) +} 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 || {}