Browse Source

feat: 完善功能

min
song 4 years ago
parent
commit
d5d98515a0
  1. 2
      src/apis/index.js
  2. BIN
      src/assets/iPhone13.png
  3. 81
      src/components/configure.vue
  4. 12
      src/components/leftMenu.vue
  5. 55
      src/components/listPlugin.vue
  6. 8
      src/components/listSearchBar.vue
  7. 2
      src/components/listTable.vue
  8. 10
      src/components/navbar.vue
  9. 29
      src/components/plugin.vue
  10. 5
      src/components/relevance.vue
  11. 67
      src/components/searchBar.vue
  12. 28
      src/routers/index.js
  13. 2
      src/utils/axios.js
  14. 5
      src/views/Index.vue
  15. 17
      src/views/index-list/add-business.vue
  16. 28
      src/views/index-list/add-plugin.vue
  17. 2
      src/views/index-list/business-detail.vue
  18. 2
      vite.config.js

2
src/apis/index.js

@ -3,7 +3,7 @@
import http from 'utils/axios';
const apiUrl = import.meta.env.VITE_API_URL_NEW;
const users = `${apiUrl}/gateway/tall3/v3.0/users`;
const users = `${apiUrl}/gateway/ptostall/users`;
// 根据userId 获取token
export const getToken = userId => http.get(`${users}/userId`, { params: { userId } });

BIN
src/assets/iPhone13.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

81
src/components/configure.vue

@ -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>

12
src/components/leftMenu.vue

@ -1,6 +1,6 @@
<template>
<el-menu :default-active="leftIndex" class="el-menu-demo" mode="vertical" @select="handleSelect">
<el-menu-item :index="index" @click="openPage(list.name)" v-for="(list, index) in data.menus" :key="index">
<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>
@ -17,11 +17,11 @@ const leftIndex = computed(() => store.state.plugin.leftIndex);
const router = useRouter();
const data = reactive({
menus: [
{ title: '概览', name: '' },
{ title: '创建业务', name: 'desk-add-business' },
{ title: '创建插件', name: 'desk-add-plugin' },
{ title: '我的业务', name: 'desk-business-list' },
{ title: '我的插件', name: 'desk-plugin-list' },
{ 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: true },
],
});

55
src/components/listPlugin.vue

