main
xy 2 years ago
parent a55ccfce36
commit b20ff9f88a

@ -2,7 +2,7 @@
ENV = 'production'
# base api
VUE_APP_BASE_API='http://cz-hjjc.115.langye.net'
VUE_APP_UPLOAD_API='http://cz-hjjc.115.langye.net/api/admin/upload-file'
VUE_APP_BASE_API='https://cz-hjjc.115.langye.net'
VUE_APP_UPLOAD_API='https://cz-hjjc.115.langye.net/api/admin/upload-file'
VUE_APP_PREVIEW=//view.langye.net/preview/onlinePreview

Binary file not shown.

Before

Width:  |  Height:  |  Size: 696 KiB

After

Width:  |  Height:  |  Size: 304 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

@ -23,7 +23,7 @@ export default {
},
mounted() {
this.$nextTick(() => {
this.theme = Cookies.get("defaultTheme")
this.theme = Cookies.get("defaultTheme") || ORIGINAL_THEME
document.body.style.setProperty('--theme-color', Cookies.get("defaultTheme"));
})
},

@ -0,0 +1 @@
<svg t="1727143647946" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6837" width="200" height="200"><path d="M512.2 475.7c-8.2-0.3-16.1-2.4-23.4-6.1L192.6 330.2c-24.9-11.1-36.1-40.3-25-65.2 5-11.2 13.9-20.1 25-25l281.5-133.2a89.43 89.43 0 0 1 76 0L831.7 240c24.9 11.1 36.1 40.3 25 65.2-5 11.2-13.9 20.1-25 25L535.5 469.5c-7.2 3.8-15.2 5.9-23.3 6.2z m-76.5 452.5c-7.6 0-15.1-1.9-21.8-5.5L146.3 797.2c-17-8.9-27.5-26.5-27.3-45.6v-320c0.1-18 9.7-34.5 25.1-43.7 14.3-8.1 31.8-8.1 46.1 0l267.1 125.4c16.1 8.7 26.4 25.4 27.1 43.7v320.4c-0.2 17.9-9.6 34.4-24.9 43.7-7.2 4.3-15.4 6.8-23.8 7.1z m152.9 0c-8.3 0-16.5-2.2-23.8-6.3-15.3-9.3-24.7-25.8-24.9-43.7V556.9c0.4-18.2 10.4-34.8 26.2-43.7L835 387c14.2-7.5 31.4-7.1 45.2 1.1 15.5 9.1 25 25.7 25.1 43.7v319.8c0.4 18.9-9.7 36.5-26.2 45.6L610.5 922.8c-6.8 3.6-14.3 5.5-21.9 5.4z" p-id="6838"></path></svg>

After

Width:  |  Height:  |  Size: 893 B

