Compare commits
19 Commits
Author | SHA1 | Date |
---|---|---|
|
2c3e5fe10f | 3 years ago |
|
d0a2de9d07 | 3 years ago |
|
e7e360db60 | 4 years ago |
|
244bca2c2c | 4 years ago |
|
7619fc3a9d | 4 years ago |
|
eba23d6024 | 4 years ago |
|
8bd74f7c75 | 4 years ago |
|
f7fbdfc19a | 4 years ago |
|
d5d98515a0 | 4 years ago |
|
05a19463dd | 4 years ago |
|
fed5c223c3 | 4 years ago |
|
8fe7c7ba4b | 4 years ago |
|
2ee5dc2ac4 | 4 years ago |
|
871975049f | 4 years ago |
|
a73f14c3e9 | 4 years ago |
|
81b073aa2a | 4 years ago |
|
215192d1d5 | 4 years ago |
|
a063e9b1c9 | 4 years ago |
|
14f543c58e | 4 years ago |
41 changed files with 2462 additions and 699 deletions
@ -1 +1,2 @@ |
|||||
VITE_API_URL=http://localhost:4001 |
VITE_API_URL=https://test.tall.wiki |
||||
|
VITE_API_URL_NEW=http://101.201.226.163 |
||||
|
@ -1 +1,2 @@ |
|||||
VITE_API_URL=http://139.196.27.233:29001 |
VITE_API_URL=http://www.tall.wiki |
||||
|
VITE_API_URL_NEW=http://101.201.226.163 |
||||
|
@ -1 +1,2 @@ |
|||||
VITE_API_URL=https://test.tall.wiki |
VITE_API_URL=https://test.tall.wiki |
||||
|
VITE_API_URL_NEW=http://101.201.226.163 |
||||
|
File diff suppressed because it is too large
@ -0,0 +1,30 @@ |
|||||
|
// noinspection SpellCheckingInspection
|
||||
|
|
||||
|
import http from 'utils/axios'; |
||||
|
|
||||
|
const apiUrl = import.meta.env.VITE_API_URL_NEW; |
||||
|
const business = `${apiUrl}/gateway/opt/business`; |
||||
|
|
||||
|
// 查询业务列表
|
||||
|
export const queryBusiness = params => http.post(`${business}/query`, params); |
||||
|
|
||||
|
// 查询业务下关联的插件
|
||||
|
export const queryPluginByBusiness = params => http.post(`${business}/queryPlugin`, params); |
||||
|
|
||||
|
// 关联业务和插件
|
||||
|
export const relevance = params => http.post(`${business}/relevance`, params); |
||||
|
|
||||
|
// 添加业务信息
|
||||
|
export const saveBusiness = params => http.post(`${business}/save`, params); |
||||
|
|
||||
|
// 修改业务下的插件配置信息
|
||||
|
export const updateConfig = params => http.post(`${business}/updateConfig`, params); |
||||
|
|
||||
|
// 通过id查询业务信息
|
||||
|
export const queryIdBusiness = params => http.post(`${business}/queryIdBusiness`, params); |
||||
|
|
||||
|
// 移除业务下关联的插件
|
||||
|
export const delRelevance = params => http.post(`${business}/delRelevance`, params); |
||||
|
|
||||
|
// 删除业务
|
||||
|
export const delBusiness = params => http.post(`${business}/del`, params); |
@ -0,0 +1,21 @@ |
|||||
|
// noinspection SpellCheckingInspection
|
||||
|
|
||||
|
import http from 'utils/axios'; |
||||
|
|
||||
|
const apiUrl = import.meta.env.VITE_API_URL_NEW; |
||||
|
const plugin = `${apiUrl}/gateway/opt/plugin`; |
||||
|
|
||||
|
// 查询插件列表
|
||||
|
export const queryPlugins = params => http.post(`${plugin}/query`, params); |
||||
|
|
||||
|
// 获取一个随机id
|
||||
|
export const randomId = params => http.post(`${plugin}/randomId`, params); |
||||
|
|
||||
|
// 创建插件
|
||||
|
export const savePlugin = params => http.post(`${plugin}/save`, params); |
||||
|
|
||||
|
// 修改插件信息
|
||||
|
export const updatePlugin = params => http.post(`${plugin}/update`, params); |
||||
|
|
||||
|
// 删除插件
|
||||
|
export const delPlugin = params => http.post(`${plugin}/del`, params); |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 2.3 KiB |
@ -0,0 +1,19 @@ |
|||||
|
<template> |
||||
|
<el-breadcrumb separator="/"> |
||||
|
<el-breadcrumb-item v-for="(item, index) in path" :key="index"> |
||||
|
<span @click="router.push({ name: item.name })" v-if="index !== path.length - 1" class="font-bold cursor-pointer">{{ |
||||
|
item.title |
||||
|
}}</span> |
||||
|
<span v-else>{{ item.title }}</span> |
||||
|
</el-breadcrumb-item> |
||||
|
</el-breadcrumb> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { useRouter } from 'vue-router'; |
||||
|
import { defineProps } from 'vue'; |
||||
|
|
||||
|
const router = useRouter(); |
||||
|
|
||||
|
defineProps({ path: { default: () => [], type: Array } }); |
||||
|
</script> |
@ -0,0 +1,81 @@ |
|||||
|
<template> |
||||
|
<el-button type="primary" @click="data.dialogVisible = true">配置</el-button> |
||||
|
<el-dialog v-model="data.dialogVisible" title="配置" width="40%"> |
||||
|
<!-- main --> |
||||
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="150px" class="forms"> |
||||
|
<el-form-item label="配置文件:" prop="config"> |
||||
|
<el-input v-model="form.config" type="textarea" placeholder="请输入配置文件"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item> <el-switch v-model="form.debug" class="mr-3"></el-switch> 是否开启debug模式 </el-form-item> |
||||
|
<el-form-item> |
||||
|
<el-button type="primary" @click="onSubmit()">发布</el-button> |
||||
|
<el-button @click="resetForm()">重置</el-button> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { defineProps, reactive, ref } from 'vue'; |
||||
|
import { ElMessage } from 'element-plus'; |
||||
|
import { updateConfig } from '@/apis/business'; |
||||
|
|
||||
|
const formRef = ref(null); |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
businessPluginId: { default: '', type: String }, |
||||
|
oldConfig: { default: '', type: String }, |
||||
|
oldDebug: { default: 0, type: Number }, |
||||
|
}); |
||||
|
|
||||
|
const form = reactive({ |
||||
|
config: '', |
||||
|
debug: false, |
||||
|
}); |
||||
|
|
||||
|
const rules = { config: [{ required: true, message: '请输入配置文件', trigger: 'blur' }] }; |
||||
|
|
||||
|
const data = reactive({ dialogVisible: false }); |
||||
|
|
||||
|
if (props.oldConfig) { |
||||
|
form.config = props.oldConfig; |
||||
|
} |
||||
|
if (props.oldDebug) { |
||||
|
form.debug = props.oldDebug === 1; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 配置修改 |
||||
|
* @param {object} params |
||||
|
*/ |
||||
|
function onSubmit() { |
||||
|
try { |
||||
|
formRef.value.validate(async valid => { |
||||
|
if (valid) { |
||||
|
const params = { |
||||
|
param: { |
||||
|
businessPluginId: props.businessPluginId, |
||||
|
config: form.config, |
||||
|
debug: form.debug ? 1 : 0, |
||||
|
}, |
||||
|
}; |
||||
|
await updateConfig(params); |
||||
|
ElMessage.success('配置修改成功'); |
||||
|
resetForm(); |
||||
|
data.dialogVisible = true; |
||||
|
} else { |
||||
|
console.log('error submit!!'); |
||||
|
return false; |
||||
|
} |
||||
|
}); |
||||
|
} catch (error) { |
||||
|
ElMessage.error(error || '配置修改失败'); |
||||
|
console.error('error: ', error); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 重置 |
||||
|
function resetForm() { |
||||
|
formRef.value.resetFields(); |
||||
|
} |
||||
|
</script> |
@ -0,0 +1,45 @@ |
|||||
|
<template> |
||||
|
<el-menu :default-active="data.menuIndex" class="el-menu-demo" mode="vertical" @select="handleSelect"> |
||||
|
<el-menu-item :disabled="list.disabled" :index="index" @click="openPage(list.name)" v-for="(list, index) in data.menus" :key="index"> |
||||
|
{{ list.title }} |
||||
|
</el-menu-item> |
||||
|
</el-menu> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { useStore } from 'vuex'; |
||||
|
import { reactive, computed, watchEffect } from 'vue'; |
||||
|
import { useRouter } from 'vue-router'; |
||||
|
|
||||
|
const store = useStore(); |
||||
|
const leftIndex = computed(() => store.state.plugin.leftIndex); |
||||
|
|
||||
|
const router = useRouter(); |
||||
|
const data = reactive({ |
||||
|
menus: [ |
||||
|
{ title: '概览', name: '', disabled: true }, |
||||
|
{ title: '创建业务', name: 'desk-add-business', disabled: false }, |
||||
|
{ title: '创建插件', name: 'desk-add-plugin', disabled: false }, |
||||
|
{ title: '我的业务', name: 'desk-business-list', disabled: false }, |
||||
|
{ title: '我的插件', name: 'desk-plugin-list', disabled: false }, |
||||
|
], |
||||
|
menuIndex: '', |
||||
|
}); |
||||
|
|
||||
|
console.log('menuIndex: ', data.menuIndex); |
||||
|
watchEffect(() => { |
||||
|
if (leftIndex && leftIndex.value) { |
||||
|
data.menuIndex = leftIndex.value; |
||||
|
console.log('data.menuIndex: ', data.menuIndex); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
function handleSelect(e) { |
||||
|
store.commit('plugin/setLeftIndex', e); |
||||
|
} |
||||
|
|
||||
|
// 点击跳转路由 |
||||
|
function openPage(name) { |
||||
|
router.push({ name }); |
||||
|
} |
||||
|
</script> |
@ -0,0 +1,215 @@ |
|||||
|
<template> |
||||
|
<div v-if="data.listArray && data.listArray.length"> |
||||
|
<div class="shop-content flex py-5" v-for="(list, index) in data.listArray" :key="list.id"> |
||||
|
<img :src="list.preview" alt="" class="shop-left" /> |
||||
|
<div class="shop-right ml-8"> |
||||
|
<div> |
||||
|
<span class="text-xl font-semibold">{{ list.name }}</span> <span class="ml-5 text-sm">{{ list.versions }}</span> |
||||
|
</div> |
||||
|
<div class="mt-4 desc text-sm"> |
||||
|
<span> 描述:</span> <span>{{ list.intro }}</span> |
||||
|
</div> |
||||
|
<div class="mt-5 text-sm" v-if="list.tags && list.tags.length"> |
||||
|
<el-tag v-for="item in list.tags" :type="item.btnType" class="mr-3" :key="item.name">{{ item.name }}</el-tag> |
||||
|
</div> |
||||
|
<div class="mt-5 text-sm flex flex-row"> |
||||
|
<span>行业:</span> <span>{{ list.industryName || '无' }}</span> <span class="ml-8">分类:</span> |
||||
|
<span>{{ list.sortName || '无' }}</span> |
||||
|
</div> |
||||
|
<div class="mt-4 text-sm"> |
||||
|
<span>更新日期:</span> <span>{{ list.updateTime || '无' }}</span> <span class="ml-8">作者:</span> |
||||
|
<span>{{ list.authorName || '无' }}</span> |
||||
|
</div> |
||||
|
<div class="mt-6"> |
||||
|
<el-popconfirm |
||||
|
title="确定要移除该插件吗?" |
||||
|
confirm-button-text="确定" |
||||
|
cancel-button-text="再想想" |
||||
|
v-if="showConfig" |
||||
|
@confirm="deleteRelevance(list)" |
||||
|
> |
||||
|
<template #reference> |
||||
|
<el-button type="primary">移除</el-button> |
||||
|
</template> |
||||
|
</el-popconfirm> |
||||
|
<el-button type="primary" disabled>下载源代码</el-button> |
||||
|
<el-button type="primary" disabled>下载示例代码</el-button> |
||||
|
<!-- 添加到业务弹框 --> |
||||
|
<el-popover placement="right" title="请选择业务" :width="240" trigger="click" v-if="!showConfig"> |
||||
|
<div class="radio-box"> |
||||
|
<Relevance |
||||
|
:businessLists="data.businessLists" |
||||
|
:pluginId="list.id" |
||||
|
:isLastPage="data.isLastPage" |
||||
|
@changePageNum="changePageNum" |
||||
|
/> |
||||
|
</div> |
||||
|
<template #reference> |
||||
|
<el-button type="primary" @click="handleQueryBusiness">添加到业务</el-button> |
||||
|
</template> |
||||
|
</el-popover> |
||||
|
<!-- 配置 --> |
||||
|
<!-- <el-button type="primary" v-if="showConfig" @click="data.dialogVisible = true">配置</el-button> --> |
||||
|
<Configure v-if="showConfig" :businessPluginId="list.businessPluginId" :oldConfig="list.config" :oldDebug="list.debug" /> |
||||
|
<!-- 预览 --> |
||||
|
<el-button type="primary" @click="collapseVisible(index)" style="margin-left: 10px">{{ |
||||
|
!list.visible ? '预览' : '关闭预览' |
||||
|
}}</el-button> |
||||
|
<div class="plugin-box" v-if="list.visible"> |
||||
|
<div class="plugin w-full h-full overflow-y-scroll"> |
||||
|
<Plugin :plugin="list" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<el-empty v-else description="暂无插件信息"></el-empty> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts" setup="true"> |
||||
|
import { defineProps, reactive, watchEffect, defineEmits } from 'vue'; |
||||
|
import { ElMessage } from 'element-plus'; |
||||
|
import { queryBusiness, delRelevance } from '@/apis/business.js'; |
||||
|
|
||||
|
const data = reactive({ |
||||
|
currentPage: 1, |
||||
|
businessLists: [], |
||||
|
isLastPage: false, |
||||
|
listArray: [], |
||||
|
}); |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
lists: { default: () => [], type: Array }, |
||||
|
showConfig: { default: false, type: Boolean }, |
||||
|
businessId: { default: '', type: String }, |
||||
|
}); |
||||
|
|
||||
|
const emit = defineEmits(['queryPluginOfBusiness']); |
||||
|
|
||||
|
watchEffect(() => { |
||||
|
if (props.lists && props.lists.length) { |
||||
|
data.listArray = []; |
||||
|
props.lists.forEach(item => { |
||||
|
item.visible = false; |
||||
|
data.listArray.push(item); |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
// 换页 |
||||
|
function changePageNum() { |
||||
|
data.currentPage++; |
||||
|
handleQueryBusiness(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询业务列表 |
||||
|
* @param {number} depth 查询深度 0则只查名称,1则查询全部 |
||||
|
* @param {number} name 插件名称,为空则不实用该条件 |
||||
|
* @param {number} pageNum 第几页 |
||||
|
* @param {number} pageSize 每页几条信息 |
||||
|
*/ |
||||
|
async function handleQueryBusiness() { |
||||
|
try { |
||||
|
const { currentPage } = data; |
||||
|
if (currentPage === 1) { |
||||
|
data.businessLists = []; |
||||
|
} |
||||
|
const params = { |
||||
|
param: { |
||||
|
depth: 0, |
||||
|
name: '', |
||||
|
pageNum: currentPage, |
||||
|
pageSize: 10, |
||||
|
}, |
||||
|
}; |
||||
|
const res = await queryBusiness(params); |
||||
|
if (res.list.length) { |
||||
|
res.list.forEach(item => { |
||||
|
data.businessLists.push(item); |
||||
|
}); |
||||
|
} |
||||
|
data.currentPage = res.pageNum - 0; |
||||
|
data.isLastPage = res.isLastPage; |
||||
|
} catch (error) { |
||||
|
console.error('error: ', error); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 预览 |
||||
|
function collapseVisible(index) { |
||||
|
data.listArray.forEach((item, i) => { |
||||
|
if (i === index) { |
||||
|
item.visible = !item.visible; |
||||
|
} else { |
||||
|
item.visible = false; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 移除业务下的插件 |
||||
|
*/ |
||||
|
async function deleteRelevance(list) { |
||||
|
try { |
||||
|
const params = { param: { businessPluginId: list.businessPluginId } }; |
||||
|
await delRelevance(params); |
||||
|
ElMessage.success('删除成功'); |
||||
|
emit('queryPluginOfBusiness', props.businessId); |
||||
|
} catch (error) { |
||||
|
ElMessage.success(error || '删除失败'); |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.el-input { |
||||
|
width: 20%; |
||||
|
margin-right: 2rem; |
||||
|
} |
||||
|
.el-select { |
||||
|
margin-right: 2rem; |
||||
|
width: 20%; |
||||
|
} |
||||
|
.desc { |
||||
|
height: 30px; |
||||
|
line-height: 15px; |
||||
|
text-overflow: -o-ellipsis-lastline; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
display: -webkit-box; |
||||
|
-webkit-line-clamp: 2; |
||||
|
line-clamp: 2; |
||||
|
-webkit-box-orient: vertical; |
||||
|
} |
||||
|
.shop-left { |
||||
|
width: 288px; |
||||
|
height: 263px; |
||||
|
} |
||||
|
|
||||
|
.radio-box { |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.radio-box >>> .el-radio { |
||||
|
min-width: 100%; |
||||
|
margin: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.plugin-box { |
||||
|
position: fixed; |
||||
|
right: 14rem; |
||||
|
background: url(../assets/iPhone13.png) no-repeat; |
||||
|
background-size: contain; |
||||
|
width: 19.375rem; |
||||
|
height: 39.2419rem; |
||||
|
top: calc(50vh - 289.93512px + 1.8rem); |
||||
|
padding: 2.8rem 1.2rem 2rem; |
||||
|
z-index: 99; |
||||
|
} |
||||
|
|
||||
|
.plugin::-webkit-scrollbar { |
||||
|
display: none; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,54 @@ |
|||||
|
<template> |
||||
|
<div class="flex flex-row justify-space-between items-center"> |
||||
|
<div class="flex flex-row items-center"> |
||||
|
<div>业务名称:</div> |
||||
|
<el-input disabled v-model="data.keywords" placeholder="请输入业务名称或标签搜索" class="search-input mr-10" /> |
||||
|
<div>状态:</div> |
||||
|
<el-select disabled v-model="data.status" placeholder="请选择" class="search-input" @change="changeState"> |
||||
|
<el-option v-for="item in data.statusList" :key="item.value" :label="item.label" :value="item.value"> </el-option> |
||||
|
</el-select> |
||||
|
</div> |
||||
|
<div class="flex-1 ml-10"> |
||||
|
<el-button type="primary" size="small" class="w-60px h-40px" disabled>查询</el-button> |
||||
|
<el-button size="small" class="w-60px h-40px reset" disabled>重置</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts" setup="true"> |
||||
|
import { reactive } from 'vue'; |
||||
|
|
||||
|
const data = reactive({ |
||||
|
keywords: '', |
||||
|
status: '', |
||||
|
statusList: [ |
||||
|
{ |
||||
|
value: '状态一', |
||||
|
label: '状态一', |
||||
|
}, |
||||
|
{ |
||||
|
value: '状态二', |
||||
|
label: '状态二', |
||||
|
}, |
||||
|
{ |
||||
|
value: '状态三', |
||||
|
label: '状态三', |
||||
|
}, |
||||
|
], |
||||
|
}); |
||||
|
|
||||
|
function changeState(e) { |
||||
|
console.log('e: ', e); |
||||
|
data.status = e; |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.search-input { |
||||
|
width: 18rem; |
||||
|
} |
||||
|
|
||||
|
.reset { |
||||
|
margin-left: 0.75rem; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,117 @@ |
|||||
|
<template> |
||||
|
<div v-if="lists && lists.length"> |
||||
|
<el-table :data="lists" class="bg-title" style="width: 100%"> |
||||
|
<el-table-column prop="name" label="业务名称"> </el-table-column> |
||||
|
<el-table-column prop="appId" label="APPID" width="300"> </el-table-column> |
||||
|
<el-table-column prop="startUsing" label="状态" key="slot" sortable> |
||||
|
<template #default="scope"> |
||||
|
<div class="flex flex-row items-center" @click="change(scope.row)"> |
||||
|
<div :class="scope.row.startUsing ? 'point bg-green-500' : 'point bg-red-500'"></div> |
||||
|
<span style="margin-left: 10px">{{ scope.row.startUsing ? '启动' : '禁用' }}</span> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="公开" sortable key="slot" width="180"> |
||||
|
<template #default="scope"> |
||||
|
<div class="flex flex-row items-center" @click="change(scope.row)"> |
||||
|
<div :class="scope.row.pub ? 'point bg-green-500' : 'point bg-red-500'"></div> |
||||
|
<span style="margin-left: 10px">{{ scope.row.pub ? '公开' : '非公开' }}</span> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="createTime" :formatter="changeDate" label="创建日期" sortable></el-table-column> |
||||
|
<el-table-column label="操作" key="slot"> |
||||
|
<template #default="scope"> |
||||
|
<el-popconfirm |
||||
|
title="确定删除这条业务吗?" |
||||
|
confirm-button-text="确定" |
||||
|
cancel-button-text="再想想" |
||||
|
@confirm="deleteBusiness(scope.row)" |
||||
|
> |
||||
|
<template #reference> |
||||
|
<el-button type="text" size="small">删除</el-button> |
||||
|
</template> |
||||
|
</el-popconfirm> |
||||
|
<el-button type="text" size="small" disabled>配置</el-button>.. |
||||
|
<el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<template slot="empty"> |
||||
|
<p>没有记录哦~</p> |
||||
|
</template> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
<el-empty v-else description="暂无业务信息"></el-empty> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { useRouter } from 'vue-router'; |
||||
|
import { defineProps, defineEmits } from 'vue'; |
||||
|
import { useStore } from 'vuex'; |
||||
|
import time from 'utils/time'; |
||||
|
import { ElMessage } from 'element-plus'; |
||||
|
import { delBusiness } from '@/apis/business.js'; |
||||
|
|
||||
|
const router = useRouter(); |
||||
|
const store = useStore(); |
||||
|
defineProps({ |
||||
|
lists: { default: () => [], type: Array }, |
||||
|
currentPage: { default: 1, type: Number }, |
||||
|
pageSize: { default: 10, type: Number }, |
||||
|
total: { default: 0, type: Number }, |
||||
|
showConfig: { default: false, type: Boolean }, |
||||
|
}); |
||||
|
|
||||
|
const emit = defineEmits(['handleQueryBusiness']); |
||||
|
|
||||
|
function change(row) { |
||||
|
console.log('row: ', row); |
||||
|
} |
||||
|
|
||||
|
function handleClick(row) { |
||||
|
router.push({ name: 'business-detail', query: { id: row.id } }); |
||||
|
store.commit('plugin/setBusinessInfo', row); |
||||
|
} |
||||
|
|
||||
|
function changeDate(row) { |
||||
|
const value = row.createTime; |
||||
|
return time.dateFormat(value); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除业务 |
||||
|
* @param {String} businessId |
||||
|
*/ |
||||
|
async function deleteBusiness(row) { |
||||
|
try { |
||||
|
// 这里写接口 记得加 async await |
||||
|
const params = { param: { businessId: row.id } }; |
||||
|
await delBusiness(params); |
||||
|
emit('handleQueryBusiness'); |
||||
|
ElMessage.success('删除成功'); |
||||
|
} catch (error) { |
||||
|
ElMessage.error(error || '删除失败'); |
||||
|
console.error('error: ', error); |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.bg-title >>> thead tr th { |
||||
|
color: #333; |
||||
|
background: #fafafa; |
||||
|
border-top: 1px solid #e8e8e8; |
||||
|
} |
||||
|
.bg-title >>> thead tr th:first-child { |
||||
|
border-left: 1px solid #e8e8e8; |
||||
|
} |
||||
|
.bg-title >>> thead tr th:last-child { |
||||
|
border-right: 1px solid #e8e8e8; |
||||
|
} |
||||
|
|
||||
|
.point { |
||||
|
width: 6px; |
||||
|
height: 6px; |
||||
|
border-radius: 50%; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,69 @@ |
|||||
|
<template> |
||||
|
<div class="pagination mt-15 flex flex-row-reverse"> |
||||
|
<el-config-provider :locale="zhCn"> |
||||
|
<el-pagination |
||||
|
@size-change="handleSizeChange" |
||||
|
@current-change="handleCurrentChange" |
||||
|
:current-page.sync="currentPage" |
||||
|
:page-size="pageSize" |
||||
|
layout="prev, pager, next, sizes, jumper" |
||||
|
:total="total" |
||||
|
:page-sizes="[10, 15, 20, 30, 40, 50]" |
||||
|
> |
||||
|
</el-pagination> |
||||
|
</el-config-provider> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts" setup="true"> |
||||
|
import { defineProps, defineEmits } from 'vue'; |
||||
|
import { ElConfigProvider } from 'element-plus'; |
||||
|
import zhCn from 'element-plus/lib/locale/lang/zh-cn'; |
||||
|
|
||||
|
defineProps({ |
||||
|
currentPage: { default: 1, type: Number }, |
||||
|
pageSize: { default: 10, type: Number }, |
||||
|
total: { default: 0, type: Number }, |
||||
|
}); |
||||
|
|
||||
|
const emit = defineEmits(['handleSizeChange', 'handleCurrentChange']); |
||||
|
|
||||
|
function handleSizeChange(val) { |
||||
|
emit('handleSizeChange', val); |
||||
|
} |
||||
|
|
||||
|
function handleCurrentChange(val) { |
||||
|
emit('handleCurrentChange', val); |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.pagination >>> .el-pager li, |
||||
|
.pagination >>> .btn-prev, |
||||
|
.pagination >>> .btn-next { |
||||
|
border: 1px solid #ccc; |
||||
|
width: 2rem; |
||||
|
height: 2rem; |
||||
|
line-height: 2rem; |
||||
|
text-align: center; |
||||
|
padding: 0; |
||||
|
margin: 0 8px; |
||||
|
border-radius: 6px; |
||||
|
font-weight: normal; |
||||
|
} |
||||
|
.pagination >>> .el-pager li.active { |
||||
|
border: 1px solid #409eff; |
||||
|
color: #fff; |
||||
|
background: #409eff; |
||||
|
} |
||||
|
.pagination >>> .el-input__inner { |
||||
|
height: 2rem; |
||||
|
line-height: 2rem; |
||||
|
border: 1px solid #ccc; |
||||
|
border-radius: 6px !important; |
||||
|
} |
||||
|
|
||||
|
.pagination >>> .el-pagination__jump { |
||||
|
margin-left: 0; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,85 @@ |
|||||
|
<template> |
||||
|
<div class="u-font-14" style="height: 100%"> |
||||
|
<div v-if="data.pluginContent"> |
||||
|
<div :data-token="token" :data-uid="userId" style="height: 100%" v-html="data.pluginContent"></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { computed, reactive, nextTick, defineProps } from 'vue'; |
||||
|
import { useStore } from 'vuex'; |
||||
|
|
||||
|
const props = defineProps({ plugin: { default: () => {}, type: Object } }); |
||||
|
const store = useStore(); |
||||
|
const token = computed(() => store.state.user.token); |
||||
|
const userId = computed(() => store.state.user.userId); |
||||
|
const data = reactive({ pluginContent: null }); |
||||
|
|
||||
|
setPlugin(); |
||||
|
|
||||
|
// 获取插件信息 |
||||
|
function setPlugin() { |
||||
|
let id = ''; |
||||
|
if (props.plugin) { |
||||
|
if (props.plugin.id) { |
||||
|
id = props.plugin.id; |
||||
|
} |
||||
|
if (props.plugin.pluginId) { |
||||
|
id = props.plugin.pluginId; |
||||
|
} |
||||
|
} |
||||
|
if (!props.plugin || !id) { |
||||
|
previewAddPlugin(); |
||||
|
return; |
||||
|
} |
||||
|
const reg = /data-root=["|']?(\w+)["|']?/gi; |
||||
|
let uuid = ''; |
||||
|
// FIXME: 没有兼容 只有js, 没有html的情况 |
||||
|
if (props.plugin.html) { |
||||
|
// 查有没有data-root=“xxx” 有的话 将xxx替换为 pluginTaskId |
||||
|
if (reg.test(props.plugin.html)) { |
||||
|
uuid = RegExp.$1; |
||||
|
const str = props.plugin.html.replace(new RegExp(uuid, 'g'), `p${id}`); |
||||
|
data.pluginContent = str; |
||||
|
} else { |
||||
|
data.pluginContent = props.plugin.html; |
||||
|
} |
||||
|
const str = props.plugin.js.replace(new RegExp(uuid, 'g'), `p${id}`); |
||||
|
handleDom(str, id); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 创建script dom |
||||
|
function handleDom(js, id) { |
||||
|
const domList = Array.from(document.getElementsByTagName('script')); |
||||
|
const index = domList.findIndex(item => item.id === `p${id}`); |
||||
|
if (index >= 0) { |
||||
|
document.body.removeChild(document.getElementById(`p${id}`)); |
||||
|
} |
||||
|
const scriptDom = document.createElement('script'); |
||||
|
scriptDom.id = `p${id}`; |
||||
|
scriptDom.setAttribute('data-type', 'plugin'); |
||||
|
scriptDom.innerHTML = js; |
||||
|
nextTick(() => { |
||||
|
document.body.append(scriptDom); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
// 没有id |
||||
|
function previewAddPlugin() { |
||||
|
console.log('props.plugin: ', props.plugin); |
||||
|
// FIXME: 没有兼容 只有js, 没有html的情况 |
||||
|
if (props.plugin.html) { |
||||
|
// 查有没有data-root=“xxx” 有的话 将xxx替换为 pluginTaskId |
||||
|
data.pluginContent = props.plugin.html; |
||||
|
const scriptDom = document.createElement('script'); |
||||
|
scriptDom.setAttribute('data-type', 'plugin'); |
||||
|
scriptDom.innerHTML = props.plugin.js; |
||||
|
console.log('scriptDom: ', scriptDom); |
||||
|
nextTick(() => { |
||||
|
document.body.append(scriptDom); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
</script> |
@ -0,0 +1,113 @@ |
|||||
|
<template> |
||||
|
<div v-if="lists && lists.length"> |
||||
|
<el-table :data="lists" class="bg-title" style="width: 100%"> |
||||
|
<el-table-column prop="name" label="插件名称"> </el-table-column> |
||||
|
<el-table-column prop="appId" label="APPID"> </el-table-column> |
||||
|
<el-table-column prop="startUsing" label="状态" key="slot" sortable> |
||||
|
<template #default="scope"> |
||||
|
<div class="flex flex-row items-center" @click="change(scope.row)"> |
||||
|
<div :class="!scope.row.startUsing ? 'point bg-green-500' : 'point bg-red-500'"></div> |
||||
|
<span style="margin-left: 10px">{{ !scope.row.startUsing ? '启动' : '禁用' }}</span> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="pub" label="公开" sortable key="slot"> |
||||
|
<template #default="scope"> |
||||
|
<div class="flex flex-row items-center" @click="change(scope.row)"> |
||||
|
<div :class="!scope.row.pub ? 'point bg-green-500' : 'point bg-red-500'"></div> |
||||
|
<span style="margin-left: 10px">{{ !scope.row.pub ? '公开' : '非公开' }}</span> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="createTime" :formatter="changeCreateDate" label="创建日期" sortable></el-table-column> |
||||
|
<el-table-column prop="updateTime" :formatter="changeUpdateDate" label="更新日期" sortable></el-table-column> |
||||
|
<el-table-column label="操作" key="slot"> |
||||
|
<template #default="scope"> |
||||
|
<el-popconfirm |
||||
|
title="确定删除这条业务吗?" |
||||
|
confirm-button-text="确定" |
||||
|
cancel-button-text="再想想" |
||||
|
@confirm="deletePlugin(scope.row)" |
||||
|
> |
||||
|
<template #reference> |
||||
|
<el-button type="text" size="small">删除</el-button> |
||||
|
</template> |
||||
|
</el-popconfirm> |
||||
|
<el-button type="text" size="small" disabled>配置</el-button>.. |
||||
|
<el-button type="text" size="small" disabled>查看</el-button> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<template slot="empty"> |
||||
|
<p>没有记录哦~</p> |
||||
|
</template> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
<el-empty v-else description="暂无业务信息"></el-empty> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { defineProps, defineEmits } from 'vue'; |
||||
|
import time from 'utils/time'; |
||||
|
import { ElMessage } from 'element-plus'; |
||||
|
import { delPlugin } from '@/apis/plugin.js'; |
||||
|
|
||||
|
defineProps({ |
||||
|
lists: { default: () => [], type: Array }, |
||||
|
currentPage: { default: 1, type: Number }, |
||||
|
pageSize: { default: 10, type: Number }, |
||||
|
total: { default: 0, type: Number }, |
||||
|
showConfig: { default: false, type: Boolean }, |
||||
|
}); |
||||
|
|
||||
|
const emit = defineEmits(['handleQueryPlugins']); |
||||
|
|
||||
|
function change(row) { |
||||
|
console.log('row: ', row); |
||||
|
} |
||||
|
|
||||
|
function changeCreateDate(row) { |
||||
|
const value = row && row.createTime ? row.createTime : ''; |
||||
|
return time.dateFormat(value); |
||||
|
} |
||||
|
|
||||
|
function changeUpdateDate(row) { |
||||
|
const value = row && row.updateTime ? row.updateTime : ''; |
||||
|
return time.dateFormat(value); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除插件 |
||||
|
* @param {String} businessId |
||||
|
*/ |
||||
|
async function deletePlugin(row) { |
||||
|
try { |
||||
|
const params = { param: { id: row.id } }; |
||||
|
await delPlugin(params); |
||||
|
ElMessage.success('删除成功'); |
||||
|
emit('handleQueryPlugins'); |
||||
|
} catch (error) { |
||||
|
console.error('error: ', error); |
||||
|
ElMessage.error(error || '删除失败'); |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.bg-title >>> thead tr th { |
||||
|
color: #333; |
||||
|
background: #fafafa; |
||||
|
border-top: 1px solid #e8e8e8; |
||||
|
} |
||||
|
.bg-title >>> thead tr th:first-child { |
||||
|
border-left: 1px solid #e8e8e8; |
||||
|
} |
||||
|
.bg-title >>> thead tr th:last-child { |
||||
|
border-right: 1px solid #e8e8e8; |
||||
|
} |
||||
|
|
||||
|
.point { |
||||
|
width: 6px; |
||||
|
height: 6px; |
||||
|
border-radius: 50%; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,71 @@ |
|||||
|
<template> |
||||
|
<el-scrollbar height="200px" @scroll="scroll"> |
||||
|
<el-radio @change="chooseBusiness" v-model="data.isCollapse" :label="business.id" v-for="business in businessLists" :key="business.id"> |
||||
|
{{ business.name }} |
||||
|
</el-radio> |
||||
|
<div class="loading my-2" v-if="!businessLists.length">暂无数据</div> |
||||
|
<div class="loading my-2" v-else>{{ isLastPage ? '到底啦~' : '加载中...' }}</div> |
||||
|
</el-scrollbar> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { reactive, defineProps, defineEmits } from 'vue'; |
||||
|
import { ElMessage } from 'element-plus'; |
||||
|
import { relevance } from '@/apis/business.js'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
businessLists: { default: () => [], type: Array }, |
||||
|
pluginId: { default: '', type: String }, |
||||
|
businessId: { default: '', type: String }, |
||||
|
isLastPage: { default: false, type: Boolean }, |
||||
|
}); |
||||
|
|
||||
|
const emit = defineEmits(['changePageNum', 'query']); |
||||
|
|
||||
|
const data = reactive({ |
||||
|
isCollapse: '', |
||||
|
showLoading: false, |
||||
|
scrollTop: 0, |
||||
|
}); |
||||
|
|
||||
|
function scroll(e) { |
||||
|
if (props.isLastPage) return; |
||||
|
data.scrollTop = e.scrollTop; |
||||
|
if (e.scrollTop === 220) { |
||||
|
emit('changePageNum'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 关联业务和插件 |
||||
|
* @param {string} businessId 业务id |
||||
|
* @param {string} pluginId 插件id |
||||
|
*/ |
||||
|
async function chooseBusiness(e) { |
||||
|
try { |
||||
|
data.isCollapse = e; |
||||
|
const params = { |
||||
|
param: { |
||||
|
businessId: props.businessId ? props.businessId : e, |
||||
|
pluginId: props.pluginId ? props.pluginId : e, |
||||
|
}, |
||||
|
}; |
||||
|
await relevance(params); |
||||
|
ElMessage.success('关联成功'); |
||||
|
if (props.businessId) { |
||||
|
emit('query', props.businessId); |
||||
|
} |
||||
|
} catch (error) { |
||||
|
ElMessage.error(error || '关联失败'); |
||||
|
console.error('error: ', error); |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.loading { |
||||
|
width: 100%; |
||||
|
text-align: center; |
||||
|
color: #aaa; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,136 @@ |
|||||
|
<template> |
||||
|
<!-- 热门插件 --> |
||||
|
<div class="flex flex-row justify-space-between items-center"> |
||||
|
<div class="font-bold"> |
||||
|
热门插件: |
||||
|
<el-button plain size="mini" v-for="(tag, tagIndex) in data.tags" :key="tagIndex" class="cursor-pointer">{{ tag }}</el-button> |
||||
|
</div> |
||||
|
<div class="flex-1"></div> |
||||
|
<div class="flex flex-row"> |
||||
|
<el-input disabled v-model="data.keywords" placeholder="请输入插件名或标签名搜索" class="search-input" /> |
||||
|
<el-button type="primary" size="small" class="w-60px h-40px" disabled>搜索</el-button> |
||||
|
<el-button type="primary" icon="el-icon-plus" size="small" class="h-40px" @click="openPage">创建插件</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- 所属行业 --> |
||||
|
<div class="types"> |
||||
|
所属行业: |
||||
|
<div |
||||
|
class="type" |
||||
|
:class="industry.checked ? 'check' : ''" |
||||
|
v-for="(industry, industryIndex) in data.industryList" |
||||
|
:key="industryIndex" |
||||
|
@click="changeIndustryCheck(industryIndex)" |
||||
|
> |
||||
|
{{ industry.value }} |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="line"></div> |
||||
|
<div class="types"> |
||||
|
所属分类: |
||||
|
<div |
||||
|
class="type" |
||||
|
:class="sort.checked ? 'check' : ''" |
||||
|
v-for="(sort, sortIndex) in data.sortList" |
||||
|
:key="sortIndex" |
||||
|
@click="changeSortCheck(sortIndex)" |
||||
|
> |
||||
|
{{ sort.value }} |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="line"></div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts" setup="true"> |
||||
|
import { reactive } from 'vue'; |
||||
|
import { useRouter } from 'vue-router'; |
||||
|
import { useStore } from 'vuex'; |
||||
|
|
||||
|
const router = useRouter(); |
||||
|
const store = useStore(); |
||||
|
|
||||
|
const data = reactive({ |
||||
|
tags: [], |
||||
|
// tags: ['交付物', '财务条', '签到打卡', '即时奖惩'], |
||||
|
keywords: '', |
||||
|
industryList: [ |
||||
|
// { |
||||
|
// value: '行业一', |
||||
|
// label: '行业一', |
||||
|
// checked: true, |
||||
|
// }, |
||||
|
// { |
||||
|
// value: '行业二', |
||||
|
// label: '行业二', |
||||
|
// checked: false, |
||||
|
// }, |
||||
|
// { |
||||
|
// value: '行业三', |
||||
|
// label: '行业三', |
||||
|
// checked: false, |
||||
|
// } |
||||
|
], |
||||
|
sortList: [ |
||||
|
// { |
||||
|
// value: '分类一', |
||||
|
// label: '分类一', |
||||
|
// checked: false, |
||||
|
// }, |
||||
|
// { |
||||
|
// value: '分类二', |
||||
|
// label: '分类二', |
||||
|
// checked: true, |
||||
|
// }, |
||||
|
// { |
||||
|
// value: '分类三', |
||||
|
// label: '分类三', |
||||
|
// checked: false, |
||||
|
// }, |
||||
|
], |
||||
|
}); |
||||
|
|
||||
|
function changeIndustryCheck(index) { |
||||
|
data.industryList[index].checked = !data.industryList[index].checked; |
||||
|
} |
||||
|
|
||||
|
function changeSortCheck(index) { |
||||
|
data.sortList[index].checked = !data.sortList[index].checked; |
||||
|
} |
||||
|
|
||||
|
function openPage() { |
||||
|
router.push({ name: 'desk-add-plugin' }); |
||||
|
store.commit('plugin/setLeftIndex', 2); |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.search-input { |
||||
|
width: 27.3125rem; |
||||
|
} |
||||
|
|
||||
|
.types { |
||||
|
display: flex; |
||||
|
flex-wrap: wrap; |
||||
|
align-items: center; |
||||
|
margin: 8px 0; |
||||
|
} |
||||
|
|
||||
|
.types .type { |
||||
|
height: 2rem; |
||||
|
line-height: 2rem; |
||||
|
cursor: pointer; |
||||
|
padding: 0 12px; |
||||
|
margin: 6px 20px; |
||||
|
} |
||||
|
|
||||
|
.types .check { |
||||
|
color: #fff; |
||||
|
background: #409eff; |
||||
|
border-radius: 3px; |
||||
|
} |
||||
|
|
||||
|
.line { |
||||
|
width: 100%; |
||||
|
border-bottom: 1px dashed #ebebeb; |
||||
|
} |
||||
|
</style> |
@ -1,14 +1,27 @@ |
|||||
import { createStore } from 'vuex'; |
import { createStore } from 'vuex'; |
||||
import user from './user'; |
import user from './user'; |
||||
|
import plugin from './plugin'; |
||||
|
|
||||
export default createStore({ |
export default createStore({ |
||||
modules: { user }, |
modules: { user, plugin }, |
||||
state: { menu: { show: true, collapse: false } }, |
state: { |
||||
|
menu: { show: true, collapse: false }, |
||||
|
systemInfo: null, // 系统设备信息
|
||||
|
}, |
||||
getters: {}, |
getters: {}, |
||||
mutations: { |
mutations: { |
||||
toggleCollapse(state) { |
toggleCollapse(state) { |
||||
state.menu.collapse = !state.menu.collapse; |
state.menu.collapse = !state.menu.collapse; |
||||
}, |
}, |
||||
|
|
||||
|
/** |
||||
|
* 设置系统信息的数据 |
||||
|
* @param {object} state |
||||
|
* @param {object | null} data 获取到的数据 |
||||
|
*/ |
||||
|
setSystemInfo(state, data) { |
||||
|
state.systemInfo = data; |
||||
|
}, |
||||
}, |
}, |
||||
actions: {}, |
actions: {}, |
||||
}); |
}); |
||||
|
@ -0,0 +1,26 @@ |
|||||
|
export default { |
||||
|
namespaced: true, |
||||
|
state: { leftIndex: 3, businessInfo: {} }, |
||||
|
getters: {}, |
||||
|
mutations: { |
||||
|
/** |
||||
|
* 设置控制台左侧菜单栏 |
||||
|
* @param {*} state |
||||
|
* @param {number} data |
||||
|
*/ |
||||
|
setLeftIndex(state, data) { |
||||
|
state.leftIndex = data; |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 设置当前查看的业务信息 |
||||
|
* @param {*} state |
||||
|
* @param {object|null} data |
||||
|
*/ |
||||
|
setBusinessInfo(state, data) { |
||||
|
state.businessInfo = data; |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
actions: {}, |
||||
|
}; |
@ -0,0 +1,18 @@ |
|||||
|
const time = { |
||||
|
dateFormat(value) { |
||||
|
if (value) { |
||||
|
const date = new Date(Number(value)); // 时间戳为秒:13位数
|
||||
|
// let date = new Date(value * 1000) // 时间戳为毫秒:10位数
|
||||
|
const year = date.getFullYear(); |
||||
|
const month = date.getMonth() + 1 < 10 ? `0${date.getMonth() + 1}` : date.getMonth() + 1; |
||||
|
const day = date.getDate() < 10 ? `0${date.getDate()}` : date.getDate(); |
||||
|
const hour = date.getHours() < 10 ? `0${date.getHours()}` : date.getHours(); |
||||
|
const minute = date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes(); |
||||
|
const second = date.getSeconds() < 10 ? `0${date.getSeconds()}` : date.getSeconds(); |
||||
|
return `${year}-${month}-${day} ${hour}:${minute}:${second}`; |
||||
|
} |
||||
|
return ''; |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
export default time; |
@ -1,3 +1,34 @@ |
|||||
<template> |
<template> |
||||
index.vue |
<el-container> |
||||
|
<el-header> |
||||
|
<div class="top"> |
||||
|
<Navbar /> |
||||
|
</div> |
||||
|
</el-header> |
||||
|
<el-main> |
||||
|
<div class="bg-white p-6"> |
||||
|
<router-view></router-view> |
||||
|
</div> |
||||
|
</el-main> |
||||
|
</el-container> |
||||
</template> |
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default {}; |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.el-header { |
||||
|
background: #00182e; |
||||
|
color: #fff; |
||||
|
} |
||||
|
.el-main { |
||||
|
padding: 1.6rem 12rem; |
||||
|
background: #f5f5f5; |
||||
|
} |
||||
|
|
||||
|
.top { |
||||
|
/* padding: 2rem 10rem; */ |
||||
|
width: 100%; |
||||
|
} |
||||
|
</style> |
||||
|
@ -0,0 +1,140 @@ |
|||||
|
<template> |
||||
|
<div class="box"> |
||||
|
<h1 class="text-lg font-semibold">配置业务</h1> |
||||
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="150px" class="forms"> |
||||
|
<el-form-item prop="name"> |
||||
|
<template v-slot:label> |
||||
|
<el-tooltip class="box-item" effect="dark" content="输入帮助" placement="top-end"> |
||||
|
<div>业务名称:</div> |
||||
|
</el-tooltip> |
||||
|
</template> |
||||
|
<el-input v-model="form.name" placeholder="输入业务名称"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="行业:" prop="region"> |
||||
|
<el-select v-model="form.region" placeholder="请选择"> |
||||
|
<el-option value="教育"></el-option> |
||||
|
<el-option value="医疗"></el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="分类:" prop="sort"> |
||||
|
<el-select v-model="form.sort" multiple placeholder="请选择,可多选"> |
||||
|
<el-option value="康复"></el-option> |
||||
|
<el-option value="管理"></el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="标签:" prop="tags"> |
||||
|
<el-select v-model="form.tags" multiple filterable allow-create default-first-option placeholder="请选择标签"> |
||||
|
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="详情:" prop="description"> |
||||
|
<el-input v-model="form.description" type="textarea" placeholder="请输入备注"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="是否公开:" prop="pub"> |
||||
|
<el-switch v-model="form.pub" class="mr-3"></el-switch> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="是否启用:" prop="startUsing"> |
||||
|
<el-switch v-model="form.startUsing" class="mr-3"></el-switch> |
||||
|
</el-form-item> |
||||
|
<!-- <el-form-item label="是否开启debug模式:" prop="debug"> |
||||
|
<el-switch v-model="form.debug" class="mr-3"></el-switch> |
||||
|
</el-form-item> --> |
||||
|
<el-form-item> <el-switch v-model="form.debug" class="mr-3"></el-switch> 是否开启debug模式 </el-form-item> |
||||
|
<el-form-item> |
||||
|
<el-button type="primary" @click="onSubmit()">发布</el-button> |
||||
|
<el-button @click="resetForm()">重置</el-button> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { ref, reactive } from 'vue'; |
||||
|
import { ElMessage } from 'element-plus'; |
||||
|
import { saveBusiness } from '@/apis/business.js'; |
||||
|
|
||||
|
const formRef = ref(null); |
||||
|
const form = reactive({ |
||||
|
name: '', |
||||
|
region: '', |
||||
|
sort: '', |
||||
|
tags: '', |
||||
|
description: '', |
||||
|
pub: false, |
||||
|
startUsing: false, |
||||
|
debug: false, |
||||
|
}); |
||||
|
|
||||
|
const rules = { |
||||
|
name: [{ required: true, message: '输入业务名称', trigger: 'blur' }], |
||||
|
region: [{ required: true, message: '请选择行业', trigger: 'blur' }], |
||||
|
sort: [{ required: true, message: '请选择分类', trigger: 'blur' }], |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* 创建业务 |
||||
|
*/ |
||||
|
const onSubmit = () => { |
||||
|
try { |
||||
|
formRef.value.validate(async valid => { |
||||
|
if (valid) { |
||||
|
const params = {}; |
||||
|
params.param = form; |
||||
|
params.param.pub = form.pub ? 1 : 0; |
||||
|
params.param.startUsing = form.startUsing ? 1 : 0; |
||||
|
params.param.debug = form.debug ? 1 : 0; |
||||
|
await saveBusiness(params); |
||||
|
ElMessage.success('创建成功'); |
||||
|
resetForm(); |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}); |
||||
|
} catch (error) { |
||||
|
ElMessage.error(error || '创建失败'); |
||||
|
console.log('error: ', error); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
function resetForm() { |
||||
|
formRef.value.resetFields(); |
||||
|
} |
||||
|
const options = [ |
||||
|
{ |
||||
|
value: 'HTML', |
||||
|
label: 'HTML', |
||||
|
}, |
||||
|
{ |
||||
|
value: 'CSS', |
||||
|
label: 'CSS', |
||||
|
}, |
||||
|
{ |
||||
|
value: 'JavaScript', |
||||
|
label: 'JavaScript', |
||||
|
}, |
||||
|
]; |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.el-form-item { |
||||
|
margin-top: 1rem; |
||||
|
} |
||||
|
.tags { |
||||
|
width: 100%; |
||||
|
} |
||||
|
.el-select { |
||||
|
width: 100%; |
||||
|
} |
||||
|
.box >>> .el-form-item__label { |
||||
|
display: flex; |
||||
|
flex-direction: row-reverse; |
||||
|
justify-content: end; |
||||
|
flex: 0 0 auto; |
||||
|
text-align: right; |
||||
|
font-size: var(--el-form-label-font-size); |
||||
|
color: var(--el-text-color-regular); |
||||
|
line-height: 40px; |
||||
|
padding: 0 12px 0 0; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,350 @@ |
|||||
|
<template> |
||||
|
<div class="box"> |
||||
|
<h1 class="text-lg font-semibold">上传插件</h1> |
||||
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="150px" class="forms"> |
||||
|
<el-form-item label="插件id:" prop="id"> |
||||
|
<div v-if="form.id"> |
||||
|
{{ form.id }} |
||||
|
<i class="el-icon-document-copy cursor-pointer ml-2" @click="copy(form.id)"></i> |
||||
|
</div> |
||||
|
<el-button type="success" plain size="mini" @click="handelPluginId" v-else>点击生成插件id</el-button> |
||||
|
</el-form-item> |
||||
|
<el-form-item prop="name"> |
||||
|
<template v-slot:label> |
||||
|
<el-tooltip class="box-item" effect="dark" content="输入帮助" placement="top-end"> |
||||
|
<div>插件名称 ①:</div> |
||||
|
</el-tooltip> |
||||
|
</template> |
||||
|
<el-input v-model="form.name" placeholder="输入插件名称"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="版本:" prop="versions"> |
||||
|
<el-input v-model="form.versions" placeholder="请输入"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="简介:" prop="intro"> |
||||
|
<el-input v-model="form.intro" type="textarea" placeholder="请输入备注"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="行业:" prop="region"> |
||||
|
<el-select v-model="form.region" placeholder="请选择"> |
||||
|
<el-option value="教育"></el-option> |
||||
|
<el-option value="医疗"></el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="分类:" prop="sort"> |
||||
|
<el-select v-model="form.sort" multiple placeholder="请选择,可多选"> |
||||
|
<el-option value="康复"></el-option> |
||||
|
<el-option value="管理"></el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="标签:" prop="tags"> |
||||
|
<el-select v-model="form.tags" multiple filterable allow-create default-first-option placeholder="请选择标签"> |
||||
|
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="HTML:" prop="html"> |
||||
|
<el-input v-model="form.html" type="textarea" placeholder="请输入HTML代码片段"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="JS:" prop="js"> |
||||
|
<el-input v-model="form.js" type="textarea" placeholder="请输入JS代码片段"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="CSS:" prop="css"> |
||||
|
<el-input v-model="form.css" type="textarea" placeholder="请输入CSS代码片段"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="配置文件:" prop="config"> |
||||
|
<el-input v-model="form.config" type="textarea" placeholder="请输入配置文件"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="上传预览图:" prop="preview"> |
||||
|
<el-upload |
||||
|
class="avatar-uploader" |
||||
|
:action="`${apiUrl}/filedeal/file/upload/single`" |
||||
|
:show-file-list="false" |
||||
|
:on-success="handleAvatarSuccess" |
||||
|
:before-upload="beforeAvatarUpload" |
||||
|
> |
||||
|
<img v-if="form.preview" :src="form.preview" class="avatar" /> |
||||
|
<i v-else class="el-icon-plus avatar-uploader-icon"></i> |
||||
|
</el-upload> |
||||
|
</el-form-item> |
||||
|
<el-form-item prop="carousel"> |
||||
|
<template v-slot:label> |
||||
|
<el-tooltip class="box-item" effect="dark" content="输入帮助" placement="top-end"> |
||||
|
<div>上传轮播图 ①:</div> |
||||
|
</el-tooltip> |
||||
|
</template> |
||||
|
<el-upload |
||||
|
class="upload-dialog" |
||||
|
name="files" |
||||
|
:action="`${apiUrl}/filedeal/file/upload/multiple`" |
||||
|
list-type="picture-card" |
||||
|
:on-success="handleBannerSuccess" |
||||
|
:on-remove="handleRemove" |
||||
|
ref="bannerUpload" |
||||
|
> |
||||
|
<i class="el-icon-plus"></i> |
||||
|
</el-upload> |
||||
|
<el-dialog :visible.sync="form.dialogVisible"> |
||||
|
<img width="100%" :src="form.banner" alt="" v-if="form.dialogVisible" /> |
||||
|
</el-dialog> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="README:" prop="description"> |
||||
|
<el-input v-model="form.description" type="textarea" placeholder="请输入markdown详细介绍信息"></el-input> |
||||
|
</el-form-item> |
||||
|
<!-- <el-form-item> <el-switch v-model="form.delivery" class="mr-3"></el-switch> 是否压缩代码 </el-form-item> --> |
||||
|
<el-form-item> |
||||
|
<el-button type="primary" @click="onSubmit()">发布</el-button> |
||||
|
<el-button @click="resetForm()">重置</el-button> |
||||
|
|
||||
|
<el-button type="success" @click="visible = !visible">{{ !visible ? '预览' : '关闭预览' }}</el-button> |
||||
|
<div class="plugin-box" v-if="visible"> |
||||
|
<div class="plugin w-full h-full overflow-y-scroll"> |
||||
|
<Plugin :plugin="form" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import useClipboard from 'vue-clipboard3'; |
||||
|
import { ref, reactive } from 'vue'; |
||||
|
import { ElMessage } from 'element-plus'; |
||||
|
import { randomId, savePlugin } from '@/apis/plugin'; |
||||
|
|
||||
|
const { toClipboard } = useClipboard(); |
||||
|
|
||||
|
const apiUrl = import.meta.env.VITE_API_URL_NEW; |
||||
|
|
||||
|
const formRef = ref(null); |
||||
|
const bannerUpload = ref(null); |
||||
|
const visible = ref(false); |
||||
|
const form = reactive({ |
||||
|
id: '', |
||||
|
name: '', |
||||
|
versions: 'V1.0.0', |
||||
|
intro: '', |
||||
|
region: '', |
||||
|
sort: '', |
||||
|
tags: '', |
||||
|
html: '', |
||||
|
js: '', |
||||
|
css: '', |
||||
|
config: '', |
||||
|
delivery: '', |
||||
|
preview: '', |
||||
|
carousel: [], |
||||
|
dialogVisible: false, |
||||
|
description: '', |
||||
|
banner: '', |
||||
|
}); |
||||
|
|
||||
|
const rules = { |
||||
|
id: [{ required: true, message: '请先生成插件id', trigger: 'blur' }], |
||||
|
name: [{ required: true, message: '请输入插件名称', trigger: 'blur' }], |
||||
|
versions: [{ required: true, message: '请输入版本号', trigger: 'blur' }], |
||||
|
// region: [{ required: true, message: '请选择行业', trigger: 'blur' }], |
||||
|
// sort: [{ required: true, message: '请选择分类', trigger: 'blur' }], |
||||
|
// tags: [{ required: true, message: '请选择标签', trigger: 'blur' }], |
||||
|
preview: [{ required: true, message: '请上传预览图', trigger: 'blur' }], |
||||
|
carousel: [{ required: true, message: '请上传轮播图', trigger: 'blur' }], |
||||
|
}; |
||||
|
|
||||
|
const options = [ |
||||
|
{ |
||||
|
value: 'HTML', |
||||
|
label: 'HTML', |
||||
|
}, |
||||
|
{ |
||||
|
value: 'CSS', |
||||
|
label: 'CSS', |
||||
|
}, |
||||
|
{ |
||||
|
value: 'JavaScript', |
||||
|
label: 'JavaScript', |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
/** |
||||
|
* 获取插件id |
||||
|
*/ |
||||
|
async function handelPluginId() { |
||||
|
try { |
||||
|
const res = await randomId(); |
||||
|
form.id = res; |
||||
|
} catch (error) { |
||||
|
console.error('error: ', error); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
handelPluginId(); |
||||
|
|
||||
|
// 复制 |
||||
|
async function copy(Msg) { |
||||
|
try { |
||||
|
// 复制 |
||||
|
await toClipboard(Msg); |
||||
|
ElMessage.success('插件id复制成功'); |
||||
|
} catch (e) { |
||||
|
// 复制失败 |
||||
|
console.error(e); |
||||
|
ElMessage.error('插件id复制失败'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 创建插件 |
||||
|
* @param {object} params |
||||
|
*/ |
||||
|
function onSubmit() { |
||||
|
try { |
||||
|
formRef.value.validate(async valid => { |
||||
|
if (valid) { |
||||
|
console.log('submit!'); |
||||
|
const params = {}; |
||||
|
params.param = form; |
||||
|
await savePlugin(params); |
||||
|
ElMessage.success('插件创建成功'); |
||||
|
resetForm(); |
||||
|
bannerUpload.value.clearFiles(); |
||||
|
} else { |
||||
|
console.log('error submit!!'); |
||||
|
return false; |
||||
|
} |
||||
|
}); |
||||
|
} catch (error) { |
||||
|
ElMessage.error(error || '插件创建失败'); |
||||
|
console.error('error: ', error); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 上传预览图 |
||||
|
* @param {*} res |
||||
|
* @param {*} file |
||||
|
*/ |
||||
|
function handleAvatarSuccess(res) { |
||||
|
if (res.data && res.data.visitUrl) { |
||||
|
form.preview = res.data.visitUrl; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function beforeAvatarUpload(file) { |
||||
|
// const isJPG = file.type === 'image/jpeg'; |
||||
|
const isLt2M = file.size / 1024 / 1024 < 2; |
||||
|
|
||||
|
// if (!isJPG) { |
||||
|
// ElMessage.error('上传头像图片只能是 JPG 格式!'); |
||||
|
// } |
||||
|
if (!isLt2M) { |
||||
|
ElMessage.error('上传头像图片大小不能超过 2MB!'); |
||||
|
} |
||||
|
return isLt2M; |
||||
|
} |
||||
|
|
||||
|
// 删除轮播图 |
||||
|
function handleRemove(res) { |
||||
|
if (res.response.data && res.response.data.length) { |
||||
|
const url = res.response.data[0].visitUrl; |
||||
|
const index = form.carousel.findIndex(item => item === url); |
||||
|
form.carousel.splice(index, 1); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 上传轮播图 |
||||
|
function handleBannerSuccess(res) { |
||||
|
if (res.data && res.data.length) { |
||||
|
form.dialogVisible = true; |
||||
|
form.banner = res.data[0].visitUrl; |
||||
|
res.data.forEach(item => { |
||||
|
if (item && item.id) { |
||||
|
form.carousel.push(item.visitUrl); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 重置 |
||||
|
function resetForm() { |
||||
|
formRef.value.resetFields(); |
||||
|
handelPluginId(); |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.box { |
||||
|
/* padding-left: 5%; */ |
||||
|
} |
||||
|
.el-form-item { |
||||
|
margin-top: 1rem; |
||||
|
} |
||||
|
.tags { |
||||
|
width: 100%; |
||||
|
} |
||||
|
.el-select { |
||||
|
width: 100%; |
||||
|
} |
||||
|
.box >>> .el-form-item__label { |
||||
|
display: flex; |
||||
|
flex-direction: row-reverse; |
||||
|
justify-content: end; |
||||
|
flex: 0 0 auto; |
||||
|
text-align: right; |
||||
|
font-size: var(--el-form-label-font-size); |
||||
|
color: var(--el-text-color-regular); |
||||
|
line-height: 40px; |
||||
|
padding: 0 12px 0 0; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
.avatar-uploader >>> .el-upload { |
||||
|
border: 1px dashed #d9d9d9; |
||||
|
border-radius: 6px; |
||||
|
cursor: pointer; |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
.avatar-uploader >>> .el-upload:hover { |
||||
|
border-color: #409eff; |
||||
|
} |
||||
|
.avatar-uploader-icon { |
||||
|
font-size: 28px; |
||||
|
color: #8c939d; |
||||
|
width: 104px; |
||||
|
height: 104px; |
||||
|
line-height: 104px; |
||||
|
text-align: center; |
||||
|
background: #fafafa; |
||||
|
} |
||||
|
.avatar { |
||||
|
width: 104px; |
||||
|
height: 104px; |
||||
|
display: block; |
||||
|
} |
||||
|
|
||||
|
.upload-dialog >>> .el-upload--picture-card { |
||||
|
width: 104px; |
||||
|
height: 104px; |
||||
|
line-height: 104px; |
||||
|
background: #fafafa; |
||||
|
} |
||||
|
|
||||
|
.upload-dialog >>> .el-upload-list--picture-card .el-upload-list__item { |
||||
|
width: 104px; |
||||
|
height: 104px; |
||||
|
} |
||||
|
|
||||
|
.plugin-box { |
||||
|
position: fixed; |
||||
|
right: 14rem; |
||||
|
background: url(../../assets/iPhone13.png) no-repeat; |
||||
|
background-size: contain; |
||||
|
width: 19.375rem; |
||||
|
height: 39.2419rem; |
||||
|
top: calc(50vh - 289.93512px + 1.8rem); |
||||
|
padding: 2.8rem 1.2rem 2rem; |
||||
|
z-index: 99; |
||||
|
} |
||||
|
|
||||
|
.plugin::-webkit-scrollbar { |
||||
|
display: none; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,194 @@ |
|||||
|
<template> |
||||
|
<breadcrumb :path="data.path" /> |
||||
|
|
||||
|
<div class="pt-12"> |
||||
|
<h1 class="text-lg font-semibold">业务名称</h1> |
||||
|
<div class="flex flex-col" v-if="data.info && data.info.id"> |
||||
|
<div class="mt-3"> |
||||
|
APPID: {{ data.info.appId }} |
||||
|
<i class="el-icon-document-copy cursor-pointer ml-2" @click="copy(data.info.appId)"></i> |
||||
|
</div> |
||||
|
<div class="mt-3">APPSecret: {{ data.info.secret }}</div> |
||||
|
<div class="mt-3">简介: {{ data.info.description }}</div> |
||||
|
<div class="flex flex-row mt-3"> |
||||
|
<div class="text-sm mr-20" v-if="data.info.tags && data.info.tags.length"> |
||||
|
<el-tag v-for="item in data.info.tags" :type="item.btnType" class="mr-3" :key="item.name">{{ item.name }}</el-tag> |
||||
|
</div> |
||||
|
<div>行业: {{ data.info.appId }}</div> |
||||
|
</div> |
||||
|
<div class="flex flex-row mt-3"> |
||||
|
<div class="mr-20">创建时间: {{ time.dateFormat(data.info.createTime) }}</div> |
||||
|
<div>最新更新时间: {{ time.dateFormat(data.info.createTime) }}</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="flex flex-col py-12"> |
||||
|
<div class="flex flex-nowrap justify-between"> |
||||
|
<h1 class="text-lg font-semibold">已绑定插件</h1> |
||||
|
<el-popover placement="bottom" title="请选择插件" :width="240" trigger="click"> |
||||
|
<div class="radio-box"> |
||||
|
<Relevance |
||||
|
:businessLists="data.pluginLists" |
||||
|
:businessId="data.info.id" |
||||
|
:isLastPage="data.isLastPage" |
||||
|
@changePageNum="changePageNum" |
||||
|
@query="queryPluginOfBusiness" |
||||
|
/> |
||||
|
</div> |
||||
|
<template #reference> |
||||
|
<el-button type="primary" @click="handleQueryPlugin">添加插件</el-button> |
||||
|
</template> |
||||
|
</el-popover> |
||||
|
</div> |
||||
|
<listPlugin :lists="data.lists" :showConfig="true" :businessId="data.businessId" @queryPluginOfBusiness="queryPluginOfBusiness" /> |
||||
|
<Pagination |
||||
|
:currentPage="data.currentPage" |
||||
|
:pageSize="data.pageSize" |
||||
|
:total="data.total" |
||||
|
@handleSizeChange="handleSizeChange" |
||||
|
@handleCurrentChange="handleCurrentChange" |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import useClipboard from 'vue-clipboard3'; |
||||
|
import { reactive } from 'vue'; |
||||
|
import { useRouter } from 'vue-router'; |
||||
|
import { ElMessage } from 'element-plus'; |
||||
|
import time from 'utils/time'; |
||||
|
import { queryPluginByBusiness, queryIdBusiness } from '@/apis/business.js'; |
||||
|
import { queryPlugins } from '@/apis/plugin.js'; |
||||
|
|
||||
|
const router = useRouter(); |
||||
|
const { toClipboard } = useClipboard(); |
||||
|
|
||||
|
const data = reactive({ |
||||
|
path: [ |
||||
|
{ title: '控制台', name: 'plugin-shop' }, |
||||
|
{ title: '我的业务', name: 'desk-business-list' }, |
||||
|
{ title: '业务详情', name: 'desk-add-business' }, |
||||
|
], |
||||
|
lists: [], |
||||
|
currentPage: 1, |
||||
|
pageSize: 10, |
||||
|
total: 0, |
||||
|
info: {}, |
||||
|
pluginLists: [], |
||||
|
isLastPage: false, |
||||
|
pageNum: 1, |
||||
|
businessId: '', |
||||
|
}); |
||||
|
|
||||
|
function handleSizeChange(val) { |
||||
|
data.pageSize = val; |
||||
|
queryPluginOfBusiness(); |
||||
|
} |
||||
|
|
||||
|
function handleCurrentChange(val) { |
||||
|
data.currentPage = val; |
||||
|
queryPluginOfBusiness(); |
||||
|
} |
||||
|
|
||||
|
// 复制 |
||||
|
async function copy(Msg) { |
||||
|
try { |
||||
|
// 复制 |
||||
|
await toClipboard(Msg); |
||||
|
ElMessage.success('复制成功'); |
||||
|
} catch (e) { |
||||
|
// 复制失败 |
||||
|
console.error(e); |
||||
|
ElMessage.error('复制失败'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 通过id查询业务信息 |
||||
|
* @param {string} businessId 业务信息对应的id |
||||
|
*/ |
||||
|
async function handleQueryIdBusiness(businessId) { |
||||
|
try { |
||||
|
const params = { param: { businessId } }; |
||||
|
const res = await queryIdBusiness(params); |
||||
|
data.info = res; |
||||
|
} catch (error) { |
||||
|
console.error('error: ', error); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询业务下关联的插件 |
||||
|
* @param {string} businessId 业务信息对应的id |
||||
|
* @param {number} name 插件名称,为空则不实用该条件 |
||||
|
* @param {number} pageNum 第几页 |
||||
|
* @param {number} pageSize 每页几条信息 |
||||
|
*/ |
||||
|
async function queryPluginOfBusiness() { |
||||
|
try { |
||||
|
const { currentPage, pageSize, businessId } = data; |
||||
|
const params = { |
||||
|
param: { |
||||
|
businessId, |
||||
|
pageNum: currentPage, |
||||
|
pageSize, |
||||
|
}, |
||||
|
}; |
||||
|
const res = await queryPluginByBusiness(params); |
||||
|
data.lists = res.list; |
||||
|
data.currentPage = res.pageNum - 0; |
||||
|
data.pageSize = res.pageSize - 0; |
||||
|
data.total = res.total - 0; |
||||
|
} catch (error) { |
||||
|
console.error('error: ', error); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const routeValue = router.currentRoute.value; |
||||
|
const id = routeValue && routeValue.query && routeValue.query.id ? routeValue.query.id : ''; |
||||
|
data.businessId = id; |
||||
|
queryPluginOfBusiness(id); |
||||
|
handleQueryIdBusiness(id); |
||||
|
|
||||
|
function changePageNum() { |
||||
|
data.pageNum++; |
||||
|
handleQueryPlugin(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询插件列表 |
||||
|
* @param {number} depth 查询深度 0则只查名称,1则查询全部 |
||||
|
* @param {number} name 插件名称,为空则不实用该条件 |
||||
|
* @param {number} pageNum 第几页 |
||||
|
* @param {number} pageSize 每页几条信息 |
||||
|
*/ |
||||
|
async function handleQueryPlugin() { |
||||
|
try { |
||||
|
const { pageNum } = data; |
||||
|
if (pageNum === 1) { |
||||
|
data.pluginLists = []; |
||||
|
} |
||||
|
const params = { |
||||
|
param: { |
||||
|
depth: 0, |
||||
|
name: '', |
||||
|
pageNum, |
||||
|
pageSize: 10, |
||||
|
}, |
||||
|
}; |
||||
|
const res = await queryPlugins(params); |
||||
|
if (res.list.length) { |
||||
|
res.list.forEach(item => { |
||||
|
data.pluginLists.push(item); |
||||
|
}); |
||||
|
} |
||||
|
data.pageNum = res.pageNum - 0; |
||||
|
data.isLastPage = res.isLastPage; |
||||
|
} catch (error) { |
||||
|
console.error('error: ', error); |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style></style> |
@ -0,0 +1,79 @@ |
|||||
|
<template> |
||||
|
<div class="flex flex-col"> |
||||
|
<listSearchBar /> |
||||
|
<div class="py-6"> |
||||
|
<el-button type="primary" icon="el-icon-plus" @click="openPage">创建业务</el-button> |
||||
|
</div> |
||||
|
<listTable :lists="data.lists" @handleQueryBusiness="handleQueryBusiness" /> |
||||
|
<Pagination |
||||
|
:currentPage="data.currentPage" |
||||
|
:pageSize="data.pageSize" |
||||
|
:total="data.total" |
||||
|
@handleSizeChange="handleSizeChange" |
||||
|
@handleCurrentChange="handleCurrentChange" |
||||
|
/> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { useRouter } from 'vue-router'; |
||||
|
import { useStore } from 'vuex'; |
||||
|
import { reactive } from 'vue'; |
||||
|
import { queryBusiness } from '@/apis/business.js'; |
||||
|
|
||||
|
const router = useRouter(); |
||||
|
const store = useStore(); |
||||
|
|
||||
|
const data = reactive({ |
||||
|
lists: [], |
||||
|
currentPage: 1, |
||||
|
pageSize: 10, |
||||
|
total: 0, |
||||
|
}); |
||||
|
|
||||
|
function openPage() { |
||||
|
router.push({ name: 'desk-add-business' }); |
||||
|
store.commit('plugin/setLeftIndex', 1); |
||||
|
} |
||||
|
|
||||
|
function handleSizeChange(val) { |
||||
|
data.pageSize = val; |
||||
|
handleQueryBusiness(); |
||||
|
} |
||||
|
|
||||
|
function handleCurrentChange(val) { |
||||
|
data.currentPage = val; |
||||
|
handleQueryBusiness(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询插件列表 |
||||
|
* @param {number} depth 查询深度 0则只查名称,1则查询全部 |
||||
|
* @param {number} name 插件名称,为空则不实用该条件 |
||||
|
* @param {number} pageNum 第几页 |
||||
|
* @param {number} pageSize 每页几条信息 |
||||
|
*/ |
||||
|
async function handleQueryBusiness() { |
||||
|
try { |
||||
|
const { currentPage, pageSize } = data; |
||||
|
const params = { |
||||
|
param: { |
||||
|
depth: 1, |
||||
|
name: '', |
||||
|
pageNum: currentPage, |
||||
|
pageSize, |
||||
|
}, |
||||
|
}; |
||||
|
const res = await queryBusiness(params); |
||||
|
data.lists = res.list; |
||||
|
data.currentPage = res.pageNum - 0; |
||||
|
data.pageSize = res.pageSize - 0; |
||||
|
data.total = res.total - 0; |
||||
|
} catch (error) { |
||||
|
console.error('error: ', error); |
||||
|
} |
||||
|
} |
||||
|
handleQueryBusiness(); |
||||
|
</script> |
||||
|
|
||||
|
<style></style> |
@ -0,0 +1,14 @@ |
|||||
|
<template> |
||||
|
<!-- <div class="flex flex-row"> --> |
||||
|
<el-container> |
||||
|
<el-aside width="208px"> |
||||
|
<leftMenu /> |
||||
|
</el-aside> |
||||
|
<el-main> |
||||
|
<router-view></router-view> |
||||
|
</el-main> |
||||
|
</el-container> |
||||
|
<!-- </div> --> |
||||
|
</template> |
||||
|
|
||||
|
<script setup></script> |
@ -0,0 +1,82 @@ |
|||||
|
<template> |
||||
|
<div class="flex flex-col"> |
||||
|
<listSearchBar /> |
||||
|
<div class="py-6"> |
||||
|
<el-button type="primary" icon="el-icon-plus" @click="openPage">创建插件</el-button> |
||||
|
</div> |
||||
|
<PluginListTable :lists="data.lists" @handleQueryPlugins="handleQueryPlugins" /> |
||||
|
<Pagination |
||||
|
:currentPage="data.currentPage" |
||||
|
:pageSize="data.pageSize" |
||||
|
:total="data.total" |
||||
|
@handleSizeChange="handleSizeChange" |
||||
|
@handleCurrentChange="handleCurrentChange" |
||||
|
/> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { useRouter } from 'vue-router'; |
||||
|
import { useStore } from 'vuex'; |
||||
|
import { reactive } from 'vue'; |
||||
|
import { queryPlugins } from '@/apis/plugin.js'; |
||||
|
|
||||
|
const router = useRouter(); |
||||
|
const store = useStore(); |
||||
|
|
||||
|
const data = reactive({ |
||||
|
lists: [], |
||||
|
currentPage: 1, |
||||
|
pageSize: 10, |
||||
|
total: 0, |
||||
|
}); |
||||
|
|
||||
|
function openPage() { |
||||
|
router.push({ name: 'desk-add-plugin' }); |
||||
|
store.commit('plugin/setLeftIndex', 2); |
||||
|
} |
||||
|
|
||||
|
function handleSizeChange(val) { |
||||
|
data.pageSize = val; |
||||
|
handleQueryPlugins(); |
||||
|
} |
||||
|
|
||||
|
function handleCurrentChange(val) { |
||||
|
data.currentPage = val; |
||||
|
handleQueryPlugins(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询插件列表 |
||||
|
* @param {number} depth 查询深度 0则只查名称,1则查询全部 |
||||
|
* @param {number} mine 查询全部插件还是自己的插件 0全部 1自己 |
||||
|
* @param {number} name 插件名称,为空则不实用该条件 |
||||
|
* @param {number} pageNum 第几页 |
||||
|
* @param {number} pageSize 每页几条信息 |
||||
|
*/ |
||||
|
async function handleQueryPlugins() { |
||||
|
try { |
||||
|
const { currentPage, pageSize } = data; |
||||
|
const params = { |
||||
|
param: { |
||||
|
depth: 1, |
||||
|
mine: 1, |
||||
|
name: '', |
||||
|
pageNum: currentPage, |
||||
|
pageSize, |
||||
|
}, |
||||
|
}; |
||||
|
const res = await queryPlugins(params); |
||||
|
data.lists = res.list; |
||||
|
data.currentPage = res.pageNum - 0; |
||||
|
data.pageSize = res.pageSize - 0; |
||||
|
data.total = res.total - 0; |
||||
|
} catch (error) { |
||||
|
console.error('error: ', error); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
handleQueryPlugins(); |
||||
|
</script> |
||||
|
|
||||
|
<style></style> |
@ -0,0 +1,67 @@ |
|||||
|
<template> |
||||
|
<searchBar /> |
||||
|
<listPlugin :lists="data.lists" /> |
||||
|
<Pagination |
||||
|
:currentPage="data.currentPage" |
||||
|
:pageSize="data.pageSize" |
||||
|
:total="data.total" |
||||
|
@handleSizeChange="handleSizeChange" |
||||
|
@handleCurrentChange="handleCurrentChange" |
||||
|
/> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts" setup="true"> |
||||
|
import { reactive } from 'vue'; |
||||
|
import { queryPlugins } from '@/apis/plugin.js'; |
||||
|
|
||||
|
const data = reactive({ |
||||
|
lists: [], |
||||
|
currentPage: 1, |
||||
|
pageSize: 10, |
||||
|
total: 0, |
||||
|
}); |
||||
|
|
||||
|
function handleSizeChange(val) { |
||||
|
data.pageSize = val; |
||||
|
handleQueryPlugins(); |
||||
|
} |
||||
|
|
||||
|
function handleCurrentChange(val) { |
||||
|
data.currentPage = val; |
||||
|
handleQueryPlugins(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询插件列表 |
||||
|
* @param {number} depth 查询深度 0则只查名称,1则查询全部 |
||||
|
* @param {number} mine 查询全部插件还是自己的插件 0全部 1自己 |
||||
|
* @param {number} name 插件名称,为空则不实用该条件 |
||||
|
* @param {number} pageNum 第几页 |
||||
|
* @param {number} pageSize 每页几条信息 |
||||
|
*/ |
||||
|
async function handleQueryPlugins() { |
||||
|
try { |
||||
|
const { currentPage, pageSize } = data; |
||||
|
const params = { |
||||
|
param: { |
||||
|
depth: 1, |
||||
|
mine: 0, |
||||
|
name: '', |
||||
|
pageNum: currentPage, |
||||
|
pageSize, |
||||
|
}, |
||||
|
}; |
||||
|
const res = await queryPlugins(params); |
||||
|
data.lists = res.list; |
||||
|
data.currentPage = res.pageNum - 0; |
||||
|
data.pageSize = res.pageSize - 0; |
||||
|
data.total = res.total - 0; |
||||
|
} catch (error) { |
||||
|
console.error('error: ', error); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
handleQueryPlugins(); |
||||
|
</script> |
||||
|
|
||||
|
<style scoped></style> |
Loading…
Reference in new issue