@ -1,6 +1,6 @@
<template>
<div v-if="data.listArray && data.listArray.length">
<div class="shop-content flex py-5" v-for="list in data.listArray" :key="list.id">
<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>
@ -22,8 +22,8 @@
</div>
<div class="mt-6">
<el-button type="primary" v-if="showConfig">移除</el-button>
<el-button type="primary">下载源代码</el-button>
<el-button type="primary">下载示例代码</el-button>
<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">
@ -38,15 +38,18 @@
<el-button type="primary" @click="handleQueryBusiness">添加到业务</el-button>
</template>
</el-popover>
<el-button type="primary" v-if="showConfig">配置</el-button>
<el-popover :visible="list.visible" placement="right" title="预览" :width="375">
<div class="radio-box">
<Plugin :plugin="list" v-if="list.visible" />
<!-- 配置 -->
<!-- <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>
<template #reference>
<el-button type="primary" @click="list.visible = !list.visible">预览</el-button>
</template>
</el-popover>
</div>
</div>
</div>
</div>
@ -80,6 +83,7 @@ watchEffect(() => {
}
});
//
function changePageNum() {
data.currentPage++;
handleQueryBusiness();
@ -118,6 +122,17 @@ async function handleQueryBusiness() {
console.error('error: ', error);
}
}
//
function collapseVisible(index) {
data.listArray.forEach((item, i) => {
if (i === index) {
item.visible = !item.visible;
} else {
item.visible = false;
}
});
}
</script>
<style scoped>
@ -147,12 +162,26 @@ async function handleQueryBusiness() {
.radio-box {
width: 100%;
/* height: 200px;
overflow: auto; */
}
.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>

8
src/components/listSearchBar.vue

@ -2,15 +2,15 @@
<div class="flex flex-row justify-space-between items-center">
<div class="flex flex-row items-center">
<div>业务名称</div>
<el-input v-model="data.keywords" placeholder="请输入业务名称或标签搜索" class="search-input mr-10" />
<el-input disabled v-model="data.keywords" placeholder="请输入业务名称或标签搜索" class="search-input mr-10" />
<div>状态</div>
<el-select v-model="data.status" placeholder="请选择" class="search-input" @change="changeState">
<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">查询</el-button>
<el-button size="small" class="w-60px h-40px reset">重置</el-button>
<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>

2
src/components/listTable.vue

@ -23,7 +23,7 @@
<el-table-column label="操作" key="slot">
<template #default="scope">
<el-button type="text" size="small">删除</el-button>
<el-button type="text" size="small">配置</el-button>..
<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>

10
src/components/navbar.vue

@ -12,13 +12,13 @@
:default-active="data.activeIndex"
mode="horizontal"
>
<el-menu-item :index="index" @click="openPage(list.name)" v-for="(list, index) in data.lists" :key="index">{{
list.title
}}</el-menu-item>
<el-menu-item :index="index" @click="openPage(list.name)" v-for="(list, index) in data.lists" :key="index">
{{ list.title }}
</el-menu-item>
</el-menu>
<div class="flex items-center" style="color: #a5adb5">
<div @click="openPage('desk-business-list')" class="text-sm cursor-pointer">控制台</div>
<i class="el-icon-bell mx-6"></i>
<el-icon class="mx-6" size="16"><bell /></el-icon>
</div>
<el-dropdown>
<span class="flex items-center" style="color: #a5adb5">
@ -46,7 +46,7 @@
import { computed, reactive } from 'vue';
import { useStore } from 'vuex';
import { useRouter } from 'vue-router';
import { ArrowDown } from '@element-plus/icons';
import { ArrowDown, Bell } from '@element-plus/icons';
const store = useStore();
const router = useRouter();

29
src/components/plugin.vue

@ -11,7 +11,6 @@ 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);
@ -21,8 +20,17 @@ setPlugin();
//
function setPlugin() {
if (!props.plugin || !props.plugin.id) return;
console.log('props.plugin: ', props.plugin);
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) return;
const reg = /data-root=["|']?(\w+)["|']?/gi;
let uuid = '';
// FIXME: js, html
@ -30,30 +38,31 @@ function setPlugin() {
// 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${props.plugin.id}`);
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${props.plugin.id}`);
handleDom(str);
const str = props.plugin.js.replace(new RegExp(uuid, 'g'), `p${id}`);
handleDom(str, id);
}
}
// script dom
function handleDom(js) {
function handleDom(js, id) {
const domList = Array.from(document.getElementsByTagName('script'));
const index = domList.findIndex(item => item.id === `p${props.plugin.id}`);
const index = domList.findIndex(item => item.id === `p${id}`);
if (index >= 0) {
document.body.removeChild(document.getElementById(`p${props.plugin.id}`));
document.body.removeChild(document.getElementById(`p${id}`));
}
const scriptDom = document.createElement('script');
scriptDom.id = `p${props.plugin.id}`;
scriptDom.id = `p${id}`;
scriptDom.setAttribute('data-type', 'plugin');
scriptDom.innerHTML = js;
console.log('scriptDom: ', scriptDom);
nextTick(() => {
document.body.append(scriptDom);
});
}
// id
</script>

5
src/components/relevance.vue

@ -3,7 +3,8 @@
<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">{{ isLastPage ? '到底啦~' : '加载中...' }}</div>
<div class="loading my-2" v-if="!businessLists.length">暂无数据</div>
<div class="loading my-2" v-else>{{ isLastPage ? '到底啦~' : '加载中...' }}</div>
</el-scrollbar>
</template>
@ -55,7 +56,7 @@ async function chooseBusiness(e) {
emit('query', props.businessId);
}
} catch (error) {
ElMessage.error('关联失败');
ElMessage.error(error || '关联失败');
console.error('error: ', error);
}
}

67
src/components/searchBar.vue

@ -7,8 +7,8 @@
</div>
<div class="flex-1"></div>
<div class="flex flex-row">
<el-input v-model="data.keywords" placeholder="请输入插件名或标签名搜索" class="search-input" />
<el-button type="primary" size="small" class="w-60px h-40px">搜索</el-button>
<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>
@ -50,41 +50,42 @@ const router = useRouter();
const store = useStore();
const data = reactive({
tags: ['交付物', '财务条', '签到打卡', '即时奖惩'],
tags: [],
// tags: ['', '', '', ''],
keywords: '',
industryList: [
{
value: '行业一',
label: '行业一',
checked: true,
},
{
value: '行业二',
label: '行业二',
checked: false,
},
{
value: '行业三',
label: '行业三',
checked: false,
},
// {
// 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,
},
// {
// value: '',
// label: '',
// checked: false,
// },
// {
// value: '',
// label: '',
// checked: true,
// },
// {
// value: '',
// label: '',
// checked: false,
// },
],
});

28
src/routers/index.js

@ -3,7 +3,7 @@ import { createRouter, createWebHistory } from 'vue-router';
export const routes = [
// {
// path: '/store/overview',
// path: '/open/overview',
// name: 'overview',
// meta: {
// title: '设备概览',
@ -15,13 +15,13 @@ export const routes = [
export const user = [
{
path: '/store/user/signin',
path: '/open/user/signin',
name: 'signin',
meta: {},
component: () => import('views/user/sign-in.vue'),
},
{
path: '/store/user/pw-change',
path: '/open/user/pw-change',
name: 'pw-change',
meta: {},
component: () => import('views/user/pw-change.vue'),
@ -33,51 +33,51 @@ const router = createRouter({
routes: [
{
path: '/',
redirect: '/store/user/signin',
redirect: '/open/user/signin',
},
{
path: '/store',
redirect: '/store/user/signin',
path: '/open',
redirect: '/open/user/signin',
},
{
path: '/store/home',
path: '/open/home',
name: 'home',
component: () => import('views/Index.vue'),
children: [
{
path: '/store/home/plugin-shop',
path: '/open/home/plugin-shop',
name: 'plugin-shop',
component: () => import('views/index-list/plugin-shop.vue'),
},
{
path: '/store/home/console-desk',
path: '/open/home/console-desk',
name: 'console-desk',
component: () => import('views/index-list/console-desk.vue'),
children: [
{
path: '/store/home/console-desk/plugin-list',
path: '/open/home/console-desk/plugin-list',
name: 'desk-plugin-list',
component: () => import('views/index-list/plugin-list.vue'),
},
{
path: '/store/home/console-desk/add-plugin',
path: '/open/home/console-desk/add-plugin',
name: 'desk-add-plugin',
component: () => import('views/index-list/add-plugin.vue'),
},
{
path: '/store/home/console-desk/business-list',
path: '/open/home/console-desk/business-list',
name: 'desk-business-list',
component: () => import('views/index-list/business-list.vue'),
},
{
path: '/store/home/console-desk/add-business',
path: '/open/home/console-desk/add-business',
name: 'desk-add-business',
component: () => import('views/index-list/add-business.vue'),
},
],
},
{
path: '/store/home/business-detail',
path: '/open/home/business-detail',
name: 'business-detail',
component: () => import('views/index-list/business-detail.vue'),
},

2
src/utils/axios.js

@ -14,7 +14,7 @@ instance.interceptors.request.use(
config => {
const token = store.getters['user/token'] || sessionStorage.getItem('token');
if (token) {
// config.headers.Authorization = `Bearer ${token}`;
config.headers.Authorization = `Bearer ${token}`;
}
// config.headers.deviceId = store.state.systemInfo.deviceId;
config.headers.deviceId = '1';

5
src/views/Index.vue

@ -14,11 +14,6 @@
</template>
<script>
// import { ref } from 'vue';
// import Navbar from '../components/navbar.vue';
// const activeIndex = ref('1');
export default {};
</script>

17
src/views/index-list/add-business.vue

@ -12,14 +12,14 @@
</el-form-item>
<el-form-item label="行业:" prop="region">
<el-select v-model="form.region" placeholder="请选择">
<el-option value="Zone one"></el-option>
<el-option value="Zone two"></el-option>
<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="Zone one"></el-option>
<el-option value="Zone two"></el-option>
<el-option value="康复"></el-option>
<el-option value="管理"></el-option>
</el-select>
</el-form-item>
<el-form-item label="标签:" prop="tags">
@ -27,7 +27,7 @@
<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-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">
@ -85,19 +85,20 @@ const onSubmit = () => {
params.param.debug = form.debug ? 1 : 0;
await saveBusiness(params);
ElMessage.success('创建成功');
resetForm();
} else {
ElMessage.error('创建失败');
return false;
}
});
} catch (error) {
ElMessage.error(error || '创建失败');
console.log('error: ', error);
}
};
const resetForm = () => {
function resetForm() {
formRef.value.resetFields();
};
}
const options = [
{
value: 'HTML',

28
src/views/index-list/add-plugin.vue

@ -33,7 +33,6 @@
<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>
@ -44,7 +43,7 @@
<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="请输入CSS代码片段"></el-input>
<el-input v-model="form.config" type="textarea" placeholder="请输入配置文件"></el-input>
</el-form-item>
<el-form-item label="上传预览图:" prop="preview">
<el-upload
@ -86,6 +85,13 @@
<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>
@ -160,12 +166,12 @@ function onSubmit() {
resetForm();
bannerUpload.value.clearFiles();
} else {
ElMessage.error('插件创建失败');
console.log('error submit!!');
return false;
}
});
} catch (error) {
ElMessage.error(error || '插件创建失败');
console.error('error: ', error);
}
}
@ -284,4 +290,20 @@ function resetForm() {
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>

2
src/views/index-list/business-detail.vue

@ -25,7 +25,7 @@
<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">
<el-popover placement="bottom" title="请选择插件" :width="240" trigger="click">
<div class="radio-box">
<Relevance
:businessLists="data.pluginLists"

2
vite.config.js

@ -11,7 +11,7 @@ const resolve = dir => path.join(__dirname, dir);
// https://vitejs.dev/config/
export default defineConfig({
base: '/store/',
base: '/open/',
plugins: [vue(), VitePWA(), WindiCSS(), Components({ resolvers: [ElementPlusResolver()] }), viteCompression()],
resolve: {
alias: {

Loading…
Cancel
Save