@ -1,5 +1,6 @@
<script>
export default {
name: "Icon",
props: {
icon: String
},

@ -10,12 +10,13 @@
</template>
<template v-else>
<el-submenu ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
<el-submenu ref="subMenu" :index="/^\/+/.test(resolvePath(item.path)) ? Math.random().toString() : resolvePath(item.path)" popper-append-to-body>
<template slot="title">
<icon :icon="item.meta.icon"></icon>{{ item.meta.title }}
</template>
<navbar-item v-for="child in item.children"
:key="child.path" :item="child"
:key="child.path"
:item="child"
:base-path="resolvePath(child.path)"
class="nest-menu" />
</el-submenu>

@ -7,9 +7,7 @@
</button>
<div class="navbar-brand navbar-brand-autodark d-none-navbar-horizontal pe-0 pe-md-3">
<router-link to="/">
<svg xmlns="http://www.w3.org/2000/svg" width="110" height="32" viewBox="0 0 232 68" class="navbar-brand-image">
<path d="M64.6 16.2C63 9.9 58.1 5 51.8 3.4 40 1.5 28 1.5 16.2 3.4 9.9 5 5 9.9 3.4 16.2 1.5 28 1.5 40 3.4 51.8 5 58.1 9.9 63 16.2 64.6c11.8 1.9 23.8 1.9 35.6 0C58.1 63 63 58.1 64.6 51.8c1.9-11.8 1.9-23.8 0-35.6zM33.3 36.3c-2.8 4.4-6.6 8.2-11.1 11-1.5.9-3.3.9-4.8.1s-2.4-2.3-2.5-4c0-1.7.9-3.3 2.4-4.1 2.3-1.4 4.4-3.2 6.1-5.3-1.8-2.1-3.8-3.8-6.1-5.3-2.3-1.3-3-4.2-1.7-6.4s4.3-2.9 6.5-1.6c4.5 2.8 8.2 6.5 11.1 10.9 1 1.4 1 3.3.1 4.7zM49.2 46H37.8c-2.1 0-3.8-1-3.8-3s1.7-3 3.8-3h11.4c2.1 0 3.8 1 3.8 3s-1.7 3-3.8 3z" fill="#066fd1" style="fill: var(--tblr-primary, #066fd1)" />
</svg>
<img :src="require('@/assets/title.png')" style="height: 20px;filter: drop-shadow(0 2px 4px #00000088)" alt="">
</router-link>
</div>
<div class="navbar-nav flex-row order-md-last">
@ -45,7 +43,7 @@
<img class="avatar avatar-sm" style="" src="@/assets/face.jpg" alt="">
<div class="d-none d-xl-block ps-2">
<div>{{ name }}</div>
<div class="mt-1 small text-secondary">{{ (department && department.name) ? department.name : '暂无部门' }}</div>
<div class="mt-1 small" style="color: #eee;">{{ (department && department.name) ? department.name : '暂无部门' }}</div>
</div>
</a>

@ -51,17 +51,17 @@ Vue.component("Treeselect",Treeselect);
import CardContainer from "@/layout/CardContainer.vue"
Vue.component("CardContainer",CardContainer)
//wujie
import Wujie from "wujie-vue2";
Vue.use(Wujie);
const { setupApp, preloadApp } = Wujie;
setupApp({
name: "modules",
sync: true,
degrade: true,
alive: true,
url: "http://localhost:9530/admin/#/",
exec: true,
});
// import Wujie from "wujie-vue2";
// Vue.use(Wujie);
// const { setupApp, preloadApp } = Wujie;
// setupApp({
// name: "modules",
// sync: true,
// degrade: true,
// alive: true,
// url: "http://localhost:9530/admin/#/",
// exec: true,
// });
Vue.config.productionTip = false;
new Vue({

@ -1,16 +1,15 @@
import { asyncRoutes, constantRoutes } from '@/router'
import { permissions } from "@/api/me"
import path from "path"
import Layout from "@/layout"
import Nested from "@/layout/nested.vue"
import Wujie from "@/views/wujie"
import { constantRoutes } from '@/router'
import { permissions } from '@/api/me'
import Layout from '@/layout'
import Nested from '@/layout/nested.vue'
import Wujie from '@/views/wujie'
const loadView = (view) => {
return (resolve) => require([`@/views${view}`], resolve);
return (resolve) => require([`@/views${view}`], resolve)
}
const componentHandle = (path, route)=> {
const componentHandle = (path, route) => {
if (/^#+/.test(path)) {
return Layout
return Layout
} else if (/^#+/.test(path) && route.pid !== 0) {
return Nested
} else if (/^\/./.test(path)) {
@ -25,7 +24,7 @@ export function filterAsyncRoutes(routes) {
routes.forEach(route => {
if (!route.visible) return
let tmp= {
const tmp = {
key: `key-${route.id}`,
path: route.path === '#' ? '' : route.path,
component: componentHandle(route.path, route),
@ -37,9 +36,10 @@ export function filterAsyncRoutes(routes) {
guard: route.guard_name,
folder: route.folder,
isModule: !/^\/./.test(route.path),
//TODO:修改地址
moduleUri: /^\/./.test(route.path) ? '' : `http://localhost:9528/${route.path}`,
moduleName: /^\/./.test(route.path) ? '' : route.path,
// TODO:修改地址
//moduleUri: /^\/./.test(route.path) ? '' : `https://cz-hjjc.115.langye.net/${route.path}`,
moduleUri: /^\/./.test(route.path) ? '' : `/${route.path}`,
moduleName: /^\/./.test(route.path) ? '' : route.path
}
}
@ -66,12 +66,11 @@ const mutations = {
const actions = {
generateRoutes({ commit }, roles) {
return new Promise(async (resolve, reject) => {
return new Promise(async(resolve, reject) => {
try {
const routes = await permissions()
let accessedRoutes
accessedRoutes = filterAsyncRoutes(routes)
//把404拦截放在最后匹配
const accessedRoutes = filterAsyncRoutes(routes)
// 把404拦截放在最后匹配
accessedRoutes.push({ path: '*', redirect: '/404', hidden: true })
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)

@ -10386,7 +10386,6 @@ body {
}
.navbar {
--tblr-navbar-bg: var(--tblr-bg-surface);
--tblr-navbar-border-width: var(--tblr-border-width);
--tblr-navbar-active-border-color: var(--tblr-primary);
--tblr-navbar-active-bg: rgba(0, 0, 0, 0.06);
@ -10395,7 +10394,7 @@ body {
align-items: stretch;
min-height: 3.5rem;
box-shadow: inset 0 calc(-1 * var(--tblr-navbar-border-width)) 0 0 var(--tblr-navbar-border-color);
background: var(--tblr-navbar-bg);
background: var(--theme-color);
color: var(--tblr-navbar-color)
}
@ -10421,7 +10420,15 @@ body {
min-width: 2rem;
min-height: 2rem;
justify-content: center;
border-radius: var(--tblr-border-radius)
border-radius: var(--tblr-border-radius);
}
.navbar .navbar-nav .nav-link svg {
color: #fff;
filter: drop-shadow(0 0 1px #000000cc);
}
.navbar .nav-link > div {
color: #fff;
text-shadow: 1px 1px #00000066;
}
.navbar .navbar-nav .nav-link .badge {

@ -13,7 +13,7 @@
}
.el-menu--collapse .el-menu .el-submenu, .el-menu--popup {
text-align: center;
min-width: 100px !important;
min-width: 120px !important;
}
#navbar-menu-mobile {

@ -69,13 +69,6 @@ const defaultSettings = require('../../../src/settings.js')
export default {
name: 'Login',
data() {
const validateUsername = (rule, value, callback) => {
if (!validUsername(value)) {
callback(new Error('请正确输入登录名'))
} else {
callback()
}
}
const validatePassword = (rule, value, callback) => {
if (value.length < 6) {
callback(new Error('密码输入错误'))
@ -94,7 +87,7 @@ export default {
username: [{
required: true,
trigger: 'blur',
validator: validateUsername
message: "请输入用户名"
}],
password: [{
required: true,

@ -28,7 +28,7 @@
:column-config="{ resizable: true }"
:edit-rules="validMenuRules"
:edit-config="{ trigger: 'manual', mode: 'row', showStatus: true, autoClear: false }"
:tree-config="{ rowField: 'id', parentField: 'pid' }"
:tree-config="{ rowField: 'id', parentField: 'pid', expandAll: true }"
:data="menus">
<vxe-column type="seq" width="58" align="center"></vxe-column>
<vxe-column field="name" tree-node width="160" title="菜单" :edit-render="{ name: 'input', attrs: { type: 'text'} }"></vxe-column>
@ -42,6 +42,16 @@
</template>
</template>
</vxe-column>
<vxe-column field="url" title="页面模块路径" min-width="140" :edit-render="{ name: 'input', attrs: { type: 'text'} }">
<template #default="{ row }">
<template v-if="/#/g.test(row.url)">
<SvgIcon icon-class="folder" class-name="icon-folder"></SvgIcon>
</template>
<template v-else>
<span>{{ row.url }}</span>
</template>
</template>
</vxe-column>
<vxe-column field="api_profix" min-width="140" title="api前缀" :edit-render="{ name: 'input', attrs: { type: 'text'} }">
<template #default="{ row }">
<template v-if="/#/g.test(row.api_profix)">
@ -382,7 +392,9 @@ export default {
async getUsers() {
this.loading = true;
try {
const res = await grant()
const res = await grant({
module_id: this.moduleId
})
console.log(res)
this.users = res.rows;
this.userTotal = res.total;

@ -30,6 +30,9 @@
<el-form-item label="路由路径" prop="path" required>
<el-input v-model="form.path" clearable></el-input>
</el-form-item>
<el-form-item label="页面模块路径" prop="url">
<el-input v-model="form.url" clearable></el-input>
</el-form-item>
<el-form-item label="api前缀" prop="api_profix" required>
<el-input v-model="form.api_profix" clearable></el-input>
</el-form-item>
@ -73,6 +76,7 @@ export default {
icon: "",
visible: 1,
path: "",
url: "",
api_profix: "",
sortnumber: 0
},

@ -8,9 +8,9 @@
</template>
</vxe-toolbar>
<vxe-table
ref="table"
stripe
style="margin-top: 10px;"
ref="table"
:loading="loading"
keep-source
show-overflow
@ -18,11 +18,12 @@
:edit-rules="validRules"
:edit-config="{ trigger: 'manual', mode: 'row', showStatus: true, isHover: true, autoClear: false }"
:align="allAlign"
:data="tableData">
<vxe-column type="seq" width="58" align="center"></vxe-column>
<vxe-column field="title" width="160" title="名称" :edit-render="{ name: 'input', attrs: { type: 'text'} }"></vxe-column>
<vxe-column field="name" width="160" title="模块" :edit-render="{ name: 'input', attrs: { type: 'text'} }"></vxe-column>
<vxe-column field="sortnumber" width="80" title="排序" align="center" :edit-render="{ name: 'input', attrs: { type: 'number' } }"></vxe-column>
:data="tableData"
>
<vxe-column type="seq" width="58" align="center" />
<vxe-column field="title" width="160" title="名称" :edit-render="{ name: 'input', attrs: { type: 'text'} }" />
<vxe-column field="name" width="160" title="模块" :edit-render="{ name: 'input', attrs: { type: 'text'} }" />
<vxe-column field="sortnumber" width="80" title="排序" align="center" :edit-render="{ name: 'input', attrs: { type: 'number' } }" />
<vxe-column field="operate" title="操作" min-width="220">
<template #default="{ row }">
<template v-if="isActiveStatus(row)">
@ -41,16 +42,16 @@
<p class="total" type="primary"> {{ total }} 条数据</p>
</card-container>
<AddModule ref="AddModule" :is-show.sync="isShowAdd" @refresh="getList"></AddModule>
<ModuleAuth ref="ModuleAuth" :is-show.sync="isShowDrawer"></ModuleAuth>
<AddModule ref="AddModule" :is-show.sync="isShowAdd" @refresh="getList" />
<ModuleAuth ref="ModuleAuth" :is-show.sync="isShowDrawer" />
</div>
</template>
<script>
import ModuleAuth from './components/ModuleAuth.vue'
import AddModule from './components/AddModule.vue'
import { deepCopy } from "@/utils"
import { index, save, destroy } from "@/api/module"
import { deepCopy } from '@/utils'
import { index, save, destroy } from '@/api/module'
export default {
components: {
AddModule,
@ -67,31 +68,43 @@ export default {
tableData: [],
validRules: {
name: [
{ required: true, message: "请输入模块" }
{ required: true, message: '请输入模块' }
],
title: [
{ required: true, message: "请输入名称" }
{ required: true, message: '请输入名称' }
]
},
form: {
id: "",
title: "",
name: "",
id: '',
title: '',
name: '',
sortnumber: 0
}
}
},
computed: {
isActiveStatus() {
return function(row) {
if (this.$refs['table']) {
return this.$refs['table'].isEditByRow(row)
}
}
}
},
created() {
this.getList()
},
methods: {
showModuleAuth(row) {
this.$refs['ModuleAuth'].setId(row.id);
this.$refs['ModuleAuth'].setId(row.id)
this.isShowDrawer = true
},
editRowEvent (row) {
editRowEvent(row) {
if (this.$refs['table']) {
this.$refs['table'].setEditRow(row)
}
},
cancelRowEvent (row) {
cancelRowEvent(row) {
if (this.$refs['table']) {
this.$refs['table'].clearEdit().then(() => {
//
@ -100,74 +113,62 @@ export default {
}
},
async getList () {
this.loading = true;
async getList() {
this.loading = true
try {
const res = await index()
this.tableData = res.rows;
this.total = res.total;
this.loading = false;
this.tableData = res.rows
this.total = res.total
this.loading = false
} catch (err) {
console.error(err)
this.loading = false;
this.loading = false
}
},
async saveRowEvent (row) {
async saveRowEvent(row) {
try {
await this.$confirm("确认保存?","提示",{
confirmButtonText: "确认",
cancelButtonText: "取消"
await this.$confirm('确认保存?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消'
})
await this.$refs['table'].clearEdit()
let form = deepCopy(this.form)
for (let key in form) {
const form = deepCopy(this.form)
for (const key in form) {
form[key] = row[key]
}
if (!form.password) {
delete form.password
}
this.loading = true;
this.loading = true
await save(form)
await this.getList();
this.loading = false;
await this.getList()
this.loading = false
} catch (err) {
this.loading = false;
this.loading = false
}
},
async destroyRowEvent (row) {
async destroyRowEvent(row) {
try {
await this.$confirm("确认删除?","提示",{
confirmButtonText: "确认",
cancelButtonText: "取消"
await this.$confirm('确认删除?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消'
})
this.loading = true;
this.loading = true
if (row.id) {
await destroy({
id: row.id
})
await this.getList();
await this.getList()
} else {
console.log(row)
this.tableData.splice(this.tableData.findIndex(i => i._X_ROW_KEY === row._X_ROW_KEY),1)
this.tableData.splice(this.tableData.findIndex(i => i._X_ROW_KEY === row._X_ROW_KEY), 1)
}
this.loading = false;
this.loading = false
} catch (err) {
this.loading = false;
}
},
},
computed: {
isActiveStatus () {
return function (row) {
if (this.$refs['table']) {
return this.$refs['table'].isEditByRow(row)
}
this.loading = false
}
}
},
created() {
this.getList()
}
}
</script>

@ -1,17 +1,30 @@
<template>
<Wujie id="wujie-app"
width="100%"
height="100%"
name="modules"
:url="module_uri"
:props="props">
</Wujie>
<div id="iframe-app"
v-loading="isLoading"
element-loading-text="拼命加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgb(255, 255, 255)">
<!-- <Wujie id="wujie-app"-->
<!-- width="100%"-->
<!-- sync-->
<!-- alive-->
<!-- degrade-->
<!-- height="100%"-->
<!-- :name="props.module_name"-->
<!-- :url="module_uri"-->
<!-- :props="props">-->
<!-- </Wujie>-->
<iframe ref="program"
:src="module_uri"
frameborder="0"></iframe>
</div>
</template>
<script>
import { getToken } from "@/utils/auth"
import Wujie from 'wujie-vue2'
import { mapGetters } from 'vuex'
let loadedModels = [];
export default {
components: {
Wujie
@ -21,19 +34,36 @@ export default {
props: {
auth_token: "",
module_name: "",
}
},
isLoading: true,
}
},
methods: {
postMessage() {
this.$refs['program'].contentWindow.postMessage(this.props)
}
},
methods: {},
computed: {
...mapGetters(['module_uri','module_name'])
},
watch: {
module_uri: {
handler:function(newVal) {
this.isLoading = true;
this.props.module_name = this.module_name;
this.props.auth_token = getToken();
this.$nextTick(() => {
this.$refs['program'].onload = this.postMessage
console.log(loadedModels)
if(loadedModels.indexOf(this.props.module_name) === -1) {
setTimeout(() => {
this.isLoading = false
},1500)
loadedModels.push(this.props.module_name)
} else {
this.isLoading = false
}
})
},
immediate: true
}
@ -41,7 +71,11 @@ export default {
created() {
},
mounted() {
},
beforeDestroy() {
this.$refs['program'].onload = null;
}
}
</script>
@ -54,6 +88,21 @@ export default {
right: 0;
bottom: 0;
}
#iframe-app {
overflow: hidden;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
iframe {
width: 100%;
height: 100%;
}
}
</style>
<style>
.app-main:has(#wujie-app) {

@ -24,8 +24,8 @@ module.exports = {
* In most cases please use '/' !!!
* Detail: https://cli.vuejs.org/config/#publicpath
*/
publicPath: '/',
outputDir: 'dist',
publicPath: '/admin',
outputDir: '../cz_hjjc/public/admin',
assetsDir: 'static',
lintOnSave: process.env.NODE_ENV === 'development',
productionSourceMap: false,

Loading…
Cancel
Save