初始化
This commit is contained in:
226
examples/App.vue
Normal file
226
examples/App.vue
Normal file
@@ -0,0 +1,226 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<div class="header" v-if="showTools">
|
||||
<b v-text="serveName"/>
|
||||
<el-button type="text" @click="showTools=false">隐藏工具栏</el-button>
|
||||
<el-button type="text" @click="handleLogin">点此登录</el-button>
|
||||
</div>
|
||||
<el-row class="main-content" type="flex">
|
||||
<el-scrollbar class="menu" v-if="showTools">
|
||||
<el-input size="small" v-model="search" placeholder="应用名称或文件名" clearable @change="recordSearch"/>
|
||||
<el-menu router>
|
||||
<el-menu-item v-for="(menu,j) in menus" :key="j" :index="menu.path">
|
||||
{{ menu.label }}
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</el-scrollbar>
|
||||
<router-view v-if="selectedApp"/>
|
||||
<ai-empty v-else>请选择应用</ai-empty>
|
||||
</el-row>
|
||||
<div v-if="dialog" class="sign-box">
|
||||
<ai-sign style="margin: auto" :instance="$axios" :action="{login:'/auth/oauth/token?corpId=ww596787bb70f08288'}"
|
||||
visible @login="getToken" :showScanLogin="false"/>
|
||||
</div>
|
||||
<el-button type="info" v-if="!showTools" class="fixedBtn" @click="showTools=true">显示工具栏</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: 'app',
|
||||
computed: {
|
||||
...mapState(['apps']),
|
||||
serveName() {
|
||||
let names = {
|
||||
development: "村微产品库",
|
||||
oms: "运营平台产品分库",
|
||||
}
|
||||
return names[process.env.NODE_ENV]
|
||||
},
|
||||
menus() {
|
||||
let reg = new RegExp(`.*${this.search.replace(/-/g,'')||''}.*`, 'gi')
|
||||
return (this.apps || []).filter(e => !this.search || reg.test(e.name) || reg.test(e.label))
|
||||
},
|
||||
selectedApp() {
|
||||
return this.$route.matched.length > 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
token: "",
|
||||
search: "",
|
||||
dialog: false,
|
||||
showTools: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setToken() {
|
||||
localStorage.setItem('ui-token', this.token)
|
||||
this.$message.success("设置token成功!")
|
||||
},
|
||||
getToken(params) {
|
||||
this.token = params.access_token
|
||||
this.setToken()
|
||||
this.dialog = false
|
||||
location.reload()
|
||||
},
|
||||
getUserInfo() {
|
||||
this.$axios.post("/admin/user/detail-phone").then(res => {
|
||||
if (res && res.data) {
|
||||
this.$store.commit("setUserInfo", res.data)
|
||||
}
|
||||
})
|
||||
},
|
||||
handleLogin() {
|
||||
this.$axios.delete("/auth/token/logout").then(() => {
|
||||
this.dialog = true
|
||||
})
|
||||
},
|
||||
recordSearch() {
|
||||
localStorage.setItem("searchApp", this.search)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.search = localStorage.getItem("searchApp") || ""
|
||||
this.token = localStorage.getItem("ui-token")
|
||||
if (this.token) this.getUserInfo()
|
||||
wx = jWeixin
|
||||
},
|
||||
destroyed() {
|
||||
this.token = ""
|
||||
},
|
||||
mounted() {
|
||||
document.title = this.serveName
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
.villageFinance-autocomplete {
|
||||
width: auto !important;
|
||||
|
||||
li {
|
||||
line-height: normal !important;
|
||||
padding: 7px !important;
|
||||
border-bottom: 1px solid #f1f1f1;
|
||||
|
||||
&:hover {
|
||||
background-color: #f4f4f4 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
text-overflow: ellipsis;
|
||||
line-height: normal;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.addr {
|
||||
font-size: 12px;
|
||||
color: #b4b4b4;
|
||||
}
|
||||
|
||||
.highlighted .addr {
|
||||
color: #ddd;
|
||||
}
|
||||
}
|
||||
|
||||
#app {
|
||||
font-family: 'Avenir', Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
color: #2c3e50;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
|
||||
.fixedBtn {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 60px;
|
||||
opacity: 0;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.menu {
|
||||
min-width: 200px;
|
||||
flex-shrink: 0;
|
||||
height: 100%;
|
||||
border-right: solid 1px #e6e6e6;
|
||||
background-color: #fff;
|
||||
|
||||
.el-scrollbar__view {
|
||||
padding: 4px 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.el-menu {
|
||||
border: none;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
& > .header {
|
||||
text-align: start;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
height: 60px;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 16px;
|
||||
|
||||
& > b {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.el-input {
|
||||
max-width: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
& > .main-content {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
box-sizing: border-box;
|
||||
|
||||
& > *:last-child {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.sign-box {
|
||||
z-index: 99;
|
||||
margin: -10px;
|
||||
display: flex;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
BIN
examples/assets/building.png
Normal file
BIN
examples/assets/building.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
22
examples/entries.js
Normal file
22
examples/entries.js
Normal file
@@ -0,0 +1,22 @@
|
||||
//引入当前工程所有的应用
|
||||
const install = function(Vue) {
|
||||
if (install.installed) return Promise.resolve();
|
||||
else {
|
||||
let contexts = require.context('../packages', true, /(\/.+)\/App[^\/]+\.vue$/);
|
||||
if (contexts) {
|
||||
contexts.keys().map((e) => {
|
||||
if (contexts(e).default) {
|
||||
Vue.component(contexts(e).default.name, contexts(e).default);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
// 判断是否是直接引入文件
|
||||
if (typeof window !== 'undefined' && window.Vue) {
|
||||
install(window.Vue);
|
||||
}
|
||||
export default {
|
||||
// 导出的对象必须具有 install,才能被 Vue.use() 方法安装
|
||||
install
|
||||
};
|
||||
31
examples/main.js
Normal file
31
examples/main.js
Normal file
@@ -0,0 +1,31 @@
|
||||
import Vue from 'vue';
|
||||
import App from './App.vue';
|
||||
import ui from 'element-ui';
|
||||
import router from './router/router';
|
||||
import apps from './entries';
|
||||
import axios from './router/axios';
|
||||
import utils from './utils';
|
||||
import vcUI from 'dvcp-ui';
|
||||
import dvUI from 'dvcp-dv-ui'
|
||||
import 'dvcp-ui/lib/styles/common.scss';
|
||||
import 'dvcp-ui/lib/dvcp-ui.css';
|
||||
import store from './store';
|
||||
import dataV from '@jiaminghi/data-view';
|
||||
|
||||
Vue.use(dataV);
|
||||
|
||||
Vue.use(apps);
|
||||
Vue.use(ui);
|
||||
Vue.use(vcUI);
|
||||
Vue.use(dvUI);
|
||||
//富文本编辑器配置
|
||||
Vue.config.productionTip = false;
|
||||
Vue.prototype.$axios = axios;
|
||||
Vue.prototype.formatContent = (val) => val.replace(/(\r\n)|(\n)/g, '<br>');
|
||||
Object.keys(utils).map((e) => (Vue.prototype[e] = utils[e]));
|
||||
utils.$store.init(store);
|
||||
new Vue({
|
||||
router,
|
||||
store,
|
||||
render: (h) => h(App)
|
||||
}).$mount('#app');
|
||||
71
examples/router/autoRoutes.js
Normal file
71
examples/router/autoRoutes.js
Normal file
@@ -0,0 +1,71 @@
|
||||
import store from "../store";
|
||||
|
||||
export default {
|
||||
routes: () => store.state.apps.map(e => {
|
||||
return {
|
||||
...e,
|
||||
component: () => import(`../views/apps/${e.entry}`)
|
||||
}
|
||||
}),
|
||||
init() {
|
||||
//约束正则式
|
||||
store.commit("cleanApps")
|
||||
// 自动化本工程应用
|
||||
this.loadApps()
|
||||
},
|
||||
loadApps() {
|
||||
//新App的自动化格式
|
||||
let files = require.context('../../packages', true, /\.(\/.+)\/App[^\/]+\.vue$/)
|
||||
files.keys().map(path => {
|
||||
if (files(path).default) {
|
||||
let {name, label} = files(path).default,
|
||||
addApp = {
|
||||
name, label: label || name,
|
||||
path: path.replace(/\.(\/.+\/App.+)\.vue$/, '$1'),
|
||||
entry: 'appEntry'
|
||||
}
|
||||
//命名规范入口文件必须以App开头
|
||||
store.commit("addApp", addApp)
|
||||
}
|
||||
})
|
||||
let cores = require.context('../../core', true, /\.(\/.+)\/App[^\/]+\.vue$/)
|
||||
cores.keys().map(path => {
|
||||
if (cores(path).default) {
|
||||
let {name, label} = cores(path).default,
|
||||
addApp = {
|
||||
name, label: label || name,
|
||||
path: path.replace(/\.(\/.+\/App.+)\.vue$/, '$1'),
|
||||
entry: 'appEntry'
|
||||
}
|
||||
//命名规范入口文件必须以App开头
|
||||
store.commit("addApp", addApp)
|
||||
}
|
||||
})
|
||||
let oms = require.context('../../oms', true, /\.(\/.+)\/App[^\/]+\.vue$/)
|
||||
oms.keys().map(path => {
|
||||
if (oms(path).default) {
|
||||
let {name, label} = oms(path).default,
|
||||
addApp = {
|
||||
name, label: label || name,
|
||||
path: path.replace(/\.(\/.+\/App.+)\.vue$/, '$1'),
|
||||
entry: 'appEntry'
|
||||
}
|
||||
//命名规范入口文件必须以App开头
|
||||
store.commit("addApp", addApp)
|
||||
}
|
||||
})
|
||||
let project = require.context('../../project', true, /\.(\/.+)\/App[^\/]+\.vue$/)
|
||||
project.keys().map(path => {
|
||||
if (project(path).default) {
|
||||
let {name, label} = project(path).default,
|
||||
addApp = {
|
||||
name, label: label || name,
|
||||
path: path.replace(/\.(\/.+\/App.+)\.vue$/, '$1'),
|
||||
entry: 'appEntry'
|
||||
}
|
||||
//命名规范入口文件必须以App开头
|
||||
store.commit("addApp", addApp)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
17
examples/router/axios.js
Normal file
17
examples/router/axios.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import instance from 'dvcp-ui/lib/js/request'
|
||||
import {Message} from 'element-ui'
|
||||
|
||||
let baseURLs = {
|
||||
production: "/",
|
||||
development: '/lan',
|
||||
oms: '/oms'
|
||||
}
|
||||
instance.defaults.baseURL = baseURLs[process.env.NODE_ENV]
|
||||
instance.interceptors.request.eject(0);
|
||||
instance.interceptors.request.use(config => {
|
||||
if (!config.withoutToken && localStorage.getItem("ui-token")) {
|
||||
config.headers['Authorization'] = ["Bearer", localStorage.getItem("ui-token")].join(" ")
|
||||
}
|
||||
return config
|
||||
}, error => Message.error(error))
|
||||
export default instance
|
||||
18
examples/router/router.js
Normal file
18
examples/router/router.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
import autoRoutes from './autoRoutes'
|
||||
|
||||
Vue.use(VueRouter)
|
||||
autoRoutes.init()
|
||||
export default new VueRouter({
|
||||
mode: 'history',
|
||||
hashbang: false,
|
||||
routes: autoRoutes.routes(),
|
||||
scrollBehavior(to) {
|
||||
if (to.hash) {
|
||||
return {
|
||||
selector: to.hash
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
50
examples/store/index.js
Normal file
50
examples/store/index.js
Normal file
@@ -0,0 +1,50 @@
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import preState from 'vuex-persistedstate'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
const user = {
|
||||
state: {
|
||||
info: {},
|
||||
ATime:''
|
||||
},
|
||||
mutations: {
|
||||
setUserInfo(state, userInfo) {
|
||||
state.info = userInfo
|
||||
},
|
||||
SET_TIME(state, pay){
|
||||
state.ATime=pay
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new Vuex.Store({
|
||||
state: {
|
||||
dicts: [],
|
||||
apps: []
|
||||
},
|
||||
mutations: {
|
||||
setDicts(state, payload) {
|
||||
if (payload) {
|
||||
payload.map(p => {
|
||||
if (state.dicts.some(d => d.key == p.key)) {
|
||||
const index = state.dicts.findIndex(d => d.key == p.key)
|
||||
state.dicts.splice(index, 1)
|
||||
state.dicts.push(p)
|
||||
} else {
|
||||
state.dicts.push(p)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
addApp(state, app) {
|
||||
state.apps.push(app)
|
||||
},
|
||||
cleanApps(state) {
|
||||
state.apps = []
|
||||
}
|
||||
},
|
||||
modules: {user},
|
||||
plugins: [preState()]
|
||||
})
|
||||
79
examples/utils/index.js
Normal file
79
examples/utils/index.js
Normal file
@@ -0,0 +1,79 @@
|
||||
import {MessageBox} from 'element-ui'
|
||||
import store from '../store'
|
||||
import tools from 'dvcp-ui/lib/js/utils'
|
||||
|
||||
const addChildParty = (parent, pending) => {
|
||||
let doBeforeCount = pending.length
|
||||
parent["children"] = parent["children"] || []
|
||||
pending.map((e, index, arr) => {
|
||||
if (e.partyOrgParentId == parent.partyOrgId) {
|
||||
parent.children.push(e)
|
||||
arr.splice(index, 1)
|
||||
addChildParty(parent, arr)
|
||||
}
|
||||
})
|
||||
if (parent.children.length == 0) {
|
||||
delete parent.children
|
||||
}
|
||||
if (pending.length > 0 && doBeforeCount > pending.length) {
|
||||
parent.children.map(c => addChildParty(c, pending))
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 封装提示框
|
||||
*/
|
||||
|
||||
|
||||
const $confirm = (content, options) => {
|
||||
return MessageBox.confirm(content, {
|
||||
type: "warning",
|
||||
confirmButtonText: "确认",
|
||||
center: true,
|
||||
title: "提示",
|
||||
dangerouslyUseHTMLString: true,
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 封装权限判断方法
|
||||
*/
|
||||
|
||||
|
||||
const $permissions = flag => {
|
||||
const buttons = store.state.user.info.buttons
|
||||
if (buttons) return buttons.some(b => b.id == flag || b.permission == flag)
|
||||
else return false
|
||||
}
|
||||
|
||||
const $decimalCalc = (...arr) => {
|
||||
//确认提升精度
|
||||
let decimalLengthes = arr.map(e => {
|
||||
let index = ("" + e).indexOf(".")
|
||||
return ("" + e).length - index
|
||||
})
|
||||
let maxDecimal = Math.max(...decimalLengthes), precision = Math.pow(10, maxDecimal)
|
||||
//计算
|
||||
let intArr = arr.map(e => (Number(e) || 0) * precision)
|
||||
//返回计算值
|
||||
return intArr.reduce((t, a) => t + a) / precision
|
||||
}
|
||||
/**
|
||||
* @param { function } func
|
||||
|
||||
* @param { number } wait 延迟执行毫秒数
|
||||
|
||||
* @param { boolean } immediate true 表立即执行,false 表非立即执行
|
||||
*/
|
||||
|
||||
|
||||
|
||||
export default {
|
||||
...tools,
|
||||
addChildParty,
|
||||
$confirm,
|
||||
$permissions,
|
||||
$decimalCalc
|
||||
}
|
||||
|
||||
|
||||
32
examples/views/apps/appEntry.vue
Normal file
32
examples/views/apps/appEntry.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<section class="appEntry">
|
||||
<component v-if="app" :is="app" :instance="$axios" :dict="$dict" :permissions="$permissions"/>
|
||||
<ai-empty v-else>无法找到应用文件</ai-empty>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "appEntry",
|
||||
label: "应用库-应用",
|
||||
computed: {
|
||||
app() {
|
||||
return this.$route.name
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.appEntry {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
|
||||
& > * {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
13
examples/views/index.vue
Normal file
13
examples/views/index.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<router-view />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "index"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user