Merge branch 'dev' into vite

# Conflicts:
#	examples/main.js
#	examples/router/autoRoutes.js
#	package.json
#	packages/bigscreen/designer/AppDesigner.vue
#	packages/bigscreen/designer/components/Add.vue
#	packages/bigscreen/designer/components/Layout.vue
#	packages/bigscreen/designer/components/List.vue
#	packages/bigscreen/designer/components/SourceData.vue
#	packages/bigscreen/designer/components/form/DataConfig.vue
#	packages/bigscreen/designer/config.js
#	packages/bigscreen/viewer/AppGigscreenViewer.vue
#	packages/conv/creditScore/scoreManage/scoreChange.vue
#	packages/index.js
#	project/dv/apps/AppGridDV.vue
#	project/dvui/components/AiMonitor/dhVideo.vue
#	project/dvui/components/AiSwiper.vue
#	project/dvui/layout/AiDvBackground.vue
#	project/dvui/layout/AiDvSummary/AiDvSummary.vue
#	project/dvui/layout/AiDvWrapper/AiDvWrapper.vue
#	project/dvui/package.json
#	public/index.html
#	vue.config.js
This commit is contained in:
aixianling
2022-07-07 09:01:40 +08:00
208 changed files with 14871 additions and 8799 deletions

View File

@@ -1,6 +1,6 @@
<template>
<div id="app">
<header-nav v-if="showTools" :title="serveName">
<header-nav v-if="showTools" title="web端产品库">
<template #right>
<div @click="showTools=false">隐藏工具栏</div>
<div @click="handleLogin">点此登录</div>
@@ -22,18 +22,13 @@
import SliderNav from "./components/sliderNav";
import MainContent from "./components/mainContent";
import HeaderNav from "./components/headerNav";
import {mapMutations, mapState} from "vuex";
export default {
name: 'app',
components: {HeaderNav, MainContent, SliderNav},
computed: {
serveName() {
let names = {
development: "村微产品库",
oms: "运营平台产品分库",
}
return names[process.env.NODE_ENV]
},
...mapState(['user']),
login() {
let url = '/auth/oauth/token';
/project\/sass/g.test(location.pathname) && (url += "?corpId=ww596787bb70f08288")
@@ -42,25 +37,24 @@ export default {
},
data() {
return {
token: "",
dialog: false,
showTools: true,
}
},
methods: {
setToken() {
localStorage.setItem('ui-token', this.token)
this.$message.success("设置token成功!")
},
...mapMutations(['setToken']),
getToken(params) {
this.token = params.access_token
this.setToken()
this.dialog = false
location.reload()
if (params.access_token) {
this.setToken([params.token_type, params.access_token].join(' '))
this.dialog = false
this.$message.success("登录成功,正在刷新页面...")
location.reload()
} else this.$message.error(params.msg || "登录失败!")
},
getUserInfo() {
this.$axios.post("/admin/user/detail-phone").then(res => {
if (res && res.data) {
if (res?.data) {
this.$store.commit("setUserInfo", res.data)
if (/^\/project\/xiushan/.test(location.pathname)) {
this.$store.commit("setFinanceUser")
@@ -69,21 +63,14 @@ export default {
})
},
handleLogin() {
this.$axios.delete("/auth/token/logout").then(() => {
this.$axios.delete("/auth/token/logout").finally(() => {
this.dialog = true
})
},
},
created() {
this.token = localStorage.getItem("ui-token")
if (this.token) this.getUserInfo()
if (this.user.token) this.getUserInfo()
wx = jWeixin
},
destroyed() {
this.token = ""
},
mounted() {
document.title = this.serveName
}
}
</script>

BIN
examples/assets/file.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -11,7 +11,7 @@
<el-dropdown @visible-change="v=>isClick=v" @command="doMenu" class="rightDropdown">
<el-row type="flex" align="middle">
<el-avatar :src="user.info.avatar">
{{ user.info.name.slice(-2) }}
{{ defaultAvatar }}
</el-avatar>
<span>{{ [user.info.name, user.info.roleName].join(" - ") }}</span>
<i :class="dropdownIcon"/>
@@ -48,6 +48,9 @@ export default {
dropdownIcon() {
return this.isClick ? 'el-icon-caret-top' : 'el-icon-caret-bottom'
},
defaultAvatar() {
return this.user.info.name?.slice(-2) || "无名"
}
},
methods: {
// 获取最新的安卓、ios下载二维码

View File

@@ -6,7 +6,7 @@
<ai-empty>欢迎使用村微产品库</ai-empty>
</el-tab-pane>
<el-tab-pane v-for="op in tabs" :key="op.name" :closable="op.name!='工作台'" :name="op.name" :label="op.label" lazy>
<router-view/>
<router-view v-if="currentTab==op.name"/>
</el-tab-pane>
</el-tabs>
</section>
@@ -21,7 +21,7 @@ export default {
...mapState(['apps']),
currentTab() {
let {name, query, hash} = this.$route
return [name, query?.id, hash].join("")
return [name?.replace(query?.id, ''), query?.id, hash].join("") || "0"
}
},
data() {
@@ -32,43 +32,44 @@ export default {
watch: {
$route: {
immediate: true,
handler(v) {
this.getTabs(v)
handler() {
this.getTabs("route")
}
},
},
methods: {
handleTabClick(tab) {
let to = {}, selectedTab = this.tabs.find(e => e.name == tab.name)
if (selectedTab) {
to = {...selectedTab, params: {tabclick: 1}}
} else {
let {name, query, hash} = tab
to = {name, query, hash, params: {tabclick: 1}}
}
this.$router.push({...to})
handleTabClick({name}) {
let {name: route, query, hash} = this.tabs.find(e => e.name == name),
exps = []
query.id && exps.push(query.id)
hash && exps.push(hash)
let reg = new RegExp(`(${exps.join("|")})`, 'g')
this.$router.push({name: route.replace(reg, ''), query, hash})
},
handleTabRemove(id = this.currentTab) {
let tabs = JSON.parse(JSON.stringify(this.tabs)),
index = tabs?.findIndex(e => id == e.name)
if (id == this.currentTab) {
let next = tabs?.[index + 1] || tabs?.[index - 1]
this.handleTabClick(next)
next ? this.handleTabClick(next) : this.$router.push({path: '/'})
}
this.tabs.splice(index, 1)
},
getTabs() {
getTabs(from) {
let {name, query, hash} = this.$route
let tab = this.tabs.find(e => e.name == this.currentTab)
console.log(`getTabs>>>>>>>>>%s>>>>>>>%s`, from, name)
let tab = this.tabs.find(e => e.name == this.currentTab),
tabName = [name, query?.id, hash].join("")
if (tab) {
} else if (name) {
} else if (!name) {
} else if (tabName) {
let menu = this.apps.find(e => e.name == name)
this.tabs.push({name, query, hash, label: menu?.label})
this.tabs.push({name: tabName, query, hash, label: menu?.label})
}
},
},
created() {
this.getTabs()
this.getTabs("created")
}
}
</script>

View File

@@ -8,6 +8,7 @@
@click.stop="openKidMenu(item)">
<i class="prep-icon" :class="item.style||'iconfont iconloudongmoxing'"/>
<span class="menuName fill" v-text="item.label"/>
<el-badge type="warning" :hidden="!item.project" :value="item.project"/>
<i v-if="item.children" class="iconfont" :class="arrowIcon(item.showChildren)"/>
</div>
<div class="kidMenu" v-if="item.showChildren" @click.stop>
@@ -41,7 +42,14 @@ export default {
...mapState(['user', 'apps']),
navs() {
let reg = new RegExp(`.*${this.searchApp?.replace(/-/g,'')||''}.*`, 'gi')
return (this.apps || []).filter(e => !this.searchApp || reg?.test(e.name) || reg?.test(e.label))
return (this.apps || []).filter(e => !this.searchApp || reg?.test(e.name) || reg?.test(e.label)).map(e => {
if (/\/project\//.test(e.path)) {
e.project = e.path.replace(/.*project\/([^\/]+)\/.+/, '$1')
} else if (/\/core\//.test(e.path)) {
e.project = "core"
}
return e
})
},
isConsoleRoute() {
return this.$route.name == "工作台"
@@ -104,7 +112,7 @@ export default {
</script>
<style lang="scss" scoped>
.sliderNav {
width: 200px;
min-width: 200px;
height: 100%;
transition: width .1s;
display: flex;

View File

@@ -8,9 +8,12 @@ import vcUI from 'dvcp-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';
import dvui from '../project/dvui/entries'
Vue.use(ui);
Vue.use(vcUI);
Vue.use(dvui)
//富文本编辑器配置
Vue.config.productionTip = false;
Vue.prototype.$axios = axios;

View File

@@ -2,6 +2,8 @@ import store from "../store";
import appEntry from "../views/appEntry";
import {waiting} from "../utils";
import router from "./router";
import axios from "./axios";
export default {
routes: [],
init() {
@@ -14,30 +16,29 @@ export default {
loadApps() {
//锁屏loading
waiting.init({innerHTML: '应用加载中..'})
//新App的自动化格式
let files = import.meta.glob('../../packages/**/App*.vue')
let cores = import.meta.glob('../../core/**/App*.vue')
let projects = import.meta.glob('../../project/**/App*.vue')
files = {...files, ...cores, ...projects}
return Promise.all(Object.keys(files).map(path => {
if (/App[A-Z]\w+\.vue/.test(path)) {
return files?.[path]()?.then(file => {
let {name, label} = file.default,
addApp = {
name: [path.replace(/[.\/]+(project)?[\/]([a-z]+).+/, '$2'), name].join("_"), label: label || name,
path: path.replace(/[.\/]+([a-zA-Z].+\/App[A-Z]\w+)\.vue$/, '/v/$1'),
component: appEntry,
module: file.default
}
//命名规范入口文件必须以App开头
waiting.setContent(`加载${name}...`)
router.addRoute(addApp)
this.routes.push(addApp)
return store.commit("addApp", addApp)
})
} else {
return Promise.resolve()
}
})).then(() => waiting.close())
let apps = require.context('../../', true, /\.(\/.+)\/App[A-Z][^\/]+\.vue$/, "lazy")
Promise.all(apps.keys().map(path => apps(path).then(file => {
if (file.default) {
let {name, label} = file.default,
addApp = {
name: path.replace(/\.\/?(vue)?/g, '')?.split("/").join("_"), label: label || name,
path: path.replace(/\.(\/.+\/App.+)\.vue$/, '$1'),
component: appEntry,
module: file.default
}
waiting.setContent(`加载${name}...`)
router.addRoute(addApp)
//命名规范入口文件必须以App开头
return store.commit("addApp", addApp)
} else return 0
}))).then(() => {
axios.post("/node/wechatapps/addOrUpdate", {
type: "web",
list: this.routes().map(({path: libPath, label, module: {name}, name: id}) => ({
id, type: 'web', libPath, label, name
}))
}, {baseURL: "/ns"}).catch(() => 0)
waiting.close()
})
}
}

View File

@@ -7,10 +7,11 @@ let baseURLs = {
oms: '/oms'
}
instance.defaults.baseURL = baseURLs[process.env.NODE_ENV]
instance.interceptors.request.eject(0);
instance.interceptors.request.use(config => {
if (config.url.startsWith("/node")) {
config.baseURL = "/ns"
} else if (/\/project\/beta/.test(location.pathname)) {
config.baseURL = "/wg"
} else if (/\/project\/sass/.test(location.pathname)) {
config.baseURL = "/saas"
} else if (/\/xiushan/.test(location.pathname)) {
@@ -19,9 +20,11 @@ instance.interceptors.request.use(config => {
} else if (/project\/oms/.test(location.pathname)) {
config.baseURL = "/omsapi"
config.url = config.url.replace(/(app|auth|admin)\//, "")
}
if (!config.withoutToken && localStorage.getItem("ui-token")) {
config.headers['Authorization'] = ["Bearer", localStorage.getItem("ui-token")].join(" ")
} else if (/#url-/.test(location.hash)) {
config.baseURL = location.hash.replace(/#url-/, '/')
if (["/xsjr", "/omsapi"].includes(config.baseURL)) {
config.url = config.url.replace(/(app|auth|admin)\//, "")
}
}
return config
}, error => Message.error(error))

View File

@@ -8,7 +8,7 @@ Vue.use(Vuex)
const user = {
state: {
info: {},
ATime: '',
token: '',
financeUser: {}
},
mutations: {
@@ -20,8 +20,8 @@ const user = {
setUserInfo(state, userInfo) {
state.info = userInfo
},
SET_TIME(state, pay) {
state.ATime = pay
setToken(state, token) {
state.token = token
}
}
}

View File

@@ -68,7 +68,9 @@ export const waiting = {
div.style.textAlign = 'center'
div.style.lineHeight = '100vh'
div.style.color = '#26f'
div.style.background = 'rgba(0,0,0,.8)'
div.style.fontSize = '20px'
div.style.background = 'rgba(255,255,255,.8)'
div.style.backdropFilter = 'blur(6px)'
document.body.appendChild(div)
} else if (count < 10) {
setTimeout(() => this.init(ops, ++count), 500)